Coverage Report

Created: 2026-10-28 07:09

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