--- scaleomat/scaleomat.pl 2004/12/06 10:02:54 1.6 +++ scaleomat/scaleomat.pl 2005/01/05 17:55:34 1.7 @@ -24,7 +24,7 @@ use MPIWGlib; $| = 1; # unblock IO -my $version = "V0.9.4 (ROC 6.12.2004)"; +my $version = "V0.9.5 (ROC 5.1.2005)"; $debug = 0; @@ -46,7 +46,8 @@ my %img_type_ext = ("tif" => "TIFF", "ti my %target_ext_type = ("TIFF" => "jpg", "JPEG" => "jpg"); # default scale settings -my $scalesize = 2048; # pixel of longest side +my $scale_w = 2048; # width in pixel +my $scale_h = 2048; # height in pixel 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 @@ -213,12 +214,14 @@ sub identify { my $bitdepth = 0; # use quickident first $pictype = quickident($filepath); - # optimize tiff identification + # optimized tiff identification if (($pictype)&&($pictype eq 'TIFF')) { logger('DEBUG', "running tiffinfo $tiffinfo"); if (open(IDENT, "nice -10 $tiffinfo '$filepath' 2>/dev/null |")) { while () { chomp; + # we take the biggest values, because embedded thumbnails + # may also show up if (/Image Width:\s*(\d+)\s*Image Length:\s*(\d+)/) { $picwidth = $1 if ($1 > $picwidth); $picheight = $2 if ($2 > $picheight); @@ -270,68 +273,106 @@ sub quickident { # -# $error = scale_jpeg(\$args); -# -# scale JPEG images to JPEG using netpbm tools -# -# args needed: $srcdir, $filename, $destdir, -# $scalesize, $scale_rel, $picwidth, $picheight +# $fact = scalefactor(\$args) # -sub scale_jpeg { +sub scalefactor { my ($args) = @_; my $srcdir = $$args{'srcdir'}; my $filename = $$args{'filename'}; - my $destdir = $$args{'destdir'}; - my $scalesize = $$args{'scalesize'}; + my $scale_w = $$args{'scale_w'}; + my $scale_h = $$args{'scale_h'}; 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); + my $scale = 0; if ($scale_rel) { # scale relative -- no size needed, only scaling factor - $scaleopt = $scalesize; + $scale = $scale_w; } else { # scale to size -- size needed my $pictype = $$args{'pictype'}; my $picwidth = $$args{'picwidth'}; my $picheight = $$args{'picheight'}; if (! $picwidth) { + # no size yet - identify ($pictype, $picwidth, $picheight) = identify("$srcdir/$filename"); if ((! $pictype)||($picwidth == 0)||($picheight == 0)) { logger('ERROR', "unable to identify $srcdir/$filename!"); - return 1; + return 0; } - } - if ($picheight > $picwidth) { - $scaleopt = $scalesize / $picheight; - logger('DEBUG', "PIC is portrait"); + # save values + $$args{'pictype'} = $pictype; + $$args{'picwidth'} = $picwidth; + $$args{'picheight'} = $picheight; + } + # calculate x and y scaling factors + my $scale_x = $scale_w / $picwidth; + my $scale_y = $scale_h / $picheight; + # take the smallest + if ($scale_x < $scale_y) { + $scale = $scale_x; + logger('DEBUG', "PIC scale to width"); } else { - $scaleopt = $scalesize / $picwidth; - logger('DEBUG', "PIC is landscape"); + $scale = $scale_y; + logger('DEBUG', "PIC scale to height"); } - if ($scaleopt >= 1) { - $scaleopt = 1; + if ($scale >= 1) { + $scale = 1; logger('DEBUG', "PIC is already smaller"); + # continue since we may have to convert } } + return $scale; +} + + +# +# $error = scale_jpeg(\$args); +# +# scale JPEG images to JPEG using netpbm tools +# +# args needed: $srcdir, $filename, $destdir, +# $scale_w, $scale_h, $scale_rel, $picwidth, $picheight +# +sub scale_jpeg { + my ($args) = @_; + + my $srcdir = $$args{'srcdir'}; + my $filename = $$args{'filename'}; + my $destdir = $$args{'destdir'}; + my $scale_w = $$args{'scale_w'}; + my $scale_h = $$args{'scale_h'}; + 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); + + $scaleopt = scalefactor($args); if (!$scaleopt) { logger('ERROR', "unable to calculate scaling options!"); return 1; } + if ($scaleopt = 1) { + # is already smaller + return 0; + } + # 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"; + if (! -s "$destdir/$newfn") { + # file broken (size 0) + logger('ERROR', "created file '$destdir/$newfn' broken -- will be removed!"); + unlink "$destdir/$newfn"; + } return 1; } @@ -355,7 +396,7 @@ sub scale_jpeg { # scale TIFF images to JPEG using ImageMagick convert # # args needed: $srcdir, $filename, $destdir, -# $scalesize, $scale_rel, $picwidth, $picheight +# $scale_w, $scale_h, $scale_rel, $picwidth, $picheight # sub scale_tiff_jpeg2 { my ($args) = @_; @@ -363,50 +404,17 @@ sub scale_tiff_jpeg2 { my $srcdir = $$args{'srcdir'}; my $filename = $$args{'filename'}; my $destdir = $$args{'destdir'}; - my $scalesize = $$args{'scalesize'}; + my $scale_w = $$args{'scale_w'}; + my $scale_h = $$args{'scale_h'}; 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; - } - } - 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; + my $per_scale = 100 * $scale_w; 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) { @@ -414,10 +422,15 @@ sub scale_tiff_jpeg2 { return 1; } } else { - logger('DEBUG', "nice -10 $converter -quality $jpeg_quality -scale ${scalesize}x${scalesize} '$srcdir/$filename' '$destdir/$newfn' 2>/dev/null"); + logger('DEBUG', "nice -10 $converter -quality $jpeg_quality -scale ${scale_w}x${scale_h} '$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) { + if (system("nice -10 $converter -quality $jpeg_quality -scale ${scale_w}x${scale_h} '$srcdir/$filename' '$destdir/$newfn' 2>/dev/null\n") != 0) { logger('ERROR', "error converting '$srcdir/$filename'!"); + if (! -s "$destdir/$newfn") { + # file broken (size 0) + logger('ERROR', "created file '$destdir/$newfn' broken -- will be removed!"); + unlink "$destdir/$newfn"; + } return 1; } } @@ -426,12 +439,6 @@ sub scale_tiff_jpeg2 { 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; } @@ -442,7 +449,7 @@ sub scale_tiff_jpeg2 { # scale TIFF images to JPEG using netpbm tools # # args needed: $srcdir, $filename, $destdir, -# $scalesize, $scale_rel, $picwidth, $picheight +# $scale_w, $scale_h, $scale_rel, $picwidth, $picheight # sub scale_tiff_jpeg { my ($args) = @_; @@ -450,7 +457,9 @@ sub scale_tiff_jpeg { my $srcdir = $$args{'srcdir'}; my $filename = $$args{'filename'}; my $destdir = $$args{'destdir'}; - my $scalesize = $$args{'scalesize'}; + my $bitdepth = $$args{'bitdepth'}; + my $scale_w = $$args{'scale_w'}; + my $scale_h = $$args{'scale_h'}; my $scale_rel = $$args{'scale_rel'}; my $scaleopt; @@ -460,33 +469,7 @@ sub scale_tiff_jpeg { 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 { - $scaleopt = $scalesize / $picwidth; - logger('DEBUG', "PIC is landscape"); - } - if ($scaleopt >= 1) { - $scaleopt = 1; - logger('DEBUG', "PIC is already smaller"); - } - } + $scaleopt = scalefactor($args); if (!$scaleopt) { logger('ERROR', "unable to calculate scaling options!"); @@ -494,11 +477,21 @@ sub scale_tiff_jpeg { } # 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"); + 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 $jpegwriter --quality $jpeg_quality > '$destdir/$newfn' 2>/dev/null"; + logger('DEBUG', "$cmd"); 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) { + if (system($cmd) != 0) { logger('ERROR', "error converting '$srcdir/$filename'!"); - unlink "$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; } @@ -506,12 +499,6 @@ sub scale_tiff_jpeg { 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; } @@ -523,7 +510,7 @@ sub scale_tiff_jpeg { # scale TIFF images to PNG using netpbm tools # # args needed: $srcdir, $filename, $destdir, -# $scalesize, $scale_rel, $picwidth, $picheight +# $scale_w, $scale_h, $scale_rel, $picwidth, $picheight # sub scale_tiff_png { my ($args) = @_; @@ -531,43 +518,18 @@ sub scale_tiff_png { my $srcdir = $$args{'srcdir'}; my $filename = $$args{'filename'}; my $destdir = $$args{'destdir'}; - my $scalesize = $$args{'scalesize'}; my $bitdepth = $$args{'bitdepth'}; + my $scale_w = $$args{'scale_w'}; + my $scale_h = $$args{'scale_h'}; my $scale_rel = $$args{'scale_rel'}; my $scaleopt; - # convert jpg -> jpg + # convert tif -> png 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; - } - } - 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"); - } - } + $scaleopt = scalefactor($args); if (!$scaleopt) { logger('ERROR', "unable to calculate scaling options!"); @@ -585,7 +547,11 @@ sub scale_tiff_png { return 0 if ($simulate); if (system($cmd) != 0) { logger('ERROR', "error converting '$srcdir/$filename'!"); - unlink "$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; } @@ -593,12 +559,6 @@ sub scale_tiff_png { 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; } @@ -648,8 +608,13 @@ sub convert_file { if (-f "$destdir/$newfn") { logger('DEBUG', "CONV file exists: $newfn"); if (! $overwrite) { - logger('INFO', "File already converted: $newfn"); - return 0; + # compare age with source file + if (-M "$destdir/$newfn" > -M "$srcdir/$filename") { + logger('DEBUG', "CONV file is older: $newfn"); + } else { + logger('INFO', "File already converted: $newfn"); + return 0; + } } } } else { @@ -674,7 +639,8 @@ sub convert_file { $args{'picheight'} = $picheight; $args{'bitdepth'} = $bitdepth; $args{'srcdir'} = $srcdir; - $args{'scalesize'} = $scalesize; + $args{'scale_w'} = $scale_w; + $args{'scale_h'} = $scale_h; $args{'scale_rel'} = $scale_relative; # decide conversion based on image type and encoding preferences @@ -774,13 +740,24 @@ sub convert_dir { my ($srcdir, $workdir, $destdir) = @_; logger('INFO', "** Converting Scans **"); - logger('INFO', "Starting in directory '$srcdir/$workdir'"); - - walk_convert_dir($srcdir, $workdir, $destdir); - - # touch source directory so digilib rescans the thumbnails - #logger('DEBUG', "/usr/bin/touch $source_base_dirs[0]/$workdir"); - system("/usr/bin/touch '$srcdir/$workdir'"); + + if (-d "$srcdir/$workdir") { + # it's a dirrectory + logger('INFO', "Starting in directory '$srcdir/$workdir'"); + walk_convert_dir($srcdir, $workdir, $destdir); + # touch source directory so digilib rescans the thumbnails + #logger('DEBUG', "/usr/bin/touch $source_base_dirs[0]/$workdir"); + system("/usr/bin/touch '$srcdir/$workdir'"); + } elsif (-f _) { + # it's a file + logger('INFO', "Converting file '$srcdir/$workdir'"); + convert_file($srcdir, $workdir, $destdir); + # touch source parent directory so digilib rescans the thumbnails + my $pdir = "$srcdir/$workdir"; + # chop off after the last slash + $pdir =~ s/\/[^\/]+$/\//; + system("/usr/bin/touch '$pdir'"); + } logger('DONE', "** Finished converting scans **"); return 1; @@ -798,7 +775,7 @@ if ($#ARGV < 3) { print "Scale-O-Mat $version\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 " -scaleto=destination size (S or WxH)\n"; print " -scaleby=magnification factor.\n"; print " -jpegqual=JPEG quality (0-100)\n"; print " -replace=yes replaces existing files (default=skip).\n"; @@ -824,13 +801,19 @@ my $workdir = cleanpath($$args{'dir'}); # destination size if ($$args{'scaleby'}) { $scale_relative = 1; - $scalesize = $$args{'scaleby'}; - logger('INFO', "Scaling relative by factor $scalesize"); + $scale_w = $$args{'scaleby'}; + logger('INFO', "Scaling relative by factor $scale_w"); } if ($$args{'scaleto'}) { $scale_relative = 0; - $scalesize = $$args{'scaleto'}; - logger('INFO', "Scaling absolute to size $scalesize"); + if ($$args{'scaleto'} =~ /(\d+)x(\d+)/) { + $scale_w = $1; + $scale_h = $2; + } else { + $scale_w = $$args{'scaleto'}; + $scale_h = $$args{'scaleto'}; + } + logger('INFO', "Scaling absolute to size $scale_w x $scale_h"); } # JPEG quality