Coverage Report

Created: 2026-07-15 07:31

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
5.40M
#define COMPARE(p,str) (strncmp((const char *)(p), (str), sizeof(str)-1)==0)
62
4.83M
#define IS_DSC(line, str) (COMPARE((line), (str)))
63
64
/* Macros for comparing the first one or two characters */
65
790k
#define IS_WHITE(ch) (((ch)==' ') || ((ch)=='\t'))
66
176k
#define IS_EOL(ch) (((ch)=='\r') || ((ch)=='\n'))
67
84.5k
#define IS_WHITE_OR_EOL(ch) (IS_WHITE(ch) || IS_EOL(ch))
68
33.8k
#define IS_BLANK(str) (IS_EOL(str[0]))
69
240k
#define NOT_DSC_LINE(str) (((str)[0]!='%') || ((str)[1]!='%'))
70
71
/* Macros for document offset to start and end of line */
72
70.6k
#define DSC_START(dsc)  ((dsc)->data_offset + (dsc)->data_index - (dsc)->line_length)
73
312k
#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
417k
#define CDSC_PROPAGATE  10
81
82
/* If document is DOS EPS and we haven't read 30 bytes, ask for more. */
83
423k
#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
31.9k
#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
15.9k
{
241
15.9k
    CDSC *dsc = (CDSC *)malloc(sizeof(CDSC));
242
15.9k
    if (dsc == NULL)
243
0
  return NULL;
244
15.9k
    memset(dsc, 0, sizeof(CDSC));
245
15.9k
    dsc->caller_data = caller_data;
246
247
15.9k
    return dsc_init2(dsc);
248
15.9k
}
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
15.9k
{
277
15.9k
    if (dsc == NULL)
278
0
  return;
279
15.9k
    dsc_reset(dsc);
280
15.9k
    dsc_memfree(dsc, dsc);
281
15.9k
}
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
128k
{
303
128k
    int bytes_read;
304
128k
    int code = 0;
305
306
128k
    if (dsc == NULL)
307
0
  return CDSC_ERROR;
308
309
128k
    if (dsc->id == CDSC_NOTDSC)
310
2.64k
  return CDSC_NOTDSC;
311
312
126k
    dsc->id = CDSC_OK;
313
126k
    if (dsc->eof)
314
0
  return CDSC_OK; /* ignore */
315
316
126k
    if (length == 0) {
317
  /* EOF, so process what remains */
318
0
  dsc->eof = TRUE;
319
0
    }
320
321
126k
    do {
322
126k
  if (dsc->id == CDSC_NOTDSC)
323
0
      break;
324
325
126k
  if (length != 0) {
326
126k
      if (dsc->data_index > dsc->data_length)
327
408
    return CDSC_NOTDSC;
328
329
      /* move existing data if needed */
330
125k
      if (dsc->data_length > CDSC_DATA_LENGTH/2) {
331
228
    memmove(dsc->data, dsc->data + dsc->data_index,
332
228
        dsc->data_length - dsc->data_index);
333
228
    dsc->data_offset += dsc->data_index;
334
228
    dsc->data_length -= dsc->data_index;
335
228
    dsc->data_index = 0;
336
228
      }
337
      /* append to buffer */
338
125k
      bytes_read = min(length, (int)(CDSC_DATA_LENGTH - dsc->data_length));
339
125k
      memcpy(dsc->data + dsc->data_length, data, bytes_read);
340
125k
      dsc->data_length += bytes_read;
341
125k
      data += bytes_read;
342
125k
      length -= bytes_read;
343
125k
  }
344
125k
  if (dsc->scan_section == scan_none) {
345
53.8k
      code = dsc_scan_type(dsc);
346
53.8k
      if (code == CDSC_NEEDMORE) {
347
    /* need more characters before we can identify type */
348
38.9k
    code = CDSC_OK;
349
38.9k
    break;
350
38.9k
      }
351
14.9k
      dsc->id = code;
352
14.9k
  }
353
354
86.6k
        if (code == CDSC_NOTDSC) {
355
580
      dsc->id = CDSC_NOTDSC;
356
580
      break;
357
580
  }
358
359
423k
  while ((code = dsc_read_line(dsc)) > 0) {
360
338k
      if (dsc->id == CDSC_NOTDSC)
361
0
    break;
362
338k
      if (dsc->doseps_end && 
363
1.85k
    (dsc->data_offset + dsc->data_index > dsc->doseps_end)) {
364
    /* have read past end of DOS EPS PostScript section */
365
1.09k
    return CDSC_OK; /* ignore */
366
1.09k
      }
367
337k
      if (dsc->eof)
368
0
    return CDSC_OK;
369
337k
      if (dsc->skip_document)
370
3.93k
    continue;  /* embedded document */
371
333k
      if (dsc->skip_lines)
372
0
    continue; /* embedded lines */
373
333k
      if (IS_DSC(dsc->line, "%%BeginData:"))
374
847
    continue;
375
332k
      if (IS_DSC(dsc->line, "%%BeginBinary:"))
376
743
    continue;
377
331k
      if (IS_DSC(dsc->line, "%%EndDocument"))
378
207
    continue;
379
331k
      if (IS_DSC(dsc->line, "%%EndData"))
380
238
    continue;
381
331k
      if (IS_DSC(dsc->line, "%%EndBinary"))
382
369
    continue;
383
384
374k
      do {
385
374k
    switch (dsc->scan_section) {
386
65.1k
        case scan_comments:
387
65.1k
      code = dsc_scan_comments(dsc);
388
65.1k
      break;
389
16.1k
        case scan_pre_preview:
390
39.6k
        case scan_preview:
391
39.6k
      code = dsc_scan_preview(dsc);
392
39.6k
      break;
393
9.96k
        case scan_pre_defaults:
394
26.9k
        case scan_defaults:
395
26.9k
      code = dsc_scan_defaults(dsc);
396
26.9k
      break;
397
8.89k
        case scan_pre_prolog:
398
61.9k
        case scan_prolog:
399
61.9k
      code = dsc_scan_prolog(dsc);
400
61.9k
      break;
401
7.75k
        case scan_pre_setup:
402
36.1k
        case scan_setup:
403
36.1k
      code = dsc_scan_setup(dsc);
404
36.1k
      break;
405
8.66k
        case scan_pre_pages:
406
91.3k
        case scan_pages:
407
91.3k
      code = dsc_scan_page(dsc);
408
91.3k
      break;
409
2.31k
        case scan_pre_trailer:
410
53.4k
        case scan_trailer:
411
53.4k
      code = dsc_scan_trailer(dsc);
412
53.4k
      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
374k
    }
420
    /* repeat if line is start of next section */
421
374k
      } while (code == CDSC_PROPAGATE);
422
423
      /* if DOS EPS header not complete, ask for more */
424
331k
      if (code == CDSC_NEEDMORE) {
425
0
    code = CDSC_OK;
426
0
    break;
427
0
      }
428
331k
      if (code == CDSC_NOTDSC) {
429
0
    dsc->id = CDSC_NOTDSC;
430
0
    break;
431
0
      }
432
331k
  }
433
86.0k
    } while (length != 0);
434
435
124k
    return (code < 0) ? code : dsc->id;
436
126k
}
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
11.1k
{
594
11.1k
    dsc->page[dsc->page_count].ordinal = ordinal;
595
11.1k
    dsc->page[dsc->page_count].label = 
596
11.1k
  dsc_alloc_string(dsc, label, strlen(label)+1);
597
11.1k
    dsc->page[dsc->page_count].begin = 0;
598
11.1k
    dsc->page[dsc->page_count].end = 0;
599
11.1k
    dsc->page[dsc->page_count].orientation = CDSC_ORIENT_UNKNOWN;
600
11.1k
    dsc->page[dsc->page_count].media = NULL;
601
11.1k
    dsc->page[dsc->page_count].bbox = NULL;
602
11.1k
    dsc->page[dsc->page_count].viewing_orientation = NULL;
603
604
11.1k
    dsc->page_count++;
605
11.1k
    if (dsc->page_count >= dsc->page_chunk_length) {
606
14
  CDSCPAGE *new_page = (CDSCPAGE *)dsc_memalloc(dsc, 
607
14
      (CDSC_PAGE_CHUNK+dsc->page_count) * sizeof(CDSCPAGE));
608
14
  if (new_page == NULL)
609
0
      return CDSC_ERROR; /* out of memory */
610
14
  memcpy(new_page, dsc->page, 
611
14
      dsc->page_count * sizeof(CDSCPAGE));
612
14
  dsc_memfree(dsc, dsc->page);
613
14
  dsc->page= new_page;
614
14
  dsc->page_chunk_length = CDSC_PAGE_CHUNK+dsc->page_count;
615
14
    }
616
11.1k
    return CDSC_OK;
617
11.1k
}
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.21k
{
624
4.21k
    CDSCMEDIA **newmedia_array;
625
4.21k
    CDSCMEDIA *newmedia;
626
627
    /* extend media array  */
628
4.21k
    newmedia_array = (CDSCMEDIA **)dsc_memalloc(dsc, 
629
4.21k
  (dsc->media_count + 1) * sizeof(CDSCMEDIA *));
630
4.21k
    if (newmedia_array == NULL)
631
0
  return CDSC_ERROR; /* out of memory */
632
4.21k
    if (dsc->media != NULL) {
633
3.17k
  memcpy(newmedia_array, dsc->media, 
634
3.17k
      dsc->media_count * sizeof(CDSCMEDIA *));
635
3.17k
  dsc_memfree(dsc, dsc->media);
636
3.17k
    }
637
4.21k
    dsc->media = newmedia_array;
638
639
    /* allocate new media */
640
4.21k
    newmedia = dsc->media[dsc->media_count] =
641
4.21k
  (CDSCMEDIA *)dsc_memalloc(dsc, sizeof(CDSCMEDIA));
642
4.21k
    if (newmedia == NULL)
643
0
  return CDSC_ERROR; /* out of memory */
644
4.21k
    newmedia->name = NULL;
645
4.21k
    newmedia->width = 595.0;
646
4.21k
    newmedia->height = 842.0;
647
4.21k
    newmedia->weight = 80.0;
648
4.21k
    newmedia->colour = NULL;
649
4.21k
    newmedia->type = NULL;
650
4.21k
    newmedia->mediabox = NULL;
651
652
4.21k
    dsc->media_count++;
653
654
4.21k
    if (media->name) {
655
1.72k
  newmedia->name = dsc_alloc_string(dsc, media->name,
656
1.72k
      strlen(media->name));
657
1.72k
  if (newmedia->name == NULL)
658
0
      return CDSC_ERROR; /* no memory */
659
1.72k
    }
660
4.21k
    newmedia->width = media->width;
661
4.21k
    newmedia->height = media->height;
662
4.21k
    newmedia->weight = media->weight;
663
4.21k
    if (media->colour) {
664
1.62k
  newmedia->colour = dsc_alloc_string(dsc, media->colour, 
665
1.62k
      strlen(media->colour));
666
1.62k
        if (newmedia->colour == NULL)
667
0
      return CDSC_ERROR; /* no memory */
668
1.62k
    }
669
4.21k
    if (media->type) {
670
629
  newmedia->type = dsc_alloc_string(dsc, media->type, 
671
629
      strlen(media->type));
672
629
  if (newmedia->type == NULL)
673
0
      return CDSC_ERROR; /* no memory */
674
629
    }
675
4.21k
    newmedia->mediabox = NULL;
676
677
4.21k
    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.21k
    return CDSC_OK;
684
4.21k
}
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
60.2k
{
716
60.2k
    if (dsc->memalloc)
717
0
  return dsc->memalloc(size, dsc->mem_closure_data);
718
60.2k
    return malloc(size);
719
60.2k
}
720
721
dsc_private void
722
dsc_memfree(CDSC*dsc, void *ptr)
723
76.8k
{
724
76.8k
    if (dsc->memfree) 
725
0
  dsc->memfree(ptr, dsc->mem_closure_data);
726
76.8k
    else
727
76.8k
  free(ptr);
728
76.8k
}
729
730
/* private constructor */
731
dsc_private CDSC *
732
dsc_init2(CDSC *dsc)
733
15.9k
{
734
15.9k
    dsc_reset(dsc);
735
736
15.9k
    dsc->string_head = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
737
15.9k
    if (dsc->string_head == NULL) {
738
0
  dsc_free(dsc);
739
0
  return NULL; /* no memory */
740
0
    }
741
15.9k
    dsc->string = dsc->string_head;
742
15.9k
    dsc->string->next = NULL;
743
15.9k
    dsc->string->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
744
15.9k
    if (dsc->string->data == NULL) {
745
0
  dsc_free(dsc);
746
0
  return NULL; /* no memory */
747
0
    }
748
15.9k
    dsc->string->index = 0;
749
15.9k
    dsc->string->length = CDSC_STRING_CHUNK;
750
  
751
15.9k
    dsc->page = (CDSCPAGE *)dsc_memalloc(dsc, CDSC_PAGE_CHUNK * sizeof(CDSCPAGE));
752
15.9k
    if (dsc->page == NULL) {
753
0
  dsc_free(dsc);
754
0
  return NULL; /* no memory */
755
0
    }
756
15.9k
    dsc->page_chunk_length = CDSC_PAGE_CHUNK;
757
15.9k
    dsc->page_count = 0;
758
  
759
15.9k
    dsc->line = NULL;
760
15.9k
    dsc->data_length = 0;
761
15.9k
    dsc->data_index = dsc->data_length;
762
763
15.9k
    return dsc;
764
15.9k
}
765
766
767
dsc_private void 
768
dsc_reset(CDSC *dsc)
769
31.9k
{
770
31.9k
    unsigned int i;
771
    /* Clear public members */
772
31.9k
    dsc->dsc = FALSE;
773
31.9k
    dsc->ctrld = FALSE;
774
31.9k
    dsc->pjl = FALSE;
775
31.9k
    dsc->epsf = FALSE;
776
31.9k
    dsc->pdf = FALSE;
777
31.9k
    dsc->epsf = FALSE;
778
31.9k
    dsc->preview = CDSC_NOPREVIEW;
779
31.9k
    dsc->dsc_version = NULL; /* stored in dsc->string */
780
31.9k
    dsc->language_level = 0;
781
31.9k
    dsc->document_data = CDSC_DATA_UNKNOWN;
782
31.9k
    dsc->begincomments = 0;
783
31.9k
    dsc->endcomments = 0;
784
31.9k
    dsc->beginpreview = 0;
785
31.9k
    dsc->endpreview = 0;
786
31.9k
    dsc->begindefaults = 0;
787
31.9k
    dsc->enddefaults = 0;
788
31.9k
    dsc->beginprolog = 0;
789
31.9k
    dsc->endprolog = 0;
790
31.9k
    dsc->beginsetup = 0;
791
31.9k
    dsc->endsetup = 0;
792
31.9k
    dsc->begintrailer = 0;
793
31.9k
    dsc->endtrailer = 0;
794
  
795
43.0k
    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
11.1k
  if (dsc->page[i].bbox)
800
63
      dsc_memfree(dsc, dsc->page[i].bbox);
801
11.1k
  if (dsc->page[i].viewing_orientation)
802
303
      dsc_memfree(dsc, dsc->page[i].viewing_orientation);
803
11.1k
    }
804
31.9k
    if (dsc->page)
805
15.9k
  dsc_memfree(dsc, dsc->page);
806
31.9k
    dsc->page = NULL;
807
  
808
31.9k
    dsc->page_count = 0;
