]> Pileus Git - ~andy/gtk/blobdiff - gdk/gdkpixbuf-drawable.c
Make GTK+ use an external gdk-pixbuf
[~andy/gtk] / gdk / gdkpixbuf-drawable.c
index ce7319acd959e03ddc571e7471cf7f5daba8c0eb..ff85cb7e7afa188e679237273cf5fb1db588ee90 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
-#include <config.h>
+#include "config.h"
 #include <stdio.h>
 #include <string.h>
-#include "gdk.h"               /* For gdk_screen_width/gdk_screen_height */
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
 #include "gdkcolor.h"
 #include "gdkimage.h"
 #include "gdkvisual.h"
 #include "gdkwindow.h"
 #include "gdkpixbuf.h"
-#include "gdk-pixbuf-private.h"
+#include "gdkpixmap.h"
 #include "gdkinternals.h"
+#include "gdkalias.h"
 
+/* Some convenient names
+ */
 #if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
 #define LITTLE
+#undef BIG
+#else
+#define BIG
+#undef LITTLE
 #endif
 #define d(x)
 
+#define SWAP16(d) GUINT16_SWAP_LE_BE(d)
+
 \f
 
-static guint32 mask_table[] = {
+static const guint32 mask_table[] = {
   0x00000000, 0x00000001, 0x00000003, 0x00000007,
   0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
   0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
@@ -204,9 +214,9 @@ rgb1 (GdkImage    *image,
                                   (0x80 >> (xx & 7)) :
                                   (1 << (xx & 7)));
 
-         *o++ = colormap->colors[data].red;
-         *o++ = colormap->colors[data].green;
-         *o++ = colormap->colors[data].blue;
+         *o++ = colormap->colors[data].red   >> 8;
+         *o++ = colormap->colors[data].green >> 8;
+         *o++ = colormap->colors[data].blue  >> 8;
        }
       srow += bpl;
       orow += rowstride;
@@ -251,9 +261,9 @@ rgb1a (GdkImage    *image,
                                   (0x80 >> (xx & 7)) :
                                   (1 << (xx & 7)));
 
-          *o++ = colormap->colors[data].red;
-         *o++ = colormap->colors[data].green;
-         *o++ = colormap->colors[data].blue;
+          *o++ = colormap->colors[data].red   >> 8;
+         *o++ = colormap->colors[data].green >> 8;
+         *o++ = colormap->colors[data].blue  >> 8;
          *o++ = 255;
        }
       srow += bpl;
@@ -296,9 +306,9 @@ rgb8 (GdkImage    *image,
       for (xx = x1; xx < x2; xx++)
         {
           data = *s++ & mask;
-          *o++ = colormap->colors[data].red;
-          *o++ = colormap->colors[data].green;
-          *o++ = colormap->colors[data].blue;
+          *o++ = colormap->colors[data].red   >> 8;
+          *o++ = colormap->colors[data].green >> 8;
+          *o++ = colormap->colors[data].blue  >> 8;
         }
       srow += bpl;
       orow += rowstride;
@@ -338,14 +348,14 @@ rgb8a (GdkImage    *image,
     {
 #ifdef LITTLE
       remap[xx] = 0xff000000
-       | colormap->colors[xx].blue << 16
-       | colormap->colors[xx].green << 8
-       | colormap->colors[xx].red;
+       | (colormap->colors[xx].blue  & 0xff00) << 8
+       | (colormap->colors[xx].green & 0xff00)
+       | (colormap->colors[xx].red   >> 8);
 #else
       remap[xx] = 0xff
-       | colormap->colors[xx].red << 24
-       | colormap->colors[xx].green << 16
-       | colormap->colors[xx].blue << 8;
+       | (colormap->colors[xx].red   & 0xff00) << 16
+       | (colormap->colors[xx].green & 0xff00) << 8
+       | (colormap->colors[xx].blue  & 0xff00);
 #endif
     }
 
@@ -363,6 +373,39 @@ rgb8a (GdkImage    *image,
     }
 }
 
+/* Bit shifting for 565 and 555 conversion routines
+ *
+ * RGB565 == rrrr rggg gggb bbbb, 16 bit native endian
+ * RGB555 == xrrr rrgg gggb bbbb
+ * ABGR8888: ARGB, 32-bit native endian
+ * RGBA8888: RGBA, 32-bit native endian
+ */
+#define R8fromRGB565(d) ((((d) >> 8) & 0xf8) | (((d) >> 13) & 0x7))
+#define G8fromRGB565(d) ((((d) >> 3) & 0xfc) | (((d) >> 9)  & 0x3))
+#define B8fromRGB565(d) ((((d) << 3) & 0xf8) | (((d) >> 2)  & 0x7))
+
+#define ABGR8888fromRGB565(d) (  ((d) & 0xf800) >> 8  | ((d) & 0xe000) >> 13 \
+                              | ((d) & 0x07e0) << 5  | ((d) & 0x0600) >> 1  \
+                              | ((d) & 0x001f) << 19 | ((d) & 0x001c) << 14 \
+                              | 0xff000000)
+#define RGBA8888fromRGB565(d) (  ((d) & 0xf800) << 16 | ((d) & 0xe000) << 11 \
+                              | ((d) & 0x07e0) << 13 | ((d) & 0x0600) << 7  \
+                              | ((d) & 0x001f) << 11 | ((d) & 0x001c) << 6  \
+                              | 0xff)
+
+#define R8fromRGB555(d) (((d) & 0x7c00) >> 7 | ((d) & 0x7000) >> 12)
+#define G8fromRGB555(d) (((d) & 0x03e0) >> 2 | ((d) & 0x0380) >> 7)
+#define B8fromRGB555(d) (((d) & 0x001f) << 3 | ((d) & 0x001c) >> 2)
+
+#define ABGR8888fromRGB555(d) (  ((d) & 0x7c00) >> 7  | ((d) & 0x7000) >> 12 \
+                              | ((d) & 0x03e0) << 6  | ((d) & 0x0380) << 1  \
+                              | ((d) & 0x001f) << 19 | ((d) & 0x001c) << 14 \
+                              | 0xff000000)
+#define RGBA8888fromRGB555(d) (  ((d) & 0x7c00) << 17 | ((d) & 0x7000) << 12 \
+                              | ((d) & 0x03e0) << 14 | ((d) & 0x0380) << 9  \
+                              | ((d) & 0x001f) << 11 | ((d) & 0x001c) << 6  \
+                              | 0xff)
+
 /*
  * convert 16 bits/pixel data
  * no alpha
@@ -372,94 +415,35 @@ static void
 rgb565lsb (GdkImage    *image,
           guchar      *pixels,
           int          rowstride,
-           int          x1,
-           int          y1,
-           int          x2,
-           int          y2,
+          int          x1,
+          int          y1,
+          int          x2,
+          int          y2,
           GdkColormap *colormap)
 {
   int xx, yy;
   int bpl;
 
-#ifdef LITTLE
-  register guint32 *s; /* read 2 pixels at once */
-#else
-  register guint8 *s;  /* read 2 pixels at once */
-#endif
-  register guint16 *o;
+  register guint16 *s;
+  register guint8 *o;
+
   guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
