Isis 3 Programmer Reference
JP2Decoder.cpp
Go to the documentation of this file.
1 
23 #include <float.h>
24 #include <iostream>
25 #include <string>
26 #include <sstream>
27 
28 #include "IException.h"
29 #include "IString.h"
30 #include "JP2Decoder.h"
31 #include "JP2Error.h"
32 
33 using namespace std;
34 
35 #if ENABLEJP2K
36 using namespace kdu_core;
37 using namespace kdu_supp;
38 #endif
39 
40 namespace Isis {
41 
48  JP2Decoder::JP2Decoder(const QString &jp2file) {
49 
50 #if ENABLEJP2K
51  p_jp2File = jp2file;
52  p_resolutionLevel = 1;
53  JP2_Source = NULL;
54 
55  // Register the Kakadu error handler
56  Kakadu_Error = new JP2Error;
57  kdu_customize_errors(Kakadu_Error);
58 #else
59  std::string msg = "JPEG2000 has not been enabled with this build of ISIS3";
60  throw IException(IException::Programmer, msg, _FILEINFO_);
61 #endif
62  }
63 
68  void JP2Decoder::OpenFile() {
69 #if ENABLEJP2K
70  // Make sure file isn't already open
71  if(JP2_Source == NULL) {
72 
73  // Open the JP2 file stream
74  JP2_Stream = new jp2_family_src();
75  JP2_Stream->open(p_jp2File.toLatin1().data());
76 
77  // Open the JP2 source
78  JP2_Source = new jp2_source();
79  if(!JP2_Source->open(JP2_Stream)) {
80  QString msg = "Unable to open the decoder because the source file ";
81  msg += "does not have valid JP2 format content [" + p_jp2File + "]";
82  throw IException(IException::User, msg, _FILEINFO_);
83  }
84 
85  // Initialize the JP2 header boxes up to the first codestream box
86  JP2_Source->read_header();
87 
88  // Open the JP2 codestream
89  JPEG2000_Codestream = new kdu_codestream();
90  JPEG2000_Codestream->create(JP2_Source);
91 
92  // Get the image characteristics
93  // Number of components (bands)
94  p_numBands = JPEG2000_Codestream->get_num_components(true);
95 
96  // Image dimensions (sample offset, line offset, number of samples,
97  // number of lines) at full resolution
98  JPEG2000_Codestream->get_dims(0, p_imageDims, true); //dims.pos.x, dims.size.x
99 
100  // Pixel data structure
101  p_pixelBits = JPEG2000_Codestream->get_bit_depth(0, true);
102  p_pixelBytes = (p_pixelBits >> 3) + ((p_pixelBits % 8) ? 1 : 0);
103  if(p_pixelBytes == 3) p_pixelBytes = 4;
104  if(p_pixelBits > 16 || p_pixelBytes > 2) {
105  QString msg = "The source file has unsupported pixel type ";
106  msg += "[" + p_jp2File + "]";
107  throw IException(IException::User, msg, _FILEINFO_);
108  }
109  p_signedData = JPEG2000_Codestream->get_signed(0, true);
110 
111  // Check all bands in the JP2 file to make sure they all have the same
112  // dimensions, bit depth, and signedness
113  kdu_dims dims;
114  unsigned int pixel_bits;
115  bool signed_data;
116  for(unsigned int band = 1; band < p_numBands; ++band) {
117  JPEG2000_Codestream->get_dims(band, dims, true);
118  pixel_bits = JPEG2000_Codestream->get_bit_depth(band, true);
119  signed_data = JPEG2000_Codestream->get_signed(band, true);
120  if(dims.size.x != p_imageDims.size.x || dims.size.y != p_imageDims.size.y ||
121  dims.pos.x != p_imageDims.pos.x || dims.pos.y != p_imageDims.pos.y ||
122  pixel_bits != p_pixelBits || signed_data != p_signedData) {
123  std::string msg = "The source file does not have bands with matching ";
124  msg += "characteristics";
125  throw IException(IException::User, msg, _FILEINFO_);
126  }
127  }
128 
129  // Get the total available resolution levels and set the effective
130  // resolution and image region
131  p_highestResLevel = JPEG2000_Codestream->get_min_dwt_levels() + 1;
132  SetResolutionAndRegion();
133 
134  // Initialize the JP2 decoder
135  // Initialize the codestream stripe decompressor
136  p_decompressor.start(*JPEG2000_Codestream);
137 
138  // Determine optimum stripe heights for accessing data - the
139  // optimum stripe heights are ignored. We are instead reading
140  // the file a line at a time.
141  p_stripeHeights = new int[p_numBands];
142  p_maxStripeHeights = new int[p_numBands];
143  p_precisions = new int[p_numBands];
144  p_isSigned = new bool[p_numBands];
145  p_decompressor.get_recommended_stripe_heights(MIN_STRIPE_HEIGHT,
146  MAX_STRIPE_HEIGHT, p_stripeHeights, p_maxStripeHeights);
147  for(unsigned int i = 0; i < p_numBands; i++) {
148  p_precisions[i] = p_pixelBits;
149  p_stripeHeights[i] = 1;
150  p_isSigned[i] = p_signedData;
151  }
152  }
153 #endif
154  }
155 
161  void JP2Decoder::SetResolutionAndRegion() {
162 #if ENABLEJP2K
163  // Determine size of image at requested resolution and reset requested image
164  // area if it falls outside of image boundaries
165  JPEG2000_Codestream->apply_input_restrictions(0, 0, p_resolutionLevel - 1, 0, NULL,
166  KDU_WANT_OUTPUT_COMPONENTS);
167 
168  JPEG2000_Codestream->get_dims(0, p_imageDims, true);
169  p_numSamples = p_imageDims.size.x;
170  p_numLines = p_imageDims.size.y;
171 #endif
172  }
173 
184  void JP2Decoder::Read(unsigned char **inbuf) {
185 #if ENABLEJP2K
186  p_readStripes = p_decompressor.pull_stripe(inbuf, p_stripeHeights, NULL, NULL,
187  p_precisions);
188 #endif
189  }
190 
201  void JP2Decoder::Read(short int **inbuf) {
202 #if ENABLEJP2K
203  p_readStripes = p_decompressor.pull_stripe(inbuf, p_stripeHeights, NULL, NULL,
204  p_precisions, p_isSigned);
205 #endif
206  }
207 
212  JP2Decoder::~JP2Decoder() {
213 #if ENABLEJP2K
214  // See kdu_stripe_decompressor::reset documentation:
215  // "You should be sure to call this function or finish before destroying the kdu_codestream
216  // inteface that was passed to start."
217  // i.e. Make sure to finish the decompressor before destroying the kdu_codestream.
218  p_decompressor.finish();
219  if(JPEG2000_Codestream) {
220  JPEG2000_Codestream->destroy();
221  }
222  JPEG2000_Codestream = NULL;
223  if(JP2_Source) {
224  JP2_Source->close();
225  delete JP2_Source;
226  }
227  JP2_Source = NULL;
228  if(JP2_Stream) {
229  JP2_Stream->close();
230  delete JP2_Stream;
231  }
232  JP2_Stream = NULL;
233  if(Kakadu_Error) {
234  delete Kakadu_Error;
235  }
236  delete [] p_stripeHeights;
237  delete [] p_maxStripeHeights;
238  delete [] p_precisions;
239  delete [] p_isSigned;
240 #endif
241  }
242 
243 
244  bool JP2Decoder::IsJP2(QString filename) {
245 #if ENABLEJP2K
246  jp2_family_src *stream = new jp2_family_src();
247  stream->open(filename.toLatin1().data());
248  jp2_source *source = new jp2_source();
249 
250  bool result = source->open(stream);
251 
252  source->close();
253  delete source;
254 
255  stream->close();
256  delete stream;
257 
258  return result;
259 #else
260  return (false);
261 #endif
262  }
263 }
Namespace for the standard library.
Kakadu error messaging class.
Definition: JP2Error.h:54
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31