Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3511 lines
94 KiB

  1. //
  2. // Sample code for using GDI+
  3. //
  4. // Revision History:
  5. //
  6. // 10/01/1999 Min Liu (minliu)
  7. // Created it.
  8. //
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <stdarg.h>
  12. #include <windows.h>
  13. #include <commctrl.h>
  14. #include <objbase.h>
  15. #include <commdlg.h>
  16. #include <initguid.h>
  17. #include "imaging.h"
  18. #include <gdiplus.h>
  19. #include <gdiplusflat.h>
  20. #include "frametest.h"
  21. using namespace Gdiplus;
  22. #include "../gpinit.inc"
  23. #define MYWNDCLASSNAME "FrameTest"
  24. #define K_DEFAULT_X 0
  25. #define K_DEFAULT_Y 0
  26. #define K_DEFAULT_WIDTH 300
  27. #define K_DEFAULT_HEIGHT 300
  28. #define MAX_FILENAME_LENGTH 1024
  29. #define K_DEFAULT_DELAY 20
  30. CHAR* g_pcAppName; // Application name
  31. HINSTANCE g_hAppInstance; // Handle of the app instance
  32. CHAR g_acImageName[MAX_PATH];// Current image filename
  33. INT g_iCurrentPageIndex; // Current page/frame index (0 base)
  34. UINT g_uiTotalPages = 0; // Total pages in current image
  35. HWND g_hwndMain; // Handle to app's main window
  36. HWND g_hwndStatus; // Handle to status window
  37. HWND g_hwndDecoderDlg; // Handle to set color key dialog
  38. HWND g_hwndColorMapDlg; // Handle to set color map dialog
  39. HWND g_hwndAnnotationDlg; // Handle to annotation dialog
  40. HWND g_hwndJpegSaveDlg; // Handle to JPEG save dialog
  41. HWND g_hwndTiffSaveDlg; // Handle to TIFF save dialog
  42. EncoderParameters* g_pEncoderParams = NULL;// Encoder parameters
  43. //
  44. // User preferred window size and initial position
  45. //
  46. INT g_iWinWidth = K_DEFAULT_WIDTH;
  47. INT g_iWinHeight = K_DEFAULT_HEIGHT;
  48. INT g_iWinX = K_DEFAULT_X;
  49. INT g_iWinY = K_DEFAULT_Y;
  50. //
  51. // Image info
  52. //
  53. UINT g_ImageWidth; // Image width
  54. UINT g_ImageHeight; // Image height
  55. UINT g_ImageFlags; // Image flag
  56. PixelFormat g_ImagePixelFormat; // Image pixel format
  57. double g_ImageXDpi; // DPI info in X
  58. double g_ImageYDpi; // DPI info in Y
  59. GUID g_ImageRawDataFormat; // RAW data format
  60. UINT g_uiDelay = K_DEFAULT_DELAY;
  61. // Delay between frames for anima.
  62. Image* g_pImage = NULL; // Pointer to current Image object
  63. ImageAttributes* g_pDrawAttrib = NULL; // Pointer to draw attributes
  64. PointF* g_pDestPoints = NULL; // Transformation points
  65. INT g_DestPointCount = 0; // number of transformation points
  66. REAL g_SourceX = NULL; // current image X offset
  67. REAL g_SourceY = NULL; // current image Y offset
  68. REAL g_SourceWidth = NULL; // current image width
  69. REAL g_SourceHeight = NULL; // current image height
  70. BOOL g_LoadImageWithICM = TRUE;
  71. // Flag for loading image with ICM
  72. // convertion or not
  73. BOOL g_bRotated = FALSE;
  74. REAL g_dScale = 1;
  75. BOOL g_fFitToWindow_w = FALSE;
  76. BOOL g_fFitToWindow_h = FALSE;
  77. InterpolationMode g_InterpolationMode = InterpolationModeHighQualityBicubic;
  78. WrapMode g_WrapMode = WrapModeTileFlipXY;
  79. void
  80. ValidateArguments(int argc,
  81. char* argv[])
  82. {
  83. g_pcAppName = *argv++;
  84. argc--;
  85. while ( argc > 0 )
  86. {
  87. if ( strcmp(*argv, "-w") == 0 )
  88. {
  89. argc--;
  90. argv++;
  91. if ( argc == 0 )
  92. {
  93. // Not enough parameters
  94. USAGE();
  95. exit(1);
  96. }
  97. g_iWinWidth = atoi(*argv++);
  98. argc--;
  99. }
  100. else if ( strcmp(*argv, "-h") == 0 )
  101. {
  102. argc--;
  103. argv++;
  104. if ( argc == 0 )
  105. {
  106. // Not enough parameters
  107. USAGE();
  108. exit(1);
  109. }
  110. g_iWinHeight = atoi(*argv++);
  111. argc--;
  112. }
  113. else if ( strcmp(*argv, "-x") == 0 )
  114. {
  115. argc--;
  116. argv++;
  117. if ( argc == 0 )
  118. {
  119. // Not enough parameters
  120. USAGE();
  121. exit(1);
  122. }
  123. g_iWinX = atoi(*argv++);
  124. argc--;
  125. }
  126. else if ( strcmp(*argv, "-y") == 0 )
  127. {
  128. argc--;
  129. argv++;
  130. if ( argc == 0 )
  131. {
  132. // Not enough parameters
  133. USAGE();
  134. exit(1);
  135. }
  136. g_iWinY = atoi(*argv++);
  137. argc--;
  138. }
  139. else if ( strcmp(*argv, "-?") == 0 )
  140. {
  141. USAGE();
  142. exit(1);
  143. }
  144. else
  145. {
  146. // Get the image name
  147. strcpy(g_acImageName, *argv++);
  148. VERBOSE(("Image file name %s\n",g_acImageName));
  149. argc--;
  150. }
  151. }// while ( argc > 0 )
  152. }// ValidateArguments()
  153. // Update image info
  154. BOOL
  155. UpdateImageInfo()
  156. {
  157. SizeF sizeF;
  158. g_ImageWidth = g_pImage->GetWidth();
  159. g_ImageHeight = g_pImage->GetHeight();
  160. g_ImageXDpi = g_pImage->GetVerticalResolution();
  161. g_ImageYDpi = g_pImage->GetHorizontalResolution();
  162. g_ImagePixelFormat = g_pImage->GetPixelFormat();
  163. g_ImageFlags = g_pImage->GetFlags();
  164. g_pImage->GetRawFormat(&g_ImageRawDataFormat);
  165. return TRUE;
  166. }// UpdateImageInfo()
  167. //
  168. // Force a refresh of the image window
  169. //
  170. inline VOID
  171. RefreshImageDisplay()
  172. {
  173. SendMessage(g_hwndMain, WM_ERASEBKGND, WPARAM(GetDC(g_hwndMain)), NULL);
  174. InvalidateRect(g_hwndMain, NULL, FALSE);
  175. // Update window title
  176. CHAR title[2 * MAX_PATH];
  177. CHAR* p = title;
  178. CHAR myChar = '%';
  179. sprintf(p, "(%d%c) Page %d of image %s", (INT)(g_dScale * 100), myChar,
  180. g_iCurrentPageIndex + 1, g_acImageName);
  181. SetWindowText(g_hwndMain, title);
  182. }// RefreshImageDisplay()
  183. inline void
  184. ResetImageAttribute()
  185. {
  186. if ( g_pDrawAttrib != NULL )
  187. {
  188. delete g_pDrawAttrib;
  189. g_pDrawAttrib = NULL;
  190. }
  191. g_pDrawAttrib = new ImageAttributes();
  192. g_pDrawAttrib->SetWrapMode(g_WrapMode, Color(0), FALSE);
  193. }// ResetImageAttribute()
  194. //
  195. // Sets up the current page for decompressing in a multi-page image
  196. //
  197. VOID
  198. SetCurrentPage()
  199. {
  200. // QueryFrame dimension info
  201. UINT uiDimCount = g_pImage->GetFrameDimensionsCount();
  202. GUID* pMyGuid = (GUID*)malloc(uiDimCount * sizeof(GUID));
  203. if ( pMyGuid == NULL )
  204. {
  205. return;
  206. }
  207. Status rCode = g_pImage->GetFrameDimensionsList(pMyGuid, uiDimCount);
  208. if ( (rCode != Ok) && (rCode != NotImplemented) )
  209. {
  210. return;
  211. }
  212. // Set current frame
  213. rCode = g_pImage->SelectActiveFrame(pMyGuid, g_iCurrentPageIndex);
  214. if ( (rCode != Ok) && (rCode != NotImplemented) )
  215. {
  216. VERBOSE(("SelectActiveFrame() failed\n"));
  217. free(pMyGuid);
  218. return;
  219. }
  220. free(pMyGuid);
  221. // Get image info for current frame
  222. if ( UpdateImageInfo() == FALSE )
  223. {
  224. VERBOSE(("UpdateImageInfo() failed\n"));
  225. return;
  226. }
  227. // Check if we need to set 'Fit window width"
  228. // We will do a fit to window iff the "Scale factor is not set" and "Image
  229. // is bigger than current window"
  230. HMENU hMenu = GetMenu(g_hwndMain);
  231. if ( ((INT)g_ImageWidth > g_iWinWidth)
  232. ||((INT)g_ImageHeight > g_iWinHeight) )
  233. {
  234. g_fFitToWindow_w = TRUE;
  235. g_dScale = (REAL)g_iWinWidth / g_ImageWidth;
  236. CheckMenuItem(hMenu, IDM_VIEW_ZOOM_FITWINDOW_W,
  237. MF_BYCOMMAND | MF_CHECKED);
  238. }
  239. else
  240. {
  241. g_dScale = 1;
  242. g_fFitToWindow_w = FALSE;
  243. g_fFitToWindow_h = FALSE;
  244. CheckMenuItem(hMenu, IDM_VIEW_ZOOM_FITWINDOW_W,
  245. MF_BYCOMMAND | MF_UNCHECKED);
  246. CheckMenuItem(hMenu, IDM_VIEW_ZOOM_FITWINDOW_H,
  247. MF_BYCOMMAND | MF_UNCHECKED);
  248. }
  249. RefreshImageDisplay();
  250. }// SetCurrentPage()
  251. //
  252. // Create an image object from a file
  253. //
  254. BOOL
  255. OpenImageFile(
  256. const CHAR* filename
  257. )
  258. {
  259. if ( (NULL == filename) || (strlen(filename) < 1) )
  260. {
  261. return FALSE;
  262. }
  263. // We need to free the previous image resource and clean the draw attrib
  264. if ( g_pImage != NULL )
  265. {
  266. delete g_pImage;
  267. }
  268. ResetImageAttribute();
  269. if ( g_pDestPoints != NULL )
  270. {
  271. delete g_pDestPoints;
  272. g_pDestPoints = NULL;
  273. }
  274. // Convert filename to a WCHAR
  275. WCHAR namestr[MAX_FILENAME_LENGTH];
  276. if ( !AnsiToUnicodeStr(filename, namestr, MAX_FILENAME_LENGTH) )
  277. {
  278. VERBOSE(("OpenImageFile:Convert %s to a WCHAR failed\n", filename));
  279. return FALSE;
  280. }
  281. if ( g_LoadImageWithICM == TRUE )
  282. {
  283. g_pImage = new Image(namestr, g_LoadImageWithICM);
  284. }
  285. else
  286. {
  287. g_pImage = new Image(namestr);
  288. }
  289. UINT uiDimCount = g_pImage->GetFrameDimensionsCount();
  290. GUID* pMyGuid = (GUID*)malloc(uiDimCount * sizeof(GUID));
  291. if ( pMyGuid == NULL )
  292. {
  293. return FALSE;
  294. }
  295. Status rCode = g_pImage->GetFrameDimensionsList(pMyGuid, uiDimCount);
  296. if ( (rCode != Ok) && (rCode != NotImplemented) )
  297. {
  298. return FALSE;
  299. }
  300. // Get total number of pages in this image
  301. // !!!Todo need a for() loop here
  302. g_uiTotalPages = g_pImage->GetFrameCount(pMyGuid);
  303. if ( g_uiTotalPages == 0 )
  304. {
  305. // If the decoder doesn't support frame count query, we can just
  306. // assume it has only 1 image. For example, gif decoder will fail
  307. // if the query GUID is FRAMEDIM_PAGE
  308. g_uiTotalPages = 1;
  309. }
  310. g_iCurrentPageIndex = 0;
  311. if ( pMyGuid != NULL )
  312. {
  313. free(pMyGuid);
  314. }
  315. SetCurrentPage();
  316. return TRUE;
  317. }// OpenImageFile()
  318. //
  319. // Open image file
  320. //
  321. VOID
  322. DoOpen(
  323. HWND hwnd
  324. )
  325. {
  326. OPENFILENAME ofn;
  327. ZeroMemory(&ofn, sizeof(ofn));
  328. ofn.lStructSize = sizeof(ofn);
  329. ofn.hwndOwner = hwnd;
  330. ofn.hInstance = g_hAppInstance;
  331. ofn.lpstrFile = g_acImageName;
  332. ofn.nMaxFile = MAX_PATH;
  333. ofn.lpstrTitle = "Open Image File";
  334. ofn.lpstrInitialDir = ".";
  335. ofn.Flags = OFN_FILEMUSTEXIST;
  336. g_acImageName[0] = '\0';
  337. // Make up the file type filter string
  338. ImageCodecInfo* codecs;
  339. UINT count;
  340. if ( g_pDestPoints != NULL )
  341. {
  342. free(g_pDestPoints);
  343. }
  344. g_DestPointCount = 0;
  345. GpStatus status;
  346. UINT cbCodecs = 0;
  347. GetImageDecodersSize(&count, &cbCodecs);
  348. codecs = static_cast<ImageCodecInfo *>(malloc (cbCodecs));
  349. if (codecs == NULL)
  350. {
  351. return;
  352. }
  353. status = GetImageDecoders(count, cbCodecs, codecs);
  354. if (status != Ok)
  355. {
  356. return;
  357. }
  358. CHAR* filter = MakeFilterFromCodecs(count, codecs, TRUE);
  359. if (codecs)
  360. {
  361. free(codecs);
  362. }
  363. if ( !filter )
  364. {
  365. VERBOSE(("DoOpen--MakeFilterFromCodecs() failed\n"));
  366. return;
  367. }
  368. ofn.lpstrFilter = filter;
  369. // Present the file/open dialog
  370. if ( GetOpenFileName(&ofn) )
  371. {
  372. OpenImageFile(g_acImageName);
  373. }
  374. free(filter);
  375. }// DoOpen()
  376. //
  377. // Open image file
  378. //
  379. VOID
  380. DoOpenAudioFile(
  381. HWND hwnd
  382. )
  383. {
  384. OPENFILENAME ofn;
  385. char audioFileName[256];
  386. ZeroMemory(&ofn, sizeof(ofn));
  387. ofn.lStructSize = sizeof(ofn);
  388. ofn.hwndOwner = hwnd;
  389. ofn.hInstance = g_hAppInstance;
  390. ofn.lpstrFile = audioFileName;
  391. ofn.nMaxFile = MAX_PATH;
  392. ofn.lpstrTitle = "Attach Audio File To Image";
  393. ofn.lpstrInitialDir = ".";
  394. ofn.Flags = OFN_FILEMUSTEXIST;
  395. g_acImageName[0] = '\0';
  396. // Make up the file type filter string
  397. ofn.lpstrFilter = ".wav";
  398. // Present the file/open dialog
  399. if ( GetOpenFileName(&ofn) )
  400. {
  401. UINT uiTextLength = strlen(audioFileName);
  402. PropertyItem myItem;
  403. myItem.id = PropertyTagExifRelatedWav;
  404. myItem.length = uiTextLength;
  405. myItem.type = TAG_TYPE_ASCII;
  406. myItem.value = malloc(uiTextLength);
  407. if ( myItem.value != NULL )
  408. {
  409. strcpy((char*)myItem.value, audioFileName);
  410. Status rCode = g_pImage->SetPropertyItem(&myItem);
  411. if ( (rCode != Ok) && (rCode != NotImplemented) )
  412. {
  413. VERBOSE(("SetPropertyItem() failed\n"));
  414. }
  415. }
  416. }
  417. }// DoOpenAudioFile()
  418. #define STEPS 100
  419. VOID
  420. CreateBackgroundBitmap()
  421. {
  422. BitmapData bmpData;
  423. Bitmap* myBmp = new Bitmap(g_iWinWidth, g_iWinHeight, PIXFMT_32BPP_ARGB);
  424. Rect rect(0, 0, g_iWinWidth, g_iWinHeight);
  425. Status status = myBmp->LockBits(&rect,
  426. ImageLockModeWrite,
  427. PIXFMT_32BPP_ARGB,
  428. &bmpData);
  429. // Make a horizontal blue gradient
  430. UINT x, y;
  431. ARGB colors[STEPS];
  432. for (x=0; x < STEPS; x++)
  433. {
  434. colors[x] = MAKEARGB(128, 0, 0, x * 255 / (STEPS-1));
  435. }
  436. for (y=0; y < STEPS; y++)
  437. {
  438. ARGB* p = (ARGB*)((BYTE*)bmpData.Scan0 + y * bmpData.Stride);
  439. for (x=0; x < STEPS; x++)
  440. {
  441. *p++ = colors[(x+y) % STEPS];
  442. }
  443. }
  444. status = myBmp->UnlockBits(&bmpData);
  445. if ( g_pImage != NULL )
  446. {
  447. delete g_pImage;
  448. g_pImage = NULL;
  449. }
  450. g_pImage = myBmp;
  451. UpdateImageInfo();
  452. return;
  453. }// CreateBackgroundBitmap()
  454. //
  455. // Handle window repaint event
  456. //
  457. VOID
  458. DoPaint(
  459. HWND hwnd,
  460. HDC *phdc = NULL
  461. )
  462. {
  463. if ( g_pImage == NULL )
  464. {
  465. return;
  466. }
  467. else
  468. {
  469. HDC hdc;
  470. PAINTSTRUCT ps;
  471. RECT rect;
  472. ImageInfo imageInfo;
  473. if (!phdc)
  474. {
  475. hdc = BeginPaint(hwnd, &ps);
  476. }
  477. else
  478. {
  479. hdc = *phdc;
  480. }
  481. // Get current window's client area. Used for paint later
  482. GetClientRect(hwnd, &rect);
  483. ULONG ulWinWidth = (ULONG)(rect.right - rect.left);
  484. ULONG ulWinHeight = (ULONG)(rect.bottom - rect.top);
  485. // Make up a dest rect that we need image to draw to
  486. REAL dDestImageWidth = g_ImageWidth * g_dScale;
  487. REAL dDestImageHeight = g_ImageHeight * g_dScale;
  488. Rect dstRect(rect.left, rect.top, (UINT)(dDestImageWidth),
  489. (UINT)(dDestImageHeight));
  490. RectF srcRect;
  491. Unit srcUnit;
  492. g_pImage->GetBounds(&srcRect, &srcUnit);
  493. Graphics* pGraphics = new Graphics(hdc);
  494. if ( pGraphics == NULL )
  495. {
  496. VERBOSE(("DoPaint--new Graphics() failed"));
  497. return;
  498. }
  499. pGraphics->SetInterpolationMode(g_InterpolationMode);
  500. // Width and height, in pixel, of the src image need to be drawn
  501. UINT uiImageWidth = g_ImageWidth;
  502. UINT uiImageHeight = g_ImageHeight;
  503. // Adjust the src image region need to be drawn.
  504. // If the image is bigger than the viewable area, we just need to
  505. // paint partial image, the viewable size
  506. #if 0
  507. if ( ulWinWidth < dDestImageWidth )
  508. {
  509. uiImageWidth = (UINT)(ulWinWidth / g_dScale);
  510. }
  511. if ( ulWinHeight < uiImageHeight )
  512. {
  513. uiImageHeight = (UINT)(ulWinHeight / g_dScale);
  514. }
  515. #endif
  516. if ( (g_DestPointCount == 0) && (g_SourceWidth == 0) )
  517. {
  518. // Simple case, draw to destRect
  519. pGraphics->DrawImage(g_pImage,
  520. dstRect,
  521. (UINT)srcRect.GetLeft(),
  522. (UINT)srcRect.GetTop(),
  523. uiImageWidth,
  524. uiImageHeight,
  525. UnitPixel,
  526. g_pDrawAttrib,
  527. NULL,
  528. NULL);
  529. }
  530. else if ( (g_DestPointCount == 0) && (g_SourceWidth != 0) )
  531. {
  532. // This case will allow cropping, etc.
  533. pGraphics->DrawImage(g_pImage,
  534. dstRect,
  535. (int)g_SourceX,
  536. (int)g_SourceY,
  537. (int)g_SourceWidth,
  538. (int)g_SourceHeight,
  539. UnitPixel,
  540. g_pDrawAttrib,
  541. NULL,
  542. NULL);
  543. }
  544. else if ( (g_DestPointCount != 0) && (g_SourceWidth == 0) )
  545. {
  546. // This case will allow cropping, etc.
  547. if ( g_DestPointCount == 4 )
  548. {
  549. // Hack until draw image support 4 transform points
  550. pGraphics->DrawImage(g_pImage,
  551. g_pDestPoints,
  552. 3,
  553. 0,
  554. 0,
  555. (float)uiImageWidth,
  556. (float)uiImageHeight,
  557. UnitPixel,
  558. g_pDrawAttrib,
  559. NULL,
  560. NULL);
  561. }
  562. else
  563. {
  564. pGraphics->DrawImage(g_pImage,
  565. g_pDestPoints,
  566. g_DestPointCount,
  567. 0,
  568. 0,
  569. (float)uiImageWidth,
  570. (float)uiImageHeight,
  571. UnitPixel,
  572. g_pDrawAttrib,
  573. NULL,
  574. NULL);
  575. }
  576. }
  577. else
  578. {
  579. // This case will allow both cropping and rotation
  580. if ( g_DestPointCount == 4 )
  581. {
  582. // Hack until DrawImage supports 4 transform points
  583. pGraphics->DrawImage(g_pImage,
  584. g_pDestPoints,
  585. 3,
  586. g_SourceX,
  587. g_SourceY,
  588. g_SourceWidth,
  589. g_SourceHeight,
  590. UnitPixel,
  591. g_pDrawAttrib,
  592. NULL,
  593. NULL);
  594. }
  595. else
  596. {
  597. pGraphics->DrawImage(g_pImage,
  598. g_pDestPoints,
  599. g_DestPointCount,
  600. g_SourceX,
  601. g_SourceY,
  602. g_SourceWidth,
  603. g_SourceHeight,
  604. UnitPixel,
  605. g_pDrawAttrib,
  606. NULL,
  607. NULL);
  608. }
  609. }
  610. delete pGraphics;
  611. // FillRect(hdc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
  612. if (!phdc)
  613. EndPaint(hwnd, &ps);
  614. }
  615. }// DoPaint()
  616. VOID
  617. DoPrint(HWND hwnd)
  618. {
  619. PRINTDLG printdlg;
  620. memset(&printdlg, 0, sizeof(PRINTDLG));
  621. printdlg.lStructSize = sizeof(PRINTDLG);
  622. printdlg.hwndOwner = hwnd;
  623. DEVMODE dm;
  624. memset(&dm, 0, sizeof(DEVMODE));
  625. dm.dmICMMethod = DMICMMETHOD_SYSTEM;
  626. printdlg.hDevMode = &dm;
  627. printdlg.hDevNames = NULL;
  628. printdlg.hDC = NULL;
  629. printdlg.Flags = PD_RETURNDC;
  630. if (PrintDlg(&printdlg))
  631. {
  632. DOCINFO di;
  633. memset(&di, 0, sizeof(DOCINFO));
  634. di.cbSize = sizeof(DOCINFO);
  635. di.lpszDocName = g_acImageName;
  636. di.lpszOutput = (LPTSTR)NULL;
  637. di.lpszDatatype = (LPTSTR)NULL;
  638. di.fwType = 0;
  639. StartDoc(printdlg.hDC, &di);
  640. StartPage(printdlg.hDC);
  641. // Use GDI+ printing code to do the real print job
  642. DoPaint(hwnd, &printdlg.hDC);
  643. EndPage(printdlg.hDC);
  644. EndDoc(printdlg.hDC);
  645. }
  646. else
  647. {
  648. DWORD error = CommDlgExtendedError();
  649. if (error)
  650. {
  651. char errormessage[100];
  652. sprintf(errormessage, "PrintDlg error: %d", error);
  653. MessageBox(hwnd, errormessage, "PrintDlg error", MB_OK);
  654. }
  655. }
  656. }// DoPrint()
  657. BOOL
  658. SetJpegDefaultParameters()
  659. {
  660. // Set default quality level as 100, unsigned value
  661. SetDlgItemInt(g_hwndJpegSaveDlg, IDC_SAVEJPEG_QEFIELD, 100, FALSE);
  662. // Set No transform as default
  663. CheckRadioButton(g_hwndJpegSaveDlg,
  664. IDC_SAVEJPEG_R90,
  665. IDC_SAVEJPEG_NOTRANSFORM,
  666. IDC_SAVEJPEG_NOTRANSFORM);
  667. return TRUE;
  668. }// SetJpegDefaultParameters()
  669. BOOL
  670. SetTiffDefaultParameters()
  671. {
  672. // Set default color depth and compression method as the same as current
  673. // image
  674. CheckRadioButton(g_hwndTiffSaveDlg,
  675. IDC_SAVETIFF_1BPP,
  676. IDC_SAVETIFF_ASSOURCE,
  677. IDC_SAVETIFF_ASSOURCE);
  678. CheckRadioButton(g_hwndTiffSaveDlg,
  679. IDC_SAVETIFF_CCITT4,
  680. IDC_SAVETIFF_COMPASSOURCE,
  681. IDC_SAVETIFF_COMPASSOURCE);
  682. // If the source image is multi-frame, check "save as multi-frame" on
  683. if ( g_uiTotalPages > 1 )
  684. {
  685. SendDlgItemMessage(g_hwndTiffSaveDlg, IDC_SAVETIFF_MULTIFRAME,
  686. BM_SETCHECK, 0, 0);
  687. }
  688. return TRUE;
  689. }// SetTiffDefaultParameters()
  690. /*****************************************************************************\
  691. *
  692. * FUNCTION : DecoderParamDlgProc(hDlg, uiMessage, wParam, lParam)
  693. *
  694. * PURPOSE : Dialog function for the Decoder Parameter settings dialog
  695. *
  696. \*****************************************************************************/
  697. INT_PTR CALLBACK
  698. DecoderParamDlgProc(
  699. HWND hDlg,
  700. UINT uiMessage,
  701. WPARAM wParam,
  702. LPARAM lParam
  703. )
  704. {
  705. switch ( uiMessage )
  706. {
  707. case WM_COMMAND:
  708. switch ( LOWORD(wParam) )
  709. {
  710. case IDC_COLORKEY_CANCEL:
  711. // End the dialog and return FALSE. So we won't do anything
  712. EndDialog(hDlg, FALSE);
  713. break;
  714. case IDC_COLORKEY_OK:
  715. // User hit the OK button. First, we need to get the values user
  716. // entered
  717. char acTemp[20];
  718. UINT uiTempLow;
  719. UINT uiTempHigh;
  720. UINT TransKeyLow = 0x0;
  721. UINT TransKeyHigh = 0x0;
  722. // Get the RED key
  723. uiTempLow = GetDlgItemInt(g_hwndDecoderDlg, IDC_TRANS_LOWER_RFIELD,
  724. NULL, FALSE);
  725. uiTempHigh = GetDlgItemInt(g_hwndDecoderDlg,
  726. IDC_TRANS_HIGHER_RFIELD, NULL, FALSE);
  727. if ( (uiTempLow > 255) || (uiTempHigh > 255)
  728. ||(uiTempLow > uiTempHigh) )
  729. {
  730. VERBOSE(("Input key value should be within 0 to 255"));
  731. VERBOSE(("Lower key should be smaller or equal to higher key"));
  732. break;
  733. }
  734. TransKeyLow = ((uiTempLow & 0xff) << 16);
  735. TransKeyHigh = ((uiTempHigh & 0xff) << 16);
  736. // Get the Green key
  737. uiTempLow = GetDlgItemInt(g_hwndDecoderDlg, IDC_TRANS_LOWER_GFIELD,
  738. NULL, FALSE);
  739. uiTempHigh = GetDlgItemInt(g_hwndDecoderDlg,
  740. IDC_TRANS_HIGHER_GFIELD, NULL, FALSE);
  741. if ( (uiTempLow > 255)
  742. ||(uiTempHigh > 255)
  743. ||(uiTempLow > uiTempHigh) )
  744. {
  745. VERBOSE(("Input key value should be within 0 to 255"));
  746. VERBOSE(("Lower key should be smaller or equal to higher key"));
  747. break;
  748. }
  749. TransKeyLow |= ((uiTempLow & 0xff) << 8);
  750. TransKeyHigh |= ((uiTempHigh & 0xff) << 8);
  751. // Get the Blue key
  752. uiTempLow = GetDlgItemInt(g_hwndDecoderDlg, IDC_TRANS_LOWER_BFIELD,
  753. NULL, FALSE);
  754. uiTempHigh = GetDlgItemInt(g_hwndDecoderDlg,
  755. IDC_TRANS_HIGHER_BFIELD, NULL, FALSE);
  756. if ( (uiTempLow > 255)
  757. ||(uiTempHigh > 255)
  758. ||(uiTempLow > uiTempHigh) )
  759. {
  760. VERBOSE(("Input key value should be within 0 to 255"));
  761. VERBOSE(("Lower key should be smaller or equal to higher key"));
  762. break;
  763. }
  764. TransKeyLow |= (uiTempLow & 0xff);
  765. TransKeyHigh |= (uiTempHigh & 0xff);
  766. // Get the C key
  767. uiTempLow = GetDlgItemInt(g_hwndDecoderDlg, IDC_TRANS_LOWER_CFIELD,
  768. NULL, FALSE);
  769. uiTempHigh = GetDlgItemInt(g_hwndDecoderDlg,
  770. IDC_TRANS_HIGHER_CFIELD, NULL, FALSE);
  771. if ( (uiTempLow > 255)
  772. ||(uiTempHigh > 255)
  773. ||(uiTempLow > uiTempHigh) )
  774. {
  775. VERBOSE(("Input key value should be within 0 to 255"));
  776. VERBOSE(("Lower key should be smaller or equal to higher key"));
  777. break;
  778. }
  779. TransKeyLow |= ((uiTempLow & 0xff) << 24);
  780. TransKeyHigh |= ((uiTempHigh & 0xff) << 24);
  781. // Up to this point, the TRANSKEY, lower and higher, should be in
  782. // the format of 0x00RRGGBB for RGB image or 0xCCMMYYKK for CMYK
  783. // image
  784. // Set draw attributes
  785. if ( g_pDrawAttrib != NULL )
  786. {
  787. delete g_pDrawAttrib;
  788. }
  789. g_pDrawAttrib = new ImageAttributes();
  790. Color lowKey(TransKeyLow);
  791. Color highKey(TransKeyHigh);
  792. g_pDrawAttrib->SetColorKey(lowKey, highKey);
  793. RefreshImageDisplay();
  794. EndDialog(hDlg, TRUE);
  795. break;
  796. }// switch on WM_COMMAND
  797. break;
  798. case WM_INITDIALOG:
  799. // Remember the dialog handle so that we can use it to deal with items
  800. // in this dialog
  801. g_hwndDecoderDlg = hDlg;
  802. // Set initial values
  803. SetDlgItemInt(g_hwndDecoderDlg, IDC_TRANS_LOWER_RFIELD, 250, FALSE);
  804. SetDlgItemInt(g_hwndDecoderDlg, IDC_TRANS_LOWER_GFIELD, 250, FALSE);
  805. SetDlgItemInt(g_hwndDecoderDlg, IDC_TRANS_LOWER_BFIELD, 250, FALSE);
  806. SetDlgItemInt(g_hwndDecoderDlg, IDC_TRANS_LOWER_CFIELD, 250, FALSE);
  807. SetDlgItemInt(g_hwndDecoderDlg, IDC_TRANS_HIGHER_RFIELD, 255, FALSE);
  808. SetDlgItemInt(g_hwndDecoderDlg, IDC_TRANS_HIGHER_GFIELD, 255, FALSE);
  809. SetDlgItemInt(g_hwndDecoderDlg, IDC_TRANS_HIGHER_BFIELD, 255, FALSE);
  810. SetDlgItemInt(g_hwndDecoderDlg, IDC_TRANS_HIGHER_CFIELD, 255, FALSE);
  811. return TRUE;
  812. }
  813. return FALSE;
  814. }// DecoderParamDlgProc()
  815. INT_PTR CALLBACK
  816. ColorMapDlgProc(
  817. HWND hDlg,
  818. UINT uiMessage,
  819. WPARAM wParam,
  820. LPARAM lParam
  821. )
  822. {
  823. switch ( uiMessage )
  824. {
  825. case WM_COMMAND:
  826. switch ( LOWORD(wParam) )
  827. {
  828. case IDC_COLORMAP_CANCEL:
  829. // End the dialog and return FALSE. So we won't do anything
  830. EndDialog(hDlg, FALSE);
  831. break;
  832. case IDC_COLORMAP_OK:
  833. // User hit the OK button. First, we need to get the values user
  834. // entered
  835. if ( NULL == g_pImage )
  836. {
  837. // If there is no image, just close the dialog
  838. EndDialog(hDlg, TRUE);
  839. break;
  840. }
  841. char acTemp[20];
  842. UINT uiOldR;
  843. UINT uiNewR;
  844. UINT uiOldG;
  845. UINT uiNewG;
  846. UINT uiOldB;
  847. UINT uiNewB;
  848. UINT uiOldA;
  849. UINT uiNewA;
  850. // Get the RED key
  851. uiOldR = GetDlgItemInt(g_hwndColorMapDlg, IDC_MAP_OLD_RFIELD,
  852. NULL, FALSE);
  853. uiNewR = GetDlgItemInt(g_hwndColorMapDlg,
  854. IDC_MAP_NEW_RFIELD, NULL, FALSE);
  855. if ( (uiOldR > 255) || (uiNewR > 255) )
  856. {
  857. VERBOSE(("Input key value should be within 0 to 255"));
  858. break;
  859. }
  860. // Get the Green key
  861. uiOldG = GetDlgItemInt(g_hwndColorMapDlg, IDC_MAP_OLD_GFIELD,
  862. NULL, FALSE);
  863. uiNewG = GetDlgItemInt(g_hwndColorMapDlg,
  864. IDC_MAP_NEW_GFIELD, NULL, FALSE);
  865. if ( (uiOldG > 255) || (uiNewG > 255) )
  866. {
  867. VERBOSE(("Input key value should be within 0 to 255"));
  868. break;
  869. }
  870. // Get the Blue key
  871. uiOldB = GetDlgItemInt(g_hwndColorMapDlg, IDC_MAP_OLD_BFIELD,
  872. NULL, FALSE);
  873. uiNewB = GetDlgItemInt(g_hwndColorMapDlg,
  874. IDC_MAP_NEW_BFIELD, NULL, FALSE);
  875. if ( (uiOldB > 255) || (uiNewB > 255) )
  876. {
  877. VERBOSE(("Input key value should be within 0 to 255"));
  878. break;
  879. }
  880. // Get the A key
  881. uiOldA = GetDlgItemInt(g_hwndColorMapDlg, IDC_MAP_OLD_AFIELD,
  882. NULL, FALSE);
  883. uiNewA = GetDlgItemInt(g_hwndColorMapDlg,
  884. IDC_MAP_NEW_AFIELD, NULL, FALSE);
  885. if ( (uiOldA > 255) || (uiNewA > 255) )
  886. {
  887. VERBOSE(("Input key value should be within 0 to 255"));
  888. break;
  889. }
  890. // Set draw attributes
  891. if ( g_pDrawAttrib == NULL )
  892. {
  893. g_pDrawAttrib = new ImageAttributes();
  894. if ( g_pDrawAttrib == NULL )
  895. {
  896. return FALSE;
  897. }
  898. }
  899. ColorMap myColorMap;
  900. Color oldColor((BYTE)uiOldA, (BYTE)uiOldR, (BYTE)uiOldG,
  901. (BYTE)uiOldB);
  902. Color newColor((BYTE)uiNewA, (BYTE)uiNewR, (BYTE)uiNewG,
  903. (BYTE)uiNewB);
  904. myColorMap.oldColor = oldColor;
  905. myColorMap.newColor = newColor;
  906. g_pDrawAttrib->SetRemapTable(1, &myColorMap, ColorAdjustTypeBitmap);
  907. RefreshImageDisplay();
  908. EndDialog(hDlg, TRUE);
  909. break;
  910. }// switch()
  911. break;
  912. case WM_INITDIALOG:
  913. // Remember the dialog handle so that we can use it to deal with items
  914. // in this dialog
  915. g_hwndColorMapDlg = hDlg;
  916. // Set initial values
  917. SetDlgItemInt(g_hwndColorMapDlg, IDC_MAP_OLD_RFIELD, 255, FALSE);
  918. SetDlgItemInt(g_hwndColorMapDlg, IDC_MAP_OLD_GFIELD, 0, FALSE);
  919. SetDlgItemInt(g_hwndColorMapDlg, IDC_MAP_OLD_BFIELD, 0, FALSE);
  920. SetDlgItemInt(g_hwndColorMapDlg, IDC_MAP_OLD_AFIELD, 255, FALSE);
  921. SetDlgItemInt(g_hwndColorMapDlg, IDC_MAP_NEW_RFIELD, 0, FALSE);
  922. SetDlgItemInt(g_hwndColorMapDlg, IDC_MAP_NEW_GFIELD, 255, FALSE);
  923. SetDlgItemInt(g_hwndColorMapDlg, IDC_MAP_NEW_BFIELD, 0, FALSE);
  924. SetDlgItemInt(g_hwndColorMapDlg, IDC_MAP_NEW_AFIELD, 255, FALSE);
  925. return TRUE;
  926. }// switch ( uiMessage )
  927. return FALSE;
  928. }// ColorMapDlgProc()
  929. INT_PTR CALLBACK
  930. AnnotationDlgProc(
  931. HWND hDlg,
  932. UINT uiMessage,
  933. WPARAM wParam,
  934. LPARAM lParam
  935. )
  936. {
  937. switch ( uiMessage )
  938. {
  939. case WM_COMMAND:
  940. switch ( LOWORD(wParam) )
  941. {
  942. case IDC_ANNOTATION_CANCEL:
  943. // End the dialog and return FALSE. So we won't do anything
  944. EndDialog(hDlg, FALSE);
  945. break;
  946. case IDC_ANNOTATION_OK:
  947. // User hit the OK button. First, we need to get the values user
  948. // entered
  949. if ( NULL == g_pImage )
  950. {
  951. // If there is no image, just close the dialog
  952. EndDialog(hDlg, TRUE);
  953. break;
  954. }
  955. char acTemp[200];
  956. UINT uiTextLength = 0;
  957. uiTextLength = GetDlgItemText(g_hwndAnnotationDlg,
  958. IDC_ANNOTATION_EDITOR, acTemp, 200);
  959. if ( uiTextLength > 0 )
  960. {
  961. // Add 1 for the NULL terminator
  962. uiTextLength++;
  963. PropertyItem myItem;
  964. myItem.id = PropertyTagExifUserComment;
  965. myItem.length = uiTextLength;
  966. myItem.type = TAG_TYPE_ASCII;
  967. myItem.value = malloc(uiTextLength);
  968. if ( myItem.value != NULL )
  969. {
  970. strcpy((char*)myItem.value, acTemp);
  971. Status rCode = g_pImage->SetPropertyItem(&myItem);
  972. if ( (rCode != Ok) && (rCode != NotImplemented) )
  973. {
  974. VERBOSE(("SetPropertyItem() failed\n"));
  975. }
  976. free(myItem.value);
  977. }
  978. }
  979. EndDialog(hDlg, TRUE);
  980. break;
  981. }// switch()
  982. break;
  983. case WM_INITDIALOG:
  984. // Remember the dialog handle so that we can use it to deal with items
  985. // in this dialog
  986. g_hwndAnnotationDlg = hDlg;
  987. // Check to see if the image has annotation in it
  988. // Check the size for this property item
  989. if ( g_pImage != NULL )
  990. {
  991. UINT uiItemSize = g_pImage->GetPropertyItemSize(
  992. PropertyTagExifUserComment);
  993. if ( uiItemSize != 0 )
  994. {
  995. // Allocate memory and get this property item
  996. PropertyItem* pBuffer = (PropertyItem*)malloc(uiItemSize);
  997. if ( pBuffer == NULL )
  998. {
  999. return FALSE;
  1000. }
  1001. if ( g_pImage->GetPropertyItem(PropertyTagExifUserComment,
  1002. uiItemSize, pBuffer) == Ok )
  1003. {
  1004. // Set initial values
  1005. SetDlgItemText(g_hwndAnnotationDlg, IDC_ANNOTATION_EDITOR,
  1006. (char*)pBuffer->value);
  1007. return TRUE;
  1008. }
  1009. else
  1010. {
  1011. // Can't get property item. Something wrong
  1012. return FALSE;
  1013. }
  1014. }
  1015. else
  1016. {
  1017. // No this property item, just initialize it with NULL
  1018. SetDlgItemText(g_hwndAnnotationDlg, IDC_ANNOTATION_EDITOR, "");
  1019. }
  1020. }
  1021. return TRUE;
  1022. }// switch ( uiMessage )
  1023. return FALSE;
  1024. }// AnnotationDlgProc()
  1025. #define NO_TRANSFORM 9999
  1026. /*****************************************************************************\
  1027. *
  1028. * FUNCTION : JpegSaveDlgProc(hDlg, uiMessage, wParam, lParam)
  1029. *
  1030. * PURPOSE : Dialog function for the Encoder Parameter settings dialog
  1031. *
  1032. \*****************************************************************************/
  1033. INT_PTR CALLBACK
  1034. JpegSaveDlgProc(
  1035. HWND hDlg,
  1036. UINT uiMessage,
  1037. WPARAM wParam,
  1038. LPARAM lParam
  1039. )
  1040. {
  1041. static ULONG flagValueTransform = NO_TRANSFORM; // No transform at all
  1042. switch ( uiMessage )
  1043. {
  1044. case WM_COMMAND:
  1045. switch ( LOWORD(wParam) )
  1046. {
  1047. case IDC_SAVEJPEG_CANCEL:
  1048. // End the dialog and return FALSE. So we won't save this image
  1049. EndDialog(hDlg, FALSE);
  1050. break;
  1051. case IDC_SAVEJPEG_OK:
  1052. // User hit the OK button. First, we need to set the EncoderParam
  1053. // based on user selection
  1054. if ( g_pImage == NULL )
  1055. {
  1056. VERBOSE(("EncoderParamDlgProc: No image avail\n"));
  1057. EndDialog(hDlg, FALSE);
  1058. }
  1059. else
  1060. {
  1061. if ( g_pEncoderParams != NULL )
  1062. {
  1063. free(g_pEncoderParams);
  1064. g_pEncoderParams = NULL;
  1065. }
  1066. if ( flagValueTransform != NO_TRANSFORM )
  1067. {
  1068. // User has set lossless transform, so we need set encoder
  1069. // parameter
  1070. g_pEncoderParams =
  1071. (EncoderParameters*)malloc(sizeof(EncoderParameters));
  1072. g_pEncoderParams->Parameter[0].Guid = EncoderTransformation;
  1073. g_pEncoderParams->Parameter[0].Type =
  1074. EncoderParameterValueTypeLong;
  1075. g_pEncoderParams->Parameter[0].NumberOfValues = 1;
  1076. g_pEncoderParams->Parameter[0].Value =
  1077. (VOID*)&flagValueTransform;
  1078. g_pEncoderParams->Count = 1;
  1079. }
  1080. EndDialog(hDlg, TRUE);
  1081. }
  1082. break;
  1083. case IDC_SAVEJPEG_R90:
  1084. flagValueTransform = EncoderValueTransformRotate90;
  1085. break;
  1086. case IDC_SAVEJPEG_R180:
  1087. flagValueTransform = EncoderValueTransformRotate180;
  1088. break;
  1089. case IDC_SAVEJPEG_R270:
  1090. flagValueTransform = EncoderValueTransformRotate270;
  1091. break;
  1092. case IDC_SAVEJPEG_HFLIP:
  1093. flagValueTransform = EncoderValueTransformFlipHorizontal;
  1094. break;
  1095. case IDC_SAVEJPEG_VFLIP:
  1096. flagValueTransform = EncoderValueTransformFlipVertical;
  1097. break;
  1098. default:
  1099. break;
  1100. }
  1101. break;
  1102. case WM_INITDIALOG:
  1103. // Remember the dialog handle so that we can use it to deal with items
  1104. // in this dialog
  1105. g_hwndJpegSaveDlg = hDlg;
  1106. flagValueTransform = NO_TRANSFORM;
  1107. SetJpegDefaultParameters();
  1108. return TRUE;
  1109. }
  1110. return FALSE;
  1111. }// JpegSaveDlgProc()
  1112. /*****************************************************************************\
  1113. *
  1114. * FUNCTION : TiffSaveDlgProc(hDlg, uiMessage, wParam, lParam)
  1115. *
  1116. * PURPOSE : Dialog function for the Encoder Parameter settings dialog
  1117. *
  1118. \*****************************************************************************/
  1119. INT_PTR CALLBACK
  1120. TiffSaveDlgProc(
  1121. HWND hDlg,
  1122. UINT uiMessage,
  1123. WPARAM wParam,
  1124. LPARAM lParam
  1125. )
  1126. {
  1127. static PixelFormat flagColorDepth = g_ImagePixelFormat; // Default color depth
  1128. static compressMethod = 0;
  1129. static ULONG colorTemp = 0;
  1130. switch ( uiMessage )
  1131. {
  1132. case WM_COMMAND:
  1133. switch ( LOWORD(wParam) )
  1134. {
  1135. case IDC_SAVETIFFDLG_CANCEL:
  1136. // End the dialog and return FALSE. So we won't save this image
  1137. EndDialog(hDlg, FALSE);
  1138. break;
  1139. case IDC_SAVETIFFDLG_OK:
  1140. {
  1141. // User hit the OK button. First, we need to set the EncoderParam
  1142. // based on user selection
  1143. if ( g_pImage == NULL )
  1144. {
  1145. VERBOSE(("EncoderParamDlgProc: No image avail\n"));
  1146. EndDialog(hDlg, FALSE);
  1147. }
  1148. else
  1149. {
  1150. if ( g_pEncoderParams != NULL )
  1151. {
  1152. free(g_pEncoderParams);
  1153. g_pEncoderParams = NULL;
  1154. }
  1155. UINT numOfParamSet = 0;
  1156. if ( flagColorDepth != g_ImagePixelFormat )
  1157. {
  1158. numOfParamSet++;
  1159. }
  1160. if ( compressMethod != 0 )
  1161. {
  1162. numOfParamSet++;
  1163. }
  1164. if ( numOfParamSet > 0 )
  1165. {
  1166. int iTemp = 0;
  1167. // User has set new color depth, so we need set encoder
  1168. // parameter for it
  1169. g_pEncoderParams =
  1170. (EncoderParameters*)malloc(sizeof(EncoderParameters) +
  1171. numOfParamSet * sizeof(EncoderParameter));
  1172. if ( compressMethod != 0 )
  1173. {
  1174. // Set compression method
  1175. g_pEncoderParams->Parameter[iTemp].Guid =
  1176. EncoderCompression;
  1177. g_pEncoderParams->Parameter[iTemp].Type =
  1178. EncoderParameterValueTypeLong;
  1179. g_pEncoderParams->Parameter[iTemp].NumberOfValues = 1;
  1180. g_pEncoderParams->Parameter[iTemp].Value =
  1181. (VOID*)&compressMethod;
  1182. iTemp++;
  1183. g_pEncoderParams->Count = iTemp;
  1184. }
  1185. if ( flagColorDepth != g_ImagePixelFormat )
  1186. {
  1187. // Set color depth
  1188. g_pEncoderParams->Parameter[iTemp].Guid =
  1189. EncoderColorDepth;
  1190. g_pEncoderParams->Parameter[iTemp].Type =
  1191. EncoderParameterValueTypeLong;
  1192. g_pEncoderParams->Parameter[iTemp].NumberOfValues = 1;
  1193. g_pEncoderParams->Parameter[iTemp].Value =
  1194. (VOID*)&colorTemp;
  1195. iTemp++;
  1196. g_pEncoderParams->Count = iTemp;
  1197. }
  1198. }// if ( numOfParamSet > 0 )
  1199. EndDialog(hDlg, TRUE);
  1200. }
  1201. }
  1202. break;
  1203. case IDC_SAVETIFF_1BPP:
  1204. flagColorDepth = PIXFMT_1BPP_INDEXED;
  1205. colorTemp = 1;
  1206. break;
  1207. case IDC_SAVETIFF_4BPP:
  1208. flagColorDepth = PIXFMT_4BPP_INDEXED;
  1209. colorTemp = 4;
  1210. break;
  1211. case IDC_SAVETIFF_8BPP:
  1212. flagColorDepth = PIXFMT_8BPP_INDEXED;
  1213. colorTemp = 8;
  1214. break;
  1215. case IDC_SAVETIFF_24BPP:
  1216. flagColorDepth = PIXFMT_24BPP_RGB;
  1217. colorTemp = 24;
  1218. break;
  1219. case IDC_SAVETIFF_32ARGB:
  1220. flagColorDepth = PIXFMT_32BPP_ARGB;
  1221. colorTemp = 32;
  1222. break;
  1223. case IDC_SAVETIFF_CCITT3:
  1224. compressMethod = EncoderValueCompressionCCITT3;
  1225. break;
  1226. case IDC_SAVETIFF_CCITT4:
  1227. compressMethod = EncoderValueCompressionCCITT4;
  1228. break;
  1229. case IDC_SAVETIFF_RLE:
  1230. compressMethod = EncoderValueCompressionRle;
  1231. break;
  1232. case IDC_SAVETIFF_LZW:
  1233. compressMethod = EncoderValueCompressionLZW;
  1234. break;
  1235. case IDC_SAVETIFF_UNCOMPRESSED:
  1236. compressMethod = EncoderValueCompressionNone;
  1237. break;
  1238. case IDC_SAVETIFF_COMPASSOURCE:
  1239. compressMethod = 0;
  1240. break;
  1241. default:
  1242. break;
  1243. }
  1244. break;
  1245. case WM_INITDIALOG:
  1246. // Remember the dialog handle so that we can use it to deal with items
  1247. // in this dialog
  1248. g_hwndTiffSaveDlg = hDlg;
  1249. flagColorDepth = g_ImagePixelFormat; // Default color depth
  1250. compressMethod = 0;
  1251. colorTemp = 0;
  1252. SetTiffDefaultParameters();
  1253. return TRUE;
  1254. }
  1255. return FALSE;
  1256. }// TiffSaveDlgProc()
  1257. BOOL
  1258. StartSaveImage(
  1259. const CHAR* filename,
  1260. const CLSID* clsid
  1261. )
  1262. {
  1263. // Convert filename to a WCHAR
  1264. WCHAR namestr[MAX_FILENAME_LENGTH];
  1265. if ( !AnsiToUnicodeStr(filename, namestr, MAX_FILENAME_LENGTH) )
  1266. {
  1267. VERBOSE(("StartSaveImage: Convert %s to a WCHAR failed\n", filename));
  1268. return FALSE;
  1269. }
  1270. if ( g_pImage != NULL )
  1271. {
  1272. CLSID tempClsID = *clsid;
  1273. Status rCode = Ok;
  1274. // Popup a dialog to let user set up the encoder parameters
  1275. if ( tempClsID == K_JPEGCLSID )
  1276. {
  1277. if ( ShowMyDialog((INT)IDD_SAVEJPEGDLG, g_hwndMain,
  1278. JpegSaveDlgProc) == FALSE )
  1279. {
  1280. return FALSE;
  1281. }
  1282. }
  1283. else if ( tempClsID == K_TIFFCLSID )
  1284. {
  1285. if ( ShowMyDialog((INT)IDD_SAVETIFFDLG, g_hwndMain,
  1286. TiffSaveDlgProc) == FALSE )
  1287. {
  1288. return FALSE;
  1289. }
  1290. }
  1291. // Note: during the save dialog, the g_pEncoderParams will be set
  1292. // depends on the user selection. Default is NULL
  1293. rCode = g_pImage->Save(namestr, &tempClsID, g_pEncoderParams);
  1294. free(g_pEncoderParams);
  1295. g_pEncoderParams = NULL;
  1296. if ( (rCode != Ok) && (rCode != NotImplemented) )
  1297. {
  1298. VERBOSE(("StartSaveImage--SaveToFile() failed\n"));
  1299. return FALSE;
  1300. }
  1301. return TRUE;
  1302. }
  1303. else
  1304. {
  1305. VERBOSE(("StartSaveImage(): No image to save\n"));
  1306. return FALSE;
  1307. }
  1308. }// StartSaveImage()
  1309. BOOL
  1310. SaveCurrentFrame()
  1311. {
  1312. GUID guid = FRAMEDIM_PAGE;
  1313. if ( NULL == g_pImage )
  1314. {
  1315. VERBOSE(("SaveCurrentFrame(): No image available\n"));
  1316. return FALSE;
  1317. }
  1318. Status rCode = Ok;
  1319. // Append the current frame
  1320. ULONG flagValueLastFrame = EncoderValueLastFrame;
  1321. ULONG flagValueDim = EncoderValueFrameDimensionPage;
  1322. EncoderParameters* pMyEncoderParams = (EncoderParameters*)malloc
  1323. (2 * sizeof(EncoderParameters));
  1324. pMyEncoderParams->Parameter[0].Guid = EncoderSaveFlag;
  1325. pMyEncoderParams->Parameter[0].Type = EncoderParameterValueTypeLong;
  1326. pMyEncoderParams->Parameter[0].NumberOfValues = 1;
  1327. pMyEncoderParams->Parameter[0].Value = (VOID*)&flagValueDim;
  1328. #if 0
  1329. pMyEncoderParams->Parameter[1].Guid = EncoderSaveFlag;
  1330. pMyEncoderParams->Parameter[1].Type = EncoderParameterValueTypeLong;
  1331. pMyEncoderParams->Parameter[1].NumberOfValues = 1;
  1332. pMyEncoderParams->Parameter[1].Value = (VOID*)& flagValueLastFrame;
  1333. pMyEncoderParams->Count = 2;
  1334. #endif
  1335. pMyEncoderParams->Count = 1;
  1336. #if 1
  1337. rCode = g_pImage->SaveAdd(pMyEncoderParams);
  1338. free(pMyEncoderParams);
  1339. if ( (rCode != Ok) && (rCode != NotImplemented) )
  1340. {
  1341. VERBOSE(("SaveAdd() failed\n"));
  1342. return FALSE;
  1343. }
  1344. #else // Save append testing
  1345. WCHAR *filename = L"x:/foo.jpg";
  1346. Image* newImage = new Image(filename);
  1347. rCode = g_pImage->SaveAdd(newImage, pMyEncoderParams);
  1348. delete newImage;
  1349. if ( (rCode != Ok) && (rCode != NotImplemented) )
  1350. {
  1351. VERBOSE(("SaveAppend() failed\n"));
  1352. return FALSE;
  1353. }
  1354. #endif
  1355. return TRUE;
  1356. }// SaveCurrentFrame()
  1357. VOID
  1358. CleanUp()
  1359. {
  1360. // Clean up before quit
  1361. if ( NULL != g_pImage )
  1362. {
  1363. delete g_pImage;
  1364. g_pImage = NULL;
  1365. }
  1366. if ( NULL != g_pDrawAttrib )
  1367. {
  1368. delete g_pDrawAttrib;
  1369. g_pDrawAttrib = NULL;
  1370. }
  1371. if ( NULL != g_pDestPoints )
  1372. {
  1373. delete g_pDestPoints;
  1374. g_pDestPoints = NULL;
  1375. }
  1376. }// CleanUp()
  1377. VOID
  1378. DoNextPage()
  1379. {
  1380. g_iCurrentPageIndex++;
  1381. // Check if we already at the last page of the image
  1382. // Note: g_iCurrentPageIndex is 0 based. So the max page index we can reach
  1383. // is g_uiTotalPages - 1
  1384. if ( g_iCurrentPageIndex >= (INT)g_uiTotalPages )
  1385. {
  1386. g_iCurrentPageIndex = g_uiTotalPages - 1;
  1387. }
  1388. // Display current page
  1389. SetCurrentPage();
  1390. }// DoNextPage()
  1391. VOID
  1392. DoPreviousPage()
  1393. {
  1394. g_iCurrentPageIndex--;
  1395. if ( g_iCurrentPageIndex < 0 )
  1396. {
  1397. g_iCurrentPageIndex = 0;
  1398. }
  1399. // Display current page
  1400. SetCurrentPage();
  1401. }// DoPreviousPage()
  1402. VOID
  1403. DoAnimated()
  1404. {
  1405. if ( g_uiTotalPages < 2 )
  1406. {
  1407. return;
  1408. }
  1409. // Reset the page to the first page
  1410. g_iCurrentPageIndex = 0;
  1411. // Display current page
  1412. SetCurrentPage();
  1413. SetTimer(g_hwndMain, 0, g_uiDelay * 10, NULL);
  1414. }// DoNextPage()
  1415. VOID
  1416. DoSave(
  1417. HWND hwnd
  1418. )
  1419. {
  1420. OPENFILENAME ofn;
  1421. CHAR filename[MAX_PATH];
  1422. ZeroMemory(&ofn, sizeof(ofn));
  1423. ofn.lStructSize = sizeof(ofn);
  1424. ofn.hwndOwner = hwnd;
  1425. ofn.hInstance = g_hAppInstance;
  1426. ofn.lpstrFile = filename;
  1427. ofn.nMaxFile = MAX_PATH;
  1428. ofn.lpstrTitle = "Save Image File";
  1429. ofn.lpstrInitialDir = ".";
  1430. ofn.Flags = OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT;
  1431. filename[0] = '\0';
  1432. // Make up the file type filter string
  1433. ImageCodecInfo* codecs;
  1434. UINT count;
  1435. GpStatus status;
  1436. UINT cbCodecs = 0;
  1437. GetImageEncodersSize(&count, &cbCodecs);
  1438. codecs = static_cast<ImageCodecInfo *>(malloc (cbCodecs));
  1439. if (codecs == NULL)
  1440. {
  1441. return;
  1442. }
  1443. status = GetImageEncoders(count, cbCodecs, codecs);
  1444. if (status != Ok)
  1445. {
  1446. return;
  1447. }
  1448. CHAR* filter = MakeFilterFromCodecs(count, codecs, FALSE);
  1449. if ( !filter )
  1450. {
  1451. VERBOSE(("DoSave---MakeFilterFromCodecs() failed\n"));
  1452. }
  1453. else
  1454. {
  1455. ofn.lpstrFilter = filter;
  1456. // Present the file/save dialog
  1457. if ( GetSaveFileName(&ofn) )
  1458. {
  1459. INT iIndex = ofn.nFilterIndex;
  1460. if ( (iIndex < 0) || (iIndex > (INT)count) )
  1461. {
  1462. iIndex = 0;
  1463. }
  1464. else
  1465. {
  1466. iIndex--;
  1467. }
  1468. // Get the image encoder
  1469. if ( StartSaveImage(filename, &codecs[iIndex].Clsid) == FALSE )
  1470. {
  1471. // Fail to get an image encoder
  1472. return;
  1473. }
  1474. }
  1475. free(filter);
  1476. }// Filter != NULL
  1477. if (codecs)
  1478. {
  1479. free(codecs);
  1480. }
  1481. }// DoSave()
  1482. //
  1483. // Flip or rotate the image in memory
  1484. //
  1485. VOID
  1486. DoTransFlipRotate(
  1487. HWND hwnd,
  1488. INT menuCmd
  1489. )
  1490. {
  1491. switch ( menuCmd )
  1492. {
  1493. case IDM_TRANSFORM_HORIZONTALFLIP:
  1494. g_pImage->RotateFlip(RotateNoneFlipX);
  1495. break;
  1496. case IDM_TRANSFORM_VERTICALFLIP:
  1497. g_pImage->RotateFlip(RotateNoneFlipY);
  1498. break;
  1499. case IDM_TRANSFORM_ROTATE90:
  1500. g_pImage->RotateFlip(Rotate90FlipNone);
  1501. break;
  1502. case IDM_TRANSFORM_ROTATE180:
  1503. g_pImage->RotateFlip(Rotate180FlipNone);
  1504. break;
  1505. case IDM_TRANSFORM_ROTATE270:
  1506. g_pImage->RotateFlip(Rotate270FlipNone);
  1507. break;
  1508. default:
  1509. break;
  1510. }
  1511. UpdateImageInfo();
  1512. RefreshImageDisplay();
  1513. }
  1514. //
  1515. // Flip or rotate the image, just for effect. No change to the source image
  1516. //
  1517. VOID
  1518. DoFlipRotate(
  1519. HWND hwnd,
  1520. INT menuCmd
  1521. )
  1522. {
  1523. Matrix mat;
  1524. REAL tmpX, tmpY;
  1525. int i;
  1526. if ( g_pImage == NULL )
  1527. {
  1528. return;
  1529. }
  1530. Graphics* pGraphics = Graphics::FromHWND(hwnd);
  1531. if ( (g_DestPointCount != 4) && (g_pDestPoints != NULL) )
  1532. {
  1533. free(g_pDestPoints);
  1534. }
  1535. g_DestPointCount = 4;
  1536. if ( g_pDestPoints == NULL )
  1537. {
  1538. g_pDestPoints = (PointF*)malloc(g_DestPointCount * sizeof(PointF));
  1539. if ( g_pDestPoints == NULL )
  1540. {
  1541. return;
  1542. }
  1543. g_pDestPoints[0].X = 0; // top left
  1544. g_pDestPoints[0].Y = 0;
  1545. g_pDestPoints[1].X = (float)g_ImageWidth - 1; // top right
  1546. g_pDestPoints[1].Y = 0;
  1547. g_pDestPoints[2].X = 0; // bottom left
  1548. g_pDestPoints[2].Y = (float)g_ImageHeight - 1;
  1549. g_pDestPoints[3].X = (float)g_ImageWidth - 1; // bottom right
  1550. g_pDestPoints[3].Y = (float)g_ImageHeight - 1;
  1551. }
  1552. switch ( menuCmd )
  1553. {
  1554. case IDM_VIEW_HORIZONTALFLIP:
  1555. if ( ((g_pDestPoints[1].X - g_pDestPoints[0].X)
  1556. == (float)g_ImageWidth)
  1557. ||((g_pDestPoints[0].X - g_pDestPoints[1].X)
  1558. == (float)g_ImageWidth) )
  1559. {
  1560. tmpX = g_pDestPoints[0].X;
  1561. tmpY = g_pDestPoints[0].Y;
  1562. g_pDestPoints[0].X = g_pDestPoints[1].X;
  1563. g_pDestPoints[0].Y = g_pDestPoints[1].Y;
  1564. g_pDestPoints[1].X = tmpX;
  1565. g_pDestPoints[1].Y = tmpY;
  1566. tmpX = g_pDestPoints[3].X;
  1567. tmpY = g_pDestPoints[3].Y;
  1568. g_pDestPoints[3].X = g_pDestPoints[2].X;
  1569. g_pDestPoints[3].Y = g_pDestPoints[2].Y;
  1570. g_pDestPoints[2].X = tmpX;
  1571. g_pDestPoints[2].Y = tmpY;
  1572. }
  1573. else
  1574. {
  1575. tmpX = g_pDestPoints[0].X;
  1576. tmpY = g_pDestPoints[0].Y;
  1577. g_pDestPoints[0].X = g_pDestPoints[2].X;
  1578. g_pDestPoints[0].Y = g_pDestPoints[2].Y;
  1579. g_pDestPoints[2].X = tmpX;
  1580. g_pDestPoints[2].Y = tmpY;
  1581. tmpX = g_pDestPoints[3].X;
  1582. tmpY = g_pDestPoints[3].Y;
  1583. g_pDestPoints[3].X = g_pDestPoints[1].X;
  1584. g_pDestPoints[3].Y = g_pDestPoints[1].Y;
  1585. g_pDestPoints[1].X = tmpX;
  1586. g_pDestPoints[1].Y = tmpY;
  1587. }
  1588. break;
  1589. case IDM_VIEW_VERTICALFLIP:
  1590. if (((g_pDestPoints[1].X - g_pDestPoints[0].X) == (float)g_ImageWidth) ||
  1591. ((g_pDestPoints[0].X - g_pDestPoints[1].X) == (float)g_ImageWidth))
  1592. {
  1593. tmpX = g_pDestPoints[0].X;
  1594. tmpY = g_pDestPoints[0].Y;
  1595. g_pDestPoints[0].X = g_pDestPoints[2].X;
  1596. g_pDestPoints[0].Y = g_pDestPoints[2].Y;
  1597. g_pDestPoints[2].X = tmpX;
  1598. g_pDestPoints[2].Y = tmpY;
  1599. tmpX = g_pDestPoints[3].X;
  1600. tmpY = g_pDestPoints[3].Y;
  1601. g_pDestPoints[3].X = g_pDestPoints[1].X;
  1602. g_pDestPoints[3].Y = g_pDestPoints[1].Y;
  1603. g_pDestPoints[1].X = tmpX;
  1604. g_pDestPoints[1].Y = tmpY;
  1605. }
  1606. else
  1607. {
  1608. tmpX = g_pDestPoints[0].X;
  1609. tmpY = g_pDestPoints[0].Y;
  1610. g_pDestPoints[0].X = g_pDestPoints[1].X;
  1611. g_pDestPoints[0].Y = g_pDestPoints[1].Y;
  1612. g_pDestPoints[1].X = tmpX;
  1613. g_pDestPoints[1].Y = tmpY;
  1614. tmpX = g_pDestPoints[3].X;
  1615. tmpY = g_pDestPoints[3].Y;
  1616. g_pDestPoints[3].X = g_pDestPoints[2].X;
  1617. g_pDestPoints[3].Y = g_pDestPoints[2].Y;
  1618. g_pDestPoints[2].X = tmpX;
  1619. g_pDestPoints[2].Y = tmpY;
  1620. }
  1621. break;
  1622. case IDM_VIEW_ROTATE90:
  1623. if (((g_pDestPoints[1].X - g_pDestPoints[0].X) == (float)g_ImageWidth - 1) ||
  1624. ((g_pDestPoints[0].X - g_pDestPoints[1].X) == (float)g_ImageWidth - 1))
  1625. {
  1626. tmpX = g_pDestPoints[0].X;
  1627. tmpY = g_pDestPoints[0].Y;
  1628. g_pDestPoints[0].X = g_pDestPoints[1].X;
  1629. g_pDestPoints[0].Y = g_pDestPoints[1].Y;
  1630. g_pDestPoints[1].X = g_pDestPoints[3].X;
  1631. g_pDestPoints[1].Y = g_pDestPoints[3].Y;
  1632. g_pDestPoints[3].X = g_pDestPoints[2].X;
  1633. g_pDestPoints[3].Y = g_pDestPoints[2].Y;
  1634. g_pDestPoints[2].X = tmpX;
  1635. g_pDestPoints[2].Y = tmpY;
  1636. for (i=0;i<4;i++)
  1637. {
  1638. if (g_pDestPoints[i].X == (float)g_ImageWidth - 1)
  1639. {
  1640. g_pDestPoints[i].X = (float)g_ImageHeight - 1;
  1641. }
  1642. else if (g_pDestPoints[i].X == (float)g_ImageHeight - 1)
  1643. {
  1644. g_pDestPoints[i].X = (float)g_ImageWidth - 1;
  1645. }
  1646. if (g_pDestPoints[i].Y == (float)g_ImageWidth - 1)
  1647. {
  1648. g_pDestPoints[i].Y = (float)g_ImageHeight - 1;
  1649. }
  1650. else if (g_pDestPoints[i].Y == (float)g_ImageHeight - 1)
  1651. {
  1652. g_pDestPoints[i].Y = (float)g_ImageWidth - 1;
  1653. }
  1654. }
  1655. }
  1656. else
  1657. {
  1658. tmpX = g_pDestPoints[0].X;
  1659. tmpY = g_pDestPoints[0].Y;
  1660. g_pDestPoints[0].X = g_pDestPoints[1].X;
  1661. g_pDestPoints[0].Y = g_pDestPoints[1].Y;
  1662. g_pDestPoints[1].X = g_pDestPoints[3].X;
  1663. g_pDestPoints[1].Y = g_pDestPoints[3].Y;
  1664. g_pDestPoints[3].X = g_pDestPoints[2].X;
  1665. g_pDestPoints[3].Y = g_pDestPoints[2].Y;
  1666. g_pDestPoints[2].X = tmpX;
  1667. g_pDestPoints[2].Y = tmpY;
  1668. for (i=0;i<4;i++)
  1669. {
  1670. if (g_pDestPoints[i].X == (float)g_ImageWidth - 1)
  1671. {
  1672. g_pDestPoints[i].X = (float)g_ImageHeight - 1;
  1673. }
  1674. else if (g_pDestPoints[i].X == (float)g_ImageHeight - 1)
  1675. {
  1676. g_pDestPoints[i].X = (float)g_ImageWidth - 1;
  1677. }
  1678. if (g_pDestPoints[i].Y == (float)g_ImageWidth - 1)
  1679. {
  1680. g_pDestPoints[i].Y = (float)g_ImageHeight - 1;
  1681. }
  1682. else if (g_pDestPoints[i].Y == (float)g_ImageHeight - 1)
  1683. {
  1684. g_pDestPoints[i].Y = (float)g_ImageWidth - 1;
  1685. }
  1686. }
  1687. }
  1688. g_bRotated = !g_bRotated;
  1689. break;
  1690. case IDM_VIEW_ROTATE270:
  1691. if (((g_pDestPoints[1].X - g_pDestPoints[0].X) == (float)g_ImageWidth) ||
  1692. ((g_pDestPoints[0].X - g_pDestPoints[1].X) == (float)g_ImageWidth))
  1693. {
  1694. tmpX = g_pDestPoints[2].X;
  1695. tmpY = g_pDestPoints[2].Y;
  1696. g_pDestPoints[2].X = g_pDestPoints[3].X;
  1697. g_pDestPoints[2].Y = g_pDestPoints[3].Y;
  1698. g_pDestPoints[3].X = g_pDestPoints[1].X;
  1699. g_pDestPoints[3].Y = g_pDestPoints[1].Y;
  1700. g_pDestPoints[1].X = g_pDestPoints[0].X;
  1701. g_pDestPoints[1].Y = g_pDestPoints[0].Y;
  1702. g_pDestPoints[0].X = tmpX;
  1703. g_pDestPoints[0].Y = tmpY;
  1704. for (i=0;i<4;i++)
  1705. {
  1706. if (g_pDestPoints[i].X == (float)g_ImageWidth)
  1707. {
  1708. g_pDestPoints[i].X = (float)g_ImageHeight;
  1709. }
  1710. else if (g_pDestPoints[i].X == (float)g_ImageHeight)
  1711. {
  1712. g_pDestPoints[i].X = (float)g_ImageWidth;
  1713. }
  1714. if (g_pDestPoints[i].Y == (float)g_ImageWidth)
  1715. {
  1716. g_pDestPoints[i].Y = (float)g_ImageHeight;
  1717. }
  1718. else if (g_pDestPoints[i].Y == (float)g_ImageHeight)
  1719. {
  1720. g_pDestPoints[i].Y = (float)g_ImageWidth;
  1721. }
  1722. }
  1723. }
  1724. else
  1725. {
  1726. tmpX = g_pDestPoints[2].X;
  1727. tmpY = g_pDestPoints[2].Y;
  1728. g_pDestPoints[2].X = g_pDestPoints[3].X;
  1729. g_pDestPoints[2].Y = g_pDestPoints[3].Y;
  1730. g_pDestPoints[3].X = g_pDestPoints[1].X;
  1731. g_pDestPoints[3].Y = g_pDestPoints[1].Y;
  1732. g_pDestPoints[1].X = g_pDestPoints[0].X;
  1733. g_pDestPoints[1].Y = g_pDestPoints[0].Y;
  1734. g_pDestPoints[0].X = tmpX;
  1735. g_pDestPoints[0].Y = tmpY;
  1736. for (i=0;i<4;i++)
  1737. {
  1738. if (g_pDestPoints[i].X == (float)g_ImageWidth)
  1739. {
  1740. g_pDestPoints[i].X = (float)g_ImageHeight;
  1741. }
  1742. else if (g_pDestPoints[i].X == (float)g_ImageHeight)
  1743. {
  1744. g_pDestPoints[i].X = (float)g_ImageWidth;
  1745. }
  1746. if (g_pDestPoints[i].Y == (float)g_ImageWidth)
  1747. {
  1748. g_pDestPoints[i].Y = (float)g_ImageHeight;
  1749. }
  1750. else if (g_pDestPoints[i].Y == (float)g_ImageHeight)
  1751. {
  1752. g_pDestPoints[i].Y = (float)g_ImageWidth;
  1753. }
  1754. }
  1755. }
  1756. g_bRotated = !g_bRotated;
  1757. break;
  1758. }// switch ( menuCmd )
  1759. mat.TransformPoints(g_pDestPoints, g_DestPointCount);
  1760. RefreshImageDisplay();
  1761. delete pGraphics;
  1762. RefreshImageDisplay();
  1763. }// DoFlipRotate()
  1764. VOID
  1765. DoGetProperties(
  1766. VOID
  1767. )
  1768. {
  1769. UINT numOfProperty;
  1770. UINT itemSize;
  1771. PropertyItem* pBuffer = NULL;
  1772. PropertyItem* pTotalBuffer = NULL;
  1773. // Check how many property items in this image
  1774. numOfProperty = g_pImage->GetPropertyCount();
  1775. VERBOSE(("There are %d property items in image %s\n", numOfProperty,
  1776. g_acImageName));
  1777. // Get all the property ID list from the image
  1778. PROPID* pList = (PROPID*)malloc(numOfProperty * sizeof(PROPID));
  1779. if ( pList == NULL )
  1780. {
  1781. return;
  1782. }
  1783. Status rCode = g_pImage->GetPropertyIdList(numOfProperty, pList);
  1784. if ( (rCode != Ok) && (rCode != NotImplemented) )
  1785. {
  1786. VERBOSE(("GetPropertyIdList() failed\n"));
  1787. return;
  1788. }
  1789. //#define UNITTEST 0
  1790. #if defined(UNITTEST)
  1791. for ( int i = 0; i < (int)numOfProperty; ++i )
  1792. {
  1793. // Show Property ID
  1794. VERBOSE(("ID[%d] = 0x%x, (%d) ", i, pList[i], pList[i]));
  1795. // Check the size for this property item
  1796. itemSize = g_pImage->GetPropertyItemSize(pList[i]);
  1797. VERBOSE(("size = %d, ", itemSize));
  1798. // Allocate memory and get this property item
  1799. pBuffer = (PropertyItem*)malloc(itemSize);
  1800. if ( pBuffer == NULL )
  1801. {
  1802. return;
  1803. }
  1804. rCode = g_pImage->GetPropertyItem(pList[i], itemSize, pBuffer);
  1805. if ( (rCode != Ok) && (rCode != NotImplemented) )
  1806. {
  1807. VERBOSE(("GetPropertyItem() failed\n"));
  1808. return;
  1809. }
  1810. DisplayPropertyItem(pBuffer);
  1811. free(pBuffer);
  1812. // Test RemovePropertyItem()
  1813. rCode = g_pImage->RemovePropertyItem(pList[i]);
  1814. if ( (rCode != Ok) && (rCode != NotImplemented) )
  1815. {
  1816. VERBOSE(("RemovePropertyItem() failed\n"));
  1817. return;
  1818. }
  1819. }// Loop through the list
  1820. free(pList);
  1821. #endif
  1822. rCode = g_pImage->GetPropertySize(&itemSize, &numOfProperty);
  1823. if ( (rCode != Ok) && (rCode != NotImplemented) )
  1824. {
  1825. VERBOSE(("GetPropertySize() failed\n"));
  1826. return;
  1827. }
  1828. pTotalBuffer = (PropertyItem*)malloc(itemSize);
  1829. rCode = g_pImage->GetAllPropertyItems(itemSize, numOfProperty,
  1830. pTotalBuffer);
  1831. if ( (rCode != Ok) && (rCode != NotImplemented) )
  1832. {
  1833. VERBOSE(("GetAllPropertyItems() failed\n"));
  1834. return;
  1835. }
  1836. PropertyItem* pTemp = pTotalBuffer;
  1837. for ( int j = 0; j < (int)numOfProperty; ++j )
  1838. {
  1839. DisplayPropertyItem(pTemp);
  1840. pTemp++;
  1841. }
  1842. free(pTotalBuffer);
  1843. }// DoGetProperties()
  1844. VOID
  1845. DoViewThumbnail()
  1846. {
  1847. // Get build in thumbnail
  1848. Image* pThumbImage = g_pImage->GetThumbnailImage(0, 0);
  1849. if ( pThumbImage == NULL )
  1850. {
  1851. VERBOSE(("Image %s doesn't have a thumbnail\n", g_acImageName));
  1852. return;
  1853. }
  1854. if ( NULL != g_pImage )
  1855. {
  1856. delete g_pImage;
  1857. }
  1858. g_pImage = pThumbImage;
  1859. UpdateImageInfo();
  1860. g_dScale = 1;
  1861. RefreshImageDisplay();
  1862. }// DoViewThumbnail()
  1863. VOID
  1864. DoChannelView(
  1865. INT menuCmd
  1866. )
  1867. {
  1868. if ( g_pDrawAttrib != NULL )
  1869. {
  1870. delete g_pDrawAttrib;
  1871. }
  1872. g_pDrawAttrib = new ImageAttributes();
  1873. switch ( menuCmd )
  1874. {
  1875. case IDM_VIEW_CHANNEL_C:
  1876. g_pDrawAttrib->SetOutputChannel(ColorChannelFlagsC);
  1877. break;
  1878. case IDM_VIEW_CHANNEL_M:
  1879. g_pDrawAttrib->SetOutputChannel(ColorChannelFlagsM);
  1880. break;
  1881. case IDM_VIEW_CHANNEL_Y:
  1882. g_pDrawAttrib->SetOutputChannel(ColorChannelFlagsY);
  1883. break;
  1884. case IDM_VIEW_CHANNEL_K:
  1885. g_pDrawAttrib->SetOutputChannel(ColorChannelFlagsK);
  1886. break;
  1887. default:
  1888. return;
  1889. }
  1890. RefreshImageDisplay();
  1891. return;
  1892. }// DoChannelView()
  1893. VOID
  1894. DisplayImageInfo()
  1895. {
  1896. VERBOSE(("\nInformation for frame %d of Image %s\n",
  1897. g_iCurrentPageIndex + 1, g_acImageName));
  1898. VERBOSE(("--------------------------------\n"));
  1899. VERBOSE(("Width = %d\n", g_ImageWidth));
  1900. VERBOSE(("Height = %d\n", g_ImageHeight));
  1901. if ( g_ImageFlags & IMGFLAG_HASREALPIXELSIZE )
  1902. {
  1903. VERBOSE(("---The pixel size info is from the original image\n"));
  1904. }
  1905. else
  1906. {
  1907. VERBOSE(("---The pixel size info is NOT from the original image\n"));
  1908. }
  1909. switch ( g_ImagePixelFormat )
  1910. {
  1911. case PIXFMT_1BPP_INDEXED:
  1912. VERBOSE(("Color depth: 1 BPP INDEXED\n"));
  1913. break;
  1914. case PIXFMT_4BPP_INDEXED:
  1915. VERBOSE(("Color depth: 4 BPP INDEXED\n"));
  1916. break;
  1917. case PIXFMT_8BPP_INDEXED:
  1918. VERBOSE(("Color depth: 8 BPP INDEXED\n"));
  1919. break;
  1920. case PIXFMT_16BPP_GRAYSCALE:
  1921. VERBOSE(("Color depth: 16 BPP GRAY SCALE\n"));
  1922. break;
  1923. case PIXFMT_16BPP_RGB555:
  1924. VERBOSE(("Color depth: 16 BPP RGB 555\n"));
  1925. break;
  1926. case PIXFMT_16BPP_RGB565:
  1927. VERBOSE(("Color depth: 16 BPP RGB 565\n"));
  1928. break;
  1929. case PIXFMT_16BPP_ARGB1555:
  1930. VERBOSE(("Color depth: 16 BPP ARGB 1555\n"));
  1931. break;
  1932. case PIXFMT_24BPP_RGB:
  1933. VERBOSE(("Color depth: 24 BPP RGB\n"));
  1934. break;
  1935. case PIXFMT_32BPP_RGB:
  1936. VERBOSE(("Color depth: 32 BPP RGB\n"));
  1937. break;
  1938. case PIXFMT_32BPP_ARGB:
  1939. VERBOSE(("Color depth: 32 BPP ARGB\n"));
  1940. break;
  1941. case PIXFMT_32BPP_PARGB:
  1942. VERBOSE(("Color depth: 32 BPP PARGB\n"));
  1943. break;
  1944. case PIXFMT_48BPP_RGB:
  1945. VERBOSE(("Color depth: 48 BPP PARGB\n"));
  1946. break;
  1947. case PIXFMT_64BPP_ARGB:
  1948. VERBOSE(("Color depth: 64 BPP ARGB\n"));
  1949. break;
  1950. case PIXFMT_64BPP_PARGB:
  1951. VERBOSE(("Color depth: 64 BPP PARGB\n"));
  1952. break;
  1953. default:
  1954. break;
  1955. }// Color format
  1956. VERBOSE(("X DPI (dots per inch) = %f\n", g_ImageXDpi));
  1957. VERBOSE(("Y DPI (dots per inch) = %f\n", g_ImageYDpi));
  1958. if ( g_ImageFlags & IMGFLAG_HASREALDPI )
  1959. {
  1960. VERBOSE(("---The DPI info is from the original image\n"));
  1961. }
  1962. else
  1963. {
  1964. VERBOSE(("---The DPI info is NOT from the original image\n"));
  1965. }
  1966. // Parse image info flags
  1967. if ( g_ImageFlags & SINKFLAG_HASALPHA )
  1968. {
  1969. VERBOSE(("This image contains alpha pixels\n"));
  1970. if ( g_ImageFlags & IMGFLAG_HASTRANSLUCENT )
  1971. {
  1972. VERBOSE(("---It has non-0 and 1 alpha pixels (TRANSLUCENT)\n"));
  1973. }
  1974. }
  1975. else
  1976. {
  1977. VERBOSE(("This image does not contain alpha pixels\n"));
  1978. }
  1979. // Figure out origianl file format
  1980. if ( g_ImageRawDataFormat == IMGFMT_MEMORYBMP )
  1981. {
  1982. VERBOSE(("RawDataFormat is MEMORYBMP\n"));
  1983. }
  1984. else if ( g_ImageRawDataFormat == IMGFMT_BMP )
  1985. {
  1986. VERBOSE(("RawDataFormat is BMP\n"));
  1987. }
  1988. else if ( g_ImageRawDataFormat == IMGFMT_EMF )
  1989. {
  1990. VERBOSE(("RawDataFormat is EMF\n"));
  1991. }
  1992. else if ( g_ImageRawDataFormat == IMGFMT_WMF )
  1993. {
  1994. VERBOSE(("RawDataFormat is WMF\n"));
  1995. }
  1996. else if ( g_ImageRawDataFormat == IMGFMT_JPEG )
  1997. {
  1998. VERBOSE(("RawDataFormat is JPEG\n"));
  1999. }
  2000. else if ( g_ImageRawDataFormat == IMGFMT_PNG )
  2001. {
  2002. VERBOSE(("RawDataFormat is PNG\n"));
  2003. }
  2004. else if ( g_ImageRawDataFormat == IMGFMT_GIF )
  2005. {
  2006. VERBOSE(("RawDataFormat is GIF\n"));
  2007. }
  2008. else if ( g_ImageRawDataFormat == IMGFMT_TIFF )
  2009. {
  2010. VERBOSE(("RawDataFormat is TIFF\n"));
  2011. }
  2012. else if ( g_ImageRawDataFormat == IMGFMT_EXIF )
  2013. {
  2014. VERBOSE(("RawDataFormat is EXIF\n"));
  2015. }
  2016. else if ( g_ImageRawDataFormat == IMGFMT_ICO )
  2017. {
  2018. VERBOSE(("RawDataFormat is ICO\n"));
  2019. }
  2020. else if ( g_ImageRawDataFormat == IMGFMT_PHOTOCD )
  2021. {
  2022. VERBOSE(("RawDataFormat is PHOTOCD\n"));
  2023. }
  2024. else if ( g_ImageRawDataFormat == IMGFMT_FLASHPIX )
  2025. {
  2026. VERBOSE(("RawDataFormat is FLASHPIX\n"));
  2027. }
  2028. else
  2029. {
  2030. VERBOSE(("RawDataFormat is UNDEFINED\n"));
  2031. }
  2032. // Figure out origianl color space
  2033. if ( g_ImageFlags & IMGFLAG_COLORSPACE_RGB )
  2034. {
  2035. VERBOSE(("This image is in RGB color space\n"));
  2036. }
  2037. else if ( g_ImageFlags & IMGFLAG_COLORSPACE_CMYK )
  2038. {
  2039. VERBOSE(("This image is in CMYK color space\n"));
  2040. }
  2041. else if ( g_ImageFlags & IMGFLAG_COLORSPACE_GRAY )
  2042. {
  2043. VERBOSE(("This image is a gray scale image\n"));
  2044. }
  2045. else if ( g_ImageFlags & IMGFLAG_COLORSPACE_YCCK )
  2046. {
  2047. VERBOSE(("This image is in YCCK color space\n"));
  2048. }
  2049. else if ( g_ImageFlags & IMGFLAG_COLORSPACE_YCBCR )
  2050. {
  2051. VERBOSE(("This image is in YCBCR color space\n"));
  2052. }
  2053. }// DisplayImageInfo()
  2054. //
  2055. // Convert the current image to a bitmap
  2056. //
  2057. VOID
  2058. DoConvertToBitmap(
  2059. HWND hwnd,
  2060. INT menuCmd
  2061. )
  2062. {
  2063. // Map menu selection to its corresponding pixel format
  2064. PixelFormatID pixfmt;
  2065. switch (menuCmd)
  2066. {
  2067. case IDM_CONVERT_8BIT:
  2068. pixfmt = PIXFMT_8BPP_INDEXED;
  2069. break;
  2070. case IDM_CONVERT_16BITRGB555:
  2071. pixfmt = PIXFMT_16BPP_RGB555;
  2072. break;
  2073. case IDM_CONVERT_16BITRGB565:
  2074. pixfmt = PIXFMT_16BPP_RGB565;
  2075. break;
  2076. case IDM_CONVERT_24BITRGB:
  2077. pixfmt = PIXFMT_24BPP_RGB;
  2078. break;
  2079. case IDM_CONVERT_32BITRGB:
  2080. pixfmt = PIXFMT_32BPP_RGB;
  2081. break;
  2082. case IDM_CONVERT_32BITARGB:
  2083. default:
  2084. pixfmt = PIXFMT_32BPP_ARGB;
  2085. break;
  2086. }
  2087. // Convert the current image to a bitmap image
  2088. if ( g_pImage != NULL )
  2089. {
  2090. Bitmap* pNewBmp = ((Bitmap*)g_pImage)->Clone(0, 0, g_ImageWidth,
  2091. g_ImageHeight, pixfmt);
  2092. if ( pNewBmp == NULL )
  2093. {
  2094. VERBOSE(("Clone failed in DoConvertToBitmap()\n"));
  2095. return;
  2096. }
  2097. //Release the old one
  2098. if ( g_pImage != NULL )
  2099. {
  2100. delete g_pImage;
  2101. }
  2102. g_pImage = (Image*)pNewBmp;
  2103. }
  2104. RefreshImageDisplay();
  2105. }// DoConvertToBitmap()
  2106. //
  2107. // Crop the image
  2108. //
  2109. // NOTE: We're not spending time here to do a fancy UI.
  2110. // So we'll just inset the image by 5 pixels each time.
  2111. //
  2112. VOID
  2113. DoCrop(
  2114. HWND hwnd
  2115. )
  2116. {
  2117. if ( g_SourceWidth == 0 )
  2118. {
  2119. // initialize global source width and height if not previously
  2120. // initialized
  2121. if ( g_pImage == NULL )
  2122. {
  2123. return;
  2124. }
  2125. g_SourceWidth = (REAL)g_ImageWidth;
  2126. g_SourceHeight = (REAL)g_ImageHeight;
  2127. }
  2128. // check to make sure source image is still at least one pixel big
  2129. if ( (g_SourceWidth - g_SourceX) > 11 )
  2130. {
  2131. g_SourceX += 10;
  2132. }
  2133. if ( (g_SourceHeight - g_SourceY) > 11 )
  2134. {
  2135. g_SourceY += 10;
  2136. }
  2137. if ( (g_SourceWidth - g_SourceX) > 6 )
  2138. {
  2139. g_SourceWidth -= 5;
  2140. }
  2141. if ( (g_SourceHeight - g_SourceY) > 6 )
  2142. {
  2143. g_SourceHeight -= 5;
  2144. }
  2145. RefreshImageDisplay();
  2146. }// DoCrop()
  2147. void
  2148. DoRender()
  2149. {
  2150. // Check if we have anything special for drawing
  2151. if ( (g_pDrawAttrib == NULL) && (g_pDestPoints == NULL) )
  2152. {
  2153. // Nothing special, we don't need "render"
  2154. return;
  2155. }
  2156. Bitmap* pNewBitmap = NULL;
  2157. // Create a Graphics object from this memory DC and draw onto it
  2158. if ( g_bRotated == TRUE )
  2159. {
  2160. pNewBitmap = new Bitmap(g_ImageHeight,
  2161. g_ImageWidth,
  2162. PIXFMT_32BPP_ARGB);
  2163. }
  2164. else
  2165. {
  2166. pNewBitmap = new Bitmap(g_ImageWidth,
  2167. g_ImageHeight,
  2168. PIXFMT_32BPP_ARGB);
  2169. }
  2170. if ( pNewBitmap == NULL )
  2171. {
  2172. return;
  2173. }
  2174. Graphics* pGraphics = new Graphics(pNewBitmap);
  2175. REAL rWidth = (REAL)g_ImageWidth;
  2176. REAL rHeight = (REAL)g_ImageHeight;
  2177. if ( g_SourceWidth != 0 )
  2178. {
  2179. rWidth = g_SourceWidth;
  2180. }
  2181. if ( g_SourceHeight != 0 )
  2182. {
  2183. rHeight = g_SourceHeight;
  2184. }
  2185. if ( g_pDestPoints != NULL )
  2186. {
  2187. pGraphics->DrawImage(g_pImage,
  2188. g_pDestPoints,
  2189. 3, // Should use g_DestPointCount,
  2190. g_SourceX,
  2191. g_SourceY,
  2192. rWidth,
  2193. rHeight,
  2194. UnitPixel,
  2195. g_pDrawAttrib,
  2196. NULL,
  2197. NULL);
  2198. }
  2199. else
  2200. {
  2201. Rect dstRect(0, 0, g_ImageWidth, g_ImageHeight);
  2202. pGraphics->DrawImage(g_pImage,
  2203. dstRect,
  2204. (INT)g_SourceX,
  2205. (INT)g_SourceY,
  2206. (INT)rWidth,
  2207. (INT)rHeight,
  2208. UnitPixel,
  2209. g_pDrawAttrib,
  2210. NULL,
  2211. NULL);
  2212. }
  2213. if ( g_pImage != NULL )
  2214. {
  2215. delete g_pImage;
  2216. }
  2217. g_pImage = (Image*)pNewBitmap;
  2218. delete pGraphics;
  2219. // Clear up all the drawing special attributes since we have already done
  2220. // the render
  2221. if ( g_pDrawAttrib != NULL )
  2222. {
  2223. delete g_pDrawAttrib;
  2224. g_pDrawAttrib = NULL;
  2225. }
  2226. if ( g_pDestPoints != NULL )
  2227. {
  2228. delete g_pDestPoints;
  2229. g_pDestPoints = NULL;
  2230. g_DestPointCount = 0;
  2231. }
  2232. RefreshImageDisplay();
  2233. }// DoRender()
  2234. VOID
  2235. DoICM()
  2236. {
  2237. HMENU hMenu = GetMenu(g_hwndMain);
  2238. UINT ulRC = GetMenuState(hMenu, IDM_EFFECT_ICC, MF_BYCOMMAND);
  2239. if ( ulRC == MF_CHECKED )
  2240. {
  2241. // Turn ICM off
  2242. CheckMenuItem(hMenu, IDM_EFFECT_ICC, MF_BYCOMMAND | MF_UNCHECKED);
  2243. // Check if we loaded the image with ICM on or off
  2244. if ( g_LoadImageWithICM == TRUE )
  2245. {
  2246. // The image we loaded is ICM converted. We need to through it
  2247. // away and load a new one without the convertion
  2248. g_LoadImageWithICM = FALSE;
  2249. OpenImageFile(g_acImageName);
  2250. }
  2251. }
  2252. else
  2253. {
  2254. // Turn ICM on
  2255. CheckMenuItem(hMenu, IDM_EFFECT_ICC, MF_BYCOMMAND | MF_CHECKED);
  2256. // Check if we loaded the image with ICM on or off
  2257. if ( g_LoadImageWithICM == FALSE )
  2258. {
  2259. // The image we loaded without ICM converted. We need to through
  2260. // it away and load a new one with the convertion
  2261. g_LoadImageWithICM = TRUE;
  2262. OpenImageFile(g_acImageName);
  2263. }
  2264. }
  2265. }// DoICM()
  2266. VOID
  2267. DoGamma()
  2268. {
  2269. // Set gamma
  2270. if ( g_pDrawAttrib == NULL )
  2271. {
  2272. g_pDrawAttrib = new ImageAttributes();
  2273. }
  2274. REAL rGamma = 1.5;
  2275. g_pDrawAttrib->SetGamma(rGamma);
  2276. }
  2277. VOID
  2278. DoMenuCommand(
  2279. HWND hwnd,
  2280. INT menuCmd
  2281. )
  2282. {
  2283. HMENU hMenu = GetMenu(g_hwndMain);
  2284. switch ( menuCmd )
  2285. {
  2286. case IDM_FILE_OPEN:
  2287. // Before we open a new image. We need be sure we have done the save
  2288. // for previous image
  2289. CleanUp();
  2290. // Now open a new image
  2291. DoOpen(hwnd);
  2292. break;
  2293. case IDM_FILE_SAVE:
  2294. DoSave(hwnd);
  2295. break;
  2296. case IDM_FILE_SAVEFRAME:
  2297. // Save the current frame
  2298. SaveCurrentFrame();
  2299. break;
  2300. case IDM_FILE_PRINT:
  2301. DoPrint(hwnd);
  2302. break;
  2303. case IDM_VIEW_NEXTPAGE:
  2304. DoNextPage();
  2305. break;
  2306. case IDM_VIEW_PREVIOUSPAGE:
  2307. DoPreviousPage();
  2308. break;
  2309. case IDM_VIEW_ANIMATED:
  2310. DoAnimated();
  2311. break;
  2312. case IDM_VIEW_THUMBNAIL:
  2313. DoViewThumbnail();
  2314. break;
  2315. case IDM_VIEW_CHANNEL_C:
  2316. case IDM_VIEW_CHANNEL_M:
  2317. case IDM_VIEW_CHANNEL_Y:
  2318. case IDM_VIEW_CHANNEL_K:
  2319. case IDM_VIEW_CHANNEL_R:
  2320. case IDM_VIEW_CHANNEL_G:
  2321. case IDM_VIEW_CHANNEL_B:
  2322. case IDM_VIEW_CHANNEL_L:
  2323. DoChannelView(menuCmd);
  2324. break;
  2325. case IDM_VIEW_ZOOM_IN:
  2326. g_dScale = g_dScale * 2;
  2327. g_fFitToWindow_w = FALSE;
  2328. g_fFitToWindow_h = FALSE;
  2329. RefreshImageDisplay();
  2330. break;
  2331. case IDM_VIEW_ZOOM_OUT:
  2332. g_dScale = g_dScale / 2;
  2333. g_fFitToWindow_w = FALSE;
  2334. g_fFitToWindow_h = FALSE;
  2335. CheckMenuItem(hMenu, IDM_VIEW_ZOOM_FITWINDOW_W,
  2336. MF_BYCOMMAND | MF_UNCHECKED);
  2337. CheckMenuItem(hMenu, IDM_VIEW_ZOOM_FITWINDOW_H,
  2338. MF_BYCOMMAND | MF_UNCHECKED);
  2339. RefreshImageDisplay();
  2340. break;
  2341. case IDM_VIEW_ZOOM_FITWINDOW_W:
  2342. g_dScale = (REAL)g_iWinWidth / g_ImageWidth;
  2343. g_fFitToWindow_w = TRUE;
  2344. g_fFitToWindow_h = FALSE;
  2345. ToggleScaleFactorMenu(IDM_VIEW_ZOOM_FITWINDOW_W, GetMenu(g_hwndMain));
  2346. RefreshImageDisplay();
  2347. break;
  2348. case IDM_VIEW_ZOOM_FITWINDOW_H:
  2349. g_dScale = (REAL)g_iWinHeight / g_ImageHeight;
  2350. g_fFitToWindow_h = TRUE;
  2351. g_fFitToWindow_w = FALSE;
  2352. ToggleScaleFactorMenu(IDM_VIEW_ZOOM_FITWINDOW_H, GetMenu(g_hwndMain));
  2353. RefreshImageDisplay();
  2354. break;
  2355. case IDM_VIEW_ZOOM_REALSIZE:
  2356. g_dScale = 1.0;
  2357. g_fFitToWindow_w = FALSE;
  2358. g_fFitToWindow_h = FALSE;
  2359. ToggleScaleFactorMenu(IDM_VIEW_ZOOM_REALSIZE, GetMenu(g_hwndMain));
  2360. RefreshImageDisplay();
  2361. break;
  2362. case IDM_VIEW_OPTION_BILINEAR:
  2363. g_InterpolationMode = InterpolationModeBilinear;
  2364. ToggleScaleOptionMenu(IDM_VIEW_OPTION_BILINEAR, GetMenu(g_hwndMain));
  2365. RefreshImageDisplay();
  2366. break;
  2367. case IDM_VIEW_OPTION_BICUBIC:
  2368. g_InterpolationMode = InterpolationModeBicubic;
  2369. ToggleScaleOptionMenu(IDM_VIEW_OPTION_BICUBIC, GetMenu(g_hwndMain));
  2370. RefreshImageDisplay();
  2371. break;
  2372. case IDM_VIEW_OPTION_NEARESTNEIGHBOR:
  2373. g_InterpolationMode = InterpolationModeNearestNeighbor;
  2374. ToggleScaleOptionMenu(IDM_VIEW_OPTION_NEARESTNEIGHBOR,
  2375. GetMenu(g_hwndMain));
  2376. RefreshImageDisplay();
  2377. break;
  2378. case IDM_VIEW_OPTION_HIGHLINEAR:
  2379. g_InterpolationMode = InterpolationModeHighQualityBilinear;
  2380. ToggleScaleOptionMenu(IDM_VIEW_OPTION_HIGHLINEAR, GetMenu(g_hwndMain));
  2381. RefreshImageDisplay();
  2382. break;
  2383. case IDM_VIEW_OPTION_HIGHCUBIC:
  2384. g_InterpolationMode = InterpolationModeHighQualityBicubic;
  2385. ToggleScaleOptionMenu(IDM_VIEW_OPTION_HIGHCUBIC, GetMenu(g_hwndMain));
  2386. RefreshImageDisplay();
  2387. break;
  2388. case IDM_VIEW_OPTION_WRAPMODETILE:
  2389. g_WrapMode = WrapModeTile;
  2390. g_pDrawAttrib->SetWrapMode(g_WrapMode, Color(0), FALSE);
  2391. ToggleWrapModeOptionMenu(IDM_VIEW_OPTION_WRAPMODETILE,
  2392. GetMenu(g_hwndMain));
  2393. RefreshImageDisplay();
  2394. break;
  2395. case IDM_VIEW_OPTION_WRAPMODEFLIPX:
  2396. g_WrapMode = WrapModeTileFlipX;
  2397. g_pDrawAttrib->SetWrapMode(g_WrapMode, Color(0), FALSE);
  2398. ToggleWrapModeOptionMenu(IDM_VIEW_OPTION_WRAPMODEFLIPX,
  2399. GetMenu(g_hwndMain));
  2400. RefreshImageDisplay();
  2401. break;
  2402. case IDM_VIEW_OPTION_WRAPMODEFLIPY:
  2403. g_WrapMode = WrapModeTileFlipY;
  2404. g_pDrawAttrib->SetWrapMode(g_WrapMode, Color(0), FALSE);
  2405. ToggleWrapModeOptionMenu(IDM_VIEW_OPTION_WRAPMODEFLIPY,
  2406. GetMenu(g_hwndMain));
  2407. RefreshImageDisplay();
  2408. break;
  2409. case IDM_VIEW_OPTION_WRAPMODEFLIPXY:
  2410. g_WrapMode = WrapModeTileFlipXY;
  2411. g_pDrawAttrib->SetWrapMode(g_WrapMode, Color(0), FALSE);
  2412. ToggleWrapModeOptionMenu(IDM_VIEW_OPTION_WRAPMODEFLIPXY,
  2413. GetMenu(g_hwndMain));
  2414. RefreshImageDisplay();
  2415. break;
  2416. case IDM_VIEW_OPTION_WRAPMODECLAMP0:
  2417. g_WrapMode = WrapModeClamp;
  2418. g_pDrawAttrib->SetWrapMode(g_WrapMode, Color(0), FALSE);
  2419. ToggleWrapModeOptionMenu(IDM_VIEW_OPTION_WRAPMODECLAMP0,
  2420. GetMenu(g_hwndMain));
  2421. RefreshImageDisplay();
  2422. break;
  2423. case IDM_VIEW_OPTION_WRAPMODECLAMPFF:
  2424. g_WrapMode = WrapModeClamp;
  2425. g_pDrawAttrib->SetWrapMode(g_WrapMode, Color(0xffff0000), FALSE);
  2426. ToggleWrapModeOptionMenu(IDM_VIEW_OPTION_WRAPMODECLAMPFF,
  2427. GetMenu(g_hwndMain));
  2428. RefreshImageDisplay();
  2429. break;
  2430. case IDM_VIEW_CROP:
  2431. DoCrop(hwnd);
  2432. break;
  2433. case IDM_VIEW_HORIZONTALFLIP:
  2434. case IDM_VIEW_VERTICALFLIP:
  2435. case IDM_VIEW_ROTATE90:
  2436. case IDM_VIEW_ROTATE270:
  2437. DoFlipRotate(hwnd, menuCmd);
  2438. break;
  2439. case IDM_TRANSFORM_HORIZONTALFLIP:
  2440. case IDM_TRANSFORM_VERTICALFLIP:
  2441. case IDM_TRANSFORM_ROTATE90:
  2442. case IDM_TRANSFORM_ROTATE180:
  2443. case IDM_TRANSFORM_ROTATE270:
  2444. DoTransFlipRotate(hwnd, menuCmd);
  2445. break;
  2446. case IDM_VIEW_ATTR_PROPERTY:
  2447. DoGetProperties();
  2448. break;
  2449. case IDM_VIEW_ATTR_INFO:
  2450. DisplayImageInfo();
  2451. break;
  2452. case IDM_FILE_RENDER:
  2453. DoRender();
  2454. break;
  2455. case IDM_FILE_QUIT:
  2456. CleanUp();
  2457. PostQuitMessage(0);
  2458. break;
  2459. case IDM_CONVERT_8BIT:
  2460. case IDM_CONVERT_16BITRGB555:
  2461. case IDM_CONVERT_16BITRGB565:
  2462. case IDM_CONVERT_24BITRGB:
  2463. case IDM_CONVERT_32BITRGB:
  2464. case IDM_CONVERT_32BITARGB:
  2465. DoConvertToBitmap(hwnd, menuCmd);
  2466. break;
  2467. case IDM_EFFECT_TRANSKEY:
  2468. // Popup a dialog to let user set up the transparent key
  2469. if ( ShowMyDialog((INT)IDD_COLORKEYDLG, g_hwndMain,
  2470. DecoderParamDlgProc) == FALSE )
  2471. {
  2472. return;
  2473. }
  2474. break;
  2475. case IDM_EFFECT_COLORMAP:
  2476. // Popup a dialog to let user set up the color map value
  2477. if ( ShowMyDialog((INT)IDD_COLORMAPDLG, g_hwndMain,
  2478. ColorMapDlgProc) == FALSE )
  2479. {
  2480. return;
  2481. }
  2482. break;
  2483. case IDM_EFFECT_ICC:
  2484. DoICM();
  2485. break;
  2486. case IDM_EFFECT_GAMMA:
  2487. DoGamma();
  2488. break;
  2489. case IDM_ANNOTATION_ANNOTATION:
  2490. // Popup a dialog to let user modify/add annotation
  2491. if ( ShowMyDialog((INT)IDD_ANNOTATIONDLG, g_hwndMain,
  2492. AnnotationDlgProc) == FALSE )
  2493. {
  2494. return;
  2495. }
  2496. break;
  2497. case IDM_ANNOTATION_SOFTWARE:
  2498. break;
  2499. case IDM_ANNOTATION_AUDIOFILE:
  2500. DoOpenAudioFile(hwnd);
  2501. }
  2502. }// DoMenuCommand()
  2503. void
  2504. DoMouseMove(
  2505. WPARAM wParam,
  2506. LPARAM lParam
  2507. )
  2508. {
  2509. if ( (wParam & MK_LBUTTON) && (g_pImage != NULL)
  2510. &&(g_ImageRawDataFormat != IMGFMT_EMF)
  2511. &&(g_ImageRawDataFormat != IMGFMT_WMF) )
  2512. {
  2513. int x = LOWORD(lParam);
  2514. int y = HIWORD(lParam);
  2515. char szAnsiMessage[256];
  2516. if ( (x >= 0) && (y >= 0)
  2517. && (x < (INT)g_ImageWidth) && ( y < (INT)g_ImageHeight) )
  2518. {
  2519. Color color;
  2520. ((Bitmap*)g_pImage)->GetPixel(x, y, &color);
  2521. sprintf(szAnsiMessage, "(%d, %d) (%d, %d, %d, %d)", x, y,
  2522. color.GetAlpha(), color.GetRed(), color.GetGreen(),
  2523. color.GetBlue());
  2524. }
  2525. else
  2526. {
  2527. sprintf(szAnsiMessage, "Out of image bounds");
  2528. }
  2529. SetWindowText(g_hwndStatus, szAnsiMessage);
  2530. }
  2531. return;
  2532. }// DoMouseMove()
  2533. //
  2534. // Window callback procedure
  2535. //
  2536. LRESULT CALLBACK
  2537. MyWindowProc(
  2538. HWND hwnd,
  2539. UINT iMsg,
  2540. WPARAM wParam,
  2541. LPARAM lParam
  2542. )
  2543. {
  2544. switch ( iMsg )
  2545. {
  2546. case WM_COMMAND:
  2547. DoMenuCommand(hwnd, LOWORD(wParam));
  2548. break;
  2549. case WM_KEYDOWN:
  2550. switch ( wParam )
  2551. {
  2552. case VK_NEXT:
  2553. // Page Down
  2554. DoNextPage();
  2555. break;
  2556. case VK_PRIOR:
  2557. // Page Up
  2558. DoPreviousPage();
  2559. break;
  2560. case VK_F1:
  2561. // F1 key for image info
  2562. UpdateImageInfo();
  2563. DisplayImageInfo();
  2564. break;
  2565. case VK_F2:
  2566. // F2 for property items
  2567. DoGetProperties();
  2568. break;
  2569. case VK_F3:
  2570. // F3 key for animation
  2571. DoAnimated();
  2572. break;
  2573. case VK_F4:
  2574. // F4 for ICM
  2575. DoICM();
  2576. break;
  2577. default:
  2578. return DefWindowProc(hwnd, iMsg, wParam, lParam);
  2579. }
  2580. break;
  2581. case WM_PAINT:
  2582. DoPaint(hwnd);
  2583. break;
  2584. case WM_SIZE:
  2585. g_iWinWidth = LOWORD(lParam);
  2586. g_iWinHeight = HIWORD(lParam);
  2587. if ( g_fFitToWindow_w == TRUE )
  2588. {
  2589. g_dScale = (REAL)g_iWinWidth / g_ImageWidth;
  2590. }
  2591. else if ( g_fFitToWindow_h == TRUE )
  2592. {
  2593. g_dScale = (REAL)g_iWinHeight / g_ImageHeight;
  2594. }
  2595. // Resize the status window
  2596. int x;
  2597. int y;
  2598. int cx;
  2599. int cy;
  2600. RECT rWindow;
  2601. // Keep status window height the same
  2602. GetWindowRect(g_hwndStatus, &rWindow);
  2603. cy = rWindow.bottom - rWindow.top;
  2604. x = 0;
  2605. y = g_iWinHeight - cy;
  2606. cx = g_iWinWidth;
  2607. MoveWindow(g_hwndStatus, x, y, cx, cy, TRUE);
  2608. SetWindowText(g_hwndStatus, "");
  2609. RefreshImageDisplay();
  2610. break;
  2611. case WM_MOUSEMOVE:
  2612. DoMouseMove(wParam, lParam);
  2613. break;
  2614. case WM_TIMER:
  2615. KillTimer(g_hwndMain, 0);
  2616. DoNextPage();
  2617. if ( (UINT)g_iCurrentPageIndex < (g_uiTotalPages - 1) )
  2618. {
  2619. // View the next frame
  2620. SetTimer(g_hwndMain, 0, g_uiDelay * 10, NULL);
  2621. }
  2622. break;
  2623. case WM_DESTROY:
  2624. CleanUp();
  2625. PostQuitMessage(0);
  2626. break;
  2627. default:
  2628. return DefWindowProc(hwnd, iMsg, wParam, lParam);
  2629. }
  2630. return 0;
  2631. }// MyWindowProc()
  2632. //
  2633. // Create main application window
  2634. //
  2635. VOID
  2636. CreateMainWindow(
  2637. int iX,
  2638. int iY,
  2639. int iWidth,
  2640. int iHeight
  2641. )
  2642. {
  2643. HBRUSH hBrush = CreateHatchBrush(HS_HORIZONTAL,
  2644. RGB(0, 200, 0));
  2645. // Register window class
  2646. WNDCLASS wndClass =
  2647. {
  2648. CS_HREDRAW|CS_VREDRAW,
  2649. MyWindowProc,
  2650. 0,
  2651. 0,
  2652. g_hAppInstance,
  2653. LoadIcon(NULL, IDI_APPLICATION),
  2654. LoadCursor(NULL, IDC_ARROW),
  2655. hBrush,
  2656. MAKEINTRESOURCE(IDR_MAINMENU),
  2657. MYWNDCLASSNAME
  2658. };
  2659. RegisterClass(&wndClass);
  2660. g_hwndMain = CreateWindow(MYWNDCLASSNAME,
  2661. MYWNDCLASSNAME,
  2662. WS_OVERLAPPEDWINDOW,
  2663. iX,
  2664. iY,
  2665. iWidth,
  2666. iHeight,
  2667. NULL,
  2668. NULL,
  2669. g_hAppInstance,
  2670. NULL);
  2671. g_hwndStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE,
  2672. (LPCSTR)"Ready",
  2673. g_hwndMain,
  2674. 2);
  2675. if ( !g_hwndMain || (!g_hwndStatus) )
  2676. {
  2677. VERBOSE(("CreateMainWindow---CreateStatusWindow() failed"));
  2678. exit(-1);
  2679. }
  2680. }// CreateMainWindow()
  2681. //
  2682. // Main program entrypoint
  2683. //
  2684. INT _cdecl
  2685. main(
  2686. int argc,
  2687. char* argv[]
  2688. )
  2689. {
  2690. if (!gGdiplusInitHelper.IsValid())
  2691. {
  2692. return 0;
  2693. }
  2694. // Parse input parameters
  2695. ValidateArguments(argc, argv);
  2696. g_hAppInstance = GetModuleHandle(NULL);
  2697. g_iCurrentPageIndex = 0;
  2698. // Create the main application window
  2699. CreateMainWindow(g_iWinX, g_iWinY, g_iWinWidth, g_iWinHeight);
  2700. // Open an image
  2701. if ( OpenImageFile(g_acImageName) == FALSE )
  2702. {
  2703. // The user probably didn't give us image name or a wrong image name
  2704. // Create our own background image now
  2705. CreateBackgroundBitmap();
  2706. }
  2707. // After OpenImageFile() and CreateBackgroundBitmap(), we
  2708. // should have an IImage obj which points to the current frame/page. If not,
  2709. // end application
  2710. ShowWindow(g_hwndMain, SW_SHOW);
  2711. HMENU hMenu = GetMenu(g_hwndMain);
  2712. CheckMenuItem(hMenu, IDM_VIEW_OPTION_HIGHCUBIC, MF_BYCOMMAND | MF_CHECKED);
  2713. ResetImageAttribute();
  2714. CheckMenuItem(hMenu, IDM_VIEW_OPTION_WRAPMODEFLIPXY,
  2715. MF_BYCOMMAND | MF_CHECKED);
  2716. // Turn ICM on
  2717. CheckMenuItem(hMenu, IDM_EFFECT_ICC, MF_BYCOMMAND | MF_CHECKED);
  2718. // Main message loop
  2719. MSG msg;
  2720. while (GetMessage(&msg, NULL, 0, 0))
  2721. {
  2722. TranslateMessage(&msg);
  2723. DispatchMessage(&msg);
  2724. }
  2725. return (INT)(msg.wParam);
  2726. }// main()
  2727. #if 0 // Set quality test
  2728. UINT uiSize = g_pImage->GetEncoderParameterListSize(&tempClsID);
  2729. EncoderParameters* pBuffer = (EncoderParameters*)malloc(uiSize);
  2730. rCode = g_pImage->GetEncoderParameterList(&tempClsID, uiSize,
  2731. pBuffer);
  2732. UINT qualityLevel = 50;
  2733. pMyEncoderParams->Parameter[0].Guid = EncoderQuality;
  2734. pMyEncoderParams->Parameter[0].Type = EncoderParameterValueTypeLong;
  2735. pMyEncoderParams->Parameter[0].NumberOfValues = 1;
  2736. pMyEncoderParams->Parameter[0].Value = (VOID*)&qualityLevel;
  2737. #endif
  2738. #if 0 // Save quantization table test
  2739. static const unsigned short luminance_tbl[64] = {
  2740. 16, 11, 10, 16, 24, 40, 51, 61,
  2741. 12, 12, 14, 19, 26, 58, 60, 55,
  2742. 14, 13, 16, 24, 40, 57, 69, 56,
  2743. 14, 17, 22, 29, 51, 87, 80, 62,
  2744. 18, 22, 37, 56, 68, 109, 103, 77,
  2745. 24, 35, 55, 64, 81, 104, 113, 92,
  2746. 49, 64, 78, 87, 103, 121, 120, 101,
  2747. 72, 92, 95, 98, 112, 100, 103, 99
  2748. };
  2749. static const unsigned short chrominance_tbl[64] = {
  2750. 17, 18, 24, 47, 99, 99, 99, 99,
  2751. 18, 21, 26, 66, 99, 99, 99, 99,
  2752. 24, 26, 56, 99, 99, 99, 99, 99,
  2753. 47, 66, 99, 99, 99, 99, 99, 99,
  2754. 99, 99, 99, 99, 99, 99, 99, 99,
  2755. 99, 99, 99, 99, 99, 99, 99, 99,
  2756. 99, 99, 99, 99, 99, 99, 99, 99,
  2757. 99, 99, 99, 99, 99, 99, 99, 99
  2758. };
  2759. pMyEncoderParams = (EncoderParameters*)malloc
  2760. (2 * sizeof(EncoderParameters));
  2761. pMyEncoderParams->Parameter[0].Guid = ENCODER_LUMINANCE_TABLE;
  2762. pMyEncoderParams->Parameter[0].Type = EncoderParameterValueTypeShort;
  2763. pMyEncoderParams->Parameter[0].NumberOfValues = 64;
  2764. pMyEncoderParams->Parameter[0].Value = (VOID*)luminance_tbl;
  2765. pMyEncoderParams->Parameter[1].Guid = ENCODER_CHROMINANCE_TABLE;
  2766. pMyEncoderParams->Parameter[1].Type = EncoderParameterValueTypeShort;
  2767. pMyEncoderParams->Parameter[1].NumberOfValues = 64;
  2768. pMyEncoderParams->Parameter[1].Value = (VOID*)chrominance_tbl;
  2769. pMyEncoderParams->Count = 2;
  2770. #endif // UNITTEST