diff options
Diffstat (limited to 'source/blender/imbuf/intern/jp2.c')
-rw-r--r-- | source/blender/imbuf/intern/jp2.c | 196 |
1 files changed, 79 insertions, 117 deletions
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index 3008c233718..01523463712 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -26,8 +26,8 @@ #include "MEM_guardedalloc.h" -#include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_fileops.h" #include "imbuf.h" @@ -36,11 +36,15 @@ #include "IMB_allocimbuf.h" #include "IMB_filetype.h" +#include "IMB_colormanagement.h" +#include "IMB_colormanagement_intern.h" + #include "openjpeg.h" #define JP2_FILEHEADER_SIZE 14 static char JP2_HEAD[] = {0x0, 0x0, 0x0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A}; +static 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' */ @@ -59,15 +63,19 @@ typedef struct img_folder { static int check_jp2(unsigned char *mem) /* J2K_CFMT */ { - return memcmp(JP2_HEAD, mem, 12) ? 0 : 1; + return memcmp(JP2_HEAD, mem, sizeof(JP2_HEAD)) ? 0 : 1; +} + +static int check_j2k(unsigned char *mem) /* J2K_CFMT */ +{ + return memcmp(J2K_HEAD, mem, sizeof(J2K_HEAD)) ? 0 : 1; } int imb_is_a_jp2(unsigned char *buf) -{ +{ return check_jp2(buf); } - /** * sample error callback expecting a FILE* client object */ @@ -104,7 +112,7 @@ static void info_callback(const char *msg, void *client_data) } \ } (void)0 \ -struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags) +struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) { struct ImBuf *ibuf = NULL; int use_float = FALSE; /* for precision higher then 8 use float */ @@ -116,6 +124,7 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags) 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 */ @@ -125,7 +134,14 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags) opj_dinfo_t *dinfo = NULL; /* handle to a decompressor */ opj_cio_t *cio = NULL; - if (check_jp2(mem) == 0) return(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)); @@ -141,7 +157,7 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags) /* JPEG 2000 compressed image data */ /* get a decoder handle */ - dinfo = opj_create_decompress(CODEC_JP2); + 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); @@ -528,6 +544,10 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *ima 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) { @@ -544,9 +564,20 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) 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) { + /* 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->ftype & JP2_CINE) { if (ibuf->x == 4096 || ibuf->y == 2160) @@ -631,136 +662,67 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) switch (prec) { case 8: /* Convert blenders float color channels to 8, 12 or 16bit ints */ if (numcomps == 4) { - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { - PIXEL_LOOPER_BEGIN(rect_float) - { - r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[2])); - a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]); - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN(rect_float) - { - r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[0]); - g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[1]); - b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[2]); - a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]); - } - PIXEL_LOOPER_END; + PIXEL_LOOPER_BEGIN(rect_float) + { + 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] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]); } + PIXEL_LOOPER_END; } else { - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { - PIXEL_LOOPER_BEGIN(rect_float) - { - r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[2])); - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN(rect_float) - { - r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[0]); - g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[1]); - b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[2]); - } - PIXEL_LOOPER_END; + PIXEL_LOOPER_BEGIN(rect_float) + { + 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; } break; case 12: if (numcomps == 4) { - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { - PIXEL_LOOPER_BEGIN(rect_float) - { - r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[2])); - a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]); - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN(rect_float) - { - r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[0]); - g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[1]); - b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[2]); - a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]); - } - PIXEL_LOOPER_END; + PIXEL_LOOPER_BEGIN(rect_float) + { + 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] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]); } + PIXEL_LOOPER_END; } else { - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { - PIXEL_LOOPER_BEGIN(rect_float) - { - r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[2])); - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN(rect_float) - { - r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[0]); - g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[1]); - b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[2]); - } - PIXEL_LOOPER_END; + PIXEL_LOOPER_BEGIN(rect_float) + { + 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; } break; case 16: if (numcomps == 4) { - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { - PIXEL_LOOPER_BEGIN(rect_float) - { - r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[2])); - a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]); - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN(rect_float) - { - r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[0]); - g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[1]); - b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[2]); - a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]); - } - PIXEL_LOOPER_END; + PIXEL_LOOPER_BEGIN(rect_float) + { + 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] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]); } + PIXEL_LOOPER_END; } else { - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { - PIXEL_LOOPER_BEGIN(rect_float) - { - r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[0])); - g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[1])); - b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[2])); - } - PIXEL_LOOPER_END; - } - else { - PIXEL_LOOPER_BEGIN(rect_float) - { - r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[0]); - g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[1]); - b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[2]); - } - PIXEL_LOOPER_END; + PIXEL_LOOPER_BEGIN(rect_float) + { + 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; } break; } @@ -864,7 +826,7 @@ int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags) /* * configure the event callbacks (not required) - * setting of each callback is optionnal + * setting of each callback is optional */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; @@ -880,7 +842,7 @@ int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags) parameters.tcp_rates[0] = ((100 - quality) / 90.0f * 99.0f) + 1; - parameters.tcp_numlayers = 1; // only one resolution + parameters.tcp_numlayers = 1; /* only one resolution */ parameters.cp_disto_alloc = 1; image = ibuftoimage(ibuf, ¶meters); |