1
--- jigl 2006-01-27 12:15:03.000000000 +0100
2
+++ jigl 2006-05-29 01:27:36.000000000 +0200
7
+# Parallel computation by Vincent Stehl� <vincent.stehle@free.fr>
9
use Getopt::Long; # options parsing
10
use Text::ParseWords; # for converting the config options into an array
12
my $gblInfoTmpl = $gblThemeDir . "/default/" . $infoTmpl; # global info template
13
my @imgMgkVer = &checkSiteInstall; # check for img tools; return ImageMagick ver
15
+###########################################################
20
+# Maximum number of parallel jobs to run at most.
21
+# We set this to the number of cpu in the system.
23
+###########################################################
24
+my $MP_MAX_JOBS = mp_detect_cpu();
26
######################
27
### end variable setup
28
######################
32
###########################################################
37
+# Temporary hash, to track the running jobs. Keys are
38
+# the jobs pids. Values are the message to print in case
39
+# of non-zero return code, when die-ing.
41
+###########################################################
44
+###########################################################
49
+# Debug printing for mp_ functions.
51
+###########################################################
54
+# print "mp[$$]: ". $_[0];
57
+###########################################################
62
+# Detect the number of cpu present in the system.
65
+# This is Linux only for now.
66
+# This could be more eleguant.
68
+###########################################################
71
+ my $r = `grep processor /proc/cpuinfo |wc -l`;
72
+ mp_debug("Detected $r cpu.\n");
76
+###########################################################
81
+# Wait for children until there are n running jobs
84
+###########################################################
90
+ my $running = scalar(keys %mp_jobs);
91
+ mp_debug("$running job(s) currently running.\n");
93
+ last if $running <= $n;
95
+ mp_debug("Waiting...\n");
97
+ # Wait for a job to finish.
100
+ mp_debug("-> $c ($rc)\n");
104
+ print "mp: wait() returned $c. Strange!\n";
107
+ if(!exists $mp_jobs{$c}){
108
+ print "mp: wait() returned $c, but job is not"
109
+ ." in mp_jobs. Strange!\n";
112
+ # Check the return code and die if non-zero.
113
+ die $mp_jobs{$c} if $rc;
116
+ delete $mp_jobs{$c};
120
+###########################################################
122
+# mp_wait_for_free_slot
125
+# Wait for a free slot. This is done before launching
126
+# one more job in parallel.
128
+###########################################################
129
+sub mp_wait_for_free_slot()
131
+ mp_wait_jobs($MP_MAX_JOBS - 1);
134
+###########################################################
136
+# mp_wait_for_all_jobs
139
+# Wait for all children until there are no more running.
141
+###########################################################
142
+sub mp_wait_for_all_jobs()
147
+###########################################################
152
+# Like "system", but forked in parallel.
155
+# $_[0]: Command to launch.
156
+# $_[1]: Die message, in case of non-zero return code.
159
+# We ensure not to exceed the maximum number of slots
162
+###########################################################
165
+ my($cmd, $die_msg) = @_;
167
+ # Wait for a free slot first.
168
+ mp_wait_for_free_slot();
174
+ # We are in the child.
176
+ mp_debug("Running $cmd.\n");
180
+ # We are in the father.
181
+ # Remember the child as well as the die msg.
182
+ mp_debug("Launched $r.\n");
183
+ $mp_jobs{$r} = $die_msg;
187
+###########################################################
188
# getWatermarkProg - determine what program we have that can watermark.
189
# older versions of ImageMagick use the program 'combine'. Newer versions
190
# use 'composite'. We'll check and see which one you have installed.
191
@@ -1216,6 +1383,8 @@
194
# generate thumbnail for each image
195
+ # First pass: scale all images. This is done in parallel
196
+ # if possible, with jobs launched in the background.
197
for $i (0 .. $#{$albumInfo->{images}}) {
198
# get the name of the file and create the thumbnail filename
199
# store the name of the thumbnail for this image in the albumInfo
200
@@ -1230,7 +1399,7 @@
201
print "\r\(" . ($i+1) . "/" . ($#{$albumInfo->{images}}+1) . "\) Scaling $tmpThumbFile $msgPad";
202
$cmd = "$scaleProg -scale x$opts{ty} -sharpen 5 \"$tmpFile\" \"$tmpThumbFile\"";
203
$dieMsg = "\nCannot scale the thumbnail image $tmpThumbFile!\n";
204
- system($cmd) == 0 or die $dieMsg;
205
+ mp_launch($cmd, $dieMsg);
207
# increment the generated count
209
@@ -1239,13 +1408,21 @@
210
print "\r\(" . ($i+1) . "/" . ($#{$albumInfo->{images}} + 1) . "\) Skipping $tmpThumbFile $msgPad";
215
+ # Wait for all processes to complete.
216
+ mp_wait_for_all_jobs();
218
+ # Second pass: now that all images have been converted,
219
+ # we can get all images informations.
220
+ for $i (0 .. $#{$albumInfo->{images}}) {
221
# get the files size and X,Y info for the slide
222
@tmpArr = &getImgInfo($albumInfo->{images}[$i]->{thumb});
223
$albumInfo->{images}[$i]->{thumbkb} = $tmpArr[0];
224
$albumInfo->{images}[$i]->{thumbx} = $tmpArr[1];
225
$albumInfo->{images}[$i]->{thumby} = $tmpArr[2];
228
print "\r"; # move back to the start of the line
229
print "$genCnt thumbnails generated. $msgPad\n" if $genCnt > 0;
230
print "$skipCnt thumbnails skipped because they already existed.\n" if $skipCnt > 0;
231
@@ -1284,6 +1461,12 @@
234
# generate slide for each image
235
+ # First pass: scale all images. This is done in parallel
236
+ # if possible, with jobs launched in the background.
237
+ # Also, we remember if watermarking is necessary for the
239
+ my %may_need_watermarking;
241
for $i (0 .. $#{$albumInfo->{images}}) {
242
# get the name of the file and create the slide filename
243
$tmpFile = $albumInfo->{images}[$i]->{file};
244
@@ -1304,45 +1487,67 @@
245
if (($opts{fs} or (!(-e $tmpSlideFile))) && !($opts{uo})) {
246
# scale the image to the slide size specs
247
print "\r\(" . ($i+1) . "/" . ($#{$albumInfo->{images}}+1) . "\) Scaling $tmpSlideFile $msgPad";
249
# only scale the slide if it's Y height is greater than
250
# the value of the sy option.
251
if ($albumInfo->{images}[$i]->{height} > $opts{sy}) {
252
$cmd = "$scaleProg -scale x$opts{sy} -sharpen 5 \"$tmpFile\" \"$tmpSlideFile\"";
253
- $dieMsg = "\nCannot scale the slide image!\n";
254
- system($cmd) == 0 or die $dieMsg;
255
+ $dieMsg = "\nCannot scale the slide image $tmpSlideFile!\n";
256
+ mp_launch($cmd, $dieMsg);
259
$dieMsg = "Cannot copy \"$tmpFile\" to \"$tmpSlideFile\"\n";
260
copy $tmpFile,$tmpSlideFile or die "$dieMsg $!\n";
263
- # if we're watermarking the slides, do it now.
265
- # check to make sure we have a valid watermark program
266
- # and that the watermark image exists
267
- if ($waterMarkProg eq "none") {
268
- print "\r\(" . ($i+1) . "/" . ($#{$albumInfo->{images}}+1) ."\) CANNOT Watermark $tmpSlideFile. No Watermark program found! $msgPad";
270
- print "\r\(" . ($i+1) . "/" . ($#{$albumInfo->{images}}+1) ."\) Watermarking $tmpSlideFile $msgPad";
271
- if ($waterMarkProg eq "composite") {
272
- $cmd = "$waterMarkProg -compose over -gravity $opts{wg} $opts{wf} \"$tmpSlideFile\" \"$tmpSlideFile\"";
274
- # combine reversed the order the image and watermark
275
- # were listed on the command line.
276
- $cmd = "$waterMarkProg -compose over -gravity $opts{wg} \"$tmpSlideFile\" $opts{wf} \"$tmpSlideFile\"";
278
- $dieMsg = "\nCannot watermark the slide image!\n";
279
- system($cmd) == 0 or die $dieMsg;
282
+ # Remember that this slide may need watermarking.
283
+ $may_need_watermarking{$i} = 1;
285
# increment the generated count
289
# increment the skipped count
290
print "\r\(" . ($i+1) . "/" . ($#{$albumInfo->{images}}+1) . "\) Skipping $tmpSlideFile $msgPad";
295
+ # Wait for all processes to complete.
296
+ mp_wait_for_all_jobs();
298
+ # Second pass: watermarking. We do this in parallel too.
299
+ # Note that we do this pass only if necessary.
301
+ for $i (0 .. $#{$albumInfo->{images}}) {
302
+ next if !exists $may_need_watermarking{$i};
304
+ # check to make sure we have a valid watermark program
305
+ # and that the watermark image exists
306
+ if ($waterMarkProg eq "none") {
307
+ print "\r\(" . ($i+1) . "/" . ($#{$albumInfo->{images}}+1) ."\) CANNOT Watermark $tmpSlideFile. No Watermark program found! $msgPad";
310
+ print "\r\(" . ($i+1) . "/" . ($#{$albumInfo->{images}}+1) ."\) Watermarking $tmpSlideFile $msgPad";
311
+ if ($waterMarkProg eq "composite") {
312
+ $cmd = "$waterMarkProg -compose over -gravity $opts{wg} $opts{wf} \"$tmpSlideFile\" \"$tmpSlideFile\"";
314
+ # combine reversed the order the image and watermark
315
+ # were listed on the command line.
316
+ $cmd = "$waterMarkProg -compose over -gravity $opts{wg} \"$tmpSlideFile\" $opts{wf} \"$tmpSlideFile\"";
318
+ $dieMsg = "\nCannot watermark the slide image $tmpSlideFile!\n";
319
+ mp_launch($cmd, $dieMsg);
323
+ # Wait for all processes to complete.
324
+ mp_wait_for_all_jobs();
327
+ # Third pass: now that all slide have been generated, we can get
328
+ # the images informations.
329
+ for $i (0 .. $#{$albumInfo->{images}}) {
330
# get the image info for the slide
332
# we're using the originals and already have the