Visualizing Compressed Value Storage (CVS)

This article describes an imagination of compressed value storage (CVS) being used in graphics storage and rendering. The imagination does not make any assumption that CVS can really be used for digital images. This is basically a spill of thought processes and no codes or implementations are shared. Still interested? Read on...

A 2D digital image is essentially a matrix where each entry is a pixel's RGBA information.

Compressed Value Storage (CVS) is a lossless compression of matrix values and coordinates, such that each distinct non-zero values are aligned with their respective linear indexes in the matrix.

Image Data to CVS

A 2D image can be seen as a matrix. Each pixel is a matrix entry. An image fills its entire size of course. Thus, by default, the matrix is dense.

However, a dominantly redundant entry value can be identified as the "0" value. For example, if an image is mostly black (or white), the black (or white) pixels can be treated as the 0's in the matrix. Doing so allows the image to be represented instead as a sparse matrix. Note that the "0" does not need to be just black (or white). It can be any RGBA value. For example, given an image that is predominantly blue, the "0" can be blue, and anything else not blue will go in to the sparse matrix representation.

Possible Image File Format

The image file can contain 3 main parts:
  • Size - tuple (int rows, int columns) size of the image
  • RGBA CVS - the "sparsified" image/matrix compressed in CVS format; CVS.Value can be an array of tuple (#xxxxxx, A) values; can be rendered by its own thread
  • Default RGBA value - the "0" value of the image/matrix; tuple (#xxxxxx, A); can be rendered by its own thread
Additional header and/or footer information can be added if desired. Regardless, the 3 parts described above will be the most significant.

Compression Process

Each pixel in an image stores RGBA information. A simple structure can be created to represent a tuple of (#xxxxxx, A) values, where #xxxxxx is the hex of the RGB colors, and A is the alpha channel value (which can be any number between 0.0 and 1.0 inclusive). Value entries will use this type to represent the pixel's RGBA information.

The simplest way is to construct the entire image in to a DOK sparse matrix and compress it to CVS format. Possibly though, the most memory effective can be to manually build the RGBA CVS Value and LinearIndex properties directly. Either way, the resulting CVS instance can be used to identify the CVS.Value with the most linear indexes. This entry will be pulled out of the CVS instance, to be saved instead as the default RGBA value.

For the RGBA CVS.LinearIndex lists entries, sequential values can be stored in the file as a hyphen separated pair (ex. 1,12,251-500,1000-1999...) instead of storing each values in range. This can save a lot of space. An algorithm may be needed to detect such series in the lists. This algorithm would be needed in both writing to and reading from the file.

To maximize possible space savings, an algorithm needs to be created to choose the best linear index mode to use that could result to the smallest possible storage size. For example, given a black and white image of two squares side by side, if black is selected as the "0", the highest compression can be achieved by storing the linear indexes of the white square in column-major order. On the other hand, if the image is that where the black square is on top and the white square is at the bottom, the row-major order is best.

Standard file compression techniques can be used to further compress the image file.

Rendering Process

If the image file is standardly compressed, it must be decompressed. Or, if the compression technique supports partial extraction, the image file's parts must be extracted.
  • The Size part will be used to set the size of the image canvas.
  • The RGBA CVS part will be used to set the pixels on the image canvas.
  • The Default RGBA value part will be used to set the pixels which coordinates/linear indexes are not in RGBA CVS.LinearIndex collection. An algorithm would need to be created to detect these coordinates/linear indexes.
Given for example a canvas that can accept pixel RGBA information, an algorithm can be put together to read and process the image file's parts in to the canvas. The rendering algorithm can be multi-threaded: a thread for the default RGBA value and a thread for the RGBA CVS, which can create a thread per value-linear index set. In effect, the canvas can be seen getting filled in random places as the threads finish consuming their respective data in to the canvas. If the canvas supports multiple pixels to be assigned/filled concurrently, it is possible to speed up the overall rendering process.

Comments