Coverage Report

Created: 2026-03-12 07:14

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