VirtualBox

source: vbox/trunk/src/libs/libpng-1.2.8/contrib/visupng/VisualPng.c@ 12130

最後變更 在這個檔案從12130是 6395,由 vboxsync 提交於 17 年 前

export libpng and zlib so Windows and OS/2 build cleanly.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette