From 916b0ea345c2418b6768695cc9334f10dcf1d415 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 22 Mar 2003 19:00:48 +0000 Subject: [PATCH] added (very) preliminary raw bitmap support git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19708 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- distrib/msw/tmake/filelist.txt | 1 + include/wx/rawbmp.h | 259 +++++++++++++++++++++++++++++++++ 2 files changed, 260 insertions(+) create mode 100644 include/wx/rawbmp.h diff --git a/distrib/msw/tmake/filelist.txt b/distrib/msw/tmake/filelist.txt index 4943a8c49a..04f281d606 100644 --- a/distrib/msw/tmake/filelist.txt +++ b/distrib/msw/tmake/filelist.txt @@ -981,6 +981,7 @@ proplist.h WXH quantize.h WXH radiobox.h WXH radiobut.h WXH +rawbmp.h WXH regex.h WXH Base region.h WXH resource.h WXH diff --git a/include/wx/rawbmp.h b/include/wx/rawbmp.h new file mode 100644 index 0000000000..889b6d129f --- /dev/null +++ b/include/wx/rawbmp.h @@ -0,0 +1,259 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/rawbmp.h +// Purpose: macros for fast, raw bitmap data access +// Author: Eric Kidd, Vadim Zeitlin +// Modified by: +// Created: 10.03.03 +// RCS-ID: $Id$ +// Copyright: (c) 2002 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_RAWBMP_H_BASE_ +#define _WX_RAWBMP_H_BASE_ + +// ---------------------------------------------------------------------------- +// Abstract Pixel API +// +// We need to access our raw bitmap data (1) portably and (2) efficiently. +// We do this using a two-dimensional "iteration" interface. Performance +// is extremely important here: these functions will be called hundreds +// of thousands of times in a row, and even small inefficiencies will +// make applications seem slow. +// +// We can't always rely on inline functions, because not all compilers actually +// bother to inline them unless we crank the optimization levels way up. +// Therefore, we also provide macros to wring maximum speed out of compiler +// unconditionally (e.g. even in debug builds). Of course, if the performance +// isn't absolutely crucial for you you shouldn't be using them but the inline +// functions instead. +// ---------------------------------------------------------------------------- + +/* + Usage example: + + wxBitmap bmp; + wxRawBitmapData data(bitmap); + if ( !data ) + { + ... raw access to bitmap data unavailable, do something else ... + return; + } + + if ( data.m_width < 20 || data.m_height < 20 ) + { + ... complain: the bitmap it too small ... + return; + } + + wxRawBitmapIterator p(data); + + // we draw a (10, 10)-(20, 20) rect manually using the given r, g, b + p.Offset(10, 10); + + for ( int y = 0; y < 10; ++y ) + { + wxRawBitmapIterator rowStart = p; + + for ( int x = 0; x < 10; ++x, ++p ) + { + p.Red() = r; + p.Green() = g; + p.Blue() = b; + } + + p = rowStart; + p.OffsetY(1); + } + */ + +// this struct represents a pointer to raw bitmap data +class wxRawBitmapData +{ +public: + // 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 + wxRawBitmapData(wxBitmap bmp) : m_bmp(bmp) + { + if ( !bmp.GetRawData(this) ) + m_pixels = NULL; + } + + // we evaluate to true only if we could get access to bitmap data + // successfully + operator bool() const { return m_pixels != NULL; } + + // dtor unlocks the bitmap + ~wxRawBitmapData() + { + m_bmp.UngetRawData(this); + } + + // accessors + unsigned char *GetPixels() const { return m_pixels; } + int GetWidth() const { return m_width; } + int GetHeight() const { return m_height; } + int GetByPP() const { return m_bypp; } + int GetBPP() const { return 8*GetByPP(); } + int GetRowStride() const { return m_stride; } + +// private: -- public because accessed by the macros below but still mustn't be +// used directly + + // the bitmap we're associated with + wxBitmap m_bmp; + + // pointer to the start of the data + unsigned char *m_pixels; + + // the size of the image we address, in pixels + int m_width, + m_height; + + // number of bytes (NOT bits) per pixel, including alpha channel if any + int m_bypp; + + // this parameter is the offset of the start of the (N+1)st row from the + // Nth one and can be different from m_bypp*width in some cases: + // a) the most usual one is to force 32/64 bit alignment of rows + // b) another one is for bottom-to-top images where it's negative + // c) finally, it could conceivably be 0 for the images with all + // lines being identical + int m_stride; +}; + +// this is the type for the iterator over raw bitmap data +class wxRawBitmapIterator +{ +public: + // ctors and such + // -------------- + + // we must be associated/initialized with some bitmap data object + wxRawBitmapIterator(const wxRawBitmapData& data) : m_data(&data) + { + m_ptr = m_data->GetPixels(); + } + + // default copy ctor, assignment operator and dtor are ok + + + // navigation + // ---------- + + // move x pixels to the right and y down + // + // note that the rows don't wrap! + void Offset(int x, int y) + { + m_ptr += m_data->GetRowStride()*y + m_data->GetByPP()*x; + } + + // move x pixels to the right (again, no row wrapping) + void OffsetX(int x) + { + m_ptr += m_data->GetByPP()*x; + } + + // move y rows to the bottom + void OffsetY(int y) + { + m_ptr += m_data->GetRowStride()*y; + } + + // go back to (0, 0) + void Reset() + { + m_ptr = m_data->GetPixels(); + } + + // go to the given position + void MoveTo(int x, int y) + { + Reset(); + Offset(x, y); + } + + // same as OffsetX(1) for convenience + wxRawBitmapIterator& operator++() + { + OffsetX(1); + return *this; + } + + // postfix (hence less efficient) version + wxRawBitmapIterator operator++(int) + { + wxRawBitmapIterator p(*this); + OffsetX(1); + return p; + } + + // data access + // ----------- + + // DIBs store data in BGR format, i.e. "little endian" RGB + enum + { +#ifdef __WXMSW__ + BLUE, GREEN, RED, +#else // !__WXMSW__ + RED, GREEN, BLUE +#endif // __WXMSW__/!__WXMSW__ + ALPHA + }; + + // access to invidividual colour components + unsigned char& Red() { return m_ptr[RED]; } + unsigned char& Green() { return m_ptr[GREEN]; } + unsigned char& Blue() { return m_ptr[BLUE]; } + unsigned char& Alpha() { return m_ptr[ALPHA]; } + + // address the pixel contents directly + // + // warning: the format is platform dependent + wxUint32& Data() { return *(wxUint32 *)m_ptr; } + +// private: -- don't access these fields directly, same as as above + unsigned char *m_ptr; + + const wxRawBitmapData *m_data; +}; + + +// these macros are used to change the current location in the bitmap +// ------------------------------------------------------------------ + +// move x pixels to the right and y down +// +// note that the rows don't wrap! +#define wxBMP_OFFSET(p, x, y) \ + p.m_ptr += p.m_data->m_stride * (y) + p.m_data->m_bypp * (x) + +// move x pixels to the right (again, no row wrapping) +#define wxBMP_OFFSET_X(p, x) p.m_ptr += p.m_data->m_bypp * (x) + +// move y rows to the bottom +#define wxBMP_OFFSET_Y(p, y) p.m_ptr += p.m_data->m_stride * (y) + + + +// these macros are used to work with the pixel values +// +// all of them can be used as either lvalues or rvalues. +// ---------------------------------------------------- + +#define wxBMP_RED(p) (p.m_ptr[wxRawBitmapIterator::RED]) +#define wxBMP_GREEN(p) (p.m_ptr[wxRawBitmapIterator::GREEN]) +#define wxBMP_BLUE(p) (p.m_ptr[wxRawBitmapIterator::BLUE]) + +#define wxBMP_ALPHA(p) (p.m_ptr[wxRawBitmapIterator::ALPHA]) + +// these macros are most efficient but return the buffer contents in +// platform-specific format, e.g. RGB on all sane platforms and BGR under Win32 +#define wxBMP_RGB(p) *(wxUint32 *)(p.m_ptr) +#define wxBMP_RGBA(p) *(wxUint32 *)(p.m_ptr) + +#endif // _WX_RAWBMP_H_BASE_ + -- 2.45.2