IMG_tif.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 22 Oct 2017 14:40:31 -0700
changeset 537 8959a43f5590
parent 528 7f9e88f4b45e
child 575 36e9e2255178
permissions -rwxr-xr-x
Fixed warnings building 64-bit with Visual Studio
     1 /*
     2   SDL_image:  An example image loading library for use with SDL
     3   Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 
    22 #if !(defined(__APPLE__) || defined(SDL_IMAGE_USE_WIC_BACKEND)) || defined(SDL_IMAGE_USE_COMMON_BACKEND)
    23 
    24 /* This is a TIFF image file loading framework */
    25 
    26 #include "SDL_image.h"
    27 
    28 #ifdef LOAD_TIF
    29 
    30 #include <tiffio.h>
    31 
    32 static struct {
    33     int loaded;
    34     void *handle;
    35     TIFF* (*TIFFClientOpen)(const char*, const char*, thandle_t, TIFFReadWriteProc, TIFFReadWriteProc, TIFFSeekProc, TIFFCloseProc, TIFFSizeProc, TIFFMapFileProc, TIFFUnmapFileProc);
    36     void (*TIFFClose)(TIFF*);
    37     int (*TIFFGetField)(TIFF*, ttag_t, ...);
    38     int (*TIFFReadRGBAImageOriented)(TIFF*, uint32, uint32, uint32*, int, int);
    39     TIFFErrorHandler (*TIFFSetErrorHandler)(TIFFErrorHandler);
    40 } lib;
    41 
    42 #ifdef LOAD_TIF_DYNAMIC
    43 #define FUNCTION_LOADER(FUNC, SIG) \
    44     lib.FUNC = (SIG) SDL_LoadFunction(lib.handle, #FUNC); \
    45     if (lib.FUNC == NULL) { SDL_UnloadObject(lib.handle); return -1; }
    46 #else
    47 #define FUNCTION_LOADER(FUNC, SIG) \
    48     lib.FUNC = FUNC;
    49 #endif
    50 
    51 int IMG_InitTIF()
    52 {
    53     if ( lib.loaded == 0 ) {
    54 #ifdef LOAD_TIF_DYNAMIC
    55         lib.handle = SDL_LoadObject(LOAD_TIF_DYNAMIC);
    56         if ( lib.handle == NULL ) {
    57             return -1;
    58         }
    59 #endif
    60         FUNCTION_LOADER(TIFFClientOpen, TIFF * (*)(const char*, const char*, thandle_t, TIFFReadWriteProc, TIFFReadWriteProc, TIFFSeekProc, TIFFCloseProc, TIFFSizeProc, TIFFMapFileProc, TIFFUnmapFileProc))
    61         FUNCTION_LOADER(TIFFClose, void (*)(TIFF*))
    62         FUNCTION_LOADER(TIFFGetField, int (*)(TIFF*, ttag_t, ...))
    63         FUNCTION_LOADER(TIFFReadRGBAImageOriented, int (*)(TIFF*, uint32, uint32, uint32*, int, int))
    64         FUNCTION_LOADER(TIFFSetErrorHandler, TIFFErrorHandler (*)(TIFFErrorHandler))
    65     }
    66     ++lib.loaded;
    67 
    68     return 0;
    69 }
    70 void IMG_QuitTIF()
    71 {
    72     if ( lib.loaded == 0 ) {
    73         return;
    74     }
    75     if ( lib.loaded == 1 ) {
    76 #ifdef LOAD_TIF_DYNAMIC
    77         SDL_UnloadObject(lib.handle);
    78 #endif
    79     }
    80     --lib.loaded;
    81 }
    82 
    83 /*
    84  * These are the thunking routine to use the SDL_RWops* routines from
    85  * libtiff's internals.
    86 */
    87 
    88 static tsize_t tiff_read(thandle_t fd, tdata_t buf, tsize_t size)
    89 {
    90     return (tsize_t)SDL_RWread((SDL_RWops*)fd, buf, 1, size);
    91 }
    92 
    93 static toff_t tiff_seek(thandle_t fd, toff_t offset, int origin)
    94 {
    95     return SDL_RWseek((SDL_RWops*)fd, offset, origin);
    96 }
    97 
    98 static tsize_t tiff_write(thandle_t fd, tdata_t buf, tsize_t size)
    99 {
   100     return (tsize_t)SDL_RWwrite((SDL_RWops*)fd, buf, 1, size);
   101 }
   102 
   103 static int tiff_close(thandle_t fd)
   104 {
   105     /*
   106      * We don't want libtiff closing our SDL_RWops*, but if it's not given
   107          * a routine to try, and if the image isn't a TIFF, it'll segfault.
   108      */
   109     return 0;
   110 }
   111 
   112 static int tiff_map(thandle_t fd, tdata_t* pbase, toff_t* psize)
   113 {
   114     return (0);
   115 }
   116 
   117 static void tiff_unmap(thandle_t fd, tdata_t base, toff_t size)
   118 {
   119     return;
   120 }
   121 
   122 static toff_t tiff_size(thandle_t fd)
   123 {
   124     Sint64 save_pos;
   125     toff_t size;
   126 
   127     save_pos = SDL_RWtell((SDL_RWops*)fd);
   128     SDL_RWseek((SDL_RWops*)fd, 0, RW_SEEK_END);
   129     size = SDL_RWtell((SDL_RWops*)fd);
   130     SDL_RWseek((SDL_RWops*)fd, save_pos, RW_SEEK_SET);
   131     return size;
   132 }
   133 
   134 int IMG_isTIF(SDL_RWops* src)
   135 {
   136     Sint64 start;
   137     int is_TIF;
   138     Uint8 magic[4];
   139 
   140     if ( !src )
   141         return 0;
   142     start = SDL_RWtell(src);
   143     is_TIF = 0;
   144     if ( SDL_RWread(src, magic, 1, sizeof(magic)) == sizeof(magic) ) {
   145         if ( (magic[0] == 'I' &&
   146                       magic[1] == 'I' &&
   147               magic[2] == 0x2a &&
   148                       magic[3] == 0x00) ||
   149              (magic[0] == 'M' &&
   150                       magic[1] == 'M' &&
   151               magic[2] == 0x00 &&
   152                       magic[3] == 0x2a) ) {
   153             is_TIF = 1;
   154         }
   155     }
   156     SDL_RWseek(src, start, RW_SEEK_SET);
   157     return(is_TIF);
   158 }
   159 
   160 SDL_Surface* IMG_LoadTIF_RW(SDL_RWops* src)
   161 {
   162     Sint64 start;
   163     TIFF* tiff = NULL;
   164     SDL_Surface* surface = NULL;
   165     Uint32 img_width, img_height;
   166     Uint32 Rmask, Gmask, Bmask, Amask;
   167 
   168     if ( !src ) {
   169         /* The error message has been set in SDL_RWFromFile */
   170         return NULL;
   171     }
   172     start = SDL_RWtell(src);
   173 
   174     if ( (IMG_Init(IMG_INIT_TIF) & IMG_INIT_TIF) == 0 ) {
   175         return NULL;
   176     }
   177 
   178     /* turn off memory mapped access with the m flag */
   179     tiff = lib.TIFFClientOpen("SDL_image", "rm", (thandle_t)src,
   180         tiff_read, tiff_write, tiff_seek, tiff_close, tiff_size, tiff_map, tiff_unmap);
   181     if(!tiff)
   182         goto error;
   183 
   184     /* Retrieve the dimensions of the image from the TIFF tags */
   185     lib.TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &img_width);
   186     lib.TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &img_height);
   187 
   188     Rmask = 0x000000FF;
   189     Gmask = 0x0000FF00;
   190     Bmask = 0x00FF0000;
   191     Amask = 0xFF000000;
   192     surface = SDL_CreateRGBSurface(SDL_SWSURFACE, img_width, img_height, 32,
   193         Rmask, Gmask, Bmask, Amask);
   194     if(!surface)
   195         goto error;
   196 
   197     if(!lib.TIFFReadRGBAImageOriented(tiff, img_width, img_height, (uint32 *)surface->pixels, ORIENTATION_TOPLEFT, 0))
   198         goto error;
   199 
   200     lib.TIFFClose(tiff);
   201 
   202     return surface;
   203 
   204 error:
   205     SDL_RWseek(src, start, RW_SEEK_SET);
   206     if (surface) {
   207         SDL_FreeSurface(surface);
   208     }
   209     if (tiff) {
   210         lib.TIFFClose(tiff);
   211     }
   212     return NULL;
   213 }
   214 
   215 #else
   216 
   217 int IMG_InitTIF()
   218 {
   219     IMG_SetError("TIFF images are not supported");
   220     return(-1);
   221 }
   222 
   223 void IMG_QuitTIF()
   224 {
   225 }
   226 
   227 /* See if an image is contained in a data source */
   228 int IMG_isTIF(SDL_RWops *src)
   229 {
   230     return(0);
   231 }
   232 
   233 /* Load a TIFF type image from an SDL datasource */
   234 SDL_Surface *IMG_LoadTIF_RW(SDL_RWops *src)
   235 {
   236     return(NULL);
   237 }
   238 
   239 #endif /* LOAD_TIF */
   240 
   241 #endif /* !defined(__APPLE__) || defined(SDL_IMAGE_USE_COMMON_BACKEND) */