Mercurial > sdl-ios-xcode
comparison src/video/SDL_bmp.c @ 1662:782fd950bd46 SDL-1.3
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.
WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.
The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce
The headers are being converted to automatically generate doxygen documentation.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 28 May 2006 13:04:16 +0000 |
parents | d910939febfa |
children | 4da1ee79c9af |
comparison
equal
deleted
inserted
replaced
1661:281d3f4870e5 | 1662:782fd950bd46 |
---|---|
43 #define BI_RLE4 2 | 43 #define BI_RLE4 2 |
44 #define BI_BITFIELDS 3 | 44 #define BI_BITFIELDS 3 |
45 #endif | 45 #endif |
46 | 46 |
47 | 47 |
48 SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) | 48 SDL_Surface * |
49 SDL_LoadBMP_RW (SDL_RWops * src, int freesrc) | |
49 { | 50 { |
50 int was_error; | 51 int was_error; |
51 long fp_offset; | 52 long fp_offset; |
52 int bmpPitch; | 53 int bmpPitch; |
53 int i, pad; | 54 int i, pad; |
54 SDL_Surface *surface; | 55 SDL_Surface *surface; |
55 Uint32 Rmask; | 56 Uint32 Rmask; |
56 Uint32 Gmask; | 57 Uint32 Gmask; |
57 Uint32 Bmask; | 58 Uint32 Bmask; |
58 SDL_Palette *palette; | 59 SDL_Palette *palette; |
59 Uint8 *bits; | 60 Uint8 *bits; |
60 int ExpandBMP; | 61 int ExpandBMP; |
61 | 62 |
62 /* The Win32 BMP file header (14 bytes) */ | 63 /* The Win32 BMP file header (14 bytes) */ |
63 char magic[2]; | 64 char magic[2]; |
64 Uint32 bfSize; | 65 Uint32 bfSize; |
65 Uint16 bfReserved1; | 66 Uint16 bfReserved1; |
66 Uint16 bfReserved2; | 67 Uint16 bfReserved2; |
67 Uint32 bfOffBits; | 68 Uint32 bfOffBits; |
68 | 69 |
69 /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ | 70 /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ |
70 Uint32 biSize; | 71 Uint32 biSize; |
71 Sint32 biWidth; | 72 Sint32 biWidth; |
72 Sint32 biHeight; | 73 Sint32 biHeight; |
73 Uint16 biPlanes; | 74 Uint16 biPlanes; |
74 Uint16 biBitCount; | 75 Uint16 biBitCount; |
75 Uint32 biCompression; | 76 Uint32 biCompression; |
76 Uint32 biSizeImage; | 77 Uint32 biSizeImage; |
77 Sint32 biXPelsPerMeter; | 78 Sint32 biXPelsPerMeter; |
78 Sint32 biYPelsPerMeter; | 79 Sint32 biYPelsPerMeter; |
79 Uint32 biClrUsed; | 80 Uint32 biClrUsed; |
80 Uint32 biClrImportant; | 81 Uint32 biClrImportant; |
81 | 82 |
82 /* Make sure we are passed a valid data source */ | 83 /* Make sure we are passed a valid data source */ |
83 surface = NULL; | 84 surface = NULL; |
84 was_error = 0; | 85 was_error = 0; |
85 if ( src == NULL ) { | 86 if (src == NULL) { |
86 was_error = 1; | 87 was_error = 1; |
87 goto done; | 88 goto done; |
88 } | 89 } |
89 | 90 |
90 /* Read in the BMP file header */ | 91 /* Read in the BMP file header */ |
91 fp_offset = SDL_RWtell(src); | 92 fp_offset = SDL_RWtell (src); |
92 SDL_ClearError(); | 93 SDL_ClearError (); |
93 if ( SDL_RWread(src, magic, 1, 2) != 2 ) { | 94 if (SDL_RWread (src, magic, 1, 2) != 2) { |
94 SDL_Error(SDL_EFREAD); | 95 SDL_Error (SDL_EFREAD); |
95 was_error = 1; | 96 was_error = 1; |
96 goto done; | 97 goto done; |
97 } | 98 } |
98 if ( SDL_strncmp(magic, "BM", 2) != 0 ) { | 99 if (SDL_strncmp (magic, "BM", 2) != 0) { |
99 SDL_SetError("File is not a Windows BMP file"); | 100 SDL_SetError ("File is not a Windows BMP file"); |
100 was_error = 1; | 101 was_error = 1; |
101 goto done; | 102 goto done; |
102 } | 103 } |
103 bfSize = SDL_ReadLE32(src); | 104 bfSize = SDL_ReadLE32 (src); |
104 bfReserved1 = SDL_ReadLE16(src); | 105 bfReserved1 = SDL_ReadLE16 (src); |
105 bfReserved2 = SDL_ReadLE16(src); | 106 bfReserved2 = SDL_ReadLE16 (src); |
106 bfOffBits = SDL_ReadLE32(src); | 107 bfOffBits = SDL_ReadLE32 (src); |
107 | 108 |
108 /* Read the Win32 BITMAPINFOHEADER */ | 109 /* Read the Win32 BITMAPINFOHEADER */ |
109 biSize = SDL_ReadLE32(src); | 110 biSize = SDL_ReadLE32 (src); |
110 if ( biSize == 12 ) { | 111 if (biSize == 12) { |
111 biWidth = (Uint32)SDL_ReadLE16(src); | 112 biWidth = (Uint32) SDL_ReadLE16 (src); |
112 biHeight = (Uint32)SDL_ReadLE16(src); | 113 biHeight = (Uint32) SDL_ReadLE16 (src); |
113 biPlanes = SDL_ReadLE16(src); | 114 biPlanes = SDL_ReadLE16 (src); |
114 biBitCount = SDL_ReadLE16(src); | 115 biBitCount = SDL_ReadLE16 (src); |
115 biCompression = BI_RGB; | 116 biCompression = BI_RGB; |
116 biSizeImage = 0; | 117 biSizeImage = 0; |
117 biXPelsPerMeter = 0; | 118 biXPelsPerMeter = 0; |
118 biYPelsPerMeter = 0; | 119 biYPelsPerMeter = 0; |
119 biClrUsed = 0; | 120 biClrUsed = 0; |
120 biClrImportant = 0; | 121 biClrImportant = 0; |
121 } else { | 122 } else { |
122 biWidth = SDL_ReadLE32(src); | 123 biWidth = SDL_ReadLE32 (src); |
123 biHeight = SDL_ReadLE32(src); | 124 biHeight = SDL_ReadLE32 (src); |
124 biPlanes = SDL_ReadLE16(src); | 125 biPlanes = SDL_ReadLE16 (src); |
125 biBitCount = SDL_ReadLE16(src); | 126 biBitCount = SDL_ReadLE16 (src); |
126 biCompression = SDL_ReadLE32(src); | 127 biCompression = SDL_ReadLE32 (src); |
127 biSizeImage = SDL_ReadLE32(src); | 128 biSizeImage = SDL_ReadLE32 (src); |
128 biXPelsPerMeter = SDL_ReadLE32(src); | 129 biXPelsPerMeter = SDL_ReadLE32 (src); |
129 biYPelsPerMeter = SDL_ReadLE32(src); | 130 biYPelsPerMeter = SDL_ReadLE32 (src); |
130 biClrUsed = SDL_ReadLE32(src); | 131 biClrUsed = SDL_ReadLE32 (src); |
131 biClrImportant = SDL_ReadLE32(src); | 132 biClrImportant = SDL_ReadLE32 (src); |
132 } | 133 } |
133 | 134 |
134 /* Check for read error */ | 135 /* Check for read error */ |
135 if ( SDL_strcmp(SDL_GetError(), "") != 0 ) { | 136 if (SDL_strcmp (SDL_GetError (), "") != 0) { |
136 was_error = 1; | 137 was_error = 1; |
137 goto done; | 138 goto done; |
138 } | 139 } |
139 | 140 |
140 /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */ | 141 /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */ |
141 switch (biBitCount) { | 142 switch (biBitCount) { |
142 case 1: | 143 case 1: |
143 case 4: | 144 case 4: |
144 ExpandBMP = biBitCount; | 145 ExpandBMP = biBitCount; |
145 biBitCount = 8; | 146 biBitCount = 8; |
146 break; | 147 break; |
147 default: | 148 default: |
148 ExpandBMP = 0; | 149 ExpandBMP = 0; |
149 break; | 150 break; |
150 } | 151 } |
151 | 152 |
152 /* We don't support any BMP compression right now */ | 153 /* We don't support any BMP compression right now */ |
153 Rmask = Gmask = Bmask = 0; | 154 Rmask = Gmask = Bmask = 0; |
154 switch (biCompression) { | 155 switch (biCompression) { |
155 case BI_RGB: | 156 case BI_RGB: |
156 /* If there are no masks, use the defaults */ | 157 /* If there are no masks, use the defaults */ |
157 if ( bfOffBits == (14+biSize) ) { | 158 if (bfOffBits == (14 + biSize)) { |
158 /* Default values for the BMP format */ | 159 /* Default values for the BMP format */ |
159 switch (biBitCount) { | 160 switch (biBitCount) { |
160 case 15: | 161 case 15: |
161 case 16: | 162 case 16: |
162 Rmask = 0x7C00; | 163 Rmask = 0x7C00; |
163 Gmask = 0x03E0; | 164 Gmask = 0x03E0; |
164 Bmask = 0x001F; | 165 Bmask = 0x001F; |
165 break; | 166 break; |
166 case 24: | 167 case 24: |
167 #if SDL_BYTEORDER == SDL_BIG_ENDIAN | 168 #if SDL_BYTEORDER == SDL_BIG_ENDIAN |
168 Rmask = 0x000000FF; | 169 Rmask = 0x000000FF; |
169 Gmask = 0x0000FF00; | 170 Gmask = 0x0000FF00; |
170 Bmask = 0x00FF0000; | 171 Bmask = 0x00FF0000; |
171 break; | 172 break; |
172 #endif | 173 #endif |
173 case 32: | 174 case 32: |
174 Rmask = 0x00FF0000; | 175 Rmask = 0x00FF0000; |
175 Gmask = 0x0000FF00; | 176 Gmask = 0x0000FF00; |
176 Bmask = 0x000000FF; | 177 Bmask = 0x000000FF; |
177 break; | 178 break; |
178 default: | 179 default: |
179 break; | 180 break; |
180 } | 181 } |
181 break; | 182 break; |
182 } | 183 } |
183 /* Fall through -- read the RGB masks */ | 184 /* Fall through -- read the RGB masks */ |
184 | 185 |
185 case BI_BITFIELDS: | 186 case BI_BITFIELDS: |
186 switch (biBitCount) { | 187 switch (biBitCount) { |
187 case 15: | 188 case 15: |
188 case 16: | 189 case 16: |
189 case 32: | 190 case 32: |
190 Rmask = SDL_ReadLE32(src); | 191 Rmask = SDL_ReadLE32 (src); |
191 Gmask = SDL_ReadLE32(src); | 192 Gmask = SDL_ReadLE32 (src); |
192 Bmask = SDL_ReadLE32(src); | 193 Bmask = SDL_ReadLE32 (src); |
193 break; | 194 break; |
194 default: | 195 default: |
195 break; | 196 break; |
196 } | 197 } |
197 break; | 198 break; |
198 default: | 199 default: |
199 SDL_SetError("Compressed BMP files not supported"); | 200 SDL_SetError ("Compressed BMP files not supported"); |
200 was_error = 1; | 201 was_error = 1; |
201 goto done; | 202 goto done; |
202 } | 203 } |
203 | 204 |
204 /* Create a compatible surface, note that the colors are RGB ordered */ | 205 /* Create a compatible surface, note that the colors are RGB ordered */ |
205 surface = SDL_CreateRGBSurface(SDL_SWSURFACE, | 206 surface = SDL_CreateRGBSurface (SDL_SWSURFACE, |
206 biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0); | 207 biWidth, biHeight, biBitCount, Rmask, |
207 if ( surface == NULL ) { | 208 Gmask, Bmask, 0); |
208 was_error = 1; | 209 if (surface == NULL) { |
209 goto done; | 210 was_error = 1; |
210 } | 211 goto done; |
211 | 212 } |
212 /* Load the palette, if any */ | 213 |
213 palette = (surface->format)->palette; | 214 /* Load the palette, if any */ |
214 if ( palette ) { | 215 palette = (surface->format)->palette; |
215 if ( biClrUsed == 0 ) { | 216 if (palette) { |
216 biClrUsed = 1 << biBitCount; | 217 if (biClrUsed == 0) { |
217 } | 218 biClrUsed = 1 << biBitCount; |
218 if ( biSize == 12 ) { | 219 } |
219 for ( i = 0; i < (int)biClrUsed; ++i ) { | 220 if (biSize == 12) { |
220 SDL_RWread(src, &palette->colors[i].b, 1, 1); | 221 for (i = 0; i < (int) biClrUsed; ++i) { |
221 SDL_RWread(src, &palette->colors[i].g, 1, 1); | 222 SDL_RWread (src, &palette->colors[i].b, 1, 1); |
222 SDL_RWread(src, &palette->colors[i].r, 1, 1); | 223 SDL_RWread (src, &palette->colors[i].g, 1, 1); |
223 palette->colors[i].unused = 0; | 224 SDL_RWread (src, &palette->colors[i].r, 1, 1); |
224 } | 225 palette->colors[i].unused = 0; |
225 } else { | 226 } |
226 for ( i = 0; i < (int)biClrUsed; ++i ) { | 227 } else { |
227 SDL_RWread(src, &palette->colors[i].b, 1, 1); | 228 for (i = 0; i < (int) biClrUsed; ++i) { |
228 SDL_RWread(src, &palette->colors[i].g, 1, 1); | 229 SDL_RWread (src, &palette->colors[i].b, 1, 1); |
229 SDL_RWread(src, &palette->colors[i].r, 1, 1); | 230 SDL_RWread (src, &palette->colors[i].g, 1, 1); |
230 SDL_RWread(src, &palette->colors[i].unused, 1, 1); | 231 SDL_RWread (src, &palette->colors[i].r, 1, 1); |
231 } | 232 SDL_RWread (src, &palette->colors[i].unused, 1, 1); |
232 } | 233 } |
233 palette->ncolors = biClrUsed; | 234 } |
234 } | 235 palette->ncolors = biClrUsed; |
235 | 236 } |
236 /* Read the surface pixels. Note that the bmp image is upside down */ | 237 |
237 if ( SDL_RWseek(src, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) { | 238 /* Read the surface pixels. Note that the bmp image is upside down */ |
238 SDL_Error(SDL_EFSEEK); | 239 if (SDL_RWseek (src, fp_offset + bfOffBits, RW_SEEK_SET) < 0) { |
239 was_error = 1; | 240 SDL_Error (SDL_EFSEEK); |
240 goto done; | 241 was_error = 1; |
241 } | 242 goto done; |
242 bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch); | 243 } |
243 switch (ExpandBMP) { | 244 bits = (Uint8 *) surface->pixels + (surface->h * surface->pitch); |
244 case 1: | 245 switch (ExpandBMP) { |
245 bmpPitch = (biWidth + 7) >> 3; | 246 case 1: |
246 pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0); | 247 bmpPitch = (biWidth + 7) >> 3; |
247 break; | 248 pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0); |
248 case 4: | 249 break; |
249 bmpPitch = (biWidth + 1) >> 1; | 250 case 4: |
250 pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0); | 251 bmpPitch = (biWidth + 1) >> 1; |
251 break; | 252 pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0); |
252 default: | 253 break; |
253 pad = ((surface->pitch%4) ? | 254 default: |
254 (4-(surface->pitch%4)) : 0); | 255 pad = ((surface->pitch % 4) ? (4 - (surface->pitch % 4)) : 0); |
255 break; | 256 break; |
256 } | 257 } |
257 while ( bits > (Uint8 *)surface->pixels ) { | 258 while (bits > (Uint8 *) surface->pixels) { |
258 bits -= surface->pitch; | 259 bits -= surface->pitch; |
259 switch (ExpandBMP) { | 260 switch (ExpandBMP) { |
260 case 1: | 261 case 1: |
261 case 4: { | 262 case 4: |
262 Uint8 pixel = 0; | 263 { |
263 int shift = (8-ExpandBMP); | 264 Uint8 pixel = 0; |
264 for ( i=0; i<surface->w; ++i ) { | 265 int shift = (8 - ExpandBMP); |
265 if ( i%(8/ExpandBMP) == 0 ) { | 266 for (i = 0; i < surface->w; ++i) { |
266 if ( !SDL_RWread(src, &pixel, 1, 1) ) { | 267 if (i % (8 / ExpandBMP) == 0) { |
267 SDL_SetError( | 268 if (!SDL_RWread (src, &pixel, 1, 1)) { |
268 "Error reading from BMP"); | 269 SDL_SetError ("Error reading from BMP"); |
269 was_error = 1; | 270 was_error = 1; |
270 goto done; | 271 goto done; |
271 } | 272 } |
272 } | 273 } |
273 *(bits+i) = (pixel>>shift); | 274 *(bits + i) = (pixel >> shift); |
274 pixel <<= ExpandBMP; | 275 pixel <<= ExpandBMP; |
275 } } | 276 } |
276 break; | 277 } |
277 | 278 break; |
278 default: | 279 |
279 if ( SDL_RWread(src, bits, 1, surface->pitch) | 280 default: |
280 != surface->pitch ) { | 281 if (SDL_RWread (src, bits, 1, surface->pitch) |
281 SDL_Error(SDL_EFREAD); | 282 != surface->pitch) { |
282 was_error = 1; | 283 SDL_Error (SDL_EFREAD); |
283 goto done; | 284 was_error = 1; |
284 } | 285 goto done; |
286 } | |
285 #if SDL_BYTEORDER == SDL_BIG_ENDIAN | 287 #if SDL_BYTEORDER == SDL_BIG_ENDIAN |
286 /* Byte-swap the pixels if needed. Note that the 24bpp | 288 /* Byte-swap the pixels if needed. Note that the 24bpp |
287 case has already been taken care of above. */ | 289 case has already been taken care of above. */ |
288 switch(biBitCount) { | 290 switch (biBitCount) { |
289 case 15: | 291 case 15: |
290 case 16: { | 292 case 16: |
291 Uint16 *pix = (Uint16 *)bits; | 293 { |
292 for(i = 0; i < surface->w; i++) | 294 Uint16 *pix = (Uint16 *) bits; |
293 pix[i] = SDL_Swap16(pix[i]); | 295 for (i = 0; i < surface->w; i++) |
294 break; | 296 pix[i] = SDL_Swap16 (pix[i]); |
295 } | 297 break; |
296 | 298 } |
297 case 32: { | 299 |
298 Uint32 *pix = (Uint32 *)bits; | 300 case 32: |
299 for(i = 0; i < surface->w; i++) | 301 { |
300 pix[i] = SDL_Swap32(pix[i]); | 302 Uint32 *pix = (Uint32 *) bits; |
301 break; | 303 for (i = 0; i < surface->w; i++) |
302 } | 304 pix[i] = SDL_Swap32 (pix[i]); |
303 } | 305 break; |
306 } | |
307 } | |
304 #endif | 308 #endif |
305 break; | 309 break; |
306 } | 310 } |
307 /* Skip padding bytes, ugh */ | 311 /* Skip padding bytes, ugh */ |
308 if ( pad ) { | 312 if (pad) { |
309 Uint8 padbyte; | 313 Uint8 padbyte; |
310 for ( i=0; i<pad; ++i ) { | 314 for (i = 0; i < pad; ++i) { |
311 SDL_RWread(src, &padbyte, 1, 1); | 315 SDL_RWread (src, &padbyte, 1, 1); |
312 } | 316 } |
313 } | 317 } |
314 } | 318 } |
315 done: | 319 done: |
316 if ( was_error ) { | 320 if (was_error) { |
317 if ( src ) { | 321 if (src) { |
318 SDL_RWseek(src, fp_offset, RW_SEEK_SET); | 322 SDL_RWseek (src, fp_offset, RW_SEEK_SET); |
319 } | 323 } |
320 if ( surface ) { | 324 if (surface) { |
321 SDL_FreeSurface(surface); | 325 SDL_FreeSurface (surface); |
322 } | 326 } |
323 surface = NULL; | 327 surface = NULL; |
324 } | 328 } |
325 if ( freesrc && src ) { | 329 if (freesrc && src) { |
326 SDL_RWclose(src); | 330 SDL_RWclose (src); |
327 } | 331 } |
328 return(surface); | 332 return (surface); |
329 } | 333 } |
330 | 334 |
331 int SDL_SaveBMP_RW (SDL_Surface *saveme, SDL_RWops *dst, int freedst) | 335 int |
336 SDL_SaveBMP_RW (SDL_Surface * saveme, SDL_RWops * dst, int freedst) | |
332 { | 337 { |
333 long fp_offset; | 338 long fp_offset; |
334 int i, pad; | 339 int i, pad; |
335 SDL_Surface *surface; | 340 SDL_Surface *surface; |
336 Uint8 *bits; | 341 Uint8 *bits; |
337 | 342 |
338 /* The Win32 BMP file header (14 bytes) */ | 343 /* The Win32 BMP file header (14 bytes) */ |
339 char magic[2] = { 'B', 'M' }; | 344 char magic[2] = { 'B', 'M' }; |
340 Uint32 bfSize; | 345 Uint32 bfSize; |
341 Uint16 bfReserved1; | 346 Uint16 bfReserved1; |
342 Uint16 bfReserved2; | 347 Uint16 bfReserved2; |
343 Uint32 bfOffBits; | 348 Uint32 bfOffBits; |
344 | 349 |
345 /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ | 350 /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ |
346 Uint32 biSize; | 351 Uint32 biSize; |
347 Sint32 biWidth; | 352 Sint32 biWidth; |
348 Sint32 biHeight; | 353 Sint32 biHeight; |
349 Uint16 biPlanes; | 354 Uint16 biPlanes; |
350 Uint16 biBitCount; | 355 Uint16 biBitCount; |
351 Uint32 biCompression; | 356 Uint32 biCompression; |
352 Uint32 biSizeImage; | 357 Uint32 biSizeImage; |
353 Sint32 biXPelsPerMeter; | 358 Sint32 biXPelsPerMeter; |
354 Sint32 biYPelsPerMeter; | 359 Sint32 biYPelsPerMeter; |
355 Uint32 biClrUsed; | 360 Uint32 biClrUsed; |
356 Uint32 biClrImportant; | 361 Uint32 biClrImportant; |
357 | 362 |
358 /* Make sure we have somewhere to save */ | 363 /* Make sure we have somewhere to save */ |
359 surface = NULL; | 364 surface = NULL; |
360 if ( dst ) { | 365 if (dst) { |
361 if ( saveme->format->palette ) { | 366 if (saveme->format->palette) { |
362 if ( saveme->format->BitsPerPixel == 8 ) { | 367 if (saveme->format->BitsPerPixel == 8) { |
363 surface = saveme; | 368 surface = saveme; |
364 } else { | 369 } else { |
365 SDL_SetError("%d bpp BMP files not supported", | 370 SDL_SetError ("%d bpp BMP files not supported", |
366 saveme->format->BitsPerPixel); | 371 saveme->format->BitsPerPixel); |
367 } | 372 } |
368 } | 373 } else if ((saveme->format->BitsPerPixel == 24) && |
369 else if ( (saveme->format->BitsPerPixel == 24) && | |
370 #if SDL_BYTEORDER == SDL_LIL_ENDIAN | 374 #if SDL_BYTEORDER == SDL_LIL_ENDIAN |
371 (saveme->format->Rmask == 0x00FF0000) && | 375 (saveme->format->Rmask == 0x00FF0000) && |
372 (saveme->format->Gmask == 0x0000FF00) && | 376 (saveme->format->Gmask == 0x0000FF00) && |
373 (saveme->format->Bmask == 0x000000FF) | 377 (saveme->format->Bmask == 0x000000FF) |
374 #else | 378 #else |
375 (saveme->format->Rmask == 0x000000FF) && | 379 (saveme->format->Rmask == 0x000000FF) && |
376 (saveme->format->Gmask == 0x0000FF00) && | 380 (saveme->format->Gmask == 0x0000FF00) && |
377 (saveme->format->Bmask == 0x00FF0000) | 381 (saveme->format->Bmask == 0x00FF0000) |
378 #endif | 382 #endif |
379 ) { | 383 ) { |
380 surface = saveme; | 384 surface = saveme; |
381 } else { | 385 } else { |
382 SDL_Rect bounds; | 386 SDL_Rect bounds; |
383 | 387 |
384 /* Convert to 24 bits per pixel */ | 388 /* Convert to 24 bits per pixel */ |
385 surface = SDL_CreateRGBSurface(SDL_SWSURFACE, | 389 surface = SDL_CreateRGBSurface (SDL_SWSURFACE, |
386 saveme->w, saveme->h, 24, | 390 saveme->w, saveme->h, 24, |
387 #if SDL_BYTEORDER == SDL_LIL_ENDIAN | 391 #if SDL_BYTEORDER == SDL_LIL_ENDIAN |
388 0x00FF0000, 0x0000FF00, 0x000000FF, | 392 0x00FF0000, 0x0000FF00, |
393 0x000000FF, | |
389 #else | 394 #else |
390 0x000000FF, 0x0000FF00, 0x00FF0000, | 395 0x000000FF, 0x0000FF00, |
396 0x00FF0000, | |
391 #endif | 397 #endif |
392 0); | 398 0); |
393 if ( surface != NULL ) { | 399 if (surface != NULL) { |
394 bounds.x = 0; | 400 bounds.x = 0; |
395 bounds.y = 0; | 401 bounds.y = 0; |
396 bounds.w = saveme->w; | 402 bounds.w = saveme->w; |
397 bounds.h = saveme->h; | 403 bounds.h = saveme->h; |
398 if ( SDL_LowerBlit(saveme, &bounds, surface, | 404 if (SDL_LowerBlit (saveme, &bounds, surface, &bounds) < 0) { |
399 &bounds) < 0 ) { | 405 SDL_FreeSurface (surface); |
400 SDL_FreeSurface(surface); | 406 SDL_SetError ("Couldn't convert image to 24 bpp"); |
401 SDL_SetError( | 407 surface = NULL; |
402 "Couldn't convert image to 24 bpp"); | 408 } |
403 surface = NULL; | 409 } |
404 } | 410 } |
405 } | 411 } |
406 } | 412 |
407 } | 413 if (surface && (SDL_LockSurface (surface) == 0)) { |
408 | 414 const int bw = surface->w * surface->format->BytesPerPixel; |
409 if ( surface && (SDL_LockSurface(surface) == 0) ) { | 415 |
410 const int bw = surface->w*surface->format->BytesPerPixel; | 416 /* Set the BMP file header values */ |
411 | 417 bfSize = 0; /* We'll write this when we're done */ |
412 /* Set the BMP file header values */ | 418 bfReserved1 = 0; |
413 bfSize = 0; /* We'll write this when we're done */ | 419 bfReserved2 = 0; |
414 bfReserved1 = 0; | 420 bfOffBits = 0; /* We'll write this when we're done */ |
415 bfReserved2 = 0; | 421 |
416 bfOffBits = 0; /* We'll write this when we're done */ | 422 /* Write the BMP file header values */ |
417 | 423 fp_offset = SDL_RWtell (dst); |
418 /* Write the BMP file header values */ | 424 SDL_ClearError (); |
419 fp_offset = SDL_RWtell(dst); | 425 SDL_RWwrite (dst, magic, 2, 1); |
420 SDL_ClearError(); | 426 SDL_WriteLE32 (dst, bfSize); |
421 SDL_RWwrite(dst, magic, 2, 1); | 427 SDL_WriteLE16 (dst, bfReserved1); |
422 SDL_WriteLE32(dst, bfSize); | 428 SDL_WriteLE16 (dst, bfReserved2); |
423 SDL_WriteLE16(dst, bfReserved1); | 429 SDL_WriteLE32 (dst, bfOffBits); |
424 SDL_WriteLE16(dst, bfReserved2); | 430 |
425 SDL_WriteLE32(dst, bfOffBits); | 431 /* Set the BMP info values */ |
426 | 432 biSize = 40; |
427 /* Set the BMP info values */ | 433 biWidth = surface->w; |
428 biSize = 40; | 434 biHeight = surface->h; |
429 biWidth = surface->w; | 435 biPlanes = 1; |
430 biHeight = surface->h; | 436 biBitCount = surface->format->BitsPerPixel; |
431 biPlanes = 1; | 437 biCompression = BI_RGB; |
432 biBitCount = surface->format->BitsPerPixel; | 438 biSizeImage = surface->h * surface->pitch; |
433 biCompression = BI_RGB; | 439 biXPelsPerMeter = 0; |
434 biSizeImage = surface->h*surface->pitch; | 440 biYPelsPerMeter = 0; |
435 biXPelsPerMeter = 0; | 441 if (surface->format->palette) { |
436 biYPelsPerMeter = 0; | 442 biClrUsed = surface->format->palette->ncolors; |
437 if ( surface->format->palette ) { | 443 } else { |
438 biClrUsed = surface->format->palette->ncolors; | 444 biClrUsed = 0; |
439 } else { | 445 } |
440 biClrUsed = 0; | 446 biClrImportant = 0; |
441 } | 447 |
442 biClrImportant = 0; | 448 /* Write the BMP info values */ |
443 | 449 SDL_WriteLE32 (dst, biSize); |
444 /* Write the BMP info values */ | 450 SDL_WriteLE32 (dst, biWidth); |
445 SDL_WriteLE32(dst, biSize); | 451 SDL_WriteLE32 (dst, biHeight); |
446 SDL_WriteLE32(dst, biWidth); | 452 SDL_WriteLE16 (dst, biPlanes); |
447 SDL_WriteLE32(dst, biHeight); | 453 SDL_WriteLE16 (dst, biBitCount); |
448 SDL_WriteLE16(dst, biPlanes); | 454 SDL_WriteLE32 (dst, biCompression); |
449 SDL_WriteLE16(dst, biBitCount); | 455 SDL_WriteLE32 (dst, biSizeImage); |
450 SDL_WriteLE32(dst, biCompression); | 456 SDL_WriteLE32 (dst, biXPelsPerMeter); |
451 SDL_WriteLE32(dst, biSizeImage); | 457 SDL_WriteLE32 (dst, biYPelsPerMeter); |
452 SDL_WriteLE32(dst, biXPelsPerMeter); | 458 SDL_WriteLE32 (dst, biClrUsed); |
453 SDL_WriteLE32(dst, biYPelsPerMeter); | 459 SDL_WriteLE32 (dst, biClrImportant); |
454 SDL_WriteLE32(dst, biClrUsed); | 460 |
455 SDL_WriteLE32(dst, biClrImportant); | 461 /* Write the palette (in BGR color order) */ |
456 | 462 if (surface->format->palette) { |
457 /* Write the palette (in BGR color order) */ | 463 SDL_Color *colors; |
458 if ( surface->format->palette ) { | 464 int ncolors; |
459 SDL_Color *colors; | 465 |
460 int ncolors; | 466 colors = surface->format->palette->colors; |
461 | 467 ncolors = surface->format->palette->ncolors; |
462 colors = surface->format->palette->colors; | 468 for (i = 0; i < ncolors; ++i) { |
463 ncolors = surface->format->palette->ncolors; | 469 SDL_RWwrite (dst, &colors[i].b, 1, 1); |
464 for ( i=0; i<ncolors; ++i ) { | 470 SDL_RWwrite (dst, &colors[i].g, 1, 1); |
465 SDL_RWwrite(dst, &colors[i].b, 1, 1); | 471 SDL_RWwrite (dst, &colors[i].r, 1, 1); |
466 SDL_RWwrite(dst, &colors[i].g, 1, 1); | 472 SDL_RWwrite (dst, &colors[i].unused, 1, 1); |
467 SDL_RWwrite(dst, &colors[i].r, 1, 1); | 473 } |
468 SDL_RWwrite(dst, &colors[i].unused, 1, 1); | 474 } |
469 } | 475 |
470 } | 476 /* Write the bitmap offset */ |
471 | 477 bfOffBits = SDL_RWtell (dst) - fp_offset; |
472 /* Write the bitmap offset */ | 478 if (SDL_RWseek (dst, fp_offset + 10, RW_SEEK_SET) < 0) { |
473 bfOffBits = SDL_RWtell(dst)-fp_offset; | 479 SDL_Error (SDL_EFSEEK); |
474 if ( SDL_RWseek(dst, fp_offset+10, RW_SEEK_SET) < 0 ) { | 480 } |
475 SDL_Error(SDL_EFSEEK); | 481 SDL_WriteLE32 (dst, bfOffBits); |
476 } | 482 if (SDL_RWseek (dst, fp_offset + bfOffBits, RW_SEEK_SET) < 0) { |
477 SDL_WriteLE32(dst, bfOffBits); | 483 SDL_Error (SDL_EFSEEK); |
478 if ( SDL_RWseek(dst, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) { | 484 } |
479 SDL_Error(SDL_EFSEEK); | 485 |
480 } | 486 /* Write the bitmap image upside down */ |
481 | 487 bits = (Uint8 *) surface->pixels + (surface->h * surface->pitch); |
482 /* Write the bitmap image upside down */ | 488 pad = ((bw % 4) ? (4 - (bw % 4)) : 0); |
483 bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch); | 489 while (bits > (Uint8 *) surface->pixels) { |
484 pad = ((bw%4) ? (4-(bw%4)) : 0); | 490 bits -= surface->pitch; |
485 while ( bits > (Uint8 *)surface->pixels ) { | 491 if (SDL_RWwrite (dst, bits, 1, bw) != bw) { |
486 bits -= surface->pitch; | 492 SDL_Error (SDL_EFWRITE); |
487 if ( SDL_RWwrite(dst, bits, 1, bw) != bw) { | 493 break; |
488 SDL_Error(SDL_EFWRITE); | 494 } |
489 break; | 495 if (pad) { |
490 } | 496 const Uint8 padbyte = 0; |
491 if ( pad ) { | 497 for (i = 0; i < pad; ++i) { |
492 const Uint8 padbyte = 0; | 498 SDL_RWwrite (dst, &padbyte, 1, 1); |
493 for ( i=0; i<pad; ++i ) { | 499 } |
494 SDL_RWwrite(dst, &padbyte, 1, 1); | 500 } |
495 } | 501 } |
496 } | 502 |
497 } | 503 /* Write the BMP file size */ |
498 | 504 bfSize = SDL_RWtell (dst) - fp_offset; |
499 /* Write the BMP file size */ | 505 if (SDL_RWseek (dst, fp_offset + 2, RW_SEEK_SET) < 0) { |
500 bfSize = SDL_RWtell(dst)-fp_offset; | 506 SDL_Error (SDL_EFSEEK); |
501 if ( SDL_RWseek(dst, fp_offset+2, RW_SEEK_SET) < 0 ) { | 507 } |
502 SDL_Error(SDL_EFSEEK); | 508 SDL_WriteLE32 (dst, bfSize); |
503 } | 509 if (SDL_RWseek (dst, fp_offset + bfSize, RW_SEEK_SET) < 0) { |
504 SDL_WriteLE32(dst, bfSize); | 510 SDL_Error (SDL_EFSEEK); |
505 if ( SDL_RWseek(dst, fp_offset+bfSize, RW_SEEK_SET) < 0 ) { | 511 } |
506 SDL_Error(SDL_EFSEEK); | 512 |
507 } | 513 /* Close it up.. */ |
508 | 514 SDL_UnlockSurface (surface); |
509 /* Close it up.. */ | 515 if (surface != saveme) { |
510 SDL_UnlockSurface(surface); | 516 SDL_FreeSurface (surface); |
511 if ( surface != saveme ) { | 517 } |
512 SDL_FreeSurface(surface); | 518 } |
513 } | 519 |
514 } | 520 if (freedst && dst) { |
515 | 521 SDL_RWclose (dst); |
516 if ( freedst && dst ) { | 522 } |
517 SDL_RWclose(dst); | 523 return ((SDL_strcmp (SDL_GetError (), "") == 0) ? 0 : -1); |
518 } | |
519 return((SDL_strcmp(SDL_GetError(), "") == 0) ? 0 : -1); | |
520 } | 524 } |
525 | |
526 /* vi: set ts=4 sw=4 expandtab: */ |