809
31.9k
    dsc->page_pages = 0;
810
31.9k
    dsc->page_order = CDSC_ORDER_UNKNOWN;
811
31.9k
    dsc->page_orientation = CDSC_ORIENT_UNKNOWN;
812
31.9k
    if (dsc->viewing_orientation)
813
80
  dsc_memfree(dsc, dsc->viewing_orientation);
814
31.9k
    dsc->viewing_orientation = NULL;
815
  
816
31.9k
    if (dsc->media) {
817
5.24k
  for (i=0; i<dsc->media_count; i++) {
818
4.21k
      if (dsc->media[i]) {
819
4.21k
    if (dsc->media[i]->mediabox)
820
0
        dsc_memfree(dsc, dsc->media[i]->mediabox);
821
4.21k
    dsc_memfree(dsc, dsc->media[i]);
822
4.21k
      }
823
4.21k
  }
824
1.03k
  dsc_memfree(dsc, dsc->media);
825
1.03k
    }
826
31.9k
    dsc->media_count = 0;
827
31.9k
    dsc->media = NULL;
828
829
    /* page_media is pointer to an element of media or dsc_known_media */
830
    /* do not free it. */
831
31.9k
    dsc->page_media = NULL;
832
833
31.9k
    if (dsc->bbox)
834
724
  dsc_memfree(dsc, dsc->bbox);
835
31.9k
    dsc->bbox = NULL;
836
31.9k
    if (dsc->page_bbox)
837
32
  dsc_memfree(dsc, dsc->page_bbox);
838
31.9k
    dsc->page_bbox = NULL;
839
31.9k
    if (dsc->doseps)
840
599
  dsc_memfree(dsc, dsc->doseps);
841
31.9k
    dsc->doseps = NULL;
842
  
843
31.9k
    dsc->dsc_title = NULL;
844
31.9k
    dsc->dsc_creator = NULL;
845
31.9k
    dsc->dsc_date = NULL;
846
31.9k
    dsc->dsc_for = NULL;
847
  
848
849
31.9k
    dsc->max_error = DSC_MAX_ERROR;
850
31.9k
    dsc->severity = dsc_severity;
851
852
    /* Clear private members */
853
    /* Don't touch dsc->caller_data */
854
31.9k
    dsc->id = CDSC_OK;
855
31.9k
    dsc->scan_section = scan_none;
856
31.9k
    dsc->doseps_end = 0;
857
31.9k
    dsc->page_chunk_length = 0;
858
31.9k
    dsc->file_length = 0;
859
31.9k
    dsc->skip_document = 0;
860
31.9k
    dsc->skip_bytes = 0;
861
31.9k
    dsc->skip_lines = 0;
862
31.9k
    dsc->skip_pjl = 0;
863
31.9k
    dsc->begin_font_count = 0;
864
31.9k
    dsc->begin_feature_count = 0;
865
31.9k
    dsc->begin_resource_count = 0;
866
31.9k
    dsc->begin_procset_count = 0;
867
868
31.9k
    dsc->data_length = 0;
869
31.9k
    dsc->data_index = 0;
870
31.9k
    dsc->data_offset = 0;
871
872
31.9k
    dsc->eof = 0;
873
  
874
31.9k
    dsc->line = 0;
875
31.9k
    dsc->line_length = 0;
876
31.9k
    dsc->eol = 0;
877
31.9k
    dsc->last_cr = FALSE;
878
31.9k
    dsc->line_count = 1;
879
31.9k
    dsc->long_line = FALSE;
880
31.9k
    memset(dsc->last_line, 0, sizeof(dsc->last_line));
881
882
31.9k
    dsc->string = dsc->string_head;
883
47.9k
    while (dsc->string != (CDSCSTRING *)NULL) {
884
15.9k
  if (dsc->string->data)
885
15.9k
      dsc_memfree(dsc, dsc->string->data);
886
15.9k
  dsc->string_head = dsc->string;
887
15.9k
  dsc->string = dsc->string->next;
888
15.9k
  dsc_memfree(dsc, dsc->string_head);
889
15.9k
    }
890
31.9k
    dsc->string_head = NULL;
891
31.9k
    dsc->string = NULL;
892
893
    /* don't touch caller functions */
894
895
    /* public data */
896
31.9k
    if (dsc->hires_bbox)
897
22
  dsc_memfree(dsc, dsc->hires_bbox);
898
31.9k
    dsc->hires_bbox = NULL;
899
31.9k
    if (dsc->crop_box)
900
225
  dsc_memfree(dsc, dsc->crop_box);
901
31.9k
    dsc->crop_box = NULL;
902
31.9k
}
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
450k
{
926
450k
    char *p, *last;
927
450k
    dsc->line = NULL;
928
929
450k
    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
450k
    if (dsc->skip_bytes) {
939
17.4k
  int cnt = min(dsc->skip_bytes,
940
17.4k
         (int)(dsc->data_length - dsc->data_index));
941
17.4k
  dsc->skip_bytes -= cnt;
942
17.4k
  dsc->data_index += cnt;
943
17.4k
  if (dsc->skip_bytes != 0)
944
16.2k
      return 0;
945
17.4k
    }
946
947
433k
    do {
948
433k
  if (dsc->data_index >= dsc->data_length) {
949
73.0k
      dsc->line_length = 0;
950
73.0k
      return 0;
951
73.0k
  }
952
360k
  dsc->line = dsc->data + dsc->data_index;
953
360k
  last = dsc->data + dsc->data_length;
954
360k
  if (dsc->eol) {
955
      /* if previous line was complete, increment line count */
956
344k
      dsc->line_count++;
957
344k
      if (dsc->skip_lines)
958
0
    dsc->skip_lines--;
959
344k
  }
960
      
961
  /* skip over \n which followed \r */
962
360k
  if (dsc->last_cr && dsc->line[0] == '\n') {
963
548
      dsc->data_index++;
964
548
      dsc->line++;
965
548
  }
966
360k
  dsc->last_cr = FALSE;
967
968
  /* look for EOL */
969
360k
  dsc->eol = FALSE;
970
8.90M
  for (p = dsc->line; p < last; p++) {
971
8.89M
      if (*p == '\r') {
972
278k
    p++;
973
278k
    if ((p<last) && (*p == '\n'))
974
1.81k
        p++;  /* include line feed also */
975
276k
    else
976
276k
        dsc->last_cr = TRUE; /* we might need to skip \n */
977
278k
    dsc->eol = TRUE; /* dsc->line is a complete line */
978
278k
    break;
979
278k
      }
980
8.61M
      if (*p == '\n') {
981
69.8k
    p++;
982
69.8k
    dsc->eol = TRUE; /* dsc->line is a complete line */
983
69.8k
    break;
984
69.8k
      }
985
8.54M
      if (*p == '\032') {   /* MS-DOS Ctrl+Z */
986
13.7k
    dsc->eol = TRUE;
987
13.7k
      }
988
8.54M
  }
989
360k
  if (dsc->eol == FALSE) {
990
      /* we haven't got a complete line yet */
991
12.1k
      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
12.1k
  }
997
348k
  dsc->data_index += dsc->line_length = (p - dsc->line);
998
348k
    } while (dsc->skip_lines && dsc->line_length);
999
1000
348k
    if (dsc->line_length == 0)
1001
0
  return 0;
1002
  
1003
348k
    if ((dsc->line[0]=='%') && (dsc->line[1]=='%'))  {
1004
  /* handle recursive %%BeginDocument */
1005
160k
  if ((dsc->skip_document) && dsc->line_length &&
1006
1.24k
    COMPARE(dsc->line, "%%EndDocument")) {
1007
80
      dsc->skip_document--;
1008
80
  }
1009
1010
  /* handle embedded lines or binary data */
1011
160k
  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
855
      char begindata[MAXSTR+1];
1018
855
      int cnt;
1019
855
            unsigned int num;
1020
855
      const char *numberof, *bytesorlines;
1021
855
            if ((num = dsc->line_length) >= sizeof(begindata)-1)
1022
77
                num = sizeof(begindata)-1;
1023
 
1024
855
            memcpy(begindata, dsc->line, num);
1025
855
            begindata[num] = '\0';
1026
855
      numberof = strtok(begindata+12, " \r\n");
1027
855
      strtok(NULL, " \r\n"); /* dump type */
1028
855
      bytesorlines = strtok(NULL, " \r\n");
1029
855
      if (bytesorlines == NULL)
1030
772
    bytesorlines = "Bytes";
1031
     
1032
855
      if ( (numberof == NULL) || (bytesorlines == NULL) ) {
1033
    /* invalid usage of %%BeginData */
1034
    /* ignore that we ever saw it */
1035
141
    int rc = dsc_error(dsc, CDSC_MESSAGE_INCORRECT_USAGE, 
1036
141
          dsc->line, dsc->line_length);
1037
141
    switch (rc) {
1038
0
        case CDSC_RESPONSE_OK:
1039
141
        case CDSC_RESPONSE_CANCEL:
1040
141
      break;
1041
0
        case CDSC_RESPONSE_IGNORE_ALL:
1042
0
      return 0;
1043
141
    }
1044
141
      }
1045
714
      else {
1046
714
    cnt = atoi(numberof);
1047
714
    if (cnt) {
1048
443
        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
443
        else {
1056
      /* byte count doesn't includes \n or \r\n  */
1057
      /* or \r of %%BeginData: */
1058
      /* skip cnt bytes */
1059
443
      if (dsc->skip_bytes == 0) {
1060
          /* we are not already skipping lines */
1061
443
          dsc->skip_bytes = cnt;
1062
443
      }
1063
1064
443
        }
1065
443
    }
1066
714
      }
1067
855
  }
1068
159k
  else if (COMPARE(dsc->line, "%%BeginBinary:")) {
1069
      /* byte count doesn't includes \n or \r\n or \r of %%BeginBinary:*/
1070
747
      unsigned long cnt = atoi(dsc->line + 14);
1071
747
      if (dsc->skip_bytes == 0) {
1072
    /* we are not already skipping lines */
1073
747
    dsc->skip_bytes = cnt;
1074
747
      }
1075
747
  }
1076
160k
    }
1077
  
1078
348k
    if ((dsc->line[0]=='%') && (dsc->line[1]=='%') &&
1079
160k
  COMPARE(dsc->line, "%%BeginDocument:") ) {
1080
  /* Skip over embedded document, recursively */
1081
414
  dsc->skip_document++;
1082
414
    }
1083
1084
348k
    if (!dsc->long_line && (dsc->line_length > DSC_LINE_LENGTH)) {
1085
1.99k
  dsc_error(dsc, CDSC_MESSAGE_LONG_LINE, dsc->line, dsc->line_length);
1086
1.99k
        dsc->long_line = TRUE;
1087
1.99k
    }
1088
  
1089
348k
    return dsc->line_length;
1090
348k
}
1091
1092
1093
/* Save last DSC line, for use with %%+ */
1094
dsc_private void 
1095
dsc_save_line(CDSC *dsc)
1096
83.2k
{
1097
83.2k
    int len = min(sizeof(dsc->last_line), dsc->line_length);
1098
83.2k
    memcpy(dsc->last_line, dsc->line, len);
1099
83.2k
}
1100
1101
/* display unknown DSC line */
1102
dsc_private void 
1103
dsc_unknown(CDSC *dsc)
1104
110k
{
1105
110k
    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
110k
}
1116
1117
1118
dsc_private GSBOOL
1119
dsc_is_section(char *line)
1120
160k
{
1121
160k
    if ( !((line[0]=='%') && (line[1]=='%')) )
1122
39.2k
  return FALSE;
1123
121k
    if (IS_DSC(line, "%%BeginPreview"))
1124
757
  return TRUE;
1125
120k
    if (IS_DSC(line, "%%BeginDefaults"))
1126
1.07k
  return TRUE;
1127
119k
    if (IS_DSC(line, "%%BeginProlog"))
1128
70
  return TRUE;
1129
119k
    if (IS_DSC(line, "%%BeginSetup"))
1130
2.09k
  return TRUE;
1131
117k
    if (IS_DSC(line, "%%Page:"))
1132
4.95k
  return TRUE;
1133
112k
    if (IS_DSC(line, "%%Trailer"))
1134
1.81k
  return TRUE;
1135
110k
    if (IS_DSC(line, "%%EOF"))
1136
2.12k
  return TRUE;
1137
108k
    return FALSE;
1138
110k
}
1139
1140
1141
dsc_private GSDWORD
1142
dsc_get_dword(const unsigned char *buf)
1143
8.41k
{
1144
8.41k
    GSDWORD dw;
1145
8.41k
    dw = (GSDWORD)buf[0];
1146
8.41k
    dw += ((GSDWORD)buf[1])<<8;
1147
8.41k
    dw += ((GSDWORD)buf[2])<<16;
1148
8.41k
    dw += ((GSDWORD)buf[3])<<24;
1149
8.41k
    return dw;
1150
8.41k
}
1151
1152
dsc_private GSWORD
1153
dsc_get_word(const unsigned char *buf)
1154
1.40k
{
1155
1.40k
    GSWORD w;
1156
1.40k
    w = (GSWORD)buf[0];
1157
1.40k
    w |= (GSWORD)(buf[1]<<8);
1158
1.40k
    return w;
1159
1.40k
}
1160
1161
dsc_private int
1162
dsc_read_doseps(CDSC *dsc)
1163
1.40k
{
1164
1.40k
    unsigned char *line = (unsigned char *)dsc->line;
1165
1.40k
    dsc_memfree(dsc, dsc->doseps);
1166
1.40k
    if ((dsc->doseps = (CDSCDOSEPS *)dsc_memalloc(dsc, sizeof(CDSCDOSEPS))) == NULL)
1167
0
  return CDSC_ERROR; /* no memory */
1168
  
1169
1.40k
    dsc->doseps->ps_begin = dsc_get_dword(line+4);
1170
1.40k
    dsc->doseps->ps_length = dsc_get_dword(line+8);
1171
1.40k
    dsc->doseps->wmf_begin = dsc_get_dword(line+12);
1172
1.40k
    dsc->doseps->wmf_length = dsc_get_dword(line+16);
1173
1.40k
    dsc->doseps->tiff_begin = dsc_get_dword(line+20);
1174
1.40k
    dsc->doseps->tiff_length = dsc_get_dword(line+24);
1175
1.40k
    dsc->doseps->checksum = dsc_get_word(line+28);
1176
  
1177
1.40k
    dsc->doseps_end = dsc->doseps->ps_begin + dsc->doseps->ps_length;
1178
1179
    /* move data_index backwards to byte after doseps header */
1180
1.40k
    dsc->data_index -= dsc->line_length - 30;
1181
    /* we haven't read a line of PostScript code yet */
1182
1.40k
    dsc->line_count = 0;
1183
    /* skip from current position to start of PostScript section */
1184
1.40k
    dsc->skip_bytes = dsc->doseps->ps_begin - 30;
1185
1186
1.40k
    if (dsc->doseps->tiff_begin)
1187
1.04k
  dsc->preview = CDSC_TIFF;
1188
1.40k
    if (dsc->doseps->wmf_begin)
1189
821
  dsc->preview = CDSC_WMF;
1190
1191
1.40k
    return CDSC_OK;
1192
1.40k
}
1193
1194
1195
1196
dsc_private int 
1197
dsc_parse_pages(CDSC *dsc)
1198
4.31k
{
1199
4.31k
    int ip, io; 
1200
4.31k
    unsigned int i;
1201
4.31k
    char *p;
1202
4.31k
    int n;
1203
4.31k
    if ((dsc->page_pages != 0) && (dsc->scan_section == scan_comments)) {
1204
309
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1205
309
    dsc->line_length);
1206
309
  switch (rc) {
1207
0
      case CDSC_RESPONSE_OK:
1208
309
      case CDSC_RESPONSE_CANCEL:
1209
309
    return CDSC_OK; /* ignore duplicate comments in header */
1210
0
      case CDSC_RESPONSE_IGNORE_ALL:
1211
0
    return CDSC_NOTDSC;
1212
309
  }
1213
309
    }
