WIP: IMB: Allow BW images in byte to float conversion #118622
|
@ -453,9 +453,7 @@ void IMB_buffer_byte_from_float_mask(unsigned char *rect_to,
|
|||
*/
|
||||
void IMB_buffer_float_from_byte(float *rect_to,
|
||||
const unsigned char *rect_from,
|
||||
int profile_to,
|
||||
int profile_from,
|
||||
bool predivide,
|
||||
int channels,
|
||||
int width,
|
||||
int height,
|
||||
int stride_to,
|
||||
|
|
|
@ -1651,15 +1651,8 @@ static void *do_display_buffer_apply_thread(void *handle_v)
|
|||
}
|
||||
|
||||
if (display_buffer) {
|
||||
IMB_buffer_float_from_byte(display_buffer,
|
||||
handle->byte_buffer,
|
||||
IB_PROFILE_SRGB,
|
||||
IB_PROFILE_SRGB,
|
||||
false,
|
||||
width,
|
||||
height,
|
||||
width,
|
||||
width);
|
||||
IMB_buffer_float_from_byte(
|
||||
display_buffer, handle->byte_buffer, channels, width, height, width, width);
|
||||
}
|
||||
OmarEmaraDev marked this conversation as resolved
|
||||
}
|
||||
else {
|
||||
|
@ -1903,15 +1896,7 @@ static void *do_processor_transform_thread(void *handle_v)
|
|||
const bool float_from_byte = handle->float_from_byte;
|
||||
|
||||
if (float_from_byte) {
|
||||
IMB_buffer_float_from_byte(float_buffer,
|
||||
byte_buffer,
|
||||
IB_PROFILE_SRGB,
|
||||
IB_PROFILE_SRGB,
|
||||
false,
|
||||
width,
|
||||
height,
|
||||
width,
|
||||
width);
|
||||
IMB_buffer_float_from_byte(float_buffer, byte_buffer, channels, width, height, width, width);
|
||||
IMB_colormanagement_processor_apply(
|
||||
handle->cm_processor, float_buffer, width, height, channels, predivide);
|
||||
IMB_premultiply_rect_float(float_buffer, 4, width, height);
|
||||
|
@ -2063,15 +2048,7 @@ void IMB_colormanagement_transform_from_byte(float *float_buffer,
|
|||
const char *from_colorspace,
|
||||
const char *to_colorspace)
|
||||
{
|
||||
IMB_buffer_float_from_byte(float_buffer,
|
||||
byte_buffer,
|
||||
IB_PROFILE_SRGB,
|
||||
IB_PROFILE_SRGB,
|
||||
true,
|
||||
width,
|
||||
height,
|
||||
width,
|
||||
width);
|
||||
IMB_buffer_float_from_byte(float_buffer, byte_buffer, channels, width, height, width, width);
|
||||
IMB_colormanagement_transform(
|
||||
float_buffer, width, height, channels, from_colorspace, to_colorspace, true);
|
||||
}
|
||||
|
@ -3618,15 +3595,8 @@ static void partial_buffer_update_rect(ImBuf *ibuf,
|
|||
else {
|
||||
if (display_buffer_float) {
|
||||
/* huh, for dither we need float buffer first, no cheaper way. currently */
|
||||
IMB_buffer_float_from_byte(display_buffer_float,
|
||||
byte_buffer,
|
||||
IB_PROFILE_SRGB,
|
||||
IB_PROFILE_SRGB,
|
||||
true,
|
||||
width,
|
||||
height,
|
||||
width,
|
||||
display_stride);
|
||||
IMB_buffer_float_from_byte(
|
||||
display_buffer_float, byte_buffer, channels, width, height, width, display_stride);
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
|
|
|
@ -349,58 +349,19 @@ void IMB_buffer_byte_from_float_mask(uchar *rect_to,
|
|||
|
||||
void IMB_buffer_float_from_byte(float *rect_to,
|
||||
const uchar *rect_from,
|
||||
int profile_to,
|
||||
int profile_from,
|
||||
bool predivide,
|
||||
int channels,
|
||||
int width,
|
||||
int height,
|
||||
int stride_to,
|
||||
int stride_from)
|
||||
{
|
||||
float tmp[4];
|
||||
int x, y;
|
||||
|
||||
/* we need valid profiles */
|
||||
BLI_assert(profile_to != IB_PROFILE_NONE);
|
||||
BLI_assert(profile_from != IB_PROFILE_NONE);
|
||||
|
||||
/* RGBA input */
|
||||
for (y = 0; y < height; y++) {
|
||||
const uchar *from = rect_from + size_t(stride_from) * y * 4;
|
||||
float *to = rect_to + size_t(stride_to) * y * 4;
|
||||
|
||||
if (profile_to == profile_from) {
|
||||
/* no color space conversion */
|
||||
for (x = 0; x < width; x++, from += 4, to += 4) {
|
||||
rgba_uchar_to_float(to, from);
|
||||
}
|
||||
}
|
||||
else if (profile_to == IB_PROFILE_LINEAR_RGB) {
|
||||
/* convert sRGB to linear */
|
||||
if (predivide) {
|
||||
for (x = 0; x < width; x++, from += 4, to += 4) {
|
||||
srgb_to_linearrgb_uchar4_predivide(to, from);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (x = 0; x < width; x++, from += 4, to += 4) {
|
||||
srgb_to_linearrgb_uchar4(to, from);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (profile_to == IB_PROFILE_SRGB) {
|
||||
/* convert linear to sRGB */
|
||||
if (predivide) {
|
||||
for (x = 0; x < width; x++, from += 4, to += 4) {
|
||||
rgba_uchar_to_float(tmp, from);
|
||||
linearrgb_to_srgb_predivide_v4(to, tmp);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (x = 0; x < width; x++, from += 4, to += 4) {
|
||||
rgba_uchar_to_float(tmp, from);
|
||||
linearrgb_to_srgb_v4(to, tmp);
|
||||
}
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int i = 0; i < channels; i++) {
|
||||
/* Bytes buffers are always 4 channel in image buffers. */
|
||||
const size_t from_index = (y * stride_from + x) * 4 + i;
|
||||
const size_t to_index = (y * stride_to + x) * channels + i;
|
||||
rect_to[to_index] = float(rect_from[from_index]) / 255.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -755,7 +716,7 @@ void IMB_float_from_rect_ex(ImBuf *dst, const ImBuf *src, const rcti *region_to_
|
|||
"Source buffer should have a byte buffer assigned.");
|
||||
BLI_assert_msg(dst->x == src->x, "Source and destination buffer should have the same dimension");
|
||||
BLI_assert_msg(dst->y == src->y, "Source and destination buffer should have the same dimension");
|
||||
BLI_assert_msg(dst->channels = 4, "Destination buffer should have 4 channels.");
|
||||
BLI_assert_msg(dst->channels > 0, "Destination buffer should have at least one channel.");
|
||||
OmarEmaraDev marked this conversation as resolved
Outdated
Sergey Sharybin
commented
I am not sure this is semantically correct in this context. The Do we even need this assert now? The code does no longer assume 4 elements pixels stride. Can perhaps assert I am not sure this is semantically correct in this context. The `src` is the image with byte buffer, the `dst` is the image with float buffer. The `imBuf::channels` as per comment is valid for float buffers. So, since the `src` is byte-only, I can not say what it'll have in its `channels`.
Do we even need this assert now? The code does no longer assume 4 elements pixels stride. Can perhaps assert `dst->channels >= 1` to catch uninitialized values.
|
||||
BLI_assert_msg(region_to_update->xmin >= 0,
|
||||
"Region to update should be clipped to the given buffers.");
|
||||
BLI_assert_msg(region_to_update->ymin >= 0,
|
||||
|
@ -766,29 +727,22 @@ void IMB_float_from_rect_ex(ImBuf *dst, const ImBuf *src, const rcti *region_to_
|
|||
"Region to update should be clipped to the given buffers.");
|
||||
|
||||
float *rect_float = dst->float_buffer.data;
|
||||
rect_float += (region_to_update->xmin + region_to_update->ymin * dst->x) * 4;
|
||||
rect_float += (region_to_update->xmin + region_to_update->ymin * dst->x) * dst->channels;
|
||||
uchar *rect = src->byte_buffer.data;
|
||||
rect += (region_to_update->xmin + region_to_update->ymin * dst->x) * 4;
|
||||
rect += (region_to_update->xmin + region_to_update->ymin * dst->x) * dst->channels;
|
||||
const int region_width = BLI_rcti_size_x(region_to_update);
|
||||
const int region_height = BLI_rcti_size_y(region_to_update);
|
||||
|
||||
/* Convert byte buffer to float buffer without color or alpha conversion. */
|
||||
IMB_buffer_float_from_byte(rect_float,
|
||||
rect,
|
||||
IB_PROFILE_SRGB,
|
||||
IB_PROFILE_SRGB,
|
||||
false,
|
||||
region_width,
|
||||
region_height,
|
||||
src->x,
|
||||
dst->x);
|
||||
IMB_buffer_float_from_byte(
|
||||
rect_float, rect, dst->channels, region_width, region_height, src->x, dst->x);
|
||||
|
||||
/* Perform color space conversion from rect color space to linear. */
|
||||
float *float_ptr = rect_float;
|
||||
for (int i = 0; i < region_height; i++) {
|
||||
IMB_colormanagement_colorspace_to_scene_linear(
|
||||
float_ptr, region_width, 1, dst->channels, src->byte_buffer.colorspace, false);
|
||||
float_ptr += 4 * dst->x;
|
||||
float_ptr += dst->channels * dst->x;
|
||||
}
|
||||
|
||||
/* Perform alpha conversion. */
|
||||
|
@ -796,7 +750,7 @@ void IMB_float_from_rect_ex(ImBuf *dst, const ImBuf *src, const rcti *region_to_
|
|||
float_ptr = rect_float;
|
||||
for (int i = 0; i < region_height; i++) {
|
||||
IMB_premultiply_rect_float(float_ptr, dst->channels, region_width, 1);
|
||||
float_ptr += 4 * dst->x;
|
||||
float_ptr += dst->channels * dst->x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -814,15 +768,24 @@ void IMB_float_from_rect(ImBuf *ibuf)
|
|||
*/
|
||||
float *rect_float = ibuf->float_buffer.data;
|
||||
if (rect_float == nullptr) {
|
||||
const size_t size = IMB_get_rect_len(ibuf) * sizeof(float[4]);
|
||||
/* For color spaces other than sRGB and linear, we force full RGBA channels since color space
|
||||
* conversion might introduce color shifts even for greyscale images. */
|
||||
if (!(IMB_colormanagement_space_is_srgb(ibuf->byte_buffer.colorspace) ||
|
||||
IMB_colormanagement_space_is_scene_linear(ibuf->byte_buffer.colorspace)))
|
||||
{
|
||||
OmarEmaraDev marked this conversation as resolved
Outdated
Sergey Sharybin
commented
Wow, surely this is not an issue with this patch, but we should not be assigning the number of channels as part of an assert expression. Wow, surely this is not an issue with this patch, but we should not be assigning the number of channels as part of an assert expression.
|
||||
ibuf->channels = 4;
|
||||
}
|
||||
else {
|
||||
OmarEmaraDev marked this conversation as resolved
Outdated
Sergey Sharybin
commented
Shouldn't we initialize Shouldn't we initialize `ibuf->channels` based on the number of planes in the `else` branch here? Otherwise it could left uninitialized, or initialized to some default value which is not necessarily corresponding to the desired value?
Omar Emara
commented
Yah, sorry. Was remnant from the time where I though channels was shared between both byte and float buffers. Yah, sorry. Was remnant from the time where I though channels was shared between both byte and float buffers.
|
||||
ibuf->channels = ibuf->planes / 8;
|
||||
}
|
||||
|
||||
const size_t size = IMB_get_rect_len(ibuf) * ibuf->channels * sizeof(float);
|
||||
rect_float = static_cast<float *>(MEM_callocN(size, "IMB_float_from_rect"));
|
||||
|
||||
if (rect_float == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
ibuf->channels = 4;
|
||||
|
||||
IMB_assign_float_buffer(ibuf, rect_float, IB_TAKE_OWNERSHIP);
|
||||
}
|
||||
|
||||
|
|
I think we should start removing this legacy profile. Will help simplifying this change as well, and I don't think we ever do color space conversion.