Color Management, Stage 2: Switch color pipeline to use OpenColorIO
[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_string.h"
47 #include "BLI_path_util.h"
48 #include "BLI_fileops.h"
49
50 #include "BLI_utildefines.h"
51
52 #include "imbuf.h"
53 #include "IMB_imbuf_types.h"
54 #include "IMB_imbuf.h"
55 #include "IMB_filetype.h"
56
57 #include "IMB_colormanagement.h"
58 #include "IMB_colormanagement_intern.h"
59
60 ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
61 {
62         ImBuf *ibuf;
63         ImFileType *type;
64         char effective_colorspace[IM_MAX_SPACE] = "";
65
66         if (mem == NULL) {
67                 fprintf(stderr, "%s: NULL pointer\n", __func__);
68                 return NULL;
69         }
70
71         if (colorspace)
72                 BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
73
74         for (type = IMB_FILE_TYPES; type->is_a; type++) {
75                 if (type->load) {
76                         ibuf = type->load(mem, size, flags, effective_colorspace);
77                         if (ibuf) {
78                                 if (colorspace) {
79                                         if (ibuf->rect) {
80                                                 /* byte buffer is never internally converted to some standard space,
81                                                  * store pointer to it's color space descriptor instead
82                                                  */
83                                                 ibuf->rect_colorspace = colormanage_colorspace_get_named(effective_colorspace);
84                                         }
85
86                                         BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
87                                 }
88
89                                 /* OCIO_TODO: in some cases it's faster to do threaded conversion,
90                                  *            but how to distinguish such cases */
91                                 colormanage_imbuf_make_linear(ibuf, effective_colorspace);
92
93                                 if (flags & IB_premul) {
94                                         IMB_premultiply_alpha(ibuf);
95                                         ibuf->flags |= IB_premul;
96                                 }
97
98                                 return ibuf;
99                         }
100                 }
101         }
102
103         fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
104
105         return NULL;
106 }
107
108 ImBuf *IMB_loadifffile(int file, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
109 {
110         ImBuf *ibuf;
111         unsigned char *mem;
112         size_t size;
113
114         if (file == -1) return NULL;
115
116         size = BLI_file_descriptor_size(file);
117
118         mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
119         if (mem == (unsigned char *) -1) {
120                 fprintf(stderr, "%s: couldn't get mapping %s\n", __func__, descr);
121                 return NULL;
122         }
123
124         ibuf = IMB_ibImageFromMemory(mem, size, flags, colorspace, descr);
125
126         if (munmap(mem, size))
127                 fprintf(stderr, "%s: couldn't unmap file %s\n", __func__, descr);
128
129         return ibuf;
130 }
131
132 static void imb_cache_filename(char *filename, const char *name, int flags)
133 {
134         /* read .tx instead if it exists and is not older */
135         if (flags & IB_tilecache) {
136                 BLI_strncpy(filename, name, IB_FILENAME_SIZE);
137                 if (!BLI_replace_extension(filename, IB_FILENAME_SIZE, ".tx"))
138                         return;
139
140                 if (BLI_file_older(name, filename))
141                         return;
142         }
143
144         BLI_strncpy(filename, name, IB_FILENAME_SIZE);
145 }
146
147 ImBuf *IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
148 {
149         ImBuf *ibuf;
150         int file, a;
151         char filepath_tx[IB_FILENAME_SIZE];
152
153         imb_cache_filename(filepath_tx, filepath, flags);
154
155         file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
156         if (file < 0) return NULL;
157
158         ibuf = IMB_loadifffile(file, flags, colorspace, filepath_tx);
159
160         if (ibuf) {
161                 BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
162                 BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
163                 for (a = 1; a < ibuf->miptot; a++)
164                         BLI_strncpy(ibuf->mipmap[a - 1]->cachename, filepath_tx, sizeof(ibuf->cachename));
165                 if (flags & IB_fields) IMB_de_interlace(ibuf);
166         }
167
168         close(file);
169
170         return ibuf;
171 }
172
173 ImBuf *IMB_testiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
174 {
175         ImBuf *ibuf;
176         int file;
177         char filepath_tx[IB_FILENAME_SIZE];
178
179         imb_cache_filename(filepath_tx, filepath, flags);
180
181         file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
182         if (file < 0) return NULL;
183
184         ibuf = IMB_loadifffile(file, flags | IB_test | IB_multilayer, colorspace, filepath_tx);
185
186         if (ibuf) {
187                 BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
188                 BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
189         }
190
191         close(file);
192
193         return ibuf;
194 }
195
196 static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int *rect)
197 {
198         ImFileType *type;
199         unsigned char *mem;
200         size_t size;
201
202         if (file == -1) return;
203
204         size = BLI_file_descriptor_size(file);
205
206         mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
207         if (mem == (unsigned char *) -1) {
208                 fprintf(stderr, "Couldn't get memory mapping for %s\n", ibuf->cachename);
209                 return;
210         }
211
212         for (type = IMB_FILE_TYPES; type->is_a; type++)
213                 if (type->load_tile && type->ftype(type, ibuf))
214                         type->load_tile(ibuf, mem, size, tx, ty, rect);
215
216         if (munmap(mem, size))
217                 fprintf(stderr, "Couldn't unmap memory for %s.\n", ibuf->cachename);
218 }
219
220 void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
221 {
222         int file;
223
224         file = BLI_open(ibuf->cachename, O_BINARY | O_RDONLY, 0);
225         if (file < 0) return;
226
227         imb_loadtilefile(ibuf, file, tx, ty, rect);
228
229         close(file);
230 }
231