📄 pcl3opts.c
字号:
/****************************************************************************** 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 lintstatic 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");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -