Blender  V2.93
image.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2011 Blender Foundation.
17  * All rights reserved.
18  */
19 
20 #include "intern/image.h"
21 #include "intern/utildefines.h"
23 
24 #include <png.h>
25 #include <cassert>
26 
27 using libmv::FloatImage;
29 
31  delete[] image->buffer;
32 }
33 
34 /* Image <-> buffers conversion */
35 
36 void libmv_byteBufferToFloatImage(const unsigned char* 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) = (float)buffer[a++] / 255.0f;
46  }
47  }
48  }
49 }
50 
52  int width,
53  int height,
54  int channels,
55  FloatImage* image) {
56  image->Resize(height, width, channels);
57  for (int y = 0, a = 0; y < height; y++) {
58  for (int x = 0; x < width; x++) {
59  for (int k = 0; k < channels; k++) {
60  (*image)(y, x, k) = buffer[a++];
61  }
62  }
63  }
64 }
65 
66 void libmv_floatImageToFloatBuffer(const FloatImage& image, float* buffer) {
67  for (int y = 0, a = 0; y < image.Height(); y++) {
68  for (int x = 0; x < image.Width(); x++) {
69  for (int k = 0; k < image.Depth(); k++) {
70  buffer[a++] = image(y, x, k);
71  }
72  }
73  }
74 }
75 
77  unsigned char* buffer) {
78  for (int y = 0, a = 0; y < image.Height(); y++) {
79  for (int x = 0; x < image.Width(); x++) {
80  for (int k = 0; k < image.Depth(); k++) {
81  buffer[a++] = image(y, x, k) * 255.0f;
82  }
83  }
84  }
85 }
86 
87 static bool savePNGImage(png_bytep* row_pointers,
88  int width,
89  int height,
90  int depth,
91  int color_type,
92  const char* file_name) {
93  png_infop info_ptr;
94  png_structp png_ptr;
95  FILE* fp = fopen(file_name, "wb");
96 
97  if (fp == NULL) {
98  return false;
99  }
100 
101  /* Initialize stuff */
102  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
103  info_ptr = png_create_info_struct(png_ptr);
104 
105  if (setjmp(png_jmpbuf(png_ptr))) {
106  fclose(fp);
107  return false;
108  }
109 
110  png_init_io(png_ptr, fp);
111 
112  /* Write PNG header. */
113  if (setjmp(png_jmpbuf(png_ptr))) {
114  fclose(fp);
115  return false;
116  }
117 
118  png_set_IHDR(png_ptr,
119  info_ptr,
120  width,
121  height,
122  depth,
123  color_type,
124  PNG_INTERLACE_NONE,
125  PNG_COMPRESSION_TYPE_BASE,
126  PNG_FILTER_TYPE_BASE);
127 
128  png_write_info(png_ptr, info_ptr);
129 
130  /* Write bytes/ */
131  if (setjmp(png_jmpbuf(png_ptr))) {
132  fclose(fp);
133  return false;
134  }
135 
136  png_write_image(png_ptr, row_pointers);
137 
138  /* End write/ */
139  if (setjmp(png_jmpbuf(png_ptr))) {
140  fclose(fp);
141  return false;
142  }
143 
144  png_write_end(png_ptr, NULL);
145  fclose(fp);
146 
147  return true;
148 }
149 
150 bool libmv_saveImage(const FloatImage& image,
151  const char* prefix,
152  int x0,
153  int y0) {
154  int x, y;
155  png_bytep* row_pointers;
156 
157  assert(image.Depth() == 1);
158 
159  row_pointers = new png_bytep[image.Height()];
160 
161  for (y = 0; y < image.Height(); y++) {
162  row_pointers[y] = new png_byte[4 * image.Width()];
163 
164  for (x = 0; x < image.Width(); x++) {
165  if (x0 == x && image.Height() - y0 - 1 == y) {
166  row_pointers[y][x * 4 + 0] = 255;
167  row_pointers[y][x * 4 + 1] = 0;
168  row_pointers[y][x * 4 + 2] = 0;
169  row_pointers[y][x * 4 + 3] = 255;
170  } else {
171  float pixel = image(image.Height() - y - 1, x, 0);
172  row_pointers[y][x * 4 + 0] = pixel * 255;
173  row_pointers[y][x * 4 + 1] = pixel * 255;
174  row_pointers[y][x * 4 + 2] = pixel * 255;
175  row_pointers[y][x * 4 + 3] = 255;
176  }
177  }
178  }
179 
180  static int image_counter = 0;
181  char file_name[128];
182  snprintf(
183  file_name, sizeof(file_name), "%s_%02d.png", prefix, ++image_counter);
184  bool result = savePNGImage(row_pointers,
185  image.Width(),
186  image.Height(),
187  8,
188  PNG_COLOR_TYPE_RGBA,
189  file_name);
190 
191  for (y = 0; y < image.Height(); y++) {
192  delete[] row_pointers[y];
193  }
194  delete[] row_pointers;
195 
196  return result;
197 }
198 
199 void libmv_samplePlanarPatchFloat(const float* image,
200  int width,
201  int height,
202  int channels,
203  const double* xs,
204  const double* ys,
205  int num_samples_x,
206  int num_samples_y,
207  const float* mask,
208  float* patch,
209  double* warped_position_x,
210  double* warped_position_y) {
211  FloatImage libmv_image, libmv_patch, libmv_mask;
212  FloatImage* libmv_mask_for_sample = NULL;
213 
214  libmv_floatBufferToFloatImage(image, width, height, channels, &libmv_image);
215 
216  if (mask) {
217  libmv_floatBufferToFloatImage(mask, width, height, 1, &libmv_mask);
218  libmv_mask_for_sample = &libmv_mask;
219  }
220 
221  SamplePlanarPatch(libmv_image,
222  xs,
223  ys,
224  num_samples_x,
225  num_samples_y,
226  libmv_mask_for_sample,
227  &libmv_patch,
228  warped_position_x,
229  warped_position_y);
230 
231  libmv_floatImageToFloatBuffer(libmv_patch, patch);
232 }
233 
234 void libmv_samplePlanarPatchByte(const unsigned char* image,
235  int width,
236  int height,
237  int channels,
238  const double* xs,
239  const double* ys,
240  int num_samples_x,
241  int num_samples_y,
242  const float* mask,
243  unsigned char* patch,
244  double* warped_position_x,
245  double* warped_position_y) {
246  libmv::FloatImage libmv_image, libmv_patch, libmv_mask;
247  libmv::FloatImage* libmv_mask_for_sample = NULL;
248 
249  libmv_byteBufferToFloatImage(image, width, height, channels, &libmv_image);
250 
251  if (mask) {
252  libmv_floatBufferToFloatImage(mask, width, height, 1, &libmv_mask);
253  libmv_mask_for_sample = &libmv_mask;
254  }
255 
256  libmv::SamplePlanarPatch(libmv_image,
257  xs,
258  ys,
259  num_samples_x,
260  num_samples_y,
261  libmv_mask_for_sample,
262  &libmv_patch,
263  warped_position_x,
264  warped_position_y);
265 
266  libmv_floatImageToByteBuffer(libmv_patch, patch);
267 }
#define snprintf
Definition: BLI_winstuff.h:69
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
3D array (row, column, channel).
Definition: array_nd.h:325
int Depth() const
Definition: array_nd.h:340
int Height() const
Definition: array_nd.h:338
int Width() const
Definition: array_nd.h:339
bool libmv_saveImage(const FloatImage &image, const char *prefix, int x0, int y0)
Definition: image.cc:150
static bool savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int color_type, const char *file_name)
Definition: image.cc:87
void libmv_floatBufferToFloatImage(const float *buffer, int width, int height, int channels, FloatImage *image)
Definition: image.cc:51
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)
Definition: image.cc:199
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)
Definition: image.cc:234
void libmv_floatImageToFloatBuffer(const FloatImage &image, float *buffer)
Definition: image.cc:66
void libmv_floatImageDestroy(libmv_FloatImage *image)
Definition: image.cc:30
void libmv_floatImageToByteBuffer(const libmv::FloatImage &image, unsigned char *buffer)
Definition: image.cc:76
void libmv_byteBufferToFloatImage(const unsigned char *buffer, int width, int height, int channels, FloatImage *image)
Definition: image.cc:36
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
static unsigned a[3]
Definition: RandGen.cpp:92
Array3Df FloatImage
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)
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)