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 //---------------------------------------------------------------------------
 
  25     wxIMAGE_ALPHA_TRANSPARENT,
 
  26     wxIMAGE_ALPHA_THRESHOLD,
 
  31 //---------------------------------------------------------------------------
 
  35 class wxImageHandler : public wxObject {
 
  37     // wxImageHandler();    Abstract Base Class
 
  39     wxString GetExtension();
 
  41     wxString GetMimeType();
 
  43     //bool LoadFile(wxImage* image, wxInputStream& stream);
 
  44     //bool SaveFile(wxImage* image, wxOutputStream& stream);
 
  45     //virtual int GetImageCount( wxInputStream& stream );
 
  46     //bool CanRead( wxInputStream& stream );
 
  48     bool CanRead( const wxString& name );
 
  50     void SetName(const wxString& name);
 
  51     void SetExtension(const wxString& extension);
 
  52     void SetType(long type);
 
  53     void SetMimeType(const wxString& mimetype);
 
  57 //---------------------------------------------------------------------------
 
  59 class wxImageHistogram /* : public wxImageHistogramBase */
 
  64     DocStr(MakeKey, "Get the key in the histogram for the given RGB values", "");
 
  65     static unsigned long MakeKey(unsigned char r,
 
  70         bool, FindFirstUnusedColour(unsigned char *OUTPUT,
 
  71                                     unsigned char *OUTPUT,
 
  72                                     unsigned char *OUTPUT,
 
  73                                     unsigned char startR = 1,
 
  74                                     unsigned char startG = 0,
 
  75                                     unsigned char startB = 0 ) const,
 
  76         "FindFirstUnusedColour(int startR=1, int startG=0, int startB=0) -> (success, r, g, b)",
 
  77         "Find first colour that is not used in the image and has higher RGB
 
  78 values than startR, startG, startB.  Returns a tuple consisting of a
 
  79 success flag and rgb values.", "");
 
  83                "Returns the pixel count for the given key.  Use `MakeKey` to create a
 
  84 key value from a RGB tripple.", "");
 
  85         unsigned long GetCount(unsigned long key) {
 
  86             wxImageHistogramEntry e = (*self)[key];
 
  91                "Returns the pixel count for the given RGB values.", "");
 
  92         unsigned long GetCountRGB(unsigned char r,
 
  95             unsigned long key = wxImageHistogram::MakeKey(r, g, b);
 
  96             wxImageHistogramEntry e = (*self)[key];
 
 100         DocStr(GetCountColour,
 
 101                "Returns the pixel count for the given `wx.Colour` value.", "");
 
 102         unsigned long GetCountColour(const wxColour& colour) {
 
 103             unsigned long key = wxImageHistogram::MakeKey(colour.Red(),
 
 106             wxImageHistogramEntry e = (*self)[key];
 
 114 //---------------------------------------------------------------------------
 
 117     typedef unsigned char* buffer;
 
 120 %typemap(in) (buffer data, int DATASIZE)
 
 121     { if (!PyArg_Parse($input, "t#", &$1, &$2)) SWIG_fail; }
 
 123 %typemap(in) (buffer alpha, int ALPHASIZE)
 
 124     { if (!PyArg_Parse($input, "t#", &$1, &$2)) SWIG_fail; }
 
 126 //---------------------------------------------------------------------------
 
 129 class wxImage : public wxObject {
 
 132         wxImage( const wxString& name, long type = wxBITMAP_TYPE_ANY, int index = -1 ),
 
 137     // Alternate constructors
 
 139         wxImage(const wxString& name, const wxString& mimetype, int index = -1),
 
 144         wxImage(wxInputStream& stream, long type = wxBITMAP_TYPE_ANY, int index = -1),
 
 149         wxImage(wxInputStream& stream, const wxString& mimetype, int index = -1 ),
 
 151         ImageFromStreamMime);
 
 156             "Construct an empty image of a given size, optionally setting all
 
 157 pixels to black.", "",
 
 158             wxImage(int width=0, int height=0, bool clear = true))
 
 160                 if (width > 0 && height > 0)
 
 161                     return new wxImage(width, height, clear);
 
 167        MustHaveApp(wxImage(const wxBitmap &bitmap));
 
 171             "Construct an Image from a `wx.Bitmap`.", "",
 
 172             wxImage(const wxBitmap &bitmap))
 
 174                 return new wxImage(bitmap.ConvertToImage());
 
 179             "Construct an Image from a buffer of RGB bytes.  Accepts either a
 
 180 string or a buffer object holding the data and the length of the data
 
 181 must be width*height*3.", "",
 
 182             wxImage(int width, int height, buffer data, int DATASIZE))
 
 184                 if (DATASIZE != width*height*3) {
 
 185                     wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 189                 // Copy the source data so the wxImage can clean it up later
 
 190                 buffer copy = (buffer)malloc(DATASIZE);
 
 192                     wxPyBLOCK_THREADS(PyErr_NoMemory());
 
 195                 memcpy(copy, data, DATASIZE);
 
 196                 return new wxImage(width, height, copy, false);
 
 201             ImageFromDataWithAlpha,
 
 202             "Construct an Image from a buffer of RGB bytes with an Alpha channel.
 
 203 Accepts either a string or a buffer object holding the data and the
 
 204 length of the data must be width*height*3.", "",
 
 205             wxImage(int width, int height, buffer data, int DATASIZE, buffer alpha, int ALPHASIZE))
 
 207                 if (DATASIZE != width*height*3) {
 
 208                     wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 211                 if (ALPHASIZE != width*height) {
 
 212                     wxPyErr_SetString(PyExc_ValueError, "Invalid alpha buffer size.");
 
 216                 // Copy the source data so the wxImage can clean it up later
 
 217                 buffer dcopy = (buffer)malloc(DATASIZE);
 
 219                     wxPyBLOCK_THREADS(PyErr_NoMemory());
 
 222                 memcpy(dcopy, data, DATASIZE);
 
 224                 buffer acopy = (buffer)malloc(ALPHASIZE);
 
 226                     wxPyBLOCK_THREADS(PyErr_NoMemory());
 
 229                 memcpy(acopy, alpha, ALPHASIZE);
 
 231                 return new wxImage(width, height, dcopy, acopy, false);
 
 235     // TODO: wxImage( char** xpmData );
 
 238     void Create( int width, int height );
 
 241     wxImage Scale( int width, int height );
 
 242     wxImage ShrinkBy( int xFactor , int yFactor ) const ;
 
 243     wxImage& Rescale(int width, int height);
 
 245     // resizes the image in place
 
 246     wxImage& Resize( const wxSize& size, const wxPoint& pos, 
 
 247                      int r = -1, int g = -1, int b = -1 );
 
 249     void SetRGB( int x, int y, unsigned char r, unsigned char g, unsigned char b );
 
 252             void, SetRGB( const wxRect& rect,
 
 253                           unsigned char r, unsigned char g, unsigned char b ));
 
 255     unsigned char GetRed( int x, int y );
 
 256     unsigned char GetGreen( int x, int y );
 
 257     unsigned char GetBlue( int x, int y );
 
 259     void SetAlpha(int x, int y, unsigned char alpha);
 
 260     unsigned char GetAlpha(int x, int y);
 
 265         "Initializes the image alpha channel data. It is an error to call it if
 
 266 the image already has alpha data. If it doesn't, alpha data will be by
 
 267 default initialized to all pixels being fully opaque. But if the image
 
 268 has a a mask colour, all mask pixels will be completely transparent.", "");
 
 272         bool , IsTransparent(int x, int y,
 
 273                              unsigned char threshold = wxIMAGE_ALPHA_THRESHOLD) const,
 
 274         "Returns True if this pixel is masked or has an alpha value less than
 
 275 the spcified threshold.", "");
 
 278     // find first colour that is not used in the image and has higher
 
 279     // RGB values than <startR,startG,startB>
 
 281         bool, FindFirstUnusedColour( byte *OUTPUT, byte *OUTPUT, byte *OUTPUT,
 
 282                                      byte startR = 0, byte startG = 0, byte startB = 0 ) const,
 
 283         "FindFirstUnusedColour(int startR=1, int startG=0, int startB=0) -> (success, r, g, b)",
 
 284         "Find first colour that is not used in the image and has higher RGB
 
 285 values than startR, startG, startB.  Returns a tuple consisting of a
 
 286 success flag and rgb values.", "");
 
 290         bool , ConvertAlphaToMask(byte threshold = wxIMAGE_ALPHA_THRESHOLD),
 
 291         "If the image has alpha channel, this method converts it to mask. All pixels
 
 292 with alpha value less than ``threshold`` are replaced with mask colour and the
 
 293 alpha channel is removed. Mask colour is chosen automatically using
 
 294 `FindFirstUnusedColour`.
 
 296 If the image image doesn't have alpha channel, ConvertAlphaToMask does
 
 301         bool , ConvertColourToAlpha( unsigned char r, unsigned char g, unsigned char b ),
 
 302         "This method converts an image where the original alpha information is
 
 303 only available as a shades of a colour (actually shades of grey)
 
 304 typically when you draw anti-aliased text into a bitmap. The DC
 
 305 drawing routines draw grey values on the black background although
 
 306 they actually mean to draw white with differnt alpha values.  This
 
 307 method reverses it, assuming a black (!) background and white text.
 
 308 The method will then fill up the whole image with the colour given.", "");
 
 312     // Set image's mask to the area of 'mask' that has <mr,mg,mb> colour
 
 313     bool SetMaskFromImage(const wxImage & mask,
 
 314                           byte mr, byte mg, byte mb);
 
 316 //      void DoFloodFill (wxCoord x, wxCoord y,
 
 317 //          const wxBrush & fillBrush,
 
 318 //          const wxColour& testColour,
 
 319 //          int style = wxFLOOD_SURFACE,
 
 320 //          int LogicalFunction = wxCOPY /* currently unused */ ) ;
 
 322     static bool CanRead( const wxString& name );
 
 323     static int GetImageCount( const wxString& name, long type = wxBITMAP_TYPE_ANY );
 
 325     bool LoadFile( const wxString& name, long type = wxBITMAP_TYPE_ANY, int index = -1 );
 
 326     %Rename(LoadMimeFile, bool,  LoadFile( const wxString& name, const wxString& mimetype, int index = -1 ));
 
 328     bool SaveFile( const wxString& name, int type );
 
 329     %Rename(SaveMimeFile, bool,  SaveFile( const wxString& name, const wxString& mimetype ));
 
 331     %Rename(CanReadStream, static bool,  CanRead( wxInputStream& stream ));
 
 332     %Rename(LoadStream, bool,  LoadFile( wxInputStream& stream, long type = wxBITMAP_TYPE_ANY, int index = -1 ));
 
 333     %Rename(LoadMimeStream, bool,  LoadFile( wxInputStream& stream, const wxString& mimetype, int index = -1 ));
 
 341             wxSize size(self->GetWidth(), self->GetHeight());
 
 346     wxImage GetSubImage(const wxRect& rect);
 
 348     // Paste the image or part of this image into an image of the given size at the pos
 
 349     //  any newly exposed areas will be filled with the rgb colour
 
 350     //  by default if r = g = b = -1 then fill with this image's mask colour or find and 
 
 351     //  set a suitable mask colour
 
 352     wxImage Size( const wxSize& size, const wxPoint& pos, 
 
 353                   int r = -1, int g = -1, int b = -1 ) const;
 
 356     void Paste( const wxImage &image, int x, int y );
 
 358     //unsigned char *GetData();
 
 359     //void SetData( unsigned char *data );
 
 363                "Returns a string containing a copy of the RGB bytes of the image.", "");
 
 366             buffer data = self->GetData();
 
 367             int len = self->GetWidth() * self->GetHeight() * 3;
 
 369             wxPyBLOCK_THREADS( rv = PyString_FromStringAndSize((char*)data, len));
 
 373                "Resets the Image's RGB data from a buffer of RGB bytes.  Accepts
 
 374 either a string or a buffer object holding the data and the length of
 
 375 the data must be width*height*3.", "");
 
 376         void SetData(buffer data, int DATASIZE)
 
 378             if (DATASIZE != self->GetWidth() * self->GetHeight() * 3) {
 
 379                 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 382             buffer copy = (buffer)malloc(DATASIZE);
 
 384                 wxPyBLOCK_THREADS(PyErr_NoMemory());
 
 387             memcpy(copy, data, DATASIZE);
 
 388             self->SetData(copy, false);
 
 389             // wxImage takes ownership of copy...
 
 393         DocStr(GetDataBuffer,
 
 394                "Returns a writable Python buffer object that is pointing at the RGB
 
 395 image data buffer inside the wx.Image.", "");
 
 396         PyObject* GetDataBuffer()
 
 398             buffer data = self->GetData();
 
 399             int len = self->GetWidth() * self->GetHeight() * 3;
 
 401             wxPyBLOCK_THREADS( rv = PyBuffer_FromReadWriteMemory(data, len) );
 
 405         DocStr(SetDataBuffer,
 
 406                "Sets the internal image data pointer to point at a Python buffer
 
 407 object.  This can save a copy of the data but you must ensure that the
 
 408 buffer object lives longer than the wx.Image does.", "");
 
 409         void SetDataBuffer(buffer data, int DATASIZE)
 
 411             if (DATASIZE != self->GetWidth() * self->GetHeight() * 3) {
 
 412                 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 415             self->SetData(data, true);
 
 421                "Returns a string containing a copy of the alpha bytes of the image.", "");
 
 422         PyObject* GetAlphaData() {
 
 423             buffer data = self->GetAlpha();
 
 427                 int len = self->GetWidth() * self->GetHeight();
 
 429                 wxPyBLOCK_THREADS( rv = PyString_FromStringAndSize((char*)data, len) );
 
 435                "Resets the Image's alpha data from a buffer of bytes.  Accepts either
 
 436 a string or a buffer object holding the data and the length of the
 
 437 data must be width*height.", ""); 
 
 438         void SetAlphaData(buffer alpha, int ALPHASIZE)
 
 440             if (ALPHASIZE != self->GetWidth() * self->GetHeight()) {
 
 441                 wxPyErr_SetString(PyExc_ValueError, "Invalid alpha buffer size.");
 
 444             buffer acopy = (buffer)malloc(ALPHASIZE);
 
 446                 wxPyBLOCK_THREADS(PyErr_NoMemory());
 
 449             memcpy(acopy, alpha, ALPHASIZE);
 
 450             self->SetAlpha(acopy, false);
 
 451             // wxImage takes ownership of acopy...
 
 456         DocStr(GetDataBuffer,
 
 457                "Returns a writable Python buffer object that is pointing at the Alpha
 
 458 data buffer inside the wx.Image.", "");
 
 459         PyObject* GetAlphaBuffer()
 
 461             buffer data = self->GetAlpha();
 
 462             int len = self->GetWidth() * self->GetHeight();
 
 464             wxPyBLOCK_THREADS( rv = PyBuffer_FromReadWriteMemory(data, len) );
 
 469         DocStr(SetDataBuffer,
 
 470                "Sets the internal image alpha pointer to point at a Python buffer
 
 471 object.  This can save a copy of the data but you must ensure that the
 
 472 buffer object lives longer than the wx.Image does.", "");
 
 473         void SetAlphaBuffer(buffer alpha, int ALPHASIZE)
 
 475             if (ALPHASIZE != self->GetWidth() * self->GetHeight()) {
 
 476                 wxPyErr_SetString(PyExc_ValueError, "Invalid alpha buffer size.");
 
 479             self->SetAlpha(alpha, true);
 
 483     void SetMaskColour( unsigned char r, unsigned char g, unsigned char b );
 
 486         /*bool*/ void , GetOrFindMaskColour( unsigned char *OUTPUT,
 
 487                                              unsigned char *OUTPUT,
 
 488                                              unsigned char *OUTPUT ) const,
 
 489         "GetOrFindMaskColour() -> (r,g,b)",
 
 490         "Get the current mask colour or find a suitable colour.", "");
 
 493     unsigned char GetMaskRed();
 
 494     unsigned char GetMaskGreen();
 
 495     unsigned char GetMaskBlue();
 
 496     void SetMask( bool mask = true );
 
 499     wxImage Rotate(double angle, const wxPoint & centre_of_rotation,
 
 500                    bool interpolating = true, wxPoint * offset_after_rotation = NULL) const ;
 
 501     wxImage Rotate90( bool clockwise = true ) ;
 
 502     wxImage Mirror( bool horizontally = true ) ;
 
 504     void Replace( unsigned char r1, unsigned char g1, unsigned char b1,
 
 505                   unsigned char r2, unsigned char g2, unsigned char b2 );
 
 507     // convert to monochrome image (<r,g,b> will be replaced by white, everything else by black)
 
 508     wxImage ConvertToMono( unsigned char r, unsigned char g, unsigned char b ) const;
 
 510     void SetOption(const wxString& name, const wxString& value);
 
 511     %Rename(SetOptionInt, void,  SetOption(const wxString& name, int value));
 
 512     wxString GetOption(const wxString& name) const;
 
 513     int GetOptionInt(const wxString& name) const;
 
 514     bool HasOption(const wxString& name) const;
 
 516     unsigned long CountColours( unsigned long stopafter = (unsigned long) -1 );
 
 517     unsigned long ComputeHistogram( wxImageHistogram& h );
 
 519     static void AddHandler( wxImageHandler *handler );
 
 520     static void InsertHandler( wxImageHandler *handler );
 
 521     static bool RemoveHandler( const wxString& name );
 
 522     static wxString GetImageExtWildcard();
 
 525 MustHaveApp(ConvertToBitmap);
 
 526 MustHaveApp(ConvertToMonoBitmap);
 
 529         wxBitmap ConvertToBitmap(int depth=-1) {
 
 530             wxBitmap bitmap(*self, depth);
 
 534         wxBitmap ConvertToMonoBitmap( unsigned char red,
 
 536                                       unsigned char blue ) {
 
 537             wxImage mono = self->ConvertToMono( red, green, blue );
 
 538             wxBitmap bitmap( mono, 1 );
 
 543     %pythoncode { def __nonzero__(self): return self.Ok() }
 
 548 ///void wxInitAllImageHandlers();
 
 551     def InitAllImageHandlers():
 
 553         The former functionality of InitAllImageHanders is now done internal to
 
 554         the _core_ extension module and so this function has become a simple NOP.
 
 561 // See also wxPy_ReinitStockObjects in helpers.cpp
 
 563 const wxImage    wxNullImage;
 
 566 //---------------------------------------------------------------------------
 
 568 MAKE_CONST_WXSTRING(IMAGE_OPTION_FILENAME);
 
 569 MAKE_CONST_WXSTRING(IMAGE_OPTION_BMP_FORMAT);
 
 570 MAKE_CONST_WXSTRING(IMAGE_OPTION_CUR_HOTSPOT_X);
 
 571 MAKE_CONST_WXSTRING(IMAGE_OPTION_CUR_HOTSPOT_Y);
 
 572 MAKE_CONST_WXSTRING(IMAGE_OPTION_RESOLUTION);
 
 573 MAKE_CONST_WXSTRING(IMAGE_OPTION_RESOLUTIONX);
 
 574 MAKE_CONST_WXSTRING(IMAGE_OPTION_RESOLUTIONY);
 
 575 MAKE_CONST_WXSTRING(IMAGE_OPTION_RESOLUTIONUNIT);
 
 576 MAKE_CONST_WXSTRING(IMAGE_OPTION_QUALITY);
 
 580     wxIMAGE_RESOLUTION_INCHES = 1,
 
 581     wxIMAGE_RESOLUTION_CM = 2
 
 585 MAKE_CONST_WXSTRING(IMAGE_OPTION_BITSPERSAMPLE);
 
 586 MAKE_CONST_WXSTRING(IMAGE_OPTION_SAMPLESPERPIXEL); 
 
 587 MAKE_CONST_WXSTRING(IMAGE_OPTION_COMPRESSION);
 
 588 MAKE_CONST_WXSTRING(IMAGE_OPTION_IMAGEDESCRIPTOR);
 
 590 MAKE_CONST_WXSTRING(IMAGE_OPTION_PNG_FORMAT);
 
 591 MAKE_CONST_WXSTRING(IMAGE_OPTION_PNG_BITDEPTH);
 
 595     wxPNG_TYPE_COLOUR = 0,
 
 597     wxPNG_TYPE_GREY_RED = 3
 
 602     wxBMP_24BPP        = 24, // default, do not need to set
 
 603     //wxBMP_16BPP      = 16, // wxQuantize can only do 236 colors?
 
 604     wxBMP_8BPP         =  8, // 8bpp, quantized colors
 
 605     wxBMP_8BPP_GREY    =  9, // 8bpp, rgb averaged to greys
 
 606     wxBMP_8BPP_GRAY    =  wxBMP_8BPP_GREY,
 
 607     wxBMP_8BPP_RED     = 10, // 8bpp, red used as greyscale
 
 608     wxBMP_8BPP_PALETTE = 11, // 8bpp, use the wxImage's palette
 
 609     wxBMP_4BPP         =  4, // 4bpp, quantized colors
 
 610     wxBMP_1BPP         =  1, // 1bpp, quantized "colors"
 
 611     wxBMP_1BPP_BW      =  2  // 1bpp, black & white from red
 
 615 class wxBMPHandler : public wxImageHandler {
 
 620 class wxICOHandler : public wxBMPHandler {
 
 625 class wxCURHandler : public wxICOHandler {
 
 630 class wxANIHandler : public wxCURHandler {
 
 636 //---------------------------------------------------------------------------
 
 638 class wxPNGHandler : public wxImageHandler {
 
 644 class wxGIFHandler : public wxImageHandler {
 
 650 class wxPCXHandler : public wxImageHandler {
 
 656 class wxJPEGHandler : public wxImageHandler {
 
 662 class wxPNMHandler : public wxImageHandler {
 
 667 class wxXPMHandler : public wxImageHandler {
 
 672 class wxTIFFHandler : public wxImageHandler {
 
 679 class wxIFFHandler : public wxImageHandler {
 
 685 //---------------------------------------------------------------------------
 
 688 #include <wx/quantize.h>
 
 692     wxQUANTIZE_INCLUDE_WINDOWS_COLOURS,
 
 693 //    wxQUANTIZE_RETURN_8BIT_DATA,
 
 694     wxQUANTIZE_FILL_DESTINATION_IMAGE
 
 699        "Performs quantization, or colour reduction, on a wxImage.", "");
 
 701 class wxQuantize /*: public wxObject */
 
 708             "Reduce the colours in the source image and put the result into the
 
 709 destination image, setting the palette in the destination if
 
 710 needed. Both images may be the same, to overwrite the source image.", "
 
 711 :todo: Create a version that returns the wx.Palette used.");
 
 713         static bool Quantize(const wxImage& src, wxImage& dest, int desiredNoColours = 236,
 
 714                              int flags = wxQUANTIZE_INCLUDE_WINDOWS_COLOURS|wxQUANTIZE_FILL_DESTINATION_IMAGE)
 
 716                 return wxQuantize::Quantize(src, dest, 
 
 719                                             NULL, // eightBitData
 
 726 //---------------------------------------------------------------------------