diff options
author | Michael R Sweet <michaelrsweet@gmail.com> | 2016-10-27 15:41:51 -0400 |
---|---|---|
committer | Michael R Sweet <michaelrsweet@gmail.com> | 2016-10-27 15:41:51 -0400 |
commit | 05fa7028daea7631946fee2e3e29bbbff49095f3 (patch) | |
tree | c68d34b23d49748772e9d3e9bec654f0be9a63e5 /filter | |
parent | dffb0ea8822fa44a4580abf7f077dd0dd592fd0d (diff) | |
download | cups-05fa7028daea7631946fee2e3e29bbbff49095f3.tar.gz |
Add beta support for AppleRaster (per IANA Printer MIB)
Diffstat (limited to 'filter')
-rw-r--r-- | filter/raster.c | 302 | ||||
-rw-r--r-- | filter/testraster.c | 20 |
2 files changed, 275 insertions, 47 deletions
diff --git a/filter/raster.c b/filter/raster.c index dee8eeca0..002cfe3a4 100644 --- a/filter/raster.c +++ b/filter/raster.c @@ -51,6 +51,7 @@ struct _cups_raster_s /**** Raster stream data ****/ #ifdef DEBUG size_t iocount; /* Number of bytes read/written */ #endif /* DEBUG */ + unsigned apple_page_count;/* Apple raster page count */ }; @@ -418,7 +419,9 @@ cupsRasterOpenIO( r->sync != CUPS_RASTER_SYNCv1 && r->sync != CUPS_RASTER_REVSYNCv1 && r->sync != CUPS_RASTER_SYNCv2 && - r->sync != CUPS_RASTER_REVSYNCv2) + 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); @@ -426,14 +429,33 @@ cupsRasterOpenIO( } if (r->sync == CUPS_RASTER_SYNCv2 || - r->sync == CUPS_RASTER_REVSYNCv2) + r->sync == CUPS_RASTER_REVSYNCv2 || + r->sync == CUPS_RASTER_SYNCapple || + r->sync == CUPS_RASTER_REVSYNCapple) r->compressed = 1; if (r->sync == CUPS_RASTER_REVSYNC || r->sync == CUPS_RASTER_REVSYNCv1 || - r->sync == CUPS_RASTER_REVSYNCv2) + 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); + return (NULL); + } + + } + DEBUG_printf(("1cupsRasterOpenIO: r->swapped=%d, r->sync=%08x\n", r->swapped, r->sync)); } else @@ -459,6 +481,13 @@ cupsRasterOpenIO( 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)) @@ -662,7 +691,31 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ return (0); } - if (byte & 128) + 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, bytes); + break; + default : + memset(temp, 0x00, bytes); + break; + } + + temp += bytes; + bytes = 0; + } + else if (byte & 128) { /* * Copy N literal pixels... @@ -891,6 +944,60 @@ cupsRasterWriteHeader( 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. + */ + + unsigned char appleheader[64]; /* Raw page header */ + + 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_RGBW ? 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[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)(r->header.cupsHeight >> 24); + appleheader[17] = (unsigned char)(r->header.cupsHeight >> 16); + appleheader[18] = (unsigned char)(r->header.cupsHeight >> 8); + appleheader[19] = (unsigned char)(r->header.cupsHeight); + 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]); + + 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)); @@ -985,6 +1092,60 @@ cupsRasterWriteHeader2( 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. + */ + + unsigned char appleheader[64]; /* Raw page header */ + + 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_RGBW ? 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[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)(r->header.cupsHeight >> 24); + appleheader[17] = (unsigned char)(r->header.cupsHeight >> 16); + appleheader[18] = (unsigned char)(r->header.cupsHeight >> 8); + appleheader[19] = (unsigned char)(r->header.cupsHeight); + 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]); + + 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)); @@ -1201,53 +1362,118 @@ cups_raster_read_header( DEBUG_printf(("4cups_raster_read_header: r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount)); + memset(&(r->header), 0, sizeof(r->header)); + /* - * Get the length of the raster header... + * Read the 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); + switch (r->sync) + { + default : + /* + * Get the length of the raster header... + */ - DEBUG_printf(("4cups_raster_read_header: len=%d", (int)len)); + if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1) + len = sizeof(cups_page_header_t); + else + len = sizeof(cups_page_header2_t); - /* - * Read the header... - */ + DEBUG_printf(("4cups_raster_read_header: len=%d", (int)len)); - memset(&(r->header), 0, sizeof(r->header)); + /* + * Read it... + */ - if (cups_raster_read(r, (unsigned char *)&(r->header), len) < (ssize_t)len) - { - DEBUG_printf(("4cups_raster_read_header: EOF, r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount)); - return (0); - } + if (cups_raster_read(r, (unsigned char *)&(r->header), len) < (ssize_t)len) + { + DEBUG_printf(("4cups_raster_read_header: EOF, r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount)); + return (0); + } - /* - * Swap bytes as needed... - */ + /* + * Swap bytes as needed... + */ - if (r->swapped) - { - unsigned *s, /* Current word */ - temp; /* Temporary copy */ + if (r->swapped) + { + unsigned *s, /* Current word */ + temp; /* Temporary copy */ - DEBUG_puts("4cups_raster_read_header: Swapping header bytes."); + DEBUG_puts("4cups_raster_read_header: 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); + 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(("4cups_raster_read_header: %08x => %08x", temp, *s)); - } + DEBUG_printf(("4cups_raster_read_header: %08x => %08x", temp, *s)); + } + } + break; + + case CUPS_RASTER_SYNCapple : + case CUPS_RASTER_REVSYNCapple : + { + unsigned char appleheader[64]; /* Raw header */ + static const unsigned rawcspace[] = + { + CUPS_CSPACE_SW, + CUPS_CSPACE_SRGB, + CUPS_CSPACE_RGBW, + CUPS_CSPACE_ADOBERGB, + CUPS_CSPACE_W, + CUPS_CSPACE_RGB, + CUPS_CSPACE_CMYK + }; + static const unsigned rawnumcolors[] = + { + 1, + 3, + 4, + 3, + 1, + 3, + 4 + }; + + if (cups_raster_read(r, appleheader, sizeof(appleheader)) < (ssize_t)sizeof(appleheader)) + { + DEBUG_printf(("4cups_raster_read_header: 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[0] = r->apple_page_count; + r->header.cupsInteger[7] = 0xffffff; + } + break; } /* diff --git a/filter/testraster.c b/filter/testraster.c index 9c3f76508..112876d98 100644 --- a/filter/testraster.c +++ b/filter/testraster.c @@ -208,6 +208,7 @@ main(int argc, /* I - Number of command-line args */ errors += do_raster_tests(CUPS_RASTER_WRITE); errors += do_raster_tests(CUPS_RASTER_WRITE_COMPRESSED); errors += do_raster_tests(CUPS_RASTER_WRITE_PWG); + errors += do_raster_tests(CUPS_RASTER_WRITE_APPLE); } else { @@ -526,8 +527,9 @@ do_raster_tests(cups_mode_t mode) /* O - Write mode */ printf("cupsRasterOpen(%s): ", mode == CUPS_RASTER_WRITE ? "CUPS_RASTER_WRITE" : - mode == CUPS_RASTER_WRITE ? "CUPS_RASTER_WRITE_COMPRESSED" : - "CUPS_RASTER_WRITE_PWG"); + mode == CUPS_RASTER_WRITE_COMPRESSED ? "CUPS_RASTER_WRITE_COMPRESSED" : + mode == CUPS_RASTER_WRITE_PWG ? "CUPS_RASTER_WRITE_PWG" : + "CUPS_RASTER_WRITE_APPLE"); fflush(stdout); if ((fp = fopen("test.raster", "wb")) == NULL) @@ -554,15 +556,15 @@ do_raster_tests(cups_mode_t mode) /* O - Write mode */ if (page & 1) { - header.cupsBytesPerLine *= 2; + header.cupsBytesPerLine *= 4; header.cupsColorSpace = CUPS_CSPACE_CMYK; header.cupsColorOrder = CUPS_ORDER_CHUNKED; header.cupsNumColors = 4; } else { - header.cupsColorSpace = CUPS_CSPACE_K; - header.cupsColorOrder = CUPS_ORDER_BANDED; + header.cupsColorSpace = CUPS_CSPACE_W; + header.cupsColorOrder = CUPS_ORDER_CHUNKED; header.cupsNumColors = 1; } @@ -678,7 +680,7 @@ do_raster_tests(cups_mode_t mode) /* O - Write mode */ expected.cupsHeight = 256; expected.cupsBytesPerLine = 256; - if (mode == CUPS_RASTER_WRITE_PWG) + if (mode >= CUPS_RASTER_WRITE_PWG) { strlcpy(expected.MediaClass, "PwgRaster", sizeof(expected.MediaClass)); expected.cupsInteger[7] = 0xffffff; @@ -686,15 +688,15 @@ do_raster_tests(cups_mode_t mode) /* O - Write mode */ if (page & 1) { - expected.cupsBytesPerLine *= 2; + expected.cupsBytesPerLine *= 4; expected.cupsColorSpace = CUPS_CSPACE_CMYK; expected.cupsColorOrder = CUPS_ORDER_CHUNKED; expected.cupsNumColors = 4; } else { - expected.cupsColorSpace = CUPS_CSPACE_K; - expected.cupsColorOrder = CUPS_ORDER_BANDED; + expected.cupsColorSpace = CUPS_CSPACE_W; + expected.cupsColorOrder = CUPS_ORDER_CHUNKED; expected.cupsNumColors = 1; } |