Fix T100886: error saving side-by-side stereo EXR image of depth pass

The stereo saving code that combines two image buffers into one did not work
correctly when the number of channels is not equal to 4.
This commit is contained in:
Brecht Van Lommel 2022-09-12 19:39:24 +02:00
parent 100fe61f7c
commit bc15c83afa
Notes: blender-bot 2023-02-14 01:35:49 +01:00
Referenced by issue #100749, Blender LTS: Maintenance Task 3.3
Referenced by issue #100886, Stereo Top/Bottom Render (Cycles) Missing Z Channel:
9 changed files with 31 additions and 21 deletions

View File

@ -156,7 +156,7 @@ void ViewerOperation::init_image()
ibuf->y = display_height_;
/* zero size can happen if no image buffers exist to define a sensible resolution */
if (ibuf->x > 0 && ibuf->y > 0) {
imb_addrectfloatImBuf(ibuf);
imb_addrectfloatImBuf(ibuf, 4);
}
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;

View File

@ -522,7 +522,7 @@ static void ubuf_ensure_compat_ibuf(const UndoImageBuf *ubuf, ImBuf *ibuf)
IMB_rect_size_set(ibuf, ubuf->image_dims);
if (ubuf->image_state.use_float) {
imb_addrectfloatImBuf(ibuf);
imb_addrectfloatImBuf(ibuf, 4);
}
else {
imb_addrectImBuf(ibuf);

View File

@ -809,7 +809,7 @@ bool imb_addrectImBuf(struct ImBuf *ibuf);
*/
void imb_freerectImBuf(struct ImBuf *ibuf);
bool imb_addrectfloatImBuf(struct ImBuf *ibuf);
bool imb_addrectfloatImBuf(struct ImBuf *ibuf, const unsigned int channels);
/**
* Any free `ibuf->rect` frees mipmaps to be sure, creation is in render on first request.
*/

View File

@ -364,7 +364,7 @@ void *imb_alloc_pixels(
return MEM_callocN(size, name);
}
bool imb_addrectfloatImBuf(ImBuf *ibuf)
bool imb_addrectfloatImBuf(ImBuf *ibuf, const unsigned int channels)
{
if (ibuf == NULL) {
return false;
@ -374,8 +374,8 @@ bool imb_addrectfloatImBuf(ImBuf *ibuf)
imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */
}
ibuf->channels = 4;
if ((ibuf->rect_float = imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(float), __func__))) {
ibuf->channels = channels;
if ((ibuf->rect_float = imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(float), __func__))) {
ibuf->mall |= IB_rectfloat;
ibuf->flags |= IB_rectfloat;
return true;
@ -536,7 +536,7 @@ bool IMB_initImBuf(
}
if (flags & IB_rectfloat) {
if (imb_addrectfloatImBuf(ibuf) == false) {
if (imb_addrectfloatImBuf(ibuf, ibuf->channels) == false) {
return false;
}
}

View File

@ -2058,7 +2058,7 @@ struct ImBuf *imb_load_openexr(const unsigned char *mem,
size_t xstride = sizeof(float[4]);
size_t ystride = -xstride * width;
imb_addrectfloatImBuf(ibuf);
imb_addrectfloatImBuf(ibuf, 4);
/* Inverse correct first pixel for data-window
* coordinates (- dw.min.y because of y flip). */

View File

@ -646,7 +646,7 @@ ImBuf *imb_loadpng(const unsigned char *mem, size_t size, int flags, char colors
if (ibuf && ((flags & IB_test) == 0)) {
if (bit_depth == 16) {
imb_addrectfloatImBuf(ibuf);
imb_addrectfloatImBuf(ibuf, 4);
png_set_swap(png_ptr);
pixels16 = imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(png_uint_16), "pixels");

View File

@ -761,11 +761,14 @@ ImBuf *IMB_stereo3d_ImBuf(const ImageFormatData *im_format, ImBuf *ibuf_left, Im
IMB_stereo3d_write_dimensions(
im_format->stereo3d_format.display_mode, false, ibuf_left->x, ibuf_left->y, &width, &height);
ibuf_stereo = IMB_allocImBuf(
width, height, ibuf_left->planes, (is_float ? IB_rectfloat : IB_rect));
ibuf_stereo = IMB_allocImBuf(width, height, ibuf_left->planes, 0);
ibuf_stereo->rect_colorspace = ibuf_left->rect_colorspace;
ibuf_stereo->float_colorspace = ibuf_left->float_colorspace;
if (is_float) {
imb_addrectfloatImBuf(ibuf_stereo, ibuf_left->channels);
}
else {
imb_addrectImBuf(ibuf_stereo);
}
ibuf_stereo->flags = ibuf_left->flags;
@ -773,7 +776,7 @@ ImBuf *IMB_stereo3d_ImBuf(const ImageFormatData *im_format, ImBuf *ibuf_left, Im
is_float,
ibuf_left->x,
ibuf_left->y,
4,
ibuf_left->channels,
(int *)ibuf_left->rect,
(int *)ibuf_right->rect,
(int *)ibuf_stereo->rect,
@ -1286,10 +1289,17 @@ void IMB_ImBufFromStereo3d(const Stereo3dFormat *s3d,
&width,
&height);
ibuf_left = IMB_allocImBuf(
width, height, ibuf_stereo3d->planes, (is_float ? IB_rectfloat : IB_rect));
ibuf_right = IMB_allocImBuf(
width, height, ibuf_stereo3d->planes, (is_float ? IB_rectfloat : IB_rect));
ibuf_left = IMB_allocImBuf(width, height, ibuf_stereo3d->planes, 0);
ibuf_right = IMB_allocImBuf(width, height, ibuf_stereo3d->planes, 0);
if (is_float) {
imb_addrectfloatImBuf(ibuf_left, ibuf_stereo3d->channels);
imb_addrectfloatImBuf(ibuf_right, ibuf_stereo3d->channels);
}
else {
imb_addrectImBuf(ibuf_left);
imb_addrectImBuf(ibuf_right);
}
ibuf_left->flags = ibuf_stereo3d->flags;
ibuf_right->flags = ibuf_stereo3d->flags;
@ -1307,7 +1317,7 @@ void IMB_ImBufFromStereo3d(const Stereo3dFormat *s3d,
is_float,
ibuf_left->x,
ibuf_left->y,
4,
ibuf_left->channels,
(int *)ibuf_left->rect,
(int *)ibuf_right->rect,
(int *)ibuf_stereo3d->rect,

View File

@ -598,7 +598,7 @@ static void modifier_color_balance_apply(
ColorBalanceInitData init_data;
if (!ibuf->rect_float && make_float) {
imb_addrectfloatImBuf(ibuf);
imb_addrectfloatImBuf(ibuf, 4);
}
init_data.cb = cb;

View File

@ -134,7 +134,7 @@ void seq_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float)
/* We perform conversion to a float buffer so we don't worry about
* precision loss.
*/
imb_addrectfloatImBuf(ibuf);
imb_addrectfloatImBuf(ibuf, 4);
IMB_colormanagement_transform_from_byte_threaded(ibuf->rect_float,
(unsigned char *)ibuf->rect,
ibuf->x,