1214
4.00k
    if ((dsc->page_pages != 0) && (dsc->scan_section == scan_trailer)) {
1215
925
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1216
925
    dsc->line_length);
1217
925
  switch (rc) {
1218
0
      case CDSC_RESPONSE_OK:
1219
925
      case CDSC_RESPONSE_CANCEL:
1220
925
    break;   /* use duplicate comments in header */
1221
0
      case CDSC_RESPONSE_IGNORE_ALL:
1222
0
    return CDSC_NOTDSC;
1223
925
  }
1224
925
    }
1225
1226
4.00k
    n = IS_DSC(dsc->line, "%%+") ? 3 : 8;
1227
17.5k
    while (IS_WHITE(dsc->line[n]))
1228
13.5k
  n++;
1229
4.00k
    p = dsc->line + n;
1230
4.00k
    if (COMPARE(p, "atend")) {
1231
251
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, dsc->line_length);
1232
251
  switch (rc) {
1233
0
      case CDSC_RESPONSE_OK:
1234
    /* assume (atend) */
1235
    /* we should mark it as deferred */
1236
0
    break;
1237
251
      case CDSC_RESPONSE_CANCEL:
1238
    /* ignore it */
1239
251
    break;
1240
0
      case CDSC_RESPONSE_IGNORE_ALL:
1241
0
    return CDSC_NOTDSC;
1242
251
  }
1243
251
    }
1244
3.75k
    else if (COMPARE(p, "(atend)")) {
1245
  /* do nothing */
1246
  /* we should mark it as deferred */
1247
230
    }
1248
3.52k
    else {
1249
3.52k
  ip = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1250
3.52k
        if (i) {
1251
1.55k
      n+=i;
1252
1.55k
      dsc->page_pages = ip;
1253
1.55k
      io = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1254
1.55k
      if (i) {
1255
    /* DSC 2 uses extra integer to indicate page order */
1256
    /* DSC 3 uses %%PageOrder: */
1257
857
    if (dsc->page_order == CDSC_ORDER_UNKNOWN)
1258
666
        switch (io) {
1259
19
      case -1:
1260
19
          dsc->page_order = CDSC_DESCEND;
1261
19
          break;
1262
128
      case 0:
1263
128
          dsc->page_order = CDSC_SPECIAL;
1264
128
          break;
1265
32
      case 1:
1266
32
          dsc->page_order = CDSC_ASCEND;
1267
32
          break;
1268
666
        }
1269
857
      }
1270
1.55k
  }
1271
1.97k
  else {
1272
1.97k
      int rc = dsc_error(dsc, CDSC_MESSAGE_INCORRECT_USAGE, dsc->line, 
1273
1.97k
    dsc->line_length);
1274
1.97k
      switch (rc) {
1275
0
    case CDSC_RESPONSE_OK:
1276
1.97k
    case CDSC_RESPONSE_CANCEL:
1277
        /* ignore it */
1278
1.97k
        break;
1279
0
    case CDSC_RESPONSE_IGNORE_ALL:
1280
0
        return CDSC_NOTDSC;
1281
1.97k
      }
1282
1.97k
  }
1283
3.52k
    }
1284
4.00k
    return CDSC_OK;
1285
4.00k
}
1286
1287
dsc_private int 
1288
dsc_parse_bounding_box(CDSC *dsc, CDSCBBOX** pbbox, int offset)
1289
7.76k
{
1290
7.76k
    unsigned int i, n;
1291
7.76k
    int llx, lly, urx, ury;
1292
7.76k
    float fllx, flly, furx, fury;
1293
7.76k
    char *p;
1294
    /* Process first %%BoundingBox: in comments, and last in trailer */
1295
7.76k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_comments)) {
1296
215
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1297
215
    dsc->line_length);
1298
215
  switch (rc) {
1299
0
      case CDSC_RESPONSE_OK:
1300
215
      case CDSC_RESPONSE_CANCEL:
1301
215
    return CDSC_OK; /* ignore duplicate comments in header */
1302
0
      case CDSC_RESPONSE_IGNORE_ALL:
1303
0
    return CDSC_NOTDSC;
1304
215
  }
1305
215
    }
1306
7.55k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_pages)) {
1307
79
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1308
79
    dsc->line_length);
1309
79
  switch (rc) {
1310
0
      case CDSC_RESPONSE_OK:
1311
79
      case CDSC_RESPONSE_CANCEL:
1312
79
    return CDSC_OK; /* ignore duplicate comments in header */
1313
0
      case CDSC_RESPONSE_IGNORE_ALL:
1314
0
    return CDSC_NOTDSC;
1315
79
  }
1316
79
    }
1317
7.47k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_trailer)) {
1318
181
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1319
181
    dsc->line_length);
1320
181
  switch (rc) {
1321
0
      case CDSC_RESPONSE_OK:
1322
181
      case CDSC_RESPONSE_CANCEL:
1323
181
    break;   /* use duplicate comments in trailer */
1324
0
      case CDSC_RESPONSE_IGNORE_ALL:
1325
0
    return CDSC_NOTDSC;
1326
181
  }
1327
181
    }
1328
7.47k
    if (*pbbox != NULL) {
1329
279
  dsc_memfree(dsc, *pbbox);
1330
279
  *pbbox = NULL;
1331
279
    }
1332
1333
    /* should only process first %%BoundingBox: */
1334
1335
9.36k
    while (IS_WHITE(dsc->line[offset]))
1336
1.89k
  offset++;
1337
7.47k
    p = dsc->line + offset;
1338
    
1339
7.47k
    if (COMPARE(p, "atend")) {
1340
725
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, 
1341
725
    dsc->line_length);
1342
725
  switch (rc) {
1343
0
      case CDSC_RESPONSE_OK:
1344
    /* assume (atend) */
1345
    /* we should mark it as deferred */
1346
0
    break;
1347
725
      case CDSC_RESPONSE_CANCEL:
1348
    /* ignore it */
1349
725
    break;
1350
0
      case CDSC_RESPONSE_IGNORE_ALL:
1351
0
    return CDSC_NOTDSC;
1352
725
  }
1353
725
    }
1354
6.74k
    else if (COMPARE(p, "(atend)")) {
1355
  /* do nothing */
1356
  /* we should mark it as deferred */
1357
614
    }
1358
6.13k
    else {
1359
6.13k
        /* llx = */ lly = urx = ury = 0;
1360
6.13k
  n = offset;
1361
6.13k
  llx = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1362
6.13k
  n += i;
1363
6.13k
  if (i)
1364
2.63k
      lly = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1365
6.13k
  n += i;
1366
6.13k
  if (i)
1367
1.93k
      urx = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1368
6.13k
  n += i;
1369
6.13k
  if (i)
1370
1.48k
      ury = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1371
6.13k
  if (i) {
1372
1.09k
      *pbbox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
1373
1.09k
      if (*pbbox == NULL)
1374
0
    return CDSC_ERROR; /* no memory */
1375
1.09k
      (*pbbox)->llx = llx;
1376
1.09k
      (*pbbox)->lly = lly;
1377
1.09k
      (*pbbox)->urx = urx;
1378
1.09k
      (*pbbox)->ury = ury;
1379
1.09k
  }
1380
5.03k
  else {
1381
5.03k
      int rc = dsc_error(dsc, CDSC_MESSAGE_BBOX, dsc->line, 
1382
5.03k
    dsc->line_length);
1383
5.03k
      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
5.03k
      case CDSC_RESPONSE_CANCEL:
1410
5.03k
    return CDSC_OK;
1411
0
      case CDSC_RESPONSE_IGNORE_ALL:
1412
0
    return CDSC_NOTDSC;
1413
5.03k
    }
1414
5.03k
  }
1415
6.13k
    }
1416
2.43k
    return CDSC_OK;
1417
7.47k
}
1418
1419
dsc_private int 
1420
dsc_parse_float_bounding_box(CDSC *dsc, CDSCFBBOX** pbbox, int offset)
1421
5.67k
{
1422
5.67k
    unsigned int i, n;
1423
5.67k
    float fllx, flly, furx, fury;
1424
5.67k
    char *p;
1425
    /* Process first %%HiResBoundingBox: or %%CropBox: in comments, 
1426
     * and last in trailer.
1427
     */
1428
5.67k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_comments)) {
1429
140
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1430
140
    dsc->line_length);
1431
140
  switch (rc) {
1432
0
      case CDSC_RESPONSE_OK:
1433
140
      case CDSC_RESPONSE_CANCEL:
1434
140
    return CDSC_OK; /* ignore duplicate comments in header */
1435
0
      case CDSC_RESPONSE_IGNORE_ALL:
1436
0
    return CDSC_NOTDSC;
1437
140
  }
1438
140
    }
1439
5.53k
    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
5.53k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_trailer)) {
1451
249
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1452
249
    dsc->line_length);
1453
249
  switch (rc) {
1454
0
      case CDSC_RESPONSE_OK:
1455
249
      case CDSC_RESPONSE_CANCEL:
1456
249
    break;   /* use duplicate comments in trailer */
1457
0
      case CDSC_RESPONSE_IGNORE_ALL:
1458
0
    return CDSC_NOTDSC;
1459
249
  }
1460
249
    }
1461
5.53k
    if (*pbbox != NULL) {
1462
249
  dsc_memfree(dsc, *pbbox);
1463
249
  *pbbox = NULL;
1464
249
    }
1465
1466
    /* should only process first %%BoundingBox: */
1467
1468
7.08k
    while (IS_WHITE(dsc->line[offset]))
1469
1.54k
  offset++;
1470
5.53k
    p = dsc->line + offset;
1471
    
1472
5.53k
    if (COMPARE(p, "atend")) {
1473
125
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, 
1474
125
    dsc->line_length);
1475
125
  switch (rc) {
1476
0
      case CDSC_RESPONSE_OK:
1477
    /* assume (atend) */
1478
    /* we should mark it as deferred */
1479
0
    break;
1480
125
      case CDSC_RESPONSE_CANCEL:
1481
    /* ignore it */
1482
125
    break;
1483
0
      case CDSC_RESPONSE_IGNORE_ALL:
1484
0
    return CDSC_NOTDSC;
1485
125
  }
1486
125
    }
1487
5.40k
    else if (COMPARE(p, "(atend)")) {
1488
  /* do nothing */
1489
  /* we should mark it as deferred */
1490
249
    }
1491
5.15k
    else {
1492
5.15k
  /* fllx = */ flly = furx = fury = 0.0;
1493
5.15k
  n = offset;
1494
5.15k
  fllx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1495
5.15k
  n += i;
1496
5.15k
  if (i)
1497
2.40k
      flly = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1498
5.15k
  n += i;
1499
5.15k
  if (i)
1500
1.51k
      furx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1501
5.15k
  n += i;
1502
5.15k
  if (i)
1503
1.15k
      fury = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1504
5.15k
  if (i) {
1505
496
      *pbbox = (CDSCFBBOX *)dsc_memalloc(dsc, sizeof(CDSCFBBOX));
1506
496
      if (*pbbox == NULL)
1507
0
    return CDSC_ERROR; /* no memory */
1508
496
      (*pbbox)->fllx = fllx;
1509
496
      (*pbbox)->flly = flly;
1510
496
      (*pbbox)->furx = furx;
1511
496
      (*pbbox)->fury = fury;
1512
496
  }
1513
5.15k
    }
1514
5.53k
    return CDSC_OK;
1515
5.53k
}
1516
1517
dsc_private int 
1518
dsc_parse_orientation(CDSC *dsc, unsigned int *porientation, int offset)
1519
4.52k
{
1520
4.52k
    char *p;
1521
4.52k
    if ((dsc->page_orientation != CDSC_ORIENT_UNKNOWN) && 
1522
632
  (dsc->scan_section == scan_comments)) {
1523
79
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1524
79
    dsc->line_length);
1525
79
  switch (rc) {
1526
0
      case CDSC_RESPONSE_OK:
1527
79
      case CDSC_RESPONSE_CANCEL:
1528
79
    return CDSC_OK; /* ignore duplicate comments in header */
1529
0
      case CDSC_RESPONSE_IGNORE_ALL:
1530
0
    return CDSC_NOTDSC;
1531
79
  }
1532
79
    }
1533
4.44k
    if ((dsc->page_orientation != CDSC_ORIENT_UNKNOWN) && 
1534
553
  (dsc->scan_section == scan_trailer)) {
1535
278
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1536
278
    dsc->line_length);
1537
278
  switch (rc) {
1538
0
      case CDSC_RESPONSE_OK:
1539
278
      case CDSC_RESPONSE_CANCEL:
1540
278
    break;   /* use duplicate comments in header; */
1541
0
      case CDSC_RESPONSE_IGNORE_ALL:
1542
0
    return CDSC_NOTDSC;
1543
278
  }
1544
278
    }
1545
4.44k
    p = dsc->line + offset;
1546
5.64k
    while (IS_WHITE(*p))
1547
1.19k
  p++;
1548
4.44k
    if (COMPARE(p, "atend")) {
1549
547
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, dsc->line_length);
1550
547
  switch (rc) {
1551
0
      case CDSC_RESPONSE_OK:
1552
    /* assume (atend) */
1553
    /* we should mark it as deferred */
1554
0
    break;
1555
547
      case CDSC_RESPONSE_CANCEL:
1556
    /* ignore it */
1557
547
    break;
1558
0
      case CDSC_RESPONSE_IGNORE_ALL:
1559
0
    return CDSC_NOTDSC;
1560
547
  }
1561
547
    }
1562
3.89k
    else if (COMPARE(p, "(atend)")) {
1563
  /* do nothing */
1564
  /* we should mark it as deferred */
1565
409
    }
1566
3.48k
    else if (COMPARE(p, "Portrait")) {
1567
184
  *porientation = CDSC_PORTRAIT;
1568
184
    }
1569
3.30k
    else if (COMPARE(p, "Landscape")) {
1570
734
  *porientation = CDSC_LANDSCAPE;
1571
734
    }
1572
2.57k
    else {
1573
2.57k
  dsc_unknown(dsc);
1574
2.57k
    }
1575
4.44k
    return CDSC_OK;
1576
4.44k
}
1577
1578
dsc_private int 
1579
dsc_parse_order(CDSC *dsc)
1580
3.11k
{
1581
3.11k
    char *p;
1582
3.11k
    if ((dsc->page_order != CDSC_ORDER_UNKNOWN) && 
1583
1.24k
  (dsc->scan_section == scan_comments)) {
1584
244
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1585
244
    dsc->line_length);
1586
244
  switch (rc) {
1587
0
      case CDSC_RESPONSE_OK:
1588
244
      case CDSC_RESPONSE_CANCEL:
1589
244
    return CDSC_OK; /* ignore duplicate comments in header */
1590
0
      case CDSC_RESPONSE_IGNORE_ALL:
1591
0
    return CDSC_NOTDSC;
1592
244
  }
1593
244
    }
