Coverage Report

Created: 2026-08-17 07:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kdegraphics-thumbnailers/ps/dscparse.cpp
Line
Count
Source
1
/* SPDX-FileCopyrightText: 2000-2001 Ghostgum Software Pty Ltd. All rights reserved.
2
    
3
  This file is part of GSview.
4
   
5
  This file is distributed in the hope that it will be useful, but
6
  WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
7
  to anyone for the consequences of using it or for whether it serves any
8
  particular purpose or works at all, unless he says so in writing.  Refer
9
  to the GNU General Public License for full details.
10
   
11
  Everyone is granted permission to copy, modify and redistribute this
12
  file, but only under the conditions described in the GNU General
13
  Public License.  A copy of this license is supposed to have been given
14
  to you along with this file so you can know your rights and
15
  responsibilities.  It should be in a file named COPYING.  Among other
16
  things, the copyright notice and this notice must be preserved on all
17
  copies.
18
*/
19
20
/* $Id$ */
21
22
/* dscparse.c - DSC parser  */
23
24
/*
25
 * This is a DSC parser, based on the DSC 3.0 spec, 
26
 * with a few DSC 2.1 additions for page size.
27
 *
28
 * Current limitations:
29
 * %%+ may be used after any comment in the comment or trailer, 
30
 * but is currently only supported by
31
 *   %%DocumentMedia
32
 *
33
 * DSC 2.1 additions (discontinued in DSC 3.0):
34
 * %%DocumentPaperColors: 
35
 * %%DocumentPaperForms: 
36
 * %%DocumentPaperSizes: 
37
 * %%DocumentPaperWeights: 
38
 * %%PaperColor:   (ignored)
39
 * %%PaperForm:    (ignored)
40
 * %%PaperSize: 
41
 * %%PaperWeight:  (ignored)
42
 *
43
 * Other additions for defaults or page section
44
 % %%ViewingOrientation: xx xy yx yy
45
*/
46
47
#include <stdio.h>  /* for sprintf(), not file I/O */
48
#include <stdlib.h>
49
#include <string.h>
50
#include <ctype.h>
51
52
#define MAXSTR 256
53
54
#include "dscparse.h"
55
56
/* Macros for comparing string literals
57
 * For maximum speed, the length of the second macro argument is
58
 * computed at compile time.
59
 * THE SECOND MACRO ARGUMENT MUST BE A STRING LITERAL.
60
 */
61
21.2M
#define COMPARE(p,str) (strncmp((const char *)(p), (str), sizeof(str)-1)==0)
62
19.9M
#define IS_DSC(line, str) (COMPARE((line), (str)))
63
64
/* Macros for comparing the first one or two characters */
65
2.61M
#define IS_WHITE(ch) (((ch)==' ') || ((ch)=='\t'))
66
502k
#define IS_EOL(ch) (((ch)=='\r') || ((ch)=='\n'))
67
142k
#define IS_WHITE_OR_EOL(ch) (IS_WHITE(ch) || IS_EOL(ch))
68
21.0k
#define IS_BLANK(str) (IS_EOL(str[0]))
69
1.81M
#define NOT_DSC_LINE(str) (((str)[0]!='%') || ((str)[1]!='%'))
70
71
/* Macros for document offset to start and end of line */
72
546k
#define DSC_START(dsc)  ((dsc)->data_offset + (dsc)->data_index - (dsc)->line_length)
73
1.96M
#define DSC_END(dsc)  ((dsc)->data_offset + (dsc)->data_index)
74
75
/* dsc_scan_SECTION() functions return one of 
76
 * CDSC_ERROR, CDSC_OK, CDSC_NOTDSC 
77
 * or one of the following
78
 */
79
/* The line should be passed on to the next section parser. */
80
2.38M
#define CDSC_PROPAGATE  10
81
82
/* If document is DOS EPS and we haven't read 30 bytes, ask for more. */
83
2.40M
#define CDSC_NEEDMORE 11
84
85
/* local prototypes */
86
dsc_private void * dsc_memalloc(P2(CDSC *dsc, size_t size));
87
dsc_private void dsc_memfree(P2(CDSC*dsc, void *ptr));
88
dsc_private CDSC * dsc_init2(P1(CDSC *dsc));
89
dsc_private void dsc_reset(P1(CDSC *dsc));
90
dsc_private void dsc_section_join(P3(unsigned long begin, unsigned long *pend, unsigned long **pplast));
91
dsc_private int dsc_read_line(P1(CDSC *dsc));
92
dsc_private int dsc_read_doseps(P1(CDSC *dsc));
93
dsc_private char * dsc_alloc_string(P3(CDSC *dsc, const char *str, int len));
94
dsc_private char * dsc_add_line(P3(CDSC *dsc, const char *line, unsigned int len));
95
dsc_private char * dsc_copy_string(P5(char *str, unsigned int slen, 
96
    char *line, unsigned int len, unsigned int *offset));
97
dsc_private GSDWORD dsc_get_dword(P1(const unsigned char *buf));
98
dsc_private GSWORD dsc_get_word(P1(const unsigned char *buf));
99
dsc_private int dsc_get_int(P3(const char *line, unsigned int len, unsigned int *offset));
100
dsc_private float dsc_get_real(P3(const char *line, unsigned int len, 
101
    unsigned int *offset));
102
dsc_private int dsc_stricmp(P2(const char *s, const char *t));
103
dsc_private void dsc_unknown(P1(CDSC *dsc)); 
104
dsc_private GSBOOL dsc_is_section(char *line);
105
dsc_private int dsc_parse_pages(P1(CDSC *dsc));
106
dsc_private int dsc_parse_bounding_box(P3(CDSC *dsc, CDSCBBOX** pbbox, int offset));
107
dsc_private int dsc_parse_float_bounding_box(P3(CDSC *dsc, CDSCFBBOX** pfbbox, int offset));
108
dsc_private int dsc_parse_orientation(P3(CDSC *dsc, unsigned int *porientation, 
109
    int offset));
110
dsc_private int dsc_parse_order(P1(CDSC *dsc));
111
dsc_private int dsc_parse_media(P2(CDSC *dsc, const CDSCMEDIA **page_media));
112
dsc_private int dsc_parse_document_media(P1(CDSC *dsc));
113
dsc_private int dsc_parse_viewing_orientation(P2(CDSC *dsc, CDSCCTM **pctm));
114
dsc_private int dsc_parse_page(P1(CDSC *dsc));
115
dsc_private void dsc_save_line(P1(CDSC *dsc));
116
dsc_private int dsc_scan_type(P1(CDSC *dsc));
117
dsc_private int dsc_scan_comments(P1(CDSC *dsc));
118
dsc_private int dsc_scan_preview(P1(CDSC *dsc));
119
dsc_private int dsc_scan_defaults(P1(CDSC *dsc));
120
dsc_private int dsc_scan_prolog(P1(CDSC *dsc));
121
dsc_private int dsc_scan_setup(P1(CDSC *dsc));
122
dsc_private int dsc_scan_page(P1(CDSC *dsc));
123
dsc_private int dsc_scan_trailer(P1(CDSC *dsc));
124
dsc_private int dsc_error(P4(CDSC *dsc, unsigned int explanation, 
125
    char *line, unsigned int line_len));
126
127
/* DSC error reporting */
128
dsc_private const int dsc_severity[] = {
129
    CDSC_ERROR_WARN,  /* CDSC_MESSAGE_BBOX */
130
    CDSC_ERROR_WARN,  /* CDSC_MESSAGE_EARLY_TRAILER */
131
    CDSC_ERROR_WARN,  /* CDSC_MESSAGE_EARLY_EOF */
132
    CDSC_ERROR_ERROR,   /* CDSC_MESSAGE_PAGE_IN_TRAILER */
133
    CDSC_ERROR_ERROR,   /* CDSC_MESSAGE_PAGE_ORDINAL */
134
    CDSC_ERROR_ERROR,   /* CDSC_MESSAGE_PAGES_WRONG */
135
    CDSC_ERROR_ERROR,   /* CDSC_MESSAGE_EPS_NO_BBOX */
136
    CDSC_ERROR_ERROR,   /* CDSC_MESSAGE_EPS_PAGES */
137
    CDSC_ERROR_WARN,  /* CDSC_MESSAGE_NO_MEDIA */
138
    CDSC_ERROR_WARN,  /* CDSC_MESSAGE_ATEND */
139
    CDSC_ERROR_INFORM,  /* CDSC_MESSAGE_DUP_COMMENT */
140
    CDSC_ERROR_INFORM,  /* CDSC_MESSAGE_DUP_TRAILER */
141
    CDSC_ERROR_WARN,  /* CDSC_MESSAGE_BEGIN_END */
142
    CDSC_ERROR_INFORM,  /* CDSC_MESSAGE_BAD_SECTION */
143
    CDSC_ERROR_INFORM,  /* CDSC_MESSAGE_LONG_LINE */
144
    CDSC_ERROR_WARN,  /* CDSC_MESSAGE_INCORRECT_USAGE */
145
    0
146
};
147
148
8.68k
#define DSC_MAX_ERROR ((sizeof(dsc_severity) / sizeof(int))-2)
149
150
const CDSCMEDIA dsc_known_media[CDSC_KNOWN_MEDIA] = {
151
    /* These sizes taken from Ghostscript gs_statd.ps */
152
    {"11x17", 792, 1224, 0, NULL, NULL, NULL},
153
    {"A0", 2380, 3368, 0, NULL, NULL, NULL},
154
    {"A1", 1684, 2380, 0, NULL, NULL, NULL}, 
155
    {"A2", 1190, 1684, 0, NULL, NULL, NULL}, 
156
    {"A3", 842, 1190, 0, NULL, NULL, NULL},
157
    {"A4", 595, 842, 0, NULL, NULL, NULL},
158
    {"A5", 421, 595, 0, NULL, NULL, NULL},
159
    {"A6", 297, 421, 0, NULL, NULL, NULL}, 
160
    {"A7", 210, 297, 0, NULL, NULL, NULL}, 
161
    {"A8", 148, 210, 0, NULL, NULL, NULL}, 
162
    {"A9", 105, 148, 0, NULL, NULL, NULL}, 
163
    {"A10", 74, 105, 0, NULL, NULL, NULL}, 
164
    {"B0", 2836, 4008, 0, NULL, NULL, NULL}, 
165
    {"B1", 2004, 2836, 0, NULL, NULL, NULL}, 
166
    {"B2", 1418, 2004, 0, NULL, NULL, NULL}, 
167
    {"B3", 1002, 1418, 0, NULL, NULL, NULL}, 
168
    {"B4", 709, 1002, 0, NULL, NULL, NULL}, /* ISO, but not Adobe standard */
169
    {"B5", 501, 709, 0, NULL, NULL, NULL},  /* ISO, but not Adobe standard */
170
    {"B6", 354, 501, 0, NULL, NULL, NULL}, 
171
    {"C0", 2600, 3677, 0, NULL, NULL, NULL}, 
172
    {"C1", 1837, 2600, 0, NULL, NULL, NULL},  
173
    {"C2", 1298, 1837, 0, NULL, NULL, NULL}, 
174
    {"C3", 918, 1298, 0, NULL, NULL, NULL}, 
175
    {"C4", 649, 918, 0, NULL, NULL, NULL}, 
176
    {"C5", 459, 649, 0, NULL, NULL, NULL}, 
177
    {"C6", 323, 459, 0, NULL, NULL, NULL}, 
178
    {"Ledger", 1224, 792, 0, NULL, NULL, NULL},
179
    {"Legal", 612, 1008, 0, NULL, NULL, NULL},
180
    {"Letter", 612, 792, 0, NULL, NULL, NULL},
181
    {"Note", 612, 792, 0, NULL, NULL, NULL},
182
// ISO and JIS B sizes are different....
183
    {"jisb0", 2916, 4128, 0, NULL, NULL, NULL},
184
    {"jisb1", 2064, 2916, 0, NULL, NULL, NULL}, 
185
    {"jisb2", 1458, 2064, 0, NULL, NULL, NULL}, 
186
    {"jisb3", 1032, 1458, 0, NULL, NULL, NULL}, 
187
    {"jisb4", 729, 1032, 0, NULL, NULL, NULL}, 
188
    {"jisb5", 516, 729, 0, NULL, NULL, NULL}, 
189
    {"jisb6", 363, 516, 0, NULL, NULL, NULL}, 
190
// U.S. CAD standard paper sizes
191
    {"archE", 2592, 3456, 0, NULL, NULL, NULL}, 
192
    {"archD", 1728, 2592, 0, NULL, NULL, NULL}, 
193
    {"archC", 1296, 1728, 0, NULL, NULL, NULL}, 
194
    {"archB", 864, 1296, 0, NULL, NULL, NULL}, 
195
    {"archA", 648, 864, 0, NULL, NULL, NULL}, 
196
// Other paper sizes
197
    {"flsa", 612, 936, 0, NULL, NULL, NULL}, /* U.S. foolscap */
198
    {"flse", 612, 936, 0, NULL, NULL, NULL}, /* European foolscap */
199
    {"halfletter", 396, 612, 0, NULL, NULL, NULL}, 
200
    {NULL, 0, 0, 0, NULL, NULL, NULL}
201
};
202
203
/* parser state */
204
enum CDSC_SCAN_SECTION {
205
    scan_none = 0,
206
    scan_comments = 1,
207
    scan_pre_preview = 2,
208
    scan_preview = 3,
209
    scan_pre_defaults = 4,
210
    scan_defaults = 5,
211
    scan_pre_prolog = 6,
212
    scan_prolog = 7,
213
    scan_pre_setup = 8,
214
    scan_setup = 9,
215
    scan_pre_pages = 10,
216
    scan_pages = 11,
217
    scan_pre_trailer = 12,
218
    scan_trailer = 13,
219
    scan_eof = 14
220
};
221
222
static const char * const dsc_scan_section_name[15] = {
223
 "Type", "Comments", 
224
 "pre-Preview", "Preview",
225
 "pre-Defaults", "Defaults",
226
 "pre-Prolog", "Prolog",
227
 "pre-Setup", "Setup",
228
 "pre-Page", "Page",
229
 "pre-Trailer", "Trailer",
230
 "EOF"
231
};
232
233
/******************************************************************/
234
/* Public functions                                               */
235
/******************************************************************/
236
237
/* constructor */
238
CDSC *
239
dsc_init(void *caller_data)
240
4.34k
{
241
4.34k
    CDSC *dsc = (CDSC *)malloc(sizeof(CDSC));
242
4.34k
    if (dsc == NULL)
243
0
  return NULL;
244
4.34k
    memset(dsc, 0, sizeof(CDSC));
245
4.34k
    dsc->caller_data = caller_data;
246
247
4.34k
    return dsc_init2(dsc);
248
4.34k
}
249
250
/* constructor, with caller supplied memalloc */
251
CDSC *
252
dsc_init_with_alloc(
253
    void *caller_data,
254
    void *(*memalloc)(size_t size, void *closure_data),
255
    void (*memfree)(void *ptr, void *closure_data),
256
    void *closure_data)
257
0
{
258
0
    CDSC *dsc = (CDSC *)memalloc(sizeof(CDSC), closure_data);
259
0
    if (dsc == NULL)
260
0
  return NULL;
261
0
    memset(dsc, 0, sizeof(CDSC));
262
0
    dsc->caller_data = caller_data;
263
264
0
    dsc->memalloc = memalloc;
265
0
    dsc->memfree = memfree;
266
0
    dsc->mem_closure_data = closure_data;
267
    
268
0
    return dsc_init2(dsc);
269
0
}
270
271
272
273
/* destructor */
274
void 
275
dsc_free(CDSC *dsc)
276
4.34k
{
277
4.34k
    if (dsc == NULL)
278
0
  return;
279
4.34k
    dsc_reset(dsc);
280
4.34k
    dsc_memfree(dsc, dsc);
281
4.34k
}
282
283
284
/* Tell DSC parser how long document will be, to allow ignoring
285
 * of early %%Trailer and %%EOF.  This is optional.
286
 */
287
void 
288
dsc_set_length(CDSC *dsc, unsigned long len)
289
0
{
290
0
    dsc->file_length = len;
291
0
}
292
293
/* Process a buffer containing DSC comments and PostScript */
294
/* Return value is < 0 for error, >=0 for OK.
295
 *  CDSC_ERROR
296
 *  CDSC_OK
297
 *  CDSC_NOTDSC (DSC will be ignored)
298
 *  other values indicate the last DSC comment read
299
 */ 
