git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19708 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			260 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			260 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| ///////////////////////////////////////////////////////////////////////////////
 | |
| // 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 <vadim@wxwindows.org>
 | |
| // 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_
 | |
| 
 |