Coverage Report

Created: 2026-05-31 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kdegraphics-thumbnailers/ps/dscparse.cpp
Line
Count
Source
1
/* SPDX-FileCopyrightText: 2000-2001 Ghostgum Software Pty Ltd. All rights reserved.
2
    
3
  This file is part of GSview.
4
   
5
  This file is distributed in the hope that it will be useful, but
6
  WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
7
  to anyone for the consequences of using it or for whether it serves any
8
  particular purpose or works at all, unless he says so in writing.  Refer
9
  to the GNU General Public License for full details.
10
   
11
  Everyone is granted permission to copy, modify and redistribute this
12
  file, but only under the conditions described in the GNU General
13
  Public License.  A copy of this license is supposed to have been given
14
  to you along with this file so you can know your rights and
15
  responsibilities.  It should be in a file named COPYING.  Among other
16
  things, the copyright notice and this notice must be preserved on all
17
  copies.
18
*/
19
20
/* $Id$ */
21
22
/* dscparse.c - DSC parser  */
23
24
/*
25
 * This is a DSC parser, based on the DSC 3.0 spec, 
26
 * with a few DSC 2.1 additions for page size.
27
 *
28
 * Current limitations:
29
 * %%+ may be used after any comment in the comment or trailer, 
30
 * but is currently only supported by
31
 *   %%DocumentMedia
32
 *
33
 * DSC 2.1 additions (discontinued in DSC 3.0):
34
 * %%DocumentPaperColors: 
35
 * %%DocumentPaperForms: 
36
 * %%DocumentPaperSizes: 
37
 * %%DocumentPaperWeights: 
38
 * %%PaperColor:   (ignored)
39
 * %%PaperForm:    (ignored)
40
 * %%PaperSize: 
41
 * %%PaperWeight:  (ignored)
42
 *
43
 * Other additions for defaults or page section
44
 % %%ViewingOrientation: xx xy yx yy
45
*/
46
47
#include <stdio.h>  /* for sprintf(), not file I/O */
48
#include <stdlib.h>
49
#include <string.h>
50
#include <ctype.h>
51
52
#define MAXSTR 256
53
54
#include "dscparse.h"
55
56
/* Macros for comparing string literals
57
 * For maximum speed, the length of the second macro argument is
58
 * computed at compile time.
59
 * THE SECOND MACRO ARGUMENT MUST BE A STRING LITERAL.
60
 */
61
4.37M
#define COMPARE(p,str) (strncmp((const char *)(p), (str), sizeof(str)-1)==0)
62
3.93M
#define IS_DSC(line, str) (COMPARE((line), (str)))
63
64
/* Macros for comparing the first one or two characters */
65
619k
#define IS_WHITE(ch) (((ch)==' ') || ((ch)=='\t'))
66
166k
#define IS_EOL(ch) (((ch)=='\r') || ((ch)=='\n'))
67
71.7k
#define IS_WHITE_OR_EOL(ch) (IS_WHITE(ch) || IS_EOL(ch))
68
32.5k
#define IS_BLANK(str) (IS_EOL(str[0]))
69
199k
#define NOT_DSC_LINE(str) (((str)[0]!='%') || ((str)[1]!='%'))
70
71
/* Macros for document offset to start and end of line */
72
59.9k
#define DSC_START(dsc)  ((dsc)->data_offset + (dsc)->data_index - (dsc)->line_length)
73
253k
#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
349k
#define CDSC_PROPAGATE  10
81
82
/* If document is DOS EPS and we haven't read 30 bytes, ask for more. */
83
370k
#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
29.9k
#define DSC_MAX_ERROR ((sizeof(dsc_severity) / sizeof(int))-2)
149
150
const CDSCMEDIA dsc_known_media[CDSC_KNOWN_MEDIA] = {
151
    /* These sizes taken from Ghostscript gs_statd.ps */
152
    {"11x17", 792, 1224, 0, NULL, NULL, NULL},
153
    {"A0", 2380, 3368, 0, NULL, NULL, NULL},
154
    {"A1", 1684, 2380, 0, NULL, NULL, NULL}, 
155
    {"A2", 1190, 1684, 0, NULL, NULL, NULL}, 
156
    {"A3", 842, 1190, 0, NULL, NULL, NULL},
157
    {"A4", 595, 842, 0, NULL, NULL, NULL},
158
    {"A5", 421, 595, 0, NULL, NULL, NULL},
159
    {"A6", 297, 421, 0, NULL, NULL, NULL}, 
160
    {"A7", 210, 297, 0, NULL, NULL, NULL}, 
161
    {"A8", 148, 210, 0, NULL, NULL, NULL}, 
162
    {"A9", 105, 148, 0, NULL, NULL, NULL}, 
163
    {"A10", 74, 105, 0, NULL, NULL, NULL}, 
164
    {"B0", 2836, 4008, 0, NULL, NULL, NULL}, 
165
    {"B1", 2004, 2836, 0, NULL, NULL, NULL}, 
166
    {"B2", 1418, 2004, 0, NULL, NULL, NULL}, 
167
    {"B3", 1002, 1418, 0, NULL, NULL, NULL}, 
168
    {"B4", 709, 1002, 0, NULL, NULL, NULL}, /* ISO, but not Adobe standard */
169
    {"B5", 501, 709, 0, NULL, NULL, NULL},  /* ISO, but not Adobe standard */
170
    {"B6", 354, 501, 0, NULL, NULL, NULL}, 
171
    {"C0", 2600, 3677, 0, NULL, NULL, NULL}, 
172
    {"C1", 1837, 2600, 0, NULL, NULL, NULL},  
173
    {"C2", 1298, 1837, 0, NULL, NULL, NULL}, 
174
    {"C3", 918, 1298, 0, NULL, NULL, NULL}, 
175
    {"C4", 649, 918, 0, NULL, NULL, NULL}, 
176
    {"C5", 459, 649, 0, NULL, NULL, NULL}, 
177
    {"C6", 323, 459, 0, NULL, NULL, NULL}, 
178
    {"Ledger", 1224, 792, 0, NULL, NULL, NULL},
179
    {"Legal", 612, 1008, 0, NULL, NULL, NULL},
180
    {"Letter", 612, 792, 0, NULL, NULL, NULL},
181
    {"Note", 612, 792, 0, NULL, NULL, NULL},
182
// ISO and JIS B sizes are different....
183
    {"jisb0", 2916, 4128, 0, NULL, NULL, NULL},
184
    {"jisb1", 2064, 2916, 0, NULL, NULL, NULL}, 
185
    {"jisb2", 1458, 2064, 0, NULL, NULL, NULL}, 
186
    {"jisb3", 1032, 1458, 0, NULL, NULL, NULL}, 
187
    {"jisb4", 729, 1032, 0, NULL, NULL, NULL}, 
188
    {"jisb5", 516, 729, 0, NULL, NULL, NULL}, 
189
    {"jisb6", 363, 516, 0, NULL, NULL, NULL}, 
190
// U.S. CAD standard paper sizes
191
    {"archE", 2592, 3456, 0, NULL, NULL, NULL}, 
192
    {"archD", 1728, 2592, 0, NULL, NULL, NULL}, 
193
    {"archC", 1296, 1728, 0, NULL, NULL, NULL}, 
194
    {"archB", 864, 1296, 0, NULL, NULL, NULL}, 
195
    {"archA", 648, 864, 0, NULL, NULL, NULL}, 
196
// Other paper sizes
197
    {"flsa", 612, 936, 0, NULL, NULL, NULL}, /* U.S. foolscap */
198
    {"flse", 612, 936, 0, NULL, NULL, NULL}, /* European foolscap */
199
    {"halfletter", 396, 612, 0, NULL, NULL, NULL}, 
200
    {NULL, 0, 0, 0, NULL, NULL, NULL}
201
};
202
203
/* parser state */
204
enum CDSC_SCAN_SECTION {
205
    scan_none = 0,
206
    scan_comments = 1,
207
    scan_pre_preview = 2,
208
    scan_preview = 3,
209
    scan_pre_defaults = 4,
210
    scan_defaults = 5,
211
    scan_pre_prolog = 6,
212
    scan_prolog = 7,
213
    scan_pre_setup = 8,
214
    scan_setup = 9,
215
    scan_pre_pages = 10,
216
    scan_pages = 11,
217
    scan_pre_trailer = 12,
218
    scan_trailer = 13,
219
    scan_eof = 14
220
};
221
222
static const char * const dsc_scan_section_name[15] = {
223
 "Type", "Comments", 
224
 "pre-Preview", "Preview",
225
 "pre-Defaults", "Defaults",
226
 "pre-Prolog", "Prolog",
227
 "pre-Setup", "Setup",
228
 "pre-Page", "Page",
229
 "pre-Trailer", "Trailer",
230
 "EOF"
231
};
232
233
/******************************************************************/
234
/* Public functions                                               */
235
/******************************************************************/
236
237
/* constructor */
238
CDSC *
239
dsc_init(void *caller_data)
240
14.9k
{
241
14.9k
    CDSC *dsc = (CDSC *)malloc(sizeof(CDSC));
242
14.9k
    if (dsc == NULL)
243
0
  return NULL;
244
14.9k
    memset(dsc, 0, sizeof(CDSC));
245
14.9k
    dsc->caller_data = caller_data;
246
247
14.9k
    return dsc_init2(dsc);
248
14.9k
}
249
250
/* constructor, with caller supplied memalloc */
251
CDSC *
252
dsc_init_with_alloc(
253
    void *caller_data,
254
    void *(*memalloc)(size_t size, void *closure_data),
255
    void (*memfree)(void *ptr, void *closure_data),
256
    void *closure_data)
257
0
{
258
0
    CDSC *dsc = (CDSC *)memalloc(sizeof(CDSC), closure_data);
259
0
    if (dsc == NULL)
260
0
  return NULL;
261
0
    memset(dsc, 0, sizeof(CDSC));
262
0
    dsc->caller_data = caller_data;
263
264
0
    dsc->memalloc = memalloc;
265
0
    dsc->memfree = memfree;
266
0
    dsc->mem_closure_data = closure_data;
267
    
268
0
    return dsc_init2(dsc);
269
0
}
270
271
272
273
/* destructor */
274
void 
275
dsc_free(CDSC *dsc)
276
14.9k
{
277
14.9k
    if (dsc == NULL)
278
0
  return;
279
14.9k
    dsc_reset(dsc);
280
14.9k
    dsc_memfree(dsc, dsc);
281
14.9k
}
282
283
284
/* Tell DSC parser how long document will be, to allow ignoring
285
 * of early %%Trailer and %%EOF.  This is optional.
286
 */
287
void 
288
dsc_set_length(CDSC *dsc, unsigned long len)
289
0
{
290
0
    dsc->file_length = len;
291
0
}
292
293
/* Process a buffer containing DSC comments and PostScript */
294
/* Return value is < 0 for error, >=0 for OK.
295
 *  CDSC_ERROR
296
 *  CDSC_OK
297
 *  CDSC_NOTDSC (DSC will be ignored)
298
 *  other values indicate the last DSC comment read
299
 */ 
