00001 
00015 #include "jp2k_tool.h"
00016 #include "jbxl_state.h"
00017 
00018 
00019 #ifdef  ENABLE_OPENJPEG
00020 
00021 #if OPENJPEG_VER >= JP2K_VER_20
00022 
00023 
00024 void  init_jp2k(JP2KImage* jp)
00025 {
00026     if (jp==NULL) return;
00027     
00028     jp->xs    = 0;
00029     jp->ys    = 0;
00030     jp->ws    = 0;
00031     jp->hs    = 0;
00032     jp->col   = 0;
00033     jp->cmode = GRAPH_COLOR_RGBA;
00034     jp->state = JBXL_NORMAL;
00035     jp->image = NULL;
00036 }
00037 
00038 
00039 
00040 void  free_jp2k(JP2KImage* jp)
00041 {
00042     if (jp==NULL) return;
00043     
00044     if (jp->image!=NULL) {
00045         opj_image_destroy(jp->image);
00046     }
00047     init_jp2k(jp);
00048 }
00049 
00050 
00051 
00052 void  setup_jp2k(JP2KImage* jp)
00053 {
00054     if (jp==NULL || jp->image==NULL || jp->image->comps==NULL) return;
00055     
00056     jp->xs = jp->image->x1 - jp->image->x0;
00057     jp->ys = jp->image->y1 - jp->image->y0;
00058 
00059     int fac = (int)jp->image->comps->factor;
00060     jp->ws = (jp->xs + (1<<fac) - 1)>>fac;
00061     jp->hs = (jp->ys + (1<<fac) - 1)>>fac;
00062 
00063     jp->col = (int)jp->image->numcomps;
00064     if (jp->image->color_space==OPJ_CLRSPC_SRGB) {
00065         jp->col = 3;
00066     }
00067     else if (jp->image->color_space==OPJ_CLRSPC_GRAY) {
00068         jp->col = 1;
00069     }
00070 
00071 
00072 
00073 
00074 
00075     
00076     jp->cmode = GRAPH_COLOR_UNKNOWN;
00077     int depth = (int)jp->image->comps->bpp;
00078     if (depth==0) {
00079         if      (jp->col==3) jp->cmode = GRAPH_COLOR_RGB;
00080         else if (jp->col==4) jp->cmode = GRAPH_COLOR_RGBA;
00081     }
00082     else if (depth==32) {
00083         if      (jp->col==3) jp->cmode = GRAPH_COLOR_RGB;
00084         else if (jp->col==4) jp->cmode = GRAPH_COLOR_RGBA;
00085     }
00086     else if (depth==24) {
00087         if      (jp->col==3) jp->cmode = GRAPH_COLOR_RGB;
00088     }
00089     else if (depth==16) {
00090         if      (jp->col==1) jp->cmode = GRAPH_COLOR_MONO16;
00091         else if (jp->col==3) jp->cmode = GRAPH_COLOR_RGB16;
00092         else if (jp->col==4) jp->cmode = GRAPH_COLOR_RGBA16;
00093     }
00094     else if (depth==8) {
00095         if      (jp->col==1) jp->cmode = GRAPH_COLOR_MONO;
00096     }
00097 }
00098 
00099 
00100 
00108 int  get_jp2k_format(uByte* buf)
00109 {
00110     int format = JP2K_FMT_NONE;
00111 
00112     if (!memcmp(buf, JP2K_MAGIC_RFC3745_JP2, 12) || !memcmp(buf, JP2K_MAGIC_JP2, 4)) {
00113         format = JP2K_FMT_JP2;
00114     }
00115     else if (!memcmp(buf, JP2K_MAGIC_J2K, 4)) {
00116         format = JP2K_FMT_J2K;
00117     }
00118     return format;
00119 }
00120 
00121 
00122 
00123 JP2KImage  read_jp2k_file(const char* fname)
00124 {
00125     unsigned char head[12];
00126     JP2KImage jp;
00127     size_t rs;
00128     UNUSED(rs);
00129 
00130     init_jp2k(&jp);
00131     
00132     if (fname==NULL) {
00133         jp.state = JBXL_GRAPH_IVDARG_ERROR;
00134         return jp;
00135     }
00136 
00137     FILE* fp = fopen(fname, "rb");
00138     if (fp==NULL) {
00139         jp.state = JBXL_GRAPH_OPFILE_ERROR;
00140         return jp;
00141     }
00142 
00143     rs = fread(head, 12, 1, fp);
00144     fseek(fp, 0, 0);
00145     int format = get_jp2k_format(head);
00146     if (format==JP2K_FMT_NONE) format = JP2K_FMT_JPT;
00147 
00148 #if OPENJPEG_VER < JP2K_VER_21
00149     jp = read_jp2k_data(fp, format);
00150     fclose(fp);
00151 #else
00152     fclose(fp);
00153     jp = read_jp2k_data(fname, format);
00154 #endif
00155 
00156     return jp;
00157 }
00158 
00159 
00160 
00161 #if OPENJPEG_VER < JP2K_VER_21
00162 JP2KImage  read_jp2k_data(FILE* fp, int format)
00163 #else
00164 JP2KImage  read_jp2k_data(const char* fname, int format)
00165 #endif
00166 {
00167     JP2KImage jp;
00168     init_jp2k(&jp);
00169 
00170     opj_stream_t* stream = NULL;
00171     opj_codec_t*  codec  = NULL;
00172 
00173     opj_dparameters_t parameters;   
00174     opj_set_default_decoder_parameters(¶meters);
00175 
00176 #if OPENJPEG_VER < JP2K_VER_21
00177     stream = opj_stream_create_default_file_stream(fp, 1);      
00178 #else
00179     stream = opj_stream_create_default_file_stream(fname, 1);   
00180 #endif
00181 
00182     if (stream==NULL){
00183         jp.state = JBXL_GRAPH_RDFILE_ERROR;
00184         return jp;
00185     }
00186 
00187     if (format==JP2K_FMT_J2K) {         
00188         codec = opj_create_decompress(OPJ_CODEC_J2K);
00189     }   
00190     else if (format==JP2K_FMT_JP2) {    
00191         codec = opj_create_decompress(OPJ_CODEC_JP2);
00192     }
00193     else if (format==JP2K_FMT_JPT) {    
00194         codec = opj_create_decompress(OPJ_CODEC_JPT);
00195     }
00196     else {
00197         PRINT_MESG("JBXL::readJPEG2KData: ERROR: unknown file format!\n");
00198         opj_stream_destroy(stream);
00199         return jp;
00200     }
00201 
00202     if (!opj_setup_decoder(codec, ¶meters) ){
00203         opj_stream_destroy(stream);
00204         opj_destroy_codec(codec);
00205         jp.state = JBXL_GRAPH_ERROR;
00206         return jp;
00207     }
00208     if (!opj_read_header(stream, codec, &jp.image)){
00209         opj_stream_destroy(stream);
00210         opj_destroy_codec(codec);
00211         jp.state = JBXL_GRAPH_ERROR;
00212         return jp;
00213     }
00214     if (!opj_set_decode_area(codec, jp.image, 0, 0, 0, 0)){
00215         opj_stream_destroy(stream);
00216         opj_destroy_codec(codec);
00217         free_jp2k(&jp);
00218         jp.state = JBXL_GRAPH_ERROR;
00219         return jp;
00220     }
00221     if (!(opj_decode(codec, stream, jp.image) && opj_end_decompress(codec, stream))) {
00222         opj_destroy_codec(codec);
00223         opj_stream_destroy(stream);
00224         free_jp2k(&jp);
00225         jp.state = JBXL_GRAPH_ERROR;
00226         return jp;
00227     }
00228 
00229     setup_jp2k(&jp);
00230 
00231     opj_stream_destroy(stream);
00232     opj_destroy_codec(codec);
00233 
00234     return jp;
00235 }
00236 
00237 
00238 
00239 BSGraph  jp2k_toBSGraph(JP2KImage jp)
00240 {
00241     BSGraph vp;
00242     int i, j, k, yp, yz, zp;
00243 
00244     memset(&vp, 0, sizeof(BSGraph));
00245     if (jp.image==NULL || jp.image->comps==NULL) {
00246         vp.state = JBXL_GRAPH_NODATA_ERROR;
00247         return vp;
00248     }
00249 
00250     vp = make_BSGraph(jp.ws, jp.hs, jp.col);
00251     if (vp.gp==NULL) return vp;
00252 
00253     for (k=0; k<jp.col; k++) {
00254         zp = k*jp.ws*jp.hs;
00255         for (j=0; j<jp.hs; j++) {
00256             yp = j*jp.xs;
00257             yz = j*jp.ws + zp;
00258             for (i=0; i<jp.ws; i++) {
00259                 vp.gp[yz + i] = (uByte)jp.image->comps[k].data[yp + i];  
00260             }
00261         }
00262     }
00263 
00264     return vp;
00265 }
00266 
00267 
00268 #endif      // OPENJPEG_VER >= JP2K_VER_20
00269 #endif      // ENABLE_OPENJPEG
00270