00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "gdcmFileHelper.h"
00019 #include "gdcmDebug.h"
00020
00021 #include <iostream>
00022 #include <fstream>
00023
00024 #if defined(__BORLANDC__)
00025 #include <mem.h>
00026 #endif
00027
00028 extern "C" {
00029 #include <openjpeg.h>
00030
00034 void error_callback(const char *msg, void *) {
00035 std::cerr << "Error in gdcmopenjpeg" << msg << std::endl;
00036 }
00040 void warning_callback(const char *msg, void *) {
00041 std::cerr << "Warning in gdcmopenjpeg" << msg << std::endl;
00042 }
00046 void info_callback(const char *msg, void *) {
00047 std::cerr << "Info in gdcmopenjpeg" << msg << std::endl;
00048 }
00049 }
00050
00051 namespace GDCM_NAME_SPACE
00052 {
00053
00065 void error_callback(const char *msg, void *) {
00066 std::cerr << "Error in gdcmopenjpeg" << msg << std::endl;
00067 }
00071 void warning_callback(const char *msg, void *) {
00072 std::cerr << "Warning in gdcmopenjpeg" << msg << std::endl;
00073 }
00077 void info_callback(const char *msg, void *) {
00078 std::cerr << "Info in gdcmopenjpeg" << msg << std::endl;
00079 }
00080
00081 #define J2K_CFMT 0
00082 #define JP2_CFMT 1
00083 #define JPT_CFMT 2
00084 #define MJ2_CFMT 3
00085 #define PXM_DFMT 0
00086 #define PGX_DFMT 1
00087 #define BMP_DFMT 2
00088 #define YUV_DFMT 3
00089
00090
00091
00092
00093
00094
00095 inline int int_ceildivpow2(int a, int b) {
00096 return (a + (1 << b) - 1) >> b;
00097 }
00098
00099
00100
00101
00102 bool gdcm_read_JPEG2000_file (void* raw, char *inputdata, size_t inputlength)
00103 {
00104 opj_dparameters_t parameters;
00105 opj_event_mgr_t event_mgr;
00106 opj_image_t *image;
00107 opj_dinfo_t* dinfo;
00108 opj_cio_t *cio;
00109 unsigned char *src = (unsigned char*)inputdata;
00110 int file_length = static_cast< int >( inputlength );
00111
00112
00113 memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
00114 event_mgr.error_handler = error_callback;
00115 event_mgr.warning_handler = warning_callback;
00116 event_mgr.info_handler = info_callback;
00117
00118
00119 opj_set_default_decoder_parameters(¶meters);
00120
00121
00122 parameters.cp_layer=0;
00123 parameters.cp_reduce=0;
00124
00125
00126
00127
00128 parameters.decod_format = J2K_CFMT;
00129 assert(parameters.decod_format == J2K_CFMT);
00130 parameters.cod_format = PGX_DFMT;
00131 assert(parameters.cod_format == PGX_DFMT);
00132
00133
00134 dinfo = opj_create_decompress(CODEC_J2K);
00135
00136
00137 opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, NULL);
00138
00139
00140 opj_setup_decoder(dinfo, ¶meters);
00141
00142
00143 cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
00144
00145
00146 image = opj_decode(dinfo, cio);
00147 if(!image) {
00148 opj_destroy_decompress(dinfo);
00149 opj_cio_close(cio);
00150 return 1;
00151 }
00152
00153
00154 opj_cio_close(cio);
00155
00156
00157 delete[] src;
00158
00159
00160 for (int compno = 0; compno < image->numcomps; compno++)
00161 {
00162 opj_image_comp_t *comp = &image->comps[compno];
00163
00164 int w = image->comps[compno].w;
00165 int wr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor);
00166
00167
00168 int hr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor);
00169
00170 if (comp->prec <= 8)
00171 {
00172 uint8_t *data8 = (uint8_t*)raw + compno;
00173 for (int i = 0; i < wr * hr; i++)
00174 {
00175 int v = image->comps[compno].data[i / wr * w + i % wr];
00176 *data8 = (uint8_t)v;
00177 data8 += image->numcomps;
00178 }
00179 }
00180 else if (comp->prec <= 16)
00181 {
00182 uint16_t *data16 = (uint16_t*)raw + compno;
00183 for (int i = 0; i < wr * hr; i++)
00184 {
00185 int v = image->comps[compno].data[i / wr * w + i % wr];
00186 *data16 = (uint16_t)v;
00187 data16 += image->numcomps;
00188 }
00189 }
00190 else
00191 {
00192 uint32_t *data32 = (uint32_t*)raw + compno;
00193 for (int i = 0; i < wr * hr; i++)
00194 {
00195 int v = image->comps[compno].data[i / wr * w + i % wr];
00196 *data32 = (uint32_t)v;
00197 data32 += image->numcomps;
00198 }
00199 }
00200
00201 }
00202
00203
00204
00205 if(dinfo) {
00206 opj_destroy_decompress(dinfo);
00207 }
00208
00209
00210 opj_image_destroy(image);
00211
00212 return true;
00213 }
00214
00215 template<typename T>
00216 void rawtoimage_fill(T *inputbuffer, int w, int h, int numcomps, opj_image_t *image)
00217 {
00218 T *p = inputbuffer;
00219 for (int i = 0; i < w * h; i++)
00220 {
00221 for(int compno = 0; compno < numcomps; compno++)
00222 {
00223
00224 image->comps[compno].data[i] = *p;
00225 ++p;
00226 }
00227 }
00228 }
00229
00230 opj_image_t* rawtoimage(char *inputbuffer, opj_cparameters_t *parameters,
00231 int fragment_size, int image_width, int image_height, int sample_pixel,
00232 int bitsallocated, int sign, int quality)
00233 {
00234 (void)quality;
00235 (void)fragment_size;
00236 int w, h;
00237 int numcomps;
00238 OPJ_COLOR_SPACE color_space;
00239 opj_image_cmptparm_t cmptparm[3];
00240 opj_image_t * image = NULL;
00241
00242 assert( sample_pixel == 1 || sample_pixel == 3 );
00243 if( sample_pixel == 1 )
00244 {
00245 numcomps = 1;
00246 color_space = CLRSPC_GRAY;
00247 }
00248 else
00249 {
00250 numcomps = 3;
00251 color_space = CLRSPC_SRGB;
00252 }
00253 int subsampling_dx = parameters->subsampling_dx;
00254 int subsampling_dy = parameters->subsampling_dy;
00255
00256
00257 w = image_width;
00258 h = image_height;
00259
00260
00261 memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
00262
00263 for(int i = 0; i < numcomps; i++) {
00264 cmptparm[i].prec = bitsallocated;
00265 cmptparm[i].bpp = bitsallocated;
00266 cmptparm[i].sgnd = sign;
00267 cmptparm[i].dx = subsampling_dx;
00268 cmptparm[i].dy = subsampling_dy;
00269 cmptparm[i].w = w;
00270 cmptparm[i].h = h;
00271 }
00272
00273
00274 image = opj_image_create(numcomps, &cmptparm[0], color_space);
00275 if(!image) {
00276 return NULL;
00277 }
00278
00279 image->x0 = parameters->image_offset_x0;
00280 image->y0 = parameters->image_offset_y0;
00281 image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1;
00282 image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1;
00283
00284
00285
00286
00287 if (bitsallocated <= 8)
00288 {
00289 if( sign )
00290 {
00291 rawtoimage_fill<int8_t>((int8_t*)inputbuffer,w,h,numcomps,image);
00292 }
00293 else
00294 {
00295 rawtoimage_fill<uint8_t>((uint8_t*)inputbuffer,w,h,numcomps,image);
00296 }
00297 }
00298 else if (bitsallocated <= 16)
00299 {
00300 if( sign )
00301 {
00302 rawtoimage_fill<int16_t>((int16_t*)inputbuffer,w,h,numcomps,image);
00303 }
00304 else
00305 {
00306 rawtoimage_fill<uint16_t>((uint16_t*)inputbuffer,w,h,numcomps,image);
00307 }
00308 }
00309 else if (bitsallocated <= 32)
00310 {
00311 if( sign )
00312 {
00313 rawtoimage_fill<int32_t>((int32_t*)inputbuffer,w,h,numcomps,image);
00314 }
00315 else
00316 {
00317 rawtoimage_fill<uint32_t>((uint32_t*)inputbuffer,w,h,numcomps,image);
00318 }
00319 }
00320 else
00321 {
00322 abort();
00323 }
00324
00325 return image;
00326 }
00327
00328
00329
00330
00331 bool gdcm_write_JPEG2000_file (std::ostream *fp, char *inputdata, size_t inputlength,
00332 int image_width, int image_height, int numZ, int sample_pixel, int bitsallocated,
00333 int sign, int quality)
00334 {
00337 (void)numZ;
00338 bool bSuccess;
00339
00340 opj_cparameters_t parameters;
00341 opj_event_mgr_t event_mgr;
00342 opj_image_t *image = NULL;
00343
00344
00345
00346
00347
00348
00349 memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
00350 event_mgr.error_handler = error_callback;
00351 event_mgr.warning_handler = warning_callback;
00352 event_mgr.info_handler = info_callback;
00353
00354
00355 memset(¶meters, 0, sizeof(parameters));
00356 opj_set_default_encoder_parameters(¶meters);
00357
00358
00359 parameters.tcp_rates[0] = 0;
00360 parameters.tcp_numlayers = 1;
00361 parameters.cp_disto_alloc = 1;
00362
00363 if(parameters.cp_comment == NULL) {
00364 const char comment[] = "Created by GDCM/OpenJPEG version 1.0";
00365 parameters.cp_comment = (char*)malloc(strlen(comment) + 1);
00366 strcpy(parameters.cp_comment, comment);
00367
00368
00369 }
00370
00371
00372
00373
00374
00375 image = rawtoimage((char*)inputdata, ¶meters,
00376 static_cast<int>( inputlength ),
00377 image_width, image_height,
00378 sample_pixel, bitsallocated, sign, quality);
00379 if (!image) {
00380 return 1;
00381 }
00382
00383
00384
00385 parameters.cod_format = J2K_CFMT;
00386 int codestream_length;
00387 opj_cio_t *cio = NULL;
00388
00389
00390
00391 opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K);
00392
00393
00394 opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
00395
00396
00397 opj_setup_encoder(cinfo, ¶meters, image);
00398
00399
00400
00401 cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
00402
00403
00404 bSuccess = opj_encode(cinfo, cio, image, parameters.index);
00405 if (!bSuccess) {
00406 opj_cio_close(cio);
00407 fprintf(stderr, "failed to encode image\n");
00408 return 1;
00409 }
00410 codestream_length = cio_tell(cio);
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 #ifdef MDEBUG
00421 static int c = 0;
00422 std::ostringstream os;
00423 os << "/tmp/debug";
00424 os << c;
00425 c++;
00426 os << ".j2k";
00427 std::ofstream debug(os.str().c_str());
00428 debug.write((char*)(cio->buffer), codestream_length);
00429 debug.close();
00430 #endif
00431 fp->write((char*)(cio->buffer), codestream_length);
00432
00433
00434
00435 opj_cio_close(cio);
00436
00437
00438 opj_destroy_compress(cinfo);
00439
00440
00441
00442
00443 if(parameters.cp_comment) free(parameters.cp_comment);
00444
00445 if(parameters.cp_matrice) free(parameters.cp_matrice);
00446
00447
00448 opj_image_destroy(image);
00449
00450
00451
00452
00453 return true;
00454 }
00455
00456 #if 0
00457
00458 bool gdcm_read_JPEG2000_file (void* raw, char *inputdata, size_t inputlength)
00459 {
00460 j2k_image_t img;
00461 j2k_cp_t cp;
00462
00463
00464 cp.layer=0;
00465 cp.reduce=0;
00466 cp.decod_format=-1;
00467 cp.cod_format=-1;
00468
00469 cp.cod_format=J2K_CFMT;
00470 cp.decod_format = PGX_DFMT;
00471 int len = inputlength;
00472 unsigned char *src = (unsigned char*)inputdata;
00473
00474
00475 if (!j2k_decode(src, len, &img, &cp))
00476 {
00477 gdcmStaticErrorMacro( "ERROR -> j2k_to_image: failed to decode image!" );
00478 return false;
00479 }
00480
00481
00482 for (int compno = 0; compno < img.numcomps; compno++)
00483 {
00484 j2k_comp_t *comp = &img.comps[compno];
00485
00486 int w = img.comps[compno].w;
00487 int wr = int_ceildivpow2(img.comps[compno].w, img.comps[compno].factor);
00488
00489
00490 int hr = int_ceildivpow2(img.comps[compno].h, img.comps[compno].factor);
00491
00492 if (comp->prec <= 8)
00493 {
00494 uint8_t *data8 = (uint8_t*)raw;
00495 for (int i = 0; i < wr * hr; i++)
00496 {
00497 int v = img.comps[compno].data[i / wr * w + i % wr];
00498 *data8++ = (uint8_t)v;
00499 }
00500 }
00501 else if (comp->prec <= 16)
00502 {
00503 uint16_t *data16 = (uint16_t*)raw;
00504 for (int i = 0; i < wr * hr; i++)
00505 {
00506 int v = img.comps[compno].data[i / wr * w + i % wr];
00507 *data16++ = (uint16_t)v;
00508 }
00509 }
00510 else
00511 {
00512 uint32_t *data32 = (uint32_t*)raw;
00513 for (int i = 0; i < wr * hr; i++)
00514 {
00515 int v = img.comps[compno].data[i / wr * w + i % wr];
00516 *data32++ = (uint32_t)v;
00517 }
00518 }
00519 free(img.comps[compno].data);
00520 }
00521
00522
00523 j2k_dec_release();
00524
00525 delete[] inputdata;
00526
00527 return true;
00528 }
00529 #endif
00530
00531 #if 0
00532 bool gdcm_read_JASPER_file (void* raw, char *inputdata, size_t inputlength)
00533 {
00534 #if 0
00535 std::cerr << "Inputlenght=" << inputlength << std::endl;
00536 std::ofstream out("/tmp/jpeg2000.jpc", std::ios::binary);
00537 out.write((char*)inputdata,inputlength);
00538 out.close();
00539 #endif
00540 jas_init();
00541 jas_stream_t *jasStream =
00542 jas_stream_memopen((char *)inputdata, inputlength);
00543
00544 int fmtid;
00545 if ((fmtid = jas_image_getfmt(jasStream)) < 0)
00546 {
00547 gdcmErrorMacro("unknown image format");
00548 return false;
00549 }
00550
00551
00552 jas_image_t *jasImage ;
00553 if (!(jasImage = jas_image_decode(jasStream, fmtid, 0)))
00554 {
00555 gdcmErrorMacro("cannot decode image");
00556 return false;
00557 }
00558
00559
00560 jas_stream_close(jasStream);
00561 int numcmpts = jas_image_numcmpts(jasImage);
00562 int width = jas_image_cmptwidth(jasImage, 0);
00563 int height = jas_image_cmptheight(jasImage, 0);
00564 int prec = jas_image_cmptprec(jasImage, 0);
00565 int i, j, k;
00566
00567
00568
00569
00570 if (prec == 8)
00571 {
00572 uint8_t *data8 = (uint8_t*)raw;
00573 for ( i = 0; i < height; i++)
00574 for ( j = 0; j < width; j++)
00575 for ( k= 0; k < numcmpts; k++)
00576 *data8++ = (uint8_t)(jas_image_readcmptsample(jasImage, k, j ,i ));
00577 }
00578 else if (prec <= 16)
00579 {
00580 uint16_t *data16 = (uint16_t*)raw;
00581 for ( i = 0; i < height; i++)
00582 for ( j = 0; j < width; j++)
00583 for ( k= 0; k < numcmpts; k++)
00584 *data16++ = (uint16_t)(jas_image_readcmptsample(jasImage, k, j ,i ));
00585 }
00586 else if (prec <= 32)
00587 {
00588 uint32_t *data32 = (uint32_t*)raw;
00589 for ( i = 0; i < height; i++)
00590 for ( j = 0; j < width; j++)
00591 for ( k= 0; k < numcmpts; k++)
00592 *data32++ = (uint32_t)(jas_image_readcmptsample(jasImage, k, j ,i ));
00593 }
00594
00595 jas_image_destroy(jasImage);
00596 jas_image_clearfmts();
00597
00598
00599
00600 #if 0
00601 std::ofstream rawout("/tmp/jpeg2000.raw");
00602 rawout.write((char*)raw,height*width*numcmpts*((prec+4)/8));
00603 rawout.close();
00604 #endif
00605 delete[] inputdata;
00606
00607 return true;
00608 }
00609 #endif
00610
00611
00612 }
00613