blob: 2b69f2bc3265ccfbdb76b51cf652cd03843b402a [file] [log] [blame]
croachrose48ede9b2006-11-08 19:24:48 +00001/* include/graphics/SkBitmap.h
2**
3** Copyright 2006, Google Inc.
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
croachrose0f87cd82006-09-20 15:47:42 +000018#ifndef SkBitmap_DEFINED
19#define SkBitmap_DEFINED
20
21#include "SkColor.h"
22#include "SkRefCnt.h"
23
24// Android - we need to run as an embedded product, not X11
25//#ifdef SK_BUILD_FOR_UNIX
26//#include <X11/Xlib.h>
27//#endif
28
29
30class SkColorTable;
31
croachrose48ede9b2006-11-08 19:24:48 +000032/** \class SkBitmap
croachrose0f87cd82006-09-20 15:47:42 +000033
croachrose48ede9b2006-11-08 19:24:48 +000034 The SkBitmap class specifies a raster bitmap. A bitmap has an integer width
35 and height, and a format (config), and a pointer to the actual pixels.
36 Bitmaps can be drawn into a SkCanvas, but they are also used to specify the target
37 of a SkCanvas' drawing operations.
croachrose0f87cd82006-09-20 15:47:42 +000038*/
39class SkBitmap {
40public:
croachrose48ede9b2006-11-08 19:24:48 +000041 enum Config {
42 kNo_Config, //!< bitmap has not been configured
43 kA1_Config, //!< 1-bit per pixel, (0 is transparent, 1 is opaque)
44 kA8_Config, //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque)
45 kIndex8_Config, //!< 8-bits per pixel, using SkColorTable to specify the colors
46 kRGB_565_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
47 kARGB_8888_Config, //!< 32-bits per pixel, (see SkColorPriv.h for packing)
croachrose0f87cd82006-09-20 15:47:42 +000048
croachrose48ede9b2006-11-08 19:24:48 +000049 kConfigCount
50 };
croachrose0f87cd82006-09-20 15:47:42 +000051
croachrose48ede9b2006-11-08 19:24:48 +000052 /** Default construct creates a bitmap with zero width and height, and no pixels.
53 Its config is set to kNo_Config.
54 */
55 SkBitmap();
56 /** Constructor initializes the new bitmap by copying the src bitmap. All fields are copied,
57 but ownership of the pixels remains with the src bitmap.
58 */
croachrose0f87cd82006-09-20 15:47:42 +000059 // This method is not exported to java.
croachrose48ede9b2006-11-08 19:24:48 +000060 SkBitmap(const SkBitmap& src);
61 /** Destructor that, if getOwnsPixels() returns true, will delete the pixel's memory.
62 */
63 ~SkBitmap();
croachrose0f87cd82006-09-20 15:47:42 +000064
croachrose48ede9b2006-11-08 19:24:48 +000065 /** Copies the src bitmap into this bitmap. Ownership of the src bitmap's pixels remains
66 with the src bitmap.
67 */
68 SkBitmap& operator=(const SkBitmap& src);
69 /** Swap the fields of the two bitmaps. This routine is guaranteed to never fail or throw.
70 */
croachrose0f87cd82006-09-20 15:47:42 +000071 // This method is not exported to java.
croachrose48ede9b2006-11-08 19:24:48 +000072 void swap(SkBitmap& other);
croachrose0f87cd82006-09-20 15:47:42 +000073
croachrose48ede9b2006-11-08 19:24:48 +000074 /** Return the config for the bitmap.
75 */
76 Config getConfig() const { return (Config)fConfig; }
77 /** Return the bitmap's width, in pixels.
78 */
79 int width() const { return fWidth; }
80 /** Return the bitmap's height, in pixels.
81 */
82 int height() const { return fHeight; }
83 /** Return the number of bytes between subsequent rows of the bitmap.
84 */
85 int rowBytes() const { return fRowBytes; }
86 /** Return the address of the pixels for this SkBitmap. This can be set either with
87 setPixels(), where the caller owns the buffer, or with allocPixels() or resizeAlloc(),
88 which marks the pixel memory to be owned by the SkBitmap (e.g. will be freed automatically
89 when the bitmap is destroyed).
90 */
91 void* getPixels() const { return fPixels; }
92 /** Return the byte size of the pixels, based on the height and rowBytes
93 */
94 size_t getSize() const { return fHeight * fRowBytes; }
croachrose0f87cd82006-09-20 15:47:42 +000095
96 /** Returns true if the bitmap is opaque (has no translucent/transparent pixels).
97 */
98 bool isOpaque() const;
99 /** Specify if this bitmap's pixels are all opaque or not. Is only meaningful for configs
100 that support per-pixel alpha (RGB32, A1, A8).
101 */
102 void setIsOpaque(bool);
103
croachrose48ede9b2006-11-08 19:24:48 +0000104 /** Reset the bitmap to its initial state (see default constructor). If getOwnsPixels() returned
105 true, then the memory for the pixels is freed.
106 */
107 void reset();
108 /** Set the bitmap's config and dimensions. If rowBytes is 0, then an appropriate value
109 is computed based on the bitmap's config and width. If getOwnsPixels() returned true,
110 then the pixel's memory is freed.
111 */
112 void setConfig(Config, U16CPU width, U16CPU height, U16CPU rowBytes = 0);
113 /** Use this to assign a new pixel address for an existing bitmap. If getOwnsPixels() returned
114 true, then the previous pixel's memory is freed. The new address is "owned" by the called,
115 and getOwnsPixels() will now return false. This method is not exported to java.
116 */
117 void setPixels(void* p);
118 /** If this is called, then the bitmap will dynamically allocate memory for its pixels
119 based on rowBytes and height. The SkBitmap will remember that it allocated
120 this, and will automatically free it as needed, thus getOwnsPixels() will now return true.
121 */
122 void allocPixels();
123 /** Realloc the memory for the pixels based on the specified width and height. This
124 keeps the old value for config, and computes a rowBytes based on the config and the width.
125 This is similar, but more efficient than calling setConfig() followed by allocPixels().
126 */
croachrose0f87cd82006-09-20 15:47:42 +0000127// not implemented
croachrose48ede9b2006-11-08 19:24:48 +0000128// void resizeAlloc(U16CPU width, U16CPU height);
croachrose0f87cd82006-09-20 15:47:42 +0000129
croachrose48ede9b2006-11-08 19:24:48 +0000130 /** Returns true if the current pixels have been allocated via allocPixels()
131 or resizeAlloc(). This method is not exported to java.
132 */
133 bool getOwnsPixels() const;
134 /** Call this to explicitly change the ownership rule for the pixels. This may be called
135 after one bitmap is copied into another, to specify which bitmap should handle freeing
136 the memory. This method is not exported to java.
137 */
138 void setOwnsPixels(bool ownsPixels);
croachrose0f87cd82006-09-20 15:47:42 +0000139
croachrose48ede9b2006-11-08 19:24:48 +0000140 /** Get the bitmap's colortable object.
141
142 Return the bitmap's colortable (if any). Does not affect the colortable's
143 reference count.
144 */
145 SkColorTable* getColorTable() const { return fColorTable; }
146 /** Assign ctable to be the colortable for the bitmap, replacing any existing reference.
147 The reference count of ctable (if it is not nil) is incremented, and any existing
148 reference has its reference count decremented. NOTE: colortable's may be assigned
149 to any bitmap, but are only interpreted for kIndex8_Config bitmaps, where they
150 are required.
151 @return the ctable argument
152 */
153 SkColorTable* setColorTable(SkColorTable* ctable);
croachrose0f87cd82006-09-20 15:47:42 +0000154
croachrose48ede9b2006-11-08 19:24:48 +0000155 /** Initialize the bitmap's pixels with the specified color+alpha, automatically converting into the correct format
156 for the bitmap's config. If the config is kRGB_565_Config, then the alpha value is ignored.
157 If the config is kA8_Config, then the r,g,b parameters are ignored.
158 */
159 void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
160 /** Initialize the bitmap's pixels with the specified color+alpha, automatically converting into the correct format
161 for the bitmap's config. If the config is kRGB_565_Config, then the alpha value is presumed
162 to be 0xFF. If the config is kA8_Config, then the r,g,b parameters are ignored and the
163 pixels are all set to 0xFF.
164 */
165 void eraseRGB(U8CPU r, U8CPU g, U8CPU b)
166 {
167 this->eraseARGB(0xFF, r, g, b);
168 }
169 /** Initialize the bitmap's pixels with the specified color, automatically converting into the correct format
170 for the bitmap's config. If the config is kRGB_565_Config, then the color's alpha value is presumed
171 to be 0xFF. If the config is kA8_Config, then only the color's alpha value is used.
172 */
173 void eraseColor(SkColor c)
174 {
175 this->eraseARGB(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c), SkColorGetB(c));
176 }
croachrose0f87cd82006-09-20 15:47:42 +0000177
croachrose48ede9b2006-11-08 19:24:48 +0000178 /** Return a bitmap that is a quarter the size of this one
179 */
180 bool quarterSizeFiltered(SkBitmap* dst) const;
181
182 /** Returns the address of the pixel specified by x,y.
183 Asserts that x,y are in range, and that the bitmap's config is either kARGB_8888_Config.
184 */
croachrose0f87cd82006-09-20 15:47:42 +0000185 // This method is not exported to java.
croachrose48ede9b2006-11-08 19:24:48 +0000186 inline uint32_t* getAddr32(int x, int y) const;
187 /** Returns the address of the pixel specified by x,y.
188 Asserts that x,y are in range, and that the bitmap's config is kRGB_565_Config.
189 */
croachrose0f87cd82006-09-20 15:47:42 +0000190 // This method is not exported to java.
croachrose48ede9b2006-11-08 19:24:48 +0000191 inline uint16_t* getAddr16(int x, int y) const;
192 /** Returns the address of the pixel specified by x,y.
193 Asserts that x,y are in range, and that the bitmap's config is either kA8_Config or kIndex8_Config.
194 */
croachrose0f87cd82006-09-20 15:47:42 +0000195 // This method is not exported to java.
croachrose48ede9b2006-11-08 19:24:48 +0000196 inline uint8_t* getAddr8(int x, int y) const;
197 /** Returns the color corresponding to the pixel specified by x,y.
198 Asserts that x,y are in range, and that the bitmap's config is kIndex8_Config.
199 */
croachrose0f87cd82006-09-20 15:47:42 +0000200 // This method is not exported to java.
croachrose48ede9b2006-11-08 19:24:48 +0000201 inline SkPMColor getIndex8Color(int x, int y) const;
202 /** Returns the address of the byte containing the pixel specified by x,y.
203 Asserts that x,y are in range, and that the bitmap's config is kA1_Config.
204 */
croachrose0f87cd82006-09-20 15:47:42 +0000205 // This method is not exported to java.
croachrose48ede9b2006-11-08 19:24:48 +0000206 inline uint8_t* getAddr1(int x, int y) const;
croachrose0f87cd82006-09-20 15:47:42 +0000207
croachrose48ede9b2006-11-08 19:24:48 +0000208 // OS-specific helpers
croachrose0f87cd82006-09-20 15:47:42 +0000209#ifndef SK_USE_WXWIDGETS
210#ifdef SK_BUILD_FOR_WIN
croachrose48ede9b2006-11-08 19:24:48 +0000211 /** On Windows and PocketPC builds, this will draw the SkBitmap onto the
212 specified HDC
213 */
214 void drawToHDC(HDC, int left, int top) const;
croachrose0f87cd82006-09-20 15:47:42 +0000215#elif defined(SK_BUILD_FOR_MAC)
croachrose48ede9b2006-11-08 19:24:48 +0000216 /** On Mac OS X and Carbon builds, this will draw the SkBitmap onto the
217 specified WindowRef
218 */
219 void drawToPort(WindowRef) const;
croachrose0f87cd82006-09-20 15:47:42 +0000220#endif
221#endif
222
croachrose48ede9b2006-11-08 19:24:48 +0000223 void buildMipMap(bool forceRebuild);
224 unsigned countMipLevels() const;
croachrose0f87cd82006-09-20 15:47:42 +0000225
226private:
croachrose48ede9b2006-11-08 19:24:48 +0000227 SkColorTable* fColorTable; // only meaningful for kIndex8
croachrose0f87cd82006-09-20 15:47:42 +0000228
229#ifdef SK_SUPPORT_MIPMAP
croachrose48ede9b2006-11-08 19:24:48 +0000230 struct MipLevel {
231 void* fPixels;
232 uint16_t fWidth, fHeight, fRowBytes;
233 uint8_t fConfig, fShift;
234 };
235 enum {
236 kMaxMipLevels = 5
237 };
238 struct MipMap {
239 MipLevel fLevel[kMaxMipLevels];
240 };
241 MipMap* fMipMap;
croachrose0f87cd82006-09-20 15:47:42 +0000242#endif
243
croachrose48ede9b2006-11-08 19:24:48 +0000244 enum Flags {
245 kWeOwnThePixels_Flag = 0x01,
246 kWeOwnTheMipMap_Flag = 0x02,
croachrose0f87cd82006-09-20 15:47:42 +0000247 kImageIsOpaque_Flag = 0x04
croachrose48ede9b2006-11-08 19:24:48 +0000248 };
croachrose0f87cd82006-09-20 15:47:42 +0000249
croachrose48ede9b2006-11-08 19:24:48 +0000250 void* fPixels;
251 uint16_t fWidth, fHeight, fRowBytes;
252 uint8_t fConfig;
253 uint8_t fFlags;
croachrose0f87cd82006-09-20 15:47:42 +0000254
croachrose48ede9b2006-11-08 19:24:48 +0000255#ifdef SK_SUPPORT_MIPMAP
256 const MipLevel* getMipLevel(unsigned level) const;
257#endif
258 void freePixels();
croachrose0f87cd82006-09-20 15:47:42 +0000259
260 friend class SkBitmapShader;
261};
262
croachrose48ede9b2006-11-08 19:24:48 +0000263/** \class SkColorTable
croachrose0f87cd82006-09-20 15:47:42 +0000264
croachrose48ede9b2006-11-08 19:24:48 +0000265 SkColorTable holds an array SkPMColors (premultiplied 32-bit colors) used by
266 8-bit bitmaps, where the bitmap bytes are interpreted as indices into the colortable.
croachrose0f87cd82006-09-20 15:47:42 +0000267*/
268class SkColorTable : public SkRefCnt {
269public:
croachrose48ede9b2006-11-08 19:24:48 +0000270 /** Constructs an empty color table (zero colors).
271 */
272 SkColorTable();
273 virtual ~SkColorTable();
croachrose0f87cd82006-09-20 15:47:42 +0000274
croachrose48ede9b2006-11-08 19:24:48 +0000275 enum Flags {
276 kColorsAreOpaque_Flag = 0x01 //!< if set, all of the colors in the table are opaque (alpha==0xFF)
277 };
278 /** Returns the flag bits for the color table. These can be changed with setFlags().
279 */
280 unsigned getFlags() const { return fFlags; }
281 /** Set the flags for the color table. See the Flags enum for possible values.
282 */
283 void setFlags(unsigned flags);
croachrose0f87cd82006-09-20 15:47:42 +0000284
croachrose48ede9b2006-11-08 19:24:48 +0000285 /** Returns the number of colors in the table.
286 */
287 int count() const { return fCount; }
croachrose0f87cd82006-09-20 15:47:42 +0000288
croachrose48ede9b2006-11-08 19:24:48 +0000289 /** Returns the specified color from the table. In the debug build, this asserts that
290 the index is in range (0 <= index < count).
291 */
292 SkPMColor operator[](int index) const
293 {
294 SkASSERT(fColors != nil && (unsigned)index < fCount);
295 return fColors[index];
296 }
croachrose0f87cd82006-09-20 15:47:42 +0000297
croachrose48ede9b2006-11-08 19:24:48 +0000298 /** Specify the number of colors in the color table. This does not initialize the colors
299 to any value, just allocates memory for them. To initialize the values, either call
300 setColors(array, count), or follow setCount(count) with a call to
301 lockColors()/{set the values}/unlockColors(true).
302 */
303 void setColors(int count) { this->setColors(nil, count); }
304 void setColors(const SkPMColor[], int count);
croachrose0f87cd82006-09-20 15:47:42 +0000305
croachrose48ede9b2006-11-08 19:24:48 +0000306 /** Return the array of colors for reading and/or writing. This must be
307 balanced by a call to unlockColors(changed?), telling the colortable if
308 the colors were changed during the lock.
309 */
310 SkPMColor* lockColors()
311 {
312 SkDEBUGCODE(fColorLockCount += 1;)
313 return fColors;
314 }
315 /** Balancing call to lockColors(). If the colors have been changed, pass true.
316 */
317 void unlockColors(bool changed)
318 {
319 SkASSERT(fColorLockCount != 0);
320 SkDEBUGCODE(fColorLockCount -= 1;)
321 }
croachrose0f87cd82006-09-20 15:47:42 +0000322
croachrose48ede9b2006-11-08 19:24:48 +0000323 /** Similar to lockColors(), lock16BitCache() returns the array of
324 RGB16 colors that mirror the 32bit colors. However, this function
325 will return nil if kColorsAreOpaque_Flag is not set.
326 Also, unlike lockColors(), the returned array here cannot be modified.
327 */
328 const uint16_t* lock16BitCache();
329 /** Balancing call to lock16BitCache().
330 */
331 void unlock16BitCache()
332 {
333 SkASSERT(f16BitCacheLockCount > 0);
334 SkDEBUGCODE(f16BitCacheLockCount -= 1);
335 }
croachrose0f87cd82006-09-20 15:47:42 +0000336
337private:
croachrose48ede9b2006-11-08 19:24:48 +0000338 SkPMColor* fColors;
339 uint16_t* f16BitCache;
340 uint16_t fCount;
341 uint8_t fFlags;
342 SkDEBUGCODE(int fColorLockCount;)
343 SkDEBUGCODE(int f16BitCacheLockCount;)
croachrose0f87cd82006-09-20 15:47:42 +0000344
croachrose48ede9b2006-11-08 19:24:48 +0000345 void inval16BitCache();
croachrose0f87cd82006-09-20 15:47:42 +0000346};
347
348//////////////////////////////////////////////////////////////////////////////////
349
350inline uint32_t* SkBitmap::getAddr32(int x, int y) const
351{
croachrose48ede9b2006-11-08 19:24:48 +0000352 SkASSERT(fPixels);
353 SkASSERT(fConfig == kARGB_8888_Config);
354 SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
croachrose0f87cd82006-09-20 15:47:42 +0000355
croachrose48ede9b2006-11-08 19:24:48 +0000356 return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2));
croachrose0f87cd82006-09-20 15:47:42 +0000357}
358
359inline uint16_t* SkBitmap::getAddr16(int x, int y) const
360{
croachrose48ede9b2006-11-08 19:24:48 +0000361 SkASSERT(fPixels);
362 SkASSERT(fConfig == kRGB_565_Config);
363 SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
croachrose0f87cd82006-09-20 15:47:42 +0000364
croachrose48ede9b2006-11-08 19:24:48 +0000365 return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1));
croachrose0f87cd82006-09-20 15:47:42 +0000366}
367
368inline uint8_t* SkBitmap::getAddr8(int x, int y) const
369{
croachrose48ede9b2006-11-08 19:24:48 +0000370 SkASSERT(fPixels);
371 SkASSERT(fConfig == kA8_Config || fConfig == kIndex8_Config);
372 SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
373 return (uint8_t*)fPixels + y * fRowBytes + x;
croachrose0f87cd82006-09-20 15:47:42 +0000374}
375
376inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const
377{
croachrose48ede9b2006-11-08 19:24:48 +0000378 SkASSERT(fPixels);
379 SkASSERT(fConfig == kIndex8_Config);
380 SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
381 SkASSERT(fColorTable);
382 return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
croachrose0f87cd82006-09-20 15:47:42 +0000383}
384
385// returns the address of the byte that contains the x coordinate
386inline uint8_t* SkBitmap::getAddr1(int x, int y) const
387{
croachrose48ede9b2006-11-08 19:24:48 +0000388 SkASSERT(fPixels);
389 SkASSERT(fConfig == kA1_Config);
390 SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
391 return (uint8_t*)fPixels + y * fRowBytes + (x >> 3);
croachrose0f87cd82006-09-20 15:47:42 +0000392}
393
394
395#endif
396