8000 SDL/src/video/SDL_pixels.c at SDL2 · apiel/SDL · GitHub
[go: up one dir, main page]

Skip to content

Latest commit

 

History

History
1182 lines (1071 loc) · 33.3 KB

SDL_pixels.c

File metadata and controls

1182 lines (1071 loc) · 33.3 KB
r |= r >> 3 | r >> 6;
colors[i].r = r;
g = (i << 3) & 0xe0;
g |= g >> 3 | g >> 6;
colors[i].g = g;
b = i & 0x3;
b |= b << 2;
b |= b << 4;
colors[i].b = b;
colors[i].a = SDL_ALPHA_OPAQUE;
}
}
/*
* Match an RGB value to a particular palette index
*/
Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
/* Do colorspace distance matching */
unsigned int smallest;
unsigned int distance;
int rd, gd, bd, ad;
int i;
Uint8 pixel = 0;
smallest = ~0;
for (i = 0; i < pal->ncolors; ++i) {
rd = pal->colors[i].r - r;
gd = pal->colors[i].g - g;
bd = pal->colors[i].b - b;
ad = pal->colors[i].a - a;
distance = (rd * rd) + (gd * gd) + (bd * bd) + (ad * ad);
if (distance < smallest) {
pixel = i;
if (distance == 0) { /* Perfect match! */
break;
}
smallest = distance;
}
}
return pixel;
}
/* Tell whether palette is opaque, and if it has an alpha_channel */
void SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel)
{
int i;
{
SDL_bool all_opaque = SDL_TRUE;
for (i = 0; i < pal->ncolors; i++) {
Uint8 alpha_value = pal->colors[i].a;
if (alpha_value != SDL_ALPHA_OPAQUE) {
all_opaque = SDL_FALSE;
break;
}
}
if (all_opaque) {
/* Palette is opaque, with an alpha channel */
*is_opaque = SDL_TRUE;
*has_alpha_channel = SDL_TRUE;
return;
}
}
{
SDL_bool all_transparent = SDL_TRUE;
for (i = 0; i < pal->ncolors; i++) {
Uint8 alpha_value = pal->colors[i].a;
if (alpha_value != SDL_ALPHA_TRANSPARENT) {
all_transparent = SDL_FALSE;
break;
}
}
if (all_transparent) {
/* Palette is opaque, without an alpha channel */
*is_opaque = SDL_TRUE;
*has_alpha_channel = SDL_FALSE;
return;
}
}
/* Palette has alpha values */
*is_opaque = SDL_FALSE;
*has_alpha_channel = SDL_TRUE;
}
/* Find the opaque pixel value corresponding to an RGB triple */
Uint32 SDL_MapRGB(const SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b)
{
if (!format) {
SDL_InvalidParamError("format");
return 0;
}
if (!format->palette) {
return (r >> format->Rloss) << format->Rshift | (g >> format->Gloss) << format->Gshift | (b >> format->Bloss) << format->Bshift | format->Amask;
} else {
return SDL_FindColor(format->palette, r, g, b, SDL_ALPHA_OPAQUE);
}
}
/* Find the pixel value corresponding to an RGBA quadruple */
Uint32 SDL_MapRGBA(const SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
if (!format) {
SDL_InvalidParamError("format");
return 0;
}
if (!format->palette) {
return (r >> format->Rloss) << format->Rshift | (g >> format->Gloss) << format->Gshift | (b >> format->Bloss) << format->Bshift | ((Uint32)(a >> format->Aloss) << format->Ashift & format->Amask);
} else {
return SDL_FindColor(format->palette, r, g, b, a);
}
}
void SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat *format, Uint8 *r, Uint8 *g,
Uint8 *b)
{
if (!format->palette) {
unsigned v;
v = (pixel & format->Rmask) >> format->Rshift;
*r = SDL_expand_byte[format->Rloss][v];
v = (pixel & format->Gmask) >> format->Gshift;
*g = SDL_expand_byte[format->Gloss][v];
v = (pixel & format->Bmask) >> format->Bshift;
*b = SDL_expand_byte[format->Bloss][v];
} else {
if (pixel < (unsigned)format->palette->ncolors) {
*r = format->palette->colors[pixel].r;
*g = format->palette->colors[pixel].g;
*b = format->palette->colors[pixel].b;
} else {
*r = *g = *b = 0;
}
}
}
void SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat *format,
Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
{
if (!format->palette) {
unsigned v;
v = (pixel & format->Rmask) >> format->Rshift;
*r = SDL_expand_byte[format->Rloss][v];
v = (pixel & format->Gmask) >> format->Gshift;
*g = SDL_expand_byte[format->Gloss][v];
v = (pixel & format->Bmask) >> format->Bshift;
*b = SDL_expand_byte[format->Bloss][v];
v = (pixel & format->Amask) >> format->Ashift;
*a = SDL_expand_byte[format->Aloss][v];
} else {
if (pixel < (unsigned)format->palette->ncolors) {
*r = format->palette->colors[pixel].r;
*g = format->palette->colors[pixel].g;
*b = format->palette->colors[pixel].b;
*a = format->palette->colors[pixel].a;
} else {
*r = *g = *b = *a = 0;
}
}
}
/* Map from Palette to Palette */
static Uint8 *Map1to1(SDL_Palette *src, SDL_Palette *dst, int *identical)
{
Uint8 *map;
int i;
if (identical) {
if (src->ncolors <= dst->ncolors) {
/* If an identical palette, no need to map */
if (src == dst ||
(SDL_memcmp(src->colors, dst->colors,
src->ncolors * sizeof(SDL_Color)) == 0)) {
*identical = 1;
return NULL;
}
}
*identical = 0;
}
map = (Uint8 *)SDL_calloc(256, sizeof(Uint8));
if (!map) {
SDL_OutOfMemory();
return NULL;
}
for (i = 0; i < src->ncolors; ++i) {
map[i] = SDL_FindColor(dst,
src->colors[i].r, src->colors[i].g,
src->colors[i].b, src->colors[i].a);
}
return map;
}
/* Map from Palette to BitField */
static Uint8 *Map1toN(SDL_PixelFormat *src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod,
SDL_PixelFormat *dst)
{
Uint8 *map;
int i;
int bpp;
SDL_Palette *pal = src->palette;
bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel);
map = (Uint8 *)SDL_calloc(256, bpp);
if (!map) {
SDL_OutOfMemory();
return NULL;
}
/* We memory copy to the pixel map so the endianness is preserved */
for (i = 0; i < pal->ncolors; ++i) {
Uint8 R = (Uint8)((pal->colors[i].r * Rmod) / 255);
Uint8 G = (Uint8)((pal->colors[i].g * Gmod) / 255);
Uint8 B = (Uint8)((pal->colors[i].b * Bmod) / 255);
Uint8 A = (Uint8)((pal->colors[i].a * Amod) / 255);
ASSEMBLE_RGBA(&map[i * bpp], dst->BytesPerPixel, dst, (Uint32)R, (Uint32)G, (Uint32)B, (Uint32)A);
}
return map;
}
/* Map from BitField to Dithered-Palette to Palette */
static Uint8 *MapNto1(SDL_PixelFormat *src, SDL_PixelFormat *dst, int *identical)
{
/* Generate a 256 color dither palette */
SDL_Palette dithered;
SDL_Color colors[256];
SDL_Palette *pal = dst->palette;
dithered.ncolors = 256;
SDL_DitherColors(colors, 8);
dithered.colors = colors;
0