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