Code Poetry
and Text Adventures

by catid posted (>30 days ago) 6:49pm Mon. Apr 22nd 2013 PDT
PNG has a couple of spatial filters like "same as left pixel" and "same as above pixel" that it applies before trying to compress the data.

My GCIF project works similarly and has filters that it applies first.  The filters chosen are much more interesting and come from a few places including two written from scratch.

Linear filters are interesting because as you can imagine there are a lot of them.  For the pixels left, left-up, up, and right, there are 6544 that are outside of my go-to list of the form:
Prediction = (a*A + b*B + c*C + d*D) / 2,
where {a,b,c,d} = {-4, -3, -2, -1, 0, 1, 2, 3, 4}

{a,b,c,d} are called "filter taps" or "filter coefficients".

The vast majority of these are not often preferable for perfect pixel prediction.  For instance if all the filter taps are negative, that wouldn't be helpful at all since pixel values are all positive.  Empirically nearly all of the linear filters are worse than my default filters.  Except about 80 of them, which I accumulated by testing across a number of sprite-sheet images from one of our games.

Those 80 I added to a table that lives in the source code, and the encoder can now quickly try out each of them and see if they are preferred to the default filters.  When the custom filters are preferred, those table indices are transmitted to the decoder by storing them in the image file with just a few bytes.

The results are decent.  I'm seeing 911KB files cut down to 908KB, and 639KB down at 636KB after applying the better filters.  And the decoding is now non-intuitively faster.  These custom filters are more complex to apply.  This is mainly because better compression means less to process, so faster decoding.
last edit by catid edited (>30 days ago) 6:54pm Mon. Apr 22nd 2013 PDT