--- scaleomat/scaleomat.pl 2004/07/23 17:58:24 1.1 +++ scaleomat/scaleomat.pl 2004/07/23 18:00:33 1.2 @@ -1,28 +1,51 @@ #!/usr/bin/perl +use strict; + +# MPIWG libraries +use lib '/usr/local/mpiwg/scripts'; +use MPIWGlib; + + $| = 1; # unblock IO -$version = "V0.7 (ROC 23.12.2003)"; +my $version = "V0.9.2 (ROC 22.4.2004)"; $debug = 0; -$simulate = 0; -$do_descend = 1; +my $simulate = 0; -@source_base_dirs = ("/docuserver/images"); -$dest_base_dir = "/docuserver/scaled/small"; -$dir_perm = 0775; -$file_perm = 0664; +my $do_descend = 1; -umask 000; # to make shure we can actually use these perms +my $dir_perm = 0775; +my $file_perm = 0664; -$dont_overwrite = 1; # don't overwrite already converted files +umask 000; # to make shure we can actually use these perms -@imgfile_ext = ("tif", "tiff", "gif", "jpg", "png"); +my $overwrite = 0; # overwrite already converted files -$target_size = 2048; # pixel of longest side -$scale_relative = 0; # scale by relative factor instead of destination size -$jpeg_quality = 75; # default JPEG compression quality +# image file extensions and formats +my %img_type_ext = ("tif" => "TIFF", "tiff" => "TIFF", "gif" => "GIF", + "jpg" => "JPEG", "png" => "PNG"); +# destination image file extensions +my %target_ext_type = ("TIFF" => "jpg", "JPEG" => "jpg"); + +# default scale settings +my $scalesize = 2048; # pixel of longest side +my $scale_relative = 0; # scale by relative factor instead of destination size +my $jpeg_quality = 75; # default JPEG compression quality +my $use_encoder = 0; # autodetect encoder + +# programs to use +my $identifier; +my $tiffinfo; +my $jpegloader; +my $tiffloader; +my $quantizer; +my $scaler; +my $jpegwriter; +my $pngwriter; +my $converter; ########################################################################## # subroutines @@ -39,6 +62,8 @@ sub checksoft { $identifier = findfile(\@softdirs, "identify") or die("ABORT: neccessary external program not found: identify"); + $tiffinfo = findfile(\@softdirs, "tiffinfo") + or die("ABORT: neccessary external program not found: tiffinfo"); $jpegloader = findfile(\@softdirs, "jpegtopnm") or die("ABORT: neccessary external program not found: jpegtopnm"); $tiffloader = findfile(\@softdirs, "tifftopnm") @@ -59,21 +84,6 @@ sub checksoft { # -# dprint($message) -# -# print if $debug = 1 -# -sub dprint { - my ($msg) = @_; - - if ($debug) { - print "$msg"; - } -} - - - -# # findir(\@basedirs, $subdir) # # check directories in @basedirs+$subdir and return the first existing basedir @@ -107,6 +117,20 @@ sub findfile { # +# ($basename, $extension) = splitfn($filename) +# +# split filename into base and (lowercase) extension +# +sub splitfn { + my ($filepath) = @_; + if ($filepath =~ /^(.*)\.(\w+)$/) { + return ($1, lc($2)); + } + return; +} + + +# # mmkdir($dirname) # # create directory recursively and check permissions @@ -116,9 +140,9 @@ sub mmkdir { my $newdir; # does the directory already exist? - if (-d $dir) { - chmod $dir_perm, $dir or do { - print "ERROR: unable to change permission on $dir!\n"; + if (-d $dirname) { + chmod $dir_perm, $dirname or do { + logger('ERROR', "unable to change permission on $dirname!"); return 0; }; return 1; @@ -129,6 +153,7 @@ sub mmkdir { my $dir = join("/", @dirlist); # test backwards which directories exist while (not -d $dir) { + last unless ($dir); # move missing elements from the end of @dirlist to @newlist unshift @newlist, pop @dirlist; $dir = join("/", @dirlist); @@ -138,7 +163,7 @@ sub mmkdir { push @dirlist, $newdir; $dir = join("/", @dirlist); mkdir "$dir", $dir_perm or do { - print "ERROR: unable to create $dir!\n"; + logger('ERROR', "unable to create $dir!"); return 0; } } @@ -146,167 +171,501 @@ sub mmkdir { } # -# dir_ok($dirname) +# ($type, $width, $height) = identify($filepath) # -# check directory name against evil -# -sub dir_ok { - my($dirname) = @_; - - if ($dirname eq "") { - print "ERROR: DIR mustn't be empty!\n"; - return 0; - } - if ($dirname =~ /\.\./) { - print "ERROR: DIR mustn't backref!\n"; - return 0; - } - if ($dirname =~ /[|<>]+/) { - print "ERROR: DIR mustn't be special!\n"; - return 0; - } - return 1; -} - - -# -# convert_file($filename) -# -# convert file -# -sub convert_file { - my($basedir, $filename) = @_; - my $newfn; +sub identify { + my ($filepath) = @_; my $pictype; my $picwidth; my $picheight; - my $scaleopt = 0.3; - - if (not (( -f "$basedir/$filename") && (-r _))) { - print "ERROR: unable to read file '$basedir/$filename'\n;"; - return 0; + my $bitdepth = 0; + # use quickident first + $pictype = quickident($filepath); + # optimize tiff identification + if (($pictype)&&($pictype eq 'TIFF')) { + logger('DEBUG', "running tiffinfo $tiffinfo"); + if (open(IDENT, "nice -10 $tiffinfo '$filepath' 2>/dev/null |")) { + while () { + chomp; + if (/Image Width:\s*(\d+)\s*Image Length:\s*(\d+)/) { + $picwidth = $1; + $picheight = $2; + next; + } + if (/Bits\/Sample:\s*(\d+)/) { + $bitdepth = $1; + next; + } + } + if ($picwidth) { + logger('DEBUG', "TIFF $1 x $2"); + return ($pictype, $picwidth, $picheight, $bitdepth); + } + } } - - # - # run ident first to get image type and dimensions - # calculate scaling factor based on destination size or factor - # - if (open(IDENT, "nice -10 $identifier -ping -format '%w %h %m\n' '$basedir/$filename' 2>/dev/null|")) { + # run ident to get image type and dimensions + logger('DEBUG', "running identifier $identifier"); + if (open(IDENT, "nice -10 $identifier -ping -format '%w %h %m\n' '$filepath' 2>/dev/null |")) { my @id = ; my $picinfo = $id[0]; close IDENT; chomp $picinfo; - dprint "INFO: PIC is $picinfo\n"; + logger('DEBUG', "PIC is '$picinfo'"); if ($picinfo =~ /^(\d+) (\d+) (\w+)$/) { $picwidth = $1; $picheight = $2; $pictype = $3; - if ($scale_relative) { - $scaleopt = $target_size; - } else { - if ($picheight > $picwidth) { - $scaleopt = $target_size / $picheight; - dprint "INFO: PIC is portrait\n"; - } else { - $scaleopt = $target_size / $picwidth; - dprint "INFO: PIC is landscape\n"; - } - if ($scaleopt >= 1) { - $scaleopt = 1; - dprint "INFO: PIC is already smaller\n"; - } - } } + } else { + logger('DEBUG', "unable to identify $filepath!"); } - - # - # scale JPEG images to JPEG using netpbm tools - # - if ($pictype eq 'JPEG') { - # convert jpg -> jpg - $newfn = $filename; - $newfn =~ s/\.\w+$/.jpg/; - if (-f "$dest_base_dir/$newfn") { - dprint "INFO CONV file exists: $newfn\n"; - if ($dont_overwrite) { - print "INFO: File already converted: $newfn\n"; + return ($pictype, $picwidth, $picheight, $bitdepth); +} + +# +# $type = quickident($filepath); +# +sub quickident { + my ($filepath) = @_; + logger('DEBUG', "running quickident"); + # look at file extension + my ($filebase, $fileext) = splitfn($filepath); + if ($fileext) { + return $img_type_ext{$fileext}; + } + return; +} + + +# +# $error = scale_jpeg(\$args); +# +# scale JPEG images to JPEG using netpbm tools +# +# args needed: $srcdir, $filename, $destdir, +# $scalesize, $scale_rel, $picwidth, $picheight +# +sub scale_jpeg { + my ($args) = @_; + + my $srcdir = $$args{'srcdir'}; + my $filename = $$args{'filename'}; + my $destdir = $$args{'destdir'}; + my $scalesize = $$args{'scalesize'}; + my $scale_rel = $$args{'scale_rel'}; + my $scaleopt; + + # convert jpg -> jpg + my ($basename, $fileext) = splitfn($filename); + my $newfn = $basename . ".jpg"; + logger('INFO', "Convert(jpg): $filename -> $newfn"); + return 1 if ($simulate); + + if ($scale_rel) { + # scale relative -- no size needed, only scaling factor + $scaleopt = $scalesize; + } else { + # scale to size -- size needed + my $pictype = $$args{'pictype'}; + my $picwidth = $$args{'picwidth'}; + my $picheight = $$args{'picheight'}; + if (! $picwidth) { + ($pictype, $picwidth, $picheight) = identify("$srcdir/$filename"); + if ((! $pictype)||($picwidth == 0)||($picheight == 0)) { + logger('ERROR', "unable to identify $srcdir/$filename!"); return 1; } } - print "INFO: Convert(jpg): $filename -> $newfn\n"; - return 1 if ($simulate); - dprint("nice -10 $jpegloader '$basedir/$filename' 2>/dev/null | nice -10 $scaler $scaleopt 2>/dev/null | nice -10 $jpegwriter > '$dest_base_dir/$newfn' 2>/dev/null\n"); - if (system("nice -10 $jpegloader '$basedir/$filename' 2>/dev/null | nice -10 $scaler $scaleopt 2>/dev/null | nice -10 $jpegwriter > '$dest_base_dir/$newfn' 2>/dev/null") != 0) { - return 0; + if ($picheight > $picwidth) { + $scaleopt = $scalesize / $picheight; + logger('DEBUG', "PIC is portrait"); + } else { + $scaleopt = $scalesize / $picwidth; + logger('DEBUG', "PIC is landscape"); + } + if ($scaleopt >= 1) { + $scaleopt = 1; + logger('DEBUG', "PIC is already smaller"); } - chmod $file_perm, "$dest_base_dir/$newfn" or - print "WARNING: unable to set permission on '$dest_base_dir/$newfn'\n"; + } + + if (!$scaleopt) { + logger('ERROR', "unable to calculate scaling options!"); return 1; } - # - # scale TIFF images to JPEG using convert - # (slower but netpbm doesn't always work) - # - if ($pictype eq 'TIFF') { - # convert tif -> jpg - $newfn = $filename; - $newfn =~ s/\.\w+$/.jpg/; - if (-f "$dest_base_dir/$newfn") { - dprint "INFO: CONV file exists: $newfn\n"; - if ($dont_overwrite) { - print "INFO: File already converted: $newfn\n"; + # convert + logger('DEBUG', "nice -10 $jpegloader '$srcdir/$filename' 2>/dev/null | nice -10 $scaler $scaleopt 2>/dev/null | nice -10 $jpegwriter > '$destdir/$newfn' 2>/dev/null"); + return 0 if ($simulate); + if (system("nice -10 $jpegloader '$srcdir/$filename' 2>/dev/null | nice -10 $scaler $scaleopt 2>/dev/null | nice -10 $jpegwriter > '$destdir/$newfn' 2>/dev/null") != 0) { + logger('ERROR', "error converting '$srcdir/$filename'!"); + unlink "$destdir/$newfn"; + return 1; + } + + # change permissions + chmod $file_perm, "$destdir/$newfn" or + logger('WARNING', "unable to set permission on '$destdir/$newfn'"); + + if (! -s "$destdir/$newfn") { + # file broken (size 0) + logger('ERROR', "created file '$destdir/$newfn' broken -- will be removed!"); + unlink "$destdir/$newfn"; + return 1; + } + return 0; +} + + +# +# $error = scale_tiff_jpeg2(\$args); +# +# scale TIFF images to JPEG using ImageMagick convert +# +# args needed: $srcdir, $filename, $destdir, +# $scalesize, $scale_rel, $picwidth, $picheight +# +sub scale_tiff_jpeg2 { + my ($args) = @_; + + my $srcdir = $$args{'srcdir'}; + my $filename = $$args{'filename'}; + my $destdir = $$args{'destdir'}; + my $scalesize = $$args{'scalesize'}; + my $scale_rel = $$args{'scale_rel'}; + my $scaleopt; + + my ($basename, $fileext) = splitfn($filename); + my $newfn = $basename . ".jpg"; + logger('INFO', "Convert(tiff2): $filename -> $newfn"); + return 1 if ($simulate); + + if ($scale_rel) { + # scale relative -- no size needed, only scaling factor + $scaleopt = $scalesize; + } else { + # scale to size -- size needed + my $pictype = $$args{'pictype'}; + my $picwidth = $$args{'picwidth'}; + my $picheight = $$args{'picheight'}; + if (! $picwidth) { + ($pictype, $picwidth, $picheight) = identify("$srcdir/$filename"); + if ((! $pictype)||($picwidth == 0)||($picheight == 0)) { + logger('ERROR', "unable to identify $srcdir/$filename!"); return 1; } } - print "INFO: Convert(tif): $filename -> $newfn\n"; - if ($scale_relative) { - my $per_scale = 100 * $scaleopt; - dprint("nice -10 $converter -quality $jpeg_quality -scale $per_scale\% $basedir/$filename $dest_base_dir/$newfn 2>/dev/null\n"); - return 1 if ($simulate); - if (system("nice -10 $converter -quality $jpeg_quality -scale $per_scale\% '$basedir/$filename' '$dest_base_dir/$newfn' 2>/dev/null\n") != 0) { - return 0; + if ($picheight > $picwidth) { + $scaleopt = $scalesize / $picheight; + logger('DEBUG', "PIC is portrait"); + } else { + $scaleopt = $scalesize / $picwidth; + logger('DEBUG', "PIC is landscape"); + } + if ($scaleopt >= 1) { + $scaleopt = 1; + logger('DEBUG', "PIC is already smaller"); + } + } + + if (!$scaleopt) { + logger('ERROR', "unable to calculate scaling options!"); + return 1; + } + + if ($scale_rel) { + my $per_scale = 100 * $scaleopt; + logger('DEBUG', "nice -10 $converter -quality $jpeg_quality -scale $per_scale\% '$srcdir/$filename' '$destdir/$newfn' 2>/dev/null"); + return 0 if ($simulate); + if (system("nice -10 $converter -quality $jpeg_quality -scale $per_scale\% '$srcdir/$filename' '$destdir/$newfn' 2>/dev/null\n") != 0) { + logger('ERROR', "error converting '$srcdir/$filename'!"); + return 1; + } + } else { + logger('DEBUG', "nice -10 $converter -quality $jpeg_quality -scale ${scalesize}x${scalesize} '$srcdir/$filename' '$destdir/$newfn' 2>/dev/null"); + return 0 if ($simulate); + if (system("nice -10 $converter -quality $jpeg_quality -scale ${scalesize}x${scalesize} '$srcdir/$filename' '$destdir/$newfn' 2>/dev/null\n") != 0) { + logger('ERROR', "error converting '$srcdir/$filename'!"); + return 1; + } + } + + # change permissions + chmod $file_perm, "$destdir/$newfn" or + logger('WARNING', "unable to set permission on '$destdir/$newfn'"); + + if (! -s "$destdir/$newfn") { + # file broken (size 0) + logger('ERROR', "created file '$destdir/$newfn' broken -- will be removed!"); + unlink "$destdir/$newfn"; + return 1; + } + return 0; +} + + +# +# $error = scale_tiff_jpeg(\$args); +# +# scale TIFF images to JPEG using netpbm tools +# +# args needed: $srcdir, $filename, $destdir, +# $scalesize, $scale_rel, $picwidth, $picheight +# +sub scale_tiff_jpeg { + my ($args) = @_; + + my $srcdir = $$args{'srcdir'}; + my $filename = $$args{'filename'}; + my $destdir = $$args{'destdir'}; + my $scalesize = $$args{'scalesize'}; + my $scale_rel = $$args{'scale_rel'}; + my $scaleopt; + + # convert jpg -> jpg + my ($basename, $fileext) = splitfn($filename); + my $newfn = $basename . ".jpg"; + logger('INFO', "Convert(tiff1): $filename -> $newfn"); + return 1 if ($simulate); + + if ($scale_rel) { + # scale relative -- no size needed, only scaling factor + $scaleopt = $scalesize; + } else { + # scale to size -- size needed + my $pictype = $$args{'pictype'}; + my $picwidth = $$args{'picwidth'}; + my $picheight = $$args{'picheight'}; + if (! $picwidth) { + ($pictype, $picwidth, $picheight) = identify("$srcdir/$filename"); + if ((! $pictype)||($picwidth == 0)||($picheight == 0)) { + logger('ERROR', "unable to identify $srcdir/$filename!"); + return 1; } + } + if ($picheight > $picwidth) { + $scaleopt = $scalesize / $picheight; + logger('DEBUG', "PIC is portrait"); } else { - dprint("nice -10 $converter -quality $jpeg_quality -scale ${target_size}x${target_size} $basedir/$filename $dest_base_dir/$newfn 2>/dev/null\n"); - return 1 if ($simulate); - if (system("nice -10 $converter -quality $jpeg_quality -scale ${target_size}x${target_size} '$basedir/$filename' '$dest_base_dir/$newfn' 2>/dev/null\n") != 0) { - return 0; + $scaleopt = $scalesize / $picwidth; + logger('DEBUG', "PIC is landscape"); + } + if ($scaleopt >= 1) { + $scaleopt = 1; + logger('DEBUG', "PIC is already smaller"); + } + } + + if (!$scaleopt) { + logger('ERROR', "unable to calculate scaling options!"); + return 1; + } + + # convert + logger('DEBUG', "nice -10 $tiffloader '$srcdir/$filename' 2>/dev/null | nice -10 $scaler $scaleopt 2>/dev/null | nice -10 $jpegwriter --quality $jpeg_quality > '$destdir/$newfn' 2>/dev/null"); + return 0 if ($simulate); + if (system("nice -10 $tiffloader '$srcdir/$filename' 2>/dev/null | nice -10 $scaler $scaleopt 2>/dev/null | nice -10 $jpegwriter --quality $jpeg_quality > '$destdir/$newfn' 2>/dev/null") != 0) { + logger('ERROR', "error converting '$srcdir/$filename'!"); + unlink "$destdir/$newfn"; + return 1; + } + + # change permissions + chmod $file_perm, "$destdir/$newfn" or + logger('WARNING', "unable to set permission on '$destdir/$newfn'"); + + if (! -s "$destdir/$newfn") { + # file broken (size 0) + logger('ERROR', "created file '$destdir/$newfn' broken -- will be removed!"); + unlink "$destdir/$newfn"; + return 1; + } + return 0; +} + + + +# +# $error = scale_tiff_png(\$args); +# +# scale TIFF images to PNG using netpbm tools +# +# args needed: $srcdir, $filename, $destdir, +# $scalesize, $scale_rel, $picwidth, $picheight +# +sub scale_tiff_png { + my ($args) = @_; + + my $srcdir = $$args{'srcdir'}; + my $filename = $$args{'filename'}; + my $destdir = $$args{'destdir'}; + my $scalesize = $$args{'scalesize'}; + my $bitdepth = $$args{'bitdepth'}; + my $scale_rel = $$args{'scale_rel'}; + my $scaleopt; + + # convert jpg -> jpg + my ($basename, $fileext) = splitfn($filename); + my $newfn = $basename . ".png"; + logger('INFO', "Convert(tiff3): $filename -> $newfn"); + + if ($scale_rel) { + # scale relative -- no size needed, only scaling factor + $scaleopt = $scalesize; + } else { + # scale to size -- size needed + my $pictype = $$args{'pictype'}; + my $picwidth = $$args{'picwidth'}; + my $picheight = $$args{'picheight'}; + if (! $picwidth) { + ($pictype, $picwidth, $picheight, $bitdepth) = identify("$srcdir/$filename"); + if ((! $pictype)||($picwidth == 0)||($picheight == 0)) { + logger('ERROR', "unable to identify $srcdir/$filename!"); + return 1; } } - chmod $file_perm, "$dest_base_dir/$newfn" or - print "WARNING: unable to set permission on '$newfn'\n;"; + if ($picheight > $picwidth) { + $scaleopt = $scalesize / $picheight; + logger('DEBUG', "PIC is portrait"); + } else { + $scaleopt = $scalesize / $picwidth; + logger('DEBUG', "PIC is landscape"); + } + if ($scaleopt >= 1) { + $scaleopt = 1; + logger('DEBUG', "PIC is already smaller"); + } + } + + if (!$scaleopt) { + logger('ERROR', "unable to calculate scaling options!"); return 1; } + # convert + my $cmd = "nice -10 $tiffloader \'$srcdir/$filename\' 2>/dev/null "; + if ($bitdepth == 1) { + # antialiasing bilevel images + $cmd .= "| nice -10 $quantizer 2 2 2>/dev/null "; + } + $cmd .= "| nice -10 $scaler $scaleopt 2>/dev/null | nice -10 $pngwriter > '$destdir/$newfn' 2>/dev/null"; + logger('DEBUG', "$cmd"); + return 0 if ($simulate); + if (system($cmd) != 0) { + logger('ERROR', "error converting '$srcdir/$filename'!"); + unlink "$destdir/$newfn"; + return 1; + } + + # change permissions + chmod $file_perm, "$destdir/$newfn" or + logger('WARNING', "unable to set permission on '$destdir/$newfn'"); + + if (! -s "$destdir/$newfn") { + # file broken (size 0) + logger('ERROR', "created file '$destdir/$newfn' broken -- will be removed!"); + unlink "$destdir/$newfn"; + return 1; + } + return 0; +} + + +# +# $error = convert_file($srcdir, $filename, $destdir); +# +# convert file +# +sub convert_file { + my($srcdir, $filename, $destdir) = @_; + my $filebase; + my $fileext; + my $newfn; + my $pictype; + my $picwidth; + my $picheight; + my $bitdepth; + my $error = 0; + + logger('DEBUG', "convert_file ($srcdir, $filename, $destdir)"); + + if (not (( -f "$srcdir/$filename") && (-r _))) { + logger('ERROR', "unable to read file '$srcdir/$filename'"); + return 1; + } + + # get base name and extension + if ($filename =~ /^(.*)\.(\w+)$/) { + $filebase = $1; + $fileext = $2; + } + # - # convert TIFF to PNG using netpbm tools (not used any more) + # quick check if target image exists # - if ($pictype eq 'TIFF_old') { - # convert tif -> png - $newfn = $filename; - $newfn =~ s/\.\w+$/.png/; - if (-f "$dest_base_dir/$newfn") { - dprint "INFO: CONV file exists: $newfn\n"; - if ($dont_overwrite) { - print "INFO: File already converted: $newfn\n"; - return 1; + $pictype = quickident("$srcdir/$filename"); + if ($pictype) { + my $newext = $target_ext_type{$pictype}; + if ($newext) { + $newfn = $filebase . ".$newext"; + # check if file exists + if (-f "$destdir/$newfn") { + logger('DEBUG', "CONV file exists: $newfn"); + if (! $overwrite) { + logger('INFO', "File already converted: $newfn"); + return 0; + } } + } else { + logger('DEBUG', "target extension for $pictype unknown!"); } - print "INFO: Convert(tif): $filename -> $newfn\n"; - return 1 if ($simulate); - dprint("nice -10 $tiffloader $basedir/$filename 2>/dev/null | nice -10 $quantizer 2 2 2>/dev/null | nice -10 $scaler $scaleopt 2>/dev/null | nice -10 $pngwriter > $dest_base_dir/$newfn 2>/dev/null\n"); - if (system("nice -10 $tiffloader $basedir/$filename 2>/dev/null | nice -10 $quantizer 2 2 2>/dev/null | nice -10 $scaler $scaleopt 2>/dev/null | nice -10 $pngwriter > $dest_base_dir/$newfn 2>/dev/null") != 0) { + } else { + # quick ident failed -- do it slowly + + ($pictype, $picwidth, $picheight, $bitdepth) = identify("$srcdir/$filename"); + if ((! $pictype)||($picwidth == 0)||($picheight == 0)) { + logger('WARNING', "unknown file type '$srcdir/$filename'"); return 0; } - chmod $file_perm, "$dest_base_dir/$newfn" or - print "WARNING: unable to set permission on '$newfn'\n;"; - return 1; } - print "WARNING: unknown file type: '$basedir/$filename'\n;"; - return 0; -} + # collect arguments for the conversion + my %args; + $args{'srcdir'} = $srcdir; + $args{'destdir'} = $destdir; + $args{'filename'} = $filename; + $args{'pictype'} = $pictype; + $args{'picwidth'} = $picwidth; + $args{'picheight'} = $picheight; + $args{'bitdepth'} = $bitdepth; + $args{'srcdir'} = $srcdir; + $args{'scalesize'} = $scalesize; + $args{'scale_rel'} = $scale_relative; + + # decide conversion based on image type and encoding preferences + if ($pictype eq 'JPEG') { + $args{'jpeg_qual'} = $jpeg_quality; + #default encoder + $error = scale_jpeg(\%args); + } elsif ($pictype eq 'TIFF') { + if ($use_encoder) { + # use specific encoder + if ($use_encoder eq 'tiff_jpeg') { + $error = scale_tiff_jpeg(\%args); + } elsif ($use_encoder eq 'tiff_jpeg2') { + $error = scale_tiff_jpeg2(\%args); + } elsif ($use_encoder eq 'tiff_png') { + $error = scale_tiff_png(\%args); + } + } else { + # default + $error = scale_tiff_jpeg(\%args); + } + } else { + logger('WARNING', "unknown file type: $pictype ($srcdir/$filename)"); + } + return $error; +} # @@ -315,14 +674,12 @@ sub convert_file { # Descend recursively through $dirname and work on all files # sub walk_convert_dir { - my($workdir) = @_; + my($srcdir, $workdir, $destdir) = @_; my $errcnt = 0; my $newfn; - my $basedir = findir(\@source_base_dirs, $workdir); - - opendir WORKDIR, "$basedir/$workdir" or do { - print "ERROR: Unable to open directory $basedir/$workdir!\n"; + opendir WORKDIR, "$srcdir/$workdir" or do { + logger('ERROR', "Unable to open directory $srcdir/$workdir!"); return 0; }; @@ -332,47 +689,41 @@ sub walk_convert_dir { if ($do_descend) { foreach (sort @dirlist) { - if (/^[.]+$/) { - next; - } - if (-d "$basedir/$workdir/$_") { - walk_convert_dir("$workdir/$_"); + next if (/^[.]+$/); + next if ($junk_files{$_}); + if (-d "$srcdir/$workdir/$_") { + walk_convert_dir($srcdir, "$workdir/$_", $destdir); } } } - print "INFO: Working on $workdir\n"; - print "INFO: Reading from $basedir.\n"; - print "INFO: Writing to $dest_base_dir\n"; + logger('INFO', "Working on $workdir"); + logger('INFO', "Reading from $srcdir/$workdir."); + logger('INFO', "Writing to $destdir/$workdir"); + # create destination directory if (not ($simulate)) { - mmkdir("$dest_base_dir/$workdir") or do { - print "ERROR: unable to create directory '$dest_base_dir/$workdir'\n;"; + mmkdir("$destdir/$workdir") or do { + logger("ERROR", "unable to create directory '$destdir/$workdir'"); $errcnt++; return 0; }; - if ($dont_overwrite == 0) { - foreach (@imgfile_ext) { - system("rm -f $dest_base_dir/$workdir/*.$_"); - } - } } - + foreach (sort @dirlist) { + # skip dot-directories if (/^[.]+.*$/) { next; } - if (-f "$basedir/$workdir/$_") { - if (convert_file($basedir, "$workdir/$_") == 0) { - $errcnt++; - } + if (-f "$srcdir/$workdir/$_") { + $errcnt += convert_file("$srcdir/$workdir", "$_", "$destdir/$workdir"); } } if ($errcnt) { - print "INFO: There were errors converting $workdir!\n"; + logger('INFO', "There were $errcnt errors converting '$workdir'!"); } else { - print "INFO: Finished converting $workdir!\n"; + logger('INFO', "Finished converting $workdir!"); } return 1; @@ -385,20 +736,18 @@ sub walk_convert_dir { # Convert directory "from_dir" and its subdirectories # sub convert_dir { - my ($workdir) = @_; + my ($srcdir, $workdir, $destdir) = @_; - print "INFO: ** Converting Scans **\n"; - print "INFO: Starting in directory '$workdir'\n"; + logger('INFO', "** Converting Scans **"); + logger('INFO', "Starting in directory '$srcdir/$workdir'"); - dir_ok($workdir) or die("ABORT: Illegal directory name '$workdir'!\n"); - - walk_convert_dir($workdir); + walk_convert_dir($srcdir, $workdir, $destdir); # touch source directory so digilib rescans the thumbnails - #print "DEBUG:/usr/bin/touch $source_base_dirs[0]/$workdir\n"; - system("/usr/bin/touch $source_base_dirs[0]/$workdir"); + #logger('DEBUG', "/usr/bin/touch $source_base_dirs[0]/$workdir"); + system("/usr/bin/touch '$srcdir/$workdir'"); - print "DONE: ** Finished converting scans **\n"; + logger('DONE', "** Finished converting scans **"); return 1; } @@ -410,55 +759,73 @@ sub convert_dir { ############################################################### ## Main -if ($#ARGV < 0) { +if ($#ARGV < 3) { print "Scale-O-Mat $version\n"; - print " use: scaleomat.pl hires-dir dest-base size [quality] [--replace]\n"; - print " - if hires-dir starts with '/' then it's absolute.\n"; - print " - if size starts with 'x' then it's magnification factor.\n"; - print " - quality is JPEG quality (0-100)\n"; - print " - --replace replaces existing files (default=skip).\n"; + print " use: scaleomat.pl -src=src-base -dest=dest-base -dir=workdir [...]\n"; + print " reads from scr-base/workdir and writes to dest-base/workdir\n"; + print " -scaleto=destination size\n"; + print " -scaleby=magnification factor.\n"; + print " -jpegqual=JPEG quality (0-100)\n"; + print " -replace=yes replaces existing files (default=skip).\n"; + print " -encoder=tiff_png|tiff_jpeg|tiff_jpeg2\n"; exit 1; } # test software installation -checksoft; +checksoft(); + +# read command line parameters +my $args = parseargs(); + +# source dir +my $srcdir = $$args{'src'}; -# parameter 1 is destination dir -if ($#ARGV > 0) { - $dest_base_dir = $ARGV[1]; +# destination dir +my $destdir = $$args{'dest'}; + +# working dir +my $workdir = $$args{'dir'}; + +# destination size +if ($$args{'scaleby'}) { + $scale_relative = 1; + $scalesize = $$args{'scaleby'}; + logger('INFO', "Scaling relative by factor $scalesize"); +} +if ($$args{'scaleto'}) { + $scale_relative = 0; + $scalesize = $$args{'scaleto'}; + logger('INFO', "Scaling absolute to size $scalesize"); } -# parameter 2 is destination size (or factor when starting with "x") -if ($#ARGV > 1) { - if ($ARGV[2] =~ /^x([\d.]+)/) { - $scale_relative = 1; - $target_size = $1; - print "INFO: scaling relative by factor $target_size\n"; - } else { - $scale_relative = 0; - $target_size = $ARGV[2]; - print "INFO: scaling absolute to size $target_size\n"; - } +# JPEG quality +if ($$args{'jpegqual'}) { + logger('INFO', "JPEG quality set to '$$args{'jpegqual'}'!"); + $jpeg_quality = $$args{'jpegqual'}; } -# optional parameters are JPEG quality or --replace -if ($#ARGV > 2) { - for ($i = 3; $i <= $#ARGV; $i++) { - $s = $ARGV[$i]; - if ($s eq "--replace") { - print "INFO: set to overwrite existing files!\n"; - $dont_overwrite = 0; - } else { - print "INFO: JPEG quality set to '$s'!\n"; - $jpeg_quality = $s; - } - } +# force encoder +if ($$args{'encoder'}) { + logger('INFO', "Using encoder '$$args{'encoder'}'!"); + $use_encoder = $$args{'encoder'}; +} + +# Overwrite +if ($$args{'replace'}) { + logger('INFO', "Set to overwrite existing files!"); + $overwrite = 1; } -# convert all files in the directory -my $srcdir = $ARGV[0]; -if ($srcdir =~ /^\//) { - # if source dir starts with / then ist's absolute - $source_base_dirs[0] = "/"; +# debug +if ($$args{'debug'}) { + logger('INFO', "Set debug level to $$args{'debug'}!"); + $debug = $$args{'debug'}; } -convert_dir($srcdir); + +# simulate +if ($$args{'simulate'}) { + logger('INFO', "Set to simulate operation only ($$args{'simulate'})!"); + $simulate = $$args{'simulate'}; +} + +convert_dir($srcdir, $workdir, $destdir);