Blender V5.0
image_impl.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7#include "util/image.h"
8#include "util/math_base.h"
9
11
12namespace {
13
14template<typename T>
15const T *util_image_read(const vector<T> &pixels,
16 const size_t width,
17 const size_t /*height*/,
18 const size_t components,
19 const size_t x,
20 const size_t y)
21{
22 const size_t index = ((size_t)y * width + (size_t)x) * components;
23 return &pixels[index];
24}
25
26template<typename T>
28 const size_t width,
29 const size_t height,
30 const size_t components,
31 const size_t kernel_size,
32 const float x,
33 const float y,
34 T *result)
35{
36 assert(components <= 4);
37 const size_t ix = (size_t)x;
38 const size_t iy = (size_t)y;
39 /* TODO(sergey): Support something smarter than box filer. */
40 float accum[4] = {0};
41 size_t count = 0;
42 for (size_t dy = 0; dy < kernel_size; ++dy) {
43 for (size_t dx = 0; dx < kernel_size; ++dx) {
44 const size_t nx = ix + dx;
45 const size_t ny = iy + dy;
46 if (nx >= width || ny >= height) {
47 continue;
48 }
49 const T *pixel = util_image_read(pixels, width, height, components, nx, ny);
50 for (size_t k = 0; k < components; ++k) {
51 accum[k] += util_image_cast_to_float(pixel[k]);
52 }
53 ++count;
54 }
55 }
56 if (count != 0) {
57 const float inv_count = 1.0f / (float)count;
58 for (size_t k = 0; k < components; ++k) {
59 result[k] = util_image_cast_from_float<T>(accum[k] * inv_count);
60 }
61 }
62 else {
63 for (size_t k = 0; k < components; ++k) {
64 result[k] = T(0.0f);
65 }
66 }
67}
68
69template<typename T>
70void util_image_downscale_pixels(const vector<T> &input_pixels,
71 const size_t input_width,
72 const size_t input_height,
73 const size_t components,
74 const float inv_scale_factor,
75 const size_t output_width,
76 const size_t output_height,
77 vector<T> *output_pixels)
78{
79 const size_t kernel_size = (size_t)(inv_scale_factor + 0.5f);
80 for (size_t y = 0; y < output_height; ++y) {
81 for (size_t x = 0; x < output_width; ++x) {
82 const float input_x = (float)x * inv_scale_factor;
83 const float input_y = (float)y * inv_scale_factor;
84 const size_t output_index = (y * output_width + x) * components;
85 util_image_downscale_sample(input_pixels,
86 input_width,
87 input_height,
88 components,
89 kernel_size,
90 input_x,
91 input_y,
92 &output_pixels->at(output_index));
93 }
94 }
95}
96
97} /* namespace */
98
99template<typename T>
100void util_image_resize_pixels(const vector<T> &input_pixels,
101 const size_t input_width,
102 const size_t input_height,
103 const size_t components,
104 const float scale_factor,
105 vector<T> *output_pixels,
106 size_t *output_width,
107 size_t *output_height)
108{
109 /* Early output for case when no scaling is applied. */
110 if (scale_factor == 1.0f) {
111 *output_width = input_width;
112 *output_height = input_height;
113 *output_pixels = input_pixels;
114 return;
115 }
116 /* First of all, we calculate output image dimensions.
117 * We clamp them to be 1 pixel at least so we do not generate degenerate
118 * image.
119 */
120 *output_width = max((size_t)((float)input_width * scale_factor), (size_t)1);
121 *output_height = max((size_t)((float)input_height * scale_factor), (size_t)1);
122 /* Prepare pixel storage for the result. */
123 const size_t num_output_pixels = ((*output_width) * (*output_height)) * components;
124 output_pixels->resize(num_output_pixels);
125 if (scale_factor < 1.0f) {
126 const float inv_scale_factor = 1.0f / scale_factor;
127 util_image_downscale_pixels(input_pixels,
128 input_width,
129 input_height,
130 components,
131 inv_scale_factor,
132 *output_width,
133 *output_height,
134 output_pixels);
135 }
136 else {
137 /* TODO(sergey): Needs implementation. */
138 }
139}
140
nullptr float
T util_image_cast_from_float(const float value)
float util_image_cast_to_float(T value)
#define CCL_NAMESPACE_END
#define assert(assertion)
void util_image_resize_pixels(const vector< T > &input_pixels, const size_t input_width, const size_t input_height, const size_t components, const float scale_factor, vector< T > *output_pixels, size_t *output_width, size_t *output_height)
Definition image_impl.h:100
int count
#define T
void util_image_downscale_sample(const vector< T > &pixels, const size_t width, const size_t height, const size_t components, const size_t kernel_size, const float x, const float y, T *result)
Definition image_impl.h:27
void util_image_downscale_pixels(const vector< T > &input_pixels, const size_t input_width, const size_t input_height, const size_t components, const float inv_scale_factor, const size_t output_width, const size_t output_height, vector< T > *output_pixels)
Definition image_impl.h:70
const T * util_image_read(const vector< T > &pixels, const size_t width, const size_t, const size_t components, const size_t x, const size_t y)
Definition image_impl.h:15
max
Definition text_draw.cc:251