VisualPng.c
上传用户:sesekoo
上传日期:2020-07-18
资源大小:21543k
文件大小:26k
- //------------------------------------
- // VisualPng.C -- Shows a PNG image
- //------------------------------------
- // Copyright 2000, Willem van Schaik. For conditions of distribution and
- // use, see the copyright/license/disclaimer notice 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>
- // 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 != ' '))
- 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] != ' ')
- {
- 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) = ' ';
- 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 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
- //-----------------