Re: [AD] Endianness in file routines |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
> > --- /cvs/allegro/src/bmp.c Wed Oct 16 14:02:38 2002
> > +++ allegro/src/bmp.c Mon Oct 28 11:23:44 2002
> > @@ -262,9 +262,7 @@
> > c.b = pack_getc(f);
> > c.g = pack_getc(f);
> > c.r = pack_getc(f);
> > - bmp->line[line][i*3+_rgb_r_shift_24/8] = c.r;
> > - bmp->line[line][i*3+_rgb_g_shift_24/8] = c.g;
> > - bmp->line[line][i*3+_rgb_b_shift_24/8] = c.b;
> > + bmp_write24((unsigned long)bmp->line[line]+i*3, makecol24(c.r,
> > c.g, c.b)); nbytes += 3;
> > }
>
> Shouldn't the original code work too, assuming the shift variables are
> set up properly?
I don't think so.
Assume the standard RGB layout
_rgb_r_shift_24 = 0
_rgb_g_shift_24 = 8
_rgb_b_shift_24 = 16
that is 0BGR within each "arithmetic" int, little or big-endian.
With the original code, we save in memory RGB.
Now, we have in alconfig.h
#ifdef ALLEGRO_LITTLE_ENDIAN
AL_INLINE(int, bmp_read24, (unsigned long addr),
{
unsigned char *p = (unsigned char *)addr;
int c;
c = p[0];
c |= (int)p[1] << 8;
c |= (int)p[2] << 16;
return c;
})
#elif defined ALLEGRO_BIG_ENDIAN
AL_INLINE(int, bmp_read24, (unsigned long addr),
{
unsigned char *p = (unsigned char *)addr;
int c;
c = (int)p[0] << 16;
c |= (int)p[1] << 8;
c |= p[2];
return c;
})
#else
#error endianess not defined
#endif
On little-endian platforms, upon reading RGB from memory, bmp_read24()
correctly returns 0BGR in an arithmetic int.
But on big-endian platforms, upon reading RGB from memory, bmp_read24()
returns 0RGB in an arithmetic int, which is in contradiction with our
hypothesis
_rgb_r_shift_24 = 0
_rgb_g_shift_24 = 8
_rgb_b_shift_24 = 16
Same problem of course with the opposite RGB layout.
--
Eric Botcazou