#!/usr/local/bin/perl 
##############################################################################
$VERSION='gif2html.pl v1.25';   # 22 April 1997 Dale Bewley <dale@bewley.net>
#$VERSION='gif2html.pl v1.11';   # 4 Dec. 1996 Dale Bewley <dlbewley@iupui.edu>
#$VERSION='gif2html.pl v1.1';   # 24 Oct. 1996 Dale Bewley <dlbewley@iupui.edu>
# v1.0 Oct. 96, v1.0b4 25 July 96, v.99 12 June 96, v.09 26 Sept. 95
#-----------------------------------------------------------------------------
#
# This script and others found at http://www.bewley.net/perl/
#
# Creates an html file for each graphic in a directory. Useful for creating
# a slide show. See slideshow.pl on my perl page above.
#
# See POD at bottom of file for instructions.
#
#
# Copyright (C) 1995, 1996, 1997 Dale Bewley <dale@bewley.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
##############################################################################

#- User Configurable Variables ----------------------------------------------#
#$BACKGROUND   = "http://www.iupui.edu/home/Graphics/emboss.gif";
$CAPTION_FILE  = ".gif2html.cap";   # default file of captions 
$TEMPLATE_FILE = ".gif2html.tmp";   # default HTML template in current dir
$BASEREF       = "./";              # to prefix IMG SRC's
#----------------------------------------------------------------------------#

#- Help! --------------------------------------------------------------------#
sub help {
	# help a lost soul
	print <<E_O_HELP;
$VERSION Dale Bewley <dale\@bewley.net>
http://www.bewley.net/perl/gif2html.pl.html

Description: This script will create an HTML file for each of a batch of
	graphics.

Usage: $0 [<options>] <filespec>

Options:

	-b                 Baseref for all URLs in output.
	-g                 Background for output files (unused)
	-c .gif2html.cap   Use this file for caption mappings. 
	-h                 This message.
	-t .gif2html.tmp   Use this template file.
	-v                 Verbose.

Filespec:
	Any pattern that names your graphics, i.e.
	luther.gif *.gif *.jpg * *.* 

Example:
	$0 -c captions.txt -v *.gif *.jpg

E_O_HELP
	1;
}
#----------------------------------------------------------------------------#


#- Main Program -------------------------------------------------------------#
use vars qw($BACKGROUND $CAPTION_FILE $TEMPLATE_FILE $BASE_REF $opt_h);
# many problems with pod2usage unfortunately. May have to dump it.
#use Pod::Usage;

# If you have Image::Size installed uncomment this
#use Image::Size 'html_imgsize'; # see CPAN/modules/by-module/Image/
require('getopt.pl') || print STDERR "Waring! get getopt.pl\n";

&getOpts;                                  # get commandline options

# either this line or the pod2usage line below...
if ((!$ARGV[0]) || ($opt_h)) { &help && exit; }    # give help and exit

# why all these use Strict-ish errors?!
if ((!$ARGV[0]) || ($opt_h)) { pod2usage(); }    # give help and exit
#pod2usage({EXIT => 0, VERBOSE => 2})  if ($opt_h); # gives lots of help and exit

@gfxFiles = @ARGV;                         # queue up the gfx
print STDERR scalar(@gfxFiles), " gfx to process\n" if ($opt_v); 

@TEMPLATE = &readTemplate($TEMPLATE_FILE); # read html template

my %CAPTIONS;
&readCaptions($CAPTION_FILE,\%CAPTIONS);  # read gfx captions 

foreach (@gfxFiles) { &writeFile($_,@TEMPLATE); } # write the html files
#----------------------------------------------------------------------------#


#- Get Command Line Opts ----------------------------------------------------#
sub getOpts {
	&Getopt('cbgt'); # these options accept commandline values
	$BASEREF       = $opt_b if ($opt_b);
	$CAPTION_FILE  = $opt_c if ($opt_c);
	$BACKGROUND    = $opt_g if ($opt_g); # unused!
	$TEMPLATE_FILE = $opt_t if ($opt_t);
}
#----------------------------------------------------------------------------#


