blob: 29ff2c5a1aad53f0e8a221c5f00365459f077b96 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00003 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00004 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00006 */
7
8#ifndef SkBitmap_DEFINED
9#define SkBitmap_DEFINED
10
reed@android.com8a1c16f2008-12-17 15:59:43 +000011#include "SkColor.h"
djsollen@google.com64a0ec32012-06-12 15:17:27 +000012#include "SkColorTable.h"
reed@google.com3443fd82013-11-13 19:09:13 +000013#include "SkImageInfo.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000014#include "SkPoint.h"
15#include "SkRefCnt.h"
16
commit-bot@chromium.orgdac52252014-02-17 21:21:46 +000017struct SkMask;
reed@android.com8a1c16f2008-12-17 15:59:43 +000018struct SkIRect;
reed@google.comfb2d3c62012-03-15 21:18:11 +000019struct SkRect;
reed@android.com8a1c16f2008-12-17 15:59:43 +000020class SkPaint;
21class SkPixelRef;
reed@google.com9ebcac52014-01-24 18:53:42 +000022class SkPixelRefFactory;
reed@android.com8a1c16f2008-12-17 15:59:43 +000023class SkRegion;
robertphillips@google.com76f9e932013-01-15 20:17:47 +000024class SkString;
commit-bot@chromium.orgb8d00db2013-06-26 19:18:23 +000025class GrTexture;
reed@android.comce4e53a2010-09-09 16:01:26 +000026
commit-bot@chromium.org968edca2014-05-23 13:21:55 +000027//#define SK_SUPPORT_LEGACY_BITMAPFLATTEN
28
reed@android.com8a1c16f2008-12-17 15:59:43 +000029/** \class SkBitmap
30
31 The SkBitmap class specifies a raster bitmap. A bitmap has an integer width
32 and height, and a format (config), and a pointer to the actual pixels.
tomhudson@google.com4b33d282011-04-27 15:39:30 +000033 Bitmaps can be drawn into a SkCanvas, but they are also used to specify the
34 target of a SkCanvas' drawing operations.
35 A const SkBitmap exposes getAddr(), which lets a caller write its pixels;
36 the constness is considered to apply to the bitmap's configuration, not
37 its contents.
reed@android.com8a1c16f2008-12-17 15:59:43 +000038*/
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000039class SK_API SkBitmap {
reed@android.com8a1c16f2008-12-17 15:59:43 +000040public:
commit-bot@chromium.orgeddb02c2013-11-25 15:44:37 +000041 class SK_API Allocator;
reed@android.com8a1c16f2008-12-17 15:59:43 +000042
43 enum Config {
44 kNo_Config, //!< bitmap has not been configured
reed@android.com8a1c16f2008-12-17 15:59:43 +000045 kA8_Config, //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque)
46 kIndex8_Config, //!< 8-bits per pixel, using SkColorTable to specify the colors
47 kRGB_565_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
48 kARGB_4444_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
49 kARGB_8888_Config, //!< 32-bits per pixel, (see SkColorPriv.h for packing)
reed@google.com62b26052013-06-25 21:23:54 +000050 };
skia.committer@gmail.com73a4b4f2013-06-26 07:00:59 +000051
reed@google.com62b26052013-06-25 21:23:54 +000052 // do not add this to the Config enum, otherwise the compiler will let us
53 // pass this as a valid parameter for Config.
54 enum {
reed@google.com2cb14802013-06-26 14:35:02 +000055 kConfigCount = kARGB_8888_Config + 1
reed@android.com8a1c16f2008-12-17 15:59:43 +000056 };
57
reed@google.com5dd510f2012-05-16 13:04:22 +000058 /**
59 * Default construct creates a bitmap with zero width and height, and no pixels.
60 * Its config is set to kNo_Config.
61 */
reed@android.com8a1c16f2008-12-17 15:59:43 +000062 SkBitmap();
reed@google.com5dd510f2012-05-16 13:04:22 +000063
64 /**
65 * Copy the settings from the src into this bitmap. If the src has pixels
66 * allocated, they will be shared, not copied, so that the two bitmaps will
67 * reference the same memory for the pixels. If a deep copy is needed,
68 * where the new bitmap has its own separate copy of the pixels, use
69 * deepCopyTo().
70 */
reed@android.com8a1c16f2008-12-17 15:59:43 +000071 SkBitmap(const SkBitmap& src);
reed@google.com5dd510f2012-05-16 13:04:22 +000072
reed@android.com8a1c16f2008-12-17 15:59:43 +000073 ~SkBitmap();
74
75 /** Copies the src bitmap into this bitmap. Ownership of the src bitmap's pixels remains
76 with the src bitmap.
77 */
78 SkBitmap& operator=(const SkBitmap& src);
79 /** Swap the fields of the two bitmaps. This routine is guaranteed to never fail or throw.
80 */
81 // This method is not exported to java.
82 void swap(SkBitmap& other);
weita@google.comf9ab99a2009-05-03 18:23:30 +000083
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +000084 ///////////////////////////////////////////////////////////////////////////
85
86 const SkImageInfo& info() const { return fInfo; }
87
88 int width() const { return fInfo.fWidth; }
89 int height() const { return fInfo.fHeight; }
90 SkColorType colorType() const { return fInfo.fColorType; }
91 SkAlphaType alphaType() const { return fInfo.fAlphaType; }
92
93 /** Return the number of bytes per pixel based on the config. If the config
94 does not have at least 1 byte per (e.g. kA1_Config) then 0 is returned.
95 */
96 int bytesPerPixel() const { return fInfo.bytesPerPixel(); }
97
98 /** Return the rowbytes expressed as a number of pixels (like width and
99 height). Note, for 1-byte per pixel configs like kA8_Config, this will
100 return the same as rowBytes(). Is undefined for configs that are less
101 than 1-byte per pixel (e.g. kA1_Config)
102 */
103 int rowBytesAsPixels() const {
104 return fRowBytes >> this->shiftPerPixel();
105 }
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 this->bytesPerPixel() >> 1; }
113
114 ///////////////////////////////////////////////////////////////////////////
115
reed@android.com8a1c16f2008-12-17 15:59:43 +0000116 /** Return true iff the bitmap has empty dimensions.
commit-bot@chromium.org50b393a2014-02-10 18:29:10 +0000117 * Hey! Before you use this, see if you really want to know drawsNothing() instead.
118 */
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000119 bool empty() const { return fInfo.isEmpty(); }
weita@google.comf9ab99a2009-05-03 18:23:30 +0000120
djsollen@google.comc84b8332012-07-27 13:41:44 +0000121 /** Return true iff the bitmap has no pixelref. Note: this can return true even if the
commit-bot@chromium.org50b393a2014-02-10 18:29:10 +0000122 * dimensions of the bitmap are > 0 (see empty()).
123 * Hey! Before you use this, see if you really want to know drawsNothing() instead.
124 */
djsollen@google.comc84b8332012-07-27 13:41:44 +0000125 bool isNull() const { return NULL == fPixelRef; }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000126
commit-bot@chromium.org50b393a2014-02-10 18:29:10 +0000127 /** Return true iff drawing this bitmap has no effect.
128 */
129 bool drawsNothing() const { return this->empty() || this->isNull(); }
130
reed@google.com44699382013-10-31 17:28:30 +0000131 /** Return the config for the bitmap. */
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000132 Config config() const;
reed@google.com44699382013-10-31 17:28:30 +0000133
134 SK_ATTR_DEPRECATED("use config()")
reed@android.com8a1c16f2008-12-17 15:59:43 +0000135 Config getConfig() const { return this->config(); }
reed@google.com44699382013-10-31 17:28:30 +0000136
reed@google.com44699382013-10-31 17:28:30 +0000137 /** Return the number of bytes between subsequent rows of the bitmap. */
scroggo@google.com0ba4bf42013-02-25 16:02:36 +0000138 size_t rowBytes() const { return fRowBytes; }
weita@google.comf9ab99a2009-05-03 18:23:30 +0000139
reed@google.com383a6972013-10-21 14:00:07 +0000140 /**
141 * Set the bitmap's alphaType, returning true on success. If false is
142 * returned, then the specified new alphaType is incompatible with the
143 * Config, and the current alphaType is unchanged.
commit-bot@chromium.org0e8d0d62014-01-27 15:41:07 +0000144 *
145 * Note: this changes the alphatype for the underlying pixels, which means
146 * that all bitmaps that might be sharing (subsets of) the pixels will
reed@google.comc1587f92014-01-28 16:05:39 +0000147 * be affected.
reed@google.com383a6972013-10-21 14:00:07 +0000148 */
149 bool setAlphaType(SkAlphaType);
150
reed@android.com8a1c16f2008-12-17 15:59:43 +0000151 /** Return the address of the pixels for this SkBitmap.
152 */
153 void* getPixels() const { return fPixels; }
154
155 /** Return the byte size of the pixels, based on the height and rowBytes.
156 Note this truncates the result to 32bits. Call getSize64() to detect
157 if the real size exceeds 32bits.
158 */
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000159 size_t getSize() const { return fInfo.fHeight * fRowBytes; }
weita@google.comf9ab99a2009-05-03 18:23:30 +0000160
wjmaclean@chromium.org86bff1f2010-11-16 20:22:41 +0000161 /** Return the number of bytes from the pointer returned by getPixels()
162 to the end of the allocated space in the buffer. Required in
epoger@google.comd27fe342012-12-07 15:27:27 +0000163 cases where extractSubset has been called.
wjmaclean@chromium.org86bff1f2010-11-16 20:22:41 +0000164 */
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000165 size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); }
wjmaclean@chromium.org86bff1f2010-11-16 20:22:41 +0000166
reed@google.com57212f92013-12-30 14:40:38 +0000167 /**
168 * Return the full size of the bitmap, in bytes.
169 */
170 int64_t computeSize64() const {
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000171 return sk_64_mul(fInfo.fHeight, fRowBytes);
reed@google.com57212f92013-12-30 14:40:38 +0000172 }
173
174 /**
175 * Return the number of bytes from the pointer returned by getPixels()
176 * to the end of the allocated space in the buffer. This may be smaller
177 * than computeSize64() if there is any rowbytes padding beyond the width.
178 */
179 int64_t computeSafeSize64() const {
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000180 return fInfo.getSafeSize64(fRowBytes);
reed@google.com57212f92013-12-30 14:40:38 +0000181 }
182
junov@chromium.orgb0521292011-12-15 20:14:06 +0000183 /** Returns true if this bitmap is marked as immutable, meaning that the
184 contents of its pixels will not change for the lifetime of the bitmap.
185 */
186 bool isImmutable() const;
187
188 /** Marks this bitmap as immutable, meaning that the contents of its
189 pixels will not change for the lifetime of the bitmap and of the
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000190 underlying pixelref. This state can be set, but it cannot be
junov@chromium.orgb0521292011-12-15 20:14:06 +0000191 cleared once it is set. This state propagates to all other bitmaps
192 that share the same pixelref.
193 */
194 void setImmutable();
195
reed@android.com8a1c16f2008-12-17 15:59:43 +0000196 /** Returns true if the bitmap is opaque (has no translucent/transparent pixels).
197 */
reed@google.com383a6972013-10-21 14:00:07 +0000198 bool isOpaque() const {
199 return SkAlphaTypeIsOpaque(this->alphaType());
200 }
junov@google.com4ee7ae52011-06-30 17:30:49 +0000201
junov@google.com4ee7ae52011-06-30 17:30:49 +0000202 /** Returns true if the bitmap is volatile (i.e. should not be cached by devices.)
203 */
204 bool isVolatile() const;
205
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000206 /** Specify whether this bitmap is volatile. Bitmaps are not volatile by
junov@google.com4ee7ae52011-06-30 17:30:49 +0000207 default. Temporary bitmaps that are discarded after use should be
208 marked as volatile. This provides a hint to the device that the bitmap
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000209 should not be cached. Providing this hint when appropriate can
210 improve performance by avoiding unnecessary overhead and resource
junov@google.com4ee7ae52011-06-30 17:30:49 +0000211 consumption on the device.
212 */
213 void setIsVolatile(bool);
214
reed@android.com8a1c16f2008-12-17 15:59:43 +0000215 /** Reset the bitmap to its initial state (see default constructor). If we are a (shared)
216 owner of the pixels, that ownership is decremented.
217 */
218 void reset();
219
220 /** Given a config and a width, this computes the optimal rowBytes value. This is called automatically
221 if you pass 0 for rowBytes to setConfig().
222 */
scroggo@google.com0ba4bf42013-02-25 16:02:36 +0000223 static size_t ComputeRowBytes(Config c, int width);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000224
225 /** Return the bytes-per-pixel for the specified config. If the config is
226 not at least 1-byte per pixel, return 0, including for kNo_Config.
227 */
228 static int ComputeBytesPerPixel(Config c);
229
230 /** Return the shift-per-pixel for the specified config. If the config is
231 not at least 1-byte per pixel, return 0, including for kNo_Config.
232 */
233 static int ComputeShiftPerPixel(Config c) {
234 return ComputeBytesPerPixel(c) >> 1;
235 }
weita@google.comf9ab99a2009-05-03 18:23:30 +0000236
reed@google.com57212f92013-12-30 14:40:38 +0000237 static int64_t ComputeSize64(Config, int width, int height);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000238 static size_t ComputeSize(Config, int width, int height);
239
reed@google.com86b2e432012-03-15 21:17:03 +0000240 /**
reed@google.com2a7579d2012-11-07 18:30:18 +0000241 * This will brute-force return true if all of the pixels in the bitmap
242 * are opaque. If it fails to read the pixels, or encounters an error,
243 * it will return false.
244 *
245 * Since this can be an expensive operation, the bitmap stores a flag for
commit-bot@chromium.org21a0b102013-11-12 18:16:34 +0000246 * this (isOpaque). Only call this if you need to compute this value from
247 * "unknown" pixels.
reed@google.com2a7579d2012-11-07 18:30:18 +0000248 */
249 static bool ComputeIsOpaque(const SkBitmap&);
250
251 /**
reed@google.com86b2e432012-03-15 21:17:03 +0000252 * Return the bitmap's bounds [0, 0, width, height] as an SkRect
253 */
254 void getBounds(SkRect* bounds) const;
reed@google.com80e14592012-03-16 14:58:07 +0000255 void getBounds(SkIRect* bounds) const;
reed@google.com86b2e432012-03-15 21:17:03 +0000256
reed@android.com8a1c16f2008-12-17 15:59:43 +0000257 /** Set the bitmap's config and dimensions. If rowBytes is 0, then
258 ComputeRowBytes() is called to compute the optimal value. This resets
259 any pixel/colortable ownership, just like reset().
260 */
reed@google.com383a6972013-10-21 14:00:07 +0000261 bool setConfig(Config, int width, int height, size_t rowBytes, SkAlphaType);
262
263 bool setConfig(Config config, int width, int height, size_t rowBytes = 0) {
264 return this->setConfig(config, width, height, rowBytes,
265 kPremul_SkAlphaType);
266 }
267
commit-bot@chromium.org6e3e4222013-11-06 10:08:30 +0000268 bool setConfig(const SkImageInfo& info, size_t rowBytes = 0);
reed@google.com383a6972013-10-21 14:00:07 +0000269
reed@google.com9230ea22013-12-09 22:01:03 +0000270 /**
reed@google.com9ebcac52014-01-24 18:53:42 +0000271 * Allocate a pixelref to match the specified image info. If the Factory
272 * is non-null, call it to allcoate the pixelref. If the ImageInfo requires
273 * a colortable, then ColorTable must be non-null, and will be ref'd.
274 * On failure, the bitmap will be set to empty and return false.
275 */
276 bool allocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*);
skia.committer@gmail.comd2ac07b2014-01-25 07:01:49 +0000277
reed@google.com9ebcac52014-01-24 18:53:42 +0000278 /**
279 * Allocate a pixelref to match the specified image info, using the default
280 * allocator.
281 * On success, the bitmap's pixels will be "locked", and return true.
282 * On failure, the bitmap will be set to empty and return false.
283 */
284 bool allocPixels(const SkImageInfo& info) {
285 return this->allocPixels(info, NULL, NULL);
286 }
skia.committer@gmail.comd2ac07b2014-01-25 07:01:49 +0000287
reed@google.com9ebcac52014-01-24 18:53:42 +0000288 /**
reed@google.comeb9a46c2014-01-25 16:46:20 +0000289 * Legacy helper function, which creates an SkImageInfo from the specified
290 * config and then calls allocPixels(info).
291 */
292 bool allocConfigPixels(Config, int width, int height, bool isOpaque = false);
293
294 bool allocN32Pixels(int width, int height, bool isOpaque = false) {
295 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
296 if (isOpaque) {
297 info.fAlphaType = kOpaque_SkAlphaType;
298 }
299 return this->allocPixels(info);
300 }
301
302 /**
reed@google.com9ebcac52014-01-24 18:53:42 +0000303 * Install a pixelref that wraps the specified pixels and rowBytes, and
304 * optional ReleaseProc and context. When the pixels are no longer
305 * referenced, if ReleaseProc is not null, it will be called with the
306 * pixels and context as parameters.
307 * On failure, the bitmap will be set to empty and return false.
308 */
309 bool installPixels(const SkImageInfo&, void* pixels, size_t rowBytes,
310 void (*ReleaseProc)(void* addr, void* context),
311 void* context);
skia.committer@gmail.com31acdea2014-02-18 03:01:51 +0000312
commit-bot@chromium.orgdac52252014-02-17 21:21:46 +0000313 /**
314 * Call installPixels with no ReleaseProc specified. This means that the
315 * caller must ensure that the specified pixels are valid for the lifetime
316 * of the created bitmap (and its pixelRef).
317 */
318 bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
319 return this->installPixels(info, pixels, rowBytes, NULL, NULL);
320 }
321
322 /**
323 * Calls installPixels() with the value in the SkMask. The caller must
324 * ensure that the specified mask pixels are valid for the lifetime
325 * of the created bitmap (and its pixelRef).
326 */
327 bool installMaskPixels(const SkMask&);
skia.committer@gmail.comd2ac07b2014-01-25 07:01:49 +0000328
reed@google.com9ebcac52014-01-24 18:53:42 +0000329 /**
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000330 * DEPRECATED: call info().
reed@google.com9230ea22013-12-09 22:01:03 +0000331 */
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000332 bool asImageInfo(SkImageInfo* info) const {
333 // compatibility: return false for kUnknown
334 if (kUnknown_SkColorType == this->colorType()) {
335 return false;
336 }
337 if (info) {
338 *info = this->info();
339 }
340 return true;
341 }
reed@google.com9230ea22013-12-09 22:01:03 +0000342
reed@android.com8a1c16f2008-12-17 15:59:43 +0000343 /** Use this to assign a new pixel address for an existing bitmap. This
344 will automatically release any pixelref previously installed. Only call
345 this if you are handling ownership/lifetime of the pixel memory.
weita@google.comf9ab99a2009-05-03 18:23:30 +0000346
reed@android.com8a1c16f2008-12-17 15:59:43 +0000347 If the bitmap retains a reference to the colortable (assuming it is
348 not null) it will take care of incrementing the reference count.
349
350 @param pixels Address for the pixels, managed by the caller.
351 @param ctable ColorTable (or null) that matches the specified pixels
352 */
353 void setPixels(void* p, SkColorTable* ctable = NULL);
354
wjmaclean@chromium.org86bff1f2010-11-16 20:22:41 +0000355 /** Copies the bitmap's pixels to the location pointed at by dst and returns
356 true if possible, returns false otherwise.
357
bsalomon@google.comc6980972011-11-02 19:57:21 +0000358 In the case when the dstRowBytes matches the bitmap's rowBytes, the copy
359 may be made faster by copying over the dst's per-row padding (for all
360 rows but the last). By setting preserveDstPad to true the caller can
361 disable this optimization and ensure that pixels in the padding are not
362 overwritten.
wjmaclean@chromium.org86bff1f2010-11-16 20:22:41 +0000363
364 Always returns false for RLE formats.
365
366 @param dst Location of destination buffer.
367 @param dstSize Size of destination buffer. Must be large enough to hold
368 pixels using indicated stride.
scroggo@google.com0ba4bf42013-02-25 16:02:36 +0000369 @param dstRowBytes Width of each line in the buffer. If 0, uses
wjmaclean@chromium.org86bff1f2010-11-16 20:22:41 +0000370 bitmap's internal stride.
bsalomon@google.comc6980972011-11-02 19:57:21 +0000371 @param preserveDstPad Must we preserve padding in the dst
wjmaclean@chromium.org86bff1f2010-11-16 20:22:41 +0000372 */
scroggo@google.com0ba4bf42013-02-25 16:02:36 +0000373 bool copyPixelsTo(void* const dst, size_t dstSize, size_t dstRowBytes = 0,
374 bool preserveDstPad = false) const;
wjmaclean@chromium.org86bff1f2010-11-16 20:22:41 +0000375
reed@android.com8a1c16f2008-12-17 15:59:43 +0000376 /** Use the standard HeapAllocator to create the pixelref that manages the
377 pixel memory. It will be sized based on the current width/height/config.
378 If this is called multiple times, a new pixelref object will be created
379 each time.
weita@google.comf9ab99a2009-05-03 18:23:30 +0000380
reed@android.com8a1c16f2008-12-17 15:59:43 +0000381 If the bitmap retains a reference to the colortable (assuming it is
382 not null) it will take care of incrementing the reference count.
383
384 @param ctable ColorTable (or null) to use with the pixels that will
385 be allocated. Only used if config == Index8_Config
386 @return true if the allocation succeeds. If not the pixelref field of
387 the bitmap will be unchanged.
388 */
389 bool allocPixels(SkColorTable* ctable = NULL) {
390 return this->allocPixels(NULL, ctable);
391 }
weita@google.comf9ab99a2009-05-03 18:23:30 +0000392
reed@android.com8a1c16f2008-12-17 15:59:43 +0000393 /** Use the specified Allocator to create the pixelref that manages the
394 pixel memory. It will be sized based on the current width/height/config.
395 If this is called multiple times, a new pixelref object will be created
396 each time.
weita@google.comf9ab99a2009-05-03 18:23:30 +0000397
reed@android.com8a1c16f2008-12-17 15:59:43 +0000398 If the bitmap retains a reference to the colortable (assuming it is
399 not null) it will take care of incrementing the reference count.
weita@google.comf9ab99a2009-05-03 18:23:30 +0000400
reed@android.com8a1c16f2008-12-17 15:59:43 +0000401 @param allocator The Allocator to use to create a pixelref that can
402 manage the pixel memory for the current
403 width/height/config. If allocator is NULL, the standard
404 HeapAllocator will be used.
405 @param ctable ColorTable (or null) to use with the pixels that will
406 be allocated. Only used if config == Index8_Config.
407 If it is non-null and the config is not Index8, it will
408 be ignored.
409 @return true if the allocation succeeds. If not the pixelref field of
410 the bitmap will be unchanged.
411 */
412 bool allocPixels(Allocator* allocator, SkColorTable* ctable);
weita@google.comf9ab99a2009-05-03 18:23:30 +0000413
reed@google.com672588b2014-01-08 15:42:01 +0000414 /**
415 * Return the current pixelref object or NULL if there is none. This does
416 * not affect the refcount of the pixelref.
417 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000418 SkPixelRef* pixelRef() const { return fPixelRef; }
reed@google.com672588b2014-01-08 15:42:01 +0000419
420 /**
421 * A bitmap can reference a subset of a pixelref's pixels. That means the
422 * bitmap's width/height can be <= the dimensions of the pixelref. The
423 * pixelref origin is the x,y location within the pixelref's pixels for
424 * the bitmap's top/left corner. To be valid the following must be true:
425 *
426 * origin_x + bitmap_width <= pixelref_width
427 * origin_y + bitmap_height <= pixelref_height
428 *
429 * pixelRefOrigin() returns this origin, or (0,0) if there is no pixelRef.
430 */
431 SkIPoint pixelRefOrigin() const { return fPixelRefOrigin; }
432
433 /**
434 * Assign a pixelref and origin to the bitmap. Pixelrefs are reference,
435 * so the existing one (if any) will be unref'd and the new one will be
436 * ref'd. (x,y) specify the offset within the pixelref's pixels for the
437 * top/left corner of the bitmap. For a bitmap that encompases the entire
438 * pixels of the pixelref, these will be (0,0).
439 */
440 SkPixelRef* setPixelRef(SkPixelRef* pr, int dx, int dy);
441
442 SkPixelRef* setPixelRef(SkPixelRef* pr, const SkIPoint& origin) {
443 return this->setPixelRef(pr, origin.fX, origin.fY);
444 }
skia.committer@gmail.com1ae91112014-01-09 07:01:42 +0000445
reed@google.com672588b2014-01-08 15:42:01 +0000446 SkPixelRef* setPixelRef(SkPixelRef* pr) {
447 return this->setPixelRef(pr, 0, 0);
448 }
weita@google.comf9ab99a2009-05-03 18:23:30 +0000449
reed@android.com8a1c16f2008-12-17 15:59:43 +0000450 /** Call this to ensure that the bitmap points to the current pixel address
451 in the pixelref. Balance it with a call to unlockPixels(). These calls
452 are harmless if there is no pixelref.
453 */
454 void lockPixels() const;
455 /** When you are finished access the pixel memory, call this to balance a
456 previous call to lockPixels(). This allows pixelrefs that implement
457 cached/deferred image decoding to know when there are active clients of
458 a given image.
459 */
460 void unlockPixels() const;
weita@google.comf9ab99a2009-05-03 18:23:30 +0000461
reed@google.com9c49bc32011-07-07 13:42:37 +0000462 /**
463 * Some bitmaps can return a copy of their pixels for lockPixels(), but
464 * that copy, if modified, will not be pushed back. These bitmaps should
465 * not be used as targets for a raster device/canvas (since all pixels
466 * modifications will be lost when unlockPixels() is called.)
467 */
468 bool lockPixelsAreWritable() const;
469
reed@android.com8a1c16f2008-12-17 15:59:43 +0000470 /** Call this to be sure that the bitmap is valid enough to be drawn (i.e.
471 it has non-null pixels, and if required by its config, it has a
472 non-null colortable. Returns true if all of the above are met.
473 */
474 bool readyToDraw() const {
475 return this->getPixels() != NULL &&
reed@google.com69e64632014-03-14 20:48:05 +0000476 (this->colorType() != kIndex_8_SkColorType || NULL != fColorTable);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000477 }
478
reed@android.comce4e53a2010-09-09 16:01:26 +0000479 /** Returns the pixelRef's texture, or NULL
480 */
commit-bot@chromium.orgb8d00db2013-06-26 19:18:23 +0000481 GrTexture* getTexture() const;
reed@android.comce4e53a2010-09-09 16:01:26 +0000482
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000483 /** Return the bitmap's colortable, if it uses one (i.e. colorType is
484 Index_8) and the pixels are locked.
scroggo@google.com665b2cc2013-05-06 18:08:05 +0000485 Otherwise returns NULL. Does not affect the colortable's
reed@android.com8a1c16f2008-12-17 15:59:43 +0000486 reference count.
487 */
488 SkColorTable* getColorTable() const { return fColorTable; }
489
490 /** Returns a non-zero, unique value corresponding to the pixels in our
djsollen@google.comc84b8332012-07-27 13:41:44 +0000491 pixelref. Each time the pixels are changed (and notifyPixelsChanged
492 is called), a different generation ID will be returned. Finally, if
493 their is no pixelRef then zero is returned.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000494 */
495 uint32_t getGenerationID() const;
weita@google.comf9ab99a2009-05-03 18:23:30 +0000496
reed@android.com8a1c16f2008-12-17 15:59:43 +0000497 /** Call this if you have changed the contents of the pixels. This will in-
498 turn cause a different generation ID value to be returned from
499 getGenerationID().
500 */
501 void notifyPixelsChanged() const;
502
reed@google.com60d32352013-06-28 19:40:50 +0000503 /**
504 * Fill the entire bitmap with the specified color.
505 * If the bitmap's config does not support alpha (e.g. 565) then the alpha
506 * of the color is ignored (treated as opaque). If the config only supports
507 * alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
508 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000509 void eraseColor(SkColor c) const {
510 this->eraseARGB(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c),
511 SkColorGetB(c));
512 }
weita@google.comf9ab99a2009-05-03 18:23:30 +0000513
reed@google.com60d32352013-06-28 19:40:50 +0000514 /**
515 * Fill the entire bitmap with the specified color.
516 * If the bitmap's config does not support alpha (e.g. 565) then the alpha
517 * of the color is ignored (treated as opaque). If the config only supports
518 * alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
519 */
520 void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const;
521
reed@google.com44699382013-10-31 17:28:30 +0000522 SK_ATTR_DEPRECATED("use eraseARGB or eraseColor")
reed@google.com60d32352013-06-28 19:40:50 +0000523 void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const {
524 this->eraseARGB(0xFF, r, g, b);
525 }
526
527 /**
528 * Fill the specified area of this bitmap with the specified color.
529 * If the bitmap's config does not support alpha (e.g. 565) then the alpha
530 * of the color is ignored (treated as opaque). If the config only supports
531 * alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
532 */
533 void eraseArea(const SkIRect& area, SkColor c) const;
534
reed@android.com8a1c16f2008-12-17 15:59:43 +0000535 /** Scroll (a subset of) the contents of this bitmap by dx/dy. If there are
536 no pixels allocated (i.e. getPixels() returns null) the method will
scroggo@google.com6a9368d2012-08-22 16:19:52 +0000537 still update the inval region (if present). If the bitmap is immutable,
538 do nothing and return false.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000539
540 @param subset The subset of the bitmap to scroll/move. To scroll the
541 entire contents, specify [0, 0, width, height] or just
542 pass null.
543 @param dx The amount to scroll in X
544 @param dy The amount to scroll in Y
545 @param inval Optional (may be null). Returns the area of the bitmap that
546 was scrolled away. E.g. if dx = dy = 0, then inval would
547 be set to empty. If dx >= width or dy >= height, then
548 inval would be set to the entire bounds of the bitmap.
549 @return true if the scroll was doable. Will return false if the bitmap
550 uses an unsupported config for scrolling (only kA8,
551 kIndex8, kRGB_565, kARGB_4444, kARGB_8888 are supported).
552 If no pixels are present (i.e. getPixels() returns false)
553 inval will still be updated, and true will be returned.
554 */
555 bool scrollRect(const SkIRect* subset, int dx, int dy,
556 SkRegion* inval = NULL) const;
557
reed@google.com3b521d02011-04-29 11:53:41 +0000558 /**
559 * Return the SkColor of the specified pixel. In most cases this will
560 * require un-premultiplying the color. Alpha only configs (A1 and A8)
561 * return black with the appropriate alpha set. The value is undefined
562 * for kNone_Config or if x or y are out of bounds, or if the bitmap
563 * does not have any pixels (or has not be locked with lockPixels()).
564 */
565 SkColor getColor(int x, int y) const;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000566
reed@android.com8a1c16f2008-12-17 15:59:43 +0000567 /** Returns the address of the specified pixel. This performs a runtime
568 check to know the size of the pixels, and will return the same answer
569 as the corresponding size-specific method (e.g. getAddr16). Since the
570 check happens at runtime, it is much slower than using a size-specific
571 version. Unlike the size-specific methods, this routine also checks if
572 getPixels() returns null, and returns that. The size-specific routines
573 perform a debugging assert that getPixels() is not null, but they do
574 not do any runtime checks.
575 */
576 void* getAddr(int x, int y) const;
577
578 /** Returns the address of the pixel specified by x,y for 32bit pixels.
reed@google.com3b521d02011-04-29 11:53:41 +0000579 * In debug build, this asserts that the pixels are allocated and locked,
580 * and that the config is 32-bit, however none of these checks are performed
581 * in the release build.
582 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000583 inline uint32_t* getAddr32(int x, int y) const;
reed@google.com3b521d02011-04-29 11:53:41 +0000584
reed@android.com8a1c16f2008-12-17 15:59:43 +0000585 /** Returns the address of the pixel specified by x,y for 16bit pixels.
reed@google.com3b521d02011-04-29 11:53:41 +0000586 * In debug build, this asserts that the pixels are allocated and locked,
587 * and that the config is 16-bit, however none of these checks are performed
588 * in the release build.
589 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000590 inline uint16_t* getAddr16(int x, int y) const;
reed@google.com3b521d02011-04-29 11:53:41 +0000591
reed@android.com8a1c16f2008-12-17 15:59:43 +0000592 /** Returns the address of the pixel specified by x,y for 8bit pixels.
reed@google.com3b521d02011-04-29 11:53:41 +0000593 * In debug build, this asserts that the pixels are allocated and locked,
594 * and that the config is 8-bit, however none of these checks are performed
595 * in the release build.
596 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000597 inline uint8_t* getAddr8(int x, int y) const;
reed@google.com3b521d02011-04-29 11:53:41 +0000598
reed@android.com8a1c16f2008-12-17 15:59:43 +0000599 /** Returns the color corresponding to the pixel specified by x,y for
reed@google.com3b521d02011-04-29 11:53:41 +0000600 * colortable based bitmaps.
601 * In debug build, this asserts that the pixels are allocated and locked,
602 * that the config is kIndex8, and that the colortable is allocated,
603 * however none of these checks are performed in the release build.
604 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000605 inline SkPMColor getIndex8Color(int x, int y) const;
606
epoger@google.com9ef2d832011-07-01 21:12:20 +0000607 /** Set dst to be a setset of this bitmap. If possible, it will share the
reed@android.com8a1c16f2008-12-17 15:59:43 +0000608 pixel memory, and just point into a subset of it. However, if the config
609 does not support this, a local copy will be made and associated with
610 the dst bitmap. If the subset rectangle, intersected with the bitmap's
611 dimensions is empty, or if there is an unsupported config, false will be
612 returned and dst will be untouched.
613 @param dst The bitmap that will be set to a subset of this bitmap
614 @param subset The rectangle of pixels in this bitmap that dst will
615 reference.
616 @return true if the subset copy was successfully made.
617 */
618 bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
619
commit-bot@chromium.org8a2ad3c2014-02-23 03:59:35 +0000620 /** Makes a deep copy of this bitmap, respecting the requested colorType,
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000621 * and allocating the dst pixels on the cpu.
622 * Returns false if either there is an error (i.e. the src does not have
623 * pixels) or the request cannot be satisfied (e.g. the src has per-pixel
624 * alpha, and the requested config does not support alpha).
625 * @param dst The bitmap to be sized and allocated
commit-bot@chromium.org8a2ad3c2014-02-23 03:59:35 +0000626 * @param ct The desired colorType for dst
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000627 * @param allocator Allocator used to allocate the pixelref for the dst
628 * bitmap. If this is null, the standard HeapAllocator
629 * will be used.
commit-bot@chromium.org8a2ad3c2014-02-23 03:59:35 +0000630 * @return true if the copy was made.
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000631 */
commit-bot@chromium.org8a2ad3c2014-02-23 03:59:35 +0000632 bool copyTo(SkBitmap* dst, SkColorType ct, Allocator* = NULL) const;
633
634 bool copyTo(SkBitmap* dst, Allocator* allocator = NULL) const {
635 return this->copyTo(dst, this->colorType(), allocator);
636 }
637
638 /**
639 * Returns true if this bitmap's pixels can be converted into the requested
640 * colorType, such that copyTo() could succeed.
641 */
642 bool canCopyTo(SkColorType colorType) const;
reed@android.com89bb83a2009-05-29 21:30:42 +0000643
commit-bot@chromium.org6285f4f2014-02-20 19:08:07 +0000644 /** Makes a deep copy of this bitmap, keeping the copied pixels
645 * in the same domain as the source: If the src pixels are allocated for
646 * the cpu, then so will the dst. If the src pixels are allocated on the
647 * gpu (typically as a texture), the it will do the same for the dst.
648 * If the request cannot be fulfilled, returns false and dst is unmodified.
649 */
650 bool deepCopyTo(SkBitmap* dst) const;
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000651
commit-bot@chromium.orgeaca36b2014-05-07 15:05:34 +0000652#ifdef SK_SUPPORT_LEGACY_BUILDMIPMAP
reed@google.com44699382013-10-31 17:28:30 +0000653 SK_ATTR_DEPRECATED("use setFilterLevel on SkPaint")
commit-bot@chromium.orgeaca36b2014-05-07 15:05:34 +0000654 void buildMipMap(bool forceRebuild = false) {}
655#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000656
djsollen@google.com4bd2bdb2013-03-08 18:35:13 +0000657#ifdef SK_BUILD_FOR_ANDROID
658 bool hasHardwareMipMap() const {
659 return (fFlags & kHasHardwareMipMap_Flag) != 0;
660 }
661
662 void setHasHardwareMipMap(bool hasHardwareMipMap) {
663 if (hasHardwareMipMap) {
664 fFlags |= kHasHardwareMipMap_Flag;
665 } else {
666 fFlags &= ~kHasHardwareMipMap_Flag;
667 }
668 }
669#endif
670
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000671 bool extractAlpha(SkBitmap* dst) const {
672 return this->extractAlpha(dst, NULL, NULL, NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000673 }
674
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000675 bool extractAlpha(SkBitmap* dst, const SkPaint* paint,
djsollen@google.com57f49692011-02-23 20:46:31 +0000676 SkIPoint* offset) const {
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000677 return this->extractAlpha(dst, paint, NULL, offset);
djsollen@google.com57f49692011-02-23 20:46:31 +0000678 }
679
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000680 /** Set dst to contain alpha layer of this bitmap. If destination bitmap
681 fails to be initialized, e.g. because allocator can't allocate pixels
682 for it, dst will not be modified and false will be returned.
683
684 @param dst The bitmap to be filled with alpha layer
685 @param paint The paint to draw with
686 @param allocator Allocator used to allocate the pixelref for the dst
687 bitmap. If this is null, the standard HeapAllocator
688 will be used.
689 @param offset If not null, it is set to top-left coordinate to position
690 the returned bitmap so that it visually lines up with the
691 original
692 */
693 bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000694 SkIPoint* offset) const;
weita@google.comf9ab99a2009-05-03 18:23:30 +0000695
commit-bot@chromium.org968edca2014-05-23 13:21:55 +0000696#ifdef SK_SUPPORT_LEGACY_BITMAPFLATTEN
djsollen@google.com21830d92012-08-07 19:49:41 +0000697 /** The following two functions provide the means to both flatten and
698 unflatten the bitmap AND its pixels into the provided buffer.
699 It is recommended that you do not call these functions directly,
700 but instead call the write/readBitmap functions on the respective
701 buffers as they can optimize the recording process and avoid recording
702 duplicate bitmaps and pixelRefs.
703 */
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000704 void flatten(SkWriteBuffer&) const;
commit-bot@chromium.org968edca2014-05-23 13:21:55 +0000705#else
706private:
707#endif
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000708 void unflatten(SkReadBuffer&);
commit-bot@chromium.org968edca2014-05-23 13:21:55 +0000709public:
reed@android.com8a1c16f2008-12-17 15:59:43 +0000710
711 SkDEBUGCODE(void validate() const;)
712
713 class Allocator : public SkRefCnt {
714 public:
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +0000715 SK_DECLARE_INST_COUNT(Allocator)
716
reed@android.com8a1c16f2008-12-17 15:59:43 +0000717 /** Allocate the pixel memory for the bitmap, given its dimensions and
718 config. Return true on success, where success means either setPixels
719 or setPixelRef was called. The pixels need not be locked when this
720 returns. If the config requires a colortable, it also must be
721 installed via setColorTable. If false is returned, the bitmap and
722 colortable should be left unchanged.
723 */
724 virtual bool allocPixelRef(SkBitmap*, SkColorTable*) = 0;
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +0000725 private:
726 typedef SkRefCnt INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000727 };
728
729 /** Subclass of Allocator that returns a pixelref that allocates its pixel
730 memory from the heap. This is the default Allocator invoked by
731 allocPixels().
732 */
733 class HeapAllocator : public Allocator {
734 public:
reed@google.com9ebcac52014-01-24 18:53:42 +0000735 virtual bool allocPixelRef(SkBitmap*, SkColorTable*) SK_OVERRIDE;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000736 };
737
738 class RLEPixels {
739 public:
740 RLEPixels(int width, int height);
741 virtual ~RLEPixels();
weita@google.comf9ab99a2009-05-03 18:23:30 +0000742
reed@android.com8a1c16f2008-12-17 15:59:43 +0000743 uint8_t* packedAtY(int y) const {
744 SkASSERT((unsigned)y < (unsigned)fHeight);
745 return fYPtrs[y];
746 }
weita@google.comf9ab99a2009-05-03 18:23:30 +0000747
reed@android.com8a1c16f2008-12-17 15:59:43 +0000748 // called by subclasses during creation
749 void setPackedAtY(int y, uint8_t* addr) {
750 SkASSERT((unsigned)y < (unsigned)fHeight);
751 fYPtrs[y] = addr;
752 }
weita@google.comf9ab99a2009-05-03 18:23:30 +0000753
reed@android.com8a1c16f2008-12-17 15:59:43 +0000754 private:
755 uint8_t** fYPtrs;
756 int fHeight;
757 };
weita@google.comf9ab99a2009-05-03 18:23:30 +0000758
commit-bot@chromium.org0f10f7b2014-03-13 18:02:17 +0000759 SK_TO_STRING_NONVIRT()
robertphillips@google.com76f9e932013-01-15 20:17:47 +0000760
reed@android.com8a1c16f2008-12-17 15:59:43 +0000761private:
reed@android.com8a1c16f2008-12-17 15:59:43 +0000762 mutable SkPixelRef* fPixelRef;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000763 mutable int fPixelLockCount;
reed@google.com5f62ed72014-01-15 19:59:45 +0000764 // These are just caches from the locked pixelref
reed@android.com8a1c16f2008-12-17 15:59:43 +0000765 mutable void* fPixels;
766 mutable SkColorTable* fColorTable; // only meaningful for kIndex8
767
reed@google.com672588b2014-01-08 15:42:01 +0000768 SkIPoint fPixelRefOrigin;
769
reed@android.com8a1c16f2008-12-17 15:59:43 +0000770 enum Flags {
junov@chromium.orgb0521292011-12-15 20:14:06 +0000771 kImageIsOpaque_Flag = 0x01,
772 kImageIsVolatile_Flag = 0x02,
djsollen@google.com4bd2bdb2013-03-08 18:35:13 +0000773 kImageIsImmutable_Flag = 0x04,
774#ifdef SK_BUILD_FOR_ANDROID
775 /* A hint for the renderer responsible for drawing this bitmap
776 * indicating that it should attempt to use mipmaps when this bitmap
777 * is drawn scaled down.
778 */
779 kHasHardwareMipMap_Flag = 0x08,
780#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000781 };
782
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000783 SkImageInfo fInfo;
784
scroggo@google.come5f48242013-02-25 21:47:41 +0000785 uint32_t fRowBytes;
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000786
reed@android.com8a1c16f2008-12-17 15:59:43 +0000787 uint8_t fFlags;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000788
reed@google.com60d32352013-06-28 19:40:50 +0000789 void internalErase(const SkIRect&, U8CPU a, U8CPU r, U8CPU g, U8CPU b)const;
790
wjmaclean@chromium.org86bff1f2010-11-16 20:22:41 +0000791 /* Internal computations for safe size.
792 */
reed@google.com57212f92013-12-30 14:40:38 +0000793 static int64_t ComputeSafeSize64(Config config,
794 uint32_t width,
795 uint32_t height,
796 size_t rowBytes);
wjmaclean@chromium.org86bff1f2010-11-16 20:22:41 +0000797 static size_t ComputeSafeSize(Config config,
798 uint32_t width,
799 uint32_t height,
scroggo@google.com0ba4bf42013-02-25 16:02:36 +0000800 size_t rowBytes);
wjmaclean@chromium.org86bff1f2010-11-16 20:22:41 +0000801
reed@android.com8a1c16f2008-12-17 15:59:43 +0000802 /* Unreference any pixelrefs or colortables
803 */
804 void freePixels();
805 void updatePixelsFromRef() const;
commit-bot@chromium.org968edca2014-05-23 13:21:55 +0000806
807 static void WriteRawPixels(SkWriteBuffer*, const SkBitmap&);
808 static bool ReadRawPixels(SkReadBuffer*, SkBitmap*);
weita@google.comf9ab99a2009-05-03 18:23:30 +0000809
commit-bot@chromium.org968edca2014-05-23 13:21:55 +0000810 friend class SkBitmapSource; // unflatten
811 friend class SkReadBuffer; // unflatten, rawpixels
812 friend class SkWriteBuffer; // rawpixels
reed@google.com4a551d42013-06-26 21:28:10 +0000813 friend struct SkBitmapProcState;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000814};
815
commit-bot@chromium.orge3beb6b2014-04-07 19:34:38 +0000816class SkAutoLockPixels : SkNoncopyable {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000817public:
reed@google.com9c49bc32011-07-07 13:42:37 +0000818 SkAutoLockPixels(const SkBitmap& bm, bool doLock = true) : fBitmap(bm) {
819 fDidLock = doLock;
820 if (doLock) {
821 bm.lockPixels();
822 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000823 }
824 ~SkAutoLockPixels() {
reed@google.com9c49bc32011-07-07 13:42:37 +0000825 if (fDidLock) {
826 fBitmap.unlockPixels();
827 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000828 }
829
830private:
831 const SkBitmap& fBitmap;
reed@google.com9c49bc32011-07-07 13:42:37 +0000832 bool fDidLock;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000833};
mtklein@google.com0f6dc212013-11-18 20:55:29 +0000834//TODO(mtklein): uncomment when 71713004 lands and Chromium's fixed.
835//#define SkAutoLockPixels(...) SK_REQUIRE_LOCAL_VAR(SkAutoLockPixels)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000836
837/** Helper class that performs the lock/unlockColors calls on a colortable.
838 The destructor will call unlockColors(false) if it has a bitmap's colortable
839*/
commit-bot@chromium.orge3beb6b2014-04-07 19:34:38 +0000840class SkAutoLockColors : SkNoncopyable {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000841public:
842 /** Initialize with no bitmap. Call lockColors(bitmap) to lock bitmap's
843 colortable
844 */
845 SkAutoLockColors() : fCTable(NULL), fColors(NULL) {}
846 /** Initialize with bitmap, locking its colortable if present
847 */
848 explicit SkAutoLockColors(const SkBitmap& bm) {
849 fCTable = bm.getColorTable();
850 fColors = fCTable ? fCTable->lockColors() : NULL;
851 }
852 /** Initialize with a colortable (may be null)
853 */
854 explicit SkAutoLockColors(SkColorTable* ctable) {
855 fCTable = ctable;
856 fColors = ctable ? ctable->lockColors() : NULL;
857 }
858 ~SkAutoLockColors() {
859 if (fCTable) {
reed@google.com0a6151d2013-10-10 14:44:56 +0000860 fCTable->unlockColors();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000861 }
862 }
weita@google.comf9ab99a2009-05-03 18:23:30 +0000863
reed@android.com8a1c16f2008-12-17 15:59:43 +0000864 /** Return the currently locked colors, or NULL if no bitmap's colortable
865 is currently locked.
866 */
867 const SkPMColor* colors() const { return fColors; }
weita@google.comf9ab99a2009-05-03 18:23:30 +0000868
reed@android.com11344262009-07-08 20:09:23 +0000869 /** Locks the table and returns is colors (assuming ctable is not null) and
870 unlocks the previous table if one was present
871 */
872 const SkPMColor* lockColors(SkColorTable* ctable) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000873 if (fCTable) {
reed@google.com0a6151d2013-10-10 14:44:56 +0000874 fCTable->unlockColors();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000875 }
reed@android.com11344262009-07-08 20:09:23 +0000876 fCTable = ctable;
877 fColors = ctable ? ctable->lockColors() : NULL;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000878 return fColors;
879 }
880
reed@android.com11344262009-07-08 20:09:23 +0000881 const SkPMColor* lockColors(const SkBitmap& bm) {
882 return this->lockColors(bm.getColorTable());
883 }
884
reed@android.com8a1c16f2008-12-17 15:59:43 +0000885private:
886 SkColorTable* fCTable;
887 const SkPMColor* fColors;
888};
commit-bot@chromium.orge61a86c2013-11-18 16:03:59 +0000889#define SkAutoLockColors(...) SK_REQUIRE_LOCAL_VAR(SkAutoLockColors)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000890
891///////////////////////////////////////////////////////////////////////////////
892
893inline uint32_t* SkBitmap::getAddr32(int x, int y) const {
894 SkASSERT(fPixels);
reed@google.com69e64632014-03-14 20:48:05 +0000895 SkASSERT(4 == this->bytesPerPixel());
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000896 SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
reed@android.com8a1c16f2008-12-17 15:59:43 +0000897 return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2));
898}
899
900inline uint16_t* SkBitmap::getAddr16(int x, int y) const {
901 SkASSERT(fPixels);
reed@google.com69e64632014-03-14 20:48:05 +0000902 SkASSERT(2 == this->bytesPerPixel());
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000903 SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
reed@android.com8a1c16f2008-12-17 15:59:43 +0000904 return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1));
905}
906
907inline uint8_t* SkBitmap::getAddr8(int x, int y) const {
908 SkASSERT(fPixels);
reed@google.com69e64632014-03-14 20:48:05 +0000909 SkASSERT(1 == this->bytesPerPixel());
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000910 SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
reed@android.com8a1c16f2008-12-17 15:59:43 +0000911 return (uint8_t*)fPixels + y * fRowBytes + x;
912}
913
914inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const {
915 SkASSERT(fPixels);
reed@google.com69e64632014-03-14 20:48:05 +0000916 SkASSERT(kIndex_8_SkColorType == this->colorType());
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000917 SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
reed@android.com8a1c16f2008-12-17 15:59:43 +0000918 SkASSERT(fColorTable);
919 return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
920}
921
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000922///////////////////////////////////////////////////////////////////////////////
923//
924// Helpers until we can fully deprecate SkBitmap::Config
925//
926extern SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType);
927extern SkColorType SkBitmapConfigToColorType(SkBitmap::Config);
928
reed@android.com8a1c16f2008-12-17 15:59:43 +0000929#endif