#!/usr/local/bin/perl

# This variable can be set manually or by the installation script
# to point to the DIRECTORY where the latex2html files can be found.
$LATEX2HTMLDIR="$ENV{'L2HMODULE'}/user";# Inserted by installation script

if ($] >= 5 ) {# we have Perl 5.0 or later...

# All operating system depended stuff should be defined in
# Override.pm before being used in the code.
# See export.pm on how to do this
# This path is set to where the Override module can be found.
use lib "$ENV{'L2HMODULE'}";

use Cwd;

use Override qw(getpwuid link setenv getenv symlink rename
		make_directory_absolute unlink $dd $envkey $DEBUG);
} else {
    print "\n*** could not configure automatically using Override.pm ***";
    print "\n*** so assuming standard Unix conventions apply ***\n";

# With Perl 5 these should have been set already, within  Override.pm

# The key, which delimts expressions defined in the environment
# depends on the operating system.
    $envkey=':' unless ($envkey);

# $dd is the directory delimiter character
    $dd = '/' unless ($dd);
}

# $Id: pstoimg_nopipes,v 1.10 1998/02/26 10:41:58 latex2html Exp $
#
# pstoimg V98.1
#
# originally by Nikos Drakos <nikos@cbl.leeds.ac.uk>
# Computer Based Learning Unit, University of Leeds.
#
# Accompanies LaTeX2HTML Version 98.1
#
# Script to convert an arbitrary PostScript image to a cropped GIF or PNG
# image suitable for incorporation into HTML documents as inlined images
# to be viewed with WWW browsers.
#
# This is based on the pstoepsi script 
# by Doug Crabill dgc@cs.purdue.edu
#
# Please note the following:

# - The -density argument has no effect unless the 
#   color depth (set with the -depth argument) is equal to 1.
# - Valid arguments for -depth are 1,8, or 24.
#  
# This software is provided as is without any guarantee.
#
# Nikos Drakos (ND), nikos@cbl.leeds.ac.uk
# Computer Based Learning Unit, University of Leeds.
#
# $Log: pstoimg_nopipes,v $
# Revision 1.10  1998/02/26 10:41:58  latex2html
#  --  implemented a  -white  switch, to make gray backgrounds into white
# 	otherwise transparent backgrounds need not work
#
# Revision 1.9  1998/02/26 02:50:37  latex2html
#  --  removed the use of full pathnames with GS
#  --  some small cleaning-up
#
# Revision 1.8  1998/02/19 11:08:40  latex2html
#  --  some messages are only printed with $DEBUG
#
# Revision 1.7  1998/02/13 13:05:59  latex2html
#  --  defined &cp to making copying file platform-independent
#
# Revision 1.6  1998/02/12 06:43:43  latex2html
#  --  fixed the error when $TMP is a relative directory
#
# Revision 1.5  1998/02/10 02:49:00  latex2html
# 	updated for V98.1 and the changes in pstoimg
#
# Revision 1.4  1997/12/10 00:45:15  RRM
#  --  bringing the nopipes version into line with the main pstoimg script
#
# Revision 1.3  1997/07/03 07:30:08  RRM
#  -   Fixed up the  $/  for the  %%Papersize search
#  -   Allow  $DEBUG  as a predefined variable
#
# Revision 1.2  1997/06/23 08:03:34  RRM
#  -  Use multi-line matching during the PaperSize search
#
# Revision 1.1  1997/06/15 08:12:08  RRM
#      This is a version of  pstoimg  that does not use Unix pipes.
#      On some systems one or more graphics utilities fails with piping;
# 	e.g.  pnmcrop .
#
# Revision 1.17  1997/04/09 13:45:10  RRM
#  -  Changed the version to 97.1
#  -  fixed small bug on the `die' --- thanks Marcus Hennecke
#  -  fixed the naming for multiple images from a single .ps file
#  -  implemented a switch  -multipage  to signify multiple pages
#  -  added `shaving' option for -extra_crop ; allows shaving to baseline
#     from below; to prevent cropping of characters just below baseline.
#
# Revision 1.16  1997/03/24 13:34:36  RRM
#  - Fixed bug whereby fractional widths/height was causing PBMMAKE to fail.
#  - Improvements to the  -shoreup  mechanism.
#
# Revision 1.15  1997/03/15 10:43:45  RRM
# Implemented Marcus Henneck's code for the -margins  switch, and how
# to use the margins. Dropped the  DVIPS_  from variable names.
#
# Revision 1.14  1997/02/25 11:36:51  RRM
# Extended the options to -crop to accept any sequence of crops along
# any sides.
#
# Revision 1.13  1997/02/21 10:59:03  MRO
# Cosmetic change.
#
# Revision 1.12  1997/02/17 02:20:36  RRM
# small fixes
#
# Revision 1.11  1997/01/03 13:16:48  MRO
# Fixed (?) bug reported by Herb Swan, added code that extracts page dimensions
# from postscript file if geometry is given.
#
# Revision 1.10  1996/12/22 10:19:56  MRO
# Oops! Fixed bugs introduced few minutes before... Removed perl -w switch.
#
# Revision 1.9  1996/12/22 10:10:22  MRO
# Added code for shore_up and bottom_crop:
#   -shoreup <pixel>: make image dimensions multiples of <pixel>
#   -crop [vhb]: v,h as before, b crop image at the bottom
#
# Revision 1.8  1996/12/20 20:28:32  JCL
# the -w switch for perl is somehow nerving.
# It always want to indicate typo cause of variables used only once.
#
# Revision 1.7  1996/12/18 14:36:29  MRO
# Included Ross Moore's latest patches, streamlined some code.
#
# Revision 1.6  1996/12/16 14:01:28  MRO
# Hacked in Ross' enhancements for pstoimg, modified these a little.
# Papersize selection and landscape rotation are disabled, but ready to be
# included.
#
# Revision 1.5  1996/12/16 08:27:29  MRO
# Fixed minor things pstoimg and configure-pstoimg (extensions, switches).
#
# Revision 1.4  1996/12/15 18:36:02  MRO
# Changed pstoimg etc to enable runtime selection of output image format.
#
# Revision 1.3  1996/12/14 16:42:02  JCL
# o  adapted for use with 'local.pm' system configuration
# o  removed spurious "-black" option
#
# (end CVS log)
#
# Oct 25 1996 Marek Rouchal: Introduced PNG image format and fine-tuned
#      image processing. Renamed pstogif to pstoimg. Added -debug
#
# Aug 25 1996 Marek Rouchal <marek@saftsack.fs.uni-bayreuth.de>
#      Extensive patch to move all bitmap stuff out of l2h to pstogif
#      Added automatic configuration script
#
# 5 JUN 96 RRM  Allow Ghostscript 3.3+  to quit without a prompt.
#		Also, removed unused variable names.
# 
# 15 Jan 96 HS Call ppmquant only if needed.  Fixed bug relative to
#    V 95.3 .
#
# 15 Dec 95 HS (Herbert Swan <dprhws.edp.Arco.com> Added support for
#    the flip=option.  This allows images to be oriented differently
#    in the paper versus the electronic media
#
# 1 Nov 95 jmn - modified for use with gs ppm driver - from jhrg's patches
#    note that ppmtops.ps and ppmtops3.ps are no longer needed
#
# 20 JUL 94 ND Converted to Perl and made several changes eg it now accepts 
#    parameters from environment variables or from command line or will use 
#    default ones. 
#      
# 1  APR 94 ND Changed the suffixes of multi-page files from xbm to gif (oops!)
#

