#!/bin/sh -- # A comment mentioning perl
eval 'exec perl -S $0 ${1+"$@"}'
if 0;
select(STDERR); $| = 1;
select(STDOUT); $| = 1;
$Program = $0;
$Program =~ s,^.*/,,;
$Usage = <<"END";
$Program: Insert HEIGHT and WIDTH parameters into HTML
tags.
Usage: $Program [] [ ...]
Options:
-d Debug messages
-O overwrite input file
-r local directory corresponding to "/" in HREF
-i file is not HTML but an image.
Notes:
Default output is to STDOUT.
No on cmd line means use STDIN.
More than one file on cmd line means to merge the HTML from all of them.
(however, if -O is specified each file is overwritten individually)
If an
tag already has HEIGHT WIDTH parameters,
they are corrected, otherwise they are inserted.
This program depends on file(1), djpeg(1), and convert(1) output.
Tested on Redhat Linux, it may work elsewhere...
Currently handles gif, jpeg, and png images.
END
if ($ARGV[0] eq '-i') {
shift;
my $bad = 0;
chomp($pwd = `pwd`);
foreach my $image (@ARGV) {
my $file = $image;
if ($image !~ m,^/,) {
$file = "$pwd/$image";
}
my $tmp = "/tmp/is.$$.html";
open(TMP, ">$tmp");
print TMP <<"END";
END
system("$0 -O $tmp 2>/dev/null");
open(TMP, "<$tmp");
my $w = 0;
my $h = 0;
while () {
if (/width="(\d+)"/i) {
$w = $1;
}
if (/height="(\d+)"/i) {
$h = $1;
}
}
close(TMP);
unlink $tmp;
if ($w && $h) {
print "${w}x${h} $image\n";
} else {
$bad = 1;
}
}
if ($bad) {
exit 1;
} else {
exit 0;
}
}
$Debug = 0;
$Root = '';
$Overwrite = 0;
LOOP:
while (@ARGV) {
$_ = shift;
CASE: {
/^-d$/ && ($Debug = 1, last CASE);
/^-O$/ && ($Overwrite = 1, last CASE);
/^-r$/ && ($Root = shift, last CASE);
/^--$/ && (last LOOP); # -- means end of switches
/^-(-.*)$/ && (unshift(@ARGV, $1), last CASE);
/^(-h|-help)$/ && ((print STDERR $Usage), exit 0, last CASE);
if ( /^-(..+)$/ ) { # split bundled switches:
local($y, $x) = ($1, '');
foreach $x (reverse(split(//, $y))) { unshift(@ARGV,"-$x") };
last CASE;
}
/^-/ && ((print STDERR "Invalid arg: $_\n$Usage"), exit 1, last CASE);
unshift(@ARGV,$_);
last LOOP;
}
}
if ( $Overwrite && @ARGV > 1 ) {
# Call ourselves for each file:
$args = "-O ";
$args .= "-d " if $Debug;
$args .= "-r $Root" if $Root;
foreach $f (@ARGV) {
print STDERR "\nrunning: $0 $args '$f'\n";
system("$0 $args '$f'");
}
exit 0;
}
if ( @ARGV > 1 ) {
print STDERR "$Program: files will be merged: ", join(' ', @ARGV), "\n";
}
$Filename = '';
$File = '';
# slurp in the whole file(s) and note the (first) filename:
while (<>) {
$Filename = $ARGV unless $Filename ne '';
$File .= $_;
}
$File0 = $File;
print STDERR "$Program: processing filename: $Filename\n";
$Dirname = &dirname($Filename);
# loop over all matches of
tags in the file:
while ($File =~ /<\s*IMG\b[^>]*>/i ) {
$File = $` . &addsize($&) . $'; # replace the tag with image size.
}
$File =~ s/<\s*#(IMG)\b/<$1/ig; # get rid of our "#IMG" marker.
if ( $Filename eq '-' || $Filename eq '' ) {
if ( $Overwrite ) {
print STDERR "$Program: cannot overwrite STDIN: $Filename\n";
$Overwrite = 0;
}
}
if ( $Overwrite ) {
if ( $File eq $File0 ) {
print STDERR "$Program: file $Filename unchanged.\n";
} else {
if ( ! -f $Filename ) {
print STDERR "$Program: does not exist $Filename: $!\n";
} elsif ( ! open(FILE, ">$Filename") ) {
print STDERR "$Program: could not open $Filename: $!\n";
} else {
print FILE $File;
close(FILE);
print STDERR "$Program: overwrote $Filename\n";
}
}
} else {
print STDOUT $File;
}
exit 0;
sub addsize {
my ($tag) = @_;
$tag =~ s/(IMG)/#$1/i; # put in <#IMG marker.
if ( $tag !~ /#IMG/i ) {
print STDERR "$Program: no #IMG marker, bailing out on possible infinite loop: $tag\n";
exit 1;
}
print STDERR "===> process: $tag\n" if $Debug;
my $image = '';
if ( $tag =~ /\bSRC=([^\s>]+)/i ) {
$image = $1;
$image =~ s/^"//;
$image =~ s/"$//;
}
if ( $image eq '' ) {
print STDERR "no image(empty): $image\n" if $Debug;
return $tag;
}
if ( $image =~ m,http:,i ) {
print STDERR "no image(http://): $image\n" if $Debug;
return $tag;
}
if ( $image =~ m,^/, ) {
$image = $Root . $image;
} else {
$image = $Dirname . "/" . $image;
}
if ( ! -f $image || $image =~ /'/ ) {
print STDERR "no image(exist/quote): $image\n" if $Debug;
return $tag;
}
my $fileout = '';
# For speed, assume the file suffix is correct:
if ( $image =~ /\.jpe?g$/i ) {
$fileout = 'JPEG';
}
if ( $fileout eq '' ) {
$fileout = `file '$image'`;
$fileout =~ s/^[^:]:\s//;
}
my $width = '';
my $height = '';
if ( $fileout =~ /\b(GIF|PNG)\b/ ) {
if ( $fileout =~ /,\s+(\d+)\s*x\s*(\d+)\b/ ) {
$width = $1;
$height = $2;
} else {
print STDERR "bad file output: $fileout\n" if $Debug;
return $tag;
}
} elsif ( $fileout =~ /\b(JPEG)\b/ ) {
if ( $Jpeg_Command eq '' ) {
# in order from fastest to slowest:
foreach my $cmd (qw(rdjpgcom djpeg jpegtran convert)) {
system("type $cmd >/dev/null 2>/dev/null");
if ( $? == 0 ) {
$Jpeg_Command = $cmd;
last;
}
}
if ( $Jpeg_Command eq '' ) {
die "No jpeg command. $!";
}
}
if ( $Jpeg_Command eq 'rdjpgcom' ) {
$fileout = `rdjpgcom -verbose '$image'`;
# JPEG image is 640w * 480h, 3 color components, 8 bits per sample
if ( $fileout =~ /JPEG image is (\d+)w[\s*]+(\d+)h/ ) {
$width = $1;
$height = $2;
}
} elsif ( $Jpeg_Command eq 'djpeg' ) {
$fileout = `djpeg -verbose -nosmooth -fast '$image' 2>&1 1>/dev/null`;
# Start Of Frame 0xc0: width=640, height=480, components=3
if ( $fileout =~ /Start Of Frame.*width=(\d+), height=(\d+)/ ) {
$width = $1;
$height = $2;
}
} elsif ( $Jpeg_Command eq 'jpegtran' ) {
$fileout = `jpegtran -verbose '$image' 2>&1 1>/dev/null`;
# Start Of Frame 0xc0: width=640, height=480, components=3
if ( $fileout =~ /Start Of Frame.*width=(\d+), height=(\d+)/ ) {
$width = $1;
$height = $2;
}
} elsif ( $Jpeg_Command eq 'convert' ) {
$fileout = `convert -verbose '$image' JPG:/dev/null 2>&1`;
# mylt.jpg 640x914 DirectClass 159kb JPEG 1s
# mylt.jpg=>/dev/null 640x914 DirectClass JPG 3s
if ( $fileout =~ /\s+(\d+)\s*x\s*(\d+)\b/ ) {
$width = $1;
$height = $2;
}
}
if ( $width !~ /^\d+$/ || $height !~ /^\d+$/ ) {
print STDERR "bad file output: $fileout\n" if $Debug;
return $tag;
}
} elsif ( $fileout =~ /\b(TIFF)\b/ ) {
$fileout = `convert -verbose '$image' JPG:/dev/null 2>&1`;
#TIFF Directory at offset 0x140008
# Image Width: 1280 Image Length: 1024
if ( $fileout =~ /Width:\s+(\d+)\b.*Length:\s+(\d+)\b/ ) {
$width = $1;
$height = $2;
}
if ( $width !~ /^\d+$/ || $height !~ /^\d+$/ ) {
print STDERR "bad file output: $fileout\n" if $Debug;
return $tag;
}
} elsif ( $fileout =~ /\b(PPM|PC bitmap data)\b/ ) {
$fileout = `convert -verbose '$image' JPG:/dev/null 2>&1`;
if ( $fileout =~ /\s+(\d+)\s*x\s*(\d+)\b/ ) {
$width = $1;
$height = $2;
}
if ( $width !~ /^\d+$/ || $height !~ /^\d+$/ ) {
print STDERR "bad file output: $fileout\n" if $Debug;
return $tag;
}
} else {
# any others?
$fileout = `identify '$image' 2>&1`;
if ( $fileout =~ /\s+(\d+)\s*x\s*(\d+)\b/ ) {
$width = $1;
$height = $2;
}
if ( $width !~ /^\d+$/ || $height !~ /^\d+$/ ) {
print STDERR "bad file output: $fileout\n" if $Debug;
return $tag;
}
}
if ( $Debug ) {
print STDERR "found width=$width height=$height\n";
}
if ( $width !~ /^\d+$/ || $height !~ /^\d+$/ ) {
return $tag;
}
my $tag0 = $tag;
if ( $tag =~ /(WIDTH)=([^\s>]+)/i ) {
($a, $b) = ($1, $2);
$tag =~ s/$a=$b/$a="$width"/;
} else {
$tag =~ s/>/ width="$width">/;
}
if ( $tag =~ /(HEIGHT)=([^\s>]+)/i ) {
($a, $b) = ($1, $2);
$tag =~ s/$a=$b/$a="$height"/;
} else {
$tag =~ s/>/ height="$height">/;
}
if ( $Debug ) {
print STDERR "before: $tag0\n";
print STDERR "after: $tag\n";
}
return $tag;
}
sub dirname {
# Like dirname(1), returns dirname of a path.
my ($x) = @_;
$x =~ s,/+$,,; # remove trailing /'s
$x =~ s,/+,/,g; # change multiple /'s to single /
if ( $x =~ m,^(.*)/[^/]+$, ) { # check if matches /
$x = $1; # grab stuff before /
$x = '/' if $x eq ''; # is root if null.
} else { # it was a bare word without /
$x = '.';
}
$x = '.' if $x eq ''; # never return null string
return $x;
}