Skip to content

rainerzufalldererste/limg

Repository files navigation

limg

What is limg?

limg is an experimental (and very much work in progress) lossy raster image codec aimed towards compressing images of various origins (photos, graphics) pretty well. It's written in C++.

How does it work?

limg breaks the image up into blocks and calculates three linear factors the colors in this block consists of.

We then try to expand those blocks into areas of similar color, and recalculate a better matching linear factor decomposition for the combined area. For the image above we end up with the following areas: limg - Blocks

For the image above, the first linear factor would be the colors between these two extremes:

Minimum Factor A Maximum Factor A
limg - Minimum Factor A limg - Maximum Factor A

This already covers most of the colors of this block, but certainly not all, so the second linear factor is the most prevalent direction of error from the first two extremes. Since these directions are relative from the best color match from the first two extremes, they are displayed here in relation to 50% gray.

Minimum Factor B Maximum Factor B
limg - Minimum Factor B limg - Maximum Factor B

In some cases even after this step there still remains some difference to the original color. The third linear factor works just like the second one to get us closer to the original colors. Since this is still a relative color, we'll again display it in relation to 50% gray.

Minimum Factor C Maximum Factor C
limg - Minimum Factor C limg - Maximum Factor C

Currently these factors aren't particularly optimal and just rely on the average error direction, which may not be a good idea in some cases.

Now, every block is factorized into these colors resulting in a value between 0 and 1 for each of the factors (where 0 corresponds to the minimum and 1 the maximum) for each pixel in a block.

Factor A Factor B Factor C
limg - Factor A limg - Factor B limg - Factor C

Since some of the linear factors are reasonably similar, we can get away with using fewer bits for the mix in some of the cases. Dithering is applied during the bit crushing process in order to reduce banding issues. (In the image below, lighter color in each channel represents fewer bits being required to represent a blocks to the desired accuracy; Red = Factor A; Green = Factor B; Blue = Factor C)

limg - BitCrush

The resulting image looks very similar to the original. The image at the top is already the decompressed version and features only very minor compression artifacts.

This is the difference to the original, boosted by a whole lot in order to make the errors visible. (The original basically looked like a completely black image.)

limg - Difference

For reference, this was the original image:

limg - Original

Releases

No releases published

Packages

No packages published

Languages