Fix msvc 2013 compiler errors after the ingenious cleanup in 4ca67869cc7a.
[blender.git] / source / blender / imbuf / intern / readimage.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
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.
8  *
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.
13  *
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.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  * allocimbuf.c
27  *
28  */
29
30 /** \file blender/imbuf/intern/readimage.c
31  *  \ingroup imbuf
32  */
33
34
35 #ifdef _WIN32
36 #  include <io.h>
37 #  include <stddef.h>
38 #  include <sys/types.h>
39 #  include "mmap_win.h"
40 #  define open _open
41 #  define read _read
42 #  define close _close
43 #endif
44
45 #include <stdlib.h>
46 #include "BLI_utildefines.h"
47 #include "BLI_string.h"
48 #include "BLI_path_util.h"
49 #include "BLI_fileops.h"
50
51 #include "imbuf.h"
52 #include "IMB_imbuf_types.h"
53 #include "IMB_imbuf.h"
54 #include "IMB_filetype.h"
55
56 #include "IMB_colormanagement.h"
57 #include "IMB_colormanagement_intern.h"
58
59 static void imb_handle_alpha(ImBuf *ibuf, int flags, char colorspace[IM_MAX_SPACE], char effective_colorspace[IM_MAX_SPACE])
60 {
61         int alpha_flags;
62
63         if (colorspace) {
64                 if (ibuf->rect) {
65                         /* byte buffer is never internally converted to some standard space,
66                          * store pointer to it's color space descriptor instead
67                          */
68                         ibuf->rect_colorspace = colormanage_colorspace_get_named(effective_colorspace);
69                 }
70
71                 BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
72         }
73
74         if (flags & IB_alphamode_detect)
75                 alpha_flags = ibuf->flags & IB_alphamode_premul;
76         else
77                 alpha_flags = flags & IB_alphamode_premul;
78
79         if (flags & IB_ignore_alpha) {
80                 IMB_rectfill_alpha(ibuf, 1.0f);
81         }
82         else {
83                 if (alpha_flags & IB_alphamode_premul) {
84                         if (ibuf->rect) {
85                                 IMB_unpremultiply_alpha(ibuf);
86                         }
87                         else {
88                                 /* pass, floats are expected to be premul */
89                         }
90                 }
91                 else {
92                         if (ibuf->rect_float) {
93                                 IMB_premultiply_alpha(ibuf);
94                         }
95                         else {
96                                 /* pass, bytes are expected to be straight */
97                         }
98                 }
99         }
100
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);
104 }
105
106 ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
107 {
108         ImBuf *ibuf;
109         ImFileType *type;
110         char effective_colorspace[IM_MAX_SPACE] = "";
111
112         if (mem == NULL) {
113                 fprintf(stderr, "%s: NULL pointer\n", __func__);
114                 return NULL;
115         }
116
117         if (colorspace)
118                 BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
119
120         for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
121                 if (type->load) {
122                         ibuf = type->load(mem, size, flags, effective_colorspace);
123                         if (ibuf) {
124                                 imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
125                                 return ibuf;
126                         }
127                 }
128         }
129
130         if ((flags & IB_test) == 0)
131                 fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
132
133         return NULL;
134 }
135
136 static ImBuf *IMB_ibImageFromFile(const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
137 {
138         ImBuf *ibuf;
139         ImFileType *type;
140         char effective_colorspace[IM_MAX_SPACE] = "";
141
142         if (colorspace)
143                 BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
144
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);
148                         if (ibuf) {
149                                 imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
150                                 return ibuf;
151                         }
152                 }
153         }
154
155         if ((flags & IB_test) == 0)
156                 fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
157
158         return NULL;
159 }
160
161 static bool imb_is_filepath_format(const char *filepath)
162 {
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);
165 }
166
167 ImBuf *IMB_loadifffile(int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
168 {
169         ImBuf *ibuf;
170         unsigned char *mem;
171         size_t size;
172
173         if (file == -1) return NULL;
174
175         if (imb_is_filepath_format(filepath))
176                 return IMB_ibImageFromFile(filepath, flags, colorspace, descr);
177
178         size = BLI_file_descriptor_size(file);
179
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);
183                 return NULL;
184         }
185
186         ibuf = IMB_ibImageFromMemory(mem, size, flags, colorspace, descr);
187
188         if (munmap(mem, size))
189                 fprintf(stderr, "%s: couldn't unmap file %s\n", __func__, descr);
190
191         return ibuf;
192 }
193
194 static void imb_cache_filename(char *filename, const char *name, int flags)
195 {
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"))
200                         return;
201
202                 if (BLI_file_older(name, filename))
203                         return;
204         }
205
206         BLI_strncpy(filename, name, IB_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[IB_FILENAME_SIZE];
214
215         imb_cache_filename(filepath_tx, filepath, flags);
216
217         file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
218         if (file == -1)
219                 return NULL;
220
221         ibuf = IMB_loadifffile(file, filepath, flags, colorspace, filepath_tx);
222
223         if (ibuf) {
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);
229         }
230
231         close(file);
232
233         return ibuf;
234 }
235
236 ImBuf *IMB_testiffname(const char *filepath, int flags)
237 {
238         ImBuf *ibuf;
239         int file;
240         char filepath_tx[IB_FILENAME_SIZE];
241         char colorspace[IM_MAX_SPACE] = "\0";
242
243         imb_cache_filename(filepath_tx, filepath, flags);
244
245         file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
246         if (file == -1)
247                 return NULL;
248
249         ibuf = IMB_loadifffile(file, filepath, flags | IB_test | IB_multilayer, colorspace, filepath_tx);
250
251         if (ibuf) {
252                 BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
253                 BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
254         }
255
256         close(file);
257
258         return ibuf;
259 }
260
261 static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int *rect)
262 {
263         ImFileType *type;
264         unsigned char *mem;
265         size_t size;
266
267         if (file == -1) return;
268
269         size = BLI_file_descriptor_size(file);
270
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);
274                 return;
275         }
276
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);
280
281         if (munmap(mem, size))
282                 fprintf(stderr, "Couldn't unmap memory for %s.\n", ibuf->cachename);
283 }
284
285 void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
286 {
287         int file;
288
289         file = BLI_open(ibuf->cachename, O_BINARY | O_RDONLY, 0);
290         if (file == -1)
291                 return;
292
293         imb_loadtilefile(ibuf, file, tx, ty, rect);
294
295         close(file);
296 }