Coverage Report

Created: 2026-02-26 07:48

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