IMG_lbm.c
changeset 96 cada40fddd77
parent 95 7fcb46931afc
child 97 e1161bd417c4
     1.1 --- a/IMG_lbm.c	Fri Dec 19 18:04:48 2003 +0000
     1.2 +++ b/IMG_lbm.c	Sun Jan 04 17:30:48 2004 +0000
     1.3 @@ -25,8 +25,10 @@
     1.4  /* This is a ILBM image file loading framework
     1.5     Load IFF pictures, PBM & ILBM packing methods, with or without stencil
     1.6     Written by Daniel Morais ( Daniel@Morais.com ) in September 2001.
     1.7 -   24 bits ILBM files support added by Marc Le Douarain (mavati@club-internet.fr)
     1.8 -   in December 2002.
     1.9 +   24 bits ILBM files support added by Marc Le Douarain (mavati AT club-internet
    1.10 +   POINT fr) in December 2002.
    1.11 +   EHB and HAM (specific Amiga graphic chip modes) support added by Marc Le Douarain
    1.12 +   (mavati AT club-internet POINT fr) in December 2003.
    1.13  */
    1.14  
    1.15  #include <stdio.h>
    1.16 @@ -86,12 +88,13 @@
    1.17  	Uint32      width;
    1.18  	BMHD	      bmhd;
    1.19  	char        *error;
    1.20 +	Uint8       flagHAM,flagEHB;
    1.21  
    1.22  	Image   = NULL;
    1.23  	error   = NULL;
    1.24  	MiniBuf = NULL;
    1.25  
    1.26 -	if ( !SDL_RWread( src, id, 4, 1 ) ) 
    1.27 +	if ( !SDL_RWread( src, id, 4, 1 ) )
    1.28  	{
    1.29  		error="error reading IFF chunk";
    1.30  		goto done;
    1.31 @@ -131,6 +134,8 @@
    1.32  	nbcolors = 0;
    1.33  
    1.34  	memset( &bmhd, 0, sizeof( BMHD ) );
    1.35 +	flagHAM = 0;
    1.36 +	flagEHB = 0;
    1.37  
    1.38  	while ( memcmp( id, "BODY", 4 ) != 0 )
    1.39  	{
    1.40 @@ -181,6 +186,23 @@
    1.41  			nbcolors = size / 3;
    1.42  		}
    1.43  
    1.44 +		if ( !memcmp( id, "CAMG", 4 ) ) /* Amiga ViewMode  */
    1.45 +		{
    1.46 +			Uint32 viewmodes;
    1.47 +			if ( !SDL_RWread( src, &viewmodes, sizeof(viewmodes), 1 ) )
    1.48 +			{
    1.49 +				error="error reading CAMG chunk";
    1.50 +				goto done;
    1.51 +			}
    1.52 +
    1.53 +			bytesloaded = size;
    1.54 +			viewmodes = SDL_SwapBE32( viewmodes );
    1.55 +			if ( viewmodes & 0x0800 )
    1.56 +				flagHAM = 1;
    1.57 +			if ( viewmodes & 0x0080 )
    1.58 +				flagEHB = 1;
    1.59 +		}
    1.60 +
    1.61  		if ( memcmp( id, "BODY", 4 ) )
    1.62  		{
    1.63  			if ( size & 1 )	++size;  	/* padding ! */
    1.64 @@ -215,13 +237,13 @@
    1.65  		goto done;
    1.66  	}
    1.67  
    1.68 -	if ( ( Image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, bmhd.h, bmhd.planes==24?24:8, 0, 0, 0, 0 ) ) == NULL )
    1.69 +	if ( ( Image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, bmhd.h, (bmhd.planes==24 || flagHAM==1)?24:8, 0, 0, 0, 0 ) ) == NULL )
    1.70  	   goto done;
    1.71  
    1.72  	/* Update palette informations */
    1.73  
    1.74  	/* There is no palette in 24 bits ILBM file */
    1.75 -	if ( nbcolors>0 )
    1.76 +	if ( nbcolors>0 && flagHAM==0 )
    1.77  	{
    1.78  		Image->format->palette->ncolors = nbcolors;
    1.79  
    1.80 @@ -233,6 +255,23 @@
    1.81  			Image->format->palette->colors[i].g = *ptr++;
    1.82  			Image->format->palette->colors[i].b = *ptr++;
    1.83  		}
    1.84 +
    1.85 +		/* Amiga EHB mode (Extra-Half-Bright) */
    1.86 +		/* 6 bitplanes mode with a 32 colors palette */
    1.87 +		/* The 32 last colors are the same but divided by 2 */
    1.88 +		/* Some Amiga pictures save 64 colors with 32 last wrong colors,
    1.89 +		/* they shouldn't !, and here we overwrite these 32 bad colors. */
    1.90 +		if ( (nbcolors==32 || flagEHB ) && (1<<bmhd.planes)==64 )
    1.91 +		{
    1.92 +			Image->format->palette->ncolors = 64;
    1.93 +			ptr = &colormap[0];
    1.94 +			for ( i=32; i<64; i++ )
    1.95 +			{
    1.96 +				Image->format->palette->colors[i].r = (*ptr++)/2;
    1.97 +				Image->format->palette->colors[i].g = (*ptr++)/2;
    1.98 +				Image->format->palette->colors[i].b = (*ptr++)/2;
    1.99 +			}
   1.100 +		}
   1.101  	}
   1.102  
   1.103  	/* Get the bitmap */
   1.104 @@ -298,7 +337,7 @@
   1.105  		/* One line has been read, store it ! */
   1.106  
   1.107  		ptr = Image->pixels;
   1.108 -		if ( nbplanes==24 )
   1.109 +		if ( nbplanes==24 || flagHAM==1 )
   1.110  			ptr += h * width * 3;
   1.111  		else
   1.112  			ptr += h * width;
   1.113 @@ -309,7 +348,7 @@
   1.114  		}
   1.115  		else		/* We have to un-interlace the bits ! */
   1.116  		{
   1.117 -			if ( nbplanes!=24 )
   1.118 +			if ( nbplanes!=24 && flagHAM==0 )
   1.119  			{
   1.120  				size = ( width + 7 ) / 8;
   1.121  
   1.122 @@ -335,34 +374,63 @@
   1.123  			}
   1.124  			else
   1.125  			{
   1.126 +				Uint32 finalcolor = 0;
   1.127  				size = ( width + 7 ) / 8;
   1.128  				/* 24 bitplanes ILBM : R0...R7,G0...G7,B0...B7 */
   1.129 +				/* or HAM (6 bitplanes) or HAM8 (8 bitplanes) modes */
   1.130  				for ( i=0; i<width; i=i+8 )
   1.131  				{
   1.132  					Uint8 maskBit = 0x80;
   1.133  					for ( j=0; j<8; j++ )
   1.134  					{
   1.135 -						Uint32 color24 = 0;
   1.136 -						Uint32 maskColor24 = 1;
   1.137 +						Uint32 pixelcolor = 0;
   1.138 +						Uint32 maskColor = 1;
   1.139  						Uint8 dataBody;
   1.140  						for ( plane=0; plane < nbplanes; plane++ )
   1.141  						{
   1.142  							dataBody = MiniBuf[ plane*size+i/8 ];
   1.143  							if ( dataBody&maskBit )
   1.144 -								color24 = color24 | maskColor24;
   1.145 -							maskColor24 = maskColor24<<1;
   1.146 +								pixelcolor = pixelcolor | maskColor;
   1.147 +							maskColor = maskColor<<1;
   1.148 +						}
   1.149 +						/* HAM : 12 bits RGB image (4 bits per color component) */
   1.150 +						/* HAM8 : 18 bits RGB image (6 bits per color component) */
   1.151 +						if ( flagHAM )
   1.152 +						{
   1.153 +							switch( pixelcolor>>(nbplanes-2) )
   1.154 +							{
   1.155 +								case 0: /* take direct color from palette */
   1.156 +									finalcolor = colormap[ pixelcolor*3 ] + (colormap[ pixelcolor*3+1 ]<<8) + (colormap[ pixelcolor*3+2 ]<<16);
   1.157 +									break;
   1.158 +								case 1: /* modify only blue component */
   1.159 +									finalcolor = finalcolor&0x00FFFF;
   1.160 +									finalcolor = finalcolor | (pixelcolor<<(16+(10-nbplanes)));
   1.161 +									break;
   1.162 +								case 2: /* modify only red component */
   1.163 +									finalcolor = finalcolor&0xFFFF00;
   1.164 +									finalcolor = finalcolor | pixelcolor<<(10-nbplanes);
   1.165 +									break;
   1.166 +								case 3: /* modify only green component */
   1.167 +									finalcolor = finalcolor&0xFF00FF;
   1.168 +									finalcolor = finalcolor | (pixelcolor<<(8+(10-nbplanes)));
   1.169 +									break;
   1.170 +							}
   1.171 +						}
   1.172 +						else
   1.173 +						{
   1.174 +							finalcolor = pixelcolor;
   1.175  						}
   1.176  						if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
   1.177  						{
   1.178 -							*ptr++ = color24>>16;
   1.179 -							*ptr++ = color24>>8;
   1.180 -							*ptr++ = color24;
   1.181 +							*ptr++ = finalcolor>>16;
   1.182 +							*ptr++ = finalcolor>>8;
   1.183 +							*ptr++ = finalcolor;
   1.184  						}
   1.185  						else
   1.186  						{
   1.187 -							*ptr++ = color24;
   1.188 -							*ptr++ = color24>>8;
   1.189 -							*ptr++ = color24>>16;
   1.190 +							*ptr++ = finalcolor;
   1.191 +							*ptr++ = finalcolor>>8;
   1.192 +							*ptr++ = finalcolor>>16;
   1.193  						}
   1.194  
   1.195  						maskBit = maskBit>>1;