1 /* |
|
2 SDL_image: An example image loading library for use with SDL |
|
3 Copyright (C) 1997-2009 Sam Lantinga |
|
4 |
|
5 This library is free software; you can redistribute it and/or |
|
6 modify it under the terms of the GNU Lesser General Public |
|
7 License as published by the Free Software Foundation; either |
|
8 version 2.1 of the License, or (at your option) any later version. |
|
9 |
|
10 This library is distributed in the hope that it will be useful, |
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 Lesser General Public License for more details. |
|
14 |
|
15 You should have received a copy of the GNU Lesser General Public |
|
16 License along with this library; if not, write to the Free Software |
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
18 |
|
19 Sam Lantinga |
|
20 slouken@libsdl.org |
|
21 */ |
|
22 |
|
23 /* A simple library to load images of various formats as SDL surfaces */ |
|
24 |
|
25 #include <stdio.h> |
|
26 #include <string.h> |
|
27 #include <ctype.h> |
|
28 |
|
29 #include "SDL_image.h" |
|
30 |
|
31 #define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0])) |
|
32 |
|
33 /* Table of image detection and loading functions */ |
|
34 static struct { |
|
35 char *type; |
|
36 int (SDLCALL *is)(SDL_RWops *src); |
|
37 SDL_Surface *(SDLCALL *load)(SDL_RWops *src); |
|
38 } supported[] = { |
|
39 /* keep magicless formats first */ |
|
40 { "PNG", IMG_isPNG, IMG_LoadPNG_RW } |
|
41 }; |
|
42 |
|
43 |
|
44 extern int IMG_InitPNG(); |
|
45 extern void IMG_QuitPNG(); |
|
46 |
|
47 static int initialized = 0; |
|
48 |
|
49 int IMG_Init(int flags) |
|
50 { |
|
51 int result = 0; |
|
52 |
|
53 if (flags & IMG_INIT_PNG) { |
|
54 if ((initialized & IMG_INIT_PNG) || IMG_InitPNG() == 0) { |
|
55 result |= IMG_INIT_PNG; |
|
56 } |
|
57 } |
|
58 initialized |= result; |
|
59 |
|
60 return (result); |
|
61 } |
|
62 |
|
63 void IMG_Quit() |
|
64 { |
|
65 if (initialized & IMG_INIT_PNG) { |
|
66 IMG_QuitPNG(); |
|
67 } |
|
68 initialized = 0; |
|
69 } |
|
70 |
|
71 /* Load an image from a file */ |
|
72 SDL_Surface *IMG_Load(const char *file) |
|
73 { |
|
74 SDL_RWops *src = SDL_RWFromFile(file, "rb"); |
|
75 char *ext = strrchr(file, '.'); |
|
76 if(ext) { |
|
77 ext++; |
|
78 } |
|
79 if(!src) { |
|
80 /* The error message has been set in SDL_RWFromFile */ |
|
81 return NULL; |
|
82 } |
|
83 return IMG_LoadTyped_RW(src, 1, ext); |
|
84 } |
|
85 |
|
86 /* Load an image from an SDL datasource (for compatibility) */ |
|
87 SDL_Surface *IMG_Load_RW(SDL_RWops *src, int freesrc) |
|
88 { |
|
89 return IMG_LoadTyped_RW(src, freesrc, NULL); |
|
90 } |
|
91 |
|
92 /* Portable case-insensitive string compare function */ |
|
93 static int IMG_string_equals(const char *str1, const char *str2) |
|
94 { |
|
95 while ( *str1 && *str2 ) { |
|
96 if ( toupper((unsigned char)*str1) != |
|
97 toupper((unsigned char)*str2) ) |
|
98 break; |
|
99 ++str1; |
|
100 ++str2; |
|
101 } |
|
102 return (!*str1 && !*str2); |
|
103 } |
|
104 |
|
105 /* Load an image from an SDL datasource, optionally specifying the type */ |
|
106 SDL_Surface *IMG_LoadTyped_RW(SDL_RWops *src, int freesrc, char *type) |
|
107 { |
|
108 int i; |
|
109 SDL_Surface *image; |
|
110 |
|
111 /* Make sure there is something to do.. */ |
|
112 if ( src == NULL ) { |
|
113 IMG_SetError("Passed a NULL data source"); |
|
114 return(NULL); |
|
115 } |
|
116 |
|
117 /* See whether or not this data source can handle seeking */ |
|
118 if ( SDL_RWseek(src, 0, RW_SEEK_CUR) < 0 ) { |
|
119 IMG_SetError("Can't seek in this data source"); |
|
120 if(freesrc) |
|
121 SDL_RWclose(src); |
|
122 return(NULL); |
|
123 } |
|
124 |
|
125 /* Detect the type of image being loaded */ |
|
126 image = NULL; |
|
127 for ( i=0; i < ARRAYSIZE(supported); ++i ) { |
|
128 if(supported[i].is) { |
|
129 if(!supported[i].is(src)) |
|
130 continue; |
|
131 } else { |
|
132 /* magicless format */ |
|
133 if(!type |
|
134 || !IMG_string_equals(type, supported[i].type)) |
|
135 continue; |
|
136 } |
|
137 #ifdef DEBUG_IMGLIB |
|
138 fprintf(stderr, "IMGLIB: Loading image as %s\n", supported[i].type); |
|
139 #endif |
|
140 image = supported[i].load(src); |
|
141 if(freesrc) |
|
142 SDL_RWclose(src); |
|
143 return image; |
|
144 } |
|
145 |
|
146 if ( freesrc ) { |
|
147 SDL_RWclose(src); |
|
148 } |
|
149 IMG_SetError("Unsupported image format"); |
|
150 return NULL; |
|
151 } |
|
152 |
|