#!/opt/perl-5.6.0/bin/perl

eval 'exec /opt/perl-5.6.0/bin/perl  -S $0 ${1+"$@"}'
    if 0; # not running under some shell

my $RCS_Id = '$Id: eps2png.pl,v 1.8 2000-07-11 19:04:40+02 jv Exp $ ';

# Author          : Johan Vromans
# Created On      : Tue Sep 15 15:59:04 1992
# Last Modified By: Johan Vromans
# Last Modified On: Tue Jul 11 19:04:01 2000
# Update Count    : 104
# Status          : Unknown, Use with caution!

################ Common stuff ################

use strict;
use Getopt::Long 2.1;

my $my_package = "Sciurix";
my ($my_name, $my_version) = $RCS_Id =~ /: (.+).pl,v ([\d.]+)/;
$my_version .= '*' if length('$Locker:  $ ') > 12;

################ Program parameters ################

### CONFIG
# Some GhostScript programs can produce GIF directly.
# If not, we need the PBM package for the conversion.
my $use_pbm = 1;		# GhostScript can not produce GIF
### END CONFIG

my $res = 82;			# default resolution
my $scale = 1;			# default scaling
my $mono = 0;			# produce BW images if non-zero
my $format;			# output format
my $gs_format;			# GS output type
my $output;			# output, defaults to STDOUT

my ($verbose,$trace,$test,$debug) = (0,0,0,0);
handle_options ();
unless ( defined $format ) {
    if ( $0 =~ /2(gif|jpg|png)$/ ) {
	set_out_type ($1);
    }
    else {
	set_out_type ('png') unless defined $format;
    }
}
print STDERR ("Producing $format ($gs_format) image.\n") if $verbose;

$trace |= $test | $debug;
$verbose |= $trace;

################ Presets ################

################ The Process ################

my $eps_file;
my $err = 0;

foreach $eps_file ( @ARGV ) {

    unless ( open (EPS, $eps_file) ) {
	print STDERR ("Cannot open $eps_file [$!], skipped\n");
	$err++;
	next;
    }

    my $line = <EPS>;
    unless ( $line =~ /^%!PS-Adobe.*EPSF-/ ) {
	print STDERR ("Not EPS file: $eps_file, skipped\n");
	$err++;
	next;
    }

    my $width;			# actual width
    my $height;			# actual height
    my $ps;			# PostScript input data

    while ( $line = <EPS> ) {

	# Search for BoundingBox.
	if ( $line =~ /^%%BoundingBox:\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/i ) {

	    # Create PostScript code to translate coordinates.
	    $ps = ($scale == 1 ? "" : "$scale $scale scale\n").
	      (0-$1) . " " . (0-$2) . " translate\n".
		"($eps_file) run\n".
		  "showpage\n".
		    "quit\n";

	    # Calculate actual width.
	    $width  = $3 - $1;
	    $height = $4 - $2;
	    print STDERR ("$eps_file: x0=$1, y0=$2, w=$width, h=$height")
		if $verbose;
	    # Normal PostScript resolution is 72.
	    $width  *= $res/72 * $scale;
	    $height *= $res/72 * $scale;
	    # Round up.
	    $width  = int ($width + 0.5) + 1;
	    $height = int ($height + 0.5) + 1;
	    print STDERR (", width=$width, height=$height\n") if $verbose;
	    last;
	}
	elsif ( $line =~ /^%%EndComments/i ) {
	    print STDERR ("No bounding box in $eps_file\n");
	    $err++;
	    last;
	}
    }
    close (EPS);

    my $out_file;		# output file
    my $pbm_file;		# temporary file for PBM conversion

    # Note the temporary PBM file is created where the output file is
    # located, since that will guarantee accessibility (and a valid
    # filename).
    if ( defined $output ) {
	$out_file = $output;
	$pbm_file = $output.".ppm";
    }
    elsif ( $eps_file =~ /^(.+).epsf?$/i ) {
	$out_file = "$1.$format";
	$pbm_file = $1.".ppm";
    }
    else {
	$out_file = $eps_file . ".$format";
	$pbm_file = $eps_file . ".ppm";
    }
    print STDERR ("Creating $out_file\n") if $verbose;

    my $gs0 = "gs -q -dNOPAUSE -r$res -g${width}x$height";
    my $gs1 = "-";
    if ( $format eq 'png' ) {
	mysystem ("$gs0 -sDEVICE=". ($mono ? "pngmono" : $gs_format).
		  " -sOutputFile=$out_file $gs1", $ps);
    }
    elsif ( $format eq 'jpg' ) {
	mysystem ("$gs0 -sDEVICE=". ($mono ? "jpeggray" : $gs_format).
		  " -sOutputFile=$out_file $gs1", $ps);
    }
    elsif ( $format eq 'gif' ) {
	if ( $use_pbm ) {
	    # Convert to PPM and use some of the PBM converters.
	    mysystem ("$gs0 -sDEVICE=". ($mono ? "pbm" : "ppm").
		      " -sOutputFile=$pbm_file $gs1", $ps);
	    # mysystem ("pnmcrop $pbm_file | ppmtogif > $out_file");
	    mysystem ("ppmtogif $pbm_file > $out_file");
	    unlink ($pbm_file);
	}
	else {
	    # GhostScript has GIF drivers built-in.
	    mysystem ("$gs0 -sDEVICE=". ($mono ? "gifmono" : "gif8").
		      " -sOutputFile=$out_file $gs1", $ps);
	}
    }
    else {
	print STDERR ("ASSERT ERROR: Unhandled output type: $format\n");
	exit (1);
    }

    unless ( -s $out_file ) {
	print STDERR ("Problem creating $out_file for $eps_file\n");
	$err++;
    }
}