#- Read HTML Template -------------------------------------------------------#
sub readTemplate {
	# get html template to put graphics into.
	local($template) = shift @_;
	local(@template);

	if (open(TEMPLATE, "$template")) {
		print STDERR "reading template file: $template\n" if ($opt_v);

		@template = <TEMPLATE>;				# read template into an array
	} else { 
		print STDERR "Template file $template not found.\n";
		print STDERR "Using default builtin template.\n";
		@template = <<E_O_TEMPLATE;
<HTML>
<HEAD><TITLE><S-INSERT TITLE></TITLE>
<!-- This file created by gif2html.pl by Dale Bewley dale\@bewley.net
	http://www.bewley.net/perl/ -->
</HEAD>
<BODY>
<center>
	<HR width=80%>
<TABLE border=1>
<TR> 
	<TD><IMG SRC=""></TD></TR>
</TABLE>
	<HR width=80%>
<H3><S-INSERT CAPTION></H3>
</center>
</BODY>
</HTML>
E_O_TEMPLATE
	}

return @template;
}
#----------------------------------------------------------------------------#


#- Read Image Captions ------------------------------------------------------#
sub readCaptions {
    my $capFile = shift;
    my $captions = shift; # is a ref to hash
    my $old_rs = $/;
    $/ = "\n\n";

    if (open(CAPTIONS, "$capFile")) {
	print STDERR "reading captions file: $capFile\n" if ($opt_v);
	while (chop($_ = <CAPTIONS>)) {
	    s/^\s*//; 	# remove begining white space
	    ($filename, $caption) = split(/\s*\|\s*/);
	    $captions->{$filename} = $caption;
	}
    } else { 
	print STDERR "Caption file $capFile not found.\n";
	print STDERR "Using converted filenames as caption.\n";
    }
    # now %$captions contains (file1.gif -> caption, file2.gif -> caption2)
    $/ = $old_rs;
}
#----------------------------------------------------------------------------#


