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

📄 iesave.c

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