add overloads of ctors and Create() functions taking wxSize; document the various...
[wxWidgets.git] / include / wx / image.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/image.h
3 // Purpose: wxImage class
4 // Author: Robert Roebling
5 // RCS-ID: $Id$
6 // Copyright: (c) Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 #ifndef _WX_IMAGE_H_
11 #define _WX_IMAGE_H_
12
13 #include "wx/defs.h"
14
15 #if wxUSE_IMAGE
16
17 #include "wx/object.h"
18 #include "wx/string.h"
19 #include "wx/gdicmn.h"
20 #include "wx/hashmap.h"
21
22 #if wxUSE_STREAMS
23 # include "wx/stream.h"
24 #endif
25
26 // on some systems (Unixware 7.x) index is defined as a macro in the headers
27 // which breaks the compilation below
28 #undef index
29
30 #define wxIMAGE_OPTION_QUALITY wxString(_T("quality"))
31 #define wxIMAGE_OPTION_FILENAME wxString(_T("FileName"))
32
33 #define wxIMAGE_OPTION_RESOLUTION wxString(_T("Resolution"))
34 #define wxIMAGE_OPTION_RESOLUTIONX wxString(_T("ResolutionX"))
35 #define wxIMAGE_OPTION_RESOLUTIONY wxString(_T("ResolutionY"))
36
37 #define wxIMAGE_OPTION_RESOLUTIONUNIT wxString(_T("ResolutionUnit"))
38
39 #define wxIMAGE_OPTION_MAX_WIDTH wxString(_T("MaxWidth"))
40 #define wxIMAGE_OPTION_MAX_HEIGHT wxString(_T("MaxHeight"))
41
42 // constants used with wxIMAGE_OPTION_RESOLUTIONUNIT
43 //
44 // NB: don't change these values, they correspond to libjpeg constants
45 enum wxImageResolution
46 {
47 // Resolution not specified
48 wxIMAGE_RESOLUTION_NONE = 0,
49
50 // Resolution specified in inches
51 wxIMAGE_RESOLUTION_INCHES = 1,
52
53 // Resolution specified in centimeters
54 wxIMAGE_RESOLUTION_CM = 2
55 };
56
57 // Constants for wxImage::Scale() for determining the level of quality
58 enum
59 {
60 wxIMAGE_QUALITY_NORMAL = 0,
61 wxIMAGE_QUALITY_HIGH = 1
62 };
63
64 // alpha channel values: fully transparent, default threshold separating
65 // transparent pixels from opaque for a few functions dealing with alpha and
66 // fully opaque
67 const unsigned char wxIMAGE_ALPHA_TRANSPARENT = 0;
68 const unsigned char wxIMAGE_ALPHA_THRESHOLD = 0x80;
69 const unsigned char wxIMAGE_ALPHA_OPAQUE = 0xff;
70
71 //-----------------------------------------------------------------------------
72 // classes
73 //-----------------------------------------------------------------------------
74
75 class WXDLLIMPEXP_FWD_CORE wxImageHandler;
76 class WXDLLIMPEXP_FWD_CORE wxImage;
77 class WXDLLIMPEXP_FWD_CORE wxPalette;
78
79 //-----------------------------------------------------------------------------
80 // wxVariant support
81 //-----------------------------------------------------------------------------
82
83 #if wxUSE_VARIANT
84 #include "wx/variant.h"
85 DECLARE_VARIANT_OBJECT_EXPORTED(wxImage,WXDLLIMPEXP_CORE)
86 #endif
87
88 //-----------------------------------------------------------------------------
89 // wxImageHandler
90 //-----------------------------------------------------------------------------
91
92 class WXDLLIMPEXP_CORE wxImageHandler: public wxObject
93 {
94 public:
95 wxImageHandler()
96 : m_name(wxEmptyString), m_extension(wxEmptyString), m_mime(), m_type(wxBITMAP_TYPE_INVALID)
97 { }
98
99 #if wxUSE_STREAMS
100 virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=true, int index=-1 );
101 virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=true );
102
103 virtual int GetImageCount( wxInputStream& stream );
104
105 bool CanRead( wxInputStream& stream ) { return CallDoCanRead(stream); }
106 bool CanRead( const wxString& name );
107 #endif // wxUSE_STREAMS
108
109 void SetName(const wxString& name) { m_name = name; }
110 void SetExtension(const wxString& ext) { m_extension = ext; }
111 void SetAlExtensions(const wxArrayString& exts) { m_altExtensions = exts; }
112 void SetType(wxBitmapType type) { m_type = type; }
113 void SetMimeType(const wxString& type) { m_mime = type; }
114 const wxString& GetName() const { return m_name; }
115 const wxString& GetExtension() const { return m_extension; }
116 const wxArrayString& GetAltExtensions() const { return m_altExtensions; }
117 wxBitmapType GetType() const { return m_type; }
118 const wxString& GetMimeType() const { return m_mime; }
119
120 #if WXWIN_COMPATIBILITY_2_8
121 wxDEPRECATED(
122 void SetType(long type) { SetType((wxBitmapType)type); }
123 )
124 #endif // WXWIN_COMPATIBILITY_2_8
125
126 protected:
127 #if wxUSE_STREAMS
128 virtual bool DoCanRead( wxInputStream& stream ) = 0;
129
130 // save the stream position, call DoCanRead() and restore the position
131 bool CallDoCanRead(wxInputStream& stream);
132 #endif // wxUSE_STREAMS
133
134 // helper for the derived classes SaveFile() implementations: returns the
135 // values of x- and y-resolution options specified as the image options if
136 // any
137 static wxImageResolution
138 GetResolutionFromOptions(const wxImage& image, int *x, int *y);
139
140
141 wxString m_name;
142 wxString m_extension;
143 wxArrayString m_altExtensions;
144 wxString m_mime;
145 wxBitmapType m_type;
146
147 private:
148 DECLARE_CLASS(wxImageHandler)
149 };
150
151 //-----------------------------------------------------------------------------
152 // wxImageHistogram
153 //-----------------------------------------------------------------------------
154
155 class WXDLLIMPEXP_CORE wxImageHistogramEntry
156 {
157 public:
158 wxImageHistogramEntry() { index = value = 0; }
159 unsigned long index;
160 unsigned long value;
161 };
162
163 WX_DECLARE_EXPORTED_HASH_MAP(unsigned long, wxImageHistogramEntry,
164 wxIntegerHash, wxIntegerEqual,
165 wxImageHistogramBase);
166
167 class WXDLLIMPEXP_CORE wxImageHistogram : public wxImageHistogramBase
168 {
169 public:
170 wxImageHistogram() : wxImageHistogramBase(256) { }
171
172 // get the key in the histogram for the given RGB values
173 static unsigned long MakeKey(unsigned char r,
174 unsigned char g,
175 unsigned char b)
176 {
177 return (r << 16) | (g << 8) | b;
178 }
179
180 // find first colour that is not used in the image and has higher
181 // RGB values than RGB(startR, startG, startB)
182 //
183 // returns true and puts this colour in r, g, b (each of which may be NULL)
184 // on success or returns false if there are no more free colours
185 bool FindFirstUnusedColour(unsigned char *r,
186 unsigned char *g,
187 unsigned char *b,
188 unsigned char startR = 1,
189 unsigned char startG = 0,
190 unsigned char startB = 0 ) const;
191 };
192
193 //-----------------------------------------------------------------------------
194 // wxImage
195 //-----------------------------------------------------------------------------
196
197 class WXDLLIMPEXP_CORE wxImage: public wxObject
198 {
199 public:
200 // red, green and blue are 8 bit unsigned integers in the range of 0..255
201 // We use the identifier RGBValue instead of RGB, since RGB is #defined
202 class RGBValue
203 {
204 public:
205 RGBValue(unsigned char r=0, unsigned char g=0, unsigned char b=0)
206 : red(r), green(g), blue(b) {}
207 unsigned char red;
208 unsigned char green;
209 unsigned char blue;
210 };
211
212 // hue, saturation and value are doubles in the range 0.0..1.0
213 class HSVValue
214 {
215 public:
216 HSVValue(double h=0.0, double s=0.0, double v=0.0)
217 : hue(h), saturation(s), value(v) {}
218 double hue;
219 double saturation;
220 double value;
221 };
222
223 wxImage() {}
224 wxImage( int width, int height, bool clear = true )
225 { Create( width, height, clear ); }
226 wxImage( int width, int height, unsigned char* data, bool static_data = false )
227 { Create( width, height, data, static_data ); }
228 wxImage( int width, int height, unsigned char* data, unsigned char* alpha, bool static_data = false )
229 { Create( width, height, data, alpha, static_data ); }
230
231 // ctor variants using wxSize:
232 wxImage( const wxSize& sz, bool clear = true )
233 { Create( sz, clear ); }
234 wxImage( const wxSize& sz, unsigned char* data, bool static_data = false )
235 { Create( sz, data, static_data ); }
236 wxImage( const wxSize& sz, unsigned char* data, unsigned char* alpha, bool static_data = false )
237 { Create( sz, data, alpha, static_data ); }
238
239 wxImage( const wxString& name, wxBitmapType type = wxBITMAP_TYPE_ANY, int index = -1 )
240 { LoadFile( name, type, index ); }
241 wxImage( const wxString& name, const wxString& mimetype, int index = -1 )
242 { LoadFile( name, mimetype, index ); }
243 wxImage( const char* const* xpmData )
244 { Create(xpmData); }
245
246 #if wxUSE_STREAMS
247 wxImage( wxInputStream& stream, wxBitmapType type = wxBITMAP_TYPE_ANY, int index = -1 )
248 { LoadFile( stream, type, index ); }
249 wxImage( wxInputStream& stream, const wxString& mimetype, int index = -1 )
250 { LoadFile( stream, mimetype, index ); }
251 #endif // wxUSE_STREAMS
252
253 bool Create( const char* const* xpmData );
254 #ifdef __BORLANDC__
255 // needed for Borland 5.5
256 wxImage( char** xpmData ) { Create(const_cast<const char* const*>(xpmData)); }
257 bool Create( char** xpmData ) { return Create(const_cast<const char* const*>(xpmData)); }
258 #endif
259
260 bool Create( int width, int height, bool clear = true );
261 bool Create( int width, int height, unsigned char* data, bool static_data = false );
262 bool Create( int width, int height, unsigned char* data, unsigned char* alpha, bool static_data = false );
263
264 // Create() variants using wxSize:
265 bool Create( const wxSize& sz, bool clear = true )
266 { return Create(sz.GetWidth(), sz.GetHeight(), clear); }
267 bool Create( const wxSize& sz, unsigned char* data, bool static_data = false )
268 { return Create(sz.GetWidth(), sz.GetHeight(), data, static_data); }
269 bool Create( const wxSize& sz, unsigned char* data, unsigned char* alpha, bool static_data = false )
270 { return Create(sz.GetWidth(), sz.GetHeight(), data, alpha, static_data); }
271
272 void Destroy();
273
274 // initialize the image data with zeroes
275 void Clear(unsigned char value = 0);
276
277 // creates an identical copy of the image (the = operator
278 // just raises the ref count)
279 wxImage Copy() const;
280
281 // return the new image with size width*height
282 wxImage GetSubImage( const wxRect& rect) const;
283
284 // Paste the image or part of this image into an image of the given size at the pos
285 // any newly exposed areas will be filled with the rgb colour
286 // by default if r = g = b = -1 then fill with this image's mask colour or find and
287 // set a suitable mask colour
288 wxImage Size( const wxSize& size, const wxPoint& pos,
289 int r = -1, int g = -1, int b = -1 ) const;
290
291 // pastes image into this instance and takes care of
292 // the mask colour and out of bounds problems
293 void Paste( const wxImage &image, int x, int y );
294
295 // return the new image with size width*height
296 wxImage Scale( int width, int height, int quality = wxIMAGE_QUALITY_NORMAL ) const;
297
298 // box averager and bicubic filters for up/down sampling
299 wxImage ResampleBox(int width, int height) const;
300 wxImage ResampleBicubic(int width, int height) const;
301
302 // blur the image according to the specified pixel radius
303 wxImage Blur(int radius) const;
304 wxImage BlurHorizontal(int radius) const;
305 wxImage BlurVertical(int radius) const;
306
307 wxImage ShrinkBy( int xFactor , int yFactor ) const ;
308
309 // rescales the image in place
310 wxImage& Rescale( int width, int height, int quality = wxIMAGE_QUALITY_NORMAL ) { return *this = Scale(width, height, quality); }
311
312 // resizes the image in place
313 wxImage& Resize( const wxSize& size, const wxPoint& pos,
314 int r = -1, int g = -1, int b = -1 ) { return *this = Size(size, pos, r, g, b); }
315
316 // Rotates the image about the given point, 'angle' radians.
317 // Returns the rotated image, leaving this image intact.
318 wxImage Rotate(double angle, const wxPoint & centre_of_rotation,
319 bool interpolating = true, wxPoint * offset_after_rotation = NULL) const;
320
321 wxImage Rotate90( bool clockwise = true ) const;
322 wxImage Mirror( bool horizontally = true ) const;
323
324 // replace one colour with another
325 void Replace( unsigned char r1, unsigned char g1, unsigned char b1,
326 unsigned char r2, unsigned char g2, unsigned char b2 );
327
328 // Convert to greyscale image. Uses the luminance component (Y) of the image.
329 // The luma value (YUV) is calculated using (R * lr) + (G * lg) + (B * lb), defaults to ITU-T BT.601
330 wxImage ConvertToGreyscale( double lr = 0.299, double lg = 0.587, double lb = 0.114 ) const;
331
332 // convert to monochrome image (<r,g,b> will be replaced by white,
333 // everything else by black)
334 wxImage ConvertToMono( unsigned char r, unsigned char g, unsigned char b ) const;
335
336 // these routines are slow but safe
337 void SetRGB( int x, int y, unsigned char r, unsigned char g, unsigned char b );
338 void SetRGB( const wxRect& rect, unsigned char r, unsigned char g, unsigned char b );
339 unsigned char GetRed( int x, int y ) const;
340 unsigned char GetGreen( int x, int y ) const;
341 unsigned char GetBlue( int x, int y ) const;
342
343 void SetAlpha(int x, int y, unsigned char alpha);
344 unsigned char GetAlpha(int x, int y) const;
345
346 // find first colour that is not used in the image and has higher
347 // RGB values than <startR,startG,startB>
348 bool FindFirstUnusedColour( unsigned char *r, unsigned char *g, unsigned char *b,
349 unsigned char startR = 1, unsigned char startG = 0,
350 unsigned char startB = 0 ) const;
351 // Set image's mask to the area of 'mask' that has <r,g,b> colour
352 bool SetMaskFromImage(const wxImage & mask,
353 unsigned char mr, unsigned char mg, unsigned char mb);
354
355 // converts image's alpha channel to mask (choosing mask colour
356 // automatically or using the specified colour for the mask), if it has
357 // any, does nothing otherwise:
358 bool ConvertAlphaToMask(unsigned char threshold = wxIMAGE_ALPHA_THRESHOLD);
359 void ConvertAlphaToMask(unsigned char mr, unsigned char mg, unsigned char mb,
360 unsigned char threshold = wxIMAGE_ALPHA_THRESHOLD);
361
362
363 // This method converts an image where the original alpha
364 // information is only available as a shades of a colour
365 // (actually shades of grey) typically when you draw anti-
366 // aliased text into a bitmap. The DC drawinf routines
367 // draw grey values on the black background although they
368 // actually mean to draw white with differnt alpha values.
369 // This method reverses it, assuming a black (!) background
370 // and white text (actually only the red channel is read).
371 // The method will then fill up the whole image with the
372 // colour given.
373 bool ConvertColourToAlpha( unsigned char r, unsigned char g, unsigned char b );
374
375 static bool CanRead( const wxString& name );
376 static int GetImageCount( const wxString& name, wxBitmapType type = wxBITMAP_TYPE_ANY );
377 virtual bool LoadFile( const wxString& name, wxBitmapType type = wxBITMAP_TYPE_ANY, int index = -1 );
378 virtual bool LoadFile( const wxString& name, const wxString& mimetype, int index = -1 );
379
380 #if wxUSE_STREAMS
381 static bool CanRead( wxInputStream& stream );
382 static int GetImageCount( wxInputStream& stream, wxBitmapType type = wxBITMAP_TYPE_ANY );
383 virtual bool LoadFile( wxInputStream& stream, wxBitmapType type = wxBITMAP_TYPE_ANY, int index = -1 );
384 virtual bool LoadFile( wxInputStream& stream, const wxString& mimetype, int index = -1 );
385 #endif
386
387 virtual bool SaveFile( const wxString& name ) const;
388 virtual bool SaveFile( const wxString& name, wxBitmapType type ) const;
389 virtual bool SaveFile( const wxString& name, const wxString& mimetype ) const;
390
391 #if wxUSE_STREAMS
392 virtual bool SaveFile( wxOutputStream& stream, wxBitmapType type ) const;
393 virtual bool SaveFile( wxOutputStream& stream, const wxString& mimetype ) const;
394 #endif
395
396 bool Ok() const { return IsOk(); }
397 bool IsOk() const;
398 int GetWidth() const;
399 int GetHeight() const;
400
401 wxSize GetSize() const
402 { return wxSize(GetWidth(), GetHeight()); }
403
404 // Gets the type of image found by LoadFile or specified with SaveFile
405 wxBitmapType GetType() const;
406
407 // Set the image type, this is normally only called if the image is being
408 // created from data in the given format but not using LoadFile() (e.g.
409 // wxGIFDecoder uses this)
410 void SetType(wxBitmapType type);
411
412 // these functions provide fastest access to wxImage data but should be
413 // used carefully as no checks are done
414 unsigned char *GetData() const;
415 void SetData( unsigned char *data, bool static_data=false );
416 void SetData( unsigned char *data, int new_width, int new_height, bool static_data=false );
417
418 unsigned char *GetAlpha() const; // may return NULL!
419 bool HasAlpha() const { return GetAlpha() != NULL; }
420 void SetAlpha(unsigned char *alpha = NULL, bool static_data=false);
421 void InitAlpha();
422
423 // return true if this pixel is masked or has alpha less than specified
424 // threshold
425 bool IsTransparent(int x, int y,
426 unsigned char threshold = wxIMAGE_ALPHA_THRESHOLD) const;
427
428 // Mask functions
429 void SetMaskColour( unsigned char r, unsigned char g, unsigned char b );
430 // Get the current mask colour or find a suitable colour
431 // returns true if using current mask colour
432 bool GetOrFindMaskColour( unsigned char *r, unsigned char *g, unsigned char *b ) const;
433 unsigned char GetMaskRed() const;
434 unsigned char GetMaskGreen() const;
435 unsigned char GetMaskBlue() const;
436 void SetMask( bool mask = true );
437 bool HasMask() const;
438
439 #if wxUSE_PALETTE
440 // Palette functions
441 bool HasPalette() const;
442 const wxPalette& GetPalette() const;
443 void SetPalette(const wxPalette& palette);
444 #endif // wxUSE_PALETTE
445
446 // Option functions (arbitrary name/value mapping)
447 void SetOption(const wxString& name, const wxString& value);
448 void SetOption(const wxString& name, int value);
449 wxString GetOption(const wxString& name) const;
450 int GetOptionInt(const wxString& name) const;
451 bool HasOption(const wxString& name) const;
452
453 unsigned long CountColours( unsigned long stopafter = (unsigned long) -1 ) const;
454
455 // Computes the histogram of the image and fills a hash table, indexed
456 // with integer keys built as 0xRRGGBB, containing wxImageHistogramEntry
457 // objects. Each of them contains an 'index' (useful to build a palette
458 // with the image colours) and a 'value', which is the number of pixels
459 // in the image with that colour.
460 // Returned value: # of entries in the histogram
461 unsigned long ComputeHistogram( wxImageHistogram &h ) const;
462
463 // Rotates the hue of each pixel of the image. angle is a double in the range
464 // -1.0..1.0 where -1.0 is -360 degrees and 1.0 is 360 degrees
465 void RotateHue(double angle);
466
467 static wxList& GetHandlers() { return sm_handlers; }
468 static void AddHandler( wxImageHandler *handler );
469 static void InsertHandler( wxImageHandler *handler );
470 static bool RemoveHandler( const wxString& name );
471 static wxImageHandler *FindHandler( const wxString& name );
472 static wxImageHandler *FindHandler( const wxString& extension, wxBitmapType imageType );
473 static wxImageHandler *FindHandler( wxBitmapType imageType );
474
475 static wxImageHandler *FindHandlerMime( const wxString& mimetype );
476
477 static wxString GetImageExtWildcard();
478
479 static void CleanUpHandlers();
480 static void InitStandardHandlers();
481
482 static HSVValue RGBtoHSV(const RGBValue& rgb);
483 static RGBValue HSVtoRGB(const HSVValue& hsv);
484
485 #if WXWIN_COMPATIBILITY_2_8
486 wxDEPRECATED_CONSTRUCTOR(
487 wxImage(const wxString& name, long type, int index = -1)
488 {
489 LoadFile(name, (wxBitmapType)type, index);
490 }
491 )
492
493 #if wxUSE_STREAMS
494 wxDEPRECATED_CONSTRUCTOR(
495 wxImage(wxInputStream& stream, long type, int index = -1)
496 {
497 LoadFile(stream, (wxBitmapType)type, index);
498 }
499 )
500
501 wxDEPRECATED(
502 bool LoadFile(wxInputStream& stream, long type, int index = -1)
503 {
504 return LoadFile(stream, (wxBitmapType)type, index);
505 }
506 )
507
508 wxDEPRECATED(
509 bool SaveFile(wxOutputStream& stream, long type) const
510 {
511 return SaveFile(stream, (wxBitmapType)type);
512 }
513 )
514 #endif // wxUSE_STREAMS
515
516 wxDEPRECATED(
517 bool LoadFile(const wxString& name, long type, int index = -1)
518 {
519 return LoadFile(name, (wxBitmapType)type, index);
520 }
521 )
522
523 wxDEPRECATED(
524 bool SaveFile(const wxString& name, long type) const
525 {
526 return SaveFile(name, (wxBitmapType)type);
527 }
528 )
529
530 wxDEPRECATED(
531 static wxImageHandler *FindHandler(const wxString& ext, long type)
532 {
533 return FindHandler(ext, (wxBitmapType)type);
534 }
535 )
536
537 wxDEPRECATED(
538 static wxImageHandler *FindHandler(long imageType)
539 {
540 return FindHandler((wxBitmapType)imageType);
541 }
542 )
543 #endif // WXWIN_COMPATIBILITY_2_8
544
545 protected:
546 static wxList sm_handlers;
547
548 // return the index of the point with the given coordinates or -1 if the
549 // image is invalid of the coordinates are out of range
550 //
551 // note that index must be multiplied by 3 when using it with RGB array
552 long XYToIndex(int x, int y) const;
553
554 virtual wxObjectRefData* CreateRefData() const;
555 virtual wxObjectRefData* CloneRefData(const wxObjectRefData* data) const;
556
557 private:
558 friend class WXDLLIMPEXP_FWD_CORE wxImageHandler;
559
560 #if wxUSE_STREAMS
561 // read the image from the specified stream updating image type if
562 // successful
563 bool DoLoad(wxImageHandler& handler, wxInputStream& stream, int index);
564
565 // write the image to the specified stream and also update the image type
566 // if successful
567 bool DoSave(wxImageHandler& handler, wxOutputStream& stream) const;
568 #endif // wxUSE_STREAMS
569
570 DECLARE_DYNAMIC_CLASS(wxImage)
571 };
572
573
574 extern void WXDLLIMPEXP_CORE wxInitAllImageHandlers();
575
576 extern WXDLLIMPEXP_DATA_CORE(wxImage) wxNullImage;
577
578 //-----------------------------------------------------------------------------
579 // wxImage handlers
580 //-----------------------------------------------------------------------------
581
582 #include "wx/imagbmp.h"
583 #include "wx/imagpng.h"
584 #include "wx/imaggif.h"
585 #include "wx/imagpcx.h"
586 #include "wx/imagjpeg.h"
587 #include "wx/imagtga.h"
588 #include "wx/imagtiff.h"
589 #include "wx/imagpnm.h"
590 #include "wx/imagxpm.h"
591 #include "wx/imagiff.h"
592
593 #endif // wxUSE_IMAGE
594
595 #endif
596 // _WX_IMAGE_H_