bmx.cpp
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 601 行 · 第 1/2 页
CPP
601 行
/****************************************************************************
*
* 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!
*
****************************************************************************/
/*
BMX: Image file handling
*/
#include <stdlib.h>
#ifdef __UNIX__
#include <unistd.h>
#else
#include <direct.h>
#endif
#include "bmx.h"
#include "compress.h"
// Magic numbers for the supported image formats.
#define BITMAP_MAGIC 0x4D42
#define SHG1_MAGIC 0x706C
#define SHG2_MAGIC 0x506C
// Bitmap::Bitmap --Check that the given file is a valid bitmap.
Bitmap::Bitmap( InFile *fp ) : Bmx( fp )
{
_size = 0;
uint_16 magic;
uint_32 filesize;
_fp->reset();
_fp->readbuf( &magic, 1, sizeof( uint_16 ) );
_fp->readbuf( &filesize, 1, sizeof( uint_32 ) );
_fp->reset(0, SEEK_END);
_fileSize = _fp->tell();
if( magic != BITMAP_MAGIC ||
filesize != _fileSize ){
_isValidImage = 0;
} else {
_isValidImage = 1;
}
_fp->close(); // To conserve file handles.
}
// Bitmap::size --Override of Dumpable::size. Reads in the
// bitmap and does a test compression of the pixels.
#define BLOCK_SIZE 1024 // Arbitrary large value.
#define BIH_SIZE 0x28 // Size of a BitmapInfoHeader (see Windows
// docs on bitmaps).
#define MIN_16BIT 0x80 // Smallest value stored in a short
#define MIN_32BIT 0x8000 // Smallest value stored in a long
#define OBJ_OFFSET 8 // Offset of the "object" in a .SHG file.
uint_32 Bitmap::size()
{
if( _size != 0 ){
return _size;
}
_fp->open();
_fp->reset( 10 ); // size of unneeded header info.
_fp->readbuf( &_pixOffset, 1, sizeof( uint_32 ) );
_fp->readbuf( &_headSize, 1, sizeof( uint_32 ) );
if( _headSize == BIH_SIZE ){
// If _headSize==0x28, this bitmap uses a BitmapInfoHeader
// and RBG quads.
_fp->readbuf( &_width, 1, sizeof( uint_32 ) );
_fp->readbuf( &_height, 1, sizeof( uint_32 ) );
_fp->readbuf( &_planes, 1, sizeof( uint_16 ) );
_fp->readbuf( &_bitsPerPix, 1, sizeof( uint_16 ) );
_fp->readbuf( &_compression, 1, sizeof( uint_32 ) );
_fp->readbuf( &_imageSize, 1, sizeof( uint_32 ) );
_fp->readbuf( &_xpels, 1, sizeof( uint_32 ) );
_fp->readbuf( &_ypels, 1, sizeof( uint_32 ) );
_fp->readbuf( &_colsUsed, 1, sizeof( uint_32 ) );
if( _colsUsed == 0 ){
// We can calculate _colsUsed from _bitsPerPix, except
// in the case of a 24-bit bitmap.
if( _bitsPerPix < 24 ){
_colsUsed = 1<<_bitsPerPix;
}
}
_fp->readbuf( &_colsImportant, 1, sizeof(uint_32) );
_dataPos = _fp->tell();
_fp->reset( sizeof(uint_32)*_colsUsed, SEEK_CUR );
} else {
// The other case is _headSize==0x0C, meaning this bitmap
// uses a BitmapCoreHeader and RGB triples.
_width = 0;
_fp->readbuf( &_width, 1, sizeof( uint_16 ) );
_height = 0;
_fp->readbuf( &_height, 1, sizeof( uint_16 ) );
_fp->readbuf( &_planes, 1, sizeof( uint_16 ) );
_fp->readbuf( &_bitsPerPix, 1, sizeof( uint_16 ) );
// Again, calculate _colsUsed from _bitsPerPix, unless
// this is a 24-bit bitmap.
if( _bitsPerPix < 24 ){
_colsUsed = 1<<_bitsPerPix;
} else {
_colsUsed = 0;
}
_colsImportant = 0;
_dataPos = _fp->tell();
_fp->reset( 3*_colsUsed, SEEK_CUR );
}
_objOffset = sizeof(uint_32)*_colsUsed + 0x1C; // 0x1C = size of
// object header
if( _bitsPerPix >= MIN_16BIT ){
_objOffset += 1;
}
if( _width >= MIN_32BIT ){
_objOffset += 2;
}
if( _height >= MIN_32BIT ){
_objOffset += 2;
}
if( _colsUsed >= MIN_32BIT ){
_objOffset += 2;
}
// Calculate the size of the compressed pixel data.
CompWriter riter;
CompReader reader( &riter );
char *buffer = new char[BLOCK_SIZE];
int blocksize;
int count = _pixOffset;
_pixSize = 0;
while( count < _fileSize ){
blocksize = _fp->readbuf( buffer, BLOCK_SIZE );
count += blocksize;
_pixSize += reader.compress( buffer, blocksize );
}
if( _pixSize >= MIN_32BIT ){
_objOffset += 2;
}
_size = _objOffset+OBJ_OFFSET+_pixSize;
delete[] buffer;
_fp->close();
return _size;
}
// Bitmap::dump --Overrides Dumpable::dump. Writes the
// converted image.
int Bitmap::dump( OutFile *dest )
{
uint_16 magic = SHG1_MAGIC;
uint_16 num_objs = 1;
uint_32 offset = OBJ_OFFSET;
uint_16 two_hund = 0x200;
uint_32 big_zero = 0x00000000;
dest->writebuf( &magic, sizeof( uint_16 ), 1 );
dest->writebuf( &num_objs, sizeof( uint_16 ), 1 );
dest->writebuf( &offset, sizeof( uint_32 ), 1 );
dest->writech( 0x06 ); // Identifies this as a .BMP
dest->writech( 0x02 ); // Specifies the compression type
dest->writech( 0xC0 ); // Specifies 96dpi
dest->writech( 0x00 ); // Magic
dest->writech( 0xC0 ); // Specifies 96dpi again
dest->writebuf( &two_hund, sizeof( uint_16 ), 1 );
_bitsPerPix *= 2;
if( _bitsPerPix >= 2*MIN_16BIT ){
_bitsPerPix += 1;
dest->writebuf( &_bitsPerPix, sizeof( uint_16 ), 1 );
} else {
dest->writech( *((uint_8*) &_bitsPerPix) );
}
_width *= 2;
if( _width >= 2*MIN_32BIT ){
_width += 1;
dest->writebuf( &_width, sizeof( uint_32 ), 1 );
} else {
dest->writebuf( (uint_16*) &_width, sizeof( uint_16 ), 1 );
}
_height *= 2;
if( _height >= 2*MIN_32BIT ){
_height += 1;
dest->writebuf( &_height, sizeof( uint_32 ), 1 );
} else {
dest->writebuf( (uint_16*) &_height, sizeof( uint_16 ), 1 );
}
_colsUsed *= 2;
if( _colsUsed >= 2*MIN_32BIT ){
_colsUsed += 1;
dest->writebuf( &_colsUsed, sizeof( uint_32 ), 1 );
} else {
dest->writebuf( (uint_16*) &_colsUsed, sizeof( uint_16 ), 1 );
}
_colsUsed /= 2; // We need this quantity again later.
dest->writebuf( (uint_16*) &big_zero, sizeof( uint_16 ), 1 );
_pixSize *= 2;
if( _pixSize >= 2*MIN_32BIT ){
_pixSize += 1;
dest->writebuf( &_pixSize, sizeof( uint_32 ), 1 );
} else {
dest->writebuf( (uint_16*) &_pixSize, sizeof( uint_16 ), 1 );
}
dest->writebuf( (uint_16*) &big_zero, sizeof( uint_16 ), 1 );
dest->writebuf( &_objOffset, sizeof( uint_32 ), 1 );
dest->writebuf( &big_zero, sizeof( uint_32 ), 1 );
// now write the colour table and pixel data.
uint_32 colour;
_fp->open();
_fp->reset( _dataPos );
if( _headSize == BIH_SIZE ){
for( int i=0; i<_colsUsed; i++ ){
_fp->readbuf( &colour, 1, sizeof( uint_32 ) );
dest->writebuf( &colour, sizeof( uint_32 ), 1 );
}
} else {
colour = 0;
for( int i=0; i<_colsUsed; i++ ){
_fp->readbuf( &colour, 3 );
dest->writebuf( &colour, sizeof( uint_32 ), 1 );
}
}
CompOutFile riter( dest );
CompReader reader( &riter );
char *buffer = new char[BLOCK_SIZE];
int blocksize;
int count = _pixOffset;
while( count < _fileSize ){
blocksize = _fp->readbuf( buffer, BLOCK_SIZE );
count += blocksize;
reader.compress( buffer, blocksize );
}
delete[] buffer;
reader.flush();
_fp->close();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?