aboutsummaryrefslogtreecommitdiffstats
path: root/qpdf/fix-qdf
diff options
context:
space:
mode:
Diffstat (limited to 'qpdf/fix-qdf')
-rwxr-xr-xqpdf/fix-qdf397
1 files changed, 0 insertions, 397 deletions
diff --git a/qpdf/fix-qdf b/qpdf/fix-qdf
deleted file mode 100755
index 2892a462..00000000
--- a/qpdf/fix-qdf
+++ /dev/null
@@ -1,397 +0,0 @@
-#!/usr/bin/env perl
-
-require 5.008_001;
-use warnings;
-use strict;
-use File::Basename;
-
-my $whoami = basename($0);
-my $dirname = dirname($0);
-
-if ((@ARGV == 1) && ($ARGV[0] eq '--version'))
-{
- exec "$dirname/qpdf", '--version';
- exit 2;
-}
-
-my $offset = 0;
-my $last_offset = 0;
-
-my $file = shift(@ARGV);
-if (defined $file)
-{
- open(F, "<$file") or die "$whoami: can't open $file: $!\n";
-}
-else
-{
- $file = 'stdin';
- open(F, "<&STDIN") or die "$whoami: can't dup stdin: $!\n";
-}
-binmode F;
-binmode STDOUT;
-
-my $line = get_line();
-if (! ((defined $line) && ($line =~ m/^%PDF-1\.\d+\b/)))
-{
- die "$whoami: $file: not a pdf file\n";
-}
-print $line;
-$line = get_line();
-die "$whoami: $file: premature EOF\n" unless defined $line;
-print $line;
-$line = get_line();
-if (! ((defined $line) && ($line =~ m/^%QDF-1.\d+\b/)))
-{
- die "$whoami: $file: not a qdf file\n";
-}
-print $line;
-
-my $last_obj = 0;
-my @xref = ();
-
-my $stream_start = 0;
-my $stream_length = 0;
-my $xref_offset = 0;
-my $xref_f1_nbytes = 0;
-my $xref_f2_nbytes = 0;
-my $xref_size = 0;
-
-my $cur_state = 0;
-my $st_top = ++$cur_state;
-my $st_in_obj = ++$cur_state;
-my $st_in_stream = ++$cur_state;
-my $st_after_stream = ++$cur_state;
-my $st_in_ostream_dict = ++$cur_state;
-my $st_in_ostream_offsets = ++$cur_state;
-my $st_in_ostream_outer = ++$cur_state;
-my $st_in_ostream_obj = ++$cur_state;
-my $st_in_xref_stream_dict = ++$cur_state;
-my $st_in_length = ++$cur_state;
-my $st_at_xref = ++$cur_state;
-my $st_before_trailer = ++$cur_state;
-my $st_in_trailer = ++$cur_state;
-my $st_done = ++$cur_state;
-
-my @ostream = ();
-my @ostream_offsets = ();
-my @ostream_discarded = ();
-my $ostream_idx = 0;
-my $ostream_id = 0;
-my $ostream_extends = "";
-
-my $state = $st_top;
-while (defined($line = get_line()))
-{
- if ($state == $st_top)
- {
- if ($line =~ m/^(\d+) 0 obj$/)
- {
- check_obj_id($1);
- $state = $st_in_obj;
- }
- elsif ($line =~ m/^xref$/)
- {
- $xref_offset = $last_offset;
- $state = $st_at_xref;
- }
- print $line;
- }
- elsif ($state == $st_in_obj)
- {
- print $line;
- if ($line =~ m/^stream$/)
- {
- $state = $st_in_stream;
- $stream_start = $offset;
- }
- elsif ($line =~ m/^endobj$/)
- {
- $state = $st_top;
- }
- elsif ($line =~ m,/Type /ObjStm,)
- {
- $state = $st_in_ostream_dict;
- $ostream_id = $last_obj;
- }
- elsif ($line =~ m,/Type /XRef,)
- {
- $xref_offset = $xref[-1][1];
- $xref_f1_nbytes = 0;
- my $t = $xref_offset;
- while ($t)
- {
- $t >>= 8;
- ++$xref_f1_nbytes;
- }
- # Figure out how many bytes we need for ostream index.
- # Make sure we get at least 1 byte even if there are no
- # object streams.
- my $max_objects = 1;
- foreach my $e (@xref)
- {
- my ($type, $f1, $f2) = @$e;
- if ((defined $f2) && ($f2 > $max_objects))
- {
- $max_objects = $f2;
- }
- }
- while ($max_objects)
- {
- $max_objects >>=8;
- ++$xref_f2_nbytes;
- }
- my $esize = 1 + $xref_f1_nbytes + $xref_f2_nbytes;
- $xref_size = 1 + @xref;
- my $length = $xref_size * $esize;
- print " /Length $length\n";
- print " /W [ 1 $xref_f1_nbytes $xref_f2_nbytes ]\n";
- $state = $st_in_xref_stream_dict;
- }
- }
- elsif ($state == $st_in_ostream_dict)
- {
- if ($line =~ m/^stream/)
- {
- $state = $st_in_ostream_offsets;
- }
- else
- {
- push(@ostream_discarded, $line);
- if ($line =~ m,/Extends (\d+ 0 R),)
- {
- $ostream_extends = $1;
- }
- }
- # discard line
- }
- elsif ($state == $st_in_ostream_offsets)
- {
- if ($line =~ m/^\%\% Object stream: object (\d+)/)
- {
- check_obj_id($1);
- $stream_start = $last_offset;
- $state = $st_in_ostream_outer;
- push(@ostream, $line);
- }
- else
- {
- push(@ostream_discarded, $line);
- }
- # discard line
- }
- elsif ($state == $st_in_ostream_outer)
- {
- adjust_ostream_xref();
- push(@ostream_offsets, $last_offset - $stream_start);
- $state = $st_in_ostream_obj;
- push(@ostream, $line);
- }
- elsif ($state == $st_in_ostream_obj)
- {
- push(@ostream, $line);
- if ($line =~ m/^\%\% Object stream: object (\d+)/)
- {
- check_obj_id($1);
- $state = $st_in_ostream_outer;
- }
- elsif ($line =~ m/^endstream/)
- {
- $stream_length = $last_offset - $stream_start;
- write_ostream();
- $state = $st_in_obj;
- }
- }
- elsif ($state == $st_in_xref_stream_dict)
- {
- if ($line =~ m,/(Length|W) ,)
- {
- # already printed
- }
- elsif ($line =~ m,/Size ,)
- {
- my $size = 1 + @xref;
- print " /Size $xref_size\n";
- }
- else
- {
- print $line;
- }
- if ($line =~ m/^stream\n/)
- {
- my $pack = "(C C$xref_f1_nbytes C$xref_f2_nbytes)";
- print pack($pack, 0, 0, 0);
- foreach my $x (@xref)
- {
- my ($type, $f1, $f2) = @$x;
- $f2 = 0 unless defined $f2;
- my @f1 = ();
- my @f2 = ();
- foreach my $d ([\@f1, $f1, $xref_f1_nbytes],
- [\@f2, $f2, $xref_f2_nbytes])
- {
- my ($fa, $f, $nbytes) = @$d;
- for (my $i = 0; $i < $nbytes; ++$i)
- {
- unshift(@$fa, $f & 0xff);
- $f >>= 8;
- }
- }
- print pack($pack, $type, @f1, @f2);
- }
- print "\nendstream\nendobj\n\n";
- print "startxref\n$xref_offset\n\%\%EOF\n";
- $state = $st_done;
- }
- }
- elsif ($state == $st_in_stream)
- {
- if ($line =~ m/^endstream$/)
- {
- $stream_length = $last_offset - $stream_start;
- $state = $st_after_stream;
- }
- print $line;
- }
- elsif ($state == $st_after_stream)
- {
- if ($line =~ m/^\%QDF: ignore_newline$/)
- {
- --$stream_length;
- }
- elsif ($line =~ m/^(\d+) 0 obj$/)
- {
- check_obj_id($1);
- $state = $st_in_length;
- }
- print $line;
- }
- elsif ($state == $st_in_length)
- {
- if ($line !~ m/^\d+$/)
- {
- die "$file:$.: expected integer\n";
- }
- my $new = "$stream_length\n";
- $offset -= length($line);
- $offset += length($new);
- print $new;
- $state = $st_top;
- }
- elsif ($state == $st_at_xref)
- {
- my $n = scalar(@xref);
- print "0 ", $n+1, "\n0000000000 65535 f \n";
- for (@xref)
- {
- my ($type, $f1, $f2) = @$_;
- printf("%010d 00000 n \n", $f1);
- }
- $state = $st_before_trailer;
- }
- elsif ($state == $st_before_trailer)
- {
- if ($line =~ m/^trailer <</)
- {
- print $line;
- $state = $st_in_trailer;
- }
- # no output
- }
- elsif ($state == $st_in_trailer)
- {
- if ($line =~ m/^ \/Size \d+$/)
- {
- print " /Size ", scalar(@xref) + 1, "\n";
- }
- else
- {
- print $line;
- }
- if ($line =~ m/^>>$/)
- {
- print "startxref\n$xref_offset\n\%\%EOF\n";
- $state = $st_done;
- }
- }
- elsif ($state == $st_done)
- {
- # ignore
- }
-}
-
-die "$whoami: $file: premature EOF\n" unless $state == $st_done;
-
-sub get_line
-{
- my $line = scalar(<F>);
- if (defined $line)
- {
- $last_offset = $offset;
- $offset += length($line);
- }
- $line;
-}
-
-sub check_obj_id
-{
- my $cur_obj = shift;
- if ($cur_obj != $last_obj + 1)
- {
- die "$file:$.: expected object ", $last_obj + 1, "\n";
- }
- $last_obj = $cur_obj;
- push(@xref, [1, $last_offset]);
-}
-
-sub adjust_ostream_xref
-{
- pop(@xref);
- push(@xref, [2, $ostream_id, $ostream_idx++]);
-}
-
-sub write_ostream
-{
- my $first = $ostream_offsets[0];
- my $onum = $ostream_id;
- my $offsets = "";
- my $n = scalar(@ostream_offsets);
- for (@ostream_offsets)
- {
- $_ -= $first;
- ++$onum;
- $offsets .= "$onum $_\n";
- }
- my $offset_adjust = length($offsets);
- $first += length($offsets);
- $stream_length += length($offsets);
- my $dict_data = "";
- $dict_data .= " /Length $stream_length\n";
- $dict_data .= " /N $n\n";
- $dict_data .= " /First $first\n";
- if ($ostream_extends)
- {
- $dict_data .= " /Extends $ostream_extends\n";
- }
- $dict_data .= ">>\n";
- $offset_adjust += length($dict_data);
- print $dict_data;
- print "stream\n";
- print $offsets;
- foreach (@ostream)
- {
- print $_;
- }
-
- for (@ostream_discarded)
- {
- $offset -= length($_);
- }
- $offset += $offset_adjust;
-
- $ostream_idx = 0;
- $ostream_id = 0;
- @ostream = ();
- @ostream_offsets = ();
- @ostream_discarded = ();
- $ostream_extends = "";
-}