📄 wrbitmap.c
字号:
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <windows.h>
#include <limits.h>
#include <string.h>
#include <malloc.h>
#include <dos.h>
#include "wrglbl.h"
#include "wrmemi.h"
#include "wrmem.h"
#include "wr_wres.h"
#include "bitmap.h"
#include "palette.h"
#include "wrbitmap.h"
/****************************************************************************/
/* macro definitions */
/****************************************************************************/
#define START_OF_HEADER sizeof( BITMAPFILEHEADER )
#define HUGE_SHIFT 8
#define CHUNK_SIZE (48 * 1024)
#define RGBQ_SIZE( bc ) ( sizeof(RGBQUAD) * ((1<<(bc))))
#define SCANLINE_SIZE 32
#define MAX_CHUNK 32768
/****************************************************************************/
/* external function prototypes */
/****************************************************************************/
/****************************************************************************/
/* type definitions */
/****************************************************************************/
/****************************************************************************/
/* static function prototypes */
/****************************************************************************/
static BITMAPINFO *WRReadDIBInfo ( BYTE **data );
static BITMAPCOREINFO *WRReadCoreInfo ( BYTE **data );
static HBITMAP WRReadBitmap ( BYTE *data, long offset, BOOL core,
bitmap_info *info );
/****************************************************************************/
/* static variables */
/****************************************************************************/
static WResID *BitmapName = NULL;
#if !defined(__386__) && !defined(__ALPHA__)
#define _HUGE __huge
#define __halloc halloc
#define __hfree hfree
static void HugeMemCopy( char far *dst, char far *src, unsigned bytes )
{
long offset, selector;
long bytes_before_segment_end;
offset = FP_OFF( dst );
selector = FP_SEG( dst );
bytes_before_segment_end = 0x10000L - offset;
if( bytes_before_segment_end < bytes ) {
_fmemcpy( dst, src, bytes_before_segment_end );
bytes -= bytes_before_segment_end;
selector += HUGE_SHIFT;
dst = MK_FP( selector, 0 );
src += bytes_before_segment_end;
}
_fmemcpy( dst, src, bytes );
}
#else
#define HugeMemCopy( a, b, c ) memcpy( a, b, c )
#ifdef _HUGE
#undef _HUGE
#endif
#define _HUGE
#define __halloc( a, b ) malloc( a )
#define __hfree free
#endif
static BITMAPINFO *WRReadDIBInfo( BYTE **data )
{
BITMAPINFO *bm;
BITMAPINFOHEADER *header;
long bitmap_size;
int pos;
if( !data || !*data ) {
return( NULL );
}
pos = START_OF_HEADER;
header = (BITMAPINFOHEADER *)((*data)+pos);
bitmap_size = DIB_INFO_SIZE( header->biBitCount );
bm = WRMemAlloc( bitmap_size );
if( bm != NULL ) {
memcpy( bm, header, bitmap_size );
*data += (pos+bitmap_size);
}
return( bm );
}
static BITMAPCOREINFO *WRReadCoreInfo( BYTE **data )
{
BITMAPCOREINFO *bm_core;
BITMAPCOREHEADER *header;
long bitmap_size;
int pos;
if( !data || !*data ) {
return( NULL );
}
pos = START_OF_HEADER;
header = (BITMAPCOREHEADER *)((*data)+pos);
bitmap_size = CORE_INFO_SIZE( header->bcBitCount );
bm_core = WRMemAlloc( bitmap_size );
if( bm_core == NULL ) {
return( NULL );
}
memcpy( bm_core, (*data)+pos, bitmap_size );
*data += ( pos + bitmap_size );
return( bm_core );
}
static void WRReadInPieces( BYTE _HUGE *dst, BYTE *data, DWORD size )
{
BYTE *buffer;
WORD chunk_size;
chunk_size = CHUNK_SIZE;
while( chunk_size && ( ( buffer = WRMemAlloc( chunk_size ) ) == NULL ) ) {
chunk_size >>= 1;
}
if( buffer == NULL ) {
return;
}
while( size > chunk_size ) {
memcpy( buffer, data, chunk_size );
HugeMemCopy( dst, buffer, chunk_size );
dst += chunk_size;
size -= chunk_size;
data += chunk_size;
}
memcpy( buffer, data, size );
HugeMemCopy( dst, buffer, size );
WRMemFree( buffer );
} /* readInPieces */
static HBITMAP WRReadBitmap( BYTE *data, long offset, BOOL core, bitmap_info *info )
{
DWORD size; /* generic size - used repeatedly */
BYTE _HUGE *mask_ptr; /* pointer to bit array in memory */
HDC hdc;
HPALETTE new_palette, old_palette;
BITMAPINFO *bm_info;
BITMAPCOREINFO *bm_core;
HBITMAP bitmap_handle;
int pos;
bitmap_handle = (HBITMAP)NULL;
if( core ) {
bm_core = WRReadCoreInfo( &data );
if( bm_core == NULL ) {
return( bitmap_handle );
}
size = BITS_TO_BYTES( bm_core->bmciHeader.bcWidth *
bm_core->bmciHeader.bcBitCount,
bm_core->bmciHeader.bcHeight );
} else {
bm_info = WRReadDIBInfo( &data );
if( bm_info == NULL ) {
return( bitmap_handle );
}
size = BITS_TO_BYTES( bm_info->bmiHeader.biWidth *
bm_info->bmiHeader.biBitCount,
bm_info->bmiHeader.biHeight );
}
pos = offset;
mask_ptr = __halloc( size, 1 );
if( mask_ptr != NULL ) {
WRReadInPieces( mask_ptr, data, size );
if( core ) {
BITMAPCOREHEADER *h;
h = &bm_core->bmciHeader;
/*
* This will cause a GP Fault!
*/
bitmap_handle = CreateBitmap( h->bcWidth, h->bcHeight, h->bcPlanes,
h->bcBitCount, mask_ptr );
} else {
if( bm_info->bmiHeader.biBitCount < 9 ) {
/* Bitmap has palette, create it */
new_palette = CreateDIBPalette( bm_info );
if( new_palette ) {
hdc = GetDC( (HWND)NULL );
old_palette = SelectPalette( hdc, new_palette, FALSE );
RealizePalette( hdc );
bitmap_handle = CreateDIBitmap( hdc, &bm_info->bmiHeader,
CBM_INIT, mask_ptr, bm_info, DIB_RGB_COLORS );
SelectPalette( hdc, old_palette, FALSE );
DeleteObject( new_palette );
ReleaseDC( (HWND)NULL, hdc );
}
}
else {
/* Bitmap with no palette*/
hdc = GetDC( (HWND)NULL );
bitmap_handle = CreateDIBitmap( hdc, &bm_info->bmiHeader,
CBM_INIT, mask_ptr, bm_info, DIB_RGB_COLORS );
ReleaseDC( (HWND)NULL, hdc );
}
}
__hfree( mask_ptr );
}
if( core ) {
if( info != NULL ) {
info->bm_core = bm_core;
} else {
WRMemFree( bm_core );
}
} else {
if( info != NULL ) {
info->bm_info = bm_info;
} else {
WRMemFree( bm_info );
}
}
return( bitmap_handle );
}
/*
* Creates a device independant bitmap from the data <data> and
* returns a handle to a newly created BITMAP.
*/
HBITMAP WR_EXPORT WRBitmapFromData( BYTE *data, bitmap_info *info )
{
HBITMAP bitmap_handle;
BITMAPFILEHEADER *file_header;
BOOL core;
DWORD *size;
int pos;
long offset;
if( data == NULL ) {
return( (HBITMAP)NULL );
}
bitmap_handle = (HBITMAP)NULL;
file_header = (BITMAPFILEHEADER *)data;
if( file_header->bfType != BITMAP_TYPE ) {
return( bitmap_handle );
}
pos = sizeof(BITMAPFILEHEADER);
size = (DWORD *)(data+pos);
core = ( *size == sizeof( BITMAPCOREHEADER ) );
if (!core) {
offset = file_header->bfOffBits;
bitmap_handle = WRReadBitmap( data, offset, core, info );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -