Blender V4.3
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#ifndef __UTIL_IMAGE_IMPL_H__
6#define __UTIL_IMAGE_IMPL_H__
7
8#include "util/algorithm.h"
9#include "util/half.h"
10#include "util/image.h"
11
13
14namespace {
15
16template<typename T>
17const T *util_image_read(const vector<T> &pixels,
18 const size_t width,
19 const size_t height,
20 const size_t /*depth*/,
21 const size_t components,
22 const size_t x,
23 const size_t y,
24 const size_t z)
25{
26 const size_t index = ((size_t)z * (width * height) + (size_t)y * width + (size_t)x) * components;
27 return &pixels[index];
28}
29
30template<typename T>
32 const size_t width,
33 const size_t height,
34 const size_t depth,
35 const size_t components,
36 const size_t kernel_size,
37 const float x,
38 const float y,
39 const float z,
40 T *result)
41{
42 assert(components <= 4);
43 const size_t ix = (size_t)x, iy = (size_t)y, iz = (size_t)z;
44 /* TODO(sergey): Support something smarter than box filer. */
45 float accum[4] = {0};
46 size_t count = 0;
47 for (size_t dz = 0; dz < kernel_size; ++dz) {
48 for (size_t dy = 0; dy < kernel_size; ++dy) {
49 for (size_t dx = 0; dx < kernel_size; ++dx) {
50 const size_t nx = ix + dx, ny = iy + dy, nz = iz + dz;
51 if (nx >= width || ny >= height || nz >= depth) {
52 continue;
53 }
54 const T *pixel = util_image_read(pixels, width, height, depth, components, nx, ny, nz);
55 for (size_t k = 0; k < components; ++k) {
56 accum[k] += util_image_cast_to_float(pixel[k]);
57 }
58 ++count;
59 }
60 }
61 }
62 if (count != 0) {
63 const float inv_count = 1.0f / (float)count;
64 for (size_t k = 0; k < components; ++k) {
65 result[k] = util_image_cast_from_float<T>(accum[k] * inv_count);
66 }
67 }
68 else {
69 for (size_t k = 0; k < components; ++k) {
70 result[k] = T(0.0f);
71 }
72 }
73}
74
75template<typename T>
76void util_image_downscale_pixels(const vector<T> &input_pixels,
77 const size_t input_width,
78 const size_t input_height,
79 const size_t input_depth,
80 const size_t components,
81 const float inv_scale_factor,
82 const size_t output_width,
83 const size_t output_height,
84 const size_t output_depth,
85 vector<T> *output_pixels)
86{
87 const size_t kernel_size = (size_t)(inv_scale_factor + 0.5f);
88 for (size_t z = 0; z < output_depth; ++z) {
89 for (size_t y = 0; y < output_height; ++y) {
90 for (size_t x = 0; x < output_width; ++x) {
91 const float input_x = (float)x * inv_scale_factor, input_y = (float)y * inv_scale_factor,
92 input_z = (float)z * inv_scale_factor;
93 const size_t output_index = (z * output_width * output_height + y * output_width + x) *
94 components;
95 util_image_downscale_sample(input_pixels,
96 input_width,
97 input_height,
98 input_depth,
99 components,
100 kernel_size,
101 input_x,
102 input_y,
103 input_z,
104 &output_pixels->at(output_index));
105 }
106 }
107 }
108}
109
110} /* namespace */
111
112template<typename T>
113void util_image_resize_pixels(const vector<T> &input_pixels,
114 const size_t input_width,
115 const size_t input_height,
116 const size_t input_depth,
117 const size_t components,
118 const float scale_factor,
119 vector<T> *output_pixels,
120 size_t *output_width,
121 size_t *output_height,
122 size_t *output_depth)
123{
124 /* Early output for case when no scaling is applied. */
125 if (scale_factor == 1.0f) {
126 *output_width = input_width;
127 *output_height = input_height;
128 *output_depth = input_depth;
129 *output_pixels = input_pixels;
130 return;
131 }
132 /* First of all, we calculate output image dimensions.
133 * We clamp them to be 1 pixel at least so we do not generate degenerate
134 * image.
135 */
136 *output_width = max((size_t)((float)input_width * scale_factor), (size_t)1);
137 *output_height = max((size_t)((float)input_height * scale_factor), (size_t)1);
138 *output_depth = max((size_t)((float)input_depth * scale_factor), (size_t)1);
139 /* Prepare pixel storage for the result. */
140 const size_t num_output_pixels = ((*output_width) * (*output_height) * (*output_depth)) *
141 components;
142 output_pixels->resize(num_output_pixels);
143 if (scale_factor < 1.0f) {
144 const float inv_scale_factor = 1.0f / scale_factor;
145 util_image_downscale_pixels(input_pixels,
146 input_width,
147 input_height,
148 input_depth,
149 components,
150 inv_scale_factor,
151 *output_width,
152 *output_height,
153 *output_depth,
154 output_pixels);
155 }
156 else {
157 /* TODO(sergey): Needs implementation. */
158 }
159}
160
162
163#endif /* __UTIL_IMAGE_IMPL_H__ */
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
float util_image_cast_to_float(T value)
T util_image_cast_from_float(float value)
#define CCL_NAMESPACE_END
draw_view in_light_buf[] float
void util_image_resize_pixels(const vector< T > &input_pixels, const size_t input_width, const size_t input_height, const size_t input_depth, const size_t components, const float scale_factor, vector< T > *output_pixels, size_t *output_width, size_t *output_height, size_t *output_depth)
Definition image_impl.h:113
int count
#define T
void util_image_downscale_sample(const vector< T > &pixels, const size_t width, const size_t height, const size_t depth, const size_t components, const size_t kernel_size, const float x, const float y, const float z, T *result)
Definition image_impl.h:31
void util_image_downscale_pixels(const vector< T > &input_pixels, const size_t input_width, const size_t input_height, const size_t input_depth, const size_t components, const float inv_scale_factor, const size_t output_width, const size_t output_height, const size_t output_depth, vector< T > *output_pixels)
Definition image_impl.h:76
const T * util_image_read(const vector< T > &pixels, const size_t width, const size_t height, const size_t, const size_t components, const size_t x, const size_t y, const size_t z)
Definition image_impl.h:17
float max