~ubuntu-branches/ubuntu/wily/ntop/wily-proposed

« back to all changes in this revision

Viewing changes to gdchart0.94c/gd-1.8.3/libpng-1.0.8/contrib/visupng/VisualPng.c

  • Committer: Bazaar Package Importer
  • Author(s): Dennis Schoen
  • Date: 2002-04-12 11:38:47 UTC
  • Revision ID: james.westby@ubuntu.com-20020412113847-4k4yydw0pzybc6g8
Tags: upstream-2.0.0
ImportĀ upstreamĀ versionĀ 2.0.0

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.  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
 
 
37
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
 
38
BOOL    CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ;
 
39
 
 
40
BOOL CenterAbout (HWND hwndChild, HWND hwndParent);
 
41
 
 
42
BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount,
 
43
        int *pFileIndex);
 
44
 
 
45
BOOL SearchPngList (TCHAR *pFileList, int FileCount, int *pFileIndex,
 
46
        PTSTR pstrPrevName, PTSTR pstrNextName);
 
47
 
 
48
BOOL LoadImageFile(HWND hwnd, PTSTR pstrPathName,
 
49
        png_byte **ppbImage, int *pxImgSize, int *pyImgSize, int *piChannels,
 
50
        png_color *pBkgColor);
 
51
 
 
52
BOOL 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
 
 
57
BOOL InitBitmap (
 
58
        BYTE *pDiData, int cxWinSize, int cyWinSize);
 
59
 
 
60
BOOL 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
 
 
67
static char *szProgName = PROGNAME;
 
68
static char *szAppName = LONGNAME;
 
69
static char *szIconName = PROGNAME;
 
70
static char szCmdFileName [MAX_PATH];
 
71
 
 
72
// MAIN routine
 
73
 
 
74
int 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
 
 
142
LRESULT 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
 
 
426
BOOL 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
 
 
454
BOOL 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
 
 
508
BOOL 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
 
 
612
BOOL 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
 
 
654
BOOL 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
 
 
698
BOOL 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
 
 
766
BOOL 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
 
 
800
BOOL 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
//-----------------