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