OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimKakaduNitfWriter.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 // Description: OSSIM Kakadu based nitf writer.
8 //
9 //----------------------------------------------------------------------------
10 // $Id: ossimKakaduNitfWriter.cpp 22111 2013-01-12 18:44:25Z dburken $
11 
12 #include "ossimKakaduNitfWriter.h"
13 #include "ossimKakaduCommon.h"
14 #include "ossimKakaduCompressor.h"
15 #include "ossimKakaduKeywords.h"
16 #include "ossimKakaduMessaging.h"
17 
19 #include <ossim/base/ossimDate.h>
20 #include <ossim/base/ossimDpt.h>
21 #include <ossim/base/ossimEndian.h>
26 #include <ossim/base/ossimTrace.h>
27 
29 
32 
39 
40 #include <ostream>
41 
42 static const ossimIpt DEFAULT_TILE_SIZE(1024, 1024);
43 
44 RTTI_DEF1(ossimKakaduNitfWriter, "ossimKakaduNitfWriter", ossimNitfWriterBase)
45 
46 //---
47 // For trace debugging (to enable at runtime do:
48 // your_app -T "ossimKakaduNitfWriter:debug" your_app_args
49 //---
50 static const ossimTrace traceDebug( ossimString("ossimKakaduNitfWriter:debug") );
51 
52 //---
53 // For the "ident" program which will find all exanded $Id: ossimKakaduNitfWriter.cpp 22111 2013-01-12 18:44:25Z dburken $
54 // them.
55 //---
56 #if OSSIM_ID_ENABLED
57 static const char OSSIM_ID[] = "$Id: ossimKakaduNitfWriter.cpp 22111 2013-01-12 18:44:25Z dburken $";
58 #endif
59 
62  m_compressor(new ossimKakaduCompressor()),
63  m_outputStream(0),
64  m_ownsStreamFlag(false)
65 {
66  if (traceDebug())
67  {
69  << "ossimKakaduNitfWriter::ossimKakaduNitfWriter entered"
70  << std::endl;
71 #if OSSIM_ID_ENABLED
73  << "OSSIM_ID: "
74  << OSSIM_ID
75  << std::endl;
76 #endif
77  }
78 
79  //---
80  // Since the internal nitf tags are not very accurate, write an external
81  // geometry out as default behavior. Users can disable this via the
82  // property interface or keyword list.
83  //---
85 
86  // Set the output image type in the base class.
88 }
89 
91 {
92  // This will flush stream and delete it if we own it.
93  close();
94 
95  if (m_compressor)
96  {
97  delete m_compressor;
98  m_compressor = 0;
99  }
100 }
101 
103 {
104  return ossimString("ossim_kakadu_nitf_j2k");
105 }
106 
108 {
109  return ossimString("ossim kakadu nitf j2k writer");
110 }
111 
113 {
114  return ossimString("ossimKakaduNitfWriter");
115 }
116 
118 {
119  // This method is called from ossimImageFileWriter::execute().
120 
121  bool result = false;
122 
123  if( theInputConnection.valid() &&
125  {
126  // Set the tile size for all processes.
127  theInputConnection->setTileSize( DEFAULT_TILE_SIZE );
129 
130  //---
131  // Note only the master process used for writing...
132  //---
134  {
135  if (!isOpen())
136  {
137  open();
138  }
139 
140  if ( isOpen() )
141  {
142  result = writeStream();
143  }
144  }
145  else // Slave process.
146  {
147  // This will return after all tiles for this node have been processed.
149 
150  result = true;
151  }
152  }
153 
154  return result;
155 }
156 
158 {
159  static const char MODULE[] = "ossimKakaduNitfWriter::writeStream";
160 
161  if (traceDebug())
162  {
164  << MODULE << " entered..." << endl;
165  }
166 
168  {
169  return false;
170  }
171 
175 
177  {
178  //---
179  // Someone can set this through the generic setProperty interface.
180  // Unset, currently only supported in jp2 writer.
181  // Could be used here but I think we would have to update the
182  // nitf tags.
183  //---
185  }
186 
187  // Create the compressor. Can through an exception.
188  try
189  {
191  SCALAR,
192  BANDS,
194  DEFAULT_TILE_SIZE,
195  TILES,
196  false);
197  }
198  catch (const ossimException& e)
199  {
200  ossimNotify(ossimNotifyLevel_WARN) << e.what() << std::endl;
201  return false;
202  }
203 
204  std::streampos endOfFileHdrPos;
205  std::streampos endOfImgHdrPos;
206  std::streampos endOfFilePos;
207 
208  // Container record withing NITF file header.
209  ossimNitfImageInfoRecordV2_1 imageInfoRecord;
210 
211  // NITF file header.
213 
214  // Note the sub header length and image length will be set later.
215  fHdr->addImageInfoRecord(imageInfoRecord);
216 
217  fHdr->setDate(ossimDate());
218  fHdr->setTitle(ossimString("")); // ???
219 
220  // Write to stream capturing the stream position for later.
221  fHdr->writeStream(*m_outputStream);
222  endOfFileHdrPos = m_outputStream->tellp();
223 
224  // NITF image header.
226 
227  // Set the compression type:
228  iHdr->setCompression(ossimString("C8"));
229 
230  // Set the Image Magnification (IMAG) field.
231  iHdr->setImageMagnification(ossimString("1.0"));
232 
233  // Set the pixel type (PVTYPE) field.
235 
236  // Set the actual bits per pixel (ABPP) field.
238  iHdr->setActualBitsPerPixel( abpp );
239 
240  // Set the bits per pixel (NBPP) field.
242 
243  iHdr->setNumberOfBands(BANDS);
244  iHdr->setImageMode('B'); // IMODE field to blocked.
245 
246  if( (BANDS == 3) && (SCALAR == OSSIM_UCHAR) )
247  {
248  iHdr->setRepresentation("RGB");
249  iHdr->setCategory("VIS");
250  }
251  else if(BANDS == 1)
252  {
253  iHdr->setRepresentation("MONO");
254  iHdr->setCategory("MS");
255  }
256  else
257  {
258  iHdr->setRepresentation("MULTI");
259  iHdr->setCategory("MS");
260  }
261 
262  ossimNitfImageBandV2_1 bandInfo;
263  for(ossim_uint32 band = 0; band < BANDS; ++band)
264  {
265  std::ostringstream out;
266 
267  out << std::setfill('0')
268  << std::setw(2)
269  << band;
270 
271  bandInfo.setBandRepresentation(out.str().c_str());
272  iHdr->setBandInfo(band, bandInfo);
273  }
274 
277 
278  iHdr->setBlocksPerRow(outputTilesWide);
279  iHdr->setBlocksPerCol(outputTilesHigh);
280  iHdr->setNumberOfPixelsPerBlockRow(DEFAULT_TILE_SIZE.y);
281  iHdr->setNumberOfPixelsPerBlockCol(DEFAULT_TILE_SIZE.x);
284 
285  // Write the geometry info to the image header.
287 
288  // Add the J2KLRA TRE:
290  m_compressor->initialize( j2klraTag.get(), abpp );
291  j2klraTag->setBandsO( BANDS );
292  ossimRefPtr<ossimNitfRegisteredTag> tag = j2klraTag.get();
293  ossimNitfTagInformation tagInfo( tag );
294  iHdr->addTag( tagInfo );
295 
296  // Write the image header to stream capturing the stream position.
297  iHdr->writeStream(*m_outputStream);
298  endOfImgHdrPos = m_outputStream->tellp();
299 
300  if (traceDebug())
301  {
303  << MODULE << " DEBUG:"
304  << "\noutputTilesWide: " << outputTilesWide
305  << "\noutputTilesHigh: " << outputTilesHigh
306  << "\nnumberOfTiles: " << TILES
307  << "\nimageRect: " << theInputConnection->getAreaOfInterest()
308  << std::endl;
309  }
310 
311  // Tile loop in the line direction.
313  bool result = true;
314  for(ossim_uint32 y = 0; y < outputTilesHigh; ++y)
315  {
316  // Tile loop in the sample (width) direction.
317  for(ossim_uint32 x = 0; x < outputTilesWide; ++x)
318  {
319  // Grab the resampled tile.
321  if (t.valid() && ( t->getDataObjectStatus() != OSSIM_NULL ) )
322  {
323  if ( ! m_compressor->writeTile( *(t.get()) ) )
324  {
326  << MODULE << " ERROR:"
327  << "Error returned writing tile: "
328  << tileNumber
329  << std::endl;
330  result = false;
331  }
332  }
333  else
334  {
336  << MODULE << " ERROR:"
337  << "Error returned writing tile: " << tileNumber
338  << std::endl;
339  result = false;
340  }
341  if ( !result )
342  {
343  // This will bust out of both loops.
344  x = outputTilesWide;
345  y = outputTilesHigh;
346  }
347 
348  // Increment tile number for percent complete.
349  ++tileNumber;
350 
351  } // End of tile loop in the sample (width) direction.
352 
353  if (needsAborting())
354  {
355  setPercentComplete(100.0);
356  break;
357  }
358  else
359  {
360  ossim_float64 tile = tileNumber;
361  ossim_float64 numTiles = TILES;
362  setPercentComplete(tile / numTiles * 100.0);
363  }
364 
365  } // End of tile loop in the line (height) direction.
366 
367  m_compressor->finish();
368 
369  // Get the file length.
370  endOfFilePos = m_outputStream->tellp();
371 
372  //---
373  // Seek back to set some things that were not know until now and
374  // rewrite the nitf file and image header.
375  //---
376  m_outputStream->seekp(0, std::ios_base::beg);
377 
378  // Set the file length.
379  std::streamoff length = endOfFilePos;
380  fHdr->setFileLength(static_cast<ossim_uint64>(length));
381 
382  // Set the file header length.
383  length = endOfFileHdrPos;
384  fHdr->setHeaderLength(static_cast<ossim_uint64>(length));
385  // Set the image sub header length.
386  length = endOfImgHdrPos - endOfFileHdrPos;
387 
388  imageInfoRecord.setSubheaderLength(static_cast<ossim_uint64>(length));
389 
390  // Set the image length.
391  length = endOfFilePos - endOfImgHdrPos;
392  imageInfoRecord.setImageLength(static_cast<ossim_uint64>(length));
393 
394  fHdr->replaceImageInfoRecord(0, imageInfoRecord);
395 
396  setComplexityLevel(length, fHdr.get());
397 
398  // Rewrite the header.
399  fHdr->writeStream(*m_outputStream);
400 
401  // Set the compression rate now that the image size is known.
404  BANDS,
405  SCALAR,
406  static_cast<ossim_uint64>(length));
407  iHdr->setCompressionRateCode(comrat);
408 
409  // Rewrite the image header.
410  iHdr->writeStream(*m_outputStream);
411 
412  close();
413 
414  if (traceDebug())
415  {
417  << MODULE << " exit status = " << (result?"true":"false\n")
418  << std::endl;
419  }
420 
421  return result;
422 }
423 
425  const char* prefix)const
426 {
427  m_compressor->saveState(kwl, prefix);
428 
429  return ossimNitfWriterBase::saveState(kwl, prefix);
430 }
431 
433  const char* prefix)
434 {
435  m_compressor->loadState(kwl, prefix);
436 
437  return ossimNitfWriterBase::loadState(kwl, prefix);
438 }
439 
441 {
442  return (m_outputStream) ? true : false;
443 }
444 
446 {
447  bool result = false;
448 
449  close();
450 
451  // Check for empty filenames.
452  if (theFilename.size())
453  {
454  std::ofstream* os = new std::ofstream();
455  os->open(theFilename.c_str(), ios::out | ios::binary);
456  if(os->is_open())
457  {
458  m_outputStream = os;
459  m_ownsStreamFlag = true;
460  result = true;
461  }
462  else
463  {
464  delete os;
465  os = 0;
466  }
467  }
468 
469  if (traceDebug())
470  {
472  << "ossimKakaduNitfWriter::open()\n"
473  << "File " << theFilename << (result ? " opened" : " not opened")
474  << std::endl;
475  }
476 
477  return result;
478 }
479 
481 {
482  if (m_outputStream)
483  {
484  m_outputStream->flush();
485 
486  if (m_ownsStreamFlag)
487  {
488  delete m_outputStream;
489  m_outputStream = 0;
490  m_ownsStreamFlag = false;
491  }
492  }
493 }
494 
496 {
497  return ossimString("ntf");
498 }
499 
501 {
502  return true;
503 }
504 
505 void ossimKakaduNitfWriter::getImageTypeList(std::vector<ossimString>& imageTypeList)const
506 {
507  imageTypeList.push_back(getShortName());
508 }
509 
511 {
512  bool result = false;
513  if ( (imageType == getShortName()) ||
514  (imageType == "image/ntf") )
515  {
516  result = true;
517  }
518  return result;
519 }
520 
522 {
523  if ( property.valid() )
524  {
525  if ( m_compressor->setProperty(property) == false )
526  {
527  // Not a compressor property.
529  }
530  }
531 }
532 
534  const ossimString& name)const
535 {
537 
538  if ( !p )
539  {
541  }
542 
543  return p;
544 }
545 
547  std::vector<ossimString>& propertyNames)const
548 {
549  m_compressor->getPropertyNames(propertyNames);
550 
552 }
553 
555 {
557  {
558  delete m_outputStream;
559  }
560  m_outputStream = &stream;
561  m_ownsStreamFlag = false;
562  return true;
563 }
virtual void setProperty(ossimRefPtr< ossimProperty > property)
Set the properties.
ossim_uint32 x
virtual void setOutputImageType(ossim_int32 type)
virtual void create(ossim::ostream *os, ossimScalarType scalar, ossim_uint32 bands, const ossimIrect &imageRect, const ossimIpt &tileSize, ossim_uint32 tilesToWrite, bool jp2)
Create method.
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
void setPixelType(const ossimString &pixelType=ossimString("INT"))
ossimKakaduCompressor * m_compressor
virtual void setFileLength(ossim_uint64 fileLength)
Sets file length (FL) field.
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
void setNumberOfPixelsPerBlockRow(ossim_uint32 pixels)
void setActualBitsPerPixel(ossim_uint32 bitsPerPixel)
virtual void setNumberOfBands(ossim_uint32 nbands)
ossim_uint32 tileNumber
Represents serializable keyword/value map.
ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
void initialize(ossimNitfJ2klraTag *j2klraTag, ossim_uint32 actualBitsPerPixel) const
Initializes the tag.
static const ossimErrorCode OSSIM_OK
void setDate(const ossimLocalTm &d)
Sets field FDT.
virtual ossim_uint32 getNumberOfOutputBands() const
Returns the number of bands in a tile returned from this TileSource.
ossim_uint32 y
bool valid() const
Definition: ossimRefPtr.h:75
virtual void finish()
Finish method.
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
Pushes this&#39;s names onto the list of property names.
virtual void writeStream(std::ostream &out)
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
void setSubheaderLength(ossim_uint32 length)
virtual ossimString getLongName() const
ossim_uint32 height() const
Definition: ossimIrect.h:487
virtual ossimRefPtr< ossimImageData > getNextTile(ossim_uint32 resLevel=0)
static ossimString getNitfPixelType(ossimScalarType scalarType)
Get the nitf pixel type string from scalar type.
virtual bool writeStream()
Method to write the image to a stream.
virtual void addTag(const ossimNitfTagInformation &tag, bool unique=true)
virtual void setHeaderLength(ossim_uint64 headerLength)
Sets header length (HL) field.
virtual void replaceImageInfoRecord(int i, const ossimNitfImageInfoRecordV2_1 &recordInfo)
virtual ossimDataObjectStatus getDataObjectStatus() const
OSSIM_DLL ossim_uint32 getActualBitsPerPixel(ossimScalarType scalarType)
Get actual bits per pixel for a given scalar type.
void getPropertyNames(std::vector< ossimString > &propertyNames) const
Pushes this&#39;s names onto the list of property names.
static ossimString getCompressionRate(const ossimIrect &rect, ossim_uint32 bands, ossimScalarType scalar, ossim_uint64 lengthInBytes)
Get compression rate (COMRAT) which is bits perpixel per band.
void setTitle(const ossimString &title)
void setBitsPerPixel(ossim_uint32 bitsPerPixel)
double ossim_float64
void setBlocksPerRow(ossim_uint32 blocks)
bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
saves the state of the object.
virtual ossimScalarType getOutputScalarType() const
This will be used to query the output pixel type of the tile source.
virtual const char * what() const
Returns the error message.
void setCategory(const ossimString &category)
std::string::size_type size() const
Definition: ossimString.h:405
ossimRefPtr< ossimImageSourceSequencer > theInputConnection
unsigned long long ossim_uint64
void setImageLength(ossim_uint64 length)
unsigned int ossim_uint32
virtual bool getOutputHasInternalOverviews(void) const
Examples of writers that always generate internal overviews are ossim_kakadu_jp2 and ossim_kakadu_nit...
virtual ossimString getClassName() const
OSSIM nitf writer base class to hold methods common to all nitf writers.
virtual ossimString getExtension() const
Returns a 3-letter extension from the image type descriptor (theOutputImageType) that can be used for...
void setCompressionRateCode(const ossimString &value)
bool getAlphaChannelFlag() const
Retrieve the writer&#39;s setting for whether or not to add an alpha channel to the output png image...
virtual bool writeFile()
Writes the file to disk or a stream.
virtual void getImageTypeList(std::vector< ossimString > &imageTypeList) const
Appends this writer image types to list "imageTypeList".
void setNumberOfPixelsPerBlockCol(ossim_uint32 pixels)
virtual void setAlphaChannelFlag(bool flag)
Set the writer to add an alpha channel to the output.
ossim_uint32 width() const
Definition: ossimIrect.h:500
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
saves the state of the object.
virtual void setNumberOfRows(ossim_uint32 rows)
ossimScalarType
OSSIM_DLL ossim_uint32 getBitsPerPixel(ossimScalarType scalarType)
Get bits per pixel for a given scalar type.
virtual void addImageInfoRecord(const ossimNitfImageInfoRecordV2_1 &recordInfo)
virtual bool setProperty(ossimRefPtr< ossimProperty > property)
Will set the property whose name matches the argument "property->getName()".
virtual bool writeTile(ossimImageData &srcTile)
Write tile method.
virtual void setNumberOfCols(ossim_uint32 cols)
virtual bool isOpen() const
ossim_int64 getNumberOfTilesHorizontal() const
void setBlocksPerCol(ossim_uint32 blocks)
void setRepresentation(const ossimString &rep)
virtual void setProperty(ossimRefPtr< ossimProperty > property)
Will set the property whose name matches the argument "property->getName()".
virtual ossimErrorCode getErrorStatus() const
void writeGeometry(ossimNitfImageHeaderV2_X *hdr, ossimImageSourceSequencer *seq)
Populates tags with geometry info from projection.
ossim_int32 y
Definition: ossimIpt.h:142
virtual void setWriteExternalGeometryFlag(bool flag)
bool hasImageType(const ossimString &imageType) const
bool hasImageType(const ossimString& imageType) const
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Initializes the state of the writer from kwl with prefix then calls base class ossimImageFileWriter::...
void setComplexityLevel(std::streamoff, ossimNitfFileHeaderV2_X *hdr)
Sets the complexity level of theFileHeader.
virtual void writeStream(ossim::ostream &out)
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
const ossimIrect & getAreaOfInterest() const
ossim_int32 x
Definition: ossimIpt.h:141
std::basic_ofstream< char > ofstream
Class for char output file streams.
Definition: ossimIosFwd.h:47
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
Gets a property.
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
virtual void setBandRepresentation(const ossimString &rep)
Sets the band representation.
void setCompression(const ossimString &value)
virtual void setPercentComplete(double percentComplete)
bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
virtual bool setOutputStream(std::ostream &stream)
Sets the output stream to write to.
virtual void setTileSize(const ossimIpt &tileSize)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Saves the state of the writer to kwl with prefix then calls base class ossimImageFileWriter::saveStat...
virtual void setImageMagnification(const ossimString &value)
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
ossim_int64 getNumberOfTilesVertical() const
ossimKakaduNitfWriter()
default constructor
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
virtual ossimString getShortName() const
8 bit unsigned iteger
virtual void setBandInfo(ossim_uint32 idx, const ossimNitfImageBandV2_1 &info)