300
int
301
dsc_scan_data(CDSC *dsc, const char *data, int length)
302
1.10M
{
303
1.10M
    int bytes_read;
304
1.10M
    int code = 0;
305
306
1.10M
    if (dsc == NULL)
307
0
  return CDSC_ERROR;
308
309
1.10M
    if (dsc->id == CDSC_NOTDSC)
310
653k
  return CDSC_NOTDSC;
311
312
446k
    dsc->id = CDSC_OK;
313
446k
    if (dsc->eof)
314
0
  return CDSC_OK; /* ignore */
315
316
446k
    if (length == 0) {
317
  /* EOF, so process what remains */
318
0
  dsc->eof = TRUE;
319
0
    }
320
321
446k
    do {
322
446k
  if (dsc->id == CDSC_NOTDSC)
323
0
      break;
324
325
446k
  if (length != 0) {
326
446k
      if (dsc->data_index > dsc->data_length)
327
19
    return CDSC_NOTDSC;
328
329
      /* move existing data if needed */
330
446k
      if (dsc->data_length > CDSC_DATA_LENGTH/2) {
331
10.1k
    memmove(dsc->data, dsc->data + dsc->data_index,
332
10.1k
        dsc->data_length - dsc->data_index);
333
10.1k
    dsc->data_offset += dsc->data_index;
334
10.1k
    dsc->data_length -= dsc->data_index;
335
10.1k
    dsc->data_index = 0;
336
10.1k
      }
337
      /* append to buffer */
338
446k
      bytes_read = min(length, (int)(CDSC_DATA_LENGTH - dsc->data_length));
339
446k
      memcpy(dsc->data + dsc->data_length, data, bytes_read);
340
446k
      dsc->data_length += bytes_read;
341
446k
      data += bytes_read;
342
446k
      length -= bytes_read;
343
446k
  }
344
446k
  if (dsc->scan_section == scan_none) {
345
27.4k
      code = dsc_scan_type(dsc);
346
27.4k
      if (code == CDSC_NEEDMORE) {
347
    /* need more characters before we can identify type */
348
23.1k
    code = CDSC_OK;
349
23.1k
    break;
350
23.1k
      }
351
4.26k
      dsc->id = code;
352
4.26k
  }
353
354
423k
        if (code == CDSC_NOTDSC) {
355
148
      dsc->id = CDSC_NOTDSC;
356
148
      break;
357
148
  }
358
359
2.79M
  while ((code = dsc_read_line(dsc)) > 0) {
360
2.37M
      if (dsc->id == CDSC_NOTDSC)
361
0
    break;
362
2.37M
      if (dsc->doseps_end && 
363
5.95k
    (dsc->data_offset + dsc->data_index > dsc->doseps_end)) {
364
    /* have read past end of DOS EPS PostScript section */
365
3.63k
    return CDSC_OK; /* ignore */
366
3.63k
      }
367
2.37M
      if (dsc->eof)
368
0
    return CDSC_OK;
369
2.37M
      if (dsc->skip_document)
370
17.9k
    continue;  /* embedded document */
371
2.35M
      if (dsc->skip_lines)
372
0
    continue; /* embedded lines */
373
2.35M
      if (IS_DSC(dsc->line, "%%BeginData:"))
374
2.10k
    continue;
375
2.35M
      if (IS_DSC(dsc->line, "%%BeginBinary:"))
376
1.87k
    continue;
377
2.35M
      if (IS_DSC(dsc->line, "%%EndDocument"))
378
836
    continue;
379
2.35M
      if (IS_DSC(dsc->line, "%%EndData"))
380
525
    continue;
381
2.34M
      if (IS_DSC(dsc->line, "%%EndBinary"))
382
377
    continue;
383
384
2.36M
      do {
385
2.36M
    switch (dsc->scan_section) {
386
99.0k
        case scan_comments:
387
99.0k
      code = dsc_scan_comments(dsc);
388
99.0k
      break;
389
12.4k
        case scan_pre_preview:
390
144k
        case scan_preview:
391
144k
      code = dsc_scan_preview(dsc);
392
144k
      break;
393
3.39k
        case scan_pre_defaults:
394
22.0k
        case scan_defaults:
395
22.0k
      code = dsc_scan_defaults(dsc);
396
22.0k
      break;
397
3.26k
        case scan_pre_prolog:
398
247k
        case scan_prolog:
399
247k
      code = dsc_scan_prolog(dsc);
400
247k
      break;
401
5.19k
        case scan_pre_setup:
402
105k
        case scan_setup:
403
105k
      code = dsc_scan_setup(dsc);
404
105k
      break;
405
300k
        case scan_pre_pages:
406
1.36M
        case scan_pages:
407
1.36M
      code = dsc_scan_page(dsc);
408
1.36M
      break;
409
1.44k
        case scan_pre_trailer:
410
382k
        case scan_trailer:
411
382k
      code = dsc_scan_trailer(dsc);
412
382k
      break;
413
0
        case scan_eof:
414
0
      code = CDSC_OK;
415
0
      break;
416
0
        default:
417
      /* invalid state */
418
0
      code = CDSC_ERROR;
419
2.36M
    }
420
    /* repeat if line is start of next section */
421
2.36M
      } while (code == CDSC_PROPAGATE);
422
423
      /* if DOS EPS header not complete, ask for more */
424
2.34M
      if (code == CDSC_NEEDMORE) {
425
0
    code = CDSC_OK;
426
0
    break;
427
0
      }
428
2.34M
      if (code == CDSC_NOTDSC) {
429
0
    dsc->id = CDSC_NOTDSC;
430
0
    break;
431
0
      }
432
2.34M
  }
433
423k
    } while (length != 0);
434
435
442k
    return (code < 0) ? code : dsc->id;
436
446k
}
437
438
/* Tidy up from incorrect DSC comments */
439
int 
440
dsc_fixup(CDSC *dsc)
441
0
{
442
0
    unsigned int i;
443
0
    char buf[32];
444
0
    unsigned long *last;
445
446
0
    if (dsc->id == CDSC_NOTDSC)
447
0
  return 0;
448
449
    /* flush last partial line */
450
0
    dsc_scan_data(dsc, NULL, 0);
451
452
    /* Fix DSC error: code between %%EndSetup and %%Page */
453
0
    if (dsc->page_count && (dsc->page[0].begin != dsc->endsetup)
454
0
    && (dsc->endsetup != dsc->beginsetup)) {
455
0
  dsc->endsetup = dsc->page[0].begin;
456
0
  dsc_debug_print(dsc, "Warning: code included between setup and first page\n");
457
0
    }
458
459
    /* Last page contained a false trailer, */
460
    /* so extend last page to start of trailer */
461
0
    if (dsc->page_count && (dsc->begintrailer != 0) &&
462
0
  (dsc->page[dsc->page_count-1].end != dsc->begintrailer)) {
463
0
  dsc_debug_print(dsc, "Ignoring earlier misplaced trailer\n");
464
0
  dsc_debug_print(dsc, "and extending last page to start of trailer\n"); 
465
0
  dsc->page[dsc->page_count-1].end = dsc->begintrailer;
466
0
    }
467
468
    /* 
469
     * Join up all sections.
470
     * There might be extra code between them, or we might have
471
     * missed including the \n which followed \r.
472
     */
473
0
    last = &dsc->endcomments;
474
0
    dsc_section_join(dsc->beginpreview, &dsc->endpreview, &last);
475
0
    dsc_section_join(dsc->begindefaults, &dsc->enddefaults, &last);
476
0
    dsc_section_join(dsc->beginprolog, &dsc->endprolog, &last);
477
0
    dsc_section_join(dsc->beginsetup, &dsc->endsetup, &last);
478
0
    for (i=0; i<dsc->page_count; i++)
479
0
  dsc_section_join(dsc->page[i].begin, &dsc->page[i].end, &last);
480
0
    if (dsc->begintrailer)
481
0
  *last = dsc->begintrailer;
482
  
483
0
    if ((dsc->page_pages == 0) && (dsc->page_count == 1)) {
484
  /* don't flag an error if %%Pages absent but one %%Page found */
485
  /* adjust incorrect page count */
486
0
  dsc->page_pages = dsc->page_count;
487
0
    }
488
489
    /* Warnings and Errors that we can now identify */
490
0
    if ((dsc->page_count != dsc->page_pages)) {
491
0
  int rc = dsc_error(dsc, CDSC_MESSAGE_PAGES_WRONG, NULL, 0);
492
0
  switch (rc) {
493
0
      case CDSC_RESPONSE_OK:
494
    /* adjust incorrect page count */
495
0
    dsc->page_pages = dsc->page_count;
496
0
    break;
497
0
      case CDSC_RESPONSE_CANCEL:
498
0
    break;;
499
0
      case CDSC_RESPONSE_IGNORE_ALL:
500
0
    return CDSC_NOTDSC;
501
0
  }
502
0
    }
503
504
0
    if (dsc->epsf && (dsc->bbox == (CDSCBBOX *)NULL)) {
505
  /* EPS files MUST include a BoundingBox */
506
0
  int rc = dsc_error(dsc, CDSC_MESSAGE_EPS_NO_BBOX, NULL, 0);
507
0
  switch (rc) {
508
0
      case CDSC_RESPONSE_OK:
509
    /* Assume that it is EPS */
510
0
    break;
511
0
      case CDSC_RESPONSE_CANCEL:
512
    /* Is NOT an EPS file */
513
0
    dsc->epsf = FALSE;
514
0
      case CDSC_RESPONSE_IGNORE_ALL:
515
0
    return CDSC_NOTDSC;
516
0
  }
517
0
    }
518
519
0
    if (dsc->epsf && ((dsc->page_count > 1) || (dsc->page_pages > 1))) {
520
0
  int rc = dsc_error(dsc, CDSC_MESSAGE_EPS_PAGES, NULL, 0);
521
0
  switch (rc) {
522
0
      case CDSC_RESPONSE_OK:
523
    /* Is an EPS file */
524
0
    break;
525
0
      case CDSC_RESPONSE_CANCEL:
526
    /* Is NOT an EPS file */
527
0
    dsc->epsf = FALSE;
528
0
    break;
529
0
      case CDSC_RESPONSE_IGNORE_ALL:
530
0
    return CDSC_NOTDSC;
531
0
  }
532
0
    }
533
534
0
    if ((dsc->media_count == 1) && (dsc->page_media == NULL)) {
535
  /* if one only media was specified, and default page media */
536
  /* was not specified, assume that default is the only media. */
537
0
  dsc->page_media = dsc->media[0];
538
0
    }
539
540
0
    if ((dsc->media_count != 0) && (dsc->page_media == NULL)) {
541
0
  int rc = dsc_error(dsc, CDSC_MESSAGE_NO_MEDIA, NULL, 0);
542
0
  switch (rc) {
543
0
      case CDSC_RESPONSE_OK:
544
    /* default media is first listed */
545
0
    dsc->page_media = dsc->media[0];
546
0
    break;
547
0
      case CDSC_RESPONSE_CANCEL:
548
    /* No default media */
549
0
    break;
550
0
      case CDSC_RESPONSE_IGNORE_ALL:
551
0
    return CDSC_NOTDSC;
552
0
  }
553
0
    }
554
555
    /* make sure all pages have a label */
556
0
    for (i=0; i<dsc->page_count; i++) {
557
0
  if (strlen(dsc->page[i].label) == 0) {
558
0
      sprintf(buf, "%d", i+1);
559
0
      if ((dsc->page[i].label = dsc_alloc_string(dsc, buf, strlen(buf))) 
560
0
    == (char *)NULL)
561
0
    return CDSC_ERROR; /* no memory */
562
0
  }
563
0
    }
564
0
    return CDSC_OK;
565
0
}
566
567
/* Install a function to be used for displaying messages about 
568
 * DSC errors and warnings, and to request advice from user.
569
 * Installing an error function is optional.
570
 */
571
void 
572
dsc_set_error_function(CDSC *dsc, 
573
  int (*fn)(P5(void *caller_data, CDSC *dsc, 
574
  unsigned int explanation, const char *line, unsigned int line_len)))
575
0
{
576
0
    dsc->dsc_error_fn = fn;
577
0
}
578
579
580
/* Install a function for printing debug messages */
581
/* This is optional */
582
void 
583
dsc_set_debug_function(CDSC *dsc, 
584
  void (*debug_fn)(P2(void *caller_data, const char *str)))
585
0
{
586
0
    dsc->debug_print_fn = debug_fn;
587
0
}
588
589
/* Doesn't need to be public for PostScript documents */
590
/* Made public so GSview can add pages when processing PDF files */
591
int 
592
dsc_add_page(CDSC *dsc, int ordinal, char *label)
593
77.6k
{
594
77.6k
    dsc->page[dsc->page_count].ordinal = ordinal;
595
77.6k
    dsc->page[dsc->page_count].label = 
596
77.6k
  dsc_alloc_string(dsc, label, strlen(label)+1);
597
77.6k
    dsc->page[dsc->page_count].begin = 0;
598
77.6k
    dsc->page[dsc->page_count].end = 0;
599
77.6k
    dsc->page[dsc->page_count].orientation = CDSC_ORIENT_UNKNOWN;
600
77.6k
    dsc->page[dsc->page_count].media = NULL;
601
77.6k
    dsc->page[dsc->page_count].bbox = NULL;
602
77.6k
    dsc->page[dsc->page_count].viewing_orientation = NULL;
603
604
77.6k
    dsc->page_count++;
605
77.6k
    if (dsc->page_count >= dsc->page_chunk_length) {
606
514
  CDSCPAGE *new_page = (CDSCPAGE *)dsc_memalloc(dsc, 
607
514
      (CDSC_PAGE_CHUNK+dsc->page_count) * sizeof(CDSCPAGE));
608
514
  if (new_page == NULL)
609
0
      return CDSC_ERROR; /* out of memory */
610
514
  memcpy(new_page, dsc->page, 
611
514
      dsc->page_count * sizeof(CDSCPAGE));
612
514
  dsc_memfree(dsc, dsc->page);
613
514
  dsc->page= new_page;
614
514
  dsc->page_chunk_length = CDSC_PAGE_CHUNK+dsc->page_count;
615
514
    }
616
77.6k
    return CDSC_OK;
617
77.6k
}
618
619
/* Doesn't need to be public for PostScript documents */
620
/* Made public so GSview can store PDF MediaBox */
621
int
622
dsc_add_media(CDSC *dsc, CDSCMEDIA *media)
623
4.64k
{
624
4.64k
    CDSCMEDIA **newmedia_array;
625
4.64k
    CDSCMEDIA *newmedia;
626
627
    /* extend media array  */
628
4.64k
    newmedia_array = (CDSCMEDIA **)dsc_memalloc(dsc, 
629
4.64k
  (dsc->media_count + 1) * sizeof(CDSCMEDIA *));
630
4.64k
    if (newmedia_array == NULL)
631
0
  return CDSC_ERROR; /* out of memory */
632
4.64k
    if (dsc->media != NULL) {
633
4.04k
  memcpy(newmedia_array, dsc->media, 
634
4.04k
      dsc->media_count * sizeof(CDSCMEDIA *));
635
4.04k
  dsc_memfree(dsc, dsc->media);
636
4.04k
    }
637
4.64k
    dsc->media = newmedia_array;
638
639
    /* allocate new media */
640
4.64k
    newmedia = dsc->media[dsc->media_count] =
641
4.64k
  (CDSCMEDIA *)dsc_memalloc(dsc, sizeof(CDSCMEDIA));
642
4.64k
    if (newmedia == NULL)
643
0
  return CDSC_ERROR; /* out of memory */
644
4.64k
    newmedia->name = NULL;
645
4.64k
    newmedia->width = 595.0;
646
4.64k
    newmedia->height = 842.0;
647
4.64k
    newmedia->weight = 80.0;
648
4.64k
    newmedia->colour = NULL;
649
4.64k
    newmedia->type = NULL;
650
4.64k
    newmedia->mediabox = NULL;
651
652
4.64k
    dsc->media_count++;
653
654
4.64k
    if (media->name) {
655
2.11k
  newmedia->name = dsc_alloc_string(dsc, media->name,
656
2.11k
      strlen(media->name));
657
2.11k
  if (newmedia->name == NULL)
658
0
      return CDSC_ERROR; /* no memory */
659
2.11k
    }
660
4.64k
    newmedia->width = media->width;
661
4.64k
    newmedia->height = media->height;
662
4.64k
    newmedia->weight = media->weight;
663
4.64k
    if (media->colour) {
664
2.55k
  newmedia->colour = dsc_alloc_string(dsc, media->colour, 
665
2.55k
      strlen(media->colour));
666
2.55k
        if (newmedia->colour == NULL)
667
0
      return CDSC_ERROR; /* no memory */
668
2.55k
    }
669
4.64k
    if (media->type) {
670
1.84k
  newmedia->type = dsc_alloc_string(dsc, media->type, 
671
1.84k
      strlen(media->type));
672
1.84k
  if (newmedia->type == NULL)
673
0
      return CDSC_ERROR; /* no memory */
674
1.84k
    }
675
4.64k
    newmedia->mediabox = NULL;
676
677
4.64k
    if (media->mediabox) {
678
0
  newmedia->mediabox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
679
0
  if (newmedia->mediabox == NULL)
680
0
      return CDSC_ERROR; /* no memory */
681
0
  *newmedia->mediabox = *media->mediabox;
682
0
    }
683
4.64k
    return CDSC_OK;
684
4.64k
}
685
686
/* Doesn't need to be public for PostScript documents */
687
/* Made public so GSview can store PDF CropBox */
688
int
689
dsc_set_page_bbox(CDSC *dsc, unsigned int page_number, 
690
    int llx, int lly, int urx, int ury)
