2 SDL_image: An example image loading library for use with SDL
3 Copyright (C) 1997-2009 Sam Lantinga
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.
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.
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
23 #if !defined(__APPLE__) || defined(SDL_IMAGE_USE_COMMON_BACKEND)
25 /* This is a TIFF image file loading framework */
29 #include "SDL_image.h"
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);
45 #ifdef LOAD_TIF_DYNAMIC
48 if ( lib.loaded == 0 ) {
49 lib.handle = SDL_LoadObject(LOAD_TIF_DYNAMIC);
50 if ( lib.handle == NULL ) {
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);
62 SDL_LoadFunction(lib.handle, "TIFFClose");
63 if ( lib.TIFFClose == NULL ) {
64 SDL_UnloadObject(lib.handle);
68 (int (*)(TIFF*, ttag_t, ...))
69 SDL_LoadFunction(lib.handle, "TIFFGetField");
70 if ( lib.TIFFGetField == NULL ) {
71 SDL_UnloadObject(lib.handle);
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);
81 lib.TIFFSetErrorHandler =
82 (TIFFErrorHandler (*)(TIFFErrorHandler))
83 SDL_LoadFunction(lib.handle, "TIFFSetErrorHandler");
84 if ( lib.TIFFSetErrorHandler == NULL ) {
85 SDL_UnloadObject(lib.handle);
95 if ( lib.loaded == 0 ) {
98 if ( lib.loaded == 1 ) {
99 SDL_UnloadObject(lib.handle);
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;
119 if ( lib.loaded == 0 ) {
122 if ( lib.loaded == 1 ) {
126 #endif /* LOAD_TIF_DYNAMIC */
129 * These are the thunking routine to use the SDL_RWops* routines from
130 * libtiff's internals.
133 static tsize_t tiff_read(thandle_t fd, tdata_t buf, tsize_t size)
135 return SDL_RWread((SDL_RWops*)fd, buf, 1, size);
138 static toff_t tiff_seek(thandle_t fd, toff_t offset, int origin)
140 return SDL_RWseek((SDL_RWops*)fd, offset, origin);
143 static tsize_t tiff_write(thandle_t fd, tdata_t buf, tsize_t size)
145 return SDL_RWwrite((SDL_RWops*)fd, buf, 1, size);
148 static int tiff_close(thandle_t fd)
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.
157 static int tiff_map(thandle_t fd, tdata_t* pbase, toff_t* psize)
162 static void tiff_unmap(thandle_t fd, tdata_t base, toff_t size)
167 static toff_t tiff_size(thandle_t fd)
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);
179 int IMG_isTIF(SDL_RWops* src)
187 start = SDL_RWtell(src);
189 if ( SDL_RWread(src, magic, 1, sizeof(magic)) == sizeof(magic) ) {
190 if ( (magic[0] == 'I' &&
197 magic[3] == 0x2a) ) {
201 SDL_RWseek(src, start, RW_SEEK_SET);
205 SDL_Surface* IMG_LoadTIF_RW(SDL_RWops* src)
209 SDL_Surface* surface = NULL;
210 Uint32 img_width, img_height;
211 Uint32 Rmask, Gmask, Bmask, Amask;
216 /* The error message has been set in SDL_RWFromFile */
219 start = SDL_RWtell(src);
221 if ( !IMG_Init(IMG_INIT_TIF) ) {
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);
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);
239 surface = SDL_AllocSurface(SDL_SWSURFACE, img_width, img_height, 32,
240 Rmask, Gmask, Bmask, Amask);
244 if(!lib.TIFFReadRGBAImage(tiff, img_width, img_height, surface->pixels, 0))
247 /* libtiff loads the image upside-down, flip it back */
248 half = img_height / 2;
249 for(y = 0; y < half; y++)
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++)
266 SDL_RWseek(src, start, RW_SEEK_SET);
268 SDL_FreeSurface(surface);
277 IMG_SetError("TIFF images are not supported");
285 /* See if an image is contained in a data source */
286 int IMG_isTIF(SDL_RWops *src)
291 /* Load a TIFF type image from an SDL datasource */
292 SDL_Surface *IMG_LoadTIF_RW(SDL_RWops *src)
297 #endif /* LOAD_TIF */
299 #endif /* !defined(__APPLE__) || defined(SDL_IMAGE_USE_COMMON_BACKEND) */