###############################################################################
$| =1;

$prompt = "pstoimg:";

### pstoimg is now automatically configured by configure-pstoimg
### there should be no need to change any settings by hand,
### nevertheless you may do it at your own risk :-)

require "$LATEX2HTMLDIR${dd}local.pm" || die <<"_EOM_";
$prompt: no configuration!
_EOM_

# Some lengths used by dvips
# MRO: Is this true for all runs of dvips?
$PAGE_HEIGHT = 841.889;   # dvips page height, in pts.
$PAGE_WIDTH  = 595.275;   # dvips page width, in pts.
$PAGE_HMARGIN = 72;       # dvips margin: 1 inch = 72pt
$PAGE_VMARGIN = 72;       # dvips margin: 1 inch = 72pt

# Netpbm/Pbmplus stuff
$REDUCE_COLOR=$PPMQUANT . ' 256' if ($PPMQUANT);
 
# This gives the location of the file landscap.ps
# only needed for &choose_paper
$GSLANDSCAPE = "$GS_LIB${dd}landscap.ps";

###############################################################################
# Default settings
# Environment overrides defaults, command line options override everything
$OUTFILE = $ENV{'OUTFILE'};

$MULTIPLEPAGES = '';

# Valid choices for $DEPTH are 1, 8 or 24. 
$DEPTH = $ENV{'DEPTH'} || 8;

#Default density is 72
$DENSITY = $ENV{'DENSITY'} || 72;
    
# Valid choices are any numbers greater than zero
# Useful choices are numbers between 0.1 - 5
# Large numbers may generate very large intermediate files
# and will take longer to process
$SCALE = $ENV{'SCALE'}; # No default value

$PAPERSIZE = $ENV{'PAPERSIZE'}; # No default value;

$DEBUG = $ENV{'DEBUG'} || 0 unless $DEBUG;

$DISCARD = $ENV{'DISCARD_PS'} || 0;

$FLIP=''; # no environment, no flipping by default

$GSROTATE = ''; # no rotation by default

$GS_UNROTATE = "cw"; # pnmflip switch to undo landscape

$GEOMETRY = ''; # no specified geometry by default

$EXTRA_CROP = ''; # no extra crop, by default

$TRANSPARENT=0; # Do not make make images transparent by default

$INTERLACE=0; # Do not make interlaced images by default

$RIGHT_JUSTIFY=0; # No right justifying by default

$CENTER=0; # No centering

$TOP_JUSTIFY=0; # No right justifying by default

$SHORE_UP=0; # No pixel alignment by default

$WHITE=0; # Don't change the background to white

$BASE = $FILE = undef;

######################################################################

# Read command line arguments

