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