|
fukasawa |
e60969 |
/*------------------------------------
|
|
fukasawa |
e60969 |
* VisualPng.C -- Shows a PNG image
|
|
fukasawa |
e60969 |
*------------------------------------
|
|
fukasawa |
e60969 |
*
|
|
fukasawa |
e60969 |
* Copyright 2000, Willem van Schaik.
|
|
fukasawa |
e60969 |
*
|
|
fukasawa |
e60969 |
* This code is released under the libpng license.
|
|
fukasawa |
e60969 |
* For conditions of distribution and use, see the disclaimer
|
|
fukasawa |
e60969 |
* and license in png.h
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* switches */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* defines */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
#define PROGNAME "VisualPng"
|
|
fukasawa |
e60969 |
#define LONGNAME "Win32 Viewer for PNG-files"
|
|
fukasawa |
e60969 |
#define VERSION "1.0 of 2000 June 07"
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* constants */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
#define MARGIN 8
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* standard includes */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
#include <stdio.h></stdio.h>
|
|
fukasawa |
e60969 |
#include <stdlib.h></stdlib.h>
|
|
fukasawa |
e60969 |
#include <string.h></string.h>
|
|
fukasawa |
e60969 |
#include <windows.h></windows.h>
|
|
fukasawa |
e60969 |
#include <zlib.h></zlib.h>
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* application includes */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
#include "png.h"
|
|
fukasawa |
e60969 |
#include "pngfile.h"
|
|
fukasawa |
e60969 |
#include "resource.h"
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* macros */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* function prototypes */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
|
|
fukasawa |
e60969 |
BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
BOOL CenterAbout (HWND hwndChild, HWND hwndParent);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount,
|
|
fukasawa |
e60969 |
int *pFileIndex);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
BOOL SearchPngList (TCHAR *pFileList, int FileCount, int *pFileIndex,
|
|
fukasawa |
e60969 |
PTSTR pstrPrevName, PTSTR pstrNextName);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
BOOL LoadImageFile(HWND hwnd, PTSTR pstrPathName,
|
|
fukasawa |
e60969 |
png_byte **ppbImage, int *pxImgSize, int *pyImgSize, int *piChannels,
|
|
fukasawa |
e60969 |
png_color *pBkgColor);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
BOOL DisplayImage (HWND hwnd, BYTE **ppDib,
|
|
fukasawa |
e60969 |
BYTE **ppDiData, int cxWinSize, int cyWinSize,
|
|
fukasawa |
e60969 |
BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
|
|
fukasawa |
e60969 |
BOOL bStretched);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
BOOL InitBitmap (
|
|
fukasawa |
e60969 |
BYTE *pDiData, int cxWinSize, int cyWinSize);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
BOOL FillBitmap (
|
|
fukasawa |
e60969 |
BYTE *pDiData, int cxWinSize, int cyWinSize,
|
|
fukasawa |
e60969 |
BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
|
|
fukasawa |
e60969 |
BOOL bStretched);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* a few global variables */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
static char *szProgName = PROGNAME;
|
|
fukasawa |
e60969 |
static char *szAppName = LONGNAME;
|
|
fukasawa |
e60969 |
static char *szIconName = PROGNAME;
|
|
fukasawa |
e60969 |
static char szCmdFileName [MAX_PATH];
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* MAIN routine */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|
fukasawa |
e60969 |
PSTR szCmdLine, int iCmdShow)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
HACCEL hAccel;
|
|
fukasawa |
e60969 |
HWND hwnd;
|
|
fukasawa |
e60969 |
MSG msg;
|
|
fukasawa |
e60969 |
WNDCLASS wndclass;
|
|
fukasawa |
e60969 |
int ixBorders, iyBorders;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
wndclass.style = CS_HREDRAW | CS_VREDRAW;
|
|
fukasawa |
e60969 |
wndclass.lpfnWndProc = WndProc;
|
|
fukasawa |
e60969 |
wndclass.cbClsExtra = 0;
|
|
fukasawa |
e60969 |
wndclass.cbWndExtra = 0;
|
|
fukasawa |
e60969 |
wndclass.hInstance = hInstance;
|
|
fukasawa |
e60969 |
wndclass.hIcon = LoadIcon (hInstance, szIconName) ;
|
|
fukasawa |
e60969 |
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
|
|
fukasawa |
e60969 |
wndclass.hbrBackground = NULL; /* (HBRUSH) GetStockObject (GRAY_BRUSH); */
|
|
fukasawa |
e60969 |
wndclass.lpszMenuName = szProgName;
|
|
fukasawa |
e60969 |
wndclass.lpszClassName = szProgName;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (!RegisterClass (&wndclass))
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
MessageBox (NULL, TEXT ("Error: this program requires Windows NT!"),
|
|
fukasawa |
e60969 |
szProgName, MB_ICONERROR);
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* if filename given on commandline, store it */
|
|
fukasawa |
e60969 |
if ((szCmdLine != NULL) && (*szCmdLine != '\0'))
|
|
fukasawa |
e60969 |
if (szCmdLine[0] == '"')
|
|
fukasawa |
e60969 |
strncpy (szCmdFileName, szCmdLine + 1, strlen(szCmdLine) - 2);
|
|
fukasawa |
e60969 |
else
|
|
fukasawa |
e60969 |
strcpy (szCmdFileName, szCmdLine);
|
|
fukasawa |
e60969 |
else
|
|
fukasawa |
e60969 |
strcpy (szCmdFileName, "");
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* calculate size of window-borders */
|
|
fukasawa |
e60969 |
ixBorders = 2 * (GetSystemMetrics (SM_CXBORDER) +
|
|
fukasawa |
e60969 |
GetSystemMetrics (SM_CXDLGFRAME));
|
|
fukasawa |
e60969 |
iyBorders = 2 * (GetSystemMetrics (SM_CYBORDER) +
|
|
fukasawa |
e60969 |
GetSystemMetrics (SM_CYDLGFRAME)) +
|
|
fukasawa |
e60969 |
GetSystemMetrics (SM_CYCAPTION) +
|
|
fukasawa |
e60969 |
GetSystemMetrics (SM_CYMENUSIZE) +
|
|
fukasawa |
e60969 |
1; /* WvS: don't ask me why? */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
hwnd = CreateWindow (szProgName, szAppName,
|
|
fukasawa |
e60969 |
WS_OVERLAPPEDWINDOW,
|
|
fukasawa |
e60969 |
CW_USEDEFAULT, CW_USEDEFAULT,
|
|
fukasawa |
e60969 |
512 + 2 * MARGIN + ixBorders, 384 + 2 * MARGIN + iyBorders,
|
|
fukasawa |
e60969 |
/* CW_USEDEFAULT, CW_USEDEFAULT, */
|
|
fukasawa |
e60969 |
NULL, NULL, hInstance, NULL);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
ShowWindow (hwnd, iCmdShow);
|
|
fukasawa |
e60969 |
UpdateWindow (hwnd);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
hAccel = LoadAccelerators (hInstance, szProgName);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
while (GetMessage (&msg, NULL, 0, 0))
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
if (!TranslateAccelerator (hwnd, hAccel, &msg))
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
TranslateMessage (&msg);
|
|
fukasawa |
e60969 |
DispatchMessage (&msg);
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
return msg.wParam;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,
|
|
fukasawa |
e60969 |
LPARAM lParam)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
static HINSTANCE hInstance ;
|
|
fukasawa |
e60969 |
static HDC hdc;
|
|
fukasawa |
e60969 |
static PAINTSTRUCT ps;
|
|
fukasawa |
e60969 |
static HMENU hMenu;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
static BITMAPFILEHEADER *pbmfh;
|
|
fukasawa |
e60969 |
static BITMAPINFOHEADER *pbmih;
|
|
fukasawa |
e60969 |
static BYTE *pbImage;
|
|
fukasawa |
e60969 |
static int cxWinSize, cyWinSize;
|
|
fukasawa |
e60969 |
static int cxImgSize, cyImgSize;
|
|
fukasawa |
e60969 |
static int cImgChannels;
|
|
fukasawa |
e60969 |
static png_color bkgColor = {127, 127, 127};
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
static BOOL bStretched = TRUE;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
static BYTE *pDib = NULL;
|
|
fukasawa |
e60969 |
static BYTE *pDiData = NULL;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
static TCHAR szImgPathName [MAX_PATH];
|
|
fukasawa |
e60969 |
static TCHAR szTitleName [MAX_PATH];
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
static TCHAR *pPngFileList = NULL;
|
|
fukasawa |
e60969 |
static int iPngFileCount;
|
|
fukasawa |
e60969 |
static int iPngFileIndex;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
BOOL bOk;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
switch (message)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
case WM_CREATE:
|
|
fukasawa |
e60969 |
hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
|
|
fukasawa |
e60969 |
PngFileInitialize (hwnd);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
strcpy (szImgPathName, "");
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* in case we process file given on command-line */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (szCmdFileName[0] != '\0')
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
strcpy (szImgPathName, szCmdFileName);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* read the other png-files in the directory for later */
|
|
fukasawa |
e60969 |
/* next/previous commands */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount,
|
|
fukasawa |
e60969 |
&iPngFileIndex);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* load the image from file */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (!LoadImageFile (hwnd, szImgPathName,
|
|
fukasawa |
e60969 |
&pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* invalidate the client area for later update */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
InvalidateRect (hwnd, NULL, TRUE);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* display the PNG into the DIBitmap */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
|
|
fukasawa |
e60969 |
pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case WM_SIZE:
|
|
fukasawa |
e60969 |
cxWinSize = LOWORD (lParam);
|
|
fukasawa |
e60969 |
cyWinSize = HIWORD (lParam);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* invalidate the client area for later update */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
InvalidateRect (hwnd, NULL, TRUE);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* display the PNG into the DIBitmap */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
|
|
fukasawa |
e60969 |
pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case WM_INITMENUPOPUP:
|
|
fukasawa |
e60969 |
hMenu = GetMenu (hwnd);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (pbImage)
|
|
fukasawa |
e60969 |
EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_ENABLED);
|
|
fukasawa |
e60969 |
else
|
|
fukasawa |
e60969 |
EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_GRAYED);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case WM_COMMAND:
|
|
fukasawa |
e60969 |
hMenu = GetMenu (hwnd);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
switch (LOWORD (wParam))
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
case IDM_FILE_OPEN:
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* show the File Open dialog box */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (!PngFileOpenDlg (hwnd, szImgPathName, szTitleName))
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* read the other png-files in the directory for later */
|
|
fukasawa |
e60969 |
/* next/previous commands */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount,
|
|
fukasawa |
e60969 |
&iPngFileIndex);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* load the image from file */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (!LoadImageFile (hwnd, szImgPathName,
|
|
fukasawa |
e60969 |
&pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* invalidate the client area for later update */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
InvalidateRect (hwnd, NULL, TRUE);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* display the PNG into the DIBitmap */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
|
|
fukasawa |
e60969 |
pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case IDM_FILE_SAVE:
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* show the File Save dialog box */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (!PngFileSaveDlg (hwnd, szImgPathName, szTitleName))
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* save the PNG to a disk file */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
SetCursor (LoadCursor (NULL, IDC_WAIT));
|
|
fukasawa |
e60969 |
ShowCursor (TRUE);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
bOk = PngSaveImage (szImgPathName, pDiData, cxWinSize, cyWinSize,
|
|
fukasawa |
e60969 |
bkgColor);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
ShowCursor (FALSE);
|
|
fukasawa |
e60969 |
SetCursor (LoadCursor (NULL, IDC_ARROW));
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (!bOk)
|
|
fukasawa |
e60969 |
MessageBox (hwnd, TEXT ("Error in saving the PNG image"),
|
|
fukasawa |
e60969 |
szProgName, MB_ICONEXCLAMATION | MB_OK);
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case IDM_FILE_NEXT:
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* read next entry in the directory */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex,
|
|
fukasawa |
e60969 |
NULL, szImgPathName))
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
if (strcmp (szImgPathName, "") == 0)
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* load the image from file */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (!LoadImageFile (hwnd, szImgPathName, &pbImage,
|
|
fukasawa |
e60969 |
&cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* invalidate the client area for later update */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
InvalidateRect (hwnd, NULL, TRUE);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* display the PNG into the DIBitmap */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
|
|
fukasawa |
e60969 |
pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case IDM_FILE_PREVIOUS:
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* read previous entry in the directory */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex,
|
|
fukasawa |
e60969 |
szImgPathName, NULL))
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (strcmp (szImgPathName, "") == 0)
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* load the image from file */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (!LoadImageFile (hwnd, szImgPathName, &pbImage, &cxImgSize,
|
|
fukasawa |
e60969 |
&cyImgSize, &cImgChannels, &bkgColor))
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* invalidate the client area for later update */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
InvalidateRect (hwnd, NULL, TRUE);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* display the PNG into the DIBitmap */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
|
|
fukasawa |
e60969 |
pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case IDM_FILE_EXIT:
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* more cleanup needed... */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* free image buffer */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (pDib != NULL)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
free (pDib);
|
|
fukasawa |
e60969 |
pDib = NULL;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* free file-list */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (pPngFileList != NULL)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
free (pPngFileList);
|
|
fukasawa |
e60969 |
pPngFileList = NULL;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* let's go ... */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
exit (0);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case IDM_OPTIONS_STRETCH:
|
|
fukasawa |
e60969 |
bStretched = !bStretched;
|
|
fukasawa |
e60969 |
if (bStretched)
|
|
fukasawa |
e60969 |
CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_CHECKED);
|
|
fukasawa |
e60969 |
else
|
|
fukasawa |
e60969 |
CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_UNCHECKED);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* invalidate the client area for later update */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
InvalidateRect (hwnd, NULL, TRUE);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* display the PNG into the DIBitmap */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
|
|
fukasawa |
e60969 |
pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case IDM_HELP_ABOUT:
|
|
fukasawa |
e60969 |
DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc) ;
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
} /* end switch */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case WM_PAINT:
|
|
fukasawa |
e60969 |
hdc = BeginPaint (hwnd, &ps);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (pDib)
|
|
fukasawa |
e60969 |
SetDIBitsToDevice (hdc, 0, 0, cxWinSize, cyWinSize, 0, 0,
|
|
fukasawa |
e60969 |
0, cyWinSize, pDiData, (BITMAPINFO *) pDib, DIB_RGB_COLORS);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
EndPaint (hwnd, &ps);
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case WM_DESTROY:
|
|
fukasawa |
e60969 |
if (pbmfh)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
free (pbmfh);
|
|
fukasawa |
e60969 |
pbmfh = NULL;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
PostQuitMessage (0);
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return DefWindowProc (hwnd, message, wParam, lParam);
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message,
|
|
fukasawa |
e60969 |
WPARAM wParam, LPARAM lParam)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
switch (message)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
case WM_INITDIALOG :
|
|
fukasawa |
e60969 |
ShowWindow (hDlg, SW_HIDE);
|
|
fukasawa |
e60969 |
CenterAbout (hDlg, GetWindow (hDlg, GW_OWNER));
|
|
fukasawa |
e60969 |
ShowWindow (hDlg, SW_SHOW);
|
|
fukasawa |
e60969 |
return TRUE ;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case WM_COMMAND :
|
|
fukasawa |
e60969 |
switch (LOWORD (wParam))
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
case IDOK :
|
|
fukasawa |
e60969 |
case IDCANCEL :
|
|
fukasawa |
e60969 |
EndDialog (hDlg, 0) ;
|
|
fukasawa |
e60969 |
return TRUE ;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
break ;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
return FALSE ;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/*---------------
|
|
fukasawa |
e60969 |
* CenterAbout
|
|
fukasawa |
e60969 |
*---------------
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
BOOL CenterAbout (HWND hwndChild, HWND hwndParent)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
RECT rChild, rParent, rWorkArea;
|
|
fukasawa |
e60969 |
int wChild, hChild, wParent, hParent;
|
|
fukasawa |
e60969 |
int xNew, yNew;
|
|
fukasawa |
e60969 |
BOOL bResult;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* Get the Height and Width of the child window */
|
|
fukasawa |
e60969 |
GetWindowRect (hwndChild, &rChild);
|
|
fukasawa |
e60969 |
wChild = rChild.right - rChild.left;
|
|
fukasawa |
e60969 |
hChild = rChild.bottom - rChild.top;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* Get the Height and Width of the parent window */
|
|
fukasawa |
e60969 |
GetWindowRect (hwndParent, &rParent);
|
|
fukasawa |
e60969 |
wParent = rParent.right - rParent.left;
|
|
fukasawa |
e60969 |
hParent = rParent.bottom - rParent.top;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* Get the limits of the 'workarea' */
|
|
fukasawa |
e60969 |
bResult = SystemParametersInfo(
|
|
fukasawa |
e60969 |
SPI_GETWORKAREA, /* system parameter to query or set */
|
|
fukasawa |
e60969 |
sizeof(RECT),
|
|
fukasawa |
e60969 |
&rWorkArea,
|
|
fukasawa |
e60969 |
0);
|
|
fukasawa |
e60969 |
if (!bResult) {
|
|
fukasawa |
e60969 |
rWorkArea.left = rWorkArea.top = 0;
|
|
fukasawa |
e60969 |
rWorkArea.right = GetSystemMetrics(SM_CXSCREEN);
|
|
fukasawa |
e60969 |
rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN);
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* Calculate new X position, then adjust for workarea */
|
|
fukasawa |
e60969 |
xNew = rParent.left + ((wParent - wChild) /2);
|
|
fukasawa |
e60969 |
if (xNew < rWorkArea.left) {
|
|
fukasawa |
e60969 |
xNew = rWorkArea.left;
|
|
fukasawa |
e60969 |
} else if ((xNew+wChild) > rWorkArea.right) {
|
|
fukasawa |
e60969 |
xNew = rWorkArea.right - wChild;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* Calculate new Y position, then adjust for workarea */
|
|
fukasawa |
e60969 |
yNew = rParent.top + ((hParent - hChild) /2);
|
|
fukasawa |
e60969 |
if (yNew < rWorkArea.top) {
|
|
fukasawa |
e60969 |
yNew = rWorkArea.top;
|
|
fukasawa |
e60969 |
} else if ((yNew+hChild) > rWorkArea.bottom) {
|
|
fukasawa |
e60969 |
yNew = rWorkArea.bottom - hChild;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* Set it, and return */
|
|
fukasawa |
e60969 |
return SetWindowPos (hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE |
|
|
fukasawa |
e60969 |
SWP_NOZORDER);
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/*----------------
|
|
fukasawa |
e60969 |
* BuildPngList
|
|
fukasawa |
e60969 |
*----------------
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount,
|
|
fukasawa |
e60969 |
int *pFileIndex)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
static TCHAR szImgPathName [MAX_PATH];
|
|
fukasawa |
e60969 |
static TCHAR szImgFileName [MAX_PATH];
|
|
fukasawa |
e60969 |
static TCHAR szImgFindName [MAX_PATH];
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
WIN32_FIND_DATA finddata;
|
|
fukasawa |
e60969 |
HANDLE hFind;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
static TCHAR szTmp [MAX_PATH];
|
|
fukasawa |
e60969 |
BOOL bOk;
|
|
fukasawa |
e60969 |
int i, ii;
|
|
fukasawa |
e60969 |
int j, jj;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* free previous file-list */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (*ppFileList != NULL)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
free (*ppFileList);
|
|
fukasawa |
e60969 |
*ppFileList = NULL;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* extract foldername, filename and search-name */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
strcpy (szImgPathName, pstrPathName);
|
|
fukasawa |
e60969 |
strcpy (szImgFileName, strrchr (pstrPathName, '\\') + 1);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
strcpy (szImgFindName, szImgPathName);
|
|
fukasawa |
e60969 |
*(strrchr (szImgFindName, '\\') + 1) = '\0';
|
|
fukasawa |
e60969 |
strcat (szImgFindName, "*.png");
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* first cycle: count number of files in directory for memory allocation */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
*pFileCount = 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
hFind = FindFirstFile(szImgFindName, &finddata);
|
|
fukasawa |
e60969 |
bOk = (hFind != (HANDLE) -1);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
while (bOk)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
*pFileCount += 1;
|
|
fukasawa |
e60969 |
bOk = FindNextFile(hFind, &finddata);
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
FindClose(hFind);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* allocation memory for file-list */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
*ppFileList = (TCHAR *) malloc (*pFileCount * MAX_PATH);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* second cycle: read directory and store filenames in file-list */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
hFind = FindFirstFile(szImgFindName, &finddata);
|
|
fukasawa |
e60969 |
bOk = (hFind != (HANDLE) -1);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
i = 0;
|
|
fukasawa |
e60969 |
ii = 0;
|
|
fukasawa |
e60969 |
while (bOk)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
strcpy (*ppFileList + ii, szImgPathName);
|
|
fukasawa |
e60969 |
strcpy (strrchr(*ppFileList + ii, '\\') + 1, finddata.cFileName);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (strcmp(pstrPathName, *ppFileList + ii) == 0)
|
|
fukasawa |
e60969 |
*pFileIndex = i;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
ii += MAX_PATH;
|
|
fukasawa |
e60969 |
i++;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
bOk = FindNextFile(hFind, &finddata);
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
FindClose(hFind);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* finally we must sort the file-list */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
for (i = 0; i < *pFileCount - 1; i++)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
ii = i * MAX_PATH;
|
|
fukasawa |
e60969 |
for (j = i+1; j < *pFileCount; j++)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
jj = j * MAX_PATH;
|
|
fukasawa |
e60969 |
if (strcmp (*ppFileList + ii, *ppFileList + jj) > 0)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
strcpy (szTmp, *ppFileList + jj);
|
|
fukasawa |
e60969 |
strcpy (*ppFileList + jj, *ppFileList + ii);
|
|
fukasawa |
e60969 |
strcpy (*ppFileList + ii, szTmp);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* check if this was the current image that we moved */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (*pFileIndex == i)
|
|
fukasawa |
e60969 |
*pFileIndex = j;
|
|
fukasawa |
e60969 |
else
|
|
fukasawa |
e60969 |
if (*pFileIndex == j)
|
|
fukasawa |
e60969 |
*pFileIndex = i;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return TRUE;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/*----------------
|
|
fukasawa |
e60969 |
* SearchPngList
|
|
fukasawa |
e60969 |
*----------------
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
BOOL SearchPngList (
|
|
fukasawa |
e60969 |
TCHAR *pFileList, int FileCount, int *pFileIndex,
|
|
fukasawa |
e60969 |
PTSTR pstrPrevName, PTSTR pstrNextName)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
if (FileCount > 0)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
/* get previous entry */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (pstrPrevName != NULL)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
if (*pFileIndex > 0)
|
|
fukasawa |
e60969 |
*pFileIndex -= 1;
|
|
fukasawa |
e60969 |
else
|
|
fukasawa |
e60969 |
*pFileIndex = FileCount - 1;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
strcpy (pstrPrevName, pFileList + (*pFileIndex * MAX_PATH));
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* get next entry */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (pstrNextName != NULL)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
if (*pFileIndex < FileCount - 1)
|
|
fukasawa |
e60969 |
*pFileIndex += 1;
|
|
fukasawa |
e60969 |
else
|
|
fukasawa |
e60969 |
*pFileIndex = 0;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
strcpy (pstrNextName, pFileList + (*pFileIndex * MAX_PATH));
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return TRUE;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
else
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
return FALSE;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/*-----------------
|
|
fukasawa |
e60969 |
* LoadImageFile
|
|
fukasawa |
e60969 |
*-----------------
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
BOOL LoadImageFile (HWND hwnd, PTSTR pstrPathName,
|
|
fukasawa |
e60969 |
png_byte **ppbImage, int *pxImgSize, int *pyImgSize,
|
|
fukasawa |
e60969 |
int *piChannels, png_color *pBkgColor)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
static TCHAR szTmp [MAX_PATH];
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* if there's an existing PNG, free the memory */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (*ppbImage)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
free (*ppbImage);
|
|
fukasawa |
e60969 |
*ppbImage = NULL;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* Load the entire PNG into memory */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
SetCursor (LoadCursor (NULL, IDC_WAIT));
|
|
fukasawa |
e60969 |
ShowCursor (TRUE);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
PngLoadImage (pstrPathName, ppbImage, pxImgSize, pyImgSize, piChannels,
|
|
fukasawa |
e60969 |
pBkgColor);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
ShowCursor (FALSE);
|
|
fukasawa |
e60969 |
SetCursor (LoadCursor (NULL, IDC_ARROW));
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (*ppbImage != NULL)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
sprintf (szTmp, "VisualPng - %s", strrchr(pstrPathName, '\\') + 1);
|
|
fukasawa |
e60969 |
SetWindowText (hwnd, szTmp);
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
else
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
MessageBox (hwnd, TEXT ("Error in loading the PNG image"),
|
|
fukasawa |
e60969 |
szProgName, MB_ICONEXCLAMATION | MB_OK);
|
|
fukasawa |
e60969 |
return FALSE;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return TRUE;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/*----------------
|
|
fukasawa |
e60969 |
* DisplayImage
|
|
fukasawa |
e60969 |
*----------------
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
BOOL DisplayImage (HWND hwnd, BYTE **ppDib,
|
|
fukasawa |
e60969 |
BYTE **ppDiData, int cxWinSize, int cyWinSize,
|
|
fukasawa |
e60969 |
BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
|
|
fukasawa |
e60969 |
BOOL bStretched)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
BYTE *pDib = *ppDib;
|
|
fukasawa |
e60969 |
BYTE *pDiData = *ppDiData;
|
|
fukasawa |
e60969 |
/* BITMAPFILEHEADER *pbmfh; */
|
|
fukasawa |
e60969 |
BITMAPINFOHEADER *pbmih;
|
|
fukasawa |
e60969 |
WORD wDIRowBytes;
|
|
fukasawa |
e60969 |
png_color bkgBlack = {0, 0, 0};
|
|
fukasawa |
e60969 |
png_color bkgGray = {127, 127, 127};
|
|
fukasawa |
e60969 |
png_color bkgWhite = {255, 255, 255};
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* allocate memory for the Device Independant bitmap */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
wDIRowBytes = (WORD) ((3 * cxWinSize + 3L) >> 2) << 2;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (pDib)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
free (pDib);
|
|
fukasawa |
e60969 |
pDib = NULL;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (!(pDib = (BYTE *) malloc (sizeof(BITMAPINFOHEADER) +
|
|
fukasawa |
e60969 |
wDIRowBytes * cyWinSize)))
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
MessageBox (hwnd, TEXT ("Error in displaying the PNG image"),
|
|
fukasawa |
e60969 |
szProgName, MB_ICONEXCLAMATION | MB_OK);
|
|
fukasawa |
e60969 |
*ppDib = pDib = NULL;
|
|
fukasawa |
e60969 |
return FALSE;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
*ppDib = pDib;
|
|
fukasawa |
e60969 |
memset (pDib, 0, sizeof(BITMAPINFOHEADER));
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* initialize the dib-structure */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
pbmih = (BITMAPINFOHEADER *) pDib;
|
|
fukasawa |
e60969 |
pbmih->biSize = sizeof(BITMAPINFOHEADER);
|
|
fukasawa |
e60969 |
pbmih->biWidth = cxWinSize;
|
|
fukasawa |
e60969 |
pbmih->biHeight = -((long) cyWinSize);
|
|
fukasawa |
e60969 |
pbmih->biPlanes = 1;
|
|
fukasawa |
e60969 |
pbmih->biBitCount = 24;
|
|
fukasawa |
e60969 |
pbmih->biCompression = 0;
|
|
fukasawa |
e60969 |
pDiData = pDib + sizeof(BITMAPINFOHEADER);
|
|
fukasawa |
e60969 |
*ppDiData = pDiData;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* first fill bitmap with gray and image border */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
InitBitmap (pDiData, cxWinSize, cyWinSize);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* then fill bitmap with image */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (pbImage)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
FillBitmap (
|
|
fukasawa |
e60969 |
pDiData, cxWinSize, cyWinSize,
|
|
fukasawa |
e60969 |
pbImage, cxImgSize, cyImgSize, cImgChannels,
|
|
fukasawa |
e60969 |
bStretched);
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return TRUE;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/*--------------
|
|
fukasawa |
e60969 |
* InitBitmap
|
|
fukasawa |
e60969 |
*--------------
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
BOOL InitBitmap (BYTE *pDiData, int cxWinSize, int cyWinSize)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
BYTE *dst;
|
|
fukasawa |
e60969 |
int x, y, col;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* initialize the background with gray */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
dst = pDiData;
|
|
fukasawa |
e60969 |
for (y = 0; y < cyWinSize; y++)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
col = 0;
|
|
fukasawa |
e60969 |
for (x = 0; x < cxWinSize; x++)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
/* fill with GRAY */
|
|
fukasawa |
e60969 |
*dst++ = 127;
|
|
fukasawa |
e60969 |
*dst++ = 127;
|
|
fukasawa |
e60969 |
*dst++ = 127;
|
|
fukasawa |
e60969 |
col += 3;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
/* rows start on 4 byte boundaries */
|
|
fukasawa |
e60969 |
while ((col % 4) != 0)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
dst++;
|
|
fukasawa |
e60969 |
col++;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return TRUE;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/*--------------
|
|
fukasawa |
e60969 |
* FillBitmap
|
|
fukasawa |
e60969 |
*--------------
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
BOOL FillBitmap (
|
|
fukasawa |
e60969 |
BYTE *pDiData, int cxWinSize, int cyWinSize,
|
|
fukasawa |
e60969 |
BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
|
|
fukasawa |
e60969 |
BOOL bStretched)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
BYTE *pStretchedImage;
|
|
fukasawa |
e60969 |
BYTE *pImg;
|
|
fukasawa |
e60969 |
BYTE *src, *dst;
|
|
fukasawa |
e60969 |
BYTE r, g, b, a;
|
|
fukasawa |
e60969 |
const int cDIChannels = 3;
|
|
fukasawa |
e60969 |
WORD wImgRowBytes;
|
|
fukasawa |
e60969 |
WORD wDIRowBytes;
|
|
fukasawa |
e60969 |
int cxNewSize, cyNewSize;
|
|
fukasawa |
e60969 |
int cxImgPos, cyImgPos;
|
|
fukasawa |
e60969 |
int xImg, yImg;
|
|
fukasawa |
e60969 |
int xWin, yWin;
|
|
fukasawa |
e60969 |
int xOld, yOld;
|
|
fukasawa |
e60969 |
int xNew, yNew;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (bStretched)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
cxNewSize = cxWinSize - 2 * MARGIN;
|
|
fukasawa |
e60969 |
cyNewSize = cyWinSize - 2 * MARGIN;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* stretch the image to it's window determined size */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* the following two are mathematically the same, but the first
|
|
fukasawa |
e60969 |
* has side-effects because of rounding
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
/* if ((cyNewSize / cxNewSize) > (cyImgSize / cxImgSize)) */
|
|
fukasawa |
e60969 |
if ((cyNewSize * cxImgSize) > (cyImgSize * cxNewSize))
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
cyNewSize = cxNewSize * cyImgSize / cxImgSize;
|
|
fukasawa |
e60969 |
cxImgPos = MARGIN;
|
|
fukasawa |
e60969 |
cyImgPos = (cyWinSize - cyNewSize) / 2;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
else
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
cxNewSize = cyNewSize * cxImgSize / cyImgSize;
|
|
fukasawa |
e60969 |
cyImgPos = MARGIN;
|
|
fukasawa |
e60969 |
cxImgPos = (cxWinSize - cxNewSize) / 2;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
pStretchedImage = malloc (cImgChannels * cxNewSize * cyNewSize);
|
|
fukasawa |
e60969 |
pImg = pStretchedImage;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
for (yNew = 0; yNew < cyNewSize; yNew++)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
yOld = yNew * cyImgSize / cyNewSize;
|
|
fukasawa |
e60969 |
for (xNew = 0; xNew < cxNewSize; xNew++)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
xOld = xNew * cxImgSize / cxNewSize;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
r = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 0);
|
|
fukasawa |
e60969 |
g = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 1);
|
|
fukasawa |
e60969 |
b = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 2);
|
|
fukasawa |
e60969 |
*pImg++ = r;
|
|
fukasawa |
e60969 |
*pImg++ = g;
|
|
fukasawa |
e60969 |
*pImg++ = b;
|
|
fukasawa |
e60969 |
if (cImgChannels == 4)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
a = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld)
|
|
fukasawa |
e60969 |
+ 3);
|
|
fukasawa |
e60969 |
*pImg++ = a;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* calculate row-bytes */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
wImgRowBytes = cImgChannels * cxNewSize;
|
|
fukasawa |
e60969 |
wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* copy image to screen */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
for (yImg = 0, yWin = cyImgPos; yImg < cyNewSize; yImg++, yWin++)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
if (yWin >= cyWinSize - cyImgPos)
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
src = pStretchedImage + yImg * wImgRowBytes;
|
|
fukasawa |
e60969 |
dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
for (xImg = 0, xWin = cxImgPos; xImg < cxNewSize; xImg++, xWin++)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
if (xWin >= cxWinSize - cxImgPos)
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
r = *src++;
|
|
fukasawa |
e60969 |
g = *src++;
|
|
fukasawa |
e60969 |
b = *src++;
|
|
fukasawa |
e60969 |
*dst++ = b; /* note the reverse order */
|
|
fukasawa |
e60969 |
*dst++ = g;
|
|
fukasawa |
e60969 |
*dst++ = r;
|
|
fukasawa |
e60969 |
if (cImgChannels == 4)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
a = *src++;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* free memory */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (pStretchedImage != NULL)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
free (pStretchedImage);
|
|
fukasawa |
e60969 |
pStretchedImage = NULL;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* process the image not-stretched */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
else
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
/* calculate the central position */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
cxImgPos = (cxWinSize - cxImgSize) / 2;
|
|
fukasawa |
e60969 |
cyImgPos = (cyWinSize - cyImgSize) / 2;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* check for image larger than window */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (cxImgPos < MARGIN)
|
|
fukasawa |
e60969 |
cxImgPos = MARGIN;
|
|
fukasawa |
e60969 |
if (cyImgPos < MARGIN)
|
|
fukasawa |
e60969 |
cyImgPos = MARGIN;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* calculate both row-bytes */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
wImgRowBytes = cImgChannels * cxImgSize;
|
|
fukasawa |
e60969 |
wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* copy image to screen */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
for (yImg = 0, yWin = cyImgPos; yImg < cyImgSize; yImg++, yWin++)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
if (yWin >= cyWinSize - MARGIN)
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
src = pbImage + yImg * wImgRowBytes;
|
|
fukasawa |
e60969 |
dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
for (xImg = 0, xWin = cxImgPos; xImg < cxImgSize; xImg++, xWin++)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
if (xWin >= cxWinSize - MARGIN)
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
r = *src++;
|
|
fukasawa |
e60969 |
g = *src++;
|
|
fukasawa |
e60969 |
b = *src++;
|
|
fukasawa |
e60969 |
*dst++ = b; /* note the reverse order */
|
|
fukasawa |
e60969 |
*dst++ = g;
|
|
fukasawa |
e60969 |
*dst++ = r;
|
|
fukasawa |
e60969 |
if (cImgChannels == 4)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
a = *src++;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return TRUE;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/*-----------------
|
|
fukasawa |
e60969 |
* end of source
|
|
fukasawa |
e60969 |
*-----------------
|
|
fukasawa |
e60969 |
*/
|