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
path: root/source
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-02-22 13:20:22 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-02-22 13:20:22 +0400
commit08d356a7e0a5ca8c840285772ec04c56c6b3421e (patch)
tree19b769b49c9fe7f7194cbfb0ffd9e2f3bfc52d35 /source
parent1cdaf1e3293b6bf641a9b9117a8bcef9364b7d85 (diff)
Fix #34359: 2.66 crashes when using output node
16bit PNG and Jpeg2K exporters were not aware of the simple fact that float buffer could have only 3 or 1 channels.
Diffstat (limited to 'source')
-rw-r--r--source/blender/imbuf/intern/jp2.c219
-rw-r--r--source/blender/imbuf/intern/png.c94
2 files changed, 250 insertions, 63 deletions
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index ff0aeb068e2..3d04b8ee184 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -108,6 +108,13 @@ static void info_callback(const char *msg, void *client_data)
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 \
@@ -663,76 +670,198 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
}
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) {
- 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]);
+ 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;
}
- PIXEL_LOOPER_END;
}
else {
- 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]));
+ 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;
}
- PIXEL_LOOPER_END;
}
break;
case 12:
if (numcomps == 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]);
+ 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;
}
- PIXEL_LOOPER_END;
}
else {
- 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]));
+ 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;
}
- PIXEL_LOOPER_END;
}
break;
case 16:
if (numcomps == 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]);
+ 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;
}
- PIXEL_LOOPER_END;
}
else {
- 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]));
+ 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;
}
- PIXEL_LOOPER_END;
}
break;
}
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index cc73f688e70..68385f22a7a 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -133,6 +133,7 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
bool is_16bit = (ibuf->ftype & PNG_16BIT);
bool has_float = (ibuf->rect_float != NULL);
+ int channels_in_float = ibuf->channels ? ibuf->channels : 4;
float (*chanel_colormanage_cb)(float);
@@ -156,7 +157,7 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
bytesperpixel = (ibuf->planes + 7) >> 3;
if ((bytesperpixel > 4) || (bytesperpixel == 2)) {
- printf("imb_savepng: Cunsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name);
+ printf("imb_savepng: Unsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name);
return (0);
}
@@ -203,13 +204,32 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
color_type = PNG_COLOR_TYPE_RGBA;
if (is_16bit) {
if (has_float) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- premul_to_straight_v4_v4(from_straight, from_float);
- to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
- to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
- to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
- to16[3] = ftoshort(chanel_colormanage_cb(from_straight[3]));
- to16 += 4; from_float += 4;
+ if (channels_in_float == 4) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4_v4(from_straight, from_float);
+ to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
+ to16[3] = ftoshort(chanel_colormanage_cb(from_straight[3]));
+ to16 += 4; from_float += 4;
+ }
+ }
+ else if (channels_in_float == 3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
+ to16[3] = 65535;
+ to16 += 4; from_float += 3;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[2] = to16[1] = to16[0];
+ to16[3] = 65535;
+ to16 += 4; from_float++;
+ }
}
}
else {
@@ -236,12 +256,29 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
color_type = PNG_COLOR_TYPE_RGB;
if (is_16bit) {
if (has_float) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- premul_to_straight_v4_v4(from_straight, from_float);
- to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
- to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
- to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
- to16 += 3; from_float += 4;
+ if (channels_in_float == 4) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4_v4(from_straight, from_float);
+ to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
+ to16 += 3; from_float += 4;
+ }
+ }
+ else if (channels_in_float == 3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
+ to16 += 3; from_float += 3;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[2] = to16[1] = to16[0];
+ to16 += 3; from_float++;
+ }
}
}
else {
@@ -266,10 +303,31 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
color_type = PNG_COLOR_TYPE_GRAY;
if (is_16bit) {
if (has_float) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- premul_to_straight_v4_v4(from_straight, from_float);
- to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
- to16++; from_float += 4;
+ float rgb[3];
+ if (channels_in_float == 4) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4_v4(from_straight, from_float);
+ rgb[0] = chanel_colormanage_cb(from_straight[0]);
+ rgb[1] = chanel_colormanage_cb(from_straight[1]);
+ rgb[2] = chanel_colormanage_cb(from_straight[2]);
+ to16[0] = ftoshort(rgb_to_bw(rgb));
+ to16++; from_float += 4;
+ }
+ }
+ else if (channels_in_float == 3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ rgb[0] = chanel_colormanage_cb(from_float[0]);
+ rgb[1] = chanel_colormanage_cb(from_float[1]);
+ rgb[2] = chanel_colormanage_cb(from_float[2]);
+ to16[0] = ftoshort(rgb_to_bw(rgb));
+ to16++; from_float += 3;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16++; from_float++;
+ }
}
}
else {