12 #include "IException.h"
14 #include "JP2Encoder.h"
20 using namespace kdu_core;
21 using namespace kdu_supp;
36 JP2Encoder::JP2Encoder(
const QString &jp2file,
const unsigned int nsamps,
37 const unsigned int nlines,
const unsigned int nbands,
42 p_sampleDimension = nsamps;
43 p_lineDimension = nlines;
44 p_bandDimension = nbands;
46 if(p_sampleDimension == 0 || p_lineDimension == 0 || p_bandDimension == 0) {
47 string msg =
"Invalid sample/line/band dimensions specified for output file";
48 throw IException(IException::Programmer, msg, _FILEINFO_);
51 if(type == Isis::SignedWord) {
56 else if(type == Isis::UnsignedWord) {
61 else if(type == Isis::UnsignedByte) {
67 string msg =
"Invalid pixel type specified for output file";
68 throw IException(IException::Programmer, msg, _FILEINFO_);
74 p_resolutionLevels = 1;
76 (p_sampleDimension > p_lineDimension) ? p_lineDimension : p_sampleDimension;
77 while(mindim > 64 && p_resolutionLevels < 32) {
83 p_precinctSize.resize(p_resolutionLevels, 256);
89 p_progressionOrder =
"PCRL";
91 p_tileSizeWidth = p_sampleDimension;
92 p_tileSizeHeight = p_lineDimension;
96 kdu_customize_errors(Kakadu_Error);
98 std::string msg =
"JPEG2000 has not been enabled with this build of ISIS3";
99 throw IException(IException::Programmer, msg, _FILEINFO_);
108 void JP2Encoder::OpenFile() {
111 JP2_Stream =
new jp2_family_tgt();
112 JP2_Stream->open(p_jp2File.toLatin1().data());
115 JP2_Boxes =
new jp2_target();
116 JP2_Boxes->open(JP2_Stream);
126 siz_params *codestream_parameters =
new siz_params();
127 codestream_parameters->set(Sdims, 0, 0, (
int)p_lineDimension);
128 codestream_parameters->set(Sdims, 0, 1, (
int)p_sampleDimension);
129 codestream_parameters->set(Sprecision, 0, 0, (
int)p_pixelBits);
130 codestream_parameters->set(Stiles, 0, 0, (
int)p_tileSizeHeight);
131 codestream_parameters->set(Stiles, 0, 1, (
int)p_tileSizeWidth);
132 codestream_parameters->set(Ssigned, 0, 0, p_signedData);
133 codestream_parameters->set(Scomponents, 0, 0, (
int)p_bandDimension);
134 ostringstream levels;
135 levels <<
"Clevels=" << (p_resolutionLevels - 1);
136 codestream_parameters->parse_string(levels.str().c_str());
137 codestream_parameters->parse_string(
"Creversible=yes");
138 string progression =
"Corder=" + p_progressionOrder;
139 codestream_parameters->parse_string(progression.c_str());
150 int p_flushLines = 0;
151 long long line_bytes = (
long long)p_sampleDimension * p_pixelBytes;
152 if(INCREMENTAL_FLUSH_BYTES < (p_lineDimension * line_bytes)) {
153 p_flushLines = p_tileSizeHeight;
154 while((p_flushLines * line_bytes) > INCREMENTAL_FLUSH_BYTES) {
155 p_flushLines -= 1024;
156 if(p_flushLines < 0) p_flushLines = 0;
160 TLM_segments = (int)(((
double)p_tileSizeHeight / (double)p_flushLines) + 0.5);
161 if(!TLM_segments) TLM_segments = 1;
167 ostringstream segments;
168 segments <<
"ORGgen_tlm=" << TLM_segments;
169 codestream_parameters->parse_string(segments.str().c_str());
172 codestream_parameters->parse_string(
"ORGgen_plt=yes");
175 codestream_parameters->finalize_all();
178 JPEG2000_Codestream =
new kdu_codestream();
179 JPEG2000_Codestream->create(codestream_parameters, JP2_Boxes);
184 codestream_parameters = JPEG2000_Codestream->access_siz();
185 codestream_parameters->parse_string(levels.str().c_str());
186 codestream_parameters->parse_string(
"Creversible=yes");
187 codestream_parameters->parse_string(progression.c_str());
188 codestream_parameters->parse_string(segments.str().c_str());
189 codestream_parameters->parse_string(
"ORGgen_plt=yes");
194 sizes <<
"Cprecincts=";
195 for(
unsigned int i = 0; i < p_precinctSize.size(); i++) {
196 if(i != 0) sizes <<
",";
197 sizes <<
"{" << p_precinctSize[i] <<
"," << p_precinctSize[i] <<
"}";
199 codestream_parameters->parse_string(sizes.str().c_str());
204 size <<
"Cblk={" << p_codeBlockSize <<
"," << p_codeBlockSize <<
"}";
205 codestream_parameters->parse_string(size.str().c_str());
207 codestream_parameters->finalize_all();
210 jp2_dimensions dimensions = JP2_Boxes->access_dimensions();
211 dimensions.init(codestream_parameters);
212 dimensions.finalize_compatibility(codestream_parameters);
215 jp2_colour colour = JP2_Boxes->access_colour();
216 colour.init((p_bandDimension >= 3) ? JP2_sRGB_SPACE : JP2_sLUM_SPACE);
219 JP2_Boxes->write_header();
223 JP2_Boxes->open_codestream();
227 kdu_params *COD = JPEG2000_Codestream->access_siz()->access_cluster(COD_params);
228 if(!(COD->get(Clayers, 0, 0, layers) && (layers > 0)))
229 COD->set(Clayers, 0, 0, layers = 1);
230 kdu_long *layer_sizes =
new kdu_long[layers];
231 memset(layer_sizes, 0,
sizeof(kdu_long)*layers);
234 p_compressor.start(*JPEG2000_Codestream, layers, layer_sizes, NULL, 0,
false,
238 p_stripeHeights =
new int[p_bandDimension];
239 p_maxStripeHeights =
new int[p_bandDimension];
240 p_precisions =
new int[p_bandDimension];
241 p_isSigned =
new bool[p_bandDimension];
242 p_compressor.get_recommended_stripe_heights(MIN_STRIPE_HEIGHT,
243 MAX_STRIPE_HEIGHT, p_stripeHeights, p_maxStripeHeights);
244 for(
unsigned int i = 0; i < p_bandDimension; i++) {
245 p_precisions[i] = p_pixelBits;
246 p_isSigned[i] = p_signedData;
247 p_stripeHeights[i] = 1;
260 void JP2Encoder::Write(
unsigned char **inbuf) {
262 p_writeStripes = p_compressor.push_stripe(inbuf, p_stripeHeights, NULL, NULL,
263 p_precisions, p_flushLines);
275 void JP2Encoder::Write(
short int **inbuf) {
277 p_writeStripes = p_compressor.push_stripe(inbuf, p_stripeHeights, NULL, NULL,
278 p_precisions, p_isSigned, p_flushLines);
286 JP2Encoder::~JP2Encoder() {
288 p_compressor.finish();
289 JPEG2000_Codestream->destroy();
292 delete [] p_stripeHeights;
293 delete [] p_maxStripeHeights;
294 delete [] p_precisions;
295 delete [] p_isSigned;