views:

70

answers:

6

We're currently creating a device for a customer that will get a block of data (like, say, 5-10KB) from a PC application. This is a bit simplified, so assume that the data must be passed and uncompressed a lot, not just once a year. The communication channel is really, really slow, so we'd like to compress the data beforehand, pass to the device and let it uncompress the data to its internal flash. The device itself, however, runs on a micro controller that is not really fast and does not have a lot of memory. It has enough flash memory to store the result, and can uncompress the data block as it is received, but it may not have enough RAM to store the entire compressed or uncompressed (or even both!) data blocks. And of course, it doesn't have an operating system or other luxury.

This means we need a sufficiently fast uncompression algorithm that does not use a lot of memory. The compression can be slow and ugly, since we're doing it on the PC side. C or .NET code preferred though for compression, to make things easier. The uncompression code should be in C, since it's unlikely that someone has an ASM optimized version for our controller.

We found LZO, which would be almost perfect for us, but it has a so-called "free" license (GPL) by default, which makes it totally unusable for our customer. The author says that commercial licenses are available on request, but unfortunately he's currently unreachable (for non-technical reasons, like the news on his site say).

I found a few other libraries, including the puff.c from zlib, and we're still investigating, but I thought I'd ask for your experience:

Which compression algorithm and/or library do you recommend for embedded purposes, given that the decompression device has really limited resources and source code and a commercial license are required?

+1  A: 

I have used LZSS. I used code from Haruhiko Okumura as base. It uses the last portion of uncompressed data(2K) as dictionary. This code can be modified to not require a temporary ring buffer if you have no memory. The licensing is not clear from his site but some versions was released with a "Use, distribute, and modify this program freely" line included and the code is used by commercial vendors.

Here is an implementation based on the same code that forms part of the Allegro game library. Allegro licensing is giftware or zlib.

Another option could be the lzfx lib that implement LZF. I have not used it yet but it seems nice. Also uses previous results so it has low memory requirements and is released under a BSD Licence.

Gerhard
+1 for LZSS. If you work at it, you can make the decompressor pretty small. Another options is its predecessor, LZ77.
Igor Skochinsky
A: 

I would recommend ZLIB. From the wiki:

The library provides facilities for control of processor and memory use There are also facilities for conserving memory. These are probably only useful in restricted memory environments such as some embedded systems. zlib is also used in many embedded devices because the code is portable, liberally-licensed and has a relatively small memory footprint.

0x69
Zlib needs about 20KB memory minimum. Depending on the controller that could be a lot or nothing.
Gerhard
Based on this http://www.zlib.net/zlib_tech.html, for 32-bit architecture, for 8-bit compression window and lowest memory usage level - I've got such memory footprint: for compression - ((1<<(8+2))+(1<<(1+9)))/1024 = 2 KB for decompression - ((1<<8)+1440*2*4)/1024 = 11 KB. I'm not sure - if compression window can be set to even less than 8-bits, memory footprint should be lowered even more. That being said - I agree ZLIB not pretends to be the compressor with smallest memory footprint. (And I didn't said that either)
0x69
A: 

You might want to check out Jørgen Ibsen's aPlib - a couple of excerpts from the product page:

The compression ratios achieved by aPLib combined with the speed and tiny footprint of the depackers (as low as 169 bytes!) makes it the ideal choice for many products.

aPLib is free to use even for commercial use, please check the included license for details.

The compression library is closed-source (yes, I know this could be a problem), but has precompiled libraries for a variety of compilers and operating systems, including both 32- and 64-bit editions. There's C and x86 assembly source code for the decompressor.

EDIT:

Jørgen also has a free (zlib license) BrifLZ library you could check out if not having compressor source is a big problem.

snemarch
+2  A: 

A lot depends on the nature of the data. If it is simple enough, you may not need anything very fancy. For example if the downloaded data was a simple image (for example something like a line graph), a simple run length encoding could cut the data down by a factor of ten and you would need trivial amounts of code and RAM to decode it.

Of course if the data is more complex, then this won't be of much use. But I'd start by exploring the data being sent and see if there are specific aspects which would allow you to compress it more effectively than using a general purpose algorithm.

sbass
I am currently unsure about what the data will look like, but I think it's a rather random binary format, unfortunately. Good answer though.
OregonGhost
A: 

I've seen people use 7zip on an embedded system with memory in the tens of megabytes.

starblue
Is that a typo? Otherwise, tens of megabytes is orders of magnitude more than we have available.
OregonGhost
No, that's correct. I don't know how much memory 7-zip actually needs, it may be much less.
starblue
A: 

One alternative could be the LZ77 coder/decoder in the Basic Compression Library.

Since it uses the unpacked data history for its dictionary, it uses no extra RAM except for the compressed and uncompressed data buffers. It should be ideal for your use case (zlib license, portable C). The entire decoder is just 70 lines of code (including comments), and really fast.

EDIT: Yet another alternative is the liblzg library, which is a refined version of the aforementioned LZ77 coder/decoder. It compresses better, is generally faster, and requires no memory for decompression. It is very, very free (zlib license).

marcus256