~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to source/Irrlicht/libpng/contrib/visupng/VisualPng.c

  • Committer: Mantas Kriaučiūnas
  • Date: 2011-07-18 13:06:25 UTC
  • Revision ID: mantas@akl.lt-20110718130625-c5pvifp61e7kj1ol
Included whole irrlicht SVN libraries to work around launchpad recipe issue with quilt, see https://answers.launchpad.net/launchpad/+question/165193

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
60
BOOL InitBitmap (
 
61
        BYTE *pDiData, int cxWinSize, int cyWinSize);
 
62
 
 
63
BOOL FillBitmap (
 
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
 
 
429
BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message,
 
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
 
 
615
BOOL SearchPngList (
 
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
 
 
803
BOOL FillBitmap (
 
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
//-----------------