-  
+
   bpl = image->bpl;
-  
+
   for (yy = y1; yy < y2; yy++)
     {
-#ifdef LITTLE
-      s = (guint32 *) srow;
-#else
-      s = srow;
-#endif
-      o = (guint16 *) orow;
-
-      /* check for first pixel odd */
-      xx = x1;
-      if (xx & 1)
-       {
-         register guint16 data;
-#ifdef LITTLE
-         data = *((short *) s);
-#else
-         data = *((short *) s);
-         data = ((data >> 8) & 0xff) | ((data & 0xff) << 8);
-#endif
-         ((char *) o)[0] = ((data >> 8) & 0xf8) | ((data >> 13) & 0x7);
-         ((char *) o)[1] = ((data >> 3) & 0xfc) | ((data >> 9) & 0x3);
-         ((char *) o)[2] = ((data << 3) & 0xf8) | ((data >> 2) & 0x7);
-          ((char *) o) += 3;
-          ++xx;
-       }
-
-      g_assert (!(xx & 1));
-
-      /* if x2 is even, then the -1 does nothing to number of
-       * loop iterations, if x2 is odd then the -1 reduces
-       * iterations by one
-       */
-      for (; xx < (x2 - 1); xx += 2)
-       {
-         register guint32 data;
-#ifdef LITTLE
-         data = *s++;
-         *o++ = (data & 0xf800) >> 8 | (data & 0xe000) >> 13
-           | (data & 0x7e0) << 5 | (data & 0x600) >> 1;
-         *o++ = (data & 0x1f) << 3 | (data & 0x1c) >> 2
-           | (data & 0xf8000000) >> 16 | (data & 0xe0000000) >> 21;
-         *o++ = (data & 0x7e00000) >> 19 | (data & 0x6000000) >> 25
-           | (data & 0x1f0000) >> 5 | (data & 0x1c0000) >> 10;
-#else
-         /* swap endianness first */
-         data = s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
-         s += 4;
-         *o++ = (data & 0xf800) | (data & 0xe000) >> 5
-           | (data & 0x7e0) >> 3 | (data & 0x600) >> 9;
-         *o++ = (data & 0x1f) << 11 | (data & 0x1c) << 6
-           | (data & 0xf8000000) >> 24 | (data & 0xe0000000) >> 29;
-         *o++ = (data & 0x7e00000) >> 11 | (data & 0x6000000) >> 17
-           | (data & 0x1f0000) >> 13 | (data & 0x1c0000) >> 18;
-#endif
-       }
-      /* check for last remaining pixel */
-      if (x2 & 1)
+      s = (guint16 *) srow;
+      o = (guint8 *) orow;
+      for (xx = x1; xx < x2; xx ++)
        {
-         register guint16 data;
-#ifdef LITTLE
-         data = *((short *) s);
-#else
-         data = *((short *) s);
-         data = ((data >> 8) & 0xff) | ((data & 0xff) << 8);
-#endif
-         ((char *) o)[0] = ((data >> 8) & 0xf8) | ((data >> 13) & 0x7);
-         ((char *) o)[1] = ((data >> 3) & 0xfc) | ((data >> 9) & 0x3);
-         ((char *) o)[2] = ((data << 3) & 0xf8) | ((data >> 2) & 0x7);
+         register guint32 data = *s++;
+#ifdef BIG
+         data = SWAP16 (data);
+#endif   
+         *o++ = R8fromRGB565 (data);
+         *o++ = G8fromRGB565 (data);
+         *o++ = B8fromRGB565 (data);
        }
       srow += bpl;
       orow += rowstride;
@@ -484,87 +468,26 @@ rgb565msb (GdkImage    *image,
   int xx, yy;
   int bpl;
 
-#ifdef LITTLE
-  register guint8 *s;  /* need to swap data order */
-#else
-  register guint32 *s; /* read 2 pixels at once */
-#endif
-  register guint16 *o;
+  register guint16 *s;
+  register guint8 *o;
+
   guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
 
   bpl = image->bpl;
 
   for (yy = y1; yy < y2; yy++)
     {
-#ifdef LITTLE
-      s = srow;
-#else
-      s = (guint32 *) srow;
-#endif
-      o = (guint16 *) orow;
-
-      xx = x1;
-      
-      /* check for first pixel odd */
-      if (xx & 1)
-       {
-         register guint16 data;
-#ifdef LITTLE
-         data = *((short *) s);
-         data = ((data >> 8) & 0xff) | ((data & 0xff) << 8);
-#else
-         data = *((short *) s);
-#endif
-         ((char *) o)[0] = ((data >> 8) & 0xf8) | ((data >> 13) & 0x7);
-         ((char *) o)[1] = ((data >> 3) & 0xfc) | ((data >> 9) & 0x3);
-         ((char *) o)[2] = ((data << 3) & 0xf8) | ((data >> 2) & 0x7);
-
-          ((char *) o) += 3;
-          ++xx;
-       }
-
-      g_assert (!(xx & 1));
-
-      /* if x2 is even, then the -1 does nothing to number of
-       * loop iterations, if x2 is odd then the -1 reduces
-       * iterations by one
-       */
-      for (; xx < (x2 - 1); xx += 2)
-       {
-         register guint32 data;
-#ifdef LITTLE
-         /* swap endianness first */
-         data = s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
-         s += 4;
-         *o++ = (data & 0xf800) >> 8 | (data & 0xe000) >> 13
-           | (data & 0x7e0) << 5 | (data & 0x600) >> 1;
-         *o++ = (data & 0x1f) << 3 | (data & 0x1c) >> 2
-           | (data & 0xf8000000) >> 16 | (data & 0xe0000000) >> 21;
-         *o++ = (data & 0x7e00000) >> 19 | (data & 0x6000000) >> 25
-           | (data & 0x1f0000) >> 5 | (data & 0x1c0000) >> 10;
-#else
-         data = *s++;
-         *o++ = (data & 0xf800) | (data & 0xe000) >> 5
-           | (data & 0x7e0) >> 3 | (data & 0x600) >> 9;
-         *o++ = (data & 0x1f) << 11 | (data & 0x1c) << 6
-           | (data & 0xf8000000) >> 24 | (data & 0xe0000000) >> 29;
-         *o++ = (data & 0x7e00000) >> 11 | (data & 0x6000000) >> 17
-           | (data & 0x1f0000) >> 13 | (data & 0x1c0000) >> 18;
-#endif
-       }
-      /* check for last remaining pixel */
-      if (x2 & 1)
+      s = (guint16 *) srow;
+      o = (guint8 *) orow;
+      for (xx = x1; xx < x2; xx ++)
        {
-         register guint16 data;
+         register guint32 data = *s++;
 #ifdef LITTLE
-         data = *((short *) s);
-         data = ((data >> 8) & 0xff) | ((data & 0xff) << 8);
-#else
-         data = *((short *) s);
-#endif
-         ((char *) o)[0] = ((data >> 8) & 0xf8) | ((data >> 13) & 0x7);
-         ((char *) o)[1] = ((data >> 3) & 0xfc) | ((data >> 9) & 0x3);
-         ((char *) o)[2] = ((data << 3) & 0xf8) | ((data >> 2) & 0x7);
+         data = SWAP16 (data);
+#endif   
+         *o++ = R8fromRGB565 (data);
+         *o++ = G8fromRGB565 (data);
+         *o++ = B8fromRGB565 (data);
        }
       srow += bpl;
       orow += rowstride;
@@ -589,11 +512,7 @@ rgb565alsb (GdkImage    *image,
   int xx, yy;
   int bpl;
 
-#ifdef LITTLE
-  register guint16 *s; /* read 1 pixels at once */
-#else
-  register guint8 *s;
-#endif
+  register guint16 *s;
   register guint32 *o;
 
   guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
@@ -602,31 +521,16 @@ rgb565alsb (GdkImage    *image,
 
   for (yy = y1; yy < y2; yy++)
     {
-#ifdef LITTLE
       s = (guint16 *) srow;
-#else
-      s = (guint8 *) srow;
-#endif
       o = (guint32 *) orow;
       for (xx = x1; xx < x2; xx ++)
        {
-         register guint32 data;
-         /*  rrrrrggg gggbbbbb -> rrrrrRRR ggggggGG bbbbbBBB aaaaaaaa */
-         /*  little endian: aaaaaaaa bbbbbBBB ggggggGG rrrrrRRR */
+         register guint32 data = *s++;
 #ifdef LITTLE
-         data = *s++;
-         *o++ = (data & 0xf800) >> 8 | (data & 0xe000) >> 13
-           | (data & 0x7e0) << 5 | (data & 0x600) >> 1
-           | (data & 0x1f) << 19 | (data & 0x1c) << 14
-           | 0xff000000;
+         *o++ = ABGR8888fromRGB565 (data);
 #else
-         /* swap endianness first */
-         data = s[0] | s[1] << 8;
-         s += 2;
-         *o++ = (data & 0xf800) << 16 | (data & 0xe000) << 11
-           | (data & 0x7e0) << 13 | (data & 0x600) << 7
-           | (data & 0x1f) << 11 | (data & 0x1c) << 6
-           | 0xff;
+         data = SWAP16 (data);
+         *o++ = RGBA8888fromRGB565 (data);
 #endif
        }
       srow += bpl;
@@ -652,11 +556,7 @@ rgb565amsb (GdkImage    *image,
   int xx, yy;
   int bpl;
 
-#ifdef LITTLE
-  register guint8 *s;
-#else
-  register guint16 *s; /* read 1 pixels at once */
-#endif
+  register guint16 *s;
   register guint32 *o;
 
   guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
@@ -665,27 +565,16 @@ rgb565amsb (GdkImage    *image,
 
   for (yy = y1; yy < y2; yy++)
     {
-      s = srow;
+      s = (guint16 *) srow;
       o = (guint32 *) orow;
       for (xx = x1; xx < x2; xx ++)
        {
-         register guint32 data;
-         /*  rrrrrggg gggbbbbb -> rrrrrRRR gggggg00 bbbbbBBB aaaaaaaa */
-         /*  little endian: aaaaaaaa bbbbbBBB gggggg00 rrrrrRRR */
+         register guint32 data = *s++;
 #ifdef LITTLE
-         /* swap endianness first */
-         data = s[0] | s[1] << 8;
-         s += 2;
-         *o++ = (data & 0xf800) >> 8 | (data & 0xe000) >> 13
-           | (data & 0x7e0) << 5 | (data & 0x600) >> 1
-           | (data & 0x1f) << 19 | (data & 0x1c) << 14
-           | 0xff000000;
+         data = SWAP16 (data);
+         *o++ = ABGR8888fromRGB565 (data);
 #else
-         data = *s++;
-         *o++ = (data & 0xf800) << 16 | (data & 0xe000) << 11
-           | (data & 0x7e0) << 13 | (data & 0x600) << 7
-           | (data & 0x1f) << 11 | (data & 0x1c) << 6
-           | 0xff;
+         *o++ = RGBA8888fromRGB565 (data);
 #endif
        }
       srow += bpl;
@@ -711,86 +600,26 @@ rgb555lsb (GdkImage     *image,
   int xx, yy;
   int bpl;
 
-#ifdef LITTLE
-  register guint32 *s; /* read 2 pixels at once */
-#else
-  register guint8 *s;  /* read 2 pixels at once */
-#endif
-  register guint16 *o;
+  register guint16 *s;
+  register guint8 *o;
+
   guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
 
   bpl = image->bpl;
 
   for (yy = y1; yy < y2; yy++)
     {
-#ifdef LITTLE
-      s = (guint32 *) srow;
-#else
-      s = srow;
-#endif
-      o = (guint16 *) orow;
-
-      xx = x1;
-      
-      /* check for first odd pixel */
-      if (xx & 1)
-       {
-         register guint16 data;
-#ifdef LITTLE
-         data = *((short *) s);
-#else
-         data = *((short *) s);
-         data = ((data >> 8) & 0xff) | ((data & 0xff) << 8);
-#endif
-         ((char *) o)[0] = (data & 0x7c00) >> 7 | (data & 0x7000) >> 12;
-         ((char *) o)[1] = (data & 0x3e0) >> 2 | (data & 0x380) >> 7;
-         ((char *) o)[2] = (data & 0x1f) << 3 | (data & 0x1c) >> 2;
-          ((char *) o) += 3;
-          ++xx;
-       }
-
-      g_assert (!(xx & 1));
-
-      /* if x2 is even, then the -1 does nothing to number of
-       * loop iterations, if x2 is odd then the -1 reduces
-       * iterations by one
-       */
-      for (; xx < (x2 - 1); xx += 2)
-       {
-         register guint32 data;
-#ifdef LITTLE
-         data = *s++;
-         *o++ = (data & 0x7c00) >> 7 | (data & 0x7000) >> 12
-           | (data & 0x3e0) << 6 | (data & 0x380) << 1;
-         *o++ = (data & 0x1f) << 3 | (data & 0x1c) >> 2
-           | (data & 0x7c000000) >> 15 | (data & 0x70000000) >> 20;
-         *o++ = (data & 0x3e00000) >> 18 | (data & 0x3800000) >> 23
-           | (data & 0x1f0000) >> 5 | (data & 0x1c0000) >> 10;
-#else
-         /* swap endianness first */
-         data = s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
-         s += 4;
-         *o++ = (data & 0x7c00) << 1 | (data & 0x7000) >> 4
-           | (data & 0x3e0) >> 2 | (data & 0x380) >> 7;
-         *o++ = (data & 0x1f) << 11 | (data & 0x1c) << 6
-           | (data & 0x7c000000) >> 23 | (data & 0x70000000) >> 28;
-         *o++ = (data & 0x3e00000) >> 10 | (data & 0x3800000) >> 15
-           | (data & 0x1f0000) >> 13 | (data & 0x1c0000) >> 18;
-#endif
-       }
-      /* check for last remaining pixel */
-      if (x2 & 1)
+      s = (guint16 *) srow;
+      o = (guint8 *) orow;
+      for (xx = x1; xx < x2; xx ++)
        {
-         register guint16 data;
-#ifdef LITTLE
-         data = *((short *) s);
-#else
-         data = *((short *) s);
-         data = ((data >> 8) & 0xff) | ((data & 0xff) << 8);
-#endif
-         ((char *) o)[0] = (data & 0x7c00) >> 7 | (data & 0x7000) >> 12;
-         ((char *) o)[1] = (data & 0x3e0) >> 2 | (data & 0x380) >> 7;
-         ((char *) o)[2] = (data & 0x1f) << 3 | (data & 0x1c) >> 2;
+         register guint32 data = *s++;
+#ifdef BIG
+         data = SWAP16 (data);
+#endif   
+         *o++ = R8fromRGB555 (data);
+         *o++ = G8fromRGB555 (data);
+         *o++ = B8fromRGB555 (data);
        }
       srow += bpl;
       orow += rowstride;
@@ -815,82 +644,26 @@ rgb555msb (GdkImage    *image,
   int xx, yy;
   int bpl;
 
-#ifdef LITTLE
-  register guint8 *s;  /* read 2 pixels at once */
-#else
-  register guint32 *s; /* read 2 pixels at once */
-#endif
-  register guint16 *o;
+  register guint16 *s;
+  register guint8 *o;
+
   guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
 
   bpl = image->bpl;
 
   for (yy = y1; yy < y2; yy++)
     {
-      s = srow;
-      o = (guint16 *) orow;
-
-      xx = x1;
-      /* See if first pixel is odd */
-      if (xx & 1)
-       {
-         register guint16 data;
-#ifdef LITTLE
-         data = *((short *) s);
-         data = ((data >> 8) & 0xff) | ((data & 0xff) << 8);
-#else
-         data = *((short *) s);
-#endif
-         ((char *) o)[0] = (data & 0x7c00) >> 7 | (data & 0x7000) >> 12;
-         ((char *) o)[1] = (data & 0x3e0) >> 2 | (data & 0x380) >> 7;
-         ((char *) o)[2] = (data & 0x1f) << 3 | (data & 0x1c) >> 2;
-
-          ((char *) o) += 3;
-          ++xx;
-       }
-
-      g_assert (!(xx & 1));
-
-      /* if x2 is even, then the -1 does nothing to number of
-       * loop iterations, if x2 is odd then the -1 reduces
-       * iterations by one
-       */
-      for (; xx < (x2 - 1); xx += 2)
-       {
-         register guint32 data;
-#ifdef LITTLE
-         /* swap endianness first */
-         data = s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
-         s += 4;
-         *o++ = (data & 0x7c00) >> 7 | (data & 0x7000) >> 12
-           | (data & 0x3e0) << 6 | (data & 0x380) << 1;
-         *o++ = (data & 0x1f) << 3 | (data & 0x1c) >> 2
-           | (data & 0x7c000000) >> 15 | (data & 0x70000000) >> 20;
-         *o++ = (data & 0x3e00000) >> 18 | (data & 0x3800000) >> 23
-           | (data & 0x1f0000) >> 5 | (data & 0x1c0000) >> 10;
-#else
-         data = *s++;
-         *o++ = (data & 0x7c00) << 1 | (data & 0x7000) >> 4
-           | (data & 0x3e0) >> 2 | (data & 0x380) >> 7;
-         *o++ = (data & 0x1f) << 11 | (data & 0x1c) << 6
-           | (data & 0x7c000000) >> 23 | (data & 0x70000000) >> 28;
-         *o++ = (data & 0x3e00000) >> 10 | (data & 0x3800000) >> 15
-           | (data & 0x1f0000) >> 13 | (data & 0x1c0000) >> 18;
-#endif
-       }
-      /* check for last remaining pixel */
-      if (x2 & 1)
+      s = (guint16 *) srow;
+      o = (guint8 *) orow;
+      for (xx = x1; xx < x2; xx ++)
        {
-         register guint16 data;
+         register guint32 data = *s++;
 #ifdef LITTLE
-         data = *((short *) s);
-         data = ((data >> 8) & 0xff) | ((data & 0xff) << 8);
-#else
-         data = *((short *) s);
-#endif
-         ((char *) o)[0] = (data & 0x7c00) >> 7 | (data & 0x7000) >> 12;
-         ((char *) o)[1] = (data & 0x3e0) >> 2 | (data & 0x380) >> 7;
-         ((char *) o)[2] = (data & 0x1f) << 3 | (data & 0x1c) >> 2;
+         data = SWAP16 (data);
+#endif   
+         *o++ = R8fromRGB555 (data);
+         *o++ = G8fromRGB555 (data);
+         *o++ = B8fromRGB555 (data);
        }
       srow += bpl;
       orow += rowstride;
@@ -915,11 +688,7 @@ rgb555alsb (GdkImage    *image,
   int xx, yy;
   int bpl;
 
-#ifdef LITTLE
   register guint16 *s; /* read 1 pixels at once */
-#else
-  register guint8 *s;
-#endif
   register guint32 *o;
 
   guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
@@ -928,31 +697,16 @@ rgb555alsb (GdkImage    *image,
 
   for (yy = y1; yy < y2; yy++)
     {
-#ifdef LITTLE
       s = (guint16 *) srow;
-#else
-      s = srow;
-#endif
       o = (guint32 *) orow;
       for (xx = x1; xx < x2; xx++)
        {
-         register guint32 data;
-         /*  rrrrrggg gggbbbbb -> rrrrrRRR gggggGGG bbbbbBBB aaaaaaaa */
-         /*  little endian: aaaaaaaa bbbbbBBB gggggGGG rrrrrRRR */
+         register guint32 data = *s++;
 #ifdef LITTLE
-         data = *s++;
-         *o++ = (data & 0x7c00) >> 7 | (data & 0x7000) >> 12
-           | (data & 0x3e0) << 6 | (data & 0x380) << 1
-           | (data & 0x1f) << 19 | (data & 0x1c) << 14
-           | 0xff000000;
+         *o++ = ABGR8888fromRGB555 (data);
 #else
-         /* swap endianness first */
-         data = s[0] | s[1] << 8;
-         s += 2;
-         *o++ = (data & 0x7c00) << 17 | (data & 0x7000) << 12
-           | (data & 0x3e0) << 14 | (data & 0x380) << 9
-           | (data & 0x1f) << 11 | (data & 0x1c) << 6
-           | 0xff;
+         data = SWAP16 (data);
+         *o++ = RGBA8888fromRGB555 (data);
 #endif
        }
       srow += bpl;
@@ -978,11 +732,7 @@ rgb555amsb (GdkImage    *image,
   int xx, yy;
   int bpl;
 
-#ifdef LITTLE
-  register guint16 *s; /* read 1 pixels at once */
-#else
-  register guint8 *s;
-#endif
+  register guint16 *s;
   register guint32 *o;
 
   guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
@@ -991,31 +741,16 @@ rgb555amsb (GdkImage    *image,
 
   for (yy = y1; yy < y2; yy++)
     {
-#ifdef LITTLE
       s = (guint16 *) srow;
-#else
-      s = srow;
-#endif
       o = (guint32 *) orow;
       for (xx = x1; xx < x2; xx++)
        {
-         register guint32 data;
-         /*  rrrrrggg gggbbbbb -> rrrrrRRR gggggGGG bbbbbBBB aaaaaaaa */
-         /*  little endian: aaaaaaaa bbbbbBBB gggggGGG rrrrrRRR */
+         register guint32 data = *s++;
 #ifdef LITTLE
-         /* swap endianness first */
-         data = s[0] | s[1] << 8;
-         s += 2;
-         *o++ = (data & 0x7c00) >> 7 | (data & 0x7000) >> 12
-           | (data & 0x3e0) << 6 | (data & 0x380) << 1
-           | (data & 0x1f) << 19 | (data & 0x1c) << 14
-           | 0xff000000;
+         data = SWAP16 (data);
+         *o++ = ABGR8888fromRGB555 (data);
 #else
-         data = *s++;
-         *o++ = (data & 0x7c00) << 17 | (data & 0x7000) << 12
-           | (data & 0x3e0) << 14 | (data & 0x380) << 9
-           | (data & 0x1f) << 11 | (data & 0x1c) << 6
-           | 0xff;
+         *o++ = RGBA8888fromRGB555 (data);
 #endif
        }
       srow += bpl;
@@ -1113,13 +848,8 @@ rgb888amsb (GdkImage    *image,
   int bpl;
 
   guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
-#ifdef LITTLE
   guint32 *o;
   guint32 *s;
-#else
-  guint8 *s;   /* for byte order swapping */
-  guint8 *o;
-#endif
 
   d (printf ("32 bit, msb, with alpha\n"));
 
@@ -1128,24 +858,14 @@ rgb888amsb (GdkImage    *image,
   /* msb data */
   for (yy = y1; yy < y2; yy++)
     {
-#ifdef LITTLE
       s = (guint32 *) srow;
       o = (guint32 *) orow;
-#else
-      s = srow;
-      o = orow;
-#endif
       for (xx = x1; xx < x2; xx++)
        {
 #ifdef LITTLE
-         *o++ = s[1];
-         *o++ = s[2];
-         *o++ = s[3];
-         *o++ = 0xff;
-         s += 4;
+         *o++ = (*s++ >> 8) | 0xff000000;
 #else
-         *o++ = (*s << 8) | 0xff; /* untested */
-         s++;
+         *o++ = (*s++ << 8) | 0xff;
 #endif
        }
       srow += bpl;
@@ -1206,7 +926,6 @@ convert_real_slow (GdkImage    *image,
                   gboolean     alpha)
 {
   int xx, yy;
-  int bpl;
   guint8 *orow = pixels;
   guint8 *o;
   guint32 pixel;
@@ -1214,9 +933,16 @@ convert_real_slow (GdkImage    *image,
   guint8 component;
   int i;
 
-  bpl = image->bpl;
-  v = gdk_colormap_get_visual(cmap);
+  v = gdk_colormap_get_visual (cmap);
 
+  if (image->depth != v->depth)
+    {
+      g_warning ("%s: The depth of the source image (%d) doesn't "
+                 "match the depth of the colormap passed in (%d).",
+                 G_STRLOC, image->depth, v->depth);
+      return;
+    } 
   d(printf("rgb  mask/shift/prec = %x:%x:%x %d:%d:%d  %d:%d:%d\n",
           v->red_mask, v->green_mask, v->blue_mask,
           v->red_shift, v->green_shift, v->blue_shift,
@@ -1227,7 +953,7 @@ convert_real_slow (GdkImage    *image,
       o = orow;
       for (xx = x1; xx < x2; xx++)
        {
-         pixel = gdk_image_get_pixel(image, xx, yy);
+         pixel = gdk_image_get_pixel (image, xx, yy);
          switch (v->type)
            {
                                /* I assume this is right for static & greyscale's too? */
@@ -1235,9 +961,9 @@ convert_real_slow (GdkImage    *image,
            case GDK_VISUAL_GRAYSCALE:
            case GDK_VISUAL_STATIC_COLOR:
            case GDK_VISUAL_PSEUDO_COLOR:
-             *o++ = cmap->colors[pixel].red;
-             *o++ = cmap->colors[pixel].green;
-             *o++ = cmap->colors[pixel].blue;
+             *o++ = cmap->colors[pixel].red   >> 8; 
+             *o++ = cmap->colors[pixel].green >> 8;
+             *o++ = cmap->colors[pixel].blue  >> 8;
              break;
            case GDK_VISUAL_TRUE_COLOR:
                                /* This is odd because it must sometimes shift left (otherwise
@@ -1258,9 +984,9 @@ convert_real_slow (GdkImage    *image,
              *o++ = component;
              break;
            case GDK_VISUAL_DIRECT_COLOR:
-             *o++ = cmap->colors[((pixel & v->red_mask) << (32 - v->red_shift - v->red_prec)) >> 24].red;
-             *o++ = cmap->colors[((pixel & v->green_mask) << (32 - v->green_shift - v->green_prec)) >> 24].green;
-             *o++ = cmap->colors[((pixel & v->blue_mask) << (32 - v->blue_shift - v->blue_prec)) >> 24].blue;
+             *o++ = cmap->colors[((pixel & v->red_mask) << (32 - v->red_shift - v->red_prec)) >> 24].red >> 8;
+             *o++ = cmap->colors[((pixel & v->green_mask) << (32 - v->green_shift - v->green_prec)) >> 24].green >> 8;
+             *o++ = cmap->colors[((pixel & v->blue_mask) << (32 - v->blue_shift - v->blue_prec)) >> 24].blue >> 8;
              break;
            }
          if (alpha)
@@ -1279,7 +1005,7 @@ typedef void (* cfunc) (GdkImage    *image,
                         int          y2,
                         GdkColormap *cmap);
 
-static cfunc convert_map[] = {
+static const cfunc convert_map[] = {
   rgb1,rgb1,rgb1a,rgb1a,
   rgb8,rgb8,rgb8a,rgb8a,
   rgb555lsb,rgb555msb,rgb555alsb,rgb555amsb,
@@ -1328,6 +1054,15 @@ rgbconvert (GdkImage    *image,
     }
   
   v = gdk_colormap_get_visual (cmap);
+
+  if (image->depth != v->depth)
+    {
+      g_warning ("%s: The depth of the source image (%d) doesn't "
+                 "match the depth of the colormap passed in (%d).",
+                 G_STRLOC, image->depth, v->depth);
+      return;
+    } 
   bank = 5; /* default fallback converter */
   index = (image->byte_order == GDK_MSB_FIRST) | (alpha != 0) << 1;
   
@@ -1401,7 +1136,7 @@ rgbconvert (GdkImage    *image,
 
 /**
  * gdk_pixbuf_get_from_drawable:
- * @dest: Destination pixbuf, or %NULL if a new pixbuf should be created.
+ * @dest: (allow-none): Destination pixbuf, or %NULL if a new pixbuf should be created.
  * @src: Source drawable.
  * @cmap: A colormap if @src doesn't have one set.
  * @src_x: Source X coordinate within drawable.
@@ -1496,17 +1231,10 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf   *dest,
     g_return_val_if_fail (dest_x == 0 && dest_y == 0, NULL);
   else
     {
-      g_return_val_if_fail (dest->colorspace == GDK_COLORSPACE_RGB, NULL);
-      g_return_val_if_fail (dest->n_channels == 3 || dest->n_channels == 4, NULL);
-      g_return_val_if_fail (dest->bits_per_sample == 8, NULL);
-    }
-
-  /* Create the pixbuf if needed */
-  if (!dest)
-    {
-      dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
-      if (dest == NULL)
-        return NULL;
+      g_return_val_if_fail (gdk_pixbuf_get_colorspace (dest) == GDK_COLORSPACE_RGB, NULL);
+      g_return_val_if_fail (gdk_pixbuf_get_n_channels (dest) == 3 ||
+                            gdk_pixbuf_get_n_channels (dest) == 4, NULL);
+      g_return_val_if_fail (gdk_pixbuf_get_bits_per_sample (dest) == 8, NULL);
     }
 
   if (cmap == NULL)
@@ -1522,6 +1250,14 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf   *dest,
       return NULL;
     }
   
+  if (cmap != NULL && depth != cmap->visual->depth)
+    {
+      g_warning ("%s: Depth of the source drawable is %d where as "
+                 "the visual depth of the colormap passed is %d",
+                 G_STRLOC, depth, cmap->visual->depth);
+      return NULL;
+    } 
   /* Coordinate sanity checks */
   
   if (GDK_IS_PIXMAP (src))
@@ -1536,11 +1272,19 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf   *dest,
       g_return_val_if_fail (src_x + width <= src_width && src_y + height <= src_height, NULL);
     }
 
+  /* Create the pixbuf if needed */
+  if (!dest)
+    {
+      dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
+      if (dest == NULL)
+        return NULL;
+    }
+  
   if (dest)
     {
       g_return_val_if_fail (dest_x >= 0 && dest_y >= 0, NULL);
-      g_return_val_if_fail (dest_x + width <= dest->width, NULL);
-      g_return_val_if_fail (dest_y + height <= dest->height, NULL);
+      g_return_val_if_fail (dest_x + width <= gdk_pixbuf_get_width (dest), NULL);
+      g_return_val_if_fail (dest_y + height <= gdk_pixbuf_get_height (dest), NULL);
     }
 
   for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
@@ -1552,10 +1296,11 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf   *dest,
          
          gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
          
-         image = _gdk_image_get_scratch (width1, height1, depth, &xs0, &ys0);
+         image = _gdk_image_get_scratch (gdk_drawable_get_screen (src), 
+                                         width1, height1, depth, &xs0, &ys0);
 
-         _gdk_drawable_copy_to_image (src, image,
-                                      src_x + x0, src_y + y0,
+         gdk_drawable_copy_to_image (src, image,
+                                     src_x + x0, src_y + y0,
                                       xs0, ys0, width1, height1);
 
          gdk_pixbuf_get_from_image (dest, image, cmap,
@@ -1569,9 +1314,9 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf   *dest,
         
 /**
  * gdk_pixbuf_get_from_image:
- * @dest: Destination pixbuf, or %NULL if a new pixbuf should be created.
+ * @dest: (allow-none): Destination pixbuf, or %NULL if a new pixbuf should be created.
  * @src: Source #GdkImage.
- * @cmap: A colormap, or %NULL to use the one for @src
+ * @cmap: (allow-none): A colormap, or %NULL to use the one for @src
  * @src_x: Source X coordinate within drawable.
  * @src_y: Source Y coordinate within drawable.
  * @dest_x: Destination X coordinate in pixbuf, or 0 if @dest is NULL.
@@ -1605,9 +1350,10 @@ gdk_pixbuf_get_from_image (GdkPixbuf   *dest,
     g_return_val_if_fail (dest_x == 0 && dest_y == 0, NULL);
   else
     {
-      g_return_val_if_fail (dest->colorspace == GDK_COLORSPACE_RGB, NULL);
-      g_return_val_if_fail (dest->n_channels == 3 || dest->n_channels == 4, NULL);
-      g_return_val_if_fail (dest->bits_per_sample == 8, NULL);
+      g_return_val_if_fail (gdk_pixbuf_get_colorspace (dest) == GDK_COLORSPACE_RGB, NULL);
+      g_return_val_if_fail (gdk_pixbuf_get_n_channels (dest) == 3 ||
+                            gdk_pixbuf_get_n_channels (dest) == 4, NULL);
+      g_return_val_if_fail (gdk_pixbuf_get_bits_per_sample (dest) == 8, NULL);
     }
 
   if (cmap == NULL)
@@ -1621,6 +1367,14 @@ gdk_pixbuf_get_from_image (GdkPixbuf   *dest,
       return NULL;
     }
   
+  if (cmap != NULL && src->depth != cmap->visual->depth)
+    {
+      g_warning ("%s: Depth of the Source image is %d where as "
+                 "the visual depth of the colormap passed is %d",
+                 G_STRLOC, src->depth, cmap->visual->depth);
+      return NULL;
+    } 
   /* Coordinate sanity checks */
 
   g_return_val_if_fail (src_x >= 0 && src_y >= 0, NULL);
@@ -1629,8 +1383,8 @@ gdk_pixbuf_get_from_image (GdkPixbuf   *dest,
   if (dest)
     {
       g_return_val_if_fail (dest_x >= 0 && dest_y >= 0, NULL);
-      g_return_val_if_fail (dest_x + width <= dest->width, NULL);
-      g_return_val_if_fail (dest_y + height <= dest->height, NULL);
+      g_return_val_if_fail (dest_x + width <= gdk_pixbuf_get_width (dest), NULL);
+      g_return_val_if_fail (dest_y + height <= gdk_pixbuf_get_height (dest), NULL);
     }
 
   /* Create the pixbuf if needed */
@@ -1641,14 +1395,14 @@ gdk_pixbuf_get_from_image (GdkPixbuf   *dest,
         return NULL;
     }
 
-  alpha = dest->has_alpha;
-  rowstride = dest->rowstride;
+  alpha = gdk_pixbuf_get_has_alpha (dest);
+  rowstride = gdk_pixbuf_get_rowstride (dest);
   bpp = alpha ? 4 : 3;
 
   /* we offset into the image data based on the position we are
    * retrieving from
    */
-  rgbconvert (src, dest->pixels +
+  rgbconvert (src, gdk_pixbuf_get_pixels (dest) +
              (dest_y * rowstride) + (dest_x * bpp),
              rowstride,
              alpha,
@@ -1659,3 +1413,6 @@ gdk_pixbuf_get_from_image (GdkPixbuf   *dest,
   
   return dest;
 }
+
+#define __GDK_PIXBUF_DRAWABLE_C__
+#include "gdkaliasdef.c"