691
0
{
692
0
    CDSCBBOX *bbox;
693
0
    if (page_number >= dsc->page_count)
694
0
  return CDSC_ERROR;
695
0
    bbox = dsc->page[page_number].bbox;
696
0
    if (bbox == NULL)
697
0
  dsc->page[page_number].bbox = bbox = 
698
0
      (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
699
0
    if (bbox == NULL)
700
0
  return CDSC_ERROR;
701
0
    bbox->llx = llx;
702
0
    bbox->lly = lly;
703
0
    bbox->urx = urx;
704
0
    bbox->ury = ury;
705
0
    return CDSC_OK;
706
0
}
707
708
709
/******************************************************************/
710
/* Private functions below here.                                  */
711
/******************************************************************/
712
713
dsc_private void *
714
dsc_memalloc(CDSC *dsc, size_t size)
715
30.0k
{
716
30.0k
    if (dsc->memalloc)
717
0
  return dsc->memalloc(size, dsc->mem_closure_data);
718
30.0k
    return malloc(size);
719
30.0k
}
720
721
dsc_private void
722
dsc_memfree(CDSC*dsc, void *ptr)
723
34.5k
{
724
34.5k
    if (dsc->memfree) 
725
0
  dsc->memfree(ptr, dsc->mem_closure_data);
726
34.5k
    else
727
34.5k
  free(ptr);
728
34.5k
}
729
730
/* private constructor */
731
dsc_private CDSC *
732
dsc_init2(CDSC *dsc)
733
4.34k
{
734
4.34k
    dsc_reset(dsc);
735
736
4.34k
    dsc->string_head = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
737
4.34k
    if (dsc->string_head == NULL) {
738
0
  dsc_free(dsc);
739
0
  return NULL; /* no memory */
740
0
    }
741
4.34k
    dsc->string = dsc->string_head;
742
4.34k
    dsc->string->next = NULL;
743
4.34k
    dsc->string->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
744
4.34k
    if (dsc->string->data == NULL) {
745
0
  dsc_free(dsc);
746
0
  return NULL; /* no memory */
747
0
    }
748
4.34k
    dsc->string->index = 0;
749
4.34k
    dsc->string->length = CDSC_STRING_CHUNK;
750
  
751
4.34k
    dsc->page = (CDSCPAGE *)dsc_memalloc(dsc, CDSC_PAGE_CHUNK * sizeof(CDSCPAGE));
752
4.34k
    if (dsc->page == NULL) {
753
0
  dsc_free(dsc);
754
0
  return NULL; /* no memory */
755
0
    }
756
4.34k
    dsc->page_chunk_length = CDSC_PAGE_CHUNK;
757
4.34k
    dsc->page_count = 0;
758
  
759
4.34k
    dsc->line = NULL;
760
4.34k
    dsc->data_length = 0;
761
4.34k
    dsc->data_index = dsc->data_length;
762
763
4.34k
    return dsc;
764
4.34k
}
765
766
767
dsc_private void 
768
dsc_reset(CDSC *dsc)
769
8.68k
{
770
8.68k
    unsigned int i;
771
    /* Clear public members */
772
8.68k
    dsc->dsc = FALSE;
773
8.68k
    dsc->ctrld = FALSE;
774
8.68k
    dsc->pjl = FALSE;
775
8.68k
    dsc->epsf = FALSE;
776
8.68k
    dsc->pdf = FALSE;
777
8.68k
    dsc->epsf = FALSE;
778
8.68k
    dsc->preview = CDSC_NOPREVIEW;
779
8.68k
    dsc->dsc_version = NULL; /* stored in dsc->string */
780
8.68k
    dsc->language_level = 0;
781
8.68k
    dsc->document_data = CDSC_DATA_UNKNOWN;
782
8.68k
    dsc->begincomments = 0;
783
8.68k
    dsc->endcomments = 0;
784
8.68k
    dsc->beginpreview = 0;
785
8.68k
    dsc->endpreview = 0;
786
8.68k
    dsc->begindefaults = 0;
787
8.68k
    dsc->enddefaults = 0;
788
8.68k
    dsc->beginprolog = 0;
789
8.68k
    dsc->endprolog = 0;
790
8.68k
    dsc->beginsetup = 0;
791
8.68k
    dsc->endsetup = 0;
792
8.68k
    dsc->begintrailer = 0;
793
8.68k
    dsc->endtrailer = 0;
794
  
795
86.3k
    for (i=0; i<dsc->page_count; i++) {
796
  /* page media is pointer to an element of media or dsc_known_media */
797
  /* do not free it. */
798
799
77.6k
  if (dsc->page[i].bbox)
800
77
      dsc_memfree(dsc, dsc->page[i].bbox);
801
77.6k
  if (dsc->page[i].viewing_orientation)
802
828
      dsc_memfree(dsc, dsc->page[i].viewing_orientation);
803
77.6k
    }
804
8.68k
    if (dsc->page)
805
4.34k
  dsc_memfree(dsc, dsc->page);
806
8.68k
    dsc->page = NULL;
807
  
808
8.68k
    dsc->page_count = 0;
809
8.68k
    dsc->page_pages = 0;
810
8.68k
    dsc->page_order = CDSC_ORDER_UNKNOWN;
811
8.68k
    dsc->page_orientation = CDSC_ORIENT_UNKNOWN;
812
8.68k
    if (dsc->viewing_orientation)
813
24
  dsc_memfree(dsc, dsc->viewing_orientation);
814
8.68k
    dsc->viewing_orientation = NULL;
815
  
816
8.68k
    if (dsc->media) {
817
5.24k
  for (i=0; i<dsc->media_count; i++) {
818
4.64k
      if (dsc->media[i]) {
819
4.64k
    if (dsc->media[i]->mediabox)
820
0
        dsc_memfree(dsc, dsc->media[i]->mediabox);
821
4.64k
    dsc_memfree(dsc, dsc->media[i]);
822
4.64k
      }
823
4.64k
  }
824
600
  dsc_memfree(dsc, dsc->media);
825
600
    }
826
8.68k
    dsc->media_count = 0;
827
8.68k
    dsc->media = NULL;
828
829
    /* page_media is pointer to an element of media or dsc_known_media */
830
    /* do not free it. */
831
8.68k
    dsc->page_media = NULL;
832
833
8.68k
    if (dsc->bbox)
834
533
  dsc_memfree(dsc, dsc->bbox);
835
8.68k
    dsc->bbox = NULL;
836
8.68k
    if (dsc->page_bbox)
837
6
  dsc_memfree(dsc, dsc->page_bbox);
838
8.68k
    dsc->page_bbox = NULL;
839
8.68k
    if (dsc->doseps)
840
100
  dsc_memfree(dsc, dsc->doseps);
841
8.68k
    dsc->doseps = NULL;
842
  
843
8.68k
    dsc->dsc_title = NULL;
844
8.68k
    dsc->dsc_creator = NULL;
845
8.68k
    dsc->dsc_date = NULL;
846
8.68k
    dsc->dsc_for = NULL;
847
  
848
849
8.68k
    dsc->max_error = DSC_MAX_ERROR;
850
8.68k
    dsc->severity = dsc_severity;
851
852
    /* Clear private members */
853
    /* Don't touch dsc->caller_data */
854
8.68k
    dsc->id = CDSC_OK;
855
8.68k
    dsc->scan_section = scan_none;
856
8.68k
    dsc->doseps_end = 0;
857
8.68k
    dsc->page_chunk_length = 0;
858
8.68k
    dsc->file_length = 0;
859
8.68k
    dsc->skip_document = 0;
860
8.68k
    dsc->skip_bytes = 0;
861
8.68k
    dsc->skip_lines = 0;
862
8.68k
    dsc->skip_pjl = 0;
863
8.68k
    dsc->begin_font_count = 0;
864
8.68k
    dsc->begin_feature_count = 0;
865
8.68k
    dsc->begin_resource_count = 0;
866
8.68k
    dsc->begin_procset_count = 0;
867
868
8.68k
    dsc->data_length = 0;
869
8.68k
    dsc->data_index = 0;
870
8.68k
    dsc->data_offset = 0;
871
872
8.68k
    dsc->eof = 0;
873
  
874
8.68k
    dsc->line = 0;
875
8.68k
    dsc->line_length = 0;
876
8.68k
    dsc->eol = 0;
877
8.68k
    dsc->last_cr = FALSE;
878
8.68k
    dsc->line_count = 1;
879
8.68k
    dsc->long_line = FALSE;
880
8.68k
    memset(dsc->last_line, 0, sizeof(dsc->last_line));
881
882
8.68k
    dsc->string = dsc->string_head;
883
13.7k
    while (dsc->string != (CDSCSTRING *)NULL) {
884
5.03k
  if (dsc->string->data)
885
5.03k
      dsc_memfree(dsc, dsc->string->data);
886
5.03k
  dsc->string_head = dsc->string;
887
5.03k
  dsc->string = dsc->string->next;
888
5.03k
  dsc_memfree(dsc, dsc->string_head);
889
5.03k
    }
890
8.68k
    dsc->string_head = NULL;
891
8.68k
    dsc->string = NULL;
892
893
    /* don't touch caller functions */
894
895
    /* public data */
896
8.68k
    if (dsc->hires_bbox)
897
8
  dsc_memfree(dsc, dsc->hires_bbox);
898
8.68k
    dsc->hires_bbox = NULL;
899
8.68k
    if (dsc->crop_box)
900
90
  dsc_memfree(dsc, dsc->crop_box);
901
8.68k
    dsc->crop_box = NULL;
902
8.68k
}
903
904
/* 
905
* Join up all sections.
906
* There might be extra code between them, or we might have
907
* missed including the \n which followed \r.
908
* begin is the start of this section
909
* pend is a pointer to the end of this section
910
* pplast is a pointer to a pointer of the end of the previous section
911
*/
912
dsc_private void 
913
dsc_section_join(unsigned long begin, unsigned long *pend, unsigned long **pplast)
914
0
{
915
0
    if (begin)
916
0
  **pplast = begin;
917
0
    if (*pend > begin)
918
0
  *pplast = pend;
919
0
}
920
921
922
/* return value is 0 if no line available, or length of line */
923
dsc_private int
924
dsc_read_line(CDSC *dsc)
925
2.80M
{
926
2.80M
    char *p, *last;
927
2.80M
    dsc->line = NULL;
928
929
2.80M
    if (dsc->eof) {
930
  /* return all that remains, even if line incomplete */
931
0
  dsc->line = dsc->data + dsc->data_index;
932
0
  dsc->line_length = dsc->data_length - dsc->data_index;
933
0
  dsc->data_index = dsc->data_length;
934
0
  return dsc->line_length;
935
0
    }
936
937
    /* ignore embedded bytes */
938
2.80M
    if (dsc->skip_bytes) {
939
13.4k
  int cnt = min(dsc->skip_bytes,
940
13.4k
         (int)(dsc->data_length - dsc->data_index));
941
13.4k
  dsc->skip_bytes -= cnt;
942
13.4k
  dsc->data_index += cnt;
943
13.4k
  if (dsc->skip_bytes != 0)
944
11.2k
      return 0;
945
13.4k
    }
946
947
2.79M
    do {
948
2.79M
  if (dsc->data_index >= dsc->data_length) {
949
406k
      dsc->line_length = 0;
950
406k
      return 0;
951
406k
  }
952
2.39M
  dsc->line = dsc->data + dsc->data_index;
953
2.39M
  last = dsc->data + dsc->data_length;
954
2.39M
  if (dsc->eol) {
955
      /* if previous line was complete, increment line count */
956
2.37M
      dsc->line_count++;
957
2.37M
      if (dsc->skip_lines)
958
0
    dsc->skip_lines--;
959
2.37M
  }
960
      
961
  /* skip over \n which followed \r */
962
2.39M
  if (dsc->last_cr && dsc->line[0] == '\n') {
963
1.19k
      dsc->data_index++;
964
1.19k
      dsc->line++;
965
1.19k
  }
966
2.39M
  dsc->last_cr = FALSE;
967
968
  /* look for EOL */
969
2.39M
  dsc->eol = FALSE;
970
52.0M
  for (p = dsc->line; p < last; p++) {
971
52.0M
      if (*p == '\r') {
972
1.97M
    p++;
973
1.97M
    if ((p<last) && (*p == '\n'))
974
1.66k
        p++;  /* include line feed also */
975
1.97M
    else
976
1.97M
        dsc->last_cr = TRUE; /* we might need to skip \n */
977
1.97M
    dsc->eol = TRUE; /* dsc->line is a complete line */
978
1.97M
    break;
979
1.97M
      }
980
50.0M
      if (*p == '\n') {
981
403k
    p++;
982
403k
    dsc->eol = TRUE; /* dsc->line is a complete line */
983
403k
    break;
984
403k
      }
985
49.6M
      if (*p == '\032') {   /* MS-DOS Ctrl+Z */
986
25.0k
    dsc->eol = TRUE;
987
25.0k
      }
988
49.6M
  }
989
2.39M
  if (dsc->eol == FALSE) {
990
      /* we haven't got a complete line yet */
991
14.2k
      if (dsc->data_length - dsc->data_index < sizeof(dsc->data)/2) {
992
    /* buffer is less than half full, ask for some more */
993
12.1k
    dsc->line_length = 0;
994
12.1k
    return 0;
995
12.1k
      }
996
14.2k
  }
997
2.37M
  dsc->data_index += dsc->line_length = (p - dsc->line);
998
2.37M
    } while (dsc->skip_lines && dsc->line_length);
999
1000
2.37M
    if (dsc->line_length == 0)
1001
0
  return 0;
1002
  
1003
2.37M
    if ((dsc->line[0]=='%') && (dsc->line[1]=='%'))  {
1004
  /* handle recursive %%BeginDocument */
1005
490k
  if ((dsc->skip_document) && dsc->line_length &&
1006
3.99k
    COMPARE(dsc->line, "%%EndDocument")) {
1007
35
      dsc->skip_document--;
1008
35
  }
1009
1010
  /* handle embedded lines or binary data */
1011
490k
  if (COMPARE(dsc->line, "%%BeginData:")) {
1012
      /* %%BeginData: <numberof>[ <type> [ <bytesorlines> ] ] 
1013
       * <numberof> ::= <uint> (Lines or physical bytes) 
1014
       * <type> ::= Hex | Binary | ASCII (Type of data) 
1015
       * <bytesorlines> ::= Bytes | Lines (Read in bytes or lines) 
1016
       */
1017
2.11k
      char begindata[MAXSTR+1];
1018
2.11k
      int cnt;
1019
2.11k
            unsigned int num;
1020
2.11k
      const char *numberof, *bytesorlines;
1021
2.11k
            if ((num = dsc->line_length) >= sizeof(begindata)-1)
1022
71
                num = sizeof(begindata)-1;
1023
 
1024
2.11k
            memcpy(begindata, dsc->line, num);
1025
2.11k
            begindata[num] = '\0';
1026
2.11k
      numberof = strtok(begindata+12, " \r\n");
1027
2.11k
      strtok(NULL, " \r\n"); /* dump type */
1028
2.11k
      bytesorlines = strtok(NULL, " \r\n");
1029
2.11k
      if (bytesorlines == NULL)
1030
1.54k
    bytesorlines = "Bytes";
1031
     
1032
2.11k
      if ( (numberof == NULL) || (bytesorlines == NULL) ) {
1033
    /* invalid usage of %%BeginData */
1034
    /* ignore that we ever saw it */
1035
502
    int rc = dsc_error(dsc, CDSC_MESSAGE_INCORRECT_USAGE, 
1036
502
          dsc->line, dsc->line_length);
1037
502
    switch (rc) {
1038
0
        case CDSC_RESPONSE_OK:
1039
502
        case CDSC_RESPONSE_CANCEL:
1040
502
      break;
1041
0
        case CDSC_RESPONSE_IGNORE_ALL:
1042
0
      return 0;
1043
502
    }
1044
502
      }
1045
1.61k
      else {
1046
1.61k
    cnt = atoi(numberof);
1047
1.61k
    if (cnt) {
1048
626
        if (bytesorlines && (dsc_stricmp(bytesorlines, "Lines")==0)) {
1049
      /* skip cnt lines */
1050
0
      if (dsc->skip_lines == 0) {
1051
          /* we are not already skipping lines */
1052
0
          dsc->skip_lines = cnt+1;
1053
0
      }
1054
0
        }
1055
626
        else {
1056
      /* byte count doesn't includes \n or \r\n  */
1057
      /* or \r of %%BeginData: */
1058
      /* skip cnt bytes */
1059
626
      if (dsc->skip_bytes == 0) {
1060
          /* we are not already skipping lines */
1061
626
          dsc->skip_bytes = cnt;
1062
626
      }
1063
1064
626
        }
1065
626
    }
1066
1.61k
      }
1067
2.11k
  }
1068
488k
  else if (COMPARE(dsc->line, "%%BeginBinary:")) {
1069
      /* byte count doesn't includes \n or \r\n or \r of %%BeginBinary:*/
1070
1.87k
      unsigned long cnt = atoi(dsc->line + 14);
1071
1.87k
      if (dsc->skip_bytes == 0) {
1072
    /* we are not already skipping lines */
1073
1.87k
    dsc->skip_bytes = cnt;
1074
1.87k
      }
1075
1.87k
  }
1076
490k
    }
1077
  
1078
2.37M
    if ((dsc->line[0]=='%') && (dsc->line[1]=='%') &&
1079
490k
  COMPARE(dsc->line, "%%BeginDocument:") ) {
1080
  /* Skip over embedded document, recursively */
1081
1.67k
  dsc->skip_document++;
1082
1.67k
    }
1083
1084
2.37M
    if (!dsc->long_line && (dsc->line_length > DSC_LINE_LENGTH)) {
1085
2.12k
  dsc_error(dsc, CDSC_MESSAGE_LONG_LINE, dsc->line, dsc->line_length);
1086
2.12k
        dsc->long_line = TRUE;
1087
2.12k
    }
1088
  
1089
2.37M
    return dsc->line_length;
1090
2.37M
}
1091
1092
1093
/* Save last DSC line, for use with %%+ */
1094
dsc_private void 
1095
dsc_save_line(CDSC *dsc)
1096
434k
{
1097
434k
    int len = min(sizeof(dsc->last_line), dsc->line_length);
1098
434k
    memcpy(dsc->last_line, dsc->line, len);
1099
434k
}
1100
1101
/* display unknown DSC line */
1102
dsc_private void 
1103
dsc_unknown(CDSC *dsc)
1104
256k
{
1105
256k
    if (dsc->debug_print_fn) {
1106
0
  char line[DSC_LINE_LENGTH];
1107
0
  unsigned int length = min(DSC_LINE_LENGTH-1, dsc->line_length);
1108
0
  sprintf(line, "Unknown in %s section at line %d:\n  ", 
1109
0
      dsc_scan_section_name[dsc->scan_section], dsc->line_count);
1110
0
  dsc_debug_print(dsc, line);
1111
0
  strncpy(line, dsc->line, length);
1112
0
  line[length] = '\0';
1113
0
  dsc_debug_print(dsc, line);
1114
0
    }
1115
256k
}
1116
1117
1118
dsc_private GSBOOL
1119
dsc_is_section(char *line)
1120
307k
{
1121
307k
    if ( !((line[0]=='%') && (line[1]=='%')) )
1122
70.7k
  return FALSE;
1123
236k
    if (IS_DSC(line, "%%BeginPreview"))
1124
442
  return TRUE;
1125
236k
    if (IS_DSC(line, "%%BeginDefaults"))
1126
263
  return TRUE;
1127
236k
    if (IS_DSC(line, "%%BeginProlog"))
1128
32
  return TRUE;
1129
236k
    if (IS_DSC(line, "%%BeginSetup"))
1130
778
  return TRUE;
1131
235k
    if (IS_DSC(line, "%%Page:"))
1132
1.45k
  return TRUE;
1133
233k
    if (IS_DSC(line, "%%Trailer"))
1134
1.20k
  return TRUE;
1135
232k
    if (IS_DSC(line, "%%EOF"))
1136
1.17k
  return TRUE;
1137
231k
    return FALSE;
1138
232k
}
1139
1140
1141
dsc_private GSDWORD
1142
dsc_get_dword(const unsigned char *buf)
1143
4.11k
{
1144
4.11k
    GSDWORD dw;
1145
4.11k
    dw = (GSDWORD)buf[0];
1146
4.11k
    dw += ((GSDWORD)buf[1])<<8;
1147
4.11k
    dw += ((GSDWORD)buf[2])<<16;
1148
4.11k
    dw += ((GSDWORD)buf[3])<<24;
1149
4.11k
    return dw;
1150
4.11k
}
1151
1152
dsc_private GSWORD
1153
dsc_get_word(const unsigned char *buf)
1154
685
{
1155
685
    GSWORD w;
1156
685
    w = (GSWORD)buf[0];
1157
685
    w |= (GSWORD)(buf[1]<<8);
1158
685
    return w;
1159
685
}
1160
1161
dsc_private int
1162
dsc_read_doseps(CDSC *dsc)
1163
685
{
1164
685
    unsigned char *line = (unsigned char *)dsc->line;
1165
685
    dsc_memfree(dsc, dsc->doseps);
1166
685
    if ((dsc->doseps = (CDSCDOSEPS *)dsc_memalloc(dsc, sizeof(CDSCDOSEPS))) == NULL)
1167
0
  return CDSC_ERROR; /* no memory */
1168
  
1169
685
    dsc->doseps->ps_begin = dsc_get_dword(line+4);
1170
685
    dsc->doseps->ps_length = dsc_get_dword(line+8);
1171
685
    dsc->doseps->wmf_begin = dsc_get_dword(line+12);
1172
685
    dsc->doseps->wmf_length = dsc_get_dword(line+16);
1173
685
    dsc->doseps->tiff_begin = dsc_get_dword(line+20);
1174
685
    dsc->doseps->tiff_length = dsc_get_dword(line+24);
1175
685
    dsc->doseps->checksum = dsc_get_word(line+28);
1176
  
1177
685
    dsc->doseps_end = dsc->doseps->ps_begin + dsc->doseps->ps_length;
1178
1179
    /* move data_index backwards to byte after doseps header */
1180
685
    dsc->data_index -= dsc->line_length - 30;
1181
    /* we haven't read a line of PostScript code yet */
1182
685
    dsc->line_count = 0;
1183
    /* skip from current position to start of PostScript section */
1184
685
    dsc->skip_bytes = dsc->doseps->ps_begin - 30;
1185
1186
685
    if (dsc->doseps->tiff_begin)
1187
469
  dsc->preview = CDSC_TIFF;
1188
685
    if (dsc->doseps->wmf_begin)
1189
280
  dsc->preview = CDSC_WMF;
1190
1191
685
    return CDSC_OK;
1192
685
}
1193
1194
1195
1196
dsc_private int 
1197
dsc_parse_pages(CDSC *dsc)
1198
7.81k
{
1199
7.81k
    int ip, io; 
1200
7.81k
    unsigned int i;
1201
7.81k
    char *p;
1202
7.81k
    int n;
1203
7.81k
    if ((dsc->page_pages != 0) && (dsc->scan_section == scan_comments)) {
1204
369
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1205
369
    dsc->line_length);
1206
369
  switch (rc) {
1207
0
      case CDSC_RESPONSE_OK:
1208
369
      case CDSC_RESPONSE_CANCEL:
1209
369
    return CDSC_OK; /* ignore duplicate comments in header */
1210
0
      case CDSC_RESPONSE_IGNORE_ALL:
1211
0
    return CDSC_NOTDSC;
1212
369
  }
1213
369
    }
1214
7.44k
    if ((dsc->page_pages != 0) && (dsc->scan_section == scan_trailer)) {
1215
3.97k
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1216
3.97k
    dsc->line_length);
1217
3.97k
  switch (rc) {
1218
0
      case CDSC_RESPONSE_OK:
1219
3.97k
      case CDSC_RESPONSE_CANCEL:
1220
3.97k
    break;   /* use duplicate comments in header */
1221
0
      case CDSC_RESPONSE_IGNORE_ALL:
1222
0
    return CDSC_NOTDSC;
1223
3.97k
  }
1224
3.97k
    }
1225
1226
7.44k
    n = IS_DSC(dsc->line, "%%+") ? 3 : 8;
1227
428k
    while (IS_WHITE(dsc->line[n]))
1228
421k
  n++;
1229
7.44k
    p = dsc->line + n;
1230
7.44k
    if (COMPARE(p, "atend")) {
1231
155
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, dsc->line_length);
1232
155
  switch (rc) {
1233
0
      case CDSC_RESPONSE_OK:
1234
    /* assume (atend) */
1235
    /* we should mark it as deferred */
1236
0
    break;
1237
155
      case CDSC_RESPONSE_CANCEL:
1238
    /* ignore it */
1239
155
    break;
1240
0
      case CDSC_RESPONSE_IGNORE_ALL:
1241
0
    return CDSC_NOTDSC;
1242
155
  }
1243
155
    }
1244
7.28k
    else if (COMPARE(p, "(atend)")) {
1245
  /* do nothing */
1246
  /* we should mark it as deferred */
1247
173
    }
1248
7.11k
    else {
1249
7.11k
  ip = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1250
7.11k
        if (i) {
1251
2.24k
      n+=i;
1252
2.24k
      dsc->page_pages = ip;
1253
2.24k
      io = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1254
2.24k
      if (i) {
1255
    /* DSC 2 uses extra integer to indicate page order */
1256
    /* DSC 3 uses %%PageOrder: */
1257
1.42k
    if (dsc->page_order == CDSC_ORDER_UNKNOWN)
1258
340
        switch (io) {
1259
20
      case -1:
1260
20
          dsc->page_order = CDSC_DESCEND;
1261
20
          break;
1262
140
      case 0:
1263
140
          dsc->page_order = CDSC_SPECIAL;
1264
140
          break;
1265
8
      case 1:
1266
8
          dsc->page_order = CDSC_ASCEND;
1267
8
          break;
1268
340
        }
1269
1.42k
      }
1270
2.24k
  }
1271
4.87k
  else {
1272
4.87k
      int rc = dsc_error(dsc, CDSC_MESSAGE_INCORRECT_USAGE, dsc->line, 
1273
4.87k
    dsc->line_length);
1274
4.87k
      switch (rc) {
1275
0
    case CDSC_RESPONSE_OK:
1276
4.87k
    case CDSC_RESPONSE_CANCEL:
1277
        /* ignore it */
1278
4.87k
        break;
1279
0
    case CDSC_RESPONSE_IGNORE_ALL:
1280
0
        return CDSC_NOTDSC;
1281
4.87k
      }
1282
4.87k
  }
1283
7.11k
    }
