/*
 * Raster file routines for CUPS.
 *
 * Copyright 2007-2019 by Apple Inc.
 * Copyright 1997-2006 by Easy Software Products.
 *
 * This file is part of the CUPS Imaging library.
 *
 * Licensed under Apache License v2.0.  See the file "LICENSE" for more
 * information.
 */

/*
 * Include necessary headers...
 */

#include "raster-private.h"
#include "debug-internal.h"
#ifdef HAVE_STDINT_H
#  include <stdint.h>
#endif /* HAVE_STDINT_H */


/*
 * Private structures...
 */

typedef void (*_cups_copyfunc_t)(void *dst, const void *src, size_t bytes);


/*
 * Local globals...
 */

static const char * const apple_media_types[] =
{					/* media-type values for Apple Raster */
  "auto",
  "stationery",
  "transparency",
  "envelope",
  "cardstock",
  "labels",
  "stationery-letterhead",
  "disc",
  "photographic-matte",
  "photographic-satin",
  "photographic-semi-gloss",
  "photographic-glossy",
  "photographic-high-gloss",
  "other"
};

#ifdef DEBUG
static const char * const cups_modes[] =
{					/* Open modes */
  "CUPS_RASTER_READ",
  "CUPS_RASTER_WRITE",
  "CUPS_RASTER_WRITE_COMPRESSED",
  "CUPS_RASTER_WRITE_PWG",
  "CUPS_RASTER_WRITE_APPLE"
};
#endif /* DEBUG */


/*
 * Local functions...
 */

static ssize_t	cups_raster_io(cups_raster_t *r, unsigned char *buf, size_t bytes);
static ssize_t	cups_raster_read(cups_raster_t *r, unsigned char *buf, size_t bytes);
static int	cups_raster_update(cups_raster_t *r);
static ssize_t	cups_raster_write(cups_raster_t *r, const unsigned char *pixels);
static void	cups_swap(unsigned char *buf, size_t bytes);
static void	cups_swap_copy(unsigned char *dst, const unsigned char *src, size_t bytes);


/*
 * '_cupsRasterColorSpaceString()' - Return the colorspace name for a
 *                                   cupsColorSpace value.
 */

const char *
_cupsRasterColorSpaceString(
    cups_cspace_t cspace)		/* I - cupsColorSpace value */
{
  static const char * const cups_color_spaces[] =
  {					/* Color spaces */
    "W",
    "RGB",
    "RGBA",
    "K",
    "CMY",
    "YMC",
    "CMYK",
    "YMCK",
    "KCMY",
    "KCMYcm",
    "GMCK",
    "GMCS",
    "WHITE",
    "GOLD",
    "SILVER",
    "CIEXYZ",
    "CIELab",
    "RGBW",
    "SW",
    "SRGB",
    "ADOBERGB",
    "21",
    "22",
    "23",
    "24",
    "25",
    "26",
    "27",
    "28",
    "29",
    "30",
    "31",
    "ICC1",
    "ICC2",
    "ICC3",
    "ICC4",
    "ICC5",
    "ICC6",
    "ICC7",
    "ICC8",
    "ICC9",
    "ICCA",
    "ICCB",
    "ICCC",
    "ICCD",
    "ICCE",
    "ICCF",
    "47",
    "DEVICE1",
    "DEVICE2",
    "DEVICE3",
    "DEVICE4",
    "DEVICE5",
    "DEVICE6",
    "DEVICE7",
    "DEVICE8",
    "DEVICE9",
    "DEVICEA",
    "DEVICEB",
    "DEVICEC",
    "DEVICED",
    "DEVICEE",
    "DEVICEF"
  };

  if (cspace < CUPS_CSPACE_W || cspace > CUPS_CSPACE_DEVICEF)
    return ("Unknown");
  else
    return (cups_color_spaces[cspace]);
}


/*
 * '_cupsRasterDelete()' - Free a raster stream.
 *
 * The file descriptor associated with the raster stream must be closed
 * separately as needed.
 */

void
_cupsRasterDelete(cups_raster_t *r)	/* I - Stream to free */
{
  if (r != NULL)
  {
    if (r->buffer)
      free(r->buffer);

    if (r->pixels)
      free(r->pixels);

    free(r);
  }
}


/*
 * '_cupsRasterInitPWGHeader()' - Initialize a page header for PWG Raster output.
 *
 * The "media" argument specifies the media to use.
 *
 * The "type" argument specifies a "pwg-raster-document-type-supported" value
 * that controls the color space and bit depth of the raster data.
 *
 * The "xres" and "yres" arguments specify the raster resolution in dots per
 * inch.
 *
 * The "sheet_back" argument specifies a "pwg-raster-document-sheet-back" value
 * to apply for the back side of a page.  Pass @code NULL@ for the front side.
 *
 * @since CUPS 2.2/macOS 10.12@
 */

