diff options
Diffstat (limited to 'source/blender/imbuf/intern')
-rw-r--r-- | source/blender/imbuf/intern/IMB_filetype.h | 5 | ||||
-rw-r--r-- | source/blender/imbuf/intern/filetype.c | 2 | ||||
-rw-r--r-- | source/blender/imbuf/intern/jp2.c | 494 |
3 files changed, 139 insertions, 362 deletions
diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h index 19d37871aa2..2bd7cbcf6eb 100644 --- a/source/blender/imbuf/intern/IMB_filetype.h +++ b/source/blender/imbuf/intern/IMB_filetype.h @@ -82,9 +82,8 @@ int imb_saveiris(struct ImBuf *ibuf, const char *name, int flags); /* jp2 */ int imb_is_a_jp2(const unsigned char *buf); -struct ImBuf *imb_load_jp2(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]); -struct ImBuf *imb_load_jp2_filepath(const char *name, int flags, char colorspace[IM_MAX_SPACE]); -int imb_save_jp2(struct ImBuf *ibuf, const char *name, int flags); +struct ImBuf *imb_jp2_decode(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]); +int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags); /* jpeg */ int imb_is_a_jpeg(const unsigned char *mem); diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c index 7ffb575cdc4..3d3e8a0646a 100644 --- a/source/blender/imbuf/intern/filetype.c +++ b/source/blender/imbuf/intern/filetype.c @@ -81,7 +81,7 @@ const ImFileType IMB_FILE_TYPES[] = { {imb_initopenexr, NULL, imb_is_a_openexr, NULL, imb_ftype_default, imb_load_openexr, NULL, imb_save_openexr, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_OPENEXR, COLOR_ROLE_DEFAULT_FLOAT}, #endif #ifdef WITH_OPENJPEG - {NULL, NULL, imb_is_a_jp2, NULL, imb_ftype_default, imb_load_jp2, imb_load_jp2_filepath, imb_save_jp2, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_JP2, COLOR_ROLE_DEFAULT_BYTE}, + {NULL, NULL, imb_is_a_jp2, NULL, imb_ftype_default, imb_jp2_decode, NULL, imb_savejp2, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_JP2, COLOR_ROLE_DEFAULT_BYTE}, #endif #ifdef WITH_DDS {NULL, NULL, imb_is_a_dds, NULL, imb_ftype_default, imb_load_dds, NULL, NULL, NULL, 0, IMB_FTYPE_DDS, COLOR_ROLE_DEFAULT_BYTE}, diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index 923318fbe58..390f2502ee7 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -38,7 +38,7 @@ #include "openjpeg.h" -#define JP2_FILEHEADER_SIZE 12 +// #define JP2_FILEHEADER_SIZE 14 /* UNUSED */ static const char JP2_HEAD[] = {0x0, 0x0, 0x0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A}; static const char J2K_HEAD[] = {0xFF, 0x4F, 0xFF, 0x51, 0x00}; @@ -73,19 +73,6 @@ static bool check_j2k(const unsigned char *mem) /* J2K_CFMT */ return memcmp(J2K_HEAD, mem, sizeof(J2K_HEAD)) ? 0 : 1; } -static OPJ_CODEC_FORMAT format_from_header(const unsigned char mem[JP2_FILEHEADER_SIZE]) -{ - if (check_jp2(mem)) { - return OPJ_CODEC_JP2; - } - else if (check_j2k(mem)) { - return OPJ_CODEC_J2K; - } - else { - return OPJ_CODEC_UNKNOWN; - } -} - int imb_is_a_jp2(const unsigned char *buf) { return check_jp2(buf); @@ -112,8 +99,8 @@ static void warning_callback(const char *msg, void *client_data) */ static void info_callback(const char *msg, void *client_data) { - FILE *stream = (FILE *)client_data; - fprintf(stream, "[INFO] %s", msg); + (void)client_data; + fprintf(stdout, "[INFO] %s", msg); } # define PIXEL_LOOPER_BEGIN(_rect) \ @@ -134,233 +121,8 @@ static void info_callback(const char *msg, void *client_data) } \ } (void)0 \ - -/** \name Buffer Stream - * \{ */ - -struct BufInfo { - const unsigned char *buf; - const unsigned char *cur; - off_t len; -}; - -static void opj_read_from_buffer_free(void *UNUSED(p_user_data)) -{ - /* nop */ -} - -static OPJ_SIZE_T opj_read_from_buffer(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) -{ - struct BufInfo *p_file = p_user_data; - OPJ_UINT32 l_nb_read; - - if (p_file->cur + p_nb_bytes < p_file->buf + p_file->len ) { - l_nb_read = p_nb_bytes; - } - else { - l_nb_read = (OPJ_UINT32)(p_file->buf + p_file->len - p_file->cur); - } - memcpy(p_buffer, p_file->cur, l_nb_read); - p_file->cur += l_nb_read; - - return l_nb_read ? l_nb_read : ((OPJ_SIZE_T)-1); -} - -#if 0 -static OPJ_SIZE_T opj_write_from_buffer(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) -{ - struct BufInfo *p_file = p_user_data; - memcpy(p_file->cur, p_buffer, p_nb_bytes); - p_file->cur += p_nb_bytes; - p_file->len += p_nb_bytes; - return p_nb_bytes; -} -#endif - -static OPJ_OFF_T opj_skip_from_buffer(OPJ_OFF_T p_nb_bytes, void *p_user_data) -{ - struct BufInfo *p_file = p_user_data; - if (p_file->cur + p_nb_bytes < p_file->buf + p_file->len) { - p_file->cur += p_nb_bytes; - return p_nb_bytes; - } - p_file->cur = p_file->buf + p_file->len; - return (OPJ_OFF_T)-1; -} - -static OPJ_BOOL opj_seek_from_buffer(OPJ_OFF_T p_nb_bytes, void *p_user_data) -{ - struct BufInfo *p_file = p_user_data; - if (p_file->cur + p_nb_bytes < p_file->buf + p_file->len) { - p_file->cur += p_nb_bytes; - return OPJ_TRUE; - } - p_file->cur = p_file->buf + p_file->len; - return OPJ_FALSE; -} - -/** - * Stream wrapper for memory buffer - * (would be nice if this was supported by the API). - */ - -static opj_stream_t *opj_stream_create_from_buffer( - struct BufInfo *p_file, OPJ_UINT32 p_size, - OPJ_BOOL p_is_read_stream) -{ - opj_stream_t *l_stream = opj_stream_create(p_size, p_is_read_stream); - if (l_stream == NULL) { - return NULL; - } - opj_stream_set_user_data(l_stream, p_file , opj_read_from_buffer_free); - opj_stream_set_user_data_length(l_stream, p_file->len); - opj_stream_set_read_function(l_stream, opj_read_from_buffer); -#if 0 /* UNUSED */ - opj_stream_set_write_function(l_stream, opj_write_from_buffer); -#endif - opj_stream_set_skip_function(l_stream, opj_skip_from_buffer); - opj_stream_set_seek_function(l_stream, opj_seek_from_buffer); - - return l_stream; -} - -/** \} */ - - -/** \name File Stream - * \{ */ - -static void opj_free_from_file(void *p_user_data) -{ - FILE *f = p_user_data; - fclose(f); -} - -static OPJ_UINT64 opj_get_data_length_from_file (void *p_user_data) -{ - FILE *p_file = p_user_data; - OPJ_OFF_T file_length = 0; - - fseek(p_file, 0, SEEK_END); - file_length = ftell(p_file); - fseek(p_file, 0, SEEK_SET); - - return (OPJ_UINT64)file_length; -} - -static OPJ_SIZE_T opj_read_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) -{ - FILE *p_file = p_user_data; - OPJ_SIZE_T l_nb_read = fread(p_buffer, 1, p_nb_bytes, p_file); - return l_nb_read ? l_nb_read : (OPJ_SIZE_T)-1; -} - -static OPJ_SIZE_T opj_write_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) -{ - FILE *p_file = p_user_data; - return fwrite(p_buffer, 1, p_nb_bytes, p_file); -} - -static OPJ_OFF_T opj_skip_from_file(OPJ_OFF_T p_nb_bytes, void *p_user_data) -{ - FILE *p_file = p_user_data; - if (fseek(p_file, p_nb_bytes, SEEK_CUR)) { - return -1; - } - return p_nb_bytes; -} - -static OPJ_BOOL opj_seek_from_file(OPJ_OFF_T p_nb_bytes, void *p_user_data) -{ - FILE *p_file = p_user_data; - if (fseek(p_file, p_nb_bytes, SEEK_SET)) { - return OPJ_FALSE; - } - return OPJ_TRUE; -} - -/** - * Stream wrapper for memory file - * (would be nice if this was supported by the API). - */ - -static opj_stream_t *opj_stream_create_from_file( - const char *filepath, OPJ_UINT32 p_size, OPJ_BOOL p_is_read_stream, - FILE **r_file) -{ - FILE *p_file = BLI_fopen(filepath, p_is_read_stream ? "rb" : "wb"); - if (p_file == NULL) { - return NULL; - } - - opj_stream_t *l_stream = opj_stream_create(p_size, p_is_read_stream); - if (l_stream == NULL) { - fclose(p_file); - return NULL; - } - - opj_stream_set_user_data(l_stream, p_file, opj_free_from_file); - opj_stream_set_user_data_length(l_stream, opj_get_data_length_from_file(p_file)); - opj_stream_set_write_function(l_stream, opj_write_from_file); - opj_stream_set_read_function(l_stream, opj_read_from_file); - opj_stream_set_skip_function(l_stream, opj_skip_from_file); - opj_stream_set_seek_function(l_stream, opj_seek_from_file); - - if (r_file) { - *r_file = p_file; - } - return l_stream; -} - -/** \} */ - -static ImBuf *imb_load_jp2_stream( - opj_stream_t stream, OPJ_CODEC_FORMAT p_format, - int flags, char colorspace[IM_MAX_SPACE]); - -ImBuf *imb_load_jp2(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +struct ImBuf *imb_jp2_decode(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) { - const OPJ_CODEC_FORMAT format = (size > JP2_FILEHEADER_SIZE) ? format_from_header(mem) : OPJ_CODEC_UNKNOWN; - struct BufInfo buf_wrapper = { .buf = mem, .cur = mem, .len = size, }; - opj_stream_t stream = opj_stream_create_from_buffer(&buf_wrapper, OPJ_J2K_STREAM_CHUNK_SIZE, true); - ImBuf *ibuf = imb_load_jp2_stream(stream, format, flags, colorspace); - opj_stream_destroy(stream); - return ibuf; -} - -ImBuf *imb_load_jp2_filepath(const char *filepath, int flags, char colorspace[IM_MAX_SPACE]) -{ - FILE *p_file = NULL; - unsigned char mem[JP2_FILEHEADER_SIZE]; - opj_stream_t *stream = opj_stream_create_from_file(filepath, OPJ_J2K_STREAM_CHUNK_SIZE, false, &p_file); - if (stream) { - return NULL; - } - else { - if (fread(mem, sizeof(mem), 1, p_file) != sizeof(mem)) { - opj_stream_destroy(stream); - return NULL; - } - else { - fseek(p_file, 0, SEEK_SET); - } - } - - const OPJ_CODEC_FORMAT format = format_from_header(mem); - ImBuf *ibuf = imb_load_jp2_stream(stream, format, flags, colorspace); - opj_stream_destroy(stream); - return ibuf; -} - - -static ImBuf *imb_load_jp2_stream( - opj_stream_t stream, const OPJ_CODEC_FORMAT format, - int flags, char colorspace[IM_MAX_SPACE]) -{ - if (format == OPJ_CODEC_UNKNOWN) { - return NULL; - } - struct ImBuf *ibuf = NULL; bool use_float = false; /* for precision higher then 8 use float */ bool use_alpha = false; @@ -371,49 +133,68 @@ static ImBuf *imb_load_jp2_stream( unsigned int i, i_next, w, h, planes; unsigned int y; int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */ + bool is_jp2, is_j2k; opj_dparameters_t parameters; /* decompression parameters */ + opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; - opj_codec_t *codec = NULL; /* handle to a decompressor */ + + 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 */ - codec = opj_create_decompress(format); + dinfo = opj_create_decompress(is_jp2 ? CODEC_JP2 : CODEC_J2K); - /* configure the event callbacks (not required) */ - opj_set_error_handler(codec, error_callback, stderr); - opj_set_warning_handler(codec, warning_callback, stderr); -#ifdef DEBUG /* too noisy */ - opj_set_info_handler(codec, info_callback, stderr); -#endif + /* 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 */ - if (opj_setup_decoder(codec, ¶meters) == false) { - goto finally; - } + opj_setup_decoder(dinfo, ¶meters); - if (opj_read_header(stream, codec, &image) == false) { - printf("OpenJPEG error: failed to read the header\n"); - goto finally; - } + /* open a byte stream */ + /* note, we can't avoid removing 'const' cast here */ + cio = opj_cio_open((opj_common_ptr)dinfo, (unsigned char *)mem, size); /* decode the stream and fill the image structure */ - if (opj_decode(codec, stream, image) == false) { + image = opj_decode(dinfo, cio); + + if (!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); - goto finally; + 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"); - goto finally; + return NULL; } w = image->comps[0].w; @@ -451,16 +232,16 @@ static ImBuf *imb_load_jp2_stream( ibuf = IMB_allocImBuf(w, h, planes, use_float ? IB_rectfloat : IB_rect); if (ibuf == NULL) { - goto finally; + if (dinfo) + opj_destroy_decompress(dinfo); + return NULL; } ibuf->ftype = IMB_FTYPE_JP2; - if (1 /* is_jp2 */ ) { + if (is_jp2) ibuf->foptions.flag |= JP2_JP2; - } - else { + else ibuf->foptions.flag |= JP2_J2K; - } if (use_float) { float *rect_float = ibuf->rect_float; @@ -566,23 +347,19 @@ static ImBuf *imb_load_jp2_stream( } } - if (flags & IB_rect) { - IMB_rect_from_float(ibuf); - } - - -finally: - /* free remaining structures */ - if (codec) { - opj_destroy_codec(codec); + if (dinfo) { + opj_destroy_decompress(dinfo); } - - if (image) { - opj_image_destroy(image); + + /* free image data structure */ + opj_image_destroy(image); + + if (flags & IB_rect) { + IMB_rect_from_float(ibuf); } - - return ibuf; + + return(ibuf); } //static opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) @@ -645,14 +422,14 @@ static int initialise_4K_poc(opj_poc_t *POC, int numres) POC[0].layno1 = 1; POC[0].resno1 = numres - 1; POC[0].compno1 = 3; - POC[0].prg1 = OPJ_CPRL; + POC[0].prg1 = CPRL; POC[1].tile = 1; POC[1].resno0 = numres - 1; POC[1].compno0 = 0; POC[1].layno1 = 1; POC[1].resno1 = numres; POC[1].compno1 = 3; - POC[1].prg1 = OPJ_CPRL; + POC[1].prg1 = CPRL; return 2; } @@ -678,7 +455,7 @@ static void cinema_parameters(opj_cparameters_t *parameters) parameters->csty |= 0x01; /*The progression order shall be CPRL*/ - parameters->prog_order = OPJ_CPRL; + parameters->prog_order = CPRL; /* No ROI */ parameters->roi_compno = -1; @@ -695,23 +472,23 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *ima float temp_rate; switch (parameters->cp_cinema) { - case OPJ_CINEMA2K_24: - case OPJ_CINEMA2K_48: + case CINEMA2K_24: + case CINEMA2K_48: if (parameters->numresolution > 6) { parameters->numresolution = 6; } if (!((image->comps[0].w == 2048) || (image->comps[0].h == 1080))) { - fprintf(stdout, "Image coordinates %u x %u is not 2K compliant.\nJPEG Digital Cinema Profile-3 " + fprintf(stdout, "Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3 " "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n", image->comps[0].w, image->comps[0].h); - parameters->cp_rsiz = OPJ_STD_RSIZ; + parameters->cp_rsiz = STD_RSIZ; } else { parameters->cp_rsiz = DCP_CINEMA2K; } break; - case OPJ_CINEMA4K_24: + case CINEMA4K_24: if (parameters->numresolution < 1) { parameters->numresolution = 1; } @@ -719,24 +496,24 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *ima parameters->numresolution = 7; } if (!((image->comps[0].w == 4096) || (image->comps[0].h == 2160))) { - fprintf(stdout, "Image coordinates %u x %u is not 4K compliant.\nJPEG Digital Cinema Profile-4" + fprintf(stdout, "Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4" "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n", image->comps[0].w, image->comps[0].h); - parameters->cp_rsiz = OPJ_STD_RSIZ; + parameters->cp_rsiz = STD_RSIZ; } else { parameters->cp_rsiz = DCP_CINEMA2K; } parameters->numpocs = initialise_4K_poc(parameters->POC, parameters->numresolution); break; - case OPJ_OFF: + case OFF: /* do nothing */ break; } switch (parameters->cp_cinema) { - case OPJ_CINEMA2K_24: - case OPJ_CINEMA4K_24: + case CINEMA2K_24: + case CINEMA4K_24: for (i = 0; i < parameters->tcp_numlayers; i++) { temp_rate = 0; if (img_fol->rates[i] == 0) { @@ -758,7 +535,7 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *ima parameters->max_comp_size = COMP_24_CS; break; - case OPJ_CINEMA2K_48: + case CINEMA2K_48: for (i = 0; i < parameters->tcp_numlayers; i++) { temp_rate = 0; if (img_fol->rates[i] == 0) { @@ -779,7 +556,7 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *ima } parameters->max_comp_size = COMP_48_CS; break; - case OPJ_OFF: + case OFF: /* do nothing */ break; } @@ -823,13 +600,13 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) if (ibuf->foptions.flag & JP2_CINE) { if (ibuf->x == 4096 || ibuf->y == 2160) - parameters->cp_cinema = OPJ_CINEMA4K_24; + parameters->cp_cinema = CINEMA4K_24; else { if (ibuf->foptions.flag & JP2_CINE_48FPS) { - parameters->cp_cinema = OPJ_CINEMA2K_48; + parameters->cp_cinema = CINEMA2K_48; } else { - parameters->cp_cinema = OPJ_CINEMA2K_24; + parameters->cp_cinema = CINEMA2K_24; } } if (parameters->cp_cinema) { @@ -840,13 +617,13 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) cinema_parameters(parameters); } - color_space = (ibuf->foptions.flag & JP2_YCC) ? OPJ_CLRSPC_SYCC : OPJ_CLRSPC_SRGB; + color_space = (ibuf->foptions.flag & JP2_YCC) ? CLRSPC_SYCC : CLRSPC_SRGB; prec = 12; numcomps = 3; } else { /* Get settings from the imbuf */ - color_space = (ibuf->foptions.flag & JP2_YCC) ? OPJ_CLRSPC_SYCC : OPJ_CLRSPC_SRGB; + color_space = (ibuf->foptions.flag & JP2_YCC) ? CLRSPC_SYCC : CLRSPC_SRGB; if (ibuf->foptions.flag & JP2_16BIT) prec = 16; else if (ibuf->foptions.flag & JP2_12BIT) prec = 12; @@ -1181,27 +958,28 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) return image; } -int imb_save_jp2_stream(struct ImBuf *ibuf, opj_stream_t stream, int flags); - -int imb_save_jp2(struct ImBuf *ibuf, const char *filepath, int flags) -{ - opj_stream_t stream = opj_stream_create_from_file(filepath, OPJ_J2K_STREAM_CHUNK_SIZE, false, NULL); - if (stream == NULL) { - return 0; - } - int ret = imb_save_jp2_stream(ibuf, stream, flags); - opj_stream_destroy(stream); - return ret; -} /* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */ -int imb_save_jp2_stream(struct ImBuf *ibuf, opj_stream_t stream, int UNUSED(flags)) +int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags) { int quality = ibuf->foptions.quality; + int bSuccess; opj_cparameters_t parameters; /* compression parameters */ + opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; + (void)flags; /* unused */ + + /* + * configure the event callbacks (not required) + * setting of each callback is optional + */ + 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 encoding parameters to default values */ opj_set_default_encoder_parameters(¶meters); @@ -1215,61 +993,61 @@ int imb_save_jp2_stream(struct ImBuf *ibuf, opj_stream_t stream, int UNUSED(flag parameters.cp_disto_alloc = 1; image = ibuftoimage(ibuf, ¶meters); + + + { /* JP2 format output */ + int codestream_length; + opj_cio_t *cio = NULL; + FILE *f = NULL; + opj_cinfo_t *cinfo = NULL; - opj_codec_t *codec = NULL; - int ok = false; - /* JP2 format output */ - { /* get a JP2 compressor handle */ - OPJ_CODEC_FORMAT format = OPJ_CODEC_JP2; - if (ibuf->foptions.flag & JP2_J2K) { - format = OPJ_CODEC_J2K; - } - else if (ibuf->foptions.flag & JP2_JP2) { - format = OPJ_CODEC_JP2; - } + if (ibuf->foptions.flag & JP2_JP2) + cinfo = opj_create_compress(CODEC_JP2); + else if (ibuf->foptions.flag & JP2_J2K) + cinfo = opj_create_compress(CODEC_J2K); + else + BLI_assert(!"Unsupported codec was specified in save settings"); - codec = opj_create_compress(format); - - /* configure the event callbacks (not required) */ - opj_set_error_handler(codec, error_callback, stderr); - opj_set_warning_handler(codec, warning_callback, stderr); -#ifdef DEBUG /* too noisy */ - opj_set_info_handler(codec, info_callback, stderr); -#endif + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); /* setup the encoder parameters using the current image and using user parameters */ - if (opj_setup_encoder(codec, ¶meters, image) == false) { - goto finally; - } + opj_setup_encoder(cinfo, ¶meters, image); - if (opj_start_compress(codec, image, stream) == false) { - goto finally; - } - if (opj_encode(codec, stream) == false) { - goto finally; - } - if (opj_end_compress(codec, stream) == false) { - goto finally; - } - } + /* open a byte stream for writing */ + /* allocate memory for all tiles */ + cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0); - ok = true; + /* encode the image */ + bSuccess = opj_encode(cinfo, cio, image, NULL); /* last arg used to be parameters.index but this deprecated */ + + if (!bSuccess) { + opj_cio_close(cio); + fprintf(stderr, "failed to encode image\n"); + return 0; + } + codestream_length = cio_tell(cio); -finally: - /* free remaining compression structures */ - if (codec) { - opj_destroy_codec(codec); + /* write the buffer to disk */ + f = BLI_fopen(name, "wb"); + + if (!f) { + fprintf(stderr, "failed to open %s for writing\n", name); + return 1; + } + fwrite(cio->buffer, 1, codestream_length, f); + fclose(f); + fprintf(stderr, "Generated outfile %s\n", name); + /* close and free the byte stream */ + opj_cio_close(cio); + + /* free remaining compression structures */ + opj_destroy_compress(cinfo); } /* free image data */ - if (image) { - opj_image_destroy(image); - } - - if (ok == false) { - fprintf(stderr, "failed to encode image\n"); - } - - return ok; + opj_image_destroy(image); + + return 1; } |