IMG.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 30 Dec 2011 15:57:44 -0500
changeset 278 2fd74c55f313
parent 268 c2221eccce15
child 280 ec4ae96c100c
permissions -rw-r--r--
Michael Bonfils added WEBP image support
slouken@0
     1
/*
slouken@53
     2
    SDL_image:  An example image loading library for use with SDL
slouken@186
     3
    Copyright (C) 1997-2009 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@121
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@121
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@121
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@121
    15
    You should have received a copy of the GNU Lesser General Public
slouken@121
    16
    License along with this library; if not, write to the Free Software
slouken@121
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@53
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@0
    22
slouken@0
    23
/* A simple library to load images of various formats as SDL surfaces */
slouken@0
    24
slouken@0
    25
#include <stdio.h>
slouken@0
    26
#include <string.h>
slouken@0
    27
#include <ctype.h>
slouken@0
    28
slouken@0
    29
#include "SDL_image.h"
slouken@0
    30
slouken@7
    31
#define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0]))
slouken@7
    32
slouken@0
    33
/* Table of image detection and loading functions */
slouken@0
    34
static struct {
slouken@0
    35
	char *type;
icculus@110
    36
	int (SDLCALL *is)(SDL_RWops *src);
icculus@110
    37
	SDL_Surface *(SDLCALL *load)(SDL_RWops *src);
slouken@0
    38
} supported[] = {
slouken@24
    39
	/* keep magicless formats first */
slouken@95
    40
	{ "TGA", NULL,      IMG_LoadTGA_RW },
couriersud@189
    41
	{ "CUR", IMG_isCUR, IMG_LoadCUR_RW },
couriersud@189
    42
	{ "ICO", IMG_isICO, IMG_LoadICO_RW },
slouken@0
    43
	{ "BMP", IMG_isBMP, IMG_LoadBMP_RW },
slouken@0
    44
	{ "GIF", IMG_isGIF, IMG_LoadGIF_RW },
slouken@0
    45
	{ "JPG", IMG_isJPG, IMG_LoadJPG_RW },
slouken@119
    46
	{ "LBM", IMG_isLBM, IMG_LoadLBM_RW },
slouken@119
    47
	{ "PCX", IMG_isPCX, IMG_LoadPCX_RW },
slouken@119
    48
	{ "PNG", IMG_isPNG, IMG_LoadPNG_RW },
slouken@119
    49
	{ "PNM", IMG_isPNM, IMG_LoadPNM_RW }, /* P[BGP]M share code */
slouken@0
    50
	{ "TIF", IMG_isTIF, IMG_LoadTIF_RW },
slouken@119
    51
	{ "XCF", IMG_isXCF, IMG_LoadXCF_RW },
slouken@119
    52
	{ "XPM", IMG_isXPM, IMG_LoadXPM_RW },
slouken@278
    53
	{ "XV",  IMG_isXV,  IMG_LoadXV_RW  },
slouken@278
    54
	{ "WEBP", IMG_isWEBP, IMG_LoadWEBP_RW },
slouken@0
    55
};
slouken@0
    56
slouken@89
    57
const SDL_version *IMG_Linked_Version(void)
slouken@89
    58
{
slouken@89
    59
	static SDL_version linked_version;
slouken@89
    60
	SDL_IMAGE_VERSION(&linked_version);
slouken@89
    61
	return(&linked_version);
slouken@89
    62
}
slouken@89
    63
slouken@205
    64
extern int IMG_InitJPG();
slouken@233
    65
extern void IMG_QuitJPG();
slouken@205
    66
extern int IMG_InitPNG();
slouken@233
    67
extern void IMG_QuitPNG();
slouken@205
    68
extern int IMG_InitTIF();
slouken@233
    69
extern void IMG_QuitTIF();
slouken@205
    70
slouken@278
    71
extern int IMG_InitWEBP();
slouken@278
    72
extern void IMG_QuitWEBP();
slouken@278
    73
slouken@205
    74
static int initialized = 0;
slouken@205
    75
slouken@205
    76
int IMG_Init(int flags)
slouken@205
    77
{
slouken@205
    78
	int result = 0;
slouken@205
    79
slouken@244
    80
	if (flags & IMG_INIT_JPG) {
slouken@244
    81
		if ((initialized & IMG_INIT_JPG) || IMG_InitJPG() == 0) {
slouken@205
    82
			result |= IMG_INIT_JPG;
slouken@205
    83
		}
slouken@205
    84
	}
slouken@244
    85
	if (flags & IMG_INIT_PNG) {
slouken@244
    86
		if ((initialized & IMG_INIT_PNG) || IMG_InitPNG() == 0) {
slouken@205
    87
			result |= IMG_INIT_PNG;
slouken@205
    88
		}
slouken@205
    89
	}
slouken@244
    90
	if (flags & IMG_INIT_TIF) {
slouken@244
    91
		if ((initialized & IMG_INIT_TIF) || IMG_InitTIF() == 0) {
slouken@205
    92
			result |= IMG_INIT_TIF;
slouken@205
    93
		}
slouken@205
    94
	}
slouken@278
    95
	if (flags & IMG_INIT_WEBP) {
slouken@278
    96
		if ((initialized & IMG_INIT_WEBP) || IMG_InitWEBP() == 0) {
slouken@278
    97
			result |= IMG_INIT_WEBP;
slouken@278
    98
		}
slouken@278
    99
	}
slouken@205
   100
	initialized |= result;
slouken@205
   101
slouken@268
   102
	return (initialized);
slouken@205
   103
}
slouken@205
   104
