📄 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 <windows.h>
#include <commdlg.h>
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <limits.h>
#include "imgedit.h"
#include "wrdll.h"
#include "wrbitmap.h"
#include "wricon.h"
#include "wrselft.h"
#include "iemem.h"
#define DEF_MEMFLAGS ( MEMFLAG_MOVEABLE | MEMFLAG_PURE )
#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( BITMAPINFO *bmi, FILE *fp, img_node *node )
{
HDC hdc;
HDC memdc;
int scanline_count;
int one_scanline_size;
long chunk_size;
int start;
int num_lines;
long byte_count;
BYTE *buffer;
hdc = GetDC( NULL );
memdc = CreateCompatibleDC( hdc );
ReleaseDC( NULL, hdc );
byte_count = bmi->bmiHeader.biSizeImage;
start = 0;
num_lines = SCANLINE_SIZE;
if (node->width > 32 && FALSE)
one_scanline_size = BITS_INTO_BYTES( node->width*node->bitcount, 1 );
else
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 = MemAlloc( chunk_size );
while (scanline_count > num_lines) {
GetDIBits(memdc, node->hxorbitmap, start, num_lines, buffer, bmi,
DIB_RGB_COLORS);
fwrite( buffer, sizeof(BYTE), chunk_size, fp );
scanline_count -= num_lines;
start += num_lines;
byte_count -= chunk_size;
}
GetDIBits(memdc, node->hxorbitmap, start, scanline_count, buffer, bmi,
DIB_RGB_COLORS);
fwrite( buffer, sizeof(BYTE), (one_scanline_size*scanline_count), fp );
MemFree( buffer );
DeleteDC( memdc );
return(TRUE);
} /* writeDataInPieces */
static BOOL writeDataInPiecesData( BITMAPINFO *bmi, BYTE **data,
uint_32 *size, img_node *node )
{
HDC hdc;
HDC memdc;
int scanline_count;
int one_scanline_size;
long chunk_size;
int start;
int num_lines;
long byte_count;
if( !data || !*data || !size ) {
return( FALSE );
}
hdc = GetDC( NULL );
memdc = CreateCompatibleDC( hdc );
ReleaseDC( NULL, hdc );
byte_count = bmi->bmiHeader.biSizeImage;
start = 0;
num_lines = SCANLINE_SIZE;
if (node->width > 32 && FALSE)
one_scanline_size = BITS_INTO_BYTES( node->width*node->bitcount, 1 );
else
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;
}
while( scanline_count > num_lines ) {
GetDIBits( memdc, node->hxorbitmap, start, num_lines, *data + *size,
bmi, DIB_RGB_COLORS );
*size += chunk_size;
scanline_count -= num_lines;
start += num_lines;
byte_count -= chunk_size;
}
GetDIBits( memdc, node->hxorbitmap, start, scanline_count, *data + *size,
bmi, DIB_RGB_COLORS );
*size += ( scanline_count * one_scanline_size );
DeleteDC( memdc );
return(TRUE);
} /* writeDataInPiecesData */
/*
* 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 */
/*
* 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 */
/*
* SaveHook - hook used called by common dialog - for 3-d controls
*/
BOOL CALLBACK SaveHook( HWND hwnd, int msg, UINT wparam, LONG lparam )
{
wparam = wparam;
lparam = lparam;
hwnd = hwnd;
switch( msg ) {
case WM_INITDIALOG:
// We must call this to subclass the directory listbox even
// if the app calls Ctl3dAutoSubclass (commdlg bug)
#if defined (__NT__)
// Only do it if NOT new shell.
if ( LOBYTE(LOWORD(GetVersion())) < 4 )
#endif
IECtl3dSubclassDlg( hwnd, CTL3D_ALL );
return( TRUE );
}
return( FALSE );
} /* SaveHook */
/*
* getSaveFName - Get the name of the file to be saved.
*/
static BOOL getSaveFName( char *fname, int imgtype )
{
static OPENFILENAME of;
char szFileTitle[_MAX_PATH];
char drive[ _MAX_DRIVE ];
char path[ _MAX_PATH ];
BOOL ret_val;
long of_size;
of_size = sizeof( OPENFILENAME );
#if defined (__NT__) && (WINVER >= 0x0500) && (_WIN32_WINNT >= 0x0500)
{
OSVERSIONINFO os_info;
os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(os_info);
if ( os_info.dwMajorVersion < 5 ) {
of_size = OPENFILENAME_SIZE_VERSION_400;
/* WIN32 major version < 5 detected */
/* See OPENFILENAME doc on www.msdn.com */
/* Added as future proofing... */
}
}
#endif
fname[ 0 ] = 0;
memset( &of, 0, of_size);
of.lStructSize = of_size;
of.hwndOwner = HMainWindow;
of.lpstrFilter = (LPSTR) IEImageFilter;
of.nFilterIndex = (long)imgtype;
of.lpstrFile = fname;
of.nMaxFile = _MAX_PATH;
of.lpstrFileTitle = szFileTitle;
of.nMaxFileTitle = sizeof(szFileTitle);
of.lpstrTitle = IESaveImageTitle;
of.lpstrInitialDir = initialDir;
#if !defined (__NT__)
/* Important! Do not use hook in WIN32, you will not get the nice dialog! */
of.lpfnHook = (LPVOID) MakeProcInstance( (LPVOID) SaveHook, Instance );
of.Flags = OFN_ENABLEHOOK;
#endif
of.Flags |= OFN_OVERWRITEPROMPT |
OFN_HIDEREADONLY;
ret_val = GetSaveFileName( &of );
#ifndef __NT__
FreeProcInstance( (LPVOID) of.lpfnHook );
#endif
if (ret_val) {
_splitpath( fname, drive, path, NULL, NULL );
strcpy( initialDir, drive );
strcat( initialDir, path );
initialDir[ strlen(initialDir)-1 ] = '\0';
}
return( ret_val );
} /* getSaveFName */
/*
* saveBitmapFile - gets the bitmap data and saves it in fname.
*/
BOOL saveBitmapFile( img_node *node )
{
BITMAPFILEHEADER bmfh;
BITMAPINFO *bmi;
long bitmap_size;
long number_of_bytes;
FILE *fp;
char filename[ _MAX_FNAME+_MAX_EXT ];
HDC hdc;
bmi = GetDIBitmapInfo(node);
if (bmi->bmiHeader.biWidth > 32 && FALSE)
number_of_bytes = BITS_INTO_BYTES(bmi->bmiHeader.biBitCount *
bmi->bmiHeader.biWidth,
bmi->bmiHeader.biHeight);
else
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( NULL );
GetDIBits(hdc, node->hxorbitmap, 0, node->height, NULL, bmi, DIB_RGB_COLORS);
ReleaseDC( 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;
GetFnameFromPath( node->fname, filename );
fp = fopen( node->fname, "wb" );
if (fp == NULL) {
WImgEditError( WIE_ERR_SAVE_FAIL, filename );
return(FALSE);
}
if (fseek( fp, 0L, SEEK_SET )) {
fclose( fp );
FreeDIBitmapInfo( bmi );
WImgEditError( WIE_ERR_SAVE_FAIL, filename );
return(FALSE);
}
if ( fwrite(&bmfh, sizeof(BITMAPFILEHEADER), 1, fp) != 1 ) {
fclose( fp );
FreeDIBitmapInfo( bmi );
WImgEditError( WIE_ERR_SAVE_FAIL, filename );
return(FALSE);
}
if ( fwrite(bmi, bitmap_size, 1, fp) != 1 ) {
fclose( fp );
FreeDIBitmapInfo( bmi );
WImgEditError( WIE_ERR_SAVE_FAIL, filename );
return(FALSE);
}
if (!writeDataInPieces( bmi, fp, node )) {
fclose( fp );
FreeDIBitmapInfo( bmi );
WImgEditError( WIE_ERR_SAVE_FAIL, filename );
return(FALSE);
}
fclose( fp );
FreeDIBitmapInfo( bmi );
AllowRestoreOption( node );
SetIsSaved( node->hwnd, TRUE );
PrintHintTextByID( WIE_BITMAPSAVEDTO, filename );
return( TRUE );
} /* saveBitmapFile */
/*
* saveBitmapToData - gets the bitmap data and saves into a block of memory
*/
BOOL saveBitmapToData( img_node *node, BYTE **data, uint_32 *size )
{
BITMAPFILEHEADER bmfh;
BITMAPINFO *bmi;
long bitmap_size;
long number_of_bytes;
HDC hdc;
if( !data || !size ) {
return( FALSE );
}
bmi = GetDIBitmapInfo(node);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -