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