do { &usage; exit 0; } if ($#ARGV == -1);

while ($ARGV[0] =~ /^-/o) {
    ($_ = shift @ARGV);
    if ("-help" =~ /^$_/) {
        &usage; exit 0;
        }
    elsif ("-debug" =~ /^$_/) {
        $DEBUG=1;
        }
    elsif ("-discard" =~ /^$_/) {
        $DISCARD=1;
        }
    elsif ("-antialias" =~ /^$_/) {
        $AALIAS=1;
        }
    elsif ("-white" =~ /^$_/) {
        $WHITE=1;
        }
    elsif ("-multipage" =~ /^$_/) {
        $MULTIPLEPAGES=1;
        }
    elsif ("-gif" =~ /^$_/) {
        $IMAGE_TYPE="gif";
        die <<"EOF" unless $PPMTOGIF;
$prompt Fatal Error: This version of pstoimg does not support GIF format.
EOF
        }
    elsif ("-png" =~ /^$_/) {
        $IMAGE_TYPE="png";
        die <<"EOF" unless $PNMTOPNG;
$prompt Fatal Error: This version of pstoimg does not support PNG format.
EOF
        }
    elsif ("-out" =~ /^$_/) {
        $OUTFILE = shift @ARGV;
        die <<"EOF" if $OUTFILE =~ /^-/;
$prompt Fatal Error: Outfile musn't begin with a `-'
EOF
        }
    elsif ("-tmp" =~ /^$_/) {
        $TMP = shift @ARGV;
        }
    elsif ("-depth" =~ /^$_/) {
        $DEPTH = shift @ARGV;
        die <<"EOF" unless $DEPTH =~ /^(1|8|24)$/;
$prompt Fatal Error: Illegal color depth specified: \"$DEPTH\"
         Depth must be either 1, 8 or 24.
EOF
        }
    elsif ("-color" =~ /^$_/) {
        $DEPTH = shift @ARGV;
        die <<"EOF" unless $DEPTH =~ /^(1|8|24)$/;
$prompt Fatal Error: Illegal color depth specified: \"$DEPTH\"
         Depth must be either 1, 8 or 24.
EOF
        }
    elsif ("-flip" =~ /^$_/) {
        $FLIP = shift @ARGV;
        die <<"EOF" unless $FLIP =~ /^\w+$/;
$prompt Fatal Error: Illegal flip option specified: \"$FLIP\"
         Flip must be one of: lr tb xy r90 ccw r270 cw r180
EOF
        do {
            $FLIP='';
            warn <<"EOF";
$prompt Warning: Cannot flip image because of missing external
         program. Run configure-pstoimg again and follow the hints.
EOF
            } unless ($PNMFLIP);
        }
    elsif ("-density" =~ /^$_/) {
        $DENSITY = shift @ARGV;
        die <<"EOF" unless $DENSITY =~ /^\d+$/;
$prompt Fatal Error: Illegal density specified: \"$DENSITY\"
        Density must be an integer value. Default is 72.
EOF
        }
    elsif ("-scale" =~ /^$_/) {
        $SCALE = shift @ARGV;
        die <<"EOF" unless (($SCALE =~ /^[0-9.]+$/) && ($SCALE > 0));
$prompt Fatal Error: Illegal scale specified: \"$SCALE\"
         Scale must be > 0
EOF
        }
    elsif ("-geometry" =~ /^$_/) {
        $GEOMETRY = shift @ARGV;
        if ($GEOMETRY =~ s/-//o ) { $EXTRA_CROP = "bl"; }
            die <<"EOF" unless (($GEOMETRY =~ /^[0-9.]+x[0-9.]+$/));
$prompt Fatal Error: Illegal geometry specified: \"$GEOMETRY\"
         Geometry must be <width>x<height>
EOF
        }
    elsif ("-margins" =~ /^$_/) {
	local($MARGINS) = shift @ARGV;
	die <<"EOF" unless (($MARGINS =~ /^([0-9.]+),([0-9.]+)$/));
$prompt Fatal Error: Illegal margins specified: \"$MARGINS\"
         Margins must be <hmargin>,<vmargin>
EOF
	$PAGE_HMARGIN = $1;
	$PAGE_VMARGIN = $2;
        }
    elsif ("-crop" =~ /^$_/) {
        $EXTRA_CROP = shift @ARGV;
        die <<"EOF" unless ( $EXTRA_CROP =~ /^([vhtblras]*)$/i );
$prompt Fatal Error: Illegal crop specified: \"$EXTRA_CROP\"
         Crop must be  h, v, t, b, l, r, a, s  or combination
EOF
         }
    elsif ("-transparent" =~ /^$_/) {
        if($IMAGE_TYPE eq "gif" && ! $HOWTO_TRANSPARENT_GIF) {
            warn <<"EOF";
$prompt Warning: Cannot make GIF transparent.
         Run the configure-pstoimg program again and follow the hints.
EOF
            }
         else {
            $TRANSPARENT=1;
            }
        }
    elsif ("-interlaced" =~ /^$_/) {
        if($IMAGE_TYPE eq "gif" && ! $HOWTO_INTERLACE_GIF) {
            warn <<"EOF";
$prompt Warning: Cannot make image interlaced.
         Run the configure-pstoimg program again and follow the hints.
EOF
            }
        else {
            $INTERLACE=1;
            }
        }
    elsif ("-rightjustify" =~ /^$_/) {
        $RIGHT_JUSTIFY = shift @ARGV;
        die <<"EOF" unless $RIGHT_JUSTIFY =~ /^\d+$/o;
$prompt Fatal Error: Illegal width for -rightjustify specified: \"$RIGHT_JUSTIFY\"
         Value must be an integer.
EOF
        do {
            $RIGHT_JUSTIFY=0;
            warn <<"EOF";
$prompt Warning: Cannot right-justify because of missing external
         programs. Run configure-pstoimg again and follow the hints.
EOF
            } unless ($PNMFILE && $PBMMAKE && $PNMCAT);
        }
    elsif ("-center" =~ /^$_/) {
        $CENTER = shift @ARGV;
        die <<"EOF" unless $CENTER =~ /^\d+$/o;
$prompt Fatal Error: Illegal width for -center specified: \"$CENTER\"
         Value must be an integer.
EOF
        do {
            $CENTER=0;
            warn <<"EOF";
$prompt Warning: Cannot center image because of missing external
         programs. Run configure-pstoimg again and follow the hints.
EOF
            } unless ($PNMFILE && $PBMMAKE && $PNMCAT);
        }
    elsif ("-topjustify" =~ /^$_/) {
        $TOP_JUSTIFY = shift @ARGV;
        die <<"EOF" unless $TOP_JUSTIFY =~ /^x?[0-9.]+$/io;
$prompt Fatal Error: Illegal align specified: \"$TOP_JUSTIFY\"
         Value must be numeric, optionally preceded by `x'
EOF
        do {
            $TOP_JUSTIFY=0;
            warn <<"EOF";
$prompt Warning: Cannot top-justify because of missing external
         programs. Run configure-pstoimg again and follow the hints.
EOF
            } unless ($PNMFILE && $PBMMAKE && $PNMCAT);
        }
    elsif ("-shoreup" =~ /^$_/) {
        $SHORE_UP = shift @ARGV;
        die <<"EOF" unless $SHORE_UP =~ /^[0-9.]+d?$/;
$prompt Fatal Error: Illegal shore-up specified: \"$SHORE_UP\"
         Value must be numeric, or <num>d
EOF
        do {
            $SHORE_UP=0;
            warn <<"EOF";
$prompt Warning: Cannot shore up image because of missing external
         programs. Run configure-pstoimg again and follow the hints.
EOF
            } unless ($PNMFILE && $PBMMAKE && $PNMCAT);
        }
    else {
        die "$prompt Illegal Argument \"$_\" specified\n";
        }
    }
$FILE = $ARGV[0];
die "$prompt Error: No input file specified\n" unless ($FILE);
$BASE = $FILE;
# remove a trailing suffix and a leading path in shell-like way
$BASE =~ s/\.[^.]*$//;
$BASE =~ s/.*$dd([^$dd]*)$/$1/;
die "$prompt Cannot find file $FILE: $!\n" unless (-f "$FILE");
die "$prompt Error: No output image type specified\n" unless ($IMAGE_TYPE);

if (defined $SCALE) {
    $DENSITY = int($SCALE * $DENSITY + .5)
    } else { $SCALE = 1; }

$aalias = ''; # DEFAULT

if (($AALIAS)&&($GS_DEVICE =~ /p(p|n|g)+mraw/io)) {
    $GS_DEVICE = 'ppmraw';
#    $GS_DEVICE = 'pgnmraw';
    if ($DEPTH == 1) {
        $REDUCE_COLOR= $PPMQUANT . " -floyd 256";
        $aalias = '-dTextAlphaBits=4 ';
    } elsif ($DEPTH == 8) {
        $aalias = '-dTextAlphaBits=4  -dGraphicsAlphaBits=4 ';
    } elsif ($DEPTH == 24) {
        $REDUCE_COLOR="";
        $aalias = '-dTextAlphaBits=4 -dGraphicsAlphaBits=4 ';
    }
} elsif ((!$AALIAS)&&($GS_DEVICE =~ /p(p|n|g)+mraw/io)) {
    if ($DEPTH == 1) {
        $REDUCE_COLOR=$PPMQUANT ." 2 " if ($PPMQUANT);
    } elsif ($DEPTH == 24) {
        $REDUCE_COLOR="";
    }
}


local($DESTDIR);

# LaTeX2HTML may supply a directory: .../tmp/<pid>/
if ($TMP =~ /$dd\w*\d+$dd$/) {
    $BASE =~ s/$TMP//;
    $DESTDIR = &getcwd;
    $DESTDIR .= $dd;
    print STDERR "\ncurrent directory is $DESTDIR ...\n";
    print STDERR "\ntemp directory is $TMP ...\n";
} else { $BASE =~ s/^(${dd}tmp)$dd/$TMP=$1;''/e }

# If l2h already uses a temp dir, the input file is located within it.
$FILE =~ /()/;# clears $`
$FILE =~ /$dd[^$dd]*$/;
$TMP = $` unless $TMP; # get leading path or empty

if (!($TMP)) {
    # l2h uses no temp dir, let's see if we can find one.
    if (-d "${dd}tmp") { $TMP = "${dd}tmp${dd}"}
    elsif (-d "${dd}usr${dd}tmp") { $TMP = "${dd}usr${dd}tmp$dd"}
    else { print "\nCannot find a ${dd}tmp directory, taking this one..." }
} elsif ($TMP =~ /$dd$/) {
} else { $TMP .= $dd }
print "\nUsing $TMP as tmp directory\n" if $DEBUG;


if ($TMP && !($DESTDIR)) {
    open(SO, ">&STDOUT");
    open(STDOUT, ">${TMP}foo$$");
    select(STDOUT); $| = 1;
    system("pwd");
    close(STDOUT);
    open(STDOUT, ">&SO");
    open(FOO,"<${TMP}foo$$");
    $DESTDIR = <FOO>;
    close(FOO);
    unlink "${TMP}foo$$";
    chop $DESTDIR;
    $DESTDIR .= $dd;
    print STDERR "\ncurrent directory is $DESTDIR ...\n" if $DEBUG;
    print STDERR "\ntemp directory is $TMP ...\n" if $DEBUG;
}
select(STDERR); $| = 1;
if (!(($TMP)&&($DESTDIR))) { $TMP = '' }


sub cp {                        # Marcus Hennecke  6/3/96
    local($src, $dest) = @_;
    return unless (-f $src);
    if ( -d $dest ) {
        $src =~ /[^$dd]*$/;
        $dest .= $dd . $&;
        $dest =~ s|$dd$dd||g;
    }
    open(IN, $src) || return; binmode(IN);
    open(OUT, ">$dest") || return; binmode(OUT);
    local($/) = undef;
    print OUT <IN>;
    close(OUT);
    close(IN);
}


# Main program

$outfile = $OUTFILE || "$BASE.$IMAGE_TYPE";
open(STDERR, ">${dd}dev${dd}null") unless $DEBUG;

$gs_input = $FILE;
if (($TMP)&&($DESTDIR)&&(-f "$TMP/$BASE.ps")) {
    print STDERR "...switching to $TMP\n" unless  chdir("$TMP");
    local($extn); if ($FILE =~ /\.(\w+)$/) {$extn = $1};
    $gs_input = "$BASE.$extn";
    undef $extn;
}

# Invoke Ghostscript
&convert;

if (-f "$TMP$BASE.ppm") {
    # switch to a /tmp directory, if there is one and it's not current
    if (($TMP)&&($DESTDIR)) {
       print STDERR "...switching to $TMP\n"
	   unless ((-f "$BASE.ppm")||chdir("$TMP"));
    } else { $TMP = '' }
    &crop_scale_etc("$BASE.ppm", $outfile);
    ++$done if(-s $outfile);
    if ($TMP) {
#	if (system("cp $outfile $DESTDIR$outfile")) {
	if (&cp("$outfile", "$DESTDIR$outfile")) {
	    print "\nOutput image is in file: $TMP$outfile\n";
	} else { unlink "$TMP$outfile" }
#	chdir("$DESTDIR");
    }
} else {
    @list = <$TMP$BASE.[1-9]*.ppm>;
    if($#list >= 0) {
        $done = 1;
        foreach $i (@list) {
            $j = $i;
            $j =~ s/\.(.*)\.ppm/$1.$IMAGE_TYPE/;
            &crop_scale_etc($i, $j);
            $done = $done && -s $j;
        }
    }
    else {
        print "$prompt Couldn't find ppm output of $FILE\n";
    }
}
&cleanup($BASE);

exit(($done) ? 0 : 1 );

sub crop_scale_etc {
    local($in, $out) = @_;
    local($tmp) = $in . ".tmp";
    local($_,$cmd,$type,$width,$height,$just);
    open(STDERR, ">${dd}dev${dd}null") unless $DEBUG;

    if($RIGHT_JUSTIFY || $TOP_JUSTIFY || $CENTER || $EXTRA_CROP || $SHORE_UP) {
        # Crop the image right away
	$cmd = "$PNMCROP < $in ";
	    print "Running $cmd > $tmp\n" if $DEBUG;		# no_pipes
	if (system("$cmd > $tmp")) {
	    &cleanup($BASE);
	    die ("Cropping failed; image too large?")
	}
	rename ($tmp,$in);	                                # no_pipes
	$cmd ="";      					        # no_pipes

        # RRM: Remove justification bars
#	$cmd .= "| $PNMCROP -r | $PNMCROP -l " if($EXTRA_CROP =~ /v/i );
	$EXTRA_CROP =~ s/h/bt/g;
	$EXTRA_CROP =~ s/v/rl/g; 
	while ($EXTRA_CROP) { 
	    $EXTRA_CROP =~ s/^(.)/$edge=$1;''/e;
	    if ($edge =~ /[tblra]/) {
		$edge = "bot" if ($edge =~ /b/);
		$cmd = "$PNMCROP -$edge < $in ";		# no_pipes
		$cmd = "$PNMCROP < $in " if ($edge =~ /a/);	# no_pipes
		print "Running $cmd > $tmp 2>&-\n" if $DEBUG;	# no_pipes
		rename ($tmp,$in) unless system("$cmd > $tmp 2>&-");	# no_pipes
       	    } elsif ($edge =~ /s/) {
		#RRM: shave at most 1 row of white from the bottom
		$cmd = "$PNMCROP -bot < $in ";
                print "Running $cmd > $tmp 2>shave.msg\n" if $DEBUG;
                local($shave) = system("$cmd > $tmp 2>shave.msg");
		if (!$shave) {
		    open (MSG,"<shave.msg");
		    while (<MSG>) {
			last if (/rows off the bottom/);
		    }
		    rename ($tmp,$in) unless (/rows off the bottom/);
		    close (MSG);
		}
		unlink ("shave.msg");
	    }
	    $cmd = "";
	}
#	if ($EXTRA_CROP =~ /v/i ) {
#            $cmd = "$PNMCROP -r < $in ";			# no_pipes
#            print "Running $cmd > $tmp\n" if $DEBUG;		# no_pipes
#            rename ($tmp,$in) unless system("$cmd > $tmp");	# no_pipes
#            $cmd = "$PNMCROP -l < $in ";			# no_pipes
#            print "Running $cmd > $tmp\n" if $DEBUG;		# no_pipes
#            rename ($tmp,$in) unless system("$cmd > $tmp");	# no_pipes
#	    $cmd ="";						# no_pipes
#	}
#        if($EXTRA_CROP =~ /(h|b)/i) {
#	    $cmd .= "| $PNMCROP -bot ";
#		$cmd = "$PNMCROP -bot  < $in ";			# no_pipes
#		print "Running $cmd > $tmp\n" if $DEBUG;	# no_pipes
#		rename ($tmp,$in) unless system("$cmd > $tmp");	# no_pipes
#		$cmd ="";					# no_pipes
#	    $cmd .= "| $PNMCROP -top " if($EXTRA_CROP =~ /h/i );
#	if($EXTRA_CROP =~ /h/i ) {				# no_pipes
#		$cmd = "$PNMCROP -top < $in ";			# no_pipes
#		print "Running $cmd > $tmp\n" if $DEBUG;	# no_pipes
#		rename ($tmp,$in) unless system("$cmd > $tmp");	# no_pipes
#		$cmd ="";					# no_pipes
#        }
#    }
#	$cmd .= "| $PNMFLIP -$GS_UNROTATE " if($GS_ROTATE);
	if($GS_ROTATE) {
	    $cmd = "$PNMFLIP -$GS_UNROTATE  < $in ";		# no_pipes
	    print "Running $cmd > $tmp\n" if $DEBUG;		# no_pipes
	    rename ($tmp,$in) unless system("$cmd > $tmp");	# no_pipes
	    $cmd ="";						# no_pipes
	}
#        $cmd .= "| $PNMFLIP -$FLIP " if $FLIP;
	if($FLIP) {
	    $cmd = "$PNMFLIP -$FLIP  < $in ";		 # no_pipes
	    print "Running $cmd > $tmp\n" if $DEBUG;		# no_pipes
	    rename ($tmp,$in) unless system("$cmd > $tmp");	# no_pipes
	    $cmd ="";						# no_pipes
	}
#	print "Running $cmd > $tmp\n" if $DEBUG;
#	rename ($tmp,$in) unless system("$cmd > $tmp");
        $cmd="";
    } else {
        # Start command pipe
	$cmd = "$PNMCROP < $in ";
	    print "Running $cmd > $tmp\n" if $DEBUG;		# no_pipes
	    rename ($tmp,$in) unless system("$cmd > $tmp");	# no_pipes
	    $cmd ="";						# no_pipes
#        $cmd .= "| $PNMFLIP -$GS_UNROTATE " if($GS_ROTATE);
	if($GS_ROTATE) {
	    $cmd = "$PNMFLIP -$GS_UNROTATE  < $in ";		# no_pipes
	    print "Running $cmd > $tmp\n" if $DEBUG;		# no_pipes
	    rename ($tmp,$in) unless system("$cmd > $tmp");	# no_pipes
	    $cmd ="";						# no_pipes
	}
#        $cmd .= "| $PNMFLIP -$FLIP " if($FLIP);
	if($FLIP) {
	    $cmd = "$PNMFLIP -$FLIP  < $in ";			# no_pipes
	    print "Running $cmd > $tmp\n" if $DEBUG;		# no_pipes
	    rename ($tmp,$in) unless system("$cmd > $tmp");	# no_pipes
	    $cmd ="";						# no_pipes
	}
    }
    # Get bitmap type and dimensions
    $_ = `$PNMFILE $in`;
    s/(P[BGP]M)[^0-9]*(\d+)\s*by\s*(\d+)/$type=$1;$width=$2;$height=$3/eo;
    print "Image is $type, ${width}x$height\n" if $DEBUG;

    if($RIGHT_JUSTIFY || $CENTER) {
        if($RIGHT_JUSTIFY) {
	    $just=int(($RIGHT_JUSTIFY-$width));
        } else { # CENTER
	    $just=int(($CENTER-$width) / 2);
        }
        # Start new command pipe
#        $cmd = "$PBMMAKE -white $just 1 | $PNMCAT -white -lr - $in " if ($just > 0);
	if($just > 0) {
	    local($tmp2) = $tmp.".tmp";				# no_pipes
	    $cmd = "$PBMMAKE -white $just 1  < $in ";		# no_pipes
	    print "Running $cmd > $tmp2\n" if $DEBUG;		# no_pipes
	    system("$cmd > $tmp2");				# no_pipes
	    $cmd = "$PNMCAT -white -lr $tmp2 $in ";		# no_pipes
	    print "Running $cmd > $tmp\n" if $DEBUG;		# no_pipes
	    rename ($tmp,$in) unless system("$cmd > $tmp");	# no_pipes
	    $cmd ="";						# no_pipes
	}
        $width += $just;
    }

    if($TOP_JUSTIFY) {
        if($TOP_JUSTIFY =~ /^x([0-9.]+)/io) {
            $just = $1 * $height;
        } else { $just = $TOP_JUSTIFY - $height }
        $just = int($just + 0.99); # Assumes $adjust is positive!
        if($just > 0) {
            if($cmd) {
                # only if also right-justify is active
                print "Running $cmd > $tmp\n" if $DEBUG;
                rename ($tmp,$in) unless system("$cmd > $tmp");
            }
#	    $cmd="$PBMMAKE -white 1 $just | $PNMCAT -white -tb $in - ";
	    local($tmp2) = $tmp.".tmp";				# no_pipes
	    $cmd = "$PBMMAKE -white 1 $just  < $in ";		# no_pipes
	    print "Running $cmd > $tmp2\n" if $DEBUG;		# no_pipes
	    system("$cmd > $tmp2");				# no_pipes
	    $cmd = "$PNMCAT -white -tb $in $tmp2 ";		# no_pipes
	    print "Running $cmd > $tmp\n" if $DEBUG;		# no_pipes
	    rename ($tmp,$in) unless system("$cmd > $tmp");	# no_pipes
	    $cmd ="";						# no_pipes
	}
	$height += $just;
    }

    if ($SHORE_UP) { # RRM: make height and width an exact multiple of $SHORE_UP
	if ($cmd) {
            print "Running $cmd > $tmp\n" if $DEBUG;
            rename ($tmp,$in) unless system("$cmd > $tmp");
	}
        # We have a correct SHORE_UP value
	local($hextra) = 0;
        $hextra = 1 if ($SHORE_UP =~ s/d//);  # when image needs `depth'
        local($extra) = int(int($height/$SHORE_UP + 0.9)*$SHORE_UP) - $height;
	local($cnt)=0;
	while (int(($height+$extra)/$SHORE_UP) - ($height+$extra)/$SHORE_UP < 0) 
	    { $extra++; $cnt++; last if ($cnt>5) }
        if($extra) {
	    local($tmp2) = $tmp.".tmp";				# no_pipes
	    if ($hextra) {     # place half the extra space underneath
		$hextra = int($extra/2);
		$extra -= $hextra;
#	        $cmd="$PBMMAKE -white 1 $hextra | $PNMCAT -white -tb $in - ";
	        $cmd = "$PBMMAKE -white 1 $hextra  < $in ";	# no_pipes
	        print "Running $cmd > $tmp2\n" if $DEBUG;	# no_pipes
	        system("$cmd > $tmp2");				# no_pipes
	        $cmd = "$PNMCAT -white -tb $in $tmp2 ";		# no_pipes
                print "Running $cmd > $tmp\n" if $DEBUG;
                rename ($tmp,$in) unless system("$cmd > $tmp");
	    }
#	    $cmd="$PBMMAKE -white 1 $extra | $PNMCAT -white -tb - $in ";
	    $cmd = "$PBMMAKE -white 1 $extra  < $in ";		# no_pipes
	    print "Running $cmd > $tmp2\n" if $DEBUG;		# no_pipes
	    system("$cmd > $tmp2");				# no_pipes
	    $cmd = "$PNMCAT -white -tb $tmp2 $in ";		# no_pipes
            print "Running $cmd > $tmp\n" if $DEBUG;
            rename ($tmp,$in) unless system("$cmd > $tmp");
	    $cmd ="";						# no_pipes
        }
        $extra = int(int($width/$SHORE_UP+0.9)*$SHORE_UP) - $width;
        local($cnt)=0;
        while (int(($width+$extra)/$SHORE_UP) - ($width+$extra)/$SHORE_UP < 0)
            { $extra++; $cnt++; last if ($cnt>5) }
        if($extra) {
            local($rextra) = int($extra/2);
            $extra -= $rextra;
            if($extra) {
#		$cmd="$PBMMAKE -white $extra 1 | $PNMCAT -white -lr - $in ";
		local($tmp2) = $tmp.".tmp";			# no_pipes
		$cmd = "$PBMMAKE -white $extra 1  < $in ";	# no_pipes
		print "Running $cmd > $tmp2\n" if $DEBUG;	# no_pipes
		system("$cmd > $tmp2");				# no_pipes
		$cmd = "$PNMCAT -white -lr $tmp2 $in ";		# no_pipes
                print "Running $cmd > $tmp\n" if $DEBUG;
                rename ($tmp,$in) unless system("$cmd > $tmp");
		$cmd ="";					# no_pipes
	    }
            if($rextra) {
#		$cmd="$PBMMAKE -white $rextra 1 | $PNMCAT -white -lr $in - ";
		local($tmp2) = $tmp.".tmp";			# no_pipes
		$cmd = "$PBMMAKE -white $rextra 1  < $in ";	# no_pipes
		print "Running $cmd > $tmp2\n" if $DEBUG;	# no_pipes
		system("$cmd > $tmp2");				# no_pipes
		$cmd = "$PNMCAT -white -lr $in $tmp2 ";		# no_pipes
                print "Running $cmd > $tmp\n" if $DEBUG;
                rename ($tmp,$in) unless system("$cmd > $tmp");
		$cmd ="";					# no_pipes
	    }
	}
        $cmd = '';
    }

    if($IMAGE_TYPE eq "gif") { $PNMTOIMG = $PPMTOGIF; }
    if($IMAGE_TYPE eq "png") { $PNMTOIMG = $PNMTOPNG; }

    if($INTERLACE) { # use netpbm if possible
        do {
            $PNMTOIMG .= " -interlace" unless ($height < 8);
            $INTERLACE=0;
	} unless ($IMAGE_TYPE eq "gif" && 
                $HOWTO_INTERLACE_GIF !~ /netpbm/io);
    }
    if($TRANSPARENT) { # use netpbm if possible
        do {
            $PNMTOIMG .= " -trans '#ffffff'";
            $TRANSPARENT=0;
	} unless ($IMAGE_TYPE eq "gif" &&
                $HOWTO_TRANSPARENT_GIF !~ /netpbm/io);
    }
    # run ppmquant only on color/gray images
    if($cmd) {
	# This shouldn't happen without pipes		# no_pipes
        $cmd .= "| $REDUCE_COLOR "
	    if(($type =~ /(ppm|pgm)/io)&&($REDUCE_COLOR));
        $cmd .= "| $PNMTOIMG ";
	$cmd ="";					# no_pipes
    } elsif (( $type =~ /(ppm|pgm)/io)&&($REDUCE_COLOR)) {
#	$cmd = "$REDUCE_COLOR < $in | $PNMTOIMG ";
	$cmd = "$REDUCE_COLOR < $in ";		# no_pipes
	print "Running $cmd > $tmp\n" if $DEBUG;
	rename ($tmp,$in) unless system("$cmd > $tmp");
	$cmd ="$PNMTOIMG < $in ";			# no_pipes
    } else {
	$cmd = "$PNMTOIMG < $in ";
    }
    print "Running $cmd > $out\n" if $DEBUG;
    if(system("$cmd > $out")) {
        print "$prompt Conversion failed: $!\n";
        unlink $out unless $DEBUG;
    } else {
        print "Writing $out\n";
        if($IMAGE_TYPE =~ /^gif/ &&
            $INTERLACE && $HOWTO_INTERLACE_GIF =~ /giftool/i) {
	    $cmd = "$GIFTOOL -B -i ";
            if($TRANSPARENT) {
                $cmd .= "-rgb ff,ff,ff ";
                $TRANSPARENT = 0;
	    }
            print "Running $cmd $out\n" if $DEBUG;
            system("$cmd $out");
	}
        if($IMAGE_TYPE =~ /^gif/ && $TRANSPARENT) {
            if($HOWTO_TRANSPARENT_GIF =~ /giftrans/i) {
		print "Running $GIFTRANS -t '#ffffff' -B '#bfbfbf' $out > $tmp\n" if $DEBUG;
		rename($tmp,$out) unless system("$GIFTRANS -t '#ffffff' -B '#bfbfbf' $out > $tmp");
	    } elsif ($HOWTO_TRANSPARENT_GIF =~ /giftool/i) {
		print "Running $GIFTOOL -B -rgb ff,ff,ff $out > $tmp\n" if $DEBUG;
		rename($tmp,$out) unless system("$GIFTOOL -B rgb ff,ff,ff $out > $tmp");
	    }
	}
    }
    unlink $tmp unless $DEBUG;
}

sub convert {
    local($size) = ($PAPERSIZE) ? "-sPAPERSIZE=$PAPERSIZE" : "";
    local($density) = ($DENSITY != 72) ? "-r$DENSITY" : "";
    local($bbx, $bby, $bbw, $bbh) = (0,0,0,0);
    local($max_lines) = 30;
    local($epsf,$have_geometry) = (0,0);

    # Parse postscript file for information
    open (PS, "$gs_input");
    $_ = <PS>;
    if ( /^%!.*EPSF/ ) {
        # we're in a EPSF file
        $epsf = 1;
    }
 
    if ($GEOMETRY || $epsf) {
        while (<PS>) {
            # Look for bounding box comment
            if ($epsf == 1 &&
                /^%%BoundingBox:\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)/) {
                $bbx = 0 - $1;    $bby = 0 - $2;
                $bbw = $3 + $bbx; $bbh = $4 + $bby;
                if(($bbw > 0) && ($bbh > 0)) { # we have a valid bounding box
                    print "$prompt EPSF dimensions are ${bbw}x$bbh\n" if $DEBUG;
                    # this overrides the -geometry switch
                    if ( $DENSITY ) { # scale the output
                        local($scale) = $DENSITY/72;
                        $bbw = int($bbw * $scale + 0.99);
                        $bbh = int($bbh * $scale + 0.99);
		    }
                    $size = "-g${bbw}x${bbh}";
                    $have_geometry = 1;
                    last;
		} else {  # i.e. when dvips gives an empty box
		    $epsf = 2; # don't look for EPSF stuff any further
		}
	    }
            # Look for page size information
            elsif ($GEOMETRY && /TeXDict\s+begin\s+(\d+)\s+(\d+)\s+/) {
                $PAGE_WIDTH  = int($1 / 65536*72/72.27 +.5);
                $PAGE_HEIGHT = int($2 / 65536*72/72.27 +.5);
                print "$prompt Page dimensions are ${PAGE_WIDTH}x$PAGE_HEIGHT\n" if $DEBUG;
                # we don't have to look further for EPSF stuff at this point
                last;
	    } elsif (!$GEOMETRY && (/^%%EndComments/ || --$max_lines == 0)) {
		last;
	    }
	}
    }
    close PS;
    if ($GEOMETRY && !$have_geometry) { # RRM: overrides  $PAPERSIZE 
	$have_geometry = 1;
	$bbx = $PAGE_HMARGIN;
	$bby = $PAGE_HEIGHT - $PAGE_VMARGIN;
	$GEOMETRY =~ /\s*([0-9.]+)x([0-9.]+)/;
	$bbw = $1 + 10;  # allow for the side-bars
	$bbh = $2;
	$bby = int($bbh - $bby + 8); # allow small margin for error
	$bbx = int(-$bbx + 5);       # allow small margin for error
	if ( $DENSITY ) {
            local($scale) = $DENSITY/72;
            $bbw = int($scale * $bbw + .99);
            $bbh = int($scale * $bbh + .99);
            }
	$bbw += 10;  # add a 5pt margin for safety
	$bbh += 40;  # add a 20pt margin for safety
	$GEOMETRY = $bbw . "x" . $bbh;
        # use this if -g option works properly...
	$size = "-g$GEOMETRY ";
        # RRM: use these next lines if -g option is broken
        # $size = "-sPAPERSIZE=". &choose_paper($GEOMETRY);
	# $have_geometry = 0;
    }
    if ($have_geometry) {
	# Remove any Postscript commands concerning Papersize if -g switch is used
	# thanks to  Axel Ramge for identifying the problem and for this code
	$* = 1;    # Multiline matching ON
	$saveRS = $/; undef $/;
	open(PS,"<$gs_input");
	$_ = <PS>;
	local($change) = s/\n%%BeginPaperSize.*%%EndPaperSize.*?\n//s;
	close(PS);
	if ($change) {
	    open(PS,">$gs_input");
	    do {
		close(PS); $* = 0; $/ = $saveRS;
		die "\n\n***file $gs_input  contains %%Papersize comments"
		    . "\nany contents of these must be removed else GS will fail.\n";
	    } unless print PS;
	    close(PS);
	}
	$/ = $saveRS; $* = 0;    # Multiline matching OFF
    }
    if ($WHITE) {
	$* = 1;    # Multiline matching ON
	$saveRS = $/; undef $/;
	open(PS,"<$gs_input");
	$_ = <PS>;
	local($change) = s/(\n1 0 bop gsave) .85( TeXcolorgray clippath fill grestore)/$1 1$2/s;
	close(PS);
	if ($change) {
	    open(PS,">$gs_input");
	    do {
		close(PS); $* = 0; $/ = $saveRS;
		die "\n\n*** image $outfile may have gray background, change to white failed\n"
	    } unless print PS;
	    close(PS);
	}
	$/ = $saveRS; $* = 0;    # Multiline matching OFF
    }

    local($basename) = $BASE . ($MULTIPLEPAGES ? ".%d" : '');
    local($quiet) = "-q -dNOPAUSE -dNO_PAUSE ";
    local($outfile) = "-sOutputFile=$basename.ppm";

    if ( $DEBUG ) {
        print "Running $GS $quiet -sDEVICE=$GS_DEVICE $size $density $aalias $outfile\n";
        print "GS>$GSROTATE " if ($GSROTATE);
        print "GS>$bbx $bby translate\n" if ($have_geometry);
        print "GS>($gs_input) run\n";
        print "GS>showpage\n" if ($epsf);
        print "GS>quit\n";
    }
    open (GS, "|$GS $quiet -sDEVICE=$GS_DEVICE $size $density $aalias $outfile");
    print GS "$GSROTATE " if ($GSROTATE);
    print GS "$bbx $bby translate " if ($have_geometry);
    print GS "($gs_input) run ";
    print GS "showpage " if ($epsf);
    print GS "quit\n";
    close GS;
    print "\n";
}

sub choose_paper {
    local($_) = @_;
    local($size, $height, $width) = ('','','');
    s/^(\d*)\s*x\s*(\d*)$/$width=$1;$height=$2/eo;
    if ($width > $height) { 
        $GSROTATE= "($GSLANDSCAPE) run ";
        ($width, $height) = ($height, $width);
        }
    else { $GSROTATE=''; }
    if (($width < 74)&&($height < 105)) { $size = "a10" }
    elsif (($width < 105)&&($height < 148)) { $size = "a9" }
    elsif (($width < 148)&&($height < 210)) { $size = "a8" }
    elsif (($width < 210)&&($height < 297)) { $size = "a7" }
    elsif (($width < 297)&&($height < 421)) { $size = "a6" }
    elsif (($width < 421)&&($height < 595)) { $size = "a5" }
    elsif (($width < 501)&&($height < 709)) { $size = "b5" }
    elsif (($width < 595)&&($height < 842)) { $size = "a4" }
    elsif (($width < 709)&&($height < 1002)) { $size = "b4" }
    elsif (($width < 842)&&($height < 1190)) { $size = "a3" }
    elsif (($width < 1002)&&($height < 1418)) { $size = "b3" }
    elsif (($width < 1190)&&($height < 1684)) { $size = "a2" }
    elsif (($width < 1418)&&($height < 2004)) { $size = "b2" }
    elsif (($width < 1684)&&($height < 2380)) { $size = "a1" }
    elsif (($width < 2004)&&($height < 2836)) { $size = "b1" }
    elsif (($width < 2380)&&($height < 3368)) { $size = "a0" }
    else { $size = "b0" }
    $size;
}
  
sub cleanup {
    unlink <$BASE[0-9.]*ppm> unless $DEBUG;
    unlink <$BASE[0-9.]*ppm.tmp> unless $DEBUG;
    unlink <$BASE[0-9.]*ppm.tmp.tmp> unless $DEBUG;
    chdir("$DESTDIR") if ($TMP);
    unlink "$FILE" if ($DISCARD && (!$DEBUG));
}

sub usage {
    print <<"EOF";
This is pstoimg V98.1. Accompanies LaTeX2HTML V98.1.

Usage: pstoimg [-help] [-debug] [-gif|-png] [-out <output file>] [-multipage]
               [-color <color depth 1, 8 or 24>] [-depth <color depth 1, 8 or 24>] 
	       [-density <pixel density>] [-geometry <width>x<height>] 
               [-discard] [-transparent] [-interlaced] [-antialias]
               [-rightjustify <width>] [-topjustify <align>] [-center <width>]
               [-flip <Flip_code>] [-crop <code>] [-shoreup <pixel>]
               <file.(e)ps>
       The options may be abbreviated to the shortest unique prefix.
EOF
    print "       This version can create the following image format(s): ";
    print "GIF " if( $PPMTOGIF );
    print "PNG " if( $PNMTOPNG );
    print "\n";
    }

