Reading arbitrary number of bits from a byte stream

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Reading arbitrary number of bits from a byte stream

Post by randomMesh »

Hi,

i try to get pixel data out of GIF89a images.
Parsing the file works ok, but now i struggle with the LZW encoded image data.

I have a byte stream of image data, out of which i need to extract n bits at a time. n can between 2 and 12 inclusive, that means that a code (sequence of bits) can spread over 1 - 2 bytes. n can increase when i read a certain value.

I thought of extracting the codes like this:

Code: Select all

 
    unsigned int first_code_size = static_cast<int>(LZW_minimum_code_size) + 1;
    const unsigned int increaseCodeSizeWhen = (1 << LZW_minimum_code_size) - 1;
 
    //A special Clear code is defined which resets all compression/decompression
    //parameters and tables to a start-up state.
    const unsigned int clear_code = (1 << LZW_minimum_code_size);
 
    //An End of Information code is defined that explicitly indicates the end of
    //the image data stream.
    const unsigned int end_code = clear_code + 1;
 
    const unsigned char* data = code_stream.data();
    unsigned char current_byte = 0;
    unsigned short current_code = 0; //12 bit max
    unsigned int last_code = 0;
 
    //this in a loop until end_code is read
    current_code = ?;
 
how would i write a loop that does this?

Should look something like:

Code: Select all

 
while (current_code == end_code)
{
    current_code = ((data[index+1] - 0) & 0x0f) + ( ((data[index] - 0) & 0xfc) << 2 );
}
 
How to get the mask /shifting right?

My question is all about splitting bytes into chunks of bits, the LZW stuff would be next.

Further reading about LZW compression in GIF:
http://www.matthewflickinger.com/lab/wh ... e_data.asp
http://gingko.homeip.net/docs/file_formats/lzwgif.html
"Whoops..."
MartinVee
Posts: 139
Joined: Tue Aug 02, 2016 3:38 pm
Location: Québec, Canada

Re: Reading arbitrary number of bits from a byte stream

Post by MartinVee »

You might want to look at how GIFLIB does this.

Check the function DGifGetPrefixChar.
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Re: Reading arbitrary number of bits from a byte stream

Post by randomMesh »

Thanks,

i think i solved it.

Code: Select all

 
unsigned char get_bit(unsigned char *data, const unsigned bitoffset)
{
    unsigned char c = (unsigned char) (data[bitoffset >> 3]); // X>>3 is X/8
    unsigned int bitmask = 1 << (bitoffset & 7);  // X&7 is X%8
 
    return ((c & bitmask) != 0) ? 1 : 0;
}
 
unsigned int get_bits(unsigned char* data, const unsigned bitOffset,
        const unsigned numBits)
{
    unsigned int bits = 0;
 
    //for (unsigned int currentbit = bitOffset; currentbit < bitOffset + numBits; ++currentbit)
    for (unsigned int currentbit = bitOffset + numBits;
            currentbit-- > bitOffset;)  //reverse order
    {
        bits = bits << 1;
        bits = bits | get_bit(data, currentbit);
    }
 
    return bits;
}
 
"Whoops..."
Post Reply