]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/image.cpp
Applied patch [ 1428990 ] wxUniv: patch for toolbar button remain in pressed status
[wxWidgets.git] / src / common / image.cpp
index d7e07b0dc01eafed18c462d308df838bc24ec33d..125e97613a11d3e05d236caa6a552934bcad8061 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        image.cpp
+// Name:        src/common/image.cpp
 // Purpose:     wxImage
 // Author:      Robert Roebling
 // RCS-ID:      $Id$
 // Purpose:     wxImage
 // Author:      Robert Roebling
 // RCS-ID:      $Id$
@@ -148,17 +148,6 @@ wxImage::wxImage( wxInputStream& stream, const wxString& mimetype, int index )
 }
 #endif // wxUSE_STREAMS
 
 }
 #endif // wxUSE_STREAMS
 
-wxImage::wxImage( const wxImage& image )
-    : wxObject()
-{
-    Ref(image);
-}
-
-wxImage::wxImage( const wxImage* image )
-{
-    if (image) Ref(*image);
-}
-
 wxImage::wxImage( const char** xpmData )
 {
     Create(xpmData);
 wxImage::wxImage( const char** xpmData )
 {
     Create(xpmData);
@@ -261,9 +250,18 @@ wxImage wxImage::Copy() const
     image.SetMask( M_IMGDATA->m_hasMask );
 
     memcpy( data, GetData(), M_IMGDATA->m_width*M_IMGDATA->m_height*3 );
     image.SetMask( M_IMGDATA->m_hasMask );
 
     memcpy( data, GetData(), M_IMGDATA->m_width*M_IMGDATA->m_height*3 );
-
-    // also copy the image options
+    
     wxImageRefData *imgData = (wxImageRefData *)image.m_refData;
     wxImageRefData *imgData = (wxImageRefData *)image.m_refData;
+    
+    // also copy the alpha channel
+    if (HasAlpha())
+    {
+        image.SetAlpha();
+        unsigned char* alpha = image.GetAlpha();
+        memcpy( alpha, GetAlpha(), M_IMGDATA->m_width*M_IMGDATA->m_height );
+    }
+    
+    // also copy the image options
     imgData->m_optionNames = M_IMGDATA->m_optionNames;
     imgData->m_optionValues = M_IMGDATA->m_optionValues;
 
     imgData->m_optionNames = M_IMGDATA->m_optionNames;
     imgData->m_optionValues = M_IMGDATA->m_optionValues;
 
@@ -380,7 +378,7 @@ wxImage wxImage::ShrinkBy( int xFactor , int yFactor ) const
         }
     }
 
         }
     }
 
-    // In case this is a cursor, make sure the hotspot is scalled accordingly:
+    // In case this is a cursor, make sure the hotspot is scaled accordingly:
     if ( HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_X) )
         image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X,
                 (GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X))/xFactor);
     if ( HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_X) )
         image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X,
                 (GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X))/xFactor);
@@ -466,7 +464,7 @@ wxImage wxImage::Scale( int width, int height ) const
         y += y_delta;
     }
 
         y += y_delta;
     }
 
-    // In case this is a cursor, make sure the hotspot is scalled accordingly:
+    // In case this is a cursor, make sure the hotspot is scaled accordingly:
     if ( HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_X) )
         image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X,
                 (GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X)*width)/old_width);
     if ( HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_X) )
         image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X,
                 (GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X)*width)/old_width);
@@ -769,6 +767,46 @@ void wxImage::Replace( unsigned char r1, unsigned char g1, unsigned char b1,
         }
 }
 
         }
 }
 
