]> git.saurik.com Git - wxWidgets.git/blame - include/wx/rawbmp.h
explicit cast for digital mars to use OLE
[wxWidgets.git] / include / wx / rawbmp.h
CommitLineData
916b0ea3
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: wx/rawbmp.h
3// Purpose: macros for fast, raw bitmap data access
4// Author: Eric Kidd, Vadim Zeitlin
5// Modified by:
6// Created: 10.03.03
7// RCS-ID: $Id$
8// Copyright: (c) 2002 Vadim Zeitlin <vadim@wxwindows.org>
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12#ifndef _WX_RAWBMP_H_BASE_
13#define _WX_RAWBMP_H_BASE_
14
15// ----------------------------------------------------------------------------
16// Abstract Pixel API
17//
18// We need to access our raw bitmap data (1) portably and (2) efficiently.
19// We do this using a two-dimensional "iteration" interface. Performance
20// is extremely important here: these functions will be called hundreds
21// of thousands of times in a row, and even small inefficiencies will
22// make applications seem slow.
23//
24// We can't always rely on inline functions, because not all compilers actually
25// bother to inline them unless we crank the optimization levels way up.
26// Therefore, we also provide macros to wring maximum speed out of compiler
27// unconditionally (e.g. even in debug builds). Of course, if the performance
28// isn't absolutely crucial for you you shouldn't be using them but the inline
29// functions instead.
30// ----------------------------------------------------------------------------
31
32/*
33 Usage example:
34
35 wxBitmap bmp;
36 wxRawBitmapData data(bitmap);
37 if ( !data )
38 {
39 ... raw access to bitmap data unavailable, do something else ...
40 return;
41 }
42
43 if ( data.m_width < 20 || data.m_height < 20 )
44 {
45 ... complain: the bitmap it too small ...
46 return;
47 }
48
49 wxRawBitmapIterator p(data);
50
51 // we draw a (10, 10)-(20, 20) rect manually using the given r, g, b
52 p.Offset(10, 10);
53
54 for ( int y = 0; y < 10; ++y )
55 {
56 wxRawBitmapIterator rowStart = p;
57
58 for ( int x = 0; x < 10; ++x, ++p )
59 {
60 p.Red() = r;
61 p.Green() = g;
62 p.Blue() = b;
63 }
64
65 p = rowStart;
66 p.OffsetY(1);
67 }
68 */
69
70// this struct represents a pointer to raw bitmap data
71class wxRawBitmapData
72{
73public:
74 // ctor associates this pointer with a bitmap and locks the bitmap for raw
75 // access, it will be unlocked only by our dtor and so these objects should
76 // normally be only created on the stack, i.e. have limited life-time
77 wxRawBitmapData(wxBitmap bmp) : m_bmp(bmp)
78 {
79 if ( !bmp.GetRawData(this) )
80 m_pixels = NULL;
81 }
82
83 // we evaluate to true only if we could get access to bitmap data
84 // successfully
85 operator bool() const { return m_pixels != NULL; }
86
87 // dtor unlocks the bitmap
88 ~wxRawBitmapData()
89 {
90 m_bmp.UngetRawData(this);
91 }
92
10b41b53
VZ
93 // call this to indicate that we should use the alpha channel
94 void UseAlpha() { m_bmp.UseAlpha(); }
95
916b0ea3
VZ
96 // accessors
97 unsigned char *GetPixels() const { return m_pixels; }
98 int GetWidth() const { return m_width; }
99 int GetHeight() const { return m_height; }
100 int GetByPP() const { return m_bypp; }
101 int GetBPP() const { return 8*GetByPP(); }
102 int GetRowStride() const { return m_stride; }
103
104// private: -- public because accessed by the macros below but still mustn't be
105// used directly
106
107 // the bitmap we're associated with
108 wxBitmap m_bmp;
109
110 // pointer to the start of the data
111 unsigned char *m_pixels;
112
113 // the size of the image we address, in pixels
114 int m_width,
115 m_height;
116
117 // number of bytes (NOT bits) per pixel, including alpha channel if any
118 int m_bypp;
119
120 // this parameter is the offset of the start of the (N+1)st row from the
121 // Nth one and can be different from m_bypp*width in some cases:
122 // a) the most usual one is to force 32/64 bit alignment of rows
123 // b) another one is for bottom-to-top images where it's negative
124 // c) finally, it could conceivably be 0 for the images with all
125 // lines being identical
126 int m_stride;
127};
128
129// this is the type for the iterator over raw bitmap data
130class wxRawBitmapIterator
131{
132public:
133 // ctors and such
134 // --------------
135
136 // we must be associated/initialized with some bitmap data object
137 wxRawBitmapIterator(const wxRawBitmapData& data) : m_data(&data)
138 {
139 m_ptr = m_data->GetPixels();
140 }
141
142 // default copy ctor, assignment operator and dtor are ok
143
e1b998ce 144
916b0ea3
VZ
145 // navigation
146 // ----------
147
148 // move x pixels to the right and y down
149 //
150 // note that the rows don't wrap!
151 void Offset(int x, int y)
152 {
153 m_ptr += m_data->GetRowStride()*y + m_data->GetByPP()*x;
154 }
155
156 // move x pixels to the right (again, no row wrapping)
157 void OffsetX(int x)
158 {
159 m_ptr += m_data->GetByPP()*x;
160 }
161
162 // move y rows to the bottom
163 void OffsetY(int y)
164 {
165 m_ptr += m_data->GetRowStride()*y;
166 }
167
168 // go back to (0, 0)
169 void Reset()
170 {
171 m_ptr = m_data->GetPixels();
172 }
173
174 // go to the given position
175 void MoveTo(int x, int y)
176 {
177 Reset();
178 Offset(x, y);
179 }
180
181 // same as OffsetX(1) for convenience
182 wxRawBitmapIterator& operator++()
183 {
184 OffsetX(1);
185 return *this;
186 }
187
188 // postfix (hence less efficient) version
189 wxRawBitmapIterator operator++(int)
190 {
191 wxRawBitmapIterator p(*this);
192 OffsetX(1);
193 return p;
194 }
195
196 // data access
197 // -----------
198
199 // DIBs store data in BGR format, i.e. "little endian" RGB
200 enum
201 {
202#ifdef __WXMSW__
203 BLUE, GREEN, RED,
204#else // !__WXMSW__
3c5bd188 205 RED, GREEN, BLUE,
916b0ea3
VZ
206#endif // __WXMSW__/!__WXMSW__
207 ALPHA
208 };
209
210 // access to invidividual colour components
211 unsigned char& Red() { return m_ptr[RED]; }
212 unsigned char& Green() { return m_ptr[GREEN]; }
213 unsigned char& Blue() { return m_ptr[BLUE]; }
214 unsigned char& Alpha() { return m_ptr[ALPHA]; }
215
216 // address the pixel contents directly
217 //
218 // warning: the format is platform dependent
219 wxUint32& Data() { return *(wxUint32 *)m_ptr; }
220
221// private: -- don't access these fields directly, same as as above
222 unsigned char *m_ptr;
223
224 const wxRawBitmapData *m_data;
225};
226
227
228// these macros are used to change the current location in the bitmap
229// ------------------------------------------------------------------
230
231// move x pixels to the right and y down
232//
233// note that the rows don't wrap!
234#define wxBMP_OFFSET(p, x, y) \
235 p.m_ptr += p.m_data->m_stride * (y) + p.m_data->m_bypp * (x)
236
237// move x pixels to the right (again, no row wrapping)
238#define wxBMP_OFFSET_X(p, x) p.m_ptr += p.m_data->m_bypp * (x)
239
240// move y rows to the bottom
241#define wxBMP_OFFSET_Y(p, y) p.m_ptr += p.m_data->m_stride * (y)
242
243
244
245// these macros are used to work with the pixel values
246//
247// all of them can be used as either lvalues or rvalues.
248// ----------------------------------------------------
249
250#define wxBMP_RED(p) (p.m_ptr[wxRawBitmapIterator::RED])
251#define wxBMP_GREEN(p) (p.m_ptr[wxRawBitmapIterator::GREEN])
252#define wxBMP_BLUE(p) (p.m_ptr[wxRawBitmapIterator::BLUE])
253
254#define wxBMP_ALPHA(p) (p.m_ptr[wxRawBitmapIterator::ALPHA])
255
256// these macros are most efficient but return the buffer contents in
257// platform-specific format, e.g. RGB on all sane platforms and BGR under Win32
258#define wxBMP_RGB(p) *(wxUint32 *)(p.m_ptr)
259#define wxBMP_RGBA(p) *(wxUint32 *)(p.m_ptr)
260
261#endif // _WX_RAWBMP_H_BASE_
262