wxArt2D
imagergba.cpp
Go to the documentation of this file.
1 /*! \file genart/src/imagergba.cpp
2  \author Klaas Holwerda
3 
4  Copyright: 2000-2004 (c) Klaas Holwerda
5 
6  Licence: wxWidgets Licence
7 
8  RCS-ID: $Id: imagergba.cpp,v 1.2 2009/09/02 20:01:23 titato Exp $
9 */
10 
11 #include "a2dprec.h"
12 
13 #ifdef __BORLANDC__
14 #pragma hdrstop
15 #endif
16 
17 #ifndef WX_PRECOMP
18 #include "wx/wx.h"
19 #include <wx/wfstream.h>
20 #include "wx/genart/imagergba.h"
21 #endif
22 
23 //----------------------------------------------------------------------------
24 // a2dImageRGBA
25 //----------------------------------------------------------------------------
26 
27 #if defined(__WXPALMOS__)
28 #elif defined(__WXMSW__)
29 #include "wx/msw/dib.h"
30 #elif defined(__WXMOTIF__)
31 #elif defined(__WXGTK20__)
32 #include <gtk/gtk.h>
33 #elif defined(__WXGTK__)
34 #include <gtk/gtk.h>
35 #elif defined(__WXX11__)
36 #elif defined(__WXMGL__)
37 #elif defined(__WXDFB__)
38 #elif defined(__WXMAC__)
39 #elif defined(__WXCOCOA__)
40 #elif defined(__WXPM__)
41 #endif
42 
43 a2dImageRGBA::a2dImageRGBA( int width, int height )
44 {
45  m_height = height;
46  m_width = width;
47  m_glimage = ( unsigned char* ) malloc( width * height * 4 );
48  memset( m_glimage, 0, width * height * 4 );
49 #if defined(__WXMSW__)
50  m_rgbOrder = false;
51 #else
52  m_rgbOrder = true;
53 #endif
54 
55 }
56 
57 a2dImageRGBA::a2dImageRGBA( const wxImage& image, unsigned char alpha )
58 {
59 #if defined(__WXMSW__)
60  m_rgbOrder = false;
61 #else
62  m_rgbOrder = true;
63 #endif
64 
65  m_height = image.GetHeight();
66  m_width = image.GetWidth();
67  m_glimage = ( unsigned char* ) malloc( image.GetWidth() * image.GetHeight() * 4 );
68  int i, j;
69 
70  unsigned char* data = ( unsigned char* ) m_glimage;
71  for ( i = m_height - 1; i >= 0 ; i-- )
72  //for ( i=0; i < m_height ; i++ )
73  {
74  for ( j = 0; j < m_width ; j++ )
75  {
76  if ( m_rgbOrder )
77  {
78  *data++ = image.GetRed( j, i );
79  *data++ = image.GetGreen( j, i );
80  *data++ = image.GetBlue( j, i );
81  if ( image.HasAlpha() )
82  * data++ = ( image.GetAlpha( j, i ) * alpha ) / 255;
83  else if ( image.HasMask() )
84  {
85  if ( image.IsTransparent( i, j ) )
86  * data++ = ( unsigned char ) 0;
87  else
88  * data++ = alpha;
89  }
90  else
91  *data++ = ( unsigned char ) alpha;
92  }
93  else
94  {
95  *data++ = image.GetBlue( j, i );
96  *data++ = image.GetGreen( j, i );
97  *data++ = image.GetRed( j, i );
98  if ( image.HasAlpha() )
99  *data++ = ( image.GetAlpha( j, i ) * alpha ) / 255;
100  else if ( image.HasMask() )
101  {
102  if ( image.IsTransparent( j, i ) )
103  * data++ = ( unsigned char ) 0;
104  else
105  * data++ = alpha;
106  }
107  else
108  *data++ = ( unsigned char ) alpha;
109  }
110 
111  }
112  }
113 }
114 
115 a2dImageRGBA::~a2dImageRGBA()
116 {
117  m_height = 0;
118  m_width = 0;
119  free( m_glimage );
120  m_glimage = NULL;
121 
122 }
123 
124 a2dImageRGBA& a2dImageRGBA::operator=( const a2dImageRGBA& other )
125 {
126  free( m_glimage );
127  m_glimage = ( unsigned char* )malloc( other.m_width * other.m_height * 4 );
128  memcpy( m_glimage, other.m_glimage, other.m_width * other.m_height * 4 );
129  m_height = other.m_height;
130  m_width = other.m_width;
131  m_rgbOrder = other.m_rgbOrder;
132  return *this;
133 }
134 
135 void a2dImageRGBA::SetAlpha( unsigned char alpha )
136 {
137  int j;
138  unsigned char* data;
139  data = ( unsigned char* ) m_glimage;
140  data = data + 3;
141  for ( j = 0; j < m_height * m_width; j++ )
142  {
143  *data = alpha;
144  data = data + 4;
145  }
146 }
147 
148 void a2dImageRGBA::SetAlpha( unsigned char* alphadata )
149 {
150  int j;
151  unsigned char* data;
152  data = ( unsigned char* ) m_glimage;
153  data = data + 3;
154  for ( j = 0; j < m_height * m_width; j++ )
155  {
156  *data = *alphadata;
157  data = data + 4;
158  alphadata++;
159  }
160 }
161 
162 wxImage a2dImageRGBA::GetImage() const
163 {
164  wxImage image = wxImage( m_width, m_height );
165  image.SetAlpha();
166  unsigned char* imageData = image.GetData();
167  int i, j;
168 
169  unsigned char* data = ( unsigned char* ) m_glimage;
170  for ( i = m_height - 1; i >= 0 ; i-- )
171  //for ( i=0; i < m_height ; i++ )
172  {
173  for ( j = 0; j < m_width ; j++ )
174  {
175  if ( m_rgbOrder )
176  {
177  *imageData++ = *data++;
178  *imageData++ = *data++;
179  *imageData++ = *data++;
180  image.SetAlpha( j, i, *data++ );
181  }
182  else
183  {
184  *imageData++ = data[2];
185  *imageData++ = data[1];
186  *imageData++ = data[0];
187  image.SetAlpha( j, i, data[3] );
188  data += 4;
189  }
190  }
191  }
192  return image;
193 }
194 
195 a2dImageRGBA* a2dImageRGBA::GetSubImage( const wxRect& rect ) const
196 {
197  const int subwidth = rect.GetWidth();
198  const int subheight = rect.GetHeight();
199 
200  a2dImageRGBA* image = new a2dImageRGBA( subwidth, subheight );
201 
202  wxCHECK_MSG( ( rect.GetLeft() >= 0 ) && ( rect.GetTop() >= 0 ) &&
203  ( rect.GetRight() <= GetWidth() ) && ( rect.GetBottom() <= GetHeight() ),
204  image, wxT( "invalid subimage size" ) );
205 
206  const unsigned char* src_data = GetData();
207  unsigned char* subdata = image->GetData();
208 
209  wxCHECK_MSG( subdata, image, wxT( "unable to create image" ) );
210 
211  const int width = GetWidth();
212  const int pixsoff = rect.GetLeft() + width * rect.GetTop();
213 
214  src_data += 4 * pixsoff;
215 
216  for ( long j = 0; j < subheight; ++j )
217  {
218  memcpy( subdata, src_data, 4 * subwidth );
219  subdata += 4 * subwidth;
220  src_data += 4 * width;
221  }
222 
223  return image;
224 }
225 
226 wxBitmap a2dImageRGBA::CreateBitmap()
227 {
228 #if defined(__WXMSW__)
229 
230  bool m_hasAlpha = true;//false;
231  wxImage image = GetImage();
232  const int bpp = m_hasAlpha ? 32 : 24;
233  return wxBitmap( image, bpp );
234 /*
235  // if we have alpha channel, we need to create a 32bpp RGBA DIB, otherwise
236  // a 24bpp RGB is sufficient
237  bool m_hasAlpha = true;//false;
238  const int bpp = m_hasAlpha ? 32 : 24;
239 
240  wxDIB dib( m_width, m_height, bpp );
241 
242  // DIBs are stored in bottom to top order (see also the comment above in
243  // Create()) so we need to copy bits line by line and starting from the end
244  const int srcBytesPerLine = m_width * 4;
245  const int dstBytesPerLine = dib.GetLineSize( m_width, bpp );
246  const unsigned char* src = GetData() + ( ( m_height - 1 ) * srcBytesPerLine );
247  unsigned char* dstLineStart = dib.GetData();
248  for ( int y = 0; y < m_height; y++ )
249  {
250  // copy one DIB line
251  unsigned char* dst = dstLineStart;
252  if ( !m_rgbOrder )
253  {
254  if ( m_hasAlpha )
255  {
256  for ( int x = 0; x < m_width; x++ )
257  {
258  // RGB order is reversed, and we need to premultiply
259  // all channels by alpha value for use with ::AlphaBlend.
260  const unsigned char a = src[3];
261  *dst++ = ( unsigned char )( ( src[0] * a + 127 ) / 255 );
262  *dst++ = ( unsigned char )( ( src[1] * a + 127 ) / 255 );
263  *dst++ = ( unsigned char )( ( src[2] * a + 127 ) / 255 );
264  *dst++ = ( unsigned char )( src[3] );
265  src += 4;
266  }
267  }
268  else // no alpha channel
269  {
270  for ( int x = 0; x < m_width; x++ )
271  {
272  // RGB order is reversed.
273  *dst++ = src[0];
274  *dst++ = src[1];
275  *dst++ = src[2];
276  src += 4;
277  }
278  }
279  }
280  else
281  {
282  if ( m_hasAlpha )
283  {
284  for ( int x = 0; x < m_width; x++ )
285  {
286  // RGB order is reversed, and we need to premultiply
287  // all channels by alpha value for use with ::AlphaBlend.
288  const unsigned char a = src[3];
289  *dst++ = ( unsigned char )( ( src[2] * a + 127 ) / 255 );
290  *dst++ = ( unsigned char )( ( src[1] * a + 127 ) / 255 );
291  *dst++ = ( unsigned char )( ( src[0] * a + 127 ) / 255 );
292  *dst++ = ( unsigned char )( src[3] );
293  src += 4;
294  }
295  }
296  else // no alpha channel
297  {
298  for ( int x = 0; x < m_width; x++ )
299  {
300  // RGB order is reversed.
301  *dst++ = src[2];
302  *dst++ = src[1];
303  *dst++ = src[0];
304  src += 4;
305  }
306  }
307  }
308 
309  // pass to the previous line in the image
310  src -= 2 * srcBytesPerLine;
311 
312  // and to the next one in the DIB
313  dstLineStart += dstBytesPerLine;
314  }
315 
316  wxBitmap bitm;
317  bitm.CopyFromDIB( dib );
318  bool alpha = bitm.HasAlpha();
319  return bitm;
320 */
321 #else
322 
323  wxBitmap bitm( m_width, m_height, 32 );
324 
325  GdkPixbuf* pixbuf = bitm.GetPixbuf();
326  if ( !pixbuf )
327  return bitm;
328 
329  // Copy the data:
330  const unsigned char* src = GetData();
331  unsigned char* dst = gdk_pixbuf_get_pixels( pixbuf );
332 
333  int rowpad = gdk_pixbuf_get_rowstride( pixbuf ) - 4 * m_width;
334 
335  if ( m_rgbOrder )
336  {
337  memcpy( dst, src, m_width * m_height * 4 );
338  }
339  else
340  {
341  for ( int y = 0; y < m_height; y++ )
342  {
343  for ( int x = 0; x < m_width; x++ )
344  {
345  // RGB order is reversed, and we need to premultiply
346  // all channels by alpha value for use with ::AlphaBlend.
347  const unsigned char a = src[3];
348  *dst++ = ( unsigned char )( ( src[0] * a + 127 ) / 255 );
349  *dst++ = ( unsigned char )( ( src[1] * a + 127 ) / 255 );
350  *dst++ = ( unsigned char )( ( src[2] * a + 127 ) / 255 );
351  *dst++ = ( unsigned char )( src[3] );
352  src += 4;
353  }
354  }
355  }
356 
357  return bitm;
358 #endif
359 
360 }
361 
Contains image with RGBA per pixel.
imagergba.cpp Source File -- Sun Oct 12 2014 17:04:21 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation