Skip to main content
GameDev.net gamedev.net
🔒 Locked

byte swapping problem

Started by Endar Jun 11, 2006 at 11:05 PM 3 replies 450+ views
Original Post
Endar
Endar
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; ?"
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper
Cocalus
Cocalus
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);}
Cocalus
Cocalus
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).
yadango
yadango
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;}

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.