From a1651ddc98ec760e522ea2ea8169b726661fa2e6 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 30 Aug 2018 14:20:19 +0200 Subject: Build: require OpenJPEG 2.x minimum, remove bundled version. * WITH_SYSTEM_OPENJPEG is removed and is now always on, this was already the case for macOS and Windows. * This should not break existing Linx builds. If there is no new enough OpenJPEG installed, CMake will no find libopenjp2 and WITH_IMAGE_OPENJPEG will be disabled. * install_deps.sh was updated with new package names, since distributions put this version in a new package. Differential Revision: https://developer.blender.org/D3663 --- source/blender/imbuf/intern/jp2.c | 1023 ------------------------------------- 1 file changed, 1023 deletions(-) (limited to 'source/blender/imbuf') diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index cd6bdd643d5..caf2634bac7 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -38,12 +38,6 @@ #include "openjpeg.h" -/* Temporary duplicated implementations for version 1.5 and 2.3, until we - * upgrade all platforms to 2.3. When removing the old code, - * imb_load_jp2_filepath can be added in filetype.c. */ - -#if defined(OPJ_VERSION_MAJOR) && OPJ_VERSION_MAJOR >= 2 - #define JP2_FILEHEADER_SIZE 12 static const char JP2_HEAD[] = {0x0, 0x0, 0x0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A}; @@ -1281,1020 +1275,3 @@ finally: return ok; } - -#else /* defined(OPJ_VERSION_MAJOR) && OPJ_VERSION_MAJOR >= 2 */ - -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}; - -/* We only need this because of how the presets are set */ -/* this typedef is copied from 'openjpeg-1.5.0/applications/codec/image_to_j2k.c' */ -typedef struct img_folder { - /** The directory path of the folder containing input images*/ - char *imgdirpath; - /** Output format*/ - char *out_format; - /** Enable option*/ - char set_imgdir; - /** Enable Cod Format for output*/ - char set_out_format; - /** User specified rate stored in case of cinema option*/ - float *rates; -} img_fol_t; - -enum { - DCP_CINEMA2K = 3, - DCP_CINEMA4K = 4, -}; - -static bool check_jp2(const unsigned char *mem) /* J2K_CFMT */ -{ - return memcmp(JP2_HEAD, mem, sizeof(JP2_HEAD)) ? 0 : 1; -} - -static bool check_j2k(const unsigned char *mem) /* J2K_CFMT */ -{ - return memcmp(J2K_HEAD, mem, sizeof(J2K_HEAD)) ? 0 : 1; -} - -int imb_is_a_jp2(const unsigned char *buf) -{ - return check_jp2(buf); -} - -/** - * sample error callback expecting a FILE* client object - */ -static void error_callback(const char *msg, void *client_data) -{ - FILE *stream = (FILE *)client_data; - fprintf(stream, "[ERROR] %s", msg); -} -/** - * sample warning callback expecting a FILE* client object - */ -static void warning_callback(const char *msg, void *client_data) -{ - FILE *stream = (FILE *)client_data; - fprintf(stream, "[WARNING] %s", msg); -} - -/** - * sample debug callback expecting no client object - */ -static void info_callback(const char *msg, void *client_data) -{ - (void)client_data; - fprintf(stdout, "[INFO] %s", msg); -} - -# define PIXEL_LOOPER_BEGIN(_rect) \ - for (y = h - 1; y != (unsigned int)(-1); y--) { \ - for (i = y * w, i_next = (y + 1) * w; \ - i < i_next; \ - i++, _rect += 4) \ - { \ - -# define PIXEL_LOOPER_BEGIN_CHANNELS(_rect, _channels) \ - for (y = h - 1; y != (unsigned int)(-1); y--) { \ - for (i = y * w, i_next = (y + 1) * w; \ - i < i_next; \ - i++, _rect += _channels) \ - { \ - -# define PIXEL_LOOPER_END \ - } \ -} (void)0 \ - -struct ImBuf *imb_load_jp2(const 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 */ - 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_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 */ - /* 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 */ - 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 = IMB_FTYPE_JP2; - if (is_jp2) - ibuf->foptions.flag |= JP2_JP2; - else - ibuf->foptions.flag |= 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; - } - } - else { - r = image->comps[0].data; - g = image->comps[1].data; - b = image->comps[2].data; - - /* rgb or rgba 12bits+ */ - if (use_alpha) { - a = image->comps[3].data; - PIXEL_LOOPER_BEGIN(rect_float) { - rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0]; - rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1]; - rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2]; - rect_float[3] = (float)(a[i] + signed_offsets[3]) / float_divs[3]; - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN(rect_float) { - rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0]; - rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1]; - rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2]; - rect_float[3] = 1.0f; - } - PIXEL_LOOPER_END; - } - } - - } - else { - unsigned char *rect_uchar = (unsigned char *)ibuf->rect; - - if (image->numcomps < 3) { - r = image->comps[0].data; - a = (use_alpha) ? image->comps[1].data : NULL; - - /* grayscale */ - if (use_alpha) { - a = image->comps[3].data; - PIXEL_LOOPER_BEGIN(rect_uchar) { - rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]); - rect_uchar[3] = a[i] + signed_offsets[1]; - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN(rect_uchar) { - rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]); - rect_uchar[3] = 255; - } - PIXEL_LOOPER_END; - } - } - else { - r = image->comps[0].data; - g = image->comps[1].data; - b = image->comps[2].data; - - /* 8bit rgb or rgba */ - if (use_alpha) { - a = image->comps[3].data; - PIXEL_LOOPER_BEGIN(rect_uchar) { - rect_uchar[0] = r[i] + signed_offsets[0]; - rect_uchar[1] = g[i] + signed_offsets[1]; - rect_uchar[2] = b[i] + signed_offsets[2]; - rect_uchar[3] = a[i] + signed_offsets[3]; - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN(rect_uchar) { - rect_uchar[0] = r[i] + signed_offsets[0]; - rect_uchar[1] = g[i] + signed_offsets[1]; - rect_uchar[2] = b[i] + signed_offsets[2]; - rect_uchar[3] = 255; - } - PIXEL_LOOPER_END; - } - } - } - - /* free remaining structures */ - if (dinfo) { - opj_destroy_decompress(dinfo); - } - - /* free image data structure */ - opj_image_destroy(image); - - if (flags & IB_rect) { - IMB_rect_from_float(ibuf); - } - - return(ibuf); -} - -//static opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) -/* prec can be 8, 12, 16 */ - -/* use inline because the float passed can be a function call that would end up being called many times */ -#if 0 -#define UPSAMPLE_8_TO_12(_val) ((_val << 4) | (_val & ((1 << 4) - 1))) -#define UPSAMPLE_8_TO_16(_val) ((_val << 8) + _val) - -#define DOWNSAMPLE_FLOAT_TO_8BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val))) -#define DOWNSAMPLE_FLOAT_TO_12BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val))) -#define DOWNSAMPLE_FLOAT_TO_16BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val))) -#else - -BLI_INLINE int UPSAMPLE_8_TO_12(const unsigned char _val) -{ - return (_val << 4) | (_val & ((1 << 4) - 1)); -} -BLI_INLINE int UPSAMPLE_8_TO_16(const unsigned char _val) -{ - return (_val << 8) + _val; -} - -BLI_INLINE int DOWNSAMPLE_FLOAT_TO_8BIT(const float _val) -{ - return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val))); -} -BLI_INLINE int DOWNSAMPLE_FLOAT_TO_12BIT(const float _val) -{ - return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val))); -} -BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val) -{ - return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val))); -} -#endif - -/* - * 2048x1080 (2K) at 24 fps or 48 fps, or 4096x2160 (4K) at 24 fps; 3x12 bits per pixel, XYZ color space - * - * - In 2K, for Scope (2.39:1) presentation 2048x858 pixels of the image is used - * - In 2K, for Flat (1.85:1) presentation 1998x1080 pixels of the image is used - */ - -/* ****************************** COPIED FROM image_to_j2k.c */ - -/* ----------------------------------------------------------------------- */ -#define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/ -#define CINEMA_48_CS 651041 /*Codestream length for 48fps*/ -#define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/ -#define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/ - - -static int initialise_4K_poc(opj_poc_t *POC, int numres) -{ - POC[0].tile = 1; - POC[0].resno0 = 0; - POC[0].compno0 = 0; - POC[0].layno1 = 1; - POC[0].resno1 = numres - 1; - POC[0].compno1 = 3; - 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 = CPRL; - return 2; -} - -static void cinema_parameters(opj_cparameters_t *parameters) -{ - parameters->tile_size_on = 0; /* false */ - parameters->cp_tdx = 1; - parameters->cp_tdy = 1; - - /*Tile part*/ - parameters->tp_flag = 'C'; - parameters->tp_on = 1; - - /*Tile and Image shall be at (0, 0)*/ - parameters->cp_tx0 = 0; - parameters->cp_ty0 = 0; - parameters->image_offset_x0 = 0; - parameters->image_offset_y0 = 0; - - /*Codeblock size = 32 * 32*/ - parameters->cblockw_init = 32; - parameters->cblockh_init = 32; - parameters->csty |= 0x01; - - /*The progression order shall be CPRL*/ - parameters->prog_order = CPRL; - - /* No ROI */ - parameters->roi_compno = -1; - - parameters->subsampling_dx = 1; parameters->subsampling_dy = 1; - - /* 9-7 transform */ - parameters->irreversible = 1; -} - -static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *image, img_fol_t *img_fol) -{ - int i; - float temp_rate; - - switch (parameters->cp_cinema) { - 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 %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 = STD_RSIZ; - } - else { - parameters->cp_rsiz = DCP_CINEMA2K; - } - break; - - case CINEMA4K_24: - if (parameters->numresolution < 1) { - parameters->numresolution = 1; - } - else if (parameters->numresolution > 7) { - parameters->numresolution = 7; - } - if (!((image->comps[0].w == 4096) || (image->comps[0].h == 2160))) { - 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 = STD_RSIZ; - } - else { - parameters->cp_rsiz = DCP_CINEMA2K; - } - parameters->numpocs = initialise_4K_poc(parameters->POC, parameters->numresolution); - break; - case OFF: - /* do nothing */ - break; - } - - switch (parameters->cp_cinema) { - case CINEMA2K_24: - case CINEMA4K_24: - for (i = 0; i < parameters->tcp_numlayers; i++) { - temp_rate = 0; - if (img_fol->rates[i] == 0) { - parameters->tcp_rates[0] = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) / - (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy); - } - else { - temp_rate = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) / - (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy); - if (temp_rate > CINEMA_24_CS) { - parameters->tcp_rates[i] = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) / - (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy); - } - else { - parameters->tcp_rates[i] = img_fol->rates[i]; - } - } - } - parameters->max_comp_size = COMP_24_CS; - break; - - case CINEMA2K_48: - for (i = 0; i < parameters->tcp_numlayers; i++) { - temp_rate = 0; - if (img_fol->rates[i] == 0) { - parameters->tcp_rates[0] = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) / - (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy); - } - else { - temp_rate = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) / - (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy); - if (temp_rate > CINEMA_48_CS) { - parameters->tcp_rates[0] = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) / - (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy); - } - else { - parameters->tcp_rates[i] = img_fol->rates[i]; - } - } - } - parameters->max_comp_size = COMP_48_CS; - break; - case OFF: - /* do nothing */ - break; - } - parameters->cp_disto_alloc = 1; -} - -static float channel_colormanage_noop(float value) -{ - return value; -} - -static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) -{ - unsigned char *rect_uchar; - float *rect_float, from_straight[4]; - - unsigned int subsampling_dx = parameters->subsampling_dx; - unsigned int subsampling_dy = parameters->subsampling_dy; - - unsigned int i, i_next, numcomps, w, h, prec; - unsigned int y; - int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */ - OPJ_COLOR_SPACE color_space; - opj_image_cmptparm_t cmptparm[4]; /* maximum of 4 components */ - opj_image_t *image = NULL; - - float (*chanel_colormanage_cb)(float); - - img_fol_t img_fol; /* only needed for cinema presets */ - memset(&img_fol, 0, sizeof(img_fol_t)); - - if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) { - /* float buffer was managed already, no need in color space conversion */ - chanel_colormanage_cb = channel_colormanage_noop; - } - else { - /* standard linear-to-srgb conversion if float buffer wasn't managed */ - chanel_colormanage_cb = linearrgb_to_srgb; - } - - if (ibuf->foptions.flag & JP2_CINE) { - - if (ibuf->x == 4096 || ibuf->y == 2160) - parameters->cp_cinema = CINEMA4K_24; - else { - if (ibuf->foptions.flag & JP2_CINE_48FPS) { - parameters->cp_cinema = CINEMA2K_48; - } - else { - parameters->cp_cinema = CINEMA2K_24; - } - } - if (parameters->cp_cinema) { - img_fol.rates = (float *)MEM_mallocN(parameters->tcp_numlayers * sizeof(float), "jp2_rates"); - for (i = 0; i < parameters->tcp_numlayers; i++) { - img_fol.rates[i] = parameters->tcp_rates[i]; - } - cinema_parameters(parameters); - } - - 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) ? CLRSPC_SYCC : CLRSPC_SRGB; - - if (ibuf->foptions.flag & JP2_16BIT) prec = 16; - else if (ibuf->foptions.flag & JP2_12BIT) prec = 12; - else prec = 8; - - /* 32bit images == alpha channel */ - /* grayscale not supported yet */ - numcomps = (ibuf->planes == 32) ? 4 : 3; - } - - w = ibuf->x; - h = ibuf->y; - - - /* initialize image components */ - memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t)); - for (i = 0; i < numcomps; i++) { - cmptparm[i].prec = prec; - cmptparm[i].bpp = prec; - cmptparm[i].sgnd = 0; - cmptparm[i].dx = subsampling_dx; - cmptparm[i].dy = subsampling_dy; - cmptparm[i].w = w; - cmptparm[i].h = h; - } - /* create the image */ - image = opj_image_create(numcomps, &cmptparm[0], color_space); - if (!image) { - printf("Error: opj_image_create() failed\n"); - return NULL; - } - - /* set image offset and reference grid */ - image->x0 = parameters->image_offset_x0; - image->y0 = parameters->image_offset_y0; - image->x1 = image->x0 + (w - 1) * subsampling_dx + 1 + image->x0; - image->y1 = image->y0 + (h - 1) * subsampling_dy + 1 + image->y0; - - /* set image data */ - rect_uchar = (unsigned char *) ibuf->rect; - rect_float = ibuf->rect_float; - - /* set the destination channels */ - r = image->comps[0].data; - g = image->comps[1].data; - b = image->comps[2].data; - a = (numcomps == 4) ? image->comps[3].data : NULL; - - if (rect_float && rect_uchar && prec == 8) { - /* No need to use the floating point buffer, just write the 8 bits from the char buffer */ - rect_float = NULL; - } - - if (rect_float) { - int channels_in_float = ibuf->channels ? ibuf->channels : 4; - - switch (prec) { - case 8: /* Convert blenders float color channels to 8, 12 or 16bit ints */ - if (numcomps == 4) { - if (channels_in_float == 4) { - PIXEL_LOOPER_BEGIN(rect_float) - { - premul_to_straight_v4_v4(from_straight, rect_float); - r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[2])); - a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(from_straight[3]); - } - PIXEL_LOOPER_END; - } - else if (channels_in_float == 3) { - PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3) - { - r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2])); - a[i] = 255; - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1) - { - r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0])); - g[i] = b[i] = r[i]; - a[i] = 255; - } - PIXEL_LOOPER_END; - } - } - else { - if (channels_in_float == 4) { - PIXEL_LOOPER_BEGIN(rect_float) - { - premul_to_straight_v4_v4(from_straight, rect_float); - r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[2])); - } - PIXEL_LOOPER_END; - } - else if (channels_in_float == 3) { - PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3) - { - r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2])); - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1) - { - r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0])); - g[i] = b[i] = r[i]; - } - PIXEL_LOOPER_END; - } - } - break; - - case 12: - if (numcomps == 4) { - if (channels_in_float == 4) { - PIXEL_LOOPER_BEGIN(rect_float) - { - premul_to_straight_v4_v4(from_straight, rect_float); - r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[2])); - a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(from_straight[3]); - } - PIXEL_LOOPER_END; - } - else if (channels_in_float == 3) { - PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3) - { - r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2])); - a[i] = 4095; - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1) - { - r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0])); - g[i] = b[i] = r[i]; - a[i] = 4095; - } - PIXEL_LOOPER_END; - } - } - else { - if (channels_in_float == 4) { - PIXEL_LOOPER_BEGIN(rect_float) - { - premul_to_straight_v4_v4(from_straight, rect_float); - r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[2])); - } - PIXEL_LOOPER_END; - } - else if (channels_in_float == 3) { - PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3) - { - r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2])); - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1) - { - r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0])); - g[i] = b[i] = r[i]; - } - PIXEL_LOOPER_END; - } - } - break; - - case 16: - if (numcomps == 4) { - if (channels_in_float == 4) { - PIXEL_LOOPER_BEGIN(rect_float) - { - premul_to_straight_v4_v4(from_straight, rect_float); - r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[2])); - a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(from_straight[3]); - } - PIXEL_LOOPER_END; - } - else if (channels_in_float == 3) { - PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3) - { - r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2])); - a[i] = 65535; - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1) - { - r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0])); - g[i] = b[i] = r[i]; - a[i] = 65535; - } - PIXEL_LOOPER_END; - } - } - else { - if (channels_in_float == 4) { - PIXEL_LOOPER_BEGIN(rect_float) - { - premul_to_straight_v4_v4(from_straight, rect_float); - r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[2])); - } - PIXEL_LOOPER_END; - } - else if (channels_in_float == 3) { - PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3) - { - r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2])); - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1) - { - r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0])); - g[i] = b[i] = r[i]; - } - PIXEL_LOOPER_END; - } - } - break; - } - } - else { - /* just use rect*/ - switch (prec) { - case 8: - if (numcomps == 4) { - PIXEL_LOOPER_BEGIN(rect_uchar) - { - r[i] = rect_uchar[0]; - g[i] = rect_uchar[1]; - b[i] = rect_uchar[2]; - a[i] = rect_uchar[3]; - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN(rect_uchar) - { - r[i] = rect_uchar[0]; - g[i] = rect_uchar[1]; - b[i] = rect_uchar[2]; - } - PIXEL_LOOPER_END; - } - break; - - case 12: /* Up Sampling, a bit pointless but best write the bit depth requested */ - if (numcomps == 4) { - PIXEL_LOOPER_BEGIN(rect_uchar) - { - r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]); - g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]); - b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]); - a[i] = UPSAMPLE_8_TO_12(rect_uchar[3]); - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN(rect_uchar) - { - r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]); - g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]); - b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]); - } - PIXEL_LOOPER_END; - } - break; - - case 16: - if (numcomps == 4) { - PIXEL_LOOPER_BEGIN(rect_uchar) - { - r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]); - g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]); - b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]); - a[i] = UPSAMPLE_8_TO_16(rect_uchar[3]); - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN(rect_uchar) - { - r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]); - g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]); - b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]); - } - PIXEL_LOOPER_END; - } - break; - } - } - - /* Decide if MCT should be used */ - parameters->tcp_mct = image->numcomps == 3 ? 1 : 0; - - if (parameters->cp_cinema) { - cinema_setup_encoder(parameters, image, &img_fol); - } - - if (img_fol.rates) - MEM_freeN(img_fol.rates); - - return image; -} - - -/* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */ -int imb_save_jp2(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); - - /* compression ratio */ - /* invert range, from 10-100, 100-1 - * where jpeg see's 1 and highest quality (lossless) and 100 is very low quality*/ - parameters.tcp_rates[0] = ((100 - quality) / 90.0f * 99.0f) + 1; - - - parameters.tcp_numlayers = 1; /* only one resolution */ - 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; - - /* get a JP2 compressor handle */ - 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"); - - /* 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 */ - 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); /* 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); - - /* 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 */ - opj_image_destroy(image); - - return 1; -} - -#endif /* defined(OPJ_VERSION_MAJOR) && OPJ_VERSION_MAJOR >= 2 */ -- cgit v1.2.3