2 Simple DirectMedia Layer
3 Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
21 #include "SDL_config.h"
23 /* General (mostly internal) pixel/color manipulation routines for SDL */
25 #include "SDL_endian.h"
26 #include "SDL_video.h"
27 #include "SDL_sysvideo.h"
29 #include "SDL_pixels_c.h"
30 #include "SDL_RLEaccel_c.h"
33 /* Lookup tables to expand partial bytes to the full 0..255 range */
35 static Uint8 lookup_0[] = {
36 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
39 static Uint8 lookup_1[] = {
40 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 255
43 static Uint8 lookup_2[] = {
44 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218, 222, 226, 230, 234, 238, 242, 246, 250, 255
47 static Uint8 lookup_3[] = {
48 0, 8, 16, 24, 32, 41, 49, 57, 65, 74, 82, 90, 98, 106, 115, 123, 131, 139, 148, 156, 164, 172, 180, 189, 197, 205, 213, 222, 230, 238, 246, 255
51 static Uint8 lookup_4[] = {
52 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255
55 static Uint8 lookup_5[] = {
56 0, 36, 72, 109, 145, 182, 218, 255
59 static Uint8 lookup_6[] = {
63 static Uint8 lookup_7[] = {
67 static Uint8 lookup_8[] = {
71 Uint8* SDL_expand_byte[9] = {
83 /* Helper functions */
86 SDL_GetPixelFormatName(Uint32 format)
89 #define CASE(X) case X: return #X;
90 CASE(SDL_PIXELFORMAT_INDEX1LSB)
91 CASE(SDL_PIXELFORMAT_INDEX1MSB)
92 CASE(SDL_PIXELFORMAT_INDEX4LSB)
93 CASE(SDL_PIXELFORMAT_INDEX4MSB)
94 CASE(SDL_PIXELFORMAT_INDEX8)
95 CASE(SDL_PIXELFORMAT_RGB332)
96 CASE(SDL_PIXELFORMAT_RGB444)
97 CASE(SDL_PIXELFORMAT_RGB555)
98 CASE(SDL_PIXELFORMAT_BGR555)
99 CASE(SDL_PIXELFORMAT_ARGB4444)
100 CASE(SDL_PIXELFORMAT_RGBA4444)
101 CASE(SDL_PIXELFORMAT_ABGR4444)
102 CASE(SDL_PIXELFORMAT_BGRA4444)
103 CASE(SDL_PIXELFORMAT_ARGB1555)
104 CASE(SDL_PIXELFORMAT_RGBA5551)
105 CASE(SDL_PIXELFORMAT_ABGR1555)
106 CASE(SDL_PIXELFORMAT_BGRA5551)
107 CASE(SDL_PIXELFORMAT_RGB565)
108 CASE(SDL_PIXELFORMAT_BGR565)
109 CASE(SDL_PIXELFORMAT_RGB24)
110 CASE(SDL_PIXELFORMAT_BGR24)
111 CASE(SDL_PIXELFORMAT_RGB888)
112 CASE(SDL_PIXELFORMAT_RGBX8888)
113 CASE(SDL_PIXELFORMAT_BGR888)
114 CASE(SDL_PIXELFORMAT_BGRX8888)
115 CASE(SDL_PIXELFORMAT_ARGB8888)
116 CASE(SDL_PIXELFORMAT_RGBA8888)
117 CASE(SDL_PIXELFORMAT_ABGR8888)
118 CASE(SDL_PIXELFORMAT_BGRA8888)
119 CASE(SDL_PIXELFORMAT_ARGB2101010)
120 CASE(SDL_PIXELFORMAT_YV12)
121 CASE(SDL_PIXELFORMAT_IYUV)
122 CASE(SDL_PIXELFORMAT_YUY2)
123 CASE(SDL_PIXELFORMAT_UYVY)
124 CASE(SDL_PIXELFORMAT_YVYU)
127 return "SDL_PIXELFORMAT_UNKNOWN";
132 SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, Uint32 * Rmask,
133 Uint32 * Gmask, Uint32 * Bmask, Uint32 * Amask)
137 /* This function doesn't work with FourCC pixel formats */
138 if (SDL_ISPIXELFORMAT_FOURCC(format)) {
139 SDL_SetError("FOURCC pixel formats are not supported");
143 /* Initialize the values here */
144 if (SDL_BYTESPERPIXEL(format) <= 2) {
145 *bpp = SDL_BITSPERPIXEL(format);
147 *bpp = SDL_BYTESPERPIXEL(format) * 8;
149 *Rmask = *Gmask = *Bmask = *Amask = 0;
151 if (format == SDL_PIXELFORMAT_RGB24) {
152 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
164 if (format == SDL_PIXELFORMAT_BGR24) {
165 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
177 if (SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED8 &&
178 SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED16 &&
179 SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED32) {
180 /* Not a format that uses masks */
184 switch (SDL_PIXELLAYOUT(format)) {
185 case SDL_PACKEDLAYOUT_332:
186 masks[0] = 0x00000000;
187 masks[1] = 0x000000E0;
188 masks[2] = 0x0000001C;
189 masks[3] = 0x00000003;
191 case SDL_PACKEDLAYOUT_4444:
192 masks[0] = 0x0000F000;
193 masks[1] = 0x00000F00;
194 masks[2] = 0x000000F0;
195 masks[3] = 0x0000000F;
197 case SDL_PACKEDLAYOUT_1555:
198 masks[0] = 0x00008000;
199 masks[1] = 0x00007C00;
200 masks[2] = 0x000003E0;
201 masks[3] = 0x0000001F;
203 case SDL_PACKEDLAYOUT_5551:
204 masks[0] = 0x0000F800;
205 masks[1] = 0x000007C0;
206 masks[2] = 0x0000003E;
207 masks[3] = 0x00000001;
209 case SDL_PACKEDLAYOUT_565:
210 masks[0] = 0x00000000;
211 masks[1] = 0x0000F800;
212 masks[2] = 0x000007E0;
213 masks[3] = 0x0000001F;
215 case SDL_PACKEDLAYOUT_8888:
216 masks[0] = 0xFF000000;
217 masks[1] = 0x00FF0000;
218 masks[2] = 0x0000FF00;
219 masks[3] = 0x000000FF;
221 case SDL_PACKEDLAYOUT_2101010:
222 masks[0] = 0xC0000000;
223 masks[1] = 0x3FF00000;
224 masks[2] = 0x000FFC00;
225 masks[3] = 0x000003FF;
227 case SDL_PACKEDLAYOUT_1010102:
228 masks[0] = 0xFFC00000;
229 masks[1] = 0x003FF000;
230 masks[2] = 0x00000FFC;
231 masks[3] = 0x00000003;
234 SDL_SetError("Unknown pixel format");
238 switch (SDL_PIXELORDER(format)) {
239 case SDL_PACKEDORDER_XRGB:
244 case SDL_PACKEDORDER_RGBX:
249 case SDL_PACKEDORDER_ARGB:
255 case SDL_PACKEDORDER_RGBA:
261 case SDL_PACKEDORDER_XBGR:
266 case SDL_PACKEDORDER_BGRX:
271 case SDL_PACKEDORDER_BGRA:
277 case SDL_PACKEDORDER_ABGR:
284 SDL_SetError("Unknown pixel format");
291 SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask,
296 /* SDL defaults to MSB ordering */
297 return SDL_PIXELFORMAT_INDEX1MSB;
299 /* SDL defaults to MSB ordering */
300 return SDL_PIXELFORMAT_INDEX4MSB;
303 return SDL_PIXELFORMAT_INDEX8;
309 return SDL_PIXELFORMAT_RGB332;
314 return SDL_PIXELFORMAT_RGB444;
316 if (Rmask == 0x0F00 &&
320 return SDL_PIXELFORMAT_RGB444;
325 return SDL_PIXELFORMAT_RGB555;
327 /* Fall through to 16-bit checks */
330 return SDL_PIXELFORMAT_RGB565;
332 if (Rmask == 0x7C00 &&
336 return SDL_PIXELFORMAT_RGB555;
338 if (Rmask == 0x001F &&
342 return SDL_PIXELFORMAT_BGR555;
344 if (Rmask == 0x0F00 &&
348 return SDL_PIXELFORMAT_ARGB4444;
350 if (Rmask == 0xF000 &&
354 return SDL_PIXELFORMAT_RGBA4444;
356 if (Rmask == 0x000F &&
360 return SDL_PIXELFORMAT_ABGR4444;
362 if (Rmask == 0x00F0 &&
366 return SDL_PIXELFORMAT_BGRA4444;
368 if (Rmask == 0x7C00 &&
372 return SDL_PIXELFORMAT_ARGB1555;
374 if (Rmask == 0xF800 &&
378 return SDL_PIXELFORMAT_RGBA5551;
380 if (Rmask == 0x001F &&
384 return SDL_PIXELFORMAT_ABGR1555;
386 if (Rmask == 0x003E &&
390 return SDL_PIXELFORMAT_BGRA5551;
392 if (Rmask == 0xF800 &&
396 return SDL_PIXELFORMAT_RGB565;
398 if (Rmask == 0x001F &&
402 return SDL_PIXELFORMAT_BGR565;
409 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
410 return SDL_PIXELFORMAT_RGB24;
412 return SDL_PIXELFORMAT_BGR24;
415 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
416 return SDL_PIXELFORMAT_BGR24;
418 return SDL_PIXELFORMAT_RGB24;
423 return SDL_PIXELFORMAT_RGB888;
425 if (Rmask == 0x00FF0000 &&
426 Gmask == 0x0000FF00 &&
427 Bmask == 0x000000FF &&
428 Amask == 0x00000000) {
429 return SDL_PIXELFORMAT_RGB888;
431 if (Rmask == 0xFF000000 &&
432 Gmask == 0x00FF0000 &&
433 Bmask == 0x0000FF00 &&
434 Amask == 0x00000000) {
435 return SDL_PIXELFORMAT_RGBX8888;
437 if (Rmask == 0x000000FF &&
438 Gmask == 0x0000FF00 &&
439 Bmask == 0x00FF0000 &&
440 Amask == 0x00000000) {
441 return SDL_PIXELFORMAT_BGR888;
443 if (Rmask == 0x0000FF00 &&
444 Gmask == 0x00FF0000 &&
445 Bmask == 0xFF000000 &&
446 Amask == 0x00000000) {
447 return SDL_PIXELFORMAT_BGRX8888;
449 if (Rmask == 0x00FF0000 &&
450 Gmask == 0x0000FF00 &&
451 Bmask == 0x000000FF &&
452 Amask == 0xFF000000) {
453 return SDL_PIXELFORMAT_ARGB8888;
455 if (Rmask == 0xFF000000 &&
456 Gmask == 0x00FF0000 &&
457 Bmask == 0x0000FF00 &&
458 Amask == 0x000000FF) {
459 return SDL_PIXELFORMAT_RGBA8888;
461 if (Rmask == 0x000000FF &&
462 Gmask == 0x0000FF00 &&
463 Bmask == 0x00FF0000 &&
464 Amask == 0xFF000000) {
465 return SDL_PIXELFORMAT_ABGR8888;
467 if (Rmask == 0x0000FF00 &&
468 Gmask == 0x00FF0000 &&
469 Bmask == 0xFF000000 &&
470 Amask == 0x000000FF) {
471 return SDL_PIXELFORMAT_BGRA8888;
473 if (Rmask == 0x3FF00000 &&
474 Gmask == 0x000FFC00 &&
475 Bmask == 0x000003FF &&
476 Amask == 0xC0000000) {
477 return SDL_PIXELFORMAT_ARGB2101010;
480 return SDL_PIXELFORMAT_UNKNOWN;
483 static SDL_PixelFormat *formats;
486 SDL_AllocFormat(Uint32 pixel_format)
488 SDL_PixelFormat *format;
490 /* Look it up in our list of previously allocated formats */
491 for (format = formats; format; format = format->next) {
492 if (pixel_format == format->format) {
498 /* Allocate an empty pixel format structure, and initialize it */
499 format = SDL_malloc(sizeof(*format));
500 if (format == NULL) {
504 if (SDL_InitFormat(format, pixel_format) < 0) {
509 if (!SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
510 /* Cache the RGB formats */
511 format->next = formats;
518 SDL_InitFormat(SDL_PixelFormat * format, Uint32 pixel_format)
521 Uint32 Rmask, Gmask, Bmask, Amask;
524 if (!SDL_PixelFormatEnumToMasks(pixel_format, &bpp,
525 &Rmask, &Gmask, &Bmask, &Amask)) {
529 /* Set up the format */
531 format->format = pixel_format;
532 format->BitsPerPixel = bpp;
533 format->BytesPerPixel = (bpp + 7) / 8;
535 format->Rmask = Rmask;
539 for (mask = Rmask; !(mask & 0x01); mask >>= 1)
541 for (; (mask & 0x01); mask >>= 1)
545 format->Gmask = Gmask;
549 for (mask = Gmask; !(mask & 0x01); mask >>= 1)
551 for (; (mask & 0x01); mask >>= 1)
555 format->Bmask = Bmask;
559 for (mask = Bmask; !(mask & 0x01); mask >>= 1)
561 for (; (mask & 0x01); mask >>= 1)
565 format->Amask = Amask;
569 for (mask = Amask; !(mask & 0x01); mask >>= 1)
571 for (; (mask & 0x01); mask >>= 1)
575 format->palette = NULL;
576 format->refcount = 1;
583 SDL_FreeFormat(SDL_PixelFormat *format)
585 SDL_PixelFormat *prev;
590 if (--format->refcount > 0) {
594 /* Remove this format from our list */
595 if (format == formats) {
596 formats = format->next;
597 } else if (formats) {
598 for (prev = formats; prev->next; prev = prev->next) {
599 if (prev->next == format) {
600 prev->next = format->next;
606 if (format->palette) {
607 SDL_FreePalette(format->palette);
613 SDL_AllocPalette(int ncolors)
615 SDL_Palette *palette;
617 palette = (SDL_Palette *) SDL_malloc(sizeof(*palette));
623 (SDL_Color *) SDL_malloc(ncolors * sizeof(*palette->colors));
624 if (!palette->colors) {
628 palette->ncolors = ncolors;
629 palette->version = 1;
630 palette->refcount = 1;
632 SDL_memset(palette->colors, 0xFF, ncolors * sizeof(*palette->colors));
638 SDL_SetPixelFormatPalette(SDL_PixelFormat * format, SDL_Palette *palette)
641 SDL_SetError("SDL_SetPixelFormatPalette() passed NULL format");
645 if (palette && palette->ncolors != (1 << format->BitsPerPixel)) {
646 SDL_SetError("SDL_SetPixelFormatPalette() passed a palette that doesn't match the format");
650 if (format->palette == palette) {
654 if (format->palette) {
655 SDL_FreePalette(format->palette);
658 format->palette = palette;
660 if (format->palette) {
661 ++format->palette->refcount;
668 SDL_SetPaletteColors(SDL_Palette * palette, const SDL_Color * colors,
669 int firstcolor, int ncolors)
673 /* Verify the parameters */
677 if (ncolors > (palette->ncolors - firstcolor)) {
678 ncolors = (palette->ncolors - firstcolor);
682 if (colors != (palette->colors + firstcolor)) {
683 SDL_memcpy(palette->colors + firstcolor, colors,
684 ncolors * sizeof(*colors));
687 if (!palette->version) {
688 palette->version = 1;
695 SDL_FreePalette(SDL_Palette * palette)
700 if (--palette->refcount > 0) {
703 if (palette->colors) {
704 SDL_free(palette->colors);
710 * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors
713 SDL_DitherColors(SDL_Color * colors, int bpp)
717 return; /* only 8bpp supported right now */
719 for (i = 0; i < 256; i++) {
721 /* map each bit field to the full [0, 255] interval,
722 so 0 is mapped to (0, 0, 0) and 255 to (255, 255, 255) */
724 r |= r >> 3 | r >> 6;
727 g |= g >> 3 | g >> 6;
733 colors[i].unused = SDL_ALPHA_OPAQUE;
738 * Calculate the pad-aligned scanline width of a surface
741 SDL_CalculatePitch(SDL_Surface * surface)
745 /* Surface should be 4-byte aligned for speed */
746 pitch = surface->w * surface->format->BytesPerPixel;
747 switch (surface->format->BitsPerPixel) {
749 pitch = (pitch + 7) / 8;
752 pitch = (pitch + 1) / 2;
757 pitch = (pitch + 3) & ~3; /* 4-byte aligning */
762 * Match an RGB value to a particular palette index
765 SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b)
767 /* Do colorspace distance matching */
768 unsigned int smallest;
769 unsigned int distance;
775 for (i = 0; i < pal->ncolors; ++i) {
776 rd = pal->colors[i].r - r;
777 gd = pal->colors[i].g - g;
778 bd = pal->colors[i].b - b;
779 distance = (rd * rd) + (gd * gd) + (bd * bd);
780 if (distance < smallest) {
782 if (distance == 0) { /* Perfect match! */
791 /* Find the opaque pixel value corresponding to an RGB triple */
793 SDL_MapRGB(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b)
795 if (format->palette == NULL) {
796 return (r >> format->Rloss) << format->Rshift
797 | (g >> format->Gloss) << format->Gshift
798 | (b >> format->Bloss) << format->Bshift | format->Amask;
800 return SDL_FindColor(format->palette, r, g, b);
804 /* Find the pixel value corresponding to an RGBA quadruple */
806 SDL_MapRGBA(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b,
809 if (format->palette == NULL) {
810 return (r >> format->Rloss) << format->Rshift
811 | (g >> format->Gloss) << format->Gshift
812 | (b >> format->Bloss) << format->Bshift
813 | ((a >> format->Aloss) << format->Ashift & format->Amask);
815 return SDL_FindColor(format->palette, r, g, b);
820 SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat * format, Uint8 * r, Uint8 * g,
823 if (format->palette == NULL) {
825 v = (pixel & format->Rmask) >> format->Rshift;
826 *r = SDL_expand_byte[format->Rloss][v];
827 v = (pixel & format->Gmask) >> format->Gshift;
828 *g = SDL_expand_byte[format->Gloss][v];
829 v = (pixel & format->Bmask) >> format->Bshift;
830 *b = SDL_expand_byte[format->Bloss][v];
832 if (pixel < (unsigned)format->palette->ncolors) {
833 *r = format->palette->colors[pixel].r;
834 *g = format->palette->colors[pixel].g;
835 *b = format->palette->colors[pixel].b;
843 SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat * format,
844 Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a)
846 if (format->palette == NULL) {
848 v = (pixel & format->Rmask) >> format->Rshift;
849 *r = SDL_expand_byte[format->Rloss][v];
850 v = (pixel & format->Gmask) >> format->Gshift;
851 *g = SDL_expand_byte[format->Gloss][v];
852 v = (pixel & format->Bmask) >> format->Bshift;
853 *b = SDL_expand_byte[format->Bloss][v];
854 v = (pixel & format->Amask) >> format->Ashift;
855 *a = SDL_expand_byte[format->Aloss][v];
857 if (pixel < (unsigned)format->palette->ncolors) {
858 *r = format->palette->colors[pixel].r;
859 *g = format->palette->colors[pixel].g;
860 *b = format->palette->colors[pixel].b;
861 *a = SDL_ALPHA_OPAQUE;
863 *r = *g = *b = *a = 0;
868 /* Map from Palette to Palette */
870 Map1to1(SDL_Palette * src, SDL_Palette * dst, int *identical)
876 if (src->ncolors <= dst->ncolors) {
877 /* If an identical palette, no need to map */
881 (src->colors, dst->colors,
882 src->ncolors * sizeof(SDL_Color)) == 0)) {
889 map = (Uint8 *) SDL_malloc(src->ncolors);
894 for (i = 0; i < src->ncolors; ++i) {
895 map[i] = SDL_FindColor(dst,
896 src->colors[i].r, src->colors[i].g,
902 /* Map from Palette to BitField */
904 Map1toN(SDL_PixelFormat * src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod,
905 SDL_PixelFormat * dst)
910 SDL_Palette *pal = src->palette;
912 bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel);
913 map = (Uint8 *) SDL_malloc(pal->ncolors * bpp);
919 /* We memory copy to the pixel map so the endianness is preserved */
920 for (i = 0; i < pal->ncolors; ++i) {
922 Uint8 R = (Uint8) ((pal->colors[i].r * Rmod) / 255);
923 Uint8 G = (Uint8) ((pal->colors[i].g * Gmod) / 255);
924 Uint8 B = (Uint8) ((pal->colors[i].b * Bmod) / 255);
925 ASSEMBLE_RGBA(&map[i * bpp], dst->BytesPerPixel, dst, R, G, B, A);
930 /* Map from BitField to Dithered-Palette to Palette */
932 MapNto1(SDL_PixelFormat * src, SDL_PixelFormat * dst, int *identical)
934 /* Generate a 256 color dither palette */
935 SDL_Palette dithered;
936 SDL_Color colors[256];
937 SDL_Palette *pal = dst->palette;
939 dithered.ncolors = 256;
940 SDL_DitherColors(colors, 8);
941 dithered.colors = colors;
942 return (Map1to1(&dithered, pal, identical));
946 SDL_AllocBlitMap(void)
950 /* Allocate the empty map */
951 map = (SDL_BlitMap *) SDL_calloc(1, sizeof(*map));
961 /* It's ready to go */
966 SDL_InvalidateMap(SDL_BlitMap * map)
972 map->src_palette_version = 0;
973 map->dst_palette_version = 0;
974 if (map->info.table) {
975 SDL_free(map->info.table);
976 map->info.table = NULL;
981 SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst)
983 SDL_PixelFormat *srcfmt;
984 SDL_PixelFormat *dstfmt;
987 /* Clear out any previous mapping */
989 if ((src->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
990 SDL_UnRLESurface(src, 1);
992 SDL_InvalidateMap(map);
994 /* Figure out what kind of mapping we're doing */
996 srcfmt = src->format;
997 dstfmt = dst->format;
998 if (SDL_ISPIXELFORMAT_INDEXED(srcfmt->format)) {
999 if (SDL_ISPIXELFORMAT_INDEXED(dstfmt->format)) {
1000 /* Palette --> Palette */
1002 Map1to1(srcfmt->palette, dstfmt->palette, &map->identity);
1003 if (!map->identity) {
1004 if (map->info.table == NULL) {
1008 if (srcfmt->BitsPerPixel != dstfmt->BitsPerPixel)
1011 /* Palette --> BitField */
1013 Map1toN(srcfmt, src->map->info.r, src->map->info.g,
1014 src->map->info.b, src->map->info.a, dstfmt);
1015 if (map->info.table == NULL) {
1020 if (SDL_ISPIXELFORMAT_INDEXED(dstfmt->format)) {
1021 /* BitField --> Palette */
1022 map->info.table = MapNto1(srcfmt, dstfmt, &map->identity);
1023 if (!map->identity) {
1024 if (map->info.table == NULL) {
1028 map->identity = 0; /* Don't optimize to copy */
1030 /* BitField --> BitField */
1031 if (srcfmt == dstfmt) {
1039 if (dstfmt->palette) {
1040 map->dst_palette_version = dstfmt->palette->version;
1042 map->dst_palette_version = 0;
1045 if (srcfmt->palette) {
1046 map->src_palette_version = srcfmt->palette->version;
1048 map->src_palette_version = 0;
1051 /* Choose your blitters wisely */
1052 return (SDL_CalculateBlit(src));
1056 SDL_FreeBlitMap(SDL_BlitMap * map)
1059 SDL_InvalidateMap(map);
1065 SDL_CalculateGammaRamp(float gamma, Uint16 * ramp)
1069 /* 0.0 gamma is all black */
1070 if (gamma <= 0.0f) {
1071 for (i = 0; i < 256; ++i) {
1075 } else if (gamma == 1.0f) {
1076 /* 1.0 gamma is identity */
1077 for (i = 0; i < 256; ++i) {
1078 ramp[i] = (i << 8) | i;
1082 /* Calculate a real gamma ramp */
1084 gamma = 1.0f / gamma;
1085 for (i = 0; i < 256; ++i) {
1087 (int) (SDL_pow((double) i / 256.0, gamma) * 65535.0 + 0.5);
1088 if (value > 65535) {
1091 ramp[i] = (Uint16) value;
1096 /* vi: set ts=4 sw=4 expandtab: */