Menu

#67 -ow and parallell requests

None
wont-fix
None
5
2016-02-09
2016-01-28
No

When pngcrush is running in parallell (e.g. starting multiple instances of pngcrush in the background), and using the -ow option, pngcrush will have a file name conflict and overwrite images with the wrong image.

This short little bash script demonstrates the issue:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/bash
ITEMS=100
for i in $(seq 1 $ITEMS)
do
    convert -background white -fill black -size 165x70 -pointsize 48 -gravity center label:$i $i.png
done

for i in $(seq 1 $ITEMS)
do
    pngcrush -q -rem alla -reduce -brute -ow $i.png &
done
wait

It first generates 100 PNG images with their number inside. The pngcrush is started in parallell in overwrite mode on each file. Since pngcrush uses the same temporary file name for all the files it is processing, it will in some cases overwrite the files with the wrong minified file.

When pngcrush is not run in -ow mode, this problem goes away, so this works:

pngcrush -q -rem alla -reduce -brute $i.png out/$i.png &
mv out/$i.png $i.png

You should take steps to ensure you are creating a real temporary file name, and not reusing the same temporary file name.

This was extremely complex to figure out when the parallelism was lower (4), and was thus rarer and was only detected after the fact.

Discussion

  • Glenn Randers-Pehrson

    It's a known issue. See the pngcrush -help screen:

       usage: ...
       pngcrush -ow [other options] file.png [tempfile.png]
       ...
    
        -ow (Overwrite)
    
               Overwrite the input file.  The input file is removed
               and the temporary file (default "pngout.png")
               is renamed to the input file after recompression
               and therefore they must reside on the same
               filesystem.
    
               CAUTION: If you are running multiple instances
               of pngcrush in parallel, you must specify a
               different temporary filename for each instance,
               to avoid collisions.
    

    So your command should be

     pngcrush -q -rem alla -brute -ow $i.png temp_$i.png &
    

    (BTW, the "-reduce" option is no longer needed starting with pngcrush-1.8.0)

     

    Last edit: Glenn Randers-Pehrson 2016-01-28
  • Glenn Randers-Pehrson

    • status: open --> wont-fix
    • assigned_to: Glenn Randers-Pehrson
    • Group: -->
     

Log in to post a comment.