diff options
Diffstat (limited to 'gs/contrib/pcl3/src/pcl3opts.c')
-rw-r--r-- | gs/contrib/pcl3/src/pcl3opts.c | 1176 |
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); -} |