Re: [dev] Looking for simple, alpha supporting image format

From: FRIGN <dev_AT_frign.de>
Date: Wed, 16 Jul 2014 15:51:07 +0200

On Wed, 16 Jul 2014 14:51:32 +0200
Anselm R Garbe <garbeam_AT_gmail.com> wrote:

> why not just binary
>
> uint32 width (BIG_ENDIAN)
> uint32 height (BIG_ENDIAN)
> uint32 pixel(s) (BIG_ENDIAN)
>
> with uint64 length of pixels = width * height;
>
> If you need ascii, just dump it to some hex or base64 converter and good is...

Great idea!
Using endian(3), this would be all rounded up. Extracting the number is
as easy as:

###

uint8_t *buf;
(..)
uint32_t width = (buffer[i ] << 0) |
                 (buffer[i+1] << 8) |
                 (buffer[i+2] << 16) |
                 (buffer[i+3] << 24);
width = be32toh(width);

###

Where i is the offset of the first byte of the given number.

Then we could also scrap this entire whitespace-blank-w/e-discussion
and just define the header this way:

Bytes Description
9 imagefile
4 uint32 width (BIG_ENDIAN)
4 uint32 height (BIG_ENDIAN)
[
1 uint8 red
1 uint8 green
1 uint8 blue
1 uint8 alpha
]

This would also make it possible to parse the header without allocating
any memory at all (if we wanted to ;)). If we allocate a 13-bytes buffer,
this is good, too. Then we can directly use be32toh():

1) a) allocate 9 bytes to buf and strcmp(buf, "imagefile")
   b) read char by char and compare on the go.
2) a) width: read() and traverse (4 times):
        width |= (c << i*8);
      height: analogous
   b) use be32toh()
3) go on and store the data to memory now

In code this would look like this:

        char *
        readimage(int fd, uint32_t *w, uint32_t *h)
        {
                char buf[13], *data;
                size_t len;

                if (read(fd, buf, 13) != 13 || strcmp(buf, "imagefile"))
                        return NULL;
                
                *w = be32toh(buf[9+0]);
                *h = be32toh(hdr[9+4]);
                len = (*w) * (*h) * 4;

                if (!(data = malloc(len)) || read(fd, data, len) != len) { free(data);
                        return NULL;
                }
                return data;
        }

This is very similar to Markus Teich' approach, but be32toh is much
more favorable than ntohs, because it's clear we are converting from
big endian.
Now, what's left to discuss if we should use uint32 or uint16.

Cheers

FRIGN

-- 
FRIGN <dev_AT_frign.de>
Received on Wed Jul 16 2014 - 15:51:07 CEST

This archive was generated by hypermail 2.3.0 : Wed Jul 16 2014 - 16:00:23 CEST