1 /*=========================================================================
4 Module: $RCSfile: gdcmJpeg2000.cxx,v $
6 Date: $Date: 2006/01/27 10:01:34 $
7 Version: $Revision: 1.40 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See Doc/License.txt or
11 http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
18 #include "gdcmFileHelper.h"
19 #include "gdcmDebug.h"
24 #if defined(__BORLANDC__)
25 #include <mem.h> // for memset
34 //-----------------------------------------------------------------------------
36 * \brief routine for JPEG decompression
38 * @param inputdata inputdata
39 * @param inputlength inputlength
40 * @return 1 on success, 0 on error
44 sample error callback expecting a FILE* client object
46 void error_callback(const char *msg, void *) {
47 std::cerr << "Error in gdcmopenjpeg" << msg << std::endl;
50 sample warning callback expecting a FILE* client object
52 void warning_callback(const char *msg, void *) {
53 std::cerr << "Warning in gdcmopenjpeg" << msg << std::endl;
56 sample debug callback expecting no client object
58 void info_callback(const char *msg, void *) {
59 std::cerr << "Info in gdcmopenjpeg" << msg << std::endl;
72 * Divide an integer by a power of 2 and round upwards.
76 inline int int_ceildivpow2(int a, int b) {
77 return (a + (1 << b) - 1) >> b;
81 * The following function was copy paste from j2k_to_image.c with part from convert.c
83 bool gdcm_read_JPEG2000_file (void* raw, char *inputdata, size_t inputlength)
85 opj_dparameters_t parameters; /* decompression parameters */
86 opj_event_mgr_t event_mgr; /* event manager */
87 opj_image_t *image = NULL;
88 opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
89 opj_cio_t *cio = NULL;
90 unsigned char *src = (unsigned char*)inputdata;
91 int file_length = inputlength;
93 /* configure the event callbacks (not required) */
94 memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
95 event_mgr.error_handler = error_callback;
96 event_mgr.warning_handler = warning_callback;
97 event_mgr.info_handler = info_callback;
99 /* set decoding parameters to default values */
100 opj_set_default_decoder_parameters(¶meters);
102 // default blindly copied
103 parameters.cp_layer=0;
104 parameters.cp_reduce=0;
105 // parameters.decod_format=-1;
106 // parameters.cod_format=-1;
108 /* JPEG-2000 codestream */
109 parameters.decod_format = J2K_CFMT;
110 assert(parameters.decod_format == J2K_CFMT);
111 parameters.cod_format = PGX_DFMT;
112 assert(parameters.cod_format == PGX_DFMT);
114 /* get a decoder handle */
115 dinfo = opj_create_decompress(CODEC_J2K);
117 /* catch events using our callbacks and give a local context */
118 opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, NULL);
120 /* setup the decoder decoding parameters using user parameters */
121 opj_setup_decoder(dinfo, ¶meters);
123 /* open a byte stream */
124 cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
126 /* decode the stream and fill the image structure */
127 image = opj_decode(dinfo, cio);
129 opj_destroy_decompress(dinfo);
134 /* close the byte stream */
137 /* free the memory containing the code-stream */
138 delete[] src; //FIXME
143 for (int compno = 0; compno < image->numcomps; compno++)
145 opj_image_comp_t *comp = &image->comps[compno];
147 int w = image->comps[compno].w;
148 int wr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor);
150 //int h = image.comps[compno].h;
151 int hr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor);
155 uint8_t *data8 = (uint8_t*)raw;
156 for (int i = 0; i < wr * hr; i++)
158 int v = image->comps[compno].data[i / wr * w + i % wr];
159 *data8++ = (uint8_t)v;
162 else if (comp->prec <= 16)
164 uint16_t *data16 = (uint16_t*)raw;
165 for (int i = 0; i < wr * hr; i++)
167 int v = image->comps[compno].data[i / wr * w + i % wr];
168 *data16++ = (uint16_t)v;
173 uint32_t *data32 = (uint32_t*)raw;
174 for (int i = 0; i < wr * hr; i++)
176 int v = image->comps[compno].data[i / wr * w + i % wr];
177 *data32++ = (uint32_t)v;
180 //free(image.comps[compno].data);
184 /* free remaining structures */
186 opj_destroy_decompress(dinfo);
189 /* free image data structure */
190 opj_image_destroy(image);
197 bool gdcm_read_JPEG2000_file (void* raw, char *inputdata, size_t inputlength)
202 // default blindly copied
208 cp.cod_format=J2K_CFMT;
209 cp.decod_format = PGX_DFMT;
210 int len = inputlength;
211 unsigned char *src = (unsigned char*)inputdata;
214 if (!j2k_decode(src, len, &img, &cp))
216 gdcmStaticErrorMacro( "ERROR -> j2k_to_image: failed to decode image!" );
221 for (int compno = 0; compno < img.numcomps; compno++)
223 j2k_comp_t *comp = &img.comps[compno];
225 int w = img.comps[compno].w;
226 int wr = int_ceildivpow2(img.comps[compno].w, img.comps[compno].factor);
228 //int h = img.comps[compno].h;
229 int hr = int_ceildivpow2(img.comps[compno].h, img.comps[compno].factor);
233 uint8_t *data8 = (uint8_t*)raw;
234 for (int i = 0; i < wr * hr; i++)
236 int v = img.comps[compno].data[i / wr * w + i % wr];
237 *data8++ = (uint8_t)v;
240 else if (comp->prec <= 16)
242 uint16_t *data16 = (uint16_t*)raw;
243 for (int i = 0; i < wr * hr; i++)
245 int v = img.comps[compno].data[i / wr * w + i % wr];
246 *data16++ = (uint16_t)v;
251 uint32_t *data32 = (uint32_t*)raw;
252 for (int i = 0; i < wr * hr; i++)
254 int v = img.comps[compno].data[i / wr * w + i % wr];
255 *data32++ = (uint32_t)v;
258 free(img.comps[compno].data);
261 // Free remaining structures
271 bool gdcm_read_JASPER_file (void* raw, char *inputdata, size_t inputlength)
274 std::cerr << "Inputlenght=" << inputlength << std::endl;
275 std::ofstream out("/tmp/jpeg2000.jpc", std::ios::binary);
276 out.write((char*)inputdata,inputlength);
279 jas_init(); //important...
280 jas_stream_t *jasStream =
281 jas_stream_memopen((char *)inputdata, inputlength);
284 if ((fmtid = jas_image_getfmt(jasStream)) < 0)
286 gdcmErrorMacro("unknown image format");
291 jas_image_t *jasImage /* = NULL*/; // Useless assignation
292 if (!(jasImage = jas_image_decode(jasStream, fmtid, 0)))
294 gdcmErrorMacro("cannot decode image");
299 jas_stream_close(jasStream);
300 int numcmpts = jas_image_numcmpts(jasImage);
301 int width = jas_image_cmptwidth(jasImage, 0);
302 int height = jas_image_cmptheight(jasImage, 0);
303 int prec = jas_image_cmptprec(jasImage, 0);
306 // The following should serioulsy be rewritten I cannot believe we need to
307 // do a per pixel decompression, there should be a way to read a full
311 uint8_t *data8 = (uint8_t*)raw;
312 for ( i = 0; i < height; i++)
313 for ( j = 0; j < width; j++)
314 for ( k= 0; k < numcmpts; k++)
315 *data8++ = (uint8_t)(jas_image_readcmptsample(jasImage, k, j ,i ));
319 uint16_t *data16 = (uint16_t*)raw;
320 for ( i = 0; i < height; i++)
321 for ( j = 0; j < width; j++)
322 for ( k= 0; k < numcmpts; k++)
323 *data16++ = (uint16_t)(jas_image_readcmptsample(jasImage, k, j ,i ));
327 uint32_t *data32 = (uint32_t*)raw;
328 for ( i = 0; i < height; i++)
329 for ( j = 0; j < width; j++)
330 for ( k= 0; k < numcmpts; k++)
331 *data32++ = (uint32_t)(jas_image_readcmptsample(jasImage, k, j ,i ));
334 jas_image_destroy(jasImage);
335 jas_image_clearfmts();
338 //delete the jpeg temp buffer
340 std::ofstream rawout("/tmp/jpeg2000.raw");
341 rawout.write((char*)raw,height*width*numcmpts*((prec+4)/8));
350 //-----------------------------------------------------------------------------
351 } // end namespace gdcm