#! /usr/local/bin/perl -w use strict; my $width = 29.7; # cm my $resolution = 600; # dpi my $tmpdir = '.intermediate'; my $outfile = 'out.pdf'; my $fs = 1; my $process = 1; my $latex = 1; #------------------------- my $uid = 0; my @manifest = ( ); foreach my $arg(@ARGV) { if($arg =~ /^-width=([0-9.]+)/) { $width = $1; print "Width set to $1cm\n"; } elsif($arg =~ /^-nolatex/) { print "Will not run LaTeX or delete intermediates afterwards.\n"; $latex = 0; } elsif($arg =~ /^-raw/) { print "Images will not be scaled or dithered.\n"; $process = 0; } elsif($arg =~ /^-dpi=([0-9]+)/) { $resolution = $1; print "Resolution set to $1dpi\n"; } elsif($arg =~ /^-o=(.+)/) { $outfile = $1; print "Output file set to $1\n"; } elsif($arg eq '-riemer') { $fs = 0; print "Riemersma dither will be used.\n"; } elsif($arg eq '-fs') { $fs = 1; print "Floyd-steinberg dither will be used.\n"; } else { push @manifest, $arg; print "File: $arg\n"; } }; my @info = ( ); $#manifest > -1 or die <<'END' Usage: makepdf [options] image image image... eg. makepdf -dpi=600 1a.tif 1b.png No files were listed on the commandline END ; my @types = ( { tag=>'PNG' }, { tag=>'JPEG' }, { tag=>'Netpbm' }, { tag=>'TIFF' } ); # --------------------------------------------------------------- my $inches = $width * 0.3937; my $pels = $inches * $resolution; my $textemplate = <<'END' \documentclass[a4paper,landscape,twoside]{minimal} \usepackage{geometry} \geometry{top=0cm,bottom=0cm,left=0cm,right=0cm,nohead,nofoot} \usepackage{graphicx} \usepackage{calc} \begin{document} \thispagestyle{empty} \centering % ---- insert images here % % % % ---- end \end{document} % ---- 8< texfile.tex - cut here 8< ---- END ; my $texout = $textemplate; # -------------------------------- sub addimage { my ($image) = @_; $image = '\includegraphics[width=' . $width . 'cm]{' . $image . '}'; print "Adding to tex source: $image\n"; $image .= "\n" . '\newpage' . "\n% % %" ; $texout =~ s/% % %/$image/m; } sub scaleimage { use POSIX; use FileHandle; my ($pnmimage) = @_; my $header = `head $pnmimage -n 3`; $header =~ /P[0-9]\n([0-9]+)[\n ]+([0-9]+)\n/ or die "Can't parse $pnmimage header\n"; my $x = $1; my $y = $2; my $ratio = ($pels / $x); my $nx = ceil($pels); my $ny = ceil($y * $ratio); print "Scale: attempting to scale $pnmimage to $width cm at $resolution dpi.\n"; print "Scale: guessing $x x $y-> $nx x $ny\n"; if($x != $nx) { my $result = `pnmscale -xsize $nx $pnmimage`; my $fh = new FileHandle; $fh->open('> ' . $pnmimage); print $fh $result; $fh->close; } else { print "Scale: image already required size; not touching.\n"; } $header = `head $pnmimage -n 3`; $header =~ /P[0-9]\n([0-9]+)[\n ]+([0-9]+)\n/ or die "Can't parse $pnmimage header\n"; $x = $1; $y = $2; print "Scale result: $x x $y image\n"; } sub ditherimage { my ($pnmimage) = @_; if($fs) { print "Dithering $pnmimage using Floyd-Steinberg\n"; use FileHandle; my $out = `pgmtopbm -fs $pnmimage`; my $fh = new FileHandle; $fh->open('> ' . $pnmimage); print $fh $out; $fh->close(); } else { my $result = `riemer $pnmimage $pnmimage`; $result =~ /\*OK\r/ or die ("Dither failed: $result\n"); print $result; } } sub prepare { my @files = @_; (-d $tmpdir or mkdir $tmpdir ); foreach my $file(@files) { $file =~ / / and die "Prepare: $file contains spaces, or is in a directory that contains spaces. LaTeX doesn't like that. Please rename or move.. \n"; (-f $file) or die "Prepare: $file not found. Current directory is " . `pwd` . ".\n"; my $id = `file $file`; my $found = 0; foreach my $candidate(@types) { $id =~ /$candidate->{tag}/ and $found = $candidate; } $found or die "Prepare: don't know how to deal with $file.\n$id\n"; print "Prepare: $file: detected $found->{tag} file.\n"; my $pgm = $tmpdir . '/' . $uid . '.pgm'; my $png = $tmpdir . '/' . $uid . '.png'; $uid++; push @info, { source=>$file, id=>$id, info=>$found, tmp=>$pgm, out=>$png }; } } sub convert { my($desc) = @_; print "Converting to pgm: $desc->{source} -> $desc->{tmp}\n"; my $result = `anytopnm $desc->{source} | ppmtopgm > $desc->{tmp}`; } sub postprocess { my($desc) = @_; print "Postprocess: converting to png for LaTeX\n"; print "Postprocess: $desc->{tmp} -> $desc->{out}\n"; my $result = `pnmtopng $desc->{tmp} > $desc->{out}`; -f $desc->{out} or die ("Postprocess: convertion failed.\n$result"); } sub writetex { my $texfile = $tmpdir . '/out.tex'; print "Writing $texfile.\n"; use FileHandle; my $fh = new FileHandle; $fh->open('> ' . $texfile); print $fh $texout; $fh->close(); } sub makepdf { my $texfile = $tmpdir . '/out.tex'; print "Running LaTeX: $texfile -> $outfile\n"; my $result = `texi2pdf -q -o $outfile $texfile`; (-f $outfile) or die ("LaTeX failed.\n$result"); } # --------------------------- prepare(@manifest); foreach my $desc(@info) { convert($desc); $process and scaleimage($desc->{tmp}); $process and ditherimage($desc->{tmp}); postprocess($desc); addimage($desc->{out}); } writetex(); if($latex) { makepdf(); print "Cleaning up..\n"; `rm .intermediate/*`; `rmdir .intermediate`; } print "Done.\n";