300
int
301
dsc_scan_data(CDSC *dsc, const char *data, int length)
302
129k
{
303
129k
    int bytes_read;
304
129k
    int code = 0;
305
306
129k
    if (dsc == NULL)
307
0
  return CDSC_ERROR;
308
309
129k
    if (dsc->id == CDSC_NOTDSC)
310
2.06k
  return CDSC_NOTDSC;
311
312
127k
    dsc->id = CDSC_OK;
313
127k
    if (dsc->eof)
314
0
  return CDSC_OK; /* ignore */
315
316
127k
    if (length == 0) {
317
  /* EOF, so process what remains */
318
0
  dsc->eof = TRUE;
319
0
    }
320
321
127k
    do {
322
127k
  if (dsc->id == CDSC_NOTDSC)
323
0
      break;
324
325
127k
  if (length != 0) {
326
127k
      if (dsc->data_index > dsc->data_length)
327
600
    return CDSC_NOTDSC;
328
329
      /* move existing data if needed */
330
127k
      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
127k
      bytes_read = min(length, (int)(CDSC_DATA_LENGTH - dsc->data_length));
339
127k
      memcpy(dsc->data + dsc->data_length, data, bytes_read);
340
127k
      dsc->data_length += bytes_read;
341
127k
      data += bytes_read;
342
127k
      length -= bytes_read;
343
127k
  }
344
127k
  if (dsc->scan_section == scan_none) {
345
56.3k
      code = dsc_scan_type(dsc);
346
56.3k
      if (code == CDSC_NEEDMORE) {
347
    /* need more characters before we can identify type */
348
42.3k
    code = CDSC_OK;
349
42.3k
    break;
350
42.3k
      }
351
13.9k
      dsc->id = code;
352
13.9k
  }
353
354
84.9k
        if (code == CDSC_NOTDSC) {
355
578
      dsc->id = CDSC_NOTDSC;
356
578
      break;
357
578
  }
358
359
364k
  while ((code = dsc_read_line(dsc)) > 0) {
360
281k
      if (dsc->id == CDSC_NOTDSC)
361
0
    break;
362
281k
      if (dsc->doseps_end && 
363
2.26k
    (dsc->data_offset + dsc->data_index > dsc->doseps_end)) {
364
    /* have read past end of DOS EPS PostScript section */
365
1.44k
    return CDSC_OK; /* ignore */
366
1.44k
      }
367
279k
      if (dsc->eof)
368
0
    return CDSC_OK;
369
279k
      if (dsc->skip_document)
370
5.80k
    continue;  /* embedded document */
371
274k
      if (dsc->skip_lines)
372
0
    continue; /* embedded lines */
373
274k
      if (IS_DSC(dsc->line, "%%BeginData:"))
374
909
    continue;
375
273k
      if (IS_DSC(dsc->line, "%%BeginBinary:"))
376
668
    continue;
377
272k
      if (IS_DSC(dsc->line, "%%EndDocument"))
378
150
    continue;
379
272k
      if (IS_DSC(dsc->line, "%%EndData"))
380
126
    continue;
381
272k
      if (IS_DSC(dsc->line, "%%EndBinary"))
382
252
    continue;
383
384
310k
      do {
385
310k
    switch (dsc->scan_section) {
386
54.7k
        case scan_comments:
387
54.7k
      code = dsc_scan_comments(dsc);
388
54.7k
      break;
389
16.5k
        case scan_pre_preview:
390
28.2k
        case scan_preview:
391
28.2k
      code = dsc_scan_preview(dsc);
392
28.2k
      break;
393
9.43k
        case scan_pre_defaults:
394
23.4k
        case scan_defaults:
395
23.4k
      code = dsc_scan_defaults(dsc);
396
23.4k
      break;
397
7.98k
        case scan_pre_prolog:
398
58.1k
        case scan_prolog:
399
58.1k
      code = dsc_scan_prolog(dsc);
400
58.1k
      break;
401
6.55k
        case scan_pre_setup:
402
32.9k
        case scan_setup:
403
32.9k
      code = dsc_scan_setup(dsc);
404
32.9k
      break;
405
9.39k
        case scan_pre_pages:
406
77.7k
        case scan_pages:
407
77.7k
      code = dsc_scan_page(dsc);
408
77.7k
      break;
409
1.88k
        case scan_pre_trailer:
410
35.2k
        case scan_trailer:
411
35.2k
      code = dsc_scan_trailer(dsc);
412
35.2k
      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
310k
    }
420
    /* repeat if line is start of next section */
421
310k
      } while (code == CDSC_PROPAGATE);
422
423
      /* if DOS EPS header not complete, ask for more */
424
271k
      if (code == CDSC_NEEDMORE) {
425
0
    code = CDSC_OK;
426
0
    break;
427
0
      }
428
271k
      if (code == CDSC_NOTDSC) {
429
0
    dsc->id = CDSC_NOTDSC;
430
0
    break;
431
0
      }
432
271k
  }
433
84.3k
    } while (length != 0);
434
435
125k
    return (code < 0) ? code : dsc->id;
436
127k
}
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.29k
{
594
8.29k
    dsc->page[dsc->page_count].ordinal = ordinal;
595
8.29k
    dsc->page[dsc->page_count].label = 
596
8.29k
  dsc_alloc_string(dsc, label, strlen(label)+1);
597
8.29k
    dsc->page[dsc->page_count].begin = 0;
598
8.29k
    dsc->page[dsc->page_count].end = 0;
599
8.29k
    dsc->page[dsc->page_count].orientation = CDSC_ORIENT_UNKNOWN;
600
8.29k
    dsc->page[dsc->page_count].media = NULL;
601
8.29k
    dsc->page[dsc->page_count].bbox = NULL;
602
8.29k
    dsc->page[dsc->page_count].viewing_orientation = NULL;
603
604
8.29k
    dsc->page_count++;
605
8.29k
    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.29k
    return CDSC_OK;
617
8.29k
}
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
3.45k
{
624
3.45k
    CDSCMEDIA **newmedia_array;
625
3.45k
    CDSCMEDIA *newmedia;
626
627
    /* extend media array  */
628
3.45k
    newmedia_array = (CDSCMEDIA **)dsc_memalloc(dsc, 
629
3.45k
  (dsc->media_count + 1) * sizeof(CDSCMEDIA *));
630
3.45k
    if (newmedia_array == NULL)
631
0
  return CDSC_ERROR; /* out of memory */
632
3.45k
    if (dsc->media != NULL) {
633
2.56k
  memcpy(newmedia_array, dsc->media, 
634
2.56k
      dsc->media_count * sizeof(CDSCMEDIA *));
635
2.56k
  dsc_memfree(dsc, dsc->media);
636
2.56k
    }
637
3.45k
    dsc->media = newmedia_array;
638
639
    /* allocate new media */
640
3.45k
    newmedia = dsc->media[dsc->media_count] =
641
3.45k
  (CDSCMEDIA *)dsc_memalloc(dsc, sizeof(CDSCMEDIA));
642
3.45k
    if (newmedia == NULL)
643
0
  return CDSC_ERROR; /* out of memory */
644
3.45k
    newmedia->name = NULL;
645
3.45k
    newmedia->width = 595.0;
646
3.45k
    newmedia->height = 842.0;
647
3.45k
    newmedia->weight = 80.0;
648
3.45k
    newmedia->colour = NULL;
649
3.45k
    newmedia->type = NULL;
650
3.45k
    newmedia->mediabox = NULL;
651
652
3.45k
    dsc->media_count++;
653
654
3.45k
    if (media->name) {
655
1.30k
  newmedia->name = dsc_alloc_string(dsc, media->name,
656
1.30k
      strlen(media->name));
657
1.30k
  if (newmedia->name == NULL)
658
0
      return CDSC_ERROR; /* no memory */
659
1.30k
    }
660
3.45k
    newmedia->width = media->width;
661
3.45k
    newmedia->height = media->height;
662
3.45k
    newmedia->weight = media->weight;
663
3.45k
    if (media->colour) {
664
1.48k
  newmedia->colour = dsc_alloc_string(dsc, media->colour, 
665
1.48k
      strlen(media->colour));
666
1.48k
        if (newmedia->colour == NULL)
667
0
      return CDSC_ERROR; /* no memory */
668
1.48k
    }
669
3.45k
    if (media->type) {
670
595
  newmedia->type = dsc_alloc_string(dsc, media->type, 
671
595
      strlen(media->type));
672
595
  if (newmedia->type == NULL)
673
0
      return CDSC_ERROR; /* no memory */
674
595
    }
675
3.45k
    newmedia->mediabox = NULL;
676
677
3.45k
    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
3.45k
    return CDSC_OK;
684
3.45k
}
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
54.7k
{
716
54.7k
    if (dsc->memalloc)
717
0
  return dsc->memalloc(size, dsc->mem_closure_data);
718
54.7k
    return malloc(size);
719
54.7k
}
720
721
dsc_private void
722
dsc_memfree(CDSC*dsc, void *ptr)
723
70.2k
{
724
70.2k
    if (dsc->memfree) 
725
0
  dsc->memfree(ptr, dsc->mem_closure_data);
726
70.2k
    else
727
70.2k
  free(ptr);
728
70.2k
}
729
730
/* private constructor */
731
dsc_private CDSC *
732
dsc_init2(CDSC *dsc)
733
14.9k
{
734
14.9k
    dsc_reset(dsc);
735
736
14.9k
    dsc->string_head = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
737
14.9k
    if (dsc->string_head == NULL) {
738
0
  dsc_free(dsc);
739
0
  return NULL; /* no memory */
740
0
    }
741
14.9k
    dsc->string = dsc->string_head;
742
14.9k
    dsc->string->next = NULL;
743
14.9k
    dsc->string->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
744
14.9k
    if (dsc->string->data == NULL) {
745
0
  dsc_free(dsc);
746
0
  return NULL; /* no memory */
747
0
    }
748
14.9k
    dsc->string->index = 0;
749
14.9k
    dsc->string->length = CDSC_STRING_CHUNK;
750
  
751
14.9k
    dsc->page = (CDSCPAGE *)dsc_memalloc(dsc, CDSC_PAGE_CHUNK * sizeof(CDSCPAGE));
752
14.9k
    if (dsc->page == NULL) {
753
0
  dsc_free(dsc);
754
0
  return NULL; /* no memory */
755
0
    }
756
14.9k
    dsc->page_chunk_length = CDSC_PAGE_CHUNK;
757
14.9k
    dsc->page_count = 0;
758
  
759
14.9k
    dsc->line = NULL;
760
14.9k
    dsc->data_length = 0;
761
14.9k
    dsc->data_index = dsc->data_length;
762
763
14.9k
    return dsc;
764
14.9k
}
765
766
767
dsc_private void 
768
dsc_reset(CDSC *dsc)
769
29.9k
{
770
29.9k
    unsigned int i;
771
    /* Clear public members */
772
29.9k
    dsc->dsc = FALSE;
773
29.9k
    dsc->ctrld = FALSE;
774
29.9k
    dsc->pjl = FALSE;
775
29.9k
    dsc->epsf = FALSE;
776
29.9k
    dsc->pdf = FALSE;
777
29.9k
    dsc->epsf = FALSE;
778
29.9k
    dsc->preview = CDSC_NOPREVIEW;
779
29.9k
    dsc->dsc_version = NULL; /* stored in dsc->string */
780
29.9k
    dsc->language_level = 0;
781
29.9k
    dsc->document_data = CDSC_DATA_UNKNOWN;
782
29.9k
    dsc->begincomments = 0;
783
29.9k
    dsc->endcomments = 0;
784
29.9k
    dsc->beginpreview = 0;
785
29.9k
    dsc->endpreview = 0;
786
29.9k
    dsc->begindefaults = 0;
787
29.9k
    dsc->enddefaults = 0;
788
29.9k
    dsc->beginprolog = 0;
789
29.9k
    dsc->endprolog = 0;
790
29.9k
    dsc->beginsetup = 0;
791
29.9k
    dsc->endsetup = 0;
792
29.9k
    dsc->begintrailer = 0;
793
29.9k
    dsc->endtrailer = 0;
794
  
795
38.2k
    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.29k
  if (dsc->page[i].bbox)
800
54
      dsc_memfree(dsc, dsc->page[i].bbox);
801
8.29k
  if (dsc->page[i].viewing_orientation)
802
256
      dsc_memfree(dsc, dsc->page[i].viewing_orientation);
803
8.29k
    }
804
29.9k
    if (dsc->page)
805
14.9k
  dsc_memfree(dsc, dsc->page);
806
29.9k
    dsc->page = NULL;
807
  
808
29.9k
    dsc->page_count = 0;
809
29.9k
    dsc->page_pages = 0;
810
29.9k
    dsc->page_order = CDSC_ORDER_UNKNOWN;
811
29.9k
    dsc->page_orientation = CDSC_ORIENT_UNKNOWN;
812
29.9k
    if (dsc->viewing_orientation)
813
57
  dsc_memfree(dsc, dsc->viewing_orientation);
814
29.9k
    dsc->viewing_orientation = NULL;
815
  
816
29.9k
    if (dsc->media) {
817
4.33k
  for (i=0; i<dsc->media_count; i++) {
818
3.45k
      if (dsc->media[i]) {
819
3.45k
    if (dsc->media[i]->mediabox)
820
0
        dsc_memfree(dsc, dsc->media[i]->mediabox);
821
3.45k
    dsc_memfree(dsc, dsc->media[i]);
822
3.45k
      }
823
3.45k
  }
824
886
  dsc_memfree(dsc, dsc->media);
825
886
    }
826
29.9k
    dsc->media_count = 0;
827
29.9k
    dsc->media = NULL;
828
829
    /* page_media is pointer to an element of media or dsc_known_media */
830
    /* do not free it. */
831
29.9k
    dsc->page_media = NULL;
832
833
29.9k
    if (dsc->bbox)
834
545
  dsc_memfree(dsc, dsc->bbox);
835
29.9k
    dsc->bbox = NULL;
836
29.9k
    if (dsc->page_bbox)
837
30
  dsc_memfree(dsc, dsc->page_bbox);
838
29.9k
    dsc->page_bbox = NULL;
839
29.9k
    if (dsc->doseps)
840
572
  dsc_memfree(dsc, dsc->doseps);
841
29.9k
    dsc->doseps = NULL;
842
  
843
29.9k
    dsc->dsc_title = NULL;
844
29.9k
    dsc->dsc_creator = NULL;
845
29.9k
    dsc->dsc_date = NULL;
846
29.9k
    dsc->dsc_for = NULL;
847
  
848
849
29.9k
    dsc->max_error = DSC_MAX_ERROR;
850
29.9k
    dsc->severity = dsc_severity;
851
852
    /* Clear private members */
853
    /* Don't touch dsc->caller_data */
854
29.9k
    dsc->id = CDSC_OK;
855
29.9k
    dsc->scan_section = scan_none;
856
29.9k
    dsc->doseps_end = 0;
857
29.9k
    dsc->page_chunk_length = 0;
858
29.9k
    dsc->file_length = 0;
859
29.9k
    dsc->skip_document = 0;
860
29.9k
    dsc->skip_bytes = 0;
861
29.9k
    dsc->skip_lines = 0;
862
29.9k
    dsc->skip_pjl = 0;
863
29.9k
    dsc->begin_font_count = 0;
864
29.9k
    dsc->begin_feature_count = 0;
865
29.9k
    dsc->begin_resource_count = 0;
866
29.9k
    dsc->begin_procset_count = 0;
867
868
29.9k
    dsc->data_length = 0;
869
29.9k
    dsc->data_index = 0;
870
29.9k
    dsc->data_offset = 0;
871
872
29.9k
    dsc->eof = 0;
873
  
874
29.9k
    dsc->line = 0;
875
29.9k
    dsc->line_length = 0;
876
29.9k
    dsc->eol = 0;
877
29.9k
    dsc->last_cr = FALSE;
878
29.9k
    dsc->line_count = 1;
879
29.9k
    dsc->long_line = FALSE;
880
29.9k
    memset(dsc->last_line, 0, sizeof(dsc->last_line));
881
882
29.9k
    dsc->string = dsc->string_head;
883
44.8k
    while (dsc->string != (CDSCSTRING *)NULL) {
884
14.9k
  if (dsc->string->data)
885
14.9k
      dsc_memfree(dsc, dsc->string->data);
886
14.9k
  dsc->string_head = dsc->string;
887
14.9k
  dsc->string = dsc->string->next;
888
14.9k
  dsc_memfree(dsc, dsc->string_head);
889
14.9k
    }
890
29.9k
    dsc->string_head = NULL;
891
29.9k
    dsc->string = NULL;
892
893
    /* don't touch caller functions */
894
895
    /* public data */
896
29.9k
    if (dsc->hires_bbox)
897
12
  dsc_memfree(dsc, dsc->hires_bbox);
898
29.9k
    dsc->hires_bbox = NULL;
899
29.9k
    if (dsc->crop_box)
900
200
  dsc_memfree(dsc, dsc->crop_box);
901
29.9k
    dsc->crop_box = NULL;
902
29.9k
}
903
904
/* 
905
* Join up all sections.
906
* There might be extra code between them, or we might have
907
* missed including the \n which followed \r.
908
* begin is the start of this section
909
* pend is a pointer to the end of this section
910
* pplast is a pointer to a pointer of the end of the previous section
911
*/
912
dsc_private void 
913
dsc_section_join(unsigned long begin, unsigned long *pend, unsigned long **pplast)
914
0
{
915
0
    if (begin)
916
0
  **pplast = begin;
917
0
    if (*pend > begin)
918
0
  *pplast = pend;
919
0
}
920
921
922
/* return value is 0 if no line available, or length of line */
923
dsc_private int
924
dsc_read_line(CDSC *dsc)
925
389k
{
926
389k
    char *p, *last;
927
389k
    dsc->line = NULL;
928
929
389k
    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
389k
    if (dsc->skip_bytes) {
939
16.3k
  int cnt = min(dsc->skip_bytes,
940
16.3k
         (int)(dsc->data_length - dsc->data_index));
941
16.3k
  dsc->skip_bytes -= cnt;
942
16.3k
  dsc->data_index += cnt;
943
16.3k
  if (dsc->skip_bytes != 0)
944
15.6k
      return 0;
945
16.3k
    }
946
947
374k
    do {
948
374k
  if (dsc->data_index >= dsc->data_length) {
949
72.3k
      dsc->line_length = 0;
950
72.3k
      return 0;
951
72.3k
  }
952
301k
  dsc->line = dsc->data + dsc->data_index;
953
301k
  last = dsc->data + dsc->data_length;
954
301k
  if (dsc->eol) {
955
      /* if previous line was complete, increment line count */
956
287k
      dsc->line_count++;
957
287k
      if (dsc->skip_lines)
958
0
    dsc->skip_lines--;
959
287k
  }
960
      
961
  /* skip over \n which followed \r */
962
301k
  if (dsc->last_cr && dsc->line[0] == '\n') {
963
160
      dsc->data_index++;
964
160
      dsc->line++;
965
160
  }
966
301k
  dsc->last_cr = FALSE;
967
968
  /* look for EOL */
969
301k
  dsc->eol = FALSE;
970
6.98M
  for (p = dsc->line; p < last; p++) {
971
6.97M
      if (*p == '\r') {
972
220k
    p++;
973
220k
    if ((p<last) && (*p == '\n'))
974
2.27k
        p++;  /* include line feed also */
975
218k
    else
976
218k
        dsc->last_cr = TRUE; /* we might need to skip \n */
977
220k
    dsc->eol = TRUE; /* dsc->line is a complete line */
978
220k
    break;
979
220k
      }
980
6.75M
      if (*p == '\n') {
981
69.7k
    p++;
982
69.7k
    dsc->eol = TRUE; /* dsc->line is a complete line */
983
69.7k
    break;
984
69.7k
      }
985
6.68M
      if (*p == '\032') {   /* MS-DOS Ctrl+Z */
986
16.9k
    dsc->eol = TRUE;
987
16.9k
      }
988
6.68M
  }
989
301k
  if (dsc->eol == FALSE) {
990
      /* we haven't got a complete line yet */
991
10.7k
      if (dsc->data_length - dsc->data_index < sizeof(dsc->data)/2) {
992
    /* buffer is less than half full, ask for some more */
993
10.6k
    dsc->line_length = 0;
994
10.6k
    return 0;
995
10.6k
      }
996
10.7k
  }
997
291k
  dsc->data_index += dsc->line_length = (p - dsc->line);
998
291k
    } while (dsc->skip_lines && dsc->line_length);
999
1000
291k
    if (dsc->line_length == 0)
1001
0
  return 0;
1002
  
1003
291k
    if ((dsc->line[0]=='%') && (dsc->line[1]=='%'))  {
1004
  /* handle recursive %%BeginDocument */
1005
126k
  if ((dsc->skip_document) && dsc->line_length &&
1006
1.68k
    COMPARE(dsc->line, "%%EndDocument")) {
1007
25
      dsc->skip_document--;
1008
25
  }
1009
1010
  /* handle embedded lines or binary data */
1011
126k
  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
924
      char begindata[MAXSTR+1];
1018
924
      int cnt;
1019
924
            unsigned int num;
1020
924
      const char *numberof, *bytesorlines;
1021
924
            if ((num = dsc->line_length) >= sizeof(begindata)-1)
1022
18
                num = sizeof(begindata)-1;
1023
 
1024
924
            memcpy(begindata, dsc->line, num);
1025
924
            begindata[num] = '\0';
1026
924
      numberof = strtok(begindata+12, " \r\n");
1027
924
      strtok(NULL, " \r\n"); /* dump type */
1028
924
      bytesorlines = strtok(NULL, " \r\n");
1029
924
      if (bytesorlines == NULL)
1030
855
    bytesorlines = "Bytes";
1031
     
1032
924
      if ( (numberof == NULL) || (bytesorlines == NULL) ) {
1033
    /* invalid usage of %%BeginData */
1034
    /* ignore that we ever saw it */
1035
580
    int rc = dsc_error(dsc, CDSC_MESSAGE_INCORRECT_USAGE, 
1036
580
          dsc->line, dsc->line_length);
1037
580
    switch (rc) {
1038
0
        case CDSC_RESPONSE_OK:
1039
580
        case CDSC_RESPONSE_CANCEL:
1040
580
      break;
1041
0
        case CDSC_RESPONSE_IGNORE_ALL:
1042
0
      return 0;
1043
580
    }
1044
580
      }
1045
344
      else {
1046
344
    cnt = atoi(numberof);
1047
344
    if (cnt) {
1048
129
        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
129
        else {
1056
      /* byte count doesn't includes \n or \r\n  */
1057
      /* or \r of %%BeginData: */
1058
      /* skip cnt bytes */
1059
129
      if (dsc->skip_bytes == 0) {
1060
          /* we are not already skipping lines */
1061
129
          dsc->skip_bytes = cnt;
1062
129
      }
1063
1064
129
        }
1065
129
    }
1066
344
      }
1067
924
  }
1068
126k
  else if (COMPARE(dsc->line, "%%BeginBinary:")) {
1069
      /* byte count doesn't includes \n or \r\n or \r of %%BeginBinary:*/
1070
673
      unsigned long cnt = atoi(dsc->line + 14);
1071
673
      if (dsc->skip_bytes == 0) {
1072
    /* we are not already skipping lines */
1073
673
    dsc->skip_bytes = cnt;
1074
673
      }
1075
673
  }
1076
126k
    }
