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