www.pudn.com > faces.rar > recoparms.c


/*** 
 **     libface - Library of face recognition and supporting algorithms 
        Copyright (c) 2003 Stefan Farthofer 
 
	This file is part of libface, which is 
 
        free software; you can redistribute it and/or modify 
        it under the terms of the GNU General Public License as published by 
        the Free Software Foundation; either version 2 of the License, or 
        (at your option) any later version. 
 
        This program is distributed in the hope that it will be useful, 
        but WITHOUT ANY WARRANTY; without even the implied warranty of 
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
        GNU General Public License for more details. 
 
        You should have received a copy of the GNU General Public License 
        along with this program; if not, write to the Free Software 
        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 
	For further information seek us at http://sourceforge.net/projects/openbio/ 
**	or write an email to dimitri.pissarenko@gmx.net or farthofer@chello.at. 
***/ 
 
#include  
#include  
#include  
#include  
#include "frbase.h" 
#include "fr.h" 
#include "recoalgo.h" 
 
void frutilFreeTrainedDataArray(FRrecognitionParameters* gParms, FRtrainedData* tData, unsigned int nr); 
 
/* recognition parameter serialize */ 
int frRecoParamsCreate(FRrecognitionParameters** gParms) { 
	*gParms = (FRrecognitionParameters*)malloc(sizeof(FRrecognitionParameters)); 
	if (*gParms == NULL) return FR_ERR_NOMEM; 
	memset(*gParms, 0, sizeof(FRrecognitionParameters)); 
	return FR_OK; 
} 
 
void frRecoParamsFree(FRrecognitionParameters** gParms) { 
	/* first delete all trainedData sets */ 
	frutilFreeTrainedDataArray(*gParms, (*gParms)->algorithms, (*gParms)->nrAlgorithms); 
	free(*gParms); 
	*gParms = NULL; 
} 
 
size_t frRecoParamsGetSize(FRrecognitionParameters* gParms) { 
	size_t sz=0; 
	unsigned int i; 
	FRtrainedData* tData; 
	FRrecoAlgo* algo; 
 
	/* calculate children size */ 
	for (i=0; inrAlgorithms; i++) { 
		sz = sz + sizeof(FRtrainedData) - sizeof(void*); /* general structure size minus data pointer */ 
		/* now add alog specific size */ 
		tData = gParms->algorithms+i; 
		algo = frGetRecoAlgoById(tData->algorithmType); 
		sz = sz + algo->getParametersSize(gParms, tData->data); 
	} 
 
	/* recognitionParameter fields minux algorithms pointer */ 
	sz = sz + sizeof(FRrecognitionParameters) - sizeof(FRtrainedData*); 
	return sz; 
} 
 
