Frequency Coding

The source code below is a bit coder class that can be used for reading or writing a compressed file. The source code provides access to a new type of entropy encoder. This new type of coder uses an algorithm I have created which I call frequency coding. The class I provide is  currently using two symbols, but is not limited to two. A frequency coder is a variant of a range coder with some minor similarities with huffman coding. Without getting into details, the main difference between a range coder and a frequency coder is that a frequency coder does not require the use of multiplication or division by only using the frequencies of the symbols but still retaining fractions, where a range coder or arithmetic coder use the probability to output a codeword. Huffman coding does not use fractions or at least retain fractions as the code is being created, where a frequency coder does, but also requires a sorted list of frequencies from lowest to highest to properly handle fractions. I will be putting out a paper in the near future that will explain how a frequency encoder can work for any number base.

 

download -> bitcoder.h (6886 downloads )

 

/*
Copyright (c) 2013 Chris Chunick, email@chrischunick.com
All rights reserved.

Redistribution and use in source and binary forms are permitted
provided that the above copyright notice and this paragraph are
duplicated in all such forms and that any documentation,
advertising materials, and other materials related to such
distribution and use acknowledge that the software was developed
by Chris Chunick  The name of Chris Chunick may not be used to 
endorse or promote products derived from this software without 
specific prior written permission.

THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

class bitcoder
{

private:
    FILE *fin;
    FILE *fout;    
    unsigned int top,bot,range;
    unsigned int code;
    unsigned int m[32];

    void init()
    {
        passed=0;
        bot=0, top=-1;
        range=top-bot;
        code=0;
        for(unsigned int i=0;i<32;i++)m[i]=(0x7FFFFFFF>>(31-i));
    }

public:
    unsigned int passed;
    unsigned int fsize;

    void initcoder(FILE* fin, FILE* fout)
    {
        init();
        this->fin=fin;
        this->fout=fout;
    }

    void startdecoder()
    {
        for(unsigned int i=0;i<4;i++)fsize=(fsize<<8)|getc(fin);
        for(unsigned int i=0;i<4;i++)code=(code<<8)|getc(fin);
    }

    void startencoder()
    {
        fseek(fin,0,SEEK_END),fsize=ftell(fin),fseek(fin,0,SEEK_SET);
        putc((fsize>>24),fout),putc((fsize>>16),fout),putc((fsize>>8),fout),putc(fsize,fout);
        passed+=4;
    }

    void flushencoder()
    {
        putc(bot>>24,fout);putc(bot>>16,fout);putc(bot>>8,fout);putc(bot,fout);
        passed+=4;
    }

    void fencode(const unsigned int bit, const unsigned int c0, const unsigned int c1)
    {
        unsigned int lbit=(c0>c1),w=31,lo=c0,tc=c0+c1,tr=top-bot;

        if(lbit)lo=c1;

        while(((tc)>=(tr>>w))&&w!=-1)w--;

        if(w<-1)
        {
            if (lbit^bit)bot=(((bot>>w)+(lo)+1)<<w)|(bot&m[w]);
            else top=(((bot>>w)+(lo))<<w)|(top&m[w]);
        }
        else 
        {
            top=bot=bot+bit;
        }

        while((top^bot)<=0xFFFFFF || top<bot)
        {
            putc(bot>>24,fout);
            bot<<=8,top=(top<<=8)|0xFF;
            passed++;
        }
    }

    unsigned int fdecode(const unsigned int c0, const unsigned int c1)
    {
        unsigned int lbit=(c0>c1),w=31,lo=c0,bit,tc=c0+c1,tr=top-bot;

        if(lbit)lo=c1;
        while(((tc)>=(tr>>w))&&w!=-1)w--;

        if(w<-1)
        {
            bit=lbit^((code>>w)>((bot>>w)+lo));
            if (lbit^bit)bot=(((bot>>w)+(lo)+1)<<w)|(bot&m[w]);
            else top=(((bot>>w)+(lo))<<w)|(top&m[w]);
        }
        else top=bot=bot+(bit=code!=bot);

        while((top^bot)<=0xFFFFFF || top<bot)
        {
            code=(code<<8)|fgetc(fin);                    
            bot<<=8,top=(top<<=8)|0xFF;
        }

        return bit;
    }

};
FacebooktwitterredditpinterestlinkedinmailFacebooktwitterredditpinterestlinkedinmail
Posted in Articles, Compression | Leave a comment

Operations Control Centre

This is a small dynamic project I have been developing over the course of the year during off work hours. It originated from the idea of having a network map done up specifically for work displayed on two monitors. Instead of using tools to create a flowchart or network topology I built a control that asynchronously allows for communication between the host machine and a destination until the program terminates. Each connection sits in a group and each group can connect to other groups – these features are automated. This is a great tool for everyone to visually see the status of the network in real-time and gives an overview of the network. A quick glance over at this two screen Ops program and you can see what servers are running and which ones are not. Future additions include audio alerts and better video alerts.

 

Ops

 

 

FacebooktwitterredditpinterestlinkedinmailFacebooktwitterredditpinterestlinkedinmail
Posted in New Projects, Projects | Leave a comment

X-Hex

X-Hex is a game I programmed a long time ago. This game is still very exciting to play and I believe was ahead of its time when it was written. The idea stemmed from my brother who had described a game to me he had played on the Unisys computers from the 1980’s.  E-games wanted to publish this title originally but that deal fell through in order to keep IP and publishing rights.  I think in the near future I plan to resurrect this product in all of it’s glory. Today this game would be perfect for a tablet or mobile device which did not exist back when it was created. The best part of programming this game was the artificial intelligence.  I designed the multiplayer aspect to be editable, and it worked great. You were able to choose to play against multiple personalities, all of whom had there very distinct game play.

 

xhex

FacebooktwitterredditpinterestlinkedinmailFacebooktwitterredditpinterestlinkedinmail
Posted in Old Projects, Projects | 2 Comments

Part 2 – Encoding a simple value

For the second part, we will encode a simple 4 bit integer value – let’s use the the 4 bit integer 6 to encode, this is our “message”. The integer six has a 4 bit binary value of 0110. To help us understand the process of encoding we will illustrate step by step how it is done. For our simple encoder we will use the following variables top(top), bottom(bot),bit (bit), probability(prob), message(message). This example will assume a 50% probability of any bit value 0 or 1 to be encoded.

First we initialize our range. Now remember from the first example, our range is our decimal values. Well let’s start with the same range 0 to 15 (a 4 bit range). Our range has a top and a bottom. We will assign the bottom variable the bottom value of the range, that value is a 0. Next we assign the top value, the top portion of our range, that value is a 15.

Currently we have assigned the following variables some initial values:

[code lang=’cpp’]message = 0110 
bot = 0
top = 15[/code]

Here are the steps of the encoding process for our message;

  1. Extract our first bit to encode, from our message; bit = 0   {message=0110}
  2. Always get the probability of the zero bit; prob = 0.5 (use 0.5 for our example)
  3. Encode our first bit using our range of 0 to 15. Partition the range into two new ranges using the probability of the zero bit.
    1. first partition is 0 to 7 (50% of the total range).  The second partition is 8 to 15 (what is left over of the total range).
    2. Now we need to update our variables with our new range. The new range will depend on the current bit we are encoding. If the bit is 0 then we choose the first partition if the bit is 1 then we choose the second partition. In this example the bit is 0 so our variables would be update like so:
      bot = 0
      top = 7

Quick overview of encoding our message:

  1. Extract bit from message
  2. Get probability of the zero bit
  3. Partition the range into two ranges
  4. Choose partition depending on bit, 0 bit=first partition, 1 bit=second partition
  5. Update top and bot variables with the new range
  6.  Goto step 1, extracting the next bit in the message

You would continue this process until you are at the end of your message or if the range is equal to zero ie:  (top bot) is equal to zero.  We will get into more detail on this in the next part of our series. Below is an illustration of the process of encoding our message.  

 4 bits have been successfully encoded with an end result/code of 6. This is the same as the original message only because the probabilities for each bit to be encoded are equal, 50%. So the message has no compression and the code or result does not change from the original message.  This is the beginning of bit encoding.

FacebooktwitterredditpinterestlinkedinmailFacebooktwitterredditpinterestlinkedinmail
Posted in Compression | Leave a comment

Part 1 – Introduction to a simple bit encoder

To start off in the first part our series we will take a look at the properties of a 4 bit integer to help imagine where our simple bit encoder comes from. For purposes of encoding and decoding data we will refer to our decimal values as our range, and every range has a top and a bottom value.

Looking at the illustration below we can see that the msb of our range can be partitioned into two groups. The second table illustrates the partioning of the msb, as you can see an integer range of 0 to 7 has a msb of 0, and an integer range of 8 to 16 has a msb value of 1. This table can be further partitioned into two ranges using the third bit. The range of 0 to 3 has a 3rd bit of 0,  and the range of 4 to 7 has a 3rd bit of 1.

Binary Partitioning of a 4 bit integer

Following this sequence you can continue to equally sub divide our 4 bit integer ranges into  further binary nodes, creating a binary tree. What is the signfigance in this ? Well our bit encoder will work with a range of values and partition that range depending on the probability of the bit we wish to encode. For the simplest example we will use a 50% probability for every bit, for encoding in our next part.

Continue to Part 2 – Encoding a simple value

FacebooktwitterredditpinterestlinkedinmailFacebooktwitterredditpinterestlinkedinmail
Posted in Compression | Leave a comment