Isis 3.0 Programmer Reference
Back | Home
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 namespace Isis {
35 
42  JP2Decoder::JP2Decoder(const QString &jp2file) {
43 
44 #if ENABLEJP2K
45  p_jp2File = jp2file;
46  p_resolutionLevel = 1;
47  JP2_Source = NULL;
48 
49  // Register the Kakadu error handler
50  Kakadu_Error = new JP2Error;
51  kdu_customize_errors(Kakadu_Error);
52 #else
53  std::string msg = "JPEG2000 has not been enabled with this build of ISIS3";
54  throw IException(IException::Programmer, msg, _FILEINFO_);
55 #endif
56  }
57 
62  void JP2Decoder::OpenFile() {
63 #if ENABLEJP2K
64  // Make sure file isn't already open
65  if(JP2_Source == NULL) {
66 
67  // Open the JP2 file stream
68  JP2_Stream = new jp2_family_src();
69  JP2_Stream->open(p_jp2File.toLatin1().data());
70 
71  // Open the JP2 source
72  JP2_Source = new jp2_source();
73  if(!JP2_Source->open(JP2_Stream)) {
74  QString msg = "Unable to open the decoder because the source file ";
75  msg += "does not have valid JP2 format content [" + p_jp2File + "]";
76  throw IException(IException::User, msg, _FILEINFO_);
77  }
78 
79  // Initialize the JP2 header boxes up to the first codestream box
80  JP2_Source->read_header();
81 
82  // Open the JP2 codestream
83  JPEG2000_Codestream = new kdu_codestream();
84  JPEG2000_Codestream->create(JP2_Source);
85 
86  // Get the image characteristics
87  // Number of components (bands)
88  p_numBands = JPEG2000_Codestream->get_num_components(true);
89 
90  // Image dimensions (sample offset, line offset, number of samples,
91  // number of lines) at full resolution
92  JPEG2000_Codestream->get_dims(0, p_imageDims, true); //dims.pos.x, dims.size.x
93 
94  // Pixel data structure
95  p_pixelBits = JPEG2000_Codestream->get_bit_depth(0, true);
96  p_pixelBytes = (p_pixelBits >> 3) + ((p_pixelBits % 8) ? 1 : 0);
97  if(p_pixelBytes == 3) p_pixelBytes = 4;
98  if(p_pixelBits > 16 || p_pixelBytes > 2) {
99  QString msg = "The source file has unsupported pixel type ";
100  msg += "[" + p_jp2File + "]";
101  throw IException(IException::User, msg, _FILEINFO_);
102  }
103  p_signedData = JPEG2000_Codestream->get_signed(0, true);
104 
105  // Check all bands in the JP2 file to make sure they all have the same
106  // dimensions, bit depth, and signedness
107  kdu_dims dims;
108  unsigned int pixel_bits;
109  bool signed_data;
110  for(unsigned int band = 1; band < p_numBands; ++band) {
111  JPEG2000_Codestream->get_dims(band, dims, true);
112  pixel_bits = JPEG2000_Codestream->get_bit_depth(band, true);
113  signed_data = JPEG2000_Codestream->get_signed(band, true);
114  if(dims.size.x != p_imageDims.size.x || dims.size.y != p_imageDims.size.y ||
115  dims.pos.x != p_imageDims.pos.x || dims.pos.y != p_imageDims.pos.y ||
116  pixel_bits != p_pixelBits || signed_data != p_signedData) {
117  std::string msg = "The source file does not have bands with matching ";
118  msg += "characteristics";
119  throw IException(IException::User, msg, _FILEINFO_);
120  }
121  }
122 
123  // Get the total available resolution levels and set the effective
124  // resolution and image region
125  p_highestResLevel = JPEG2000_Codestream->get_min_dwt_levels() + 1;
126  SetResolutionAndRegion();
127 
128  // Initialize the JP2 decoder
129  // Initialize the codestream stripe decompressor
130  p_decompressor.start(*JPEG2000_Codestream);
131 
132  // Determine optimum stripe heights for accessing data - the
133  // optimum stripe heights are ignored. We are instead reading
134  // the file a line at a time.
135  p_stripeHeights = new int[p_numBands];
136  p_maxStripeHeights = new int[p_numBands];
137  p_precisions = new int[p_numBands];
138  p_isSigned = new bool[p_numBands];
139  p_decompressor.get_recommended_stripe_heights(MIN_STRIPE_HEIGHT,
140  MAX_STRIPE_HEIGHT, p_stripeHeights, p_maxStripeHeights);
141  for(unsigned int i = 0; i < p_numBands; i++) {
142  p_precisions[i] = p_pixelBits;
143  p_stripeHeights[i] = 1;
144  p_isSigned[i] = p_signedData;
145  }
146  }
147 #endif
148  }
149 
155  void JP2Decoder::SetResolutionAndRegion() {
156 #if ENABLEJP2K
157  // Determine size of image at requested resolution and reset requested image
158  // area if it falls outside of image boundaries
159  JPEG2000_Codestream->apply_input_restrictions(0, 0, p_resolutionLevel - 1, 0, NULL,
160  KDU_WANT_OUTPUT_COMPONENTS);
161 
162  JPEG2000_Codestream->get_dims(0, p_imageDims, true);
163  p_numSamples = p_imageDims.size.x;
164  p_numLines = p_imageDims.size.y;
165 #endif
166  }
167 
178  void JP2Decoder::Read(unsigned char **inbuf) {
179 #if ENABLEJP2K
180  p_readStripes = p_decompressor.pull_stripe(inbuf, p_stripeHeights, NULL, NULL,
181  p_precisions);
182 #endif
183  }
184 
195  void JP2Decoder::Read(short int **inbuf) {
196 #if ENABLEJP2K
197  p_readStripes = p_decompressor.pull_stripe(inbuf, p_stripeHeights, NULL, NULL,
198  p_precisions, p_isSigned);
199 #endif
200  }
201 
206  JP2Decoder::~JP2Decoder() {
207 #if ENABLEJP2K
208  if(JPEG2000_Codestream) JPEG2000_Codestream->destroy();
209  JPEG2000_Codestream = NULL;
210  if(JP2_Source) {
211  JP2_Source->close();
212  delete JP2_Source;
213  }
214  JP2_Source = NULL;
215  if(JP2_Stream) {
216  JP2_Stream->close();
217  delete JP2_Stream;
218  }
219  JP2_Stream = NULL;
220  p_decompressor.finish();
221  if(Kakadu_Error) {
222  delete Kakadu_Error;
223  }
224  delete [] p_stripeHeights;
225  delete [] p_maxStripeHeights;
226  delete [] p_precisions;
227  delete [] p_isSigned;
228 #endif
229  }
230 
231 
232  bool JP2Decoder::IsJP2(QString filename) {
233 #if ENABLEJP2K
234  jp2_family_src *stream = new jp2_family_src();
235  stream->open(filename.toLatin1().data());
236  jp2_source *source = new jp2_source();
237 
238  bool result = source->open(stream);
239 
240  source->close();
241  delete source;
242 
243  stream->close();
244  delete stream;
245 
246  return result;
247 #else
248  return (false);
249 #endif
250  }
251 }
Kakadu error messaging class.
Definition: JP2Error.h:52
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
Isis exception class.
Definition: IException.h:99

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:21:19