home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / common / imagxpm.cpp < prev    next >
C/C++ Source or Header  |  2002-11-10  |  10KB  |  255 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        imagxpm.cpp
  3. // Purpose:     wxXPMHandler
  4. // Author:      Vaclav Slavik, Robert Roebling
  5. // RCS-ID:      $Id: imagxpm.cpp,v 1.12.2.1 2002/11/09 21:43:23 RR Exp $
  6. // Copyright:   (c) 2001 Vaclav Slavik
  7. // Licence:     wxWindows licence
  8. /////////////////////////////////////////////////////////////////////////////
  9.  
  10. /*
  11.  
  12. This file is partially based on source code of ImageMagick by John Cristy. Its
  13. license is as follows:
  14.  
  15. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  16. %                                                                             %
  17. %                                                                             %
  18. %                                                                             %
  19. %                            X   X  PPPP   M   M                              %
  20. %                             X X   P   P  MM MM                              %
  21. %                              X    PPPP   M M M                              %
  22. %                             X X   P      M   M                              %
  23. %                            X   X  P      M   M                              %
  24. %                                                                             %
  25. %                                                                             %
  26. %                    Read/Write ImageMagick Image Format.                     %
  27. %                                                                             %
  28. %                                                                             %
  29. %                              Software Design                                %
  30. %                                John Cristy                                  %
  31. %                                 July 1992                                   %
  32. %                                                                             %
  33. %                                                                             %
  34. %  Copyright (C) 2001 ImageMagick Studio, a non-profit organization dedicated %
  35. %  to making software imaging solutions freely available.                     %
  36. %                                                                             %
  37. %  Permission is hereby granted, free of charge, to any person obtaining a    %
  38. %  copy of this software and associated documentation files ("ImageMagick"),  %
  39. %  to deal in ImageMagick without restriction, including without limitation   %
  40. %  the rights to use, copy, modify, merge, publish, distribute, sublicense,   %
  41. %  and/or sell copies of ImageMagick, and to permit persons to whom the       %
  42. %  ImageMagick is furnished to do so, subject to the following conditions:    %
  43. %                                                                             %
  44. %  The above copyright notice and this permission notice shall be included in %
  45. %  all copies or substantial portions of ImageMagick.                         %
  46. %                                                                             %
  47. %  The software is provided "as is", without warranty of any kind, express or %
  48. %  implied, including but not limited to the warranties of merchantability,   %
  49. %  fitness for a particular purpose and noninfringement.  In no event shall   %
  50. %  ImageMagick Studio be liable for any claim, damages or other liability,    %
  51. %  whether in an action of contract, tort or otherwise, arising from, out of  %
  52. %  or in connection with ImageMagick or the use or other dealings in          %
  53. %  ImageMagick.                                                               %
  54. %                                                                             %
  55. %  Except as contained in this notice, the name of the ImageMagick Studio     %
  56. %  shall not be used in advertising or otherwise to promote the sale, use or  %
  57. %  other dealings in ImageMagick without prior written authorization from the %
  58. %  ImageMagick Studio.                                                        %
  59. %                                                                             %
  60. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  61. %
  62. %
  63. */
  64.  
  65. #ifdef __GNUG__
  66. #pragma implementation "imagxpm.h"
  67. #endif
  68.  
  69. // For compilers that support precompilation, includes "wx.h".
  70. #include "wx/wxprec.h"
  71.  
  72. #ifdef __BORLANDC__
  73. #  pragma hdrstop
  74. #endif
  75.  
  76. #ifndef WX_PRECOMP
  77. #  include "wx/defs.h"
  78. #endif
  79.  
  80. #if wxUSE_XPM
  81.  
  82. #include "wx/imagxpm.h"
  83. #include "wx/wfstream.h"
  84. #include "wx/log.h"
  85. #include "wx/intl.h"
  86. #include "wx/utils.h"
  87. #include "wx/xpmdecod.h"
  88.  
  89. IMPLEMENT_DYNAMIC_CLASS(wxXPMHandler,wxImageHandler)
  90.  
  91. //-----------------------------------------------------------------------------
  92. // wxXPMHandler
  93. //-----------------------------------------------------------------------------
  94.  
  95. #if wxUSE_STREAMS
  96.  
  97. bool wxXPMHandler::LoadFile(wxImage *image,
  98.                             wxInputStream& stream,
  99.                             bool WXUNUSED(verbose), int WXUNUSED(index))
  100. {
  101.     wxXPMDecoder decoder;
  102.  
  103.     wxImage img = decoder.ReadFile(stream);
  104.     if ( !img.Ok() )
  105.         return FALSE;
  106.     *image = img;
  107.     return TRUE;
  108. }
  109.  
  110.  
  111. static char hexArray[] = "0123456789ABCDEF";
  112.  
  113. static void DecToHex(int dec, char *buf)
  114. {
  115.     int firstDigit = (int)(dec/16.0);
  116.     int secondDigit = (int)(dec - (firstDigit*16.0));
  117.     buf[0] = hexArray[firstDigit];
  118.     buf[1] = hexArray[secondDigit];
  119.     buf[2] = 0;
  120. }
  121.  
  122.  
  123. bool wxXPMHandler::SaveFile(wxImage * image,
  124.                             wxOutputStream& stream, bool WXUNUSED(verbose))
  125. {
  126.     wxString tmp;
  127.     char tmp_c;
  128.  
  129.     // 1. count colours:
  130.     #define MaxCixels  92
  131.     static const char Cixel[MaxCixels+1] =
  132.                          " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk"
  133.                          "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
  134.     int chars_per_pixel;
  135.     int cols;
  136.     int i, j, k;
  137.  
  138.     cols = image->CountColours();
  139.     chars_per_pixel = 1;
  140.     for ( k = MaxCixels; cols > k; k *= MaxCixels)
  141.         chars_per_pixel++;
  142.  
  143.     // 2. write the header:    
  144.     wxString sName;
  145.     if ( image->HasOption(wxIMAGE_OPTION_FILENAME) )
  146.     {
  147.         wxSplitPath(image->GetOption(wxIMAGE_OPTION_FILENAME),
  148.                     NULL, &sName, NULL);
  149.         sName << wxT("_xpm");
  150.     }
  151.     
  152.     if ( !sName.IsEmpty() )
  153.         sName = wxString(wxT("/* XPM */\nstatic char *")) + sName;
  154.     else 
  155.         sName = wxT("/* XPM */\nstatic char *xpm_data");
  156.     stream.Write( (const char*) sName.ToAscii(), sName.Len() );
  157.  
  158.     char tmpbuf[200];
  159.     // VS: 200b is safe upper bound for anything produced by sprintf below
  160.     //     (<101 bytes the string, neither %i can expand into more than 10 chars)
  161.     sprintf(tmpbuf, 
  162.                "[] = {\n"
  163.                "/* columns rows colors chars-per-pixel */\n"
  164.                "\"%i %i %i %i\",\n",
  165.                image->GetWidth(), image->GetHeight(), cols, chars_per_pixel);
  166.     stream.Write(tmpbuf, strlen(tmpbuf));
  167.  
  168.     // 3. create color symbols table:
  169.     wxImageHistogram histogram;
  170.     image->ComputeHistogram(histogram);
  171.  
  172.     char *symbols_data = new char[cols * (chars_per_pixel+1)];
  173.     char **symbols = new char*[cols];
  174.  
  175.     // 2a. find mask colour:
  176.     unsigned long mask_key = 0x1000000 /*invalid RGB value*/;
  177.     if (image->HasMask())
  178.         mask_key = (image->GetMaskRed() << 16) |
  179.                    (image->GetMaskGreen() << 8) | image->GetMaskBlue();
  180.  
  181.     // 2b. generate colour table:
  182.     for (wxImageHistogram::iterator entry = histogram.begin();
  183.          entry != histogram.end(); entry++ )
  184.     {
  185.         unsigned long index = entry->second.index;
  186.         symbols[index] = symbols_data + index * (chars_per_pixel+1);
  187.         char *sym = symbols[index];
  188.  
  189.         k = index % MaxCixels;
  190.         sym[0] = Cixel[k];
  191.         for (j = 1; j < chars_per_pixel; j++)
  192.         {
  193.             k = ((index - k) / MaxCixels) % MaxCixels;
  194.             sym[j] = Cixel[k];
  195.         }
  196.         sym[j] = '\0';
  197.  
  198.         unsigned long key = entry->first;
  199.  
  200.         if (key == 0)
  201.             sprintf( tmpbuf, "\"%s c Black\",\n", sym);
  202.         else if (key == mask_key)
  203.             sprintf( tmpbuf, "\"%s c None\",\n", sym);
  204.         else
  205.         {
  206.             char rbuf[3];
  207.             DecToHex( (unsigned char)(key >> 16), rbuf );
  208.             char gbuf[3];
  209.             DecToHex( (unsigned char)(key >> 8), gbuf );
  210.             char bbuf[3];
  211.             DecToHex( (unsigned char)(key), bbuf );
  212.             sprintf( tmpbuf, "\"%s c #%s%s%s\",\n", sym, rbuf, gbuf, bbuf );
  213.         }
  214.         stream.Write( tmpbuf, strlen(tmpbuf) );
  215.     }
  216.  
  217.     tmp = wxT("/* pixels */\n");
  218.     stream.Write( (const char*) tmp.ToAscii(), tmp.Length() );
  219.  
  220.     unsigned char *data = image->GetData();
  221.     for (j = 0; j < image->GetHeight(); j++)
  222.     {
  223.         tmp_c = '\"'; stream.Write(&tmp_c, 1);
  224.         for (i = 0; i < image->GetWidth(); i++, data += 3)
  225.         {
  226.             unsigned long key = (data[0] << 16) | (data[1] << 8) | (data[2]);
  227.             stream.Write(symbols[histogram[key].index], chars_per_pixel);
  228.         }
  229.         tmp_c = '\"'; stream.Write(&tmp_c, 1);
  230.         if ( j + 1 < image->GetHeight() )
  231.         {
  232.             tmp_c = ','; stream.Write(&tmp_c, 1);
  233.         }
  234.         tmp_c = '\n'; stream.Write(&tmp_c, 1);
  235.     }
  236.     tmp = wxT("};\n");
  237.     stream.Write( (const char*) tmp.ToAscii(), 3 );
  238.  
  239.     // Clean up:
  240.     delete[] symbols;
  241.     delete[] symbols_data;
  242.  
  243.     return TRUE;
  244. }
  245.  
  246. bool wxXPMHandler::DoCanRead(wxInputStream& stream)
  247. {
  248.     wxXPMDecoder decoder;
  249.     return decoder.CanRead(stream);
  250. }
  251.  
  252. #endif  // wxUSE_STREAMS
  253.  
  254. #endif // wxUSE_XPM
  255.