1284
7.44k
    return CDSC_OK;
1285
7.44k
}
1286
1287
dsc_private int 
1288
dsc_parse_bounding_box(CDSC *dsc, CDSCBBOX** pbbox, int offset)
1289
17.3k
{
1290
17.3k
    unsigned int i, n;
1291
17.3k
    int llx, lly, urx, ury;
1292
17.3k
    float fllx, flly, furx, fury;
1293
17.3k
    char *p;
1294
    /* Process first %%BoundingBox: in comments, and last in trailer */
1295
17.3k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_comments)) {
1296
144
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1297
144
    dsc->line_length);
1298
144
  switch (rc) {
1299
0
      case CDSC_RESPONSE_OK:
1300
144
      case CDSC_RESPONSE_CANCEL:
1301
144
    return CDSC_OK; /* ignore duplicate comments in header */
1302
0
      case CDSC_RESPONSE_IGNORE_ALL:
1303
0
    return CDSC_NOTDSC;
1304
144
  }
1305
144
    }
1306
17.2k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_pages)) {
1307
299
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1308
299
    dsc->line_length);
1309
299
  switch (rc) {
1310
0
      case CDSC_RESPONSE_OK:
1311
299
      case CDSC_RESPONSE_CANCEL:
1312
299
    return CDSC_OK; /* ignore duplicate comments in header */
1313
0
      case CDSC_RESPONSE_IGNORE_ALL:
1314
0
    return CDSC_NOTDSC;
1315
299
  }
1316
299
    }
1317
16.9k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_trailer)) {
1318
1.52k
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1319
1.52k
    dsc->line_length);
1320
1.52k
  switch (rc) {
1321
0
      case CDSC_RESPONSE_OK:
1322
1.52k
      case CDSC_RESPONSE_CANCEL:
1323
1.52k
    break;   /* use duplicate comments in trailer */
1324
0
      case CDSC_RESPONSE_IGNORE_ALL:
1325
0
    return CDSC_NOTDSC;
1326
1.52k
  }
1327
1.52k
    }
1328
16.9k
    if (*pbbox != NULL) {
1329
1.81k
  dsc_memfree(dsc, *pbbox);
1330
1.81k
  *pbbox = NULL;
1331
1.81k
    }
1332
1333
    /* should only process first %%BoundingBox: */
1334
1335
18.5k
    while (IS_WHITE(dsc->line[offset]))
1336
1.62k
  offset++;
1337
16.9k
    p = dsc->line + offset;
1338
    
1339
16.9k
    if (COMPARE(p, "atend")) {
1340
249
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, 
1341
249
    dsc->line_length);
1342
249
  switch (rc) {
1343
0
      case CDSC_RESPONSE_OK:
1344
    /* assume (atend) */
1345
    /* we should mark it as deferred */
1346
0
    break;
1347
249
      case CDSC_RESPONSE_CANCEL:
1348
    /* ignore it */
1349
249
    break;
1350
0
      case CDSC_RESPONSE_IGNORE_ALL:
1351
0
    return CDSC_NOTDSC;
1352
249
  }
1353
249
    }
1354
16.7k
    else if (COMPARE(p, "(atend)")) {
1355
  /* do nothing */
1356
  /* we should mark it as deferred */
1357
449
    }
1358
16.2k
    else {
1359
16.2k
        /* llx = */ lly = urx = ury = 0;
1360
16.2k
  n = offset;
1361
16.2k
  llx = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1362
16.2k
  n += i;
1363
16.2k
  if (i)
1364
6.13k
      lly = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1365
16.2k
  n += i;
1366
16.2k
  if (i)
1367
4.67k
      urx = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1368
16.2k
  n += i;
1369
16.2k
  if (i)
1370
3.35k
      ury = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1371
16.2k
  if (i) {
1372
2.42k
      *pbbox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
1373
2.42k
      if (*pbbox == NULL)
1374
0
    return CDSC_ERROR; /* no memory */
1375
2.42k
      (*pbbox)->llx = llx;
1376
2.42k
      (*pbbox)->lly = lly;
1377
2.42k
      (*pbbox)->urx = urx;
1378
2.42k
      (*pbbox)->ury = ury;
1379
2.42k
  }
1380
13.8k
  else {
1381
13.8k
      int rc = dsc_error(dsc, CDSC_MESSAGE_BBOX, dsc->line, 
1382
13.8k
    dsc->line_length);
1383
13.8k
      switch (rc) {
1384
0
        case CDSC_RESPONSE_OK:
1385
0
    /* fllx = */ flly = furx = fury = 0.0;
1386
0
    n = offset;
1387
0
    n += i;
1388
0
    fllx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1389
0
    n += i;
1390
0
    if (i)
1391
0
        flly = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1392
0
    n += i;
1393
0
    if (i)
1394
0
        furx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1395
0
    n += i;
1396
0
    if (i)
1397
0
        fury = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1398
0
    if (i) {
1399
0
        *pbbox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
1400
0
                    if (*pbbox == NULL) {
1401
0
                        return CDSC_ERROR;  /* no memory */
1402
0
                    }
1403
0
                    (*pbbox)->llx = (int)fllx;
1404
0
                    (*pbbox)->lly = (int)flly;
1405
0
                    (*pbbox)->urx = (int)(furx+0.999);
1406
0
                    (*pbbox)->ury = (int)(fury+0.999);
1407
0
                }
1408
0
    return CDSC_OK;
1409
13.8k
      case CDSC_RESPONSE_CANCEL:
1410
13.8k
    return CDSC_OK;
1411
0
      case CDSC_RESPONSE_IGNORE_ALL:
1412
0
    return CDSC_NOTDSC;
1413
13.8k
    }
1414
13.8k
  }
1415
16.2k
    }
1416
3.12k
    return CDSC_OK;
1417
16.9k
}
1418
1419
dsc_private int 
1420
dsc_parse_float_bounding_box(CDSC *dsc, CDSCFBBOX** pbbox, int offset)
1421
12.4k
{
1422
12.4k
    unsigned int i, n;
1423
12.4k
    float fllx, flly, furx, fury;
1424
12.4k
    char *p;
1425
    /* Process first %%HiResBoundingBox: or %%CropBox: in comments, 
1426
     * and last in trailer.
1427
     */
1428
12.4k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_comments)) {
1429
521
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1430
521
    dsc->line_length);
1431
521
  switch (rc) {
1432
0
      case CDSC_RESPONSE_OK:
1433
521
      case CDSC_RESPONSE_CANCEL:
1434
521
    return CDSC_OK; /* ignore duplicate comments in header */
1435
0
      case CDSC_RESPONSE_IGNORE_ALL:
1436
0
    return CDSC_NOTDSC;
1437
521
  }
1438
521
    }
1439
11.9k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_pages)) {
1440
0
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1441
0
    dsc->line_length);
1442
0
  switch (rc) {
1443
0
      case CDSC_RESPONSE_OK:
1444
0
      case CDSC_RESPONSE_CANCEL:
1445
0
    return CDSC_OK; /* ignore duplicate comments in header */
1446
0
      case CDSC_RESPONSE_IGNORE_ALL:
1447
0
    return CDSC_NOTDSC;
1448
0
  }
1449
0
    }
1450
11.9k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_trailer)) {
1451
1.01k
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1452
1.01k
    dsc->line_length);
1453
1.01k
  switch (rc) {
1454
0
      case CDSC_RESPONSE_OK:
1455
1.01k
      case CDSC_RESPONSE_CANCEL:
1456
1.01k
    break;   /* use duplicate comments in trailer */
1457
0
      case CDSC_RESPONSE_IGNORE_ALL:
1458
0
    return CDSC_NOTDSC;
1459
1.01k
  }
1460
1.01k
    }
1461
11.9k
    if (*pbbox != NULL) {
1462
1.01k
  dsc_memfree(dsc, *pbbox);
1463
1.01k
  *pbbox = NULL;
1464
1.01k
    }
1465
1466
    /* should only process first %%BoundingBox: */
1467
1468
12.9k
    while (IS_WHITE(dsc->line[offset]))
1469
998
  offset++;
1470
11.9k
    p = dsc->line + offset;
1471
    
1472
11.9k
    if (COMPARE(p, "atend")) {
1473
247
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, 
1474
247
    dsc->line_length);
1475
247
  switch (rc) {
1476
0
      case CDSC_RESPONSE_OK:
1477
    /* assume (atend) */
1478
    /* we should mark it as deferred */
1479
0
    break;
1480
247
      case CDSC_RESPONSE_CANCEL:
1481
    /* ignore it */
1482
247
    break;
1483
0
      case CDSC_RESPONSE_IGNORE_ALL:
1484
0
    return CDSC_NOTDSC;
1485
247
  }
1486
247
    }
1487
11.7k
    else if (COMPARE(p, "(atend)")) {
1488
  /* do nothing */
1489
  /* we should mark it as deferred */
1490
306
    }
1491
11.4k
    else {
1492
11.4k
  /* fllx = */ flly = furx = fury = 0.0;
1493
11.4k
  n = offset;
1494
11.4k
  fllx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1495
11.4k
  n += i;
1496
11.4k
  if (i)
1497
5.21k
      flly = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1498
11.4k
  n += i;
1499
11.4k
  if (i)
1500
3.10k
      furx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1501
11.4k
  n += i;
1502
11.4k
  if (i)
1503
2.19k
      fury = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1504
11.4k
  if (i) {
1505
1.10k
      *pbbox = (CDSCFBBOX *)dsc_memalloc(dsc, sizeof(CDSCFBBOX));
1506
1.10k
      if (*pbbox == NULL)
1507
0
    return CDSC_ERROR; /* no memory */
1508
1.10k
      (*pbbox)->fllx = fllx;
1509
1.10k
      (*pbbox)->flly = flly;
1510
1.10k
      (*pbbox)->furx = furx;
1511
1.10k
      (*pbbox)->fury = fury;
1512
1.10k
  }
1513
11.4k
    }
1514
11.9k
    return CDSC_OK;
1515
11.9k
}
1516
1517
dsc_private int 
1518
dsc_parse_orientation(CDSC *dsc, unsigned int *porientation, int offset)
1519
3.27k
{
1520
3.27k
    char *p;
1521
3.27k
    if ((dsc->page_orientation != CDSC_ORIENT_UNKNOWN) && 
1522
787
  (dsc->scan_section == scan_comments)) {
1523
164
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1524
164
    dsc->line_length);
1525
164
  switch (rc) {
1526
0
      case CDSC_RESPONSE_OK:
1527
164
      case CDSC_RESPONSE_CANCEL:
1528
164
    return CDSC_OK; /* ignore duplicate comments in header */
1529
0
      case CDSC_RESPONSE_IGNORE_ALL:
1530
0
    return CDSC_NOTDSC;
1531
164
  }
1532
164
    }
1533
3.10k
    if ((dsc->page_orientation != CDSC_ORIENT_UNKNOWN) && 
1534
623
  (dsc->scan_section == scan_trailer)) {
1535
314
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1536
314
    dsc->line_length);
1537
314
  switch (rc) {
1538
0
      case CDSC_RESPONSE_OK:
1539
314
      case CDSC_RESPONSE_CANCEL:
1540
314
    break;   /* use duplicate comments in header; */
1541
0
      case CDSC_RESPONSE_IGNORE_ALL:
1542
0
    return CDSC_NOTDSC;
1543
314
  }
1544
314
    }
1545
3.10k
    p = dsc->line + offset;
1546
3.45k
    while (IS_WHITE(*p))
1547
342
  p++;
1548
3.10k
    if (COMPARE(p, "atend")) {
1549
171
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, dsc->line_length);
1550
171
  switch (rc) {
1551
0
      case CDSC_RESPONSE_OK:
1552
    /* assume (atend) */
1553
    /* we should mark it as deferred */
1554
0
    break;
1555
171
      case CDSC_RESPONSE_CANCEL:
1556
    /* ignore it */
1557
171
    break;
1558
0
      case CDSC_RESPONSE_IGNORE_ALL:
1559
0
    return CDSC_NOTDSC;
1560
171
  }
1561
171
    }
1562
2.93k
    else if (COMPARE(p, "(atend)")) {
1563
  /* do nothing */
1564
  /* we should mark it as deferred */
1565
371
    }
1566
2.56k
    else if (COMPARE(p, "Portrait")) {
1567
252
  *porientation = CDSC_PORTRAIT;
1568
252
    }
1569
2.31k
    else if (COMPARE(p, "Landscape")) {
1570
519
  *porientation = CDSC_LANDSCAPE;
1571
519
    }
1572
1.79k
    else {
1573
1.79k
  dsc_unknown(dsc);
1574
1.79k
    }
1575
3.10k
    return CDSC_OK;
1576
3.10k
}
1577
1578
dsc_private int 
1579
dsc_parse_order(CDSC *dsc)
1580
5.82k
{
1581
5.82k
    char *p;
1582
5.82k
    if ((dsc->page_order != CDSC_ORDER_UNKNOWN) && 
1583
4.07k
  (dsc->scan_section == scan_comments)) {
1584
168
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1585
168
    dsc->line_length);
1586
168
  switch (rc) {
1587
0
      case CDSC_RESPONSE_OK:
1588
168
      case CDSC_RESPONSE_CANCEL:
1589
168
    return CDSC_OK; /* ignore duplicate comments in header */
1590
0
      case CDSC_RESPONSE_IGNORE_ALL:
1591
0
    return CDSC_NOTDSC;
1592
168
  }
1593
168
    }
1594
5.65k
    if ((dsc->page_order != CDSC_ORDER_UNKNOWN) && 
1595
3.90k
  (dsc->scan_section == scan_trailer)) {
1596
3.90k
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1597
3.90k
    dsc->line_length);
1598
3.90k
  switch (rc) {
1599
0
      case CDSC_RESPONSE_OK:
1600
3.90k
      case CDSC_RESPONSE_CANCEL:
1601
3.90k
    break;   /* use duplicate comments in trailer */
1602
0
      case CDSC_RESPONSE_IGNORE_ALL:
1603
0
    return CDSC_NOTDSC;
1604
3.90k
  }
1605
3.90k
    }
1606
1607
5.65k
    p = dsc->line + (IS_DSC(dsc->line, "%%+") ? 3 : 13);
1608
6.05k
    while (IS_WHITE(*p))
1609
405
  p++;
1610
5.65k
    if (COMPARE(p, "atend")) {
1611
452
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, 
1612
452
    dsc->line_length);
1613
452
  switch (rc) {
1614
0
      case CDSC_RESPONSE_OK:
1615
    /* assume (atend) */
1616
    /* we should mark it as deferred */
1617
0
    break;
1618
452
      case CDSC_RESPONSE_CANCEL:
1619
    /* ignore it */
1620
452
    break;
1621
0
      case CDSC_RESPONSE_IGNORE_ALL:
1622
0
    return CDSC_NOTDSC;
1623
452
  }
1624
452
    }
1625
5.20k
    else if (COMPARE(p, "(atend)")) {
1626
  /* do nothing */
1627
  /* we should mark it as deferred */
1628
385
    }
1629
4.81k
    else if (COMPARE(p, "Ascend")) {
1630
250
  dsc->page_order = CDSC_ASCEND;
1631
250
    }
1632
4.56k
    else if (COMPARE(p, "Descend")) {
1633
1.42k
  dsc->page_order = CDSC_DESCEND;
1634
1.42k
    }
1635
3.14k
    else if (COMPARE(p, "Special")) {
1636
195
  dsc->page_order = CDSC_SPECIAL;
1637
195
    }
1638
2.94k
    else {
1639
2.94k
  dsc_unknown(dsc);
1640
2.94k
    }
1641
5.65k
    return CDSC_OK;
1642
5.65k
}
1643
1644
1645
dsc_private int 
1646
dsc_parse_media(CDSC *dsc, const CDSCMEDIA **page_media)
1647
2.82k
{
1648
2.82k
    char media_name[MAXSTR];
1649
2.82k
    int n = IS_DSC(dsc->line, "%%+") ? 3 : 12; /* %%PageMedia: */
1650
2.82k
    unsigned int i;
1651
1652
2.82k
    if (dsc_copy_string(media_name, sizeof(media_name)-1,
1653
2.82k
  dsc->line+n, dsc->line_length-n, NULL)) {
1654
11.3k
  for (i=0; i<dsc->media_count; i++) {
1655
9.60k
      if (dsc->media[i]->name && 
1656
8.30k
    (dsc_stricmp(media_name, dsc->media[i]->name) == 0)) {
1657
1.04k
    *page_media = dsc->media[i];
1658
1.04k
    return CDSC_OK;
1659
1.04k
      }
1660
9.60k
  }
1661
2.82k
    }
1662
1.77k
    dsc_unknown(dsc);
1663
    
1664
1.77k
    return CDSC_OK;
1665
2.82k
}
1666
1667
1668
dsc_private int 
1669
dsc_parse_document_media(CDSC *dsc)
1670
12.5k
{
1671
12.5k
    unsigned int i, n;
1672
12.5k
    CDSCMEDIA lmedia;
1673
12.5k
    GSBOOL blank_line;
1674
1675
12.5k
    if (IS_DSC(dsc->line, "%%DocumentMedia:"))
1676
9.03k
  n = 16;
1677
3.52k
    else if (IS_DSC(dsc->line, "%%+"))
1678
3.52k
  n = 3;
1679
0
    else
1680
0
  return CDSC_ERROR; /* error */
1681
1682
    /* check for blank remainder of line */
1683
12.5k
    blank_line = TRUE;
1684
15.9k
    for (i=n; i<dsc->line_length; i++) {
1685
15.7k
  if (!IS_WHITE_OR_EOL(dsc->line[i])) {
1686
12.3k
      blank_line = FALSE;
1687
12.3k
      break;
1688
12.3k
  }
1689
15.7k
    }
1690
1691
12.5k
    if (!blank_line) {
1692
12.3k
  char name[MAXSTR];
1693
12.3k
  char colour[MAXSTR];
1694
12.3k
  char type[MAXSTR];
1695
12.3k
  lmedia.name = lmedia.colour = lmedia.type = (char *)NULL;
1696
12.3k
  lmedia.width = lmedia.height = lmedia.weight = 0;
1697
12.3k
  lmedia.mediabox = (CDSCBBOX *)NULL;
1698
12.3k
  lmedia.name = dsc_copy_string(name, sizeof(name)-1,
1699
12.3k
    dsc->line+n, dsc->line_length-n, &i);
1700
12.3k
  n+=i;
1701
12.3k
  if (i)
1702
12.3k
      lmedia.width = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1703
12.3k
  n+=i;
1704
12.3k
  if (i)
1705
4.73k
      lmedia.height = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1706
12.3k
  n+=i;
1707
12.3k
  if (i)
1708
3.65k
      lmedia.weight = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1709
12.3k
  n+=i;
1710
12.3k
  if (i)
1711
2.29k
      lmedia.colour = dsc_copy_string(colour, sizeof(colour)-1,
1712
2.29k
    dsc->line+n, dsc->line_length-n, &i);
1713
12.3k
  n+=i;
1714
12.3k
  if (i)
1715
2.29k
      lmedia.type = dsc_copy_string(type, sizeof(type)-1,
1716
2.29k
    dsc->line+n, dsc->line_length-n, &i);
1717
1718
12.3k
  if (i==0)
1719
11.1k
      dsc_unknown(dsc); /* we didn't get all fields */
1720
1.22k
  else {
1721
1.22k
      if (dsc_add_media(dsc, &lmedia))
1722
0
    return CDSC_ERROR; /* out of memory */
1723
1.22k
  }
1724
12.3k
    }
1725
12.5k
    return CDSC_OK;
1726
12.5k
}
1727
1728
/* viewing orientation is believed to be the first four elements of
1729
 * a CTM matrix
1730
 */
