Академический Документы
Профессиональный Документы
Культура Документы
%
% 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.
% if true --> we have an object with duplicate object and generation numbers.
/dup_obj_gen_num false def
% Print the contents of the xref array. This actually consists of two
% arrays (Objects and Generations). Both are larrays. larrays are a
% special Ghostscript object which can be arrays with more than 64k
% elements.
/print_xref % - print_xref -
{ 0 1 Objects llength 1 sub % stack: 0 1 <number of objects - 1>
{ dup =only % print object number
( ) print
dup Generations exch lget 1 sub =only % print Generation number
( ) print
dup ObjectStream exch lget ==only % print ObjectStream object number
( ) print
Objects exch lget === % print object location
} for
flush
} bind def
% This routine will determine if there is stuff after the %%EOF. There is
% supposed to be only a line termination. However many real life files
% contain some garbage. This routine checks how much. We then ignore this
% stuff when we are scanning for objects.
/determine_post_eof_count % - determine_post_eof_count <count>
{ % Position to read block of data from the end of the file.
PDFfile 0 setfileposition
PDFfile bytesavailable % size of file
dup 4096 .min % block size to read
% stack: <file size> <file size> <block size>
% move file position to the start of the block
2 copy sub PDFfile exch setfileposition
% read block of data
dup string 0 1 4 -1 roll 1 sub { 2 copy PDFfile read pop put pop } for
% search for last occurance of '%%EOF'
(%%EOF) { search not { exit } if pop } loop
% how much is left = remaining string length
length exch pop % pop /%%EOF
} bind def
% This routine will scan a file searaching for object locations to build
% an alternate version of the data in the xref tables.
% Its purpose is to provide a basis for an xref fixing facility.
/search_objects % - search_objects -
{ % Initialize the Objects, Generations, etc. larrays
initPDFobjects
% reset duplicate object and generation numbers error flag
/dup_obj_gen_num false def
% Determine how many bytes are in the file after the final %%EOF
/post_eof_count determine_post_eof_count def
% Start at the beginning of the file
PDFfile 0 setfileposition
% Create a working string (and also store its length on stack)
1024 dup string
{ % Now loop through the entire file lloking for objects
PDFfile fileposition % save current file position
% When we get near the end of the file, we use a smaller interval of
% our working string to prevent reading past the end. (See comments on
% EOF testing below.)
PDFfile bytesavailable post_eof_count sub 10 sub dup 4 index lt {
2 index 0 3 -1 roll getinterval % near EOF, use interval of string
} { pop 1 index % not near end, use full working string
}ifelse
% Read a line from file. If the line does not fit into our working string,
% or any other error, then we will discard it.
PDFfile exch { readline } .internalstopped
{ pop pop false } if % indicate no string if we stopped
{ % stack: <length> <working_str> <loc> <string>
% Now that we have line, get obj num, ref num, and 'obj'. Verify that each
% of these is correct type.
/integertype typed_token { % get obj number
/integertype typed_token { % get ref number
/nametype typed_token { % get 'obj' text
pop % pop remaining string
/obj eq { % verify name is 'obj'
% make sure we have room in the arrays. We work in increments
% of 20 each time we increase the size.
1 index 20 add 20 idiv 20 mul
growPDFobjects
% save xref parameters into ObjectStream, Objects and Generations
1 index 0 4 index 3 index % rearrange parms for setxrefentry
setxrefentry % save parameters
pop pop pop pop % clear parameters
} if % check if name is 'obj'
} if % check if we got 'obj" string
pop % remove ref number
} if % check if we got ref number
pop % remove obj number
} if % check if we got object number
} if % check if got a string from readline
pop % remove location
% Check if we are approaching the end of the file. We do not want to
% read past the end of the file since that closes it. We actually stop
% 10-20 bytes early since there cannot be an object that close to the end.
% (There is a Trailer dictionary, etc. at the end of the file.)
PDFfile bytesavailable post_eof_count sub 20 lt { exit } if
} loop % loop through the entire file
pop pop % remove working string and its length
% Output warning if we have two objects with the same object and generation
% numbers.
dup_obj_gen_num {
( **** Warning: There are objects with matching object and generation\n)
pdfformaterror
( **** numbers. The accuracy of the resulting image is unknown.\n)
pdfformaterror
} if
} bind def
% Print warning message because we found a problem while reading the xref
% tables
/print_xref_warning
{ ( **** Warning: An error occurred while reading an XREF table.\n)
pdfformaterror
( **** The file has been damaged. This may have been caused\n)
pdfformaterror
( **** by a problem while converting or transfering the file.\n)
pdfformaterror
( **** Ghostscript will attempt to recover the data.\n)
pdfformaterror
} bind def