No idea if this is the right way to submit this path… If not, let me know!-------------------------------------------
— SDL_bmp_old.c Tue Mar 16 11:07:27 2004
+++ SDL_bmp.c Fri Jul 30 10:31:46 2004
@@ -22,7 +22,7 @@
#ifdef SAVE_RCSID
static char rcsid =
- “@(#) $Id: SDL_bmp.c,v 1.1.1.1 2004/03/16 11:07:27 petrus Exp $”;
- “@(#) $Id: SDL_bmp.c,v 1.2 2004/07/30 10:31:46 petrus Exp $”;
#endif
#ifndef DISABLE_FILE
@@ -53,6 +53,7 @@
#define BI_BITFIELDS 3
#endif
+static int readRlePixels(SDL_Surface * surface, SDL_RWops *src, int isRle8);
SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
{
@@ -158,7 +159,7 @@
break;
}
- /* We don’t support any BMP compression right now */
- /* RLE4 and RLE8 BMP compression is supported /
Rmask = Gmask = Bmask = 0;
switch (biCompression) {
case BI_RGB:
@@ -191,7 +192,7 @@
}
/ Fall through – read the RGB masks */
-
case BI_BITFIELDS:
-
default: switch (biBitCount) { case 15: case 16:
@@ -204,10 +205,6 @@
break;
}
break;
-
default:
-
SDL_SetError("Compressed BMP files not supported");
-
was_error = 1;
-
goto done;
}
/* Create a compatible surface, note that the colors are RGB ordered /
@@ -221,9 +218,13 @@
/ Load the palette, if any */
palette = (surface->format)->palette;
if ( palette ) { -
if ( biClrUsed == 0 ) {
-
biClrUsed = 1 << biBitCount;
-
}
-
/*
-
| guich: always use 1<<bpp b/c some bitmaps can bring wrong
information
-
| for colorsUsed
-
*/
-
/* if ( biClrUsed == 0 ) { */
-
biClrUsed = 1 << biBitCount;
-
/* } */ if ( biSize == 12 ) { for ( i = 0; i < (int)biClrUsed; ++i ) { SDL_RWread(src, &palette->colors[i].b, 1, 1);
@@ -248,6 +249,13 @@
was_error = 1;
goto done;
}
- if ((biCompression == BI_RLE4) || (biCompression == BI_RLE8)) {
-
SDL_LockSurface(surface); /* petrus: not sure if I have to
this. Sam? */
-
was_error = readRlePixels(surface, src, biCompression ==
BI_RLE8);
-
SDL_UnlockSurface(surface); /* see comment above. */
-
if (was_error) SDL_SetError("Error reading from BMP");
-
goto done;
- }
bits = (Uint8 )surface->pixels+(surface->hsurface->pitch);
switch (ExpandBMP) {
case 1:
@@ -332,6 +340,86 @@
SDL_RWclose(src);
}
return(surface);
+}
+static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8)
+{
- /*
- | Sets the surface pixels from src. A bmp image is upside down.
- */
- int pitch = surface->pitch;
- int height = surface->h;
- Uint8 * bits = (Uint8 *)surface->pixels + ((height-1) * pitch);
- int ofs = 0;
- Uint8 ch;
- Uint8 needsPad;
- for (;
{
-
if ( !SDL_RWread(src, &ch, 1, 1) ) return 1;
-
/*
-
| encoded mode starts with a run length, and then a byte
-
| with two colour indexes to alternate between for the run
-
*/
-
if ( ch ) {
-
Uint8 pixel;
-
if ( !SDL_RWread(src, &pixel, 1, 1) ) return 1;
-
if ( isRle8 ) { /* 256-color bitmap,
compressed */
-
do {
-
bits[ofs++] = pixel;
-
} while (--ch);
-
}else { /* 16-color bitmap,
compressed */
-
Uint8 pixel0 = pixel >> 4;
-
Uint8 pixel1 = pixel & 0x0F;
-
for (;;) {
-
bits[ofs++] = pixel0; /* even
count, high nibble */
-
if (!--ch) break;
-
bits[ofs++] = pixel1; /* odd count,
low nibble */
-
if (!--ch) break;
-
}
-
}
-
} else {
-
/*
-
| A leading zero is an escape; it may signal the end of
the bitmap,
-
| a cursor move, or some absolute data.
-
| zero tag may be absolute mode or an escape
-
*/
-
if ( !SDL_RWread(src, &ch, 1, 1) ) return 1;
-
switch (ch) {
-
case 0: /* end of line */
-
ofs = 0;
-
bits -= pitch; /* go to previous
*/
-
break;
-
case 1: /* end of bitmap */
-
return 0; /* success! */
-
case 2: /* delta */
-
if ( !SDL_RWread(src, &ch, 1, 1) ) return 1;
-
ofs += ch;
-
if ( !SDL_RWread(src, &ch, 1, 1) ) return 1;
-
bits -= (ch * pitch);
-
break;
-
default: /* no compression */
-
if (isRle8) {
-
needsPad = ( ch & 1 );
-
do {
-
if ( !SDL_RWread(src, bits +
ofs++, 1, 1) ) return 1;
-
} while (--ch);
-
} else {
-
needsPad = ( ((ch+1)>>1) & 1 ); /*
(ch+1)>>1: bytes size */
-
for (;;) {
-
Uint8 pixel;
-
if ( !SDL_RWread(src, &pixel,
1, 1) ) return 1;
-
bits[ofs++] = pixel >> 4;
-
if (!--ch) break;
-
bits[ofs++] = pixel & 0x0F;
-
if (!--ch) break;
-
}
-
}
-
/* pad at even boundary */
-
if ( needsPad && !SDL_RWread(src, &ch, 1, 1) )
return 1;
-
break;
-
}
-
}
- }
}
int SDL_SaveBMP_RW (SDL_Surface *saveme, SDL_RWops *dst, int freedst)