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