summaryrefslogtreecommitdiffstats
path: root/pdftool.pl
diff options
context:
space:
mode:
Diffstat (limited to 'pdftool.pl')
-rwxr-xr-xpdftool.pl119
1 files changed, 78 insertions, 41 deletions
diff --git a/pdftool.pl b/pdftool.pl
index bb4d3dc..5c331ce 100755
--- a/pdftool.pl
+++ b/pdftool.pl
@@ -72,6 +72,9 @@ Version: 0.1, 25 September 2010
=cut
+# TODO: inline it in the header
+$main::VERSION = "0.1, 25 September 2010";
+
my $tmpdir = '/tmp';
@@ -155,6 +158,9 @@ if (defined $infile && $infile ne "-") {
*FIN = *STDIN;
$infile_display = "(stdin)";
}
+# After the pipe, it won't be detected as seekable
+my $inseek = (seek FIN, 0, 1) ? 1 : undef;
+
if (defined $outfile && $outfile ne "-") {
open FOUT, '>', "$outfile" or die "Can't create `$outfile': $!";
@@ -167,15 +173,42 @@ if (defined $outfile && $outfile ne "-") {
#
# Detect filetype
#
+# To avoid to seek into FIN, it gonna be copied from WRITE to READ in
+# background, once the filetype has been read
+
+# TODO: read specification to detect filetype properly
my $filetype;
-my $fstline = <FIN>;
-if (defined $fstline && $fstline =~ /^%!PS.*/) {
- $filetype = "PS";
-} elsif (defined $fstline && $fstline =~ /^%PDF.*/) {
- $filetype = "PDF";
-} else {
- die "Can't recognize the type of `$infile_display'";
+pipe *READ, *WRITE or die "Can't pipe: $!";
+while (not (defined $filetype) && defined (my $l = <FIN>)) {
+ print WRITE $l or die "Can't close: $!";
+
+ if (defined $l && $l =~ /^%!PS/) {
+ $filetype = "PS";
+ } elsif (defined $l && $l =~ /^%PDF/) {
+ $filetype = "PDF";
+ }
+}
+
+die "Cannot recognise FileType" unless defined $filetype;
+
+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 or die "Can't print: $!";
+ }
+ exit;
}
+# Parent
+
+close WRITE or die "Can't close: $!";
+close FIN or die "Can't close: $!";
+
+open *FIN, "<&READ" or die "Can't dup: $!";
+
+
# Auxiliary files, to remove
my @auxfiles;
@@ -185,7 +218,6 @@ my @auxfds;
# Pids, to waid for
my @pids;
-my $pid;
@@ -194,39 +226,37 @@ my $pid;
#
my @cmd;
if ($filetype eq "PDF") {
- unless (defined $infile) {
+ unless (defined $infile && $inseek) {
# Need to copy the whole input to an auxiliary file, since
# conversion from PDF to PS requires random access to the data
$infile = "$tmpdir/pdftool-stdin-$$" . lc ".$filetype";
- open FIN2, '>', "$infile"
+ open FINAUX, '>', "$infile"
or die "Can't write into `$infile': $!";
push @auxfiles, "$infile";
- # cat > $filename
- # TODO: useless seek
- seek FIN, 0, 0 or die $!;
+ # cat > $infile
while (<FIN>) {
- print FIN2 $_ or die "Can't print: $!";
+ print FINAUX or die "Can't print: $!";
}
- close FIN2;
+ close FINAUX;
}
- close FIN;
+
# Convert to PS
@cmd = ('pdftops', "$infile", '-');
push @cmd, '-q' if defined $quiet;
- $pid = open *PSIN, "-|", @cmd
- or die "Can't run: `" . &printcmd (@cmd) . "'";
- push @pids, $pid;
+ my $pid = open PSIN, "-|", @cmd
+ or die "Can't run `" . &printcmd (@cmd) . "'";
+ my @pair = ($pid, @cmd);
+ push @pids, \@pair;
} else {
- # TODO: useless seek
- seek FIN, 0, 0 or die $!;
*PSIN = *FIN;
}
+
#
# Select, if necessary
#
@@ -234,9 +264,9 @@ if ($filetype eq "PDF") {
if (defined $select) {
@cmd = ('psselect', "-p$select");
push @cmd, '-q' if defined $quiet;
- $pid = open2 *PSSELECT, "<&PSIN", @cmd
- or die "Can't run: `" . &printcmd (@cmd) . "'";
- push @pids, $pid;
+ my $pid = open2 *PSSELECT, "<&PSIN", @cmd;
+ my @pair = ($pid, @cmd);
+ push @pids, \@pair;
} else {
*PSSELECT = *PSIN;
}
@@ -250,9 +280,9 @@ if (defined $select) {
push @cmd, "-c" if defined $crop;
push @cmd, '-q' if defined $quiet;
-$pid = open2 *PSRESIZE, "<&PSSELECT", @cmd
- or die "Can't run: `" . &printcmd (@cmd) . "'";
-push @pids, $pid;
+my $pid = open2 *PSRESIZE, "<&PSSELECT", @cmd;
+my @pair = ($pid, @cmd);
+push @pids, \@pair;
# Note: open2 closes the filehandles for us :)
@@ -263,9 +293,10 @@ push @pids, $pid;
if (defined $book) {
@cmd = ('psbook');
push @cmd, '-q' if defined $quiet;
- $pid = open2 *PSBOOK, "<&PSRESIZE", @cmd
- or die "Can't run: `" . &printcmd (@cmd) . "'";
- push @pids, $pid;
+
+ my $pid = open2 *PSBOOK, "<&PSRESIZE", @cmd;
+ my @pair = ($pid, @cmd);
+ push @pids, \@pair;
} else {
*PSBOOK = *PSRESIZE;
}
@@ -278,9 +309,10 @@ if (defined $book) {
if ($nup > 1) {
@cmd = ('psnup', "-p$paper", "-m$mnup", "-$nup");
push @cmd, '-q' if defined $quiet;
- $pid = open2 *PSOUT, "<&PSBOOK", @cmd
- or die "Can't run: `" . &printcmd (@cmd) . "'";
- push @pids, $pid;
+
+ my $pid = open2 *PSOUT, "<&PSBOOK", @cmd;
+ my @pair = ($pid, @cmd);
+ push @pids, \@pair;
} else {
*PSOUT = *PSBOOK;
}
@@ -294,25 +326,30 @@ if ($filetype eq "PDF") {
# Convert back to PDF
@cmd = ('ps2pdf', "-dEmbedAllFonts=true", "-sPAPERSIZE=$paper", '-', '-');
- $pid = open2 ">&FOUT", "<&PSOUT", @cmd
- or die "Can't run: `" . &printcmd (@cmd) . "'";
- push @pids, $pid;
+ $pid = open2 ">&FOUT", "<&PSOUT", @cmd;
+ my @pair = ($pid, @cmd);
+ push @pids, \@pair;
} else {
# cat > FOUT
while (<PSOUT>) {
- print FOUT $_ or die "Can't print: $!";
+ print FOUT or die "Can't print: $!";
}
}
# Avoid zombies
-map {waitpid $_, 0} @pids;
+map { my ($pid, @cmd) = @$_;
+# print STDERR "PID: ", $pid, " Cmd: `", &printcmd (@cmd), "'";
+ my ($r,$v) = (waitpid ($pid, 0), $?);
+ warn "Can't run `" . &printcmd (@cmd) . "'" if ($r != -1 and $v >> 8);
+ } @pids;
# Close auxiliary filehandles
-map {close $_} @auxfds;
-close FIN;
-close FOUT;
+map {close} @auxfds;
+close READ or die "Can't close: $!";
+close FIN or die "Can't close: $!";
+close FOUT or die "Can't close: $!";
# Delete auxiliary files