1 /////////////////////////////////////////////////////////////////////////////
 
   3 // Purpose:     SWIG definitions for wxImage and such
 
   7 // Created:     25-Sept-2000
 
   9 // Copyright:   (c) 2003 by Total Control Software
 
  10 // Licence:     wxWindows license
 
  11 /////////////////////////////////////////////////////////////////////////////
 
  16 //---------------------------------------------------------------------------
 
  19 #include "wx/wxPython/pyistream.h"
 
  22 //---------------------------------------------------------------------------
 
  26 class wxImageHandler : public wxObject {
 
  28     // wxImageHandler();    Abstract Base Class
 
  30     wxString GetExtension();
 
  32     wxString GetMimeType();
 
  34     //bool LoadFile(wxImage* image, wxInputStream& stream);
 
  35     //bool SaveFile(wxImage* image, wxOutputStream& stream);
 
  36     //virtual int GetImageCount( wxInputStream& stream );
 
  37     //bool CanRead( wxInputStream& stream );
 
  39     bool CanRead( const wxString& name );
 
  41     void SetName(const wxString& name);
 
  42     void SetExtension(const wxString& extension);
 
  43     void SetType(long type);
 
  44     void SetMimeType(const wxString& mimetype);
 
  48 //---------------------------------------------------------------------------
 
  50 class wxImageHistogram /* : public wxImageHistogramBase */
 
  55     DocStr(MakeKey, "Get the key in the histogram for the given RGB values", "");
 
  56     static unsigned long MakeKey(unsigned char r,
 
  61         bool, FindFirstUnusedColour(unsigned char *OUTPUT,
 
  62                                     unsigned char *OUTPUT,
 
  63                                     unsigned char *OUTPUT,
 
  64                                     unsigned char startR = 1,
 
  65                                     unsigned char startG = 0,
 
  66                                     unsigned char startB = 0 ) const,
 
  67         "FindFirstUnusedColour(int startR=1, int startG=0, int startB=0) -> (success, r, g, b)",
 
  68         "Find first colour that is not used in the image and has higher RGB
 
  69 values than startR, startG, startB.  Returns a tuple consisting of a
 
  70 success flag and rgb values.", "");
 
  74                "Returns the pixel count for the given key.  Use `MakeKey` to create a
 
  75 key value from a RGB tripple.", "");
 
  76         unsigned long GetCount(unsigned long key) {
 
  77             wxImageHistogramEntry e = (*self)[key];
 
  82                "Returns the pixel count for the given RGB values.", "");
 
  83         unsigned long GetCountRGB(unsigned char r,
 
  86             unsigned long key = wxImageHistogram::MakeKey(r, g, b);
 
  87             wxImageHistogramEntry e = (*self)[key];
 
  91         DocStr(GetCountColour,
 
  92                "Returns the pixel count for the given `wx.Colour` value.", "");
 
  93         unsigned long GetCountColour(const wxColour& colour) {
 
  94             unsigned long key = wxImageHistogram::MakeKey(colour.Red(),
 
  97             wxImageHistogramEntry e = (*self)[key];
 
 105 //---------------------------------------------------------------------------
 
 108     typedef unsigned char* buffer;
 
 111 %typemap(in) (buffer data, int DATASIZE)
 
 112     { if (!PyArg_Parse($input, "t#", &$1, &$2)) SWIG_fail; }
 
 114 %typemap(in) (buffer alpha, int ALPHASIZE)
 
 115     { if (!PyArg_Parse($input, "t#", &$1, &$2)) SWIG_fail; }
 
 117 //---------------------------------------------------------------------------
 
 120 class wxImage : public wxObject {
 
 123         wxImage( const wxString& name, long type = wxBITMAP_TYPE_ANY, int index = -1 ),
 
 128     // Alternate constructors
 
 130         wxImage(const wxString& name, const wxString& mimetype, int index = -1),
 
 135         wxImage(wxInputStream& stream, long type = wxBITMAP_TYPE_ANY, int index = -1),
 
 140         wxImage(wxInputStream& stream, const wxString& mimetype, int index = -1 ),
 
 142         ImageFromStreamMime);
 
 147             "Construct an empty image of a given size, optionally setting all
 
 148 pixels to black.", "",
 
 149             wxImage(int width=0, int height=0, bool clear = true))
 
 151                 if (width > 0 && height > 0)
 
 152                     return new wxImage(width, height, clear);
 
 158        MustHaveApp(wxImage(const wxBitmap &bitmap));
 
 162             "Construct an Image from a `wx.Bitmap`.", "",
 
 163             wxImage(const wxBitmap &bitmap))
 
 165                 return new wxImage(bitmap.ConvertToImage());
 
 170             "Construct an Image from a buffer of RGB bytes.  Accepts either a
 
 171 string or a buffer object holding the data and the length of the data
 
 172 must be width*height*3.", "",
 
 173             wxImage(int width, int height, buffer data, int DATASIZE))
 
 175                 if (DATASIZE != width*height*3) {
 
 176                     wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 180                 // Copy the source data so the wxImage can clean it up later
 
 181                 buffer copy = (buffer)malloc(DATASIZE);
 
 183                     wxPyBLOCK_THREADS(PyErr_NoMemory());
 
 186                 memcpy(copy, data, DATASIZE);
 
 187                 return new wxImage(width, height, copy, false);
 
 192             ImageFromDataWithAlpha,
 
 193             "Construct an Image from a buffer of RGB bytes with an Alpha channel.
 
 194 Accepts either a string or a buffer object holding the data and the
 
 195 length of the data must be width*height*3.", "",
 
 196             wxImage(int width, int height, buffer data, int DATASIZE, buffer alpha, int ALPHASIZE))
 
 198                 if (DATASIZE != width*height*3) {
 
 199                     wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 202                 if (ALPHASIZE != width*height) {
 
 203                     wxPyErr_SetString(PyExc_ValueError, "Invalid alpha buffer size.");
 
 207                 // Copy the source data so the wxImage can clean it up later
 
 208                 buffer dcopy = (buffer)malloc(DATASIZE);
 
 210                     wxPyBLOCK_THREADS(PyErr_NoMemory());
 
 213                 memcpy(dcopy, data, DATASIZE);
 
 215                 buffer acopy = (buffer)malloc(ALPHASIZE);
 
 217                     wxPyBLOCK_THREADS(PyErr_NoMemory());
 
 220                 memcpy(acopy, alpha, ALPHASIZE);
 
 222                 return new wxImage(width, height, dcopy, acopy, false);
 
 226     // TODO: wxImage( char** xpmData );
 
 229     void Create( int width, int height );
 
 232     wxImage Scale( int width, int height );
 
 233     wxImage ShrinkBy( int xFactor , int yFactor ) const ;
 
 234     wxImage& Rescale(int width, int height);
 
 236     // resizes the image in place
 
 237     wxImage& Resize( const wxSize& size, const wxPoint& pos, 
 
 238                      int r = -1, int g = -1, int b = -1 );
 
 240     void SetRGB( int x, int y, unsigned char r, unsigned char g, unsigned char b );
 
 243             void, SetRGB( const wxRect& rect,
 
 244                           unsigned char r, unsigned char g, unsigned char b ));
 
 246     unsigned char GetRed( int x, int y );
 
 247     unsigned char GetGreen( int x, int y );
 
 248     unsigned char GetBlue( int x, int y );
 
 250     void SetAlpha(int x, int y, unsigned char alpha);
 
 251     unsigned char GetAlpha(int x, int y);
 
 256         "Initializes the image alpha channel data. It is an error to call it if
 
 257 the image already has alpha data. If it doesn't, alpha data will be by
 
 258 default initialized to all pixels being fully opaque. But if the image
 
 259 has a a mask colour, all mask pixels will be completely transparent.", "");
 
 262     // find first colour that is not used in the image and has higher
 
 263     // RGB values than <startR,startG,startB>
 
 265         bool, FindFirstUnusedColour( byte *OUTPUT, byte *OUTPUT, byte *OUTPUT,
 
 266                                      byte startR = 0, byte startG = 0, byte startB = 0 ) const,
 
 267         "FindFirstUnusedColour(int startR=1, int startG=0, int startB=0) -> (success, r, g, b)",
 
 268         "Find first colour that is not used in the image and has higher RGB
 
 269 values than startR, startG, startB.  Returns a tuple consisting of a
 
 270 success flag and rgb values.", "");
 
 274         bool , ConvertAlphaToMask(byte threshold = 128),
 
 275         "If the image has alpha channel, this method converts it to mask. All pixels
 
 276 with alpha value less than ``threshold`` are replaced with mask colour and the
 
 277 alpha channel is removed. Mask colour is chosen automatically using
 
 278 `FindFirstUnusedColour`.
 
 280 If the image image doesn't have alpha channel, ConvertAlphaToMask does
 
 285         bool , ConvertColourToAlpha( unsigned char r, unsigned char g, unsigned char b ),
 
 286         "This method converts an image where the original alpha information is
 
 287 only available as a shades of a colour (actually shades of grey)
 
 288 typically when you draw anti-aliased text into a bitmap. The DC
 
 289 drawing routines draw grey values on the black background although
 
 290 they actually mean to draw white with differnt alpha values.  This
 
 291 method reverses it, assuming a black (!) background and white text.
 
 292 The method will then fill up the whole image with the colour given.", "");
 
 296     // Set image's mask to the area of 'mask' that has <mr,mg,mb> colour
 
 297     bool SetMaskFromImage(const wxImage & mask,
 
 298                           byte mr, byte mg, byte mb);
 
 300 //      void DoFloodFill (wxCoord x, wxCoord y,
 
 301 //          const wxBrush & fillBrush,
 
 302 //          const wxColour& testColour,
 
 303 //          int style = wxFLOOD_SURFACE,
 
 304 //          int LogicalFunction = wxCOPY /* currently unused */ ) ;
 
 306     static bool CanRead( const wxString& name );
 
 307     static int GetImageCount( const wxString& name, long type = wxBITMAP_TYPE_ANY );
 
 309     bool LoadFile( const wxString& name, long type = wxBITMAP_TYPE_ANY, int index = -1 );
 
 310     %Rename(LoadMimeFile, bool,  LoadFile( const wxString& name, const wxString& mimetype, int index = -1 ));
 
 312     bool SaveFile( const wxString& name, int type );
 
 313     %Rename(SaveMimeFile, bool,  SaveFile( const wxString& name, const wxString& mimetype ));
 
 315     %Rename(CanReadStream, static bool,  CanRead( wxInputStream& stream ));
 
 316     %Rename(LoadStream, bool,  LoadFile( wxInputStream& stream, long type = wxBITMAP_TYPE_ANY, int index = -1 ));
 
 317     %Rename(LoadMimeStream, bool,  LoadFile( wxInputStream& stream, const wxString& mimetype, int index = -1 ));
 
 325             wxSize size(self->GetWidth(), self->GetHeight());
 
 330     wxImage GetSubImage(const wxRect& rect);
 
 332     // Paste the image or part of this image into an image of the given size at the pos
 
 333     //  any newly exposed areas will be filled with the rgb colour
 
 334     //  by default if r = g = b = -1 then fill with this image's mask colour or find and 
 
 335     //  set a suitable mask colour
 
 336     wxImage Size( const wxSize& size, const wxPoint& pos, 
 
 337                   int r = -1, int g = -1, int b = -1 ) const;
 
 340     void Paste( const wxImage &image, int x, int y );
 
 342     //unsigned char *GetData();
 
 343     //void SetData( unsigned char *data );
 
 347                "Returns a string containing a copy of the RGB bytes of the image.", "");
 
 350             buffer data = self->GetData();
 
 351             int len = self->GetWidth() * self->GetHeight() * 3;
 
 353             wxPyBLOCK_THREADS( rv = PyString_FromStringAndSize((char*)data, len));
 
 357                "Resets the Image's RGB data from a buffer of RGB bytes.  Accepts
 
 358 either a string or a buffer object holding the data and the length of
 
 359 the data must be width*height*3.", "");
 
 360         void SetData(buffer data, int DATASIZE)
 
 362             if (DATASIZE != self->GetWidth() * self->GetHeight() * 3) {
 
 363                 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 366             buffer copy = (buffer)malloc(DATASIZE);
 
 368                 wxPyBLOCK_THREADS(PyErr_NoMemory());
 
 371             memcpy(copy, data, DATASIZE);
 
 372             self->SetData(copy, false);
 
 373             // wxImage takes ownership of copy...
 
 377         DocStr(GetDataBuffer,
 
 378                "Returns a writable Python buffer object that is pointing at the RGB
 
 379 image data buffer inside the wx.Image.", "");
 
 380         PyObject* GetDataBuffer()
 
 382             buffer data = self->GetData();
 
 383             int len = self->GetWidth() * self->GetHeight() * 3;
 
 385             wxPyBLOCK_THREADS( rv = PyBuffer_FromReadWriteMemory(data, len) );
 
 389         DocStr(SetDataBuffer,
 
 390                "Sets the internal image data pointer to point at a Python buffer
 
 391 object.  This can save a copy of the data but you must ensure that the
 
 392 buffer object lives longer than the wx.Image does.", "");
 
 393         void SetDataBuffer(buffer data, int DATASIZE)
 
 395             if (DATASIZE != self->GetWidth() * self->GetHeight() * 3) {
 
 396                 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 399             self->SetData(data, true);
 
 405                "Returns a string containing a copy of the alpha bytes of the image.", "");
 
 406         PyObject* GetAlphaData() {
 
 407             buffer data = self->GetAlpha();
 
 411                 int len = self->GetWidth() * self->GetHeight();
 
 413                 wxPyBLOCK_THREADS( rv = PyString_FromStringAndSize((char*)data, len) );
 
 419                "Resets the Image's alpha data from a buffer of bytes.  Accepts either
 
 420 a string or a buffer object holding the data and the length of the
 
 421 data must be width*height.", ""); 
 
 422         void SetAlphaData(buffer alpha, int ALPHASIZE)
 
 424             if (ALPHASIZE != self->GetWidth() * self->GetHeight()) {
 
 425                 wxPyErr_SetString(PyExc_ValueError, "Invalid alpha buffer size.");
 
 428             buffer acopy = (buffer)malloc(ALPHASIZE);
 
 430                 wxPyBLOCK_THREADS(PyErr_NoMemory());
 
 433             memcpy(acopy, alpha, ALPHASIZE);
 
 434             self->SetAlpha(acopy, false);
 
 435             // wxImage takes ownership of acopy...
 
 440         DocStr(GetDataBuffer,
 
 441                "Returns a writable Python buffer object that is pointing at the Alpha
 
 442 data buffer inside the wx.Image.", "");
 
 443         PyObject* GetAlphaBuffer()
 
 445             buffer data = self->GetAlpha();
 
 446             int len = self->GetWidth() * self->GetHeight();
 
 448             wxPyBLOCK_THREADS( rv = PyBuffer_FromReadWriteMemory(data, len) );
 
 453         DocStr(SetDataBuffer,
 
 454                "Sets the internal image alpha pointer to point at a Python buffer
 
 455 object.  This can save a copy of the data but you must ensure that the
 
 456 buffer object lives longer than the wx.Image does.", "");
 
 457         void SetAlphaBuffer(buffer alpha, int ALPHASIZE)
 
 459             if (ALPHASIZE != self->GetWidth() * self->GetHeight()) {
 
 460                 wxPyErr_SetString(PyExc_ValueError, "Invalid alpha buffer size.");
 
 463             self->SetAlpha(alpha, true);
 
 467     void SetMaskColour( unsigned char r, unsigned char g, unsigned char b );
 
 470         /*bool*/ void , GetOrFindMaskColour( unsigned char *OUTPUT,
 
 471                                              unsigned char *OUTPUT,
 
 472                                              unsigned char *OUTPUT ) const,
 
 473         "GetOrFindMaskColour() -> (r,g,b)",
 
 474         "Get the current mask colour or find a suitable colour.", "");
 
 477     unsigned char GetMaskRed();
 
 478     unsigned char GetMaskGreen();
 
 479     unsigned char GetMaskBlue();
 
 480     void SetMask( bool mask = true );
 
 483     wxImage Rotate(double angle, const wxPoint & centre_of_rotation,
 
 484                    bool interpolating = true, wxPoint * offset_after_rotation = NULL) const ;
 
 485     wxImage Rotate90( bool clockwise = true ) ;
 
 486     wxImage Mirror( bool horizontally = true ) ;
 
 488     void Replace( unsigned char r1, unsigned char g1, unsigned char b1,
 
 489                   unsigned char r2, unsigned char g2, unsigned char b2 );
 
 491     // convert to monochrome image (<r,g,b> will be replaced by white, everything else by black)
 
 492     wxImage ConvertToMono( unsigned char r, unsigned char g, unsigned char b ) const;
 
 494     void SetOption(const wxString& name, const wxString& value);
 
 495     %Rename(SetOptionInt, void,  SetOption(const wxString& name, int value));
 
 496     wxString GetOption(const wxString& name) const;
 
 497     int GetOptionInt(const wxString& name) const;
 
 498     bool HasOption(const wxString& name) const;
 
 500     unsigned long CountColours( unsigned long stopafter = (unsigned long) -1 );
 
 501     unsigned long ComputeHistogram( wxImageHistogram& h );
 
 503     static void AddHandler( wxImageHandler *handler );
 
 504     static void InsertHandler( wxImageHandler *handler );
 
 505     static bool RemoveHandler( const wxString& name );
 
 506     static wxString GetImageExtWildcard();
 
 509 MustHaveApp(ConvertToBitmap);
 
 510 MustHaveApp(ConvertToMonoBitmap);
 
 513         wxBitmap ConvertToBitmap(int depth=-1) {
 
 514             wxBitmap bitmap(*self, depth);
 
 518         wxBitmap ConvertToMonoBitmap( unsigned char red,
 
 520                                       unsigned char blue ) {
 
 521             wxImage mono = self->ConvertToMono( red, green, blue );
 
 522             wxBitmap bitmap( mono, 1 );
 
 527     %pythoncode { def __nonzero__(self): return self.Ok() }
 
 532 ///void wxInitAllImageHandlers();
 
 535     def InitAllImageHandlers():
 
 537         The former functionality of InitAllImageHanders is now done internal to
 
 538         the _core_ extension module and so this function has become a simple NOP.
 
 545 // See also wxPy_ReinitStockObjects in helpers.cpp
 
 547 const wxImage    wxNullImage;
 
 550 //---------------------------------------------------------------------------
 
 552 MAKE_CONST_WXSTRING(IMAGE_OPTION_FILENAME);
 
 553 MAKE_CONST_WXSTRING(IMAGE_OPTION_BMP_FORMAT);
 
 554 MAKE_CONST_WXSTRING(IMAGE_OPTION_CUR_HOTSPOT_X);
 
 555 MAKE_CONST_WXSTRING(IMAGE_OPTION_CUR_HOTSPOT_Y);
 
 556 MAKE_CONST_WXSTRING(IMAGE_OPTION_RESOLUTION);
 
 557 MAKE_CONST_WXSTRING(IMAGE_OPTION_RESOLUTIONX);
 
 558 MAKE_CONST_WXSTRING(IMAGE_OPTION_RESOLUTIONY);
 
 559 MAKE_CONST_WXSTRING(IMAGE_OPTION_RESOLUTIONUNIT);
 
 560 MAKE_CONST_WXSTRING(IMAGE_OPTION_QUALITY);
 
 564     wxIMAGE_RESOLUTION_INCHES = 1,
 
 565     wxIMAGE_RESOLUTION_CM = 2
 
 569 MAKE_CONST_WXSTRING(IMAGE_OPTION_BITSPERSAMPLE);
 
 570 MAKE_CONST_WXSTRING(IMAGE_OPTION_SAMPLESPERPIXEL); 
 
 571 MAKE_CONST_WXSTRING(IMAGE_OPTION_COMPRESSION);
 
 572 MAKE_CONST_WXSTRING(IMAGE_OPTION_IMAGEDESCRIPTOR);
 
 574 MAKE_CONST_WXSTRING(IMAGE_OPTION_PNG_FORMAT);
 
 575 MAKE_CONST_WXSTRING(IMAGE_OPTION_PNG_BITDEPTH);
 
 579     wxPNG_TYPE_COLOUR = 0,
 
 581     wxPNG_TYPE_GREY_RED = 3
 
 586     wxBMP_24BPP        = 24, // default, do not need to set
 
 587     //wxBMP_16BPP      = 16, // wxQuantize can only do 236 colors?
 
 588     wxBMP_8BPP         =  8, // 8bpp, quantized colors
 
 589     wxBMP_8BPP_GREY    =  9, // 8bpp, rgb averaged to greys
 
 590     wxBMP_8BPP_GRAY    =  wxBMP_8BPP_GREY,
 
 591     wxBMP_8BPP_RED     = 10, // 8bpp, red used as greyscale
 
 592     wxBMP_8BPP_PALETTE = 11, // 8bpp, use the wxImage's palette
 
 593     wxBMP_4BPP         =  4, // 4bpp, quantized colors
 
 594     wxBMP_1BPP         =  1, // 1bpp, quantized "colors"
 
 595     wxBMP_1BPP_BW      =  2  // 1bpp, black & white from red
 
 599 class wxBMPHandler : public wxImageHandler {
 
 604 class wxICOHandler : public wxBMPHandler {
 
 609 class wxCURHandler : public wxICOHandler {
 
 614 class wxANIHandler : public wxCURHandler {
 
 620 //---------------------------------------------------------------------------
 
 622 class wxPNGHandler : public wxImageHandler {
 
 628 class wxGIFHandler : public wxImageHandler {
 
 634 class wxPCXHandler : public wxImageHandler {
 
 640 class wxJPEGHandler : public wxImageHandler {
 
 646 class wxPNMHandler : public wxImageHandler {
 
 651 class wxXPMHandler : public wxImageHandler {
 
 656 class wxTIFFHandler : public wxImageHandler {
 
 663 class wxIFFHandler : public wxImageHandler {
 
 669 //---------------------------------------------------------------------------
 
 672 #include <wx/quantize.h>
 
 676     wxQUANTIZE_INCLUDE_WINDOWS_COLOURS,
 
 677 //    wxQUANTIZE_RETURN_8BIT_DATA,
 
 678     wxQUANTIZE_FILL_DESTINATION_IMAGE
 
 683        "Performs quantization, or colour reduction, on a wxImage.", "");
 
 685 class wxQuantize /*: public wxObject */
 
 692             "Reduce the colours in the source image and put the result into the
 
 693 destination image, setting the palette in the destination if
 
 694 needed. Both images may be the same, to overwrite the source image.", "
 
 695 :todo: Create a version that returns the wx.Palette used.");
 
 697         static bool Quantize(const wxImage& src, wxImage& dest, int desiredNoColours = 236,
 
 698                              int flags = wxQUANTIZE_INCLUDE_WINDOWS_COLOURS|wxQUANTIZE_FILL_DESTINATION_IMAGE)
 
 700                 return wxQuantize::Quantize(src, dest, 
 
 703                                             NULL, // eightBitData
 
 710 //---------------------------------------------------------------------------