1731
dsc_private int 
1732
dsc_parse_viewing_orientation(CDSC *dsc, CDSCCTM **pctm)
1733
5.13k
{
1734
5.13k
    CDSCCTM ctm;
1735
5.13k
    unsigned int i, n;
1736
1737
5.13k
    if (*pctm != NULL) {
1738
778
  dsc_memfree(dsc, *pctm);
1739
778
  *pctm = NULL;
1740
778
    }
1741
1742
5.13k
    n = IS_DSC(dsc->line, "%%+") ? 3 : 21;  /* %%ViewingOrientation: */
1743
23.0k
    while (IS_WHITE(dsc->line[n]))
1744
17.8k
  n++;
1745
1746
    /* ctm.xx = */ ctm.xy = ctm.yx = ctm.yy = 0.0;
1747
5.13k
    ctm.xx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1748
5.13k
    n += i;
1749
5.13k
    if (i)
1750
4.86k
        ctm.xy = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1751
5.13k
    n += i;
1752
5.13k
    if (i)
1753
4.73k
        ctm.yx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1754
5.13k
    n += i;
1755
5.13k
    if (i)
1756
3.18k
        ctm.yy = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1757
5.13k
    if (i==0) {
1758
3.50k
  dsc_unknown(dsc); /* we didn't get all fields */
1759
3.50k
    }
1760
1.63k
    else {
1761
1.63k
  *pctm = (CDSCCTM *)dsc_memalloc(dsc, sizeof(CDSCCTM));
1762
1.63k
  if (*pctm == NULL)
1763
0
      return CDSC_ERROR; /* no memory */
1764
1.63k
  **pctm = ctm;
1765
1.63k
    }
1766
5.13k
    return CDSC_OK;
1767
5.13k
}
1768
   
1769
1770
/* This is called before dsc_read_line(), since we may
1771
 * need to skip a binary header which contains a new line
1772
 * character
1773
 */
1774
dsc_private int 
1775
dsc_scan_type(CDSC *dsc)
1776
27.5k
{
1777
27.5k
    if (dsc->data_index > dsc->data_length)
1778
0
  return CDSC_NOTDSC;
1779
1780
27.5k
    unsigned char *p;
1781
27.5k
    unsigned char *line = (unsigned char *)(dsc->data + dsc->data_index);
1782
27.5k
    int length = dsc->data_length - dsc->data_index;
1783
1784
    /* Types that should be known:
1785
     *   DSC
1786
     *   EPSF
1787
     *   PJL + any of above
1788
     *   ^D + any of above
1789
     *   DOS EPS
1790
     *   PDF
1791
     *   non-DSC
1792
     */
1793
1794
    /* First process any non PostScript headers */
1795
    /* At this stage we do not have a complete line */
1796
1797
27.5k
    if (length == 0)
1798
0
  return CDSC_NEEDMORE;
1799
1800
27.5k
    if (dsc->skip_pjl) {
1801
  /* skip until first PostScript comment */
1802
3.52k
  while (length >= 2) {
1803
272k
      while (length && !IS_EOL(line[0])) {
1804
    /* skip until EOL character */
1805
269k
    line++;
1806
269k
    dsc->data_index++;
1807
269k
    length--;
1808
269k
      }
1809
22.5k
      while ((length >= 2) && IS_EOL(line[0]) && IS_EOL(line[1])) {
1810
    /* skip until EOL followed by non-EOL */
1811
18.9k
    line++;
1812
18.9k
    dsc->data_index++;
1813
18.9k
    length--;
1814
18.9k
      }
1815
3.51k
      if (length < 2)
1816
1.19k
    return CDSC_NEEDMORE;
1817
1818
2.32k
      if (IS_EOL(line[0]) && line[1]=='%') {
1819
98
    line++;
1820
98
    dsc->data_index++;
1821
98
    length--;
1822
98
    dsc->skip_pjl = FALSE;
1823
98
    break;
1824
98
      }
1825
2.22k
      else {
1826
    /* line++; */
1827
2.22k
    dsc->data_index++;
1828
    /* length--; */
1829
2.22k
    return CDSC_NEEDMORE;
1830
2.22k
      }
1831
2.32k
  }
1832
103
  if (dsc->skip_pjl)
1833
5
      return CDSC_NEEDMORE;
1834
103
    }
1835
1836
24.1k
    if (length == 0)
1837
0
  return CDSC_NEEDMORE;
1838
1839
24.1k
    if (line[0] == '\004') {
1840
265
  line++;
1841
265
  dsc->data_index++;
1842
265
  length--;
1843
265
  dsc->ctrld = TRUE;
1844
265
    }
1845
1846
24.1k
    if (line[0] == '\033') {
1847
  /* possibly PJL */
1848
157
  if (length < 9)
1849
0
      return CDSC_NEEDMORE;
1850
157
  if (COMPARE(line, "\033%-12345X")) {
1851
157
      dsc->skip_pjl = TRUE;  /* skip until first PostScript comment */
1852
157
      dsc->pjl = TRUE;
1853
157
      dsc->data_index += 9;
1854
157
      return dsc_scan_type(dsc);
1855
157
  }
1856
157
    }
1857
1858
23.9k
    if ((line[0]==0xc5) && (length < 4))
1859
561
  return CDSC_NEEDMORE;
1860
23.4k
    if ((line[0]==0xc5) && (line[1]==0xd0) && 
1861
4.04k
   (line[2]==0xd3) && (line[3]==0xc6) ) {
1862
  /* id is "EPSF" with bit 7 set */
1863
  /* read DOS EPS header, then ignore all bytes until the PS section */
1864
3.44k
  if (length < 30)
1865
2.76k
      return CDSC_NEEDMORE;
1866
685
  dsc->line = (char *)line;
1867
685
  if (dsc_read_doseps(dsc))
1868
0
      return CDSC_ERROR;
1869
685
    }
1870
19.9k
    else {
1871
19.9k
  if (length < 2)
1872
5.62k
      return CDSC_NEEDMORE;
1873
14.3k
  if ((line[0] == '%') && (line[1] == 'P')) {
1874
2.19k
      if (length < 5)
1875
213
          return CDSC_NEEDMORE;
1876
1.97k
      if (COMPARE(line, "%PDF-")) {
1877
1.51k
    dsc->pdf = TRUE;
1878
1.51k
    dsc->scan_section = scan_comments;
1879
1.51k
    return CDSC_OK;
1880
1.51k
      }
1881
1.97k
  }
1882
14.3k
    }
1883
1884
    /* Finally process PostScript headers */
1885
1886
13.2k
    if (dsc_read_line(dsc) <= 0)
1887
10.5k
  return CDSC_NEEDMORE;
1888
  
1889
2.74k
    dsc->dsc_version = dsc_add_line(dsc, dsc->line, dsc->line_length);
1890
2.74k
    if (COMPARE(dsc->line, "%!PS-Adobe")) {
1891
2.60k
  dsc->dsc = TRUE;
1892
2.60k
  dsc->begincomments = DSC_START(dsc);
1893
2.60k
  if (dsc->dsc_version == NULL)
1894
65
      return CDSC_ERROR;  /* no memory */
1895
2.53k
  p = (unsigned char *)dsc->line + 14;
1896
2.71k
  while (IS_WHITE(*p))
1897
179
      p++;
1898
2.53k
  if (COMPARE(p, "EPSF-"))
1899
0
      dsc->epsf = TRUE;
1900
2.53k
  dsc->scan_section = scan_comments;
1901
2.53k
  return CDSC_PSADOBE;
1902
2.60k
    }
1903
148
    if (COMPARE(dsc->line, "%!")) {
1904
4
  dsc->scan_section = scan_comments;
1905
4
  return CDSC_NOTDSC;
1906
4
    }
1907
1908
144
    dsc->scan_section = scan_comments;
1909
144
    return CDSC_NOTDSC; /* unrecognised */
1910
148
}
1911
1912
1913
1914
dsc_private int 
1915
dsc_scan_comments(CDSC *dsc)
1916
99.0k
{
1917
    /* Comments section ends at */
1918
    /*  %%EndComments */
1919
    /*  another section */
1920
    /*  line that does not start with %% */
1921
    /* Save a few important lines */
1922
1923
99.0k
    char *line = dsc->line;
1924
99.0k
    GSBOOL continued = FALSE;
1925
99.0k
    dsc->id = CDSC_OK;
1926
99.0k
    if (IS_DSC(line, "%%EndComments")) {
1927
3
  dsc->id = CDSC_ENDCOMMENTS;
1928
3
  dsc->endcomments = DSC_END(dsc);
1929
3
  dsc->scan_section = scan_pre_preview;
1930
3
  return CDSC_OK;
1931
3
    }
1932
99.0k
    else if (IS_DSC(line, "%%BeginComments")) {
1933
  /* ignore because we are in this section */
1934
253
  dsc->id = CDSC_BEGINCOMMENTS;
1935
253
    }
1936
98.7k
    else if (dsc_is_section(line)) {
1937
1.36k
  dsc->endcomments = DSC_START(dsc);
1938
1.36k
  dsc->scan_section = scan_pre_preview;
1939
1.36k
  return CDSC_PROPAGATE;
1940
1.36k
    }
1941
97.4k
    else if (line[0] == '%' && IS_WHITE_OR_EOL(line[1])) {
1942
67
  dsc->endcomments = DSC_START(dsc);
1943
67
  dsc->scan_section = scan_pre_preview;
1944
67
  return CDSC_PROPAGATE;
1945
67
    }
1946
97.3k
    else if (line[0] != '%') {
1947
1.56k
  dsc->id = CDSC_OK;
1948
1.56k
  dsc->endcomments = DSC_START(dsc);
1949
1.56k
  dsc->scan_section = scan_pre_preview;
1950
1.56k
  return CDSC_PROPAGATE;
1951
1.56k
    }
1952
95.7k
    else if (IS_DSC(line, "%%Begin")) {
1953
441
  dsc->endcomments = DSC_START(dsc);
1954
441
  dsc->scan_section = scan_pre_preview;
1955
441
  return CDSC_PROPAGATE;
1956
441
    }
1957
1958
    /* Handle continuation lines.
1959
     * To simply processing, we assume that contination lines 
1960
     * will only occur if repeat parameters are allowed and that 
1961
     * a complete set of these parameters appears on each line.  
1962
     * This is more restrictive than the DSC specification, but
1963
     * is valid for the DSC comments understood by this parser
1964
     * for all documents that we have seen.
1965
     */
1966
95.5k
    if (IS_DSC(line, "%%+")) {
1967
19.9k
  line = dsc->last_line;
1968
19.9k
  continued = TRUE;
1969
19.9k
    }
1970
75.6k
    else
1971
75.6k
  dsc_save_line(dsc);
1972
1973
95.5k
    if (IS_DSC(line, "%%Pages:")) {
1974
1.85k
  dsc->id = CDSC_PAGES;
1975
1.85k
  if (dsc_parse_pages(dsc) != 0)
1976
0
      return CDSC_ERROR;
1977
1.85k
    }
1978
93.7k
    else if (IS_DSC(line, "%%Creator:")) {
1979
957
  dsc->id = CDSC_CREATOR;
1980
957
  dsc->dsc_creator = dsc_add_line(dsc, dsc->line+10, dsc->line_length-10);
1981
957
  if (dsc->dsc_creator==NULL)
1982
216
      return CDSC_ERROR;
1983
957
    }
1984
92.7k
    else if (IS_DSC(line, "%%CreationDate:")) {
1985
923
  dsc->id = CDSC_CREATIONDATE;
1986
923
  dsc->dsc_date = dsc_add_line(dsc, dsc->line+15, dsc->line_length-15);
1987
923
  if (dsc->dsc_date==NULL)
1988
184
      return CDSC_ERROR;
1989
923
    }
1990
91.8k
    else if (IS_DSC(line, "%%Title:")) {
1991
1.06k
  dsc->id = CDSC_TITLE;
1992
1.06k
  dsc->dsc_title = dsc_add_line(dsc, dsc->line+8, dsc->line_length-8);
1993
1.06k
  if (dsc->dsc_title==NULL)
1994
147
      return CDSC_ERROR;
1995
1.06k
    }
1996
90.7k
    else if (IS_DSC(line, "%%For:")) {
1997
22.0k
  dsc->id = CDSC_FOR;
1998
22.0k
  dsc->dsc_for = dsc_add_line(dsc, dsc->line+6, dsc->line_length-6);
1999
22.0k
  if (dsc->dsc_for==NULL)
2000
208
      return CDSC_ERROR;
2001
22.0k
    }
2002
68.7k
    else if (IS_DSC(line, "%%LanguageLevel:")) {
2003
3.19k
  unsigned int n = continued ? 3 : 16;
2004
3.19k
  unsigned int i;
2005
3.19k
  int ll;
2006
3.19k
  dsc->id = CDSC_LANGUAGELEVEL;
2007
3.19k
  ll = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
2008
3.19k
  if (i) {
2009
2.11k
      if ( (ll==1) || (ll==2) || (ll==3) )
2010
633
    dsc->language_level = ll;
2011
1.48k
      else {
2012
1.48k
    dsc_unknown(dsc);
2013
1.48k
      }
2014
2.11k
  }
2015
1.07k
  else 
2016
1.07k
      dsc_unknown(dsc);
2017
3.19k
    }
2018
65.5k
    else if (IS_DSC(line, "%%BoundingBox:")) {
2019
2.80k
  dsc->id = CDSC_BOUNDINGBOX;
2020
2.80k
  if (dsc_parse_bounding_box(dsc, &(dsc->bbox), continued ? 3 : 14))
2021
0
      return CDSC_ERROR;
2022
2.80k
    }
2023
62.7k
    else if (IS_DSC(line, "%%HiResBoundingBox:")) {
2024
222
  dsc->id = CDSC_HIRESBOUNDINGBOX;
2025
222
  if (dsc_parse_float_bounding_box(dsc, &(dsc->hires_bbox), 
2026
222
      continued ? 3 : 19))
2027
0
      return CDSC_ERROR;
2028
222
    }
2029
62.5k
    else if (IS_DSC(line, "%%CropBox:")) {
2030
2.10k
  dsc->id = CDSC_CROPBOX;
2031
2.10k
  if (dsc_parse_float_bounding_box(dsc, &(dsc->crop_box), 
2032
2.10k
      continued ? 3 : 10))
2033
0
      return CDSC_ERROR;
2034
2.10k
    }
2035
60.4k
    else if (IS_DSC(line, "%%Orientation:")) {
2036
1.19k
  dsc->id = CDSC_ORIENTATION;
2037
1.19k
  if (dsc_parse_orientation(dsc, &(dsc->page_orientation), 
2038
1.19k
    continued ? 3 : 14))
2039
0
      return CDSC_ERROR;
2040
1.19k
    }
2041
59.2k
    else if (IS_DSC(line, "%%PageOrder:")) {
2042
1.21k
  dsc->id = CDSC_PAGEORDER;
2043
1.21k
  if (dsc_parse_order(dsc))
2044
0
      return CDSC_ERROR;
2045
1.21k
    }
2046
58.0k
    else if (IS_DSC(line, "%%DocumentMedia:")) {
2047
5.20k
  dsc->id = CDSC_DOCUMENTMEDIA;
2048
5.20k
  if (dsc_parse_document_media(dsc))
2049
0
      return CDSC_ERROR;
2050
5.20k
    }
2051
52.8k
    else if (IS_DSC(line, "%%DocumentPaperSizes:")) {
2052
  /* DSC 2.1 */
2053
533
  unsigned int n = continued ? 3 : 21;
2054
533
  unsigned int count = 0;
2055
533
  unsigned int i = 1;
2056
533
  char name[MAXSTR];
2057
533
  char *p;
2058
533
  dsc->id = CDSC_DOCUMENTPAPERSIZES;
2059
2.76k
  while (i && n < dsc->line_length && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
2060
2.22k
      p = dsc_copy_string(name, sizeof(name)-1,
2061
2.22k
        dsc->line+n, dsc->line_length-n, &i);
2062
2.22k
      if (i && p) {
2063
2.22k
    const CDSCMEDIA *m = dsc_known_media;
2064
2.22k
    if (count >= dsc->media_count) {
2065
        /* set some default values */
2066
885
        CDSCMEDIA lmedia;
2067
885
        lmedia.name = p;
2068
885
        lmedia.width = 595.0;
2069
885
        lmedia.height = 842.0;
2070
885
        lmedia.weight = 80.0;
2071
885
        lmedia.colour = NULL;
2072
885
        lmedia.type = NULL;
2073
885
        lmedia.mediabox = NULL;
2074
885
        if (dsc_add_media(dsc, &lmedia))
2075
0
      return CDSC_ERROR;
2076
885
    }
2077
1.34k
    else
2078
1.34k
        dsc->media[count]->name = 
2079
1.34k
      dsc_alloc_string(dsc, p, strlen(p));
2080
    /* find in list of known media */
2081
102k
    while (m && m->name) {
2082
100k
        if (dsc_stricmp(p, m->name)==0) {
2083
0
      dsc->media[count]->width = m->width;
2084
0
      dsc->media[count]->height = m->height;
2085
0
      break;
2086
0
        }
2087
100k
        m++;
2088
100k
    }
2089
2.22k
      }
2090
2.22k
      n+=i;
2091
2.22k
      count++;
2092
2.22k
  }
2093
533
    }
2094
52.3k
    else if (IS_DSC(line, "%%DocumentPaperForms:")) {
2095
  /* DSC 2.1 */
2096
282
  unsigned int n = continued ? 3 : 21;
2097
282
  unsigned int count = 0;
2098
282
  unsigned int i = 1;
2099
282
  char type[MAXSTR];
2100
282
  char *p;
2101
282
  dsc->id = CDSC_DOCUMENTPAPERFORMS;
2102
1.39k
  while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
2103
1.11k
      p = dsc_copy_string(type, sizeof(type)-1,
2104
1.11k
        dsc->line+n, dsc->line_length-n, &i);
2105
1.11k
      if (i && p) {
2106
876
    if (count >= dsc->media_count) {
2107
        /* set some default values */
2108
619
        CDSCMEDIA lmedia;
2109
619
        lmedia.name = NULL;
2110
619
        lmedia.width = 595.0;
2111
619
        lmedia.height = 842.0;
2112
619
        lmedia.weight = 80.0;
2113
619
        lmedia.colour = NULL;
2114
619
        lmedia.type = p;
2115
619
        lmedia.mediabox = NULL;
2116
619
        if (dsc_add_media(dsc, &lmedia))
2117
0
      return CDSC_ERROR;
2118
619
    }
2119
257
    else
2120
257
        dsc->media[count]->type = 
2121
257
      dsc_alloc_string(dsc, p, strlen(p));
2122
876
      }
2123
1.11k
      n+=i;
2124
1.11k
      count++;
2125
1.11k
  }
2126
282
    }
2127
52.0k
    else if (IS_DSC(line, "%%DocumentPaperColors:")) {
2128
  /* DSC 2.1 */
2129
1.35k
  unsigned int n = continued ? 3 : 22;
2130
1.35k
  unsigned int count = 0;
2131
1.35k
  unsigned int i = 1;
2132
1.35k
  char colour[MAXSTR];
2133
1.35k
  char *p;
2134
1.35k
  dsc->id = CDSC_DOCUMENTPAPERCOLORS;
2135
4.52k
  while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
2136
3.16k
      if (n > dsc->line_length) {
2137
0
    break;
2138
0
      }
2139
3.16k
      p = dsc_copy_string(colour, sizeof(colour)-1, 
2140
3.16k
        dsc->line+n, dsc->line_length-n, &i);
2141
3.16k
      if (i && p) {
2142
2.80k
    if (count >= dsc->media_count) {
2143
        /* set some default values */
2144
1.32k
        CDSCMEDIA lmedia;
2145
1.32k
        lmedia.name = NULL;
2146
1.32k
        lmedia.width = 595.0;
2147
1.32k
        lmedia.height = 842.0;
2148
1.32k
        lmedia.weight = 80.0;
2149
1.32k
        lmedia.colour = p;
2150
1.32k
        lmedia.type = NULL;
2151
1.32k
        lmedia.mediabox = NULL;
2152
1.32k
        if (dsc_add_media(dsc, &lmedia))
2153
0
      return CDSC_ERROR;
2154
1.32k
    }
2155
1.47k
    else
2156
1.47k
        dsc->media[count]->colour = 
2157
1.47k
      dsc_alloc_string(dsc, p, strlen(p));
2158
2.80k
      }
2159
3.16k
      n+=i;
2160
3.16k
      count++;
2161
3.16k
  }
2162
1.35k
    }
