Blame gdk/gdkpixbuf-drawable.c

Packit 98cdb6
/* GdkPixbuf library - convert X drawable information to RGB
Packit 98cdb6
 *
Packit 98cdb6
 * Copyright (C) 1999 Michael Zucchi
Packit 98cdb6
 *
Packit 98cdb6
 * Authors: Michael Zucchi <zucchi@zedzone.mmc.com.au>
Packit 98cdb6
 *          Cody Russell <bratsche@dfw.net>
Packit 98cdb6
 * 	    Federico Mena-Quintero <federico@gimp.org>
Packit 98cdb6
 *
Packit 98cdb6
 * This library is free software; you can redistribute it and/or
Packit 98cdb6
 * modify it under the terms of the GNU Lesser General Public
Packit 98cdb6
 * License as published by the Free Software Foundation; either
Packit 98cdb6
 * version 2 of the License, or (at your option) any later version.
Packit 98cdb6
 *
Packit 98cdb6
 * This library is distributed in the hope that it will be useful,
Packit 98cdb6
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 98cdb6
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 98cdb6
 * Lesser General Public License for more details.
Packit 98cdb6
 *
Packit 98cdb6
 * You should have received a copy of the GNU Lesser General Public
Packit 98cdb6
 * License along with this library; if not, write to the
Packit 98cdb6
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 98cdb6
 * Boston, MA 02111-1307, USA.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#include "config.h"
Packit 98cdb6
#include <stdio.h>
Packit 98cdb6
#include <string.h>
Packit 98cdb6
#include <gdk-pixbuf/gdk-pixbuf.h>
Packit 98cdb6
Packit 98cdb6
#include "gdkcolor.h"
Packit 98cdb6
#include "gdkimage.h"
Packit 98cdb6
#include "gdkvisual.h"
Packit 98cdb6
#include "gdkwindow.h"
Packit 98cdb6
#include "gdkpixbuf.h"
Packit 98cdb6
#include "gdkpixmap.h"
Packit 98cdb6
#include "gdkinternals.h"
Packit 98cdb6
#include "gdkalias.h"
Packit 98cdb6
Packit 98cdb6
/* Some convenient names
Packit 98cdb6
 */
Packit 98cdb6
#if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
Packit 98cdb6
#define LITTLE
Packit 98cdb6
#undef BIG
Packit 98cdb6
#else
Packit 98cdb6
#define BIG
Packit 98cdb6
#undef LITTLE
Packit 98cdb6
#endif
Packit 98cdb6
#define d(x)
Packit 98cdb6
Packit 98cdb6
#define SWAP16(d) GUINT16_SWAP_LE_BE(d)
Packit 98cdb6
Packit 98cdb6

