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

📄 wrbitmap.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*
*                            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 + -