home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1997 May / Pcwk0597.iso / delphi / imagelib / imagevw.cp_ / imagevw.cp
Text File  |  1995-09-27  |  23KB  |  935 lines

  1. #include <owl\owlpch.h>
  2. #pragma hdrstop
  3. #include <owl\framewin.h>
  4. #include <owl\scroller.h>
  5. #include <owl\opensave.h>
  6. #include <string.h>
  7. #include <dir.h>
  8. #include <time.h>
  9. #include <stdio.h>
  10. #include <io.h>
  11. #include <fcntl.h>
  12. #include <sys\stat.h>
  13. #include "viewdlg.h"
  14. #include "imagevw.h"
  15. #include "imglib30.h"
  16.  
  17. #define MAXAPPNAME  20
  18. #define JPG 1
  19. #define PCX 2
  20. #define GIF 3
  21. #define BMP 4
  22. #define PNG 5
  23.  
  24. static const char AppName[] = "ImageView";
  25. TGaugeDialog* Gdlg;
  26. TGauge2Dialog* Gdlg2;
  27. short Callback(int i)
  28.  {
  29.     return Gdlg->SetValue(i);
  30.   };
  31.  
  32. short Callback2(int i)
  33.  {
  34.     return Gdlg2->SetValue(i);
  35.  };
  36.  
  37.  
  38. class TViewWindow : virtual public TWindow {
  39.   public:
  40.         char      FileName[MAXPATH];
  41.         TBitmap*  Bitmap;
  42.         TPalette* Palette;
  43.         TBrush*   BkgndBrush;
  44.         long      Rop;
  45.         int       PixelWidth;
  46.         int       PixelHeight;
  47.         WORD      Colors;
  48.         BOOL      Fit;
  49.  
  50.         TViewWindow();
  51.       ~TViewWindow();
  52.  
  53.   protected:
  54.         void      CmOpenJpg();
  55.         void      CmOpenBmp();
  56.         void      CmOpenGif();
  57.         void      CmOpenPcx();
  58.         void      CmOpenPng();
  59.         void      CmImageInfo();
  60.         void      CmFit();
  61.         void      CeFit(TCommandEnabler& ce);
  62.  
  63.         void      Paint(TDC&, BOOL erase, TRect&);
  64.         void      EvSize(UINT sizeType, TSize&);
  65.  
  66.         void      EvPaletteChanged(HWND hWndPalChg);
  67.         BOOL      EvQueryNewPalette();
  68.         void      EvSetFocus(HWND); // should use above when working
  69.         void      EvDestroy();
  70.         void      ShowError(int errormsg);
  71.  
  72.         BOOL      UpdatePalette(BOOL alwaysRepaint);
  73.         void      AdjustScroller();
  74.         void      SetCaption(const char*);
  75.         void      CmSaveToJpg();
  76.         void      CmSaveToBmp();
  77.         void      CmSaveToPng();
  78.         void      CmSaveToGif();
  79.         void      CmSaveToPcx();
  80.         int       ReadStream(const char * filename, const char * filetitle, int type);
  81.         int       WriteStream(const char * filename, int type);
  82.   private:
  83.         DecTransfer DecBuffer;
  84.         ComTransfer ComBuffer;
  85.         EncTransfer EncBuffer;
  86.  
  87.   DECLARE_RESPONSE_TABLE(TViewWindow);
  88. };
  89.  
  90. DEFINE_RESPONSE_TABLE1(TViewWindow, TWindow)
  91.   EV_COMMAND(CM_OPENJPG, CmOpenJpg),
  92.   EV_COMMAND(CM_OPENBMP, CmOpenBmp),
  93.   EV_COMMAND(CM_OPENGIF, CmOpenGif),
  94.   EV_COMMAND(CM_OPENPCX, CmOpenPcx),
  95.   EV_COMMAND(CM_OPENPNG, CmOpenPng),
  96.   EV_COMMAND(CM_INFO, CmImageInfo),
  97.   EV_COMMAND(CM_FIT, CmFit),
  98.   EV_COMMAND(CM_SAVETOJPG, CmSaveToJpg),
  99.   EV_COMMAND(CM_SAVETOBMP, CmSaveToBmp),
  100.   EV_COMMAND(CM_SAVETOPNG, CmSaveToPng),
  101.   EV_COMMAND(CM_SAVETOGIF, CmSaveToGif),
  102.   EV_COMMAND(CM_SAVETOPCX, CmSaveToPcx),
  103.   EV_COMMAND_ENABLE(CM_FIT, CeFit),
  104.   EV_WM_SIZE,
  105.   EV_WM_PALETTECHANGED,
  106.   EV_WM_QUERYNEWPALETTE,
  107.   EV_WM_SETFOCUS,
  108.   EV_WM_DESTROY,
  109. END_RESPONSE_TABLE;
  110.  
  111. //
  112. // Constructor for a TViewWindow, sets scroll styles andconstructs
  113. // the Scroller object.  Also sets the Rop based on whether thedisplay
  114. // is monochrome (two-color) or polychrome.
  115. //
  116. TViewWindow::TViewWindow()
  117.   : TWindow(0, 0, 0)
  118. {
  119.   Attr.Style |= WS_VSCROLL | WS_HSCROLL;
  120.   Bitmap = 0;
  121.   Palette = 0;
  122.   BkgndBrush = new TBrush(::GetSysColor(COLOR_WINDOW));
  123.   Scroller = new TScroller(this, 1, 1, 200, 200);
  124.   Fit = FALSE;
  125.  
  126.   TScreenDC screenDC;
  127.   if (screenDC.GetDeviceCaps(NUMCOLORS) < 3 )
  128.      Rop = NOTSRCCOPY;
  129.   else
  130.      Rop = SRCCOPY;
  131.   memset(&DecBuffer, 0, sizeof(DecBuffer));
  132.   DecBuffer.Res8But = BF_CHECKED;
  133.   DecBuffer.Scl1But = BF_CHECKED;
  134.   DecBuffer.Rad1DBut = BF_CHECKED;
  135.   memset(&EncBuffer, 0, sizeof(EncBuffer));
  136.   EncBuffer.Res8But = BF_CHECKED;
  137.   memset(&ComBuffer, 0, sizeof(ComBuffer));
  138.   strcpy(ComBuffer.Cquality, "75");
  139.   strcpy(ComBuffer.Csmooth, "00");
  140.  
  141.   SetCaption(0);
  142. }
  143.  
  144. TViewWindow::~TViewWindow()
  145. {
  146.   delete Bitmap;
  147.   delete Palette;
  148.   delete BkgndBrush;
  149.   delete Scroller;
  150. }
  151.  
  152. //
  153. // Build up a caption based on a filename, and set it into the title.
  154. //
  155. void
  156. TViewWindow::SetCaption(const char* name)
  157. {
  158.   char caption[MAXPATH + MAXAPPNAME + 2 + 1];
  159.   strcpy(FileName, name ? name : "(Untitled)");
  160.   strcpy(caption, GetApplication()->GetName());
  161.   strcat(caption, " - ");
  162.   strcat(caption, FileName);
  163.   if (Parent)
  164.      Parent->SetCaption(caption);
  165. }
  166.  
  167. //
  168. // Toggle Fit member variable & adjust scroller as needed
  169. //
  170. void
  171. TViewWindow::CmFit()
  172. {
  173.   Fit = !Fit;
  174.   AdjustScroller();
  175. }
  176.  
  177. //
  178. // The fit menu item is checked if the Fit member is true
  179. //
  180. void
  181. TViewWindow::CeFit(TCommandEnabler& ce)
  182. {
  183.   ce.SetCheck(Fit ? TCommandEnabler::Checked : TCommandEnabler::Unchecked);
  184. }
  185.  
  186. void TViewWindow::ShowError(int msgcode)
  187. {
  188.   HINSTANCE moduleinst;
  189.   int res;
  190.   char buffer[80];
  191.   if ((moduleinst = GetModuleHandle("IMGLIB30.DLL")) != NULL)
  192.     {
  193.      res = LoadString(moduleinst, msgcode, buffer, 80);
  194.      /* get message string */
  195.      /* Create the message */
  196.      if (res != 0)
  197.         MessageBox(buffer, "Error", MB_OK);
  198.      else
  199.         MessageBox("Could not find String", "Error", MB_OK);
  200.     }
  201.   else
  202.      MessageBox("Could not get module handle", "Error", MB_OK);
  203. }
  204.  
  205. int TViewWindow::ReadStream(const char * filename, const char * filetitle, int type)
  206. {
  207.   int resolution, option, scale, res;
  208.   unsigned int hddb, hpal;
  209.   struct stat statbuf;
  210.   void far * lpBuffer;
  211.   HGLOBAL hglb;
  212.   long lres;
  213.   unsigned char huge * cbuffer;
  214.   FILE * fpin;
  215.   char message[40];
  216.  
  217.   TDecDialog* pDlg = new TDecDialog(this, &DecBuffer);
  218.   if (pDlg->Execute() != IDOK)
  219.   // leave
  220.   return 0;
  221.  
  222.   SetCursor(0, IDC_WAIT);
  223.  
  224.   // Set Bitmap output resolution  - 24, 8, or 4 bit
  225.   if (DecBuffer.Res24But == BF_CHECKED)
  226.      resolution = 24;
  227.   else if (DecBuffer.Res8But == BF_CHECKED)
  228.      resolution = 8;
  229.   else
  230.      resolution = 4;
  231.  
  232.   // Set Color Quantization and dithering methods for output.
  233.   // This is used if Resolution != 24
  234.  
  235.   if (DecBuffer.Rad1But == BF_CHECKED)
  236.      option = 0;
  237.   else
  238.      option = 1;
  239.  
  240.   // Set output Bitmap scale factor either 1/1, 1/2, 1/4, or 1/8
  241.   // of origional size
  242.   if (DecBuffer.Scl1But == BF_CHECKED)
  243.      scale = 1;
  244.   else if (DecBuffer.Scl2But == BF_CHECKED)
  245.      scale = 2;
  246.   else if (DecBuffer.Scl4But == BF_CHECKED)
  247.      scale = 4;
  248.   else
  249.      scale = 8;
  250.  
  251.   // read in file into global memory
  252.  
  253.   // Open file
  254.   if ((fpin = fopen(filename, "rb")) == NULL)
  255.     {
  256.      MessageBox("Cannot open input file", filename, MB_OK);
  257.      return 0;
  258.     }
  259.  
  260.   // get file size
  261.   stat(filename, &statbuf);
  262.   // allocate memory
  263.   hglb = GlobalAlloc(GPTR, statbuf.st_size);
  264.   lpBuffer = GlobalLock(hglb);
  265.   cbuffer = (unsigned char huge *)lpBuffer;
  266.  
  267.   // set how many bytes to read at a time
  268.   int readsize = 16384;
  269.   long count = statbuf.st_size / readsize;
  270.   int numreads;
  271.   lres = 0;
  272.   numreads = fread(cbuffer, readsize, count, fpin);
  273.   lres = lres + ((long)numreads * (long)readsize);
  274.   cbuffer = cbuffer + ((long)readsize * (long)numreads);
  275.   readsize = (int)(statbuf.st_size - lres);
  276.   numreads = fread(cbuffer, readsize, 1, fpin);
  277.   lres = lres + ((long)numreads * (long)readsize);
  278.   fclose(fpin);
  279.  
  280.   // Show progress display modaless dialog box
  281.   if (type == 1)
  282.      sprintf(message, "Decompressing JPG Stream");
  283.   else if (type == 2)
  284.      sprintf(message, "Decompressing PCX Stream");
  285.   else if (type == 3)
  286.      sprintf(message, "Decompressing GIF Stream");
  287.   else if (type == 4)
  288.      sprintf(message, "Decompressing BMP stream");
  289.   else
  290.      sprintf(message, "Decompressing PNG stream");
  291.   Gdlg = new TGaugeDialog(this);
  292.   Gdlg->SetCaption(message);
  293.   Gdlg->Create();
  294.  
  295.   // password variable - the code is given when you register
  296.   int password = 0;
  297.   res = 0;
  298.   // call the DLL function to read the image in global memory
  299.   switch (type)
  300.     {
  301.      case 1:
  302.         res = readjpgstream(lpBuffer, lres, resolution, scale, option, password,
  303.                           &hddb, &hpal, Callback, 0);
  304.         break;
  305.      case 2:
  306.         res = readpcxstream(lpBuffer, lres, resolution, option, password, &hddb,
  307.                                   &hpal, Callback, 0);
  308.         break;
  309.      case 3:
  310.         res = readgifstream(lpBuffer, lres, resolution, option, password, &hddb,
  311.                                   &hpal, Callback, 0);
  312.         break;
  313.      case 4:
  314.         res = readbmpstream(lpBuffer, lres, resolution, option, password, &hddb,
  315.                             &hpal, Callback, 0);
  316.         break;
  317.      case 5:
  318.         res = readpngstream(lpBuffer, lres, resolution, option, password, &hddb,
  319.                             &hpal, Callback, 0);
  320.         break;
  321.     }
  322.  
  323.   // destroy progress display dialog and free global memory
  324.   Gdlg->Destroy();
  325.   delete Gdlg;
  326.   GlobalUnlock(hglb);
  327.   GlobalFree(hglb);
  328.   SetCursor(0, IDC_ARROW);
  329.  
  330.   // if success set Bitmap and Palette for Painting
  331.   if (res != 1)
  332.     {
  333.      ShowError(res);
  334.      return 0;
  335.     }
  336.  
  337.   delete Palette;
  338.   Palette = new TPalette((HPALETTE)hpal, AutoDelete);
  339.   delete Bitmap;
  340.   Bitmap = new TBitmap((HBITMAP)hddb, AutoDelete);
  341.   PixelWidth = Bitmap->Width();
  342.   PixelHeight = Bitmap->Height();
  343.   UpdatePalette(TRUE);
  344.   AdjustScroller();
  345.   SetCaption(filetitle);
  346.   return 1;
  347. }
  348.  
  349.  
  350. void
  351. TViewWindow::CmOpenJpg()
  352. {
  353.   TOpenSaveDialog::TData data (
  354.         OFN_FILEMUSTEXIST,
  355.         "JPEG Files (*.JPG)|*.jpg|",
  356.         0,
  357.         "",
  358.         "JPG"
  359.   );
  360.   int res = 0;
  361.   TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,data);
  362.   if (tmpdlg->Execute() == IDOK)
  363.     {
  364.      char fileTitle[MAXPATH];
  365.      TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle,MAXPATH);
  366.      res = ReadStream(data.FileName, fileTitle, 1);
  367.     }
  368.   delete tmpdlg;
  369. }
  370.  
  371. void
  372. TViewWindow::CmOpenGif()
  373. {
  374.   TOpenSaveDialog::TData data (
  375.         OFN_FILEMUSTEXIST,
  376.         "GIF Files (*.GIF)|*.gif|",
  377.         0,
  378.         "",
  379.         "GIF"
  380.   );
  381.   int res = 0;
  382.   TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,data);
  383.   if (tmpdlg->Execute() == IDOK)
  384.     {
  385.      char fileTitle[MAXPATH];
  386.      TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle,MAXPATH);
  387.      res = ReadStream(data.FileName, fileTitle, 3);
  388.     }
  389.   delete tmpdlg;
  390. }
  391.  
  392. void
  393. TViewWindow::CmOpenPcx()
  394. {
  395.   TOpenSaveDialog::TData data (
  396.         OFN_FILEMUSTEXIST,
  397.         "PCX Files (*.PCX)|*.pcx|",
  398.         0,
  399.         "",
  400.         "PCX"
  401.   );
  402.   int res = 0;
  403.   TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,data);
  404.   if (tmpdlg->Execute() == IDOK)
  405.     {
  406.      char fileTitle[MAXPATH];
  407.      TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle,MAXPATH);
  408.      res = ReadStream(data.FileName, fileTitle, 2);
  409.     }
  410.   delete tmpdlg;
  411. }
  412.  
  413. void
  414. TViewWindow::CmOpenBmp()
  415. {
  416.   TOpenSaveDialog::TData data (
  417.         OFN_FILEMUSTEXIST,
  418.         "Bitmap Files (*.BMP)|*.bmp|",
  419.         0,
  420.         "",
  421.         "BMP"
  422.   );
  423.   int res = 0;
  424.   TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,data);
  425.   if (tmpdlg->Execute() == IDOK)
  426.     {
  427.      char fileTitle[MAXPATH];
  428.      TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle,MAXPATH);
  429.      res = ReadStream(data.FileName, fileTitle, 4);
  430.     }
  431.   delete tmpdlg;
  432. }
  433.  
  434. void
  435. TViewWindow::CmOpenPng()
  436. {
  437.   TOpenSaveDialog::TData data (
  438.         OFN_FILEMUSTEXIST,
  439.         "PNG Files (*.PNG)|*.png|",
  440.         0,
  441.         "",
  442.         "PNG"
  443.   );
  444.   int res = 0;
  445.   TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,data);
  446.   if (tmpdlg->Execute() == IDOK)
  447.     {
  448.      char fileTitle[MAXPATH];
  449.      TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle,MAXPATH);
  450.      res = ReadStream(data.FileName, fileTitle, 5);
  451.     }
  452.   delete tmpdlg;
  453. }
  454.  
  455. void TViewWindow::CmSaveToBmp()
  456. {
  457.  TOpenSaveDialog::TData bmpdata (
  458.         OFN_HIDEREADONLY|OFN_NOREADONLYRETURN,
  459.         "Bmp Files (*.BMP)|*.BMP|",
  460.         0,
  461.         0,
  462.         "*.bmp"
  463.       );
  464.  int res = 0;
  465.  if (Bitmap)
  466.   {
  467.     TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,bmpdata);
  468.     if (tmpdlg->Execute() == IDOK)
  469.      {
  470.       res = WriteStream(bmpdata.FileName, 4);
  471.       if (!res)
  472.          MessageBox("Error Writing BMP File", "Error", MB_ICONSTOP | MB_OK);
  473.      }
  474.     delete tmpdlg;
  475.   }
  476.     else
  477.       MessageBox("No Image Loaded!", "Error Writing BMP", MB_OK);
  478. }
  479.  
  480. void TViewWindow::CmSaveToJpg()
  481. {
  482.  TOpenSaveDialog::TData jpgdata (
  483.         OFN_HIDEREADONLY|OFN_NOREADONLYRETURN,
  484.         "Jpg Files (*.JPG)|*.JPG|",
  485.         0,
  486.         0,
  487.         "*.jpg"
  488.       );
  489.  int res = 0;
  490.  if (Bitmap)
  491.   {
  492.     TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,jpgdata);
  493.     if (tmpdlg->Execute() == IDOK)
  494.      {
  495.       res = WriteStream(jpgdata.FileName, 1);
  496.       if (!res)
  497.          MessageBox("Error Writing JPG File", "Error", MB_ICONSTOP | MB_OK);
  498.      }
  499.     delete tmpdlg;
  500.   }
  501.     else
  502.       MessageBox("No Image Loaded!", "Error Writing JPG", MB_OK);
  503. }
  504.  
  505. void TViewWindow::CmSaveToPng()
  506. {
  507.  TOpenSaveDialog::TData jpgdata (
  508.         OFN_HIDEREADONLY|OFN_NOREADONLYRETURN,
  509.         "Png Files (*.PNG)|*.PNG|",
  510.         0,
  511.         0,
  512.         "*.png"
  513.       );
  514.  int res = 0;
  515.  if (Bitmap)
  516.   {
  517.     TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,jpgdata);
  518.     if (tmpdlg->Execute() == IDOK)
  519.      {
  520.       res = WriteStream(jpgdata.FileName, 5);
  521.       if (!res)
  522.          MessageBox("Error Writing PNG File", "Error", MB_ICONSTOP | MB_OK);
  523.      }
  524.     delete tmpdlg;
  525.   }
  526.     else
  527.       MessageBox("No Image Loaded!", "Error Writing PNG", MB_OK);
  528. }
  529.  
  530. void TViewWindow::CmSaveToGif()
  531. {
  532.  TOpenSaveDialog::TData jpgdata (
  533.         OFN_HIDEREADONLY|OFN_NOREADONLYRETURN,
  534.         "Gif Files (*.GIF)|*.GIF|",
  535.         0,
  536.         0,
  537.         "*.gif"
  538.       );
  539.  int res = 0;
  540.  if (Bitmap)
  541.   {
  542.     TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,jpgdata);
  543.     if (tmpdlg->Execute() == IDOK)
  544.      {
  545.       res = WriteStream(jpgdata.FileName, 3);
  546.       if (!res)
  547.          MessageBox("Error Writing GIF File", "Error", MB_ICONSTOP | MB_OK);
  548.      }
  549.     delete tmpdlg;
  550.   }
  551.     else
  552.       MessageBox("No Image Loaded!", "Error Writing GIF", MB_OK);
  553. }
  554.  
  555. void TViewWindow::CmSaveToPcx()
  556. {
  557.  TOpenSaveDialog::TData jpgdata (
  558.         OFN_HIDEREADONLY|OFN_NOREADONLYRETURN,
  559.         "Pcx Files (*.PCX)|*.PCX|",
  560.         0,
  561.         0,
  562.         "*.pcx"
  563.       );
  564.  int res = 0;
  565.  if (Bitmap)
  566.   {
  567.     TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,jpgdata);
  568.     if (tmpdlg->Execute() == IDOK)
  569.      {
  570.       res = WriteStream(jpgdata.FileName, 2);
  571.       if (!res)
  572.          MessageBox("Error Writing PCX File", "Error", MB_ICONSTOP | MB_OK);
  573.      }
  574.     delete tmpdlg;
  575.   }
  576.     else
  577.       MessageBox("No Image Loaded!", "Error Writing PCX", MB_OK);
  578. }
  579.  
  580. int TViewWindow::WriteStream(const char * filename, int type)
  581. {
  582.     HBITMAP hddb;
  583.     HPALETTE hpal;
  584.     void far * lpBuffer;
  585.     HGLOBAL hglb;
  586.     long lres, alsize;
  587.     int ret = 0;
  588.     unsigned char huge * cbuffer;
  589.     FILE * fpout;
  590.     int quality, smooth, resolution;
  591.     char message[20];
  592.     if (type == 1)
  593.      {
  594.       TComDialog* pDlg = new TComDialog(this, &ComBuffer);
  595.  
  596.       // Display the options for writing a JPEG file
  597.       if (pDlg->Execute() != IDOK)
  598.         {
  599.          delete pDlg;
  600.          return 0;
  601.         }
  602.       // Set the quality of the JPEG image.  A higher quality
  603.       // yields a better JPEG image that takes more space.
  604.  
  605.       sscanf(ComBuffer.Cquality, "%d", &quality);
  606.  
  607.       // Set a smoothing factor on the JPEG image.
  608.       sscanf(ComBuffer.Csmooth, "%d", &smooth);
  609.      }
  610.     else
  611.      {
  612.       TEncDialog* pDlg = new TEncDialog(this, &EncBuffer);
  613.       if (pDlg->Execute() != IDOK)
  614.          // leave
  615.          return 0;
  616.  
  617.       SetCursor(0, IDC_WAIT);
  618.  
  619.       // Set Bitmap output resolution  - 24, 8, or 4 bit
  620.       if (EncBuffer.Res24But == BF_CHECKED)
  621.          resolution = 24;
  622.       else if (EncBuffer.Res8But == BF_CHECKED)
  623.          resolution = 8;
  624.       else
  625.          resolution = 4;
  626.      }
  627.     SetCursor(0, IDC_WAIT);
  628.  
  629.     hddb = *Bitmap;
  630.     hpal = *Palette;
  631.  
  632.     // get bitmap size and allocate space
  633.     long width = Bitmap->Width();
  634.     long height = Bitmap->Height();
  635.     alsize = width * height * 3;
  636.  
  637.     // allocate memory
  638.     hglb = GlobalAlloc(GPTR, alsize);
  639.     lpBuffer = GlobalLock(hglb);
  640.     Gdlg2 = new TGauge2Dialog(this);
  641.     if (type == 1)
  642.       sprintf(message, "Creating JPEG Stream");
  643.     else if (type == 2)
  644.       sprintf(message, "Creating PCX Stream");
  645.     else if (type == 3)
  646.       sprintf(message, "Creating GIF Stream");
  647.     else if (type == 4)
  648.       sprintf(message, "Creating BMP Stream");
  649.     else
  650.       sprintf(message, "Creating PNG Stream");
  651.  
  652.     Gdlg2->SetCaption(message);
  653.     Gdlg2->Create();
  654.  
  655.     switch (type)
  656.      {
  657.       case 1:
  658.          ret = writejpegstream(lpBuffer, &alsize, quality, smooth, 0,
  659.                             (unsigned int)hddb, (unsigned int)hpal, Callback2, 0);
  660.          break;
  661.       case 2:
  662.          ret = writepcxstream(lpBuffer, &alsize, resolution, 0,
  663.                             (unsigned int)hddb, (unsigned int)hpal, Callback2, 0);
  664.          break;
  665.       case 3:
  666.          ret = writegifstream(lpBuffer, &alsize, resolution, 0,
  667.                             (unsigned int)hddb, (unsigned int)hpal, Callback2, 0);
  668.          break;
  669.       case 4:
  670.          ret = writebmpstream(lpBuffer, &alsize, resolution, 0,
  671.                             (unsigned int)hddb, (unsigned int)hpal, Callback2, 0);
  672.          break;
  673.       case 5:
  674.          ret = writepngstream(lpBuffer, &alsize, resolution, 1, 0,
  675.                             (unsigned int)hddb, (unsigned int)hpal, Callback2, 0);
  676.          break;
  677.      }
  678.  
  679.     Gdlg2->Destroy();
  680.     delete Gdlg2;
  681.     if (ret == 1)
  682.      {
  683.       // write out to file
  684.       if ((fpout = fopen(filename, "wb")) == NULL)
  685.         {
  686.          MessageBox("Cannot open file", filename, MB_OK);
  687.          GlobalUnlock(hglb);
  688.          GlobalFree(hglb);
  689.          return 0;
  690.         }
  691.       cbuffer = (unsigned char huge *)lpBuffer;
  692.       int writesize = 16384;
  693.       long count = alsize / writesize;
  694.       int numwrites;
  695.       lres = 0;
  696.       numwrites = fwrite(cbuffer, writesize, count, fpout);
  697.       lres = lres + ((long)numwrites * (long)writesize);
  698.       cbuffer = cbuffer + ((long)writesize * (long)numwrites);
  699.       writesize = (int)(alsize - lres);
  700.       numwrites = fwrite(cbuffer, writesize, 1, fpout);
  701.       lres = lres + ((long)numwrites * (long)writesize);
  702.       fclose(fpout);
  703.      }
  704.     else
  705.       ShowError(ret);
  706.     SetCursor(0, IDC_ARROW);
  707.     GlobalUnlock(hglb);
  708.     GlobalFree(hglb);
  709.     if (ret)
  710.       return 1;
  711.     else
  712.       return 0;
  713. }
  714.  
  715. //
  716. // Adjust the Scroller range so that the the origin is the
  717. // upper-most scrollable point and the corner is the
  718. // bottom-most.
  719. //
  720. void
  721. TViewWindow::AdjustScroller()
  722. {
  723.   TRect  clientRect = GetClientRect();
  724.  
  725.   // only show scrollbars when image is larger than
  726.   // the client area and we are not stretching to fit.
  727.   //
  728.   if (Fit)
  729.      Scroller->SetRange(0, 0);
  730.  
  731.   else
  732.     {
  733.      TPoint Range(Max(PixelWidth-clientRect.Width(), 0),
  734.                                     Max(PixelHeight-clientRect.Height(),0));
  735.      Scroller->SetRange(Range.x, Range.y);
  736.     }
  737.   Scroller->ScrollTo(0, 0);
  738.   if (!GetUpdateRect(clientRect, FALSE))
  739.      Invalidate(FALSE);
  740. }
  741.  
  742. //
  743. // Reset scroller range.
  744. //
  745. void
  746. TViewWindow::EvSize(UINT SizeType, TSize& Size)
  747. {
  748.   TWindow::EvSize(SizeType, Size);
  749.   if (SizeType != SIZEICONIC)
  750.     {
  751.      AdjustScroller();
  752.      Invalidate(FALSE);
  753.     }
  754. }
  755.  
  756. //
  757. // Somebody changed the palette. If its not us, then we need toupdate.
  758. //
  759. void
  760. TViewWindow::EvPaletteChanged(HWND hWndPalChg)
  761. {
  762.   if (hWndPalChg != HWindow)
  763.      UpdatePalette(TRUE);    // pass FALSE to UpdateColors()instead of repaint
  764. }
  765.  
  766. //
  767. // We need to re-realize the logical palette each time
  768. // we regain the input focus
  769. //
  770. BOOL
  771. TViewWindow::EvQueryNewPalette()
  772. {
  773.   return UpdatePalette(TRUE);
  774. }
  775.  
  776. //
  777. // Use this message temporarily until the palette msgs get routedto us
  778. //
  779. void
  780. TViewWindow::EvSetFocus(HWND)
  781. {
  782.   UpdatePalette(TRUE);
  783. }
  784.  
  785. void
  786. TViewWindow::EvDestroy()
  787. {
  788.   TWindow::EvDestroy();
  789. }
  790.  
  791. BOOL
  792. TViewWindow::UpdatePalette(BOOL alwaysRepaint)
  793. {
  794.   if (Palette)
  795.     {
  796.      TClientDC clientDC(*this);
  797.      #if !defined(__WIN32__)
  798.         Palette->UnrealizeObject();
  799.      #endif
  800.      clientDC.SelectObject(*Palette, FALSE);
  801.      if (alwaysRepaint)
  802.         Invalidate(FALSE);
  803.      else
  804.         clientDC.UpdateColors();
  805.      return TRUE;
  806.     }
  807.   return FALSE;
  808. }
  809.  
  810. void
  811. TViewWindow::Paint(TDC& dc, BOOL, TRect&)
  812. {
  813.   TRect clientRect = GetClientRect();
  814.   dc.SelectObject(*BkgndBrush);
  815.  
  816.   if (Bitmap)
  817.     {
  818.      TMemoryDC memoryDC(dc);
  819.      memoryDC.SelectObject(*Bitmap);
  820.      dc.SetStretchBltMode(COLORONCOLOR);
  821.      if (Palette)
  822.       {
  823.         dc.SelectObject(*Palette, FALSE);
  824.         dc.RealizePalette();
  825.         memoryDC.SelectObject(*Palette, FALSE);
  826.       }
  827.  
  828.      TRect imageRect(0,0, PixelWidth, PixelHeight);
  829.      if (Parent->IsIconic())
  830.       {
  831.         dc.StretchBlt(Parent->GetClientRect(), memoryDC,imageRect, Rop);
  832.       }
  833.      else
  834.       {
  835.         clientRect += TPoint((int)Scroller->XPos,(int)Scroller->YPos);
  836.         if (Fit)
  837.           dc.StretchBlt(clientRect, memoryDC,imageRect, Rop);
  838.         else
  839.           dc.BitBlt(imageRect, memoryDC, TPoint(0,0), Rop);
  840.         // Clear borders here for no flicker
  841.         //
  842.         if (!Fit)
  843.          {
  844.           dc.PatBlt(TRect(TPoint(PixelWidth,0),clientRect.BottomRight()));
  845.           dc.PatBlt(TRect(TPoint(0,PixelHeight),clientRect.BottomRight()));
  846.        }
  847.       }
  848.     }
  849.   else
  850.     dc.PatBlt(clientRect, PATCOPY);
  851. }
  852.  
  853.  
  854. void
  855. TViewWindow::CmImageInfo()
  856. {
  857.   TOpenSaveDialog::TData data (
  858.         OFN_HIDEREADONLY|OFN_FILEMUSTEXIST|OFN_NOREADONLYRETURN,
  859.         "Image Files (*.*)|*.*|",
  860.         0,
  861.         "",
  862.         ""
  863.   );
  864.   int result, width, height, numcolors, bitspixel, planes;
  865.   char filetype[20], filecomp[20];
  866.   char message[300];
  867.   struct stat statbuf;
  868.   void far * lpBuffer;
  869.   HGLOBAL hglb;
  870.   long lres;
  871.   unsigned char huge * cbuffer;
  872.   FILE * fpin;
  873.   TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,data);
  874.   if (tmpdlg->Execute() == IDOK)
  875.     {
  876.      char fileTitle[MAXPATH];
  877.      TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle,MAXPATH);
  878.      if ((fpin = fopen(data.FileName, "rb")) == NULL)
  879.       {
  880.         MessageBox("Cannot open input file", data.FileName, MB_OK);
  881.         return;
  882.       }
  883.      stat(data.FileName, &statbuf);
  884.      // allocate memory
  885.      hglb = GlobalAlloc(GPTR, statbuf.st_size);
  886.      lpBuffer = GlobalLock(hglb);
  887.      cbuffer = (unsigned char huge *)lpBuffer;
  888.      int readsize = 16384;
  889.      long count = statbuf.st_size / readsize;
  890.      int numreads;
  891.      lres = 0;
  892.      numreads = fread(cbuffer, readsize, count, fpin);
  893.      lres = lres + ((long)numreads * (long)readsize);
  894.      cbuffer = cbuffer + ((long)readsize * (long)numreads);
  895.      readsize = (int)(statbuf.st_size - lres);
  896.      numreads = fread(cbuffer, readsize, 1, fpin);
  897.      lres = lres + ((long)numreads * (long)readsize);
  898.      fclose(fpin);
  899.      result = streaminfo(lpBuffer, lres, filetype, &width, &height, &bitspixel,
  900.                              &planes, &numcolors, filecomp, 0);
  901.      GlobalUnlock(hglb);
  902.      GlobalFree(hglb);
  903.      if (result == 1)
  904.       {
  905.         sprintf(message, "%s %s\nw: %d h: %d\nbits per pixel: %d planes: %d\n colors: %d",
  906.                         filetype, filecomp, width, height, bitspixel, planes, numcolors);
  907.         MessageBox(message, fileTitle, MB_ICONINFORMATION | MB_OK);
  908.       }
  909.      else
  910.         MessageBox("Cannot Identify File", fileTitle, MB_ICONINFORMATION | MB_OK);
  911.     }
  912.   delete tmpdlg;
  913. }
  914.  
  915. //----------------------------------------------------------------------------
  916.  
  917. class TViewApp : public TApplication {
  918.   public:
  919.         TViewApp(const char far* name) : TApplication(name) {}
  920.         void InitMainWindow()
  921.          {
  922.           MainWindow = new TFrameWindow(0, Name, new TViewWindow);
  923.           MainWindow->AssignMenu(JPGMENU);
  924.           MainWindow->SetIcon(this, JPGVIEW);
  925.          }
  926. };
  927.  
  928. //----------------------------------------------------------------------------
  929.  
  930. int
  931. OwlMain(int /*argc*/, char* /*argv*/ [])
  932. {
  933.   return TViewApp(AppName).Run();
  934. }
  935.