2163
50.6k
    else if (IS_DSC(line, "%%DocumentPaperWeights:")) {
2164
  /* DSC 2.1 */
2165
1.23k
  unsigned int n = continued ? 3 : 23;
2166
1.23k
  unsigned int count = 0;
2167
1.23k
  unsigned int i = 1;
2168
1.23k
  float w;
2169
1.23k
  dsc->id = CDSC_DOCUMENTPAPERWEIGHTS;
2170
3.85k
  while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
2171
2.62k
      w = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
2172
2.62k
      if (i) {
2173
1.65k
    if (count >= dsc->media_count) {
2174
        /* set some default values */
2175
588
        CDSCMEDIA lmedia;
2176
588
        lmedia.name = NULL;
2177
588
        lmedia.width = 595.0;
2178
588
        lmedia.height = 842.0;
2179
588
        lmedia.weight = w;
2180
588
        lmedia.colour = NULL;
2181
588
        lmedia.type = NULL;
2182
588
        lmedia.mediabox = NULL;
2183
588
        if (dsc_add_media(dsc, &lmedia))
2184
0
      return CDSC_ERROR;
2185
588
    }
2186
1.06k
    else
2187
1.06k
        dsc->media[count]->weight = w;
2188
1.65k
      }
2189
2.62k
      n+=i;
2190
2.62k
      count++;
2191
2.62k
  }
2192
1.23k
    }
2193
49.4k
    else if (IS_DSC(line, "%%DocumentData:")) {
2194
3.14k
  unsigned int n = continued ? 3 : 15;
2195
3.14k
  char *p = dsc->line + n;
2196
3.15k
        while (IS_WHITE(*p))
2197
6
      p++;
2198
3.14k
  dsc->id = CDSC_DOCUMENTDATA;
2199
3.14k
  if (COMPARE(p, "Clean7Bit"))
2200
2.09k
      dsc->document_data = CDSC_CLEAN7BIT;
2201
1.05k
  else if (COMPARE(p, "Clean8Bit"))
2202
223
      dsc->document_data = CDSC_CLEAN8BIT;
2203
835
  else if (COMPARE(p, "Binary"))
2204
164
      dsc->document_data = CDSC_BINARY;
2205
671
  else
2206
671
      dsc_unknown(dsc);
2207
3.14k
    }
2208
46.3k
    else if (IS_DSC(line, "%%Requirements:")) {
2209
14.9k
  dsc->id = CDSC_REQUIREMENTS;
2210
  /* ignore */
2211
14.9k
    }
2212
31.3k
    else if (IS_DSC(line, "%%DocumentNeededFonts:")) {
2213
217
  dsc->id = CDSC_DOCUMENTNEEDEDFONTS;
2214
  /* ignore */
2215
217
    }
2216
31.1k
    else if (IS_DSC(line, "%%DocumentSuppliedFonts:")) {
2217
60
  dsc->id = CDSC_DOCUMENTSUPPLIEDFONTS;
2218
  /* ignore */
2219
60
    }
2220
31.1k
    else if (dsc->line[0] == '%' && IS_WHITE_OR_EOL(dsc->line[1])) {
2221
0
  dsc->id = CDSC_OK;
2222
  /* ignore */
2223
0
    }
2224
31.1k
    else {
2225
31.1k
  dsc->id = CDSC_UNKNOWNDSC;
2226
31.1k
  dsc_unknown(dsc);
2227
31.1k
    }
2228
2229
94.8k
    dsc->endcomments = DSC_END(dsc);
2230
94.8k
    return CDSC_OK;
2231
95.5k
}
2232
2233
2234
dsc_private int 
2235
dsc_scan_preview(CDSC *dsc)
2236
144k
{
2237
    /* Preview section ends at */
2238
    /*  %%EndPreview */
2239
    /*  another section */
2240
    /* Preview section must start with %%BeginPreview */
2241
144k
    char *line = dsc->line;
2242
144k
    dsc->id = CDSC_OK;
2243
2244
144k
    if (dsc->scan_section == scan_pre_preview) {
2245
12.4k
  if (IS_BLANK(line))
2246
9.00k
      return CDSC_OK;  /* ignore blank lines before preview */
2247
3.41k
  else if (IS_DSC(line, "%%BeginPreview")) {
2248
450
      dsc->id = CDSC_BEGINPREVIEW;
2249
450
      dsc->beginpreview = DSC_START(dsc);
2250
450
      dsc->endpreview = DSC_END(dsc);
2251
450
      dsc->scan_section = scan_preview;
2252
      /* Don't mark the preview as EPSI if a DOS EPS header is present */
2253
450
      if (dsc->preview == CDSC_NOPREVIEW)
2254
450
    dsc->preview = CDSC_EPSI;
2255
450
      return CDSC_OK;
2256
450
  }
2257
2.96k
  else {
2258
2.96k
      dsc->scan_section = scan_pre_defaults;
2259
2.96k
      return CDSC_PROPAGATE;
2260
2.96k
  }
2261
12.4k
    }
2262
2263
132k
    if (IS_DSC(line, "%%BeginPreview")) {
2264
  /* ignore because we are in this section */
2265
36.8k
    }
2266
95.7k
    else if (dsc_is_section(line)) {
2267
418
  dsc->endpreview = DSC_START(dsc);
2268
418
  dsc->scan_section = scan_pre_defaults;
2269
418
  return CDSC_PROPAGATE;
2270
418
    }
2271
95.3k
    else if (IS_DSC(line, "%%EndPreview")) {
2272
8
  dsc->id = CDSC_ENDPREVIEW;
2273
8
  dsc->endpreview = DSC_END(dsc);
2274
8
  dsc->scan_section = scan_pre_defaults;
2275
8
  return CDSC_OK;
2276
8
    }
2277
95.3k
    else if (line[0] == '%' && line[1] != '%') {
2278
  /* Ordinary comments are OK */
2279
37.9k
    }
2280
57.3k
    else {
2281
57.3k
  dsc->id = CDSC_UNKNOWNDSC;
2282
  /* DSC comments should not occur in preview */
2283
57.3k
  dsc_unknown(dsc);
2284
57.3k
    }
2285
2286
132k
    dsc->endpreview = DSC_END(dsc);
2287
132k
    return CDSC_OK;
2288
132k
}
2289
2290
dsc_private int
2291
dsc_scan_defaults(CDSC *dsc)
2292
22.0k
{
2293
    /* Defaults section ends at */
2294
    /*  %%EndDefaults */
2295
    /*  another section */
2296
    /* Defaults section must start with %%BeginDefaults */
2297
22.0k
    char *line = dsc->line;
2298
22.0k
    dsc->id = CDSC_OK;
2299
2300
22.0k
    if (dsc->scan_section == scan_pre_defaults) {
2301
3.39k
  if (IS_BLANK(line))
2302
3
      return CDSC_OK;  /* ignore blank lines before defaults */
2303
3.39k
  else if (IS_DSC(line, "%%BeginDefaults")) {
2304
249
      dsc->id = CDSC_BEGINDEFAULTS;
2305
249
      dsc->begindefaults = DSC_START(dsc);
2306
249
      dsc->enddefaults = DSC_END(dsc);
2307
249
      dsc->scan_section = scan_defaults;
2308
249
      return CDSC_OK;
2309
249
  }
2310
3.14k
  else {
2311
3.14k
      dsc->scan_section = scan_pre_prolog;
2312
3.14k
      return CDSC_PROPAGATE;
2313
3.14k
  }
2314
3.39k
    }
2315
2316
18.6k
    if (NOT_DSC_LINE(line)) {
2317
  /* ignore */
2318
12.7k
    }
2319
5.87k
    else if (IS_DSC(line, "%%BeginPreview")) {
2320
  /* ignore because we have already processed this section */
2321
219
    }
2322
5.65k
    else if (IS_DSC(line, "%%BeginDefaults")) {
2323
  /* ignore because we are in this section */
2324
349
    }
2325
5.30k
    else if (dsc_is_section(line)) {
2326
114
  dsc->enddefaults = DSC_START(dsc);
2327
114
  dsc->scan_section = scan_pre_prolog;
2328
114
  return CDSC_PROPAGATE;
2329
114
    }
2330
5.19k
    else if (IS_DSC(line, "%%EndDefaults")) {
2331
14
  dsc->id = CDSC_ENDDEFAULTS;
2332
14
  dsc->enddefaults = DSC_END(dsc);
2333
14
  dsc->scan_section = scan_pre_prolog;
2334
14
  return CDSC_OK;
2335
14
    }
2336
5.18k
    else if (IS_DSC(line, "%%PageMedia:")) {
2337
154
  dsc->id = CDSC_PAGEMEDIA;
2338
154
  dsc_parse_media(dsc, &dsc->page_media);
2339
154
    }
2340
5.02k
    else if (IS_DSC(line, "%%PageOrientation:")) {
2341
324
  dsc->id = CDSC_PAGEORIENTATION;
2342
  /* This can override %%Orientation:  */
2343
324
  if (dsc_parse_orientation(dsc, &(dsc->page_orientation), 18))
2344
0
      return CDSC_ERROR;
2345
324
    }
2346
4.70k
    else if (IS_DSC(line, "%%PageBoundingBox:")) {
2347
566
  dsc->id = CDSC_PAGEBOUNDINGBOX;
2348
566
  if (dsc_parse_bounding_box(dsc, &(dsc->page_bbox), 18))
2349
0
      return CDSC_ERROR;
2350
566
    }
2351
4.13k
    else if (IS_DSC(line, "%%ViewingOrientation:")) {
2352
408
  dsc->id = CDSC_VIEWINGORIENTATION;
2353
408
  if (dsc_parse_viewing_orientation(dsc, &dsc->viewing_orientation))
2354
0
      return CDSC_ERROR;
2355
408
    }
2356
3.72k
    else {
2357
3.72k
  dsc->id = CDSC_UNKNOWNDSC;
2358
  /* All other DSC comments are unknown, but not an error */
2359
3.72k
  dsc_unknown(dsc);
2360
3.72k
    }
2361
18.4k
    dsc->enddefaults = DSC_END(dsc);
2362
18.4k
    return CDSC_OK;
2363
18.6k
}
2364
2365
/* CDSC_RESPONSE_OK and CDSC_RESPONSE_CANCEL mean ignore the 
2366
 * mismatch (default) */
