diff src/video/SDL_pixels.c @ 1683:396a35389351 SDL-1.3

Finished palettized display handling. Added support for surface palette sharing.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 17 Jun 2006 06:45:14 +0000
parents 7ae8018b2e5d
children 1577404809f0
line wrap: on
line diff
--- a/src/video/SDL_pixels.c	Fri Jun 16 06:00:31 2006 +0000
+++ b/src/video/SDL_pixels.c	Sat Jun 17 06:45:14 2006 +0000
@@ -215,6 +215,126 @@
     return SDL_PixelFormat_Unknown;
 }
 
+
+SDL_Palette *
+SDL_AllocPalette(int ncolors)
+{
+    SDL_Palette *palette;
+
+    palette = (SDL_Palette *) SDL_malloc(sizeof(*palette));
+    if (!palette) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+    palette->colors =
+        (SDL_Color *) SDL_malloc(ncolors * sizeof(*palette->colors));
+    if (!palette->colors) {
+        SDL_free(palette);
+        return NULL;
+    }
+    palette->ncolors = ncolors;
+    palette->watch = NULL;
+    palette->refcount = 1;
+
+    SDL_memset(palette->colors, 0xFF, ncolors * sizeof(*palette->colors));
+
+    return palette;
+}
+
+int
+SDL_AddPaletteWatch(SDL_Palette * palette, SDL_PaletteChangedFunc callback,
+                    void *userdata)
+{
+    SDL_PaletteWatch *watch;
+
+    if (!palette) {
+        return -1;
+    }
+
+    watch = (SDL_PaletteWatch *) SDL_malloc(sizeof(*watch));
+    if (!watch) {
+        SDL_OutOfMemory();
+        return -1;
+    }
+
+    watch->callback = callback;
+    watch->userdata = userdata;
+    watch->next = palette->watch;
+    palette->watch = watch;
+    ++palette->refcount;
+    return 0;
+}
+
+void
+SDL_DelPaletteWatch(SDL_Palette * palette, SDL_PaletteChangedFunc callback,
+                    void *userdata)
+{
+    SDL_PaletteWatch *prev, *watch;
+
+    if (!palette) {
+        return;
+    }
+
+    for (prev = NULL, watch = palette->watch; watch;
+         prev = watch, watch = watch->next) {
+        if (watch->callback == callback && watch->userdata == userdata) {
+            if (prev) {
+                prev->next = watch->next;
+            } else {
+                palette->watch = watch->next;
+            }
+            SDL_free(watch);
+            SDL_FreePalette(palette);
+            return;
+        }
+    }
+}
+
+int
+SDL_SetPaletteColors(SDL_Palette * palette, const SDL_Color * colors,
+                     int firstcolor, int ncolors)
+{
+    SDL_PaletteWatch *watch;
+    int status = 0;
+
+    /* Verify the parameters */
+    if (!palette) {
+        return -1;
+    }
+    if (ncolors > (palette->ncolors - firstcolor)) {
+        ncolors = (palette->ncolors - firstcolor);
+        status = -1;
+    }
+
+    if (colors != (palette->colors + firstcolor)) {
+        SDL_memcpy(palette->colors + firstcolor, colors,
+                   ncolors * sizeof(*colors));
+    }
+
+    for (watch = palette->watch; watch; watch = watch->next) {
+        if (watch->callback(watch->userdata, palette) < 0) {
+            status = -1;
+        }
+    }
+
+    return status;
+}
+
+void
+SDL_FreePalette(SDL_Palette * palette)
+{
+    if (!palette) {
+        return;
+    }
+    if (--palette->refcount > 0) {
+        return;
+    }
+    if (palette->colors) {
+        SDL_free(palette->colors);
+    }
+    SDL_free(palette);
+}
+
 /*
  * Allocate a pixel format structure and fill it according to the given info.
  */
