zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_pixels.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4 
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.
8 
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:
12 
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.
20 */
21 #include "SDL_config.h"
22 
23 /* General (mostly internal) pixel/color manipulation routines for SDL */
24 
25 #include "SDL_endian.h"
26 #include "SDL_video.h"
27 #include "SDL_sysvideo.h"
28 #include "SDL_blit.h"
29 #include "SDL_pixels_c.h"
30 #include "SDL_RLEaccel_c.h"
31 
32 
33 /* Lookup tables to expand partial bytes to the full 0..255 range */
34 
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
37 };
38 
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
41 };
42 
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
45 };
46 
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
49 };
50 
51 static Uint8 lookup_4[] = {
52 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255
53 };
54 
55 static Uint8 lookup_5[] = {
56 0, 36, 72, 109, 145, 182, 218, 255
57 };
58 
59 static Uint8 lookup_6[] = {
60 0, 85, 170, 255
61 };
62 
63 static Uint8 lookup_7[] = {
64 0, 255
65 };
66 
67 static Uint8 lookup_8[] = {
68 255
69 };
70 
72  lookup_0,
73  lookup_1,
74  lookup_2,
75  lookup_3,
76  lookup_4,
77  lookup_5,
78  lookup_6,
79  lookup_7,
80  lookup_8
81 };
82 
83 /* Helper functions */
84 
85 const char*
87 {
88  switch (format) {
89 #define CASE(X) case X: return #X;
125 #undef CASE
126  default:
127  return "SDL_PIXELFORMAT_UNKNOWN";
128  }
129 }
130 
131 SDL_bool
133  Uint32 * Gmask, Uint32 * Bmask, Uint32 * Amask)
134 {
135  Uint32 masks[4];
136 
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");
140  return SDL_FALSE;
141  }
142 
143  /* Initialize the values here */
144  if (SDL_BYTESPERPIXEL(format) <= 2) {
145  *bpp = SDL_BITSPERPIXEL(format);
146  } else {
147  *bpp = SDL_BYTESPERPIXEL(format) * 8;
148  }
149  *Rmask = *Gmask = *Bmask = *Amask = 0;
150 
151  if (format == SDL_PIXELFORMAT_RGB24) {
152 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
153  *Rmask = 0x00FF0000;
154  *Gmask = 0x0000FF00;
155  *Bmask = 0x000000FF;
156 #else
157  *Rmask = 0x000000FF;
158  *Gmask = 0x0000FF00;
159  *Bmask = 0x00FF0000;
160 #endif
161  return SDL_TRUE;
162  }
163 
164  if (format == SDL_PIXELFORMAT_BGR24) {
165 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
166  *Rmask = 0x000000FF;
167  *Gmask = 0x0000FF00;
168  *Bmask = 0x00FF0000;
169 #else
170  *Rmask = 0x00FF0000;
171  *Gmask = 0x0000FF00;
172  *Bmask = 0x000000FF;
173 #endif
174  return SDL_TRUE;
175  }
176 
177  if (SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED8 &&
180  /* Not a format that uses masks */
181  return SDL_TRUE;
182  }
183 
184  switch (SDL_PIXELLAYOUT(format)) {
186  masks[0] = 0x00000000;
187  masks[1] = 0x000000E0;
188  masks[2] = 0x0000001C;
189  masks[3] = 0x00000003;
190  break;
192  masks[0] = 0x0000F000;
193  masks[1] = 0x00000F00;
194  masks[2] = 0x000000F0;
195  masks[3] = 0x0000000F;
196  break;
198  masks[0] = 0x00008000;
199  masks[1] = 0x00007C00;
200  masks[2] = 0x000003E0;
201  masks[3] = 0x0000001F;
202  break;
204  masks[0] = 0x0000F800;
205  masks[1] = 0x000007C0;
206  masks[2] = 0x0000003E;
207  masks[3] = 0x00000001;
208  break;
210  masks[0] = 0x00000000;
211  masks[1] = 0x0000F800;
212  masks[2] = 0x000007E0;
213  masks[3] = 0x0000001F;
214  break;
216  masks[0] = 0xFF000000;
217  masks[1] = 0x00FF0000;
218  masks[2] = 0x0000FF00;
219  masks[3] = 0x000000FF;
220  break;
222  masks[0] = 0xC0000000;
223  masks[1] = 0x3FF00000;
224  masks[2] = 0x000FFC00;
225  masks[3] = 0x000003FF;
226  break;
228  masks[0] = 0xFFC00000;
229  masks[1] = 0x003FF000;
230  masks[2] = 0x00000FFC;
231  masks[3] = 0x00000003;
232  break;
233  default:
234  SDL_SetError("Unknown pixel format");
235  return SDL_FALSE;
236  }
237 
238  switch (SDL_PIXELORDER(format)) {
240  *Rmask = masks[1];
241  *Gmask = masks[2];
242  *Bmask = masks[3];
243  break;
245  *Rmask = masks[0];
246  *Gmask = masks[1];
247  *Bmask = masks[2];
248  break;
250  *Amask = masks[0];
251  *Rmask = masks[1];
252  *Gmask = masks[2];
253  *Bmask = masks[3];
254  break;
256  *Rmask = masks[0];
257  *Gmask = masks[1];
258  *Bmask = masks[2];
259  *Amask = masks[3];
260  break;
262  *Bmask = masks[1];
263  *Gmask = masks[2];
264  *Rmask = masks[3];
265  break;
267  *Bmask = masks[0];
268  *Gmask = masks[1];
269  *Rmask = masks[2];
270  break;
272  *Bmask = masks[0];
273  *Gmask = masks[1];
274  *Rmask = masks[2];
275  *Amask = masks[3];
276  break;
278  *Amask = masks[0];
279  *Bmask = masks[1];
280  *Gmask = masks[2];
281  *Rmask = masks[3];
282  break;
283  default:
284  SDL_SetError("Unknown pixel format");
285  return SDL_FALSE;
286  }
287  return SDL_TRUE;
288 }
289 
290 Uint32
291 SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask,
292  Uint32 Amask)
293 {
294  switch (bpp) {
295  case 1:
296  /* SDL defaults to MSB ordering */
298  case 4:
299  /* SDL defaults to MSB ordering */
301  case 8:
302  if (Rmask == 0) {
303  return SDL_PIXELFORMAT_INDEX8;
304  }
305  if (Rmask == 0xE0 &&
306  Gmask == 0x1C &&
307  Bmask == 0x03 &&
308  Amask == 0x00) {
309  return SDL_PIXELFORMAT_RGB332;
310  }
311  break;
312  case 12:
313  if (Rmask == 0) {
314  return SDL_PIXELFORMAT_RGB444;
315  }
316  if (Rmask == 0x0F00 &&
317  Gmask == 0x00F0 &&
318  Bmask == 0x000F &&
319  Amask == 0x0000) {
320  return SDL_PIXELFORMAT_RGB444;
321  }
322  break;
323  case 15:
324  if (Rmask == 0) {
325  return SDL_PIXELFORMAT_RGB555;
326  }
327  /* Fall through to 16-bit checks */
328  case 16:
329  if (Rmask == 0) {
330  return SDL_PIXELFORMAT_RGB565;
331  }
332  if (Rmask == 0x7C00 &&
333  Gmask == 0x03E0 &&
334  Bmask == 0x001F &&
335  Amask == 0x0000) {
336  return SDL_PIXELFORMAT_RGB555;
337  }
338  if (Rmask == 0x001F &&
339  Gmask == 0x03E0 &&
340  Bmask == 0x7C00 &&
341  Amask == 0x0000) {
342  return SDL_PIXELFORMAT_BGR555;
343  }
344  if (Rmask == 0x0F00 &&
345  Gmask == 0x00F0 &&
346  Bmask == 0x000F &&
347  Amask == 0xF000) {
349  }
350  if (Rmask == 0xF000 &&
351  Gmask == 0x0F00 &&
352  Bmask == 0x00F0 &&
353  Amask == 0x000F) {
355  }
356  if (Rmask == 0x000F &&
357  Gmask == 0x00F0 &&
358  Bmask == 0x0F00 &&
359  Amask == 0xF000) {
361  }
362  if (Rmask == 0x00F0 &&
363  Gmask == 0x0F00 &&
364  Bmask == 0xF000 &&
365  Amask == 0x000F) {
367  }
368  if (Rmask == 0x7C00 &&
369  Gmask == 0x03E0 &&
370  Bmask == 0x001F &&
371  Amask == 0x8000) {
373  }
374  if (Rmask == 0xF800 &&
375  Gmask == 0x07C0 &&
376  Bmask == 0x003E &&
377  Amask == 0x0001) {
379  }
380  if (Rmask == 0x001F &&
381  Gmask == 0x03E0 &&
382  Bmask == 0x7C00 &&
383  Amask == 0x8000) {
385  }
386  if (Rmask == 0x003E &&
387  Gmask == 0x07C0 &&
388  Bmask == 0xF800 &&
389  Amask == 0x0001) {
391  }
392  if (Rmask == 0xF800 &&
393  Gmask == 0x07E0 &&
394  Bmask == 0x001F &&
395  Amask == 0x0000) {
396  return SDL_PIXELFORMAT_RGB565;
397  }
398  if (Rmask == 0x001F &&
399  Gmask == 0x07E0 &&
400  Bmask == 0xF800 &&
401  Amask == 0x0000) {
402  return SDL_PIXELFORMAT_BGR565;
403  }
404  break;
405  case 24:
406  switch (Rmask) {
407  case 0:
408  case 0x00FF0000:
409 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
410  return SDL_PIXELFORMAT_RGB24;
411 #else
412  return SDL_PIXELFORMAT_BGR24;
413 #endif
414  case 0x000000FF:
415 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
416  return SDL_PIXELFORMAT_BGR24;
417 #else
418  return SDL_PIXELFORMAT_RGB24;
419 #endif
420  }
421  case 32:
422  if (Rmask == 0) {
423  return SDL_PIXELFORMAT_RGB888;
424  }
425  if (Rmask == 0x00FF0000 &&
426  Gmask == 0x0000FF00 &&
427  Bmask == 0x000000FF &&
428  Amask == 0x00000000) {
429  return SDL_PIXELFORMAT_RGB888;
430  }
431  if (Rmask == 0xFF000000 &&
432  Gmask == 0x00FF0000 &&
433  Bmask == 0x0000FF00 &&
434  Amask == 0x00000000) {
436  }
437  if (Rmask == 0x000000FF &&
438  Gmask == 0x0000FF00 &&
439  Bmask == 0x00FF0000 &&
440  Amask == 0x00000000) {
441  return SDL_PIXELFORMAT_BGR888;
442  }
443  if (Rmask == 0x0000FF00 &&
444  Gmask == 0x00FF0000 &&
445  Bmask == 0xFF000000 &&
446  Amask == 0x00000000) {
448  }
449  if (Rmask == 0x00FF0000 &&
450  Gmask == 0x0000FF00 &&
451  Bmask == 0x000000FF &&
452  Amask == 0xFF000000) {
454  }
455  if (Rmask == 0xFF000000 &&
456  Gmask == 0x00FF0000 &&
457  Bmask == 0x0000FF00 &&
458  Amask == 0x000000FF) {
460  }
461  if (Rmask == 0x000000FF &&
462  Gmask == 0x0000FF00 &&
463  Bmask == 0x00FF0000 &&
464  Amask == 0xFF000000) {
466  }
467  if (Rmask == 0x0000FF00 &&
468  Gmask == 0x00FF0000 &&
469  Bmask == 0xFF000000 &&
470  Amask == 0x000000FF) {
472  }
473  if (Rmask == 0x3FF00000 &&
474  Gmask == 0x000FFC00 &&
475  Bmask == 0x000003FF &&
476  Amask == 0xC0000000) {
478  }
479  }
481 }
482 
484 
486 SDL_AllocFormat(Uint32 pixel_format)
487 {
489 
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) {
493  ++format->refcount;
494  return format;
495  }
496  }
497 
498  /* Allocate an empty pixel format structure, and initialize it */
499  format = SDL_malloc(sizeof(*format));
500  if (format == NULL) {
501  SDL_OutOfMemory();
502  return NULL;
503  }
504  if (SDL_InitFormat(format, pixel_format) < 0) {
505  SDL_free(format);
506  SDL_InvalidParamError("format");
507  return NULL;
508  }
509 
510  if (!SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
511  /* Cache the RGB formats */
512  format->next = formats;
513  formats = format;
514  }
515  return format;
516 }
517 
518 int
520 {
521  int bpp;
522  Uint32 Rmask, Gmask, Bmask, Amask;
523  Uint32 mask;
524 
525  if (!SDL_PixelFormatEnumToMasks(pixel_format, &bpp,
526  &Rmask, &Gmask, &Bmask, &Amask)) {
527  return -1;
528  }
529 
530  /* Set up the format */
531  SDL_zerop(format);
532  format->format = pixel_format;
533  format->BitsPerPixel = bpp;
534  format->BytesPerPixel = (bpp + 7) / 8;
535 
536  format->Rmask = Rmask;
537  format->Rshift = 0;
538  format->Rloss = 8;
539  if (Rmask) {
540  for (mask = Rmask; !(mask & 0x01); mask >>= 1)
541  ++format->Rshift;
542  for (; (mask & 0x01); mask >>= 1)
543  --format->Rloss;
544  }
545 
546  format->Gmask = Gmask;
547  format->Gshift = 0;
548  format->Gloss = 8;
549  if (Gmask) {
550  for (mask = Gmask; !(mask & 0x01); mask >>= 1)
551  ++format->Gshift;
552  for (; (mask & 0x01); mask >>= 1)
553  --format->Gloss;
554  }
555 
556  format->Bmask = Bmask;
557  format->Bshift = 0;
558  format->Bloss = 8;
559  if (Bmask) {
560  for (mask = Bmask; !(mask & 0x01); mask >>= 1)
561  ++format->Bshift;
562  for (; (mask & 0x01); mask >>= 1)
563  --format->Bloss;
564  }
565 
566  format->Amask = Amask;
567  format->Ashift = 0;
568  format->Aloss = 8;
569  if (Amask) {
570  for (mask = Amask; !(mask & 0x01); mask >>= 1)
571  ++format->Ashift;
572  for (; (mask & 0x01); mask >>= 1)
573  --format->Aloss;
574  }
575 
576  format->palette = NULL;
577  format->refcount = 1;
578  format->next = NULL;
579 
580  return 0;
581 }
582 
583 void
585 {
586  SDL_PixelFormat *prev;
587 
588  if (!format) {
589  SDL_InvalidParamError("format");
590  return;
591  }
592  if (--format->refcount > 0) {
593  return;
594  }
595 
596  /* Remove this format from our list */
597  if (format == formats) {
598  formats = format->next;
599  } else if (formats) {
600  for (prev = formats; prev->next; prev = prev->next) {
601  if (prev->next == format) {
602  prev->next = format->next;
603  break;
604  }
605  }
606  }
607 
608  if (format->palette) {
609  SDL_FreePalette(format->palette);
610  }
611  SDL_free(format);
612 }
613 
614 SDL_Palette *
615 SDL_AllocPalette(int ncolors)
616 {
617  SDL_Palette *palette;
618 
619  /* Input validation */
620  if (ncolors < 1) {
621  SDL_InvalidParamError("ncolors");
622  return NULL;
623  }
624 
625  palette = (SDL_Palette *) SDL_malloc(sizeof(*palette));
626  if (!palette) {
627  SDL_OutOfMemory();
628  return NULL;
629  }
630  palette->colors =
631  (SDL_Color *) SDL_malloc(ncolors * sizeof(*palette->colors));
632  if (!palette->colors) {
633  SDL_free(palette);
634  return NULL;
635  }
636  palette->ncolors = ncolors;
637  palette->version = 1;
638  palette->refcount = 1;
639 
640  SDL_memset(palette->colors, 0xFF, ncolors * sizeof(*palette->colors));
641 
642  return palette;
643 }
644 
645 int
647 {
648  if (!format) {
649  return SDL_SetError("SDL_SetPixelFormatPalette() passed NULL format");
650  }
651 
652  if (palette && palette->ncolors != (1 << format->BitsPerPixel)) {
653  return SDL_SetError("SDL_SetPixelFormatPalette() passed a palette that doesn't match the format");
654  }
655 
656  if (format->palette == palette) {
657  return 0;
658  }
659 
660  if (format->palette) {
661  SDL_FreePalette(format->palette);
662  }
663 
664  format->palette = palette;
665 
666  if (format->palette) {
667  ++format->palette->refcount;
668  }
669 
670  return 0;
671 }
672 
673 int
675  int firstcolor, int ncolors)
676 {
677  int status = 0;
678 
679  /* Verify the parameters */
680  if (!palette) {
681  return -1;
682  }
683  if (ncolors > (palette->ncolors - firstcolor)) {
684  ncolors = (palette->ncolors - firstcolor);
685  status = -1;
686  }
687 
688  if (colors != (palette->colors + firstcolor)) {
689  SDL_memcpy(palette->colors + firstcolor, colors,
690  ncolors * sizeof(*colors));
691  }
692  ++palette->version;
693  if (!palette->version) {
694  palette->version = 1;
695  }
696 
697  return status;
698 }
699 
700 void
702 {
703  if (!palette) {
704  SDL_InvalidParamError("palette");
705  return;
706  }
707  if (--palette->refcount > 0) {
708  return;
709  }
710  SDL_free(palette->colors);
711  SDL_free(palette);
712 }
713 
714 /*
715  * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors
716  */
717 void
719 {
720  int i;
721  if (bpp != 8)
722  return; /* only 8bpp supported right now */
723 
724  for (i = 0; i < 256; i++) {
725  int r, g, b;
726  /* map each bit field to the full [0, 255] interval,
727  so 0 is mapped to (0, 0, 0) and 255 to (255, 255, 255) */
728  r = i & 0xe0;
729  r |= r >> 3 | r >> 6;
730  colors[i].r = r;
731  g = (i << 3) & 0xe0;
732  g |= g >> 3 | g >> 6;
733  colors[i].g = g;
734  b = i & 0x3;
735  b |= b << 2;
736  b |= b << 4;
737  colors[i].b = b;
738  colors[i].a = SDL_ALPHA_OPAQUE;
739  }
740 }
741 
742 /*
743  * Calculate the pad-aligned scanline width of a surface
744  */
745 int
747 {
748  int pitch;
749 
750  /* Surface should be 4-byte aligned for speed */
751  pitch = surface->w * surface->format->BytesPerPixel;
752  switch (surface->format->BitsPerPixel) {
753  case 1:
754  pitch = (pitch + 7) / 8;
755  break;
756  case 4:
757  pitch = (pitch + 1) / 2;
758  break;
759  default:
760  break;
761  }
762  pitch = (pitch + 3) & ~3; /* 4-byte aligning */
763  return (pitch);
764 }
765 
766 /*
767  * Match an RGB value to a particular palette index
768  */
769 Uint8
771 {
772  /* Do colorspace distance matching */
773  unsigned int smallest;
774  unsigned int distance;
775  int rd, gd, bd, ad;
776  int i;
777  Uint8 pixel = 0;
778 
779  smallest = ~0;
780  for (i = 0; i < pal->ncolors; ++i) {
781  rd = pal->colors[i].r - r;
782  gd = pal->colors[i].g - g;
783  bd = pal->colors[i].b - b;
784  ad = pal->colors[i].a - a;
785  distance = (rd * rd) + (gd * gd) + (bd * bd) + (ad * ad);
786  if (distance < smallest) {
787  pixel = i;
788  if (distance == 0) { /* Perfect match! */
789  break;
790  }
791  smallest = distance;
792  }
793  }
794  return (pixel);
795 }
796 
797 /* Find the opaque pixel value corresponding to an RGB triple */
798 Uint32
800 {
801  if (format->palette == NULL) {
802  return (r >> format->Rloss) << format->Rshift
803  | (g >> format->Gloss) << format->Gshift
804  | (b >> format->Bloss) << format->Bshift | format->Amask;
805  } else {
806  return SDL_FindColor(format->palette, r, g, b, SDL_ALPHA_OPAQUE);
807  }
808 }
809 
810 /* Find the pixel value corresponding to an RGBA quadruple */
811 Uint32
813  Uint8 a)
814 {
815  if (format->palette == NULL) {
816  return (r >> format->Rloss) << format->Rshift
817  | (g >> format->Gloss) << format->Gshift
818  | (b >> format->Bloss) << format->Bshift
819  | ((a >> format->Aloss) << format->Ashift & format->Amask);
820  } else {
821  return SDL_FindColor(format->palette, r, g, b, a);
822  }
823 }
824 
825 void
827  Uint8 * b)
828 {
829  if (format->palette == NULL) {
830  unsigned v;
831  v = (pixel & format->Rmask) >> format->Rshift;
832  *r = SDL_expand_byte[format->Rloss][v];
833  v = (pixel & format->Gmask) >> format->Gshift;
834  *g = SDL_expand_byte[format->Gloss][v];
835  v = (pixel & format->Bmask) >> format->Bshift;
836  *b = SDL_expand_byte[format->Bloss][v];
837  } else {
838  if (pixel < (unsigned)format->palette->ncolors) {
839  *r = format->palette->colors[pixel].r;
840  *g = format->palette->colors[pixel].g;
841  *b = format->palette->colors[pixel].b;
842  } else {
843  *r = *g = *b = 0;
844  }
845  }
846 }
847 
848 void
850  Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a)
851 {
852  if (format->palette == NULL) {
853  unsigned v;
854  v = (pixel & format->Rmask) >> format->Rshift;
855  *r = SDL_expand_byte[format->Rloss][v];
856  v = (pixel & format->Gmask) >> format->Gshift;
857  *g = SDL_expand_byte[format->Gloss][v];
858  v = (pixel & format->Bmask) >> format->Bshift;
859  *b = SDL_expand_byte[format->Bloss][v];
860  v = (pixel & format->Amask) >> format->Ashift;
861  *a = SDL_expand_byte[format->Aloss][v];
862  } else {
863  if (pixel < (unsigned)format->palette->ncolors) {
864  *r = format->palette->colors[pixel].r;
865  *g = format->palette->colors[pixel].g;
866  *b = format->palette->colors[pixel].b;
867  *a = format->palette->colors[pixel].a;
868  } else {
869  *r = *g = *b = *a = 0;
870  }
871  }
872 }
873 
874 /* Map from Palette to Palette */
875 static Uint8 *
876 Map1to1(SDL_Palette * src, SDL_Palette * dst, int *identical)
877 {
878  Uint8 *map;
879  int i;
880 
881  if (identical) {
882  if (src->ncolors <= dst->ncolors) {
883  /* If an identical palette, no need to map */
884  if (src == dst
885  ||
886  (SDL_memcmp
887  (src->colors, dst->colors,
888  src->ncolors * sizeof(SDL_Color)) == 0)) {
889  *identical = 1;
890  return (NULL);
891  }
892  }
893  *identical = 0;
894  }
895  map = (Uint8 *) SDL_malloc(src->ncolors);
896  if (map == NULL) {
897  SDL_OutOfMemory();
898  return (NULL);
899  }
900  for (i = 0; i < src->ncolors; ++i) {
901  map[i] = SDL_FindColor(dst,
902  src->colors[i].r, src->colors[i].g,
903  src->colors[i].b, src->colors[i].a);
904  }
905  return (map);
906 }
907 
908 /* Map from Palette to BitField */
909 static Uint8 *
910 Map1toN(SDL_PixelFormat * src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod,
912 {
913  Uint8 *map;
914  int i;
915  int bpp;
916  SDL_Palette *pal = src->palette;
917 
918  bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel);
919  map = (Uint8 *) SDL_malloc(pal->ncolors * bpp);
920  if (map == NULL) {
921  SDL_OutOfMemory();
922  return (NULL);
923  }
924 
925  /* We memory copy to the pixel map so the endianness is preserved */
926  for (i = 0; i < pal->ncolors; ++i) {
927  Uint8 R = (Uint8) ((pal->colors[i].r * Rmod) / 255);
928  Uint8 G = (Uint8) ((pal->colors[i].g * Gmod) / 255);
929  Uint8 B = (Uint8) ((pal->colors[i].b * Bmod) / 255);
930  Uint8 A = (Uint8) ((pal->colors[i].a * Amod) / 255);
931  ASSEMBLE_RGBA(&map[i * bpp], dst->BytesPerPixel, dst, R, G, B, A);
932  }
933  return (map);
934 }
935 
936 /* Map from BitField to Dithered-Palette to Palette */
937 static Uint8 *
939 {
940  /* Generate a 256 color dither palette */
941  SDL_Palette dithered;
942  SDL_Color colors[256];
943  SDL_Palette *pal = dst->palette;
944 
945  dithered.ncolors = 256;
946  SDL_DitherColors(colors, 8);
947  dithered.colors = colors;
948  return (Map1to1(&dithered, pal, identical));
949 }
950 
951 SDL_BlitMap *
953 {
954  SDL_BlitMap *map;
955 
956  /* Allocate the empty map */
957  map = (SDL_BlitMap *) SDL_calloc(1, sizeof(*map));
958  if (map == NULL) {
959  SDL_OutOfMemory();
960  return (NULL);
961  }
962  map->info.r = 0xFF;
963  map->info.g = 0xFF;
964  map->info.b = 0xFF;
965  map->info.a = 0xFF;
966 
967  /* It's ready to go */
968  return (map);
969 }
970 
971 void
973 {
974  if (!map) {
975  return;
976  }
977  if (map->dst) {
978  /* Release our reference to the surface - see the note below */
979  if (--map->dst->refcount <= 0) {
980  SDL_FreeSurface(map->dst);
981  }
982  }
983  map->dst = NULL;
984  map->src_palette_version = 0;
985  map->dst_palette_version = 0;
986  SDL_free(map->info.table);
987  map->info.table = NULL;
988 }
989 
990 int
992 {
993  SDL_PixelFormat *srcfmt;
994  SDL_PixelFormat *dstfmt;
995  SDL_BlitMap *map;
996 
997  /* Clear out any previous mapping */
998  map = src->map;
999  if ((src->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
1000  SDL_UnRLESurface(src, 1);
1001  }
1002  SDL_InvalidateMap(map);
1003 
1004  /* Figure out what kind of mapping we're doing */
1005  map->identity = 0;
1006  srcfmt = src->format;
1007  dstfmt = dst->format;
1008  if (SDL_ISPIXELFORMAT_INDEXED(srcfmt->format)) {
1009  if (SDL_ISPIXELFORMAT_INDEXED(dstfmt->format)) {
1010  /* Palette --> Palette */
1011  map->info.table =
1012  Map1to1(srcfmt->palette, dstfmt->palette, &map->identity);
1013  if (!map->identity) {
1014  if (map->info.table == NULL) {
1015  return (-1);
1016  }
1017  }
1018  if (srcfmt->BitsPerPixel != dstfmt->BitsPerPixel)
1019  map->identity = 0;
1020  } else {
1021  /* Palette --> BitField */
1022  map->info.table =
1023  Map1toN(srcfmt, src->map->info.r, src->map->info.g,
1024  src->map->info.b, src->map->info.a, dstfmt);
1025  if (map->info.table == NULL) {
1026  return (-1);
1027  }
1028  }
1029  } else {
1030  if (SDL_ISPIXELFORMAT_INDEXED(dstfmt->format)) {
1031  /* BitField --> Palette */
1032  map->info.table = MapNto1(srcfmt, dstfmt, &map->identity);
1033  if (!map->identity) {
1034  if (map->info.table == NULL) {
1035  return (-1);
1036  }
1037  }
1038  map->identity = 0; /* Don't optimize to copy */
1039  } else {
1040  /* BitField --> BitField */
1041  if (srcfmt == dstfmt) {
1042  map->identity = 1;
1043  }
1044  }
1045  }
1046 
1047  map->dst = dst;
1048 
1049  if (map->dst) {
1050  /* Keep a reference to this surface so it doesn't get deleted
1051  while we're still pointing at it.
1052 
1053  A better method would be for the destination surface to keep
1054  track of surfaces that are mapped to it and automatically
1055  invalidate them when it is freed, but this will do for now.
1056  */
1057  ++map->dst->refcount;
1058  }
1059 
1060  if (dstfmt->palette) {
1061  map->dst_palette_version = dstfmt->palette->version;
1062  } else {
1063  map->dst_palette_version = 0;
1064  }
1065 
1066  if (srcfmt->palette) {
1067  map->src_palette_version = srcfmt->palette->version;
1068  } else {
1069  map->src_palette_version = 0;
1070  }
1071 
1072  /* Choose your blitters wisely */
1073  return (SDL_CalculateBlit(src));
1074 }
1075 
1076 void
1078 {
1079  if (map) {
1080  SDL_InvalidateMap(map);
1081  SDL_free(map);
1082  }
1083 }
1084 
1085 void
1086 SDL_CalculateGammaRamp(float gamma, Uint16 * ramp)
1087 {
1088  int i;
1089 
1090  /* Input validation */
1091  if (gamma < 0.0f ) {
1092  SDL_InvalidParamError("gamma");
1093  return;
1094  }
1095  if (ramp == NULL) {
1096  SDL_InvalidParamError("ramp");
1097  return;
1098  }
1099 
1100  /* 0.0 gamma is all black */
1101  if (gamma == 0.0f) {
1102  for (i = 0; i < 256; ++i) {
1103  ramp[i] = 0;
1104  }
1105  return;
1106  } else if (gamma == 1.0f) {
1107  /* 1.0 gamma is identity */
1108  for (i = 0; i < 256; ++i) {
1109  ramp[i] = (i << 8) | i;
1110  }
1111  return;
1112  } else {
1113  /* Calculate a real gamma ramp */
1114  int value;
1115  gamma = 1.0f / gamma;
1116  for (i = 0; i < 256; ++i) {
1117  value =
1118  (int) (SDL_pow((double) i / 256.0, gamma) * 65535.0 + 0.5);
1119  if (value > 65535) {
1120  value = 65535;
1121  }
1122  ramp[i] = (Uint16) value;
1123  }
1124  }
1125 }
1126 
1127 /* vi: set ts=4 sw=4 expandtab: */
static Uint8 lookup_5[]
Definition: SDL_pixels.c:55
Uint8 * table
Definition: SDL_blit.h:67
Uint8 r
Definition: SDL_blit.h:70
DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface *surface)
Definition: SDL_surface.c:1053
Uint32 version
Definition: SDL_pixels.h:265
Uint8 b
Definition: SDL_blit.h:70
void SDL_DitherColors(SDL_Color *colors, int bpp)
Definition: SDL_pixels.c:718
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
DECLSPEC void SDLCALL SDL_FreeFormat(SDL_PixelFormat *format)
Free an SDL_PixelFormat structure.
Definition: SDL_pixels.c:584
Uint8 g
Definition: SDL_pixels.h:255
DECLSPEC double SDLCALL SDL_pow(double x, double y)
Definition: SDL_stdlib.c:120
DECLSPEC int SDLCALL SDL_SetPixelFormatPalette(SDL_PixelFormat *format, SDL_Palette *palette)
Set the palette for a pixel format structure.
Definition: SDL_pixels.c:646
#define SDL_PIXELLAYOUT(X)
Definition: SDL_pixels.h:121
GLboolean GLboolean g
Definition: glew.h:8736
#define NULL
Definition: ftobjs.h:61
GLclampf f
Definition: glew.h:3390
#define SDL_ISPIXELFORMAT_INDEXED(format)
Definition: SDL_pixels.h:129
static SDL_PixelFormat * formats
Definition: SDL_pixels.c:483
Uint8 BytesPerPixel
Definition: SDL_pixels.h:277
DECLSPEC const char *SDLCALL SDL_GetPixelFormatName(Uint32 format)
Get the human readable name of a pixel format.
Definition: SDL_pixels.c:86
SDL_bool
Definition: SDL_stdinc.h:116
Uint8 g
Definition: SDL_blit.h:70
static Uint8 lookup_0[]
Definition: SDL_pixels.c:35
EGLSurface surface
Definition: eglext.h:74
#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a)
Definition: SDL_blit.h:401
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
DECLSPEC void SDLCALL SDL_free(void *mem)
DECLSPEC void SDLCALL SDL_FreePalette(SDL_Palette *palette)
Free a palette created with SDL_AllocPalette().
Definition: SDL_pixels.c:701
void SDL_UnRLESurface(SDL_Surface *surface, int recode)
DECLSPEC Uint32 SDLCALL SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
Convert a bpp and RGBA masks to an enumerated pixel format.
Definition: SDL_pixels.c:291
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:8736
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:123
Uint32 dst_palette_version
Definition: SDL_blit.h:95
Uint8 b
Definition: SDL_pixels.h:256
DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len)
Definition: SDL_string.c:370
static Uint8 lookup_4[]
Definition: SDL_pixels.c:51
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
static Uint8 lookup_2[]
Definition: SDL_pixels.c:43
static Uint8 lookup_7[]
Definition: SDL_pixels.c:63
DECLSPEC Uint32 SDLCALL SDL_MapRGBA(const SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Maps an RGBA quadruple to a pixel value for a given pixel format.
Definition: SDL_pixels.c:812
Uint32 flags
Definition: SDL_surface.h:71
Uint32 src_palette_version
Definition: SDL_blit.h:96
void SDL_InvalidateMap(SDL_BlitMap *map)
Definition: SDL_pixels.c:972
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
static Uint8 lookup_1[]
Definition: SDL_pixels.c:39
struct SDL_BlitMap * map
Definition: SDL_surface.h:88
const GLdouble * v
Definition: glew.h:1377
DECLSPEC SDL_PixelFormat *SDLCALL SDL_AllocFormat(Uint32 pixel_format)
Create an SDL_PixelFormat structure from a pixel format enum.
Definition: SDL_pixels.c:486
Uint8 r
Definition: SDL_pixels.h:254
GLenum GLenum dst
Definition: glew.h:2396
static Uint8 * Map1to1(SDL_Palette *src, SDL_Palette *dst, int *identical)
Definition: SDL_pixels.c:876
static Uint8 lookup_8[]
Definition: SDL_pixels.c:67
int
Definition: SDL_systhread.c:37
for(;;)
int SDL_MapSurface(SDL_Surface *src, SDL_Surface *dst)
Definition: SDL_pixels.c:991
Uint8 * SDL_expand_byte[9]
Definition: SDL_pixels.c:71
Uint8 a
Definition: SDL_pixels.h:257
Uint8 BitsPerPixel
Definition: SDL_pixels.h:276
Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Definition: SDL_pixels.c:770
GLsizei GLsizei GLfloat distance
Definition: glew.h:12423
DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len)
Definition: SDL_string.c:261
#define SDL_PIXELORDER(X)
Definition: SDL_pixels.h:120
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
int SDL_CalculateBlit(SDL_Surface *surface)
Definition: SDL_blit.c:216
int SDL_InitFormat(SDL_PixelFormat *format, Uint32 pixel_format)
Definition: SDL_pixels.c:519
static Uint8 * MapNto1(SDL_PixelFormat *src, SDL_PixelFormat *dst, int *identical)
Definition: SDL_pixels.c:938
#define SDL_PIXELTYPE(X)
Definition: SDL_pixels.h:119
SDL_Surface * dst
Definition: SDL_blit.h:87
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_Color * colors
Definition: SDL_pixels.h:264
SDL_PixelFormat * format
Definition: SDL_surface.h:72
EGLSurface EGLint void ** value
Definition: eglext.h:301
DECLSPEC void SDLCALL SDL_CalculateGammaRamp(float gamma, Uint16 *ramp)
Calculate a 256 entry gamma ramp for a gamma value.
Definition: SDL_pixels.c:1086
DECLSPEC void SDLCALL SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat *format, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
Get the RGBA components from a pixel of the specified format.
Definition: SDL_pixels.c:849
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
Definition: SDL_string.c:293
static Uint8 * Map1toN(SDL_PixelFormat *src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod, SDL_PixelFormat *dst)
Definition: SDL_pixels.c:910
DECLSPEC SDL_Palette *SDLCALL SDL_AllocPalette(int ncolors)
Create a palette structure with the specified number of color entries.
Definition: SDL_pixels.c:615
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
#define G(x, y, z)
Definition: SDL_test_md5.c:74
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
Definition: gl2ext.h:961
#define SDL_zerop(x)
Definition: SDL_stdinc.h:255
DECLSPEC SDL_bool SDLCALL SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, Uint32 *Rmask, Uint32 *Gmask, Uint32 *Bmask, Uint32 *Amask)
Convert one of the enumerated pixel formats to a bpp and RGBA masks.
Definition: SDL_pixels.c:132
DECLSPEC Uint32 SDLCALL SDL_MapRGB(const SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b)
Maps an RGB triple to an opaque pixel value for a given pixel format.
Definition: SDL_pixels.c:799
DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat *format, Uint8 *r, Uint8 *g, Uint8 *b)
Get the RGB components from a pixel of the specified format.
Definition: SDL_pixels.c:826
SDL_BlitMap * SDL_AllocBlitMap(void)
Definition: SDL_pixels.c:952
GLdouble GLdouble GLdouble r
Definition: glew.h:1392
GLdouble GLdouble GLdouble b
Definition: glew.h:8383
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:137
int SDL_CalculatePitch(SDL_Surface *surface)
Definition: SDL_pixels.c:746
SDL_Palette * palette
Definition: SDL_pixels.h:275
#define SDL_ISPIXELFORMAT_FOURCC(format)
Definition: SDL_pixels.h:143
GLenum src
Definition: glew.h:2396
R
Definition: e_log.c:153
int i
Definition: pngrutil.c:1377
const GLubyte GLuint GLuint GLuint GLuint alpha GLboolean GLboolean GLboolean GLboolean alpha GLint GLint GLsizei GLsizei GLenum type GLenum GLint GLenum GLint GLint GLsizei GLsizei GLint border GLenum GLint GLint GLint GLint GLint GLsizei GLsizei height GLsizei GLsizei GLenum GLenum const GLvoid *pixels GLenum GLint GLint GLint GLint j2 GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble zFar GLenum GLenum GLint *params GLenum GLenum GLint *params GLenum GLenum GLint *params GLenum GLenum GLfloat *params GLenum GLint GLenum GLenum GLvoid *pixels GLenum GLint GLenum GLint *params GLenum GLenum GLint *params GLenum GLsizei const GLvoid *pointer GLenum GLenum const GLint *params GLenum GLfloat GLfloat GLint GLint const GLfloat *points GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat *points GLint GLfloat GLfloat GLint GLfloat GLfloat v2 GLenum GLenum const GLint *params GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble zFar GLenum map
Definition: SDL_glfuncs.h:268
static Uint8 lookup_3[]
Definition: SDL_pixels.c:47
#define SDL_ALPHA_OPAQUE
Definition: SDL_pixels.h:43
void SDL_FreeBlitMap(SDL_BlitMap *map)
Definition: SDL_pixels.c:1077
int identity
Definition: SDL_blit.h:88
#define SDL_BITSPERPIXEL(X)
Definition: SDL_pixels.h:122
struct SDL_PixelFormat * next
Definition: SDL_pixels.h:292
SDL_BlitInfo info
Definition: SDL_blit.h:91
static Uint8 lookup_6[]
Definition: SDL_pixels.c:59
#define CASE(X)
GLuint colors[3]
Definition: modern.h:25
#define SDL_RLEACCEL
Definition: SDL_surface.h:54
DECLSPEC int SDLCALL SDL_SetPaletteColors(SDL_Palette *palette, const SDL_Color *colors, int firstcolor, int ncolors)
Set a range of colors in a palette.
Definition: SDL_pixels.c:674
Uint8 a
Definition: SDL_blit.h:70