From f304de1ba7e4ffd0d13d4e9883c72579a2b494e8 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 23 Sep 2001 23:33:06 +0000 Subject: [PATCH] Daniel Morais - Sun Sep 23 16:32:13 PDT 2001 * Added support for the IFF (LBM) image format --- CHANGES | 2 + IMG.c | 3 +- IMG_lbm.c | 369 +++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile.am | 1 + README | 2 +- SDL_image.h | 5 + VisualC.zip | Bin 244250 -> 244258 bytes configure.in | 6 + 8 files changed, 386 insertions(+), 2 deletions(-) create mode 100644 IMG_lbm.c diff --git a/CHANGES b/CHANGES index 4952fc5c..5623d489 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ 1.2.1: +Daniel Morais - Sun Sep 23 16:32:13 PDT 2001 + * Added support for the IFF (LBM) image format Sam Lantinga - Sun Aug 19 01:51:44 PDT 2001 * Added Project Builder projects for building MacOS X framework Mattias Engdegård - Tue Jul 31 04:32:29 PDT 2001 diff --git a/IMG.c b/IMG.c index db8751cc..7b86f0f9 100644 --- a/IMG.c +++ b/IMG.c @@ -48,6 +48,7 @@ static struct { { "GIF", IMG_isGIF, IMG_LoadGIF_RW }, { "JPG", IMG_isJPG, IMG_LoadJPG_RW }, { "TIF", IMG_isTIF, IMG_LoadTIF_RW }, + { "LBM", IMG_isLBM, IMG_LoadLBM_RW }, { "PNG", IMG_isPNG, IMG_LoadPNG_RW } }; @@ -68,7 +69,7 @@ SDL_Surface *IMG_Load_RW(SDL_RWops *src, int freesrc) } /* Portable case-insensitive string compare function */ -static int IMG_string_equals(const char *str1, const char *str2) +int IMG_string_equals(const char *str1, const char *str2) { while ( *str1 && *str2 ) { if ( toupper((unsigned char)*str1) != diff --git a/IMG_lbm.c b/IMG_lbm.c new file mode 100644 index 00000000..e9dc560d --- /dev/null +++ b/IMG_lbm.c @@ -0,0 +1,369 @@ +/* + IMGLIB: An example image loading library for use with SDL + Copyright (C) 1999 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +/* 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 +*/ + +#include +#include + +#include "SDL_endian.h" +#include "SDL_image.h" + +#ifdef LOAD_LBM + + +//=========================================================================== +// DEFINES +//=========================================================================== + +#define MAXCOLORS 256 + +//=========================================================================== +// STRUCTURES +//=========================================================================== + +// Structure for an IFF picture ( BMHD = Bitmap Header ) + +typedef struct +{ + Uint16 w, h; // width & height of the bitmap in pixels + Sint16 x, y; // screen coordinates of the bitmap + Uint8 planes; // number of planes of the bitmap + Uint8 mask; // mask type ( 0 => no mask ) + Uint8 tcomp; // compression type + Uint8 pad1; // dummy value, for padding + Uint16 tcolor; // transparent color + Uint8 xAspect, // pixel aspect ratio + yAspect; + Sint16 Lpage; // width of the screen in pixels + Sint16 Hpage; // height of the screen in pixels + +} BMHD; + +//=========================================================================== +// See if an image is contained in a data source + +int IMG_isLBM( SDL_RWops *src ) +{ + int is_LBM; + Uint8 magic[4+4+4]; + + is_LBM = 0; + if ( SDL_RWread( src, magic, 4+4+4, 1 ) ) + { + if ( !memcmp( magic, "FORM", 4 ) && + ( !memcmp( magic + 8, "PBM ", 4 ) || + !memcmp( magic + 8, "ILBM", 4 ) ) ) + { + is_LBM = 1; + } + } + return( is_LBM ); +} + +//=========================================================================== +// Load a IFF type image from an SDL datasource + +SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src ) +{ + SDL_Surface *Image; + Uint8 id[4], pbm, colormap[MAXCOLORS*3], *MiniBuf, *ptr, count, color, msk; + Uint32 size, bytesloaded, nbcolors; + Uint32 i, j, bytesperline, nbplanes, plane, h; + Uint32 remainingbytes; + int width; + BMHD bmhd; + char *error; + + Image = NULL; + error = NULL; + MiniBuf = NULL; + + if ( src == NULL ) goto done; + + if ( !SDL_RWread( src, id, 4, 1 ) ) + { + error="error reading IFF chunk"; + goto done; + } + + if ( !SDL_RWread( src, &size, 4, 1 ) ) // Should be the size of the file minus 4+4 ( 'FORM'+size ) + { + error="error reading IFF chunk size"; + goto done; + } + + // As size is not used here, no need to swap it + + if ( memcmp( id, "FORM", 4 ) != 0 ) + { + error="not a IFF file"; + goto done; + } + + if ( !SDL_RWread( src, id, 4, 1 ) ) + { + error="error reading IFF chunk"; + goto done; + } + + pbm = 0; + + if ( !memcmp( id, "PBM ", 4 ) ) pbm = 1; // File format : PBM=Packed Bitmap, ILBM=Interleaved Bitmap + else if ( memcmp( id, "ILBM", 4 ) ) + { + error="not a IFF picture"; + goto done; + } + + nbcolors = 0; + + memset( &bmhd, 0, sizeof( BMHD ) ); + + while ( memcmp( id, "BODY", 4 ) != 0 ) + { + if ( !SDL_RWread( src, id, 4, 1 ) ) + { + error="error reading IFF chunk"; + goto done; + } + + if ( !SDL_RWread( src, &size, 4, 1 ) ) + { + error="error reading IFF chunk size"; + goto done; + } + + bytesloaded = 0; + + size = SDL_SwapBE32( size ); + + if ( !memcmp( id, "BMHD", 4 ) ) // Bitmap header + { + if ( !SDL_RWread( src, &bmhd, sizeof( BMHD ), 1 ) ) + { + error="error reading BMHD chunk"; + goto done; + } + + bytesloaded = sizeof( BMHD ); + + bmhd.w = SDL_SwapBE16( bmhd.w ); + bmhd.h = SDL_SwapBE16( bmhd.h ); + bmhd.x = SDL_SwapBE16( bmhd.x ); + bmhd.y = SDL_SwapBE16( bmhd.y ); + bmhd.tcolor = SDL_SwapBE16( bmhd.tcolor ); + bmhd.Lpage = SDL_SwapBE16( bmhd.Lpage ); + bmhd.Hpage = SDL_SwapBE16( bmhd.Hpage ); + } + + if ( !memcmp( id, "CMAP", 4 ) ) // palette ( Color Map ) + { + if ( !SDL_RWread( src, &colormap, size, 1 ) ) + { + error="error reading CMAP chunk"; + goto done; + } + + bytesloaded = size; + nbcolors = size / 3; + } + + if ( memcmp( id, "BODY", 4 ) ) + { + if ( size & 1 ) ++size; // padding ! + size -= bytesloaded; + if ( size ) SDL_RWseek( src, size, SEEK_CUR ); // skip the remaining bytes of this chunk + } + } + + // compute some usefull values, based on the bitmap header + + width = ( bmhd.w + 15 ) & 0xFFFFFFF0; // Width in pixels modulo 16 + + bytesperline = ( ( bmhd.w + 15 ) / 16 ) * 2; // Number of bytes per line + + nbplanes = bmhd.planes; // Number of planes + + if ( pbm ) // File format : 'Packed Bitmap' + { + bytesperline *= 8; + nbplanes = 1; + } + + if ( bmhd.mask ) ++nbplanes; // There is a mask ( 'stencil' ) + + // Allocate memory for a temporary buffer ( used for decompression/deinterleaving ) + + if ( ( MiniBuf = (void *)malloc( bytesperline * nbplanes ) ) == NULL ) + { + error="no enough memory for temporary buffer"; + goto done; + } + + // Create the surface + + if ( ( Image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, bmhd.h, 8, 0, 0, 0, 0 ) ) == NULL ) + goto done; + + // Update palette informations + + Image->format->palette->ncolors = nbcolors; + + ptr = &colormap[0]; + + for ( i=0; iformat->palette->colors[i].r = *ptr++; + Image->format->palette->colors[i].g = *ptr++; + Image->format->palette->colors[i].b = *ptr++; + } + + // Get the bitmap + + for ( h=0; h < bmhd.h; h++ ) + { + // uncompress the datas of each planes + + for ( plane=0; plane < nbplanes; plane++ ) + { + ptr = MiniBuf + ( plane * bytesperline ); + + remainingbytes = bytesperline; + + if ( bmhd.tcomp == 1 ) // Datas are compressed + { + do + { + if ( !SDL_RWread( src, &count, 1, 1 ) ) + { + error="error reading BODY chunk"; + goto done; + } + + if ( count & 0x80 ) + { + count ^= 0xFF; + count += 2; // now it + + if ( !SDL_RWread( src, &color, 1, 1 ) ) + { + error="error reading BODY chunk"; + goto done; + } + memset( ptr, color, count ); + } + else + { + ++count; + + if ( !SDL_RWread( src, ptr, count, 1 ) ) + { + error="error reading BODY chunk"; + goto done; + } + } + + ptr += count; + remainingbytes -= count; + + } while ( remainingbytes > 0 ); + } + else + { + if ( !SDL_RWread( src, ptr, bytesperline, 1 ) ) + { + error="error reading BODY chunk"; + goto done; + } + } + } + + // One line has been read, store it ! + + ptr = Image->pixels; + ptr += h * width; + + if ( pbm ) // File format : 'Packed Bitmap' + { + memcpy( ptr, MiniBuf, width ); + } + else // We have to un-interlace the bits ! + { + size = ( width + 7 ) / 8; + + for ( i=0; i < size; i++ ) + { + memset( ptr, 0, 8 ); + + for ( plane=0; plane < nbplanes; plane++ ) + { + color = *( MiniBuf + i + ( plane * bytesperline ) ); + msk = 0x80; + + for ( j=0; j<8; j++ ) + { + if ( ( plane + j ) <= 7 ) ptr[j] |= (Uint8)( color & msk ) >> ( 7 - plane - j ); + else ptr[j] |= (Uint8)( color & msk ) << ( plane + j - 7 ); + + msk >>= 1; + } + } + ptr += 8; + } + } + } + +done: + + if ( MiniBuf ) free( MiniBuf ); + + if ( error ) + { + IMG_SetError( error ); + SDL_FreeSurface( Image ); + Image = NULL; + } + + return( Image ); +} + +#else /* LOAD_LBM */ + +/* See if an image is contained in a data source */ +int IMG_isLBM(SDL_RWops *src) +{ + return(0); +} + +/* Load an IFF type image from an SDL datasource */ +SDL_Surface *IMG_LoadLBM_RW(SDL_RWops *src) +{ + return(NULL); +} + +#endif /* LOAD_LBM */ diff --git a/Makefile.am b/Makefile.am index ae476576..1f6162f1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,6 +11,7 @@ libSDL_image_la_SOURCES = \ IMG_bmp.c \ IMG_gif.c \ IMG_jpg.c \ + IMG_lbm.c \ IMG_pcx.c \ IMG_png.c \ IMG_pnm.c \ diff --git a/README b/README index 62cfc56d..073e747e 100644 --- a/README +++ b/README @@ -5,7 +5,7 @@ The latest version of this library is available from: http://www.libsdl.org/projects/SDL_image/ This is a simple library to load images of various formats as SDL surfaces. -This library supports BMP, PNM (PPM/PGM/PBM), XPM, PCX, GIF, JPEG, PNG, +This library supports BMP, PNM (PPM/PGM/PBM), XPM, LBM, PCX, GIF, JPEG, PNG, TGA, and TIFF formats. API: diff --git a/SDL_image.h b/SDL_image.h index 29013c0f..949cbad7 100644 --- a/SDL_image.h +++ b/SDL_image.h @@ -64,6 +64,7 @@ extern DECLSPEC int IMG_isGIF(SDL_RWops *src); extern DECLSPEC int IMG_isJPG(SDL_RWops *src); extern DECLSPEC int IMG_isTIF(SDL_RWops *src); extern DECLSPEC int IMG_isPNG(SDL_RWops *src); +extern DECLSPEC int IMG_isLBM(SDL_RWops *src); /* Individual loading functions */ extern DECLSPEC SDL_Surface *IMG_LoadBMP_RW(SDL_RWops *src); @@ -76,6 +77,7 @@ extern DECLSPEC SDL_Surface *IMG_LoadJPG_RW(SDL_RWops *src); extern DECLSPEC SDL_Surface *IMG_LoadTIF_RW(SDL_RWops *src); extern DECLSPEC SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src); extern DECLSPEC SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface *IMG_LoadLBM_RW(SDL_RWops *src); extern DECLSPEC SDL_Surface *IMG_ReadXPMFromArray(char **xpm); @@ -83,6 +85,9 @@ extern DECLSPEC SDL_Surface *IMG_ReadXPMFromArray(char **xpm); #define IMG_SetError SDL_SetError #define IMG_GetError SDL_GetError +/* used internally, NOT an exported function */ +extern int IMG_string_equals(const char *str1, const char *str2); + /* Ends C function definitions when using C++ */ #ifdef __cplusplus } diff --git a/VisualC.zip b/VisualC.zip index 775d64403dba943acb8a44b131ef00726538ca5b..04d036c0a281f4bf83ec0a76171c53bb6d8ed9e3 100644 GIT binary patch delta 2036 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 diff --git a/configure.in b/configure.in index b6b3af96..a1be89b5 100644 --- a/configure.in +++ b/configure.in @@ -111,6 +111,12 @@ if test x$enable_jpg = xyes; then AC_MSG_WARN([JPG image loading disabled]) fi fi +AC_ARG_ENABLE(lbm, +[ --enable-lbm support loading LBM images [default=yes]], + , enable_lbm=yes) +if test x$enable_lbm = xyes; then + CFLAGS="$CFLAGS -DLOAD_LBM" +fi AC_ARG_ENABLE(pcx, [ --enable-pcx support loading PCX images [default=yes]], , enable_pcx=yes)