Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/imbuf/intern/jp2.c')
-rw-r--r--source/blender/imbuf/intern/jp2.c196
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, &parameters);