Skip to content
/ qoiimg Public

Quite OK image compression Verilog implementation

License

Notifications You must be signed in to change notification settings

ZipCPU/qoiimg

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

An All-Verilog Implementation of the "Quite-OK Image Format"

The full format description can be found here.

This repository currently consists of a QOI encoder implementation. This includes the file header, image compression, and trailer. The result of this encoder is an AXI stream of video image "packets". A Wishbone recorder can be used to record these packets to memory. The recorder requires components from the ZipCPU's DMA at present.

A separate decoder is also planned to decode and decompress images, but it remains in the early stages of its development.

Back story

The purpose of this implementation is simply to minimize the bandwidth required to store video images in memory.

Let me back up. I have a SONAR project that can (currently) display some amazing things to the HDMI output--in simulation. In hardware, the displays are all messed up. Therefore, I need something that can capture the display output to memory, so that I can then come back later and debug what was actually going to the display. The problem I have is that the memory bandwidth is already well used--I don't want to take up any more of it, or risk any more of the design failing due to memory latencies. Therefore, the memory compression needs to be quick.

Many of these SONAR images consist of plots or other charts on a black background. QOI's run-length compression should make quick work of this black background. Likewise, the images often contain only a small number of colors, such as the white lines. Again, the image compression might note the white pixel initially, but then ever after the white pixel(s) will be compressed to a single byte of white, followed by a single byte of black, followed by a run of black. Again, this should compress quite well, reducing the bandwidth to memory required by the algorithm.

Implementation notes

Project Goal: real-time compression and decompression. I think I've figured out how to map the compression component to hardware. The decompression algorithm isn't there yet. (i.e., it has known bugs) Neither algorithm has been properly verified (yet).

The trick in this implementation is getting the compression table, a block RAM memory, to the point where it can be accessed in one cycle. This means that the table index must be calculated ahead of time, and the multiplications before that. This necessitates a pipeline operation, which is provided in the image. At present, this pipeline is 5-stages deep for compression. Key to this operation are the two clock cycles required prior to the compression table lookup.

Decoding is a bit more of a challenge, particularly since the compression table address may depend upon a previous pixel's value--even before we know the index of that previous pixel in the table. Hence, a table lookup followed by an offset value would require calculating the pixel offset prior to the table lookup. While I think I have this challenge solved, other issues remain.

Status

This IP is currently a work-in-progress. I think I can say the encoder is now hardware proven, since I have now used it to capture several black and white hardware images, but I'd really like to see a successful test with more color involved. The decoder is known to not be ready yet. Worse, the design doesn't (yet) have a regression suite--whether it be simulation or formal verification based.

One step at a time.

The current (and planned) components of this repository include:

  • qoi_compress compresses pixel data. This critical component has now been formally verified.

  • qoi_encoder wraps the compression algorithm, providing both a file header containing image width and height, as well as an image trailer.

    This component has worked in hardware at one time. Since that time, it has gone through a formal verification process which has found several bugs. It has not been tested in hardware since.

  • qoi_recorder wraps the QOI encoder so that an entire image stream may be encoded and a fixed number of images may be copied to memory. This recording capability depends upon both the RXGears and the S2MM components of the ZipDMA, both found in the ZipCPU's git repository. As with the encoder, this component has worked in hardware (at one time) but the verification infrastructure (which should be found here) remains woefully inadequate (i.e. non-existent).

  • qoi_decompress is designed to decompress QOI encoded pixel data. At present, this component passes a lint check. Yep. That's it. Although I have started work to formally verify this component, it continues to have known bugs within it that still need to be addressed--particularly with the LUMA compression encoding.

  • qoi_decoder is designed to decompress QOI frames (files). It removes the header and trailer, detects the width and height, and produces a one-frame AXI video stream as an output. That is, it will produce one frame per incoming QOI image once completed. This component is about as developed as the QOI decompressor, since both only pass lint checks. As such, neither are ready for prime time ... yet.

  • qoi_framebuffer is not yet written. Once written, this component will repeatedly read QOI image files from memory, and feed them to the decoder. The result (should) be a proper video stream once completed. (Yeah, I know, I'll believe it when I see it too.) For now, this component is nothing more than vaporware.

License

This IP is available under GPLv3. Other licenses may be available for purchase.

About

Quite OK image compression Verilog implementation

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages