diff options
Diffstat (limited to 'source/blender/imbuf/intern/imageprocess.c')
-rw-r--r-- | source/blender/imbuf/intern/imageprocess.c | 186 |
1 files changed, 20 insertions, 166 deletions
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index 0ec1e4c19d8..23c4c53d602 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -40,7 +40,6 @@ #include "IMB_imbuf_types.h" #include <math.h> -/* Only this one is used liberally here, and in imbuf */ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf) { size_t size; @@ -76,7 +75,8 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf) } } -static void pixel_from_buffer(struct ImBuf *ibuf, unsigned char **outI, float **outF, int x, int y) +static void pixel_from_buffer( + const struct ImBuf *ibuf, unsigned char **outI, float **outF, int x, int y) { size_t offset = ((size_t)ibuf->x) * y * 4 + 4 * x; @@ -95,7 +95,7 @@ static void pixel_from_buffer(struct ImBuf *ibuf, unsigned char **outI, float ** * \{ */ void bicubic_interpolation_color( - struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) + const struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) { if (outF) { BLI_bicubic_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v); @@ -105,7 +105,7 @@ void bicubic_interpolation_color( } } -void bicubic_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout) +void bicubic_interpolation(const ImBuf *in, ImBuf *out, float u, float v, int xout, int yout) { unsigned char *outI = NULL; float *outF = NULL; @@ -126,16 +126,16 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, in /** \name Bi-Linear Interpolation * \{ */ -BLI_INLINE void bilinear_interpolation_color_fl( - struct ImBuf *in, unsigned char UNUSED(outI[4]), float outF[4], float u, float v) +void bilinear_interpolation_color_fl( + const struct ImBuf *in, unsigned char UNUSED(outI[4]), float outF[4], float u, float v) { BLI_assert(outF); BLI_assert(in->rect_float); BLI_bilinear_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v); } -BLI_INLINE void bilinear_interpolation_color_char( - struct ImBuf *in, unsigned char outI[4], float UNUSED(outF[4]), float u, float v) +void bilinear_interpolation_color_char( + const struct ImBuf *in, unsigned char outI[4], float UNUSED(outF[4]), float u, float v) { BLI_assert(outI); BLI_assert(in->rect); @@ -143,7 +143,7 @@ BLI_INLINE void bilinear_interpolation_color_char( } void bilinear_interpolation_color( - struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) + const struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) { if (outF) { BLI_bilinear_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v); @@ -156,12 +156,8 @@ void bilinear_interpolation_color( /* function assumes out to be zero'ed, only does RGBA */ /* BILINEAR INTERPOLATION */ -/* Note about wrapping, the u/v still needs to be within the image bounds, - * just the interpolation is wrapped. - * This the same as bilinear_interpolation_color except it wraps - * rather than using empty and emptyI. */ void bilinear_interpolation_color_wrap( - struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) + const struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) { float *row1, *row2, *row3, *row4, a, b; unsigned char *row1I, *row2I, *row3I, *row4I; @@ -232,7 +228,7 @@ void bilinear_interpolation_color_wrap( } } -void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout) +void bilinear_interpolation(const ImBuf *in, ImBuf *out, float u, float v, int xout, int yout) { unsigned char *outI = NULL; float *outF = NULL; @@ -253,9 +249,8 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i /** \name Nearest Interpolation * \{ */ -/* functions assumes out to be zero'ed, only does RGBA */ -BLI_INLINE void nearest_interpolation_color_char( - struct ImBuf *in, unsigned char outI[4], float UNUSED(outF[4]), float u, float v) +void nearest_interpolation_color_char( + const struct ImBuf *in, unsigned char outI[4], float UNUSED(outF[4]), float u, float v) { BLI_assert(outI); BLI_assert(in->rect); @@ -269,7 +264,7 @@ BLI_INLINE void nearest_interpolation_color_char( return; } - const size_t offset = (in->x * y1 + x1) * 4; + const size_t offset = ((size_t)in->x * y1 + x1) * 4; const unsigned char *dataI = (unsigned char *)in->rect + offset; outI[0] = dataI[0]; outI[1] = dataI[1]; @@ -277,8 +272,8 @@ BLI_INLINE void nearest_interpolation_color_char( outI[3] = dataI[3]; } -BLI_INLINE void nearest_interpolation_color_fl( - struct ImBuf *in, unsigned char UNUSED(outI[4]), float outF[4], float u, float v) +void nearest_interpolation_color_fl( + const struct ImBuf *in, unsigned char UNUSED(outI[4]), float outF[4], float u, float v) { BLI_assert(outF); BLI_assert(in->rect_float); @@ -292,13 +287,13 @@ BLI_INLINE void nearest_interpolation_color_fl( return; } - const size_t offset = (in->x * y1 + x1) * 4; + const size_t offset = ((size_t)in->x * y1 + x1) * 4; const float *dataF = in->rect_float + offset; copy_v4_v4(outF, dataF); } void nearest_interpolation_color( - struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) + const struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) { if (outF) { nearest_interpolation_color_fl(in, outI, outF, u, v); @@ -309,7 +304,7 @@ void nearest_interpolation_color( } void nearest_interpolation_color_wrap( - struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) + const struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) { const float *dataF; unsigned char *dataI; @@ -347,7 +342,7 @@ void nearest_interpolation_color_wrap( } } -void nearest_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout) +void nearest_interpolation(const ImBuf *in, ImBuf *out, float u, float v, int xout, int yout) { unsigned char *outI = NULL; float *outF = NULL; @@ -362,146 +357,6 @@ void nearest_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, in nearest_interpolation_color(in, outI, outF, u, v); } -/* -------------------------------------------------------------------- */ -/** \name Image transform - * \{ */ -typedef struct TransformUserData { - ImBuf *src; - ImBuf *dst; - float start_uv[2]; - float add_x[2]; - float add_y[2]; - rctf src_crop; -} TransformUserData; - -static void imb_transform_calc_start_uv(const float transform_matrix[4][4], float r_start_uv[2]) -{ - float r_start_uv_temp[3]; - float orig[3]; - zero_v3(orig); - mul_v3_m4v3(r_start_uv_temp, transform_matrix, orig); - copy_v2_v2(r_start_uv, r_start_uv_temp); -} - -static void imb_transform_calc_add_x(const float transform_matrix[4][4], - const float start_uv[2], - const int width, - float r_add_x[2]) -{ - float r_add_x_temp[3]; - float uv_max_x[3]; - zero_v3(uv_max_x); - uv_max_x[0] = width; - uv_max_x[1] = 0.0f; - mul_v3_m4v3(r_add_x_temp, transform_matrix, uv_max_x); - sub_v2_v2(r_add_x_temp, start_uv); - mul_v2_fl(r_add_x_temp, 1.0f / width); - copy_v2_v2(r_add_x, r_add_x_temp); -} - -static void imb_transform_calc_add_y(const float transform_matrix[4][4], - const float start_uv[2], - const int height, - float r_add_y[2]) -{ - float r_add_y_temp[3]; - float uv_max_y[3]; - zero_v3(uv_max_y); - uv_max_y[0] = 0.0f; - uv_max_y[1] = height; - mul_v3_m4v3(r_add_y_temp, transform_matrix, uv_max_y); - sub_v2_v2(r_add_y_temp, start_uv); - mul_v2_fl(r_add_y_temp, 1.0f / height); - copy_v2_v2(r_add_y, r_add_y_temp); -} - -typedef void (*InterpolationColorFunction)( - struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v); -BLI_INLINE void imb_transform_scanlines(const TransformUserData *user_data, - int scanline, - InterpolationColorFunction interpolation) -{ - const int width = user_data->dst->x; - - float uv[2]; - madd_v2_v2v2fl(uv, user_data->start_uv, user_data->add_y, scanline); - - unsigned char *outI = NULL; - float *outF = NULL; - pixel_from_buffer(user_data->dst, &outI, &outF, 0, scanline); - - for (int xi = 0; xi < width; xi++) { - if (uv[0] >= user_data->src_crop.xmin && uv[0] < user_data->src_crop.xmax && - uv[1] >= user_data->src_crop.ymin && uv[1] < user_data->src_crop.ymax) { - interpolation(user_data->src, outI, outF, uv[0], uv[1]); - } - add_v2_v2(uv, user_data->add_x); - if (outI) { - outI += 4; - } - if (outF) { - outF += 4; - } - } -} - -static void imb_transform_nearest_scanlines(void *custom_data, int scanline) -{ - const TransformUserData *user_data = custom_data; - InterpolationColorFunction interpolation = NULL; - if (user_data->dst->rect_float) { - interpolation = nearest_interpolation_color_fl; - } - else { - interpolation = nearest_interpolation_color_char; - } - imb_transform_scanlines(user_data, scanline, interpolation); -} - -static void imb_transform_bilinear_scanlines(void *custom_data, int scanline) -{ - const TransformUserData *user_data = custom_data; - InterpolationColorFunction interpolation = NULL; - if (user_data->dst->rect_float) { - interpolation = bilinear_interpolation_color_fl; - } - else if (user_data->dst->rect) { - interpolation = bilinear_interpolation_color_char; - } - imb_transform_scanlines(user_data, scanline, interpolation); -} - -static ScanlineThreadFunc imb_transform_scanline_func(const eIMBInterpolationFilterMode filter) -{ - ScanlineThreadFunc scanline_func = NULL; - switch (filter) { - case IMB_FILTER_NEAREST: - scanline_func = imb_transform_nearest_scanlines; - break; - case IMB_FILTER_BILINEAR: - scanline_func = imb_transform_bilinear_scanlines; - break; - } - return scanline_func; -} - -void IMB_transform(struct ImBuf *src, - struct ImBuf *dst, - float transform_matrix[4][4], - struct rctf *src_crop, - const eIMBInterpolationFilterMode filter) -{ - TransformUserData user_data; - user_data.src = src; - user_data.dst = dst; - user_data.src_crop = *src_crop; - imb_transform_calc_start_uv(transform_matrix, user_data.start_uv); - imb_transform_calc_add_x(transform_matrix, user_data.start_uv, src->x, user_data.add_x); - imb_transform_calc_add_y(transform_matrix, user_data.start_uv, src->y, user_data.add_y); - ScanlineThreadFunc scanline_func = imb_transform_scanline_func(filter); - IMB_processor_apply_threaded_scanlines(dst->y, scanline_func, &user_data); -} - /** \} */ /* -------------------------------------------------------------------- */ @@ -643,7 +498,6 @@ void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, const float b /** \name Sample Pixel * \{ */ -/* Sample pixel of image using NEAREST method. */ void IMB_sampleImageAtLocation(ImBuf *ibuf, float x, float y, bool make_linear_rgb, float color[4]) { if (ibuf->rect_float) { |