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