📄 cface.cpp
字号:
#include "stdafx.h"
#include "CFace.h"
#include "error.h"
//#include "utilcpp.h"
#include "str.h"
#include "def.h"
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <io.h>
int IsOneOf(char chr, char *str);
char str_RT[] = "\n";
char str_SPCRT[] = " \n";
char str_NUMBERS[] = "0123456789";
char str_ASCIIFORMAT[] = "P2";
char str_BINARYFORMAT[] = "P5";
char str_SPC[] = " ";
char str_PPM[] = "ppm";
char str_NAME[] = "NAME:";
char chr_SPC = ' ';
CFace::CFace()
{
xlen = 0;
ylen = 0;
bMat = FALSE;
cFileType = PGM;
cFormat = ASCII;
strcpy(FileName, "");
strcpy(FaceName, "");
data = NULL;
}
CFace::CFace(long w, long h)
{
xlen = w;
ylen = h;
bMat = FALSE;
cFileType = PGM;
cFormat = ASCII;
strcpy(FileName, "");
strcpy(FaceName, "");
data = NULL;
}
CFace::CFace(char *tFileName, char *tFaceName)
{
xlen = 0;
ylen = 0;
bMat = FALSE;
cFileType = PGM;
cFormat = ASCII;
strcpy(FileName, tFileName);
strcpy(FaceName, tFaceName);
bAlloc = FALSE;
data = NULL;
}
CFace::~CFace()
{
if (bAlloc == TRUE)
delete data;
}
/**********************************************************************************************
* Copy the column c of the matrix pMatt to this face's data
* c must be greater than 0 and less or equal the number of columns in the metrix pMatt
* pMat must be locked before the call to this fct
* Beware : it is only the value of the pointer which is copied, the actual data are NOT copied.
**********************************************************************************************/
int CFace::Copy(CMatrixPtr *pMatt, long c)
{
long lpixel;
pMat = pMatt;
col = c;
bMat = TRUE;
lpixel = pMat->GetLi();
xlen = (long)sqrt(lpixel);
ylen = xlen;
if (lpixel > pMat->GetLi())
{ /*The number of matrix's rows is too short*/
lpixel = pMat->GetLi();
}
return 0;
}
/**********************************************************************************************
* Save a face in the PGM (binary) graphics file format.
* If the file already exists, it overwrites it.
* The name of the face is saved as a comment in the second line of the file : "#NAME:<name>"
**********************************************************************************************/
int CFace::Save()
{
int fh;
CMemory *pmem; /*memory storing the file's data*/
unsigned char *str, *str_file;
char DirName[200];
size_t lpixel, l, lheader;
size_t lwritten;
float shift, scale;
int ret;
char str_ext[] = ".ppm";
shift = 0.0;
scale = 1.0;
cFileType = PGM;
strcpy(DirName, FileName); /*Construct the file name*/
strcat(DirName, str_ext); /*by adding its extension*/
Msg(1, str_SAVING, DirName);
fh = _open(DirName, _O_WRONLY | _O_CREAT | _O_BINARY, _S_IREAD | _S_IWRITE);
/*Create a new file in binary mode, overwites it if it exists*/
if (fh == -1)
{
Msg(-1, str_ERR_FILE_OPEN, strerror(errno));
return ERR_FILE_OPEN;
}
Expand(&scale, &shift, 0, 255);
pmem = new CMemory();
ret = pmem->Allocate(xlen*ylen*sizeof(char)+ 500L); /*Allocate memory for the hole file's data*/
if (ret < 0) /*It needs space for the header and for the data*/
{
delete pmem;
_close(fh);
return ret;
}
str = (unsigned char *)pmem->GetPtr();
strcpy((char*)str, "");
cFormat = BINARY;
if (strcmp(FaceName, "") != 0)
sprintf((char*)str, "P5 %ld %ld\n#%s%s\n255 ", xlen, ylen, str_NAME, FaceName);
else
sprintf((char*)str, "P5 %ld %ld\n255 ", xlen, ylen);
lheader = strlen((char*)str);
str_file = str;
str = str + lheader;
Lock();
lpixel = xlen*ylen;
for (l = 0; l < lpixel; l++)
{
str[l] = (unsigned char)(shift + scale*GetAt(l));
}
Unlock();
lwritten = _write(fh, (char *)str_file, lpixel+lheader);
if (lwritten != lpixel+lheader)
{
Msg(0, str_ERR_FILE_WRITE, lwritten, lpixel+lheader);
}
if (_close(fh) == -1)
{
Msg(0, str_ERR_FILE_CLOSE, strerror(errno));
}
pmem->ReleasePtr();
delete pmem;
Msg(-1, ""/*str_SAVED*/);
return 0;
}
/**********************************************************************************************
* Load a face from a PGM graphics file
**********************************************************************************************/
int CFace::Load()
{
CException *excpt;
int fh;
long filelen; /*file length*/
long lread; /*number of characters actually read*/
int ret, pos;
CMemory *pmem;
char *buf;
char *str;
int err = 0;
char str_Delimit[10];
char chr_Delimit;
Msg(1, str_LOADING, FileName);
pos = strlen(FileName);
if (strcmp(&(FileName[pos-strlen(str_PPM)]), str_PPM) == 0)
{
cFileType = PPM;
strcpy(str_Delimit, str_SPC);
chr_Delimit = str_SPC[0];
}
else
{
cFileType = PGM;
strcpy(str_Delimit, str_RT);
chr_Delimit = str_RT[0];
}
fh = _open(FileName, _O_RDONLY | _O_BINARY); /*Open the file in read mode*/
if (fh == -1)
{
Msg(-1, str_ERR_FILE_OPEN, strerror(errno));
return ERR_FILE_OPEN;
}
TRY
{
_lseek(fh, 0, SEEK_END);
filelen = _tell(fh); /*Calculates the file lenght*/
if (filelen == -1L)
{
Msg(0, strerror(errno));
_close(fh); /*Close the file*/
return err;
}
_lseek(fh, 0, SEEK_SET);
pmem = new CMemory();
ret = pmem->Allocate(filelen*sizeof(char)); /*Allocate memory for the hole file's data*/
if (ret < 0)
{
_close(fh);
return ret;
}
buf = (char *)pmem->GetPtr();
lread = _read(fh, buf, (unsigned int)filelen);
/*read the data*/
if (lread != filelen)
{ /*Problem : All the data have not been read*/
Msg(0, str_ERR_FILE_READPROB, lread, filelen);
}
if (lread == 0)
{
_close(fh);
Msg(-1, str_ERR_FILE_READPROB, lread, filelen);
return ERR_FILE_READ; /*Nothing has been read*/
}
_close(fh); /*Close the file*/
str = buf;
while (str[0] == '#')
str = strchr(str, '\n') + 1L;
if (str == 0 || (strncmp(str, str_ASCIIFORMAT, strlen(str_ASCIIFORMAT)) != 0 &&
strncmp(str, str_BINARYFORMAT, strlen(str_BINARYFORMAT)) != 0))
{ /*neither ASCII nor BINARY format, so reject and quit*/
err = ERR_FF;
Msg(-1, str_ERR_ASCIIBIN);
return err;
}
if (strncmp(str, str_ASCIIFORMAT, strlen(str_ASCIIFORMAT)) == 0)
{
cFormat = ASCII; /*check the format*/
str = str + strlen(str_ASCIIFORMAT);
}
else
{
cFormat = BINARY;
str = str + strlen(str_BINARYFORMAT);
}
str = GetNextTok(str);
if (str == NULL)
{ /*unexpected end of file found*/
err = ERR_FF;
Msg(-1, str_ERR_FILE_UNEXPECTEDEOF);
return err;
}
xlen = atoi(str); /*get the width*/
str = GetNextTok(str);
if (str == NULL)
{ /*unexpected end of file found*/
err = ERR_FF;
Msg(-1, str_ERR_FILE_UNEXPECTEDEOF);
return err;
}
ylen = atoi(str); /*get the height*/
str = GetNextTok(str);
if (str == 0)
{ /*unexpected end of file found*/
err = ERR_FF;
Msg(-1, str_ERR_FILE_UNEXPECTEDEOF);
return err;
}
ret = atoi(str);
if (ret != 255)
{ /*not 8bit coded, so reject and quit*/
err = ERR_FF;
Msg(-1, str_ERR_NOT255);
return err;
}
str = GetNextLine(str);
if (str == 0)
{ /*unexpected end of file found*/
err = ERR_FF;
Msg(-1, str_ERR_FILE_UNEXPECTEDEOF);
return err;
}
pos = str - buf; /*get the position of the data in the file*/
Allocate(); /*Allocate memory if necessary*/
if (cFormat == ASCII)
ret = ReadASCII((unsigned char *)str);
else
ret = ReadBinary((unsigned char *)str);
}
CATCH(CException, excpt)
{
if (err >= 0)
err = -1;
}
END_CATCH
if (ret >= 0)
Msg(-1, ""/*str_LOADED*/);
pmem->ReleasePtr();
delete pmem;
return err;
}
void CFace::Allocate()
{
if (data == NULL)
{
data = /*TCL_NEW(*/ new CMemory();
bAlloc = TRUE;
}
data->Allocate(xlen*ylen*sizeof(typeface)); /*allocate the data's memory*/
}
char *CFace::GetNextTok(char *str)
{
char str_Delimit[] = " \t\n\r";
str = GetNextLine(str);
if (str == NULL)
return str;
while (isalnum(str[0]) == 0)
str++;
return str;
}
char *CFace::GetNextLine(char *str)
{
char str_Delimit[] = " \t\n\r";
char chr_Comment = '#';
char chr_RT = '\n';
while (!IsOneOf(str[0], str_Delimit))
{
if (str[0] == NULL)
return NULL;
if (str[0] == chr_Comment)
{
str++;
if (strncmp(str, str_NAME, strlen(str_NAME)) == 0)
{
SetName(str + strlen(str_NAME), 5);
}
str = strchr(str, chr_RT);
}
str++;
}
str++;
while (str[0] == chr_Comment)
{ str++;
if (strncmp(str, str_NAME, strlen(str_NAME)) == 0)
{
SetName(str + strlen(str_NAME), 5);
}
str = strchr(str, chr_RT)+1L;
}
return str;
}
int IsOneOf(char chr, char *str)
{
int i, len = strlen(str);
for (i = 0; i < len; i++)
{
if (chr == str[i])
return 1;
}
return 0;
}
int CFace::ReadBinary(unsigned char *str)
{
long l, lpixel;
typeface *pdata = 0;
lpixel = xlen*ylen;
pdata = (typeface*)data->GetPtr();
for(l = 0; l < lpixel; l++)
{
pdata[l] = (typeface)str[l];
}
data->ReleasePtr();
return 0;
}
int CFace::ReadASCII(unsigned char *buf)
{
long x, y;
char *str;
int err = 0;
str = strtok((char *)buf, str_SPCRT);
if (str == 0)
{ /*unexpected end of file found*/
err = ERR_FF;
Msg(0, str_ERR_FILE_UNEXPECTEDEOF); /*error of file format*/
return err;
}
for (y = 0; y < ylen; y++)
{
for (x = 0; x < xlen; x++)
{
if (x != 0 || y != 0) /*strtok is already done for the first*/
str = strtok(NULL, str_SPCRT); /*get the next pixel value*/
if (str == 0)
{ /*unexpected end of file found*/
err = ERR_FF;
Msg(0, str_ERR_FILE_UNEXPECTEDEOF); /*file format error*/
return err;
}
pdata[x + y*xlen] = atof(str); /*put the pixel value in memory*/
}
}
return 0;
}
void CFace::Expand(float *scale, float *shift, float dest_min, float dest_max)
{
typeface val, src_min, src_max;
long l, lpixel = xlen*ylen;;
Lock();
src_min = MAXFLOAT;
src_max = -MAXFLOAT;
for (l = 0; l < lpixel; l++)
{
val = GetAt(l);
if (val < src_min)
src_min = val;
if (val > src_max)
src_max = val;
}
if (src_max == src_min)
{
*scale = 1.0;
*shift = 0.0;
}
else
{
*scale = fabs((dest_max - dest_min)) / fabs((src_max - src_min));
*shift = dest_min - *scale * src_min;
}
Unlock();
}
long CFace::Getxlen()
{return xlen;}
long CFace::Getylen()
{return ylen;}
typeface *CFace::GetData()
{
return (bMat == TRUE) ? NULL : (typeface *)(data->GetPtr());
}
char *CFace::GetName()
{
return FaceName;
}
char *CFace::GetFileName()
{
return FileName;
}
void CFace::ReleaseData()
{
if (bMat == FALSE)
data->ReleasePtr();
}
CMemory *CFace::GetMem()
{return data;}
/*inline*/ void CFace::SetAt(long x, long y, typeface val)
{
if (bMat == TRUE)
pMat->SetAt((y-1L)*xlen + (x-1L) + 1L, col, val);
else
pdata[(y-1L)*xlen + (x-1L)] = val;
}
/*inline*/ void CFace::SetAt(long lpixel, typeface val)
{
if (bMat == TRUE)
pMat->SetAt(lpixel + 1, col, val);
else
pdata[lpixel] = val;
}
/*inline*/ typeface CFace::GetAt(long x, long y)
{
return (bMat == TRUE) ?
pMat->GetAt((y-1L)*xlen + (x-1L) + 1L, col)
:
pdata[(y-1L)*xlen + (x-1L)];
}
/*inline*/ typeface CFace::GetAt(long lpixel)
{
return (bMat == TRUE) ?
pMat->GetAt(lpixel + 1, col)
:
pdata[lpixel];
}
void CFace::Lock()
{
if (bMat == TRUE)
pMat->Lock();
else
pdata = (typeface*)data->GetPtr();
}
void CFace::Unlock()
{
if (bMat == TRUE)
pMat->Unlock();
else
data->ReleasePtr();
pdata = NULL;
}
void CFace::SetFileName(char *str_file)
{strcpy(FileName, str_file);}
void CFace::SetName(char *str_file, int len)
{
if (len < 0)
strcpy(FaceName, str_file);
else
strncpy(FaceName, str_file, len);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -