Blender V4.5
readimage.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#ifdef _WIN32
10# include "BLI_winstuff.h"
11# include <exception>
12# include <io.h>
13# include <stddef.h>
14# include <sys/types.h>
15#endif
16
17#include "BLI_fileops.h"
18#include "BLI_mmap.h"
19#include "BLI_path_utils.hh" /* For assertions. */
20#include "BLI_string.h"
21#include <cstdlib>
22
23#include "IMB_allocimbuf.hh"
24#include "IMB_filetype.hh"
25#include "IMB_imbuf.hh"
26#include "IMB_imbuf_types.hh"
27#include "IMB_metadata.hh"
28#include "IMB_thumbs.hh"
29#include "imbuf.hh"
30
33
35 const int flags,
36 const char *filepath,
37 const ImFileColorSpace &file_colorspace,
38 char r_colorspace[IM_MAX_SPACE])
39{
40 /* Determine file colorspace. */
41 char new_colorspace[IM_MAX_SPACE];
42
43 if (r_colorspace && r_colorspace[0]) {
44 /* Existing configured colorspace has priority. */
45 STRNCPY(new_colorspace, r_colorspace);
46 }
47 else if (file_colorspace.metadata_colorspace[0] &&
49 {
50 /* Use colorspace from file metadata if provided. */
51 STRNCPY(new_colorspace, file_colorspace.metadata_colorspace);
52 }
53 else {
54 const char *filepath_colorspace = (filepath) ?
56 nullptr;
57 if (filepath_colorspace) {
58 /* Use colorspace from OpenColorIO file rules. */
59 STRNCPY(new_colorspace, filepath_colorspace);
60 }
61 else {
62 /* Use float colorspace if the image may contain HDR colors, byte otherwise. */
63 const char *role_colorspace = IMB_colormanagement_role_colorspace_name_get(
65 STRNCPY(new_colorspace, role_colorspace);
66 }
67 }
68
69 if (r_colorspace) {
70 BLI_strncpy(r_colorspace, new_colorspace, IM_MAX_SPACE);
71 }
72
73 if (r_colorspace) {
74 if (ibuf->byte_buffer.data != nullptr && ibuf->float_buffer.data == nullptr) {
75 /* byte buffer is never internally converted to some standard space,
76 * store pointer to its color space descriptor instead
77 */
79 }
80 }
81
82 bool is_data = (r_colorspace && IMB_colormanagement_space_name_is_data(new_colorspace));
83 int alpha_flags = (flags & IB_alphamode_detect) ? ibuf->flags : flags;
84
85 if (is_data || (flags & IB_alphamode_channel_packed)) {
86 /* Don't touch alpha. */
88 }
89 else if (flags & IB_alphamode_ignore) {
90 /* Make opaque. */
91 IMB_rectfill_alpha(ibuf, 1.0f);
93 }
94 else {
95 if (alpha_flags & IB_alphamode_premul) {
96 if (ibuf->byte_buffer.data) {
98 }
99 else {
100 /* pass, floats are expected to be premul */
101 }
102 }
103 else {
104 if (ibuf->float_buffer.data) {
106 }
107 else {
108 /* pass, bytes are expected to be straight */
109 }
110 }
111 }
112
113 colormanage_imbuf_make_linear(ibuf, new_colorspace);
114}
115
117 const size_t size,
118 const int flags,
119 const char *descr,
120 const char *filepath,
121 char r_colorspace[IM_MAX_SPACE])
122{
123 ImBuf *ibuf;
124 const ImFileType *type;
125
126 if (mem == nullptr) {
127 fprintf(stderr, "%s: nullptr pointer\n", __func__);
128 return nullptr;
129 }
130
131 ImFileColorSpace file_colorspace;
132
133 for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
134 if (type->load) {
135 ibuf = type->load(mem, size, flags, file_colorspace);
136 if (ibuf) {
137 imb_handle_colorspace_and_alpha(ibuf, flags, filepath, file_colorspace, r_colorspace);
138 return ibuf;
139 }
140 }
141 }
142
143 if ((flags & IB_test) == 0) {
144 fprintf(stderr, "%s: unknown file-format (%s)\n", __func__, descr);
145 }
146
147 return nullptr;
148}
149
151 const int flags,
152 const char *filepath,
153 char r_colorspace[IM_MAX_SPACE])
154{
155 ImBuf *ibuf;
156
157 if (file == -1) {
158 return nullptr;
159 }
160
162 BLI_mmap_file *mmap_file = BLI_mmap_open(file);
164 if (mmap_file == nullptr) {
165 fprintf(stderr, "%s: couldn't get mapping %s\n", __func__, filepath);
166 return nullptr;
167 }
168
169 const uchar *mem = static_cast<const uchar *>(BLI_mmap_get_pointer(mmap_file));
170 const size_t size = BLI_mmap_get_length(mmap_file);
171
172 /* There could be broken mmap due to network drives and other issues, handles exception the
173 * same way as in #BLI_mmap_read. Note that if the mmap becomes invalid mid-way through reading,
174 * external calls in #IMB_load_image_from_memory could leave unfreed memory, but this is the
175 * limitation of current exception handling method. Ref #139472. */
176#ifdef WIN32
177 __try
178 {
179#endif
180
181 ibuf = IMB_load_image_from_memory(mem, size, flags, filepath, filepath, r_colorspace);
182
183#ifdef WIN32
184 }
185 __except (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR ? EXCEPTION_EXECUTE_HANDLER :
186 EXCEPTION_CONTINUE_SEARCH)
187 {
188 ibuf = nullptr;
189 }
190#else
191 /* For unix, if mmap encounters an exception, BLI_mmap_file::io_error would be set. */
192 if (BLI_mmap_any_io_error(mmap_file)) {
193 ibuf = nullptr;
194 }
195#endif
196
198 BLI_mmap_free(mmap_file);
200
201 return ibuf;
202}
203
205 const int flags,
206 char r_colorspace[IM_MAX_SPACE])
207{
208 ImBuf *ibuf;
209 int file;
210
211 BLI_assert(!BLI_path_is_rel(filepath));
212
213 file = BLI_open(filepath, O_BINARY | O_RDONLY, 0);
214 if (file == -1) {
215 return nullptr;
216 }
217
218 ibuf = IMB_load_image_from_file_descriptor(file, flags, filepath, r_colorspace);
219
220 if (ibuf) {
221 STRNCPY(ibuf->filepath, filepath);
222 }
223
224 close(file);
225
226 return ibuf;
227}
228
229ImBuf *IMB_thumb_load_image(const char *filepath,
230 const size_t max_thumb_size,
231 char r_colorspace[IM_MAX_SPACE],
232 const IMBThumbLoadFlags load_flags)
233{
235 if (type == nullptr) {
236 return nullptr;
237 }
238
239 ImBuf *ibuf = nullptr;
240 int flags = IB_byte_data | IB_metadata;
241 /* Size of the original image. */
242 size_t width = 0;
243 size_t height = 0;
244
245 if (type->load_filepath_thumbnail) {
246 ImFileColorSpace file_colorspace;
247 ibuf = type->load_filepath_thumbnail(
248 filepath, flags, max_thumb_size, file_colorspace, &width, &height);
249 if (ibuf) {
250 imb_handle_colorspace_and_alpha(ibuf, flags, filepath, file_colorspace, r_colorspace);
251 }
252 }
253 else {
254 /* Skip images of other types if over 100MB. */
256 const size_t file_size = BLI_file_size(filepath);
257 if (file_size != size_t(-1) && file_size > THUMB_SIZE_MAX) {
258 return nullptr;
259 }
260 }
261 ibuf = IMB_load_image_from_filepath(filepath, flags, r_colorspace);
262 if (ibuf) {
263 width = ibuf->x;
264 height = ibuf->y;
265 }
266 }
267
268 if (ibuf) {
269 if (width > 0 && height > 0) {
270 /* Save dimensions of original image into the thumbnail metadata. */
271 char cwidth[40];
272 char cheight[40];
273 SNPRINTF(cwidth, "%zu", width);
274 SNPRINTF(cheight, "%zu", height);
276 IMB_metadata_set_field(ibuf->metadata, "Thumb::Image::Width", cwidth);
277 IMB_metadata_set_field(ibuf->metadata, "Thumb::Image::Height", cheight);
278 }
279 }
280
281 return ibuf;
282}
#define BLI_assert(a)
Definition BLI_assert.h:46
File and directory operations.
#define O_BINARY
size_t BLI_file_size(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:239
int BLI_open(const char *filepath, int oflag, int pmode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void * BLI_mmap_get_pointer(BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT
Definition BLI_mmap.cc:212
void BLI_mmap_free(BLI_mmap_file *file) ATTR_NONNULL(1)
Definition BLI_mmap.cc:227
bool BLI_mmap_any_io_error(const BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT
Definition BLI_mmap.cc:222
BLI_mmap_file * BLI_mmap_open(int fd) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_mmap.cc:133
size_t BLI_mmap_get_length(const BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT
Definition BLI_mmap.cc:217
bool BLI_path_is_rel(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:599
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
unsigned char uchar
Compatibility-like things for windows.
bool IMB_colormanagement_space_name_is_data(const char *name)
const char * IMB_colormanagement_space_from_filepath_rules(const char *filepath)
@ COLOR_ROLE_DEFAULT_FLOAT
@ COLOR_ROLE_DEFAULT_BYTE
const char * IMB_colormanagement_role_colorspace_name_get(int role)
void IMB_premultiply_alpha(ImBuf *ibuf)
Definition filter.cc:577
void IMB_rectfill_alpha(ImBuf *ibuf, float value)
Definition rectop.cc:1195
int IMB_test_image_type(const char *filepath)
void IMB_unpremultiply_alpha(ImBuf *ibuf)
Definition filter.cc:639
IMBThumbLoadFlags
Definition IMB_imbuf.hh:73
#define IM_MAX_SPACE
@ IB_alphamode_channel_packed
@ IB_alphamode_premul
@ IB_byte_data
@ IB_alphamode_ignore
@ IB_metadata
@ IB_alphamode_detect
@ IB_test
void IMB_metadata_set_field(IDProperty *metadata, const char *key, const char *value)
Definition metadata.cc:68
void IMB_metadata_ensure(IDProperty **metadata)
Definition metadata.cc:23
#define THUMB_SIZE_MAX
Definition IMB_thumbs.hh:38
void imb_mmap_lock()
Definition allocimbuf.cc:46
void imb_mmap_unlock()
Definition allocimbuf.cc:51
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
const ColorSpace * colormanage_colorspace_get_named(const char *name)
void colormanage_imbuf_make_linear(ImBuf *ibuf, const char *from_colorspace)
const ImFileType * IMB_file_type_from_ftype(int ftype)
Definition filetype.cc:222
const ImFileType IMB_FILE_TYPES[]
Definition filetype.cc:24
const ImFileType * IMB_FILE_TYPES_LAST
Definition filetype.cc:220
static void imb_handle_colorspace_and_alpha(ImBuf *ibuf, const int flags, const char *filepath, const ImFileColorSpace &file_colorspace, char r_colorspace[IM_MAX_SPACE])
Definition readimage.cc:34
ImBuf * IMB_load_image_from_file_descriptor(const int file, const int flags, const char *filepath, char r_colorspace[IM_MAX_SPACE])
Definition readimage.cc:150
ImBuf * IMB_load_image_from_memory(const uchar *mem, const size_t size, const int flags, const char *descr, const char *filepath, char r_colorspace[IM_MAX_SPACE])
Definition readimage.cc:116
ImBuf * IMB_thumb_load_image(const char *filepath, const size_t max_thumb_size, char r_colorspace[IM_MAX_SPACE], const IMBThumbLoadFlags load_flags)
Definition readimage.cc:229
ImBuf * IMB_load_image_from_filepath(const char *filepath, const int flags, char r_colorspace[IM_MAX_SPACE])
Definition readimage.cc:204
const ColorSpace * colorspace
char filepath[IMB_FILEPATH_SIZE]
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
IDProperty * metadata
char metadata_colorspace[IM_MAX_SPACE]
ImBuf *(* load)(const unsigned char *mem, size_t size, int flags, ImFileColorSpace &r_colorspace)
ImBuf *(* load_filepath_thumbnail)(const char *filepath, int flags, size_t max_thumb_size, ImFileColorSpace &r_colorspace, size_t *r_width, size_t *r_height)