/epstool-3.08/src/dscparse.c
C | 4598 lines | 3741 code | 313 blank | 544 comment | 1355 complexity | a3c4c56321097b58b651c817c1f23449 MD5 | raw file
Possible License(s): GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /* Copyright (C) 2000-2005, Ghostgum Software Pty Ltd. All rights reserved.
-
- This file is part of GSview.
-
- This program is distributed with NO WARRANTY OF ANY KIND. No author
- or distributor accepts any responsibility for the consequences of using it,
- or for whether it serves any particular purpose or works at all, unless he
- or she says so in writing. Refer to the GSview Licence (the "Licence")
- for full details.
-
- Every copy of GSview must include a copy of the Licence, normally in a
- plain ASCII text file named LICENCE. The Licence grants you the right
- to copy, modify and redistribute GSview, but only under certain conditions
- described in the Licence. Among other things, the Licence requires that
- the copyright notice and this notice be preserved on all copies.
- */
- /* $Id: dscparse.c,v 1.36 2005/01/20 11:19:00 ghostgum Exp $ */
- /*
- * This is a DSC parser, based on the DSC 3.0 spec,
- * with a few DSC 2.1 additions for page size.
- *
- * Current limitations:
- * %%+ may be used after any comment in the comment or trailer,
- * but is currently only supported by
- * %%DocumentMedia
- *
- * DSC 2.1 additions (discontinued in DSC 3.0):
- * %%DocumentPaperColors:
- * %%DocumentPaperForms:
- * %%DocumentPaperSizes:
- * %%DocumentPaperWeights:
- * %%PaperColor: (ignored)
- * %%PaperForm: (ignored)
- * %%PaperSize:
- * %%PaperWeight: (ignored)
- *
- * Other additions for defaults or page section
- % %%ViewingOrientation: xx xy yx yy
- */
- #include <stdio.h> /* for sprintf(), not file I/O */
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #define MAXSTR 256
- #include "dscparse.h"
- /* Macros for comparing string literals
- * For maximum speed, the length of the second macro argument is
- * computed at compile time.
- * THE SECOND MACRO ARGUMENT MUST BE A STRING LITERAL.
- */
- #define COMPARE(p,str) (strncmp((const char *)(p), (str), sizeof(str)-1)==0)
- #define IS_DSC(line, str) (COMPARE((line), (str)))
- /* Macros for comparing the first one or two characters */
- #define IS_WHITE(ch) (((ch)==' ') || ((ch)=='\t'))
- #define IS_EOL(ch) (((ch)=='\r') || ((ch)=='\n'))
- #define IS_WHITE_OR_EOL(ch) (IS_WHITE(ch) || IS_EOL(ch))
- #define IS_BLANK(str) (IS_EOL(str[0]))
- #define NOT_DSC_LINE(str) (((str)[0]!='%') || ((str)[1]!='%'))
- /* Macros for document offset to start and end of line */
- #define DSC_START(dsc) ((dsc)->data_offset + (dsc)->data_index - (dsc)->line_length)
- #define DSC_END(dsc) ((dsc)->data_offset + (dsc)->data_index)
- /* dsc_scan_SECTION() functions return one of
- * CDSC_ERROR, CDSC_OK, CDSC_NOTDSC
- * or one of the following
- */
- /* The line should be passed on to the next section parser. */
- #define CDSC_PROPAGATE 10
- /* If document is DOS EPS and we haven't read 30 bytes, ask for more. */
- #define CDSC_NEEDMORE 11
- /* local prototypes */
- dsc_private void * dsc_memalloc(CDSC *dsc, size_t size);
- dsc_private void dsc_memfree(CDSC*dsc, void *ptr);
- dsc_private CDSC * dsc_init2(CDSC *dsc);
- dsc_private void dsc_reset(CDSC *dsc);
- dsc_private void dsc_section_join(DSC_OFFSET begin, DSC_OFFSET *pend, DSC_OFFSET **pplast);
- dsc_private int dsc_read_line(CDSC *dsc);
- dsc_private int dsc_read_doseps(CDSC *dsc);
- dsc_private int dsc_read_macbin(CDSC *dsc);
- dsc_private int dsc_read_applesingle(CDSC *dsc);
- dsc_private char * dsc_alloc_string(CDSC *dsc, const char *str, int len);
- dsc_private char * dsc_add_line(CDSC *dsc, const char *line, unsigned int len);
- dsc_private char * dsc_copy_string(char *str, unsigned int slen,
- char *line, unsigned int len, unsigned int *offset);
- dsc_private GSDWORD dsc_get_dword(const unsigned char *buf);
- dsc_private GSWORD dsc_get_word(const unsigned char *buf);
- dsc_private GSDWORD dsc_get_bigendian_dword(const unsigned char *buf);
- dsc_private GSWORD dsc_get_bigendian_word(const unsigned char *buf);
- dsc_private int dsc_get_int(const char *line, unsigned int len, unsigned int *offset);
- dsc_private float dsc_get_real(const char *line, unsigned int len,
- unsigned int *offset);
- dsc_private void dsc_unknown(CDSC *dsc);
- dsc_private GSBOOL dsc_is_section(char *line);
- dsc_private int dsc_parse_pages(CDSC *dsc);
- dsc_private int dsc_parse_feature(CDSC *dsc);
- dsc_private int dsc_parse_bounding_box(CDSC *dsc, CDSCBBOX** pbbox, int offset);
- dsc_private int dsc_parse_float_bounding_box(CDSC *dsc, CDSCFBBOX** pfbbox, int offset);
- dsc_private int dsc_parse_orientation(CDSC *dsc, unsigned int *porientation,
- int offset);
- dsc_private int dsc_parse_order(CDSC *dsc);
- dsc_private int dsc_parse_media(CDSC *dsc, const CDSCMEDIA **page_media);
- dsc_private int dsc_parse_document_media(CDSC *dsc);
- dsc_private int dsc_parse_viewing_orientation(CDSC *dsc, CDSCCTM **pctm);
- dsc_private int dsc_parse_page(CDSC *dsc);
- dsc_private void dsc_save_line(CDSC *dsc);
- dsc_private int dsc_scan_type(CDSC *dsc);
- dsc_private int dsc_scan_comments(CDSC *dsc);
- dsc_private int dsc_scan_preview(CDSC *dsc);
- dsc_private int dsc_scan_defaults(CDSC *dsc);
- dsc_private int dsc_scan_prolog(CDSC *dsc);
- dsc_private int dsc_scan_setup(CDSC *dsc);
- dsc_private int dsc_scan_page(CDSC *dsc);
- dsc_private int dsc_scan_trailer(CDSC *dsc);
- dsc_private int dsc_error(CDSC *dsc, unsigned int explanation,
- char *line, unsigned int line_len);
- dsc_private int dsc_dcs2_fixup(CDSC *dsc);
- dsc_private int dsc_parse_platefile(CDSC *dsc);
- dsc_private int dsc_parse_dcs1plate(CDSC *dsc);
- dsc_private CDSCCOLOUR * dsc_find_colour(CDSC *dsc, const char *colourname);
- dsc_private int dsc_parse_process_colours(CDSC *dsc);
- dsc_private int dsc_parse_custom_colours(CDSC *dsc);
- dsc_private int dsc_parse_cmyk_custom_colour(CDSC *dsc);
- dsc_private int dsc_parse_rgb_custom_colour(CDSC *dsc);
- /* DSC error reporting */
- dsc_private const int dsc_severity[] = {
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_BBOX */
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_EARLY_TRAILER */
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_EARLY_EOF */
- CDSC_ERROR_ERROR, /* CDSC_MESSAGE_PAGE_IN_TRAILER */
- CDSC_ERROR_ERROR, /* CDSC_MESSAGE_PAGE_ORDINAL */
- CDSC_ERROR_ERROR, /* CDSC_MESSAGE_PAGES_WRONG */
- CDSC_ERROR_ERROR, /* CDSC_MESSAGE_EPS_NO_BBOX */
- CDSC_ERROR_ERROR, /* CDSC_MESSAGE_EPS_PAGES */
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_NO_MEDIA */
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_ATEND */
- CDSC_ERROR_INFORM, /* CDSC_MESSAGE_DUP_COMMENT */
- CDSC_ERROR_INFORM, /* CDSC_MESSAGE_DUP_TRAILER */
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_BEGIN_END */
- CDSC_ERROR_INFORM, /* CDSC_MESSAGE_BAD_SECTION */
- CDSC_ERROR_INFORM, /* CDSC_MESSAGE_LONG_LINE */
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_INCORRECT_USAGE */
- 0
- };
- #define DSC_MAX_ERROR ((sizeof(dsc_severity) / sizeof(int))-2)
- const CDSCMEDIA dsc_known_media[CDSC_KNOWN_MEDIA] = {
- /* These sizes taken from Ghostscript gs_statd.ps */
- {"11x17", 792, 1224, 0, NULL, NULL, NULL},
- {"A3", 842, 1190, 0, NULL, NULL, NULL},
- {"A4", 595, 842, 0, NULL, NULL, NULL},
- {"A5", 421, 595, 0, NULL, NULL, NULL},
- {"B4", 709, 1002, 0, NULL, NULL, NULL}, /* ISO, but not Adobe standard */
- {"B5", 501, 709, 0, NULL, NULL, NULL}, /* ISO, but not Adobe standard */
- {"Ledger", 1224, 792, 0, NULL, NULL, NULL},
- {"Legal", 612, 1008, 0, NULL, NULL, NULL},
- {"Letter", 612, 792, 0, NULL, NULL, NULL},
- {"Note", 612, 792, 0, NULL, NULL, NULL},
- /* Other standard sizes */
- {"A0", 2384, 3370, 0, NULL, NULL, NULL},
- {"A1", 1684, 2384, 0, NULL, NULL, NULL},
- {"A2", 1190, 1684, 0, NULL, NULL, NULL},
- /* Other non-standard sizes */
- {"AnsiA", 612, 792, 0, NULL, NULL, NULL}, /* 8.5 x 11" */
- {"AnsiB", 792, 1224, 0, NULL, NULL, NULL}, /* 11 x 17" */
- {"AnsiC", 1224, 1584, 0, NULL, NULL, NULL}, /* 17 x 22" */
- {"AnsiD", 1584, 2448, 0, NULL, NULL, NULL}, /* 22 x 34" */
- {"AnsiE", 2448, 3168, 0, NULL, NULL, NULL}, /* 34 x 44" */
- {"ArchA", 648, 864, 0, NULL, NULL, NULL}, /* 9 x 12" */
- {"ArchB", 864, 1296, 0, NULL, NULL, NULL}, /* 12 x 18" */
- {"ArchC", 1296, 1728, 0, NULL, NULL, NULL}, /* 18 x 24" */
- {"ArchD", 1728, 2592, 0, NULL, NULL, NULL}, /* 24 x 36" */
- {"ArchE", 2592, 3456, 0, NULL, NULL, NULL}, /* 36 x 48" */
- {"ArchF", 2160, 3024, 0, NULL, NULL, NULL}, /* 30 x 42" */
- {NULL, 0, 0, 0, NULL, NULL, NULL}
- };
- /* parser state */
- enum CDSC_SCAN_SECTION {
- scan_none = 0,
- scan_comments = 1,
- scan_pre_preview = 2,
- scan_preview = 3,
- scan_pre_defaults = 4,
- scan_defaults = 5,
- scan_pre_prolog = 6,
- scan_prolog = 7,
- scan_pre_setup = 8,
- scan_setup = 9,
- scan_pre_pages = 10,
- scan_pages = 11,
- scan_pre_trailer = 12,
- scan_trailer = 13,
- scan_eof = 14
- };
- static const char * const dsc_scan_section_name[15] = {
- "Type", "Comments",
- "pre-Preview", "Preview",
- "pre-Defaults", "Defaults",
- "pre-Prolog", "Prolog",
- "pre-Setup", "Setup",
- "pre-Page", "Page",
- "pre-Trailer", "Trailer",
- "EOF"
- };
- /******************************************************************/
- /* Public functions */
- /******************************************************************/
- /* constructor */
- CDSC *
- dsc_init(void *caller_data)
- {
- CDSC *dsc = (CDSC *)malloc(sizeof(CDSC));
- if (dsc == NULL)
- return NULL;
- memset(dsc, 0, sizeof(CDSC));
- dsc->caller_data = caller_data;
- dsc->ref_count = 0;
- dsc_ref(dsc);
- return dsc_init2(dsc);
- }
- /* constructor, with caller supplied memalloc */
- CDSC *
- dsc_init_with_alloc(
- void *caller_data,
- void *(*memalloc)(size_t size, void *closure_data),
- void (*memfree)(void *ptr, void *closure_data),
- void *closure_data)
- {
- CDSC *dsc = (CDSC *)memalloc(sizeof(CDSC), closure_data);
- if (dsc == NULL)
- return NULL;
- memset(dsc, 0, sizeof(CDSC));
- dsc->caller_data = caller_data;
- dsc->memalloc = memalloc;
- dsc->memfree = memfree;
- dsc->mem_closure_data = closure_data;
- dsc->ref_count = 0;
- dsc_ref(dsc);
-
- return dsc_init2(dsc);
- }
- /* destructor */
- void
- dsc_free(CDSC *dsc)
- {
- if (dsc == NULL)
- return;
- dsc_reset(dsc);
- dsc_memfree(dsc, dsc);
- }
- CDSC *
- dsc_new(void *caller_data)
- {
- return dsc_init(caller_data);
- }
- int
- dsc_ref(CDSC *dsc)
- {
- return ++(dsc->ref_count);
- }
- int
- dsc_unref(CDSC *dsc)
- {
- if (dsc->ref_count <= 0)
- return -1;
- dsc->ref_count--;
- if (dsc->ref_count == 0) {
- dsc_free(dsc);
- return 0;
- }
- return dsc->ref_count;
- }
- /* Tell DSC parser how long document will be, to allow ignoring
- * of early %%Trailer and %%EOF. This is optional.
- */
- void
- dsc_set_length(CDSC *dsc, DSC_OFFSET len)
- {
- dsc->file_length = len;
- }
- /* Process a buffer containing DSC comments and PostScript */
- /* Return value is < 0 for error, >=0 for OK.
- * CDSC_ERROR
- * CDSC_OK
- * CDSC_NOTDSC (DSC will be ignored)
- * other values indicate the last DSC comment read
- */
- int
- dsc_scan_data(CDSC *dsc, const char *data, int length)
- {
- int bytes_read;
- int code = 0;
- if (dsc == NULL)
- return CDSC_ERROR;
- if (dsc->id == CDSC_NOTDSC)
- return CDSC_NOTDSC;
- dsc->id = CDSC_OK;
- if (dsc->eof)
- return CDSC_OK; /* ignore */
- if (length == 0) {
- /* EOF, so process what remains */
- dsc->eof = TRUE;
- }
- do {
- if (dsc->id == CDSC_NOTDSC)
- break;
- if (length != 0) {
- /* move existing data if needed */
- if (dsc->data_length > CDSC_DATA_LENGTH/2) {
- memmove(dsc->data, dsc->data + dsc->data_index,
- dsc->data_length - dsc->data_index);
- dsc->data_offset += dsc->data_index;
- dsc->data_length -= dsc->data_index;
- dsc->data_index = 0;
- }
- /* append to buffer */
- bytes_read = min(length, (int)(CDSC_DATA_LENGTH - dsc->data_length));
- memcpy(dsc->data + dsc->data_length, data, bytes_read);
- dsc->data_length += bytes_read;
- data += bytes_read;
- length -= bytes_read;
- }
- if (dsc->scan_section == scan_none) {
- code = dsc_scan_type(dsc);
- if (code == CDSC_NEEDMORE) {
- /* need more characters before we can identify type */
- code = CDSC_OK;
- break;
- }
- dsc->id = code;
- }
- if (code == CDSC_NOTDSC) {
- dsc->id = CDSC_NOTDSC;
- break;
- }
- while ((code = dsc_read_line(dsc)) > 0) {
- if (dsc->id == CDSC_NOTDSC)
- break;
- if (dsc->file_length &&
- (dsc->data_offset + dsc->data_index > dsc->file_length)) {
- /* have read past end of where we need to parse. */
- return CDSC_OK; /* ignore */
- }
- if (dsc->doseps_end &&
- (dsc->data_offset + dsc->data_index > dsc->doseps_end)) {
- /* have read past end of DOS EPS or Mac Binary
- * PostScript section
- */
- return CDSC_OK; /* ignore */
- }
- if (dsc->eof)
- return CDSC_OK;
- if (dsc->skip_document)
- continue; /* embedded document */
- if (dsc->skip_lines)
- continue; /* embedded lines */
- if (IS_DSC(dsc->line, "%%BeginData:"))
- continue;
- if (IS_DSC(dsc->line, "%%BeginBinary:"))
- continue;
- if (IS_DSC(dsc->line, "%%EndDocument"))
- continue;
- if (IS_DSC(dsc->line, "%%EndData"))
- continue;
- if (IS_DSC(dsc->line, "%%EndBinary"))
- continue;
- do {
- switch (dsc->scan_section) {
- case scan_comments:
- code = dsc_scan_comments(dsc);
- break;
- case scan_pre_preview:
- case scan_preview:
- code = dsc_scan_preview(dsc);
- break;
- case scan_pre_defaults:
- case scan_defaults:
- code = dsc_scan_defaults(dsc);
- break;
- case scan_pre_prolog:
- case scan_prolog:
- code = dsc_scan_prolog(dsc);
- break;
- case scan_pre_setup:
- case scan_setup:
- code = dsc_scan_setup(dsc);
- break;
- case scan_pre_pages:
- case scan_pages:
- code = dsc_scan_page(dsc);
- break;
- case scan_pre_trailer:
- case scan_trailer:
- code = dsc_scan_trailer(dsc);
- break;
- case scan_eof:
- code = CDSC_OK;
- break;
- default:
- /* invalid state */
- code = CDSC_ERROR;
- }
- /* repeat if line is start of next section */
- } while (code == CDSC_PROPAGATE);
- /* if DOS EPS header not complete, ask for more */
- if (code == CDSC_NEEDMORE) {
- code = CDSC_OK;
- break;
- }
- if (code == CDSC_NOTDSC) {
- dsc->id = CDSC_NOTDSC;
- break;
- }
- }
- } while (length != 0);
- return (code < 0) ? code : dsc->id;
- }
- /* Tidy up from incorrect DSC comments */
- int
- dsc_fixup(CDSC *dsc)
- {
- unsigned int i;
- char buf[32];
- DSC_OFFSET *last;
- if (dsc->id == CDSC_NOTDSC)
- return 0;
- /* flush last partial line */
- dsc_scan_data(dsc, NULL, 0);
- /* Fix DSC error: EOF before end of %%BeginData */
- if (dsc->eof &&
- (dsc->skip_lines || dsc->skip_bytes || dsc->skip_document)) {
- switch (dsc->scan_section) {
- case scan_comments:
- dsc->endcomments = DSC_END(dsc);
- break;
- case scan_preview:
- dsc->endpreview = DSC_END(dsc);
- break;
- case scan_defaults:
- dsc->enddefaults = DSC_END(dsc);
- break;
- case scan_prolog:
- dsc->endprolog = DSC_END(dsc);
- break;
- case scan_setup:
- dsc->endsetup = DSC_END(dsc);
- break;
- case scan_pages:
- if (dsc->page_count)
- dsc->page[dsc->page_count-1].end = DSC_END(dsc);
- break;
- case scan_trailer:
- case scan_eof:
- dsc->endtrailer = DSC_END(dsc);
- break;
- }
- }
-
- /* Fix DSC error: code between %%EndSetup and %%Page */
- if (dsc->page_count && (dsc->page[0].begin != dsc->endsetup)
- && (dsc->endsetup != dsc->beginsetup)) {
- dsc->endsetup = dsc->page[0].begin;
- dsc_debug_print(dsc, "Warning: code included between setup and first page\n");
- }
- /* Last page contained a false trailer, */
- /* so extend last page to start of trailer */
- if (dsc->page_count && (dsc->begintrailer != 0) &&
- (dsc->page[dsc->page_count-1].end != dsc->begintrailer)) {
- dsc_debug_print(dsc, "Ignoring earlier misplaced trailer\n");
- dsc_debug_print(dsc, "and extending last page to start of trailer\n");
- dsc->page[dsc->page_count-1].end = dsc->begintrailer;
- }
- /*
- * Join up all sections.
- * There might be extra code between them, or we might have
- * missed including the \n which followed \r.
- */
- last = &dsc->endcomments;
- dsc_section_join(dsc->beginpreview, &dsc->endpreview, &last);
- dsc_section_join(dsc->begindefaults, &dsc->enddefaults, &last);
- dsc_section_join(dsc->beginprolog, &dsc->endprolog, &last);
- dsc_section_join(dsc->beginsetup, &dsc->endsetup, &last);
- for (i=0; i<dsc->page_count; i++)
- dsc_section_join(dsc->page[i].begin, &dsc->page[i].end, &last);
- if (dsc->begintrailer)
- *last = dsc->begintrailer;
-
- if ((dsc->page_pages == 0) && (dsc->page_count == 1)) {
- /* don't flag an error if %%Pages absent but one %%Page found */
- /* adjust incorrect page count */
- dsc->page_pages = dsc->page_count;
- }
- /* Warnings and Errors that we can now identify */
- if ((dsc->page_count != dsc->page_pages)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_PAGES_WRONG, NULL, 0);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* adjust incorrect page count */
- dsc->page_pages = dsc->page_count;
- break;
- case CDSC_RESPONSE_CANCEL:
- break;;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if (dsc->epsf && (dsc->bbox == (CDSCBBOX *)NULL)) {
- /* EPS files MUST include a BoundingBox */
- int rc = dsc_error(dsc, CDSC_MESSAGE_EPS_NO_BBOX, NULL, 0);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* Assume that it is EPS */
- break;
- case CDSC_RESPONSE_CANCEL:
- /* Is NOT an EPS file */
- dsc->epsf = FALSE;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if (dsc->epsf && ((dsc->page_count > 1) || (dsc->page_pages > 1))) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_EPS_PAGES, NULL, 0);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* Is an EPS file */
- break;
- case CDSC_RESPONSE_CANCEL:
- /* Is NOT an EPS file */
- dsc->epsf = FALSE;
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- /* convert single file DSC 2.0 into multiple pages */
- dsc_dcs2_fixup(dsc);
- if ((dsc->media_count == 1) && (dsc->page_media == NULL)) {
- /* if one only media was specified, and default page media */
- /* was not specified, assume that default is the only media. */
- dsc->page_media = dsc->media[0];
- }
- if ((dsc->media_count != 0) && (dsc->page_media == NULL)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_NO_MEDIA, NULL, 0);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* default media is first listed */
- dsc->page_media = dsc->media[0];
- break;
- case CDSC_RESPONSE_CANCEL:
- /* No default media */
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- /* make sure all pages have a label */
- for (i=0; i<dsc->page_count; i++) {
- if (strlen(dsc->page[i].label) == 0) {
- sprintf(buf, "%d", i+1);
- if ((dsc->page[i].label = dsc_alloc_string(dsc, buf, (int)strlen(buf)))
- == (char *)NULL)
- return CDSC_ERROR; /* no memory */
- }
- }
- return CDSC_OK;
- }
- /* Install a function to be used for displaying messages about
- * DSC errors and warnings, and to request advice from user.
- * Installing an error function is optional.
- */
- void
- dsc_set_error_function(CDSC *dsc,
- int (*fn)(void *caller_data, CDSC *dsc,
- unsigned int explanation, const char *line, unsigned int line_len))
- {
- dsc->dsc_error_fn = fn;
- }
- /* Install a function for printing debug messages */
- /* This is optional */
- void
- dsc_set_debug_function(CDSC *dsc,
- void (*debug_fn)(void *caller_data, const char *str))
- {
- dsc->debug_print_fn = debug_fn;
- }
- /* Doesn't need to be public for PostScript documents */
- /* Made public so GSview can add pages when processing PDF files */
- int
- dsc_add_page(CDSC *dsc, int ordinal, char *label)
- {
- dsc->page[dsc->page_count].ordinal = ordinal;
- dsc->page[dsc->page_count].label =
- dsc_alloc_string(dsc, label, (int)strlen(label)+1);
- dsc->page[dsc->page_count].begin = 0;
- dsc->page[dsc->page_count].end = 0;
- dsc->page[dsc->page_count].orientation = CDSC_ORIENT_UNKNOWN;
- dsc->page[dsc->page_count].media = NULL;
- dsc->page[dsc->page_count].bbox = NULL;
- dsc->page[dsc->page_count].viewing_orientation = NULL;
- dsc->page[dsc->page_count].crop_box = NULL;
- dsc->page_count++;
- if (dsc->page_count >= dsc->page_chunk_length) {
- CDSCPAGE *new_page = (CDSCPAGE *)dsc_memalloc(dsc,
- (CDSC_PAGE_CHUNK+dsc->page_count) * sizeof(CDSCPAGE));
- if (new_page == NULL)
- return CDSC_ERROR; /* out of memory */
- memcpy(new_page, dsc->page,
- dsc->page_count * sizeof(CDSCPAGE));
- dsc_memfree(dsc, dsc->page);
- dsc->page= new_page;
- dsc->page_chunk_length = CDSC_PAGE_CHUNK+dsc->page_count;
- }
- return CDSC_OK;
- }
- /* Doesn't need to be public for PostScript documents */
- /* Made public so GSview can store PDF MediaBox */
- int
- dsc_add_media(CDSC *dsc, CDSCMEDIA *media)
- {
- CDSCMEDIA **newmedia_array;
- CDSCMEDIA *newmedia;
- /* extend media array */
- newmedia_array = (CDSCMEDIA **)dsc_memalloc(dsc,
- (dsc->media_count + 1) * sizeof(CDSCMEDIA *));
- if (newmedia_array == NULL)
- return CDSC_ERROR; /* out of memory */
- if (dsc->media != NULL) {
- memcpy(newmedia_array, dsc->media,
- dsc->media_count * sizeof(CDSCMEDIA *));
- dsc_memfree(dsc, dsc->media);
- }
- dsc->media = newmedia_array;
- /* allocate new media */
- newmedia = dsc->media[dsc->media_count] =
- (CDSCMEDIA *)dsc_memalloc(dsc, sizeof(CDSCMEDIA));
- if (newmedia == NULL)
- return CDSC_ERROR; /* out of memory */
- newmedia->name = NULL;
- newmedia->width = 595.0;
- newmedia->height = 842.0;
- newmedia->weight = 80.0;
- newmedia->colour = NULL;
- newmedia->type = NULL;
- newmedia->mediabox = NULL;
- dsc->media_count++;
- if (media->name) {
- newmedia->name = dsc_alloc_string(dsc, media->name,
- (int)strlen(media->name));
- if (newmedia->name == NULL)
- return CDSC_ERROR; /* no memory */
- }
- newmedia->width = media->width;
- newmedia->height = media->height;
- newmedia->weight = media->weight;
- if (media->colour) {
- newmedia->colour = dsc_alloc_string(dsc, media->colour,
- (int)strlen(media->colour));
- if (newmedia->colour == NULL)
- return CDSC_ERROR; /* no memory */
- }
- if (media->type) {
- newmedia->type = dsc_alloc_string(dsc, media->type,
- (int)strlen(media->type));
- if (newmedia->type == NULL)
- return CDSC_ERROR; /* no memory */
- }
- newmedia->mediabox = NULL;
- if (media->mediabox) {
- newmedia->mediabox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
- if (newmedia->mediabox == NULL)
- return CDSC_ERROR; /* no memory */
- *newmedia->mediabox = *media->mediabox;
- }
- return CDSC_OK;
- }
- /* Doesn't need to be public for PostScript documents */
- /* Made public so GSview can store PDF CropBox */
- int
- dsc_set_page_bbox(CDSC *dsc, unsigned int page_number,
- int llx, int lly, int urx, int ury)
- {
- CDSCBBOX *bbox;
- if (page_number >= dsc->page_count)
- return CDSC_ERROR;
- bbox = dsc->page[page_number].bbox;
- if (bbox == NULL)
- dsc->page[page_number].bbox = bbox =
- (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
- if (bbox == NULL)
- return CDSC_ERROR;
- bbox->llx = llx;
- bbox->lly = lly;
- bbox->urx = urx;
- bbox->ury = ury;
- return CDSC_OK;
- }
- /******************************************************************/
- /* Private functions below here. */
- /******************************************************************/
- dsc_private void *
- dsc_memalloc(CDSC *dsc, size_t size)
- {
- if (dsc->memalloc)
- return dsc->memalloc(size, dsc->mem_closure_data);
- return malloc(size);
- }
- dsc_private void
- dsc_memfree(CDSC*dsc, void *ptr)
- {
- if (dsc->memfree)
- dsc->memfree(ptr, dsc->mem_closure_data);
- else
- free(ptr);
- }
- /* private constructor */
- dsc_private CDSC *
- dsc_init2(CDSC *dsc)
- {
- dsc_reset(dsc);
- dsc->string_head = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
- if (dsc->string_head == NULL) {
- dsc_free(dsc);
- return NULL; /* no memory */
- }
- dsc->string = dsc->string_head;
- dsc->string->next = NULL;
- dsc->string->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
- if (dsc->string->data == NULL) {
- dsc_free(dsc);
- return NULL; /* no memory */
- }
- dsc->string->index = 0;
- dsc->string->length = CDSC_STRING_CHUNK;
-
- dsc->page = (CDSCPAGE *)dsc_memalloc(dsc, CDSC_PAGE_CHUNK * sizeof(CDSCPAGE));
- if (dsc->page == NULL) {
- dsc_free(dsc);
- return NULL; /* no memory */
- }
- dsc->page_chunk_length = CDSC_PAGE_CHUNK;
- dsc->page_count = 0;
-
- dsc->line = NULL;
- dsc->data_length = 0;
- dsc->data_index = dsc->data_length;
- return dsc;
- }
- dsc_private void
- dsc_reset(CDSC *dsc)
- {
- unsigned int i;
- /* Clear public members */
- dsc->dsc = FALSE;
- dsc->ctrld = FALSE;
- dsc->pjl = FALSE;
- dsc->epsf = FALSE;
- dsc->pdf = FALSE;
- dsc->epsf = FALSE;
- dsc->preview = CDSC_NOPREVIEW;
- dsc->dsc_version = NULL; /* stored in dsc->string */
- dsc->language_level = 0;
- dsc->document_data = CDSC_DATA_UNKNOWN;
- dsc->begincomments = 0;
- dsc->endcomments = 0;
- dsc->beginpreview = 0;
- dsc->endpreview = 0;
- dsc->begindefaults = 0;
- dsc->enddefaults = 0;
- dsc->beginprolog = 0;
- dsc->endprolog = 0;
- dsc->beginsetup = 0;
- dsc->endsetup = 0;
- dsc->begintrailer = 0;
- dsc->endtrailer = 0;
-
- for (i=0; i<dsc->page_count; i++) {
- /* page media is pointer to an element of media or dsc_known_media */
- /* do not free it. */
- if (dsc->page[i].bbox)
- dsc_memfree(dsc, dsc->page[i].bbox);
- if (dsc->page[i].viewing_orientation)
- dsc_memfree(dsc, dsc->page[i].viewing_orientation);
- if (dsc->page[i].crop_box)
- dsc_memfree(dsc, dsc->page[i].crop_box);
- }
- if (dsc->page)
- dsc_memfree(dsc, dsc->page);
- dsc->page = NULL;
-
- dsc->page_count = 0;
- dsc->page_pages = 0;
- dsc->page_order = CDSC_ORDER_UNKNOWN;
- dsc->page_orientation = CDSC_ORIENT_UNKNOWN;
- if (dsc->viewing_orientation)
- dsc_memfree(dsc, dsc->viewing_orientation);
- dsc->viewing_orientation = NULL;
-
- if (dsc->media) {
- for (i=0; i<dsc->media_count; i++) {
- if (dsc->media[i]) {
- if (dsc->media[i]->mediabox)
- dsc_memfree(dsc, dsc->media[i]->mediabox);
- dsc_memfree(dsc, dsc->media[i]);
- }
- }
- dsc_memfree(dsc, dsc->media);
- }
- dsc->media_count = 0;
- dsc->media = NULL;
- /* page_media is pointer to an element of media or dsc_known_media */
- /* do not free it. */
- dsc->page_media = NULL;
- if (dsc->bbox)
- dsc_memfree(dsc, dsc->bbox);
- dsc->bbox = NULL;
- if (dsc->page_bbox)
- dsc_memfree(dsc, dsc->page_bbox);
- dsc->page_bbox = NULL;
- if (dsc->doseps)
- dsc_memfree(dsc, dsc->doseps);
- dsc->doseps = NULL;
-
- dsc->dsc_title = NULL;
- dsc->dsc_creator = NULL;
- dsc->dsc_date = NULL;
- dsc->dsc_for = NULL;
-
- dsc->max_error = DSC_MAX_ERROR;
- dsc->severity = dsc_severity;
- /* Clear private members */
- /* Don't touch dsc->caller_data */
- dsc->id = CDSC_OK;
- dsc->scan_section = scan_none;
- dsc->doseps_end = 0;
- dsc->page_chunk_length = 0;
- dsc->file_length = 0;
- dsc->skip_document = 0;
- dsc->skip_bytes = 0;
- dsc->skip_lines = 0;
- dsc->skip_pjl = 0;
- dsc->begin_font_count = 0;
- dsc->begin_feature_count = 0;
- dsc->begin_resource_count = 0;
- dsc->begin_procset_count = 0;
- dsc->data_length = 0;
- dsc->data_index = 0;
- dsc->data_offset = 0;
- dsc->eof = 0;
-
- dsc->line = 0;
- dsc->line_length = 0;
- dsc->eol = 0;
- dsc->last_cr = FALSE;
- dsc->line_count = 1;
- dsc->long_line = FALSE;
- memset(dsc->last_line, 0, sizeof(dsc->last_line));
- dsc->string = dsc->string_head;
- while (dsc->string != (CDSCSTRING *)NULL) {
- if (dsc->string->data)
- dsc_memfree(dsc, dsc->string->data);
- dsc->string_head = dsc->string;
- dsc->string = dsc->string->next;
- dsc_memfree(dsc, dsc->string_head);
- }
- dsc->string_head = NULL;
- dsc->string = NULL;
- /* don't touch caller functions */
- /* public data */
- if (dsc->hires_bbox)
- dsc_memfree(dsc, dsc->hires_bbox);
- dsc->hires_bbox = NULL;
- if (dsc->crop_box)
- dsc_memfree(dsc, dsc->crop_box);
- dsc->crop_box = NULL;
- if (dsc->dcs2) {
- CDCS2 *this_dcs, *next_dcs;
- this_dcs = dsc->dcs2;
- while (this_dcs) {
- next_dcs = this_dcs->next;
- /* strings have already been freed */
- dsc_memfree(dsc, this_dcs);
- this_dcs = next_dcs;
- }
- dsc->dcs2 = NULL;
- }
- if (dsc->colours) {
- CDSCCOLOUR *this_colour, *next_colour;
- this_colour = dsc->colours;
- while (this_colour) {
- next_colour = this_colour->next;
- /* strings have already been freed */
- dsc_memfree(dsc, this_colour);
- this_colour = next_colour;
- }
- dsc->colours = NULL;
- }
- if (dsc->macbin)
- dsc_memfree(dsc, dsc->macbin);
- dsc->macbin = NULL;
- dsc->worst_error = CDSC_ERROR_NONE;
- }
- /*
- * Join up all sections.
- * There might be extra code between them, or we might have
- * missed including the \n which followed \r.
- * begin is the start of this section
- * pend is a pointer to the end of this section
- * pplast is a pointer to a pointer of the end of the previous section
- */
- dsc_private void
- dsc_section_join(DSC_OFFSET begin, DSC_OFFSET *pend, DSC_OFFSET **pplast)
- {
- if (begin)
- **pplast = begin;
- if (*pend > begin)
- *pplast = pend;
- }
- /* return value is 0 if no line available, or length of line */
- dsc_private int
- dsc_read_line(CDSC *dsc)
- {
- char *p, *last;
- dsc->line = NULL;
- if (dsc->eof) {
- /* return all that remains, even if line incomplete */
- dsc->line = dsc->data + dsc->data_index;
- dsc->line_length = dsc->data_length - dsc->data_index;
- dsc->data_index = dsc->data_length;
- return dsc->line_length;
- }
- if (dsc->file_length &&
- (dsc->data_offset + dsc->data_index >= dsc->file_length)) {
- /* Have read past where we need to parse. */
- /* Ignore all that remains. */
- dsc->line = dsc->data + dsc->data_index;
- dsc->line_length = dsc->data_length - dsc->data_index;
- dsc->data_index = dsc->data_length;
- return dsc->line_length;
- }
- if (dsc->doseps_end &&
- (dsc->data_offset + dsc->data_index >= dsc->doseps_end)) {
- /* Have read past end of DOS EPS PostScript section. */
- /* Ignore all that remains. */
- dsc->line = dsc->data + dsc->data_index;
- dsc->line_length = dsc->data_length - dsc->data_index;
- dsc->data_index = dsc->data_length;
- return dsc->line_length;
- }
- /* ignore embedded bytes */
- if (dsc->skip_bytes) {
- int cnt = min(dsc->skip_bytes,
- (int)(dsc->data_length - dsc->data_index));
- dsc->skip_bytes -= cnt;
- dsc->data_index += cnt;
- if (dsc->skip_bytes != 0)
- return 0;
- }
- do {
- dsc->line = dsc->data + dsc->data_index;
- last = dsc->data + dsc->data_length;
- if (dsc->data_index == dsc->data_length) {
- dsc->line_length = 0;
- return 0;
- }
- if (dsc->eol) {
- /* if previous line was complete, increment line count */
- dsc->line_count++;
- if (dsc->skip_lines)
- dsc->skip_lines--;
- }
-
- /* skip over \n which followed \r */
- if (dsc->last_cr && dsc->line[0] == '\n') {
- dsc->data_index++;
- dsc->line++;
- }
- dsc->last_cr = FALSE;
- /* look for EOL */
- dsc->eol = FALSE;
- for (p = dsc->line; p < last; p++) {
- if (*p == '\r') {
- p++;
- if ((p<last) && (*p == '\n'))
- p++; /* include line feed also */
- else
- dsc->last_cr = TRUE; /* we might need to skip \n */
- dsc->eol = TRUE; /* dsc->line is a complete line */
- break;
- }
- if (*p == '\n') {
- p++;
- dsc->eol = TRUE; /* dsc->line is a complete line */
- break;
- }
- if (*p == '\032') { /* MS-DOS Ctrl+Z */
- dsc->eol = TRUE;
- }
- }
- if (dsc->eol == FALSE) {
- /* we haven't got a complete line yet */
- if (dsc->data_length - dsc->data_index < sizeof(dsc->data)/2) {
- /* buffer is less than half full, ask for some more */
- dsc->line_length = 0;
- return 0;
- }
- }
- dsc->data_index += dsc->line_length = (int)(p - dsc->line);
- } while (dsc->skip_lines && dsc->line_length);
- if (dsc->line_length == 0)
- return 0;
-
- if ((dsc->line[0]=='%') && (dsc->line[1]=='%')) {
- /* handle recursive %%BeginDocument */
- if ((dsc->skip_document) && dsc->line_length &&
- COMPARE(dsc->line, "%%EndDocument")) {
- dsc->skip_document--;
- }
- /* handle embedded lines or binary data */
- if (COMPARE(dsc->line, "%%BeginData:")) {
- /* %%BeginData: <numberof>[ <type> [ <bytesorlines> ] ]
- * <numberof> ::= <uint> (Lines or physical bytes)
- * <type> ::= Hex | Binary | ASCII (Type of data)
- * <bytesorlines> ::= Bytes | Lines (Read in bytes or lines)
- */
- char begindata[MAXSTR+1];
- int cnt;
- const char *numberof, *bytesorlines;
- cnt = dsc->line_length;
- if (dsc->line_length > sizeof(begindata)-1)
- cnt = sizeof(begindata)-1;
- memcpy(begindata, dsc->line, cnt);
- begindata[cnt] = '\0';
- numberof = strtok(begindata+12, " \r\n");
- strtok(NULL, " \r\n"); /* dump type */
- bytesorlines = strtok(NULL, " \r\n");
- if (bytesorlines == NULL)
- bytesorlines = "Bytes";
-
- if ( (numberof == NULL) || (bytesorlines == NULL) ) {
- /* invalid usage of %%BeginData */
- /* ignore that we ever saw it */
- int rc = dsc_error(dsc, CDSC_MESSAGE_INCORRECT_USAGE,
- dsc->line, dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return 0;
- }
- }
- else {
- cnt = atoi(numberof);
- if (cnt) {
- if (bytesorlines && (dsc_stricmp(bytesorlines, "Lines")==0)) {
- /* skip cnt lines */
- if (dsc->skip_lines == 0) {
- /* we are not already skipping lines */
- dsc->skip_lines = cnt+1;
- }
- }
- else {
- /* byte count doesn't includes \n or \r\n */
- /* or \r of %%BeginData: */
- /* skip cnt bytes */
- if (dsc->skip_bytes == 0) {
- /* we are not already skipping lines */
- dsc->skip_bytes = cnt;
- }
- }
- }
- }
- }
- else if (COMPARE(dsc->line, "%%BeginBinary:")) {
- /* byte count doesn't includes \n or \r\n or \r of %%BeginBinary:*/
- int cnt = dsc_get_int(dsc->line + 14,
- dsc->line_length - 14, NULL);
- if (dsc->skip_bytes == 0) {
- /* we are not already skipping lines */
- dsc->skip_bytes = cnt;
- }
- }
- }
-
- if ((dsc->line[0]=='%') && (dsc->line[1]=='%') &&
- COMPARE(dsc->line, "%%BeginDocument:") ) {
- /* Skip over embedded document, recursively */
- dsc->skip_document++;
- }
- if (!dsc->long_line && (dsc->line_length > DSC_LINE_LENGTH)) {
- dsc_error(dsc, CDSC_MESSAGE_LONG_LINE, dsc->line, dsc->line_length);
- dsc->long_line = TRUE;
- }
-
- return dsc->line_length;
- }
- /* Save last DSC line, for use with %%+ */
- dsc_private void
- dsc_save_line(CDSC *dsc)
- {
- int len = min(sizeof(dsc->last_line), dsc->line_length);
- memcpy(dsc->last_line, dsc->line, len);
- }
- /* display unknown DSC line */
- dsc_private void
- dsc_unknown(CDSC *dsc)
- {
- if (dsc->debug_print_fn) {
- char line[DSC_LINE_LENGTH];
- unsigned int length = min(DSC_LINE_LENGTH-1, dsc->line_length);
- sprintf(line, "Unknown in %s section at line %d:\n ",
- dsc_scan_section_name[dsc->scan_section], dsc->line_count);
- dsc_debug_print(dsc, line);
- strncpy(line, dsc->line, length);
- line[length] = '\0';
- dsc_debug_print(dsc, line);
- dsc_debug_print(dsc, "\n");
- }
- }
- dsc_private GSBOOL
- dsc_is_section(char *line)
- {
- if ( !((line[0]=='%') && (line[1]=='%')) )
- return FALSE;
- if (IS_DSC(line, "%%BeginPreview"))
- return TRUE;
- if (IS_DSC(line, "%%BeginDefaults"))
- return TRUE;
- if (IS_DSC(line, "%%BeginProlog"))
- return TRUE;
- if (IS_DSC(line, "%%BeginSetup"))
- return TRUE;
- if (IS_DSC(line, "%%Page:"))
- return TRUE;
- if (IS_DSC(line, "%%Trailer"))
- return TRUE;
- if (IS_DSC(line, "%%EOF"))
- return TRUE;
- return FALSE;
- }
- /* Get little-endian DWORD, used for DOS EPS files */
- dsc_private GSDWORD
- dsc_get_dword(const unsigned char *buf)
- {
- GSDWORD dw;
- dw = (GSDWORD)buf[0];
- dw += ((GSDWORD)buf[1])<<8;
- dw += ((GSDWORD)buf[2])<<16;
- dw += ((GSDWORD)buf[3])<<24;
- return dw;
- }
- dsc_private GSWORD
- dsc_get_word(const unsigned char *buf)
- {
- GSWORD w;
- w = (GSWORD)buf[0];
- w |= (GSWORD)(buf[1]<<8);
- return w;
- }
- /* Get big-endian DWORD, used for Mac Binary files */
- dsc_private GSDWORD
- dsc_get_bigendian_dword(const unsigned char *buf)
- {
- GSDWORD dw;
- dw = (GSDWORD)buf[3];
- dw += ((GSDWORD)buf[2])<<8;
- dw += ((GSDWORD)buf[1])<<16;
- dw += ((GSDWORD)buf[0])<<24;
- return dw;
- }
- dsc_private GSWORD
- dsc_get_bigendian_word(const unsigned char *buf)
- {
- GSWORD w;
- w = (GSWORD)buf[1];
- w |= (GSWORD)(buf[0]<<8);
- return w;
- }
- dsc_private int
- dsc_read_doseps(CDSC *dsc)
- {
- unsigned char *line = (unsigned char *)dsc->line;
- if ((dsc->doseps = (CDSCDOSEPS *)dsc_memalloc(dsc, sizeof(CDSCDOSEPS))) == NULL)
- return CDSC_ERROR; /* no memory */
-
- dsc->doseps->ps_begin = dsc_get_dword(line+4);
- dsc->doseps->ps_length = dsc_get_dword(line+8);
- dsc->doseps->wmf_begin = dsc_get_dword(line+12);
- dsc->doseps->wmf_length = dsc_get_dword(line+16);
- dsc->doseps->tiff_begin = dsc_get_dword(line+20);
- dsc->doseps->tiff_length = dsc_get_dword(line+24);
- dsc->doseps->checksum = dsc_get_word(line+28);
- if (dsc->file_length &&
- (dsc->doseps->ps_begin + dsc->doseps->ps_length > dsc->file_length)) {
- /* Error in DOS EPS header.
- * Some files have been seen with a fixed large value as
- * the length of the PostScript section.
- * Correct for these erroneous files.
- */
- dsc->doseps->ps_length =
- (GSDWORD)(dsc->file_length - dsc->doseps->ps_begin);
- }
- dsc->doseps_end = dsc->doseps->ps_begin + dsc->doseps->ps_length;
- /* move data_index backwards to byte after doseps header */
- dsc->data_index -= dsc->line_length - 30;
- /* we haven't read a line of PostScript code yet */
- dsc->line_count = 0;
- /* skip from current position to start of PostScript section */
- dsc->skip_bytes = dsc->doseps->ps_begin - 30;
- if (dsc->doseps->tiff_begin)
- dsc->preview = CDSC_TIFF;
- if (dsc->doseps->wmf_begin)
- dsc->preview = CDSC_WMF;
- return CDSC_OK;
- }
- dsc_private int
- dsc_read_macbin(CDSC *dsc)
- {
- unsigned char *line = (unsigned char *)dsc->line;
- if ((dsc->macbin =
- (CDSCMACBIN *)dsc_memalloc(dsc, sizeof(CDSCMACBIN))) == NULL)
- return CDSC_ERROR; /* no memory */
-
- dsc->macbin->data_begin = 128;
- dsc->macbin->data_length = dsc_get_bigendian_dword(line+83);
- dsc->macbin->resource_begin =
- (dsc->macbin->data_begin + dsc->macbin->data_length + 127 ) & ~127;
- dsc->macbin->resource_length = dsc_get_bigendian_dword(line+87);
- /* A MacBinary file has been seen that doesn't have the resource
- * fork padded out to 128 bytes. Just make sure that the resource
- * doesn't extend beyond EOF.
- */
- if (dsc->file_length &&
- (((dsc->macbin->resource_begin + dsc->macbin->resource_length
- /* + 127 */ ) /* & ~127 */ ) > dsc->file_length)) {
- return CDSC_ERROR;
- }
- dsc->doseps_end = dsc->macbin->data_begin + dsc->macbin->data_length;
- /* move data_index to byte after Mac Binary header */
- dsc->data_index -= dsc->line_length - 128;
- /* we haven't read a line of PostScript code yet */
- dsc->line_count = 0;
- dsc->preview = CDSC_PICT;
- return CDSC_OK;
- }
- dsc_private int
- dsc_read_applesingle(CDSC *dsc)
- {
- GSDWORD EntryID;
- GSDWORD Offset;
- GSDWORD Length;
- GSWORD entries;
- int index;
- int header;
- int i;
- unsigned char *line = (unsigned char *)dsc->line;
- if ((dsc->macbin =
- (CDSCMACBIN *)dsc_memalloc(dsc, sizeof(CDSCMACBIN))) == NULL)
- return CDSC_ERROR; /* no memory */
- entries = dsc_get_bigendian_word(line+24);
- for (i=0; i<(int)entries; i++) {
- index = 26 + i * 12;
- EntryID = dsc_get_bigendian_dword(line+index);
- Offset = dsc_get_bigendian_dword(line+index+4);
- Length = dsc_get_bigendian_dword(line+index+8);
- if (EntryID == 1) {
- /* data fork */
- dsc->macbin->data_begin = Offset;
- dsc->macbin->data_length = Length;
- }
- else if (EntryID == 2) {
- /* resource fork */
- dsc->macbin->resource_begin = Offset;
- dsc->macbin->resource_length = Length;
- }
- }
-
- if (dsc->file_length &&
- (dsc->macbin->resource_begin + dsc->macbin->resource_length
- > dsc->file_length)) {
- return CDSC_ERROR;
- }
- if (dsc->file_length &&
- (dsc->macbin->data_begin + dsc->macbin->data_length
- > dsc->file_length)) {
- return CDSC_ERROR;
- }
- dsc->doseps_end = dsc->macbin->data_begin + dsc->macbin->data_length;
- header = 26 + entries * 12;
- /* move data_index to byte after AppleSingle/AppleDouble header */
- dsc->data_index -= dsc->line_length - header;
- /* we haven't read a line of PostScript code yet */
- dsc->line_count = 0;
- /* skip from current position to start of PostScript section */
- dsc->skip_bytes = dsc->macbin->data_begin - header;
- dsc->preview = CDSC_PICT;
- return CDSC_OK;
- }
- dsc_private int
- dsc_parse_pages(CDSC *dsc)
- {
- int ip, io;
- unsigned int i;
- char *p;
- int n;
- if ((dsc->page_pages != 0) && (dsc->scan_section == scan_comments)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- return CDSC_OK; /* ignore duplicate comments in header */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if ((dsc->page_pages != 0) && (dsc->scan_section == scan_trailer)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- break; /* use duplicate comments in header */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- n = IS_DSC(dsc->line, "%%+") ? 3 : 8;
- while (IS_WHITE(dsc->line[n]))
- n++;
- p = dsc->line + n;
- if (COMPARE(p, "atend")) {
- if (dsc->scan_section != scan_comments)
- dsc_unknown(dsc);
- else {
- int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND,
- dsc->line, dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* assume (atend) */
- /* we should mark it as deferred */
- break;
- case CDSC_RESPONSE_CANCEL:
- /* ignore it */
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- }
- else if (COMPARE(p, "(atend)")) {
- if (dsc->scan_section != scan_comments)
- dsc_unknown(dsc);
- /* do nothing */
- /* we should mark it as deferred */
- }
- else {
- ip = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
- if (i) {
- n+=i;
- dsc->page_pages = ip;
- io = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
- if (i) {
- /* DSC 2 uses extra integer to indicate page order */
- /* DSC 3 uses %%PageOrder: */
- if (dsc->page_order == CDSC_ORDER_UNKNOWN)
- switch (io) {
- case -1:
- dsc->page_order = CDSC_DESCEND;
- break;
- case 0:
- dsc->page_order = CDSC_SPECIAL;
- break;
- case 1:
- dsc->page_order = CDSC_ASCEND;
- break;
- }
- }
- }
- else {
- int rc = dsc_error(dsc, CDSC_MESSAGE_INCORRECT_USAGE, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- /* ignore it */
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- }
- return CDSC_OK;
- }
- dsc_private int
- dsc_parse_bounding_box(CDSC *dsc, CDSCBBOX** pbbox, int offset)
- {
- unsigned int i, n;
- int llx, lly, urx, ury;
- float fllx, flly, furx, fury;
- char *p;
- /* Process first %%BoundingBox: in comments, and last in trailer */
- if ((*pbbox != NULL) && (dsc->scan_section == scan_comments)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- return CDSC_OK; /* ignore duplicate comments in header */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if ((*pbbox != NULL) && (dsc->scan_section == scan_pages)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- return CDSC_OK; /* ignore duplicate comments in header */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if ((*pbbox != NULL) && (dsc->scan_section == scan_trailer)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- break; /* use duplicate comments in trailer */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if (*pbbox != NULL) {
- dsc_memfree(dsc, *pbbox);
- *pbbox = NULL;
- }
- /* should only process first %%BoundingBox: */
- while (IS_WHITE(dsc->line[offset]))
- offset++;
- p = dsc->line + offset;
-
- if (COMPARE(p, "atend")) {
- if (dsc->scan_section == scan_trailer)
- dsc_unknown(dsc);
- else {
- int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* assume (atend) */
- /* we should mark it as deferred */
- break;
- case CDSC_RESPONSE_CANCEL:
- /* ignore it */
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- }
- else if (COMPARE(p, "(atend)")) {
- if (dsc->scan_section == scan_trailer)
- dsc_unknown(dsc);
- /* do nothing */
- /* we should mark it as deferred */
- }
- else {
- /* llx = */ lly = urx = ury = 0;
- n = offset;
- llx = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- lly = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- urx = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- ury = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
- if (i) {
- *pbbox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
- if (*pbbox == NULL)
- return CDSC_ERROR; /* no memory */
- (*pbbox)->llx = llx;
- (*pbbox)->lly = lly;
- (*pbbox)->urx = urx;
- (*pbbox)->ury = ury;
- }
- else {
- int rc = dsc_error(dsc, CDSC_MESSAGE_BBOX, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* fllx = */ flly = furx = fury = 0.0;
- n = offset;
- n += i;
- fllx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- flly = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- furx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- fury = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- if (i) {
- *pbbox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
- if (*pbbox == NULL)
- return CDSC_ERROR; /* no memory */
- (*pbbox)->llx = (int)fllx;
- (*pbbox)->lly = (int)flly;
- (*pbbox)->urx = (int)(furx+0.999);
- (*pbbox)->ury = (int)(fury+0.999);
- }
- return CDSC_OK;
- case CDSC_RESPONSE_CANCEL:
- return CDSC_OK;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- }
- return CDSC_OK;
- }
- dsc_private int
- dsc_parse_float_bounding_box(CDSC *dsc, CDSCFBBOX** pbbox, int offset)
- {
- unsigned int i, n;
- float fllx, flly, furx, fury;
- char *p;
- /* Process first %%HiResBoundingBox: or %%CropBox: in comments,
- * and last in trailer.
- */
- if ((*pbbox != NULL) && (dsc->scan_section == scan_comments)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- return CDSC_OK; /* ignore duplicate comments in header */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if ((*pbbox != NULL) && (dsc->scan_section == scan_pages)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- return CDSC_OK; /* ignore duplicate comments in header */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if ((*pbbox != NULL) && (dsc->scan_section == scan_trailer)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- break; /* use duplicate comments in trailer */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if (*pbbox != NULL) {
- dsc_memfree(dsc, *pbbox);
- *pbbox = NULL;
- }
- /* should only process first %%BoundingBox: */
- while (IS_WHITE(dsc->line[offset]))
- offset++;
- p = dsc->line + offset;
-
- if (COMPARE(p, "atend")) {
- if (dsc->scan_section == scan_trailer)
- dsc_unknown(dsc);
- else {
- int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* assume (atend) */
- /* we should mark it as deferred */
- break;
- case CDSC_RESPONSE_CANCEL:
- /* ignore it */
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- }
- else if (COMPARE(p, "(atend)")) {
- if (dsc->scan_section == scan_trailer)
- dsc_unknown(dsc);
- /* do nothing */
- /* we should mark it as deferred */
- }
- else {
- /* fllx = */ flly = furx = fury = 0.0;
- n = offset;
- fllx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- flly = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- furx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- fury = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- if (i) {
- *pbbox = (CDSCFBBOX *)dsc_memalloc(dsc, sizeof(CDSCFBBOX));
- if (*pbbox == NULL)
- return CDSC_ERROR; /* no memory */
- (*pbbox)->fllx = fllx;
- (*pbbox)->flly = flly;
- (*pbbox)->furx = furx;
- (*pbbox)->fury = fury;
- }
- }
- return CDSC_OK;
- }
- dsc_private int
- dsc_parse_orientation(CDSC *dsc, unsigned int *porientation, int offset)
- {
- char *p;
- if ((dsc->page_orientation != CDSC_ORIENT_UNKNOWN) &&
- (dsc->scan_section == scan_comments)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- ret…
Large files files are truncated, but you can click here to view the full file