📄 iesave.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 <malloc.h>
#include <math.h>
#include "imgedit.h"
#include "..\h\wbitmap.h"
#define SCANLINE_SIZE 32
#define MAX_CHUNK 32768
static char initialDir[ _MAX_PATH ];
/*
* writeDataInPieces - writes the xor data for the bitmap in chunks
*/
static BOOL writeDataInPieces( BITMAPINFO2 *bmi, FILE *fp, img_node *node )
{
WPI_PRES pres;
WPI_PRES mempres;
HDC memdc;
int scanline_count;
int one_scanline_size;
long chunk_size;
int start;
int num_lines;
long byte_count;
BYTE *buffer;
HBITMAP oldbitmap;
pres = _wpi_getpres( HWND_DESKTOP );
mempres = _wpi_createcompatiblepres( pres, Instance, &memdc );
_wpi_releasepres( HWND_DESKTOP, pres );
oldbitmap = _wpi_selectobject( mempres, node->hxorbitmap );
byte_count = BITS_TO_BYTES( node->bitcount * node->width, node->height );
start = 0;
num_lines = SCANLINE_SIZE;
one_scanline_size = BITS_TO_BYTES( node->width*node->bitcount, 1 );
scanline_count = node->height;
chunk_size = one_scanline_size * num_lines;
while ( chunk_size > MAX_CHUNK ) {
chunk_size >>= 1;
num_lines = chunk_size / one_scanline_size;
}
buffer = calloc( chunk_size, sizeof(BYTE) );
while (scanline_count > num_lines) {
GpiQueryBitmapBits( mempres, start, num_lines, buffer, bmi );
fwrite( buffer, sizeof(BYTE), chunk_size, fp );
scanline_count -= num_lines;
start += num_lines;
byte_count -= chunk_size;
}
GpiQueryBitmapBits( mempres, start, scanline_count, buffer, bmi );
fwrite( buffer, sizeof(BYTE), (one_scanline_size*scanline_count), fp );
free( buffer );
_wpi_selectobject( mempres, oldbitmap );
_wpi_deletecompatiblepres( mempres, memdc );
return(TRUE);
} /* writeDataInPieces */
/*
* writeImageBits - writes the bits for the image
*/
static BOOL writeImageBits( FILE *fp, img_node *node )
{
WPI_PRES pres;
WPI_PRES mempres;
HDC memdc;
ULONG byte_count;
img_node *new_image;
BITMAPINFO2 *bmi;
HBITMAP oldbitmap;
HBITMAP inverse_bitmap;
HBITMAP clr_bitmap;
BYTE *buffer;
pres = _wpi_getpres( HWND_DESKTOP );
mempres = _wpi_createcompatiblepres( pres, Instance, &memdc );
_wpi_releasepres( HWND_DESKTOP, pres );
new_image = node;
while( new_image ) {
bmi = GetAndBitmapInfo(new_image);
if (!bmi) {
return(FALSE);
}
/*
* first we write the PM XOR mask (inverse mask) then the PM AND
* mask (and mask) and then the PM colour mask (xor mask).
*/
byte_count = BITS_TO_BYTES( new_image->width, new_image->height );
buffer = MemAlloc( byte_count );
inverse_bitmap = CreateInverseBitmap( new_image->handbitmap,
new_image->hxorbitmap );
oldbitmap = _wpi_selectobject( mempres, inverse_bitmap );
GpiQueryBitmapBits( mempres, 0, new_image->height, buffer, bmi );
fwrite( buffer, sizeof(BYTE), byte_count, fp );
_wpi_selectobject( mempres, oldbitmap );
_wpi_deletebitmap( inverse_bitmap );
oldbitmap = _wpi_selectobject( mempres, new_image->handbitmap );
GpiQueryBitmapBits( mempres, 0, new_image->height, buffer, bmi );
fwrite( buffer, sizeof(BYTE), byte_count, fp );
_wpi_selectobject( mempres, oldbitmap );
free( buffer );
FreeDIBitmapInfo( bmi );
bmi = GetXorBitmapInfo( new_image );
if (!bmi) {
return(FALSE);
}
clr_bitmap = CreateColourBitmap( new_image->handbitmap,
new_image->hxorbitmap );
oldbitmap = _wpi_selectobject( mempres, clr_bitmap );
byte_count = BITS_TO_BYTES( new_image->width * new_image->bitcount,
new_image->height );
buffer = MemAlloc( byte_count );
GpiQueryBitmapBits( mempres, 0, node->height, buffer, bmi );
fwrite( buffer, sizeof(BYTE), byte_count, fp );
free( buffer );
FreeDIBitmapInfo( bmi );
_wpi_selectobject( mempres, oldbitmap );
_wpi_deletebitmap( clr_bitmap );
new_image = new_image->nexticon;
}
_wpi_deletecompatiblepres( mempres, memdc );
return( TRUE );
} /* writeImageBits */
/*
* fillFileHeader - fills the bitmap file header for the given node
*/
static BITMAPFILEHEADER2 *fillFileHeader( img_node *node )
{
BITMAPFILEHEADER2 *fileheader;
fileheader = MemAlloc( sizeof(BITMAPFILEHEADER2) );
memset( fileheader, 0, sizeof(BITMAPFILEHEADER2) );
if (node->imgtype == ICON_IMG) {
fileheader->usType = BFT_COLORICON;
} else {
fileheader->usType = BFT_COLORPOINTER;
}
fileheader->cbSize = sizeof( BITMAPFILEHEADER2 );
fileheader->xHotspot = node->hotspot.x;
fileheader->yHotspot = node->hotspot.y;
return( fileheader );
} /* fillFileHeader */
/*
* checkForExt - if no extension is given, use the default for the given
* type.
*/
static void checkForExt( img_node *node )
{
char drive[ _MAX_PATH ];
char dir[ _MAX_DIR ];
char fname[ _MAX_FNAME ];
char ext[ _MAX_EXT ];
char *fullpath;
img_node *next_icon;
char default_ext[3][4] = {
"bmp",
"ico",
"cur" };
next_icon = node;
while (next_icon) {
fullpath = next_icon->fname;
_splitpath( fullpath, drive, dir, fname, ext );
if ( strlen(ext) > 1 ) {
return;
}
if ( fullpath[strlen(fullpath) - 1] != '.' ) {
strcat( fullpath, "." );
}
strcat( fullpath, default_ext[ next_icon->imgtype-1 ] );
next_icon = next_icon->nexticon;
}
} /* checkForExt */
#if 0
/*
* checkForPalExt - if no extension is given, use the default palette
* extension of .pal.
*/
static void checkForPalExt( char *filename )
{
char ext[ _MAX_EXT ];
_splitpath( filename, NULL, NULL, NULL, ext );
if ( strlen(ext) > 1 ) {
return;
}
if ( filename[strlen(filename) - 1] != '.' ) {
strcat( filename, "." );
}
strcat( filename, "pal" );
} /* checkForPalExt */
#endif
/*
* getSaveFName - Get the name of the file to be saved.
*/
static BOOL getSaveFName( char *fname, int imgtype )
{
FILEDLG filedlg;
char ext[ _MAX_EXT ];
char drive[ _MAX_DRIVE ];
char path[ _MAX_PATH ];
HWND hdlg;
char fullfile[ CCHMAXPATH ];
fname[ 0 ] = 0;
memset( &filedlg, 0, sizeof( FILEDLG ) );
strcpy( fullfile, initialDir );
if ( fullfile[strlen(fullfile)-1] != '\\' ) {
strcat( fullfile, "\\" );
}
if ( imgtype == BITMAP_IMG ) {
strcat( fullfile, "*.bmp" );
} else if (imgtype == ICON_IMG) {
strcat( fullfile, "*.ico" );
} else {
strcat( fullfile, "*.ptr" );
}
/*
* set the values of the filedlg structure ...
*/
filedlg.cbSize = sizeof( FILEDLG );
filedlg.fl = FDS_SAVEAS_DIALOG | FDS_CENTER;
filedlg.pszTitle = "Save Image File";
filedlg.pszOKButton = "Save";
strcpy( filedlg.szFullFile, fullfile );
hdlg = WinFileDlg( HWND_DESKTOP, HMainWindow, &filedlg );
if ((hdlg == NULLHANDLE) || (filedlg.lReturn != DID_OK)) {
return(FALSE);
}
strcpy( fname, filedlg.szFullFile );
_splitpath( fname, drive, path, NULL, ext );
strcpy( initialDir, drive );
strcat( initialDir, path );
initialDir[ strlen(initialDir)-1 ] = '\0';
return(TRUE);
} /* getSaveFName */
/*
* saveBitmapFile - gets the bitmap data and saves it in fname.
*/
static BOOL saveBitmapFile( img_node *node )
{
BITMAPARRAYFILEHEADER2 new_file;
BITMAPINFO2 *bmi;
long clrtable_size;
RGB2 *colours;
FILE *fp;
char text[ HINT_TEXT_LEN ];
char filename[ _MAX_FNAME ];
bmi = GetXorBitmapInfo(node);
if (!bmi) {
return(FALSE);
}
clrtable_size = sizeof(RGB2) * (1<<(node->bitcount));
new_file.usType = BFT_BITMAPARRAY;
new_file.cbSize = sizeof( BITMAPARRAYFILEHEADER2 );
new_file.offNext = 0;
new_file.cxDisplay = 0;
new_file.cyDisplay = 0;
new_file.bfh2.usType = BFT_BMAP;
new_file.bfh2.cbSize = sizeof( BITMAPFILEHEADER2 );
new_file.bfh2.xHotspot = 0;
new_file.bfh2.yHotspot = 0;
new_file.bfh2.offBits = new_file.cbSize + clrtable_size;
memcpy( &(new_file.bfh2.bmp2), bmi, sizeof(BITMAPINFOHEADER2) );
colours = (void *)&(bmi->argbColor[0]);
fp = fopen( node->fname, "wb" );
if (fp == NULL) {
FreeDIBitmapInfo( bmi );
return(FALSE);
}
if (fseek( fp, 0L, SEEK_SET )) {
fclose( fp );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -