Fix #120175: File Output node has wrong BW output

The File Output node produces wrong output when the output is set to BW.
This is because the image saving logic assumes float buffers always have
4 channels and ignores the image buffer channels member. So for single
channel images, the code weighted sum neighbouring pixels and asigned
them as a single pixel, producing bleeding at best and crashes at worst.

To fix this, we skip Color to BW conversion if the image is already BW.
And, we fix the functions that assume 4 channels for float buffers.

Pull Request: https://projects.blender.org/blender/blender/pulls/120206
This commit is contained in:
Omar Emara
2024-04-04 08:51:57 +02:00
committed by Omar Emara
parent 7e9f7320e4
commit 0c91ad9008
2 changed files with 12 additions and 6 deletions

View File

@@ -844,8 +844,10 @@ void IMB_color_to_bw(ImBuf *ibuf)
size_t i;
if (rct_fl) {
for (i = IMB_get_rect_len(ibuf); i > 0; i--, rct_fl += 4) {
rct_fl[0] = rct_fl[1] = rct_fl[2] = IMB_colormanagement_get_luminance(rct_fl);
if (ibuf->channels >= 3) {
for (i = IMB_get_rect_len(ibuf); i > 0; i--, rct_fl += ibuf->channels) {
rct_fl[0] = rct_fl[1] = rct_fl[2] = IMB_colormanagement_get_luminance(rct_fl);
}
}
}
@@ -880,9 +882,11 @@ void IMB_saturation(ImBuf *ibuf, float sat)
}
if (rct_fl) {
for (i = IMB_get_rect_len(ibuf); i > 0; i--, rct_fl += 4) {
rgb_to_hsv_v(rct_fl, hsv);
hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rct_fl, rct_fl + 1, rct_fl + 2);
if (ibuf->channels >= 3) {
for (i = IMB_get_rect_len(ibuf); i > 0; i--, rct_fl += ibuf->channels) {
rgb_to_hsv_v(rct_fl, hsv);
hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rct_fl, rct_fl + 1, rct_fl + 2);
}
}
}
}

View File

@@ -1115,7 +1115,9 @@ ImBuf *RE_render_result_rect_to_ibuf(RenderResult *rr,
/* Color -> gray-scale. */
/* editing directly would alter the render view */
if (imf->planes == R_IMF_PLANES_BW && imf->imtype != R_IMF_IMTYPE_MULTILAYER) {
if (imf->planes == R_IMF_PLANES_BW && imf->imtype != R_IMF_IMTYPE_MULTILAYER &&
!(ibuf->float_buffer.data && !ibuf->byte_buffer.data && ibuf->channels == 1))
{
ImBuf *ibuf_bw = IMB_dupImBuf(ibuf);
IMB_color_to_bw(ibuf_bw);
IMB_freeImBuf(ibuf);