Blender  V3.3
readimage.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #ifdef _WIN32
9 # include <io.h>
10 # include <stddef.h>
11 # include <sys/types.h>
12 #endif
13 
14 #include "BLI_fileops.h"
15 #include "BLI_mmap.h"
16 #include "BLI_path_util.h"
17 #include "BLI_string.h"
18 #include "BLI_utildefines.h"
19 #include <stdlib.h>
20 
21 #include "IMB_allocimbuf.h"
22 #include "IMB_filetype.h"
23 #include "IMB_imbuf.h"
24 #include "IMB_imbuf_types.h"
25 #include "IMB_metadata.h"
26 #include "IMB_thumbs.h"
27 #include "imbuf.h"
28 
29 #include "IMB_colormanagement.h"
31 
32 static void imb_handle_alpha(ImBuf *ibuf,
33  int flags,
34  char colorspace[IM_MAX_SPACE],
35  char effective_colorspace[IM_MAX_SPACE])
36 {
37  if (colorspace) {
38  if (ibuf->rect != NULL && ibuf->rect_float == NULL) {
39  /* byte buffer is never internally converted to some standard space,
40  * store pointer to its color space descriptor instead
41  */
42  ibuf->rect_colorspace = colormanage_colorspace_get_named(effective_colorspace);
43  }
44 
45  BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
46  }
47 
48  bool is_data = (colorspace && IMB_colormanagement_space_name_is_data(colorspace));
49  int alpha_flags = (flags & IB_alphamode_detect) ? ibuf->flags : flags;
50 
51  if (is_data || (flags & IB_alphamode_channel_packed)) {
52  /* Don't touch alpha. */
54  }
55  else if (flags & IB_alphamode_ignore) {
56  /* Make opaque. */
57  IMB_rectfill_alpha(ibuf, 1.0f);
58  ibuf->flags |= IB_alphamode_ignore;
59  }
60  else {
61  if (alpha_flags & IB_alphamode_premul) {
62  if (ibuf->rect) {
64  }
65  else {
66  /* pass, floats are expected to be premul */
67  }
68  }
69  else {
70  if (ibuf->rect_float) {
72  }
73  else {
74  /* pass, bytes are expected to be straight */
75  }
76  }
77  }
78 
79  /* OCIO_TODO: in some cases it's faster to do threaded conversion,
80  * but how to distinguish such cases */
81  colormanage_imbuf_make_linear(ibuf, effective_colorspace);
82 }
83 
84 ImBuf *IMB_ibImageFromMemory(const unsigned char *mem,
85  size_t size,
86  int flags,
87  char colorspace[IM_MAX_SPACE],
88  const char *descr)
89 {
90  ImBuf *ibuf;
91  const ImFileType *type;
92  char effective_colorspace[IM_MAX_SPACE] = "";
93 
94  if (mem == NULL) {
95  fprintf(stderr, "%s: NULL pointer\n", __func__);
96  return NULL;
97  }
98 
99  if (colorspace) {
100  BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
101  }
102 
104  if (type->load) {
105  ibuf = type->load(mem, size, flags, effective_colorspace);
106  if (ibuf) {
107  imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
108  return ibuf;
109  }
110  }
111  }
112 
113  if ((flags & IB_test) == 0) {
114  fprintf(stderr, "%s: unknown file-format (%s)\n", __func__, descr);
115  }
116 
117  return NULL;
118 }
119 
120 static ImBuf *IMB_ibImageFromFile(const char *filepath,
121  int flags,
122  char colorspace[IM_MAX_SPACE],
123  const char *descr)
124 {
125  ImBuf *ibuf;
126  const ImFileType *type;
127  char effective_colorspace[IM_MAX_SPACE] = "";
128 
129  if (colorspace) {
130  BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
131  }
132 
134  if (type->load_filepath) {
135  ibuf = type->load_filepath(filepath, flags, effective_colorspace);
136  if (ibuf) {
137  imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
138  return ibuf;
139  }
140  }
141  }
142 
143  if ((flags & IB_test) == 0) {
144  fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
145  }
146 
147  return NULL;
148 }
149 
150 static bool imb_is_filepath_format(const char *filepath)
151 {
152  /* return true if this is one of the formats that can't be loaded from memory */
154 }
155 
157  int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
158 {
159  ImBuf *ibuf;
160  unsigned char *mem;
161  size_t size;
162 
163  if (file == -1) {
164  return NULL;
165  }
166 
167  if (imb_is_filepath_format(filepath)) {
168  return IMB_ibImageFromFile(filepath, flags, colorspace, descr);
169  }
170 
172 
173  imb_mmap_lock();
174  BLI_mmap_file *mmap_file = BLI_mmap_open(file);
175  imb_mmap_unlock();
176  if (mmap_file == NULL) {
177  fprintf(stderr, "%s: couldn't get mapping %s\n", __func__, descr);
178  return NULL;
179  }
180 
181  mem = BLI_mmap_get_pointer(mmap_file);
182 
183  ibuf = IMB_ibImageFromMemory(mem, size, flags, colorspace, descr);
184 
185  imb_mmap_lock();
186  BLI_mmap_free(mmap_file);
187  imb_mmap_unlock();
188 
189  return ibuf;
190 }
191 
192 static void imb_cache_filename(char *filepath, const char *name, int flags)
193 {
194  /* read .tx instead if it exists and is not older */
195  if (flags & IB_tilecache) {
196  BLI_strncpy(filepath, name, IMB_FILENAME_SIZE);
197  if (!BLI_path_extension_replace(filepath, IMB_FILENAME_SIZE, ".tx")) {
198  return;
199  }
200 
201  if (BLI_file_older(name, filepath)) {
202  return;
203  }
204  }
205 
206  BLI_strncpy(filepath, name, IMB_FILENAME_SIZE);
207 }
208 
209 ImBuf *IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
210 {
211  ImBuf *ibuf;
212  int file, a;
213  char filepath_tx[IMB_FILENAME_SIZE];
214 
215  BLI_assert(!BLI_path_is_rel(filepath));
216 
217  imb_cache_filename(filepath_tx, filepath, flags);
218 
219  file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
220  if (file == -1) {
221  return NULL;
222  }
223 
224  ibuf = IMB_loadifffile(file, filepath, flags, colorspace, filepath_tx);
225 
226  if (ibuf) {
227  BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
228  BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
229  for (a = 1; a < ibuf->miptot; a++) {
230  BLI_strncpy(ibuf->mipmap[a - 1]->cachename, filepath_tx, sizeof(ibuf->cachename));
231  }
232  }
233 
234  close(file);
235 
236  return ibuf;
237 }
238 
239 struct ImBuf *IMB_thumb_load_image(const char *filepath,
240  size_t max_thumb_size,
241  char colorspace[IM_MAX_SPACE])
242 {
244  if (type == NULL) {
245  return NULL;
246  }
247 
248  ImBuf *ibuf = NULL;
249  int flags = IB_rect | IB_metadata;
250  /* Size of the original image. */
251  size_t width = 0;
252  size_t height = 0;
253 
254  char effective_colorspace[IM_MAX_SPACE] = "";
255  if (colorspace) {
256  BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
257  }
258 
259  if (type->load_filepath_thumbnail) {
260  ibuf = type->load_filepath_thumbnail(
261  filepath, flags, max_thumb_size, colorspace, &width, &height);
262  }
263  else {
264  /* Skip images of other types if over 100MB. */
265  const size_t file_size = BLI_file_size(filepath);
266  if (file_size != -1 && file_size > THUMB_SIZE_MAX) {
267  return NULL;
268  }
269  ibuf = IMB_loadiffname(filepath, flags, colorspace);
270  if (ibuf) {
271  width = ibuf->x;
272  height = ibuf->y;
273  }
274  }
275 
276  if (ibuf) {
277  imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
278 
279  if (width > 0 && height > 0) {
280  /* Save dimensions of original image into the thumbnail metadata. */
281  char cwidth[40];
282  char cheight[40];
283  SNPRINTF(cwidth, "%zu", width);
284  SNPRINTF(cheight, "%zu", height);
286  IMB_metadata_set_field(ibuf->metadata, "Thumb::Image::Width", cwidth);
287  IMB_metadata_set_field(ibuf->metadata, "Thumb::Image::Height", cheight);
288  }
289  }
290 
291  return ibuf;
292 }
293 
294 ImBuf *IMB_testiffname(const char *filepath, int flags)
295 {
296  ImBuf *ibuf;
297  int file;
298  char filepath_tx[IMB_FILENAME_SIZE];
299  char colorspace[IM_MAX_SPACE] = "\0";
300 
301  BLI_assert(!BLI_path_is_rel(filepath));
302 
303  imb_cache_filename(filepath_tx, filepath, flags);
304 
305  file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
306  if (file == -1) {
307  return NULL;
308  }
309 
310  ibuf = IMB_loadifffile(file, filepath, flags | IB_test | IB_multilayer, colorspace, filepath_tx);
311 
312  if (ibuf) {
313  BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
314  BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
315  }
316 
317  close(file);
318 
319  return ibuf;
320 }
321 
322 static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int *rect)
323 {
324  unsigned char *mem;
325  size_t size;
326 
327  if (file == -1) {
328  return;
329  }
330 
332 
333  imb_mmap_lock();
334  BLI_mmap_file *mmap_file = BLI_mmap_open(file);
335  imb_mmap_unlock();
336  if (mmap_file == NULL) {
337  fprintf(stderr, "Couldn't get memory mapping for %s\n", ibuf->cachename);
338  return;
339  }
340 
341  mem = BLI_mmap_get_pointer(mmap_file);
342 
343  const ImFileType *type = IMB_file_type_from_ibuf(ibuf);
344  if (type != NULL) {
345  if (type->load_tile != NULL) {
346  type->load_tile(ibuf, mem, size, tx, ty, rect);
347  }
348  }
349 
350  imb_mmap_lock();
351  BLI_mmap_free(mmap_file);
352  imb_mmap_unlock();
353 }
354 
355 void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
356 {
357  int file;
358 
359  file = BLI_open(ibuf->cachename, O_BINARY | O_RDONLY, 0);
360  if (file == -1) {
361  return;
362  }
363 
364  imb_loadtilefile(ibuf, file, tx, ty, rect);
365 
366  close(file);
367 }
#define BLI_assert(a)
Definition: BLI_assert.h:46
File and directory operations.
bool BLI_file_older(const char *file1, const char *file2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:569
#define O_BINARY
Definition: BLI_fileops.h:319
size_t BLI_file_descriptor_size(int file) ATTR_WARN_UNUSED_RESULT
Definition: storage.c:178
size_t BLI_file_size(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:187
int BLI_open(const char *filepath, int oflag, int pmode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: fileops.c:920
BLI_mmap_file * BLI_mmap_open(int fd) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_mmap.c:131
void BLI_mmap_free(BLI_mmap_file *file) ATTR_NONNULL(1)
Definition: BLI_mmap.c:210
void * BLI_mmap_get_pointer(BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT
Definition: BLI_mmap.c:205
bool BLI_path_extension_check_array(const char *str, const char **ext_array) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:1326
bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:347
bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext) ATTR_NONNULL()
Definition: path_util.c:1393
#define SNPRINTF(dst, format,...)
Definition: BLI_string.h:485
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
_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 type
_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
Header file for allocimbuf.c.
bool IMB_colormanagement_space_name_is_data(const char *name)
void IMB_rectfill_alpha(struct ImBuf *ibuf, float value)
Definition: rectop.c:1262
int IMB_ispic_type(const char *filepath)
Definition: util.c:151
#define IM_MAX_SPACE
Definition: IMB_imbuf.h:49
void IMB_premultiply_alpha(struct ImBuf *ibuf)
Definition: filter.c:662
void IMB_unpremultiply_alpha(struct ImBuf *ibuf)
Definition: filter.c:724
Contains defines and structs used throughout the imbuf module.
const char * imb_ext_image_filepath_only[]
Definition: util.c:72
#define IMB_FILENAME_SIZE
@ IB_alphamode_channel_packed
@ IB_alphamode_premul
@ IB_alphamode_ignore
@ IB_metadata
@ IB_multilayer
@ IB_tilecache
@ IB_alphamode_detect
@ IB_test
@ IB_rect
void IMB_metadata_set_field(struct IDProperty *metadata, const char *key, const char *value)
Definition: metadata.c:73
void IMB_metadata_ensure(struct IDProperty **metadata)
Definition: metadata.c:25
#define THUMB_SIZE_MAX
Definition: IMB_thumbs.h:38
void imb_mmap_lock(void)
Definition: allocimbuf.c:53
void imb_mmap_unlock(void)
Definition: allocimbuf.c:58
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
ColorSpace * colormanage_colorspace_get_named(const char *name)
void colormanage_imbuf_make_linear(ImBuf *ibuf, const char *from_colorspace)
FILE * file
const ImFileType * IMB_file_type_from_ftype(int ftype)
Definition: filetype.c:233
const ImFileType IMB_FILE_TYPES[]
Definition: filetype.c:29
const ImFileType * IMB_file_type_from_ibuf(const ImBuf *ibuf)
Definition: filetype.c:243
const ImFileType * IMB_FILE_TYPES_LAST
Definition: filetype.c:231
static unsigned a[3]
Definition: RandGen.cpp:78
static ImBuf * IMB_ibImageFromFile(const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
Definition: readimage.c:120
ImBuf * IMB_testiffname(const char *filepath, int flags)
Definition: readimage.c:294
static void imb_cache_filename(char *filepath, const char *name, int flags)
Definition: readimage.c:192
ImBuf * IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
Definition: readimage.c:209
ImBuf * IMB_ibImageFromMemory(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
Definition: readimage.c:84
static bool imb_is_filepath_format(const char *filepath)
Definition: readimage.c:150
void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
Definition: readimage.c:355
static void imb_handle_alpha(ImBuf *ibuf, int flags, char colorspace[IM_MAX_SPACE], char effective_colorspace[IM_MAX_SPACE])
Definition: readimage.c:32
struct ImBuf * IMB_thumb_load_image(const char *filepath, size_t max_thumb_size, char colorspace[IM_MAX_SPACE])
Definition: readimage.c:239
static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int *rect)
Definition: readimage.c:322
ImBuf * IMB_loadifffile(int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
Definition: readimage.c:156
struct IDProperty * metadata
struct ImBuf * mipmap[IMB_MIPMAP_LEVELS]
struct ColorSpace * rect_colorspace
char name[IMB_FILENAME_SIZE]
unsigned int * rect
char cachename[IMB_FILENAME_SIZE]
float * rect_float