% 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: dumphint.ps 8284 2007-10-10 17:40:38Z giles $
% 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 { % 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 of bits from the bit stream.
/bitread { % bitwrite
exch begin
0 % bit val
{
1 index N .min % bit val m
dup 3 1 roll % bit m val m
bitshift % bit m val<>(N-m)
3 -1 roll % m val' bit
2 index sub % m val' bit'
3 -1 roll % val' bit' m
N exch sub dup % val' bit' N' N'
1 exch bitshift % val' bit' N' 1<)=
} {
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.) two_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 thumbnail 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.) two_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 logical structure hierarchy.)
1 index hint_sobits ne {
(\n*** This fiels is not equal to max shared object ID bits ***) concatstrings
} 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 { % <> 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 { % pdf_dump_hints -
dup (r) file % fname
false exch % fname F file
{
dup 7 string readstring pop % fname F file ()
(%PDF-1.) ne { pop exit } if % fname F file
dup 0 setfileposition
dup token not { pop exit } if % fname F file obj
dup type /integertype ne { pop exit } if % fname F file obj
1 index token not { pop pop exit } if % fname F file obj gen
dup type /integertype ne {pop pop exit}if % fname F file obj gen
4 2 roll % fname obj gen F file
dup 0 setfileposition
exch true or % fname obj gen file T
exit
} loop
{
pdfdict begin
pdfopenfile dup begin
40 dict begin
/IDict exch def
.setsafe
% 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