1077
  
1078
291k
    if ((dsc->line[0]=='%') && (dsc->line[1]=='%') &&
1079
126k
  COMPARE(dsc->line, "%%BeginDocument:") ) {
1080
  /* Skip over embedded document, recursively */
1081
478
  dsc->skip_document++;
1082
478
    }
1083
1084
291k
    if (!dsc->long_line && (dsc->line_length > DSC_LINE_LENGTH)) {
1085
1.69k
  dsc_error(dsc, CDSC_MESSAGE_LONG_LINE, dsc->line, dsc->line_length);
1086
1.69k
        dsc->long_line = TRUE;
1087
1.69k
    }
1088
  
1089
291k
    return dsc->line_length;
1090
291k
}
1091
1092
1093
/* Save last DSC line, for use with %%+ */
1094
dsc_private void 
1095
dsc_save_line(CDSC *dsc)
1096
63.4k
{
1097
63.4k
    int len = min(sizeof(dsc->last_line), dsc->line_length);
1098
63.4k
    memcpy(dsc->last_line, dsc->line, len);
1099
63.4k
}
1100
1101
/* display unknown DSC line */
1102
dsc_private void 
1103
dsc_unknown(CDSC *dsc)
1104
81.1k
{
1105
81.1k
    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
81.1k
}
1116
1117
1118
dsc_private GSBOOL
1119
dsc_is_section(char *line)
1120
125k
{
1121
125k
    if ( !((line[0]=='%') && (line[1]=='%')) )
1122
25.0k
  return FALSE;
1123
100k
    if (IS_DSC(line, "%%BeginPreview"))
1124
634
  return TRUE;
1125
99.9k
    if (IS_DSC(line, "%%BeginDefaults"))
1126
1.00k
  return TRUE;
1127
98.9k
    if (IS_DSC(line, "%%BeginProlog"))
1128
90
  return TRUE;
1129
98.8k
    if (IS_DSC(line, "%%BeginSetup"))
1130
1.83k
  return TRUE;
1131
97.0k
    if (IS_DSC(line, "%%Page:"))
1132
4.41k
  return TRUE;
1133
92.6k
    if (IS_DSC(line, "%%Trailer"))
1134
1.44k
  return TRUE;
1135
91.1k
    if (IS_DSC(line, "%%EOF"))
1136
1.76k
  return TRUE;
1137
89.4k
    return FALSE;
1138
91.1k
}
1139
1140
1141
dsc_private GSDWORD
1142
dsc_get_dword(const unsigned char *buf)
1143
7.37k
{
1144
7.37k
    GSDWORD dw;
1145
7.37k
    dw = (GSDWORD)buf[0];
1146
7.37k
    dw += ((GSDWORD)buf[1])<<8;
1147
7.37k
    dw += ((GSDWORD)buf[2])<<16;
1148
7.37k
    dw += ((GSDWORD)buf[3])<<24;
1149
7.37k
    return dw;
1150
7.37k
}
1151
1152
dsc_private GSWORD
1153
dsc_get_word(const unsigned char *buf)
1154
1.22k
{
1155
1.22k
    GSWORD w;
1156
1.22k
    w = (GSWORD)buf[0];
1157
1.22k
    w |= (GSWORD)(buf[1]<<8);
1158
1.22k
    return w;
1159
1.22k
}
1160
1161
dsc_private int
1162
dsc_read_doseps(CDSC *dsc)
1163
1.22k
{
1164
1.22k
    unsigned char *line = (unsigned char *)dsc->line;
1165
1.22k
    dsc_memfree(dsc, dsc->doseps);
1166
1.22k
    if ((dsc->doseps = (CDSCDOSEPS *)dsc_memalloc(dsc, sizeof(CDSCDOSEPS))) == NULL)
1167
0
  return CDSC_ERROR; /* no memory */
1168
  
1169
1.22k
    dsc->doseps->ps_begin = dsc_get_dword(line+4);
1170
1.22k
    dsc->doseps->ps_length = dsc_get_dword(line+8);
1171
1.22k
    dsc->doseps->wmf_begin = dsc_get_dword(line+12);
1172
1.22k
    dsc->doseps->wmf_length = dsc_get_dword(line+16);
1173
1.22k
    dsc->doseps->tiff_begin = dsc_get_dword(line+20);
1174
1.22k
    dsc->doseps->tiff_length = dsc_get_dword(line+24);
1175
1.22k
    dsc->doseps->checksum = dsc_get_word(line+28);
1176
  
1177
1.22k
    dsc->doseps_end = dsc->doseps->ps_begin + dsc->doseps->ps_length;
1178
1179
    /* move data_index backwards to byte after doseps header */
1180
1.22k
    dsc->data_index -= dsc->line_length - 30;
1181
    /* we haven't read a line of PostScript code yet */
1182
1.22k
    dsc->line_count = 0;
1183
    /* skip from current position to start of PostScript section */
1184
1.22k
    dsc->skip_bytes = dsc->doseps->ps_begin - 30;
1185
1186
1.22k
    if (dsc->doseps->tiff_begin)
1187
1.08k
  dsc->preview = CDSC_TIFF;
1188
1.22k
    if (dsc->doseps->wmf_begin)
1189
1.10k
  dsc->preview = CDSC_WMF;
1190
1191
1.22k
    return CDSC_OK;
1192
1.22k
}
1193
1194
1195
1196
dsc_private int 
1197
dsc_parse_pages(CDSC *dsc)
1198
3.79k
{
1199
3.79k
    int ip, io; 
1200
3.79k
    unsigned int i;
1201
3.79k
    char *p;
1202
3.79k
    int n;
1203
3.79k
    if ((dsc->page_pages != 0) && (dsc->scan_section == scan_comments)) {
1204
247
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1205
247
    dsc->line_length);
1206
247
  switch (rc) {
1207
0
      case CDSC_RESPONSE_OK:
1208
247
      case CDSC_RESPONSE_CANCEL:
1209
247
    return CDSC_OK; /* ignore duplicate comments in header */
1210
0
      case CDSC_RESPONSE_IGNORE_ALL:
1211
0
    return CDSC_NOTDSC;
1212
247
  }
1213
247
    }
1214
3.54k
    if ((dsc->page_pages != 0) && (dsc->scan_section == scan_trailer)) {
1215
540
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1216
540
    dsc->line_length);
1217
540
  switch (rc) {
1218
0
      case CDSC_RESPONSE_OK:
1219
540
      case CDSC_RESPONSE_CANCEL:
1220
540
    break;   /* use duplicate comments in header */
1221
0
      case CDSC_RESPONSE_IGNORE_ALL:
1222
0
    return CDSC_NOTDSC;
1223
540
  }
1224
540
    }
1225
1226
3.54k
    n = IS_DSC(dsc->line, "%%+") ? 3 : 8;
1227
19.0k
    while (IS_WHITE(dsc->line[n]))
1228
15.5k
  n++;
1229
3.54k
    p = dsc->line + n;
1230
3.54k
    if (COMPARE(p, "atend")) {
1231
444
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, dsc->line_length);
1232
444
  switch (rc) {
1233
0
      case CDSC_RESPONSE_OK:
1234
    /* assume (atend) */
1235
    /* we should mark it as deferred */
1236
0
    break;
1237
444
      case CDSC_RESPONSE_CANCEL:
1238
    /* ignore it */
1239
444
    break;
1240
0
      case CDSC_RESPONSE_IGNORE_ALL:
1241
0
    return CDSC_NOTDSC;
1242
444
  }
1243
444
    }
1244
3.10k
    else if (COMPARE(p, "(atend)")) {
1245
  /* do nothing */
1246
  /* we should mark it as deferred */
1247
199
    }
1248
2.90k
    else {
1249
2.90k
  ip = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1250
2.90k
        if (i) {
1251
1.08k
      n+=i;
1252
1.08k
      dsc->page_pages = ip;
1253
1.08k
      io = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1254
1.08k
      if (i) {
1255
    /* DSC 2 uses extra integer to indicate page order */
1256
    /* DSC 3 uses %%PageOrder: */
1257
603
    if (dsc->page_order == CDSC_ORDER_UNKNOWN)
1258
461
        switch (io) {
1259
14
      case -1:
1260
14
          dsc->page_order = CDSC_DESCEND;
1261
14
          break;
1262
105
      case 0:
1263
105
          dsc->page_order = CDSC_SPECIAL;
1264
105
          break;
1265
39
      case 1:
1266
39
          dsc->page_order = CDSC_ASCEND;
1267
39
          break;
1268
461
        }
1269
603
      }
1270
1.08k
  }
1271
1.82k
  else {
1272
1.82k
      int rc = dsc_error(dsc, CDSC_MESSAGE_INCORRECT_USAGE, dsc->line, 
1273
1.82k
    dsc->line_length);
1274
1.82k
      switch (rc) {
1275
0
    case CDSC_RESPONSE_OK:
1276
1.82k
    case CDSC_RESPONSE_CANCEL:
1277
        /* ignore it */
1278
1.82k
        break;
1279
0
    case CDSC_RESPONSE_IGNORE_ALL:
1280
0
        return CDSC_NOTDSC;
1281
1.82k
      }
1282
1.82k
  }
1283
2.90k
    }
1284
3.54k
    return CDSC_OK;
1285
3.54k
}
1286
1287
dsc_private int 
1288
dsc_parse_bounding_box(CDSC *dsc, CDSCBBOX** pbbox, int offset)
1289
5.60k
{
1290
5.60k
    unsigned int i, n;
1291
5.60k
    int llx, lly, urx, ury;
1292
5.60k
    float fllx, flly, furx, fury;
1293
5.60k
    char *p;
1294
    /* Process first %%BoundingBox: in comments, and last in trailer */
1295
5.60k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_comments)) {
1296
284
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1297
284
    dsc->line_length);
1298
284
  switch (rc) {
1299
0
      case CDSC_RESPONSE_OK:
1300
284
      case CDSC_RESPONSE_CANCEL:
1301
284
    return CDSC_OK; /* ignore duplicate comments in header */
1302
0
      case CDSC_RESPONSE_IGNORE_ALL:
1303
0
    return CDSC_NOTDSC;
1304
284
  }
1305
284
    }
1306
5.31k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_pages)) {
1307
70
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1308
70
    dsc->line_length);
1309
70
  switch (rc) {
1310
0
      case CDSC_RESPONSE_OK:
1311
70
      case CDSC_RESPONSE_CANCEL:
1312
70
    return CDSC_OK; /* ignore duplicate comments in header */
1313
0
      case CDSC_RESPONSE_IGNORE_ALL:
1314
0
    return CDSC_NOTDSC;
1315
70
  }
1316
70
    }
1317
5.24k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_trailer)) {
1318
105
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1319
105
    dsc->line_length);
1320
105
  switch (rc) {
1321
0
      case CDSC_RESPONSE_OK:
1322
105
      case CDSC_RESPONSE_CANCEL:
1323
105
    break;   /* use duplicate comments in trailer */
1324
0
      case CDSC_RESPONSE_IGNORE_ALL:
1325
0
    return CDSC_NOTDSC;
1326
105
  }
1327
105
    }
1328
5.24k
    if (*pbbox != NULL) {
1329
175
  dsc_memfree(dsc, *pbbox);
1330
175
  *pbbox = NULL;
1331
175
    }
1332
1333
    /* should only process first %%BoundingBox: */
1334
1335
6.80k
    while (IS_WHITE(dsc->line[offset]))
1336
1.55k
  offset++;
1337
5.24k
    p = dsc->line + offset;
1338
    
1339
5.24k
    if (COMPARE(p, "atend")) {
1340
362
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, 
1341
362
    dsc->line_length);
1342
362
  switch (rc) {
1343
0
      case CDSC_RESPONSE_OK:
1344
    /* assume (atend) */
1345
    /* we should mark it as deferred */
1346
0
    break;
1347
362
      case CDSC_RESPONSE_CANCEL:
1348
    /* ignore it */
1349
362
    break;
1350
0
      case CDSC_RESPONSE_IGNORE_ALL:
1351
0
    return CDSC_NOTDSC;
1352
362
  }
1353
362
    }
1354
4.88k
    else if (COMPARE(p, "(atend)")) {
1355
  /* do nothing */
1356
  /* we should mark it as deferred */
1357
206
    }
1358
4.68k
    else {
1359
4.68k
        /* llx = */ lly = urx = ury = 0;
1360
4.68k
  n = offset;
1361
4.68k
  llx = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1362
4.68k
  n += i;
1363
4.68k
  if (i)
1364
2.04k
      lly = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1365
4.68k
  n += i;
1366
4.68k
  if (i)
1367
1.40k
      urx = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1368
4.68k
  n += i;
1369
4.68k
  if (i)
1370
1.14k
      ury = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
1371
4.68k
  if (i) {
1372
804
      *pbbox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
1373
804
      if (*pbbox == NULL)
1374
0
    return CDSC_ERROR; /* no memory */
1375
804
      (*pbbox)->llx = llx;
1376
804
      (*pbbox)->lly = lly;
1377
804
      (*pbbox)->urx = urx;
1378
804
      (*pbbox)->ury = ury;
1379
804
  }
1380
3.87k
  else {
1381
3.87k
      int rc = dsc_error(dsc, CDSC_MESSAGE_BBOX, dsc->line, 
1382
3.87k
    dsc->line_length);
1383
3.87k
      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
3.87k
      case CDSC_RESPONSE_CANCEL:
1410
3.87k
    return CDSC_OK;
1411
0
      case CDSC_RESPONSE_IGNORE_ALL:
1412
0
    return CDSC_NOTDSC;
1413
3.87k
    }
1414
3.87k
  }
1415
4.68k
    }
1416
1.37k
    return CDSC_OK;
1417
5.24k
}
1418
1419
dsc_private int 
1420
dsc_parse_float_bounding_box(CDSC *dsc, CDSCFBBOX** pbbox, int offset)
1421
4.74k
{
1422
4.74k
    unsigned int i, n;
1423
4.74k
    float fllx, flly, furx, fury;
1424
4.74k
    char *p;
1425
    /* Process first %%HiResBoundingBox: or %%CropBox: in comments, 
1426
     * and last in trailer.
1427
     */
1428
4.74k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_comments)) {
1429
247
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1430
247
    dsc->line_length);
1431
247
  switch (rc) {
1432
0
      case CDSC_RESPONSE_OK:
1433
247
      case CDSC_RESPONSE_CANCEL:
1434
247
    return CDSC_OK; /* ignore duplicate comments in header */
1435
0
      case CDSC_RESPONSE_IGNORE_ALL:
1436
0
    return CDSC_NOTDSC;
1437
247
  }
1438
247
    }
1439
4.49k
    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.49k
    if ((*pbbox != NULL) && (dsc->scan_section == scan_trailer)) {
1451
118
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1452
118
    dsc->line_length);
1453
118
  switch (rc) {
1454
0
      case CDSC_RESPONSE_OK:
1455
118
      case CDSC_RESPONSE_CANCEL:
1456
118
    break;   /* use duplicate comments in trailer */
1457
0
      case CDSC_RESPONSE_IGNORE_ALL:
1458
0
    return CDSC_NOTDSC;
1459
118
  }
