From a452af5e682893eb97b15cde1e63a09fd02e5931 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 1 May 2003 16:37:51 +0000 Subject: [PATCH] allow raw access to a part of the image only (faster when using alpha) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20409 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/rawbmp.h | 106 ++++++++++++++++++++++++++++++++++------ samples/image/image.cpp | 6 +-- src/msw/dc.cpp | 2 +- 3 files changed, 94 insertions(+), 20 deletions(-) diff --git a/include/wx/rawbmp.h b/include/wx/rawbmp.h index b0037d8966..e5d03d0a6d 100644 --- a/include/wx/rawbmp.h +++ b/include/wx/rawbmp.h @@ -180,12 +180,21 @@ struct WXDLLEXPORT wxPixelFormatFor class WXDLLEXPORT wxPixelDataBase { public: + // origin of the rectangular region we represent + wxPoint GetOrigin() const { return m_ptOrigin; } + + // width and height of the region we represent int GetWidth() const { return m_width; } int GetHeight() const { return m_height; } + + // the distance between two rows int GetRowStride() const { return m_stride; } // private: -- see comment in the beginning of the file + // the origin of this image inside the bigger bitmap (usually (0, 0)) + wxPoint m_ptOrigin; + // the size of the image we address, in pixels int m_width, m_height; @@ -316,7 +325,8 @@ struct WXDLLEXPORT wxPixelDataOut return *this; } - // postfix (hence less efficient -- don't use unless you must) version + // postfix (hence less efficient -- don't use it unless you + // absolutely must) version Iterator operator++(int) { Iterator p(*this); @@ -384,6 +394,25 @@ struct WXDLLEXPORT wxPixelDataOut m_stride = Iterator::SizePixel * m_width; } + // initializes us with the given region of the specified image + wxPixelDataIn(ImageType& image, + const wxPoint& pt, + const wxSize& sz) : m_image(image), m_pixels(image) + { + m_stride = Iterator::SizePixel * m_width; + + InitRect(pt, sz); + } + + // initializes us with the given region of the specified image + wxPixelDataIn(ImageType& image, + const wxRect& rect) : m_image(image), m_pixels(image) + { + m_stride = Iterator::SizePixel * m_width; + + InitRect(rect.GetPositions(), rect.GetSize()); + } + // we evaluate to true only if we could get access to bitmap data // successfully operator bool() const { return m_pixels.IsOk(); } @@ -392,6 +421,15 @@ struct WXDLLEXPORT wxPixelDataOut Iterator GetPixels() const { return m_pixels; } private: + void InitRect(const wxPoint& pt, const wxSize& sz) + { + m_width = sz.x; + m_height = sz.y; + + m_ptOrigin = pt; + m_pixels.Offset(*this, pt.x, pt.y); + } + // the image we're working with ImageType& m_image; @@ -431,21 +469,22 @@ struct WXDLLEXPORT wxPixelDataOut *this = data.GetPixels(); } - // initializes the iterator to point to the origin of the given pixel - // data + // initializes the iterator to point to the origin of the given + // pixel data Iterator(PixelData& data) { Reset(data); } - // initializes the iterator to point to the origin of the given bitmap + // initializes the iterator to point to the origin of the given + // bitmap Iterator(wxBitmap& bmp, PixelData& data) { - // using cast here is ugly but it should be safe as GetRawData() - // real return type should be consistent with BitsPerPixel (which - // is in turn defined by ChannelType) and this is the only thing we - // can do without making GetRawData() a template function which is - // undesirable + // using cast here is ugly but it should be safe as + // GetRawData() real return type should be consistent with + // BitsPerPixel (which is in turn defined by ChannelType) and + // this is the only thing we can do without making GetRawData() + // a template function which is undesirable m_ptr = (ChannelType *) bmp.GetRawData(data, PixelFormat::BitsPerPixel); } @@ -465,7 +504,8 @@ struct WXDLLEXPORT wxPixelDataOut return *this; } - // postfix (hence less efficient -- don't use unless you must) version + // postfix (hence less efficient -- don't use it unless you + // absolutely must) version Iterator operator++(int) { Iterator p(*this); @@ -520,17 +560,31 @@ struct WXDLLEXPORT wxPixelDataOut // NB: for efficiency reasons this class must *not* have any other // fields, otherwise it won't be put into a CPU register (as it - // should inside the inner loops) by some compilers, notably gcc + // should inside the inner loops) by some compilers, notably + // gcc ChannelType *m_ptr; }; - // ctor associates this pointer with a bitmap and locks the bitmap for raw - // access, it will be unlocked only by our dtor and so these objects should - // normally be only created on the stack, i.e. have limited life-time - wxPixelDataIn(wxBitmap bmp) : m_bmp(bmp), m_pixels(bmp, *this) + // ctor associates this pointer with a bitmap and locks the bitmap for + // raw access, it will be unlocked only by our dtor and so these + // objects should normally be only created on the stack, i.e. have + // limited life-time + wxPixelDataIn(wxBitmap& bmp) : m_bmp(bmp), m_pixels(bmp, *this) { } + wxPixelDataIn(wxBitmap& bmp, const wxRect& rect) + : m_bmp(bmp), m_pixels(bmp, *this) + { + InitRect(rect.GetPositions(), rect.GetSize()); + } + + wxPixelDataIn(wxBitmap& bmp, const wxPoint& pt, const wxSize& sz) + : m_bmp(bmp), m_pixels(bmp, *this) + { + InitRect(pt, sz); + } + // we evaluate to true only if we could get access to bitmap data // successfully operator bool() const { return m_pixels.IsOk(); } @@ -554,6 +608,16 @@ struct WXDLLEXPORT wxPixelDataOut // the iterator pointing to the image origin Iterator m_pixels; + + private: + void InitRect(const wxPoint& pt, const wxSize& sz) + { + m_pixels.Offset(*this, pt.x, pt.y); + + m_ptOrigin = pt; + m_width = sz.x; + m_height = sz.y; + } }; }; @@ -562,10 +626,20 @@ class wxPixelData : public wxPixelDataOut::template wxPixelDataIn { public: - wxPixelData(const Image& image) + wxPixelData(Image& image) : wxPixelDataOut::template wxPixelDataIn(image) { } + + wxPixelData(Image& i, const wxPoint& pt, const wxSize& sz) + : wxPixelDataOut::template wxPixelDataIn(i, pt, sz) + { + } + + wxPixelData(Image& i, const wxRect& rect) + : wxPixelDataOut::template wxPixelDataIn(i, rect) + { + } }; // some "predefined" pixel data classes diff --git a/samples/image/image.cpp b/samples/image/image.cpp index c2abf84360..6306f97c77 100644 --- a/samples/image/image.cpp +++ b/samples/image/image.cpp @@ -260,7 +260,9 @@ public: { SetClientSize(SIZE, SIZE); - wxAlphaPixelData data(m_bitmap); + wxAlphaPixelData data(m_bitmap, + wxPoint(BORDER, BORDER), + wxSize(REAL_SIZE, REAL_SIZE)); if ( !data ) { wxLogError(_T("Failed to gain raw access to bitmap data")); @@ -271,8 +273,6 @@ public: wxAlphaPixelData::Iterator p(data); - p.Offset(data, BORDER, BORDER); - for ( int y = 0; y < REAL_SIZE; ++y ) { wxAlphaPixelData::Iterator rowStart = p; diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index ab92546271..e1b6743cd4 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -2314,7 +2314,7 @@ wxAlphaBlend(wxDC& dc, int xDst, int yDst, int w, int h, const wxBitmap& bmpSrc) // combine them with the source bitmap using alpha wxAlphaPixelData dataDst(bmpDst), - dataSrc(bmpSrc); + dataSrc((wxBitmap &)bmpSrc); wxCHECK_RET( dataDst && dataSrc, _T("failed to get raw data in wxAlphaBlend") ); -- 2.47.2