home *** CD-ROM | disk | FTP | other *** search
/ Compressed Image File Formats / CompressedImageFileFormatsJohnMiano.iso / pc / Library / BCBViewer / ChildWin.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-17  |  9.5 KB  |  309 lines

  1. //
  2. // Copyright (c) 1998 Colosseum Builders, Inc.
  3. // All rights reserved.
  4. //
  5. // Colosseum Builders, Inc. makes no warranty, expressed or implied
  6. // with regards to this software. It is provided as is.
  7. //
  8. // Permission to use, redistribute, and copy this file is granted
  9. // without a fee so long as as the following conditions are adhered to:
  10. //
  11. // o The user assumes all risk for using this software. The authors of this
  12. //   software shall be liable for no damages of any kind.
  13. //
  14. // o If the source code is distributed then this copyright notice must
  15. //   remain unaltered and any modification must be noted.
  16. //
  17. // o If this code is shipped in binary format the accompanying documentation
  18. //   should state that "this software is based, in part, on the work of
  19. //   Colosseum Builders, Inc."
  20. //
  21.  
  22. //
  23. //  Title:  Sample Image Viewer/Format Conversion Application
  24. //
  25. //  Author:  John M. Miano miano@colosseumbuilders.com
  26. //
  27. //  Description:
  28. //
  29. //    MDI Child Class
  30. //
  31. //---------------------------------------------------------------------
  32. #include <vcl.h>
  33.  
  34. #include <fstream>
  35. #pragma hdrstop
  36.  
  37. #include "ChildWin.h"
  38. #include "main.h"
  39.  
  40. //---------------------------------------------------------------------
  41. #pragma resource "*.dfm"
  42.  
  43. static void ProgressFunction (BitmapImageCoder &coder,
  44.                               void *data,
  45.                               unsigned int currentpass,
  46.                               unsigned int passcount,
  47.                               unsigned int progress,
  48.                               bool &cancel)
  49. {
  50.   MainForm->ProgressBar->Position = (100 * (currentpass - 1) + progress)
  51.                                / passcount ;
  52.   if (progress == 100 && MainForm->ShowProgressive)
  53.   {
  54.     coder.UpdateImage () ;
  55.     TMDIChild *child = (TMDIChild *) data ;
  56.     child->image_type = JpegImage ;
  57.     child->PaintBox->SetBounds (0, 0, child->image.Width (),
  58.                                 child->image.Height ()) ;
  59.     child->LoadBitmapInfoHeader () ;
  60.     child->PaintBox->Refresh () ;
  61.     child->PaintBox->Update () ;
  62.   }
  63.   Application->ProcessMessages () ;
  64.   return ;
  65. }
  66.  
  67. void ImageProgressFunction (BitmapImage &image,
  68.                               void *data,
  69.                               unsigned int currentpass,
  70.                               unsigned int passcount,
  71.                               unsigned int progress,
  72.                               bool &cancel)
  73. {
  74.   MainForm->ProgressBar->Position = (100 * (currentpass - 1) + progress)
  75.                                / passcount ;
  76.   Application->ProcessMessages () ;
  77.   return ;
  78. }
  79.  
  80. //---------------------------------------------------------------------
  81. __fastcall TMDIChild::TMDIChild(TComponent *Owner)
  82.     : TForm(Owner)
  83. {
  84.   image_type = UnknownImage ;
  85.   gamma_value = 1.0 ;
  86.   return ;
  87. }
  88. //---------------------------------------------------------------------
  89. void __fastcall TMDIChild::FormClose(TObject *Sender, TCloseAction &Action)
  90. {
  91.   Action = caFree;
  92.   return ;
  93. }
  94. //---------------------------------------------------------------------
  95. void TMDIChild::ReadImage (const String &filename)
  96. {
  97.   MainForm->ShowProgressBar () ;
  98.   Cursor = crHourGlass ;
  99.   Caption = filename ;
  100.   image_type = UnknownImage ;
  101.   ifstream strm (filename.c_str (), ios::binary) ;
  102.   if (! strm)
  103.   {
  104.     Caption = "" ;
  105.     Cursor = crDefault ;
  106.     throw Exception (String ("Can't open file ") + filename) ;
  107.   }
  108.  
  109.   try
  110.   {
  111.     image_type = ::ReadImage (strm, image, ProgressFunction, (void*) this) ;
  112.   }
  113.   catch (EGraphicsException &ee)
  114.   {
  115.     Caption = "" ;
  116.     Cursor = crDefault ;
  117.     MainForm->ProgressBar->Visible = false ;
  118.     throw Exception (ee.what ()) ;
  119.   }
  120.  
  121.   // If we have a 24-bit image that is being displayed on an 8-bit
  122.   // (or fewer) display then we quantize the colors. From there we
  123.   // allow the system to do the color manipultions (e.g. we do not do
  124.   // quantization for 24-bit images on a 16-bit display).
  125.   HDC dc = CreateDC ("DISPLAY", NULL, NULL, NULL) ;
  126.   int caps = GetDeviceCaps (dc, BITSPIXEL) ;
  127.   if (caps <= 8 && image.BitCount () > 8)
  128.   {
  129.     BitmapImage newimage ;
  130.     image.SetProgressFunction (ImageProgressFunction, NULL) ;
  131.     newimage.EightBitQuantization (image) ;
  132.     image = newimage ;
  133.   }
  134.   DeleteDC (dc) ;
  135.  
  136.   LoadBitmapInfoHeader () ;
  137.  
  138.   PaintBox->SetBounds (0, 0, image.Width (), image.Height ()) ;
  139.   MainForm->ProgressBar->Visible = false ;
  140.   Cursor = crDefault ;
  141.   return ;
  142. }
  143.  
  144.  
  145. void __fastcall TMDIChild::PaintBoxPaint(TObject *Sender)
  146. {
  147.   if (image_type == UnknownImage)
  148.     return ;
  149.  
  150.   SetDIBitsToDevice (PaintBox->Canvas->Handle,
  151.                      0,
  152.                      0,
  153.                      image.Width (),
  154.                      image.Height (),
  155.                      0,
  156.                      0,
  157.                      0,
  158.                      image.Height (),
  159.                      image.ImageData (),
  160.                      (BITMAPINFO *) bitinfobuffer,
  161.                      DIB_RGB_COLORS) ;
  162.   return ;
  163. }
  164. //---------------------------------------------------------------------------
  165.  
  166.  
  167. void TMDIChild::LoadBitmapInfoHeader ()
  168. {
  169.   BITMAPINFO *bitmapinfo = (BITMAPINFO *) bitinfobuffer ;
  170.   bitmapinfo->bmiHeader.biSize = sizeof (BITMAPINFOHEADER) ;
  171.   bitmapinfo->bmiHeader.biWidth = image.Width () ;
  172.   bitmapinfo->bmiHeader.biHeight = image.Height () ;
  173.   bitmapinfo->bmiHeader.biPlanes = 1 ;
  174.   bitmapinfo->bmiHeader.biBitCount = (WORD) image.BitCount () ;
  175.   bitmapinfo->bmiHeader.biCompression = BI_RGB ;
  176.   bitmapinfo->bmiHeader.biSizeImage = 0 ;
  177.   bitmapinfo->bmiHeader.biXPelsPerMeter = 0 ;
  178.   bitmapinfo->bmiHeader.biYPelsPerMeter = 0 ;
  179.   bitmapinfo->bmiHeader.biClrUsed = 0 ;
  180.   bitmapinfo->bmiHeader.biClrImportant = 0 ;
  181.  
  182.   for (unsigned int ii = 0 ; ii < image.ColorCount () ; ++ ii)
  183.   {
  184.     bitmapinfo->bmiColors [ii].rgbRed = image.ColorMap (ii).red ;
  185.     bitmapinfo->bmiColors [ii].rgbGreen = image.ColorMap (ii).green ;
  186.     bitmapinfo->bmiColors [ii].rgbBlue = image.ColorMap (ii).blue ;
  187.     bitmapinfo->bmiColors [ii].rgbReserved = 0 ;
  188.   }
  189.   return ;
  190. }
  191.  
  192. void __fastcall TMDIChild::SetGammaValue (double value)
  193. {
  194.   double adjust = value / gamma_value ;
  195.   Cursor = crHourGlass ;
  196.   Application->ProcessMessages () ;
  197.   image.GammaCorrect (adjust) ;
  198.   gamma_value = value ;
  199.   LoadBitmapInfoHeader () ;
  200.   PaintBox->Refresh () ;
  201.   Cursor = crDefault ;
  202.   return ;
  203. }
  204.  
  205. void TMDIChild::Grayscale ()
  206. {
  207.   Cursor = crHourGlass ;
  208.   Application->ProcessMessages () ;
  209.   image.ToGrayscale () ;
  210.   LoadBitmapInfoHeader () ;
  211.   PaintBox->Refresh () ;
  212.   Cursor = crDefault ;
  213.   return ;
  214. }
  215.  
  216. void TMDIChild::CopyToClipboard ()
  217. {
  218.   // The clipboard format for a Device Independent Bitmap
  219.   // is a BITMAPINFOHEADER followed by the image data.
  220.   unsigned int headersize = sizeof (BITMAPINFOHEADER) ;
  221.   if (image.BitCount () != 24)
  222.     headersize += (1 << image.BitCount ()) * sizeof (RGBQUAD) ;
  223.   unsigned int datasize = image.BytesPerRow () * image.Height () ;
  224.  
  225.   // Allocate a global memory block for the iamge.
  226.   HANDLE hmem = GlobalAlloc (GMEM_MOVEABLE, headersize + datasize) ;
  227.   if (hmem == NULL)
  228.     throw Exception ("Cannot Allocate Global Memory for Clipboard") ;
  229.   char *data = (char *) GlobalLock (hmem) ;
  230.  
  231.   // We have already created a BITMAPINFOHEADER structure for the
  232.   // image in order to display it. Here we copy that structure into
  233.   // the buffer followed by the image data.
  234.   memcpy (data, bitinfobuffer, headersize) ;
  235.   memcpy (&data [headersize], image.ImageData (), datasize) ;
  236.  
  237.   // Now we write the image to the clipboard. This transfers ownership
  238.   // of the global block to the system.
  239.   bool status = OpenClipboard (Application->Handle) ;
  240.   if (! status)
  241.   {
  242.     GlobalFree (hmem) ;
  243.     throw Exception ("Cannot Open the Clipboard") ;
  244.   }
  245.   HANDLE clipboard = SetClipboardData (CF_DIB, hmem) ;
  246.   CloseClipboard () ;
  247.   // Cleanup.
  248.   GlobalUnlock (hmem) ;
  249.   return ;
  250. }
  251.  
  252. void TMDIChild::CopyFromClipboard ()
  253. {
  254.   OpenClipboard (Application->Handle) ;
  255.   HANDLE hmem = GetClipboardData (CF_DIB) ;
  256.   if (hmem == NULL)
  257.   {
  258.     CloseClipboard () ;
  259.     return ;
  260.   }
  261.  
  262.   char *buffer = (char *) GlobalLock (hmem) ;
  263.   BITMAPINFOHEADER *header = (BITMAPINFOHEADER *) buffer ;
  264.  
  265.   unsigned int colorcount ;
  266.   if (header->biBitCount < 24)
  267.     colorcount = 1 << header->biBitCount ;
  268.   else
  269.     colorcount = 0 ;
  270.   image.SetSize (colorcount,
  271.                  header->biBitCount,
  272.                  header->biWidth,
  273.                  header->biHeight) ;
  274.   BITMAPINFO *info = (BITMAPINFO *) buffer ;
  275.   if (image.BitCount () != 24)
  276.   {
  277.     for (unsigned int ii = 0 ; ii < colorcount ; ++ ii)
  278.     {
  279.       image.ColorMap (ii).red = info->bmiColors [ii].rgbRed ;
  280.       image.ColorMap (ii).green = info->bmiColors [ii].rgbGreen ;
  281.       image.ColorMap (ii).blue = info->bmiColors [ii].rgbBlue ;
  282.     }
  283.   }
  284.   char *imagedata = &buffer [sizeof (BITMAPINFOHEADER)
  285.                              + colorcount * sizeof (RGBQUAD)] ;
  286.   unsigned int datasize = image.BytesPerRow () * image.Height () ;
  287.   memcpy (image.ImageData (), imagedata, datasize) ;
  288.   CloseClipboard () ;
  289.   GlobalFree (hmem) ;
  290.   LoadBitmapInfoHeader () ;
  291.   image_type = BmpImage ;
  292.   PaintBox->SetBounds (0, 0, image.Width (), image.Height ()) ;
  293.  
  294.   HDC dc = CreateDC ("DISPLAY", NULL, NULL, NULL) ;
  295.   int caps = GetDeviceCaps (dc, BITSPIXEL) ;
  296.   if (caps <= 8 && image.BitCount () > 8)
  297.   {
  298.     BitmapImage newimage ;
  299.     image.SetProgressFunction (ImageProgressFunction, NULL) ;
  300.     newimage.EightBitQuantization (image) ;
  301.     image = newimage ;
  302.   }
  303.   DeleteDC (dc) ;
  304.  
  305.   Caption = "Untitled" ;
  306.   return ;
  307. }
  308.  
  309.