1460
118
    }
1461
4.49k
    if (*pbbox != NULL) {
1462
118
  dsc_memfree(dsc, *pbbox);
1463
118
  *pbbox = NULL;
1464
118
    }
1465
1466
    /* should only process first %%BoundingBox: */
1467
1468
5.78k
    while (IS_WHITE(dsc->line[offset]))
1469
1.29k
  offset++;
1470
4.49k
    p = dsc->line + offset;
1471
    
1472
4.49k
    if (COMPARE(p, "atend")) {
1473
124
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, 
1474
124
    dsc->line_length);
1475
124
  switch (rc) {
1476
0
      case CDSC_RESPONSE_OK:
1477
    /* assume (atend) */
1478
    /* we should mark it as deferred */
1479
0
    break;
1480
124
      case CDSC_RESPONSE_CANCEL:
1481
    /* ignore it */
1482
124
    break;
1483
0
      case CDSC_RESPONSE_IGNORE_ALL:
1484
0
    return CDSC_NOTDSC;
1485
124
  }
1486
124
    }
1487
4.37k
    else if (COMPARE(p, "(atend)")) {
1488
  /* do nothing */
1489
  /* we should mark it as deferred */
1490
386
    }
1491
3.98k
    else {
1492
3.98k
  /* fllx = */ flly = furx = fury = 0.0;
1493
3.98k
  n = offset;
1494
3.98k
  fllx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1495
3.98k
  n += i;
1496
3.98k
  if (i)
1497
1.71k
      flly = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1498
3.98k
  n += i;
1499
3.98k
  if (i)
1500
1.14k
      furx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1501
3.98k
  n += i;
1502
3.98k
  if (i)
1503
763
      fury = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1504
3.98k
  if (i) {
1505
330
      *pbbox = (CDSCFBBOX *)dsc_memalloc(dsc, sizeof(CDSCFBBOX));
1506
330
      if (*pbbox == NULL)
1507
0
    return CDSC_ERROR; /* no memory */
1508
330
      (*pbbox)->fllx = fllx;
1509
330
      (*pbbox)->flly = flly;
1510
330
      (*pbbox)->furx = furx;
1511
330
      (*pbbox)->fury = fury;
1512
330
  }
1513
3.98k
    }
1514
4.49k
    return CDSC_OK;
1515
4.49k
}
1516
1517
dsc_private int 
1518
dsc_parse_orientation(CDSC *dsc, unsigned int *porientation, int offset)
1519
3.09k
{
1520
3.09k
    char *p;
1521
3.09k
    if ((dsc->page_orientation != CDSC_ORIENT_UNKNOWN) && 
1522
742
  (dsc->scan_section == scan_comments)) {
1523
77
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1524
77
    dsc->line_length);
1525
77
  switch (rc) {
1526
0
      case CDSC_RESPONSE_OK:
1527
77
      case CDSC_RESPONSE_CANCEL:
1528
77
    return CDSC_OK; /* ignore duplicate comments in header */
1529
0
      case CDSC_RESPONSE_IGNORE_ALL:
1530
0
    return CDSC_NOTDSC;
1531
77
  }
1532
77
    }
1533
3.02k
    if ((dsc->page_orientation != CDSC_ORIENT_UNKNOWN) && 
1534
665
  (dsc->scan_section == scan_trailer)) {
1535
262
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1536
262
    dsc->line_length);
1537
262
  switch (rc) {
1538
0
      case CDSC_RESPONSE_OK:
1539
262
      case CDSC_RESPONSE_CANCEL:
1540
262
    break;   /* use duplicate comments in header; */
1541
0
      case CDSC_RESPONSE_IGNORE_ALL:
1542
0
    return CDSC_NOTDSC;
1543
262
  }
1544
262
    }
1545
3.02k
    p = dsc->line + offset;
1546
3.54k
    while (IS_WHITE(*p))
1547
520
  p++;
1548
3.02k
    if (COMPARE(p, "atend")) {
1549
424
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, dsc->line_length);
1550
424
  switch (rc) {
1551
0
      case CDSC_RESPONSE_OK:
1552
    /* assume (atend) */
1553
    /* we should mark it as deferred */
1554
0
    break;
1555
424
      case CDSC_RESPONSE_CANCEL:
1556
    /* ignore it */
1557
424
    break;
1558
0
      case CDSC_RESPONSE_IGNORE_ALL:
1559
0
    return CDSC_NOTDSC;
1560
424
  }
1561
424
    }
1562
2.59k
    else if (COMPARE(p, "(atend)")) {
1563
  /* do nothing */
1564
  /* we should mark it as deferred */
1565
187
    }
1566
2.41k
    else if (COMPARE(p, "Portrait")) {
1567
131
  *porientation = CDSC_PORTRAIT;
1568
131
    }
1569
2.27k
    else if (COMPARE(p, "Landscape")) {
1570
768
  *porientation = CDSC_LANDSCAPE;
1571
768
    }
1572
1.51k
    else {
1573
1.51k
  dsc_unknown(dsc);
1574
1.51k
    }
1575
3.02k
    return CDSC_OK;
1576
3.02k
}
1577
1578
dsc_private int 
1579
dsc_parse_order(CDSC *dsc)
1580
2.12k
{
1581
2.12k
    char *p;
1582
2.12k
    if ((dsc->page_order != CDSC_ORDER_UNKNOWN) && 
1583
839
  (dsc->scan_section == scan_comments)) {
1584
264
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line, 
1585
264
    dsc->line_length);
1586
264
  switch (rc) {
1587
0
      case CDSC_RESPONSE_OK:
1588
264
      case CDSC_RESPONSE_CANCEL:
1589
264
    return CDSC_OK; /* ignore duplicate comments in header */
1590
0
      case CDSC_RESPONSE_IGNORE_ALL:
1591
0
    return CDSC_NOTDSC;
1592
264
  }
1593
264
    }
1594
1.86k
    if ((dsc->page_order != CDSC_ORDER_UNKNOWN) && 
1595
575
  (dsc->scan_section == scan_trailer)) {
1596
575
  int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
1597
575
    dsc->line_length);
1598
575
  switch (rc) {
1599
0
      case CDSC_RESPONSE_OK:
1600
575
      case CDSC_RESPONSE_CANCEL:
1601
575
    break;   /* use duplicate comments in trailer */
1602
0
      case CDSC_RESPONSE_IGNORE_ALL:
1603
0
    return CDSC_NOTDSC;
1604
575
  }
1605
575
    }
1606
1607
1.86k
    p = dsc->line + (IS_DSC(dsc->line, "%%+") ? 3 : 13);
1608
3.22k
    while (IS_WHITE(*p))
1609
1.36k
  p++;
1610
1.86k
    if (COMPARE(p, "atend")) {
1611
289
  int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, 
1612
289
    dsc->line_length);
1613
289
  switch (rc) {
1614
0
      case CDSC_RESPONSE_OK:
1615
    /* assume (atend) */
1616
    /* we should mark it as deferred */
1617
0
    break;
1618
289
      case CDSC_RESPONSE_CANCEL:
1619
    /* ignore it */
1620
289
    break;
1621
0
      case CDSC_RESPONSE_IGNORE_ALL:
1622
0
    return CDSC_NOTDSC;
1623
289
  }
1624
289
    }
1625
1.57k
    else if (COMPARE(p, "(atend)")) {
1626
  /* do nothing */
1627
  /* we should mark it as deferred */
1628
90
    }
1629
1.48k
    else if (COMPARE(p, "Ascend")) {
1630
126
  dsc->page_order = CDSC_ASCEND;
1631
126
    }
1632
1.35k
    else if (COMPARE(p, "Descend")) {
1633
255
  dsc->page_order = CDSC_DESCEND;
1634
255
    }
1635
1.10k
    else if (COMPARE(p, "Special")) {
1636
105
  dsc->page_order = CDSC_SPECIAL;
1637
105
    }
1638
996
    else {
1639
996
  dsc_unknown(dsc);
1640
996
    }
1641
1.86k
    return CDSC_OK;
