bool DotNetDecode(MarshalledImage* image) { opj_dparameters dparameters; try { opj_set_default_decoder_parameters(&dparameters); opj_dinfo_t* dinfo = opj_create_decompress(CODEC_J2K); opj_setup_decoder(dinfo, &dparameters); opj_cio* cio = opj_cio_open((opj_common_ptr)dinfo, image->encoded, image->length); opj_image* jp2_image = opj_decode(dinfo, cio); // decode happens here if (jp2_image == NULL) throw "opj_decode failed"; image->width = jp2_image->x1 - jp2_image->x0; image->height = jp2_image->y1 - jp2_image->y0; image->components = jp2_image->numcomps; int n = image->width * image->height; image->decoded = new unsigned char[n * image->components]; for (int i = 0; i < image->components; i++) std::copy(jp2_image->comps[i].data, jp2_image->comps[i].data + n, image->decoded + i * n); opj_image_destroy(jp2_image); opj_destroy_decompress(dinfo); opj_cio_close(cio); return true; } catch (...) { return false; } }
void J2KReader::decode(bool headeronly) { if( !_fileData || !_dataLength ) { BOOST_THROW_EXCEPTION( exception::Bug() << exception::dev( "Need to open the file before decoding." ) ); } opj_dparameters_t parameters; // decompression parameters opj_dinfo_t *dinfo = NULL; // handle to a decompressor opj_cio_t *cio = NULL; _openjpeg.event_mgr.error_handler = NULL; _openjpeg.event_mgr.warning_handler = NULL; _openjpeg.event_mgr.info_handler = NULL; opj_set_default_decoder_parameters(¶meters); if (headeronly) { parameters.cp_limit_decoding = LIMIT_TO_MAIN_HEADER; } // Decompress a JPEG-2000 codestream // get a decoder handle dinfo = opj_create_decompress(CODEC_J2K); // Catch events using our callbacks and give a local context opj_set_event_mgr((opj_common_ptr) dinfo, &_openjpeg.event_mgr, stderr ); // setup the decoder decoding parameters using user parameters opj_setup_decoder(dinfo, ¶meters); if( !dinfo ) { BOOST_THROW_EXCEPTION( exception::Unknown() << exception::dev( "Failed to open decoder for image." ) ); } // open a byte stream cio = opj_cio_open((opj_common_ptr)dinfo, _fileData, _dataLength); if( !cio ) { opj_destroy_decompress( dinfo ); BOOST_THROW_EXCEPTION( exception::Unknown() << exception::dev( "Failed to open decoder for image." ) ); } // Start decoding to get an image if( _openjpeg.image ) { opj_image_destroy( _openjpeg.image ); } _openjpeg.image = opj_decode( dinfo, cio ); // close the byte stream opj_destroy_decompress( dinfo ); opj_cio_close( cio ); if( !_openjpeg.image ) { BOOST_THROW_EXCEPTION( exception::Unknown() << exception::dev( "Failed to decode image." ) ); } }
J2kImage * J2kImageDecoder::getImage( char * data, size_t len ) { opj_image_t *image; opj_cio_t *cio = opj_cio_open((opj_common_ptr)dinfo, reinterpret_cast<unsigned char*>(data), len); image = opj_decode(dinfo, cio); opj_cio_close(cio); return new J2kImage( image ); }
void JPXStream::init2(unsigned char *buf, int bufLen, OPJ_CODEC_FORMAT format) { opj_cio_t *cio = NULL; /* Use default decompression parameters */ opj_dparameters_t parameters; opj_set_default_decoder_parameters(¶meters); /* Configure the event manager to receive errors and warnings */ opj_event_mgr_t event_mgr; memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = libopenjpeg_error_callback; event_mgr.warning_handler = libopenjpeg_warning_callback; /* Get the decoder handle of the format */ dinfo = opj_create_decompress(format); if (dinfo == NULL) goto error; /* Catch events using our callbacks */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, NULL); /* Setup the decoder decoding parameters */ opj_setup_decoder(dinfo, ¶meters); /* Open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, buf, bufLen); if (cio == NULL) goto error; /* Decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); /* Close the byte stream */ opj_cio_close(cio); if (image == NULL) goto error; else return; error: if (format == CODEC_JP2) { error(-1, "Did no succeed opening JPX Stream as JP2, trying as J2K."); init2(buf, bufLen, CODEC_J2K); } else if (format == CODEC_J2K) { error(-1, "Did no succeed opening JPX Stream as J2K, trying as JPT."); init2(buf, bufLen, CODEC_JPT); } else { error(-1, "Did no succeed opening JPX Stream."); } }
JP2KImage read_jp2k_data(unsigned char* data, int len, int format) { JP2KImage jp; init_jp2k(&jp); opj_dinfo_t* codec = NULL; opj_cio_t* stream = NULL; opj_dparameters_t parameters; opj_set_default_decoder_parameters(¶meters); if (format==JP2K_FMT_J2K) { // JPEG 2000 codestream codec = opj_create_decompress(CODEC_J2K); } else if (format==JP2K_FMT_JP2) { // JPEG 2000 compressed image data codec = opj_create_decompress(CODEC_JP2); } else if (format==JP2K_FMT_JPT) { // JPEG 2000 JPIP codec = opj_create_decompress(CODEC_JPT); } else { print_message("JBXL::readJPEG2KData: ERROR: unknown file format!\n"); jp.state = ERROR_GRAPH_NODATA; return jp; } opj_setup_decoder(codec, ¶meters); stream = opj_cio_open((opj_common_ptr)codec, data, len); jp.image = opj_decode(codec, stream); if (jp.image==NULL) { opj_cio_close(stream); opj_destroy_decompress(codec); jp.state = ERROR_GRAPH_IVDDATA; return jp; } setup_jp2k(&jp); opj_cio_close(stream); opj_destroy_decompress(codec); return jp; }
fz_pixmap * fz_load_jpx(fz_context *ctx, unsigned char *data, int size, fz_colorspace *defcs) { fz_pixmap *img; opj_event_mgr_t evtmgr; opj_dparameters_t params; opj_dinfo_t *info; opj_cio_t *cio; opj_image_t *jpx; fz_colorspace *colorspace; unsigned char *p; int format; int a, n, w, h, depth, sgnd; int x, y, k, v; if (size < 2) fz_throw(ctx, "not enough data to determine image format"); /* Check for SOC marker -- if found we have a bare J2K stream */ if (data[0] == 0xFF && data[1] == 0x4F) format = CODEC_J2K; else format = CODEC_JP2; memset(&evtmgr, 0, sizeof(evtmgr)); evtmgr.error_handler = fz_opj_error_callback; evtmgr.warning_handler = fz_opj_warning_callback; evtmgr.info_handler = fz_opj_info_callback; opj_set_default_decoder_parameters(¶ms); info = opj_create_decompress(format); opj_set_event_mgr((opj_common_ptr)info, &evtmgr, ctx); opj_setup_decoder(info, ¶ms); cio = opj_cio_open((opj_common_ptr)info, data, size); jpx = opj_decode(info, cio); opj_cio_close(cio); opj_destroy_decompress(info); if (!jpx) fz_throw(ctx, "opj_decode failed"); for (k = 1; k < jpx->numcomps; k++) { if (jpx->comps[k].w != jpx->comps[0].w) fz_throw(ctx, "image components have different width"); if (jpx->comps[k].h != jpx->comps[0].h) fz_throw(ctx, "image components have different height"); if (jpx->comps[k].prec != jpx->comps[0].prec) fz_throw(ctx, "image components have different precision"); } n = jpx->numcomps; w = jpx->comps[0].w; h = jpx->comps[0].h; depth = jpx->comps[0].prec; sgnd = jpx->comps[0].sgnd; if (jpx->color_space == CLRSPC_SRGB && n == 4) { n = 3; a = 1; } else if (jpx->color_space == CLRSPC_SYCC && n == 4) { n = 3; a = 1; } else if (n == 2) { n = 1; a = 1; } else if (n > 4) { n = 4; a = 1; } else { a = 0; } if (defcs) { if (defcs->n == n) { colorspace = defcs; } else { fz_warn(ctx, "jpx file and dict colorspaces do not match"); defcs = NULL; } } if (!defcs) { switch (n) { case 1: colorspace = fz_device_gray; break; case 3: colorspace = fz_device_rgb; break; case 4: colorspace = fz_device_cmyk; break; } } fz_try(ctx) { img = fz_new_pixmap(ctx, colorspace, w, h); } fz_catch(ctx) { opj_image_destroy(jpx); fz_throw(ctx, "out of memory"); } p = img->samples; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { for (k = 0; k < n + a; k++) { v = jpx->comps[k].data[y * w + x]; if (sgnd) v = v + (1 << (depth - 1)); if (depth > 8) v = v >> (depth - 8); *p++ = v; } if (!a) *p++ = 255; } } if (a) { if (n == 4) { fz_pixmap *tmp = fz_new_pixmap(ctx, fz_device_rgb, w, h); fz_convert_pixmap(ctx, img, tmp); fz_drop_pixmap(ctx, img); img = tmp; } fz_premultiply_pixmap(ctx, img); } opj_image_destroy(jpx); return img; }
int main(int argc, char *argv[]) { mj2_dparameters_t mj2_parameters; /* decompression parameters */ opj_dinfo_t* dinfo; opj_event_mgr_t event_mgr; /* event manager */ opj_cio_t *cio = NULL; unsigned int tnum, snum; opj_mj2_t *movie; mj2_tk_t *track; mj2_sample_t *sample; unsigned char* frame_codestream; FILE *file, *outfile; char outfilename[50]; opj_image_t *img = NULL; unsigned int max_codstrm_size = 0; double total_time = 0; unsigned int numframes = 0; if (argc != 3) { printf("Usage: %s inputfile.mj2 outputfile.yuv\n",argv[0]); return 1; } file = fopen(argv[1], "rb"); if (!file) { fprintf(stderr, "failed to open %s for reading\n", argv[1]); return 1; } /* Checking output file */ outfile = fopen(argv[2], "w"); if (!file) { fprintf(stderr, "failed to open %s for writing\n", argv[2]); return 1; } fclose(outfile); /* configure the event callbacks (not required) setting of each callback is optionnal */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = NULL; /* get a MJ2 decompressor handle */ dinfo = mj2_create_decompress(); movie = (opj_mj2_t*)dinfo->mj2_handle; /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); memset(&mj2_parameters, 0, sizeof(mj2_dparameters_t)); /* set J2K decoding parameters to default values */ opj_set_default_decoder_parameters(&mj2_parameters.j2k_parameters); /* setup the decoder decoding parameters using user parameters */ mj2_setup_decoder(movie, &mj2_parameters); if (mj2_read_struct(file, movie)) /* Creating the movie structure */ return 1; /* Decode first video track */ for (tnum=0; tnum < (unsigned int)(movie->num_htk + movie->num_stk + movie->num_vtk); tnum++) { if (movie->tk[tnum].track_type == 0) break; } if (movie->tk[tnum].track_type != 0) { printf("Error. Movie does not contain any video track\n"); return 1; } track = &movie->tk[tnum]; /* Output info on first video tracl */ fprintf(stdout,"The first video track contains %d frames.\nWidth: %d, Height: %d \n\n", track->num_samples, track->w, track->h); max_codstrm_size = track->sample[0].sample_size-8; frame_codestream = (unsigned char*) malloc(max_codstrm_size * sizeof(unsigned char)); numframes = track->num_samples; for (snum=0; snum < numframes; snum++) { double init_time = opj_clock(); double elapsed_time; sample = &track->sample[snum]; if (sample->sample_size-8 > max_codstrm_size) { max_codstrm_size = sample->sample_size-8; if ((frame_codestream = (unsigned char*) realloc(frame_codestream, max_codstrm_size)) == NULL) { printf("Error reallocation memory\n"); return 1; }; } fseek(file,sample->offset+8,SEEK_SET); fread(frame_codestream, sample->sample_size-8, 1, file); /* Assuming that jp and ftyp markers size do */ /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, frame_codestream, sample->sample_size-8); img = opj_decode(dinfo, cio); /* Decode J2K to image */ #ifdef WANT_SYCC_TO_RGB if(img->color_space == CLRSPC_SYCC) { color_sycc_to_rgb(img); } #endif if(img->icc_profile_buf) { #if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2) color_apply_icc_profile(img); #endif free(img->icc_profile_buf); img->icc_profile_buf = NULL; img->icc_profile_len = 0; } if (((img->numcomps == 3) && (img->comps[0].dx == img->comps[1].dx / 2) && (img->comps[0].dx == img->comps[2].dx / 2 ) && (img->comps[0].dx == 1)) || (img->numcomps == 1)) { if (!imagetoyuv(img, argv[2])) /* Convert image to YUV */ return 1; } else if ((img->numcomps == 3) && (img->comps[0].dx == 1) && (img->comps[1].dx == 1)&& (img->comps[2].dx == 1))/* If YUV 4:4:4 input --> to bmp */ { fprintf(stdout,"The frames will be output in a bmp format (output_1.bmp, ...)\n"); sprintf(outfilename,"output_%d.bmp",snum); if (imagetobmp(img, outfilename)) /* Convert image to BMP */ return 1; } else { fprintf(stdout,"Image component dimensions are unknown. Unable to output image\n"); fprintf(stdout,"The frames will be output in a j2k file (output_1.j2k, ...)\n"); sprintf(outfilename,"output_%d.j2k",snum); outfile = fopen(outfilename, "wb"); if (!outfile) { fprintf(stderr, "failed to open %s for writing\n",outfilename); return 1; } fwrite(frame_codestream,sample->sample_size-8,1,outfile); fclose(outfile); } /* close the byte stream */ opj_cio_close(cio); /* free image data structure */ opj_image_destroy(img); elapsed_time = opj_clock()-init_time; fprintf(stderr, "Frame number %d/%d decoded in %.2f mseconds\n", snum + 1, numframes, elapsed_time*1000); total_time += elapsed_time; } free(frame_codestream); fclose(file); /* free remaining structures */ if(dinfo) { mj2_destroy_decompress((opj_mj2_t*)dinfo->mj2_handle); } free(dinfo); fprintf(stdout, "%d frame(s) correctly decompressed\n", snum); fprintf(stdout,"Total decoding time: %.2f seconds (%.1f fps)\n", total_time, (float)numframes/total_time); return 0; }
dt_imageio_retval_t dt_imageio_open_j2k(dt_image_t *img, const char *filename, dt_mipmap_cache_allocator_t a) { opj_dparameters_t parameters; /* decompression parameters */ opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; FILE *fsrc = NULL; unsigned char *src = NULL; int file_length; opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ opj_cio_t *cio = NULL; OPJ_CODEC_FORMAT codec; int ret = DT_IMAGEIO_FILE_CORRUPTED; int file_format = get_file_format(filename); if(file_format == -1) return DT_IMAGEIO_FILE_CORRUPTED; if(!img->exif_inited) (void) dt_exif_read(img, filename); /* read the input file and put it in memory */ /* ---------------------------------------- */ fsrc = fopen(filename, "rb"); if(!fsrc) { fprintf(stderr, "[j2k_open] Error: failed to open `%s' for reading\n", filename); return DT_IMAGEIO_FILE_NOT_FOUND; } fseek(fsrc, 0, SEEK_END); file_length = ftell(fsrc); fseek(fsrc, 0, SEEK_SET); src = (unsigned char *) malloc(file_length); if(fread(src, 1, file_length, fsrc) != (size_t)file_length) { free(src); fclose(fsrc); fprintf(stderr, "[j2k_open] Error: fread returned a number of elements different from the expected.\n"); return DT_IMAGEIO_FILE_NOT_FOUND; } fclose(fsrc); if(memcmp(JP2_HEAD, src, sizeof(JP2_HEAD)) == 0) { file_format = JP2_CFMT; // just in case someone used the wrong extension } else if(memcmp(J2K_HEAD, src, sizeof(J2K_HEAD)) == 0) { file_format = J2K_CFMT; // just in case someone used the wrong extension } else // this will also reject jpt files. { free(src); fprintf(stderr, "[j2k_open] Error: `%s' has unsupported file format.\n", filename); return DT_IMAGEIO_FILE_CORRUPTED; } /* configure the event callbacks (not required) */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; // event_mgr.warning_handler = warning_callback; // event_mgr.info_handler = info_callback; /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); /* decode the code-stream */ /* ---------------------- */ if(file_format == J2K_CFMT) /* JPEG-2000 codestream */ codec = CODEC_J2K; else if(file_format == JP2_CFMT) /* JPEG 2000 compressed image data */ codec = CODEC_JP2; else if(file_format == JPT_CFMT) /* JPEG 2000, JPIP */ codec = CODEC_JPT; else { free(src); return DT_IMAGEIO_FILE_CORRUPTED; // can't happen } /* get a decoder handle */ dinfo = opj_create_decompress(codec); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); /* close the byte stream */ opj_cio_close(cio); /* free the memory containing the code-stream */ free(src); if(!image) { fprintf(stderr, "[j2k_open] Error: failed to decode image `%s'\n", filename); ret = DT_IMAGEIO_FILE_CORRUPTED; goto end_of_the_world; } if(image->color_space == CLRSPC_SYCC) { color_sycc_to_rgb(image); } //FIXME: openjpeg didn't have support for icc profiles before version 1.5 // this needs some #ifdef magic and proper implementation #ifdef HAVE_OPENJPEG_ICC if(image->icc_profile_buf) { #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) color_apply_icc_profile(image); #endif free(image->icc_profile_buf); image->icc_profile_buf = NULL; image->icc_profile_len = 0; } #endif /* create output image */ /* ------------------- */ long signed_offsets[4] = {0, 0, 0, 0}; int float_divs[4] = {1, 1, 1, 1}; // some sanity checks if(image->numcomps == 0 || image->x1 == 0 || image->y1 == 0) { fprintf(stderr, "[j2k_open] Error: invalid raw image parameters in `%s'\n", filename); ret = DT_IMAGEIO_FILE_CORRUPTED; goto end_of_the_world; } for(int i = 0; i < image->numcomps; i++) { if(image->comps[i].w != image->x1 || image->comps[i].h != image->y1) { fprintf(stderr, "[j2k_open] Error: some component has different size in `%s'\n", filename); ret = DT_IMAGEIO_FILE_CORRUPTED; goto end_of_the_world; } if(image->comps[i].prec > 16) { fprintf(stderr,"[j2k_open] Error: precision %d is larger than 16 in `%s'\n", image->comps[1].prec, filename); ret = DT_IMAGEIO_FILE_CORRUPTED; goto end_of_the_world; } } img->width = image->x1; img->height = image->y1; img->bpp = 4*sizeof(float); float *buf = (float *)dt_mipmap_cache_alloc(img, DT_MIPMAP_FULL, a); if(!buf) { ret = DT_IMAGEIO_CACHE_FULL; goto end_of_the_world; } int i = image->numcomps; if(i > 4) i = 4; while(i) { i--; if(image->comps[i].sgnd) signed_offsets[i] = 1 << (image->comps[i].prec - 1); float_divs[i] = (1 << image->comps[i].prec) - 1; } // numcomps == 1 : grey -> r = grey, g = grey, b = grey // numcomps == 2 : grey, alpha -> r = grey, g = grey, b = grey. put alpha into the mix? // numcomps == 3 : rgb -> rgb // numcomps == 4 : rgb, alpha -> rgb. put alpha into the mix? // first try: ignore alpha. if(image->numcomps < 3) // 1, 2 => grayscale { for(int i = 0; i < img->width * img->height; i++) buf[i*4 + 0] = buf[i*4 + 1] = buf[i*4 + 2] = (float)(image->comps[0].data[i] + signed_offsets[0]) / float_divs[0]; } else // 3, 4 => rgb { for(int i = 0; i < img->width * img->height; i++) for(int k = 0; k < 3; k++) buf[i*4 + k] = (float)(image->comps[k].data[i] + signed_offsets[k]) / float_divs[k]; } ret = DT_IMAGEIO_OK; end_of_the_world: /* free remaining structures */ if(dinfo) opj_destroy_decompress(dinfo); /* free image data structure */ opj_image_destroy(image); return ret; }
int dt_imageio_j2k_read_profile(const char *filename, uint8_t **out) { #ifdef HAVE_OPENJPEG_ICC opj_dparameters_t parameters; /* decompression parameters */ opj_image_t *image = NULL; FILE *fsrc = NULL; unsigned char *src = NULL; int file_length; opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ opj_cio_t *cio = NULL; OPJ_CODEC_FORMAT codec; gboolean res = FALSE; unsigned int length = 0; *out = NULL; /* read the input file and put it in memory */ /* ---------------------------------------- */ fsrc = fopen(filename, "rb"); if(!fsrc) { fprintf(stderr, "[j2k_open] Error: failed to open `%s' for reading\n", filename); goto another_end_of_the_world; } fseek(fsrc, 0, SEEK_END); file_length = ftell(fsrc); fseek(fsrc, 0, SEEK_SET); src = (unsigned char *) malloc(file_length); if(fread(src, 1, file_length, fsrc) != (size_t)file_length) { free(src); fclose(fsrc); fprintf(stderr, "[j2k_open] Error: fread returned a number of elements different from the expected.\n"); goto another_end_of_the_world; } fclose(fsrc); if(memcmp(JP2_HEAD, src, sizeof(JP2_HEAD)) == 0) { codec = CODEC_JP2; } else if(memcmp(J2K_HEAD, src, sizeof(J2K_HEAD)) == 0) { codec = CODEC_J2K; } else // this will also reject jpt files. { free(src); fprintf(stderr, "[j2k_open] Error: `%s' has unsupported file format.\n", filename); goto another_end_of_the_world; } /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); parameters.cp_limit_decoding = LIMIT_TO_MAIN_HEADER; /* decode the code-stream */ /* ---------------------- */ /* get a decoder handle */ dinfo = opj_create_decompress(codec); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); /* close the byte stream */ opj_cio_close(cio); /* free the memory containing the code-stream */ free(src); if(!image) { fprintf(stderr, "[j2k_open] Error: failed to decode image `%s'\n", filename); goto another_end_of_the_world; } if(image->icc_profile_buf) { res = TRUE; length = image->icc_profile_len; *out = image->icc_profile_buf; image->icc_profile_buf = NULL; image->icc_profile_len = 0; } another_end_of_the_world: /* free remaining structures */ if(dinfo) opj_destroy_decompress(dinfo); /* free image data structure */ opj_image_destroy(image); return res?length:0; #else return 0; #endif }
void* OPJSupport::decompressJPEG2KWithBuffer(void* inputBuffer, void* jp2Data, long jp2DataSize, long *decompressedBufferSize, int *colorModel) { //decoderMutex.lock(); opj_dparameters_t parameters; int i; int width, height; OPJ_BOOL hasAlpha, fails = OPJ_FALSE; OPJ_CODEC_FORMAT codec_format; unsigned char rc, gc, bc, ac; if (jp2DataSize<12) { //decoderMutex.unlock(); return 0; } /*-----------------------------------------------*/ decode_info_t decodeInfo; memset(&decodeInfo, 0, sizeof(decode_info_t)); opj_set_default_decoder_parameters(¶meters); parameters.decod_format = buffer_format(jp2Data); // Create the stream opj_buffer_info_t bufferInfo; bufferInfo.cur = bufferInfo.buf = (OPJ_BYTE *)jp2Data; bufferInfo.len = (OPJ_SIZE_T) jp2DataSize; // Create the stream decodeInfo.stream = opj_stream_create_buffer_stream(&bufferInfo , OPJ_STREAM_READ); //GROK //decodeInfo.stream = opj_stream_create_buffer_stream((OPJ_BYTE *)jp2Data, (OPJ_SIZE_T) jp2DataSize , OPJ_STREAM_READ); if (!decodeInfo.stream) { fprintf(stderr,"%s:%d:\n\tNO decodeInfo.stream\n",__FILE__,__LINE__); //decoderMutex.unlock(); return NULL; } /*-----------------------------------------------*/ switch (parameters.decod_format) { case J2K_CFMT: /* JPEG-2000 codestream */ codec_format = OPJ_CODEC_J2K; break; case JP2_CFMT: /* JPEG 2000 compressed image data */ codec_format = OPJ_CODEC_JP2; break; case JPT_CFMT: /* JPEG 2000, JPIP */ codec_format = OPJ_CODEC_JPT; break; case -1: default: release(&decodeInfo); fprintf(stderr,"%s:%d: decode format missing\n",__FILE__,__LINE__); //decoderMutex.unlock(); return NULL; } /*-----------------------------------------------*/ while(1) { int user_changed_tile=0, user_changed_reduction=0; int max_tiles=0, max_reduction=0; fails = OPJ_TRUE; decodeInfo.codec = opj_create_decompress(codec_format); if (decodeInfo.codec == NULL) { fprintf(stderr,"%s:%d:\n\tNO codec\n",__FILE__,__LINE__); break; } #ifdef OPJ_VERBOSE opj_set_info_handler(decodeInfo.codec, info_callback, this); opj_set_warning_handler(decodeInfo.codec, warning_callback, this); #endif opj_set_error_handler(decodeInfo.codec, error_callback, this); // Setup the decoder decoding parameters if ( !opj_setup_decoder(decodeInfo.codec, ¶meters)) { fprintf(stderr,"%s:%d:\n\topj_setup_decoder failed\n",__FILE__,__LINE__); break; } if (user_changed_tile && user_changed_reduction) { int reduction=0; opj_set_decoded_resolution_factor(decodeInfo.codec, reduction); } /* Read the main header of the codestream and if necessary the JP2 boxes * see openjpeg.c * For OPJ_CODEC_JP2 it will call 'opj_jp2_read_header()' in jp2.c:2276 * then call 'opj_j2k_read_header()' */ if( !opj_read_header(decodeInfo.stream, decodeInfo.codec, &(decodeInfo.image))) { fprintf(stderr,"%s:%d:\n\topj_read_header failed\n",__FILE__,__LINE__); break; } if ( !(user_changed_tile && user_changed_reduction) || (max_tiles <= 0) || (max_reduction <= 0) ) { decodeInfo.cstr_info = opj_get_cstr_info(decodeInfo.codec); max_reduction = decodeInfo.cstr_info->m_default_tile_info.tccp_info->numresolutions; max_tiles = decodeInfo.cstr_info->tw * decodeInfo.cstr_info->th; decodeInfo.cstr_index = opj_get_cstr_index(decodeInfo.codec); } if (!parameters.nb_tile_to_decode) { int user_changed_area=0; if(user_changed_area) { } /* Optional if you want decode the entire image */ if (!opj_set_decode_area(decodeInfo.codec, decodeInfo.image, (OPJ_INT32)parameters.DA_x0, (OPJ_INT32)parameters.DA_y0, (OPJ_INT32)parameters.DA_x1, (OPJ_INT32)parameters.DA_y1)) { fprintf(stderr,"%s:%d:\n\topj_set_decode_area failed\n",__FILE__,__LINE__); break; } /* Get the decoded image */ if (!opj_decode(decodeInfo.codec, decodeInfo.stream, decodeInfo.image)) { fprintf(stderr,"%s:%d:\n\topj_decode failed\n",__FILE__,__LINE__); //decoderMutex.unlock(); return NULL; } if (!opj_end_decompress(decodeInfo.codec, decodeInfo.stream)) { fprintf(stderr,"%s:%d:\n\topj_end_decompress failed\n",__FILE__,__LINE__); break; } } else { if (!opj_get_decoded_tile(decodeInfo.codec, decodeInfo.stream, decodeInfo.image, parameters.tile_index)) { fprintf(stderr,"%s:%d:\n\topj_get_decoded_tile failed\n",__FILE__,__LINE__); break; } } fails = OPJ_FALSE; break; } // while decodeInfo.deleteImage = fails; if (fails) { //decoderMutex.unlock(); return NULL; } decodeInfo.deleteImage = OPJ_TRUE; if(decodeInfo.image->color_space == OPJ_CLRSPC_SYCC) { //disable for now //color_sycc_to_rgb(decodeInfo.image); } if (decodeInfo.image->color_space != OPJ_CLRSPC_SYCC && decodeInfo.image->numcomps == 3 && decodeInfo.image->comps[0].dx == decodeInfo.image->comps[0].dy && decodeInfo.image->comps[1].dx != 1) { decodeInfo.image->color_space = OPJ_CLRSPC_SYCC; } else if(decodeInfo.image->numcomps <= 2) { decodeInfo.image->color_space = OPJ_CLRSPC_GRAY; } if (decodeInfo.image->icc_profile_buf) { #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) color_apply_icc_profile(decodeInfo.image); #endif free(decodeInfo.image->icc_profile_buf); decodeInfo.image->icc_profile_buf = NULL; decodeInfo.image->icc_profile_len = 0; } //--- width = decodeInfo.image->comps[0].w; height = decodeInfo.image->comps[0].h; long depth = (decodeInfo.image->comps[0].prec + 7)/8; long decompressSize = width * height * decodeInfo.image->numcomps * depth; if (decompressedBufferSize) *decompressedBufferSize = decompressSize;; if (!inputBuffer ) { inputBuffer = malloc(decompressSize); } if (colorModel) *colorModel = 0; if ((decodeInfo.image->numcomps >= 3 && decodeInfo.image->comps[0].dx == decodeInfo.image->comps[1].dx && decodeInfo.image->comps[1].dx == decodeInfo.image->comps[2].dx && decodeInfo.image->comps[0].dy == decodeInfo.image->comps[1].dy && decodeInfo.image->comps[1].dy == decodeInfo.image->comps[2].dy && decodeInfo.image->comps[0].prec == decodeInfo.image->comps[1].prec && decodeInfo.image->comps[1].prec == decodeInfo.image->comps[2].prec )/* RGB[A] */ || (decodeInfo.image->numcomps == 2 && decodeInfo.image->comps[0].dx == decodeInfo.image->comps[1].dx && decodeInfo.image->comps[0].dy == decodeInfo.image->comps[1].dy && decodeInfo.image->comps[0].prec == decodeInfo.image->comps[1].prec ) ) /* GA */ { int has_alpha4, has_alpha2, has_rgb; int *red, *green, *blue, *alpha; if (colorModel) *colorModel = 1; alpha = NULL; has_rgb = (decodeInfo.image->numcomps == 3); has_alpha4 = (decodeInfo.image->numcomps == 4); has_alpha2 = (decodeInfo.image->numcomps == 2); hasAlpha = (has_alpha4 || has_alpha2); if(has_rgb) { red = decodeInfo.image->comps[0].data; green = decodeInfo.image->comps[1].data; blue = decodeInfo.image->comps[2].data; if(has_alpha4) { alpha = decodeInfo.image->comps[3].data; } } /* if(has_rgb) */ else { red = green = blue = decodeInfo.image->comps[0].data; if(has_alpha2) { alpha = decodeInfo.image->comps[1].data; } } /* if(has_rgb) */ ac = 255;/* 255: FULLY_OPAQUE; 0: FULLY_TRANSPARENT */ unsigned char* ptrIBody = (unsigned char*)inputBuffer; for(i = 0; i < width*height; i++) { rc = (unsigned char)*red++; gc = (unsigned char)*green++; bc = (unsigned char)*blue++; if(hasAlpha) { ac = (unsigned char)*alpha++;; } /* A R G B */ //*ptrIBody++ = (int)((ac<<24) | (rc<<16) | (gc<<8) | bc); *ptrIBody = rc; ptrIBody++; *ptrIBody = gc; ptrIBody++; *ptrIBody = bc; ptrIBody++; if (hasAlpha) { *ptrIBody = ac; ptrIBody++; } } /* for(i) */ }/* if (decodeInfo.image->numcomps >= 3 */ else if(decodeInfo.image->numcomps == 1) /* Grey */ { /* 1 component 8 or 16 bpp decodeInfo.image */ int *grey = decodeInfo.image->comps[0].data; if(decodeInfo.image->comps[0].prec <= 8) { char* ptrBBody = (char*)inputBuffer; for(i=0; i<width*height; i++) { *ptrBBody++ = *grey++; } /* Replace image8 buffer: */ } else /* prec[9:16] */ { int *grey = decodeInfo.image->comps[0].data; //int ushift = 0, dshift = 0, force16 = 0; short* ptrSBody = (short*)inputBuffer; for(i=0; i<width*height; i++) { //disable shift up for signed data: don't know why we are doing this *ptrSBody++ = *grey++; } /* Replace image16 buffer: */ } } else { int *grey; fprintf(stderr,"%s:%d:Can show only first component of decodeInfo.image\n" " components(%d) prec(%d) color_space[%d](%s)\n" " RECT(%d,%d,%d,%d)\n",__FILE__,__LINE__,decodeInfo.image->numcomps, decodeInfo.image->comps[0].prec, decodeInfo.image->color_space,clr_space(decodeInfo.image->color_space), decodeInfo.image->x0,decodeInfo.image->y0,decodeInfo.image->x1,decodeInfo.image->y1 ); for(i = 0; i < decodeInfo.image->numcomps; ++i) { fprintf(stderr,"[%d]dx(%d) dy(%d) w(%d) h(%d) signed(%u)\n",i, decodeInfo.image->comps[i].dx ,decodeInfo.image->comps[i].dy, decodeInfo.image->comps[i].w,decodeInfo.image->comps[i].h, decodeInfo.image->comps[i].sgnd); } /* 1 component 8 or 16 bpp decodeInfo.image */ grey = decodeInfo.image->comps[0].data; if(decodeInfo.image->comps[0].prec <= 8) { char* ptrBBody = (char*)inputBuffer; for(i=0; i<width*height; i++) { *ptrBBody++ = *grey++; } /* Replace image8 buffer: */ } else /* prec[9:16] */ { int *grey; //int ushift = 0, dshift = 0, force16 = 0; grey = decodeInfo.image->comps[0].data; short* ptrSBody = (short*)inputBuffer; for(i=0; i<width*height; i++) { *ptrSBody++ = *grey++; } /* Replace image16 buffer: */ } } release(&decodeInfo); opj_destroy_cstr_index(&(decodeInfo.cstr_index)); //decoderMutex.unlock(); return inputBuffer; }
/* Read a frame from an IPX file */ int IPX_read_frame(int fnr, TFrame *frame, IPX_status *status) { int offset, size; int i, j, p; static unsigned int data_max = 0; static unsigned char *data; float factor; /* JPEG 2000 variables */ static int jp2_init = 1; static opj_dparameters_t parameters; /* decompression parameters */ static opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ static opj_event_mgr_t event_mgr; /* event manager */ opj_cio_t *cio = NULL; opj_image_t *image = NULL; if(fnr >= status->header.numFrames) { return(1); } offset = status->frames[fnr].offset + IPX_UINT + IPX_DOUBLE; //sizeof(uint) + sizeof(double); if(fseek(status->fd, offset, SEEK_SET)) { return(2); } size = status->frames[fnr].size - IPX_UINT - IPX_DOUBLE; //sizeof(uint) - sizeof(double); /* Allocate memory */ if(data_max < size) { if(data_max == 0) { data = (unsigned char*) malloc(size); }else { data = (unsigned char*) realloc(data, size); } data_max = size; } /* Read data */ if(fread(data, size, 1, status->fd) != 1) { return(2); } /* Decode JP2 image */ if(jp2_init) { jp2_init = 0; /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_JP2); /* Setup callbacks */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters */ opj_setup_decoder(dinfo, ¶meters); } /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, data, size); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); if(!image) { opj_cio_close(cio); return(3); } /* close the byte stream */ opj_cio_close(cio); /* Copy image into TRawFrame structure */ /* Check frame data is allocated. If not, allocate it */ if(allocate_output(status->header.width, status->header.height, frame)) { /* Frame is wrong size */ return(4); } factor = (float) ((1 << image->comps[0].prec) - 1); //factor = (float) ((1 << 16) - 1); p = 0; for(j=0;j<status->header.height;j++) { for(i=0;i<status->header.width;i++) { frame->data[i][j] = ((float) image->comps[0].data[p]) / factor; p++; } } if(fnr == (status->header.numFrames-1)) { /* This is the last frame */ frame->last = 1; } /* free image data structure */ opj_image_destroy(image); frame->time = status->frames[fnr].time; return(0); }
JP2KImage read_jp2k_data(const char* fname, int format) #endif { JP2KImage jp; init_jp2k(&jp); opj_stream_t* stream = NULL; opj_codec_t* codec = NULL; opj_dparameters_t parameters; opj_set_default_decoder_parameters(¶meters); #if OPENJPEG_VER < JP2K_VER_21 stream = opj_stream_create_default_file_stream(fp, 1); // 2.0.0 #else stream = opj_stream_create_default_file_stream(fname, 1); // 2.1.0 #endif if (stream==NULL){ jp.state = ERROR_GRAPH_RDFILE; return jp; } if (format==JP2K_FMT_J2K) { // JPEG 2000 codestream codec = opj_create_decompress(OPJ_CODEC_J2K); } else if (format==JP2K_FMT_JP2) { // JPEG 2000 compressed image data codec = opj_create_decompress(OPJ_CODEC_JP2); } else if (format==JP2K_FMT_JPT) { // JPEG 2000 JPIP codec = opj_create_decompress(OPJ_CODEC_JPT); } else { print_message("JBXL::readJPEG2KData: ERROR: unknown file format!\n"); opj_stream_destroy(stream); return jp; } if (!opj_setup_decoder(codec, ¶meters) ){ opj_stream_destroy(stream); opj_destroy_codec(codec); jp.state = ERROR_GRAPH; return jp; } if (!opj_read_header(stream, codec, &jp.image)){ opj_stream_destroy(stream); opj_destroy_codec(codec); jp.state = ERROR_GRAPH; return jp; } if (!opj_set_decode_area(codec, jp.image, 0, 0, 0, 0)){ opj_stream_destroy(stream); opj_destroy_codec(codec); free_jp2k(&jp); jp.state = ERROR_GRAPH; return jp; } if (!(opj_decode(codec, stream, jp.image) && opj_end_decompress(codec, stream))) { opj_destroy_codec(codec); opj_stream_destroy(stream); free_jp2k(&jp); jp.state = ERROR_GRAPH; return jp; } setup_jp2k(&jp); opj_stream_destroy(stream); opj_destroy_codec(codec); return jp; }
static Image *ReadJP2Image(const ImageInfo *image_info,ExceptionInfo *exception) { const char *option; Image *image; int jp2_status; MagickBooleanType status; opj_codec_t *jp2_codec; opj_codestream_index_t *codestream_index = (opj_codestream_index_t *) NULL; opj_dparameters_t parameters; opj_image_t *jp2_image; opj_stream_t *jp2_stream; register ssize_t i; ssize_t y; unsigned char sans[4]; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); image=AcquireImage(image_info,exception); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Initialize JP2 codec. */ if (ReadBlob(image,4,sans) != 4) { image=DestroyImageList(image); return((Image *) NULL); } (void) SeekBlob(image,SEEK_SET,0); if (LocaleCompare(image_info->magick,"JPT") == 0) jp2_codec=opj_create_decompress(OPJ_CODEC_JPT); else if (IsJ2K(sans,4) != MagickFalse) jp2_codec=opj_create_decompress(OPJ_CODEC_J2K); else jp2_codec=opj_create_decompress(OPJ_CODEC_JP2); opj_set_warning_handler(jp2_codec,JP2WarningHandler,exception); opj_set_error_handler(jp2_codec,JP2ErrorHandler,exception); opj_set_default_decoder_parameters(¶meters); option=GetImageOption(image_info,"jp2:reduce-factor"); if (option != (const char *) NULL) parameters.cp_reduce=StringToInteger(option); option=GetImageOption(image_info,"jp2:quality-layers"); if (option != (const char *) NULL) parameters.cp_layer=StringToInteger(option); if (opj_setup_decoder(jp2_codec,¶meters) == 0) { opj_destroy_codec(jp2_codec); ThrowReaderException(DelegateError,"UnableToManageJP2Stream"); } jp2_stream=opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE,1); opj_stream_set_read_function(jp2_stream,JP2ReadHandler); opj_stream_set_write_function(jp2_stream,JP2WriteHandler); opj_stream_set_seek_function(jp2_stream,JP2SeekHandler); opj_stream_set_skip_function(jp2_stream,JP2SkipHandler); opj_stream_set_user_data(jp2_stream,image,NULL); opj_stream_set_user_data_length(jp2_stream,GetBlobSize(image)); if (opj_read_header(jp2_stream,jp2_codec,&jp2_image) == 0) { opj_stream_destroy(jp2_stream); opj_destroy_codec(jp2_codec); ThrowReaderException(DelegateError,"UnableToDecodeImageFile"); } jp2_status=1; if ((image->columns != 0) && (image->rows != 0)) { /* Extract an area from the image. */ jp2_status=opj_set_decode_area(jp2_codec,jp2_image, (OPJ_INT32) image->extract_info.x,(OPJ_INT32) image->extract_info.y, (OPJ_INT32) (image->extract_info.x+(ssize_t) image->columns), (OPJ_INT32) (image->extract_info.y+(ssize_t) image->rows)); if (jp2_status == 0) { opj_stream_destroy(jp2_stream); opj_destroy_codec(jp2_codec); opj_image_destroy(jp2_image); ThrowReaderException(DelegateError,"UnableToDecodeImageFile"); } } if ((image_info->number_scenes != 0) && (image_info->scene != 0)) jp2_status=opj_get_decoded_tile(jp2_codec,jp2_stream,jp2_image, (unsigned int) image_info->scene-1); else if (image->ping == MagickFalse) { jp2_status=opj_decode(jp2_codec,jp2_stream,jp2_image); if (jp2_status != 0) jp2_status=opj_end_decompress(jp2_codec,jp2_stream); } if (jp2_status == 0) { opj_stream_destroy(jp2_stream); opj_destroy_codec(jp2_codec); opj_image_destroy(jp2_image); ThrowReaderException(DelegateError,"UnableToDecodeImageFile"); } opj_stream_destroy(jp2_stream); for (i=0; i < (ssize_t) jp2_image->numcomps; i++) { if ((jp2_image->comps[i].dx == 0) || (jp2_image->comps[i].dy == 0)) { opj_destroy_codec(jp2_codec); opj_image_destroy(jp2_image); ThrowReaderException(CoderError,"IrregularChannelGeometryNotSupported") } }
/* -------------------------------------------------------------------------- */ int main(int argc, char **argv) { opj_decompress_parameters parameters; /* decompression parameters */ opj_image_t* image = NULL; opj_stream_t *l_stream = NULL; /* Stream */ opj_codec_t* l_codec = NULL; /* Handle to a decompressor */ opj_codestream_index_t* cstr_index = NULL; char indexfilename[OPJ_PATH_LEN]; /* index file name */ OPJ_INT32 num_images, imageno; img_fol_t img_fol; dircnt_t *dirptr = NULL; int failed = 0; OPJ_FLOAT64 t, tCumulative = 0; OPJ_UINT32 numDecompressedImages = 0; /* set decoding parameters to default values */ set_default_parameters(¶meters); /* FIXME Initialize indexfilename and img_fol */ *indexfilename = 0; /* Initialize img_fol */ memset(&img_fol,0,sizeof(img_fol_t)); /* parse input and get user encoding parameters */ if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) { destroy_parameters(¶meters); return EXIT_FAILURE; } /* Initialize reading of directory */ if(img_fol.set_imgdir==1){ int it_image; num_images=get_num_images(img_fol.imgdirpath); dirptr=(dircnt_t*)malloc(sizeof(dircnt_t)); if(dirptr){ dirptr->filename_buf = (char*)malloc((size_t)num_images*OPJ_PATH_LEN*sizeof(char)); /* Stores at max 10 image file names*/ dirptr->filename = (char**) malloc((size_t)num_images*sizeof(char*)); if(!dirptr->filename_buf){ destroy_parameters(¶meters); return EXIT_FAILURE; } for(it_image=0;it_image<num_images;it_image++){ dirptr->filename[it_image] = dirptr->filename_buf + it_image*OPJ_PATH_LEN; } } if(load_images(dirptr,img_fol.imgdirpath)==1){ destroy_parameters(¶meters); return EXIT_FAILURE; } if (num_images==0){ fprintf(stdout,"Folder is empty\n"); destroy_parameters(¶meters); return EXIT_FAILURE; } }else{ num_images=1; } /*Decoding image one by one*/ for(imageno = 0; imageno < num_images ; imageno++) { fprintf(stderr,"\n"); if(img_fol.set_imgdir==1){ if (get_next_file(imageno, dirptr,&img_fol, ¶meters)) { fprintf(stderr,"skipping file...\n"); destroy_parameters(¶meters); continue; } } /* read the input file and put it in memory */ /* ---------------------------------------- */ l_stream = opj_stream_create_default_file_stream(parameters.infile,1); if (!l_stream){ fprintf(stderr, "ERROR -> failed to create the stream from the file %s\n", parameters.infile); destroy_parameters(¶meters); return EXIT_FAILURE; } /* decode the JPEG2000 stream */ /* ---------------------- */ switch(parameters.decod_format) { case J2K_CFMT: /* JPEG-2000 codestream */ { /* Get a decoder handle */ l_codec = opj_create_decompress(OPJ_CODEC_J2K); break; } case JP2_CFMT: /* JPEG 2000 compressed image data */ { /* Get a decoder handle */ l_codec = opj_create_decompress(OPJ_CODEC_JP2); break; } case JPT_CFMT: /* JPEG 2000, JPIP */ { /* Get a decoder handle */ l_codec = opj_create_decompress(OPJ_CODEC_JPT); break; } default: fprintf(stderr, "skipping file..\n"); destroy_parameters(¶meters); opj_stream_destroy(l_stream); continue; } /* catch events using our callbacks and give a local context */ opj_set_info_handler(l_codec, info_callback,00); opj_set_warning_handler(l_codec, warning_callback,00); opj_set_error_handler(l_codec, error_callback,00); t = opj_clock(); /* Setup the decoder decoding parameters using user parameters */ if ( !opj_setup_decoder(l_codec, &(parameters.core)) ){ fprintf(stderr, "ERROR -> opj_decompress: failed to setup the decoder\n"); destroy_parameters(¶meters); opj_stream_destroy(l_stream); opj_destroy_codec(l_codec); return EXIT_FAILURE; } /* Read the main header of the codestream and if necessary the JP2 boxes*/ if(! opj_read_header(l_stream, l_codec, &image)){ fprintf(stderr, "ERROR -> opj_decompress: failed to read the header\n"); destroy_parameters(¶meters); opj_stream_destroy(l_stream); opj_destroy_codec(l_codec); opj_image_destroy(image); return EXIT_FAILURE; } if (!parameters.nb_tile_to_decode) { /* Optional if you want decode the entire image */ if (!opj_set_decode_area(l_codec, image, (OPJ_INT32)parameters.DA_x0, (OPJ_INT32)parameters.DA_y0, (OPJ_INT32)parameters.DA_x1, (OPJ_INT32)parameters.DA_y1)){ fprintf(stderr, "ERROR -> opj_decompress: failed to set the decoded area\n"); destroy_parameters(¶meters); opj_stream_destroy(l_stream); opj_destroy_codec(l_codec); opj_image_destroy(image); return EXIT_FAILURE; } /* Get the decoded image */ if (!(opj_decode(l_codec, l_stream, image) && opj_end_decompress(l_codec, l_stream))) { fprintf(stderr,"ERROR -> opj_decompress: failed to decode image!\n"); destroy_parameters(¶meters); opj_destroy_codec(l_codec); opj_stream_destroy(l_stream); opj_image_destroy(image); return EXIT_FAILURE; } } else { /* It is just here to illustrate how to use the resolution after set parameters */ /*if (!opj_set_decoded_resolution_factor(l_codec, 5)) { fprintf(stderr, "ERROR -> opj_decompress: failed to set the resolution factor tile!\n"); opj_destroy_codec(l_codec); opj_stream_destroy(l_stream); opj_image_destroy(image); return EXIT_FAILURE; }*/ if (!opj_get_decoded_tile(l_codec, l_stream, image, parameters.tile_index)) { fprintf(stderr, "ERROR -> opj_decompress: failed to decode tile!\n"); destroy_parameters(¶meters); opj_destroy_codec(l_codec); opj_stream_destroy(l_stream); opj_image_destroy(image); return EXIT_FAILURE; } fprintf(stdout, "tile %d is decoded!\n\n", parameters.tile_index); } tCumulative += opj_clock() - t; numDecompressedImages++; /* Close the byte stream */ opj_stream_destroy(l_stream); if( image->color_space != OPJ_CLRSPC_SYCC && image->numcomps == 3 && image->comps[0].dx == image->comps[0].dy && image->comps[1].dx != 1 ) image->color_space = OPJ_CLRSPC_SYCC; else if (image->numcomps <= 2) image->color_space = OPJ_CLRSPC_GRAY; if(image->color_space == OPJ_CLRSPC_SYCC){ color_sycc_to_rgb(image); } else if((image->color_space == OPJ_CLRSPC_CMYK) && (parameters.cod_format != TIF_DFMT)){ color_cmyk_to_rgb(image); } else if(image->color_space == OPJ_CLRSPC_EYCC){ color_esycc_to_rgb(image); } if(image->icc_profile_buf) { #if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2) if(image->icc_profile_len) color_apply_icc_profile(image); else color_cielab_to_rgb(image); #endif free(image->icc_profile_buf); image->icc_profile_buf = NULL; image->icc_profile_len = 0; } /* Force output precision */ /* ---------------------- */ if (parameters.precision != NULL) { OPJ_UINT32 compno; for (compno = 0; compno < image->numcomps; ++compno) { OPJ_UINT32 precno = compno; OPJ_UINT32 prec; if (precno >= parameters.nb_precision) { precno = parameters.nb_precision - 1U; } prec = parameters.precision[precno].prec; if (prec == 0) { prec = image->comps[compno].prec; } switch (parameters.precision[precno].mode) { case OPJ_PREC_MODE_CLIP: clip_component(&(image->comps[compno]), prec); break; case OPJ_PREC_MODE_SCALE: scale_component(&(image->comps[compno]), prec); break; default: break; } } } /* Upsample components */ /* ------------------- */ if (parameters.upsample) { image = upsample_image_components(image); if (image == NULL) { fprintf(stderr, "ERROR -> opj_decompress: failed to upsample image components!\n"); destroy_parameters(¶meters); opj_destroy_codec(l_codec); return EXIT_FAILURE; } } /* Force RGB output */ /* ---------------- */ if (parameters.force_rgb) { switch (image->color_space) { case OPJ_CLRSPC_SRGB: break; case OPJ_CLRSPC_GRAY: image = convert_gray_to_rgb(image); break; default: fprintf(stderr, "ERROR -> opj_decompress: don't know how to convert image to RGB colorspace!\n"); opj_image_destroy(image); image = NULL; break; } if (image == NULL) { fprintf(stderr, "ERROR -> opj_decompress: failed to convert to RGB image!\n"); destroy_parameters(¶meters); opj_destroy_codec(l_codec); return EXIT_FAILURE; } } /* create output image */ /* ------------------- */ switch (parameters.cod_format) { case PXM_DFMT: /* PNM PGM PPM */ if (imagetopnm(image, parameters.outfile, parameters.split_pnm)) { fprintf(stderr,"[ERROR] Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile); } break; case PGX_DFMT: /* PGX */ if(imagetopgx(image, parameters.outfile)){ fprintf(stderr,"[ERROR] Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile); } break; case BMP_DFMT: /* BMP */ if(imagetobmp(image, parameters.outfile)){ fprintf(stderr,"[ERROR] Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile); } break; #ifdef OPJ_HAVE_LIBTIFF case TIF_DFMT: /* TIFF */ if(imagetotif(image, parameters.outfile)){ fprintf(stderr,"[ERROR] Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile); } break; #endif /* OPJ_HAVE_LIBTIFF */ case RAW_DFMT: /* RAW */ if(imagetoraw(image, parameters.outfile)){ fprintf(stderr,"[ERROR] Error generating raw file. Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile); } break; case RAWL_DFMT: /* RAWL */ if(imagetorawl(image, parameters.outfile)){ fprintf(stderr,"[ERROR] Error generating rawl file. Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile); } break; case TGA_DFMT: /* TGA */ if(imagetotga(image, parameters.outfile)){ fprintf(stderr,"[ERROR] Error generating tga file. Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile); } break; #ifdef OPJ_HAVE_LIBPNG case PNG_DFMT: /* PNG */ if(imagetopng(image, parameters.outfile)){ fprintf(stderr,"[ERROR] Error generating png file. Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile); } break; #endif /* OPJ_HAVE_LIBPNG */ /* Can happen if output file is TIFF or PNG * and OPJ_HAVE_LIBTIF or OPJ_HAVE_LIBPNG is undefined */ default: fprintf(stderr,"[ERROR] Outfile %s not generated\n",parameters.outfile); failed = 1; } /* free remaining structures */ if (l_codec) { opj_destroy_codec(l_codec); } /* free image data structure */ opj_image_destroy(image); /* destroy the codestream index */ opj_destroy_cstr_index(&cstr_index); if(failed) remove(parameters.outfile); } destroy_parameters(¶meters); if (numDecompressedImages) { fprintf(stdout, "decode time: %d ms\n", (int)( (tCumulative * 1000.0) / (OPJ_FLOAT64)numDecompressedImages)); } return failed ? EXIT_FAILURE : EXIT_SUCCESS; }
BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) { LLTimer decode_timer; /* Extract metadata */ /* ---------------- */ U8* c_data = base.getData(); size_t c_size = base.getDataSize(); size_t position = 0; while (position < 1024 && position < (c_size - 7)) // the comment field should be in the first 1024 bytes. { if (c_data[position] == 0xff && c_data[position + 1] == 0x64) { U8 high_byte = c_data[position + 2]; U8 low_byte = c_data[position + 3]; S32 c_length = (high_byte * 256) + low_byte; // This size also counts the markers, 00 01 and itself if (c_length > 200) // sanity check { // While comments can be very long, anything longer then 200 is suspect. break; } if (position + 2 + c_length > c_size) { // comment extends past end of data, corruption, or all data not retrived yet. break; } // if the comment block does not end at the end of data, check to see if the next // block starts with 0xFF if (position + 2 + c_length < c_size && c_data[position + 2 + c_length] != 0xff) { // invalied comment block break; } // extract the comment minus the markers, 00 01 raw_image.mComment.assign((char*)c_data + position + 6, c_length - 4); break; } ++position; } opj_dparameters_t parameters; /* decompression parameters */ opj_event_mgr_t event_mgr = { }; /* event manager */ opj_image_t *image = nullptr; opj_dinfo_t* dinfo = nullptr; /* handle to a decompressor */ opj_cio_t *cio = nullptr; /* configure the event callbacks (not required) */ event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); parameters.cp_reduce = base.getRawDiscardLevel(); if(parameters.cp_reduce == 0 && *(U16*)(base.getData() + base.getDataSize() - 2) != 0xD9FF) { bool failed = true; for(S32 i = base.getDataSize()-1; i > 42; --i) { if(base.getData()[i] != 0x00) { failed = *(U16*)(base.getData()+i-1) != 0xD9FF; break; } } if(failed) { opj_image_destroy(image); base.decodeFailed(); return TRUE; } } /* decode the code-stream */ /* ---------------------- */ /* JPEG-2000 codestream */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_J2K); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize()); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); /* close the byte stream */ opj_cio_close(cio); /* free remaining structures */ if(dinfo) { opj_destroy_decompress(dinfo); } // The image decode failed if the return was NULL or the component // count was zero. The latter is just a sanity check before we // dereference the array. if(!image || !image->numcomps) { LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image!" << LL_ENDL; if (image) { opj_image_destroy(image); } base.decodeFailed(); return TRUE; // done } // sometimes we get bad data out of the cache - check to see if the decode succeeded for (S32 i = 0; i < image->numcomps; i++) { if (image->comps[i].factor != base.getRawDiscardLevel()) { // if we didn't get the discard level we're expecting, fail opj_image_destroy(image); base.decodeFailed(); return TRUE; } } if(image->numcomps <= first_channel) { LL_WARNS("Texture") << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << LL_ENDL; if (image) { opj_image_destroy(image); } base.decodeFailed(); return TRUE; } // Copy image data into our raw image format (instead of the separate channel format S32 img_components = image->numcomps; S32 channels = img_components - first_channel; if( channels > max_channel_count ) channels = max_channel_count; // Component buffers are allocated in an image width by height buffer. // The image placed in that buffer is ceil(width/2^factor) by // ceil(height/2^factor) and if the factor isn't zero it will be at the // top left of the buffer with black filled in the rest of the pixels. // It is integer math so the formula is written in ceildivpo2. // (Assuming all the components have the same width, height and // factor.) S32 comp_width = image->comps[0].w; S32 f=image->comps[0].factor; S32 width = ceildivpow2(image->x1 - image->x0, f); S32 height = ceildivpow2(image->y1 - image->y0, f); raw_image.resize(width, height, channels); U8 *rawp = raw_image.getData(); if (!rawp) { opj_image_destroy(image); base.setLastError("Memory error"); base.decodeFailed(); return true; // done } // first_channel is what channel to start copying from // dest is what channel to copy to. first_channel comes from the // argument, dest always starts writing at channel zero. for (S32 comp = first_channel, dest=0; comp < first_channel + channels; comp++, dest++) { if (image->comps[comp].data) { S32 offset = dest; for (S32 y = (height - 1); y >= 0; y--) { for (S32 x = 0; x < width; x++) { rawp[offset] = image->comps[comp].data[y*comp_width + x]; offset += channels; } } } else // Some rare OpenJPEG versions have this bug. { LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL; if (image) { opj_image_destroy(image); } base.decodeFailed(); return TRUE; // done } } /* free image data structure */ opj_image_destroy(image); return TRUE; // done }
struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) { struct ImBuf *ibuf = NULL; bool use_float = false; /* for precision higher then 8 use float */ bool use_alpha = false; long signed_offsets[4] = {0, 0, 0, 0}; int float_divs[4] = {1, 1, 1, 1}; unsigned int i, i_next, w, h, planes; unsigned int y; int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */ int is_jp2, is_j2k; opj_dparameters_t parameters; /* decompression parameters */ opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; opj_dinfo_t *dinfo = NULL; /* handle to a decompressor */ opj_cio_t *cio = NULL; is_jp2 = check_jp2(mem); is_j2k = check_j2k(mem); if (!is_jp2 && !is_j2k) return(NULL); /* both 8, 12 and 16 bit JP2Ks are default to standard byte colorspace */ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); /* configure the event callbacks (not required) */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); /* JPEG 2000 compressed image data */ /* get a decoder handle */ dinfo = opj_create_decompress(is_jp2 ? CODEC_JP2 : CODEC_J2K); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using the current image and user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, mem, size); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); if (!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); return NULL; } /* close the byte stream */ opj_cio_close(cio); if ((image->numcomps * image->x1 * image->y1) == 0) { fprintf(stderr, "\nError: invalid raw image parameters\n"); return NULL; } w = image->comps[0].w; h = image->comps[0].h; switch (image->numcomps) { case 1: /* Grayscale */ case 3: /* Color */ planes = 24; use_alpha = false; break; default: /* 2 or 4 - Grayscale or Color + alpha */ planes = 32; /* grayscale + alpha */ use_alpha = true; break; } i = image->numcomps; if (i > 4) i = 4; while (i) { i--; if (image->comps[i].prec > 8) use_float = true; if (image->comps[i].sgnd) signed_offsets[i] = 1 << (image->comps[i].prec - 1); /* only needed for float images but dosnt hurt to calc this */ float_divs[i] = (1 << image->comps[i].prec) - 1; } ibuf = IMB_allocImBuf(w, h, planes, use_float ? IB_rectfloat : IB_rect); if (ibuf == NULL) { if (dinfo) opj_destroy_decompress(dinfo); return NULL; } ibuf->ftype = JP2; if (is_jp2) ibuf->ftype |= JP2_JP2; else ibuf->ftype |= JP2_J2K; if (use_float) { float *rect_float = ibuf->rect_float; if (image->numcomps < 3) { r = image->comps[0].data; a = (use_alpha) ? image->comps[1].data : NULL; /* grayscale 12bits+ */ if (use_alpha) { a = image->comps[1].data; PIXEL_LOOPER_BEGIN(rect_float) { rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) / float_divs[0]; rect_float[3] = (a[i] + signed_offsets[1]) / float_divs[1]; } PIXEL_LOOPER_END; } else { PIXEL_LOOPER_BEGIN(rect_float) { rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) / float_divs[0]; rect_float[3] = 1.0f; } PIXEL_LOOPER_END; } }
int main(int argc, char *argv[]) { const char * v = opj_version(); const OPJ_COLOR_SPACE color_space = OPJ_CLRSPC_GRAY; unsigned int numcomps = 1; unsigned int i; unsigned int image_width = 256; unsigned int image_height = 256; opj_cparameters_t parameters; unsigned int subsampling_dx; unsigned int subsampling_dy; const char outputfile[] = "testempty2.j2k"; opj_image_cmptparm_t cmptparm; opj_image_t *image; opj_codec_t* l_codec = 00; OPJ_BOOL bSuccess; opj_stream_t *l_stream = 00; (void)argc; (void)argv; opj_set_default_encoder_parameters(¶meters); parameters.cod_format = J2K_CFMT; puts(v); subsampling_dx = (unsigned int)parameters.subsampling_dx; subsampling_dy = (unsigned int)parameters.subsampling_dy; cmptparm.prec = 8; cmptparm.bpp = 8; cmptparm.sgnd = 0; cmptparm.dx = subsampling_dx; cmptparm.dy = subsampling_dy; cmptparm.w = image_width; cmptparm.h = image_height; strncpy(parameters.outfile, outputfile, sizeof(parameters.outfile)-1); image = opj_image_create(numcomps, &cmptparm, color_space); assert( image ); for (i = 0; i < image_width * image_height; i++) { unsigned int compno; for(compno = 0; compno < numcomps; compno++) { image->comps[compno].data[i] = 0; } } /* catch events using our callbacks and give a local context */ opj_set_info_handler(l_codec, info_callback,00); opj_set_warning_handler(l_codec, warning_callback,00); opj_set_error_handler(l_codec, error_callback,00); l_codec = opj_create_compress(OPJ_CODEC_J2K); opj_set_info_handler(l_codec, info_callback,00); opj_set_warning_handler(l_codec, warning_callback,00); opj_set_error_handler(l_codec, error_callback,00); opj_setup_encoder(l_codec, ¶meters, image); l_stream = opj_stream_create_default_file_stream_v3(parameters.outfile,OPJ_FALSE); if( !l_stream ) { fprintf( stderr, "Something went wrong during creation of stream\n" ); opj_destroy_codec(l_codec); opj_image_destroy(image); opj_stream_destroy_v3(l_stream); return 1; } assert(l_stream); bSuccess = opj_start_compress(l_codec,image,l_stream); if( !bSuccess ) { opj_stream_destroy_v3(l_stream); opj_destroy_codec(l_codec); opj_image_destroy(image); return 0; } assert( bSuccess ); bSuccess = opj_encode(l_codec, l_stream); assert( bSuccess ); bSuccess = opj_end_compress(l_codec, l_stream); assert( bSuccess ); opj_stream_destroy_v3(l_stream); opj_destroy_codec(l_codec); opj_image_destroy(image); /* read back the generated file */ { opj_codec_t* d_codec = 00; opj_dparameters_t dparameters; d_codec = opj_create_decompress(OPJ_CODEC_J2K); opj_set_info_handler(d_codec, info_callback,00); opj_set_warning_handler(d_codec, warning_callback,00); opj_set_error_handler(d_codec, error_callback,00); bSuccess = opj_setup_decoder(d_codec, &dparameters); assert( bSuccess ); l_stream = opj_stream_create_default_file_stream_v3(outputfile,1); assert( l_stream ); bSuccess = opj_read_header(l_stream, d_codec, &image); assert( bSuccess ); bSuccess = opj_decode(l_codec, l_stream, image); assert( bSuccess ); bSuccess = opj_end_decompress(l_codec, l_stream); assert( bSuccess ); opj_stream_destroy_v3(l_stream); opj_destroy_codec(d_codec); opj_image_destroy(image); } puts( "end" ); return 0; }
int openjpeg2k_decode_mem(IMG_DAT **oimg_dat, int *lossyflag, unsigned char *idata, const int ilen) { IMG_DAT *img_dat; opj_image_t *image = NULL; opj_event_mgr_t event_mgr; opj_dinfo_t* dinfo = NULL; opj_cio_t *cio = NULL; opj_dparameters_t parameters; opj_codestream_info_t cstr_info; signed char* sgnd_buf = NULL; unsigned char* unsgnd_buf = NULL; int size; /* configure the event handler */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); /* set the decode and encode format */ parameters.decod_format = get_file_format("b.jp2"); parameters.cod_format = get_file_format("a.raw"); /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_JP2); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, idata, ilen); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); if (!image) { fprintf(stderr, "ERROR -> failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); return(-1); } opj_cio_close(cio); if (dinfo) { opj_destroy_decompress(dinfo); } size = image->numcomps * image->comps[0].w * image->comps[0].h; /* only support unsigned jp2 image */ if (image->comps[0].sgnd == 1) { fprintf(stderr, "ERROR -> Can't decode signed buffer!\n"); opj_image_destroy(image); return(-2); } /* allocate buf for the Raw image */ unsgnd_buf = (unsigned char *) malloc(size * sizeof(unsigned char)); /* convert JP2 to Raw */ if (image_to_raw(image, unsgnd_buf)) { fprintf(stderr, "ERROR -> image_to_raw!\n"); opj_image_destroy(image); return(-3); } /* consturct img_dat format */ if ((img_dat_generate_openjpeg(&img_dat, image, unsgnd_buf)) != 0){ free(unsgnd_buf); opj_image_destroy(image); fprintf(stderr, "ERROR : openjpeg2k_decode_mem: failed to generate img_dat\n"); return(-4); } free(unsgnd_buf); opj_image_destroy(image); *oimg_dat = img_dat; *lossyflag = 0; return(0); }
/* -------------------------------------------------------------------------- -------------------- MAIN METHOD, CALLED BY JAVA -----------------------*/ JNIEXPORT jint JNICALL Java_org_openJpeg_OpenJPEGJavaDecoder_internalDecodeJ2KtoImage(JNIEnv *env, jobject obj, jobjectArray javaParameters) { int argc; /* To simulate the command line parameters (taken from the javaParameters variable) and be able to re-use the */ char **argv; /* 'parse_cmdline_decoder' method taken from the j2k_to_image project */ opj_dparameters_t parameters; /* decompression parameters */ img_fol_t img_fol; opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; FILE *fsrc = NULL; unsigned char *src = NULL; int file_length; int num_images; int i,j,imageno; opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ opj_cio_t *cio = NULL; int w,h; long min_value, max_value; short tempS; unsigned char tempUC, tempUC1, tempUC2; /* ==> Access variables to the Java member variables*/ jsize arraySize; jclass cls; jobject object; jboolean isCopy; jfieldID fid; jbyteArray jba; jshortArray jsa; jintArray jia; jbyte *jbBody, *ptrBBody; jshort *jsBody, *ptrSBody; jint *jiBody, *ptrIBody; callback_variables_t msgErrorCallback_vars; /* <=== access variable to Java member variables */ int *ptr, *ptr1, *ptr2; /* <== To transfer the decoded image to Java*/ /* configure the event callbacks */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; /* JNI reference to the calling class*/ cls = (*env)->GetObjectClass(env, obj); /* Pointers to be able to call a Java method for all the info and error messages*/ msgErrorCallback_vars.env = env; msgErrorCallback_vars.jobj = &obj; msgErrorCallback_vars.message_mid = (*env)->GetMethodID(env, cls, "logMessage", "(Ljava/lang/String;)V"); msgErrorCallback_vars.error_mid = (*env)->GetMethodID(env, cls, "logError", "(Ljava/lang/String;)V"); /* Get the String[] containing the parameters, and converts it into a char** to simulate command line arguments.*/ arraySize = (*env)->GetArrayLength(env, javaParameters); argc = (int) arraySize +1; argv = opj_malloc(argc*sizeof(char*)); argv[0] = "ProgramName.exe"; /* The program name: useless*/ j=0; for (i=1; i<argc; i++) { object = (*env)->GetObjectArrayElement(env, javaParameters, i-1); argv[i] = (char*)(*env)->GetStringUTFChars(env, object, &isCopy); } /*printf("C: decoder params = "); for (i=0; i<argc; i++) { printf("[%s]",argv[i]); } printf("\n");*/ /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); parameters.decod_format = J2K_CFMT; /* parse input and get user encoding parameters */ if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol) == 1) { /* Release the Java arguments array*/ for (i=1; i<argc; i++) (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]); return -1; } /* Release the Java arguments array*/ for (i=1; i<argc; i++) (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]); num_images=1; /* Get additional information from the Java object variables*/ fid = (*env)->GetFieldID(env, cls,"skippedResolutions", "I"); parameters.cp_reduce = (short) (*env)->GetIntField(env, obj, fid); /*Decoding image one by one*/ for(imageno = 0; imageno < num_images ; imageno++) { image = NULL; fprintf(stderr,"\n"); /* read the input file and put it in memory into the 'src' object, if the -i option is given in JavaParameters. Implemented for debug purpose. */ /* -------------------------------------------------------------- */ if (parameters.infile && parameters.infile[0]!='\0') { /*printf("C: opening [%s]\n", parameters.infile);*/ fsrc = fopen(parameters.infile, "rb"); if (!fsrc) { fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile); return 1; } fseek(fsrc, 0, SEEK_END); file_length = ftell(fsrc); fseek(fsrc, 0, SEEK_SET); src = (unsigned char *) opj_malloc(file_length); fread(src, 1, file_length, fsrc); fclose(fsrc); /*printf("C: %d bytes read from file\n",file_length);*/ } else { /* Preparing the transfer of the codestream from Java to C*/ /*printf("C: before transfering codestream\n");*/ fid = (*env)->GetFieldID(env, cls,"compressedStream", "[B"); jba = (*env)->GetObjectField(env, obj, fid); file_length = (*env)->GetArrayLength(env, jba); jbBody = (*env)->GetByteArrayElements(env, jba, &isCopy); src = (unsigned char*)jbBody; } /* decode the code-stream */ /* ---------------------- */ switch(parameters.decod_format) { case J2K_CFMT: { /* JPEG-2000 codestream */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_J2K); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); return 1; } /* close the byte stream */ opj_cio_close(cio); } break; case JP2_CFMT: { /* JPEG 2000 compressed image data */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_JP2); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars); /* setup the decoder decoding parameters using the current image and user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); return 1; } /* close the byte stream */ opj_cio_close(cio); } break; case JPT_CFMT: { /* JPEG 2000, JPIP */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_JPT); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); return 1; } /* close the byte stream */ opj_cio_close(cio); } break; default: fprintf(stderr, "skipping file..\n"); continue; } /* free the memory containing the code-stream */ if (parameters.infile && parameters.infile[0]!='\0') { opj_free(src); } else { (*env)->ReleaseByteArrayElements(env, jba, jbBody, 0); } src = NULL; /* create output image. If the -o parameter is given in the JavaParameters, write the decoded version into a file. Implemented for debug purpose. */ /* ---------------------------------- */ switch (parameters.cod_format) { case PXM_DFMT: /* PNM PGM PPM */ if (imagetopnm(image, parameters.outfile)) { fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; case PGX_DFMT: /* PGX */ if(imagetopgx(image, parameters.outfile)){ fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; case BMP_DFMT: /* BMP */ if(imagetobmp(image, parameters.outfile)){ fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; } /* ========= Return the image to the Java structure ===============*/ #ifdef CHECK_THRESHOLDS printf("C: checking thresholds\n"); #endif /* First compute the real with and height, in function of the resolutions decoded.*/ /*wr = (image->comps[0].w + (1 << image->comps[0].factor) -1) >> image->comps[0].factor;*/ /*hr = (image->comps[0].h + (1 << image->comps[0].factor) -1) >> image->comps[0].factor;*/ w = image->comps[0].w; h = image->comps[0].h; if (image->numcomps==3) { /* 3 components color image*/ ptr = image->comps[0].data; ptr1 = image->comps[1].data; ptr2 = image->comps[2].data; #ifdef CHECK_THRESHOLDS if (image->comps[0].sgnd) { min_value = -128; max_value = 127; } else { min_value = 0; max_value = 255; } #endif /* Get the pointer to the Java structure where the data must be copied*/ fid = (*env)->GetFieldID(env, cls,"image24", "[I"); jia = (*env)->GetObjectField(env, obj, fid); jiBody = (*env)->GetIntArrayElements(env, jia, 0); ptrIBody = jiBody; printf("C: transfering image24: %d int to Java pointer=%d\n",image->numcomps*w*h, ptrIBody); for (i=0; i<w*h; i++) { tempUC = (unsigned char)(ptr[i]); tempUC1 = (unsigned char)(ptr1[i]); tempUC2 = (unsigned char)(ptr2[i]); #ifdef CHECK_THRESHOLDS if (tempUC < min_value) tempUC=min_value; else if (tempUC > max_value) tempUC=max_value; if (tempUC1 < min_value) tempUC1=min_value; else if (tempUC1 > max_value) tempUC1=max_value; if (tempUC2 < min_value) tempUC2=min_value; else if (tempUC2 > max_value) tempUC2=max_value; #endif *(ptrIBody++) = (int) ( (tempUC2<<16) + (tempUC1<<8) + tempUC ); } (*env)->ReleaseIntArrayElements(env, jia, jiBody, 0); } else { /* 1 component 8 or 16 bpp image*/ ptr = image->comps[0].data; printf("C: before transfering a %d bpp image to java (length = %d)\n",image->comps[0].prec ,w*h); if (image->comps[0].prec<=8) { fid = (*env)->GetFieldID(env, cls,"image8", "[B"); jba = (*env)->GetObjectField(env, obj, fid); jbBody = (*env)->GetByteArrayElements(env, jba, 0); ptrBBody = jbBody; #ifdef CHECK_THRESHOLDS if (image->comps[0].sgnd) { min_value = -128; max_value = 127; } else { min_value = 0; max_value = 255; } #endif /*printf("C: transfering %d shorts to Java image8 pointer = %d\n", wr*hr,ptrSBody);*/ for (i=0; i<w*h; i++) { tempUC = (unsigned char) (ptr[i]); #ifdef CHECK_THRESHOLDS if (tempUC<min_value) tempUC = min_value; else if (tempUC > max_value) tempUC = max_value; #endif *(ptrBBody++) = tempUC; } (*env)->ReleaseByteArrayElements(env, jba, jbBody, 0); printf("C: image8 transfered to Java\n"); } else { fid = (*env)->GetFieldID(env, cls,"image16", "[S"); jsa = (*env)->GetObjectField(env, obj, fid); jsBody = (*env)->GetShortArrayElements(env, jsa, 0); ptrSBody = jsBody; #ifdef CHECK_THRESHOLDS if (image->comps[0].sgnd) { min_value = -32768; max_value = 32767; } else { min_value = 0; max_value = 65535; } printf("C: minValue = %d, maxValue = %d\n", min_value, max_value); #endif printf("C: transfering %d shorts to Java image16 pointer = %d\n", w*h,ptrSBody); for (i=0; i<w*h; i++) { tempS = (short) (ptr[i]); #ifdef CHECK_THRESHOLDS if (tempS<min_value) { printf("C: value %d truncated to %d\n", tempS, min_value); tempS = min_value; } else if (tempS > max_value) { printf("C: value %d truncated to %d\n", tempS, max_value); tempS = max_value; } #endif *(ptrSBody++) = tempS; } (*env)->ReleaseShortArrayElements(env, jsa, jsBody, 0); printf("C: image16 completely filled\n"); } } /* free remaining structures */ if(dinfo) { opj_destroy_decompress(dinfo); } /* free image data structure */ opj_image_destroy(image); } return 1; /* OK */ }
int GP_ReadJP2Ex(GP_IO *io, GP_Context **rimg, GP_DataStorage *storage, GP_ProgressCallback *callback) { opj_dparameters_t params; opj_codec_t *codec; opj_stream_t *stream; opj_image_t *img; GP_PixelType pixel_type; GP_Context *res = NULL; unsigned int i, x, y; int err = 0, ret = 1; opj_set_default_decoder_parameters(¶ms); codec = opj_create_decompress(OPJ_CODEC_JP2); if (!codec) { GP_DEBUG(1, "opj_create_decompress failed"); err = ENOMEM; goto err0; } opj_set_error_handler(codec, jp2_err_callback, NULL); opj_set_warning_handler(codec, jp2_warn_callback, NULL); opj_set_info_handler(codec, jp2_info_callback, callback); if (!opj_setup_decoder(codec, ¶ms)) { GP_DEBUG(1, "opj_setup_decoder failed"); err = ENOMEM; goto err1; } stream = opj_stream_default_create(OPJ_TRUE); if (!stream) { GP_DEBUG(1, "opj_stream_create_default_file_stream faled"); err = ENOMEM; goto err1; } //TODO: Do we need seek and skip? opj_stream_set_read_function(stream, jp2_io_read); opj_stream_set_user_data(stream, io); if (!opj_read_header(stream, codec, &img)) { GP_DEBUG(1, "opj_read_header failed"); err = EINVAL; goto err2; } if (storage) fill_metadata(img, storage); GP_DEBUG(1, "Have image %ux%u-%ux%u colorspace=%s numcomps=%u", img->x0, img->y0, img->x1, img->y1, color_space_name(img->color_space), img->numcomps); if (!rimg) return 0; /* * Try to match the image information into pixel type. * * Unfortunately the images I had have color_space set * to unspecified yet they were RGB888. */ for (i = 0; i < img->numcomps; i++) { opj_image_comp_t *comp = &img->comps[i]; GP_DEBUG(2, "Component %u %ux%u bpp=%u", i, comp->w, comp->h, comp->prec); if (comp->w != img->comps[0].w || comp->h != img->comps[0].h) { GP_DEBUG(1, "Component %u has different size", 1); err = ENOSYS; goto err3; } if (comp->prec != 8) { GP_DEBUG(1, "Component %u has different bpp", 1); err = ENOSYS; goto err3; } } switch (img->color_space) { case OPJ_CLRSPC_UNSPECIFIED: if (img->numcomps != 3) { GP_DEBUG(1, "Unexpected number of components"); err = ENOSYS; goto err3; } pixel_type = GP_PIXEL_RGB888; break; default: GP_DEBUG(1, "Unsupported colorspace"); err = ENOSYS; goto err3; } GP_ProgressCallbackReport(callback, 0, 100, 100); if (!opj_decode(codec, stream, img)) { GP_DEBUG(1, "opj_decode failed"); err = EINVAL; goto err3; } res = GP_ContextAlloc(img->comps[0].w, img->comps[0].h, pixel_type); if (!res) { GP_DEBUG(1, "Malloc failed :("); err = ENOMEM; goto err3; } for (y = 0; y < res->h; y++) { for (x = 0; x < res->w; x++) { i = y * res->w + x; GP_Pixel p = img->comps[0].data[i] << 16| img->comps[1].data[i] << 8 | img->comps[2].data[i]; GP_PutPixel_Raw_24BPP(res, x, y, p); } } GP_ProgressCallbackDone(callback); *rimg = res; ret = 0; err3: opj_image_destroy(img); err2: opj_stream_destroy(stream); err1: opj_destroy_codec(codec); err0: if (err) errno = err; return ret; }
bool _openslide_jp2k_decode_buffer(uint32_t *dest, int32_t w, int32_t h, void *data, int32_t datalen, enum _openslide_jp2k_colorspace space, GError **err) { GError *tmp_err = NULL; bool success = false; // opj_cio_open interprets a NULL buffer as opening for write g_assert(data != NULL); // init decompressor opj_cio_t *stream = NULL; opj_dinfo_t *dinfo = NULL; opj_image_t *image = NULL; // note: don't use info_handler, it outputs lots of junk opj_event_mgr_t event_callbacks = { .error_handler = error_callback, .warning_handler = warning_callback, }; opj_dparameters_t parameters; dinfo = opj_create_decompress(CODEC_J2K); opj_set_default_decoder_parameters(¶meters); opj_setup_decoder(dinfo, ¶meters); stream = opj_cio_open((opj_common_ptr) dinfo, data, datalen); opj_set_event_mgr((opj_common_ptr) dinfo, &event_callbacks, &tmp_err); // decode image = opj_decode(dinfo, stream); // check error if (tmp_err) { g_propagate_error(err, tmp_err); goto DONE; } // sanity check if (image->numcomps != 3) { g_set_error(err, OPENSLIDE_ERROR, OPENSLIDE_ERROR_FAILED, "image->numcomps != 3"); goto DONE; } // TODO more checks? unpack_argb(space, image->comps, dest, w, h); success = true; DONE: if (image) { opj_image_destroy(image); } if (stream) { opj_cio_close(stream); } if (dinfo) { opj_destroy_decompress(dinfo); } return success; }
BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base) { // // FIXME: We get metadata by decoding the ENTIRE image. // // Update the raw discard level base.updateRawDiscardLevel(); opj_dparameters_t parameters; /* decompression parameters */ opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ opj_cio_t *cio = NULL; /* configure the event callbacks (not required) */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); // Only decode what's required to get the size data. parameters.cp_limit_decoding=LIMIT_TO_MAIN_HEADER; //parameters.cp_reduce = mRawDiscardLevel; /* decode the code-stream */ /* ---------------------- */ /* JPEG-2000 codestream */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_J2K); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize()); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); /* close the byte stream */ opj_cio_close(cio); /* free remaining structures */ if(dinfo) { opj_destroy_decompress(dinfo); } if(!image) { llwarns << "ERROR -> getMetadata: failed to decode image!" << llendl; return FALSE; } // Copy image data into our raw image format (instead of the separate channel format S32 width = 0; S32 height = 0; S32 img_components = image->numcomps; width = image->x1 - image->x0; height = image->y1 - image->y0; base.setSize(width, height, img_components); /* free image data structure */ opj_image_destroy(image); return TRUE; }
bool ossim::opj_decode( std::ifstream* in, const ossimIrect& rect, ossim_uint32 resLevel, ossim_int32 format, // OPJ_CODEC_FORMAT std::streamoff fileOffset, ossimImageData* tile) { static const char MODULE[] = "ossimOpjDecoder::decode"; bool status = false; if ( traceDebug() ) { ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << "entered...\nrect: " << rect << "\nresLevel: " << resLevel << std::endl; } // Need to check for NAN in rect if ( in && tile && !rect.hasNans()) { in->seekg( fileOffset, std::ios_base::beg ); opj_dparameters_t param; opj_codec_t* codec = 0; opj_image_t* image = 0;; opj_stream_t* stream = 0; opj_user_istream* userStream = new opj_user_istream(); userStream->m_str = in; userStream->m_offset = fileOffset; /* Set the length to avoid an assert */ in->seekg(0, std::ios_base::end); // Fix: length must be passed in for nift blocks. userStream->m_length = in->tellg(); // Set back to front: in->clear(); in->seekg(fileOffset, std::ios_base::beg); stream = opj_stream_default_create(OPJ_TRUE); if (!stream) { opj_stream_destroy(stream); std::string errMsg = MODULE; errMsg += " ERROR: opj_setup_decoder failed!"; throw ossimException(errMsg); } opj_stream_set_read_function(stream, ossim_opj_istream_read); opj_stream_set_skip_function(stream, ossim_opj_istream_skip); opj_stream_set_seek_function(stream, ossim_opj_istream_seek); // Fix: length must be passed in for nift blocks. opj_stream_set_user_data_length(stream, userStream->m_length); opj_stream_set_user_data(stream, userStream, ossim_opj_free_user_istream_data); opj_stream_set_user_data_length(stream, userStream->m_length); /* Set the default decoding parameters */ opj_set_default_decoder_parameters(¶m); param.decod_format = format; /** you may here add custom decoding parameters */ /* do not use layer decoding limitations */ param.cp_layer = 0; /* do not use resolutions reductions */ param.cp_reduce = resLevel; codec = opj_create_decompress( (CODEC_FORMAT)format ); // catch events using our callbacks and give a local context //opj_set_info_handler (codec, ossim::opj_info_callback, 00); opj_set_info_handler (codec, NULL, 00); opj_set_warning_handler(codec, ossim::opj_warning_callback,00); opj_set_error_handler (codec, ossim::opj_error_callback, 00); // Setup the decoder decoding parameters using user parameters if ( opj_setup_decoder(codec, ¶m) == false ) { opj_stream_destroy(stream); opj_destroy_codec(codec); std::string errMsg = MODULE; errMsg += " ERROR: opj_setup_decoder failed!"; throw ossimException(errMsg); } // Read the main header of the codestream and if necessary the JP2 boxes. if ( opj_read_header(stream, codec, &image) == false ) { opj_stream_destroy(stream); opj_destroy_codec(codec); opj_image_destroy(image); std::string errMsg = MODULE; errMsg += " ERROR: opj_read_header failed!"; throw ossimException(errMsg); } // tmp drb: // opj_stream_destroy(stream); // return; if ( opj_set_decoded_resolution_factor(codec, resLevel) == false) { opj_stream_destroy(stream); opj_destroy_codec(codec); opj_image_destroy(image); std::string errMsg = MODULE; errMsg += " ERROR: opj_set_decoded_resolution_factor failed!"; throw ossimException(errMsg); } //ossim_float32 res = resLevel; ossimIrect resRect = rect * (1 << resLevel); //std::cout << "resRect.ul(): " << resRect.ul() // << "\nresRect.lr(): " << resRect.lr() // << std::endl; // if ( opj_set_decode_area(codec, image, rect.ul().x, rect.ul().y, // rect.lr().x+1, rect.lr().y+1) == false ) if ( opj_set_decode_area(codec, image, resRect.ul().x, resRect.ul().y, resRect.lr().x+1, resRect.lr().y+1) == false ) { opj_stream_destroy(stream); opj_destroy_codec(codec); opj_image_destroy(image); std::string errMsg = MODULE; errMsg += " ERROR: opj_set_decode_area failed!"; throw ossimException(errMsg); } // Get the decoded image: if ( opj_decode(codec, stream, image) == false ) { opj_stream_destroy(stream); opj_destroy_codec(codec); opj_image_destroy(image); std::string errMsg = MODULE; errMsg += " ERROR: opj_decode failed!"; throw ossimException(errMsg); } // ossim::print(std::cout, *image); if(image->icc_profile_buf) { #if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2) color_apply_icc_profile(image); /* FIXME */ #endif free(image->icc_profile_buf); image->icc_profile_buf = NULL; image->icc_profile_len = 0; } status = ossim::copyOpjImage(image, tile); #if 0 ossim_uint32 tile_index = 0; ossim_uint32 data_size = 0; ossim_int32 current_tile_x0 = 0; ossim_int32 current_tile_y0 = 0; ossim_int32 current_tile_x1 = 0; ossim_int32 current_tile_y1 = 0; ossim_uint32 nb_comps = 0; OPJ_BOOL go_on = 1; if ( opj_read_tile_header( codec, stream, &tile_index, &data_size, ¤t_tile_x0, ¤t_tile_y0, ¤t_tile_x1, ¤t_tile_y1, &nb_comps, &go_on) == false ) { opj_stream_destroy(stream); opj_destroy_codec(codec); opj_image_destroy(image); std::string errMsg = MODULE; errMsg += " ERROR: opj_read_tile_header failed!"; throw ossimException(errMsg); } #endif #if 0 std::cout << "tile_index: " << tile_index << "\ndata_size: " << data_size << "\ncurrent_tile_x0: " << current_tile_x0 << "\ncurrent_tile_y0: " << current_tile_y0 << "\ncurrent_tile_x1: " << current_tile_x1 << "\ncurrent_tile_y1: " << current_tile_y1 << "\nnb_comps: " << nb_comps << std::endl; #endif #if 0 if ( opj_decode_tile_data(codec, tile_index,l_data,l_data_size,l_stream) == false) { opj_stream_destroy(l_stream); opj_destroy_codec(l_codec); opj_image_destroy(l_image); std::string errMsg = MODULE; errMsg += " ERROR: opj_read_tile_header failed!"; throw ossimException(errMsg); } #endif #if 0 if (opj_end_decompress(codec,stream) == false ) { opj_stream_destroy(stream); opj_destroy_codec(codec); opj_image_destroy(image); std::string errMsg = MODULE; errMsg += " ERROR: opj_end_decompress failed!"; throw ossimException(errMsg); } #endif /* Free memory */ opj_stream_destroy(stream); opj_destroy_codec(codec); opj_image_destroy(image); // Tmp drb: if ( in->eof() ) { in->clear(); } in->seekg(fileOffset, std::ios_base::beg ); } // Matches: if ( in && tile ) return status; } // End: ossim::opj_decode( ... )
struct redcode_frame_raw * redcode_decode_video_raw( struct redcode_frame * frame, int scale) { struct redcode_frame_raw * rv = NULL; opj_dparameters_t parameters; /* decompression parameters */ opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ opj_cio_t *cio = NULL; memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; opj_set_default_decoder_parameters(¶meters); parameters.decod_format = JP2_CFMT; if (scale == 2) { parameters.cp_reduce = 1; } else if (scale == 4) { parameters.cp_reduce = 2; } else if (scale == 8) { parameters.cp_reduce = 3; } /* JPEG 2000 compressed image data */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_JP2); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using the current image and user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, frame->data + frame->offset, frame->length); image = opj_decode(dinfo, cio); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); return 0; } /* close the byte stream */ opj_cio_close(cio); /* free remaining structures */ if(dinfo) { opj_destroy_decompress(dinfo); } if((image->numcomps * image->x1 * image->y1) == 0) { opj_image_destroy(image); return 0; } rv = (struct redcode_frame_raw *) calloc( 1, sizeof(struct redcode_frame_raw)); rv->data = image; rv->width = image->comps[0].w; rv->height = image->comps[0].h; return rv; }
/* -------------------------------------------------------------------------- */ int main(int argc, char **argv) { FILE *fsrc = NULL; opj_dparameters_t parameters; /* decompression parameters */ opj_image_t* image = NULL; opj_stream_t *l_stream = NULL; /* Stream */ opj_codec_t* l_codec = NULL; /* Handle to a decompressor */ opj_codestream_index_t* cstr_index = NULL; char indexfilename[OPJ_PATH_LEN]; /* index file name */ OPJ_INT32 num_images, imageno; img_fol_t img_fol; dircnt_t *dirptr = NULL; int failed = 0; /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); /* FIXME Initialize indexfilename and img_fol */ *indexfilename = 0; /* Initialize img_fol */ memset(&img_fol,0,sizeof(img_fol_t)); /* parse input and get user encoding parameters */ if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) { return EXIT_FAILURE; } /* Initialize reading of directory */ if(img_fol.set_imgdir==1){ int it_image; num_images=get_num_images(img_fol.imgdirpath); dirptr=(dircnt_t*)malloc(sizeof(dircnt_t)); if(dirptr){ dirptr->filename_buf = (char*)malloc((size_t)num_images*OPJ_PATH_LEN*sizeof(char)); /* Stores at max 10 image file names*/ dirptr->filename = (char**) malloc((size_t)num_images*sizeof(char*)); if(!dirptr->filename_buf){ return EXIT_FAILURE; } for(it_image=0;it_image<num_images;it_image++){ dirptr->filename[it_image] = dirptr->filename_buf + it_image*OPJ_PATH_LEN; } } if(load_images(dirptr,img_fol.imgdirpath)==1){ return EXIT_FAILURE; } if (num_images==0){ fprintf(stdout,"Folder is empty\n"); return EXIT_FAILURE; } }else{ num_images=1; } /*Decoding image one by one*/ for(imageno = 0; imageno < num_images ; imageno++) { fprintf(stderr,"\n"); if(img_fol.set_imgdir==1){ if (get_next_file(imageno, dirptr,&img_fol, ¶meters)) { fprintf(stderr,"skipping file...\n"); continue; } } /* read the input file and put it in memory */ /* ---------------------------------------- */ fsrc = fopen(parameters.infile, "rb"); if (!fsrc) { fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile); return EXIT_FAILURE; } l_stream = opj_stream_create_default_file_stream(fsrc,1); if (!l_stream){ fclose(fsrc); fprintf(stderr, "ERROR -> failed to create the stream from the file\n"); return EXIT_FAILURE; } /* decode the JPEG2000 stream */ /* ---------------------- */ switch(parameters.decod_format) { case J2K_CFMT: /* JPEG-2000 codestream */ { /* Get a decoder handle */ l_codec = opj_create_decompress(OPJ_CODEC_J2K); break; } case JP2_CFMT: /* JPEG 2000 compressed image data */ { /* Get a decoder handle */ l_codec = opj_create_decompress(OPJ_CODEC_JP2); break; } case JPT_CFMT: /* JPEG 2000, JPIP */ { /* Get a decoder handle */ l_codec = opj_create_decompress(OPJ_CODEC_JPT); break; } default: fprintf(stderr, "skipping file..\n"); opj_stream_destroy(l_stream); continue; } /* catch events using our callbacks and give a local context */ opj_set_info_handler(l_codec, info_callback,00); opj_set_warning_handler(l_codec, warning_callback,00); opj_set_error_handler(l_codec, error_callback,00); /* Setup the decoder decoding parameters using user parameters */ if ( !opj_setup_decoder(l_codec, ¶meters) ){ fprintf(stderr, "ERROR -> opj_compress: failed to setup the decoder\n"); opj_stream_destroy(l_stream); fclose(fsrc); opj_destroy_codec(l_codec); return EXIT_FAILURE; } /* Read the main header of the codestream and if necessary the JP2 boxes*/ if(! opj_read_header(l_stream, l_codec, &image)){ fprintf(stderr, "ERROR -> opj_decompress: failed to read the header\n"); opj_stream_destroy(l_stream); fclose(fsrc); opj_destroy_codec(l_codec); opj_image_destroy(image); return EXIT_FAILURE; } if (!parameters.nb_tile_to_decode) { /* Optional if you want decode the entire image */ if (!opj_set_decode_area(l_codec, image, (OPJ_INT32)parameters.DA_x0, (OPJ_INT32)parameters.DA_y0, (OPJ_INT32)parameters.DA_x1, (OPJ_INT32)parameters.DA_y1)){ fprintf(stderr, "ERROR -> opj_decompress: failed to set the decoded area\n"); opj_stream_destroy(l_stream); opj_destroy_codec(l_codec); opj_image_destroy(image); fclose(fsrc); return EXIT_FAILURE; } /* Get the decoded image */ if (!(opj_decode(l_codec, l_stream, image) && opj_end_decompress(l_codec, l_stream))) { fprintf(stderr,"ERROR -> opj_decompress: failed to decode image!\n"); opj_destroy_codec(l_codec); opj_stream_destroy(l_stream); opj_image_destroy(image); fclose(fsrc); return EXIT_FAILURE; } } else { /* It is just here to illustrate how to use the resolution after set parameters */ /*if (!opj_set_decoded_resolution_factor(l_codec, 5)) { fprintf(stderr, "ERROR -> opj_decompress: failed to set the resolution factor tile!\n"); opj_destroy_codec(l_codec); opj_stream_destroy(l_stream); opj_image_destroy(image); fclose(fsrc); return EXIT_FAILURE; }*/ if (!opj_get_decoded_tile(l_codec, l_stream, image, parameters.tile_index)) { fprintf(stderr, "ERROR -> opj_decompress: failed to decode tile!\n"); opj_destroy_codec(l_codec); opj_stream_destroy(l_stream); opj_image_destroy(image); fclose(fsrc); return EXIT_FAILURE; } fprintf(stdout, "tile %d is decoded!\n\n", parameters.tile_index); } /* Close the byte stream */ opj_stream_destroy(l_stream); fclose(fsrc); if(image->color_space == OPJ_CLRSPC_SYCC){ color_sycc_to_rgb(image); /* FIXME */ } if( image->color_space != OPJ_CLRSPC_SYCC && image->numcomps == 3 && image->comps[0].dx == image->comps[0].dy && image->comps[1].dx != 1 ) image->color_space = OPJ_CLRSPC_SYCC; else if (image->numcomps <= 2) image->color_space = OPJ_CLRSPC_GRAY; if(image->icc_profile_buf) { #if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2) color_apply_icc_profile(image); /* FIXME */ #endif free(image->icc_profile_buf); image->icc_profile_buf = NULL; image->icc_profile_len = 0; } /* create output image */ /* ------------------- */ switch (parameters.cod_format) { case PXM_DFMT: /* PNM PGM PPM */ if (imagetopnm(image, parameters.outfile)) { fprintf(stderr,"Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; case PGX_DFMT: /* PGX */ if(imagetopgx(image, parameters.outfile)){ fprintf(stderr,"Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; case BMP_DFMT: /* BMP */ if(imagetobmp(image, parameters.outfile)){ fprintf(stderr,"Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; #ifdef OPJ_HAVE_LIBTIFF case TIF_DFMT: /* TIFF */ if(imagetotif(image, parameters.outfile)){ fprintf(stderr,"Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; #endif /* OPJ_HAVE_LIBTIFF */ case RAW_DFMT: /* RAW */ if(imagetoraw(image, parameters.outfile)){ fprintf(stderr,"Error generating raw file. Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile); } break; case RAWL_DFMT: /* RAWL */ if(imagetorawl(image, parameters.outfile)){ fprintf(stderr,"Error generating rawl file. Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile); } break; case TGA_DFMT: /* TGA */ if(imagetotga(image, parameters.outfile)){ fprintf(stderr,"Error generating tga file. Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile); } break; #ifdef OPJ_HAVE_LIBPNG case PNG_DFMT: /* PNG */ if(imagetopng(image, parameters.outfile)){ fprintf(stderr,"Error generating png file. Outfile %s not generated\n",parameters.outfile); failed = 1; } else { fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile); } break; #endif /* OPJ_HAVE_LIBPNG */ /* Can happen if output file is TIFF or PNG * and OPJ_HAVE_LIBTIF or OPJ_HAVE_LIBPNG is undefined */ default: fprintf(stderr,"Outfile %s not generated\n",parameters.outfile); failed = 1; } /* free remaining structures */ if (l_codec) { opj_destroy_codec(l_codec); } /* free image data structure */ opj_image_destroy(image); /* destroy the codestream index */ opj_destroy_cstr_index(&cstr_index); } return failed ? EXIT_FAILURE : EXIT_SUCCESS; }
static FIBITMAP * DLL_CALLCONV Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { J2KFIO_t *fio = (J2KFIO_t*)data; if (handle && fio) { opj_codec_t *d_codec = NULL; // handle to a decompressor opj_dparameters_t parameters; // decompression parameters opj_image_t *image = NULL; // decoded image FIBITMAP *dib = NULL; // check the file format if(!Validate(io, handle)) { return NULL; } BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS; // get the OpenJPEG stream opj_stream_t *d_stream = fio->stream; // set decoding parameters to default values opj_set_default_decoder_parameters(¶meters); try { // decode the JPEG-2000 codestream // get a decoder handle d_codec = opj_create_decompress(OPJ_CODEC_J2K); // configure the event callbacks // catch events using our callbacks (no local context needed here) opj_set_info_handler(d_codec, NULL, NULL); opj_set_warning_handler(d_codec, j2k_warning_callback, NULL); opj_set_error_handler(d_codec, j2k_error_callback, NULL); // setup the decoder decoding parameters using user parameters if( !opj_setup_decoder(d_codec, ¶meters) ) { throw "Failed to setup the decoder\n"; } // read the main header of the codestream and if necessary the JP2 boxes if( !opj_read_header(d_stream, d_codec, &image)) { throw "Failed to read the header\n"; } // --- header only mode if (header_only) { // create output image dib = J2KImageToFIBITMAP(s_format_id, image, header_only); if(!dib) { throw "Failed to import JPEG2000 image"; } // clean-up and return header data opj_destroy_codec(d_codec); opj_image_destroy(image); return dib; } // decode the stream and fill the image structure if( !( opj_decode(d_codec, d_stream, image) && opj_end_decompress(d_codec, d_stream) ) ) { throw "Failed to decode image!\n"; } // free the codec context opj_destroy_codec(d_codec); d_codec = NULL; // create output image dib = J2KImageToFIBITMAP(s_format_id, image, header_only); if(!dib) { throw "Failed to import JPEG2000 image"; } // free image data structure opj_image_destroy(image); return dib; } catch (const char *text) { if(dib) { FreeImage_Unload(dib); } // free remaining structures opj_destroy_codec(d_codec); opj_image_destroy(image); FreeImage_OutputMessageProc(s_format_id, text); return NULL; } } return NULL; }
BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) { // // FIXME: Get the comment field out of the texture // LLTimer decode_timer; opj_dparameters_t parameters; /* decompression parameters */ opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ opj_cio_t *cio = NULL; /* configure the event callbacks (not required) */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); parameters.cp_reduce = base.getRawDiscardLevel(); /* decode the code-stream */ /* ---------------------- */ /* JPEG-2000 codestream */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_J2K); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize()); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); /* close the byte stream */ opj_cio_close(cio); /* free remaining structures */ if(dinfo) { opj_destroy_decompress(dinfo); } // The image decode failed if the return was NULL or the component // count was zero. The latter is just a sanity check before we // dereference the array. if(!image || !image->numcomps) { LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image!" << LL_ENDL; if (image) { opj_image_destroy(image); } return TRUE; // done } // sometimes we get bad data out of the cache - check to see if the decode succeeded for (S32 i = 0; i < image->numcomps; i++) { if (image->comps[i].factor != base.getRawDiscardLevel()) { // if we didn't get the discard level we're expecting, fail opj_image_destroy(image); base.mDecoding = FALSE; return TRUE; } } if(image->numcomps <= first_channel) { llwarns << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << llendl; if (image) { opj_image_destroy(image); } return TRUE; } // Copy image data into our raw image format (instead of the separate channel format S32 img_components = image->numcomps; S32 channels = img_components - first_channel; if( channels > max_channel_count ) channels = max_channel_count; // Component buffers are allocated in an image width by height buffer. // The image placed in that buffer is ceil(width/2^factor) by // ceil(height/2^factor) and if the factor isn't zero it will be at the // top left of the buffer with black filled in the rest of the pixels. // It is integer math so the formula is written in ceildivpo2. // (Assuming all the components have the same width, height and // factor.) S32 comp_width = image->comps[0].w; S32 f=image->comps[0].factor; S32 width = ceildivpow2(image->x1 - image->x0, f); S32 height = ceildivpow2(image->y1 - image->y0, f); raw_image.resize(width, height, channels); U8 *rawp = raw_image.getData(); // first_channel is what channel to start copying from // dest is what channel to copy to. first_channel comes from the // argument, dest always starts writing at channel zero. for (S32 comp = first_channel, dest=0; comp < first_channel + channels; comp++, dest++) { if (image->comps[comp].data) { S32 offset = dest; for (S32 y = (height - 1); y >= 0; y--) { for (S32 x = 0; x < width; x++) { rawp[offset] = image->comps[comp].data[y*comp_width + x]; offset += channels; } } } else // Some rare OpenJPEG versions have this bug. { LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL; opj_image_destroy(image); return TRUE; // done } } /* free image data structure */ opj_image_destroy(image); return TRUE; // done }
int main(int argc, char *argv[]) { opj_dparameters_t parameters; /* decompression parameters */ img_fol_t img_fol; opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; FILE *fsrc = NULL, *fout = NULL; unsigned char *src = NULL; int file_length; int num_images; int i,imageno; dircnt_t *dirptr = NULL; opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ opj_cio_t *cio = NULL; opj_codestream_info_t cstr_info; /* Codestream information structure */ char indexfilename[OPJ_PATH_LEN]; /* index file name */ /* configure the event callbacks (not required) */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); /* Initialize indexfilename and img_fol */ *indexfilename = 0; memset(&img_fol,0,sizeof(img_fol_t)); /* parse input and get user encoding parameters */ if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) { return 1; } /* Initialize reading of directory */ if(img_fol.set_imgdir==1){ num_images=get_num_images(img_fol.imgdirpath); dirptr=(dircnt_t*)malloc(sizeof(dircnt_t)); if(dirptr){ dirptr->filename_buf = (char*)malloc(num_images*OPJ_PATH_LEN*sizeof(char)); /* Stores at max 10 image file names*/ dirptr->filename = (char**) malloc(num_images*sizeof(char*)); if(!dirptr->filename_buf){ return 1; } for(i=0;i<num_images;i++){ dirptr->filename[i] = dirptr->filename_buf + i*OPJ_PATH_LEN; } } if(load_images(dirptr,img_fol.imgdirpath)==1){ return 1; } if (num_images==0){ fprintf(stdout,"Folder is empty\n"); return 1; } }else{ num_images=1; } /* */ if (parameters.outfile[0] != 0) { fout = fopen(parameters.outfile,"w"); if (!fout) { fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.outfile); return 1; } } else fout = stdout; /*Encoding image one by one*/ for(imageno = 0; imageno < num_images ; imageno++) { image = NULL; fprintf(stderr,"\n"); if(img_fol.set_imgdir==1){ if (get_next_file(imageno, dirptr,&img_fol, ¶meters)) { fprintf(stderr,"skipping file...\n"); continue; } } /* read the input file and put it in memory */ /* ---------------------------------------- */ fsrc = fopen(parameters.infile, "rb"); if (!fsrc) { fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile); return 1; } fseek(fsrc, 0, SEEK_END); file_length = ftell(fsrc); fseek(fsrc, 0, SEEK_SET); src = (unsigned char *) malloc(file_length); if (fread(src, 1, file_length, fsrc) != (size_t)file_length) { free(src); fclose(fsrc); fclose(fout); fprintf(stderr, "\nERROR: fread return a number of element different from the expected.\n"); return 1; } fclose(fsrc); /* decode the code-stream */ /* ---------------------- */ switch(parameters.decod_format) { case J2K_CFMT: { /* JPEG-2000 codestream */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_J2K); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ if (*indexfilename) /* If need to extract codestream information*/ image = opj_decode_with_info(dinfo, cio, &cstr_info); else image = opj_decode(dinfo, cio); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); fclose(fout); free(src); return 1; } /* dump image */ j2k_dump_image(fout, image); /* dump cp */ j2k_dump_cp(fout, image, ((opj_j2k_t*)dinfo->j2k_handle)->cp); /* close the byte stream */ opj_cio_close(cio); /* Write the index to disk */ if (*indexfilename) { opj_bool bSuccess; bSuccess = write_index_file(&cstr_info, indexfilename); if (bSuccess) { fprintf(stderr, "Failed to output index file\n"); } } } break; case JP2_CFMT: { /* JPEG 2000 compressed image data */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_JP2); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using the current image and user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ if (*indexfilename) /* If need to extract codestream information*/ image = opj_decode_with_info(dinfo, cio, &cstr_info); else image = opj_decode(dinfo, cio); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); fclose(fout); free(src); return 1; } /* dump image */ if(image->icc_profile_buf) { free(image->icc_profile_buf); image->icc_profile_buf = NULL; } j2k_dump_image(fout, image); /* dump cp */ j2k_dump_cp(fout, image, ((opj_jp2_t*)dinfo->jp2_handle)->j2k->cp); /* close the byte stream */ opj_cio_close(cio); /* Write the index to disk */ if (*indexfilename) { opj_bool bSuccess; bSuccess = write_index_file(&cstr_info, indexfilename); if (bSuccess) { fprintf(stderr, "Failed to output index file\n"); } } } break; case JPT_CFMT: { /* JPEG 2000, JPIP */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_JPT); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ if (*indexfilename) /* If need to extract codestream information*/ image = opj_decode_with_info(dinfo, cio, &cstr_info); else image = opj_decode(dinfo, cio); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); fclose(fout); free(src); return 1; } /* close the byte stream */ opj_cio_close(cio); /* Write the index to disk */ if (*indexfilename) { opj_bool bSuccess; bSuccess = write_index_file(&cstr_info, indexfilename); if (bSuccess) { fprintf(stderr, "Failed to output index file\n"); } } } break; default: fprintf(stderr, "skipping file..\n"); continue; } /* free the memory containing the code-stream */ free(src); src = NULL; /* free remaining structures */ if(dinfo) { opj_destroy_decompress(dinfo); } /* free codestream information structure */ if (*indexfilename) opj_destroy_cstr_info(&cstr_info); /* free image data structure */ opj_image_destroy(image); } fclose(fout); return EXIT_SUCCESS; }
static FIBITMAP * DLL_CALLCONV Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { if (handle) { opj_dparameters_t parameters; // decompression parameters opj_event_mgr_t event_mgr; // event manager opj_image_t *image = NULL; // decoded image BYTE *src = NULL; long file_length; opj_dinfo_t* dinfo = NULL; // handle to a decompressor opj_cio_t *cio = NULL; FIBITMAP *dib = NULL; // check the file format if(!Validate(io, handle)) { return NULL; } // configure the event callbacks memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = jp2_error_callback; event_mgr.warning_handler = jp2_warning_callback; event_mgr.info_handler = NULL; // set decoding parameters to default values opj_set_default_decoder_parameters(¶meters); try { // read the input file and put it in memory long start_pos = io->tell_proc(handle); io->seek_proc(handle, 0, SEEK_END); file_length = io->tell_proc(handle) - start_pos; io->seek_proc(handle, start_pos, SEEK_SET); src = (BYTE*)malloc(file_length * sizeof(BYTE)); if(!src) { throw FI_MSG_ERROR_MEMORY; } if(io->read_proc(src, 1, file_length, handle) < 1) { throw "Error while reading input stream"; } // decode the JPEG-2000 file // get a decoder handle dinfo = opj_create_decompress(CODEC_JP2); // catch events using our callbacks opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, NULL); // setup the decoder decoding parameters using user parameters opj_setup_decoder(dinfo, ¶meters); // open a byte stream cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); // decode the stream and fill the image structure image = opj_decode(dinfo, cio); if(!image) { throw "Failed to decode image!\n"; } // close the byte stream opj_cio_close(cio); cio = NULL; // free the memory containing the code-stream free(src); src = NULL; // free the codec context opj_destroy_decompress(dinfo); // create output image dib = J2KImageToFIBITMAP(s_format_id, image); if(!dib) throw "Failed to import JPEG2000 image"; // free image data structure opj_image_destroy(image); return dib; } catch (const char *text) { if(src) free(src); if(dib) FreeImage_Unload(dib); // free remaining structures opj_destroy_decompress(dinfo); opj_image_destroy(image); // close the byte stream if(cio) opj_cio_close(cio); FreeImage_OutputMessageProc(s_format_id, text); return NULL; } } return NULL; }
int main(int argc, char **argv) { opj_dparameters_t parameters; /* decompression parameters */ img_fol_t img_fol; opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; FILE *fsrc = NULL; unsigned char *src = NULL; int file_length; int num_images; int i,imageno; dircnt_t *dirptr = NULL; opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ opj_cio_t *cio = NULL; opj_codestream_info_t cstr_info; /* Codestream information structure */ char indexfilename[OPJ_PATH_LEN]; /* index file name */ /* configure the event callbacks (not required) */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); /* Initialize indexfilename and img_fol */ *indexfilename = 0; memset(&img_fol,0,sizeof(img_fol_t)); /* parse input and get user encoding parameters */ if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) { return 1; } /* Initialize reading of directory */ if(img_fol.set_imgdir==1){ num_images=get_num_images(img_fol.imgdirpath); dirptr=(dircnt_t*)malloc(sizeof(dircnt_t)); if(dirptr){ dirptr->filename_buf = (char*)malloc(num_images*OPJ_PATH_LEN*sizeof(char)); /* Stores at max 10 image file names*/ dirptr->filename = (char**) malloc(num_images*sizeof(char*)); if(!dirptr->filename_buf){ return 1; } for(i=0;i<num_images;i++){ dirptr->filename[i] = dirptr->filename_buf + i*OPJ_PATH_LEN; } } if(load_images(dirptr,img_fol.imgdirpath)==1){ return 1; } if (num_images==0){ fprintf(stdout,"Folder is empty\n"); return 1; } }else{ num_images=1; } /*Encoding image one by one*/ for(imageno = 0; imageno < num_images ; imageno++) { image = NULL; fprintf(stderr,"\n"); if(img_fol.set_imgdir==1){ if (get_next_file(imageno, dirptr,&img_fol, ¶meters)) { fprintf(stderr,"skipping file...\n"); continue; } } /* read the input file and put it in memory */ /* ---------------------------------------- */ fsrc = fopen(parameters.infile, "rb"); if (!fsrc) { fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile); return 1; } fseek(fsrc, 0, SEEK_END); file_length = ftell(fsrc); fseek(fsrc, 0, SEEK_SET); src = (unsigned char *) malloc(file_length); if (fread(src, 1, file_length, fsrc) != (size_t)file_length) { free(src); fclose(fsrc); fprintf(stderr, "\nERROR: fread return a number of element different from the expected.\n"); return 1; } fclose(fsrc); /* decode the code-stream */ /* ---------------------- */ switch(parameters.decod_format) { case J2K_CFMT: { /* JPEG-2000 codestream */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_J2K); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ if (*indexfilename) /* If need to extract codestream information*/ image = opj_decode_with_info(dinfo, cio, &cstr_info); else image = opj_decode(dinfo, cio); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); free(src); return 1; } /* close the byte stream */ opj_cio_close(cio); /* Write the index to disk */ if (*indexfilename) { opj_bool bSuccess; bSuccess = write_index_file(&cstr_info, indexfilename); if (bSuccess) { fprintf(stderr, "Failed to output index file\n"); } } } break; case JP2_CFMT: { /* JPEG 2000 compressed image data */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_JP2); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using the current image and user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ if (*indexfilename) /* If need to extract codestream information*/ image = opj_decode_with_info(dinfo, cio, &cstr_info); else image = opj_decode(dinfo, cio); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); free(src); return 1; } /* close the byte stream */ opj_cio_close(cio); /* Write the index to disk */ if (*indexfilename) { opj_bool bSuccess; bSuccess = write_index_file(&cstr_info, indexfilename); if (bSuccess) { fprintf(stderr, "Failed to output index file\n"); } } } break; case JPT_CFMT: { /* JPEG 2000, JPIP */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_JPT); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ if (*indexfilename) /* If need to extract codestream information*/ image = opj_decode_with_info(dinfo, cio, &cstr_info); else image = opj_decode(dinfo, cio); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); free(src); return 1; } /* close the byte stream */ opj_cio_close(cio); /* Write the index to disk */ if (*indexfilename) { opj_bool bSuccess; bSuccess = write_index_file(&cstr_info, indexfilename); if (bSuccess) { fprintf(stderr, "Failed to output index file\n"); } } } break; default: fprintf(stderr, "skipping file..\n"); continue; } /* free the memory containing the code-stream */ free(src); src = NULL; if(image->color_space == CLRSPC_SYCC) { color_sycc_to_rgb(image); } if(image->icc_profile_buf) { #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) color_apply_icc_profile(image); #endif free(image->icc_profile_buf); image->icc_profile_buf = NULL; image->icc_profile_len = 0; } /* create output image */ /* ------------------- */ switch (parameters.cod_format) { case PXM_DFMT: /* PNM PGM PPM */ if (imagetopnm(image, parameters.outfile)) { fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; case PGX_DFMT: /* PGX */ if(imagetopgx(image, parameters.outfile)){ fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; case BMP_DFMT: /* BMP */ if(imagetobmp(image, parameters.outfile)){ fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; #ifdef HAVE_LIBTIFF case TIF_DFMT: /* TIFF */ if(imagetotif(image, parameters.outfile)){ fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; #endif /* HAVE_LIBTIFF */ case RAW_DFMT: /* RAW */ if(imagetoraw(image, parameters.outfile)){ fprintf(stdout,"Error generating raw file. Outfile %s not generated\n",parameters.outfile); } else { fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile); } break; case TGA_DFMT: /* TGA */ if(imagetotga(image, parameters.outfile)){ fprintf(stdout,"Error generating tga file. Outfile %s not generated\n",parameters.outfile); } else { fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile); } break; #ifdef HAVE_LIBPNG case PNG_DFMT: /* PNG */ if(imagetopng(image, parameters.outfile)){ fprintf(stdout,"Error generating png file. Outfile %s not generated\n",parameters.outfile); } else { fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile); } break; #endif /* HAVE_LIBPNG */ /* Can happen if output file is TIFF or PNG * and HAVE_LIBTIF or HAVE_LIBPNG is undefined */ default: fprintf(stderr,"Outfile %s not generated\n",parameters.outfile); } /* free remaining structures */ if(dinfo) { opj_destroy_decompress(dinfo); } /* free codestream information structure */ if (*indexfilename) opj_destroy_cstr_info(&cstr_info); /* free image data structure */ opj_image_destroy(image); } return 0; }