home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Game Programming for Dummies (2nd Edition)
/
WinGamProgFD.iso
/
mac
/
Source
/
GPCHAP10
/
PROG10_4.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
2002-04-27
|
7KB
|
222 lines
// PROG10_4.CPP - bitmap loading software
// INCLUDES ///////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <iostream.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <io.h>
#include <fcntl.h>
#include <signal.h>
#include <float.h>
// this builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)
#define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))
// this builds a 16 bit color value in 5.6.5 format (green dominate mode)
#define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))
#define BITMAP_ID 0x4D42 // this is the universal id for a bitmap
// container structure for bitmaps .BMP file
typedef struct BITMAP_FILE_TAG
{
BITMAPFILEHEADER bitmapfileheader; // this contains the bitmapfile header
BITMAPINFOHEADER bitmapinfoheader; // this is all the info including the palette
PALETTEENTRY palette[256]; // we will store the palette here
UCHAR *buffer; // this is a pointer to the data
} BITMAP_FILE, *BITMAP_FILE_PTR;
//////////////////////////////////////////////////////////////////////////////
int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
{
// this function opens a bitmap file and loads the data into bitmap
int file_handle, // the file handle
index; // looping index
UCHAR *temp_buffer = NULL; // used to convert 24 bit images to 16 bit
OFSTRUCT file_data; // the file data information
// open the file if it exists
if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
return(0);
// now load the bitmap file header
_lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
// test if this is a bitmap file
if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
{
// close the file
_lclose(file_handle);
// return error
return(0);
} // end if
// now we know this is a bitmap, so read in all the sections
// first the bitmap infoheader
// now load the bitmap file header
_lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));
// now load the color palette if there is one
if (bitmap->bitmapinfoheader.biBitCount == 8)
{
_lread(file_handle, &bitmap->palette,256*sizeof(PALETTEENTRY));
// now set all the flags in the palette correctly and fix the reversed
// BGR RGBQUAD data format
for (index=0; index<256; index++)
{
// reverse the red and green fields
int temp_color = bitmap->palette[index].peRed;
bitmap->palette[index].peRed = bitmap->palette[index].peBlue;
bitmap->palette[index].peBlue = temp_color;
// always set the flags word to this
bitmap->palette[index].peFlags = PC_NOCOLLAPSE;
} // end for index
} // end if
// finally the image data itself
_lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);
// now read in the image, if the image is 8 or 16 bit then simply read it
// but if its 24 bit then read it into a temporary area and then convert
// it to a 16 bit image
if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16)
{
// allocate the memory for the image
if (!(bitmap->buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
{
// close the file
_lclose(file_handle);
// return error
return(0);
} // end if
// now read it in
_lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);
} // end if
else
{
// this must be a 24 bit image, load it in and convert it to 16 bit
printf("\nconverting 24 bit image...");
// allocate temporary buffer
if (!(temp_buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
{
// close the file
_lclose(file_handle);
// return error
return(0);
} // end if
// allocate final 16 bit storage buffer
if (!(bitmap->buffer = (UCHAR *)malloc(2 * bitmap->bitmapinfoheader.biWidth * bitmap->bitmapinfoheader.biHeight)))
{
// close the file
_lclose(file_handle);
// release working buffer
free(temp_buffer);
// return error
return(0);
} // end if
// now read it in
_lread(file_handle,temp_buffer,bitmap->bitmapinfoheader.biSizeImage);
// now convert each 24 bit RGB value into a 16 bit value
for (index=0; index<bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight; index++)
{
// extract RGB components (note they are in memory BGR)
// also, assume 5.6.5 format, so scale appropriately
UCHAR red = (temp_buffer[index*3 + 2] >> 3), // 5 bits
green = (temp_buffer[index*3 + 1] >> 2), // 6 bits, change to 3 for 5 bits
blue = (temp_buffer[index*3 + 0] >> 3); // 5 bits
// build up 16 bit color word assume 5.6.5 format
USHORT color = _RGB16BIT565(red,green,blue);
// write color to buffer
((USHORT *)bitmap->buffer)[index] = color;
} // end for index
} // end if
// write the file info out
printf("\nfilename:%s \nsize=%d \nwidth=%d \nheight=%d \nbitsperpixel=%d \ncolors=%d \nimpcolors=%d",
filename,
bitmap->bitmapinfoheader.biSizeImage,
bitmap->bitmapinfoheader.biWidth,
bitmap->bitmapinfoheader.biHeight,
bitmap->bitmapinfoheader.biBitCount,
bitmap->bitmapinfoheader.biClrUsed,
bitmap->bitmapinfoheader.biClrImportant);
// close the file
_lclose(file_handle);
// return success
return(1);
} // end Load_Bitmap_File
///////////////////////////////////////////////////////////////////////////////
int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
{
// this function releases all memory associated with "bitmap"
if (bitmap->buffer)
{
// release memory
free(bitmap->buffer);
// reset pointer
bitmap->buffer = NULL;
} // end if
// return success
return(1);
} // end Unload_Bitmap_File
///////////////////////////////////////////////////////////////////////////////
void main(void)
{
char filename[80];
BITMAP_FILE bitmap;
// load in .bmp files
while(1)
{
printf("\nenter filename to load?");
scanf("%s", filename);
Load_Bitmap_File(&bitmap,filename);
Unload_Bitmap_File(&bitmap);
} // end while
} // end main