Blender  V2.93
readimage.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) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  * allocimbuf.c
19  */
20 
25 #ifdef _WIN32
26 # include <io.h>
27 # include <stddef.h>
28 # include <sys/types.h>
29 #endif
30 
31 #include "BLI_fileops.h"
32 #include "BLI_mmap.h"
33 #include "BLI_path_util.h"
34 #include "BLI_string.h"
35 #include "BLI_utildefines.h"
36 #include <stdlib.h>
37 
38 #include "IMB_allocimbuf.h"
39 #include "IMB_filetype.h"
40 #include "IMB_imbuf.h"
41 #include "IMB_imbuf_types.h"
42 #include "imbuf.h"
43 
44 #include "IMB_colormanagement.h"
46 
47 static void imb_handle_alpha(ImBuf *ibuf,
48  int flags,
49  char colorspace[IM_MAX_SPACE],
50  char effective_colorspace[IM_MAX_SPACE])
51 {
52  if (colorspace) {
53  if (ibuf->rect != NULL && ibuf->rect_float == NULL) {
54  /* byte buffer is never internally converted to some standard space,
55  * store pointer to its color space descriptor instead
56  */
57  ibuf->rect_colorspace = colormanage_colorspace_get_named(effective_colorspace);
58  }
59 
60  BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
61  }
62 
63  bool is_data = (colorspace && IMB_colormanagement_space_name_is_data(colorspace));
64  int alpha_flags = (flags & IB_alphamode_detect) ? ibuf->flags : flags;
65 
66  if (is_data || (flags & IB_alphamode_channel_packed)) {
67  /* Don't touch alpha. */
69  }
70  else if (flags & IB_alphamode_ignore) {
71  /* Make opaque. */
72  IMB_rectfill_alpha(ibuf, 1.0f);
73  ibuf->flags |= IB_alphamode_ignore;
74  }
75  else {
76  if (alpha_flags & IB_alphamode_premul) {
77  if (ibuf->rect) {
79  }
80  else {
81  /* pass, floats are expected to be premul */
82  }
83  }
84  else {
85  if (ibuf->rect_float) {
87  }
88  else {
89  /* pass, bytes are expected to be straight */
90  }
91  }
92  }
93 
94  /* OCIO_TODO: in some cases it's faster to do threaded conversion,
95  * but how to distinguish such cases */
96  colormanage_imbuf_make_linear(ibuf, effective_colorspace);
97 }
98 
99 ImBuf *IMB_ibImageFromMemory(const unsigned char *mem,
100  size_t size,
101  int flags,
102  char colorspace[IM_MAX_SPACE],
103  const char *descr)
104 {
105  ImBuf *ibuf;
106  const ImFileType *type;
107  char effective_colorspace[IM_MAX_SPACE] = "";
108 
109  if (mem == NULL) {
110  fprintf(stderr, "%s: NULL pointer\n", __func__);
111  return NULL;
112  }
113 
114  if (colorspace) {
115  BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
116  }
117 
119  if (type->load) {
120  ibuf = type->load(mem, size, flags, effective_colorspace);
121  if (ibuf) {
122  imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
123  return ibuf;
124  }
125  }
126  }
127 
128  if ((flags & IB_test) == 0) {
129  fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
130  }
131 
132  return NULL;
133 }
134 
135 static ImBuf *IMB_ibImageFromFile(const char *filepath,
136  int flags,
137  char colorspace[IM_MAX_SPACE],
138  const char *descr)
139 {
140  ImBuf *ibuf;
141  const ImFileType *type;
142  char effective_colorspace[IM_MAX_SPACE] = "";
143 
144  if (colorspace) {
145  BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
146  }
147 
149  if (type->load_filepath) {
150  ibuf = type->load_filepath(filepath, flags, effective_colorspace);
151  if (ibuf) {
152  imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
153  return ibuf;
154  }
155  }
156  }
157 
158  if ((flags & IB_test) == 0) {
159  fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
160  }
161 
162  return NULL;
163 }
164 
165 static bool imb_is_filepath_format(const char *filepath)
166 {
167  /* return true if this is one of the formats that can't be loaded from memory */
169 }
170 
172  int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
173 {
174  ImBuf *ibuf;
175  unsigned char *mem;
176  size_t size;
177 
178  if (file == -1) {
179  return NULL;
180  }
181 
182  if (imb_is_filepath_format(filepath)) {
183  return IMB_ibImageFromFile(filepath, flags, colorspace, descr);
184  }
185 
187 
188  imb_mmap_lock();
189  BLI_mmap_file *mmap_file = BLI_mmap_open(file);
190  imb_mmap_unlock();
191  if (mmap_file == NULL) {
192  fprintf(stderr, "%s: couldn't get mapping %s\n", __func__, descr);
193  return NULL;
194  }
195 
196  mem = BLI_mmap_get_pointer(mmap_file);
197 
198  ibuf = IMB_ibImageFromMemory(mem, size, flags, colorspace, descr);
199 
200  imb_mmap_lock();
201  BLI_mmap_free(mmap_file);
202  imb_mmap_unlock();
203 
204  return ibuf;
205 }
206 
207 static void imb_cache_filename(char *filename, const char *name, int flags)
208 {
209  /* read .tx instead if it exists and is not older */
210  if (flags & IB_tilecache) {
211  BLI_strncpy(filename, name, IMB_FILENAME_SIZE);
212  if (!BLI_path_extension_replace(filename, IMB_FILENAME_SIZE, ".tx")) {
213  return;
214  }
215 
216  if (BLI_file_older(name, filename)) {
217  return;
218  }
219  }
220 
221  BLI_strncpy(filename, name, IMB_FILENAME_SIZE);
222 }
223 
224 ImBuf *IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
225 {
226  ImBuf *ibuf;
227  int file, a;
228  char filepath_tx[IMB_FILENAME_SIZE];
229 
230  BLI_assert(!BLI_path_is_rel(filepath));
231 
232  imb_cache_filename(filepath_tx, filepath, flags);
233 
234  file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
235  if (file == -1) {
236  return NULL;
237  }
238 
239  ibuf = IMB_loadifffile(file, filepath, flags, colorspace, filepath_tx);
240 
241  if (ibuf) {
242  BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
243  BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
244  for (a = 1; a < ibuf->miptot; a++) {
245  BLI_strncpy(ibuf->mipmap[a - 1]->cachename, filepath_tx, sizeof(ibuf->cachename));
246  }
247  }
248 
249  close(file);
250 
251  return ibuf;
252 }
253 
254 ImBuf *IMB_testiffname(const char *filepath, int flags)
255 {
256  ImBuf *ibuf;
257  int file;
258  char filepath_tx[IMB_FILENAME_SIZE];
259  char colorspace[IM_MAX_SPACE] = "\0";
260 
261  BLI_assert(!BLI_path_is_rel(filepath));
262 
263  imb_cache_filename(filepath_tx, filepath, flags);
264 
265  file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
266  if (file == -1) {
267  return NULL;
268  }
269 
270  ibuf = IMB_loadifffile(file, filepath, flags | IB_test | IB_multilayer, colorspace, filepath_tx);
271 
272  if (ibuf) {
273  BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
274  BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
275  }
276 
277  close(file);
278 
279  return ibuf;
280 }
281 
282 static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int *rect)
283 {
284  unsigned char *mem;
285  size_t size;
286 
287  if (file == -1) {
288  return;
289  }
290 
292 
293  imb_mmap_lock();
294  BLI_mmap_file *mmap_file = BLI_mmap_open(file);
295  imb_mmap_unlock();
296  if (mmap_file == NULL) {
297  fprintf(stderr, "Couldn't get memory mapping for %s\n", ibuf->cachename);
298  return;
299  }
300 
301  mem = BLI_mmap_get_pointer(mmap_file);
302 
303  const ImFileType *type = IMB_file_type_from_ibuf(ibuf);
304  if (type != NULL) {
305  if (type->load_tile != NULL) {
306  type->load_tile(ibuf, mem, size, tx, ty, rect);
307  }
308  }
309 
310  imb_mmap_lock();
311  BLI_mmap_free(mmap_file);
312  imb_mmap_unlock();
313 }
314 
315 void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
316 {
317  int file;
318 
319  file = BLI_open(ibuf->cachename, O_BINARY | O_RDONLY, 0);
320  if (file == -1) {
321  return;
322  }
323 
324  imb_loadtilefile(ibuf, file, tx, ty, rect);
325 
326  close(file);
327 }
#define BLI_assert(a)
Definition: BLI_assert.h:58
File and directory operations.
int BLI_open(const char *filename, int oflag, int pmode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: fileops.c:1017
bool BLI_file_older(const char *file1, const char *file2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:645
#define O_BINARY
Definition: BLI_fileops.h:182
size_t BLI_file_descriptor_size(int file) ATTR_WARN_UNUSED_RESULT
Definition: storage.c:207
BLI_mmap_file * BLI_mmap_open(int fd) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_mmap.c:147
void BLI_mmap_free(BLI_mmap_file *file) ATTR_NONNULL(1)
Definition: BLI_mmap.c:226
void * BLI_mmap_get_pointer(BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT
Definition: BLI_mmap.c:221
bool BLI_path_extension_check_array(const char *str, const char **ext_array) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:1487
bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:411
bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext) ATTR_NONNULL()
Definition: path_util.c:1571
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
_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
Header file for allocimbuf.c.
bool IMB_colormanagement_space_name_is_data(const char *name)
#define IM_MAX_SPACE
Definition: IMB_imbuf.h:65
void IMB_premultiply_alpha(struct ImBuf *ibuf)
Definition: filter.c:687
void IMB_rectfill_alpha(struct ImBuf *ibuf, const float value)
Definition: rectop.c:1313
void IMB_unpremultiply_alpha(struct ImBuf *ibuf)
Definition: filter.c:749
Contains defines and structs used throughout the imbuf module.
const char * imb_ext_image_filepath_only[]
Definition: util.c:86
#define IMB_FILENAME_SIZE
@ IB_alphamode_channel_packed
@ IB_alphamode_premul
@ IB_alphamode_ignore
@ IB_multilayer
@ IB_tilecache
@ IB_alphamode_detect
@ IB_test
void imb_mmap_lock(void)
Definition: allocimbuf.c:69
void imb_mmap_unlock(void)
Definition: allocimbuf.c:74
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_TYPES[]
Definition: filetype.c:43
const ImFileType * IMB_file_type_from_ibuf(const ImBuf *ibuf)
Definition: filetype.c:229
const ImFileType * IMB_FILE_TYPES_LAST
Definition: filetype.c:217
static unsigned a[3]
Definition: RandGen.cpp:92
static ImBuf * IMB_ibImageFromFile(const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
Definition: readimage.c:135
static void imb_cache_filename(char *filename, const char *name, int flags)
Definition: readimage.c:207
ImBuf * IMB_testiffname(const char *filepath, int flags)
Definition: readimage.c:254
ImBuf * IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
Definition: readimage.c:224
ImBuf * IMB_ibImageFromMemory(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
Definition: readimage.c:99
static bool imb_is_filepath_format(const char *filepath)
Definition: readimage.c:165
void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
Definition: readimage.c:315
static void imb_handle_alpha(ImBuf *ibuf, int flags, char colorspace[IM_MAX_SPACE], char effective_colorspace[IM_MAX_SPACE])
Definition: readimage.c:47
static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int *rect)
Definition: readimage.c:282
ImBuf * IMB_loadifffile(int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
Definition: readimage.c:171
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