OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimKakaduJp2Writer.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 jp2 writer class definition.
8 //
9 //----------------------------------------------------------------------------
10 // $Id: ossimKakaduJp2Writer.cpp 23121 2015-01-30 01:24:56Z dburken $
11 
12 #include "ossimKakaduJp2Writer.h"
13 #include "ossimKakaduCommon.h"
14 #include "ossimKakaduCompressor.h"
15 #include "ossimKakaduMessaging.h"
16 
17 #include <ossim/base/ossimDate.h>
18 #include <ossim/base/ossimDpt.h>
19 #include <ossim/base/ossimEndian.h>
24 #include <ossim/base/ossimTrace.h>
25 
27 
31 
33 
34 #include <jp2.h>
35 #include <ostream>
36 
37 static const ossimIpt DEFAULT_TILE_SIZE(1024, 1024);
38 
39 RTTI_DEF1(ossimKakaduJp2Writer, "ossimKakaduJp2Writer", ossimImageFileWriter)
40 
41 //---
42 // For trace debugging (to enable at runtime do:
43 // your_app -T "ossimKakaduJp2Writer:debug" your_app_args
44 //---
45 static const ossimTrace traceDebug( ossimString("ossimKakaduJp2Writer:debug") );
46 
47 //---
48 // For the "ident" program which will find all exanded:
49 // $Id: ossimKakaduJp2Writer.cpp 23121 2015-01-30 01:24:56Z dburken $
50 //---
51 #if OSSIM_ID_ENABLED
52 static const char OSSIM_ID[] = "$Id: ossimKakaduJp2Writer.cpp 23121 2015-01-30 01:24:56Z dburken $";
53 #endif
54 
57  m_compressor(new ossimKakaduCompressor()),
58  m_outputStream(0),
59  m_ownsStreamFlag(false)
60 {
61  if (traceDebug())
62  {
64  << "ossimKakaduJp2Writer::ossimKakaduJp2Writer entered"
65  << std::endl;
66 #if OSSIM_ID_ENABLED
68  << "OSSIM_ID: "
69  << OSSIM_ID
70  << std::endl;
71 #endif
72  }
73 
74  // Set the output image type in the base class.
76 }
77 
79 {
80  // This will flush stream and delete it if we own it.
81  close();
82 
83  if (m_compressor)
84  {
85  delete m_compressor;
86  m_compressor = 0;
87  }
88 }
89 
91 {
92  return ossimString("ossim_kakadu_jp2");
93 }
94 
96 {
97  return ossimString("ossim kakadu jp2 writer");
98 }
99 
101 {
102  return ossimString("ossimKakaduJp2Writer");
103 }
104 
106 {
107  // This method is called from ossimImageFileWriter::execute().
108 
109  bool result = false;
110 
111  if( theInputConnection.valid() &&
113  {
114  // Set the tile size for all processes.
115  theInputConnection->setTileSize( DEFAULT_TILE_SIZE );
117 
118  //---
119  // Note only the master process used for writing...
120  //---
122  {
123  if (!isOpen())
124  {
125  open();
126  }
127 
128  if ( isOpen() )
129  {
130  result = writeStream();
131  }
132  }
133  else // Slave process.
134  {
135  // This will return after all tiles for this node have been processed.
137 
138  result = true;
139  }
140  }
141 
142  return result;
143 }
144 
146 {
147  static const char MODULE[] = "ossimKakaduJp2Writer::writeStream";
148 
149  if (traceDebug())
150  {
152  << MODULE << " entered..." << endl;
153  }
154 
155  bool result = false;
156 
159  {
160  result = true; // Assuming good at this point...
161 
162  ossim_uint32 outputTilesWide =
164  ossim_uint32 outputTilesHigh =
166  ossim_uint32 numberOfTiles =
169 
170  if (traceDebug())
171  {
173  << MODULE << " DEBUG:"
174  << "\noutputTilesWide: " << outputTilesWide
175  << "\noutputTilesHigh: " << outputTilesHigh
176  << "\nnumberOfTiles: " << numberOfTiles
177  << "\nimageRect: " << theInputConnection->getAreaOfInterest()
178  << std::endl;
179  }
180 
182 
184 
185  // Create the compressor. Can through an exception.
186  try
187  {
189  scalarType,
190  BANDS,
192  DEFAULT_TILE_SIZE,
193  numberOfTiles,
194  true);
195  }
196  catch (const ossimException& e)
197  {
198  ossimNotify(ossimNotifyLevel_WARN) << e.what() << std::endl;
199  return false;
200  }
201 
204 
206 
207  bool needAlpha = m_compressor->getAlphaChannelFlag();
208 
209  // Tile loop in the line direction.
210  for(ossim_uint32 y = 0; y < outputTilesHigh; ++y)
211  {
212  // Tile loop in the sample (width) direction.
213  for(ossim_uint32 x = 0; x < outputTilesWide; ++x)
214  {
215  // Grab the resampled tile.
217  if (t.valid() && ( t->getDataObjectStatus() != OSSIM_NULL ) )
218  {
219  if (needAlpha)
220  {
221  t->computeAlphaChannel();
222  }
223  if ( ! m_compressor->writeTile( *(t.get()) ) )
224  {
226  << MODULE << " ERROR:"
227  << "Error returned writing tile: "
228  << tileNumber
229  << std::endl;
230  result = false;
231  }
232  }
233  else
234  {
236  << MODULE << " ERROR:"
237  << "Error returned writing tile: " << tileNumber
238  << std::endl;
239  result = false;
240  }
241  if (result == false)
242  {
243  // This will bust out of both loops.
244  x = outputTilesWide;
245  y = outputTilesHigh;
246  }
247 
248  // Increment tile number for percent complete.
249  ++tileNumber;
250 
251  } // End of tile loop in the sample (width) direction.
252 
253  if (needsAborting())
254  {
255  setPercentComplete(100.0);
256  break;
257  }
258  else
259  {
260  ossim_float64 tile = tileNumber;
261  ossim_float64 numTiles = numberOfTiles;
262  setPercentComplete(tile / numTiles * 100.0);
263  }
264 
265  } // End of tile loop in the line (height) direction.
266 
267  m_compressor->finish();
268 
269  close();
270 
271  } // matches: if (theInputConnection.valid() ...
272 
273  if (traceDebug())
274  {
276  << MODULE << " exit status = " << (result?"true":"false\n")
277  << std::endl;
278  }
279 
280  return result;
281 }
282 
284 {
285  bool result = false;
286 
287  if ( theInputConnection.valid() && compressor )
288  {
290  if ( geom.valid() )
291  {
292  //---
293  // Make a temp file. No means currently write a tiff straight to
294  // memory.
295  //---
297  tmpFile += "-tmp.tif";
298 
299  // Output rect.
301 
302  result = compressor->writeGeotiffBox(geom.get(), rect, tmpFile, getPixelType());
303  }
304  }
305 
306  return result;
307 
308 } // End: ossimKakaduJp2Writer::writeGeotffBox
309 
311 {
312  bool result = false;
313 
314  if ( theInputConnection.valid() && compressor )
315  {
317  if ( geom.valid() )
318  {
319  // Output rect.
321 
322  result = compressor->writeGmlBox( geom.get(), rect );
323  }
324  }
325 
326  return result;
327 
328 } // End: ossimKakaduJp2Writer::writeGmlBox
329 
331  const char* prefix)const
332 {
333  m_compressor->saveState(kwl, prefix);
334 
335  return ossimImageFileWriter::saveState(kwl, prefix);
336 }
337 
339  const char* prefix)
340 {
341  m_compressor->loadState(kwl, prefix);
342 
343  return ossimImageFileWriter::loadState(kwl, prefix);
344 }
345 
347 {
348  return (m_outputStream?true:false);
349 }
350 
352 {
353  bool result = false;
354 
355  close();
356 
357  // Check for empty filenames.
358  if (theFilename.size())
359  {
360  std::ofstream* os = new std::ofstream();
361  os->open(theFilename.c_str(), ios::out | ios::binary);
362  if(os->is_open())
363  {
364  m_outputStream = os;
365  m_ownsStreamFlag = true;
366  result = true;
367  }
368  else
369  {
370  delete os;
371  os = 0;
372  }
373  }
374 
375  if (traceDebug())
376  {
378  << "ossimKakaduJp2Writer::open()\n"
379  << "File " << theFilename << (result ? " opened" : " not opened")
380  << std::endl;
381  }
382 
383  return result;
384 }
385 
387 {
388  if (m_outputStream)
389  {
390  m_outputStream->flush();
391  if (m_ownsStreamFlag)
392  {
393  delete m_outputStream;
394  m_outputStream = 0;
395  m_ownsStreamFlag = false;
396  }
397  }
398 }
399 
400 void ossimKakaduJp2Writer::getImageTypeList(std::vector<ossimString>& imageTypeList)const
401 {
402  imageTypeList.push_back(getShortName());
403 }
404 
406 {
407  return ossimString("jp2");
408 }
409 
411 {
412  return true;
413 }
414 
416 {
417  bool result = false;
418  if ( (imageType == getShortName()) ||
419  (imageType == "image/jp2") )
420  {
421  result = true;
422  }
423  return result;
424 }
425 
427 {
428  if ( property.valid() )
429  {
430  if ( m_compressor->setProperty(property) == false )
431  {
432  // Not a compressor property.
434  }
435  }
436 }
437 
439  const ossimString& name)const
440 {
442 
443  if ( !p )
444  {
446  }
447 
448  return p;
449 }
450 
452  std::vector<ossimString>& propertyNames)const
453 {
454  m_compressor->getPropertyNames(propertyNames);
455 
457 }
458 
460 {
462  {
463  delete m_outputStream;
464  }
465  m_outputStream = &stream;
466  m_ownsStreamFlag = false;
467  return true;
468 }
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
ossim_uint32 x
virtual ossimString getLongName() const
virtual void setOutputImageType(ossim_int32 type)
virtual ossimString getShortName() const
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 computeAlphaChannel()
Computes the alpha channel.
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
ossim_uint32 tileNumber
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
Pushes this&#39;s names onto the list of property names.
Represents serializable keyword/value map.
ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
static const ossimErrorCode OSSIM_OK
virtual ossim_uint32 getNumberOfOutputBands() const
Returns the number of bands in a tile returned from this TileSource.
ossim_uint32 y
bool writeGmlBox(const ossimImageGeometry *geom, const ossimIrect &rect)
Writes the GML box to the jp2.
bool valid() const
Definition: ossimRefPtr.h:75
virtual void finish()
Finish method.
ossimKakaduJp2Writer()
default constructor
virtual bool writeStream()
Method to write the image to a stream.
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
virtual ossimRefPtr< ossimImageData > getNextTile(ossim_uint32 resLevel=0)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
virtual ossimDataObjectStatus getDataObjectStatus() const
virtual ossimString getExtension() const
Returns a 3-letter extension from the image type descriptor (theOutputImageType) that can be used for...
Pure virtual base class for image file writers.
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
virtual void setProperty(ossimRefPtr< ossimProperty > property)
Will set the property whose name matches the argument "property->getName()".
void getPropertyNames(std::vector< ossimString > &propertyNames) const
Pushes this&#39;s names onto the list of property names.
double ossim_float64
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
saves the state of the object.
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.
std::string::size_type size() const
Definition: ossimString.h:405
ossimRefPtr< ossimImageSourceSequencer > theInputConnection
virtual bool setOutputStream(std::ostream &stream)
Sets the output stream to write to.
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
This will return the bounding rect of the source.
unsigned int ossim_uint32
virtual ossimString getClassName() const
void openJp2Codestream()
Calls "open_codestream" on the m_jp2Target.
bool getAlphaChannelFlag() const
Retrieve the writer&#39;s setting for whether or not to add an alpha channel to the output png image...
virtual ossimPixelType getPixelType() const
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
virtual ossimRefPtr< ossimImageGeometry > getImageGeometry()
Returns the image geometry object associated with this tile source or NULL if not defined...
ossimScalarType
bool writeGeotiffBox(const ossimImageGeometry *geom, const ossimIrect &rect, const ossimFilename &tmpFile, ossimPixelType pixelType)
Writes the geotiff box to the jp2.
virtual bool isOpen() const
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 getImageTypeList(std::vector< ossimString > &imageTypeList) const
Appends this writer image types to list "imageTypeList".
ossim_int64 getNumberOfTilesHorizontal() const
virtual void setProperty(ossimRefPtr< ossimProperty > property)
virtual ossimErrorCode getErrorStatus() const
bool writeGeotiffBox(ossimKakaduCompressor *compressor)
Writes geotiff box if input has good geometry.
ossimFilename fileNoExtension() 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
bool hasImageType(const ossimString &imageType) const
bool hasImageType(const ossimString& imageType) const
virtual bool writeFile()
Writes the file to disk or a stream.
const ossimIrect & getAreaOfInterest() const
std::basic_ofstream< char > ofstream
Class for char output file streams.
Definition: ossimIosFwd.h:47
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
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.
bool writeGmlBox(ossimKakaduCompressor *compressor)
Writes GML box if input has good geometry.
virtual void setTileSize(const ossimIpt &tileSize)
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
ossim_int64 getNumberOfTilesVertical() const
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
ossimKakaduCompressor * m_compressor
virtual bool getOutputHasInternalOverviews(void) const
Examples of writers that always generate internal overviews are ossim_kakadu_jp2 and ossim_kakadu_nit...