📄 bmp.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 + -