1 /*****************************************************************************************
2 * Copyright (c) 2006 Hewlett-Packard Development Company, L.P.
3 * Permission is hereby granted, free of charge, to any person obtaining a copy of
4 * this software and associated documentation files (the "Software"), to deal in
5 * the Software without restriction, including without limitation the rights to use,
6 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
7 * Software, and to permit persons to whom the Software is furnished to do so,
8 * subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
16 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
17 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 *****************************************************************************************/
19 
20 /************************************************************************
21  * SVN MACROS
22  *
23  * $LastChangedDate: 2008-07-18 15:00:39 +0530 (Fri, 18 Jul 2008) $
24  * $Revision: 561 $
25  * $Author: sharmnid $
26  *
27  ************************************************************************/
28 /************************************************************************
29 * FILE DESCR: Implementation for LTKShapeRecoUtil
30 *
31 * CONTENTS:
32 *			 getAbsolutePath
33 * 			 isProjectDynamic
34 *			 initializePreprocessor
35 *			 deletePreprocessor
36 *			 unloadPreprocessor
37 *			 readInkFromFile
38 *			 checkEmptyTraces
39 *			 shapeFeatureVectorToFloatVector
40 *			 shapeFeatureVectorToIntVector
41 *
42 * AUTHOR:     Saravanan R.
43 *
44 * DATE:       January 23, 2004
45 * CHANGE HISTORY:
46 * Author       Date            Description of change
47 ************************************************************************/
48 
49 #ifdef _WIN32
50 #include "windows.h"
51 #endif
52 
53 #include "LTKInc.h"
54 #include "LTKLoggerUtil.h"
55 #include "LTKTrace.h"
56 #include "LTKMacros.h"
57 #include "LTKErrors.h"
58 #include "LTKException.h"
59 #include "LTKErrorsList.h"
60 #include "LTKInkFileReader.h"
61 #include "LTKTraceGroup.h"
62 #include "LTKStringUtil.h"
63 #include "LTKConfigFileReader.h"
64 #include "LTKShapeRecoUtil.h"
65 #include "LTKShapeFeatureExtractor.h"
66 #include "LTKShapeFeature.h"
67 #include "LTKPreprocessorInterface.h"
68 
69 
70 //FN_PTR_DELETE_SHAPE_FTR_PTR LTKShapeRecoUtil::m_deleteShapeFeatureFunc = NULL;
71 
72 /**********************************************************************************
73 * AUTHOR		: Saravanan. R
74 * DATE			: 11-01-2007
75 * NAME			: LTKShapeRecoUtil
76 * DESCRIPTION	: Constructor
77 * ARGUMENTS		: None
78 * RETURNS		: None
79 * NOTES			:
80 * CHANGE HISTROY
81 * Author			Date				Description
82 *************************************************************************************/
LTKShapeRecoUtil()83 LTKShapeRecoUtil::LTKShapeRecoUtil()
84 {
85     LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<
86         "Entered LTKShapeRecoUtil::LTKShapeRecoUtil()"  <<endl;
87     LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<
88         "Exiting LTKShapeRecoUtil::LTKShapeRecoUtil()"  <<endl;
89 }
90 
91 /**********************************************************************************
92  * AUTHOR		: Saravanan. R
93  * DATE			: 31-01-2007
94  * NAME			: LTKShapeRecoUtil
95  * DESCRIPTION	: Destructor
96  * ARGUMENTS		: None
97  * RETURNS		: None
98  * NOTES			:
99  * CHANGE HISTROY
100  * Author			Date				Description
101  *************************************************************************************/
~LTKShapeRecoUtil()102 LTKShapeRecoUtil::~LTKShapeRecoUtil()
103 {
104 }
105 
106 /**********************************************************************************
107  * AUTHOR		: Saravanan. R
108  * DATE			: 11-01-2007
109  * NAME			: getAbsolutePath
110  * DESCRIPTION	: This method is used to convert the relative path to the absolute path
111  * ARGUMENTS		: pathName     : string : Holds the path of the training file
112  *				  lipiRootPath : string : Holds the lipiroot path
113  *
114  * RETURNS		: SUCCESS only
115  * NOTES			:
116  * CHANGE HISTROY
117  * Author			Date				Descriptionh
118  *************************************************************************************/
getAbsolutePath(const string & inputPath,const string & lipiRootPath,string & outPath)119 int LTKShapeRecoUtil::getAbsolutePath (const string& inputPath,
120         const string& lipiRootPath,
121         string& outPath)
122 {
123     LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<
124         "Entered LTKShapeRecoUtil::getAbsolutePath()"  <<endl;
125 
126     outPath = "";
127     vector<string> tokens;
128 
129     int returnStatus = SUCCESS;
130 
131     //Split the path name into number of tokens based on the delimter
132     returnStatus = LTKStringUtil::tokenizeString(inputPath,  "\\/",  tokens);
133 
134     if(returnStatus != SUCCESS)
135     {
136         LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<"Error: " <<
137             getErrorMessage(returnStatus) <<
138             " LTKShapeRecoUtil::getAbsolutePath()"  <<endl;
139 
140         LTKReturnError(returnStatus);
141     }
142 
143     //The first token must be the $LIPI_ROOT. Otherwise return from the function
144     if (tokens[0] != LIPIROOT)
145     {
146 		outPath = inputPath;
147         return SUCCESS;
148     }
149 
150     //Store the Environment variable into the tokens
151     tokens[0] = lipiRootPath;
152 
153     //Reinitialize the outPath
154     for(int i=0 ; i < tokens.size() ; i++)
155     {
156         outPath += tokens[i] + SEPARATOR;
157     }
158 
159     // Erase the last character '\'
160     outPath.erase(outPath.size()-1,1);
161 
162     LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<
163         "Exiting LTKShapeRecoUtil::getAbsolutePath()"  <<endl;
164 
165     return SUCCESS;
166 }
167 
168 
169 /***********************************************************************************
170  * AUTHOR		: Saravanan. R
171  * DATE			: 19-01-2007
172  * NAME			: isProjectDynamic
173  * DESCRIPTION	: This method reads the project.cfg to find whether the project
174  *				  is dynamic or not
175  * ARGUMENTS		: configFilePath : string : Holds the path of the project.cfg
176  *				  numShapes : unsigned short : Holds the NumShapes value from config file
177  *				  returnStauts : int : Holds SUCCESS or ErrorValues
178  *				  strNumShapes : string : Holds the NumShapes value from config file
179  * RETURNS		: true : if the project was dynamic
180  *				  false : if the project was dynamic
181  * NOTES			:
182  * CHANGE HISTROY
183  * Author			Date				Description
184  *************************************************************************************/
isProjectDynamic(const string & configFilePath,unsigned short & numShapes,string & strNumShapes,bool & outIsDynamic)185 int LTKShapeRecoUtil::isProjectDynamic(const string& configFilePath,
186         unsigned short& numShapes,
187         string& strNumShapes,
188         bool& outIsDynamic )
189 {
190     LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<
191         "Entering LTKShapeRecoUtil::isProjectDynamic()"  <<endl;
192 
193     //Specifies the project is dynamic or not
194     outIsDynamic = false;
195 
196     string numShapesCfgAttr = "";
197 
198     //As numshapes was unsigned short we use this tempNumShapes as integer,
199     //it is used for checking whether it is less than 0
200     int tempNumShapes = 0;
201     LTKConfigFileReader* projectCfgAttrs = NULL;
202     string valueFromCFG = "0";
203 
204     int errorCode = SUCCESS;
205 
206     try
207     {
208         //Read the config entries
209         projectCfgAttrs = new LTKConfigFileReader(configFilePath);
210         errorCode = projectCfgAttrs->getConfigValue(PROJECT_CFG_ATTR_NUMSHAPES_STR, numShapesCfgAttr);
211 
212         //Checking whether the numshapes was dynamic
213         if(errorCode != SUCCESS)
214         {
215             LOG( LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: " <<
216                 "NumShapes should be set to  dynamic or the number of training classes"  <<
217                 " LTKShapeRecoUtil::isProjectDynamic()"  <<endl;
218 
219             LTKReturnError(errorCode);
220 
221         }
222         else if( LTKSTRCMP(numShapesCfgAttr.c_str(), DYNAMIC) == 0 )
223         {
224             //Numshapes was dynamic
225             outIsDynamic = true;
226             tempNumShapes = 0;
227         }
228         else
229         {
230             bool isPositiveInteger=true;
231 
232             valueFromCFG = numShapesCfgAttr;
233 
234             for(int charIndex=0 ; charIndex < valueFromCFG.size() ; ++charIndex)
235             {
236                 if(!(valueFromCFG[charIndex]>='0' && valueFromCFG[charIndex]<='9'))
237                 {
238                     isPositiveInteger=false;
239                     break;
240                 }
241             }
242 
243 
244 
245             if(!isPositiveInteger)
246             {
247                 LOG( LTKLogger::LTK_LOGLEVEL_ERR)<<"Error" <<
248                     "NumShapes should be set to  dynamic or the number of training classes"  <<
249                     " LTKShapeRecoUtil::isProjectDynamic()"  <<endl;
250 
251                 LTKReturnError(EINVALID_NUM_OF_SHAPES);
252             }
253             else
254             {
255                 tempNumShapes = atoi(valueFromCFG.c_str());
256                 if(tempNumShapes==0)
257                 {
258                     LOG( LTKLogger::LTK_LOGLEVEL_ERR)<<"Error" <<
259                         "NumShapes should be set to  dynamic or the number of training classes"  <<
260                         " LTKShapeRecoUtil::isProjectDynamic()"  <<endl;
261 
262                     LTKReturnError(EINVALID_NUM_OF_SHAPES);
263                 }
264                 else
265                 {
266                     //Numshapes was not dynamic
267                     outIsDynamic = false;
268                 }
269 
270             }
271 
272         }
273 
274         numShapes = tempNumShapes;
275         strNumShapes = valueFromCFG;
276         LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<
277             "NumShapes in the project is " <<  valueFromCFG <<endl;
278 
279 
280     }
281     catch(LTKException e)
282     {
283         delete projectCfgAttrs;
284         throw e;
285     }
286 
287     delete projectCfgAttrs;
288     LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<
289         "Exiting LTKShapeRecoUtil::isProjectDynamic()"  <<endl;
290 
291     return SUCCESS;
292 }
293 
294 
295 
296 /**********************************************************************************
297  * AUTHOR		: Saravanan. R
298  * DATE			: 30-01-2007
299  * NAME          : readInkFromFile
300  * DESCRIPTION   : This method reads the Ink file and check from empty traces
301  * ARGUMENTS     : string : Holds the Path of the unipen ink file
302 string : Holds the Path of the lipi root
303  * RETURNS       :
304  * NOTES         :
305  * CHANGE HISTROY
306  * Author            Date                Description
307  *************************************************************************************/
readInkFromFile(const string & path,const string & lipiRootPath,LTKTraceGroup & inTraceGroup,LTKCaptureDevice & captureDevice,LTKScreenContext & screenContext)308 int LTKShapeRecoUtil::readInkFromFile(const string& path, const string& lipiRootPath,
309         LTKTraceGroup& inTraceGroup,
310         LTKCaptureDevice& captureDevice,
311         LTKScreenContext& screenContext)
312 {
313     LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<
314         "Entering LTKShapeRecoUtil::readInkFromFile()"  <<endl;
315 
316     //inTraceGroup.emptyAllTraces();
317 
318     string tempPath = path;
319 
320     //Check and convert Relative path to Absolute path
321     string outPath = "";
322     getAbsolutePath(tempPath, lipiRootPath, outPath);
323 
324     //Print the path name
325     cout << outPath << endl;
326 
327     //Read Ink file to inTraceGroup
328     //    errorVal = LTKInkFileReader::readUnipenInkFile(tempPath,inTraceGroup,captureDevice,screenContext);
329     int errorCode = LTKInkFileReader::readUnipenInkFile(outPath,inTraceGroup,captureDevice,screenContext);
330 
331     if (errorCode != SUCCESS)
332     {
333         LOG( LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: " <<
334             getErrorMessage(errorCode) <<
335             " LTKShapeRecoUtil::readInkFromFile()"  <<endl;
336 
337         LTKReturnError(errorCode);
338     }
339 
340     //Check for empty traces in inTraceGroup
341 
342     if (inTraceGroup.containsAnyEmptyTrace())
343     {
344         LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<"Error: " <<
345             "TraceGroup has empty traces" <<
346             " LTKShapeRecoUtil::readInkFromFile()"  <<endl;
347 
348         LTKReturnError(EEMPTY_TRACE);
349     }
350 
351 
352     LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<
353         "Exiting LTKShapeRecoUtil::readInkFromFile()"  <<endl;
354 
355     return SUCCESS;
356 }
357 
358 /**********************************************************************************
359  * AUTHOR		: Saravanan. R
360  * DATE			: 30-01-2007
361  * NAME          : checkEmptyTraces
362  * DESCRIPTION   : This method checks for empty traces
363  * ARGUMENTS     : inTraceGroup : LTKTraceGroup :
364  * RETURNS       : 1 if it contains empty trace group, 0 otherwise
365  * NOTES         :
366  * CHANGE HISTROY
367  * Author            Date                Description
368  *************************************************************************************/
369 /*
370 int LTKShapeRecoUtil::checkEmptyTraces(const LTKTraceGroup& inTraceGroup)
371 {
372     LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<
373         "Entering LTKShapeRecoUtil::checkEmptyTraces()"  <<endl;
374 
375     int returnVal = SUCCESS;
376 
377     vector<LTKTrace> tracesVec = inTraceGroup.getAllTraces();  //traces in trace group
378 
379     int numTraces = tracesVec.size();
380 
381     int numTracePoints = 0;
382 
383     LTKTrace trace;							//	a trace of the trace group
384 
385     LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<  "numTraces = " << numTraces  <<endl;
386 
387 
388     for(int traceIndex=0; traceIndex < numTraces; ++traceIndex)
389     {
390         trace = tracesVec.at(traceIndex);
391 
392         numTracePoints=trace.getNumberOfPoints();
393 
394         if(numTracePoints==0)
395         {
396             LOG( LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<<
397                 getError(EEMPTY_TRACE) <<
398                 "Exiting LTKShapeRecoUtil::checkEmptyTraces()"  <<endl;
399             LTKReturnError(EEMPTY_TRACE);
400         }
401 
402     }
403 
404     LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<
405         "Exiting LTKShapeRecoUtil::checkEmptyTraces()"  <<endl;
406     return SUCCESS;
407 }
408 */
convertHeaderToStringStringMap(const string & header,stringStringMap & headerSequence)409 int LTKShapeRecoUtil::convertHeaderToStringStringMap(const string& header, stringStringMap& headerSequence)
410 {
411     LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<
412         "Entering LTKShapeRecoUtil::convertHeaderToStringStringMap()"  <<endl;
413 
414     vector<string> tokens;
415     vector<string> strList;
416 
417     int returnStatus = SUCCESS;
418 
419     LTKStringUtil::tokenizeString(header, "<>", tokens);
420 
421     for(int i=0 ; i < tokens.size(); ++i)
422     {
423         returnStatus = LTKStringUtil::tokenizeString(tokens[i],  "=",  strList);
424         if(returnStatus != SUCCESS)
425         {
426             LOG( LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: " <<
427                 getErrorMessage(returnStatus) <<
428                 " LTKShapeRecoUtil::convertHeaderToStringStringMap()"  <<endl;
429             LTKReturnError(returnStatus);
430         }
431         if(strList.size() == 2)
432         {
433             headerSequence[strList[0]] = strList[1];
434         }
435     }
436     LOG( LTKLogger::LTK_LOGLEVEL_DEBUG)<<
437         "Exiting LTKShapeRecoUtil::convertHeaderToStringStringMap()"  <<endl;
438 
439     return SUCCESS;
440 }
441 
442 
443 /**********************************************************************************
444 * AUTHOR		: Saravanan. R
445 * DATE			: 14-03-2007
446 * NAME          : shapeFeatureVectorToFloatVector
447 * DESCRIPTION   : This method converts the ShapeFeatureVector to float vector
448 * ARGUMENTS     :
449 * RETURNS       :
450 * NOTES         :
451 * CHANGE HISTROY
452 * Author            Date                Description
453 *************************************************************************************/
shapeFeatureVectorToFloatVector(const vector<LTKShapeFeaturePtr> & shapeFeature,floatVector & outFloatVector)454 int LTKShapeRecoUtil::shapeFeatureVectorToFloatVector(const vector<LTKShapeFeaturePtr>& shapeFeature,
455                                                    floatVector& outFloatVector)
456 {
457     int returnVal = SUCCESS;
458 
459 	//Iterators for the LTKShapeFeature
460 	vector<LTKShapeFeaturePtr>::const_iterator shapeFeatureIter = shapeFeature.begin();
461 	vector<LTKShapeFeaturePtr>::const_iterator shapeFeatureIterEnd = shapeFeature.end();
462 
463 
464 	vector<float> shapeFeatureFloatvector;
465 
466 	for(; shapeFeatureIter != shapeFeatureIterEnd; ++shapeFeatureIter)
467 	{
468 
469 		//Convert the shapefeature to float vector
470 		returnVal = (*shapeFeatureIter)->toFloatVector(shapeFeatureFloatvector);
471 
472         if ( returnVal != SUCCESS )
473         {
474             break;
475         }
476 
477 		outFloatVector.insert(outFloatVector.end(),
478 			                  shapeFeatureFloatvector.begin(),
479 							  shapeFeatureFloatvector.end());
480 
481 		shapeFeatureFloatvector.clear();
482 
483 	}
484 
485 	return returnVal;
486 }