2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): none yet.
25 * ***** END GPL LICENSE BLOCK *****
30 /** \file blender/imbuf/intern/readimage.c
38 # include <sys/types.h>
39 # include "mmap_win.h"
46 #include "BLI_utildefines.h"
47 #include "BLI_string.h"
48 #include "BLI_path_util.h"
49 #include "BLI_fileops.h"
52 #include "IMB_imbuf_types.h"
53 #include "IMB_imbuf.h"
54 #include "IMB_filetype.h"
56 #include "IMB_colormanagement.h"
57 #include "IMB_colormanagement_intern.h"
59 static void imb_handle_alpha(ImBuf *ibuf, int flags, char colorspace[IM_MAX_SPACE], char effective_colorspace[IM_MAX_SPACE])
65 /* byte buffer is never internally converted to some standard space,
66 * store pointer to it's color space descriptor instead
68 ibuf->rect_colorspace = colormanage_colorspace_get_named(effective_colorspace);
71 BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
74 if (flags & IB_alphamode_detect)
75 alpha_flags = ibuf->flags & IB_alphamode_premul;
77 alpha_flags = flags & IB_alphamode_premul;
79 if (flags & IB_ignore_alpha) {
80 IMB_rectfill_alpha(ibuf, 1.0f);
83 if (alpha_flags & IB_alphamode_premul) {
85 IMB_unpremultiply_alpha(ibuf);
88 /* pass, floats are expected to be premul */
92 if (ibuf->rect_float) {
93 IMB_premultiply_alpha(ibuf);
96 /* pass, bytes are expected to be straight */
101 /* OCIO_TODO: in some cases it's faster to do threaded conversion,
102 * but how to distinguish such cases */
103 colormanage_imbuf_make_linear(ibuf, effective_colorspace);
106 ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
110 char effective_colorspace[IM_MAX_SPACE] = "";
113 fprintf(stderr, "%s: NULL pointer\n", __func__);
118 BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
120 for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
122 ibuf = type->load(mem, size, flags, effective_colorspace);
124 imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
130 if ((flags & IB_test) == 0)
131 fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
136 static ImBuf *IMB_ibImageFromFile(const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
140 char effective_colorspace[IM_MAX_SPACE] = "";
143 BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
145 for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
146 if (type->load_filepath) {
147 ibuf = type->load_filepath(filepath, flags, effective_colorspace);
149 imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
155 if ((flags & IB_test) == 0)
156 fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
161 static bool imb_is_filepath_format(const char *filepath)
163 /* return true if this is one of the formats that can't be loaded from memory */
164 return BLI_testextensie_array(filepath, imb_ext_image_filepath_only);
167 ImBuf *IMB_loadifffile(int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
173 if (file == -1) return NULL;
175 if (imb_is_filepath_format(filepath))
176 return IMB_ibImageFromFile(filepath, flags, colorspace, descr);
178 size = BLI_file_descriptor_size(file);
180 mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
181 if (mem == (unsigned char *) -1) {
182 fprintf(stderr, "%s: couldn't get mapping %s\n", __func__, descr);
186 ibuf = IMB_ibImageFromMemory(mem, size, flags, colorspace, descr);
188 if (munmap(mem, size))
189 fprintf(stderr, "%s: couldn't unmap file %s\n", __func__, descr);
194 static void imb_cache_filename(char *filename, const char *name, int flags)
196 /* read .tx instead if it exists and is not older */
197 if (flags & IB_tilecache) {
198 BLI_strncpy(filename, name, IB_FILENAME_SIZE);
199 if (!BLI_replace_extension(filename, IB_FILENAME_SIZE, ".tx"))
202 if (BLI_file_older(name, filename))
206 BLI_strncpy(filename, name, IB_FILENAME_SIZE);
209 ImBuf *IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
213 char filepath_tx[IB_FILENAME_SIZE];
215 imb_cache_filename(filepath_tx, filepath, flags);
217 file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
221 ibuf = IMB_loadifffile(file, filepath, flags, colorspace, filepath_tx);
224 BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
225 BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
226 for (a = 1; a < ibuf->miptot; a++)
227 BLI_strncpy(ibuf->mipmap[a - 1]->cachename, filepath_tx, sizeof(ibuf->cachename));
228 if (flags & IB_fields) IMB_de_interlace(ibuf);
236 ImBuf *IMB_testiffname(const char *filepath, int flags)
240 char filepath_tx[IB_FILENAME_SIZE];
241 char colorspace[IM_MAX_SPACE] = "\0";
243 imb_cache_filename(filepath_tx, filepath, flags);
245 file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
249 ibuf = IMB_loadifffile(file, filepath, flags | IB_test | IB_multilayer, colorspace, filepath_tx);
252 BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
253 BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
261 static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int *rect)
267 if (file == -1) return;
269 size = BLI_file_descriptor_size(file);
271 mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
272 if (mem == (unsigned char *) -1) {
273 fprintf(stderr, "Couldn't get memory mapping for %s\n", ibuf->cachename);
277 for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++)
278 if (type->load_tile && type->ftype(type, ibuf))
279 type->load_tile(ibuf, mem, size, tx, ty, rect);
281 if (munmap(mem, size))
282 fprintf(stderr, "Couldn't unmap memory for %s.\n", ibuf->cachename);
285 void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
289 file = BLI_open(ibuf->cachename, O_BINARY | O_RDONLY, 0);
293 imb_loadtilefile(ibuf, file, tx, ty, rect);