Sie sind auf Seite 1von 13

% % % % % % % % % % % % % %

Copyright (C) 2000, 2001 Aladdin Enterprises. All rights reserved. This software is provided AS-IS with no warranty, either express or implied. This software is distributed under license and may not be copied, modified or distributed except as expressly authorized under the terms of the license contained in the file LICENSE in this distribution. For more information about licensing, please refer to http://www.ghostscript.com/licensing/. For information on commercial licensing, go to http://www.artifex.com/licensing/ or contact Artifex Software, Inc., 101 Lucas Valley Road #110, San Rafael, CA 94903, U.S.A., +1(415)492-9861.

% $Id$ % Linearized PDF hint formatting utility. % % % % % % % % % % % % Linearized PDF hints generated by Acrobat suite seem to deviate from the published specification. /P (page offset hint table) key in hint stream is not generated by Adobe products. The key is no longer required in PDF 1.5. Per-page items 4 and 5 of the page offset hint table start from 1st page rather than 2nd page as the spec claims. All array entries start from the new byte boundary.

/table_width 79 def /col1_width 66 def % Skip bits to the next byte boundary /bytealign { % <stream> bytealign begin /N 0 def /B 0 def end } bind def % Set bit stream position and align it to byte boundary /set_align { % <<>> pos set_align exch begin S exch setfileposition /N 0 def /B 0 def end } bind def % Read requested number /bitread { exch begin 0 { 1 index N .min dup 3 1 roll bitshift B 2 index N sub bitshift add 3 -1 roll 2 index sub 3 -1 roll of bits from the bit stream. % <bstream> <width> bitwrite <value> % bit val % % % % % % % % bit val m bit m val m bit m val<<m bit m val<<m B m-N bit m val<<m+B>>(N-m) m val' bit m val' bit' val' bit' m

N exch sub dup % val' bit' 1 exch bitshift % val' bit' 1 sub B and % val' bit' /B exch def % val' bit' /N exch def % val' bit' dup 0 le { pop exit % val' } if /N N 8 add def /B B 8 bitshift S read not { 0 ( exch } loop % bit' val' end } bind def

N' N' N' 1<<N' N' B&(1<<N') N'

*** EOF! *** ) = } if add def

