+++ /dev/null
-/*
- * "$Id$"
- *
- * Advanced EPSON ESC/P raster driver for CUPS.
- *
- * Copyright 2007-2010 by Apple Inc.
- * Copyright 1993-2005 by Easy Software Products.
- *
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * Setup() - Prepare the printer for graphics output.
- * StartPage() - Start a page of graphics.
- * EndPage() - Finish a page of graphics.
- * Shutdown() - Shutdown a printer.
- * CancelJob() - Cancel the current job...
- * CompressData() - Compress a line of graphics.
- * OutputBand() - Output a band of graphics.
- * ProcessLine() - Read graphics from the page stream and output
- * as needed.
- * main() - Main entry and processing of driver.
- */
-
-/*
- * Include necessary headers...
- */
-
-#include "driver.h"
-#include <cups/language-private.h>
-#include <cups/string-private.h>
-#include "data/escp.h"
-#include <signal.h>
-
-
-/*
- * Softweave data...
- */
-
-typedef struct cups_weave_str
-{
- struct cups_weave_str *prev, /* Previous band */
- *next; /* Next band */
- int x, y, /* Column/Line on the page */
- plane, /* Color plane */
- dirty, /* Is this buffer dirty? */
- row, /* Row in the buffer */
- count; /* Max rows this pass */
- unsigned char *buffer; /* Data buffer */
-} cups_weave_t;
-
-
-/*
- * Globals...
- */
-
-cups_rgb_t *RGB; /* RGB color separation data */
-cups_cmyk_t *CMYK; /* CMYK color separation data */
-unsigned char *PixelBuffer, /* Pixel buffer */
- *CMYKBuffer, /* CMYK buffer */
- *OutputBuffers[7], /* Output buffers */
- *DotBuffers[7], /* Dot buffers */
- *CompBuffer; /* Compression buffer */
-short *InputBuffer; /* Color separation buffer */
-cups_weave_t *DotAvailList, /* Available buffers */
- *DotUsedList, /* Used buffers */
- *DotBands[128][7]; /* Buffers in use */
-int DotBufferSize, /* Size of dot buffers */
- DotRowMax, /* Maximum row number in buffer */
- DotColStep, /* Step for each output column */
- DotRowStep, /* Step for each output line */
- DotRowFeed, /* Amount to feed for interleave */
- DotRowCount, /* Number of rows to output */
- DotRowOffset[7], /* Offset for each color on print head */
- DotRowCurrent, /* Current row */
- DotSize; /* Dot size (Pro 5000 only) */
-int PrinterPlanes, /* # of color planes */
- BitPlanes, /* # of bit planes per color */
- PrinterTop, /* Top of page */
- PrinterLength; /* Length of page */
-cups_lut_t *DitherLuts[7]; /* Lookup tables for dithering */
-cups_dither_t *DitherStates[7]; /* Dither state tables */
-int OutputFeed; /* Number of lines to skip */
-int Canceled; /* Is the job canceled? */
-
-
-/*
- * Prototypes...
- */
-
-void Setup(ppd_file_t *);
-void StartPage(ppd_file_t *, cups_page_header2_t *);
-void EndPage(ppd_file_t *, cups_page_header2_t *);
-void Shutdown(ppd_file_t *);
-
-void AddBand(cups_weave_t *band);
-void CancelJob(int sig);
-void CompressData(ppd_file_t *, const unsigned char *, const int,
- int, int, const int, const int, const int,
- const int);
-void OutputBand(ppd_file_t *, cups_page_header2_t *,
- cups_weave_t *band);
-void ProcessLine(ppd_file_t *, cups_raster_t *,
- cups_page_header2_t *, const int y);
-
-
-/*
- * 'Setup()' - Prepare a printer for graphics output.
- */
-
-void
-Setup(ppd_file_t *ppd) /* I - PPD file */
-{
- /*
- * Some EPSON printers need an additional command issued at the
- * beginning of each job to exit from USB "packet" mode...
- */
-
- if (ppd->model_number & ESCP_USB)
- cupsWritePrintData("\000\000\000\033\001@EJL 1284.4\n@EJL \n\033@", 29);
-}
-
-
-/*
- * 'StartPage()' - Start a page of graphics.
- */
-
-void
-StartPage(ppd_file_t *ppd, /* I - PPD file */
- cups_page_header2_t *header) /* I - Page header */
-{
- int i, y; /* Looping vars */
- int subrow, /* Current subrow */
- modrow, /* Subrow modulus */
- plane; /* Current color plane */
- unsigned char *ptr; /* Pointer into dot buffer */
- int bands; /* Number of bands to allocate */
- int units; /* Units for resolution */
- cups_weave_t *band; /* Current band */
- const char *colormodel; /* Color model string */
- char resolution[PPD_MAX_NAME],
- /* Resolution string */
- spec[PPD_MAX_NAME]; /* PPD attribute name */
- ppd_attr_t *attr; /* Attribute from PPD file */
- const float default_lut[2] = /* Default dithering lookup table */
- {
- 0.0,
- 1.0
- };
-
-
- fprintf(stderr, "DEBUG: StartPage...\n");
- fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass);
- fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor);
- fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType);
- fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType);
-
- fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance);
- fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia);
- fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate);
- fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia);
- fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex);
- fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0],
- header->HWResolution[1]);
- fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n",
- header->ImagingBoundingBox[0], header->ImagingBoundingBox[1],
- header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]);
- fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet);
- fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog);
- fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge);
- fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0],
- header->Margins[1]);
- fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed);
- fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition);
- fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight);
- fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint);
- fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint);
- fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies);
- fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation);
- fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp);
- fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0],
- header->PageSize[1]);
- fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations);
- fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch);
- fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble);
- fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth);
- fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight);
- fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType);
- fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header->cupsBitsPerColor);
- fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header->cupsBitsPerPixel);
- fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header->cupsBytesPerLine);
- fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header->cupsColorOrder);
- fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header->cupsColorSpace);
- fprintf(stderr, "DEBUG: cupsCompression = %d\n", header->cupsCompression);
- fprintf(stderr, "DEBUG: cupsRowCount = %d\n", header->cupsRowCount);
- fprintf(stderr, "DEBUG: cupsRowFeed = %d\n", header->cupsRowFeed);
- fprintf(stderr, "DEBUG: cupsRowStep = %d\n", header->cupsRowStep);
-
- /*
- * Figure out the color model and spec strings...
- */
-
- switch (header->cupsColorSpace)
- {
- case CUPS_CSPACE_K :
- colormodel = "Black";
- break;
- case CUPS_CSPACE_W :
- colormodel = "Gray";
- break;
- default :
- case CUPS_CSPACE_RGB :
- colormodel = "RGB";
- break;
- case CUPS_CSPACE_CMYK :
- colormodel = "CMYK";
- break;
- }
-
- if (header->HWResolution[0] != header->HWResolution[1])
- snprintf(resolution, sizeof(resolution), "%dx%ddpi",
- header->HWResolution[0], header->HWResolution[1]);
- else
- snprintf(resolution, sizeof(resolution), "%ddpi",
- header->HWResolution[0]);
-
- if (!header->MediaType[0])
- strcpy(header->MediaType, "Plain");
-
- /*
- * Load the appropriate color profiles...
- */
-
- RGB = NULL;
- CMYK = NULL;
-
- fputs("DEBUG: Attempting to load color profiles using the following values:\n", stderr);
- fprintf(stderr, "DEBUG: ColorModel = %s\n", colormodel);
- fprintf(stderr, "DEBUG: MediaType = %s\n", header->MediaType);
- fprintf(stderr, "DEBUG: Resolution = %s\n", resolution);
-
- if (header->cupsColorSpace == CUPS_CSPACE_RGB ||
- header->cupsColorSpace == CUPS_CSPACE_W)
- RGB = cupsRGBLoad(ppd, colormodel, header->MediaType, resolution);
- else
- RGB = NULL;
-
- CMYK = cupsCMYKLoad(ppd, colormodel, header->MediaType, resolution);
-
- if (RGB)
- fputs("DEBUG: Loaded RGB separation from PPD.\n", stderr);
-
- if (CMYK)
- fputs("DEBUG: Loaded CMYK separation from PPD.\n", stderr);
- else
- {
- fputs("DEBUG: Loading default CMYK separation.\n", stderr);
- CMYK = cupsCMYKNew(4);
- }
-
- PrinterPlanes = CMYK->num_channels;
-
- fprintf(stderr, "DEBUG: PrinterPlanes = %d\n", PrinterPlanes);
-
- /*
- * Get the dithering parameters...
- */
-
- switch (PrinterPlanes)
- {
- case 1 : /* K */
- DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Black");
- break;
-
- case 2 : /* Kk */
- DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Black");
- DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "LightBlack");
- break;
-
- case 3 : /* CMY */
- DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Cyan");
- DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Magenta");
- DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Yellow");
- break;
-
- case 4 : /* CMYK */
- DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Cyan");
- DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Magenta");
- DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Yellow");
- DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Black");
- break;
-
- case 6 : /* CcMmYK */
- DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Cyan");
- DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "LightCyan");
- DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Magenta");
- DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "LightMagenta");
- DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Yellow");
- DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Black");
- break;
-
- case 7 : /* CcMmYKk */
- DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Cyan");
- DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "LightCyan");
- DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Magenta");
- DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "LightMagenta");
- DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Yellow");
- DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "Black");
- DitherLuts[6] = cupsLutLoad(ppd, colormodel, header->MediaType,
- resolution, "LightBlack");
- break;
- }
-
- for (plane = 0; plane < PrinterPlanes; plane ++)
- {
- DitherStates[plane] = cupsDitherNew(header->cupsWidth);
-
- if (!DitherLuts[plane])
- DitherLuts[plane] = cupsLutNew(2, default_lut);
- }
-
- if (DitherLuts[0][4095].pixel > 1)
- BitPlanes = 2;
- else
- BitPlanes = 1;
-
- /*
- * Initialize the printer...
- */
-
- printf("\033@");
-
- if (ppd->model_number & ESCP_REMOTE)
- {
- /*
- * Go into remote mode...
- */
-
- cupsWritePrintData("\033(R\010\000\000REMOTE1", 13);
-
- /*
- * Disable status reporting...
- */
-
- cupsWritePrintData("ST\002\000\000\000", 6);
-
- /*
- * Enable borderless printing...
- */
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPFP", NULL)) != NULL && attr->value)
- {
- /*
- * Set horizontal offset...
- */
-
- i = atoi(attr->value);
-
- cupsWritePrintData("FP\003\000\000", 5);
- putchar(i & 255);
- putchar(i >> 8);
- }
-
- /*
- * Set media type...
- */
-
- if (header->cupsMediaType)
- {
- sprintf(spec, "%d", header->cupsMediaType);
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPSN0", spec)) != NULL && attr->value)
- {
- /*
- * Set feed sequence...
- */
-
- cupsWritePrintData("SN\003\000\000\000", 6);
- putchar(atoi(attr->value));
- }
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPSN1", spec)) != NULL && attr->value)
- {
- /*
- * Set platten gap...
- */
-
- cupsWritePrintData("SN\003\000\000\001", 6);
- putchar(atoi(attr->value));
- }
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPSN2", spec)) != NULL && attr->value)
- {
- /*
- * Paper feeding/ejecting sequence...
- */
-
- cupsWritePrintData("SN\003\000\000\002", 6);
- putchar(atoi(attr->value));
- }
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPSN6", spec)) != NULL && attr->value)
- {
- /*
- * Eject delay...
- */
-
- cupsWritePrintData("SN\003\000\000\006", 6);
- putchar(atoi(attr->value));
- }
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPMT", spec)) != NULL && attr->value)
- {
- /*
- * Set media type.
- */
-
- cupsWritePrintData("MT\003\000\000\000", 6);
- putchar(atoi(attr->value));
- }
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPPH", spec)) != NULL && attr->value)
- {
- /*
- * Set paper thickness.
- */
-
- cupsWritePrintData("PH\002\000\000", 5);
- putchar(atoi(attr->value));
- }
- }
-
- sprintf(spec, "%d", header->MediaPosition);
-
- if (header->MediaPosition)
- {
- if ((attr = ppdFindAttr(ppd, "cupsESCPPC", spec)) != NULL && attr->value)
- {
- /*
- * Paper check.
- */
-
- cupsWritePrintData("PC\002\000\000", 5);
- putchar(atoi(attr->value));
- }
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPPP", spec)) != NULL && attr->value)
- {
- /*
- * Paper path.
- */
-
- int a, b;
-
- a = b = 0;
- sscanf(attr->value, "%d%d", &a, &b);
-
- cupsWritePrintData("PP\003\000\000", 5);
- putchar(a);
- putchar(b);
- }
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPEX", spec)) != NULL && attr->value)
- {
- /*
- * Set media position.
- */
-
- cupsWritePrintData("EX\006\000\000\000\000\000\005", 9);
- putchar(atoi(attr->value));
- }
- }
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPMS", spec)) != NULL && attr->value)
- {
- /*
- * Set media size...
- */
-
- cupsWritePrintData("MS\010\000\000", 5);
- putchar(atoi(attr->value));
-
- switch (header->PageSize[1])
- {
- case 1191 : /* A3 */
- putchar(0x01);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- break;
- case 1032 : /* B4 */
- putchar(0x02);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- break;
- case 842 : /* A4 */
- putchar(0x03);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- break;
- case 595 : /* A4.Transverse */
- putchar(0x03);
- putchar(0x01);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- break;
- case 729 : /* B5 */
- putchar(0x04);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- break;
- case 516 : /* B5.Transverse */
- putchar(0x04);
- putchar(0x01);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- break;
- case 1369 : /* Super A3/B */
- putchar(0x20);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- break;
- case 792 : /* Letter */
- putchar(0x08);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- break;
- case 612 : /* Letter.Transverse */
- putchar(0x08);
- putchar(0x01);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- break;
- case 1004 : /* Legal */
- putchar(0x0a);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- break;
- case 1224 : /* Tabloid */
- putchar(0x2d);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- putchar(0x00);
- break;
- default : /* Custom size */
- putchar(0xff);
- putchar(0xff);
- i = 360 * header->PageSize[0] / 72;
- putchar(i);
- putchar(i >> 8);
- i = 360 * header->PageSize[1] / 72;
- putchar(i);
- putchar(i >> 8);
- break;
- }
- }
-
- sprintf(spec, "%d", header->CutMedia);
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPAC", spec)) != NULL && attr->value)
- {
- /*
- * Enable/disable cutter.
- */
-
- cupsWritePrintData("AC\002\000\000", 5);
- putchar(atoi(attr->value));
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPSN80", header->MediaType)) != NULL && attr->value)
- {
- /*
- * Cutting method...
- */
-
- cupsWritePrintData("SN\003\000\000\200", 6);
- putchar(atoi(attr->value));
- }
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPSN81", header->MediaType)) != NULL && attr->value)
- {
- /*
- * Cutting pressure...
- */
-
- cupsWritePrintData("SN\003\000\000\201", 6);
- putchar(atoi(attr->value));
- }
- }
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPCO", spec)) != NULL && attr->value)
- {
- /*
- * Enable/disable cutter.
- */
-
- cupsWritePrintData("CO\010\000\000\000", 6);
- putchar(atoi(attr->value));
- cupsWritePrintData("\000\000\000\000\000", 5);
- }
-
- /*
- * Exit remote mode...
- */
-
- cupsWritePrintData("\033\000\000\000", 4);
- }
-
- /*
- * Enter graphics mode...
- */
-
- cupsWritePrintData("\033(G\001\000\001", 6);
-
- /*
- * Set the line feed increment...
- */
-
- /* TODO: get this from the PPD file... */
- for (units = 1440; units < header->HWResolution[0]; units *= 2);
-
- if (ppd->model_number & ESCP_EXT_UNITS)
- {
- cupsWritePrintData("\033(U\005\000", 5);
- putchar(units / header->HWResolution[1]);
- putchar(units / header->HWResolution[1]);
- putchar(units / header->HWResolution[0]);
- putchar(units);
- putchar(units >> 8);
- }
- else
- {
- cupsWritePrintData("\033(U\001\000", 5);
- putchar(3600 / header->HWResolution[1]);
- }
-
- /*
- * Set the page length...
- */
-
- PrinterLength = header->PageSize[1] * header->HWResolution[1] / 72;
-
- if (ppd->model_number & ESCP_PAGE_SIZE)
- {
- /*
- * Set page size (expands bottom margin)...
- */
-
- cupsWritePrintData("\033(S\010\000", 5);
-
- i = header->PageSize[0] * header->HWResolution[1] / 72;
- putchar(i);
- putchar(i >> 8);
- putchar(i >> 16);
- putchar(i >> 24);
-
- i = header->PageSize[1] * header->HWResolution[1] / 72;
- putchar(i);
- putchar(i >> 8);
- putchar(i >> 16);
- putchar(i >> 24);
- }
- else
- {
- cupsWritePrintData("\033(C\002\000", 5);
- putchar(PrinterLength & 255);
- putchar(PrinterLength >> 8);
- }
-
- /*
- * Set the top and bottom margins...
- */
-
- PrinterTop = (int)((ppd->sizes[1].length - ppd->sizes[1].top) *
- header->HWResolution[1] / 72.0);
-
- if (ppd->model_number & ESCP_EXT_MARGINS)
- {
- cupsWritePrintData("\033(c\010\000", 5);
-
- putchar(PrinterTop);
- putchar(PrinterTop >> 8);
- putchar(PrinterTop >> 16);
- putchar(PrinterTop >> 24);
-
- putchar(PrinterLength);
- putchar(PrinterLength >> 8);
- putchar(PrinterLength >> 16);
- putchar(PrinterLength >> 24);
- }
- else
- {
- cupsWritePrintData("\033(c\004\000", 5);
-
- putchar(PrinterTop & 255);
- putchar(PrinterTop >> 8);
-
- putchar(PrinterLength & 255);
- putchar(PrinterLength >> 8);
- }
-
- /*
- * Set the top position...
- */
-
- cupsWritePrintData("\033(V\002\000\000\000", 7);
-
- /*
- * Enable unidirectional printing depending on the mode...
- */
-
- if ((attr = cupsFindAttr(ppd, "cupsESCPDirection", colormodel,
- header->MediaType, resolution, spec,
- sizeof(spec))) != NULL)
- printf("\033U%c", atoi(attr->value));
-
- /*
- * Enable/disable microweaving as needed...
- */
-
- if ((attr = cupsFindAttr(ppd, "cupsESCPMicroWeave", colormodel,
- header->MediaType, resolution, spec,
- sizeof(spec))) != NULL)
- printf("\033(i\001%c%c", 0, atoi(attr->value));
-
- /*
- * Set the dot size and print speed as needed...
- */
-
- if ((attr = cupsFindAttr(ppd, "cupsESCPDotSize", colormodel,
- header->MediaType, resolution, spec,
- sizeof(spec))) != NULL)
- printf("\033(e\002%c%c%c", 0, 0, atoi(attr->value));
-
- if (ppd->model_number & ESCP_ESCK)
- {
- /*
- * Set the print mode...
- */
-
- if (PrinterPlanes == 1)
- {
- /*
- * Fast black printing.
- */
-
- cupsWritePrintData("\033(K\002\000\000\001", 7);
- }
- else
- {
- /*
- * Color printing.
- */
-
- cupsWritePrintData("\033(K\002\000\000\002", 7);
- }
- }
-
- /*
- * Get softweave settings from header...
- */
-
- if (header->cupsRowCount <= 1)
- {
- DotRowCount = 1;
- DotColStep = 1;
- DotRowStep = 1;
- DotRowFeed = 1;
- }
- else
- {
- DotRowCount = header->cupsRowCount;
- DotRowFeed = header->cupsRowFeed;
- DotRowStep = header->cupsRowStep % 100;
- DotColStep = header->cupsRowStep / 100;
-
- if (DotColStep == 0)
- DotColStep ++;
- }
-
- /*
- * Setup softweave parameters...
- */
-
- DotRowCurrent = 0;
- DotRowMax = DotRowCount * DotRowStep;
- DotBufferSize = (header->cupsWidth / DotColStep * BitPlanes + 7) / 8;
-
- fprintf(stderr, "DEBUG: DotBufferSize = %d\n", DotBufferSize);
- fprintf(stderr, "DEBUG: DotColStep = %d\n", DotColStep);
- fprintf(stderr, "DEBUG: DotRowMax = %d\n", DotRowMax);
- fprintf(stderr, "DEBUG: DotRowStep = %d\n", DotRowStep);
- fprintf(stderr, "DEBUG: DotRowFeed = %d\n", DotRowFeed);
- fprintf(stderr, "DEBUG: DotRowCount = %d\n", DotRowCount);
-
- DotAvailList = NULL;
- DotUsedList = NULL;
- DotBuffers[0] = NULL;
-
- fprintf(stderr, "DEBUG: model_number = %x\n", ppd->model_number);
-
- if (DotRowMax > 1)
- {
- /*
- * Compute offsets for the color jets on the print head...
- */
-
- bands = DotRowStep * DotColStep * PrinterPlanes * 4;
-
- memset(DotRowOffset, 0, sizeof(DotRowOffset));
-
- if (PrinterPlanes == 1)
- {
- /*
- * Use full height of print head...
- */
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPBlack", resolution)) != NULL &&
- attr->value)
- {
- /*
- * Use custom black head data...
- */
-
- sscanf(attr->value, "%d%d", &DotRowCount, &DotRowStep);
- }
- }
- else if (ppd->model_number & ESCP_STAGGER)
- {
- /*
- * Use staggered print head...
- */
-
- fputs("DEBUG: Offset head detected...\n", stderr);
-
- if ((attr = ppdFindAttr(ppd, "cupsESCPOffsets", resolution)) != NULL &&
- attr->value)
- {
- /*
- * Use only 1/3 of the print head when printing color...
- */
-
- sscanf(attr->value, "%d%d%d%d", DotRowOffset + 0,
- DotRowOffset + 1, DotRowOffset + 2, DotRowOffset + 3);
- }
- }
-
- for (i = 0; i < PrinterPlanes; i ++)
- fprintf(stderr, "DEBUG: DotRowOffset[%d] = %d\n", i, DotRowOffset[i]);
-
- /*
- * Allocate bands...
- */
-
- for (i = 0; i < bands; i ++)
- {
- band = (cups_weave_t *)calloc(1, sizeof(cups_weave_t));
- band->next = DotAvailList;
- DotAvailList = band;
-
- band->buffer = calloc(DotRowCount, DotBufferSize);
- }
-
- if (!DotAvailList)
- {
- fputs("ERROR: Unable to allocate band list\n", stderr);
- exit(1);
- }
-
- fputs("DEBUG: Pointer list at start of page...\n", stderr);
-
- for (band = DotAvailList; band != NULL; band = band->next)
- fprintf(stderr, "DEBUG: %p\n", band);
-
- fputs("DEBUG: ----END----\n", stderr);
-
- /*
- * Fill the initial bands...
- */
-
- modrow = DotColStep * DotRowStep;
-
- if (DotRowFeed == 0)
- {
- /*
- * Automatically compute the optimal feed value...
- */
-
- DotRowFeed = DotRowCount / DotColStep - DotRowStep;
-
- while ((((DotRowFeed % 2) == 0) == ((DotRowCount % 2) == 0) ||
- ((DotRowFeed % 3) == 0) == ((DotRowCount % 3) == 0) ||
- ((DotRowFeed % 5) == 0) == ((DotRowCount % 5) == 0)) &&
- DotRowFeed > 1)
- DotRowFeed --;
-
- if (DotRowFeed < 1)
- DotRowFeed = 1;
-
- fprintf(stderr, "DEBUG: Auto DotRowFeed = %d, modrow=%d...\n",
- DotRowFeed, modrow);
- }
-
- memset(DotBands, 0, sizeof(DotBands));
-
- for (i = modrow, subrow = modrow - 1, y = DotRowFeed;
- i > 0;
- i --, y += DotRowFeed)
- {
- while (DotBands[subrow][0])
- {
- /*
- * This subrow is already used, move to another one...
- */
-
- subrow = (subrow + 1) % modrow;
- }
-
- for (plane = 0; plane < PrinterPlanes; plane ++)
- {
- /*
- * Pull the next available band from the list...
- */
-
- band = DotAvailList;
- DotAvailList = DotAvailList->next;
- DotBands[subrow][plane] = band;
-
- /*
- * Start the band in the first few passes, with the number of rows
- * varying to allow for a nice interleaved pattern...
- */
-
- band->x = subrow / DotRowStep;
- band->y = (subrow % DotRowStep) + DotRowOffset[plane];
- band->plane = plane;
- band->row = 0;
- band->count = DotRowCount - y / DotRowStep;
-
- if (band->count < 1)
- band->count = 1;
- else if (band->count > DotRowCount)
- band->count = DotRowCount;
-
- fprintf(stderr, "DEBUG: DotBands[%d][%d] = %p, x = %d, y = %d, plane = %d, count = %d\n",
- subrow, plane, band, band->x, band->y, band->plane, band->count);
- }
-
- subrow = (subrow + DotRowFeed) % modrow;
- }
- }
- else
- {
- /*
- * Allocate memory for a single line of graphics...
- */
-
- ptr = calloc(PrinterPlanes, DotBufferSize);
-
- for (plane = 0; plane < PrinterPlanes; plane ++, ptr += DotBufferSize)
- DotBuffers[plane] = ptr;
- }
-
- /*
- * Set the output resolution...
- */
-
- cupsWritePrintData("\033(D\004\000", 5);
- putchar(units);
- putchar(units >> 8);
- putchar(units * DotRowStep / header->HWResolution[1]);
- putchar(units * DotColStep / header->HWResolution[0]);
-
- /*
- * Set the top of form...
- */
-
- OutputFeed = 0;
-
- /*
- * Allocate buffers as needed...
- */
-
- PixelBuffer = malloc(header->cupsBytesPerLine);
- InputBuffer = malloc(header->cupsWidth * PrinterPlanes * 2);
- OutputBuffers[0] = malloc(PrinterPlanes * header->cupsWidth);
-
- for (i = 1; i < PrinterPlanes; i ++)
- OutputBuffers[i] = OutputBuffers[0] + i * header->cupsWidth;
-
- if (RGB)
- CMYKBuffer = malloc(header->cupsWidth * PrinterPlanes);
-
- CompBuffer = malloc(10 * DotBufferSize * DotRowMax);
-}
-
-
-/*
- * 'EndPage()' - Finish a page of graphics.
- */
-
-void
-EndPage(ppd_file_t *ppd, /* I - PPD file */
- cups_page_header2_t *header) /* I - Page header */
-{
- int i; /* Looping var */
- cups_weave_t *band, /* Current band */
- *next; /* Next band in list */
- int plane; /* Current plane */
- int subrow; /* Current subrow */
- int subrows; /* Number of subrows */
-
-
- /*
- * Output the last bands of print data as necessary...
- */
-
- if (DotRowMax > 1)
- {
- /*
- * Move the remaining bands to the used or avail lists...
- */
-
- subrows = DotRowStep * DotColStep;
-
- for (subrow = 0; subrow < subrows; subrow ++)
- for (plane = 0; plane < PrinterPlanes; plane ++)
- {
- if (DotBands[subrow][plane]->dirty)
- {
- /*
- * Insert into the used list...
- */
-
- DotBands[subrow][plane]->count = DotBands[subrow][plane]->row;
-
- AddBand(DotBands[subrow][plane]);
- }
- else
- {
- /*
- * Nothing here, so move it to the available list...
- */
-
- DotBands[subrow][plane]->next = DotAvailList;
- DotAvailList = DotBands[subrow][plane];
- }
-
- DotBands[subrow][plane] = NULL;
- }
-
- /*
- * Loop until all bands are written...
- */
-
- fputs("DEBUG: Pointer list at end of page...\n", stderr);
-
- for (band = DotUsedList; band != NULL; band = band->next)
- fprintf(stderr, "DEBUG: %p (used)\n", band);
- for (band = DotAvailList; band != NULL; band = band->next)
- fprintf(stderr, "DEBUG: %p (avail)\n", band);
-
- fputs("DEBUG: ----END----\n", stderr);
-
- for (band = DotUsedList; band != NULL; band = next)
- {
- next = band->next;
-
- OutputBand(ppd, header, band);
-
- fprintf(stderr, "DEBUG: freeing used band %p, prev = %p, next = %p\n",
- band, band->prev, band->next);
-
- free(band->buffer);
- free(band);
- }
-
- /*
- * Free memory for the available bands, if any...
- */
-
- for (band = DotAvailList; band != NULL; band = next)
- {
- next = band->next;
-
- fprintf(stderr, "DEBUG: freeing avail band %p, prev = %p, next = %p\n",
- band, band->prev, band->next);
-
- free(band->buffer);
- free(band);
- }
- }
- else
- free(DotBuffers[0]);
-
- /*
- * Output a page eject sequence...
- */
-
- putchar(12);
-
- /*
- * Free memory for the page...
- */
-
- for (i = 0; i < PrinterPlanes; i ++)
- {
- cupsDitherDelete(DitherStates[i]);
- cupsLutDelete(DitherLuts[i]);
- }
-
- free(OutputBuffers[0]);
-
- free(PixelBuffer);
- free(InputBuffer);
- free(CompBuffer);
-
- cupsCMYKDelete(CMYK);
-
- if (RGB)
- {
- cupsRGBDelete(RGB);
- free(CMYKBuffer);
- }
-}
-
-
-/*
- * 'Shutdown()' - Shutdown a printer.
- */
-
-void
-Shutdown(ppd_file_t *ppd) /* I - PPD file */
-{
- /*
- * Reset the printer...
- */
-
- printf("\033@");
-
- if (ppd->model_number & ESCP_REMOTE)
- {
- /*
- * Go into remote mode...
- */
-
- cupsWritePrintData("\033(R\010\000\000REMOTE1", 13);
-
- /*
- * Load defaults...
- */
-
- cupsWritePrintData("LD\000\000", 4);
-
- /*
- * Exit remote mode...
- */
-
- cupsWritePrintData("\033\000\000\000", 4);
- }
-}
-
-
-/*
- * 'AddBand()' - Add a band of data to the used list.
- */
-
-void
-AddBand(cups_weave_t *band) /* I - Band to add */
-{
- cups_weave_t *current, /* Current band */
- *prev; /* Previous band */
-
-
- if (band->count < 1)
- return;
-
- for (current = DotUsedList, prev = NULL;
- current != NULL;
- prev = current, current = current->next)
- if (band->y < current->y ||
- (band->y == current->y && band->x < current->x) ||
- (band->y == current->y && band->x == current->x &&
- band->plane < current->plane))
- break;
-
- if (current != NULL)
- {
- /*
- * Insert the band...
- */
-
- band->next = current;
- band->prev = prev;
- current->prev = band;
-
- if (prev != NULL)
- prev->next = band;
- else
- DotUsedList = band;
- }
- else if (prev != NULL)
- {
- /*
- * Append the band to the end...
- */
-
- band->prev = prev;
- prev->next = band;
- band->next = NULL;
- }
- else
- {
- /*
- * First band in list...
- */
-
- DotUsedList = band;
- band->prev = NULL;
- band->next = NULL;
- }
-}
-
-
-/*
- * 'CancelJob()' - Cancel the current job...
- */
-
-void
-CancelJob(int sig) /* I - Signal */
-{
- (void)sig;
-
- Canceled = 1;
-}
-
-
-/*
- * 'CompressData()' - Compress a line of graphics.
- */
-
-void
-CompressData(ppd_file_t *ppd, /* I - PPD file information */
- const unsigned char *line, /* I - Data to compress */
- const int length,/* I - Number of bytes */
- int plane, /* I - Color plane */
- int type, /* I - Type of compression */
- const int rows, /* I - Number of lines to write */
- const int xstep, /* I - Spacing between columns */
- const int ystep, /* I - Spacing between lines */
- const int offset)/* I - Head offset */
-{
- register const unsigned char *line_ptr,
- /* Current byte pointer */
- *line_end, /* End-of-line byte pointer */
- *start; /* Start of compression sequence */
- register unsigned char *comp_ptr; /* Pointer into compression buffer */
- register int count; /* Count of bytes for output */
- register int bytes; /* Number of bytes per row */
- static int ctable[7][7] = /* Colors */
- {
- { 0, 0, 0, 0, 0, 0, 0 }, /* K */
- { 0, 16, 0, 0, 0, 0, 0 }, /* Kk */
- { 2, 1, 4, 0, 0, 0, 0 }, /* CMY */
- { 2, 1, 4, 0, 0, 0, 0 }, /* CMYK */
- { 0, 0, 0, 0, 0, 0, 0 },
- { 2, 18, 1, 17, 4, 0, 0 }, /* CcMmYK */
- { 2, 18, 1, 17, 4, 0, 16 }, /* CcMmYKk */
- };
-
-
- switch (type)
- {
- case 0 :
- /*
- * Do no compression...
- */
-
- line_ptr = (const unsigned char *)line;
- line_end = (const unsigned char *)line + length;
- break;
-
- default :
- /*
- * Do TIFF pack-bits encoding...
- */
-
- line_ptr = (const unsigned char *)line;
- line_end = (const unsigned char *)line + length;
- comp_ptr = CompBuffer;
-
- while (line_ptr < line_end && (comp_ptr - CompBuffer) < length)
- {
- if ((line_ptr + 1) >= line_end)
- {
- /*
- * Single byte on the end...
- */
-
- *comp_ptr++ = 0x00;
- *comp_ptr++ = *line_ptr++;
- }
- else if (line_ptr[0] == line_ptr[1])
- {
- /*
- * Repeated sequence...
- */
-
- line_ptr ++;
- count = 2;
-
- while (line_ptr < (line_end - 1) &&
- line_ptr[0] == line_ptr[1] &&
- count < 127)
- {
- line_ptr ++;
- count ++;
- }
-
- *comp_ptr++ = 257 - count;
- *comp_ptr++ = *line_ptr++;
- }
- else
- {
- /*
- * Non-repeated sequence...
- */
-
- start = line_ptr;
- line_ptr ++;
- count = 1;
-
- while (line_ptr < (line_end - 1) &&
- line_ptr[0] != line_ptr[1] &&
- count < 127)
- {
- line_ptr ++;
- count ++;
- }
-
- *comp_ptr++ = count - 1;
-
- memcpy(comp_ptr, start, count);
- comp_ptr += count;
- }
- }
-
- if ((comp_ptr - CompBuffer) < length)
- {
- line_ptr = (const unsigned char *)CompBuffer;
- line_end = (const unsigned char *)comp_ptr;
- }
- else
- {
- type = 0;
- line_ptr = (const unsigned char *)line;
- line_end = (const unsigned char *)line + length;
- }
- break;
- }
-
- /*
- * Position the print head...
- */
-
- putchar(0x0d);
-
- if (offset)
- {
- if (BitPlanes == 1)
- cupsWritePrintData("\033(\\\004\000\240\005", 7);
- else
- printf("\033\\");
-
- putchar(offset);
- putchar(offset >> 8);
- }
-
- /*
- * Send the graphics...
- */
-
- bytes = length / rows;
-
- if (ppd->model_number & ESCP_RASTER_ESCI)
- {
- /*
- * Send graphics with ESC i command.
- */
-
- printf("\033i");
- putchar(ctable[PrinterPlanes - 1][plane]);
- putchar(type != 0);
- putchar(BitPlanes);
- putchar(bytes & 255);
- putchar(bytes >> 8);
- putchar(rows & 255);
- putchar(rows >> 8);
- }
- else
- {
- /*
- * Set the color if necessary...
- */
-
- if (PrinterPlanes > 1)
- {
- plane = ctable[PrinterPlanes - 1][plane];
-
- if (plane & 0x10)
- printf("\033(r%c%c%c%c", 2, 0, 1, plane & 0x0f);
- else
- printf("\033r%c", plane);
- }
-
- /*
- * Send graphics with ESC . command.
- */
-
- bytes *= 8;
-
- printf("\033.");
- putchar(type != 0);
- putchar(ystep);
- putchar(xstep);
- putchar(rows);
- putchar(bytes & 255);
- putchar(bytes >> 8);
- }
-
- cupsWritePrintData(line_ptr, line_end - line_ptr);
-}
-
-
-/*
- * 'OutputBand()' - Output a band of graphics.
- */
-
-void
-OutputBand(ppd_file_t *ppd, /* I - PPD file */
- cups_page_header2_t *header, /* I - Page header */
- cups_weave_t *band) /* I - Current band */
-{
- int xstep, /* Spacing between columns */
- ystep; /* Spacing between rows */
-
-
- /*
- * Interleaved ESC/P2 graphics...
- */
-
- OutputFeed = band->y - DotRowCurrent;
- DotRowCurrent = band->y;
-
- fprintf(stderr, "DEBUG: Printing band %p, x = %d, y = %d, plane = %d, count = %d, OutputFeed = %d\n",
- band, band->x, band->y, band->plane, band->count, OutputFeed);
-
- /*
- * Compute step values...
- */
-
- xstep = 3600 * DotColStep / header->HWResolution[0];
- ystep = 3600 * DotRowStep / header->HWResolution[1];
-
- /*
- * Output the band...
- */
-
- if (OutputFeed > 0)
- {
- cupsWritePrintData("\033(v\002\000", 5);
- putchar(OutputFeed & 255);
- putchar(OutputFeed >> 8);
-
- OutputFeed = 0;
- }
-
- CompressData(ppd, band->buffer, band->count * DotBufferSize, band->plane,
- header->cupsCompression, band->count, xstep, ystep, band->x);
-
- /*
- * Clear the band...
- */
-
- memset(band->buffer, 0, band->count * DotBufferSize);
- band->dirty = 0;
-
- /*
- * Flush the output buffers...
- */
-
- fflush(stdout);
-}
-
-
-/*
- * 'ProcessLine()' - Read graphics from the page stream and output as needed.
- */
-
-void
-ProcessLine(ppd_file_t *ppd, /* I - PPD file */
- cups_raster_t *ras, /* I - Raster stream */
- cups_page_header2_t *header, /* I - Page header */
- const int y) /* I - Current scanline */
-{
- int plane, /* Current color plane */
- width, /* Width of line */
- subwidth, /* Width of interleaved row */
- subrow, /* Subrow for interleaved output */
- offset, /* Offset to current line */
- pass, /* Pass number */
- xstep, /* X step value */
- ystep; /* Y step value */
- cups_weave_t *band; /* Current band */
-
-
- /*
- * Read a row of graphics...
- */
-
- if (!cupsRasterReadPixels(ras, PixelBuffer, header->cupsBytesPerLine))
- return;
-
- /*
- * Perform the color separation...
- */
-
- width = header->cupsWidth;
- subwidth = header->cupsWidth / DotColStep;
- xstep = 3600 / header->HWResolution[0];
- ystep = 3600 / header->HWResolution[1];
-
- switch (header->cupsColorSpace)
- {
- case CUPS_CSPACE_W :
- if (RGB)
- {
- cupsRGBDoGray(RGB, PixelBuffer, CMYKBuffer, width);
- cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width);
- }
- else
- cupsCMYKDoGray(CMYK, PixelBuffer, InputBuffer, width);
- break;
-
- case CUPS_CSPACE_K :
- cupsCMYKDoBlack(CMYK, PixelBuffer, InputBuffer, width);
- break;
-
- default :
- case CUPS_CSPACE_RGB :
- if (RGB)
- {
- cupsRGBDoRGB(RGB, PixelBuffer, CMYKBuffer, width);
- cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width);
- }
- else
- cupsCMYKDoRGB(CMYK, PixelBuffer, InputBuffer, width);
- break;
-
- case CUPS_CSPACE_CMYK :
- cupsCMYKDoCMYK(CMYK, PixelBuffer, InputBuffer, width);
- break;
- }
-
- /*
- * Dither the pixels...
- */
-
- for (plane = 0; plane < PrinterPlanes; plane ++)
- {
- cupsDitherLine(DitherStates[plane], DitherLuts[plane], InputBuffer + plane,
- PrinterPlanes, OutputBuffers[plane]);
-
- if (DotRowMax == 1)
- {
- /*
- * Handle microweaved output...
- */
-
- if (cupsCheckBytes(OutputBuffers[plane], width))
- continue;
-
- if (BitPlanes == 1)
- cupsPackHorizontal(OutputBuffers[plane], DotBuffers[plane],
- width, 0, 1);
- else
- cupsPackHorizontal2(OutputBuffers[plane], DotBuffers[plane],
- width, 1);
-
- if (OutputFeed > 0)
- {
- cupsWritePrintData("\033(v\002\000", 5);
- putchar(OutputFeed & 255);
- putchar(OutputFeed >> 8);
- OutputFeed = 0;
- }
-
- CompressData(ppd, DotBuffers[plane], DotBufferSize, plane, 1, 1,
- xstep, ystep, 0);
- fflush(stdout);
- }
- else
- {
- /*
- * Handle softweaved output...
- */
-
- for (pass = 0, subrow = y % DotRowStep;
- pass < DotColStep;
- pass ++, subrow += DotRowStep)
- {
- /*
- * See if we need to output the band...
- */
-
- band = DotBands[subrow][plane];
- offset = band->row * DotBufferSize;
-
- if (BitPlanes == 1)
- cupsPackHorizontal(OutputBuffers[plane] + pass,
- band->buffer + offset, subwidth, 0, DotColStep);
- else
- cupsPackHorizontal2(OutputBuffers[plane] + pass,
- band->buffer + offset, subwidth, DotColStep);
-
- band->row ++;
- band->dirty |= !cupsCheckBytes(band->buffer + offset, DotBufferSize);
- if (band->row >= band->count)
- {
- if (band->dirty)
- {
- /*
- * Dirty band needs to be added to the used list...
- */
-
- AddBand(band);
-
- /*
- * Then find a new band...
- */
-
- if (DotAvailList == NULL)
- {
- OutputBand(ppd, header, DotUsedList);
-
- DotBands[subrow][plane] = DotUsedList;
- DotUsedList->x = band->x;
- DotUsedList->y = band->y + band->count * DotRowStep;
- DotUsedList->plane = band->plane;
- DotUsedList->row = 0;
- DotUsedList->count = DotRowCount;
- DotUsedList = DotUsedList->next;
- }
- else
- {
- DotBands[subrow][plane] = DotAvailList;
- DotAvailList->x = band->x;
- DotAvailList->y = band->y + band->count * DotRowStep;
- DotAvailList->plane = band->plane;
- DotAvailList->row = 0;
- DotAvailList->count = DotRowCount;
- DotAvailList = DotAvailList->next;
- }
- }
- else
- {
- /*
- * This band isn't dirty, so reuse it...
- */
-
- fprintf(stderr, "DEBUG: Blank band %p, x = %d, y = %d, plane = %d, count = %d\n",
- band, band->x, band->y, band->plane, band->count);
-
- band->y += band->count * DotRowStep;
- band->row = 0;
- band->count = DotRowCount;
- }
- }
- }
- }
- }
-
- if (DotRowMax == 1)
- OutputFeed ++;
-}
-
-
-/*
- * 'main()' - Main entry and processing of driver.
- */
-
-int /* O - Exit status */
-main(int argc, /* I - Number of command-line arguments */
- char *argv[]) /* I - Command-line arguments */
-{
- int fd; /* File descriptor */
- cups_raster_t *ras; /* Raster stream for printing */
- cups_page_header2_t header; /* Page header from file */
- int page; /* Current page */
- int y; /* Current line */
- ppd_file_t *ppd; /* PPD file */
- int num_options; /* Number of options */
- cups_option_t *options; /* Options */
-#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
- struct sigaction action; /* Actions for POSIX signals */
-#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
-
-
- /*
- * Make sure status messages are not buffered...
- */
-
- setbuf(stderr, NULL);
-
- /*
- * Check command-line...
- */
-
- if (argc < 6 || argc > 7)
- {
- _cupsLangPrintFilter(stderr, "ERROR",
- _("%s job-id user title copies options [file]"),
- "rastertoescpx");
- return (1);
- }
-
- num_options = cupsParseOptions(argv[5], 0, &options);
-
- /*
- * Open the PPD file...
- */
-
- ppd = ppdOpenFile(getenv("PPD"));
-
- if (!ppd)
- {
- ppd_status_t status; /* PPD error */
- int linenum; /* Line number */
-
- _cupsLangPrintFilter(stderr, "ERROR",
- _("The PPD file could not be opened."));
-
- status = ppdLastError(&linenum);
-
- fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);
-
- return (1);
- }
-
- ppdMarkDefaults(ppd);
- cupsMarkOptions(ppd, num_options, options);
-
- /*
- * Open the page stream...
- */
-
- if (argc == 7)
- {
- if ((fd = open(argv[6], O_RDONLY)) == -1)
- {
- _cupsLangPrintError("ERROR", _("Unable to open raster file"));
- return (1);
- }
- }
- else
- fd = 0;
-
- ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
-
- /*
- * Register a signal handler to eject the current page if the
- * job is cancelled.
- */
-
- Canceled = 0;
-
-#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
- sigset(SIGTERM, CancelJob);
-#elif defined(HAVE_SIGACTION)
- memset(&action, 0, sizeof(action));
-
- sigemptyset(&action.sa_mask);
- action.sa_handler = CancelJob;
- sigaction(SIGTERM, &action, NULL);
-#else
- signal(SIGTERM, CancelJob);
-#endif /* HAVE_SIGSET */
-
- /*
- * Initialize the print device...
- */
-
- Setup(ppd);
-
- /*
- * Process pages as needed...
- */
-
- page = 0;
-
- while (cupsRasterReadHeader2(ras, &header))
- {
- /*
- * Write a status message with the page number and number of copies.
- */
-
- if (Canceled)
- break;
-
- page ++;
-
- fprintf(stderr, "PAGE: %d 1\n", page);
- _cupsLangPrintFilter(stderr, "INFO", _("Starting page %d."), page);
-
- StartPage(ppd, &header);
-
- for (y = 0; y < header.cupsHeight; y ++)
- {
- /*
- * Let the user know how far we have progressed...
- */
-
- if (Canceled)
- break;
-
- if ((y & 127) == 0)
- {
- _cupsLangPrintFilter(stderr, "INFO",
- _("Printing page %d, %d%% complete."),
- page, 100 * y / header.cupsHeight);
- fprintf(stderr, "ATTR: job-media-progress=%d\n",
- 100 * y / header.cupsHeight);
- }
-
- /*
- * Read and write a line of graphics or whitespace...
- */
-
- ProcessLine(ppd, ras, &header, y);
- }
-
- /*
- * Eject the page...
- */
-
- _cupsLangPrintFilter(stderr, "INFO", _("Finished page %d."), page);
-
- EndPage(ppd, &header);
-
- if (Canceled)
- break;
- }
-
- Shutdown(ppd);
-
- cupsFreeOptions(num_options, options);
-
- cupsRasterClose(ras);
-
- if (fd != 0)
- close(fd);
-
- if (page == 0)
- {
- _cupsLangPrintFilter(stderr, "ERROR", _("No pages were found."));
- return (1);
- }
- else
- {
- _cupsLangPrintFilter(stderr, "INFO", _("Ready to print."));
- return (0);
- }
-}
-
-
-/*
- * End of "$Id$".
- */