summaryrefslogtreecommitdiff
path: root/gs/contrib/pcl3/src/pcl3opts.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/contrib/pcl3/src/pcl3opts.c')
-rw-r--r--gs/contrib/pcl3/src/pcl3opts.c1176
1 files changed, 0 insertions, 1176 deletions
diff --git a/gs/contrib/pcl3/src/pcl3opts.c b/gs/contrib/pcl3/src/pcl3opts.c
deleted file mode 100644
index 394e232e1..000000000
--- a/gs/contrib/pcl3/src/pcl3opts.c
+++ /dev/null
@@ -1,1176 +0,0 @@
-/******************************************************************************
- File: $Id: pcl3opts.c,v 1.17 2001/05/31 15:19:16 Martin Rel $
- Contents: Program to convert information in PCL-3+ files into options to be
- used for the ghostscript device "pcl3" in order to produce a
- file using a similar configuration
- Author: Martin Lottermoser, Greifswaldstrasse 28, 38124 Braunschweig,
- Germany; e-mail: Martin.Lottermoser@t-online.de.
-
-*******************************************************************************
-* *
-* Copyright (C) 1999, 2000, 2001 by Martin Lottermoser *
-* All rights reserved *
-* *
-******************************************************************************/
-
-/* Configuration management identification */
-#ifndef lint
-static char
- cm_id[] = "@(#)$Id: pcl3opts.c,v 1.17 2001/05/31 15:19:16 Martin Rel $";
-#endif
-
-/*****************************************************************************/
-
-#ifndef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 500
-#endif
-
-/* Standard headers */
-#include <assert.h>
-#include <errno.h>
-#include <locale.h>
-#include <nl_types.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-/* Application headers */
-#include "pclsize.h"
-#include "pclgen.h"
-#include "pclscan.h"
-
-/*****************************************************************************/
-
-#define check(p) \
- if ((p) == NULL) { \
- emessage(9, "Memory allocation failure: %s.\n", strerror(errno)); \
- return -1; \
- }
-
-/*****************************************************************************/
-
-/* Global variables */
-
-static const char *progname; /* The program's name in messages */
-static nl_catd catd = (nl_catd)(-1); /* NLS message catalogue descriptor */
-
-/*****************************************************************************/
-
-static void message(FILE *f, int msg_id, const char *fmt, va_list ap)
-{
- vfprintf(f, catd == (nl_catd)(-1)? fmt: catgets(catd, 2, msg_id, fmt), ap);
-
- return;
-}
-
-/*****************************************************************************/
-
-static void emessage(int msg_id, const char *fmt, ...)
-{
- va_list ap;
-
- fprintf(stderr, "? %s: ", progname);
- va_start(ap, fmt);
- message(stderr, msg_id, fmt, ap);
- va_end(ap);
-
- return;
-}
-
-/*****************************************************************************/
-
-static void imessage(FILE *f, int msg_id, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- message(f, msg_id, fmt, ap);
- va_end(ap);
-
- return;
-}
-
-/*****************************************************************************/
-
-static void check_line_length(FILE *out, int *line_length, int expected)
-{
- if (*line_length + expected <= 78) return;
-
- fputs(" \\\n", out);
- fputs(" ", out);
- *line_length = 4;
-
- return;
-}
-
-/*****************************************************************************/
-
-/* Type for state and information collected during parsing a file */
-typedef struct {
- FILE *out;
-
- /* Capability */
- pcl_bool
- seen_ERG_B, /* End Raster Graphics */
- seen_ERG_C,
- seen_RGR, /* Raster Graphics Resolution */
- seen_CRD, /* Configure Raster Data */
- seen_old_quality,
- seen_new_quality,
- seen_unknown_compression;
-
- /* State */
- int
- first_colorant_planes,
- next_plane,
- number_of_outputs;
- pcl_FileData
- fdata,
- fdata_old;
- pcl_bool
- CRD_active,
- seen_first_colorant,
- seen_raster_data;
-} CollectedInfo;
-
-/*****************************************************************************/
-
-static void print_result(CollectedInfo *ip) /* NLS: 10, 70 */
-{
- pcl_bool
- different_resolutions = FALSE,
- different_non_black_levels = FALSE;
- pcl_Compression
- default_compression;
- int j;
- int ll; /* line length */
- unsigned int min_hres, min_vres, black_levels, non_black_levels, start;
-
- if (ip->number_of_outputs > 0)
- imessage(ip->out, 10,
- "\nThe previous raster data section is followed by one with a different\n"
- "configuration.\n");
- ip->number_of_outputs++;
-
- /* Find the smallest resolutions and look for different resolutions */
- min_hres = ip->fdata.colorant_array[0].hres;
- min_vres = ip->fdata.colorant_array[0].vres;
- for (j = 1; j < ip->fdata.number_of_colorants; j++) {
- int
- h = ip->fdata.colorant_array[j].hres,
- v = ip->fdata.colorant_array[j].vres;
- if (h != min_hres || v != min_vres) different_resolutions = TRUE;
- if (h < min_hres) min_hres = h;
- if (v < min_vres) min_vres = v;
- }
-
- black_levels = ip->fdata.colorant_array[0].levels;
-
- /* Check for deviations in the non-black levels */
- start = (ip->fdata.palette == pcl_CMY || ip->fdata.palette == pcl_RGB? 0: 1);
- non_black_levels = ip->fdata.colorant_array[start].levels;
- for (j = 1; j < 3; j++)
- if (ip->fdata.colorant_array[start + j].levels != non_black_levels)
- different_non_black_levels = TRUE;
-
- if (different_resolutions || different_non_black_levels) {
- imessage(ip->out, 11,
- "I've found a raster data section which uses a combination of "
- "resolutions\n"
- "and intensity levels which pcl3 cannot reproduce:\n");
- for (j = 0; j < ip->fdata.number_of_colorants; j++)
- imessage(ip->out, 12, " colorant %d: %4d x %4d ppi %2d levels\n",
- j + 1,
- ip->fdata.colorant_array[j].hres, ip->fdata.colorant_array[j].vres,
- ip->fdata.colorant_array[j].levels);
- if (ip->fdata.palette == pcl_CMYK &&
- non_black_levels > 2 && black_levels < 4)
- black_levels = 4;
- }
-
- imessage(ip->out, 13,
- "My best guess for the command line needed to generate a similar file "
- "is:\n");
-
- /* Device selection */
- ll = -1;
- ll += fprintf(ip->out, "\n gs -sDEVICE=pcl3 -sSubdevice=");
- default_compression = pcl_cm_tiff;
- if (ip->seen_CRD || ip->seen_new_quality)
- ll += fprintf(ip->out, "unspec");
- else if (ip->seen_ERG_B && !ip->seen_ERG_C && ip->fdata.shingling == -1 &&
- (ip->fdata.palette == pcl_no_palette || ip->fdata.palette == pcl_black)) {
- /* This command line can still fail because of, e.g., resolution. */
- ll += fprintf(ip->out, "hpdj500");
- default_compression = pcl_cm_delta;
- }
- else
- ll += fprintf(ip->out, "unspecold");
-
- /* Special global language features */
- if (ip->fdata.NULs_to_send > 0) {
- check_line_length(ip->out, &ll, sizeof("-dSendNULs=9600"));
- /* Note the missing SP which is instead accounted for by NUL. */
- ll += fprintf(ip->out, " -dSendNULs=%d", ip->fdata.NULs_to_send);
- }
- if (ip->fdata.PJL_job != NULL) {
- check_line_length(ip->out, &ll,
- sizeof("-sPJLJob=") + strlen(ip->fdata.PJL_job));
- ll += fprintf(ip->out, " -sPJLJob=%s", ip->fdata.PJL_job);
- }
- if (ip->fdata.PJL_language != NULL) {
- check_line_length(ip->out, &ll,
- sizeof("-sPJLLanguage=") + strlen(ip->fdata.PJL_language));
- ll += fprintf(ip->out, " -sPJLLanguage=%s", ip->fdata.PJL_language);
- }
- if (ip->seen_CRD && !ip->seen_RGR) {
- check_line_length(ip->out, &ll, sizeof("-dOnlyCRD"));
- ll += fprintf(ip->out, " -dOnlyCRD");
- }
-
- /* Media handling except media source */
- if (ip->fdata.manual_feed) {
- check_line_length(ip->out, &ll, sizeof("-dManualFeed"));
- ll += fprintf(ip->out, " -dManualFeed");
- }
- if (ip->fdata.duplex > 0) {
- const char s[] = " -dDuplex";
-
- if (ip->fdata.duplex == 1) {
- const char s[] = " -sDuplexCapability=sameLeadingEdge";
- check_line_length(ip->out, &ll, sizeof(s) - 1);
- ll += fprintf(ip->out, s);
- }
- else if (ip->fdata.duplex == 2) {
- const char s[] = " -sDuplexCapability=oppositeLeadingEdge";
- check_line_length(ip->out, &ll, sizeof(s) - 1);
- ll += fprintf(ip->out, s);
- }
- check_line_length(ip->out, &ll, sizeof(s) - 1);
- ll += fprintf(ip->out, s);
- }
- if (ip->fdata.dry_time >= 0) {
- check_line_length(ip->out, &ll, sizeof("-dDryTime=") + 4);
- ll += fprintf(ip->out, " -dDryTime=%d", ip->fdata.dry_time);
- }
-
- /* Resolution */
- if (min_hres != 0) {
- check_line_length(ip->out, &ll, 12);
- ll += fprintf(ip->out, " -r%u", min_hres);
- if (min_vres != min_hres) ll += fprintf(ip->out, "x%u", min_vres);
- }
-
- /* Colour model */
- if (ip->fdata.palette != pcl_no_palette) {
- check_line_length(ip->out, &ll, sizeof("-sColourModel=CMY+K"));
- ll += fprintf(ip->out, " -sColourModel=");
- switch (ip->fdata.palette) {
- case pcl_black:
- ll += fprintf(ip->out, "Gray"); break;
- case pcl_RGB:
- ll += fprintf(ip->out, "RGB"); break;
- case pcl_CMY:
- ll += fprintf(ip->out, "CMY"); break;
- case pcl_CMYK:
- if (ip->seen_new_quality || ip->seen_CRD) /* Guess */
- ll += fprintf(ip->out, "CMYK");
- else
- ll += fprintf(ip->out, "CMY+K");
- break;
- default:
- assert(0); /* bug guard */
- }
- }
-
- /* Intensity levels */
- if (ip->fdata.palette == pcl_CMY) {
- if (non_black_levels > 2) {
- check_line_length(ip->out, &ll, sizeof("-dCMYLevels=") + 2);
- ll += fprintf(ip->out, " -dCMYLevels=%d", non_black_levels);
- }
- }
- else {
- if (black_levels > 2) {
- check_line_length(ip->out, &ll, sizeof("-dBlackLevels=") + 2);
- ll += fprintf(ip->out, " -dBlackLevels=%d", black_levels);
- }
- if (ip->fdata.palette == pcl_CMYK && non_black_levels > 2) {
- check_line_length(ip->out, &ll, sizeof("-dCMYLevels=") + 2);
- ll += fprintf(ip->out, " -dCMYLevels=%d", non_black_levels);
- }
- }
-
- /* Print quality, possibly also medium */
- if (ip->seen_new_quality) {
- check_line_length(ip->out, &ll, sizeof("-sPrintQuality=presentation"));
- ll += fprintf(ip->out, " -sPrintQuality=");
- switch (ip->fdata.print_quality) {
- case -1:
- ll += fprintf(ip->out, "draft"); break;
- case 0:
- ll += fprintf(ip->out, "normal"); break;
- case 1:
- ll += fprintf(ip->out, "presentation"); break;
- default:
- ll += fprintf(ip->out, "%d", ip->fdata.print_quality);
- }
-
- check_line_length(ip->out, &ll,
- sizeof("-sMedium='quick dry transparency'"));
- ll += fprintf(ip->out, " -sMedium=");
- switch (ip->fdata.media_type) {
- case 0:
- ll += fprintf(ip->out, "plain"); break;
- case 1:
- ll += fprintf(ip->out, "bond"); break;
- case 2:
- ll += fprintf(ip->out, "Premium"); break;
- case 3:
- ll += fprintf(ip->out, "glossy"); break;
- case 4:
- ll += fprintf(ip->out, "transparency"); break;
- case 5:
- ll += fprintf(ip->out, "'quick dry glossy'"); break;
- case 6:
- ll += fprintf(ip->out, "'quick dry transparency'"); break;
- default:
- ll += fprintf(ip->out, "%d", ip->fdata.media_type);
- }
- }
- else if (ip->seen_old_quality) {
- if (ip->fdata.depletion != 0) {
- check_line_length(ip->out, &ll, sizeof("-dDepletion=") + 2);
- ll += fprintf(ip->out, " -dDepletion=%d", ip->fdata.depletion);
- }
- if (ip->fdata.shingling != -1) {
- check_line_length(ip->out, &ll, sizeof("-dShingling=") + 2);
- ll += fprintf(ip->out, " -dShingling=%d", ip->fdata.shingling);
- }
- if (ip->fdata.raster_graphics_quality != -1) {
- check_line_length(ip->out, &ll,
- sizeof("-dRasterGraphicsQuality=") + 2);
- ll += fprintf(ip->out, " -dRasterGraphicsQuality=%d",
- ip->fdata.raster_graphics_quality);
- }
- }
-
- /* Compression. We display this option only if the value is different from
- what pcl3 would otherwise use. */
- if (ip->fdata.compression != default_compression) {
- check_line_length(ip->out, &ll, sizeof("-dCompressionMethod=") + 1);
- ll += fprintf(ip->out, " -dCompressionMethod=%d", ip->fdata.compression);
- }
-
- fputs("\n\n", ip->out);
- if (ip->fdata.palette == pcl_CMYK && !ip->seen_first_colorant) {
- imessage(ip->out, 70,
- "Although the colour model in this file is declared as CMYK, "
- "the file does not\n"
- "use the black colorant. If you find that the printer does not accept "
- "a file\n"
- "generated with the command line above, "
- "try the CMY colour model instead.\n\n");
- }
-
- if (ip->fdata.size != 0) {
- ms_MediaCode media_code = pcl3_media_code(ip->fdata.size);
- const ms_SizeDescription *size = ms_find_size_from_code(media_code);
- if (size == NULL)
- imessage(ip->out, 14,
- "This file uses a PCL page size code (%d) which is unknown to pcl3.\n",
- (int)ip->fdata.size);
- else {
- imessage(ip->out, 15, "The page size is set to %s", size->name);
- /* I'm using the size specification as an indication of the PCL Page Size
- code used, hence I'm adding the card flag if present. Note that
- adding "Big" is not useful. */
- if (media_code & PCL_CARD_FLAG) fputs(PCL_CARD_STRING, ip->out);
- if (size->dimen[0] > 0) {
- const char *unit = catgets(catd, 2, 16, "mm");
-
- fputs(" (", ip->out);
- if (strcmp(unit, "bp") == 0)
- fprintf(ip->out, "%.0f x %.0f bp", size->dimen[0],
- size->dimen[1]);
- else if (strcmp(unit, "in") == 0)
- fprintf(ip->out, "%.1f x %.1f in", size->dimen[0]/BP_PER_IN,
- size->dimen[1]/BP_PER_IN);
- else
- fprintf(ip->out, "%.0f x %.0f mm", size->dimen[0]/BP_PER_MM,
- size->dimen[1]/BP_PER_MM);
- fputc(')', ip->out);
- }
- fputs(".\n", ip->out);
- }
- }
- if (ip->fdata.media_source != 0 && ip->fdata.media_source != 1)
- imessage(ip->out, 19, "The media source (input tray) selected is %d.\n",
- ip->fdata.media_source);
- if (ip->fdata.media_destination != 0)
- imessage(ip->out, 17,
- "The media destination (output tray) selected is %d.\n",
- ip->fdata.media_destination);
- if (ip->fdata.media_source != 0 && ip->fdata.media_source != 1 ||
- ip->fdata.media_destination != 0)
- imessage(ip->out, 18,
- "To be able to select a media position (input or output) you will have "
- "to\n"
- "configure the `InputAttributes' or `OutputAttributes' dictionaries\n"
- "appropriately. See the manual page gs-pcl3(1).\n");
-
- return;
-}
-
-/*****************************************************************************/
-
-static int action_PageSize(FILE *in, const pcl_Command *cmd, void *i)
-{
- CollectedInfo *ip = i;
-
- ip->fdata.size = cmd->i;
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int action_dry_time(FILE *in, const pcl_Command *cmd, void *i)
-{
- CollectedInfo *ip = i;
-
- ip->fdata.dry_time = cmd->i;
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int action_destination(FILE *in, const pcl_Command *cmd, void *i)
-{
- CollectedInfo *ip = i;
-
- ip->fdata.media_destination = cmd->i;
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int action_source(FILE *in, const pcl_Command *cmd, void *i)
-{
- CollectedInfo *ip = i;
-
- if (cmd->i != 0 && cmd->i != -2) {
- if (cmd->i == 2) ip->fdata.manual_feed = TRUE;
- else ip->fdata.media_source = cmd->i;
- }
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int action_media_type(FILE *in, const pcl_Command *cmd, void *i)
-{
- CollectedInfo *ip = i;
-
- ip->seen_new_quality = TRUE;
- ip->fdata.media_type = cmd->i;
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int action_duplex(FILE *in, const pcl_Command *cmd, void *i)
-{ /* NLS: 60 */
- CollectedInfo *ip = i;
-
- ip->fdata.duplex = cmd->i;
- if (ip->fdata.duplex < 0 || 2 < ip->fdata.duplex)
- imessage(ip->out, 60, "I've found an unknown value for the command to "
- "select\nsimplex/duplex printing: %d.\n", ip->fdata.duplex);
-
- return 0;
-}
-
-/*****************************************************************************/
-
-/* PJL white space. Note: no expressions with side effects permitted. */
-#define PJL_ws(c) ((c) == ' ' || (c) == '\t')
-
-/******************************************************************************
-
- Function to check "@PJL" prefix
-
- Return codes:
- 0: starts correctly, prefix has been read,
- 1: starts wrong, read characters have been pushed back,
- -1: starts wrong, read characters could not be pushed back and an error
- message has been issued.
-*/
-
-static int check_prefix(FILE *in)
-{
- static const pcl_Octet prefix[] = "@PJL";
- /* Note that the "@PJL" prefix is required to be uppercase in PJL. */
- int c, j;
-
- /* Check for prefix followed by white space or EOL */
- j = 0; /* number of matching characters read */
- while (j < 4 && (c = fgetc(in)) == prefix[j]) j++;
- if (j == 4) {
- c = fgetc(in);
- if (PJL_ws(c) || c == '\r' || c == '\n') j++;
- /* I'm assuming that we're dealing with legal PJL, i.e., the CR is followed
- by LF. It is not the responsibility of this program to discover PJL
- syntax errors. */
- }
- if (j < 5) {
- /* Keep in mind that one byte of push-back is guaranteed to work. */
- if (c != EOF) ungetc(c, in);
- while (j > 0) {
- j--;
- if (ungetc(prefix[j], in) == EOF) {
- emessage(80,
- "Error trying to push back characters while parsing PJL:\n %s.\n",
- strerror(errno));
- /* This should only happen for unprofessional PJL, i.e., without a
- terminating ENTER LANGUAGE. */
- return -1;
- }
- }
-
- return 1;
- }
-
- /* Ensure we've not read past the end of the line */
- if (c == '\n') ungetc(c, in);
-
- return 0;
-}
-
-/*****************************************************************************/
-
-#define PJL_letter(c) ('a' <= (c) && (c) <= 'z' || 'A' <= (c) && (c) <= 'Z')
-
-/*****************************************************************************/
-
-#define TILE_SIZE 200
-
-static int action_UEL(FILE *in, const pcl_Command *cmd, void *i)
-{
- CollectedInfo *ip = i;
- int c;
- pcl_Octet *buffer, *s;
- size_t allocated, used;
-
- if (cmd->i != 12345) return 1;
-
- /* As we have entered PJL, the previous personality is irrelevant. */
- if (ip->fdata.PJL_language != NULL) {
- free(ip->fdata.PJL_language); ip->fdata.PJL_language = NULL;
- }
-
- buffer = (pcl_Octet *)malloc(TILE_SIZE);
- check(buffer);
- allocated = TILE_SIZE;
-
- /* Read one PJL command at a time (necessary in order to catch ENTER) */
- do {
- c = check_prefix(in);
- if (c != 0) c = EOF;
- else {
- /* Read up to EOL or EOF */
- used = 0;
- while ((c = fgetc(in)) != EOF && c != '\n') {
- if (used >= allocated - 1) {
- allocated += TILE_SIZE;
- buffer = (pcl_Octet *)realloc(buffer, allocated);
- check(buffer);
- }
- buffer[used] = c;
- used++;
- }
- /* Remove an optional trailing CR */
- if (used > 0 && buffer[used-1] == 'r') used--;
- buffer[used] = '\0';
-
- /* Skip optional whitespace */
- s = buffer;
- while (PJL_ws(*s)) s++;
-
- if (PJL_letter(*s)) {
- pcl_Octet *t;
- int l;
-
- /* Isolate command and convert to upper case. Note that we're running
- in an internationalized environment, hence we can't use toupper(). */
- t = s;
- do {
- if ('a' <= *t && *t <= 'z') *t -= 'a' - 'A';
- t++;
- } while (*t != '\0' && !PJL_ws(*t));
-
- /* Identify command */
- l = t - s;
-#if 0
- fprintf(stderr, "Command (length %d): `", l);
- fwrite(s, 1, l, stderr);
- fprintf(stderr, "'.\n");
-#endif
- if (l == sizeof("ENTER") - 1 && strncmp(s, "ENTER", l) == 0 &&
- PJL_ws(*t)) {
- /* Check for "LANGUAGE" */
- s = t + 1;
- while (PJL_ws(*s)) s++;
- t = s;
- while (*t != '\0' && !PJL_ws(*t) && *t != '=') {
- if ('a' <= *t && *t <= 'z') *t -= 'a' - 'A';
- t++;
- }
- l = t - s;
- if (l == sizeof("LANGUAGE") - 1 && strncmp(s, "LANGUAGE", t - s) == 0
- && (PJL_ws(*t) || *t == '=')) {
- s = strchr(t, '='); /* again assuming legal PJL */
- if (s != NULL) {
- s++;
- while (PJL_ws(*s)) s++;
- if (PJL_letter(*s)){
- t = s + 1;
- while (*t != '\0' && !PJL_ws(*t)) t++;
- ip->fdata.PJL_language = (char *)malloc(t - s + 1);
- check(ip->fdata.PJL_language);
- strncpy(ip->fdata.PJL_language, s, t - s);
- ip->fdata.PJL_language[t - s] = '\0';
- }
- }
- c = EOF; /* exit PJL and this loop */
- }
- }
- else if (l == 3 && strncmp(s, "JOB", 3) == 0) {
- /* Don't bother to identify the job name; let the user create an
- unnamed job. */
- static char jobname[] = "";
- ip->fdata.PJL_job = jobname;
- }
- }
- }
- }
- while (c != EOF);
-
- free(buffer);
-
- return 0;
-}
-
-/*****************************************************************************/
-
- /* NLS: 20 */
-static int action_compression(FILE *in, const pcl_Command *cmd, void *i)
-{
- CollectedInfo *ip = i;
-
- if (cmd->i != pcl_cm_none && cmd->i != pcl_cm_rl && cmd->i != pcl_cm_tiff &&
- cmd->i != pcl_cm_delta && cmd->i != pcl_cm_crdr) {
- if (!ip->seen_unknown_compression)
- imessage(ip->out, 20,
- "This file uses at least one compression method for raster data (%d)\n"
- "which pcl3 does not know.\n", cmd->i);
- ip->seen_unknown_compression = TRUE;
- }
- else {
- if (cmd->i > ip->fdata.compression) ip->fdata.compression = cmd->i;
- }
-
- return 0;
-}
-
-/*****************************************************************************/
-
-/* The following function is only called for "*bV" and "*bW". */
-
-static int action_raster_data(FILE *in, const pcl_Command *cmd, void *i)
-{
- CollectedInfo *ip = i;
- int j;
-
- ip->seen_raster_data = TRUE;
- if (!ip->seen_first_colorant && cmd->i > 0 &&
- ip->next_plane < ip->first_colorant_planes)
- ip->seen_first_colorant = TRUE;
-
- for (j = cmd->i; j > 0; j--) fgetc(in);
- if (cmd->chars[2] == 'W') ip->next_plane = 0; else ip->next_plane++;
-
- return 0;
-}
-
-/*****************************************************************************/
-
-#define two_octets(index) (buffer[index]*256 + buffer[(index) + 1])
-
-/*****************************************************************************/
-
-static void print_CRD(FILE *out, const pcl_Octet *buffer)
-{
- int j;
-
- for (j = 0; j < buffer[1]; j++)
- imessage(out, 12, " colorant %d: %4d x %4d ppi %2d levels\n",
- j + 1, two_octets(2 + 6*j), two_octets(4 + 6*j),
- two_octets(6 + 6*j));
-
- return;
-}
-
-/*****************************************************************************/
-
-static int action_CRD(FILE *in, const pcl_Command *cmd, void *i) /* NLS: 30 */
-{
- CollectedInfo *ip = i;
- pcl_Octet *buffer;
- int errors = 0;
-
- ip->seen_CRD = TRUE;
-
- if (cmd->i <= 0) {
- ip->CRD_active = FALSE;
- ip->fdata.palette = pcl_no_palette;
- ip->fdata.number_of_colorants = 1;
- ip->fdata.colorant_array[0].hres = ip->fdata.colorant_array[0].vres = 75;
- ip->fdata.colorant_array[0].levels = 2;
- ip->first_colorant_planes = 1;
- return 0;
- }
- ip->CRD_active = TRUE;
-
- buffer = (pcl_Octet *)malloc(cmd->i);
- check(buffer);
- fread(buffer, sizeof(pcl_Octet), cmd->i, in);
-
- if (buffer[0] == 2) {
- /* Just occasionally, a little paranoia is good for the soul, let alone for
- for the reliability of the program! */
- if (2 + buffer[1]*6 != cmd->i) {
- emessage(30, "Illegal field length in Configure Raster Data command.\n");
- return -1;
- }
-
- if (buffer[1] == 1 || buffer[1] == 3 || buffer[1] == 4) {
- int j;
-
- ip->fdata.number_of_colorants = buffer[1];
- switch (ip->fdata.number_of_colorants) {
- case 1:
- ip->fdata.palette = pcl_black; break;
- case 3:
- ip->fdata.palette = pcl_CMY; break;
- case 4:
- ip->fdata.palette = pcl_CMYK; break;
- }
-
- for (j = 0; j < ip->fdata.number_of_colorants; j++) {
- ip->fdata.colorant_array[j].hres = two_octets(2 + 6*j);
- ip->fdata.colorant_array[j].vres = two_octets(4 + 6*j);
- ip->fdata.colorant_array[j].levels = two_octets(6 + 6*j);
- }
-
- {
- int power = 1;
- ip->first_colorant_planes = 0;
-
- while (power < ip->fdata.colorant_array[0].levels) {
- power *= 2;
- ip->first_colorant_planes++;
- }
- }
- }
- else {
- emessage(31,
- "This file contains a Configure Raster Data command with an\n"
- " illegal number of colorants (%d) and the following data:\n",
- buffer[1]);
- print_CRD(stderr, buffer);
- errors++;
- }
- }
- else {
- emessage(32,
- "This file contains a Configure Raster Data command with an\n"
- " unknown format (%d).\n",
- (int)buffer[0]);
- if (cmd->i > 2 && cmd->i == 2 + buffer[1]*6) {
- imessage(stderr, 33, " It *might* mean the following:\n");
- print_CRD(stderr, buffer);
- imessage(stderr, 34, " This format is not supported by pcl3.\n");
- }
- errors++;
- }
- free(buffer);
-
- return errors > 0? -1: 0;
-}
-
-/*****************************************************************************/
-
-static int action_old_quality(FILE *in, const pcl_Command *cmd, void *i)
-{
- CollectedInfo *ip = i;
-
- ip->seen_old_quality = TRUE;
- if (cmd->chars[1] == 'o') {
- if (cmd->chars[2] == 'D') ip->fdata.depletion = cmd->i;
- else if (cmd->chars[2] == 'Q') ip->fdata.shingling = cmd->i;
- }
- else if (cmd->chars[1] == 'r' && cmd->chars[2] == 'Q')
- ip->fdata.raster_graphics_quality = cmd->i;
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int action_quality(FILE *in, const pcl_Command *cmd, void *i)
-{
- CollectedInfo *ip = i;
-
- ip->seen_new_quality = TRUE;
- ip->fdata.print_quality = cmd->i;
-
- return 0;
-}
-
-/*****************************************************************************/
-
- /* NLS: 40 */
-static int action_colour(FILE *in, const pcl_Command *cmd, void *i)
-{
- CollectedInfo *ip = i;
-
- if (!ip->CRD_active) {
- switch (cmd->i) {
- case -4:
- ip->fdata.palette = pcl_CMYK; break;
- case -3:
- ip->fdata.palette = pcl_CMY; break;
- case -1:
- /*FALLTHROUGH*/
- case 0:
- /*FALLTHROUGH*/
- case 1:
- ip->fdata.palette = pcl_black; break;
- case 3:
- ip->fdata.palette = pcl_RGB; break;
- default:
- emessage(41, "This file uses a palette (%d) not supported by pcl3.\n",
- cmd->i);
- return -1;
- }
- ip->fdata.number_of_colorants = abs(cmd->i);
-
- {
- int j;
-
- for (j = 0; j < ip->fdata.number_of_colorants; j++) {
- ip->fdata.colorant_array[j].hres = ip->fdata.colorant_array[j].vres =
- ip->fdata.colorant_array[0].hres;
- ip->fdata.colorant_array[j].levels = 2;
- }
- }
-
- ip->first_colorant_planes = 1;
- }
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int action_resolution(FILE *in, const pcl_Command *cmd, void *i)
-{
- CollectedInfo *ip = i;
-
- ip->seen_RGR = TRUE;
-
- if (!ip->CRD_active) {
- int j;
-
- for (j = 0; j < ip->fdata.number_of_colorants; j++) {
- ip->fdata.colorant_array[j].hres =
- ip->fdata.colorant_array[j].vres = cmd->i;
- ip->fdata.colorant_array[j].levels = 2;
- }
- }
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int action_end_raster(FILE *in, const pcl_Command *cmd, void *i)
-{
- CollectedInfo *ip = i;
-
- if (cmd->chars[2] == 'B') ip->seen_ERG_B = TRUE;
- else if (cmd->chars[2] == 'C') ip->seen_ERG_C = TRUE;
-
- if (ip->seen_raster_data &&
- memcmp(&ip->fdata, &ip->fdata_old, sizeof(pcl_FileData)) != 0) {
- print_result(ip);
- memcpy(&ip->fdata_old, &ip->fdata, sizeof(pcl_FileData));
- }
- ip->seen_raster_data = FALSE;
-
- return 0;
-}
-
-/*****************************************************************************/
-
-typedef struct {
- char cmd[4];
- pcl_CommandInterpreter action;
-} ActionEntry;
-
-static ActionEntry action_table[] = {
- {"%-X", &action_UEL}, /* Universal Exit Language */
- {"&bT", &action_dry_time}, /* Set Dry Time */
- {"&lA", &action_PageSize}, /* Page Size */
- {"&lG", &action_destination}, /* Set Output Bin */
- {"&lH", &action_source}, /* Media Source */
- {"&lM", &action_media_type}, /* Media Type */
- {"&lS", &action_duplex}, /* Simplex/Duplex Print */
- {"*bM", &action_compression}, /* Raster Graphics Compression Method */
- {"*bV", &action_raster_data}, /* Transfer Raster Graphics Data by Plane */
- {"*bW", &action_raster_data}, /* Transfer Raster Graphics Data by Row */
- {"*gW", &action_CRD}, /* Configure Raster Data */
- {"*oD", &action_old_quality}, /* Set Raster Graphics Depletion */
- {"*oM", &action_quality}, /* Print Quality */
- {"*oQ", &action_old_quality}, /* Set Raster Graphics Shingling */
- {"*rB", &action_end_raster}, /* End Raster Graphics (old) */
- {"*rC", &action_end_raster}, /* End Raster Graphics (new) */
- {"*rQ", &action_old_quality}, /* Raster Graphics Quality */
- {"*rU", &action_colour}, /* Set Number of Planes Per Row */
- {"*tR", &action_resolution} /* Set Raster Graphics Resolution */
-};
-
-/*****************************************************************************/
-
-static int cmp_entries(const void *a, const void *b)
-{
- return
- strncmp(((const ActionEntry *)a)->cmd, ((const ActionEntry *)b)->cmd, 3);
-}
-
-/*****************************************************************************/
-
-static int analyzer(FILE *in, const pcl_Command *cmd, void *i)
-{
- ActionEntry key;
- const ActionEntry *entry;
- CollectedInfo *ip = i;
-
- /* Control codes */
- if (cmd->kind == 1) {
- if (cmd->chars[0] == '\0' &&
- /* Guard against NULs somewhere else except initially */
- !ip->seen_RGR && !ip->seen_CRD)
- ip->fdata.NULs_to_send = cmd->i;
- return 0;
- }
-
- /* Two-character escape sequences */
- if (cmd->kind == 2) {
- switch (cmd->chars[0]) {
- case 'E': /* Printer Reset */
- {
- /* Preserve some global data (mostly PJL state) across PCL Reset
- invocations */
- unsigned int NULs_to_send = ip->fdata.NULs_to_send;
- char *PJL_language = ip->fdata.PJL_language;
- char *PJL_job = ip->fdata.PJL_job;
-
- ip->CRD_active = FALSE;
- ip->seen_raster_data = FALSE;
- memset(&ip->fdata, 0, sizeof(pcl_FileData));
- ip->fdata.colorant_array[0].hres =
- ip->fdata.colorant_array[0].vres = 75;
- ip->fdata.colorant_array[0].levels = 2;
- ip->fdata.number_of_colorants = 1;
- ip->fdata.duplex = -1;
- ip->fdata.dry_time = -1;
- ip->fdata.raster_graphics_quality = -1;
- ip->fdata.shingling = -1;
-
- ip->fdata.NULs_to_send = NULs_to_send;
- ip->fdata.PJL_language = PJL_language;
- ip->fdata.PJL_job = PJL_job;
- }
- break;
- default:
- return 1;
- }
- return 0;
- }
-
- /* Parameterized escape sequences */
- strncpy(key.cmd, cmd->chars, 3);
- entry = (const ActionEntry *)bsearch(&key, action_table,
- sizeof(action_table)/sizeof(ActionEntry), sizeof(ActionEntry), cmp_entries);
- if (entry != NULL) return (*entry->action)(in, cmd, ip);
-
- return 1;
-}
-
-/******************************************************************************
-
- Function: work
-
- On errors, the return value is positive, on success it is zero.
-
-******************************************************************************/
-
-static int work(FILE *in, FILE *out) /* NLS: 50 */
-{
- CollectedInfo info;
- int rc;
-
- memset(&info, 0, sizeof(CollectedInfo));
- info.out = out;
- info.fdata.duplex = -1;
- info.fdata.dry_time = -1;
- info.fdata.raster_graphics_quality = -1;
- info.fdata.shingling = -1;
-
- rc = pcl_scan(in, &analyzer, &info, NULL, NULL);
- if (rc != 0) return 1;
-
- if (info.number_of_outputs == 0) {
- emessage(50,
- "This does not seem to be a PCL file containing raster data.\n");
- return 1;
- }
-
- return 0;
-}
-
-/******************************************************************************
-
- Function: main
-
- Usage: pcl3opts <options> <input files>
- <option> ::= '-o' <output file>
- <input files> ::= <empty> | <input file> <input files>
-
-******************************************************************************/
-
-int main(int argc, char **argv)
-{
- char
- *outfile_name = NULL;
- FILE
- *outfile,
- *infile;
- int
- c,
- errors = 0,
- number_of_infiles;
-
-#ifndef NDEBUG
- {
- int j;
-
- for (j = 1; j < sizeof(action_table)/sizeof(ActionEntry); j++)
- assert(cmp_entries(action_table + (j - 1), action_table + j) < 0);
- }
-#endif /* !NDEBUG */
-
- /* Set the locale depending on the environment */
- setlocale(LC_ALL, "");
- catd = catopen("pcl3opts", 0);
-
- puts("*** pcl3opts\n"); /* Note that puts() appends another '\n'. */
-
- /* Set the program's name. We assume: argc <= 0 || parts(argv) >= 1. */
- if (argc <= 0 || argv[0] == NULL || argv[0][0] == '\0')
- progname = "pcl3opts";
- else {
- if ((progname = strrchr(argv[0], '/')) == NULL || progname[1] == '\0')
- progname = argv[0];
- else
- progname++;
- }
-
- /* Parse the options */
- while ((c = getopt(argc, argv, "o:")) != EOF) {
- switch(c) {
- case 'o':
- outfile_name = optarg;
- break;
- default:
- errors++;
- break;
- }
- }
-
- /* Leave on errors in the command line */
- if (errors > 0) {
- emessage(1, "Usage: %s [<options>] [<input files>].\n"
- " <option> ::= -o <output file>\n",
- progname);
- exit(EXIT_FAILURE);
- }
-
- /* Open the output file */
- if (outfile_name == NULL) outfile = stdout;
- else {
- outfile = fopen(outfile_name, "w");
- if (outfile == NULL) {
- emessage(2, "The file `%s' could not be opened for writing:\n %s.\n",
- outfile_name, strerror(errno));
- exit(EXIT_FAILURE);
- }
- }
-
- /* Loop over the input files */
- number_of_infiles = argc - optind;
- if (number_of_infiles <= 0) errors += work(stdin, outfile);
- else do {
- char *infile_name;
-
- /* Open */
- infile_name = argv[optind];
- infile = fopen(infile_name, "rb");
- if (infile == NULL) {
- emessage(3, "Could not open the input file `%s':\n %s.\n",
- infile_name, strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- if (number_of_infiles > 1) fprintf(outfile, "*** %s:\n", infile_name);
- errors += work(infile, outfile);
-
- /* Close */
- if (fclose(infile) != 0) {
- emessage(4, "Error closing `%s':\n %s.\n",
- infile_name, strerror(errno));
- errors++;
- }
- optind++;
- if (errors == 0 && optind < argc) fputs("\n", outfile);
- } while (errors == 0 && optind < argc);
-
- /* Close the output file */
- if (fclose(outfile) != 0) {
- emessage(4, "Error closing `%s':\n %s.\n",
- outfile_name == NULL? "[standard output]": outfile_name, strerror(errno));
- errors++;
- }
-
- catclose(catd);
-
- exit(errors == 0? EXIT_SUCCESS: EXIT_FAILURE);
-}