From aab0624d62cdbf8721dc1ea8d098f815fc763dde Mon Sep 17 00:00:00 2001 From: Jai Luthra Date: Tue, 18 Aug 2020 12:39:00 +0530 Subject: [PATCH] Introduced rastertops filter function. Signed-off-by: Jai Luthra --- Makefile.am | 1 + cupsfilters/filter.h | 7 + cupsfilters/rastertops.c | 525 +++++++++++++++++++++++++++++++++++++++ filter/rastertops.c | 472 +---------------------------------- 4 files changed, 544 insertions(+), 461 deletions(-) create mode 100644 cupsfilters/rastertops.c diff --git a/Makefile.am b/Makefile.am index 42b56d9e0..b92b53d92 100644 --- a/Makefile.am +++ b/Makefile.am @@ -297,6 +297,7 @@ libcupsfilters_la_SOURCES = \ cupsfilters/ppdgenerator.c \ cupsfilters/pstops.c \ cupsfilters/raster.c \ + cupsfilters/rastertops.c \ cupsfilters/rgb.c \ cupsfilters/srgb.c \ $(pkgfiltersinclude_DATA) diff --git a/cupsfilters/filter.h b/cupsfilters/filter.h index cbd4c26d0..077f6d651 100644 --- a/cupsfilters/filter.h +++ b/cupsfilters/filter.h @@ -102,6 +102,13 @@ extern int pstops(int inputfd, filter_data_t *data, void *parameters); +extern int rastertops(int inputfd, + int outputfd, + int inputseekable, + int *jobcanceled, + filter_data_t *data, + void *parameters); + extern void filterSetCommonOptions(ppd_file_t *ppd, int num_options, cups_option_t *options, diff --git a/cupsfilters/rastertops.c b/cupsfilters/rastertops.c new file mode 100644 index 000000000..d867d4107 --- /dev/null +++ b/cupsfilters/rastertops.c @@ -0,0 +1,525 @@ +/* + * Include necessary headers... + */ + +#include "colormanager.h" +#include "filter.h" +#include "image.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Types... + */ +typedef struct { /**** Document information ****/ + int *JobCanceled; /* Caller sets to 1 when job canceled */ + filter_logfunc_t logfunc; /* Logging function, NULL for no + logging */ + void *logdata; /* User data for logging function, can + be NULL */ + cups_file_t *inputfp; /* Temporary file, if any */ + FILE *outputfp; /* Temporary file, if any */ +} rastertops_doc_t; + + +/* + * 'write_prolog()' - Writing the PostScript prolog for the file + */ + +void +writeProlog(int width, /* I - width of the image in points */ + int height, /* I - height of the image in points */ + rastertops_doc_t *doc) /* I - Document information */ +{ + /* Document header... */ + fprintf(doc->outputfp, "%%!PS-Adobe-3.0\n"); + fprintf(doc->outputfp, "%%%%BoundingBox: %d %d %d %d\n", 0, 0, width, height); + fprintf(doc->outputfp, "%%%%Creator: cups-filters\n"); + fprintf(doc->outputfp, "%%%%LanguageLevel: 2\n"); + fprintf(doc->outputfp, "%%%%DocumentData: Clean7Bit\n"); + fprintf(doc->outputfp, "%%%%Pages: (atend)\n"); + fprintf(doc->outputfp, "%%%%EndComments\n"); + fprintf(doc->outputfp, "%%%%BeginProlog\n"); + fprintf(doc->outputfp, "%%%%EndProlog\n"); +} + +/* + * 'writeStartPage()' - Write the basic page setup + */ + +void +writeStartPage(int page, /* I - Page to write */ + int width, /* I - Page width in points */ + int length, /* I - Page length in points */ + rastertops_doc_t *doc) /* I - Document information */ +{ + fprintf(doc->outputfp, "%%%%Page: %d %d\n", page, page); + fprintf(doc->outputfp, "%%%%BeginPageSetup\n"); + fprintf(doc->outputfp, "<< /PageSize[%d %d] >> setpagedevice\n", width, length); + fprintf(doc->outputfp, "%%%%EndPageSetup\n"); +} + +/* + * 'find_bits()' - Finding the number of bits per color + */ + +int /* O - Exit status */ +find_bits(cups_cspace_t mode, /* I - Color space of data */ + int bpc) /* I - Original bits per color of data */ +{ + if (bpc == 1 && + (mode == CUPS_CSPACE_RGB || + mode == CUPS_CSPACE_ADOBERGB || + mode == CUPS_CSPACE_SRGB || + mode == CUPS_CSPACE_CMY)) + return 8; + + if (bpc == 16) + return 8; + + return bpc; +} + +/* + * 'writeImage()' - Write the information regarding the image + */ + +void /* O - Exit status */ +writeImage(int pagewidth, /* I - width of page in points */ + int pageheight, /* I - height of page in points */ + int bpc, /* I - bits per color */ + int pixwidth, /* I - width of image in pixels */ + int pixheight, /* I - height of image in pixels */ + cups_cspace_t mode, /* I - color model of image */ + rastertops_doc_t *doc) /* I - Document information */ +{ + fprintf(doc->outputfp, "gsave\n"); + + switch (mode) + { + case CUPS_CSPACE_RGB: + case CUPS_CSPACE_CMY: + case CUPS_CSPACE_SRGB: + case CUPS_CSPACE_ADOBERGB: + fprintf(doc->outputfp, "/DeviceRGB setcolorspace\n"); + break; + + case CUPS_CSPACE_CMYK: + fprintf(doc->outputfp, "/DeviceCMYK setcolorspace\n"); + break; + + default: + case CUPS_CSPACE_K: + case CUPS_CSPACE_W: + case CUPS_CSPACE_SW: + fprintf(doc->outputfp, "/DeviceGray setcolorspace\n"); + break; + } + + if (bpc == 16) + fprintf(doc->outputfp, "/Input currentfile /FlateDecode filter def\n"); + fprintf(doc->outputfp, "%d %d scale\n", pagewidth, pageheight); + fprintf(doc->outputfp, "<< \n" + "/ImageType 1\n" + "/Width %d\n" + "/Height %d\n" + "/BitsPerComponent %d\n", pixwidth, pixheight, find_bits(mode, bpc)); + + switch (mode) + { + case CUPS_CSPACE_RGB: + case CUPS_CSPACE_CMY: + case CUPS_CSPACE_SRGB: + case CUPS_CSPACE_ADOBERGB: + fprintf(doc->outputfp, "/Decode [0 1 0 1 0 1]\n"); + break; + + case CUPS_CSPACE_CMYK: + fprintf(doc->outputfp, "/Decode [0 1 0 1 0 1 0 1]\n"); + break; + + case CUPS_CSPACE_SW: + fprintf(doc->outputfp, "/Decode [0 1]\n"); + break; + + default: + case CUPS_CSPACE_K: + case CUPS_CSPACE_W: + fprintf(doc->outputfp, "/Decode [1 0]\n"); + break; + } + + if(bpc==16) + fprintf(doc->outputfp, "/DataSource {3 string 0 1 2 {1 index exch Input read {pop}" + "if Input read pop put } for} bind\n"); + else + fprintf(doc->outputfp, "/DataSource currentfile /FlateDecode filter\n"); + + fprintf(doc->outputfp, "/ImageMatrix [%d 0 0 %d 0 %d]\n", pixwidth, -1*pixheight, pixheight); + fprintf(doc->outputfp, ">> image\n"); +} + +/* + * 'convert_pixels()'- Convert 1 bpc to 8 bpc + */ + +void +convert_pixels(unsigned char *pixdata, /* I - Original pixel data */ + unsigned char *convertedpix, /* I - Buffer for converted data */ + int width) /* I - Width of data */ +{ + int j, k = 0; /* Variables for iteration */ + unsigned int mask; /* Variable for per byte iteration */ + unsigned char temp; /* temporary character */ + + for(j = 0; j < width; ++j) + { + temp = *(pixdata + j); + for (mask = 0x80; mask != 0; mask >>= 1) + { + if (mask!=0x80 && mask != 0x08) + { + if (temp & mask) + convertedpix[k] = 0xFF; + else + convertedpix[k] = 0; + ++k; + } + } + } +} + +/* + * 'write_flate()' - Write the image data in flate encoded format + */ + +int /* O - Error value */ +write_flate(cups_raster_t *ras, /* I - Image data */ + cups_page_header2_t header, /* I - Bytes Per Line */ + rastertops_doc_t *doc) /* I - Document information */ +{ + int ret, /* Return value of this + function */ + flush, /* Check the end of image + data */ + curr_line=1, /* Maitining the working + line of pixels */ + alloc, + flag = 0; + unsigned have; /* Bytes available in + output buffer */ + z_stream strm; /* Structure required + by deflate */ + unsigned char *pixdata, + *convertedpix; + unsigned char in[header.cupsBytesPerLine * 6], /* Input data buffer */ + out[header.cupsBytesPerLine * 6]; /* Output data buffer */ + + /* allocate deflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = deflateInit(&strm, -1); + if (ret != Z_OK) + return ret; + + if(header.cupsBitsPerColor == 1 && + (header.cupsColorSpace == CUPS_CSPACE_RGB || + header.cupsColorSpace == CUPS_CSPACE_ADOBERGB || + header.cupsColorSpace == CUPS_CSPACE_SRGB)) + flag = 1; + + /* compress until end of file */ + do { + pixdata = malloc(header.cupsBytesPerLine); + cupsRasterReadPixels(ras, pixdata, header.cupsBytesPerLine); + if (flag) + { + convertedpix = malloc(header.cupsBytesPerLine * 6); + convert_pixels(pixdata,convertedpix, header.cupsBytesPerLine); + alloc = header.cupsBytesPerLine * 6; + } + else + { + convertedpix = malloc(header.cupsBytesPerLine); + memcpy(convertedpix, pixdata, header.cupsBytesPerLine); + alloc = header.cupsBytesPerLine; + } + + if(curr_line == header.cupsHeight) + flush = Z_FINISH; + else + flush = Z_NO_FLUSH; + curr_line++; + memcpy(in, convertedpix, alloc); + strm.avail_in = alloc; + strm.next_in = in; + + /* run deflate() on input until output buffer not full, finish + * compression if all of source has been read in */ + do { + strm.avail_out = alloc; + strm.next_out = out; + + /* Run the deflate algorithm on the data */ + ret = deflate(&strm, flush); + + /* check whether state is not clobbered */ + assert(ret != Z_STREAM_ERROR); + have = alloc - strm.avail_out; + if (fwrite(out, 1, have, doc->outputfp) != have) + { + (void)deflateEnd(&strm); + if (convertedpix != NULL) + free(convertedpix); + return Z_ERRNO; + } + } while (strm.avail_out == 0); + + /* all input will be used */ + assert(strm.avail_in == 0); + + /* done when last data in file processed */ + free(pixdata); + free(convertedpix); + } while (flush != Z_FINISH); + + /* stream will be complete */ + assert(ret == Z_STREAM_END); + + /* clean up and return */ + (void)deflateEnd(&strm); + return Z_OK; +} + +/* + * Report a zlib or i/o error + */ + +void +zerr(int ret, /* I - Return status of deflate */ + rastertops_doc_t *doc) /* I - Document information */ +{ + switch (ret) { + case Z_ERRNO: + if (doc->logfunc) doc->logfunc(doc->logdata, FILTER_LOGLEVEL_ERROR, + "rastertops: zpipe - error in source data or output file\n"); + break; + case Z_STREAM_ERROR: + if (doc->logfunc) doc->logfunc(doc->logdata, FILTER_LOGLEVEL_ERROR, + "rastertops: zpipe - invalid compression level\n"); + break; + case Z_DATA_ERROR: + if (doc->logfunc) doc->logfunc(doc->logdata, FILTER_LOGLEVEL_ERROR, + "rastertops: zpipe - invalid or incomplete deflate data\n"); + break; + case Z_MEM_ERROR: + if (doc->logfunc) doc->logfunc(doc->logdata, FILTER_LOGLEVEL_ERROR, + "rastertops: zpipe - out of memory\n"); + break; + case Z_VERSION_ERROR: + if (doc->logfunc) doc->logfunc(doc->logdata, FILTER_LOGLEVEL_ERROR, + "rastertops: zpipe - zlib version mismatch!\n"); + } +} + +/* + * 'writeEndPage()' - Show the current page. + */ + +void +writeEndPage(rastertops_doc_t *doc) /* I - Document information */ +{ + fprintf(doc->outputfp, "\ngrestore\n"); + fprintf(doc->outputfp, "showpage\n"); + fprintf(doc->outputfp, "%%%%PageTrailer\n"); +} + +/* + * 'writeTrailer()' - Write the PostScript trailer. + */ + +void +writeTrailer(int pages, /* I - Number of pages */ + rastertops_doc_t *doc) /* I - Document information */ +{ + fprintf(doc->outputfp, "%%%%Trailer\n"); + fprintf(doc->outputfp, "%%%%Pages: %d\n", pages); + fprintf(doc->outputfp, "%%%%EOF\n"); +} + +/* + * 'rastertops()' - Filter function to convert PWG raster input + * to PostScript + */ + +int /* O - Error status */ +rastertops(int inputfd, /* I - File descriptor input stream */ + int outputfd, /* I - File descriptor output stream */ + int inputseekable, /* I - Is input stream seekable? (unused) */ + int *jobcanceled, /* I - Pointer to integer marking + whether job is canceled */ + filter_data_t *data, /* I - Job and printer data */ + void *parameters) /* I - Filter-specific parameters (unused) */ +{ + rastertops_doc_t doc; /* Document information */ + cups_file_t *inputfp; /* Print file */ + FILE *outputfp; /* Output data stream */ + cups_raster_t *ras; /* Raster stream for printing */ + cups_page_header2_t header; /* Page header from file */ + filter_logfunc_t log = data->logfunc; + void *ld = data->logdata; + int empty, /* Is the input empty? */ + Page = 0, /* variable for counting the pages */ + ret; /* Return value of deflate compression */ + + (void)inputseekable; + (void)parameters; + + /* + * Open the input data stream specified by the inputfd... + */ + + if ((inputfp = cupsFileOpenFd(inputfd, "r")) == NULL) + { + if (!*jobcanceled) + { + if (log) log(ld, FILTER_LOGLEVEL_DEBUG, + "rastertops: Unable to open input data stream.\n"); + } + + return (1); + } + + /* + * Open the output data stream specified by the outputfd... + */ + + if ((outputfp = fdopen(outputfd, "w")) == NULL) + { + if (!*jobcanceled) + { + if (log) log(ld, FILTER_LOGLEVEL_DEBUG, + "rastertops: Unable to open output data stream.\n"); + } + + cupsFileClose(inputfp); + + return (1); + } + + /* + * Load PPD file if needed... + */ + + if (data->ppdfile == NULL && data->ppd == NULL) + { + char *p = getenv("PPD"); + if (p) + data->ppdfile = strdup(p); + else + data->ppdfile = NULL; + } + + if (data->ppd == NULL && data->ppdfile) + data->ppd = ppdOpenFile(data->ppdfile); + + if (data->ppd) + { + ppdMarkDefaults(data->ppd); + ppdMarkOptions(data->ppd, data->num_options, data->options); + } + else + { + ppd_status_t status; /* PPD error */ + int linenum; /* Line number */ + + if (log) log(ld, FILTER_LOGLEVEL_DEBUG, + "rastertops: The PPD file could not be opened.\n"); + status = ppdLastError(&linenum); + if (log) log(ld, FILTER_LOGLEVEL_DEBUG, + "rastertops: %s on line %d.\n", ppdErrorString(status), linenum); + } + + doc.JobCanceled = jobcanceled; + doc.inputfp = inputfp; + doc.outputfp = outputfp; + /* Logging function */ + doc.logdata = ld; + doc.logfunc = log; + + ras = cupsRasterOpen(inputfd, CUPS_RASTER_READ); + + /* + * Process pages as needed... + */ + Page = 0; + empty = 1; + + while (cupsRasterReadHeader2(ras, &header)) + { + /* + * Write the prolog for PS only once + */ + if (empty) + { + empty = 0; + writeProlog(header.PageSize[0], header.PageSize[1], &doc); + } + + /* + * Write a status message with the page number and number of copies. + */ + if (*jobcanceled) + break; + + Page ++; + + if (log) log(ld, FILTER_LOGLEVEL_INFO, + "rastertops: Starting page %d.\n", Page); + + /* + * Write the starting of the page + */ + writeStartPage(Page, header.PageSize[0], header.PageSize[1], &doc); + + /* + * write the information regarding the image + */ + writeImage(header.PageSize[0], header.PageSize[1], + header.cupsBitsPerColor, + header.cupsWidth, header.cupsHeight, + header.cupsColorSpace, &doc); + + /* Write the compressed image data*/ + ret = write_flate(ras, header, &doc); + if (ret != Z_OK) + zerr(ret, &doc); + writeEndPage(&doc); + } + + if (empty) + { + if (log) log(ld, FILTER_LOGLEVEL_DEBUG, + "rastertops: Input is empty, outputting empty file.\n"); + cupsRasterClose(ras); + return 0; + } + + writeTrailer(Page, &doc); + + cupsRasterClose(ras); + + cupsFileClose(inputfp); + + fclose(outputfp); + + return 0; +} diff --git a/filter/rastertops.c b/filter/rastertops.c index cef529c1d..90c0bb644 100644 --- a/filter/rastertops.c +++ b/filter/rastertops.c @@ -20,340 +20,17 @@ * @author Till Kamppeter (c) 2014 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * 'write_prolog()' - Writing the PostScript prolog for the file - */ - -void -writeProlog(int width, /* I - width of the image in points */ - int height) /* I - height of the image in points */ -{ - /* Document header... */ - printf("%%!PS-Adobe-3.0\n"); - printf("%%%%BoundingBox: %d %d %d %d\n", 0, 0, width, height); - printf("%%%%Creator: cups-filters\n"); - printf("%%%%LanguageLevel: 2\n"); - printf("%%%%DocumentData: Clean7Bit\n"); - printf("%%%%Pages: (atend)\n"); - printf("%%%%EndComments\n"); - printf("%%%%BeginProlog\n"); - printf("%%%%EndProlog\n"); -} - -/* - * 'writeStartPage()' - Write the basic page setup - */ - -void -writeStartPage(int page, /* I - Page to write */ - int width, /* I - Page width in points */ - int length) /* I - Page length in points */ -{ - printf("%%%%Page: %d %d\n", page, page); - printf("%%%%BeginPageSetup\n"); - printf("<< /PageSize[%d %d] >> setpagedevice\n", width, length); - printf("%%%%EndPageSetup\n"); -} - -/* - * 'find_bits()' - Finding the number of bits per color - */ - -int /* O - Exit status */ -find_bits(cups_cspace_t mode, /* I - Color space of data */ - int bpc) /* I - Original bits per color of data */ -{ - if (bpc == 1 && - (mode == CUPS_CSPACE_RGB || - mode == CUPS_CSPACE_ADOBERGB || - mode == CUPS_CSPACE_SRGB || - mode == CUPS_CSPACE_CMY)) - return 8; - - if (bpc == 16) - return 8; - - return bpc; -} - -/* - * 'writeImage()' - Write the information regarding the image - */ - -void /* O - Exit status */ -writeImage(int pagewidth, /* I - width of page in points */ - int pageheight, /* I - height of page in points */ - int bpc, /* I - bits per color */ - int pixwidth, /* I - width of image in pixels */ - int pixheight, /* I - height of image in pixels */ - cups_cspace_t mode) /* I - color model of image */ -{ - printf("gsave\n"); - - switch (mode) - { - case CUPS_CSPACE_RGB: - case CUPS_CSPACE_CMY: - case CUPS_CSPACE_SRGB: - case CUPS_CSPACE_ADOBERGB: - printf("/DeviceRGB setcolorspace\n"); - break; - - case CUPS_CSPACE_CMYK: - printf("/DeviceCMYK setcolorspace\n"); - break; - - default: - case CUPS_CSPACE_K: - case CUPS_CSPACE_W: - case CUPS_CSPACE_SW: - printf("/DeviceGray setcolorspace\n"); - break; - } - - if (bpc == 16) - printf("/Input currentfile /FlateDecode filter def\n"); - printf("%d %d scale\n", pagewidth, pageheight); - printf("<< \n" - "/ImageType 1\n" - "/Width %d\n" - "/Height %d\n" - "/BitsPerComponent %d\n", pixwidth, pixheight, find_bits(mode, bpc)); - - switch (mode) - { - case CUPS_CSPACE_RGB: - case CUPS_CSPACE_CMY: - case CUPS_CSPACE_SRGB: - case CUPS_CSPACE_ADOBERGB: - printf("/Decode [0 1 0 1 0 1]\n"); - break; - - case CUPS_CSPACE_CMYK: - printf("/Decode [0 1 0 1 0 1 0 1]\n"); - break; - - case CUPS_CSPACE_SW: - printf("/Decode [0 1]\n"); - break; - - default: - case CUPS_CSPACE_K: - case CUPS_CSPACE_W: - printf("/Decode [1 0]\n"); - break; - } - - if(bpc==16) - printf("/DataSource {3 string 0 1 2 {1 index exch Input read {pop}" - "if Input read pop put } for} bind\n"); - else - printf("/DataSource currentfile /FlateDecode filter\n"); - - printf("/ImageMatrix [%d 0 0 %d 0 %d]\n", pixwidth, -1*pixheight, pixheight); - printf(">> image\n"); -} - -/* - * 'convert_pixels()'- Convert 1 bpc to 8 bpc - */ - -void -convert_pixels(unsigned char *pixdata, /* I - Original pixel data */ - unsigned char *convertedpix, /* I - Buffer for converted data */ - int width) /* I - Width of data */ -{ - int j, k = 0; /* Variables for iteration */ - unsigned int mask; /* Variable for per byte iteration */ - unsigned char temp; /* temporary character */ - - for(j = 0; j < width; ++j) - { - temp = *(pixdata + j); - for (mask = 0x80; mask != 0; mask >>= 1) - { - if (mask!=0x80 && mask != 0x08) - { - if (temp & mask) - convertedpix[k] = 0xFF; - else - convertedpix[k] = 0; - ++k; - } - } - } -} - -/* - * 'write_flate()' - Write the image data in flate encoded format - */ - -int /* O - Error value */ -write_flate(cups_raster_t *ras, /* I - Image data */ - cups_page_header2_t header) /* I - Bytes Per Line */ -{ - int ret, /* Return value of this - function */ - flush, /* Check the end of image - data */ - curr_line=1, /* Maitining the working - line of pixels */ - alloc, - flag = 0; - unsigned have; /* Bytes available in - output buffer */ - z_stream strm; /* Structure required - by deflate */ - unsigned char *pixdata, - *convertedpix; - unsigned char in[header.cupsBytesPerLine * 6], /* Input data buffer */ - out[header.cupsBytesPerLine * 6]; /* Output data buffer */ - - /* allocate deflate state */ - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - ret = deflateInit(&strm, -1); - if (ret != Z_OK) - return ret; - - if(header.cupsBitsPerColor == 1 && - (header.cupsColorSpace == CUPS_CSPACE_RGB || - header.cupsColorSpace == CUPS_CSPACE_ADOBERGB || - header.cupsColorSpace == CUPS_CSPACE_SRGB)) - flag = 1; - - /* compress until end of file */ - do { - pixdata = malloc(header.cupsBytesPerLine); - cupsRasterReadPixels(ras, pixdata, header.cupsBytesPerLine); - if (flag) - { - convertedpix = malloc(header.cupsBytesPerLine * 6); - convert_pixels(pixdata,convertedpix, header.cupsBytesPerLine); - alloc = header.cupsBytesPerLine * 6; - } - else - { - convertedpix = malloc(header.cupsBytesPerLine); - memcpy(convertedpix, pixdata, header.cupsBytesPerLine); - alloc = header.cupsBytesPerLine; - } - - if(curr_line == header.cupsHeight) - flush = Z_FINISH; - else - flush = Z_NO_FLUSH; - curr_line++; - memcpy(in, convertedpix, alloc); - strm.avail_in = alloc; - strm.next_in = in; - - /* run deflate() on input until output buffer not full, finish - * compression if all of source has been read in */ - do { - strm.avail_out = alloc; - strm.next_out = out; - - /* Run the deflate algorithm on the data */ - ret = deflate(&strm, flush); - - /* check whether state is not clobbered */ - assert(ret != Z_STREAM_ERROR); - have = alloc - strm.avail_out; - if (fwrite(out, 1, have, stdout) != have) - { - (void)deflateEnd(&strm); - if (convertedpix != NULL) - free(convertedpix); - return Z_ERRNO; - } - } while (strm.avail_out == 0); - - /* all input will be used */ - assert(strm.avail_in == 0); - - /* done when last data in file processed */ - free(pixdata); - free(convertedpix); - } while (flush != Z_FINISH); - - /* stream will be complete */ - assert(ret == Z_STREAM_END); - - /* clean up and return */ - (void)deflateEnd(&strm); - return Z_OK; -} - /* - * Report a zlib or i/o error + * Include necessary headers... */ -void -zerr(int ret) /* I - Return status of deflate */ -{ - fputs("zpipe: ", stderr); - switch (ret) { - case Z_ERRNO: - fputs("error in source data or output file\n", stderr); - break; - case Z_STREAM_ERROR: - fputs("invalid compression level\n", stderr); - break; - case Z_DATA_ERROR: - fputs("invalid or incomplete deflate data\n", stderr); - break; - case Z_MEM_ERROR: - fputs("out of memory\n", stderr); - break; - case Z_VERSION_ERROR: - fputs("zlib version mismatch!\n", stderr); - } -} +#include /* - * 'writeEndPage()' - Show the current page. + * Local globals... */ -void -writeEndPage() -{ - printf("\ngrestore\n"); - printf("showpage\n"); - printf("%%%%PageTrailer\n"); -} - -/* - * 'writeTrailer()' - Write the PostScript trailer. - */ - -void -writeTrailer(int pages) /* I - Number of pages */ -{ - printf("%%%%Trailer\n"); - printf("%%%%Pages: %d\n", pages); - printf("%%%%EOF\n"); -} +static int JobCanceled = 0;/* Set to 1 on SIGTERM */ /* * 'main()' - Main entry and processing of driver. @@ -363,143 +40,16 @@ int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { - FILE *input = NULL; /* File pointer to raster document */ - int fd, /* File descriptor for raster document */ - num_options, /* Number of options */ - Canceled = 0, /* variable for job cancellation */ - empty, /* Is the input empty? */ - Page = 0, /* variable for counting the pages */ - ret; /* Return value of deflate compression */ - ppd_file_t *ppd; /* PPD file */ - cups_raster_t *ras; /* Raster stream for printing */ - cups_page_header2_t header; /* Page header from file */ - cups_option_t *options; /* Options */ - - /* - * Make sure status messages are not buffered... - */ - setbuf(stderr, NULL); + int ret; - /* - * Check command-line... + /* + * Fire up the rastertops() filter function */ - if (argc < 6 || argc > 7) - { - fprintf(stderr, "Usage: %s job-id user title copies options [file]\n", - "rastertops"); - return (1); - } - - num_options = cupsParseOptions(argv[5], 0, &options); - - /* - * Open the PPD file... - */ - ppd = ppdOpenFile(getenv("PPD")); - - if (ppd) - { - ppdMarkDefaults(ppd); - ppdMarkOptions(ppd, num_options, options); - } - else - { - ppd_status_t status; /* PPD error */ - int linenum; /* Line number */ - - fprintf(stderr, "DEBUG: The PPD file could not be opened.\n"); - status = ppdLastError(&linenum); - fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum); - } - - /* - * Open the page stream... - */ - if (argc == 7) - { - input = fopen(argv[6], "rb"); - if (input == NULL) { - fprintf(stderr, "Unable to open PWG Raster file\n"); - exit(1); - } - } - else - input = stdin; - - /* - * Get fd from file - */ - fd = fileno(input); - - /* - * Transform - */ - ras = cupsRasterOpen(fd, CUPS_RASTER_READ); - - /* - * Register a signal handler to eject the current page if the - * job is cancelled. - */ - Canceled = 0; - - - /* - * Process pages as needed... - */ - Page = 0; - empty = 1; - - while (cupsRasterReadHeader2(ras, &header)) - { - /* - * Write the prolog for PS only once - */ - if (empty) - { - empty = 0; - writeProlog(header.PageSize[0], header.PageSize[1]); - } - - /* - * Write a status message with the page number and number of copies. - */ - if (Canceled) - break; - - Page ++; - - fprintf(stderr, "INFO: Starting page %d.\n", Page); - - /* - * Write the starting of the page - */ - writeStartPage(Page, header.PageSize[0], header.PageSize[1]); - - /* - * write the information regarding the image - */ - writeImage(header.PageSize[0], header.PageSize[1], - header.cupsBitsPerColor, - header.cupsWidth, header.cupsHeight, - header.cupsColorSpace); - - /* Write the compressed image data*/ - ret = write_flate(ras, header); - if (ret != Z_OK) - zerr(ret); - writeEndPage(); - } - - if (empty) - { - fprintf(stderr, "DEBUG: Input is empty, outputting empty file.\n"); - cupsRasterClose(ras); - return 0; - } - writeTrailer(Page); + ret = filterCUPSWrapper(argc, argv, rastertops, NULL, &JobCanceled); - cupsRasterClose(ras); + if (ret) + fprintf(stderr, "ERROR: rastertops filter function failed.\n"); - return 0; + return (ret); } -- 2.47.2