diff options
Diffstat (limited to 'source/blender/imbuf/intern/divers.c')
-rw-r--r-- | source/blender/imbuf/intern/divers.c | 1515 |
1 files changed, 792 insertions, 723 deletions
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index d1997e4612d..fb8dcffe9d4 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -33,469 +33,495 @@ #include "IMB_colormanagement.h" #include "IMB_colormanagement_intern.h" - #include "MEM_guardedalloc.h" /************************* Floyd-Steinberg dithering *************************/ typedef struct DitherContext { - float dither; + float dither; } DitherContext; static DitherContext *create_dither_context(float dither) { - DitherContext *di; + DitherContext *di; - di = MEM_mallocN(sizeof(DitherContext), "dithering context"); - di->dither = dither; + di = MEM_mallocN(sizeof(DitherContext), "dithering context"); + di->dither = dither; - return di; + return di; } static void clear_dither_context(DitherContext *di) { - MEM_freeN(di); + MEM_freeN(di); } - /************************* Generic Buffer Conversion *************************/ MINLINE void ushort_to_byte_v4(uchar b[4], const unsigned short us[4]) { - b[0] = unit_ushort_to_uchar(us[0]); - b[1] = unit_ushort_to_uchar(us[1]); - b[2] = unit_ushort_to_uchar(us[2]); - b[3] = unit_ushort_to_uchar(us[3]); + b[0] = unit_ushort_to_uchar(us[0]); + b[1] = unit_ushort_to_uchar(us[1]); + b[2] = unit_ushort_to_uchar(us[2]); + b[3] = unit_ushort_to_uchar(us[3]); } MINLINE unsigned char ftochar(float value) { - return unit_float_to_uchar_clamp(value); + return unit_float_to_uchar_clamp(value); } -MINLINE void ushort_to_byte_dither_v4(uchar b[4], const unsigned short us[4], DitherContext *di, float s, float t) +MINLINE void ushort_to_byte_dither_v4( + uchar b[4], const unsigned short us[4], DitherContext *di, float s, float t) { #define USHORTTOFLOAT(val) ((float)val / 65535.0f) - float dither_value = dither_random_value(s, t) * 0.005f * di->dither; + float dither_value = dither_random_value(s, t) * 0.005f * di->dither; - b[0] = ftochar(dither_value + USHORTTOFLOAT(us[0])); - b[1] = ftochar(dither_value + USHORTTOFLOAT(us[1])); - b[2] = ftochar(dither_value + USHORTTOFLOAT(us[2])); - b[3] = unit_ushort_to_uchar(us[3]); + b[0] = ftochar(dither_value + USHORTTOFLOAT(us[0])); + b[1] = ftochar(dither_value + USHORTTOFLOAT(us[1])); + b[2] = ftochar(dither_value + USHORTTOFLOAT(us[2])); + b[3] = unit_ushort_to_uchar(us[3]); #undef USHORTTOFLOAT } -MINLINE void float_to_byte_dither_v4(uchar b[4], const float f[4], DitherContext *di, float s, float t) +MINLINE void float_to_byte_dither_v4( + uchar b[4], const float f[4], DitherContext *di, float s, float t) { - float dither_value = dither_random_value(s, t) * 0.005f * di->dither; + float dither_value = dither_random_value(s, t) * 0.005f * di->dither; - b[0] = ftochar(dither_value + f[0]); - b[1] = ftochar(dither_value + f[1]); - b[2] = ftochar(dither_value + f[2]); - b[3] = unit_float_to_uchar_clamp(f[3]); + b[0] = ftochar(dither_value + f[0]); + b[1] = ftochar(dither_value + f[1]); + b[2] = ftochar(dither_value + f[2]); + b[3] = unit_float_to_uchar_clamp(f[3]); } /* float to byte pixels, output 4-channel RGBA */ -void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from, - int channels_from, float dither, int profile_to, int profile_from, bool predivide, - int width, int height, int stride_to, int stride_from) +void IMB_buffer_byte_from_float(uchar *rect_to, + const float *rect_from, + int channels_from, + float dither, + int profile_to, + int profile_from, + bool predivide, + int width, + int height, + int stride_to, + int stride_from) { - float tmp[4]; - int x, y; - DitherContext *di = NULL; - float inv_width = 1.0f / width; - float inv_height = 1.0f / height; - - /* we need valid profiles */ - BLI_assert(profile_to != IB_PROFILE_NONE); - BLI_assert(profile_from != IB_PROFILE_NONE); - - if (dither) - di = create_dither_context(dither); - - for (y = 0; y < height; y++) { - float t = y * inv_height; - - if (channels_from == 1) { - /* single channel input */ - const float *from = rect_from + ((size_t)stride_from) * y; - uchar *to = rect_to + ((size_t)stride_to) * y * 4; - - for (x = 0; x < width; x++, from++, to += 4) - to[0] = to[1] = to[2] = to[3] = unit_float_to_uchar_clamp(from[0]); - } - else if (channels_from == 3) { - /* RGB input */ - const float *from = rect_from + ((size_t)stride_from) * y * 3; - uchar *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 += 3, to += 4) { - rgb_float_to_uchar(to, from); - to[3] = 255; - } - } - else if (profile_to == IB_PROFILE_SRGB) { - /* convert from linear to sRGB */ - for (x = 0; x < width; x++, from += 3, to += 4) { - linearrgb_to_srgb_v3_v3(tmp, from); - rgb_float_to_uchar(to, tmp); - to[3] = 255; - } - } - else if (profile_to == IB_PROFILE_LINEAR_RGB) { - /* convert from sRGB to linear */ - for (x = 0; x < width; x++, from += 3, to += 4) { - srgb_to_linearrgb_v3_v3(tmp, from); - rgb_float_to_uchar(to, tmp); - to[3] = 255; - } - } - } - else if (channels_from == 4) { - /* RGBA input */ - const float *from = rect_from + ((size_t)stride_from) * y * 4; - uchar *to = rect_to + ((size_t)stride_to) * y * 4; - - if (profile_to == profile_from) { - float straight[4]; - - /* no color space conversion */ - if (dither && predivide) { - for (x = 0; x < width; x++, from += 4, to += 4) { - premul_to_straight_v4_v4(straight, from); - float_to_byte_dither_v4(to, straight, di, (float) x * inv_width, t); - } - } - else if (dither) { - for (x = 0; x < width; x++, from += 4, to += 4) - float_to_byte_dither_v4(to, from, di, (float) x * inv_width, t); - } - else if (predivide) { - for (x = 0; x < width; x++, from += 4, to += 4) { - premul_to_straight_v4_v4(straight, from); - rgba_float_to_uchar(to, straight); - } - } - else { - for (x = 0; x < width; x++, from += 4, to += 4) - rgba_float_to_uchar(to, from); - } - } - else if (profile_to == IB_PROFILE_SRGB) { - /* convert from linear to sRGB */ - unsigned short us[4]; - float straight[4]; - - if (dither && predivide) { - for (x = 0; x < width; x++, from += 4, to += 4) { - premul_to_straight_v4_v4(straight, from); - linearrgb_to_srgb_ushort4(us, from); - ushort_to_byte_dither_v4(to, us, di, (float) x * inv_width, t); - } - } - else if (dither) { - for (x = 0; x < width; x++, from += 4, to += 4) { - linearrgb_to_srgb_ushort4(us, from); - ushort_to_byte_dither_v4(to, us, di, (float) x * inv_width, t); - } - } - else if (predivide) { - for (x = 0; x < width; x++, from += 4, to += 4) { - premul_to_straight_v4_v4(straight, from); - linearrgb_to_srgb_ushort4(us, from); - ushort_to_byte_v4(to, us); - } - } - else { - for (x = 0; x < width; x++, from += 4, to += 4) { - linearrgb_to_srgb_ushort4(us, from); - ushort_to_byte_v4(to, us); - } - } - } - else if (profile_to == IB_PROFILE_LINEAR_RGB) { - /* convert from sRGB to linear */ - if (dither && predivide) { - for (x = 0; x < width; x++, from += 4, to += 4) { - srgb_to_linearrgb_predivide_v4(tmp, from); - float_to_byte_dither_v4(to, tmp, di, (float) x * inv_width, t); - } - } - else if (dither) { - for (x = 0; x < width; x++, from += 4, to += 4) { - srgb_to_linearrgb_v4(tmp, from); - float_to_byte_dither_v4(to, tmp, di, (float) x * inv_width, t); - } - } - else if (predivide) { - for (x = 0; x < width; x++, from += 4, to += 4) { - srgb_to_linearrgb_predivide_v4(tmp, from); - rgba_float_to_uchar(to, tmp); - } - } - else { - for (x = 0; x < width; x++, from += 4, to += 4) { - srgb_to_linearrgb_v4(tmp, from); - rgba_float_to_uchar(to, tmp); - } - } - } - } - } - - if (dither) - clear_dither_context(di); + float tmp[4]; + int x, y; + DitherContext *di = NULL; + float inv_width = 1.0f / width; + float inv_height = 1.0f / height; + + /* we need valid profiles */ + BLI_assert(profile_to != IB_PROFILE_NONE); + BLI_assert(profile_from != IB_PROFILE_NONE); + + if (dither) + di = create_dither_context(dither); + + for (y = 0; y < height; y++) { + float t = y * inv_height; + + if (channels_from == 1) { + /* single channel input */ + const float *from = rect_from + ((size_t)stride_from) * y; + uchar *to = rect_to + ((size_t)stride_to) * y * 4; + + for (x = 0; x < width; x++, from++, to += 4) + to[0] = to[1] = to[2] = to[3] = unit_float_to_uchar_clamp(from[0]); + } + else if (channels_from == 3) { + /* RGB input */ + const float *from = rect_from + ((size_t)stride_from) * y * 3; + uchar *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 += 3, to += 4) { + rgb_float_to_uchar(to, from); + to[3] = 255; + } + } + else if (profile_to == IB_PROFILE_SRGB) { + /* convert from linear to sRGB */ + for (x = 0; x < width; x++, from += 3, to += 4) { + linearrgb_to_srgb_v3_v3(tmp, from); + rgb_float_to_uchar(to, tmp); + to[3] = 255; + } + } + else if (profile_to == IB_PROFILE_LINEAR_RGB) { + /* convert from sRGB to linear */ + for (x = 0; x < width; x++, from += 3, to += 4) { + srgb_to_linearrgb_v3_v3(tmp, from); + rgb_float_to_uchar(to, tmp); + to[3] = 255; + } + } + } + else if (channels_from == 4) { + /* RGBA input */ + const float *from = rect_from + ((size_t)stride_from) * y * 4; + uchar *to = rect_to + ((size_t)stride_to) * y * 4; + + if (profile_to == profile_from) { + float straight[4]; + + /* no color space conversion */ + if (dither && predivide) { + for (x = 0; x < width; x++, from += 4, to += 4) { + premul_to_straight_v4_v4(straight, from); + float_to_byte_dither_v4(to, straight, di, (float)x * inv_width, t); + } + } + else if (dither) { + for (x = 0; x < width; x++, from += 4, to += 4) + float_to_byte_dither_v4(to, from, di, (float)x * inv_width, t); + } + else if (predivide) { + for (x = 0; x < width; x++, from += 4, to += 4) { + premul_to_straight_v4_v4(straight, from); + rgba_float_to_uchar(to, straight); + } + } + else { + for (x = 0; x < width; x++, from += 4, to += 4) + rgba_float_to_uchar(to, from); + } + } + else if (profile_to == IB_PROFILE_SRGB) { + /* convert from linear to sRGB */ + unsigned short us[4]; + float straight[4]; + + if (dither && predivide) { + for (x = 0; x < width; x++, from += 4, to += 4) { + premul_to_straight_v4_v4(straight, from); + linearrgb_to_srgb_ushort4(us, from); + ushort_to_byte_dither_v4(to, us, di, (float)x * inv_width, t); + } + } + else if (dither) { + for (x = 0; x < width; x++, from += 4, to += 4) { + linearrgb_to_srgb_ushort4(us, from); + ushort_to_byte_dither_v4(to, us, di, (float)x * inv_width, t); + } + } + else if (predivide) { + for (x = 0; x < width; x++, from += 4, to += 4) { + premul_to_straight_v4_v4(straight, from); + linearrgb_to_srgb_ushort4(us, from); + ushort_to_byte_v4(to, us); + } + } + else { + for (x = 0; x < width; x++, from += 4, to += 4) { + linearrgb_to_srgb_ushort4(us, from); + ushort_to_byte_v4(to, us); + } + } + } + else if (profile_to == IB_PROFILE_LINEAR_RGB) { + /* convert from sRGB to linear */ + if (dither && predivide) { + for (x = 0; x < width; x++, from += 4, to += 4) { + srgb_to_linearrgb_predivide_v4(tmp, from); + float_to_byte_dither_v4(to, tmp, di, (float)x * inv_width, t); + } + } + else if (dither) { + for (x = 0; x < width; x++, from += 4, to += 4) { + srgb_to_linearrgb_v4(tmp, from); + float_to_byte_dither_v4(to, tmp, di, (float)x * inv_width, t); + } + } + else if (predivide) { + for (x = 0; x < width; x++, from += 4, to += 4) { + srgb_to_linearrgb_predivide_v4(tmp, from); + rgba_float_to_uchar(to, tmp); + } + } + else { + for (x = 0; x < width; x++, from += 4, to += 4) { + srgb_to_linearrgb_v4(tmp, from); + rgba_float_to_uchar(to, tmp); + } + } + } + } + } + + if (dither) + clear_dither_context(di); } - /* float to byte pixels, output 4-channel RGBA */ -void IMB_buffer_byte_from_float_mask(uchar *rect_to, const float *rect_from, - int channels_from, float dither, bool predivide, - int width, int height, int stride_to, int stride_from, char *mask) +void IMB_buffer_byte_from_float_mask(uchar *rect_to, + const float *rect_from, + int channels_from, + float dither, + bool predivide, + int width, + int height, + int stride_to, + int stride_from, + char *mask) { - int x, y; - DitherContext *di = NULL; - float inv_width = 1.0f / width, - inv_height = 1.0f / height; - - if (dither) - di = create_dither_context(dither); - - for (y = 0; y < height; y++) { - float t = y * inv_height; - - if (channels_from == 1) { - /* single channel input */ - const float *from = rect_from + ((size_t)stride_from) * y; - uchar *to = rect_to + ((size_t)stride_to) * y * 4; - - for (x = 0; x < width; x++, from++, to += 4) - if (*mask++ == FILTER_MASK_USED) - to[0] = to[1] = to[2] = to[3] = unit_float_to_uchar_clamp(from[0]); - } - else if (channels_from == 3) { - /* RGB input */ - const float *from = rect_from + ((size_t)stride_from) * y * 3; - uchar *to = rect_to + ((size_t)stride_to) * y * 4; - - for (x = 0; x < width; x++, from += 3, to += 4) { - if (*mask++ == FILTER_MASK_USED) { - rgb_float_to_uchar(to, from); - to[3] = 255; - } - } - } - else if (channels_from == 4) { - /* RGBA input */ - const float *from = rect_from + ((size_t)stride_from) * y * 4; - uchar *to = rect_to + ((size_t)stride_to) * y * 4; - - float straight[4]; - - if (dither && predivide) { - for (x = 0; x < width; x++, from += 4, to += 4) { - if (*mask++ == FILTER_MASK_USED) { - premul_to_straight_v4_v4(straight, from); - float_to_byte_dither_v4(to, straight, di, (float) x * inv_width, t); - } - } - } - else if (dither) { - for (x = 0; x < width; x++, from += 4, to += 4) - if (*mask++ == FILTER_MASK_USED) - float_to_byte_dither_v4(to, from, di, (float) x * inv_width, t); - } - else if (predivide) { - for (x = 0; x < width; x++, from += 4, to += 4) { - if (*mask++ == FILTER_MASK_USED) { - premul_to_straight_v4_v4(straight, from); - rgba_float_to_uchar(to, straight); - } - } - } - else { - for (x = 0; x < width; x++, from += 4, to += 4) - if (*mask++ == FILTER_MASK_USED) - rgba_float_to_uchar(to, from); - } - } - } - - if (dither) - clear_dither_context(di); + int x, y; + DitherContext *di = NULL; + float inv_width = 1.0f / width, inv_height = 1.0f / height; + + if (dither) + di = create_dither_context(dither); + + for (y = 0; y < height; y++) { + float t = y * inv_height; + + if (channels_from == 1) { + /* single channel input */ + const float *from = rect_from + ((size_t)stride_from) * y; + uchar *to = rect_to + ((size_t)stride_to) * y * 4; + + for (x = 0; x < width; x++, from++, to += 4) + if (*mask++ == FILTER_MASK_USED) + to[0] = to[1] = to[2] = to[3] = unit_float_to_uchar_clamp(from[0]); + } + else if (channels_from == 3) { + /* RGB input */ + const float *from = rect_from + ((size_t)stride_from) * y * 3; + uchar *to = rect_to + ((size_t)stride_to) * y * 4; + + for (x = 0; x < width; x++, from += 3, to += 4) { + if (*mask++ == FILTER_MASK_USED) { + rgb_float_to_uchar(to, from); + to[3] = 255; + } + } + } + else if (channels_from == 4) { + /* RGBA input */ + const float *from = rect_from + ((size_t)stride_from) * y * 4; + uchar *to = rect_to + ((size_t)stride_to) * y * 4; + + float straight[4]; + + if (dither && predivide) { + for (x = 0; x < width; x++, from += 4, to += 4) { + if (*mask++ == FILTER_MASK_USED) { + premul_to_straight_v4_v4(straight, from); + float_to_byte_dither_v4(to, straight, di, (float)x * inv_width, t); + } + } + } + else if (dither) { + for (x = 0; x < width; x++, from += 4, to += 4) + if (*mask++ == FILTER_MASK_USED) + float_to_byte_dither_v4(to, from, di, (float)x * inv_width, t); + } + else if (predivide) { + for (x = 0; x < width; x++, from += 4, to += 4) { + if (*mask++ == FILTER_MASK_USED) { + premul_to_straight_v4_v4(straight, from); + rgba_float_to_uchar(to, straight); + } + } + } + else { + for (x = 0; x < width; x++, from += 4, to += 4) + if (*mask++ == FILTER_MASK_USED) + rgba_float_to_uchar(to, from); + } + } + } + + if (dither) + clear_dither_context(di); } /* byte to float pixels, input and output 4-channel RGBA */ -void IMB_buffer_float_from_byte(float *rect_to, const uchar *rect_from, - int profile_to, int profile_from, bool predivide, - int width, int height, int stride_to, int stride_from) +void IMB_buffer_float_from_byte(float *rect_to, + const uchar *rect_from, + int profile_to, + int profile_from, + bool predivide, + 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 + 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); - } - } - } - } + 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 + 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); + } + } + } + } } /* float to float pixels, output 4-channel RGBA */ -void IMB_buffer_float_from_float(float *rect_to, const float *rect_from, - int channels_from, int profile_to, int profile_from, bool predivide, - int width, int height, int stride_to, int stride_from) +void IMB_buffer_float_from_float(float *rect_to, + const float *rect_from, + int channels_from, + int profile_to, + int profile_from, + bool predivide, + int width, + int height, + int stride_to, + int stride_from) { - int x, y; - - /* we need valid profiles */ - BLI_assert(profile_to != IB_PROFILE_NONE); - BLI_assert(profile_from != IB_PROFILE_NONE); - - if (channels_from == 1) { - /* single channel input */ - for (y = 0; y < height; y++) { - const float *from = rect_from + ((size_t)stride_from) * y; - float *to = rect_to + ((size_t)stride_to) * y * 4; - - for (x = 0; x < width; x++, from++, to += 4) - to[0] = to[1] = to[2] = to[3] = from[0]; - } - } - else if (channels_from == 3) { - /* RGB input */ - for (y = 0; y < height; y++) { - const float *from = rect_from + ((size_t)stride_from) * y * 3; - 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 += 3, to += 4) { - copy_v3_v3(to, from); - to[3] = 1.0f; - } - } - else if (profile_to == IB_PROFILE_LINEAR_RGB) { - /* convert from sRGB to linear */ - for (x = 0; x < width; x++, from += 3, to += 4) { - srgb_to_linearrgb_v3_v3(to, from); - to[3] = 1.0f; - } - } - else if (profile_to == IB_PROFILE_SRGB) { - /* convert from linear to sRGB */ - for (x = 0; x < width; x++, from += 3, to += 4) { - linearrgb_to_srgb_v3_v3(to, from); - to[3] = 1.0f; - } - } - } - } - else if (channels_from == 4) { - /* RGBA input */ - for (y = 0; y < height; y++) { - const float *from = rect_from + ((size_t)stride_from) * y * 4; - float *to = rect_to + ((size_t)stride_to) * y * 4; - - if (profile_to == profile_from) { - /* same profile, copy */ - memcpy(to, from, sizeof(float) * ((size_t)4) * width); - } - else if (profile_to == IB_PROFILE_LINEAR_RGB) { - /* convert to sRGB to linear */ - if (predivide) { - for (x = 0; x < width; x++, from += 4, to += 4) - srgb_to_linearrgb_predivide_v4(to, from); - } - else { - for (x = 0; x < width; x++, from += 4, to += 4) - srgb_to_linearrgb_v4(to, from); - } - } - else if (profile_to == IB_PROFILE_SRGB) { - /* convert from linear to sRGB */ - if (predivide) { - for (x = 0; x < width; x++, from += 4, to += 4) - linearrgb_to_srgb_predivide_v4(to, from); - } - else { - for (x = 0; x < width; x++, from += 4, to += 4) - linearrgb_to_srgb_v4(to, from); - } - } - } - } + int x, y; + + /* we need valid profiles */ + BLI_assert(profile_to != IB_PROFILE_NONE); + BLI_assert(profile_from != IB_PROFILE_NONE); + + if (channels_from == 1) { + /* single channel input */ + for (y = 0; y < height; y++) { + const float *from = rect_from + ((size_t)stride_from) * y; + float *to = rect_to + ((size_t)stride_to) * y * 4; + + for (x = 0; x < width; x++, from++, to += 4) + to[0] = to[1] = to[2] = to[3] = from[0]; + } + } + else if (channels_from == 3) { + /* RGB input */ + for (y = 0; y < height; y++) { + const float *from = rect_from + ((size_t)stride_from) * y * 3; + 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 += 3, to += 4) { + copy_v3_v3(to, from); + to[3] = 1.0f; + } + } + else if (profile_to == IB_PROFILE_LINEAR_RGB) { + /* convert from sRGB to linear */ + for (x = 0; x < width; x++, from += 3, to += 4) { + srgb_to_linearrgb_v3_v3(to, from); + to[3] = 1.0f; + } + } + else if (profile_to == IB_PROFILE_SRGB) { + /* convert from linear to sRGB */ + for (x = 0; x < width; x++, from += 3, to += 4) { + linearrgb_to_srgb_v3_v3(to, from); + to[3] = 1.0f; + } + } + } + } + else if (channels_from == 4) { + /* RGBA input */ + for (y = 0; y < height; y++) { + const float *from = rect_from + ((size_t)stride_from) * y * 4; + float *to = rect_to + ((size_t)stride_to) * y * 4; + + if (profile_to == profile_from) { + /* same profile, copy */ + memcpy(to, from, sizeof(float) * ((size_t)4) * width); + } + else if (profile_to == IB_PROFILE_LINEAR_RGB) { + /* convert to sRGB to linear */ + if (predivide) { + for (x = 0; x < width; x++, from += 4, to += 4) + srgb_to_linearrgb_predivide_v4(to, from); + } + else { + for (x = 0; x < width; x++, from += 4, to += 4) + srgb_to_linearrgb_v4(to, from); + } + } + else if (profile_to == IB_PROFILE_SRGB) { + /* convert from linear to sRGB */ + if (predivide) { + for (x = 0; x < width; x++, from += 4, to += 4) + linearrgb_to_srgb_predivide_v4(to, from); + } + else { + for (x = 0; x < width; x++, from += 4, to += 4) + linearrgb_to_srgb_v4(to, from); + } + } + } + } } typedef struct FloatToFloatThreadData { - float *rect_to; - const float *rect_from; - int channels_from; - int profile_to; - int profile_from; - bool predivide; - int width; - int stride_to; - int stride_from; + float *rect_to; + const float *rect_from; + int channels_from; + int profile_to; + int profile_from; + bool predivide; + int width; + int stride_to; + int stride_from; } FloatToFloatThreadData; static void imb_buffer_float_from_float_thread_do(void *data_v, int start_scanline, int num_scanlines) { - FloatToFloatThreadData *data = (FloatToFloatThreadData *)data_v; - size_t offset_from = ((size_t)start_scanline) * data->stride_from * data->channels_from; - size_t offset_to = ((size_t)start_scanline) * data->stride_to * data->channels_from; - IMB_buffer_float_from_float(data->rect_to + offset_to, - data->rect_from + offset_from, - data->channels_from, - data->profile_to, - data->profile_from, - data->predivide, - data->width, - num_scanlines, - data->stride_to, - data->stride_from); + FloatToFloatThreadData *data = (FloatToFloatThreadData *)data_v; + size_t offset_from = ((size_t)start_scanline) * data->stride_from * data->channels_from; + size_t offset_to = ((size_t)start_scanline) * data->stride_to * data->channels_from; + IMB_buffer_float_from_float(data->rect_to + offset_to, + data->rect_from + offset_from, + data->channels_from, + data->profile_to, + data->profile_from, + data->predivide, + data->width, + num_scanlines, + data->stride_to, + data->stride_from); } void IMB_buffer_float_from_float_threaded(float *rect_to, @@ -509,183 +535,209 @@ void IMB_buffer_float_from_float_threaded(float *rect_to, int stride_to, int stride_from) { - if (((size_t)width) * height < 64 * 64) { - IMB_buffer_float_from_float(rect_to, - rect_from, - channels_from, - profile_to, - profile_from, - predivide, - width, - height, - stride_to, - stride_from); - } - else { - FloatToFloatThreadData data; - data.rect_to = rect_to; - data.rect_from = rect_from; - data.channels_from = channels_from; - data.profile_to = profile_to; - data.profile_from = profile_from; - data.predivide = predivide; - data.width = width; - data.stride_to = stride_to; - data.stride_from = stride_from; - IMB_processor_apply_threaded_scanlines( - height, imb_buffer_float_from_float_thread_do, &data); - } + if (((size_t)width) * height < 64 * 64) { + IMB_buffer_float_from_float(rect_to, + rect_from, + channels_from, + profile_to, + profile_from, + predivide, + width, + height, + stride_to, + stride_from); + } + else { + FloatToFloatThreadData data; + data.rect_to = rect_to; + data.rect_from = rect_from; + data.channels_from = channels_from; + data.profile_to = profile_to; + data.profile_from = profile_from; + data.predivide = predivide; + data.width = width; + data.stride_to = stride_to; + data.stride_from = stride_from; + IMB_processor_apply_threaded_scanlines(height, imb_buffer_float_from_float_thread_do, &data); + } } /* float to float pixels, output 4-channel RGBA */ -void IMB_buffer_float_from_float_mask(float *rect_to, const float *rect_from, int channels_from, - int width, int height, int stride_to, int stride_from, char *mask) +void IMB_buffer_float_from_float_mask(float *rect_to, + const float *rect_from, + int channels_from, + int width, + int height, + int stride_to, + int stride_from, + char *mask) { - int x, y; - - if (channels_from == 1) { - /* single channel input */ - for (y = 0; y < height; y++) { - const float *from = rect_from + ((size_t)stride_from) * y; - float *to = rect_to + ((size_t)stride_to) * y * 4; - - for (x = 0; x < width; x++, from++, to += 4) - if (*mask++ == FILTER_MASK_USED) - to[0] = to[1] = to[2] = to[3] = from[0]; - } - } - else if (channels_from == 3) { - /* RGB input */ - for (y = 0; y < height; y++) { - const float *from = rect_from + ((size_t)stride_from) * y * 3; - float *to = rect_to + ((size_t)stride_to) * y * 4; - - for (x = 0; x < width; x++, from += 3, to += 4) { - if (*mask++ == FILTER_MASK_USED) { - copy_v3_v3(to, from); - to[3] = 1.0f; - } - } - } - } - else if (channels_from == 4) { - /* RGBA input */ - for (y = 0; y < height; y++) { - const float *from = rect_from + ((size_t)stride_from) * y * 4; - float *to = rect_to + ((size_t)stride_to) * y * 4; - - for (x = 0; x < width; x++, from += 4, to += 4) - if (*mask++ == FILTER_MASK_USED) - copy_v4_v4(to, from); - } - } + int x, y; + + if (channels_from == 1) { + /* single channel input */ + for (y = 0; y < height; y++) { + const float *from = rect_from + ((size_t)stride_from) * y; + float *to = rect_to + ((size_t)stride_to) * y * 4; + + for (x = 0; x < width; x++, from++, to += 4) + if (*mask++ == FILTER_MASK_USED) + to[0] = to[1] = to[2] = to[3] = from[0]; + } + } + else if (channels_from == 3) { + /* RGB input */ + for (y = 0; y < height; y++) { + const float *from = rect_from + ((size_t)stride_from) * y * 3; + float *to = rect_to + ((size_t)stride_to) * y * 4; + + for (x = 0; x < width; x++, from += 3, to += 4) { + if (*mask++ == FILTER_MASK_USED) { + copy_v3_v3(to, from); + to[3] = 1.0f; + } + } + } + } + else if (channels_from == 4) { + /* RGBA input */ + for (y = 0; y < height; y++) { + const float *from = rect_from + ((size_t)stride_from) * y * 4; + float *to = rect_to + ((size_t)stride_to) * y * 4; + + for (x = 0; x < width; x++, from += 4, to += 4) + if (*mask++ == FILTER_MASK_USED) + copy_v4_v4(to, from); + } + } } /* byte to byte pixels, input and output 4-channel RGBA */ -void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from, - int profile_to, int profile_from, bool predivide, - int width, int height, int stride_to, int stride_from) +void IMB_buffer_byte_from_byte(uchar *rect_to, + const uchar *rect_from, + int profile_to, + int profile_from, + bool predivide, + 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); - - /* always RGBA input */ - for (y = 0; y < height; y++) { - const uchar *from = rect_from + ((size_t)stride_from) * y * 4; - uchar *to = rect_to + ((size_t)stride_to) * y * 4; - - if (profile_to == profile_from) { - /* same profile, copy */ - memcpy(to, from, sizeof(uchar) * 4 * width); - } - else if (profile_to == IB_PROFILE_LINEAR_RGB) { - /* convert to sRGB to linear */ - if (predivide) { - for (x = 0; x < width; x++, from += 4, to += 4) { - rgba_uchar_to_float(tmp, from); - srgb_to_linearrgb_predivide_v4(tmp, tmp); - rgba_float_to_uchar(to, tmp); - } - } - else { - for (x = 0; x < width; x++, from += 4, to += 4) { - rgba_uchar_to_float(tmp, from); - srgb_to_linearrgb_v4(tmp, tmp); - rgba_float_to_uchar(to, tmp); - } - } - } - else if (profile_to == IB_PROFILE_SRGB) { - /* convert from 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(tmp, tmp); - rgba_float_to_uchar(to, tmp); - } - } - else { - for (x = 0; x < width; x++, from += 4, to += 4) { - rgba_uchar_to_float(tmp, from); - linearrgb_to_srgb_v4(tmp, tmp); - rgba_float_to_uchar(to, tmp); - } - } - } - } + float tmp[4]; + int x, y; + + /* we need valid profiles */ + BLI_assert(profile_to != IB_PROFILE_NONE); + BLI_assert(profile_from != IB_PROFILE_NONE); + + /* always RGBA input */ + for (y = 0; y < height; y++) { + const uchar *from = rect_from + ((size_t)stride_from) * y * 4; + uchar *to = rect_to + ((size_t)stride_to) * y * 4; + + if (profile_to == profile_from) { + /* same profile, copy */ + memcpy(to, from, sizeof(uchar) * 4 * width); + } + else if (profile_to == IB_PROFILE_LINEAR_RGB) { + /* convert to sRGB to linear */ + if (predivide) { + for (x = 0; x < width; x++, from += 4, to += 4) { + rgba_uchar_to_float(tmp, from); + srgb_to_linearrgb_predivide_v4(tmp, tmp); + rgba_float_to_uchar(to, tmp); + } + } + else { + for (x = 0; x < width; x++, from += 4, to += 4) { + rgba_uchar_to_float(tmp, from); + srgb_to_linearrgb_v4(tmp, tmp); + rgba_float_to_uchar(to, tmp); + } + } + } + else if (profile_to == IB_PROFILE_SRGB) { + /* convert from 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(tmp, tmp); + rgba_float_to_uchar(to, tmp); + } + } + else { + for (x = 0; x < width; x++, from += 4, to += 4) { + rgba_uchar_to_float(tmp, from); + linearrgb_to_srgb_v4(tmp, tmp); + rgba_float_to_uchar(to, tmp); + } + } + } + } } /****************************** ImBuf Conversion *****************************/ void IMB_rect_from_float(ImBuf *ibuf) { - float *buffer; - const char *from_colorspace; - - /* verify we have a float buffer */ - if (ibuf->rect_float == NULL) - return; - - /* create byte rect if it didn't exist yet */ - if (ibuf->rect == NULL) { - if (imb_addrectImBuf(ibuf) == 0) - return; - } - - if (ibuf->float_colorspace == NULL) - from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR); - else - from_colorspace = ibuf->float_colorspace->name; - - buffer = MEM_dupallocN(ibuf->rect_float); - - /* first make float buffer in byte space */ - IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, ibuf->rect_colorspace->name, true); - - /* convert from float's premul alpha to byte's straight alpha */ - IMB_unpremultiply_rect_float(buffer, ibuf->channels, ibuf->x, ibuf->y); - - /* convert float to byte */ - IMB_buffer_byte_from_float((unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, - false, ibuf->x, ibuf->y, ibuf->x, ibuf->x); - - MEM_freeN(buffer); - - /* ensure user flag is reset */ - ibuf->userflags &= ~IB_RECT_INVALID; + float *buffer; + const char *from_colorspace; + + /* verify we have a float buffer */ + if (ibuf->rect_float == NULL) + return; + + /* create byte rect if it didn't exist yet */ + if (ibuf->rect == NULL) { + if (imb_addrectImBuf(ibuf) == 0) + return; + } + + if (ibuf->float_colorspace == NULL) + from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR); + else + from_colorspace = ibuf->float_colorspace->name; + + buffer = MEM_dupallocN(ibuf->rect_float); + + /* first make float buffer in byte space */ + IMB_colormanagement_transform(buffer, + ibuf->x, + ibuf->y, + ibuf->channels, + from_colorspace, + ibuf->rect_colorspace->name, + true); + + /* convert from float's premul alpha to byte's straight alpha */ + IMB_unpremultiply_rect_float(buffer, ibuf->channels, ibuf->x, ibuf->y); + + /* convert float to byte */ + IMB_buffer_byte_from_float((unsigned char *)ibuf->rect, + buffer, + ibuf->channels, + ibuf->dither, + IB_PROFILE_SRGB, + IB_PROFILE_SRGB, + false, + ibuf->x, + ibuf->y, + ibuf->x, + ibuf->x); + + MEM_freeN(buffer); + + /* ensure user flag is reset */ + ibuf->userflags &= ~IB_RECT_INVALID; } typedef struct PartialThreadData { - ImBuf *ibuf; - float *buffer; - uchar *rect_byte; - const float *rect_float; - int width; - bool is_data; + ImBuf *ibuf; + float *buffer; + uchar *rect_byte; + const float *rect_float; + int width; + bool is_data; } PartialThreadData; static void partial_rect_from_float_slice(float *buffer, @@ -696,128 +748,145 @@ static void partial_rect_from_float_slice(float *buffer, const int h, const bool is_data) { - const int profile_from = IB_PROFILE_LINEAR_RGB; - if (is_data) { - /* exception for non-color data, just copy float */ - IMB_buffer_float_from_float(buffer, rect_float, - ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, 0, - w, h, w, ibuf->x); - - /* and do color space conversion to byte */ - IMB_buffer_byte_from_float(rect_byte, rect_float, - 4, ibuf->dither, IB_PROFILE_SRGB, profile_from, true, - w, h, ibuf->x, w); - } - else { - IMB_buffer_float_from_float(buffer, rect_float, - ibuf->channels, IB_PROFILE_SRGB, profile_from, true, - w, h, w, ibuf->x); - - IMB_buffer_float_unpremultiply(buffer, w, h); - /* XXX: need to convert to image buffer's rect space */ - IMB_buffer_byte_from_float(rect_byte, buffer, - 4, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, 0, - w, h, ibuf->x, w); - } + const int profile_from = IB_PROFILE_LINEAR_RGB; + if (is_data) { + /* exception for non-color data, just copy float */ + IMB_buffer_float_from_float(buffer, + rect_float, + ibuf->channels, + IB_PROFILE_LINEAR_RGB, + IB_PROFILE_LINEAR_RGB, + 0, + w, + h, + w, + ibuf->x); + + /* and do color space conversion to byte */ + IMB_buffer_byte_from_float(rect_byte, + rect_float, + 4, + ibuf->dither, + IB_PROFILE_SRGB, + profile_from, + true, + w, + h, + ibuf->x, + w); + } + else { + IMB_buffer_float_from_float( + buffer, rect_float, ibuf->channels, IB_PROFILE_SRGB, profile_from, true, w, h, w, ibuf->x); + + IMB_buffer_float_unpremultiply(buffer, w, h); + /* XXX: need to convert to image buffer's rect space */ + IMB_buffer_byte_from_float( + rect_byte, buffer, 4, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, 0, w, h, ibuf->x, w); + } } -static void partial_rect_from_float_thread_do(void *data_v, - int start_scanline, - int num_scanlines) +static void partial_rect_from_float_thread_do(void *data_v, int start_scanline, int num_scanlines) { - PartialThreadData *data = (PartialThreadData *)data_v; - ImBuf *ibuf = data->ibuf; - size_t global_offset = ((size_t)ibuf->x) * start_scanline; - size_t local_offset = ((size_t)data->width) * start_scanline; - partial_rect_from_float_slice(data->buffer + local_offset * ibuf->channels, - data->rect_byte + global_offset * 4, - ibuf, - data->rect_float + global_offset * ibuf->channels, - data->width, - num_scanlines, - data->is_data); + PartialThreadData *data = (PartialThreadData *)data_v; + ImBuf *ibuf = data->ibuf; + size_t global_offset = ((size_t)ibuf->x) * start_scanline; + size_t local_offset = ((size_t)data->width) * start_scanline; + partial_rect_from_float_slice(data->buffer + local_offset * ibuf->channels, + data->rect_byte + global_offset * 4, + ibuf, + data->rect_float + global_offset * ibuf->channels, + data->width, + num_scanlines, + data->is_data); } /* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */ -void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w, int h, bool is_data) +void IMB_partial_rect_from_float( + ImBuf *ibuf, float *buffer, int x, int y, int w, int h, bool is_data) { - const float *rect_float; - uchar *rect_byte; - - /* verify we have a float buffer */ - if (ibuf->rect_float == NULL || buffer == NULL) - return; - - /* create byte rect if it didn't exist yet */ - if (ibuf->rect == NULL) - imb_addrectImBuf(ibuf); - - /* do conversion */ - rect_float = ibuf->rect_float + (x + ((size_t)y) * ibuf->x) * ibuf->channels; - rect_byte = (uchar *)ibuf->rect + (x + ((size_t)y) * ibuf->x) * 4; - - if (((size_t)w) * h < 64 * 64) { - partial_rect_from_float_slice( - buffer, rect_byte, ibuf, rect_float, w, h, is_data); - } - else { - PartialThreadData data; - data.ibuf = ibuf; - data.buffer = buffer; - data.rect_byte = rect_byte; - data.rect_float = rect_float; - data.width = w; - data.is_data = is_data; - IMB_processor_apply_threaded_scanlines( - h, partial_rect_from_float_thread_do, &data); - } - - /* ensure user flag is reset */ - ibuf->userflags &= ~IB_RECT_INVALID; + const float *rect_float; + uchar *rect_byte; + + /* verify we have a float buffer */ + if (ibuf->rect_float == NULL || buffer == NULL) + return; + + /* create byte rect if it didn't exist yet */ + if (ibuf->rect == NULL) + imb_addrectImBuf(ibuf); + + /* do conversion */ + rect_float = ibuf->rect_float + (x + ((size_t)y) * ibuf->x) * ibuf->channels; + rect_byte = (uchar *)ibuf->rect + (x + ((size_t)y) * ibuf->x) * 4; + + if (((size_t)w) * h < 64 * 64) { + partial_rect_from_float_slice(buffer, rect_byte, ibuf, rect_float, w, h, is_data); + } + else { + PartialThreadData data; + data.ibuf = ibuf; + data.buffer = buffer; + data.rect_byte = rect_byte; + data.rect_float = rect_float; + data.width = w; + data.is_data = is_data; + IMB_processor_apply_threaded_scanlines(h, partial_rect_from_float_thread_do, &data); + } + + /* ensure user flag is reset */ + ibuf->userflags &= ~IB_RECT_INVALID; } void IMB_float_from_rect(ImBuf *ibuf) { - float *rect_float; - - /* verify if we byte and float buffers */ - if (ibuf->rect == NULL) - return; - - /* allocate float buffer outside of image buffer, - * so work-in-progress color space conversion doesn't - * interfere with other parts of blender - */ - rect_float = ibuf->rect_float; - if (rect_float == NULL) { - size_t size; - - size = ((size_t)ibuf->x) * ibuf->y; - size = size * 4 * sizeof(float); - ibuf->channels = 4; - - rect_float = MEM_mapallocN(size, "IMB_float_from_rect"); - - if (rect_float == NULL) - return; - } - - /* first, create float buffer in non-linear space */ - IMB_buffer_float_from_byte(rect_float, (unsigned char *) ibuf->rect, IB_PROFILE_SRGB, IB_PROFILE_SRGB, - false, ibuf->x, ibuf->y, ibuf->x, ibuf->x); - - /* then make float be in linear space */ - IMB_colormanagement_colorspace_to_scene_linear(rect_float, ibuf->x, ibuf->y, ibuf->channels, - ibuf->rect_colorspace, false); - - /* byte buffer is straight alpha, float should always be premul */ - IMB_premultiply_rect_float(rect_float, ibuf->channels, ibuf->x, ibuf->y); - - if (ibuf->rect_float == NULL) { - ibuf->rect_float = rect_float; - ibuf->mall |= IB_rectfloat; - ibuf->flags |= IB_rectfloat; - } + float *rect_float; + + /* verify if we byte and float buffers */ + if (ibuf->rect == NULL) + return; + + /* allocate float buffer outside of image buffer, + * so work-in-progress color space conversion doesn't + * interfere with other parts of blender + */ + rect_float = ibuf->rect_float; + if (rect_float == NULL) { + size_t size; + + size = ((size_t)ibuf->x) * ibuf->y; + size = size * 4 * sizeof(float); + ibuf->channels = 4; + + rect_float = MEM_mapallocN(size, "IMB_float_from_rect"); + + if (rect_float == NULL) + return; + } + + /* first, create float buffer in non-linear space */ + IMB_buffer_float_from_byte(rect_float, + (unsigned char *)ibuf->rect, + IB_PROFILE_SRGB, + IB_PROFILE_SRGB, + false, + ibuf->x, + ibuf->y, + ibuf->x, + ibuf->x); + + /* then make float be in linear space */ + IMB_colormanagement_colorspace_to_scene_linear( + rect_float, ibuf->x, ibuf->y, ibuf->channels, ibuf->rect_colorspace, false); + + /* byte buffer is straight alpha, float should always be premul */ + IMB_premultiply_rect_float(rect_float, ibuf->channels, ibuf->x, ibuf->y); + + if (ibuf->rect_float == NULL) { + ibuf->rect_float = rect_float; + ibuf->mall |= IB_rectfloat; + ibuf->flags |= IB_rectfloat; + } } /**************************** Color to Grayscale *****************************/ @@ -825,72 +894,72 @@ void IMB_float_from_rect(ImBuf *ibuf) /* no profile conversion */ void IMB_color_to_bw(ImBuf *ibuf) { - float *rct_fl = ibuf->rect_float; - uchar *rct = (uchar *)ibuf->rect; - size_t i; - - if (rct_fl) { - for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct_fl += 4) - rct_fl[0] = rct_fl[1] = rct_fl[2] = IMB_colormanagement_get_luminance(rct_fl); - } - - if (rct) { - for (i = ((size_t)ibuf->x * ibuf->y); i > 0; i--, rct += 4) - rct[0] = rct[1] = rct[2] = IMB_colormanagement_get_luminance_byte(rct); - } + float *rct_fl = ibuf->rect_float; + uchar *rct = (uchar *)ibuf->rect; + size_t i; + + if (rct_fl) { + for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct_fl += 4) + rct_fl[0] = rct_fl[1] = rct_fl[2] = IMB_colormanagement_get_luminance(rct_fl); + } + + if (rct) { + for (i = ((size_t)ibuf->x * ibuf->y); i > 0; i--, rct += 4) + rct[0] = rct[1] = rct[2] = IMB_colormanagement_get_luminance_byte(rct); + } } void IMB_buffer_float_clamp(float *buf, int width, int height) { - size_t i, total = ((size_t)width) * height * 4; - for (i = 0; i < total; i++) { - buf[i] = min_ff(1.0, buf[i]); - } + size_t i, total = ((size_t)width) * height * 4; + for (i = 0; i < total; i++) { + buf[i] = min_ff(1.0, buf[i]); + } } void IMB_buffer_float_unpremultiply(float *buf, int width, int height) { - size_t total = ((size_t)width) * height; - float *fp = buf; - while (total--) { - premul_to_straight_v4(fp); - fp += 4; - } + size_t total = ((size_t)width) * height; + float *fp = buf; + while (total--) { + premul_to_straight_v4(fp); + fp += 4; + } } void IMB_buffer_float_premultiply(float *buf, int width, int height) { - size_t total = ((size_t)width) * height; - float *fp = buf; - while (total--) { - straight_to_premul_v4(fp); - fp += 4; - } + size_t total = ((size_t)width) * height; + float *fp = buf; + while (total--) { + straight_to_premul_v4(fp); + fp += 4; + } } /**************************** alter saturation *****************************/ void IMB_saturation(ImBuf *ibuf, float sat) { - size_t i; - unsigned char *rct = (unsigned char *)ibuf->rect; - float *rct_fl = ibuf->rect_float; - float hsv[3]; - - if (rct) { - float rgb[3]; - for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct += 4) { - rgb_uchar_to_float(rgb, rct); - rgb_to_hsv_v(rgb, hsv); - hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb + 1, rgb + 2); - rgb_float_to_uchar(rct, rgb); - } - } - - if (rct_fl) { - for (i = ((size_t)ibuf->x) * ibuf->y; 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); - } - } + size_t i; + unsigned char *rct = (unsigned char *)ibuf->rect; + float *rct_fl = ibuf->rect_float; + float hsv[3]; + + if (rct) { + float rgb[3]; + for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct += 4) { + rgb_uchar_to_float(rgb, rct); + rgb_to_hsv_v(rgb, hsv); + hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb + 1, rgb + 2); + rgb_float_to_uchar(rct, rgb); + } + } + + if (rct_fl) { + for (i = ((size_t)ibuf->x) * ibuf->y; 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); + } + } } |