#!/usr/local/bin/perl # Name: mybin/xv2small Author: Joe Smith 27-Sep-97 # Purpose: Given the name of a .xvpics directory, it looks at the thumbnail # images there (created by xv-3.10), and creates a .small directory # with the thumbnails converted to 80x60 GIFs. The names of the images # are sent to STDOUT in the form of an HTML table. If no *.gif files are # in .xvpics, the thumbnails will be created in the current directory. # Uses: "index.txt" to provide additional information about the pictures. # Format of index.txt: # filename1 description of first file # filename2 description of second file ... # $source_to_xv = "ftp.cis.upenn.edu/pub/xv/ and http://www.trilon.com/xv/"; $usage = "Usage: $0 .xvpics >index.html\n"; $small = "small"; # Directory hold the small gifs $index_txt = "index.txt"; # Name of file with one-line descriptions # An alternative name for index.txt can be specified as first argument. $index_txt = shift(@ARGV) if -f $ARGV[0]; if (! @ARGV) { # If no command line arguments if (-d ".xvpics") { push(@ARGV,".xvpics"); # Use default directory } else { print "Unable to locate the .xvpics in the current directory.\n"; print "The 'xv' program can be found at $source_to_xv\n" unless -f "/usr/local/bin/xv"; die $usage; } } die $usage unless -d $ARGV[0]; # Must have one or more .xvpics directories foreach (@ARGV) { &xvpics($_); # Do thumbnails } exit; sub xvpics { local($xvpics) = @_; unless (($parent,$basename) = $xvpics =~ m%(.*/)(.*)%) { ($parent,$basename) = ("",$xvpics); } &make_small; # Pass $parent, $basename, $xvpics to subroutine &make_table; # Output %tabledata } sub make_small { @files = (); opendir(DIR,$xvpics) || return(warn("Cannot open directory $xvpics: $!\n")); foreach $_ (grep(!/^\./,readdir(DIR))) { push(@files,$_) if -s "$parent$_" > 4096; # Skip thumbnails of thumbnails }; closedir(DIR); $gif_files = grep(/\.gif$/,@files); # False if only *.jpg if ($gif_files) { $destdir = "$parent$small" ; mkdir($destdir,0775) unless -d $destdir; } else { $destdir = $parent; # Put GIFs in current directory } %tabledata = (); foreach $file (@files) { $xv = "$xvpics/$file"; @statxv = stat($xv); open(IN,$xv) || warn("Could not read $xv: $!\n"); $_ = ; # "P7 332" for thumbnail with 3 red 3 green 2 blue bits $_ = ; # "#XVVERSION:Version 3.10a Rev: 12/29/94" chop($_ = ); # "#IMGINFO:754x510 JPEG file (61922 bytes)" close(IN); next unless s/#IMGINFO://; # Skip files with "#BUILTIN:UNKNOWN" $imginfo = $_; $mtime = $statxv[9]; if ($gif_files) { $sm = $file =~ /\.gif$/ ? "$destdir/$file" : "$destdir/$file.gif"; } else { ($sm = "$destdir$file") =~ s/\....$/.gif/; # Use *.gif for *.jpg } @statsm = stat($sm); # Failure is to be expected if ($statsm[9] < $mtime || $statsm[7] == 0) { # If gif is old or empty $| = 1; print STDERR ">$sm\t\t"; system("xvpictoppm <$xv | ppmtogif >$sm"); # Make small .gif utime($mtime,$mtime,$sm) || warn("Could not set mtime on $sm: $!\n"); } # Determine how big the thumbnail is. Usually 80 x 60 pixels. open(IN,$sm); read(IN,$string,15); close(IN); # 4749 4638 3761 5000 3600 A5 = GIF87a 0050 x 0036 (5 bits) ($magic,$width,$height,$bits) = unpack("a6 v v c",$string); warn("Unknown file type: $magic $width $height $bits\n") unless $magic =~ /GIF8\da/; $_ = ""; $_ .= "$parent$file - $imginfo\n"; $tabledata{$file} = $_; } } sub make_table { $file = $parent . $index_txt; # List of names and descriptions if (open(IN,$file)) { @description = (); # Images will be listed in this order close(IN); } else { warn "$file not found\n"; @description = (); } ($file,$descr) = split(" ",$description[0],2); # First line of index.txt if ($file eq ".") { # Look for ". Title" chop($descr); shift(@description); } else { $descr = "Pictures in " . $parent ? "'$parent'" : "this directory"; } print "$descr

$descr

\n"; $_ = (keys %tabledata); # Number of pictures $_ = scalar(@description) if scalar(@description) > $_; $pics_per_table = $_ > 20 ? 10 : $_; # Make multiple tables if too many # First, do all the pictures with descriptions, putting them in the # same order that they are mentioned in index.txt $count = 0; foreach (@description) { # Do images with descriptions first s/\015//; # Chop off CR from MS-DOS ($file,$descr) = split(" ",$_,2); print("$descr\n"),next if $file eq "."; if ($file eq "" || /text print "\n

\n" if $count > 0; $count = 0; $pics_per_table = 20; print $_; # Output embedded HTML or blank line next; } next unless -f "$parent$file"; # Skip deleted pics chop($descr); print "\n" if $count == 0; if ($tabledata{$file}) { print "$tabledata{$file}\n"; delete $tabledata{$file}; } else { # Text files listed in "index.txt" next if $file =~ /\.gif$/; # Skip listed thumbnails print "\n \n"; print "\n"; } if (++$count == $pics_per_table) { print "
$descr
TEXT"; print ""; print "$parent$file - (", -s "$parent$file", " bytes)
$descr
\n

\n"; $count = 0; } } foreach $file (sort keys %tabledata) { # Do images without descriptions chop($descr = `ls -l $parent$file`); print "\n" if $count == 0; print "$tabledata{$file}\n"; if (++$count == $pics_per_table) { print "
$descr
\n

\n"; $count = 0; } } print "\n

\n" if $count; }