1642
1.86k
}
1643
1644
1645
dsc_private int 
1646
dsc_parse_media(CDSC *dsc, const CDSCMEDIA **page_media)
1647
955
{
1648
955
    char media_name[MAXSTR];
1649
955
    int n = IS_DSC(dsc->line, "%%+") ? 3 : 12; /* %%PageMedia: */
1650
955
    unsigned int i;
1651
1652
955
    if (dsc_copy_string(media_name, sizeof(media_name)-1,
1653
955
  dsc->line+n, dsc->line_length-n, NULL)) {
1654
2.98k
  for (i=0; i<dsc->media_count; i++) {
1655
2.17k
      if (dsc->media[i]->name && 
1656
1.03k
    (dsc_stricmp(media_name, dsc->media[i]->name) == 0)) {
1657
145
    *page_media = dsc->media[i];
1658
145
    return CDSC_OK;
1659
145
      }
1660
2.17k
  }
1661
955
    }
1662
810
    dsc_unknown(dsc);
1663
    
1664
810
    return CDSC_OK;
1665
955
}
1666
1667
1668
dsc_private int 
1669
dsc_parse_document_media(CDSC *dsc)
1670
2.31k
{
1671
2.31k
    unsigned int i, n;
1672
2.31k
    CDSCMEDIA lmedia;
1673
2.31k
    GSBOOL blank_line;
1674
1675
2.31k
    if (IS_DSC(dsc->line, "%%DocumentMedia:"))
1676
1.74k
  n = 16;
1677
573
    else if (IS_DSC(dsc->line, "%%+"))
1678
573
  n = 3;
1679
0
    else
1680
0
  return CDSC_ERROR; /* error */
1681
1682
    /* check for blank remainder of line */
1683
2.31k
    blank_line = TRUE;
1684
3.48k
    for (i=n; i<dsc->line_length; i++) {
1685
3.25k
  if (!IS_WHITE_OR_EOL(dsc->line[i])) {
1686
2.08k
      blank_line = FALSE;
1687
2.08k
      break;
1688
2.08k
  }
1689
3.25k
    }
1690
1691
2.31k
    if (!blank_line) {
1692
2.08k
  char name[MAXSTR];
1693
2.08k
  char colour[MAXSTR];
1694
2.08k
  char type[MAXSTR];
1695
2.08k
  lmedia.name = lmedia.colour = lmedia.type = (char *)NULL;
1696
2.08k
  lmedia.width = lmedia.height = lmedia.weight = 0;
1697
2.08k
  lmedia.mediabox = (CDSCBBOX *)NULL;
1698
2.08k
  lmedia.name = dsc_copy_string(name, sizeof(name)-1,
1699
2.08k
    dsc->line+n, dsc->line_length-n, &i);
1700
2.08k
  n+=i;
1701
2.08k
  if (i)
1702
2.08k
      lmedia.width = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1703
2.08k
  n+=i;
1704
2.08k
  if (i)
1705
903
      lmedia.height = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1706
2.08k
  n+=i;
1707
2.08k
  if (i)
1708
538
      lmedia.weight = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1709
2.08k
  n+=i;
1710
2.08k
  if (i)
1711
240
      lmedia.colour = dsc_copy_string(colour, sizeof(colour)-1,
1712
240
    dsc->line+n, dsc->line_length-n, &i);
1713
2.08k
  n+=i;
1714
2.08k
  if (i)
1715
240
      lmedia.type = dsc_copy_string(type, sizeof(type)-1,
1716
240
    dsc->line+n, dsc->line_length-n, &i);
1717
1718
2.08k
  if (i==0)
1719
1.96k
      dsc_unknown(dsc); /* we didn't get all fields */
1720
125
  else {
1721
125
      if (dsc_add_media(dsc, &lmedia))
1722
0
    return CDSC_ERROR; /* out of memory */
1723
125
  }
1724
2.08k
    }
1725
2.31k
    return CDSC_OK;
1726
2.31k
}
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.57k
{
1734
1.57k
    CDSCCTM ctm;
1735
1.57k
    unsigned int i, n;
1736
1737
1.57k
    if (*pctm != NULL) {
1738
236
  dsc_memfree(dsc, *pctm);
1739
236
  *pctm = NULL;
1740
236
    }
1741
1742
1.57k
    n = IS_DSC(dsc->line, "%%+") ? 3 : 21;  /* %%ViewingOrientation: */
1743
8.63k
    while (IS_WHITE(dsc->line[n]))
1744
7.06k
  n++;
1745
1746
    /* ctm.xx = */ ctm.xy = ctm.yx = ctm.yy = 0.0;
1747
1.57k
    ctm.xx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1748
1.57k
    n += i;
1749
1.57k
    if (i)
1750
1.40k
        ctm.xy = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1751
1.57k
    n += i;
1752
1.57k
    if (i)
1753
1.20k
        ctm.yx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1754
1.57k
    n += i;
1755
1.57k
    if (i)
1756
863
        ctm.yy = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
1757
1.57k
    if (i==0) {
1758
1.02k
  dsc_unknown(dsc); /* we didn't get all fields */
1759
1.02k
    }
1760
549
    else {
1761
549
  *pctm = (CDSCCTM *)dsc_memalloc(dsc, sizeof(CDSCCTM));
1762
549
  if (*pctm == NULL)
1763
0
      return CDSC_ERROR; /* no memory */
1764
549
  **pctm = ctm;
1765
549
    }
1766
1.57k
    return CDSC_OK;
1767
1.57k
}
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
56.4k
{
1777
56.4k
    if (dsc->data_index > dsc->data_length)
1778
0
  return CDSC_NOTDSC;
1779
1780
56.4k
    unsigned char *p;
1781
56.4k
    unsigned char *line = (unsigned char *)(dsc->data + dsc->data_index);
1782
56.4k
    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
56.4k
    if (length == 0)
1798
1
  return CDSC_NEEDMORE;
1799
1800
56.4k
    if (dsc->skip_pjl) {
1801
  /* skip until first PostScript comment */
1802
5.20k
  while (length >= 2) {
1803
19.2k
      while (length && !IS_EOL(line[0])) {
1804
    /* skip until EOL character */
1805
14.1k
    line++;
1806
14.1k
    dsc->data_index++;
1807
14.1k
    length--;
1808
14.1k
      }
1809
15.4k
      while ((length >= 2) && IS_EOL(line[0]) && IS_EOL(line[1])) {
1810
    /* skip until EOL followed by non-EOL */
1811
10.3k
    line++;
1812
10.3k
    dsc->data_index++;
1813
10.3k
    length--;
1814
10.3k
      }
1815
5.16k
      if (length < 2)
1816
3.30k
    return CDSC_NEEDMORE;
1817
1818
1.86k
      if (IS_EOL(line[0]) && line[1]=='%') {
1819
61
    line++;
1820
61
    dsc->data_index++;
1821
61
    length--;
1822
61
    dsc->skip_pjl = FALSE;
1823
61
    break;
1824
61
      }
1825
1.79k
      else {
1826
    /* line++; */
1827
1.79k
    dsc->data_index++;
1828
    /* length--; */
1829
1.79k
    return CDSC_NEEDMORE;
1830
1.79k
      }
1831
1.86k
  }
1832
101
  if (dsc->skip_pjl)
1833
40
      return CDSC_NEEDMORE;
1834
101
    }
1835
1836
51.3k
    if (length == 0)
1837
0
  return CDSC_NEEDMORE;
1838
1839
51.3k
    if (line[0] == '\004') {
1840
170
  line++;
1841
170
  dsc->data_index++;
1842
170
  length--;
1843
170
  dsc->ctrld = TRUE;
1844
170
    }
1845
1846
51.3k
    if (line[0] == '\033') {
1847
  /* possibly PJL */
1848
1.44k
  if (length < 9)
1849
942
      return CDSC_NEEDMORE;
1850
502
  if (COMPARE(line, "\033%-12345X")) {
1851
189
      dsc->skip_pjl = TRUE;  /* skip until first PostScript comment */
1852
189
      dsc->pjl = TRUE;
1853
189
      dsc->data_index += 9;
1854
189
      return dsc_scan_type(dsc);
1855
189
  }
1856
502
    }
1857
1858
50.2k
    if ((line[0]==0xc5) && (length < 4))
1859
1.12k
  return CDSC_NEEDMORE;
1860
49.0k
    if ((line[0]==0xc5) && (line[1]==0xd0) && 
1861
11.0k
   (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
10.5k
  if (length < 30)
1865
9.28k
      return CDSC_NEEDMORE;
1866
1.22k
  dsc->line = (char *)line;
1867
1.22k
  if (dsc_read_doseps(dsc))
1868
0
      return CDSC_ERROR;
1869
1.22k
    }
1870
38.5k
    else {
1871
38.5k
  if (length < 2)
1872
9.95k
      return CDSC_NEEDMORE;
1873
28.6k
  if ((line[0] == '%') && (line[1] == 'P')) {
1874
4.40k
      if (length < 5)
1875
92
          return CDSC_NEEDMORE;
1876
4.31k
      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.31k
  }
1882
28.6k
    }
1883
1884
    /* Finally process PostScript headers */
1885
1886
25.6k
    if (dsc_read_line(dsc) <= 0)
1887
15.7k
  return CDSC_NEEDMORE;
1888
  
1889
9.84k
    dsc->dsc_version = dsc_add_line(dsc, dsc->line, dsc->line_length);
1890
9.84k
    if (COMPARE(dsc->line, "%!PS-Adobe")) {
1891
9.26k
  dsc->dsc = TRUE;
1892
9.26k
  dsc->begincomments = DSC_START(dsc);
1893
9.26k
  if (dsc->dsc_version == NULL)
1894
9
      return CDSC_ERROR;  /* no memory */
1895
9.25k
  p = (unsigned char *)dsc->line + 14;
1896
10.2k
  while (IS_WHITE(*p))
1897
1.02k
      p++;
1898
9.25k
  if (COMPARE(p, "EPSF-"))
1899
6
      dsc->epsf = TRUE;
1900
9.25k
  dsc->scan_section = scan_comments;
1901
9.25k
  return CDSC_PSADOBE;
1902
9.26k
    }
1903
578
    if (COMPARE(dsc->line, "%!")) {
1904
143
  dsc->scan_section = scan_comments;
1905
143
  return CDSC_NOTDSC;
1906
143
    }
1907
1908
435
    dsc->scan_section = scan_comments;
1909
435
    return CDSC_NOTDSC; /* unrecognised */
1910
578
}
1911
1912
1913
1914
dsc_private int 
1915
dsc_scan_comments(CDSC *dsc)
1916
54.7k
{
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
54.7k
    char *line = dsc->line;
1924
54.7k
    GSBOOL continued = FALSE;
1925
54.7k
    dsc->id = CDSC_OK;
1926
54.7k
    if (IS_DSC(line, "%%EndComments")) {
1927
14
  dsc->id = CDSC_ENDCOMMENTS;
1928
14
  dsc->endcomments = DSC_END(dsc);
1929
14
  dsc->scan_section = scan_pre_preview;
1930
14
  return CDSC_OK;
1931
14
    }
1932
54.7k
    else if (IS_DSC(line, "%%BeginComments")) {
1933
  /* ignore because we are in this section */
1934
132
  dsc->id = CDSC_BEGINCOMMENTS;
1935
132
    }
1936
54.5k
    else if (dsc_is_section(line)) {
1937
4.32k
  dsc->endcomments = DSC_START(dsc);
1938
4.32k
  dsc->scan_section = scan_pre_preview;
1939
4.32k
  return CDSC_PROPAGATE;
1940
4.32k
    }
1941
50.2k
    else if (line[0] == '%' && IS_WHITE_OR_EOL(line[1])) {
1942
223
  dsc->endcomments = DSC_START(dsc);
1943
223
  dsc->scan_section = scan_pre_preview;
1944
223
  return CDSC_PROPAGATE;
1945
223
    }
1946
50.0k
    else if (line[0] != '%') {
1947
3.81k
  dsc->id = CDSC_OK;
1948
3.81k
  dsc->endcomments = DSC_START(dsc);
1949
3.81k
  dsc->scan_section = scan_pre_preview;
1950
3.81k
  return CDSC_PROPAGATE;
1951
3.81k
    }
1952
46.2k
    else if (IS_DSC(line, "%%Begin")) {
1953
877
  dsc->endcomments = DSC_START(dsc);
1954
877
  dsc->scan_section = scan_pre_preview;
1955
877
  return CDSC_PROPAGATE;
1956
877
    }
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
45.4k
    if (IS_DSC(line, "%%+")) {
1967
11.4k
  line = dsc->last_line;
1968
11.4k
  continued = TRUE;
1969
11.4k
    }
1970
34.0k
    else
1971
34.0k
  dsc_save_line(dsc);
1972
1973
45.4k
    if (IS_DSC(line, "%%Pages:")) {
1974
2.53k
  dsc->id = CDSC_PAGES;
1975
2.53k
  if (dsc_parse_pages(dsc) != 0)
1976
0
      return CDSC_ERROR;
1977
2.53k
    }
1978
42.9k
    else if (IS_DSC(line, "%%Creator:")) {
1979
1.23k
  dsc->id = CDSC_CREATOR;
1980
1.23k
  dsc->dsc_creator = dsc_add_line(dsc, dsc->line+10, dsc->line_length-10);
1981
1.23k
  if (dsc->dsc_creator==NULL)
1982
343
      return CDSC_ERROR;
1983
1.23k
    }
1984
41.7k
    else if (IS_DSC(line, "%%CreationDate:")) {
1985
987
  dsc->id = CDSC_CREATIONDATE;
1986
987
  dsc->dsc_date = dsc_add_line(dsc, dsc->line+15, dsc->line_length-15);
1987
987
  if (dsc->dsc_date==NULL)
1988
196
      return CDSC_ERROR;
1989
987
    }
1990
40.7k
    else if (IS_DSC(line, "%%Title:")) {
1991
1.06k
  dsc->id = CDSC_TITLE;
1992
1.06k
  dsc->dsc_title = dsc_add_line(dsc, dsc->line+8, dsc->line_length-8);
1993
1.06k
  if (dsc->dsc_title==NULL)
1994
126
      return CDSC_ERROR;
1995
1.06k
    }
1996
39.6k
    else if (IS_DSC(line, "%%For:")) {
1997
1.36k
  dsc->id = CDSC_FOR;
1998
1.36k
  dsc->dsc_for = dsc_add_line(dsc, dsc->line+6, dsc->line_length-6);
1999
1.36k
  if (dsc->dsc_for==NULL)
2000
222
      return CDSC_ERROR;
2001
1.36k
    }
2002
38.2k
    else if (IS_DSC(line, "%%LanguageLevel:")) {
2003
1.61k
  unsigned int n = continued ? 3 : 16;
2004
1.61k
  unsigned int i;
2005
1.61k
  int ll;
2006
1.61k
  dsc->id = CDSC_LANGUAGELEVEL;
2007
1.61k
  ll = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
2008
1.61k
  if (i) {
2009
1.05k
      if ( (ll==1) || (ll==2) || (ll==3) )
2010
229
    dsc->language_level = ll;
2011
828
      else {
2012
828
    dsc_unknown(dsc);
2013
828
      }
2014
1.05k
  }
2015
556
  else 
2016
556
      dsc_unknown(dsc);
2017
1.61k
    }
2018
36.6k
    else if (IS_DSC(line, "%%BoundingBox:")) {
2019
3.03k
  dsc->id = CDSC_BOUNDINGBOX;
2020
3.03k
  if (dsc_parse_bounding_box(dsc, &(dsc->bbox), continued ? 3 : 14))
2021
0
      return CDSC_ERROR;
2022
3.03k
    }
2023
33.6k
    else if (IS_DSC(line, "%%HiResBoundingBox:")) {
2024
279
  dsc->id = CDSC_HIRESBOUNDINGBOX;
2025
279
  if (dsc_parse_float_bounding_box(dsc, &(dsc->hires_bbox), 
2026
279
      continued ? 3 : 19))
2027
0
      return CDSC_ERROR;
2028
279
    }
2029
33.3k
    else if (IS_DSC(line, "%%CropBox:")) {
2030
2.89k
  dsc->id = CDSC_CROPBOX;
2031
2.89k
  if (dsc_parse_float_bounding_box(dsc, &(dsc->crop_box), 
2032
2.89k
      continued ? 3 : 10))
2033
0
      return CDSC_ERROR;
2034
2.89k
    }
2035
30.4k
    else if (IS_DSC(line, "%%Orientation:")) {
2036
884
  dsc->id = CDSC_ORIENTATION;
2037
884
  if (dsc_parse_orientation(dsc, &(dsc->page_orientation), 
2038
884
    continued ? 3 : 14))
2039
0
      return CDSC_ERROR;
2040
884
    }
2041
29.5k
    else if (IS_DSC(line, "%%PageOrder:")) {
2042
1.26k
  dsc->id = CDSC_PAGEORDER;
2043
1.26k
  if (dsc_parse_order(dsc))
2044
0
      return CDSC_ERROR;
2045
1.26k
    }
2046
28.3k
    else if (IS_DSC(line, "%%DocumentMedia:")) {
2047
1.87k
  dsc->id = CDSC_DOCUMENTMEDIA;
2048
1.87k
  if (dsc_parse_document_media(dsc))
2049
0
      return CDSC_ERROR;
2050
1.87k
    }
2051
26.4k
    else if (IS_DSC(line, "%%DocumentPaperSizes:")) {
2052
  /* DSC 2.1 */
2053
716
  unsigned int n = continued ? 3 : 21;
2054
716
  unsigned int count = 0;
2055
716
  unsigned int i = 1;
2056
716
  char name[MAXSTR];
2057
716
  char *p;
2058
716
  dsc->id = CDSC_DOCUMENTPAPERSIZES;
2059
2.82k
  while (i && n < dsc->line_length && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
2060
2.10k
      p = dsc_copy_string(name, sizeof(name)-1,
2061
2.10k
        dsc->line+n, dsc->line_length-n, &i);
2062
2.10k
      if (i && p) {
2063
2.10k
    const CDSCMEDIA *m = dsc_known_media;
2064
2.10k
    if (count >= dsc->media_count) {
2065
        /* set some default values */
2066
1.17k
        CDSCMEDIA lmedia;
2067
1.17k
        lmedia.name = p;
2068
1.17k
        lmedia.width = 595.0;
2069
1.17k
        lmedia.height = 842.0;
2070
1.17k
        lmedia.weight = 80.0;
2071
1.17k
        lmedia.colour = NULL;
2072
1.17k
        lmedia.type = NULL;
2073
1.17k
        lmedia.mediabox = NULL;
2074
1.17k
        if (dsc_add_media(dsc, &lmedia))
2075
0
      return CDSC_ERROR;
2076
1.17k
    }
2077
927
    else
2078
927
        dsc->media[count]->name = 
2079
927
      dsc_alloc_string(dsc, p, strlen(p));
2080
    /* find in list of known media */
2081
96.8k
    while (m && m->name) {
2082
94.7k
        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
94.7k
        m++;
2088
94.7k
    }
2089
2.10k
      }
2090
2.10k
      n+=i;
2091
2.10k
      count++;
2092
2.10k
  }
2093
716
    }
2094
25.7k
    else if (IS_DSC(line, "%%DocumentPaperForms:")) {
2095
  /* DSC 2.1 */
2096
560
  unsigned int n = continued ? 3 : 21;
2097
560
  unsigned int count = 0;
2098
560
  unsigned int i = 1;
2099
560
  char type[MAXSTR];
2100
560
  char *p;
2101
560
  dsc->id = CDSC_DOCUMENTPAPERFORMS;
2102
2.18k
  while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
2103
1.62k
      p = dsc_copy_string(type, sizeof(type)-1,
2104
1.62k
        dsc->line+n, dsc->line_length-n, &i);
2105
1.62k
      if (i && p) {
2106
1.30k
    if (count >= dsc->media_count) {
2107
        /* set some default values */
2108
470
        CDSCMEDIA lmedia;
2109
470
        lmedia.name = NULL;
2110
470
        lmedia.width = 595.0;
2111
470
        lmedia.height = 842.0;
2112
470
        lmedia.weight = 80.0;
2113
470
        lmedia.colour = NULL;
2114
470
        lmedia.type = p;
2115
470
        lmedia.mediabox = NULL;
2116
470
        if (dsc_add_media(dsc, &lmedia))
2117
0
      return CDSC_ERROR;
2118
470
    }
2119
838
    else
2120
838
        dsc->media[count]->type = 
2121
838
      dsc_alloc_string(dsc, p, strlen(p));
2122
1.30k
      }
2123
1.62k
      n+=i;
2124
1.62k
      count++;
2125
1.62k
  }
2126
560
    }
2127
25.1k
    else if (IS_DSC(line, "%%DocumentPaperColors:")) {
2128
  /* DSC 2.1 */
2129
418
  unsigned int n = continued ? 3 : 22;
2130
418
  unsigned int count = 0;
2131
418
  unsigned int i = 1;
2132
418
  char colour[MAXSTR];
2133
418
  char *p;
2134
418
  dsc->id = CDSC_DOCUMENTPAPERCOLORS;
2135
2.79k
  while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
2136
2.38k
      if (n > dsc->line_length) {
2137
8
    break;
2138
8
      }
2139
2.37k
      p = dsc_copy_string(colour, sizeof(colour)-1, 
2140
2.37k
        dsc->line+n, dsc->line_length-n, &i);
2141
2.37k
      if (i && p) {
2142
2.04k
    if (count >= dsc->media_count) {
2143
        /* set some default values */
2144
1.35k
        CDSCMEDIA lmedia;
2145
1.35k
        lmedia.name = NULL;
2146
1.35k
        lmedia.width = 595.0;
2147
1.35k
        lmedia.height = 842.0;
2148
1.35k
        lmedia.weight = 80.0;
2149
1.35k
        lmedia.colour = p;
2150
1.35k
        lmedia.type = NULL;
2151
1.35k
        lmedia.mediabox = NULL;
2152
1.35k
        if (dsc_add_media(dsc, &lmedia))
2153
0
      return CDSC_ERROR;
2154
1.35k
    }
2155
684
    else
2156
684
        dsc->media[count]->colour = 
2157
684
      dsc_alloc_string(dsc, p, strlen(p));
2158
2.04k
      }
2159
2.37k
      n+=i;
2160
2.37k
      count++;
2161
2.37k
  }
2162
418
    }
2163
24.7k
    else if (IS_DSC(line, "%%DocumentPaperWeights:")) {
2164
  /* DSC 2.1 */
2165
1.18k
  unsigned int n = continued ? 3 : 23;
2166
1.18k
  unsigned int count = 0;
2167
1.18k
  unsigned int i = 1;
2168
1.18k
  float w;
2169
1.18k
  dsc->id = CDSC_DOCUMENTPAPERWEIGHTS;
2170
3.23k
  while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
2171
2.04k
      w = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
2172
2.04k
      if (i) {
2173
1.05k
    if (count >= dsc->media_count) {
2174
        /* set some default values */
2175
321
        CDSCMEDIA lmedia;
2176
321
        lmedia.name = NULL;
2177
321
        lmedia.width = 595.0;
2178
321
        lmedia.height = 842.0;
2179
321
        lmedia.weight = w;
2180
321
        lmedia.colour = NULL;
2181
321
        lmedia.type = NULL;
2182
321
        lmedia.mediabox = NULL;
2183
321
        if (dsc_add_media(dsc, &lmedia))
2184
0
      return CDSC_ERROR;
2185
321
    }
2186
738
    else
2187
738
        dsc->media[count]->weight = w;
2188
1.05k
      }
2189
2.04k
      n+=i;
2190
2.04k
      count++;
2191
2.04k
  }
2192
1.18k
    }
2193
23.5k
    else if (IS_DSC(line, "%%DocumentData:")) {
2194
1.12k
  unsigned int n = continued ? 3 : 15;
2195
1.12k
  char *p = dsc->line + n;
2196
1.66k
        while (IS_WHITE(*p))
2197
543
      p++;
2198
1.12k
  dsc->id = CDSC_DOCUMENTDATA;
2199
1.12k
  if (COMPARE(p, "Clean7Bit"))
2200
470
      dsc->document_data = CDSC_CLEAN7BIT;
2201
650
  else if (COMPARE(p, "Clean8Bit"))
2202
78
      dsc->document_data = CDSC_CLEAN8BIT;
2203
572
  else if (COMPARE(p, "Binary"))
2204
243
      dsc->document_data = CDSC_BINARY;
2205
329
  else
2206
329
      dsc_unknown(dsc);
2207
1.12k
    }
2208
22.4k
    else if (IS_DSC(line, "%%Requirements:")) {
2209
248
  dsc->id = CDSC_REQUIREMENTS;
2210
  /* ignore */
2211
248
    }