slouken@205
   105
void IMG_Quit()
slouken@205
   106
{
slouken@205
   107
	if (initialized & IMG_INIT_JPG) {
slouken@205
   108
		IMG_QuitJPG();
slouken@205
   109
	}
slouken@205
   110
	if (initialized & IMG_INIT_PNG) {
slouken@205
   111
		IMG_QuitPNG();
slouken@205
   112
	}
slouken@205
   113
	if (initialized & IMG_INIT_TIF) {
slouken@205
   114
		IMG_QuitTIF();
slouken@205
   115
	}
slouken@278
   116
	if (initialized & IMG_INIT_WEBP) {
slouken@278
   117
		IMG_QuitWEBP();
slouken@278
   118
	}
slouken@205
   119
	initialized = 0;
slouken@205
   120
}
slouken@205
   121
slouken@187
   122
#if !defined(__APPLE__) || defined(SDL_IMAGE_USE_COMMON_BACKEND)
slouken@0
   123
/* Load an image from a file */
slouken@0
   124
SDL_Surface *IMG_Load(const char *file)
slouken@0
   125
{
slouken@0
   126
    SDL_RWops *src = SDL_RWFromFile(file, "rb");
slouken@0
   127
    char *ext = strrchr(file, '.');
slouken@95
   128
    if(ext) {
slouken@95
   129
        ext++;
slouken@95
   130
    }
slouken@95
   131
    if(!src) {
slouken@95
   132
        /* The error message has been set in SDL_RWFromFile */
slouken@95
   133
        return NULL;
slouken@95
   134
    }
slouken@0
   135
    return IMG_LoadTyped_RW(src, 1, ext);
slouken@0
   136
}
slouken@187
   137
#endif
slouken@0
   138
slouken@0
   139
/* Load an image from an SDL datasource (for compatibility) */
slouken@0
   140
SDL_Surface *IMG_Load_RW(SDL_RWops *src, int freesrc)
slouken@0
   141
{
slouken@0
   142
    return IMG_LoadTyped_RW(src, freesrc, NULL);
slouken@0
   143
}
slouken@0
   144
slouken@0
   145
/* Portable case-insensitive string compare function */
slouken@50
   146
static int IMG_string_equals(const char *str1, const char *str2)
slouken@0
   147
{
slouken@0
   148
	while ( *str1 && *str2 ) {
slouken@0
   149
		if ( toupper((unsigned char)*str1) !=
slouken@0
   150
		     toupper((unsigned char)*str2) )
slouken@0
   151
			break;
slouken@0
   152
		++str1;
slouken@0
   153
		++str2;
slouken@0
   154
	}
slouken@0
   155
	return (!*str1 && !*str2);
slouken@0
   156
}
slouken@0
   157
slouken@0
   158
/* Load an image from an SDL datasource, optionally specifying the type */
slouken@0
   159
SDL_Surface *IMG_LoadTyped_RW(SDL_RWops *src, int freesrc, char *type)
slouken@0
   160
{
slouken@117
   161
	int i;
slouken@0
   162
	SDL_Surface *image;
slouken@0
   163
slouken@0
   164
	/* Make sure there is something to do.. */
slouken@0
   165
	if ( src == NULL ) {
slouken@95
   166
		IMG_SetError("Passed a NULL data source");
slouken@0
   167
		return(NULL);
slouken@0
   168
	}
slouken@0
   169
slouken@0
   170
	/* See whether or not this data source can handle seeking */
slouken@236
   171
	if ( SDL_RWseek(src, 0, RW_SEEK_CUR) < 0 ) {
slouken@0
   172
		IMG_SetError("Can't seek in this data source");
slouken@78
   173
		if(freesrc)
slouken@78
   174
			SDL_RWclose(src);
slouken@0
   175
		return(NULL);
slouken@0
   176
	}
slouken@0
   177
slouken@0
   178
	/* Detect the type of image being loaded */
slouken@0
   179
	image = NULL;
slouken@11
   180
	for ( i=0; i < ARRAYSIZE(supported); ++i ) {
slouken@62
   181
		if(supported[i].is) {
slouken@62
   182
			if(!supported[i].is(src))
slouken@62
   183
				continue;
slouken@62
   184
		} else {
slouken@62
   185
			/* magicless format */
slouken@62
   186
			if(!type
slouken@62
   187
			   || !IMG_string_equals(type, supported[i].type))
slouken@62
   188
				continue;
slouken@62
   189
		}
slouken@0
   190
#ifdef DEBUG_IMGLIB
slouken@62
   191
		fprintf(stderr, "IMGLIB: Loading image as %s\n",
slouken@62
   192
			supported[i].type);
slouken@0
   193
#endif
slouken@62
   194
		image = supported[i].load(src);
slouken@62
   195
		if(freesrc)
slouken@62
   196
			SDL_RWclose(src);
slouken@62
   197
		return image;
slouken@0
   198
	}
slouken@0
   199
slouken@0
   200
	if ( freesrc ) {
slouken@0
   201
		SDL_RWclose(src);
slouken@0
   202
	}
slouken@62
   203
	IMG_SetError("Unsupported image format");
slouken@62
   204
	return NULL;
slouken@0
   205
}
slouken@0
   206
slouken@0
   207
/* Invert the alpha of a surface for use with OpenGL
slouken@4
   208
   This function is a no-op and only kept for backwards compatibility.
slouken@0
   209
 */
slouken@0
   210
int IMG_InvertAlpha(int on)
slouken@0
   211
{
slouken@4
   212
    return 1;
slouken@0
   213
}