Converting a ubyte[] to a struct with respect to endianness?

Stefan Koch via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Jun 24 07:08:48 PDT 2017


On Saturday, 24 June 2017 at 02:52:23 UTC, Felix wrote:
> I'm trying to read in just the first part of a .png file to 
> peek at it's width and height without loading in the whole 
> file. I'm using FreeImage for reading the whole file but since 
> it doesn't have a function to let me peek at the image size 
> before loading it all in I'm rolling my own.
>
> I've gotten as a far as reading in the first 16 bytes which 
> includes an 8 byte signature, then the length and type of the 
> first chunk:
>
> struct Header {
>     ubyte[8] signature;
>     uint length;
>     char[4] type;
> }
> union Un {
>     Header h;
>     ubyte[16] u;
> }
>
> auto f = File(path, "r");
> foreach (ubyte[] buffer; f.byChunk(16)){
>     Un fff;
>     fff.u = buffer[0..16];
>     writeln(fff.h);
>     break;
> }
>
> It prints out:
> Header([137, 80, 78, 71, 13, 10, 26, 10], 218103808, "IHDR")
>
> The signature is correct, the type is correct, but the value I 
> get for length should be 13, not 218103808. So I'm guessing my 
> ubytes are in the wrong order in the uint... how should I put 
> them around the correct way so that my code won't break on 
> another machine with different endianness?

I would advise a look at sqlite.d 
https://github.com/UplinkCoder/sqlite-d
which solves the same problem albeit for sqlite database files 
and for png.
But it provides the means of simply putting a BigEndian!uint into 
your struct and have conversion on stuff be automatically handled.


More information about the Digitalmars-d-learn mailing list