OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimCibCadrgTileSource.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: LGPL
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author: Garrett Potts
8 //
9 //********************************************************************
10 // $Id: ossimCibCadrgTileSource.cpp 23021 2014-12-04 20:57:16Z dburken $
11 #include <algorithm>
12 
14 
20 #include <ossim/base/ossimCommon.h>
26 #include <ossim/base/ossimDatum.h>
27 #include <ossim/base/ossimNotify.h>
37 #include <ossim/base/ossimEndian.h>
38 #include <ossim/base/ossimTrace.h>
39 
40 static ossimTrace traceDebug = ossimTrace("ossimCibCadrgTileSource:debug");
41 
42 #ifdef OSSIM_ID_ENABLED
43 static const char OSSIM_ID[] = "$Id: ossimCibCadrgTileSource.cpp 23021 2014-12-04 20:57:16Z dburken $";
44 #endif
45 
46 RTTI_DEF1(ossimCibCadrgTileSource, "ossimCibCadrgTileSource", ossimImageHandler)
47 
50 
53  theCompressedBuffer(0),
54  theUncompressedBuffer(0),
55  theNumberOfLines(0),
56  theNumberOfSamples(0),
57  theTile(0),
58  theTableOfContents(0),
59  theEntryToRender(0),
60  theEntryNumberToRender(1),
61  theProductType(OSSIM_PRODUCT_TYPE_UNKNOWN),
62  theWorkFrame(0),
63  theSkipEmptyCheck(false)
64 {
65  if (traceDebug())
66  {
68  << "ossimCibCadrgTileSource::ossimCibCadrgTileSource entered...\n";
69 #ifdef OSSIM_ID_ENABLED
71  << "OSSIM_ID: " << OSSIM_ID << "\n";
72 #endif
73  }
74 
75  // Moved memory allocation to happen in first get tile. drb
76 
77  // theWorkFrame = new ossimRpfFrame;
78 
79  // a CADRG and CIBis a 64*64*12 bit buffer and must divide by 8 to
80  // convert to bytes
81  // theCompressedBuffer = new ossim_uint8[(64*64*12)/8];
82 
83  // whether CIB or CADRG we will alocate the buffer
84  // to the larger of the 2 (CADRG is 3 bands)
85  // theUncompressedBuffer = new ossim_uint8[256*256*3];
86 
87 }
88 
90 {
92  {
93  delete [] theCompressedBuffer;
95  }
97  {
98  delete [] theUncompressedBuffer;
100  }
101  if(theWorkFrame)
102  {
103  delete theWorkFrame;
104  theWorkFrame = 0;
105  }
106  close();
107 }
108 
110 {
111  return ossimString("CIB/CADRG");
112 }
113 
115 {
116  return ossimString("CIB/CADRG reader");
117 }
118 
119 
121 {
122  deleteAll();
124 }
125 
127 {
128  return (theTableOfContents!=0);
129 }
130 
132 {
133  if(traceDebug())
134  {
136  << "ossimCibCadrgTileSource::open(): Entered....."
137  << "\ntheImageFile: " << theImageFile << std::endl;
138  }
139 
140  bool result = false;
141 
142  if(isOpen())
143  {
144  close();
145  }
146 
148 
150  {
152  {
154  {
155  vector<ossimString> scaleList = getProductScaleList();
156  if(scaleList.size() > 0)
157  {
158  std::vector<ossim_uint32> entryList;
159  getEntryList(entryList);
160  if(entryList.size() > 0)
161  {
162  setCurrentEntry(entryList[0]);
163 
164  if(theEntryToRender)
165  {
166  // a CADRG is 1536x1536 per frame.
169  }
170 
171  if(theEntryToRender->getProductType().trim().upcase() == "CADRG")
172  {
174  result = true;
175  }
176  else if(theEntryToRender->getProductType().trim().upcase() == "CIB")
177  {
179  result = true;
180  }
181 
182  // Moved this code to be called on first get tile. drb
183  // if ( result )
184  // {
185  // This initializes tiles and buffers.
186  // allocateForProduct();
187  // }
188  }
189  }
190  }
191  }
192  }
193 
194  if(!result)
195  {
197  close();
198  }
199 
200 #if 0 /* 20100414 - drb */
201  else
202  {
203  //---
204  // Adjust image rect so not to go over the -180 to 180 and -90 to 90
205  // bounds.
206  //---
207  // Note this did not do any boundary checking and was in conflict with setTocEntryToRender
208  // method calculation of lines and samps.
209  // setActualImageRect();
210 
211  std::ifstream in(theImageFile.c_str(), std::ios::in|std::ios::binary);
212  if(in.good()&&theTableOfContents->getRpfHeader())
213  {
214  }
215  completeOpen();
216 
218  theTile->initialize();
219  }
220 #endif
221 
222  if(traceDebug())
223  {
225  << "ossimCibCadrgTileSource::open(): Leaving at line " << __LINE__
226  << " result=" << (result?"true":"false") << std::endl;
227  }
228 
229  return result;
230 }
231 
232 void ossimCibCadrgTileSource::setSkipEmptyCheck( bool bSkipEmptyCheck )
233 {
234  theSkipEmptyCheck = bSkipEmptyCheck;
235 }
236 
238  const ossimIrect& rect, ossim_uint32 resLevel)
239 {
240  if ( theTile.valid() == false )
241  {
242  // First time through.
244  }
245 
246  if (theTile.valid())
247  {
248  // Image rectangle must be set prior to calling getTile.
249  theTile->setImageRectangle(rect);
250 
251  if ( getTile( theTile.get(), resLevel ) == false )
252  {
254  {
255  theTile->makeBlank();
256  }
257  }
258  }
259 
260  return theTile;
261 }
262 
264  ossim_uint32 resLevel)
265 {
266  bool status = false;
267 
268  //---
269  // Not open, this tile source bypassed, or invalid res level,
270  // return a blank tile.
271  //---
272  if( isOpen() && isSourceEnabled() && isValidRLevel(resLevel) &&
273  result && (result->getNumberOfBands() == getNumberOfOutputBands()) &&
275  {
276  if ( resLevel > 0 )
277  {
278  //---
279  // Check for overview tile. Some overviews can contain r0 so always
280  // call even if resLevel is 0 (if overview is not virtual). Method
281  // returns true on success, false on error.
282  //---
283  status = getOverviewTile(resLevel, result);
284  }
285 
286  if (!status) // Did not get an overview tile.
287  {
288  if ( !theCompressedBuffer )
289  {
290  // First time through.
292  }
293 
294  if ( theCompressedBuffer )
295  {
296  status = true;
297 
298  ossimIrect rect = result->getImageRectangle();
299 
300  ossimIrect imageRect = getImageRectangle();
301 
302  if ( rect.intersects(imageRect) )
303  {
304  //---
305  // Start with a blank tile in case there is not total coverage
306  // for rect.
307  //---
308  result->makeBlank();
309 
310  vector<ossimFrameEntryData> frames = getIntersectingEntries(rect);
311  if(frames.size() > 0)
312  {
313  //---
314  // Now lets render each frame. Note we will have to find
315  // subframes
316  // that intersect the rectangle of interest for each frame.
317  //---
318  fillTile(rect, frames, result);
319 
320  // Revalidate tile status.
321  result->validate();
322  }
323  }
324  else
325  {
326  result->makeBlank();
327  }
328  }
329  }
330  }
331 
332  return status;
333 }
334 
336 {
337  switch(theProductType)
338  {
340  {
341  return 0;
342  }
344  {
345  return 1;
346  }
348  {
349  return 3;
350  }
351  }
352 
353  return 0;
354 }
355 
357 {
358  switch(theProductType)
359  {
361  {
362  return 0;
363  }
365  {
366  return 1;
367  }
369  {
370  return 3;
371  }
372  }
373 
374  return 0;
375 }
376 
378 {
379  if (reduced_res_level == 0)
380  {
381  return theNumberOfLines;
382  }
383  else if (theOverview.valid())
384  {
385  return theOverview->getNumberOfLines(reduced_res_level);
386  }
387 
388  return 0;
389 }
390 
392 {
393  if (reduced_res_level == 0)
394  {
395  return theNumberOfSamples;
396  }
397  else if (theOverview.valid())
398  {
399  return theOverview->getNumberOfSamples(reduced_res_level);
400  }
401 
402  return 0;
403 }
404 
406 {
407  return ossimIrect(0, // upper left x
408  0, // upper left y
409  getNumberOfSamples(reduced_res_level) - 1, // lower right x
410  getNumberOfLines(reduced_res_level) - 1); // lower right y
411 }
412 
414 {
415  if ( !theGeometry )
416  {
417  // Check for external geom:
419 
420  if ( !theGeometry && theEntryToRender )
421  {
423  }
424 
425  // Set image things the geometry object should know about.
427  }
428 
429  return theGeometry;
430 }
431 
433 {
434  return OSSIM_UCHAR;
435 }
436 
438 {
439  return getImageTileWidth();
440 }
441 
443 {
444  return getImageTileHeight();
445 }
446 
448 {
450 }
451 
453 {
454  bool result = false;
455 
456  theDecimationFactors.clear();
457 
458  // Clear the geometry.
459  theGeometry = 0;
460 
461  // Must clear or openOverview will use last entries.
463 
464  if(setEntryToRender(entryIdx))
465  {
466  completeOpen();
467  result = true;
468  }
469 
470  return result;
471 }
472 
473 void ossimCibCadrgTileSource::getEntryList(std::vector<ossim_uint32>& entryList)const
474 {
475  std::vector<ossimString> scaleList = getProductScaleList();
476  ossim_uint32 scaleIdx = 0;
477  ossim_uint32 entryIdx = 0;
478  for(scaleIdx = 0; scaleIdx < scaleList.size(); ++scaleIdx)
479  {
480  std::vector<ossim_int32> eList = getProductEntryList(scaleList[scaleIdx]);
481 
482  for(entryIdx = 0; entryIdx < eList.size(); ++entryIdx)
483  {
484  entryList.push_back(eList[entryIdx]);
485  }
486  }
487 
488 }
489 
491 {
492  if(isOpen())
493  {
494  const ossimRpfTocEntry *temp = theTableOfContents->getTocEntry(index);
495 
496  if(temp)
497  {
499  {
500  setTocEntryToRender(temp);
501  theEntryNumberToRender = index;
502  if(theEntryToRender)
503  {
504  if(theEntryToRender->getProductType().trim().upcase() == "CADRG")
505  {
507  }
508  else if(theEntryToRender->getProductType().trim().upcase() == "CIB")
509  {
511  }
512  else
513  {
515  }
516  }
517 
518  populateLut();
519 
520  return true;
521  }
522  }
523  }
524 
525  return false;
526 }
527 
529 {
530  if(isOpen()&&entry)
531  {
532  theEntryToRender = entry;
536  }
537 }
538 
540 {
541  return theEntryNumberToRender;
542 }
543 
545 {
546  return theEntryToRender;
547 }
548 
550 {
551  return theTableOfContents;
552 }
553 
555 {
556  if (reduced_res_level == 0)
557  {
558  return true;
559  }
560  else if (theOverview.valid())
561  {
562  return theOverview->isValidRLevel(reduced_res_level);
563  }
564  else
565  {
566  return false;
567  }
568 }
569 
571 {
572  vector<ossimString> result;
573 
574  if(isOpen())
575  {
577 
578  for(ossim_int32 index = 0; index < upperBound; ++index)
579  {
580  const ossimRpfTocEntry* entry = theTableOfContents->getTocEntry(index);
581  ossimString scale = entry->getBoundaryInformation().getScale();
582 
583  scale = scale.trim().upcase();
584  if(scale!="")
585  {
586  // CIB will have product scales like 5M or 10M
587  // and CADRG's will have product scales like
588  // 1:50K and 1:250K ...
589  // So if these patterns exist then add it to
590  // the product list.
591  if( ( std::find(scale.begin(), scale.end(), ':') != scale.end() )
592  ||
593  (scale[scale.size()-1]=='M'))
594  {
595  // only add it if it doesn't already exist
596  // on the list.
597  if(find(result.begin(), result.end(), scale) == result.end())
598  {
599  result.push_back(scale);
600  }
601  }
602  }
603  }
604  }
605 
606  if (traceDebug())
607  {
609  << "ossimCibCadrgTileSource::getProductScaleList DEBUG:"
610  << endl;
611 
612  std::vector<ossimString>::const_iterator i = result.begin();
613  ossim_uint32 index = 0;
614  while (i != result.end())
615  {
617  << "scale[" << index << "]: " << (*i) << endl;
618  ++index;
619  ++i;
620  }
621  }
622 
623  return result;
624 }
625 
626 vector<ossim_int32> ossimCibCadrgTileSource::getProductEntryList(const ossimString& productScale)const
627 {
628  vector<ossim_int32> result;
629 
630  if(isOpen())
631  {
633 
634  for(ossim_int32 index = 0; index < upperBound; ++index)
635  {
636  const ossimRpfTocEntry* entry = theTableOfContents->getTocEntry(index);
637 
638  if(entry)
639  {
640  // If the "skip empty check" is true, we don't check to see if the
641  // actual frame images exist. Otherwise the check is carried out,
642  // which is the default situation.
643  bool bIsEmpty = (theSkipEmptyCheck==false) ? entry->isEmpty() : false;
644 
645  // if the entry is not empty then add it to the list.
646  if( bIsEmpty == false )
647  {
648  ossimString scale = entry->getBoundaryInformation().getScale();
649  scale = scale.trim().upcase();
650  if(scale==productScale)
651  {
652  result.push_back(index);
653  }
654  }
655  }
656  }
657  }
658 
659  if (traceDebug())
660  {
662  << "ossimCibCadrgTileSource::getProductEntryList DEBUG:"
663  << endl;
664 
665  std::vector<ossim_int32>::const_iterator i = result.begin();
666  ossim_uint32 index = 0;
667  while (i != result.end())
668  {
670  << "scale[" << index << "]: " << (*i) << endl;
671  ++index;
672  ++i;
673  }
674  }
675 
676  return result;
677 
678 }
679 
680 vector<ossimCibCadrgTileSource::ossimFrameEntryData> ossimCibCadrgTileSource::getIntersectingEntries(const ossimIrect& rect)
681 {
682  vector<ossimFrameEntryData> result;
683 
684  // make sure we have the Toc entry to render
685  if(!isOpen()) return result;
686 
687  ossimIrect imageRect = getImageRectangle();
688  if(rect.intersects(imageRect))
689  {
690  ossimIrect clipRect = rect.clipToRect(imageRect);
691  ossimIrect frameRect(clipRect.ul().x/CIBCADRG_FRAME_WIDTH,
692  clipRect.ul().y/CIBCADRG_FRAME_HEIGHT,
693  clipRect.lr().x/CIBCADRG_FRAME_WIDTH,
694  clipRect.lr().y/CIBCADRG_FRAME_HEIGHT);
695 
696  ossimRpfFrameEntry tempEntry;
697 
698 
699  for(ossim_int32 row = frameRect.ul().y; row <= frameRect.lr().y; ++row)
700  {
701  for(ossim_int32 col = frameRect.ul().x; col <= frameRect.lr().x; ++col)
702  {
704  col,
705  tempEntry))
706  {
707  if(tempEntry.exists())
708  {
709  result.push_back(ossimFrameEntryData(row,
710  col,
713  tempEntry));
714  }
715  }
716  }
717  }
718  }
719 
720  return result;
721 }
722 
724  const ossimIrect& tileRect,
725  const vector<ossimFrameEntryData>& framesInvolved,
726  ossimImageData* tile)
727 {
728  ossim_uint32 idx = 0;
729  for(idx = 0;
730  idx < framesInvolved.size();
731  ++idx)
732  {
733 
734  if(theWorkFrame->parseFile(framesInvolved[idx].theFrameEntry.getFullPath())
736  {
737  // we will fill a subtile. We pass in which frame it is and the position of the frame.
738  // the actual pixel will be 1536*row and 1536 *col.
740  {
742  tileRect,
743  framesInvolved[idx],
744  tile);
745  }
746  else
747  {
749  tileRect,
750  framesInvolved[idx],
751  tile);
752  }
753  }
754  }
755 }
756 
758  const ossimRpfFrame& aFrame,
759  const ossimIrect& tileRect,
760  const ossimFrameEntryData& frameEntryData,
761  ossimImageData* tile)
762 {
763  // first let's grab the absolute position of the frame rectangle in pixel space
764  ossimIrect frameRect(frameEntryData.thePixelCol,
765  frameEntryData.thePixelRow,
766  frameEntryData.thePixelCol + CIBCADRG_FRAME_WIDTH - 1,
767  frameEntryData.thePixelRow + CIBCADRG_FRAME_HEIGHT - 1);
768 
769 
770  // now clip it to the tile
771  ossimIrect clipRect = tileRect.clipToRect(frameRect);
772 
773  const ossimRpfCompressionSection* compressionSection = aFrame.getCompressionSection();
774 
775  if(!compressionSection)
776  {
777  return;
778  }
779 
780  const vector<ossimRpfColorGrayscaleTable>& colorTable =
781  aFrame.getColorGrayscaleTable();
782 
783  // ESH 03/2009 -- Partial fix for ticket #646.
784  // Crash fix on reading RPFs: Make sure the colorTable vector
785  // has entries before trying to make use of them.
786  int numTables = (int)colorTable.size();
787  if ( numTables <= 0 )
788  {
789  return;
790  }
791 
792  ossim_uint8 *tempRows[3];
793 
794  tempRows[0] = theUncompressedBuffer;
795  tempRows[1] = (theUncompressedBuffer + 256*256);
796  tempRows[2] = (tempRows[1] + 256*256);
797 
798  // find the shift to 0,0
799  ossimIpt tempDelta(clipRect.ul().x - frameEntryData.thePixelCol,
800  clipRect.ul().y - frameEntryData.thePixelRow);
801 
802 
803  // In order to compute the subframe we will need the corner offsets of
804  // the upper left of the frame and the upper left of the clip rect. The
805  // clip rect should be completely within the frame. This just translates the value
806  // to make the upper left of the frame be 0,0.
807  //
808  ossimIrect offsetRect(tempDelta.x,
809  tempDelta.y,
810  tempDelta.x + clipRect.width()-1,
811  tempDelta.y + clipRect.height()-1);
812 
813  // each subframe is 64x64. We will actually use 256x256 since
814  // we will be uncompressing them. Note CADRG is a 256x256 tile
815  // compressed to 64x64x12 bit data
816  //
817  ossimIrect subFrameRect(offsetRect.ul().x/256,
818  offsetRect.ul().y/256,
819  (offsetRect.lr().x)/256,
820  (offsetRect.lr().y)/256);
821 
822  ossim_uint32 readPtr = 0;
823 
824  ossim_int32 row = 0;
825  ossim_int32 col = 0;
826  ossim_uint32 i = 0;
827  ossim_uint32 j = 0;
828  ossim_int32 upperY = subFrameRect.lr().y;
829  ossim_int32 upperX = subFrameRect.lr().x;
830  ossim_int32 lowerY = subFrameRect.ul().y;
831  ossim_int32 lowerX = subFrameRect.ul().x;
832  for(row = lowerY; row <= upperY; ++row)
833  {
834  for(col = lowerX; col <= upperX; ++col)
835  {
836  readPtr = 0;
837  if(aFrame.fillSubFrameBuffer(theCompressedBuffer, 0, row, col))
838  {
839  for (i = 0; i < 256; i += 4)
840  {
841  for (j = 0; j < 256; j += 8)
842  {
843  ossim_uint16 firstByte = theCompressedBuffer[readPtr++] & 0xff;
844  ossim_uint16 secondByte = theCompressedBuffer[readPtr++] & 0xff;
845  ossim_uint16 thirdByte = theCompressedBuffer[readPtr++] & 0xff;
846 
847  //because dealing with half-bytes is hard, we
848  //uncompress two 4x4 tiles at the same time. (a
849  //4x4 tile compressed is 12 bits )
850  // this little code was grabbed from openmap software.
851 
852  /* Get first 12-bit value as index into VQ table */
853  // I think we need to swap
854  ossim_uint16 val1 = (firstByte << 4) | (secondByte >> 4);
855 
856  /* Get second 12-bit value as index into VQ table*/
857  ossim_uint16 val2 = ((secondByte & 0x000F) << 8) | thirdByte;
858 
859  for (ossim_uint32 t = 0; t < 4; ++t)
860  {
861  for (ossim_uint32 e = 0; e < 4; ++e)
862  {
863  ossim_uint16 tableVal1 = compressionSection->getTable()[t].theData[val1*4 + e] & 0xff;
864  ossim_uint16 tableVal2 = compressionSection->getTable()[t].theData[val2*4 + e] & 0xff;
865 
866  ossim_uint32 pixindex = ((i+t)*256) +
867  (j + e);
868  const ossim_uint8* color1 = colorTable[0].getStartOfData(tableVal1);
869  const ossim_uint8* color2 = colorTable[0].getStartOfData(tableVal2);
870 
871 
872  tempRows[0][pixindex] = color1[0];
873  tempRows[1][pixindex] = color1[1];
874  tempRows[2][pixindex] = color1[2];
875 
876  tempRows[0][pixindex+4] = color2[0];
877  tempRows[1][pixindex+4] = color2[1];
878  tempRows[2][pixindex+4] = color2[2];
879  } //for e
880  } //for t
881  } /* for j */
882  } //for i
883  }
884  else
885  {
886  memset(theUncompressedBuffer, 0, 256*256*3);
887  }
888  ossim_int32 tempCol = col*256;
889  ossim_int32 tempRow = row*256;
890  ossimIrect subRectToFill(frameRect.ul().x + tempCol,
891  frameRect.ul().y + tempRow,
892  frameRect.ul().x + tempCol + 255,
893  frameRect.ul().y + tempRow + 255);
895  subRectToFill,
896  OSSIM_BSQ);
897  }
898  }
899 }
900 
902  const ossimRpfFrame& aFrame,
903  const ossimIrect& tileRect,
904  const ossimFrameEntryData& frameEntryData,
905  ossimImageData* tile)
906 {
907  // first let's grab the absolute position of the frame rectangle in pixel
908  // space
909  ossimIrect frameRect(frameEntryData.thePixelCol,
910  frameEntryData.thePixelRow,
911  frameEntryData.thePixelCol + CIBCADRG_FRAME_WIDTH - 1,
912  frameEntryData.thePixelRow + CIBCADRG_FRAME_HEIGHT - 1);
913 
914 
915  // now clip it to the tile
916  ossimIrect clipRect = tileRect.clipToRect(frameRect);
917 
918  const ossimRpfCompressionSection* compressionSection = aFrame.getCompressionSection();
919 
920  if(!compressionSection)
921  {
922  return;
923  }
924 
925  const vector<ossimRpfColorGrayscaleTable>& colorTable =
926  aFrame.getColorGrayscaleTable();
927 
928  // ESH 03/2009 -- Partial fix for ticket #646.
929  // Crash fix on reading RPFs: Make sure the colorTable vector
930  // has entries before trying to make use of them.
931  int numTables = (int)colorTable.size();
932  if ( numTables <= 0 )
933  {
934  return;
935  }
936 
937  // check to see if it does overlap. If it doesn't then the width and height
938  // will be a single point
939  {
940  ossim_uint8 *tempRow;
941 
942  tempRow = theUncompressedBuffer;
943 
944  // find the shift to 0,0
945  ossimIpt tempDelta(clipRect.ul().x - frameEntryData.thePixelCol,
946  clipRect.ul().y - frameEntryData.thePixelRow);
947 
948  // In order to compute the subframe we will need the corner offsets of
949  // the upper left of the frame and the upper left of the clip rect. The
950  // clip rect should be completely within the frame. This just translates the value
951  // to make the upper left of the frame be 0,0.
952  //
953  ossimIrect offsetRect(tempDelta.x,
954  tempDelta.y,
955  tempDelta.x + clipRect.width()-1,
956  tempDelta.y + clipRect.height()-1);
957 
958  // each subframe is 64x64. We will actually use 256x256 since
959  // we will be uncompressing them. Note CADRG is a 256x256 tile
960  // compressed to 64x64x12 bit data
961  //
962  ossimIrect subFrameRect(offsetRect.ul().x/256,
963  offsetRect.ul().y/256,
964  (offsetRect.lr().x)/256,
965  (offsetRect.lr().y)/256);
966 
967  ossim_int32 row = 0;
968  ossim_int32 col = 0;
969  ossim_uint32 i = 0;
970  ossim_uint32 j = 0;
971  ossim_uint32 readPtr = 0;
972  for(row = subFrameRect.ul().y; row <= subFrameRect.lr().y; ++row)
973  {
974  for(col = subFrameRect.ul().x; col <= subFrameRect.lr().x; ++col)
975  {
976  readPtr = 0;
977  if(aFrame.fillSubFrameBuffer(theCompressedBuffer, 0, row, col))
978  {
979  for (i = 0; i < 256; i += 4)
980  {
981  for (j = 0; j < 256; j += 8)
982  {
983  ossim_uint16 firstByte = theCompressedBuffer[readPtr++] & 0xff;
984  ossim_uint16 secondByte = theCompressedBuffer[readPtr++] & 0xff;
985  ossim_uint16 thirdByte = theCompressedBuffer[readPtr++] & 0xff;
986 
987  //because dealing with half-bytes is hard, we
988  //uncompress two 4x4 tiles at the same time. (a
989  //4x4 tile compressed is 12 bits )
990  // this little code was grabbed from openmap software.
991 
992  /* Get first 12-bit value as index into VQ table */
993  // I think we need to swap
994  ossim_uint16 val1 = (firstByte << 4) | (secondByte >> 4);
995 
996  /* Get second 12-bit value as index into VQ table*/
997  ossim_uint16 val2 = ((secondByte & 0x000F) << 8) | thirdByte;
998 
999  for (ossim_uint32 t = 0; t < 4; ++t)
1000  {
1001  for (ossim_uint32 e = 0; e < 4; ++e)
1002  {
1003  ossim_uint16 tableVal1 = compressionSection->getTable()[t].theData[val1*4 + e] & 0xff;
1004  ossim_uint16 tableVal2 = compressionSection->getTable()[t].theData[val2*4 + e] & 0xff;
1005 
1006  ossim_uint32 pixindex = ((i+t)*256) + (j + e);
1007  const ossim_uint8* color1 = colorTable[0].getStartOfData(tableVal1);
1008  const ossim_uint8* color2 = colorTable[0].getStartOfData(tableVal2);
1009 
1010 
1011  tempRow[pixindex] = color1[0];
1012  tempRow[pixindex + 4] = color2[0];
1013  } //for e
1014  } //for t
1015  } /* for j */
1016  } //for i
1017  }
1018  else
1019  {
1020  memset(theUncompressedBuffer, 0, 256*256);
1021  }
1022  ossim_int32 tCol = col*256;
1023  ossim_int32 tRow = row*256;
1024  ossimIrect subRectToFill(frameRect.ul().x + tCol,
1025  frameRect.ul().y + tRow,
1026  frameRect.ul().x + tCol + 255,
1027  frameRect.ul().y + tRow + 255);
1029  subRectToFill,
1030  OSSIM_BSQ);
1031  }
1032  }
1033  }
1034 }
1035 
1037 {
1039  {
1040  return;
1041  }
1042 
1043  if ( theWorkFrame )
1044  {
1045  delete theWorkFrame;
1046  }
1048 
1050  {
1051  delete [] theCompressedBuffer;
1052  }
1053 
1054  //---
1055  // A CADRG and CIBis a 64*64*12 bit buffer and must divide by 8 to convert
1056  // to bytes.
1057  //---
1058  theCompressedBuffer = new ossim_uint8[(64*64*12)/8];
1059 
1061  {
1062  delete [] theUncompressedBuffer;
1063  }
1065  {
1066  theUncompressedBuffer = new ossim_uint8[256*256];
1067  }
1068  else
1069  {
1070  theUncompressedBuffer = new ossim_uint8[256*256*3];
1071  }
1072 
1074  theTile->initialize();
1075 }
1076 
1078 {
1079  vector<ossimString> products = getProductScaleList();
1080  vector<ossim_int32> indexProducts;
1081 
1082  if(products.size() > 0)
1083  {
1084  indexProducts = getProductEntryList(products[0]);
1085 
1086  if(indexProducts.size()>0)
1087  {
1088  theEntryNumberToRender = indexProducts[0];
1089 
1090  return theTableOfContents->getTocEntry(indexProducts[0]);
1091  }
1092  }
1093 
1094  return 0;
1095 }
1096 
1097 
1099 {
1100  theOverview = 0;
1101  if(theTableOfContents)
1102  {
1103  delete theTableOfContents;
1104  theTableOfContents = 0;
1105  }
1106 }
1107 
1109  const char* prefix)const
1110 {
1111  bool result = ossimImageHandler::saveState(kwl, prefix);
1112 
1113  kwl.add(prefix,
1114  "entry",
1116  true);
1117 
1118  return result;
1119 }
1120 
1122  const char* prefix)
1123 {
1124  const char* MODULE = "ossimCibCadrgTileSource::loadState";
1125 
1126  if(traceDebug())
1127  {
1128  CLOG << "Entering..." << endl;
1129  }
1130  bool result = ossimImageHandler::loadState(kwl, prefix);
1131 
1132  if(!result)
1133  {
1134  if(traceDebug())
1135  {
1136  CLOG << "Leaving..." << endl;
1137  }
1138  return false;
1139  }
1140  const char* lookup = 0;
1141  lookup = kwl.find(ossimString(prefix), "entry");
1142  ossim_int32 entry = ossimString(lookup).toInt32();
1143 
1144  // if an entry is specified then
1145  // call the open with an entry number
1146  if(lookup)
1147  {
1148  if(traceDebug())
1149  {
1150  CLOG << "Leaving..." << endl;
1151  }
1153  setCurrentEntry(entry);
1154  return result;
1155  }
1156 
1158 
1159  return result;
1160 }
1161 
1163 {
1164  return 256; // ??? drb
1165 }
1166 
1168 {
1169  return 256; // ??? drb
1170 }
1171 
1173 {
1175 }
1176 
1178 {
1180 }
1181 
1183 {
1184  ossimString result;
1185 
1186  const ossimRpfTocEntry* entry =
1188 
1189  if (entry)
1190  {
1191  result = entry->getBoundaryInformation().getScale();
1192  }
1193 
1194  return result;
1195 }
1196 
1198 {
1199  ossimString result;
1200 
1201  const ossimRpfHeader* header =
1203 
1204  if (header)
1205  {
1206  result = header->getSecurityClassification();
1207  }
1208 
1209  return result;
1210 }
1211 
1213 {
1214  if(name == "file_type")
1215  {
1217  {
1218  return new ossimStringProperty("file_type", "CIB");
1219  }
1221  {
1222  return new ossimStringProperty("file_type", "CADRG");
1223  }
1224  return 0;
1225  }
1226  return ossimImageHandler::getProperty(name);
1227 }
1228 
1229 void ossimCibCadrgTileSource::getPropertyNames(std::vector<ossimString>& propertyNames)const
1230 {
1231  ossimImageHandler::getPropertyNames(propertyNames);
1232  propertyNames.push_back("file_type");
1233 
1238 #if 0
1239  const ossimRpfHeader* header =
1241  if(header)
1242  {
1243  std::ifstream in(theImageFile.c_str(), std::ios::in|std::ios::binary);
1244  }
1245 #endif
1246 }
1247 
1249 {
1250  theLut = 0;
1251  if(theEntryToRender)
1252  {
1255  ossim_uint32 wi, hi;
1256  bool found = false;
1257  ossimRpfFrameEntry tempEntry;
1258  ossimRpfFrame aFrame;
1259  for(wi = 0; ((wi < w)&&(!found)); ++wi)
1260  {
1261  for(hi = 0; ((hi < h)&&(!found)); ++hi)
1262  {
1264  wi,
1265  tempEntry);
1266  if(tempEntry.getFullPath().exists())
1267  {
1268  found = true;
1269  }
1270  }
1271  }
1272  if(aFrame.parseFile(tempEntry.getFullPath())
1274  {
1275  const vector<ossimRpfColorGrayscaleTable>& colorTable =
1276  aFrame.getColorGrayscaleTable();
1277 
1278  // ESH 03/2009 -- Partial fix for ticket #646.
1279  // Crash fix on reading RPFs: Make sure the colorTable vector
1280  // has entries before trying to make use of them.
1281  int numTables = (int)colorTable.size();
1282 
1283  ossim_uint32 numElements = (numTables > 0) ? colorTable[0].getNumberOfElements() : 0;
1284  if(numElements > 0)
1285  {
1288  {
1289  theLut = new ossimNBandLutDataObject(numElements,
1290  3,
1291  OSSIM_UINT8);
1292  }
1293  else
1294  {
1295  theLut = 0;
1296  return;
1297  }
1298  ossim_uint32 idx = 0;
1299 
1300  for(idx = 0; idx < numElements;++idx)
1301  {
1302  const ossim_uint8* startOfData = colorTable[0].getStartOfData(idx);
1303  switch(theProductType)
1304  {
1306  {
1307  (*theLut)[idx][0] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(startOfData[0]);
1308  (*theLut)[idx][1] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(startOfData[0]);
1309  (*theLut)[idx][2] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(startOfData[0]);
1310  break;
1311  }
1313  {
1314  (*theLut)[idx][0] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(startOfData[0]);
1315  (*theLut)[idx][1] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(startOfData[1]);
1316  (*theLut)[idx][2] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(startOfData[2]);
1317  break;
1318  }
1319  default:
1320  {
1321  break;
1322  }
1323  }
1324  }
1325  }
1326  }
1327  }
1328 }
1329 
1331 {
1332  if(theEntryToRender)
1333  {
1336  ossim_uint32 wi, hi;
1337  bool found = false;
1338  ossimRpfFrameEntry tempEntry;
1339  ossimRpfFrame aFrame;
1340  for(wi = 0; ((wi < w)&&(!found)); ++wi)
1341  {
1342  for(hi = 0; ((hi < h)&&(!found)); ++hi)
1343  {
1345  wi,
1346  tempEntry);
1347  if(tempEntry.getFullPath().exists())
1348  {
1349  found = true;
1350  }
1351  }
1352  }
1353  if(found)
1354  {
1355  if(aFrame.parseFile(tempEntry.getFullPath()) == ossimErrorCodes::OSSIM_OK)
1356  {
1357 
1358  }
1359  }
1360  }
1361 }
virtual bool open()=0
Pure virtual open.
void clear()
Erases the entire container.
Definition: ossimString.h:432
virtual bool isSourceEnabled() const
Definition: ossimSource.cpp:79
virtual ossim_uint32 getNumberOfOutputBands() const
This method allows one to query the number of output bands.
const ossimRpfTocEntry * findFirstFrame()
This will search each entry in the table and look for a certain entry.
ossimRefPtr< ossimImageGeometry > theGeometry
ossim_uint32 getNumberOfEntries() const
static ossimString upcase(const ossimString &aString)
Definition: ossimString.cpp:34
ossim_uint32 theNumberOfLines
This will be computed based on the frames organized within the directory.
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to load the state of an object from a keyword list.
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
Gets a property for matching name.
virtual ossim_uint32 getNumberOfBands() const
#define CLOG
Definition: ossimTrace.h:23
ossimFilename theImageFile
virtual void setImageRectangle(const ossimIrect &rect)
vector< ossimString > getProductScaleList() const
This retrieves all product scales that are within the Table of contents.
void allocateForProduct()
Will allocate an internal buffer for the given product.
const std::vector< ossimRpfCompressionOffsetTableData > & getTable() const
Represents serializable keyword/value map.
virtual ossim_uint32 getImageTileWidth() const
Returns the tile width of the image or 0 if the image is not tiled.
static const ossimErrorCode OSSIM_OK
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
bool valid() const
Definition: ossimRefPtr.h:75
const char * find(const char *key) const
std::vector< ossimDpt > theDecimationFactors
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
ossimRpfToc * theTableOfContents
Will own a table of contents.
virtual ossim_uint32 getNumberOfLines(ossim_uint32 resLevel=0) const =0
Pure virtual, derived classes must implement.
ossimString getProductType() const
virtual ossim_uint32 getTileHeight() const
Returns the height of the output tile.
void fillTile(const ossimIrect &tileRect, const vector< ossimFrameEntryData > &framesInvolved, ossimImageData *tile)
This is a wrapper for the fill cib and fill cadrg.
ossim_uint32 getNumberOfFramesVertical() const
ossimCibCadrgTileSource()
Default constructor.
ossim_uint32 height() const
Definition: ossimIrect.h:487
ossim_uint32 getNumberOfSamples() const
virtual ossimScalarType getOutputScalarType() const
This method allows you to query the scalar type of the output data.
ossimRefPtr< ossimImageGeometry > getImageGeometry() const
Returns the image geometry object associated with this tile source or NULL if non defined...
void fillSubTileCib(const ossimRpfFrame &aFrame, const ossimIrect &tileRect, const ossimFrameEntryData &frameEntryData, ossimImageData *tile)
Will uncompress the CIB file using a VQ decompression algorithm.
virtual void setTocEntryToRender(const ossimRpfTocEntry *entry)
Sets the entry to be renderer.
const ossimIpt & ul() const
Definition: ossimIrect.h:274
virtual ossimDataObjectStatus getDataObjectStatus() const
ossimString getSecurityClassification() const
const ossimRpfCoverageSection & getCoverage() const
bool intersects(const ossimIrect &rect) const
Definition: ossimIrect.cpp:183
const ossimRpfHeader * getRpfHeader() const
unsigned short ossim_uint16
unsigned char * theCompressedBuffer
This is for storage of a single compressed buffer.
bool theSkipEmptyCheck
If true during the call to open(), the RPF file is opened even if all the frame files are missing...
Protected structure that is only used internally by this class.
const ossimRpfBoundaryRectRecord & getBoundaryInformation() const
virtual void getEntryList(std::vector< ossim_uint32 > &entryList) const
virtual ossim_uint32 getCurrentEntry() const
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
std::string::iterator end()
Definition: ossimString.h:423
virtual void initialize()
Initialize the data buffer.
virtual const ossimRpfTocEntry * getCurrentTocEntry() const
virtual bool setEntryToRender(ossim_uint32 index)
Sets the entry to render.
virtual bool isValidRLevel(ossim_uint32 resLevel) const
Determines if the passed in reslution level is valid.
virtual ossimString getLongName() const
This method is defined in the base class ossimObject.
ossim_int32 toInt32() const
virtual bool setCurrentEntry(ossim_uint32 entryIdx)
bool isOpen() const
Determines if its open if there eists a table of contents object.
void push_back(char c)
Equivalent to insert(end(), c).
Definition: ossimString.h:905
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
const vector< ossimRpfColorGrayscaleTable > & getColorGrayscaleTable() const
Definition: ossimRpfFrame.h:80
const ossimRpfTocEntry * theEntryToRender
This is the actual frame file to render.
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
virtual void loadTile(const void *src, const ossimIrect &src_rect, ossimInterleaveType il_type)
virtual bool open()
Pure virtual open.
virtual bool getOverviewTile(ossim_uint32 resLevel, ossimImageData *result)
Method to get an overview tile.
static ossimImageDataFactory * instance()
unsigned char * theUncompressedBuffer
This is used as a buffer to uncompress the data to.
static const ossim_uint32 CIBCADRG_FRAME_HEIGHT
CONSTANT representing the height of a Frame.
bool fillSubFrameBuffer(ossim_uint8 *buffer, ossim_uint32 spectralGroup, ossim_uint32 row, ossim_uint32 col) const
virtual ossimIrect getImageRectangle(ossim_uint32 reduced_res_level=0) const
virtual ossimDataObjectStatus validate() const
bool exists() const
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
Gets a list of property names available.
std::string::size_type size() const
Definition: ossimString.h:405
virtual ossim_uint32 getImageTileHeight() const
Returns the tile width of the image or 0 if the image is not tiled.
vector< ossimFrameEntryData > getIntersectingEntries(const ossimIrect &rect)
It is important to note that each frame is organized into an easting northing type orientation...
std::string::iterator begin()
Definition: ossimString.h:420
unsigned int ossim_uint32
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
ossimCibCadrgProductType theProductType
Holds the enumeration specifying the product type.
virtual ossim_uint32 getNumberOfInputBands() const
This method allows you to query the number of input bands.
const ossimRpfTocEntry * getTocEntry(ossim_uint32 index) const
virtual ossimIrect getImageRectangle() const
virtual ossimRefPtr< ossimImageGeometry > getImageGeometry()
Populates the geometry object with image geometry information.
virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level=0) const
Satisfies pure virtual requirement from ImageHandler class.
const ossimIpt & lr() const
Definition: ossimIrect.h:276
virtual void close()
Deletes the overview and clears the valid image vertices.
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
ossim_uint32 width() const
Definition: ossimIrect.h:500
void initImageParameters(ossimImageGeometry *geom) const
Convenience method to set things needed in the image geometry from the image handler.
ossimIrect clipToRect(const ossimIrect &rect) const
Definition: ossimIrect.cpp:501
virtual ~ossimCibCadrgTileSource()
Destructor.
ossimErrorCode parseFile(const ossimFilename &fileName, bool keepFileHeader=false)
Parses a.toc file.
Definition: ossimRpfToc.cpp:55
ossimRefPtr< ossimImageData > theTile
This is the actual data returned from a getTile request.
ossimScalarType
CIB/CADRG formats are encoded the same except that the CIB is a grey scale image and the CADRG is a c...
ossim_uint32 getNumberOfFramesHorizontal() const
virtual ossim_uint32 getTileWidth() const
Returns the width of the output tile.
vector< ossim_int32 > getProductEntryList(const ossimString &productScale) const
Using the product scales from getProductScaleList() you can pass each string in so you can get all as...
virtual ossimRefPtr< ossimImageGeometry > getExternalImageGeometry() const
Returns the image geometry object associated with this tile source or NULL if non defined...
return status
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
ossimErrorCode parseFile(const ossimFilename &filename, bool minimalParse=false)
virtual void makeBlank()
Initializes data to null pixel values.
virtual void close()
Closes this image handler and deletes any allocated data.
virtual void completeOpen()
Will complete the opening process.
ossimString getSecurityClassification() const
static const ossim_uint32 CIBCADRG_FRAME_WIDTH
CONSTANT representing the width of a Frame.
ossimRefPtr< ossimImageHandler > theOverview
ossim_int32 theEntryNumberToRender
This will be the entry number that we are currently rendering.
ossim_uint32 getNumberOfLines() const
This class defines an abstract Handler which all image handlers(loaders) should derive from...
void setSkipEmptyCheck(bool bSkipEmptyCheck=false)
Changes the way the open() routine functions slightly.
ossim_int32 y
Definition: ossimIpt.h:142
virtual const ossimRpfToc * getToc() const
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
class ossimNBandLutDataObject
ossimFilename theOverviewFile
virtual ossim_uint32 getNumberOfSamples(ossim_uint32 resLevel=0) const =0
Pure virtual, derived classes must implement.
virtual ossim_uint32 getNumberOfLines(ossim_uint32 reduced_res_level=0) const
Satisfies pure virtual requirement from ImageHandler class.
bool isValidRLevel(ossim_uint32 reduced_res_level) const
void fillSubTileCadrg(const ossimRpfFrame &aFrame, const ossimIrect &tileRect, const ossimFrameEntryData &frameEntryData, ossimImageData *tile)
Will uncompress the CADRG file using a VQ decompression algorithm.
ossim_int32 x
Definition: ossimIpt.h:141
ossimRefPtr< ossimNBandLutDataObject > theLut
8 bit unsigned integer
ossim_uint32 theNumberOfSamples
This will be computed based on the frames organized within the directory.
bool getEntry(long row, long col, ossimRpfFrameEntry &result) const
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
virtual ossimString getShortName() const
This method is defined in the base class ossimObject.
const ossimRpfCompressionSection * getCompressionSection() const
Definition: ossimRpfFrame.h:76
virtual ossim_int32 getCurrentEntryIndex() const
Returns -1 if invalid.
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &rect, ossim_uint32 resLevel=0)
Returns a pointer to an ossimImageDataObject given a rectangluar region of interest.
ossim_int32 getTocEntryIndex(const ossimRpfTocEntry *entry)
Returns -1 if not found.
const ossimFilename & getFullPath() const
unsigned char ossim_uint8
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
8 bit unsigned iteger
int ossim_int32