/////////////////////////////////////////////////////////////////////////////
-// Name: image.cpp
+// Name: src/common/image.cpp
// Purpose: wxImage
// Author: Robert Roebling
// RCS-ID: $Id$
}
#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);
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;
+
+ // 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;
}
}
- // 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);
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);
}
}
+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;
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 )
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
const double value = maximumRGB;
- double hue, saturation;
+ double hue = 0.0, saturation;
const double deltaRGB = maximumRGB - minimumRGB;
if ( wxIsNullDouble(deltaRGB) )
{
case BLUE:
hue = 4.0 + (red - green) / deltaRGB;
break;
+
+ default:
+ wxFAIL_MSG(wxT("hue not specified"));
+ break;
}
hue /= 6.0;
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
- 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)
{
- *offset_after_rotation = wxPoint (x1, y1);
+ *offset_after_rotation = wxPoint (x1a, y1a);
}
// GRG: The rotated (destination) image is always accessed
{
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)
// 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)
*(dst++) = *p;
if (has_alpha)
- {
- unsigned char *p = alpha[y1] + x1;
- *(alpha_dst++) = *p;
- }
+ *(alpha_dst++) = *(alpha[y1] + x1);
}
else if (d2 < gs_Epsilon)
{
*(dst++) = *p;
if (has_alpha)
- {
- unsigned char *p = alpha[y1] + x2;
- *(alpha_dst++) = *p;
- }
+ *(alpha_dst++) = *(alpha[y1] + x2);
}
else if (d3 < gs_Epsilon)
{
*(dst++) = *p;
if (has_alpha)
- {
- unsigned char *p = alpha[y2] + x2;
- *(alpha_dst++) = *p;
- }
+ *(alpha_dst++) = *(alpha[y2] + x2);
}
else if (d4 < gs_Epsilon)
{
*(dst++) = *p;
if (has_alpha)
- {
- unsigned char *p = alpha[y2] + x1;
- *(alpha_dst++) = *p;
- }
+ *(alpha_dst++) = *(alpha[y2] + x1);
}
else
{
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 +
{
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
*(dst++) = *p;
if (has_alpha)
- {
- unsigned char *p = alpha[ys] + (xs);
- *(alpha_dst++) = *p;
- }
+ *(alpha_dst++) = *(alpha[ys] + (xs));
}
else
{