diff options
Diffstat (limited to 'distrib/sdl-1.2.12/src/video/SDL_bmp.c')
-rw-r--r-- | distrib/sdl-1.2.12/src/video/SDL_bmp.c | 520 |
1 files changed, 0 insertions, 520 deletions
diff --git a/distrib/sdl-1.2.12/src/video/SDL_bmp.c b/distrib/sdl-1.2.12/src/video/SDL_bmp.c deleted file mode 100644 index 874cb27..0000000 --- a/distrib/sdl-1.2.12/src/video/SDL_bmp.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - Code to load and save surfaces in Windows BMP format. - - Why support BMP format? Well, it's a native format for Windows, and - most image processing programs can read and write it. It would be nice - to be able to have at least one image format that we can natively load - and save, and since PNG is so complex that it would bloat the library, - BMP is a good alternative. - - This code currently supports Win32 DIBs in uncompressed 8 and 24 bpp. -*/ - -#include "SDL_video.h" -#include "SDL_endian.h" - -/* Compression encodings for BMP files */ -#ifndef BI_RGB -#define BI_RGB 0 -#define BI_RLE8 1 -#define BI_RLE4 2 -#define BI_BITFIELDS 3 -#endif - - -SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) -{ - int was_error; - long fp_offset; - int bmpPitch; - int i, pad; - SDL_Surface *surface; - Uint32 Rmask; - Uint32 Gmask; - Uint32 Bmask; - SDL_Palette *palette; - Uint8 *bits; - int ExpandBMP; - - /* The Win32 BMP file header (14 bytes) */ - char magic[2]; - Uint32 bfSize; - Uint16 bfReserved1; - Uint16 bfReserved2; - Uint32 bfOffBits; - - /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ - Uint32 biSize; - Sint32 biWidth; - Sint32 biHeight; - Uint16 biPlanes; - Uint16 biBitCount; - Uint32 biCompression; - Uint32 biSizeImage; - Sint32 biXPelsPerMeter; - Sint32 biYPelsPerMeter; - Uint32 biClrUsed; - Uint32 biClrImportant; - - /* Make sure we are passed a valid data source */ - surface = NULL; - was_error = 0; - if ( src == NULL ) { - was_error = 1; - goto done; - } - - /* Read in the BMP file header */ - fp_offset = SDL_RWtell(src); - SDL_ClearError(); - if ( SDL_RWread(src, magic, 1, 2) != 2 ) { - SDL_Error(SDL_EFREAD); - was_error = 1; - goto done; - } - if ( SDL_strncmp(magic, "BM", 2) != 0 ) { - SDL_SetError("File is not a Windows BMP file"); - was_error = 1; - goto done; - } - bfSize = SDL_ReadLE32(src); - bfReserved1 = SDL_ReadLE16(src); - bfReserved2 = SDL_ReadLE16(src); - bfOffBits = SDL_ReadLE32(src); - - /* Read the Win32 BITMAPINFOHEADER */ - biSize = SDL_ReadLE32(src); - if ( biSize == 12 ) { - biWidth = (Uint32)SDL_ReadLE16(src); - biHeight = (Uint32)SDL_ReadLE16(src); - biPlanes = SDL_ReadLE16(src); - biBitCount = SDL_ReadLE16(src); - biCompression = BI_RGB; - biSizeImage = 0; - biXPelsPerMeter = 0; - biYPelsPerMeter = 0; - biClrUsed = 0; - biClrImportant = 0; - } else { - biWidth = SDL_ReadLE32(src); - biHeight = SDL_ReadLE32(src); - biPlanes = SDL_ReadLE16(src); - biBitCount = SDL_ReadLE16(src); - biCompression = SDL_ReadLE32(src); - biSizeImage = SDL_ReadLE32(src); - biXPelsPerMeter = SDL_ReadLE32(src); - biYPelsPerMeter = SDL_ReadLE32(src); - biClrUsed = SDL_ReadLE32(src); - biClrImportant = SDL_ReadLE32(src); - } - - /* Check for read error */ - if ( SDL_strcmp(SDL_GetError(), "") != 0 ) { - was_error = 1; - goto done; - } - - /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */ - switch (biBitCount) { - case 1: - case 4: - ExpandBMP = biBitCount; - biBitCount = 8; - break; - default: - ExpandBMP = 0; - break; - } - - /* We don't support any BMP compression right now */ - Rmask = Gmask = Bmask = 0; - switch (biCompression) { - case BI_RGB: - /* If there are no masks, use the defaults */ - if ( bfOffBits == (14+biSize) ) { - /* Default values for the BMP format */ - switch (biBitCount) { - case 15: - case 16: - Rmask = 0x7C00; - Gmask = 0x03E0; - Bmask = 0x001F; - break; - case 24: -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - Rmask = 0x000000FF; - Gmask = 0x0000FF00; - Bmask = 0x00FF0000; - break; -#endif - case 32: - Rmask = 0x00FF0000; - Gmask = 0x0000FF00; - Bmask = 0x000000FF; - break; - default: - break; - } - break; - } - /* Fall through -- read the RGB masks */ - - case BI_BITFIELDS: - switch (biBitCount) { - case 15: - case 16: - case 32: - Rmask = SDL_ReadLE32(src); - Gmask = SDL_ReadLE32(src); - Bmask = SDL_ReadLE32(src); - break; - default: - 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 */ - surface = SDL_CreateRGBSurface(SDL_SWSURFACE, - biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0); - if ( surface == NULL ) { - was_error = 1; - goto done; - } - - /* Load the palette, if any */ - palette = (surface->format)->palette; - if ( palette ) { - 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); - SDL_RWread(src, &palette->colors[i].g, 1, 1); - SDL_RWread(src, &palette->colors[i].r, 1, 1); - palette->colors[i].unused = 0; - } - } else { - for ( i = 0; i < (int)biClrUsed; ++i ) { - SDL_RWread(src, &palette->colors[i].b, 1, 1); - SDL_RWread(src, &palette->colors[i].g, 1, 1); - SDL_RWread(src, &palette->colors[i].r, 1, 1); - SDL_RWread(src, &palette->colors[i].unused, 1, 1); - } - } - palette->ncolors = biClrUsed; - } - - /* Read the surface pixels. Note that the bmp image is upside down */ - if ( SDL_RWseek(src, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) { - SDL_Error(SDL_EFSEEK); - was_error = 1; - goto done; - } - bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch); - switch (ExpandBMP) { - case 1: - bmpPitch = (biWidth + 7) >> 3; - pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0); - break; - case 4: - bmpPitch = (biWidth + 1) >> 1; - pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0); - break; - default: - pad = ((surface->pitch%4) ? - (4-(surface->pitch%4)) : 0); - break; - } - while ( bits > (Uint8 *)surface->pixels ) { - bits -= surface->pitch; - switch (ExpandBMP) { - case 1: - case 4: { - Uint8 pixel = 0; - int shift = (8-ExpandBMP); - for ( i=0; i<surface->w; ++i ) { - if ( i%(8/ExpandBMP) == 0 ) { - if ( !SDL_RWread(src, &pixel, 1, 1) ) { - SDL_SetError( - "Error reading from BMP"); - was_error = 1; - goto done; - } - } - *(bits+i) = (pixel>>shift); - pixel <<= ExpandBMP; - } } - break; - - default: - if ( SDL_RWread(src, bits, 1, surface->pitch) - != surface->pitch ) { - SDL_Error(SDL_EFREAD); - was_error = 1; - goto done; - } -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - /* Byte-swap the pixels if needed. Note that the 24bpp - case has already been taken care of above. */ - switch(biBitCount) { - case 15: - case 16: { - Uint16 *pix = (Uint16 *)bits; - for(i = 0; i < surface->w; i++) - pix[i] = SDL_Swap16(pix[i]); - break; - } - - case 32: { - Uint32 *pix = (Uint32 *)bits; - for(i = 0; i < surface->w; i++) - pix[i] = SDL_Swap32(pix[i]); - break; - } - } -#endif - break; - } - /* Skip padding bytes, ugh */ - if ( pad ) { - Uint8 padbyte; - for ( i=0; i<pad; ++i ) { - SDL_RWread(src, &padbyte, 1, 1); - } - } - } -done: - if ( was_error ) { - if ( src ) { - SDL_RWseek(src, fp_offset, RW_SEEK_SET); - } - if ( surface ) { - SDL_FreeSurface(surface); - } - surface = NULL; - } - if ( freesrc && src ) { - SDL_RWclose(src); - } - return(surface); -} - -int SDL_SaveBMP_RW (SDL_Surface *saveme, SDL_RWops *dst, int freedst) -{ - long fp_offset; - int i, pad; - SDL_Surface *surface; - Uint8 *bits; - - /* The Win32 BMP file header (14 bytes) */ - char magic[2] = { 'B', 'M' }; - Uint32 bfSize; - Uint16 bfReserved1; - Uint16 bfReserved2; - Uint32 bfOffBits; - - /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ - Uint32 biSize; - Sint32 biWidth; - Sint32 biHeight; - Uint16 biPlanes; - Uint16 biBitCount; - Uint32 biCompression; - Uint32 biSizeImage; - Sint32 biXPelsPerMeter; - Sint32 biYPelsPerMeter; - Uint32 biClrUsed; - Uint32 biClrImportant; - - /* Make sure we have somewhere to save */ - surface = NULL; - if ( dst ) { - if ( saveme->format->palette ) { - if ( saveme->format->BitsPerPixel == 8 ) { - surface = saveme; - } else { - SDL_SetError("%d bpp BMP files not supported", - saveme->format->BitsPerPixel); - } - } - else if ( (saveme->format->BitsPerPixel == 24) && -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - (saveme->format->Rmask == 0x00FF0000) && - (saveme->format->Gmask == 0x0000FF00) && - (saveme->format->Bmask == 0x000000FF) -#else - (saveme->format->Rmask == 0x000000FF) && - (saveme->format->Gmask == 0x0000FF00) && - (saveme->format->Bmask == 0x00FF0000) -#endif - ) { - surface = saveme; - } else { - SDL_Rect bounds; - - /* Convert to 24 bits per pixel */ - surface = SDL_CreateRGBSurface(SDL_SWSURFACE, - saveme->w, saveme->h, 24, -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - 0x00FF0000, 0x0000FF00, 0x000000FF, -#else - 0x000000FF, 0x0000FF00, 0x00FF0000, -#endif - 0); - if ( surface != NULL ) { - bounds.x = 0; - bounds.y = 0; - bounds.w = saveme->w; - bounds.h = saveme->h; - if ( SDL_LowerBlit(saveme, &bounds, surface, - &bounds) < 0 ) { - SDL_FreeSurface(surface); - SDL_SetError( - "Couldn't convert image to 24 bpp"); - surface = NULL; - } - } - } - } - - if ( surface && (SDL_LockSurface(surface) == 0) ) { - const int bw = surface->w*surface->format->BytesPerPixel; - - /* Set the BMP file header values */ - bfSize = 0; /* We'll write this when we're done */ - bfReserved1 = 0; - bfReserved2 = 0; - bfOffBits = 0; /* We'll write this when we're done */ - - /* Write the BMP file header values */ - fp_offset = SDL_RWtell(dst); - SDL_ClearError(); - SDL_RWwrite(dst, magic, 2, 1); - SDL_WriteLE32(dst, bfSize); - SDL_WriteLE16(dst, bfReserved1); - SDL_WriteLE16(dst, bfReserved2); - SDL_WriteLE32(dst, bfOffBits); - - /* Set the BMP info values */ - biSize = 40; - biWidth = surface->w; - biHeight = surface->h; - biPlanes = 1; - biBitCount = surface->format->BitsPerPixel; - biCompression = BI_RGB; - biSizeImage = surface->h*surface->pitch; - biXPelsPerMeter = 0; - biYPelsPerMeter = 0; - if ( surface->format->palette ) { - biClrUsed = surface->format->palette->ncolors; - } else { - biClrUsed = 0; - } - biClrImportant = 0; - - /* Write the BMP info values */ - SDL_WriteLE32(dst, biSize); - SDL_WriteLE32(dst, biWidth); - SDL_WriteLE32(dst, biHeight); - SDL_WriteLE16(dst, biPlanes); - SDL_WriteLE16(dst, biBitCount); - SDL_WriteLE32(dst, biCompression); - SDL_WriteLE32(dst, biSizeImage); - SDL_WriteLE32(dst, biXPelsPerMeter); - SDL_WriteLE32(dst, biYPelsPerMeter); - SDL_WriteLE32(dst, biClrUsed); - SDL_WriteLE32(dst, biClrImportant); - - /* Write the palette (in BGR color order) */ - if ( surface->format->palette ) { - SDL_Color *colors; - int ncolors; - - colors = surface->format->palette->colors; - ncolors = surface->format->palette->ncolors; - for ( i=0; i<ncolors; ++i ) { - SDL_RWwrite(dst, &colors[i].b, 1, 1); - SDL_RWwrite(dst, &colors[i].g, 1, 1); - SDL_RWwrite(dst, &colors[i].r, 1, 1); - SDL_RWwrite(dst, &colors[i].unused, 1, 1); - } - } - - /* Write the bitmap offset */ - bfOffBits = SDL_RWtell(dst)-fp_offset; - if ( SDL_RWseek(dst, fp_offset+10, RW_SEEK_SET) < 0 ) { - SDL_Error(SDL_EFSEEK); - } - SDL_WriteLE32(dst, bfOffBits); - if ( SDL_RWseek(dst, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) { - SDL_Error(SDL_EFSEEK); - } - - /* Write the bitmap image upside down */ - bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch); - pad = ((bw%4) ? (4-(bw%4)) : 0); - while ( bits > (Uint8 *)surface->pixels ) { - bits -= surface->pitch; - if ( SDL_RWwrite(dst, bits, 1, bw) != bw) { - SDL_Error(SDL_EFWRITE); - break; - } - if ( pad ) { - const Uint8 padbyte = 0; - for ( i=0; i<pad; ++i ) { - SDL_RWwrite(dst, &padbyte, 1, 1); - } - } - } - - /* Write the BMP file size */ - bfSize = SDL_RWtell(dst)-fp_offset; - if ( SDL_RWseek(dst, fp_offset+2, RW_SEEK_SET) < 0 ) { - SDL_Error(SDL_EFSEEK); - } - SDL_WriteLE32(dst, bfSize); - if ( SDL_RWseek(dst, fp_offset+bfSize, RW_SEEK_SET) < 0 ) { - SDL_Error(SDL_EFSEEK); - } - - /* Close it up.. */ - SDL_UnlockSurface(surface); - if ( surface != saveme ) { - SDL_FreeSurface(surface); - } - } - - if ( freedst && dst ) { - SDL_RWclose(dst); - } - return((SDL_strcmp(SDL_GetError(), "") == 0) ? 0 : -1); -} |