I have a void type array. I want to create a function which will read 12 bits in each time and store it in a unsigned int type variable.

Any ideas?

Thank you.

Recommended Answers

All 18 Replies

I have a void type array. I want to create a function which will read 12 bits in each time and store it in a unsigned int type variable.

Any ideas?

Thank you.

So you wish to extract the first 12 bits from each element in your void array? How, in 12 bit chunks, the first 12 bits from each 32bit word, first 12 bits from 16 bit words? More info required here to be specific but essentially you need to cast your void pointer to a know type, probably an unsigned int and then pull out the first twelve bits by masking off the bits you do not require. Can you give more details...

In the past I have used this extract function. It is generalized to allow for extracting a field of n-bits from a position p in a 32 bit word. The result will be right adjusted. To extract the first twelve bits set n to 12 and p to 0.
So, say you have an array of ints to simplify matters...

int arr[10];

void do_something( void *data ) // pass array as pointer to void
{
   int *pi = (int*)data; // cast void pointer to desired type
   unsigned int extracted_bits[10];
   for( int i = 0; i < 10; ++i )
      extracted_bits[i] = bits_get(  pi[i], 0, 12 ); 

}

unsigned int bits_getr( int x, int p, int n )
{
   return( x >> (p + 1 - n)) & ~(~0 << n );
}

Its some time since I actually use this so I can't explaint it properly right now. Will get back later with good explanation. However it displays the general principal. Get a pointer to the word you wish to extract bit from. Cast it to the desired type. Use bit twiddling to extract the bits.


To explain...

The expression
x >> (p+1-n) moves the desired field to the right end of the word. ~0 is all the 1 bits. Shifting this left by n with ~0 << n places 0s in the right most bits and then complementing that with ~, eg. ~(~0 << n) makes a bit mask with 1s in the rightmost n bits.
& that with the desired field shifted to the first n bits in the word
x >> (p+1-n) & ~(~0<<n) gives you just the contents of those first n bits.

So you wish to extract the first 12 bits from each element in your void array? How, in 12 bit chunks, the first 12 bits from each 32bit word, first 12 bits from 16 bit words? More info required here to be specific but essentially you need to cast your void pointer to a know type, probably an unsigned int and then pull out the first twelve bits by masking off the bits you do not require. Can you give more details...

I have a void type buffer which holds 12 bit grey scale image. I want to read 12 bits from the void type buffer with an index which will start from 0 and till the end of the buffer. In each iteration it will read 12 bits from the buffer and convert these 12 bits into a number which will thwn be assigned to a unsigned int.

so buffer looks like

bits
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24...

and you want to read bits 1 to 12, followed by 13 to 24, 24 to 36 and so on...

so buffer looks like

bits
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24...

and you want to read bits 1 to 12, followed by 13 to 24, 24 to 36 and so on...

Exactly. Then I want to put these 12 bits to represent a integer value and assign it to a integer. Following is my TRY---

typedef struct {
    unsigned __int8 bit1  :1;
	unsigned __int8 bit2  :1;
	unsigned __int8 bit3  :1;
	unsigned __int8 bit4  :1;
	unsigned __int8 bit5  :1;
	unsigned __int8 bit6  :1;
	unsigned __int8 bit7  :1;
	unsigned __int8 bit8  :1;
	unsigned __int8 bit9  :1;
	unsigned __int8 bit10 :1;
	unsigned __int8 bit11  :1;
	unsigned __int8 bit12  :1;
} datapixel;


static unsigned int _Rice_ReadWord( void *ptr, unsigned int idx )
{	


 unsigned  int   x;
	datapixel pixel;

pixel =  *(reinterpret_cast<datapixel*>(ptr)+idx);

				x=(pixel.bit1*pow(2.0,0))+(pixel.bit2*pow(2.0,1))+(pixel.bit3*pow(2.0,2))+(pixel.bit4*pow(2.0,3))+(pixel.bit5*pow(2.0,4))+(pixel.bit6*pow(2.0,5))+
					(pixel.bit7*pow(2.0,6))+(pixel.bit8*pow(2.0,7))+(pixel.bit9*pow(2.0,8))+(pixel.bit10*pow(2.0,9))+(pixel.bit11*pow(2.0,10))+(pixel.bit12*pow(2.0,11));


return x;
}

I do not know if I am going in the right direction.

Thank you.....

Its a way to go certainly. the problem with bit fields is that they are highly implementation dependent and as such not very portable.
For that reason I have personally always avoided their use, so i shall refrain from commenting further.

Exactly. Then I want to put these 12 bits to represent a integer value and assign it to a integer. Following is my TRY---

typedef struct {
    unsigned __int8 bit1  :1;
	unsigned __int8 bit2  :1;
	unsigned __int8 bit3  :1;
	unsigned __int8 bit4  :1;
	unsigned __int8 bit5  :1;
	unsigned __int8 bit6  :1;
	unsigned __int8 bit7  :1;
	unsigned __int8 bit8  :1;
	unsigned __int8 bit9  :1;
	unsigned __int8 bit10 :1;
	unsigned __int8 bit11  :1;
	unsigned __int8 bit12  :1;
} datapixel;


