Skip to content

Commit

Permalink
Marc Le Douarain - Fri, 26 Dec 2003 18:23:42 +0100
Browse files Browse the repository at this point in the history
 * Added EHB and HAM mode support to the ILBM loader
  • Loading branch information
slouken committed Jan 4, 2004
1 parent 46c847e commit 9fc3a61
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 17 deletions.
2 changes: 2 additions & 0 deletions CHANGES
@@ -1,4 +1,6 @@
1.2.4:
Marc Le Douarain - Fri, 26 Dec 2003 18:23:42 +0100
* Added EHB and HAM mode support to the ILBM loader
Sam Lantinga - Wed Nov 19 00:23:44 PST 2003
* Updated libtool support for new mingw32 DLL build process
Holger Schemel - Mon, 04 Aug 2003 21:50:52 +0200
Expand Down
102 changes: 85 additions & 17 deletions IMG_lbm.c
Expand Up @@ -25,8 +25,10 @@
/* This is a ILBM image file loading framework
Load IFF pictures, PBM & ILBM packing methods, with or without stencil
Written by Daniel Morais ( Daniel@Morais.com ) in September 2001.
24 bits ILBM files support added by Marc Le Douarain (mavati@club-internet.fr)
in December 2002.
24 bits ILBM files support added by Marc Le Douarain (mavati AT club-internet
POINT fr) in December 2002.
EHB and HAM (specific Amiga graphic chip modes) support added by Marc Le Douarain
(mavati AT club-internet POINT fr) in December 2003.
*/

#include <stdio.h>
Expand Down Expand Up @@ -86,12 +88,13 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
Uint32 width;
BMHD bmhd;
char *error;
Uint8 flagHAM,flagEHB;

Image = NULL;
error = NULL;
MiniBuf = NULL;

if ( !SDL_RWread( src, id, 4, 1 ) )
if ( !SDL_RWread( src, id, 4, 1 ) )
{
error="error reading IFF chunk";
goto done;
Expand Down Expand Up @@ -131,6 +134,8 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
nbcolors = 0;

memset( &bmhd, 0, sizeof( BMHD ) );
flagHAM = 0;
flagEHB = 0;

while ( memcmp( id, "BODY", 4 ) != 0 )
{
Expand Down Expand Up @@ -181,6 +186,23 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
nbcolors = size / 3;
}

if ( !memcmp( id, "CAMG", 4 ) ) /* Amiga ViewMode */
{
Uint32 viewmodes;
if ( !SDL_RWread( src, &viewmodes, sizeof(viewmodes), 1 ) )
{
error="error reading CAMG chunk";
goto done;
}

bytesloaded = size;
viewmodes = SDL_SwapBE32( viewmodes );
if ( viewmodes & 0x0800 )
flagHAM = 1;
if ( viewmodes & 0x0080 )
flagEHB = 1;
}

if ( memcmp( id, "BODY", 4 ) )
{
if ( size & 1 ) ++size; /* padding ! */
Expand Down Expand Up @@ -215,13 +237,13 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
goto done;
}

if ( ( Image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, bmhd.h, bmhd.planes==24?24:8, 0, 0, 0, 0 ) ) == NULL )
if ( ( Image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, bmhd.h, (bmhd.planes==24 || flagHAM==1)?24:8, 0, 0, 0, 0 ) ) == NULL )
goto done;

/* Update palette informations */

/* There is no palette in 24 bits ILBM file */
if ( nbcolors>0 )
if ( nbcolors>0 && flagHAM==0 )
{
Image->format->palette->ncolors = nbcolors;

Expand All @@ -233,6 +255,23 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
Image->format->palette->colors[i].g = *ptr++;
Image->format->palette->colors[i].b = *ptr++;
}

/* Amiga EHB mode (Extra-Half-Bright) */
/* 6 bitplanes mode with a 32 colors palette */
/* The 32 last colors are the same but divided by 2 */
/* Some Amiga pictures save 64 colors with 32 last wrong colors,
/* they shouldn't !, and here we overwrite these 32 bad colors. */
if ( (nbcolors==32 || flagEHB ) && (1<<bmhd.planes)==64 )
{
Image->format->palette->ncolors = 64;
ptr = &colormap[0];
for ( i=32; i<64; i++ )
{
Image->format->palette->colors[i].r = (*ptr++)/2;
Image->format->palette->colors[i].g = (*ptr++)/2;
Image->format->palette->colors[i].b = (*ptr++)/2;
}
}
}

/* Get the bitmap */
Expand Down Expand Up @@ -298,7 +337,7 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
/* One line has been read, store it ! */

ptr = Image->pixels;
if ( nbplanes==24 )
if ( nbplanes==24 || flagHAM==1 )
ptr += h * width * 3;
else
ptr += h * width;
Expand All @@ -309,7 +348,7 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
}
else /* We have to un-interlace the bits ! */
{
if ( nbplanes!=24 )
if ( nbplanes!=24 && flagHAM==0 )
{
size = ( width + 7 ) / 8;

Expand All @@ -335,34 +374,63 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
}
else
{
Uint32 finalcolor = 0;
size = ( width + 7 ) / 8;
/* 24 bitplanes ILBM : R0...R7,G0...G7,B0...B7 */
/* or HAM (6 bitplanes) or HAM8 (8 bitplanes) modes */
for ( i=0; i<width; i=i+8 )
{
Uint8 maskBit = 0x80;
for ( j=0; j<8; j++ )
{
Uint32 color24 = 0;
Uint32 maskColor24 = 1;
Uint32 pixelcolor = 0;
Uint32 maskColor = 1;
Uint8 dataBody;
for ( plane=0; plane < nbplanes; plane++ )
{
dataBody = MiniBuf[ plane*size+i/8 ];
if ( dataBody&maskBit )
color24 = color24 | maskColor24;
maskColor24 = maskColor24<<1;
pixelcolor = pixelcolor | maskColor;
maskColor = maskColor<<1;
}
/* HAM : 12 bits RGB image (4 bits per color component) */
/* HAM8 : 18 bits RGB image (6 bits per color component) */
if ( flagHAM )
{
switch( pixelcolor>>(nbplanes-2) )
{
case 0: /* take direct color from palette */
finalcolor = colormap[ pixelcolor*3 ] + (colormap[ pixelcolor*3+1 ]<<8) + (colormap[ pixelcolor*3+2 ]<<16);
break;
case 1: /* modify only blue component */
finalcolor = finalcolor&0x00FFFF;
finalcolor = finalcolor | (pixelcolor<<(16+(10-nbplanes)));
break;
case 2: /* modify only red component */
finalcolor = finalcolor&0xFFFF00;
finalcolor = finalcolor | pixelcolor<<(10-nbplanes);
break;
case 3: /* modify only green component */
finalcolor = finalcolor&0xFF00FF;
finalcolor = finalcolor | (pixelcolor<<(8+(10-nbplanes)));
break;
}
}
else
{
finalcolor = pixelcolor;
}
if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
{
*ptr++ = color24>>16;
*ptr++ = color24>>8;
*ptr++ = color24;
*ptr++ = finalcolor>>16;
*ptr++ = finalcolor>>8;
*ptr++ = finalcolor;
}
else
{
*ptr++ = color24;
*ptr++ = color24>>8;
*ptr++ = color24>>16;
*ptr++ = finalcolor;
*ptr++ = finalcolor>>8;
*ptr++ = finalcolor>>16;
}

maskBit = maskBit>>1;
Expand Down

0 comments on commit 9fc3a61

Please sign in to comment.