473,480 Members | 1,823 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Unpacking 12bits integer type into 16bits

Hi there,

I am looking for comments on the following piece of code: is this
efficiently written ? I am only focusing on little endian system for
now.

out : will contains a buffer of 16bits values where each value is at
most 12bits
in: contains *packed* 12bits value
n: is the size in char of in (multiple of 2).

char *unpack12into16(char *out, const char *in, size_t n)
{
uint16_t *out16 = (uint16_t*)out;
char *pout = out;
const uint8_t *p = (const uint8_t*)in;
const uint8_t * end = p + n;
for(; p != end; )
{
uint8_t b0, b1, b2;
b0 = *p++;
b1 = *p++;
b2 = *p++;
*out16++ = ((b0 >4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f);
*out16++ = ((b2 & 0x0f) << 8) + ((b1 >4) << 4) + (b2 >4);
}
return pout;
}

Thanks
-Mathieu
Jun 27 '08 #1
3 4454
mathieu wrote:
Hi there,

I am looking for comments on the following piece
of code: is this efficiently written?
It's not inefficient.
I am only focusing on little endian system for
now.
Your unpack should mirror the pack.
out : will contains a buffer of 16bits values where
each value is at most 12bits
in: contains *packed* 12bits value
How are they packed? Your code suggests they are packed
in nibbles.
n: is the size in char of in (multiple of 2).
n needs to be a multiple of 3.
>
char *unpack12into16(char *out, const char *in, size_t n)
Unsigned char is better than char (which may be signed).
{
uint16_t *out16 = (uint16_t*)out;
char *pout = out;
You don't need pout as you never modify out.
const uint8_t *p = (const uint8_t*)in;
const uint8_t * end = p + n;
for(; p != end; )
{
uint8_t b0, b1, b2;
b0 = *p++;
b1 = *p++;
b2 = *p++;
*out16++ = ((b0 >4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f);
*out16++ = ((b2 & 0x0f) << 8) + ((b1 >4) << 4) + (b2 >4);
So input bytes 0x12, 0x34, 0x56 extract to 0x0124, 0x0635?!
}
return pout;
}
I would write it like...

void *unpack12into16_pn(void *out, const void *in, size_t n)
{
const uint8_t *in8 = in;
uint16_t *out16 = out;
unsigned full, half;

for (n /= 3; n--; )
{
full = *in8++;
half = *in8++;
*out16++ = (full << 4) | (half & 0x0F);

full = *in8++;
*out16++ = ((full & 0x0F) << 8) | (half & 0xF0) | (full >4);
}

return out;
}

Which only really changes ((b0 >4) << 8) + ((b0 & 0x0f) << 4)
to the obvious (with the specs spelled out) b0 << 4. Note that
b0 will promote to int which can support 0xFFF (4095).

--
Peter
Jun 27 '08 #2

"mathieu" <ma***************@gmail.comwrote in message
news:bd**********************************@c65g2000 hsa.googlegroups.com...
Hi there,

I am looking for comments on the following piece of code: is this
efficiently written ? I am only focusing on little endian system for
now.

out : will contains a buffer of 16bits values where each value is at
most 12bits
in: contains *packed* 12bits value
n: is the size in char of in (multiple of 2).

char *unpack12into16(char *out, const char *in, size_t n)
{
uint16_t *out16 = (uint16_t*)out;
char *pout = out;
const uint8_t *p = (const uint8_t*)in;
const uint8_t * end = p + n;
for(; p != end; )
{
uint8_t b0, b1, b2;
b0 = *p++;
b1 = *p++;
b2 = *p++;
*out16++ = ((b0 >4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f);
*out16++ = ((b2 & 0x0f) << 8) + ((b1 >4) << 4) + (b2 >4);
}
return pout;
}
Does this code work? I couldn't get it to function properly, although we may
have different assumptions about bit-ordering.

I did try this version which appears to work. In this code, I know that char
is 8 bits and short is 16 bits:

void myunpack(short *q, unsigned char *p, int n)
{
unsigned char *end = p+n;
unsigned char b0,b1,b2;

while (p!=end)
{
b0 = *p++;
b1 = *p++;
b2 = *p++;
*q++ = ((b1 & 0xf) << 8) + b0;
*q++ = (b1>>4) + (b2<<4);
}
}

Even if we use different bit ordering, you appear to have quite a few extra
shifts in yours.

And I think there is some scope for improvement if you need speed. I've
moved declarations b0,b1,b2 outside the loop (probably makes no difference,
but just in case).

If your computer allows unaligned access, you may be able to read b0,b1 as a
single 16-bit value, and the bottom 12 bits will be retained. The top 4 is
added to the next byte. (You seem to be making the assumption that n is a
multiple of 3.)

--
Bartc
Jun 27 '08 #3
On Apr 18, 1:04 am, "Bartc" <b...@freeuk.comwrote:
"mathieu" <mathieu.malate...@gmail.comwrote in message

news:bd**********************************@c65g2000 hsa.googlegroups.com...
Hi there,
I am looking for comments on the following piece of code: is this
efficiently written ? I am only focusing on little endian system for
now.
out : will contains a buffer of 16bits values where each value is at
most 12bits
in: contains *packed* 12bits value
n: is the size in char of in (multiple of 2).
char *unpack12into16(char *out, const char *in, size_t n)
{
uint16_t *out16 = (uint16_t*)out;
char *pout = out;
const uint8_t *p = (const uint8_t*)in;
const uint8_t * end = p + n;
for(; p != end; )
{
uint8_t b0, b1, b2;
b0 = *p++;
b1 = *p++;
b2 = *p++;
*out16++ = ((b0 >4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f);
*out16++ = ((b2 & 0x0f) << 8) + ((b1 >4) << 4) + (b2 >4);
}
return pout;
}

Does this code work? I couldn't get it to function properly, although we may
have different assumptions about bit-ordering.

I did try this version which appears to work. In this code, I know that char
is 8 bits and short is 16 bits:

void myunpack(short *q, unsigned char *p, int n)
{
unsigned char *end = p+n;
unsigned char b0,b1,b2;

while (p!=end)
{
b0 = *p++;
b1 = *p++;
b2 = *p++;
*q++ = ((b1 & 0xf) << 8) + b0;
*q++ = (b1>>4) + (b2<<4);
}

}

Even if we use different bit ordering, you appear to have quite a few extra
shifts in yours.

And I think there is some scope for improvement if you need speed. I've
moved declarations b0,b1,b2 outside the loop (probably makes no difference,
but just in case).

If your computer allows unaligned access, you may be able to read b0,b1 as a
single 16-bit value, and the bottom 12 bits will be retained. The top 4 is
added to the next byte. (You seem to be making the assumption that n is a
multiple of 3.)

--
Bartc
Indeed you were right ! My code was bogus. Thanks a bunch !

-Mathieu
Jun 27 '08 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
1747
by: george young | last post by:
I came across an cool python feature that I've not seen discussed. This may be *implied* by the language reference manual http://docs.python.org/ref/assignment.html], but it was never obvious to...
8
3609
by: Paul McGuire | last post by:
I'm trying to manage some configuration data in a list of tuples, and I unpack the values with something like this: configList = for data in configList: name,a,b,c = data ... do something...
14
13003
by: David Fisher | last post by:
The most common sizes of integer types seem to be: 8 bits - signed char 16 bits - short 16 or 32 bits - int 32 or 64 bits - long Question #1: Does anyone know how common sizes other than...
5
1969
by: Chris | last post by:
Hi I'm attempting to write a client for an existing p2p network. The protocol defines that ints are packed into 4 bytes for transfer. // Creating the byte vector using the following is fine:...
4
3350
by: Claudio Grondi | last post by:
I need to unpack on a Windows 2000 machine some Wikipedia media .tar archives which are compressed with TAR 1.14 (support for long file names and maybe some other features) . It seems, that...
18
2998
by: David Buchan | last post by:
Hi guys, This may be a dumb question; I'm just getting into C language here. I wrote a program to unpack a binary file and write out the contents to a new file as a list of unsigned integers....
61
3280
by: John Baker | last post by:
When declaring an integer, you can specify the size by using int16, int32, or int64, with plain integer being int32. Is integer the accepted default in the programming community? If so, is...
16
1318
by: John Salerno | last post by:
I'm a little confused, but I'm sure this is something trivial. I'm confused about why this works: ('more', 'less'), ('something', 'nothing'), ('good', 'bad')) (('hello', 'goodbye'), ('more',...
4
6931
by: mathieu | last post by:
Hello, Has anyone heard of the 'half' floating point type. That would be a 16bits floating point, see for example: http://oss.sgi.com/projects/ogl-sample/registry/ARB/half_float_pixel.txt ...
0
7048
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7091
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
6743
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
6966
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
4488
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
2999
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
2988
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1303
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
185
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.