]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/image.cpp
Sorry folks, a lot of changes to remedy GetFont, GetBrush etc.
[wxWidgets.git] / src / common / image.cpp
index 5dac31e47788e00e78109747ceb90062ab28ee5e..982b3067fb42f61b5818bbc07932f49923f30a9c 100644 (file)
 
 class wxImageRefData: public wxObjectRefData
 {
-  public:
-  
-    wxImageRefData(void);
-    ~wxImageRefData(void);
+
+public:
+  wxImageRefData(void);
+  ~wxImageRefData(void);
   
-    int             m_width;
-    int             m_height;
-    unsigned char  *m_data;
-    bool            m_hasMask;
-    unsigned char   m_maskRed,m_maskGreen,m_maskBlue;
-    bool            m_ok;
+  int             m_width;
+  int             m_height;
+  unsigned char  *m_data;
+  bool            m_hasMask;
+  unsigned char   m_maskRed,m_maskGreen,m_maskBlue;
+  bool            m_ok;
 };
 
 wxImageRefData::wxImageRefData(void)
 {
-  m_width = 0;
-  m_height = 0;
-  m_data = (unsigned char*) NULL;
-  m_ok = FALSE;
-  m_maskRed = 0;
-  m_maskGreen = 0;
-  m_maskBlue = 0;
-  m_hasMask = FALSE;
+    m_width = 0;
+    m_height = 0;
+    m_data = (unsigned char*) NULL;
+    m_ok = FALSE;
+    m_maskRed = 0;
+    m_maskGreen = 0;
+    m_maskBlue = 0;
+    m_hasMask = FALSE;
 }
 
 wxImageRefData::~wxImageRefData(void)
 {
-  if (m_data) free( m_data );
+    if (m_data) free( m_data );
 }
 
 wxList wxImage::sm_handlers;
@@ -76,156 +76,256 @@ wxImage::wxImage()
 
 wxImage::wxImage( int width, int height )
 {
-  Create( width, height );
+    Create( width, height );
 }
 
 wxImage::wxImage( const wxString& name, long type )
 {
-  LoadFile( name, type );
+    LoadFile( name, type );
 }
 
 wxImage::wxImage( const wxImage& image )  
 {  
-  Ref(image); 
+    Ref(image); 
 }
 
 wxImage::wxImage( const wxImage* image )  
 { 
-  if (image) Ref(*image); 
+    if (image) Ref(*image); 
 }
 
 void wxImage::Create( int width, int height )
 {
-  m_refData = new wxImageRefData();
+    m_refData = new wxImageRefData();
   
-  M_IMGDATA->m_data = (unsigned char *) malloc( width*height*3 );
-  if (M_IMGDATA->m_data)
-  {
-    for (int l = 0; l < width*height*3; l++) M_IMGDATA->m_data[l] = 0;
+    M_IMGDATA->m_data = (unsigned char *) malloc( width*height*3 );
+    if (M_IMGDATA->m_data)
+    {
+        for (int l = 0; l < width*height*3; l++) M_IMGDATA->m_data[l] = 0;
   
-    M_IMGDATA->m_width = width;
-    M_IMGDATA->m_height = height;
-    M_IMGDATA->m_ok = TRUE;
-  }
-  else
-  {
-    UnRef();
-  }
+        M_IMGDATA->m_width = width;
+        M_IMGDATA->m_height = height;
+        M_IMGDATA->m_ok = TRUE;
+    }
+    else
+    {
+        UnRef();
+    }
 }
 
 void wxImage::Destroy()
 {
-  UnRef();
+    UnRef();
 }
 
