Fix #126108: Crash when EXR image is loaded in image list
Technically the regression was caused by #124472 which made it so duplicating ImBuf allocates the exact amount of memory needed to hold the pixels, while before IMB_dupImBuf() would leave the float buffer over-allocated for images that are less than 4 channels per pixel. At the same time IMB_scalefastImBuf() was hard-coded to use 4 channels per pixels, for both byte and float buffers. It did not crash in Blender 4.1 as it was accessing memory that is over-allocated, but it also did not generate proper preview. This fix makes the IMB_scalefastImBuf() to operate on an arbitrary number of channels in the float buffer. Pull Request: https://projects.blender.org/blender/blender/pulls/126234
This commit is contained in:
committed by
Sergey Sharybin
parent
847a3a7ea3
commit
1fc6a5b9bd
@@ -1473,16 +1473,12 @@ bool IMB_scaleImBuf(ImBuf *ibuf, uint newx, uint newy)
|
||||
return true;
|
||||
}
|
||||
|
||||
struct imbufRGBA {
|
||||
float r, g, b, a;
|
||||
};
|
||||
|
||||
bool IMB_scalefastImBuf(ImBuf *ibuf, uint newx, uint newy)
|
||||
{
|
||||
BLI_assert_msg(newx > 0 && newy > 0, "Images must be at least 1 on both dimensions!");
|
||||
|
||||
uint *rect, *_newrect, *newrect;
|
||||
imbufRGBA *rectf, *_newrectf, *newrectf;
|
||||
float *rectf, *_newrectf, *newrectf;
|
||||
int x, y;
|
||||
bool do_float = false, do_rect = false;
|
||||
size_t ofsx, ofsy, stepx, stepy;
|
||||
@@ -1520,8 +1516,8 @@ bool IMB_scalefastImBuf(ImBuf *ibuf, uint newx, uint newy)
|
||||
}
|
||||
|
||||
if (do_float) {
|
||||
_newrectf = static_cast<imbufRGBA *>(
|
||||
MEM_mallocN(sizeof(float[4]) * newx * newy, "scalefastimbuf f"));
|
||||
_newrectf = static_cast<float *>(
|
||||
MEM_mallocN(sizeof(float) * ibuf->channels * newx * newy, "scalefastimbuf f"));
|
||||
if (_newrectf == nullptr) {
|
||||
if (_newrect) {
|
||||
MEM_freeN(_newrect);
|
||||
@@ -1547,12 +1543,15 @@ bool IMB_scalefastImBuf(ImBuf *ibuf, uint newx, uint newy)
|
||||
}
|
||||
|
||||
if (do_float) {
|
||||
rectf = (imbufRGBA *)ibuf->float_buffer.data;
|
||||
rectf += (ofsy >> 16) * ibuf->x;
|
||||
rectf = ibuf->float_buffer.data;
|
||||
rectf += size_t(ofsy >> 16) * ibuf->x * ibuf->channels;
|
||||
ofsx = 32768;
|
||||
|
||||
for (x = newx; x > 0; x--, ofsx += stepx) {
|
||||
*newrectf++ = rectf[ofsx >> 16];
|
||||
float *pixel = &rectf[size_t(ofsx >> 16) * ibuf->channels];
|
||||
for (int c = 0; c < ibuf->channels; ++c) {
|
||||
*newrectf++ = pixel[c];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user