J
junk5
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
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