blob: 02c8cd9621d8610cd1ad9513df1b3cc8880df333 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkBitmap_DEFINED
18#define SkBitmap_DEFINED
19
20#include "Sk64.h"
21#include "SkColor.h"
22#include "SkPoint.h"
23#include "SkRefCnt.h"
24
25#if defined(SK_BUILD_FOR_MAC)
26#include <carbon/carbon.h>
27#endif
28
29struct SkIRect;
30class SkColorTable;
31class SkPaint;
32class SkPixelRef;
33class SkRegion;
34class SkFlattenableReadBuffer;
35class SkFlattenableWriteBuffer;
36
37/** \class SkBitmap
38
39 The SkBitmap class specifies a raster bitmap. A bitmap has an integer width
40 and height, and a format (config), and a pointer to the actual pixels.
41 Bitmaps can be drawn into a SkCanvas, but they are also used to specify the target
42 of a SkCanvas' drawing operations.
43*/
44class SkBitmap {
45public:
46 class Allocator;
47
48 enum Config {
49 kNo_Config, //!< bitmap has not been configured
50 kA1_Config, //!< 1-bit per pixel, (0 is transparent, 1 is opaque)
51 kA8_Config, //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque)
52 kIndex8_Config, //!< 8-bits per pixel, using SkColorTable to specify the colors
53 kRGB_565_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
54 kARGB_4444_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
55 kARGB_8888_Config, //!< 32-bits per pixel, (see SkColorPriv.h for packing)
56 kRLE_Index8_Config,
57
58 kConfigCount
59 };
60
61 /** Default construct creates a bitmap with zero width and height, and no pixels.
62 Its config is set to kNo_Config.
63 */
64 SkBitmap();
65 /** Constructor initializes the new bitmap by copying the src bitmap. All fields are copied,
66 but ownership of the pixels remains with the src bitmap.
67 */
68 SkBitmap(const SkBitmap& src);
69 /** Decrements our (shared) pixel ownership if needed.
70 */
71 ~SkBitmap();
72
73 /** Copies the src bitmap into this bitmap. Ownership of the src bitmap's pixels remains
74 with the src bitmap.
75 */
76 SkBitmap& operator=(const SkBitmap& src);
77 /** Swap the fields of the two bitmaps. This routine is guaranteed to never fail or throw.
78 */
79 // This method is not exported to java.
80 void swap(SkBitmap& other);
81
82 /** Return true iff the bitmap has empty dimensions.
83 */
84 bool empty() const { return 0 == fWidth || 0 == fHeight; }
85
86 /** Return true iff the bitmap has no pixels nor a pixelref. Note: this can
87 return true even if the dimensions of the bitmap are > 0 (see empty()).
88 */
89 bool isNull() const { return NULL == fPixels && NULL == fPixelRef; }
90
91 /** Return the config for the bitmap.
92 */
93 Config config() const { return (Config)fConfig; }
94 /** DEPRECATED, use config()
95 */
96 Config getConfig() const { return this->config(); }
97 /** Return the bitmap's width, in pixels.
98 */
99 int width() const { return fWidth; }
100 /** Return the bitmap's height, in pixels.
101 */
102 int height() const { return fHeight; }
103 /** Return the number of bytes between subsequent rows of the bitmap.
104 */
105 int rowBytes() const { return fRowBytes; }
106
107 /** Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for
108 2-bytes per pixel configs, 2 for 4-bytes per pixel configs). Return 0
109 for configs that are not at least 1-byte per pixel (e.g. kA1_Config
110 or kNo_Config)
111 */
112 int shiftPerPixel() const { return fBytesPerPixel >> 1; }
113
114 /** Return the number of bytes per pixel based on the config. If the config
115 does not have at least 1 byte per (e.g. kA1_Config) then 0 is returned.
116 */
117 int bytesPerPixel() const { return fBytesPerPixel; }
118
119 /** Return the rowbytes expressed as a number of pixels (like width and
120 height). Note, for 1-byte per pixel configs like kA8_Config, this will
121 return the same as rowBytes(). Is undefined for configs that are less
122 than 1-byte per pixel (e.g. kA1_Config)
123 */
124 int rowBytesAsPixels() const { return fRowBytes >> (fBytesPerPixel >> 1); }
125
126 /** Return the address of the pixels for this SkBitmap.
127 */
128 void* getPixels() const { return fPixels; }
129
130 /** Return the byte size of the pixels, based on the height and rowBytes.
131 Note this truncates the result to 32bits. Call getSize64() to detect
132 if the real size exceeds 32bits.
133 */
134 size_t getSize() const { return fHeight * fRowBytes; }
135
136 /** Return the byte size of the pixels, based on the height and rowBytes.
137 This routine is slightly slower than getSize(), but does not truncate
138 the answer to 32bits.
139 */
140 Sk64 getSize64() const {
141 Sk64 size;
142 size.setMul(fHeight, fRowBytes);
143 return size;
144 }
145
146 /** Returns true if the bitmap is opaque (has no translucent/transparent pixels).
147 */
148 bool isOpaque() const;
149 /** Specify if this bitmap's pixels are all opaque or not. Is only meaningful for configs
150 that support per-pixel alpha (RGB32, A1, A8).
151 */
152 void setIsOpaque(bool);
153
154 /** Reset the bitmap to its initial state (see default constructor). If we are a (shared)
155 owner of the pixels, that ownership is decremented.
156 */
157 void reset();
158
159 /** Given a config and a width, this computes the optimal rowBytes value. This is called automatically
160 if you pass 0 for rowBytes to setConfig().
161 */
162 static int ComputeRowBytes(Config c, int width);
163
164 /** Return the bytes-per-pixel for the specified config. If the config is
165 not at least 1-byte per pixel, return 0, including for kNo_Config.
166 */
167 static int ComputeBytesPerPixel(Config c);
168
169 /** Return the shift-per-pixel for the specified config. If the config is
170 not at least 1-byte per pixel, return 0, including for kNo_Config.
171 */
172 static int ComputeShiftPerPixel(Config c) {
173 return ComputeBytesPerPixel(c) >> 1;
174 }
175
176 static Sk64 ComputeSize64(Config, int width, int height);
177 static size_t ComputeSize(Config, int width, int height);
178
179 /** Set the bitmap's config and dimensions. If rowBytes is 0, then
180 ComputeRowBytes() is called to compute the optimal value. This resets
181 any pixel/colortable ownership, just like reset().
182 */
183 void setConfig(Config, int width, int height, int rowBytes = 0);
184 /** Use this to assign a new pixel address for an existing bitmap. This
185 will automatically release any pixelref previously installed. Only call
186 this if you are handling ownership/lifetime of the pixel memory.
187
188 If the bitmap retains a reference to the colortable (assuming it is
189 not null) it will take care of incrementing the reference count.
190
191 @param pixels Address for the pixels, managed by the caller.
192 @param ctable ColorTable (or null) that matches the specified pixels
193 */
194 void setPixels(void* p, SkColorTable* ctable = NULL);
195
196 /** Use the standard HeapAllocator to create the pixelref that manages the
197 pixel memory. It will be sized based on the current width/height/config.
198 If this is called multiple times, a new pixelref object will be created
199 each time.
200
201 If the bitmap retains a reference to the colortable (assuming it is
202 not null) it will take care of incrementing the reference count.
203
204 @param ctable ColorTable (or null) to use with the pixels that will
205 be allocated. Only used if config == Index8_Config
206 @return true if the allocation succeeds. If not the pixelref field of
207 the bitmap will be unchanged.
208 */
209 bool allocPixels(SkColorTable* ctable = NULL) {
210 return this->allocPixels(NULL, ctable);
211 }
212
213 /** Use the specified Allocator to create the pixelref that manages the
214 pixel memory. It will be sized based on the current width/height/config.
215 If this is called multiple times, a new pixelref object will be created
216 each time.
217
218 If the bitmap retains a reference to the colortable (assuming it is
219 not null) it will take care of incrementing the reference count.
220
221 @param allocator The Allocator to use to create a pixelref that can
222 manage the pixel memory for the current
223 width/height/config. If allocator is NULL, the standard
224 HeapAllocator will be used.
225 @param ctable ColorTable (or null) to use with the pixels that will
226 be allocated. Only used if config == Index8_Config.
227 If it is non-null and the config is not Index8, it will
228 be ignored.
229 @return true if the allocation succeeds. If not the pixelref field of
230 the bitmap will be unchanged.
231 */
232 bool allocPixels(Allocator* allocator, SkColorTable* ctable);
233
234 /** Return the current pixelref object, of any
235 */
236 SkPixelRef* pixelRef() const { return fPixelRef; }
237 /** Return the offset into the pixelref, if any. Will return 0 if there is
238 no pixelref installed.
239 */
240 size_t pixelRefOffset() const { return fPixelRefOffset; }
241 /** Assign a pixelref and optional offset. Pixelrefs are reference counted,
242 so the existing one (if any) will be unref'd and the new one will be
243 ref'd.
244 */
245 SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset = 0);
246
247 /** Call this to ensure that the bitmap points to the current pixel address
248 in the pixelref. Balance it with a call to unlockPixels(). These calls
249 are harmless if there is no pixelref.
250 */
251 void lockPixels() const;
252 /** When you are finished access the pixel memory, call this to balance a
253 previous call to lockPixels(). This allows pixelrefs that implement
254 cached/deferred image decoding to know when there are active clients of
255 a given image.
256 */
257 void unlockPixels() const;
258
259 /** Call this to be sure that the bitmap is valid enough to be drawn (i.e.
260 it has non-null pixels, and if required by its config, it has a
261 non-null colortable. Returns true if all of the above are met.
262 */
263 bool readyToDraw() const {
264 return this->getPixels() != NULL &&
265 ((this->config() != kIndex8_Config && this->config() != kRLE_Index8_Config) ||
266 fColorTable != NULL);
267 }
268
269 /** Return the bitmap's colortable (if any). Does not affect the colortable's
270 reference count.
271 */
272 SkColorTable* getColorTable() const { return fColorTable; }
273
274 /** Returns a non-zero, unique value corresponding to the pixels in our
275 pixelref, or 0 if we do not have a pixelref. Each time the pixels are
276 changed (and notifyPixelsChanged is called), a different generation ID
277 will be returned.
278 */
279 uint32_t getGenerationID() const;
280
281 /** Call this if you have changed the contents of the pixels. This will in-
282 turn cause a different generation ID value to be returned from
283 getGenerationID().
284 */
285 void notifyPixelsChanged() const;
286
287 /** Initialize the bitmap's pixels with the specified color+alpha, automatically converting into the correct format
288 for the bitmap's config. If the config is kRGB_565_Config, then the alpha value is ignored.
289 If the config is kA8_Config, then the r,g,b parameters are ignored.
290 */
291 void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const;
292 /** Initialize the bitmap's pixels with the specified color+alpha, automatically converting into the correct format
293 for the bitmap's config. If the config is kRGB_565_Config, then the alpha value is presumed
294 to be 0xFF. If the config is kA8_Config, then the r,g,b parameters are ignored and the
295 pixels are all set to 0xFF.
296 */
297 void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const {
298 this->eraseARGB(0xFF, r, g, b);
299 }
300 /** Initialize the bitmap's pixels with the specified color, automatically converting into the correct format
301 for the bitmap's config. If the config is kRGB_565_Config, then the color's alpha value is presumed
302 to be 0xFF. If the config is kA8_Config, then only the color's alpha value is used.
303 */
304 void eraseColor(SkColor c) const {
305 this->eraseARGB(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c),
306 SkColorGetB(c));
307 }
308
309 /** Scroll (a subset of) the contents of this bitmap by dx/dy. If there are
310 no pixels allocated (i.e. getPixels() returns null) the method will
311 still update the inval region (if present).
312
313 @param subset The subset of the bitmap to scroll/move. To scroll the
314 entire contents, specify [0, 0, width, height] or just
315 pass null.
316 @param dx The amount to scroll in X
317 @param dy The amount to scroll in Y
318 @param inval Optional (may be null). Returns the area of the bitmap that
319 was scrolled away. E.g. if dx = dy = 0, then inval would
320 be set to empty. If dx >= width or dy >= height, then
321 inval would be set to the entire bounds of the bitmap.
322 @return true if the scroll was doable. Will return false if the bitmap
323 uses an unsupported config for scrolling (only kA8,
324 kIndex8, kRGB_565, kARGB_4444, kARGB_8888 are supported).
325 If no pixels are present (i.e. getPixels() returns false)
326 inval will still be updated, and true will be returned.
327 */
328 bool scrollRect(const SkIRect* subset, int dx, int dy,
329 SkRegion* inval = NULL) const;
330
331 /** Returns the address of the specified pixel. This performs a runtime
332 check to know the size of the pixels, and will return the same answer
333 as the corresponding size-specific method (e.g. getAddr16). Since the
334 check happens at runtime, it is much slower than using a size-specific
335 version. Unlike the size-specific methods, this routine also checks if
336 getPixels() returns null, and returns that. The size-specific routines
337 perform a debugging assert that getPixels() is not null, but they do
338 not do any runtime checks.
339 */
340 void* getAddr(int x, int y) const;
341
342 /** Returns the address of the pixel specified by x,y for 32bit pixels.
343 */
344 inline uint32_t* getAddr32(int x, int y) const;
345 /** Returns the address of the pixel specified by x,y for 16bit pixels.
346 */
347 inline uint16_t* getAddr16(int x, int y) const;
348 /** Returns the address of the pixel specified by x,y for 8bit pixels.
349 */
350 inline uint8_t* getAddr8(int x, int y) const;
351 /** Returns the address of the byte containing the pixel specified by x,y
352 for 1bit pixels.
353 */
354 inline uint8_t* getAddr1(int x, int y) const;
355
356 /** Returns the color corresponding to the pixel specified by x,y for
357 colortable based bitmaps.
358 */
359 inline SkPMColor getIndex8Color(int x, int y) const;
360
361 // OS-specific helpers
362#ifndef SK_USE_WXWIDGETS
363#ifdef SK_BUILD_FOR_WIN
364 /** On Windows and PocketPC builds, this will draw the SkBitmap onto the
365 specified HDC
366 */
367 void drawToHDC(HDC, int left, int top) const;
368#elif defined(SK_BUILD_FOR_MAC)
369 /** On Mac OS X and Carbon builds, this will draw the SkBitmap onto the
370 specified WindowRef
371 */
372 void drawToPort(WindowRef, CGContextRef) const;
373#endif
374#endif
375
376 /** Set dst to be a setset of this bitmap. If possible, it will share the
377 pixel memory, and just point into a subset of it. However, if the config
378 does not support this, a local copy will be made and associated with
379 the dst bitmap. If the subset rectangle, intersected with the bitmap's
380 dimensions is empty, or if there is an unsupported config, false will be
381 returned and dst will be untouched.
382 @param dst The bitmap that will be set to a subset of this bitmap
383 @param subset The rectangle of pixels in this bitmap that dst will
384 reference.
385 @return true if the subset copy was successfully made.
386 */
387 bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
388
389 /** Tries to make a new bitmap based on the dimensions of this bitmap,
390 setting the new bitmap's config to the one specified, and then copying
391 this bitmap's pixels into the new bitmap. If the conversion is not
392 supported, or the allocator fails, then this method returns false and
393 dst is left unchanged.
394 @param dst The bitmap to be sized and allocated
395 @param c The desired config for dst
396 @param allocator Allocator used to allocate the pixelref for the dst
397 bitmap. If this is null, the standard HeapAllocator
398 will be used.
399 @return true if the copy could be made.
400 */
401 bool copyTo(SkBitmap* dst, Config c, Allocator* allocator = NULL) const;
402
403 bool hasMipMap() const;
404 void buildMipMap(bool forceRebuild = false);
405 void freeMipMap();
406
407 /** Given scale factors sx, sy, determine the miplevel available in the
408 bitmap, and return it (this is the amount to shift matrix iterators
409 by). If dst is not null, it is set to the correct level.
410 */
411 int extractMipLevel(SkBitmap* dst, SkFixed sx, SkFixed sy);
412
413 void extractAlpha(SkBitmap* dst) const {
414 this->extractAlpha(dst, NULL, NULL);
415 }
416
417 void extractAlpha(SkBitmap* dst, const SkPaint* paint,
418 SkIPoint* offset) const;
419
420 void flatten(SkFlattenableWriteBuffer&) const;
421 void unflatten(SkFlattenableReadBuffer&);
422
423 SkDEBUGCODE(void validate() const;)
424
425 class Allocator : public SkRefCnt {
426 public:
427 /** Allocate the pixel memory for the bitmap, given its dimensions and
428 config. Return true on success, where success means either setPixels
429 or setPixelRef was called. The pixels need not be locked when this
430 returns. If the config requires a colortable, it also must be
431 installed via setColorTable. If false is returned, the bitmap and
432 colortable should be left unchanged.
433 */
434 virtual bool allocPixelRef(SkBitmap*, SkColorTable*) = 0;
435 };
436
437 /** Subclass of Allocator that returns a pixelref that allocates its pixel
438 memory from the heap. This is the default Allocator invoked by
439 allocPixels().
440 */
441 class HeapAllocator : public Allocator {
442 public:
443 virtual bool allocPixelRef(SkBitmap*, SkColorTable*);
444 };
445
446 class RLEPixels {
447 public:
448 RLEPixels(int width, int height);
449 virtual ~RLEPixels();
450
451 uint8_t* packedAtY(int y) const {
452 SkASSERT((unsigned)y < (unsigned)fHeight);
453 return fYPtrs[y];
454 }
455
456 // called by subclasses during creation
457 void setPackedAtY(int y, uint8_t* addr) {
458 SkASSERT((unsigned)y < (unsigned)fHeight);
459 fYPtrs[y] = addr;
460 }
461
462 private:
463 uint8_t** fYPtrs;
464 int fHeight;
465 };
466
467private:
468#ifdef SK_SUPPORT_MIPMAP
469 struct MipMap;
470 mutable MipMap* fMipMap;
471#endif
472
473 mutable SkPixelRef* fPixelRef;
474 mutable size_t fPixelRefOffset;
475 mutable int fPixelLockCount;
476 // either user-specified (in which case it is not treated as mutable)
477 // or a cache of the returned value from fPixelRef->lockPixels()
478 mutable void* fPixels;
479 mutable SkColorTable* fColorTable; // only meaningful for kIndex8
480
481 enum Flags {
482 kImageIsOpaque_Flag = 0x01
483 };
484
485 uint32_t fRowBytes;
486 uint16_t fWidth, fHeight;
487 uint8_t fConfig;
488 uint8_t fFlags;
489 uint8_t fBytesPerPixel; // based on config
490
491 /* Unreference any pixelrefs or colortables
492 */
493 void freePixels();
494 void updatePixelsFromRef() const;
495
496 static SkFixed ComputeMipLevel(SkFixed sx, SkFixed dy);
497};
498
499/** \class SkColorTable
500
501 SkColorTable holds an array SkPMColors (premultiplied 32-bit colors) used by
502 8-bit bitmaps, where the bitmap bytes are interpreted as indices into the colortable.
503*/
504class SkColorTable : public SkRefCnt {
505public:
506 /** Constructs an empty color table (zero colors).
507 */
508 explicit SkColorTable(int count);
509 explicit SkColorTable(SkFlattenableReadBuffer&);
510 SkColorTable(const SkPMColor colors[], int count);
511 virtual ~SkColorTable();
512
513 enum Flags {
514 kColorsAreOpaque_Flag = 0x01 //!< if set, all of the colors in the table are opaque (alpha==0xFF)
515 };
516 /** Returns the flag bits for the color table. These can be changed with setFlags().
517 */
518 unsigned getFlags() const { return fFlags; }
519 /** Set the flags for the color table. See the Flags enum for possible values.
520 */
521 void setFlags(unsigned flags);
522
523 /** Returns the number of colors in the table.
524 */
525 int count() const { return fCount; }
526
527 /** Returns the specified color from the table. In the debug build, this asserts that
528 the index is in range (0 <= index < count).
529 */
530 SkPMColor operator[](int index) const {
531 SkASSERT(fColors != NULL && (unsigned)index < fCount);
532 return fColors[index];
533 }
534
535 /** Specify the number of colors in the color table. This does not initialize the colors
536 to any value, just allocates memory for them. To initialize the values, either call
537 setColors(array, count), or follow setCount(count) with a call to
538 lockColors()/{set the values}/unlockColors(true).
539 */
540// void setColors(int count) { this->setColors(NULL, count); }
541// void setColors(const SkPMColor[], int count);
542
543 /** Return the array of colors for reading and/or writing. This must be
544 balanced by a call to unlockColors(changed?), telling the colortable if
545 the colors were changed during the lock.
546 */
547 SkPMColor* lockColors() {
548 SkDEBUGCODE(fColorLockCount += 1;)
549 return fColors;
550 }
551 /** Balancing call to lockColors(). If the colors have been changed, pass true.
552 */
553 void unlockColors(bool changed);
554
555 /** Similar to lockColors(), lock16BitCache() returns the array of
556 RGB16 colors that mirror the 32bit colors. However, this function
557 will return null if kColorsAreOpaque_Flag is not set.
558 Also, unlike lockColors(), the returned array here cannot be modified.
559 */
560 const uint16_t* lock16BitCache();
561 /** Balancing call to lock16BitCache().
562 */
563 void unlock16BitCache() {
564 SkASSERT(f16BitCacheLockCount > 0);
565 SkDEBUGCODE(f16BitCacheLockCount -= 1);
566 }
567
568 void flatten(SkFlattenableWriteBuffer&) const;
569
570private:
571 SkPMColor* fColors;
572 uint16_t* f16BitCache;
573 uint16_t fCount;
574 uint8_t fFlags;
575 SkDEBUGCODE(int fColorLockCount;)
576 SkDEBUGCODE(int f16BitCacheLockCount;)
577
578 void inval16BitCache();
579};
580
581class SkAutoLockPixels {
582public:
583 SkAutoLockPixels(const SkBitmap& bitmap) : fBitmap(bitmap) {
584 bitmap.lockPixels();
585 }
586 ~SkAutoLockPixels() {
587 fBitmap.unlockPixels();
588 }
589
590private:
591 const SkBitmap& fBitmap;
592};
593
594/** Helper class that performs the lock/unlockColors calls on a colortable.
595 The destructor will call unlockColors(false) if it has a bitmap's colortable
596*/
597class SkAutoLockColors : public SkNoncopyable {
598public:
599 /** Initialize with no bitmap. Call lockColors(bitmap) to lock bitmap's
600 colortable
601 */
602 SkAutoLockColors() : fCTable(NULL), fColors(NULL) {}
603 /** Initialize with bitmap, locking its colortable if present
604 */
605 explicit SkAutoLockColors(const SkBitmap& bm) {
606 fCTable = bm.getColorTable();
607 fColors = fCTable ? fCTable->lockColors() : NULL;
608 }
609 /** Initialize with a colortable (may be null)
610 */
611 explicit SkAutoLockColors(SkColorTable* ctable) {
612 fCTable = ctable;
613 fColors = ctable ? ctable->lockColors() : NULL;
614 }
615 ~SkAutoLockColors() {
616 if (fCTable) {
617 fCTable->unlockColors(false);
618 }
619 }
620
621 /** Return the currently locked colors, or NULL if no bitmap's colortable
622 is currently locked.
623 */
624 const SkPMColor* colors() const { return fColors; }
625
626 /** If a previous bitmap has been locked by this object, unlock its colors
627 first. If the specified bitmap has a colortable, lock its colors and
628 return them.
629 */
630 const SkPMColor* lockColors(const SkBitmap& bm) {
631 if (fCTable) {
632 fCTable->unlockColors(false);
633 }
634 fCTable = bm.getColorTable();
635 fColors = fCTable ? fCTable->lockColors() : NULL;
636 return fColors;
637 }
638
639private:
640 SkColorTable* fCTable;
641 const SkPMColor* fColors;
642};
643
644///////////////////////////////////////////////////////////////////////////////
645
646inline uint32_t* SkBitmap::getAddr32(int x, int y) const {
647 SkASSERT(fPixels);
648 SkASSERT(fConfig == kARGB_8888_Config);
649 SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
650 return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2));
651}
652
653inline uint16_t* SkBitmap::getAddr16(int x, int y) const {
654 SkASSERT(fPixels);
655 SkASSERT(fConfig == kRGB_565_Config || fConfig == kARGB_4444_Config);
656 SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
657 return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1));
658}
659
660inline uint8_t* SkBitmap::getAddr8(int x, int y) const {
661 SkASSERT(fPixels);
662 SkASSERT(fConfig == kA8_Config || fConfig == kIndex8_Config);
663 SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
664 return (uint8_t*)fPixels + y * fRowBytes + x;
665}
666
667inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const {
668 SkASSERT(fPixels);
669 SkASSERT(fConfig == kIndex8_Config);
670 SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
671 SkASSERT(fColorTable);
672 return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
673}
674
675// returns the address of the byte that contains the x coordinate
676inline uint8_t* SkBitmap::getAddr1(int x, int y) const {
677 SkASSERT(fPixels);
678 SkASSERT(fConfig == kA1_Config);
679 SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
680 return (uint8_t*)fPixels + y * fRowBytes + (x >> 3);
681}
682
683#endif
684