Code Poetry
and Text Adventures

by catid posted (>30 days ago) 5:04pm Mon. Aug 5th 2013 PDT
There seem to be two ways to do LZ decoding interleaved with other decoders:

(1) You can limit LZ matches to row length, escape into LZ mode, handle the whole match in an inner loop, and then skip ahead a number of x pixels.

(2) Or you can incorporate it into the big x,y outer loop and for each pixel have if (lz_copy_count > 0), and copy each pixel one at a time.

The advantage of approach (1) is that it can decode faster, since there isn't an extra if-statement in the per-pixel inner loop and the pixel copying can happen all at once so there is better cache locality.  The disadvantage is you want to limit the LZ encoder to stop matches at the end of each row, so that the copy loop does not need to handle row starts too.

In practice this doesn't seem to hurt the compression ratio more than 1-2 KB, and actually helps in some files by 1-2 KB because my LZ match finder is still greedy and doesn't take distance into account in the middle of a match after it is found.  I'm going to revisit the LZ match finder and make it more optimal at some point and expect to win some more KB/file this way.

Method (1) is a little trickier to code but should run much faster, and decoding time is very important to me.

I'm only looking at the RGBA decoder right now.  The monochrome decoder is a lot less sensitive to how much I cram into its inner loop, since it is called less often.  It may make more sense to use method (2) to simplify writing it, especially since there is a lot more going on in the monochrome decoder.