]> git.saurik.com Git - wxWidgets.git/blob - src/cocoa/bitmap.mm
Added simple implementation of (Get|Unget)RawData.
[wxWidgets.git] / src / cocoa / bitmap.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/cocoa/bitmap.cpp
3 // Purpose: wxBitmap
4 // Author: David Elliott
5 // Modified by:
6 // Created: 2003/07/19
7 // RCS-ID: $Id$
8 // Copyright: (c) 2003 David Elliott
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13 #ifndef WX_PRECOMP
14 #include "wx/log.h"
15 #include "wx/utils.h"
16 #include "wx/palette.h"
17 #include "wx/icon.h"
18 #endif //WX_PRECOMP
19 #include "wx/bitmap.h"
20 #include "wx/image.h"
21 #include "wx/xpmdecod.h"
22 #include "wx/rawbmp.h"
23
24 #include "wx/cocoa/autorelease.h"
25 #include "wx/cocoa/string.h"
26
27 #import <AppKit/NSBitmapImageRep.h>
28 #import <AppKit/NSGraphics.h>
29
30 // ========================================================================
31 // wxBitmapRefData
32 // ========================================================================
33 class wxBitmapRefData: public wxGDIRefData
34 {
35 friend class wxBitmap;
36 public:
37 wxBitmapRefData();
38 wxBitmapRefData( const wxBitmapRefData& data );
39 virtual ~wxBitmapRefData();
40
41 protected:
42 int m_width;
43 int m_height;
44 int m_depth;
45 bool m_ok;
46 int m_numColors;
47 wxPalette m_bitmapPalette;
48 int m_quality;
49 WX_NSBitmapImageRep m_cocoaNSBitmapImageRep;
50 wxMask *m_bitmapMask; // Optional mask
51 };
52
53 #define M_BITMAPDATA ((wxBitmapRefData *)m_refData)
54
55 wxBitmapRefData::wxBitmapRefData()
56 {
57 m_ok = FALSE;
58 m_width = 0;
59 m_height = 0;
60 m_depth = 0;
61 m_quality = 0;
62 m_numColors = 0;
63 m_cocoaNSBitmapImageRep = nil;
64 m_bitmapMask = NULL;
65 }
66
67 wxBitmapRefData::wxBitmapRefData( const wxBitmapRefData& data)
68 {
69 m_width = data.m_width;
70 m_height = data.m_height;
71 m_depth = data.m_depth;
72 m_ok = data.m_ok;
73 m_numColors = data.m_numColors;
74 m_bitmapPalette = data.m_bitmapPalette;
75 m_quality = data.m_quality;
76 m_cocoaNSBitmapImageRep = [data.m_cocoaNSBitmapImageRep copyWithZone:nil];
77 m_bitmapMask = data.m_bitmapMask?new wxMask(*data.m_bitmapMask):NULL;
78 }
79
80 wxBitmapRefData::~wxBitmapRefData()
81 {
82 [m_cocoaNSBitmapImageRep release];
83 m_cocoaNSBitmapImageRep = NULL;
84
85 delete m_bitmapMask;
86 m_bitmapMask = NULL;
87 }
88
89 // ========================================================================
90 // wxBitmap
91 // ========================================================================
92 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
93
94 wxBitmap::wxBitmap()
95 {
96 m_refData = NULL;
97 }
98
99 wxBitmap::~wxBitmap()
100 {
101 }
102
103 wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
104 {
105 m_refData = new wxBitmapRefData;
106
107 M_BITMAPDATA->m_width = the_width ;
108 M_BITMAPDATA->m_height = the_height ;
109 M_BITMAPDATA->m_depth = no_bits ;
110 M_BITMAPDATA->m_numColors = 0;
111
112 /* TODO: create the bitmap from data */
113 }
114
115 wxBitmap::wxBitmap(int w, int h, int d)
116 {
117 (void)Create(w, h, d);
118 }
119
120 wxBitmap::wxBitmap(void *data, wxBitmapType type, int width, int height, int depth)
121 {
122 (void) Create(data, type, width, height, depth);
123 }
124
125 wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type)
126 {
127 LoadFile(filename, type);
128 }
129
130 wxObjectRefData *wxBitmap::CreateRefData() const
131 {
132 return new wxBitmapRefData;
133 }
134
135 wxObjectRefData *wxBitmap::CloneRefData(const wxObjectRefData *data) const
136 {
137 return new wxBitmapRefData(*(wxBitmapRefData*)data);
138 }
139
140 WX_NSBitmapImageRep wxBitmap::GetNSBitmapImageRep()
141 {
142 if(!M_BITMAPDATA)
143 return NULL;
144 return M_BITMAPDATA->m_cocoaNSBitmapImageRep;
145 }
146
147 void wxBitmap::SetNSBitmapImageRep(WX_NSBitmapImageRep bitmapImageRep)
148 {
149 if(!M_BITMAPDATA)
150 return;
151 // NOTE: No checking is done to make sure width/height agree
152 [bitmapImageRep retain];
153 [M_BITMAPDATA->m_cocoaNSBitmapImageRep release];
154 M_BITMAPDATA->m_cocoaNSBitmapImageRep = bitmapImageRep;
155 }
156
157 void wxBitmap::SetWidth(int w)
158 {
159 if (!M_BITMAPDATA)
160 m_refData = new wxBitmapRefData;
161
162 M_BITMAPDATA->m_width = w;
163 }
164
165 void wxBitmap::SetHeight(int h)
166 {
167 if (!M_BITMAPDATA)
168 m_refData = new wxBitmapRefData;
169
170 M_BITMAPDATA->m_height = h;
171 }
172
173 void wxBitmap::SetDepth(int d)
174 {
175 if (!M_BITMAPDATA)
176 m_refData = new wxBitmapRefData;
177
178 M_BITMAPDATA->m_depth = d;
179 }
180
181 void wxBitmap::SetQuality(int q)
182 {
183 if (!M_BITMAPDATA)
184 m_refData = new wxBitmapRefData;
185
186 M_BITMAPDATA->m_quality = q;
187 }
188
189 void wxBitmap::SetOk(bool isOk)
190 {
191 if (!M_BITMAPDATA)
192 m_refData = new wxBitmapRefData;
193
194 M_BITMAPDATA->m_ok = isOk;
195 }
196
197 void wxBitmap::SetPalette(const wxPalette& palette)
198 {
199 if (!M_BITMAPDATA)
200 m_refData = new wxBitmapRefData;
201
202 M_BITMAPDATA->m_bitmapPalette = palette ;
203 }
204
205 void wxBitmap::SetMask(wxMask *mask)
206 {
207 if (!M_BITMAPDATA)
208 m_refData = new wxBitmapRefData;
209
210 M_BITMAPDATA->m_bitmapMask = mask ;
211 }
212
213 bool wxBitmap::Ok() const
214 {
215 return m_refData && M_BITMAPDATA->m_ok;
216 }
217
218 wxPalette* wxBitmap::GetPalette() const
219 {
220 if(!m_refData)
221 return NULL;
222 return &M_BITMAPDATA->m_bitmapPalette;
223 }
224
225 wxMask* wxBitmap::GetMask() const
226 {
227 if(!m_refData)
228 return NULL;
229 return M_BITMAPDATA->m_bitmapMask;
230 }
231
232 int wxBitmap::GetDepth() const
233 {
234 if(!m_refData)
235 return 0;
236 return M_BITMAPDATA->m_depth;
237 }
238
239 int wxBitmap::GetWidth() const
240 {
241 if(!m_refData)
242 return 0;
243 return M_BITMAPDATA->m_width;
244 }
245
246 int wxBitmap::GetHeight() const
247 {
248 if(!m_refData)
249 return 0;
250 return M_BITMAPDATA->m_height;
251 }
252
253 bool wxBitmap::Create(int w, int h, int d)
254 {
255 UnRef();
256
257 m_refData = new wxBitmapRefData;
258
259 M_BITMAPDATA->m_width = w;
260 M_BITMAPDATA->m_height = h;
261 M_BITMAPDATA->m_depth = d;
262
263 /* TODO: create new bitmap */
264 M_BITMAPDATA->m_cocoaNSBitmapImageRep = [[NSBitmapImageRep alloc]
265 initWithBitmapDataPlanes: NULL
266 pixelsWide: w
267 pixelsHigh: h
268 bitsPerSample: 8
269 samplesPerPixel: 3
270 hasAlpha: NO
271 isPlanar: NO
272 colorSpaceName: NSCalibratedRGBColorSpace
273 bytesPerRow: 0
274 bitsPerPixel: 0];
275
276 wxLogDebug("M_BITMAPDATA=%p NSBitmapImageRep bitmapData=%p", M_BITMAPDATA, [M_BITMAPDATA->m_cocoaNSBitmapImageRep bitmapData]);
277 M_BITMAPDATA->m_ok = true;
278 M_BITMAPDATA->m_numColors = 0;
279 M_BITMAPDATA->m_quality = 0;
280 M_BITMAPDATA->m_bitmapMask = NULL;
281
282 return M_BITMAPDATA->m_ok;
283 }
284
285 bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type)
286 {
287 wxAutoNSAutoreleasePool pool;
288 UnRef();
289
290 m_refData = new wxBitmapRefData;
291
292 NSBitmapImageRep *imageRep = [NSBitmapImageRep
293 imageRepWithContentsOfFile:wxNSStringWithWxString(filename)];
294
295 if(imageRep)
296 {
297 M_BITMAPDATA->m_width = [imageRep pixelsWide];
298 M_BITMAPDATA->m_height = [imageRep pixelsHigh];
299 M_BITMAPDATA->m_depth = 24; // FIXME
300 M_BITMAPDATA->m_ok = true;
301 M_BITMAPDATA->m_numColors = 0;
302 M_BITMAPDATA->m_quality = 0;
303 M_BITMAPDATA->m_cocoaNSBitmapImageRep = [imageRep retain];
304 M_BITMAPDATA->m_bitmapMask = NULL;
305 return true;
306 }
307 wxImage image;
308 if(!image.LoadFile(filename,type))
309 return false;
310 if(!image.Ok())
311 return false;
312 *this = wxBitmap(image);
313 return true;
314 }
315
316 bool wxBitmap::Create(void *data, wxBitmapType type, int width, int height, int depth)
317 {
318 UnRef();
319
320 m_refData = new wxBitmapRefData;
321
322 return false;
323 }
324
325 bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPalette *palette) const
326 {
327 return false;
328 }
329
330 bool wxBitmap::CopyFromIcon(const wxIcon& icno)
331 {
332 return false;
333 }
334
335 wxBitmap wxBitmap::GetSubBitmap(wxRect const&) const
336 {
337 return wxNullBitmap;
338 }
339
340 wxImage wxBitmap::ConvertToImage() const
341 {
342 if(!M_BITMAPDATA->m_ok)
343 return wxImage(5,5)/*wxNullImage*/;
344 return wxImage(M_BITMAPDATA->m_width,M_BITMAPDATA->m_height);
345 }
346
347 bool wxBitmap::CreateFromXpm(const char **xpm)
348 {
349 #if wxUSE_IMAGE && wxUSE_XPM
350 UnRef();
351
352 wxCHECK_MSG( xpm, false, wxT("invalid XPM data") )
353
354 wxXPMDecoder decoder;
355 wxImage img = decoder.ReadData(xpm);
356 wxCHECK_MSG( img.Ok(), false, wxT("invalid XPM data") )
357
358 *this = wxBitmap(img);
359 return true;
360 #else
361 return false;
362 #endif
363 }
364
365 bool wxBitmap::CreateFromImage(const wxImage& image, int depth)
366 {
367 UnRef();
368
369 wxCHECK_MSG(image.Ok(), false, wxT("invalid image"));
370 wxCHECK_MSG(depth == -1 || depth == 1, false, wxT("invalid bitmap depth"));
371
372 m_refData = new wxBitmapRefData();
373
374 M_BITMAPDATA->m_width = image.GetWidth();
375 M_BITMAPDATA->m_height = image.GetHeight();
376 NSBitmapImageRep *bitmapImage = [[NSBitmapImageRep alloc]
377 initWithBitmapDataPlanes: NULL
378 pixelsWide: image.GetWidth()
379 pixelsHigh: image.GetHeight()
380 bitsPerSample: 8
381 samplesPerPixel: 3
382 hasAlpha: NO
383 isPlanar: NO
384 colorSpaceName: NSCalibratedRGBColorSpace
385 bytesPerRow: 0
386 bitsPerPixel: 0];
387
388 const int numBytes = image.GetWidth()*image.GetHeight()*3;
389 memcpy([bitmapImage bitmapData], image.GetData(), numBytes);
390 // TODO: Alpha and convert to desired depth
391 M_BITMAPDATA->m_depth = 24;
392 M_BITMAPDATA->m_ok = true;
393 M_BITMAPDATA->m_numColors = 0;
394 M_BITMAPDATA->m_quality = 0;
395 M_BITMAPDATA->m_cocoaNSBitmapImageRep = bitmapImage;
396 M_BITMAPDATA->m_bitmapMask = NULL;
397 return true;
398 }
399
400 void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
401 {
402 if(!Ok())
403 return NULL;
404
405 NSBitmapImageRep *bitmapRep = M_BITMAPDATA->m_cocoaNSBitmapImageRep;
406 if(!bitmapRep)
407 return NULL;
408
409 if([bitmapRep bitsPerPixel]!=bpp)
410 {
411 wxFAIL_MSG( _T("incorrect bitmap type in wxBitmap::GetRawData()") );
412 return NULL;
413 }
414 data.m_width = [bitmapRep pixelsWide];
415 data.m_height = [bitmapRep pixelsHigh];
416 data.m_stride = [bitmapRep bytesPerRow];
417 return [bitmapRep bitmapData];
418
419 // NOTE: It is up to the user to make sure they used the proper
420 // pixel format class that details what is actually inside the pixels
421 // We can only check to make sure that the total number of bits per
422 // pixel are being iterated over properly
423 // NSBitmapImageRep can contain grayscale or CMYK data and
424 // wxPixelDataBase doesn't really define the color format
425 }
426
427 void wxBitmap::UngetRawData(wxPixelDataBase& data)
428 { // TODO
429 }
430
431 // ========================================================================
432 // wxMask
433 // ========================================================================
434
435 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
436
437 wxMask::wxMask()
438 {
439 /* TODO
440 m_maskBitmap = 0;
441 */
442 }
443
444 // Construct a mask from a bitmap and a colour indicating
445 // the transparent area
446 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
447 {
448 /* TODO
449 m_maskBitmap = 0;
450 */
451 Create(bitmap, colour);
452 }
453
454 // Construct a mask from a bitmap and a palette index indicating
455 // the transparent area
456 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
457 {
458 /* TODO
459 m_maskBitmap = 0;
460 */
461
462 Create(bitmap, paletteIndex);
463 }
464
465 // Construct a mask from a mono bitmap (copies the bitmap).
466 wxMask::wxMask(const wxBitmap& bitmap)
467 {
468 /* TODO
469 m_maskBitmap = 0;
470 */
471
472 Create(bitmap);
473 }
474
475 wxMask::~wxMask()
476 {
477 // TODO: delete mask bitmap
478 }
479
480 // Create a mask from a mono bitmap (copies the bitmap).
481 bool wxMask::Create(const wxBitmap& bitmap)
482 {
483 // TODO
484 return FALSE;
485 }
486
487 // Create a mask from a bitmap and a palette index indicating
488 // the transparent area
489 bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
490 {
491 // TODO
492 return FALSE;
493 }
494
495 // Create a mask from a bitmap and a colour indicating
496 // the transparent area
497 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
498 {
499 // TODO
500 return FALSE;
501 }
502