/* * readDIBInfo - read BITMAPINFO structure from a bitmap file * * NOTE: Assume fp is positioned at the start of the bitmap information. * We first read in the BITMAPINFOHEADER to get information about the * number of quads needed, then we reposition ourselves and read in * the entire BITMAPINFOHEADER structure. */ static BITMAPINFO *readDIBInfo( FILE *fp ) { BITMAPINFO *bm; BITMAPINFOHEADER *header; long bitmap_size; header = MemAlloc( sizeof( BITMAPINFOHEADER ) ); if( header == NULL ) { return( NULL ); } fseek( fp, START_OF_HEADER, SEEK_SET ); fread( header, sizeof( BITMAPINFOHEADER ), 1, fp ); if( header->biBitCount < 9 ) { /* Bitmap has palette, read it */ fseek( fp, START_OF_HEADER, SEEK_SET ); bitmap_size = DIB_INFO_SIZE( header->biBitCount ); bm = MemReAlloc( header, bitmap_size ); if( bm == NULL ) { return( NULL ); } fread( bm, bitmap_size, 1, fp ); } else { return( (BITMAPINFO*) header ); } return( bm ); } /* readDIBInfo */
uint_32 WRAPI WRSizeOfImage( BITMAPINFOHEADER *bih ) { uint_32 size; size = (uint_32)(DIB_INFO_SIZE( bih->biBitCount ) + bih->biSizeImage); return( size ); }
bool WRAPI WRWriteBitmapToData( HBITMAP hbitmap, BYTE **data, size_t *size ) { BITMAPFILEHEADER bmfh; BITMAPINFO *bmi; long bitmap_size; long number_of_bytes; HDC hdc; bool ok; ok = false; if( hbitmap == (HBITMAP)NULL || data == NULL || size == NULL ) { return( ok ); } bmi = WRGetDIBitmapInfo( hbitmap ); if( bmi != NULL ) { number_of_bytes = BITS_TO_BYTES( bmi->bmiHeader.biBitCount * bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight ); bitmap_size = DIB_INFO_SIZE( bmi->bmiHeader.biBitCount ); hdc = GetDC( (HWND)NULL ); GetDIBits( hdc, hbitmap, 0, bmi->bmiHeader.biHeight, NULL, bmi, DIB_RGB_COLORS ); ReleaseDC( (HWND)NULL, hdc ); if( bmi->bmiHeader.biSizeImage == 0 ) { bmi->bmiHeader.biSizeImage = number_of_bytes; } else { number_of_bytes = bmi->bmiHeader.biSizeImage; } bmfh.bfType = BITMAP_TYPE; bmfh.bfSize = sizeof( BITMAPFILEHEADER ) + bitmap_size + number_of_bytes; bmfh.bfReserved1 = 0; bmfh.bfReserved2 = 0; bmfh.bfOffBits = sizeof( BITMAPFILEHEADER ) + bitmap_size; // make sure the bitmap can actually be malloc'd!! if( bmfh.bfSize <= INT_MAX ) { *data = MemAlloc( bmfh.bfSize ); if( *data != NULL ) { ok = true; *size = 0; memcpy( *data + *size, &bmfh, sizeof( BITMAPFILEHEADER ) ); *size += sizeof( BITMAPFILEHEADER ); memcpy( *data + *size, bmi, bitmap_size ); *size += bitmap_size; if( !WRWriteDataInPiecesData( bmi, data, size, hbitmap ) ) { ok = false; } } } MemFree( bmi ); } return( ok ); }
static BITMAPINFO *WRGetDIBitmapInfo( HBITMAP hbitmap ) { long size; BITMAPINFO *bmi; BITMAP bm; if( hbitmap == (HBITMAP)NULL ) { return( NULL ); } GetObject( hbitmap, sizeof( BITMAP ), &bm ); size = DIB_INFO_SIZE( bm.bmPlanes ); bmi = (BITMAPINFO *)MemAlloc( size ); if( bmi != NULL ) { if( !WRGetBitmapInfo( bmi, &bm ) ) { MemFree( bmi ); bmi = NULL; } } return( bmi ); }
static BITMAPINFO *WRReadDIBInfo( BYTE **data ) { BITMAPINFO *bm; BITMAPINFOHEADER *header; long bitmap_size; int pos; if( data == NULL || *data == NULL ) { return( NULL ); } pos = START_OF_HEADER; header = (BITMAPINFOHEADER *)((*data) + pos); bitmap_size = DIB_INFO_SIZE( header->biBitCount ); bm = MemAlloc( bitmap_size ); if( bm != NULL ) { memcpy( bm, header, bitmap_size ); *data += pos + bitmap_size; } return( bm ); }
bool WRAPI WRAddBitmapFileHeader( BYTE **data, size_t *size ) { BITMAPFILEHEADER *bmfh; BITMAPINFO *bmi; BITMAPCOREINFO *bmci; int hsize; bool is_core; if( data == NULL || size == NULL ) { return( false ); } is_core = ( *(DWORD *)*data == sizeof( BITMAPCOREHEADER ) ); hsize = sizeof( BITMAPFILEHEADER ); *data = MemRealloc( *data, *size + hsize ); if( *data == NULL ) { return( false ); } memmove( *data + hsize, *data, *size ); memset( *data, 0, hsize ); *size += hsize; bmfh = (BITMAPFILEHEADER *)*data; bmfh->bfType = BITMAP_TYPE; bmfh->bfSize = *size; bmfh->bfOffBits = hsize; if( is_core ) { bmci = (BITMAPCOREINFO *)( *data + hsize ); bmfh->bfOffBits += CORE_INFO_SIZE( bmci->bmciHeader.bcBitCount ); } else { bmi = (BITMAPINFO *)( *data + hsize ); bmfh->bfOffBits += DIB_INFO_SIZE( bmi->bmiHeader.biBitCount ); } return( true ); }