Mercurial > sdl-ios-xcode
annotate src/video/SDL_pixels.c @ 1057:e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
From: Jonathan Atkins
Subject: Re: [PATCH] *CRITICAL* 8bit direct RGB palette not being created
I think that SDL_AllocFormat should create the palette for all 8bit
surfaces. And when the RGBAmasks match the normal 3:3:2:0 we need to
apply the old behavior. If the mask doesn't match that, then we need
to make the right palette assuming the masks are valid (I don't think
we validate any masks for high color surfaces...so we wouldn't here)
Then there's always a palette available for the 8bit surfaces.
This restores the normal behavior and allows for masks to create
palettes automatically for odd masks even, which would be a neato
thing to have in there, as SDL never did this before.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 16 May 2005 05:34:58 +0000 |
parents | c69697a85412 |
children | c9b51268668f |
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; | |
1027
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
64 if ( Rmask || Bmask || Gmask ) { /* Packed pixels with custom mask */ |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
65 format->palette = NULL; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
66 format->Rshift = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
67 format->Rloss = 8; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
68 if ( Rmask ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
69 for ( mask = Rmask; !(mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
70 ++format->Rshift; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
71 for ( ; (mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
72 --format->Rloss; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
73 } |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
74 format->Gshift = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
75 format->Gloss = 8; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
76 if ( Gmask ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
77 for ( mask = Gmask; !(mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
78 ++format->Gshift; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
79 for ( ; (mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
80 --format->Gloss; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
81 } |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
82 format->Bshift = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
83 format->Bloss = 8; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
84 if ( Bmask ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
85 for ( mask = Bmask; !(mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
86 ++format->Bshift; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
87 for ( ; (mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
88 --format->Bloss; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
89 } |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
90 format->Ashift = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
91 format->Aloss = 8; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
92 if ( Amask ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
93 for ( mask = Amask; !(mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
94 ++format->Ashift; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
95 for ( ; (mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
96 --format->Aloss; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
97 } |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
98 format->Rmask = Rmask; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
99 format->Gmask = Gmask; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
100 format->Bmask = Bmask; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
101 format->Amask = Amask; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
102 } else if ( bpp > 8 ) { /* Packed pixels with standard mask */ |
0 | 103 /* R-G-B */ |
104 if ( bpp > 24 ) | |
105 bpp = 24; | |
106 format->Rloss = 8-(bpp/3); | |
107 format->Gloss = 8-(bpp/3)-(bpp%3); | |
108 format->Bloss = 8-(bpp/3); | |
109 format->Rshift = ((bpp/3)+(bpp%3))+(bpp/3); | |
110 format->Gshift = (bpp/3); | |
111 format->Bshift = 0; | |
112 format->Rmask = ((0xFF>>format->Rloss)<<format->Rshift); | |
113 format->Gmask = ((0xFF>>format->Gloss)<<format->Gshift); | |
114 format->Bmask = ((0xFF>>format->Bloss)<<format->Bshift); | |
1057
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
115 } else { |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
116 /* Palettized formats have no mask info */ |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
117 format->Rloss = 8; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
118 format->Gloss = 8; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
119 format->Bloss = 8; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
120 format->Aloss = 8; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
121 format->Rshift = 0; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
122 format->Gshift = 0; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
123 format->Bshift = 0; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
124 format->Ashift = 0; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
125 format->Rmask = 0; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
126 format->Gmask = 0; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
127 format->Bmask = 0; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
128 format->Amask = 0; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
129 } |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
130 if ( bpp <= 8 ) { /* Palettized mode */ |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
131 int ncolors = 1<<bpp; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
132 #ifdef DEBUG_PALETTE |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
133 fprintf(stderr,"bpp=%d ncolors=%d\n",bpp,ncolors); |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
134 #endif |
1027
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
135 format->palette = (SDL_Palette *)malloc(sizeof(SDL_Palette)); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
136 if ( format->palette == NULL ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
137 SDL_FreeFormat(format); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
138 SDL_OutOfMemory(); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
139 return(NULL); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
140 } |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
141 (format->palette)->ncolors = ncolors; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
142 (format->palette)->colors = (SDL_Color *)malloc( |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
143 (format->palette)->ncolors*sizeof(SDL_Color)); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
144 if ( (format->palette)->colors == NULL ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
145 SDL_FreeFormat(format); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
146 SDL_OutOfMemory(); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
147 return(NULL); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
148 } |
1057
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
149 if ( Rmask || Bmask || Gmask ) { |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
150 /* create palette according to masks */ |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
151 int i; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
152 int Rm=0,Gm=0,Bm=0; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
153 int Rw=0,Gw=0,Bw=0; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
154 #ifdef ENABLE_PALETTE_ALPHA |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
155 int Am=0,Aw=0; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
156 #endif |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
157 if(Rmask) |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
158 { |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
159 Rw=8-format->Rloss; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
160 for(i=format->Rloss;i>0;i-=Rw) |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
161 Rm|=1<<i; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
162 } |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
163 #ifdef DEBUG_PALETTE |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
164 fprintf(stderr,"Rw=%d Rm=0x%02X\n",Rw,Rm); |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
165 #endif |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
166 if(Gmask) |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
167 { |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
168 Gw=8-format->Gloss; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
169 for(i=format->Gloss;i>0;i-=Gw) |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
170 Gm|=1<<i; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
171 } |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
172 #ifdef DEBUG_PALETTE |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
173 fprintf(stderr,"Gw=%d Gm=0x%02X\n",Gw,Gm); |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
174 #endif |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
175 if(Bmask) |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
176 { |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
177 Bw=8-format->Bloss; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
178 for(i=format->Bloss;i>0;i-=Bw) |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
179 Bm|=1<<i; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
180 } |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
181 #ifdef DEBUG_PALETTE |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
182 fprintf(stderr,"Bw=%d Bm=0x%02X\n",Bw,Bm); |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
183 #endif |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
184 #ifdef ENABLE_PALETTE_ALPHA |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
185 if(Amask) |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
186 { |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
187 Aw=8-format->Aloss; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
188 for(i=format->Aloss;i>0;i-=Aw) |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
189 Am|=1<<i; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
190 } |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
191 # ifdef DEBUG_PALETTE |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
192 fprintf(stderr,"Aw=%d Am=0x%02X\n",Aw,Am); |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
193 # endif |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
194 #endif |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
195 for(i=0; i < ncolors; ++i) { |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
196 int r,g,b; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
197 r=(i&Rmask)>>format->Rshift; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
198 r=(r<<format->Rloss)|((r*Rm)>>Rw); |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
199 format->palette->colors[i].r=r; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
200 |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
201 g=(i&Gmask)>>format->Gshift; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
202 g=(g<<format->Gloss)|((g*Gm)>>Gw); |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
203 format->palette->colors[i].g=g; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
204 |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
205 b=(i&Bmask)>>format->Bshift; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
206 b=(b<<format->Bloss)|((b*Bm)>>Bw); |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
207 format->palette->colors[i].b=b; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
208 |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
209 #ifdef ENABLE_PALETTE_ALPHA |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
210 a=(i&Amask)>>format->Ashift; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
211 a=(a<<format->Aloss)|((a*Am)>>Aw); |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
212 format->palette->colors[i].unused=a; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
213 #else |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
214 format->palette->colors[i].unused=0; |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
215 #endif |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
216 } |
e9d23bb80140
Date: Mon, 02 May 2005 04:23:16 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
1027
diff
changeset
|
217 } else if ( ncolors == 2 ) { |
1027
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
218 /* Create a black and white bitmap palette */ |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
219 format->palette->colors[0].r = 0xFF; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
220 format->palette->colors[0].g = 0xFF; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
221 format->palette->colors[0].b = 0xFF; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
222 format->palette->colors[1].r = 0x00; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
223 format->palette->colors[1].g = 0x00; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
224 format->palette->colors[1].b = 0x00; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
225 } else { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
226 /* Create an empty palette */ |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
227 memset((format->palette)->colors, 0, |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
228 (format->palette)->ncolors*sizeof(SDL_Color)); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
229 } |
0 | 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]; | |
997
3bf4103b2b89
Date: Sat, 27 Nov 2004 13:35:43 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
845
diff
changeset
|
497 |
3bf4103b2b89
Date: Sat, 27 Nov 2004 13:35:43 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
845
diff
changeset
|
498 /* SDL_DitherColors does not initialize the 'unused' component of colors, |
3bf4103b2b89
Date: Sat, 27 Nov 2004 13:35:43 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
845
diff
changeset
|
499 but Map1to1 compares it against dst, so we should initialize it. */ |
3bf4103b2b89
Date: Sat, 27 Nov 2004 13:35:43 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
845
diff
changeset
|
500 memset(colors, 0, sizeof(colors)); |
0 | 501 |
502 dithered.ncolors = 256; | |
503 SDL_DitherColors(colors, 8); | |
504 dithered.colors = colors; | |
505 return(Map1to1(&dithered, dst, identical)); | |
506 } | |
507 | |
508 SDL_BlitMap *SDL_AllocBlitMap(void) | |
509 { | |
510 SDL_BlitMap *map; | |
511 | |
512 /* Allocate the empty map */ | |
513 map = (SDL_BlitMap *)malloc(sizeof(*map)); | |
514 if ( map == NULL ) { | |
515 SDL_OutOfMemory(); | |
516 return(NULL); | |
517 } | |
518 memset(map, 0, sizeof(*map)); | |
519 | |
520 /* Allocate the software blit data */ | |
521 map->sw_data = (struct private_swaccel *)malloc(sizeof(*map->sw_data)); | |
522 if ( map->sw_data == NULL ) { | |
523 SDL_FreeBlitMap(map); | |
524 SDL_OutOfMemory(); | |
525 return(NULL); | |
526 } | |
527 memset(map->sw_data, 0, sizeof(*map->sw_data)); | |
528 | |
529 /* It's ready to go */ | |
530 return(map); | |
531 } | |
532 void SDL_InvalidateMap(SDL_BlitMap *map) | |
533 { | |
534 if ( ! map ) { | |
535 return; | |
536 } | |
537 map->dst = NULL; | |
538 map->format_version = (unsigned int)-1; | |
539 if ( map->table ) { | |
540 free(map->table); | |
541 map->table = NULL; | |
542 } | |
543 } | |
544 int SDL_MapSurface (SDL_Surface *src, SDL_Surface *dst) | |
545 { | |
546 SDL_PixelFormat *srcfmt; | |
547 SDL_PixelFormat *dstfmt; | |
548 SDL_BlitMap *map; | |
549 | |
550 /* Clear out any previous mapping */ | |
551 map = src->map; | |
552 if ( (src->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { | |
553 SDL_UnRLESurface(src, 1); | |
554 } | |
555 SDL_InvalidateMap(map); | |
556 | |
557 /* Figure out what kind of mapping we're doing */ | |
558 map->identity = 0; | |
559 srcfmt = src->format; | |
560 dstfmt = dst->format; | |
561 switch (srcfmt->BytesPerPixel) { | |
562 case 1: | |
563 switch (dstfmt->BytesPerPixel) { | |
564 case 1: | |
565 /* Palette --> Palette */ | |
566 /* If both SDL_HWSURFACE, assume have same palette */ | |
567 if ( ((src->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && | |
568 ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) ) { | |
569 map->identity = 1; | |
570 } else { | |
571 map->table = Map1to1(srcfmt->palette, | |
572 dstfmt->palette, &map->identity); | |
573 } | |
574 if ( ! map->identity ) { | |
575 if ( map->table == NULL ) { | |
576 return(-1); | |
577 } | |
578 } | |
579 if (srcfmt->BitsPerPixel!=dstfmt->BitsPerPixel) | |
580 map->identity = 0; | |
581 break; | |
582 | |
583 default: | |
584 /* Palette --> BitField */ | |
585 map->table = Map1toN(srcfmt->palette, dstfmt); | |
586 if ( map->table == NULL ) { | |
587 return(-1); | |
588 } | |
589 break; | |
590 } | |
591 break; | |
592 default: | |
593 switch (dstfmt->BytesPerPixel) { | |
594 case 1: | |
595 /* BitField --> Palette */ | |
596 map->table = MapNto1(srcfmt, | |
597 dstfmt->palette, &map->identity); | |
598 if ( ! map->identity ) { | |
599 if ( map->table == NULL ) { | |
600 return(-1); | |
601 } | |
602 } | |
603 map->identity = 0; /* Don't optimize to copy */ | |
604 break; | |
605 default: | |
606 /* BitField --> BitField */ | |
607 if ( FORMAT_EQUAL(srcfmt, dstfmt) ) | |
608 map->identity = 1; | |
609 break; | |
610 } | |
611 break; | |
612 } | |
613 | |
614 map->dst = dst; | |
615 map->format_version = dst->format_version; | |
616 | |
617 /* Choose your blitters wisely */ | |
618 return(SDL_CalculateBlit(src)); | |
619 } | |
620 void SDL_FreeBlitMap(SDL_BlitMap *map) | |
621 { | |
622 if ( map ) { | |
623 SDL_InvalidateMap(map); | |
624 if ( map->sw_data != NULL ) { | |
625 free(map->sw_data); | |
626 } | |
627 free(map); | |
628 } | |
629 } |