Blender  V2.93
rna_image_api.c
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) 2009 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <time.h>
28 
29 #include "DNA_packedFile_types.h"
30 
31 #include "BLI_path_util.h"
32 #include "BLI_utildefines.h"
33 
34 #include "RNA_define.h"
35 #include "RNA_enum_types.h"
36 
37 #include "BKE_packedFile.h"
38 
39 #include "rna_internal.h" /* own include */
40 
41 #ifdef RNA_RUNTIME
42 
43 # include "BKE_image.h"
44 # include "BKE_main.h"
45 # include <errno.h>
46 
47 # include "IMB_colormanagement.h"
48 # include "IMB_imbuf.h"
49 
50 # include "DNA_image_types.h"
51 # include "DNA_scene_types.h"
52 
53 # include "MEM_guardedalloc.h"
54 
55 static void rna_ImagePackedFile_save(ImagePackedFile *imapf, Main *bmain, ReportList *reports)
56 {
58  reports, BKE_main_blendfile_path(bmain), imapf->filepath, imapf->packedfile, 0) !=
59  RET_OK) {
60  BKE_reportf(reports, RPT_ERROR, "Could not save packed file to disk as '%s'", imapf->filepath);
61  }
62 }
63 
64 static void rna_Image_save_render(
65  Image *image, bContext *C, ReportList *reports, const char *path, Scene *scene)
66 {
67  ImBuf *ibuf;
68 
69  if (scene == NULL) {
71  }
72 
73  if (scene) {
74  ImageUser iuser = {NULL};
75  void *lock;
76 
77  iuser.scene = scene;
78  iuser.ok = 1;
79 
80  ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
81 
82  if (ibuf == NULL) {
83  BKE_report(reports, RPT_ERROR, "Could not acquire buffer from image");
84  }
85  else {
86  ImBuf *write_ibuf;
87 
89  ibuf, true, true, &scene->view_settings, &scene->display_settings, &scene->r.im_format);
90 
91  write_ibuf->planes = scene->r.im_format.planes;
92  write_ibuf->dither = scene->r.dither_intensity;
93 
94  if (!BKE_imbuf_write(write_ibuf, path, &scene->r.im_format)) {
95  BKE_reportf(reports, RPT_ERROR, "Could not write image: %s, '%s'", strerror(errno), path);
96  }
97 
98  if (write_ibuf != ibuf) {
99  IMB_freeImBuf(write_ibuf);
100  }
101  }
102 
103  BKE_image_release_ibuf(image, ibuf, lock);
104  }
105  else {
106  BKE_report(reports, RPT_ERROR, "Scene not in context, could not get save parameters");
107  }
108 }
109 
110 static void rna_Image_save(Image *image, Main *bmain, bContext *C, ReportList *reports)
111 {
112  void *lock;
113 
114  ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
115  if (ibuf) {
116  char filename[FILE_MAX];
117  BLI_strncpy(filename, image->filepath, sizeof(filename));
118  BLI_path_abs(filename, ID_BLEND_PATH(bmain, &image->id));
119 
120  /* note, we purposefully ignore packed files here,
121  * developers need to explicitly write them via 'packed_files' */
122 
123  if (IMB_saveiff(ibuf, filename, ibuf->flags)) {
124  image->type = IMA_TYPE_IMAGE;
125 
126  if (image->source == IMA_SRC_GENERATED) {
127  image->source = IMA_SRC_FILE;
128  }
129 
131 
132  ibuf->userflags &= ~IB_BITMAPDIRTY;
133  }
134  else {
135  BKE_reportf(reports,
136  RPT_ERROR,
137  "Image '%s' could not be saved to '%s'",
138  image->id.name + 2,
139  image->filepath);
140  }
141  }
142  else {
143  BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2);
144  }
145 
146  BKE_image_release_ibuf(image, ibuf, lock);
148 }
149 
150 static void rna_Image_pack(
151  Image *image, Main *bmain, bContext *C, ReportList *reports, const char *data, int data_len)
152 {
154 
155  if (data) {
156  char *data_dup = MEM_mallocN(sizeof(*data_dup) * (size_t)data_len, __func__);
157  memcpy(data_dup, data, (size_t)data_len);
158  BKE_image_packfiles_from_mem(reports, image, data_dup, (size_t)data_len);
159  }
160  else if (BKE_image_is_dirty(image)) {
161  BKE_image_memorypack(image);
162  }
163  else {
164  BKE_image_packfiles(reports, image, ID_BLEND_PATH(bmain, &image->id));
165  }
166 
168 }
169 
170 static void rna_Image_unpack(Image *image, Main *bmain, ReportList *reports, int method)
171 {
172  if (!BKE_image_has_packedfile(image)) {
173  BKE_report(reports, RPT_ERROR, "Image not packed");
174  }
175  else if (BKE_image_has_multiple_ibufs(image)) {
176  BKE_report(
177  reports, RPT_ERROR, "Unpacking movies, image sequences or tiled images not supported");
178  return;
179  }
180  else {
181  /* reports its own error on failure */
182  BKE_packedfile_unpack_image(bmain, reports, image, method);
183  }
184 }
185 
186 static void rna_Image_reload(Image *image, Main *bmain)
187 {
188  BKE_image_signal(bmain, image, NULL, IMA_SIGNAL_RELOAD);
190 }
191 
192 static void rna_Image_update(Image *image, ReportList *reports)
193 {
194  ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
195 
196  if (ibuf == NULL) {
197  BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2);
198  return;
199  }
200 
201  if (ibuf->rect) {
202  IMB_rect_from_float(ibuf);
203  }
204 
206 
207  BKE_image_release_ibuf(image, ibuf, NULL);
208 }
209 
210 static void rna_Image_scale(Image *image, ReportList *reports, int width, int height)
211 {
212  if (!BKE_image_scale(image, width, height)) {
213  BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2);
214  }
215 }
216 
217 static int rna_Image_gl_load(Image *image, ReportList *reports, int frame)
218 {
219  ImageUser iuser;
220  BKE_imageuser_default(&iuser);
221  iuser.framenr = frame;
222 
223  GPUTexture *tex = BKE_image_get_gpu_texture(image, &iuser, NULL);
224 
225  if (tex == NULL) {
226  BKE_reportf(reports, RPT_ERROR, "Failed to load image texture '%s'", image->id.name + 2);
227  /* TODO(fclem): this error code makes no sense for vulkan. */
228  return 0x0502; /* GL_INVALID_OPERATION */
229  }
230 
231  return 0; /* GL_NO_ERROR */
232 }
233 
234 static int rna_Image_gl_touch(Image *image, ReportList *reports, int frame)
235 {
236  int error = 0; /* GL_NO_ERROR */
237 
238  BKE_image_tag_time(image);
239 
240  if (image->gputexture[TEXTARGET_2D][0] == NULL) {
241  error = rna_Image_gl_load(image, reports, frame);
242  }
243 
244  return error;
245 }
246 
247 static void rna_Image_gl_free(Image *image)
248 {
250 
251  /* remove the nocollect flag, image is available for garbage collection again */
252  image->flag &= ~IMA_NOCOLLECT;
253 }
254 
255 static void rna_Image_filepath_from_user(Image *image, ImageUser *image_user, char *filepath)
256 {
257  BKE_image_user_file_path(image_user, image, filepath);
258 }
259 
260 static void rna_Image_buffers_free(Image *image)
261 {
262  BKE_image_free_buffers_ex(image, true);
263 }
264 
265 #else
266 
268 {
269  FunctionRNA *func;
270 
271  func = RNA_def_function(srna, "save", "rna_ImagePackedFile_save");
272  RNA_def_function_ui_description(func, "Save the packed file to its filepath");
274 }
275 
277 {
278  FunctionRNA *func;
279  PropertyRNA *parm;
280 
281  func = RNA_def_function(srna, "save_render", "rna_Image_save_render");
283  "Save image to a specific path using a scenes render settings");
285  parm = RNA_def_string_file_path(func, "filepath", NULL, 0, "", "Save path");
287  RNA_def_pointer(func, "scene", "Scene", "", "Scene to take image parameters from");
288 
289  func = RNA_def_function(srna, "save", "rna_Image_save");
290  RNA_def_function_ui_description(func, "Save image to its source path");
292 
293  func = RNA_def_function(srna, "pack", "rna_Image_pack");
294  RNA_def_function_ui_description(func, "Pack an image as embedded data into the .blend file");
296  parm = RNA_def_property(func, "data", PROP_STRING, PROP_BYTESTRING);
297  RNA_def_property_ui_text(parm, "data", "Raw data (bytes, exact content of the embedded file)");
298  RNA_def_int(func,
299  "data_len",
300  0,
301  0,
302  INT_MAX,
303  "data_len",
304  "length of given data (mandatory if data is provided)",
305  0,
306  INT_MAX);
307 
308  func = RNA_def_function(srna, "unpack", "rna_Image_unpack");
309  RNA_def_function_ui_description(func, "Save an image packed in the .blend file to disk");
311  RNA_def_enum(
312  func, "method", rna_enum_unpack_method_items, PF_USE_LOCAL, "method", "How to unpack");
313 
314  func = RNA_def_function(srna, "reload", "rna_Image_reload");
316  RNA_def_function_ui_description(func, "Reload the image from its source path");
317 
318  func = RNA_def_function(srna, "update", "rna_Image_update");
319  RNA_def_function_ui_description(func, "Update the display image from the floating-point buffer");
321 
322  func = RNA_def_function(srna, "scale", "rna_Image_scale");
323  RNA_def_function_ui_description(func, "Scale the image in pixels");
325  parm = RNA_def_int(func, "width", 1, 1, INT_MAX, "", "Width", 1, INT_MAX);
327  parm = RNA_def_int(func, "height", 1, 1, INT_MAX, "", "Height", 1, INT_MAX);
329 
330  func = RNA_def_function(srna, "gl_touch", "rna_Image_gl_touch");
332  func, "Delay the image from being cleaned from the cache due inactivity");
334  RNA_def_int(
335  func, "frame", 0, 0, INT_MAX, "Frame", "Frame of image sequence or movie", 0, INT_MAX);
336  /* return value */
337  parm = RNA_def_int(
338  func, "error", 0, -INT_MAX, INT_MAX, "Error", "OpenGL error value", -INT_MAX, INT_MAX);
339  RNA_def_function_return(func, parm);
340 
341  func = RNA_def_function(srna, "gl_load", "rna_Image_gl_load");
343  func,
344  "Load the image into an OpenGL texture. On success, image.bindcode will contain the "
345  "OpenGL texture bindcode. Colors read from the texture will be in scene linear color space "
346  "and have premultiplied or straight alpha matching the image alpha mode");
348  RNA_def_int(
349  func, "frame", 0, 0, INT_MAX, "Frame", "Frame of image sequence or movie", 0, INT_MAX);
350  /* return value */
351  parm = RNA_def_int(
352  func, "error", 0, -INT_MAX, INT_MAX, "Error", "OpenGL error value", -INT_MAX, INT_MAX);
353  RNA_def_function_return(func, parm);
354 
355  func = RNA_def_function(srna, "gl_free", "rna_Image_gl_free");
356  RNA_def_function_ui_description(func, "Free the image from OpenGL graphics memory");
357 
358  /* path to an frame specified by image user */
359  func = RNA_def_function(srna, "filepath_from_user", "rna_Image_filepath_from_user");
361  func,
362  "Return the absolute path to the filepath of an image frame specified by the image user");
364  func, "image_user", "ImageUser", "", "Image user of the image to get filepath for");
365  parm = RNA_def_string_file_path(func,
366  "filepath",
367  NULL,
368  FILE_MAX,
369  "File Path",
370  "The resulting filepath from the image and its user");
371  RNA_def_parameter_flags(parm, PROP_THICK_WRAP, 0); /* needed for string return value */
372  RNA_def_function_output(func, parm);
373 
374  func = RNA_def_function(srna, "buffers_free", "rna_Image_buffers_free");
375  RNA_def_function_ui_description(func, "Free the image buffers from memory");
376 
377  /* TODO, pack/unpack, maybe should be generic functions? */
378 }
379 
380 #endif
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock)
Definition: image.c:5113
void BKE_image_user_file_path(struct ImageUser *iuser, struct Image *ima, char *path)
Definition: image.c:5451
void BKE_image_free_buffers_ex(struct Image *image, bool do_lock)
Definition: image.c:490
bool BKE_image_has_packedfile(struct Image *image)
Definition: image.c:5627
int BKE_imbuf_write(struct ImBuf *ibuf, const char *name, const struct ImageFormatData *imf)
struct ImBuf * BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **r_lock)
Definition: image.c:5100
bool BKE_image_scale(struct Image *image, int width, int height)
Definition: image.c:643
void BKE_image_packfiles(struct ReportList *reports, struct Image *ima, const char *basepath)
Definition: image.c:1134
bool BKE_image_memorypack(struct Image *ima)
Definition: image.c:1083
void BKE_image_packfiles_from_mem(struct ReportList *reports, struct Image *ima, char *data, const size_t data_len)
Definition: image.c:1166
void BKE_image_free_gputextures(struct Image *ima)
Definition: image_gpu.c:517
struct GPUTexture * BKE_image_get_gpu_texture(struct Image *image, struct ImageUser *iuser, struct ImBuf *ibuf)
Definition: image_gpu.c:439
bool BKE_image_is_dirty(struct Image *image)
Definition: image.c:5681
#define IMA_SIGNAL_RELOAD
Definition: BKE_image.h:162
void BKE_image_signal(struct Main *bmain, struct Image *ima, struct ImageUser *iuser, int signal)
Definition: image.c:3499
void BKE_image_free_packedfiles(struct Image *image)
Definition: image.c:463
void BKE_imageuser_default(struct ImageUser *iuser)
Definition: image.c:3451
void BKE_image_tag_time(struct Image *ima)
Definition: image.c:1184
bool BKE_image_has_multiple_ibufs(struct Image *image)
Definition: image.c:5646
const char * BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL()
int BKE_packedfile_write_to_file(struct ReportList *reports, const char *ref_file_name, const char *filename, struct PackedFile *pf, const bool guimode)
Definition: packedFile.c:302
int BKE_packedfile_unpack_image(struct Main *bmain, struct ReportList *reports, struct Image *ima, enum ePF_FileStatus how)
Definition: packedFile.c:635
#define RET_OK
@ PF_USE_LOCAL
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define FILE_MAX
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
Definition: path_util.c:1016
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define ID_BLEND_PATH(_bmain, _id)
Definition: DNA_ID.h:419
@ IMA_NOCOLLECT
@ IMA_TYPE_IMAGE
@ IMA_SRC_FILE
@ IMA_SRC_GENERATED
@ TEXTARGET_2D
_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
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
void IMB_colormanagement_colorspace_from_ibuf_ftype(struct ColorManagedColorspaceSettings *colorspace_settings, struct ImBuf *ibuf)
struct ImBuf * IMB_colormanagement_imbuf_for_write(struct ImBuf *ibuf, bool save_as_render, bool allocate_result, const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings, struct ImageFormatData *image_format_data)
void IMB_rect_from_float(struct ImBuf *ibuf)
Definition: divers.c:720
void IMB_freeImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:211
bool IMB_saveiff(struct ImBuf *ibuf, const char *filepath, int flags)
Definition: writeimage.c:44
@ IB_BITMAPDIRTY
@ IB_DISPLAY_BUFFER_INVALID
Read Guarded memory(de)allocation.
@ PARM_REQUIRED
Definition: RNA_types.h:337
@ FUNC_USE_REPORTS
Definition: RNA_types.h:578
@ FUNC_USE_MAIN
Definition: RNA_types.h:576
@ FUNC_USE_CONTEXT
Definition: RNA_types.h:577
@ PROP_STRING
Definition: RNA_types.h:76
@ PROP_THICK_WRAP
Definition: RNA_types.h:270
@ PROP_BYTESTRING
Definition: RNA_types.h:120
#define C
Definition: RandGen.cpp:39
#define NA_EDITED
Definition: WM_types.h:462
#define NC_IMAGE
Definition: WM_types.h:285
ColorManagedColorspaceSettings colorspace_settings
char filepath[1024]
short type
struct GPUTexture * gputexture[3][2]
short source
Scene scene
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static void error(const char *str)
Definition: meshlaplacian.c:65
PropertyRNA * RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type, const char *ui_name, const char *ui_description)
Definition: rna_define.c:4159
void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
Definition: rna_define.c:4302
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
Definition: rna_define.c:1676
PropertyRNA * RNA_def_string_file_path(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3699
FunctionRNA * RNA_def_function(StructRNA *srna, const char *identifier, const char *call)
Definition: rna_define.c:4262
void RNA_def_function_output(FunctionRNA *UNUSED(func), PropertyRNA *ret)
Definition: rna_define.c:4327
void RNA_def_function_ui_description(FunctionRNA *func, const char *description)
Definition: rna_define.c:4337
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
Definition: rna_define.c:1279
void RNA_def_function_flag(FunctionRNA *func, int flag)
Definition: rna_define.c:4332
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3585
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
void RNA_def_parameter_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter)
Definition: rna_define.c:1547
void RNA_api_image(StructRNA *srna)
void RNA_api_image_packed_file(StructRNA *srna)
const EnumPropertyItem rna_enum_unpack_method_items[]
char name[66]
Definition: DNA_ID.h:283
int userflags
float dither
unsigned char planes
unsigned int * rect
struct PackedFile * packedfile
char filepath[1024]
struct Scene * scene
Definition: BKE_main.h:116
struct ImageFormatData im_format
float dither_intensity
ColorManagedViewSettings view_settings
struct RenderData r
ColorManagedDisplaySettings display_settings
void WM_main_add_notifier(unsigned int type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)