Do premultiplication in wx*PixelData_Iterator::Get and Set

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40858 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2006-08-27 00:46:22 +00:00
parent c7b2e4941f
commit c4caf81dbc
2 changed files with 54 additions and 40 deletions

View File

@@ -327,8 +327,10 @@ the ``type`` parameter.", "");
// automatically do it for wxMSW here. // automatically do it for wxMSW here.
#ifdef __WXMSW__ #ifdef __WXMSW__
#define wxPy_premultiply(p, a) ((p) * (a) / 256) #define wxPy_premultiply(p, a) ((p) * (a) / 256)
#define wxPy_unpremultiply(p, a) ((a) ? ((p) * 256 / (a)) : (p))
#else #else
#define wxPy_premultiply(p, a) (p) #define wxPy_premultiply(p, a) (p)
#define wxPy_unpremultiply(p, a) (p)
#endif #endif
%} %}
@@ -351,16 +353,16 @@ the ``type`` parameter.", "");
} }
wxBitmap* bmp = new wxBitmap(width, height, 32); wxBitmap* bmp = new wxBitmap(width, height, 32);
wxAlphaPixelData pixels(*bmp, wxPoint(0,0), wxSize(width,height)); wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
if (! pixels) { if (! pixData) {
// raise an exception... // raise an exception...
wxPyErr_SetString(PyExc_RuntimeError, wxPyErr_SetString(PyExc_RuntimeError,
"Failed to gain raw access to bitmap data."); "Failed to gain raw access to bitmap data.");
return NULL; return NULL;
} }
pixels.UseAlpha(); pixData.UseAlpha();
wxAlphaPixelData::Iterator p(pixels); wxAlphaPixelData::Iterator p(pixData);
for (int y=0; y<height; y++) { for (int y=0; y<height; y++) {
wxAlphaPixelData::Iterator rowStart = p; wxAlphaPixelData::Iterator rowStart = p;
for (int x=0; x<width; x++) { for (int x=0; x<width; x++) {
@@ -372,7 +374,7 @@ the ``type`` parameter.", "");
++p; ++p;
} }
p = rowStart; p = rowStart;
p.OffsetY(pixels, 1); p.OffsetY(pixData, 1);
} }
return bmp; return bmp;
} }
@@ -385,15 +387,15 @@ the ``type`` parameter.", "");
} }
wxBitmap* bmp = new wxBitmap(width, height, 24); wxBitmap* bmp = new wxBitmap(width, height, 24);
wxNativePixelData pixels(*bmp, wxPoint(0,0), wxSize(width,height)); wxNativePixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
if (! pixels) { if (! pixData) {
// raise an exception... // raise an exception...
wxPyErr_SetString(PyExc_RuntimeError, wxPyErr_SetString(PyExc_RuntimeError,
"Failed to gain raw access to bitmap data."); "Failed to gain raw access to bitmap data.");
return NULL; return NULL;
} }
wxNativePixelData::Iterator p(pixels); wxNativePixelData::Iterator p(pixData);
for (int y=0; y<height; y++) { for (int y=0; y<height; y++) {
wxNativePixelData::Iterator rowStart = p; wxNativePixelData::Iterator rowStart = p;
for (int x=0; x<width; x++) { for (int x=0; x<width; x++) {
@@ -403,7 +405,7 @@ the ``type`` parameter.", "");
++p; ++p;
} }
p = rowStart; p = rowStart;
p.OffsetY(pixels, 1); p.OffsetY(pixData, 1);
} }
return bmp; return bmp;
} }
@@ -455,16 +457,16 @@ def BitmapFromBuffer(width, height, dataBuffer, alphaBuffer=None):
} }
wxBitmap* bmp = new wxBitmap(width, height, 32); wxBitmap* bmp = new wxBitmap(width, height, 32);
wxAlphaPixelData pixels(*bmp, wxPoint(0,0), wxSize(width,height)); wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
if (! pixels) { if (! pixData) {
// raise an exception... // raise an exception...
wxPyErr_SetString(PyExc_RuntimeError, wxPyErr_SetString(PyExc_RuntimeError,
"Failed to gain raw access to bitmap data."); "Failed to gain raw access to bitmap data.");
return NULL; return NULL;
} }
pixels.UseAlpha(); pixData.UseAlpha();
wxAlphaPixelData::Iterator p(pixels); wxAlphaPixelData::Iterator p(pixData);
for (int y=0; y<height; y++) { for (int y=0; y<height; y++) {
wxAlphaPixelData::Iterator rowStart = p; wxAlphaPixelData::Iterator rowStart = p;
for (int x=0; x<width; x++) { for (int x=0; x<width; x++) {
@@ -476,7 +478,7 @@ def BitmapFromBuffer(width, height, dataBuffer, alphaBuffer=None):
++p; ++p;
} }
p = rowStart; p = rowStart;
p.OffsetY(pixels, 1); p.OffsetY(pixData, 1);
} }
return bmp; return bmp;
} }
@@ -555,6 +557,7 @@ public:
}; };
class PixelData##_Iterator class PixelData##_Iterator
{ {
public: public:
@@ -579,22 +582,26 @@ public:
void OffsetY(const PixelData& data, int y); void OffsetY(const PixelData& data, int y);
void MoveTo(const PixelData& data, int x, int y); void MoveTo(const PixelData& data, int x, int y);
%extend { // NOTE: For now I'm not wrapping the Red, Green, Blue and Alpha functions
byte _get_Red() { return self->Red(); } // because I can't hide the premultiplying needed on wxMSW if only the
byte _get_Green() { return self->Green(); } // individual components are wrapped. Instead I've added the Set and Get
byte _get_Blue() { return self->Blue(); } // functions and put the puemultiplying in there.
void _set_Red(byte val) { self->Red() = val; } // %extend {
void _set_Green(byte val) { self->Green() = val; } // byte _get_Red() { return self->Red(); }
void _set_Blue(byte val) { self->Blue() = val; } // byte _get_Green() { return self->Green(); }
} // byte _get_Blue() { return self->Blue(); }
%pythoncode { // void _set_Red(byte val) { self->Red() = val; }
Red = property(_get_Red, _set_Red) // void _set_Green(byte val) { self->Green() = val; }
Green = property(_get_Green, _set_Green) // void _set_Blue(byte val) { self->Blue() = val; }
Blue = property(_get_Blue, _set_Blue) // }
}
// %pythoncode {
// Red = property(_get_Red, _set_Red)
// Green = property(_get_Green, _set_Green)
// Blue = property(_get_Blue, _set_Blue)
// }
}; };
%enddef %enddef
@@ -623,26 +630,31 @@ PIXELDATA(wxAlphaPixelData)
} }
%extend wxAlphaPixelData_Iterator { %extend wxAlphaPixelData_Iterator {
byte _get_Alpha() { return self->Alpha(); } // byte _get_Alpha() { return self->Alpha(); }
void _set_Alpha(byte val) { self->Alpha() = val; } // void _set_Alpha(byte val) { self->Alpha() = val; }
%pythoncode { // %pythoncode {
Alpha = property(_get_Alpha, _set_Alpha) // Alpha = property(_get_Alpha, _set_Alpha)
} // }
void Set(byte red, byte green, byte blue, byte alpha) { void Set(byte red, byte green, byte blue, byte alpha) {
self->Red() = red; self->Red() = wxPy_premultiply(red, alpha);
self->Green() = green; self->Green() = wxPy_premultiply(green, alpha);
self->Blue() = blue; self->Blue() = wxPy_premultiply(blue, alpha);
self->Alpha() = alpha; self->Alpha() = alpha;
} }
PyObject* Get() { PyObject* Get() {
PyObject* rv = PyTuple_New(4); PyObject* rv = PyTuple_New(4);
PyTuple_SetItem(rv, 0, PyInt_FromLong(self->Red())); int red = self->Red();
PyTuple_SetItem(rv, 1, PyInt_FromLong(self->Green())); int green = self->Green();
PyTuple_SetItem(rv, 2, PyInt_FromLong(self->Blue())); int blue = self->Blue();
PyTuple_SetItem(rv, 3, PyInt_FromLong(self->Alpha())); int alpha = self->Alpha();
PyTuple_SetItem(rv, 0, PyInt_FromLong( wxPy_unpremultiply(red, alpha) ));
PyTuple_SetItem(rv, 1, PyInt_FromLong( wxPy_unpremultiply(green, alpha) ));
PyTuple_SetItem(rv, 2, PyInt_FromLong( wxPy_unpremultiply(blue, alpha) ));
PyTuple_SetItem(rv, 3, PyInt_FromLong( alpha ));
return rv; return rv;
} }
} }

View File

@@ -161,6 +161,7 @@ is returned if the pixel is invalid (on X, unallocated).", "");
%extend { %extend {
KeepGIL(Get);
DocAStr(Get, DocAStr(Get,
"Get() -> (r, g, b)", "Get() -> (r, g, b)",
"Returns the RGB intensity values as a tuple.", ""); "Returns the RGB intensity values as a tuple.", "");
@@ -184,6 +185,7 @@ is returned if the pixel is invalid (on X, unallocated).", "");
return rv; return rv;
} }
KeepGIL(GetRGB);
DocStr(GetRGB, DocStr(GetRGB,
"Return the colour as a packed RGB value", ""); "Return the colour as a packed RGB value", "");
unsigned long GetRGB() { unsigned long GetRGB() {