dumphint.ps 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. % Copyright (C) 2000, 2001 Aladdin Enterprises. All rights reserved.
  2. %
  3. % This software is provided AS-IS with no warranty, either express or
  4. % implied.
  5. %
  6. % This software is distributed under license and may not be copied,
  7. % modified or distributed except as expressly authorized under the terms
  8. % of the license contained in the file LICENSE in this distribution.
  9. %
  10. % For more information about licensing, please refer to
  11. % http://www.ghostscript.com/licensing/. For information on
  12. % commercial licensing, go to http://www.artifex.com/licensing/ or
  13. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  14. % San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  15. % $Id: dumphint.ps,v 1.2 2004/04/08 16:18:25 giles Exp $
  16. % Linearized PDF hint formatting utility.
  17. %
  18. % Linearized PDF hints generated by Acrobat suite seem to deviate from
  19. % the published specification.
  20. %
  21. % /P (page offset hint table) key in hint stream is not generated by
  22. % Adobe products. The key is no longer required in PDF 1.5.
  23. %
  24. % Per-page items 4 and 5 of the page offset hint table start from 1st
  25. % page rather than 2nd page as the spec claims.
  26. %
  27. % All array entries start from the new byte boundary.
  28. %
  29. /table_width 79 def
  30. /col1_width 66 def
  31. % Skip bits to the next byte boundary
  32. /bytealign { % <stream> bytealign -
  33. begin /N 0 def /B 0 def end
  34. } bind def
  35. % Set bit stream position and align it to byte boundary
  36. /set_align { % <<>> pos set_align -
  37. exch begin
  38. S exch setfileposition
  39. /N 0 def /B 0 def
  40. end
  41. } bind def
  42. % Read requested number of bits from the bit stream.
  43. /bitread { % <bstream> <width> bitwrite <value>
  44. exch begin
  45. 0 % bit val
  46. {
  47. 1 index N .min % bit val m
  48. dup 3 1 roll % bit m val m
  49. bitshift % bit m val<<m
  50. B 2 index N sub % bit m val<<m B m-N
  51. bitshift add % bit m val<<m+B>>(N-m)
  52. 3 -1 roll % m val' bit
  53. 2 index sub % m val' bit'
  54. 3 -1 roll % val' bit' m
  55. N exch sub dup % val' bit' N' N'
  56. 1 exch bitshift % val' bit' N' 1<<N'
  57. 1 sub B and % val' bit' N' B&(1<<N')
  58. /B exch def % val' bit' N'
  59. /N exch def % val' bit'
  60. dup 0 le {
  61. pop exit % val'
  62. } if
  63. /N N 8 add def
  64. /B B 8 bitshift S read not { 0 ( *** EOF! *** ) = } if add def
  65. exch
  66. } loop % bit' val'
  67. end
  68. } bind def
  69. % Print a string several times
  70. /multiprint { % cnt (s) multiprint -
  71. exch { dup print } repeat pop
  72. } bind def
  73. % Split the line into 2 substrings.
  74. /split_line { % (s) split_line () ()
  75. dup length col1_width gt {
  76. col1_width 1 sub
  77. dup -1 0 {
  78. dup % (s) w i i
  79. 3 index % (s) w i i ()
  80. exch get % (s) w i c
  81. 32 eq {
  82. exch pop exit
  83. } if
  84. pop
  85. } for
  86. 1 add % (s) w'
  87. 1 index exch % (s) (s) w'
  88. 0 exch % (s) (s) 0 w'
  89. getinterval % (s) (v)
  90. } {
  91. dup % (s) (s)
  92. } ifelse
  93. (\n) search {
  94. 4 1 roll % (pre) (s) (post) (match)
  95. pop pop % (pre) (s)
  96. 1 index length % (pre) (s) len
  97. 1 add % (pre) (s) len+1
  98. } {
  99. exch % (pre) (s)
  100. 1 index length % (pre) (s) len
  101. } ifelse
  102. 1 index length % (pre) (s) len Len
  103. 1 index sub % (pre) (s) len Len-len
  104. getinterval % (pre) (post)
  105. } bind def
  106. % Print a 2 column table. The string is printed in 1st column
  107. % left-aligned. The number is printed in 2nd column right-aligned.
  108. /two_column { % n () two_column -
  109. split_line % n (a) ()
  110. 3 1 roll % () n (a)
  111. dup length % () n (a) len
  112. exch print % () n len
  113. exch =string cvs % () len (n)
  114. dup length % () len (n) len2
  115. 3 -1 roll add % () (n) len+len2
  116. //table_width % () (n) len+len2 78
  117. exch sub % () (n) 78-len+len2
  118. ( ) multiprint % () (n)
  119. = % ()
  120. { dup length 0 eq { exit } if
  121. split_line exch =
  122. } loop
  123. pop
  124. () =
  125. } bind def
  126. % Print the header of a hint table
  127. /table_header { % () table_header -
  128. dup length dup
  129. table_width exch sub 2 idiv % () len sp
  130. dup ( ) multiprint % () len sp
  131. 3 -1 roll = % len sp
  132. ( ) multiprint % len
  133. (=) multiprint
  134. ()= ()=
  135. } bind def
  136. % Pretty-print an array on top level
  137. /dump_array { % [ ] dump_array -
  138. ([) = ( ) print
  139. 1 exch {
  140. =string cvs % pos ()
  141. dup length dup % pos () len len
  142. 3 index add 1 add % pos () len len+pos+1
  143. table_width gt {
  144. () =
  145. ( ) print % pos () len
  146. 2 add % pos () pos'
  147. 3 1 roll print pop % pos'
  148. } {
  149. ( ) print % pos () len
  150. exch print % pos len
  151. add 1 add % pos'
  152. } ifelse
  153. } forall
  154. pop
  155. () = (]) =
  156. } bind def
  157. % Pretty-print an array on 2nd level
  158. /dump_array2 { % [ ] dump_array2 -
  159. ( [) print
  160. 3 exch {
  161. =string cvs % pos ()
  162. dup length dup % pos () len len
  163. 3 index add 1 add % pos () len len+pos+1
  164. table_width 2 sub gt {
  165. () =
  166. ( ) print % pos () len
  167. 4 add % pos () pos'
  168. 3 1 roll print pop % pos'
  169. } {
  170. ( ) print % pos () len
  171. exch print % pos len
  172. add 1 add % pos'
  173. } ifelse
  174. } forall
  175. pop
  176. ( ]) =
  177. } bind def
  178. % Print an array header
  179. /array_header {
  180. () = =
  181. } bind def
  182. % Analyze the page offset hint table.
  183. /dump_page_offset_table { % - dump_page_offset_table -
  184. hint_stream
  185. dup 32 bitread
  186. dup /hint_minnop exch def
  187. (1. The least number of objects in a page.) two_column
  188. dup 32 bitread
  189. dup /hint_1st_obj exch def
  190. (2. Location of the first page's page object.) two_column
  191. dup 16 bitread
  192. dup /hint_maxnopbits exch def
  193. (3. Bits for difference between max and min number of page objects.) two_column
  194. dup 32 bitread
  195. dup /hint_minpl exch def
  196. (4. Least length of a page.) two_column
  197. dup 16 bitread
  198. dup /hint_maxplbits exch def
  199. (5. Bits for difference between max and min length of a page.) two_column
  200. dup 32 bitread
  201. dup /hint_minsco exch def
  202. (6. Least start of Contents offset. )
  203. 1 index 0 ne { (\n*** Acrobat expects 0 ***) concatstrings } if
  204. two_column
  205. dup 16 bitread
  206. dup /hint_maxscobits exch def
  207. (7. Bits for difference between max and min offset to the start of the content stream.) two_column
  208. dup 32 bitread
  209. dup /hint_mincl exch def
  210. (8. Least contents length.) two_column
  211. dup 16 bitread
  212. dup /hint_maxclbits exch def
  213. (9. Bits needed to represent the greatest Contents length.) two_column
  214. dup 16 bitread
  215. dup /hint_maxsorbits exch def
  216. (10. Bits needed to represent the greatest number of Shared Object references.) two_column
  217. dup 16 bitread
  218. dup /hint_sobits exch def
  219. (11. Bits needed to identify a Shared Object.) two_column
  220. dup 16 bitread
  221. dup /hint_numfbits exch def
  222. (12. Bits needed to represent numerator of fraction.) two_column
  223. dup 16 bitread
  224. dup /hint_denf exch def
  225. (13. Denominator of fraction.) two_column
  226. pop
  227. LinearizationParams /N get
  228. % 1. Number of objects in the page.
  229. hint_stream bytealign
  230. /hint_page_obj [
  231. 2 index {
  232. hint_stream hint_maxnopbits bitread
  233. hint_minnop add
  234. } repeat
  235. ] readonly def
  236. (1. Number of objects on the page) array_header
  237. hint_page_obj dump_array
  238. % 2, Page length in bytes.
  239. hint_stream bytealign
  240. /hint_page_len [
  241. 2 index {
  242. hint_stream hint_maxplbits bitread
  243. hint_minpl add
  244. } repeat
  245. ] readonly def
  246. (2. Page length in bytes.) array_header
  247. hint_page_len dump_array
  248. % 3, Number of shared objects referenced from the page
  249. hint_stream bytealign
  250. /hint_page_sobj [
  251. 2 index {
  252. hint_stream hint_maxsorbits bitread
  253. } repeat
  254. ] readonly def
  255. (3. Number of shared objects referenced from the page.) array_header
  256. hint_page_sobj dump_array
  257. % 4. Index into the shared objects hint table
  258. hint_stream bytealign
  259. /hint_page_sobj_id [
  260. 0 1 4 index 1 sub {
  261. hint_page_sobj exch get [
  262. exch {
  263. hint_stream hint_sobits bitread
  264. } repeat
  265. ] readonly
  266. } for
  267. ] readonly def
  268. (4. Index into the shared objects hint table.) array_header
  269. ([) =
  270. hint_page_sobj_id { dump_array2 } forall
  271. (])=
  272. % 5. Fractional position for each shared object reference
  273. hint_stream bytealign
  274. /hint_page_sobj_pos [
  275. 0 1 4 index 1 sub {
  276. hint_page_sobj exch get [
  277. exch {
  278. hint_stream hint_numfbits bitread
  279. hint_denf div
  280. } repeat
  281. ] readonly
  282. } for
  283. ] readonly def
  284. (5. Fractional position for each shared object reference. ) array_header
  285. ([)=
  286. hint_page_sobj_pos { dump_array2 } forall
  287. (])=
  288. % 6. Offset of the page's content stream from the beginning of the page.
  289. hint_stream bytealign
  290. /hint_page_content_offset [
  291. 2 index {
  292. hint_stream hint_maxscobits bitread
  293. hint_minsco add
  294. } repeat
  295. ] readonly def
  296. (6. Offset of the page's content stream from the beginning of the page.) array_header
  297. hint_page_content_offset dump_array
  298. % 7. Length of the page's content stream in bytes.
  299. hint_stream bytealign
  300. /hint_page_content_len [
  301. 2 index {
  302. hint_stream hint_maxclbits bitread
  303. hint_mincl add
  304. } repeat
  305. ] readonly def
  306. (7. Length of the page's content stream in bytes.) array_header
  307. hint_page_content_len dump_array
  308. pop
  309. } bind def
  310. % Analyze tha shared object hint table
  311. /dump_shared_object_table {
  312. hint_stream
  313. dup 32 bitread
  314. dup /shint_1st_obj_id exch def
  315. (1. Object number of the first object in the shared objects section) two_column
  316. dup 32 bitread
  317. dup /shint_1st_obj_pos exch def
  318. (2. Location of the first object in the shared objects section.) two_column
  319. dup 32 bitread
  320. dup /shint_1st_shared exch def
  321. (3. The number of shared object entries for the first page.) two_column
  322. dup 32 bitread
  323. dup /shint_all_shared exch def
  324. (4. Number of shared object entries for the shared objects section including 1st page.) two_column
  325. dup 16 bitread
  326. dup /shint_group_bits exch def
  327. (5. Number of bits needed to represent the greatest number of objects in a shared object group.) two_column
  328. dup 32 bitread
  329. dup /shint_group_least_sz exch def
  330. (6. Least length of a shared object group in bytes.) two_column
  331. dup 16 bitread
  332. dup /shint_group_diff_bits exch def
  333. (7. Bits for the difference between the greatest and least length of a shared object group size.) two_column
  334. pop
  335. (1. length of the object group in bytes.) array_header
  336. hint_stream bytealign
  337. /shint_group_sz [
  338. shint_all_shared {
  339. hint_stream shint_group_diff_bits bitread
  340. shint_group_least_sz add
  341. } repeat
  342. ] readonly def
  343. shint_group_sz dump_array
  344. (2. MD5 signature flag) array_header
  345. hint_stream bytealign
  346. /shint_md5_flags
  347. [ shint_all_shared
  348. { hint_stream 1 bitread
  349. } repeat
  350. ] readonly def
  351. shint_md5_flags dump_array
  352. (3. MD5 signature string) array_header
  353. false shint_md5_flags { 0 ne or } forall {
  354. shint_md5_flags {
  355. 0 eq {
  356. (<>)=
  357. } {
  358. hint_stream /S get 128 string
  359. readstring pop
  360. dup length 128 eq {
  361. ==
  362. } { pop (Error reading nd5 string.) ==
  363. } ifelse
  364. } ifelse
  365. } forall
  366. } {
  367. () = (none) =
  368. } ifelse
  369. (4. The number of objects in the group.) array_header
  370. hint_stream bytealign
  371. /shint_group_cnt [
  372. shint_all_shared {
  373. hint_stream shint_group_bits bitread
  374. } repeat
  375. ] readonly def
  376. shint_group_cnt dump_array
  377. } bind def
  378. % Analyze the thumbnail hint table.
  379. /dump_thumbnail_table {
  380. hint_stream
  381. dup 32 bitread
  382. dup /thint_1st_obj_id exch def
  383. (1. Object number of the first thumbnail image.) two_column
  384. dup 32 bitread
  385. dup /thint_1st_obj_pos exch def
  386. (2. Location of the first thumbnail image.) two_column
  387. dup 32 bitread
  388. dup /thint_page_cnt exch def
  389. (3. Number of pages that have thumbnail images.) two_column
  390. dup 16 bitread
  391. dup /thint_no_thumbnail_bits exch def
  392. (4. Bits for the max number of consecutive pages without a thumbnail image.) two_column
  393. dup 32 bitread
  394. dup /thint_min_sz exch def
  395. (5. The least length of a thumbnail image in bytes.) two_column
  396. dup 15 bitread
  397. dup /thint_obj_sz_bits exch def
  398. (6. Bits for the difference between max and min length of a thumbnail image.) two_column
  399. dup 32 bitread
  400. dup /thint_min_obj_cnt exch def
  401. (7. The least number of objects in a thumbnail image.) two_column
  402. dup 16 bitread
  403. dup /thint_obj_cnt_bits exch def
  404. (8. Bits for the difference between max and min number of objects in a thumbnail image.) two_column
  405. dup 32 bitread
  406. dup /thint_1st_shared_obj exch def
  407. (9. First object in the thumbnail shared objects section.) two_column
  408. dup 32 bitread
  409. dup /thint_1st_shared_pos exch def
  410. (10. Location of the first object in the thumbnail shared objects section.) two_column
  411. dup 32 bitread
  412. dup /thint_shared_cnt exch def
  413. (11. Number of thumbnail shared objects.) two_column
  414. dup 32 bitread
  415. dup /thint_shared_section_sz exch def
  416. (12. Length of the thumbnail shared objects section in bytes.) two_column
  417. pop
  418. LinearizationParams /N get
  419. (1. The number of preceding pages lacking a thumbnail image.) array_header
  420. hint_stream bytealign
  421. /thint_no_thumbnail_pages [
  422. 2 index {
  423. hint_stream thint_no_thumbnail_bits bitread
  424. } repeat
  425. ] readonly def
  426. thint_no_thumbnail_pages dump_array
  427. (2. Number of objects in this page's thumbnail image.) array_header
  428. hint_stream bytealign
  429. /thint_page_obj_cnt [
  430. 2 index {
  431. hint_stream thint_obj_cnt_bits bitread
  432. thint_min_obj_cnt add
  433. } repeat
  434. ] readonly def
  435. thint_page_obj_cnt dump_array
  436. (3. Length of this page's thumbnail image in bytes.) array_header
  437. hint_stream bytealign
  438. /thint_page_obj_sz [
  439. 2 index {
  440. hint_stream thint_obj_sz_bits bitread
  441. thint_min_sz add
  442. } repeat
  443. ] readonly def
  444. thint_page_obj_sz dump_array
  445. pop
  446. } bind def
  447. % Analyze the generic hint table.
  448. % The hint field names are re-used.
  449. /dump_generic_table {
  450. hint_stream
  451. dup 32 bitread
  452. dup /ghint_1st_obj exch def
  453. (1. Object number of the first object in the group.) two_column
  454. dup 32 bitread
  455. dup /ghint_1st_obj_pos exch def
  456. (2. Location of the first object in the group.) two_column
  457. dup 32 bitread
  458. dup /ghint_obj_cnt exch def
  459. (3. Number of objects in the group.) two_column
  460. dup 32 bitread
  461. dup /ghint_group_sz exch def
  462. (4. Length of the object group in bytes.) two_column
  463. pop
  464. } bind def
  465. % Analyze the interactive hint table.
  466. % The hint field names are re-used.
  467. /dump_interactive_table {
  468. hint_stream
  469. dup 32 bitread
  470. dup /ihint_1st_obj exch def
  471. (1. Object number of the first object in the group.) two_column
  472. dup 32 bitread
  473. dup /ihint_1st_obj_pos exch def
  474. (2. Location of the first object in the group.) two_column
  475. dup 32 bitread
  476. dup /ihint_obj_cnt exch def
  477. (3. Number of objects in the group.) two_column
  478. dup 32 bitread
  479. dup /ihint_group_sz exch def
  480. (4. Length of the object group in bytes.) two_column
  481. dup 32 bitread
  482. dup /ihint_shared_cnt exch def
  483. (5. Number of shared object references.) two_column
  484. dup 16 bitread
  485. dup /ihint_shared_obj_bits exch def
  486. (6. Bits for the max shared object id used by the interactive form or the logical structure hierarchy.)
  487. 1 index hint_sobits ne {
  488. (\n*** This fiels is not equal to max shared object ID bits ***) concatstrings
  489. } if
  490. pop
  491. (7. Shared object identifier.) array_header
  492. hint_stream bytealign
  493. /ihint_shared_obj_id [
  494. ihint_shared_cnt {
  495. hint_stream hint_sobits bitread
  496. } repeat
  497. ] readonly def
  498. ihint_shared_obj_id dump_array
  499. } bind def
  500. % Enumerate all documented hint tables.
  501. /dump_all_tables { % <<stream>> dump_all_tables -
  502. (Page offset hint table) table_header
  503. hint_stream 0 set_align
  504. dump_page_offset_table
  505. (S, Shared object hint table) table_header
  506. dup /S .knownget {
  507. hint_stream exch set_align
  508. dump_shared_object_table
  509. } {
  510. (Required table is not found.) error_msg
  511. } ifelse
  512. dup /T .knownget {
  513. (T, Thumbnail hint table) table_header
  514. hint_stream exch set_align
  515. dump_thumbnail_table
  516. } if
  517. dup /O .knownget {
  518. (O, Outline hint table) table_header
  519. hint_stream exch set_align
  520. dump_generic_table
  521. } if
  522. dup /A .knownget {
  523. (A, Thread information hint table) table_header
  524. hint_stream exch set_align
  525. dump_generic_table
  526. } if
  527. dup /E .knownget {
  528. (E, Named destination hint table) table_header
  529. hint_stream exch set_align
  530. dump_generic_table
  531. } if
  532. dup /V .knownget {
  533. (V, Interactive form hint table) table_header
  534. hint_stream exch set_align
  535. dump_interactive_table
  536. } if
  537. dup /I .knownget {
  538. (I, Information dictionary hint table) table_header
  539. hint_stream exch set_align
  540. dump_generic_table
  541. } if
  542. dup /C .knownget {
  543. (C, Logical structure hint table) table_header
  544. hint_stream exch set_align
  545. dump_interactive_table
  546. } if
  547. dup /L .knownget {
  548. (L, Page label hint table) table_header
  549. hint_stream exch set_align
  550. dump_generic_table
  551. } if
  552. pop
  553. } bind def
  554. % Load PDF file and extract the hint stream.
  555. /pdf_dump_hints { % <infile> pdf_dump_hints -
  556. dup (r) file % fname
  557. false exch % fname F file
  558. {
  559. dup 7 string readstring pop % fname F file ()
  560. (%PDF-1.) ne { pop exit } if % fname F file
  561. dup 0 setfileposition
  562. dup token not { pop exit } if % fname F file obj
  563. dup type /integertype ne { pop exit } if % fname F file obj
  564. 1 index token not { pop pop exit } if % fname F file obj gen
  565. dup type /integertype ne {pop pop exit}if % fname F file obj gen
  566. 4 2 roll % fname obj gen F file
  567. dup 0 setfileposition
  568. exch true or % fname obj gen file T
  569. exit
  570. } loop
  571. {
  572. pdfdict begin
  573. pdfopenfile dup begin
  574. 40 dict begin
  575. /IDict exch def
  576. .setsafe
  577. % Read all objects into memory.
  578. Trailer touch
  579. resolveR % fname <<>>
  580. dup /Linearized known {
  581. dup /L get % fname <<>> Len
  582. 3 -1 roll status not { 0 0 0 0 } if % <<>> Len
  583. pop pop exch pop % <<>> Len len
  584. eq {
  585. /LinearizationParams exch def
  586. LinearizationParams /H get
  587. dup length 2 eq {
  588. 0 get PDFoffset add PDFfile exch setfileposition
  589. PDFfile token pop
  590. PDFfile token pop
  591. resolveR dup true resolvestream
  592. /ReusableStreamDecode filter
  593. bitstream dup bytealign
  594. /hint_stream exch def
  595. dump_all_tables
  596. } {
  597. pop
  598. (Overflow hint stream is not supported.) =
  599. } ifelse
  600. } {
  601. pop
  602. (Wrong file length in linearization dictionary.) =
  603. } ifelse
  604. } {
  605. pop (The file is not linearized.) =
  606. } ifelse
  607. end % temporary dict
  608. end % IDict
  609. end
  610. } {
  611. pop
  612. (Input file is not a valid PDF file.) =
  613. } ifelse
  614. } bind def
  615. % Initial setup
  616. /dump_hints {
  617. counttomark 1 eq {
  618. exch pop
  619. save exch
  620. 3000000 setvmthreshold
  621. pdfoptdict begin
  622. pdf_dump_hints
  623. end
  624. restore
  625. true
  626. } {
  627. cleartomark false
  628. } ifelse
  629. } bind def
  630. /shellarguments {false} def
  631. (pdfopt.ps) runlibfile
  632. currentdict /shellarguments undef
  633. % Check for command line arguments.
  634. mark shellarguments {
  635. dump_hints not {
  636. (Usage: gs -dNODISPLAY -- dumphint.ps input.pdf) = flush
  637. } if
  638. } {
  639. pop
  640. } ifelse
  641. % EOF