style cleanup: follow style guide for formatting of if/for/while loops, and else...
[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 "BLI_blenlib.h"
46 #include "BLI_utildefines.h"
47
48 #include "imbuf.h"
49 #include "IMB_imbuf_types.h"
50 #include "IMB_imbuf.h"
51 #include "IMB_filetype.h"
52
53 ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, const char *descr)
54 {
55         ImBuf *ibuf;
56         ImFileType *type;
57
58         if (mem == NULL) {
59                 fprintf(stderr, "%s: NULL pointer\n", __func__);
60                 return NULL;
61         }
62
63         for (type=IMB_FILE_TYPES; type->is_a; type++) {
64                 if (type->load) {
65                         ibuf= type->load(mem, size, flags);
66                         if (ibuf) {
67                                 if (flags & IB_premul) {
68                                         IMB_premultiply_alpha(ibuf);
69                                         ibuf->flags |= IB_premul;
70                                 }
71
72                                 return ibuf;
73                         }
74                 }
75         }
76
77         fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
78
79         return NULL;
80 }
81
82 ImBuf *IMB_loadifffile(int file, int flags, const char *descr)
83 {
84         ImBuf *ibuf;
85         unsigned char *mem;
86         size_t size;
87
88         if (file == -1) return NULL;
89
90         size= BLI_file_descriptor_size(file);
91
92         mem= mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
93         if (mem==(unsigned char*)-1) {
94                 fprintf(stderr, "%s: couldn't get mapping %s\n", __func__, descr);
95                 return NULL;
96         }
97
98         ibuf= IMB_ibImageFromMemory(mem, size, flags, descr);
99
100         if (munmap(mem, size))
101                 fprintf(stderr, "%s: couldn't unmap file %s\n", __func__, descr);
102
103         return ibuf;
104 }
105
106 static void imb_cache_filename(char *filename, const char *name, int flags)
107 {
108         /* read .tx instead if it exists and is not older */
109         if (flags & IB_tilecache) {
110                 BLI_strncpy(filename, name, IB_FILENAME_SIZE);
111                 if (!BLI_replace_extension(filename, IB_FILENAME_SIZE, ".tx"))
112                         return;
113
114                 if (BLI_file_older(name, filename))
115                         return;
116         }
117
118         BLI_strncpy(filename, name, IB_FILENAME_SIZE);
119 }
120
121 ImBuf *IMB_loadiffname(const char *filepath, int flags)
122 {
123         ImBuf *ibuf;
124         int file, a;
125         char filepath_tx[IB_FILENAME_SIZE];
126
127         imb_cache_filename(filepath_tx, filepath, flags);
128
129         file = BLI_open(filepath_tx, O_BINARY|O_RDONLY, 0);
130         if (file < 0) return NULL;
131
132         ibuf= IMB_loadifffile(file, flags, filepath_tx);
133
134         if (ibuf) {
135                 BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
136                 BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
137                 for (a=1; a<ibuf->miptot; a++)
138                         BLI_strncpy(ibuf->mipmap[a-1]->cachename, filepath_tx, sizeof(ibuf->cachename));
139                 if (flags & IB_fields) IMB_de_interlace(ibuf);
140         }
141
142         close(file);
143
144         return ibuf;
145 }
146
147 ImBuf *IMB_testiffname(const char *filepath, int flags)
148 {
149         ImBuf *ibuf;
150         int file;
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|IB_test|IB_multilayer, 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         }
164
165         close(file);
166
167         return ibuf;
168 }
169
170 static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int *rect)
171 {
172         ImFileType *type;
173         unsigned char *mem;
174         size_t size;
175
176         if (file == -1) return;
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, "Couldn't get memory mapping for %s\n", ibuf->cachename);
183                 return;
184         }
185
186         for (type=IMB_FILE_TYPES; type->is_a; type++)
187                 if (type->load_tile && type->ftype(type, ibuf))
188                         type->load_tile(ibuf, mem, size, tx, ty, rect);
189
190         if (munmap(mem, size))
191                 fprintf(stderr, "Couldn't unmap memory for %s.\n", ibuf->cachename);
192 }
193
194 void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
195 {
196         int file;
197
198         file = BLI_open(ibuf->cachename, O_BINARY|O_RDONLY, 0);
199         if (file < 0) return;
200
201         imb_loadtilefile(ibuf, file, tx, ty, rect);
202
203         close(file);
204 }
205