int frRecoParamsSerialize(BYTE** mem, size_t maxsz, FRrecognitionParameters** gParms, BYTE direction) { 
	BYTE* begin = *mem; 
	unsigned int i; 
	int ret = FR_OK; 
	FRtrainedData* tData; 
	FRrecoAlgo* algo; 
 
	/* sanity check */ 
	if (direction == FR_OUT && maxsz < frRecoParamsGetSize(*gParms)) 
		return FR_ERR_ALLOCMORE; 
 
	/* if direction is IN, we have to allocate memory */ 
	if (direction == FR_IN) { 
		*gParms = (FRrecognitionParameters*)malloc(sizeof(FRrecognitionParameters)); 
		if (*gParms == NULL) return FR_ERR_NOMEM; 
	} 
 
	/* write/read fields */ 
	frCopyMem(mem, &(*gParms)->width, sizeof((*gParms)->width), direction); 
	frCopyMem(mem, &(*gParms)->height, sizeof((*gParms)->height), direction); 
	frCopyMem(mem, &(*gParms)->nextId, sizeof((*gParms)->nextId), direction); 
	frCopyMem(mem, &(*gParms)->faceFinder, sizeof((*gParms)->faceFinder), direction); 
	frCopyMem(mem, &(*gParms)->nrAlgorithms, sizeof((*gParms)->nrAlgorithms), direction); 
 
	/* if direction is IN, allocate memroy for algorithm entries */ 
	if (direction == FR_IN) { 
		(*gParms)->algorithms = (FRtrainedData*)malloc(sizeof(FRtrainedData)*(*gParms)->nrAlgorithms); 
		if ((*gParms)->algorithms == NULL) { 
			free(*gParms); 
			return FR_ERR_NOMEM; 
		} 
	} 
 
	/* de/serialize trained data entries */ 
	for (i=0; i < (*gParms)->nrAlgorithms && ret == FR_OK; i++) { 
		tData = (*gParms)->algorithms+i; 
		frCopyMem(mem, &tData->id, sizeof(tData->id), direction); 
		frCopyMem(mem, &tData->algorithmType, sizeof(tData->algorithmType), direction); 
		/* write custom data */ 
		algo = frGetRecoAlgoById(tData->algorithmType); 
		ret = algo->serializeParameters(*gParms, &tData->data, mem, maxsz-(*mem-begin), direction); 
	} 
 
	if (ret != FR_OK && direction == FR_IN) { /* free all previous allocations */ 
		frutilFreeTrainedDataArray(*gParms, (*gParms)->algorithms, i-1); 
		free(*gParms); 
	} 
	return ret; 
} 
 
int frRecoParamsSaveFile(FILE* fileHandle, FRrecognitionParameters* gParms) { 
	int err = FR_OK; 
	size_t sz; 
	BYTE* data, * temp; 
 
	/* get serialized data */ 
	sz = frRecoParamsGetSize(gParms); 
	temp = data = (BYTE*)malloc(sz); 
	if (data == NULL) return FR_ERR_NOMEM; 
	 
	err = frRecoParamsSerialize(&temp, sz, &gParms, FR_OUT); 
 
	/* write size and then data */ 
	if (err == FR_OK && !fwrite(&sz, sizeof(sz), 1, fileHandle)) err = FR_ERR_FILE; 
	if (err == FR_OK && !fwrite(data, sz, 1, fileHandle)) err = FR_ERR_FILE; 
 
	free(data); 
	return err; 
} 
 
int frRecoParamsLoadFile(FILE* fileHandle, FRrecognitionParameters** gParms) { 
	int err = FR_OK; 
	size_t sz; 
	BYTE* data, * temp; 
 
	/* read size */ 
	if (!fread(&sz, sizeof(sz), 1, fileHandle)) return FR_ERR_FILE; 
 
	/* allocate memory */ 
	temp = data = (BYTE*) malloc(sz); 
	if (data == NULL) return FR_ERR_NOMEM; 
 
	/* read serialized data */ 
	if (!fread(data, sz, 1, fileHandle)) { 
		free(data); 
		return FR_ERR_FILE; 
	} 
 
	/* deserialize */ 
	err = frRecoParamsSerialize(&temp, sz, gParms, FR_IN); 
	free(data); 
 
	return err; 
} 
 
