A project log for 3RGB image lossless compression format

Tiled CODEC for still and moving pictures based on the 3R compaction algorithm

yann-guidon-ygdesYann Guidon / YGDES 05/26/2017 at 04:200 Comments

A main motivation for this project is the streaming of video over Ethernet to the #WizYasep screen controllers. The data is transmitted over UDP and received by a WZ5300 controller. For reasons that remain unknown, the MTU is not as large as documented and I have succeeded transmission with 1200 bytes per packet. It can be a little more but that's what I work with...

I want to keep packet framing as simple and easy as possible. The trick of "chunking" on 3RGB is to group small data blocks to fit in 1200 bytes and send them over. Error detection occurs at the chunk level so a whole chunk can be discarded if the received chunk is invalid. 3R-encoded blocks are "self-validating" to add another level of resilience but the interesting part is to use the UDP protocol to implicitly carry the size informations.

Using TCP, which is a stream protocol, the receiver must first read the number of bytes in a block or chunk, then ensure that enough are available in the reception queue. With UDP, the chunks are already correctly sized, the Wiznet Ethernet tranceiver announces that one packet with XXX bytes has been received and there is no need to parse it, or so little. A whole number of blocks is available for direct use.

The desired chunk size is in the 1024-1200 bytes range and this influences the granularity of the data blocks. Ideally, tles would be 8×8, as a good compromise for compression ratio versus effort, and the smaller sizes make the tiles easy on the CPU caches or the small FPGA. However 8×8 bytes is only 64 bytes, which is pretty small compared to the MTU.

16×16 pixels tiles would contain 256 values, and 4 or 5 uncompressed blocks of 256 bytes fit in the MTU: 4×256=1024, 5×256=1280 (without block type headers) which is a bit too large, so the larger blocks create a big variability in the chunk size.

So chunks are stored in groups of roughly 1200 bytes on disk, and each chunk is preceded by a fixed-sized word that contains informations for the player, such as:

Inside the chunk is an ordered collection of individual blocks of various types, from a few bytes to 1200 bytes.