📄 pixels.c
字号:
break; } pitch = (pitch + 3) & ~3; /* 4-byte aligning */ return(pitch);}/* * Match an RGB value to a particular palette index */Uint8 GAL_FindColor(GAL_Palette *pal, Uint8 r, Uint8 g, Uint8 b){ /* Do colorspace distance matching */ unsigned int smallest; unsigned int distance; int rd, gd, bd; 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; distance = (rd*rd)+(gd*gd)+(bd*bd); if ( distance < smallest ) { pixel = i; if ( distance == 0 ) { /* Perfect match! */ break; } smallest = distance; } } return(pixel);}/* Find the opaque pixel value corresponding to an RGB triple */Uint32 GAL_MapRGB(GAL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b){ if ( format->palette == NULL ) { return (r >> format->Rloss) << format->Rshift | (g >> format->Gloss) << format->Gshift | (b >> format->Bloss) << format->Bshift | format->Amask; } else { if (format->DitheredPalette) return GAL_FindDitheredColor (format->BitsPerPixel, r, g, b); else return GAL_FindColor(format->palette, r, g, b); }}/* Find the pixel value corresponding to an RGBA quadruple */Uint32 GAL_MapRGBA(GAL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ if ( format->palette == NULL ) { return (r >> format->Rloss) << format->Rshift | (g >> format->Gloss) << format->Gshift | (b >> format->Bloss) << format->Bshift | ((a >> format->Aloss) << format->Ashift & format->Amask); } else { if (format->DitheredPalette) return GAL_FindDitheredColor (format->BitsPerPixel, r, g, b); else return GAL_FindColor(format->palette, r, g, b); }}void GAL_GetRGBA(Uint32 pixel, GAL_PixelFormat *fmt, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a){ if ( fmt->palette == NULL ) { /* * This makes sure that the result is mapped to the * interval [0..255], and the maximum value for each * component is 255. This is important to make sure * that white is indeed reported as (255, 255, 255), * and that opaque alpha is 255. * This only works for RGB bit fields at least 4 bit * wide, which is almost always the case. */ unsigned rv, gv, bv, av; rv = (pixel & fmt->Rmask) >> fmt->Rshift; *r = (rv << fmt->Rloss) + (rv >> (8 - fmt->Rloss)); gv = (pixel & fmt->Gmask) >> fmt->Gshift; *g = (gv << fmt->Gloss) + (gv >> (8 - fmt->Gloss)); bv = (pixel & fmt->Bmask) >> fmt->Bshift; *b = (bv << fmt->Bloss) + (bv >> (8 - fmt->Bloss)); if(fmt->Amask) { av = (pixel & fmt->Amask) >> fmt->Ashift; *a = (av << fmt->Aloss) + (av >> (8 - fmt->Aloss)); } else *a = GAL_ALPHA_OPAQUE; } else { *r = fmt->palette->colors[pixel].r; *g = fmt->palette->colors[pixel].g; *b = fmt->palette->colors[pixel].b; *a = GAL_ALPHA_OPAQUE; }}void GAL_GetRGB(Uint32 pixel, GAL_PixelFormat *fmt, Uint8 *r,Uint8 *g,Uint8 *b){ if ( fmt->palette == NULL ) { /* the note for GAL_GetRGBA above applies here too */ unsigned rv, gv, bv; rv = (pixel & fmt->Rmask) >> fmt->Rshift; *r = (rv << fmt->Rloss) + (rv >> (8 - fmt->Rloss)); gv = (pixel & fmt->Gmask) >> fmt->Gshift; *g = (gv << fmt->Gloss) + (gv >> (8 - fmt->Gloss)); bv = (pixel & fmt->Bmask) >> fmt->Bshift; *b = (bv << fmt->Bloss) + (bv >> (8 - fmt->Bloss)); } else { *r = fmt->palette->colors[pixel].r; *g = fmt->palette->colors[pixel].g; *b = fmt->palette->colors[pixel].b; }}/* Apply gamma to a set of colors - this is easy. :) */void GAL_ApplyGamma(Uint16 *gamma, GAL_Color *colors, GAL_Color *output, int ncolors){ int i; for ( i=0; i<ncolors; ++i ) { output[i].r = gamma[0*256 + colors[i].r] >> 8; output[i].g = gamma[1*256 + colors[i].g] >> 8; output[i].b = gamma[2*256 + colors[i].b] >> 8; }}/* Map from Palette to Palette */static Uint8 *Map1to1(GAL_Palette *src, GAL_Palette *dst, int *identical){ Uint8 *map; int i; if ( identical ) { if ( src->ncolors <= dst->ncolors ) { /* If an identical palette, no need to map */ if ( memcmp(src->colors, dst->colors, src->ncolors* sizeof(GAL_Color)) == 0 ) { *identical = 1; return(NULL); } } *identical = 0; } map = (Uint8 *)malloc(src->ncolors); if ( map == NULL ) { GAL_OutOfMemory(); return(NULL); } for ( i=0; i<src->ncolors; ++i ) { map[i] = GAL_FindColor(dst, src->colors[i].r, src->colors[i].g, src->colors[i].b); } return(map);}/* Map from Palette to BitField */static Uint8 *Map1toN(GAL_Palette *src, GAL_PixelFormat *dst){ Uint8 *map; int i; int bpp; unsigned alpha; bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel); map = (Uint8 *)malloc(src->ncolors*bpp); if ( map == NULL ) { GAL_OutOfMemory(); return(NULL); } alpha = dst->Amask ? GAL_ALPHA_OPAQUE : 0; /* We memory copy to the pixel map so the endianness is preserved */ for ( i=0; i<src->ncolors; ++i ) { ASSEMBLE_RGBA(&map[i*bpp], dst->BytesPerPixel, dst, src->colors[i].r, src->colors[i].g, src->colors[i].b, alpha); } return(map);}/* Map from BitField to Dithered-Palette to Palette */static Uint8 *MapNto1(GAL_PixelFormat *src, GAL_Palette *dst, int *identical){ /* Generate a 256 color dither palette */ GAL_Palette dithered; GAL_Color colors[256]; dithered.ncolors = 256; GAL_DitherColors(colors, 8); dithered.colors = colors; return(Map1to1(&dithered, dst, identical));}GAL_BlitMap *GAL_AllocBlitMap(void){ GAL_BlitMap *map; /* Allocate the empty map */ map = (GAL_BlitMap *)malloc(sizeof(*map)); if ( map == NULL ) { GAL_OutOfMemory(); return(NULL); } memset(map, 0, sizeof(*map)); /* Allocate the software blit data */ map->sw_data = (struct private_swaccel *)malloc(sizeof(*map->sw_data)); if ( map->sw_data == NULL ) { GAL_FreeBlitMap(map); GAL_OutOfMemory(); return(NULL); } memset(map->sw_data, 0, sizeof(*map->sw_data)); /* It's ready to go */ return(map);}void GAL_InvalidateMap(GAL_BlitMap *map){ if ( ! map ) { return; } map->dst = NULL; map->format_version = (unsigned int)-1; if ( map->table ) { free(map->table); map->table = NULL; }}int GAL_MapSurface (GAL_Surface *src, GAL_Surface *dst){ GAL_PixelFormat *srcfmt; GAL_PixelFormat *dstfmt; GAL_BlitMap *map; /* Clear out any previous mapping */ map = src->map; if ( (src->flags & GAL_RLEACCEL) == GAL_RLEACCEL ) { GAL_UnRLESurface(src, 1); } GAL_InvalidateMap(map); /* Figure out what kind of mapping we're doing */ map->identity = 0; srcfmt = src->format; dstfmt = dst->format; switch (srcfmt->BytesPerPixel) { case 1: switch (dstfmt->BytesPerPixel) { case 1: /* Palette --> Palette */ /* If both GAL_HWSURFACE, assume have same palette */ if ( ((src->flags & GAL_HWSURFACE) == GAL_HWSURFACE) && ((dst->flags & GAL_HWSURFACE) == GAL_HWSURFACE) ) { map->identity = 1; } else { map->table = Map1to1(srcfmt->palette, dstfmt->palette, &map->identity); } if ( ! map->identity ) { if ( map->table == NULL ) { return(-1); } } if (srcfmt->BitsPerPixel!=dstfmt->BitsPerPixel) map->identity = 0; break; default: /* Palette --> BitField */ map->table = Map1toN(srcfmt->palette, dstfmt); if ( map->table == NULL ) { return(-1); } break; } break; default: switch (dstfmt->BytesPerPixel) { case 1: /* BitField --> Palette */ map->table = MapNto1(srcfmt, dstfmt->palette, &map->identity); if ( ! map->identity ) { if ( map->table == NULL ) { return(-1); } } map->identity = 0; /* Don't optimize to copy */ break; default: /* BitField --> BitField */ if ( FORMAT_EQUAL(srcfmt, dstfmt) ) map->identity = 1; break; } break; } map->dst = dst; map->format_version = dst->format_version; /* Choose your blitters wisely */ return(GAL_CalculateBlit(src));}void GAL_FreeBlitMap(GAL_BlitMap *map){ if ( map ) { GAL_InvalidateMap(map); if ( map->sw_data != NULL ) { free(map->sw_data); } free(map); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -