summaryrefslogtreecommitdiff
path: root/src/cups/rastertoprinter.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cups/rastertoprinter.c')
-rw-r--r--src/cups/rastertoprinter.c1231
1 files changed, 723 insertions, 508 deletions
diff --git a/src/cups/rastertoprinter.c b/src/cups/rastertoprinter.c
index c88a0be..b9da368 100644
--- a/src/cups/rastertoprinter.c
+++ b/src/cups/rastertoprinter.c
@@ -1,7 +1,7 @@
/*
- * "$Id: rastertoprinter.c,v 1.19.4.15 2004/03/26 03:29:39 rlk Exp $"
+ * "$Id: rastertoprinter.c,v 1.96 2005/04/23 00:26:07 rlk Exp $"
*
- * GIMP-print based raster filter for the Common UNIX Printing System.
+ * Gutenprint based raster filter for the Common UNIX Printing System.
*
* Copyright 1993-2003 by Easy Software Products.
*
@@ -32,16 +32,11 @@
* main() - Main entry and processing of driver.
* cups_writefunc() - Write data to a file...
* cancel_job() - Cancel the current job...
- * Image_bpp() - Return the bytes-per-pixel of an image.
* Image_get_appname() - Get the application we are running.
* Image_get_row() - Get one row of the image.
* Image_height() - Return the height of an image.
* Image_init() - Initialize an image.
- * Image_note_progress() - Notify the user of our progress.
- * Image_progress_conclude() - Close the progress display.
- * Image_progress_init() - Initialize progress display.
- * Image_rotate_ccw() - Rotate the image counter-clockwise
- * (unsupported).
+ * Image_conclude() - Close the progress display.
* Image_width() - Return the width of an image.
*/
@@ -49,6 +44,9 @@
* Include necessary headers...
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <cups/cups.h>
#include <cups/ppd.h>
#include <cups/raster.h>
@@ -57,15 +55,11 @@
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
+#include <sys/times.h>
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
-#ifdef INCLUDE_GIMP_PRINT_H
-#include INCLUDE_GIMP_PRINT_H
-#else
-#include <gimp-print/gimp-print.h>
-#endif
-#include "../../lib/libprintut.h"
+#include <gutenprint/gutenprint.h>
/* Solaris with gcc has problems because gcc's limits.h doesn't #define */
/* this */
@@ -88,49 +82,480 @@ typedef struct
int top;
int width;
int height;
+ int adjusted_width;
+ int adjusted_height;
+ int last_percent;
cups_page_header_t header; /* Page header from file */
} cups_image_t;
static void cups_writefunc(void *file, const char *buf, size_t bytes);
+static void cups_errfunc(void *file, const char *buf, size_t bytes);
static void cancel_job(int sig);
static const char *Image_get_appname(stp_image_t *image);
-static void Image_progress_conclude(stp_image_t *image);
-static void Image_note_progress(stp_image_t *image,
- double current, double total);
-static void Image_progress_init(stp_image_t *image);
static stp_image_status_t Image_get_row(stp_image_t *image,
- unsigned char *data, int row);
+ unsigned char *data,
+ size_t byte_limit, int row);
static int Image_height(stp_image_t *image);
static int Image_width(stp_image_t *image);
-static int Image_bpp(stp_image_t *image);
-static void Image_rotate_180(stp_image_t *image);
-static void Image_rotate_cw(stp_image_t *image);
-static void Image_rotate_ccw(stp_image_t *image);
+static void Image_conclude(stp_image_t *image);
static void Image_init(stp_image_t *image);
static stp_image_t theImage =
{
Image_init,
NULL, /* reset */
- NULL, /* transpose */
- NULL, /* hflip */
- NULL, /* vflip */
- NULL, /* crop */
- Image_rotate_ccw,
- Image_rotate_cw,
- Image_rotate_180,
- Image_bpp,
Image_width,
Image_height,
Image_get_row,
Image_get_appname,
- Image_progress_init,
- Image_note_progress,
- Image_progress_conclude,
+ Image_conclude,
NULL
};
-static volatile stp_image_status_t Image_status;
+static volatile stp_image_status_t Image_status = STP_IMAGE_STATUS_OK;
+static double total_bytes_printed = 0;
+static int print_messages_as_errors = 0;
+
+static void
+set_string_parameter(stp_vars_t *v, const char *name, const char *val)
+{
+ fprintf(stderr, "DEBUG: Gutenprint set string %s to %s\n", name, val);
+ stp_set_string_parameter(v, name, val);
+}
+
+
+static void
+set_special_parameter(stp_vars_t *v, const char *name, int choice)
+{
+ stp_parameter_t desc;
+ stp_describe_parameter(v, name, &desc);
+ if (desc.p_type == STP_PARAMETER_TYPE_STRING_LIST)
+ {
+ if (choice >= stp_string_list_count(desc.bounds.str))
+ fprintf(stderr, "ERROR: Gutenprint unable to set %s!\n", name);
+ else
+ {
+ stp_set_string_parameter
+ (v, name, stp_string_list_param(desc.bounds.str, choice)->name);
+ fprintf(stderr, "DEBUG: Gutenprint set special parameter %s to choice %d (%s)\n",
+ name, choice,
+ stp_string_list_param(desc.bounds.str, choice)->name);
+ }
+ }
+ else
+ fprintf(stderr, "DEBUG: Gutenprint unable to set special %s: not a string\n",
+ name);
+ stp_parameter_description_destroy(&desc);
+}
+
+static void
+print_debug_block(const stp_vars_t *v, const cups_image_t *cups)
+{
+ stp_parameter_list_t params;
+ int nparams;
+ int i;
+ fprintf(stderr, "DEBUG: Gutenprint StartPage...\n");
+ fprintf(stderr, "DEBUG: Gutenprint MediaClass = \"%s\"\n", cups->header.MediaClass);
+ fprintf(stderr, "DEBUG: Gutenprint MediaColor = \"%s\"\n", cups->header.MediaColor);
+ fprintf(stderr, "DEBUG: Gutenprint MediaType = \"%s\"\n", cups->header.MediaType);
+ fprintf(stderr, "DEBUG: Gutenprint OutputType = \"%s\"\n", cups->header.OutputType);
+
+ fprintf(stderr, "DEBUG: Gutenprint AdvanceDistance = %d\n", cups->header.AdvanceDistance);
+ fprintf(stderr, "DEBUG: Gutenprint AdvanceMedia = %d\n", cups->header.AdvanceMedia);
+ fprintf(stderr, "DEBUG: Gutenprint Collate = %d\n", cups->header.Collate);
+ fprintf(stderr, "DEBUG: Gutenprint CutMedia = %d\n", cups->header.CutMedia);
+ fprintf(stderr, "DEBUG: Gutenprint Duplex = %d\n", cups->header.Duplex);
+ fprintf(stderr, "DEBUG: Gutenprint HWResolution = [ %d %d ]\n", cups->header.HWResolution[0],
+ cups->header.HWResolution[1]);
+ fprintf(stderr, "DEBUG: Gutenprint ImagingBoundingBox = [ %d %d %d %d ]\n",
+ cups->header.ImagingBoundingBox[0], cups->header.ImagingBoundingBox[1],
+ cups->header.ImagingBoundingBox[2], cups->header.ImagingBoundingBox[3]);
+ fprintf(stderr, "DEBUG: Gutenprint InsertSheet = %d\n", cups->header.InsertSheet);
+ fprintf(stderr, "DEBUG: Gutenprint Jog = %d\n", cups->header.Jog);
+ fprintf(stderr, "DEBUG: Gutenprint LeadingEdge = %d\n", cups->header.LeadingEdge);
+ fprintf(stderr, "DEBUG: Gutenprint Margins = [ %d %d ]\n", cups->header.Margins[0],
+ cups->header.Margins[1]);
+ fprintf(stderr, "DEBUG: Gutenprint ManualFeed = %d\n", cups->header.ManualFeed);
+ fprintf(stderr, "DEBUG: Gutenprint MediaPosition = %d\n", cups->header.MediaPosition);
+ fprintf(stderr, "DEBUG: Gutenprint MediaWeight = %d\n", cups->header.MediaWeight);
+ fprintf(stderr, "DEBUG: Gutenprint MirrorPrint = %d\n", cups->header.MirrorPrint);
+ fprintf(stderr, "DEBUG: Gutenprint NegativePrint = %d\n", cups->header.NegativePrint);
+ fprintf(stderr, "DEBUG: Gutenprint NumCopies = %d\n", cups->header.NumCopies);
+ fprintf(stderr, "DEBUG: Gutenprint Orientation = %d\n", cups->header.Orientation);
+ fprintf(stderr, "DEBUG: Gutenprint OutputFaceUp = %d\n", cups->header.OutputFaceUp);
+ fprintf(stderr, "DEBUG: Gutenprint PageSize = [ %d %d ]\n", cups->header.PageSize[0],
+ cups->header.PageSize[1]);
+ fprintf(stderr, "DEBUG: Gutenprint Separations = %d\n", cups->header.Separations);
+ fprintf(stderr, "DEBUG: Gutenprint TraySwitch = %d\n", cups->header.TraySwitch);
+ fprintf(stderr, "DEBUG: Gutenprint Tumble = %d\n", cups->header.Tumble);
+ fprintf(stderr, "DEBUG: Gutenprint cupsWidth = %d\n", cups->header.cupsWidth);
+ fprintf(stderr, "DEBUG: Gutenprint cupsHeight = %d\n", cups->header.cupsHeight);
+ fprintf(stderr, "DEBUG: Gutenprint cups->width = %d\n", cups->width);
+ fprintf(stderr, "DEBUG: Gutenprint cups->height = %d\n", cups->height);
+ fprintf(stderr, "DEBUG: Gutenprint cups->adjusted_width = %d\n", cups->adjusted_width);
+ fprintf(stderr, "DEBUG: Gutenprint cups->adjusted_height = %d\n", cups->adjusted_height);
+ fprintf(stderr, "DEBUG: Gutenprint cupsMediaType = %d\n", cups->header.cupsMediaType);
+ fprintf(stderr, "DEBUG: Gutenprint cupsBitsPerColor = %d\n", cups->header.cupsBitsPerColor);
+ fprintf(stderr, "DEBUG: Gutenprint cupsBitsPerPixel = %d\n", cups->header.cupsBitsPerPixel);
+ fprintf(stderr, "DEBUG: Gutenprint cupsBytesPerLine = %d\n", cups->header.cupsBytesPerLine);
+ fprintf(stderr, "DEBUG: Gutenprint cupsColorOrder = %d\n", cups->header.cupsColorOrder);
+ fprintf(stderr, "DEBUG: Gutenprint cupsColorSpace = %d\n", cups->header.cupsColorSpace);
+ fprintf(stderr, "DEBUG: Gutenprint cupsCompression = %d\n", cups->header.cupsCompression);
+ fprintf(stderr, "DEBUG: Gutenprint cupsRowCount = %d\n", cups->header.cupsRowCount);
+ fprintf(stderr, "DEBUG: Gutenprint cupsRowFeed = %d\n", cups->header.cupsRowFeed);
+ fprintf(stderr, "DEBUG: Gutenprint cupsRowStep = %d\n", cups->header.cupsRowStep);
+ fprintf(stderr, "DEBUG: Gutenprint stp_get_driver(v) |%s|\n", stp_get_driver(v));
+ fprintf(stderr, "DEBUG: Gutenprint stp_get_left(v) |%d|\n", stp_get_left(v));
+ fprintf(stderr, "DEBUG: Gutenprint stp_get_top(v) |%d|\n", stp_get_top(v));
+ fprintf(stderr, "DEBUG: Gutenprint stp_get_page_width(v) |%d|\n", stp_get_page_width(v));
+ fprintf(stderr, "DEBUG: Gutenprint stp_get_page_height(v) |%d|\n", stp_get_page_height(v));
+ params = stp_get_parameter_list(v);
+ nparams = stp_parameter_list_count(params);
+ for (i = 0; i < nparams; i++)
+ {
+ const stp_parameter_t *p = stp_parameter_list_param(params, i);
+ switch (p->p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ fprintf(stderr, "DEBUG: Gutenprint stp_get_string %s(v) |%s| %d\n",
+ p->name, stp_get_string_parameter(v, p->name) ?
+ stp_get_string_parameter(v, p->name) : "NULL",
+ stp_get_string_parameter_active(v, p->name));
+ break;
+ case STP_PARAMETER_TYPE_DOUBLE:
+ fprintf(stderr, "DEBUG: Gutenprint stp_get_float %s(v) |%.3f| %d\n",
+ p->name, stp_get_float_parameter(v, p->name),
+ stp_get_float_parameter_active(v, p->name));
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ fprintf(stderr, "DEBUG: Gutenprint stp_get_dimension %s(v) |%d| %d\n",
+ p->name, stp_get_dimension_parameter(v, p->name),
+ stp_get_dimension_parameter_active(v, p->name));
+ break;
+ case STP_PARAMETER_TYPE_INT:
+ fprintf(stderr, "DEBUG: Gutenprint stp_get_int %s(v) |%d| %d\n",
+ p->name, stp_get_int_parameter(v, p->name),
+ stp_get_int_parameter_active(v, p->name));
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ fprintf(stderr, "DEBUG: Gutenprint stp_get_boolean %s(v) |%d| %d\n",
+ p->name, stp_get_boolean_parameter(v, p->name),
+ stp_get_boolean_parameter_active(v, p->name));
+ break;
+ /*
+ * We don't handle raw, curve, or filename arguments.
+ */
+ default:
+ break;
+ }
+ }
+ stp_parameter_list_destroy(params);
+}
+
+static int
+printer_supports_bw(const stp_vars_t *v)
+{
+ stp_parameter_t desc;
+ int status = 0;
+ stp_describe_parameter(v, "PrintingMode", &desc);
+ if (stp_string_list_is_present(desc.bounds.str, "BW"))
+ status = 1;
+ stp_parameter_description_destroy(&desc);
+ return status;
+}
+
+static void
+validate_options(stp_vars_t *v, cups_image_t *cups)
+{
+ stp_parameter_list_t params = stp_get_parameter_list(v);
+ int nparams = stp_parameter_list_count(params);
+ int i;
+ for (i = 0; i < nparams; i++)
+ {
+ const stp_parameter_t *param = stp_parameter_list_param(params, i);
+ stp_parameter_t desc;
+ stp_describe_parameter(v, param->name, &desc);
+ if (desc.p_type == STP_PARAMETER_TYPE_STRING_LIST)
+ {
+ if (!stp_string_list_is_present
+ (desc.bounds.str, stp_get_string_parameter(v, desc.name)))
+ {
+ fprintf(stderr, "DEBUG: Gutenprint clearing string %s (%s)\n",
+ desc.name, stp_get_string_parameter(v, desc.name));
+ stp_clear_string_parameter(v, desc.name);
+ if (desc.is_mandatory)
+ {
+ fprintf(stderr, "DEBUG: Gutenprint setting default string %s to %s\n",
+ desc.name, desc.deflt.str);
+ stp_set_string_parameter(v, desc.name, desc.deflt.str);
+ if (strcmp(desc.name, "PageSize") == 0)
+ {
+ const stp_papersize_t *ps =
+ stp_get_papersize_by_name(desc.deflt.str);
+ if (ps->width > 0)
+ {
+ fprintf(stderr, "DEBUG: Gutenprint setting page width to %d\n",
+ ps->width);
+ if (ps->width < stp_get_page_width(v))
+ stp_set_page_width(v, ps->width);
+ }
+ if (ps->height > 0)
+ {
+ fprintf(stderr, "DEBUG: Gutenprint setting page height to %d\n",
+ ps->height);
+ if (ps->height < stp_get_page_height(v))
+ stp_set_page_height(v, ps->height);
+ }
+ }
+ }
+ }
+ }
+ stp_parameter_description_destroy(&desc);
+ }
+ stp_parameter_list_destroy(params);
+}
+
+static stp_vars_t *
+initialize_page(cups_image_t *cups, const stp_vars_t *default_settings)
+{
+ const stp_papersize_t *size; /* Paper size */
+ stp_vars_t *v = stp_vars_create_copy(default_settings);
+
+ stp_set_page_width(v, cups->header.PageSize[0]);
+ stp_set_page_height(v, cups->header.PageSize[1]);
+ stp_set_outfunc(v, cups_writefunc);
+ stp_set_errfunc(v, cups_errfunc);
+ stp_set_outdata(v, stdout);
+ stp_set_errdata(v, stderr);
+
+ if (cups->header.cupsBitsPerColor == 16)
+ set_string_parameter(v, "ChannelBitDepth", "16");
+ else
+ set_string_parameter(v, "ChannelBitDepth", "8");
+ switch (cups->header.cupsColorSpace)
+ {
+ case CUPS_CSPACE_W :
+ /* Olympus photo printers don't support black & white ink! */
+ if (printer_supports_bw(v))
+ set_string_parameter(v, "PrintingMode", "BW");
+ set_string_parameter(v, "InputImageType", "Whitescale");
+ break;
+ case CUPS_CSPACE_K :
+ /* Olympus photo printers don't support black & white ink! */
+ if (printer_supports_bw(v))
+ set_string_parameter(v, "PrintingMode", "BW");
+ set_string_parameter(v, "InputImageType", "Grayscale");
+ break;
+ case CUPS_CSPACE_RGB :
+ set_string_parameter(v, "PrintingMode", "Color");
+ set_string_parameter(v, "InputImageType", "RGB");
+ break;
+ case CUPS_CSPACE_CMY :
+ set_string_parameter(v, "PrintingMode", "Color");
+ set_string_parameter(v, "InputImageType", "CMY");
+ break;
+ case CUPS_CSPACE_CMYK :
+ set_string_parameter(v, "PrintingMode", "Color");
+ set_string_parameter(v, "InputImageType", "CMYK");
+ break;
+ case CUPS_CSPACE_KCMY :
+ set_string_parameter(v, "PrintingMode", "Color");
+ set_string_parameter(v, "InputImageType", "KCMY");
+ break;
+ default :
+ fprintf(stderr, "ERROR: Gutenprint Bad colorspace %d!\n",
+ cups->header.cupsColorSpace);
+ break;
+ }
+
+ if (cups->header.cupsCompression >= 0)
+ set_special_parameter(v, "Resolution", cups->header.cupsCompression);
+
+ if (cups->header.MediaClass && strlen(cups->header.MediaClass) > 0)
+ set_string_parameter(v, "InputSlot", cups->header.MediaClass);
+
+ if (cups->header.MediaType && strlen(cups->header.MediaType) > 0)
+ set_string_parameter(v, "MediaType", cups->header.MediaType);
+
+ fprintf(stderr, "DEBUG: Gutenprint PageSize = %dx%d\n", cups->header.PageSize[0],
+ cups->header.PageSize[1]);
+
+ if ((size = stp_get_papersize_by_size(cups->header.PageSize[1],
+ cups->header.PageSize[0])) != NULL)
+ set_string_parameter(v, "PageSize", size->name);
+ else
+ fprintf(stderr, "DEBUG: Gutenprint Unable to get media size for (%d, %d)\n",
+ cups->header.PageSize[1], cups->header.PageSize[0]);
+
+ /*
+ * Duplex
+ * Note that the names MUST match those in the printer driver(s)
+ */
+
+ if (cups->header.Duplex != 0)
+ {
+ if (cups->header.Tumble != 0)
+ set_string_parameter(v, "Duplex", "DuplexTumble");
+ else
+ set_string_parameter(v, "Duplex", "DuplexNoTumble");
+ }
+
+ set_string_parameter(v, "JobMode", "Job");
+ validate_options(v, cups);
+ stp_get_media_size(v, &(cups->width), &(cups->height));
+ stp_get_imageable_area(v, &(cups->left), &(cups->right),
+ &(cups->bottom), &(cups->top));
+ fprintf(stderr, "DEBUG: Gutenprint limits w %d l %d r %d h %d t %d b %d\n",
+ cups->width, cups->left, cups->right, cups->height, cups->top, cups->bottom);
+ stp_set_width(v, cups->right - cups->left);
+ stp_set_height(v, cups->bottom - cups->top);
+ stp_set_left(v, cups->left);
+ stp_set_top(v, cups->top);
+ cups->right = cups->width - cups->right;
+ cups->width = cups->width - cups->left - cups->right;
+ cups->width = cups->header.HWResolution[0] * cups->width / 72;
+ cups->left = cups->header.HWResolution[0] * cups->left / 72;
+ cups->right = cups->header.HWResolution[0] * cups->right / 72;
+ cups->adjusted_width = cups->width;
+ if (cups->adjusted_width > cups->header.cupsWidth)
+ cups->adjusted_width = cups->header.cupsWidth;
+
+ cups->bottom = cups->height - cups->bottom;
+ cups->height = cups->height - cups->top - cups->bottom;
+ cups->height = cups->header.HWResolution[1] * cups->height / 72;
+ cups->top = cups->header.HWResolution[1] * cups->top / 72;
+ cups->bottom = cups->header.HWResolution[1] * cups->bottom / 72;
+ cups->adjusted_height = cups->height;
+ if (cups->adjusted_height > cups->header.cupsHeight)
+ cups->adjusted_height = cups->header.cupsHeight;
+ fprintf(stderr, "DEBUG: Gutenprint CUPS settings w %d %d l %d r %d h %d %d t %d b %d\n",
+ cups->width, cups->adjusted_width, cups->left, cups->right,
+ cups->height, cups->adjusted_height, cups->top, cups->bottom);
+
+ return v;
+}
+
+static void
+purge_excess_data(cups_image_t *cups)
+{
+ char *buffer = stp_malloc(cups->header.cupsBytesPerLine);
+ if (buffer)
+ {
+ fprintf(stderr, "DEBUG: Gutenprint purging %d rows\n",
+ cups->header.cupsHeight - cups->row);
+ while (cups->row < cups->header.cupsHeight)
+ {
+ cupsRasterReadPixels(cups->ras, (unsigned char *)buffer,
+ cups->header.cupsBytesPerLine);
+ cups->row ++;
+ }
+ }
+ stp_free(buffer);
+}
+
+static void
+set_all_options(stp_vars_t *v, cups_option_t *options, int num_options,
+ ppd_file_t *ppd)
+{
+ stp_parameter_list_t params = stp_get_parameter_list(v);
+ int nparams = stp_parameter_list_count(params);
+ int i;
+ for (i = 0; i < nparams; i++)
+ {
+ const stp_parameter_t *param = stp_parameter_list_param(params, i);
+ stp_parameter_t desc;
+ char *ppd_option_name = stp_malloc(strlen(param->name) + 8); /* StpFineFOO\0 */
+
+ const char *val; /* CUPS option value */
+ ppd_option_t *ppd_option;
+ stp_describe_parameter(v, param->name, &desc);
+ if (desc.p_type == STP_PARAMETER_TYPE_DOUBLE)
+ {
+ sprintf(ppd_option_name, "Stp%s", desc.name);
+ val = cupsGetOption(ppd_option_name, num_options, options);
+ if (!val)
+ {
+ ppd_option = ppdFindOption(ppd, ppd_option_name);
+ if (ppd_option)
+ val = ppd_option->defchoice;
+ }
+ if (val && strlen(val) > 0 && strcmp(val, "None") != 0)
+ {
+ double coarse_val = atof(val) * 0.001;
+ double fine_val = 0;
+ sprintf(ppd_option_name, "StpFine%s", desc.name);
+ val = cupsGetOption(ppd_option_name, num_options, options);
+ if (!val)
+ {
+ ppd_option = ppdFindOption(ppd, ppd_option_name);
+ if (ppd_option)
+ val = ppd_option->defchoice;
+ }
+ if (val && strlen(val) > 0 && strcmp(val, "None") != 0)
+ fine_val = atof(val) * 0.001;
+ fprintf(stderr, "DEBUG: Gutenprint set float %s to %f + %f\n",
+ desc.name, coarse_val, fine_val);
+ fine_val += coarse_val;
+ if (fine_val > desc.bounds.dbl.upper)
+ fine_val = desc.bounds.dbl.upper;
+ stp_set_float_parameter(v, desc.name, fine_val);
+ }
+ }
+ else
+ {
+ sprintf(ppd_option_name, "Stp%s", desc.name);
+ val = cupsGetOption(ppd_option_name, num_options, options);
+ if (!val)
+ {
+ ppd_option = ppdFindOption(ppd, ppd_option_name);
+ if (ppd_option)
+ val = ppd_option->defchoice;
+ }
+ if (val && ((strlen(val) > 0 && strcmp(val, "None") != 0) ||
+ (desc.p_type == STP_PARAMETER_TYPE_STRING_LIST)))
+ {
+ switch (desc.p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ fprintf(stderr, "DEBUG: Gutenprint set string %s to %s\n",
+ desc.name, val);
+ set_string_parameter(v, desc.name, val);
+ break;
+ case STP_PARAMETER_TYPE_INT:
+ fprintf(stderr, "DEBUG: Gutenprint set int %s to %s\n",
+ desc.name, val);
+ stp_set_int_parameter(v, desc.name, atoi(val));
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ fprintf(stderr, "DEBUG: Gutenprint set dimension %s to %s\n",
+ desc.name, val);
+ stp_set_dimension_parameter(v, desc.name, atoi(val));
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ fprintf(stderr, "DEBUG: Gutenprint set bool %s to %s\n",
+ desc.name, val);
+ stp_set_boolean_parameter
+ (v, desc.name, strcmp(val, "True") == 0 ? 1 : 0);
+ break;
+ case STP_PARAMETER_TYPE_CURVE: /* figure this out later... */
+ case STP_PARAMETER_TYPE_FILE: /* Probably not, security hole */
+ case STP_PARAMETER_TYPE_RAW: /* figure this out later, too */
+ fprintf(stderr, "DEBUG: Gutenprint ignoring option %s %s type %d\n",
+ desc.name, val, desc.p_type);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ fprintf(stderr, "DEBUG: Gutenprint NOT setting %s to %s\n",
+ desc.name, val);
+ }
+ stp_parameter_description_destroy(&desc);
+ stp_free(ppd_option_name);
+ }
+ stp_parameter_list_destroy(params);
+}
/*
* 'main()' - Main entry and processing of driver.
@@ -144,37 +569,35 @@ main(int argc, /* I - Number of command-line arguments */
cups_image_t cups; /* CUPS image */
const char *ppdfile; /* PPD environment variable */
ppd_file_t *ppd; /* PPD file */
- ppd_option_t *option; /* PPD option */
- stp_printer_t printer; /* Printer driver */
- stp_vars_t v; /* Printer driver variables */
- stp_papersize_t size; /* Paper size */
- char *buffer; /* Overflow buffer */
+ const stp_printer_t *printer; /* Printer driver */
int num_options; /* Number of CUPS options */
cups_option_t *options; /* CUPS options */
- const char *val; /* CUPS option value */
- int num_res; /* Number of printer resolutions */
- stp_param_t *res; /* Printer resolutions */
- float stp_gamma, /* STP options */
- stp_brightness,
- stp_cyan,
- stp_magenta,
- stp_yellow,
- stp_contrast,
- stp_saturation,
- stp_density;
-
+ stp_vars_t *v = NULL;
+ stp_vars_t *default_settings;
+ int initialized_job = 0;
+ const char *version_id;
+ const char *release_version_id;
+ struct tms tms;
+ clock_t clk;
+ long clocks_per_sec;
+ struct timeval t1, t2;
+ struct timezone tz;
/*
- * Initialise libgimpprint
+ * Initialise libgutenprint
*/
theImage.rep = &cups;
+ (void) gettimeofday(&t1, &tz);
stp_init();
-
+ version_id = stp_get_version();
+ release_version_id = stp_get_release_version();
+ default_settings = stp_vars_create();
/*
* Check for valid arguments...
*/
+ fprintf(stderr, "DEBUG: Gutenprint %s Starting\n", version_id);
if (argc < 6 || argc > 7)
{
@@ -183,36 +606,73 @@ main(int argc, /* I - Number of command-line arguments */
* and return.
*/
- fputs("ERROR: rastertoprinter job-id user title copies options [file]\n", stderr);
+ fputs("ERROR: Gutenprint rastertoprinter job-id user title copies options [file]\n", stderr);
return (1);
}
- Image_status = STP_IMAGE_OK;
-
/*
* Get the PPD file...
*/
if ((ppdfile = getenv("PPD")) == NULL)
{
- fputs("ERROR: Fatal error: PPD environment variable not set!\n", stderr);
+ fputs("ERROR: Gutenprint Fatal error: PPD environment variable not set!\n", stderr);
return (1);
}
+ fprintf(stderr, "DEBUG: Gutenprint using PPD file %s\n", ppdfile);
if ((ppd = ppdOpenFile(ppdfile)) == NULL)
{
- fprintf(stderr, "ERROR: Fatal error: Unable to load PPD file \"%s\"!\n",
+ fprintf(stderr, "ERROR: Gutenprint Fatal error: Unable to load PPD file \"%s\"!\n",
ppdfile);
return (1);
}
if (ppd->modelname == NULL)
{
- fprintf(stderr, "ERROR: Fatal error: No ModelName attribute in PPD file \"%s\"!\n",
+ fprintf(stderr, "ERROR: Gutenprint Fatal error: No ModelName attribute in PPD file \"%s\"!\n",
+ ppdfile);
+ ppdClose(ppd);
+ return (1);
+ }
+
+ if (ppd->nickname == NULL)
+ {
+ fprintf(stderr, "ERROR: Gutenprint Fatal error: No NickName attribute in PPD file \"%s\"!\n",
+ ppdfile);
+ ppdClose(ppd);
+ return (1);
+ }
+ else if (strlen(ppd->nickname) <
+ strlen(ppd->modelname) + strlen(CUPS_PPD_NICKNAME_STRING) + 3)
+ {
+ fprintf(stderr, "ERROR: Gutenprint Fatal error: Corrupted NickName attribute in PPD file \"%s\"!\n",
ppdfile);
ppdClose(ppd);
return (1);
}
+ else if (strcmp(ppd->nickname + strlen(ppd->modelname) +
+ strlen(CUPS_PPD_NICKNAME_STRING), version_id) != 0)
+ {
+ fprintf(stderr, "ERROR: Gutenprint: The version of Gutenprint software installed (%s) does not match the PPD file (%s).\n",
+ version_id,
+ ppd->nickname+strlen(ppd->modelname)+strlen(CUPS_PPD_NICKNAME_STRING));
+ fprintf(stderr, "ERROR: Gutenprint: If you have upgraded your version of Gutenprint\n");
+ fprintf(stderr, "ERROR: Gutenprint: recently, you must reinstall all printer queues.\n");
+ fprintf(stderr, "ERROR: Gutenprint: If the previous installed version of Gutenprint\n");
+ fprintf(stderr, "ERROR: Gutenprint: was 4.3.19 or higher, you can use the `cups-genppdupdate.%s'\n", release_version_id);
+ fprintf(stderr, "ERROR: Gutenprint: program to do this; if the previous installed version\n");
+ fprintf(stderr, "ERROR: Gutenprint: was older, you can use the Modify Printer command via\n");
+ fprintf(stderr, "ERROR: Gutenprint: the CUPS web interface: http://localhost:631/printers.\n");
+ /*
+ * Repeat the first line of the message so that CUPS will display it
+ */
+ fprintf(stderr, "ERROR: Gutenprint: The version of Gutenprint software installed (%s) does not match the PPD file (%s).\n",
+ version_id,
+ ppd->nickname+strlen(ppd->modelname)+strlen(CUPS_PPD_NICKNAME_STRING));
+ ppdClose(ppd);
+ return 1;
+ }
/*
* Get the STP options, if any...
@@ -220,83 +680,33 @@ main(int argc, /* I - Number of command-line arguments */
num_options = cupsParseOptions(argv[5], 0, &options);
- if ((val = cupsGetOption("stpGamma", num_options, options)) != NULL)
- stp_gamma = atof(val) * 0.001;
- else if ((option = ppdFindOption(ppd, "stpGamma")) != NULL)
- stp_gamma = atof(option->defchoice) * 0.001;
- else
- stp_gamma = 1.0;
-
- if ((val = cupsGetOption("stpBrightness", num_options, options)) != NULL)
- stp_brightness = atof(val) * 0.001;
- else if ((option = ppdFindOption(ppd, "stpBrightness")) != NULL)
- stp_brightness = atof(option->defchoice) * 0.001;
- else
- stp_brightness = 1.0;
-
- if ((val = cupsGetOption("stpCyan", num_options, options)) != NULL)
- stp_cyan = atof(val) * 0.001;
- else if ((option = ppdFindOption(ppd, "stpCyan")) != NULL)
- stp_cyan = atof(option->defchoice) * 0.001;
- else
- stp_cyan = 1.0;
-
- if ((val = cupsGetOption("stpMagenta", num_options, options)) != NULL)
- stp_magenta = atof(val) * 0.001;
- else if ((option = ppdFindOption(ppd, "stpMagenta")) != NULL)
- stp_magenta = atof(option->defchoice) * 0.001;
- else
- stp_magenta = 1.0;
-
- if ((val = cupsGetOption("stpYellow", num_options, options)) != NULL)
- stp_yellow = atof(val) * 0.001;
- else if ((option = ppdFindOption(ppd, "stpYellow")) != NULL)
- stp_yellow = atof(option->defchoice) * 0.001;
- else
- stp_yellow = 1.0;
-
- if ((val = cupsGetOption("stpContrast", num_options, options)) != NULL)
- stp_contrast = atof(val) * 0.001;
- else if ((option = ppdFindOption(ppd, "stpContrast")) != NULL)
- stp_contrast = atof(option->defchoice) * 0.001;
- else
- stp_contrast = 1.0;
-
- if ((val = cupsGetOption("stpSaturation", num_options, options)) != NULL)
- stp_saturation = atof(val) * 0.001;
- else if ((option = ppdFindOption(ppd, "stpSaturation")) != NULL)
- stp_saturation = atof(option->defchoice) * 0.001;
- else
- stp_saturation = 1.0;
+ fprintf(stderr, "DEBUG: Gutenprint CUPS option count is %d (%d bytes)\n",
+ num_options, strlen(argv[5]));
- if ((val = cupsGetOption("stpDensity", num_options, options)) != NULL)
- stp_density = atof(val) * 0.001;
- else if ((option = ppdFindOption(ppd, "stpDensity")) != NULL)
- stp_density = atof(option->defchoice) * 0.001;
- else
- stp_density = 1.0;
+ if (num_options > 0)
+ {
+ int i;
+ for (i = 0; i < num_options; i++)
+ fprintf(stderr, "DEBUG: Gutenprint CUPS option %d %s = %s\n",
+ i, options[i].name, options[i].value);
+ }
/*
* Figure out which driver to use...
*/
- if ((printer = stp_get_printer_by_long_name(ppd->modelname)) == NULL)
- if ((printer = stp_get_printer_by_driver(ppd->modelname)) == NULL)
+ printer = stp_get_printer_by_driver(ppd->modelname);
+ if (!printer)
+ printer = stp_get_printer_by_long_name(ppd->modelname);
+
+ if (printer == NULL)
{
- fprintf(stderr, "ERROR: Fatal error: Unable to find driver named \"%s\"!\n",
+ fprintf(stderr, "ERROR: Gutenprint Fatal error: Unable to find driver named \"%s\"!\n",
ppd->modelname);
ppdClose(ppd);
return (1);
}
-
- ppdClose(ppd);
-
- /*
- * Get the resolution options...
- */
-
- res = stp_printer_get_printfuncs(printer)->parameters(printer, NULL,
- "Resolution", &num_res);
+ fprintf(stderr, "DEBUG: Gutenprint driver %s\n", ppd->modelname);
/*
* Open the page stream...
@@ -306,32 +716,22 @@ main(int argc, /* I - Number of command-line arguments */
{
if ((fd = open(argv[6], O_RDONLY)) == -1)
{
- perror("ERROR: Unable to open raster file - ");
+ perror("ERROR: Gutenprint Unable to open raster file - ");
sleep(1);
return (1);
}
}
else
fd = 0;
+ fprintf(stderr, "DEBUG: Gutenprint using fd %d\n", fd);
- cups.ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
-
- /*
- * Setup default print variables...
- */
-
- v = stp_allocate_copy(stp_printer_get_printvars(printer));
+ stp_set_printer_defaults(default_settings, printer);
+ stp_set_float_parameter(default_settings, "AppGamma", 1.0);
+ set_all_options(default_settings, options, num_options, ppd);
+ stp_merge_printvars(default_settings, stp_printer_get_defaults(printer));
+ ppdClose(ppd);
- stp_set_scaling(v, 0); /* No scaling */
- stp_set_cmap(v, NULL);
- stp_set_left(v, 0);
- stp_set_top(v, 0);
- stp_set_orientation(v, ORIENT_PORTRAIT);
- stp_set_outfunc(v, cups_writefunc);
- stp_set_errfunc(v, cups_writefunc);
- stp_set_outdata(v, stdout);
- stp_set_errdata(v, stderr);
- stp_set_job_mode(v, STP_JOB_MODE_JOB);
+ cups.ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
/*
* Process pages as needed...
@@ -339,244 +739,108 @@ main(int argc, /* I - Number of command-line arguments */
cups.page = 0;
+ fprintf(stderr, "DEBUG: Gutenprint about to start printing loop.\n");
+ /*
+ * Read the first page header, which we need in order to set up
+ * the page.
+ */
+ signal(SIGTERM, cancel_job);
while (cupsRasterReadHeader(cups.ras, &cups.header))
- {
- /*
- * Update the current page...
- */
-
- cups.row = 0;
-
- fprintf(stderr, "PAGE: %d 1\n", cups.page + 1);
- /* use 1-based page logging */
-
- /*
- * Debugging info...
- */
-
- fprintf(stderr, "DEBUG: StartPage...\n");
- fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", cups.header.MediaClass);
- fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", cups.header.MediaColor);
- fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", cups.header.MediaType);
- fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", cups.header.OutputType);
-
- fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", cups.header.AdvanceDistance);
- fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", cups.header.AdvanceMedia);
- fprintf(stderr, "DEBUG: Collate = %d\n", cups.header.Collate);
- fprintf(stderr, "DEBUG: CutMedia = %d\n", cups.header.CutMedia);
- fprintf(stderr, "DEBUG: Duplex = %d\n", cups.header.Duplex);
- fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", cups.header.HWResolution[0],
- cups.header.HWResolution[1]);
- fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n",
- cups.header.ImagingBoundingBox[0], cups.header.ImagingBoundingBox[1],
- cups.header.ImagingBoundingBox[2], cups.header.ImagingBoundingBox[3]);
- fprintf(stderr, "DEBUG: InsertSheet = %d\n", cups.header.InsertSheet);
- fprintf(stderr, "DEBUG: Jog = %d\n", cups.header.Jog);
- fprintf(stderr, "DEBUG: LeadingEdge = %d\n", cups.header.LeadingEdge);
- fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", cups.header.Margins[0],
- cups.header.Margins[1]);
- fprintf(stderr, "DEBUG: ManualFeed = %d\n", cups.header.ManualFeed);
- fprintf(stderr, "DEBUG: MediaPosition = %d\n", cups.header.MediaPosition);
- fprintf(stderr, "DEBUG: MediaWeight = %d\n", cups.header.MediaWeight);
- fprintf(stderr, "DEBUG: MirrorPrint = %d\n", cups.header.MirrorPrint);
- fprintf(stderr, "DEBUG: NegativePrint = %d\n", cups.header.NegativePrint);
- fprintf(stderr, "DEBUG: NumCopies = %d\n", cups.header.NumCopies);
- fprintf(stderr, "DEBUG: Orientation = %d\n", cups.header.Orientation);
- fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", cups.header.OutputFaceUp);
- fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", cups.header.PageSize[0],
- cups.header.PageSize[1]);
- fprintf(stderr, "DEBUG: Separations = %d\n", cups.header.Separations);
- fprintf(stderr, "DEBUG: TraySwitch = %d\n", cups.header.TraySwitch);
- fprintf(stderr, "DEBUG: Tumble = %d\n", cups.header.Tumble);
- fprintf(stderr, "DEBUG: cupsWidth = %d\n", cups.header.cupsWidth);
- fprintf(stderr, "DEBUG: cupsHeight = %d\n", cups.header.cupsHeight);
- fprintf(stderr, "DEBUG: cupsMediaType = %d\n", cups.header.cupsMediaType);
- fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", cups.header.cupsBitsPerColor);
- fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", cups.header.cupsBitsPerPixel);
- fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", cups.header.cupsBytesPerLine);
- fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", cups.header.cupsColorOrder);
- fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", cups.header.cupsColorSpace);
- fprintf(stderr, "DEBUG: cupsCompression = %d\n", cups.header.cupsCompression);
- fprintf(stderr, "DEBUG: cupsRowCount = %d\n", cups.header.cupsRowCount);
- fprintf(stderr, "DEBUG: cupsRowFeed = %d\n", cups.header.cupsRowFeed);
- fprintf(stderr, "DEBUG: cupsRowStep = %d\n", cups.header.cupsRowStep);
-
- /*
- * Setup printer driver variables...
- */
-
- stp_set_page_width(v, cups.header.PageSize[0]);
- stp_set_page_height(v, cups.header.PageSize[1]);
- stp_set_image_type(v, cups.header.cupsRowCount);
-
- switch (cups.header.cupsColorSpace)
{
- case CUPS_CSPACE_W :
- stp_set_output_type(v, OUTPUT_GRAY);
- break;
- case CUPS_CSPACE_K :
- stp_set_output_type(v, OUTPUT_MONOCHROME);
- break;
- case CUPS_CSPACE_RGB :
- stp_set_output_type(v, OUTPUT_COLOR);
- break;
- case CUPS_CSPACE_CMYK :
- stp_set_output_type(v, OUTPUT_RAW_CMYK);
- break;
- default :
- fprintf(stderr, "ERROR: Bad colorspace %d!",
- cups.header.cupsColorSpace);
- break;
- }
+ /*
+ * We don't know how many pages we're going to print, and
+ * we need to call stp_end_job at the completion of the job.
+ * Therefore, we need to keep v in scope after the termination
+ * of the loop to permit calling stp_end_job then. Therefore,
+ * we have to free the previous page's stp_vars_t at the start
+ * of the loop.
+ */
+ if (v)
+ stp_vars_destroy(v);
+
+ /*
+ * Setup printer driver variables...
+ */
+ v = initialize_page(&cups, default_settings);
+ stp_set_int_parameter(v, "PageNumber", cups.page);
+ cups.row = 0;
+ fprintf(stderr, "DEBUG: Gutenprint printing page %d\n", cups.page + 1);
+ fprintf(stderr, "PAGE: %d 1\n", cups.page + 1);
+ print_debug_block(v, &cups);
+ print_messages_as_errors = 1;
+ if (!stp_verify(v))
+ {
+ fprintf(stderr, "ERROR: Gutenprint: options failed to verify.\n");
+ fprintf(stderr, "ERROR: Gutenprint: Make sure that you are using ESP Ghostscript rather\n");
+ fprintf(stderr, "ERROR: Gutenprint: than GNU or AFPL Ghostscript with CUPS.\n");
+ fprintf(stderr, "ERROR: Gutenprint: If this is not the cause, set LogLevel to debug2 to identify the problem.\n");
+ goto cups_abort;
+ }
- if (cups.header.cupsRowStep >= stp_dither_algorithm_count())
- fprintf(stderr, "ERROR: Unable to set dither algorithm!\n");
- else
- stp_set_dither_algorithm(v,
- stp_dither_algorithm_name(cups.header.cupsRowStep));
-
- if (cups.header.MediaClass && strlen(cups.header.MediaClass) > 0)
- stp_set_media_source(v, cups.header.MediaClass);
- if (cups.header.MediaType && strlen(cups.header.MediaType) > 0)
- stp_set_media_type(v, cups.header.MediaType);
- if (cups.header.OutputType && strlen(cups.header.OutputType) > 0)
- stp_set_ink_type(v, cups.header.OutputType);
-
- fprintf(stderr, "DEBUG: PageSize = %dx%d\n", cups.header.PageSize[0],
- cups.header.PageSize[1]);
-
- if ((size = stp_get_papersize_by_size(cups.header.PageSize[1],
- cups.header.PageSize[0])) != NULL)
- stp_set_media_size(v, stp_papersize_get_name(size));
- else
- fprintf(stderr, "ERROR: Unable to get media size!\n");
-
- if (cups.header.cupsCompression >= num_res)
- fprintf(stderr, "ERROR: Unable to set printer resolution!\n");
- else
- stp_set_resolution(v, res[cups.header.cupsCompression].name);
-
- stp_set_app_gamma(v, 1.0);
- stp_set_brightness(v, stp_brightness);
- stp_set_contrast(v, stp_contrast);
- stp_set_cyan(v, stp_cyan);
- stp_set_magenta(v, stp_magenta);
- stp_set_yellow(v, stp_yellow);
- stp_set_saturation(v, stp_saturation);
- stp_set_density(v, stp_density);
- stp_set_gamma(v, stp_gamma);
- stp_merge_printvars(v, stp_printer_get_printvars(printer));
-
- fprintf(stderr, "DEBUG: stp_get_output_to(v) |%s|\n", stp_get_output_to(v));
- fprintf(stderr, "DEBUG: stp_get_driver(v) |%s|\n", stp_get_driver(v));
- fprintf(stderr, "DEBUG: stp_get_ppd_file(v) |%s|\n", stp_get_ppd_file(v));
- fprintf(stderr, "DEBUG: stp_get_resolution(v) |%s|\n", stp_get_resolution(v));
- fprintf(stderr, "DEBUG: stp_get_media_size(v) |%s|\n", stp_get_media_size(v));
- fprintf(stderr, "DEBUG: stp_get_media_type(v) |%s|\n", stp_get_media_type(v));
- fprintf(stderr, "DEBUG: stp_get_media_source(v) |%s|\n", stp_get_media_source(v));
- fprintf(stderr, "DEBUG: stp_get_ink_type(v) |%s|\n", stp_get_ink_type(v));
- fprintf(stderr, "DEBUG: stp_get_dither_algorithm(v) |%s|\n", stp_get_dither_algorithm(v));
- fprintf(stderr, "DEBUG: stp_get_output_type(v) |%d|\n", stp_get_output_type(v));
- fprintf(stderr, "DEBUG: stp_get_orientation(v) |%d|\n", stp_get_orientation(v));
- fprintf(stderr, "DEBUG: stp_get_left(v) |%d|\n", stp_get_left(v));
- fprintf(stderr, "DEBUG: stp_get_top(v) |%d|\n", stp_get_top(v));
- fprintf(stderr, "DEBUG: stp_get_image_type(v) |%d|\n", stp_get_image_type(v));
- fprintf(stderr, "DEBUG: stp_get_unit(v) |%d|\n", stp_get_unit(v));
- fprintf(stderr, "DEBUG: stp_get_page_width(v) |%d|\n", stp_get_page_width(v));
- fprintf(stderr, "DEBUG: stp_get_page_height(v) |%d|\n", stp_get_page_height(v));
- fprintf(stderr, "DEBUG: stp_get_input_color_model(v) |%d|\n", stp_get_input_color_model(v));
- fprintf(stderr, "DEBUG: stp_get_output_color_model(v) |%d|\n", stp_get_output_color_model(v));
- fprintf(stderr, "DEBUG: stp_get_brightness(v) |%.3f|\n", stp_get_brightness(v));
- fprintf(stderr, "DEBUG: stp_get_scaling(v) |%.3f|\n", stp_get_scaling(v));
- fprintf(stderr, "DEBUG: stp_get_gamma(v) |%.3f|\n", stp_get_gamma(v));
- fprintf(stderr, "DEBUG: stp_get_contrast(v) |%.3f|\n", stp_get_contrast(v));
- fprintf(stderr, "DEBUG: stp_get_cyan(v) |%.3f|\n", stp_get_cyan(v));
- fprintf(stderr, "DEBUG: stp_get_magenta(v) |%.3f|\n", stp_get_magenta(v));
- fprintf(stderr, "DEBUG: stp_get_yellow(v) |%.3f|\n", stp_get_yellow(v));
- fprintf(stderr, "DEBUG: stp_get_saturation(v) |%.3f|\n", stp_get_saturation(v));
- fprintf(stderr, "DEBUG: stp_get_density(v) |%.3f|\n", stp_get_density(v));
- fprintf(stderr, "DEBUG: stp_get_app_gamma(v) |%.3f|\n", stp_get_app_gamma(v));
-
- stp_set_page_number(v, cups.page);
-
- (*stp_printer_get_printfuncs(printer)->media_size)
- (printer, v, &(cups.width), &(cups.height));
- (*stp_printer_get_printfuncs(printer)->imageable_area)
- (printer, v, &(cups.left), &(cups.right), &(cups.bottom), &(cups.top));
- fprintf(stderr, "DEBUG: GIMP-PRINT %d %d %d %d %d %d\n",
- cups.width, cups.left, cups.right, cups.height, cups.top, cups.bottom);
- cups.right = cups.width - cups.right;
- cups.width = cups.width - cups.left - cups.right;
- cups.width = cups.header.HWResolution[0] * cups.width / 72;
- cups.left = cups.header.HWResolution[0] * cups.left / 72;
- cups.right = cups.header.HWResolution[0] * cups.right / 72;
-
- cups.top = cups.height - cups.top;
- cups.height = cups.height - cups.top - cups.bottom;
- cups.height = cups.header.HWResolution[1] * cups.height / 72;
- cups.top = cups.header.HWResolution[1] * cups.top / 72;
- cups.bottom = cups.header.HWResolution[1] * cups.bottom / 72;
- fprintf(stderr, "DEBUG: GIMP-PRINT %d %d %d %d %d %d\n",
- cups.width, cups.left, cups.right, cups.height, cups.top, cups.bottom);
+ if (!initialized_job)
+ {
+ stp_start_job(v, &theImage);
+ initialized_job = 1;
+ }
- /*
- * Print the page...
- */
+ if (!stp_print(v, &theImage))
+ {
+ fprintf(stderr, "ERROR: Gutenprint failed to print, set LogLevel to debug2 to identify why\n");
+ goto cups_abort;
+ }
+ print_messages_as_errors = 0;
- if (stp_printer_get_printfuncs(printer)->verify(printer, v))
- {
- signal(SIGTERM, cancel_job);
- if (cups.page == 0)
- stp_printer_get_printfuncs(printer)->start_job(printer, &theImage, v);
- stp_printer_get_printfuncs(printer)->print(printer, &theImage, v);
fflush(stdout);
- }
- else
- fputs("ERROR: Invalid printer settings!\n", stderr);
- /*
- * Purge any remaining bitmap data...
- */
-
- if (cups.row < cups.header.cupsHeight)
+ /*
+ * Purge any remaining bitmap data...
+ */
+ if (cups.row < cups.header.cupsHeight)
+ purge_excess_data(&cups);
+ cups.page ++;
+ }
+ if (v)
{
- if ((buffer = xmalloc(cups.header.cupsBytesPerLine)) == NULL)
- break;
-
- while (cups.row < cups.header.cupsHeight)
- {
- cupsRasterReadPixels(cups.ras, (unsigned char *)buffer,
- cups.header.cupsBytesPerLine);
- cups.row ++;
- }
+ fprintf(stderr, "DEBUG: Gutenprint ending job\n");
+ stp_end_job(v, &theImage);
+ stp_vars_destroy(v);
}
- cups.page ++;
- }
-
- if (cups.page > 0)
- stp_printer_get_printfuncs(printer)->end_job(printer, &theImage, v);
-
- stp_free_vars(v);
-
- /*
- * Close the raster stream...
- */
-
cupsRasterClose(cups.ras);
+ clk = times(&tms);
+ (void) gettimeofday(&t2, &tz);
+ clocks_per_sec = sysconf(_SC_CLK_TCK);
+ fprintf(stderr, "DEBUG: Gutenprint printed total %.0f bytes\n",
+ total_bytes_printed);
+ fprintf(stderr, "DEBUG: Gutenprint used %.3f seconds user, %.3f seconds system, %.3f seconds elapsed\n",
+ (double) tms.tms_utime / clocks_per_sec,
+ (double) tms.tms_stime / clocks_per_sec,
+ (double) (t2.tv_sec - t1.tv_sec) +
+ ((double) (t2.tv_usec - t1.tv_usec)) / 1000000.0);
+ fputs("INFO: Gutenprint Ready to print.\n", stderr);
if (fd != 0)
close(fd);
-
- /*
- * If no pages were printed, send an error message...
- */
-
- if (cups.page == 0)
- fputs("ERROR: No pages found!\n", stderr);
- else
- fputs("INFO: Ready to print.\n", stderr);
-
- return (cups.page == 0);
+ return 0;
+
+cups_abort:
+ clk = times(&tms);
+ (void) gettimeofday(&t2, &tz);
+ clocks_per_sec = sysconf(_SC_CLK_TCK);
+ fprintf(stderr, "DEBUG: Gutenprint printed total %.0f bytes\n",
+ total_bytes_printed);
+ fprintf(stderr, "DEBUG: Gutenprint used %.3f seconds user, %.3f seconds system, %.3f seconds elapsed\n",
+ (double) tms.tms_utime / clocks_per_sec,
+ (double) tms.tms_stime / clocks_per_sec,
+ (double) (t2.tv_sec - t1.tv_sec) +
+ ((double) (t2.tv_usec - t1.tv_usec)) / 1000000.0);
+ fputs("ERROR: Gutenprint No pages found!\n", stderr);
+ fputs("ERROR: Gutenprint Invalid printer settings!\n", stderr);
+ stp_end_job(v, &theImage);
+ stp_vars_destroy(v);
+ cupsRasterClose(cups.ras);
+ if (fd != 0)
+ close(fd);
+ return 1;
}
@@ -588,9 +852,32 @@ static void
cups_writefunc(void *file, const char *buf, size_t bytes)
{
FILE *prn = (FILE *)file;
+ total_bytes_printed += bytes;
fwrite(buf, 1, bytes, prn);
}
+static void
+cups_errfunc(void *file, const char *buf, size_t bytes)
+{
+ size_t next_nl = 0;
+ size_t where = 0;
+ FILE *prn = (FILE *)file;
+ while (where < bytes)
+ {
+ if (print_messages_as_errors)
+ fputs("ERROR: Gutenprint: ", prn);
+ else
+ fputs("DEBUG: Gutenprint internal: ", prn);
+ while (next_nl < bytes)
+ {
+ if (buf[next_nl++] == '\n')
+ break;
+ }
+ fwrite(buf + where, 1, next_nl - where, prn);
+ where = next_nl;
+ }
+}
+
/*
* 'cancel_job()' - Cancel the current job...
@@ -600,41 +887,9 @@ void
cancel_job(int sig) /* I - Signal */
{
(void)sig;
-
- Image_status = STP_IMAGE_ABORT;
-}
-
-
-/*
- * 'Image_bpp()' - Return the bytes-per-pixel of an image.
- */
-
-static int /* O - Bytes per pixel */
-Image_bpp(stp_image_t *image) /* I - Image */
-{
- cups_image_t *cups; /* CUPS image */
-
-
- if ((cups = (cups_image_t *)(image->rep)) == NULL)
- return (0);
-
- /*
- * For now, we only support RGB and grayscale input from the
- * raster filters.
- */
-
- switch (cups->header.cupsColorSpace)
- {
- default :
- return (1);
- case CUPS_CSPACE_RGB :
- return (3);
- case CUPS_CSPACE_CMYK :
- return (4);
- }
+ Image_status = STP_IMAGE_STATUS_ABORT;
}
-
/*
* 'Image_get_appname()' - Get the application we are running.
*/
@@ -644,7 +899,7 @@ Image_get_appname(stp_image_t *image) /* I - Image */
{
(void)image;
- return ("CUPS 1.1.x driver based on GIMP-print");
+ return ("CUPS 1.1.x driver based on Gutenprint");
}
@@ -670,50 +925,68 @@ throwaway_data(int amount, cups_image_t *cups)
stp_image_status_t
Image_get_row(stp_image_t *image, /* I - Image */
unsigned char *data, /* O - Row */
+ size_t byte_limit, /* I - how many bytes in data */
int row) /* I - Row number (unused) */
{
cups_image_t *cups; /* CUPS image */
int i; /* Looping var */
int bytes_per_line;
int margin;
- unsigned char *orig = data;
- static int warned = 0;
-
+ stp_image_status_t tmp_image_status = Image_status;
+ unsigned char *orig = data; /* Temporary pointer */
+ static int warned = 0; /* Error warning printed? */
+ int new_percent;
if ((cups = (cups_image_t *)(image->rep)) == NULL)
- return STP_IMAGE_ABORT;
- bytes_per_line = cups->width * cups->header.cupsBitsPerPixel / CHAR_BIT;
+ {
+ fprintf(stderr, "ERROR: Gutenprint image is null! Please report this bug to gimp-print-devel@lists.sourceforge.net\n");
+ return STP_IMAGE_STATUS_ABORT;
+ }
+ bytes_per_line =
+ ((cups->adjusted_width * cups->header.cupsBitsPerPixel) + CHAR_BIT - 1) /
+ CHAR_BIT;
margin = cups->header.cupsBytesPerLine - bytes_per_line;
if (cups->row < cups->header.cupsHeight)
{
- fprintf(stderr, "DEBUG: GIMP-PRINT reading %d %d\n",
+ fprintf(stderr, "DEBUG2: Gutenprint reading %d %d\n",
bytes_per_line, cups->row);
- cupsRasterReadPixels(cups->ras, data, bytes_per_line);
- cups->row ++;
- fprintf(stderr, "DEBUG: GIMP-PRINT tossing right %d\n", margin);
- if (margin)
- throwaway_data(margin, cups);
-
- /*
- * Invert black data for monochrome output...
- */
-
- if (cups->header.cupsColorSpace == CUPS_CSPACE_K)
- for (i = bytes_per_line; i > 0; i --, data ++)
- *data = ((1 << CHAR_BIT) - 1) - *data;
+ while (cups->row <= row && cups->row < cups->header.cupsHeight)
+ {
+ cupsRasterReadPixels(cups->ras, data, bytes_per_line);
+ cups->row ++;
+ if (margin > 0)
+ {
+ fprintf(stderr, "DEBUG2: Gutenprint tossing right %d\n", margin);
+ throwaway_data(margin, cups);
+ }
+ }
}
else
{
- if (cups->header.cupsColorSpace == CUPS_CSPACE_CMYK)
- memset(data, 0, bytes_per_line);
- else
- memset(data, ((1 << CHAR_BIT) - 1), bytes_per_line);
+ switch (cups->header.cupsColorSpace)
+ {
+ case CUPS_CSPACE_K:
+ case CUPS_CSPACE_CMYK:
+ case CUPS_CSPACE_KCMY:
+ case CUPS_CSPACE_CMY:
+ memset(data, 0, bytes_per_line);
+ break;
+ case CUPS_CSPACE_RGB:
+ case CUPS_CSPACE_W:
+ memset(data, ((1 << CHAR_BIT) - 1), bytes_per_line);
+ break;
+ default:
+ fprintf(stderr, "ERROR: Gutenprint Unknown colorspace %d!\n",
+ cups->header.cupsColorSpace);
+ return STP_IMAGE_STATUS_ABORT;
+ }
}
/*
* This exists to print non-ADSC input which has messed up the job
- * input, such as that generated by psnup.
+ * input, such as that generated by psnup. The output is barely
+ * legible, but it's better than the garbage output otherwise.
*/
data = orig;
if (cups->header.cupsBitsPerPixel == 1)
@@ -721,11 +994,11 @@ Image_get_row(stp_image_t *image, /* I - Image */
if (warned == 0)
{
fprintf(stderr,
- "WARNING: GIMP-PRINT detected broken job options. "
+ "WARNING: Gutenprint detected broken job options. "
"Output quality is degraded. Are you using psnup or non-ADSC PostScript?\n");
warned = 1;
}
- for (i = cups->width - 1; i >= 0; i--)
+ for (i = cups->adjusted_width - 1; i >= 0; i--)
{
if ( (data[i/8] >> (7 - i%8)) &0x1)
data[i]=255;
@@ -734,7 +1007,17 @@ Image_get_row(stp_image_t *image, /* I - Image */
}
}
- return Image_status;
+ new_percent = (int) (100.0 * cups->row / cups->header.cupsHeight);
+ if (new_percent > cups->last_percent)
+ {
+ fprintf(stderr, "INFO: Gutenprint Printing page %d, %d%%\n",
+ cups->page + 1, new_percent);
+ cups->last_percent = new_percent;
+ }
+
+ if (tmp_image_status != STP_IMAGE_STATUS_OK)
+ fprintf(stderr, "DEBUG: Gutenprint image status %d\n", tmp_image_status);
+ return tmp_image_status;
}
@@ -751,8 +1034,8 @@ Image_height(stp_image_t *image) /* I - Image */
if ((cups = (cups_image_t *)(image->rep)) == NULL)
return (0);
- fprintf(stderr, "DEBUG: GIMP-PRINT: Image_height %d\n", cups->height);
- return (cups->height);
+ fprintf(stderr, "DEBUG: Gutenprint: Image_height %d\n", cups->adjusted_height);
+ return (cups->adjusted_height);
}
@@ -763,55 +1046,22 @@ Image_height(stp_image_t *image) /* I - Image */
static void
Image_init(stp_image_t *image) /* I - Image */
{
- (void)image;
-}
-
-
-/*
- * 'Image_note_progress()' - Notify the user of our progress.
- */
-
-void
-Image_note_progress(stp_image_t *image, /* I - Image */
- double current, /* I - Current progress */
- double total) /* I - Maximum progress */
-{
cups_image_t *cups; /* CUPS image */
-
if ((cups = (cups_image_t *)(image->rep)) == NULL)
return;
+ cups->last_percent = 0;
- fprintf(stderr, "INFO: Printing page %d, %.0f%%\n",
- cups->page +1, 100.0 * current / total);
- /* cups->page + 1 because users expect 1-based counting */
-}
-
-
-/*
- * 'Image_progress_conclude()' - Close the progress display.
- */
-
-static void
-Image_progress_conclude(stp_image_t *image) /* I - Image */
-{
- cups_image_t *cups; /* CUPS image */
-
-
- if ((cups = (cups_image_t *)(image->rep)) == NULL)
- return;
-
- fprintf(stderr, "INFO: Finished page %d...\n", cups->page + 1);
+ fprintf(stderr, "INFO: Starting page %d...\n", cups->page + 1);
/* cups->page + 1 because users expect 1-based counting */
}
-
/*
- * 'Image_progress_init()' - Initialize progress display.
+ * 'Image_progress_conclude()' - Close the progress display.
*/
static void
-Image_progress_init(stp_image_t *image)/* I - Image */
+Image_conclude(stp_image_t *image) /* I - Image */
{
cups_image_t *cups; /* CUPS image */
@@ -819,44 +1069,9 @@ Image_progress_init(stp_image_t *image)/* I - Image */
if ((cups = (cups_image_t *)(image->rep)) == NULL)
return;
- fprintf(stderr, "INFO: Starting page %d...\n", cups->page + 1);
- /* cups->page + 1 because users expect 1-based counting */
+ fprintf(stderr, "INFO: Gutenprint Finished page %d...\n", cups->page + 1);
}
-
-/*
- * 'Image_rotate_180()' - Rotate the image 180 degrees (unsupported).
- */
-
-static void
-Image_rotate_180(stp_image_t *image) /* I - Image */
-{
- (void)image;
-}
-
-
-/*
- * 'Image_rotate_ccw()' - Rotate the image counter-clockwise (unsupported).
- */
-
-static void
-Image_rotate_ccw(stp_image_t *image) /* I - Image */
-{
- (void)image;
-}
-
-
-/*
- * 'Image_rotate_cw()' - Rotate the image clockwise (unsupported).
- */
-
-static void
-Image_rotate_cw(stp_image_t *image) /* I - Image */
-{
- (void)image;
-}
-
-
/*
* 'Image_width()' - Return the width of an image.
*/
@@ -870,11 +1085,11 @@ Image_width(stp_image_t *image) /* I - Image */
if ((cups = (cups_image_t *)(image->rep)) == NULL)
return (0);
- fprintf(stderr, "DEBUG: GIMP-PRINT: Image_width %d\n", cups->width);
- return (cups->width);
+ fprintf(stderr, "DEBUG: Gutenprint: Image_width %d\n", cups->adjusted_width);
+ return (cups->adjusted_width);
}
/*
- * End of "$Id: rastertoprinter.c,v 1.19.4.15 2004/03/26 03:29:39 rlk Exp $".
+ * End of "$Id: rastertoprinter.c,v 1.96 2005/04/23 00:26:07 rlk Exp $".
*/