static unsigned int _Rice_ReadWord( void *ptr, unsigned int idx )
{	


 unsigned  int   x;
	datapixel pixel;

pixel =  *(reinterpret_cast<datapixel*>(ptr)+idx);

				x=(pixel.bit1*pow(2.0,0))+(pixel.bit2*pow(2.0,1))+(pixel.bit3*pow(2.0,2))+(pixel.bit4*pow(2.0,3))+(pixel.bit5*pow(2.0,4))+(pixel.bit6*pow(2.0,5))+
					(pixel.bit7*pow(2.0,6))+(pixel.bit8*pow(2.0,7))+(pixel.bit9*pow(2.0,8))+(pixel.bit10*pow(2.0,9))+(pixel.bit11*pow(2.0,10))+(pixel.bit12*pow(2.0,11));


return x;
}

I do not know if I am going in the right direction.

Thank you.....

Whilst refraining from commenting further I do have a quick question regarding the above... Does it work?

No because the size of datapixel will be in bytes and a mutiple of whole bytes

No because the size of datapixel will be in bytes and a mutiple of whole bytes

I was wondering about alignment.

As you have said bit fields are platform dependent. Data alignment is an issue and is also platform dependent but for the datapixel structure defined in terms of __int8 aka char it may well be able to align the structure on any byte boundary.

On many platforms structures are aligned at the largest alignment required for any of its members. A struct containing only char aligns at byte boundaries, a struct containing only short (2 byte int) and smaller aligns at 2 byte boundaries, a struct containing only long (4 byte int) and smaller aligns at 4 byte boundaries.

All data types have a size in bytes so the datapixel data type has a minimum of 4 padding bits. It may have 2 padding bytes as well if the compiler has decided to align the structure at 4 byte boundaries.

So the expression *(reinterpret_cast<datapixel*>(ptr)+idx) for values of idx != 0 will be skipping bits, the padding bits.

Bit fields are really just semantic magic for access the bits in an integer data field without resorting to using the bitwise operators. Since bit field implementation is platform dependent and bitwise operators are not conventional wisdom is to leave bit fields alone and use bitwise operators.

To extract data from a series of bytes (char * or void *) where the bit size of the fields you want to extract is != N*CHAR_BIT the only portable way to do it, in fact the way to do it if the bits are tightly packed as in this case is to write the code using bit wise operators to extract the bits required from the data in sequence.


BTW I think this

unsigned int bits_getr( int x, int p, int n )
{
return( x >> (p + 1 - n)) & ~(~0 << n );
}

should be

unsigned int bits_getr( int x, int p, int n )
{
return( x >> p) & ~(~0 << n );
}

For the example you give the original code results in a left shift of -11 which does not sound right.

Whilst refraining from commenting further I do have a quick question regarding the above... Does it work?

No it does not. Now I am planning to use Bit set container class for another try.


For the example you give the original code results in a left shift of -11 which does not sound right.

The code is correct as written but it gets a field to the right of the position bit.

i.e. to extract the 5 bits from 11 to 15 you would call bits_getr with position 15 and field length of 5. Like so...

int i =00x0000B800;
x = bits_getr( i, 15, 5 );

However, I will admit to intending to show my bits_getl function instead, which will get a field from the left of the position, but i copied the wrong one. :)

At the moment I am trying to impliment bitset container class to deal with my 12 bit data. Is there any idea to convert the void pointer to my custom made 12 bit vector?

Thank you.

At the moment I am trying to impliment bitset container class to deal with my 12 bit data. Is there any idea to convert the void pointer to my custom made 12 bit vector?

Thank you.

Do you know how alignment affects your bitsets? What does the size of yuur bitsets comeout as?

Do you know how alignment affects your bitsets? What does the size of yuur bitsets comeout as?

I just want to give some further information on my work--
I have a void type array which is holding a grey scale image. Each pixel is represented by 12 bits so they range from 0 to 4096. If I can cut the void type memory into 12 bit intervals and put it in a container with an index, then My life can become very simple.

Alignment is Linear.
I am planning to do is as follows
At first declare a bit set with 12 bits.
Then convert the void array to a collection of 12 bit bitset array with index.

Do you have any information on how to convert the void array to bitset?

Thnak you.

Sorry no. But I thought you wanted to extract these values to an unsigned int? It seems like you are now complicating matters by extracting to a bitset first.

If I can convert the void type pointer to bitset array. I can easily convert the 12 bits to any type of number I wish. In that way I can use this array for my use.

I do not think a bitset is going to be very useful to you. You will have to extract each bit out of the stream individually and put it in the bitset from what I see of its implementation.

I think you might be better off creating a Pixel class of your own based on a 16 bit integer data type that can be constructed from a 16 bit integer or 3 4 bit nibbles. Then use a vector to hold you class data.

You class would contain helpers to extract specific bits if you are really interested in them but that doesn't seem likely as the 12 bits actually represent a level/value.

Then you will need to write code to extract 12 bits at a time (or 3 4 bit nibbles) from you buffer of data.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.