1594
2.86k
    if ((dsc->page_order != CDSC_ORDER_UNKNOWN) && 
1595
1.00k
  (dsc->scan_section == scan_trailer)) {
1596
1.00k
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1597
1.00k
    dsc->line_length);
1598
1.00k
  switch (rc) {
1599
0
      case CDSC_RESPONSE_OK:
1600
1.00k
      case CDSC_RESPONSE_CANCEL:
1601
1.00k
    break;   /* use duplicate comments in trailer */
1602
0
      case CDSC_RESPONSE_IGNORE_ALL:
1603
0
    return CDSC_NOTDSC;
1604
1.00k
  }
1605
1.00k
    }
1606
1607
2.86k
    p = dsc->line + (IS_DSC(dsc->line, "%%+") ? 3 : 13);
1608
4.63k
    while (IS_WHITE(*p))
1609
1.76k
  p++;
1610
2.86k
    if (COMPARE(p, "atend")) {
1611
517
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, 
1612
517
    dsc->line_length);
1613
517
  switch (rc) {
1614
0
      case CDSC_RESPONSE_OK:
1615
    /* assume (atend) */
1616
    /* we should mark it as deferred */
1617
0
    break;
1618
517
      case CDSC_RESPONSE_CANCEL:
1619
    /* ignore it */
1620
517
    break;
1621
0
      case CDSC_RESPONSE_IGNORE_ALL:
1622
0
    return CDSC_NOTDSC;
1623
517
  }
1624
517
    }
1625
2.35k
    else if (COMPARE(p, "(atend)")) {
1626
  /* do nothing */
1627
  /* we should mark it as deferred */
1628
133
    }
1629
2.21k
    else if (COMPARE(p, "Ascend")) {
1630
94
  dsc->page_order = CDSC_ASCEND;
1631
94
    }
1632
2.12k
    else if (COMPARE(p, "Descend")) {
1633
462
  dsc->page_order = CDSC_DESCEND;
1634
462
    }
1635
1.66k
    else if (COMPARE(p, "Special")) {
1636
300
  dsc->page_order = CDSC_SPECIAL;
1637
300
    }
1638
1.36k
    else {
1639
1.36k
  dsc_unknown(dsc);
1640
1.36k
    }
1641
2.86k
    return CDSC_OK;
1642
2.86k
}
1643
1644
1645
dsc_private int 
1646
dsc_parse_media(CDSC *dsc, const CDSCMEDIA **page_media)
1647
1.23k
{
1648
1.23k
    char media_name[MAXSTR];
1649
1.23k
    int n = IS_DSC(dsc->line, "%%+") ? 3 : 12; /* %%PageMedia: */
1650
1.23k
    unsigned int i;
1651
1652
1.23k
    if (dsc_copy_string(media_name, sizeof(media_name)-1,
1653
1.23k
  dsc->line+n, dsc->line_length-n, NULL)) {
1654
4.84k
  for (i=0; i<dsc->media_count; i++) {
1655
3.69k
      if (dsc->media[i]->name && 
1656
1.54k
    (dsc_stricmp(media_name, dsc->media[i]->name) == 0)) {
1657
90
    *page_media = dsc->media[i];
1658
90
    return CDSC_OK;
1659
90
      }
1660
3.69k
  }
1661
1.23k
    }
1662
1.14k
    dsc_unknown(dsc);
1663
    
1664
1.14k
    return CDSC_OK;
1665
1.23k
}
1666
1667
1668
dsc_private int 
1669
dsc_parse_document_media(CDSC *dsc)
1670
3.12k
{
1671
3.12k
    unsigned int i, n;
1672
3.12k
    CDSCMEDIA lmedia;
1673
3.12k
    GSBOOL blank_line;
1674
1675
3.12k
    if (IS_DSC(dsc->line, "%%DocumentMedia:"))
1676
2.01k
  n = 16;
1677
1.10k
    else if (IS_DSC(dsc->line, "%%+"))
1678
1.10k
  n = 3;
1679
0
    else
1680
0
  return CDSC_ERROR; /* error */
1681
1682
    /* check for blank remainder of line */
1683
3.12k
    blank_line = TRUE;
1684
4.38k
    for (i=n; i<dsc->line_length; i++) {
1685
3.87k
  if (!IS_WHITE_OR_EOL(dsc->line[i])) {
1686
2.61k
      blank_line = FALSE;
1687
2.61k
      break;
1688
2.61k
  }
1689
3.87k
    }
1690
1691
3.12k
    if (!blank_line) {
1692
2.61k
  char name[MAXSTR];
1693
2.61k
  char colour[MAXSTR];
1694
2.61k
  char type[MAXSTR];
1695
2.61k
  lmedia.name = lmedia.colour = lmedia.type = (char *)NULL;
1696
2.61k
  lmedia.width = lmedia.height = lmedia.weight = 0;
1697
2.61k
  lmedia.mediabox = (CDSCBBOX *)NULL;
1698
2.61k
  lmedia.name = dsc_copy_string(name, sizeof(name)-1,
1699
2.61k
    dsc->line+n, dsc->line_length-n, &i);
1700
2.61k
  n+=i;
1701
2.61k
  if (i)
1702
2.61k
      lmedia.width = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1703
2.61k
  n+=i;
1704
2.61k
  if (i)
1705
1.05k
      lmedia.height = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1706
2.61k
  n+=i;
1707
2.61k
  if (i)
1708
508
      lmedia.weight = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1709
2.61k
  n+=i;
1710
2.61k
  if (i)
1711
303
      lmedia.colour = dsc_copy_string(colour, sizeof(colour)-1,
1712
303
    dsc->line+n, dsc->line_length-n, &i);
1713
2.61k
  n+=i;
1714
2.61k
  if (i)
1715
303
      lmedia.type = dsc_copy_string(type, sizeof(type)-1,
1716
303
    dsc->line+n, dsc->line_length-n, &i);
1717
1718
2.61k
  if (i==0)
1719
2.43k
      dsc_unknown(dsc); /* we didn't get all fields */
1720
177
  else {
1721
177
      if (dsc_add_media(dsc, &lmedia))
1722
0
    return CDSC_ERROR; /* out of memory */
1723
177
  }
1724
2.61k
    }
1725
3.12k
    return CDSC_OK;
1726
3.12k
}
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
2.45k
{
1734
2.45k
    CDSCCTM ctm;
1735
2.45k
    unsigned int i, n;
1736
1737
2.45k
    if (*pctm != NULL) {
1738
481
  dsc_memfree(dsc, *pctm);
1739
481
  *pctm = NULL;
1740
481
    }
1741
1742
2.45k
    n = IS_DSC(dsc->line, "%%+") ? 3 : 21;  /* %%ViewingOrientation: */
1743
12.4k
    while (IS_WHITE(dsc->line[n]))
1744
9.98k
  n++;
1745
1746
    /* ctm.xx = */ ctm.xy = ctm.yx = ctm.yy = 0.0;
1747
2.45k
    ctm.xx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1748
2.45k
    n += i;
1749
2.45k
    if (i)
1750
2.06k
        ctm.xy = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1751
2.45k
    n += i;
1752
2.45k
    if (i)
1753
1.82k
        ctm.yx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1754
2.45k
    n += i;
1755
2.45k
    if (i)
1756
1.25k
        ctm.yy = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1757
2.45k
    if (i==0) {
1758
1.58k
  dsc_unknown(dsc); /* we didn't get all fields */
1759
1.58k
    }
1760
864
    else {
1761
864
  *pctm = (CDSCCTM *)dsc_memalloc(dsc, sizeof(CDSCCTM));
1762
864
  if (*pctm == NULL)
1763
0
      return CDSC_ERROR; /* no memory */
1764
864
  **pctm = ctm;
1765
864
    }
1766
2.45k
    return CDSC_OK;
1767
2.45k
}
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
54.0k
{
1777
54.0k
    if (dsc->data_index > dsc->data_length)
1778
0
  return CDSC_NOTDSC;
1779
1780
54.0k
    unsigned char *p;
1781
54.0k
    unsigned char *line = (unsigned char *)(dsc->data + dsc->data_index);
1782
54.0k
    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
54.0k
    if (length == 0)
1798
0
  return CDSC_NEEDMORE;
1799
1800
54.0k
    if (dsc->skip_pjl) {
1801
  /* skip until first PostScript comment */
1802
4.66k
  while (length >= 2) {
1803
15.0k
      while (length && !IS_EOL(line[0])) {
1804
    /* skip until EOL character */
1805
10.3k
    line++;
1806
10.3k
    dsc->data_index++;
1807
10.3k
    length--;
1808
10.3k
      }
1809
15.1k
      while ((length >= 2) && IS_EOL(line[0]) && IS_EOL(line[1])) {
1810
    /* skip until EOL followed by non-EOL */
1811
10.4k
    line++;
1812
10.4k
    dsc->data_index++;
1813
10.4k
    length--;
1814
10.4k
      }
1815
4.62k
      if (length < 2)
1816
2.59k
    return CDSC_NEEDMORE;
1817
1818
2.03k
      if (IS_EOL(line[0]) && line[1]=='%') {
1819
61
    line++;
1820
61
    dsc->data_index++;
1821
61
    length--;
1822
61
    dsc->skip_pjl = FALSE;
1823
61
    break;
1824
61
      }
1825
1.97k
      else {
1826
    /* line++; */
1827
1.97k
    dsc->data_index++;
1828
    /* length--; */
1829
1.97k
    return CDSC_NEEDMORE;
1830
1.97k
      }
1831
2.03k
  }
1832
98
  if (dsc->skip_pjl)
1833
37
      return CDSC_NEEDMORE;
1834
98
    }
1835
1836
49.4k
    if (length == 0)
1837
0
  return CDSC_NEEDMORE;
1838
1839
49.4k
    if (line[0] == '\004') {
1840
242
  line++;
1841
242
  dsc->data_index++;
1842
242
  length--;
1843
242
  dsc->ctrld = TRUE;
1844
242
    }
1845
1846
49.4k
    if (line[0] == '\033') {
1847
  /* possibly PJL */
1848
1.41k
  if (length < 9)
1849
914
      return CDSC_NEEDMORE;
1850
500
  if (COMPARE(line, "\033%-12345X")) {
1851
200
      dsc->skip_pjl = TRUE;  /* skip until first PostScript comment */
1852
200
      dsc->pjl = TRUE;
1853
200
      dsc->data_index += 9;
1854
200
      return dsc_scan_type(dsc);
1855
200
  }
1856
500
    }
1857
1858
48.3k
    if ((line[0]==0xc5) && (length < 4))
1859
1.22k
  return CDSC_NEEDMORE;
1860
47.1k
    if ((line[0]==0xc5) && (line[1]==0xd0) && 
1861
8.44k
   (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
7.57k
  if (length < 30)
1865
6.17k
      return CDSC_NEEDMORE;
1866
1.40k
  dsc->line = (char *)line;
1867
1.40k
  if (dsc_read_doseps(dsc))
1868
0
      return CDSC_ERROR;
1869
1.40k
    }
1870
39.5k
    else {
1871
39.5k
  if (length < 2)
1872
9.53k
      return CDSC_NEEDMORE;
1873
30.0k
  if ((line[0] == '%') && (line[1] == 'P')) {
1874
5.19k
      if (length < 5)
1875
145
          return CDSC_NEEDMORE;
1876
5.04k
      if (COMPARE(line, "%PDF-")) {
1877
4.69k
    dsc->pdf = TRUE;
1878
4.69k
    dsc->scan_section = scan_comments;
1879
4.69k
    return CDSC_OK;
1880
4.69k
      }
1881
5.04k
  }
1882
30.0k
    }
1883
1884
    /* Finally process PostScript headers */
1885
1886
26.6k
    if (dsc_read_line(dsc) <= 0)
1887
16.3k
  return CDSC_NEEDMORE;
1888
  
1889
10.2k
    dsc->dsc_version = dsc_add_line(dsc, dsc->line, dsc->line_length);
1890
10.2k
    if (COMPARE(dsc->line, "%!PS-Adobe")) {
1891
9.67k
  dsc->dsc = TRUE;
1892
9.67k
  dsc->begincomments = DSC_START(dsc);
1893
9.67k
  if (dsc->dsc_version == NULL)
1894
12
      return CDSC_ERROR;  /* no memory */
1895
9.65k
  p = (unsigned char *)dsc->line + 14;
1896
10.7k
  while (IS_WHITE(*p))
1897
1.06k
      p++;
1898
9.65k
  if (COMPARE(p, "EPSF-"))
1899
6
      dsc->epsf = TRUE;
1900
9.65k
  dsc->scan_section = scan_comments;
1901
9.65k
  return CDSC_PSADOBE;
1902
9.67k
    }
1903
580
    if (COMPARE(dsc->line, "%!")) {
1904
162
  dsc->scan_section = scan_comments;
1905
162
  return CDSC_NOTDSC;
1906
162
    }
1907
1908
418
    dsc->scan_section = scan_comments;
1909
418
    return CDSC_NOTDSC; /* unrecognised */
1910
580
}
1911
1912
1913
1914
dsc_private int 
1915
dsc_scan_comments(CDSC *dsc)
1916
65.1k
{
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
65.1k
    char *line = dsc->line;
1924
65.1k
    GSBOOL continued = FALSE;
1925
65.1k
    dsc->id = CDSC_OK;
1926
65.1k
    if (IS_DSC(line, "%%EndComments")) {
1927
17
  dsc->id = CDSC_ENDCOMMENTS;
1928
17
  dsc->endcomments = DSC_END(dsc);
1929
17
  dsc->scan_section = scan_pre_preview;
1930
17
  return CDSC_OK;
1931
17
    }
1932
65.0k
    else if (IS_DSC(line, "%%BeginComments")) {
1933
  /* ignore because we are in this section */
1934
359
  dsc->id = CDSC_BEGINCOMMENTS;
1935
359
    }
1936
64.7k
    else if (dsc_is_section(line)) {
1937
4.79k
  dsc->endcomments = DSC_START(dsc);
1938
4.79k
  dsc->scan_section = scan_pre_preview;
1939
4.79k
  return CDSC_PROPAGATE;
1940
4.79k
    }
1941
59.9k
    else if (line[0] == '%' && IS_WHITE_OR_EOL(line[1])) {
1942
294
  dsc->endcomments = DSC_START(dsc);
1943
294
  dsc->scan_section = scan_pre_preview;
1944
294
  return CDSC_PROPAGATE;
1945
294
    }
1946
59.6k
    else if (line[0] != '%') {
1947
4.13k
  dsc->id = CDSC_OK;
1948
4.13k
  dsc->endcomments = DSC_START(dsc);
1949
4.13k
  dsc->scan_section = scan_pre_preview;
1950
4.13k
  return CDSC_PROPAGATE;
1951
4.13k
    }
1952
55.5k
    else if (IS_DSC(line, "%%Begin")) {
1953
988
  dsc->endcomments = DSC_START(dsc);
1954
988
  dsc->scan_section = scan_pre_preview;
1955
988
  return CDSC_PROPAGATE;
1956
988
    }
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
54.8k
    if (IS_DSC(line, "%%+")) {
1967
16.3k
  line = dsc->last_line;
1968
16.3k
  continued = TRUE;
1969
16.3k
    }
1970
38.5k
    else
1971
38.5k
  dsc_save_line(dsc);
1972
1973
54.8k
    if (IS_DSC(line, "%%Pages:")) {
1974
2.66k
  dsc->id = CDSC_PAGES;
1975
2.66k
  if (dsc_parse_pages(dsc) != 0)
1976
0
      return CDSC_ERROR;
1977
2.66k
    }
1978
52.2k
    else if (IS_DSC(line, "%%Creator:")) {
1979
891
  dsc->id = CDSC_CREATOR;
1980
891
  dsc->dsc_creator = dsc_add_line(dsc, dsc->line+10, dsc->line_length-10);
1981
891
  if (dsc->dsc_creator==NULL)
1982
113
      return CDSC_ERROR;
1983
891
    }
1984
51.3k
    else if (IS_DSC(line, "%%CreationDate:")) {
1985
1.26k
  dsc->id = CDSC_CREATIONDATE;
1986
1.26k
  dsc->dsc_date = dsc_add_line(dsc, dsc->line+15, dsc->line_length-15);
1987
1.26k
  if (dsc->dsc_date==NULL)
1988
214
      return CDSC_ERROR;
1989
1.26k
    }
1990
50.0k
    else if (IS_DSC(line, "%%Title:")) {
1991
1.71k
  dsc->id = CDSC_TITLE;
1992
1.71k
  dsc->dsc_title = dsc_add_line(dsc, dsc->line+8, dsc->line_length-8);
1993
1.71k
  if (dsc->dsc_title==NULL)
1994
303
      return CDSC_ERROR;
1995
1.71k
    }
1996
48.3k
    else if (IS_DSC(line, "%%For:")) {
1997
3.10k
  dsc->id = CDSC_FOR;
1998
3.10k
  dsc->dsc_for = dsc_add_line(dsc, dsc->line+6, dsc->line_length-6);
1999
3.10k
  if (dsc->dsc_for==NULL)
2000
526
      return CDSC_ERROR;
2001
3.10k
    }
2002
45.2k
    else if (IS_DSC(line, "%%LanguageLevel:")) {
2003
1.62k
  unsigned int n = continued ? 3 : 16;
2004
1.62k
  unsigned int i;
2005
1.62k
  int ll;
2006
1.62k
  dsc->id = CDSC_LANGUAGELEVEL;
2007
1.62k
  ll = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
2008
1.62k
  if (i) {
2009
737
      if ( (ll==1) || (ll==2) || (ll==3) )
2010
205
    dsc->language_level = ll;
2011
532
      else {
2012
532
    dsc_unknown(dsc);
2013
532
      }
2014
737
  }
2015
883
  else 
2016
883
      dsc_unknown(dsc);
2017
1.62k
    }
2018
43.6k
    else if (IS_DSC(line, "%%BoundingBox:")) {
2019
4.27k
  dsc->id = CDSC_BOUNDINGBOX;
2020
4.27k
  if (dsc_parse_bounding_box(dsc, &(dsc->bbox), continued ? 3 : 14))
2021
0
      return CDSC_ERROR;
2022
4.27k
    }
2023
39.3k
    else if (IS_DSC(line, "%%HiResBoundingBox:")) {
2024
256
  dsc->id = CDSC_HIRESBOUNDINGBOX;
2025
256
  if (dsc_parse_float_bounding_box(dsc, &(dsc->hires_bbox), 
2026
256
      continued ? 3 : 19))
2027
0
      return CDSC_ERROR;
2028
256
    }
2029
39.0k
    else if (IS_DSC(line, "%%CropBox:")) {
2030
2.72k
  dsc->id = CDSC_CROPBOX;
2031
2.72k
  if (dsc_parse_float_bounding_box(dsc, &(dsc->crop_box), 
2032
2.72k
      continued ? 3 : 10))
2033
0
      return CDSC_ERROR;
2034
2.72k
    }
2035
36.3k
    else if (IS_DSC(line, "%%Orientation:")) {
2036
1.78k
  dsc->id = CDSC_ORIENTATION;
2037
1.78k
  if (dsc_parse_orientation(dsc, &(dsc->page_orientation), 
2038
1.78k
    continued ? 3 : 14))
2039
0
      return CDSC_ERROR;
2040
1.78k
    }
2041
34.5k
    else if (IS_DSC(line, "%%PageOrder:")) {
2042
1.57k
  dsc->id = CDSC_PAGEORDER;
2043
1.57k
  if (dsc_parse_order(dsc))
2044
0
      return CDSC_ERROR;
2045
1.57k
    }
2046
32.9k
    else if (IS_DSC(line, "%%DocumentMedia:")) {
2047
2.32k
  dsc->id = CDSC_DOCUMENTMEDIA;
2048
2.32k
  if (dsc_parse_document_media(dsc))
2049
0
      return CDSC_ERROR;
2050
2.32k
    }
2051
30.6k
    else if (IS_DSC(line, "%%DocumentPaperSizes:")) {
2052
  /* DSC 2.1 */
2053
954
  unsigned int n = continued ? 3 : 21;
2054
954
  unsigned int count = 0;
2055
954
  unsigned int i = 1;
2056
954
  char name[MAXSTR];
2057
954
  char *p;
2058
954
  dsc->id = CDSC_DOCUMENTPAPERSIZES;
2059
4.62k
  while (i && n < dsc->line_length && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
2060
3.66k
      p = dsc_copy_string(name, sizeof(name)-1,
2061
3.66k
        dsc->line+n, dsc->line_length-n, &i);
2062
3.66k
      if (i && p) {
2063
3.66k
    const CDSCMEDIA *m = dsc_known_media;
2064
3.66k
    if (count >= dsc->media_count) {
2065
        /* set some default values */
2066
1.54k
        CDSCMEDIA lmedia;
2067
1.54k
        lmedia.name = p;
2068
1.54k
        lmedia.width = 595.0;
2069
1.54k
        lmedia.height = 842.0;
2070
1.54k
        lmedia.weight = 80.0;
2071
1.54k
        lmedia.colour = NULL;
2072
1.54k
        lmedia.type = NULL;
2073
1.54k
        lmedia.mediabox = NULL;
2074
1.54k
        if (dsc_add_media(dsc, &lmedia))
2075
0
      return CDSC_ERROR;
2076
1.54k
    }
2077
2.11k
    else
2078
2.11k
        dsc->media[count]->name = 
2079
2.11k
      dsc_alloc_string(dsc, p, strlen(p));
2080
    /* find in list of known media */
2081
168k
    while (m && m->name) {
2082
164k
        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
164k
        m++;
2088
164k
    }
2089
3.66k
      }
2090
3.66k
      n+=i;
2091
3.66k
      count++;
2092
3.66k
  }
2093
954
    }
2094
29.7k
    else if (IS_DSC(line, "%%DocumentPaperForms:")) {
2095
  /* DSC 2.1 */
2096
1.03k
  unsigned int n = continued ? 3 : 21;
2097
1.03k
  unsigned int count = 0;
2098
1.03k
  unsigned int i = 1;
2099
1.03k
  char type[MAXSTR];
2100
1.03k
  char *p;
2101
1.03k
  dsc->id = CDSC_DOCUMENTPAPERFORMS;
2102
2.89k
  while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
2103
1.85k
      p = dsc_copy_string(type, sizeof(type)-1,
2104
1.85k
        dsc->line+n, dsc->line_length-n, &i);
2105
1.85k
      if (i && p) {
2106
1.54k
    if (count >= dsc->media_count) {
2107
        /* set some default values */
2108
452
        CDSCMEDIA lmedia;
2109
452
        lmedia.name = NULL;
2110
452
        lmedia.width = 595.0;
2111
452
        lmedia.height = 842.0;
2112
452
        lmedia.weight = 80.0;
2113
452
        lmedia.colour = NULL;
2114
452
        lmedia.type = p;
2115
452
        lmedia.mediabox = NULL;
2116
452
        if (dsc_add_media(dsc, &lmedia))
2117
0
      return CDSC_ERROR;
2118
452
    }
2119
1.09k
    else
2120
1.09k
        dsc->media[count]->type = 
2121
1.09k
      dsc_alloc_string(dsc, p, strlen(p));
2122
1.54k
      }
2123
1.85k
      n+=i;
2124
1.85k
      count++;
2125
1.85k
  }
2126
1.03k
    }
2127
28.6k
    else if (IS_DSC(line, "%%DocumentPaperColors:")) {
2128
  /* DSC 2.1 */
2129
442
  unsigned int n = continued ? 3 : 22;
2130
442
  unsigned int count = 0;
2131
442
  unsigned int i = 1;
2132
442
  char colour[MAXSTR];
2133
442
  char *p;
2134
442
  dsc->id = CDSC_DOCUMENTPAPERCOLORS;
2135
2.62k
  while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
2136
2.19k
      if (n > dsc->line_length) {
2137
10
    break;
2138
10
      }
2139
2.18k
      p = dsc_copy_string(colour, sizeof(colour)-1, 
2140
2.18k
        dsc->line+n, dsc->line_length-n, &i);
2141
2.18k
      if (i && p) {
2142
1.91k
    if (count >= dsc->media_count) {
2143
        /* set some default values */
2144
1.44k
        CDSCMEDIA lmedia;
2145
1.44k
        lmedia.name = NULL;
2146
1.44k
        lmedia.width = 595.0;
2147
1.44k
        lmedia.height = 842.0;
2148
1.44k
        lmedia.weight = 80.0;
2149
1.44k
        lmedia.colour = p;
2150
1.44k
        lmedia.type = NULL;
2151
1.44k
        lmedia.mediabox = NULL;
2152
1.44k
        if (dsc_add_media(dsc, &lmedia))
2153
0
      return CDSC_ERROR;
2154
1.44k
    }
2155
468
    else
2156
468
        dsc->media[count]->colour = 
2157
468
      dsc_alloc_string(dsc, p, strlen(p));
2158
1.91k
      }
2159
2.18k
      n+=i;
2160
2.18k
      count++;
2161
2.18k
  }
2162
442
    }