exit ( $err ? 1 : 0 );

################ Subroutines ################

sub mysystem {
    my ($cmd, $data) = @_;
    print STDERR ("+ $cmd\n") if $trace;
    if ( $data ) {
	if ( $trace ) {
	    my $dp = ">> " . $data;
	    $dp =~ s/\n(.)/\n>> $1/g;
	    print STDERR ("$dp");
	}
	open (CMD, "|$cmd") or die ("cmd: $!\n");
	print CMD $data;
	close CMD or die ("cmd close: $!\n");
    }
    else {
	system ($cmd);
    }
}

sub set_out_type {
    my ($opt) = lc (shift (@_));
    if ( $opt =~ /^png(mono|gray|16|256|16m)?$/ ) {
	$format = 'png';
	$gs_format = $format.(defined $1 ? $1 : '16m');
    }
    elsif ( $opt =~ /^gif(mono)?$/ ) {
	$format = 'gif';
	$gs_format = $format.(defined $1 ? $1 : '');
    }
    elsif ( $opt =~ /^(jpg|jpeg)(gray)?$/ ) {
	$format = 'jpg';
	$gs_format = 'jpeg'.(defined $2 ? $2 : '');
    }
    else {
	print STDERR ("ASSERT ERROR: Invalid value to set_out_type: $opt\n");
	exit (1);
    }
}

sub handle_options {
    my  ($help) = 0;		# handled locally
    my ($ident) = 0;		# handled locally

    # Process options.
    if ( @ARGV > 0 && $ARGV[0] =~ /^[-+]/ ) {
	usage () 
	  unless GetOptions ('ident'     => \$ident,
			     'verbose'   => \$verbose,
			     'scale=f'   => \$scale,
			     'output=s'  => \$output,
			     'png'       => \&set_out_type,
			     'pngmono'   => \&set_out_type,
			     'pnggray'   => \&set_out_type,
			     'png16'     => \&set_out_type,
			     'png256'    => \&set_out_type,
			     'png16m'    => \&set_out_type,
			     'jpg'       => \&set_out_type,
			     'jpggray'   => \&set_out_type,
			     'jpeg'      => \&set_out_type,
			     'jpeggray'  => \&set_out_type,
			     'gif'       => \&set_out_type,
			     'gifmono'   => \&set_out_type,
			     'mono!'     => \$mono,
			     'res=i'     => \$res,
			     'pbm!'      => \$use_pbm,
			     'trace'     => \$trace,
			     'help'      => \$help,
			     'debug'     => \$debug)
		&& !$help;
    }
    print STDERR ("This is $my_package [$my_name $my_version]\n")
	if $ident;
    usage () unless @ARGV;
    usage () if @ARGV > 1 && defined $output;
}

sub usage {
    print STDERR <<EndOfUsage;
This is $my_package [$my_name $my_version]
Usage: $0 [options] file [...]

    -png -pngmono -pnggray -png16 -png256 -png16m
                        produce PNG image
    -jpg -jpggray -jpeg -jpeggray
                        produce JPG image
    -gif -gifmono       produce GIF image
    -[no]mono		monochrome/colour rendition
    -res XXX		resolution (default = $res)
    -scale XXX		scaling factor
    -[no]pbm		GIF only: [do not] convert via pbm format
    -output XXX		output to this file (only one input file)
    -help		this message
    -ident		show identification
    -verbose		verbose information
EndOfUsage
    exit 1;
}
__END__

=pod

=head1 NAME

epf2png - convert EPS files to PNG, JPG or GIF images

=head1 SYNOPSIS

    eps2png [ options ] files ...
    eps2gif [ options ] files ...
    eps2jpg [ options ] files ...

=head1 DESCRIPTION

Converts files from EPS format (Encapsulated PostScript) to some
popular image formats.

If installed as C<eps2png> (the default), it produces PNG images by
default. Likewise, C<eps2gif> defaults to GIF images and C<eps2jpg>
defaults to JPG. Note that the normal installation procedure will
I<only> install C<eps2png>.

It uses GhostScript to produce the images. Since modern GhostScript
programs do not support GIF anymore, GIF images are produced via the
Portable PixMap converters (PBM-package). In this case, a temporary
file is created, named after the output file, with the extension
replaced by ".ppm". It is deleted upon completion.

=head1 ARGUMENTS

    -png -pngmono -pnggray -png16 -png256 -png16m
                        produce PNG image
    -jpg -jpggray -jpeg -jpeggray
                        produce JPG image
    -gif -gifmono       produce GIF image
    -[no]mono		monochrome/colour rendition
    -res XXX		resolution (default = 82)
    -scale XXX		scaling factor
    -[no]pbm		GIF only: [do not] convert via pbm format
    -output XXX		output to this file (only one input file)
    -help		this message
    -ident		show identification
    -verbose		verbose information


=head1 AUTHOR

Johan Vromans, E<lt>jvromans@squirrel.nlE<gt>.

=head1 BUGS

GhostScript and, if required, the PBM package, need to be installed and
accessible through the user's C<PATH>.

GhostScript is assumed to be capable of handling all the image types
listed above.

=head1 COPYRIGHT AND DISCLAIMER

This program is Copyright 1994,2000 by Johan Vromans.
This program is free software; you can redistribute it and/or
modify it under the terms of the Perl Artistic License or the
GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

If you do not have a copy of the GNU General Public License write to
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
MA 02139, USA.

=cut
