Posted on Tuesday 5 December 2006
I’ve modified Tinic Uro’s PNGEnc class to make it a bit faster and get lower file sizes.
The first modification is to the non-transparent encoding algorithm which I have modified to use getPixels instead of getPixel. The reason Tinic was using getPixel is that getPixels returns pixels in the ARGB format and PNGs use RGBA, and thus getPixel was used to make the transition at a pixel level. Since in the case of non-transparent bitmaps all the alpha bytes are set to 0xff, there is also the possibility of simply getting a single scan line, deleting the first byte, and appending 0xff at the end (wrapping). This gives a modest speed boost on the order of 1 ms per 2000 pixels, so that the total process takes between 20% and 30% less time depending on data. The new bottleneck then is the CRC algorithm in writeChunk so if you have experience with that please do take a stab at it.
The second modification is the addition of support for scanline filter type “sub”. Although PNG is lossless there are a certain amount (4) of scanline lossless filters you can apply before compression which may enhance the compressibility of the data. The “sub” filter is the simplest one and encodes bytes as the difference between adjacent pixels on a scan line. This can improve the compression ratio if the image has gradients in it, but can decrease it if the image has unicolored shapes and sharp edges. As a sample data source I used a google maps street map and satellite view of Montreal at 800×500. In the case of the street map the data went from 62 to 80 KBs. In the case of the satellite view it went from 756 to 585 KBs. As for the encoding time, it’s about twice as much as the no filter mode. I am almost certain however that it is possible to rewrite the function so that no pixel level manipulation will be done, instead doing the “calculation” using the difference blend mode beforehand (please take a stab at it if you know what I’m talking about). I may take on the 3 other scanline filters if it’s something people are interested.