2163
28.2k
    else if (IS_DSC(line, "%%DocumentPaperWeights:")) {
2164
  /* DSC 2.1 */
2165
1.11k
  unsigned int n = continued ? 3 : 23;
2166
1.11k
  unsigned int count = 0;
2167
1.11k
  unsigned int i = 1;
2168
1.11k
  float w;
2169
1.11k
  dsc->id = CDSC_DOCUMENTPAPERWEIGHTS;
2170
3.44k
  while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
2171
2.33k
      w = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
2172
2.33k
      if (i) {
2173
1.28k
    if (count >= dsc->media_count) {
2174
        /* set some default values */
2175
590
        CDSCMEDIA lmedia;
2176
590
        lmedia.name = NULL;
2177
590
        lmedia.width = 595.0;
2178
590
        lmedia.height = 842.0;
2179
590
        lmedia.weight = w;
2180
590
        lmedia.colour = NULL;
2181
590
        lmedia.type = NULL;
2182
590
        lmedia.mediabox = NULL;
2183
590
        if (dsc_add_media(dsc, &lmedia))
2184
0
      return CDSC_ERROR;
2185
590
    }
2186
699
    else
2187
699
        dsc->media[count]->weight = w;
2188
1.28k
      }
2189
2.33k
      n+=i;
2190
2.33k
      count++;
2191
2.33k
  }
2192
1.11k
    }
2193
27.1k
    else if (IS_DSC(line, "%%DocumentData:")) {
2194
1.40k
  unsigned int n = continued ? 3 : 15;
2195
1.40k
  char *p = dsc->line + n;
2196
2.02k
        while (IS_WHITE(*p))
2197
620
      p++;
2198
1.40k
  dsc->id = CDSC_DOCUMENTDATA;
2199
1.40k
  if (COMPARE(p, "Clean7Bit"))
2200
647
      dsc->document_data = CDSC_CLEAN7BIT;
2201
761
  else if (COMPARE(p, "Clean8Bit"))
2202
67
      dsc->document_data = CDSC_CLEAN8BIT;
2203
694
  else if (COMPARE(p, "Binary"))
2204
222
      dsc->document_data = CDSC_BINARY;
2205
472
  else
2206
472
      dsc_unknown(dsc);
2207
1.40k
    }
2208
25.7k
    else if (IS_DSC(line, "%%Requirements:")) {
2209
675
  dsc->id = CDSC_REQUIREMENTS;
2210
  /* ignore */
2211
675
    }
2212
25.0k
    else if (IS_DSC(line, "%%DocumentNeededFonts:")) {
2213
74
  dsc->id = CDSC_DOCUMENTNEEDEDFONTS;
2214
  /* ignore */
2215
74
    }
2216
24.9k
    else if (IS_DSC(line, "%%DocumentSuppliedFonts:")) {
2217
125
  dsc->id = CDSC_DOCUMENTSUPPLIEDFONTS;
2218
  /* ignore */
2219
125
    }
2220
24.8k
    else if (dsc->line[0] == '%' && IS_WHITE_OR_EOL(dsc->line[1])) {
2221
0
  dsc->id = CDSC_OK;
2222
  /* ignore */
2223
0
    }
2224
24.8k
    else {
2225
24.8k
  dsc->id = CDSC_UNKNOWNDSC;
2226
24.8k
  dsc_unknown(dsc);
2227
24.8k
    }
2228
2229
53.7k
    dsc->endcomments = DSC_END(dsc);
2230
53.7k
    return CDSC_OK;
2231
54.8k
}
2232
2233
2234
dsc_private int 
2235
dsc_scan_preview(CDSC *dsc)
2236
39.6k
{
2237
    /* Preview section ends at */
2238
    /*  %%EndPreview */
2239
    /*  another section */
2240
    /* Preview section must start with %%BeginPreview */
2241
39.6k
    char *line = dsc->line;
2242
39.6k
    dsc->id = CDSC_OK;
2243
2244
39.6k
    if (dsc->scan_section == scan_pre_preview) {
2245
16.1k
  if (IS_BLANK(line))
2246
6.21k
      return CDSC_OK;  /* ignore blank lines before preview */
2247
9.95k
  else if (IS_DSC(line, "%%BeginPreview")) {
2248
803
      dsc->id = CDSC_BEGINPREVIEW;
2249
803
      dsc->beginpreview = DSC_START(dsc);
2250
803
      dsc->endpreview = DSC_END(dsc);
2251
803
      dsc->scan_section = scan_preview;
2252
      /* Don't mark the preview as EPSI if a DOS EPS header is present */
2253
803
      if (dsc->preview == CDSC_NOPREVIEW)
2254
803
    dsc->preview = CDSC_EPSI;
2255
803
      return CDSC_OK;
2256
803
  }
2257
9.14k
  else {
2258
9.14k
      dsc->scan_section = scan_pre_defaults;
2259
9.14k
      return CDSC_PROPAGATE;
2260
9.14k
  }
2261
16.1k
    }
2262
2263
23.4k
    if (IS_DSC(line, "%%BeginPreview")) {
2264
  /* ignore because we are in this section */
2265
448
    }
2266
23.0k
    else if (dsc_is_section(line)) {
2267
560
  dsc->endpreview = DSC_START(dsc);
2268
560
  dsc->scan_section = scan_pre_defaults;
2269
560
  return CDSC_PROPAGATE;
2270
560
    }
2271
22.4k
    else if (IS_DSC(line, "%%EndPreview")) {
2272
63
  dsc->id = CDSC_ENDPREVIEW;
2273
63
  dsc->endpreview = DSC_END(dsc);
2274
63
  dsc->scan_section = scan_pre_defaults;
2275
63
  return CDSC_OK;
2276
63
    }
2277
22.3k
    else if (line[0] == '%' && line[1] != '%') {
2278
  /* Ordinary comments are OK */
2279
1.53k
    }
2280
20.8k
    else {
2281
20.8k
  dsc->id = CDSC_UNKNOWNDSC;
2282
  /* DSC comments should not occur in preview */
2283
20.8k
  dsc_unknown(dsc);
2284
20.8k
    }
2285
2286
22.8k
    dsc->endpreview = DSC_END(dsc);
2287
22.8k
    return CDSC_OK;
2288
23.4k
}
2289
2290
dsc_private int
2291
dsc_scan_defaults(CDSC *dsc)
2292
26.9k
{
2293
    /* Defaults section ends at */
2294
    /*  %%EndDefaults */
2295
    /*  another section */
2296
    /* Defaults section must start with %%BeginDefaults */
2297
26.9k
    char *line = dsc->line;
2298
26.9k
    dsc->id = CDSC_OK;
2299
2300
26.9k
    if (dsc->scan_section == scan_pre_defaults) {
2301
9.96k
  if (IS_BLANK(line))
2302
216
      return CDSC_OK;  /* ignore blank lines before defaults */
2303
9.74k
  else if (IS_DSC(line, "%%BeginDefaults")) {
2304
1.05k
      dsc->id = CDSC_BEGINDEFAULTS;
2305
1.05k
      dsc->begindefaults = DSC_START(dsc);
2306
1.05k
      dsc->enddefaults = DSC_END(dsc);
2307
1.05k
      dsc->scan_section = scan_defaults;
2308
1.05k
      return CDSC_OK;
2309
1.05k
  }
2310
8.68k
  else {
2311
8.68k
      dsc->scan_section = scan_pre_prolog;
2312
8.68k
      return CDSC_PROPAGATE;
2313
8.68k
  }
2314
9.96k
    }
2315
2316
16.9k
    if (NOT_DSC_LINE(line)) {
2317
  /* ignore */
2318
8.89k
    }
2319
8.04k
    else if (IS_DSC(line, "%%BeginPreview")) {
2320
  /* ignore because we have already processed this section */
2321
329
    }
2322
7.71k
    else if (IS_DSC(line, "%%BeginDefaults")) {
2323
  /* ignore because we are in this section */
2324
564
    }
2325
7.15k
    else if (dsc_is_section(line)) {
2326
176
  dsc->enddefaults = DSC_START(dsc);
2327
176
  dsc->scan_section = scan_pre_prolog;
2328
176
  return CDSC_PROPAGATE;
2329
176
    }
2330
6.97k
    else if (IS_DSC(line, "%%EndDefaults")) {
2331
38
  dsc->id = CDSC_ENDDEFAULTS;
2332
38
  dsc->enddefaults = DSC_END(dsc);
2333
38
  dsc->scan_section = scan_pre_prolog;
2334
38
  return CDSC_OK;
2335
38
    }
2336
6.93k
    else if (IS_DSC(line, "%%PageMedia:")) {
2337
233
  dsc->id = CDSC_PAGEMEDIA;
2338
233
  dsc_parse_media(dsc, &dsc->page_media);
2339
233
    }
2340
6.70k
    else if (IS_DSC(line, "%%PageOrientation:")) {
2341
454
  dsc->id = CDSC_PAGEORIENTATION;
2342
  /* This can override %%Orientation:  */
2343
454
  if (dsc_parse_orientation(dsc, &(dsc->page_orientation), 18))
2344
0
      return CDSC_ERROR;
2345
454
    }
2346
6.25k
    else if (IS_DSC(line, "%%PageBoundingBox:")) {
2347
723
  dsc->id = CDSC_PAGEBOUNDINGBOX;
2348
723
  if (dsc_parse_bounding_box(dsc, &(dsc->page_bbox), 18))
2349
0
      return CDSC_ERROR;
2350
723
    }
2351
5.52k
    else if (IS_DSC(line, "%%ViewingOrientation:")) {
2352
470
  dsc->id = CDSC_VIEWINGORIENTATION;
2353
470
  if (dsc_parse_viewing_orientation(dsc, &dsc->viewing_orientation))
2354
0
      return CDSC_ERROR;
2355
470
    }
2356
5.05k
    else {
2357
5.05k
  dsc->id = CDSC_UNKNOWNDSC;
2358
  /* All other DSC comments are unknown, but not an error */
2359
5.05k
  dsc_unknown(dsc);
2360
5.05k
    }
2361
16.7k
    dsc->enddefaults = DSC_END(dsc);
2362
16.7k
    return CDSC_OK;
2363
16.9k
}
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
45.2k
{
2370
45.2k
    if (count != 0) {
2371
615
  char buf[MAXSTR+MAXSTR] = "";
2372
615
  if (dsc->line_length < (unsigned int)(sizeof(buf)/2-1))  {
2373
573
      strncpy(buf, dsc->line, dsc->line_length);
2374
573
      buf[dsc->line_length] = '\0';
2375
573
  }
2376
615
  sprintf(buf+strlen(buf), "\n%%%%Begin%.40s: / %%%%End%.40s\n", str, str);
2377
615
  return dsc_error(dsc, CDSC_MESSAGE_BEGIN_END, buf, strlen(buf));
2378
615
    }
2379
44.6k
    return CDSC_RESPONSE_CANCEL;
2380
45.2k
}
2381
2382
dsc_private int
2383
dsc_check_match_type(CDSC *dsc, const char *str, int count)
2384
45.2k
{
2385
45.2k
    if (dsc_check_match_prompt(dsc, str, count) == CDSC_RESPONSE_IGNORE_ALL)
2386
0
  return CDSC_NOTDSC;
2387
45.2k
    return CDSC_OK;
2388
45.2k
}
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
11.3k
{
2395
11.3k
    int rc = 0;
2396
11.3k
    const char *font = "Font";
2397
11.3k
    const char *feature = "Feature";
2398
11.3k
    const char *resource = "Resource";
2399
11.3k
    const char *procset = "ProcSet";
2400
2401
11.3k
    if (!rc)
2402
11.3k
  rc = dsc_check_match_type(dsc, font, dsc->begin_font_count);
2403
11.3k
    if (!rc)
2404
11.3k
  rc = dsc_check_match_type(dsc, feature, dsc->begin_feature_count);
2405
11.3k
    if (!rc)
2406
11.3k
  rc = dsc_check_match_type(dsc, resource, dsc->begin_resource_count);
2407
11.3k
    if (!rc)
2408
11.3k
  rc = dsc_check_match_type(dsc, procset, dsc->begin_procset_count);
2409
2410
11.3k
    dsc->begin_font_count = 0;
2411
11.3k
    dsc->begin_feature_count = 0;
2412
11.3k
    dsc->begin_resource_count = 0;
2413
11.3k
    dsc->begin_procset_count = 0;
2414
11.3k
    return rc;
2415
11.3k
}
2416
2417
2418
dsc_private int 
2419
dsc_scan_prolog(CDSC *dsc)
2420
61.9k
{
2421
    /* Prolog section ends at */
2422
    /*  %%EndProlog */
2423
    /*  another section */
2424
    /* Prolog section may start with %%BeginProlog or non-dsc line */
2425
61.9k
    char *line = dsc->line;
2426
61.9k
    dsc->id = CDSC_OK;
2427
2428
61.9k
    if (dsc->scan_section == scan_pre_prolog) {
2429
8.89k
        if (dsc_is_section(line) && (!IS_DSC(line, "%%BeginProlog"))) {
2430
3.88k
      dsc->scan_section = scan_pre_setup;
2431
3.88k
      return CDSC_PROPAGATE;
2432
3.88k
  }
2433
5.01k
  dsc->id = CDSC_BEGINPROLOG;
2434
5.01k
  dsc->beginprolog = DSC_START(dsc);
2435
5.01k
  dsc->endprolog = DSC_END(dsc);
2436
5.01k
  dsc->scan_section = scan_prolog;
2437
5.01k
  if (IS_DSC(line, "%%BeginProlog"))
2438
37
      return CDSC_OK;
2439
5.01k
    }
2440
   
2441
58.0k
    if (NOT_DSC_LINE(line)) {
2442
  /* ignore */
2443
40.0k
    }
2444
17.9k
    else if (IS_DSC(line, "%%BeginPreview")) {
2445
  /* ignore because we have already processed this section */
2446
339
    }
2447
17.6k
    else if (IS_DSC(line, "%%BeginDefaults")) {
2448
  /* ignore because we have already processed this section */
2449
339
    }
2450
17.2k
    else if (IS_DSC(line, "%%BeginProlog")) {
2451
  /* ignore because we are in this section */
2452
332
    }
2453
16.9k
    else if (dsc_is_section(line)) {
2454
2.79k
  dsc->endprolog = DSC_START(dsc);
2455
2.79k
  dsc->scan_section = scan_pre_setup;
2456
2.79k
  if (dsc_check_match(dsc))
2457
0
      return CDSC_NOTDSC;
2458
2.79k
  return CDSC_PROPAGATE;
2459
2.79k
    }
2460
14.1k
    else if (IS_DSC(line, "%%EndProlog")) {
2461
104
  dsc->id = CDSC_ENDPROLOG;
2462
104
  dsc->endprolog = DSC_END(dsc);
2463
104
  dsc->scan_section = scan_pre_setup;
2464
104
  if (dsc_check_match(dsc))
2465
0
      return CDSC_NOTDSC;
2466
104
  return CDSC_OK;
2467
104
    }
2468
14.0k
    else if (IS_DSC(line, "%%BeginFont:")) {
2469
1.03k
  dsc->id = CDSC_BEGINFONT;
2470
  /* ignore Begin/EndFont, apart form making sure */
2471
  /* that they are matched. */
2472
1.03k
  dsc->begin_font_count++;
2473
1.03k
    }
2474
13.0k
    else if (IS_DSC(line, "%%EndFont")) {
2475
260
  dsc->id = CDSC_ENDFONT;
2476
260
  dsc->begin_font_count--;
2477
260
    }
2478
12.7k
    else if (IS_DSC(line, "%%BeginFeature:")) {
2479
280
  dsc->id = CDSC_BEGINFEATURE;
2480
  /* ignore Begin/EndFeature, apart form making sure */
2481
  /* that they are matched. */
2482
280
  dsc->begin_feature_count++;
2483
280
    }
2484
12.4k
    else if (IS_DSC(line, "%%EndFeature")) {
2485
270
  dsc->id = CDSC_ENDFEATURE;
2486
270
  dsc->begin_feature_count--;
2487
270
    }
2488
12.2k
    else if (IS_DSC(line, "%%BeginResource:")) {
2489
418
  dsc->id = CDSC_BEGINRESOURCE;
2490
  /* ignore Begin/EndResource, apart form making sure */
2491
  /* that they are matched. */
2492
418
  dsc->begin_resource_count++;
2493
418
    }
2494
11.7k
    else if (IS_DSC(line, "%%EndResource")) {
2495
276
  dsc->id = CDSC_ENDRESOURCE;
2496
276
  dsc->begin_resource_count--;
2497
276
    }
2498
11.5k
    else if (IS_DSC(line, "%%BeginProcSet:")) {
2499
239
  dsc->id = CDSC_BEGINPROCSET;
2500
  /* ignore Begin/EndProcSet, apart form making sure */
2501
  /* that they are matched. */
2502
239
  dsc->begin_procset_count++;
2503
239
    }
2504
11.2k
    else if (IS_DSC(line, "%%EndProcSet")) {
2505
114
  dsc->id = CDSC_ENDPROCSET;
2506
114
  dsc->begin_procset_count--;
2507
114
    }
2508
11.1k
    else {
2509
  /* All other DSC comments are unknown, but not an error */
2510
11.1k
  dsc->id = CDSC_UNKNOWNDSC;
2511
11.1k
  dsc_unknown(dsc);
2512
11.1k
    }
2513
2514
55.1k
    dsc->endprolog = DSC_END(dsc);
2515
55.1k
    return CDSC_OK;
2516
58.0k
}
2517
2518
dsc_private int
2519
dsc_scan_setup(CDSC *dsc)
2520
36.1k
{
2521
    /* Setup section ends at */
2522
    /*  %%EndSetup */
2523
    /*  another section */
2524
    /* Setup section must start with %%BeginSetup */
2525
2526
36.1k
    char *line = dsc->line;
2527
36.1k
    dsc->id = CDSC_OK;
2528
2529
36.1k
    if (dsc->scan_section == scan_pre_setup) {
2530
7.75k
  if (IS_BLANK(line))
2531
1.00k
      return CDSC_OK;  /* ignore blank lines before setup */
2532
6.75k
  else if (IS_DSC(line, "%%BeginSetup")) {
2533
1.30k
      dsc->id = CDSC_BEGINSETUP;
2534
1.30k
      dsc->beginsetup = DSC_START(dsc);
2535
1.30k
      dsc->endsetup = DSC_END(dsc);
2536
1.30k
      dsc->scan_section = scan_setup;
2537
1.30k
      return CDSC_OK;
2538
1.30k
  }
2539
5.45k
  else {
2540
5.45k
      dsc->scan_section = scan_pre_pages;
2541
5.45k
      return CDSC_PROPAGATE;
2542
5.45k
  }
2543
7.75k
    }
2544
2545
28.4k
    if (NOT_DSC_LINE(line)) {
2546
  /* ignore */
2547
14.8k
    }
2548
13.5k
    else if (IS_DSC(line, "%%BeginPreview")) {
2549
  /* ignore because we have already processed this section */
2550
195
    }
2551
13.3k
    else if (IS_DSC(line, "%%BeginDefaults")) {
2552
  /* ignore because we have already processed this section */
2553
272
    }
2554
13.0k
    else if (IS_DSC(line, "%%BeginProlog")) {
2555
  /* ignore because we have already processed this section */
2556
357
    }
2557
12.7k
    else if (IS_DSC(line, "%%BeginSetup")) {
2558
  /* ignore because we are in this section */
2559
1.04k
    }
2560
11.6k
    else if (dsc_is_section(line)) {
2561
273
  dsc->endsetup = DSC_START(dsc);
2562
273
  dsc->scan_section = scan_pre_pages;
2563
273
  if (dsc_check_match(dsc))
2564
0
      return CDSC_NOTDSC;
2565
273
  return CDSC_PROPAGATE;
2566
273
    }
2567
11.4k
    else if (IS_DSC(line, "%%EndSetup")) {
2568
25
  dsc->id = CDSC_ENDSETUP;
2569
25
  dsc->endsetup = DSC_END(dsc);
2570
25
  dsc->scan_section = scan_pre_pages;
2571
25
  if (dsc_check_match(dsc))
2572
0
      return CDSC_NOTDSC;
2573
25
  return CDSC_OK;
2574
25
    }
2575
11.3k
    else if (IS_DSC(line, "%%BeginFeature:")) {
2576
364
  dsc->id = CDSC_BEGINFEATURE;
2577
  /* ignore Begin/EndFeature, apart form making sure */
2578
  /* that they are matched. */
2579
364
  dsc->begin_feature_count++;
2580
364
    }
2581
11.0k
    else if (IS_DSC(line, "%%EndFeature")) {
2582
290
  dsc->id = CDSC_ENDFEATURE;
2583
290
  dsc->begin_feature_count--;
2584
290
    }
2585
10.7k
    else if (IS_DSC(line, "%%Feature:")) {
2586
485
  dsc->id = CDSC_FEATURE;
2587
  /* ignore */
2588
485
    }
2589
10.2k
    else if (IS_DSC(line, "%%BeginResource:")) {
2590
216
  dsc->id = CDSC_BEGINRESOURCE;
2591
  /* ignore Begin/EndResource, apart form making sure */
2592
  /* that they are matched. */
2593
216
  dsc->begin_resource_count++;
2594
216
    }
2595
10.0k
    else if (IS_DSC(line, "%%EndResource")) {
2596
165
  dsc->id = CDSC_ENDRESOURCE;
2597
165
  dsc->begin_resource_count--;
2598
165
    }
2599
9.87k
    else if (IS_DSC(line, "%%PaperColor:")) {
2600
147
  dsc->id = CDSC_PAPERCOLOR;
2601
  /* ignore */
2602
147
    }
2603
9.72k
    else if (IS_DSC(line, "%%PaperForm:")) {
2604
321
  dsc->id = CDSC_PAPERFORM;
2605
  /* ignore */
2606
321
    }
2607
9.40k
    else if (IS_DSC(line, "%%PaperWeight:")) {
2608
142
  dsc->id = CDSC_PAPERWEIGHT;
2609
  /* ignore */
2610
142
    }
2611
9.26k
    else if (IS_DSC(line, "%%PaperSize:")) {
2612
  /* DSC 2.1 */
2613
521
        GSBOOL found_media = FALSE;
2614
521
  int i;
2615
521
  int n = 12;
2616
521
  char buf[MAXSTR];
2617
521
  buf[0] = '\0';
2618
521
  dsc->id = CDSC_PAPERSIZE;
2619
521
  dsc_copy_string(buf, sizeof(buf)-1, dsc->line+n, dsc->line_length-n, 
2620
521
    NULL);
2621
1.26k
  for (i=0; i<(int)dsc->media_count; i++) {
2622
845
      if (dsc->media[i] && dsc->media[i]->name && 
2623
245
    (dsc_stricmp(buf, dsc->media[i]->name)==0)) {
2624
106
    dsc->page_media = dsc->media[i];
2625
106
    found_media = TRUE;
2626
106
    break;
2627
106
      }
2628
845
  }
2629
521
  if (!found_media) {
2630
      /* It didn't match %%DocumentPaperSizes: */
2631
      /* Try our known media */
2632
415
      const CDSCMEDIA *m = dsc_known_media;
2633
19.0k
      while (m->name) {
2634
18.6k
    if (dsc_stricmp(buf, m->name)==0) {
2635
0
        dsc->page_media = m;
2636
0
        break;
2637
0
    }
2638
18.6k
    m++;
2639
18.6k
      }
2640
415
      if (m->name == NULL)
2641
415
    dsc_unknown(dsc);
2642
415
  }
2643
521
    }
2644
8.74k
    else {
2645
  /* All other DSC comments are unknown, but not an error */
2646
8.74k
  dsc->id = CDSC_UNKNOWNDSC;
2647
8.74k
  dsc_unknown(dsc);
2648
8.74k
    }
2649
2650
28.1k
    dsc->endsetup = DSC_END(dsc);
2651
28.1k
    return CDSC_OK;
2652
28.4k
}
2653
2654
dsc_private int 
2655
dsc_scan_page(CDSC *dsc)
2656
91.3k
{
2657
    /* Page section ends at */
2658
    /*  %%Page */
2659
    /*  %%Trailer */
2660
    /*  %%EOF */
2661
91.3k
    char *line = dsc->line;
2662
91.3k
    dsc->id = CDSC_OK;
2663
2664
91.3k
    if (dsc->scan_section == scan_pre_pages) {
2665
8.66k
  if (IS_DSC(line, "%%Page:")) {
2666
3.36k
      dsc->scan_section = scan_pages;
2667
      /* fall through */
2668
3.36k
  }
2669
5.30k
  else  {
2670
      /* %%Page: didn't follow %%EndSetup
2671
       * Keep reading until reach %%Page or %%Trailer
2672
       * and add it to previous section.
2673
       */
2674
5.30k
      unsigned long *last;
2675
5.30k
      if (dsc->endsetup != 0)
2676
389
    last = &dsc->endsetup;
2677
4.91k
      else if (dsc->endprolog != 0)
2678
3.02k
    last = &dsc->endprolog;
2679
1.89k
      else if (dsc->enddefaults != 0)
2680
379
    last = &dsc->enddefaults;
2681
1.51k
      else if (dsc->endpreview != 0)
2682
706
    last = &dsc->endpreview;
2683
805
      else if (dsc->endcomments != 0)
2684
805
    last = &dsc->endcomments;
2685
0
      else
2686
0
    last = &dsc->begincomments;
2687
5.30k
      *last = DSC_START(dsc);
2688
5.30k
      if (IS_DSC(line, "%%Trailer") || IS_DSC(line, "%%EOF")) {
2689
2.25k
    dsc->scan_section = scan_pre_trailer;
2690
2.25k
    return CDSC_PROPAGATE;
2691
2.25k
      }
2692
3.04k
      return CDSC_OK;
2693
5.30k
  }
2694
8.66k
    }
2695
2696
86.0k
    if (NOT_DSC_LINE(line)) {
2697
  /* ignore */
2698
44.7k
    }
2699
41.2k
    else if (IS_DSC(line, "%%Page:")) {
2700
11.1k
  dsc->id = CDSC_PAGE;
2701
11.1k
  if (dsc->page_count) {
2702
7.74k
      dsc->page[dsc->page_count-1].end = DSC_START(dsc);
2703
7.74k
      if (dsc_check_match(dsc))
2704
0
    return CDSC_NOTDSC;
2705
7.74k
  }
2706
2707
11.1k
  if (dsc_parse_page(dsc) != 0)
2708
0
      return CDSC_ERROR;
2709
2710
11.1k
  return CDSC_OK;
2711
11.1k
    }
2712
30.1k
    else if (IS_DSC(line, "%%BeginPreview")) {
2713
  /* ignore because we have already processed this section */
2714
337
    }
2715
29.8k
    else if (IS_DSC(line, "%%BeginDefaults")) {
2716
  /* ignore because we have already processed this section */
2717
521
    }
2718
29.2k
    else if (IS_DSC(line, "%%BeginProlog")) {
2719
  /* ignore because we have already processed this section */
2720
465
    }
2721
28.8k
    else if (IS_DSC(line, "%%BeginSetup")) {
2722
  /* ignore because we have already processed this section */
2723
752
    }
2724
28.0k
    else if (dsc_is_section(line)) {
2725
373
  if (IS_DSC(line, "%%Trailer")) {
2726
61
      dsc->page[dsc->page_count-1].end = DSC_START(dsc);
2727
61
      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
61
      else {
2756
61
    dsc->scan_section = scan_pre_trailer;
2757
61
    if (dsc_check_match(dsc))
2758
0
        return CDSC_NOTDSC;
2759
61
    return CDSC_PROPAGATE;
2760
61
      }
2761
61
  }
2762
312
  else if (IS_DSC(line, "%%EOF")) {
2763
312
      dsc->page[dsc->page_count-1].end = DSC_START(dsc);
2764
312
      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
312
      else {
2786
    /* ignore it */
2787
312
    if (dsc_check_match(dsc))
2788
0
        return CDSC_NOTDSC;
2789
312
    return CDSC_OK;
2790
312
      }
2791
312
  }
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
373
    }
2801
27.7k
    else if (IS_DSC(line, "%%PageTrailer")) {
2802
93
  dsc->id = CDSC_PAGETRAILER;
2803
  /* ignore */
2804
93
    }
2805
27.6k
    else if (IS_DSC(line, "%%BeginPageSetup")) {
2806
471
  dsc->id = CDSC_BEGINPAGESETUP;
2807
  /* ignore */
2808
471
    }
2809
27.1k
    else if (IS_DSC(line, "%%EndPageSetup")) {
2810
145
  dsc->id = CDSC_ENDPAGESETUP;
2811
  /* ignore */
2812
145
    }
2813
26.9k
    else if (IS_DSC(line, "%%PageMedia:")) {
2814
1.00k
  dsc->id = CDSC_PAGEMEDIA;
2815
1.00k
  dsc_parse_media(dsc, &(dsc->page[dsc->page_count-1].media));
2816
1.00k
    }
2817
25.9k
    else if (IS_DSC(line, "%%PaperColor:")) {
2818
368
  dsc->id = CDSC_PAPERCOLOR;
2819
  /* ignore */
2820
368
    }
2821
25.6k
    else if (IS_DSC(line, "%%PaperForm:")) {
2822
402
  dsc->id = CDSC_PAPERFORM;
2823
  /* ignore */
2824
402
    }
2825
25.2k
    else if (IS_DSC(line, "%%PaperWeight:")) {
2826
496
  dsc->id = CDSC_PAPERWEIGHT;
2827
  /* ignore */
2828
496
    }
2829
24.7k
    else if (IS_DSC(line, "%%PaperSize:")) {
2830
  /* DSC 2.1 */
2831
869
        GSBOOL found_media = FALSE;
2832
869
  int i;
2833
869
  int n = 12;
2834
869
  char buf[MAXSTR];
2835
869
  buf[0] = '\0';
2836
869
  dsc_copy_string(buf, sizeof(buf)-1, dsc->line+n, 
2837
869
      dsc->line_length-n, NULL);
2838
1.49k
  for (i=0; i<(int)dsc->media_count; i++) {
2839
736
      if (dsc->media[i] && dsc->media[i]->name && 
2840
235
    (dsc_stricmp(buf, dsc->media[i]->name)==0)) {
2841
109
    dsc->page_media = dsc->media[i];
2842
109
    found_media = TRUE;
2843
109
    break;
2844
109
      }
2845
736
  }
2846
869
  if (!found_media) {
2847
      /* It didn't match %%DocumentPaperSizes: */
2848
      /* Try our known media */
2849
760
      const CDSCMEDIA *m = dsc_known_media;
2850
34.9k
      while (m->name) {
2851
34.2k
    if (dsc_stricmp(buf, m->name)==0) {
2852
0
        dsc->page[dsc->page_count-1].media = m;
2853
0
        break;
2854
0
    }
2855
34.2k
    m++;
2856
34.2k
      }
2857
760
      if (m->name == NULL)
2858
760
    dsc_unknown(dsc);
2859
760
  }
2860
869
    }
2861
23.8k
    else if (IS_DSC(line, "%%PageOrientation:")) {
2862
811
  dsc->id = CDSC_PAGEORIENTATION;
2863
811
  if (dsc_parse_orientation(dsc, 
2864
811
    &(dsc->page[dsc->page_count-1].orientation) ,18))
2865
0
      return CDSC_NOTDSC;
2866
811
    }
2867
23.0k
    else if (IS_DSC(line, "%%PageBoundingBox:")) {
2868
315
  dsc->id = CDSC_PAGEBOUNDINGBOX;
2869
315
  if (dsc_parse_bounding_box(dsc, &dsc->page[dsc->page_count-1].bbox, 18))
2870
0
      return CDSC_NOTDSC;
2871
315
    }
2872
22.7k
    else if (IS_DSC(line, "%%ViewingOrientation:")) {
2873
1.98k
  dsc->id = CDSC_VIEWINGORIENTATION;
2874
1.98k
  if (dsc_parse_viewing_orientation(dsc, 
2875
1.98k
      &dsc->page[dsc->page_count-1].viewing_orientation))
2876
0
      return CDSC_ERROR;
2877
1.98k
    }
2878
20.7k
    else if (IS_DSC(line, "%%BeginFont:")) {
2879
559
  dsc->id = CDSC_BEGINFONT;
2880
  /* ignore Begin/EndFont, apart form making sure */
2881
  /* that they are matched. */
2882
559
  dsc->begin_font_count++;
2883
559
    }
2884
20.1k
    else if (IS_DSC(line, "%%EndFont")) {
2885
355
  dsc->id = CDSC_BEGINFONT;
2886
355
  dsc->begin_font_count--;
2887
355
    }
2888
19.8k
    else if (IS_DSC(line, "%%BeginFeature:")) {
2889
360
  dsc->id = CDSC_BEGINFEATURE;
2890
  /* ignore Begin/EndFeature, apart form making sure */
2891
  /* that they are matched. */
2892
360
  dsc->begin_feature_count++;
2893
360
    }
2894
19.4k
    else if (IS_DSC(line, "%%EndFeature")) {
2895
294
  dsc->id = CDSC_ENDFEATURE;
2896
294
  dsc->begin_feature_count--;
2897
294
    }
2898
19.1k
    else if (IS_DSC(line, "%%BeginResource:")) {
2899
161
  dsc->id = CDSC_BEGINRESOURCE;
2900
  /* ignore Begin/EndResource, apart form making sure */
2901
  /* that they are matched. */
2902
161
  dsc->begin_resource_count++;
2903
161
    }
2904
19.0k
    else if (IS_DSC(line, "%%EndResource")) {
2905
405
  dsc->id = CDSC_ENDRESOURCE;
2906
405
  dsc->begin_resource_count--;
2907
405
    }
2908
18.6k
    else if (IS_DSC(line, "%%BeginProcSet:")) {
2909
120
  dsc->id = CDSC_BEGINPROCSET;
2910
  /* ignore Begin/EndProcSet, apart form making sure */
2911
  /* that they are matched. */
2912
120
  dsc->begin_procset_count++;
2913
120
    }
2914
18.4k
    else if (IS_DSC(line, "%%EndProcSet")) {
2915
115
  dsc->id = CDSC_ENDPROCSET;
2916
115
  dsc->begin_procset_count--;
2917
115
    }
2918
18.3k
    else if (IS_DSC(line, "%%IncludeFont:")) {
2919
349
  dsc->id = CDSC_INCLUDEFONT;
2920
  /* ignore */
2921
349
    }
2922
18.0k
    else {
2923
  /* All other DSC comments are unknown, but not an error */
2924
18.0k
  dsc->id = CDSC_UNKNOWNDSC;
2925
18.0k
  dsc_unknown(dsc);
2926
18.0k
    }
2927
2928
74.5k
    dsc->page[dsc->page_count-1].end = DSC_END(dsc);
2929
74.5k
    return CDSC_OK;
2930
86.0k
}
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
53.4k
{
2977
    /* Trailer section start at */
2978
    /*  %%Trailer */
2979
    /* and ends at */
2980
    /*  %%EOF */
2981
53.4k
    char *line = dsc->line;
2982
53.4k
    GSBOOL continued = FALSE;
2983
53.4k
    dsc->id = CDSC_OK;
2984
2985
53.4k
    if (dsc->scan_section == scan_pre_trailer) {
2986
2.31k
  if (IS_DSC(line, "%%Trailer")) {
2987
1.12k
      dsc->id = CDSC_TRAILER;
2988
1.12k
      dsc->begintrailer = DSC_START(dsc);
2989
1.12k
      dsc->endtrailer = DSC_END(dsc);
2990
1.12k
      dsc->scan_section = scan_trailer;
2991
1.12k
      return CDSC_OK;
2992
1.12k
  }
2993
1.19k
  else if (IS_DSC(line, "%%EOF")) {
2994
1.19k
      dsc->id = CDSC_EOF;
2995
1.19k
      dsc->begintrailer = DSC_START(dsc);
2996
1.19k
      dsc->endtrailer = DSC_END(dsc);
2997
1.19k
      dsc->scan_section = scan_trailer;
2998
      /* Continue, in case we found %%EOF in an embedded document */
2999
1.19k
      return CDSC_OK;
3000
1.19k
  }
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
2.31k
    }
3017
3018
    /* Handle continuation lines.
3019
     * See comment above about our restrictive processing of 
3020
     * continuation lines
3021
     */
3022
51.0k
    if (IS_DSC(line, "%%+")) {
3023
6.33k
  line = dsc->last_line;
3024
6.33k
  continued = TRUE;
3025
6.33k
    }
3026
44.7k
    else
3027
44.7k
  dsc_save_line(dsc);
3028
3029
51.0k
    if (NOT_DSC_LINE(line)) {
3030
  /* ignore */
3031
25.5k
    }
3032
25.5k
    else if (IS_DSC(dsc->line, "%%EOF")) {
3033
  /* Keep scanning, in case we have a false trailer */
3034
2.01k
  dsc->id = CDSC_EOF;
3035
2.01k
    }
3036
23.5k
    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
883
  dsc->id = CDSC_TRAILER;
3040
883
  dsc->begintrailer = DSC_START(dsc);
3041
883
    }
3042
22.6k
    else if (IS_DSC(line, "%%Pages:")) {
3043
1.64k
  dsc->id = CDSC_PAGES;
3044
1.64k
  if (dsc_parse_pages(dsc) != 0)
3045
0
         return CDSC_ERROR;
3046
1.64k
    }
3047
21.0k
    else if (IS_DSC(line, "%%BoundingBox:")) {
3048
2.45k
  dsc->id = CDSC_BOUNDINGBOX;
3049
2.45k
  if (dsc_parse_bounding_box(dsc, &(dsc->bbox), continued ? 3 : 14))
3050
0
      return CDSC_ERROR;
3051
2.45k
    }
3052
18.5k
    else if (IS_DSC(line, "%%HiResBoundingBox:")) {
3053
493
  dsc->id = CDSC_HIRESBOUNDINGBOX;
3054
493
  if (dsc_parse_float_bounding_box(dsc, &(dsc->hires_bbox), 
3055
493
      continued ? 3 : 19))
3056
0
      return CDSC_ERROR;
3057
493
    }
3058
18.1k
    else if (IS_DSC(line, "%%CropBox:")) {
3059
2.19k
  dsc->id = CDSC_CROPBOX;
3060
2.19k
  if (dsc_parse_float_bounding_box(dsc, &(dsc->crop_box), 
3061
2.19k
      continued ? 3 : 10))
3062
0
      return CDSC_ERROR;
3063
2.19k
    }
3064
15.9k
    else if (IS_DSC(line, "%%Orientation:")) {
3065
1.47k
  dsc->id = CDSC_ORIENTATION;
3066
1.47k
  if (dsc_parse_orientation(dsc, &(dsc->page_orientation), continued ? 3 : 14))
3067
0
      return CDSC_ERROR;
3068
1.47k
    }
3069
14.4k
    else if (IS_DSC(line, "%%PageOrder:")) {
3070
1.53k
  dsc->id = CDSC_PAGEORDER;
3071
1.53k
  if (dsc_parse_order(dsc))
3072
0
      return CDSC_ERROR;
3073
1.53k
    }
3074
12.8k
    else if (IS_DSC(line, "%%DocumentMedia:")) {
3075
797
  dsc->id = CDSC_DOCUMENTMEDIA;
3076
797
  if (dsc_parse_document_media(dsc))
3077
0
      return CDSC_ERROR;
3078
797
    }
3079
12.0k
    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
1.39k
  int rc = dsc_error(dsc, CDSC_MESSAGE_PAGE_IN_TRAILER, 
3084
1.39k
    dsc->line, dsc->line_length);
3085
1.39k
  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
1.39k
      case CDSC_RESPONSE_CANCEL:
3094
    /* ignore pages in trailer */
3095
1.39k
    break;
3096
0
      case CDSC_RESPONSE_IGNORE_ALL:
3097
0
    return CDSC_NOTDSC;
3098
1.39k
  }
3099
1.39k
    }
3100
10.7k
    else if (IS_DSC(line, "%%DocumentNeededFonts:")) {
3101
284
  dsc->id = CDSC_DOCUMENTNEEDEDFONTS;
3102
  /* ignore */
3103
284
    }
3104
10.4k
    else if (IS_DSC(line, "%%DocumentSuppliedFonts:")) {
3105
281
  dsc->id = CDSC_DOCUMENTSUPPLIEDFONTS;
3106
  /* ignore */
3107
281
    }
3108
10.1k
    else {
3109
  /* All other DSC comments are unknown, but not an error */
3110
10.1k
  dsc->id = CDSC_UNKNOWNDSC;
3111
10.1k
  dsc_unknown(dsc);
3112
10.1k
    }
3113
3114
51.0k
    dsc->endtrailer = DSC_END(dsc);
3115
51.0k
    return CDSC_OK;
3116
51.0k
}
3117
3118
3119
dsc_private char *
3120
dsc_alloc_string(CDSC *dsc, const char *str, int len)
3121
35.9k
{
3122
35.9k
    if (len < 0) {
3123
1.15k
  return nullptr;
3124
1.15k
    }
3125
3126
34.8k
    char *p;
3127
34.8k
    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
34.8k
    if ( dsc->string->index + len + 1 > dsc->string->length) {
3142
  /* allocate another string block */
3143
23
  CDSCSTRING *newstring = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
3144
23
  if (newstring == NULL) {
3145
0
      dsc_debug_print(dsc, "Out of memory\n");
3146
0
      return NULL;
3147
0
  }
3148
23
        newstring->next = NULL;
3149
23
  newstring->length = 0;
3150
23
  newstring->index = 0;
3151
23
  newstring->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
3152
23
  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
23
  newstring->length = CDSC_STRING_CHUNK;
3158
23
  dsc->string->next = newstring;
3159
23
  dsc->string = newstring;
3160
23
    }
3161
34.8k
    if ( dsc->string->index + len + 1 > dsc->string->length)
3162
23
  return NULL;  /* failed */
3163
34.8k
    p = dsc->string->data + dsc->string->index;
3164
34.8k
    memcpy(p, str, len);
3165
34.8k
    *(p+len) = '\0';
3166
34.8k
    dsc->string->index += len + 1;
3167
34.8k
    return p;
3168
34.8k
}
3169
3170
/* store line, ignoring leading spaces */
3171
dsc_private char *
3172
dsc_add_line(CDSC *dsc, const char *line, unsigned int len)
3173
17.2k
{
3174
17.2k
    char *newline;
3175
17.2k
    unsigned int i;
3176
23.4k
    while (len && (IS_WHITE(*line))) {
3177
6.18k
  len--;
3178
6.18k
  line++;
3179
6.18k
    }
3180
17.2k
    newline = dsc_alloc_string(dsc, line, len);
3181
17.2k
    if (newline == NULL)
3182
1.17k
  return NULL;
3183
3184
406k
    for (i=0; i<len; i++) {
3185
405k
  if (newline[i] == '\r') {
3186
12.4k
      newline[i]='\0';
3187
12.4k
      break;
3188
12.4k
  }
3189
393k
  if (newline[i] == '\n') {
3190
2.60k
      newline[i]='\0';
3191
2.60k
      break;
3192
2.60k
  }
3193
393k
    }
3194
16.0k
    return newline;
3195
17.2k
}
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
24.6k
{
3208
24.6k
    int quoted = FALSE;
3209
24.6k
    int instring=0;
3210
24.6k
    unsigned int newlength = 0;
3211
24.6k
    unsigned int i = 0;
3212
24.6k
    unsigned char ch;
3213
24.6k
    if (len > slen)
3214
1.58k
  len = slen-1;
3215
36.5k
    while ( (i<len) && IS_WHITE(line[i]))
3216
11.9k
  i++; /* skip leading spaces */
3217
24.6k
    if (line[i]=='(') {
3218
774
  quoted = TRUE;
3219
774
  instring++;
3220
774
  i++; /* don't copy outside () */
3221
774
    }
3222
419k
    while (i < len) {
3223
418k
  str[newlength] = ch = line[i];
3224
418k
  i++;
3225
418k
  if (quoted) {
3226
22.4k
      if (ch == '(')
3227
2.56k
        instring++;
3228
22.4k
      if (ch == ')')
3229
355
        instring--;
3230
22.4k
      if (instring==0)
3231
151
        break;
3232
22.4k
  }
3233
395k
  else if (ch == ' ')
3234
8.00k
      break;
3235
3236
409k
  if (ch == '\r')
3237
11.9k
      break;
3238
398k
  if (ch == '\n')
3239
3.44k
      break;
3240
394k
  else if ( (ch == '\\') && (i+1 < len) ) {
3241
6.53k
      ch = line[i];
3242
6.53k
      if ((ch >= '0') && (ch <= '9')) {
3243
    /* octal coded character */
3244
1.51k
    int j = 3;
3245
1.51k
    ch = 0;
3246
4.02k
    while (j && (i < len) && line[i]>='0' && line[i]<='7') {
3247
2.50k
        ch = (unsigned char)((ch<<3) + (line[i]-'0'));
3248
2.50k
        i++;
3249
2.50k
        j--;
3250
2.50k
    }
3251
1.51k
    str[newlength] = ch;
3252
1.51k
      }
3253
5.01k
      else if (ch == '(') {
3254
221
    str[newlength] = ch;
3255
221
    i++;
3256
221
      }
3257
4.79k
      else if (ch == ')') {
3258
95
    str[newlength] = ch;
3259
95
    i++;
3260
95
      }
3261
4.70k
      else if (ch == 'b') {
3262
289
    str[newlength] = '\b';
3263
289
    i++;
3264
289
      }
3265
4.41k
      else if (ch == 'f') {
3266
132
    str[newlength] = '\b';
3267
132
    i++;
3268
132
      }
3269
4.27k
      else if (ch == 'n') {
3270
579
    str[newlength] = '\n';
3271
579
    i++;
3272
579
      }
3273
3.70k
      else if (ch == 'r') {
3274
508
    str[newlength] = '\r';
3275
508
    i++;
3276
508
      }
3277
3.19k
      else if (ch == 't') {
3278
247
    str[newlength] = '\t';
3279
247
    i++;
3280
247
      }
3281
2.94k
      else if (ch == '\\') {
3282
1.11k
    str[newlength] = '\\';
3283
1.11k
    i++;
3284
1.11k
      }
3285
6.53k
  }
3286
394k
  newlength++;
3287
394k
    }
3288
24.6k
    str[newlength] = '\0';
3289
24.6k
    if (offset != (unsigned int *)NULL)
3290
22.0k
        *offset = i;
3291
24.6k
    return str;
3292
24.6k
}
3293
3294
dsc_private int 
3295
dsc_get_int(const char *line, unsigned int len, unsigned int *offset)
3296
18.8k
{
3297
18.8k
    char newline[MAXSTR];
3298
18.8k
    int newlength = 0;
3299
18.8k
    unsigned int i = 0;
3300
18.8k
    unsigned char ch;
3301
3302
18.8k
    len = min(len, sizeof(newline)-1);
3303
49.5k
    while ((i<len) && IS_WHITE(line[i]))
3304
30.7k
  i++; /* skip leading spaces */
3305
220k
    while (i < len) {
3306
219k
  newline[newlength] = ch = line[i];
3307
219k
  if (!(isdigit(ch) || (ch=='-') || (ch=='+')))
3308
18.4k
      break;  /* not part of an integer number */
3309
201k
  i++;
3310
201k
  newlength++;
3311
201k
    }
3312
132k
    while ((i<len) && IS_WHITE(line[i]))
3313
113k
  i++; /* skip trailing spaces */
3314
18.8k
    newline[newlength] = '\0';
3315
18.8k
    if (offset != (unsigned int *)NULL)
3316
18.8k
        *offset = i;
3317
18.8k
    return atoi(newline);
3318
18.8k
}
3319
3320
dsc_private float 
3321
dsc_get_real(const char *line, unsigned int len, unsigned int *offset)
3322
24.3k
{
3323
24.3k
    char newline[MAXSTR];
3324
24.3k
    int newlength = 0;
3325
24.3k
    unsigned int i = 0;
3326
24.3k
    unsigned char ch;
3327
3328
24.3k
    len = min(len, sizeof(newline)-1);
3329
150k
    while ((i<len) && IS_WHITE(line[i]))
3330
125k
  i++; /* skip leading spaces */
3331
405k
    while (i < len) {
3332
403k
  newline[newlength] = ch = line[i];
3333
403k
  if (!(isdigit(ch) || (ch=='.') || (ch=='-') || (ch=='+') 
3334
128k
      || (ch=='e') || (ch=='E')))
3335
22.4k
      break;  /* not part of a real number */
3336
380k
  i++;
3337
380k
  newlength++;
3338
380k
    }
3339
165k
    while ((i<len) && IS_WHITE(line[i]))
3340
141k
  i++; /* skip trailing spaces */
3341
3342
24.3k
    newline[newlength] = '\0';
3343
3344
24.3k
    if (offset != (unsigned int *)NULL)
3345
24.3k
        *offset = i;
3346
24.3k
    return (float)atof(newline);
3347
24.3k
}
3348
3349
dsc_private int
3350
dsc_stricmp(const char *s, const char *t)
3351
220k
{
3352
225k
    while (toupper(*s) == toupper(*t)) {
3353
5.49k
  if (*s == '\0')
3354
305
      return 0;
3355
5.19k
    s++;
3356
5.19k
  t++; 
3357
5.19k
    }
3358
220k
    return (toupper(*s) - toupper(*t));
3359
220k
}
3360
3361
3362
dsc_private int
3363
dsc_parse_page(CDSC *dsc)
3364
11.1k
{
3365
11.1k
    char *p;
3366
11.1k
    unsigned int i;
3367
11.1k
    char page_label[MAXSTR];
3368
11.1k
    char *pl;
3369
11.1k
    int page_ordinal;
3370
11.1k
    int page_number;
3371
3372
11.1k
    p = dsc->line + 7;
3373
11.1k
    pl = dsc_copy_string(page_label, sizeof(page_label)-1, p, dsc->line_length-7, &i);
3374
11.1k
    if (pl == NULL)
3375
0
  return CDSC_ERROR;
3376
11.1k
    p += i;
3377
11.1k
    page_ordinal = atoi(p);
3378
3379
11.1k
    if ( (page_ordinal == 0) || (strlen(page_label) == 0) ||
3380
831
       (dsc->page_count && 
3381
10.8k
      (page_ordinal != dsc->page[dsc->page_count-1].ordinal+1)) ) {
3382
10.8k
  int rc = dsc_error(dsc, CDSC_MESSAGE_PAGE_ORDINAL, dsc->line, 
3383
10.8k
    dsc->line_length);
3384
10.8k
  switch (rc) {
3385
0
      case CDSC_RESPONSE_OK:
3386
    /* ignore this page */
3387
0
    return CDSC_OK;
3388
10.8k
      case CDSC_RESPONSE_CANCEL:
3389
    /* accept the page */
3390
10.8k
    break;
3391
0
      case CDSC_RESPONSE_IGNORE_ALL:
3392
0
    return CDSC_NOTDSC;
3393
10.8k
  }
3394
10.8k
    }
3395
3396
11.1k
    page_number = dsc->page_count;
3397
11.1k
    dsc_add_page(dsc, page_ordinal, page_label);
3398
11.1k
    dsc->page[page_number].begin = DSC_START(dsc);
3399
11.1k
    dsc->page[page_number].end = DSC_START(dsc);
3400
3401
11.1k
    if (dsc->page[page_number].label == NULL)
3402
0
  return CDSC_ERROR; /* no memory */
3403
  
3404
11.1k
    return CDSC_OK;
3405
11.1k
}
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
27.8k
{
3435
    /* if error function provided, use it */
3436
27.8k
    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
27.8k
    return CDSC_RESPONSE_CANCEL;
3442
27.8k
}
3443
3444
3445
// vim:sw=4:sts=4:ts=8:noet