2367
dsc_private int
2368
dsc_check_match_prompt(CDSC *dsc, const char *str, int count)
2369
314k
{
2370
314k
    if (count != 0) {
2371
947
  char buf[MAXSTR+MAXSTR] = "";
2372
947
  if (dsc->line_length < (unsigned int)(sizeof(buf)/2-1))  {
2373
879
      strncpy(buf, dsc->line, dsc->line_length);
2374
879
      buf[dsc->line_length] = '\0';
2375
879
  }
2376
947
  sprintf(buf+strlen(buf), "\n%%%%Begin%.40s: / %%%%End%.40s\n", str, str);
2377
947
  return dsc_error(dsc, CDSC_MESSAGE_BEGIN_END, buf, strlen(buf));
2378
947
    }
2379
314k
    return CDSC_RESPONSE_CANCEL;
2380
314k
}
2381
2382
dsc_private int
2383
dsc_check_match_type(CDSC *dsc, const char *str, int count)
2384
314k
{
2385
314k
    if (dsc_check_match_prompt(dsc, str, count) == CDSC_RESPONSE_IGNORE_ALL)
2386
0
  return CDSC_NOTDSC;
2387
314k
    return CDSC_OK;
2388
314k
}
2389
2390
/* complain if Begin/End blocks didn't match */
2391
/* return non-zero if we should ignore all DSC */
2392
dsc_private int
2393
dsc_check_match(CDSC *dsc)
2394
78.7k
{
2395
78.7k
    int rc = 0;
2396
78.7k
    const char *font = "Font";
2397
78.7k
    const char *feature = "Feature";
2398
78.7k
    const char *resource = "Resource";
2399
78.7k
    const char *procset = "ProcSet";
2400
2401
78.7k
    if (!rc)
2402
78.7k
  rc = dsc_check_match_type(dsc, font, dsc->begin_font_count);
2403
78.7k
    if (!rc)
2404
78.7k
  rc = dsc_check_match_type(dsc, feature, dsc->begin_feature_count);
2405
78.7k
    if (!rc)
2406
78.7k
  rc = dsc_check_match_type(dsc, resource, dsc->begin_resource_count);
2407
78.7k
    if (!rc)
2408
78.7k
  rc = dsc_check_match_type(dsc, procset, dsc->begin_procset_count);
2409
2410
78.7k
    dsc->begin_font_count = 0;
2411
78.7k
    dsc->begin_feature_count = 0;
2412
78.7k
    dsc->begin_resource_count = 0;
2413
78.7k
    dsc->begin_procset_count = 0;
2414
78.7k
    return rc;
2415
78.7k
}
2416
2417
2418
dsc_private int 
2419
dsc_scan_prolog(CDSC *dsc)
2420
247k
{
2421
    /* Prolog section ends at */
2422
    /*  %%EndProlog */
2423
    /*  another section */
2424
    /* Prolog section may start with %%BeginProlog or non-dsc line */
2425
247k
    char *line = dsc->line;
2426
247k
    dsc->id = CDSC_OK;
2427
2428
247k
    if (dsc->scan_section == scan_pre_prolog) {
2429
3.26k
        if (dsc_is_section(line) && (!IS_DSC(line, "%%BeginProlog"))) {
2430
1.24k
      dsc->scan_section = scan_pre_setup;
2431
1.24k
      return CDSC_PROPAGATE;
2432
1.24k
  }
2433
2.02k
  dsc->id = CDSC_BEGINPROLOG;
2434
2.02k
  dsc->beginprolog = DSC_START(dsc);
2435
2.02k
  dsc->endprolog = DSC_END(dsc);
2436
2.02k
  dsc->scan_section = scan_prolog;
2437
2.02k
  if (IS_DSC(line, "%%BeginProlog"))
2438
16
      return CDSC_OK;
2439
2.02k
    }
2440
   
2441
245k
    if (NOT_DSC_LINE(line)) {
2442
  /* ignore */
2443
230k
    }
2444
15.4k
    else if (IS_DSC(line, "%%BeginPreview")) {
2445
  /* ignore because we have already processed this section */
2446
331
    }
2447
15.1k
    else if (IS_DSC(line, "%%BeginDefaults")) {
2448
  /* ignore because we have already processed this section */
2449
263
    }
2450
14.8k
    else if (IS_DSC(line, "%%BeginProlog")) {
2451
  /* ignore because we are in this section */
2452
261
    }
2453
14.6k
    else if (dsc_is_section(line)) {
2454
1.64k
  dsc->endprolog = DSC_START(dsc);
2455
1.64k
  dsc->scan_section = scan_pre_setup;
2456
1.64k
  if (dsc_check_match(dsc))
2457
0
      return CDSC_NOTDSC;
2458
1.64k
  return CDSC_PROPAGATE;
2459
1.64k
    }
2460
12.9k
    else if (IS_DSC(line, "%%EndProlog")) {
2461
118
  dsc->id = CDSC_ENDPROLOG;
2462
118
  dsc->endprolog = DSC_END(dsc);
2463
118
  dsc->scan_section = scan_pre_setup;
2464
118
  if (dsc_check_match(dsc))
2465
0
      return CDSC_NOTDSC;
2466
118
  return CDSC_OK;
2467
118
    }
2468
12.8k
    else if (IS_DSC(line, "%%BeginFont:")) {
2469
221
  dsc->id = CDSC_BEGINFONT;
2470
  /* ignore Begin/EndFont, apart form making sure */
2471
  /* that they are matched. */
2472
221
  dsc->begin_font_count++;
2473
221
    }
2474
12.6k
    else if (IS_DSC(line, "%%EndFont")) {
2475
141
  dsc->id = CDSC_ENDFONT;
2476
141
  dsc->begin_font_count--;
2477
141
    }
2478
12.5k
    else if (IS_DSC(line, "%%BeginFeature:")) {
2479
161
  dsc->id = CDSC_BEGINFEATURE;
2480
  /* ignore Begin/EndFeature, apart form making sure */
2481
  /* that they are matched. */
2482
161
  dsc->begin_feature_count++;
2483
161
    }
2484
12.3k
    else if (IS_DSC(line, "%%EndFeature")) {
2485
451
  dsc->id = CDSC_ENDFEATURE;
2486
451
  dsc->begin_feature_count--;
2487
451
    }
2488
11.9k
    else if (IS_DSC(line, "%%BeginResource:")) {
2489
527
  dsc->id = CDSC_BEGINRESOURCE;
2490
  /* ignore Begin/EndResource, apart form making sure */
2491
  /* that they are matched. */
2492
527
  dsc->begin_resource_count++;
2493
527
    }
2494
11.3k
    else if (IS_DSC(line, "%%EndResource")) {
2495
185
  dsc->id = CDSC_ENDRESOURCE;
2496
185
  dsc->begin_resource_count--;
2497
185
    }
2498
11.1k
    else if (IS_DSC(line, "%%BeginProcSet:")) {
2499
135
  dsc->id = CDSC_BEGINPROCSET;
2500
  /* ignore Begin/EndProcSet, apart form making sure */
2501
  /* that they are matched. */
2502
135
  dsc->begin_procset_count++;
2503
135
    }
2504
11.0k
    else if (IS_DSC(line, "%%EndProcSet")) {
2505
398
  dsc->id = CDSC_ENDPROCSET;
2506
398
  dsc->begin_procset_count--;
2507
398
    }
2508
10.6k
    else {
2509
  /* All other DSC comments are unknown, but not an error */
2510
10.6k
  dsc->id = CDSC_UNKNOWNDSC;
2511
10.6k
  dsc_unknown(dsc);
2512
10.6k
    }
2513
2514
244k
    dsc->endprolog = DSC_END(dsc);
2515
244k
    return CDSC_OK;
2516
245k
}
2517
2518
dsc_private int
2519
dsc_scan_setup(CDSC *dsc)
2520
105k
{
2521
    /* Setup section ends at */
2522
    /*  %%EndSetup */
2523
    /*  another section */
2524
    /* Setup section must start with %%BeginSetup */
2525
2526
105k
    char *line = dsc->line;
2527
105k
    dsc->id = CDSC_OK;
2528
2529
105k
    if (dsc->scan_section == scan_pre_setup) {
2530
5.19k
  if (IS_BLANK(line))
2531
2.19k
      return CDSC_OK;  /* ignore blank lines before setup */
2532
3.00k
  else if (IS_DSC(line, "%%BeginSetup")) {
2533
506
      dsc->id = CDSC_BEGINSETUP;
2534
506
      dsc->beginsetup = DSC_START(dsc);
2535
506
      dsc->endsetup = DSC_END(dsc);
2536
506
      dsc->scan_section = scan_setup;
2537
506
      return CDSC_OK;
2538
506
  }
2539
2.49k
  else {
2540
2.49k
      dsc->scan_section = scan_pre_pages;
2541
2.49k
      return CDSC_PROPAGATE;
2542
2.49k
  }
2543
5.19k
    }
2544
2545
100k
    if (NOT_DSC_LINE(line)) {
2546
  /* ignore */
2547
71.8k
    }
2548
28.2k
    else if (IS_DSC(line, "%%BeginPreview")) {
2549
  /* ignore because we have already processed this section */
2550
331
    }
2551
27.9k
    else if (IS_DSC(line, "%%BeginDefaults")) {
2552
  /* ignore because we have already processed this section */
2553
297
    }
2554
27.6k
    else if (IS_DSC(line, "%%BeginProlog")) {
2555
  /* ignore because we have already processed this section */
2556
433
    }
2557
27.1k
    else if (IS_DSC(line, "%%BeginSetup")) {
2558
  /* ignore because we are in this section */
2559
1.32k
    }
2560
25.8k
    else if (dsc_is_section(line)) {
2561
186
  dsc->endsetup = DSC_START(dsc);
2562
186
  dsc->scan_section = scan_pre_pages;
2563
186
  if (dsc_check_match(dsc))
2564
0
      return CDSC_NOTDSC;
2565
186
  return CDSC_PROPAGATE;
2566
186
    }
2567
25.6k
    else if (IS_DSC(line, "%%EndSetup")) {
2568
4
  dsc->id = CDSC_ENDSETUP;
2569
4
  dsc->endsetup = DSC_END(dsc);
2570
4
  dsc->scan_section = scan_pre_pages;
2571
4
  if (dsc_check_match(dsc))
2572
0
      return CDSC_NOTDSC;
2573
4
  return CDSC_OK;
2574
4
    }
2575
25.6k
    else if (IS_DSC(line, "%%BeginFeature:")) {
2576
227
  dsc->id = CDSC_BEGINFEATURE;
2577
  /* ignore Begin/EndFeature, apart form making sure */
2578
  /* that they are matched. */
2579
227
  dsc->begin_feature_count++;
2580
227
    }
2581
25.4k
    else if (IS_DSC(line, "%%EndFeature")) {
2582
626
  dsc->id = CDSC_ENDFEATURE;
2583
626
  dsc->begin_feature_count--;
2584
626
    }
2585
24.8k
    else if (IS_DSC(line, "%%Feature:")) {
2586
156
  dsc->id = CDSC_FEATURE;
2587
  /* ignore */
2588
156
    }
2589
24.6k
    else if (IS_DSC(line, "%%BeginResource:")) {
2590
486
  dsc->id = CDSC_BEGINRESOURCE;
2591
  /* ignore Begin/EndResource, apart form making sure */
2592
  /* that they are matched. */
2593
486
  dsc->begin_resource_count++;
2594
486
    }
2595
24.1k
    else if (IS_DSC(line, "%%EndResource")) {
2596
321
  dsc->id = CDSC_ENDRESOURCE;
2597
321
  dsc->begin_resource_count--;
2598
321
    }
2599
23.8k
    else if (IS_DSC(line, "%%PaperColor:")) {
2600
2.12k
  dsc->id = CDSC_PAPERCOLOR;
2601
  /* ignore */
2602
2.12k
    }
2603
21.7k
    else if (IS_DSC(line, "%%PaperForm:")) {
2604
500
  dsc->id = CDSC_PAPERFORM;
2605
  /* ignore */
2606
500
    }
2607
21.2k
    else if (IS_DSC(line, "%%PaperWeight:")) {
2608
452
  dsc->id = CDSC_PAPERWEIGHT;
2609
  /* ignore */
2610
452
    }
2611
20.7k
    else if (IS_DSC(line, "%%PaperSize:")) {
2612
  /* DSC 2.1 */
2613
905
        GSBOOL found_media = FALSE;
2614
905
  int i;
2615
905
  int n = 12;
2616
905
  char buf[MAXSTR];
2617
905
  buf[0] = '\0';
2618
905
  dsc->id = CDSC_PAPERSIZE;
2619
905
  dsc_copy_string(buf, sizeof(buf)-1, dsc->line+n, dsc->line_length-n, 
2620
905
    NULL);
2621
3.11k
  for (i=0; i<(int)dsc->media_count; i++) {
2622
2.55k
      if (dsc->media[i] && dsc->media[i]->name && 
2623
717
    (dsc_stricmp(buf, dsc->media[i]->name)==0)) {
2624
344
    dsc->page_media = dsc->media[i];
2625
344
    found_media = TRUE;
2626
344
    break;
2627
344
      }
2628
2.55k
  }
2629
905
  if (!found_media) {
2630
      /* It didn't match %%DocumentPaperSizes: */
2631
      /* Try our known media */
2632
561
      const CDSCMEDIA *m = dsc_known_media;
2633
25.8k
      while (m->name) {
2634
25.2k
    if (dsc_stricmp(buf, m->name)==0) {
2635
0
        dsc->page_media = m;
2636
0
        break;
2637
0
    }
2638
25.2k
    m++;
2639
25.2k
      }
2640
561
      if (m->name == NULL)
2641
561
    dsc_unknown(dsc);
2642
561
  }
2643
905
    }
2644
19.8k
    else {
2645
  /* All other DSC comments are unknown, but not an error */
2646
19.8k
  dsc->id = CDSC_UNKNOWNDSC;
2647
19.8k
  dsc_unknown(dsc);
2648
19.8k
    }
2649
2650
99.9k
    dsc->endsetup = DSC_END(dsc);
2651
99.9k
    return CDSC_OK;
2652
100k
}
2653
2654
dsc_private int 
2655
dsc_scan_page(CDSC *dsc)
2656
1.36M
{
2657
    /* Page section ends at */
2658
    /*  %%Page */
2659
    /*  %%Trailer */
2660
    /*  %%EOF */
2661
1.36M
    char *line = dsc->line;
2662
1.36M
    dsc->id = CDSC_OK;
2663
2664
1.36M
    if (dsc->scan_section == scan_pre_pages) {
2665
300k
  if (IS_DSC(line, "%%Page:")) {
2666
1.23k
      dsc->scan_section = scan_pages;
2667
      /* fall through */
2668
1.23k
  }
2669
299k
  else  {
2670
      /* %%Page: didn't follow %%EndSetup
2671
       * Keep reading until reach %%Page or %%Trailer
2672
       * and add it to previous section.
2673
       */
2674
299k
      unsigned long *last;
2675
299k
      if (dsc->endsetup != 0)
2676
117
    last = &dsc->endsetup;
2677
299k
      else if (dsc->endprolog != 0)
2678
291k
    last = &dsc->endprolog;
2679
7.94k
      else if (dsc->enddefaults != 0)
2680
6.67k
    last = &dsc->enddefaults;
2681
1.27k
      else if (dsc->endpreview != 0)
2682
1.02k
    last = &dsc->endpreview;
2683
247
      else if (dsc->endcomments != 0)
2684
247
    last = &dsc->endcomments;
2685
0
      else
2686
0
    last = &dsc->begincomments;
2687
299k
      *last = DSC_START(dsc);
2688
299k
      if (IS_DSC(line, "%%Trailer") || IS_DSC(line, "%%EOF")) {
2689
1.37k
    dsc->scan_section = scan_pre_trailer;
2690
1.37k
    return CDSC_PROPAGATE;
2691
1.37k
      }
2692
297k
      return CDSC_OK;
2693
299k
  }
2694
300k
    }
2695
2696
1.06M
    if (NOT_DSC_LINE(line)) {
2697
  /* ignore */
2698
923k
    }
2699
143k
    else if (IS_DSC(line, "%%Page:")) {
2700
77.6k
  dsc->id = CDSC_PAGE;
2701
77.6k
  if (dsc->page_count) {
2702
76.4k
      dsc->page[dsc->page_count-1].end = DSC_START(dsc);
2703
76.4k
      if (dsc_check_match(dsc))
2704
0
    return CDSC_NOTDSC;
2705
76.4k
  }
2706
2707
77.6k
  if (dsc_parse_page(dsc) != 0)
2708
0
      return CDSC_ERROR;
2709
2710
77.6k
  return CDSC_OK;
2711
77.6k
    }
2712
65.9k
    else if (IS_DSC(line, "%%BeginPreview")) {
2713
  /* ignore because we have already processed this section */
2714
300
    }
2715
65.6k
    else if (IS_DSC(line, "%%BeginDefaults")) {
2716
  /* ignore because we have already processed this section */
2717
550
    }
2718
65.0k
    else if (IS_DSC(line, "%%BeginProlog")) {
2719
  /* ignore because we have already processed this section */
2720
230
    }
2721
64.8k
    else if (IS_DSC(line, "%%BeginSetup")) {
2722
  /* ignore because we have already processed this section */
2723
753
    }
2724
64.0k
    else if (dsc_is_section(line)) {
2725
360
  if (IS_DSC(line, "%%Trailer")) {
2726
67
      dsc->page[dsc->page_count-1].end = DSC_START(dsc);
2727
67
      if (dsc->file_length) {
2728
0
    if ((!dsc->doseps && 
2729
0
      ((DSC_END(dsc) + 32768) < dsc->file_length)) ||
2730
0
         ((dsc->doseps) && 
2731
0
      ((DSC_END(dsc) + 32768) < dsc->doseps_end))) {
2732
0
        int rc = dsc_error(dsc, CDSC_MESSAGE_EARLY_TRAILER, 
2733
0
      dsc->line, dsc->line_length);
2734
0
        switch (rc) {
2735
0
      case CDSC_RESPONSE_OK:
2736
          /* ignore early trailer */
2737
0
          break;
2738
0
      case CDSC_RESPONSE_CANCEL:
2739
          /* this is the trailer */
2740
0
          dsc->scan_section = scan_pre_trailer;
2741
0
          if (dsc_check_match(dsc))
2742
0
        return CDSC_NOTDSC;
2743
0
          return CDSC_PROPAGATE;
2744
0
      case CDSC_RESPONSE_IGNORE_ALL:
2745
0
          return CDSC_NOTDSC;
2746
0
        }
2747
0
    }
2748
0
    else {
2749
0
        dsc->scan_section = scan_pre_trailer;
2750
0
        if (dsc_check_match(dsc))
2751
0
      return CDSC_NOTDSC;
2752
0
        return CDSC_PROPAGATE;
2753
0
    }
2754
0
      }
2755
67
      else {
2756
67
    dsc->scan_section = scan_pre_trailer;
2757
67
    if (dsc_check_match(dsc))
2758
0
        return CDSC_NOTDSC;
2759
67
    return CDSC_PROPAGATE;
2760
67
      }
2761
67
  }
2762
293
  else if (IS_DSC(line, "%%EOF")) {
2763
293
      dsc->page[dsc->page_count-1].end = DSC_START(dsc);
2764
293
      if (dsc->file_length) {
2765
0
    if ((DSC_END(dsc)+100 < dsc->file_length) ||
2766
0
        (dsc->doseps && (DSC_END(dsc) + 100 < dsc->doseps_end))) {
2767
0
        int rc = dsc_error(dsc, CDSC_MESSAGE_EARLY_EOF, 
2768
0
      dsc->line, dsc->line_length);
2769
0
        switch (rc) {
2770
0
      case CDSC_RESPONSE_OK:
2771
          /* %%EOF is wrong, ignore it */
2772
0
          break;
2773
0
      case CDSC_RESPONSE_CANCEL:
2774
          /* %%EOF is correct */
2775
0
          dsc->scan_section = scan_eof;
2776
0
          dsc->eof = TRUE;
2777
0
          if (dsc_check_match(dsc))
2778
0
        return CDSC_NOTDSC;
2779
0
          return CDSC_PROPAGATE;
2780
0
      case CDSC_RESPONSE_IGNORE_ALL:
2781
0
          return CDSC_NOTDSC;
2782
0
        }
2783
0
    }
2784
0
      }
2785
293
      else {
2786
    /* ignore it */
2787
293
    if (dsc_check_match(dsc))
2788
0
        return CDSC_NOTDSC;
2789
293
    return CDSC_OK;
2790
293
      }
2791
293
  }
2792
0
  else {
2793
      /* Section comment, probably from a badly */
2794
      /* encapsulated EPS file. */
2795
0
      int rc = dsc_error(dsc, CDSC_MESSAGE_BAD_SECTION, 
2796
0
        dsc->line, dsc->line_length);
2797
0
      if (rc == CDSC_RESPONSE_IGNORE_ALL)
2798
0
    return CDSC_NOTDSC;
2799
0
  }
2800
360
    }
2801
63.7k
    else if (IS_DSC(line, "%%PageTrailer")) {
2802
164
  dsc->id = CDSC_PAGETRAILER;
2803
  /* ignore */
2804
164
    }
2805
63.5k
    else if (IS_DSC(line, "%%BeginPageSetup")) {
2806
825
  dsc->id = CDSC_BEGINPAGESETUP;
2807
  /* ignore */
2808
825
    }
2809
62.7k
    else if (IS_DSC(line, "%%EndPageSetup")) {
2810
200
  dsc->id = CDSC_ENDPAGESETUP;
2811
  /* ignore */
2812
200
    }
2813
62.5k
    else if (IS_DSC(line, "%%PageMedia:")) {
2814
2.67k
  dsc->id = CDSC_PAGEMEDIA;
2815
2.67k
  dsc_parse_media(dsc, &(dsc->page[dsc->page_count-1].media));
2816
2.67k
    }
2817
59.8k
    else if (IS_DSC(line, "%%PaperColor:")) {
2818
534
  dsc->id = CDSC_PAPERCOLOR;
2819
  /* ignore */
2820
534
    }
2821
59.3k
    else if (IS_DSC(line, "%%PaperForm:")) {
2822
286
  dsc->id = CDSC_PAPERFORM;
2823
  /* ignore */
2824
286
    }
2825
59.0k
    else if (IS_DSC(line, "%%PaperWeight:")) {
2826
572
  dsc->id = CDSC_PAPERWEIGHT;
2827
  /* ignore */
2828
572
    }
2829
58.4k
    else if (IS_DSC(line, "%%PaperSize:")) {
2830
  /* DSC 2.1 */
2831
2.74k
        GSBOOL found_media = FALSE;
2832
2.74k
  int i;
2833
2.74k
  int n = 12;
2834
2.74k
  char buf[MAXSTR];
2835
2.74k
  buf[0] = '\0';
2836
2.74k
  dsc_copy_string(buf, sizeof(buf)-1, dsc->line+n, 
2837
2.74k
      dsc->line_length-n, NULL);
2838
9.53k
  for (i=0; i<(int)dsc->media_count; i++) {
2839
6.98k
      if (dsc->media[i] && dsc->media[i]->name && 
2840
6.27k
    (dsc_stricmp(buf, dsc->media[i]->name)==0)) {
2841
195
    dsc->page_media = dsc->media[i];
2842
195
    found_media = TRUE;
2843
195
    break;
2844
195
      }
2845
6.98k
  }
2846
2.74k
  if (!found_media) {
2847
      /* It didn't match %%DocumentPaperSizes: */
2848
      /* Try our known media */
2849
2.55k
      const CDSCMEDIA *m = dsc_known_media;
2850
117k
      while (m->name) {
2851
114k
    if (dsc_stricmp(buf, m->name)==0) {
2852
0
        dsc->page[dsc->page_count-1].media = m;
2853
0
        break;
2854
0
    }
2855
114k
    m++;
2856
114k
      }
2857
2.55k
      if (m->name == NULL)
2858
2.55k
    dsc_unknown(dsc);
2859
2.55k
  }
2860
2.74k
    }
2861
55.7k
    else if (IS_DSC(line, "%%PageOrientation:")) {
2862
944
  dsc->id = CDSC_PAGEORIENTATION;
2863
944
  if (dsc_parse_orientation(dsc, 
2864
944
    &(dsc->page[dsc->page_count-1].orientation) ,18))
2865
0
      return CDSC_NOTDSC;
2866
944
    }
2867
54.7k
    else if (IS_DSC(line, "%%PageBoundingBox:")) {
2868
876
  dsc->id = CDSC_PAGEBOUNDINGBOX;
2869
876
  if (dsc_parse_bounding_box(dsc, &dsc->page[dsc->page_count-1].bbox, 18))
2870
0
      return CDSC_NOTDSC;
2871
876
    }
2872
53.8k
    else if (IS_DSC(line, "%%ViewingOrientation:")) {
2873
4.72k
  dsc->id = CDSC_VIEWINGORIENTATION;
2874
4.72k
  if (dsc_parse_viewing_orientation(dsc, 
2875
4.72k
      &dsc->page[dsc->page_count-1].viewing_orientation))
2876
0
      return CDSC_ERROR;
2877
4.72k
    }
2878
49.1k
    else if (IS_DSC(line, "%%BeginFont:")) {
2879
374
  dsc->id = CDSC_BEGINFONT;
2880
  /* ignore Begin/EndFont, apart form making sure */
2881
  /* that they are matched. */
2882
374
  dsc->begin_font_count++;
2883
374
    }
2884
48.7k
    else if (IS_DSC(line, "%%EndFont")) {
2885
261
  dsc->id = CDSC_BEGINFONT;
2886
261
  dsc->begin_font_count--;
2887
261
    }
2888
48.5k
    else if (IS_DSC(line, "%%BeginFeature:")) {
2889
234
  dsc->id = CDSC_BEGINFEATURE;
2890
  /* ignore Begin/EndFeature, apart form making sure */
2891
  /* that they are matched. */
2892
234
  dsc->begin_feature_count++;
2893
234
    }
2894
48.2k
    else if (IS_DSC(line, "%%EndFeature")) {
2895
551
  dsc->id = CDSC_ENDFEATURE;
2896
551
  dsc->begin_feature_count--;
2897
551
    }
2898
47.7k
    else if (IS_DSC(line, "%%BeginResource:")) {
2899
753
  dsc->id = CDSC_BEGINRESOURCE;
2900
  /* ignore Begin/EndResource, apart form making sure */
2901
  /* that they are matched. */
2902
753
  dsc->begin_resource_count++;
2903
753
    }
2904
46.9k
    else if (IS_DSC(line, "%%EndResource")) {
2905
220
  dsc->id = CDSC_ENDRESOURCE;
2906
220
  dsc->begin_resource_count--;
2907
220
    }
2908
46.7k
    else if (IS_DSC(line, "%%BeginProcSet:")) {
2909
829
  dsc->id = CDSC_BEGINPROCSET;
2910
  /* ignore Begin/EndProcSet, apart form making sure */
2911
  /* that they are matched. */
2912
829
  dsc->begin_procset_count++;
2913
829
    }
2914
45.9k
    else if (IS_DSC(line, "%%EndProcSet")) {
2915
139
  dsc->id = CDSC_ENDPROCSET;
2916
139
  dsc->begin_procset_count--;
2917
139
    }
2918
45.8k
    else if (IS_DSC(line, "%%IncludeFont:")) {
2919
316
  dsc->id = CDSC_INCLUDEFONT;
2920
  /* ignore */
2921
316
    }
2922
45.4k
    else {
2923
  /* All other DSC comments are unknown, but not an error */
2924
45.4k
  dsc->id = CDSC_UNKNOWNDSC;
2925
45.4k
  dsc_unknown(dsc);
2926
45.4k
    }
2927
2928
989k
    dsc->page[dsc->page_count-1].end = DSC_END(dsc);
2929
989k
    return CDSC_OK;
2930
1.06M
}
2931
2932
/* Valid Trailer comments are
2933
 * %%Trailer
2934
 * %%EOF
2935
 * or the following deferred with (atend)
2936
 * %%BoundingBox:
2937
 * %%DocumentCustomColors:
2938
 * %%DocumentFiles:
2939
 * %%DocumentFonts:
2940
 * %%DocumentNeededFiles:
2941
 * %%DocumentNeededFonts:
2942
 * %%DocumentNeededProcSets:
2943
 * %%DocumentNeededResources:
2944
 * %%DocumentProcSets:
2945
 * %%DocumentProcessColors:
2946
 * %%DocumentSuppliedFiles:
2947
 * %%DocumentSuppliedFonts:
2948
 * %%DocumentSuppliedProcSets: 
2949
 * %%DocumentSuppliedResources: 
2950
 * %%Orientation: 
2951
 * %%Pages: 
2952
 * %%PageOrder: 
2953
 *
2954
 * Our supported subset is
2955
 * %%Trailer
2956
 * %%EOF
2957
 * %%BoundingBox:
2958
 * %%Orientation: 
2959
 * %%Pages: 
2960
 * %%PageOrder: 
2961
 * In addition to these, we support
2962
 * %%DocumentMedia:
2963
 * 
2964
 * A %%PageTrailer can have the following:
2965
 * %%PageBoundingBox: 
2966
 * %%PageCustomColors: 
2967
 * %%PageFiles: 
2968
 * %%PageFonts: 
2969
 * %%PageOrientation: 
2970
 * %%PageProcessColors: 
2971
 * %%PageResources: 
2972
 */
