forked from bartvdbraak/blender
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.
This commit is contained in:
parent
1cdaf1e329
commit
08d356a7e0
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user