By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,234 Members | 2,041 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,234 IT Pros & Developers. It's quick & easy.

Reading 16-bit raw data

P: n/a
Hi

I need to read raw 16 bit data from a file, where the first byte is the
most significant byte of the first data value and the second byte is
the least significant byte of the first data value (the next pair or
bytes and the next etc. specify the second and third values).

For example, if I had a file containing

0xff22
0xfe23
0x11ff
0x1000

then the two values I should read back would be:

0x01002023
and
0x00120F00

I wrote the following code snippet which I thought would read the data:

// The input and output variables are ifstream and ofstream objects
respectively.
char currentByte[1]; // A buffer for reading the file.
unsigned int thisValue;
bool oddByte = true; // The first byte is odd-numbered, the second is
even-numbered, etc.
while(input->good()) // While we can extract data from the input
file.
{
// Get the next byte, and write the next value if the byte read
is an even byte.
input->read(currentByte, 1); // Probably inefficient, but I'll
speed things up later.
if(oddByte)
{
thisValue = (unsigned int)(*currentByte); // Most significant byte.
*output << "No mult.: thisValue is: " << thisValue << std::endl; //
Debug noise.

thisPixel *= 256; // Equiv. to leftshift by 8 places.
*output << "Current thisValue is: " << thisVaule << std::endl; //
Debugg noise.
}
else
{
thisValue += (unsigned int)(*currentByte); // Least significant
byte.
*output << "Current thisValue is: " << thisValue << std::endl; //
Debug noise.
*output << thisValue << " "; // Write out the computed value
in decimal.
}

// Invert oddByte.
oddByte = !oddByte;
}

If the above is a bit impenetrable, here's my thinking: each value in
the file is represented by two bytes, an odd byte (the MSB) and an even
byte (the LSB). oddByte is inverted after every read. If we just read a
MSB, then we need to left-shift the bits read by 8 binary places (I do
a multiply by 256 above, but it's the same thing). If we just read a
LSB, then we need to add this onto the result of doing the left-shift
by 8. After adding the LSB I write out the value to an output stream
(the other writes are just for debugging purposes).

I compile the above using gcc -Wall and it compiles cleanly. The code
runs OK, but I don't get out what I expect; instead I get values like:

4294967229
4294950144
4294950263
4294967241
4294953216
4294953122

which are far too big to have come from 16-bit values. (They look like
pointer addresses to me.)

It's been a long while since I've needed to do any bit-twiddling (or
used C++ in anger). Which bit of basic C/C++ have I forgotten?

Thanks,

C

Dec 15 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
ju***@microserf.org.uk wrote:
[..]
I compile the above using gcc -Wall and it compiles cleanly. The code
runs OK, but I don't get out what I expect; instead I get values like:

4294967229
4294950144
4294950263
4294967241
4294953216
4294953122
Display them in hex.
which are far too big to have come from 16-bit values. (They look like
pointer addresses to me.)
They are just large numbers (0xffff....).
It's been a long while since I've needed to do any bit-twiddling (or
used C++ in anger). Which bit of basic C/C++ have I forgotten?

Perhaps you need to have your "currentbyte" as _unsigned_char_...

V
Dec 15 '05 #2

P: n/a

ju***@microserf.org.uk wrote:
thisValue = (unsigned int)(*currentByte); // Most significant byte.
*output << "No mult.: thisValue is: " << thisValue << std::endl; //
Debug noise.


It's the conversion - try instead:

thisValue = (unsigned int)(*currentByte & 0xff)
, and it' will work.

/Patrick

Dec 15 '05 #3

P: n/a
On 15 Dec 2005 13:14:24 -0800, lo******@kth.se wrote:

ju***@microserf.org.uk wrote:
thisValue = (unsigned int)(*currentByte); // Most significant byte.
*output << "No mult.: thisValue is: " << thisValue << std::endl; //
Debug noise.


It's the conversion - try instead:

thisValue = (unsigned int)(*currentByte & 0xff)
, and it' will work.


Don't you mean:

thisValue = ((unsigned int)(*currentByte)) & 0xff;

??

--
Bob Hairgrove
No**********@Home.com
Dec 15 '05 #4

P: n/a
Hi all, and thanks for your responses.

A few minutes after posting I tried using the "int get()" function
instead of the "get(char*)" version, and things seem to work fine.

C

Dec 15 '05 #5

P: n/a

Bob Hairgrove wrote:
On 15 Dec 2005 13:14:24 -0800, lo******@kth.se wrote:

ju***@microserf.org.uk wrote:
thisValue = (unsigned int)(*currentByte); // Most significant byte.
*output << "No mult.: thisValue is: " << thisValue << std::endl; //
Debug noise.


It's the conversion - try instead:

thisValue = (unsigned int)(*currentByte & 0xff)
, and it' will work.


Don't you mean:

thisValue = ((unsigned int)(*currentByte)) & 0xff;


This is not necessary if currentByte were of type pointer to unsigned
char, rather than plain char! Use unsigned char for binary data.

An unsigned char will promote to signed int, or to unsigned int,
depending on whichever will hold all values of its type, including
sign.

On most platforms, unsigned char will promote to int, because it's
narrower, and so int can hold all unsigned char values.

The only remaining issue then is that the & 0xFF may be done against a
signed int zero value that doesn't have an all-bits-zero
representation. Under sign-magnitude, you are okay, because a negative
zero still has all-zero bits in the mantissa, but under one's
complement, zero can be represented by a bit pattern of all 1's.
Masking out the least significant 8 bits of that produces 255.

But even on hardware that uses one's complement for signed integers, I
wouldn't expect an unsigned char zero to promote to the negative flavor
of zero! That zero would have to be the result of some arithmetic
computation involving negative values.

So basically, you are worried to portability to one's complement
machines on which conversions are pathologically behaved.

If hardware like that were designed to day, it wouldn't see the light
of day. The reams of nonportable code that would not run on it would
seal its fate in the marketplace. :)

