IMG.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 01 Jan 2017 18:50:51 -0800
changeset 496 6332f9425dcc
parent 486 7bb8af91e887
child 503 1e32e1f475a9
permissions -rw-r--r--
Updated copyright for 2017
     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 /* A simple library to load images of various formats as SDL surfaces */
    23 
    24 #include <stdio.h>
    25 #include <string.h>
    26 #include <ctype.h>
    27 
    28 #include "SDL_image.h"
    29 
    30 #define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0]))
    31 
    32 /* Table of image detection and loading functions */
    33 static struct {
    34     char *type;
    35     int (SDLCALL *is)(SDL_RWops *src);
    36     SDL_Surface *(SDLCALL *load)(SDL_RWops *src);
    37 } supported[] = {
    38     /* keep magicless formats first */
    39     { "TGA", NULL,      IMG_LoadTGA_RW },
    40     { "CUR", IMG_isCUR, IMG_LoadCUR_RW },
    41     { "ICO", IMG_isICO, IMG_LoadICO_RW },
    42     { "BMP", IMG_isBMP, IMG_LoadBMP_RW },
    43     { "GIF", IMG_isGIF, IMG_LoadGIF_RW },
    44     { "JPG", IMG_isJPG, IMG_LoadJPG_RW },
    45     { "LBM", IMG_isLBM, IMG_LoadLBM_RW },
    46     { "PCX", IMG_isPCX, IMG_LoadPCX_RW },
    47     { "PNG", IMG_isPNG, IMG_LoadPNG_RW },
    48     { "PNM", IMG_isPNM, IMG_LoadPNM_RW }, /* P[BGP]M share code */
    49     { "TIF", IMG_isTIF, IMG_LoadTIF_RW },
    50     { "XCF", IMG_isXCF, IMG_LoadXCF_RW },
    51     { "XPM", IMG_isXPM, IMG_LoadXPM_RW },
    52     { "XV",  IMG_isXV,  IMG_LoadXV_RW  },
    53     { "WEBP", IMG_isWEBP, IMG_LoadWEBP_RW },
    54 };
    55 
    56 const SDL_version *IMG_Linked_Version(void)
    57 {
    58     static SDL_version linked_version;
    59     SDL_IMAGE_VERSION(&linked_version);
    60     return(&linked_version);
    61 }
    62 
    63 extern int IMG_InitJPG();
    64 extern void IMG_QuitJPG();
    65 extern int IMG_InitPNG();
    66 extern void IMG_QuitPNG();
    67 extern int IMG_InitTIF();
    68 extern void IMG_QuitTIF();
    69 
    70 extern int IMG_InitWEBP();
    71 extern void IMG_QuitWEBP();
    72 
    73 static int initialized = 0;
    74 
    75 int IMG_Init(int flags)
    76 {
    77     int result = 0;
    78 
    79     /* Passing 0 returns the currently initialized loaders */
    80     if (!flags) {
    81         return initialized;
    82     }
    83 
    84     if (flags & IMG_INIT_JPG) {
    85         if ((initialized & IMG_INIT_JPG) || IMG_InitJPG() == 0) {
    86             result |= IMG_INIT_JPG;
    87         }
    88     }
    89     if (flags & IMG_INIT_PNG) {
    90         if ((initialized & IMG_INIT_PNG) || IMG_InitPNG() == 0) {
    91             result |= IMG_INIT_PNG;
    92         }
    93     }
    94     if (flags & IMG_INIT_TIF) {
    95         if ((initialized & IMG_INIT_TIF) || IMG_InitTIF() == 0) {
    96             result |= IMG_INIT_TIF;
    97         }
    98     }
    99     if (flags & IMG_INIT_WEBP) {
   100         if ((initialized & IMG_INIT_WEBP) || IMG_InitWEBP() == 0) {
   101             result |= IMG_INIT_WEBP;
   102         }
   103     }
   104     initialized |= result;
   105 
   106     return result;
   107 }
   108 
   109 void IMG_Quit()
   110 {
   111     if (initialized & IMG_INIT_JPG) {
   112         IMG_QuitJPG();
   113     }
   114     if (initialized & IMG_INIT_PNG) {
   115         IMG_QuitPNG();
   116     }
   117     if (initialized & IMG_INIT_TIF) {
   118         IMG_QuitTIF();
   119     }
   120     if (initialized & IMG_INIT_WEBP) {
   121         IMG_QuitWEBP();
   122     }
   123     initialized = 0;
   124 }
   125 
   126 #if !defined(__APPLE__) || defined(SDL_IMAGE_USE_COMMON_BACKEND)
   127 /* Load an image from a file */
   128 SDL_Surface *IMG_Load(const char *file)
   129 {
   130     SDL_RWops *src = SDL_RWFromFile(file, "rb");
   131     const char *ext = SDL_strrchr(file, '.');
   132     if(ext) {
   133         ext++;
   134     }
   135     if(!src) {
   136         /* The error message has been set in SDL_RWFromFile */
   137         return NULL;
   138     }
   139     return IMG_LoadTyped_RW(src, 1, ext);
   140 }
   141 #endif
   142 
   143 /* Load an image from an SDL datasource (for compatibility) */
   144 SDL_Surface *IMG_Load_RW(SDL_RWops *src, int freesrc)
   145 {
   146     return IMG_LoadTyped_RW(src, freesrc, NULL);
   147 }
   148 
   149 /* Portable case-insensitive string compare function */
   150 static int IMG_string_equals(const char *str1, const char *str2)
   151 {
   152     while ( *str1 && *str2 ) {
   153         if ( SDL_toupper((unsigned char)*str1) !=
   154              SDL_toupper((unsigned char)*str2) )
   155             break;
   156         ++str1;
   157         ++str2;
   158     }
   159     return (!*str1 && !*str2);
   160 }
   161 
   162 /* Load an image from an SDL datasource, optionally specifying the type */
   163 SDL_Surface *IMG_LoadTyped_RW(SDL_RWops *src, int freesrc, const char *type)
   164 {
   165     int i;
   166     SDL_Surface *image;
   167 
   168     /* Make sure there is something to do.. */
   169     if ( src == NULL ) {
   170         IMG_SetError("Passed a NULL data source");
   171         return(NULL);
   172     }
   173 
   174     /* See whether or not this data source can handle seeking */
   175     if ( SDL_RWseek(src, 0, RW_SEEK_CUR) < 0 ) {
   176         IMG_SetError("Can't seek in this data source");
   177         if(freesrc)
   178             SDL_RWclose(src);
   179         return(NULL);
   180     }
   181 
   182     /* Detect the type of image being loaded */
   183     image = NULL;
   184     for ( i=0; i < ARRAYSIZE(supported); ++i ) {
   185         if(supported[i].is) {
   186             if(!supported[i].is(src))
   187                 continue;
   188         } else {
   189             /* magicless format */
   190             if(!type
   191                || !IMG_string_equals(type, supported[i].type))
   192                 continue;
   193         }
   194 #ifdef DEBUG_IMGLIB
   195         fprintf(stderr, "IMGLIB: Loading image as %s\n",
   196             supported[i].type);
   197 #endif
   198         image = supported[i].load(src);
   199         if(freesrc)
   200             SDL_RWclose(src);
   201         return image;
   202     }
   203 
   204     if ( freesrc ) {
   205         SDL_RWclose(src);
   206     }
   207     IMG_SetError("Unsupported image format");
   208     return NULL;
   209 }
   210 
   211 #if SDL_VERSION_ATLEAST(2,0,0)
   212 SDL_Texture *IMG_LoadTexture(SDL_Renderer *renderer, const char *file)
   213 {
   214     SDL_Texture *texture = NULL;
   215     SDL_Surface *surface = IMG_Load(file);
   216     if (surface) {
   217         texture = SDL_CreateTextureFromSurface(renderer, surface);
   218         SDL_FreeSurface(surface);
   219     }
   220     return texture;
   221 }
   222 
   223 SDL_Texture *IMG_LoadTexture_RW(SDL_Renderer *renderer, SDL_RWops *src, int freesrc)
   224 {
   225     SDL_Texture *texture = NULL;
   226     SDL_Surface *surface = IMG_Load_RW(src, freesrc);
   227     if (surface) {
   228         texture = SDL_CreateTextureFromSurface(renderer, surface);
   229         SDL_FreeSurface(surface);
   230     }
   231     return texture;
   232 }
   233 
   234 SDL_Texture *IMG_LoadTextureTyped_RW(SDL_Renderer *renderer, SDL_RWops *src, int freesrc, const char *type)
   235 {
   236     SDL_Texture *texture = NULL;
   237     SDL_Surface *surface = IMG_LoadTyped_RW(src, freesrc, type);
   238     if (surface) {
   239         texture = SDL_CreateTextureFromSurface(renderer, surface);
   240         SDL_FreeSurface(surface);
   241     }
   242     return texture;
   243 }
   244 #endif /* SDL 2.0 */