+wxImage wxImage::ConvertToGreyscale( double lr, double lg, double lb ) const
+{
+    wxImage image;
+
+    wxCHECK_MSG( Ok(), image, wxT("invalid image") );
+
+    image.Create(M_IMGDATA->m_width, M_IMGDATA->m_height, false);
+
+    unsigned char *dest = image.GetData();
+
+    wxCHECK_MSG( dest, image, wxT("unable to create image") );
+
+    unsigned char *src = M_IMGDATA->m_data;
+    bool hasMask = M_IMGDATA->m_hasMask;
+    unsigned char maskRed = M_IMGDATA->m_maskRed;
+    unsigned char maskGreen = M_IMGDATA->m_maskGreen;
+    unsigned char maskBlue = M_IMGDATA->m_maskBlue;
+
+    if ( hasMask )
+        image.SetMaskColour(maskRed, maskGreen, maskBlue);
+
+    const long size = M_IMGDATA->m_width * M_IMGDATA->m_height;
+    for ( long i = 0; i < size; i++, src += 3, dest += 3 )
+    {
+        // don't modify the mask
+        if ( hasMask && src[0] == maskRed && src[1] == maskGreen && src[2] == maskBlue )
+        {
+            memcpy(dest, src, 3);
+        }
+        else
+        {
+            // calculate the luma
+            double luma = (src[0] * lr + src[1] * lg + src[2] * lb) + 0.5;
+            dest[0] = dest[1] = dest[2] = wx_static_cast(unsigned char, luma);
+        }
+    }
+
+    return image;
+}
+
 wxImage wxImage::ConvertToMono( unsigned char r, unsigned char g, unsigned char b ) const
 {
     wxImage image;
 wxImage wxImage::ConvertToMono( unsigned char r, unsigned char g, unsigned char b ) const
 {
     wxImage image;
@@ -1554,7 +1592,13 @@ bool wxImage::LoadFile( wxInputStream& stream, long type, int index )
         return false;
     }
 
         return false;
     }
 
-    return handler->LoadFile(this, stream, true/*verbose*/, index);
+    if (stream.IsSeekable() && !handler->CanRead(stream))
+    {
+        wxLogError(_("Image file is not of type %d."), type);
+        return false;
+    }
+    else
+        return handler->LoadFile(this, stream, true/*verbose*/, index);
 }
 
 bool wxImage::LoadFile( wxInputStream& stream, const wxString& mimetype, int index )
 }
 
 bool wxImage::LoadFile( wxInputStream& stream, const wxString& mimetype, int index )
@@ -1572,7 +1616,13 @@ bool wxImage::LoadFile( wxInputStream& stream, const wxString& mimetype, int ind
         return false;
     }
 
         return false;
     }
 
-    return handler->LoadFile( this, stream, true/*verbose*/, index );
+    if (stream.IsSeekable() && !handler->CanRead(stream))
+    {
+        wxLogError(_("Image file is not of type %s."), (const wxChar*) mimetype);
+        return false;
+    }
+    else
+        return handler->LoadFile( this, stream, true/*verbose*/, index );
 }
 
 bool wxImage::SaveFile( wxOutputStream& stream, int type ) const
 }
 
 bool wxImage::SaveFile( wxOutputStream& stream, int type ) const
@@ -1778,7 +1828,7 @@ wxImage::HSVValue wxImage::RGBtoHSV(const RGBValue& rgb)
 
     const double value = maximumRGB;
 
 
     const double value = maximumRGB;
 
-    double hue, saturation;
+    double hue = 0.0, saturation;
     const double deltaRGB = maximumRGB - minimumRGB;
     if ( wxIsNullDouble(deltaRGB) )
     {
     const double deltaRGB = maximumRGB - minimumRGB;
     if ( wxIsNullDouble(deltaRGB) )
     {
@@ -1801,6 +1851,10 @@ wxImage::HSVValue wxImage::RGBtoHSV(const RGBValue& rgb)
             case BLUE:
                 hue = 4.0 + (red - green) / deltaRGB;
                 break;
             case BLUE:
                 hue = 4.0 + (red - green) / deltaRGB;
                 break;
+
+            default:
+                wxFAIL_MSG(wxT("hue not specified"));
+                break;
         }
 
         hue /= 6.0;
         }
 
         hue /= 6.0;