2212
22.1k
    else if (IS_DSC(line, "%%DocumentNeededFonts:")) {
2213
80
  dsc->id = CDSC_DOCUMENTNEEDEDFONTS;
2214
  /* ignore */
2215
80
    }
2216
22.1k
    else if (IS_DSC(line, "%%DocumentSuppliedFonts:")) {
2217
118
  dsc->id = CDSC_DOCUMENTSUPPLIEDFONTS;
2218
  /* ignore */
2219
118
    }
2220
22.0k
    else if (dsc->line[0] == '%' && IS_WHITE_OR_EOL(dsc->line[1])) {
2221
0
  dsc->id = CDSC_OK;
2222
  /* ignore */
2223
0
    }
2224
22.0k
    else {
2225
22.0k
  dsc->id = CDSC_UNKNOWNDSC;
2226
22.0k
  dsc_unknown(dsc);
2227
22.0k
    }
2228
2229
44.5k
    dsc->endcomments = DSC_END(dsc);
2230
44.5k
    return CDSC_OK;
2231
45.4k
}
2232
2233
2234
dsc_private int 
2235
dsc_scan_preview(CDSC *dsc)
2236
28.2k
{
2237
    /* Preview section ends at */
2238
    /*  %%EndPreview */
2239
    /*  another section */
2240
    /* Preview section must start with %%BeginPreview */
2241
28.2k
    char *line = dsc->line;
2242
28.2k
    dsc->id = CDSC_OK;
2243
2244
28.2k
    if (dsc->scan_section == scan_pre_preview) {
2245
16.5k
  if (IS_BLANK(line))
2246
7.50k
      return CDSC_OK;  /* ignore blank lines before preview */
2247
9.02k
  else if (IS_DSC(line, "%%BeginPreview")) {
2248
684
      dsc->id = CDSC_BEGINPREVIEW;
2249
684
      dsc->beginpreview = DSC_START(dsc);
2250
684
      dsc->endpreview = DSC_END(dsc);
2251
684
      dsc->scan_section = scan_preview;
2252
      /* Don't mark the preview as EPSI if a DOS EPS header is present */
2253
684
      if (dsc->preview == CDSC_NOPREVIEW)
2254
684
    dsc->preview = CDSC_EPSI;
2255
684
      return CDSC_OK;
2256
684
  }
2257
8.34k
  else {
2258
8.34k
      dsc->scan_section = scan_pre_defaults;
2259
8.34k
      return CDSC_PROPAGATE;
2260
8.34k
  }
2261
16.5k
    }
2262
2263
11.7k
    if (IS_DSC(line, "%%BeginPreview")) {
2264
  /* ignore because we are in this section */
2265
564
    }
2266
11.1k
    else if (dsc_is_section(line)) {
2267
434
  dsc->endpreview = DSC_START(dsc);
2268
434
  dsc->scan_section = scan_pre_defaults;
2269
434
  return CDSC_PROPAGATE;
2270
434
    }
2271
10.7k
    else if (IS_DSC(line, "%%EndPreview")) {
2272
51
  dsc->id = CDSC_ENDPREVIEW;
2273
51
  dsc->endpreview = DSC_END(dsc);
2274
51
  dsc->scan_section = scan_pre_defaults;
2275
51
  return CDSC_OK;
2276
51
    }
2277
10.7k
    else if (line[0] == '%' && line[1] != '%') {
2278
  /* Ordinary comments are OK */
2279
1.23k
    }
2280
9.48k
    else {
2281
9.48k
  dsc->id = CDSC_UNKNOWNDSC;
2282
  /* DSC comments should not occur in preview */
2283
9.48k
  dsc_unknown(dsc);
2284
9.48k
    }
2285
2286
11.2k
    dsc->endpreview = DSC_END(dsc);
2287
11.2k
    return CDSC_OK;
2288
11.7k
}
2289
2290
dsc_private int
2291
dsc_scan_defaults(CDSC *dsc)
2292
23.4k
{
2293
    /* Defaults section ends at */
2294
    /*  %%EndDefaults */
2295
    /*  another section */
2296
    /* Defaults section must start with %%BeginDefaults */
2297
23.4k
    char *line = dsc->line;
2298
23.4k
    dsc->id = CDSC_OK;
2299
2300
23.4k
    if (dsc->scan_section == scan_pre_defaults) {
2301
9.43k
  if (IS_BLANK(line))
2302
630
      return CDSC_OK;  /* ignore blank lines before defaults */
2303
8.80k
  else if (IS_DSC(line, "%%BeginDefaults")) {
2304
995
      dsc->id = CDSC_BEGINDEFAULTS;
2305
995
      dsc->begindefaults = DSC_START(dsc);
2306
995
      dsc->enddefaults = DSC_END(dsc);
2307
995
      dsc->scan_section = scan_defaults;
2308
995
      return CDSC_OK;
2309
995
  }
2310
7.81k
  else {
2311
7.81k
      dsc->scan_section = scan_pre_prolog;
2312
7.81k
      return CDSC_PROPAGATE;
2313
7.81k
  }
2314
9.43k
    }
2315
2316
14.0k
    if (NOT_DSC_LINE(line)) {
2317
  /* ignore */
2318
7.70k
    }
2319
6.36k
    else if (IS_DSC(line, "%%BeginPreview")) {
2320
  /* ignore because we have already processed this section */
2321
223
    }
2322
6.13k
    else if (IS_DSC(line, "%%BeginDefaults")) {
2323
  /* ignore because we are in this section */
2324
627
    }
2325
5.51k
    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.35k
    else if (IS_DSC(line, "%%EndDefaults")) {
2331
16
  dsc->id = CDSC_ENDDEFAULTS;
2332
16
  dsc->enddefaults = DSC_END(dsc);
2333
16
  dsc->scan_section = scan_pre_prolog;
2334
16
  return CDSC_OK;
2335
16
    }
2336
5.33k
    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.16k
    else if (IS_DSC(line, "%%PageOrientation:")) {
2341
579
  dsc->id = CDSC_PAGEORIENTATION;
2342
  /* This can override %%Orientation:  */
2343
579
  if (dsc_parse_orientation(dsc, &(dsc->page_orientation), 18))
2344
0
      return CDSC_ERROR;
2345
579
    }
2346
4.58k
    else if (IS_DSC(line, "%%PageBoundingBox:")) {
2347
428
  dsc->id = CDSC_PAGEBOUNDINGBOX;
2348
428
  if (dsc_parse_bounding_box(dsc, &(dsc->page_bbox), 18))
2349
0
      return CDSC_ERROR;
2350
428
    }
2351
4.16k
    else if (IS_DSC(line, "%%ViewingOrientation:")) {
2352
425
  dsc->id = CDSC_VIEWINGORIENTATION;
2353
425
  if (dsc_parse_viewing_orientation(dsc, &dsc->viewing_orientation))
2354
0
      return CDSC_ERROR;
2355
425
    }
2356
3.73k
    else {
2357
3.73k
  dsc->id = CDSC_UNKNOWNDSC;
2358
  /* All other DSC comments are unknown, but not an error */
2359
3.73k
  dsc_unknown(dsc);
2360
3.73k
    }
2361
13.8k
    dsc->enddefaults = DSC_END(dsc);
2362
13.8k
    return CDSC_OK;
2363
14.0k
}
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
32.8k
{
2370
32.8k
    if (count != 0) {
2371
571
  char buf[MAXSTR+MAXSTR] = "";
2372
571
  if (dsc->line_length < (unsigned int)(sizeof(buf)/2-1))  {
2373
543
      strncpy(buf, dsc->line, dsc->line_length);
2374
543
      buf[dsc->line_length] = '\0';
2375
543
  }
2376
571
  sprintf(buf+strlen(buf), "\n%%%%Begin%.40s: / %%%%End%.40s\n", str, str);
2377
571
  return dsc_error(dsc, CDSC_MESSAGE_BEGIN_END, buf, strlen(buf));
2378
571
    }
2379
32.2k
    return CDSC_RESPONSE_CANCEL;
2380
32.8k
}
2381
2382
dsc_private int
2383
dsc_check_match_type(CDSC *dsc, const char *str, int count)
2384
32.8k
{
2385
32.8k
    if (dsc_check_match_prompt(dsc, str, count) == CDSC_RESPONSE_IGNORE_ALL)
2386
0
  return CDSC_NOTDSC;
2387
32.8k
    return CDSC_OK;
2388
32.8k
}
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.21k
{
2395
8.21k
    int rc = 0;
2396
8.21k
    const char *font = "Font";
2397
8.21k
    const char *feature = "Feature";
2398
8.21k
    const char *resource = "Resource";
2399
8.21k
    const char *procset = "ProcSet";
2400
2401
8.21k
    if (!rc)
2402
8.21k
  rc = dsc_check_match_type(dsc, font, dsc->begin_font_count);
2403
8.21k
    if (!rc)
2404
8.21k
  rc = dsc_check_match_type(dsc, feature, dsc->begin_feature_count);
2405
8.21k
    if (!rc)
2406
8.21k
  rc = dsc_check_match_type(dsc, resource, dsc->begin_resource_count);
2407
8.21k
    if (!rc)
2408
8.21k
  rc = dsc_check_match_type(dsc, procset, dsc->begin_procset_count);
2409
2410
8.21k
    dsc->begin_font_count = 0;
2411
8.21k
    dsc->begin_feature_count = 0;
2412
8.21k
    dsc->begin_resource_count = 0;
2413
8.21k
    dsc->begin_procset_count = 0;
2414
8.21k
    return rc;
2415
8.21k
}
2416
2417
2418
dsc_private int 
2419
dsc_scan_prolog(CDSC *dsc)
2420
58.1k
{
2421
    /* Prolog section ends at */
2422
    /*  %%EndProlog */
2423
    /*  another section */
2424
    /* Prolog section may start with %%BeginProlog or non-dsc line */
2425
58.1k
    char *line = dsc->line;
2426
58.1k
    dsc->id = CDSC_OK;
2427
2428
58.1k
    if (dsc->scan_section == scan_pre_prolog) {
2429
7.98k
        if (dsc_is_section(line) && (!IS_DSC(line, "%%BeginProlog"))) {
2430
3.40k
      dsc->scan_section = scan_pre_setup;
2431
3.40k
      return CDSC_PROPAGATE;
2432
3.40k
  }
2433
4.58k
  dsc->id = CDSC_BEGINPROLOG;
2434
4.58k
  dsc->beginprolog = DSC_START(dsc);
2435
4.58k
  dsc->endprolog = DSC_END(dsc);
2436
4.58k
  dsc->scan_section = scan_prolog;
2437
4.58k
  if (IS_DSC(line, "%%BeginProlog"))
2438
47
      return CDSC_OK;
2439
4.58k
    }
2440
   
2441
54.6k
    if (NOT_DSC_LINE(line)) {
2442
  /* ignore */
2443
39.5k
    }
2444
15.1k
    else if (IS_DSC(line, "%%BeginPreview")) {
2445
  /* ignore because we have already processed this section */
2446
289
    }
2447
14.8k
    else if (IS_DSC(line, "%%BeginDefaults")) {
2448
  /* ignore because we have already processed this section */
2449
350
    }
2450
14.5k
    else if (IS_DSC(line, "%%BeginProlog")) {
2451
  /* ignore because we are in this section */
2452
291
    }
2453
14.2k
    else if (dsc_is_section(line)) {
2454
2.47k
  dsc->endprolog = DSC_START(dsc);
2455
2.47k
  dsc->scan_section = scan_pre_setup;
2456
2.47k
  if (dsc_check_match(dsc))
2457
0
      return CDSC_NOTDSC;
2458
2.47k
  return CDSC_PROPAGATE;
2459
2.47k
    }
2460
11.7k
    else if (IS_DSC(line, "%%EndProlog")) {
2461
97
  dsc->id = CDSC_ENDPROLOG;
2462
97
  dsc->endprolog = DSC_END(dsc);
2463
97
  dsc->scan_section = scan_pre_setup;
2464
97
  if (dsc_check_match(dsc))
2465
0
      return CDSC_NOTDSC;
2466
97
  return CDSC_OK;
2467
97
    }
2468
11.6k
    else if (IS_DSC(line, "%%BeginFont:")) {
2469
184
  dsc->id = CDSC_BEGINFONT;
2470
  /* ignore Begin/EndFont, apart form making sure */
2471
  /* that they are matched. */
2472
184
  dsc->begin_font_count++;
2473
184
    }
2474
11.4k
    else if (IS_DSC(line, "%%EndFont")) {
2475
267
  dsc->id = CDSC_ENDFONT;
2476
267
  dsc->begin_font_count--;
2477
267
    }
2478
11.2k
    else if (IS_DSC(line, "%%BeginFeature:")) {
2479
257
  dsc->id = CDSC_BEGINFEATURE;
2480
  /* ignore Begin/EndFeature, apart form making sure */
2481
  /* that they are matched. */
2482
257
  dsc->begin_feature_count++;
2483
257
    }
2484
10.9k
    else if (IS_DSC(line, "%%EndFeature")) {
2485
178
  dsc->id = CDSC_ENDFEATURE;
2486
178
  dsc->begin_feature_count--;
2487
178
    }
2488
10.7k
    else if (IS_DSC(line, "%%BeginResource:")) {
2489
427
  dsc->id = CDSC_BEGINRESOURCE;
2490
  /* ignore Begin/EndResource, apart form making sure */
2491
  /* that they are matched. */
2492
427
  dsc->begin_resource_count++;
2493
427
    }
2494
10.3k
    else if (IS_DSC(line, "%%EndResource")) {
2495
290
  dsc->id = CDSC_ENDRESOURCE;
2496
290
  dsc->begin_resource_count--;
2497
290
    }
2498
10.0k
    else if (IS_DSC(line, "%%BeginProcSet:")) {
2499
244
  dsc->id = CDSC_BEGINPROCSET;
2500
  /* ignore Begin/EndProcSet, apart form making sure */
2501
  /* that they are matched. */
2502
244
  dsc->begin_procset_count++;
2503
244
    }
2504
9.80k
    else if (IS_DSC(line, "%%EndProcSet")) {
2505
262
  dsc->id = CDSC_ENDPROCSET;
2506
262
  dsc->begin_procset_count--;
2507
262
    }
2508
9.54k
    else {
2509
  /* All other DSC comments are unknown, but not an error */
2510
9.54k
  dsc->id = CDSC_UNKNOWNDSC;
2511
9.54k
  dsc_unknown(dsc);
2512
9.54k
    }
2513
2514
52.1k
    dsc->endprolog = DSC_END(dsc);
2515
52.1k
    return CDSC_OK;
2516
54.6k
}
2517
2518
dsc_private int
2519
dsc_scan_setup(CDSC *dsc)
2520
32.9k
{
2521
    /* Setup section ends at */
2522
    /*  %%EndSetup */
2523
    /*  another section */
2524
    /* Setup section must start with %%BeginSetup */
2525
2526
32.9k
    char *line = dsc->line;
2527
32.9k
    dsc->id = CDSC_OK;
2528
2529
32.9k
    if (dsc->scan_section == scan_pre_setup) {
2530
6.55k
  if (IS_BLANK(line))
2531
600
      return CDSC_OK;  /* ignore blank lines before setup */
2532
5.95k
  else if (IS_DSC(line, "%%BeginSetup")) {
2533
1.14k
      dsc->id = CDSC_BEGINSETUP;
2534
1.14k
      dsc->beginsetup = DSC_START(dsc);
2535
1.14k
      dsc->endsetup = DSC_END(dsc);
2536
1.14k
      dsc->scan_section = scan_setup;
2537
1.14k
      return CDSC_OK;
2538
1.14k
  }
2539
4.81k
  else {
2540
4.81k
      dsc->scan_section = scan_pre_pages;
2541
4.81k
      return CDSC_PROPAGATE;
2542
4.81k
  }
2543
6.55k
    }
2544
2545
26.4k
    if (NOT_DSC_LINE(line)) {
2546
  /* ignore */
2547
15.6k
    }
2548
10.7k
    else if (IS_DSC(line, "%%BeginPreview")) {
2549
  /* ignore because we have already processed this section */
2550
335
    }
2551
10.4k
    else if (IS_DSC(line, "%%BeginDefaults")) {
2552
  /* ignore because we have already processed this section */
2553
352
    }
2554
10.1k
    else if (IS_DSC(line, "%%BeginProlog")) {
2555
  /* ignore because we have already processed this section */
2556
206
    }
2557
9.89k
    else if (IS_DSC(line, "%%BeginSetup")) {
2558
  /* ignore because we are in this section */
2559
660
    }
2560
9.23k
    else if (dsc_is_section(line)) {
2561
152
  dsc->endsetup = DSC_START(dsc);
2562
152
  dsc->scan_section = scan_pre_pages;
2563
152
  if (dsc_check_match(dsc))
2564
0
      return CDSC_NOTDSC;
2565
152
  return CDSC_PROPAGATE;
2566
152
    }
2567
9.08k
    else if (IS_DSC(line, "%%EndSetup")) {
2568
45
  dsc->id = CDSC_ENDSETUP;
2569
45
  dsc->endsetup = DSC_END(dsc);
2570
45
  dsc->scan_section = scan_pre_pages;
2571
45
  if (dsc_check_match(dsc))
2572
0
      return CDSC_NOTDSC;
2573
45
  return CDSC_OK;
2574
45
    }
2575
9.03k
    else if (IS_DSC(line, "%%BeginFeature:")) {
2576
142
  dsc->id = CDSC_BEGINFEATURE;
2577
  /* ignore Begin/EndFeature, apart form making sure */
2578
  /* that they are matched. */
2579
142
  dsc->begin_feature_count++;
2580
142
    }
2581
8.89k
    else if (IS_DSC(line, "%%EndFeature")) {
2582
152
  dsc->id = CDSC_ENDFEATURE;
2583
152
  dsc->begin_feature_count--;
2584
152
    }
2585
8.74k
    else if (IS_DSC(line, "%%Feature:")) {
2586
153
  dsc->id = CDSC_FEATURE;
2587
  /* ignore */
2588
153
    }
2589
8.59k
    else if (IS_DSC(line, "%%BeginResource:")) {
2590
255
  dsc->id = CDSC_BEGINRESOURCE;
2591
  /* ignore Begin/EndResource, apart form making sure */
2592
  /* that they are matched. */
2593
255
  dsc->begin_resource_count++;
2594
255
    }
2595
8.33k
    else if (IS_DSC(line, "%%EndResource")) {
2596
150
  dsc->id = CDSC_ENDRESOURCE;
2597
150
  dsc->begin_resource_count--;
2598
150
    }
2599
8.18k
    else if (IS_DSC(line, "%%PaperColor:")) {
2600
163
  dsc->id = CDSC_PAPERCOLOR;
2601
  /* ignore */
2602
163
    }
2603
8.02k
    else if (IS_DSC(line, "%%PaperForm:")) {
2604
391
  dsc->id = CDSC_PAPERFORM;
2605
  /* ignore */
2606
391
    }
2607
7.63k
    else if (IS_DSC(line, "%%PaperWeight:")) {
2608
135
  dsc->id = CDSC_PAPERWEIGHT;
2609
  /* ignore */
2610
135
    }
2611
7.49k
    else if (IS_DSC(line, "%%PaperSize:")) {
2612
  /* DSC 2.1 */
2613
453
        GSBOOL found_media = FALSE;
2614
453
  int i;
2615
453
  int n = 12;
2616
453
  char buf[MAXSTR];
2617
453
  buf[0] = '\0';
2618
453
  dsc->id = CDSC_PAPERSIZE;
2619
453
  dsc_copy_string(buf, sizeof(buf)-1, dsc->line+n, dsc->line_length-n, 
2620
453
    NULL);
2621
1.57k
  for (i=0; i<(int)dsc->media_count; i++) {
2622
1.17k
      if (dsc->media[i] && dsc->media[i]->name && 
2623
289
    (dsc_stricmp(buf, dsc->media[i]->name)==0)) {
2624
53
    dsc->page_media = dsc->media[i];
2625
53
    found_media = TRUE;
2626
53
    break;
2627
53
      }
2628
1.17k
  }
2629
453
  if (!found_media) {
2630
      /* It didn't match %%DocumentPaperSizes: */
2631
      /* Try our known media */
2632
400
      const CDSCMEDIA *m = dsc_known_media;
2633
18.4k
      while (m->name) {
2634
18.0k
    if (dsc_stricmp(buf, m->name)==0) {
2635
0
        dsc->page_media = m;
2636
0
        break;
2637
0
    }
2638
18.0k
    m++;
2639
18.0k
      }
2640
400
      if (m->name == NULL)
2641
400
    dsc_unknown(dsc);
2642
400
  }
2643
453
    }
2644
7.04k
    else {
2645
  /* All other DSC comments are unknown, but not an error */
2646
7.04k
  dsc->id = CDSC_UNKNOWNDSC;
2647
7.04k
  dsc_unknown(dsc);
2648
7.04k
    }
2649
2650
26.2k
    dsc->endsetup = DSC_END(dsc);
2651
26.2k
    return CDSC_OK;
2652
26.4k
}
2653
2654
dsc_private int 
2655
dsc_scan_page(CDSC *dsc)
2656
77.7k
{
2657
    /* Page section ends at */
2658
    /*  %%Page */
2659
    /*  %%Trailer */
2660
    /*  %%EOF */
2661
77.7k
    char *line = dsc->line;
2662
77.7k
    dsc->id = CDSC_OK;
2663
2664
77.7k
    if (dsc->scan_section == scan_pre_pages) {
2665
9.39k
  if (IS_DSC(line, "%%Page:")) {
2666
3.03k
      dsc->scan_section = scan_pages;
2667
      /* fall through */
2668
3.03k
  }
2669
6.36k
  else  {
2670
      /* %%Page: didn't follow %%EndSetup
2671
       * Keep reading until reach %%Page or %%Trailer
2672
       * and add it to previous section.
2673
       */
2674
6.36k
      unsigned long *last;
2675
6.36k
      if (dsc->endsetup != 0)
2676
889
    last = &dsc->endsetup;
2677
5.47k
      else if (dsc->endprolog != 0)
2678
4.02k
    last = &dsc->endprolog;
2679
1.45k
      else if (dsc->enddefaults != 0)
2680
63
    last = &dsc->enddefaults;
2681
1.38k
      else if (dsc->endpreview != 0)
2682
600
    last = &dsc->endpreview;
2683
787
      else if (dsc->endcomments != 0)
2684
787
    last = &dsc->endcomments;
2685
0
      else
2686
0
    last = &dsc->begincomments;
2687
6.36k
      *last = DSC_START(dsc);
2688
6.36k
      if (IS_DSC(line, "%%Trailer") || IS_DSC(line, "%%EOF")) {
2689
1.84k
    dsc->scan_section = scan_pre_trailer;
2690
1.84k
    return CDSC_PROPAGATE;
2691
1.84k
      }
2692
4.52k
      return CDSC_OK;
2693
6.36k
  }
2694
9.39k
    }
2695
2696
71.4k
    if (NOT_DSC_LINE(line)) {
2697
  /* ignore */
2698
38.5k
    }
2699
32.8k
    else if (IS_DSC(line, "%%Page:")) {
2700
8.29k
  dsc->id = CDSC_PAGE;
2701
8.29k
  if (dsc->page_count) {
2702
5.26k
      dsc->page[dsc->page_count-1].end = DSC_START(dsc);
2703
5.26k
      if (dsc_check_match(dsc))
2704
0
    return CDSC_NOTDSC;
2705
5.26k
  }
2706
2707
8.29k
  if (dsc_parse_page(dsc) != 0)
2708
0
      return CDSC_ERROR;
2709
2710
8.29k
  return CDSC_OK;
2711
8.29k
    }
2712
24.5k
    else if (IS_DSC(line, "%%BeginPreview")) {
2713
  /* ignore because we have already processed this section */
2714
366
    }
2715
24.2k
    else if (IS_DSC(line, "%%BeginDefaults")) {
2716
  /* ignore because we have already processed this section */
2717
416
    }
2718
23.7k
    else if (IS_DSC(line, "%%BeginProlog")) {
2719
  /* ignore because we have already processed this section */
2720
292
    }
2721
23.4k
    else if (IS_DSC(line, "%%BeginSetup")) {
2722
  /* ignore because we have already processed this section */
2723
533
    }
2724
22.9k
    else if (dsc_is_section(line)) {
2725
184
  if (IS_DSC(line, "%%Trailer")) {
2726
42
      dsc->page[dsc->page_count-1].end = DSC_START(dsc);
2727
42
      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
42
      else {
2756
42
    dsc->scan_section = scan_pre_trailer;
2757
42
    if (dsc_check_match(dsc))
2758
0
        return CDSC_NOTDSC;
2759
42
    return CDSC_PROPAGATE;
2760
42
      }
2761
42
  }
2762
142
  else if (IS_DSC(line, "%%EOF")) {
2763
142
      dsc->page[dsc->page_count-1].end = DSC_START(dsc);
2764
142
      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
142
      else {
2786
    /* ignore it */
2787
142
    if (dsc_check_match(dsc))
2788
0
        return CDSC_NOTDSC;
2789
142
    return CDSC_OK;
2790
142
      }
2791
142
  }
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
184
    }
2801
22.7k
    else if (IS_DSC(line, "%%PageTrailer")) {
2802
87
  dsc->id = CDSC_PAGETRAILER;
2803
  /* ignore */
2804
87
    }
2805
22.6k
    else if (IS_DSC(line, "%%BeginPageSetup")) {
2806
485
  dsc->id = CDSC_BEGINPAGESETUP;
2807
  /* ignore */
2808
485
    }
2809
22.2k
    else if (IS_DSC(line, "%%EndPageSetup")) {
2810
159
  dsc->id = CDSC_ENDPAGESETUP;
2811
  /* ignore */
2812
159
    }
2813
22.0k
    else if (IS_DSC(line, "%%PageMedia:")) {
2814
788
  dsc->id = CDSC_PAGEMEDIA;
2815
788
  dsc_parse_media(dsc, &(dsc->page[dsc->page_count-1].media));
2816
788
    }
2817
21.2k
    else if (IS_DSC(line, "%%PaperColor:")) {
2818
280
  dsc->id = CDSC_PAPERCOLOR;
2819
  /* ignore */
2820
280
    }
2821
20.9k
    else if (IS_DSC(line, "%%PaperForm:")) {
2822
520
  dsc->id = CDSC_PAPERFORM;
2823
  /* ignore */
2824
520
    }
2825
20.4k
    else if (IS_DSC(line, "%%PaperWeight:")) {
2826
280
  dsc->id = CDSC_PAPERWEIGHT;
2827
  /* ignore */
2828
280
    }
2829
20.1k
    else if (IS_DSC(line, "%%PaperSize:")) {
2830
  /* DSC 2.1 */
2831
637
        GSBOOL found_media = FALSE;
2832
637
  int i;
2833
637
  int n = 12;
2834
637
  char buf[MAXSTR];
2835
637
  buf[0] = '\0';
2836
637
  dsc_copy_string(buf, sizeof(buf)-1, dsc->line+n, 
2837
637
      dsc->line_length-n, NULL);
2838
1.20k
  for (i=0; i<(int)dsc->media_count; i++) {
2839
663
      if (dsc->media[i] && dsc->media[i]->name && 
2840
296
    (dsc_stricmp(buf, dsc->media[i]->name)==0)) {
2841
98
    dsc->page_media = dsc->media[i];
2842
98
    found_media = TRUE;
2843
98
    break;
2844
98
      }
2845
663
  }
2846
637
  if (!found_media) {
2847
      /* It didn't match %%DocumentPaperSizes: */
2848
      /* Try our known media */
2849
539
      const CDSCMEDIA *m = dsc_known_media;
2850
24.7k
      while (m->name) {
2851
24.2k
    if (dsc_stricmp(buf, m->name)==0) {
2852
0
        dsc->page[dsc->page_count-1].media = m;
2853
0
        break;
2854
0
    }
2855
24.2k
    m++;
2856
24.2k
      }
2857
539
      if (m->name == NULL)
2858
539
    dsc_unknown(dsc);
2859
539
  }
2860
637
    }
2861
19.5k
    else if (IS_DSC(line, "%%PageOrientation:")) {
2862
735
  dsc->id = CDSC_PAGEORIENTATION;
2863
735
  if (dsc_parse_orientation(dsc, 
2864
735
    &(dsc->page[dsc->page_count-1].orientation) ,18))
2865
0
      return CDSC_NOTDSC;
2866
735
    }
2867
18.8k
    else if (IS_DSC(line, "%%PageBoundingBox:")) {
2868
485
  dsc->id = CDSC_PAGEBOUNDINGBOX;
2869
485
  if (dsc_parse_bounding_box(dsc, &dsc->page[dsc->page_count-1].bbox, 18))
2870
0
      return CDSC_NOTDSC;
2871
485
    }
2872
18.3k
    else if (IS_DSC(line, "%%ViewingOrientation:")) {
2873
1.14k
  dsc->id = CDSC_VIEWINGORIENTATION;
2874
1.14k
  if (dsc_parse_viewing_orientation(dsc, 
2875
1.14k
      &dsc->page[dsc->page_count-1].viewing_orientation))
2876
0
      return CDSC_ERROR;
2877
1.14k
    }
2878
17.1k
    else if (IS_DSC(line, "%%BeginFont:")) {
2879
500
  dsc->id = CDSC_BEGINFONT;
2880
  /* ignore Begin/EndFont, apart form making sure */
2881
  /* that they are matched. */
2882
500
  dsc->begin_font_count++;
2883
500
    }
2884
16.6k
    else if (IS_DSC(line, "%%EndFont")) {
2885
492
  dsc->id = CDSC_BEGINFONT;
2886
492
  dsc->begin_font_count--;
2887
492
    }
2888
16.1k
    else if (IS_DSC(line, "%%BeginFeature:")) {
2889
391
  dsc->id = CDSC_BEGINFEATURE;
2890
  /* ignore Begin/EndFeature, apart form making sure */
2891
  /* that they are matched. */
2892
391
  dsc->begin_feature_count++;
2893
391
    }
2894
15.7k
    else if (IS_DSC(line, "%%EndFeature")) {
2895
266
  dsc->id = CDSC_ENDFEATURE;
2896
266
  dsc->begin_feature_count--;
2897
266
    }
2898
15.5k
    else if (IS_DSC(line, "%%BeginResource:")) {
2899
202
  dsc->id = CDSC_BEGINRESOURCE;
2900
  /* ignore Begin/EndResource, apart form making sure */
2901
  /* that they are matched. */
2902
202
  dsc->begin_resource_count++;
2903
202
    }
2904
15.3k
    else if (IS_DSC(line, "%%EndResource")) {
2905
341
  dsc->id = CDSC_ENDRESOURCE;
2906
341
  dsc->begin_resource_count--;
2907
341
    }
2908
14.9k
    else if (IS_DSC(line, "%%BeginProcSet:")) {
2909
117
  dsc->id = CDSC_BEGINPROCSET;
2910
  /* ignore Begin/EndProcSet, apart form making sure */
2911
  /* that they are matched. */
2912
117
  dsc->begin_procset_count++;
2913
117
    }
2914
14.8k
    else if (IS_DSC(line, "%%EndProcSet")) {
2915
281
  dsc->id = CDSC_ENDPROCSET;
2916
281
  dsc->begin_procset_count--;
2917
281
    }
2918
14.5k
    else if (IS_DSC(line, "%%IncludeFont:")) {
2919
443
  dsc->id = CDSC_INCLUDEFONT;
2920
  /* ignore */
2921
443
    }
2922
14.1k
    else {
2923
  /* All other DSC comments are unknown, but not an error */
2924
14.1k
  dsc->id = CDSC_UNKNOWNDSC;
2925
14.1k
  dsc_unknown(dsc);
2926
14.1k
    }
2927
2928
62.9k
    dsc->page[dsc->page_count-1].end = DSC_END(dsc);
2929
62.9k
    return CDSC_OK;
2930
71.4k
}
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
35.2k
{
2977
    /* Trailer section start at */
2978
    /*  %%Trailer */
2979
    /* and ends at */
2980
    /*  %%EOF */
2981
35.2k
    char *line = dsc->line;
2982
35.2k
    GSBOOL continued = FALSE;
2983
35.2k
    dsc->id = CDSC_OK;
2984
2985
35.2k
    if (dsc->scan_section == scan_pre_trailer) {
2986
1.88k
  if (IS_DSC(line, "%%Trailer")) {
2987
896
      dsc->id = CDSC_TRAILER;
2988
896
      dsc->begintrailer = DSC_START(dsc);
2989
896
      dsc->endtrailer = DSC_END(dsc);
2990
896
      dsc->scan_section = scan_trailer;
2991
896
      return CDSC_OK;
2992
896
  }
2993
988
  else if (IS_DSC(line, "%%EOF")) {
2994
988
      dsc->id = CDSC_EOF;
2995
988
      dsc->begintrailer = DSC_START(dsc);
2996
988
      dsc->endtrailer = DSC_END(dsc);
2997
988
      dsc->scan_section = scan_trailer;
2998
      /* Continue, in case we found %%EOF in an embedded document */
2999
988
      return CDSC_OK;
3000
988
  }
3001
0
  else {
3002
      /* %%Page: didn't follow %%EndSetup
3003
       * Keep reading until reach %%Page or %%Trailer
3004
       * and add it to setup section
3005
       */
3006
      /* append to previous section */
3007
0
      if (dsc->beginsetup)
3008
0
    dsc->endsetup = DSC_END(dsc);
3009
0
      else if (dsc->beginprolog)
3010
0
    dsc->endprolog = DSC_END(dsc);
3011
0
      else {
3012
    /* horribly confused */
3013
0
      }
3014
0
      return CDSC_OK;
3015
0
  }
3016
1.88k
    }
3017
3018
    /* Handle continuation lines.
3019
     * See comment above about our restrictive processing of 
3020
     * continuation lines
3021
     */
3022
33.3k
    if (IS_DSC(line, "%%+")) {
3023
3.88k
  line = dsc->last_line;
3024
3.88k
  continued = TRUE;
3025
3.88k
    }
3026
29.4k
    else
3027
29.4k
  dsc_save_line(dsc);
3028
3029
33.3k
    if (NOT_DSC_LINE(line)) {
3030
  /* ignore */
3031
18.1k
    }
3032
15.2k
    else if (IS_DSC(dsc->line, "%%EOF")) {
3033
  /* Keep scanning, in case we have a false trailer */
3034
963
  dsc->id = CDSC_EOF;
3035
963
    }
3036
14.2k
    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
535
  dsc->id = CDSC_TRAILER;
3040
535
  dsc->begintrailer = DSC_START(dsc);
3041
535
    }