int					/* O - 1 on success, 0 on failure */
_cupsRasterInitPWGHeader(
    cups_page_header2_t *h,		/* I - Page header */
    pwg_media_t         *media,		/* I - PWG media information */
    const char          *type,		/* I - PWG raster type string */
    int                 xdpi,		/* I - Cross-feed direction (horizontal) resolution */
    int                 ydpi,		/* I - Feed direction (vertical) resolution */
    const char          *sides,		/* I - IPP "sides" option value */
    const char          *sheet_back)	/* I - Transform for back side or @code NULL@ for none */
{
  if (!h || !media || !type || xdpi <= 0 || ydpi <= 0)
  {
    _cupsRasterAddError("%s", strerror(EINVAL));
    return (0);
  }

 /*
  * Initialize the page header...
  */

  memset(h, 0, sizeof(cups_page_header2_t));

  strlcpy(h->cupsPageSizeName, media->pwg, sizeof(h->cupsPageSizeName));

  h->PageSize[0] = (unsigned)(72 * media->width / 2540);
  h->PageSize[1] = (unsigned)(72 * media->length / 2540);

  /* This never gets written but is needed for some applications */
  h->cupsPageSize[0] = 72.0f * media->width / 2540.0f;
  h->cupsPageSize[1] = 72.0f * media->length / 2540.0f;

  h->ImagingBoundingBox[2] = h->PageSize[0];
  h->ImagingBoundingBox[3] = h->PageSize[1];

  h->HWResolution[0] = (unsigned)xdpi;
  h->HWResolution[1] = (unsigned)ydpi;

  h->cupsWidth  = (unsigned)(media->width * xdpi / 2540);
  h->cupsHeight = (unsigned)(media->length * ydpi / 2540);

  if (h->cupsWidth > 0x00ffffff || h->cupsHeight > 0x00ffffff)
  {
    _cupsRasterAddError("Raster dimensions too large.");
    return (0);
  }

  h->cupsInteger[CUPS_RASTER_PWG_ImageBoxRight]  = h->cupsWidth;
  h->cupsInteger[CUPS_RASTER_PWG_ImageBoxBottom] = h->cupsHeight;

 /*
  * Colorspace and bytes per line...
  */

  if (!strcmp(type, "adobe-rgb_8"))
  {
    h->cupsBitsPerColor = 8;
    h->cupsBitsPerPixel = 24;
    h->cupsColorSpace   = CUPS_CSPACE_ADOBERGB;
  }
  else if (!strcmp(type, "adobe-rgb_16"))
  {
    h->cupsBitsPerColor = 16;
    h->cupsBitsPerPixel = 48;
    h->cupsColorSpace   = CUPS_CSPACE_ADOBERGB;
  }
  else if (!strcmp(type, "black_1"))
  {
    h->cupsBitsPerColor = 1;
    h->cupsBitsPerPixel = 1;
    h->cupsColorSpace   = CUPS_CSPACE_K;
  }
  else if (!strcmp(type, "black_8"))
  {
    h->cupsBitsPerColor = 8;
    h->cupsBitsPerPixel = 8;
    h->cupsColorSpace   = CUPS_CSPACE_K;
  }
  else if (!strcmp(type, "black_16"))
  {
    h->cupsBitsPerColor = 16;
    h->cupsBitsPerPixel = 16;
    h->cupsColorSpace   = CUPS_CSPACE_K;
  }
  else if (!strcmp(type, "cmyk_8"))
  {
    h->cupsBitsPerColor = 8;
    h->cupsBitsPerPixel = 32;
    h->cupsColorSpace   = CUPS_CSPACE_CMYK;
  }
  else if (!strcmp(type, "cmyk_16"))
  {
    h->cupsBitsPerColor = 16;
    h->cupsBitsPerPixel = 64;
    h->cupsColorSpace   = CUPS_CSPACE_CMYK;
  }
  else if (!strncmp(type, "device", 6) && type[6] >= '1' && type[6] <= '9')
  {
    int ncolors, bits;			/* Number of colors and bits */


    if (sscanf(type, "device%d_%d", &ncolors, &bits) != 2 || ncolors > 15 || (bits != 8 && bits != 16))
    {
      _cupsRasterAddError("Unsupported raster type \'%s\'.", type);
      return (0);
    }

    h->cupsBitsPerColor = (unsigned)bits;
    h->cupsBitsPerPixel = (unsigned)(ncolors * bits);
    h->cupsColorSpace   = (cups_cspace_t)(CUPS_CSPACE_DEVICE1 + ncolors - 1);
  }
  else if (!strcmp(type, "rgb_8"))
  {
    h->cupsBitsPerColor = 8;
    h->cupsBitsPerPixel = 24;
    h->cupsColorSpace   = CUPS_CSPACE_RGB;
  }
  else if (!strcmp(type, "rgb_16"))
  {
    h->cupsBitsPerColor = 16;
    h->cupsBitsPerPixel = 48;
    h->cupsColorSpace   = CUPS_CSPACE_RGB;
  }
  else if (!strcmp(type, "sgray_1"))
  {
    h->cupsBitsPerColor = 1;
    h->cupsBitsPerPixel = 1;
    h->cupsColorSpace   = CUPS_CSPACE_SW;
  }
  else if (!strcmp(type, "sgray_8"))
  {
    h->cupsBitsPerColor = 8;
    h->cupsBitsPerPixel = 8;
    h->cupsColorSpace   = CUPS_CSPACE_SW;
  }
  else if (!strcmp(type, "sgray_16"))
  {
    h->cupsBitsPerColor = 16;
    h->cupsBitsPerPixel = 16;
    h->cupsColorSpace   = CUPS_CSPACE_SW;
  }
  else if (!strcmp(type, "srgb_8"))
  {
    h->cupsBitsPerColor = 8;
    h->cupsBitsPerPixel = 24;
    h->cupsColorSpace   = CUPS_CSPACE_SRGB;
  }
  else if (!strcmp(type, "srgb_16"))
  {
    h->cupsBitsPerColor = 16;
    h->cupsBitsPerPixel = 48;
    h->cupsColorSpace   = CUPS_CSPACE_SRGB;
  }
  else
  {
    _cupsRasterAddError("Unsupported raster type \'%s\'.", type);
    return (0);
  }

  h->cupsColorOrder   = CUPS_ORDER_CHUNKED;
  h->cupsNumColors    = h->cupsBitsPerPixel / h->cupsBitsPerColor;
  h->cupsBytesPerLine = (h->cupsWidth * h->cupsBitsPerPixel + 7) / 8;

 /*
  * Duplex support...
  */

  h->cupsInteger[CUPS_RASTER_PWG_CrossFeedTransform] = 1;
  h->cupsInteger[CUPS_RASTER_PWG_FeedTransform]      = 1;

  if (sides)
  {
    if (!strcmp(sides, "two-sided-long-edge"))
    {
      h->Duplex = 1;
    }
    else if (!strcmp(sides, "two-sided-short-edge"))
    {
      h->Duplex = 1;
      h->Tumble = 1;
    }
    else if (strcmp(sides, "one-sided"))
    {
      _cupsRasterAddError("Unsupported sides value \'%s\'.", sides);
      return (0);
    }

    if (sheet_back)
    {
      if (!strcmp(sheet_back, "flipped"))
      {
        if (h->Tumble)
          h->cupsInteger[CUPS_RASTER_PWG_CrossFeedTransform] = 0xffffffffU;
        else
          h->cupsInteger[CUPS_RASTER_PWG_FeedTransform] = 0xffffffffU;
      }
      else if (!strcmp(sheet_back, "manual-tumble"))
      {
        if (h->Tumble)
        {
          h->cupsInteger[CUPS_RASTER_PWG_CrossFeedTransform] = 0xffffffffU;
          h->cupsInteger[CUPS_RASTER_PWG_FeedTransform]      = 0xffffffffU;
        }
      }
      else if (!strcmp(sheet_back, "rotated"))
      {
        if (!h->Tumble)
        {
          h->cupsInteger[CUPS_RASTER_PWG_CrossFeedTransform] = 0xffffffffU;
          h->cupsInteger[CUPS_RASTER_PWG_FeedTransform]      = 0xffffffffU;
        }
      }
      else if (strcmp(sheet_back, "normal"))
      {
	_cupsRasterAddError("Unsupported sheet_back value \'%s\'.", sheet_back);
	return (0);
      }
    }
  }

  return (1);
}


/*
 * '_cupsRasterNew()' - Create a raster stream using a callback function.
 *
 * This function associates a raster stream with the given callback function and
 * context pointer.
 *
 * When writing raster data, the @code CUPS_RASTER_WRITE@,
 * @code CUPS_RASTER_WRITE_COMPRESS@, or @code CUPS_RASTER_WRITE_PWG@ mode can
 * be used - compressed and PWG output is generally 25-50% smaller but adds a
 * 100-300% execution time overhead.
 */

