… | |
… | |
121 | my $hash = substr +(Digest::MD5::md5 $$dataref), 0, $clen || 5; |
121 | my $hash = substr +(Digest::MD5::md5 $$dataref), 0, $clen || 5; |
122 | |
122 | |
123 | if (exists $hash{$hash}) { |
123 | if (exists $hash{$hash}) { |
124 | # hash collision, but some files are simply identical |
124 | # hash collision, but some files are simply identical |
125 | if (${$hash{$hash}[1]} ne $$dataref) { |
125 | if (${$hash{$hash}[1]} ne $$dataref) { |
126 | warn "hash collision $hash{$hash}[0] vs. $id\n"; |
126 | warn "hash collision $hash{$hash}[0] vs. $id (increase the default \$clen in make_hash?)\n"; |
127 | exit 1; |
127 | exit 1; |
128 | } else { |
128 | } else { |
129 | print "$hash{$hash}[0] and $id are identical (which is fine).\n" if $VERBOSE >= 3; |
129 | print "$hash{$hash}[0] and $id are identical (which is fine).\n" if $VERBOSE >= 3; |
130 | } |
130 | } |
131 | } |
131 | } |
… | |
… | |
133 | |
133 | |
134 | $$hashref = $hash; |
134 | $$hashref = $hash; |
135 | } |
135 | } |
136 | |
136 | |
137 | sub optipng($) { |
137 | sub optipng($) { |
138 | system $OPTIPNG, "-i0", "-q", $_[0]; |
138 | system $OPTIPNG, "-o5", "-i0", "-q", $_[0]; |
139 | die "$_[0] has zero size, aborting." unless -s $_[0]; |
139 | die "$_[0] has zero size, aborting." unless -s $_[0]; |
140 | } |
140 | } |
141 | |
141 | |
142 | mkdir $TMPDIR, 0700 |
142 | mkdir $TMPDIR, 0700 |
143 | or die "$TMPDIR: $!"; |
143 | or die "$TMPDIR: $!"; |
… | |
… | |
365 | my $other = "$stem.32x32.png~"; |
365 | my $other = "$stem.32x32.png~"; |
366 | |
366 | |
367 | make_file $path, $other, sub { |
367 | make_file $path, $other, sub { |
368 | fork_exec { |
368 | fork_exec { |
369 | system "convert png:\Q$path\E -geometry 50% -filter lanczos $QUANTIZE -quality 00 png32:\Q$other\E~"; |
369 | system "convert png:\Q$path\E -geometry 50% -filter lanczos $QUANTIZE -quality 00 png32:\Q$other\E~"; |
370 | system $OPTIPNG, "-i0", "-q", "$other~"; |
370 | optipng "$other~"; |
371 | |
371 | |
372 | # reduce smoothfaces >10000 bytes |
372 | # reduce smoothfaces >10000 bytes |
373 | # obsolete, no longer required |
373 | # obsolete, no longer required |
374 | if (0 && $stem =~ /_S\./ && (-s "$other~") > 10000) { |
374 | if (0 && $stem =~ /_S\./ && (-s "$other~") > 10000) { |
375 | my $ncolor = 256; |
375 | my $ncolor = 256; |
376 | while () { |
376 | while () { |
377 | system "<\Q$other~\E $PNGNQ -s1 -n$ncolor >\Q$other~~\E"; |
377 | system "<\Q$other~\E $PNGNQ -s1 -n$ncolor >\Q$other~~\E"; |
378 | system $OPTIPNG, "-i0", "-q", "$other~~"; |
378 | optipng "$other~~"; |
379 | last if 10000 > -s "$other~~"; |
379 | last if 10000 > -s "$other~~"; |
380 | $ncolor = int $ncolor * 0.9; |
380 | $ncolor = int $ncolor * 0.9; |
381 | $ncolor > 8 or die "cannot reduce filesize to < 10000 bytes"; |
381 | $ncolor > 8 or die "cannot reduce filesize to < 10000 bytes"; |
382 | } |
382 | } |
383 | |
383 | |
… | |
… | |
435 | print $convert $png; |
435 | print $convert $png; |
436 | close $convert; |
436 | close $convert; |
437 | |
437 | |
438 | # pass 2, optimise, and rename |
438 | # pass 2, optimise, and rename |
439 | for (@todo) { |
439 | for (@todo) { |
440 | system $OPTIPNG, "-o5", "-i0", "-q", "$_->[2]~"; |
440 | optipng "$_->[2]~"; |
441 | die "$_->[2]~ has zero size, aborting." unless -s "$_->[2]~"; |
|
|
442 | rename "$_->[2]~", $_->[2]; |
441 | rename "$_->[2]~", $_->[2]; |
443 | } |
442 | } |
444 | }; |
443 | }; |
445 | } |
444 | } |
446 | |
445 | |