Annotation of scaleomat/scaleomat.pl, revision 1.5
1.1 casties 1: #!/usr/bin/perl
2:
1.3 casties 3: # Copyright (C) 2003,2004 Robert Casties, IT-Group MPIWG
4: #
5: # This program is free software; you can redistribute it and/or modify it
6: # under the terms of the GNU General Public License as published by the Free
7: # Software Foundation; either version 2 of the License, or (at your option)
8: # any later version.
9: #
10: # Please read license.txt for the full details. A copy of the GPL may be found
11: # at http://www.gnu.org/copyleft/lgpl.html
12: #
13: # You should have received a copy of the GNU General Public License along with
14: # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15: # Place, Suite 330, Boston, MA 02111-1307 USA
16:
1.2 casties 17: use strict;
1.4 casties 18: use sigtrap qw(die normal-signals);
1.2 casties 19:
20: # MPIWG libraries
21: use lib '/usr/local/mpiwg/scripts';
22: use MPIWGlib;
23:
24:
1.1 casties 25: $| = 1; # unblock IO
26:
1.4 casties 27: my $version = "V0.9.3 (ROC 18.11.2004)";
1.1 casties 28:
29: $debug = 0;
30:
1.2 casties 31: my $simulate = 0;
32:
33: my $do_descend = 1;
1.1 casties 34:
1.2 casties 35: my $dir_perm = 0775;
36: my $file_perm = 0664;
1.1 casties 37:
38: umask 000; # to make shure we can actually use these perms
39:
1.2 casties 40: my $overwrite = 0; # overwrite already converted files
1.1 casties 41:
1.2 casties 42: # image file extensions and formats
43: my %img_type_ext = ("tif" => "TIFF", "tiff" => "TIFF", "gif" => "GIF",
44: "jpg" => "JPEG", "png" => "PNG");
45: # destination image file extensions
46: my %target_ext_type = ("TIFF" => "jpg", "JPEG" => "jpg");
47:
48: # default scale settings
49: my $scalesize = 2048; # pixel of longest side
50: my $scale_relative = 0; # scale by relative factor instead of destination size
51: my $jpeg_quality = 75; # default JPEG compression quality
52: my $use_encoder = 0; # autodetect encoder
53:
54: # programs to use
55: my $identifier;
56: my $tiffinfo;
57: my $jpegloader;
58: my $tiffloader;
59: my $quantizer;
60: my $scaler;
61: my $jpegwriter;
62: my $pngwriter;
63: my $converter;
1.1 casties 64:
65: ##########################################################################
66: # subroutines
67: #
68:
69: #
70: # checksoft()
71: #
72: # returns if all necessary external programs are installed
73: #
74: sub checksoft {
75:
76: my @softdirs = ("/usr/X11R6/bin", "/usr/bin", "/usr/local/bin");
77:
78: $identifier = findfile(\@softdirs, "identify")
79: or die("ABORT: neccessary external program not found: identify");
1.2 casties 80: $tiffinfo = findfile(\@softdirs, "tiffinfo")
81: or die("ABORT: neccessary external program not found: tiffinfo");
1.1 casties 82: $jpegloader = findfile(\@softdirs, "jpegtopnm")
83: or die("ABORT: neccessary external program not found: jpegtopnm");
84: $tiffloader = findfile(\@softdirs, "tifftopnm")
85: or die("ABORT: neccessary external program not found: tifftopnm");
86: $quantizer = findfile(\@softdirs, "pbmtopgm")
87: or die("ABORT: neccessary external program not found: pbmtopgm");
88: $scaler = findfile(\@softdirs, "pnmscale")
89: or die("ABORT: neccessary external program not found: pnmscale");
90: $jpegwriter = findfile(\@softdirs, "ppmtojpeg")
91: or die("ABORT: neccessary external program not found: ppmtojpeg");
92: $pngwriter = findfile(\@softdirs, "pnmtopng")
93: or die("ABORT: neccessary external program not found: pnmtopng");
94: $converter = findfile(\@softdirs, "convert")
95: or die("ABORT: neccessary external program not found: convert");
96:
97: }
98:
99:
100:
101: #
102: # findir(\@basedirs, $subdir)
103: #
104: # check directories in @basedirs+$subdir and return the first existing basedir
105: #
106: sub findir {
107: my($dirlist, $subdir) = @_;
108:
109: foreach my $dir (@$dirlist) {
110: if (-d "$dir/$subdir") {
111: return "$dir";
112: }
113: }
114: return;
115: }
116:
117: #
118: # findfile(\@basedirs, $filename)
119: #
120: # check @basedirs+$filename and return the first existing file
121: #
122: sub findfile {
123: my($dirlist, $fn) = @_;
124:
125: foreach my $dir (@$dirlist) {
126: if (-f "$dir/$fn") {
127: return "$dir/$fn";
128: }
129: }
130: return;
131: }
132:
1.5 ! casties 133: #
! 134: # $p = cleanpath($path, $startslash).
! 135: #
! 136: # returns a pathname with trailing and starting slash removed (if
! 137: # $startslash is true the starting slash is not removed)
! 138: #
1.4 casties 139: sub cleanpath {
140: my ($path, $startslash) = @_;
141:
142: if ($path =~ /^(\/)*(.*?)\/*$/) {
143: if ($startslash) {
144: return $1 . $2;
145: } else {
146: return $2;
147: }
148: }
149: return $path;
150: }
151:
1.1 casties 152: #
1.2 casties 153: # ($basename, $extension) = splitfn($filename)
154: #
155: # split filename into base and (lowercase) extension
156: #
157: sub splitfn {
158: my ($filepath) = @_;
159: if ($filepath =~ /^(.*)\.(\w+)$/) {
160: return ($1, lc($2));
161: }
162: return;
163: }
164:
165:
166: #
1.1 casties 167: # mmkdir($dirname)
168: #
169: # create directory recursively and check permissions
170: #
171: sub mmkdir {
172: my($dirname) = @_;
173: my $newdir;
174:
175: # does the directory already exist?
1.2 casties 176: if (-d $dirname) {
177: chmod $dir_perm, $dirname or do {
1.4 casties 178: logger('WARNING', "unable to change permission on $dirname!");
1.1 casties 179: };
180: return 1;
181: }
182: # split directory name by levels
183: my @dirlist = split /\//, $dirname;
184: my @newlist = ();
185: my $dir = join("/", @dirlist);
186: # test backwards which directories exist
187: while (not -d $dir) {
1.2 casties 188: last unless ($dir);
1.1 casties 189: # move missing elements from the end of @dirlist to @newlist
190: unshift @newlist, pop @dirlist;
191: $dir = join("/", @dirlist);
192: }
193: # create missing directories level by level
194: foreach $newdir (@newlist) {
195: push @dirlist, $newdir;
196: $dir = join("/", @dirlist);
197: mkdir "$dir", $dir_perm or do {
1.2 casties 198: logger('ERROR', "unable to create $dir!");
1.1 casties 199: return 0;
200: }
201: }
202: return 1;
203: }
204:
205: #
1.2 casties 206: # ($type, $width, $height) = identify($filepath)
207: #
208: sub identify {
209: my ($filepath) = @_;
1.4 casties 210: my $pictype = "";
211: my $picwidth = 0;
212: my $picheight = 0;
1.2 casties 213: my $bitdepth = 0;
214: # use quickident first
215: $pictype = quickident($filepath);
216: # optimize tiff identification
217: if (($pictype)&&($pictype eq 'TIFF')) {
218: logger('DEBUG', "running tiffinfo $tiffinfo");
219: if (open(IDENT, "nice -10 $tiffinfo '$filepath' 2>/dev/null |")) {
220: while (<IDENT>) {
221: chomp;
222: if (/Image Width:\s*(\d+)\s*Image Length:\s*(\d+)/) {
1.4 casties 223: $picwidth = $1 if ($1 > $picwidth);
224: $picheight = $2 if ($2 > $picheight);
1.2 casties 225: next;
226: }
227: if (/Bits\/Sample:\s*(\d+)/) {
1.4 casties 228: $bitdepth = $1 if ($1 > $bitdepth);
1.2 casties 229: next;
230: }
231: }
232: if ($picwidth) {
1.4 casties 233: logger('DEBUG', "TIFF $picwidth x $picheight");
1.2 casties 234: return ($pictype, $picwidth, $picheight, $bitdepth);
235: }
236: }
237: }
238: # run ident to get image type and dimensions
239: logger('DEBUG', "running identifier $identifier");
240: if (open(IDENT, "nice -10 $identifier -ping -format '%w %h %m\n' '$filepath' 2>/dev/null |")) {
241: my @id = <IDENT>;
242: my $picinfo = $id[0];
243: close IDENT;
244: chomp $picinfo;
245: logger('DEBUG', "PIC is '$picinfo'");
246: if ($picinfo =~ /^(\d+) (\d+) (\w+)$/) {
247: $picwidth = $1;
248: $picheight = $2;
249: $pictype = $3;
250: }
251: } else {
252: logger('DEBUG', "unable to identify $filepath!");
253: }
254: return ($pictype, $picwidth, $picheight, $bitdepth);
255: }
256:
257: #
258: # $type = quickident($filepath);
259: #
260: sub quickident {
261: my ($filepath) = @_;
262: logger('DEBUG', "running quickident");
263: # look at file extension
264: my ($filebase, $fileext) = splitfn($filepath);
265: if ($fileext) {
266: return $img_type_ext{$fileext};
267: }
268: return;
269: }
270:
271:
272: #
273: # $error = scale_jpeg(\$args);
274: #
275: # scale JPEG images to JPEG using netpbm tools
1.1 casties 276: #
1.2 casties 277: # args needed: $srcdir, $filename, $destdir,
278: # $scalesize, $scale_rel, $picwidth, $picheight
1.1 casties 279: #
1.2 casties 280: sub scale_jpeg {
281: my ($args) = @_;
282:
283: my $srcdir = $$args{'srcdir'};
284: my $filename = $$args{'filename'};
285: my $destdir = $$args{'destdir'};
286: my $scalesize = $$args{'scalesize'};
287: my $scale_rel = $$args{'scale_rel'};
288: my $scaleopt;
289:
290: # convert jpg -> jpg
291: my ($basename, $fileext) = splitfn($filename);
292: my $newfn = $basename . ".jpg";
293: logger('INFO', "Convert(jpg): $filename -> $newfn");
294: return 1 if ($simulate);
295:
296: if ($scale_rel) {
297: # scale relative -- no size needed, only scaling factor
298: $scaleopt = $scalesize;
299: } else {
300: # scale to size -- size needed
301: my $pictype = $$args{'pictype'};
302: my $picwidth = $$args{'picwidth'};
303: my $picheight = $$args{'picheight'};
304: if (! $picwidth) {
305: ($pictype, $picwidth, $picheight) = identify("$srcdir/$filename");
306: if ((! $pictype)||($picwidth == 0)||($picheight == 0)) {
307: logger('ERROR', "unable to identify $srcdir/$filename!");
308: return 1;
309: }
310: }
311: if ($picheight > $picwidth) {
312: $scaleopt = $scalesize / $picheight;
313: logger('DEBUG', "PIC is portrait");
314: } else {
315: $scaleopt = $scalesize / $picwidth;
316: logger('DEBUG', "PIC is landscape");
317: }
318: if ($scaleopt >= 1) {
319: $scaleopt = 1;
320: logger('DEBUG', "PIC is already smaller");
321: }
322: }
1.1 casties 323:
1.2 casties 324: if (!$scaleopt) {
325: logger('ERROR', "unable to calculate scaling options!");
326: return 1;
1.1 casties 327: }
1.2 casties 328:
329: # convert
330: 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");
331: return 0 if ($simulate);
332: 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) {
333: logger('ERROR', "error converting '$srcdir/$filename'!");
334: unlink "$destdir/$newfn";
335: return 1;
1.1 casties 336: }
1.2 casties 337:
338: # change permissions
339: chmod $file_perm, "$destdir/$newfn" or
340: logger('WARNING', "unable to set permission on '$destdir/$newfn'");
341:
342: if (! -s "$destdir/$newfn") {
343: # file broken (size 0)
344: logger('ERROR', "created file '$destdir/$newfn' broken -- will be removed!");
345: unlink "$destdir/$newfn";
346: return 1;
1.1 casties 347: }
1.2 casties 348: return 0;
1.1 casties 349: }
350:
351:
352: #
1.2 casties 353: # $error = scale_tiff_jpeg2(\$args);
354: #
355: # scale TIFF images to JPEG using ImageMagick convert
1.1 casties 356: #
1.2 casties 357: # args needed: $srcdir, $filename, $destdir,
358: # $scalesize, $scale_rel, $picwidth, $picheight
1.1 casties 359: #
1.2 casties 360: sub scale_tiff_jpeg2 {
361: my ($args) = @_;
362:
363: my $srcdir = $$args{'srcdir'};
364: my $filename = $$args{'filename'};
365: my $destdir = $$args{'destdir'};
366: my $scalesize = $$args{'scalesize'};
367: my $scale_rel = $$args{'scale_rel'};
368: my $scaleopt;
369:
370: my ($basename, $fileext) = splitfn($filename);
371: my $newfn = $basename . ".jpg";
372: logger('INFO', "Convert(tiff2): $filename -> $newfn");
373: return 1 if ($simulate);
374:
375: if ($scale_rel) {
376: # scale relative -- no size needed, only scaling factor
377: $scaleopt = $scalesize;
378: } else {
379: # scale to size -- size needed
380: my $pictype = $$args{'pictype'};
381: my $picwidth = $$args{'picwidth'};
382: my $picheight = $$args{'picheight'};
383: if (! $picwidth) {
384: ($pictype, $picwidth, $picheight) = identify("$srcdir/$filename");
385: if ((! $pictype)||($picwidth == 0)||($picheight == 0)) {
386: logger('ERROR', "unable to identify $srcdir/$filename!");
387: return 1;
388: }
389: }
390: if ($picheight > $picwidth) {
391: $scaleopt = $scalesize / $picheight;
392: logger('DEBUG', "PIC is portrait");
393: } else {
394: $scaleopt = $scalesize / $picwidth;
395: logger('DEBUG', "PIC is landscape");
396: }
397: if ($scaleopt >= 1) {
398: $scaleopt = 1;
399: logger('DEBUG', "PIC is already smaller");
400: }
401: }
1.1 casties 402:
1.2 casties 403: if (!$scaleopt) {
404: logger('ERROR', "unable to calculate scaling options!");
405: return 1;
1.1 casties 406: }
407:
1.2 casties 408: if ($scale_rel) {
409: my $per_scale = 100 * $scaleopt;
410: logger('DEBUG', "nice -10 $converter -quality $jpeg_quality -scale $per_scale\% '$srcdir/$filename' '$destdir/$newfn' 2>/dev/null");
411: return 0 if ($simulate);
412: if (system("nice -10 $converter -quality $jpeg_quality -scale $per_scale\% '$srcdir/$filename' '$destdir/$newfn' 2>/dev/null\n") != 0) {
413: logger('ERROR', "error converting '$srcdir/$filename'!");
414: return 1;
415: }
416: } else {
417: logger('DEBUG', "nice -10 $converter -quality $jpeg_quality -scale ${scalesize}x${scalesize} '$srcdir/$filename' '$destdir/$newfn' 2>/dev/null");
418: return 0 if ($simulate);
419: if (system("nice -10 $converter -quality $jpeg_quality -scale ${scalesize}x${scalesize} '$srcdir/$filename' '$destdir/$newfn' 2>/dev/null\n") != 0) {
420: logger('ERROR', "error converting '$srcdir/$filename'!");
421: return 1;
1.1 casties 422: }
423: }
1.2 casties 424:
425: # change permissions
426: chmod $file_perm, "$destdir/$newfn" or
427: logger('WARNING', "unable to set permission on '$destdir/$newfn'");
428:
429: if (! -s "$destdir/$newfn") {
430: # file broken (size 0)
431: logger('ERROR', "created file '$destdir/$newfn' broken -- will be removed!");
432: unlink "$destdir/$newfn";
433: return 1;
434: }
435: return 0;
436: }
437:
438:
439: #
440: # $error = scale_tiff_jpeg(\$args);
441: #
442: # scale TIFF images to JPEG using netpbm tools
443: #
444: # args needed: $srcdir, $filename, $destdir,
445: # $scalesize, $scale_rel, $picwidth, $picheight
446: #
447: sub scale_tiff_jpeg {
448: my ($args) = @_;
449:
450: my $srcdir = $$args{'srcdir'};
451: my $filename = $$args{'filename'};
452: my $destdir = $$args{'destdir'};
453: my $scalesize = $$args{'scalesize'};
454: my $scale_rel = $$args{'scale_rel'};
455: my $scaleopt;
456:
457: # convert jpg -> jpg
458: my ($basename, $fileext) = splitfn($filename);
459: my $newfn = $basename . ".jpg";
460: logger('INFO', "Convert(tiff1): $filename -> $newfn");
461: return 1 if ($simulate);
462:
463: if ($scale_rel) {
464: # scale relative -- no size needed, only scaling factor
465: $scaleopt = $scalesize;
466: } else {
467: # scale to size -- size needed
468: my $pictype = $$args{'pictype'};
469: my $picwidth = $$args{'picwidth'};
470: my $picheight = $$args{'picheight'};
471: if (! $picwidth) {
472: ($pictype, $picwidth, $picheight) = identify("$srcdir/$filename");
473: if ((! $pictype)||($picwidth == 0)||($picheight == 0)) {
474: logger('ERROR', "unable to identify $srcdir/$filename!");
1.1 casties 475: return 1;
476: }
477: }
1.2 casties 478: if ($picheight > $picwidth) {
479: $scaleopt = $scalesize / $picheight;
480: logger('DEBUG', "PIC is portrait");
481: } else {
482: $scaleopt = $scalesize / $picwidth;
483: logger('DEBUG', "PIC is landscape");
484: }
485: if ($scaleopt >= 1) {
486: $scaleopt = 1;
487: logger('DEBUG', "PIC is already smaller");
1.1 casties 488: }
1.2 casties 489: }
490:
491: if (!$scaleopt) {
492: logger('ERROR', "unable to calculate scaling options!");
1.1 casties 493: return 1;
494: }
495:
1.2 casties 496: # convert
497: 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");
498: return 0 if ($simulate);
499: 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) {
500: logger('ERROR', "error converting '$srcdir/$filename'!");
501: unlink "$destdir/$newfn";
502: return 1;
503: }
504:
505: # change permissions
506: chmod $file_perm, "$destdir/$newfn" or
507: logger('WARNING', "unable to set permission on '$destdir/$newfn'");
508:
509: if (! -s "$destdir/$newfn") {
510: # file broken (size 0)
511: logger('ERROR', "created file '$destdir/$newfn' broken -- will be removed!");
512: unlink "$destdir/$newfn";
513: return 1;
514: }
515: return 0;
516: }
517:
518:
519:
520: #
521: # $error = scale_tiff_png(\$args);
522: #
523: # scale TIFF images to PNG using netpbm tools
524: #
525: # args needed: $srcdir, $filename, $destdir,
526: # $scalesize, $scale_rel, $picwidth, $picheight
527: #
528: sub scale_tiff_png {
529: my ($args) = @_;
530:
531: my $srcdir = $$args{'srcdir'};
532: my $filename = $$args{'filename'};
533: my $destdir = $$args{'destdir'};
534: my $scalesize = $$args{'scalesize'};
535: my $bitdepth = $$args{'bitdepth'};
536: my $scale_rel = $$args{'scale_rel'};
537: my $scaleopt;
538:
539: # convert jpg -> jpg
540: my ($basename, $fileext) = splitfn($filename);
541: my $newfn = $basename . ".png";
542: logger('INFO', "Convert(tiff3): $filename -> $newfn");
543:
544: if ($scale_rel) {
545: # scale relative -- no size needed, only scaling factor
546: $scaleopt = $scalesize;
547: } else {
548: # scale to size -- size needed
549: my $pictype = $$args{'pictype'};
550: my $picwidth = $$args{'picwidth'};
551: my $picheight = $$args{'picheight'};
552: if (! $picwidth) {
553: ($pictype, $picwidth, $picheight, $bitdepth) = identify("$srcdir/$filename");
554: if ((! $pictype)||($picwidth == 0)||($picheight == 0)) {
555: logger('ERROR', "unable to identify $srcdir/$filename!");
1.1 casties 556: return 1;
557: }
558: }
1.2 casties 559: if ($picheight > $picwidth) {
560: $scaleopt = $scalesize / $picheight;
561: logger('DEBUG', "PIC is portrait");
1.1 casties 562: } else {
1.2 casties 563: $scaleopt = $scalesize / $picwidth;
564: logger('DEBUG', "PIC is landscape");
565: }
566: if ($scaleopt >= 1) {
567: $scaleopt = 1;
568: logger('DEBUG', "PIC is already smaller");
1.1 casties 569: }
1.2 casties 570: }
571:
572: if (!$scaleopt) {
573: logger('ERROR', "unable to calculate scaling options!");
1.1 casties 574: return 1;
575: }
576:
1.2 casties 577: # convert
578: my $cmd = "nice -10 $tiffloader \'$srcdir/$filename\' 2>/dev/null ";
579: if ($bitdepth == 1) {
580: # antialiasing bilevel images
581: $cmd .= "| nice -10 $quantizer 2 2 2>/dev/null ";
582: }
583: $cmd .= "| nice -10 $scaler $scaleopt 2>/dev/null | nice -10 $pngwriter > '$destdir/$newfn' 2>/dev/null";
584: logger('DEBUG', "$cmd");
585: return 0 if ($simulate);
586: if (system($cmd) != 0) {
587: logger('ERROR', "error converting '$srcdir/$filename'!");
588: unlink "$destdir/$newfn";
589: return 1;
590: }
591:
592: # change permissions
593: chmod $file_perm, "$destdir/$newfn" or
594: logger('WARNING', "unable to set permission on '$destdir/$newfn'");
595:
596: if (! -s "$destdir/$newfn") {
597: # file broken (size 0)
598: logger('ERROR', "created file '$destdir/$newfn' broken -- will be removed!");
599: unlink "$destdir/$newfn";
600: return 1;
601: }
602: return 0;
603: }
604:
605:
606: #
607: # $error = convert_file($srcdir, $filename, $destdir);
608: #
609: # convert file
610: #
611: sub convert_file {
612: my($srcdir, $filename, $destdir) = @_;
613: my $filebase;
614: my $fileext;
615: my $newfn;
616: my $pictype;
617: my $picwidth;
618: my $picheight;
619: my $bitdepth;
620: my $error = 0;
621:
622: logger('DEBUG', "convert_file ($srcdir, $filename, $destdir)");
623:
624: if (not (( -f "$srcdir/$filename") && (-r _))) {
625: logger('ERROR', "unable to read file '$srcdir/$filename'");
626: return 1;
627: }
628:
629: # get base name and extension
630: if ($filename =~ /^(.*)\.(\w+)$/) {
631: $filebase = $1;
632: $fileext = $2;
633: }
634:
1.1 casties 635: #
1.2 casties 636: # quick check if target image exists
1.1 casties 637: #
1.2 casties 638: $pictype = quickident("$srcdir/$filename");
639: if ($pictype) {
640: my $newext = $target_ext_type{$pictype};
641: if ($newext) {
642: $newfn = $filebase . ".$newext";
643: # check if file exists
644: if (-f "$destdir/$newfn") {
645: logger('DEBUG', "CONV file exists: $newfn");
646: if (! $overwrite) {
647: logger('INFO', "File already converted: $newfn");
648: return 0;
649: }
1.1 casties 650: }
1.2 casties 651: } else {
652: logger('DEBUG', "target extension for $pictype unknown!");
1.1 casties 653: }
1.2 casties 654: } else {
655: # quick ident failed -- do it slowly
656:
657: ($pictype, $picwidth, $picheight, $bitdepth) = identify("$srcdir/$filename");
658: if ((! $pictype)||($picwidth == 0)||($picheight == 0)) {
659: logger('WARNING', "unknown file type '$srcdir/$filename'");
1.1 casties 660: return 0;
661: }
662: }
663:
1.2 casties 664: # collect arguments for the conversion
665: my %args;
666: $args{'srcdir'} = $srcdir;
667: $args{'destdir'} = $destdir;
668: $args{'filename'} = $filename;
669: $args{'pictype'} = $pictype;
670: $args{'picwidth'} = $picwidth;
671: $args{'picheight'} = $picheight;
672: $args{'bitdepth'} = $bitdepth;
673: $args{'srcdir'} = $srcdir;
674: $args{'scalesize'} = $scalesize;
675: $args{'scale_rel'} = $scale_relative;
676:
677: # decide conversion based on image type and encoding preferences
678: if ($pictype eq 'JPEG') {
679: $args{'jpeg_qual'} = $jpeg_quality;
680: #default encoder
681: $error = scale_jpeg(\%args);
682: } elsif ($pictype eq 'TIFF') {
683: if ($use_encoder) {
684: # use specific encoder
685: if ($use_encoder eq 'tiff_jpeg') {
686: $error = scale_tiff_jpeg(\%args);
687: } elsif ($use_encoder eq 'tiff_jpeg2') {
688: $error = scale_tiff_jpeg2(\%args);
689: } elsif ($use_encoder eq 'tiff_png') {
690: $error = scale_tiff_png(\%args);
691: }
692: } else {
693: # default
694: $error = scale_tiff_jpeg(\%args);
695: }
696: } else {
697: logger('WARNING', "unknown file type: $pictype ($srcdir/$filename)");
698: }
699: return $error;
700: }
1.1 casties 701:
702:
703: #
704: # walk_convert_dir($dirname)
705: #
706: # Descend recursively through $dirname and work on all files
707: #
708: sub walk_convert_dir {
1.2 casties 709: my($srcdir, $workdir, $destdir) = @_;
1.1 casties 710: my $errcnt = 0;
711: my $newfn;
712:
1.2 casties 713: opendir WORKDIR, "$srcdir/$workdir" or do {
714: logger('ERROR', "Unable to open directory $srcdir/$workdir!");
1.1 casties 715: return 0;
716: };
717:
718: my @dirlist = readdir(WORKDIR);
719:
720: closedir WORKDIR;
721:
722: if ($do_descend) {
723: foreach (sort @dirlist) {
1.2 casties 724: next if (/^[.]+$/);
725: next if ($junk_files{$_});
726: if (-d "$srcdir/$workdir/$_") {
727: walk_convert_dir($srcdir, "$workdir/$_", $destdir);
1.1 casties 728: }
729: }
730: }
731:
1.2 casties 732: logger('INFO', "Working on $workdir");
733: logger('INFO', "Reading from $srcdir/$workdir.");
734: logger('INFO', "Writing to $destdir/$workdir");
1.1 casties 735:
1.2 casties 736: # create destination directory
1.1 casties 737: if (not ($simulate)) {
1.2 casties 738: mmkdir("$destdir/$workdir") or do {
739: logger("ERROR", "unable to create directory '$destdir/$workdir'");
1.1 casties 740: $errcnt++;
741: return 0;
742: };
743: }
1.2 casties 744:
1.1 casties 745: foreach (sort @dirlist) {
1.2 casties 746: # skip dot-directories
1.1 casties 747: if (/^[.]+.*$/) {
748: next;
749: }
1.2 casties 750: if (-f "$srcdir/$workdir/$_") {
751: $errcnt += convert_file("$srcdir/$workdir", "$_", "$destdir/$workdir");
1.1 casties 752: }
753: }
754:
755: if ($errcnt) {
1.2 casties 756: logger('INFO', "There were $errcnt errors converting '$workdir'!");
1.1 casties 757: } else {
1.2 casties 758: logger('INFO', "Finished converting $workdir!");
1.1 casties 759: }
760:
761: return 1;
762: }
763:
764:
765: #
766: # convert_dir($from_dir)
767: #
768: # Convert directory "from_dir" and its subdirectories
769: #
770: sub convert_dir {
1.2 casties 771: my ($srcdir, $workdir, $destdir) = @_;
1.1 casties 772:
1.2 casties 773: logger('INFO', "** Converting Scans **");
774: logger('INFO', "Starting in directory '$srcdir/$workdir'");
1.1 casties 775:
1.2 casties 776: walk_convert_dir($srcdir, $workdir, $destdir);
1.1 casties 777:
778: # touch source directory so digilib rescans the thumbnails
1.2 casties 779: #logger('DEBUG', "/usr/bin/touch $source_base_dirs[0]/$workdir");
780: system("/usr/bin/touch '$srcdir/$workdir'");
1.1 casties 781:
1.2 casties 782: logger('DONE', "** Finished converting scans **");
1.1 casties 783: return 1;
784: }
785:
786:
787:
788:
789:
790:
791: ###############################################################
792: ## Main
793:
1.2 casties 794: if ($#ARGV < 3) {
1.1 casties 795: print "Scale-O-Mat $version\n";
1.2 casties 796: print " use: scaleomat.pl -src=src-base -dest=dest-base -dir=workdir [...]\n";
797: print " reads from scr-base/workdir and writes to dest-base/workdir\n";
798: print " -scaleto=destination size\n";
799: print " -scaleby=magnification factor.\n";
800: print " -jpegqual=JPEG quality (0-100)\n";
801: print " -replace=yes replaces existing files (default=skip).\n";
802: print " -encoder=tiff_png|tiff_jpeg|tiff_jpeg2\n";
1.1 casties 803: exit 1;
804: }
805:
806: # test software installation
1.2 casties 807: checksoft();
808:
809: # read command line parameters
810: my $args = parseargs();
811:
812: # source dir
1.4 casties 813: my $srcdir = cleanpath($$args{'src'}, 1);
1.1 casties 814:
1.2 casties 815: # destination dir
1.4 casties 816: my $destdir = cleanpath($$args{'dest'}, 1);
1.2 casties 817:
818: # working dir
1.4 casties 819: my $workdir = cleanpath($$args{'dir'});
1.2 casties 820:
821: # destination size
822: if ($$args{'scaleby'}) {
823: $scale_relative = 1;
824: $scalesize = $$args{'scaleby'};
825: logger('INFO', "Scaling relative by factor $scalesize");
826: }
827: if ($$args{'scaleto'}) {
828: $scale_relative = 0;
829: $scalesize = $$args{'scaleto'};
830: logger('INFO', "Scaling absolute to size $scalesize");
831: }
832:
833: # JPEG quality
834: if ($$args{'jpegqual'}) {
835: logger('INFO', "JPEG quality set to '$$args{'jpegqual'}'!");
836: $jpeg_quality = $$args{'jpegqual'};
837: }
838:
839: # force encoder
840: if ($$args{'encoder'}) {
841: logger('INFO', "Using encoder '$$args{'encoder'}'!");
842: $use_encoder = $$args{'encoder'};
1.1 casties 843: }
844:
1.2 casties 845: # Overwrite
846: if ($$args{'replace'}) {
847: logger('INFO', "Set to overwrite existing files!");
848: $overwrite = 1;
1.1 casties 849: }
850:
1.2 casties 851: # debug
852: if ($$args{'debug'}) {
853: logger('INFO', "Set debug level to $$args{'debug'}!");
854: $debug = $$args{'debug'};
1.1 casties 855: }
856:
1.2 casties 857: # simulate
858: if ($$args{'simulate'}) {
859: logger('INFO', "Set to simulate operation only ($$args{'simulate'})!");
860: $simulate = $$args{'simulate'};
1.1 casties 861: }
1.2 casties 862:
863: convert_dir($srcdir, $workdir, $destdir);
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>