#!/usr/bin/perl
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
#NAME
#  jpgresizes - Generate set of scaled-down JPEG files
#
#SYNOPSIS
#  jpgresizes file..
#
#REQUIRES
#
#DESCRIPTION
#  This program takes a list of .JPG files and  produces  a  set  of  smaller
#  files that are scaled-down by successive factors of two.
#
#  Our convention is that the original file will have a .JPG or .JPEG suffix.
#  The  results  will  be files with a .jpg suffix.  This is done to simplify
#  finding the derived files easily, perhaps for deletion, while ignoring the
#  original files.
#
#  The value of $thumbsize is the lower limit to the halving.  We  stop  when
#  the  next  halving would produce a file with height and width both smaller
#  than $thumbsize, which should be an integer.
#
#  Actually, the current approach is to generate the  list  of  sizes  first,
#  with  $thumbsize  the larger of the two values, and double the sizes until
#  we pass the size of the original file.  This way,  the  "thumbnail"  files
#  always have their larger dimension equal to $thumbsize, which turns out to
#  be more useful when presenting the thumbnail images in web pages.
#
#OPTIONS
#
#EXAMPLES
#
#FILES
#
#BUGS
#  We should have a command-line option to set $thumbsize.
#
#SEE ALSO
#  jpegtopnm, pamfile, pnmscale
#  
#
#AUTHOR
#  John Chambers <jc@trillian.mit.edu>
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

$| = 1;
$exitstat = 0;
($P = $0) =~ s".*/"";
$V = $ENV{"V_$P"} || $ENV{"D_$P"} || 2;	# Verbose level.

$lncmd = '/bin/ln';	# File-link command to use
$lscmd = '/bin/ls';	# File-list command to use
$thumbsize = 100;	# Larger pixel size of thumbnail images
$created = 0;		# Number of new files written

for $pth (@ARGV) {
	if (($dir,$nam,$suf) = ($pth =~ m"^(.*)/(.+)\.(JPE*G)$"i)) {
		if (($n = &onefile($dir,$nam,$suf)) > 0) {
			print "$P: Created $n files for \"$pth\"\n" if $V>1;
			$created += $n;
		} else {
			print "$P: ### Failed for \"$pth\"\n" if $V>0;
		}
	} elsif (($nam,$suf) = ($pth =~ m"^([-_\w]+)\.(JPE*G)$"i)) {
		$dir = '.';
		if (($n = &onefile($dir,$nam,$suf)) > 0) {
			print "$P: Created $n files for \"$pth\"\n" if $V>1;
			$created += $n;
		} else {
			print "$P: ### Failed for \"$pth\"\n" if $V>0;
		}
	} else {
		print "$P: --- Ignored \"$pth\"\n" if $V>0;
	}
}
print "$P: Created $created files.\n" if $V>0;

print "$P: Exit with status $exitstat.\n" if $V>1;
exit $exitstat;
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

sub onefile {my $F='onefile'; local($d,$b,$s) = @_;
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	local($cmd,$pnm,$rsp,$src);
	local($files,$hpx,$vpx,@widths,$width,@heights,$height);
	$files = 0;
#
	print "$F: PATH={" . $ENV{PATH} . "}\n" if $V>1;
	$src = "$d/$b.$s";
	$pnm = "$d/$b.pnm";
	$cmd = "jpegtopnm $src >$pnm";
	print "$F: cmd: {$cmd}\n" if $V>1;
	$rsp = `$cmd 2>1`;
	print "$F: rsp: {$rsp}\n" if $V>1;
#
	$cmd = "pamfile $d/$b.pnm";
	print "$F: cmd: {$cmd}\n" if $V>1;
	$rsp = `$cmd 2>&1`;		# Build temporary .pnm file
	print "$F: rsp: {$rsp}\n" if $V>1;
	if ($rsp =~ /\s(\d+) by (\d+)\s/) {
		$hpx = int($1);
		$vpx = int($2);
		print "$F: $b is $hpx x $vpx pixels.\n" if $V>1;
		system "$lncmd $d/$b.$s $d/${b}_${hpx}x${vpx}.jpg";
		if ($hpx > $vpx) {			# Landscape
			print "$F: Landscape layout.\n" if $V>2;
			$width = $thumbsize;		# Min landscape width
			$height = int(($width * $vpx) / $hpx);
			print "$F: Thumbnail is $width x $height.\n" if $V>2;
		} elsif ($hpx < $vpx) {	# Portrait
			print "$F: Portrait layout.\n" if $V>2;
			$height = $thumbsize;		# Min portrait height
			$width = int(($height * $hpx) / $vpx);
			print "$F: Thumbnail is $width x $height.\n" if $V>2;
		} else {			# Square image
			$width = $height = $thumbsize;
			print "$F: Thumbnail is $width x $height.\n" if $V>2;
		}
	} else {
		print "$F: ### No size for $d/$b.$s\n" if $V>0;
		print "$F: rsp=\{$rsp\}\n" if $V>0;
		return $files;
	}
#
	push @widths,  $width;	# Horizontal pixel size of thumbnail
	push @heights, $height;	# Vertical   pixel size of thumbnail
	while ((($width *= 2) < $hpx) && (($height *= 2) < $vpx)) {	# Generate list by doubling
		print "$F: Add ${width}x${height} to sizes.\n" if $V>2;
		push @widths,  $width;
		push @heights, $height;
	}
	while ($width = pop @widths) {
		$height = pop @heights;
		print "$F: SIZE $width x $height.\n" if $V>2;
		$cmd = "pnmscale -width=$width $d/$b.pnm |pnmtojpeg >$d/${b}_${width}x${height}.jpg";
		print "$F: cmd: {$cmd}\n" if $V>2;
		$rsp = `$cmd 2>1`;
		if ($?) {
			print "$F: ### FAILED for $d/$b.$s ${width}x${height}\n" if $V>1;
			print "$F: ### {$rsp}\n" if $V>1;
		} else {
			print "$F: rsp: {$rsp}\n" if $V>2;
			++$files;
		}
	}
	unlink "$d/$b.pnm";		# Get rid of the temporary .pnm file
#
	system "$lscmd -l $d/$b*";
	return $files;
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
