thumb2

This script uses some small program which came with my default installation of RedHat.
#!/usr/bin/perl -w
use strict;

#  thumb was written by Rick Dean  July 28, 2000   v2.0

# This script will rename jpeg files with a _zoom.jpg extension
# if they are over 1.4 megapixes.
# For _zoom.jpg files this script will make a 1 megapixel image
# with just a .jpg extension
# For all pictures this script will create a 20000 kilopixel
# thumbnail which ends in _small.jpg

if(!defined($ARGV[0])) {  # if no command line argument
   print "usage: thumb filename\n";
   exit(1);
}

foreach my $filename (@ARGV) {
   if(! -e $filename) {
      print "skipping $filename (file does not exist)\n";
      next;
   };
   if($filename =~ /.JPG$/) {
      print "fixing case of extension $filename\n";
      my $oldname = $filename;
      $filename =~ s/.JPG$/.jpg/;
      rename($oldname,$filename) || die "can't rename($oldname,$filename)"
   };
   if($filename !~ /.jpg$/) {
      print "skipping $filename (not jpeg)\n";
      next;
   };
   if($filename =~ /_small.jpg$/) {
      print "skipping $filename (already small)\n";
      next;
   };
   my $numPixels = numPixelsOfFile($filename);
   my $fileMTime = (stat($filename))[9];
   if($numPixels > 1400000) {
      my $zoomname = $filename;
      if($filename =~ /_zoom.jpg$/) {
         $filename =~ s/_zoom.jpg$/.jpg/;  # add _zoom to name
      } else {
         $zoomname =~ s/.jpg$/_zoom.jpg/;  # remove _zoom from name
         if(-e $zoomname) {  # if file exists
            print "warning: zoom exists but file too big ($filename)\n";
            next;
         };
         rename($filename,$zoomname) || die "can't rename($filename,$zoomname)";
      };
      my $zoomMTime = (stat($zoomname))[9];
      if((! -e $filename) || $zoomMTime > $fileMTime) {  # if non-zoom is missing, or zoom is newer
        print "unzooming $filename\n";
        `djpeg -pnm "$zoomname" | pnmscale -pixels 600000 | cjpeg >"$filename"`;
        $fileMTime = (stat($filename))[9];
        $numPixels = numPixelsOfFile($filename);
      } else {
         #print "skipping unzoom of $zoomname (non-zoom already exists and is newer)\n";
      };
   };
   my $thumbname = $filename;
   $thumbname =~ s/.jpg$/_small.jpg/;
   my $thumbMTime = (stat($thumbname))[9];
   if((! -e $thumbname) || $thumbMTime < $fileMTime) {  # if thumb is missing, or thumb is older
      print "thumbing $filename\n";
      `djpeg -pnm "$filename" | pnmscale -pixels 20000 | cjpeg  >"$thumbname"`;
   };
};



# 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($c1,$c2,$ch,$s,$length, $dummy)=(0,0,0,0,0,0);
  my($a,$b,$c,$d);

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

sub numPixelsOfFile {
  my($filename) = @_;
  my($imageData);
  my($width,$height);

  open(IMAGEFILE,$filename);
  ($width,$height) = jpegsize(\*IMAGEFILE);
  close(IMAGEFILE);
  return ($width * $height);
}