1 //*******************************************************************
2 // Copyright (C) 2000 ImageLinks Inc.
3 //
4 // License: LGPL
5 //
6 // See LICENSE.txt file in the top level directory for more details.
7 //
8 // Author: Garrett Potts
9 //
10 //*************************************************************************
11 // $Id: ossimEquationCombiner.cpp 23407 2015-07-06 15:59:23Z okramer $
12
13 #include <cstdlib>
14 #include <sstream>
15 using namespace std;
16
17 #include <ossim/imaging/ossimEquationCombiner.h>
18 #include <ossim/imaging/ossimCastTileSourceFilter.h>
19 #include <ossim/imaging/ossimImageDataFactory.h>
20 #include <ossim/imaging/ossimConvolutionSource.h>
21 #include <ossim/imaging/ossimSubImageTileSource.h>
22 #include <ossim/base/ossimStringProperty.h>
23 #include <ossim/matrix/newmatio.h>
24 #include <ossim/base/ossimScalarTypeLut.h>
25 #include <ossim/base/ossimNotifyContext.h>
26
27 RTTI_DEF1(ossimEquationCombiner, "ossimEquationCombiner", ossimImageCombiner);
28
29 static const char* EQUATION_KW = "equation";
30
31
32 class ossimBinaryOpAdd : public ossimEquationCombiner::ossimBinaryOp
33 {
34 public:
apply(double v1,double v2) const35 virtual double apply(double v1, double v2)const
36 {
37 return v1 + v2;
38 }
39 };
40
41 class ossimBinaryOpAnd : public ossimEquationCombiner::ossimBinaryOp
42 {
43 public:
apply(double v1,double v2) const44 virtual double apply(double v1, double v2)const
45 {
46 return (double)(((ossim_uint32)v1) & ((ossim_uint32)v2));
47 }
48 };
49
50 class ossimBinaryOpOr : public ossimEquationCombiner::ossimBinaryOp
51 {
52 public:
apply(double v1,double v2) const53 virtual double apply(double v1, double v2)const
54 {
55 return (double)(((ossim_uint32)v1) | ((ossim_uint32)v2));
56 }
57 };
58
59 class ossimBinaryOpXor : public ossimEquationCombiner::ossimBinaryOp
60 {
61 public:
apply(double v1,double v2) const62 virtual double apply(double v1, double v2)const
63 {
64 return (double)(((ossim_uint32)v1) ^ ((ossim_uint32)v2));
65 }
66 };
67
68 class ossimBinaryOpSub : public ossimEquationCombiner::ossimBinaryOp
69 {
70 public:
apply(double v1,double v2) const71 virtual double apply(double v1, double v2)const
72 {
73 return v1 - v2;
74 }
75 };
76
77 class ossimBinaryOpMax : public ossimEquationCombiner::ossimBinaryOp
78 {
79 public:
apply(double v1,double v2) const80 virtual double apply(double v1, double v2)const
81 {
82 return std::max(v1, v2);
83 }
84 };
85
86 class ossimBinaryOpMin : public ossimEquationCombiner::ossimBinaryOp
87 {
88 public:
apply(double v1,double v2) const89 virtual double apply(double v1, double v2)const
90 {
91 return std::min(v1, v2);
92 }
93 };
94
95 class ossimBinaryOpMul : public ossimEquationCombiner::ossimBinaryOp
96 {
97 public:
apply(double v1,double v2) const98 virtual double apply(double v1, double v2)const
99 {
100 return v1 * v2;
101 }
102 };
103
104 class ossimBinaryOpDiv : public ossimEquationCombiner::ossimBinaryOp
105 {
106 public:
apply(double v1,double v2) const107 virtual double apply(double v1, double v2)const
108 {
109 if(fabs(v2)>FLT_EPSILON)
110 return v1 / v2;
111
112 return 1.0/FLT_EPSILON;
113 }
114 };
115
116 class ossimBinaryOpMod : public ossimEquationCombiner::ossimBinaryOp
117 {
118 public:
apply(double v1,double v2) const119 virtual double apply(double v1, double v2)const
120 {
121 if(fabs(v2)>FLT_EPSILON)
122 return fmod(v1,v2);
123
124 return 1.0/FLT_EPSILON;
125 }
126 };
127
128 class ossimBinaryOpPow : public ossimEquationCombiner::ossimBinaryOp
129 {
130 public:
apply(double v1,double v2) const131 virtual double apply(double v1, double v2)const
132 {
133 return pow(v1, v2);
134 }
135 };
136 // boolean operators
137 class ossimBinaryOpEqual : public ossimEquationCombiner::ossimBinaryOp
138 {
139 public:
apply(double v1,double v2) const140 virtual double apply(double v1, double v2)const
141 {
142 return (v1==v2)?1.0:0.0;
143 }
144 };
145 class ossimBinaryOpGreater : public ossimEquationCombiner::ossimBinaryOp
146 {
147 public:
apply(double v1,double v2) const148 virtual double apply(double v1, double v2)const
149 {
150 return (v1>v2)?1.0:0.0;
151 }
152 };
153 class ossimBinaryOpGreaterOrEqual : public ossimEquationCombiner::ossimBinaryOp
154 {
155 public:
apply(double v1,double v2) const156 virtual double apply(double v1, double v2)const
157 {
158 return (v1>=v2)?1.0:0.0;
159 }
160 };
161 class ossimBinaryOpLess : public ossimEquationCombiner::ossimBinaryOp
162 {
163 public:
apply(double v1,double v2) const164 virtual double apply(double v1, double v2)const
165 {
166 return (v1<v2)?1.0:0.0;
167 }
168 };
169 class ossimBinaryOpLessOrEqual : public ossimEquationCombiner::ossimBinaryOp
170 {
171 public:
apply(double v1,double v2) const172 virtual double apply(double v1, double v2)const
173 {
174 return (v1<=v2)?1.0:0.0;
175 }
176 };
177 class ossimBinaryOpDifferent : public ossimEquationCombiner::ossimBinaryOp
178 {
179 public:
apply(double v1,double v2) const180 virtual double apply(double v1, double v2)const
181 {
182 return (v1!=v2)?1.0:0.0;
183 }
184 };
185 class ossimUnaryOpNot : public ossimEquationCombiner::ossimUnaryOp
186 {
187 public:
apply(double v) const188 virtual double apply(double v)const
189 {
190 return 1-v;
191 }
192 };
193
194 class ossimUnaryOpAbs : public ossimEquationCombiner::ossimUnaryOp
195 {
196 public:
apply(double v) const197 virtual double apply(double v)const
198 {
199 return fabs(v);
200 }
201 };
202
203 class ossimUnaryOpOnesComplement : public ossimEquationCombiner::ossimUnaryOp
204 {
205 public:
apply(double v) const206 virtual double apply(double v)const
207 {
208 return (double)((ossim_uint8)~((ossim_uint8)v));
209 }
210 };
211
212 class ossimUnaryOpLog : public ossimEquationCombiner::ossimUnaryOp
213 {
214 public:
apply(double v) const215 virtual double apply(double v)const
216 {
217 return log(v);
218 }
219 };
220
221 class ossimUnaryOpLog10 : public ossimEquationCombiner::ossimUnaryOp
222 {
223 public:
apply(double v) const224 virtual double apply(double v)const
225 {
226 return log10(v);
227 }
228 };
229
230 class ossimUnaryOpNeg : public ossimEquationCombiner::ossimUnaryOp
231 {
232 public:
apply(double v) const233 virtual double apply(double v)const
234 {
235 return -v;
236 }
237 };
238
239 class ossimUnaryOpSqrt : public ossimEquationCombiner::ossimUnaryOp
240 {
241 public:
apply(double v) const242 virtual double apply(double v)const
243 {
244 if(v >= 0)
245 {
246 return sqrt(v);
247 }
248
249 return -1;
250 }
251 };
252
253 class ossimUnaryOpExp : public ossimEquationCombiner::ossimUnaryOp
254 {
255 public:
apply(double v) const256 virtual double apply(double v)const
257 {
258 return exp(v);
259 }
260 };
261
262 class ossimUnaryOpSin : public ossimEquationCombiner::ossimUnaryOp
263 {
264 public:
apply(double v) const265 virtual double apply(double v)const
266 {
267 return sin(v);
268 }
269 };
270
271 class ossimUnaryOpSind : public ossimEquationCombiner::ossimUnaryOp
272 {
273 public:
apply(double v) const274 virtual double apply(double v)const
275 {
276 return sin(v*M_PI/180.0);
277 }
278 };
279
280 class ossimUnaryOpASin : public ossimEquationCombiner::ossimUnaryOp
281 {
282 public:
apply(double v) const283 virtual double apply(double v)const
284 {
285 if(v > 1) v = 1;
286 if(v < -1) v = -1;
287 return asin(v);
288 }
289 };
290
291 class ossimUnaryOpASind : public ossimEquationCombiner::ossimUnaryOp
292 {
293 public:
apply(double v) const294 virtual double apply(double v)const
295 {
296 if(v > 1) v = 1;
297 if(v < -1) v = -1;
298 return (180/M_PI)*asin(v);
299 }
300 };
301
302 class ossimUnaryOpACos : public ossimEquationCombiner::ossimUnaryOp
303 {
304 public:
apply(double v) const305 virtual double apply(double v)const
306 {
307 if(v > 1) v = 1;
308 if(v < -1) v = -1;
309 return acos(v);
310 }
311 };
312
313 class ossimUnaryOpACosd : public ossimEquationCombiner::ossimUnaryOp
314 {
315 public:
apply(double v) const316 virtual double apply(double v)const
317 {
318 if(v > 1) v = 1;
319 if(v < -1) v = -1;
320 return (180/M_PI)*acos(v);
321 }
322 };
323
324 class ossimUnaryOpCos : public ossimEquationCombiner::ossimUnaryOp
325 {
326 public:
apply(double v) const327 virtual double apply(double v)const
328 {
329 return cos(v);
330 }
331 };
332
333 class ossimUnaryOpCosd : public ossimEquationCombiner::ossimUnaryOp
334 {
335 public:
apply(double v) const336 virtual double apply(double v)const
337 {
338 return cos(v*M_PI/180.0);
339 }
340 };
341
342 class ossimUnaryOpTan : public ossimEquationCombiner::ossimUnaryOp
343 {
344 public:
apply(double v) const345 virtual double apply(double v)const
346 {
347 return tan(v);
348 }
349 };
350
351 class ossimUnaryOpTand : public ossimEquationCombiner::ossimUnaryOp
352 {
353 public:
apply(double v) const354 virtual double apply(double v)const
355 {
356 return tan(v*M_PI/180.0);
357 }
358 };
359
360 class ossimUnaryOpATan : public ossimEquationCombiner::ossimUnaryOp
361 {
362 public:
apply(double v) const363 virtual double apply(double v)const
364 {
365 return atan(v);
366 }
367 };
368
369 class ossimUnaryOpATand : public ossimEquationCombiner::ossimUnaryOp
370 {
371 public:
apply(double v) const372 virtual double apply(double v)const
373 {
374 return (180/M_PI)*atan(v);
375 }
376 };
377
378
ossimEquationCombiner()379 ossimEquationCombiner::ossimEquationCombiner()
380 :ossimImageCombiner(),
381 theOutputScalarType(OSSIM_FLOAT64),
382 theEquation(""),
383 theLexer(NULL),
384 theTile(NULL),
385 theCastFilter(NULL),
386 theCastOutputFilter(NULL),
387 theCurrentId(0),
388 theCurrentResLevel(0)
389 {
390 theLexer = new ossimEquTokenizer;
391 theCastFilter = new ossimCastTileSourceFilter;
392 theCastFilter->setOutputScalarType(OSSIM_FLOAT64);
393 }
394
ossimEquationCombiner(ossimConnectableObject::ConnectableObjectList & inputs)395 ossimEquationCombiner::ossimEquationCombiner(ossimConnectableObject::ConnectableObjectList& inputs)
396 :ossimImageCombiner(inputs),
397 theOutputScalarType(OSSIM_FLOAT64),
398 theEquation(""),
399 theLexer(NULL),
400 theTile(NULL),
401 theCastFilter(NULL),
402 theCastOutputFilter(NULL),
403 theCurrentId(0),
404 theCurrentResLevel(0)
405 {
406 theLexer = new ossimEquTokenizer;
407 theCastFilter = new ossimCastTileSourceFilter;
408 theCastFilter->setOutputScalarType(OSSIM_FLOAT64);
409 }
410
~ossimEquationCombiner()411 ossimEquationCombiner::~ossimEquationCombiner()
412 {
413 if(theLexer)
414 {
415 delete theLexer;
416 theLexer = NULL;
417 }
418
419 if(theCastFilter.valid())
420 {
421 theCastFilter->disconnect();
422 theCastFilter = 0;
423 }
424
425 if(theCastOutputFilter.valid())
426 {
427 theCastOutputFilter->disconnect();
428 theCastOutputFilter = 0;
429 }
430 // make sure they are cleared
431 clearStacks();
432 }
433
getNullPixelValue(ossim_uint32 band) const434 double ossimEquationCombiner::getNullPixelValue(ossim_uint32 band)const
435 {
436
437 if(theEquation == "")
438 {
439 if(getInput())
440 {
441 ossimImageSource* inter = PTR_CAST(ossimImageSource, getInput());
442 if(inter)
443 {
444 return inter->getNullPixelValue(band);
445 }
446 }
447 }
448 return ossim::defaultNull(getOutputScalarType());
449 }
450
getMinPixelValue(ossim_uint32 band) const451 double ossimEquationCombiner::getMinPixelValue(ossim_uint32 band)const
452 {
453 if(theEquation == "")
454 {
455 if(getInput())
456 {
457 ossimImageSource* inter = PTR_CAST(ossimImageSource, getInput());
458 if(inter)
459 {
460 return inter->getMinPixelValue(band);
461 }
462 }
463 }
464 return ossim::defaultMin(getOutputScalarType());
465 }
466
getMaxPixelValue(ossim_uint32 band) const467 double ossimEquationCombiner::getMaxPixelValue(ossim_uint32 band)const
468 {
469 if(theEquation == "")
470 {
471 if(getInput())
472 {
473 ossimImageSource* inter = PTR_CAST(ossimImageSource, getInput());
474 if(inter)
475 {
476 return inter->getMaxPixelValue(band);
477 }
478 }
479 }
480 return ossim::defaultMax(getOutputScalarType());
481 }
482
getOutputScalarType() const483 ossimScalarType ossimEquationCombiner::getOutputScalarType() const
484 {
485
486 if(theEquation == "")
487 {
488 if(getInput())
489 {
490 ossimImageSource* inter = PTR_CAST(ossimImageSource, getInput());
491 if(inter)
492 {
493 return inter->getOutputScalarType();
494 }
495 }
496 }
497
498 return theOutputScalarType;
499 }
500
501
getTile(const ossimIrect & tileRect,ossim_uint32 resLevel)502 ossimRefPtr<ossimImageData> ossimEquationCombiner::getTile(
503 const ossimIrect& tileRect,
504 ossim_uint32 resLevel)
505 {
506 if(!theTile)
507 {
508 initialize();
509 }
510 long w = tileRect.width();
511 long h = tileRect.height();
512 long tw = theTile->getWidth();
513 long th = theTile->getHeight();
514
515 if(theEquation != "")
516 {
517 theTile->setImageRectangle(tileRect);
518
519 if(w*h != tw*th)
520 {
521 theTile->initialize();
522 }
523 else
524 {
525 theTile->makeBlank();
526 }
527 theCurrentResLevel = resLevel;
528
529 ossimRefPtr<ossimImageData> outputTile = parseEquation();
530
531 if(theCastOutputFilter.valid())
532 {
533 outputTile = theCastOutputFilter->applyCast(outputTile);
534 }
535
536 return outputTile;
537 }
538 else
539 {
540 if(getInput())
541 {
542 ossimImageSource* inter =
543 PTR_CAST(ossimImageSource, getInput());
544 if(inter)
545 {
546 return inter->getTile(tileRect, resLevel);
547 }
548 }
549 }
550
551 return ossimRefPtr<ossimImageData>();
552 }
553
setOutputScalarType(ossimScalarType scalarType)554 void ossimEquationCombiner::setOutputScalarType(ossimScalarType scalarType)
555 {
556 if(theOutputScalarType != scalarType)
557 {
558 theOutputScalarType = scalarType;
559
560 if(theOutputScalarType == OSSIM_SCALAR_UNKNOWN)
561 {
562 theOutputScalarType = OSSIM_FLOAT64;
563 }
564 if(theCastOutputFilter.valid())
565 {
566 theCastOutputFilter = 0;
567 }
568
569 if(theOutputScalarType != OSSIM_FLOAT64)
570 {
571 theCastOutputFilter = new ossimCastTileSourceFilter;
572 theCastOutputFilter->setOutputScalarType(theOutputScalarType);
573 theCastOutputFilter->connectMyInputTo(0, this);
574 theCastOutputFilter->initialize();
575 }
576 }
577 }
578
setProperty(ossimRefPtr<ossimProperty> property)579 void ossimEquationCombiner::setProperty(ossimRefPtr<ossimProperty> property)
580 {
581 if(!property) return;
582
583 if(property->getName() == "Equation")
584 {
585 theEquation = property->valueToString();
586 }
587 else if(property->getName() == "Output scalar type")
588 {
589 setOutputScalarType(ossimScalarTypeLut::instance()->
590 getScalarTypeFromString(property->valueToString()));
591 }
592 else
593 {
594 ossimImageCombiner::setProperty(property);
595 }
596 }
597
getProperty(const ossimString & name) const598 ossimRefPtr<ossimProperty> ossimEquationCombiner::getProperty(const ossimString& name)const
599 {
600 if(name == "Equation")
601 {
602 ossimStringProperty* stringProp = new ossimStringProperty("Equation",
603 theEquation,
604 false);
605 stringProp->clearChangeType();
606 stringProp->setReadOnlyFlag(false);
607 stringProp->setCacheRefreshBit();
608
609 return stringProp;
610 }
611 else if(name == "Output scalar type")
612 {
613 ossimScalarTypeLut* sl = ossimScalarTypeLut::instance();
614
615 std::vector<ossimString> scalarNames;
616
617 ossim_int32 tableSize = (ossim_int32)sl->getTableSize();
618 ossim_int32 idx;
619
620 for(idx = 0; idx < tableSize; ++idx)
621 {
622 scalarNames.push_back(sl->getEntryString(idx));
623 }
624 ossimStringProperty* stringProp = new ossimStringProperty("Output scalar type",
625 sl->getEntryString((ossim_int32)theOutputScalarType),
626 false,
627 scalarNames);
628 stringProp->clearChangeType();
629 stringProp->setReadOnlyFlag(false);
630 stringProp->setCacheRefreshBit();
631
632 return stringProp;
633
634 }
635
636 return ossimImageCombiner::getProperty(name);
637 }
638
getPropertyNames(std::vector<ossimString> & propertyNames) const639 void ossimEquationCombiner::getPropertyNames(std::vector<ossimString>& propertyNames)const
640 {
641 ossimImageCombiner::getPropertyNames(propertyNames);
642 propertyNames.push_back("Equation");
643 propertyNames.push_back("Output scalar type");
644 }
645
646
initialize()647 void ossimEquationCombiner::initialize()
648 {
649 ossimImageCombiner::initialize();
650
651 theTile = ossimImageDataFactory::instance()->create(this, OSSIM_FLOAT64, getNumberOfOutputBands(), getTileWidth(), getTileHeight());
652 theTile->initialize();
653 if(theCastOutputFilter.valid())
654 {
655 theCastOutputFilter->initialize();
656 }
657 }
658
assignValue()659 void ossimEquationCombiner::assignValue()
660 {
661 if(!theValueStack.empty())
662 {
663 if(theValueStack.top().type == OSSIM_EQU_IMAGE_DATA_TYPE)
664 {
665 ossimImageData* topData = theValueStack.top().d.imageDataValue;
666 ossim_uint32 minBands = std::min(theTile->getNumberOfBands(),
667 topData->getNumberOfBands());
668 ossim_uint32 maxBands = theTile->getNumberOfBands();
669 ossim_uint32 band = 0;
670 ossim_uint32 offset = 0;
671 ossim_uint32 size = theTile->getWidth()*theTile->getHeight();
672
673 if(topData->getDataObjectStatus() == OSSIM_PARTIAL)
674 {
675 for(band = 0; band < minBands; ++band)
676 {
677 double* inBuf = (double*)topData->getBuf(band);
678 double* outBuf = (double*)theTile->getBuf(band);
679 double np = topData->getNullPix(band);
680 if(outBuf && inBuf)
681 {
682 for(offset = 0; offset < size; ++offset)
683 {
684 if(*inBuf != np)
685 {
686 *outBuf = *inBuf;
687 }
688 ++outBuf;
689 ++inBuf;
690 }
691 }
692 }
693 for(;band < maxBands; ++band)
694 {
695 double* inBuf = (double*)topData->getBuf(minBands-1);
696 double* outBuf = (double*)theTile->getBuf(band);
697 double np = topData->getNullPix(band);
698
699 if(outBuf && inBuf)
700 {
701 for(offset = 0; offset < size; ++offset)
702 {
703 if(*inBuf != np)
704 {
705 *outBuf = *inBuf;
706 }
707 ++outBuf;
708 ++inBuf;
709 }
710 }
711 }
712
713 }
714 else if(topData->getDataObjectStatus() == OSSIM_FULL)
715 {
716 for(band = 0; band < minBands; ++band)
717 {
718 double* inBuf = (double*)theValueStack.top().d.imageDataValue->getBuf(band);
719 double* outBuf = (double*)theTile->getBuf(band);
720 if(outBuf && inBuf)
721 {
722 for(offset = 0; offset < size; ++offset)
723 {
724 *outBuf = *inBuf;
725 ++outBuf;
726 ++inBuf;
727 }
728 }
729 }
730 for(;band < maxBands; ++band)
731 {
732 double* inBuf = (double*)theValueStack.top().d.imageDataValue->getBuf(minBands-1);
733 double* outBuf = (double*)theTile->getBuf(band);
734
735 if(outBuf && inBuf)
736 {
737 for(offset = 0; offset < size; ++offset)
738 {
739 *outBuf = *inBuf;
740 ++outBuf;
741 ++inBuf;
742 }
743 }
744 }
745 }
746
747 // Delete the object indirectly through an ossimRefPtr.
748 ossimRefPtr<ossimImageData> id = theValueStack.top().d.imageDataValue;
749 id = NULL;
750 }
751 else
752 {
753 double* buf = static_cast<double*>(theTile->getBuf());
754 ossim_uint32 size = theTile->getSize();
755 double value = (double)theValueStack.top().d.doubleValue;
756
757 for(ossim_uint32 offset = 0; offset < size; ++offset)
758 {
759 *buf = value;
760 ++buf;
761 }
762 }
763
764 theValueStack.pop();
765 }
766 }
767
clearStacks()768 void ossimEquationCombiner::clearStacks()
769 {
770
771 while(!theValueStack.empty())
772 {
773 if(theValueStack.top().type == OSSIM_EQU_IMAGE_DATA_TYPE)
774 {
775 // Delete the object indirectly through an ossimRefPtr.
776 ossimRefPtr<ossimImageData> id = theValueStack.top().d.imageDataValue;
777 id = NULL;
778 }
779
780 theValueStack.pop();
781 }
782 }
783
clearArgList(vector<ossimEquValue> & argList)784 void ossimEquationCombiner::clearArgList(vector<ossimEquValue>& argList)
785 {
786 for(ossim_uint32 i = 0; i < argList.size(); ++i)
787 {
788 if(argList[i].type == OSSIM_EQU_IMAGE_DATA_TYPE)
789 {
790 if(argList[i].d.imageDataValue)
791 {
792 // Delete the object indirectly through an ossimRefPtr.
793 ossimRefPtr<ossimImageData> id = argList[i].d.imageDataValue;
794 id = NULL;
795 argList[i].d.imageDataValue = (ossimImageData*)NULL;
796 }
797 }
798 }
799 argList.clear();
800 }
801
deleteArgList(vector<ossimEquValue> & args)802 void ossimEquationCombiner::deleteArgList(vector<ossimEquValue>& args)
803 {
804 int i = 0;
805
806 for(i = 0; i < (int)args.size(); ++i)
807 {
808 if(args[i].type == OSSIM_EQU_IMAGE_DATA_TYPE)
809 {
810 if(args[i].d.imageDataValue)
811 {
812 // Delete the object indirectly through an ossimRefPtr.
813 ossimRefPtr<ossimImageData> id = args[i].d.imageDataValue;
814 id = NULL;
815 args[i].d.imageDataValue = NULL;
816 }
817 }
818 }
819
820 args.clear();
821 }
822
parseArgList(vector<ossimEquValue> & args,bool popValueStack)823 bool ossimEquationCombiner::parseArgList(vector<ossimEquValue>& args,
824 bool popValueStack)
825 {
826 bool result = true;
827
828 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
829 {
830 theCurrentId = theLexer->yylex();
831 do
832 {
833 if(parseExpression())
834 {
835 if(!theValueStack.empty())
836 {
837 args.push_back(theValueStack.top());
838 if(popValueStack)
839 {
840 theValueStack.pop();
841 }
842 }
843 else
844 {
845 ossimNotify(ossimNotifyLevel_WARN)
846 << "The expression at arg " << (args.size()+1)
847 << " is empty" << endl;
848
849 result = false;
850 }
851 }
852 else
853 {
854 ossimNotify(ossimNotifyLevel_WARN)
855 <<"Unable to parse expression" << endl;
856 result = false;
857 }
858
859 if(theCurrentId == OSSIM_EQU_TOKEN_COMMA)
860 {
861 theCurrentId = theLexer->yylex();
862 }
863 else if(theCurrentId != OSSIM_EQU_TOKEN_RIGHT_PAREN)
864 {
865 ossimNotify(ossimNotifyLevel_WARN)
866 <<"Missing comma in argument list" << endl;
867 result = false;
868 }
869
870 }while(result&&(theCurrentId != OSSIM_EQU_TOKEN_RIGHT_PAREN));
871 }
872 else
873 {
874 ossimNotify(ossimNotifyLevel_WARN)
875 << "Starting left parenthesis missing from arg list" << endl;
876 result = false;
877 }
878
879 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
880 {
881 theCurrentId = theLexer->yylex(); // skip past right parenthesis
882 }
883 else
884 {
885 ossimNotify(ossimNotifyLevel_WARN)
886 <<"No matching right parenthesis for arg list" << endl;
887 result = false;
888 }
889
890 if(!result && popValueStack)
891 {
892 clearArgList(args);
893 }
894 return result;
895 }
896
parseAssignBand()897 bool ossimEquationCombiner::parseAssignBand()
898 {
899 bool result = true;
900
901 vector<ossimEquValue> argList;
902
903 if(parseArgList(argList))
904 {
905 if((argList.size() == 3) ||
906 (argList.size() == 4))
907 {
908 ossimEquValue v3 = argList[2];
909 ossimEquValue v2 = argList[1];
910 ossimEquValue v1 = argList[0];
911
912 if(argList.size() == 3)
913 {
914 if((v1.type == OSSIM_EQU_IMAGE_DATA_TYPE) &&
915 (v2.type == OSSIM_EQU_DOUBLE_TYPE))
916 {
917 ossimImageData *data = (ossimImageData*)v1.d.imageDataValue->dup();
918 ossimEquValue v;
919
920 if(v3.type == OSSIM_EQU_IMAGE_DATA_TYPE)
921 {
922 if(data->getBuf()&&
923 v3.d.imageDataValue->getBuf())
924 {
925 if((ossim_uint32)(v2.d.doubleValue) < data->getNumberOfBands())
926 {
927 data->assignBand(v3.d.imageDataValue,
928 0,
929 (ossim_uint32)v2.d.doubleValue);
930
931 }
932 }
933 }
934 else
935 {
936 if(data->getBuf()&&
937 (ossim_uint32)v2.d.doubleValue < data->getNumberOfBands())
938 {
939 ossim_uint32 upper = data->getWidth()*data->getHeight();
940 double* buf = (double*)data->getBuf((ossim_uint32)v2.d.doubleValue);
941 double value = v3.d.doubleValue;
942 if(buf)
943 {
944 for(ossim_uint32 i = 0; i < upper; ++i)
945 {
946 *buf = value;
947 ++buf;
948 }
949 }
950 else
951 {
952 result = false;
953 }
954 }
955 }
956 if(result)
957 {
958 data->validate();
959 v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
960 v.d.imageDataValue = data;
961 theValueStack.push(v);
962 }
963 }
964 else
965 {
966 result = false;
967 }
968 }
969 else
970 {
971 ossimEquValue v4 = argList[3];
972 if((v1.type == OSSIM_EQU_IMAGE_DATA_TYPE) &&
973 (v2.type == OSSIM_EQU_DOUBLE_TYPE)&&
974 (v3.type == OSSIM_EQU_IMAGE_DATA_TYPE)&&
975 (v4.type == OSSIM_EQU_DOUBLE_TYPE))
976 {
977 ossimImageData *data = (ossimImageData*)v1.d.imageDataValue->dup();
978 ossimEquValue v;
979 v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
980 v.d.imageDataValue = data;
981 if(data->getBuf()&&v3.d.imageDataValue->getBuf())
982 {
983
984 ossim_uint32 index1 = (ossim_uint32)v4.d.doubleValue;
985 ossim_uint32 index2 = (ossim_uint32)v2.d.doubleValue;
986
987 if((index1 > data->getNumberOfBands()) ||
988 (index1 > v3.d.imageDataValue->getNumberOfBands()))
989 {
990 result = false;
991 }
992 else
993 {
994 data->assignBand(v3.d.imageDataValue,
995 index1,
996 index2);
997 data->validate();
998 }
999
1000 }
1001
1002 theValueStack.push(v);
1003 }
1004 }
1005 }
1006 else
1007 {
1008 ossimNotify(ossimNotifyLevel_WARN)
1009 << "Invalid number of arguments to assign_band" << endl;
1010 result = false;
1011 }
1012 }
1013 else
1014 {
1015 ossimNotify(ossimNotifyLevel_WARN)
1016 << "unable to parse arguments for assign band" << endl;
1017 result = false;
1018 }
1019
1020 clearArgList(argList);
1021
1022 return result;
1023 }
1024
parseStdFuncs()1025 bool ossimEquationCombiner::parseStdFuncs()
1026 {
1027 bool result = true;
1028
1029 switch(theCurrentId)
1030 {
1031 case OSSIM_EQU_TOKEN_ASSIGN_BAND:
1032 {
1033 theCurrentId = theLexer->yylex();
1034 if(!parseAssignBand())
1035 {
1036 result = false;
1037 }
1038
1039 break;
1040 }
1041 case OSSIM_EQU_TOKEN_CONV:
1042 {
1043 theCurrentId = theLexer->yylex();
1044 vector<ossimEquValue> args;
1045 if(parseArgList(args))
1046 {
1047 ossimImageData* resultImage = (ossimImageData*)NULL;
1048 if(applyConvolution(resultImage,
1049 args))
1050 {
1051 if(resultImage)
1052 {
1053 ossimEquValue v;
1054 v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
1055 v.d.imageDataValue = resultImage;
1056
1057 theValueStack.push(v);
1058 }
1059 else
1060 {
1061 ossimNotify(ossimNotifyLevel_WARN)
1062 << "function conv error: resulting image is NULL" << endl;
1063 result = false;
1064 }
1065 }
1066 else
1067 {
1068 ossimNotify(ossimNotifyLevel_WARN)
1069 << "Unable to apply convolution" << endl;
1070 result = false;
1071 }
1072 }
1073 else
1074 {
1075 result = false;
1076 }
1077
1078 break;
1079 }
1080 case OSSIM_EQU_TOKEN_CLAMP:
1081 {
1082 theCurrentId = theLexer->yylex();
1083 vector<ossimEquValue> args;
1084 if(parseArgList(args))
1085 {
1086 ossimImageData* resultImage = (ossimImageData*)NULL;
1087 if(applyClamp(resultImage,
1088 args))
1089 {
1090 if(resultImage)
1091 {
1092 ossimEquValue v;
1093 v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
1094 v.d.imageDataValue = resultImage;
1095
1096 theValueStack.push(v);
1097 }
1098 else
1099 {
1100 ossimNotify(ossimNotifyLevel_WARN)
1101 << "function clamp error: resulting image is NULL" << endl;
1102 result = false;
1103 }
1104
1105 }
1106 else
1107 {
1108 ossimNotify(ossimNotifyLevel_WARN)
1109 << "Unable to apply clamp" << endl;
1110 result = false;
1111 }
1112 }
1113 else
1114 {
1115 result = false;
1116 }
1117
1118 break;
1119 }
1120 case OSSIM_EQU_TOKEN_BAND:
1121 {
1122 // need to parse the following rule for blurr function
1123 //
1124 // band(image data, number)
1125 theCurrentId = theLexer->yylex();
1126
1127
1128 vector<ossimEquValue> argList;
1129
1130 if(parseArgList(argList))
1131 {
1132 if(argList.size() == 2)
1133 {
1134 ossimEquValue v1 = argList[0];
1135 ossimEquValue v2 = argList[1];
1136 ossimImageData* tempData = NULL;
1137 ossim_uint32 bandNumber = 0;
1138 if(v1.type == OSSIM_EQU_IMAGE_DATA_TYPE)
1139 {
1140 tempData = v1.d.imageDataValue;
1141 }
1142 else
1143 {
1144 result = false;
1145 }
1146 if(v2.type == OSSIM_EQU_DOUBLE_TYPE)
1147 {
1148 bandNumber = (ossim_uint32)(v2.d.doubleValue);
1149 }
1150 else
1151 {
1152 result = false;
1153 }
1154 if(bandNumber > tempData->getNumberOfBands())
1155 {
1156 result = false;
1157 }
1158 if(result)
1159 {
1160 ossimImageData* data = new ossimImageData(this,
1161 OSSIM_FLOAT64,
1162 1);
1163 data->setWidthHeight(tempData->getWidth(),
1164 tempData->getHeight());
1165 data->setOrigin(tempData->getOrigin());
1166 data->setNullPix(tempData->getNullPix(bandNumber),
1167 0);
1168 data->setMinPix(tempData->getMinPix(bandNumber),
1169 0);
1170 data->setMaxPix(tempData->getMaxPix(bandNumber),
1171 0);
1172 data->initialize();
1173
1174 if((tempData->getBuf())&&
1175 (bandNumber < tempData->getNumberOfBands()))
1176 {
1177 data->assignBand(tempData,
1178 bandNumber,
1179 0);
1180 data->validate();
1181 }
1182 ossimEquValue v;
1183 v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
1184 v.d.imageDataValue = data;
1185 theValueStack.push(v);
1186 }
1187
1188 if(tempData)
1189 {
1190 // Delete the object indirectly through an ossimRefPtr.
1191 ossimRefPtr<ossimImageData> id = tempData;
1192 tempData = NULL;
1193 }
1194 }
1195 else
1196 {
1197 ossimNotify(ossimNotifyLevel_WARN)
1198 << "Invalid number of args in function band" << endl;
1199
1200 result = false;
1201 }
1202 }
1203 else
1204 {
1205 result = false;
1206 }
1207
1208 break;
1209 }
1210 case OSSIM_EQU_TOKEN_BLURR:
1211 {
1212 theCurrentId = theLexer->yylex();
1213 vector<ossimEquValue> args;
1214 if(parseArgList(args))
1215 {
1216 ossimImageData* resultImage = (ossimImageData*)NULL;
1217 if(applyBlurr(resultImage,
1218 args))
1219 {
1220 if(resultImage)
1221 {
1222 ossimEquValue v;
1223 v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
1224 v.d.imageDataValue = resultImage;
1225
1226 theValueStack.push(v);
1227 }
1228 else
1229 {
1230 result = false;
1231 }
1232 }
1233 else
1234 {
1235 result = false;
1236 }
1237 }
1238 else
1239 {
1240 result = false;
1241 }
1242
1243 break;
1244 }
1245 case OSSIM_EQU_TOKEN_SHIFT:
1246 {
1247 theCurrentId = theLexer->yylex();
1248 vector<ossimEquValue> args;
1249 if(parseArgList(args))
1250 {
1251 ossimImageData* resultImage = (ossimImageData*)NULL;
1252 if(applyShift(resultImage,
1253 args))
1254 {
1255 if(resultImage)
1256 {
1257 ossimEquValue v;
1258 v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
1259 v.d.imageDataValue = resultImage;
1260
1261 theValueStack.push(v);
1262 }
1263 else
1264 {
1265 result = false;
1266 }
1267 }
1268 else
1269 {
1270 result = false;
1271 }
1272 }
1273 else
1274 {
1275 result = false;
1276 }
1277
1278 break;
1279 }
1280 case OSSIM_EQU_TOKEN_MAX:
1281 case OSSIM_EQU_TOKEN_MIN:
1282 {
1283 ossimBinaryOp* op = NULL;
1284 if(theCurrentId == OSSIM_EQU_TOKEN_MIN) op = new ossimBinaryOpMin;
1285 else op = new ossimBinaryOpMax;
1286
1287 int argCount = 0;
1288 theCurrentId = theLexer->yylex();
1289 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1290 {
1291 theCurrentId = theLexer->yylex();
1292 bool done = false;
1293 while(!done)
1294 {
1295 if(parseExpression())
1296 {
1297
1298 ++argCount;
1299 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1300 {
1301 theCurrentId = theLexer->yylex();
1302
1303 done = true;
1304 }
1305 else if(theCurrentId == OSSIM_EQU_TOKEN_COMMA)
1306 {
1307 theCurrentId = theLexer->yylex();
1308 }
1309 else
1310 {
1311 result = false;
1312 done = true;
1313 }
1314 }
1315 else
1316 {
1317 done = true;
1318 result = false;
1319 }
1320 }
1321 if((argCount > 1)&&result)
1322 {
1323 result = true;
1324
1325 ossimEquValue v;
1326 ossimEquValue v1;
1327 ossimEquValue v2;
1328
1329 v2 = theValueStack.top();
1330 theValueStack.pop();
1331 v1 = theValueStack.top();
1332 theValueStack.pop();
1333 argCount -=2;
1334
1335 do
1336 {
1337 if(applyOp(*op,
1338 v,
1339 v1,
1340 v2))
1341 {
1342 theValueStack.push(v);
1343 }
1344 else
1345 {
1346 result = false;
1347 argCount = 0;
1348
1349 }
1350 --argCount;
1351
1352 if((argCount>0)&&result)
1353 {
1354 v2 = theValueStack.top();
1355 theValueStack.pop();
1356 v1 = theValueStack.top();
1357 theValueStack.pop();
1358 }
1359
1360 }while((argCount > 0)&&(result));
1361 }
1362 else
1363 {
1364 result = false;
1365 }
1366 }
1367 else
1368 {
1369 result = false;
1370 }
1371 if(op)
1372 {
1373 delete op;
1374 op = NULL;
1375 }
1376 break;
1377 }
1378 case OSSIM_EQU_TOKEN_ABS:
1379 {
1380 theCurrentId = theLexer->yylex();
1381 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1382 {
1383 theCurrentId = theLexer->yylex();
1384 result = parseExpression();
1385 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1386 {
1387 if(theValueStack.size() > 0)
1388 {
1389 theCurrentId = theLexer->yylex();
1390 ossimEquValue v;
1391 ossimEquValue v1 = theValueStack.top();
1392 theValueStack.pop();
1393
1394 applyOp(ossimUnaryOpAbs(),
1395 v,
1396 v1);
1397
1398 theValueStack.push(v);
1399 }
1400 else
1401 {
1402 result = false;
1403 }
1404 }
1405 }
1406 else
1407 {
1408 result = false;
1409 }
1410 break;
1411 }
1412 case OSSIM_EQU_TOKEN_SIN:
1413 {
1414 theCurrentId = theLexer->yylex();
1415 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1416 {
1417 theCurrentId = theLexer->yylex();
1418 result = parseExpression();
1419 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1420 {
1421 if(theValueStack.size() > 0)
1422 {
1423 theCurrentId = theLexer->yylex();
1424 ossimEquValue v;
1425 ossimEquValue v1 = theValueStack.top();
1426 theValueStack.pop();
1427
1428 applyOp(ossimUnaryOpSin(),
1429 v,
1430 v1);
1431
1432 theValueStack.push(v);
1433 }
1434 else
1435 {
1436 result = false;
1437 }
1438 }
1439 }
1440 else
1441 {
1442 result = false;
1443 }
1444 break;
1445 }
1446 case OSSIM_EQU_TOKEN_SIND:
1447 {
1448 theCurrentId = theLexer->yylex();
1449 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1450 {
1451 theCurrentId = theLexer->yylex();
1452 result = parseExpression();
1453 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1454 {
1455 if(theValueStack.size() > 0)
1456 {
1457 theCurrentId = theLexer->yylex();
1458 ossimEquValue v;
1459 ossimEquValue v1 = theValueStack.top();
1460 theValueStack.pop();
1461
1462 applyOp(ossimUnaryOpSind(),
1463 v,
1464 v1);
1465
1466 theValueStack.push(v);
1467 }
1468 else
1469 {
1470 result = false;
1471 }
1472 }
1473 }
1474 else
1475 {
1476 result = false;
1477 }
1478 break;
1479 }
1480 case OSSIM_EQU_TOKEN_ASIN:
1481 {
1482 theCurrentId = theLexer->yylex();
1483 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1484 {
1485 theCurrentId = theLexer->yylex();
1486 result = parseExpression();
1487 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1488 {
1489 if(theValueStack.size() > 0)
1490 {
1491 theCurrentId = theLexer->yylex();
1492 ossimEquValue v;
1493 ossimEquValue v1 = theValueStack.top();
1494 theValueStack.pop();
1495
1496 applyOp(ossimUnaryOpASin(),
1497 v,
1498 v1);
1499
1500 theValueStack.push(v);
1501 }
1502 else
1503 {
1504 result = false;
1505 }
1506 }
1507 }
1508 else
1509 {
1510 result = false;
1511 }
1512 break;
1513 }
1514 case OSSIM_EQU_TOKEN_ASIND:
1515 {
1516 theCurrentId = theLexer->yylex();
1517 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1518 {
1519 theCurrentId = theLexer->yylex();
1520 result = parseExpression();
1521 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1522 {
1523 if(theValueStack.size() > 0)
1524 {
1525 theCurrentId = theLexer->yylex();
1526 ossimEquValue v;
1527 ossimEquValue v1 = theValueStack.top();
1528 theValueStack.pop();
1529
1530 applyOp(ossimUnaryOpASind(),
1531 v,
1532 v1);
1533
1534 theValueStack.push(v);
1535 }
1536 else
1537 {
1538 result = false;
1539 }
1540 }
1541 }
1542 else
1543 {
1544 result = false;
1545 }
1546 break;
1547 }
1548 case OSSIM_EQU_TOKEN_COS:
1549 {
1550 theCurrentId = theLexer->yylex();
1551 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1552 {
1553 theCurrentId = theLexer->yylex();
1554 result = parseExpression();
1555 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1556 {
1557 if(theValueStack.size() > 0)
1558 {
1559 theCurrentId = theLexer->yylex();
1560 ossimEquValue v;
1561 ossimEquValue v1 = theValueStack.top();
1562 theValueStack.pop();
1563
1564 applyOp(ossimUnaryOpCos(),
1565 v,
1566 v1);
1567
1568 theValueStack.push(v);
1569 }
1570 else
1571 {
1572 result = false;
1573 }
1574 }
1575 }
1576 else
1577 {
1578 result = false;
1579 }
1580 break;
1581 }
1582 case OSSIM_EQU_TOKEN_COSD:
1583 {
1584 theCurrentId = theLexer->yylex();
1585 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1586 {
1587 theCurrentId = theLexer->yylex();
1588 result = parseExpression();
1589 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1590 {
1591 if(theValueStack.size() > 0)
1592 {
1593 theCurrentId = theLexer->yylex();
1594 ossimEquValue v;
1595 ossimEquValue v1 = theValueStack.top();
1596 theValueStack.pop();
1597
1598 applyOp(ossimUnaryOpCosd(),
1599 v,
1600 v1);
1601
1602 theValueStack.push(v);
1603 }
1604 else
1605 {
1606 result = false;
1607 }
1608 }
1609 }
1610 else
1611 {
1612 result = false;
1613 }
1614 break;
1615 }
1616 case OSSIM_EQU_TOKEN_ACOS:
1617 {
1618 theCurrentId = theLexer->yylex();
1619 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1620 {
1621 theCurrentId = theLexer->yylex();
1622 result = parseExpression();
1623 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1624 {
1625 if(theValueStack.size() > 0)
1626 {
1627 theCurrentId = theLexer->yylex();
1628 ossimEquValue v;
1629 ossimEquValue v1 = theValueStack.top();
1630 theValueStack.pop();
1631
1632 applyOp(ossimUnaryOpACos(),
1633 v,
1634 v1);
1635
1636 theValueStack.push(v);
1637 }
1638 else
1639 {
1640 result = false;
1641 }
1642 }
1643 }
1644 else
1645 {
1646 result = false;
1647 }
1648 break;
1649 }
1650 case OSSIM_EQU_TOKEN_ACOSD:
1651 {
1652 theCurrentId = theLexer->yylex();
1653 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1654 {
1655 theCurrentId = theLexer->yylex();
1656 result = parseExpression();
1657 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1658 {
1659 if(theValueStack.size() > 0)
1660 {
1661 theCurrentId = theLexer->yylex();
1662 ossimEquValue v;
1663 ossimEquValue v1 = theValueStack.top();
1664 theValueStack.pop();
1665
1666 applyOp(ossimUnaryOpACosd(),
1667 v,
1668 v1);
1669
1670 theValueStack.push(v);
1671 }
1672 else
1673 {
1674 result = false;
1675 }
1676 }
1677 }
1678 else
1679 {
1680 result = false;
1681 }
1682 break;
1683 }
1684 case OSSIM_EQU_TOKEN_TAN:
1685 {
1686 theCurrentId = theLexer->yylex();
1687 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1688 {
1689 theCurrentId = theLexer->yylex();
1690 result = parseExpression();
1691 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1692 {
1693 if(theValueStack.size() > 0)
1694 {
1695 theCurrentId = theLexer->yylex();
1696 ossimEquValue v;
1697 ossimEquValue v1 = theValueStack.top();
1698 theValueStack.pop();
1699
1700 applyOp(ossimUnaryOpTan(),
1701 v,
1702 v1);
1703
1704 theValueStack.push(v);
1705 }
1706 else
1707 {
1708 result = false;
1709 }
1710 }
1711 }
1712 else
1713 {
1714 result = false;
1715 }
1716 break;
1717 }
1718 case OSSIM_EQU_TOKEN_TAND:
1719 {
1720 theCurrentId = theLexer->yylex();
1721 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1722 {
1723 theCurrentId = theLexer->yylex();
1724 result = parseExpression();
1725 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1726 {
1727 if(theValueStack.size() > 0)
1728 {
1729 theCurrentId = theLexer->yylex();
1730 ossimEquValue v;
1731 ossimEquValue v1 = theValueStack.top();
1732 theValueStack.pop();
1733
1734 applyOp(ossimUnaryOpTand(),
1735 v,
1736 v1);
1737
1738 theValueStack.push(v);
1739 }
1740 else
1741 {
1742 result = false;
1743 }
1744 }
1745 }
1746 else
1747 {
1748 result = false;
1749 }
1750 break;
1751 }
1752 case OSSIM_EQU_TOKEN_ATAN:
1753 {
1754 theCurrentId = theLexer->yylex();
1755 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1756 {
1757 theCurrentId = theLexer->yylex();
1758 result = parseExpression();
1759 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1760 {
1761 if(theValueStack.size() > 0)
1762 {
1763 theCurrentId = theLexer->yylex();
1764 ossimEquValue v;
1765 ossimEquValue v1 = theValueStack.top();
1766 theValueStack.pop();
1767
1768 applyOp(ossimUnaryOpATan(),
1769 v,
1770 v1);
1771
1772 theValueStack.push(v);
1773 }
1774 else
1775 {
1776 result = false;
1777 }
1778 }
1779 }
1780 else
1781 {
1782 result = false;
1783 }
1784 break;
1785 }
1786 case OSSIM_EQU_TOKEN_ATAND:
1787 {
1788 theCurrentId = theLexer->yylex();
1789 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1790 {
1791 theCurrentId = theLexer->yylex();
1792 result = parseExpression();
1793 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1794 {
1795 if(theValueStack.size() > 0)
1796 {
1797 theCurrentId = theLexer->yylex();
1798 ossimEquValue v;
1799 ossimEquValue v1 = theValueStack.top();
1800 theValueStack.pop();
1801
1802 applyOp(ossimUnaryOpATand(),
1803 v,
1804 v1);
1805
1806 theValueStack.push(v);
1807 }
1808 else
1809 {
1810 result = false;
1811 }
1812 }
1813 }
1814 else
1815 {
1816 result = false;
1817 }
1818 break;
1819 }
1820 case OSSIM_EQU_TOKEN_LOG:
1821 {
1822 theCurrentId = theLexer->yylex();
1823 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1824 {
1825 theCurrentId = theLexer->yylex();
1826 result = parseExpression();
1827 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1828 {
1829 if(theValueStack.size() > 0)
1830 {
1831 theCurrentId = theLexer->yylex();
1832 ossimEquValue v;
1833 ossimEquValue v1 = theValueStack.top();
1834 theValueStack.pop();
1835
1836 applyOp(ossimUnaryOpLog(),
1837 v,
1838 v1);
1839
1840 theValueStack.push(v);
1841 }
1842 else
1843 {
1844 result = false;
1845 }
1846 }
1847 }
1848 else
1849 {
1850 result = false;
1851 }
1852 break;
1853 }
1854 case OSSIM_EQU_TOKEN_LOG10:
1855 {
1856 theCurrentId = theLexer->yylex();
1857 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1858 {
1859 theCurrentId = theLexer->yylex();
1860 result = parseExpression();
1861 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1862 {
1863 if(theValueStack.size() > 0)
1864 {
1865 theCurrentId = theLexer->yylex();
1866 ossimEquValue v;
1867 ossimEquValue v1 = theValueStack.top();
1868 theValueStack.pop();
1869
1870 applyOp(ossimUnaryOpLog10(),
1871 v,
1872 v1);
1873
1874 theValueStack.push(v);
1875 }
1876 else
1877 {
1878 result = false;
1879 }
1880 }
1881 }
1882 else
1883 {
1884 result = false;
1885 }
1886 break;
1887 }
1888 case OSSIM_EQU_TOKEN_SQRT:
1889 {
1890 theCurrentId = theLexer->yylex();
1891 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1892 {
1893 theCurrentId = theLexer->yylex();
1894 result = parseExpression();
1895 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1896 {
1897 if(theValueStack.size() > 0)
1898 {
1899 theCurrentId = theLexer->yylex();
1900 ossimEquValue v;
1901 ossimEquValue v1 = theValueStack.top();
1902 theValueStack.pop();
1903
1904 applyOp(ossimUnaryOpSqrt(),
1905 v,
1906 v1);
1907
1908 theValueStack.push(v);
1909 }
1910 else
1911 {
1912 result = false;
1913 }
1914 }
1915 }
1916 else
1917 {
1918 result = false;
1919 }
1920 break;
1921 }
1922 case OSSIM_EQU_TOKEN_EXP:
1923 {
1924 theCurrentId = theLexer->yylex();
1925 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
1926 {
1927 theCurrentId = theLexer->yylex();
1928 result = parseExpression();
1929 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
1930 {
1931 if(theValueStack.size() > 0)
1932 {
1933 theCurrentId = theLexer->yylex();
1934 ossimEquValue v;
1935 ossimEquValue v1 = theValueStack.top();
1936 theValueStack.pop();
1937
1938 applyOp(ossimUnaryOpExp(),
1939 v,
1940 v1);
1941
1942 theValueStack.push(v);
1943 }
1944 else
1945 {
1946 result = false;
1947 }
1948 }
1949 }
1950 else
1951 {
1952 result = false;
1953 }
1954 break;
1955 }
1956 default:
1957 {
1958 result = false;
1959 }
1960 }
1961
1962 return result;
1963 }
1964
parseUnaryFactor()1965 bool ossimEquationCombiner::parseUnaryFactor()
1966 {
1967 bool result = false;
1968
1969
1970 if(theCurrentId == OSSIM_EQU_TOKEN_MINUS)
1971 {
1972 theCurrentId = theLexer->yylex();
1973
1974 if(parseFactor())
1975 {
1976 if(theValueStack.size() > 0)
1977 {
1978 ossimEquValue v;
1979 ossimEquValue v1 = theValueStack.top();
1980 theValueStack.pop();
1981
1982 applyOp(ossimUnaryOpNeg(),
1983 v,
1984 v1);
1985
1986 theValueStack.push(v);
1987 }
1988 else
1989 {
1990 result = false;
1991 }
1992
1993 result = true;
1994 }
1995 else
1996 {
1997 result = false;
1998 }
1999 }
2000 else if(theCurrentId == OSSIM_EQU_TOKEN_TILDE)
2001 {
2002 theCurrentId = theLexer->yylex();
2003
2004 if(parseFactor())
2005 {
2006 if(theValueStack.size() > 0)
2007 {
2008 ossimEquValue v;
2009 ossimEquValue v1 = theValueStack.top();
2010 theValueStack.pop();
2011
2012 applyOp(ossimUnaryOpOnesComplement(),
2013 v,
2014 v1);
2015
2016 theValueStack.push(v);
2017 }
2018 else
2019 {
2020 result = false;
2021 }
2022
2023 result = true;
2024 }
2025 else
2026 {
2027 result = false;
2028 }
2029 }
2030 return result;
2031 }
2032
parseFactor()2033 bool ossimEquationCombiner::parseFactor()
2034 {
2035 bool result = false;
2036
2037 switch(theCurrentId)
2038 {
2039 case OSSIM_EQU_TOKEN_CONSTANT:
2040 {
2041 ossimEquValue v;
2042
2043 v.type = OSSIM_EQU_DOUBLE_TYPE;
2044 v.d.doubleValue = atof(theLexer->YYText());
2045 theValueStack.push(v);
2046
2047 theCurrentId = theLexer->yylex();
2048
2049 result = true;
2050 break;
2051 }
2052 case OSSIM_EQU_TOKEN_PI:
2053 {
2054 ossimEquValue v;
2055
2056 v.type = OSSIM_EQU_DOUBLE_TYPE;
2057 v.d.doubleValue = M_PI;
2058 theValueStack.push(v);
2059
2060 theCurrentId = theLexer->yylex();
2061
2062 result = true;
2063 break;
2064 }
2065 case OSSIM_EQU_TOKEN_IMAGE_VARIABLE:
2066 {
2067 theCurrentId = theLexer->yylex();
2068 if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_ARRAY_BRACKET)
2069 {
2070 theCurrentId = theLexer->yylex();
2071 if(parseExpression())
2072 {
2073 if(!theValueStack.empty())
2074 {
2075 if(theValueStack.top().type == OSSIM_EQU_DOUBLE_TYPE)
2076 {
2077 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_ARRAY_BRACKET)
2078 {
2079 theCurrentId = theLexer->yylex();
2080 ossim_uint32 index = (ossim_uint32)theValueStack.top().d.doubleValue;
2081 theValueStack.pop();
2082 ossimRefPtr<ossimImageData> data = getNewImageData(index);
2083 result = true;
2084 if(data.valid())
2085 {
2086 ossimEquValue v;
2087 v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
2088 v.d.imageDataValue = data.release();
2089 theValueStack.push(v);
2090
2091 }
2092 else
2093 {
2094 ossimNotify(ossimNotifyLevel_WARN)
2095 <<"Data is NULL for array operation" << endl;
2096 }
2097 result = true;
2098 }
2099 else
2100 {
2101 ossimNotify(ossimNotifyLevel_WARN)
2102 << "Mismatched Right array bracket" << endl;
2103 }
2104 }
2105 else
2106 {
2107 ossimNotify(ossimNotifyLevel_WARN)
2108 << "Expression between array brackets is not a number"
2109 << endl;
2110 }
2111 }
2112 else
2113 {
2114 ossimNotify(ossimNotifyLevel_WARN)
2115 << "no expression within array brackets" << endl;
2116 }
2117 }
2118 else
2119 {
2120 ossimNotify(ossimNotifyLevel_WARN)
2121 << "Unabel to parse expression"<<endl;
2122 }
2123 }
2124 else
2125 {
2126 ossimNotify(ossimNotifyLevel_WARN)
2127 <<"Need left array brackets to access an input source"<<endl;
2128 }
2129
2130 break;
2131 }
2132 case OSSIM_EQU_TOKEN_LEFT_PAREN:
2133 {
2134 theCurrentId = theLexer->yylex();
2135 if(parseExpression())
2136 {
2137 if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
2138 {
2139 result = true;
2140 theCurrentId = theLexer->yylex();
2141 }
2142 else
2143 {
2144 ossimNotify(ossimNotifyLevel_WARN)
2145 << "Right parenthesis missing" << endl;
2146 result = false;
2147 }
2148 }
2149 else
2150 {
2151 ossimNotify(ossimNotifyLevel_WARN)
2152 << "Unable to parse expression within parenthesis" << endl;
2153 result = false;
2154 }
2155
2156 break;
2157 }
2158 }
2159 if(!result) result = parseUnaryFactor();
2160
2161 if(!result) result = parseStdFuncs();
2162
2163 return result;
2164 }
2165
parseRestOfTerm()2166 bool ossimEquationCombiner::parseRestOfTerm()
2167 {
2168 //---
2169 // Parse the following rule:
2170 // RestOfTerm: * Factor RestOfTerm | / Factor RestOfTerm |
2171 // ^ Factor RestOfTerm
2172 //---
2173 bool result = true;
2174
2175 switch(theCurrentId)
2176 {
2177 case OSSIM_EQU_TOKEN_MULT:
2178 {
2179 theCurrentId = theLexer->yylex();
2180 if(parseFactor())
2181 {
2182 if(theValueStack.size() > 1)
2183 {
2184 ossimEquValue v;
2185
2186 ossimEquValue v2 = theValueStack.top();
2187 theValueStack.pop();
2188 ossimEquValue v1 = theValueStack.top();
2189 theValueStack.pop();
2190
2191 applyOp(ossimBinaryOpMul(),
2192 v,
2193 v1,
2194 v2);
2195
2196 theValueStack.push(v);
2197 }
2198 else
2199 {
2200 ossimNotify(ossimNotifyLevel_WARN)
2201 << "Multiplication requires two arguments" << endl;
2202 result = false;
2203 }
2204 if(result)
2205 {
2206 result = parseRestOfTerm();
2207 }
2208 }
2209 else
2210 {
2211 result = false;
2212 }
2213 break;
2214 }
2215 case OSSIM_EQU_TOKEN_DIV:
2216 {
2217 theCurrentId = theLexer->yylex();
2218 if(parseFactor())
2219 {
2220 if(theValueStack.size() > 1)
2221 {
2222 ossimEquValue v;
2223
2224 ossimEquValue v2 = theValueStack.top();
2225 theValueStack.pop();
2226 ossimEquValue v1 = theValueStack.top();
2227 theValueStack.pop();
2228
2229 applyOp(ossimBinaryOpDiv(),
2230 v,
2231 v1,
2232 v2);
2233
2234 theValueStack.push(v);
2235 }
2236 else
2237 {
2238 result = false;
2239 }
2240 if(result)
2241 {
2242 result = parseRestOfTerm();
2243 }
2244 }
2245 else
2246 {
2247 result = false;
2248 }
2249
2250 break;
2251 }
2252 case OSSIM_EQU_TOKEN_XOR:
2253 {
2254 theCurrentId = theLexer->yylex();
2255 if(parseFactor())
2256 {
2257 if(theValueStack.size() > 1)
2258 {
2259 ossimEquValue v;
2260
2261 ossimEquValue v2 = theValueStack.top();
2262 theValueStack.pop();
2263 ossimEquValue v1 = theValueStack.top();
2264 theValueStack.pop();
2265
2266 applyOp(ossimBinaryOpXor(),
2267 v,
2268 v1,
2269 v2);
2270
2271 theValueStack.push(v);
2272 }
2273 else
2274 {
2275 result = false;
2276 }
2277 if(result)
2278 {
2279 result = parseRestOfTerm();
2280 }
2281 }
2282 else
2283 {
2284 result = false;
2285 }
2286
2287 break;
2288 }
2289 case OSSIM_EQU_TOKEN_AMPERSAND:
2290 {
2291 theCurrentId = theLexer->yylex();
2292 if(parseFactor())
2293 {
2294 if(theValueStack.size() > 1)
2295 {
2296 ossimEquValue v;
2297
2298 ossimEquValue v2 = theValueStack.top();
2299 theValueStack.pop();
2300 ossimEquValue v1 = theValueStack.top();
2301 theValueStack.pop();
2302
2303 applyOp(ossimBinaryOpAnd(),
2304 v,
2305 v1,
2306 v2);
2307
2308 theValueStack.push(v);
2309 }
2310 else
2311 {
2312 result = false;
2313 }
2314 if(result)
2315 {
2316 result = parseRestOfTerm();
2317 }
2318 }
2319 else
2320 {
2321 result = false;
2322 }
2323
2324 break;
2325 }
2326 case OSSIM_EQU_TOKEN_OR_BAR:
2327 {
2328 theCurrentId = theLexer->yylex();
2329 if(parseFactor())
2330 {
2331 if(theValueStack.size() > 1)
2332 {
2333 ossimEquValue v;
2334
2335 ossimEquValue v2 = theValueStack.top();
2336 theValueStack.pop();
2337 ossimEquValue v1 = theValueStack.top();
2338 theValueStack.pop();
2339
2340 applyOp(ossimBinaryOpOr(),
2341 v,
2342 v1,
2343 v2);
2344
2345 theValueStack.push(v);
2346 }
2347 else
2348 {
2349 result = false;
2350 }
2351 if(result)
2352 {
2353 result = parseRestOfTerm();
2354 }
2355 }
2356 else
2357 {
2358 result = false;
2359 }
2360
2361 break;
2362 }
2363 case OSSIM_EQU_TOKEN_MOD:
2364 {
2365 theCurrentId = theLexer->yylex();
2366 if(parseFactor())
2367 {
2368 if(theValueStack.size() > 1)
2369 {
2370 ossimEquValue v;
2371
2372 ossimEquValue v2 = theValueStack.top();
2373 theValueStack.pop();
2374 ossimEquValue v1 = theValueStack.top();
2375 theValueStack.pop();
2376
2377 applyOp(ossimBinaryOpMod(),
2378 v,
2379 v1,
2380 v2);
2381
2382 theValueStack.push(v);
2383 }
2384 else
2385 {
2386 result = false;
2387 }
2388 if(result)
2389 {
2390 result = parseRestOfTerm();
2391 }
2392 }
2393 else
2394 {
2395 result = false;
2396 }
2397
2398 break;
2399 }
2400 case OSSIM_EQU_TOKEN_POWER:
2401 {
2402 theCurrentId = theLexer->yylex();
2403 if(parseFactor())
2404 {
2405 if(theValueStack.size() > 1)
2406 {
2407 ossimEquValue v;
2408
2409 ossimEquValue v2 = theValueStack.top();
2410 theValueStack.pop();
2411 ossimEquValue v1 = theValueStack.top();
2412 theValueStack.pop();
2413
2414 applyOp(ossimBinaryOpPow(),
2415 v,
2416 v1,
2417 v2);
2418
2419 theValueStack.push(v);
2420 }
2421 else
2422 {
2423 result = false;
2424 }
2425 if(result)
2426 {
2427 result = parseRestOfTerm();
2428 }
2429 }
2430 else
2431 {
2432 result = false;
2433 }
2434 break;
2435 }
2436 case OSSIM_EQU_TOKEN_BEQUAL:
2437 {
2438 theCurrentId = theLexer->yylex();
2439 if(parseFactor())
2440 {
2441 if(theValueStack.size() > 1)
2442 {
2443 ossimEquValue v;
2444
2445 ossimEquValue v2 = theValueStack.top();
2446 theValueStack.pop();
2447 ossimEquValue v1 = theValueStack.top();
2448 theValueStack.pop();
2449
2450 applyOp(ossimBinaryOpEqual(),
2451 v,
2452 v1,
2453 v2);
2454
2455 theValueStack.push(v);
2456 }
2457 else
2458 {
2459 result = false;
2460 }
2461 if(result)
2462 {
2463 result = parseRestOfTerm();
2464 }
2465 }
2466 else
2467 {
2468 result = false;
2469 }
2470
2471 break;
2472 }
2473 case OSSIM_EQU_TOKEN_BGREATER:
2474 {
2475 theCurrentId = theLexer->yylex();
2476 if(parseFactor())
2477 {
2478 if(theValueStack.size() > 1)
2479 {
2480 ossimEquValue v;
2481
2482 ossimEquValue v2 = theValueStack.top();
2483 theValueStack.pop();
2484 ossimEquValue v1 = theValueStack.top();
2485 theValueStack.pop();
2486
2487 applyOp(ossimBinaryOpGreater(),
2488 v,
2489 v1,
2490 v2);
2491
2492 theValueStack.push(v);
2493 }
2494 else
2495 {
2496 result = false;
2497 }
2498 if(result)
2499 {
2500 result = parseRestOfTerm();
2501 }
2502 }
2503 else
2504 {
2505 result = false;
2506 }
2507
2508 break;
2509 }
2510 case OSSIM_EQU_TOKEN_BGREATEROREQUAL:
2511 {
2512 theCurrentId = theLexer->yylex();
2513 if(parseFactor())
2514 {
2515 if(theValueStack.size() > 1)
2516 {
2517 ossimEquValue v;
2518
2519 ossimEquValue v2 = theValueStack.top();
2520 theValueStack.pop();
2521 ossimEquValue v1 = theValueStack.top();
2522 theValueStack.pop();
2523
2524 applyOp(ossimBinaryOpGreaterOrEqual(),
2525 v,
2526 v1,
2527 v2);
2528
2529 theValueStack.push(v);
2530 }
2531 else
2532 {
2533 result = false;
2534 }
2535 if(result)
2536 {
2537 result = parseRestOfTerm();
2538 }
2539 }
2540 else
2541 {
2542 result = false;
2543 }
2544
2545 break;
2546 }
2547 case OSSIM_EQU_TOKEN_BLESS:
2548 {
2549 theCurrentId = theLexer->yylex();
2550 if(parseFactor())
2551 {
2552 if(theValueStack.size() > 1)
2553 {
2554 ossimEquValue v;
2555
2556 ossimEquValue v2 = theValueStack.top();
2557 theValueStack.pop();
2558 ossimEquValue v1 = theValueStack.top();
2559 theValueStack.pop();
2560
2561 applyOp(ossimBinaryOpLess(),
2562 v,
2563 v1,
2564 v2);
2565
2566 theValueStack.push(v);
2567 }
2568 else
2569 {
2570 result = false;
2571 }
2572 if(result)
2573 {
2574 result = parseRestOfTerm();
2575 }
2576 }
2577 else
2578 {
2579 result = false;
2580 }
2581
2582 break;
2583 }
2584 case OSSIM_EQU_TOKEN_BLESSOREQUAL:
2585 {
2586 theCurrentId = theLexer->yylex();
2587 if(parseFactor())
2588 {
2589 if(theValueStack.size() > 1)
2590 {
2591 ossimEquValue v;
2592
2593 ossimEquValue v2 = theValueStack.top();
2594 theValueStack.pop();
2595 ossimEquValue v1 = theValueStack.top();
2596 theValueStack.pop();
2597
2598 applyOp(ossimBinaryOpLessOrEqual(),
2599 v,
2600 v1,
2601 v2);
2602
2603 theValueStack.push(v);
2604 }
2605 else
2606 {
2607 result = false;
2608 }
2609 if(result)
2610 {
2611 result = parseRestOfTerm();
2612 }
2613 }
2614 else
2615 {
2616 result = false;
2617 }
2618
2619 break;
2620 }
2621 case OSSIM_EQU_TOKEN_BDIFFERENT:
2622 {
2623 theCurrentId = theLexer->yylex();
2624 if(parseFactor())
2625 {
2626 if(theValueStack.size() > 1)
2627 {
2628 ossimEquValue v;
2629
2630 ossimEquValue v2 = theValueStack.top();
2631 theValueStack.pop();
2632 ossimEquValue v1 = theValueStack.top();
2633 theValueStack.pop();
2634
2635 applyOp(ossimBinaryOpDifferent(),
2636 v,
2637 v1,
2638 v2);
2639
2640 theValueStack.push(v);
2641 }
2642 else
2643 {
2644 result = false;
2645 }
2646 if(result)
2647 {
2648 result = parseRestOfTerm();
2649 }
2650 }
2651 else
2652 {
2653 result = false;
2654 }
2655
2656 break;
2657 }
2658
2659 }
2660
2661 return result;
2662 }
2663
parseTerm()2664 bool ossimEquationCombiner::parseTerm()
2665 {
2666 // parse the following rule:
2667 //
2668 // Term : Factor RestOfTerm
2669
2670 bool result = false;
2671
2672 result = parseFactor();
2673
2674 if(result)
2675 {
2676 result = parseRestOfTerm();
2677 }
2678
2679 return result;
2680 }
2681
parseRestOfExp()2682 bool ossimEquationCombiner::parseRestOfExp()
2683 {
2684 // parse the following rule:
2685 // RestOfExpression : + Term RestOfExpression | - Term RestOfExpression | epsilon
2686 //
2687 bool result = true;
2688
2689 if(theCurrentId == OSSIM_EQU_TOKEN_PLUS)
2690 {
2691 theCurrentId = theLexer->yylex();
2692 if(parseTerm())
2693 {
2694
2695 if(theValueStack.size() > 1)
2696 {
2697 ossimEquValue v;
2698
2699 ossimEquValue v2 = theValueStack.top();
2700 theValueStack.pop();
2701 ossimEquValue v1 = theValueStack.top();
2702 theValueStack.pop();
2703
2704
2705 applyOp(ossimBinaryOpAdd(),
2706 v,
2707 v1,
2708 v2);
2709
2710 theValueStack.push(v);
2711 }
2712 else
2713 {
2714 result = false;
2715 }
2716 if(result)
2717 {
2718 result = parseRestOfExp();
2719 }
2720 }
2721 else
2722 {
2723 result = false;
2724 }
2725 }
2726 else if(theCurrentId == OSSIM_EQU_TOKEN_MINUS)
2727 {
2728 theCurrentId = theLexer->yylex();
2729 if(parseTerm())
2730 {
2731 if(theValueStack.size() > 1)
2732 {
2733 ossimEquValue v;
2734
2735 ossimEquValue v2 = theValueStack.top();
2736 theValueStack.pop();
2737 ossimEquValue v1 = theValueStack.top();
2738 theValueStack.pop();
2739
2740 applyOp(ossimBinaryOpSub(),
2741 v,
2742 v1,
2743 v2);
2744
2745 theValueStack.push(v);
2746 }
2747 else
2748 {
2749 result = false;
2750 }
2751 if(result)
2752 {
2753 result = parseRestOfExp();
2754 }
2755 }
2756 else
2757 {
2758 result = false;
2759 }
2760 }
2761
2762 return result;
2763 }
2764
getImageData(ossim_uint32 index)2765 ossimRefPtr<ossimImageData> ossimEquationCombiner::getImageData(ossim_uint32 index)
2766 {
2767 ossimRefPtr<ossimImageData> result;
2768 ossimConnectableObject* obj = getInput(index);
2769
2770 if(obj)
2771 {
2772 theCastFilter->connectMyInputTo(0, obj);
2773 result= (theCastFilter->getTile(theTile->getImageRectangle(),
2774 theCurrentResLevel));
2775
2776 if(result.valid())
2777 {
2778 result->setMinPix(theTile->getMinPix(), theTile->getNumberOfBands());
2779 result->setMaxPix(theTile->getMaxPix(), theTile->getNumberOfBands());
2780 }
2781 }
2782
2783 return result;
2784 }
2785
getNewImageData(ossim_uint32 index)2786 ossimRefPtr<ossimImageData> ossimEquationCombiner::getNewImageData(
2787 ossim_uint32 index)
2788 {
2789 ossimRefPtr<ossimImageData> result = getImageData(index);
2790
2791 if(result.valid())
2792 {
2793 if(result->getBuf())
2794 {
2795 result = (ossimImageData*)result->dup();
2796 }
2797 }
2798
2799 return result;
2800 }
2801
parseExpression()2802 bool ossimEquationCombiner::parseExpression()
2803 {
2804 // parse the following rule:
2805 // expression : Term ResOfExpression
2806 //
2807
2808 bool result = false;
2809
2810 if(parseTerm())
2811 {
2812 result = parseRestOfExp();
2813 }
2814
2815 return result;
2816 }
2817
parseEquation()2818 ossimRefPtr<ossimImageData> ossimEquationCombiner::parseEquation()
2819 {
2820 ostringstream s;
2821
2822 s << theEquation;
2823
2824 istringstream inS(s.str());
2825 theLexer->switch_streams(&inS, &ossimNotify(ossimNotifyLevel_WARN));
2826
2827 theCurrentId = theLexer->yylex();
2828
2829 while(theCurrentId)
2830 {
2831 if(!parseExpression())
2832 {
2833 break;
2834 }
2835 }
2836
2837 if(!theValueStack.empty())
2838 {
2839 assignValue();
2840 theTile->validate();
2841 clearStacks();
2842 }
2843
2844 return theTile;
2845 }
2846
applyClamp(ossimImageData * & result,const vector<ossimEquValue> & argList)2847 bool ossimEquationCombiner::applyClamp(ossimImageData* &result,
2848 const vector<ossimEquValue>& argList)
2849 {
2850 if(result)
2851 {
2852 // Delete the object indirectly through an ossimRefPtr.
2853 ossimRefPtr<ossimImageData> id = result;
2854 id = NULL;
2855 result = (ossimImageData*) NULL;
2856 }
2857 if(argList.size() <3)
2858 {
2859 return false;
2860 }
2861
2862 if(argList[0].type == OSSIM_EQU_DOUBLE_TYPE)
2863 {
2864 return false;
2865 }
2866 else if( (argList[1].type == OSSIM_EQU_DOUBLE_TYPE)&&
2867 (argList[2].type == OSSIM_EQU_DOUBLE_TYPE))
2868 {
2869 result = argList[0].d.imageDataValue;
2870
2871 if(argList[0].d.imageDataValue)
2872 {
2873 ossimDataObjectStatus status = result->getDataObjectStatus();
2874 if((status != OSSIM_NULL) &&
2875 (status != OSSIM_EMPTY))
2876 {
2877 double minValue = argList[1].d.doubleValue;
2878 double maxValue = argList[2].d.doubleValue;
2879
2880 if(minValue > maxValue)
2881 {
2882 std::swap(minValue, maxValue);
2883 }
2884
2885 int band = 0;
2886 int offset = 0;
2887
2888 int upperBoundBand = result->getNumberOfBands();
2889 int offsetUpperBound = result->getWidth()*result->getHeight();
2890
2891 if(status == OSSIM_PARTIAL)
2892 {
2893 for(band = 0; band < upperBoundBand; ++band)
2894 {
2895 double np = static_cast<double>(result->getNullPix(band));
2896 double *buf = static_cast<double*>(result->getBuf(band));
2897 for(offset = 0; offset < offsetUpperBound; ++ offset)
2898 {
2899 if( *buf != np )
2900 {
2901 if( (*buf) < minValue) *buf = minValue;
2902 else if( (*buf) >maxValue) *buf = maxValue;
2903 }
2904 ++buf;
2905 }
2906 }
2907 }
2908 else
2909 {
2910 for(band = 0; band < upperBoundBand; ++band)
2911 {
2912 double *buf = static_cast<double*>(result->getBuf(band));
2913 for(offset = 0; offset < offsetUpperBound; ++ offset)
2914 {
2915 if( (*buf) < minValue) *buf = minValue;
2916 else if( (*buf) >maxValue) *buf = maxValue;
2917 ++buf;
2918 }
2919 }
2920 }
2921 }
2922 }
2923
2924 return true;
2925 }
2926 return false;
2927 }
2928
applyConvolution(ossimImageData * & result,const vector<ossimEquValue> & argList)2929 bool ossimEquationCombiner::applyConvolution(ossimImageData* &result,
2930 const vector<ossimEquValue>& argList)
2931 {
2932 if(result)
2933 {
2934 // Delete the object indirectly through an ossimRefPtr.
2935 ossimRefPtr<ossimImageData> id = result;
2936 id = NULL;
2937 result = (ossimImageData*) NULL;
2938 }
2939 if(argList.size() <4) return false;
2940
2941 for(ossim_uint32 i = 0; i < argList.size(); ++i)
2942 {
2943 if(argList[i].type != OSSIM_EQU_DOUBLE_TYPE)
2944 {
2945 return false;
2946 }
2947 }
2948
2949 ossim_uint32 index = (ossim_uint32)argList[0].d.doubleValue;
2950 int rows = (int)argList[1].d.doubleValue;
2951 int cols = (int)argList[2].d.doubleValue;
2952
2953 if((rows*cols) != (int)(argList.size()-3))
2954 {
2955 return false;
2956 }
2957
2958 NEWMAT::Matrix m(rows,cols);
2959
2960 int count = 3;
2961 for(int r = 0; r< rows;++r)
2962 {
2963 for(int c=0;c<cols;++c)
2964 {
2965 m[r][c] = argList[count].d.doubleValue;
2966 ++count;
2967 }
2968 }
2969 ossimConnectableObject* obj = getInput(index);
2970 if(obj)
2971 {
2972 ossimRefPtr<ossimConvolutionSource> conv = new ossimConvolutionSource(NULL, m);
2973
2974 conv->connectMyInputTo(0, obj);
2975 theCastFilter->connectMyInputTo(0, conv.get());
2976
2977 ossimRefPtr<ossimImageData> tempData =
2978 theCastFilter->getTile(theTile->getImageRectangle(),
2979 theCurrentResLevel);
2980 if(tempData.valid())
2981 {
2982 result = (ossimImageData*)tempData->dup();
2983 }
2984 else
2985 {
2986 result = (ossimImageData*)theTile->dup();
2987 }
2988 conv->disconnect();
2989 conv = 0;
2990 }
2991 if(result)
2992 {
2993 return true;
2994 }
2995
2996 return false;
2997 }
2998
applyBlurr(ossimImageData * & result,const vector<ossimEquValue> & argList)2999 bool ossimEquationCombiner::applyBlurr(ossimImageData* &result,
3000 const vector<ossimEquValue>& argList)
3001 {
3002 if(result)
3003 {
3004 // Delete the object indirectly through an ossimRefPtr.
3005 ossimRefPtr<ossimImageData> id = result;
3006 id = NULL;
3007 result = (ossimImageData*) NULL;
3008 }
3009 if(argList.size() !=3) return false;
3010
3011 for(ossim_uint32 i = 0; i < argList.size(); ++i)
3012 {
3013 if(argList[i].type != OSSIM_EQU_DOUBLE_TYPE)
3014 {
3015 return false;
3016 }
3017 }
3018
3019 ossim_uint32 index = (ossim_uint32)argList[0].d.doubleValue;
3020 int rows = (int)argList[1].d.doubleValue;
3021 int cols = (int)argList[2].d.doubleValue;
3022
3023 NEWMAT::Matrix m(rows, cols);
3024
3025 m = 1.0/(rows*cols);
3026
3027 ossimConnectableObject* obj = getInput(index);
3028 if(obj)
3029 {
3030 ossimRefPtr<ossimConvolutionSource> conv = new ossimConvolutionSource(NULL,
3031 m);
3032
3033 conv->connectMyInputTo(0, obj);
3034 theCastFilter->connectMyInputTo(0, conv.get());
3035 theCastFilter->initialize();
3036
3037 ossimRefPtr<ossimImageData> tempData =
3038 theCastFilter->getTile(theTile->getImageRectangle(),
3039 theCurrentResLevel);
3040 if(tempData.valid())
3041 {
3042 result = (ossimImageData*)tempData->dup();
3043 }
3044 conv->disconnect();
3045 conv = 0;
3046 }
3047
3048 if(result)
3049 {
3050 return true;
3051 }
3052
3053 return false;
3054 }
3055
applyShift(ossimImageData * & result,const vector<ossimEquValue> & argList)3056 bool ossimEquationCombiner::applyShift(ossimImageData* &result,
3057 const vector<ossimEquValue>& argList)
3058 {
3059 if(result)
3060 {
3061 // Delete the object indirectly through an ossimRefPtr.
3062 ossimRefPtr<ossimImageData> id = result;
3063 id = NULL;
3064 result = (ossimImageData*) NULL;
3065 }
3066 if(argList.size() !=3) return false;
3067
3068 for(ossim_uint32 i = 0; i < argList.size(); ++i)
3069 {
3070 if(argList[i].type != OSSIM_EQU_DOUBLE_TYPE)
3071 {
3072 return false;
3073 }
3074 }
3075
3076 ossim_uint32 index = (ossim_uint32)argList[0].d.doubleValue;
3077 int x = (int)argList[1].d.doubleValue;
3078 int y = (int)argList[2].d.doubleValue;
3079
3080 ossimConnectableObject* obj = getInput(index);
3081 if(obj)
3082 {
3083 ossimRefPtr<ossimSubImageTileSource> shiftSource =
3084 new ossimSubImageTileSource(NULL, ossimIpt(x, y));
3085
3086 shiftSource->connectMyInputTo(0, obj);
3087 theCastFilter->connectMyInputTo(0, shiftSource.get());
3088
3089 ossimRefPtr<ossimImageData> tempData =
3090 theCastFilter->getTile(theTile->getImageRectangle(),
3091 theCurrentResLevel);
3092 if(tempData.valid())
3093 {
3094 result = (ossimImageData*)tempData->dup();
3095 }
3096 shiftSource->disconnect();
3097 shiftSource = 0;
3098 }
3099
3100 if(result)
3101 {
3102 return true;
3103 }
3104
3105 return false;
3106 }
3107
applyOp(const ossimBinaryOp & op,ossimEquValue & result,ossimEquValue & v1,ossimEquValue & v2)3108 bool ossimEquationCombiner::applyOp(const ossimBinaryOp& op,
3109 ossimEquValue& result,
3110 ossimEquValue& v1,
3111 ossimEquValue& v2)
3112 {
3113 bool returnValue = true;
3114
3115 if(v1.type == OSSIM_EQU_DOUBLE_TYPE)
3116 {
3117 if(v2.type == OSSIM_EQU_DOUBLE_TYPE)
3118 {
3119 result.type = OSSIM_EQU_DOUBLE_TYPE;
3120 result.d.doubleValue = op.apply(v1.d.doubleValue, v2.d.doubleValue);
3121 }
3122 else if(v2.type == OSSIM_EQU_IMAGE_DATA_TYPE)
3123 {
3124 returnValue = applyOp(op,
3125 v1.d.doubleValue,
3126 v2.d.imageDataValue);
3127
3128 result.type = OSSIM_EQU_IMAGE_DATA_TYPE;
3129 result.d.imageDataValue = v2.d.imageDataValue;
3130 }
3131 else
3132 {
3133 returnValue = false;
3134 }
3135 }
3136 else if(v1.type == OSSIM_EQU_IMAGE_DATA_TYPE)
3137 {
3138 if(v2.type == OSSIM_EQU_DOUBLE_TYPE)
3139 {
3140
3141 returnValue = applyOp(op,
3142 v1.d.imageDataValue,
3143 v2.d.doubleValue);
3144
3145 result.type = OSSIM_EQU_IMAGE_DATA_TYPE;
3146 result.d.imageDataValue = v1.d.imageDataValue;
3147 returnValue = true;
3148 }
3149 else if(v2.type == OSSIM_EQU_IMAGE_DATA_TYPE)
3150 {
3151 returnValue = applyOp(op,
3152 v1.d.imageDataValue,
3153 v2.d.imageDataValue);
3154 result.type = OSSIM_EQU_IMAGE_DATA_TYPE;
3155 result.d.imageDataValue = v1.d.imageDataValue;
3156
3157 // Delete the object indirectly through an ossimRefPtr.
3158 ossimRefPtr<ossimImageData> id = v2.d.imageDataValue;
3159 id = NULL;
3160 v2.d.imageDataValue = (ossimImageData*)NULL;
3161 returnValue = true;
3162 }
3163 else
3164 {
3165 returnValue = false;
3166 }
3167 }
3168 else
3169 {
3170 returnValue = false;
3171 }
3172
3173 return returnValue;
3174 }
3175
applyOp(const ossimBinaryOp & op,ossimImageData * v1,double v2)3176 bool ossimEquationCombiner::applyOp(const ossimBinaryOp& op,
3177 ossimImageData* v1,
3178 double v2)
3179 {
3180 double* buf = static_cast<double*>(v1->getBuf());
3181 if(!buf) return true;
3182 ossimDataObjectStatus status = v1->getDataObjectStatus();
3183
3184 if(status == OSSIM_EMPTY || status == OSSIM_NULL)
3185 {
3186 return true;
3187 }
3188
3189 if(status == OSSIM_FULL )
3190 {
3191 ossim_uint32 size = v1->getSize();
3192 double value = (static_cast<double>(v2));
3193
3194 for(ossim_uint32 i = 0; i < size; ++i)
3195 {
3196 *buf = (double)op.apply(*buf, value);
3197 ++buf;
3198 }
3199 }
3200 else
3201 {
3202 ossim_uint32 sizePerBand = v1->getSizePerBand();
3203 ossim_uint32 numberOfBands = v1->getNumberOfBands();
3204
3205 if(numberOfBands)
3206 {
3207 for(ossim_uint32 band = 0; band < numberOfBands; ++band)
3208 {
3209 double* buf = static_cast<double*>(v1->getBuf(band));
3210
3211 if(buf)
3212 {
3213 double np = static_cast<double>(v1->getNullPix()[band]);
3214
3215 for(ossim_uint32 offset = 0; offset < sizePerBand;++offset)
3216 {
3217 if(*buf != np)
3218 {
3219 *buf = (double)op.apply(*buf, v2);
3220 }
3221 ++buf;
3222 }
3223 }
3224 }
3225 }
3226 }
3227 return true;
3228 }
3229
applyOp(const ossimBinaryOp & op,double v1,ossimImageData * v2)3230 bool ossimEquationCombiner::applyOp(const ossimBinaryOp& op,
3231 double v1,
3232 ossimImageData* v2)
3233 {
3234 double* buf = static_cast<double*>(v2->getBuf());
3235 if(!buf) return true;
3236 ossimDataObjectStatus status = v2->getDataObjectStatus();
3237
3238 if(status == OSSIM_EMPTY || status == OSSIM_NULL)
3239 {
3240 return true;
3241 }
3242
3243 if(status == OSSIM_FULL )
3244 {
3245 ossim_uint32 size = v2->getSize();
3246 double value = (static_cast<double>(v1));
3247
3248 for(ossim_uint32 i = 0; i < size; ++i)
3249 {
3250 *buf = (double)op.apply(value, *buf);
3251 ++buf;
3252 }
3253 }
3254 else
3255 {
3256 ossim_uint32 sizePerBand = v2->getSizePerBand();
3257 ossim_uint32 numberOfBands = v2->getNumberOfBands();
3258
3259 if(numberOfBands)
3260 {
3261 for(ossim_uint32 band = 0; band < numberOfBands; ++band)
3262 {
3263 double* buf = static_cast<double*>(v2->getBuf(band));
3264
3265 if(buf)
3266 {
3267 double np = static_cast<double>(v2->getNullPix()[band]);
3268
3269 for(ossim_uint32 offset = 0; offset < sizePerBand; ++offset)
3270 {
3271 if(*buf != np)
3272 {
3273 *buf = (double)op.apply((double)v1, *buf);
3274 }
3275 ++buf;
3276 }
3277 }
3278 }
3279 }
3280 }
3281
3282 return true;
3283 }
3284
applyOp(const ossimBinaryOp & op,ossimImageData * v1,ossimImageData * v2)3285 bool ossimEquationCombiner::applyOp(const ossimBinaryOp& op,
3286 ossimImageData* v1,
3287 ossimImageData* v2)
3288 {
3289 ossim_uint32 minNumberOfBands = std::min(v1->getNumberOfBands(), v2->getNumberOfBands());
3290 ossim_uint32 maxNumberOfBands = std::max(v1->getNumberOfBands(), v2->getNumberOfBands());
3291
3292 ossim_uint32 size = v1->getWidth()*v1->getHeight();
3293 ossimDataObjectStatus status1 = v1->getDataObjectStatus();
3294 ossimDataObjectStatus status2 = v2->getDataObjectStatus();
3295
3296 double** bandV1 = new double*[maxNumberOfBands];
3297 double** bandV2 = new double*[maxNumberOfBands];
3298 double* bandV1Np = new double[maxNumberOfBands];
3299 double* bandV2Np = new double[maxNumberOfBands];
3300 ossim_uint32 band = 0;
3301 for(band = 0; band < minNumberOfBands; ++band)
3302 {
3303 bandV1[band] = (double*)v1->getBuf(band);
3304 bandV2[band] = (double*)v2->getBuf(band);
3305 bandV1Np[band] = (double)v1->getNullPix(band);
3306 bandV2Np[band] = (double)v2->getNullPix(band);
3307 }
3308 if(v1->getNumberOfBands() < v2->getNumberOfBands())
3309 {
3310 for(band = 0; band < maxNumberOfBands; ++band)
3311 {
3312 bandV1[band] = (double*)v1->getBuf(minNumberOfBands-1);
3313 bandV2[band] = (double*)v2->getBuf(band);
3314 bandV1Np[band] = (double)v1->getNullPix(minNumberOfBands-1);
3315 bandV2Np[band] = (double)v2->getNullPix(band);
3316 }
3317 }
3318 else if(v2->getNumberOfBands() < v1->getNumberOfBands())
3319 {
3320 for(band = 0; band < maxNumberOfBands; ++band)
3321 {
3322 bandV1[band] = (double*)v1->getBuf(band);
3323 bandV2[band] = (double*)v2->getBuf(minNumberOfBands-1);
3324 bandV1Np[band] = (double)v1->getNullPix(band);
3325 bandV2Np[band] = (double)v2->getNullPix(minNumberOfBands-1);
3326 }
3327 }
3328
3329 if(status1 == OSSIM_EMPTY)
3330 {
3331 if(status2 == OSSIM_FULL)
3332 {
3333 for(band = 0; band < maxNumberOfBands; ++band)
3334 {
3335 double* buf1 = bandV1[band];
3336 double* buf2 = bandV2[band];
3337
3338 for(ossim_uint32 i = 0; i < size; ++i)
3339 {
3340 *buf1 = *buf2;
3341 ++buf1;
3342 ++buf2;
3343 }
3344 }
3345 }
3346 else if(status2 == OSSIM_PARTIAL)
3347 {
3348 for(band = 0; band < maxNumberOfBands; ++band)
3349 {
3350 double* buf1 = bandV1[band];
3351 double* buf2 = bandV2[band];
3352 double nullPix2 = bandV2Np[band];
3353 for(ossim_uint32 i = 0; i < size; ++i)
3354 {
3355 if(*buf2 != nullPix2)
3356 {
3357 *buf1 = *buf2;
3358 }
3359 ++buf1;
3360 ++buf2;
3361 }
3362 }
3363 }
3364 v1->setDataObjectStatus(status2);
3365 }
3366 else if((status1 == OSSIM_FULL)&&
3367 (status2 == OSSIM_FULL))
3368 {
3369 for(band = 0; band < maxNumberOfBands; ++band)
3370 {
3371 double* buf1 = bandV1[band];
3372 double* buf2 = bandV2[band];
3373
3374 for(ossim_uint32 i = 0; i < size; ++i)
3375 {
3376 *buf1 = op.apply(*buf1, *buf2);
3377 ++buf1;
3378 ++buf2;
3379 }
3380 }
3381 }
3382 else if((status1 == OSSIM_FULL)&&
3383 (status2 == OSSIM_PARTIAL))
3384 {
3385 for(band = 0; band < maxNumberOfBands; ++band)
3386 {
3387 double* buf1 = bandV1[band];
3388 double* buf2 = bandV2[band];
3389 double nullPix2 = bandV2Np[band];
3390 for(ossim_uint32 i = 0; i < size; ++i)
3391 {
3392 if(*buf2 != nullPix2)
3393 {
3394 *buf1 = op.apply(*buf1, *buf2);
3395 }
3396
3397 ++buf1;
3398 ++buf2;
3399 }
3400 }
3401 }
3402 else if((status1 == OSSIM_PARTIAL)&&
3403 (status2 == OSSIM_FULL))
3404 {
3405 for(band = 0; band < maxNumberOfBands; ++band)
3406 {
3407 double* buf1 = bandV1[band];
3408 double* buf2 = bandV2[band];
3409 double nullPix1 = bandV1Np[band];
3410 for(ossim_uint32 i = 0; i < size; ++i)
3411 {
3412 if(*buf1 != nullPix1)
3413 {
3414 *buf1 = op.apply(*buf1, *buf2);
3415 }
3416
3417 ++buf1;
3418 ++buf2;
3419 }
3420 }
3421 }
3422 else if((status1 == OSSIM_PARTIAL)&&
3423 (status2 == OSSIM_PARTIAL))
3424 {
3425 for(band = 0; band < maxNumberOfBands; ++band)
3426 {
3427 double* buf1 = bandV1[band];
3428 double* buf2 = bandV2[band];
3429 double nullPix1 = bandV1Np[band];
3430 double nullPix2 = bandV2Np[band];
3431 for(ossim_uint32 i = 0; i < size; ++i)
3432 {
3433 if((*buf1 != nullPix1)&&
3434 (*buf2 != nullPix2))
3435 {
3436 *buf1 = op.apply(*buf1, *buf2);
3437 }
3438
3439 ++buf1;
3440 ++buf2;
3441 }
3442 }
3443 }
3444
3445 delete [] bandV1;
3446 delete [] bandV2;
3447 delete [] bandV1Np;
3448 delete [] bandV2Np;
3449
3450 return true;
3451 }
3452
3453
applyOp(const ossimUnaryOp & op,ossimEquValue & result,ossimEquValue & v)3454 bool ossimEquationCombiner::applyOp(const ossimUnaryOp& op,
3455 ossimEquValue& result,
3456 ossimEquValue& v)
3457 {
3458 bool returnValue = true;
3459
3460 if(v.type == OSSIM_EQU_DOUBLE_TYPE)
3461 {
3462 result.type = OSSIM_EQU_DOUBLE_TYPE;
3463 result.d.doubleValue = op.apply(v.d.doubleValue);
3464 }
3465 else if(v.type == OSSIM_EQU_IMAGE_DATA_TYPE)
3466 {
3467 returnValue = applyOp(op,
3468 v.d.imageDataValue);
3469 result.type = OSSIM_EQU_IMAGE_DATA_TYPE;
3470 result.d.imageDataValue = v.d.imageDataValue;
3471 returnValue = true;
3472 }
3473 else
3474 {
3475 returnValue = false;
3476 }
3477
3478 return returnValue;
3479 }
3480
applyOp(const ossimUnaryOp & op,ossimImageData * v)3481 bool ossimEquationCombiner::applyOp(const ossimUnaryOp& op,
3482 ossimImageData* v)
3483 {
3484 double* buf = static_cast<double*>(v->getBuf());
3485 if(!buf) return true;
3486 ossimDataObjectStatus status = v->getDataObjectStatus();
3487
3488 if(status == OSSIM_EMPTY || status == OSSIM_NULL)
3489 {
3490 return true;
3491 }
3492
3493 if(status == OSSIM_FULL )
3494 {
3495 ossim_uint32 size = v->getSize();
3496
3497 for(ossim_uint32 i = 0; i < size; ++i)
3498 {
3499 *buf = (double)op.apply(*buf);
3500 ++buf;
3501 }
3502 }
3503 else
3504 {
3505 ossim_uint32 sizePerBand = v->getSizePerBand();
3506 ossim_uint32 numberOfBands = v->getNumberOfBands();
3507
3508 if(numberOfBands)
3509 {
3510 for(ossim_uint32 band = 0; band < numberOfBands; ++band)
3511 {
3512 double* buf = static_cast<double*>(v->getBuf(band));
3513
3514 if(buf)
3515 {
3516 double np = static_cast<double>(v->getNullPix()[band]);
3517
3518 for(ossim_uint32 offset = 0; offset < sizePerBand;++offset)
3519 {
3520 if(*buf != np)
3521 {
3522 *buf = (double)op.apply(*buf);
3523 }
3524 ++buf;
3525 }
3526 }
3527 }
3528 }
3529 }
3530
3531 return true;
3532 }
3533
saveState(ossimKeywordlist & kwl,const char * prefix) const3534 bool ossimEquationCombiner::saveState(ossimKeywordlist& kwl,
3535 const char* prefix)const
3536 {
3537 ossimString outputScalarType =
3538 ossimScalarTypeLut::instance()->getEntryString(theOutputScalarType);
3539
3540 kwl.add(prefix,
3541 EQUATION_KW,
3542 theEquation.c_str(),
3543 true);
3544
3545 kwl.add(prefix,
3546 "output_scalar_type",
3547 outputScalarType.c_str(),
3548 true);
3549
3550 return ossimImageCombiner::saveState(kwl,
3551 prefix);
3552 }
3553
loadState(const ossimKeywordlist & kwl,const char * prefix)3554 bool ossimEquationCombiner::loadState(const ossimKeywordlist& kwl,
3555 const char* prefix)
3556 {
3557 const char* equ = kwl.find(prefix, EQUATION_KW);
3558 const char* scalar = kwl.find(prefix, "output_scalar_type");
3559
3560 bool result = ossimImageCombiner::loadState(kwl,
3561 prefix);
3562
3563 if(equ)
3564 {
3565 theEquation = equ;
3566 }
3567
3568 if(scalar)
3569 {
3570 setOutputScalarType(ossimScalarTypeLut::instance()->
3571 getScalarTypeFromString(scalar));
3572 }
3573
3574 return result;
3575 }
3576
3577