⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bmp.cpp

📁 仿游戏 Diablo 的源代码
💻 CPP
字号:
#include <errno.h>
#include "gl.h"

#define WININFOHEADERSIZE 40

/*#define BI_RGB          0
#define BI_RLE8         1
#define BI_RLE4         2
#define BI_BITFIELDS    3

typedef struct BITMAPFILEHEADER{
	DWORD bfType;
	DWORD bfSize;
	WORD  bfReserved1;
	WORD  bfReserved2;
	DWORD bfOffBits;
} BITMAPFILEHEADER;

typedef struct BITMAPINFOHEADER{  
	DWORD biSize;
	DWORD biWidth;
	DWORD biHeight;
	WORD  biPlanes;
	WORD  biBitCount;
	DWORD biCompression;
	DWORD biSizeImage;
	DWORD biXPelsPerMeter;
	DWORD biYPelsPerMeter;
	DWORD biClrUsed;
	DWORD biClrImportant;
} BITMAPINFOHEADER;

typedef struct RGBQUAD{
	BYTE rgbBlue;
	BYTE rgbGreen;
	BYTE rgbRed;
	BYTE rgbReserved;
} RGBQUAD;
*/
static int ReadBmpFileHeader( File *fp, BITMAPFILEHEADER *fileheader )
{
	fileheader->bfType = fp->Getw( );
	fileheader->bfSize = fp->Getdw();
	fileheader->bfReserved1 = fp->Getw();
	fileheader->bfReserved2 = fp->Getw();
	fileheader->bfOffBits = fp->Getdw();

	if( (short)(fileheader->bfType) != 19778 )
		return -1;
	return 0;
}

static int ReadBmpInfoHeader( File *fp, BITMAPINFOHEADER *infoheader )
{
	infoheader->biSize = fp->Getdw( );
	infoheader->biWidth = fp->Getdw( );
	infoheader->biHeight = fp->Getdw( );
	infoheader->biPlanes = fp->Getw( );
	infoheader->biBitCount = fp->Getw( );
	infoheader->biCompression = fp->Getdw();
	infoheader->biSizeImage = fp->Getdw( );
	infoheader->biXPelsPerMeter = fp->Getdw();
	infoheader->biYPelsPerMeter = fp->Getdw();
	infoheader->biClrUsed = fp->Getdw();
	infoheader->biClrImportant = fp->Getdw();

	return 0;
}

// 读取调色板
static int ReadColors( int num, Palette *pal, File *fp )
{
	int i;
	for( i=0; i<num; i++ ){
		pal->palette[i].rgbBlue = fp->Getc( );
		pal->palette[i].rgbGreen = fp->Getc( );
		pal->palette[i].rgbRed = fp->Getc( );
		pal->palette[i].rgbRsvd = fp->Getc( );
	}
	pal->Convert();
	return 0;
}

// 读取未经压缩的8位位图
static void ReadImage8( Bitmap8 *bmp, BITMAPINFOHEADER *infoheader, File *fp )
{
	int i;
	long j, k, l;
	char b[4];
	long n;

	for( i=(int)infoheader->biHeight - 1; i>=0; i-- ){
		for( j=0; j<infoheader->biWidth; j++ ){
			k = j % 4;
			if( k == 0 ){
				n = fp->Getdw();
				for( l=0; l<4; l++ ){
					b[l] = n & 0xff;
					n = n >> 8;
				}
			}
			bmp->line[ i ][ j ] = b[k];
		}
	}
}

//读取未经压缩的24位位图
static void ReadImage24( Bitmap24 *bmp, BITMAPINFOHEADER *infoheader, File *fp )
{
	int i, k;
	long j, bytes;

	for( i=(int)infoheader->biHeight - 1; i>=0; i-- ){
		for( j=0; j<infoheader->biWidth; j++ ){
			bmp->line[ i ][ j*3 + pixelInfo24.bluePos/8 ] = fp->Getc();
			bmp->line[ i ][ j*3 + pixelInfo24.greenPos/8 ] = fp->Getc();
			bmp->line[ i ][ j*3 + pixelInfo24.redPos/8 ] = fp->Getc();
		}
		bytes = infoheader->biWidth * 3;
		if( (k=bytes % 4) != 0 )
			for( ; k<4; k++ )
				fp->Getc();
	}
}

// 读取rel8压缩过的8位位图
static void ReadRle8CompressedImage( Bitmap *bmp, BITMAPINFOHEADER *infoheader, File *fp )
{
	unsigned char count, val, val0;
	int j, pos, line;
	int eolflag, eopicflag;
	
	eopicflag = 0;
	line = infoheader->biHeight - 1;
	
	while( eopicflag == 0 ){
		pos = 0;
		eolflag = 0;
		while(( eolflag == 0 ) && ( eopicflag == 0 )){
			count = fp->Getc();
			val = fp->Getc();
			if( count > 0 ){
				//OutputDebugString( "count > 0 " );
				for( j=0; j<count; j++ ){
					bmp->line[line][pos] = val;
					pos ++;
				}
			}
			else{
				//puts( "count < 0" );
				switch( val ){
				case 0:
					eolflag = 1;
					break;

				case 1:
					eopicflag = 1;
					break;

				case 2:
					count = fp->Getc();
					val = fp->Getc();
					pos += count;
					line -= val;
					break;

				default:
					for( j=0; j<val; j++ ){
						val0 = fp->Getc();
						bmp->line[line][pos] = val0;
						pos ++;
					}
					if( val & 1 == 1 )
						val0 = fp->Getc();
					break;
				}
			}
			if(pos>(int)(infoheader->biWidth));
				eolflag = 1;
		}
		line --;
		if( line < 0 )
			eopicflag = 1;
	}
}

Bitmap* LoadBmp( char *filename, Palette *pal )
{
	BITMAPFILEHEADER fileheader;
	BITMAPINFOHEADER infoheader;
	File *fp;
	Bitmap *bmp;

	errno = 0;

	if( ( fp = cfile.Open( filename )) == NULL )
		return NULL;

	if( ReadBmpFileHeader( fp, &fileheader ) != 0 ){
		fp->Close();
		return NULL;
	}
	ReadBmpInfoHeader( fp, &infoheader );

	if( infoheader.biSize != WININFOHEADERSIZE ){
		fp->Close();
		return NULL;
	}
//	printf( "%d\n", fileheader.bfOffBits );
	fp->Seek( fileheader.bfOffBits, SEEK_SET );
//	printf( "fp: %u\n", fp->count );

	bmp = CreateBitmapEx(  infoheader.biWidth, infoheader.biHeight, infoheader.biBitCount );

	switch( infoheader.biBitCount ){
	case 8:
		if( infoheader.biCompression == BI_RLE8 )
			ReadRle8CompressedImage( bmp, &infoheader, fp );
		else
			ReadImage8( (Bitmap8*)bmp, &infoheader, fp );
		break;

	case 24:
		ReadImage24( (Bitmap24* )bmp, &infoheader, fp );
		break;

	default:
		delete bmp;
		fp->Close();
		return NULL;
		break;
	}
	
	// read palette
	if( pal != NULL ){
		fp->Seek( 54, SEEK_SET );
//		printf( "fp: %u\n", fp->count );
		ReadColors( (fileheader.bfOffBits - 54)/4, pal, fp );
		(( Bitmap8* )bmp )->palette = pal;
	}
	
	fp->Close();
	if( errno ){
		delete bmp;
		return NULL;
	}
	return bmp;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -