patch [#34103] use booleans for extensions testing.
[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 ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
60 {
61         ImBuf *ibuf;
62         ImFileType *type;
63         char effective_colorspace[IM_MAX_SPACE] = "";
64
65         if (mem == NULL) {
66                 fprintf(stderr, "%s: NULL pointer\n", __func__);
67                 return NULL;
68         }
69
70         if (colorspace)
71                 BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
72
73         for (type = IMB_FILE_TYPES; type->is_a; type++) {
74                 if (type->load) {
75                         ibuf = type->load(mem, size, flags, effective_colorspace);
76                         if (ibuf) {
77                                 int alpha_flags;
78
79                                 if (colorspace) {
80                                         if (ibuf->rect) {
81                                                 /* byte buffer is never internally converted to some standard space,
82                                                  * store pointer to it's color space descriptor instead
83                                                  */
84                                                 ibuf->rect_colorspace = colormanage_colorspace_get_named(effective_colorspace);
85                                         }
86
87                                         BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
88                                 }
89
90                                 if (flags & IB_alphamode_detect)
91                                         alpha_flags = ibuf->flags & IB_alphamode_premul;
92                                 else
93                                         alpha_flags = flags & IB_alphamode_premul;
94
95                                 if (flags & IB_ignore_alpha) {
96                                         IMB_rectfill_alpha(ibuf, 1.0f);
97                                 }
98                                 else {
99                                         if (alpha_flags & IB_alphamode_premul) {
100                                                 if (ibuf->rect) {
101                                                         IMB_unpremultiply_alpha(ibuf);
102                                                 }
103                                                 else {
104                                                         /* pass, floats are expected to be premul */
105                                                 }
106                                         }
107                                         else {
108                                                 if (ibuf->rect_float) {
109                                                         IMB_premultiply_alpha(ibuf);
110                                                 }
111                                                 else {
112                                                         /* pass, bytes are expected to be straight */
113                                                 }
114                                         }
115                                 }
116
117                                 /* OCIO_TODO: in some cases it's faster to do threaded conversion,
118                                  *            but how to distinguish such cases */
119                                 colormanage_imbuf_make_linear(ibuf, effective_colorspace);
120
121                                 return ibuf;
122                         }
123                 }
124         }
125
126         if ((flags & IB_test) == 0)
127                 fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
128
129         return NULL;
130 }
131
132 ImBuf *IMB_loadifffile(int file, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
133 {
134         ImBuf *ibuf;
135         unsigned char *mem;
136         size_t size;
137
138         if (file == -1) return NULL;
139
140         size = BLI_file_descriptor_size(file);
141
142         mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
143         if (mem == (unsigned char *) -1) {
144                 fprintf(stderr, "%s: couldn't get mapping %s\n", __func__, descr);
145                 return NULL;
146         }
147
148         ibuf = IMB_ibImageFromMemory(mem, size, flags, colorspace, descr);
149
150         if (munmap(mem, size))
151                 fprintf(stderr, "%s: couldn't unmap file %s\n", __func__, descr);
152
153         return ibuf;
154 }
155
156 static void imb_cache_filename(char *filename, const char *name, int flags)
157 {
158         /* read .tx instead if it exists and is not older */
159         if (flags & IB_tilecache) {
160                 BLI_strncpy(filename, name, IB_FILENAME_SIZE);
161                 if (!BLI_replace_extension(filename, IB_FILENAME_SIZE, ".tx"))
162                         return;
163
164                 if (BLI_file_older(name, filename))
165                         return;
166         }
167
168         BLI_strncpy(filename, name, IB_FILENAME_SIZE);
169 }
170
171 ImBuf *IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
172 {
173         ImBuf *ibuf;
174         int file, a;
175         char filepath_tx[IB_FILENAME_SIZE];
176
177         imb_cache_filename(filepath_tx, filepath, flags);
178
179         file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
180         if (file < 0) return NULL;
181
182         ibuf = IMB_loadifffile(file, flags, colorspace, filepath_tx);
183
184         if (ibuf) {
185                 BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
186                 BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
187                 for (a = 1; a < ibuf->miptot; a++)
188                         BLI_strncpy(ibuf->mipmap[a - 1]->cachename, filepath_tx, sizeof(ibuf->cachename));
189                 if (flags & IB_fields) IMB_de_interlace(ibuf);
190         }
191
192         close(file);
193
194         return ibuf;
195 }
196
197 ImBuf *IMB_testiffname(const char *filepath, int flags)
198 {
199         ImBuf *ibuf;
200         int file;
201         char filepath_tx[IB_FILENAME_SIZE];
202         char colorspace[IM_MAX_SPACE] = "\0";
203
204         imb_cache_filename(filepath_tx, filepath, flags);
205
206         file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
207         if (file < 0) return NULL;
208
209         ibuf = IMB_loadifffile(file, flags | IB_test | IB_multilayer, colorspace, filepath_tx);
210
211         if (ibuf) {
212                 BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
213                 BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
214         }
215
216         close(file);
217
218         return ibuf;
219 }
220
221 static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int *rect)
222 {
223         ImFileType *type;
224         unsigned char *mem;
225         size_t size;
226
227         if (file == -1) return;
228
229         size = BLI_file_descriptor_size(file);
230
231         mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
232         if (mem == (unsigned char *) -1) {
233                 fprintf(stderr, "Couldn't get memory mapping for %s\n", ibuf->cachename);
234                 return;
235         }
236
237         for (type = IMB_FILE_TYPES; type->is_a; type++)
238                 if (type->load_tile && type->ftype(type, ibuf))
239                         type->load_tile(ibuf, mem, size, tx, ty, rect);
240
241         if (munmap(mem, size))
242                 fprintf(stderr, "Couldn't unmap memory for %s.\n", ibuf->cachename);
243 }
244
245 void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
246 {
247         int file;
248
249         file = BLI_open(ibuf->cachename, O_BINARY | O_RDONLY, 0);
250         if (file < 0) return;
251
252         imb_loadtilefile(ibuf, file, tx, ty, rect);
253
254         close(file);
255 }