|
|
@ -16,6 +16,18 @@ GNU General Public License for more details. |
|
|
|
#include "imagelib.h" |
|
|
|
#include "imagelib.h" |
|
|
|
#include "mathlib.h" |
|
|
|
#include "mathlib.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define BI_SIZE 40 //size of bitmap info header.
|
|
|
|
|
|
|
|
#ifndef _WIN32 |
|
|
|
|
|
|
|
#define BI_RGB 0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct tagRGBQUAD { |
|
|
|
|
|
|
|
BYTE rgbBlue; |
|
|
|
|
|
|
|
BYTE rgbGreen; |
|
|
|
|
|
|
|
BYTE rgbRed; |
|
|
|
|
|
|
|
BYTE rgbReserved; |
|
|
|
|
|
|
|
} RGBQUAD; |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
============= |
|
|
|
============= |
|
|
|
Image_LoadBMP |
|
|
|
Image_LoadBMP |
|
|
@ -310,17 +322,16 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, size_t filesize ) |
|
|
|
qboolean Image_SaveBMP( const char *name, rgbdata_t *pix ) |
|
|
|
qboolean Image_SaveBMP( const char *name, rgbdata_t *pix ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
file_t *pfile = NULL; |
|
|
|
file_t *pfile = NULL; |
|
|
|
BITMAPFILEHEADER bmfh; |
|
|
|
|
|
|
|
BITMAPINFOHEADER bmih; |
|
|
|
|
|
|
|
size_t total_size, cur_size; |
|
|
|
size_t total_size, cur_size; |
|
|
|
RGBQUAD rgrgbPalette[256]; |
|
|
|
RGBQUAD rgrgbPalette[256]; |
|
|
|
dword cbBmpBits; |
|
|
|
dword cbBmpBits; |
|
|
|
byte *clipbuf = NULL; |
|
|
|
byte *clipbuf = NULL; |
|
|
|
byte *pb, *pbBmpBits; |
|
|
|
byte *pb, *pbBmpBits; |
|
|
|
dword cbPalBytes = 0; |
|
|
|
dword cbPalBytes; |
|
|
|
dword biTrueWidth; |
|
|
|
dword biTrueWidth; |
|
|
|
int pixel_size; |
|
|
|
int pixel_size; |
|
|
|
int i, x, y; |
|
|
|
int i, x, y; |
|
|
|
|
|
|
|
bmp_t hdr; |
|
|
|
|
|
|
|
|
|
|
|
if( FS_FileExists( name, false ) && !Image_CheckFlag( IL_ALLOW_OVERWRITE ) && !host.write_to_clipboard ) |
|
|
|
if( FS_FileExists( name, false ) && !Image_CheckFlag( IL_ALLOW_OVERWRITE ) && !host.write_to_clipboard ) |
|
|
|
return false; // already existed
|
|
|
|
return false; // already existed
|
|
|
@ -357,50 +368,39 @@ qboolean Image_SaveBMP( const char *name, rgbdata_t *pix ) |
|
|
|
// after create sprite or lump image, it's just standard requiriments
|
|
|
|
// after create sprite or lump image, it's just standard requiriments
|
|
|
|
biTrueWidth = ((pix->width + 3) & ~3); |
|
|
|
biTrueWidth = ((pix->width + 3) & ~3); |
|
|
|
cbBmpBits = biTrueWidth * pix->height * pixel_size; |
|
|
|
cbBmpBits = biTrueWidth * pix->height * pixel_size; |
|
|
|
if( pixel_size == 1 ) cbPalBytes = 256 * sizeof( RGBQUAD ); |
|
|
|
cbPalBytes = ( pixel_size == 1 ) ? 256 * sizeof( RGBQUAD ) : 0; |
|
|
|
|
|
|
|
|
|
|
|
// Bogus file header check
|
|
|
|
// Bogus file header check
|
|
|
|
bmfh.bfType = MAKEWORD( 'B', 'M' ); |
|
|
|
hdr.id[0] = 'B'; |
|
|
|
bmfh.bfSize = sizeof( bmfh ) + sizeof( bmih ) + cbBmpBits + cbPalBytes; |
|
|
|
hdr.id[1] = 'M'; |
|
|
|
bmfh.bfReserved1 = 0; |
|
|
|
hdr.fileSize = sizeof( hdr ) + cbBmpBits + cbPalBytes; |
|
|
|
bmfh.bfReserved2 = 0; |
|
|
|
hdr.bitmapDataOffset = sizeof( hdr ) + cbPalBytes; |
|
|
|
bmfh.bfOffBits = sizeof( bmfh ) + sizeof( bmih ) + cbPalBytes; |
|
|
|
hdr.bitmapHeaderSize = BI_SIZE; |
|
|
|
|
|
|
|
hdr.width = biTrueWidth; |
|
|
|
|
|
|
|
hdr.height = pix->height; |
|
|
|
|
|
|
|
hdr.planes = 1; |
|
|
|
|
|
|
|
hdr.bitsPerPixel = pixel_size * 8; |
|
|
|
|
|
|
|
hdr.compression = BI_RGB; |
|
|
|
|
|
|
|
hdr.bitmapDataSize = cbBmpBits; |
|
|
|
|
|
|
|
hdr.hRes = 0; |
|
|
|
|
|
|
|
hdr.vRes = 0; |
|
|
|
|
|
|
|
hdr.colors = ( pixel_size == 1 ) ? 256 : 0; |
|
|
|
|
|
|
|
hdr.importantColors = 0; |
|
|
|
|
|
|
|
|
|
|
|
if( host.write_to_clipboard ) |
|
|
|
if( host.write_to_clipboard ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// NOTE: the cbPalBytes may be 0
|
|
|
|
// NOTE: the cbPalBytes may be 0
|
|
|
|
total_size = sizeof( bmih ) + cbPalBytes + cbBmpBits; |
|
|
|
total_size = BI_SIZE + cbPalBytes + cbBmpBits; |
|
|
|
clipbuf = Z_Malloc( total_size ); |
|
|
|
clipbuf = Z_Malloc( total_size ); |
|
|
|
cur_size = 0; |
|
|
|
memcpy( clipbuf, (byte *)&hdr + ( sizeof( bmp_t ) - BI_SIZE ), BI_SIZE ); |
|
|
|
|
|
|
|
cur_size = BI_SIZE; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
// write header
|
|
|
|
// Write header
|
|
|
|
FS_Write( pfile, &bmfh, sizeof( bmfh )); |
|
|
|
bmp_t sw = hdr; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// size of structure
|
|
|
|
FS_Write( pfile, &sw, sizeof( bmp_t )); |
|
|
|
bmih.biSize = sizeof( bmih ); |
|
|
|
|
|
|
|
bmih.biWidth = biTrueWidth; |
|
|
|
|
|
|
|
bmih.biHeight = pix->height; |
|
|
|
|
|
|
|
bmih.biPlanes = 1; |
|
|
|
|
|
|
|
bmih.biBitCount = pixel_size * 8; |
|
|
|
|
|
|
|
bmih.biCompression = BI_RGB; |
|
|
|
|
|
|
|
bmih.biSizeImage = cbBmpBits; |
|
|
|
|
|
|
|
bmih.biXPelsPerMeter = 0; |
|
|
|
|
|
|
|
bmih.biYPelsPerMeter = 0; |
|
|
|
|
|
|
|
bmih.biClrUsed = ( pixel_size == 1 ) ? 256 : 0; |
|
|
|
|
|
|
|
bmih.biClrImportant = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( host.write_to_clipboard ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
memcpy( clipbuf + cur_size, &bmih, sizeof( bmih )); |
|
|
|
|
|
|
|
cur_size += sizeof( bmih ); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// Write info header
|
|
|
|
|
|
|
|
FS_Write( pfile, &bmih, sizeof( bmih )); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pbBmpBits = Mem_Alloc( host.imagepool, cbBmpBits ); |
|
|
|
pbBmpBits = Mem_Alloc( host.imagepool, cbBmpBits ); |
|
|
@ -410,7 +410,7 @@ qboolean Image_SaveBMP( const char *name, rgbdata_t *pix ) |
|
|
|
pb = pix->palette; |
|
|
|
pb = pix->palette; |
|
|
|
|
|
|
|
|
|
|
|
// copy over used entries
|
|
|
|
// copy over used entries
|
|
|
|
for( i = 0; i < (int)bmih.biClrUsed; i++ ) |
|
|
|
for( i = 0; i < (int)hdr.colors; i++ ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
rgrgbPalette[i].rgbRed = *pb++; |
|
|
|
rgrgbPalette[i].rgbRed = *pb++; |
|
|
|
rgrgbPalette[i].rgbGreen = *pb++; |
|
|
|
rgrgbPalette[i].rgbGreen = *pb++; |
|
|
@ -437,9 +437,9 @@ qboolean Image_SaveBMP( const char *name, rgbdata_t *pix ) |
|
|
|
|
|
|
|
|
|
|
|
pb = pix->buffer; |
|
|
|
pb = pix->buffer; |
|
|
|
|
|
|
|
|
|
|
|
for( y = 0; y < bmih.biHeight; y++ ) |
|
|
|
for( y = 0; y < hdr.height; y++ ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
i = (bmih.biHeight - 1 - y ) * (bmih.biWidth); |
|
|
|
i = (hdr.height - 1 - y ) * (hdr.width); |
|
|
|
|
|
|
|
|
|
|
|
for( x = 0; x < pix->width; x++ ) |
|
|
|
for( x = 0; x < pix->width; x++ ) |
|
|
|
{ |
|
|
|
{ |
|
|
|