From cb2737b5683adfbe5cc25bada323f43cc1ca2329 Mon Sep 17 00:00:00 2001 From: Till Kamppeter Date: Sat, 12 Feb 2022 23:39:57 -0300 Subject: [PATCH] libcupsfilters: Many filter function fixes - All filter functions, at least the ones producing CUPS/Apple/PWG Raster output, work with cups-filters-generated PPD files now, where no pseudo-PostScript code for the color space and depth is contained any more but instead, copies of the printer IPP attributes telling about supported color spaces and depths for Apple Raster and PWG Raster (using cupsRasterPrepareHeader() function). Did this for imagetoraster(), mupdftoraster(), and pdftoraster(). - In filter functions which only output CUPS Raster and not for example Apple Raster or PCLm, cups-filters-generated PPD files without Pseudo-PostScript code but copies of IPP attributes for color spaces can also be used so that the generated CUPS Raster is the one needed by rastertopwg() or rastertopdf() to generate the final format. This is available in ghostscript(), imagetoraster(), mupdftoraster(), and pdftoraster() now. - In pdftoraster() and pwgtoraster() 16-bit-per color (high color depth) modes printed in wrong colors, it was not taken account that the color space/profile conversion by LittleCMS also converts to the higher color depth, due to a bug in marking that no color depth conversion is needed any more. - In the imageto...() filter functions fixed the print-scaling=none (crop-to-fit) mode, which prints the image in its original size (based on PPI resolution stored in the image file or on 200 dpi resolution, which is the standard resolution for shipping labels). Also use crop-to-fit always when requested, do not fall back to fit-to-page when the image is significantly larger or smaller than the page. - The cupsRasterPrepareHeader() function got enhanced to get separate arguments for the actual format of the generated Raster header and for the final output format of the job, to obtain color space and depth, and the resolution according to that final output format. --- cupsfilters/filter.h | 53 ++++++--- cupsfilters/ghostscript.c | 7 +- cupsfilters/imagetopdf.c | 64 +++++----- cupsfilters/imagetops.c | 60 +++++----- cupsfilters/imagetoraster.c | 229 ++++++++++++++++++------------------ cupsfilters/mupdftoraster.c | 27 ++--- cupsfilters/pdftoraster.cxx | 35 ++++-- cupsfilters/pwgtoraster.c | 4 +- cupsfilters/raster.c | 53 ++++++--- cupsfilters/raster.h | 4 +- filter/imagetoraster.c | 13 +- filter/pdftoraster.c | 4 + 12 files changed, 304 insertions(+), 249 deletions(-) diff --git a/cupsfilters/filter.h b/cupsfilters/filter.h index 8878f0882..aa959b2f3 100644 --- a/cupsfilters/filter.h +++ b/cupsfilters/filter.h @@ -216,6 +216,7 @@ extern int ghostscript(int inputfd, Ghostscript's "cups" output device.*/ + extern int bannertopdf(int inputfd, int outputfd, int inputseekable, @@ -242,11 +243,23 @@ extern int imagetoraster(int inputfd, filter_data_t *data, void *parameters); +/* Parameters: filter_out_format_t* Ouput format: CUPS Raster, PWG + Raster, Apple Raster, PCLM + Note: On the Apple Raster, PWG Raster, and PCLm selection the + output is actually CUPS Raster but information about available + color spaces and depths is taken from the urf-supported or + pwg-raster-document-type-supported printer IPP attributes or + appropriate PPD file attributes. This mode is for further + processing with rastertopwg or rastertopclm. This can change in the + future when we add Apple Raster and PWG Raster output support to + this filter function. */ + + extern int mupdftoraster(int inputfd, - int outputfd, - int inputseekable, - filter_data_t *data, - void *parameters); + int outputfd, + int inputseekable, + filter_data_t *data, + void *parameters); extern int pclmtoraster(int inputfd, int outputfd, @@ -281,7 +294,14 @@ extern int pdftoraster(int inputfd, void* parameters); /* Parameters: filter_out_format_t* - Ouput format: CUPS Raster or PWG Raster */ + Ouput format: CUPS Raster, PWG Raster, Apple Raster, PCLm + Note: With Apple Raster or PCLm selections the output is actually + CUPS Raster but information about available color spaces and depths + is taken from the urf-supported printer IPP attribute or the + appropriate PPD file attribute (PCLM is always sRGB 8-bit). These + modes are for further processing with rastertopwg or + rastertopclm. This can change in the future when we add Apple + Raster output support to this filter. */ extern int pstops(int inputfd, @@ -335,23 +355,24 @@ extern int texttopdf(int inputfd, Data directory (fonts, charsets), charset, content type (for prettyprint), classification (for overprint/watermark) */ -extern int texttotext(int inputfd, - int outputfd, - int inputseekable, - filter_data_t *data, - void *parameters); -extern int universal(int inputfd, +extern int texttotext(int inputfd, int outputfd, int inputseekable, filter_data_t *data, void *parameters); -/* - Parameters: filter_input_output_format_t - Contains : Input_type : CONTENT_TYPE environment variable - Output type : FINAL_CONTENT TYPE environment variable */ - +extern int universal(int inputfd, + int outputfd, + int inputseekable, + filter_data_t *data, + void *parameters); + +/* Parameters: filter_input_output_format_t + Contains : Input_type : CONTENT_TYPE environment variable + Output type : FINAL_CONTENT TYPE environment variable */ + + extern void filterSetCommonOptions(ppd_file_t *ppd, int num_options, cups_option_t *options, diff --git a/cupsfilters/ghostscript.c b/cupsfilters/ghostscript.c index 4d7a62c47..ae50046c7 100644 --- a/cupsfilters/ghostscript.c +++ b/cupsfilters/ghostscript.c @@ -791,7 +791,7 @@ ghostscript(int inputfd, /* I - File descriptor input stream */ FILE *fp = NULL; GsDocType doc_type; gs_page_header h; - cups_cspace_t cspace; + cups_cspace_t cspace = -1; int bytes; int fd; int cm_disabled; @@ -1158,7 +1158,10 @@ ghostscript(int inputfd, /* I - File descriptor input stream */ } cspace = icc_profile ? CUPS_CSPACE_RGB : -1; - cupsRasterPrepareHeader(&h, data, outformat, &cspace); + cupsRasterPrepareHeader(&h, data, outformat, + (outformat != OUTPUT_FORMAT_APPLE_RASTER ? + outformat : OUTPUT_FORMAT_CUPS_RASTER), + &cspace); /* Special Ghostscript options for raster-only PDF output */ diff --git a/cupsfilters/imagetopdf.c b/cupsfilters/imagetopdf.c index ec320c9a2..d16c54eeb 100644 --- a/cupsfilters/imagetopdf.c +++ b/cupsfilters/imagetopdf.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -1333,43 +1334,40 @@ imagetopdf(int inputfd, /* I - File descriptor input stream */ } else { float final_w=w,final_h=h; - if(final_w>pw) - { - final_w = pw; - } - if(final_h>ph) + if (w > pw * doc.img->xppi / 72.0) + final_w = pw * doc.img->xppi / 72.0; + if (h > ph * doc.img->yppi / 72.0) + final_h = ph * doc.img->yppi / 72.0; + float posw=(w-final_w)/2,posh=(h-final_h)/2; + posw = (1+doc.XPosition)*posw; + posh = (1-doc.YPosition)*posh; + cups_image_t *img2 = cupsImageCrop(doc.img,posw,posh,final_w,final_h); + cupsImageClose(doc.img); + doc.img = img2; + if(flag==4) { - final_h = ph; + doc.PageBottom += (doc.PageTop - doc.PageBottom - + final_w * 72.0 / doc.img->xppi) / 2; + doc.PageTop = doc.PageBottom + + final_w * 72.0 / doc.img->xppi; + doc.PageLeft += (doc.PageRight - doc.PageLeft - + final_h * 72.0 / doc.img->yppi) / 2; + doc.PageRight = doc.PageLeft + + final_h * 72.0 / doc.img->yppi; } - if((fabs(final_w-w)>0.5*w)||(fabs(final_h-h)>0.5*h)) + else { - if (log) log(ld, FILTER_LOGLEVEL_DEBUG, - "imagetopdf: Ignoring crop-to-fit option!"); - cropfit=0; + doc.PageBottom += (doc.PageTop - doc.PageBottom - + final_h * 72.0 / doc.img->yppi) / 2; + doc.PageTop = doc.PageBottom + + final_h * 72.0 / doc.img->yppi; + doc.PageLeft += (doc.PageRight - doc.PageLeft - + final_w * 72.0 / doc.img->xppi) / 2; + doc.PageRight = doc.PageLeft + + final_w * 72.0 / doc.img->xppi; } - else{ - float posw=(w-final_w)/2,posh=(h-final_h)/2; - posw = (1+doc.XPosition)*posw; - posh = (1-doc.YPosition)*posh; - cups_image_t *img2 = cupsImageCrop(doc.img,posw,posh,final_w,final_h); - cupsImageClose(doc.img); - doc.img = img2; - if(flag==4) - { - doc.PageBottom+=(doc.PageTop-doc.PageBottom-final_w)/2; - doc.PageTop = doc.PageBottom+final_w; - doc.PageLeft +=(doc.PageRight-doc.PageLeft-final_h)/2; - doc.PageRight = doc.PageLeft+final_h; - } - else{ - doc.PageBottom+=(doc.PageTop-doc.PageBottom-final_h)/2; - doc.PageTop = doc.PageBottom+final_h; - doc.PageLeft +=(doc.PageRight-doc.PageLeft-final_w)/2; - doc.PageRight = doc.PageLeft+final_w; - } - if(doc.PageBottom<0) doc.PageBottom = 0; - if(doc.PageLeft<0) doc.PageLeft = 0; - } + if(doc.PageBottom<0) doc.PageBottom = 0; + if(doc.PageLeft<0) doc.PageLeft = 0; } } diff --git a/cupsfilters/imagetops.c b/cupsfilters/imagetops.c index 94629d74c..01044017a 100644 --- a/cupsfilters/imagetops.c +++ b/cupsfilters/imagetops.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -595,41 +596,40 @@ imagetops(int inputfd, /* I - File descriptor input stream */ else { float final_w = w, final_h = h; - if(final_w > pw) - final_w = pw; - if(final_h > ph) - final_h = ph; - if ((fabs(final_w - w) > 0.5 * w) || (fabs(final_h - h) > 0.5 * h)) + if (w > pw * img->xppi / 72.0) + final_w = pw * img->xppi / 72.0; + if (h > ph * img->yppi / 72.0) + final_h = ph * img->yppi / 72.0; + float posw = (w - final_w) / 2, posh = (h - final_h) / 2; + posw = (1 + XPosition) * posw; + posh = (1 - YPosition) * posh; + cups_image_t *img2 = cupsImageCrop(img, posw, posh, final_w, final_h); + cupsImageClose(img); + img = img2; + if (flag == 4) { - if (log) log(ld, FILTER_LOGLEVEL_DEBUG, - "imagetops: Ignoring crop-to-fit option!"); - cropfit = 0; + doc.PageBottom += (doc.PageTop - doc.PageBottom - + final_w * 72.0 / img->xppi) / 2; + doc.PageTop = doc.PageBottom + + final_w * 72.0 / img->xppi; + doc.PageLeft += (doc.PageRight - doc.PageLeft - + final_h * 72.0 / img->yppi) / 2; + doc.PageRight = doc.PageLeft + + final_h * 72.0 / img->yppi; } else { - float posw = (w - final_w) / 2, posh = (h - final_h) / 2; - posw = (1 + XPosition) * posw; - posh = (1 - YPosition) * posh; - cups_image_t *img2 = cupsImageCrop(img, posw, posh, final_w, final_h); - cupsImageClose(img); - img = img2; - if (flag == 4) - { - doc.PageBottom += (doc.PageTop - doc.PageBottom - final_w) / 2; - doc.PageTop = doc.PageBottom + final_w; - doc.PageLeft += (doc.PageRight - doc.PageLeft - final_h) / 2; - doc.PageRight = doc.PageLeft + final_h; - } - else - { - doc.PageBottom += (doc.PageTop - doc.PageBottom - final_h) / 2; - doc.PageTop = doc.PageBottom + final_h; - doc.PageLeft += (doc.PageRight - doc.PageLeft - final_w) / 2; - doc.PageRight = doc.PageLeft + final_w; - } - if (doc.PageBottom < 0) doc.PageBottom = 0; - if (doc.PageLeft < 0) doc.PageLeft = 0; + doc.PageBottom += (doc.PageTop - doc.PageBottom - + final_h * 72.0 / img->yppi) / 2; + doc.PageTop = doc.PageBottom + + final_h * 72.0 / img->yppi; + doc.PageLeft += (doc.PageRight - doc.PageLeft - + final_w * 72.0 / img->xppi) / 2; + doc.PageRight = doc.PageLeft + + final_w * 72.0 / img->xppi; } + if (doc.PageBottom < 0) doc.PageBottom = 0; + if (doc.PageLeft < 0) doc.PageLeft = 0; } } } diff --git a/cupsfilters/imagetoraster.c b/cupsfilters/imagetoraster.c index 822c7ba0b..729e6f7f3 100644 --- a/cupsfilters/imagetoraster.c +++ b/cupsfilters/imagetoraster.c @@ -172,7 +172,6 @@ static void format_YMCK(imagetoraster_doc_t *doc, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); static void make_lut(cups_ib_t *, int, float, float); -static int raster_cb(cups_page_header2_t *header, int preferred_bits); /* @@ -211,6 +210,7 @@ imagetoraster(int inputfd, /* I - File descriptor input stream */ xc1, yc1; ppd_file_t *ppd; /* PPD file */ ppd_choice_t *choice; /* PPD option choice */ + cups_cspace_t cspace = -1; /* CUPS color space */ char *resolution, /* Output resolution */ *media_type; /* Media type */ ppd_profile_t *profile; /* Color profile */ @@ -268,6 +268,34 @@ imagetoraster(int inputfd, /* I - File descriptor input stream */ customRight = 0.0, /* ppd->custom_margin[2] */ customTop = 0.0; /* ppd->custom_margin[3] */ char defSize[41]; + filter_out_format_t outformat; + + /* Note: With the OUTPUT_FORMAT_APPLE_RASTER, + OUTPUT_FORMAT_PWG_RASTER, or OUTPUT_FORMAT_PCLM selections the + output is actually CUPS Raster but information about available + color spaces and depths are taken from the urf-supported or + pwg-raster-document-type-supported printer IPP attributes or + appropriate PPD file attributes (PCLM is always sRGB + 8-bit). These modes are for further processing with rastertopwg + or rastertopclm. This can change in the future when we add Apple + Raster and PWG Raster output support to this filter. */ + + if (parameters) { + outformat = *(filter_out_format_t *)parameters; + if (outformat != OUTPUT_FORMAT_PCLM && + outformat != OUTPUT_FORMAT_CUPS_RASTER && + outformat != OUTPUT_FORMAT_PWG_RASTER && + outformat != OUTPUT_FORMAT_APPLE_RASTER) + outformat = OUTPUT_FORMAT_CUPS_RASTER; + } else + outformat = OUTPUT_FORMAT_CUPS_RASTER; + + if (log) log(ld, FILTER_LOGLEVEL_DEBUG, + "imagetorater: Final output format: %s", + (outformat == OUTPUT_FORMAT_CUPS_RASTER ? "CUPS Raster" : + (outformat == OUTPUT_FORMAT_PWG_RASTER ? "PWG Raster" : + (outformat == OUTPUT_FORMAT_APPLE_RASTER ? "Apple Raster" : + "PCLm")))); if (printer_attrs != NULL) { int left, right, top, bottom; @@ -384,49 +412,60 @@ imagetoraster(int inputfd, /* I - File descriptor input stream */ * Process job options... */ + cupsRasterPrepareHeader(&header, data, outformat, + OUTPUT_FORMAT_CUPS_RASTER, &cspace); ppd = data->ppd; - if (ppd) + doc.Orientation = header.Orientation; + doc.Duplex = header.Duplex; + doc.LanguageLevel = 1; + doc.Color = header.cupsNumColors>1?1:0; + doc.PageLeft = header.cupsImagingBBox[0] != 0.0 ? + header.cupsImagingBBox[0] : + (float)header.ImagingBoundingBox[0]; + doc.PageRight = header.cupsImagingBBox[2] != 0.0 ? + header.cupsImagingBBox[2] : + (float)header.ImagingBoundingBox[2]; + doc.PageTop = header.cupsImagingBBox[3] != 0.0 ? + header.cupsImagingBBox[3] : + (float)header.ImagingBoundingBox[3]; + doc.PageBottom = header.cupsImagingBBox[1] != 0.0 ? + header.cupsImagingBBox[1] : + (float)header.ImagingBoundingBox[1]; + doc.PageWidth = header.cupsPageSize[0] != 0.0 ? + header.cupsPageSize[0] : + (float)header.PageSize[0]; + doc.PageLength = header.cupsPageSize[1] != 0.0 ? + header.cupsPageSize[1] : + (float)header.PageSize[1]; + + if (log) { - filterSetCommonOptions(ppd, num_options, options, 0, - &doc.Orientation, &doc.Duplex, - &doc.LanguageLevel, &doc.Color, - &doc.PageLeft, &doc.PageRight, - &doc.PageTop, &doc.PageBottom, - &doc.PageWidth, &doc.PageLength, - log, ld); - } - else - { - cupsRasterParseIPPOptions(&header, data, 0, 1); - doc.Orientation = header.Orientation; - doc.Duplex = header.Duplex; - doc.LanguageLevel = 1; - doc.Color = header.cupsNumColors>1?1:0; - doc.PageLeft = header.cupsImagingBBox[0] != 0.0 ? - header.cupsImagingBBox[0] : - (float)header.ImagingBoundingBox[0]; - doc.PageRight = header.cupsImagingBBox[2] != 0.0 ? - header.cupsImagingBBox[2] : - (float)header.ImagingBoundingBox[2]; - doc.PageTop = header.cupsImagingBBox[3] != 0.0 ? - header.cupsImagingBBox[3] : - (float)header.ImagingBoundingBox[3]; - doc.PageBottom = header.cupsImagingBBox[1] != 0.0 ? - header.cupsImagingBBox[1] : - (float)header.ImagingBoundingBox[1]; - doc.PageWidth = header.cupsPageSize[0] != 0.0 ? - header.cupsPageSize[0] : - (float)header.PageSize[0]; - doc.PageLength = header.cupsPageSize[1] != 0.0 ? - header.cupsPageSize[1] : - (float)header.PageSize[1]; + log(ld, FILTER_LOGLEVEL_DEBUG, + "imagetoraster: doc.color = %d", doc.Color); + log(ld, FILTER_LOGLEVEL_DEBUG, + "imagetoraster: doc.Orientation = %d", doc.Orientation); + log(ld, FILTER_LOGLEVEL_DEBUG, + "imagetoraster: doc.Duplex = %d", doc.Duplex); + log(ld, FILTER_LOGLEVEL_DEBUG, + "imagetoraster: doc.PageWidth = %.1f", doc.PageWidth); + log(ld, FILTER_LOGLEVEL_DEBUG, + "imagetoraster: doc.PageLength = %.1f", doc.PageLength); + log(ld, FILTER_LOGLEVEL_DEBUG, + "imagetoraster: doc.PageLeft = %.1f", doc.PageLeft); + log(ld, FILTER_LOGLEVEL_DEBUG, + "imagetoraster: doc.PageRight = %.1f", doc.PageRight); + log(ld, FILTER_LOGLEVEL_DEBUG, + "imagetoraster: doc.PageTop = %.1f", doc.PageTop); + log(ld, FILTER_LOGLEVEL_DEBUG, + "imagetoraster: doc.PageBottom = %.1f", doc.PageBottom); } -if(log) log(ld, FILTER_LOGLEVEL_DEBUG, "doc.color = %d", doc.Color); -/* Find print-rendering-intent */ - getPrintRenderIntent(data, &header); - if(log) log(ld, FILTER_LOGLEVEL_DEBUG, - "Print rendering intent = %s", header.cupsRenderingIntent); + /* Find print-rendering-intent */ + + getPrintRenderIntent(data, &header); + if(log) log(ld, FILTER_LOGLEVEL_DEBUG, + "imagetoraster: Print rendering intent = %s", + header.cupsRenderingIntent); if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL) @@ -565,23 +604,6 @@ if(log) log(ld, FILTER_LOGLEVEL_DEBUG, "doc.color = %d", doc.Color); !strcasecmp(val, "yes"))) doc.Flip = 1; - /* - * Set the needed options in the page header... - */ - if(ppd!=NULL) - if (ppdRasterInterpretPPD(&header, ppd, num_options, options, raster_cb)) - { - if (log) { - log(ld, FILTER_LOGLEVEL_ERROR, - "imagetoraster: The page setup information was not valid."); - log(ld, FILTER_LOGLEVEL_DEBUG, - "imagetoraster: %s", cupsRasterErrorString()); - } - if (!inputseekable) - unlink(tempfile); - return (1); - } - /* * Get the media type and resolution that have been chosen... */ @@ -1045,43 +1067,40 @@ if(log) log(ld, FILTER_LOGLEVEL_DEBUG, "doc.color = %d", doc.Color); } else { float final_w=w,final_h=h; - if(w>pw) - { - final_w = pw; - } - if(h>ph) - { - final_h = ph; - } - if((fabs(final_w-w)>0.5*w)||(fabs(final_h-h)>0.5*h)) + if (w > pw * img->xppi / 72.0) + final_w = pw * img->xppi / 72.0; + if (h > ph * img->yppi / 72.0) + final_h = ph * img->yppi / 72.0; + float posw=(w-final_w)/2,posh=(h-final_h)/2; + posw = (1+doc.XPosition)*posw; + posh = (1-doc.YPosition)*posh; + cups_image_t *img2 = cupsImageCrop(img,posw,posh,final_w,final_h); + cupsImageClose(img); + img = img2; + if(flag==4) { - if (log) log(ld, FILTER_LOGLEVEL_DEBUG, - "imagetoraster: Ignoring crop-to-fit option!"); - cropfit=0; - } - else{ - float posw=(w-final_w)/2,posh=(h-final_h)/2; - posw = (1+doc.XPosition)*posw; - posh = (1-doc.YPosition)*posh; - cups_image_t *img2 = cupsImageCrop(img,posw,posh,final_w,final_h); - cupsImageClose(img); - img = img2; - if(flag==4) - { - doc.PageBottom+=(doc.PageTop-doc.PageBottom-final_w)/2; - doc.PageTop = doc.PageBottom+final_w; - doc.PageLeft +=(doc.PageRight-doc.PageLeft-final_h)/2; - doc.PageRight = doc.PageLeft+final_h; - } - else{ - doc.PageBottom+=(doc.PageTop-doc.PageBottom-final_h)/2; - doc.PageTop = doc.PageBottom+final_h; - doc.PageLeft +=(doc.PageRight-doc.PageLeft-final_w)/2; - doc.PageRight = doc.PageLeft+final_w; - } - if(doc.PageBottom<0) doc.PageBottom = 0; - if(doc.PageLeft<0) doc.PageLeft = 0; - } + doc.PageBottom += (doc.PageTop - doc.PageBottom - + final_w * 72.0 / img->xppi) / 2; + doc.PageTop = doc.PageBottom + + final_w * 72.0 / img->xppi; + doc.PageLeft += (doc.PageRight - doc.PageLeft - + final_h * 72.0 / img->yppi) / 2; + doc.PageRight = doc.PageLeft + + final_h * 72.0 / img->yppi; + } + else + { + doc.PageBottom += (doc.PageTop - doc.PageBottom - + final_h * 72.0 / img->yppi) / 2; + doc.PageTop = doc.PageBottom + + final_h * 72.0 / img->yppi; + doc.PageLeft += (doc.PageRight - doc.PageLeft - + final_w * 72.0 / img->xppi) / 2; + doc.PageRight = doc.PageLeft + + final_w * 72.0 / img->xppi; + } + if(doc.PageBottom<0) doc.PageBottom = 0; + if(doc.PageLeft<0) doc.PageLeft = 0; } } } @@ -4895,27 +4914,3 @@ make_lut(cups_ib_t *lut, /* I - Lookup table */ *lut++ = v; } } - - -/* - * 'raster_cb()' - Validate the page header. - */ - -static int /* O - 0 if OK, -1 if not */ -raster_cb( - cups_page_header2_t *header, /* IO - Raster header */ - int preferred_bits) /* I - Preferred bits per color */ -{ - /* - * Ensure that colorimetric colorspaces use at least 8 bits per - * component... - */ - - if ((header->cupsColorSpace == CUPS_CSPACE_CIEXYZ || - header->cupsColorSpace == CUPS_CSPACE_CIELab || - header->cupsColorSpace >= CUPS_CSPACE_ICC1) && - header->cupsBitsPerColor < 8) - header->cupsBitsPerColor = 8; - - return (0); -} diff --git a/cupsfilters/mupdftoraster.c b/cupsfilters/mupdftoraster.c index a7727c358..2d60bc0a8 100644 --- a/cupsfilters/mupdftoraster.c +++ b/cupsfilters/mupdftoraster.c @@ -415,6 +415,7 @@ mupdftoraster (int inputfd, /* I - File descriptor input stream */ filter_iscanceledfunc_t iscanceled = data->iscanceledfunc; void *icd = data->iscanceleddata; char **envp; + cups_cspace_t cspace = -1; #ifdef HAVE_CUPS_1_7 ppd_attr_t *attr; @@ -524,7 +525,8 @@ mupdftoraster (int inputfd, /* I - File descriptor input stream */ goto out; } - if(log) log(ld, FILTER_LOGLEVEL_DEBUG, "mupdftoraster: command: %s\n",CUPS_MUTOOL); + if(log) log(ld, FILTER_LOGLEVEL_DEBUG, "mupdftoraster: command: %s", + CUPS_MUTOOL); snprintf(tmpstr, sizeof(tmpstr), "%s", CUPS_MUTOOL); cupsArrayAdd(mupdf_args, strdup(tmpstr)); cupsArrayAdd(mupdf_args, strdup("draw")); @@ -536,26 +538,13 @@ mupdftoraster (int inputfd, /* I - File descriptor input stream */ cupsArrayAdd(mupdf_args, strdup("-Fpwg")); /* Note that MuPDF only creates PWG Raster and never CUPS Raster, - so we always set the PWG Raster flag in the cupsRasterParseIPPOptions() - calls. - Make also sure that the width and height of the page in pixels is - the size of the full page (as PWG Raster and MuPDF require it) and not - only the printable area (as ppdRasterInterpretPPD() sets, to fulfill - CUPS Raster standard) + so we set the PWG Raster flag in the cupsRasterPrepareHeader() call. + This function takes care of generating a completely consistent PWG + Raster header then, no extra manipulation needed. From the header h only cupsWidth/cupsHeight (dimensions in pixels), resolution, and color space are used here. */ - if (ppd) { - ppdRasterInterpretPPD(&h, ppd, num_options, options, 0); - h.cupsWidth = h.HWResolution[0] * h.PageSize[0] / 72; - h.cupsHeight = h.HWResolution[1] * h.PageSize[1] / 72; - } else { -#ifdef HAVE_CUPS_1_7 - cupsRasterParseIPPOptions(&h, &curr_data, 1, 1); -#else - if(log) log(ld, FILTER_LOGLEVEL_ERROR, "mupdftoraster: No PPD file specified."); - goto out; -#endif /* HAVE_CUPS_1_7 */ - } + cupsRasterPrepareHeader(&h, &curr_data, OUTPUT_FORMAT_PWG_RASTER, + OUTPUT_FORMAT_PWG_RASTER, &cspace); if ((h.HWResolution[0] == 100) && (h.HWResolution[1] == 100)) { /* No "Resolution" option */ diff --git a/cupsfilters/pdftoraster.cxx b/cupsfilters/pdftoraster.cxx index 713a2179e..31cb36cc5 100644 --- a/cupsfilters/pdftoraster.cxx +++ b/cupsfilters/pdftoraster.cxx @@ -312,11 +312,24 @@ static int parseOpts(filter_data_t *data, filter_logfunc_t log = data->logfunc; void *ld = data ->logdata; ipp_t *printer_attrs = data->printer_attrs; + cups_cspace_t cspace = (cups_cspace_t)(-1); + + /* Note: With the OUTPUT_FORMAT_APPLE_RASTER or OUTPUT_FORMAT_PCLM + selections the output is actually CUPS Raster but information + about available color spaces and depths is taken from the + urf-supported printer IPP attribute or the appropriate PPD file + attribute (PCLM is always sRGB 8-bit). These modes are for + further processing with rastertopwg or rastertopclm. This can + change in the future when we add Apple Raster output support to + this filter. */ + #ifdef HAVE_CUPS_1_7 if (parameters) { outformat = *(filter_out_format_t *)parameters; if (outformat != OUTPUT_FORMAT_CUPS_RASTER && - outformat != OUTPUT_FORMAT_PWG_RASTER) + outformat != OUTPUT_FORMAT_PWG_RASTER && + outformat != OUTPUT_FORMAT_APPLE_RASTER && + outformat != OUTPUT_FORMAT_PCLM) outformat = OUTPUT_FORMAT_CUPS_RASTER; } else outformat = OUTPUT_FORMAT_CUPS_RASTER; @@ -330,20 +343,26 @@ static int parseOpts(filter_data_t *data, doc->pwgraster = 1; #endif /* HAVE_CUPS_1_7 */ + num_options = joinJobOptionsAndAttrs(data, num_options, &options); + if (data->ppd) doc->ppd = data->ppd; else if (data->ppdfile) doc->ppd = ppdOpenFile(data->ppdfile); - if (doc->ppd == NULL) + if (doc->ppd) { + ppdMarkOptions(doc->ppd,num_options,options); + handleRqeuiresPageRegion(doc); + } else if (log) log(ld, FILTER_LOGLEVEL_DEBUG, "pdftoraster: PPD file is not specified."); - num_options = joinJobOptionsAndAttrs(data, num_options, &options); + cupsRasterPrepareHeader(&(doc->header), data, outformat, + (outformat == OUTPUT_FORMAT_PWG_RASTER ? + outformat : OUTPUT_FORMAT_CUPS_RASTER), + &cspace); + if (doc->ppd) { - ppdMarkOptions(doc->ppd,num_options,options); - handleRqeuiresPageRegion(doc); - ppdRasterInterpretPPD(&(doc->header),doc->ppd,num_options,options,0); attr = ppdFindAttr(doc->ppd,"pdftorasterRenderingIntent",NULL); if (attr != NULL && attr->value != NULL) { if (strcasecmp(attr->value,"PERCEPTUAL") == 0) { @@ -441,7 +460,6 @@ static int parseOpts(filter_data_t *data, else doc->pwgraster = 0; } - cupsRasterParseIPPOptions(&(doc->header),data,doc->pwgraster,1); getPrintRenderIntent(data, &(doc->header)); if(strcasecmp(doc->header.cupsRenderingIntent, "PERCEPTUAL")==0){ doc->colour_profile.renderingIntent = INTENT_PERCEPTUAL; @@ -1055,6 +1073,7 @@ static unsigned int getCMSColorSpaceType(cmsColorSpaceSignature cs) /* select convertLine function */ static int selectConvertFunc(cups_raster_t *raster, pdftoraster_doc_t* doc, conversion_function_t *convert, filter_logfunc_t log, void* ld) { + doc->bitspercolor = doc->header.cupsBitsPerColor; if ((doc->colour_profile.colorProfile == NULL || doc->colour_profile.popplerColorProfile == doc->colour_profile.colorProfile) && (doc->header.cupsColorOrder == CUPS_ORDER_CHUNKED || doc->header.cupsNumColors == 1)) { @@ -1219,8 +1238,6 @@ static int selectConvertFunc(cups_raster_t *raster, pdftoraster_doc_t* doc, conv (doc->header.cupsNumColors == 1 || doc->header.cupsColorSpace == CUPS_CSPACE_KCMYcm )) doc->bitspercolor = 0; /*Do not convertbits*/ - else - doc->bitspercolor = doc->header.cupsBitsPerColor; return (0); } diff --git a/cupsfilters/pwgtoraster.c b/cupsfilters/pwgtoraster.c index c901f5c95..759f86207 100644 --- a/cupsfilters/pwgtoraster.c +++ b/cupsfilters/pwgtoraster.c @@ -930,6 +930,8 @@ static int selectConvertFunc(cups_raster_t *raster, filter_logfunc_t log, void* ld) { + doc->bitspercolor = doc->outheader.cupsBitsPerColor; + if ((doc->color_profile.colorProfile == NULL || doc->color_profile.outputColorProfile == doc->color_profile.colorProfile) && (doc->outheader.cupsColorOrder == CUPS_ORDER_CHUNKED || doc->outheader.cupsNumColors == 1)) { @@ -1093,8 +1095,6 @@ static int selectConvertFunc(cups_raster_t *raster, (doc->outheader.cupsNumColors == 1 || doc->outheader.cupsColorSpace == CUPS_CSPACE_KCMYcm )) doc->bitspercolor = 0; /*Do not convertbits*/ - else - doc->bitspercolor = doc->outheader.cupsBitsPerColor; return (0); } diff --git a/cupsfilters/raster.c b/cupsfilters/raster.c index 7ad132ef5..bf1f636de 100644 --- a/cupsfilters/raster.c +++ b/cupsfilters/raster.c @@ -536,8 +536,14 @@ int /* O - 0 on success, -1 on error */ cupsRasterPrepareHeader(cups_page_header2_t *h, /* I - Raster header */ filter_data_t *data, /* I - Job and printer data */ - filter_out_format_t final_content_type, - /* I - Job output format */ + filter_out_format_t final_outformat, + /* I - Job output format + (determines color space, + and resolution) */ + filter_out_format_t header_outformat, + /* I - This filter's output + format (determines + header format) */ cups_cspace_t *cspace) /* IO - Color space we want to use, -1 for auto, we return color space @@ -556,6 +562,7 @@ cupsRasterPrepareHeader(cups_page_header2_t *h, /* I - Raster header */ appleraster = 0, cupsraster = 0, pclm = 0; + int cupsrasterheader = 1; const char *p; ppd_attr_t *ppd_attr; ipp_attribute_t *attr; @@ -568,6 +575,19 @@ cupsRasterPrepareHeader(cups_page_header2_t *h, /* I - Raster header */ double margins[4]; double dimensions[2]; + if (final_outformat == OUTPUT_FORMAT_PWG_RASTER) + pwgraster = 1; + else if (final_outformat == OUTPUT_FORMAT_APPLE_RASTER) + appleraster = 1; + else if (final_outformat == OUTPUT_FORMAT_PCLM) + pclm = 1; + else + cupsraster = 1; + + if (header_outformat == OUTPUT_FORMAT_PWG_RASTER || + header_outformat == OUTPUT_FORMAT_APPLE_RASTER) + cupsrasterheader = 0; + printer_attrs = data->printer_attrs; job_attrs = data->job_attrs; @@ -576,17 +596,8 @@ cupsRasterPrepareHeader(cups_page_header2_t *h, /* I - Raster header */ printer_attrs = data->printer_attrs; job_attrs = data->job_attrs; - if (final_content_type == OUTPUT_FORMAT_PWG_RASTER) - pwgraster = 1; - else if (final_content_type == OUTPUT_FORMAT_APPLE_RASTER) - appleraster = 1; - else if (final_content_type == OUTPUT_FORMAT_PCLM) - pclm = 1; - else - cupsraster = 1; - /* These values will be used in case we don't find supported resolutions - for given OUTFORMAT */ + for given output format */ if ((attr = ippFindAttribute(printer_attrs, "printer-resolution-default", IPP_TAG_RESOLUTION)) != NULL) { @@ -598,7 +609,7 @@ cupsRasterPrepareHeader(cups_page_header2_t *h, /* I - Raster header */ else yres = xres; } - /* Finding supported resolution for given outFormat */ + /* Finding supported resolution for given output format */ if (pwgraster) { if ((attr = ippFindAttribute(printer_attrs, @@ -743,7 +754,7 @@ cupsRasterPrepareHeader(cups_page_header2_t *h, /* I - Raster header */ for (i = 0; i < 2; i ++) dimensions[i] = h->PageSize[i]; - if (cupsraster) { + if (cupsrasterheader) { margins[0] = h->cupsImagingBBox[0]; margins[1] = h->cupsImagingBBox[1]; margins[2] = dimensions[0] - h->cupsImagingBBox[2]; @@ -773,13 +784,13 @@ cupsRasterPrepareHeader(cups_page_header2_t *h, /* I - Raster header */ pwgraster = 0; } } - cupsRasterParseIPPOptions(h, data, pwgraster, 1); + cupsRasterParseIPPOptions(h, data, 1 - cupsrasterheader, 1); if (ippRasterMatchIPPSize(h, data, margins, dimensions, NULL, NULL) < 0) { for (i = 0; i < 2; i ++) dimensions[i] = h->PageSize[i]; memset(margins, 0, sizeof(margins)); } - if (!cupsraster) + if (!cupsrasterheader) memset(margins, 0, sizeof(margins)); if (printer_attrs && @@ -881,7 +892,7 @@ cupsRasterPrepareHeader(cups_page_header2_t *h, /* I - Raster header */ } /* Make all page geometry fields in the header consistent */ - if (cupsraster) { + if (cupsrasterheader) { h->cupsWidth = ((dimensions[0] - margins[0] - margins[2]) / 72.0 * h->HWResolution[0]) + 0.5; h->cupsHeight = ((dimensions[1] - margins[1] - margins[3]) / @@ -895,12 +906,12 @@ cupsRasterPrepareHeader(cups_page_header2_t *h, /* I - Raster header */ for (i = 0; i < 2; i ++) { h->cupsPageSize[i] = dimensions[i]; h->PageSize[i] = (unsigned int)(h->cupsPageSize[i] + 0.5); - if (cupsraster) + if (cupsrasterheader) h->Margins[i] = margins[i] + 0.5; else h->Margins[i] = 0; } - if (cupsraster) { + if (cupsrasterheader) { h->cupsImagingBBox[0] = margins[0]; h->cupsImagingBBox[1] = margins[1]; h->cupsImagingBBox[2] = dimensions[0] - margins[2]; @@ -917,6 +928,10 @@ cupsRasterPrepareHeader(cups_page_header2_t *h, /* I - Raster header */ if (h->cupsColorOrder == CUPS_ORDER_BANDED) h->cupsBytesPerLine *= h->cupsNumColors; + /* Mark header as PWG Raster if it is not CUPS Raster */ + if (!cupsrasterheader) + strcpy(h->MediaClass, "PwgRaster"); + cupsFreeOptions(num_options, options); return (0); diff --git a/cupsfilters/raster.h b/cupsfilters/raster.h index b0d15aaad..4dc54645d 100644 --- a/cupsfilters/raster.h +++ b/cupsfilters/raster.h @@ -54,7 +54,9 @@ typedef enum backside_orient_e extern int cupsRasterPrepareHeader(cups_page_header2_t *h, filter_data_t *data, filter_out_format_t - final_content_type, + final_outformat, + filter_out_format_t + header_outformat, cups_cspace_t *cspace); extern int cupsRasterSetColorSpace(cups_page_header2_t *h, const char *available, diff --git a/filter/imagetoraster.c b/filter/imagetoraster.c index a0c5df0e2..80d13888d 100644 --- a/filter/imagetoraster.c +++ b/filter/imagetoraster.c @@ -64,7 +64,18 @@ main(int argc, /* I - Number of command-line args */ * Fire up the imagetoraster() filter function */ - ret = filterCUPSWrapper(argc, argv, imagetoraster, NULL, &JobCanceled); + filter_out_format_t outformat = OUTPUT_FORMAT_CUPS_RASTER; + char *t = getenv("FINAL_CONTENT_TYPE"); + if (t) { + if (strcasestr(t, "pwg")) + outformat = OUTPUT_FORMAT_PWG_RASTER; + else if (strcasestr(t, "urf")) + outformat = OUTPUT_FORMAT_APPLE_RASTER; + else if (strcasestr(t, "pclm")) + outformat = OUTPUT_FORMAT_PCLM; + } + + ret = filterCUPSWrapper(argc, argv, imagetoraster, &outformat, &JobCanceled); if (ret) fprintf(stderr, "ERROR: imagetoraster filter function failed.\n"); diff --git a/filter/pdftoraster.c b/filter/pdftoraster.c index 1b45bd27e..bd17814e7 100644 --- a/filter/pdftoraster.c +++ b/filter/pdftoraster.c @@ -59,6 +59,10 @@ main(int argc, /* I - Number of command-line arguments */ outformat = OUTPUT_FORMAT_PWG_RASTER; else if (strcasestr(t, "cups")) outformat = OUTPUT_FORMAT_CUPS_RASTER; + else if (strcasestr(t, "urf")) + outformat = OUTPUT_FORMAT_APPLE_RASTER; + else if (strcasestr(t, "pclm")) + outformat = OUTPUT_FORMAT_PCLM; } ret = filterCUPSWrapper(argc, argv, pdftoraster, &outformat, &JobCanceled); -- 2.47.3