]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libsdl-image/contrib/IMG_tif.c
update
[l4.git] / l4 / pkg / libsdl-image / contrib / IMG_tif.c
1 /*
2     SDL_image:  An example image loading library for use with SDL
3     Copyright (C) 1997-2009 Sam Lantinga
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22
23 #if !defined(__APPLE__) || defined(SDL_IMAGE_USE_COMMON_BACKEND)
24
25 /* This is a TIFF image file loading framework */
26
27 #include <stdio.h>
28
29 #include "SDL_image.h"
30
31 #ifdef LOAD_TIF
32
33 #include <tiffio.h>
34
35 static struct {
36         int loaded;
37         void *handle;
38         TIFF* (*TIFFClientOpen)(const char*, const char*, thandle_t, TIFFReadWriteProc, TIFFReadWriteProc, TIFFSeekProc, TIFFCloseProc, TIFFSizeProc, TIFFMapFileProc, TIFFUnmapFileProc);
39         void (*TIFFClose)(TIFF*);
40         int (*TIFFGetField)(TIFF*, ttag_t, ...);
41         int (*TIFFReadRGBAImage)(TIFF*, uint32, uint32, uint32*, int);
42         TIFFErrorHandler (*TIFFSetErrorHandler)(TIFFErrorHandler);
43 } lib;
44
45 #ifdef LOAD_TIF_DYNAMIC
46 int IMG_InitTIF()
47 {
48         if ( lib.loaded == 0 ) {
49                 lib.handle = SDL_LoadObject(LOAD_TIF_DYNAMIC);
50                 if ( lib.handle == NULL ) {
51                         return -1;
52                 }
53                 lib.TIFFClientOpen =
54                         (TIFF* (*)(const char*, const char*, thandle_t, TIFFReadWriteProc, TIFFReadWriteProc, TIFFSeekProc, TIFFCloseProc, TIFFSizeProc, TIFFMapFileProc, TIFFUnmapFileProc))
55                         SDL_LoadFunction(lib.handle, "TIFFClientOpen");
56                 if ( lib.TIFFClientOpen == NULL ) {
57                         SDL_UnloadObject(lib.handle);
58                         return -1;
59                 }
60                 lib.TIFFClose =
61                         (void (*)(TIFF*))
62                         SDL_LoadFunction(lib.handle, "TIFFClose");
63                 if ( lib.TIFFClose == NULL ) {
64                         SDL_UnloadObject(lib.handle);
65                         return -1;
66                 }
67                 lib.TIFFGetField =
68                         (int (*)(TIFF*, ttag_t, ...))
69                         SDL_LoadFunction(lib.handle, "TIFFGetField");
70                 if ( lib.TIFFGetField == NULL ) {
71                         SDL_UnloadObject(lib.handle);
72                         return -1;
73                 }
74                 lib.TIFFReadRGBAImage =
75                         (int (*)(TIFF*, uint32, uint32, uint32*, int))
76                         SDL_LoadFunction(lib.handle, "TIFFReadRGBAImage");
77                 if ( lib.TIFFReadRGBAImage == NULL ) {
78                         SDL_UnloadObject(lib.handle);
79                         return -1;
80                 }
81                 lib.TIFFSetErrorHandler =
82                         (TIFFErrorHandler (*)(TIFFErrorHandler))
83                         SDL_LoadFunction(lib.handle, "TIFFSetErrorHandler");
84                 if ( lib.TIFFSetErrorHandler == NULL ) {
85                         SDL_UnloadObject(lib.handle);
86                         return -1;
87                 }
88         }
89         ++lib.loaded;
90
91         return 0;
92 }
93 void IMG_QuitTIF()
94 {
95         if ( lib.loaded == 0 ) {
96                 return;
97         }
98         if ( lib.loaded == 1 ) {
99                 SDL_UnloadObject(lib.handle);
100         }
101         --lib.loaded;
102 }
103 #else
104 int IMG_InitTIF()
105 {
106         if ( lib.loaded == 0 ) {
107                 lib.TIFFClientOpen = TIFFClientOpen;
108                 lib.TIFFClose = TIFFClose;
109                 lib.TIFFGetField = TIFFGetField;
110                 lib.TIFFReadRGBAImage = TIFFReadRGBAImage;
111                 lib.TIFFSetErrorHandler = TIFFSetErrorHandler;
112         }
113         ++lib.loaded;
114
115         return 0;
116 }
117 void IMG_QuitTIF()
118 {
119         if ( lib.loaded == 0 ) {
120                 return;
121         }
122         if ( lib.loaded == 1 ) {
123         }
124         --lib.loaded;
125 }
126 #endif /* LOAD_TIF_DYNAMIC */
127
128 /*
129  * These are the thunking routine to use the SDL_RWops* routines from
130  * libtiff's internals.
131 */
132
133 static tsize_t tiff_read(thandle_t fd, tdata_t buf, tsize_t size)
134 {
135         return SDL_RWread((SDL_RWops*)fd, buf, 1, size);
136 }
137
138 static toff_t tiff_seek(thandle_t fd, toff_t offset, int origin)
139 {
140         return SDL_RWseek((SDL_RWops*)fd, offset, origin);
141 }
142
143 static tsize_t tiff_write(thandle_t fd, tdata_t buf, tsize_t size)
144 {
145         return SDL_RWwrite((SDL_RWops*)fd, buf, 1, size);
146 }
147
148 static int tiff_close(thandle_t fd)
149 {
150         /*
151          * We don't want libtiff closing our SDL_RWops*, but if it's not given
152          * a routine to try, and if the image isn't a TIFF, it'll segfault.
153          */
154         return 0;
155 }
156
157 static int tiff_map(thandle_t fd, tdata_t* pbase, toff_t* psize)
158 {
159         return (0);
160 }
161
162 static void tiff_unmap(thandle_t fd, tdata_t base, toff_t size)
163 {
164         return;
165 }
166
167 static toff_t tiff_size(thandle_t fd)
168 {
169         Uint32 save_pos;
170         toff_t size;
171
172         save_pos = SDL_RWtell((SDL_RWops*)fd);
173         SDL_RWseek((SDL_RWops*)fd, 0, RW_SEEK_END);
174         size = SDL_RWtell((SDL_RWops*)fd);
175         SDL_RWseek((SDL_RWops*)fd, save_pos, RW_SEEK_SET);
176         return size;
177 }
178
179 int IMG_isTIF(SDL_RWops* src)
180 {
181         int start;
182         int is_TIF;
183         Uint8 magic[4];
184
185         if ( !src )
186                 return 0;
187         start = SDL_RWtell(src);
188         is_TIF = 0;
189         if ( SDL_RWread(src, magic, 1, sizeof(magic)) == sizeof(magic) ) {
190                 if ( (magic[0] == 'I' &&
191                       magic[1] == 'I' &&
192                       magic[2] == 0x2a &&
193                       magic[3] == 0x00) ||
194                      (magic[0] == 'M' &&
195                       magic[1] == 'M' &&
196                       magic[2] == 0x00 &&
197                       magic[3] == 0x2a) ) {
198                         is_TIF = 1;
199                 }
200         }
201         SDL_RWseek(src, start, RW_SEEK_SET);
202         return(is_TIF);
203 }
204
205 SDL_Surface* IMG_LoadTIF_RW(SDL_RWops* src)
206 {
207         int start;
208         TIFF* tiff;
209         SDL_Surface* surface = NULL;
210         Uint32 img_width, img_height;
211         Uint32 Rmask, Gmask, Bmask, Amask;
212         Uint32 x, y;
213         Uint32 half;
214
215         if ( !src ) {
216                 /* The error message has been set in SDL_RWFromFile */
217                 return NULL;
218         }
219         start = SDL_RWtell(src);
220
221         if ( !IMG_Init(IMG_INIT_TIF) ) {
222                 return NULL;
223         }
224
225         /* turn off memory mapped access with the m flag */
226         tiff = lib.TIFFClientOpen("SDL_image", "rm", (thandle_t)src, 
227                 tiff_read, tiff_write, tiff_seek, tiff_close, tiff_size, tiff_map, tiff_unmap);
228         if(!tiff)
229                 goto error;
230
231         /* Retrieve the dimensions of the image from the TIFF tags */
232         lib.TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &img_width);
233         lib.TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &img_height);
234
235         Rmask = 0x000000FF;
236         Gmask = 0x0000FF00;
237         Bmask = 0x00FF0000;
238         Amask = 0xFF000000;
239         surface = SDL_AllocSurface(SDL_SWSURFACE, img_width, img_height, 32,
240                 Rmask, Gmask, Bmask, Amask);
241         if(!surface)
242                 goto error;
243         
244         if(!lib.TIFFReadRGBAImage(tiff, img_width, img_height, surface->pixels, 0))
245                 goto error;
246
247         /* libtiff loads the image upside-down, flip it back */
248         half = img_height / 2;
249         for(y = 0; y < half; y++)
250         {
251                 Uint32 *top = (Uint32 *)surface->pixels + y * surface->pitch/4;
252                 Uint32 *bot = (Uint32 *)surface->pixels
253                               + (img_height - y - 1) * surface->pitch/4;
254                 for(x = 0; x < img_width; x++)
255                 {
256                         Uint32 tmp = top[x];
257                         top[x] = bot[x];
258                         bot[x] = tmp;
259                 }
260         }
261         lib.TIFFClose(tiff);
262         
263         return surface;
264
265 error:
266         SDL_RWseek(src, start, RW_SEEK_SET);
267         if ( surface ) {
268                 SDL_FreeSurface(surface);
269         }
270         return NULL;
271 }
272
273 #else
274
275 int IMG_InitTIF()
276 {
277         IMG_SetError("TIFF images are not supported");
278         return(-1);
279 }
280
281 void IMG_QuitTIF()
282 {
283 }
284
285 /* See if an image is contained in a data source */
286 int IMG_isTIF(SDL_RWops *src)
287 {
288         return(0);
289 }
290
291 /* Load a TIFF type image from an SDL datasource */
292 SDL_Surface *IMG_LoadTIF_RW(SDL_RWops *src)
293 {
294         return(NULL);
295 }
296
297 #endif /* LOAD_TIF */
298
299 #endif /* !defined(__APPLE__) || defined(SDL_IMAGE_USE_COMMON_BACKEND) */