Packit 98cdb6
Packit 98cdb6
static const guint32 mask_table[] = {
Packit 98cdb6
  0x00000000, 0x00000001, 0x00000003, 0x00000007,
Packit 98cdb6
  0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
Packit 98cdb6
  0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
Packit 98cdb6
  0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
Packit 98cdb6
  0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
Packit 98cdb6
  0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
Packit 98cdb6
  0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
Packit 98cdb6
  0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
Packit 98cdb6
  0xffffffff
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6

Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert bitmap data to pixbuf without alpha,
Packit 98cdb6
 * without using a colormap 
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
bitmap1 (GdkImage    *image,
Packit 98cdb6
         guchar      *pixels,
Packit 98cdb6
         int          rowstride,
Packit 98cdb6
         int          x1,
Packit 98cdb6
         int          y1,
Packit 98cdb6
         int          x2,
Packit 98cdb6
         int          y2)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
  register guint8 data;
Packit 98cdb6
  guint8 *o;
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl, *orow = pixels;
Packit 98cdb6
Packit 98cdb6
  d (printf ("bitmap, no alpha\n"));
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      o = orow;
Packit 98cdb6
      
Packit 98cdb6
      for (xx = x1; xx < x2; xx ++)
Packit 98cdb6
	{
Packit 98cdb6
          /* top 29 bits of xx (xx >> 3) indicate the byte the bit is inside,
Packit 98cdb6
           * bottom 3 bits (xx & 7) indicate bit inside that byte,
Packit 98cdb6
           * we don't bother to canonicalize data to 1 or 0, just
Packit 98cdb6
           * leave the relevant bit in-place.
Packit 98cdb6
           */
Packit 98cdb6
          data = srow[xx >> 3] & (image->byte_order == GDK_MSB_FIRST ?
Packit 98cdb6
                                  (0x80 >> (xx & 7)) :
Packit 98cdb6
                                  (1 << (xx & 7)));
Packit 98cdb6
Packit 98cdb6
          if (data)
Packit 98cdb6
            {
Packit 98cdb6
              *o++ = 255;
Packit 98cdb6
              *o++ = 255;
Packit 98cdb6
              *o++ = 255;
Packit 98cdb6
            }
Packit 98cdb6
          else
Packit 98cdb6
            {
Packit 98cdb6
              *o++ = 0;
Packit 98cdb6
              *o++ = 0;
Packit 98cdb6
              *o++ = 0;
Packit 98cdb6
            }
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert bitmap data to pixbuf with alpha,
Packit 98cdb6
 * without using a colormap 
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
bitmap1a (GdkImage    *image,
Packit 98cdb6
          guchar      *pixels,
Packit 98cdb6
          int          rowstride,
Packit 98cdb6
          int          x1,
Packit 98cdb6
          int          y1,
Packit 98cdb6
          int          x2,
Packit 98cdb6
          int          y2)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
  register guint8 data;
Packit 98cdb6
  guint8 *o;
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl, *orow = pixels;
Packit 98cdb6
Packit 98cdb6
  d (printf ("bitmap, with alpha\n"));
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      o = orow;
Packit 98cdb6
      
Packit 98cdb6
      for (xx = x1; xx < x2; xx ++)
Packit 98cdb6
	{
Packit 98cdb6
          /* see comment in bitmap1() */
Packit 98cdb6
          data = srow[xx >> 3] & (image->byte_order == GDK_MSB_FIRST ?
Packit 98cdb6
                                  (0x80 >> (xx & 7)) :
Packit 98cdb6
                                  (1 << (xx & 7)));
Packit 98cdb6
Packit 98cdb6
          if (data)
Packit 98cdb6
            {
Packit 98cdb6
              *o++ = 255;
Packit 98cdb6
              *o++ = 255;
Packit 98cdb6
              *o++ = 255;
Packit 98cdb6
              *o++ = 255;
Packit 98cdb6
            }
Packit 98cdb6
          else
Packit 98cdb6
            {
Packit 98cdb6
              *o++ = 0;
Packit 98cdb6
              *o++ = 0;
Packit 98cdb6
              *o++ = 0;
Packit 98cdb6
              *o++ = 0;
Packit 98cdb6
            }
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert 1 bits-pixel data
Packit 98cdb6
 * no alpha
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
rgb1 (GdkImage    *image,
Packit 98cdb6
      guchar      *pixels,
Packit 98cdb6
      int          rowstride,
Packit 98cdb6
      int          x1,
Packit 98cdb6
      int          y1,
Packit 98cdb6
      int          x2,
Packit 98cdb6
      int          y2,
Packit 98cdb6
      GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
  register guint8 data;
Packit 98cdb6
  guint8 *o;
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl, *orow = pixels;
Packit 98cdb6
Packit 98cdb6
  d (printf ("1 bits/pixel\n"));
Packit 98cdb6
Packit 98cdb6
  /* convert upto 8 pixels/time */
Packit 98cdb6
  /* its probably not worth trying to make this run very fast, who uses
Packit 98cdb6
   * 1 bit displays anymore?
Packit 98cdb6
   */
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      o = orow;
Packit 98cdb6
      
Packit 98cdb6
      for (xx = x1; xx < x2; xx ++)
Packit 98cdb6
	{
Packit 98cdb6
          /* see comment in bitmap1() */
Packit 98cdb6
          data = srow[xx >> 3] & (image->byte_order == GDK_MSB_FIRST ?
Packit 98cdb6
                                  (0x80 >> (xx & 7)) :
Packit 98cdb6
                                  (1 << (xx & 7)));
Packit 98cdb6
Packit 98cdb6
	  *o++ = colormap->colors[data].red   >> 8;
Packit 98cdb6
	  *o++ = colormap->colors[data].green >> 8;
Packit 98cdb6
	  *o++ = colormap->colors[data].blue  >> 8;
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert 1 bits/pixel data
Packit 98cdb6
 * with alpha
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
rgb1a (GdkImage    *image,
Packit 98cdb6
       guchar      *pixels,
Packit 98cdb6
       int          rowstride,
Packit 98cdb6
       int          x1,
Packit 98cdb6
       int          y1,
Packit 98cdb6
       int          x2,
Packit 98cdb6
       int          y2,
Packit 98cdb6
       GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
  register guint8 data;
Packit 98cdb6
  guint8 *o;
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl, *orow = pixels;
Packit 98cdb6
  
Packit 98cdb6
  d (printf ("1 bits/pixel\n"));
Packit 98cdb6
Packit 98cdb6
  /* convert upto 8 pixels/time */
Packit 98cdb6
  /* its probably not worth trying to make this run very fast, who uses
Packit 98cdb6
   * 1 bit displays anymore? */
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      o = orow;
Packit 98cdb6
      
Packit 98cdb6
      for (xx = x1; xx < x2; xx ++)
Packit 98cdb6
	{
Packit 98cdb6
          /* see comment in bitmap1() */
Packit 98cdb6
          data = srow[xx >> 3] & (image->byte_order == GDK_MSB_FIRST ?
Packit 98cdb6
                                  (0x80 >> (xx & 7)) :
Packit 98cdb6
                                  (1 << (xx & 7)));
Packit 98cdb6
Packit 98cdb6
          *o++ = colormap->colors[data].red   >> 8;
Packit 98cdb6
	  *o++ = colormap->colors[data].green >> 8;
Packit 98cdb6
	  *o++ = colormap->colors[data].blue  >> 8;
Packit 98cdb6
	  *o++ = 255;
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert 8 bits/pixel data
Packit 98cdb6
 * no alpha
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
rgb8 (GdkImage    *image,
Packit 98cdb6
      guchar      *pixels,
Packit 98cdb6
      int          rowstride,
Packit 98cdb6
      int          x1,
Packit 98cdb6
      int          y1,
Packit 98cdb6
      int          x2,
Packit 98cdb6
      int          y2,
Packit 98cdb6
      GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
  guint32 mask;
Packit 98cdb6
  register guint32 data;
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
  register guint8 *s;
Packit 98cdb6
  register guint8 *o;
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  d (printf ("8 bit, no alpha output\n"));
Packit 98cdb6
Packit 98cdb6
  mask = mask_table[image->depth];
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = srow;
Packit 98cdb6
      o = orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx++)
Packit 98cdb6
        {
Packit 98cdb6
          data = *s++ & mask;
Packit 98cdb6
          *o++ = colormap->colors[data].red   >> 8;
Packit 98cdb6
          *o++ = colormap->colors[data].green >> 8;
Packit 98cdb6
          *o++ = colormap->colors[data].blue  >> 8;
Packit 98cdb6
        }
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert 8 bits/pixel data
Packit 98cdb6
 * with alpha
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
rgb8a (GdkImage    *image,
Packit 98cdb6
       guchar      *pixels,
Packit 98cdb6
       int          rowstride,
Packit 98cdb6
       int          x1,
Packit 98cdb6
       int          y1,
Packit 98cdb6
       int          x2,
Packit 98cdb6
       int          y2,
Packit 98cdb6
       GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
  guint32 mask;
Packit 98cdb6
  register guint32 data;
Packit 98cdb6
  guint32 remap[256];
Packit 98cdb6
  register guint8 *s;	/* read 2 pixels at once */
Packit 98cdb6
  register guint32 *o;
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  d (printf ("8 bit, with alpha output\n"));
Packit 98cdb6
Packit 98cdb6
  mask = mask_table[image->depth];
Packit 98cdb6
Packit 98cdb6
  for (xx = x1; xx < colormap->size; xx++)
Packit 98cdb6
    {
Packit 98cdb6
#ifdef LITTLE
Packit 98cdb6
      remap[xx] = 0xff000000
Packit 98cdb6
	| (colormap->colors[xx].blue  & 0xff00) << 8
Packit 98cdb6
	| (colormap->colors[xx].green & 0xff00)
Packit 98cdb6
	| (colormap->colors[xx].red   >> 8);
Packit 98cdb6
#else
Packit 98cdb6
      remap[xx] = 0xff
Packit 98cdb6
	| (colormap->colors[xx].red   & 0xff00) << 16
Packit 98cdb6
	| (colormap->colors[xx].green & 0xff00) << 8
Packit 98cdb6
	| (colormap->colors[xx].blue  & 0xff00);
Packit 98cdb6
#endif
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = srow;
Packit 98cdb6
      o = (guint32 *) orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx ++)
Packit 98cdb6
	{
Packit 98cdb6
	  data = *s++ & mask;
Packit 98cdb6
	  *o++ = remap[data];
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* Bit shifting for 565 and 555 conversion routines
Packit 98cdb6
 *
Packit 98cdb6
 * RGB565 == rrrr rggg gggb bbbb, 16 bit native endian
Packit 98cdb6
 * RGB555 == xrrr rrgg gggb bbbb
Packit 98cdb6
 * ABGR8888: ARGB, 32-bit native endian
Packit 98cdb6
 * RGBA8888: RGBA, 32-bit native endian
Packit 98cdb6
 */
Packit 98cdb6
#define R8fromRGB565(d) ((((d) >> 8) & 0xf8) | (((d) >> 13) & 0x7))
Packit 98cdb6
#define G8fromRGB565(d) ((((d) >> 3) & 0xfc) | (((d) >> 9)  & 0x3))
Packit 98cdb6
#define B8fromRGB565(d) ((((d) << 3) & 0xf8) | (((d) >> 2)  & 0x7))
Packit 98cdb6
Packit 98cdb6
#define ABGR8888fromRGB565(d) (  ((d) & 0xf800) >> 8  | ((d) & 0xe000) >> 13 \
Packit 98cdb6
			       | ((d) & 0x07e0) << 5  | ((d) & 0x0600) >> 1  \
Packit 98cdb6
			       | ((d) & 0x001f) << 19 | ((d) & 0x001c) << 14 \
Packit 98cdb6
			       | 0xff000000)
Packit 98cdb6
#define RGBA8888fromRGB565(d) (  ((d) & 0xf800) << 16 | ((d) & 0xe000) << 11 \
Packit 98cdb6
			       | ((d) & 0x07e0) << 13 | ((d) & 0x0600) << 7  \
Packit 98cdb6
			       | ((d) & 0x001f) << 11 | ((d) & 0x001c) << 6  \
Packit 98cdb6
			       | 0xff)
Packit 98cdb6
Packit 98cdb6
#define R8fromRGB555(d) (((d) & 0x7c00) >> 7 | ((d) & 0x7000) >> 12)
Packit 98cdb6
#define G8fromRGB555(d) (((d) & 0x03e0) >> 2 | ((d) & 0x0380) >> 7)
Packit 98cdb6
#define B8fromRGB555(d) (((d) & 0x001f) << 3 | ((d) & 0x001c) >> 2)
Packit 98cdb6
Packit 98cdb6
#define ABGR8888fromRGB555(d) (  ((d) & 0x7c00) >> 7  | ((d) & 0x7000) >> 12 \
Packit 98cdb6
			       | ((d) & 0x03e0) << 6  | ((d) & 0x0380) << 1  \
Packit 98cdb6
			       | ((d) & 0x001f) << 19 | ((d) & 0x001c) << 14 \
Packit 98cdb6
			       | 0xff000000)
Packit 98cdb6
#define RGBA8888fromRGB555(d) (  ((d) & 0x7c00) << 17 | ((d) & 0x7000) << 12 \
Packit 98cdb6
			       | ((d) & 0x03e0) << 14 | ((d) & 0x0380) << 9  \
Packit 98cdb6
			       | ((d) & 0x001f) << 11 | ((d) & 0x001c) << 6  \
Packit 98cdb6
			       | 0xff)
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert 16 bits/pixel data
Packit 98cdb6
 * no alpha
Packit 98cdb6
 * data in lsb format
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
rgb565lsb (GdkImage    *image,
Packit 98cdb6
	   guchar      *pixels,
Packit 98cdb6
	   int          rowstride,
Packit 98cdb6
	   int          x1,
Packit 98cdb6
	   int          y1,
Packit 98cdb6
	   int          x2,
Packit 98cdb6
	   int          y2,
Packit 98cdb6
	   GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
Packit 98cdb6
  register guint16 *s;
Packit 98cdb6
  register guint8 *o;
Packit 98cdb6
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = (guint16 *) srow;
Packit 98cdb6
      o = (guint8 *) orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx ++)
Packit 98cdb6
	{
Packit 98cdb6
	  register guint32 data = *s++;
Packit 98cdb6
#ifdef BIG
Packit 98cdb6
	  data = SWAP16 (data);
Packit 98cdb6
#endif	  
Packit 98cdb6
	  *o++ = R8fromRGB565 (data);
Packit 98cdb6
	  *o++ = G8fromRGB565 (data);
Packit 98cdb6
	  *o++ = B8fromRGB565 (data);
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert 16 bits/pixel data
Packit 98cdb6
 * no alpha
Packit 98cdb6
 * data in msb format
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
rgb565msb (GdkImage    *image,
Packit 98cdb6
	   guchar      *pixels,
Packit 98cdb6
	   int          rowstride,
Packit 98cdb6
           int          x1,
Packit 98cdb6
           int          y1,
Packit 98cdb6
           int          x2,
Packit 98cdb6
           int          y2,
Packit 98cdb6
	   GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
Packit 98cdb6
  register guint16 *s;
Packit 98cdb6
  register guint8 *o;
Packit 98cdb6
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = (guint16 *) srow;
Packit 98cdb6
      o = (guint8 *) orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx ++)
Packit 98cdb6
	{
Packit 98cdb6
	  register guint32 data = *s++;
Packit 98cdb6
#ifdef LITTLE
Packit 98cdb6
	  data = SWAP16 (data);
Packit 98cdb6
#endif	  
Packit 98cdb6
	  *o++ = R8fromRGB565 (data);
Packit 98cdb6
	  *o++ = G8fromRGB565 (data);
Packit 98cdb6
	  *o++ = B8fromRGB565 (data);
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert 16 bits/pixel data
Packit 98cdb6
 * with alpha
Packit 98cdb6
 * data in lsb format
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
rgb565alsb (GdkImage    *image,
Packit 98cdb6
	    guchar      *pixels,
Packit 98cdb6
	    int          rowstride,
Packit 98cdb6
            int          x1,
Packit 98cdb6
            int          y1,
Packit 98cdb6
            int          x2,
Packit 98cdb6
            int          y2,
Packit 98cdb6
	    GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
Packit 98cdb6
  register guint16 *s;
Packit 98cdb6
  register guint32 *o;
Packit 98cdb6
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = (guint16 *) srow;
Packit 98cdb6
      o = (guint32 *) orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx ++)
Packit 98cdb6
	{
Packit 98cdb6
	  register guint32 data = *s++;
Packit 98cdb6
#ifdef LITTLE
Packit 98cdb6
	  *o++ = ABGR8888fromRGB565 (data);
Packit 98cdb6
#else
Packit 98cdb6
	  data = SWAP16 (data);
Packit 98cdb6
	  *o++ = RGBA8888fromRGB565 (data);
Packit 98cdb6
#endif
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert 16 bits/pixel data
Packit 98cdb6
 * with alpha
Packit 98cdb6
 * data in msb format
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
rgb565amsb (GdkImage    *image,
Packit 98cdb6
	    guchar      *pixels,
Packit 98cdb6
	    int          rowstride,
Packit 98cdb6
            int          x1,
Packit 98cdb6
            int          y1,
Packit 98cdb6
            int          x2,
Packit 98cdb6
            int          y2,
Packit 98cdb6
	    GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
Packit 98cdb6
  register guint16 *s;
Packit 98cdb6
  register guint32 *o;
Packit 98cdb6
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = (guint16 *) srow;
Packit 98cdb6
      o = (guint32 *) orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx ++)
Packit 98cdb6
	{
Packit 98cdb6
	  register guint32 data = *s++;
Packit 98cdb6
#ifdef LITTLE
Packit 98cdb6
	  data = SWAP16 (data);
Packit 98cdb6
	  *o++ = ABGR8888fromRGB565 (data);
Packit 98cdb6
#else
Packit 98cdb6
	  *o++ = RGBA8888fromRGB565 (data);
Packit 98cdb6
#endif
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert 15 bits/pixel data
Packit 98cdb6
 * no alpha
Packit 98cdb6
 * data in lsb format
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
rgb555lsb (GdkImage     *image,
Packit 98cdb6
	   guchar       *pixels,
Packit 98cdb6
	   int           rowstride,
Packit 98cdb6
           int          x1,
Packit 98cdb6
           int          y1,
Packit 98cdb6
           int          x2,
Packit 98cdb6
           int          y2,
Packit 98cdb6
	   GdkColormap  *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
Packit 98cdb6
  register guint16 *s;
Packit 98cdb6
  register guint8 *o;
Packit 98cdb6
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = (guint16 *) srow;
Packit 98cdb6
      o = (guint8 *) orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx ++)
Packit 98cdb6
	{
Packit 98cdb6
	  register guint32 data = *s++;
Packit 98cdb6
#ifdef BIG
Packit 98cdb6
	  data = SWAP16 (data);
Packit 98cdb6
#endif	  
Packit 98cdb6
	  *o++ = R8fromRGB555 (data);
Packit 98cdb6
	  *o++ = G8fromRGB555 (data);
Packit 98cdb6
	  *o++ = B8fromRGB555 (data);
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert 15 bits/pixel data
Packit 98cdb6
 * no alpha
Packit 98cdb6
 * data in msb format
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
rgb555msb (GdkImage    *image,
Packit 98cdb6
	   guchar      *pixels,
Packit 98cdb6
	   int          rowstride,
Packit 98cdb6
           int          x1,
Packit 98cdb6
           int          y1,
Packit 98cdb6
           int          x2,
Packit 98cdb6
           int          y2,
Packit 98cdb6
	   GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
Packit 98cdb6
  register guint16 *s;
Packit 98cdb6
  register guint8 *o;
Packit 98cdb6
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = (guint16 *) srow;
Packit 98cdb6
      o = (guint8 *) orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx ++)
Packit 98cdb6
	{
Packit 98cdb6
	  register guint32 data = *s++;
Packit 98cdb6
#ifdef LITTLE
Packit 98cdb6
	  data = SWAP16 (data);
Packit 98cdb6
#endif	  
Packit 98cdb6
	  *o++ = R8fromRGB555 (data);
Packit 98cdb6
	  *o++ = G8fromRGB555 (data);
Packit 98cdb6
	  *o++ = B8fromRGB555 (data);
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert 15 bits/pixel data
Packit 98cdb6
 * with alpha
Packit 98cdb6
 * data in lsb format
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
rgb555alsb (GdkImage    *image,
Packit 98cdb6
	    guchar      *pixels,
Packit 98cdb6
	    int          rowstride,
Packit 98cdb6
            int          x1,
Packit 98cdb6
            int          y1,
Packit 98cdb6
            int          x2,
Packit 98cdb6
            int          y2,
Packit 98cdb6
	    GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
Packit 98cdb6
  register guint16 *s;	/* read 1 pixels at once */
Packit 98cdb6
  register guint32 *o;
Packit 98cdb6
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = (guint16 *) srow;
Packit 98cdb6
      o = (guint32 *) orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx++)
Packit 98cdb6
	{
Packit 98cdb6
	  register guint32 data = *s++;
Packit 98cdb6
#ifdef LITTLE
Packit 98cdb6
	  *o++ = ABGR8888fromRGB555 (data);
Packit 98cdb6
#else
Packit 98cdb6
	  data = SWAP16 (data);
Packit 98cdb6
	  *o++ = RGBA8888fromRGB555 (data);
Packit 98cdb6
#endif
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * convert 15 bits/pixel data
Packit 98cdb6
 * with alpha
Packit 98cdb6
 * data in msb format
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
rgb555amsb (GdkImage    *image,
Packit 98cdb6
	    guchar      *pixels,
Packit 98cdb6
	    int          rowstride,
Packit 98cdb6
            int          x1,
Packit 98cdb6
            int          y1,
Packit 98cdb6
            int          x2,
Packit 98cdb6
            int          y2,
Packit 98cdb6
	    GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
Packit 98cdb6
  register guint16 *s;
Packit 98cdb6
  register guint32 *o;
Packit 98cdb6
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = (guint16 *) srow;
Packit 98cdb6
      o = (guint32 *) orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx++)
Packit 98cdb6
	{
Packit 98cdb6
	  register guint32 data = *s++;
Packit 98cdb6
#ifdef LITTLE
Packit 98cdb6
	  data = SWAP16 (data);
Packit 98cdb6
	  *o++ = ABGR8888fromRGB555 (data);
Packit 98cdb6
#else
Packit 98cdb6
	  *o++ = RGBA8888fromRGB555 (data);
Packit 98cdb6
#endif
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
rgb888alsb (GdkImage    *image,
Packit 98cdb6
	    guchar      *pixels,
Packit 98cdb6
	    int          rowstride,
Packit 98cdb6
            int          x1,
Packit 98cdb6
            int          y1,
Packit 98cdb6
            int          x2,
Packit 98cdb6
            int          y2,
Packit 98cdb6
	    GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
Packit 98cdb6
  guint8 *s;	/* for byte order swapping */
Packit 98cdb6
  guint8 *o;
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  d (printf ("32 bits/pixel with alpha\n"));
Packit 98cdb6
Packit 98cdb6
  /* lsb data */
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = srow;
Packit 98cdb6
      o = orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx++)
Packit 98cdb6
	{
Packit 98cdb6
	  *o++ = s[2];
Packit 98cdb6
	  *o++ = s[1];
Packit 98cdb6
	  *o++ = s[0];
Packit 98cdb6
	  *o++ = 0xff;
Packit 98cdb6
	  s += 4;
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
rgb888lsb (GdkImage    *image,
Packit 98cdb6
	   guchar      *pixels,
Packit 98cdb6
	   int          rowstride,
Packit 98cdb6
           int          x1,
Packit 98cdb6
           int          y1,
Packit 98cdb6
           int          x2,
Packit 98cdb6
           int          y2,
Packit 98cdb6
	   GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
  guint8 *o, *s;
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  d (printf ("32 bit, lsb, no alpha\n"));
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = srow;
Packit 98cdb6
      o = orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx++)
Packit 98cdb6
	{
Packit 98cdb6
	  *o++ = s[2];
Packit 98cdb6
	  *o++ = s[1];
Packit 98cdb6
	  *o++ = s[0];
Packit 98cdb6
	  s += 4;
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
rgb888amsb (GdkImage    *image,
Packit 98cdb6
	    guchar      *pixels,
Packit 98cdb6
	    int          rowstride,
Packit 98cdb6
            int          x1,
Packit 98cdb6
            int          y1,
Packit 98cdb6
            int          x2,
Packit 98cdb6
            int          y2,
Packit 98cdb6
	    GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
  guint32 *o;
Packit 98cdb6
  guint32 *s;
Packit 98cdb6
Packit 98cdb6
  d (printf ("32 bit, msb, with alpha\n"));
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  /* msb data */
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = (guint32 *) srow;
Packit 98cdb6
      o = (guint32 *) orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx++)
Packit 98cdb6
	{
Packit 98cdb6
#ifdef LITTLE
Packit 98cdb6
	  *o++ = (*s++ >> 8) | 0xff000000;
Packit 98cdb6
#else
Packit 98cdb6
	  *o++ = (*s++ << 8) | 0xff;
Packit 98cdb6
#endif
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
rgb888msb (GdkImage    *image,
Packit 98cdb6
	   guchar      *pixels,
Packit 98cdb6
	   int          rowstride,
Packit 98cdb6
           int          x1,
Packit 98cdb6
           int          y1,
Packit 98cdb6
           int          x2,
Packit 98cdb6
           int          y2,
Packit 98cdb6
	   GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  int bpl;
Packit 98cdb6
Packit 98cdb6
  guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
Packit 98cdb6
  guint8 *s;
Packit 98cdb6
  guint8 *o;
Packit 98cdb6
Packit 98cdb6
  d (printf ("32 bit, msb, no alpha\n"));
Packit 98cdb6
Packit 98cdb6
  bpl = image->bpl;
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      s = srow;
Packit 98cdb6
      o = orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx++)
Packit 98cdb6
	{
Packit 98cdb6
	  *o++ = s[1];
Packit 98cdb6
	  *o++ = s[2];
Packit 98cdb6
	  *o++ = s[3];
Packit 98cdb6
	  s += 4;
Packit 98cdb6
	}
Packit 98cdb6
      srow += bpl;
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * This should work correctly with any display/any endianness, but will probably
Packit 98cdb6
 * run quite slow
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
convert_real_slow (GdkImage    *image,
Packit 98cdb6
		   guchar      *pixels,
Packit 98cdb6
		   int          rowstride,
Packit 98cdb6
                   int          x1,
Packit 98cdb6
                   int          y1,
Packit 98cdb6
                   int          x2,
Packit 98cdb6
                   int          y2,
Packit 98cdb6
		   GdkColormap *cmap,
Packit 98cdb6
		   gboolean     alpha)
Packit 98cdb6
{
Packit 98cdb6
  int xx, yy;
Packit 98cdb6
  guint8 *orow = pixels;
Packit 98cdb6
  guint8 *o;
Packit 98cdb6
  guint32 pixel;
Packit 98cdb6
  GdkVisual *v;
Packit 98cdb6
  guint8 component;
Packit 98cdb6
  int i;
Packit 98cdb6
Packit 98cdb6
  v = gdk_colormap_get_visual (cmap);
Packit 98cdb6
Packit 98cdb6
  if (image->depth != v->depth)
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("%s: The depth of the source image (%d) doesn't "
Packit 98cdb6
                 "match the depth of the colormap passed in (%d).",
Packit 98cdb6
                 G_STRLOC, image->depth, v->depth);
Packit 98cdb6
      return;
Packit 98cdb6
    } 
Packit 98cdb6
 
Packit 98cdb6
  d(printf("rgb  mask/shift/prec = %x:%x:%x %d:%d:%d  %d:%d:%d\n",
Packit 98cdb6
	   v->red_mask, v->green_mask, v->blue_mask,
Packit 98cdb6
	   v->red_shift, v->green_shift, v->blue_shift,
Packit 98cdb6
	   v->red_prec, v->green_prec, v->blue_prec));
Packit 98cdb6
Packit 98cdb6
  for (yy = y1; yy < y2; yy++)
Packit 98cdb6
    {
Packit 98cdb6
      o = orow;
Packit 98cdb6
      for (xx = x1; xx < x2; xx++)
Packit 98cdb6
	{
Packit 98cdb6
	  pixel = gdk_image_get_pixel (image, xx, yy);
Packit 98cdb6
	  switch (v->type)
Packit 98cdb6
	    {
Packit 98cdb6
				/* I assume this is right for static & greyscale's too? */
Packit 98cdb6
	    case GDK_VISUAL_STATIC_GRAY:
Packit 98cdb6
	    case GDK_VISUAL_GRAYSCALE:
Packit 98cdb6
	    case GDK_VISUAL_STATIC_COLOR:
Packit 98cdb6
	    case GDK_VISUAL_PSEUDO_COLOR:
Packit 98cdb6
	      *o++ = cmap->colors[pixel].red   >> 8; 
Packit 98cdb6
	      *o++ = cmap->colors[pixel].green >> 8;
Packit 98cdb6
	      *o++ = cmap->colors[pixel].blue  >> 8;
Packit 98cdb6
	      break;
Packit 98cdb6
	    case GDK_VISUAL_TRUE_COLOR:
Packit 98cdb6
				/* This is odd because it must sometimes shift left (otherwise
Packit 98cdb6
				 * I'd just shift >> (*_shift - 8 + *_prec + <0-7>). This logic
Packit 98cdb6
				 * should work for all bit sizes/shifts/etc.
Packit 98cdb6
				 */
Packit 98cdb6
	      component = 0;
Packit 98cdb6
	      for (i = 24; i < 32; i += v->red_prec)
Packit 98cdb6
		component |= ((pixel & v->red_mask) << (32 - v->red_shift - v->red_prec)) >> i;
Packit 98cdb6
	      *o++ = component;
Packit 98cdb6
	      component = 0;
Packit 98cdb6
	      for (i = 24; i < 32; i += v->green_prec)
Packit 98cdb6
		component |= ((pixel & v->green_mask) << (32 - v->green_shift - v->green_prec)) >> i;
Packit 98cdb6
	      *o++ = component;
Packit 98cdb6
	      component = 0;
Packit 98cdb6
	      for (i = 24; i < 32; i += v->blue_prec)
Packit 98cdb6
		component |= ((pixel & v->blue_mask) << (32 - v->blue_shift - v->blue_prec)) >> i;
Packit 98cdb6
	      *o++ = component;
Packit 98cdb6
	      break;
Packit 98cdb6
	    case GDK_VISUAL_DIRECT_COLOR:
Packit 98cdb6
	      *o++ = cmap->colors[((pixel & v->red_mask) << (32 - v->red_shift - v->red_prec)) >> 24].red >> 8;
Packit 98cdb6
	      *o++ = cmap->colors[((pixel & v->green_mask) << (32 - v->green_shift - v->green_prec)) >> 24].green >> 8;
Packit 98cdb6
	      *o++ = cmap->colors[((pixel & v->blue_mask) << (32 - v->blue_shift - v->blue_prec)) >> 24].blue >> 8;
Packit 98cdb6
	      break;
Packit 98cdb6
	    }
Packit 98cdb6
	  if (alpha)
Packit 98cdb6
	    *o++ = 0xff;
Packit 98cdb6
	}
Packit 98cdb6
      orow += rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
typedef void (* cfunc) (GdkImage    *image,
Packit 98cdb6
                        guchar      *pixels,
Packit 98cdb6
                        int          rowstride,
Packit 98cdb6
                        int          x1,
Packit 98cdb6
                        int          y1,
Packit 98cdb6
                        int          x2,
Packit 98cdb6
                        int          y2,
Packit 98cdb6
                        GdkColormap *cmap);
Packit 98cdb6
Packit 98cdb6
static const cfunc convert_map[] = {
Packit 98cdb6
  rgb1,rgb1,rgb1a,rgb1a,
Packit 98cdb6
  rgb8,rgb8,rgb8a,rgb8a,
Packit 98cdb6
  rgb555lsb,rgb555msb,rgb555alsb,rgb555amsb,
Packit 98cdb6
  rgb565lsb,rgb565msb,rgb565alsb,rgb565amsb,
Packit 98cdb6
  rgb888lsb,rgb888msb,rgb888alsb,rgb888amsb
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * perform actual conversion
Packit 98cdb6
 *
Packit 98cdb6
 *  If we can, try and use the optimised code versions, but as a default
Packit 98cdb6
 * fallback, and always for direct colour, use the generic/slow but complete
Packit 98cdb6
 * conversion function.
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
rgbconvert (GdkImage    *image,
Packit 98cdb6
	    guchar      *pixels,
Packit 98cdb6
	    int          rowstride,
Packit 98cdb6
	    gboolean     alpha,
Packit 98cdb6
            int          x,
Packit 98cdb6
            int          y,
Packit 98cdb6
            int          width,
Packit 98cdb6
            int          height,
Packit 98cdb6
	    GdkColormap *cmap)
Packit 98cdb6
{
Packit 98cdb6
  int index;
Packit 98cdb6
  int bank;
Packit 98cdb6
  GdkVisual *v;
Packit 98cdb6
Packit 98cdb6
  g_assert ((x + width) <= image->width);
Packit 98cdb6
  g_assert ((y + height) <= image->height);
Packit 98cdb6
  
Packit 98cdb6
  if (cmap == NULL)
Packit 98cdb6
    {
Packit 98cdb6
      /* Only allowed for bitmaps */
Packit 98cdb6
      g_return_if_fail (image->depth == 1);
Packit 98cdb6
      
Packit 98cdb6
      if (alpha)
Packit 98cdb6
        bitmap1a (image, pixels, rowstride,
Packit 98cdb6
                  x, y, x + width, y + height);
Packit 98cdb6
      else
Packit 98cdb6
        bitmap1 (image, pixels, rowstride,
Packit 98cdb6
                  x, y, x + width, y + height);
Packit 98cdb6
      
Packit 98cdb6
      return;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  v = gdk_colormap_get_visual (cmap);
Packit 98cdb6
Packit 98cdb6
  if (image->depth != v->depth)
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("%s: The depth of the source image (%d) doesn't "
Packit 98cdb6
                 "match the depth of the colormap passed in (%d).",
Packit 98cdb6
                 G_STRLOC, image->depth, v->depth);
Packit 98cdb6
      return;
Packit 98cdb6
    } 
Packit 98cdb6
 
Packit 98cdb6
  bank = 5; /* default fallback converter */
Packit 98cdb6
  index = (image->byte_order == GDK_MSB_FIRST) | (alpha != 0) << 1;
Packit 98cdb6
  
Packit 98cdb6
  d(printf("masks = %x:%x:%x\n", v->red_mask, v->green_mask, v->blue_mask));
Packit 98cdb6
  d(printf("image depth = %d, bits per pixel = %d\n", image->depth, image->bits_per_pixel));
Packit 98cdb6
  
Packit 98cdb6
  switch (v->type)
Packit 98cdb6
    {
Packit 98cdb6
				/* I assume this is right for static & greyscale's too? */
Packit 98cdb6
    case GDK_VISUAL_STATIC_GRAY:
Packit 98cdb6
    case GDK_VISUAL_GRAYSCALE:
Packit 98cdb6
    case GDK_VISUAL_STATIC_COLOR:
Packit 98cdb6
    case GDK_VISUAL_PSEUDO_COLOR:
Packit 98cdb6
      switch (image->bits_per_pixel)
Packit 98cdb6
	{
Packit 98cdb6
	case 1:
Packit 98cdb6
	  bank = 0;
Packit 98cdb6
	  break;
Packit 98cdb6
	case 8:
Packit 98cdb6
	  if (image->depth == 8)
Packit 98cdb6
	    bank = 1;
Packit 98cdb6
	  break;
Packit 98cdb6
	}
Packit 98cdb6
      break;
Packit 98cdb6
    case GDK_VISUAL_TRUE_COLOR:
Packit 98cdb6
      switch (image->depth)
Packit 98cdb6
	{
Packit 98cdb6
	case 15:
Packit 98cdb6
	  if (v->red_mask == 0x7c00 && v->green_mask == 0x3e0 && v->blue_mask == 0x1f
Packit 98cdb6
	      && image->bits_per_pixel == 16)
Packit 98cdb6
	    bank = 2;
Packit 98cdb6
	  break;
Packit 98cdb6
	case 16:
Packit 98cdb6
	  if (v->red_mask == 0xf800 && v->green_mask == 0x7e0 && v->blue_mask == 0x1f
Packit 98cdb6
	      && image->bits_per_pixel == 16)
Packit 98cdb6
	    bank = 3;
Packit 98cdb6
	  break;
Packit 98cdb6
	case 24:
Packit 98cdb6
	case 32:
Packit 98cdb6
	  if (v->red_mask == 0xff0000 && v->green_mask == 0xff00 && v->blue_mask == 0xff
Packit 98cdb6
	      && image->bits_per_pixel == 32)
Packit 98cdb6
	    bank = 4;
Packit 98cdb6
	  break;
Packit 98cdb6
	}
Packit 98cdb6
      break;
Packit 98cdb6
    case GDK_VISUAL_DIRECT_COLOR:
Packit 98cdb6
      /* always use the slow version */
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  d (g_print ("converting using conversion function in bank %d\n", bank));
Packit 98cdb6
Packit 98cdb6
  if (bank == 5)
Packit 98cdb6
    {
Packit 98cdb6
      convert_real_slow (image, pixels, rowstride,
Packit 98cdb6
                         x, y, x + width, y + height,                         
Packit 98cdb6
                         cmap, alpha);
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      index |= bank << 2;
Packit 98cdb6
      d (g_print ("converting with index %d\n", index));
Packit 98cdb6
      (* convert_map[index]) (image, pixels, rowstride,
Packit 98cdb6
                              x, y, x + width, y + height,
Packit 98cdb6
                              cmap);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
/* Exported functions */
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pixbuf_get_from_drawable:
Packit 98cdb6
 * @dest: (allow-none): Destination pixbuf, or %NULL if a new pixbuf should be created.
Packit 98cdb6
 * @src: Source drawable.
Packit 98cdb6
 * @cmap: A colormap if @src doesn't have one set.
Packit 98cdb6
 * @src_x: Source X coordinate within drawable.
Packit 98cdb6
 * @src_y: Source Y coordinate within drawable.
Packit 98cdb6
 * @dest_x: Destination X coordinate in pixbuf, or 0 if @dest is NULL.
Packit 98cdb6
 * @dest_y: Destination Y coordinate in pixbuf, or 0 if @dest is NULL.
Packit 98cdb6
 * @width: Width in pixels of region to get.
Packit 98cdb6
 * @height: Height in pixels of region to get.
Packit 98cdb6
 *
Packit 98cdb6
 * Transfers image data from a #GdkDrawable and converts it to an RGB(A)
Packit 98cdb6
 * representation inside a #GdkPixbuf. In other words, copies
Packit 98cdb6
 * image data from a server-side drawable to a client-side RGB(A) buffer.
Packit 98cdb6
 * This allows you to efficiently read individual pixels on the client side.
Packit 98cdb6
 * 
Packit 98cdb6
 * If the drawable @src has no colormap (gdk_drawable_get_colormap()
Packit 98cdb6
 * returns %NULL), then a suitable colormap must be specified.
Packit 98cdb6
 * Typically a #GdkWindow or a pixmap created by passing a #GdkWindow
Packit 98cdb6
 * to gdk_pixmap_new() will already have a colormap associated with
Packit 98cdb6
 * it.  If the drawable has a colormap, the @cmap argument will be
Packit 98cdb6
 * ignored.  If the drawable is a bitmap (1 bit per pixel pixmap),
Packit 98cdb6
 * then a colormap is not required; pixels with a value of 1 are
Packit 98cdb6
 * assumed to be white, and pixels with a value of 0 are assumed to be
Packit 98cdb6
 * black. For taking screenshots, gdk_colormap_get_system() returns
Packit 98cdb6
 * the correct colormap to use.
Packit 98cdb6
 *
Packit 98cdb6
 * If the specified destination pixbuf @dest is %NULL, then this
Packit 98cdb6
 * function will create an RGB pixbuf with 8 bits per channel and no
Packit 98cdb6
 * alpha, with the same size specified by the @width and @height
Packit 98cdb6
 * arguments.  In this case, the @dest_x and @dest_y arguments must be
Packit 98cdb6
 * specified as 0.  If the specified destination pixbuf is not %NULL
Packit 98cdb6
 * and it contains alpha information, then the filled pixels will be
Packit 98cdb6
 * set to full opacity (alpha = 255).
Packit 98cdb6
 *
Packit 98cdb6
 * If the specified drawable is a pixmap, then the requested source
Packit 98cdb6
 * rectangle must be completely contained within the pixmap, otherwise
Packit 98cdb6
 * the function will return %NULL. For pixmaps only (not for windows)
Packit 98cdb6
 * passing -1 for width or height is allowed to mean the full width
Packit 98cdb6
 * or height of the pixmap.
Packit 98cdb6
 *
Packit 98cdb6
 * If the specified drawable is a window, and the window is off the
Packit 98cdb6
 * screen, then there is no image data in the obscured/offscreen
Packit 98cdb6
 * regions to be placed in the pixbuf. The contents of portions of the
Packit 98cdb6
 * pixbuf corresponding to the offscreen region are undefined.
Packit 98cdb6
 *
Packit 98cdb6
 * If the window you're obtaining data from is partially obscured by
Packit 98cdb6
 * other windows, then the contents of the pixbuf areas corresponding
Packit 98cdb6
 * to the obscured regions are undefined.
Packit 98cdb6
 * 
Packit 98cdb6
 * If the target drawable is not mapped (typically because it's
Packit 98cdb6
 * iconified/minimized or not on the current workspace), then %NULL
Packit 98cdb6
 * will be returned.
Packit 98cdb6
 *
Packit 98cdb6
 * If memory can't be allocated for the return value, %NULL will be returned
Packit 98cdb6
 * instead.
Packit 98cdb6
 *
Packit 98cdb6
 * (In short, there are several ways this function can fail, and if it fails
Packit 98cdb6
 *  it returns %NULL; so check the return value.)
Packit 98cdb6
 *
Packit 98cdb6
 * This function calls gdk_drawable_get_image() internally and
Packit 98cdb6
 * converts the resulting image to a #GdkPixbuf, so the
Packit 98cdb6
 * documentation for gdk_drawable_get_image() may also be relevant.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: The same pixbuf as @dest if it was non-%NULL, or a newly-created
Packit 98cdb6
 * pixbuf with a reference count of 1 if no destination pixbuf was specified, or %NULL on error
Packit 98cdb6
 **/
Packit 98cdb6
GdkPixbuf *
Packit 98cdb6
gdk_pixbuf_get_from_drawable (GdkPixbuf   *dest,
Packit 98cdb6
			      GdkDrawable *src,
Packit 98cdb6
			      GdkColormap *cmap,
Packit 98cdb6
			      int src_x,  int src_y,
Packit 98cdb6
			      int dest_x, int dest_y,
Packit 98cdb6
			      int width,  int height)
Packit 98cdb6
{
Packit 98cdb6
  int src_width, src_height;
Packit 98cdb6
  GdkImage *image;
Packit 98cdb6
  int depth;
Packit 98cdb6
  int x0, y0;
Packit 98cdb6
  
Packit 98cdb6
  /* General sanity checks */
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (src != NULL, NULL);
Packit 98cdb6
Packit 98cdb6
  if (GDK_IS_WINDOW (src))
Packit 98cdb6
    /* FIXME: this is not perfect, since is_viewable() only tests
Packit 98cdb6
     * recursively up the Gdk parent window tree, but stops at
Packit 98cdb6
     * foreign windows or Gdk toplevels.  I.e. if a window manager
Packit 98cdb6
     * unmapped one of its own windows, this won't work.
Packit 98cdb6
     */
Packit 98cdb6
    g_return_val_if_fail (gdk_window_is_viewable (src), NULL);
Packit 98cdb6
Packit 98cdb6
  if (!dest)
Packit 98cdb6
    g_return_val_if_fail (dest_x == 0 && dest_y == 0, NULL);
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      g_return_val_if_fail (gdk_pixbuf_get_colorspace (dest) == GDK_COLORSPACE_RGB, NULL);
Packit 98cdb6
      g_return_val_if_fail (gdk_pixbuf_get_n_channels (dest) == 3 ||
Packit 98cdb6
                            gdk_pixbuf_get_n_channels (dest) == 4, NULL);
Packit 98cdb6
      g_return_val_if_fail (gdk_pixbuf_get_bits_per_sample (dest) == 8, NULL);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (cmap == NULL)
Packit 98cdb6
    cmap = gdk_drawable_get_colormap (src);
Packit 98cdb6
Packit 98cdb6
  depth = gdk_drawable_get_depth (src);
Packit 98cdb6
  
Packit 98cdb6
  if (depth != 1 && cmap == NULL)
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("%s: Source drawable has no colormap; either pass "
Packit 98cdb6
                 "in a colormap, or set the colormap on the drawable "
Packit 98cdb6
                 "with gdk_drawable_set_colormap()", G_STRLOC);
Packit 98cdb6
      return NULL;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  if (cmap != NULL && depth != cmap->visual->depth)
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("%s: Depth of the source drawable is %d where as "
Packit 98cdb6
                 "the visual depth of the colormap passed is %d",
Packit 98cdb6
                 G_STRLOC, depth, cmap->visual->depth);
Packit 98cdb6
      return NULL;
Packit 98cdb6
    } 
Packit 98cdb6
 
Packit 98cdb6
  /* Coordinate sanity checks */
Packit 98cdb6
  
Packit 98cdb6
  if (GDK_IS_PIXMAP (src))
Packit 98cdb6
    {
Packit 98cdb6
      gdk_drawable_get_size (src, &src_width, &src_height);
Packit 98cdb6
      if (width < 0)
Packit 98cdb6
        width = src_width;
Packit 98cdb6
      if (height < 0)
Packit 98cdb6
        height = src_height;
Packit 98cdb6
      
Packit 98cdb6
      g_return_val_if_fail (src_x >= 0 && src_y >= 0, NULL);
Packit 98cdb6
      g_return_val_if_fail (src_x + width <= src_width && src_y + height <= src_height, NULL);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  /* Create the pixbuf if needed */
Packit 98cdb6
  if (!dest)
Packit 98cdb6
    {
Packit 98cdb6
      dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
Packit 98cdb6
      if (dest == NULL)
Packit 98cdb6
        return NULL;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  if (dest)
Packit 98cdb6
    {
Packit 98cdb6
      g_return_val_if_fail (dest_x >= 0 && dest_y >= 0, NULL);
Packit 98cdb6
      g_return_val_if_fail (dest_x + width <= gdk_pixbuf_get_width (dest), NULL);
Packit 98cdb6
      g_return_val_if_fail (dest_y + height <= gdk_pixbuf_get_height (dest), NULL);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
Packit 98cdb6
    {
Packit 98cdb6
      gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
Packit 98cdb6
      for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
Packit 98cdb6
	{
Packit 98cdb6
	  gint xs0, ys0;
Packit 98cdb6
	  
Packit 98cdb6
	  gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
Packit 98cdb6
	  
Packit 98cdb6
	  image = _gdk_image_get_scratch (gdk_drawable_get_screen (src), 
Packit 98cdb6
					  width1, height1, depth, &xs0, &ys0;;
Packit 98cdb6
Packit 98cdb6
	  gdk_drawable_copy_to_image (src, image,
Packit 98cdb6
				      src_x + x0, src_y + y0,
Packit 98cdb6
				       xs0, ys0, width1, height1);
Packit 98cdb6
Packit 98cdb6
	  gdk_pixbuf_get_from_image (dest, image, cmap,
Packit 98cdb6
				     xs0, ys0, dest_x + x0, dest_y + y0,
Packit 98cdb6
				     width1, height1);
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  return dest;
Packit 98cdb6
}
Packit 98cdb6
        
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pixbuf_get_from_image:
Packit 98cdb6
 * @dest: (allow-none): Destination pixbuf, or %NULL if a new pixbuf should be created.
Packit 98cdb6
 * @src: Source #GdkImage.
Packit 98cdb6
 * @cmap: (allow-none): A colormap, or %NULL to use the one for @src
Packit 98cdb6
 * @src_x: Source X coordinate within drawable.
Packit 98cdb6
 * @src_y: Source Y coordinate within drawable.
Packit 98cdb6
 * @dest_x: Destination X coordinate in pixbuf, or 0 if @dest is NULL.
Packit 98cdb6
 * @dest_y: Destination Y coordinate in pixbuf, or 0 if @dest is NULL.
Packit 98cdb6
 * @width: Width in pixels of region to get.
Packit 98cdb6
 * @height: Height in pixels of region to get.
Packit 98cdb6
 * 
Packit 98cdb6
 * Same as gdk_pixbuf_get_from_drawable() but gets the pixbuf from
Packit 98cdb6
 * an image.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: @dest, newly-created pixbuf if @dest was %NULL, %NULL on error
Packit 98cdb6
 **/
Packit 98cdb6
GdkPixbuf*
Packit 98cdb6
gdk_pixbuf_get_from_image (GdkPixbuf   *dest,
Packit 98cdb6
                           GdkImage    *src,
Packit 98cdb6
                           GdkColormap *cmap,
Packit 98cdb6
                           int          src_x,
Packit 98cdb6
                           int          src_y,
Packit 98cdb6
                           int          dest_x,
Packit 98cdb6
                           int          dest_y,
Packit 98cdb6
                           int          width,
Packit 98cdb6
                           int          height)
Packit 98cdb6
{
Packit 98cdb6
  int rowstride, bpp, alpha;
Packit 98cdb6
  
Packit 98cdb6
  /* General sanity checks */
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (GDK_IS_IMAGE (src), NULL);
Packit 98cdb6
Packit 98cdb6
  if (!dest)
Packit 98cdb6
    g_return_val_if_fail (dest_x == 0 && dest_y == 0, NULL);
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      g_return_val_if_fail (gdk_pixbuf_get_colorspace (dest) == GDK_COLORSPACE_RGB, NULL);
Packit 98cdb6
      g_return_val_if_fail (gdk_pixbuf_get_n_channels (dest) == 3 ||
Packit 98cdb6
                            gdk_pixbuf_get_n_channels (dest) == 4, NULL);
Packit 98cdb6
      g_return_val_if_fail (gdk_pixbuf_get_bits_per_sample (dest) == 8, NULL);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (cmap == NULL)
Packit 98cdb6
    cmap = gdk_image_get_colormap (src);
Packit 98cdb6
  
Packit 98cdb6
  if (src->depth != 1 && cmap == NULL)
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("%s: Source image has no colormap; either pass "
Packit 98cdb6
                 "in a colormap, or set the colormap on the image "
Packit 98cdb6
                 "with gdk_image_set_colormap()", G_STRLOC);
Packit 98cdb6
      return NULL;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  if (cmap != NULL && src->depth != cmap->visual->depth)
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("%s: Depth of the Source image is %d where as "
Packit 98cdb6
                 "the visual depth of the colormap passed is %d",
Packit 98cdb6
                 G_STRLOC, src->depth, cmap->visual->depth);
Packit 98cdb6
      return NULL;
Packit 98cdb6
    } 
Packit 98cdb6
 
Packit 98cdb6
  /* Coordinate sanity checks */
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (src_x >= 0 && src_y >= 0, NULL);
Packit 98cdb6
  g_return_val_if_fail (src_x + width <= src->width && src_y + height <= src->height, NULL);
Packit 98cdb6
Packit 98cdb6
  if (dest)
Packit 98cdb6
    {
Packit 98cdb6
      g_return_val_if_fail (dest_x >= 0 && dest_y >= 0, NULL);
Packit 98cdb6
      g_return_val_if_fail (dest_x + width <= gdk_pixbuf_get_width (dest), NULL);
Packit 98cdb6
      g_return_val_if_fail (dest_y + height <= gdk_pixbuf_get_height (dest), NULL);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  /* Create the pixbuf if needed */
Packit 98cdb6
  if (!dest)
Packit 98cdb6
    {
Packit 98cdb6
      dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
Packit 98cdb6
      if (dest == NULL)
Packit 98cdb6
        return NULL;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  alpha = gdk_pixbuf_get_has_alpha (dest);
Packit 98cdb6
  rowstride = gdk_pixbuf_get_rowstride (dest);
Packit 98cdb6
  bpp = alpha ? 4 : 3;
Packit 98cdb6
Packit 98cdb6
  /* we offset into the image data based on the position we are
Packit 98cdb6
   * retrieving from
Packit 98cdb6
   */
Packit 98cdb6
  rgbconvert (src, gdk_pixbuf_get_pixels (dest) +
Packit 98cdb6
	      (dest_y * rowstride) + (dest_x * bpp),
Packit 98cdb6
	      rowstride,
Packit 98cdb6
	      alpha,
Packit 98cdb6
              src_x, src_y,
Packit 98cdb6
              width,
Packit 98cdb6
              height,
Packit 98cdb6
	      cmap);
Packit 98cdb6
  
Packit 98cdb6
  return dest;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
#define __GDK_PIXBUF_DRAWABLE_C__
Packit 98cdb6
#include "gdkaliasdef.c"