Blender  V2.93
blender_image.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "MEM_guardedalloc.h"
18 
19 #include "blender/blender_image.h"
21 #include "blender/blender_util.h"
22 
24 
25 /* Packed Images */
26 
28  : b_image(b_image), frame(frame), free_cache(!b_image.has_data())
29 {
30 }
31 
33 {
34  metadata.width = b_image.size()[0];
35  metadata.height = b_image.size()[1];
36  metadata.depth = 1;
37  metadata.channels = b_image.channels();
38 
39  if (b_image.is_float()) {
40  if (metadata.channels == 1) {
41  metadata.type = IMAGE_DATA_TYPE_FLOAT;
42  }
43  else if (metadata.channels == 4) {
44  metadata.type = IMAGE_DATA_TYPE_FLOAT4;
45  }
46  else {
47  return false;
48  }
49 
50  /* Float images are already converted on the Blender side,
51  * no need to do anything in Cycles. */
52  metadata.colorspace = u_colorspace_raw;
53  }
54  else {
55  if (metadata.channels == 1) {
56  metadata.type = IMAGE_DATA_TYPE_BYTE;
57  }
58  else if (metadata.channels == 4) {
59  metadata.type = IMAGE_DATA_TYPE_BYTE4;
60  }
61  else {
62  return false;
63  }
64  }
65 
66  return true;
67 }
68 
70  void *pixels,
71  const size_t pixels_size,
72  const bool associate_alpha)
73 {
74  const size_t num_pixels = ((size_t)metadata.width) * metadata.height;
75  const int channels = metadata.channels;
76  const int tile = 0; /* TODO(lukas): Support tiles here? */
77 
78  if (b_image.is_float()) {
79  /* image data */
80  float *image_pixels;
81  image_pixels = image_get_float_pixels_for_frame(b_image, frame, tile);
82 
83  if (image_pixels && num_pixels * channels == pixels_size) {
84  memcpy(pixels, image_pixels, pixels_size * sizeof(float));
85  }
86  else {
87  if (channels == 1) {
88  memset(pixels, 0, num_pixels * sizeof(float));
89  }
90  else {
91  const size_t num_pixels_safe = pixels_size / channels;
92  float *fp = (float *)pixels;
93  for (int i = 0; i < num_pixels_safe; i++, fp += channels) {
94  fp[0] = 1.0f;
95  fp[1] = 0.0f;
96  fp[2] = 1.0f;
97  if (channels == 4) {
98  fp[3] = 1.0f;
99  }
100  }
101  }
102  }
103 
104  if (image_pixels) {
105  MEM_freeN(image_pixels);
106  }
107  }
108  else {
109  unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame, tile);
110 
111  if (image_pixels && num_pixels * channels == pixels_size) {
112  memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char));
113  }
114  else {
115  if (channels == 1) {
116  memset(pixels, 0, pixels_size * sizeof(unsigned char));
117  }
118  else {
119  const size_t num_pixels_safe = pixels_size / channels;
120  unsigned char *cp = (unsigned char *)pixels;
121  for (size_t i = 0; i < num_pixels_safe; i++, cp += channels) {
122  cp[0] = 255;
123  cp[1] = 0;
124  cp[2] = 255;
125  if (channels == 4) {
126  cp[3] = 255;
127  }
128  }
129  }
130  }
131 
132  if (image_pixels) {
133  MEM_freeN(image_pixels);
134  }
135 
136  if (associate_alpha) {
137  /* Premultiply, byte images are always straight for Blender. */
138  unsigned char *cp = (unsigned char *)pixels;
139  for (size_t i = 0; i < num_pixels; i++, cp += channels) {
140  cp[0] = (cp[0] * cp[3]) >> 8;
141  cp[1] = (cp[1] * cp[3]) >> 8;
142  cp[2] = (cp[2] * cp[3]) >> 8;
143  }
144  }
145  }
146 
147  /* Free image buffers to save memory during render. */
148  if (free_cache) {
149  b_image.buffers_free();
150  }
151 
152  return true;
153 }
154 
156 {
157  return BL::Image(b_image).name();
158 }
159 
160 bool BlenderImageLoader::equals(const ImageLoader &other) const
161 {
162  const BlenderImageLoader &other_loader = (const BlenderImageLoader &)other;
163  return b_image == other_loader.b_image && frame == other_loader.frame;
164 }
165 
166 /* Point Density */
167 
169  BL::ShaderNodeTexPointDensity b_node)
170  : b_depsgraph(b_depsgraph), b_node(b_node)
171 {
172 }
173 
175 {
176  metadata.channels = 4;
177  metadata.width = b_node.resolution();
178  metadata.height = metadata.width;
179  metadata.depth = metadata.width;
180  metadata.type = IMAGE_DATA_TYPE_FLOAT4;
181  return true;
182 }
183 
185  void *pixels,
186  const size_t,
187  const bool)
188 {
189  int length;
190  b_node.calc_point_density(b_depsgraph, &length, (float **)&pixels);
191  return true;
192 }
193 
195 {
196  /* Force builtin images to be loaded along with Blender data sync. This
197  * is needed because we may be reading from depsgraph evaluated data which
198  * can be freed by Blender before Cycles reads it.
199  *
200  * TODO: the assumption that no further access to builtin image data will
201  * happen is really weak, and likely to break in the future. We should find
202  * a better solution to hand over the data directly to the image manager
203  * instead of through callbacks whose timing is difficult to control. */
205  Device *device = session->device;
206  manager->device_load_builtin(device, session->scene, session->progress);
207 }
208 
210 {
211  return BL::ShaderNodeTexPointDensity(b_node).name();
212 }
213 
215 {
216  const BlenderPointDensityLoader &other_loader = (const BlenderPointDensityLoader &)other;
217  return b_node == other_loader.b_node && b_depsgraph == other_loader.b_depsgraph;
218 }
219 
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
struct Image Image
Read Guarded memory(de)allocation.
static unsigned char * image_get_pixels_for_frame(BL::Image &image, int frame, int tile)
Definition: blender_util.h:260
static float * image_get_float_pixels_for_frame(BL::Image &image, int frame, int tile)
Definition: blender_util.h:265
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:895
bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override
bool load_pixels(const ImageMetaData &metadata, void *pixels, const size_t pixels_size, const bool associate_alpha) override
bool equals(const ImageLoader &other) const override
BlenderImageLoader(BL::Image b_image, int frame)
string name() const override
bool equals(const ImageLoader &other) const override
BL::ShaderNodeTexPointDensity b_node
Definition: blender_image.h:56
BlenderPointDensityLoader(BL::Depsgraph depsgraph, BL::ShaderNodeTexPointDensity b_node)
string name() const override
bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override
bool load_pixels(const ImageMetaData &metadata, void *pixels, const size_t pixels_size, const bool associate_alpha) override
void builtin_images_load()
Session * session
Definition: device.h:293
void device_load_builtin(Device *device, Scene *scene, Progress &progress)
Definition: image.cpp:849
ImageDataType type
Device * device
Definition: session.h:132
Progress progress
Definition: session.h:136
Scene * scene
Definition: session.h:133
ustring u_colorspace_raw
#define CCL_NAMESPACE_END
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
static void free_cache(bNodeTree *ntree)
ImageManager * image_manager
Definition: scene.h:243
@ IMAGE_DATA_TYPE_BYTE
Definition: util_texture.h:56
@ IMAGE_DATA_TYPE_FLOAT
Definition: util_texture.h:55
@ IMAGE_DATA_TYPE_FLOAT4
Definition: util_texture.h:52
@ IMAGE_DATA_TYPE_BYTE4
Definition: util_texture.h:53