static BOOL DLL_CALLCONV Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) { if ((dib) && (handle)) { BOOL bSuccess; opj_cparameters_t parameters; // compression parameters opj_event_mgr_t event_mgr; // event manager opj_image_t *image = NULL; // image to encode opj_cinfo_t* cinfo = NULL; // codec context opj_cio_t *cio = NULL; // memory byte stream // 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 encoding parameters to default values opj_set_default_encoder_parameters(¶meters); parameters.tcp_numlayers = 0; // if no rate entered, apply a 16:1 rate by default if(flags == JP2_DEFAULT) { parameters.tcp_rates[0] = (float)16; } else { // for now, the flags parameter is only used to specify the rate parameters.tcp_rates[0] = (float)flags; } parameters.tcp_numlayers++; parameters.cp_disto_alloc = 1; try { // convert the dib to a OpenJPEG image image = FIBITMAPToJ2KImage(s_format_id, dib, ¶meters); if(!image) return FALSE; // encode the destination image // get a J2K compressor handle cinfo = opj_create_compress(CODEC_JP2); // catch events using our callbacks opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, NULL); // setup the encoder parameters using the current image and using user parameters opj_setup_encoder(cinfo, ¶meters, image); // open a byte stream for writing, allocate memory for all tiles cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0); // encode the image bSuccess = opj_encode(cinfo, cio, image, NULL/*parameters.index*/); if (!bSuccess) { throw "Failed to encode image"; } int codestream_length = cio_tell(cio); // write the buffer to user's IO handle io->write_proc(cio->buffer, 1, codestream_length, handle); // close and free the byte stream opj_cio_close(cio); // free remaining compression structures opj_destroy_compress(cinfo); // free image data opj_image_destroy(image); return TRUE; } catch (const char *text) { if(cio) opj_cio_close(cio); if(cinfo) opj_destroy_compress(cinfo); if(image) opj_image_destroy(image); FreeImage_OutputMessageProc(s_format_id, text); return FALSE; } } return FALSE; }
static BOOL DLL_CALLCONV Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) { J2KFIO_t *fio = (J2KFIO_t*)data; if (dib && handle && fio) { BOOL bSuccess; opj_codec_t *c_codec = NULL; // handle to a compressor opj_cparameters_t parameters; // compression parameters opj_image_t *image = NULL; // image to encode // get the OpenJPEG stream opj_stream_t *c_stream = fio->stream; // set encoding parameters to default values opj_set_default_encoder_parameters(¶meters); try { parameters.tcp_numlayers = 0; // if no rate entered, apply a 16:1 rate by default if(flags == J2K_DEFAULT) { parameters.tcp_rates[0] = (float)16; } else { // for now, the flags parameter is only used to specify the rate parameters.tcp_rates[0] = (float)(flags & 0x3FF); } parameters.tcp_numlayers++; parameters.cp_disto_alloc = 1; // convert the dib to a OpenJPEG image image = FIBITMAPToJ2KImage(s_format_id, dib, ¶meters); if(!image) { return FALSE; } // decide if MCT should be used parameters.tcp_mct = (image->numcomps == 3) ? 1 : 0; // encode the destination image // get a J2K compressor handle c_codec = opj_create_compress(OPJ_CODEC_J2K); // configure the event callbacks // catch events using our callbacks (no local context needed here) opj_set_info_handler(c_codec, NULL, NULL); opj_set_warning_handler(c_codec, j2k_warning_callback, NULL); opj_set_error_handler(c_codec, j2k_error_callback, NULL); // setup the encoder parameters using the current image and using user parameters opj_setup_encoder(c_codec, ¶meters, image); // encode the image bSuccess = opj_start_compress(c_codec, image, c_stream); if(bSuccess) { bSuccess = bSuccess && opj_encode(c_codec, c_stream); if(bSuccess) { bSuccess = bSuccess && opj_end_compress(c_codec, c_stream); } } if (!bSuccess) { throw "Failed to encode image"; } // free remaining compression structures opj_destroy_codec(c_codec); // free image data opj_image_destroy(image); return TRUE; } catch (const char *text) { if(c_codec) opj_destroy_codec(c_codec); if(image) opj_image_destroy(image); FreeImage_OutputMessageProc(s_format_id, text); return FALSE; } } return FALSE; }