Base bitmap header for 256 color - other formats derive from this
Code:
//256 color Bitmap class
#ifndef _BITMAP_
#define _BITMAP_
#include <mem.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <process.h>
#include <stdio.h>
//Makes calls to fast VGA assembly functions for blitting images
#include "vga.h"
//Generic 256 color bitmap class
class Bitmap256
{
protected:
BYTE far *Image;
BYTE Palette[768];
WORD Width;
WORD Height;
DWORD Size;
int XPos;
int YPos;
int ZOrder;
public:
Bitmap256(void);
Bitmap256(Bitmap256 &B);
virtual void Load(char far *filename);
virtual void Draw(void);
virtual void Draw(int x,int y);
virtual void SetDimensions(WORD w,WORD h)
{Width=w;Height=h;};
virtual void SetPalette(void) {::SetPalette(Palette);};
Bitmap256 operator=(Bitmap256 B);
};
#endif
Header for bmp.h - derives from Bitmap - see above
Code:
//class BMP - derived from Bitmap
#ifndef _BMP_
#define _BMP
#include "vga.h"
#include "bitmap.h"
//struct for BMP header
#define SRC_COPY 0x01
#define SRC_TRANS 0x02
//BMP header
struct BITMAPINFO
{
WORD Type;
DWORD Size;
DWORD Reserved;
DWORD Offset;
DWORD HeaderSize;
DWORD Width;
DWORD Height;
WORD Planes;
WORD BitsPerPixel;
DWORD Compression;
DWORD SizeImage;
DWORD XPixelsPerMeter;
DWORD YPixelsPerMeter;
DWORD ColorsUsed;
DWORD ColorsImportant;
};
//BMP class - implements Windows BMPs
class BMP:public Bitmap256
{
BITMAPINFO bmInfo;
int Padding;
BYTE Transparent;
public:
BMP(void) {};
virtual void Load(char far *filename);
void SetTransparent(BYTE color) {Transparent=color;};
BYTE GetTransparent(void) {return Transparent;};
void Draw(int x,int y,BYTE mode);
protected:
void ConvertPalette(BYTE nPAl[1024]);
};
#endif
Code for bmp.h
Code:
#include "bmp.h"
#include <conio.h>
//Load the BMP from disk
void BMP::Load(char far *filename)
{
int handle=0;
if ((handle=open(filename,O_BINARY|O_RDONLY,S_IREAD))==-1)
{
printf("Cannot open file %s\n",filename);
exit(0);
}
read (handle,&bmInfo,sizeof(bmInfo));
Size=bmInfo.SizeImage;
Image=new BYTE[Size];
BYTE tempPal[1024];
read (handle,&tempPal,1024);
read (handle,Image,bmInfo.SizeImage);
Width=bmInfo.Width;
Height=bmInfo.Height;
ConvertPalette(tempPal);
::SetPalette(Palette);
}
//Convert the palette to match the BMP
void BMP::ConvertPalette(BYTE nPal[1024])
{
int palentry=0;
//Delete 4th byte in BMP palette
//Change format to RGB in prep for changing palette
//Divide values by 4 to convert from 24-bit to 256 color
for (int i=0;i<1024;i+=4)
{
BYTE blu=nPal[i];
BYTE grn=nPal[i+1];
BYTE red=nPal[i+2];
Palette[palentry]=red>>2;
Palette[palentry+1]=grn>>2;
Palette[palentry+2]=blu>>2;
palentry+=3;
}
}
I did not include bitmap.cpp, this post is already long enough. Remember that each BMP is zero padded to the nearest 4 byte boundary (4+(width%4)). If you don't take this into account, BMPs that are not multiples of 4 will not display correctly. This code will automatically ignore the 4th byte in the palette. BMP palettes are stored as 4 byte entries - BGRA, and in the reverse order the hardware needs. This code ignores the A byte and reverses the BGR so calls to palette functions are easy.
Format of the BMP file.
Header (see the BITMAPINFO struct in bmp.h)
Palette (1024 bytes - BGRA)
Raw data(BYTES).
So read in the header.
Read in the palette.
Read in the raw data.
I recommend using assembly to blit the images. I have code in assembly that will blit a rectangular image to the screen and will also allow you to set transparent pixels. If you are interested in it, PM me or look for the post titled Bitmap Blues on this board. The full sources for these functions from my VGA library are there.
Hope this helps.