Changeset View
Changeset View
Standalone View
Standalone View
source/blender/imbuf/intern/imageprocess.c
| Show First 20 Lines • Show All 344 Lines • ▼ Show 20 Lines | void nearest_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout) | ||||
| /* gcc warns these could be uninitialized, but its ok. */ | /* gcc warns these could be uninitialized, but its ok. */ | ||||
| pixel_from_buffer(out, &outI, &outF, xout, yout); | pixel_from_buffer(out, &outI, &outF, xout, yout); | ||||
| nearest_interpolation_color(in, outI, outF, u, v); | 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[3][3], float r_start_uv[2]) | |||||
| { | |||||
| float orig[2]; | |||||
| orig[0] = 0.0f; | |||||
| orig[1] = 0.0f; | |||||
| mul_v2_m3v2(r_start_uv, transform_matrix, orig); | |||||
| } | |||||
| static void imb_transform_calc_add_x(const float transform_matrix[3][3], | |||||
| const float start_uv[2], | |||||
| const int width, | |||||
| float r_add_x[2]) | |||||
| { | |||||
| float uv_max_x[2]; | |||||
| uv_max_x[0] = width; | |||||
| uv_max_x[1] = 0.0f; | |||||
| mul_v2_m3v2(r_add_x, transform_matrix, uv_max_x); | |||||
| sub_v2_v2(r_add_x, start_uv); | |||||
| mul_v2_fl(r_add_x, 1.0f / width); | |||||
| } | |||||
| static void imb_transform_calc_add_y(const float transform_matrix[3][3], | |||||
| const float start_uv[2], | |||||
| const int height, | |||||
| float r_add_y[2]) | |||||
| { | |||||
| float uv_max_y[2]; | |||||
| uv_max_y[0] = 0.0f; | |||||
| uv_max_y[1] = height; | |||||
| mul_v2_m3v2(r_add_y, transform_matrix, uv_max_y); | |||||
| sub_v2_v2(r_add_y, start_uv); | |||||
| mul_v2_fl(r_add_y, 1.0f / height); | |||||
| } | |||||
| 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 start_scanline, | |||||
| int num_scanlines, | |||||
| InterpolationColorFunction interpolation) | |||||
| { | |||||
| const int width = user_data->dst->x; | |||||
| float next_line_start_uv[2]; | |||||
| madd_v2_v2v2fl(next_line_start_uv, user_data->start_uv, user_data->add_y, start_scanline); | |||||
| unsigned char *outI = NULL; | |||||
| float *outF = NULL; | |||||
| pixel_from_buffer(user_data->dst, &outI, &outF, 0, start_scanline); | |||||
| for (int yi = start_scanline; yi < start_scanline + num_scanlines; yi++) { | |||||
| float uv[2]; | |||||
| copy_v2_v2(uv, next_line_start_uv); | |||||
| add_v2_v2(next_line_start_uv, user_data->add_y); | |||||
| 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 start_scanline, | |||||
| int num_scanlines) | |||||
| { | |||||
| const TransformUserData *user_data = custom_data; | |||||
| imb_transform_scanlines(user_data, start_scanline, num_scanlines, nearest_interpolation_color); | |||||
| } | |||||
| static void imb_transform_bilinear_scanlines(void *custom_data, | |||||
| int start_scanline, | |||||
| int num_scanlines) | |||||
| { | |||||
| const TransformUserData *user_data = custom_data; | |||||
| imb_transform_scanlines(user_data, start_scanline, num_scanlines, bilinear_interpolation_color); | |||||
| } | |||||
| 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[3][3], | |||||
| 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); | |||||
| } | |||||
| /** \} */ | |||||
| /* -------------------------------------------------------------------- */ | |||||
| /** \name Threaded Image Processing | /** \name Threaded Image Processing | ||||
| * \{ */ | * \{ */ | ||||
| static void processor_apply_func(TaskPool *__restrict pool, void *taskdata) | static void processor_apply_func(TaskPool *__restrict pool, void *taskdata) | ||||
| { | { | ||||
| void (*do_thread)(void *) = (void (*)(void *))BLI_task_pool_user_data(pool); | void (*do_thread)(void *) = (void (*)(void *))BLI_task_pool_user_data(pool); | ||||
| do_thread(taskdata); | do_thread(taskdata); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 160 Lines • Show Last 20 Lines | |||||