2973
2974
dsc_private int
2975
dsc_scan_trailer(CDSC *dsc)
2976
382k
{
2977
    /* Trailer section start at */
2978
    /*  %%Trailer */
2979
    /* and ends at */
2980
    /*  %%EOF */
2981
382k
    char *line = dsc->line;
2982
382k
    GSBOOL continued = FALSE;
2983
382k
    dsc->id = CDSC_OK;
2984
2985
382k
    if (dsc->scan_section == scan_pre_trailer) {
2986
1.44k
  if (IS_DSC(line, "%%Trailer")) {
2987
775
      dsc->id = CDSC_TRAILER;
2988
775
      dsc->begintrailer = DSC_START(dsc);
2989
775
      dsc->endtrailer = DSC_END(dsc);
2990
775
      dsc->scan_section = scan_trailer;
2991
775
      return CDSC_OK;
2992
775
  }
2993
671
  else if (IS_DSC(line, "%%EOF")) {
2994
671
      dsc->id = CDSC_EOF;
2995
671
      dsc->begintrailer = DSC_START(dsc);
2996
671
      dsc->endtrailer = DSC_END(dsc);
2997
671
      dsc->scan_section = scan_trailer;
2998
      /* Continue, in case we found %%EOF in an embedded document */
2999
671
      return CDSC_OK;
3000
671
  }
3001
0
  else {
3002
      /* %%Page: didn't follow %%EndSetup
3003
       * Keep reading until reach %%Page or %%Trailer
3004
       * and add it to setup section
3005
       */
3006
      /* append to previous section */
3007
0
      if (dsc->beginsetup)
3008
0
    dsc->endsetup = DSC_END(dsc);
3009
0
      else if (dsc->beginprolog)
3010
0
    dsc->endprolog = DSC_END(dsc);
3011
0
      else {
3012
    /* horribly confused */
3013
0
      }
3014
0
      return CDSC_OK;
3015
0
  }
3016
1.44k
    }
3017
3018
    /* Handle continuation lines.
3019
     * See comment above about our restrictive processing of 
3020
     * continuation lines
3021
     */
3022
380k
    if (IS_DSC(line, "%%+")) {
3023
21.9k
  line = dsc->last_line;
3024
21.9k
  continued = TRUE;
3025
21.9k
    }
3026
358k
    else
3027
358k
  dsc_save_line(dsc);
3028
3029
380k
    if (NOT_DSC_LINE(line)) {
3030
  /* ignore */
3031
267k
    }
3032
112k
    else if (IS_DSC(dsc->line, "%%EOF")) {
3033
  /* Keep scanning, in case we have a false trailer */
3034
4.40k
  dsc->id = CDSC_EOF;
3035
4.40k
    }
3036
108k
    else if (IS_DSC(dsc->line, "%%Trailer")) {
3037
  /* Cope with no pages with code after setup and before trailer. */
3038
  /* Last trailer is the correct one. */
3039
2.10k
  dsc->id = CDSC_TRAILER;
3040
2.10k
  dsc->begintrailer = DSC_START(dsc);
3041
2.10k
    }
3042
106k
    else if (IS_DSC(line, "%%Pages:")) {
3043
5.95k
  dsc->id = CDSC_PAGES;
3044
5.95k
  if (dsc_parse_pages(dsc) != 0)
3045
0
         return CDSC_ERROR;
3046
5.95k
    }
3047
100k
    else if (IS_DSC(line, "%%BoundingBox:")) {
3048
13.1k
  dsc->id = CDSC_BOUNDINGBOX;
3049
13.1k
  if (dsc_parse_bounding_box(dsc, &(dsc->bbox), continued ? 3 : 14))
3050
0
      return CDSC_ERROR;
3051
13.1k
    }
3052
87.2k
    else if (IS_DSC(line, "%%HiResBoundingBox:")) {
3053
194
  dsc->id = CDSC_HIRESBOUNDINGBOX;
3054
194
  if (dsc_parse_float_bounding_box(dsc, &(dsc->hires_bbox), 
3055
194
      continued ? 3 : 19))
3056
0
      return CDSC_ERROR;
3057
194
    }
3058
87.0k
    else if (IS_DSC(line, "%%CropBox:")) {
3059
9.97k
  dsc->id = CDSC_CROPBOX;
3060
9.97k
  if (dsc_parse_float_bounding_box(dsc, &(dsc->crop_box), 
3061
9.97k
      continued ? 3 : 10))
3062
0
      return CDSC_ERROR;
3063
9.97k
    }
3064
77.0k
    else if (IS_DSC(line, "%%Orientation:")) {
3065
810
  dsc->id = CDSC_ORIENTATION;
3066
810
  if (dsc_parse_orientation(dsc, &(dsc->page_orientation), continued ? 3 : 14))
3067
0
      return CDSC_ERROR;
3068
810
    }
3069
76.2k
    else if (IS_DSC(line, "%%PageOrder:")) {
3070
4.61k
  dsc->id = CDSC_PAGEORDER;
3071
4.61k
  if (dsc_parse_order(dsc))
3072
0
      return CDSC_ERROR;
3073
4.61k
    }
3074
71.6k
    else if (IS_DSC(line, "%%DocumentMedia:")) {
3075
7.35k
  dsc->id = CDSC_DOCUMENTMEDIA;
3076
7.35k
  if (dsc_parse_document_media(dsc))
3077
0
      return CDSC_ERROR;
3078
7.35k
    }
3079
64.2k
    else if (IS_DSC(dsc->line, "%%Page:")) {
3080
  /* This should not occur in the trailer, but we might see 
3081
   * this if a document has been incorrectly embedded.
3082
   */
3083
3.49k
  int rc = dsc_error(dsc, CDSC_MESSAGE_PAGE_IN_TRAILER, 
3084
3.49k
    dsc->line, dsc->line_length);
3085
3.49k
  switch (rc) {
3086
0
      case CDSC_RESPONSE_OK:
3087
    /* Assume that we are really in the previous */
3088
    /* page, not the trailer */
3089
0
    dsc->scan_section = scan_pre_pages;
3090
0
    if (dsc->page_count)
3091
0
        dsc->page[dsc->page_count-1].end = DSC_START(dsc);
3092
0
    return CDSC_PROPAGATE; /* try again */
3093
3.49k
      case CDSC_RESPONSE_CANCEL:
3094
    /* ignore pages in trailer */
3095
3.49k
    break;
3096
0
      case CDSC_RESPONSE_IGNORE_ALL:
3097
0
    return CDSC_NOTDSC;
3098
3.49k
  }
3099
3.49k
    }
3100
60.7k
    else if (IS_DSC(line, "%%DocumentNeededFonts:")) {
3101
174
  dsc->id = CDSC_DOCUMENTNEEDEDFONTS;
3102
  /* ignore */
3103
174
    }
3104
60.6k
    else if (IS_DSC(line, "%%DocumentSuppliedFonts:")) {
3105
307
  dsc->id = CDSC_DOCUMENTSUPPLIEDFONTS;
3106
  /* ignore */
3107
307
    }
3108
60.2k
    else {
3109
  /* All other DSC comments are unknown, but not an error */
3110
60.2k
  dsc->id = CDSC_UNKNOWNDSC;
3111
60.2k
  dsc_unknown(dsc);
3112
60.2k
    }
3113
3114
380k
    dsc->endtrailer = DSC_END(dsc);
3115
380k
    return CDSC_OK;
3116
380k
}
3117
3118
3119
dsc_private char *
3120
dsc_alloc_string(CDSC *dsc, const char *str, int len)
3121
114k
{
3122
114k
    if (len < 0) {
3123
747
  return nullptr;
3124
747
    }
3125
3126
114k
    char *p;
3127
114k
    if (dsc->string_head == NULL) {
3128
0
  dsc->string_head = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
3129
0
  if (dsc->string_head == NULL)
3130
0
      return NULL; /* no memory */
3131
0
  dsc->string = dsc->string_head;
3132
0
  dsc->string->next = NULL;
3133
0
  dsc->string->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
3134
0
  if (dsc->string->data == NULL) {
3135
0
      dsc_reset(dsc);
3136
0
      return NULL; /* no memory */
3137
0
  }
3138
0
  dsc->string->index = 0;
3139
0
  dsc->string->length = CDSC_STRING_CHUNK;
3140
0
    }
3141
114k
    if ( dsc->string->index + len + 1 > dsc->string->length) {
3142
  /* allocate another string block */
3143
691
  CDSCSTRING *newstring = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
3144
691
  if (newstring == NULL) {
3145
0
      dsc_debug_print(dsc, "Out of memory\n");
3146
0
      return NULL;
3147
0
  }
3148
691
        newstring->next = NULL;
3149
691
  newstring->length = 0;
3150
691
  newstring->index = 0;
3151
691
  newstring->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
3152
691
  if (newstring->data == NULL) {
3153
0
      dsc_memfree(dsc, newstring);
3154
0
      dsc_debug_print(dsc, "Out of memory\n");
3155
0
      return NULL; /* no memory */
3156
0
  }
3157
691
  newstring->length = CDSC_STRING_CHUNK;
3158
691
  dsc->string->next = newstring;
3159
691
  dsc->string = newstring;
3160
691
    }
3161
114k
    if ( dsc->string->index + len + 1 > dsc->string->length)
3162
109
  return NULL;  /* failed */
3163
114k
    p = dsc->string->data + dsc->string->index;
3164
114k
    memcpy(p, str, len);
3165
114k
    *(p+len) = '\0';
3166
114k
    dsc->string->index += len + 1;
3167
114k
    return p;
3168
114k
}
3169
3170
/* store line, ignoring leading spaces */
3171
dsc_private char *
3172
dsc_add_line(CDSC *dsc, const char *line, unsigned int len)
3173
27.6k
{
3174
27.6k
    char *newline;
3175
27.6k
    unsigned int i;
3176
65.9k
    while (len && (IS_WHITE(*line))) {
3177
38.2k
  len--;
3178
38.2k
  line++;
3179
38.2k
    }
3180
27.6k
    newline = dsc_alloc_string(dsc, line, len);
3181
27.6k
    if (newline == NULL)
3182
856
  return NULL;
3183
3184
1.91M
    for (i=0; i<len; i++) {
3185
1.91M
  if (newline[i] == '\r') {
3186
24.3k
      newline[i]='\0';
3187
24.3k
      break;
3188
24.3k
  }
3189
1.89M
  if (newline[i] == '\n') {
3190
1.81k
      newline[i]='\0';
3191
1.81k
      break;
3192
1.81k
  }
3193
1.89M
    }
3194
26.8k
    return newline;
3195
27.6k
}
3196
3197
3198
/* Copy string on line to new allocated string str */
3199
/* String is always null terminated */
3200
/* String is no longer than len */
3201
/* Return pointer to string  */
3202
/* Store number of used characters from line */
3203
/* Don't copy enclosing () */
3204
dsc_private char *
3205
dsc_copy_string(char *str, unsigned int slen, char *line, 
3206
  unsigned int len, unsigned int *offset)
3207
107k
{
3208
107k
    int quoted = FALSE;
3209
107k
    int instring=0;
3210
107k
    unsigned int newlength = 0;
3211
107k
    unsigned int i = 0;
3212
107k
    unsigned char ch;
3213
107k
    if (len > slen)
3214
6.44k
  len = slen-1;
3215
180k
    while ( (i<len) && IS_WHITE(line[i]))
3216
72.5k
  i++; /* skip leading spaces */
3217
107k
    if (line[i]=='(') {
3218
722
  quoted = TRUE;
3219
722
  instring++;
3220
722
  i++; /* don't copy outside () */
3221
722
    }
3222
1.92M
    while (i < len) {
3223
1.92M
  str[newlength] = ch = line[i];
3224
1.92M
  i++;
3225
1.92M
  if (quoted) {
3226
36.7k
      if (ch == '(')
3227
2.02k
        instring++;
3228
36.7k
      if (ch == ')')
3229
495
        instring--;
3230
36.7k
      if (instring==0)
3231
253
        break;
3232
36.7k
  }
3233
1.88M
  else if (ch == ' ')
3234
10.6k
      break;
3235
3236
1.90M
  if (ch == '\r')
3237
84.5k
      break;
3238
1.82M
  if (ch == '\n')
3239
7.26k
      break;
3240
1.81M
  else if ( (ch == '\\') && (i+1 < len) ) {
3241
19.5k
      ch = line[i];
3242
19.5k
      if ((ch >= '0') && (ch <= '9')) {
3243
    /* octal coded character */
3244
9.74k
    int j = 3;
3245
9.74k
    ch = 0;
3246
34.7k
    while (j && (i < len) && line[i]>='0' && line[i]<='7') {
3247
24.9k
        ch = (unsigned char)((ch<<3) + (line[i]-'0'));
3248
24.9k
        i++;
3249
24.9k
        j--;
3250
24.9k
    }
3251
9.74k
    str[newlength] = ch;
3252
9.74k
      }
3253
9.84k
      else if (ch == '(') {
3254
132
    str[newlength] = ch;
3255
132
    i++;
3256
132
      }
3257
9.71k
      else if (ch == ')') {
3258
167
    str[newlength] = ch;
3259
167
    i++;
3260
167
      }
3261
9.54k
      else if (ch == 'b') {
3262
140
    str[newlength] = '\b';
3263
140
    i++;
3264
140
      }
3265
9.40k
      else if (ch == 'f') {
3266
835
    str[newlength] = '\b';
3267
835
    i++;
3268
835
      }
3269
8.57k
      else if (ch == 'n') {
3270
1.13k
    str[newlength] = '\n';
3271
1.13k
    i++;
3272
1.13k
      }
3273
7.44k
      else if (ch == 'r') {
3274
428
    str[newlength] = '\r';
3275
428
    i++;
3276
428
      }
3277
7.01k
      else if (ch == 't') {
3278
200
    str[newlength] = '\t';
3279
200
    i++;
3280
200
      }
3281
6.81k
      else if (ch == '\\') {
3282
472
    str[newlength] = '\\';
3283
472
    i++;
3284
472
      }
3285
19.5k
  }
3286
1.81M
  newlength++;
3287
1.81M
    }
3288
107k
    str[newlength] = '\0';
3289
107k
    if (offset != (unsigned int *)NULL)
3290
101k
        *offset = i;
3291
107k
    return str;
3292
107k
}
3293
3294
dsc_private int 
3295
dsc_get_int(const char *line, unsigned int len, unsigned int *offset)
3296
42.9k
{
3297
42.9k
    char newline[MAXSTR];
3298
42.9k
    int newlength = 0;
3299
42.9k
    unsigned int i = 0;
3300
42.9k
    unsigned char ch;
3301
3302
42.9k
    len = min(len, sizeof(newline)-1);
3303
453k
    while ((i<len) && IS_WHITE(line[i]))
3304
410k
  i++; /* skip leading spaces */
3305
1.44M
    while (i < len) {
3306
1.43M
  newline[newlength] = ch = line[i];
3307
1.43M
  if (!(isdigit(ch) || (ch=='-') || (ch=='+')))
3308
37.7k
      break;  /* not part of an integer number */
3309
1.39M
  i++;
3310
1.39M
  newlength++;
3311
1.39M
    }
3312
301k
    while ((i<len) && IS_WHITE(line[i]))
3313
258k
  i++; /* skip trailing spaces */
3314
42.9k
    newline[newlength] = '\0';
3315
42.9k
    if (offset != (unsigned int *)NULL)
3316
42.9k
        *offset = i;
3317
42.9k
    return atoi(newline);
3318
42.9k
}
3319
3320
dsc_private float 
3321
dsc_get_real(const char *line, unsigned int len, unsigned int *offset)
3322
63.2k
{
3323
63.2k
    char newline[MAXSTR];
3324
63.2k
    int newlength = 0;
3325
63.2k
    unsigned int i = 0;
3326
63.2k
    unsigned char ch;
3327
3328
63.2k
    len = min(len, sizeof(newline)-1);
3329
431k
    while ((i<len) && IS_WHITE(line[i]))
3330
367k
  i++; /* skip leading spaces */
3331
2.46M
    while (i < len) {
3332
2.44M
  newline[newlength] = ch = line[i];
3333
2.44M
  if (!(isdigit(ch) || (ch=='.') || (ch=='-') || (ch=='+') 
3334
883k
      || (ch=='e') || (ch=='E')))
3335
51.0k
      break;  /* not part of a real number */
3336
2.39M
  i++;
3337
2.39M
  newlength++;
3338
2.39M
    }
3339
430k
    while ((i<len) && IS_WHITE(line[i]))
3340
367k
  i++; /* skip trailing spaces */
3341
3342
63.2k
    newline[newlength] = '\0';
3343
3344
63.2k
    if (offset != (unsigned int *)NULL)
3345
63.2k
        *offset = i;
3346
63.2k
    return (float)atof(newline);
3347
63.2k
}
3348
3349
dsc_private int
3350
dsc_stricmp(const char *s, const char *t)
3351
256k
{
3352
264k
    while (toupper(*s) == toupper(*t)) {
3353
9.45k
  if (*s == '\0')
3354
1.58k
      return 0;
3355
7.86k
    s++;
3356
7.86k
  t++; 
3357
7.86k
    }
3358
254k
    return (toupper(*s) - toupper(*t));
3359
256k
}
3360
3361
3362
dsc_private int
3363
dsc_parse_page(CDSC *dsc)
3364
77.6k
{
3365
77.6k
    char *p;
3366
77.6k
    unsigned int i;
3367
77.6k
    char page_label[MAXSTR];
3368
77.6k
    char *pl;
3369
77.6k
    int page_ordinal;
3370
77.6k
    int page_number;
3371
3372
77.6k
    p = dsc->line + 7;
3373
77.6k
    pl = dsc_copy_string(page_label, sizeof(page_label)-1, p, dsc->line_length-7, &i);
3374
77.6k
    if (pl == NULL)
3375
0
  return CDSC_ERROR;
3376
77.6k
    p += i;
3377
77.6k
    page_ordinal = atoi(p);
3378
3379
77.6k
    if ( (page_ordinal == 0) || (strlen(page_label) == 0) ||
3380
2.42k
       (dsc->page_count && 
3381
77.5k
      (page_ordinal != dsc->page[dsc->page_count-1].ordinal+1)) ) {
3382
77.5k
  int rc = dsc_error(dsc, CDSC_MESSAGE_PAGE_ORDINAL, dsc->line, 
3383
77.5k
    dsc->line_length);
3384
77.5k
  switch (rc) {
3385
0
      case CDSC_RESPONSE_OK:
3386
    /* ignore this page */
3387
0
    return CDSC_OK;
3388
77.5k
      case CDSC_RESPONSE_CANCEL:
3389
    /* accept the page */
3390
77.5k
    break;
3391
0
      case CDSC_RESPONSE_IGNORE_ALL:
3392
0
    return CDSC_NOTDSC;
3393
77.5k
  }
3394
77.5k
    }
3395
3396
77.6k
    page_number = dsc->page_count;
3397
77.6k
    dsc_add_page(dsc, page_ordinal, page_label);
3398
77.6k
    dsc->page[page_number].begin = DSC_START(dsc);
3399
77.6k
    dsc->page[page_number].end = DSC_START(dsc);
3400
3401
77.6k
    if (dsc->page[page_number].label == NULL)
3402
0
  return CDSC_ERROR; /* no memory */
3403
  
3404
77.6k
    return CDSC_OK;
3405
77.6k
}
3406
3407
3408
3409
/* DSC error reporting */
3410
3411
void 
3412
dsc_debug_print(CDSC *dsc, const char *str)
3413
0
{
3414
0
    if (dsc->debug_print_fn)
3415
0
  dsc->debug_print_fn(dsc->caller_data, str);
3416
0
}
3417
3418
3419
/* Display a message about a problem with the DSC comments.
3420
 * 
3421
 * explanation = an index to to a multiline explanation in dsc_message[]
3422
 * line = pointer to the offending DSC line (if any)
3423
 * return code = 
3424
 *   CDSC_RESPONSE_OK          DSC was wrong, make a guess about what 
3425
 *                             was really meant.
3426
 *   CDSC_RESPONSE_CANCEL      Assume DSC was correct, ignore if it 
3427
 *                             is misplaced.
3428
 *   CDSC_RESPONSE_IGNORE_ALL  Ignore all DSC.
3429
 */
3430
/* Silent operation.  Don't display errors. */
3431
dsc_private int 
3432
dsc_error(CDSC *dsc, unsigned int explanation, 
3433
  char *line, unsigned int line_len)
3434
116k
{
3435
    /* if error function provided, use it */
3436
116k
    if (dsc->dsc_error_fn)
3437
0
  return dsc->dsc_error_fn(dsc->caller_data, dsc, 
3438
0
      explanation, line, line_len);
3439
3440
    /* treat DSC as being correct */
3441
116k
    return CDSC_RESPONSE_CANCEL;
3442
116k
}
3443
3444
3445
// vim:sw=4:sts=4:ts=8:noet