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




Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/