Sign in to follow this  
Endar

byte swapping problem

Recommended Posts

I found that the jpeg format was a big endian format, so to read it I needed to write a couple of small functions that would swap the bytes in a variable.
/**
 * Swap the bytes in the var
 * \param s A reference to the var to swap the bytes
 */
void swapBytes(short& s)
{
	char b0 = s & 0xff;				// lower byte
	char b1 = (s & 0xff00) >> 8;	// upper byte

	s = 0;

	s |= b0 << 8;		// set lower byte to upper byte
	s |= (b1 & 0xff);	// set upper byte to lower byte
}


I was having problems with this until about 5 minutes ago. Previously, the last line was "s |= b1;", which I thought would work fine. But, I had a value 0x8400, which after being swapped became 0xff84. Where would it get the 0xff for the upper byte? Would it transfer OR the short with 2 bytes worth of b1, regardless of the fact that it's a single byte char? Edit:: oh, and just for the sake of writing proper code, should the second-to-last line be "s |= (b0 << 8) & 0xff00; ?"

Share this post


Link to post
Share on other sites
The ff comes from using chars instead of unsigned chars. Because when you promote a char to a short, it needs to maintian its sign.
So
0000001 = 1
becomes
00000000000001 = 1

and
11111111 = -1
becomes
1111111111111111 = -1

With unsigned values it just fills it with zeros.

You could use something like this to be shorter.


inline unsigned short swap16(const unsigned short x){
return(x<<8|x>>8);
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
htons (Big Endian short to Little Endian short)
htonl (Big Endian long to Little Endian long)

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
htons (Big Endian short to Little Endian short)
htonl (Big Endian long to Little Endian long)


I think you mean Little Endian to Big Endian.

And those are nops on a Big Endian Machine (PC's are Little Endian).

Share this post


Link to post
Share on other sites
this should also work (doesn't need a bit hack either):


short swapBytes(const short& s)
{
short retval = s;
unsigned char* data = reinterpret_cast<unsigned char*>(&retval);
std::swap(data[0], data[1]);
return retval;
}



though for my LightWave file parser I use a more
general function:


template<class T>
inline T ReverseByteOrder(const T& value) {
T retval = value;
unsigned char* data = reinterpret_cast<unsigned char*>(&retval);
std::reverse(data, data + sizeof(T));
return retval;
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this