cups_raster_t *				/* O - New stream */
_cupsRasterNew(
    cups_raster_iocb_t iocb,		/* I - Read/write callback */
    void               *ctx,		/* I - Context pointer for callback */
    cups_mode_t        mode)		/* I - Mode - @code CUPS_RASTER_READ@,
	                                       @code CUPS_RASTER_WRITE@,
					       @code CUPS_RASTER_WRITE_COMPRESSED@,
					       or @code CUPS_RASTER_WRITE_PWG@ */
{
  cups_raster_t	*r;			/* New stream */


  DEBUG_printf(("_cupsRasterOpenIO(iocb=%p, ctx=%p, mode=%s)", (void *)iocb, ctx, cups_modes[mode]));

  _cupsRasterClearError();

  if ((r = calloc(sizeof(cups_raster_t), 1)) == NULL)
  {
    _cupsRasterAddError("Unable to allocate memory for raster stream: %s\n",
                        strerror(errno));
    DEBUG_puts("1_cupsRasterOpenIO: Returning NULL.");
    return (NULL);
  }

  r->ctx  = ctx;
  r->iocb = iocb;
  r->mode = mode;

  if (mode == CUPS_RASTER_READ)
  {
   /*
    * Open for read - get sync word...
    */

    if (cups_raster_io(r, (unsigned char *)&(r->sync), sizeof(r->sync)) !=
            sizeof(r->sync))
    {
      _cupsRasterAddError("Unable to read header from raster stream: %s\n",
                          strerror(errno));
      free(r);
      DEBUG_puts("1_cupsRasterOpenIO: Unable to read header, returning NULL.");
      return (NULL);
    }

    if (r->sync != CUPS_RASTER_SYNC &&
        r->sync != CUPS_RASTER_REVSYNC &&
        r->sync != CUPS_RASTER_SYNCv1 &&
        r->sync != CUPS_RASTER_REVSYNCv1 &&
        r->sync != CUPS_RASTER_SYNCv2 &&
        r->sync != CUPS_RASTER_REVSYNCv2 &&
        r->sync != CUPS_RASTER_SYNCapple &&
        r->sync != CUPS_RASTER_REVSYNCapple)
    {
      _cupsRasterAddError("Unknown raster format %08x!\n", r->sync);
      free(r);
      DEBUG_puts("1_cupsRasterOpenIO: Unknown format, returning NULL.");
      return (NULL);
    }

    if (r->sync == CUPS_RASTER_SYNCv2 ||
        r->sync == CUPS_RASTER_REVSYNCv2 ||
        r->sync == CUPS_RASTER_SYNCapple ||
        r->sync == CUPS_RASTER_REVSYNCapple)
      r->compressed = 1;

    DEBUG_printf(("1_cupsRasterOpenIO: sync=%08x", r->sync));

    if (r->sync == CUPS_RASTER_REVSYNC ||
        r->sync == CUPS_RASTER_REVSYNCv1 ||
        r->sync == CUPS_RASTER_REVSYNCv2 ||
        r->sync == CUPS_RASTER_REVSYNCapple)
      r->swapped = 1;

    if (r->sync == CUPS_RASTER_SYNCapple ||
        r->sync == CUPS_RASTER_REVSYNCapple)
    {
      unsigned char	header[8];	/* File header */

      if (cups_raster_io(r, (unsigned char *)header, sizeof(header)) !=
	      sizeof(header))
      {
	_cupsRasterAddError("Unable to read header from raster stream: %s\n",
			    strerror(errno));
	free(r);
	DEBUG_puts("1_cupsRasterOpenIO: Unable to read header, returning NULL.");
	return (NULL);
      }
    }

#ifdef DEBUG
    r->iostart = r->iocount;
#endif /* DEBUG */
  }
  else
  {
   /*
    * Open for write - put sync word...
    */

    switch (mode)
    {
      default :
      case CUPS_RASTER_WRITE :
          r->sync = CUPS_RASTER_SYNC;
	  break;

      case CUPS_RASTER_WRITE_COMPRESSED :
          r->compressed = 1;
          r->sync       = CUPS_RASTER_SYNCv2;
	  break;

      case CUPS_RASTER_WRITE_PWG :
          r->compressed = 1;
          r->sync       = htonl(CUPS_RASTER_SYNC_PWG);
          r->swapped    = r->sync != CUPS_RASTER_SYNC_PWG;
	  break;

      case CUPS_RASTER_WRITE_APPLE :
          r->compressed     = 1;
          r->sync           = htonl(CUPS_RASTER_SYNCapple);
          r->swapped        = r->sync != CUPS_RASTER_SYNCapple;
          r->apple_page_count = 0xffffffffU;
	  break;
    }

    if (cups_raster_io(r, (unsigned char *)&(r->sync), sizeof(r->sync)) < (ssize_t)sizeof(r->sync))
    {
      _cupsRasterAddError("Unable to write raster stream header: %s\n",
                          strerror(errno));
      free(r);
      DEBUG_puts("1_cupsRasterOpenIO: Unable to write header, returning NULL.");
      return (NULL);
    }
  }

  DEBUG_printf(("1_cupsRasterOpenIO: compressed=%d, swapped=%d, returning %p", r->compressed, r->swapped, (void *)r));

  return (r);
}


/*
 * '_cupsRasterReadHeader()' - Read a raster page header.
 */

