Index:
[thread]
[date]
[subject]
[author]
From: Andrew Apted <ajapted@netspace.net.au>
To : ggi-develop@eskimo.com
Date: Mon, 10 Aug 1998 15:22:37 +1000
Re: LibGGI & 24/32 bit modes
Marcus writes:
> > 1) 32 bit modes -- the set of masks describe the layout perfectly,
> > without any funniness like you get with reverse-endian 16 bit modes,
> > so shouldn't we avoid using the GGI_PF_REVERSE_ENDIAN flag here ?
>
> Sure, every mode should be described in the most simple way that still
> is correct.
Yep.
> > 2) 24 bit modes have to be read / written 1 byte at a time, but in
> > what order ? There are two possibilities:
> >
> > buf[0] = (ggi_pixel & 0xff0000) >> 16;
> > buf[1] = (ggi_pixel & 0xff00) >> 8;
> > buf[2] = (ggi_pixel & 0xff)
> >
> > versus
> >
> > buf[0] = (ggi_pixel & 0xff)
> > buf[1] = (ggi_pixel & 0xff00) >> 8;
> > buf[2] = (ggi_pixel & 0xff0000) >> 16;
> >
> > We should pick one and stick to it. I think the second version looks
> > easier to optimize (e.g. *buf++ = (uint8) pix; pix >>= 8).
>
> Well, that will depend on the endianness.
> When reading/writing multiple pixels at a time we should put 4 bytes
> at a time (8 an 64-bit machines), and the order we put the bytes in
> when writing a single pixel must be the same as it is when putting
> multiple ones.
No, writing multible pixels at a time is CPU-endianness dependent. For
example when writing 16 bit pixels to a put-buffer, they still have to
end up in 0,1,2,3 order, so if the app wants to write 4 of these at once
then that is an optimization which has nothing to do with the
pixel-endianness.
Now, a single 24 bit pixel is something that cannot be read/written at
once as a whole (unlike 8/16/32 bit pixels), so it must be read/written
as three bytes. These three bytes have an order in the put-buffer, and
the burning question remains: how do these three bytes correspond to a
ggi_pixel value ?
For example, here is a piece of code I wrote which converts a line of 8
bit pixels to arbitrary sized pixels (where lookup[] contains the results
of ggiMapColor) :
ggi_pixel lookup[256];
uint8 trans_buffer[8192];
void win_translate_hline(int x, int y, int w, uchar *data)
{
int ww = w;
uint8 *buf1 = (uint8 *) trans_buffer;
uint16 *buf2 = (uint16 *) trans_buffer;
uint32 *buf4 = (uint32 *) trans_buffer;
switch ((graphtype & GT_ACCESS_MASK) >> GT_ACCESS_SHIFT)
case 8:
for (; ww > 0; ww--) {
*buf1++ = lookup[*data++];
}
break;
case 16:
for (; ww > 0; ww--) {
*buf2++ = lookup[*data++];
}
break;
--> case 24:
--> for (; ww > 0; ww--) {
--> ggi_pixel pix = lookup[*data++];
-->
--> *buf1++ = pix; pix >>= 8;
--> *buf1++ = pix; pix >>= 8;
--> *buf1++ = pix;
--> }
--> break;
case 32:
for (; ww > 0; ww--) {
*buf4++ = lookup[*data++];
}
break;
}
ggiPutHLine(vis, x, y, w, trans_buffer);
}
That assumes that for 24 bit modes, the LSB of a ggi_pixel value is
stored as the first byte of each group of three. Should we make this
the official behaviour ?
Cheers,
_____________________________________________ ____
\ /
Andrew Apted <andrew@ggi-project.org> \/
Index:
[thread]
[date]
[subject]
[author]