/* recognition parameter setup */ 
int frRecoParamsAddAlogrithm(FRrecognitionParameters* gParms, int type, FRalgoParam* algoParms, unsigned int nrAlgoParms, FRimage* images, unsigned int nrImages) { 
	unsigned int i; 
	int err=FR_OK; 
	FRtrainedData* newdat; 
	FRrecoAlgo* algo, * newalgo; 
 
	/* check if global parms have been set, if not, assume width and height of first picture */ 
	if (gParms->width == 0 || gParms->height == 0) { 
		if (nrImages == 0) return FR_ERR_INVALID_PARMS; 
		gParms->height = images->height; 
		gParms->width = images->width; 
	} 
 
	/* check if requested algo exists */ 
	newalgo = frGetRecoAlgoById(type); 
	if (newalgo == NULL) return FR_ERR_NOALGO; 
 
	/* allocate new FRtrainedData array */ 
	newdat = (FRtrainedData*) malloc(sizeof(FRtrainedData)*(gParms->nrAlgorithms+1)); 
	if (newdat == NULL) return FR_ERR_NOMEM; 
 
	/* copy old parameters */ 
	for (i=0; err == FR_OK && i < gParms->nrAlgorithms; i++) { 
		newdat[i].algorithmType = gParms->algorithms[i].algorithmType; 
		newdat[i].id = gParms->algorithms[i].id; 
		algo = frGetRecoAlgoById(gParms->algorithms[i].algorithmType); 
		err = algo->copyParameters(gParms, &newdat[i].data, gParms->algorithms[i].data); 
	} 
 
	if (err != FR_OK) { /* rollback */ 
		frutilFreeTrainedDataArray(gParms, newdat,i-1); 
		return err; 
	} 
 
	newdat[i].algorithmType = type; 
	newdat[i].id = gParms->nextId++; 
	err = newalgo->setupAlgoInstance(gParms, algoParms, nrAlgoParms, images, nrImages, &newdat[i].data); 
 
	if (err != FR_OK) { /* rollback */ 
		frutilFreeTrainedDataArray(gParms, newdat, i); 
	} else { /* link new array */ 
		frutilFreeTrainedDataArray(gParms, gParms->algorithms, gParms->nrAlgorithms); 
		gParms->algorithms = newdat; 
		gParms->nrAlgorithms++; 
	} 
	return err; 
} 
 
int frRecoParamsRemoveAlgorithm(FRrecognitionParameters* gParms, unsigned int id) { 
	unsigned int i, j; 
	int err = FR_OK; 
	FRtrainedData* newdat; 
	FRrecoAlgo* algo; 
 
	/* check if the specified algo exists */ 
	for (i=0; i < gParms->nrAlgorithms; i++)  
		if ((gParms->algorithms+i)->id == id) break; 
	if (i == gParms->nrAlgorithms) 
		return FR_ERR_NOALGO; 
 
	/* allocate memory for new struct */ 
	newdat = (FRtrainedData*) malloc(sizeof(FRtrainedData)*(gParms->nrAlgorithms-1)); 
	if (newdat == NULL) return FR_ERR_NOMEM; 
 
	/* fill new struct */ 
	for (i=0, j=0; err == FR_OK && i < gParms->nrAlgorithms; i++) { 
		if ((gParms->algorithms+i)->id != id) { 
			(newdat+j)->algorithmType = (gParms->algorithms+i)->algorithmType; 
			(newdat+j)->id = (gParms->algorithms+i)->id; 
			algo = frGetRecoAlgoById((gParms->algorithms+i)->algorithmType); 
			err = algo->copyParameters(gParms, &(newdat+j)->data, (gParms->algorithms+i)->data); 
			j++; 
		} 
	} 
 
	if (err != FR_OK) { 
		/* free everything that has been allocated */ 
		frutilFreeTrainedDataArray(gParms, newdat, j-1); 
	} else { /* else everything ok and link new FRtrainedData array */ 
		frutilFreeTrainedDataArray(gParms, gParms->algorithms, gParms->nrAlgorithms); 
		gParms->algorithms = newdat; 
		gParms->nrAlgorithms--; 
	} 
 
	return err; 
} 
 
void frCopyMem(BYTE** mem, void * data, size_t sz, BYTE direction) { 
	if (direction == FR_IN) 
		memcpy(data, *mem, sz); 
	else 
		memcpy(*mem, data, sz); 
	*mem = *mem + sz; 
} 
 
void frutilFreeTrainedDataArray(FRrecognitionParameters* gParms, FRtrainedData* tData, unsigned int nr) { 
	unsigned int i = 0; 
	FRrecoAlgo* algo; 
 
	for (; i < nr; i++) { 
		algo = frGetRecoAlgoById(tData[i].algorithmType); 
		algo->freeParameters(gParms, &tData[i].data); 
	} 
	free(tData); 
}