Compression Library, Part Two
Since, I was in the neighborhood, that neighborhood being my Compression library, I decided to redesign the interface. The code comes from some Java code that I’d written quite a few years ago as a way of learning Java and building a Java Imaging library. As it turns out, I hate programming in Java for the simple reason that I think that unsigned integer data types are quite useful as pixel values.
I forget the details of the Java implementation, but the C++ translation had the compression and decompression functions as static functions within individual compressor and decompressor classes. RLE compression would be encapsulated within RLECompressor and RLEDecompressor classes. To compress: RLECompressor::Compress(). I also included measuring functions in order to allow for an adaptive algorithm that could test and determine which algorithm would do the best job at compressing a particular data stream.
Well, now that I’m going to be using LZW compression to compress sub-byte data streams, and to facilitate an adaptive algorithm approach, I decided to do away with the homogenous static API as well as the separate TypeCompressor and TypeDecompressor approach and, instead, combine them into a single TypeCompressor which would be derived from a CompressorIF abstract base class which would define the API. Additionally, I’ve defined a CompressorCapabilities class that encapsulates the various compression types: Lossless vs. Lossy, BitStream, ByteStream, ImageStream (2-dimensional data driven, such as the Delta Row image compression algorithm), as well as Measurable, which would allow an adaptive approach to pre-measure the output buffer.
So, I did all the above and started the conversion process with the RLE compressor. As it turns out, my RLE compressor and decompressor had bugs. I found that out by simplifying the CmprTest program by building a common compressor test function that referenced the compression and decompression code through the CompressorIF* interface. By doing this, and enhancing the tests to include a file compression test, I was able to find the bugs.
Here are the pseudo-code snippets:
void TestCompressor(CompressorIF* compressor) { }
TestCompressor(new RLECompressor);
As much work as all this is turning out to be, it is improving my object-oriented design and implementation skills. That’s not a bad thing.