1 ////////////////////////////////////////////////////////
2 // Name : globalFnc.cpp
3 // Purpose : Global function definitions for EDISON
4 // command prompt.
5 // Author : Chris M. Christoudias
6 // Modified by
7 // Created : 03/20/2002
8 // Copyright: (c) Chris M. Christoudias
9 // Version : v0.1
10 ////////////////////////////////////////////////////////
11
12 #include "defs.h"
13 #include "error.h"
14 #include "parser.h"
15 #include "imfilt.h"
16 #include "edison.h"
17 #include <stdio.h>
18 #include <stdarg.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 ////////////////////////////////////////////////////
23 //define global flags
24 ////////////////////////////////////////////////////
25
26 //segmentation flags
27 bool CmCSynergistic = false;
28 bool CmCGradWinChanged = false;
29 bool CmCMixtureChanged = false;
30 bool CmCUseCustomWeightMap = false;
31
32 //system flags
33 bool CmCImageDefined = false;
34 bool CmCMapDefined = false;
35 bool CmCDisplayProgress = false;
36
37 //edge detection flags
38 bool CmCRankMapDefined = false;
39 bool CmCConfMapDefined = false;
40
41 ////////////////////////////////////////////////////////
42 //Declare global EDISON wrapper class object
43 ////////////////////////////////////////////////////////
44
45 EDISON edison;
46
47 ////////////////////////////////////////////////////////
48 //Display prompt function
49 ////////////////////////////////////////////////////////
50
CmCPrompt(const char * PromptStr,...)51 void CmCPrompt(const char *PromptStr, ...)
52 {
53 //obtain argument list using ANSI standard...
54 va_list argList;
55 va_start(argList, PromptStr);
56
57 //print the output string to stderr using
58 if(CmCDisplayProgress) vfprintf(stdout, PromptStr, argList);
59 va_end(argList);
60
61 //done.
62 return;
63 }
64
65 ////////////////////////////////////////////////////////
66 //Identity (Look-up Table Functions) Functions
67 ////////////////////////////////////////////////////////
68
69 //************************
70 //identify command type
71 //************************
72
Command(char * cmd)73 int Command(char *cmd)
74 {
75 int i;
76 for(i = 0; i < CMD_NUM; i++)
77 {
78 if(!strcmp(cmd, CMD_LIST[i])) return i;
79 }
80 return UNKNOWN_COMMAND;
81 }
82
83 //************************
84 //identify command type
85 //************************
86
CommandType(int cmdId)87 int CommandType(int cmdId)
88 {
89 return CMD_TYPE_LIST[cmdId];
90 }
91
92 //************************
93 //identify parameter
94 //************************
95
Parameter(char * param)96 int Parameter(char *param)
97 {
98 int i;
99 for(i = 0; i < PARAM_NUM; i++)
100 {
101 if(!strcmp(param, PARAM_LIST[i])) return i;
102 }
103 return UNKNOWN_PARAMETER;
104 }
105
106 //************************
107 //identify custom curve list
108 //************************
109
CustomCurve(char * curve)110 int CustomCurve(char *curve)
111 {
112 int i;
113 for(i = 0; i < CUST_CURVE_NUM; i++)
114 {
115 if(!strcmp(curve, CUST_CURVE_LIST[i])) return i;
116 }
117 return UNKNOWN_CURVE;
118 }
119
120 //************************
121 //identify input type
122 //************************
123
InputType(char * inputtype)124 int InputType(char *inputtype)
125 {
126 int i;
127 for(i = 0; i < INPUTTYPE_NUM; i++) {
128 if(!strcmp(inputtype, INPUTTYPE_LIST[i])) return i;
129 }
130 return INPUT_UNKNOWN;
131 }
132
133 //************************
134 //identify output type
135 //************************
136
OutputType(char * outputtype)137 int OutputType(char *outputtype)
138 {
139 int i;
140 for(i = 0; i < OUTPUTTYPE_NUM; i++) {
141 if(!strcmp(outputtype, OUTPUTTYPE_LIST[i])) return i;
142 }
143 return OUTPUT_UNKNOWN;
144 }
145
146 //************************
147 //identify file type
148 //************************
149
FileType(char * filetype)150 int FileType(char *filetype)
151 {
152 int i;
153 for(i = 0; i < FILETYPE_NUM; i++) {
154 if(!strcmp(filetype, FILETYPE_LIST[i])) return i;
155 }
156 return FILE_UNKNOWN;
157 }
158
159 ////////////////////////////////////////////////////////
160 //Report Errors
161 ////////////////////////////////////////////////////////
162
Report(CmCError * error,char * filename,CmCParser * srcParser)163 void Report(CmCError *error, char *filename, CmCParser *srcParser)
164 {
165
166 //obtain error code
167 int errorCode = error->errorCode_;
168
169 //report invalid file error
170 if(errorCode == SYN_INVALID_FILE) {
171 fprintf(stderr, "EDISON Fatal Error: Cannot open file '%s'.\n", filename);
172 fprintf(stderr, "Permission denied or file does not exist.\n");
173 return;
174 }
175
176 //obtain line number and token string of bad token
177 int lineNumber = error->token_->lineNumber_;
178 char *token = error->token_->token_;
179
180 //***************************************
181 //report syntax error
182 //***************************************
183
184 //check if out of bounds error
185 if(errorCode == SYN_BOUNDS_ERROR) {
186 fprintf(stderr, "Out of bounds error in file '%s'.\n", filename);
187 fprintf(stderr, "Line %d (parameter %s) Error: %s\n", lineNumber, token,
188 boundsTable[BOUNDS_TABLE[Parameter(token)]]);
189 return;
190 }
191
192 //check for unsupported file formats
193 if(errorCode == SYN_UNSUPPORTED_FILETYPE) {
194 fprintf(stderr, "Version incompatability error:\n");
195 fprintf(stderr, "Line %d (argument '%s') Error: %s\n", lineNumber, token, ErrorMsgTable[errorCode-1]);
196 return;
197 }
198
199 //decrement error code to index the error message
200 //table correctly (starting from 0 instead of 1)
201 errorCode--;
202
203 if(errorCode < SYN_INVALID_PARAMCMD) {
204 //report syntax error
205 fprintf(stderr, "Syntax error in file '%s':\n", filename);
206 fprintf(stderr, "Line %d (confused by '%s') Error: %s\n", lineNumber, token, ErrorMsgTable[errorCode]);
207 } else if (errorCode < SYN_ASSIGN_INVALID_ARG) {
208 //report assignment error
209 fprintf(stderr, "Assignment error in file '%s':\n", filename);
210 fprintf(stderr, "Line %d (parameter %s) Error: %s\n", lineNumber, token, ErrorMsgTable[errorCode]);
211 }
212
213 //***************************************
214 //report run-time error
215 //***************************************
216
217 //check if parameter is missing
218 if(errorCode == (EXE_MISSING_PARAM-1)) {
219 //report missing parameter
220 fprintf(stderr, "Run-time error cause while running script '%s':\n", filename);
221 fprintf(stderr, "Line %d Fatal Error: Parameter '%s' is not specified.\n", lineNumber, token);
222 delete error->token_;
223 return;
224 }
225
226 if(errorCode >= SYN_ASSIGN_INVALID_ARG) {
227 //report run-time error
228 fprintf(stderr, "Run-time error caused while running script '%s':\n", filename);
229 fprintf(stderr, "Line %d (at '%s') Fatal Error: %s\n", lineNumber, token, ErrorMsgTable[errorCode]);
230 }
231
232 //done.
233 return;
234 }
235
236 ////////////////////////////////////////////////////////
237 //Check Syntax
238 ////////////////////////////////////////////////////////
239
240 //************************
241 //get token set for a specified command type
242 //************************
243
GetTokenSet(int cmdId,CmCToken ** tokenSet,CmCParser * synParser)244 int GetTokenSet(int cmdId, CmCToken **tokenSet, CmCParser *synParser)
245 {
246 //obtain token count
247 int tokenCount, cmdTypeId = CommandType(cmdId);
248 switch(cmdTypeId)
249 {
250 case CMD_IO :
251 switch(cmdId)
252 {
253 case CMD_SAVE : tokenCount = 10; break;
254 case CMD_LOAD : tokenCount = 8; break;
255 default : tokenCount = 4; break;
256 }
257 break;
258 case CMD_EXECUTION: tokenCount = 1; break;
259 case CMD_FLAGS : tokenCount = 2; break;
260 default : return UNKNOWN_COMMAND;
261 }
262
263 //populate token set
264 int i;
265 for(i = 0; i < tokenCount; i++)
266 {
267 if(!(tokenSet[i] = synParser->GetToken()))
268 return SYN_ERROR;
269 }
270
271 //Appropriate number of tokens read.
272 return NO_ERRORS;
273 }
274
275 //************************
276 //get token set for a parameter
277 //************************
278
GetParamTokenSet(CmCToken ** tokenSet,CmCParser * synParser)279 int GetParamTokenSet(CmCToken **tokenSet, CmCParser *synParser)
280 {
281 int i;
282 for(i = 0; i < 3; i++)
283 {
284 if(!(tokenSet[i] = synParser->GetToken()))
285 return SYN_ERROR;
286 }
287 return NO_ERRORS;
288 }
289
290 //************************
291 //check for valid file type
292 //************************
293
validFileType(char * fileType)294 bool validFileType(char *fileType)
295 {
296 int i;
297 for(i = 0; i < FILETYPE_NUM; i++)
298 if(!strcmp(fileType, FILETYPE_LIST[i])) return true;
299 return false;
300 }
301
302 //************************
303 //check for valid output type
304 //************************
305
validOutputType(char * outputType)306 bool validOutputType(char *outputType)
307 {
308 int i;
309 for(i = 0; i < OUTPUTTYPE_NUM; i++)
310 if(!strcmp(outputType, OUTPUTTYPE_LIST[i])) return true;
311 return false;
312 }
313
314 //************************
315 //check for valid intput type
316 //************************
317
validInputType(char * inputType)318 bool validInputType(char *inputType)
319 {
320 int i;
321 for(i = 0; i < INPUTTYPE_NUM; i++)
322 if(!strcmp(inputType, INPUTTYPE_LIST[i])) return true;
323 return false;
324 }
325
326 //************************
327 //check for valid flag
328 //************************
329
validFlag(char * flag)330 bool validFlag(char *flag)
331 {
332 return !(strcmp(flag, "ON") && strcmp(flag, "OFF"));
333 }
334
335 //************************
336 //check for valid data type and value
337 //************************
338
checkInteger(char * data)339 int checkInteger(char *data)
340 {
341 char *dptr = data, ch;
342 while(ch = *(dptr++)) if(((ch < 48)||(ch > 57))&&(ch != '-')) return SYN_ASSIGN_INTEGER;
343 return NO_ERRORS;
344 }
345
checkFloatingPoint(char * data)346 int checkFloatingPoint(char *data)
347 {
348 char *dptr = data, ch;
349 while(ch = *(dptr++)) if(((ch < 48)||(ch > 57))&&(ch != '.')&&(ch != '-')) return SYN_ASSIGN_FLOAT;
350 return NO_ERRORS;
351 }
352
checkSpeedup(char * data)353 int checkSpeedup(char *data)
354 {
355 if(strcmp(data, "NONE")&&strcmp(data, "MEDIUM")&&strcmp(data, "HIGH"))
356 return SYN_ASSIGN_SPEEDUP;
357 else
358 return NO_ERRORS;
359 }
360
checkCurveType(int paramId,char * data)361 int checkCurveType(int paramId, char *data)
362 {
363 int i;
364 for(i = 0; i < CURVE_NUM; i++) {
365 if(paramId == PARAM_NMX_TYPE && i == CURVE_CUSTOM) break;
366 if(!strcmp(data, CURVETYPE_LIST[i])) return NO_ERRORS;
367 }
368 if(i == CURVE_CUSTOM) return SYN_ASSIGN_NMX_CUSTOM;
369 return SYN_ASSIGN_CURVE_TYPE;
370 }
371
checkBounds(int paramId,char * data)372 int checkBounds(int paramId, char *data)
373 {
374 float dataVal = atof(data);
375 if(UBOUND_LIST[paramId] > 0) {
376 if((dataVal <= 0)||(dataVal < LBOUND_LIST[paramId])||(dataVal > UBOUND_LIST[paramId]))
377 return SYN_BOUNDS_ERROR;
378 } else {
379 if((dataVal <= 0)||(dataVal < LBOUND_LIST[paramId]))
380 return SYN_BOUNDS_ERROR;
381 }
382 return NO_ERRORS;
383 }
384
checkBounds(char * data,float lower,float upper)385 int checkBounds(char *data, float lower, float upper)
386 {
387 float dataVal = atof(data);
388 if((dataVal < lower)||(dataVal > upper)) return SYN_BOUNDS_ERROR;
389 return NO_ERRORS;
390 }
391
CheckParameter(int paramId,char * data)392 int CheckParameter(int paramId, char *data)
393 {
394 int error;
395 switch(PARAMTYPE_LIST[paramId])
396 {
397 case PARAM_INTEGER:
398 error = checkInteger(data);
399 if(!error) error = checkBounds(paramId, data);
400 break;
401 case PARAM_FLOAT:
402 error = checkFloatingPoint(data);
403 if(!error) error = checkBounds(paramId, data);
404 break;
405 case PARAM_SPEEDUP_TYPE:
406 error = checkSpeedup(data);
407 break;
408 case PARAM_CURVE_TYPE:
409 error = checkCurveType(paramId, data);
410 break;
411 }
412 return error;
413 }
414
CheckList(CmCParser * synParser,CmCToken ** token)415 int CheckList(CmCParser *synParser, CmCToken **token)
416 {
417 //check for initial left curl bracket
418 (*token) = synParser->GetToken();
419 if((*token)->token_[0] != '{') return SYN_MISSING_LEFT_CURL;
420
421 //read in each data point
422 do {
423 (*token) = synParser->GetToken();
424 if((*token)->token_[0] != '(') return SYN_MISSING_LEFT_PARENTHESIS;
425 (*token) = synParser->GetToken();
426 if(checkFloatingPoint((*token)->token_)) return SYN_INCOMPLETE_LIST;
427 if(checkBounds((*token)->token_, 0, 1)) return SYN_ARG_BOUNDS_ERROR;
428 (*token) = synParser->GetToken();
429 if((*token)->token_[0] != ',') return SYN_MISSING_COMMA;
430 (*token) = synParser->GetToken();
431 if(checkFloatingPoint((*token)->token_)) return SYN_INCOMPLETE_LIST;
432 if(checkBounds((*token)->token_, 0, 1)) return SYN_ARG_BOUNDS_ERROR;
433 (*token) = synParser->GetToken();
434 if((*token)->token_[0] != ')') return SYN_MISSING_RIGHT_PARENTHESIS;
435 (*token) = synParser->GetToken();
436 if(((*token)->token_[0] != ',') && ((*token)->token_[0] != '}')) return SYN_MISSING_RIGHT_CURL;
437 } while((*token)->token_[0] != '}');
438
439 //the point list has proper structure!
440 return NO_ERRORS;
441 }
442
checkSupported(int filetype)443 int checkSupported(int filetype)
444 {
445 int i;
446 for(i = 0; i < SUPPORT_NUM; i++) {
447 if(filetype == SUPPORTED_FILETYPE_LIST[i]) return NO_ERRORS;
448 }
449 return SYN_UNSUPPORTED_FILETYPE;
450 }
451
452 //************************
453 //check syntax
454 //************************
455
CheckSyntax(char * filename,CmCParser * synParser)456 CmCError CheckSyntax(char *filename, CmCParser *synParser)
457 {
458
459 //*****************************************
460 //parse the file
461 //*****************************************
462
463 int error;
464 synParser->SetDelimiters("=(){},;'");
465 synParser->StoreDelimiters(true);
466 error = synParser->Parse(filename);
467 if(error) return (CmCError((CmCToken *) NULL, SYN_INVALID_FILE));
468
469 //*****************************************
470 //check syntax
471 //*****************************************
472
473 int curveId;
474 int parameterId;
475 int commandTypeId, commandId;
476 CmCToken *token, *(tokenSet)[MAX_TOKEN_NUM];
477 while(token = synParser->GetToken())
478 {
479 //identify the command...
480 commandId = Command(token->token_);
481 commandTypeId = CommandType(commandId);
482
483 //based on the command, identify the number of tokens
484 //associated with it and obtain those tokens
485 error = GetTokenSet(commandId, tokenSet, synParser);
486
487 //if the specified number of tokens does not exist
488 //then return an error
489 if(error == SYN_ERROR) return CmCError((CmCToken *) NULL, error);
490
491 //if the specified tokens exist, then check them for
492 //their validity
493
494 switch(commandTypeId)
495 {
496 case CMD_IO:
497 switch(commandId)
498 {
499 case CMD_SAVE:
500 //check structure
501 if(strcmp(tokenSet[0]->token_, "(")) return CmCError(tokenSet[0], SYN_MISSING_LEFT_PARENTHESIS);
502 if(strcmp(tokenSet[1]->token_, "'")) return CmCError(tokenSet[1],SYN_MISSING_QUOTATION);
503 if(strcmp(tokenSet[3]->token_, "'")) return CmCError(tokenSet[3],SYN_MISSING_QUOTATION);
504 if(strcmp(tokenSet[4]->token_, ",")) return CmCError(tokenSet[4],SYN_MISSING_COMMA);
505 if(strcmp(tokenSet[6]->token_, ",")) return CmCError(tokenSet[6],SYN_MISSING_COMMA);
506 if(strcmp(tokenSet[8]->token_, ")")) return CmCError(tokenSet[8],SYN_MISSING_RIGHT_PARENTHESIS);
507 if(strcmp(tokenSet[9]->token_, ";")) return CmCError(tokenSet[9],SYN_MISSING_SEMICOLON);
508
509 //check constants
510 if(!validFileType(tokenSet[5]->token_)) return CmCError(tokenSet[5],SYN_INVALID_FILETYPE);
511 if(!validOutputType(tokenSet[7]->token_))return CmCError(tokenSet[7],SYN_INVALID_OUTPUTTYPE);
512 if(checkSupported(FileType(tokenSet[5]->token_)))
513 return CmCError(tokenSet[5],SYN_UNSUPPORTED_FILETYPE);
514 break;
515
516 case CMD_LOAD:
517 //check structure
518 if(strcmp(tokenSet[0]->token_, "(")) return CmCError(tokenSet[0],SYN_MISSING_LEFT_PARENTHESIS);
519 if(strcmp(tokenSet[1]->token_, "'")) return CmCError(tokenSet[1],SYN_MISSING_QUOTATION);
520 if(strcmp(tokenSet[3]->token_, "'")) return CmCError(tokenSet[3],SYN_MISSING_QUOTATION);
521 if(strcmp(tokenSet[4]->token_, ",")) return CmCError(tokenSet[4],SYN_MISSING_COMMA);
522 if(strcmp(tokenSet[6]->token_, ")")) return CmCError(tokenSet[6],SYN_MISSING_RIGHT_PARENTHESIS);
523 if(strcmp(tokenSet[7]->token_, ";")) return CmCError(tokenSet[7],SYN_MISSING_SEMICOLON);
524
525 //check constants
526 if(!validInputType(tokenSet[5]->token_)) return CmCError(tokenSet[5],SYN_INVALID_INPUTTYPE);
527 break;
528
529 case CMD_USE_RESULT:
530 if(strcmp(tokenSet[0]->token_, "(")) return CmCError(tokenSet[0], SYN_MISSING_LEFT_PARENTHESIS);
531 if(strcmp(tokenSet[2]->token_, ")")) return CmCError(tokenSet[2], SYN_MISSING_RIGHT_PARENTHESIS);
532 if(strcmp(tokenSet[3]->token_, ";")) return CmCError(tokenSet[3], SYN_MISSING_SEMICOLON);
533 if((OutputType(tokenSet[1]->token_) != OUTPUT_SEGM_IMAGE) &&
534 (OutputType(tokenSet[1]->token_) != OUTPUT_FILT_IMAGE)) {
535 if(OutputType(tokenSet[1]->token_) != OUTPUT_UNKNOWN) {
536 return CmCError(tokenSet[1], SYN_ASSIGN_INVALID_ARG);
537 } else {
538 return CmCError(tokenSet[1], SYN_INVALID_OUTPUTTYPE);
539 }
540 }
541 break;
542 }
543 break;
544
545 case CMD_EXECUTION:
546 if(tokenSet[0]->token_[0] != ';') return CmCError(tokenSet[0],SYN_MISSING_SEMICOLON);
547 break;
548 case CMD_FLAGS:
549 if(!validFlag(tokenSet[0]->token_)) return CmCError(tokenSet[0],SYN_INVALID_FLAG);
550 if(tokenSet[1]->token_[0] != ';') return CmCError(tokenSet[1],SYN_MISSING_SEMICOLON);
551 break;
552 //unknown command
553 default:
554 break;
555 }
556
557 //if its not a command, then maybe its a parameter
558 if(commandTypeId == UNKNOWN_COMMAND) {
559 //get the parameter type
560 parameterId = Parameter(token->token_);
561
562 if(parameterId != UNKNOWN_PARAMETER) {
563
564 //retreive tokens expected given a parameter
565 error = GetParamTokenSet(tokenSet, synParser);
566 if(error == SYN_ERROR) return CmCError(token, SYN_ERROR);
567
568 //check those tokens for validity
569 if(strcmp(tokenSet[0]->token_, "=")) return CmCError(tokenSet[0],SYN_MISSING_EQUALS);
570 if(strcmp(tokenSet[2]->token_, ";")) return CmCError(tokenSet[2],SYN_MISSING_SEMICOLON);
571
572 //make sure parameter is of the right type
573 error = CheckParameter(parameterId, tokenSet[1]->token_);
574 if(error) return CmCError(token, error);
575
576 //if its an unknown parameter then maybe its a curve list
577 } else {
578 //get custom curve
579 curveId = CustomCurve(token->token_);
580
581 //if its not a custom curve list then flag an error
582 if(curveId == UNKNOWN_CURVE) return CmCError(token,SYN_INVALID_PARAMCMD);
583
584 //check for equals
585 token = synParser->GetToken();
586 if(token->token_[0] != '=') return CmCError(token,SYN_MISSING_EQUALS);
587
588 //if its a curve list, then check that a proper point list
589 //is provided
590 error = CheckList(synParser, &token);
591 if(error) return CmCError(token, error);
592
593 //check for semicolon
594 token = synParser->GetToken();
595 if(token->token_[0] != ';') return CmCError(token,SYN_MISSING_SEMICOLON);
596 }
597 }
598
599 //command/parameter identified and verified for
600 //its validity, next command/parameter
601 }
602
603 //reset parser
604 synParser->StartOver();
605
606 //file is syntaxically correct
607 return CmCError((CmCToken *) NULL, NO_ERRORS);
608
609 }
610
611 ////////////////////////////////////////////////////////
612 //Run Script
613 ////////////////////////////////////////////////////////
614
convert(int paramId,char * data)615 void *convert(int paramId, char *data)
616 {
617 switch(PARAMTYPE_LIST[paramId]) {
618 case PARAM_INTEGER: {
619 int *idata = new int;
620 if(!idata) return (void *) NULL;
621 *idata = atoi(data);
622 return (void *) idata;
623 }
624 break;
625 case PARAM_FLOAT: {
626 float *fdata = new float;
627 if(!fdata) return (void *) NULL;
628 *fdata = atof(data);
629 return (void *) fdata;
630 }
631 break;
632 case PARAM_SPEEDUP_TYPE: {
633 int *speed = new int;
634 if(!speed) return (void *) NULL;
635 int i;
636 for(i = 0; i < SPEED_NUM; i++)
637 if(!strcmp(data, SPEEDTYPE_LIST[i])) {
638 *speed = i;
639 break;
640 }
641 return (void *) speed;
642 }
643 break;
644 default: {
645 int *curve = new int;
646 if(!curve) return (void *) NULL;
647 int i;
648 for(i = 0; i < CURVE_NUM; i++)
649 if(!strcmp(data, CURVETYPE_LIST[i])) {
650 *curve = i;
651 break;
652 }
653 return (void *) curve;
654 }
655 break;
656 }
657 }
658
findMissing(void ** paramTable,int cmd)659 int findMissing(void **paramTable, int cmd)
660 {
661 switch(cmd) {
662 case CMD_SEGMENT:
663 if(!paramTable[PARAM_SPATIAL_BANDWIDTH]) return PARAM_SPATIAL_BANDWIDTH;
664 if(!paramTable[PARAM_RANGE_BANDWIDTH]) return PARAM_RANGE_BANDWIDTH;
665 if(!paramTable[PARAM_MINIMUM_REGION_AREA]) return PARAM_MINIMUM_REGION_AREA;
666 if(!paramTable[PARAM_SPEEDUP]) return PARAM_SPEEDUP;
667 break;
668 case CMD_FILTER:
669 if(!paramTable[PARAM_SPATIAL_BANDWIDTH]) return PARAM_SPATIAL_BANDWIDTH;
670 if(!paramTable[PARAM_RANGE_BANDWIDTH]) return PARAM_RANGE_BANDWIDTH;
671 if(!paramTable[PARAM_SPEEDUP]) return PARAM_SPEEDUP;
672 break;
673 case CMD_FUSE:
674 if(!paramTable[PARAM_RANGE_BANDWIDTH]) return PARAM_RANGE_BANDWIDTH;
675 if(!paramTable[PARAM_MINIMUM_REGION_AREA]) return PARAM_MINIMUM_REGION_AREA;
676 if(!paramTable[PARAM_SPEEDUP]) return PARAM_SPEEDUP;
677 break;
678 case CMD_EDGE_DETECT: {
679 if(!paramTable[PARAM_GRADIENT_WINDOW_RADIUS]) return PARAM_GRADIENT_WINDOW_RADIUS;
680 int paramId;
681 for(paramId = PARAM_MINIMUM_LENGTH; paramId <= PARAM_HYSTERISIS_LOW_TYPE; paramId++) {
682 if(!paramTable[paramId]) return paramId;
683 }
684 break;
685 }
686 default:
687 break;
688 }
689
690 if(CmCSynergistic) {
691 int paramId;
692 for(paramId = PARAM_GRADIENT_WINDOW_RADIUS; paramId <= PARAM_EDGE_STRENGTH_THRESHOLD; paramId++) {
693 if(!paramTable[paramId]) return paramId;
694 }
695 }
696 return UNKNOWN_PARAMETER;
697 }
698
SET(int paramId,CmCParser * script,void ** paramTable)699 int SET(int paramId, CmCParser *script, void **paramTable)
700 {
701 //get data
702 script->GetToken(); //skip equals
703 CmCToken *token = script->GetToken(); //get data
704 char *data = token->token_;
705 script->GetToken(); //skip semi-colon
706
707 //monitor synergistic parameters
708 if(paramId == PARAM_GRADIENT_WINDOW_RADIUS) {
709 int *idata = (int *) convert(paramId, data);
710 if(!idata) return EXE_OUT_OF_MEMORY;
711 int *old = (int *)(paramTable[paramId]);
712 if((!old) || (*idata != *old)) {
713 if(old) delete old;
714 paramTable[paramId] = (void *) idata;
715 CmCGradWinChanged = true;
716 return NO_ERRORS;
717 }
718 delete idata;
719 return NO_ERRORS;
720 }
721 if(paramId == PARAM_MIXTURE_PARAMETER) {
722 float *fdata = (float *) convert(paramId, data);
723 if(!fdata) return EXE_OUT_OF_MEMORY;
724 float *old = (float *)(paramTable[paramId]);
725 if((!old) || (*fdata != *old)) {
726 if(old) delete old;
727 paramTable[paramId] = (void *) fdata;
728 CmCMixtureChanged = true;
729 return NO_ERRORS;
730 }
731 delete fdata;
732 return NO_ERRORS;
733 }
734
735 //de-allocate memory used for old data
736 if(paramTable[paramId]) {
737 if(PARAMTYPE_LIST[paramId] == PARAM_FLOAT) {
738 delete (float *) paramTable[paramId];
739 } else {
740 delete (int *) paramTable[paramId];
741 }
742 }
743
744 //convert data to appropriate data type
745 //and place it onto the parameter table
746 if(!(paramTable[paramId] = convert(paramId, data))) return EXE_OUT_OF_MEMORY;
747
748 //parameter set successfully!
749 return NO_ERRORS;
750 }
751
752 const int MAX_SIZE = 1000;
READLIST(int curveId,CmCParser * script,void ** paramTable)753 int READLIST(int curveId, CmCParser *script, void **paramTable)
754 {
755 //traverse the and read the point list into
756 //the temporary buffer (NOTE: a maximum of MAX_SIZE points
757 //may be read into the point list)
758 float tempBuf[2*MAX_SIZE];
759 CmCToken *token;
760 script->GetToken(); //skip "={"
761 script->GetToken();
762 int n = 0;
763 do {
764 if(n >= MAX_SIZE) return EXE_LONG_POINT_LIST;
765 script->GetToken(); //skip '('
766 token = script->GetToken(); //read x-coordinate
767 tempBuf[2*n] = (float) atof(token->token_);
768 script->GetToken(); //skip ','
769 token = script->GetToken(); //read y-coordinate
770 tempBuf[2*n+1] = (float) atof(token->token_);
771 script->GetToken(); //skip '),'
772 token = script->GetToken();
773 n++; //next data point
774 } while(token->token_[0] != '}');
775 script->GetToken(); //skip ';'
776
777 //create point list
778 float *data = new float[2*n];
779 if(!data) return EXE_OUT_OF_MEMORY;
780 memcpy(data, tempBuf, 2*n*sizeof(float));
781
782 //place point list into parameter table
783 paramTable[PARAM_NUM + 2*curveId] = (void *) data;
784 int *nPts = new int;
785 if(!nPts) return EXE_OUT_OF_MEMORY;
786 *nPts = n;
787 paramTable[PARAM_NUM + 2*curveId + 1] = (void *) nPts;
788
789 //point list has been read successfully!
790 return NO_ERRORS;
791 }
792
EXECUTE(int cmdId,CmCParser * script,void ** paramTable)793 int EXECUTE(int cmdId, CmCParser *script, void **paramTable)
794 {
795 switch(cmdId) {
796
797 //***************************************************
798 //set global flags
799 //***************************************************
800
801 case CMD_SYNERGISTIC: {
802 CmCToken *token;
803 token = script->GetToken(); //get flag
804 if(!strcmp(token->token_, "ON")) {
805 CmCSynergistic = true;
806 CmCPrompt("Synergistic Segmentation ENABLED.\n");
807 } else {
808 CmCSynergistic = false;
809 CmCPrompt("Synergistic Segmentation DISABLED.\n");
810 }
811 script->GetToken(); //skip ';'
812 break;
813 }
814
815 case CMD_DISPLAY_PROGRESS: {
816 CmCToken *token;
817 token = script->GetToken(); //get flag
818 if(!strcmp(token->token_, "ON"))
819 CmCDisplayProgress = true;
820 else
821 CmCDisplayProgress = false;
822 script->GetToken(); //skip ';'
823 CmCPrompt("Display progress ENABLED.\n");
824 break;
825 }
826
827 case CMD_USE_CUSTOM_WEIGHT_MAP: {
828 CmCToken *token;
829 token = script->GetToken(); //get flag
830 if(!strcmp(token->token_, "ON")) {
831 CmCUseCustomWeightMap = true;
832 CmCPrompt("Custum weight map IN-USE (if defined).\n");
833 } else {
834 CmCUseCustomWeightMap = false;
835 CmCPrompt("Custum weight map IN-ACTIVE.\n");
836 }
837 script->GetToken(); //skip ';'
838 break;
839 }
840
841 //***************************************************
842 //load a file
843 //***************************************************
844
845 case CMD_LOAD: {
846 CmCToken *token;
847 script->GetToken(); //skip "('"
848 script->GetToken();
849 token = script->GetToken(); //get filename
850 char *filename = new char[strlen(token->token_)+1];
851 strcpy(filename, token->token_);
852 script->GetToken(); //skip "',"
853 script->GetToken();
854 token = script->GetToken(); //get input type
855 int inputtype = InputType(token->token_);
856 script->GetToken(); //skip ");"
857 script->GetToken();
858
859 //load file
860 int error = edison.Load(filename, inputtype);
861 if(!error) CmCPrompt("File '%s' has been successfully loaded!\n", filename);
862 delete [] filename;
863
864 //return any errors
865 if(error) return error;
866
867 break;
868 }
869
870 //***************************************************
871 //save a file
872 //***************************************************
873
874 case CMD_SAVE: {
875 CmCToken *token;
876 script->GetToken(); //skip "('"
877 script->GetToken();
878 token = script->GetToken(); //get filename
879 char *filename = new char [strlen(token->token_) + 1];
880 strcpy(filename, token->token_);
881 script->GetToken(); //skip "',"
882 script->GetToken();
883 token = script->GetToken(); //filetype
884 int filetype = FileType(token->token_);
885 script->GetToken(); //skip ','
886 token = script->GetToken(); //get output type
887 int outputtype = OutputType(token->token_);
888 script->GetToken(); //skip ");"
889 script->GetToken();
890
891 //save file
892 int error = edison.Save(filename, filetype, outputtype);
893 if(!error) CmCPrompt("File '%s' has been successfully saved!\n", filename);
894 delete [] filename;
895
896 //return any errors
897 if(error) return error;
898 break;
899 }
900
901 //***************************************************
902 //route output to input
903 //***************************************************
904
905 case CMD_USE_RESULT: {
906 CmCToken *token;
907 script->GetToken(); //skip '('
908 token = script->GetToken(); //get output type
909 int outputtype = OutputType(token->token_);
910 script->GetToken(); //skip ");"
911 script->GetToken();
912
913 //route output to input
914 int error = edison.UseResult(outputtype);
915 if(!error) {
916 if(outputtype == OUTPUT_SEGM_IMAGE) {
917 CmCPrompt("Segmented image result has been set as input.\n");
918 } else {
919 CmCPrompt("Filtered image result has been set as input.\n");
920 }
921 }
922 if(error) return error;
923 break;
924 }
925
926 //***************************************************
927 //edge detect the input image
928 //***************************************************
929
930 case CMD_EDGE_DETECT: {
931 edison.SetParameters(paramTable);
932 int error = edison.EdgeDetect();
933 if(error) return error;
934 script->GetToken(); //skip ';'
935 break;
936 }
937
938 //***************************************************
939 //filter the input image
940 //***************************************************
941
942 case CMD_FILTER: {
943 edison.SetParameters(paramTable);
944 int error = edison.Filter();
945 if(error) return error;
946 script->GetToken(); //skip ';'
947 break;
948 }
949
950 //***************************************************
951 //fuse the regions of the input image
952 //***************************************************
953
954 case CMD_FUSE: {
955 edison.SetParameters(paramTable);
956 int error = edison.Fuse();
957 if(error) return error;
958 script->GetToken(); //skip ';'
959 break;
960 }
961 //***************************************************
962 //segment the input image
963 //***************************************************
964
965 case CMD_SEGMENT: {
966 edison.SetParameters(paramTable);
967 int error = edison.Segment();
968 if(error) return error;
969 script->GetToken(); //skip ';'
970 break;
971 }
972
973 //***************************************************
974 //does nothing
975 //***************************************************
976
977 default:
978 break;
979 }
980
981 //command executed succesfully!
982 return NO_ERRORS;
983
984 }
985
986 //de-allocates the parameter table
DEALLOCATE(void ** paramTable)987 void DEALLOCATE(void **paramTable)
988 {
989 int i;
990 for(i = 0; i < PARAM_NUM + 2*CUST_CURVE_NUM; i++) {
991 if(paramTable[i]) {
992 switch(PARAMTYPE_LIST[i]) {
993 case PARAM_FLOAT: {
994 float *fdata = (float *) paramTable[i];
995 delete fdata;
996 paramTable[i] = (void *) NULL;
997 break;
998 }
999 default: {
1000 int *idata = (int *) paramTable[i];
1001 delete idata;
1002 paramTable[i] = (void *) NULL;
1003 break;
1004 }
1005 }
1006 }
1007 }
1008 }
1009
Run(CmCParser * script)1010 CmCError Run(CmCParser *script)
1011 {
1012
1013 //define and initialize parameter table
1014 void *(paramTable)[PARAM_NUM + 2*CUST_CURVE_NUM];
1015 int i;
1016 for(i = 0; i < PARAM_NUM + 2*CUST_CURVE_NUM; i++)
1017 paramTable[i] = (void *) NULL;
1018
1019 //parse script, setting parameters and
1020 //running commands along the way...
1021 int tokenId, error;
1022 CmCToken *token;
1023 while(token = script->GetToken()) {
1024 //determine type of token (parameter or command)
1025 tokenId = Command(token->token_);
1026
1027 //token is a command, so run it
1028 if(tokenId != UNKNOWN_COMMAND) {
1029 error = EXECUTE(tokenId, script, paramTable);
1030 if(error) {
1031 if(error == EXE_MISSING_PARAM) {
1032 CmCToken *ertok = new CmCToken((char *) PARAM_LIST[findMissing(paramTable, Command(token->token_))],
1033 token->lineNumber_);
1034 return CmCError(ertok, error);
1035 } else {
1036 return CmCError(token, error);
1037 }
1038 }
1039 }
1040 //token is a parameter, so set its value
1041 else {
1042 tokenId = Parameter(token->token_);
1043 if(tokenId != UNKNOWN_PARAMETER) {
1044 error = SET(tokenId, script, paramTable);
1045 if(error) return CmCError(token, error);
1046 //token is custum curve list, so read it
1047 } else {
1048 tokenId = CustomCurve(token->token_);
1049 error = READLIST(tokenId, script, paramTable);
1050 if(error) return CmCError(token, error);
1051 }
1052 }
1053 }
1054
1055 //done running script...
1056
1057 //de-allocate parameter table
1058 DEALLOCATE(paramTable);
1059
1060 //reset script parser
1061 script->StartOver();
1062
1063 //script has been run succesfully!
1064 return CmCError((CmCToken *) NULL, NO_ERRORS);
1065
1066 }
1067
1068 ////////////////////////////////////////////////////////
1069 //I/O Filters
1070 ////////////////////////////////////////////////////////
1071
1072 //get the fileformat of an image
CmCGetImageFormat(char * filename)1073 int CmCGetImageFormat(char *filename)
1074 {
1075 if(!filename) return EXE_NULL_PTR;
1076 FILE *fp = fopen(filename, "rb");
1077 if(!fp) return EXE_FILE_READ_ERROR;
1078 char buf[3];
1079 if(!fgets(buf, 3, fp)) {
1080 fclose(fp);
1081 return EXE_FILE_READ_ERROR;
1082 }
1083 fclose(fp);
1084 int i;
1085 for(i = 0; i < FILETYPE_NUM-1; i++) {
1086 if(!strncmp(buf, FILETYPE_HEADER_LIST[i], 2)) return i;
1087 }
1088 return FILE_UNKNOWN;
1089 }
1090
1091 //converts an image into floating point format
CmCConvertToFloat(unsigned char * image,int height,int width,int dim)1092 float *CmCConvertToFloat(unsigned char *image, int height, int width, int dim)
1093 {
1094 float *data = new float[height * width * dim];
1095 if(!data) return (float *) NULL;
1096 int i;
1097 for(i = 0; i < height * width * dim; i++) {
1098 data[i] = (float)(image[i]);
1099 }
1100 return data;
1101 }
1102
1103 //converts an image from color to grayscale
1104 const double W1 = 0.299;
1105 const double W2 = 0.587;
1106 const double W3 = 0.114;
CmCConvertToGrayscale(unsigned char * image,int height,int width)1107 unsigned char *CmCConvertToGrayscale(unsigned char *image, int height, int width)
1108 {
1109 unsigned char *data = new unsigned char [height * width];
1110 if(!data) return (unsigned char *) NULL;
1111 int i;
1112 double r, g, b;
1113 for(i = 0; i < height * width; i++) {
1114 r = (double)(image[3*i]);
1115 g = (double)(image[3*i+1]);
1116 b = (double)(image[3*i+2]);
1117 data[i] = (unsigned char)(r*W1 + g*W2 + b*W3);
1118 }
1119 return data;
1120 }
1121
1122 //write image data
CmCWriteImage(char * filename,unsigned char * image,int height,int width,int dim,int filetype)1123 int CmCWriteImage(char *filename, unsigned char *image, int height, int width, int dim, int filetype)
1124 {
1125 int error, i;
1126 unsigned char *data;
1127 switch(filetype) {
1128 case FILE_PPM:
1129 data = image;
1130 if(dim == 1) {
1131 data = new unsigned char [height * width * 3];
1132 if(!data) return EXE_OUT_OF_MEMORY;
1133 for(i = 0; i < height*width; i++) {
1134 data[3*i] = data[3*i+1] = data[3*i+2] = image[i];
1135 }
1136 }
1137 error = writePPMImage(filename, data, height, width, 255, (char *) NULL);
1138 if(data != image) delete [] data;
1139 break;
1140 case FILE_PGM:
1141 data = image;
1142 if(dim == 3) {
1143 data = CmCConvertToGrayscale(image, height, width);
1144 if(!data) return EXE_OUT_OF_MEMORY;
1145 }
1146 error = writePGMImage(filename, data, height, width, 255, (char *) NULL);
1147 if(data != image) delete [] data;
1148 break;
1149 case FILE_PNM: {
1150 bool color;
1151 if(dim == 3) {
1152 color = true;
1153 } else {
1154 color = false;
1155 }
1156 error = writePNMImage(filename, image, height, width, 255, color, (char *) NULL);
1157 break;
1158 }
1159 case FILE_MATLAB_ASCII: {
1160 float *fdata = CmCConvertToFloat(image, height, width, dim);
1161 if(!fdata) return EXE_OUT_OF_MEMORY;
1162 error = CmCWriteMFile(filename, fdata, height, width, dim);
1163 delete [] fdata;
1164 break;
1165 }
1166 default:
1167 return EXE_UNSUPPORTED_FILE_FORMAT;
1168 }
1169 if(!error)
1170 return NO_ERRORS;
1171 else
1172 return EXE_FILE_WRITE_ERROR;
1173 }
1174
1175 //write Matlab ASCII file
CmCWriteMFile(char * filename,float * data,int rows,int cols,int n)1176 int CmCWriteMFile(char *filename, float *data, int rows, int cols, int n)
1177 {
1178 if(!filename || !data) return EXE_NULL_PTR;
1179 FILE *fp = fopen(filename, "wb");
1180 if(!fp) return EXE_FILE_WRITE_ERROR;
1181 int i, j, k;
1182 for(i = 0; i < rows; i++) {
1183 for(j = 0; j < cols-1; j++) {
1184 for(k = 0; k < n; k++) {
1185 fprintf(fp, "%f ", data[n*(rows*i+j)+k]);
1186 }
1187 }
1188 for(k = 0; k < n-1; k++) {
1189 fprintf(fp, "%f ", data[n*(rows*i+cols-1)+k]);
1190 }
1191 fprintf(fp, "%f\n", data[n*(rows*i+cols-1)+n-1]);
1192 }
1193 fclose(fp);
1194 return NO_ERRORS;
1195 }
1196
1197 //read image data
CmCReadImage(char * filename,unsigned char ** image,int & height,int & width,int & dim)1198 int CmCReadImage(char *filename, unsigned char **image, int& height, int& width, int& dim)
1199 {
1200 if(!filename) return EXE_NULL_PTR;
1201 int filetype = CmCGetImageFormat(filename);
1202 int error = filetype; //possible error in reading file header
1203 switch(filetype) {
1204 case FILE_PPM:
1205 error = readPPMImage(filename, image, height, width, dim);
1206 dim = 3;
1207 break;
1208 case FILE_PGM:
1209 error = readPGMImage(filename, image, height, width, dim);
1210 dim = 1;
1211 break;
1212 case FILE_PNM: {
1213 bool color;
1214 error = readPNMImage(filename, image, height, width, dim, color);
1215 if(color) {
1216 dim = 3;
1217 } else {
1218 dim = 1;
1219 }
1220 break;
1221 }
1222 default:
1223 if(filetype == FILE_UNKNOWN) return EXE_UNKNOWN_FILE_FORMAT;
1224 }
1225
1226 if(!error)
1227 {
1228 //due to LUV conversion must always work in 5D
1229 if(dim == 1) {
1230 dim = 3;
1231 unsigned char *rgbImage = new unsigned char [height * width * dim];
1232 int i;
1233 for(i = 0; i < height * width; i++) {
1234 rgbImage[3*i] = rgbImage[3*i+1] = rgbImage[3*i+2] = (*image)[i];
1235 }
1236 delete [] *image;
1237 *image = rgbImage;
1238 }
1239 return NO_ERRORS;
1240 }
1241 else
1242 return EXE_FILE_READ_ERROR;
1243 }
1244
1245 //read Matlab ASCII file
CmCReadMFile(char * filename,float ** data,int rows,int cols)1246 int CmCReadMFile(char *filename, float **data, int rows, int cols)
1247 {
1248 if(!filename || !data) return EXE_NULL_PTR;
1249 FILE *fp = fopen(filename, "rb");
1250 if(!fp) return EXE_FILE_READ_ERROR;
1251 *data = new float [rows * cols];
1252 if(!data) {
1253 fclose(fp);
1254 return EXE_OUT_OF_MEMORY;
1255 }
1256 int i;
1257 for(i = 0; i < rows*cols; i++) {
1258 if(fscanf(fp, "%f", &((*data)[i])) == EOF) {
1259 delete[] *data;
1260 fclose(fp);
1261 return EXE_FILE_READ_ERROR;
1262 }
1263 }
1264 delete[] *data;
1265 fclose(fp);
1266 return NO_ERRORS;
1267 }
1268
1269
1270