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