+wxImage wxImage::Scale( int width, int height )
+{
+    wxImage image;
+    
+    wxCHECK_MSG( Ok(), image, "invlaid image" );
+    
+    wxCHECK_MSG( (width > 0) && (height > 0), image, "invalid image size" );
+    
+    image.Create( width, height );
+    
+    char unsigned *data = image.GetData();
+    
+    wxCHECK_MSG( data, image, "unable to create image" );
+    
+    if (M_IMGDATA->m_hasMask)
+        image.SetMaskColour( M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue );
+    
+    double xscale = (double)width / (double)M_IMGDATA->m_width;
+    double yscale = (double)height / (double)M_IMGDATA->m_height;
+    
+    for (int j = 0; j < height; j++)
+    {
+        for (int i = 0; i < width; i++)
+       {
+           int new_pos = 3*(j*width + i);
+           int old_pos = 3*((long)(j/yscale)*M_IMGDATA->m_width + (long)(i/xscale));
+           data[ new_pos   ] = M_IMGDATA->m_data[ old_pos   ];
+           data[ new_pos+1 ] = M_IMGDATA->m_data[ old_pos+1 ];
+           data[ new_pos+2 ] = M_IMGDATA->m_data[ old_pos+2 ];
+       }
+    }
+    
+    return image;
+}
+  
+void wxImage::SetRGB( int x, int y, unsigned char r, unsigned char g, unsigned char b )
+{
+    wxCHECK_RET( Ok(), "invalid image" );
+    
+    int w = M_IMGDATA->m_width;
+    int h = M_IMGDATA->m_height;
+    
+    wxCHECK_RET( (x>=0) && (y>=0) && (x<w) && (y<h), "invalid image index" );
+    
+    long pos = (y * w + x) * 3;
+    
+    M_IMGDATA->m_data[ pos   ] = r;
+    M_IMGDATA->m_data[ pos+1 ] = g;
+    M_IMGDATA->m_data[ pos+2 ] = b;
+}
+
+unsigned char wxImage::GetRed( int x, int y )
+{
+    wxCHECK_MSG( Ok(), 0, "invalid image" );
+    
+    int w = M_IMGDATA->m_width;
+    int h = M_IMGDATA->m_height;
+    
+    wxCHECK_MSG( (x>=0) && (y>=0) && (x<w) && (y<h), 0, "invalid image index" );
+    
+    long pos = (y * w + x) * 3;
+    
+    return M_IMGDATA->m_data[pos];
+}
+
+unsigned char wxImage::GetGreen( int x, int y )
+{
+    wxCHECK_MSG( Ok(), 0, "invalid image" );
+    
+    int w = M_IMGDATA->m_width;
+    int h = M_IMGDATA->m_height;
+    
+    wxCHECK_MSG( (x>=0) && (y>=0) && (x<w) && (y<h), 0, "invalid image index" );
+    
+    long pos = (y * w + x) * 3;
+    
+    return M_IMGDATA->m_data[pos+1];
+}
+
+unsigned char wxImage::GetBlue( int x, int y )
+{
+    wxCHECK_MSG( Ok(), 0, "invalid image" );
+    
+    int w = M_IMGDATA->m_width;
+    int h = M_IMGDATA->m_height;
+    
+    wxCHECK_MSG( (x>=0) && (y>=0) && (x<w) && (y<h), 0, "invalid image index" );
+    
+    long pos = (y * w + x) * 3;
+    
+    return M_IMGDATA->m_data[pos+2];
+}
+  
 bool wxImage::Ok() const 
 { 
-  return (M_IMGDATA && M_IMGDATA->m_ok); 
+    return (M_IMGDATA && M_IMGDATA->m_ok); 
 }
 
 char unsigned *wxImage::GetData() const
 {
-  if (!Ok()) return (char unsigned *)NULL;
+    wxCHECK_MSG( Ok(), (char unsigned *)NULL, "invalid image" );
   
-  return M_IMGDATA->m_data;
+    return M_IMGDATA->m_data;
 }
 
 void wxImage::SetData( char unsigned *WXUNUSED(data) )
 {
+    wxCHECK_RET( Ok(), "invalid image" );
 }
 
 void wxImage::SetMaskColour( unsigned char r, unsigned char g, unsigned char b )
 {
-  if (!Ok()) return;
+    wxCHECK_RET( Ok(), "invalid image" );
   
-  M_IMGDATA->m_maskRed = r;
-  M_IMGDATA->m_maskGreen = g;
-  M_IMGDATA->m_maskBlue = b;
-  M_IMGDATA->m_hasMask = TRUE;
+    M_IMGDATA->m_maskRed = r;
+    M_IMGDATA->m_maskGreen = g;
+    M_IMGDATA->m_maskBlue = b;
+    M_IMGDATA->m_hasMask = TRUE;
 }
 
 unsigned char wxImage::GetMaskRed() const
 {
-  if (!Ok()) return 0;
+    wxCHECK_MSG( Ok(), 0, "invalid image" );
   
-  return M_IMGDATA->m_maskRed;
+    return M_IMGDATA->m_maskRed;
 }
 
 unsigned char wxImage::GetMaskGreen() const
 {
-  if (!Ok()) return 0;
-  
-  return M_IMGDATA->m_maskGreen;
+    wxCHECK_MSG( Ok(), 0, "invalid image" );
+   
+    return M_IMGDATA->m_maskGreen;
 }
 
 unsigned char wxImage::GetMaskBlue() const
 {
-  if (!Ok()) return 0;
+    wxCHECK_MSG( Ok(), 0, "invalid image" );
   
-  return M_IMGDATA->m_maskBlue;
+    return M_IMGDATA->m_maskBlue;
 }
   
 void wxImage::SetMask( bool mask )
 {
-  if (!Ok()) return;
+    wxCHECK_RET( Ok(), "invalid image" );
   
-  M_IMGDATA->m_hasMask = mask;
+    M_IMGDATA->m_hasMask = mask;
 }
 
 bool wxImage::HasMask() const
 {
-  if (!Ok()) return FALSE;
+    wxCHECK_MSG( Ok(), FALSE, "invalid image" );
   
-  return M_IMGDATA->m_hasMask;
+    return M_IMGDATA->m_hasMask;
 }
 
 int wxImage::GetWidth() const 
 { 
-  return (M_IMGDATA ? M_IMGDATA->m_width : 0); 
+    wxCHECK_MSG( Ok(), 0, "invalid image" );
+    
+    return M_IMGDATA->m_width; 
 }
 
 int wxImage::GetHeight() const 
 { 
-  return (M_IMGDATA ? M_IMGDATA->m_height : 0); 
+    wxCHECK_MSG( Ok(), 0, "invalid image" );
+    
+    return M_IMGDATA->m_height; 
 }
 
 bool wxImage::LoadFile( const wxString& filename, long type )
 {
-  UnRef();
+    UnRef();
   
-  if (!wxFileExists(filename))
-  {
-    wxLogWarning( "Image file does not exist." );
+    if (!wxFileExists(filename))
+    {
+        wxLogWarning( "Image file does not exist." );
 
-    return FALSE;
-  }
+        return FALSE;
+    }
 
-  m_refData = new wxImageRefData;
+    m_refData = new wxImageRefData;
 
-  wxImageHandler *handler = FindHandler(type);
+    wxImageHandler *handler = FindHandler(type);
 
-  if (handler == NULL) 
-  {
-    wxLogWarning( "No image handler for type %d defined.", type );
+    if (handler == NULL) 
+    {
+        wxLogWarning( "No image handler for type %d defined.", type );
 
-    return FALSE;
-  }
+        return FALSE;
+    }
 
-  return handler->LoadFile( this, filename );
+    return handler->LoadFile( this, filename );
 }
 
 bool wxImage::SaveFile( const wxString& filename, int type )
 {
-  wxImageHandler *handler = FindHandler(type);
+    wxCHECK_MSG( Ok(), FALSE, "invalid image" );
+    
+    wxImageHandler *handler = FindHandler(type);
 
-  if (handler == NULL) 
-  {
-    wxLogWarning( "No image handler for type %d defined.", type );
+    if (handler == NULL) 
+    {
+      wxLogWarning( "No image handler for type %d defined.", type );
 
-    return FALSE;
-  }
+      return FALSE;
+    }
 
-  return handler->SaveFile( this, filename );
+    return handler->SaveFile( this, filename );
 }
 
 void wxImage::AddHandler( wxImageHandler *handler )