3042
13.7k
    else if (IS_DSC(line, "%%Pages:")) {
3043
1.25k
  dsc->id = CDSC_PAGES;
3044
1.25k
  if (dsc_parse_pages(dsc) != 0)
3045
0
         return CDSC_ERROR;
3046
1.25k
    }
3047
12.4k
    else if (IS_DSC(line, "%%BoundingBox:")) {
3048
1.65k
  dsc->id = CDSC_BOUNDINGBOX;
3049
1.65k
  if (dsc_parse_bounding_box(dsc, &(dsc->bbox), continued ? 3 : 14))
3050
0
      return CDSC_ERROR;
3051
1.65k
    }
3052
10.8k
    else if (IS_DSC(line, "%%HiResBoundingBox:")) {
3053
109
  dsc->id = CDSC_HIRESBOUNDINGBOX;
3054
109
  if (dsc_parse_float_bounding_box(dsc, &(dsc->hires_bbox), 
3055
109
      continued ? 3 : 19))
3056
0
      return CDSC_ERROR;
3057
109
    }
3058
10.7k
    else if (IS_DSC(line, "%%CropBox:")) {
3059
1.45k
  dsc->id = CDSC_CROPBOX;
3060
1.45k
  if (dsc_parse_float_bounding_box(dsc, &(dsc->crop_box), 
3061
1.45k
      continued ? 3 : 10))
3062
0
      return CDSC_ERROR;
3063
1.45k
    }
