• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#Topic Bitmap
2#Alias Bitmaps ##
3#Alias Bitmap_Reference ##
4
5#Class SkBitmap
6#Line # two-dimensional raster pixel array ##
7
8#Code
9#Populate
10##
11
12Bitmap describes a two-dimensional raster pixel array. Bitmap is built on
13Image_Info, containing integer width and height, Color_Type and Alpha_Type
14describing the pixel format, and Color_Space describing the range of colors.
15Bitmap points to Pixel_Ref, which describes the physical array of pixels.
16Image_Info bounds may be located anywhere fully inside Pixel_Ref bounds.
17
18Bitmap can be drawn using Canvas. Bitmap can be a drawing destination for Canvas
19draw member functions. Bitmap flexibility as a pixel container limits some
20optimizations available to the target platform.
21
22If pixel array is primarily read-only, use Image for better performance.
23If pixel array is primarily written to, use Surface for better performance.
24
25Declaring SkBitmap const prevents altering Image_Info: the Bitmap height, width,
26and so on cannot change. It does not affect Pixel_Ref: a caller may write its
27pixels. Declaring SkBitmap const affects Bitmap configuration, not its contents.
28
29Bitmap is not thread safe. Each thread must have its own copy of Bitmap fields,
30although threads may share the underlying pixel array.
31
32#Subtopic Row_Bytes
33#Line # interval from one row to the next ##
34Bitmap pixels may be contiguous, or may have a gap at the end of each row.
35Row_Bytes is the interval from one row to the next. Row_Bytes may be specified;
36sometimes passing zero will compute the Row_Bytes from the row width and the
37number of bytes in a pixel. Row_Bytes may be larger than the row requires. This
38is useful to position one or more Bitmaps within a shared pixel array.
39##
40
41# ------------------------------------------------------------------------------
42
43#Class Allocator
44#Line # abstract subclass of HeapAllocator ##
45#Code
46#Populate
47##
48
49Abstract subclass of HeapAllocator.
50
51# ------------------------------------------------------------------------------
52
53#Method virtual bool allocPixelRef(SkBitmap* bitmap) = 0
54#Line # allocates pixel memory ##
55#Populate
56
57#NoExample
58##
59
60#SeeAlso HeapAllocator
61
62##
63
64#Class Allocator ##
65
66# ------------------------------------------------------------------------------
67
68#Class HeapAllocator
69#Line # allocates pixel memory from heap ##
70
71#Code
72#Populate
73##
74
75Subclass of SkBitmap::Allocator that returns a Pixel_Ref that allocates its pixel
76memory from the heap. This is the default SkBitmap::Allocator invoked by
77allocPixels.
78
79# ------------------------------------------------------------------------------
80
81#Method bool allocPixelRef(SkBitmap* bitmap) override
82#Line # allocates pixel memory ##
83#Populate
84
85#Example
86    SkBitmap bitmap;
87    bitmap.setInfo(SkImageInfo::MakeN32(16, 16, kPremul_SkAlphaType));
88    SkDebugf("pixel address = %p\n", bitmap.getPixels());
89    SkBitmap::HeapAllocator stdalloc;
90    if (!stdalloc.allocPixelRef(&bitmap)) {
91        SkDebugf("pixel allocation failed\n");
92    } else {
93        SkDebugf("pixel address = %p\n", bitmap.getPixels());
94    }
95#StdOut
96#Volatile
97pixel address = (nil)
98pixel address = 0x560ddd0ac670
99##
100##
101
102#SeeAlso SkBitmap::Allocator tryAllocPixels
103
104##
105
106#Class HeapAllocator ##
107
108# ------------------------------------------------------------------------------
109
110#Method SkBitmap()
111
112#Line # constructs with default values ##
113#Populate
114
115#Example
116void draw(SkCanvas* canvas) {
117    const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"};
118    const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
119                            "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
120    SkBitmap bitmap;
121    for (int i = 0; i < 2; ++i) {
122       SkDebugf("width: %2d  height: %2d", bitmap.width(), bitmap.height());
123       SkDebugf("  color: k%s_SkColorType", colors[bitmap.colorType()]);
124       SkDebugf("  alpha: k%s_SkAlphaType\n", alphas[bitmap.alphaType()]);
125       bitmap.setInfo(SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType),
126                      0);
127    }
128}
129#StdOut
130width:  0  height:  0  color: kUnknown_SkColorType  alpha: kUnknown_SkAlphaType
131width: 25  height: 35  color: kRGBA_8888_SkColorType  alpha: kOpaque_SkAlphaType
132##
133##
134
135#SeeAlso setInfo
136
137##
138
139# ------------------------------------------------------------------------------
140
141#Method SkBitmap(const SkBitmap& src)
142
143#Line # shares ownership of pixels ##
144#Populate
145
146#Example
147void draw(SkCanvas* canvas) {
148    SkBitmap original;
149    if (original.tryAllocPixels(
150            SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) {
151        SkDebugf("original has pixels before copy: %s\n", original.getPixels() ? "true" : "false");
152        SkBitmap copy(original);
153        SkDebugf("original has pixels after copy: %s\n", original.getPixels() ? "true" : "false");
154        SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false");
155    }
156}
157#StdOut
158original has pixels before copy: true
159original has pixels after copy: true
160copy has pixels: true
161##
162##
163
164#SeeAlso setInfo setPixelRef setPixels swap
165
166##
167
168# ------------------------------------------------------------------------------
169
170#Method SkBitmap(SkBitmap&& src)
171
172#Line # takes ownership of pixels ##
173#Populate
174
175#Example
176void draw(SkCanvas* canvas) {
177    SkBitmap original;
178    if (original.tryAllocPixels(
179            SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) {
180        SkDebugf("original has pixels before move: %s\n", original.getPixels() ? "true" : "false");
181        SkBitmap copy(std::move(original));
182        SkDebugf("original has pixels after move: %s\n", original.getPixels() ? "true" : "false");
183        SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false");
184    }
185}
186#StdOut
187original has pixels before move: true
188original has pixels after move: false
189copy has pixels: true
190##
191##
192
193#SeeAlso setInfo setPixelRef setPixels swap
194
195##
196
197# ------------------------------------------------------------------------------
198
199#Method ~SkBitmap()
200
201#Line # releases ownership of pixels ##
202#Populate
203
204#NoExample
205##
206
207#SeeAlso Pixel_Ref
208
209##
210
211# ------------------------------------------------------------------------------
212
213#Method SkBitmap& operator=(const SkBitmap& src)
214
215#Line # shares ownership of pixels ##
216#Populate
217
218#Example
219void draw(SkCanvas* canvas) {
220    SkBitmap original;
221    if (original.tryAllocPixels(
222            SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) {
223        SkDebugf("original has pixels before copy: %s\n", original.getPixels() ? "true" : "false");
224        SkBitmap copy = original;
225        SkDebugf("original has pixels after copy: %s\n", original.getPixels() ? "true" : "false");
226        SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false");
227    }
228}
229#StdOut
230original has pixels before copy: true
231original has pixels after copy: true
232copy has pixels: true
233##
234##
235
236#SeeAlso setInfo setPixelRef setPixels swap
237
238##
239
240# ------------------------------------------------------------------------------
241
242#Method SkBitmap& operator=(SkBitmap&& src)
243
244#Line # takes ownership of pixels ##
245#Populate
246
247#Example
248void draw(SkCanvas* canvas) {
249    SkBitmap original;
250    if (original.tryAllocPixels(
251            SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) {
252        SkDebugf("original has pixels before move: %s\n", original.getPixels() ? "true" : "false");
253        SkBitmap copy = std::move(original);
254        SkDebugf("original has pixels after move: %s\n", original.getPixels() ? "true" : "false");
255        SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false");
256    }
257}
258#StdOut
259original has pixels before move: true
260original has pixels after move: false
261copy has pixels: true
262##
263##
264
265#SeeAlso setInfo setPixelRef setPixels swap
266
267##
268
269# ------------------------------------------------------------------------------
270
271#Method void swap(SkBitmap& other)
272#In Utility
273#Line # exchanges Bitmap pair ##
274#Populate
275
276#Example
277void draw(SkCanvas* canvas) {
278    auto debugster = [](const char* prefix, const SkBitmap& b) -> void {
279        const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"};
280        const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
281                                "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
282        SkDebugf("%s width:%d height:%d colorType:k%s_SkColorType alphaType:k%s_SkAlphaType\n",
283                 prefix, b.width(), b.height(), colors[b.colorType()], alphas[b.alphaType()]);
284    };
285    SkBitmap one, two;
286    if (!one.tryAllocPixels(
287            SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) {
288        return;
289    }
290    if (!two.tryAllocPixels(
291            SkImageInfo::Make(2, 2, kBGRA_8888_SkColorType, kPremul_SkAlphaType))) {
292        return;
293    }
294    for (int index = 0; index < 2; ++index) {
295       debugster("one", one);
296       debugster("two", two);
297       one.swap(two);
298    }
299}
300#StdOut
301one width:1 height:1 colorType:kRGBA_8888_SkColorType alphaType:kOpaque_SkAlphaType
302two width:2 height:2 colorType:kBGRA_8888_SkColorType alphaType:kPremul_SkAlphaType
303one width:2 height:2 colorType:kBGRA_8888_SkColorType alphaType:kPremul_SkAlphaType
304two width:1 height:1 colorType:kRGBA_8888_SkColorType alphaType:kOpaque_SkAlphaType
305##
306##
307
308#SeeAlso SkBitmap(SkBitmap&& src) operator=(SkBitmap&& src)
309
310##
311
312# ------------------------------------------------------------------------------
313#Subtopic Property
314#Line # metrics and attributes ##
315##
316
317#Method const SkPixmap& pixmap() const
318#In Property
319#Line # returns Pixmap ##
320#Populate
321
322#Example
323    SkBitmap bitmap;
324    bitmap.allocPixels(SkImageInfo::MakeN32Premul(10, 11));
325    SkCanvas offscreen(bitmap);
326    offscreen.clear(SK_ColorWHITE);
327    SkPaint paint;
328    offscreen.drawString("&", 0, 10, paint);
329    const SkPixmap& pixmap = bitmap.pixmap();
330    if (pixmap.addr()) {
331        SkPMColor pmWhite = *pixmap.addr32(0, 0);
332        for (int y = 0; y < pixmap.height(); ++y) {
333            for (int x = 0; x < pixmap.width(); ++x) {
334                SkDebugf("%c", *pixmap.addr32(x, y) == pmWhite ? '-' : 'x');
335            }
336            SkDebugf("\n");
337        }
338    }
339    #StdOut
340----------
341---xx-----
342--x--x----
343--x-------
344--xx------
345--x-x---x-
346-x---x--x-
347-x----xx--
348-xx---x---
349--xxxx-xx-
350----------
351    #StdOut ##
352
353##
354
355#SeeAlso peekPixels installPixels readPixels writePixels
356
357##
358
359# ------------------------------------------------------------------------------
360
361#Method const SkImageInfo& info() const
362#In Property
363#Line # returns Image_Info ##
364#Populate
365
366#Example
367#Image 4
368void draw(SkCanvas* canvas) {
369    // SkBitmap source;  // pre-populated with soccer ball by fiddle.skia.org
370    const SkImageInfo& info = source.info();
371    const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"};
372    const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
373                            "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
374    SkDebugf("width: %d height: %d color: %s alpha: %s\n", info.width(), info.height(),
375                colors[info.colorType()], alphas[info.alphaType()]);
376#StdOut
377width: 56 height: 56 color: BGRA_8888 alpha: Opaque
378##
379}
380##
381
382#SeeAlso Image_Info
383
384##
385
386# ------------------------------------------------------------------------------
387
388#Method int width() const
389#In Property
390#Line # returns pixel column count ##
391Returns pixel count in each row. Should be equal or less than
392#Formula # rowBytes() / info().bytesPerPixel() ##.
393
394May be less than pixelRef().width(). Will not exceed pixelRef().width() less
395pixelRefOrigin().fX.
396
397#Return  pixel width in Image_Info ##
398
399#Example
400    SkImageInfo info = SkImageInfo::MakeA8(16, 32);
401    SkBitmap bitmap;
402    bitmap.setInfo(info);
403    SkDebugf("bitmap width: %d  info width: %d\n", bitmap.width(), info.width());
404#StdOut
405bitmap width: 16  info width: 16
406##
407##
408
409#SeeAlso height() SkPixelRef::width() SkImageInfo::width()
410
411##
412
413# ------------------------------------------------------------------------------
414
415#Method int height() const
416#In Property
417#Line # returns pixel row count ##
418#Populate
419
420#Example
421    SkImageInfo info = SkImageInfo::MakeA8(16, 32);
422    SkBitmap bitmap;
423    bitmap.setInfo(info);
424    SkDebugf("bitmap height: %d  info height: %d\n", bitmap.height(), info.height());
425#StdOut
426bitmap height: 32  info height: 32
427##
428##
429
430#SeeAlso width() SkPixelRef::height() SkImageInfo::height()
431
432##
433
434# ------------------------------------------------------------------------------
435
436#Method SkColorType colorType() const
437#In Property
438#Line # returns Image_Info Color_Type ##
439Returns Color_Type, one of: #list_of_color_types#.
440
441#Return  Color_Type in Image_Info ##
442
443#Example
444    const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
445                            "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
446    SkBitmap bitmap;
447    bitmap.setInfo(SkImageInfo::MakeA8(16, 32));
448    SkDebugf("color type: k" "%s" "_SkColorType\n", colors[bitmap.colorType()]);
449#StdOut
450color type: kAlpha_8_SkColorType
451##
452##
453
454#SeeAlso alphaType() SkImageInfo::colorType
455
456##
457
458# ------------------------------------------------------------------------------
459
460#Method SkAlphaType alphaType() const
461#In Property
462#Line # returns Image_Info Alpha_Type ##
463Returns Alpha_Type, one of: #list_of_alpha_types#.
464
465#Return  Alpha_Type in Image_Info ##
466
467#Example
468    const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"};
469    SkPixmap pixmap(SkImageInfo::MakeA8(16, 32), nullptr, 64);
470    SkDebugf("alpha type: k" "%s" "_SkAlphaType\n", alphas[pixmap.alphaType()]);
471#StdOut
472alpha type: kPremul_SkAlphaType
473##
474##
475
476#SeeAlso colorType() SkImageInfo::alphaType
477
478##
479
480# ------------------------------------------------------------------------------
481
482#Method SkColorSpace* colorSpace() const
483#In Property
484#Line # returns Image_Info Color_Space ##
485#Populate
486
487#Example
488#Description
489SkColorSpace::MakeSRGBLinear creates Color_Space with linear gamma
490and an sRGB gamut. This Color_Space gamma is not close to sRGB gamma.
491##
492    SkBitmap bitmap;
493    bitmap.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType,
494            SkColorSpace::MakeSRGBLinear()));
495    SkColorSpace* colorSpace = bitmap.colorSpace();
496    SkDebugf("gammaCloseToSRGB: %s  gammaIsLinear: %s  isSRGB: %s\n",
497            colorSpace->gammaCloseToSRGB() ? "true" : "false",
498            colorSpace->gammaIsLinear() ? "true" : "false",
499            colorSpace->isSRGB() ? "true" : "false");
500#StdOut
501gammaCloseToSRGB: false  gammaIsLinear: true  isSRGB: false
502##
503##
504
505#SeeAlso Color_Space SkImageInfo::colorSpace
506
507##
508
509# ------------------------------------------------------------------------------
510
511#Method sk_sp<SkColorSpace> refColorSpace() const
512#In Property
513#Line # returns Image_Info Color_Space ##
514#Populate
515
516#Example
517    SkBitmap bitmap1, bitmap2;
518    bitmap1.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType,
519            SkColorSpace::MakeSRGBLinear()));
520    bitmap2.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType,
521            bitmap1.refColorSpace()));
522    SkColorSpace* colorSpace = bitmap2.colorSpace();
523    SkDebugf("gammaCloseToSRGB: %s  gammaIsLinear: %s  isSRGB: %s\n",
524            colorSpace->gammaCloseToSRGB() ? "true" : "false",
525            colorSpace->gammaIsLinear() ? "true" : "false",
526            colorSpace->isSRGB() ? "true" : "false");
527#StdOut
528gammaCloseToSRGB: false  gammaIsLinear: true  isSRGB: false
529##
530##
531
532#SeeAlso Color_Space SkImageInfo::colorSpace
533
534##
535
536# ------------------------------------------------------------------------------
537
538#Method int bytesPerPixel() const
539#In Property
540#Line # returns number of bytes in pixel based on Color_Type ##
541#Populate
542
543#Example
544    const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
545                            "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
546    SkImageInfo info = SkImageInfo::MakeA8(1, 1);
547    SkBitmap bitmap;
548    for (SkColorType colorType : { #list_of_color_types#
549                                 } ) {
550        bitmap.setInfo(info.makeColorType(colorType));
551        SkDebugf("color: k" "%s" "_SkColorType" "%*s" "bytesPerPixel: %d\n",
552                colors[colorType], 13 - strlen(colors[colorType]), " ",
553                bitmap.bytesPerPixel());
554    }
555#StdOut
556color: kUnknown_SkColorType      bytesPerPixel: 0
557color: kAlpha_8_SkColorType      bytesPerPixel: 1
558color: kRGB_565_SkColorType      bytesPerPixel: 2
559color: kARGB_4444_SkColorType    bytesPerPixel: 2
560color: kRGBA_8888_SkColorType    bytesPerPixel: 4
561color: kRGB_888x_SkColorType     bytesPerPixel: 4
562color: kBGRA_8888_SkColorType    bytesPerPixel: 4
563color: kRGBA_1010102_SkColorType bytesPerPixel: 4
564color: kRGB_101010x_SkColorType  bytesPerPixel: 4
565color: kGray_8_SkColorType       bytesPerPixel: 1
566color: kRGBA_F16_SkColorType     bytesPerPixel: 8
567##
568##
569
570#SeeAlso rowBytes rowBytesAsPixels width shiftPerPixel SkImageInfo::bytesPerPixel
571
572##
573
574# ------------------------------------------------------------------------------
575
576#Method int rowBytesAsPixels() const
577#In Property
578#Line # returns interval between rows in pixels ##
579#Populate
580
581#Example
582    SkBitmap bitmap;
583    for (int rowBytes : { 4, 5, 6, 7, 8} ) {
584        bitmap.setInfo(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType), rowBytes);
585        SkDebugf("rowBytes: %d rowBytesAsPixels: %d\n", rowBytes, bitmap.rowBytesAsPixels());
586    }
587#StdOut
588rowBytes: 4 rowBytesAsPixels: 1
589rowBytes: 5 rowBytesAsPixels: 1
590rowBytes: 6 rowBytesAsPixels: 1
591rowBytes: 7 rowBytesAsPixels: 1
592rowBytes: 8 rowBytesAsPixels: 2
593##
594##
595
596#SeeAlso rowBytes shiftPerPixel width bytesPerPixel
597
598##
599
600# ------------------------------------------------------------------------------
601
602#Method int shiftPerPixel() const
603#In Property
604#Line # returns bit shift from pixels to bytes ##
605#Populate
606
607#Example
608    const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
609                            "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
610    SkImageInfo info = SkImageInfo::MakeA8(1, 1);
611    SkBitmap bitmap;
612    for (SkColorType colorType : { #list_of_color_types#
613                                 } ) {
614        bitmap.setInfo(info.makeColorType(colorType));
615        SkDebugf("color: k" "%s" "_SkColorType" "%*s" "shiftPerPixel: %d\n",
616                colors[colorType], 14 - strlen(colors[colorType]), " ",
617                bitmap.shiftPerPixel());
618    }
619#StdOut
620color: kUnknown_SkColorType       shiftPerPixel: 0
621color: kAlpha_8_SkColorType       shiftPerPixel: 0
622color: kRGB_565_SkColorType       shiftPerPixel: 1
623color: kARGB_4444_SkColorType     shiftPerPixel: 1
624color: kRGBA_8888_SkColorType     shiftPerPixel: 2
625color: kRGB_888x_SkColorType      shiftPerPixel: 2
626color: kBGRA_8888_SkColorType     shiftPerPixel: 2
627color: kRGBA_1010102_SkColorType  shiftPerPixel: 2
628color: kRGB_101010x_SkColorType   shiftPerPixel: 2
629color: kGray_8_SkColorType        shiftPerPixel: 0
630color: kRGBA_F16_SkColorType      shiftPerPixel: 3
631##
632##
633
634#SeeAlso rowBytes rowBytesAsPixels width bytesPerPixel
635
636##
637
638# ------------------------------------------------------------------------------
639
640#Method bool empty() const
641#In Property
642#Line # returns true if Image_Info has zero width() or height() ##
643#Populate
644
645#Example
646    SkBitmap bitmap;
647    for (int width : { 0, 2 } ) {
648        for (int height : { 0, 2 } ) {
649             bitmap.setInfo(SkImageInfo::MakeA8(width, height));
650             SkDebugf("width: %d height: %d empty: %s\n", width, height,
651                      bitmap.empty() ? "true" : "false");
652        }
653    }
654#StdOut
655width: 0 height: 0 empty: true
656width: 0 height: 2 empty: true
657width: 2 height: 0 empty: true
658width: 2 height: 2 empty: false
659##
660##
661
662#SeeAlso height() width() drawsNothing
663
664##
665
666# ------------------------------------------------------------------------------
667
668#Method bool isNull() const
669#In Property
670#Line # returns true if Pixel_Ref is nullptr ##
671#Populate
672
673#Example
674    SkBitmap bitmap;
675    SkDebugf("empty bitmap does %shave pixels\n", bitmap.isNull() ? "not " : "");
676    bitmap.setInfo(SkImageInfo::MakeA8(8, 8));
677    SkDebugf("bitmap with dimensions does %shave pixels\n", bitmap.isNull() ? "not " : "");
678    bitmap.allocPixels();
679    SkDebugf("allocated bitmap does %shave pixels\n", bitmap.isNull() ? "not " : "");
680#StdOut
681empty bitmap does not have pixels
682bitmap with dimensions does not have pixels
683allocated bitmap does have pixels
684##
685##
686
687#SeeAlso empty() drawsNothing pixelRef
688
689##
690
691# ------------------------------------------------------------------------------
692
693#Method bool drawsNothing() const
694#In Property
695#Line # returns true if no width(), no height(), or no Pixel_Ref ##
696#Populate
697
698#Example
699    SkBitmap bitmap;
700    for (int w : { 0, 8 } ) {
701        for (bool allocate : { false, true} ) {
702            bitmap.setInfo(SkImageInfo::MakeA8(w, 8));
703            allocate ? bitmap.allocPixels() : (void) 0 ;
704            SkDebugf("empty:%s isNull:%s drawsNothing:%s\n", bitmap.empty() ? "true " : "false",
705                     bitmap.isNull() ? "true " : "false", bitmap.drawsNothing() ? "true" : "false");
706        }
707    }
708#StdOut
709empty:true  isNull:true  drawsNothing:true
710empty:true  isNull:false drawsNothing:true
711empty:false isNull:true  drawsNothing:true
712empty:false isNull:false drawsNothing:false
713##
714##
715
716#SeeAlso empty() isNull pixelRef
717
718##
719
720# ------------------------------------------------------------------------------
721
722#Method size_t rowBytes() const
723#In Property
724#Line # returns interval between rows in bytes ##
725Returns row bytes, the interval from one pixel row to the next. Row bytes
726is at least as large as: #Formula # width() * info().bytesPerPixel() ##.
727
728Returns zero if colorType is kUnknown_SkColorType, or if row bytes supplied to
729setInfo is not large enough to hold a row of pixels.
730
731#Return  byte length of pixel row ##
732
733#Example
734   SkBitmap bitmap;
735   for (int rowBytes : { 2, 8 } ) {
736       bool result = bitmap.setInfo(SkImageInfo::MakeA8(4, 4), rowBytes);
737       SkDebugf("setInfo returned:%s rowBytes:%d\n", result ? "true " : "false", bitmap.rowBytes());
738    }
739#StdOut
740setInfo returned:false rowBytes:0
741setInfo returned:true  rowBytes:8
742##
743##
744
745#SeeAlso info() setInfo SkImageInfo::minRowBytes
746
747##
748
749# ------------------------------------------------------------------------------
750
751#Method bool setAlphaType(SkAlphaType alphaType)
752#In Set
753#Line # sets Alpha_Type of shared pixels ##
754#Populate
755
756#Example
757void draw(SkCanvas* canvas) {
758    const char* colors[] = { "Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
759                             "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16" };
760    const char* alphas[] = {"Unknown ", "Opaque  ", "Premul  ", "Unpremul"};
761    SkBitmap bitmap;
762    SkAlphaType alphaTypes[] = { #list_of_alpha_types#
763                               };
764    SkDebugf("%18s%15s%17s%18s%19s\n", "Canonical", "Unknown", "Opaque", "Premul", "Unpremul");
765    for (SkColorType colorType : { #list_of_color_types#
766                                 } ) {
767        for (SkAlphaType canonicalAlphaType : alphaTypes) {
768            SkColorTypeValidateAlphaType(colorType, kUnknown_SkAlphaType, &canonicalAlphaType );
769            SkDebugf("%12s %9s  ", colors[(int) colorType], alphas[(int) canonicalAlphaType ]);
770            for (SkAlphaType alphaType : alphaTypes) {
771                bitmap.setInfo(SkImageInfo::Make(4, 4, colorType, canonicalAlphaType));
772                bool result = bitmap.setAlphaType(alphaType);
773                SkDebugf("%s %s    ", result ? "true " : "false", alphas[(int) bitmap.alphaType()]);
774            }
775            SkDebugf("\n");
776        }
777    }
778}
779##
780
781#SeeAlso Alpha_Type Color_Type Image_Info setInfo
782
783##
784
785# ------------------------------------------------------------------------------
786
787#Method void* getPixels() const
788#In Property
789#Line # returns address of pixels ##
790#Populate
791
792#Example
793    SkBitmap bitmap;
794    bitmap.setInfo(SkImageInfo::MakeN32(4, 4, kPremul_SkAlphaType));
795    bitmap.allocPixels();
796    bitmap.eraseColor(0x00000000);
797    void* baseAddr = bitmap.getPixels();
798    *(SkPMColor*)baseAddr = 0xFFFFFFFF;
799    SkDebugf("bitmap.getColor(0, 1) %c= 0x00000000\n",
800              bitmap.getColor(0, 1)  == 0x00000000 ? '=' : '!');
801    SkDebugf("bitmap.getColor(0, 0) %c= 0xFFFFFFFF\n",
802              bitmap.getColor(0, 0)  == 0xFFFFFFFF ? '=' : '!');
803#StdOut
804bitmap.getColor(0, 1) == 0x00000000
805bitmap.getColor(0, 0) == 0xFFFFFFFF
806##
807##
808
809#SeeAlso isNull drawsNothing
810
811##
812
813# ------------------------------------------------------------------------------
814
815#Method size_t computeByteSize() const
816#In Utility
817#Line # returns size required for pixels ##
818#Populate
819
820#Example
821    SkBitmap bitmap;
822    for (int width : { 1, 1000, 1000000 } ) {
823        for (int height: { 1, 1000, 1000000 } ) {
824            SkImageInfo imageInfo = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType);
825            bitmap.setInfo(imageInfo, width * 5);
826            SkDebugf("width: %7d height: %7d computeByteSize: %13lld\n", width, height,
827                     bitmap.computeByteSize());
828        }
829    }
830#StdOut
831width:       1 height:       1 computeByteSize:             4
832width:       1 height:    1000 computeByteSize:          4999
833width:       1 height: 1000000 computeByteSize:       4999999
834width:    1000 height:       1 computeByteSize:          4000
835width:    1000 height:    1000 computeByteSize:       4999000
836width:    1000 height: 1000000 computeByteSize:    4999999000
837width: 1000000 height:       1 computeByteSize:       4000000
838width: 1000000 height:    1000 computeByteSize:    4999000000
839width: 1000000 height: 1000000 computeByteSize: 4999999000000
840##
841##
842
843#SeeAlso SkImageInfo::computeByteSize
844
845##
846
847# ------------------------------------------------------------------------------
848
849#Method bool isImmutable() const
850#In Property
851#Line # returns true if pixels will not change ##
852#Populate
853
854#Example
855    SkBitmap original;
856    SkImageInfo info = SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
857    if (original.tryAllocPixels(info)) {
858        original.setImmutable();
859        SkBitmap copy;
860        original.extractSubset(&copy, {5, 10, 15, 20});
861        SkDebugf("original is " "%s" "immutable\n", original.isImmutable() ? "" : "not ");
862        SkDebugf("copy is " "%s" "immutable\n", copy.isImmutable() ? "" : "not ");
863    }
864#StdOut
865original is immutable
866copy is immutable
867##
868##
869
870#SeeAlso setImmutable SkPixelRef::isImmutable SkImage
871
872##
873
874# ------------------------------------------------------------------------------
875
876#Method void setImmutable()
877#In Set
878#Line # marks that pixels will not change ##
879#Populate
880
881#Example
882#Description
883Triggers assert if SK_DEBUG is true, runs fine otherwise.
884##
885    SkBitmap bitmap;
886    bitmap.setInfo(SkImageInfo::MakeN32(4, 4, kPremul_SkAlphaType));
887    bitmap.allocPixels();
888    SkCanvas offscreen(bitmap);
889    SkDebugf("draw white\n");
890    offscreen.clear(SK_ColorWHITE);
891    bitmap.setImmutable();
892    SkDebugf("draw black\n");
893    offscreen.clear(SK_ColorBLACK);
894##
895
896#SeeAlso isImmutable SkPixelRef::setImmutable SkImage
897
898##
899
900# ------------------------------------------------------------------------------
901
902#Method bool isOpaque() const
903#In Property
904#Line # returns true if Image_Info describes opaque pixels ##
905#Populate
906
907#Example
908#Description
909    isOpaque ignores whether all pixels are opaque or not.
910##
911    const int height = 2;
912    const int width = 2;
913    SkBitmap bitmap;
914    bitmap.setInfo(SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType));
915    for (int index = 0; index < 2; ++index) {
916        bitmap.allocPixels();
917        bitmap.eraseColor(0x00000000);
918        SkDebugf("isOpaque: %s\n", bitmap.isOpaque() ? "true" : "false");
919        bitmap.eraseColor(0xFFFFFFFF);
920        SkDebugf("isOpaque: %s\n", bitmap.isOpaque() ? "true" : "false");
921        bitmap.setInfo(bitmap.info().makeAlphaType(kOpaque_SkAlphaType));
922    }
923#StdOut
924isOpaque: false
925isOpaque: false
926isOpaque: true
927isOpaque: true
928##
929##
930
931#SeeAlso ComputeIsOpaque SkImageInfo::isOpaque
932
933##
934
935# ------------------------------------------------------------------------------
936
937#Method bool isVolatile() const
938#In Property
939#Line # returns true if pixels should not be cached ##
940#Populate
941
942#Example
943    SkBitmap original;
944    SkImageInfo info = SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
945    if (original.tryAllocPixels(info)) {
946        original.setIsVolatile(true);
947        SkBitmap copy;
948        original.extractSubset(&copy, {5, 10, 15, 20});
949        SkDebugf("original is " "%s" "volatile\n", original.isVolatile() ? "" : "not ");
950        SkDebugf("copy is " "%s" "volatile\n", copy.isImmutable() ? "" : "not ");
951    }
952#StdOut
953original is volatile
954copy is not volatile
955##
956##
957
958#SeeAlso setIsVolatile
959
960##
961
962# ------------------------------------------------------------------------------
963
964#Method void setIsVolatile(bool isVolatile)
965#In Set
966#Line # marks if pixels should not be cached ##
967#Populate
968
969#Example
970#Height 20
971    SkBitmap bitmap;
972    bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
973    bitmap.allocPixels();
974    bitmap.eraseColor(SK_ColorRED);
975    canvas->scale(16, 16);
976    canvas->drawBitmap(bitmap, 0, 0);
977    *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorBLUE);
978    canvas->drawBitmap(bitmap, 2, 0);
979    bitmap.setIsVolatile(true);
980    *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorGREEN);
981    canvas->drawBitmap(bitmap, 4, 0);
982##
983
984#SeeAlso isVolatile
985
986##
987
988# ------------------------------------------------------------------------------
989
990#Method void reset()
991#In Constructors
992#Line # sets to default values, releases pixel ownership ##
993#Populate
994
995#Example
996    SkBitmap bitmap;
997    bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
998    bitmap.allocPixels();
999    SkDebugf("width:%d height:%d isNull:%s\n", bitmap.width(), bitmap.height(),
1000             bitmap.isNull() ? "true" : "false");
1001    bitmap.reset();
1002    SkDebugf("width:%d height:%d isNull:%s\n", bitmap.width(), bitmap.height(),
1003             bitmap.isNull() ? "true" : "false");
1004#StdOut
1005width:1 height:1 isNull:false
1006width:0 height:0 isNull:true
1007##
1008##
1009
1010#SeeAlso SkBitmap() SkAlphaType SkColorType
1011
1012##
1013
1014# ------------------------------------------------------------------------------
1015
1016#Method static bool ComputeIsOpaque(const SkBitmap& bm)
1017#In Utility
1018#Line # returns true if all pixels are opaque ##
1019#Populate
1020
1021#Example
1022    SkBitmap bitmap;
1023    bitmap.setInfo(SkImageInfo::Make(2, 2, kN32_SkColorType, kPremul_SkAlphaType));
1024    for (int index = 0; index < 2; ++index) {
1025        bitmap.allocPixels();
1026        bitmap.eraseColor(0x00000000);
1027        SkDebugf("computeIsOpaque: %s\n", SkBitmap::ComputeIsOpaque(bitmap) ? "true" : "false");
1028        bitmap.eraseColor(0xFFFFFFFF);
1029        SkDebugf("computeIsOpaque: %s\n", SkBitmap::ComputeIsOpaque(bitmap) ? "true" : "false");
1030        bitmap.setInfo(bitmap.info().makeAlphaType(kOpaque_SkAlphaType));
1031    }
1032#StdOut
1033computeIsOpaque: false
1034computeIsOpaque: true
1035computeIsOpaque: false
1036computeIsOpaque: true
1037##
1038##
1039
1040#SeeAlso isOpaque Color_Type Alpha
1041
1042##
1043
1044# ------------------------------------------------------------------------------
1045
1046#Method void getBounds(SkRect* bounds) const
1047#In Property
1048#Line # returns width() and height() as Rectangle ##
1049#Populate
1050
1051#Example
1052#Height 160
1053#Image 3
1054    SkRect bounds;
1055    source.getBounds(&bounds);
1056    bounds.offset(100, 100);
1057    SkPaint paint;
1058    paint.setColor(SK_ColorGRAY);
1059    canvas->scale(.25f, .25f);
1060    canvas->drawRect(bounds, paint);
1061    canvas->drawBitmap(source, 40, 40);
1062##
1063
1064#SeeAlso bounds()
1065
1066##
1067
1068# ------------------------------------------------------------------------------
1069
1070#Method void getBounds(SkIRect* bounds) const
1071#Populate
1072
1073#Example
1074#Image 3
1075    SkIRect bounds;
1076    source.getBounds(&bounds);
1077    bounds.inset(100, 100);
1078    SkBitmap bitmap;
1079    source.extractSubset(&bitmap, bounds);
1080    canvas->scale(.5f, .5f);
1081    canvas->drawBitmap(bitmap, 10, 10);
1082##
1083
1084#SeeAlso bounds()
1085
1086##
1087
1088# ------------------------------------------------------------------------------
1089
1090#Method SkIRect bounds() const
1091#In Property
1092#Line # returns width() and height() as Rectangle ##
1093#Populate
1094
1095#Example
1096#Height 64
1097#Image 4
1098    canvas->scale(.5f, .5f);
1099    SkIRect bounds = source.bounds();
1100    for (int x : { 0, bounds.width() } ) {
1101        for (int y : { 0, bounds.height() } ) {
1102            canvas->drawBitmap(source, x, y);
1103        }
1104    }
1105##
1106
1107#SeeAlso getBounds
1108
1109##
1110
1111# ------------------------------------------------------------------------------
1112
1113#Method SkISize dimensions() const
1114#In Property
1115#Line # returns width() and height() ##
1116#Populate
1117
1118#Example
1119    SkBitmap bitmap;
1120    bitmap.setInfo(SkImageInfo::MakeN32(33, 55, kOpaque_SkAlphaType));
1121    SkISize dimensions = bitmap.dimensions();
1122    SkRect bounds;
1123    bitmap.getBounds(&bounds);
1124    SkRect dimensionsAsBounds = SkRect::Make(dimensions);
1125    SkDebugf("dimensionsAsBounds %c= bounds\n", dimensionsAsBounds == bounds ? '=' : '!');
1126##
1127
1128#SeeAlso height width
1129
1130##
1131
1132# ------------------------------------------------------------------------------
1133
1134#Method SkIRect getSubset() const
1135#In Property
1136#Line # returns bounds offset by origin ##
1137#Populate
1138
1139#Example
1140#Image 3
1141    SkIRect bounds;
1142    source.getBounds(&bounds);
1143    bounds.inset(100, 100);
1144    SkBitmap subset;
1145    source.extractSubset(&subset, bounds);
1146    SkIRect r = source.getSubset();
1147    SkDebugf("source: %d, %d, %d, %d\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
1148    r = subset.getSubset();
1149    SkDebugf("subset: %d, %d, %d, %d\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
1150#StdOut
1151source: 0, 0, 512, 512
1152subset: 100, 100, 412, 412
1153##
1154##
1155
1156#SeeAlso extractSubset getBounds
1157
1158##
1159
1160# ------------------------------------------------------------------------------
1161
1162#Method bool setInfo(const SkImageInfo& imageInfo, size_t rowBytes = 0)
1163#In Set
1164#Line # sets height, width, Color_Type, and so on, releasing pixels ##
1165Sets width, height, Alpha_Type, Color_Type, Color_Space, and optional
1166rowBytes. Frees pixels, and returns true if successful.
1167
1168imageInfo.alphaType() may be altered to a value permitted by imageInfo.colorSpace().
1169If imageInfo.colorType() is kUnknown_SkColorType, imageInfo.alphaType() is
1170set to kUnknown_SkAlphaType.
1171If imageInfo.colorType() is kAlpha_8_SkColorType and imageInfo.alphaType() is
1172kUnpremul_SkAlphaType, imageInfo.alphaType() is replaced by kPremul_SkAlphaType.
1173If imageInfo.colorType() is kRGB_565_SkColorType or kGray_8_SkColorType,
1174imageInfo.alphaType() is set to kOpaque_SkAlphaType.
1175If imageInfo.colorType() is kARGB_4444_SkColorType, kRGBA_8888_SkColorType,
1176kBGRA_8888_SkColorType, or kRGBA_F16_SkColorType: imageInfo.alphaType() remains
1177unchanged.
1178
1179rowBytes must equal or exceed imageInfo.minRowBytes(). If imageInfo.colorSpace() is
1180kUnknown_SkColorType, rowBytes is ignored and treated as zero; for all other
1181Color_Space values, rowBytes of zero is treated as imageInfo.minRowBytes().
1182
1183Calls reset() and returns false if:
1184#List
1185# rowBytes exceeds 31 bits ##
1186# imageInfo.width() is negative ##
1187# imageInfo.height() is negative ##
1188# rowBytes is positive and less than imageInfo.width() times imageInfo.bytesPerPixel() ##
1189##
1190
1191#Param imageInfo  contains width, height, Alpha_Type, Color_Type, Color_Space ##
1192#Param rowBytes   imageInfo.minRowBytes() or larger; or zero ##
1193
1194#Return  true if Image_Info set successfully ##
1195
1196#Example
1197#Height 96
1198###^
1199SkBitmap bitmap;
1200bitmap.setInfo(SkImageInfo::MakeN32(44, 16, kOpaque_SkAlphaType));
1201bitmap.allocPixels();
1202bitmap.eraseColor(SK_ColorGREEN);
1203SkCanvas offscreen(bitmap);
1204SkPaint paint;
1205offscreen.drawString("!@#$%", 0, 12, paint);
1206canvas->scale(6, 6);
1207canvas->drawBitmap(bitmap, 0, 0);
1208^^^#
1209##
1210
1211#SeeAlso Alpha_Type Color_Type Color_Space height rowBytes width
1212
1213##
1214
1215# ------------------------------------------------------------------------------
1216
1217#Enum AllocFlags
1218#Line # zero pixel memory ##
1219#Code
1220#Populate
1221##
1222
1223AllocFlags provides the option to zero pixel memory when allocated.
1224
1225#Const kZeroPixels_AllocFlag 1
1226#Line # zero pixel memory ##
1227    Instructs tryAllocPixelsFlags and allocPixelsFlags to zero pixel memory.
1228##
1229
1230#NoExample
1231##
1232
1233#SeeAlso tryAllocPixelsFlags allocPixelsFlags erase eraseColor
1234
1235##
1236
1237# ------------------------------------------------------------------------------
1238#Subtopic Allocate
1239#Line # allocates storage for pixels ##
1240##
1241
1242#Method bool tryAllocPixelsFlags(const SkImageInfo& info, uint32_t flags)
1243#In Allocate
1244#Line # allocates pixels from Image_Info with options if possible ##
1245#Populate
1246
1247#Example
1248    SkBitmap bitmap;
1249    if (!bitmap.tryAllocPixelsFlags(SkImageInfo::MakeN32(10000, 10000, kOpaque_SkAlphaType),
1250                                    SkBitmap::kZeroPixels_AllocFlag)) {
1251        SkDebugf("bitmap allocation failed!\n");
1252    } else {
1253        SkDebugf("bitmap allocation succeeded!\n");
1254    }
1255#StdOut
1256bitmap allocation succeeded!
1257##
1258##
1259
1260#SeeAlso allocPixelsFlags tryAllocPixels SkMallocPixelRef::MakeZeroed
1261
1262##
1263
1264# ------------------------------------------------------------------------------
1265
1266#Method void allocPixelsFlags(const SkImageInfo& info, uint32_t flags)
1267#In Allocate
1268#Line # allocates pixels from Image_Info with options, or aborts ##
1269#Populate
1270
1271#Example
1272#Height 128
1273#Description
1274Text is drawn on a transparent background; drawing the bitmap a second time
1275lets the first draw show through.
1276##
1277###^
1278SkBitmap bitmap;
1279bitmap.allocPixelsFlags(SkImageInfo::MakeN32(44, 16, kPremul_SkAlphaType),
1280                        SkBitmap::kZeroPixels_AllocFlag);
1281SkCanvas offscreen(bitmap);
1282SkPaint paint;
1283offscreen.drawString("!@#$%", 0, 12, paint);
1284canvas->scale(6, 6);
1285canvas->drawBitmap(bitmap, 0, 0);
1286canvas->drawBitmap(bitmap, 8, 8);
1287^^^#
1288##
1289
1290#SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeZeroed
1291
1292##
1293
1294# ------------------------------------------------------------------------------
1295
1296#Method bool tryAllocPixels(const SkImageInfo& info, size_t rowBytes)
1297#In Allocate
1298#Line # allocates pixels from Image_Info if possible ##
1299#Populate
1300
1301#Example
1302#Image 3
1303SkBitmap bitmap;
1304SkImageInfo info = SkImageInfo::Make(64, 256, kGray_8_SkColorType, kOpaque_SkAlphaType);
1305if (bitmap.tryAllocPixels(info, 0)) {
1306    SkCanvas offscreen(bitmap);
1307    offscreen.scale(.5f, .5f);
1308    for (int x : { 0, 64, 128, 192 } ) {
1309        offscreen.drawBitmap(source, -x, 0);
1310        canvas->drawBitmap(bitmap, x, 0);
1311    }
1312}
1313##
1314
1315#SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeAllocate
1316
1317##
1318
1319# ------------------------------------------------------------------------------
1320
1321#Method void allocPixels(const SkImageInfo& info, size_t rowBytes)
1322#In Allocate
1323#Line # allocates pixels from Image_Info, or aborts ##
1324#Populate
1325
1326#Example
1327#Image 3
1328SkBitmap bitmap;
1329SkImageInfo info = SkImageInfo::Make(256, 64, kGray_8_SkColorType, kOpaque_SkAlphaType);
1330bitmap.allocPixels(info, info.width() * info.bytesPerPixel() + 64);
1331SkCanvas offscreen(bitmap);
1332offscreen.scale(.5f, .5f);
1333for (int y : { 0, 64, 128, 192 } ) {
1334    offscreen.drawBitmap(source, 0, -y);
1335    canvas->drawBitmap(bitmap, 0, y);
1336}
1337##
1338
1339#SeeAlso tryAllocPixels allocPixelsFlags SkMallocPixelRef::MakeAllocate
1340
1341##
1342
1343# ------------------------------------------------------------------------------
1344
1345#Method bool tryAllocPixels(const SkImageInfo& info)
1346#Populate
1347
1348#Example
1349#Image 3
1350SkBitmap bitmap;
1351if (bitmap.tryAllocPixels(SkImageInfo::Make(64, 64, kGray_8_SkColorType, kOpaque_SkAlphaType))) {
1352    SkCanvas offscreen(bitmap);
1353    offscreen.scale(.25f, .5f);
1354    for (int y : { 0, 64, 128, 192 } ) {
1355        offscreen.drawBitmap(source, -y, -y);
1356        canvas->drawBitmap(bitmap, y, y);
1357    }
1358}
1359##
1360
1361#SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeAllocate
1362
1363##
1364
1365# ------------------------------------------------------------------------------
1366
1367#Method void allocPixels(const SkImageInfo& info)
1368#Populate
1369
1370#Example
1371#Image 4
1372SkBitmap bitmap;
1373bitmap.allocPixels(SkImageInfo::Make(64, 64, kGray_8_SkColorType, kOpaque_SkAlphaType));
1374SkCanvas offscreen(bitmap);
1375offscreen.scale(.5f, .5f);
1376for (int y : { 0, 64, 128, 192 } ) {
1377    offscreen.drawBitmap(source, -y, -y);
1378    canvas->drawBitmap(bitmap, y, y);
1379}
1380##
1381
1382#SeeAlso tryAllocPixels allocPixelsFlags SkMallocPixelRef::MakeAllocate
1383
1384##
1385
1386# ------------------------------------------------------------------------------
1387
1388#Method bool tryAllocN32Pixels(int width, int height, bool isOpaque = false)
1389#In Allocate
1390#Line # allocates compatible ARGB pixels if possible ##
1391#Populate
1392
1393#Example
1394#Height 160
1395    SkBitmap bitmap;
1396    if (bitmap.tryAllocN32Pixels(80, 80)) {
1397        bitmap.eraseColor(SK_ColorTRANSPARENT);
1398        bitmap.erase(0x7f3f7fff, SkIRect::MakeWH(50, 30));
1399        bitmap.erase(0x3f7fff3f, SkIRect::MakeXYWH(20, 10, 50, 30));
1400        bitmap.erase(0x5fff3f7f, SkIRect::MakeXYWH(40, 20, 50, 30));
1401        canvas->drawBitmap(bitmap, 0, 0);
1402        for (int x : { 0, 30, 60, 90 } ) {
1403            canvas->drawBitmap(bitmap, x, 70);
1404        }
1405    }
1406##
1407
1408#SeeAlso tryAllocPixels allocN32Pixels SkMallocPixelRef::MakeAllocate
1409
1410##
1411
1412# ------------------------------------------------------------------------------
1413
1414#Method void allocN32Pixels(int width, int height, bool isOpaque = false)
1415#In Allocate
1416#Line # allocates compatible ARGB pixels, or aborts ##
1417#Populate
1418
1419#Example
1420    SkRandom random;
1421    SkBitmap bitmap;
1422    bitmap.allocN32Pixels(64, 64);
1423    bitmap.eraseColor(SK_ColorTRANSPARENT);
1424    for (int y = 0; y < 256; y += 64) {
1425        for (int x = 0; x < 256; x += 64) {
1426            SkColor color = random.nextU();
1427            uint32_t w = random.nextRangeU(4, 32);
1428            uint32_t cx = random.nextRangeU(0, 64 - w);
1429            uint32_t h = random.nextRangeU(4, 32);
1430            uint32_t cy = random.nextRangeU(0, 64 - h);
1431            bitmap.erase(color, SkIRect::MakeXYWH(cx, cy, w, h));
1432            canvas->drawBitmap(bitmap, x, y);
1433        }
1434    }
1435##
1436
1437#SeeAlso allocPixels tryAllocN32Pixels SkMallocPixelRef::MakeAllocate
1438
1439##
1440
1441# ------------------------------------------------------------------------------
1442
1443#Method bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
1444                       void (*releaseProc)(void* addr, void* context), void* context)
1445#In Allocate
1446#Line # creates Pixel_Ref, with optional release function ##
1447#Populate
1448
1449#Example
1450#Description
1451releaseProc is called immediately because rowBytes is too small for Pixel_Ref.
1452##
1453#Function
1454static void releaseProc(void* addr, void* ) {
1455    SkDebugf("releaseProc called\n");
1456    delete[] (uint32_t*) addr;
1457}
1458
1459##
1460
1461void draw(SkCanvas* canvas) {
1462   SkBitmap bitmap;
1463   void* pixels = new uint32_t[8 * 8];
1464   SkImageInfo info = SkImageInfo::MakeN32(8, 8, kOpaque_SkAlphaType);
1465   SkDebugf("before installPixels\n");
1466   bool installed = bitmap.installPixels(info, pixels, 16, releaseProc, nullptr);
1467   SkDebugf("install " "%s" "successful\n", installed ? "" : "not ");
1468}
1469#StdOut
1470before installPixels
1471releaseProc called
1472install not successful
1473##
1474##
1475
1476#SeeAlso allocPixels
1477
1478##
1479
1480# ------------------------------------------------------------------------------
1481
1482#Method bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes)
1483#Populate
1484
1485#Example
1486#Bug 7079
1487#Description
1488GPU does not support kUnpremul_SkAlphaType, does not assert that it does not.
1489##
1490void draw(SkCanvas* canvas) {
1491   SkRandom random;
1492   SkBitmap bitmap;
1493   const int width = 8;
1494   const int height = 8;
1495   uint32_t pixels[width * height];
1496   for (unsigned x = 0; x < width * height; ++x) {
1497       pixels[x] = random.nextU();
1498   }
1499   SkImageInfo info = SkImageInfo::MakeN32(width, height, kUnpremul_SkAlphaType);
1500   if (bitmap.installPixels(info, pixels, info.minRowBytes())) {
1501       canvas->scale(32, 32);
1502       canvas->drawBitmap(bitmap, 0, 0);
1503   }
1504}
1505##
1506
1507#SeeAlso allocPixels
1508
1509##
1510
1511# ------------------------------------------------------------------------------
1512
1513#Method bool installPixels(const SkPixmap& pixmap)
1514#Populate
1515
1516#Example
1517#Description
1518Draw a five by five bitmap, and draw it again with a center white pixel.
1519##
1520#Height 64
1521    uint8_t storage[][5] = {{ 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 },
1522                            { 0xAC, 0xA8, 0x89, 0x47, 0x87 },
1523                            { 0x4B, 0x25, 0x25, 0x25, 0x46 },
1524                            { 0x90, 0x81, 0x25, 0x41, 0x33 },
1525                            { 0x75, 0x55, 0x44, 0x20, 0x00 }};
1526    SkImageInfo imageInfo = SkImageInfo::Make(5, 5, kGray_8_SkColorType, kOpaque_SkAlphaType);
1527    SkPixmap pixmap(imageInfo, storage[0], sizeof(storage) / 5);
1528    SkBitmap bitmap;
1529    bitmap.installPixels(pixmap);
1530    canvas->scale(10, 10);
1531    canvas->drawBitmap(bitmap, 0, 0);
1532    *pixmap.writable_addr8(2, 2) = 0xFF;
1533    bitmap.installPixels(pixmap);
1534    canvas->drawBitmap(bitmap, 10, 0);
1535##
1536
1537#SeeAlso allocPixels
1538
1539##
1540
1541# ------------------------------------------------------------------------------
1542#Subtopic Pixels
1543#Line # read and write pixel values ##
1544##
1545
1546#Method void setPixels(void* pixels)
1547#In Pixels
1548#Line # sets Pixel_Ref without an offset ##
1549#Populate
1550
1551#Example
1552#Height 50
1553    uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 };
1554    uint8_t set2[5] = { 0xAC, 0xA8, 0x89, 0x47, 0x87 };
1555    SkBitmap bitmap;
1556    bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5);
1557    canvas->scale(10, 50);
1558    canvas->drawBitmap(bitmap, 0, 0);
1559    bitmap.setPixels(set2);
1560    canvas->drawBitmap(bitmap, 10, 0);
1561##
1562
1563#SeeAlso installPixels allocPixels
1564
1565##
1566
1567# ------------------------------------------------------------------------------
1568
1569#Method bool tryAllocPixels()
1570#In Allocate
1571#Populate
1572
1573#Example
1574#Height 50
1575#Description
1576Bitmap hosts and draws gray values in set1. tryAllocPixels replaces Pixel_Ref
1577and erases it to black, but does not alter set1. setPixels replaces black
1578Pixel_Ref with set1.
1579##
1580    uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 };
1581    SkBitmap bitmap;
1582    bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5);
1583    canvas->scale(10, 50);
1584    canvas->drawBitmap(bitmap, 0, 0);
1585    if (bitmap.tryAllocPixels()) {
1586        bitmap.eraseColor(SK_ColorBLACK);
1587        canvas->drawBitmap(bitmap, 8, 0);
1588        bitmap.setPixels(set1);
1589        canvas->drawBitmap(bitmap, 16, 0);
1590    }
1591##
1592
1593#SeeAlso allocPixels installPixels setPixels
1594
1595##
1596
1597# ------------------------------------------------------------------------------
1598
1599#Method void allocPixels()
1600#In Allocate
1601#Populate
1602
1603#Example
1604#Height 50
1605#Description
1606Bitmap hosts and draws gray values in set1. allocPixels replaces Pixel_Ref
1607and erases it to black, but does not alter set1. setPixels replaces black
1608Pixel_Ref with set2.
1609##
1610    uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 };
1611    uint8_t set2[5] = { 0xAC, 0xA8, 0x89, 0x47, 0x87 };
1612    SkBitmap bitmap;
1613    bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5);
1614    canvas->scale(10, 50);
1615    canvas->drawBitmap(bitmap, 0, 0);
1616    bitmap.allocPixels();
1617    bitmap.eraseColor(SK_ColorBLACK);
1618    canvas->drawBitmap(bitmap, 8, 0);
1619    bitmap.setPixels(set2);
1620    canvas->drawBitmap(bitmap, 16, 0);
1621##
1622
1623#SeeAlso tryAllocPixels installPixels setPixels
1624
1625##
1626
1627# ------------------------------------------------------------------------------
1628
1629#Method bool tryAllocPixels(Allocator* allocator)
1630#Populate
1631
1632#Example
1633#Height 100
1634#Description
1635HeapAllocator limits the maximum size of Bitmap to two gigabytes. Using
1636a custom allocator, this limitation may be relaxed. This example can be
1637modified to allocate an eight gigabyte Bitmap on a 64-bit platform with
1638sufficient memory.
1639##
1640#Function
1641class LargePixelRef : public SkPixelRef {
1642public:
1643    LargePixelRef(const SkImageInfo& info, char* storage, size_t rowBytes)
1644        : SkPixelRef(info.width(), info.height(), storage, rowBytes) {
1645    }
1646
1647    ~LargePixelRef() override {
1648        delete[] (char* ) this->pixels();
1649    }
1650};
1651
1652class LargeAllocator : public SkBitmap::Allocator {
1653public:
1654    bool allocPixelRef(SkBitmap* bitmap) override {
1655        const SkImageInfo& info = bitmap->info();
1656        uint64_t rowBytes = info.minRowBytes64();
1657        uint64_t size = info.height() * rowBytes;
1658        char* addr = new char[size];
1659        if (nullptr == addr) {
1660            return false;
1661        }
1662        sk_sp<SkPixelRef> pr = sk_sp<SkPixelRef>(new LargePixelRef(info, addr, rowBytes));
1663        if (!pr) {
1664            return false;
1665        }
1666        bitmap->setPixelRef(std::move(pr), 0, 0);
1667        return true;
1668    }
1669};
1670
1671##
1672
1673void draw(SkCanvas* canvas) {
1674   LargeAllocator largeAllocator;
1675   SkBitmap bitmap;
1676   int width = 100; // make this 20000
1677   int height = 100; // and this 100000 to allocate 8 gigs on a 64-bit platform
1678   bitmap.setInfo(SkImageInfo::MakeN32(width, height, kOpaque_SkAlphaType));
1679   if (bitmap.tryAllocPixels(&largeAllocator)) {
1680       bitmap.eraseColor(0xff55aa33);
1681       canvas->drawBitmap(bitmap, 0, 0);
1682   }
1683}
1684
1685##
1686
1687#SeeAlso allocPixels Allocator Pixel_Ref
1688
1689##
1690
1691# ------------------------------------------------------------------------------
1692
1693#Method void allocPixels(Allocator* allocator)
1694#Populate
1695
1696#Example
1697#Height 32
1698#Function
1699class TinyAllocator : public SkBitmap::Allocator {
1700public:
1701    bool allocPixelRef(SkBitmap* bitmap) override {
1702        const SkImageInfo& info = bitmap->info();
1703        if (info.height() * info.minRowBytes() > sizeof(storage)) {
1704            return false;
1705        }
1706        sk_sp<SkPixelRef> pr = sk_sp<SkPixelRef>(
1707                new SkPixelRef(info.width(), info.height(), storage, info.minRowBytes()));
1708        bitmap->setPixelRef(std::move(pr), 0, 0);
1709        return true;
1710    }
1711
1712    char storage[16];
1713};
1714
1715##
1716
1717void draw(SkCanvas* canvas) {
1718   TinyAllocator tinyAllocator;
1719   SkBitmap bitmap;
1720   bitmap.setInfo(SkImageInfo::MakeN32(2, 2, kOpaque_SkAlphaType));
1721   if (bitmap.tryAllocPixels(&tinyAllocator)) {
1722       bitmap.eraseColor(0xff55aa33);
1723       bitmap.erase(0xffaa3355, SkIRect::MakeXYWH(1, 1, 1, 1));
1724       canvas->scale(16, 16);
1725       canvas->drawBitmap(bitmap, 0, 0);
1726   }
1727}
1728##
1729
1730#SeeAlso allocPixels Allocator Pixel_Ref
1731
1732##
1733
1734# ------------------------------------------------------------------------------
1735
1736#Method SkPixelRef* pixelRef() const
1737#In Property
1738#Line # returns Pixel_Ref, or nullptr ##
1739#Populate
1740
1741#Example
1742#Image 3
1743   SkBitmap subset;
1744   source.extractSubset(&subset, SkIRect::MakeXYWH(32, 64, 128, 256));
1745   SkDebugf("src ref %c= sub ref\n", source.pixelRef() == subset.pixelRef() ? '=' : '!');
1746   SkDebugf("src pixels %c= sub pixels\n", source.getPixels() == subset.getPixels() ? '=' : '!');
1747   SkDebugf("src addr %c= sub addr\n", source.getAddr(32, 64) == subset.getAddr(0, 0) ? '=' : '!');
1748##
1749
1750#SeeAlso getPixels getAddr
1751
1752##
1753
1754# ------------------------------------------------------------------------------
1755
1756#Method SkIPoint pixelRefOrigin() const
1757#In Property
1758#Line # returns offset within Pixel_Ref ##
1759#Populate
1760
1761#Example
1762#Image 3
1763   SkBitmap subset;
1764   source.extractSubset(&subset, SkIRect::MakeXYWH(32, 64, 128, 256));
1765   SkIPoint sourceOrigin = source.pixelRefOrigin();
1766   SkIPoint subsetOrigin = subset.pixelRefOrigin();
1767   SkDebugf("source origin: %d, %d\n", sourceOrigin.fX, sourceOrigin.fY);
1768   SkDebugf("subset origin: %d, %d\n", subsetOrigin.fX, subsetOrigin.fY);
1769#StdOut
1770source origin: 0, 0
1771subset origin: 32, 64
1772##
1773##
1774
1775#SeeAlso SkPixelRef getSubset setPixelRef
1776
1777##
1778
1779# ------------------------------------------------------------------------------
1780#Subtopic Set
1781#Line # updates values and attributes ##
1782##
1783
1784#Method void setPixelRef(sk_sp<SkPixelRef> pixelRef, int dx, int dy)
1785#In Set
1786#Line # sets Pixel_Ref and offset ##
1787#Populate
1788
1789#Example
1790#Height 140
1791#Image 5
1792#Description
1793Treating 32-bit data as 8-bit data is unlikely to produce useful results.
1794##
1795    SkBitmap bitmap;
1796    bitmap.setInfo(SkImageInfo::Make(source.width() - 5, source.height() - 5,
1797                   kGray_8_SkColorType, kOpaque_SkAlphaType), source.rowBytes());
1798    bitmap.setPixelRef(sk_ref_sp(source.pixelRef()), 5, 5);
1799    canvas->drawBitmap(bitmap, 10, 10);
1800##
1801
1802#SeeAlso setInfo
1803
1804##
1805
1806# ------------------------------------------------------------------------------
1807
1808#Method bool readyToDraw() const
1809#In Utility
1810#Line # returns true if address of pixels is not nullptr ##
1811#Populate
1812
1813#Example
1814#Image 5
1815#Height 160
1816    if (source.readyToDraw()) {
1817        canvas->drawBitmap(source, 10, 10);
1818    }
1819##
1820
1821#SeeAlso getPixels drawsNothing
1822
1823##
1824
1825# ------------------------------------------------------------------------------
1826
1827#Method uint32_t getGenerationID() const
1828#In Utility
1829#Line # returns unique ID ##
1830#Populate
1831
1832#Example
1833    SkBitmap bitmap;
1834    SkDebugf("empty id %u\n", bitmap.getGenerationID());
1835    bitmap.allocPixels(SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType));
1836    SkDebugf("alloc id %u\n", bitmap.getGenerationID());
1837    bitmap.eraseColor(SK_ColorRED);
1838    SkDebugf("erase id %u\n", bitmap.getGenerationID());
1839#StdOut
1840#Volatile
1841empty id 0
1842alloc id 4
1843erase id 6
1844##
1845##
1846
1847#SeeAlso notifyPixelsChanged Pixel_Ref
1848
1849##
1850
1851# ------------------------------------------------------------------------------
1852
1853#Method void notifyPixelsChanged() const
1854#In Pixels
1855#Line # marks pixels as changed, altering the unique ID ##
1856#Populate
1857
1858#Example
1859#Height 20
1860    SkBitmap bitmap;
1861    bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
1862    bitmap.allocPixels();
1863    bitmap.eraseColor(SK_ColorRED);
1864    canvas->scale(16, 16);
1865    canvas->drawBitmap(bitmap, 0, 0);
1866    *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorBLUE);
1867    canvas->drawBitmap(bitmap, 2, 0);
1868    bitmap.notifyPixelsChanged();
1869    *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorGREEN);
1870    canvas->drawBitmap(bitmap, 4, 0);
1871##
1872
1873#SeeAlso getGenerationID isVolatile Pixel_Ref
1874
1875##
1876
1877# ------------------------------------------------------------------------------
1878#Subtopic Draw
1879#Line # sets pixels to Color ##
1880##
1881
1882#Method void eraseColor(SkColor c) const
1883#In Draw
1884#Line # writes Color to pixels ##
1885#Populate
1886
1887#Example
1888#Height 20
1889    SkBitmap bitmap;
1890    bitmap.allocPixels(SkImageInfo::MakeN32(1, 1, kOpaque_SkAlphaType));
1891    bitmap.eraseColor(SK_ColorRED);
1892    canvas->scale(16, 16);
1893    canvas->drawBitmap(bitmap, 0, 0);
1894##
1895
1896#SeeAlso eraseARGB erase
1897
1898##
1899
1900# ------------------------------------------------------------------------------
1901
1902#Method void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const
1903#In Draw
1904#Line # writes Color to pixels ##
1905#Populate
1906
1907#Example
1908#Height 80
1909    SkBitmap bitmap;
1910    bitmap.allocPixels(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType));
1911    bitmap.eraseARGB(0x7f, 0xff, 0x7f, 0x3f);
1912    canvas->scale(50, 50);
1913    canvas->drawBitmap(bitmap, 0, 0);
1914    canvas->drawBitmap(bitmap, .5f, .5f);
1915##
1916
1917#SeeAlso eraseColor erase
1918
1919##
1920
1921# ------------------------------------------------------------------------------
1922
1923#Method void erase(SkColor c, const SkIRect& area) const
1924#In Draw
1925#Line # writes Color to rectangle of pixels ##
1926#Populate
1927
1928#Example
1929#Height 70
1930    SkBitmap bitmap;
1931    bitmap.allocPixels(SkImageInfo::MakeN32(2, 2, kPremul_SkAlphaType));
1932    bitmap.erase(0x7fff7f3f, SkIRect::MakeWH(1, 1));
1933    bitmap.erase(0x7f7f3fff, SkIRect::MakeXYWH(0, 1, 1, 1));
1934    bitmap.erase(0x7f3fff7f, SkIRect::MakeXYWH(1, 0, 1, 1));
1935    bitmap.erase(0x7f1fbf5f, SkIRect::MakeXYWH(1, 1, 1, 1));
1936    canvas->scale(25, 25);
1937    canvas->drawBitmap(bitmap, 0, 0);
1938    canvas->drawBitmap(bitmap, .5f, .5f);
1939
1940##
1941
1942#SeeAlso eraseColor eraseARGB SkCanvas::drawRect
1943
1944##
1945
1946# ------------------------------------------------------------------------------
1947
1948#Method SkColor getColor(int x, int y) const
1949#In Property
1950#In Pixels
1951#Line # returns one pixel as Unpremultiplied Color ##
1952#Populate
1953
1954#Example
1955    const int w = 4;
1956    const int h = 4;
1957    SkColor colors[][w] = {
1958        { 0x00000000, 0x2a0e002a, 0x55380055, 0x7f7f007f },
1959        { 0x2a000e2a, 0x551c1c55, 0x7f542a7f, 0xaaaa38aa },
1960        { 0x55003855, 0x7f2a547f, 0xaa7171aa, 0xd4d48dd4 },
1961        { 0x7f007f7f, 0xaa38aaaa, 0xd48dd4d4, 0xffffffff }
1962    };
1963    SkDebugf("Premultiplied:\n");
1964    for (int y = 0; y < h; ++y) {
1965        SkDebugf("(0, %d) ", y);
1966        for (int x = 0; x < w; ++x) {
1967            SkDebugf("0x%08x%c", colors[y][x], x == w - 1 ? '\n' : ' ');
1968        }
1969    }
1970    SkPixmap pixmap(SkImageInfo::MakeN32(w, h, kPremul_SkAlphaType), colors, w * 4);
1971    SkBitmap bitmap;
1972    bitmap.installPixels(pixmap);
1973    SkDebugf("Unpremultiplied:\n");
1974    for (int y = 0; y < h; ++y) {
1975        SkDebugf("(0, %d) ", y);
1976        for (int x = 0; x < w; ++x) {
1977            SkDebugf("0x%08x%c", bitmap.getColor(x, y), x == w - 1 ? '\n' : ' ');
1978        }
1979    }
1980#StdOut
1981Premultiplied:
1982(0, 0) 0x00000000 0x2a0e002a 0x55380055 0x7f7f007f
1983(0, 1) 0x2a000e2a 0x551c1c55 0x7f542a7f 0xaaaa38aa
1984(0, 2) 0x55003855 0x7f2a547f 0xaa7171aa 0xd4d48dd4
1985(0, 3) 0x7f007f7f 0xaa38aaaa 0xd48dd4d4 0xffffffff
1986Unpremultiplied:
1987(0, 0) 0x00000000 0x2a5500ff 0x55a800ff 0x7fff00ff
1988(0, 1) 0x2a0055ff 0x555454ff 0x7fa954ff 0xaaff54ff
1989(0, 2) 0x5500a8ff 0x7f54a9ff 0xaaaaaaff 0xd4ffaaff
1990(0, 3) 0x7f00ffff 0xaa54ffff 0xd4aaffff 0xffffffff
1991##
1992##
1993
1994#SeeAlso getAlphaf getAddr readPixels
1995
1996##
1997
1998#Method float getAlphaf(int x, int y) const
1999#In Property
2000#Line # returns Alpha normalized from zero to one ##
2001
2002Looks up the pixel at (x,y) and return its alpha component, normalized to [0..1].
2003This is roughly equivalent to #Formula # SkGetColorA(getColor()) ##, but can be more efficient
2004(and more precise if the pixels store more than 8 bits per component).
2005
2006#Param x  column index, zero or greater, and less than width() ##
2007#Param y  row index, zero or greater, and less than height() ##
2008
2009#Return   alpha converted to normalized float ##
2010
2011#NoExample
2012##
2013
2014#SeeAlso getColor
2015
2016##
2017
2018
2019# ------------------------------------------------------------------------------
2020
2021#Method void* getAddr(int x, int y) const
2022#In Property
2023#Line # returns readable pixel address as void pointer ##
2024#Populate
2025
2026#Example
2027#Image 3
2028    char* row0 = (char* ) source.getAddr(0, 0);
2029    char* row1 = (char* ) source.getAddr(0, 1);
2030    SkDebugf("addr interval %c= rowBytes\n",
2031             (size_t) (row1 - row0) == source.rowBytes() ? '=' : '!');
2032#StdOut
2033addr interval == rowBytes
2034##
2035##
2036
2037#SeeAlso getAddr8 getAddr16 getAddr32 readPixels SkPixmap::addr
2038
2039##
2040
2041# ------------------------------------------------------------------------------
2042
2043#Method uint32_t* getAddr32(int x, int y) const
2044#In Property
2045#Line # returns readable pixel address as 32-bit pointer ##
2046Returns address at (x, y).
2047
2048Input is not validated. Triggers an assert() if built with SK_DEBUG defined and:
2049#List
2050# Pixel_Ref is nullptr ##
2051# bytesPerPixel() is not four ##
2052# x is negative, or not less than width() ##
2053# y is negative, or not less than height() ##
2054##
2055
2056#Param x  column index, zero or greater, and less than width() ##
2057#Param y  row index, zero or greater, and less than height() ##
2058
2059#Return  unsigned 32-bit pointer to pixel at (x, y) ##
2060
2061#Example
2062#Image 3
2063    uint32_t* row0 = source.getAddr32(0, 0);
2064    uint32_t* row1 = source.getAddr32(0, 1);
2065    size_t interval = (row1 - row0) * source.bytesPerPixel();
2066    SkDebugf("addr interval %c= rowBytes\n", interval == source.rowBytes() ? '=' : '!');
2067#StdOut
2068addr interval == rowBytes
2069##
2070##
2071
2072#SeeAlso getAddr8 getAddr16 getAddr readPixels SkPixmap::addr32
2073
2074##
2075
2076# ------------------------------------------------------------------------------
2077
2078#Method uint16_t* getAddr16(int x, int y) const
2079#In Property
2080#Line # returns readable pixel address as 16-bit pointer ##
2081Returns address at (x, y).
2082
2083Input is not validated. Triggers an assert() if built with SK_DEBUG defined and:
2084#List
2085# Pixel_Ref is nullptr ##
2086# bytesPerPixel() is not two ##
2087# x is negative, or not less than width() ##
2088# y is negative, or not less than height() ##
2089##
2090
2091#Param x  column index, zero or greater, and less than width() ##
2092#Param y  row index, zero or greater, and less than height() ##
2093
2094#Return  unsigned 16-bit pointer to pixel at (x, y)##
2095
2096#Example
2097#Image 3
2098    SkBitmap bitmap16;
2099    SkImageInfo dstInfo = SkImageInfo::Make(source.width(), source.height(), kARGB_4444_SkColorType,
2100                     kPremul_SkAlphaType);
2101    bitmap16.allocPixels(dstInfo);
2102    if (source.readPixels(dstInfo, bitmap16.getPixels(), bitmap16.rowBytes(), 0, 0)) {
2103        uint16_t* row0 = bitmap16.getAddr16(0, 0);
2104        uint16_t* row1 = bitmap16.getAddr16(0, 1);
2105        size_t interval = (row1 - row0) * bitmap16.bytesPerPixel();
2106        SkDebugf("addr interval %c= rowBytes\n", interval == bitmap16.rowBytes() ? '=' : '!');
2107    }
2108#StdOut
2109addr interval == rowBytes
2110##
2111##
2112
2113#SeeAlso getAddr8 getAddr getAddr32 readPixels SkPixmap::addr16
2114
2115##
2116
2117# ------------------------------------------------------------------------------
2118
2119#Method uint8_t* getAddr8(int x, int y) const
2120#In Property
2121#Line # returns readable pixel address as 8-bit pointer ##
2122Returns address at (x, y).
2123
2124Input is not validated. Triggers an assert() if built with SK_DEBUG defined and:
2125#List
2126# Pixel_Ref is nullptr ##
2127# bytesPerPixel() is not one ##
2128# x is negative, or not less than width() ##
2129# y is negative, or not less than height() ##
2130##
2131
2132#Param x  column index, zero or greater, and less than width() ##
2133#Param y  row index, zero or greater, and less than height() ##
2134
2135#Return unsigned 8-bit pointer to pixel at (x, y) ##
2136
2137#Example
2138   SkBitmap bitmap;
2139   const int width = 8;
2140   const int height = 8;
2141   uint8_t pixels[height][width];
2142   SkImageInfo info = SkImageInfo::Make(width, height, kGray_8_SkColorType, kOpaque_SkAlphaType);
2143   if (bitmap.installPixels(info, pixels, info.minRowBytes())) {
2144       SkDebugf("&pixels[4][2] %c= bitmap.getAddr8(2, 4)\n",
2145                 &pixels[4][2]  == bitmap.getAddr8(2, 4) ? '=' : '!');
2146   }
2147#StdOut
2148&pixels[4][2] == bitmap.getAddr8(2, 4)
2149##
2150##
2151
2152#SeeAlso getAddr getAddr16 getAddr32 readPixels SkPixmap::addr8
2153
2154##
2155
2156# ------------------------------------------------------------------------------
2157
2158#Method bool extractSubset(SkBitmap* dst, const SkIRect& subset) const
2159#In Constructors
2160#Line # creates Bitmap, sharing pixels if possible ##
2161Shares Pixel_Ref with dst. Pixels are not copied; Bitmap and dst point
2162to the same pixels; dst bounds() are set to the intersection of subset
2163and the original bounds().
2164
2165subset may be larger than bounds(). Any area outside of bounds() is ignored.
2166
2167Any contents of dst are discarded. isVolatile setting is copied to dst.
2168dst is set to colorType, alphaType, and colorSpace.
2169
2170Return false if:
2171#List
2172# dst is nullptr ##
2173# Pixel_Ref is nullptr ##
2174# subset does not intersect bounds() ##
2175##
2176
2177#Param dst  Bitmap set to subset ##
2178#Param subset  rectangle of pixels to reference ##
2179
2180#Return  true if dst is replaced by subset
2181##
2182
2183#Example
2184#Image 3
2185    SkIRect bounds, s;
2186    source.getBounds(&bounds);
2187    SkDebugf("bounds: %d, %d, %d, %d\n", bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2188    SkBitmap subset;
2189    for (int left: { -100, 0, 100, 1000 } ) {
2190         for (int right: { 0, 100, 1000 } ) {
2191             SkIRect b = SkIRect::MakeLTRB(left, 100, right, 200);
2192             bool success = source.extractSubset(&subset, b);
2193             SkDebugf("subset: %4d, %4d, %4d, %4d  ", b.fLeft, b.fTop, b.fRight, b.fBottom);
2194             SkDebugf("success; %s", success ? "true" : "false");
2195             if (success) {
2196                 subset.getBounds(&s);
2197                 SkDebugf("  subset: %d, %d, %d, %d", s.fLeft, s.fTop, s.fRight, s.fBottom);
2198             }
2199             SkDebugf("\n");
2200         }
2201    }
2202#StdOut
2203bounds: 0, 0, 512, 512
2204subset: -100,  100,    0,  200  success; false
2205subset: -100,  100,  100,  200  success; true  subset: 0, 0, 100, 100
2206subset: -100,  100, 1000,  200  success; true  subset: 0, 0, 512, 100
2207subset:    0,  100,    0,  200  success; false
2208subset:    0,  100,  100,  200  success; true  subset: 0, 0, 100, 100
2209subset:    0,  100, 1000,  200  success; true  subset: 0, 0, 512, 100
2210subset:  100,  100,    0,  200  success; false
2211subset:  100,  100,  100,  200  success; false
2212subset:  100,  100, 1000,  200  success; true  subset: 0, 0, 412, 100
2213subset: 1000,  100,    0,  200  success; false
2214subset: 1000,  100,  100,  200  success; false
2215subset: 1000,  100, 1000,  200  success; false
2216##
2217##
2218
2219#SeeAlso readPixels writePixels SkCanvas::drawBitmap
2220
2221##
2222
2223# ------------------------------------------------------------------------------
2224
2225#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
2226                    int srcX, int srcY) const
2227#In Pixels
2228#Line # copies and converts pixels ##
2229
2230Copies a Rect of pixels from Bitmap to dstPixels. Copy starts at (srcX, srcY),
2231and does not exceed Bitmap (width(), height()).
2232
2233dstInfo specifies width, height, Color_Type, Alpha_Type, and Color_Space of
2234destination. dstRowBytes specifics the gap from one destination row to the next.
2235Returns true if pixels are copied. Returns false if:
2236#List
2237# dstInfo has no address ##
2238# dstRowBytes is less than dstInfo.minRowBytes() ##
2239# Pixel_Ref is nullptr ##
2240##
2241
2242Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
2243kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
2244If Bitmap colorType is kGray_8_SkColorType, dstInfo.colorSpace() must match.
2245If Bitmap alphaType is kOpaque_SkAlphaType, dstInfo.alphaType() must
2246match. If Bitmap colorSpace is nullptr, dstInfo.colorSpace() must match. Returns
2247false if pixel conversion is not possible.
2248
2249srcX and srcY may be negative to copy only top or left of source. Returns
2250false if width() or height() is zero or negative.
2251Returns false if #Formula # abs(srcX) >= Bitmap width() ##, or if #Formula # abs(srcY) >= Bitmap height() ##.
2252
2253#Param dstInfo  destination width, height, Color_Type, Alpha_Type, Color_Space ##
2254#Param dstPixels  destination pixel storage ##
2255#Param dstRowBytes  destination row length ##
2256#Param srcX  column index whose absolute value is less than width() ##
2257#Param srcY  row index whose absolute value is less than height() ##
2258
2259#Return  true if pixels are copied to dstPixels ##
2260
2261#Example
2262#Height 128
2263#Description
2264Transferring the gradient from 8 bits per component to 4 bits per component
2265creates visible banding.
2266##
2267    const int width = 256;
2268    const int height = 64;
2269    SkImageInfo srcInfo = SkImageInfo::MakeN32Premul(width, height);
2270    SkColor  gradColors[] = { 0xFFAA3300, 0x7F881122 };
2271    SkPoint  gradPoints[] = { { 0, 0 }, { 256, 0 } };
2272    SkPaint paint;
2273    paint.setShader(SkGradientShader::MakeLinear(gradPoints, gradColors, nullptr,
2274                    SK_ARRAY_COUNT(gradColors), SkShader::kClamp_TileMode));
2275    SkBitmap bitmap;
2276    bitmap.allocPixels(srcInfo);
2277    SkCanvas srcCanvas(bitmap);
2278    srcCanvas.drawRect(SkRect::MakeWH(width, height), paint);
2279    canvas->drawBitmap(bitmap, 0, 0);
2280    SkImageInfo dstInfo = srcInfo.makeColorType(kARGB_4444_SkColorType);
2281    std::vector<int16_t> dstPixels;
2282    dstPixels.resize(height * width);
2283    bitmap.readPixels(dstInfo, &dstPixels.front(), width * 2, 0, 0);
2284    SkPixmap dstPixmap(dstInfo, &dstPixels.front(), width * 2);
2285    bitmap.installPixels(dstPixmap);
2286    canvas->drawBitmap(bitmap, 0, 64);
2287##
2288
2289#SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels
2290
2291##
2292
2293# ------------------------------------------------------------------------------
2294
2295#Method bool readPixels(const SkPixmap& dst, int srcX, int srcY) const
2296
2297Copies a Rect of pixels from Bitmap to dst. Copy starts at (srcX, srcY), and
2298does not exceed Bitmap (width(), height()).
2299
2300dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
2301and row bytes of destination. dst.rowBytes() specifics the gap from one destination
2302row to the next. Returns true if pixels are copied. Returns false if:
2303#List
2304# dst pixel storage equals nullptr ##
2305# dst.rowBytes() is less than SkImageInfo::minRowBytes() ##
2306# Pixel_Ref is nullptr ##
2307##
2308
2309Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
2310kGray_8_SkColorType, or kAlpha_8_SkColorType; dst Color_Type must match.
2311If Bitmap colorType is kGray_8_SkColorType, dst Color_Space must match.
2312If Bitmap alphaType is kOpaque_SkAlphaType, dst Alpha_Type must
2313match. If Bitmap colorSpace is nullptr, dst Color_Space must match. Returns
2314false if pixel conversion is not possible.
2315
2316srcX and srcY may be negative to copy only top or left of source. Returns
2317false if width() or height() is zero or negative.
2318Returns false if #Formula # abs(srcX) >= Bitmap width() ##, or if #Formula # abs(srcY) >= Bitmap height() ##.
2319
2320#Param dst  destination Pixmap: Image_Info, pixels, row bytes ##
2321#Param srcX  column index whose absolute value is less than width() ##
2322#Param srcY  row index whose absolute value is less than height() ##
2323
2324#Return  true if pixels are copied to dst ##
2325
2326#Example
2327#Image 3
2328    std::vector<int32_t> srcPixels;
2329    srcPixels.resize(source.height() * source.rowBytes());
2330    for (int y = 0; y < 4; ++y) {
2331        for (int x = 0; x < 4; ++x) {
2332            SkPixmap pixmap(SkImageInfo::MakeN32Premul(source.width() / 4, source.height() / 4),
2333                    &srcPixels.front() + x * source.height() * source.width() / 4 +
2334                    y * source.width() / 4, source.rowBytes());
2335            source.readPixels(pixmap, x * source.width() / 4, y * source.height() / 4);
2336        }
2337    }
2338    canvas->scale(.5f, .5f);
2339    SkBitmap bitmap;
2340    bitmap.installPixels(SkImageInfo::MakeN32Premul(source.width(), source.height()),
2341                             &srcPixels.front(), source.rowBytes());
2342    canvas->drawBitmap(bitmap, 0, 0);
2343##
2344
2345#SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels
2346
2347##
2348
2349# ------------------------------------------------------------------------------
2350
2351#Method bool readPixels(const SkPixmap& dst) const
2352
2353Copies a Rect of pixels from Bitmap to dst. Copy starts at (0, 0), and
2354does not exceed Bitmap (width(), height()).
2355
2356dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
2357and row bytes of destination. dst.rowBytes() specifics the gap from one destination
2358row to the next. Returns true if pixels are copied. Returns false if:
2359#List
2360# dst pixel storage equals nullptr ##
2361# dst.rowBytes() is less than SkImageInfo::minRowBytes() ##
2362# Pixel_Ref is nullptr ##
2363##
2364
2365Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
2366kGray_8_SkColorType, or kAlpha_8_SkColorType; dst Color_Type must match.
2367If Bitmap colorType is kGray_8_SkColorType, dst Color_Space must match.
2368If Bitmap alphaType is kOpaque_SkAlphaType, dst Alpha_Type must
2369match. If Bitmap colorSpace is nullptr, dst Color_Space must match. Returns
2370false if pixel conversion is not possible.
2371
2372#Param dst  destination Pixmap: Image_Info, pixels, row bytes ##
2373
2374#Return  true if pixels are copied to dst ##
2375
2376#Example
2377#Height 128
2378#Image 3
2379    std::vector<int32_t> srcPixels;
2380    srcPixels.resize(source.height() * source.width() * 8);
2381    for (int i = 0;  i < 2; ++i) {
2382    SkPixmap pixmap(SkImageInfo::Make(source.width() * 2, source.height(),
2383                    i ? kRGBA_8888_SkColorType : kBGRA_8888_SkColorType, kPremul_SkAlphaType),
2384                    &srcPixels.front() + i * source.width(), source.rowBytes() * 2);
2385        source.readPixels(pixmap);
2386    }
2387    canvas->scale(.25f, .25f);
2388    SkBitmap bitmap;
2389    bitmap.installPixels(SkImageInfo::MakeN32Premul(source.width() * 2, source.height()),
2390                         &srcPixels.front(), source.rowBytes() * 2);
2391    canvas->drawBitmap(bitmap, 0, 0);
2392##
2393
2394#SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels
2395
2396##
2397
2398# ------------------------------------------------------------------------------
2399
2400#Method bool writePixels(const SkPixmap& src, int dstX, int dstY)
2401#In Pixels
2402#Line # copies and converts pixels ##
2403Copies a Rect of pixels from src. Copy starts at (dstX, dstY), and does not exceed
2404(src.width(), src.height()).
2405
2406src specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
2407and row bytes of source. src.rowBytes() specifics the gap from one source
2408row to the next. Returns true if pixels are copied. Returns false if:
2409#List
2410# src pixel storage equals nullptr ##
2411# src.rowBytes() is less than SkImageInfo::minRowBytes() ##
2412# Pixel_Ref is nullptr ##
2413##
2414
2415Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
2416kGray_8_SkColorType, or kAlpha_8_SkColorType; src Color_Type must match.
2417If Bitmap colorType is kGray_8_SkColorType, src Color_Space must match.
2418If Bitmap alphaType is kOpaque_SkAlphaType, src Alpha_Type must
2419match. If Bitmap colorSpace is nullptr, src Color_Space must match. Returns
2420false if pixel conversion is not possible.
2421
2422dstX and dstY may be negative to copy only top or left of source. Returns
2423false if width() or height() is zero or negative.
2424Returns false if #Formula # abs(dstX) >= Bitmap width() ##, or if #Formula # abs(dstY) >= Bitmap height() ##.
2425
2426#Param src  source Pixmap: Image_Info, pixels, row bytes ##
2427#Param dstX  column index whose absolute value is less than width() ##
2428#Param dstY  row index whose absolute value is less than height() ##
2429
2430#Return  true if src pixels are copied to Bitmap ##
2431
2432#Example
2433#Image 3
2434    std::vector<int32_t> srcPixels;
2435    int width = image->width();
2436    int height = image->height();
2437    srcPixels.resize(height * width  * 4);
2438    SkPixmap pixmap(SkImageInfo::MakeN32Premul(width, height), (const void*) &srcPixels.front(),
2439                    width * 4);
2440    image->readPixels(pixmap, 0, 0);
2441    canvas->scale(.5f, .5f);
2442    width /= 4;
2443    height /= 4;
2444    for (int y = 0; y < 4; ++y) {
2445        for (int x = 0; x < 4; ++x) {
2446            SkBitmap bitmap;
2447            bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height));
2448            bitmap.writePixels(pixmap, -y * width, -x * height);
2449            canvas->drawBitmap(bitmap, x * width, y * height);
2450        }
2451    }
2452##
2453
2454#SeeAlso readPixels
2455
2456##
2457
2458# ------------------------------------------------------------------------------
2459
2460#Method bool writePixels(const SkPixmap& src)
2461
2462Copies a Rect of pixels from src. Copy starts at (0, 0), and does not exceed
2463(src.width(), src.height()).
2464
2465src specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
2466and row bytes of source. src.rowBytes() specifics the gap from one source
2467row to the next. Returns true if pixels are copied. Returns false if:
2468#List
2469# src pixel storage equals nullptr ##
2470# src.rowBytes() is less than SkImageInfo::minRowBytes() ##
2471# Pixel_Ref is nullptr ##
2472##
2473
2474Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
2475kGray_8_SkColorType, or kAlpha_8_SkColorType; src Color_Type must match.
2476If Bitmap colorType is kGray_8_SkColorType, src Color_Space must match.
2477If Bitmap alphaType is kOpaque_SkAlphaType, src Alpha_Type must
2478match. If Bitmap colorSpace is nullptr, src Color_Space must match. Returns
2479false if pixel conversion is not possible.
2480
2481#Param src  source Pixmap: Image_Info, pixels, row bytes ##
2482
2483#Return  true if src pixels are copied to Bitmap ##
2484
2485#Example
2486#Height 80
2487    SkBitmap bitmap;
2488    bitmap.allocPixels(SkImageInfo::MakeN32Premul(2, 2));
2489    bitmap.eraseColor(SK_ColorGREEN);
2490    SkPMColor color = 0xFF5599BB;
2491    SkPixmap src(SkImageInfo::MakeN32Premul(1, 1), &color, 4);
2492    bitmap.writePixels(src);
2493    canvas->scale(40, 40);
2494    canvas->drawBitmap(bitmap, 0, 0);
2495##
2496
2497#SeeAlso readPixels
2498
2499##
2500
2501# ------------------------------------------------------------------------------
2502
2503#Method bool extractAlpha(SkBitmap* dst) const
2504#In Constructors
2505#Line # creates Bitmap containing Alpha of pixels ##
2506#Populate
2507
2508#Example
2509#Height 100
2510    SkBitmap alpha, bitmap;
2511    bitmap.allocN32Pixels(100, 100);
2512    SkCanvas offscreen(bitmap);
2513    offscreen.clear(0);
2514    SkPaint paint;
2515    paint.setAntiAlias(true);
2516    paint.setColor(SK_ColorBLUE);
2517    paint.setStyle(SkPaint::kStroke_Style);
2518    paint.setStrokeWidth(20);
2519    offscreen.drawCircle(50, 50, 39, paint);
2520    offscreen.flush();
2521    bitmap.extractAlpha(&alpha);
2522    paint.setColor(SK_ColorRED);
2523    canvas->drawBitmap(bitmap, 0, 0, &paint);
2524    canvas->drawBitmap(alpha, 100, 0, &paint);
2525##
2526
2527#SeeAlso extractSubset
2528
2529##
2530
2531# ------------------------------------------------------------------------------
2532
2533#Method bool extractAlpha(SkBitmap* dst, const SkPaint* paint,
2534                      SkIPoint* offset) const
2535#Populate
2536
2537#Example
2538#Height 160
2539    auto radiusToSigma = [](SkScalar radius) -> SkScalar {
2540         static const SkScalar kBLUR_SIGMA_SCALE = 0.57735f;
2541         return radius > 0 ? kBLUR_SIGMA_SCALE * radius + 0.5f : 0.0f;
2542    };
2543    SkBitmap alpha, bitmap;
2544    bitmap.allocN32Pixels(100, 100);
2545    SkCanvas offscreen(bitmap);
2546    offscreen.clear(0);
2547    SkPaint paint;
2548    paint.setAntiAlias(true);
2549    paint.setColor(SK_ColorBLUE);
2550    paint.setStyle(SkPaint::kStroke_Style);
2551    paint.setStrokeWidth(20);
2552    offscreen.drawCircle(50, 50, 39, paint);
2553    offscreen.flush();
2554    paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, radiusToSigma(25)));
2555    SkIPoint offset;
2556    bitmap.extractAlpha(&alpha, &paint, &offset);
2557    paint.setColor(SK_ColorRED);
2558    canvas->drawBitmap(bitmap, 0, -offset.fY, &paint);
2559    canvas->drawBitmap(alpha, 100 + offset.fX, 0, &paint);
2560##
2561
2562#SeeAlso extractSubset
2563
2564##
2565
2566# ------------------------------------------------------------------------------
2567
2568#Method bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
2569                      SkIPoint* offset) const
2570#Populate
2571
2572#Example
2573#Height 128
2574    SkBitmap alpha, bitmap;
2575    bitmap.allocN32Pixels(100, 100);
2576    SkCanvas offscreen(bitmap);
2577    offscreen.clear(0);
2578    SkPaint paint;
2579    paint.setAntiAlias(true);
2580    paint.setColor(SK_ColorBLUE);
2581    paint.setStyle(SkPaint::kStroke_Style);
2582    paint.setStrokeWidth(20);
2583    offscreen.drawCircle(50, 50, 39, paint);
2584    offscreen.flush();
2585    paint.setMaskFilter(SkMaskFilter::MakeBlur(kOuter_SkBlurStyle, 3));
2586    SkIPoint offset;
2587    bitmap.extractAlpha(&alpha, &paint, nullptr, &offset);
2588    paint.setColor(SK_ColorRED);
2589    canvas->drawBitmap(bitmap, 0, -offset.fY, &paint);
2590    canvas->drawBitmap(alpha, 100 + offset.fX, 0, &paint);
2591##
2592
2593#SeeAlso extractSubset
2594
2595##
2596
2597# ------------------------------------------------------------------------------
2598
2599#Method bool peekPixels(SkPixmap* pixmap) const
2600#In Pixels
2601#Line # returns Pixmap if possible ##
2602#Populate
2603
2604#Example
2605    SkBitmap bitmap;
2606    bitmap.allocPixels(SkImageInfo::MakeN32Premul(6, 11));
2607    SkCanvas offscreen(bitmap);
2608    offscreen.clear(SK_ColorWHITE);
2609    SkPaint paint;
2610    offscreen.drawString("?", 0, 10, paint);
2611    SkPixmap pixmap;
2612    if (bitmap.peekPixels(&pixmap)) {
2613        const SkPMColor* pixels = pixmap.addr32();
2614        SkPMColor pmWhite = pixels[0];
2615        for (int y = 0; y < bitmap.height(); ++y) {
2616            for (int x = 0; x < bitmap.width(); ++x) {
2617                SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
2618            }
2619            SkDebugf("\n");
2620        }
2621    }
2622    #StdOut
2623------
2624-xxx--
2625x---x-
2626----x-
2627---x--
2628--x---
2629--x---
2630------
2631--x---
2632--x---
2633------
2634    #StdOut ##
2635##
2636
2637#SeeAlso pixmap installPixels readPixels writePixels
2638
2639##
2640
2641# ------------------------------------------------------------------------------
2642#Subtopic Utility
2643#Line # rarely called management functions ##
2644##
2645
2646#Method void validate() const;
2647#In Utility
2648#Line # asserts if Bitmap is invalid (debug only) ##
2649#Populate
2650
2651#NoExample
2652##
2653
2654#SeeAlso SkImageInfo::validate
2655
2656##
2657
2658# ------------------------------------------------------------------------------
2659
2660#Class SkBitmap ##
2661
2662#Topic Bitmap ##
2663