Blender V5.0
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 <io.h>
11# include <stddef.h>
12# include <sys/types.h>
13#endif
14
15#include <cstdlib>
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 "BLI_string_utf8.h"
22
23#include "CLG_log.h"
24
25#include "IMB_allocimbuf.hh"
26#include "IMB_filetype.hh"
27#include "IMB_imbuf.hh"
28#include "IMB_imbuf_types.hh"
29#include "IMB_metadata.hh"
30#include "IMB_thumbs.hh"
31#include "imbuf.hh"
32
35
36static CLG_LogRef LOG = {"image.read"};
37
39 const int flags,
40 const char *filepath,
41 const ImFileColorSpace &file_colorspace,
42 char r_colorspace[IM_MAX_SPACE])
43{
44 /* Determine file colorspace. */
45 char new_colorspace[IM_MAX_SPACE];
46
47 if (r_colorspace && r_colorspace[0]) {
48 /* Existing configured colorspace has priority. */
49 STRNCPY_UTF8(new_colorspace, r_colorspace);
50 }
51 else if (file_colorspace.metadata_colorspace[0] &&
53 {
54 /* Use colorspace from file metadata if provided. */
55 STRNCPY_UTF8(new_colorspace, file_colorspace.metadata_colorspace);
56 }
57 else {
58 /* The color-space from the file-path (not a file-path). */
59 const char *filepath_colorspace = (filepath) ?
61 nullptr;
62 if (filepath_colorspace) {
63 /* Use colorspace from OpenColorIO file rules. */
64 STRNCPY_UTF8(new_colorspace, filepath_colorspace);
65 }
66 else {
67 /* Use float colorspace if the image may contain HDR colors, byte otherwise. */
68 const char *role_colorspace = IMB_colormanagement_role_colorspace_name_get(
70 STRNCPY_UTF8(new_colorspace, role_colorspace);
71 }
72 }
73
74 if (r_colorspace) {
75 BLI_strncpy_utf8(r_colorspace, new_colorspace, IM_MAX_SPACE);
76 }
77
78 if (r_colorspace) {
79 if (ibuf->byte_buffer.data != nullptr && ibuf->float_buffer.data == nullptr) {
80 /* byte buffer is never internally converted to some standard space,
81 * store pointer to its color space descriptor instead
82 */
84 }
85 }
86
87 bool is_data = (r_colorspace && IMB_colormanagement_space_name_is_data(new_colorspace));
88 int alpha_flags = (flags & IB_alphamode_detect) ? ibuf->flags : flags;
89
90 if (is_data || (flags & IB_alphamode_channel_packed)) {
91 /* Don't touch alpha. */
93 }
94 else if (flags & IB_alphamode_ignore) {
95 /* Make opaque. */
96 IMB_rectfill_alpha(ibuf, 1.0f);
98 }
99 else {
100 if (alpha_flags & IB_alphamode_premul) {
101 if (ibuf->byte_buffer.data) {
103 }
104 else {
105 /* pass, floats are expected to be premul */
106 }
107 }
108 else {
109 if (ibuf->float_buffer.data) {
111 }
112 else {
113 /* pass, bytes are expected to be straight */
114 }
115 }
116 }
117
119}
120
122 const size_t size,
123 const int flags,
124 const char *descr,
125 const char *filepath,
126 char r_colorspace[IM_MAX_SPACE])
127{
128 ImBuf *ibuf;
129 const ImFileType *type;
130
131 if (mem == nullptr) {
132 CLOG_ERROR(&LOG, "%s: nullptr pointer", __func__);
133 return nullptr;
134 }
135
136 ImFileColorSpace file_colorspace;
137
138 for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
139 if (type->load) {
140 ibuf = type->load(mem, size, flags, file_colorspace);
141 if (ibuf) {
142 imb_handle_colorspace_and_alpha(ibuf, flags, filepath, file_colorspace, r_colorspace);
143 return ibuf;
144 }
145 }
146 }
147
148 if ((flags & IB_test) == 0) {
149 CLOG_ERROR(&LOG, "%s: unknown file-format (%s)", __func__, descr);
150 }
151
152 return nullptr;
153}
154
156 const int flags,
157 const char *filepath,
158 char r_colorspace[IM_MAX_SPACE])
159{
160 ImBuf *ibuf = nullptr;
161
162 if (file == -1) {
163 return nullptr;
164 }
165
166 BLI_mmap_file *mmap_file = BLI_mmap_open(file);
167 if (mmap_file == nullptr) {
168 CLOG_ERROR(&LOG, "%s: couldn't get mapping for \"%s\"", __func__, filepath);
169 return nullptr;
170 }
171
172 const uchar *mem = static_cast<const uchar *>(BLI_mmap_get_pointer(mmap_file));
173 const size_t size = BLI_mmap_get_length(mmap_file);
174
175 ibuf = IMB_load_image_from_memory(mem, size, flags, filepath, filepath, r_colorspace);
176
177 /* If we got an image but mmap encountered an error,
178 * free the image and return nullptr as it could be corrupted. */
179 if (ibuf != nullptr && BLI_mmap_any_io_error(mmap_file)) {
180 IMB_freeImBuf(ibuf);
181 ibuf = nullptr;
182 }
183
184 BLI_mmap_free(mmap_file);
185
186 return ibuf;
187}
188
190 const int flags,
191 char r_colorspace[IM_MAX_SPACE])
192{
193 ImBuf *ibuf;
194 int file;
195
196 BLI_assert(!BLI_path_is_rel(filepath));
197
198 file = BLI_open(filepath, O_BINARY | O_RDONLY, 0);
199 if (file == -1) {
200 return nullptr;
201 }
202
203 ibuf = IMB_load_image_from_file_descriptor(file, flags, filepath, r_colorspace);
204
205 if (ibuf) {
206 STRNCPY(ibuf->filepath, filepath);
207 }
208
209 close(file);
210
211 return ibuf;
212}
213
214ImBuf *IMB_thumb_load_image(const char *filepath,
215 const size_t max_thumb_size,
216 char r_colorspace[IM_MAX_SPACE],
217 const IMBThumbLoadFlags load_flags)
218{
220 if (type == nullptr) {
221 return nullptr;
222 }
223
224 ImBuf *ibuf = nullptr;
225 int flags = IB_byte_data | IB_metadata;
226 /* Size of the original image. */
227 size_t width = 0;
228 size_t height = 0;
229
230 if (type->load_filepath_thumbnail) {
231 ImFileColorSpace file_colorspace;
232 ibuf = type->load_filepath_thumbnail(
233 filepath, flags, max_thumb_size, file_colorspace, &width, &height);
234 if (ibuf) {
235 imb_handle_colorspace_and_alpha(ibuf, flags, filepath, file_colorspace, r_colorspace);
236 }
237 }
238 else {
239 /* Skip images of other types if over 100MB. */
241 const size_t file_size = BLI_file_size(filepath);
242 if (file_size != size_t(-1) && file_size > THUMB_SIZE_MAX) {
243 return nullptr;
244 }
245 }
246 ibuf = IMB_load_image_from_filepath(filepath, flags, r_colorspace);
247 if (ibuf) {
248 width = ibuf->x;
249 height = ibuf->y;
250 }
251 }
252
253 if (ibuf) {
254 if (width > 0 && height > 0) {
255 /* Save dimensions of original image into the thumbnail metadata. */
256 char cwidth[40];
257 char cheight[40];
258 SNPRINTF_UTF8(cwidth, "%zu", width);
259 SNPRINTF_UTF8(cheight, "%zu", height);
261 IMB_metadata_set_field(ibuf->metadata, "Thumb::Image::Width", cwidth);
262 IMB_metadata_set_field(ibuf->metadata, "Thumb::Image::Height", cheight);
263 }
264 }
265
266 return ibuf;
267}
#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:226
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:472
void BLI_mmap_free(BLI_mmap_file *file) ATTR_NONNULL(1)
Definition BLI_mmap.cc:487
bool BLI_mmap_any_io_error(const BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT
Definition BLI_mmap.cc:482
BLI_mmap_file * BLI_mmap_open(int fd) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_mmap.cc:367
size_t BLI_mmap_get_length(const BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT
Definition BLI_mmap.cc:477
bool BLI_path_is_rel(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
#define SNPRINTF_UTF8(dst, format,...)
char * BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
unsigned char uchar
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:188
@ COLOR_ROLE_DEFAULT_FLOAT
@ COLOR_ROLE_DEFAULT_BYTE
bool IMB_colormanagement_space_name_is_data(const char *name)
const char * IMB_colormanagement_space_from_filepath_rules(const char *filepath)
const char * IMB_colormanagement_role_colorspace_name_get(int role)
void IMB_premultiply_alpha(ImBuf *ibuf)
Definition filter.cc:381
void IMB_rectfill_alpha(ImBuf *ibuf, float value)
Definition rectop.cc:1122
int IMB_test_image_type(const char *filepath)
void IMB_unpremultiply_alpha(ImBuf *ibuf)
Definition filter.cc:443
void IMB_freeImBuf(ImBuf *ibuf)
IMBThumbLoadFlags
Definition IMB_imbuf.hh:68
#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
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 ColorManagedFileOutput output)
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
#define LOG(level)
Definition log.h:97
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:38
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:155
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:121
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:214
ImBuf * IMB_load_image_from_filepath(const char *filepath, const int flags, char r_colorspace[IM_MAX_SPACE])
Definition readimage.cc:189
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)