Swap endianness of a 24bit int?

Recommended Posts

Hi everyone. I've found plenty of help and code snippits to swap endianness of common types like int, long etc, but I can't find (or work out) how to swap a 24bit int. Here's where I'm stuck:
.... blah code ....

typedef struct {
unsigned char   flags:8;
unsigned int    length:24;

.... blah code ....

// Insert some swap magic here!


I need to swap the endianness of block_header->length. My attempts give a number I know can't be correct. Then again, maybe my approach is incorrect?

Share on other sites
This should do it:
block_header->length =   ((block_header->length & 0x00ff0000) >> 16) |   ((block_header->length & 0x0000ff00)) |   ((block_header->length & 0x000000ff) << 16);

Share on other sites
Awesome! Thank you.

Share on other sites
This makes no sense to me, and I bet a lot of other people have glanced over this thread thinking the same thing. If the endianness of incomming data is wrong then it has to be the case that the order of either 2, 4 or 8 bytes etc is reversed. It is logically impossible for only 3 bytes to be out of order due to wrong-endian reasons.

If this really is an endian related issue then I'm pretty sure you'll find that you actually need to swap all four bytes of the BLOCK_HEADER structure around.

If the flags do currently appear to be correct then I suspect you're off-by-one in your reading of the data, which would happen to place the flags byte where you want it.
Are you sure you need to dynamically allocate such a small structure?

Share on other sites
Quote:
 Original post by iMalcIf this really is an endian related issue then I'm pretty sure you'll find that you actually need to swap all four bytes of the BLOCK_HEADER structure around.

Why do you say this? a byte is not effected by endianess.

Share on other sites
Quote:
 Original post by iMalcThis makes no sense to me, and I bet a lot of other people have glanced over this thread thinking the same thing. If the endianness of incomming data is wrong then it has to be the case that the order of either 2, 4 or 8 bytes etc is reversed. It is logically impossible for only 3 bytes to be out of order due to wrong-endian reasons.If this really is an endian related issue then I'm pretty sure you'll find that you actually need to swap all four bytes of the BLOCK_HEADER structure around.

I'm scanning through .flac files to extract the metadata, specifically the Vorbis comments. The spec for the block header is here:
Quote:
 METADATA_BLOCK_HEADER<1>Last-metadata-block flag: '1' if this block is the last metadata block before the audio blocks, '0' otherwise. <7>BLOCK_TYPE 0 : STREAMINFO 1 : PADDING 2 : APPLICATION 3 : SEEKTABLE 4 : VORBIS_COMMENT 5 : CUESHEET 6 : PICTURE 7-126 : reserved 127 : invalid, to avoid confusion with a frame sync code <24>Length (in bytes) of metadata to follow (does not include the size of the METADATA_BLOCK_HEADER)

The spec also states: "All numbers are big-endian coded." So I use Evil Steve's

Basically what I'm doing is reading the METADATA_BLOCK_HEADER, checking if the BLOCK_TYPE == 4, and fseek-ing 'length' to the next METADATA_BLOCK_HEADER if it isn't. Repeat until I'm at the Vorbis comments. It works perfectly.
Quote:
 If the flags do currently appear to be correct then I suspect you're off-by-one in your reading of the data, which would happen to place the flags byte where you want it.

If I was off by one, wouldn't that make the fseek jump to the wrong position? If the position was off by just one the Vorbis comments (vorbis-spec-comment) would be read incorrectly? My code appears to work on every .flac file (from various encoders, downloads etc) I've tried it with.
Quote:
 Are you sure you need to dynamically allocate such a small structure?

I dunno! [embarrass] Probably not. I'm still a newbie, slowly learning though! [smile]

Share on other sites
Okay that makes sense now.
I think that they probably expect people to extract the bytes individually and reconstruct the length value by shifting and ORing, rather than reading it directly into the struct and then rearranging it later. An advantage of this is that your code would then work the same on either endian machine, without any kind of compile switches etc.
But what Evil Steve has posted will work for you too.

Create an account

Register a new account

• Forum Statistics

• Total Topics
628372
• Total Posts
2982305

• 10
• 9
• 13
• 24
• 11