@@ -2175,20 +2229,20 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
     wxRealPoint p3 = rotated_point (GetWidth(), 0, cos_angle, sin_angle, p0);
     wxRealPoint p4 = rotated_point (GetWidth(), GetHeight(), cos_angle, sin_angle, p0);
 
     wxRealPoint p3 = rotated_point (GetWidth(), 0, cos_angle, sin_angle, p0);
     wxRealPoint p4 = rotated_point (GetWidth(), GetHeight(), cos_angle, sin_angle, p0);
 
-    int x1 = (int) floor (wxMin (wxMin(p1.x, p2.x), wxMin(p3.x, p4.x)));
-    int y1 = (int) floor (wxMin (wxMin(p1.y, p2.y), wxMin(p3.y, p4.y)));
-    int x2 = (int) ceil (wxMax (wxMax(p1.x, p2.x), wxMax(p3.x, p4.x)));
-    int y2 = (int) ceil (wxMax (wxMax(p1.y, p2.y), wxMax(p3.y, p4.y)));
+    int x1a = (int) floor (wxMin (wxMin(p1.x, p2.x), wxMin(p3.x, p4.x)));
+    int y1a = (int) floor (wxMin (wxMin(p1.y, p2.y), wxMin(p3.y, p4.y)));
+    int x2a = (int) ceil (wxMax (wxMax(p1.x, p2.x), wxMax(p3.x, p4.x)));
+    int y2a = (int) ceil (wxMax (wxMax(p1.y, p2.y), wxMax(p3.y, p4.y)));
 
     // Create rotated image
 
     // Create rotated image
-    wxImage rotated (x2 - x1 + 1, y2 - y1 + 1, false);
+    wxImage rotated (x2a - x1a + 1, y2a - y1a + 1, false);
     // With alpha channel
     if (has_alpha)
         rotated.SetAlpha();
 
     if (offset_after_rotation != NULL)
     {
     // With alpha channel
     if (has_alpha)
         rotated.SetAlpha();
 
     if (offset_after_rotation != NULL)
     {
-        *offset_after_rotation = wxPoint (x1, y1);
+        *offset_after_rotation = wxPoint (x1a, y1a);
     }
 
     // GRG: The rotated (destination) image is always accessed
     }
 
     // GRG: The rotated (destination) image is always accessed