unsigned				/* O - 1 on success, 0 on fail */
_cupsRasterReadHeader(
    cups_raster_t *r)			/* I - Raster stream */
{
  size_t	len;			/* Length for read/swap */


  DEBUG_printf(("3_cupsRasterReadHeader(r=%p), r->mode=%s", (void *)r, r ? cups_modes[r->mode] : ""));

  if (r == NULL || r->mode != CUPS_RASTER_READ)
    return (0);

  DEBUG_printf(("4_cupsRasterReadHeader: r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount));

  memset(&(r->header), 0, sizeof(r->header));

 /*
  * Read the header...
  */

  switch (r->sync)
  {
    default :
       /*
	* Get the length of the raster header...
	*/

	if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1)
	  len = sizeof(cups_page_header_t);
	else
	  len = sizeof(cups_page_header2_t);

	DEBUG_printf(("4_cupsRasterReadHeader: len=%d", (int)len));

       /*
        * Read it...
        */

	if (cups_raster_read(r, (unsigned char *)&(r->header), len) < (ssize_t)len)
	{
	  DEBUG_printf(("4_cupsRasterReadHeader: EOF, r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount));
	  return (0);
	}

       /*
	* Swap bytes as needed...
	*/

	if (r->swapped)
	{
	  unsigned	*s,		/* Current word */
			temp;		/* Temporary copy */


	  DEBUG_puts("4_cupsRasterReadHeader: Swapping header bytes.");

	  for (len = 81, s = &(r->header.AdvanceDistance);
	       len > 0;
	       len --, s ++)
	  {
	    temp = *s;
	    *s   = ((temp & 0xff) << 24) |
		   ((temp & 0xff00) << 8) |
		   ((temp & 0xff0000) >> 8) |
		   ((temp & 0xff000000) >> 24);

	    DEBUG_printf(("4_cupsRasterReadHeader: %08x => %08x", temp, *s));
	  }
	}
        break;

    case CUPS_RASTER_SYNCapple :
    case CUPS_RASTER_REVSYNCapple :
        {
          unsigned char	appleheader[32];	/* Raw header */
          static const unsigned rawcspace[] =
          {
            CUPS_CSPACE_SW,
            CUPS_CSPACE_SRGB,
            CUPS_CSPACE_CIELab,
            CUPS_CSPACE_ADOBERGB,
            CUPS_CSPACE_W,
            CUPS_CSPACE_RGB,
            CUPS_CSPACE_CMYK
          };
          static const unsigned rawnumcolors[] =
          {
            1,
            3,
            3,
            3,
            1,
            3,
            4
          };

	  if (cups_raster_read(r, appleheader, sizeof(appleheader)) < (ssize_t)sizeof(appleheader))
	  {
	    DEBUG_printf(("4_cupsRasterReadHeader: EOF, r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount));
	    return (0);
	  }

	  strlcpy(r->header.MediaClass, "PwgRaster", sizeof(r->header.MediaClass));
					      /* PwgRaster */
          r->header.cupsBitsPerPixel = appleheader[0];
          r->header.cupsColorSpace   = appleheader[1] >= (sizeof(rawcspace) / sizeof(rawcspace[0])) ? CUPS_CSPACE_DEVICE1 : rawcspace[appleheader[1]];
          r->header.cupsNumColors    = appleheader[1] >= (sizeof(rawnumcolors) / sizeof(rawnumcolors[0])) ? 1 : rawnumcolors[appleheader[1]];
          r->header.cupsBitsPerColor = r->header.cupsBitsPerPixel / r->header.cupsNumColors;
          r->header.cupsWidth        = ((((((unsigned)appleheader[12] << 8) | (unsigned)appleheader[13]) << 8) | (unsigned)appleheader[14]) << 8) | (unsigned)appleheader[15];
          r->header.cupsHeight       = ((((((unsigned)appleheader[16] << 8) | (unsigned)appleheader[17]) << 8) | (unsigned)appleheader[18]) << 8) | (unsigned)appleheader[19];
          r->header.cupsBytesPerLine = r->header.cupsWidth * r->header.cupsBitsPerPixel / 8;
          r->header.cupsColorOrder   = CUPS_ORDER_CHUNKED;
          r->header.HWResolution[0]  = r->header.HWResolution[1] = ((((((unsigned)appleheader[20] << 8) | (unsigned)appleheader[21]) << 8) | (unsigned)appleheader[22]) << 8) | (unsigned)appleheader[23];

          if (r->header.HWResolution[0] > 0)
          {
	    r->header.PageSize[0]     = (unsigned)(r->header.cupsWidth * 72 / r->header.HWResolution[0]);
	    r->header.PageSize[1]     = (unsigned)(r->header.cupsHeight * 72 / r->header.HWResolution[1]);
	    r->header.cupsPageSize[0] = (float)(r->header.cupsWidth * 72.0 / r->header.HWResolution[0]);
	    r->header.cupsPageSize[1] = (float)(r->header.cupsHeight * 72.0 / r->header.HWResolution[1]);
          }

          r->header.cupsInteger[CUPS_RASTER_PWG_TotalPageCount]   = r->apple_page_count;
          r->header.cupsInteger[CUPS_RASTER_PWG_AlternatePrimary] = 0xffffff;
          r->header.cupsInteger[CUPS_RASTER_PWG_PrintQuality]     = appleheader[3];

          if (appleheader[2] >= 2)
            r->header.Duplex = 1;
          if (appleheader[2] == 2)
            r->header.Tumble = 1;

          r->header.MediaPosition = appleheader[5];

          if (appleheader[4] < (int)(sizeof(apple_media_types) / sizeof(apple_media_types[0])))
            strlcpy(r->header.MediaType, apple_media_types[appleheader[4]], sizeof(r->header.MediaType));
          else
            strlcpy(r->header.MediaType, "other", sizeof(r->header.MediaType));
        }
        break;
  }

 /*
  * Update the header and row count...
  */

  if (!cups_raster_update(r))
    return (0);

  DEBUG_printf(("4_cupsRasterReadHeader: cupsColorSpace=%s", _cupsRasterColorSpaceString(r->header.cupsColorSpace)));
  DEBUG_printf(("4_cupsRasterReadHeader: cupsBitsPerColor=%u", r->header.cupsBitsPerColor));
  DEBUG_printf(("4_cupsRasterReadHeader: cupsBitsPerPixel=%u", r->header.cupsBitsPerPixel));
  DEBUG_printf(("4_cupsRasterReadHeader: cupsBytesPerLine=%u", r->header.cupsBytesPerLine));
  DEBUG_printf(("4_cupsRasterReadHeader: cupsWidth=%u", r->header.cupsWidth));
  DEBUG_printf(("4_cupsRasterReadHeader: cupsHeight=%u", r->header.cupsHeight));
  DEBUG_printf(("4_cupsRasterReadHeader: r->bpp=%d", r->bpp));

  return (r->header.cupsBitsPerPixel > 0 && r->header.cupsBitsPerPixel <= 240 && r->header.cupsBitsPerColor > 0 && r->header.cupsBitsPerColor <= 16 && r->header.cupsBytesPerLine > 0 && r->header.cupsBytesPerLine <= 0x7fffffff && r->header.cupsHeight != 0 && (r->header.cupsBytesPerLine % r->bpp) == 0);
}


/*
 * '_cupsRasterReadPixels()' - Read raster pixels.
 *
 * For best performance, filters should read one or more whole lines.
 * The "cupsBytesPerLine" value from the page header can be used to allocate
 * the line buffer and as the number of bytes to read.
 */

unsigned				/* O - Number of bytes read */
_cupsRasterReadPixels(
    cups_raster_t *r,			/* I - Raster stream */
    unsigned char *p,			/* I - Pointer to pixel buffer */
    unsigned      len)			/* I - Number of bytes to read */
{
  ssize_t	bytes;			/* Bytes read */
  unsigned	cupsBytesPerLine;	/* cupsBytesPerLine value */
  unsigned	remaining;		/* Bytes remaining */
  unsigned char	*ptr,			/* Pointer to read buffer */
		byte,			/* Byte from file */
		*temp;			/* Pointer into buffer */
  unsigned	count;			/* Repetition count */


  DEBUG_printf(("_cupsRasterReadPixels(r=%p, p=%p, len=%u)", (void *)r, (void *)p, len));

  if (r == NULL || r->mode != CUPS_RASTER_READ || r->remaining == 0 ||
      r->header.cupsBytesPerLine == 0)
  {
    DEBUG_puts("1_cupsRasterReadPixels: Returning 0.");
    return (0);
  }

  DEBUG_printf(("1_cupsRasterReadPixels: compressed=%d, remaining=%u", r->compressed, r->remaining));

  if (!r->compressed)
  {
   /*
    * Read without compression...
    */

    r->remaining -= len / r->header.cupsBytesPerLine;

    if (cups_raster_io(r, p, len) < (ssize_t)len)
    {
      DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0.");
      return (0);
    }

   /*
    * Swap bytes as needed...
    */

    if (r->swapped &&
        (r->header.cupsBitsPerColor == 16 ||
         r->header.cupsBitsPerPixel == 12 ||
         r->header.cupsBitsPerPixel == 16))
      cups_swap(p, len);

   /*
    * Return...
    */

    DEBUG_printf(("1_cupsRasterReadPixels: Returning %u", len));

    return (len);
  }

 /*
  * Read compressed data...
  */

  remaining        = len;
  cupsBytesPerLine = r->header.cupsBytesPerLine;

  while (remaining > 0 && r->remaining > 0)
  {
    if (r->count == 0)
    {
     /*
      * Need to read a new row...
      */

      if (remaining == cupsBytesPerLine)
	ptr = p;
      else
	ptr = r->pixels;

     /*
      * Read using a modified PackBits compression...
      */

      if (!cups_raster_read(r, &byte, 1))
      {
	DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0.");
	return (0);
      }

      r->count = (unsigned)byte + 1;

      if (r->count > 1)
	ptr = r->pixels;

      temp  = ptr;
      bytes = (ssize_t)cupsBytesPerLine;

      while (bytes > 0)
      {
       /*
	* Get a new repeat count...
	*/

        if (!cups_raster_read(r, &byte, 1))
	{
	  DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0.");
	  return (0);
	}

        if (byte == 128)
        {
         /*
          * Clear to end of line...
          */

          switch (r->header.cupsColorSpace)
          {
            case CUPS_CSPACE_W :
            case CUPS_CSPACE_RGB :
            case CUPS_CSPACE_SW :
            case CUPS_CSPACE_SRGB :
            case CUPS_CSPACE_RGBW :
            case CUPS_CSPACE_ADOBERGB :
                memset(temp, 0xff, (size_t)bytes);
                break;
            default :
                memset(temp, 0x00, (size_t)bytes);
                break;
          }

          temp += bytes;
          bytes = 0;
        }
	else if (byte & 128)
	{
	 /*
	  * Copy N literal pixels...
	  */

	  count = (unsigned)(257 - byte) * r->bpp;

          if (count > (unsigned)bytes)
	    count = (unsigned)bytes;

          if (!cups_raster_read(r, temp, count))
	  {
	    DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0.");
	    return (0);
	  }

	  temp  += count;
	  bytes -= (ssize_t)count;
	}
	else
	{
	 /*
	  * Repeat the next N bytes...
	  */

          count = ((unsigned)byte + 1) * r->bpp;
          if (count > (unsigned)bytes)
	    count = (unsigned)bytes;

          if (count < r->bpp)
	    break;

	  bytes -= (ssize_t)count;

          if (!cups_raster_read(r, temp, r->bpp))
	  {
	    DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0.");
	    return (0);
	  }

	  temp  += r->bpp;
	  count -= r->bpp;

	  while (count > 0)
	  {
	    memcpy(temp, temp - r->bpp, r->bpp);
	    temp  += r->bpp;
	    count -= r->bpp;
          }
	}
      }

     /*
      * Swap bytes as needed...
      */

      if ((r->header.cupsBitsPerColor == 16 ||
           r->header.cupsBitsPerPixel == 12 ||
           r->header.cupsBitsPerPixel == 16) &&
          r->swapped)
      {
        DEBUG_puts("1_cupsRasterReadPixels: Swapping bytes.");
        cups_swap(ptr, (size_t)cupsBytesPerLine);
      }

     /*
      * Update pointers...
      */

      if (remaining >= cupsBytesPerLine)
      {
	bytes       = (ssize_t)cupsBytesPerLine;
        r->pcurrent = r->pixels;
	r->count --;
	r->remaining --;
      }
      else
      {
	bytes       = (ssize_t)remaining;
        r->pcurrent = r->pixels + bytes;
      }

     /*
      * Copy data as needed...
      */

      if (ptr != p)
        memcpy(p, ptr, (size_t)bytes);
    }
    else
    {
     /*
      * Copy fragment from buffer...
      */

      if ((unsigned)(bytes = (int)(r->pend - r->pcurrent)) > remaining)
        bytes = (ssize_t)remaining;

      memcpy(p, r->pcurrent, (size_t)bytes);
      r->pcurrent += bytes;

      if (r->pcurrent >= r->pend)
      {
        r->pcurrent = r->pixels;
	r->count --;
	r->remaining --;
      }
    }

    remaining -= (unsigned)bytes;
    p         += bytes;
  }

  DEBUG_printf(("1_cupsRasterReadPixels: Returning %u", len));

  return (len);
}


/*
 * '_cupsRasterWriteHeader()' - Write a raster page header.
 */

unsigned				/* O - 1 on success, 0 on failure */
_cupsRasterWriteHeader(
    cups_raster_t *r)			/* I - Raster stream */
{
  DEBUG_printf(("_cupsRasterWriteHeader(r=%p)", (void *)r));

  DEBUG_printf(("1_cupsRasterWriteHeader: cupsColorSpace=%s", _cupsRasterColorSpaceString(r->header.cupsColorSpace)));
  DEBUG_printf(("1_cupsRasterWriteHeader: cupsBitsPerColor=%u", r->header.cupsBitsPerColor));
  DEBUG_printf(("1_cupsRasterWriteHeader: cupsBitsPerPixel=%u", r->header.cupsBitsPerPixel));
  DEBUG_printf(("1_cupsRasterWriteHeader: cupsBytesPerLine=%u", r->header.cupsBytesPerLine));
  DEBUG_printf(("1_cupsRasterWriteHeader: cupsWidth=%u", r->header.cupsWidth));
  DEBUG_printf(("1_cupsRasterWriteHeader: cupsHeight=%u", r->header.cupsHeight));

 /*
  * Compute the number of raster lines in the page image...
  */

  if (!cups_raster_update(r))
  {
    DEBUG_puts("1_cupsRasterWriteHeader: Unable to update parameters, returning 0.");
    return (0);
  }

  if (r->mode == CUPS_RASTER_WRITE_APPLE)
  {
    r->rowheight = r->header.HWResolution[0] / r->header.HWResolution[1];

    if (r->header.HWResolution[0] != (r->rowheight * r->header.HWResolution[1]))
      return (0);
  }
  else
    r->rowheight = 1;

 /*
  * Write the raster header...
  */

  if (r->mode == CUPS_RASTER_WRITE_PWG)
  {
   /*
    * PWG raster data is always network byte order with much of the page header
    * zeroed.
    */

    cups_page_header2_t	fh;		/* File page header */

    memset(&fh, 0, sizeof(fh));
    strlcpy(fh.MediaClass, "PwgRaster", sizeof(fh.MediaClass));
    strlcpy(fh.MediaColor, r->header.MediaColor, sizeof(fh.MediaColor));
    strlcpy(fh.MediaType, r->header.MediaType, sizeof(fh.MediaType));
    strlcpy(fh.OutputType, r->header.OutputType, sizeof(fh.OutputType));
    strlcpy(fh.cupsRenderingIntent, r->header.cupsRenderingIntent,
            sizeof(fh.cupsRenderingIntent));
    strlcpy(fh.cupsPageSizeName, r->header.cupsPageSizeName,
            sizeof(fh.cupsPageSizeName));

    fh.CutMedia              = htonl(r->header.CutMedia);
    fh.Duplex                = htonl(r->header.Duplex);
    fh.HWResolution[0]       = htonl(r->header.HWResolution[0]);
    fh.HWResolution[1]       = htonl(r->header.HWResolution[1]);
    fh.ImagingBoundingBox[0] = htonl(r->header.ImagingBoundingBox[0]);
    fh.ImagingBoundingBox[1] = htonl(r->header.ImagingBoundingBox[1]);
    fh.ImagingBoundingBox[2] = htonl(r->header.ImagingBoundingBox[2]);
    fh.ImagingBoundingBox[3] = htonl(r->header.ImagingBoundingBox[3]);
    fh.InsertSheet           = htonl(r->header.InsertSheet);
    fh.Jog                   = htonl(r->header.Jog);
    fh.LeadingEdge           = htonl(r->header.LeadingEdge);
    fh.ManualFeed            = htonl(r->header.ManualFeed);
    fh.MediaPosition         = htonl(r->header.MediaPosition);
    fh.MediaWeight           = htonl(r->header.MediaWeight);
    fh.NumCopies             = htonl(r->header.NumCopies);
    fh.Orientation           = htonl(r->header.Orientation);
    fh.PageSize[0]           = htonl(r->header.PageSize[0]);
    fh.PageSize[1]           = htonl(r->header.PageSize[1]);
    fh.Tumble                = htonl(r->header.Tumble);
    fh.cupsWidth             = htonl(r->header.cupsWidth);
    fh.cupsHeight            = htonl(r->header.cupsHeight);
    fh.cupsBitsPerColor      = htonl(r->header.cupsBitsPerColor);
    fh.cupsBitsPerPixel      = htonl(r->header.cupsBitsPerPixel);
    fh.cupsBytesPerLine      = htonl(r->header.cupsBytesPerLine);
    fh.cupsColorOrder        = htonl(r->header.cupsColorOrder);
    fh.cupsColorSpace        = htonl(r->header.cupsColorSpace);
    fh.cupsNumColors         = htonl(r->header.cupsNumColors);
    fh.cupsInteger[0]        = htonl(r->header.cupsInteger[0]);
    fh.cupsInteger[1]        = htonl(r->header.cupsInteger[1]);
    fh.cupsInteger[2]        = htonl(r->header.cupsInteger[2]);
    fh.cupsInteger[3]        = htonl((unsigned)(r->header.cupsImagingBBox[0] * r->header.HWResolution[0] / 72.0));
    fh.cupsInteger[4]        = htonl((unsigned)(r->header.cupsImagingBBox[1] * r->header.HWResolution[1] / 72.0));
    fh.cupsInteger[5]        = htonl((unsigned)(r->header.cupsImagingBBox[2] * r->header.HWResolution[0] / 72.0));
    fh.cupsInteger[6]        = htonl((unsigned)(r->header.cupsImagingBBox[3] * r->header.HWResolution[1] / 72.0));
    fh.cupsInteger[7]        = htonl(0xffffff);

    return (cups_raster_io(r, (unsigned char *)&fh, sizeof(fh)) == sizeof(fh));
  }
  else if (r->mode == CUPS_RASTER_WRITE_APPLE)
  {
   /*
    * Raw raster data is always network byte order with most of the page header
    * zeroed.
    */

    int			i;		/* Looping var */
    unsigned char	appleheader[32];/* Raw page header */
    unsigned		height = r->header.cupsHeight * r->rowheight;
					/* Computed page height */

    if (r->apple_page_count == 0xffffffffU)
    {
     /*
      * Write raw page count from raster page header...
      */

      r->apple_page_count = r->header.cupsInteger[0];

      appleheader[0] = 'A';
      appleheader[1] = 'S';
      appleheader[2] = 'T';
      appleheader[3] = 0;
      appleheader[4] = (unsigned char)(r->apple_page_count >> 24);
      appleheader[5] = (unsigned char)(r->apple_page_count >> 16);
      appleheader[6] = (unsigned char)(r->apple_page_count >> 8);
      appleheader[7] = (unsigned char)(r->apple_page_count);

      if (cups_raster_io(r, appleheader, 8) != 8)
        return (0);
    }

    memset(appleheader, 0, sizeof(appleheader));

    appleheader[0]  = (unsigned char)r->header.cupsBitsPerPixel;
    appleheader[1]  = r->header.cupsColorSpace == CUPS_CSPACE_SRGB ? 1 :
                        r->header.cupsColorSpace == CUPS_CSPACE_CIELab ? 2 :
                        r->header.cupsColorSpace == CUPS_CSPACE_ADOBERGB ? 3 :
                        r->header.cupsColorSpace == CUPS_CSPACE_W ? 4 :
                        r->header.cupsColorSpace == CUPS_CSPACE_RGB ? 5 :
                        r->header.cupsColorSpace == CUPS_CSPACE_CMYK ? 6 : 0;
    appleheader[2]  = r->header.Duplex ? (r->header.Tumble ? 2 : 3) : 1;
    appleheader[3]  = (unsigned char)(r->header.cupsInteger[CUPS_RASTER_PWG_PrintQuality]);
    appleheader[5]  = (unsigned char)(r->header.MediaPosition);
    appleheader[12] = (unsigned char)(r->header.cupsWidth >> 24);
    appleheader[13] = (unsigned char)(r->header.cupsWidth >> 16);
    appleheader[14] = (unsigned char)(r->header.cupsWidth >> 8);
    appleheader[15] = (unsigned char)(r->header.cupsWidth);
    appleheader[16] = (unsigned char)(height >> 24);
    appleheader[17] = (unsigned char)(height >> 16);
    appleheader[18] = (unsigned char)(height >> 8);
    appleheader[19] = (unsigned char)(height);
    appleheader[20] = (unsigned char)(r->header.HWResolution[0] >> 24);
    appleheader[21] = (unsigned char)(r->header.HWResolution[0] >> 16);
    appleheader[22] = (unsigned char)(r->header.HWResolution[0] >> 8);
    appleheader[23] = (unsigned char)(r->header.HWResolution[0]);

    for (i = 0; i < (int)(sizeof(apple_media_types) / sizeof(apple_media_types[0])); i ++)
    {
      if (!strcmp(r->header.MediaType, apple_media_types[i]))
      {
        appleheader[4] = (unsigned char)i;
        break;
      }
    }

    return (cups_raster_io(r, appleheader, sizeof(appleheader)) == sizeof(appleheader));
  }
  else
    return (cups_raster_io(r, (unsigned char *)&(r->header), sizeof(r->header))
		== sizeof(r->header));
}


/*
 * '_cupsRasterWritePixels()' - Write raster pixels.
 *
 * For best performance, filters should write one or more whole lines.
 * The "cupsBytesPerLine" value from the page header can be used to allocate
 * the line buffer and as the number of bytes to write.
 */

unsigned				/* O - Number of bytes written */
_cupsRasterWritePixels(
    cups_raster_t *r,			/* I - Raster stream */
    unsigned char *p,			/* I - Bytes to write */
    unsigned      len)			/* I - Number of bytes to write */
{
  ssize_t	bytes;			/* Bytes read */
  unsigned	remaining;		/* Bytes remaining */


  DEBUG_printf(("_cupsRasterWritePixels(r=%p, p=%p, len=%u), remaining=%u", (void *)r, (void *)p, len, r->remaining));

  if (r == NULL || r->mode == CUPS_RASTER_READ || r->remaining == 0)
    return (0);

  if (!r->compressed)
  {
   /*
    * Without compression, just write the raster data raw unless the data needs
    * to be swapped...
    */

    r->remaining -= len / r->header.cupsBytesPerLine;

    if (r->swapped &&
        (r->header.cupsBitsPerColor == 16 ||
         r->header.cupsBitsPerPixel == 12 ||
         r->header.cupsBitsPerPixel == 16))
    {
      unsigned char	*bufptr;	/* Pointer into write buffer */

     /*
      * Allocate a write buffer as needed...
      */

      if ((size_t)len > r->bufsize)
      {
	if (r->buffer)
	  bufptr = realloc(r->buffer, len);
	else
	  bufptr = malloc(len);

	if (!bufptr)
	  return (0);

	r->buffer  = bufptr;
	r->bufsize = len;
      }

     /*
      * Byte swap the pixels and write them...
      */

      cups_swap_copy(r->buffer, p, len);

      bytes = cups_raster_io(r, r->buffer, len);
    }
    else
      bytes = cups_raster_io(r, p, len);

    if (bytes < (ssize_t)len)
      return (0);
    else
      return (len);
  }

 /*
  * Otherwise, compress each line...
  */

  for (remaining = len; remaining > 0; remaining -= (unsigned)bytes, p += bytes)
  {
   /*
    * Figure out the number of remaining bytes on the current line...
    */

    if ((bytes = (ssize_t)remaining) > (ssize_t)(r->pend - r->pcurrent))
      bytes = (ssize_t)(r->pend - r->pcurrent);

    if (r->count > 0)
    {
     /*
      * Check to see if this line is the same as the previous line...
      */

      if (memcmp(p, r->pcurrent, (size_t)bytes))
      {
        if (cups_raster_write(r, r->pixels) <= 0)
	  return (0);

	r->count = 0;
      }
      else
      {
       /*
        * Mark more bytes as the same...
	*/

        r->pcurrent += bytes;

	if (r->pcurrent >= r->pend)
	{
	 /*
          * Increase the repeat count...
	  */

	  r->count += r->rowheight;
	  r->pcurrent = r->pixels;

	 /*
          * Flush out this line if it is the last one...
	  */

	  r->remaining --;

	  if (r->remaining == 0)
	  {
	    if (cups_raster_write(r, r->pixels) <= 0)
	      return (0);
	    else
	      return (len);
	  }
	  else if (r->count > (256 - r->rowheight))
	  {
	    if (cups_raster_write(r, r->pixels) <= 0)
	      return (0);

	    r->count = 0;
	  }
	}

	continue;
      }
    }

    if (r->count == 0)
    {
     /*
      * Copy the raster data to the buffer...
      */

      memcpy(r->pcurrent, p, (size_t)bytes);

      r->pcurrent += bytes;

      if (r->pcurrent >= r->pend)
      {
       /*
        * Increase the repeat count...
	*/

	r->count += r->rowheight;
	r->pcurrent = r->pixels;

       /*
        * Flush out this line if it is the last one...
	*/

	r->remaining --;

	if (r->remaining == 0)
	{
	  if (cups_raster_write(r, r->pixels) <= 0)
	    return (0);
	}
      }
    }
  }

  return (len);
}


/*
 * 'cups_raster_io()' - Read/write bytes from a context, handling interruptions.
 */

static ssize_t				/* O - Bytes read/write or -1 */
cups_raster_io(cups_raster_t *r,	/* I - Raster stream */
               unsigned char *buf,	/* I - Buffer for read/write */
               size_t        bytes)	/* I - Number of bytes to read/write */
{
  ssize_t	count,			/* Number of bytes read/written */
		total;			/* Total bytes read/written */


  DEBUG_printf(("5cups_raster_io(r=%p, buf=%p, bytes=" CUPS_LLFMT ")", (void *)r, (void *)buf, CUPS_LLCAST bytes));

  for (total = 0; total < (ssize_t)bytes; total += count, buf += count)
  {
    count = (*r->iocb)(r->ctx, buf, bytes - (size_t)total);

    DEBUG_printf(("6cups_raster_io: count=%d, total=%d", (int)count, (int)total));
    if (count == 0)
      break;
//    {
//      DEBUG_puts("6cups_raster_io: Returning 0.");
//      return (0);
//    }
    else if (count < 0)
    {
      DEBUG_puts("6cups_raster_io: Returning -1 on error.");
      return (-1);
    }

#ifdef DEBUG
    r->iocount += (size_t)count;
#endif /* DEBUG */
  }

  DEBUG_printf(("6cups_raster_io: iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount));
  DEBUG_printf(("6cups_raster_io: Returning " CUPS_LLFMT ".", CUPS_LLCAST total));

  return (total);
}


/*
 * 'cups_raster_read()' - Read through the raster buffer.
 */

static ssize_t				/* O - Number of bytes read */
cups_raster_read(cups_raster_t *r,	/* I - Raster stream */
                 unsigned char *buf,	/* I - Buffer */
                 size_t        bytes)	/* I - Number of bytes to read */
{
  ssize_t	count,			/* Number of bytes read */
		remaining,		/* Remaining bytes in buffer */
		total;			/* Total bytes read */


  DEBUG_printf(("4cups_raster_read(r=%p, buf=%p, bytes=" CUPS_LLFMT "), offset=" CUPS_LLFMT, (void *)r, (void *)buf, CUPS_LLCAST bytes, CUPS_LLCAST (r->iostart + r->bufptr - r->buffer)));

  if (!r->compressed)
    return (cups_raster_io(r, buf, bytes));

 /*
  * Allocate a read buffer as needed...
  */

  count = (ssize_t)(2 * r->header.cupsBytesPerLine);
  if (count < 65536)
    count = 65536;

  if ((size_t)count > r->bufsize)
  {
    ssize_t offset = r->bufptr - r->buffer;
					/* Offset to current start of buffer */
    ssize_t end = r->bufend - r->buffer;/* Offset to current end of buffer */
    unsigned char *rptr;		/* Pointer in read buffer */

    if (r->buffer)
      rptr = realloc(r->buffer, (size_t)count);
    else
      rptr = malloc((size_t)count);

    if (!rptr)
      return (0);

    r->buffer  = rptr;
    r->bufptr  = rptr + offset;
    r->bufend  = rptr + end;
    r->bufsize = (size_t)count;
  }

 /*
  * Loop until we have read everything...
  */

  for (total = 0, remaining = (int)(r->bufend - r->bufptr);
       total < (ssize_t)bytes;
       total += count, buf += count)
  {
    count = (ssize_t)bytes - total;

    DEBUG_printf(("5cups_raster_read: count=" CUPS_LLFMT ", remaining=" CUPS_LLFMT ", buf=%p, bufptr=%p, bufend=%p", CUPS_LLCAST count, CUPS_LLCAST remaining, (void *)buf, (void *)r->bufptr, (void *)r->bufend));

    if (remaining == 0)
    {
      if (count < 16)
      {
       /*
        * Read into the raster buffer and then copy...
	*/

#ifdef DEBUG
        r->iostart += (size_t)(r->bufend - r->buffer);
#endif /* DEBUG */

        remaining = (*r->iocb)(r->ctx, r->buffer, r->bufsize);
	if (remaining <= 0)
	  return (0);

	r->bufptr = r->buffer;
	r->bufend = r->buffer + remaining;

#ifdef DEBUG
        r->iocount += (size_t)remaining;
#endif /* DEBUG */
      }
      else
      {
       /*
        * Read directly into "buf"...
	*/

	count = (*r->iocb)(r->ctx, buf, (size_t)count);

	if (count <= 0)
	  return (0);

#ifdef DEBUG
	r->iostart += (size_t)count;
        r->iocount += (size_t)count;
#endif /* DEBUG */

	continue;
      }
    }

   /*
    * Copy bytes from raster buffer to "buf"...
    */

    if (count > remaining)
      count = remaining;

    if (count == 1)
    {
     /*
      * Copy 1 byte...
      */

      *buf = *(r->bufptr)++;
      remaining --;
    }
    else if (count < 128)
    {
     /*
      * Copy up to 127 bytes without using memcpy(); this is
      * faster because it avoids an extra function call and is
      * often further optimized by the compiler...
      */

      unsigned char	*bufptr;	/* Temporary buffer pointer */

      remaining -= count;

      for (bufptr = r->bufptr; count > 0; count --, total ++)
	*buf++ = *bufptr++;

      r->bufptr = bufptr;
    }
    else
    {
     /*
      * Use memcpy() for a large read...
      */

      memcpy(buf, r->bufptr, (size_t)count);
      r->bufptr += count;
      remaining -= count;
    }
  }

  DEBUG_printf(("5cups_raster_read: Returning %ld", (long)total));

  return (total);
}


/*
 * 'cups_raster_update()' - Update the raster header and row count for the
 *                          current page.
 */

static int				/* O - 1 on success, 0 on failure */
cups_raster_update(cups_raster_t *r)	/* I - Raster stream */
{
  if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1 ||
      r->header.cupsNumColors == 0)
  {
   /*
    * Set the "cupsNumColors" field according to the colorspace...
    */

    switch (r->header.cupsColorSpace)
    {
      case CUPS_CSPACE_W :
      case CUPS_CSPACE_K :
      case CUPS_CSPACE_WHITE :
      case CUPS_CSPACE_GOLD :
      case CUPS_CSPACE_SILVER :
      case CUPS_CSPACE_SW :
          r->header.cupsNumColors = 1;
	  break;

      case CUPS_CSPACE_RGB :
      case CUPS_CSPACE_CMY :
      case CUPS_CSPACE_YMC :
      case CUPS_CSPACE_CIEXYZ :
      case CUPS_CSPACE_CIELab :
      case CUPS_CSPACE_SRGB :
      case CUPS_CSPACE_ADOBERGB :
      case CUPS_CSPACE_ICC1 :
      case CUPS_CSPACE_ICC2 :
      case CUPS_CSPACE_ICC3 :
      case CUPS_CSPACE_ICC4 :
      case CUPS_CSPACE_ICC5 :
      case CUPS_CSPACE_ICC6 :
      case CUPS_CSPACE_ICC7 :
      case CUPS_CSPACE_ICC8 :
      case CUPS_CSPACE_ICC9 :
      case CUPS_CSPACE_ICCA :
      case CUPS_CSPACE_ICCB :
      case CUPS_CSPACE_ICCC :
      case CUPS_CSPACE_ICCD :
      case CUPS_CSPACE_ICCE :
      case CUPS_CSPACE_ICCF :
          r->header.cupsNumColors = 3;
	  break;

      case CUPS_CSPACE_RGBA :
      case CUPS_CSPACE_RGBW :
      case CUPS_CSPACE_CMYK :
      case CUPS_CSPACE_YMCK :
      case CUPS_CSPACE_KCMY :
      case CUPS_CSPACE_GMCK :
      case CUPS_CSPACE_GMCS :
          r->header.cupsNumColors = 4;
	  break;

      case CUPS_CSPACE_KCMYcm :
          if (r->header.cupsBitsPerPixel < 8)
            r->header.cupsNumColors = 6;
	  else
            r->header.cupsNumColors = 4;
	  break;

      case CUPS_CSPACE_DEVICE1 :
      case CUPS_CSPACE_DEVICE2 :
      case CUPS_CSPACE_DEVICE3 :
      case CUPS_CSPACE_DEVICE4 :
      case CUPS_CSPACE_DEVICE5 :
      case CUPS_CSPACE_DEVICE6 :
      case CUPS_CSPACE_DEVICE7 :
      case CUPS_CSPACE_DEVICE8 :
      case CUPS_CSPACE_DEVICE9 :
      case CUPS_CSPACE_DEVICEA :
      case CUPS_CSPACE_DEVICEB :
      case CUPS_CSPACE_DEVICEC :
      case CUPS_CSPACE_DEVICED :
      case CUPS_CSPACE_DEVICEE :
      case CUPS_CSPACE_DEVICEF :
          r->header.cupsNumColors = r->header.cupsColorSpace -
	                            CUPS_CSPACE_DEVICE1 + 1;
	  break;

      default :
          /* Unknown color space */
          return (0);
    }
  }

 /*
  * Set the number of bytes per pixel/color...
  */

  if (r->header.cupsColorOrder == CUPS_ORDER_CHUNKED)
    r->bpp = (r->header.cupsBitsPerPixel + 7) / 8;
  else
    r->bpp = (r->header.cupsBitsPerColor + 7) / 8;

  if (r->bpp == 0)
    r->bpp = 1;

 /*
  * Set the number of remaining rows...
  */

  if (r->header.cupsColorOrder == CUPS_ORDER_PLANAR)
    r->remaining = r->header.cupsHeight * r->header.cupsNumColors;
  else
    r->remaining = r->header.cupsHeight;

 /*
  * Allocate the compression buffer...
  */

  if (r->compressed)
  {
    if (r->pixels != NULL)
      free(r->pixels);

    if ((r->pixels = calloc(r->header.cupsBytesPerLine, 1)) == NULL)
    {
      r->pcurrent = NULL;
      r->pend     = NULL;
      r->count    = 0;

      return (0);
    }

    r->pcurrent = r->pixels;
    r->pend     = r->pixels + r->header.cupsBytesPerLine;
    r->count    = 0;
  }

  return (1);
}


/*
 * 'cups_raster_write()' - Write a row of compressed raster data...
 */

static ssize_t				/* O - Number of bytes written */
cups_raster_write(
    cups_raster_t       *r,		/* I - Raster stream */
    const unsigned char *pixels)	/* I - Pixel data to write */
{
  const unsigned char	*start,		/* Start of sequence */
			*ptr,		/* Current pointer in sequence */
			*pend,		/* End of raster buffer */
			*plast;		/* Pointer to last pixel */
  unsigned char		*wptr;		/* Pointer into write buffer */
  unsigned		bpp,		/* Bytes per pixel */
			count;		/* Count */
  _cups_copyfunc_t	cf;		/* Copy function */


  DEBUG_printf(("3cups_raster_write(r=%p, pixels=%p)", (void *)r, (void *)pixels));

 /*
  * Determine whether we need to swap bytes...
  */

  if (r->swapped && (r->header.cupsBitsPerColor == 16 || r->header.cupsBitsPerPixel == 12 || r->header.cupsBitsPerPixel == 16))
  {
    DEBUG_puts("4cups_raster_write: Swapping bytes when writing.");
    cf = (_cups_copyfunc_t)cups_swap_copy;
  }
  else
    cf = (_cups_copyfunc_t)memcpy;

  /*
  * Allocate a write buffer as needed...
  */

  count = r->header.cupsBytesPerLine * 2;
  if (count < 65536)
    count = 65536;

  if ((size_t)count > r->bufsize)
  {
    if (r->buffer)
      wptr = realloc(r->buffer, count);
    else
      wptr = malloc(count);

    if (!wptr)
    {
      DEBUG_printf(("4cups_raster_write: Unable to allocate " CUPS_LLFMT " bytes for raster buffer: %s", CUPS_LLCAST count, strerror(errno)));
      return (-1);
    }

    r->buffer  = wptr;
    r->bufsize = count;
  }

 /*
  * Write the row repeat count...
  */

  bpp     = r->bpp;
  pend    = pixels + r->header.cupsBytesPerLine;
  plast   = pend - bpp;
  wptr    = r->buffer;
  *wptr++ = (unsigned char)(r->count - 1);

 /*
  * Write using a modified PackBits compression...
  */

  for (ptr = pixels; ptr < pend;)
  {
    start = ptr;
    ptr += bpp;

    if (ptr == pend)
    {
     /*
      * Encode a single pixel at the end...
      */

      *wptr++ = 0;
      (*cf)(wptr, start, bpp);
      wptr += bpp;
    }
    else if (!memcmp(start, ptr, bpp))
    {
     /*
      * Encode a sequence of repeating pixels...
      */

      for (count = 2; count < 128 && ptr < plast; count ++, ptr += bpp)
        if (memcmp(ptr, ptr + bpp, bpp))
	  break;

      *wptr++ = (unsigned char)(count - 1);
      (*cf)(wptr, ptr, bpp);
      wptr += bpp;
      ptr  += bpp;
    }
    else
    {
     /*
      * Encode a sequence of non-repeating pixels...
      */

      for (count = 1; count < 128 && ptr < plast; count ++, ptr += bpp)
        if (!memcmp(ptr, ptr + bpp, bpp))
	  break;

      if (ptr >= plast && count < 128)
      {
        count ++;
	ptr += bpp;
      }

      *wptr++ = (unsigned char)(257 - count);

      count *= bpp;
      (*cf)(wptr, start, count);
      wptr += count;
    }
  }

  DEBUG_printf(("4cups_raster_write: Writing " CUPS_LLFMT " bytes.", CUPS_LLCAST (wptr - r->buffer)));

  return (cups_raster_io(r, r->buffer, (size_t)(wptr - r->buffer)));
}


/*
 * 'cups_swap()' - Swap bytes in raster data...
 */

static void
cups_swap(unsigned char *buf,		/* I - Buffer to swap */
          size_t        bytes)		/* I - Number of bytes to swap */
{
  unsigned char	even, odd;		/* Temporary variables */


  bytes /= 2;

  while (bytes > 0)
  {
    even   = buf[0];
    odd    = buf[1];
    buf[0] = odd;
    buf[1] = even;

    buf += 2;
    bytes --;
  }
}


/*
 * 'cups_swap_copy()' - Copy and swap bytes in raster data...
 */

static void
cups_swap_copy(
    unsigned char       *dst,		/* I - Destination */
    const unsigned char *src,		/* I - Source */
    size_t              bytes)		/* I - Number of bytes to swap */
{
  bytes /= 2;

  while (bytes > 0)
  {
    dst[0] = src[1];
    dst[1] = src[0];

    dst += 2;
    src += 2;
    bytes --;
  }
}
