PageRenderTime 44ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/epstool-3.08/src/dscparse.c

#
C | 4598 lines | 3741 code | 313 blank | 544 comment | 1355 complexity | a3c4c56321097b58b651c817c1f23449 MD5 | raw file
Possible License(s): GPL-2.0
  1. /* Copyright (C) 2000-2005, Ghostgum Software Pty Ltd. All rights reserved.
  2. This file is part of GSview.
  3. This program is distributed with NO WARRANTY OF ANY KIND. No author
  4. or distributor accepts any responsibility for the consequences of using it,
  5. or for whether it serves any particular purpose or works at all, unless he
  6. or she says so in writing. Refer to the GSview Licence (the "Licence")
  7. for full details.
  8. Every copy of GSview must include a copy of the Licence, normally in a
  9. plain ASCII text file named LICENCE. The Licence grants you the right
  10. to copy, modify and redistribute GSview, but only under certain conditions
  11. described in the Licence. Among other things, the Licence requires that
  12. the copyright notice and this notice be preserved on all copies.
  13. */
  14. /* $Id: dscparse.c,v 1.36 2005/01/20 11:19:00 ghostgum Exp $ */
  15. /*
  16. * This is a DSC parser, based on the DSC 3.0 spec,
  17. * with a few DSC 2.1 additions for page size.
  18. *
  19. * Current limitations:
  20. * %%+ may be used after any comment in the comment or trailer,
  21. * but is currently only supported by
  22. * %%DocumentMedia
  23. *
  24. * DSC 2.1 additions (discontinued in DSC 3.0):
  25. * %%DocumentPaperColors:
  26. * %%DocumentPaperForms:
  27. * %%DocumentPaperSizes:
  28. * %%DocumentPaperWeights:
  29. * %%PaperColor: (ignored)
  30. * %%PaperForm: (ignored)
  31. * %%PaperSize:
  32. * %%PaperWeight: (ignored)
  33. *
  34. * Other additions for defaults or page section
  35. % %%ViewingOrientation: xx xy yx yy
  36. */
  37. #include <stdio.h> /* for sprintf(), not file I/O */
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <ctype.h>
  41. #define MAXSTR 256
  42. #include "dscparse.h"
  43. /* Macros for comparing string literals
  44. * For maximum speed, the length of the second macro argument is
  45. * computed at compile time.
  46. * THE SECOND MACRO ARGUMENT MUST BE A STRING LITERAL.
  47. */
  48. #define COMPARE(p,str) (strncmp((const char *)(p), (str), sizeof(str)-1)==0)
  49. #define IS_DSC(line, str) (COMPARE((line), (str)))
  50. /* Macros for comparing the first one or two characters */
  51. #define IS_WHITE(ch) (((ch)==' ') || ((ch)=='\t'))
  52. #define IS_EOL(ch) (((ch)=='\r') || ((ch)=='\n'))
  53. #define IS_WHITE_OR_EOL(ch) (IS_WHITE(ch) || IS_EOL(ch))
  54. #define IS_BLANK(str) (IS_EOL(str[0]))
  55. #define NOT_DSC_LINE(str) (((str)[0]!='%') || ((str)[1]!='%'))
  56. /* Macros for document offset to start and end of line */
  57. #define DSC_START(dsc) ((dsc)->data_offset + (dsc)->data_index - (dsc)->line_length)
  58. #define DSC_END(dsc) ((dsc)->data_offset + (dsc)->data_index)
  59. /* dsc_scan_SECTION() functions return one of
  60. * CDSC_ERROR, CDSC_OK, CDSC_NOTDSC
  61. * or one of the following
  62. */
  63. /* The line should be passed on to the next section parser. */
  64. #define CDSC_PROPAGATE 10
  65. /* If document is DOS EPS and we haven't read 30 bytes, ask for more. */
  66. #define CDSC_NEEDMORE 11
  67. /* local prototypes */
  68. dsc_private void * dsc_memalloc(CDSC *dsc, size_t size);
  69. dsc_private void dsc_memfree(CDSC*dsc, void *ptr);
  70. dsc_private CDSC * dsc_init2(CDSC *dsc);
  71. dsc_private void dsc_reset(CDSC *dsc);
  72. dsc_private void dsc_section_join(DSC_OFFSET begin, DSC_OFFSET *pend, DSC_OFFSET **pplast);
  73. dsc_private int dsc_read_line(CDSC *dsc);
  74. dsc_private int dsc_read_doseps(CDSC *dsc);
  75. dsc_private int dsc_read_macbin(CDSC *dsc);
  76. dsc_private int dsc_read_applesingle(CDSC *dsc);
  77. dsc_private char * dsc_alloc_string(CDSC *dsc, const char *str, int len);
  78. dsc_private char * dsc_add_line(CDSC *dsc, const char *line, unsigned int len);
  79. dsc_private char * dsc_copy_string(char *str, unsigned int slen,
  80. char *line, unsigned int len, unsigned int *offset);
  81. dsc_private GSDWORD dsc_get_dword(const unsigned char *buf);
  82. dsc_private GSWORD dsc_get_word(const unsigned char *buf);
  83. dsc_private GSDWORD dsc_get_bigendian_dword(const unsigned char *buf);
  84. dsc_private GSWORD dsc_get_bigendian_word(const unsigned char *buf);
  85. dsc_private int dsc_get_int(const char *line, unsigned int len, unsigned int *offset);
  86. dsc_private float dsc_get_real(const char *line, unsigned int len,
  87. unsigned int *offset);
  88. dsc_private void dsc_unknown(CDSC *dsc);
  89. dsc_private GSBOOL dsc_is_section(char *line);
  90. dsc_private int dsc_parse_pages(CDSC *dsc);
  91. dsc_private int dsc_parse_feature(CDSC *dsc);
  92. dsc_private int dsc_parse_bounding_box(CDSC *dsc, CDSCBBOX** pbbox, int offset);
  93. dsc_private int dsc_parse_float_bounding_box(CDSC *dsc, CDSCFBBOX** pfbbox, int offset);
  94. dsc_private int dsc_parse_orientation(CDSC *dsc, unsigned int *porientation,
  95. int offset);
  96. dsc_private int dsc_parse_order(CDSC *dsc);
  97. dsc_private int dsc_parse_media(CDSC *dsc, const CDSCMEDIA **page_media);
  98. dsc_private int dsc_parse_document_media(CDSC *dsc);
  99. dsc_private int dsc_parse_viewing_orientation(CDSC *dsc, CDSCCTM **pctm);
  100. dsc_private int dsc_parse_page(CDSC *dsc);
  101. dsc_private void dsc_save_line(CDSC *dsc);
  102. dsc_private int dsc_scan_type(CDSC *dsc);
  103. dsc_private int dsc_scan_comments(CDSC *dsc);
  104. dsc_private int dsc_scan_preview(CDSC *dsc);
  105. dsc_private int dsc_scan_defaults(CDSC *dsc);
  106. dsc_private int dsc_scan_prolog(CDSC *dsc);
  107. dsc_private int dsc_scan_setup(CDSC *dsc);
  108. dsc_private int dsc_scan_page(CDSC *dsc);
  109. dsc_private int dsc_scan_trailer(CDSC *dsc);
  110. dsc_private int dsc_error(CDSC *dsc, unsigned int explanation,
  111. char *line, unsigned int line_len);
  112. dsc_private int dsc_dcs2_fixup(CDSC *dsc);
  113. dsc_private int dsc_parse_platefile(CDSC *dsc);
  114. dsc_private int dsc_parse_dcs1plate(CDSC *dsc);
  115. dsc_private CDSCCOLOUR * dsc_find_colour(CDSC *dsc, const char *colourname);
  116. dsc_private int dsc_parse_process_colours(CDSC *dsc);
  117. dsc_private int dsc_parse_custom_colours(CDSC *dsc);
  118. dsc_private int dsc_parse_cmyk_custom_colour(CDSC *dsc);
  119. dsc_private int dsc_parse_rgb_custom_colour(CDSC *dsc);
  120. /* DSC error reporting */
  121. dsc_private const int dsc_severity[] = {
  122. CDSC_ERROR_WARN, /* CDSC_MESSAGE_BBOX */
  123. CDSC_ERROR_WARN, /* CDSC_MESSAGE_EARLY_TRAILER */
  124. CDSC_ERROR_WARN, /* CDSC_MESSAGE_EARLY_EOF */
  125. CDSC_ERROR_ERROR, /* CDSC_MESSAGE_PAGE_IN_TRAILER */
  126. CDSC_ERROR_ERROR, /* CDSC_MESSAGE_PAGE_ORDINAL */
  127. CDSC_ERROR_ERROR, /* CDSC_MESSAGE_PAGES_WRONG */
  128. CDSC_ERROR_ERROR, /* CDSC_MESSAGE_EPS_NO_BBOX */
  129. CDSC_ERROR_ERROR, /* CDSC_MESSAGE_EPS_PAGES */
  130. CDSC_ERROR_WARN, /* CDSC_MESSAGE_NO_MEDIA */
  131. CDSC_ERROR_WARN, /* CDSC_MESSAGE_ATEND */
  132. CDSC_ERROR_INFORM, /* CDSC_MESSAGE_DUP_COMMENT */
  133. CDSC_ERROR_INFORM, /* CDSC_MESSAGE_DUP_TRAILER */
  134. CDSC_ERROR_WARN, /* CDSC_MESSAGE_BEGIN_END */
  135. CDSC_ERROR_INFORM, /* CDSC_MESSAGE_BAD_SECTION */
  136. CDSC_ERROR_INFORM, /* CDSC_MESSAGE_LONG_LINE */
  137. CDSC_ERROR_WARN, /* CDSC_MESSAGE_INCORRECT_USAGE */
  138. 0
  139. };
  140. #define DSC_MAX_ERROR ((sizeof(dsc_severity) / sizeof(int))-2)
  141. const CDSCMEDIA dsc_known_media[CDSC_KNOWN_MEDIA] = {
  142. /* These sizes taken from Ghostscript gs_statd.ps */
  143. {"11x17", 792, 1224, 0, NULL, NULL, NULL},
  144. {"A3", 842, 1190, 0, NULL, NULL, NULL},
  145. {"A4", 595, 842, 0, NULL, NULL, NULL},
  146. {"A5", 421, 595, 0, NULL, NULL, NULL},
  147. {"B4", 709, 1002, 0, NULL, NULL, NULL}, /* ISO, but not Adobe standard */
  148. {"B5", 501, 709, 0, NULL, NULL, NULL}, /* ISO, but not Adobe standard */
  149. {"Ledger", 1224, 792, 0, NULL, NULL, NULL},
  150. {"Legal", 612, 1008, 0, NULL, NULL, NULL},
  151. {"Letter", 612, 792, 0, NULL, NULL, NULL},
  152. {"Note", 612, 792, 0, NULL, NULL, NULL},
  153. /* Other standard sizes */
  154. {"A0", 2384, 3370, 0, NULL, NULL, NULL},
  155. {"A1", 1684, 2384, 0, NULL, NULL, NULL},
  156. {"A2", 1190, 1684, 0, NULL, NULL, NULL},
  157. /* Other non-standard sizes */
  158. {"AnsiA", 612, 792, 0, NULL, NULL, NULL}, /* 8.5 x 11" */
  159. {"AnsiB", 792, 1224, 0, NULL, NULL, NULL}, /* 11 x 17" */
  160. {"AnsiC", 1224, 1584, 0, NULL, NULL, NULL}, /* 17 x 22" */
  161. {"AnsiD", 1584, 2448, 0, NULL, NULL, NULL}, /* 22 x 34" */
  162. {"AnsiE", 2448, 3168, 0, NULL, NULL, NULL}, /* 34 x 44" */
  163. {"ArchA", 648, 864, 0, NULL, NULL, NULL}, /* 9 x 12" */
  164. {"ArchB", 864, 1296, 0, NULL, NULL, NULL}, /* 12 x 18" */
  165. {"ArchC", 1296, 1728, 0, NULL, NULL, NULL}, /* 18 x 24" */
  166. {"ArchD", 1728, 2592, 0, NULL, NULL, NULL}, /* 24 x 36" */
  167. {"ArchE", 2592, 3456, 0, NULL, NULL, NULL}, /* 36 x 48" */
  168. {"ArchF", 2160, 3024, 0, NULL, NULL, NULL}, /* 30 x 42" */
  169. {NULL, 0, 0, 0, NULL, NULL, NULL}
  170. };
  171. /* parser state */
  172. enum CDSC_SCAN_SECTION {
  173. scan_none = 0,
  174. scan_comments = 1,
  175. scan_pre_preview = 2,
  176. scan_preview = 3,
  177. scan_pre_defaults = 4,
  178. scan_defaults = 5,
  179. scan_pre_prolog = 6,
  180. scan_prolog = 7,
  181. scan_pre_setup = 8,
  182. scan_setup = 9,
  183. scan_pre_pages = 10,
  184. scan_pages = 11,
  185. scan_pre_trailer = 12,
  186. scan_trailer = 13,
  187. scan_eof = 14
  188. };
  189. static const char * const dsc_scan_section_name[15] = {
  190. "Type", "Comments",
  191. "pre-Preview", "Preview",
  192. "pre-Defaults", "Defaults",
  193. "pre-Prolog", "Prolog",
  194. "pre-Setup", "Setup",
  195. "pre-Page", "Page",
  196. "pre-Trailer", "Trailer",
  197. "EOF"
  198. };
  199. /******************************************************************/
  200. /* Public functions */
  201. /******************************************************************/
  202. /* constructor */
  203. CDSC *
  204. dsc_init(void *caller_data)
  205. {
  206. CDSC *dsc = (CDSC *)malloc(sizeof(CDSC));
  207. if (dsc == NULL)
  208. return NULL;
  209. memset(dsc, 0, sizeof(CDSC));
  210. dsc->caller_data = caller_data;
  211. dsc->ref_count = 0;
  212. dsc_ref(dsc);
  213. return dsc_init2(dsc);
  214. }
  215. /* constructor, with caller supplied memalloc */
  216. CDSC *
  217. dsc_init_with_alloc(
  218. void *caller_data,
  219. void *(*memalloc)(size_t size, void *closure_data),
  220. void (*memfree)(void *ptr, void *closure_data),
  221. void *closure_data)
  222. {
  223. CDSC *dsc = (CDSC *)memalloc(sizeof(CDSC), closure_data);
  224. if (dsc == NULL)
  225. return NULL;
  226. memset(dsc, 0, sizeof(CDSC));
  227. dsc->caller_data = caller_data;
  228. dsc->memalloc = memalloc;
  229. dsc->memfree = memfree;
  230. dsc->mem_closure_data = closure_data;
  231. dsc->ref_count = 0;
  232. dsc_ref(dsc);
  233. return dsc_init2(dsc);
  234. }
  235. /* destructor */
  236. void
  237. dsc_free(CDSC *dsc)
  238. {
  239. if (dsc == NULL)
  240. return;
  241. dsc_reset(dsc);
  242. dsc_memfree(dsc, dsc);
  243. }
  244. CDSC *
  245. dsc_new(void *caller_data)
  246. {
  247. return dsc_init(caller_data);
  248. }
  249. int
  250. dsc_ref(CDSC *dsc)
  251. {
  252. return ++(dsc->ref_count);
  253. }
  254. int
  255. dsc_unref(CDSC *dsc)
  256. {
  257. if (dsc->ref_count <= 0)
  258. return -1;
  259. dsc->ref_count--;
  260. if (dsc->ref_count == 0) {
  261. dsc_free(dsc);
  262. return 0;
  263. }
  264. return dsc->ref_count;
  265. }
  266. /* Tell DSC parser how long document will be, to allow ignoring
  267. * of early %%Trailer and %%EOF. This is optional.
  268. */
  269. void
  270. dsc_set_length(CDSC *dsc, DSC_OFFSET len)
  271. {
  272. dsc->file_length = len;
  273. }
  274. /* Process a buffer containing DSC comments and PostScript */
  275. /* Return value is < 0 for error, >=0 for OK.
  276. * CDSC_ERROR
  277. * CDSC_OK
  278. * CDSC_NOTDSC (DSC will be ignored)
  279. * other values indicate the last DSC comment read
  280. */
  281. int
  282. dsc_scan_data(CDSC *dsc, const char *data, int length)
  283. {
  284. int bytes_read;
  285. int code = 0;
  286. if (dsc == NULL)
  287. return CDSC_ERROR;
  288. if (dsc->id == CDSC_NOTDSC)
  289. return CDSC_NOTDSC;
  290. dsc->id = CDSC_OK;
  291. if (dsc->eof)
  292. return CDSC_OK; /* ignore */
  293. if (length == 0) {
  294. /* EOF, so process what remains */
  295. dsc->eof = TRUE;
  296. }
  297. do {
  298. if (dsc->id == CDSC_NOTDSC)
  299. break;
  300. if (length != 0) {
  301. /* move existing data if needed */
  302. if (dsc->data_length > CDSC_DATA_LENGTH/2) {
  303. memmove(dsc->data, dsc->data + dsc->data_index,
  304. dsc->data_length - dsc->data_index);
  305. dsc->data_offset += dsc->data_index;
  306. dsc->data_length -= dsc->data_index;
  307. dsc->data_index = 0;
  308. }
  309. /* append to buffer */
  310. bytes_read = min(length, (int)(CDSC_DATA_LENGTH - dsc->data_length));
  311. memcpy(dsc->data + dsc->data_length, data, bytes_read);
  312. dsc->data_length += bytes_read;
  313. data += bytes_read;
  314. length -= bytes_read;
  315. }
  316. if (dsc->scan_section == scan_none) {
  317. code = dsc_scan_type(dsc);
  318. if (code == CDSC_NEEDMORE) {
  319. /* need more characters before we can identify type */
  320. code = CDSC_OK;
  321. break;
  322. }
  323. dsc->id = code;
  324. }
  325. if (code == CDSC_NOTDSC) {
  326. dsc->id = CDSC_NOTDSC;
  327. break;
  328. }
  329. while ((code = dsc_read_line(dsc)) > 0) {
  330. if (dsc->id == CDSC_NOTDSC)
  331. break;
  332. if (dsc->file_length &&
  333. (dsc->data_offset + dsc->data_index > dsc->file_length)) {
  334. /* have read past end of where we need to parse. */
  335. return CDSC_OK; /* ignore */
  336. }
  337. if (dsc->doseps_end &&
  338. (dsc->data_offset + dsc->data_index > dsc->doseps_end)) {
  339. /* have read past end of DOS EPS or Mac Binary
  340. * PostScript section
  341. */
  342. return CDSC_OK; /* ignore */
  343. }
  344. if (dsc->eof)
  345. return CDSC_OK;
  346. if (dsc->skip_document)
  347. continue; /* embedded document */
  348. if (dsc->skip_lines)
  349. continue; /* embedded lines */
  350. if (IS_DSC(dsc->line, "%%BeginData:"))
  351. continue;
  352. if (IS_DSC(dsc->line, "%%BeginBinary:"))
  353. continue;
  354. if (IS_DSC(dsc->line, "%%EndDocument"))
  355. continue;
  356. if (IS_DSC(dsc->line, "%%EndData"))
  357. continue;
  358. if (IS_DSC(dsc->line, "%%EndBinary"))
  359. continue;
  360. do {
  361. switch (dsc->scan_section) {
  362. case scan_comments:
  363. code = dsc_scan_comments(dsc);
  364. break;
  365. case scan_pre_preview:
  366. case scan_preview:
  367. code = dsc_scan_preview(dsc);
  368. break;
  369. case scan_pre_defaults:
  370. case scan_defaults:
  371. code = dsc_scan_defaults(dsc);
  372. break;
  373. case scan_pre_prolog:
  374. case scan_prolog:
  375. code = dsc_scan_prolog(dsc);
  376. break;
  377. case scan_pre_setup:
  378. case scan_setup:
  379. code = dsc_scan_setup(dsc);
  380. break;
  381. case scan_pre_pages:
  382. case scan_pages:
  383. code = dsc_scan_page(dsc);
  384. break;
  385. case scan_pre_trailer:
  386. case scan_trailer:
  387. code = dsc_scan_trailer(dsc);
  388. break;
  389. case scan_eof:
  390. code = CDSC_OK;
  391. break;
  392. default:
  393. /* invalid state */
  394. code = CDSC_ERROR;
  395. }
  396. /* repeat if line is start of next section */
  397. } while (code == CDSC_PROPAGATE);
  398. /* if DOS EPS header not complete, ask for more */
  399. if (code == CDSC_NEEDMORE) {
  400. code = CDSC_OK;
  401. break;
  402. }
  403. if (code == CDSC_NOTDSC) {
  404. dsc->id = CDSC_NOTDSC;
  405. break;
  406. }
  407. }
  408. } while (length != 0);
  409. return (code < 0) ? code : dsc->id;
  410. }
  411. /* Tidy up from incorrect DSC comments */
  412. int
  413. dsc_fixup(CDSC *dsc)
  414. {
  415. unsigned int i;
  416. char buf[32];
  417. DSC_OFFSET *last;
  418. if (dsc->id == CDSC_NOTDSC)
  419. return 0;
  420. /* flush last partial line */
  421. dsc_scan_data(dsc, NULL, 0);
  422. /* Fix DSC error: EOF before end of %%BeginData */
  423. if (dsc->eof &&
  424. (dsc->skip_lines || dsc->skip_bytes || dsc->skip_document)) {
  425. switch (dsc->scan_section) {
  426. case scan_comments:
  427. dsc->endcomments = DSC_END(dsc);
  428. break;
  429. case scan_preview:
  430. dsc->endpreview = DSC_END(dsc);
  431. break;
  432. case scan_defaults:
  433. dsc->enddefaults = DSC_END(dsc);
  434. break;
  435. case scan_prolog:
  436. dsc->endprolog = DSC_END(dsc);
  437. break;
  438. case scan_setup:
  439. dsc->endsetup = DSC_END(dsc);
  440. break;
  441. case scan_pages:
  442. if (dsc->page_count)
  443. dsc->page[dsc->page_count-1].end = DSC_END(dsc);
  444. break;
  445. case scan_trailer:
  446. case scan_eof:
  447. dsc->endtrailer = DSC_END(dsc);
  448. break;
  449. }
  450. }
  451. /* Fix DSC error: code between %%EndSetup and %%Page */
  452. if (dsc->page_count && (dsc->page[0].begin != dsc->endsetup)
  453. && (dsc->endsetup != dsc->beginsetup)) {
  454. dsc->endsetup = dsc->page[0].begin;
  455. dsc_debug_print(dsc, "Warning: code included between setup and first page\n");
  456. }
  457. /* Last page contained a false trailer, */
  458. /* so extend last page to start of trailer */
  459. if (dsc->page_count && (dsc->begintrailer != 0) &&
  460. (dsc->page[dsc->page_count-1].end != dsc->begintrailer)) {
  461. dsc_debug_print(dsc, "Ignoring earlier misplaced trailer\n");
  462. dsc_debug_print(dsc, "and extending last page to start of trailer\n");
  463. dsc->page[dsc->page_count-1].end = dsc->begintrailer;
  464. }
  465. /*
  466. * Join up all sections.
  467. * There might be extra code between them, or we might have
  468. * missed including the \n which followed \r.
  469. */
  470. last = &dsc->endcomments;
  471. dsc_section_join(dsc->beginpreview, &dsc->endpreview, &last);
  472. dsc_section_join(dsc->begindefaults, &dsc->enddefaults, &last);
  473. dsc_section_join(dsc->beginprolog, &dsc->endprolog, &last);
  474. dsc_section_join(dsc->beginsetup, &dsc->endsetup, &last);
  475. for (i=0; i<dsc->page_count; i++)
  476. dsc_section_join(dsc->page[i].begin, &dsc->page[i].end, &last);
  477. if (dsc->begintrailer)
  478. *last = dsc->begintrailer;
  479. 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. dsc->page_pages = dsc->page_count;
  483. }
  484. /* Warnings and Errors that we can now identify */
  485. if ((dsc->page_count != dsc->page_pages)) {
  486. int rc = dsc_error(dsc, CDSC_MESSAGE_PAGES_WRONG, NULL, 0);
  487. switch (rc) {
  488. case CDSC_RESPONSE_OK:
  489. /* adjust incorrect page count */
  490. dsc->page_pages = dsc->page_count;
  491. break;
  492. case CDSC_RESPONSE_CANCEL:
  493. break;;
  494. case CDSC_RESPONSE_IGNORE_ALL:
  495. return CDSC_NOTDSC;
  496. }
  497. }
  498. if (dsc->epsf && (dsc->bbox == (CDSCBBOX *)NULL)) {
  499. /* EPS files MUST include a BoundingBox */
  500. int rc = dsc_error(dsc, CDSC_MESSAGE_EPS_NO_BBOX, NULL, 0);
  501. switch (rc) {
  502. case CDSC_RESPONSE_OK:
  503. /* Assume that it is EPS */
  504. break;
  505. case CDSC_RESPONSE_CANCEL:
  506. /* Is NOT an EPS file */
  507. dsc->epsf = FALSE;
  508. case CDSC_RESPONSE_IGNORE_ALL:
  509. return CDSC_NOTDSC;
  510. }
  511. }
  512. if (dsc->epsf && ((dsc->page_count > 1) || (dsc->page_pages > 1))) {
  513. int rc = dsc_error(dsc, CDSC_MESSAGE_EPS_PAGES, NULL, 0);
  514. switch (rc) {
  515. case CDSC_RESPONSE_OK:
  516. /* Is an EPS file */
  517. break;
  518. case CDSC_RESPONSE_CANCEL:
  519. /* Is NOT an EPS file */
  520. dsc->epsf = FALSE;
  521. break;
  522. case CDSC_RESPONSE_IGNORE_ALL:
  523. return CDSC_NOTDSC;
  524. }
  525. }
  526. /* convert single file DSC 2.0 into multiple pages */
  527. dsc_dcs2_fixup(dsc);
  528. if ((dsc->media_count == 1) && (dsc->page_media == NULL)) {
  529. /* if one only media was specified, and default page media */
  530. /* was not specified, assume that default is the only media. */
  531. dsc->page_media = dsc->media[0];
  532. }
  533. if ((dsc->media_count != 0) && (dsc->page_media == NULL)) {
  534. int rc = dsc_error(dsc, CDSC_MESSAGE_NO_MEDIA, NULL, 0);
  535. switch (rc) {
  536. case CDSC_RESPONSE_OK:
  537. /* default media is first listed */
  538. dsc->page_media = dsc->media[0];
  539. break;
  540. case CDSC_RESPONSE_CANCEL:
  541. /* No default media */
  542. break;
  543. case CDSC_RESPONSE_IGNORE_ALL:
  544. return CDSC_NOTDSC;
  545. }
  546. }
  547. /* make sure all pages have a label */
  548. for (i=0; i<dsc->page_count; i++) {
  549. if (strlen(dsc->page[i].label) == 0) {
  550. sprintf(buf, "%d", i+1);
  551. if ((dsc->page[i].label = dsc_alloc_string(dsc, buf, (int)strlen(buf)))
  552. == (char *)NULL)
  553. return CDSC_ERROR; /* no memory */
  554. }
  555. }
  556. return CDSC_OK;
  557. }
  558. /* Install a function to be used for displaying messages about
  559. * DSC errors and warnings, and to request advice from user.
  560. * Installing an error function is optional.
  561. */
  562. void
  563. dsc_set_error_function(CDSC *dsc,
  564. int (*fn)(void *caller_data, CDSC *dsc,
  565. unsigned int explanation, const char *line, unsigned int line_len))
  566. {
  567. dsc->dsc_error_fn = fn;
  568. }
  569. /* Install a function for printing debug messages */
  570. /* This is optional */
  571. void
  572. dsc_set_debug_function(CDSC *dsc,
  573. void (*debug_fn)(void *caller_data, const char *str))
  574. {
  575. dsc->debug_print_fn = debug_fn;
  576. }
  577. /* Doesn't need to be public for PostScript documents */
  578. /* Made public so GSview can add pages when processing PDF files */
  579. int
  580. dsc_add_page(CDSC *dsc, int ordinal, char *label)
  581. {
  582. dsc->page[dsc->page_count].ordinal = ordinal;
  583. dsc->page[dsc->page_count].label =
  584. dsc_alloc_string(dsc, label, (int)strlen(label)+1);
  585. dsc->page[dsc->page_count].begin = 0;
  586. dsc->page[dsc->page_count].end = 0;
  587. dsc->page[dsc->page_count].orientation = CDSC_ORIENT_UNKNOWN;
  588. dsc->page[dsc->page_count].media = NULL;
  589. dsc->page[dsc->page_count].bbox = NULL;
  590. dsc->page[dsc->page_count].viewing_orientation = NULL;
  591. dsc->page[dsc->page_count].crop_box = NULL;
  592. dsc->page_count++;
  593. if (dsc->page_count >= dsc->page_chunk_length) {
  594. CDSCPAGE *new_page = (CDSCPAGE *)dsc_memalloc(dsc,
  595. (CDSC_PAGE_CHUNK+dsc->page_count) * sizeof(CDSCPAGE));
  596. if (new_page == NULL)
  597. return CDSC_ERROR; /* out of memory */
  598. memcpy(new_page, dsc->page,
  599. dsc->page_count * sizeof(CDSCPAGE));
  600. dsc_memfree(dsc, dsc->page);
  601. dsc->page= new_page;
  602. dsc->page_chunk_length = CDSC_PAGE_CHUNK+dsc->page_count;
  603. }
  604. return CDSC_OK;
  605. }
  606. /* Doesn't need to be public for PostScript documents */
  607. /* Made public so GSview can store PDF MediaBox */
  608. int
  609. dsc_add_media(CDSC *dsc, CDSCMEDIA *media)
  610. {
  611. CDSCMEDIA **newmedia_array;
  612. CDSCMEDIA *newmedia;
  613. /* extend media array */
  614. newmedia_array = (CDSCMEDIA **)dsc_memalloc(dsc,
  615. (dsc->media_count + 1) * sizeof(CDSCMEDIA *));
  616. if (newmedia_array == NULL)
  617. return CDSC_ERROR; /* out of memory */
  618. if (dsc->media != NULL) {
  619. memcpy(newmedia_array, dsc->media,
  620. dsc->media_count * sizeof(CDSCMEDIA *));
  621. dsc_memfree(dsc, dsc->media);
  622. }
  623. dsc->media = newmedia_array;
  624. /* allocate new media */
  625. newmedia = dsc->media[dsc->media_count] =
  626. (CDSCMEDIA *)dsc_memalloc(dsc, sizeof(CDSCMEDIA));
  627. if (newmedia == NULL)
  628. return CDSC_ERROR; /* out of memory */
  629. newmedia->name = NULL;
  630. newmedia->width = 595.0;
  631. newmedia->height = 842.0;
  632. newmedia->weight = 80.0;
  633. newmedia->colour = NULL;
  634. newmedia->type = NULL;
  635. newmedia->mediabox = NULL;
  636. dsc->media_count++;
  637. if (media->name) {
  638. newmedia->name = dsc_alloc_string(dsc, media->name,
  639. (int)strlen(media->name));
  640. if (newmedia->name == NULL)
  641. return CDSC_ERROR; /* no memory */
  642. }
  643. newmedia->width = media->width;
  644. newmedia->height = media->height;
  645. newmedia->weight = media->weight;
  646. if (media->colour) {
  647. newmedia->colour = dsc_alloc_string(dsc, media->colour,
  648. (int)strlen(media->colour));
  649. if (newmedia->colour == NULL)
  650. return CDSC_ERROR; /* no memory */
  651. }
  652. if (media->type) {
  653. newmedia->type = dsc_alloc_string(dsc, media->type,
  654. (int)strlen(media->type));
  655. if (newmedia->type == NULL)
  656. return CDSC_ERROR; /* no memory */
  657. }
  658. newmedia->mediabox = NULL;
  659. if (media->mediabox) {
  660. newmedia->mediabox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
  661. if (newmedia->mediabox == NULL)
  662. return CDSC_ERROR; /* no memory */
  663. *newmedia->mediabox = *media->mediabox;
  664. }
  665. return CDSC_OK;
  666. }
  667. /* Doesn't need to be public for PostScript documents */
  668. /* Made public so GSview can store PDF CropBox */
  669. int
  670. dsc_set_page_bbox(CDSC *dsc, unsigned int page_number,
  671. int llx, int lly, int urx, int ury)
  672. {
  673. CDSCBBOX *bbox;
  674. if (page_number >= dsc->page_count)
  675. return CDSC_ERROR;
  676. bbox = dsc->page[page_number].bbox;
  677. if (bbox == NULL)
  678. dsc->page[page_number].bbox = bbox =
  679. (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
  680. if (bbox == NULL)
  681. return CDSC_ERROR;
  682. bbox->llx = llx;
  683. bbox->lly = lly;
  684. bbox->urx = urx;
  685. bbox->ury = ury;
  686. return CDSC_OK;
  687. }
  688. /******************************************************************/
  689. /* Private functions below here. */
  690. /******************************************************************/
  691. dsc_private void *
  692. dsc_memalloc(CDSC *dsc, size_t size)
  693. {
  694. if (dsc->memalloc)
  695. return dsc->memalloc(size, dsc->mem_closure_data);
  696. return malloc(size);
  697. }
  698. dsc_private void
  699. dsc_memfree(CDSC*dsc, void *ptr)
  700. {
  701. if (dsc->memfree)
  702. dsc->memfree(ptr, dsc->mem_closure_data);
  703. else
  704. free(ptr);
  705. }
  706. /* private constructor */
  707. dsc_private CDSC *
  708. dsc_init2(CDSC *dsc)
  709. {
  710. dsc_reset(dsc);
  711. dsc->string_head = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
  712. if (dsc->string_head == NULL) {
  713. dsc_free(dsc);
  714. return NULL; /* no memory */
  715. }
  716. dsc->string = dsc->string_head;
  717. dsc->string->next = NULL;
  718. dsc->string->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
  719. if (dsc->string->data == NULL) {
  720. dsc_free(dsc);
  721. return NULL; /* no memory */
  722. }
  723. dsc->string->index = 0;
  724. dsc->string->length = CDSC_STRING_CHUNK;
  725. dsc->page = (CDSCPAGE *)dsc_memalloc(dsc, CDSC_PAGE_CHUNK * sizeof(CDSCPAGE));
  726. if (dsc->page == NULL) {
  727. dsc_free(dsc);
  728. return NULL; /* no memory */
  729. }
  730. dsc->page_chunk_length = CDSC_PAGE_CHUNK;
  731. dsc->page_count = 0;
  732. dsc->line = NULL;
  733. dsc->data_length = 0;
  734. dsc->data_index = dsc->data_length;
  735. return dsc;
  736. }
  737. dsc_private void
  738. dsc_reset(CDSC *dsc)
  739. {
  740. unsigned int i;
  741. /* Clear public members */
  742. dsc->dsc = FALSE;
  743. dsc->ctrld = FALSE;
  744. dsc->pjl = FALSE;
  745. dsc->epsf = FALSE;
  746. dsc->pdf = FALSE;
  747. dsc->epsf = FALSE;
  748. dsc->preview = CDSC_NOPREVIEW;
  749. dsc->dsc_version = NULL; /* stored in dsc->string */
  750. dsc->language_level = 0;
  751. dsc->document_data = CDSC_DATA_UNKNOWN;
  752. dsc->begincomments = 0;
  753. dsc->endcomments = 0;
  754. dsc->beginpreview = 0;
  755. dsc->endpreview = 0;
  756. dsc->begindefaults = 0;
  757. dsc->enddefaults = 0;
  758. dsc->beginprolog = 0;
  759. dsc->endprolog = 0;
  760. dsc->beginsetup = 0;
  761. dsc->endsetup = 0;
  762. dsc->begintrailer = 0;
  763. dsc->endtrailer = 0;
  764. for (i=0; i<dsc->page_count; i++) {
  765. /* page media is pointer to an element of media or dsc_known_media */
  766. /* do not free it. */
  767. if (dsc->page[i].bbox)
  768. dsc_memfree(dsc, dsc->page[i].bbox);
  769. if (dsc->page[i].viewing_orientation)
  770. dsc_memfree(dsc, dsc->page[i].viewing_orientation);
  771. if (dsc->page[i].crop_box)
  772. dsc_memfree(dsc, dsc->page[i].crop_box);
  773. }
  774. if (dsc->page)
  775. dsc_memfree(dsc, dsc->page);
  776. dsc->page = NULL;
  777. dsc->page_count = 0;
  778. dsc->page_pages = 0;
  779. dsc->page_order = CDSC_ORDER_UNKNOWN;
  780. dsc->page_orientation = CDSC_ORIENT_UNKNOWN;
  781. if (dsc->viewing_orientation)
  782. dsc_memfree(dsc, dsc->viewing_orientation);
  783. dsc->viewing_orientation = NULL;
  784. if (dsc->media) {
  785. for (i=0; i<dsc->media_count; i++) {
  786. if (dsc->media[i]) {
  787. if (dsc->media[i]->mediabox)
  788. dsc_memfree(dsc, dsc->media[i]->mediabox);
  789. dsc_memfree(dsc, dsc->media[i]);
  790. }
  791. }
  792. dsc_memfree(dsc, dsc->media);
  793. }
  794. dsc->media_count = 0;
  795. dsc->media = NULL;
  796. /* page_media is pointer to an element of media or dsc_known_media */
  797. /* do not free it. */
  798. dsc->page_media = NULL;
  799. if (dsc->bbox)
  800. dsc_memfree(dsc, dsc->bbox);
  801. dsc->bbox = NULL;
  802. if (dsc->page_bbox)
  803. dsc_memfree(dsc, dsc->page_bbox);
  804. dsc->page_bbox = NULL;
  805. if (dsc->doseps)
  806. dsc_memfree(dsc, dsc->doseps);
  807. dsc->doseps = NULL;
  808. dsc->dsc_title = NULL;
  809. dsc->dsc_creator = NULL;
  810. dsc->dsc_date = NULL;
  811. dsc->dsc_for = NULL;
  812. dsc->max_error = DSC_MAX_ERROR;
  813. dsc->severity = dsc_severity;
  814. /* Clear private members */
  815. /* Don't touch dsc->caller_data */
  816. dsc->id = CDSC_OK;
  817. dsc->scan_section = scan_none;
  818. dsc->doseps_end = 0;
  819. dsc->page_chunk_length = 0;
  820. dsc->file_length = 0;
  821. dsc->skip_document = 0;
  822. dsc->skip_bytes = 0;
  823. dsc->skip_lines = 0;
  824. dsc->skip_pjl = 0;
  825. dsc->begin_font_count = 0;
  826. dsc->begin_feature_count = 0;
  827. dsc->begin_resource_count = 0;
  828. dsc->begin_procset_count = 0;
  829. dsc->data_length = 0;
  830. dsc->data_index = 0;
  831. dsc->data_offset = 0;
  832. dsc->eof = 0;
  833. dsc->line = 0;
  834. dsc->line_length = 0;
  835. dsc->eol = 0;
  836. dsc->last_cr = FALSE;
  837. dsc->line_count = 1;
  838. dsc->long_line = FALSE;
  839. memset(dsc->last_line, 0, sizeof(dsc->last_line));
  840. dsc->string = dsc->string_head;
  841. while (dsc->string != (CDSCSTRING *)NULL) {
  842. if (dsc->string->data)
  843. dsc_memfree(dsc, dsc->string->data);
  844. dsc->string_head = dsc->string;
  845. dsc->string = dsc->string->next;
  846. dsc_memfree(dsc, dsc->string_head);
  847. }
  848. dsc->string_head = NULL;
  849. dsc->string = NULL;
  850. /* don't touch caller functions */
  851. /* public data */
  852. if (dsc->hires_bbox)
  853. dsc_memfree(dsc, dsc->hires_bbox);
  854. dsc->hires_bbox = NULL;
  855. if (dsc->crop_box)
  856. dsc_memfree(dsc, dsc->crop_box);
  857. dsc->crop_box = NULL;
  858. if (dsc->dcs2) {
  859. CDCS2 *this_dcs, *next_dcs;
  860. this_dcs = dsc->dcs2;
  861. while (this_dcs) {
  862. next_dcs = this_dcs->next;
  863. /* strings have already been freed */
  864. dsc_memfree(dsc, this_dcs);
  865. this_dcs = next_dcs;
  866. }
  867. dsc->dcs2 = NULL;
  868. }
  869. if (dsc->colours) {
  870. CDSCCOLOUR *this_colour, *next_colour;
  871. this_colour = dsc->colours;
  872. while (this_colour) {
  873. next_colour = this_colour->next;
  874. /* strings have already been freed */
  875. dsc_memfree(dsc, this_colour);
  876. this_colour = next_colour;
  877. }
  878. dsc->colours = NULL;
  879. }
  880. if (dsc->macbin)
  881. dsc_memfree(dsc, dsc->macbin);
  882. dsc->macbin = NULL;
  883. dsc->worst_error = CDSC_ERROR_NONE;
  884. }
  885. /*
  886. * Join up all sections.
  887. * There might be extra code between them, or we might have
  888. * missed including the \n which followed \r.
  889. * begin is the start of this section
  890. * pend is a pointer to the end of this section
  891. * pplast is a pointer to a pointer of the end of the previous section
  892. */
  893. dsc_private void
  894. dsc_section_join(DSC_OFFSET begin, DSC_OFFSET *pend, DSC_OFFSET **pplast)
  895. {
  896. if (begin)
  897. **pplast = begin;
  898. if (*pend > begin)
  899. *pplast = pend;
  900. }
  901. /* return value is 0 if no line available, or length of line */
  902. dsc_private int
  903. dsc_read_line(CDSC *dsc)
  904. {
  905. char *p, *last;
  906. dsc->line = NULL;
  907. if (dsc->eof) {
  908. /* return all that remains, even if line incomplete */
  909. dsc->line = dsc->data + dsc->data_index;
  910. dsc->line_length = dsc->data_length - dsc->data_index;
  911. dsc->data_index = dsc->data_length;
  912. return dsc->line_length;
  913. }
  914. if (dsc->file_length &&
  915. (dsc->data_offset + dsc->data_index >= dsc->file_length)) {
  916. /* Have read past where we need to parse. */
  917. /* Ignore all that remains. */
  918. dsc->line = dsc->data + dsc->data_index;
  919. dsc->line_length = dsc->data_length - dsc->data_index;
  920. dsc->data_index = dsc->data_length;
  921. return dsc->line_length;
  922. }
  923. if (dsc->doseps_end &&
  924. (dsc->data_offset + dsc->data_index >= dsc->doseps_end)) {
  925. /* Have read past end of DOS EPS PostScript section. */
  926. /* Ignore all that remains. */
  927. dsc->line = dsc->data + dsc->data_index;
  928. dsc->line_length = dsc->data_length - dsc->data_index;
  929. dsc->data_index = dsc->data_length;
  930. return dsc->line_length;
  931. }
  932. /* ignore embedded bytes */
  933. if (dsc->skip_bytes) {
  934. int cnt = min(dsc->skip_bytes,
  935. (int)(dsc->data_length - dsc->data_index));
  936. dsc->skip_bytes -= cnt;
  937. dsc->data_index += cnt;
  938. if (dsc->skip_bytes != 0)
  939. return 0;
  940. }
  941. do {
  942. dsc->line = dsc->data + dsc->data_index;
  943. last = dsc->data + dsc->data_length;
  944. if (dsc->data_index == dsc->data_length) {
  945. dsc->line_length = 0;
  946. return 0;
  947. }
  948. if (dsc->eol) {
  949. /* if previous line was complete, increment line count */
  950. dsc->line_count++;
  951. if (dsc->skip_lines)
  952. dsc->skip_lines--;
  953. }
  954. /* skip over \n which followed \r */
  955. if (dsc->last_cr && dsc->line[0] == '\n') {
  956. dsc->data_index++;
  957. dsc->line++;
  958. }
  959. dsc->last_cr = FALSE;
  960. /* look for EOL */
  961. dsc->eol = FALSE;
  962. for (p = dsc->line; p < last; p++) {
  963. if (*p == '\r') {
  964. p++;
  965. if ((p<last) && (*p == '\n'))
  966. p++; /* include line feed also */
  967. else
  968. dsc->last_cr = TRUE; /* we might need to skip \n */
  969. dsc->eol = TRUE; /* dsc->line is a complete line */
  970. break;
  971. }
  972. if (*p == '\n') {
  973. p++;
  974. dsc->eol = TRUE; /* dsc->line is a complete line */
  975. break;
  976. }
  977. if (*p == '\032') { /* MS-DOS Ctrl+Z */
  978. dsc->eol = TRUE;
  979. }
  980. }
  981. if (dsc->eol == FALSE) {
  982. /* we haven't got a complete line yet */
  983. if (dsc->data_length - dsc->data_index < sizeof(dsc->data)/2) {
  984. /* buffer is less than half full, ask for some more */
  985. dsc->line_length = 0;
  986. return 0;
  987. }
  988. }
  989. dsc->data_index += dsc->line_length = (int)(p - dsc->line);
  990. } while (dsc->skip_lines && dsc->line_length);
  991. if (dsc->line_length == 0)
  992. return 0;
  993. if ((dsc->line[0]=='%') && (dsc->line[1]=='%')) {
  994. /* handle recursive %%BeginDocument */
  995. if ((dsc->skip_document) && dsc->line_length &&
  996. COMPARE(dsc->line, "%%EndDocument")) {
  997. dsc->skip_document--;
  998. }
  999. /* handle embedded lines or binary data */
  1000. if (COMPARE(dsc->line, "%%BeginData:")) {
  1001. /* %%BeginData: <numberof>[ <type> [ <bytesorlines> ] ]
  1002. * <numberof> ::= <uint> (Lines or physical bytes)
  1003. * <type> ::= Hex | Binary | ASCII (Type of data)
  1004. * <bytesorlines> ::= Bytes | Lines (Read in bytes or lines)
  1005. */
  1006. char begindata[MAXSTR+1];
  1007. int cnt;
  1008. const char *numberof, *bytesorlines;
  1009. cnt = dsc->line_length;
  1010. if (dsc->line_length > sizeof(begindata)-1)
  1011. cnt = sizeof(begindata)-1;
  1012. memcpy(begindata, dsc->line, cnt);
  1013. begindata[cnt] = '\0';
  1014. numberof = strtok(begindata+12, " \r\n");
  1015. strtok(NULL, " \r\n"); /* dump type */
  1016. bytesorlines = strtok(NULL, " \r\n");
  1017. if (bytesorlines == NULL)
  1018. bytesorlines = "Bytes";
  1019. if ( (numberof == NULL) || (bytesorlines == NULL) ) {
  1020. /* invalid usage of %%BeginData */
  1021. /* ignore that we ever saw it */
  1022. int rc = dsc_error(dsc, CDSC_MESSAGE_INCORRECT_USAGE,
  1023. dsc->line, dsc->line_length);
  1024. switch (rc) {
  1025. case CDSC_RESPONSE_OK:
  1026. case CDSC_RESPONSE_CANCEL:
  1027. break;
  1028. case CDSC_RESPONSE_IGNORE_ALL:
  1029. return 0;
  1030. }
  1031. }
  1032. else {
  1033. cnt = atoi(numberof);
  1034. if (cnt) {
  1035. if (bytesorlines && (dsc_stricmp(bytesorlines, "Lines")==0)) {
  1036. /* skip cnt lines */
  1037. if (dsc->skip_lines == 0) {
  1038. /* we are not already skipping lines */
  1039. dsc->skip_lines = cnt+1;
  1040. }
  1041. }
  1042. else {
  1043. /* byte count doesn't includes \n or \r\n */
  1044. /* or \r of %%BeginData: */
  1045. /* skip cnt bytes */
  1046. if (dsc->skip_bytes == 0) {
  1047. /* we are not already skipping lines */
  1048. dsc->skip_bytes = cnt;
  1049. }
  1050. }
  1051. }
  1052. }
  1053. }
  1054. else if (COMPARE(dsc->line, "%%BeginBinary:")) {
  1055. /* byte count doesn't includes \n or \r\n or \r of %%BeginBinary:*/
  1056. int cnt = dsc_get_int(dsc->line + 14,
  1057. dsc->line_length - 14, NULL);
  1058. if (dsc->skip_bytes == 0) {
  1059. /* we are not already skipping lines */
  1060. dsc->skip_bytes = cnt;
  1061. }
  1062. }
  1063. }
  1064. if ((dsc->line[0]=='%') && (dsc->line[1]=='%') &&
  1065. COMPARE(dsc->line, "%%BeginDocument:") ) {
  1066. /* Skip over embedded document, recursively */
  1067. dsc->skip_document++;
  1068. }
  1069. if (!dsc->long_line && (dsc->line_length > DSC_LINE_LENGTH)) {
  1070. dsc_error(dsc, CDSC_MESSAGE_LONG_LINE, dsc->line, dsc->line_length);
  1071. dsc->long_line = TRUE;
  1072. }
  1073. return dsc->line_length;
  1074. }
  1075. /* Save last DSC line, for use with %%+ */
  1076. dsc_private void
  1077. dsc_save_line(CDSC *dsc)
  1078. {
  1079. int len = min(sizeof(dsc->last_line), dsc->line_length);
  1080. memcpy(dsc->last_line, dsc->line, len);
  1081. }
  1082. /* display unknown DSC line */
  1083. dsc_private void
  1084. dsc_unknown(CDSC *dsc)
  1085. {
  1086. if (dsc->debug_print_fn) {
  1087. char line[DSC_LINE_LENGTH];
  1088. unsigned int length = min(DSC_LINE_LENGTH-1, dsc->line_length);
  1089. sprintf(line, "Unknown in %s section at line %d:\n ",
  1090. dsc_scan_section_name[dsc->scan_section], dsc->line_count);
  1091. dsc_debug_print(dsc, line);
  1092. strncpy(line, dsc->line, length);
  1093. line[length] = '\0';
  1094. dsc_debug_print(dsc, line);
  1095. dsc_debug_print(dsc, "\n");
  1096. }
  1097. }
  1098. dsc_private GSBOOL
  1099. dsc_is_section(char *line)
  1100. {
  1101. if ( !((line[0]=='%') && (line[1]=='%')) )
  1102. return FALSE;
  1103. if (IS_DSC(line, "%%BeginPreview"))
  1104. return TRUE;
  1105. if (IS_DSC(line, "%%BeginDefaults"))
  1106. return TRUE;
  1107. if (IS_DSC(line, "%%BeginProlog"))
  1108. return TRUE;
  1109. if (IS_DSC(line, "%%BeginSetup"))
  1110. return TRUE;
  1111. if (IS_DSC(line, "%%Page:"))
  1112. return TRUE;
  1113. if (IS_DSC(line, "%%Trailer"))
  1114. return TRUE;
  1115. if (IS_DSC(line, "%%EOF"))
  1116. return TRUE;
  1117. return FALSE;
  1118. }
  1119. /* Get little-endian DWORD, used for DOS EPS files */
  1120. dsc_private GSDWORD
  1121. dsc_get_dword(const unsigned char *buf)
  1122. {
  1123. GSDWORD dw;
  1124. dw = (GSDWORD)buf[0];
  1125. dw += ((GSDWORD)buf[1])<<8;
  1126. dw += ((GSDWORD)buf[2])<<16;
  1127. dw += ((GSDWORD)buf[3])<<24;
  1128. return dw;
  1129. }
  1130. dsc_private GSWORD
  1131. dsc_get_word(const unsigned char *buf)
  1132. {
  1133. GSWORD w;
  1134. w = (GSWORD)buf[0];
  1135. w |= (GSWORD)(buf[1]<<8);
  1136. return w;
  1137. }
  1138. /* Get big-endian DWORD, used for Mac Binary files */
  1139. dsc_private GSDWORD
  1140. dsc_get_bigendian_dword(const unsigned char *buf)
  1141. {
  1142. GSDWORD dw;
  1143. dw = (GSDWORD)buf[3];
  1144. dw += ((GSDWORD)buf[2])<<8;
  1145. dw += ((GSDWORD)buf[1])<<16;
  1146. dw += ((GSDWORD)buf[0])<<24;
  1147. return dw;
  1148. }
  1149. dsc_private GSWORD
  1150. dsc_get_bigendian_word(const unsigned char *buf)
  1151. {
  1152. GSWORD w;
  1153. w = (GSWORD)buf[1];
  1154. w |= (GSWORD)(buf[0]<<8);
  1155. return w;
  1156. }
  1157. dsc_private int
  1158. dsc_read_doseps(CDSC *dsc)
  1159. {
  1160. unsigned char *line = (unsigned char *)dsc->line;
  1161. if ((dsc->doseps = (CDSCDOSEPS *)dsc_memalloc(dsc, sizeof(CDSCDOSEPS))) == NULL)
  1162. return CDSC_ERROR; /* no memory */
  1163. dsc->doseps->ps_begin = dsc_get_dword(line+4);
  1164. dsc->doseps->ps_length = dsc_get_dword(line+8);
  1165. dsc->doseps->wmf_begin = dsc_get_dword(line+12);
  1166. dsc->doseps->wmf_length = dsc_get_dword(line+16);
  1167. dsc->doseps->tiff_begin = dsc_get_dword(line+20);
  1168. dsc->doseps->tiff_length = dsc_get_dword(line+24);
  1169. dsc->doseps->checksum = dsc_get_word(line+28);
  1170. if (dsc->file_length &&
  1171. (dsc->doseps->ps_begin + dsc->doseps->ps_length > dsc->file_length)) {
  1172. /* Error in DOS EPS header.
  1173. * Some files have been seen with a fixed large value as
  1174. * the length of the PostScript section.
  1175. * Correct for these erroneous files.
  1176. */
  1177. dsc->doseps->ps_length =
  1178. (GSDWORD)(dsc->file_length - dsc->doseps->ps_begin);
  1179. }
  1180. dsc->doseps_end = dsc->doseps->ps_begin + dsc->doseps->ps_length;
  1181. /* move data_index backwards to byte after doseps header */
  1182. dsc->data_index -= dsc->line_length - 30;
  1183. /* we haven't read a line of PostScript code yet */
  1184. dsc->line_count = 0;
  1185. /* skip from current position to start of PostScript section */
  1186. dsc->skip_bytes = dsc->doseps->ps_begin - 30;
  1187. if (dsc->doseps->tiff_begin)
  1188. dsc->preview = CDSC_TIFF;
  1189. if (dsc->doseps->wmf_begin)
  1190. dsc->preview = CDSC_WMF;
  1191. return CDSC_OK;
  1192. }
  1193. dsc_private int
  1194. dsc_read_macbin(CDSC *dsc)
  1195. {
  1196. unsigned char *line = (unsigned char *)dsc->line;
  1197. if ((dsc->macbin =
  1198. (CDSCMACBIN *)dsc_memalloc(dsc, sizeof(CDSCMACBIN))) == NULL)
  1199. return CDSC_ERROR; /* no memory */
  1200. dsc->macbin->data_begin = 128;
  1201. dsc->macbin->data_length = dsc_get_bigendian_dword(line+83);
  1202. dsc->macbin->resource_begin =
  1203. (dsc->macbin->data_begin + dsc->macbin->data_length + 127 ) & ~127;
  1204. dsc->macbin->resource_length = dsc_get_bigendian_dword(line+87);
  1205. /* A MacBinary file has been seen that doesn't have the resource
  1206. * fork padded out to 128 bytes. Just make sure that the resource
  1207. * doesn't extend beyond EOF.
  1208. */
  1209. if (dsc->file_length &&
  1210. (((dsc->macbin->resource_begin + dsc->macbin->resource_length
  1211. /* + 127 */ ) /* & ~127 */ ) > dsc->file_length)) {
  1212. return CDSC_ERROR;
  1213. }
  1214. dsc->doseps_end = dsc->macbin->data_begin + dsc->macbin->data_length;
  1215. /* move data_index to byte after Mac Binary header */
  1216. dsc->data_index -= dsc->line_length - 128;
  1217. /* we haven't read a line of PostScript code yet */
  1218. dsc->line_count = 0;
  1219. dsc->preview = CDSC_PICT;
  1220. return CDSC_OK;
  1221. }
  1222. dsc_private int
  1223. dsc_read_applesingle(CDSC *dsc)
  1224. {
  1225. GSDWORD EntryID;
  1226. GSDWORD Offset;
  1227. GSDWORD Length;
  1228. GSWORD entries;
  1229. int index;
  1230. int header;
  1231. int i;
  1232. unsigned char *line = (unsigned char *)dsc->line;
  1233. if ((dsc->macbin =
  1234. (CDSCMACBIN *)dsc_memalloc(dsc, sizeof(CDSCMACBIN))) == NULL)
  1235. return CDSC_ERROR; /* no memory */
  1236. entries = dsc_get_bigendian_word(line+24);
  1237. for (i=0; i<(int)entries; i++) {
  1238. index = 26 + i * 12;
  1239. EntryID = dsc_get_bigendian_dword(line+index);
  1240. Offset = dsc_get_bigendian_dword(line+index+4);
  1241. Length = dsc_get_bigendian_dword(line+index+8);
  1242. if (EntryID == 1) {
  1243. /* data fork */
  1244. dsc->macbin->data_begin = Offset;
  1245. dsc->macbin->data_length = Length;
  1246. }
  1247. else if (EntryID == 2) {
  1248. /* resource fork */
  1249. dsc->macbin->resource_begin = Offset;
  1250. dsc->macbin->resource_length = Length;
  1251. }
  1252. }
  1253. if (dsc->file_length &&
  1254. (dsc->macbin->resource_begin + dsc->macbin->resource_length
  1255. > dsc->file_length)) {
  1256. return CDSC_ERROR;
  1257. }
  1258. if (dsc->file_length &&
  1259. (dsc->macbin->data_begin + dsc->macbin->data_length
  1260. > dsc->file_length)) {
  1261. return CDSC_ERROR;
  1262. }
  1263. dsc->doseps_end = dsc->macbin->data_begin + dsc->macbin->data_length;
  1264. header = 26 + entries * 12;
  1265. /* move data_index to byte after AppleSingle/AppleDouble header */
  1266. dsc->data_index -= dsc->line_length - header;
  1267. /* we haven't read a line of PostScript code yet */
  1268. dsc->line_count = 0;
  1269. /* skip from current position to start of PostScript section */
  1270. dsc->skip_bytes = dsc->macbin->data_begin - header;
  1271. dsc->preview = CDSC_PICT;
  1272. return CDSC_OK;
  1273. }
  1274. dsc_private int
  1275. dsc_parse_pages(CDSC *dsc)
  1276. {
  1277. int ip, io;
  1278. unsigned int i;
  1279. char *p;
  1280. int n;
  1281. if ((dsc->page_pages != 0) && (dsc->scan_section == scan_comments)) {
  1282. int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
  1283. dsc->line_length);
  1284. switch (rc) {
  1285. case CDSC_RESPONSE_OK:
  1286. case CDSC_RESPONSE_CANCEL:
  1287. return CDSC_OK; /* ignore duplicate comments in header */
  1288. case CDSC_RESPONSE_IGNORE_ALL:
  1289. return CDSC_NOTDSC;
  1290. }
  1291. }
  1292. if ((dsc->page_pages != 0) && (dsc->scan_section == scan_trailer)) {
  1293. int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line,
  1294. dsc->line_length);
  1295. switch (rc) {
  1296. case CDSC_RESPONSE_OK:
  1297. case CDSC_RESPONSE_CANCEL:
  1298. break; /* use duplicate comments in header */
  1299. case CDSC_RESPONSE_IGNORE_ALL:
  1300. return CDSC_NOTDSC;
  1301. }
  1302. }
  1303. n = IS_DSC(dsc->line, "%%+") ? 3 : 8;
  1304. while (IS_WHITE(dsc->line[n]))
  1305. n++;
  1306. p = dsc->line + n;
  1307. if (COMPARE(p, "atend")) {
  1308. if (dsc->scan_section != scan_comments)
  1309. dsc_unknown(dsc);
  1310. else {
  1311. int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND,
  1312. dsc->line, dsc->line_length);
  1313. switch (rc) {
  1314. case CDSC_RESPONSE_OK:
  1315. /* assume (atend) */
  1316. /* we should mark it as deferred */
  1317. break;
  1318. case CDSC_RESPONSE_CANCEL:
  1319. /* ignore it */
  1320. break;
  1321. case CDSC_RESPONSE_IGNORE_ALL:
  1322. return CDSC_NOTDSC;
  1323. }
  1324. }
  1325. }
  1326. else if (COMPARE(p, "(atend)")) {
  1327. if (dsc->scan_section != scan_comments)
  1328. dsc_unknown(dsc);
  1329. /* do nothing */
  1330. /* we should mark it as deferred */
  1331. }
  1332. else {
  1333. ip = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
  1334. if (i) {
  1335. n+=i;
  1336. dsc->page_pages = ip;
  1337. io = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
  1338. if (i) {
  1339. /* DSC 2 uses extra integer to indicate page order */
  1340. /* DSC 3 uses %%PageOrder: */
  1341. if (dsc->page_order == CDSC_ORDER_UNKNOWN)
  1342. switch (io) {
  1343. case -1:
  1344. dsc->page_order = CDSC_DESCEND;
  1345. break;
  1346. case 0:
  1347. dsc->page_order = CDSC_SPECIAL;
  1348. break;
  1349. case 1:
  1350. dsc->page_order = CDSC_ASCEND;
  1351. break;
  1352. }
  1353. }
  1354. }
  1355. else {
  1356. int rc = dsc_error(dsc, CDSC_MESSAGE_INCORRECT_USAGE, dsc->line,
  1357. dsc->line_length);
  1358. switch (rc) {
  1359. case CDSC_RESPONSE_OK:
  1360. case CDSC_RESPONSE_CANCEL:
  1361. /* ignore it */
  1362. break;
  1363. case CDSC_RESPONSE_IGNORE_ALL:
  1364. return CDSC_NOTDSC;
  1365. }
  1366. }
  1367. }
  1368. return CDSC_OK;
  1369. }
  1370. dsc_private int
  1371. dsc_parse_bounding_box(CDSC *dsc, CDSCBBOX** pbbox, int offset)
  1372. {
  1373. unsigned int i, n;
  1374. int llx, lly, urx, ury;
  1375. float fllx, flly, furx, fury;
  1376. char *p;
  1377. /* Process first %%BoundingBox: in comments, and last in trailer */
  1378. if ((*pbbox != NULL) && (dsc->scan_section == scan_comments)) {
  1379. int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
  1380. dsc->line_length);
  1381. switch (rc) {
  1382. case CDSC_RESPONSE_OK:
  1383. case CDSC_RESPONSE_CANCEL:
  1384. return CDSC_OK; /* ignore duplicate comments in header */
  1385. case CDSC_RESPONSE_IGNORE_ALL:
  1386. return CDSC_NOTDSC;
  1387. }
  1388. }
  1389. if ((*pbbox != NULL) && (dsc->scan_section == scan_pages)) {
  1390. int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
  1391. dsc->line_length);
  1392. switch (rc) {
  1393. case CDSC_RESPONSE_OK:
  1394. case CDSC_RESPONSE_CANCEL:
  1395. return CDSC_OK; /* ignore duplicate comments in header */
  1396. case CDSC_RESPONSE_IGNORE_ALL:
  1397. return CDSC_NOTDSC;
  1398. }
  1399. }
  1400. if ((*pbbox != NULL) && (dsc->scan_section == scan_trailer)) {
  1401. int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line,
  1402. dsc->line_length);
  1403. switch (rc) {
  1404. case CDSC_RESPONSE_OK:
  1405. case CDSC_RESPONSE_CANCEL:
  1406. break; /* use duplicate comments in trailer */
  1407. case CDSC_RESPONSE_IGNORE_ALL:
  1408. return CDSC_NOTDSC;
  1409. }
  1410. }
  1411. if (*pbbox != NULL) {
  1412. dsc_memfree(dsc, *pbbox);
  1413. *pbbox = NULL;
  1414. }
  1415. /* should only process first %%BoundingBox: */
  1416. while (IS_WHITE(dsc->line[offset]))
  1417. offset++;
  1418. p = dsc->line + offset;
  1419. if (COMPARE(p, "atend")) {
  1420. if (dsc->scan_section == scan_trailer)
  1421. dsc_unknown(dsc);
  1422. else {
  1423. int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line,
  1424. dsc->line_length);
  1425. switch (rc) {
  1426. case CDSC_RESPONSE_OK:
  1427. /* assume (atend) */
  1428. /* we should mark it as deferred */
  1429. break;
  1430. case CDSC_RESPONSE_CANCEL:
  1431. /* ignore it */
  1432. break;
  1433. case CDSC_RESPONSE_IGNORE_ALL:
  1434. return CDSC_NOTDSC;
  1435. }
  1436. }
  1437. }
  1438. else if (COMPARE(p, "(atend)")) {
  1439. if (dsc->scan_section == scan_trailer)
  1440. dsc_unknown(dsc);
  1441. /* do nothing */
  1442. /* we should mark it as deferred */
  1443. }
  1444. else {
  1445. /* llx = */ lly = urx = ury = 0;
  1446. n = offset;
  1447. llx = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
  1448. n += i;
  1449. if (i)
  1450. lly = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
  1451. n += i;
  1452. if (i)
  1453. urx = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
  1454. n += i;
  1455. if (i)
  1456. ury = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
  1457. if (i) {
  1458. *pbbox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
  1459. if (*pbbox == NULL)
  1460. return CDSC_ERROR; /* no memory */
  1461. (*pbbox)->llx = llx;
  1462. (*pbbox)->lly = lly;
  1463. (*pbbox)->urx = urx;
  1464. (*pbbox)->ury = ury;
  1465. }
  1466. else {
  1467. int rc = dsc_error(dsc, CDSC_MESSAGE_BBOX, dsc->line,
  1468. dsc->line_length);
  1469. switch (rc) {
  1470. case CDSC_RESPONSE_OK:
  1471. /* fllx = */ flly = furx = fury = 0.0;
  1472. n = offset;
  1473. n += i;
  1474. fllx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1475. n += i;
  1476. if (i)
  1477. flly = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1478. n += i;
  1479. if (i)
  1480. furx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1481. n += i;
  1482. if (i)
  1483. fury = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1484. if (i) {
  1485. *pbbox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
  1486. if (*pbbox == NULL)
  1487. return CDSC_ERROR; /* no memory */
  1488. (*pbbox)->llx = (int)fllx;
  1489. (*pbbox)->lly = (int)flly;
  1490. (*pbbox)->urx = (int)(furx+0.999);
  1491. (*pbbox)->ury = (int)(fury+0.999);
  1492. }
  1493. return CDSC_OK;
  1494. case CDSC_RESPONSE_CANCEL:
  1495. return CDSC_OK;
  1496. case CDSC_RESPONSE_IGNORE_ALL:
  1497. return CDSC_NOTDSC;
  1498. }
  1499. }
  1500. }
  1501. return CDSC_OK;
  1502. }
  1503. dsc_private int
  1504. dsc_parse_float_bounding_box(CDSC *dsc, CDSCFBBOX** pbbox, int offset)
  1505. {
  1506. unsigned int i, n;
  1507. float fllx, flly, furx, fury;
  1508. char *p;
  1509. /* Process first %%HiResBoundingBox: or %%CropBox: in comments,
  1510. * and last in trailer.
  1511. */
  1512. if ((*pbbox != NULL) && (dsc->scan_section == scan_comments)) {
  1513. int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
  1514. dsc->line_length);
  1515. switch (rc) {
  1516. case CDSC_RESPONSE_OK:
  1517. case CDSC_RESPONSE_CANCEL:
  1518. return CDSC_OK; /* ignore duplicate comments in header */
  1519. case CDSC_RESPONSE_IGNORE_ALL:
  1520. return CDSC_NOTDSC;
  1521. }
  1522. }
  1523. if ((*pbbox != NULL) && (dsc->scan_section == scan_pages)) {
  1524. int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
  1525. dsc->line_length);
  1526. switch (rc) {
  1527. case CDSC_RESPONSE_OK:
  1528. case CDSC_RESPONSE_CANCEL:
  1529. return CDSC_OK; /* ignore duplicate comments in header */
  1530. case CDSC_RESPONSE_IGNORE_ALL:
  1531. return CDSC_NOTDSC;
  1532. }
  1533. }
  1534. if ((*pbbox != NULL) && (dsc->scan_section == scan_trailer)) {
  1535. int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line,
  1536. dsc->line_length);
  1537. switch (rc) {
  1538. case CDSC_RESPONSE_OK:
  1539. case CDSC_RESPONSE_CANCEL:
  1540. break; /* use duplicate comments in trailer */
  1541. case CDSC_RESPONSE_IGNORE_ALL:
  1542. return CDSC_NOTDSC;
  1543. }
  1544. }
  1545. if (*pbbox != NULL) {
  1546. dsc_memfree(dsc, *pbbox);
  1547. *pbbox = NULL;
  1548. }
  1549. /* should only process first %%BoundingBox: */
  1550. while (IS_WHITE(dsc->line[offset]))
  1551. offset++;
  1552. p = dsc->line + offset;
  1553. if (COMPARE(p, "atend")) {
  1554. if (dsc->scan_section == scan_trailer)
  1555. dsc_unknown(dsc);
  1556. else {
  1557. int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line,
  1558. dsc->line_length);
  1559. switch (rc) {
  1560. case CDSC_RESPONSE_OK:
  1561. /* assume (atend) */
  1562. /* we should mark it as deferred */
  1563. break;
  1564. case CDSC_RESPONSE_CANCEL:
  1565. /* ignore it */
  1566. break;
  1567. case CDSC_RESPONSE_IGNORE_ALL:
  1568. return CDSC_NOTDSC;
  1569. }
  1570. }
  1571. }
  1572. else if (COMPARE(p, "(atend)")) {
  1573. if (dsc->scan_section == scan_trailer)
  1574. dsc_unknown(dsc);
  1575. /* do nothing */
  1576. /* we should mark it as deferred */
  1577. }
  1578. else {
  1579. /* fllx = */ flly = furx = fury = 0.0;
  1580. n = offset;
  1581. fllx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1582. n += i;
  1583. if (i)
  1584. flly = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1585. n += i;
  1586. if (i)
  1587. furx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1588. n += i;
  1589. if (i)
  1590. fury = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1591. if (i) {
  1592. *pbbox = (CDSCFBBOX *)dsc_memalloc(dsc, sizeof(CDSCFBBOX));
  1593. if (*pbbox == NULL)
  1594. return CDSC_ERROR; /* no memory */
  1595. (*pbbox)->fllx = fllx;
  1596. (*pbbox)->flly = flly;
  1597. (*pbbox)->furx = furx;
  1598. (*pbbox)->fury = fury;
  1599. }
  1600. }
  1601. return CDSC_OK;
  1602. }
  1603. dsc_private int
  1604. dsc_parse_orientation(CDSC *dsc, unsigned int *porientation, int offset)
  1605. {
  1606. char *p;
  1607. if ((dsc->page_orientation != CDSC_ORIENT_UNKNOWN) &&
  1608. (dsc->scan_section == scan_comments)) {
  1609. int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
  1610. dsc->line_length);
  1611. switch (rc) {
  1612. case CDSC_RESPONSE_OK:
  1613. case CDSC_RESPONSE_CANCEL:
  1614. return CDSC_OK; /* ignore duplicate comments in header */
  1615. case CDSC_RESPONSE_IGNORE_ALL:
  1616. return CDSC_NOTDSC;
  1617. }
  1618. }
  1619. if ((dsc->page_orientation != CDSC_ORIENT_UNKNOWN) &&
  1620. (dsc->scan_section == scan_trailer)) {
  1621. int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line,
  1622. dsc->line_length);
  1623. switch (rc) {
  1624. case CDSC_RESPONSE_OK:
  1625. case CDSC_RESPONSE_CANCEL:
  1626. break; /* use duplicate comments in header; */
  1627. case CDSC_RESPONSE_IGNORE_ALL:
  1628. return CDSC_NOTDSC;
  1629. }
  1630. }
  1631. p = dsc->line + offset;
  1632. while (IS_WHITE(*p))
  1633. p++;
  1634. if (COMPARE(p, "atend")) {
  1635. if (dsc->scan_section == scan_trailer)
  1636. dsc_unknown(dsc);
  1637. else {
  1638. int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND,
  1639. dsc->line, dsc->line_length);
  1640. switch (rc) {
  1641. case CDSC_RESPONSE_OK:
  1642. /* assume (atend) */
  1643. /* we should mark it as deferred */
  1644. break;
  1645. case CDSC_RESPONSE_CANCEL:
  1646. /* ignore it */
  1647. break;
  1648. case CDSC_RESPONSE_IGNORE_ALL:
  1649. return CDSC_NOTDSC;
  1650. }
  1651. }
  1652. }
  1653. else if (COMPARE(p, "(atend)")) {
  1654. if (dsc->scan_section == scan_trailer)
  1655. dsc_unknown(dsc);
  1656. /* do nothing */
  1657. /* we should mark it as deferred */
  1658. }
  1659. else if (COMPARE(p, "Portrait")) {
  1660. *porientation = CDSC_PORTRAIT;
  1661. }
  1662. else if (COMPARE(p, "Landscape")) {
  1663. *porientation = CDSC_LANDSCAPE;
  1664. }
  1665. else {
  1666. dsc_unknown(dsc);
  1667. }
  1668. return CDSC_OK;
  1669. }
  1670. dsc_private int
  1671. dsc_parse_order(CDSC *dsc)
  1672. {
  1673. char *p;
  1674. if ((dsc->page_order != CDSC_ORDER_UNKNOWN) &&
  1675. (dsc->scan_section == scan_comments)) {
  1676. int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
  1677. dsc->line_length);
  1678. switch (rc) {
  1679. case CDSC_RESPONSE_OK:
  1680. case CDSC_RESPONSE_CANCEL:
  1681. return CDSC_OK; /* ignore duplicate comments in header */
  1682. case CDSC_RESPONSE_IGNORE_ALL:
  1683. return CDSC_NOTDSC;
  1684. }
  1685. }
  1686. if ((dsc->page_order != CDSC_ORDER_UNKNOWN) &&
  1687. (dsc->scan_section == scan_trailer)) {
  1688. int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line,
  1689. dsc->line_length);
  1690. switch (rc) {
  1691. case CDSC_RESPONSE_OK:
  1692. case CDSC_RESPONSE_CANCEL:
  1693. break; /* use duplicate comments in trailer */
  1694. case CDSC_RESPONSE_IGNORE_ALL:
  1695. return CDSC_NOTDSC;
  1696. }
  1697. }
  1698. p = dsc->line + (IS_DSC(dsc->line, "%%+") ? 3 : 13);
  1699. while (IS_WHITE(*p))
  1700. p++;
  1701. if (COMPARE(p, "atend")) {
  1702. if (dsc->scan_section == scan_trailer)
  1703. dsc_unknown(dsc);
  1704. else {
  1705. int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line,
  1706. dsc->line_length);
  1707. switch (rc) {
  1708. case CDSC_RESPONSE_OK:
  1709. /* assume (atend) */
  1710. /* we should mark it as deferred */
  1711. break;
  1712. case CDSC_RESPONSE_CANCEL:
  1713. /* ignore it */
  1714. break;
  1715. case CDSC_RESPONSE_IGNORE_ALL:
  1716. return CDSC_NOTDSC;
  1717. }
  1718. }
  1719. }
  1720. else if (COMPARE(p, "(atend)")) {
  1721. if (dsc->scan_section == scan_trailer)
  1722. dsc_unknown(dsc);
  1723. /* do nothing */
  1724. /* we should mark it as deferred */
  1725. }
  1726. else if (COMPARE(p, "Ascend")) {
  1727. dsc->page_order = CDSC_ASCEND;
  1728. }
  1729. else if (COMPARE(p, "Descend")) {
  1730. dsc->page_order = CDSC_DESCEND;
  1731. }
  1732. else if (COMPARE(p, "Special")) {
  1733. dsc->page_order = CDSC_SPECIAL;
  1734. }
  1735. else {
  1736. dsc_unknown(dsc);
  1737. }
  1738. return CDSC_OK;
  1739. }
  1740. dsc_private int
  1741. dsc_parse_media(CDSC *dsc, const CDSCMEDIA **page_media)
  1742. {
  1743. char media_name[MAXSTR];
  1744. int n = IS_DSC(dsc->line, "%%+") ? 3 : 12; /* %%PageMedia: */
  1745. unsigned int i;
  1746. if (dsc_copy_string(media_name, sizeof(media_name)-1,
  1747. dsc->line+n, dsc->line_length-n, NULL)) {
  1748. for (i=0; i<dsc->media_count; i++) {
  1749. if (dsc->media[i]->name &&
  1750. (dsc_stricmp(media_name, dsc->media[i]->name) == 0)) {
  1751. *page_media = dsc->media[i];
  1752. return CDSC_OK;
  1753. }
  1754. }
  1755. }
  1756. dsc_unknown(dsc);
  1757. return CDSC_OK;
  1758. }
  1759. dsc_private int
  1760. dsc_parse_document_media(CDSC *dsc)
  1761. {
  1762. unsigned int i, n;
  1763. CDSCMEDIA lmedia;
  1764. GSBOOL blank_line;
  1765. if (IS_DSC(dsc->line, "%%DocumentMedia:"))
  1766. n = 16;
  1767. else if (IS_DSC(dsc->line, "%%+"))
  1768. n = 3;
  1769. else
  1770. return CDSC_ERROR; /* error */
  1771. /* check for blank remainder of line */
  1772. blank_line = TRUE;
  1773. for (i=n; i<dsc->line_length; i++) {
  1774. if (!IS_WHITE_OR_EOL(dsc->line[i])) {
  1775. blank_line = FALSE;
  1776. break;
  1777. }
  1778. }
  1779. if (!blank_line) {
  1780. char name[MAXSTR];
  1781. char colour[MAXSTR];
  1782. char type[MAXSTR];
  1783. lmedia.name = lmedia.colour = lmedia.type = (char *)NULL;
  1784. lmedia.width = lmedia.height = lmedia.weight = 0;
  1785. lmedia.mediabox = (CDSCBBOX *)NULL;
  1786. lmedia.name = dsc_copy_string(name, sizeof(name),
  1787. dsc->line+n, dsc->line_length-n, &i);
  1788. n+=i;
  1789. if (i)
  1790. lmedia.width = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1791. n+=i;
  1792. if (i)
  1793. lmedia.height = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1794. n+=i;
  1795. if (i)
  1796. lmedia.weight = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1797. n+=i;
  1798. if (i)
  1799. lmedia.colour = dsc_copy_string(colour, sizeof(colour),
  1800. dsc->line+n, dsc->line_length-n, &i);
  1801. n+=i;
  1802. if (i)
  1803. lmedia.type = dsc_copy_string(type, sizeof(type),
  1804. dsc->line+n, dsc->line_length-n, &i);
  1805. if (i==0)
  1806. dsc_unknown(dsc); /* we didn't get all fields */
  1807. else {
  1808. if (dsc_add_media(dsc, &lmedia))
  1809. return CDSC_ERROR; /* out of memory */
  1810. }
  1811. }
  1812. return CDSC_OK;
  1813. }
  1814. /* viewing orientation is believed to be the first four elements of
  1815. * a CTM matrix
  1816. */
  1817. dsc_private int
  1818. dsc_parse_viewing_orientation(CDSC *dsc, CDSCCTM **pctm)
  1819. {
  1820. CDSCCTM ctm;
  1821. unsigned int i, n;
  1822. if (*pctm != NULL) {
  1823. dsc_memfree(dsc, *pctm);
  1824. *pctm = NULL;
  1825. }
  1826. n = IS_DSC(dsc->line, "%%+") ? 3 : 21; /* %%ViewingOrientation: */
  1827. while (IS_WHITE(dsc->line[n]))
  1828. n++;
  1829. /* ctm.xx = */ ctm.xy = ctm.yx = ctm.yy = 0.0;
  1830. ctm.xx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1831. n += i;
  1832. if (i)
  1833. ctm.xy = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1834. n += i;
  1835. if (i)
  1836. ctm.yx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1837. n += i;
  1838. if (i)
  1839. ctm.yy = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  1840. if (i==0) {
  1841. dsc_unknown(dsc); /* we didn't get all fields */
  1842. }
  1843. else {
  1844. *pctm = (CDSCCTM *)dsc_memalloc(dsc, sizeof(CDSCCTM));
  1845. if (*pctm == NULL)
  1846. return CDSC_ERROR; /* no memory */
  1847. **pctm = ctm;
  1848. }
  1849. return CDSC_OK;
  1850. }
  1851. /* This is called before dsc_read_line(), since we may
  1852. * need to skip a binary header which contains a new line
  1853. * character
  1854. */
  1855. dsc_private int
  1856. dsc_scan_type(CDSC *dsc)
  1857. {
  1858. unsigned char *p;
  1859. unsigned char *line = (unsigned char *)(dsc->data + dsc->data_index);
  1860. int length = dsc->data_length - dsc->data_index;
  1861. /* Types that should be known:
  1862. * DSC
  1863. * EPSF
  1864. * PJL + any of above
  1865. * ^D + any of above
  1866. * DOS EPS
  1867. * PDF
  1868. * non-DSC
  1869. */
  1870. /* First process any non PostScript headers */
  1871. /* At this stage we do not have a complete line */
  1872. if (length == 0)
  1873. return CDSC_NEEDMORE;
  1874. /* If we have already found a DOS EPS header, */
  1875. /* ignore all until the PostScript section */
  1876. if (dsc->skip_bytes) {
  1877. int cnt = min(dsc->skip_bytes,
  1878. (int)(dsc->data_length - dsc->data_index));
  1879. dsc->skip_bytes -= cnt;
  1880. dsc->data_index += cnt;
  1881. length -= cnt;
  1882. line += cnt;
  1883. if (dsc->skip_bytes != 0)
  1884. return CDSC_NEEDMORE;
  1885. }
  1886. if (dsc->skip_pjl) {
  1887. /* skip until first PostScript comment */
  1888. while (length >= 2) {
  1889. while (length && !IS_EOL(line[0])) {
  1890. /* skip until EOL character */
  1891. line++;
  1892. dsc->data_index++;
  1893. length--;
  1894. }
  1895. while ((length >= 2) && IS_EOL(line[0]) && IS_EOL(line[1])) {
  1896. /* skip until EOL followed by non-EOL */
  1897. line++;
  1898. dsc->data_index++;
  1899. length--;
  1900. }
  1901. if (length < 2)
  1902. return CDSC_NEEDMORE;
  1903. if (IS_EOL(line[0]) && line[1]=='%') {
  1904. line++;
  1905. dsc->data_index++;
  1906. length--;
  1907. dsc->skip_pjl = FALSE;
  1908. break;
  1909. }
  1910. else {
  1911. line++;
  1912. dsc->data_index++;
  1913. length--;
  1914. }
  1915. }
  1916. if (dsc->skip_pjl)
  1917. return CDSC_NEEDMORE;
  1918. }
  1919. if (length == 0)
  1920. return CDSC_NEEDMORE;
  1921. if (line[0] == '\004') {
  1922. line++;
  1923. dsc->data_index++;
  1924. length--;
  1925. dsc->ctrld = TRUE;
  1926. }
  1927. if (line[0] == '\033') {
  1928. /* possibly PJL */
  1929. if (length < 9)
  1930. return CDSC_NEEDMORE;
  1931. if (COMPARE(line, "\033%-12345X")) {
  1932. dsc->skip_pjl = TRUE; /* skip until first PostScript comment */
  1933. dsc->pjl = TRUE;
  1934. dsc->data_index += 9;
  1935. return dsc_scan_type(dsc);
  1936. }
  1937. }
  1938. if ((line[0]==0x0) && (length < 2))
  1939. return CDSC_NEEDMORE; /* Could be Mac Binary EPSF */
  1940. if ((line[0]==0x0) && (line[1] >= 1) && (line[1] <= 63) && (length < 128))
  1941. return CDSC_NEEDMORE; /* Could be Mac Binary EPSF */
  1942. if ((line[0]==0x0) && (line[1] == 0x5) && (length < 4))
  1943. return CDSC_NEEDMORE; /* Could be Mac AppleSingle/AppleDouble */
  1944. if ((line[0]==0xc5) && (length < 4))
  1945. return CDSC_NEEDMORE; /* Could be DOS EPS */
  1946. if ((line[0]==0xc5) && (line[1]==0xd0) &&
  1947. (line[2]==0xd3) && (line[3]==0xc6) ) {
  1948. /* id is "EPSF" with bit 7 set */
  1949. /* read DOS EPS header, then ignore all bytes until the PS section */
  1950. if (length < 30)
  1951. return CDSC_NEEDMORE;
  1952. dsc->line = (char *)line;
  1953. if (dsc_read_doseps(dsc))
  1954. return CDSC_ERROR;
  1955. }
  1956. else if ((line[0]==0x0) && (line[1]==0x05) &&
  1957. (line[2]==0x16) && ((line[3]==0x0) || (line[3] == 0x07))) {
  1958. /* Mac AppleSingle or AppleDouble */
  1959. GSDWORD version;
  1960. GSWORD entries;
  1961. if (length < 26)
  1962. return CDSC_NEEDMORE;
  1963. version = dsc_get_bigendian_dword(line+4);
  1964. entries = dsc_get_bigendian_word(line+24);
  1965. if ((version == 0x00010000) || (version == 0x00020000)) {
  1966. if (length < (int)(26 + entries * 12))
  1967. return CDSC_NEEDMORE;
  1968. dsc->line = (char *)line;
  1969. if (dsc_read_applesingle(dsc))
  1970. return CDSC_ERROR;
  1971. }
  1972. }
  1973. else if ((line[0]==0x0) &&
  1974. (line[1] >= 1) && (line[1] <= 63) &&
  1975. (line[74]==0x0) &&
  1976. (line[65]=='E') && (line[66]=='P') &&
  1977. (line[67]=='S') && (line[68]=='F')) {
  1978. /* Mac Binary EPSF */
  1979. dsc->line = (char *)line;
  1980. if (dsc_read_macbin(dsc))
  1981. return CDSC_ERROR;
  1982. }
  1983. else {
  1984. if (length < 2)
  1985. return CDSC_NEEDMORE;
  1986. if ((line[0] == '%') && (line[1] == 'P')) {
  1987. if (length < 5)
  1988. return CDSC_NEEDMORE;
  1989. if (COMPARE(line, "%PDF-")) {
  1990. dsc->pdf = TRUE;
  1991. dsc->scan_section = scan_comments;
  1992. return CDSC_OK;
  1993. }
  1994. }
  1995. }
  1996. /* Finally process PostScript headers */
  1997. if (dsc_read_line(dsc) <= 0)
  1998. return CDSC_NEEDMORE;
  1999. dsc->dsc_version = dsc_add_line(dsc, dsc->line, dsc->line_length);
  2000. if (COMPARE(dsc->line, "%!PS-Adobe")) {
  2001. dsc->dsc = TRUE;
  2002. dsc->begincomments = DSC_START(dsc);
  2003. if (dsc->dsc_version == NULL)
  2004. return CDSC_ERROR; /* no memory */
  2005. p = (unsigned char *)dsc->line + 14;
  2006. while (IS_WHITE(*p))
  2007. p++;
  2008. if (COMPARE(p, "EPSF-"))
  2009. dsc->epsf = TRUE;
  2010. dsc->scan_section = scan_comments;
  2011. return CDSC_PSADOBE;
  2012. }
  2013. if (COMPARE(dsc->line, "%!")) {
  2014. dsc->scan_section = scan_comments;
  2015. return CDSC_NOTDSC;
  2016. }
  2017. dsc->scan_section = scan_comments;
  2018. return CDSC_NOTDSC; /* unrecognised */
  2019. }
  2020. dsc_private int
  2021. dsc_scan_comments(CDSC *dsc)
  2022. {
  2023. /* Comments section ends at */
  2024. /* %%EndComments */
  2025. /* another section */
  2026. /* line that does not start with %% */
  2027. /* Save a few important lines */
  2028. char *line = dsc->line;
  2029. GSBOOL continued = FALSE;
  2030. dsc->id = CDSC_OK;
  2031. if (IS_DSC(line, "%%EndComments")) {
  2032. dsc->id = CDSC_ENDCOMMENTS;
  2033. dsc->endcomments = DSC_END(dsc);
  2034. dsc->scan_section = scan_pre_preview;
  2035. return CDSC_OK;
  2036. }
  2037. else if (IS_DSC(line, "%%BeginComments")) {
  2038. /* ignore because we are in this section */
  2039. dsc->id = CDSC_BEGINCOMMENTS;
  2040. }
  2041. else if (dsc_is_section(line)) {
  2042. dsc->endcomments = DSC_START(dsc);
  2043. dsc->scan_section = scan_pre_preview;
  2044. return CDSC_PROPAGATE;
  2045. }
  2046. else if (line[0] == '%' && IS_WHITE_OR_EOL(line[1])) {
  2047. dsc->endcomments = DSC_START(dsc);
  2048. dsc->scan_section = scan_pre_preview;
  2049. return CDSC_PROPAGATE;
  2050. }
  2051. else if (line[0] != '%') {
  2052. dsc->id = CDSC_OK;
  2053. dsc->endcomments = DSC_START(dsc);
  2054. dsc->scan_section = scan_pre_preview;
  2055. return CDSC_PROPAGATE;
  2056. }
  2057. else if (IS_DSC(line, "%%Begin")) {
  2058. dsc->endcomments = DSC_START(dsc);
  2059. dsc->scan_section = scan_pre_preview;
  2060. return CDSC_PROPAGATE;
  2061. }
  2062. /* Handle continuation lines.
  2063. * To simply processing, we assume that contination lines
  2064. * will only occur if repeat parameters are allowed and that
  2065. * a complete set of these parameters appears on each line.
  2066. * This is more restrictive than the DSC specification, but
  2067. * is valid for the DSC comments understood by this parser
  2068. * for all documents that we have seen.
  2069. */
  2070. if (IS_DSC(line, "%%+")) {
  2071. line = dsc->last_line;
  2072. continued = TRUE;
  2073. }
  2074. else
  2075. dsc_save_line(dsc);
  2076. if (IS_DSC(line, "%%Pages:")) {
  2077. dsc->id = CDSC_PAGES;
  2078. if (dsc_parse_pages(dsc) != 0)
  2079. return CDSC_ERROR;
  2080. }
  2081. else if (IS_DSC(line, "%%Creator:")) {
  2082. dsc->id = CDSC_CREATOR;
  2083. dsc->dsc_creator = dsc_add_line(dsc, dsc->line+10, dsc->line_length-10);
  2084. if (dsc->dsc_creator==NULL)
  2085. return CDSC_ERROR;
  2086. }
  2087. else if (IS_DSC(line, "%%CreationDate:")) {
  2088. dsc->id = CDSC_CREATIONDATE;
  2089. dsc->dsc_date = dsc_add_line(dsc, dsc->line+15, dsc->line_length-15);
  2090. if (dsc->dsc_date==NULL)
  2091. return CDSC_ERROR;
  2092. }
  2093. else if (IS_DSC(line, "%%Title:")) {
  2094. dsc->id = CDSC_TITLE;
  2095. dsc->dsc_title = dsc_add_line(dsc, dsc->line+8, dsc->line_length-8);
  2096. if (dsc->dsc_title==NULL)
  2097. return CDSC_ERROR;
  2098. }
  2099. else if (IS_DSC(line, "%%For:")) {
  2100. dsc->id = CDSC_FOR;
  2101. dsc->dsc_for = dsc_add_line(dsc, dsc->line+6, dsc->line_length-6);
  2102. if (dsc->dsc_for==NULL)
  2103. return CDSC_ERROR;
  2104. }
  2105. else if (IS_DSC(line, "%%LanguageLevel:")) {
  2106. unsigned int n = continued ? 3 : 16;
  2107. unsigned int i;
  2108. int ll;
  2109. dsc->id = CDSC_LANGUAGELEVEL;
  2110. ll = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
  2111. if (i) {
  2112. if ( (ll==1) || (ll==2) || (ll==3) )
  2113. dsc->language_level = ll;
  2114. else {
  2115. dsc_unknown(dsc);
  2116. }
  2117. }
  2118. else
  2119. dsc_unknown(dsc);
  2120. }
  2121. else if (IS_DSC(line, "%%BoundingBox:")) {
  2122. dsc->id = CDSC_BOUNDINGBOX;
  2123. if (dsc_parse_bounding_box(dsc, &(dsc->bbox), continued ? 3 : 14))
  2124. return CDSC_ERROR;
  2125. }
  2126. else if (IS_DSC(line, "%%HiResBoundingBox:")) {
  2127. dsc->id = CDSC_HIRESBOUNDINGBOX;
  2128. if (dsc_parse_float_bounding_box(dsc, &(dsc->hires_bbox),
  2129. continued ? 3 : 19))
  2130. return CDSC_ERROR;
  2131. }
  2132. else if (IS_DSC(line, "%%CropBox:")) {
  2133. dsc->id = CDSC_CROPBOX;
  2134. if (dsc_parse_float_bounding_box(dsc, &(dsc->crop_box),
  2135. continued ? 3 : 10))
  2136. return CDSC_ERROR;
  2137. }
  2138. else if (IS_DSC(line, "%%Orientation:")) {
  2139. dsc->id = CDSC_ORIENTATION;
  2140. if (dsc_parse_orientation(dsc, &(dsc->page_orientation),
  2141. continued ? 3 : 14))
  2142. return CDSC_ERROR;
  2143. }
  2144. else if (IS_DSC(line, "%%PageOrder:")) {
  2145. dsc->id = CDSC_PAGEORDER;
  2146. if (dsc_parse_order(dsc))
  2147. return CDSC_ERROR;
  2148. }
  2149. else if (IS_DSC(line, "%%DocumentMedia:")) {
  2150. dsc->id = CDSC_DOCUMENTMEDIA;
  2151. if (dsc_parse_document_media(dsc))
  2152. return CDSC_ERROR;
  2153. }
  2154. else if (IS_DSC(line, "%%DocumentPaperSizes:")) {
  2155. /* DSC 2.1 */
  2156. unsigned int n = continued ? 3 : 21;
  2157. unsigned int count = 0;
  2158. unsigned int i = 1;
  2159. char name[MAXSTR];
  2160. char *p;
  2161. dsc->id = CDSC_DOCUMENTPAPERSIZES;
  2162. while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
  2163. p = dsc_copy_string(name, sizeof(name)-1,
  2164. dsc->line+n, dsc->line_length-n, &i);
  2165. if (i && p) {
  2166. const CDSCMEDIA *m = dsc_known_media;
  2167. if (count >= dsc->media_count) {
  2168. /* set some default values */
  2169. CDSCMEDIA lmedia;
  2170. lmedia.name = p;
  2171. lmedia.width = 595.0;
  2172. lmedia.height = 842.0;
  2173. lmedia.weight = 80.0;
  2174. lmedia.colour = NULL;
  2175. lmedia.type = NULL;
  2176. lmedia.mediabox = NULL;
  2177. if (dsc_add_media(dsc, &lmedia))
  2178. return CDSC_ERROR;
  2179. }
  2180. else
  2181. dsc->media[count]->name =
  2182. dsc_alloc_string(dsc, p, (int)strlen(p));
  2183. /* find in list of known media */
  2184. while (m && m->name) {
  2185. if (dsc_stricmp(p, m->name)==0) {
  2186. dsc->media[count]->width = m->width;
  2187. dsc->media[count]->height = m->height;
  2188. break;
  2189. }
  2190. m++;
  2191. }
  2192. }
  2193. n+=i;
  2194. count++;
  2195. }
  2196. }
  2197. else if (IS_DSC(line, "%%DocumentPaperForms:")) {
  2198. /* DSC 2.1 */
  2199. unsigned int n = continued ? 3 : 21;
  2200. unsigned int count = 0;
  2201. unsigned int i = 1;
  2202. char type[MAXSTR];
  2203. char *p;
  2204. dsc->id = CDSC_DOCUMENTPAPERFORMS;
  2205. while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
  2206. p = dsc_copy_string(type, sizeof(type)-1,
  2207. dsc->line+n, dsc->line_length-n, &i);
  2208. if (i && p) {
  2209. if (count >= dsc->media_count) {
  2210. /* set some default values */
  2211. CDSCMEDIA lmedia;
  2212. lmedia.name = NULL;
  2213. lmedia.width = 595.0;
  2214. lmedia.height = 842.0;
  2215. lmedia.weight = 80.0;
  2216. lmedia.colour = NULL;
  2217. lmedia.type = p;
  2218. lmedia.mediabox = NULL;
  2219. if (dsc_add_media(dsc, &lmedia))
  2220. return CDSC_ERROR;
  2221. }
  2222. else
  2223. dsc->media[count]->type =
  2224. dsc_alloc_string(dsc, p, (int)strlen(p));
  2225. }
  2226. n+=i;
  2227. count++;
  2228. }
  2229. }
  2230. else if (IS_DSC(line, "%%DocumentPaperColors:")) {
  2231. /* DSC 2.1 */
  2232. unsigned int n = continued ? 3 : 22;
  2233. unsigned int count = 0;
  2234. unsigned int i = 1;
  2235. char colour[MAXSTR];
  2236. char *p;
  2237. dsc->id = CDSC_DOCUMENTPAPERCOLORS;
  2238. while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
  2239. p = dsc_copy_string(colour, sizeof(colour)-1,
  2240. dsc->line+n, dsc->line_length-n, &i);
  2241. if (i && p) {
  2242. if (count >= dsc->media_count) {
  2243. /* set some default values */
  2244. CDSCMEDIA lmedia;
  2245. lmedia.name = NULL;
  2246. lmedia.width = 595.0;
  2247. lmedia.height = 842.0;
  2248. lmedia.weight = 80.0;
  2249. lmedia.colour = p;
  2250. lmedia.type = NULL;
  2251. lmedia.mediabox = NULL;
  2252. if (dsc_add_media(dsc, &lmedia))
  2253. return CDSC_ERROR;
  2254. }
  2255. else
  2256. dsc->media[count]->colour =
  2257. dsc_alloc_string(dsc, p, (int)strlen(p));
  2258. }
  2259. n+=i;
  2260. count++;
  2261. }
  2262. }
  2263. else if (IS_DSC(line, "%%DocumentPaperWeights:")) {
  2264. /* DSC 2.1 */
  2265. unsigned int n = continued ? 3 : 23;
  2266. unsigned int count = 0;
  2267. unsigned int i = 1;
  2268. float w;
  2269. dsc->id = CDSC_DOCUMENTPAPERWEIGHTS;
  2270. while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
  2271. w = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  2272. if (i) {
  2273. if (count >= dsc->media_count) {
  2274. /* set some default values */
  2275. CDSCMEDIA lmedia;
  2276. lmedia.name = NULL;
  2277. lmedia.width = 595.0;
  2278. lmedia.height = 842.0;
  2279. lmedia.weight = w;
  2280. lmedia.colour = NULL;
  2281. lmedia.type = NULL;
  2282. lmedia.mediabox = NULL;
  2283. if (dsc_add_media(dsc, &lmedia))
  2284. return CDSC_ERROR;
  2285. }
  2286. else
  2287. dsc->media[count]->weight = w;
  2288. }
  2289. n+=i;
  2290. count++;
  2291. }
  2292. }
  2293. else if (IS_DSC(line, "%%DocumentData:")) {
  2294. unsigned int n = continued ? 3 : 15;
  2295. char *p = dsc->line + n;
  2296. while (IS_WHITE(*p))
  2297. p++;
  2298. dsc->id = CDSC_DOCUMENTDATA;
  2299. if (COMPARE(p, "Clean7Bit"))
  2300. dsc->document_data = CDSC_CLEAN7BIT;
  2301. else if (COMPARE(p, "Clean8Bit"))
  2302. dsc->document_data = CDSC_CLEAN8BIT;
  2303. else if (COMPARE(p, "Binary"))
  2304. dsc->document_data = CDSC_BINARY;
  2305. else
  2306. dsc_unknown(dsc);
  2307. }
  2308. else if (IS_DSC(line, "%%Requirements:")) {
  2309. dsc->id = CDSC_REQUIREMENTS;
  2310. /* ignore */
  2311. }
  2312. else if (IS_DSC(line, "%%DocumentNeededFonts:")) {
  2313. dsc->id = CDSC_DOCUMENTNEEDEDFONTS;
  2314. /* ignore */
  2315. }
  2316. else if (IS_DSC(line, "%%DocumentSuppliedFonts:")) {
  2317. dsc->id = CDSC_DOCUMENTSUPPLIEDFONTS;
  2318. /* ignore */
  2319. }
  2320. else if (IS_DSC(line, "%%PlateFile:")) {
  2321. dsc->id = CDSC_PLATEFILE;
  2322. if (dsc_parse_platefile(dsc) != CDSC_OK)
  2323. dsc->id = CDSC_UNKNOWNDSC;
  2324. }
  2325. else if (IS_DSC(line, "%%CyanPlate:") ||
  2326. IS_DSC(line, "%%MagentaPlate:") ||
  2327. IS_DSC(line, "%%YellowPlate:") ||
  2328. IS_DSC(line, "%%BlackPlate:")) {
  2329. dsc->id = CDSC_PLATEFILE;
  2330. if (dsc_parse_dcs1plate(dsc) != CDSC_OK)
  2331. dsc->id = CDSC_UNKNOWNDSC;
  2332. }
  2333. else if (IS_DSC(line, "%%DocumentProcessColors:")) {
  2334. dsc->id = CDSC_DOCUMENTPROCESSCOLORS;
  2335. if (dsc_parse_process_colours(dsc) != CDSC_OK)
  2336. dsc->id = CDSC_UNKNOWNDSC;
  2337. }
  2338. else if (IS_DSC(line, "%%DocumentCustomColors:")) {
  2339. dsc->id = CDSC_DOCUMENTCUSTOMCOLORS;
  2340. if (dsc_parse_custom_colours(dsc) != CDSC_OK)
  2341. dsc->id = CDSC_UNKNOWNDSC;
  2342. }
  2343. else if (IS_DSC(line, "%%CMYKCustomColor:")) {
  2344. dsc->id = CDSC_CMYKCUSTOMCOLOR;
  2345. if (dsc_parse_cmyk_custom_colour(dsc) != CDSC_OK)
  2346. dsc->id = CDSC_UNKNOWNDSC;
  2347. }
  2348. else if (IS_DSC(line, "%%RGBCustomColor:")) {
  2349. dsc->id = CDSC_RGBCUSTOMCOLOR;
  2350. if (dsc_parse_rgb_custom_colour(dsc) != CDSC_OK)
  2351. dsc->id = CDSC_UNKNOWNDSC;
  2352. }
  2353. else if (dsc->line[0] == '%' && IS_WHITE_OR_EOL(dsc->line[1])) {
  2354. dsc->id = CDSC_OK;
  2355. /* ignore */
  2356. }
  2357. else {
  2358. dsc->id = CDSC_UNKNOWNDSC;
  2359. dsc_unknown(dsc);
  2360. }
  2361. dsc->endcomments = DSC_END(dsc);
  2362. return CDSC_OK;
  2363. }
  2364. dsc_private int
  2365. dsc_scan_preview(CDSC *dsc)
  2366. {
  2367. /* Preview section ends at */
  2368. /* %%EndPreview */
  2369. /* another section */
  2370. /* Preview section must start with %%BeginPreview */
  2371. char *line = dsc->line;
  2372. dsc->id = CDSC_OK;
  2373. if (dsc->scan_section == scan_pre_preview) {
  2374. if (IS_BLANK(line))
  2375. return CDSC_OK; /* ignore blank lines before preview */
  2376. else if (IS_DSC(line, "%%BeginPreview")) {
  2377. dsc->id = CDSC_BEGINPREVIEW;
  2378. dsc->beginpreview = DSC_START(dsc);
  2379. dsc->endpreview = DSC_END(dsc);
  2380. dsc->scan_section = scan_preview;
  2381. /* Don't mark the preview as EPSI if a DOS EPS header is present */
  2382. if (dsc->preview == CDSC_NOPREVIEW)
  2383. dsc->preview = CDSC_EPSI;
  2384. return CDSC_OK;
  2385. }
  2386. else {
  2387. dsc->scan_section = scan_pre_defaults;
  2388. return CDSC_PROPAGATE;
  2389. }
  2390. }
  2391. if (IS_DSC(line, "%%BeginPreview")) {
  2392. /* ignore because we are in this section */
  2393. }
  2394. else if (dsc_is_section(line)) {
  2395. dsc->endpreview = DSC_START(dsc);
  2396. dsc->scan_section = scan_pre_defaults;
  2397. return CDSC_PROPAGATE;
  2398. }
  2399. else if (IS_DSC(line, "%%EndPreview")) {
  2400. dsc->id = CDSC_ENDPREVIEW;
  2401. dsc->endpreview = DSC_END(dsc);
  2402. dsc->scan_section = scan_pre_defaults;
  2403. return CDSC_OK;
  2404. }
  2405. else if (line[0] == '%' && line[1] != '%') {
  2406. /* Ordinary comments are OK */
  2407. }
  2408. else {
  2409. dsc->id = CDSC_UNKNOWNDSC;
  2410. /* DSC comments should not occur in preview */
  2411. dsc_unknown(dsc);
  2412. }
  2413. dsc->endpreview = DSC_END(dsc);
  2414. return CDSC_OK;
  2415. }
  2416. dsc_private int
  2417. dsc_scan_defaults(CDSC *dsc)
  2418. {
  2419. /* Defaults section ends at */
  2420. /* %%EndDefaults */
  2421. /* another section */
  2422. /* Defaults section must start with %%BeginDefaults */
  2423. char *line = dsc->line;
  2424. dsc->id = CDSC_OK;
  2425. if (dsc->scan_section == scan_pre_defaults) {
  2426. if (IS_BLANK(line))
  2427. return CDSC_OK; /* ignore blank lines before defaults */
  2428. else if (IS_DSC(line, "%%BeginDefaults")) {
  2429. dsc->id = CDSC_BEGINDEFAULTS;
  2430. dsc->begindefaults = DSC_START(dsc);
  2431. dsc->enddefaults = DSC_END(dsc);
  2432. dsc->scan_section = scan_defaults;
  2433. return CDSC_OK;
  2434. }
  2435. else {
  2436. dsc->scan_section = scan_pre_prolog;
  2437. return CDSC_PROPAGATE;
  2438. }
  2439. }
  2440. if (NOT_DSC_LINE(line)) {
  2441. /* ignore */
  2442. }
  2443. else if (IS_DSC(line, "%%BeginPreview")) {
  2444. /* ignore because we have already processed this section */
  2445. }
  2446. else if (IS_DSC(line, "%%BeginDefaults")) {
  2447. /* ignore because we are in this section */
  2448. }
  2449. else if (dsc_is_section(line)) {
  2450. dsc->enddefaults = DSC_START(dsc);
  2451. dsc->scan_section = scan_pre_prolog;
  2452. return CDSC_PROPAGATE;
  2453. }
  2454. else if (IS_DSC(line, "%%EndDefaults")) {
  2455. dsc->id = CDSC_ENDDEFAULTS;
  2456. dsc->enddefaults = DSC_END(dsc);
  2457. dsc->scan_section = scan_pre_prolog;
  2458. return CDSC_OK;
  2459. }
  2460. else if (IS_DSC(line, "%%PageMedia:")) {
  2461. dsc->id = CDSC_PAGEMEDIA;
  2462. dsc_parse_media(dsc, &dsc->page_media);
  2463. }
  2464. else if (IS_DSC(line, "%%PageOrientation:")) {
  2465. dsc->id = CDSC_PAGEORIENTATION;
  2466. /* This can override %%Orientation: */
  2467. if (dsc_parse_orientation(dsc, &(dsc->page_orientation), 18))
  2468. return CDSC_ERROR;
  2469. }
  2470. else if (IS_DSC(line, "%%PageBoundingBox:")) {
  2471. dsc->id = CDSC_PAGEBOUNDINGBOX;
  2472. if (dsc_parse_bounding_box(dsc, &(dsc->page_bbox), 18))
  2473. return CDSC_ERROR;
  2474. }
  2475. else if (IS_DSC(line, "%%ViewingOrientation:")) {
  2476. dsc->id = CDSC_VIEWINGORIENTATION;
  2477. if (dsc_parse_viewing_orientation(dsc, &dsc->viewing_orientation))
  2478. return CDSC_ERROR;
  2479. }
  2480. else if (IS_DSC(line, "%%PageCropBox:")) {
  2481. dsc->id = CDSC_PAGECROPBOX;
  2482. if (dsc_parse_float_bounding_box(dsc, &dsc->crop_box, 14))
  2483. return CDSC_ERROR;
  2484. }
  2485. else {
  2486. dsc->id = CDSC_UNKNOWNDSC;
  2487. /* All other DSC comments are unknown, but not an error */
  2488. dsc_unknown(dsc);
  2489. }
  2490. dsc->enddefaults = DSC_END(dsc);
  2491. return CDSC_OK;
  2492. }
  2493. /* CDSC_RESPONSE_OK and CDSC_RESPONSE_CANCEL mean ignore the
  2494. * mismatch (default) */
  2495. dsc_private int
  2496. dsc_check_match_prompt(CDSC *dsc, const char *str, int count)
  2497. {
  2498. if (count != 0) {
  2499. char buf[MAXSTR+MAXSTR];
  2500. if (dsc->line_length < (unsigned int)(sizeof(buf)/2-1)) {
  2501. strncpy(buf, dsc->line, dsc->line_length);
  2502. buf[dsc->line_length] = '\0';
  2503. }
  2504. sprintf(buf+strlen(buf), "\n%%%%Begin%.40s: / %%%%End%.40s\n", str, str);
  2505. return dsc_error(dsc, CDSC_MESSAGE_BEGIN_END, buf, (int)strlen(buf));
  2506. }
  2507. return CDSC_RESPONSE_CANCEL;
  2508. }
  2509. dsc_private int
  2510. dsc_check_match_type(CDSC *dsc, const char *str, int count)
  2511. {
  2512. if (dsc_check_match_prompt(dsc, str, count) == CDSC_RESPONSE_IGNORE_ALL)
  2513. return CDSC_NOTDSC;
  2514. return CDSC_OK;
  2515. }
  2516. /* complain if Begin/End blocks didn't match */
  2517. /* return non-zero if we should ignore all DSC */
  2518. dsc_private int
  2519. dsc_check_match(CDSC *dsc)
  2520. {
  2521. int rc = 0;
  2522. const char *font = "Font";
  2523. const char *feature = "Feature";
  2524. const char *resource = "Resource";
  2525. const char *procset = "ProcSet";
  2526. if (!rc)
  2527. rc = dsc_check_match_type(dsc, font, dsc->begin_font_count);
  2528. if (!rc)
  2529. rc = dsc_check_match_type(dsc, feature, dsc->begin_feature_count);
  2530. if (!rc)
  2531. rc = dsc_check_match_type(dsc, resource, dsc->begin_resource_count);
  2532. if (!rc)
  2533. rc = dsc_check_match_type(dsc, procset, dsc->begin_procset_count);
  2534. dsc->begin_font_count = 0;
  2535. dsc->begin_feature_count = 0;
  2536. dsc->begin_resource_count = 0;
  2537. dsc->begin_procset_count = 0;
  2538. return rc;
  2539. }
  2540. dsc_private int
  2541. dsc_scan_prolog(CDSC *dsc)
  2542. {
  2543. /* Prolog section ends at */
  2544. /* %%EndProlog */
  2545. /* another section */
  2546. /* Prolog section may start with %%BeginProlog or non-dsc line */
  2547. char *line = dsc->line;
  2548. dsc->id = CDSC_OK;
  2549. if (dsc->scan_section == scan_pre_prolog) {
  2550. if (dsc_is_section(line) && (!IS_DSC(line, "%%BeginProlog"))) {
  2551. dsc->scan_section = scan_pre_setup;
  2552. return CDSC_PROPAGATE;
  2553. }
  2554. dsc->id = CDSC_BEGINPROLOG;
  2555. dsc->beginprolog = DSC_START(dsc);
  2556. dsc->endprolog = DSC_END(dsc);
  2557. dsc->scan_section = scan_prolog;
  2558. if (IS_DSC(line, "%%BeginProlog"))
  2559. return CDSC_OK;
  2560. }
  2561. if (NOT_DSC_LINE(line)) {
  2562. /* ignore */
  2563. }
  2564. else if (IS_DSC(line, "%%BeginPreview")) {
  2565. /* ignore because we have already processed this section */
  2566. }
  2567. else if (IS_DSC(line, "%%BeginDefaults")) {
  2568. /* ignore because we have already processed this section */
  2569. }
  2570. else if (IS_DSC(line, "%%BeginProlog")) {
  2571. /* ignore because we are in this section */
  2572. }
  2573. else if (dsc_is_section(line)) {
  2574. dsc->endprolog = DSC_START(dsc);
  2575. dsc->scan_section = scan_pre_setup;
  2576. if (dsc_check_match(dsc))
  2577. return CDSC_NOTDSC;
  2578. return CDSC_PROPAGATE;
  2579. }
  2580. else if (IS_DSC(line, "%%EndProlog")) {
  2581. dsc->id = CDSC_ENDPROLOG;
  2582. dsc->endprolog = DSC_END(dsc);
  2583. dsc->scan_section = scan_pre_setup;
  2584. if (dsc_check_match(dsc))
  2585. return CDSC_NOTDSC;
  2586. return CDSC_OK;
  2587. }
  2588. else if (IS_DSC(line, "%%BeginFont:")) {
  2589. dsc->id = CDSC_BEGINFONT;
  2590. /* ignore Begin/EndFont, apart form making sure */
  2591. /* that they are matched. */
  2592. dsc->begin_font_count++;
  2593. }
  2594. else if (IS_DSC(line, "%%EndFont")) {
  2595. dsc->id = CDSC_ENDFONT;
  2596. dsc->begin_font_count--;
  2597. }
  2598. else if (IS_DSC(line, "%%BeginFeature:")) {
  2599. dsc->id = CDSC_BEGINFEATURE;
  2600. /* ignore Begin/EndFeature, apart form making sure */
  2601. /* that they are matched. */
  2602. dsc->begin_feature_count++;
  2603. }
  2604. else if (IS_DSC(line, "%%EndFeature")) {
  2605. dsc->id = CDSC_ENDFEATURE;
  2606. dsc->begin_feature_count--;
  2607. }
  2608. else if (IS_DSC(line, "%%BeginResource:")) {
  2609. dsc->id = CDSC_BEGINRESOURCE;
  2610. /* ignore Begin/EndResource, apart form making sure */
  2611. /* that they are matched. */
  2612. dsc->begin_resource_count++;
  2613. }
  2614. else if (IS_DSC(line, "%%EndResource")) {
  2615. dsc->id = CDSC_ENDRESOURCE;
  2616. dsc->begin_resource_count--;
  2617. }
  2618. else if (IS_DSC(line, "%%BeginProcSet:")) {
  2619. dsc->id = CDSC_BEGINPROCSET;
  2620. /* ignore Begin/EndProcSet, apart form making sure */
  2621. /* that they are matched. */
  2622. dsc->begin_procset_count++;
  2623. }
  2624. else if (IS_DSC(line, "%%EndProcSet")) {
  2625. dsc->id = CDSC_ENDPROCSET;
  2626. dsc->begin_procset_count--;
  2627. }
  2628. else {
  2629. /* All other DSC comments are unknown, but not an error */
  2630. dsc->id = CDSC_UNKNOWNDSC;
  2631. dsc_unknown(dsc);
  2632. }
  2633. dsc->endprolog = DSC_END(dsc);
  2634. return CDSC_OK;
  2635. }
  2636. dsc_private int
  2637. dsc_scan_setup(CDSC *dsc)
  2638. {
  2639. /* Setup section ends at */
  2640. /* %%EndSetup */
  2641. /* another section */
  2642. /* Setup section must start with %%BeginSetup */
  2643. char *line = dsc->line;
  2644. dsc->id = CDSC_OK;
  2645. if (dsc->scan_section == scan_pre_setup) {
  2646. if (IS_BLANK(line))
  2647. return CDSC_OK; /* ignore blank lines before setup */
  2648. else if (IS_DSC(line, "%%BeginSetup")) {
  2649. dsc->id = CDSC_BEGINSETUP;
  2650. dsc->beginsetup = DSC_START(dsc);
  2651. dsc->endsetup = DSC_END(dsc);
  2652. dsc->scan_section = scan_setup;
  2653. return CDSC_OK;
  2654. }
  2655. else {
  2656. dsc->scan_section = scan_pre_pages;
  2657. return CDSC_PROPAGATE;
  2658. }
  2659. }
  2660. if (NOT_DSC_LINE(line)) {
  2661. /* ignore */
  2662. }
  2663. else if (IS_DSC(line, "%%BeginPreview")) {
  2664. /* ignore because we have already processed this section */
  2665. }
  2666. else if (IS_DSC(line, "%%BeginDefaults")) {
  2667. /* ignore because we have already processed this section */
  2668. }
  2669. else if (IS_DSC(line, "%%BeginProlog")) {
  2670. /* ignore because we have already processed this section */
  2671. }
  2672. else if (IS_DSC(line, "%%BeginSetup")) {
  2673. /* ignore because we are in this section */
  2674. }
  2675. else if (dsc_is_section(line)) {
  2676. dsc->endsetup = DSC_START(dsc);
  2677. dsc->scan_section = scan_pre_pages;
  2678. if (dsc_check_match(dsc))
  2679. return CDSC_NOTDSC;
  2680. return CDSC_PROPAGATE;
  2681. }
  2682. else if (IS_DSC(line, "%%EndSetup")) {
  2683. dsc->id = CDSC_ENDSETUP;
  2684. dsc->endsetup = DSC_END(dsc);
  2685. dsc->scan_section = scan_pre_pages;
  2686. if (dsc_check_match(dsc))
  2687. return CDSC_NOTDSC;
  2688. return CDSC_OK;
  2689. }
  2690. else if (IS_DSC(line, "%%BeginFeature:")) {
  2691. dsc->id = CDSC_BEGINFEATURE;
  2692. /* ignore Begin/EndFeature, apart form making sure */
  2693. /* that they are matched. */
  2694. dsc->begin_feature_count++;
  2695. /* Look for "*PageSize name" where name is known */
  2696. if (dsc_parse_feature(dsc))
  2697. return CDSC_ERROR;
  2698. }
  2699. else if (IS_DSC(line, "%%EndFeature")) {
  2700. dsc->id = CDSC_ENDFEATURE;
  2701. dsc->begin_feature_count--;
  2702. }
  2703. else if (IS_DSC(line, "%%Feature:")) {
  2704. dsc->id = CDSC_FEATURE;
  2705. /* ignore */
  2706. }
  2707. else if (IS_DSC(line, "%%BeginResource:")) {
  2708. dsc->id = CDSC_BEGINRESOURCE;
  2709. /* ignore Begin/EndResource, apart form making sure */
  2710. /* that they are matched. */
  2711. dsc->begin_resource_count++;
  2712. }
  2713. else if (IS_DSC(line, "%%EndResource")) {
  2714. dsc->id = CDSC_ENDRESOURCE;
  2715. dsc->begin_resource_count--;
  2716. }
  2717. else if (IS_DSC(line, "%%PaperColor:")) {
  2718. dsc->id = CDSC_PAPERCOLOR;
  2719. /* ignore */
  2720. }
  2721. else if (IS_DSC(line, "%%PaperForm:")) {
  2722. dsc->id = CDSC_PAPERFORM;
  2723. /* ignore */
  2724. }
  2725. else if (IS_DSC(line, "%%PaperWeight:")) {
  2726. dsc->id = CDSC_PAPERWEIGHT;
  2727. /* ignore */
  2728. }
  2729. else if (IS_DSC(line, "%%PaperSize:")) {
  2730. /* DSC 2.1 */
  2731. GSBOOL found_media = FALSE;
  2732. int i;
  2733. int n = 12;
  2734. char buf[MAXSTR];
  2735. buf[0] = '\0';
  2736. dsc->id = CDSC_PAPERSIZE;
  2737. dsc_copy_string(buf, sizeof(buf)-1, dsc->line+n, dsc->line_length-n,
  2738. NULL);
  2739. for (i=0; i<(int)dsc->media_count; i++) {
  2740. if (dsc->media[i] && dsc->media[i]->name &&
  2741. (dsc_stricmp(buf, dsc->media[i]->name)==0)) {
  2742. dsc->page_media = dsc->media[i];
  2743. found_media = TRUE;
  2744. break;
  2745. }
  2746. }
  2747. if (!found_media) {
  2748. /* It didn't match %%DocumentPaperSizes: */
  2749. /* Try our known media */
  2750. const CDSCMEDIA *m = dsc_known_media;
  2751. while (m->name) {
  2752. if (dsc_stricmp(buf, m->name)==0) {
  2753. dsc->page_media = m;
  2754. break;
  2755. }
  2756. m++;
  2757. }
  2758. if (m->name == NULL)
  2759. dsc_unknown(dsc);
  2760. }
  2761. }
  2762. else {
  2763. /* All other DSC comments are unknown, but not an error */
  2764. dsc->id = CDSC_UNKNOWNDSC;
  2765. dsc_unknown(dsc);
  2766. }
  2767. dsc->endsetup = DSC_END(dsc);
  2768. return CDSC_OK;
  2769. }
  2770. dsc_private int
  2771. dsc_scan_page(CDSC *dsc)
  2772. {
  2773. /* Page section ends at */
  2774. /* %%Page */
  2775. /* %%Trailer */
  2776. /* %%EOF */
  2777. char *line = dsc->line;
  2778. dsc->id = CDSC_OK;
  2779. if (dsc->scan_section == scan_pre_pages) {
  2780. if (IS_DSC(line, "%%Page:")) {
  2781. dsc->scan_section = scan_pages;
  2782. /* fall through */
  2783. }
  2784. else {
  2785. /* %%Page: didn't follow %%EndSetup
  2786. * Keep reading until reach %%Page or %%Trailer
  2787. * and add it to previous section.
  2788. */
  2789. DSC_OFFSET *last;
  2790. if (dsc->endsetup != 0)
  2791. last = &dsc->endsetup;
  2792. else if (dsc->endprolog != 0)
  2793. last = &dsc->endprolog;
  2794. else if (dsc->enddefaults != 0)
  2795. last = &dsc->enddefaults;
  2796. else if (dsc->endpreview != 0)
  2797. last = &dsc->endpreview;
  2798. else if (dsc->endcomments != 0)
  2799. last = &dsc->endcomments;
  2800. else
  2801. last = &dsc->begincomments;
  2802. *last = DSC_START(dsc);
  2803. if (IS_DSC(line, "%%Trailer") || IS_DSC(line, "%%EOF")) {
  2804. dsc->scan_section = scan_pre_trailer;
  2805. return CDSC_PROPAGATE;
  2806. }
  2807. *last = DSC_END(dsc);
  2808. return CDSC_OK;
  2809. }
  2810. }
  2811. if (NOT_DSC_LINE(line)) {
  2812. /* ignore */
  2813. }
  2814. else if (IS_DSC(line, "%%Page:")) {
  2815. int code;
  2816. dsc->id = CDSC_PAGE;
  2817. if (dsc->page_count) {
  2818. dsc->page[dsc->page_count-1].end = DSC_START(dsc);
  2819. if (dsc_check_match(dsc))
  2820. return CDSC_NOTDSC;
  2821. }
  2822. if ( (code = dsc_parse_page(dsc)) != CDSC_OK)
  2823. return code;
  2824. if (dsc->page_count == 0)
  2825. dsc->scan_section = scan_pre_pages;
  2826. }
  2827. else if (IS_DSC(line, "%%BeginPreview")) {
  2828. /* ignore because we have already processed this section */
  2829. }
  2830. else if (IS_DSC(line, "%%BeginDefaults")) {
  2831. /* ignore because we have already processed this section */
  2832. }
  2833. else if (IS_DSC(line, "%%BeginProlog")) {
  2834. /* ignore because we have already processed this section */
  2835. }
  2836. else if (IS_DSC(line, "%%BeginSetup")) {
  2837. /* ignore because we have already processed this section */
  2838. }
  2839. else if (dsc_is_section(line)) {
  2840. if (IS_DSC(line, "%%Trailer")) {
  2841. if (dsc->page_count)
  2842. dsc->page[dsc->page_count-1].end = DSC_START(dsc);
  2843. if (dsc->file_length) {
  2844. if ((!dsc->doseps_end &&
  2845. ((DSC_END(dsc) + 32768) < dsc->file_length)) ||
  2846. ((dsc->doseps_end) &&
  2847. ((DSC_END(dsc) + 32768) < dsc->doseps_end))) {
  2848. int rc = dsc_error(dsc, CDSC_MESSAGE_EARLY_TRAILER,
  2849. dsc->line, dsc->line_length);
  2850. switch (rc) {
  2851. case CDSC_RESPONSE_OK:
  2852. /* ignore early trailer */
  2853. break;
  2854. case CDSC_RESPONSE_CANCEL:
  2855. /* this is the trailer */
  2856. dsc->scan_section = scan_pre_trailer;
  2857. if (dsc_check_match(dsc))
  2858. return CDSC_NOTDSC;
  2859. return CDSC_PROPAGATE;
  2860. case CDSC_RESPONSE_IGNORE_ALL:
  2861. return CDSC_NOTDSC;
  2862. }
  2863. }
  2864. else {
  2865. dsc->scan_section = scan_pre_trailer;
  2866. if (dsc_check_match(dsc))
  2867. return CDSC_NOTDSC;
  2868. return CDSC_PROPAGATE;
  2869. }
  2870. }
  2871. else {
  2872. dsc->scan_section = scan_pre_trailer;
  2873. if (dsc_check_match(dsc))
  2874. return CDSC_NOTDSC;
  2875. return CDSC_PROPAGATE;
  2876. }
  2877. }
  2878. else if (IS_DSC(line, "%%EOF")) {
  2879. if (dsc->page_count)
  2880. dsc->page[dsc->page_count-1].end = DSC_START(dsc);
  2881. if (dsc->file_length) {
  2882. if ((!dsc->doseps_end &&
  2883. ((DSC_END(dsc) + 100) < dsc->file_length)) ||
  2884. ((dsc->doseps_end) &&
  2885. ((DSC_END(dsc) + 100) < dsc->doseps_end))) {
  2886. int rc = dsc_error(dsc, CDSC_MESSAGE_EARLY_EOF,
  2887. dsc->line, dsc->line_length);
  2888. switch (rc) {
  2889. case CDSC_RESPONSE_OK:
  2890. /* %%EOF is wrong, ignore it */
  2891. break;
  2892. case CDSC_RESPONSE_CANCEL:
  2893. /* %%EOF is correct */
  2894. dsc->scan_section = scan_eof;
  2895. dsc->eof = TRUE;
  2896. if (dsc_check_match(dsc))
  2897. return CDSC_NOTDSC;
  2898. return CDSC_PROPAGATE;
  2899. case CDSC_RESPONSE_IGNORE_ALL:
  2900. return CDSC_NOTDSC;
  2901. }
  2902. }
  2903. }
  2904. else {
  2905. /* ignore it */
  2906. if (dsc_check_match(dsc))
  2907. return CDSC_NOTDSC;
  2908. return CDSC_OK;
  2909. }
  2910. }
  2911. else {
  2912. /* Section comment, probably from a badly */
  2913. /* encapsulated EPS file. */
  2914. int rc = dsc_error(dsc, CDSC_MESSAGE_BAD_SECTION,
  2915. dsc->line, dsc->line_length);
  2916. if (rc == CDSC_RESPONSE_IGNORE_ALL)
  2917. return CDSC_NOTDSC;
  2918. }
  2919. }
  2920. else if (IS_DSC(line, "%%PageTrailer")) {
  2921. dsc->id = CDSC_PAGETRAILER;
  2922. /* ignore */
  2923. }
  2924. else if (IS_DSC(line, "%%BeginPageSetup")) {
  2925. dsc->id = CDSC_BEGINPAGESETUP;
  2926. /* ignore */
  2927. }
  2928. else if (IS_DSC(line, "%%EndPageSetup")) {
  2929. dsc->id = CDSC_ENDPAGESETUP;
  2930. /* ignore */
  2931. }
  2932. else if (IS_DSC(line, "%%PageMedia:")) {
  2933. dsc->id = CDSC_PAGEMEDIA;
  2934. if (dsc->page_count)
  2935. dsc_parse_media(dsc, &(dsc->page[dsc->page_count-1].media));
  2936. }
  2937. else if (IS_DSC(line, "%%PaperColor:")) {
  2938. dsc->id = CDSC_PAPERCOLOR;
  2939. /* ignore */
  2940. }
  2941. else if (IS_DSC(line, "%%PaperForm:")) {
  2942. dsc->id = CDSC_PAPERFORM;
  2943. /* ignore */
  2944. }
  2945. else if (IS_DSC(line, "%%PaperWeight:")) {
  2946. dsc->id = CDSC_PAPERWEIGHT;
  2947. /* ignore */
  2948. }
  2949. else if (IS_DSC(line, "%%PaperSize:")) {
  2950. /* DSC 2.1 */
  2951. GSBOOL found_media = FALSE;
  2952. int i;
  2953. int n = 12;
  2954. char buf[MAXSTR];
  2955. buf[0] = '\0';
  2956. dsc_copy_string(buf, sizeof(buf)-1, dsc->line+n,
  2957. dsc->line_length-n, NULL);
  2958. for (i=0; i<(int)dsc->media_count; i++) {
  2959. if (dsc->media[i] && dsc->media[i]->name &&
  2960. (dsc_stricmp(buf, dsc->media[i]->name)==0)) {
  2961. if (dsc->page_count)
  2962. dsc->page[dsc->page_count-1].media = dsc->media[i];
  2963. found_media = TRUE;
  2964. break;
  2965. }
  2966. }
  2967. if (!found_media) {
  2968. /* It didn't match %%DocumentPaperSizes: */
  2969. /* Try our known media */
  2970. const CDSCMEDIA *m = dsc_known_media;
  2971. while (m->name) {
  2972. if (dsc_stricmp(buf, m->name)==0) {
  2973. if (dsc->page_count)
  2974. dsc->page[dsc->page_count-1].media = m;
  2975. break;
  2976. }
  2977. m++;
  2978. }
  2979. if (m->name == NULL)
  2980. dsc_unknown(dsc);
  2981. }
  2982. }
  2983. else if (IS_DSC(line, "%%PageOrientation:")) {
  2984. if (dsc->page_count) {
  2985. dsc->id = CDSC_PAGEORIENTATION;
  2986. if (dsc_parse_orientation(dsc,
  2987. &(dsc->page[dsc->page_count-1].orientation) ,18))
  2988. return CDSC_NOTDSC;
  2989. }
  2990. }
  2991. else if (IS_DSC(line, "%%PageBoundingBox:")) {
  2992. if (dsc->page_count) {
  2993. dsc->id = CDSC_PAGEBOUNDINGBOX;
  2994. if (dsc_parse_bounding_box(dsc,
  2995. &dsc->page[dsc->page_count-1].bbox, 18))
  2996. return CDSC_NOTDSC;
  2997. }
  2998. }
  2999. else if (IS_DSC(line, "%%ViewingOrientation:")) {
  3000. if (dsc->page_count) {
  3001. dsc->id = CDSC_VIEWINGORIENTATION;
  3002. if (dsc_parse_viewing_orientation(dsc,
  3003. &dsc->page[dsc->page_count-1].viewing_orientation))
  3004. return CDSC_ERROR;
  3005. }
  3006. }
  3007. else if (IS_DSC(line, "%%PageCropBox:")) {
  3008. if (dsc->page_count) {
  3009. dsc->id = CDSC_PAGECROPBOX;
  3010. if (dsc_parse_float_bounding_box(dsc,
  3011. &(dsc->page[dsc->page_count-1].crop_box), 14))
  3012. return CDSC_ERROR;
  3013. }
  3014. }
  3015. else if (IS_DSC(line, "%%BeginFont:")) {
  3016. dsc->id = CDSC_BEGINFONT;
  3017. /* ignore Begin/EndFont, apart form making sure */
  3018. /* that they are matched. */
  3019. dsc->begin_font_count++;
  3020. }
  3021. else if (IS_DSC(line, "%%EndFont")) {
  3022. dsc->id = CDSC_BEGINFONT;
  3023. dsc->begin_font_count--;
  3024. }
  3025. else if (IS_DSC(line, "%%BeginFeature:")) {
  3026. dsc->id = CDSC_BEGINFEATURE;
  3027. /* ignore Begin/EndFeature, apart form making sure */
  3028. /* that they are matched. */
  3029. dsc->begin_feature_count++;
  3030. }
  3031. else if (IS_DSC(line, "%%EndFeature")) {
  3032. dsc->id = CDSC_ENDFEATURE;
  3033. dsc->begin_feature_count--;
  3034. }
  3035. else if (IS_DSC(line, "%%BeginResource:")) {
  3036. dsc->id = CDSC_BEGINRESOURCE;
  3037. /* ignore Begin/EndResource, apart form making sure */
  3038. /* that they are matched. */
  3039. dsc->begin_resource_count++;
  3040. }
  3041. else if (IS_DSC(line, "%%EndResource")) {
  3042. dsc->id = CDSC_ENDRESOURCE;
  3043. dsc->begin_resource_count--;
  3044. }
  3045. else if (IS_DSC(line, "%%BeginProcSet:")) {
  3046. dsc->id = CDSC_BEGINPROCSET;
  3047. /* ignore Begin/EndProcSet, apart form making sure */
  3048. /* that they are matched. */
  3049. dsc->begin_procset_count++;
  3050. }
  3051. else if (IS_DSC(line, "%%EndProcSet")) {
  3052. dsc->id = CDSC_ENDPROCSET;
  3053. dsc->begin_procset_count--;
  3054. }
  3055. else if (IS_DSC(line, "%%IncludeFont:")) {
  3056. dsc->id = CDSC_INCLUDEFONT;
  3057. /* ignore */
  3058. }
  3059. else {
  3060. /* All other DSC comments are unknown, but not an error */
  3061. dsc->id = CDSC_UNKNOWNDSC;
  3062. dsc_unknown(dsc);
  3063. }
  3064. if (dsc->page_count)
  3065. dsc->page[dsc->page_count-1].end = DSC_END(dsc);
  3066. return CDSC_OK;
  3067. }
  3068. /* Valid Trailer comments are
  3069. * %%Trailer
  3070. * %%EOF
  3071. * or the following deferred with (atend)
  3072. * %%BoundingBox:
  3073. * %%DocumentCustomColors:
  3074. * %%DocumentFiles:
  3075. * %%DocumentFonts:
  3076. * %%DocumentNeededFiles:
  3077. * %%DocumentNeededFonts:
  3078. * %%DocumentNeededProcSets:
  3079. * %%DocumentNeededResources:
  3080. * %%DocumentProcSets:
  3081. * %%DocumentProcessColors:
  3082. * %%DocumentSuppliedFiles:
  3083. * %%DocumentSuppliedFonts:
  3084. * %%DocumentSuppliedProcSets:
  3085. * %%DocumentSuppliedResources:
  3086. * %%Orientation:
  3087. * %%Pages:
  3088. * %%PageOrder:
  3089. *
  3090. * Our supported subset is
  3091. * %%Trailer
  3092. * %%EOF
  3093. * %%BoundingBox:
  3094. * %%CropBox:
  3095. * %%HiResBoundingBox:
  3096. * %%DocumentCustomColors:
  3097. * %%DocumentProcessColors:
  3098. * %%Orientation:
  3099. * %%Pages:
  3100. * %%PageOrder:
  3101. * In addition to these, we support
  3102. * %%DocumentMedia:
  3103. *
  3104. * A %%PageTrailer can have the following:
  3105. * %%PageBoundingBox:
  3106. * %%PageCustomColors:
  3107. * %%PageFiles:
  3108. * %%PageFonts:
  3109. * %%PageOrientation:
  3110. * %%PageProcessColors:
  3111. * %%PageResources:
  3112. */
  3113. dsc_private int
  3114. dsc_scan_trailer(CDSC *dsc)
  3115. {
  3116. /* Trailer section start at */
  3117. /* %%Trailer */
  3118. /* and ends at */
  3119. /* %%EOF */
  3120. char *line = dsc->line;
  3121. GSBOOL continued = FALSE;
  3122. dsc->id = CDSC_OK;
  3123. if (dsc->scan_section == scan_pre_trailer) {
  3124. if (IS_DSC(line, "%%Trailer")) {
  3125. dsc->id = CDSC_TRAILER;
  3126. dsc->begintrailer = DSC_START(dsc);
  3127. dsc->endtrailer = DSC_END(dsc);
  3128. dsc->scan_section = scan_trailer;
  3129. return CDSC_OK;
  3130. }
  3131. else if (IS_DSC(line, "%%EOF")) {
  3132. dsc->id = CDSC_EOF;
  3133. dsc->begintrailer = DSC_START(dsc);
  3134. dsc->endtrailer = DSC_END(dsc);
  3135. dsc->scan_section = scan_trailer;
  3136. /* Continue, in case we found %%EOF in an embedded document */
  3137. return CDSC_OK;
  3138. }
  3139. else {
  3140. /* %%Page: didn't follow %%EndSetup
  3141. * Keep reading until reach %%Page or %%Trailer
  3142. * and add it to setup section
  3143. */
  3144. /* append to previous section */
  3145. if (dsc->beginsetup)
  3146. dsc->endsetup = DSC_END(dsc);
  3147. else if (dsc->beginprolog)
  3148. dsc->endprolog = DSC_END(dsc);
  3149. else {
  3150. /* horribly confused */
  3151. }
  3152. return CDSC_OK;
  3153. }
  3154. }
  3155. /* Handle continuation lines.
  3156. * See comment above about our restrictive processing of
  3157. * continuation lines
  3158. */
  3159. if (IS_DSC(line, "%%+")) {
  3160. line = dsc->last_line;
  3161. continued = TRUE;
  3162. }
  3163. else
  3164. dsc_save_line(dsc);
  3165. if (NOT_DSC_LINE(line)) {
  3166. /* ignore */
  3167. }
  3168. else if (IS_DSC(dsc->line, "%%EOF")) {
  3169. /* Keep scanning, in case we have a false trailer */
  3170. dsc->id = CDSC_EOF;
  3171. }
  3172. else if (IS_DSC(dsc->line, "%%Trailer")) {
  3173. /* Cope with no pages with code after setup and before trailer. */
  3174. /* Last trailer is the correct one. */
  3175. dsc->id = CDSC_TRAILER;
  3176. dsc->begintrailer = DSC_START(dsc);
  3177. }
  3178. else if (IS_DSC(line, "%%Pages:")) {
  3179. dsc->id = CDSC_PAGES;
  3180. if (dsc_parse_pages(dsc) != 0)
  3181. return CDSC_ERROR;
  3182. }
  3183. else if (IS_DSC(line, "%%BoundingBox:")) {
  3184. dsc->id = CDSC_BOUNDINGBOX;
  3185. if (dsc_parse_bounding_box(dsc, &(dsc->bbox), continued ? 3 : 14))
  3186. return CDSC_ERROR;
  3187. }
  3188. else if (IS_DSC(line, "%%HiResBoundingBox:")) {
  3189. dsc->id = CDSC_HIRESBOUNDINGBOX;
  3190. if (dsc_parse_float_bounding_box(dsc, &(dsc->hires_bbox),
  3191. continued ? 3 : 19))
  3192. return CDSC_ERROR;
  3193. }
  3194. else if (IS_DSC(line, "%%CropBox:")) {
  3195. dsc->id = CDSC_CROPBOX;
  3196. if (dsc_parse_float_bounding_box(dsc, &(dsc->crop_box),
  3197. continued ? 3 : 10))
  3198. return CDSC_ERROR;
  3199. }
  3200. else if (IS_DSC(line, "%%Orientation:")) {
  3201. dsc->id = CDSC_ORIENTATION;
  3202. if (dsc_parse_orientation(dsc, &(dsc->page_orientation), continued ? 3 : 14))
  3203. return CDSC_ERROR;
  3204. }
  3205. else if (IS_DSC(line, "%%PageOrder:")) {
  3206. dsc->id = CDSC_PAGEORDER;
  3207. if (dsc_parse_order(dsc))
  3208. return CDSC_ERROR;
  3209. }
  3210. else if (IS_DSC(line, "%%DocumentMedia:")) {
  3211. dsc->id = CDSC_DOCUMENTMEDIA;
  3212. if (dsc_parse_document_media(dsc))
  3213. return CDSC_ERROR;
  3214. }
  3215. else if (IS_DSC(dsc->line, "%%Page:")) {
  3216. /* This should not occur in the trailer, but we might see
  3217. * this if a document has been incorrectly embedded.
  3218. */
  3219. int rc = dsc_error(dsc, CDSC_MESSAGE_PAGE_IN_TRAILER,
  3220. dsc->line, dsc->line_length);
  3221. switch (rc) {
  3222. case CDSC_RESPONSE_OK:
  3223. /* Assume that we are really in the previous */
  3224. /* page, not the trailer */
  3225. dsc->scan_section = scan_pre_pages;
  3226. if (dsc->page_count)
  3227. dsc->page[dsc->page_count-1].end = DSC_START(dsc);
  3228. return CDSC_PROPAGATE; /* try again */
  3229. case CDSC_RESPONSE_CANCEL:
  3230. /* ignore pages in trailer */
  3231. break;
  3232. case CDSC_RESPONSE_IGNORE_ALL:
  3233. return CDSC_NOTDSC;
  3234. }
  3235. }
  3236. else if (IS_DSC(line, "%%DocumentNeededFonts:")) {
  3237. dsc->id = CDSC_DOCUMENTNEEDEDFONTS;
  3238. /* ignore */
  3239. }
  3240. else if (IS_DSC(line, "%%DocumentSuppliedFonts:")) {
  3241. dsc->id = CDSC_DOCUMENTSUPPLIEDFONTS;
  3242. /* ignore */
  3243. }
  3244. else if (IS_DSC(line, "%%DocumentProcessColors:")) {
  3245. dsc->id = CDSC_DOCUMENTPROCESSCOLORS;
  3246. if (dsc_parse_process_colours(dsc) != CDSC_OK)
  3247. dsc->id = CDSC_UNKNOWNDSC;
  3248. }
  3249. else if (IS_DSC(line, "%%DocumentCustomColors:")) {
  3250. dsc->id = CDSC_DOCUMENTCUSTOMCOLORS;
  3251. if (dsc_parse_custom_colours(dsc) != CDSC_OK)
  3252. dsc->id = CDSC_UNKNOWNDSC;
  3253. }
  3254. else {
  3255. /* All other DSC comments are unknown, but not an error */
  3256. dsc->id = CDSC_UNKNOWNDSC;
  3257. dsc_unknown(dsc);
  3258. }
  3259. dsc->endtrailer = DSC_END(dsc);
  3260. return CDSC_OK;
  3261. }
  3262. dsc_private char *
  3263. dsc_alloc_string(CDSC *dsc, const char *str, int len)
  3264. {
  3265. char *p;
  3266. if (dsc->string_head == NULL) {
  3267. dsc->string_head = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
  3268. if (dsc->string_head == NULL)
  3269. return NULL; /* no memory */
  3270. dsc->string = dsc->string_head;
  3271. dsc->string->next = NULL;
  3272. dsc->string->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
  3273. if (dsc->string->data == NULL) {
  3274. dsc_reset(dsc);
  3275. return NULL; /* no memory */
  3276. }
  3277. dsc->string->index = 0;
  3278. dsc->string->length = CDSC_STRING_CHUNK;
  3279. }
  3280. if ( dsc->string->index + len + 1 > dsc->string->length) {
  3281. /* allocate another string block */
  3282. CDSCSTRING *newstring = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
  3283. if (newstring == NULL) {
  3284. dsc_debug_print(dsc, "Out of memory\n");
  3285. return NULL;
  3286. }
  3287. newstring->next = NULL;
  3288. newstring->length = 0;
  3289. newstring->index = 0;
  3290. newstring->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
  3291. if (newstring->data == NULL) {
  3292. dsc_memfree(dsc, newstring);
  3293. dsc_debug_print(dsc, "Out of memory\n");
  3294. return NULL; /* no memory */
  3295. }
  3296. newstring->length = CDSC_STRING_CHUNK;
  3297. dsc->string->next = newstring;
  3298. dsc->string = newstring;
  3299. }
  3300. if ( dsc->string->index + len + 1 > dsc->string->length)
  3301. return NULL; /* failed */
  3302. p = dsc->string->data + dsc->string->index;
  3303. memcpy(p, str, len);
  3304. *(p+len) = '\0';
  3305. dsc->string->index += len + 1;
  3306. return p;
  3307. }
  3308. /* store line, ignoring leading spaces */
  3309. dsc_private char *
  3310. dsc_add_line(CDSC *dsc, const char *line, unsigned int len)
  3311. {
  3312. char *newline;
  3313. unsigned int i;
  3314. while (len && (IS_WHITE(*line))) {
  3315. len--;
  3316. line++;
  3317. }
  3318. newline = dsc_alloc_string(dsc, line, len);
  3319. if (newline == NULL)
  3320. return NULL;
  3321. for (i=0; i<len; i++) {
  3322. if (newline[i] == '\r') {
  3323. newline[i]='\0';
  3324. break;
  3325. }
  3326. if (newline[i] == '\n') {
  3327. newline[i]='\0';
  3328. break;
  3329. }
  3330. }
  3331. return newline;
  3332. }
  3333. /* Copy string on line to new allocated string str */
  3334. /* String is always null terminated */
  3335. /* String is no longer than len */
  3336. /* Return pointer to string */
  3337. /* Store number of used characters from line */
  3338. /* Don't copy enclosing () */
  3339. dsc_private char *
  3340. dsc_copy_string(char *str, unsigned int slen, char *line,
  3341. unsigned int len, unsigned int *offset)
  3342. {
  3343. int quoted = FALSE;
  3344. int instring=0;
  3345. unsigned int newlength = 0;
  3346. unsigned int i = 0;
  3347. unsigned char ch;
  3348. if (len > slen)
  3349. len = slen-1;
  3350. while ( (i<len) && IS_WHITE(line[i]))
  3351. i++; /* skip leading spaces */
  3352. if ((i < len) && (line[i]=='(')) {
  3353. quoted = TRUE;
  3354. instring++;
  3355. i++; /* don't copy outside () */
  3356. }
  3357. while (i < len) {
  3358. str[newlength] = ch = line[i];
  3359. i++;
  3360. if (quoted) {
  3361. if (ch == '(')
  3362. instring++;
  3363. if (ch == ')')
  3364. instring--;
  3365. if (instring==0)
  3366. break;
  3367. }
  3368. else if (ch == ' ')
  3369. break;
  3370. if (ch == '\r')
  3371. break;
  3372. if (ch == '\n')
  3373. break;
  3374. else if ( (ch == '\\') && (i+1 < len) ) {
  3375. ch = line[i];
  3376. if ((ch >= '0') && (ch <= '9')) {
  3377. /* octal coded character */
  3378. int j = 3;
  3379. ch = 0;
  3380. while (j && (i < len) && line[i]>='0' && line[i]<='7') {
  3381. ch = (unsigned char)((ch<<3) + (line[i]-'0'));
  3382. i++;
  3383. j--;
  3384. }
  3385. str[newlength] = ch;
  3386. }
  3387. else if (ch == '(') {
  3388. str[newlength] = ch;
  3389. i++;
  3390. }
  3391. else if (ch == ')') {
  3392. str[newlength] = ch;
  3393. i++;
  3394. }
  3395. else if (ch == 'b') {
  3396. str[newlength] = '\b';
  3397. i++;
  3398. }
  3399. else if (ch == 'f') {
  3400. str[newlength] = '\b';
  3401. i++;
  3402. }
  3403. else if (ch == 'n') {
  3404. str[newlength] = '\n';
  3405. i++;
  3406. }
  3407. else if (ch == 'r') {
  3408. str[newlength] = '\r';
  3409. i++;
  3410. }
  3411. else if (ch == 't') {
  3412. str[newlength] = '\t';
  3413. i++;
  3414. }
  3415. else if (ch == '\\') {
  3416. str[newlength] = '\\';
  3417. i++;
  3418. }
  3419. }
  3420. newlength++;
  3421. }
  3422. str[newlength] = '\0';
  3423. if (offset != (unsigned int *)NULL)
  3424. *offset = i;
  3425. return str;
  3426. }
  3427. dsc_private int
  3428. dsc_get_int(const char *line, unsigned int len, unsigned int *offset)
  3429. {
  3430. char newline[MAXSTR];
  3431. int newlength = 0;
  3432. unsigned int i = 0;
  3433. unsigned char ch;
  3434. len = min(len, sizeof(newline)-1);
  3435. while ((i<len) && IS_WHITE(line[i]))
  3436. i++; /* skip leading spaces */
  3437. while (i < len) {
  3438. newline[newlength] = ch = line[i];
  3439. if (!(isdigit(ch) || (ch=='-') || (ch=='+')))
  3440. break; /* not part of an integer number */
  3441. i++;
  3442. newlength++;
  3443. }
  3444. while ((i<len) && IS_WHITE(line[i]))
  3445. i++; /* skip trailing spaces */
  3446. newline[newlength] = '\0';
  3447. if (offset != (unsigned int *)NULL)
  3448. *offset = i;
  3449. return atoi(newline);
  3450. }
  3451. dsc_private float
  3452. dsc_get_real(const char *line, unsigned int len, unsigned int *offset)
  3453. {
  3454. char newline[MAXSTR];
  3455. int newlength = 0;
  3456. unsigned int i = 0;
  3457. unsigned char ch;
  3458. len = min(len, sizeof(newline)-1);
  3459. while ((i<len) && IS_WHITE(line[i]))
  3460. i++; /* skip leading spaces */
  3461. while (i < len) {
  3462. newline[newlength] = ch = line[i];
  3463. if (!(isdigit(ch) || (ch=='.') || (ch=='-') || (ch=='+')
  3464. || (ch=='e') || (ch=='E')))
  3465. break; /* not part of a real number */
  3466. i++;
  3467. newlength++;
  3468. }
  3469. while ((i<len) && IS_WHITE(line[i]))
  3470. i++; /* skip trailing spaces */
  3471. newline[newlength] = '\0';
  3472. if (offset != (unsigned int *)NULL)
  3473. *offset = i;
  3474. return (float)atof(newline);
  3475. }
  3476. int
  3477. dsc_stricmp(const char *s, const char *t)
  3478. {
  3479. while (toupper(*s) == toupper(*t)) {
  3480. if (*s == '\0')
  3481. return 0;
  3482. s++;
  3483. t++;
  3484. }
  3485. return (toupper(*s) - toupper(*t));
  3486. }
  3487. dsc_private int
  3488. dsc_parse_page(CDSC *dsc)
  3489. {
  3490. char *p;
  3491. unsigned int i;
  3492. char page_label[MAXSTR];
  3493. char *pl;
  3494. int page_ordinal;
  3495. int page_number;
  3496. p = dsc->line + 7;
  3497. pl = dsc_copy_string(page_label, sizeof(page_label), p, dsc->line_length-7, &i);
  3498. if (pl == NULL)
  3499. return CDSC_ERROR;
  3500. p += i;
  3501. if (dsc->line_length - 7 - i == 0) {
  3502. /* Ordinal missing, or parentheses not matched in label */
  3503. /* Try to find ordinal at end of line */
  3504. while (i > 0) {
  3505. if (!IS_WHITE_OR_EOL(p[-1]))
  3506. break;
  3507. p--;
  3508. i--;
  3509. }
  3510. while (i > 0) {
  3511. if (!isdigit((int)p[-1]))
  3512. break;
  3513. p--;
  3514. i--;
  3515. }
  3516. }
  3517. page_ordinal = dsc_get_int(p, dsc->line_length - 7 - i, NULL);
  3518. if ( (page_ordinal == 0) || (strlen(page_label) == 0) ||
  3519. ((dsc->page_count == 0) && (page_ordinal != 1)) ||
  3520. (dsc->page_count &&
  3521. (page_ordinal != dsc->page[dsc->page_count-1].ordinal+1)) ) {
  3522. int rc = dsc_error(dsc, CDSC_MESSAGE_PAGE_ORDINAL, dsc->line,
  3523. dsc->line_length);
  3524. switch (rc) {
  3525. case CDSC_RESPONSE_OK:
  3526. /* ignore this page */
  3527. return CDSC_OK;
  3528. case CDSC_RESPONSE_CANCEL:
  3529. /* accept the page */
  3530. break;
  3531. case CDSC_RESPONSE_IGNORE_ALL:
  3532. return CDSC_NOTDSC;
  3533. }
  3534. }
  3535. page_number = dsc->page_count;
  3536. dsc_add_page(dsc, page_ordinal, page_label);
  3537. dsc->page[page_number].begin = DSC_START(dsc);
  3538. dsc->page[page_number].end = DSC_START(dsc);
  3539. if (dsc->page[page_number].label == NULL)
  3540. return CDSC_ERROR; /* no memory */
  3541. return CDSC_OK;
  3542. }
  3543. dsc_private int
  3544. dsc_parse_feature(CDSC *dsc)
  3545. {
  3546. char *p;
  3547. unsigned int i;
  3548. char feature_name[MAXSTR];
  3549. char feature_value[MAXSTR];
  3550. char *fn;
  3551. char *fv;
  3552. feature_name[0] = '\0';
  3553. feature_value[0] = '\0';
  3554. p = dsc->line + 15; /* %%BeginFeature: */
  3555. fn = dsc_copy_string(feature_name, sizeof(feature_name),
  3556. p, dsc->line_length-15, &i);
  3557. if (fn == NULL)
  3558. return CDSC_ERROR;
  3559. p += i;
  3560. fv = dsc_copy_string(feature_value, sizeof(feature_value),
  3561. p, dsc->line_length-15-i, &i);
  3562. if ((dsc_stricmp(feature_name, "*PageSize") == 0) &&
  3563. (fv != NULL) &&
  3564. (dsc->scan_section == scan_setup)) {
  3565. /* If this media was not specified in the header and the name
  3566. * is known to us, add it to the media list
  3567. */
  3568. int found = 0;
  3569. int media_index = -1;
  3570. for (i=0; i<dsc->media_count; i++) {
  3571. if (dsc->media[i]->name &&
  3572. (dsc_stricmp(feature_value, dsc->media[i]->name) == 0))
  3573. found = 1; /* don't add it again */
  3574. }
  3575. for (i=0; dsc_known_media[i].name; i++) {
  3576. if (dsc_stricmp(feature_value, dsc_known_media[i].name)==0) {
  3577. media_index = i; /* we know this paper size */
  3578. break;
  3579. }
  3580. }
  3581. if (!found && (media_index >= 0)) {
  3582. /* This media type was not included in the header where
  3583. * it should have been. Add it to the media list now.
  3584. */
  3585. CDSCMEDIA lmedia;
  3586. lmedia.name = feature_value;
  3587. lmedia.width = dsc_known_media[i].width;
  3588. lmedia.height = dsc_known_media[i].height;
  3589. lmedia.weight = 80.0;
  3590. lmedia.colour = NULL;
  3591. lmedia.type = NULL;
  3592. lmedia.mediabox = NULL;
  3593. if (dsc_add_media(dsc, &lmedia))
  3594. return CDSC_ERROR; /* out of memory */
  3595. }
  3596. }
  3597. return CDSC_OK;
  3598. }
  3599. /* DSC error reporting */
  3600. void
  3601. dsc_debug_print(CDSC *dsc, const char *str)
  3602. {
  3603. if (dsc->debug_print_fn)
  3604. dsc->debug_print_fn(dsc->caller_data, str);
  3605. }
  3606. /* Display a message about a problem with the DSC comments.
  3607. *
  3608. * explanation = an index to to a multiline explanation in dsc_message[]
  3609. * line = pointer to the offending DSC line (if any)
  3610. * return code =
  3611. * CDSC_RESPONSE_OK DSC was wrong, make a guess about what
  3612. * was really meant.
  3613. * CDSC_RESPONSE_CANCEL Assume DSC was correct, ignore if it
  3614. * is misplaced.
  3615. * CDSC_RESPONSE_IGNORE_ALL Ignore all DSC.
  3616. */
  3617. /* Silent operation. Don't display errors. */
  3618. dsc_private int
  3619. dsc_error(CDSC *dsc, unsigned int explanation,
  3620. char *line, unsigned int line_len)
  3621. {
  3622. if (explanation > DSC_MAX_ERROR)
  3623. return CDSC_RESPONSE_CANCEL;
  3624. if ((int)dsc->worst_error < (int)dsc_severity[explanation])
  3625. dsc->worst_error = dsc_severity[explanation];
  3626. /* if error function provided, use it */
  3627. if (dsc->dsc_error_fn)
  3628. return dsc->dsc_error_fn(dsc->caller_data, dsc,
  3629. explanation, line, line_len);
  3630. /* treat DSC as being correct */
  3631. return CDSC_RESPONSE_CANCEL;
  3632. }
  3633. /* Fixup if DCS 2.0 was used */
  3634. dsc_private int
  3635. dsc_dcs2_fixup(CDSC *dsc)
  3636. {
  3637. char composite[] = "Composite";
  3638. /* If DCS 2.0 single file format found, expose the separations
  3639. * as multiple pages. Treat the initial EPS file as a single
  3640. * page without comments, prolog or trailer.
  3641. */
  3642. if (dsc->dcs2) {
  3643. int code = CDSC_OK;
  3644. int page_number;
  3645. DSC_OFFSET *pbegin;
  3646. DSC_OFFSET *pend;
  3647. DSC_OFFSET end;
  3648. CDCS2 *pdcs = dsc->dcs2;
  3649. /* Now treat the initial EPS file as a single page without
  3650. * headers or trailer, so page extraction will fetch the
  3651. * the correct separation. */
  3652. if (dsc->page_count == 0)
  3653. code = dsc_add_page(dsc, 1, composite);
  3654. else if (dsc->page_count == 1)
  3655. dsc->page[0].label =
  3656. dsc_alloc_string(dsc, composite, (int)strlen(composite)+1);
  3657. if (code != CDSC_OK)
  3658. return code;
  3659. page_number = dsc->page_count - 1;
  3660. pbegin = &dsc->page[page_number].begin;
  3661. pend = &dsc->page[page_number].end;
  3662. if (*pbegin == *pend) {
  3663. /* no page, so force it to conform to the following sections */
  3664. *pbegin = 999999999;
  3665. *pend = 0;
  3666. }
  3667. if (dsc->begincomments != dsc->endcomments) {
  3668. *pbegin = min(dsc->begincomments, *pbegin);
  3669. dsc->begincomments = 0;
  3670. *pend = max(dsc->endcomments, *pend);
  3671. dsc->endcomments = 0;
  3672. }
  3673. if (dsc->beginpreview != dsc->endpreview) {
  3674. *pbegin = min(dsc->beginpreview, *pbegin);
  3675. dsc->beginpreview = 0;
  3676. *pend = max(dsc->endpreview, *pend);
  3677. dsc->endpreview = 0;
  3678. }
  3679. if (dsc->begindefaults != dsc->enddefaults) {
  3680. *pbegin = min(dsc->begindefaults, *pbegin);
  3681. dsc->begindefaults = 0;
  3682. *pend = max(dsc->enddefaults, *pend);
  3683. dsc->enddefaults = 0;
  3684. }
  3685. if (dsc->beginprolog != dsc->endprolog) {
  3686. *pbegin = min(dsc->beginprolog, *pbegin);
  3687. dsc->beginprolog = 0;
  3688. *pend = max(dsc->endprolog, *pend);
  3689. dsc->endprolog = 0;
  3690. }
  3691. if (dsc->beginsetup != dsc->endsetup) {
  3692. *pbegin = min(dsc->beginsetup, *pbegin);
  3693. dsc->beginsetup = 0;
  3694. *pend = max(dsc->endsetup, *pend);
  3695. dsc->endsetup = 0;
  3696. }
  3697. if (dsc->begintrailer != dsc->endtrailer) {
  3698. *pbegin = min(dsc->begintrailer, *pbegin);
  3699. dsc->begintrailer = 0;
  3700. *pend = max(dsc->endtrailer, *pend);
  3701. dsc->endtrailer = 0;
  3702. }
  3703. if (*pbegin == 999999999)
  3704. *pbegin = *pend;
  3705. end = 0; /* end of composite is start of first separation */
  3706. while (pdcs) {
  3707. page_number = dsc->page_count;
  3708. if ((pdcs->begin) && (pdcs->colourname != NULL)) {
  3709. /* Single file DCS 2.0 */
  3710. code = dsc_add_page(dsc, page_number+1, pdcs->colourname);
  3711. if (code)
  3712. return code;
  3713. dsc->page[page_number].begin = pdcs->begin;
  3714. dsc->page[page_number].end = pdcs->end;
  3715. if (end != 0)
  3716. end = min(end, pdcs->begin);
  3717. else
  3718. end = pdcs->begin; /* first separation */
  3719. }
  3720. else {
  3721. /* Multiple file DCS 2.0 */
  3722. if ((pdcs->location != NULL) &&
  3723. (pdcs->filetype != NULL) &&
  3724. (pdcs->colourname != NULL) &&
  3725. (dsc_stricmp(pdcs->location, "Local") == 0) &&
  3726. ((dsc_stricmp(pdcs->filetype, "EPS") == 0) ||
  3727. (dsc_stricmp(pdcs->filetype, "EPSF") == 0))) {
  3728. code = dsc_add_page(dsc, page_number+1, pdcs->colourname);
  3729. if (code)
  3730. return code;
  3731. dsc->page[page_number].begin = 0;
  3732. dsc->page[page_number].end = 0;
  3733. }
  3734. }
  3735. pdcs = pdcs->next;
  3736. }
  3737. /* end of composite is start of first separation */
  3738. if (end != 0)
  3739. *pend = end;
  3740. /* According to the DCS2 specification, the size of the composite
  3741. * section can be determined by the smallest #offset.
  3742. * Some incorrect DCS2 files don't put the separations inside
  3743. * the DOS EPS PostScript section, and have a TIFF separation
  3744. * between the composite and the first separation. This
  3745. * contravenes the DCS2 specification. If we see one of these
  3746. * files, bring the end of the composite back to the end of
  3747. * the DOS EPS PostScript section.
  3748. */
  3749. if (dsc->doseps_end && (*pend > dsc->doseps_end))
  3750. *pend = dsc->doseps_end;
  3751. }
  3752. return 0;
  3753. }
  3754. dsc_private int
  3755. dsc_parse_platefile(CDSC *dsc)
  3756. {
  3757. unsigned int i, n;
  3758. CDCS2 dcs2;
  3759. CDCS2 *pdcs2;
  3760. char colourname[MAXSTR];
  3761. char filetype[MAXSTR];
  3762. char location[MAXSTR];
  3763. char *filename = NULL;
  3764. int filename_length = 0;
  3765. GSBOOL blank_line;
  3766. GSBOOL single = FALSE;
  3767. if (IS_DSC(dsc->line, "%%PlateFile:"))
  3768. n = 12;
  3769. else if (IS_DSC(dsc->line, "%%+"))
  3770. n = 3;
  3771. else
  3772. return CDSC_ERROR; /* error */
  3773. memset(&dcs2, 0, sizeof(dcs2));
  3774. memset(&colourname, 0, sizeof(colourname));
  3775. memset(&filetype, 0, sizeof(filetype));
  3776. memset(&location, 0, sizeof(location));
  3777. memset(&filename, 0, sizeof(filename));
  3778. /* check for blank remainder of line */
  3779. blank_line = TRUE;
  3780. for (i=n; i<dsc->line_length; i++) {
  3781. if (!IS_WHITE_OR_EOL(dsc->line[i])) {
  3782. blank_line = FALSE;
  3783. break;
  3784. }
  3785. }
  3786. if (!blank_line) {
  3787. dsc_copy_string(colourname, sizeof(colourname),
  3788. dsc->line+n, dsc->line_length-n, &i);
  3789. n+=i;
  3790. if (i)
  3791. dsc_copy_string(filetype, sizeof(filetype),
  3792. dsc->line+n, dsc->line_length-n, &i);
  3793. n+=i;
  3794. while (IS_WHITE_OR_EOL(dsc->line[n]))
  3795. n++;
  3796. if (dsc->line[n] == '#') {
  3797. /* single file DCS 2.0 */
  3798. single = TRUE;
  3799. n++;
  3800. if (i)
  3801. dcs2.begin= dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
  3802. n+=i;
  3803. if (i)
  3804. dcs2.end= dcs2.begin +
  3805. dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
  3806. }
  3807. else {
  3808. /* multiple file DCS 2.0 */
  3809. if (i)
  3810. dsc_copy_string(location, sizeof(location),
  3811. dsc->line+n, dsc->line_length-n, &i);
  3812. n+=i;
  3813. if (i) {
  3814. filename = dsc->line+n;
  3815. filename_length = dsc->line_length-n;
  3816. if (filename[0] == '(') {
  3817. /* Filename in parentheses like a PS string */
  3818. int j;
  3819. for (j=0; j<filename_length; j++)
  3820. if (filename[j] == ')')
  3821. break;
  3822. if (j < filename_length) {
  3823. filename++;
  3824. filename_length = j-1;
  3825. }
  3826. }
  3827. }
  3828. }
  3829. if (i==0)
  3830. dsc_unknown(dsc); /* we didn't get all fields */
  3831. else {
  3832. /* Allocate strings */
  3833. if (strlen(colourname))
  3834. dcs2.colourname = dsc_alloc_string(dsc,
  3835. colourname, (int)strlen(colourname));
  3836. if (strlen(filetype))
  3837. dcs2.filetype = dsc_alloc_string(dsc,
  3838. filetype, (int)strlen(filetype));
  3839. if (strlen(location))
  3840. dcs2.location = dsc_alloc_string(dsc,
  3841. location, (int)strlen(location));
  3842. if (filename)
  3843. dcs2.filename = dsc_add_line(dsc, filename, filename_length);
  3844. /* Prevent parser from reading separations */
  3845. if (single)
  3846. dsc->file_length = min(dsc->file_length, dcs2.begin);
  3847. /* Allocate it */
  3848. pdcs2 = (CDCS2 *)dsc_memalloc(dsc, sizeof(CDCS2));
  3849. if (pdcs2 == NULL)
  3850. return CDSC_ERROR; /* out of memory */
  3851. memcpy(pdcs2, &dcs2, sizeof(CDCS2));
  3852. /* Then add to list of separations */
  3853. if (dsc->dcs2 == NULL)
  3854. dsc->dcs2 = pdcs2;
  3855. else {
  3856. CDCS2 *this_dcs2 = dsc->dcs2;
  3857. while (this_dcs2->next)
  3858. this_dcs2 = this_dcs2->next;
  3859. this_dcs2->next = pdcs2;
  3860. }
  3861. }
  3862. }
  3863. return CDSC_OK;
  3864. }
  3865. /* Parse a DCS 1.0 plate comment, storing like a multi file DSC 2.0 */
  3866. dsc_private int
  3867. dsc_parse_dcs1plate(CDSC *dsc)
  3868. {
  3869. unsigned int i, n = 0;
  3870. CDCS2 dcs2;
  3871. CDCS2 *pdcs2;
  3872. const char *colourname;
  3873. char *filename = NULL;
  3874. int filename_length = 0;
  3875. GSBOOL blank_line;
  3876. GSBOOL continued = FALSE;
  3877. char *line = dsc->line;
  3878. memset(&dcs2, 0, sizeof(dcs2));
  3879. memset(&filename, 0, sizeof(filename));
  3880. if (IS_DSC(line, "%%+")) {
  3881. n = 3;
  3882. line = dsc->last_line;
  3883. continued = TRUE;
  3884. }
  3885. if (IS_DSC(line, "%%CyanPlate:")) {
  3886. colourname = "Cyan";
  3887. if (!continued)
  3888. n = 12;
  3889. }
  3890. else if (IS_DSC(line, "%%MagentaPlate:")) {
  3891. colourname = "Magenta";
  3892. if (!continued)
  3893. n = 15;
  3894. }
  3895. else if (IS_DSC(line, "%%YellowPlate:")) {
  3896. colourname = "Yellow";
  3897. if (!continued)
  3898. n = 14;
  3899. }
  3900. else if (IS_DSC(line, "%%BlackPlate:")) {
  3901. colourname = "Black";
  3902. if (!continued)
  3903. n = 13;
  3904. }
  3905. else
  3906. return CDSC_ERROR; /* error */
  3907. /* check for blank remainder of line */
  3908. blank_line = TRUE;
  3909. for (i=n; i<dsc->line_length; i++) {
  3910. if (!IS_WHITE_OR_EOL(dsc->line[i])) {
  3911. blank_line = FALSE;
  3912. break;
  3913. }
  3914. }
  3915. if (!blank_line) {
  3916. filename = dsc->line+n;
  3917. filename_length = dsc->line_length - n;
  3918. if ((filename_length==0) || (strlen(filename) == 0))
  3919. dsc_unknown(dsc); /* we didn't get all fields */
  3920. else {
  3921. /* Allocate strings */
  3922. dcs2.colourname = dsc_alloc_string(dsc,
  3923. colourname, (int)strlen(colourname));
  3924. dcs2.filetype = dsc_alloc_string(dsc, "EPS", 3);
  3925. dcs2.location = dsc_alloc_string(dsc, "Local", 5);
  3926. dcs2.filename = dsc_add_line(dsc, filename, filename_length);
  3927. /* Allocate it */
  3928. pdcs2 = (CDCS2 *)dsc_memalloc(dsc, sizeof(CDCS2));
  3929. if (pdcs2 == NULL)
  3930. return CDSC_ERROR; /* out of memory */
  3931. memcpy(pdcs2, &dcs2, sizeof(CDCS2));
  3932. /* Then add to list of separations */
  3933. if (dsc->dcs2 == NULL)
  3934. dsc->dcs2 = pdcs2;
  3935. else {
  3936. CDCS2 *this_dcs2 = dsc->dcs2;
  3937. while (this_dcs2->next)
  3938. this_dcs2 = this_dcs2->next;
  3939. this_dcs2->next = pdcs2;
  3940. }
  3941. /* We've set the DCS 2.0 data, but it really is DCS 1.0 */
  3942. dsc->dcs1 = TRUE;
  3943. }
  3944. }
  3945. return CDSC_OK;
  3946. }
  3947. /* Find the filename which corresponds to this separation.
  3948. * Used with multiple file DCS 2.0.
  3949. * Returns NULL if there is no filename, or not DCS 2.0,
  3950. * or single file DCS 2.0.
  3951. * Caller will need to obtain the filesize from the file.
  3952. */
  3953. const char *
  3954. dsc_find_platefile(CDSC *dsc, int page)
  3955. {
  3956. CDCS2 *pdcs = dsc->dcs2;
  3957. int i = 1;
  3958. while (pdcs) {
  3959. if (pdcs->begin != pdcs->end)
  3960. return NULL; /* Single file DCS 2.0 */
  3961. if (pdcs->location && pdcs->filetype && pdcs->colourname
  3962. && (dsc_stricmp(pdcs->location, "Local") == 0)
  3963. && ((dsc_stricmp(pdcs->filetype, "EPS") == 0) ||
  3964. (dsc_stricmp(pdcs->filetype, "EPSF") == 0))) {
  3965. if (i == page)
  3966. return pdcs->filename;
  3967. i++;
  3968. }
  3969. pdcs = pdcs->next;
  3970. }
  3971. return NULL;
  3972. }
  3973. dsc_private CDSCCOLOUR *
  3974. dsc_find_colour(CDSC *dsc, const char *colourname)
  3975. {
  3976. CDSCCOLOUR *colour = dsc->colours;
  3977. while (colour) {
  3978. if (colour->name && (dsc_stricmp(colour->name, colourname)==0))
  3979. return colour;
  3980. colour = colour->next;
  3981. }
  3982. return 0;
  3983. }
  3984. dsc_private int
  3985. dsc_parse_process_colours(CDSC *dsc)
  3986. {
  3987. unsigned int i, n;
  3988. CDSCCOLOUR *pcolour;
  3989. char colourname[MAXSTR];
  3990. GSBOOL blank_line;
  3991. if (IS_DSC(dsc->line, "%%DocumentProcessColors:"))
  3992. n = 24;
  3993. else if (IS_DSC(dsc->line, "%%+"))
  3994. n = 3;
  3995. else
  3996. return CDSC_ERROR; /* error */
  3997. memset(&colourname, 0, sizeof(colourname));
  3998. /* check for blank remainder of line */
  3999. blank_line = TRUE;
  4000. for (i=n; i<dsc->line_length; i++) {
  4001. if (!IS_WHITE_OR_EOL(dsc->line[i])) {
  4002. blank_line = FALSE;
  4003. break;
  4004. }
  4005. }
  4006. while (IS_WHITE(dsc->line[n]))
  4007. n++;
  4008. if (COMPARE(dsc->line+n, "(atend)")) {
  4009. if (dsc->scan_section == scan_comments)
  4010. blank_line = TRUE;
  4011. else {
  4012. dsc_unknown(dsc);
  4013. return CDSC_NOTDSC;
  4014. }
  4015. }
  4016. if (!blank_line) {
  4017. do {
  4018. dsc_copy_string(colourname, sizeof(colourname),
  4019. dsc->line+n, dsc->line_length-n, &i);
  4020. n+=i;
  4021. if (i && strlen(colourname)) {
  4022. if ((pcolour = dsc_find_colour(dsc, colourname)) == NULL) {
  4023. pcolour = (CDSCCOLOUR *)
  4024. dsc_memalloc(dsc, sizeof(CDSCCOLOUR));
  4025. if (pcolour == NULL)
  4026. return CDSC_ERROR; /* out of memory */
  4027. memset(pcolour, 0, sizeof(CDSCCOLOUR));
  4028. pcolour->custom = CDSC_CUSTOM_COLOUR_UNKNOWN;
  4029. pcolour->name = dsc_alloc_string(dsc,
  4030. colourname, (int)strlen(colourname));
  4031. if (dsc->colours == NULL)
  4032. dsc->colours = pcolour;
  4033. else {
  4034. CDSCCOLOUR *this_colour = dsc->colours;
  4035. while (this_colour->next)
  4036. this_colour = this_colour->next;
  4037. this_colour->next = pcolour;
  4038. }
  4039. }
  4040. pcolour->type = CDSC_COLOUR_PROCESS;
  4041. if (dsc_stricmp(colourname, "Cyan")==0) {
  4042. pcolour->custom = CDSC_CUSTOM_COLOUR_CMYK;
  4043. pcolour->cyan = 1.0;
  4044. pcolour->magenta = pcolour->yellow = pcolour->black = 0.0;
  4045. }
  4046. else if (dsc_stricmp(colourname, "Magenta")==0) {
  4047. pcolour->custom = CDSC_CUSTOM_COLOUR_CMYK;
  4048. pcolour->magenta = 1.0;
  4049. pcolour->cyan = pcolour->yellow = pcolour->black = 0.0;
  4050. }
  4051. else if (dsc_stricmp(colourname, "Yellow")==0) {
  4052. pcolour->custom = CDSC_CUSTOM_COLOUR_CMYK;
  4053. pcolour->yellow = 1.0;
  4054. pcolour->cyan = pcolour->magenta = pcolour->black = 0.0;
  4055. }
  4056. else if (dsc_stricmp(colourname, "Black")==0) {
  4057. pcolour->custom = CDSC_CUSTOM_COLOUR_CMYK;
  4058. pcolour->black = 1.0;
  4059. pcolour->cyan = pcolour->magenta = pcolour->yellow = 0.0;
  4060. }
  4061. else if (dsc_stricmp(colourname, "Red")==0) {
  4062. pcolour->custom = CDSC_CUSTOM_COLOUR_RGB;
  4063. pcolour->red = 1.0;
  4064. pcolour->green = pcolour->blue = 0.0;
  4065. }
  4066. else if (dsc_stricmp(colourname, "Green")==0) {
  4067. pcolour->custom = CDSC_CUSTOM_COLOUR_RGB;
  4068. pcolour->green = 1.0;
  4069. pcolour->red = pcolour->blue = 0.0;
  4070. }
  4071. else if (dsc_stricmp(colourname, "Blue")==0) {
  4072. pcolour->custom = CDSC_CUSTOM_COLOUR_RGB;
  4073. pcolour->blue = 1.0;
  4074. pcolour->red = pcolour->green = 0.0;
  4075. }
  4076. }
  4077. } while (i != 0);
  4078. }
  4079. return CDSC_OK;
  4080. }
  4081. dsc_private int
  4082. dsc_parse_custom_colours(CDSC *dsc)
  4083. {
  4084. unsigned int i, n;
  4085. CDSCCOLOUR *pcolour;
  4086. char colourname[MAXSTR];
  4087. GSBOOL blank_line;
  4088. if (IS_DSC(dsc->line, "%%DocumentCustomColors:"))
  4089. n = 23;
  4090. else if (IS_DSC(dsc->line, "%%+"))
  4091. n = 3;
  4092. else
  4093. return CDSC_ERROR; /* error */
  4094. memset(&colourname, 0, sizeof(colourname));
  4095. /* check for blank remainder of line */
  4096. blank_line = TRUE;
  4097. for (i=n; i<dsc->line_length; i++) {
  4098. if (!IS_WHITE_OR_EOL(dsc->line[i])) {
  4099. blank_line = FALSE;
  4100. break;
  4101. }
  4102. }
  4103. while (IS_WHITE(dsc->line[n]))
  4104. n++;
  4105. if (COMPARE(dsc->line+n, "(atend)")) {
  4106. if (dsc->scan_section == scan_comments)
  4107. blank_line = TRUE;
  4108. else {
  4109. dsc_unknown(dsc);
  4110. return CDSC_NOTDSC;
  4111. }
  4112. }
  4113. if (!blank_line) {
  4114. do {
  4115. dsc_copy_string(colourname, sizeof(colourname),
  4116. dsc->line+n, dsc->line_length-n, &i);
  4117. n+=i;
  4118. if (i && strlen(colourname)) {
  4119. if ((pcolour = dsc_find_colour(dsc, colourname)) == NULL) {
  4120. pcolour = (CDSCCOLOUR *)
  4121. dsc_memalloc(dsc, sizeof(CDSCCOLOUR));
  4122. if (pcolour == NULL)
  4123. return CDSC_ERROR; /* out of memory */
  4124. memset(pcolour, 0, sizeof(CDSCCOLOUR));
  4125. pcolour->name = dsc_alloc_string(dsc,
  4126. colourname, (int)strlen(colourname));
  4127. pcolour->custom = CDSC_CUSTOM_COLOUR_UNKNOWN;
  4128. if (dsc->colours == NULL)
  4129. dsc->colours = pcolour;
  4130. else {
  4131. CDSCCOLOUR *this_colour = dsc->colours;
  4132. while (this_colour->next)
  4133. this_colour = this_colour->next;
  4134. this_colour->next = pcolour;
  4135. }
  4136. }
  4137. pcolour->type = CDSC_COLOUR_CUSTOM;
  4138. }
  4139. } while (i != 0);
  4140. }
  4141. return CDSC_OK;
  4142. }
  4143. dsc_private int
  4144. dsc_parse_cmyk_custom_colour(CDSC *dsc)
  4145. {
  4146. unsigned int i, n;
  4147. CDSCCOLOUR *pcolour;
  4148. char colourname[MAXSTR];
  4149. float cyan, magenta, yellow, black;
  4150. GSBOOL blank_line;
  4151. if (IS_DSC(dsc->line, "%%CMYKCustomColor:"))
  4152. n = 18;
  4153. else if (IS_DSC(dsc->line, "%%+"))
  4154. n = 3;
  4155. else
  4156. return CDSC_ERROR; /* error */
  4157. memset(&colourname, 0, sizeof(colourname));
  4158. /* check for blank remainder of line */
  4159. do {
  4160. blank_line = TRUE;
  4161. for (i=n; i<dsc->line_length; i++) {
  4162. if (!IS_WHITE_OR_EOL(dsc->line[i])) {
  4163. blank_line = FALSE;
  4164. break;
  4165. }
  4166. }
  4167. if (blank_line)
  4168. break;
  4169. else {
  4170. cyan = magenta = yellow = black = 0.0;
  4171. cyan = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  4172. n += i;
  4173. if (i)
  4174. magenta = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  4175. n += i;
  4176. if (i)
  4177. yellow = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  4178. n += i;
  4179. if (i)
  4180. black = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  4181. n += i;
  4182. if (i)
  4183. dsc_copy_string(colourname, sizeof(colourname),
  4184. dsc->line+n, dsc->line_length-n, &i);
  4185. n+=i;
  4186. if (i && strlen(colourname)) {
  4187. if ((pcolour = dsc_find_colour(dsc, colourname)) == NULL) {
  4188. pcolour = (CDSCCOLOUR *)
  4189. dsc_memalloc(dsc, sizeof(CDSCCOLOUR));
  4190. if (pcolour == NULL)
  4191. return CDSC_ERROR; /* out of memory */
  4192. memset(pcolour, 0, sizeof(CDSCCOLOUR));
  4193. pcolour->name = dsc_alloc_string(dsc,
  4194. colourname, (int)strlen(colourname));
  4195. pcolour->type = CDSC_COLOUR_UNKNOWN;
  4196. if (dsc->colours == NULL)
  4197. dsc->colours = pcolour;
  4198. else {
  4199. CDSCCOLOUR *this_colour = dsc->colours;
  4200. while (this_colour->next)
  4201. this_colour = this_colour->next;
  4202. this_colour->next = pcolour;
  4203. }
  4204. }
  4205. pcolour->custom = CDSC_CUSTOM_COLOUR_CMYK;
  4206. pcolour->cyan = cyan;
  4207. pcolour->magenta = magenta;
  4208. pcolour->yellow = yellow;
  4209. pcolour->black = black;
  4210. }
  4211. }
  4212. } while (i != 0);
  4213. return CDSC_OK;
  4214. }
  4215. dsc_private int
  4216. dsc_parse_rgb_custom_colour(CDSC *dsc)
  4217. {
  4218. unsigned int i, n;
  4219. CDSCCOLOUR *pcolour;
  4220. char colourname[MAXSTR];
  4221. float red, green, blue;
  4222. GSBOOL blank_line;
  4223. if (IS_DSC(dsc->line, "%%RGBCustomColor:"))
  4224. n = 17;
  4225. else if (IS_DSC(dsc->line, "%%+"))
  4226. n = 3;
  4227. else
  4228. return CDSC_ERROR; /* error */
  4229. memset(&colourname, 0, sizeof(colourname));
  4230. /* check for blank remainder of line */
  4231. do {
  4232. blank_line = TRUE;
  4233. for (i=n; i<dsc->line_length; i++) {
  4234. if (!IS_WHITE_OR_EOL(dsc->line[i])) {
  4235. blank_line = FALSE;
  4236. break;
  4237. }
  4238. }
  4239. if (blank_line)
  4240. break;
  4241. else {
  4242. red = green = blue = 0.0;
  4243. red = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  4244. n += i;
  4245. if (i)
  4246. green = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  4247. n += i;
  4248. if (i)
  4249. blue = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
  4250. n += i;
  4251. if (i)
  4252. dsc_copy_string(colourname, sizeof(colourname),
  4253. dsc->line+n, dsc->line_length-n, &i);
  4254. n+=i;
  4255. if (i && strlen(colourname)) {
  4256. if ((pcolour = dsc_find_colour(dsc, colourname)) == NULL) {
  4257. pcolour = (CDSCCOLOUR *)
  4258. dsc_memalloc(dsc, sizeof(CDSCCOLOUR));
  4259. if (pcolour == NULL)
  4260. return CDSC_ERROR; /* out of memory */
  4261. memset(pcolour, 0, sizeof(CDSCCOLOUR));
  4262. pcolour->name = dsc_alloc_string(dsc,
  4263. colourname, (int)strlen(colourname));
  4264. pcolour->type = CDSC_COLOUR_UNKNOWN;
  4265. if (dsc->colours == NULL)
  4266. dsc->colours = pcolour;
  4267. else {
  4268. CDSCCOLOUR *this_colour = dsc->colours;
  4269. while (this_colour->next)
  4270. this_colour = this_colour->next;
  4271. this_colour->next = pcolour;
  4272. }
  4273. }
  4274. pcolour->custom = CDSC_CUSTOM_COLOUR_RGB;
  4275. pcolour->red = red;
  4276. pcolour->green = green;
  4277. pcolour->blue = blue;
  4278. }
  4279. }
  4280. } while (i != 0);
  4281. return CDSC_OK;
  4282. }