From 7db66bd078c3fcba6cf4913b5bb11efb2b27dfdd Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 26 Sep 2010 18:47:58 +0200 Subject: No more useless seek (as far I know) --- psresize2.pl | 117 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 75 insertions(+), 42 deletions(-) diff --git a/psresize2.pl b/psresize2.pl index dc3ee6f..67e9d4a 100755 --- a/psresize2.pl +++ b/psresize2.pl @@ -26,6 +26,15 @@ I rescales and centres a document on a different size of paper. The input PostScript file should follow the Adobe Document Structuring Conventions. +If no input file is given, or if a single hyphen-minus (B<->) is given as +file name, I will read the PostScript data from the standard +input. In that case, and if the crop option (B<-c>) is set, an auxiliary +file will be created, and removed afterwards. + +If no output file is given, or if a single hyphen-minus (B<->) is given as +file name, I will send the PostScript data to the standard +output. + =head1 OPTIONS =over 8 @@ -199,23 +208,6 @@ if (defined $infile && $infile ne "-") { open FIN, '<', "$infile" or die "Can't read `$infile': $!"; } else { *FIN = *STDIN; - - # TODO: no need to such an ugly auxiliary file? - - $infile = "$tmpdir/psresize-stdin-$$.ps"; - - open FIN2, '>', "$infile" - or die "Can't write into `$infile': $!"; - push @auxfiles, "$infile"; - - # cat > $filename - while () { - print FIN2 $_ or die "Can't print: $!"; - } - close FIN2; - close FIN; - - open FIN, '<', "$infile" or die "Can't read `$infile': $!"; } if (defined $outfile && $outfile ne "-") { @@ -224,6 +216,8 @@ if (defined $outfile && $outfile ne "-") { *FOUT = *STDOUT; } +*LOG = *STDERR; + # @@ -232,19 +226,35 @@ if (defined $outfile && $outfile ne "-") { my @bbox; if (defined $crop) { # Calculate the maximal bounding box + + unless (seek FIN, 0, 1) { + # The input is not seekable: have to create a seekable auxiliary file + + my $auxfile = "$tmpdir/psresize-stdin-$$.ps"; + open FINAUX, '>', "$auxfile" + or die "Can't write into `$auxfile': $!"; + push @auxfiles, $auxfile; + + # cat > $auxfile + while () { + print FINAUX $_ or die "Can't print: $!"; + } + close FINAUX or die "Can't close: $!"; + close FIN or die "Can't close: $!"; + + open FIN, '<', "$auxfile" or die "Can't read `$auxfile': $!"; + } + # Need to duplicate FIN, since it will be closed in the parent process - open *KIDFIN, "<&FIN" or die "Can't dup FIN: $!"; - - my @cmd = ('gs', '-sDEVICE=bbox', '-dBATCH', '-dNOPAUSE', '-'); - my $pid = open3 "<&KIDFIN", ">&GS", *GS, @cmd - or die "Can't run: `" . &printcmd (@cmd) . "'"; - # TODO: this `die' is actually useless, since it doesn't catch the - # signals of the child + open *GSIN, '<&FIN'; + my @cmd = ('gs', '-sDEVICE=bbox', '-dBATCH', '-dNOPAUSE', '-'); + my $pid = open3 "<&GSIN", ">&GSOUT", *GSOUT, @cmd; + my ($p,$c) = (0,0); # Page & character counter my ($x0, $y0, $x1, $y1) = (1<<16, 1<<16, -(1<<16), -(1<<16)); - while () { + while () { if ($_ =~ m/^\%\%BoundingBox: (\d+) (\d+) (\d+) (\d+)/) { $x0 = $1 if $1 < $x0; $y0 = $2 if $2 < $y0; @@ -254,18 +264,19 @@ if (defined $crop) { my $s = "[" . ++$p . "] "; $c += length $s; if ($c >= 80) { - print STDERR "\n"; + print LOG "\n"; $c = length $s; } - print STDERR $s; + print LOG $s; } } } - close GS; - print STDERR "\n" unless defined $quiet; + close GSOUT or die "Can't close: $!";; + print LOG "\n" unless defined $quiet; # No zombie processes waitpid $pid, 0; + die "Can't run `" . &printcmd (@cmd) . "'" if $? >> 8; die "Error when calculating bounding box" if ($x0 >= $x1 || $y0 >= $y1); @bbox = ($x0, $y0, $x1, $y1); @@ -277,20 +288,42 @@ if (defined $crop) { @bbox = (0, 0, $inwidth, $inheight); } else { # Guess page size from the input file - + + # To avoid to seek into FIN, it gonna be copied from WRITE to READ + # in background, once the Bounding Box has been read + pipe *READ, *WRITE or die "Can't pipe: $!"; + while () { + print WRITE $_; if ($_ =~ m/^\%\%BoundingBox: (\d+) (\d+) (\d+) (\d+)/) { @bbox = ($1, $2, $3, $4); last; } } - die "Cannot guess input page size!" unless @bbox; + + die "Cannot guess input page size!" unless @bbox; - seek FIN, 0, 0 or die "$!"; + unless (my $pid = fork) { + # Child: cat FIN > WRITE in background + die "Can't fork: $!" unless defined $pid; + close READ or die "Can't close: $!";; + + while () { + print WRITE $_; + } + exit; + } + # Parent + + close WRITE or die "Can't close: $!"; + close FIN or die "Can't close: $!"; + + open *FIN, "<&READ" or die "Can't dup: $!"; } + # # Calculate PStoPS specification # @@ -307,12 +340,11 @@ my $spec = 0 . &calc_pstops_page(@bbox, $x0, $y0, $x1, $y1); my @cmd = ('pstops', "-w$outwidth", "-h$outheight", "$spec"); push @cmd, '-q' if defined $quiet; -my $pid = open2 *FINPS2PS, "<&FIN", @cmd - or die "Can't run: `" . &printcmd (@cmd) . "'"; +my $pid = open3 "<&FIN", *PS2PS, ">&LOG", @cmd; my $l; # Header and comments -while (defined ($l = ) && $l ne "\%\%EndComments\n") { +while (defined ($l = ) && $l ne "\%\%EndComments\n") { # Optional, but nice: tune how "gv" will show the document next if $l =~ m/^\%\%DocumentMedia:/; @@ -334,30 +366,31 @@ print FOUT << "EOF"; EOF # Body -while () { +while () { print FOUT $_ or die "Can't print: $!"; # PStoPSclip hack: increase clipping box by 10 if ($_ =~ m/^userdict\/PStoPSclip{0 0 moveto$/) { - $l = ; + $l = ; $l =~ s/\./0./g; print FOUT $l or die "Can't print: $!"; } } -close FIN; -close FOUT; - # No zombie processes waitpid $pid, 0; +die "Can't run `" . &printcmd (@cmd) . "'" if $? >> 8; + +close FIN; +close FOUT; # Delete auxiliary files unlink @auxfiles; # Useless, but Perl doesn't see that this filehandle is used more than # one time (and even automatically closed by `open3') -exit 0; -close KIDFIN; +exit; +close GSIN; -- cgit v1.2.3