3064
9.27k
    else if (IS_DSC(line, "%%Orientation:")) {
3065
900
  dsc->id = CDSC_ORIENTATION;
3066
900
  if (dsc_parse_orientation(dsc, &(dsc->page_orientation), continued ? 3 : 14))
3067
0
      return CDSC_ERROR;
3068
900
    }
3069
8.37k
    else if (IS_DSC(line, "%%PageOrder:")) {
3070
859
  dsc->id = CDSC_PAGEORDER;
3071
859
  if (dsc_parse_order(dsc))
3072
0
      return CDSC_ERROR;
3073
859
    }
3074
7.51k
    else if (IS_DSC(line, "%%DocumentMedia:")) {
3075
444
  dsc->id = CDSC_DOCUMENTMEDIA;
3076
444
  if (dsc_parse_document_media(dsc))
3077
0
      return CDSC_ERROR;
3078
444
    }
3079
7.06k
    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
427
  int rc = dsc_error(dsc, CDSC_MESSAGE_PAGE_IN_TRAILER, 
3084
427
    dsc->line, dsc->line_length);
3085
427
  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
427
      case CDSC_RESPONSE_CANCEL:
3094
    /* ignore pages in trailer */
3095
427
    break;
3096
0
      case CDSC_RESPONSE_IGNORE_ALL:
3097
0
    return CDSC_NOTDSC;
3098
427
  }
3099
427
    }
3100
6.64k
    else if (IS_DSC(line, "%%DocumentNeededFonts:")) {
3101
219
  dsc->id = CDSC_DOCUMENTNEEDEDFONTS;
3102
  /* ignore */
3103
219
    }
3104
6.42k
    else if (IS_DSC(line, "%%DocumentSuppliedFonts:")) {
3105
134
  dsc->id = CDSC_DOCUMENTSUPPLIEDFONTS;
3106
  /* ignore */
3107
134
    }
3108
6.28k
    else {
3109
  /* All other DSC comments are unknown, but not an error */
3110
6.28k
  dsc->id = CDSC_UNKNOWNDSC;
3111
6.28k
  dsc_unknown(dsc);
3112
6.28k
    }
3113
3114
33.3k
    dsc->endtrailer = DSC_END(dsc);
3115
33.3k
    return CDSC_OK;
3116
33.3k
}
3117
3118
3119
dsc_private char *
3120
dsc_alloc_string(CDSC *dsc, const char *str, int len)
3121
28.6k
{
3122
28.6k
    if (len < 0) {
3123
887
  return nullptr;
3124
887
    }
3125
3126
27.7k
    char *p;
3127
27.7k
    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
27.7k
    if ( dsc->string->index + len + 1 > dsc->string->length) {
3142
  /* allocate another string block */
3143
12
  CDSCSTRING *newstring = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
3144
12
  if (newstring == NULL) {
3145
0
      dsc_debug_print(dsc, "Out of memory\n");
3146
0
      return NULL;
3147
0
  }
3148
12
        newstring->next = NULL;
3149
12
  newstring->length = 0;
3150
12
  newstring->index = 0;
3151
12
  newstring->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
3152
12
  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
12
  newstring->length = CDSC_STRING_CHUNK;
3158
12
  dsc->string->next = newstring;
3159
12
  dsc->string = newstring;
3160
12
    }
3161
27.7k
    if ( dsc->string->index + len + 1 > dsc->string->length)
3162
12
  return NULL;  /* failed */
3163
27.7k
    p = dsc->string->data + dsc->string->index;
3164
27.7k
    memcpy(p, str, len);
3165
27.7k
    *(p+len) = '\0';
3166
27.7k
    dsc->string->index += len + 1;
3167
27.7k
    return p;
3168
27.7k
}
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.4k
{
3174
14.4k
    char *newline;
3175
14.4k
    unsigned int i;
3176
21.0k
    while (len && (IS_WHITE(*line))) {
3177
6.58k
  len--;
3178
6.58k
  line++;
3179
6.58k
    }
3180
14.4k
    newline = dsc_alloc_string(dsc, line, len);
3181
14.4k
    if (newline == NULL)
3182
899
  return NULL;
3183
3184
369k
    for (i=0; i<len; i++) {
3185
369k
  if (newline[i] == '\r') {
3186
10.9k
      newline[i]='\0';
3187
10.9k
      break;
3188
10.9k
  }
3189
358k
  if (newline[i] == '\n') {
3190
2.22k
      newline[i]='\0';
3191
2.22k
      break;
3192
2.22k
  }
3193
358k
    }
3194
13.5k
    return newline;
3195
14.4k
}
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
19.0k
{
3208
19.0k
    int quoted = FALSE;
3209
19.0k
    int instring=0;
3210
19.0k
    unsigned int newlength = 0;
3211
19.0k
    unsigned int i = 0;
3212
19.0k
    unsigned char ch;
3213
19.0k
    if (len > slen)
3214
1.51k
  len = slen-1;
3215
33.3k
    while ( (i<len) && IS_WHITE(line[i]))
3216
14.2k
  i++; /* skip leading spaces */
3217
19.0k
    if (line[i]=='(') {
3218
464
  quoted = TRUE;
3219
464
  instring++;
3220
464
  i++; /* don't copy outside () */
3221
464
    }
3222
365k
    while (i < len) {
3223
364k
  str[newlength] = ch = line[i];
3224
364k
  i++;
3225
364k
  if (quoted) {
3226
15.4k
      if (ch == '(')
3227
737
        instring++;
3228
15.4k
      if (ch == ')')
3229
232
        instring--;
3230
15.4k
      if (instring==0)
3231
156
        break;
3232
15.4k
  }
3233
348k
  else if (ch == ' ')
3234
5.72k
      break;
3235
3236
358k
  if (ch == '\r')
3237
8.76k
      break;
3238
349k
  if (ch == '\n')
3239
3.21k
      break;
3240
346k
  else if ( (ch == '\\') && (i+1 < len) ) {
3241
6.31k
      ch = line[i];
3242
6.31k
      if ((ch >= '0') && (ch <= '9')) {
3243
    /* octal coded character */
3244
1.18k
    int j = 3;
3245
1.18k
    ch = 0;
3246
4.00k
    while (j && (i < len) && line[i]>='0' && line[i]<='7') {
3247
2.82k
        ch = (unsigned char)((ch<<3) + (line[i]-'0'));
3248
2.82k
        i++;
3249
2.82k
        j--;
3250
2.82k
    }
3251
1.18k
    str[newlength] = ch;
3252
1.18k
      }
3253
5.13k
      else if (ch == '(') {
3254
239
    str[newlength] = ch;
3255
239
    i++;
3256
239
      }
3257
4.89k
      else if (ch == ')') {
3258
82
    str[newlength] = ch;
3259
82
    i++;
3260
82
      }
3261
4.81k
      else if (ch == 'b') {
3262
321
    str[newlength] = '\b';
3263
321
    i++;
3264
321
      }
3265
4.48k
      else if (ch == 'f') {
3266
125
    str[newlength] = '\b';
3267
125
    i++;
3268
125
      }
3269
4.36k
      else if (ch == 'n') {
3270
870
    str[newlength] = '\n';
3271
870
    i++;
3272
870
      }
3273
3.49k
      else if (ch == 'r') {
3274
597
    str[newlength] = '\r';
3275
597
    i++;
3276
597
      }
3277
2.89k
      else if (ch == 't') {
3278
213
    str[newlength] = '\t';
3279
213
    i++;
3280
213
      }
3281
2.68k
      else if (ch == '\\') {
3282
1.02k
    str[newlength] = '\\';
3283
1.02k
    i++;
3284
1.02k
      }
3285
6.31k
  }
3286
346k
  newlength++;
3287
346k
    }
3288
19.0k
    str[newlength] = '\0';
3289
19.0k
    if (offset != (unsigned int *)NULL)
3290
16.9k
        *offset = i;
3291
19.0k
    return str;
3292
19.0k
}
3293
3294
dsc_private int 
3295
dsc_get_int(const char *line, unsigned int len, unsigned int *offset)
3296
14.8k
{
3297
14.8k
    char newline[MAXSTR];
3298
14.8k
    int newlength = 0;
3299
14.8k
    unsigned int i = 0;
3300
14.8k
    unsigned char ch;
3301
3302
14.8k
    len = min(len, sizeof(newline)-1);
3303
34.0k
    while ((i<len) && IS_WHITE(line[i]))
3304
19.1k
  i++; /* skip leading spaces */
3305
160k
    while (i < len) {
3306
160k
  newline[newlength] = ch = line[i];
3307
160k
  if (!(isdigit(ch) || (ch=='-') || (ch=='+')))
3308
14.6k
      break;  /* not part of an integer number */
3309
145k
  i++;
3310
145k
  newlength++;
3311
145k
    }
3312
98.4k
    while ((i<len) && IS_WHITE(line[i]))
3313
83.6k
  i++; /* skip trailing spaces */
3314
14.8k
    newline[newlength] = '\0';
3315
14.8k
    if (offset != (unsigned int *)NULL)
3316
14.8k
        *offset = i;
3317
14.8k
    return atoi(newline);
3318
14.8k
}
3319
3320
dsc_private float 
3321
dsc_get_real(const char *line, unsigned int len, unsigned int *offset)
3322
18.2k
{
3323
18.2k
    char newline[MAXSTR];
3324
18.2k
    int newlength = 0;
3325
18.2k
    unsigned int i = 0;
3326
18.2k
    unsigned char ch;
3327
3328
18.2k
    len = min(len, sizeof(newline)-1);
3329
105k
    while ((i<len) && IS_WHITE(line[i]))
3330
87.3k
  i++; /* skip leading spaces */
3331
248k
    while (i < len) {
3332
246k
  newline[newlength] = ch = line[i];
3333
246k
  if (!(isdigit(ch) || (ch=='.') || (ch=='-') || (ch=='+') 
3334
59.7k
      || (ch=='e') || (ch=='E')))
3335
16.6k
      break;  /* not part of a real number */
3336
229k
  i++;
3337
229k
  newlength++;
3338
229k
    }
3339
129k
    while ((i<len) && IS_WHITE(line[i]))
3340
111k
  i++; /* skip trailing spaces */
3341
3342
18.2k
    newline[newlength] = '\0';
3343
3344
18.2k
    if (offset != (unsigned int *)NULL)
3345
18.2k
        *offset = i;
3346
18.2k
    return (float)atof(newline);
3347
18.2k
}
3348
3349
dsc_private int
3350
dsc_stricmp(const char *s, const char *t)
3351
138k
{
3352
140k
    while (toupper(*s) == toupper(*t)) {
3353
2.16k
  if (*s == '\0')
3354
296
      return 0;
3355
1.87k
    s++;
3356
1.87k
  t++; 
3357
1.87k
    }
3358
138k
    return (toupper(*s) - toupper(*t));
3359
138k
}
3360
3361
3362
dsc_private int
3363
dsc_parse_page(CDSC *dsc)
3364
8.29k
{
3365
8.29k
    char *p;
3366
8.29k
    unsigned int i;
3367
8.29k
    char page_label[MAXSTR];
3368
8.29k
    char *pl;
3369
8.29k
    int page_ordinal;
3370
8.29k
    int page_number;
3371
3372
8.29k
    p = dsc->line + 7;
3373
8.29k
    pl = dsc_copy_string(page_label, sizeof(page_label)-1, p, dsc->line_length-7, &i);
3374
8.29k
    if (pl == NULL)
3375
0
  return CDSC_ERROR;
3376
8.29k
    p += i;
3377
8.29k
    page_ordinal = atoi(p);
3378
3379
8.29k
    if ( (page_ordinal == 0) || (strlen(page_label) == 0) ||
3380
379
       (dsc->page_count && 
3381
8.09k
      (page_ordinal != dsc->page[dsc->page_count-1].ordinal+1)) ) {
3382
8.09k
  int rc = dsc_error(dsc, CDSC_MESSAGE_PAGE_ORDINAL, dsc->line, 
3383
8.09k
    dsc->line_length);
3384
8.09k
  switch (rc) {
3385
0
      case CDSC_RESPONSE_OK:
3386
    /* ignore this page */
3387
0
    return CDSC_OK;
3388
8.09k
      case CDSC_RESPONSE_CANCEL:
3389
    /* accept the page */
3390
8.09k
    break;
3391
0
      case CDSC_RESPONSE_IGNORE_ALL:
3392
0
    return CDSC_NOTDSC;
3393
8.09k
  }
3394
8.09k
    }
3395
3396
8.29k
    page_number = dsc->page_count;
3397
8.29k
    dsc_add_page(dsc, page_ordinal, page_label);
3398
8.29k
    dsc->page[page_number].begin = DSC_START(dsc);
3399
8.29k
    dsc->page[page_number].end = DSC_START(dsc);
3400
3401
8.29k
    if (dsc->page[page_number].label == NULL)
3402
0
  return CDSC_ERROR; /* no memory */
3403
  
3404
8.29k
    return CDSC_OK;
3405
8.29k
}
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
21.5k
{
3435
    /* if error function provided, use it */
3436
21.5k
    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
21.5k
    return CDSC_RESPONSE_CANCEL;
3442
21.5k
}
3443
3444
3445
// vim:sw=4:sts=4:ts=8:noet