QuickLZ manual, version 1.10

Files

\quick.c
Source code of the QuickLZ library.

\Visual C++ 2005 demo
Contains the source code of the executables that can be downloaded from the website - quick32.exe and quick64.exe.

\Simple ANSI C demo
Contains a very simple demonstration of compressing and decompressing a file. The source code of this demo is included at the end of this manual in the chapter "Example of use".

\Visual Basic 6.0 demo simple
Sample project for Visual Basic 6.0 using the string type as input and output. Some speed is lost because strings need to be converted to and from Unicode.

\Visual Basic 6.0 demo fast
Sample project for Visual Basic 6.0 which is using byte arrays as input and output. Both demo projects are using the quick32.dll file which is compiled for x86 and using the __stdcall calling convention.

Functions

This part is not valid for the Visual Basic demo projects because they include wrapper functions for a very easy to use interface which hardly needs any documentation.

unsigned int qlz_compress(const void *source, char *destination, unsigned int size);
This function will compress the source and store the result in the destination. The size in bytes of the source must be
given in the size parameter. If the function fails, the return value is 0 else the size of the compressed data is returned.

qlz_compress expects that the destination buffer is exactly size + 36000 bytes or larger and will crash otherwise.

unsigned int qlz_decompress(const char *source, void *destination);
This function will decompress the source and store the result in the destination.
If decompression fails the return value is 0 else the return value tells the size of the decompressed data.

unsigned int qlz_size_decompressed(char *source);
This function takes data compressed with QuickLZ as argument and returns its uncompressed size. The function can be used for allocating the correct amount of memory before decompression.

unsigned int qlz_size_source(char *source);
This function takes the first 32 bytes of data compressed with QuickLZ as argument (these 32 bytes contain a header) and returns the size of the entire compressed data.

The function is usefull when handling files that are too large to fit into memory and need to be compressed into several smaller chunks that are stored concecutive in a single destination file. When decompressing, the function tells how many bytes needs to be read from the file in order to have read the compressed chunk entirely into memory before calling qlz_decompress on it. The Visual C++ 2005 demo project uses this method.

Compatibility

Two architecture types are supported which can be specified with the #define x86x64 flag in the quick.c file:

x86x64 defined: Generates code which is higly optimized for the x86 and x64 architectures but is not compatible with other architectures. It assumes that the processor supports unaligned memory access, is little endian and that sizeof(unsigned int) == 4. Examples of supported processors are 80386, 80486, Xeon, Athlon64, Pentium 4, Pentium 4 EMT64, Opteron, Sempron, Centrino, Celeron.

x86x64 commented out: Does not use unaligned memory access, is independant of endianess and likewise assumes sizeof(unsigned int) == 4. Supported architectures are Alpha, MIPS, IA64 (Itanium), SPARC, POWER and the like. x86 and x64 are also supported in this mode but do not run at optimal speed.

Data compressed on one architecture with one setting of the x86x64 flag can be decompressed on any other architecture with any setting of the x86x64 flag - no problems can occur exchanging compressed data across architectures.

QuickLZ 1.10 is fully backwards compatible with QuickLZ 1.0 for both data format and programming API.

Notes

  • All functions are thread safe
     
  • The compiled library is around 16 Kbyte in size and no system calls to memory allocation or other system interaction is done.
     
  • Due to performance QuickLZ performs very little error checking, so passing corrupted data to qlz_decompress() can cause an exception. The only error checking done on the source is testing if the header is OK and if the last dword of the source is correct (which will detect many cases where the source is incomplete, for example due to incomplete file reads, etc.).
     
  • The length of input data is limited only by the system or by 4 Gbyte, whichever is smallest.

Example of use

compress.c
#include <stdio.h>
#include <stdlib.h>
#include "quick.c"

int
main(int argc, char* argv[])
{
 
    FILE *ifile, *ofile;
     char *src, *dst;
     unsigned int len;

      ifile = fopen(argv[1], "rb");
      ofile = fopen(argv[2], "wb");

      // allocate source buffer and read file
      fseek(ifile, 0, SEEK_END);
      len = ftell(ifile);
      fseek(ifile, 0, SEEK_SET);
      src = (char*) malloc(len);
      fread(src, 1, len, ifile);

      // Allocate destination buffer. It is very important that you
      // allocate exactly len + 36000 bytes or more!

      dst = (char*) malloc(len + 36000);

      // compress and write result
      len = qlz_compress(src, dst, len);
     
fwrite(dst, len, 1, ofile);
     
fclose(ofile);
}

decompress.c
#include <stdio.h>
#include <stdlib.h>
#include "quick.c"

int main(int argc, char* argv[])
{
     FILE *ifile, *ofile;
     char *src, *dst;
     unsigned int len;

     ifile = fopen(argv[1], "rb");
     ofile = fopen(argv[2], "wb");

     // allocate source buffer
     fseek(ifile, 0, SEEK_END);
     len = ftell(ifile);
     fseek(ifile, 0, SEEK_SET);
     src = (char*) malloc(len);

     // read file and allocate destination buffer
     fread(src, 1, len, ifile);
     len = qlz_size_decompressed(src);
     dst = (char*) malloc(len);

     // decompress and write result
     len = qlz_decompress(src, dst);
    
fwrite(dst, len, 1, ofile);
     fclose(ofile);
}