1 //--- 2 // 3 // License: MIT 4 // 5 // See LICENSE.txt file in the top level directory for more details. 6 // 7 // Author: David Burken 8 // 9 // Description: 10 // 11 // Contains class declaration for NitfTileSource. 12 // 13 //--- 14 // $Id$ 15 16 #ifndef ossimNitfTileSource_HEADER 17 #define ossimNitfTileSource_HEADER 1 18 19 #include <ossim/imaging/ossimImageHandler.h> 20 #include <ossim/base/ossimIoStream.h> 21 #include <ossim/imaging/ossimAppFixedTileCache.h> 22 #include <ossim/support_data/ossimNitfFile.h> 23 #include <ossim/support_data/ossimNitfFileHeader.h> 24 #include <ossim/support_data/ossimNitfImageHeader.h> 25 #include <memory> 26 27 struct jpeg_decompress_struct; 28 29 class OSSIM_DLL ossimNitfTileSource : public ossimImageHandler 30 { 31 public: 32 33 enum ReadMode 34 { 35 READ_MODE_UNKNOWN = 0, 36 37 /** IMODE = B "Band Interleaved By Block or a single band" */ 38 READ_BIB_BLOCK = 1, 39 40 /** IMODE = P "Band Interleaved By Pixel" */ 41 READ_BIP_BLOCK = 2, 42 43 /** IMODE = R "Band Interleaved By Row" */ 44 READ_BIR_BLOCK = 3, 45 46 /** IMODE = S "Band Sequential" */ 47 READ_BSQ_BLOCK = 4, 48 49 /** IMODE = B of S "single block or one block for each band" */ 50 READ_BIB = 5, 51 52 /** IMODE = P "single block Band Interleaved By Pixel" */ 53 READ_BIP = 6, 54 55 /** IMODE = R "single block Band Interleaved By Row" */ 56 READ_BIR = 7, 57 58 /** IMODE = B, IC = C3 "JPEG compressed blocks" */ 59 READ_JPEG_BLOCK = 8 60 }; 61 62 ossimNitfTileSource(); 63 64 65 virtual ossimString getShortName() const; 66 virtual ossimString getLongName() const; 67 68 /** 69 * Returns true if the image_file can be opened and is a valid nitf file. 70 */ 71 virtual bool open(); 72 73 /** 74 * @brief This open takes a stream and stores/captures the shared pointer 75 * on success. 76 * @param str Open stream to image. 77 * @param connectionString Stored on success as the file name. 78 * @return true on success, false on error. 79 */ 80 bool open( std::shared_ptr<ossim::istream>& str, 81 const std::string& connectionString ); 82 83 /** @brief Closes file and destroys all memory allocated. */ 84 virtual void close(); 85 86 /** 87 * @param tileRect Requested rectangle. 88 * 89 * @param resLevel Reduced resolution level to grab tileRect from. 90 * Default = 0 or the full resolution data set. 91 * 92 * @return Returns an image data object with requested rectangle from the 93 * image. Depending on the overlap of tileRect with respect to the image 94 * rectangle, the returned tile could be full, partial, or an empty(blank) 95 * tile. 96 */ 97 virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect, 98 ossim_uint32 resLevel=0); 99 100 /** 101 * @return Returns the number of bands in the image. 102 * Satisfies pure virtual from ImageHandler class. 103 */ 104 virtual ossim_uint32 getNumberOfInputBands() const; 105 106 /** 107 * @return Number of output bands. 108 */ 109 virtual ossim_uint32 getNumberOfOutputBands() const; 110 111 /** 112 * Returns the number of lines in the image. 113 * Satisfies pure virtual from ImageHandler class. 114 */ 115 virtual ossim_uint32 getNumberOfLines(ossim_uint32 resLevel = 0) const; 116 117 /** 118 * Returns the number of samples in the image. 119 * Satisfies pure virtual from ImageHandler class. 120 */ 121 virtual ossim_uint32 getNumberOfSamples(ossim_uint32 resLevel = 0) const; 122 123 /** 124 * Method to save the state of an object to a keyword list. 125 * Return true if ok or false on error. 126 */ 127 virtual bool saveState(ossimKeywordlist& kwl, 128 const char* prefix=0)const; 129 130 /** 131 * Method to the load (recreate) the state of an object from a keyword 132 * list. Return true if ok or false on error. 133 */ 134 virtual bool loadState(const ossimKeywordlist& kwl, 135 const char* prefix=0); 136 137 /** 138 * Returns the output pixel type of the tile source. 139 */ 140 virtual ossimScalarType getOutputScalarType() const; 141 142 /** 143 * Returns the width of the output tile. 144 */ 145 virtual ossim_uint32 getTileWidth() const; 146 147 /** 148 * Returns the height of the output tile. 149 */ 150 virtual ossim_uint32 getTileHeight() const; 151 152 /** 153 * Returns the tile width of the image or 0 if the image is not tiled. 154 * Note: this is not the same as the ossimImageSource::getTileWidth which 155 * returns the output tile width which can be different than the internal 156 * image tile width on disk. 157 */ 158 virtual ossim_uint32 getImageTileWidth() const; 159 160 /** 161 * Returns the tile width of the image or 0 if the image is not tiled. 162 * Note: this is not the same as the ossimImageSource::getTileWidth which 163 * returns the output tile width which can be different than the internal 164 * image tile width on disk. 165 */ 166 virtual ossim_uint32 getImageTileHeight() const; 167 168 virtual bool isOpen()const; 169 170 /** 171 * @return The current entry number. 172 * 173 * @note NITF's can contain multiple images in a single file. This returns 174 * the index of the current image being read. 175 */ 176 virtual ossim_uint32 getCurrentEntry() const; 177 178 /** 179 * @param entryList This is the list to initialize with entry indexes. 180 */ 181 virtual void getEntryList(std::vector<ossim_uint32>& entryList) const; 182 183 /** 184 * @return Returns the number of entries (or images) within the nitf 185 * file. 186 */ 187 ossim_uint32 getNumberOfEntries() const; 188 189 /** 190 * @param entryIdx Zero base entry number to select. Sets data member 191 * "theCurrentEntry". 192 * 193 * @note "theCurrentEntry" will not be set if "entryIdx" is out of range. 194 */ 195 virtual bool setCurrentEntry(ossim_uint32 entryIdx); 196 197 virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const; 198 virtual void setProperty(ossimRefPtr<ossimProperty> property); 199 virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const; 200 201 ossimString getSecurityClassification()const; 202 203 /** 204 * @return Returns theCacheEnabledFlag. 205 */ 206 bool getCacheEnabledFlag() const; 207 208 /** 209 * @param flag Sets theCacheEnabledFlag and disables/enables caching 210 * accordingly. If cache is disabled it is also flushed at the same time. 211 * If cache is enabled, blocks read from the image will be cached. 212 */ 213 void setCacheEnabledFlag(bool flag); 214 215 virtual double getMinPixelValue(ossim_uint32 band=0)const; 216 virtual double getMaxPixelValue(ossim_uint32 band=0)const; 217 virtual double getNullPixelValue(ossim_uint32 band=0)const; 218 219 const ossimNitfFileHeader* getFileHeader()const; 220 ossimNitfFileHeader* getFileHeader(); 221 ossimNitfFile *getNitfFile(); 222 const ossimNitfFile *getNitfFile()const; 223 224 /** 225 * @return The image header for the current entry. 226 */ 227 const ossimNitfImageHeader* getCurrentImageHeader() const; 228 ossimNitfImageHeader* getCurrentImageHeader(); 229 230 /** 231 * @brief Convenience method to get the zero based rgb output band list. 232 * 233 * Attempts to derive RGB bands from nitf fields. 234 * 235 * @param bandList Initialized by this. 236 * @return true on success, false if number of bands is less than 3 or if 237 * rgb bands could not be derived from nitf fields. 238 */ 239 virtual bool getRgbBandList(std::vector<ossim_uint32>& bandList) const; 240 241 protected: 242 virtual ~ossimNitfTileSource(); 243 244 /** 245 * @param imageRect The full resolution image rectangle. 246 * 247 * @note Should contain offsets if there are any. 248 */ 249 void setBoundingRectangle(const ossimIrect& imageRect); 250 251 /** Copy constructor, disallow... */ 252 ossimNitfTileSource(const ossimNitfTileSource& obj); 253 254 /** Operator=, disallow... */ 255 ossimNitfTileSource& operator=(const ossimNitfTileSource& rhs); 256 257 /** 258 * Returns true on success, false on error. 259 */ 260 bool loadTile(const ossimIrect& clipRect); 261 262 /** 263 * @return Returns the block number given an origin. 264 */ 265 ossim_uint32 getBlockNumber(const ossimIpt& block_origin) const; 266 267 /** 268 * Deletes all memory allocated by this object. 269 */ 270 void destroy(); 271 272 /** 273 * @brief Parses "theImageFile" and initializes all nitf headers. 274 * @return true on success, false on error. 275 */ 276 virtual bool parseFile(); 277 278 /** 279 * @brief Allocates everything for current entry. 280 * 281 * This is called on an open() or a entry change to an already open nitf 282 * file. 283 * 284 * This does not allocate buffers and tiles to keep open and 285 * setCurrentEntry times to a minimum. Buffers are allocated on first 286 * grab of pixel data by allocatBuffers method. 287 * 288 * @return True on success, false on error. 289 */ 290 virtual bool allocate(); 291 292 /** 293 * @brief Allocates buffers for current entry. 294 * 295 * This is called on first getTile(). 296 * 297 * @return True on success, false on error. 298 */ 299 virtual bool allocateBuffers(); 300 301 /** 302 * @param hdr Pointer to image header. 303 * @return true if reader can uncompress nitf. 304 * */ 305 virtual bool canUncompress(const ossimNitfImageHeader* hdr) const; 306 307 /** 308 * Initializes the data member "theScalarType" from the current entry. 309 */ 310 virtual void initializeScalarType(); 311 312 /** 313 * Initializes the data member "theSwapBytesFlag" from the current entry. 314 */ 315 virtual void initializeSwapBytesFlag(); 316 317 /** 318 * Initializes the data member "theReadMode" from the current entry. 319 */ 320 virtual void initializeReadMode(); 321 322 /** 323 * Initializes the data member "theNumberOfBands" from the current entry. 324 */ 325 void initializeBandCount(); 326 327 /** 328 * Initializes the data member "theBlockSize" from the current entry. 329 * 330 * @note This should be performed after setting the read mode and 331 * band count. 332 * 333 * @note This is the size of a single block read. So if the bands are 334 * separated by block, a read of this size will get one block. 335 * 336 * @return true on success, false on error. 337 */ 338 bool initializeBlockSize(); 339 340 /** 341 * Initializes the data members "theImageRect" and "theBlockRect" 342 * from the current entry. 343 * 344 * @return true on success, false on error. 345 */ 346 virtual bool initializeImageRect(); 347 348 /** 349 * Initializes the data member "theCacheSize". 350 */ 351 void initializeCacheSize(); 352 353 /** 354 * Initializes the data member "theCacheTileInterLeaveType". 355 */ 356 virtual void initializeCacheTileInterLeaveType(); 357 358 /** 359 * Initializes the cache tile size(width and height). For block images 360 * this will be the size of one block. For images that are a single block, 361 * this will be the image width by the height of one tile. 362 */ 363 void initializeCacheTile(); 364 365 /** 366 * Initializes the data member theCompressedBuf. 367 */ 368 virtual void initializeCompressedBuf(); 369 370 /** 371 * Initializes the output tile size(width and height). 372 */ 373 virtual void initializeOutputTile(); 374 375 /** 376 * @brief Initializes "theLut" if applicable. 377 */ 378 void initializeLut(); 379 380 /** 381 * Loads a block of data to theCacheTile. 382 * 383 * @param x Starting x position of block to load. 384 * 385 * @param y Starting y position of block to load. 386 * 387 * @return true on success, false on error. 388 * 389 * @note x and y are zero based relative to the upper left corner so any 390 * sub image offset should be subtracted off. 391 */ 392 bool loadBlockFromCache(ossim_uint32 x, ossim_uint32 y, 393 const ossimIrect& clipRect); 394 395 /** 396 * Loads a block of data to theCacheTile. 397 * 398 * @param x Starting x position of block to load. 399 * 400 * @param y Starting y position of block to load. 401 * 402 * @return true on success, false on error. 403 * 404 * @note x and y are zero based relative to the upper left corner so any 405 * sub image offset should be subtracted off. 406 */ 407 virtual bool loadBlock(ossim_uint32 x, ossim_uint32 y); 408 409 /** 410 * @param x Horizontal upper left pixel position of the requested block. 411 * 412 * @param y Vertical upper left pixel position of the requested block. 413 * 414 * @param band Band of block. Only relative with IMODES that have bands 415 * in separate blocks. 416 * 417 * @return true if the stream offset was settable and false otherwise. 418 */ 419 bool getPosition(std::streamoff& position, 420 ossim_uint32 x, 421 ossim_uint32 y, 422 ossim_uint32 band) const; 423 424 /** 425 * @return the total number of blocks for the current entry. 426 * 427 * @note For band separated blocks, all bands will be counted as on block. 428 */ 429 ossim_uint32 getNumberOfBlocks() const; 430 431 /** 432 * @return The number of bytes to get from one block band to the next band. 433 */ 434 std::streampos getBandOffset() const; 435 436 /** 437 * @return The number of bytes to get from one block to the next block. 438 */ 439 std::streampos getBlockOffset() const; 440 441 442 void explodePackedBits(ossimRefPtr<ossimImageData> packedBuffer)const; 443 444 void convertTransparentToNull(ossimRefPtr<ossimImageData> tile)const; 445 446 ossim_uint32 getPartialReadSize(const ossimIpt& blockOrigin)const; 447 bool isVqCompressed(const ossimString& compressionCode)const; 448 449 /** 450 * @brief Uncompresses Vector Quantization unmasked image data. 451 * IC field = C4 452 * @param destination tile to stuff. 453 * @param source Pointer to compressed data. 454 */ 455 void vqUncompressC4(ossimRefPtr<ossimImageData> destination, 456 ossim_uint8* source); 457 458 /** 459 * @brief Uncompresses Vector Quantization masked image data. 460 * IC field = M4 461 * @param destination tile to stuff. 462 * @param source Pointer to compressed data. 463 */ 464 void vqUncompressM4(ossimRefPtr<ossimImageData> destination, 465 ossim_uint8* source); 466 467 void lutUncompress(ossimRefPtr<ossimImageData> destination, 468 ossim_uint8* source); 469 470 /** 471 * @brief scans the file storing in offsets in "theNitfBlockOffset" and 472 * block sizes in "theNitfBlockSize". 473 * @return true on success, false on error. This checks for arrays being 474 * the same size as number of blocks. 475 */ 476 virtual bool scanForJpegBlockOffsets(); 477 478 /** 479 * @brief Uncompresses a jpeg block using the jpeg-6b library. 480 * This method does eight bit jpeg compressed blocks. Note there is 481 * specialized jpeg12 plugin for 12 bit. 482 * @param x sample location in image space. 483 * @param y line location in image space. 484 * @return true on success, false on error. 485 */ 486 virtual bool uncompressJpegBlock(ossim_uint32 x, ossim_uint32 y); 487 488 /** 489 * @brief Loads one of the default tables based on COMRAT value. 490 * 491 * @return true if comrat had valid table value(1-5) and table was loaded, 492 * false if COMRAT value did not contain a valid value. Will also return 493 * false if there is already a table loaded. 494 * 495 * @note COMRAT is nitf compression rate code field: 496 * - "00.2" == default compression table 2 497 * - "00.5" == default compression table 5 and so on. 498 */ 499 bool loadJpegQuantizationTables(jpeg_decompress_struct& cinfo) const; 500 501 /** 502 * @brief Loads default huffman tables. 503 * 504 * @return true success, false on error. 505 */ 506 bool loadJpegHuffmanTables(jpeg_decompress_struct& cinfo) const; 507 508 /** 509 * @brief Virtual method determines the decimation factors at each resolution level. 510 * This method derives the decimations from the image metadata. 511 */ 512 virtual void establishDecimationFactors(); 513 514 ossimRefPtr<ossimImageData> theTile; 515 ossimRefPtr<ossimImageData> theCacheTile; 516 ossimRefPtr<ossimNitfFile> theNitfFile; 517 std::vector<ossimRefPtr<ossimNitfImageHeader> > theNitfImageHeader; 518 ReadMode theReadMode; 519 ossimScalarType theScalarType; 520 bool theSwapBytesFlag; 521 ossim_uint32 theNumberOfInputBands; 522 ossim_uint32 theNumberOfOutputBands; 523 ossim_uint32 theBlockSizeInBytes; 524 ossim_uint32 theReadBlockSizeInBytes; 525 ossim_uint32 theNumberOfImages; 526 ossim_uint32 theCurrentEntry; 527 ossimIrect theImageRect; 528 std::shared_ptr<ossim::istream> theFileStr; 529 std::vector<ossim_uint32> theSelectorBandList; 530 std::vector<ossim_uint32> theOutputBandList; 531 ossimIpt theCacheSize; 532 ossimInterleaveType theCacheTileInterLeaveType; 533 bool theCacheEnabledFlag; 534 std::vector<ossim_uint32> theEntryList; 535 ossimAppFixedTileCache::ossimAppFixedCacheId theCacheId; 536 bool thePackedBitsFlag; 537 ossimIrect theBlockImageRect; 538 std::vector<ossim_uint8> theCompressedBuf; 539 540 //--- 541 // Have compressed jpeg blocks of variable length so we must scan and 542 // capture the offsetts and block sizes for reading. 543 //--- 544 std::vector<std::streamoff> theNitfBlockOffset; 545 std::vector<ossim_uint32> theNitfBlockSize; 546 547 //--- 548 // If set to true indicates scanForJpegBlockOffsets() needs to be called 549 // prior to grabbing a block. 550 //--- 551 bool m_jpegOffsetsDirty; 552 553 TYPE_DATA 554 }; 555 556 #endif /* #ifndef ossimNitfTileSource_HEADER */ 557