The palette unused value is treated as alpha and updated when setting the colorkey.
This fixes issues loading palettized images that have a colorkey with the same RGB values as another entry in the palette (e.g. bug 1746)
This commit is contained in:
parent
890d7ee576
commit
8f9ae94235
3 changed files with 44 additions and 16 deletions
|
@ -762,12 +762,12 @@ SDL_CalculatePitch(SDL_Surface * surface)
|
||||||
* Match an RGB value to a particular palette index
|
* Match an RGB value to a particular palette index
|
||||||
*/
|
*/
|
||||||
Uint8
|
Uint8
|
||||||
SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b)
|
SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||||
{
|
{
|
||||||
/* Do colorspace distance matching */
|
/* Do colorspace distance matching */
|
||||||
unsigned int smallest;
|
unsigned int smallest;
|
||||||
unsigned int distance;
|
unsigned int distance;
|
||||||
int rd, gd, bd;
|
int rd, gd, bd, ad;
|
||||||
int i;
|
int i;
|
||||||
Uint8 pixel = 0;
|
Uint8 pixel = 0;
|
||||||
|
|
||||||
|
@ -776,7 +776,8 @@ SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b)
|
||||||
rd = pal->colors[i].r - r;
|
rd = pal->colors[i].r - r;
|
||||||
gd = pal->colors[i].g - g;
|
gd = pal->colors[i].g - g;
|
||||||
bd = pal->colors[i].b - b;
|
bd = pal->colors[i].b - b;
|
||||||
distance = (rd * rd) + (gd * gd) + (bd * bd);
|
ad = pal->colors[i].unused - a;
|
||||||
|
distance = (rd * rd) + (gd * gd) + (bd * bd) + (ad * ad);
|
||||||
if (distance < smallest) {
|
if (distance < smallest) {
|
||||||
pixel = i;
|
pixel = i;
|
||||||
if (distance == 0) { /* Perfect match! */
|
if (distance == 0) { /* Perfect match! */
|
||||||
|
@ -797,7 +798,7 @@ SDL_MapRGB(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b)
|
||||||
| (g >> format->Gloss) << format->Gshift
|
| (g >> format->Gloss) << format->Gshift
|
||||||
| (b >> format->Bloss) << format->Bshift | format->Amask;
|
| (b >> format->Bloss) << format->Bshift | format->Amask;
|
||||||
} else {
|
} else {
|
||||||
return SDL_FindColor(format->palette, r, g, b);
|
return SDL_FindColor(format->palette, r, g, b, SDL_ALPHA_OPAQUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -812,7 +813,7 @@ SDL_MapRGBA(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b,
|
||||||
| (b >> format->Bloss) << format->Bshift
|
| (b >> format->Bloss) << format->Bshift
|
||||||
| ((a >> format->Aloss) << format->Ashift & format->Amask);
|
| ((a >> format->Aloss) << format->Ashift & format->Amask);
|
||||||
} else {
|
} else {
|
||||||
return SDL_FindColor(format->palette, r, g, b);
|
return SDL_FindColor(format->palette, r, g, b, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,7 +859,7 @@ SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat * format,
|
||||||
*r = format->palette->colors[pixel].r;
|
*r = format->palette->colors[pixel].r;
|
||||||
*g = format->palette->colors[pixel].g;
|
*g = format->palette->colors[pixel].g;
|
||||||
*b = format->palette->colors[pixel].b;
|
*b = format->palette->colors[pixel].b;
|
||||||
*a = SDL_ALPHA_OPAQUE;
|
*a = format->palette->colors[pixel].unused;
|
||||||
} else {
|
} else {
|
||||||
*r = *g = *b = *a = 0;
|
*r = *g = *b = *a = 0;
|
||||||
}
|
}
|
||||||
|
@ -894,7 +895,7 @@ Map1to1(SDL_Palette * src, SDL_Palette * dst, int *identical)
|
||||||
for (i = 0; i < src->ncolors; ++i) {
|
for (i = 0; i < src->ncolors; ++i) {
|
||||||
map[i] = SDL_FindColor(dst,
|
map[i] = SDL_FindColor(dst,
|
||||||
src->colors[i].r, src->colors[i].g,
|
src->colors[i].r, src->colors[i].g,
|
||||||
src->colors[i].b);
|
src->colors[i].b, src->colors[i].unused);
|
||||||
}
|
}
|
||||||
return (map);
|
return (map);
|
||||||
}
|
}
|
||||||
|
@ -918,10 +919,10 @@ Map1toN(SDL_PixelFormat * src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod,
|
||||||
|
|
||||||
/* We memory copy to the pixel map so the endianness is preserved */
|
/* We memory copy to the pixel map so the endianness is preserved */
|
||||||
for (i = 0; i < pal->ncolors; ++i) {
|
for (i = 0; i < pal->ncolors; ++i) {
|
||||||
Uint8 A = Amod;
|
|
||||||
Uint8 R = (Uint8) ((pal->colors[i].r * Rmod) / 255);
|
Uint8 R = (Uint8) ((pal->colors[i].r * Rmod) / 255);
|
||||||
Uint8 G = (Uint8) ((pal->colors[i].g * Gmod) / 255);
|
Uint8 G = (Uint8) ((pal->colors[i].g * Gmod) / 255);
|
||||||
Uint8 B = (Uint8) ((pal->colors[i].b * Bmod) / 255);
|
Uint8 B = (Uint8) ((pal->colors[i].b * Bmod) / 255);
|
||||||
|
Uint8 A = (Uint8) ((pal->colors[i].unused * Amod) / 255);
|
||||||
ASSEMBLE_RGBA(&map[i * bpp], dst->BytesPerPixel, dst, R, G, B, A);
|
ASSEMBLE_RGBA(&map[i * bpp], dst->BytesPerPixel, dst, R, G, B, A);
|
||||||
}
|
}
|
||||||
return (map);
|
return (map);
|
||||||
|
|
|
@ -36,6 +36,6 @@ extern void SDL_FreeBlitMap(SDL_BlitMap * map);
|
||||||
/* Miscellaneous functions */
|
/* Miscellaneous functions */
|
||||||
extern int SDL_CalculatePitch(SDL_Surface * surface);
|
extern int SDL_CalculatePitch(SDL_Surface * surface);
|
||||||
extern void SDL_DitherColors(SDL_Color * colors, int bpp);
|
extern void SDL_DitherColors(SDL_Color * colors, int bpp);
|
||||||
extern Uint8 SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b);
|
extern Uint8 SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -187,7 +187,13 @@ SDL_SetColorKey(SDL_Surface * surface, int flag, Uint32 key)
|
||||||
if (flag) {
|
if (flag) {
|
||||||
surface->map->info.flags |= SDL_COPY_COLORKEY;
|
surface->map->info.flags |= SDL_COPY_COLORKEY;
|
||||||
surface->map->info.colorkey = key;
|
surface->map->info.colorkey = key;
|
||||||
|
if (surface->format->palette) {
|
||||||
|
surface->format->palette->colors[surface->map->info.colorkey].unused = SDL_ALPHA_TRANSPARENT;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (surface->format->palette) {
|
||||||
|
surface->format->palette->colors[surface->map->info.colorkey].unused = SDL_ALPHA_OPAQUE;
|
||||||
|
}
|
||||||
surface->map->info.flags &= ~SDL_COPY_COLORKEY;
|
surface->map->info.flags &= ~SDL_COPY_COLORKEY;
|
||||||
}
|
}
|
||||||
if (surface->map->info.flags != flags) {
|
if (surface->map->info.flags != flags) {
|
||||||
|
@ -843,14 +849,35 @@ SDL_ConvertSurface(SDL_Surface * surface, SDL_PixelFormat * format,
|
||||||
SDL_COPY_RLE_ALPHAKEY));
|
SDL_COPY_RLE_ALPHAKEY));
|
||||||
surface->map->info.flags = copy_flags;
|
surface->map->info.flags = copy_flags;
|
||||||
if (copy_flags & SDL_COPY_COLORKEY) {
|
if (copy_flags & SDL_COPY_COLORKEY) {
|
||||||
Uint8 keyR, keyG, keyB, keyA;
|
SDL_bool set_colorkey_by_color = SDL_FALSE;
|
||||||
|
|
||||||
SDL_GetRGBA(surface->map->info.colorkey, surface->format, &keyR,
|
if (surface->format->palette) {
|
||||||
&keyG, &keyB, &keyA);
|
if (format->palette &&
|
||||||
SDL_SetColorKey(convert, 1,
|
surface->format->palette->ncolors <= format->palette->ncolors &&
|
||||||
SDL_MapRGBA(convert->format, keyR, keyG, keyB, keyA));
|
(SDL_memcmp(surface->format->palette->colors, format->palette->colors,
|
||||||
/* This is needed when converting for 3D texture upload */
|
surface->format->palette->ncolors * sizeof(SDL_Color)) == 0)) {
|
||||||
SDL_ConvertColorkeyToAlpha(convert);
|
/* The palette is identical, just set the same colorkey */
|
||||||
|
SDL_SetColorKey(convert, 1, surface->map->info.colorkey);
|
||||||
|
} else if (format->Amask) {
|
||||||
|
/* The alpha was set in the destination from the palette */
|
||||||
|
} else {
|
||||||
|
set_colorkey_by_color = SDL_TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
set_colorkey_by_color = SDL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (set_colorkey_by_color) {
|
||||||
|
/* Set the colorkey by color, which needs to be unique */
|
||||||
|
Uint8 keyR, keyG, keyB, keyA;
|
||||||
|
|
||||||
|
SDL_GetRGBA(surface->map->info.colorkey, surface->format, &keyR,
|
||||||
|
&keyG, &keyB, &keyA);
|
||||||
|
SDL_SetColorKey(convert, 1,
|
||||||
|
SDL_MapRGBA(convert->format, keyR, keyG, keyB, keyA));
|
||||||
|
/* This is needed when converting for 3D texture upload */
|
||||||
|
SDL_ConvertColorkeyToAlpha(convert);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SDL_SetClipRect(convert, &surface->clip_rect);
|
SDL_SetClipRect(convert, &surface->clip_rect);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue