📄 cfacedb.cpp
字号:
#include "stdafx.h"
#include "CFace.h"
#include "CFaceDB.h"
#include "error.h"
#include "str.h"
#include "utilcpp.h"
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <io.h>
#include <stdlib.h>
CFaceDB::CFaceDB()
{
pArray = new CObArray();
nNumFace = 0;
}
CFaceDB::~CFaceDB()
{
int l, len = pArray->GetUpperBound();
for (l = len; l >= 0; l--)
{
delete pArray->GetAt(l);
pArray->RemoveAt(l);
}
delete pArray; /*Deletes the objects of the area and the area itself*/
}
/*********************************************************************************************
* Read the one face and append it to the databasee.
* The character string parameter must contain the face's file name followed by the face's name.
* Between these two, there must be some tab characters.
*
* It returns 0 if all was ok, a negatib\ve value in case of any errors
*********************************************************************************************/
int CFaceDB::AddFace(char *data)
{
int ret, index;
long xlent, ylent;
char *str_line = 0;
char FileName[255];
char FaceName[64];
CFace *pFace = NULL, *pFace0 = NULL;
int err = 0;
strcpy(FileName, "");
strcpy(FaceName, "");
GetLine(data, FileName, sizeof(FileName)/sizeof(char), FaceName, sizeof(FaceName)/sizeof(char));
index = pArray->Add(new CFace(FileName, FaceName));
nNumFace++;
pFace = (CFace*)(pArray->GetAt(index)); /*Put the address of the face element in the pointer pFace*/
if (pFace == NULL)
{
nNumFace--;
return 0;
}
ret = pFace->Load(); /*Load the image data of the face from the disk*/
if (ret < 0)
{
pArray->RemoveAt(index);
delete pFace;
nNumFace--;
return 0;
}
pFace0 = (CFace*)(pArray->GetAt(0)); /*Put the address of the first face element in the pointer pFace*/
xlen = pFace0->Getxlen(); /*gets the face's dimensions*/
ylen = pFace0->Getylen();
/*Verify that this faces have the same dimensions as the first one*/
xlent = pFace->Getxlen();
ylent = pFace->Getylen();
if (xlent != xlen || ylent != ylen)
{
Msg(0, str_ERR_DIMENSION, pFace->GetFileName(), xlen, ylen, xlent, ylent);
pArray->RemoveAt(index); /*Remove the face from the array*/
delete pFace; /*delete the face object*/
nNumFace--; /*Decrease the number of faces in our database*/
return 0;
}
return 0;
}
/*********************************************************************************************
* Read the face database file. the character string parameter is a stream of lines. Each line
* contains the mac full path name of a face file of the database.
*
* It returns 0 if all was ok, a negatib\ve value in case of any errors
*********************************************************************************************/
int CFaceDB::Load(char *data)
{
int ret, i;
long xlent, ylent;
char *str_line = 0;
char FileName[255];
char FaceName[64];
CFace *pFace = 0;
int err = 0;
while (isalpha(data[0]) == 0)
data++;
str_line = strtok(data, str_RET);
while (str_line != NULL)
{ /*while there are file name in the TRAINING directory*/
strcpy(FileName, "");
strcpy(FaceName, "");
GetLine(str_line, FileName, sizeof(FileName)/sizeof(char), FaceName, sizeof(FaceName)/sizeof(char));
if (FileName[0] != chr_PROJ_COMMENT)
{
pArray->Add(new CFace(FileName, FaceName));
nNumFace++;
}
str_line = strtok(NULL, str_RET);
}
for (i = 0; i < nNumFace; i++)
{
pFace = (CFace*)(pArray->GetAt(i)); /*Put the address of the ith face element in the pointer pFace*/
ret = pFace->Load(); /*Load the image data of the face from the disk*/
#if 0
if (ret == ERR_FILE_OPEN)
{ /*Cannot open a file*/
/*probably because EOF was not detected*/
break; /*So there was one too much record in the face database*/
}
#endif
if (ret < 0)
{
pArray->RemoveAt(i);
delete pFace;
i--;
nNumFace--;
}
}
if (nNumFace == 0)
return -1;
pFace = (CFace*)(pArray->GetAt(0)); /*Put the address of the first face element in the pointer pFace*/
xlen = pFace->Getxlen(); /*gets the face's dimensions*/
ylen = pFace->Getylen();
/*Verify that all the faces have the same dimensions*/
for (i = 1; i < nNumFace; i++)
{
pFace = (CFace*)(pArray->GetAt(i)); /*Put the address of the ith face element in the pointer pFace*/
xlent = pFace->Getxlen();
ylent = pFace->Getylen();
if (xlent != xlen || ylent != ylen)
{
Msg(0, str_ERR_DIMENSION, pFace->GetFileName(), xlen, ylen, xlent, ylent);
pArray->RemoveAt(i); /*Remove the face from the array*/
delete pFace; /*delete the face object*/
i--;
nNumFace--; /*Decrease the number of faces in our database*/
}
}
return 0;
}
/**********************************************************************************************
* CFaceDB::GetLine gets a face database's line from the string str_temp. It separates the elements
* of the line into FileName (the file's name full path name), and FaceName (the face's name).
* lenFileName is the length of the char array FileName and lenFaceName is the one of FaceName.
* If a line is a comment, it put the comment character in the first character of filename
*
* it returns 0 if all is ok, a negative number in case of any errors.
**********************************************************************************************/
int CFaceDB::GetLine(char *str_temp, char *FileName, int lenFileName, char *FaceName, int lenFaceName)
{
int i;
while(isalpha(str_temp[0]) == 0 && str_temp[0] != chr_PROJ_COMMENT && (str_temp[0] != chr_RT1 && str_temp[0] != chr_RT2) && str_temp[0] != 0)
str_temp++; /*look for the first alphabetic character*/
if (str_temp[0] == 0)
return -1;
if (str_temp[0] == chr_PROJ_COMMENT)
{
FileName[0] = chr_PROJ_COMMENT;
return 0;
}
i = GetStr(str_temp, FileName, lenFileName, str_TABRT); /*put the file name (the first name in the line) in aName*/
str_temp = str_temp + i; /*increase the string*/
while(isalpha(str_temp[0]) == 0 && (str_temp[0] != chr_RT1 && str_temp[0] != chr_RT2) && str_temp[0] != 0)
str_temp++; /*look for the first alphabetic character*/
if (str_temp[0] == 0)
return 0;
if (str_temp[0] != chr_RT1 && str_temp[0] != chr_RT2)
{ /*there is a face's name*/
i = GetStr(str_temp, FaceName, lenFaceName, str_TABRT);
/*put the face's name in fName*/
str_temp = str_temp + i; /*increase the string*/
}
return 0;
}
/**********************************************************************************************
* GetStr get the first string, not containing any of the characters in Delimit, of the string
* str_temp, put it in aName (which length is the integer lenaName, and increase the pointer str_temp
* to the end of the word (copied into aName). So str_temp is changed by the fct,
* therefore the ADDRESS of a pointer to a string must be passed.
* The calling function must keep a pointer to the beginning of str_temp, in order to keep the
* memory safe and not to lose anything.
* char *str_temp pointer to the beginning of the string
* char aName[] array of char that will receive the word
* int lenaName length of aName
* return nothing.
**********************************************************************************************/
int CFaceDB::GetStr(char *str_temp, char *aName, int lenaName, char *Delimit)
{
int i;
i = 0;
while (strchr(Delimit, str_temp[i]) == NULL && i < strlen(str_temp))
i++; /*look for the end of the word*/
strncpy(aName, str_temp, __min(i, lenaName)); /*copy the word*/
aName[i] = 0;
return i;
}
/**********************************************************************************************
* GetLong gets the first word (which must be a number) of the string str_temp, convert it into a
* long value, increase the pointer str_temp to the end of the word, and return the value.
* The calling function must keep a pointer to the beginning of str_temp, in order to keep the
* memory safe and not to lose anything.
* char *str_temp pointer to the beginning of the string
* return the long value
**********************************************************************************************/
long CFaceDB::GetLong(char *str_temp)
{
int i;
long ret;
ret = atol(str_temp);
i = 0;
while (isdigit(str_temp[i]) == 0 && str_temp[i] != chr_RT1 && str_temp[i] != chr_RT2)
i++; /*look for the end of the number*/
/*increase the string*/
return ret;
}
/**********************************************************************************************
* Deletes all the faces in this database and puts the faces contained in the matrix by copying
* each column data to a CFace object. The Faces' names are the values contained in the diagonal
* matrix.
* Beware : it is only the value of the pointer which is copied, the actual data are NOT copied.
**********************************************************************************************/
int CFaceDB::Copy(CMatrixPtr *pMat, CDiag *pDiag)
{
long col, l;
CFace *pFace = NULL;
char name[10];
int c, l2, len = pArray->GetUpperBound();
/*first delete all the elements*/
for (l2 = len; l2 >= 0; l2--)
{
delete pArray->GetAt(l2);
pArray->RemoveAt(l2);
}
delete pArray; /*Deletes the objects of the area and the area itself*/
pArray = new CObArray();
/*second iterates on all the columns*/
col = pMat->GetCol(); /*Verify that the matrix and the vectors have the same number of columns*/
l = pDiag->GetCol();
if (l < col)
{
Msg(0, str_ERR_MAT_COPY);
Fail(0);
}
pDiag->Lock();
for (c = 1; c <= col; c++)
{
sprintf(name, "%.2E", pDiag->GetAt(c));
pArray->Add(new CFace("", name));
pFace = (CFace*)(pArray->GetAt(c-1)); /*Put the address of the ith face element in the pointer pFace*/
pFace->Copy(pMat, c); /*Copy the values in the CFace object*/
nNumFace++;
}
pDiag->Unlock();
pFace = (CFace*)(pArray->GetAt(0)); /*Put the address of the first face element in the pointer pFace*/
xlen = pFace->Getxlen(); /*gets the face's dimensions*/
ylen = pFace->Getylen();
return 0;
}
/**********************************************************************************************
* Saves in the full mac pathname str_dir, the whole face database
* Each face is saved in a PGM file
**********************************************************************************************/
int CFaceDB::Save(char *str_dir)
{
int len, n;
char str_path[200], str_number[10], str_path_real[200];
CFace *pFace;
len = 0;
while (str_dir[len] == ' ' || str_dir[0] == '\t')
len++;
strcpy(str_path, str_dir + len);
n = 0;
len = pArray->GetSize();
for (n = 0; n < len; n++)
{
pFace = (CFace*)(pArray->GetAt(n));
strcpy(str_path_real, str_path);
sprintf(str_number, "%i", n+1);
strcat(str_path_real, str_number);
pFace->SetFileName(str_path_real);
pFace->Save();
}
return 0;
}
void CFaceDB::Expand(int nFace, float *scale, float *shift, float dest_min, float dest_max)
{
CFace *pFace = (CFace*)(pArray->GetAt(nFace-1));/*Put the address of the ith face element in the pointer pFace*/
pFace->Expand(scale, shift, dest_min, dest_max);
}
long CFaceDB::Getxlen()
{return xlen;}
long CFaceDB::Getylen()
{return ylen;}
long CFaceDB::GetNumFace()
{return nNumFace;}
long CFaceDB::GetNumPixel()
{return Getxlen() * Getylen();}
CMemory* CFaceDB::GetFaceMem(int l)
{
CFace *pFace = (CFace*)(pArray->GetAt(l-1)); /*Put the address of the ith face element in the pointer pFace*/
return pFace->GetMem();
}
char *CFaceDB::GetFaceName(int l)
{
CFace *pFace = (CFace*)(pArray->GetAt(l-1)); /*Put the address of the ith face element in the pointer pFace*/
return pFace->GetName();
}
typeface *CFaceDB::GetFaceData(int l)
{
CFace *pFace = (CFace*)(pArray->GetAt(l-1)); /*Put the address of the ith face element in the pointer pFace*/
return pFace->GetData();
}
void CFaceDB::ReleaseFaceData(int l)
{
CFace *pFace = (CFace*)(pArray->GetAt(l-1)); /*Put the address of the ith face element in the pointer pFace*/
pFace->ReleaseData();
}
CFace *CFaceDB::GetFace(int l)
{
return (CFace*)(pArray->GetAt(l-1));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -