Coverage Report

Created: 2026-04-29 07:00

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