aboutsummaryrefslogtreecommitdiffstats
path: root/filter/raster.c
diff options
context:
space:
mode:
Diffstat (limited to 'filter/raster.c')
-rw-r--r--filter/raster.c276
1 files changed, 233 insertions, 43 deletions
diff --git a/filter/raster.c b/filter/raster.c
index bacf5ba7..3ff03008 100644
--- a/filter/raster.c
+++ b/filter/raster.c
@@ -1,7 +1,7 @@
/*
* Raster file routines for CUPS.
*
- * Copyright 2007-2016 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* This file is part of the CUPS Imaging library.
@@ -50,11 +50,96 @@ struct _cups_raster_s /**** Raster stream data ****/
*bufend; /* End of current (read) buffer */
size_t bufsize; /* Buffer size */
#ifdef DEBUG
- size_t iocount; /* Number of bytes read/written */
+ size_t iostart, /* Start of read/write buffer */
+ iocount; /* Number of bytes read/written */
#endif /* DEBUG */
unsigned apple_page_count;/* Apple raster page count */
};
+typedef void (*_cups_copyfunc_t)(void *dst, const void *src, size_t bytes);
+
+
+/*
+ * Local globals...
+ */
+
+#ifdef DEBUG
+ static const char * const cups_color_spaces[] =
+ { /* Color spaces */
+ "CUPS_CSPACE_W",
+ "CUPS_CSPACE_RGB",
+ "CUPS_CSPACE_RGBA",
+ "CUPS_CSPACE_K",
+ "CUPS_CSPACE_CMY",
+ "CUPS_CSPACE_YMC",
+ "CUPS_CSPACE_CMYK",
+ "CUPS_CSPACE_YMCK",
+ "CUPS_CSPACE_KCMY",
+ "CUPS_CSPACE_KCMYcm",
+ "CUPS_CSPACE_GMCK",
+ "CUPS_CSPACE_GMCS",
+ "CUPS_CSPACE_WHITE",
+ "CUPS_CSPACE_GOLD",
+ "CUPS_CSPACE_SILVER",
+ "CUPS_CSPACE_CIEXYZ",
+ "CUPS_CSPACE_CIELab",
+ "CUPS_CSPACE_RGBW",
+ "CUPS_CSPACE_SW",
+ "CUPS_CSPACE_SRGB",
+ "CUPS_CSPACE_ADOBERGB",
+ "21",
+ "22",
+ "23",
+ "24",
+ "25",
+ "26",
+ "27",
+ "28",
+ "29",
+ "30",
+ "31",
+ "CUPS_CSPACE_ICC1",
+ "CUPS_CSPACE_ICC2",
+ "CUPS_CSPACE_ICC3",
+ "CUPS_CSPACE_ICC4",
+ "CUPS_CSPACE_ICC5",
+ "CUPS_CSPACE_ICC6",
+ "CUPS_CSPACE_ICC7",
+ "CUPS_CSPACE_ICC8",
+ "CUPS_CSPACE_ICC9",
+ "CUPS_CSPACE_ICCA",
+ "CUPS_CSPACE_ICCB",
+ "CUPS_CSPACE_ICCC",
+ "CUPS_CSPACE_ICCD",
+ "CUPS_CSPACE_ICCE",
+ "CUPS_CSPACE_ICCF",
+ "47",
+ "CUPS_CSPACE_DEVICE1",
+ "CUPS_CSPACE_DEVICE2",
+ "CUPS_CSPACE_DEVICE3",
+ "CUPS_CSPACE_DEVICE4",
+ "CUPS_CSPACE_DEVICE5",
+ "CUPS_CSPACE_DEVICE6",
+ "CUPS_CSPACE_DEVICE7",
+ "CUPS_CSPACE_DEVICE8",
+ "CUPS_CSPACE_DEVICE9",
+ "CUPS_CSPACE_DEVICEA",
+ "CUPS_CSPACE_DEVICEB",
+ "CUPS_CSPACE_DEVICEC",
+ "CUPS_CSPACE_DEVICED",
+ "CUPS_CSPACE_DEVICEE",
+ "CUPS_CSPACE_DEVICEF"
+ };
+ 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...
@@ -62,13 +147,12 @@ struct _cups_raster_s /**** Raster stream data ****/
static ssize_t cups_raster_io(cups_raster_t *r, unsigned char *buf, size_t bytes);
static unsigned cups_raster_read_header(cups_raster_t *r);
-static ssize_t cups_raster_read(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 ssize_t cups_raster_write(cups_raster_t *r, const unsigned char *pixels);
static ssize_t cups_read_fd(void *ctx, unsigned char *buf, size_t bytes);
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);
static ssize_t cups_write_fd(void *ctx, unsigned char *buf, size_t bytes);
@@ -356,6 +440,8 @@ cupsRasterOpen(int fd, /* I - File descriptor */
@code CUPS_RASTER_WRITE_COMPRESSED@,
or @code CUPS_RASTER_WRITE_PWG@ */
{
+ DEBUG_printf(("cupsRasterOpen(fd=%d, mode=%s)", fd, cups_modes[mode]));
+
if (mode == CUPS_RASTER_READ)
return (cupsRasterOpenIO(cups_read_fd, (void *)((intptr_t)fd), mode));
else
@@ -387,12 +473,15 @@ cupsRasterOpenIO(
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("1cupsRasterOpenIO: Returning NULL.");
return (NULL);
}
@@ -412,6 +501,7 @@ cupsRasterOpenIO(
_cupsRasterAddError("Unable to read header from raster stream: %s\n",
strerror(errno));
free(r);
+ DEBUG_puts("1cupsRasterOpenIO: Unable to read header, returning NULL.");
return (NULL);
}
@@ -426,6 +516,7 @@ cupsRasterOpenIO(
{
_cupsRasterAddError("Unknown raster format %08x!\n", r->sync);
free(r);
+ DEBUG_puts("1cupsRasterOpenIO: Unknown format, returning NULL.");
return (NULL);
}
@@ -435,6 +526,8 @@ cupsRasterOpenIO(
r->sync == CUPS_RASTER_REVSYNCapple)
r->compressed = 1;
+ DEBUG_printf(("1cupsRasterOpenIO: sync=%08x", r->sync));
+
if (r->sync == CUPS_RASTER_REVSYNC ||
r->sync == CUPS_RASTER_REVSYNCv1 ||
r->sync == CUPS_RASTER_REVSYNCv2 ||
@@ -452,12 +545,14 @@ cupsRasterOpenIO(
_cupsRasterAddError("Unable to read header from raster stream: %s\n",
strerror(errno));
free(r);
+ DEBUG_puts("1cupsRasterOpenIO: Unable to read header, returning NULL.");
return (NULL);
}
-
}
- DEBUG_printf(("1cupsRasterOpenIO: r->swapped=%d, r->sync=%08x\n", r->swapped, r->sync));
+#ifdef DEBUG
+ r->iostart = r->iocount;
+#endif /* DEBUG */
}
else
{
@@ -496,10 +591,13 @@ cupsRasterOpenIO(
_cupsRasterAddError("Unable to write raster stream header: %s\n",
strerror(errno));
free(r);
+ DEBUG_puts("1cupsRasterOpenIO: Unable to write header, returning NULL.");
return (NULL);
}
}
+ DEBUG_printf(("1cupsRasterOpenIO: compressed=%d, swapped=%d, returning %p", r->compressed, r->swapped, (void *)r));
+
return (r);
}
@@ -522,6 +620,8 @@ cupsRasterReadHeader(
cups_raster_t *r, /* I - Raster stream */
cups_page_header_t *h) /* I - Pointer to header data */
{
+ DEBUG_printf(("cupsRasterReadHeader(r=%p, h=%p)", (void *)r, (void *)h));
+
/*
* Get the raster header...
*/
@@ -529,6 +629,7 @@ cupsRasterReadHeader(
if (!cups_raster_read_header(r))
{
memset(h, 0, sizeof(cups_page_header_t));
+ DEBUG_puts("1cupsRasterReadHeader: Unable to read page header, returning 0.");
return (0);
}
@@ -538,6 +639,14 @@ cupsRasterReadHeader(
memcpy(h, &(r->header), sizeof(cups_page_header_t));
+ DEBUG_printf(("1cupsRasterReadHeader: cupsColorSpace=%s", cups_color_spaces[h->cupsColorSpace]));
+ DEBUG_printf(("1cupsRasterReadHeader: cupsBitsPerColor=%u", h->cupsBitsPerColor));
+ DEBUG_printf(("1cupsRasterReadHeader: cupsBitsPerPixel=%u", h->cupsBitsPerPixel));
+ DEBUG_printf(("1cupsRasterReadHeader: cupsBytesPerLine=%u", h->cupsBytesPerLine));
+ DEBUG_printf(("1cupsRasterReadHeader: cupsWidth=%u", h->cupsWidth));
+ DEBUG_printf(("1cupsRasterReadHeader: cupsHeight=%u", h->cupsHeight));
+
+ DEBUG_puts("1cupsRasterReadHeader: Returning 1.");
return (1);
}
@@ -563,6 +672,7 @@ cupsRasterReadHeader2(
if (!cups_raster_read_header(r))
{
memset(h, 0, sizeof(cups_page_header2_t));
+ DEBUG_puts("1cupsRasterReadHeader2: Unable to read header, returning 0.");
return (0);
}
@@ -572,6 +682,14 @@ cupsRasterReadHeader2(
memcpy(h, &(r->header), sizeof(cups_page_header2_t));
+ DEBUG_printf(("1cupsRasterReadHeader2: cupsColorSpace=%s", cups_color_spaces[h->cupsColorSpace]));
+ DEBUG_printf(("1cupsRasterReadHeader2: cupsBitsPerColor=%u", h->cupsBitsPerColor));
+ DEBUG_printf(("1cupsRasterReadHeader2: cupsBitsPerPixel=%u", h->cupsBitsPerPixel));
+ DEBUG_printf(("1cupsRasterReadHeader2: cupsBytesPerLine=%u", h->cupsBytesPerLine));
+ DEBUG_printf(("1cupsRasterReadHeader2: cupsWidth=%u", h->cupsWidth));
+ DEBUG_printf(("1cupsRasterReadHeader2: cupsHeight=%u", h->cupsHeight));
+
+ DEBUG_puts("1cupsRasterReadHeader2: Returning 1.");
return (1);
}
@@ -777,7 +895,10 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */
r->header.cupsBitsPerPixel == 12 ||
r->header.cupsBitsPerPixel == 16) &&
r->swapped)
- cups_swap(ptr, (size_t)bytes);
+ {
+ DEBUG_puts("1cupsRasterReadPixels: Swapping bytes.");
+ cups_swap(ptr, (size_t)cupsBytesPerLine);
+ }
/*
* Update pointers...
@@ -847,8 +968,20 @@ cupsRasterWriteHeader(
cups_raster_t *r, /* I - Raster stream */
cups_page_header_t *h) /* I - Raster page header */
{
+ DEBUG_printf(("cupsRasterWriteHeader(r=%p, h=%p)", (void *)r, (void *)h));
+
if (r == NULL || r->mode == CUPS_RASTER_READ)
+ {
+ DEBUG_puts("1cupsRasterWriteHeader: Returning 0.");
return (0);
+ }
+
+ DEBUG_printf(("1cupsRasterWriteHeader: cupsColorSpace=%s", cups_color_spaces[h->cupsColorSpace]));
+ DEBUG_printf(("1cupsRasterWriteHeader: cupsBitsPerColor=%u", h->cupsBitsPerColor));
+ DEBUG_printf(("1cupsRasterWriteHeader: cupsBitsPerPixel=%u", h->cupsBitsPerPixel));
+ DEBUG_printf(("1cupsRasterWriteHeader: cupsBytesPerLine=%u", h->cupsBytesPerLine));
+ DEBUG_printf(("1cupsRasterWriteHeader: cupsWidth=%u", h->cupsWidth));
+ DEBUG_printf(("1cupsRasterWriteHeader: cupsHeight=%u", h->cupsHeight));
/*
* Make a copy of the header, and compute the number of raster
@@ -859,7 +992,20 @@ cupsRasterWriteHeader(
memcpy(&(r->header), h, sizeof(cups_page_header_t));
if (!cups_raster_update(r))
+ {
+ DEBUG_puts("1cupsRasterWriteHeader: Unable to update parameters, returning 0.");
return (0);
+ }
+
+ if (r->mode == CUPS_RASTER_WRITE_APPLE)
+ {
+ r->rowheight = h->HWResolution[0] / h->HWResolution[1];
+
+ if (h->HWResolution[0] != (r->rowheight * h->HWResolution[1]))
+ return (0);
+ }
+ else
+ r->rowheight = 1;
/*
* Write the raster header...
@@ -1019,8 +1165,20 @@ cupsRasterWriteHeader2(
cups_raster_t *r, /* I - Raster stream */
cups_page_header2_t *h) /* I - Raster page header */
{
+ DEBUG_printf(("cupsRasterWriteHeader(r=%p, h=%p)", (void *)r, (void *)h));
+
if (r == NULL || r->mode == CUPS_RASTER_READ)
+ {
+ DEBUG_puts("1cupsRasterWriteHeader2: Returning 0.");
return (0);
+ }
+
+ DEBUG_printf(("1cupsRasterWriteHeader2: cupsColorSpace=%s", cups_color_spaces[h->cupsColorSpace]));
+ DEBUG_printf(("1cupsRasterWriteHeader2: cupsBitsPerColor=%u", h->cupsBitsPerColor));
+ DEBUG_printf(("1cupsRasterWriteHeader2: cupsBitsPerPixel=%u", h->cupsBitsPerPixel));
+ DEBUG_printf(("1cupsRasterWriteHeader2: cupsBytesPerLine=%u", h->cupsBytesPerLine));
+ DEBUG_printf(("1cupsRasterWriteHeader2: cupsWidth=%u", h->cupsWidth));
+ DEBUG_printf(("1cupsRasterWriteHeader2: cupsHeight=%u", h->cupsHeight));
/*
* Make a copy of the header, and compute the number of raster
@@ -1030,7 +1188,10 @@ cupsRasterWriteHeader2(
memcpy(&(r->header), h, sizeof(cups_page_header2_t));
if (!cups_raster_update(r))
+ {
+ DEBUG_puts("1cupsRasterWriteHeader: Unable to update parameters, returning 0.");
return (0);
+ }
if (r->mode == CUPS_RASTER_WRITE_APPLE)
{
@@ -1202,7 +1363,6 @@ cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */
r->header.cupsBitsPerPixel == 16))
{
unsigned char *bufptr; /* Pointer into write buffer */
- unsigned count; /* Remaining count */
/*
* Allocate a write buffer as needed...
@@ -1223,21 +1383,10 @@ cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */
}
/*
- * Byte swap the pixels...
+ * Byte swap the pixels and write them...
*/
- for (bufptr = r->buffer, count = len; count > 1; count -= 2, bufptr += 2)
- {
- bufptr[1] = *p++;
- bufptr[0] = *p++;
- }
-
- if (count) /* This should never happen... */
- *bufptr = *p;
-
- /*
- * Write the byte-swapped buffer...
- */
+ cups_swap_copy(r->buffer, p, len);
bytes = cups_raster_io(r, r->buffer, len);
}
@@ -1368,7 +1517,7 @@ cups_raster_read_header(
size_t len; /* Length for read/swap */
- DEBUG_printf(("3cups_raster_read_header(r=%p), r->mode=%d", (void *)r, r ? r->mode : 0));
+ DEBUG_printf(("3cups_raster_read_header(r=%p), r->mode=%s", (void *)r, r ? cups_modes[r->mode] : ""));
if (r == NULL || r->mode != CUPS_RASTER_READ)
return (0);
@@ -1523,10 +1672,7 @@ cups_raster_io(cups_raster_t *r, /* I - Raster stream */
DEBUG_printf(("6cups_raster_io: count=%d, total=%d", (int)count, (int)total));
if (count == 0)
- {
- DEBUG_puts("6cups_raster_io: Returning 0.");
- return (0);
- }
+ break;
else if (count < 0)
{
DEBUG_puts("6cups_raster_io: Returning -1 on error.");
@@ -1538,6 +1684,7 @@ cups_raster_io(cups_raster_t *r, /* I - Raster stream */
#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);
@@ -1558,7 +1705,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */
total; /* Total bytes read */
- DEBUG_printf(("5cups_raster_read(r=%p, buf=%p, bytes=" CUPS_LLFMT ")", (void *)r, (void *)buf, CUPS_LLCAST bytes));
+ 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));
@@ -1602,7 +1749,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */
{
count = (ssize_t)bytes - total;
- DEBUG_printf(("6cups_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));
+ 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)
{
@@ -1612,6 +1759,10 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */
* 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);
@@ -1635,6 +1786,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */
return (0);
#ifdef DEBUG
+ r->iostart += (size_t)count;
r->iocount += (size_t)count;
#endif /* DEBUG */
@@ -1687,7 +1839,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */
}
}
- DEBUG_printf(("6cups_raster_read: Returning %ld", (long)total));
+ DEBUG_printf(("5cups_raster_read: Returning %ld", (long)total));
return (total);
}
@@ -1850,11 +2002,24 @@ cups_raster_write(
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...
*/
@@ -1905,8 +2070,8 @@ cups_raster_write(
*/
*wptr++ = 0;
- for (count = bpp; count > 0; count --)
- *wptr++ = *start++;
+ (*cf)(wptr, start, bpp);
+ wptr += bpp;
}
else if (!memcmp(start, ptr, bpp))
{
@@ -1919,8 +2084,9 @@ cups_raster_write(
break;
*wptr++ = (unsigned char)(count - 1);
- for (count = bpp; count > 0; count --)
- *wptr++ = *ptr++;
+ (*cf)(wptr, ptr, bpp);
+ wptr += bpp;
+ ptr += bpp;
}
else
{
@@ -1941,7 +2107,7 @@ cups_raster_write(
*wptr++ = (unsigned char)(257 - count);
count *= bpp;
- memcpy(wptr, start, count);
+ (*cf)(wptr, start, count);
wptr += count;
}
}
@@ -1966,18 +2132,18 @@ cups_read_fd(void *ctx, /* I - File descriptor as pointer */
ssize_t count; /* Number of bytes read */
-#ifdef WIN32 /* Sigh */
+#ifdef _WIN32 /* Sigh */
while ((count = read(fd, buf, (unsigned)bytes)) < 0)
#else
while ((count = read(fd, buf, bytes)) < 0)
-#endif /* WIN32 */
+#endif /* _WIN32 */
if (errno != EINTR && errno != EAGAIN)
{
- DEBUG_printf(("4cups_read_fd: %s", strerror(errno)));
+ DEBUG_printf(("8cups_read_fd: %s", strerror(errno)));
return (-1);
}
- DEBUG_printf(("4cups_read_fd: Returning %d bytes.", (int)count));
+ DEBUG_printf(("8cups_read_fd: Returning %d bytes.", (int)count));
return (count);
}
@@ -2010,6 +2176,30 @@ cups_swap(unsigned char *buf, /* I - Buffer to swap */
/*
+ * '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 --;
+ }
+}
+
+
+/*
* 'cups_write_fd()' - Write bytes to a file.
*/
@@ -2023,14 +2213,14 @@ cups_write_fd(void *ctx, /* I - File descriptor pointer */
ssize_t count; /* Number of bytes written */
-#ifdef WIN32 /* Sigh */
+#ifdef _WIN32 /* Sigh */
while ((count = write(fd, buf, (unsigned)bytes)) < 0)
#else
while ((count = write(fd, buf, bytes)) < 0)
-#endif /* WIN32 */
+#endif /* _WIN32 */
if (errno != EINTR && errno != EAGAIN)
{
- DEBUG_printf(("4cups_write_fd: %s", strerror(errno)));
+ DEBUG_printf(("8cups_write_fd: %s", strerror(errno)));
return (-1);
}