BZip2 – Gotta Love It :)

I’ve never been much of a friend of commercials and recommendations, but there simply are stuff that have to be recommended.

Like Woody Allen’s 1975 movie “Love and Death“. 😀

Or like BZip2.

It’s free, it’s even patent free, it’s great, it’s almost unused in Windows world… Why? I have really no idea. The compression ratio is typically twice as good as that of zip. The only “down-side” is, that it can store only 1 file per archive… But then again, there’s tar to take care of this, and e.g. total commander can handle both pretty well.

But that’s not what I wanted to talk about. Yes, I wanted to talk to all you geeks who love programming just as much as I do – about the bzip2 API. And what’s more – it also has a nice documentation! Wow, yes!

I used to use many different compression formats throughout my programming carrier – zip, rar, lzo, minilzo, arithmetic, freearc, … – but never I used library so simple to learn and use. Plus, again, that has such a good ratio at reasonable speed and memory requirements (of course, if you want the best, there’s always PAQ in flavour of your choice, but who can afford to wait 10 hours for 1 file to be compressed?).

But enough talking, more coding. As an example, here’s how to do file-to-file compression (leave out error handling and comments, and whole code is 18 lines long, including declarations, etc.):

bool PackFile(const char* file_name)
{
    // open the input file
    FILE* file = fopen(file_name, "rb");
    if (0 == file)
        return false;

    // open the output file
    std::string out_file_name = file_name;
    out_file_name += ".bz2";
    FILE* out_file = fopen(out_file_name.c_str(), "wb");
    if (0 == out_file)
    {
        fclose(file);
        return false;
    }

    int bz2error;
    BZFILE* out_bz2 = BZ2_bzWriteOpen(&bz2error, out_file, 9, 0, 0);
    if (BZ_OK != bz2error)
    {
        fclose(file);
        fclose(out_file);
        return false;
    }

    // load file data into buffer, and store them to bzip2-out stream
    char buffer[1024];
    uint loaded_len;
    while ((loaded_len = fread(buffer, 1, 1024, file)) > 0)
    {
        BZ2_bzWrite(&bz2error, out_bz2, buffer, loaded_len);
        if (BZ_OK != bz2error)
        {
            fclose(file);
            BZ2_bzWriteClose(&bz2error, out_bz2, 1, 0, 0);
            fclose(out_file);
            return false;
        }
    }

    // close in file
    fclose(file);

    // close out bzip2 stream and the file
    uint total_in, total_cmp;   // how many bytes we read, and resulting compressed size
    BZ2_bzWriteClose(&bz2error, out_bz2, 0, &total_in, &total_cmp);
    fclose(out_file);

    return true;
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s