Mercurial > sdl-ios-xcode
annotate src/video/SDL_pixels.c @ 855:aa4ac9e65d92
I noticed MacOSX SDL sets up working directory to parent of executable.
On BeOS is should setup it the same way, but it only does when Tracker
wasn't restarted.
I checked code and it looks like a hack to me :(
It looks for env variable and than comapres it to default when OpenTracker
was started after boot, and wasn't restarted. That's probably ok, for that
exact case. Unfortunetly that variable isn't always like that. For
example, after Tracker crashes and is restarted, env variable most
probably is different (depends on how Tracker was restarted, by what
application, etc... for example: i have launcher application from which i
can restart Tracker, and after that nev variable points to that
application's directory, not Tracker's).
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 24 Feb 2004 18:58:40 +0000 |
parents | 333db1d87876 |
children | 3bf4103b2b89 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
695
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 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 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
50
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* General (mostly internal) pixel/color manipulation routines for SDL */ | |
29 | |
30 #include <stdio.h> | |
31 #include <stdlib.h> | |
32 #include <string.h> | |
33 | |
34 #include "SDL_error.h" | |
35 #include "SDL_endian.h" | |
36 #include "SDL_video.h" | |
37 #include "SDL_sysvideo.h" | |
38 #include "SDL_blit.h" | |
39 #include "SDL_pixels_c.h" | |
40 #include "SDL_RLEaccel_c.h" | |
41 | |
42 /* Helper functions */ | |
43 /* | |
44 * Allocate a pixel format structure and fill it according to the given info. | |
45 */ | |
46 SDL_PixelFormat *SDL_AllocFormat(int bpp, | |
47 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) | |
48 { | |
49 SDL_PixelFormat *format; | |
50 Uint32 mask; | |
51 | |
52 /* Allocate an empty pixel format structure */ | |
53 format = malloc(sizeof(*format)); | |
54 if ( format == NULL ) { | |
55 SDL_OutOfMemory(); | |
56 return(NULL); | |
57 } | |
58 memset(format, 0, sizeof(*format)); | |
59 format->alpha = SDL_ALPHA_OPAQUE; | |
60 | |
61 /* Set up the format */ | |
62 format->BitsPerPixel = bpp; | |
63 format->BytesPerPixel = (bpp+7)/8; | |
64 switch (bpp) { | |
65 case 1: | |
66 /* Create the 2 color black-white palette */ | |
67 format->palette = (SDL_Palette *)malloc( | |
68 sizeof(SDL_Palette)); | |
69 if ( format->palette == NULL ) { | |
70 SDL_FreeFormat(format); | |
71 SDL_OutOfMemory(); | |
72 return(NULL); | |
73 } | |
74 (format->palette)->ncolors = 2; | |
75 (format->palette)->colors = (SDL_Color *)malloc( | |
76 (format->palette)->ncolors*sizeof(SDL_Color)); | |
77 if ( (format->palette)->colors == NULL ) { | |
78 SDL_FreeFormat(format); | |
79 SDL_OutOfMemory(); | |
80 return(NULL); | |
81 } | |
82 format->palette->colors[0].r = 0xFF; | |
83 format->palette->colors[0].g = 0xFF; | |
84 format->palette->colors[0].b = 0xFF; | |
85 format->palette->colors[1].r = 0x00; | |
86 format->palette->colors[1].g = 0x00; | |
87 format->palette->colors[1].b = 0x00; | |
88 format->Rloss = 8; | |
89 format->Gloss = 8; | |
90 format->Bloss = 8; | |
91 format->Aloss = 8; | |
92 format->Rshift = 0; | |
93 format->Gshift = 0; | |
94 format->Bshift = 0; | |
95 format->Ashift = 0; | |
96 format->Rmask = 0; | |
97 format->Gmask = 0; | |
98 format->Bmask = 0; | |
99 format->Amask = 0; | |
100 break; | |
101 | |
102 case 4: | |
103 /* Create the 16 color VGA palette */ | |
104 format->palette = (SDL_Palette *)malloc( | |
105 sizeof(SDL_Palette)); | |
106 if ( format->palette == NULL ) { | |
107 SDL_FreeFormat(format); | |
108 SDL_OutOfMemory(); | |
109 return(NULL); | |
110 } | |
111 (format->palette)->ncolors = 16; | |
112 (format->palette)->colors = (SDL_Color *)malloc( | |
113 (format->palette)->ncolors*sizeof(SDL_Color)); | |
114 if ( (format->palette)->colors == NULL ) { | |
115 SDL_FreeFormat(format); | |
116 SDL_OutOfMemory(); | |
117 return(NULL); | |
118 } | |
119 /* Punt for now, will this ever be used? */ | |
120 memset((format->palette)->colors, 0, | |
121 (format->palette)->ncolors*sizeof(SDL_Color)); | |
122 | |
123 /* Palettized formats have no mask info */ | |
124 format->Rloss = 8; | |
125 format->Gloss = 8; | |
126 format->Bloss = 8; | |
127 format->Aloss = 8; | |
128 format->Rshift = 0; | |
129 format->Gshift = 0; | |
130 format->Bshift = 0; | |
131 format->Ashift = 0; | |
132 format->Rmask = 0; | |
133 format->Gmask = 0; | |
134 format->Bmask = 0; | |
135 format->Amask = 0; | |
136 break; | |
137 | |
138 case 8: | |
139 /* Create an empty 256 color palette */ | |
140 format->palette = (SDL_Palette *)malloc( | |
141 sizeof(SDL_Palette)); | |
142 if ( format->palette == NULL ) { | |
143 SDL_FreeFormat(format); | |
144 SDL_OutOfMemory(); | |
145 return(NULL); | |
146 } | |
147 (format->palette)->ncolors = 256; | |
148 (format->palette)->colors = (SDL_Color *)malloc( | |
149 (format->palette)->ncolors*sizeof(SDL_Color)); | |
150 if ( (format->palette)->colors == NULL ) { | |
151 SDL_FreeFormat(format); | |
152 SDL_OutOfMemory(); | |
153 return(NULL); | |
154 } | |
155 memset((format->palette)->colors, 0, | |
156 (format->palette)->ncolors*sizeof(SDL_Color)); | |
157 | |
158 /* Palettized formats have no mask info */ | |
159 format->Rloss = 8; | |
160 format->Gloss = 8; | |
161 format->Bloss = 8; | |
162 format->Aloss = 8; | |
163 format->Rshift = 0; | |
164 format->Gshift = 0; | |
165 format->Bshift = 0; | |
166 format->Ashift = 0; | |
167 format->Rmask = 0; | |
168 format->Gmask = 0; | |
169 format->Bmask = 0; | |
170 format->Amask = 0; | |
171 break; | |
172 | |
173 default: | |
174 /* No palette, just packed pixel info */ | |
175 format->palette = NULL; | |
176 format->Rshift = 0; | |
177 format->Rloss = 8; | |
178 if ( Rmask ) { | |
179 for ( mask = Rmask; !(mask&0x01); mask >>= 1 ) | |
180 ++format->Rshift; | |
181 for ( ; (mask&0x01); mask >>= 1 ) | |
182 --format->Rloss; | |
183 } | |
184 format->Gshift = 0; | |
185 format->Gloss = 8; | |
186 if ( Gmask ) { | |
187 for ( mask = Gmask; !(mask&0x01); mask >>= 1 ) | |
188 ++format->Gshift; | |
189 for ( ; (mask&0x01); mask >>= 1 ) | |
190 --format->Gloss; | |
191 } | |
192 format->Bshift = 0; | |
193 format->Bloss = 8; | |
194 if ( Bmask ) { | |
195 for ( mask = Bmask; !(mask&0x01); mask >>= 1 ) | |
196 ++format->Bshift; | |
197 for ( ; (mask&0x01); mask >>= 1 ) | |
198 --format->Bloss; | |
199 } | |
200 format->Ashift = 0; | |
201 format->Aloss = 8; | |
202 if ( Amask ) { | |
203 for ( mask = Amask; !(mask&0x01); mask >>= 1 ) | |
204 ++format->Ashift; | |
205 for ( ; (mask&0x01); mask >>= 1 ) | |
206 --format->Aloss; | |
207 } | |
208 format->Rmask = Rmask; | |
209 format->Gmask = Gmask; | |
210 format->Bmask = Bmask; | |
211 format->Amask = Amask; | |
212 break; | |
213 } | |
214 /* Calculate some standard bitmasks, if necessary | |
215 * Note: This could conflict with an alpha mask, if given. | |
216 */ | |
217 if ( (bpp > 8) && !format->Rmask && !format->Gmask && !format->Bmask ) { | |
218 /* R-G-B */ | |
219 if ( bpp > 24 ) | |
220 bpp = 24; | |
221 format->Rloss = 8-(bpp/3); | |
222 format->Gloss = 8-(bpp/3)-(bpp%3); | |
223 format->Bloss = 8-(bpp/3); | |
224 format->Rshift = ((bpp/3)+(bpp%3))+(bpp/3); | |
225 format->Gshift = (bpp/3); | |
226 format->Bshift = 0; | |
227 format->Rmask = ((0xFF>>format->Rloss)<<format->Rshift); | |
228 format->Gmask = ((0xFF>>format->Gloss)<<format->Gshift); | |
229 format->Bmask = ((0xFF>>format->Bloss)<<format->Bshift); | |
230 } | |
231 return(format); | |
232 } | |
233 SDL_PixelFormat *SDL_ReallocFormat(SDL_Surface *surface, int bpp, | |
234 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) | |
235 { | |
236 if ( surface->format ) { | |
237 SDL_FreeFormat(surface->format); | |
238 SDL_FormatChanged(surface); | |
239 } | |
240 surface->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); | |
241 return surface->format; | |
242 } | |
243 | |
244 /* | |
245 * Change any previous mappings from/to the new surface format | |
246 */ | |
247 void SDL_FormatChanged(SDL_Surface *surface) | |
248 { | |
845
333db1d87876
Fixed a bug in detecting surface mapping changes
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
249 static int format_version = 0; |
333db1d87876
Fixed a bug in detecting surface mapping changes
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
250 ++format_version; |
333db1d87876
Fixed a bug in detecting surface mapping changes
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
251 if ( format_version < 0 ) { /* It wrapped... */ |
333db1d87876
Fixed a bug in detecting surface mapping changes
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
252 format_version = 1; |
333db1d87876
Fixed a bug in detecting surface mapping changes
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
253 } |
333db1d87876
Fixed a bug in detecting surface mapping changes
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
254 surface->format_version = format_version; |
0 | 255 SDL_InvalidateMap(surface->map); |
256 } | |
257 /* | |
258 * Free a previously allocated format structure | |
259 */ | |
260 void SDL_FreeFormat(SDL_PixelFormat *format) | |
261 { | |
262 if ( format ) { | |
263 if ( format->palette ) { | |
264 if ( format->palette->colors ) { | |
265 free(format->palette->colors); | |
266 } | |
267 free(format->palette); | |
268 } | |
269 free(format); | |
270 } | |
271 } | |
272 /* | |
273 * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors | |
274 */ | |
275 void SDL_DitherColors(SDL_Color *colors, int bpp) | |
276 { | |
277 int i; | |
278 if(bpp != 8) | |
279 return; /* only 8bpp supported right now */ | |
280 | |
281 for(i = 0; i < 256; i++) { | |
282 int r, g, b; | |
283 /* map each bit field to the full [0, 255] interval, | |
284 so 0 is mapped to (0, 0, 0) and 255 to (255, 255, 255) */ | |
285 r = i & 0xe0; | |
286 r |= r >> 3 | r >> 6; | |
287 colors[i].r = r; | |
288 g = (i << 3) & 0xe0; | |
289 g |= g >> 3 | g >> 6; | |
290 colors[i].g = g; | |
291 b = i & 0x3; | |
292 b |= b << 2; | |
293 b |= b << 4; | |
294 colors[i].b = b; | |
295 } | |
296 } | |
297 /* | |
298 * Calculate the pad-aligned scanline width of a surface | |
299 */ | |
300 Uint16 SDL_CalculatePitch(SDL_Surface *surface) | |
301 { | |
302 Uint16 pitch; | |
303 | |
304 /* Surface should be 4-byte aligned for speed */ | |
305 pitch = surface->w*surface->format->BytesPerPixel; | |
306 switch (surface->format->BitsPerPixel) { | |
307 case 1: | |
308 pitch = (pitch+7)/8; | |
309 break; | |
310 case 4: | |
311 pitch = (pitch+1)/2; | |
312 break; | |
313 default: | |
314 break; | |
315 } | |
316 pitch = (pitch + 3) & ~3; /* 4-byte aligning */ | |
317 return(pitch); | |
318 } | |
319 /* | |
320 * Match an RGB value to a particular palette index | |
321 */ | |
322 Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b) | |
323 { | |
324 /* Do colorspace distance matching */ | |
325 unsigned int smallest; | |
326 unsigned int distance; | |
327 int rd, gd, bd; | |
328 int i; | |
329 Uint8 pixel=0; | |
330 | |
331 smallest = ~0; | |
332 for ( i=0; i<pal->ncolors; ++i ) { | |
333 rd = pal->colors[i].r - r; | |
334 gd = pal->colors[i].g - g; | |
335 bd = pal->colors[i].b - b; | |
336 distance = (rd*rd)+(gd*gd)+(bd*bd); | |
337 if ( distance < smallest ) { | |
338 pixel = i; | |
339 if ( distance == 0 ) { /* Perfect match! */ | |
340 break; | |
341 } | |
342 smallest = distance; | |
343 } | |
344 } | |
345 return(pixel); | |
346 } | |
347 | |
348 /* Find the opaque pixel value corresponding to an RGB triple */ | |
349 Uint32 SDL_MapRGB(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b) | |
350 { | |
351 if ( format->palette == NULL ) { | |
352 return (r >> format->Rloss) << format->Rshift | |
353 | (g >> format->Gloss) << format->Gshift | |
354 | (b >> format->Bloss) << format->Bshift | |
355 | format->Amask; | |
356 } else { | |
357 return SDL_FindColor(format->palette, r, g, b); | |
358 } | |
359 } | |
360 | |
361 /* Find the pixel value corresponding to an RGBA quadruple */ | |
362 Uint32 SDL_MapRGBA(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b, Uint8 a) | |
363 { | |
364 if ( format->palette == NULL ) { | |
365 return (r >> format->Rloss) << format->Rshift | |
366 | (g >> format->Gloss) << format->Gshift | |
367 | (b >> format->Bloss) << format->Bshift | |
368 | ((a >> format->Aloss) << format->Ashift & format->Amask); | |
369 } else { | |
370 return SDL_FindColor(format->palette, r, g, b); | |
371 } | |
372 } | |
373 | |
374 void SDL_GetRGBA(Uint32 pixel, SDL_PixelFormat *fmt, | |
375 Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a) | |
376 { | |
377 if ( fmt->palette == NULL ) { | |
378 /* | |
379 * This makes sure that the result is mapped to the | |
380 * interval [0..255], and the maximum value for each | |
381 * component is 255. This is important to make sure | |
382 * that white is indeed reported as (255, 255, 255), | |
383 * and that opaque alpha is 255. | |
384 * This only works for RGB bit fields at least 4 bit | |
385 * wide, which is almost always the case. | |
386 */ | |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
387 unsigned v; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
388 v = (pixel & fmt->Rmask) >> fmt->Rshift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
389 *r = (v << fmt->Rloss) + (v >> (8 - (fmt->Rloss << 1))); |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
390 v = (pixel & fmt->Gmask) >> fmt->Gshift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
391 *g = (v << fmt->Gloss) + (v >> (8 - (fmt->Gloss << 1))); |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
392 v = (pixel & fmt->Bmask) >> fmt->Bshift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
393 *b = (v << fmt->Bloss) + (v >> (8 - (fmt->Bloss << 1))); |
0 | 394 if(fmt->Amask) { |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
395 v = (pixel & fmt->Amask) >> fmt->Ashift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
396 *a = (v << fmt->Aloss) + (v >> (8 - (fmt->Aloss << 1))); |
695 | 397 } else { |
0 | 398 *a = SDL_ALPHA_OPAQUE; |
695 | 399 } |
0 | 400 } else { |
401 *r = fmt->palette->colors[pixel].r; | |
402 *g = fmt->palette->colors[pixel].g; | |
403 *b = fmt->palette->colors[pixel].b; | |
404 *a = SDL_ALPHA_OPAQUE; | |
405 } | |
406 } | |
407 | |
408 void SDL_GetRGB(Uint32 pixel, SDL_PixelFormat *fmt, Uint8 *r,Uint8 *g,Uint8 *b) | |
409 { | |
410 if ( fmt->palette == NULL ) { | |
411 /* the note for SDL_GetRGBA above applies here too */ | |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
412 unsigned v; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
413 v = (pixel & fmt->Rmask) >> fmt->Rshift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
414 *r = (v << fmt->Rloss) + (v >> (8 - (fmt->Rloss << 1))); |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
415 v = (pixel & fmt->Gmask) >> fmt->Gshift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
416 *g = (v << fmt->Gloss) + (v >> (8 - (fmt->Gloss << 1))); |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
417 v = (pixel & fmt->Bmask) >> fmt->Bshift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
418 *b = (v << fmt->Bloss) + (v >> (8 - (fmt->Bloss << 1))); |
0 | 419 } else { |
420 *r = fmt->palette->colors[pixel].r; | |
421 *g = fmt->palette->colors[pixel].g; | |
422 *b = fmt->palette->colors[pixel].b; | |
423 } | |
424 } | |
425 | |
426 /* Apply gamma to a set of colors - this is easy. :) */ | |
427 void SDL_ApplyGamma(Uint16 *gamma, SDL_Color *colors, SDL_Color *output, | |
428 int ncolors) | |
429 { | |
430 int i; | |
431 | |
432 for ( i=0; i<ncolors; ++i ) { | |
433 output[i].r = gamma[0*256 + colors[i].r] >> 8; | |
434 output[i].g = gamma[1*256 + colors[i].g] >> 8; | |
435 output[i].b = gamma[2*256 + colors[i].b] >> 8; | |
436 } | |
437 } | |
438 | |
439 /* Map from Palette to Palette */ | |
440 static Uint8 *Map1to1(SDL_Palette *src, SDL_Palette *dst, int *identical) | |
441 { | |
442 Uint8 *map; | |
443 int i; | |
444 | |
445 if ( identical ) { | |
446 if ( src->ncolors <= dst->ncolors ) { | |
447 /* If an identical palette, no need to map */ | |
448 if ( memcmp(src->colors, dst->colors, src->ncolors* | |
449 sizeof(SDL_Color)) == 0 ) { | |
450 *identical = 1; | |
451 return(NULL); | |
452 } | |
453 } | |
454 *identical = 0; | |
455 } | |
456 map = (Uint8 *)malloc(src->ncolors); | |
457 if ( map == NULL ) { | |
458 SDL_OutOfMemory(); | |
459 return(NULL); | |
460 } | |
461 for ( i=0; i<src->ncolors; ++i ) { | |
462 map[i] = SDL_FindColor(dst, | |
463 src->colors[i].r, src->colors[i].g, src->colors[i].b); | |
464 } | |
465 return(map); | |
466 } | |
467 /* Map from Palette to BitField */ | |
468 static Uint8 *Map1toN(SDL_Palette *src, SDL_PixelFormat *dst) | |
469 { | |
470 Uint8 *map; | |
471 int i; | |
472 int bpp; | |
50 | 473 unsigned alpha; |
0 | 474 |
475 bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel); | |
476 map = (Uint8 *)malloc(src->ncolors*bpp); | |
477 if ( map == NULL ) { | |
478 SDL_OutOfMemory(); | |
479 return(NULL); | |
480 } | |
481 | |
50 | 482 alpha = dst->Amask ? SDL_ALPHA_OPAQUE : 0; |
0 | 483 /* We memory copy to the pixel map so the endianness is preserved */ |
484 for ( i=0; i<src->ncolors; ++i ) { | |
485 ASSEMBLE_RGBA(&map[i*bpp], dst->BytesPerPixel, dst, | |
486 src->colors[i].r, src->colors[i].g, | |
50 | 487 src->colors[i].b, alpha); |
0 | 488 } |
489 return(map); | |
490 } | |
491 /* Map from BitField to Dithered-Palette to Palette */ | |
492 static Uint8 *MapNto1(SDL_PixelFormat *src, SDL_Palette *dst, int *identical) | |
493 { | |
494 /* Generate a 256 color dither palette */ | |
495 SDL_Palette dithered; | |
496 SDL_Color colors[256]; | |
497 | |
498 dithered.ncolors = 256; | |
499 SDL_DitherColors(colors, 8); | |
500 dithered.colors = colors; | |
501 return(Map1to1(&dithered, dst, identical)); | |
502 } | |
503 | |
504 SDL_BlitMap *SDL_AllocBlitMap(void) | |
505 { | |
506 SDL_BlitMap *map; | |
507 | |
508 /* Allocate the empty map */ | |
509 map = (SDL_BlitMap *)malloc(sizeof(*map)); | |
510 if ( map == NULL ) { | |
511 SDL_OutOfMemory(); | |
512 return(NULL); | |
513 } | |
514 memset(map, 0, sizeof(*map)); | |
515 | |
516 /* Allocate the software blit data */ | |
517 map->sw_data = (struct private_swaccel *)malloc(sizeof(*map->sw_data)); | |
518 if ( map->sw_data == NULL ) { | |
519 SDL_FreeBlitMap(map); | |
520 SDL_OutOfMemory(); | |
521 return(NULL); | |
522 } | |
523 memset(map->sw_data, 0, sizeof(*map->sw_data)); | |
524 | |
525 /* It's ready to go */ | |
526 return(map); | |
527 } | |
528 void SDL_InvalidateMap(SDL_BlitMap *map) | |
529 { | |
530 if ( ! map ) { | |
531 return; | |
532 } | |
533 map->dst = NULL; | |
534 map->format_version = (unsigned int)-1; | |
535 if ( map->table ) { | |
536 free(map->table); | |
537 map->table = NULL; | |
538 } | |
539 } | |
540 int SDL_MapSurface (SDL_Surface *src, SDL_Surface *dst) | |
541 { | |
542 SDL_PixelFormat *srcfmt; | |
543 SDL_PixelFormat *dstfmt; | |
544 SDL_BlitMap *map; | |
545 | |
546 /* Clear out any previous mapping */ | |
547 map = src->map; | |
548 if ( (src->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { | |
549 SDL_UnRLESurface(src, 1); | |
550 } | |
551 SDL_InvalidateMap(map); | |
552 | |
553 /* Figure out what kind of mapping we're doing */ | |
554 map->identity = 0; | |
555 srcfmt = src->format; | |
556 dstfmt = dst->format; | |
557 switch (srcfmt->BytesPerPixel) { | |
558 case 1: | |
559 switch (dstfmt->BytesPerPixel) { | |
560 case 1: | |
561 /* Palette --> Palette */ | |
562 /* If both SDL_HWSURFACE, assume have same palette */ | |
563 if ( ((src->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && | |
564 ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) ) { | |
565 map->identity = 1; | |
566 } else { | |
567 map->table = Map1to1(srcfmt->palette, | |
568 dstfmt->palette, &map->identity); | |
569 } | |
570 if ( ! map->identity ) { | |
571 if ( map->table == NULL ) { | |
572 return(-1); | |
573 } | |
574 } | |
575 if (srcfmt->BitsPerPixel!=dstfmt->BitsPerPixel) | |
576 map->identity = 0; | |
577 break; | |
578 | |
579 default: | |
580 /* Palette --> BitField */ | |
581 map->table = Map1toN(srcfmt->palette, dstfmt); | |
582 if ( map->table == NULL ) { | |
583 return(-1); | |
584 } | |
585 break; | |
586 } | |
587 break; | |
588 default: | |
589 switch (dstfmt->BytesPerPixel) { | |
590 case 1: | |
591 /* BitField --> Palette */ | |
592 map->table = MapNto1(srcfmt, | |
593 dstfmt->palette, &map->identity); | |
594 if ( ! map->identity ) { | |
595 if ( map->table == NULL ) { | |
596 return(-1); | |
597 } | |
598 } | |
599 map->identity = 0; /* Don't optimize to copy */ | |
600 break; | |
601 default: | |
602 /* BitField --> BitField */ | |
603 if ( FORMAT_EQUAL(srcfmt, dstfmt) ) | |
604 map->identity = 1; | |
605 break; | |
606 } | |
607 break; | |
608 } | |
609 | |
610 map->dst = dst; | |
611 map->format_version = dst->format_version; | |
612 | |
613 /* Choose your blitters wisely */ | |
614 return(SDL_CalculateBlit(src)); | |
615 } | |
616 void SDL_FreeBlitMap(SDL_BlitMap *map) | |
617 { | |
618 if ( map ) { | |
619 SDL_InvalidateMap(map); | |
620 if ( map->sw_data != NULL ) { | |
621 free(map->sw_data); | |
622 } | |
623 free(map); | |
624 } | |
625 } |