% Print a string several times /multiprint { % cnt (s) multiprint exch { dup print } repeat pop } bind def % Split the line into 2 /split_line { dup length col1_width col1_width 1 sub dup -1 0 { dup 3 index exch get 32 eq { exch pop exit } if pop } for 1 add 1 index exch 0 exch getinterval } { dup } ifelse (\n) search { 4 1 roll pop pop 1 index length 1 add } { exch 1 index length } ifelse 1 index length 1 index sub getinterval } bind def substrings. % (s) split_line () () gt { % (s) w i i % (s) w i i () % (s) w i c

% % % %

(s) (s) (s) (s)

w' (s) w' (s) 0 w' (v)

% (s) (s) % % % % (pre) (pre) (pre) (pre) (s) (post) (match) (s) (s) len (s) len+1

% (pre) (s) % (pre) (s) len % (pre) (s) len Len % (pre) (s) len Len-len % (pre) (post)

% Print a 2 column table. The string is printed in 1st column % left-aligned. The number is printed in 2nd column right-aligned. /two_column { % n () two_column split_line % n (a) () 3 1 roll % () n (a) dup length % () n (a) len

exch print % () exch =string cvs % () dup length % () 3 -1 roll add % () //table_width % () exch sub % () ( ) multiprint % () = % () { dup length 0 eq { exit } split_line exch = } loop pop () = } bind def

n len len (n) len (n) len2 (n) len+len2 (n) len+len2 78 (n) 78-len+len2 (n) if

% Print the header of a hint table /table_header { % () table_header dup length dup table_width exch sub 2 idiv % () len sp dup ( ) multiprint % () len sp 3 -1 roll = % len sp ( ) multiprint % len (=) multiprint ()= ()= } bind def % Pretty-print an array on top level /dump_array { % [ ] dump_array ([) = ( ) print 1 exch { =string cvs % pos () dup length dup % pos () len len 3 index add 1 add % pos () len len+pos+1 table_width gt { () = ( ) print % pos () len 2 add % pos () pos' 3 1 roll print pop % pos' } { ( ) print % pos () len exch print % pos len add 1 add % pos' } ifelse } forall pop () = (]) = } bind def % Pretty-print an array on /dump_array2 { ( [) print 3 exch { =string cvs dup length dup 3 index add 1 add table_width 2 sub gt { () = ( ) print 4 add 3 1 roll print pop 2nd level % [ ] dump_array2 % pos () % pos () len len % pos () len len+pos+1 % pos () len % pos () pos' % pos'

} { ( ) print exch print add 1 add } ifelse } forall pop ( ]) = } bind def % Print an array header /array_header { () = = } bind def

% pos () len % pos len % pos'

% Analyze the page offset hint table. /dump_page_offset_table { % - dump_page_offset_table hint_stream dup 32 bitread dup /hint_minnop exch def (1. The least number of objects in a page.) two_column dup 32 bitread dup /hint_1st_obj exch def (2. Location of the first page's page object.) two_column dup 16 bitread dup /hint_maxnopbits exch def (3. Bits for difference between max and min number of page objects.) two_colum n dup 32 bitread dup /hint_minpl exch def (4. Least length of a page.) two_column dup 16 bitread dup /hint_maxplbits exch def (5. Bits for difference between max and min length of a page.) two_column dup 32 bitread dup /hint_minsco exch def (6. Least start of Contents offset. ) 1 index 0 ne { (\n*** Acrobat expects 0 ***) concatstrings } if two_column dup 16 bitread dup /hint_maxscobits exch def (7. Bits for difference between max and min offset to the start of the content stream.) two_column dup 32 bitread dup /hint_mincl exch def (8. Least contents length.) two_column dup 16 bitread dup /hint_maxclbits exch def (9. Bits needed to represent the greatest Contents length.) two_column dup 16 bitread

dup /hint_maxsorbits exch def (10. Bits needed to represent the greatest number of Shared Object references. ) two_column dup 16 bitread dup /hint_sobits exch def (11. Bits needed to identify a Shared Object.) two_column dup 16 bitread dup /hint_numfbits exch def (12. Bits needed to represent numerator of fraction.) two_column dup 16 bitread dup /hint_denf exch def (13. Denominator of fraction.) two_column pop LinearizationParams /N get % 1. Number of objects in the page. hint_stream bytealign /hint_page_obj [ 2 index { hint_stream hint_maxnopbits bitread hint_minnop add } repeat ] readonly def (1. Number of objects on the page) array_header hint_page_obj dump_array % 2, Page length in bytes. hint_stream bytealign /hint_page_len [ 2 index { hint_stream hint_maxplbits bitread hint_minpl add } repeat ] readonly def (2. Page length in bytes.) array_header hint_page_len dump_array % 3, Number of shared objects referenced from the page hint_stream bytealign /hint_page_sobj [ 2 index { hint_stream hint_maxsorbits bitread } repeat ] readonly def (3. Number of shared objects referenced from the page.) array_header hint_page_sobj dump_array % 4. Index into the shared objects hint table hint_stream bytealign /hint_page_sobj_id [ 0 1 4 index 1 sub { hint_page_sobj exch get [

exch { hint_stream hint_sobits bitread } repeat ] readonly } for ] readonly def (4. Index into the shared objects hint table.) array_header ([) = hint_page_sobj_id { dump_array2 } forall (])= % 5. Fractional position for each shared object reference hint_stream bytealign /hint_page_sobj_pos [ 0 1 4 index 1 sub { hint_page_sobj exch get [ exch { hint_stream hint_numfbits bitread hint_denf div } repeat ] readonly } for ] readonly def (5. Fractional position for each shared object reference. ) array_header ([)= hint_page_sobj_pos { dump_array2 } forall (])= % 6. Offset of the page's content stream from the beginning of the page. hint_stream bytealign /hint_page_content_offset [ 2 index { hint_stream hint_maxscobits bitread hint_minsco add } repeat ] readonly def (6. Offset of the page's content stream from the beginning of the page.) array _header hint_page_content_offset dump_array % 7. Length of the page's content stream in bytes. hint_stream bytealign /hint_page_content_len [ 2 index { hint_stream hint_maxclbits bitread hint_mincl add } repeat ] readonly def (7. Length of the page's content stream in bytes.) array_header hint_page_content_len dump_array pop } bind def % Analyze tha shared object hint table /dump_shared_object_table {

hint_stream dup 32 bitread dup /shint_1st_obj_id exch def (1. Object number of the first object in the shared objects section) two_colum n dup 32 bitread dup /shint_1st_obj_pos exch def (2. Location of the first object in the shared objects section.) two_column dup 32 bitread dup /shint_1st_shared exch def (3. The number of shared object entries for the first page.) two_column dup 32 bitread dup /shint_all_shared exch def (4. Number of shared object entries for the shared objects section including 1 st page.) two_column dup 16 bitread dup /shint_group_bits exch def (5. Number of bits needed to represent the greatest number of objects in a sha red object group.) two_column dup 32 bitread dup /shint_group_least_sz exch def (6. Least length of a shared object group in bytes.) two_column dup 16 bitread dup /shint_group_diff_bits exch def (7. Bits for the difference between the greatest and least length of a shared object group size.) two_column pop (1. length of the object group in bytes.) array_header hint_stream bytealign /shint_group_sz [ shint_all_shared { hint_stream shint_group_diff_bits bitread shint_group_least_sz add } repeat ] readonly def shint_group_sz dump_array (2. MD5 signature flag) array_header hint_stream bytealign /shint_md5_flags [ shint_all_shared { hint_stream 1 bitread } repeat ] readonly def shint_md5_flags dump_array (3. MD5 signature string) array_header false shint_md5_flags { 0 ne or } forall { shint_md5_flags { 0 eq {

(<>)= } { hint_stream /S get 128 string readstring pop dup length 128 eq { == } { pop (Error reading nd5 string.) == } ifelse } ifelse } forall } { () = (none) = } ifelse (4. The number of objects in the group.) array_header hint_stream bytealign /shint_group_cnt [ shint_all_shared { hint_stream shint_group_bits bitread } repeat ] readonly def shint_group_cnt dump_array } bind def % Analyze the thumbnail hint table. /dump_thumbnail_table { hint_stream dup 32 bitread dup /thint_1st_obj_id exch def (1. Object number of the first thumbnail image.) two_column dup 32 bitread dup /thint_1st_obj_pos exch def (2. Location of the first thumbnail image.) two_column dup 32 bitread dup /thint_page_cnt exch def (3. Number of pages that have thumbnail images.) two_column dup 16 bitread dup /thint_no_thumbnail_bits exch def (4. Bits for the max number of consecutive pages without a thumbnail image.) t wo_column dup 32 bitread dup /thint_min_sz exch def (5. The least length of a thumbnail image in bytes.) two_column dup 15 bitread dup /thint_obj_sz_bits exch def (6. Bits for the difference between max and min length of a thumbnail image.) two_column dup 32 bitread dup /thint_min_obj_cnt exch def (7. The least number of objects in a thumbnail image.) two_column

dup 16 bitread dup /thint_obj_cnt_bits exch def (8. Bits for the difference between max and min number of objects in a thumbna il image.) two_column dup 32 bitread dup /thint_1st_shared_obj exch def (9. First object in the thumbnail shared objects section.) two_column dup 32 bitread dup /thint_1st_shared_pos exch def (10. Location of the first object in the thumbnail shared objects section.) tw o_column dup 32 bitread dup /thint_shared_cnt exch def (11. Number of thumbnail shared objects.) two_column dup 32 bitread dup /thint_shared_section_sz exch def (12. Length of the thumbnail shared objects section in bytes.) two_column pop LinearizationParams /N get (1. The number of preceding pages lacking a thumbnail image.) array_header hint_stream bytealign /thint_no_thumbnail_pages [ 2 index { hint_stream thint_no_thumbnail_bits bitread } repeat ] readonly def thint_no_thumbnail_pages dump_array (2. Number of objects in this page's thumbnail image.) array_header hint_stream bytealign /thint_page_obj_cnt [ 2 index { hint_stream thint_obj_cnt_bits bitread thint_min_obj_cnt add } repeat ] readonly def thint_page_obj_cnt dump_array (3. Length of this page's thumbnail image in bytes.) array_header hint_stream bytealign /thint_page_obj_sz [ 2 index { hint_stream thint_obj_sz_bits bitread thint_min_sz add } repeat ] readonly def thint_page_obj_sz dump_array pop } bind def % Analyze the generic hint table.

% The hint field names are re-used. /dump_generic_table { hint_stream dup 32 bitread dup /ghint_1st_obj exch def (1. Object number of the first object in the group.) two_column dup 32 bitread dup /ghint_1st_obj_pos exch def (2. Location of the first object in the group.) two_column dup 32 bitread dup /ghint_obj_cnt exch def (3. Number of objects in the group.) two_column dup 32 bitread dup /ghint_group_sz exch def (4. Length of the object group in bytes.) two_column pop } bind def % Analyze the interactive hint table. % The hint field names are re-used. /dump_interactive_table { hint_stream dup 32 bitread dup /ihint_1st_obj exch def (1. Object number of the first object in the group.) two_column dup 32 bitread dup /ihint_1st_obj_pos exch def (2. Location of the first object in the group.) two_column dup 32 bitread dup /ihint_obj_cnt exch def (3. Number of objects in the group.) two_column dup 32 bitread dup /ihint_group_sz exch def (4. Length of the object group in bytes.) two_column dup 32 bitread dup /ihint_shared_cnt exch def (5. Number of shared object references.) two_column dup 16 bitread dup /ihint_shared_obj_bits exch def (6. Bits for the max shared object id used by the interactive form or the logi cal structure hierarchy.) 1 index hint_sobits ne { (\n*** This fiels is not equal to max shared object ID bits ***) concatstrin gs } if pop (7. Shared object identifier.) array_header

hint_stream bytealign /ihint_shared_obj_id [ ihint_shared_cnt { hint_stream hint_sobits bitread } repeat ] readonly def ihint_shared_obj_id dump_array } bind def % Enumerate all documented hint tables. /dump_all_tables { % <<stream>> dump_all_tables (Page offset hint table) table_header hint_stream 0 set_align dump_page_offset_table (S, Shared object hint table) table_header dup /S .knownget { hint_stream exch set_align dump_shared_object_table } { (Required table is not found.) error_msg } ifelse dup /T .knownget { (T, Thumbnail hint table) table_header hint_stream exch set_align dump_thumbnail_table } if dup /O .knownget { (O, Outline hint table) table_header hint_stream exch set_align dump_generic_table } if dup /A .knownget { (A, Thread information hint table) table_header hint_stream exch set_align dump_generic_table } if dup /E .knownget { (E, Named destination hint table) table_header hint_stream exch set_align dump_generic_table } if dup /V .knownget { (V, Interactive form hint table) table_header hint_stream exch set_align dump_interactive_table } if dup /I .knownget { (I, Information dictionary hint table) table_header hint_stream exch set_align dump_generic_table } if

dup /C .knownget { (C, Logical structure hint table) table_header hint_stream exch set_align dump_interactive_table } if dup /L .knownget { (L, Page label hint table) table_header hint_stream exch set_align dump_generic_table } if pop } bind def % Load PDF file and extract the hint stream. /pdf_dump_hints { dup (r) file false exch { dup 7 string readstring pop (%PDF-1.) ne { pop exit } if dup 0 setfileposition dup token not { pop exit } if dup type /integertype ne { pop exit } if 1 index token not { pop pop exit } if dup type /integertype ne {pop pop exit}if 4 2 roll dup 0 setfileposition exch true or exit } loop { pdfdict begin pdfopenfile dup begin 40 dict begin /IDict exch def .setsafe % <infile> pdf_dump_hints % fname % fname F file % fname F file () % fname F file % % % % % fname fname fname fname fname F file obj F file obj F file obj gen F file obj gen obj gen F file

% fname obj gen file T

% Read all objects into memory. Trailer touch resolveR % fname <<>> dup /Linearized known { dup /L get % fname <<>> Len 3 -1 roll status not { 0 0 0 0 } if % <<>> Len pop pop exch pop % <<>> Len len eq { /LinearizationParams exch def LinearizationParams /H get dup length 2 eq { 0 get PDFoffset add PDFfile exch setfileposition PDFfile token pop PDFfile token pop resolveR dup true resolvestream /ReusableStreamDecode filter bitstream dup bytealign /hint_stream exch def dump_all_tables } {

pop (Overflow hint stream is not supported.) = } ifelse } { pop (Wrong file length in linearization dictionary.) = } ifelse } { pop (The file is not linearized.) = } ifelse end % temporary dict end % IDict end } { pop (Input file is not a valid PDF file.) = } ifelse } bind def % Initial setup /dump_hints { counttomark 1 eq { exch pop save exch 3000000 setvmthreshold pdfoptdict begin pdf_dump_hints end restore true } { cleartomark false } ifelse } bind def /shellarguments {false} def (pdfopt.ps) runlibfile currentdict /shellarguments undef % Check for command line arguments. mark shellarguments { dump_hints not { (Usage: gs -dNODISPLAY -- dumphint.ps input.pdf) = flush } if } { pop } ifelse % EOF

Das könnte Ihnen auch gefallen