Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
VisualPng.c
Go to the documentation of this file.
1 //------------------------------------
2 // VisualPng.C -- Shows a PNG image
3 //------------------------------------
4 
5 // Copyright 2000, Willem van Schaik.
6 
7 // This code is released under the libpng license.
8 // For conditions of distribution and use, see the disclaimer
9 // and license in png.h
10 
11 // switches
12 
13 // defines
14 
15 #define PROGNAME "VisualPng"
16 #define LONGNAME "Win32 Viewer for PNG-files"
17 #define VERSION "1.0 of 2000 June 07"
18 
19 // constants
20 
21 #define MARGIN 8
22 
23 // standard includes
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <windows.h>
29 
30 // application includes
31 
32 #include "png.h"
33 #include "pngfile.h"
34 #include "resource.h"
35 
36 // macros
37 
38 // function prototypes
39 
40 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
41 BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ;
42 
43 BOOL CenterAbout (HWND hwndChild, HWND hwndParent);
44 
45 BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount,
46  int *pFileIndex);
47 
48 BOOL SearchPngList (TCHAR *pFileList, int FileCount, int *pFileIndex,
49  PTSTR pstrPrevName, PTSTR pstrNextName);
50 
51 BOOL LoadImageFile(HWND hwnd, PTSTR pstrPathName,
52  png_byte **ppbImage, int *pxImgSize, int *pyImgSize, int *piChannels,
53  png_color *pBkgColor);
54 
55 BOOL DisplayImage (HWND hwnd, BYTE **ppDib,
56  BYTE **ppDiData, int cxWinSize, int cyWinSize,
57  BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
58  BOOL bStretched);
59 
61  BYTE *pDiData, int cxWinSize, int cyWinSize);
62 
64  BYTE *pDiData, int cxWinSize, int cyWinSize,
65  BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
66  BOOL bStretched);
67 
68 // a few global variables
69 
70 static char *szProgName = PROGNAME;
71 static char *szAppName = LONGNAME;
72 static char *szIconName = PROGNAME;
73 static char szCmdFileName [MAX_PATH];
74 
75 // MAIN routine
76 
77 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
78  PSTR szCmdLine, int iCmdShow)
79 {
80  HACCEL hAccel;
81  HWND hwnd;
82  MSG msg;
83  WNDCLASS wndclass;
84  int ixBorders, iyBorders;
85 
86  wndclass.style = CS_HREDRAW | CS_VREDRAW;
87  wndclass.lpfnWndProc = WndProc;
88  wndclass.cbClsExtra = 0;
89  wndclass.cbWndExtra = 0;
90  wndclass.hInstance = hInstance;
91  wndclass.hIcon = LoadIcon (hInstance, szIconName) ;
92  wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
93  wndclass.hbrBackground = NULL; // (HBRUSH) GetStockObject (GRAY_BRUSH);
94  wndclass.lpszMenuName = szProgName;
95  wndclass.lpszClassName = szProgName;
96 
97  if (!RegisterClass (&wndclass))
98  {
99  MessageBox (NULL, TEXT ("Error: this program requires Windows NT!"),
100  szProgName, MB_ICONERROR);
101  return 0;
102  }
103 
104  // if filename given on commandline, store it
105  if ((szCmdLine != NULL) && (*szCmdLine != '\0'))
106  if (szCmdLine[0] == '"')
107  strncpy (szCmdFileName, szCmdLine + 1, strlen(szCmdLine) - 2);
108  else
109  strcpy (szCmdFileName, szCmdLine);
110  else
111  strcpy (szCmdFileName, "");
112 
113  // calculate size of window-borders
114  ixBorders = 2 * (GetSystemMetrics (SM_CXBORDER) +
115  GetSystemMetrics (SM_CXDLGFRAME));
116  iyBorders = 2 * (GetSystemMetrics (SM_CYBORDER) +
117  GetSystemMetrics (SM_CYDLGFRAME)) +
118  GetSystemMetrics (SM_CYCAPTION) +
119  GetSystemMetrics (SM_CYMENUSIZE) +
120  1; /* WvS: don't ask me why? */
121 
122  hwnd = CreateWindow (szProgName, szAppName,
123  WS_OVERLAPPEDWINDOW,
124  CW_USEDEFAULT, CW_USEDEFAULT,
125  512 + 2 * MARGIN + ixBorders, 384 + 2 * MARGIN + iyBorders,
126 // CW_USEDEFAULT, CW_USEDEFAULT,
127  NULL, NULL, hInstance, NULL);
128 
129  ShowWindow (hwnd, iCmdShow);
130  UpdateWindow (hwnd);
131 
132  hAccel = LoadAccelerators (hInstance, szProgName);
133 
134  while (GetMessage (&msg, NULL, 0, 0))
135  {
136  if (!TranslateAccelerator (hwnd, hAccel, &msg))
137  {
138  TranslateMessage (&msg);
139  DispatchMessage (&msg);
140  }
141  }
142  return msg.wParam;
143 }
144 
145 LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,
146  LPARAM lParam)
147 {
148  static HINSTANCE hInstance ;
149  static HDC hdc;
150  static PAINTSTRUCT ps;
151  static HMENU hMenu;
152 
153  static BITMAPFILEHEADER *pbmfh;
154  static BITMAPINFOHEADER *pbmih;
155  static BYTE *pbImage;
156  static int cxWinSize, cyWinSize;
157  static int cxImgSize, cyImgSize;
158  static int cImgChannels;
159  static png_color bkgColor = {127, 127, 127};
160 
161  static BOOL bStretched = TRUE;
162 
163  static BYTE *pDib = NULL;
164  static BYTE *pDiData = NULL;
165 
166  static TCHAR szImgPathName [MAX_PATH];
167  static TCHAR szTitleName [MAX_PATH];
168 
169  static TCHAR *pPngFileList = NULL;
170  static int iPngFileCount;
171  static int iPngFileIndex;
172 
173  BOOL bOk;
174 
175  switch (message)
176  {
177  case WM_CREATE:
178  hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
179  PngFileInitialize (hwnd);
180 
181  strcpy (szImgPathName, "");
182 
183  // in case we process file given on command-line
184 
185  if (szCmdFileName[0] != '\0')
186  {
187  strcpy (szImgPathName, szCmdFileName);
188 
189  // read the other png-files in the directory for later
190  // next/previous commands
191 
192  BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount,
193  &iPngFileIndex);
194 
195  // load the image from file
196 
197  if (!LoadImageFile (hwnd, szImgPathName,
198  &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))
199  return 0;
200 
201  // invalidate the client area for later update
202 
203  InvalidateRect (hwnd, NULL, TRUE);
204 
205  // display the PNG into the DIBitmap
206 
207  DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
208  pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
209  }
210 
211  return 0;
212 
213  case WM_SIZE:
214  cxWinSize = LOWORD (lParam);
215  cyWinSize = HIWORD (lParam);
216 
217  // invalidate the client area for later update
218 
219  InvalidateRect (hwnd, NULL, TRUE);
220 
221  // display the PNG into the DIBitmap
222 
223  DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
224  pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
225 
226  return 0;
227 
228  case WM_INITMENUPOPUP:
229  hMenu = GetMenu (hwnd);
230 
231  if (pbImage)
232  EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_ENABLED);
233  else
234  EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_GRAYED);
235 
236  return 0;
237 
238  case WM_COMMAND:
239  hMenu = GetMenu (hwnd);
240 
241  switch (LOWORD (wParam))
242  {
243  case IDM_FILE_OPEN:
244 
245  // show the File Open dialog box
246 
247  if (!PngFileOpenDlg (hwnd, szImgPathName, szTitleName))
248  return 0;
249 
250  // read the other png-files in the directory for later
251  // next/previous commands
252 
253  BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount,
254  &iPngFileIndex);
255 
256  // load the image from file
257 
258  if (!LoadImageFile (hwnd, szImgPathName,
259  &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))
260  return 0;
261 
262  // invalidate the client area for later update
263 
264  InvalidateRect (hwnd, NULL, TRUE);
265 
266  // display the PNG into the DIBitmap
267 
268  DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
269  pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
270 
271  return 0;
272 
273  case IDM_FILE_SAVE:
274 
275  // show the File Save dialog box
276 
277  if (!PngFileSaveDlg (hwnd, szImgPathName, szTitleName))
278  return 0;
279 
280  // save the PNG to a disk file
281 
282  SetCursor (LoadCursor (NULL, IDC_WAIT));
283  ShowCursor (TRUE);
284 
285  bOk = PngSaveImage (szImgPathName, pDiData, cxWinSize, cyWinSize,
286  bkgColor);
287 
288  ShowCursor (FALSE);
289  SetCursor (LoadCursor (NULL, IDC_ARROW));
290 
291  if (!bOk)
292  MessageBox (hwnd, TEXT ("Error in saving the PNG image"),
293  szProgName, MB_ICONEXCLAMATION | MB_OK);
294  return 0;
295 
296  case IDM_FILE_NEXT:
297 
298  // read next entry in the directory
299 
300  if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex,
301  NULL, szImgPathName))
302  {
303  if (strcmp (szImgPathName, "") == 0)
304  return 0;
305 
306  // load the image from file
307 
308  if (!LoadImageFile (hwnd, szImgPathName, &pbImage,
309  &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))
310  return 0;
311 
312  // invalidate the client area for later update
313 
314  InvalidateRect (hwnd, NULL, TRUE);
315 
316  // display the PNG into the DIBitmap
317 
318  DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
319  pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
320  }
321 
322  return 0;
323 
324  case IDM_FILE_PREVIOUS:
325 
326  // read previous entry in the directory
327 
328  if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex,
329  szImgPathName, NULL))
330  {
331 
332  if (strcmp (szImgPathName, "") == 0)
333  return 0;
334 
335  // load the image from file
336 
337  if (!LoadImageFile (hwnd, szImgPathName, &pbImage, &cxImgSize,
338  &cyImgSize, &cImgChannels, &bkgColor))
339  return 0;
340 
341  // invalidate the client area for later update
342 
343  InvalidateRect (hwnd, NULL, TRUE);
344 
345  // display the PNG into the DIBitmap
346 
347  DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
348  pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
349  }
350 
351  return 0;
352 
353  case IDM_FILE_EXIT:
354 
355  // more cleanup needed...
356 
357  // free image buffer
358 
359  if (pDib != NULL)
360  {
361  free (pDib);
362  pDib = NULL;
363  }
364 
365  // free file-list
366 
367  if (pPngFileList != NULL)
368  {
369  free (pPngFileList);
370  pPngFileList = NULL;
371  }
372 
373  // let's go ...
374 
375  exit (0);
376 
377  return 0;
378 
379  case IDM_OPTIONS_STRETCH:
380  bStretched = !bStretched;
381  if (bStretched)
382  CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_CHECKED);
383  else
384  CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_UNCHECKED);
385 
386  // invalidate the client area for later update
387 
388  InvalidateRect (hwnd, NULL, TRUE);
389 
390  // display the PNG into the DIBitmap
391 
392  DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
393  pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
394 
395  return 0;
396 
397  case IDM_HELP_ABOUT:
398  DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc) ;
399  return 0;
400 
401  } // end switch
402 
403  break;
404 
405  case WM_PAINT:
406  hdc = BeginPaint (hwnd, &ps);
407 
408  if (pDib)
409  SetDIBitsToDevice (hdc, 0, 0, cxWinSize, cyWinSize, 0, 0,
410  0, cyWinSize, pDiData, (BITMAPINFO *) pDib, DIB_RGB_COLORS);
411 
412  EndPaint (hwnd, &ps);
413  return 0;
414 
415  case WM_DESTROY:
416  if (pbmfh)
417  {
418  free (pbmfh);
419  pbmfh = NULL;
420  }
421 
422  PostQuitMessage (0);
423  return 0;
424  }
425 
426  return DefWindowProc (hwnd, message, wParam, lParam);
427 }
428 
430  WPARAM wParam, LPARAM lParam)
431 {
432  switch (message)
433  {
434  case WM_INITDIALOG :
435  ShowWindow (hDlg, SW_HIDE);
436  CenterAbout (hDlg, GetWindow (hDlg, GW_OWNER));
437  ShowWindow (hDlg, SW_SHOW);
438  return TRUE ;
439 
440  case WM_COMMAND :
441  switch (LOWORD (wParam))
442  {
443  case IDOK :
444  case IDCANCEL :
445  EndDialog (hDlg, 0) ;
446  return TRUE ;
447  }
448  break ;
449  }
450  return FALSE ;
451 }
452 
453 //---------------
454 // CenterAbout
455 //---------------
456 
457 BOOL CenterAbout (HWND hwndChild, HWND hwndParent)
458 {
459  RECT rChild, rParent, rWorkArea;
460  int wChild, hChild, wParent, hParent;
461  int xNew, yNew;
462  BOOL bResult;
463 
464  // Get the Height and Width of the child window
465  GetWindowRect (hwndChild, &rChild);
466  wChild = rChild.right - rChild.left;
467  hChild = rChild.bottom - rChild.top;
468 
469  // Get the Height and Width of the parent window
470  GetWindowRect (hwndParent, &rParent);
471  wParent = rParent.right - rParent.left;
472  hParent = rParent.bottom - rParent.top;
473 
474  // Get the limits of the 'workarea'
475  bResult = SystemParametersInfo(
476  SPI_GETWORKAREA, // system parameter to query or set
477  sizeof(RECT),
478  &rWorkArea,
479  0);
480  if (!bResult) {
481  rWorkArea.left = rWorkArea.top = 0;
482  rWorkArea.right = GetSystemMetrics(SM_CXSCREEN);
483  rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN);
484  }
485 
486  // Calculate new X position, then adjust for workarea
487  xNew = rParent.left + ((wParent - wChild) /2);
488  if (xNew < rWorkArea.left) {
489  xNew = rWorkArea.left;
490  } else if ((xNew+wChild) > rWorkArea.right) {
491  xNew = rWorkArea.right - wChild;
492  }
493 
494  // Calculate new Y position, then adjust for workarea
495  yNew = rParent.top + ((hParent - hChild) /2);
496  if (yNew < rWorkArea.top) {
497  yNew = rWorkArea.top;
498  } else if ((yNew+hChild) > rWorkArea.bottom) {
499  yNew = rWorkArea.bottom - hChild;
500  }
501 
502  // Set it, and return
503  return SetWindowPos (hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE |
504  SWP_NOZORDER);
505 }
506 
507 //----------------
508 // BuildPngList
509 //----------------
510 
511 BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount,
512  int *pFileIndex)
513 {
514  static TCHAR szImgPathName [MAX_PATH];
515  static TCHAR szImgFileName [MAX_PATH];
516  static TCHAR szImgFindName [MAX_PATH];
517 
518  WIN32_FIND_DATA finddata;
519  HANDLE hFind;
520 
521  static TCHAR szTmp [MAX_PATH];
522  BOOL bOk;
523  int i, ii;
524  int j, jj;
525 
526  // free previous file-list
527 
528  if (*ppFileList != NULL)
529  {
530  free (*ppFileList);
531  *ppFileList = NULL;
532  }
533 
534  // extract foldername, filename and search-name
535 
536  strcpy (szImgPathName, pstrPathName);
537  strcpy (szImgFileName, strrchr (pstrPathName, '\\') + 1);
538 
539  strcpy (szImgFindName, szImgPathName);
540  *(strrchr (szImgFindName, '\\') + 1) = '\0';
541  strcat (szImgFindName, "*.png");
542 
543  // first cycle: count number of files in directory for memory allocation
544 
545  *pFileCount = 0;
546 
547  hFind = FindFirstFile(szImgFindName, &finddata);
548  bOk = (hFind != (HANDLE) -1);
549 
550  while (bOk)
551  {
552  *pFileCount += 1;
553  bOk = FindNextFile(hFind, &finddata);
554  }
555  FindClose(hFind);
556 
557  // allocation memory for file-list
558 
559  *ppFileList = (TCHAR *) malloc (*pFileCount * MAX_PATH);
560 
561  // second cycle: read directory and store filenames in file-list
562 
563  hFind = FindFirstFile(szImgFindName, &finddata);
564  bOk = (hFind != (HANDLE) -1);
565 
566  i = 0;
567  ii = 0;
568  while (bOk)
569  {
570  strcpy (*ppFileList + ii, szImgPathName);
571  strcpy (strrchr(*ppFileList + ii, '\\') + 1, finddata.cFileName);
572 
573  if (strcmp(pstrPathName, *ppFileList + ii) == 0)
574  *pFileIndex = i;
575 
576  ii += MAX_PATH;
577  i++;
578 
579  bOk = FindNextFile(hFind, &finddata);
580  }
581  FindClose(hFind);
582 
583  // finally we must sort the file-list
584 
585  for (i = 0; i < *pFileCount - 1; i++)
586  {
587  ii = i * MAX_PATH;
588  for (j = i+1; j < *pFileCount; j++)
589  {
590  jj = j * MAX_PATH;
591  if (strcmp (*ppFileList + ii, *ppFileList + jj) > 0)
592  {
593  strcpy (szTmp, *ppFileList + jj);
594  strcpy (*ppFileList + jj, *ppFileList + ii);
595  strcpy (*ppFileList + ii, szTmp);
596 
597  // check if this was the current image that we moved
598 
599  if (*pFileIndex == i)
600  *pFileIndex = j;
601  else
602  if (*pFileIndex == j)
603  *pFileIndex = i;
604  }
605  }
606  }
607 
608  return TRUE;
609 }
610 
611 //----------------
612 // SearchPngList
613 //----------------
614 
616  TCHAR *pFileList, int FileCount, int *pFileIndex,
617  PTSTR pstrPrevName, PTSTR pstrNextName)
618 {
619  if (FileCount > 0)
620  {
621  // get previous entry
622 
623  if (pstrPrevName != NULL)
624  {
625  if (*pFileIndex > 0)
626  *pFileIndex -= 1;
627  else
628  *pFileIndex = FileCount - 1;
629 
630  strcpy (pstrPrevName, pFileList + (*pFileIndex * MAX_PATH));
631  }
632 
633  // get next entry
634 
635  if (pstrNextName != NULL)
636  {
637  if (*pFileIndex < FileCount - 1)
638  *pFileIndex += 1;
639  else
640  *pFileIndex = 0;
641 
642  strcpy (pstrNextName, pFileList + (*pFileIndex * MAX_PATH));
643  }
644 
645  return TRUE;
646  }
647  else
648  {
649  return FALSE;
650  }
651 }
652 
653 //-----------------
654 // LoadImageFile
655 //-----------------
656 
657 BOOL LoadImageFile (HWND hwnd, PTSTR pstrPathName,
658  png_byte **ppbImage, int *pxImgSize, int *pyImgSize,
659  int *piChannels, png_color *pBkgColor)
660 {
661  static TCHAR szTmp [MAX_PATH];
662 
663  // if there's an existing PNG, free the memory
664 
665  if (*ppbImage)
666  {
667  free (*ppbImage);
668  *ppbImage = NULL;
669  }
670 
671  // Load the entire PNG into memory
672 
673  SetCursor (LoadCursor (NULL, IDC_WAIT));
674  ShowCursor (TRUE);
675 
676  PngLoadImage (pstrPathName, ppbImage, pxImgSize, pyImgSize, piChannels,
677  pBkgColor);
678 
679  ShowCursor (FALSE);
680  SetCursor (LoadCursor (NULL, IDC_ARROW));
681 
682  if (*ppbImage != NULL)
683  {
684  sprintf (szTmp, "VisualPng - %s", strrchr(pstrPathName, '\\') + 1);
685  SetWindowText (hwnd, szTmp);
686  }
687  else
688  {
689  MessageBox (hwnd, TEXT ("Error in loading the PNG image"),
690  szProgName, MB_ICONEXCLAMATION | MB_OK);
691  return FALSE;
692  }
693 
694  return TRUE;
695 }
696 
697 //----------------
698 // DisplayImage
699 //----------------
700 
701 BOOL DisplayImage (HWND hwnd, BYTE **ppDib,
702  BYTE **ppDiData, int cxWinSize, int cyWinSize,
703  BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
704  BOOL bStretched)
705 {
706  BYTE *pDib = *ppDib;
707  BYTE *pDiData = *ppDiData;
708  // BITMAPFILEHEADER *pbmfh;
709  BITMAPINFOHEADER *pbmih;
710  WORD wDIRowBytes;
711  png_color bkgBlack = {0, 0, 0};
712  png_color bkgGray = {127, 127, 127};
713  png_color bkgWhite = {255, 255, 255};
714 
715  // allocate memory for the Device Independant bitmap
716 
717  wDIRowBytes = (WORD) ((3 * cxWinSize + 3L) >> 2) << 2;
718 
719  if (pDib)
720  {
721  free (pDib);
722  pDib = NULL;
723  }
724 
725  if (!(pDib = (BYTE *) malloc (sizeof(BITMAPINFOHEADER) +
726  wDIRowBytes * cyWinSize)))
727  {
728  MessageBox (hwnd, TEXT ("Error in displaying the PNG image"),
729  szProgName, MB_ICONEXCLAMATION | MB_OK);
730  *ppDib = pDib = NULL;
731  return FALSE;
732  }
733  *ppDib = pDib;
734  memset (pDib, 0, sizeof(BITMAPINFOHEADER));
735 
736  // initialize the dib-structure
737 
738  pbmih = (BITMAPINFOHEADER *) pDib;
739  pbmih->biSize = sizeof(BITMAPINFOHEADER);
740  pbmih->biWidth = cxWinSize;
741  pbmih->biHeight = -((long) cyWinSize);
742  pbmih->biPlanes = 1;
743  pbmih->biBitCount = 24;
744  pbmih->biCompression = 0;
745  pDiData = pDib + sizeof(BITMAPINFOHEADER);
746  *ppDiData = pDiData;
747 
748  // first fill bitmap with gray and image border
749 
750  InitBitmap (pDiData, cxWinSize, cyWinSize);
751 
752  // then fill bitmap with image
753 
754  if (pbImage)
755  {
756  FillBitmap (
757  pDiData, cxWinSize, cyWinSize,
758  pbImage, cxImgSize, cyImgSize, cImgChannels,
759  bStretched);
760  }
761 
762  return TRUE;
763 }
764 
765 //--------------
766 // InitBitmap
767 //--------------
768 
769 BOOL InitBitmap (BYTE *pDiData, int cxWinSize, int cyWinSize)
770 {
771  BYTE *dst;
772  int x, y, col;
773 
774  // initialize the background with gray
775 
776  dst = pDiData;
777  for (y = 0; y < cyWinSize; y++)
778  {
779  col = 0;
780  for (x = 0; x < cxWinSize; x++)
781  {
782  // fill with GRAY
783  *dst++ = 127;
784  *dst++ = 127;
785  *dst++ = 127;
786  col += 3;
787  }
788  // rows start on 4 byte boundaries
789  while ((col % 4) != 0)
790  {
791  dst++;
792  col++;
793  }
794  }
795 
796  return TRUE;
797 }
798 
799 //--------------
800 // FillBitmap
801 //--------------
802 
804  BYTE *pDiData, int cxWinSize, int cyWinSize,
805  BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
806  BOOL bStretched)
807 {
808  BYTE *pStretchedImage;
809  BYTE *pImg;
810  BYTE *src, *dst;
811  BYTE r, g, b, a;
812  const int cDIChannels = 3;
813  WORD wImgRowBytes;
814  WORD wDIRowBytes;
815  int cxNewSize, cyNewSize;
816  int cxImgPos, cyImgPos;
817  int xImg, yImg;
818  int xWin, yWin;
819  int xOld, yOld;
820  int xNew, yNew;
821 
822  if (bStretched)
823  {
824  cxNewSize = cxWinSize - 2 * MARGIN;
825  cyNewSize = cyWinSize - 2 * MARGIN;
826 
827  // stretch the image to it's window determined size
828 
829  // the following two are the same, but the first has side-effects
830  // because of rounding
831 // if ((cyNewSize / cxNewSize) > (cyImgSize / cxImgSize))
832  if ((cyNewSize * cxImgSize) > (cyImgSize * cxNewSize))
833  {
834  cyNewSize = cxNewSize * cyImgSize / cxImgSize;
835  cxImgPos = MARGIN;
836  cyImgPos = (cyWinSize - cyNewSize) / 2;
837  }
838  else
839  {
840  cxNewSize = cyNewSize * cxImgSize / cyImgSize;
841  cyImgPos = MARGIN;
842  cxImgPos = (cxWinSize - cxNewSize) / 2;
843  }
844 
845  pStretchedImage = malloc (cImgChannels * cxNewSize * cyNewSize);
846  pImg = pStretchedImage;
847 
848  for (yNew = 0; yNew < cyNewSize; yNew++)
849  {
850  yOld = yNew * cyImgSize / cyNewSize;
851  for (xNew = 0; xNew < cxNewSize; xNew++)
852  {
853  xOld = xNew * cxImgSize / cxNewSize;
854 
855  r = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 0);
856  g = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 1);
857  b = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 2);
858  *pImg++ = r;
859  *pImg++ = g;
860  *pImg++ = b;
861  if (cImgChannels == 4)
862  {
863  a = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld)
864  + 3);
865  *pImg++ = a;
866  }
867  }
868  }
869 
870  // calculate row-bytes
871 
872  wImgRowBytes = cImgChannels * cxNewSize;
873  wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2;
874 
875  // copy image to screen
876 
877  for (yImg = 0, yWin = cyImgPos; yImg < cyNewSize; yImg++, yWin++)
878  {
879  if (yWin >= cyWinSize - cyImgPos)
880  break;
881  src = pStretchedImage + yImg * wImgRowBytes;
882  dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels;
883 
884  for (xImg = 0, xWin = cxImgPos; xImg < cxNewSize; xImg++, xWin++)
885  {
886  if (xWin >= cxWinSize - cxImgPos)
887  break;
888  r = *src++;
889  g = *src++;
890  b = *src++;
891  *dst++ = b; /* note the reverse order */
892  *dst++ = g;
893  *dst++ = r;
894  if (cImgChannels == 4)
895  {
896  a = *src++;
897  }
898  }
899  }
900 
901  // free memory
902 
903  if (pStretchedImage != NULL)
904  {
905  free (pStretchedImage);
906  pStretchedImage = NULL;
907  }
908 
909  }
910 
911  // process the image not-stretched
912 
913  else
914  {
915  // calculate the central position
916 
917  cxImgPos = (cxWinSize - cxImgSize) / 2;
918  cyImgPos = (cyWinSize - cyImgSize) / 2;
919 
920  // check for image larger than window
921 
922  if (cxImgPos < MARGIN)
923  cxImgPos = MARGIN;
924  if (cyImgPos < MARGIN)
925  cyImgPos = MARGIN;
926 
927  // calculate both row-bytes
928 
929  wImgRowBytes = cImgChannels * cxImgSize;
930  wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2;
931 
932  // copy image to screen
933 
934  for (yImg = 0, yWin = cyImgPos; yImg < cyImgSize; yImg++, yWin++)
935  {
936  if (yWin >= cyWinSize - MARGIN)
937  break;
938  src = pbImage + yImg * wImgRowBytes;
939  dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels;
940 
941  for (xImg = 0, xWin = cxImgPos; xImg < cxImgSize; xImg++, xWin++)
942  {
943  if (xWin >= cxWinSize - MARGIN)
944  break;
945  r = *src++;
946  g = *src++;
947  b = *src++;
948  *dst++ = b; /* note the reverse order */
949  *dst++ = g;
950  *dst++ = r;
951  if (cImgChannels == 4)
952  {
953  a = *src++;
954  }
955  }
956  }
957  }
958 
959  return TRUE;
960 }
961 
962 //-----------------
963 // end of source
964 //-----------------
GLboolean GLboolean GLboolean GLboolean a
BOOL BuildPngList(PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount, int *pFileIndex)
Definition: VisualPng.c:511
#define NULL
Definition: ftobjs.h:61
GLint GLint GLint GLint GLint GLint y
BOOL PngFileOpenDlg(HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
Definition: PngFile.c:75
void PngFileInitialize(HWND hwnd)
Definition: PngFile.c:48
#define PROGNAME
Definition: VisualPng.c:15
BOOL LoadImageFile(HWND hwnd, PTSTR pstrPathName, png_byte **ppbImage, int *pxImgSize, int *pyImgSize, int *piChannels, png_color *pBkgColor)
Definition: VisualPng.c:657
#define IDM_FILE_EXIT
Definition: resource.h:9
char * malloc()
BOOL SearchPngList(TCHAR *pFileList, int FileCount, int *pFileIndex, PTSTR pstrPrevName, PTSTR pstrNextName)
Definition: VisualPng.c:615
#define IDM_FILE_NEXT
Definition: resource.h:7
GLint GLint GLint GLint GLint x
GLboolean GLboolean GLboolean b
BOOL FillBitmap(BYTE *pDiData, int cxWinSize, int cyWinSize, BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels, BOOL bStretched)
Definition: VisualPng.c:803
png_uint_32 i
Definition: png.h:2640
BOOL PngFileSaveDlg(HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
Definition: PngFile.c:85
#define IDM_FILE_PREVIOUS
Definition: resource.h:8
#define BOOL
Definition: png2pnm.c:23
#define MARGIN
Definition: VisualPng.c:21
#define IDM_FILE_OPEN
Definition: resource.h:5
GLenum GLenum dst
BOOL CenterAbout(HWND hwndChild, HWND hwndParent)
Definition: VisualPng.c:457
#define IDM_HELP_ABOUT
Definition: resource.h:12
unsigned char png_byte
Definition: pngconf.h:1251
GLdouble GLdouble GLdouble r
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
int free()
GLenum src
#define LONGNAME
Definition: VisualPng.c:16
#define FALSE
Definition: ftobjs.h:57
#define IDM_FILE_SAVE
Definition: resource.h:6
#define CALLBACK
Definition: Tessellator.hpp:41
BOOL InitBitmap(BYTE *pDiData, int cxWinSize, int cyWinSize)
Definition: VisualPng.c:769
GLenum GLuint GLenum GLsizei const GLchar * message
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
Definition: VisualPng.c:77
BOOL PngLoadImage(PTSTR pstrFileName, png_byte **ppbImageData, int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor)
Definition: PngFile.c:97
GLboolean GLboolean g
BOOL CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM)
Definition: VisualPng.c:429
BOOL DisplayImage(HWND hwnd, BYTE **ppDib, BYTE **ppDiData, int cxWinSize, int cyWinSize, BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels, BOOL bStretched)
Definition: VisualPng.c:701
#define IDM_OPTIONS_STRETCH
Definition: resource.h:11
#define TRUE
Definition: ftobjs.h:53
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM)
Definition: VisualPng.c:145
BOOL PngSaveImage(PTSTR pstrFileName, png_byte *pDiData, int iWidth, int iHeight, png_color bkgColor)
Definition: PngFile.c:287
png_const_charp msg
Definition: PngFile.c:23