Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > 12 Bit data inside 16 bit words: how to truncate blanking bits

Reply
Thread Tools

12 Bit data inside 16 bit words: how to truncate blanking bits

 
 
johnny
Guest
Posts: n/a
 
      01-08-2009
Dear comp.lang.c members,

I have the following problem:
I am writing an application which reads data from a device. This data
is 12 bit wide and comes as a stream of words to be stored to a file.
At the moment I write it to 16 bit words, which creates an unessecary
overhead.

I currently use uint16_t.

How may I do this?

Any comments welcome

Thank you and
best regards,
Johann
 
Reply With Quote
 
 
 
 
s0suk3@gmail.com
Guest
Posts: n/a
 
      01-08-2009
On Jan 8, 9:17*am, johnny <horvat.joh...@gmx.net> wrote:
> Dear comp.lang.c members,
>
> I have the following problem:
> I am writing an application which reads data from a device. This data
> is 12 bit wide and comes as a stream of words to be stored to a file.
> At the moment I write it to 16 bit words, which creates an unessecary
> overhead.
>
> I currently use uint16_t.
>
> How may I do this?


It depends on what you need to do with the data. If all you need is to
read it and then write it to somewhere else, you can just use unsigned
char[] (i.e., "bytes") and be done with it.

But if you need to perform arithmetic operations on the 12-bit
integers, for example, you can still use unsigned char[] to hold the
data and then copy individual 12-bit units into uint16_t variables to
perform the desired operations:

unsigned char* data;
size_t len;
ReadDeviceData(&data, &len);

// Fetch the first 12-bit unit and store it in a uint16_t
uint16_t num = *(uint16_t*) data >> 4;

(Your program may need to take byte ordering into account.) You may
write a macro to fetch a 12-bit value that is at a specific "bit
offset":

//
// Returns a 12-bit unit as a uint16_t
//
// @param offset the bit offset of the 12-bit value; must be
// a multiple of 12
// @param ptr a pointer to the block of memory
//
#define GET_UNIT(offset, ptr) \
(*(uint16_t*) ((ptr) + (offset) / CHAR_BIT) >> \
4 - (offset) % CHAR_BIT & \
~0U >> (offset) % CHAR_BIT)

Using such a macro you could step through every 12-bit value in an
arbitrary block of memory (unsigned char[]). For example, this loop
would print all 12-bit values as decimal numbers:

for (size_t offset = 0; offset + 12 < len * CHAR_BIT; offset +=
12)
printf("%" PRIu16 "\n", GET_UNIT(offset, data));

The point is that now you're using an array of unsigned char to hold
the data (thus saving space), and then copying individual 12-bit
values into uint16_t variables whenever you need to perform an
operation on them.

Sebastian

 
Reply With Quote
 
 
 
 
Tim Rentsch
Guest
Posts: n/a
 
      01-08-2009
Eric Sosman <> writes:

> johnny wrote:
> > Dear comp.lang.c members,
> >
> > I have the following problem:
> > I am writing an application which reads data from a device. This data
> > is 12 bit wide and comes as a stream of words to be stored to a file.
> > At the moment I write it to 16 bit words, which creates an unessecary
> > overhead.
> >
> > I currently use uint16_t.
> >
> > How may I do this?

>
> With a bit of shifting and OR-ing you can pack two 12-bit
> samples into three 8-bit bytes (uint8_t) and write those to
> the file. [snip]


It seems to me that doing such packing takes at least four bits
of shifting.

(Sorry, I couldn't resist...)
 
Reply With Quote
 
Tomás Ó hÉilidhe
Guest
Posts: n/a
 
      01-09-2009
On Jan 8, 11:12*pm, Eric Sosman <Eric.Sos...@sun.com> wrote:

> * * *With a bit of shifting and OR-ing you can pack two 12-bit
> samples into three 8-bit bytes (uint8_t) and write those to
> the file.


The amount of memory need is calculable as follows:

(amount_twelves * 3 / 2) + (amount_twelves * 3 % 2)

Throw together in five minutes so likely to contain a bug:

#include <assert.h>
#include <stdint.h>

uint_fast16_t GetChunk(uint8_t *const mem, uint_fast32_t chunk_index)
{
if ( !(chunk_index & 1) ) /* If index is not odd */
{
/* The first 8 bits are in the leading octet,
The last 4 bits are the lowest 4 in the trailing octet */

return (uint_fast16_t)(mem[chunk_index * 3 / 2])
| (mem[chunk_index * 3 / 2 + 1] & 0xF);
}
else
{
/* The first 4 bits are the high 4 in the leading octet,
The last 4 bits are the low 4 in the trailing octet */

--chunk_index;

return (uint_fast16_t)(mem[chunk_index * 3 / 2 + 1] >> 4)
| (mem[chunk_index * 3 / 2 + 2] & 0xF);
}
}


void SetChunk(uint8_t *const mem, uint_fast32_t chunk_index,
uint_fast16_t const val)
{
assert(val <= 0xFFFu);

if ( !(chunk_index & 1) ) /* If index is not odd */
{
/* The first 8 bits are in the leading octet,
The last 4 bits are the lowest 4 in the trailing octet */

mem[chunk_index * 3 / 2] = val;

mem[chunk_index * 3 / 2 + 1] &= 0xF0;

mem[chunk_index * 3 / 2 + 1] |= val >> 8;
}
else
{
/* The first 4 bits are the high 4 in the leading octet,
The last 8 bits are in the trailing octet */

--chunk_index;

mem[chunk_index * 3 / 2 + 1] &= 0x0F;

mem[chunk_index * 3 / 2 + 1] = val & 0xFu << 4;

mem[chunk_index * 3 / 2 + 2] = val >> 4;
}
}

Again, likely to contain a bug.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
shifting bits, shift 32 bits on 32 bit int GGG C++ 10 07-06-2006 06:09 AM
Crystal Reports .Net Blanking Password TylerB ASP .Net 3 08-26-2004 06:16 PM
Blanking on Redirect =?Utf-8?B?VG9iZQ==?= ASP .Net 1 02-20-2004 08:47 PM
8-Bits vs 12 or 16 bits/pixel; When does more than 8 bits count ? Al Dykes Digital Photography 3 12-29-2003 07:08 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57