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