Fixed defined __sparc to also check for __sparc__ (thanks to Ferris)
[blender.git] / source / blender / imbuf / intern / readimage.c
1 /**
2  *
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  * allocimbuf.c
31  *
32  * $Id$
33  */
34
35 #include "BLI_blenlib.h"
36
37 #include "imbuf.h"
38 #include "imbuf_patch.h"
39 #include "IMB_imbuf_types.h"
40 #include "IMB_imbuf.h"
41
42 #include "IMB_amiga.h"
43 #include "IMB_iris.h"
44 #include "IMB_targa.h"
45 #include "IMB_png.h"
46 #include "IMB_hamx.h"
47 #include "IMB_jpeg.h"
48 #include "IMB_bmp.h"
49
50 /* actually hard coded endianness */
51 #define GET_BIG_LONG(x) (((uchar *) (x))[0] << 24 | ((uchar *) (x))[1] << 16 | ((uchar *) (x))[2] << 8 | ((uchar *) (x))[3])
52 #define GET_LITTLE_LONG(x) (((uchar *) (x))[3] << 24 | ((uchar *) (x))[2] << 16 | ((uchar *) (x))[1] << 8 | ((uchar *) (x))[0])
53 #define SWAP_L(x) (((x << 24) & 0xff000000) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff))
54 #define SWAP_S(x) (((x << 8) & 0xff00) | ((x >> 8) & 0xff))
55
56 /* more endianness... should move to a separate file... */
57 #if defined(__sgi) || defined (__sparc) || defined(__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
58 #define GET_ID GET_BIG_LONG
59 #define LITTLE_LONG SWAP_LONG
60 #else
61 #define GET_ID GET_LITTLE_LONG
62 #define LITTLE_LONG ENDIAN_NOP
63 #endif
64
65 /* from misc_util: flip the bytes from x  */
66 #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1])
67
68 /* this one is only def-ed once, strangely... */
69 #define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0])
70
71 int IB_verbose = TRUE;
72
73 ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags) {
74         int len;
75         struct ImBuf *ibuf;
76
77         if (mem == NULL) {
78                 printf("Error in ibImageFromMemory: NULL pointer\n");
79         } else {
80                 if ((GS(mem) == IMAGIC) || (GSS(mem) == IMAGIC)){
81                         return (imb_loadiris((uchar *) mem, flags));
82                 } else if ((BIG_LONG(mem[0]) & 0xfffffff0) == 0xffd8ffe0) {
83                         return (imb_ibJpegImageFromMemory((uchar *)mem, size, flags));
84                 }
85                 
86                 if (GET_ID(mem) == CAT){
87                         mem += 3;
88                         size -= 4;
89                         while (size > 0){
90                                 if (GET_ID(mem) == FORM){
91                                         len = ((GET_BIG_LONG(mem+1) + 1) & ~1) + 8;
92                                         if ((GET_ID(mem+2) == ILBM) || (GET_ID(mem+2) == ANIM)) break;
93                                         mem = (int *)((uchar *)mem +len);
94                                         size -= len;
95                                 } else return(0);
96                         }
97                 }
98         
99                 if (size > 0){
100                         if (GET_ID(mem) == FORM){
101                                 if (GET_ID(mem+2) == ILBM){
102                                         return (imb_loadamiga(mem, flags));
103                                 } else if (GET_ID(mem+5) == ILBM){                      /* animaties */
104                                         return (imb_loadamiga(mem+3, flags));
105                                 } else if (GET_ID(mem+2) == ANIM){
106                                         return (imb_loadanim(mem, flags));
107                                 }
108                         }
109                 }
110         
111                 ibuf = imb_png_decode((uchar *)mem, size, flags);
112                 if (ibuf) return(ibuf);
113
114                 ibuf = imb_bmp_decode((uchar *)mem, size, flags);
115                 if (ibuf) return(ibuf);
116
117                 ibuf = imb_loadtarga((uchar *)mem, flags);
118                 if (ibuf) return(ibuf);
119         
120                 if (IB_verbose) fprintf(stderr, "Unknown fileformat\n");
121         }
122         
123         return (0);
124 }
125
126
127 struct ImBuf *IMB_loadiffmem(int *mem, int flags) {
128         int len,maxlen;
129         struct ImBuf *ibuf;
130
131         // IMB_loadiffmem shouldn't be used anymore in new development
132         // it's still here to be backwards compatible...
133
134         maxlen= (GET_BIG_LONG(mem+1) + 1) & ~1;
135
136         if (GET_ID(mem) == CAT){
137                 mem += 3;
138                 maxlen -= 4;
139                 while(maxlen > 0){
140                         if (GET_ID(mem) == FORM){
141                                 len = ((GET_BIG_LONG(mem+1) + 1) & ~1) + 8;
142                                 if ((GET_ID(mem+2) == ILBM) || (GET_ID(mem+2) == ANIM)) break;
143                                 mem = (int *)((uchar *)mem +len);
144                                 maxlen -= len;
145                         } else return(0);
146                 }
147         }
148
149         if (maxlen > 0){
150                 if (GET_ID(mem) == FORM){
151                         if (GET_ID(mem+2) == ILBM){
152                                 return (imb_loadamiga(mem, flags));
153                         } else if (GET_ID(mem+5) == ILBM){                      /* animaties */
154                                 return (imb_loadamiga(mem+3, flags));
155                         } else if (GET_ID(mem+2) == ANIM){
156                                 return (imb_loadanim(mem, flags));
157                         }
158                 } else if ((GS(mem) == IMAGIC) || (GSS(mem) == IMAGIC)){
159                         return (imb_loadiris((uchar *) mem,flags));
160                 } else if ((BIG_LONG(mem[0]) & 0xfffffff0) == 0xffd8ffe0) {
161                         return (0);
162                 }
163         }
164
165         ibuf = imb_loadtarga((uchar *) mem,flags);
166         if (ibuf) return(ibuf);
167
168         if (IB_verbose) fprintf(stderr,"Unknown fileformat\n");
169         return (0);
170 }
171
172 struct ImBuf *IMB_loadifffile(int file, int flags) {
173         struct ImBuf *ibuf;
174         int size, *mem;
175
176         if (file == -1) return (0);
177
178         size = BLI_filesize(file);
179
180 #if defined(AMIGA) || defined(__BeOS) || defined(WIN32)
181         mem= (int *)malloc(size);
182         if (mem==0) {
183                 printf("Out of mem\n");
184                 return (0);
185         }
186
187         if (read(file, mem, size)!=size){
188                 printf("Read Error\n");
189                 free(mem);
190                 return (0);
191         }
192
193         ibuf = IMB_ibImageFromMemory(mem, size, flags);
194         free(mem);
195
196         /* for jpeg read */
197         lseek(file, 0L, SEEK_SET);
198
199 #else
200         mem= (int *)mmap(0,size,PROT_READ,MAP_SHARED,file,0);
201         if (mem==(int *)-1){
202                 printf("Couldn't get mapping\n");
203                 return (0);
204         }
205
206         ibuf = IMB_ibImageFromMemory(mem, size, flags);
207
208         if (munmap( (void *) mem, size)){
209                 printf("Couldn't unmap file.\n");
210         }
211 #endif
212         return(ibuf);
213 }
214
215
216 struct ImBuf *IMB_loadiffname(char *naam, int flags) {
217         int file;
218         struct ImBuf *ibuf;
219         int buf[1];
220
221         file = open(naam, O_BINARY|O_RDONLY);
222
223         if (file == -1) return (0);
224
225         ibuf= IMB_loadifffile(file, flags);
226
227         if (ibuf == 0) {
228                 if (read(file, buf, 4) != 4) buf[0] = 0;
229                 if ((BIG_LONG(buf[0]) & 0xfffffff0) == 0xffd8ffe0)
230                         ibuf = imb_ibJpegImageFromFilename(naam, flags);                        
231         }
232
233         if (ibuf) {
234                 strncpy(ibuf->name, naam, sizeof(ibuf->name));
235                 if (flags & IB_fields) IMB_de_interlace(ibuf);
236         }
237         close(file);
238         return(ibuf);
239 }
240
241 struct ImBuf *IMB_testiffname(char *naam,int flags) {
242         int file;
243         struct ImBuf *ibuf;
244
245         flags |= IB_test;
246         file = open(naam,O_BINARY|O_RDONLY);
247
248         if (file<=0) return (0);
249
250         ibuf=IMB_loadifffile(file,flags);
251         if (ibuf) {
252                 strncpy(ibuf->name, naam, sizeof(ibuf->name));
253         }
254         close(file);
255         return(ibuf);
256 }