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