Blender V4.3
intern/libmv/intern/image.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "intern/image.h"
8
9#include <png.h>
10#include <cassert>
11
14
16 delete[] image->buffer;
17}
18
19/* Image <-> buffers conversion */
20
21void libmv_byteBufferToFloatImage(const unsigned char* buffer,
22 int width,
23 int height,
24 int channels,
25 FloatImage* image) {
26 image->Resize(height, width, channels);
27 for (int y = 0, a = 0; y < height; y++) {
28 for (int x = 0; x < width; x++) {
29 for (int k = 0; k < channels; k++) {
30 (*image)(y, x, k) = (float)buffer[a++] / 255.0f;
31 }
32 }
33 }
34}
35
36void libmv_floatBufferToFloatImage(const float* buffer,
37 int width,
38 int height,
39 int channels,
40 FloatImage* image) {
41 image->Resize(height, width, channels);
42 for (int y = 0, a = 0; y < height; y++) {
43 for (int x = 0; x < width; x++) {
44 for (int k = 0; k < channels; k++) {
45 (*image)(y, x, k) = buffer[a++];
46 }
47 }
48 }
49}
50
51void libmv_floatImageToFloatBuffer(const FloatImage& image, float* buffer) {
52 for (int y = 0, a = 0; y < image.Height(); y++) {
53 for (int x = 0; x < image.Width(); x++) {
54 for (int k = 0; k < image.Depth(); k++) {
55 buffer[a++] = image(y, x, k);
56 }
57 }
58 }
59}
60
62 unsigned char* buffer) {
63 for (int y = 0, a = 0; y < image.Height(); y++) {
64 for (int x = 0; x < image.Width(); x++) {
65 for (int k = 0; k < image.Depth(); k++) {
66 buffer[a++] = image(y, x, k) * 255.0f;
67 }
68 }
69 }
70}
71
72static bool savePNGImage(png_bytep* row_pointers,
73 int width,
74 int height,
75 int depth,
76 int color_type,
77 const char* file_name) {
78 png_infop info_ptr;
79 png_structp png_ptr;
80 FILE* fp = fopen(file_name, "wb");
81
82 if (fp == NULL) {
83 return false;
84 }
85
86 /* Initialize stuff */
87 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
88 info_ptr = png_create_info_struct(png_ptr);
89
90 if (setjmp(png_jmpbuf(png_ptr))) {
91 fclose(fp);
92 return false;
93 }
94
95 png_init_io(png_ptr, fp);
96
97 /* Write PNG header. */
98 if (setjmp(png_jmpbuf(png_ptr))) {
99 fclose(fp);
100 return false;
101 }
102
103 png_set_IHDR(png_ptr,
104 info_ptr,
105 width,
106 height,
107 depth,
108 color_type,
109 PNG_INTERLACE_NONE,
110 PNG_COMPRESSION_TYPE_BASE,
111 PNG_FILTER_TYPE_BASE);
112
113 png_write_info(png_ptr, info_ptr);
114
115 /* Write bytes/ */
116 if (setjmp(png_jmpbuf(png_ptr))) {
117 fclose(fp);
118 return false;
119 }
120
121 png_write_image(png_ptr, row_pointers);
122
123 /* End write/ */
124 if (setjmp(png_jmpbuf(png_ptr))) {
125 fclose(fp);
126 return false;
127 }
128
129 png_write_end(png_ptr, NULL);
130 fclose(fp);
131
132 return true;
133}
134
135bool libmv_saveImage(const FloatImage& image,
136 const char* prefix,
137 int x0,
138 int y0) {
139 int x, y;
140 png_bytep* row_pointers;
141
142 assert(image.Depth() == 1);
143
144 row_pointers = new png_bytep[image.Height()];
145
146 for (y = 0; y < image.Height(); y++) {
147 row_pointers[y] = new png_byte[4 * image.Width()];
148
149 for (x = 0; x < image.Width(); x++) {
150 if (x0 == x && image.Height() - y0 - 1 == y) {
151 row_pointers[y][x * 4 + 0] = 255;
152 row_pointers[y][x * 4 + 1] = 0;
153 row_pointers[y][x * 4 + 2] = 0;
154 row_pointers[y][x * 4 + 3] = 255;
155 } else {
156 float pixel = image(image.Height() - y - 1, x, 0);
157 row_pointers[y][x * 4 + 0] = pixel * 255;
158 row_pointers[y][x * 4 + 1] = pixel * 255;
159 row_pointers[y][x * 4 + 2] = pixel * 255;
160 row_pointers[y][x * 4 + 3] = 255;
161 }
162 }
163 }
164
165 static int image_counter = 0;
166 char file_name[128];
167 snprintf(
168 file_name, sizeof(file_name), "%s_%02d.png", prefix, ++image_counter);
169 bool result = savePNGImage(row_pointers,
170 image.Width(),
171 image.Height(),
172 8,
173 PNG_COLOR_TYPE_RGBA,
174 file_name);
175
176 for (y = 0; y < image.Height(); y++) {
177 delete[] row_pointers[y];
178 }
179 delete[] row_pointers;
180
181 return result;
182}
183
184void libmv_samplePlanarPatchFloat(const float* image,
185 int width,
186 int height,
187 int channels,
188 const double* xs,
189 const double* ys,
190 int num_samples_x,
191 int num_samples_y,
192 const float* mask,
193 float* patch,
194 double* warped_position_x,
195 double* warped_position_y) {
196 FloatImage libmv_image, libmv_patch, libmv_mask;
197 FloatImage* libmv_mask_for_sample = NULL;
198
199 libmv_floatBufferToFloatImage(image, width, height, channels, &libmv_image);
200
201 if (mask) {
202 libmv_floatBufferToFloatImage(mask, width, height, 1, &libmv_mask);
203 libmv_mask_for_sample = &libmv_mask;
204 }
205
206 SamplePlanarPatch(libmv_image,
207 xs,
208 ys,
209 num_samples_x,
210 num_samples_y,
211 libmv_mask_for_sample,
212 &libmv_patch,
213 warped_position_x,
214 warped_position_y);
215
216 libmv_floatImageToFloatBuffer(libmv_patch, patch);
217}
218
219void libmv_samplePlanarPatchByte(const unsigned char* image,
220 int width,
221 int height,
222 int channels,
223 const double* xs,
224 const double* ys,
225 int num_samples_x,
226 int num_samples_y,
227 const float* mask,
228 unsigned char* patch,
229 double* warped_position_x,
230 double* warped_position_y) {
231 libmv::FloatImage libmv_image, libmv_patch, libmv_mask;
232 libmv::FloatImage* libmv_mask_for_sample = NULL;
233
234 libmv_byteBufferToFloatImage(image, width, height, channels, &libmv_image);
235
236 if (mask) {
237 libmv_floatBufferToFloatImage(mask, width, height, 1, &libmv_mask);
238 libmv_mask_for_sample = &libmv_mask;
239 }
240
241 libmv::SamplePlanarPatch(libmv_image,
242 xs,
243 ys,
244 num_samples_x,
245 num_samples_y,
246 libmv_mask_for_sample,
247 &libmv_patch,
248 warped_position_x,
249 warped_position_y);
250
251 libmv_floatImageToByteBuffer(libmv_patch, patch);
252}
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
3D array (row, column, channel).
Definition array_nd.h:332
void Resize(int height, int width, int depth=1)
Definition array_nd.h:341
input_tx image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "preview_img") .compute_source("compositor_compute_preview.glsl") .do_static_compilation(true)
#define NULL
bool libmv_saveImage(const FloatImage &image, const char *prefix, int x0, int y0)
static bool savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int color_type, const char *file_name)
void libmv_floatBufferToFloatImage(const float *buffer, int width, int height, int channels, FloatImage *image)
void libmv_samplePlanarPatchFloat(const float *image, int width, int height, int channels, const double *xs, const double *ys, int num_samples_x, int num_samples_y, const float *mask, float *patch, double *warped_position_x, double *warped_position_y)
void libmv_samplePlanarPatchByte(const unsigned char *image, int width, int height, int channels, const double *xs, const double *ys, int num_samples_x, int num_samples_y, const float *mask, unsigned char *patch, double *warped_position_x, double *warped_position_y)
void libmv_floatImageToFloatBuffer(const FloatImage &image, float *buffer)
void libmv_floatImageDestroy(libmv_FloatImage *image)
void libmv_floatImageToByteBuffer(const libmv::FloatImage &image, unsigned char *buffer)
void libmv_byteBufferToFloatImage(const unsigned char *buffer, int width, int height, int channels, FloatImage *image)
bool SamplePlanarPatch(const FloatImage &image, const double *xs, const double *ys, int num_samples_x, int num_samples_y, FloatImage *mask, FloatImage *patch, double *warped_position_x, double *warped_position_y)