File indexing completed on 2024-05-12 08:17:50

0001 /* Copyright (C) 2000-2001, Ghostgum Software Pty Ltd.  All rights reserved.
0002     
0003   This file is part of GSview.
0004    
0005   This file is distributed in the hope that it will be useful, but
0006   WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
0007   to anyone for the consequences of using it or for whether it serves any
0008   particular purpose or works at all, unless he says so in writing.  Refer
0009   to the GNU General Public License for full details.
0010    
0011   Everyone is granted permission to copy, modify and redistribute this
0012   file, but only under the conditions described in the GNU General
0013   Public License.  A copy of this license is supposed to have been given
0014   to you along with this file so you can know your rights and
0015   responsibilities.  It should be in a file named COPYING.  Among other
0016   things, the copyright notice and this notice must be preserved on all
0017   copies.
0018 */
0019 
0020 /* $Id$ */
0021 
0022 /* dscparse.h */
0023 /* Interface for the DSC parser. */
0024 
0025 #ifndef _DSCPARSE_H_
0026 #define _DSCPARSE_H_
0027 
0028 /* Some local types that may need modification */
0029 typedef bool GSBOOL;
0030 typedef unsigned long GSDWORD;  /* must be at least 32 bits */
0031 typedef unsigned int GSWORD;    /* must be at least 16 bits */
0032 
0033 #ifndef FALSE
0034 # define FALSE ((GSBOOL)0)
0035 # define TRUE ((GSBOOL)(!FALSE))
0036 #endif
0037 
0038 #ifndef dsc_private
0039 # ifdef private
0040 #  define dsc_private private
0041 # else
0042 #  define dsc_private static
0043 # endif
0044 #endif
0045 
0046 #ifndef min
0047 # define min(a,b)  ((a) < (b) ? (a) : (b))
0048 #endif
0049 
0050 /* macros to allow conversion of function declarations to K&R */
0051 #ifndef P0
0052 #define P0() void
0053 #define P1(t1) t1
0054 #define P2(t1,t2) t1,t2
0055 #define P3(t1,t2,t3) t1,t2,t3
0056 #define P4(t1,t2,t3,t4) t1,t2,t3,t4
0057 #define P5(t1,t2,t3,t4,t5) t1,t2,t3,t4,t5
0058 #define P6(t1,t2,t3,t4,t5,t6) t1,t2,t3,t4,t5,t6
0059 #endif
0060 
0061 /* maximum legal length of lines in a DSC compliant file */
0062 #define DSC_LINE_LENGTH 255
0063 
0064 /* memory for strings is allocated in chunks of this length */
0065 #define CDSC_STRING_CHUNK 4096
0066 
0067 /* page array is allocated in chunks of this many pages */
0068 #define CDSC_PAGE_CHUNK 128 
0069 
0070 /* buffer length for storing lines passed to dsc_scan_data() */
0071 /* must be at least 2 * DSC_LINE_LENGTH */
0072 /* We choose 8192 as twice the length passed to us by GSview */
0073 #define CDSC_DATA_LENGTH 8192
0074 
0075 /* Return codes from dsc_scan_data()
0076  *  < 0     = error
0077  *  >=0     = OK
0078  *
0079  *  -1      = error, usually insufficient memory.
0080  *  0-9     = normal
0081  *  10-99   = internal codes, should not be seen.
0082  *  100-999 = identifier of last DSC comment processed.
0083  */
0084 
0085 typedef enum {
0086   CDSC_ERROR        = -1,   /* Fatal error, usually insufficient memory */
0087 
0088   CDSC_OK       = 0,    /* OK, no DSC comment found */
0089   CDSC_NOTDSC       = 1,    /* Not DSC, or DSC is being ignored */
0090 
0091 /* Any section */
0092   CDSC_UNKNOWNDSC   = 100,  /* DSC comment not recognised */
0093 
0094 /* Header section */
0095   CDSC_PSADOBE      = 200,  /* %!PS-Adobe- */
0096   CDSC_BEGINCOMMENTS    = 201,  /* %%BeginComments */
0097   CDSC_ENDCOMMENTS  = 202,  /* %%EndComments */
0098   CDSC_PAGES        = 203,  /* %%Pages: */
0099   CDSC_CREATOR      = 204,  /* %%Creator: */
0100   CDSC_CREATIONDATE = 205,  /* %%CreationDate: */
0101   CDSC_TITLE        = 206,  /* %%Title: */
0102   CDSC_FOR      = 207,  /* %%For: */
0103   CDSC_LANGUAGELEVEL    = 208,  /* %%LanguageLevel: */
0104   CDSC_BOUNDINGBOX  = 209,  /* %%BoundingBox: */
0105   CDSC_ORIENTATION  = 210,  /* %%Orientation: */
0106   CDSC_PAGEORDER    = 211,  /* %%PageOrder: */
0107   CDSC_DOCUMENTMEDIA    = 212,  /* %%DocumentMedia: */
0108   CDSC_DOCUMENTPAPERSIZES    = 213, /* %%DocumentPaperSizes: */
0109   CDSC_DOCUMENTPAPERFORMS    = 214, /* %%DocumentPaperForms: */
0110   CDSC_DOCUMENTPAPERCOLORS   = 215, /* %%DocumentPaperColors: */
0111   CDSC_DOCUMENTPAPERWEIGHTS  = 216, /* %%DocumentPaperWeights: */
0112   CDSC_DOCUMENTDATA      = 217, /* %%DocumentData: */
0113   CDSC_REQUIREMENTS      = 218, /* IGNORED %%Requirements: */
0114   CDSC_DOCUMENTNEEDEDFONTS   = 219, /* IGNORED %%DocumentNeededFonts: */
0115   CDSC_DOCUMENTSUPPLIEDFONTS = 220, /* IGNORED %%DocumentSuppliedFonts: */
0116   CDSC_HIRESBOUNDINGBOX      = 221, /* %%HiResBoundingBox: */
0117   CDSC_CROPBOX               = 222, /* %%CropBox: */
0118 
0119 /* Preview section */
0120   CDSC_BEGINPREVIEW = 301,  /* %%BeginPreview */
0121   CDSC_ENDPREVIEW   = 302,  /* %%EndPreview */
0122 
0123 /* Defaults section */
0124   CDSC_BEGINDEFAULTS    = 401,  /* %%BeginDefaults */
0125   CDSC_ENDDEFAULTS  = 402,  /* %%EndDefaults */
0126 /* also %%PageMedia, %%PageOrientation, %%PageBoundingBox */
0127 
0128 /* Prolog section */
0129   CDSC_BEGINPROLOG  = 501,  /* %%BeginProlog */
0130   CDSC_ENDPROLOG    = 502,  /* %%EndProlog */
0131   CDSC_BEGINFONT    = 503,  /* IGNORED %%BeginFont */
0132   CDSC_ENDFONT      = 504,  /* IGNORED %%EndFont */
0133   CDSC_BEGINFEATURE = 505,  /* IGNORED %%BeginFeature */
0134   CDSC_ENDFEATURE   = 506,  /* IGNORED %%EndFeature */
0135   CDSC_BEGINRESOURCE    = 507,  /* IGNORED %%BeginResource */
0136   CDSC_ENDRESOURCE  = 508,  /* IGNORED %%EndResource */
0137   CDSC_BEGINPROCSET = 509,  /* IGNORED %%BeginProcSet */
0138   CDSC_ENDPROCSET   = 510,  /* IGNORED %%EndProcSet */
0139 
0140 /* Setup section */
0141   CDSC_BEGINSETUP   = 601,  /* %%BeginSetup */
0142   CDSC_ENDSETUP     = 602,  /* %%EndSetup */
0143   CDSC_FEATURE      = 603,  /* IGNORED %%Feature: */
0144   CDSC_PAPERCOLOR   = 604,  /* IGNORED %%PaperColor: */
0145   CDSC_PAPERFORM    = 605,  /* IGNORED %%PaperForm: */
0146   CDSC_PAPERWEIGHT  = 606,  /* IGNORED %%PaperWeight: */
0147   CDSC_PAPERSIZE    = 607,  /* %%PaperSize: */
0148 /* also %%Begin/EndFeature, %%Begin/EndResource */
0149 
0150 /* Page section */
0151   CDSC_PAGE     = 700,  /* %%Page: */
0152   CDSC_PAGETRAILER  = 701,  /* IGNORED %%PageTrailer */
0153   CDSC_BEGINPAGESETUP   = 702,  /* IGNORED %%BeginPageSetup */
0154   CDSC_ENDPAGESETUP = 703,  /* IGNORED %%EndPageSetup */
0155   CDSC_PAGEMEDIA    = 704,  /* %%PageMedia: */
0156 /* also %%PaperColor, %%PaperForm, %%PaperWeight, %%PaperSize */
0157   CDSC_PAGEORIENTATION  = 705,  /* %%PageOrientation: */
0158   CDSC_PAGEBOUNDINGBOX  = 706,  /* %%PageBoundingBox: */
0159 /* also %%Begin/EndFont, %%Begin/EndFeature */
0160 /* also %%Begin/EndResource, %%Begin/EndProcSet */
0161   CDSC_INCLUDEFONT  = 707,  /* IGNORED %%IncludeFont: */
0162   CDSC_VIEWINGORIENTATION = 708, /* %%ViewingOrientation: */
0163 
0164 /* Trailer section */
0165   CDSC_TRAILER      = 800,  /* %%Trailer */
0166 /* also %%Pages, %%BoundingBox, %%Orientation, %%PageOrder, %%DocumentMedia */ 
0167 /* %%Page is recognised as an error */
0168 /* also %%DocumentNeededFonts, %%DocumentSuppliedFonts */
0169 
0170 /* End of File */
0171   CDSC_EOF      = 900   /* %%EOF */
0172 } CDSC_RETURN_CODE;
0173 
0174 
0175 /* stored in dsc->preview */ 
0176 typedef enum {
0177     CDSC_NOPREVIEW = 0,
0178     CDSC_EPSI = 1,
0179     CDSC_TIFF = 2,
0180     CDSC_WMF = 3,
0181     CDSC_PICT = 4
0182 } CDSC_PREVIEW_TYPE;
0183 
0184 /* stored in dsc->page_order */ 
0185 typedef enum {
0186     CDSC_ORDER_UNKNOWN = 0,
0187     CDSC_ASCEND = 1,
0188     CDSC_DESCEND = 2,
0189     CDSC_SPECIAL = 3
0190 } CDSC_PAGE_ORDER;
0191 
0192 /* stored in dsc->page_orientation and dsc->page[pagenum-1].orientation */ 
0193 typedef enum {
0194     CDSC_ORIENT_UNKNOWN = 0,
0195     CDSC_PORTRAIT = 1,
0196     CDSC_LANDSCAPE = 2,
0197     CDSC_UPSIDEDOWN = 3,
0198     CDSC_SEASCAPE = 4
0199 } CDSC_ORIENTATION_ENUM;
0200 
0201 /* stored in dsc->document_data */
0202 typedef enum {
0203     CDSC_DATA_UNKNOWN = 0,
0204     CDSC_CLEAN7BIT = 1,
0205     CDSC_CLEAN8BIT = 2,
0206     CDSC_BINARY = 3
0207 } CDSC_DOCUMENT_DATA ;
0208 
0209 typedef struct CDSCBBOX_S {
0210     int llx;
0211     int lly;
0212     int urx;
0213     int ury;
0214 } CDSCBBOX;
0215 
0216 typedef struct CDSCFBBOX_S {
0217     float fllx;
0218     float flly;
0219     float furx;
0220     float fury;
0221 } CDSCFBBOX;
0222 
0223 typedef struct CDSCMEDIA_S {
0224     const char *name;
0225     float width;    /* PostScript points */
0226     float height;
0227     float weight;   /* GSM */
0228     const char *colour;
0229     const char *type;
0230     CDSCBBOX *mediabox; /* Used by GSview for PDF MediaBox */
0231 } CDSCMEDIA;
0232 
0233 #define CDSC_KNOWN_MEDIA 46
0234 extern const CDSCMEDIA dsc_known_media[CDSC_KNOWN_MEDIA];
0235 
0236 typedef struct CDSCCTM_S { /* used for %%ViewingOrientation */
0237     float xx;
0238     float xy;
0239     float yx;
0240     float yy;
0241     /* float ty; */
0242     /* float ty; */
0243 } CDSCCTM;
0244 
0245 typedef struct CDSCPAGE_S {
0246     int ordinal;
0247     const char *label;
0248     unsigned long begin;
0249     unsigned long end;
0250     unsigned int orientation;
0251     const CDSCMEDIA *media;
0252     CDSCBBOX *bbox;  /* PageBoundingBox, also used by GSview for PDF CropBox */
0253     CDSCCTM *viewing_orientation;
0254 } CDSCPAGE;
0255 
0256 /* binary DOS EPS header */
0257 typedef struct CDSCDOSEPS_S {
0258     GSDWORD ps_begin;
0259     GSDWORD ps_length;
0260     GSDWORD wmf_begin;
0261     GSDWORD wmf_length;
0262     GSDWORD tiff_begin;
0263     GSDWORD tiff_length;
0264     GSWORD checksum;
0265 } CDSCDOSEPS;
0266 
0267 /* rather than allocated every string with malloc, we allocate
0268  * chunks of 4k and place the (usually) short strings in these
0269  * chunks.
0270  */
0271 typedef struct CDSCSTRING_S CDSCSTRING;
0272 struct CDSCSTRING_S {
0273     unsigned int index;
0274     unsigned int length;
0275     char *data;
0276     CDSCSTRING *next;
0277 };
0278 
0279 
0280 /* DSC error reporting */
0281 
0282 typedef enum {
0283   CDSC_MESSAGE_BBOX = 0,
0284   CDSC_MESSAGE_EARLY_TRAILER = 1,
0285   CDSC_MESSAGE_EARLY_EOF = 2,
0286   CDSC_MESSAGE_PAGE_IN_TRAILER = 3,
0287   CDSC_MESSAGE_PAGE_ORDINAL = 4,
0288   CDSC_MESSAGE_PAGES_WRONG = 5,
0289   CDSC_MESSAGE_EPS_NO_BBOX = 6,
0290   CDSC_MESSAGE_EPS_PAGES = 7,
0291   CDSC_MESSAGE_NO_MEDIA = 8,
0292   CDSC_MESSAGE_ATEND = 9,
0293   CDSC_MESSAGE_DUP_COMMENT = 10,
0294   CDSC_MESSAGE_DUP_TRAILER = 11,
0295   CDSC_MESSAGE_BEGIN_END = 12,
0296   CDSC_MESSAGE_BAD_SECTION = 13,
0297   CDSC_MESSAGE_LONG_LINE = 14,
0298   CDSC_MESSAGE_INCORRECT_USAGE = 15
0299 } CDSC_MESSAGE_ERROR;
0300 
0301 /* severity */
0302 typedef enum {
0303   CDSC_ERROR_INFORM = 0,    /* Not an error */
0304   CDSC_ERROR_WARN   = 1,    /* Not a DSC error itself,  */
0305   CDSC_ERROR_ERROR  = 2 /* DSC error */
0306 } CDSC_MESSAGE_SEVERITY;
0307 
0308 /* response */
0309 typedef enum {
0310   CDSC_RESPONSE_OK  = 0,
0311   CDSC_RESPONSE_CANCEL  = 1,
0312   CDSC_RESPONSE_IGNORE_ALL = 2
0313 } CDSC_RESPONSE;
0314 
0315 extern const char * const dsc_message[];
0316 
0317 typedef struct CDSC_S CDSC;
0318 struct CDSC_S {
0319     /* public data */
0320     GSBOOL dsc;         /* TRUE if DSC comments found */
0321     GSBOOL ctrld;       /* TRUE if has CTRLD at start of stream */
0322     GSBOOL pjl;         /* TRUE if has HP PJL at start of stream */
0323     GSBOOL epsf;        /* TRUE if EPSF */
0324     GSBOOL pdf;         /* TRUE if Portable Document Format */
0325     unsigned int preview;   /* enum CDSC_PREVIEW_TYPE */
0326     char *dsc_version;  /* first line of file */
0327     unsigned int language_level;
0328     unsigned int document_data; /* Clean7Bit, Clean8Bit, Binary */
0329                 /* enum CDSC_DOCUMENT_DATA */
0330     /* DSC sections */
0331     unsigned long begincomments;
0332     unsigned long endcomments;
0333     unsigned long beginpreview;
0334     unsigned long endpreview;
0335     unsigned long begindefaults;
0336     unsigned long enddefaults;
0337     unsigned long beginprolog;
0338     unsigned long endprolog;
0339     unsigned long beginsetup;
0340     unsigned long endsetup;
0341     unsigned long begintrailer;
0342     unsigned long endtrailer;
0343     CDSCPAGE *page;
0344     unsigned int page_count;    /* number of %%Page: pages in document */
0345     unsigned int page_pages;    /* number of pages in document from %%Pages: */
0346     unsigned int page_order;    /* enum CDSC_PAGE_ORDER */
0347     unsigned int page_orientation;  /* the default page orientation */
0348                 /* enum CDSC_ORIENTATION */
0349     CDSCCTM *viewing_orientation;
0350     unsigned int media_count;   /* number of media items */
0351     CDSCMEDIA **media;      /* the array of media */
0352     const CDSCMEDIA *page_media;/* the default page media */
0353     CDSCBBOX *bbox;     /* the document bounding box */
0354     CDSCBBOX *page_bbox;    /* the default page bounding box */
0355     CDSCDOSEPS *doseps;     /* DOS binary header */
0356     char *dsc_title;
0357     char *dsc_creator;
0358     char *dsc_date;
0359     char *dsc_for;
0360 
0361     unsigned int max_error; /* highest error number that will be reported */
0362     const int *severity;    /* array of severity values, one per error */
0363 
0364 
0365     /* private data */
0366     void *caller_data;      /* pointer to be provided when calling */
0367                     /* error and debug callbacks */
0368     int id;         /* last DSC comment found */
0369     int scan_section;       /* section currently being scanned */
0370                 /* enum CDSC_SECTION */
0371 
0372     unsigned long doseps_end;   /* ps_begin+ps_length, otherwise 0 */
0373     unsigned int page_chunk_length; /* number of pages allocated */
0374     unsigned long file_length;  /* length of document */
0375         /* If provided we try to recognise %%Trailer and %%EOF */
0376         /* incorrectly embedded inside document. */
0377         /* Can be left set to default value of 0 */
0378     int skip_document;      /* recursion level of %%BeginDocument: */
0379     int skip_bytes;     /* #bytes to ignore from BeginData: */
0380                 /* or DOSEPS preview section */
0381     int skip_lines;     /* #lines to ignore from BeginData: */
0382     GSBOOL skip_pjl;        /* TRUE if skip PJL until first PS comment */ 
0383     int begin_font_count;   /* recursion level of %%BeginFont */
0384     int begin_feature_count;    /* recursion level of %%BeginFeature */
0385     int begin_resource_count;   /* recursion level of %%BeginResource */
0386     int begin_procset_count;    /* recursion level of %%BeginProcSet */
0387 
0388     /* buffer for input */
0389     char data[CDSC_DATA_LENGTH];/* start of buffer */
0390     unsigned int data_length;   /* length of data in buffer */
0391     unsigned int data_index;    /* offset to next char in buffer */
0392     unsigned long data_offset;  /* offset from start of document */
0393                     /* to byte in data[0] */
0394     GSBOOL eof;         /* TRUE if there is no more data */
0395 
0396     /* information about DSC line */
0397     char *line;         /* pointer to last read DSC line */
0398                 /* not null terminated */
0399     unsigned int line_length;   /* number of characters in line */
0400     GSBOOL eol;         /* TRUE if dsc_line contains EOL */
0401     GSBOOL last_cr;     /* TRUE if last line ended in \r */
0402                 /* check next time for \n */
0403     unsigned int line_count;    /* line number */
0404     GSBOOL long_line;       /* TRUE if found a line longer than 255 characters */
0405     char last_line[256];    /* previous DSC line, used for %%+ */
0406 
0407     /* more efficient string storage (for short strings) than malloc */
0408     CDSCSTRING *string_head;    /* linked list head */
0409     CDSCSTRING *string;     /* current list item */
0410 
0411     /* memory allocation routines */
0412     void *(*memalloc)(P2(size_t size, void *closure_data));
0413     void (*memfree)(P2(void *ptr, void *closure_data));
0414     void *mem_closure_data;
0415 
0416     /* function for printing debug messages */
0417     void (*debug_print_fn)(P2(void *caller_data, const char *str));
0418 
0419     /* function for reporting errors in DSC comments */
0420     int (*dsc_error_fn)(P5(void *caller_data, CDSC *dsc, 
0421     unsigned int explanation, const char *line, unsigned int line_len));
0422 
0423     /* public data */
0424     /* Added 2001-10-01 */
0425     CDSCFBBOX *hires_bbox;  /* the hires document bounding box */
0426     CDSCFBBOX *crop_box;    /* the size of the trimmed page */
0427 };
0428 
0429 
0430 /* Public functions */
0431 
0432 /* Create and initialise DSC parser */
0433 CDSC *dsc_init(P1(void *caller_data));
0434 
0435 CDSC *dsc_init_with_alloc(P4(
0436     void *caller_data,
0437     void *(*memalloc)(size_t size, void *closure_data),
0438     void (*memfree)(void *ptr, void *closure_data),
0439     void *closure_data));
0440 
0441 /* Free the DSC parser */
0442 void dsc_free(P1(CDSC *dsc));
0443 
0444 /* Tell DSC parser how long document will be, to allow ignoring
0445  * of early %%Trailer and %%EOF.  This is optional.
0446  */
0447 void dsc_set_length(P2(CDSC *dsc, unsigned long len));
0448 
0449 /* Process a buffer containing DSC comments and PostScript */
0450 int dsc_scan_data(P3(CDSC *dsc, const char *data, int len));
0451 
0452 /* All data has been processed, fixup any DSC errors */
0453 int dsc_fixup(P1(CDSC *dsc));
0454 
0455 /* Install error query function */
0456 void dsc_set_error_function(P2(CDSC *dsc, 
0457     int (*dsc_error_fn)(P5(void *caller_data, CDSC *dsc, 
0458     unsigned int explanation, const char *line, unsigned int line_len))));
0459 
0460 /* Install print function for debug messages */
0461 void dsc_set_debug_function(P2(CDSC *dsc, 
0462     void (*debug_fn)(P2(void *caller_data, const char *str))));
0463 
0464 /* Print a message to debug output, if provided */
0465 void dsc_debug_print(P2(CDSC *dsc, const char *str));
0466 
0467 /* should be internal only functions, but made available to 
0468  * GSview for handling PDF
0469  */
0470 int dsc_add_page(P3(CDSC *dsc, int ordinal, char *label));
0471 int dsc_add_media(P2(CDSC *dsc, CDSCMEDIA *media));
0472 int dsc_set_page_bbox(P6(CDSC *dsc, unsigned int page_number, 
0473     int llx, int lly, int urx, int ury));
0474 
0475 #endif
0476 
0477 // vim:sw=4:sts=4:ts=8:noet