@@ -240,65 +340,71 @@ void wxImage::InsertHandler( wxImageHandler *handler )
 
 bool wxImage::RemoveHandler( const wxString& name )
 {
-  wxImageHandler *handler = FindHandler(name);
-  if (handler)
-  {
-    sm_handlers.DeleteObject(handler);
-    return TRUE;
-  }
-  else
-    return FALSE;
+    wxImageHandler *handler = FindHandler(name);
+    if (handler)
+    {
+        sm_handlers.DeleteObject(handler);
+        return TRUE;
+    }
+    else
+        return FALSE;
 }
 
 wxImageHandler *wxImage::FindHandler( const wxString& name )
 {
-  wxNode *node = sm_handlers.First();
-  while (node)
-  {
-    wxImageHandler *handler = (wxImageHandler*)node->Data();
-    if (handler->GetName() == name) return handler;
-    node = node->Next();
-  }
-  return (wxImageHandler *)NULL;
+    wxNode *node = sm_handlers.First();
+    while (node)
+    {
+        wxImageHandler *handler = (wxImageHandler*)node->Data();
+        if (handler->GetName() == name) return handler;
+        node = node->Next();
+    }
+    return (wxImageHandler *)NULL;
 }
 
 wxImageHandler *wxImage::FindHandler( const wxString& extension, long bitmapType )
 {
-  wxNode *node = sm_handlers.First();
-  while (node)
-  {
-    wxImageHandler *handler = (wxImageHandler*)node->Data();
-    if ( handler->GetExtension() == extension &&
-        (bitmapType == -1 || handler->GetType() == bitmapType) )
-      return handler;
-    node = node->Next();
-  }
-  return (wxImageHandler*)NULL;
+    wxNode *node = sm_handlers.First();
+    while (node)
+    {
+        wxImageHandler *handler = (wxImageHandler*)node->Data();
+        if ( handler->GetExtension() == extension &&
+            (bitmapType == -1 || handler->GetType() == bitmapType) )
+        return handler;
+        node = node->Next();
+    }
+    return (wxImageHandler*)NULL;
 }
 
 wxImageHandler *wxImage::FindHandler( long bitmapType )
 {
-  wxNode *node = sm_handlers.First();
-  while (node)
-  {
-    wxImageHandler *handler = (wxImageHandler *)node->Data();
-    if (handler->GetType() == bitmapType) return handler;
-    node = node->Next();
-  }
-  return NULL;
+    wxNode *node = sm_handlers.First();
+    while (node)
+    {
+        wxImageHandler *handler = (wxImageHandler *)node->Data();
+        if (handler->GetType() == bitmapType) return handler;
+        node = node->Next();
+    }
+    return NULL;
+}
+
+void wxImage::InitStandardHandlers()
+{
+    AddHandler( new wxBMPHandler );
+    AddHandler( new wxPNGHandler );
 }
 
 void wxImage::CleanUpHandlers()
 {
-  wxNode *node = sm_handlers.First();
-  while (node)
-  {
-    wxImageHandler *handler = (wxImageHandler *)node->Data();
-    wxNode *next = node->Next();
-    delete handler;
-    delete node;
-    node = next;
-  }
+    wxNode *node = sm_handlers.First();
+    while (node)
+    {
+        wxImageHandler *handler = (wxImageHandler *)node->Data();
+        wxNode *next = node->Next();
+        delete handler;
+        delete node;
+        node = next;
+    }
 }
 
 //-----------------------------------------------------------------------------
@@ -311,12 +417,12 @@ IMPLEMENT_DYNAMIC_CLASS(wxImageHandler,wxObject)
 
 bool wxImageHandler::LoadFile( wxImage *WXUNUSED(image), const wxString& WXUNUSED(name) )
 {
-  return FALSE;
+    return FALSE;
 }
 
 bool wxImageHandler::SaveFile( wxImage *WXUNUSED(image), const wxString& WXUNUSED(name) )
 {
-  return FALSE;
+    return FALSE;
 }
 
 //-----------------------------------------------------------------------------
@@ -828,7 +934,7 @@ bool wxBMPHandler::LoadFile( wxImage *image, const wxString& name )
 
                                      for (i = 0; i < absolute; i++)
                                        {
-                                          +linepos++;
+                                          linepos++;
                                           byte = getc(file);
                                           ptr[poffset] = cmap[byte].r;
                                           ptr[poffset + 1] = cmap[byte].g;