Dec 15 '05 #6

P: n/a
ju***@microserf.org.uk wrote:

I need to read raw 16 bit data from a file, where the first byte is the
most significant byte of the first data value and the second byte is
the least significant byte of the first data value (the next pair or
bytes and the next etc. specify the second and third values).

For example, if I had a file containing

0xff22
Do you mean the file contains 0xFF followed by 0x22 ?
0xfe23
0x11ff
0x1000

then the two values I should read back would be:

0x01002023
and
0x00120F00


Does anyone else follow this? I haven't had my coffee today

Dec 16 '05 #7

P: n/a

Old Wolf wrote:
ju***@microserf.org.uk wrote:

I need to read raw 16 bit data from a file, where the first byte is the
most significant byte of the first data value and the second byte is
the least significant byte of the first data value (the next pair or
bytes and the next etc. specify the second and third values).

For example, if I had a file containing

0xff22


Do you mean the file contains 0xFF followed by 0x22 ?
0xfe23
0x11ff
0x1000

then the two values I should read back would be:

0x01002023
and
0x00120F00


Does anyone else follow this? I haven't had my coffee today


You're right - it should of course be 0xff followed by 0x22. In his
example he used 16bit numbers, shifted the first one 8 bits and added
the next one.
(0xff22 << 8) + 0xfe23 = 0x1002023

Dec 16 '05 #8

P: n/a
>>Do you mean the file contains 0xFF followed by 0x22 ?
0xfe23
0x11ff

0x1000
then the two values I should read back would be:

0x01002023
and
0x00120F00


Does anyone else follow this? I haven't had my coffee today


Obviously neither had I! Sorry all---I was 'forgetting' that one hex
digit was four bits, rather than two, but I hope the example served its
purpose.

Dec 16 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.