summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem.moulin@chalmers.se>2010-09-26 18:47:58 +0200
committerGuilhem Moulin <guilhem.moulin@chalmers.se>2010-09-26 18:47:58 +0200
commit7db66bd078c3fcba6cf4913b5bb11efb2b27dfdd (patch)
treeecaea6f087a270dd05abd6b565b35770fad9568d
parent38e9dfed2421cf359feba6ae56b308f45df3cb9b (diff)
No more useless seek (as far I know)
-rwxr-xr-xpsresize2.pl117
1 files 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<PSResize2> 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<PSResize2> 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<PSResize2> 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 (<FIN>) {
- 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 (<FIN>) {
+ 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 (<GS>) {
+ while (<GSOUT>) {
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 (<FIN>) {
+ 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 (<FIN>) {
+ 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 = <FINPS2PS>) && $l ne "\%\%EndComments\n") {
+while (defined ($l = <PS2PS>) && $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 (<FINPS2PS>) {
+while (<PS2PS>) {
print FOUT $_ or die "Can't print: $!";
# PStoPSclip hack: increase clipping box by 10
if ($_ =~ m/^userdict\/PStoPSclip{0 0 moveto$/) {
- $l = <FINPS2PS>;
+ $l = <PS2PS>;
$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;