bool config_funcFailure_outOfRange()
{
	SP_CONFIG_MSG msg;
	char path[100];

	SPConfig config = NULL;



	ASSERT_TRUE(true == runConfigTest(SUCCESS, /* test type */
										3, /* file index */
										0,	/* line of the error */
										&config)
				);

	/* you can see config values in config_success_Full_Values_Check test */

	msg = spConfigGetImagePath(path, config, 10);
	checkMsgOutOfRange_AndRevertMsgToSuccess(&msg);
	msg = spConfigGetImagePath(path, config, -1);
	checkMsgOutOfRange_AndRevertMsgToSuccess(&msg);


	msg = spConfigGetFeatsPath(path, config, 10);
	checkMsgOutOfRange_AndRevertMsgToSuccess(&msg);
	msg = spConfigGetFeatsPath(path, config, -1);
	checkMsgOutOfRange_AndRevertMsgToSuccess(&msg);

	spConfigDestroy(config);

	return true;
}
bool config_success_WithCarrigeReturnAtEOF()
{
	SPConfig config = NULL;
	SP_CONFIG_MSG msg;

	ASSERT_TRUE(true == runConfigTest(SUCCESS, /* test type */
										8, /* file index */
										0,	/* line of the error */
										&config)
				);


	char imgPath[100];
	msg = spConfigGetImagePath(imgPath, config, 4);
	ASSERT_TRUE( 0 == strcmp(imgPath, "./images/img4.png") );
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}

	ASSERT_TRUE(16 == spConfigGetNumOfImages(config, &msg));
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}

	spConfigDestroy(config);

	return true;
}
Exemple #3
0
void endControlFlow(SPConfig config, SPImageData image,
		bool isCurrentImageFeaturesArrayAllocated, SPKDTreeNode kdTree, SPBPQueue bpq,
		int returnValue) {
	if (returnValue < 0) {
		printf(MAIN_RETURNED_ERROR);
	}
	printf("%s", EXITING);
	spConfigDestroy(config);
	freeImageData(image, !isCurrentImageFeaturesArrayAllocated, true);
	spKDTreeDestroy(kdTree, true);
	spBPQueueDestroy(bpq);
	spLoggerDestroy();
}
bool config_success_Tab_As_Space()
{
	SPConfig config = NULL;

	ASSERT_TRUE(true == runConfigTest(SUCCESS, /* test type */
										6, /* file index */
										0,	/* line of the error */
										&config)
				);

	spConfigDestroy(config);


	return true;
}
bool config_success_Bounds_Check2()
{
	SPConfig config = NULL;

	ASSERT_TRUE(true == runConfigTest(SUCCESS, /* test type */
										5, /* file index */
										0,	/* line of the error */
										&config)
				);

	spConfigDestroy(config);


	return true;
}
bool config_success_PlusSign()
{
	SPConfig config = NULL;
	SP_CONFIG_MSG msg;

	ASSERT_TRUE(true == runConfigTest(SUCCESS, /* test type */
										2, /* file index */
										0,	/* line of the error */
										&config)
				);

	ASSERT_TRUE(16 == spConfigGetNumOfImages(config, &msg));

	spConfigDestroy(config);

	return true;
}
SPConfig spConfigCreate(const char* filename, SP_CONFIG_MSG* msg){

	char line[1024];
	char *variable;
	char *value;
	bool isComment, isValidLine, isEqualSign;
	FILE *configFile = NULL;
	int lineCounter = 0;
	int lineLength, varStart, varEnd, valueStart, valueEnd, charIndex;
	SPConfig config;

	assert(msg != NULL);

	if(filename == NULL){
		*msg = SP_CONFIG_INVALID_ARGUMENT;
		return NULL;
	}

	config = (SPConfig) malloc(sizeof(*config)); //allocating memory for the new configuration
	if(config == NULL) { //Allocation Fails
		*msg = SP_CONFIG_ALLOC_FAIL;
		return NULL;
	}

	config->spImagesDirectory = (char*) malloc(sizeof(char)*1025); //allocating memory for the new point
	if (config->spImagesDirectory == NULL) { //Allocation Fails
		*msg = SP_CONFIG_ALLOC_FAIL;
		free(config);
		return NULL;
	}
	*config->spImagesDirectory = '\0';
	config->spImagesPrefix = (char*) malloc(sizeof(char)*1025); //allocating memory for the new point
	if (config->spImagesPrefix == NULL) { //Allocation Fails
		*msg = SP_CONFIG_ALLOC_FAIL;
		free(config->spImagesDirectory);
		free(config);
		return NULL;
	}
	*config->spImagesPrefix = '\0';
	config->spImagesSuffix = (char*) malloc(sizeof(char)*1025); //allocating memory for the new point
	if (config->spImagesSuffix == NULL) { //Allocation Fails
		*msg = SP_CONFIG_ALLOC_FAIL;
		free(config->spImagesPrefix);
		free(config->spImagesDirectory);
		free(config);
		return NULL;
	}
	*config->spImagesSuffix = '\0';
	config->spPCAFilename = (char*) malloc(sizeof(char)*1025); //allocating memory for the new point
	if (config->spPCAFilename == NULL) { //Allocation Fails
		*msg = SP_CONFIG_ALLOC_FAIL;
		free(config->spImagesSuffix);
		free(config->spImagesPrefix);
		free(config->spImagesDirectory);
		free(config);
		return NULL;
	}
	strcpy(config->spPCAFilename, "pca.yml");
	config->spExtractionMode = true;
	config->spMinimalGUI = false;
	config->spNumOfImages = -1;
	config->spNumOfFeatures = 100;
	config->spPCADimension = 20;
	config->spNumOfSimilarImages = 1;
	config->spKDTreeSplitMethod = MAX_SPREAD;
	config->spKNN = 1;
	config->spLoggerLevel = 3;
	config->spLoggerFilename = (char*) malloc(sizeof(char)*1025); //allocating memory for the new point
	if (config->spLoggerFilename == NULL) { //Allocation Fails
		*msg = SP_CONFIG_ALLOC_FAIL;
		free(config->spPCAFilename);
		free(config->spImagesSuffix);
		free(config->spImagesPrefix);
		free(config->spImagesDirectory);
		free(config);
		return NULL;
	}
	strcpy(config->spLoggerFilename, "stdout");


	configFile = fopen(filename,"r");
	if (configFile == NULL){
		*msg = SP_CONFIG_CANNOT_OPEN_FILE;
		spConfigDestroy(config);
		printf("The configuration file %s couldn’t be open\n", filename);
		return NULL;
	}

	while(!(feof(configFile)))
	{
		lineCounter++;
		fgets(line, 1024, configFile);
		lineLength = strlen(line);
		varStart= -1;
		varEnd = -1;
		valueStart = -1;
		valueEnd = -1;
		isEqualSign = false;
		isComment = false;
		isValidLine = true;

		charIndex = 0;

		//Phase 1: Searching for the start of variable name
		while(varStart == -1 && charIndex < lineLength && !isComment && isValidLine)
		{

			if(line[charIndex] == '#')
			{
				isComment = true;
			}
			else if(line[charIndex] == '=')
			{
				isValidLine = false;
			}
			else if(!isspace(line[charIndex]))
			{
				varStart = charIndex;
			}

			charIndex++;
		}

		//Phase 2: Searching for the end of variable name
		while(varStart != -1 && varEnd == -1 && charIndex < lineLength && !isComment && isValidLine)
		{

			if(line[charIndex] == '=' || isspace(line[charIndex]))
			{
				varEnd = charIndex;

				if(line[charIndex] == '=')
				{
					isEqualSign = true;
				}

			}

			charIndex++;
		}

		//Phase 3: Searching for the equal sign
		while(varStart != -1 && varEnd != -1 && !isEqualSign && charIndex < lineLength && !isComment && isValidLine)
		{

			if(line[charIndex] == '=')
			{
				isEqualSign = true;
			}
			else if(!isspace(line[charIndex]))
			{
				isValidLine = false;
			}

			charIndex++;
		}

		//Phase 4: Searching for the start of the value
		while(varStart != -1 && varEnd != -1 && isEqualSign && valueStart == -1 && charIndex < lineLength && !isComment && isValidLine)
		{

			if(!isspace(line[charIndex]))
			{
				valueStart = charIndex;
			}

			charIndex++;
		}

		//Phase 5: Searching for the end of the value
		while(varStart != -1 && varEnd != -1 && isEqualSign && valueStart != -1 && valueEnd == -1 && !isComment && isValidLine && charIndex < lineLength)
		{
			if(isspace(line[charIndex]))
			{
				valueEnd = charIndex;
			}
			charIndex++;
		}

		if(valueEnd == -1 && charIndex == lineLength)
		{
			valueEnd = charIndex;
		}

		//Phase 6: Checking if there is excess data
		while(varStart != -1 && varEnd != -1 && isEqualSign && valueStart != -1 && valueEnd != -1 && !isComment && isValidLine && line[charIndex] != '\0')
		{

			if(!isspace(line[charIndex]))
			{
				isValidLine = false;
			}

			charIndex++;
		}

		if(varStart != -1 && varEnd != -1 && isEqualSign && valueStart != -1 && valueEnd != -1 && !isComment && isValidLine)
		{

			int varLen = varEnd - varStart;

			variable = (char*)malloc(sizeof(char)*(varLen + 1)); //allocating memory for the new point
			if (variable == NULL) { //Allocation Fails
				*msg = SP_CONFIG_ALLOC_FAIL;
				spConfigDestroy(config);
				return NULL;
			}

			memcpy(variable, &line[varStart], varLen);
			variable[varLen] = '\0';

			int valLen = valueEnd - valueStart;

			value = (char*) malloc(sizeof(char)*(valLen + 1)); //allocating memory for the new point
			if (value == NULL) { //Allocation Fails
				*msg = SP_CONFIG_ALLOC_FAIL;
				spConfigDestroy(config);
				return NULL;
			}

			memcpy(value, &line[valueStart], (valLen));
			value[valLen] = '\0';

			*msg = SP_CONFIG_SUCCESS;
			spConfigAssignValue(config, variable, value, msg, lineCounter, filename);

			if(*msg == SP_CONFIG_INVALID_INTEGER || *msg == SP_CONFIG_INVALID_STRING || *msg == SP_CONFIG_ALLOC_FAIL){
				spConfigDestroy(config);
				return NULL;
			}

			free(variable);
			free(value);
		}
		else if(!isComment && varStart != -1){
			//ERROR - Invalid line
			*msg = SP_CONFIG_INVALID_STRING;
			printf("File: %s\n Line: %d\n Message: Invalid configuration line\n", filename, lineCounter);
			spConfigDestroy(config);
			return NULL;
		}

	}

	//Checking for missing parameters

	if(*config->spImagesDirectory == '\0'){
		*msg = SP_CONFIG_MISSING_DIR;
		printf("File: %s\nLine: %d\nMessage: Parameter %s is not set\n", filename, lineCounter, "spImagesDirectory");
		spConfigDestroy(config);
		return NULL;
	}

	if(*config->spImagesPrefix == '\0'){
		*msg = SP_CONFIG_MISSING_PREFIX;
		printf("File: %s\nLine: %d\nMessage: Parameter %s is not set\n", filename, lineCounter, "spImagesPrefix");
		spConfigDestroy(config);
		return NULL;
	}

	if(*config->spImagesSuffix == '\0'){
		*msg = SP_CONFIG_MISSING_SUFFIX;
		printf("File: %s\nLine: %d\nMessage: Parameter %s is not set\n", filename, lineCounter, "spImagesSuffix");
		spConfigDestroy(config);
		return NULL;
	}

	if(config->spNumOfImages == -1){
		*msg = SP_CONFIG_MISSING_NUM_IMAGES;
		printf("File: %s\nLine: %d\nMessage: Parameter %s is not set\n", filename, lineCounter, "spNumOfImages");
		spConfigDestroy(config);
		return NULL;
	}

	fclose(configFile);

	*msg = SP_CONFIG_SUCCESS;
	return config;
}
int main(char * args){
//Make sure that the logger was set at the beginning of the main function


//start

// COMMAND LINE ARGUMENT with the Error messages
	char * configFilename;
	if (args == NULL){
		configFilename = "spcbir.config";
	}
	else{
		configFilename = args;
	}
	//“Invalid command line : use -c <config_filename>” - check

//init from config
	SP_CONFIG_MSG spConfigMsg;
	SPConfig configFile = spConfigCreate(configFilename,spConfigMsg);  //should destroy it
	if (spConfigMsg == SP_CONFIG_CANNOT_OPEN_FILE){
		if (configFilename == "spcbir.config" ){
			//“The default configuration file spcbir.config couldn’t be open” +new line + exit?
		}
		else{
			//#2 “The configuration file <filename> couldn’t be open” + new line +exit?
		}
	}


	//variables

	int NumOfImages = spConfigGetNumOfImages(configFile,spConfigMsg);
	char * imagePath =(char*) malloc (1024*sizeof(char));  // should free it
	int spKNN = spConfigGetspKNN(configFile,spConfigMsg);
	int NumOfFeatures =  spConfigGetNumOfFeatures(configFile,spConfigMsg);
	int * imgArray = (int*)malloc (sizeof(int)*configFile,spConfigMsg); // should free it
	int NumOfSimilarImages=spConfigGetNumOfSimilarImages(configFile,spConfigMsg);
	int * SimilarImagesArr = (int*)malloc (NumOfSimilarImages*sizeof(int)); // should free it
	int i=0;
	for (i=0;i<NumOfSimilarImages;i++){
		SimilarImagesArr[i]=0;
	}
	i=0;
	for (i=0; i<NumOfImages;i++){
		imgArray[i]=0;
	}
	i=0;
	SPPoint * queryFeatures = (SPPoint*) malloc (NumOfFeatures*sizeof (SPPoint)); // should free it
	char * queryImgPath =(char*)  malloc (1024*sizeof(char)); // should free it

	int max=0;
	int j=0;
// extract mode?
	if (spConfigIsExtractionMode(configFile,spConfigMsg)){
		// yes:

		//extract features

		// done?

		// no: repeat

		// yes: save to directory

	}
	else{
		//no:

		//	extract from file
	}

// init data structures

// recive command

// query?
	query:

    printf("Please enter an image path:\n");
    scanf("%s", queryImgPath);

// no: exit
if (queryImgPath== '<>'){
	goto ending;
}

// get query features
queryFeatures = getImageFeatures(queryImgPath,int index,int* numOfFeats);
for (i=0;i<NumOfFeatures;i++){
	spKNNSearch( tree,  queryFeatures[i],  spKNN, imgArray);
}
i=0;

// get most similar images
for (i=0;i<NumOfSimilarImages;i++){
	for (j=0;j<NumOfFeatures;j++){
		if (imgArray[j]>imgArray[max]){
			max = j;
		}
	}
	SimilarImagesArr[i]= max;
	imgArray[max] =-1;
}

i=0;

// show results
if(spConfigMinimalGui(configFile,spConfigMsg)){

	for (i=0;i<NumOfSimilarImages;i++){
		spConfigGetImagePath(imagePath, configFile, SimilarImagesArr[i]);
		showImage(imagePath);
		//wait
	}
}
else{
	printf("Best candidates for - %d - are:\n",queryImgPath);
	for (i=0;i<NumOfSimilarImages;i++){
		spConfigGetImagePath(imagePath, configFile, SimilarImagesArr[i]);
		printf ("%d\n",imagePath);

	}
}
goto query;
ending:
// ending
//frees ();

spConfigDestroy (configFilename);
free (imagePath);
free (SimilarImagesArr);
free (queryFeatures);
free (queryImgPath);
free (imgArray);

return 0;




};
bool testGivenConfFile() {
	char imagePath[100], pcaPath[100];
	SP_CONFIG_MSG msg = SP_CONFIG_SUCCESS;
	SPConfig config = spConfigCreate("./unit_tests/spcbirTestCase1.config", &msg);

	ASSERT_TRUE(config != NULL);
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(!strcmp(spConfigGetImagesDirectory(config, &msg), "./images/"));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigGetImagesDirectory(NULL, &msg) == NULL);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);

	ASSERT_TRUE(!strcmp(spConfigGetImagesPrefix(config, &msg), "img"));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigGetImagesPrefix(NULL, &msg) == NULL);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);

	ASSERT_TRUE(!strcmp(spConfigGetImagesSuffix(config, &msg), ".png"));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigGetImagesSuffix(NULL, &msg) == NULL);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);

	ASSERT_TRUE(!strcmp(spConfigGetPCAFilename(config, &msg), "pca.yml"));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigGetPCAFilename(NULL, &msg) == NULL);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);

	ASSERT_TRUE(spConfigIsExtractionMode(config, &msg) == true);
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigIsExtractionMode(NULL, &msg) == false);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);

	ASSERT_TRUE(spConfigMinimalGui(config, &msg) == false);
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigMinimalGui(NULL, &msg) == false);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);

	ASSERT_TRUE(spConfigGetNumOfImages(config, &msg) == 22);
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigGetNumOfImages(NULL, &msg) == -1);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);

	ASSERT_TRUE(spConfigGetNumOfFeatures(config, &msg) == 100);
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigGetNumOfFeatures(NULL, &msg) == -1);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);

	ASSERT_TRUE(spConfigGetPCADim(config, &msg) == 20);
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigGetPCADim(NULL, &msg) == -1);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);

	ASSERT_TRUE(spConfigGetNumOfSimilarImages(config, &msg) == 5);
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigGetNumOfSimilarImages(NULL, &msg) == -1);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);

	ASSERT_TRUE(spConfigGetKNN(config, &msg) == 5);
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigGetKNN(NULL, &msg) == -1);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);

	ASSERT_TRUE(spConfigGetSplitMethod(config, &msg) == MAX_SPREAD);
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigGetSplitMethod(NULL, &msg) == MAX_SPREAD);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);

	ASSERT_TRUE(spConfigGetLoggerLevel(config, &msg) == SP_LOGGER_DEBUG_INFO_WARNING_ERROR_LEVEL);
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigGetLoggerLevel(NULL, &msg) == SP_LOGGER_INFO_WARNING_ERROR_LEVEL);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);

	ASSERT_TRUE(!strcmp(spConfigGetLoggerFilename(config, &msg), "stdout"));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigGetLoggerFilename(NULL, &msg) == NULL);
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_ARGUMENT);


	ASSERT_TRUE(spConfigGetImagePath(imagePath, config, 13) == SP_CONFIG_SUCCESS);
	ASSERT_TRUE(!strcmp(imagePath, "./images/img13.png"));

	ASSERT_TRUE(spConfigGetImagePath(imagePath, config, 22) == SP_CONFIG_INDEX_OUT_OF_RANGE);
	ASSERT_TRUE(spConfigGetImagePath(NULL, config, 1) == SP_CONFIG_INVALID_ARGUMENT);
	ASSERT_TRUE(spConfigGetImagePath(imagePath, NULL, 1) == SP_CONFIG_INVALID_ARGUMENT);
	ASSERT_TRUE(spConfigGetImagePath(NULL, NULL, 1) == SP_CONFIG_INVALID_ARGUMENT);


	ASSERT_TRUE(spConfigGetPCAPath(pcaPath, config) == SP_CONFIG_SUCCESS);
	ASSERT_TRUE(!strcmp(pcaPath, "./images/pca.yml"));

	ASSERT_TRUE(spConfigGetPCAPath(NULL, config) == SP_CONFIG_INVALID_ARGUMENT);
	ASSERT_TRUE(spConfigGetPCAPath(pcaPath, NULL) == SP_CONFIG_INVALID_ARGUMENT);
	ASSERT_TRUE(spConfigGetPCAPath(NULL, NULL) == SP_CONFIG_INVALID_ARGUMENT);

	spConfigDestroy(config);

	return true;
}
bool testHandler() {
	SPConfig config = (SPConfig)calloc(1, spConfigGetConfigStructSize());
	SP_CONFIG_MSG msg = SP_CONFIG_SUCCESS;

	ASSERT_TRUE(config != NULL);

	ASSERT_FALSE(handleVariable(config, "a", 1, "spImagesDirectori", "C:\\MyDocuments\\",
			&msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_LINE);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spImagesDirectory", "C:\\My Documents\\",
			&msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_STRING);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spImagesPrefix", "my image", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_STRING);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spImagesSuffix", ".jpj", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_STRING);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spNumOfImages", "-9000", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_INTEGER);
	msg = SP_CONFIG_SUCCESS;

	// check that a valid int is according to the rules in the forum (next 4 tests)
	ASSERT_TRUE(handleVariable(config, "a", 1, "spNumOfImages", "014", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);
	ASSERT_TRUE(spConfigGetNumOfImages(config, &msg) == 14);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_TRUE(handleVariable(config, "a", 1, "spNumOfImages", "+1", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);
	ASSERT_TRUE(spConfigGetNumOfImages(config, &msg) == 1);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spNumOfImages", "1.0", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_INTEGER);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spNumOfImages", "20 40", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_INTEGER);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spNumOfSimilarImages", "0", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_INTEGER);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spKNN", "aaa", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_INTEGER);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spLoggerLevel", "5", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_INTEGER);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spPCADimension", "9", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_INTEGER);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spPCADimension", "30", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_INTEGER);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spKDTreeSplitMethod", "something", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_KDTREE_SPLIT_METHOD);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spExtractionMode", "tru", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_BOOLEAN);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_FALSE(handleVariable(config, "a", 1, "spMinimalGUI", "fal", &msg));
	ASSERT_TRUE(msg == SP_CONFIG_INVALID_BOOLEAN);
	msg = SP_CONFIG_SUCCESS;

	ASSERT_TRUE(handleVariable(config, "a", 1, "spImagesDirectory", "C:\\Documents\\",
			&msg));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);
	ASSERT_TRUE(!strcmp(spConfigGetImagesDirectory(config, &msg), "C:\\Documents\\"));

	ASSERT_TRUE(handleVariable(config, "a", 1, "spImagesSuffix", ".bmp",
			&msg));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);
	ASSERT_TRUE(!strcmp(spConfigGetImagesSuffix(config, &msg), ".bmp"));

	ASSERT_TRUE(handleVariable(config, "a", 1, "spNumOfFeatures", "80",
			&msg));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);
	ASSERT_TRUE(spConfigGetNumOfFeatures(config, &msg) == 80);

	ASSERT_TRUE(handleVariable(config, "a", 1, "spPCADimension", "19",
			&msg));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);
	ASSERT_TRUE(spConfigGetPCADim(config, &msg) == 19);

	ASSERT_TRUE(handleVariable(config, "a", 1, "spExtractionMode", "true",
			&msg));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);
	ASSERT_TRUE(spConfigIsExtractionMode(config, &msg));

	ASSERT_TRUE(handleVariable(config, "a", 1, "spKDTreeSplitMethod", "INCREMENTAL",
			&msg));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);
	ASSERT_TRUE(spConfigGetSplitMethod(config, &msg) == INCREMENTAL);

	spConfigDestroy(config);
	return true;
}
bool testDefault() {
	char imagePath[100], *loggerFilename = NULL, *pcaFilename = NULL;
	SPConfig config = (SPConfig)calloc(1, spConfigGetConfigStructSize());
	SP_CONFIG_MSG msg = SP_CONFIG_SUCCESS;

	ASSERT_TRUE(config != NULL);

	initConfigToDefault(config);

	ASSERT_TRUE(spConfigGetImagesDirectory(config, &msg) == NULL);
	ASSERT_TRUE(spConfigGetImagesPrefix(config, &msg) == NULL);
	ASSERT_TRUE(spConfigGetImagesSuffix(config, &msg) == NULL);
	ASSERT_TRUE(spConfigGetNumOfImages(config, &msg) == 0);

	ASSERT_TRUE(parameterSetCheck(config, &msg, "a", 1, NULL) == NULL);
	ASSERT_TRUE(msg == SP_CONFIG_MISSING_DIR);
	msg = SP_CONFIG_SUCCESS;

	config = (SPConfig)calloc(1, spConfigGetConfigStructSize());
	ASSERT_TRUE(config != NULL);
	initConfigToDefault(config);
	spConfigSetImagesDirectory(config, duplicateString("./bla/bla/"));
	ASSERT_TRUE(parameterSetCheck(config, &msg, "a", 1, NULL) == NULL);
	ASSERT_TRUE(msg == SP_CONFIG_MISSING_PREFIX);
	msg = SP_CONFIG_SUCCESS;

	config = (SPConfig)calloc(1, spConfigGetConfigStructSize());
	ASSERT_TRUE(config != NULL);
	initConfigToDefault(config);
	spConfigSetImagesDirectory(config, duplicateString("./bla/bla/"));
	spConfigSetImagesPrefix(config, duplicateString("whatever"));
	ASSERT_TRUE(parameterSetCheck(config, &msg, "a", 1, NULL) == NULL);
	ASSERT_TRUE(msg == SP_CONFIG_MISSING_SUFFIX);
	msg = SP_CONFIG_SUCCESS;

	config = (SPConfig)calloc(1, spConfigGetConfigStructSize());
	ASSERT_TRUE(config != NULL);
	initConfigToDefault(config);
	spConfigSetImagesDirectory(config, duplicateString("./bla/bla/"));
	spConfigSetImagesPrefix(config, duplicateString("whatever"));
	spConfigSetImagesSuffix(config, duplicateString(".jpg"));
	ASSERT_TRUE(parameterSetCheck(config, &msg, "a", 1, NULL) == NULL);
	ASSERT_TRUE(msg == SP_CONFIG_MISSING_NUM_IMAGES);
	msg = SP_CONFIG_SUCCESS;

	config = (SPConfig)calloc(1, spConfigGetConfigStructSize());
	ASSERT_TRUE(config != NULL);
	initConfigToDefault(config);
	spConfigSetImagesDirectory(config, duplicateString("./bla/bla/"));
	spConfigSetImagesPrefix(config, duplicateString("whatever"));
	spConfigSetImagesSuffix(config, duplicateString(".jpg"));
	spConfigSetImagesNum(config, 9000);
	ASSERT_TRUE(parameterSetCheck(config, &msg, "a", 1, NULL) == config);
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);

	ASSERT_TRUE(spConfigGetImagePath(imagePath, config, 4444) == SP_CONFIG_SUCCESS);
	ASSERT_TRUE(!strcmp(imagePath, "./bla/bla/whatever4444.jpg"));

	ASSERT_TRUE(checkAndSetDefIfNeeded(&loggerFilename, "stdout", &msg));
	ASSERT_TRUE(!strcmp(loggerFilename, "stdout"));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);
	free(loggerFilename);

	loggerFilename = duplicateString("/tmp/whatever");
	ASSERT_TRUE(checkAndSetDefIfNeeded(&loggerFilename, "stdout", &msg));
	ASSERT_TRUE(!strcmp(loggerFilename, "/tmp/whatever"));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);
	free(loggerFilename);

	ASSERT_TRUE(checkAndSetDefIfNeeded(&pcaFilename, "pca.yml", &msg));
	ASSERT_TRUE(!strcmp(pcaFilename, "pca.yml"));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);
	free(pcaFilename);

	pcaFilename = duplicateString("/tmp/whatever2");
	ASSERT_TRUE(checkAndSetDefIfNeeded(&pcaFilename, "pca.yml", &msg));
	ASSERT_TRUE(!strcmp(pcaFilename, "/tmp/whatever2"));
	ASSERT_TRUE(msg == SP_CONFIG_SUCCESS);
	free(pcaFilename);

	spConfigDestroy(config);
	return true;
}
Exemple #12
0
bool config_funcFailure_nullCheck()
{
	SP_CONFIG_MSG msg;
	char path[100];

	SPConfig config = NULL;

	ASSERT_TRUE(true == runConfigTest(SUCCESS, /* test type */
										1, /* file index */
										0,	/* line of the error */
										&config)
				);


	ASSERT_TRUE(false == spConfigIsExtractionMode(NULL, &msg));
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);

	ASSERT_TRUE(false == spConfigMinimalGui(NULL,&msg));
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);

	ASSERT_TRUE(-1 == spConfigGetNumOfImages(NULL, &msg));
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);

	ASSERT_TRUE(-1 == spConfigGetNumOfFeatures(NULL, &msg));
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);

	ASSERT_TRUE(-1 == spConfigGetPCADim(NULL, &msg));
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);

	msg = spConfigGetImagePath(path, NULL, 1);
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);
	msg = spConfigGetImagePath(NULL, config , 1);
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);

	msg = spConfigGetFeatsPath(path, NULL, 1);
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);
	msg = spConfigGetFeatsPath(NULL, config, 1);
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);

	msg = spConfigGetPCAPath(path,NULL);
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);
	msg = spConfigGetPCAPath(NULL,config);
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);

	ASSERT_TRUE(-1 == spConfigGetNumOfSimilarImages(NULL, &msg));
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);

	spConfigGetKDTreeSplitMethod(NULL, &msg);
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);

	ASSERT_TRUE(-1 == spConfigGetKNN(NULL, &msg));
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);

	spConfigGetLoggerLevel(NULL, &msg);
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);

	msg = spConfigGetLoggerFilename(path,NULL);
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);
	msg = spConfigGetLoggerFilename(NULL,config);
	checkMsgInvalidArg_AndRevertMsgToSuccess(&msg);

	spConfigDestroy(config);

	return true;
}
Exemple #13
0
bool config_success_checkDefaults()
{
	SPConfig config = NULL;
	SP_CONFIG_MSG msg;

	ASSERT_TRUE(true == runConfigTest(SUCCESS, /* test type */
										7, /* file index */
										0,	/* line of the error */
										&config)
				);



	char featurePath[100];
	msg = spConfigGetFeatsPath(featurePath, config, 2);
	ASSERT_TRUE( 0 == strcmp(featurePath, "./images10/myImg2.feats") );
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}

	char imgPath[100];
	msg = spConfigGetImagePath(imgPath, config, 4);
	ASSERT_TRUE( 0 == strcmp(imgPath, "./images10/myImg4.gif") );
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}

	ASSERT_TRUE(SPLIT_METHOD_MAXSPREAD ==
							spConfigGetKDTreeSplitMethod(config, &msg));
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}

	ASSERT_TRUE(1 == spConfigGetKNN(config, &msg));
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}

	char loggerFile[100];
	msg = spConfigGetLoggerFilename(loggerFile, config);
	ASSERT_TRUE( 0 == strcmp(loggerFile, "stdout") );
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}

	ASSERT_TRUE(SP_LOGGER_INFO_WARNING_ERROR_LEVEL ==
							spConfigGetLoggerLevel(config, &msg));
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}

	ASSERT_TRUE(100 == spConfigGetNumOfFeatures(config, &msg));
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}

	ASSERT_TRUE(10 == spConfigGetNumOfImages(config, &msg));
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}

	ASSERT_TRUE(1 == spConfigGetNumOfSimilarImages(config, &msg));
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}

	ASSERT_TRUE(20 == spConfigGetPCADim(config, &msg));
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}

	char pcaPath[100];
	msg = spConfigGetPCAPath(pcaPath, config);
	ASSERT_TRUE( 0 == strcmp(pcaPath, "./images10/pca.yml") );
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}

	ASSERT_TRUE( true == spConfigIsExtractionMode(config, &msg));
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}


	ASSERT_TRUE( false == spConfigMinimalGui(config, &msg));
	if(!checkMsgSuccess_AndRevertMsgToNonSuccess(&msg))
	{
		printf("error line %d", __LINE__);
		return false;
	}


	spConfigDestroy(config);

	return true;
}
Exemple #14
0
int main(int argc, char *argv[]) {
	SPConfig config = NULL;						    // hold configuration parameters
	char config_filename[CONFIG_FILE_PATH_SIZE];    // the configuration file name
	int knn;										// the number of similar features in each image to find (spKNN from configuration file)
	int num_of_similar_images_to_find;              // the number of similar images (to the query) to find (from configuration file)
	int split_method;                               // holds an int representing the split method: 0=RANDOM, 1= MAX_SPREAD,  2=INCREMENTAL
	bool minGui = false;                            // value of the system variable MinimalGui
	bool extraction_mode;							// indicates if extraction mode on or off
	int num_of_images = 0;   					    // number of images in the directory given by the user in the configuration file
	char** all_images_paths = NULL;					// array with the paths to all the images
	
	int last_extracted_feature = 0;  				// helper - holds the last feature extracted in order to free all extracted features on error
	SPPoint** features_per_image = NULL;   			// helper - holds the features for each images
	int* num_of_features_per_image = NULL;			// holds number of features extracted for each image
	
	char query_image[CONFIG_FILE_PATH_SIZE];        // the query image 
	SPPoint* query_features = NULL;				    // all query features
	int query_num_of_features;					    // number of features in query image
	
	KDTreeNode kd_tree = NULL;						// array holds a KDTree for the images
	int* closest_images = NULL;  				    // array holds the spNumOfSimilarImages indexes of the closest images to the query image
	int print_result;   							// holds the result of the call to PrintMinGuiFalse
	
	int retval = 0;									 // return value - default 0 on success
	char string_holder[CONFIG_FILE_PATH_SIZE];       // helper to hold strings
	sp::ImageProc *improc = NULL;
	SP_CONFIG_MSG msg;
	int i;
	int j;
	int n;

	// validate command line arguments:
	// cmd line arguments are ok if there was no arguments specified (argc == 1) or two arguments specified ( -c and filname)
	if (argc != 3 && argc != 1) {
		printf(INVALID_CMD_LINE_MSG);
		return -1;
	}

	if (argc == 1) {
		strcpy(config_filename, DEFAULT_CONFIG_FILENAME);
		config = spConfigCreate(config_filename, &msg);
		if (msg == SP_CONFIG_CANNOT_OPEN_FILE) {
			printf(ERROR_OPENING_DEFAULT_CONFIG_FILE_MSG, DEFAULT_CONFIG_FILENAME);
		}

		if (msg != SP_CONFIG_SUCCESS) {
			retval = -1;
			goto err; // error is printed inside spConfigCreate
		}
	}
	else { // argc == 3

		// check that second argument is the -c flag
		if (strcmp(argv[1], CMD_LINE_CONFIG_FILENAME_FLAG) != 0) {
			printf(INVALID_CMD_LINE_MSG);
			retval = -1;
			goto err;
		}
	
		strcpy(config_filename, argv[2]);
		config = spConfigCreate(config_filename, &msg);
		if (msg == SP_CONFIG_CANNOT_OPEN_FILE) {
			printf(ERROR_OPENING_CONFIG_FILE_MSG, config_filename);
		}

		if (msg != SP_CONFIG_SUCCESS) {
			retval = -1;
			goto err; // error is printed inside spConfigCreate
		}
	}
	
	// initiate from config
	if (initFromConfig(config, &num_of_images, &num_of_similar_images_to_find, &knn, &split_method, &extraction_mode, &minGui, &all_images_paths) == -1 ) {
		retval = -1; 
		goto err; // error is printed inside initFromConfig 
	}


	// initiate image proc
	improc = new sp::ImageProc(config);

	// extract images features
	if ((num_of_features_per_image = (int*)malloc(sizeof(*num_of_features_per_image) * num_of_images)) == NULL) {
		spLoggerPrintError(ALLOCATION_FAILURE_MSG, __FILE__, __func__, __LINE__);
		retval = -1;
		goto err;
	}

	spLoggerPrintInfo(CHECK_EXTRACTION_MODE_INFO_LOG);
	if (extraction_mode) {	// extraction mode is chosen
		spLoggerPrintMsg(USE_EXTRACTION_MODE_LOG);
		spLoggerPrintInfo(EXTRACT_IMAGES_FEATURES_INFO_LOG);

		if ((features_per_image = (SPPoint**)malloc(sizeof(*features_per_image) * num_of_images)) == NULL) {
			spLoggerPrintError(ALLOCATION_FAILURE_MSG, __FILE__, __func__, __LINE__);
			retval = -1;
			goto err;
		}

		// extract each image features and write them to file
		for (i=0; i < num_of_images; i++) {	
			// extract image features
			if ((features_per_image[i] = improc->getImageFeatures(all_images_paths[i], i, &(num_of_features_per_image[i]))) == NULL) {
				last_extracted_feature = i;
				retval = -1;
				goto err; // error is printed inside  getImageFeatures
			}
		}

		if (saveToDirectory(config, features_per_image, num_of_features_per_image, num_of_images) == -1) {
			retval = -1;
			goto err; // error is printed inside  saveToDirectory
		}
	}

	else { // not extraction mode
		spLoggerPrintMsg(USE_NOT_EXTRACTION_MODE_LOG);
		spLoggerPrintInfo(READ_FEATURES_FROM_FILE_LOG);

		if ((features_per_image = extractFromFiles(config, num_of_features_per_image, num_of_images)) == NULL) {
			retval = -1;
			goto err; // error is printed inside  extractFromFiles
		}
	}
	
	if ((kd_tree = initiateDataStructures(features_per_image, num_of_features_per_image, num_of_images, split_method)) == NULL) {
		retval = -1;
		goto err; // error is printed inside initiateDataStructures
	}

	query:
	while(1) {
		// get a query image from the user
		printf(ENTER_AN_IMAGE_MSG);
		fflush(NULL);
		scanf("%s",query_image);

		// exit if user asked
		if (strcmp (query_image,EXIT_SIGN) == 0) {
			printf(EXIT_MSG);
			fflush(NULL);
			goto err; // free memory and quit 
		}

		if( access( query_image, F_OK ) == -1 ) {
		    printf(FILE_DOESNT_EXIST, query_image);
			goto query;
		}

		// extract query image features
		spLoggerPrintMsg(EXTRACT_QUERY_IMAGE_FEATURES_LOG);
		if ((query_features = improc->getImageFeatures(query_image, num_of_images, &query_num_of_features)) == NULL) {
			retval = -1;
			goto err_inside_loop; // error log is printed inside getImageFeatures	
		}
		
		// print debug log
		if ((n = sprintf(string_holder, NUM_OF_EXTRACTED_FEATURES_DEBUG_LOG, query_num_of_features)) < 0) {
			spLoggerPrintError(GENERAL_ERROR_MSG, __FILE__, __func__, __LINE__);
			retval = -1;
			goto err_inside_loop;
		}

		spLoggerPrintDebug(string_holder, __FILE__, __func__, __LINE__);
		
		//  print log message
		if ((n = sprintf(string_holder, SEARCING_SIMILAR_IMAGES_MSG, num_of_similar_images_to_find)) < 0) {
			spLoggerPrintError(GENERAL_ERROR_MSG, __FILE__, __func__, __LINE__);
			retval = -1;
			goto err_inside_loop;
		}

		spLoggerPrintMsg(string_holder);

		// find similar images to the query image
		closest_images = getKClosestImages(num_of_similar_images_to_find, knn, query_features,
										   kd_tree, query_num_of_features, num_of_images);

		if (closest_images == NULL) { 
			retval = -1;
			goto err_inside_loop; // error is printed to inside getKClosestImages
		}

		// show (display) closest_images images

		//need to show images
		if (minGui==true){ 
			for (i=0; i<num_of_similar_images_to_find; i++){
				//get file path of the images by the indexes in closest_images
				improc->showImage(all_images_paths[closest_images[i]]);
			}
		}

		// i.e. minGui==false,  just need to print images path
		else{
			print_result = PrintMinGuiFalse(query_image, num_of_similar_images_to_find, all_images_paths, closest_images);
			if (print_result == 0) {
				retval = -1;
				goto err_inside_loop; // error is printed inside 
			}

		}
		// free memory before entering the loop again
		
		free(closest_images);
		if (query_features != NULL) {
			for (i=0; i<query_num_of_features; i++) {
				spPointDestroy(query_features[i]);
			}
			free(query_features);
		}
	}

	err_inside_loop:	
		free(closest_images);
		// free query_features
		if (query_features != NULL) {
			for (i=0; i<query_num_of_features; i++) {
				spPointDestroy(query_features[i]);
			}
			free(query_features);
		}

	// done - destroy logger and free everything 
	err:
		spLoggerDestroy();

		// free the kd tree
		DestroyKDTreeNode(kd_tree);
		spConfigDestroy(config);

		// free all images paths
		if (all_images_paths != NULL) {
			for (i = 0; i < num_of_images; i ++) {
				free(all_images_paths[i]);
			}
			free(all_images_paths);
		}

		if (features_per_image != NULL) {
			// free features_per_image
			for (i = 0; i < last_extracted_feature; i ++) {
				if (features_per_image[i] != NULL) {
					for (j = 0; j < num_of_features_per_image[i]; j++) {
						spPointDestroy(features_per_image[i][j]);
					}
				}
			}
			free(features_per_image);
		}
		free(num_of_features_per_image); // must be freed after features_per_image
		if (improc != NULL) {
			delete improc;
		}

	return retval;
}