@@ -238,7 +358,6 @@
     format->BitsPerPixel = bpp;
     format->BytesPerPixel = (bpp + 7) / 8;
     if (Rmask || Bmask || Gmask) {      /* Packed pixels with custom mask */
-        format->palette = NULL;
         format->Rshift = 0;
         format->Rloss = 8;
         if (Rmask) {
@@ -303,121 +422,11 @@
         format->Bmask = 0;
         format->Amask = 0;
     }
-    if (bpp <= 8) {             /* Palettized mode */
-        int ncolors = 1 << bpp;
-#ifdef DEBUG_PALETTE
-        fprintf(stderr, "bpp=%d ncolors=%d\n", bpp, ncolors);
-#endif
-        format->palette = (SDL_Palette *) SDL_malloc(sizeof(SDL_Palette));
-        if (format->palette == NULL) {
-            SDL_FreeFormat(format);
-            SDL_OutOfMemory();
-            return (NULL);
-        }
-        (format->palette)->ncolors = ncolors;
-        (format->palette)->colors = (SDL_Color *) SDL_malloc((format->
-                                                              palette)->
-                                                             ncolors *
-                                                             sizeof
-                                                             (SDL_Color));
-        if ((format->palette)->colors == NULL) {
-            SDL_FreeFormat(format);
-            SDL_OutOfMemory();
-            return (NULL);
-        }
-        if (Rmask || Bmask || Gmask) {
-            /* create palette according to masks */
-            int i;
-            int Rm = 0, Gm = 0, Bm = 0;
-            int Rw = 0, Gw = 0, Bw = 0;
-#ifdef ENABLE_PALETTE_ALPHA
-            int Am = 0, Aw = 0;
-#endif
-            if (Rmask) {
-                Rw = 8 - format->Rloss;
-                for (i = format->Rloss; i > 0; i -= Rw)
-                    Rm |= 1 << i;
-            }
-#ifdef DEBUG_PALETTE
-            fprintf(stderr, "Rw=%d Rm=0x%02X\n", Rw, Rm);
-#endif
-            if (Gmask) {
-                Gw = 8 - format->Gloss;
-                for (i = format->Gloss; i > 0; i -= Gw)
-                    Gm |= 1 << i;
-            }
-#ifdef DEBUG_PALETTE
-            fprintf(stderr, "Gw=%d Gm=0x%02X\n", Gw, Gm);
-#endif
-            if (Bmask) {
-                Bw = 8 - format->Bloss;
-                for (i = format->Bloss; i > 0; i -= Bw)
-                    Bm |= 1 << i;
-            }
-#ifdef DEBUG_PALETTE
-            fprintf(stderr, "Bw=%d Bm=0x%02X\n", Bw, Bm);
-#endif
-#ifdef ENABLE_PALETTE_ALPHA
-            if (Amask) {
-                Aw = 8 - format->Aloss;
-                for (i = format->Aloss; i > 0; i -= Aw)
-                    Am |= 1 << i;
-            }
-# ifdef DEBUG_PALETTE
-            fprintf(stderr, "Aw=%d Am=0x%02X\n", Aw, Am);
-# endif
-#endif
-            for (i = 0; i < ncolors; ++i) {
-                int r, g, b;
-                r = (i & Rmask) >> format->Rshift;
-                r = (r << format->Rloss) | ((r * Rm) >> Rw);
-                format->palette->colors[i].r = r;
+    format->palette = NULL;
 
-                g = (i & Gmask) >> format->Gshift;
-                g = (g << format->Gloss) | ((g * Gm) >> Gw);
-                format->palette->colors[i].g = g;
-
-                b = (i & Bmask) >> format->Bshift;
-                b = (b << format->Bloss) | ((b * Bm) >> Bw);
-                format->palette->colors[i].b = b;
-
-#ifdef ENABLE_PALETTE_ALPHA
-                a = (i & Amask) >> format->Ashift;
-                a = (a << format->Aloss) | ((a * Am) >> Aw);
-                format->palette->colors[i].unused = a;
-#else
-                format->palette->colors[i].unused = SDL_ALPHA_OPAQUE;
-#endif
-            }
-        } else if (ncolors == 2) {
-            /* Create a black and white bitmap palette */
-            format->palette->colors[0].r = 0xFF;
-            format->palette->colors[0].g = 0xFF;
-            format->palette->colors[0].b = 0xFF;
-            format->palette->colors[1].r = 0x00;
-            format->palette->colors[1].g = 0x00;
-            format->palette->colors[1].b = 0x00;
-        } else {
-            /* Create an empty palette */
-            SDL_memset((format->palette)->colors, 0xFF,
-                       (format->palette)->ncolors * sizeof(SDL_Color));
-        }
-    }
     return (format);
 }
 
-SDL_PixelFormat *
-SDL_ReallocFormat(SDL_Surface * surface, int bpp,
-                  Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
-{
-    if (surface->format) {
-        SDL_FreeFormat(surface->format);
-        SDL_FormatChanged(surface);
-    }
-    surface->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
-    return surface->format;
-}
-
 /*
  * Change any previous mappings from/to the new surface format
  */
@@ -439,15 +448,10 @@
 void
 SDL_FreeFormat(SDL_PixelFormat * format)
 {
-    if (format) {
-        if (format->palette) {
-            if (format->palette->colors) {
-                SDL_free(format->palette->colors);
-            }
-            SDL_free(format->palette);
-        }
-        SDL_free(format);
+    if (!format) {
+        return;
     }
+    SDL_free(format);
 }
 
 /*
@@ -695,10 +699,6 @@
     SDL_Color colors[256];
     SDL_Palette *pal = dst->palette;
 
-    /* SDL_DitherColors does not initialize the 'unused' component of colors,
-       but Map1to1 compares it against pal, so we should initialize it. */
-    SDL_memset(colors, 0xFF, sizeof(colors));
-
     dithered.ncolors = 256;
     SDL_DitherColors(colors, 8);
     dithered.colors = colors;
@@ -768,14 +768,8 @@
         switch (dstfmt->BytesPerPixel) {
         case 1:
             /* Palette --> Palette */
-            /* If both SDL_HWSURFACE, assume have same palette */
-            if (((src->flags & SDL_HWSURFACE) == SDL_HWSURFACE) &&
-                ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE)) {
-                map->identity = 1;
-            } else {
-                map->table = Map1to1(srcfmt->palette,
-                                     dstfmt->palette, &map->identity);
-            }
+            map->table =
+                Map1to1(srcfmt->palette, dstfmt->palette, &map->identity);
             if (!map->identity) {
                 if (map->table == NULL) {
                     return (-1);