@@ -2230,7 +2284,7 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
         {
             for (x = 0; x < rotated.GetWidth(); x++)
             {
         {
             for (x = 0; x < rotated.GetWidth(); x++)
             {
-                wxRealPoint src = rotated_point (x + x1, y + y1, cos_angle, -sin_angle, p0);
+                wxRealPoint src = rotated_point (x + x1a, y + y1a, cos_angle, -sin_angle, p0);
 
                 if (-0.25 < src.x && src.x < GetWidth() - 0.75 &&
                     -0.25 < src.y && src.y < GetHeight() - 0.75)
 
                 if (-0.25 < src.x && src.x < GetWidth() - 0.75 &&
                     -0.25 < src.y && src.y < GetHeight() - 0.75)
@@ -2238,8 +2292,6 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
                     // interpolate using the 4 enclosing grid-points.  Those
                     // points can be obtained using floor and ceiling of the
                     // exact coordinates of the point
                     // interpolate using the 4 enclosing grid-points.  Those
                     // points can be obtained using floor and ceiling of the
                     // exact coordinates of the point
-                        // C.M. 2000-02-17:  when the point is near the border, special care is required.
-
                     int x1, y1, x2, y2;
 
                     if (0 < src.x && src.x < GetWidth() - 1)
                     int x1, y1, x2, y2;
 
                     if (0 < src.x && src.x < GetWidth() - 1)
@@ -2289,10 +2341,7 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
                         *(dst++) = *p;
 
                         if (has_alpha)
                         *(dst++) = *p;
 
                         if (has_alpha)
-                        {
-                            unsigned char *p = alpha[y1] + x1;
-                            *(alpha_dst++) = *p;
-                        }
+                            *(alpha_dst++) = *(alpha[y1] + x1);
                     }
                     else if (d2 < gs_Epsilon)
                     {
                     }
                     else if (d2 < gs_Epsilon)
                     {
@@ -2302,10 +2351,7 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
                         *(dst++) = *p;
 
                         if (has_alpha)
                         *(dst++) = *p;
 
                         if (has_alpha)
-                        {
-                            unsigned char *p = alpha[y1] + x2;
-                            *(alpha_dst++) = *p;
-                        }
+                            *(alpha_dst++) = *(alpha[y1] + x2);
                     }
                     else if (d3 < gs_Epsilon)
                     {
                     }
                     else if (d3 < gs_Epsilon)
                     {
@@ -2315,10 +2361,7 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
                         *(dst++) = *p;
 
                         if (has_alpha)
                         *(dst++) = *p;
 
                         if (has_alpha)
-                        {
-                            unsigned char *p = alpha[y2] + x2;
-                            *(alpha_dst++) = *p;
-                        }
+                            *(alpha_dst++) = *(alpha[y2] + x2);
                     }
                     else if (d4 < gs_Epsilon)
                     {
                     }
                     else if (d4 < gs_Epsilon)
                     {
@@ -2328,10 +2371,7 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
                         *(dst++) = *p;
 
                         if (has_alpha)
                         *(dst++) = *p;
 
                         if (has_alpha)
-                        {
-                            unsigned char *p = alpha[y2] + x1;
-                            *(alpha_dst++) = *p;
-                        }
+                            *(alpha_dst++) = *(alpha[y2] + x1);
                     }
                     else
                     {
                     }
                     else
                     {
@@ -2360,10 +2400,10 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
 
                         if (has_alpha)
                         {
 
                         if (has_alpha)
                         {
-                            unsigned char *v1 = alpha[y1] + (x1);
-                            unsigned char *v2 = alpha[y1] + (x2);
-                            unsigned char *v3 = alpha[y2] + (x2);
-                            unsigned char *v4 = alpha[y2] + (x1);
+                            v1 = alpha[y1] + (x1);
+                            v2 = alpha[y1] + (x2);
+                            v3 = alpha[y2] + (x2);
+                            v4 = alpha[y2] + (x1);
 
                             *(alpha_dst++) = (unsigned char)
                                 ( (w1 * *v1 + w2 * *v2 +
 
                             *(alpha_dst++) = (unsigned char)
                                 ( (w1 * *v1 + w2 * *v2 +
@@ -2390,7 +2430,7 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
         {
             for (x = 0; x < rotated.GetWidth(); x++)
             {
         {
             for (x = 0; x < rotated.GetWidth(); x++)
             {
-                wxRealPoint src = rotated_point (x + x1, y + y1, cos_angle, -sin_angle, p0);
+                wxRealPoint src = rotated_point (x + x1a, y + y1a, cos_angle, -sin_angle, p0);
 
                 const int xs = wxCint (src.x);      // wxCint rounds to the
                 const int ys = wxCint (src.y);      // closest integer
 
                 const int xs = wxCint (src.x);      // wxCint rounds to the
                 const int ys = wxCint (src.y);      // closest integer
@@ -2404,10 +2444,7 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
                     *(dst++) = *p;
 
                     if (has_alpha)
                     *(dst++) = *p;
 
                     if (has_alpha)
-                    {
-                        unsigned char *p = alpha[ys] + (xs);
-                        *(alpha_dst++) = *p;
-                    }
+                        *(alpha_dst++) = *(alpha[ys] + (xs));
                 }
                 else
                 {
                 }
                 else
                 {