#- Write the HTML Out -------------------------------------------------------#
sub writeFile {
    # Create html file from graphic and template
    $gfxFile = shift(@_);
    local(@TEMPLATE) = @_;
    
    open (FILE,">$gfxFile.html") || die "Can't open > $gfxFile.html $!";
    print STDERR "creating file $gfxFile.html\n" if ($opt_v);
    
    # Create title with spaces in place or dashes and without an extension.
    $picTitle = $gfxFile;
    $picTitle =~ s/\.[^.]*$//ig; # remove file extension 
    $picTitle =~ s/-|_/ /g; # replace - and _ with a space for default title

    foreach (@TEMPLATE) {
	# insert title and images
	s!<\s*S-INSERT\s+TITLE\s*>!$picTitle!ig;
	s!<\s*IMG\s+SRC\s*=\s*["|']*\s*>!"<IMG SRC=\"$BASEREF$gfxFile\" " . 
	    hwTags($gfxFile) . ">"!ige; 

        # below only works with Image::Size
#	s!<\s*IMG\s+SRC\s*=\s*["|']*\s*>!"<IMG SRC=\"$BASEREF$gfxFile\" " . 
#	    html_imgsize($gfxFile) . ">"!ige; 

	# insert caption from cap file or default of converted filename
	if (m#\<\s*S-INSERT\s+CAPTION\s*>#i) {
	    if ($CAPTIONS{$gfxFile}) {
		s#\<\s*S-INSERT\s+CAPTION\s*>#$CAPTIONS{$gfxFile}#ig;
	    } else {
		s#\<\s*S-INSERT\s+CAPTION\s*>#$picTitle#ig;
	    }
	}

	print FILE;
    }
}
#----------------------------------------------------------------------------#


#----------------------------------------------------------------------------#
sub hwTags {
	my ($file) = @_ ;
	open(GRAPHIC, "$file") || die "Can't open graphic $file $!";
	binmode(GRAPHIC); # necessary for non UNIX perl. just leave it.

	if ($file =~ /\.gif$/i) {
		$tags = &gifSize(GRAPHIC);
	} elsif ($file =~ /\.jpg$|.jpeg$/i) {
		$tags =  &jpegSize(GRAPHIC);
	} 

	close (GRAPHIC);
	return $tags;
}
#----------------------------------------------------------------------------#


#- Size Gifs ----------------------------------------------------------------#
sub gifSize {
	# return a string of height and width tags for a gif.
	# this code "adapted" from:
	# http://rajiv.org/programming/gifsize.txt

	my ($GIF) = @_;
	my ($w, $w2, $h, $h2, $gifwidth, $gifsize, $type) = () ;

	read ($GIF, $type, 3);
	seek ($GIF, 6, 0); 
	read ($GIF, $w, 1);
	read ($GIF, $w2, 1);
	read ($GIF, $h,  1); 
	read ($GIF, $h2, 1);

	$width  = ord ($w) + ord ($w2) * 256;
	$height = ord ($h) + ord ($h2) * 256;
	return ("WIDTH=\"$width\" HEIGHT=\"$height\"");
}
#----------------------------------------------------------------------------#


#----------------------------------------------------------------------------#
# jpegsize : gets the width and height (in pixels) of a jpeg file
# Andrew Tong, werdna@ugcs.caltech.edu           February 14, 1995
# modified slightly by alex@ed.ac.uk
sub jpegSize {
  my ($JPEG) = @_;
  my ($done) = 0;
  my ($size) = "";

  read($JPEG, $c1, 1); read($JPEG, $c2, 1);
  if( !((ord($c1) == 0xFF) && (ord($c2) == 0xD8))){
    print "This is not a JPEG!";
    $done=1;
  }
  while (ord($ch) != 0xDA && !$done) {
    # Find next marker (JPEG markers begin with 0xFF)
    # This can hang the program!!
    while (ord($ch) != 0xFF) {  read($JPEG, $ch, 1); }
    # JPEG markers can be padded with unlimited 0xFF's
    while (ord($ch) == 0xFF) { read($JPEG, $ch, 1); }
    # Now, $ch contains the value of the marker.
    if ((ord($ch) >= 0xC0) && (ord($ch) <= 0xC3)) {
      read ($JPEG, $junk, 3); read($JPEG, $s, 4);
      ($a,$b,$c,$d)=unpack("C"x4,$s);
      $size=join("", 'HEIGHT=',$a<<8|$b,' WIDTH=',$c<<8|$d );
      $done=1;
    } else {
      # We **MUST** skip variables, since FF's within variable names are
      # NOT valid JPEG markers
      read ($JPEG, $s, 2); 
      ($c1, $c2) = unpack("C"x2,$s); 
      $length = $c1<<8|$c2;
      if( ($length < 2) ){
        print "Erroneous JPEG marker length";
        $done=1;
      } else {
        read($JPEG, $junk, $length-2);
      }
    }
  }
  return $size;
}
#----------------------------------------------------------------------------#

# Documentation. Extract to html with 'pod2html gif2html.pl' 
# Extract to man page with 'pod2man gif2html.pl'

__END__



=head1 NAME

B<gif2html.pl> - create html files for images with caption and height width 
tags

v1.25 - http://www.bewley.net/perl/gif2html.pl

=head1 SYNOPSIS

gif2html.pl [ C<-h> ] | [ C<-v> ] [ C<-c> F<captions file> ] 
[ C<-t> F<template file> ] [ C<-b> F<baseref> ] F<filenames>

Example:
    gif2html.pl -v -t template.html *.gif *.jpg

Sample Output:
    http://www.bewley.net/vacation/sf-alcatraz1.jpg.html

=head1 DESCRIPTION


Use gif2html.pl in batch jobs. It takes a butt load of graphics and creates 
an html file for each one, giving you complete control over the html. Simply 
create an html C<Template> with an empty <img src=> in it. Gif2html.pl will 
copy the template for each image and fill in each <img src=> with the 
appropriate URL and width/height tags. It will also include unique C<Captions> 
for each image. 

Tested with UNIX of course and also Win95 Perl5.001m b107

Give your graphics descriptive names. Use full words seperated by
a '-'. Dashes will be converted to spaces and possibly placed in the 
title depending on your template. Better yet, use the captions.

=head2 What's New

Can make use of the Image::Size module. The advantage is width and height
tags can be generated for many more formats than just gif or jpeg.
See your nearest L< CPAN / http://www.ind.net/pub/mirrors/CPAN/ > node.

=head2 B<Template> support

You have complete control over how the image will be presented. Create an html file like so: 


        <HTML>
        <HEAD><TITLE><S-INSERT TITLE></TITLE>
        <!-- This file created by gif2html.pl by Dale Bewley dlbewley@iupui.edu
                http://www.bewley.net/perl/ -->
        </HEAD>
        <BODY>
        <center>
                <HR width=80%>
        <TABLE border=1>
        <TR> 
        <TD><IMG SRC=""></TD></TR>
        </TABLE>
                <HR width=80%>
        <H3><S-INSERT CAPTION></H3>
        </center>
        </BODY>
        </HTML>


This template will be copied for each image to a file having the same name as 
the image but ending in .html. Also see the default template in sub 
C<readTemplate>.

Notice the empty <IMG SRC=""> tag. This will automagically
be filled in with the URL of the graphic along with its width and height tags.

Also notice the <S-INSERT TITLE> and <S-INSERT CAPTION>. If you do not insert 
a title then the name of the graphic file will become the default title of 
the HTML file although dashes and underscores will be converted to spaces.  
The <S-INSERT CAPTION> will be filled in with the corresponding caption for 
the image.

=head2 B<Captions>

Of course you can put html in them! 

It is possible to create a custom caption for each image. Simply create a file that looks like so:

        dale.gif | <h2>Vegan guy</h2>
        Means he don't eat no animal pieces or excretions.
 
   
        no-meat-graphic.jpg | Use this logo to make stickers for your local McD's
  
   
	jill.jpg | <B>Bestest</B> gurly in the <em>world</em>! 

The first word must be a graphics filename followed by a | with optional spaces
around it. The caption continues until a blank line and will be stuffed
in place of the <S-INSERT CAPTION> tag in the C<template>.
Captions may span lines and must be seperated by a BLANK line. If you need a 
blank line in your caption for some reason (maybe you are useing 
&lt;PRE&gt;) then you need to put a space on the blank line.

If a graphic does not have a caption  then gif2html.pl will put the graphics 
name in as a caption, just as in the title.

Tell gif2html.pl where to find this file by either specifying it on the 
command line with the C<-c> option or putting its name in the $CAPTION_FILE user variable.

=head1 OPTIONS

=head2 Command Line

=over 4

=item B<-b> I<URL>
Baseref for all URLs in output. 

=item B<-g> I<URL>
Background for output files (unused) 

=item B<-c> F<filename>
Use this file for caption mappings. Default is .gif2html.cap.

=item B<-h> 
Help. 

=item B<-t> F<filename>
Use this template file. Default is .gif2html.tmp.

=item B<-v>
Verbose. Gives you a little feedback. 

=back


=head2 Script Variables

You may modify these variables to your heart's content. 

=over 4

=item B<$CAPTION_FILE> = ".gif2html.cap"; 
Default file of captions.

=item B<$BASEREF> = "./"; 
Where are the graphics located? This will prefix IMG SRC's. You might want to
use this if you are running gif2html.pl on a different box or in a different directory than where you will publish the output.

=item B<$TEMPLATE_FILE> = ".gif2html.tmp"; 
Default HTML template in current dir.

=back


=head1 TODO

=over 4

=item *    
Replace the <S-INSERT> tag with an html extension of some sort or just a gif2html tag... 

=item *     
Clean up. 

=item *     
Change caption mechanism. Allow multi-line captions.

=item *     
Make callable from slideshow.pl, other programs and CGI. 

=item *     
Add a -makecap option to allow interactive creation of caption files? Prompt you with the filename and allow you to enter a caption for it. I really need to mess with tkperl... 

=item *
Add the ability to tell if Image:Size is available and use it.

=item *     
Any other ideas? 

=back

=head1 SEE ALSO

Output of this program is particularly suited for 
L< slideshow / http://www.bewley.net/perl/slideshow.html > and
L< thumbindex / http://www.bewley.net/perl/thumbindex.html >.

Old versions still hanging around:
L< v0.90 / http://www.bewley.net/perl/gif2html.pl-0.9 >
L< v1.10 / http://www.bewley.net/perl/gif2html.pl-1.1 >

=head1 AUTHOR

Dale Bewley <dale@bewley.net>

Dale has recently started a business, Bewley Internet Solutions 
http://www.bewley.net/ if you like this script why not send him a job,
a check, or maybe just a book?

=cut


