Coverage Report

Created: 2026-01-25 07:18

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