1#Topic Bitmap
2#Alias Bitmaps
3#Alias Bitmap_Reference
4
5#Subtopic Overview
6    #Subtopic Subtopic
7    #Populate
8    ##
9##
10
11#Class SkBitmap
12
13Bitmap describes a two-dimensional raster pixel array. Bitmap is built on
14Image_Info, containing integer width and height, Color_Type and Alpha_Type
15describing the pixel format, and Color_Space describing the range of colors.
16Bitmap points to Pixel_Ref, which describes the physical array of pixels.
17Image_Info bounds may be located anywhere fully inside Pixel_Ref bounds.
18
19Bitmap can be drawn using Canvas. Bitmap can be a drawing destination for Canvas
20draw methods. Bitmap flexibility as a pixel container limits some optimizations
21available to the target platform.
22
23If pixel array is primarily read-only, use Image for better performance.
24If pixel array is primarily written to, use Surface for better performance.
25
26Declaring SkBitmap const prevents altering Image_Info: the Bitmap height, width,
27and so on cannot change. It does not affect Pixel_Ref: a caller may write its
28pixels. Declaring SkBitmap const affects Bitmap configuration, not its contents.
29
30Bitmap is not thread safe. Each thread must have its own copy of Bitmap fields,
31although threads may share the underlying pixel array.
32
33#Subtopic Row_Bytes
34#Line # interval from one row to the next ##
35Bitmap pixels may be contiguous, or may have a gap at the end of each row.
36Row_Bytes is the interval from one row to the next. Row_Bytes may be specified;
37sometimes passing zero will compute the Row_Bytes from the row width and the
38number of bytes in a pixel. Row_Bytes may be larger than the row requires. This
39is useful to position one or more Bitmaps within a shared pixel array.
40##
41
42#Subtopic Related_Function
43#Populate
44##
45
46#Subtopic Constant
47#Populate
48##
49
50#Subtopic Class_or_Struct
51#Populate
52##
53
54#Subtopic Constructor
55#Populate
56##
57
58#Subtopic Operator
59#Populate
60##
61
62#Subtopic Member_Function
63#Populate
64##
65
66# ------------------------------------------------------------------------------
67
68#Class Allocator
69#Line # abstract subclass of HeapAllocator ##
70#Code
71    class Allocator : public SkRefCnt {
72    public:
73        virtual bool allocPixelRef(SkBitmap* bitmap) = 0;
74    };
75##
76
77Abstract subclass of HeapAllocator.
78
79# ------------------------------------------------------------------------------
80
81#Method virtual bool allocPixelRef(SkBitmap* bitmap) = 0
82
83Allocates the pixel memory for the bitmap, given its dimensions and
84Color_Type. Returns true on success, where success means either setPixels
85or setPixelRef was called.
86
87#Param bitmap  Bitmap containing Image_Info as input, and Pixel_Ref as output ##
88
89#Return  true if Pixel_Ref was allocated ##
90
91#NoExample
92##
93
94#SeeAlso HeapAllocator
95
96##
97
98#Class Allocator ##
99
100# ------------------------------------------------------------------------------
101
102#Class HeapAllocator
103#Line # allocates pixel memory from heap ##
104
105#Code
106    class HeapAllocator : public Allocator {
107    public:
108        bool allocPixelRef(SkBitmap* bitmap) override;
109    };
110##
111
112Subclass of SkBitmap::Allocator that returns a Pixel_Ref that allocates its pixel
113memory from the heap. This is the default SkBitmap::Allocator invoked by
114allocPixels.
115
116# ------------------------------------------------------------------------------
117
118#Method bool allocPixelRef(SkBitmap* bitmap) override
119
120Allocates the pixel memory for the bitmap, given its dimensions and
121Color_Type. Returns true on success, where success means either setPixels
122or setPixelRef was called.
123
124#Param bitmap  Bitmap containing Image_Info as input, and Pixel_Ref as output ##
125
126#Return  true if pixels are allocated ##
127
128#Example
129    SkBitmap bitmap;
130    bitmap.setInfo(SkImageInfo::MakeN32(16, 16, kPremul_SkAlphaType));
131    SkDebugf("pixel address = %p\n", bitmap.getPixels());
132    SkBitmap::HeapAllocator stdalloc;
133    if (!stdalloc.allocPixelRef(&bitmap)) {
134        SkDebugf("pixel allocation failed\n");
135    } else {
136        SkDebugf("pixel address = %p\n", bitmap.getPixels());
137    }
138#StdOut
139#Volatile
140pixel address = (nil)
141pixel address = 0x560ddd0ac670
142##
143##
144
145#SeeAlso SkBitmap::Allocator tryAllocPixels
146
147##
148
149#Class HeapAllocator ##
150
151# ------------------------------------------------------------------------------
152
153#Method SkBitmap()
154
155#Line # constructs with default values ##
156Creates an empty Bitmap without pixels, with kUnknown_SkColorType,
157kUnknown_SkAlphaType, and with a width and height of zero. Pixel_Ref origin is
158set to (0, 0). Bitmap is not volatile.
159
160Use setInfo to associate SkColorType, SkAlphaType, width, and height
161after Bitmap has been created.
162
163#Return  empty Bitmap ##
164
165#Example
166void draw(SkCanvas* canvas) {
167    const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"};
168    const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
169                            "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
170    SkBitmap bitmap;
171    for (int i = 0; i < 2; ++i) {
172       SkDebugf("width: %2d  height: %2d", bitmap.width(), bitmap.height());
173       SkDebugf("  color: k%s_SkColorType", colors[bitmap.colorType()]);
174       SkDebugf("  alpha: k%s_SkAlphaType\n", alphas[bitmap.alphaType()]);
175       bitmap.setInfo(SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType),
176                      0);
177    }
178}
179#StdOut
180width:  0  height:  0  color: kUnknown_SkColorType  alpha: kUnknown_SkAlphaType
181width: 25  height: 35  color: kRGBA_8888_SkColorType  alpha: kOpaque_SkAlphaType
182##
183##
184
185#SeeAlso setInfo
186
187##
188
189# ------------------------------------------------------------------------------
190
191#Method SkBitmap(const SkBitmap& src)
192
193#Line # shares ownership of pixels ##
194Copies settings from src to returned Bitmap. Shares pixels if src has pixels
195allocated, so both bitmaps reference the same pixels.
196
197#Param src  Bitmap to copy Image_Info, and share Pixel_Ref ##
198
199#Return  copy of src ##
200
201#Example
202void draw(SkCanvas* canvas) {
203    SkBitmap original;
204    original.tryAllocPixels(SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
205    SkDebugf("original has pixels before copy: %s\n", original.getPixels() ? "true" : "false");
206    SkBitmap copy(original);
207    SkDebugf("original has pixels after copy: %s\n", original.getPixels() ? "true" : "false");
208    SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false");
209}
210#StdOut
211original has pixels before copy: true
212original has pixels after copy: true
213copy has pixels: true
214##
215##
216
217#SeeAlso setInfo setPixelRef setPixels swap
218
219##
220
221# ------------------------------------------------------------------------------
222
223#Method SkBitmap(SkBitmap&& src)
224
225#Line # takes ownership of pixels ##
226Copies settings from src to returned Bitmap. Moves ownership of src pixels to
227Bitmap.
228
229#Param src  Bitmap to copy Image_Info, and reassign Pixel_Ref ##
230
231#Return  copy of src ##
232
233#Example
234void draw(SkCanvas* canvas) {
235    SkBitmap original;
236    original.tryAllocPixels(SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
237    SkDebugf("original has pixels before move: %s\n", original.getPixels() ? "true" : "false");
238    SkBitmap copy(std::move(original));
239    SkDebugf("original has pixels after move: %s\n", original.getPixels() ? "true" : "false");
240    SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false");
241}
242#StdOut
243original has pixels before move: true
244original has pixels after move: false
245copy has pixels: true
246##
247##
248
249#SeeAlso setInfo setPixelRef setPixels swap
250
251##
252
253# ------------------------------------------------------------------------------
254
255#Method ~SkBitmap()
256
257#Line # releases ownership of pixels ##
258Decrements Pixel_Ref reference count, if Pixel_Ref is not nullptr.
259
260#NoExample
261##
262
263#SeeAlso Pixel_Ref
264
265##
266
267# ------------------------------------------------------------------------------
268
269#Method SkBitmap& operator=(const SkBitmap& src)
270
271#Line # shares ownership of pixels ##
272Copies settings from src to returned Bitmap. Shares pixels if src has pixels
273allocated, so both bitmaps reference the same pixels.
274
275#Param src  Bitmap to copy Image_Info, and share Pixel_Ref ##
276
277#Return  copy of src ##
278
279#Example
280void draw(SkCanvas* canvas) {
281    SkBitmap original;
282    original.tryAllocPixels(SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
283    SkDebugf("original has pixels before copy: %s\n", original.getPixels() ? "true" : "false");
284    SkBitmap copy = original;
285    SkDebugf("original has pixels after copy: %s\n", original.getPixels() ? "true" : "false");
286    SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false");
287}
288#StdOut
289original has pixels before copy: true
290original has pixels after copy: true
291copy has pixels: true
292##
293##
294
295#SeeAlso setInfo setPixelRef setPixels swap
296
297##
298
299# ------------------------------------------------------------------------------
300
301#Method SkBitmap& operator=(SkBitmap&& src)
302
303#Line # takes ownership of pixels ##
304Copies settings from src to returned Bitmap. Moves ownership of src pixels to
305Bitmap.
306
307#Param src  Bitmap to copy Image_Info, and reassign Pixel_Ref ##
308
309#Return  copy of src ##
310
311#Example
312void draw(SkCanvas* canvas) {
313    SkBitmap original;
314    original.tryAllocPixels(SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
315    SkDebugf("original has pixels before move: %s\n", original.getPixels() ? "true" : "false");
316    SkBitmap copy = std::move(original);
317    SkDebugf("original has pixels after move: %s\n", original.getPixels() ? "true" : "false");
318    SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false");
319}
320#StdOut
321original has pixels before move: true
322original has pixels after move: false
323copy has pixels: true
324##
325##
326
327#SeeAlso setInfo setPixelRef setPixels swap
328
329##
330
331# ------------------------------------------------------------------------------
332
333#Method void swap(SkBitmap& other)
334#In Utility
335#Line # exchanges Bitmap pair ##
336Swaps the fields of the two bitmaps.
337
338#Param other  Bitmap exchanged with original ##
339
340#Example
341void draw(SkCanvas* canvas) {
342    auto debugster = [](const char* prefix, const SkBitmap& b) -> void {
343        const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"};
344        const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
345                                "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
346        SkDebugf("%s width:%d height:%d colorType:k%s_SkColorType alphaType:k%s_SkAlphaType\n",
347                 prefix, b.width(), b.height(), colors[b.colorType()], alphas[b.alphaType()]);
348    };
349    SkBitmap one, two;
350    one.tryAllocPixels(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
351    two.tryAllocPixels(SkImageInfo::Make(2, 2, kBGRA_8888_SkColorType, kPremul_SkAlphaType));
352    for (int index = 0; index < 2; ++index) {
353       debugster("one", one);
354       debugster("two", two);
355       one.swap(two);
356    }
357}
358#StdOut
359one width:1 height:1 colorType:kRGBA_8888_SkColorType alphaType:kOpaque_SkAlphaType
360two width:2 height:2 colorType:kBGRA_8888_SkColorType alphaType:kPremul_SkAlphaType
361one width:2 height:2 colorType:kBGRA_8888_SkColorType alphaType:kPremul_SkAlphaType
362two width:1 height:1 colorType:kRGBA_8888_SkColorType alphaType:kOpaque_SkAlphaType
363##
364##
365
366#SeeAlso SkBitmap(SkBitmap&& src) operator=(SkBitmap&& src)
367
368##
369
370# ------------------------------------------------------------------------------
371#Subtopic Property
372#Populate
373#Line # metrics and attributes ##
374##
375
376#Method const SkPixmap& pixmap() const
377#In Property
378#Line # returns Pixmap ##
379Returns a constant reference to the Pixmap holding the Bitmap pixel
380address, row bytes, and Image_Info.
381
382#Return reference to Pixmap describing this Bitmap ##
383
384#Example
385    SkBitmap bitmap;
386    bitmap.allocPixels(SkImageInfo::MakeN32Premul(10, 11));
387    SkCanvas offscreen(bitmap);
388    offscreen.clear(SK_ColorWHITE);
389    SkPaint paint;
390    offscreen.drawString("&", 0, 10, paint);
391    const SkPixmap& pixmap = bitmap.pixmap();
392    if (pixmap.addr()) {
393        SkPMColor pmWhite = *pixmap.addr32(0, 0);
394        for (int y = 0; y < pixmap.height(); ++y) {
395            for (int x = 0; x < pixmap.width(); ++x) {
396                SkDebugf("%c", *pixmap.addr32(x, y) == pmWhite ? '-' : 'x');
397            }
398            SkDebugf("\n");
399        }
400    }
401    #StdOut
402----------
403---xx-----
404--x--x----
405--x-------
406--xx------
407--x-x---x-
408-x---x--x-
409-x----xx--
410-xx---x---
411--xxxx-xx-
412----------
413    #StdOut ##
414
415##
416
417#SeeAlso peekPixels installPixels readPixels writePixels
418
419##
420
421# ------------------------------------------------------------------------------
422
423#Method const SkImageInfo& info() const
424#In Property
425#Line # returns Image_Info ##
426Returns width, height, Alpha_Type, Color_Type, and Color_Space.
427
428#Return reference to Image_Info  ##
429
430#Example
431#Image 4
432void draw(SkCanvas* canvas) {
433    // SkBitmap source;  // pre-populated with soccer ball by fiddle.skia.org
434    const SkImageInfo& info = source.info();
435    const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"};
436    const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
437                            "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
438    SkDebugf("width: %d height: %d color: %s alpha: %s\n", info.width(), info.height(),
439                colors[info.colorType()], alphas[info.alphaType()]);
440#StdOut
441width: 56 height: 56 color: BGRA_8888 alpha: Opaque
442##
443}
444##
445
446#SeeAlso Image_Info
447
448##
449
450# ------------------------------------------------------------------------------
451
452#Method int width() const
453#In Property
454#Line # returns pixel column count ##
455Returns pixel count in each row. Should be equal or less than:
456
457#Formula
458rowBytes() / info().bytesPerPixel()
459##
460.
461
462Maybe be less than pixelRef().width(). Will not exceed pixelRef().width() less
463pixelRefOrigin().fX.
464
465#Return  pixel width in Image_Info ##
466
467#Example
468    SkImageInfo info = SkImageInfo::MakeA8(16, 32);
469    SkBitmap bitmap;
470    bitmap.setInfo(info);
471    SkDebugf("bitmap width: %d  info width: %d\n", bitmap.width(), info.width());
472#StdOut
473bitmap width: 16  info width: 16
474##
475##
476
477#SeeAlso height() SkPixelRef::width() SkImageInfo::width()
478
479##
480
481# ------------------------------------------------------------------------------
482
483#Method int height() const
484#In Property
485#Line # returns pixel row count ##
486Returns pixel row count.
487
488Maybe be less than pixelRef().height(). Will not exceed pixelRef().height() less
489pixelRefOrigin().fY.
490
491#Return pixel height in Image_Info ##
492
493#Example
494    SkImageInfo info = SkImageInfo::MakeA8(16, 32);
495    SkBitmap bitmap;
496    bitmap.setInfo(info);
497    SkDebugf("bitmap height: %d  info height: %d\n", bitmap.height(), info.height());
498#StdOut
499bitmap height: 32  info height: 32
500##
501##
502
503#SeeAlso width() SkPixelRef::height() SkImageInfo::height()
504
505##
506
507# ------------------------------------------------------------------------------
508
509#Method SkColorType colorType() const
510#In Property
511#Line # returns Image_Info Color_Type ##
512Returns Color_Type, one of: kUnknown_SkColorType, kAlpha_8_SkColorType,
513kRGB_565_SkColorType, kARGB_4444_SkColorType, kRGBA_8888_SkColorType,
514kBGRA_8888_SkColorType, kGray_8_SkColorType, kRGBA_F16_SkColorType.
515
516#Return  Color_Type in Image_Info ##
517
518#Example
519    const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
520                            "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
521    SkBitmap bitmap;
522    bitmap.setInfo(SkImageInfo::MakeA8(16, 32));
523    SkDebugf("color type: k" "%s" "_SkColorType\n", colors[bitmap.colorType()]);
524#StdOut
525color type: kAlpha_8_SkColorType
526##
527##
528
529#SeeAlso alphaType() SkImageInfo::colorType
530
531##
532
533# ------------------------------------------------------------------------------
534
535#Method SkAlphaType alphaType() const
536#In Property
537#Line # returns Image_Info Alpha_Type ##
538Returns Alpha_Type, one of: kUnknown_SkAlphaType, kOpaque_SkAlphaType,
539kPremul_SkAlphaType, kUnpremul_SkAlphaType.
540
541#Return  Alpha_Type in Image_Info ##
542
543#Example
544    const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"};
545    SkPixmap pixmap(SkImageInfo::MakeA8(16, 32), nullptr, 64);
546    SkDebugf("alpha type: k" "%s" "_SkAlphaType\n", alphas[pixmap.alphaType()]);
547#StdOut
548alpha type: kPremul_SkAlphaType
549##
550##
551
552#SeeAlso colorType() SkImageInfo::alphaType
553
554##
555
556# ------------------------------------------------------------------------------
557
558#Method SkColorSpace* colorSpace() const
559#In Property
560#Line # returns Image_Info Color_Space ##
561Returns Color_Space, the range of colors, associated with Image_Info. The
562reference count of Color_Space is unchanged. The returned Color_Space is
563immutable.
564
565#Return Color_Space in Image_Info, or nullptr ##
566
567#Example
568#Description
569SkColorSpace::MakeSRGBLinear creates Color_Space with linear gamma
570and an sRGB gamut. This Color_Space gamma is not close to sRGB gamma.
571##
572    SkBitmap bitmap;
573    bitmap.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType,
574            SkColorSpace::MakeSRGBLinear()));
575    SkColorSpace* colorSpace = bitmap.colorSpace();
576    SkDebugf("gammaCloseToSRGB: %s  gammaIsLinear: %s  isSRGB: %s\n",
577            colorSpace->gammaCloseToSRGB() ? "true" : "false",
578            colorSpace->gammaIsLinear() ? "true" : "false",
579            colorSpace->isSRGB() ? "true" : "false");
580#StdOut
581gammaCloseToSRGB: false  gammaIsLinear: true  isSRGB: false
582##
583##
584
585#SeeAlso Color_Space SkImageInfo::colorSpace
586
587##
588
589# ------------------------------------------------------------------------------
590
591#Method sk_sp<SkColorSpace> refColorSpace() const
592#In Property
593#Line # returns Image_Info Color_Space ##
594Returns a smart pointer to Color_Space, the range of colors, associated with
595Image_Info. The smart pointer tracks the number of objects sharing this
596Color_Space reference so the memory is released when the owners destruct.
597
598The returned Color_Space is immutable.
599
600#Return Color_Space in Image_Info wrapped in a smart pointer ##
601
602#Example
603    SkBitmap bitmap1, bitmap2;
604    bitmap1.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType,
605            SkColorSpace::MakeSRGBLinear()));
606    bitmap2.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType,
607            bitmap1.refColorSpace()));
608    SkColorSpace* colorSpace = bitmap2.colorSpace();
609    SkDebugf("gammaCloseToSRGB: %s  gammaIsLinear: %s  isSRGB: %s\n",
610            colorSpace->gammaCloseToSRGB() ? "true" : "false",
611            colorSpace->gammaIsLinear() ? "true" : "false",
612            colorSpace->isSRGB() ? "true" : "false");
613#StdOut
614gammaCloseToSRGB: false  gammaIsLinear: true  isSRGB: false
615##
616##
617
618#SeeAlso Color_Space SkImageInfo::colorSpace
619
620##
621
622# ------------------------------------------------------------------------------
623
624#Method int bytesPerPixel() const
625#In Property
626#Line # returns number of bytes in pixel based on Color_Type ##
627Returns number of bytes per pixel required by Color_Type.
628Returns zero if colorType( is kUnknown_SkColorType.
629
630#Return  bytes in pixel ##
631
632#Example
633    const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
634                            "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
635    SkImageInfo info = SkImageInfo::MakeA8(1, 1);
636    SkBitmap bitmap;
637    for (SkColorType colorType : { kUnknown_SkColorType,     kAlpha_8_SkColorType,
638                                   kRGB_565_SkColorType,     kARGB_4444_SkColorType,
639                                   kRGBA_8888_SkColorType,
640                                   kBGRA_8888_SkColorType,   kGray_8_SkColorType,
641                                   kRGBA_F16_SkColorType } ) {
642        bitmap.setInfo(info.makeColorType(colorType));
643        SkDebugf("color: k" "%s" "_SkColorType" "%*s" "bytesPerPixel: %d\n",
644                colors[colorType], 13 - strlen(colors[colorType]), " ",
645                bitmap.bytesPerPixel());
646    }
647#StdOut
648color: kUnknown_SkColorType      bytesPerPixel: 0
649color: kAlpha_8_SkColorType      bytesPerPixel: 1
650color: kRGB_565_SkColorType      bytesPerPixel: 2
651color: kARGB_4444_SkColorType    bytesPerPixel: 2
652color: kRGBA_8888_SkColorType    bytesPerPixel: 4
653color: kBGRA_8888_SkColorType    bytesPerPixel: 4
654color: kGray_8_SkColorType       bytesPerPixel: 1
655color: kRGBA_F16_SkColorType     bytesPerPixel: 8
656##
657##
658
659#SeeAlso rowBytes rowBytesAsPixels width shiftPerPixel
660
661##
662
663# ------------------------------------------------------------------------------
664
665#Method int rowBytesAsPixels() const
666#In Property
667#Line # returns interval between rows in pixels ##
668Returns number of pixels that fit on row. Should be greater than or equal to
669width().
670
671#Return  maximum pixels per row ##
672
673#Example
674    SkBitmap bitmap;
675    for (int rowBytes : { 4, 5, 6, 7, 8} ) {
676        bitmap.setInfo(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType), rowBytes);
677        SkDebugf("rowBytes: %d rowBytesAsPixels: %d\n", rowBytes, bitmap.rowBytesAsPixels());
678    }
679#StdOut
680rowBytes: 4 rowBytesAsPixels: 1
681rowBytes: 5 rowBytesAsPixels: 1
682rowBytes: 6 rowBytesAsPixels: 1
683rowBytes: 7 rowBytesAsPixels: 1
684rowBytes: 8 rowBytesAsPixels: 2
685##
686##
687
688#SeeAlso rowBytes shiftPerPixel width bytesPerPixel
689
690##
691
692# ------------------------------------------------------------------------------
693
694#Method int shiftPerPixel() const
695#In Property
696#Line # returns bit shift from pixels to bytes ##
697Returns bit shift converting row bytes to row pixels.
698Returns zero for kUnknown_SkColorType.
699
700#Return one of: 0, 1, 2, 3; left shift to convert pixels to bytes ##
701
702#Example
703    const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
704                            "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
705    SkImageInfo info = SkImageInfo::MakeA8(1, 1);
706    SkBitmap bitmap;
707    for (SkColorType colorType : { kUnknown_SkColorType,   kAlpha_8_SkColorType,
708                                   kRGB_565_SkColorType,   kARGB_4444_SkColorType,
709                                   kRGBA_8888_SkColorType, kBGRA_8888_SkColorType,
710                                   kGray_8_SkColorType,    kRGBA_F16_SkColorType } ) {
711        bitmap.setInfo(info.makeColorType(colorType));
712        SkDebugf("color: k" "%s" "_SkColorType" "%*s" "shiftPerPixel: %d\n",
713                colors[colorType], 10 - strlen(colors[colorType]), " ",
714                bitmap.shiftPerPixel());
715    }
716#StdOut
717color: kUnknown_SkColorType   shiftPerPixel: 0
718color: kAlpha_8_SkColorType   shiftPerPixel: 0
719color: kRGB_565_SkColorType   shiftPerPixel: 1
720color: kARGB_4444_SkColorType shiftPerPixel: 1
721color: kRGBA_8888_SkColorType shiftPerPixel: 2
722color: kBGRA_8888_SkColorType shiftPerPixel: 2
723color: kGray_8_SkColorType    shiftPerPixel: 0
724color: kRGBA_F16_SkColorType  shiftPerPixel: 3
725##
726##
727
728#SeeAlso rowBytes rowBytesAsPixels width bytesPerPixel
729
730##
731
732# ------------------------------------------------------------------------------
733
734#Method bool empty() const
735#In Property
736#Line # returns true if Image_Info has zero width() or height() ##
737Returns true if either width() or height() are zero.
738
739Does not check if Pixel_Ref is nullptr; call drawsNothing to check width(),
740height(), and Pixel_Ref.
741
742#Return  true if dimensions do not enclose area ##
743
744#Example
745    SkBitmap bitmap;
746    for (int width : { 0, 2 } ) {
747        for (int height : { 0, 2 } ) {
748             bitmap.setInfo(SkImageInfo::MakeA8(width, height));
749             SkDebugf("width: %d height: %d empty: %s\n", width, height,
750                      bitmap.empty() ? "true" : "false");
751        }
752    }
753#StdOut
754width: 0 height: 0 empty: true
755width: 0 height: 2 empty: true
756width: 2 height: 0 empty: true
757width: 2 height: 2 empty: false
758##
759##
760
761#SeeAlso height() width() drawsNothing
762
763##
764
765# ------------------------------------------------------------------------------
766
767#Method bool isNull() const
768#In Property
769#Line # returns true if Pixel_Ref is nullptr ##
770Return true if Pixel_Ref is nullptr.
771
772Does not check if width() or height() are zero; call drawsNothing to check
773width(), height(), and Pixel_Ref.
774
775#Return  true if no Pixel_Ref is associated ##
776
777#Example
778    SkBitmap bitmap;
779    SkDebugf("empty bitmap does %shave pixels\n", bitmap.isNull() ? "not " : "");
780    bitmap.setInfo(SkImageInfo::MakeA8(8, 8));
781    SkDebugf("bitmap with dimensions does %shave pixels\n", bitmap.isNull() ? "not " : "");
782    bitmap.allocPixels();
783    SkDebugf("allocated bitmap does %shave pixels\n", bitmap.isNull() ? "not " : "");
784#StdOut
785empty bitmap does not have pixels
786bitmap with dimensions does not have pixels
787allocated bitmap does have pixels
788##
789##
790
791#SeeAlso empty() drawsNothing pixelRef
792
793##
794
795# ------------------------------------------------------------------------------
796
797#Method bool drawsNothing() const
798#In Property
799#Line # returns true if no width(), no height(), or no Pixel_Ref ##
800Return true if width() or height() are zero, or if Pixel_Ref is nullptr.
801If true, Bitmap has no effect when drawn or drawn into.
802
803#Return  true if drawing has no effect ##
804
805#Example
806    SkBitmap bitmap;
807    for (int w : { 0, 8 } ) {
808        for (bool allocate : { false, true} ) {
809            bitmap.setInfo(SkImageInfo::MakeA8(w, 8));
810            allocate ? bitmap.allocPixels() : (void) 0 ;
811            SkDebugf("empty:%s isNull:%s drawsNothing:%s\n", bitmap.empty() ? "true " : "false",
812                     bitmap.isNull() ? "true " : "false", bitmap.drawsNothing() ? "true" : "false");
813        }
814    }
815#StdOut
816empty:true  isNull:true  drawsNothing:true
817empty:true  isNull:false drawsNothing:true
818empty:false isNull:true  drawsNothing:true
819empty:false isNull:false drawsNothing:false
820##
821##
822
823#SeeAlso empty() isNull pixelRef
824
825##
826
827# ------------------------------------------------------------------------------
828
829#Method size_t rowBytes() const
830#In Property
831#Line # returns interval between rows in bytes ##
832Returns row bytes, the interval from one pixel row to the next. Row bytes
833is at least as large as
834#Formula
835width() * info().bytesPerPixel()
836##
837.
838
839Returns zero if colorType is kUnknown_SkColorType, or if row bytes supplied to
840setInfo is not large enough to hold a row of pixels.
841
842#Return  byte length of pixel row ##
843
844#Example
845   SkBitmap bitmap;
846   for (int rowBytes : { 2, 8 } ) {
847       bool result = bitmap.setInfo(SkImageInfo::MakeA8(4, 4), rowBytes);
848       SkDebugf("setInfo returned:%s rowBytes:%d\n", result ? "true " : "false", bitmap.rowBytes());
849    }
850#StdOut
851setInfo returned:false rowBytes:0
852setInfo returned:true  rowBytes:8
853##
854##
855
856#SeeAlso info() setInfo SkImageInfo::minRowBytes
857
858##
859
860# ------------------------------------------------------------------------------
861
862#Method bool setAlphaType(SkAlphaType alphaType)
863#In Set
864#Line # sets Alpha_Type of shared pixels ##
865Sets Alpha_Type, if alphaType is compatible with Color_Type.
866Returns true unless alphaType is kUnknown_SkAlphaType and current Alpha_Type
867is not kUnknown_SkAlphaType.
868
869Returns true if Color_Type is kUnknown_SkColorType. alphaType is ignored, and
870Alpha_Type remains kUnknown_SkAlphaType.
871
872Returns true if Color_Type is kRGB_565_SkColorType or kGray_8_SkColorType.
873alphaType is ignored, and Alpha_Type remains kOpaque_SkAlphaType.
874
875If Color_Type is kARGB_4444_SkColorType, kRGBA_8888_SkColorType,
876kBGRA_8888_SkColorType, or kRGBA_F16_SkColorType: returns true unless
877alphaType is kUnknown_SkAlphaType and Alpha_Type is not kUnknown_SkAlphaType.
878If Alpha_Type is kUnknown_SkAlphaType, alphaType is ignored.
879
880If Color_Type is kAlpha_8_SkColorType, returns true unless
881alphaType is kUnknown_SkAlphaType and Alpha_Type is not kUnknown_SkAlphaType.
882If Alpha_Type is kUnknown_SkAlphaType, alphaType is ignored. If alphaType is
883kUnpremul_SkAlphaType, it is treated as kPremul_SkAlphaType.
884
885This changes Alpha_Type in Pixel_Ref; all bitmaps sharing Pixel_Ref
886are affected.
887
888#Param alphaType  one of: kUnknown_SkAlphaType, kOpaque_SkAlphaType,
889                          kPremul_SkAlphaType, kUnpremul_SkAlphaType
890##
891
892#Return  true if Alpha_Type is set ##
893
894#Example
895void draw(SkCanvas* canvas) {
896    const char* colors[] = { "Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
897                             "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16" };
898    const char* alphas[] = {"Unknown ", "Opaque  ", "Premul  ", "Unpremul"};
899    SkBitmap bitmap;
900    SkAlphaType alphaTypes[] = { kUnknown_SkAlphaType, kOpaque_SkAlphaType,
901                                 kPremul_SkAlphaType, kUnpremul_SkAlphaType };
902    SkDebugf("%88s", "Canonical    Unknown           Opaque            Premul            Unpremul\n");
903    for (SkColorType colorType : { kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType,
904                            kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kBGRA_8888_SkColorType,
905                            kGray_8_SkColorType, kRGBA_F16_SkColorType } ) {
906        for (SkAlphaType canonicalAlphaType : alphaTypes) {
907            SkColorTypeValidateAlphaType(colorType, kUnknown_SkAlphaType, &canonicalAlphaType );
908            SkDebugf("%10s %10s ", colors[(int) colorType], alphas[(int) canonicalAlphaType ]);
909            for (SkAlphaType alphaType : alphaTypes) {
910                bitmap.setInfo(SkImageInfo::Make(4, 4, colorType, canonicalAlphaType));
911                bool result = bitmap.setAlphaType(alphaType);
912                SkDebugf("%s %s    ", result ? "true " : "false", alphas[(int) bitmap.alphaType()]);
913            }
914            SkDebugf("\n");
915        }
916    }
917}
918##
919
920#SeeAlso Alpha_Type Color_Type Image_Info setInfo
921
922##
923
924# ------------------------------------------------------------------------------
925
926#Method void* getPixels() const
927#In Property
928#Line # returns address of pixels ##
929Returns pixel address, the base address corresponding to the pixel origin.
930
931#Return  pixel address ##
932
933#Example
934    SkBitmap bitmap;
935    bitmap.setInfo(SkImageInfo::MakeN32(4, 4, kPremul_SkAlphaType));
936    bitmap.allocPixels();
937    bitmap.eraseColor(0x00000000);
938    void* baseAddr = bitmap.getPixels();
939    *(SkPMColor*)baseAddr = 0xFFFFFFFF;
940    SkDebugf("bitmap.getColor(0, 1) %c= 0x00000000\n",
941              bitmap.getColor(0, 1)  == 0x00000000 ? '=' : '!');
942    SkDebugf("bitmap.getColor(0, 0) %c= 0xFFFFFFFF\n",
943              bitmap.getColor(0, 0)  == 0xFFFFFFFF ? '=' : '!');
944#StdOut
945bitmap.getColor(0, 1) == 0x00000000
946bitmap.getColor(0, 0) == 0xFFFFFFFF
947##
948##
949
950#SeeAlso isNull drawsNothing
951
952##
953
954# ------------------------------------------------------------------------------
955
956#Method size_t computeByteSize() const
957#In Utility
958#Line # returns size required for pixels ##
959Returns minimum memory required for pixel storage.
960Does not include unused memory on last row when rowBytesAsPixels exceeds width().
961Returns zero if result does not fit in size_t.
962Returns zero if height() or width() is 0.
963Returns height() times rowBytes if colorType is kUnknown_SkColorType.
964
965#Return size in bytes of image buffer ##
966
967#Example
968    SkBitmap bitmap;
969    for (int width : { 1, 1000, 1000000 } ) {
970        for (int height: { 1, 1000, 1000000 } ) {
971            SkImageInfo imageInfo = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType);
972            bitmap.setInfo(imageInfo, width * 5);
973            SkDebugf("width: %7d height: %7d computeByteSize: %13lld\n", width, height,
974                     bitmap.computeByteSize());
975        }
976    }
977#StdOut
978width:       1 height:       1 computeByteSize:             4
979width:       1 height:    1000 computeByteSize:          4999
980width:       1 height: 1000000 computeByteSize:       4999999
981width:    1000 height:       1 computeByteSize:          4000
982width:    1000 height:    1000 computeByteSize:       4999000
983width:    1000 height: 1000000 computeByteSize:    4999999000
984width: 1000000 height:       1 computeByteSize:       4000000
985width: 1000000 height:    1000 computeByteSize:    4999000000
986width: 1000000 height: 1000000 computeByteSize: 4999999000000
987##
988##
989
990#SeeAlso SkImageInfo::computeByteSize
991
992##
993
994# ------------------------------------------------------------------------------
995
996#Method bool isImmutable() const
997#In Property
998#Line # returns true if pixels will not change ##
999Returns true if pixels can not change.
1000
1001Most immutable Bitmap checks trigger an assert only on debug builds.
1002
1003#Return  true if pixels are immutable ##
1004
1005#Example
1006    SkBitmap original;
1007    SkImageInfo info = SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
1008    if (original.tryAllocPixels(info)) {
1009        original.setImmutable();
1010        SkBitmap copy;
1011        original.extractSubset(&copy, {5, 10, 15, 20});
1012        SkDebugf("original is " "%s" "immutable\n", original.isImmutable() ? "" : "not ");
1013        SkDebugf("copy is " "%s" "immutable\n", copy.isImmutable() ? "" : "not ");
1014    }
1015#StdOut
1016original is immutable
1017copy is immutable
1018##
1019##
1020
1021#SeeAlso setImmutable SkPixelRef::isImmutable SkImage
1022
1023##
1024
1025# ------------------------------------------------------------------------------
1026
1027#Method void setImmutable()
1028#In Set
1029#Line # marks that pixels will not change ##
1030Sets internal flag to mark Bitmap as immutable. Once set, pixels can not change.
1031Any other bitmap sharing the same Pixel_Ref are also marked as immutable.
1032Once Pixel_Ref is marked immutable, the setting cannot be cleared.
1033
1034Writing to immutable Bitmap pixels triggers an assert on debug builds.
1035
1036#Example
1037#Description
1038Triggers assert if SK_DEBUG is true, runs fine otherwise.
1039##
1040    SkBitmap bitmap;
1041    bitmap.setInfo(SkImageInfo::MakeN32(4, 4, kPremul_SkAlphaType));
1042    bitmap.allocPixels();
1043    SkCanvas offscreen(bitmap);
1044    SkDebugf("draw white\n");
1045    offscreen.clear(SK_ColorWHITE);
1046    bitmap.setImmutable();
1047    SkDebugf("draw black\n");
1048    offscreen.clear(SK_ColorBLACK);
1049##
1050
1051#SeeAlso isImmutable SkPixelRef::setImmutable SkImage
1052
1053##
1054
1055# ------------------------------------------------------------------------------
1056
1057#Method bool isOpaque() const
1058#In Property
1059#Line # returns true if Image_Info describes opaque pixels ##
1060Returns true if Alpha_Type is kOpaque_SkAlphaType.
1061Does not check if Color_Type allows Alpha, or if any pixel value has
1062transparency.
1063
1064#Return  true if Image_Info describes opaque Alpha ##
1065
1066#Example
1067#Description
1068    isOpaque ignores whether all pixels are opaque or not.
1069##
1070    const int height = 2;
1071    const int width = 2;
1072    SkBitmap bitmap;
1073    bitmap.setInfo(SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType));
1074    for (int index = 0; index < 2; ++index) {
1075        bitmap.allocPixels();
1076        bitmap.eraseColor(0x00000000);
1077        SkDebugf("isOpaque: %s\n", bitmap.isOpaque() ? "true" : "false");
1078        bitmap.eraseColor(0xFFFFFFFF);
1079        SkDebugf("isOpaque: %s\n", bitmap.isOpaque() ? "true" : "false");
1080        bitmap.setInfo(bitmap.info().makeAlphaType(kOpaque_SkAlphaType));
1081    }
1082#StdOut
1083isOpaque: false
1084isOpaque: false
1085isOpaque: true
1086isOpaque: true
1087##
1088##
1089
1090#SeeAlso ComputeIsOpaque SkImageInfo::isOpaque
1091
1092##
1093
1094# ------------------------------------------------------------------------------
1095
1096#Method bool isVolatile() const
1097#In Property
1098#Line # returns true if pixels should not be cached ##
1099If true, provides a hint to caller that pixels should not
1100be cached. Only true if setIsVolatile has been called to mark as volatile.
1101
1102Volatile state is not shared by other bitmaps sharing the same Pixel_Ref.
1103
1104#Return  true if marked volatile ##
1105
1106#Example
1107    SkBitmap original;
1108    SkImageInfo info = SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
1109    if (original.tryAllocPixels(info)) {
1110        original.setIsVolatile(true);
1111        SkBitmap copy;
1112        original.extractSubset(&copy, {5, 10, 15, 20});
1113        SkDebugf("original is " "%s" "volatile\n", original.isVolatile() ? "" : "not ");
1114        SkDebugf("copy is " "%s" "volatile\n", copy.isImmutable() ? "" : "not ");
1115    }
1116#StdOut
1117original is volatile
1118copy is not volatile
1119##
1120##
1121
1122#SeeAlso setIsVolatile
1123
1124##
1125
1126# ------------------------------------------------------------------------------
1127
1128#Method void setIsVolatile(bool isVolatile)
1129#In Set
1130#Line # marks if pixels should not be cached ##
1131Sets if pixels should be read from Pixel_Ref on every access. Bitmaps are not
1132volatile by default; a GPU back end may upload pixel values expecting them to be
1133accessed repeatedly. Marking temporary Bitmaps as volatile provides a hint to
1134Device that the Bitmap pixels should not be cached. This can
1135improve performance by avoiding overhead and reducing resource
1136consumption on Device.
1137
1138#Param isVolatile  true if backing pixels are temporary ##
1139
1140#Example
1141#Height 20
1142    SkBitmap bitmap;
1143    bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
1144    bitmap.allocPixels();
1145    bitmap.eraseColor(SK_ColorRED);
1146    canvas->scale(16, 16);
1147    canvas->drawBitmap(bitmap, 0, 0);
1148    *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorBLUE);
1149    canvas->drawBitmap(bitmap, 2, 0);
1150    bitmap.setIsVolatile(true);
1151    *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorGREEN);
1152    canvas->drawBitmap(bitmap, 4, 0);
1153##
1154
1155#SeeAlso isVolatile
1156
1157##
1158
1159# ------------------------------------------------------------------------------
1160
1161#Method void reset()
1162#In Constructor
1163#Line # sets to default values, releases pixel ownership ##
1164Resets to its initial state; all fields are set to zero, as if Bitmap had
1165been initialized by SkBitmap().
1166
1167Sets width, height, row bytes to zero; pixel address to nullptr; SkColorType to
1168kUnknown_SkColorType; and SkAlphaType to kUnknown_SkAlphaType.
1169
1170If Pixel_Ref is allocated, its reference count is decreased by one, releasing
1171its memory if Bitmap is the sole owner.
1172
1173#Example
1174    SkBitmap bitmap;
1175    bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
1176    bitmap.allocPixels();
1177    SkDebugf("width:%d height:%d isNull:%s\n", bitmap.width(), bitmap.height(),
1178             bitmap.isNull() ? "true" : "false");
1179    bitmap.reset();
1180    SkDebugf("width:%d height:%d isNull:%s\n", bitmap.width(), bitmap.height(),
1181             bitmap.isNull() ? "true" : "false");
1182#StdOut
1183width:1 height:1 isNull:false
1184width:0 height:0 isNull:true
1185##
1186##
1187
1188#SeeAlso SkBitmap() SkAlphaType SkColorType
1189
1190##
1191
1192# ------------------------------------------------------------------------------
1193
1194#Method static bool ComputeIsOpaque(const SkBitmap& bm)
1195#In Utility
1196#Line # returns true if all pixels are opaque ##
1197Returns true if all pixels are opaque. Color_Type determines how pixels
1198are encoded, and whether pixel describes Alpha. Returns true for Color_Types
1199without alpha in each pixel; for other Color_Types, returns true if all
1200pixels have alpha values equivalent to 1.0 or greater.
1201
1202For Color_Types kRGB_565_SkColorType or kGray_8_SkColorType: always
1203returns true. For Color_Types kAlpha_8_SkColorType, kBGRA_8888_SkColorType,
1204kRGBA_8888_SkColorType: returns true if all pixel Alpha values are 255.
1205For Color_Type kARGB_4444_SkColorType: returns true if all pixel Alpha values are 15.
1206For kRGBA_F16_SkColorType: returns true if all pixel Alpha values are 1.0 or
1207greater.
1208
1209Returns false for kUnknown_SkColorType.
1210
1211#Param bm  Bitmap to check ##
1212
1213#Return true if all pixels have opaque values or Color_Type is opaque ##
1214
1215#Example
1216    SkBitmap bitmap;
1217    bitmap.setInfo(SkImageInfo::Make(2, 2, kN32_SkColorType, kPremul_SkAlphaType));
1218    for (int index = 0; index < 2; ++index) {
1219        bitmap.allocPixels();
1220        bitmap.eraseColor(0x00000000);
1221        SkDebugf("computeIsOpaque: %s\n", SkBitmap::ComputeIsOpaque(bitmap) ? "true" : "false");
1222        bitmap.eraseColor(0xFFFFFFFF);
1223        SkDebugf("computeIsOpaque: %s\n", SkBitmap::ComputeIsOpaque(bitmap) ? "true" : "false");
1224        bitmap.setInfo(bitmap.info().makeAlphaType(kOpaque_SkAlphaType));
1225    }
1226#StdOut
1227computeIsOpaque: false
1228computeIsOpaque: true
1229computeIsOpaque: false
1230computeIsOpaque: true
1231##
1232##
1233
1234#SeeAlso isOpaque Color_Type Alpha
1235
1236##
1237
1238# ------------------------------------------------------------------------------
1239
1240#Method void getBounds(SkRect* bounds) const
1241#In Property
1242#Line # returns width() and height() as Rectangle ##
1243Returns Rect { 0, 0, width(), height() }.
1244
1245#Param bounds container for floating point rectangle ##
1246
1247#Example
1248#Height 160
1249#Image 3
1250    SkRect bounds;
1251    source.getBounds(&bounds);
1252    bounds.offset(100, 100);
1253    SkPaint paint;
1254    paint.setColor(SK_ColorGRAY);
1255    canvas->scale(.25f, .25f);
1256    canvas->drawRect(bounds, paint);
1257    canvas->drawBitmap(source, 40, 40);
1258##
1259
1260#SeeAlso bounds()
1261
1262##
1263
1264# ------------------------------------------------------------------------------
1265
1266#Method void getBounds(SkIRect* bounds) const
1267
1268Returns IRect { 0, 0, width(), height() }.
1269
1270#Param bounds container for integral rectangle ##
1271
1272#Example
1273#Image 3
1274    SkIRect bounds;
1275    source.getBounds(&bounds);
1276    bounds.inset(100, 100);
1277    SkBitmap bitmap;
1278    source.extractSubset(&bitmap, bounds);
1279    canvas->scale(.5f, .5f);
1280    canvas->drawBitmap(bitmap, 10, 10);
1281##
1282
1283#SeeAlso bounds()
1284
1285##
1286
1287# ------------------------------------------------------------------------------
1288
1289#Method SkIRect bounds() const
1290#In Property
1291#Line # returns width() and height() as Rectangle ##
1292Returns IRect { 0, 0, width(), height() }.
1293
1294#Return  integral rectangle from origin to width() and height() ##
1295
1296#Example
1297#Height 128
1298#Image 4
1299    canvas->scale(.5f, .5f);
1300    SkIRect bounds = source.bounds();
1301    for (int x : { 0, bounds.width() } ) {
1302        for (int y : { 0, bounds.height() } ) {
1303            canvas->drawBitmap(source, x, y);
1304        }
1305    }
1306##
1307
1308#SeeAlso getBounds
1309
1310##
1311
1312# ------------------------------------------------------------------------------
1313
1314#Method SkISize dimensions() const
1315#In Property
1316#Line # returns width() and height() ##
1317Returns ISize { width(), height() }.
1318
1319#Return integral size of width() and height() ##
1320
1321#Example
1322    SkBitmap bitmap;
1323    bitmap.setInfo(SkImageInfo::MakeN32(33, 55, kOpaque_SkAlphaType));
1324    SkISize dimensions = bitmap.dimensions();
1325    SkRect bounds;
1326    bitmap.getBounds(&bounds);
1327    SkRect dimensionsAsBounds = SkRect::Make(dimensions);
1328    SkDebugf("dimensionsAsBounds %c= bounds\n", dimensionsAsBounds == bounds ? '=' : '!');
1329##
1330
1331#SeeAlso height() width()
1332
1333##
1334
1335# ------------------------------------------------------------------------------
1336
1337#Method SkIRect getSubset() const
1338#In Property
1339#Line # returns bounds offset by origin ##
1340Returns the bounds of this bitmap, offset by its Pixel_Ref origin.
1341
1342#Return bounds within Pixel_Ref bounds ##
1343
1344#Example
1345#Image 3
1346    SkIRect bounds;
1347    source.getBounds(&bounds);
1348    bounds.inset(100, 100);
1349    SkBitmap subset;
1350    source.extractSubset(&subset, bounds);
1351    SkIRect r = source.getSubset();
1352    SkDebugf("source: %d, %d, %d, %d\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
1353    r = subset.getSubset();
1354    SkDebugf("subset: %d, %d, %d, %d\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
1355#StdOut
1356source: 0, 0, 512, 512
1357subset: 100, 100, 412, 412
1358##
1359##
1360
1361#SeeAlso extractSubset getBounds
1362
1363##
1364
1365# ------------------------------------------------------------------------------
1366
1367#Method bool setInfo(const SkImageInfo& imageInfo, size_t rowBytes = 0)
1368#In Set
1369#Line # sets height, width, Color_Type, and so on, releasing pixels ##
1370Sets width, height, Alpha_Type, Color_Type, Color_Space, and optional
1371rowBytes. Frees pixels, and returns true if successful.
1372
1373imageInfo.alphaType may be altered to a value permitted by imageInfo.colorSpace.
1374If imageInfo.colorType is kUnknown_SkColorType, imageInfo.alphaType is
1375set to kUnknown_SkAlphaType.
1376If imageInfo.colorType is kAlpha_8_SkColorType and imageInfo.alphaType is
1377kUnpremul_SkAlphaType, imageInfo.alphaType is replaced by kPremul_SkAlphaType.
1378If imageInfo.colorType is kRGB_565_SkColorType or kGray_8_SkColorType,
1379imageInfo.alphaType is set to kOpaque_SkAlphaType.
1380If imageInfo.colorType is kARGB_4444_SkColorType, kRGBA_8888_SkColorType,
1381kBGRA_8888_SkColorType, or kRGBA_F16_SkColorType: imageInfo.alphaType remains
1382unchanged.
1383
1384rowBytes must equal or exceed imageInfo.minRowBytes. If imageInfo.colorSpace is
1385kUnknown_SkColorType, rowBytes is ignored and treated as zero; for all other
1386Color_Space values, rowBytes of zero is treated as imageInfo.minRowBytes.
1387
1388Calls reset() and returns false if:
1389#List
1390# rowBytes exceeds 31 bits ##
1391# imageInfo.width() is negative ##
1392# imageInfo.height() is negative ##
1393# rowBytes is positive and less than imageInfo.width() times imageInfo.bytesPerPixel ##
1394##
1395
1396#Param imageInfo  contains width, height, Alpha_Type, Color_Type, Color_Space ##
1397#Param rowBytes   imageInfo.minRowBytes or larger; or zero ##
1398
1399#Return  true if Image_Info set successfully ##
1400
1401#Example
1402#Height 96
1403###^
1404SkBitmap bitmap;
1405bitmap.setInfo(SkImageInfo::MakeN32(44, 16, kOpaque_SkAlphaType));
1406bitmap.allocPixels();
1407bitmap.eraseColor(SK_ColorGREEN);
1408SkCanvas offscreen(bitmap);
1409SkPaint paint;
1410offscreen.drawString("!@#$%", 0, 12, paint);
1411canvas->scale(6, 6);
1412canvas->drawBitmap(bitmap, 0, 0);
1413^^^#
1414##
1415
1416#SeeAlso Alpha_Type Color_Type Color_Space height rowBytes width
1417
1418##
1419
1420# ------------------------------------------------------------------------------
1421
1422#Enum AllocFlags
1423#Line # zero pixel memory ##
1424#Code
1425    enum AllocFlags {
1426        kZeroPixels_AllocFlag = 1 << 0,
1427    };
1428##
1429
1430AllocFlags provides the option to zero pixel memory when allocated.
1431
1432#Const kZeroPixels_AllocFlag 1
1433    Instructs tryAllocPixelsFlags and allocPixelsFlags to zero pixel memory.
1434##
1435
1436#NoExample
1437##
1438
1439#SeeAlso tryAllocPixelsFlags allocPixelsFlags erase() eraseColor
1440
1441##
1442
1443# ------------------------------------------------------------------------------
1444#Subtopic Allocate
1445#Populate
1446#Line # allocates storage for pixels ##
1447##
1448
1449#Method bool SK_WARN_UNUSED_RESULT tryAllocPixelsFlags(const SkImageInfo& info, uint32_t flags)
1450#In Allocate
1451#Line # allocates pixels from Image_Info with options if possible ##
1452Sets Image_Info to info following the rules in setInfo and allocates pixel
1453memory. If flags is kZeroPixels_AllocFlag, memory is zeroed.
1454
1455Returns false and calls reset() if Image_Info could not be set, or memory could
1456not be allocated, or memory could not optionally be zeroed.
1457
1458On most platforms, allocating pixel memory may succeed even though there is
1459not sufficient memory to hold pixels; allocation does not take place
1460until the pixels are written to. The actual behavior depends on the platform
1461implementation of malloc(), if flags is zero, and calloc(), if flags is
1462kZeroPixels_AllocFlag.
1463
1464Passing kZeroPixels_AllocFlag is usually faster than separately calling
1465eraseColor(SK_ColorTRANSPARENT).
1466
1467#Param info  contains width, height, Alpha_Type, Color_Type, Color_Space ##
1468#Param flags  kZeroPixels_AllocFlag, or zero ##
1469
1470#Return  true if pixels allocation is successful ##
1471
1472#Example
1473    SkBitmap bitmap;
1474    if (!bitmap.tryAllocPixelsFlags(SkImageInfo::MakeN32(10000, 10000, kOpaque_SkAlphaType),
1475                                    SkBitmap::kZeroPixels_AllocFlag)) {
1476        SkDebugf("bitmap allocation failed!\n");
1477    } else {
1478        SkDebugf("bitmap allocation succeeded!\n");
1479    }
1480#StdOut
1481bitmap allocation succeeded!
1482##
1483##
1484
1485#SeeAlso allocPixelsFlags tryAllocPixels SkMallocPixelRef::MakeZeroed
1486
1487##
1488
1489# ------------------------------------------------------------------------------
1490
1491#Method void allocPixelsFlags(const SkImageInfo& info, uint32_t flags)
1492#In Allocate
1493#Line # allocates pixels from Image_Info with options, or aborts ##
1494Sets Image_Info to info following the rules in setInfo and allocates pixel
1495memory. If flags is kZeroPixels_AllocFlag, memory is zeroed.
1496
1497Aborts execution if Image_Info could not be set, or memory could
1498not be allocated, or memory could not optionally
1499be zeroed. Abort steps may be provided by the user at compile time by defining
1500SK_ABORT.
1501
1502On most platforms, allocating pixel memory may succeed even though there is
1503not sufficient memory to hold pixels; allocation does not take place
1504until the pixels are written to. The actual behavior depends on the platform
1505implementation of malloc(), if flags is zero, and calloc(), if flags is
1506kZeroPixels_AllocFlag.
1507
1508Passing kZeroPixels_AllocFlag is usually faster than separately calling
1509eraseColor(SK_ColorTRANSPARENT).
1510
1511#Param info  contains width, height, Alpha_Type, Color_Type, Color_Space ##
1512#Param flags  kZeroPixels_AllocFlag, or zero ##
1513
1514#Example
1515#Height 128
1516#Description
1517Text is drawn on a transparent background; drawing the bitmap a second time
1518lets the first draw show through.
1519##
1520###^
1521SkBitmap bitmap;
1522bitmap.allocPixelsFlags(SkImageInfo::MakeN32(44, 16, kPremul_SkAlphaType),
1523                        SkBitmap::kZeroPixels_AllocFlag);
1524SkCanvas offscreen(bitmap);
1525SkPaint paint;
1526offscreen.drawString("!@#$%", 0, 12, paint);
1527canvas->scale(6, 6);
1528canvas->drawBitmap(bitmap, 0, 0);
1529canvas->drawBitmap(bitmap, 8, 8);
1530^^^#
1531##
1532
1533#SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeZeroed
1534
1535##
1536
1537# ------------------------------------------------------------------------------
1538
1539#Method bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info, size_t rowBytes)
1540#In Allocate
1541#Line # allocates pixels from Image_Info if possible ##
1542#ToDo  am I ever conflicted about setInfo rules. It needs to be able to be replicated
1543       if, for instance, I generate one-page-per-method HTML-style documentation
1544       I'm not so sure it makes sense to put the indirection in for .h either unless
1545       my mantra is that .h should abbreviate full documentation. And, what to do
1546       for generated markdown? At least there the rules are a click away, although
1547       a pop-down in place would be way better. Hmmm.
1548##
1549
1550Sets Image_Info to info following the rules in setInfo and allocates pixel
1551memory. rowBytes must equal or exceed info.width() times info.bytesPerPixel(),
1552or equal zero. Pass in zero for rowBytes to compute the minimum valid value.
1553
1554Returns false and calls reset() if Image_Info could not be set, or memory could
1555not be allocated.
1556
1557On most platforms, allocating pixel memory may succeed even though there is
1558not sufficient memory to hold pixels; allocation does not take place
1559until the pixels are written to. The actual behavior depends on the platform
1560implementation of malloc().
1561
1562#Param info  contains width, height, Alpha_Type, Color_Type, Color_Space ##
1563#Param rowBytes  size of pixel row or larger; may be zero  ##
1564
1565#Return  true if pixel storage is allocated ##
1566
1567#Example
1568#Image 3
1569SkBitmap bitmap;
1570SkImageInfo info = SkImageInfo::Make(64, 256, kGray_8_SkColorType, kOpaque_SkAlphaType);
1571if (bitmap.tryAllocPixels(info, 0)) {
1572    SkCanvas offscreen(bitmap);
1573    offscreen.scale(.5f, .5f);
1574    for (int x : { 0, 64, 128, 192 } ) {
1575        offscreen.drawBitmap(source, -x, 0);
1576        canvas->drawBitmap(bitmap, x, 0);
1577    }
1578}
1579##
1580
1581#SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeAllocate
1582
1583##
1584
1585# ------------------------------------------------------------------------------
1586
1587#Method void allocPixels(const SkImageInfo& info, size_t rowBytes)
1588#In Allocate
1589#Line # allocates pixels from Image_Info, or aborts ##
1590Sets Image_Info to info following the rules in setInfo and allocates pixel
1591memory. rowBytes must equal or exceed info.width() times info.bytesPerPixel(),
1592or equal zero. Pass in zero for rowBytes to compute the minimum valid value.
1593
1594Aborts execution if Image_Info could not be set, or memory could
1595not be allocated. Abort steps may be provided by
1596the user at compile time by defining SK_ABORT.
1597
1598On most platforms, allocating pixel memory may succeed even though there is
1599not sufficient memory to hold pixels; allocation does not take place
1600until the pixels are written to. The actual behavior depends on the platform
1601implementation of malloc().
1602
1603#Param info  contains width, height, Alpha_Type, Color_Type, Color_Space ##
1604#Param rowBytes  size of pixel row or larger; may be zero  ##
1605
1606#Example
1607#Image 3
1608SkBitmap bitmap;
1609SkImageInfo info = SkImageInfo::Make(256, 64, kGray_8_SkColorType, kOpaque_SkAlphaType);
1610bitmap.allocPixels(info, info.width() * info.bytesPerPixel() + 64);
1611SkCanvas offscreen(bitmap);
1612offscreen.scale(.5f, .5f);
1613for (int y : { 0, 64, 128, 192 } ) {
1614    offscreen.drawBitmap(source, 0, -y);
1615    canvas->drawBitmap(bitmap, 0, y);
1616}
1617##
1618
1619#SeeAlso tryAllocPixels allocPixelsFlags SkMallocPixelRef::MakeAllocate
1620
1621##
1622
1623# ------------------------------------------------------------------------------
1624
1625#Method bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info)
1626
1627Sets Image_Info to info following the rules in setInfo and allocates pixel
1628memory.
1629
1630Returns false and calls reset() if Image_Info could not be set, or memory could
1631not be allocated.
1632
1633On most platforms, allocating pixel memory may succeed even though there is
1634not sufficient memory to hold pixels; allocation does not take place
1635until the pixels are written to. The actual behavior depends on the platform
1636implementation of malloc().
1637
1638#Param info  contains width, height, Alpha_Type, Color_Type, Color_Space ##
1639
1640#Return  true if pixel storage is allocated ##
1641
1642#Example
1643#Image 3
1644SkBitmap bitmap;
1645if (bitmap.tryAllocPixels(SkImageInfo::Make(64, 64, kGray_8_SkColorType, kOpaque_SkAlphaType))) {
1646    SkCanvas offscreen(bitmap);
1647    offscreen.scale(.25f, .5f);
1648    for (int y : { 0, 64, 128, 192 } ) {
1649        offscreen.drawBitmap(source, -y, -y);
1650        canvas->drawBitmap(bitmap, y, y);
1651    }
1652}
1653##
1654
1655#SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeAllocate
1656
1657##
1658
1659# ------------------------------------------------------------------------------
1660
1661#Method void allocPixels(const SkImageInfo& info)
1662
1663Sets Image_Info to info following the rules in setInfo and allocates pixel
1664memory.
1665
1666Aborts execution if Image_Info could not be set, or memory could
1667not be allocated. Abort steps may be provided by
1668the user at compile time by defining SK_ABORT.
1669
1670On most platforms, allocating pixel memory may succeed even though there is
1671not sufficient memory to hold pixels; allocation does not take place
1672until the pixels are written to. The actual behavior depends on the platform
1673implementation of malloc().
1674
1675#Param info  contains width, height, Alpha_Type, Color_Type, Color_Space ##
1676
1677#Example
1678#Image 4
1679SkBitmap bitmap;
1680bitmap.allocPixels(SkImageInfo::Make(64, 64, kGray_8_SkColorType, kOpaque_SkAlphaType));
1681SkCanvas offscreen(bitmap);
1682offscreen.scale(.5f, .5f);
1683for (int y : { 0, 64, 128, 192 } ) {
1684    offscreen.drawBitmap(source, -y, -y);
1685    canvas->drawBitmap(bitmap, y, y);
1686}
1687##
1688
1689#SeeAlso tryAllocPixels allocPixelsFlags SkMallocPixelRef::MakeAllocate
1690
1691##
1692
1693# ------------------------------------------------------------------------------
1694
1695#Method bool SK_WARN_UNUSED_RESULT tryAllocN32Pixels(int width, int height, bool isOpaque = false)
1696#In Allocate
1697#Line # allocates compatible Color_ARGB pixels if possible ##
1698Sets Image_Info to width, height, and Native_Color_Type; and allocates
1699pixel memory. If isOpaque is true, sets Image_Info to kOpaque_SkAlphaType;
1700otherwise, sets to kPremul_SkAlphaType.
1701
1702Calls reset() and returns false if width exceeds 29 bits or is negative,
1703or height is negative.
1704
1705Returns false if allocation fails.
1706
1707Use to create Bitmap that matches SkPMColor, the native pixel arrangement on
1708the platform. Bitmap drawn to output device skips converting its pixel format.
1709
1710#Param width  pixel column count; must be zero or greater ##
1711#Param height  pixel row count; must be zero or greater ##
1712#Param isOpaque  true if pixels do not have transparency ##
1713
1714#Return  true if pixel storage is allocated ##
1715
1716#Example
1717#Height 160
1718    SkBitmap bitmap;
1719    if (bitmap.tryAllocN32Pixels(80, 80)) {
1720        bitmap.eraseColor(SK_ColorTRANSPARENT);
1721        bitmap.erase(0x7f3f7fff, SkIRect::MakeWH(50, 30));
1722        bitmap.erase(0x3f7fff3f, SkIRect::MakeXYWH(20, 10, 50, 30));
1723        bitmap.erase(0x5fff3f7f, SkIRect::MakeXYWH(40, 20, 50, 30));
1724        canvas->drawBitmap(bitmap, 0, 0);
1725        for (int x : { 0, 30, 60, 90 } ) {
1726            canvas->drawBitmap(bitmap, x, 70);
1727        }
1728    }
1729##
1730
1731#SeeAlso tryAllocPixels allocN32Pixels SkMallocPixelRef::MakeAllocate
1732
1733##
1734
1735# ------------------------------------------------------------------------------
1736
1737#Method void allocN32Pixels(int width, int height, bool isOpaque = false)
1738#In Allocate
1739#Line # allocates compatible Color_ARGB pixels, or aborts ##
1740Sets Image_Info to width, height, and the Native_Color_Type; and allocates
1741pixel memory. If isOpaque is true, sets Image_Info to kPremul_SkAlphaType;
1742otherwise, sets to kOpaque_SkAlphaType.
1743
1744Aborts if width exceeds 29 bits or is negative, or height is negative, or
1745allocation fails. Abort steps may be provided by the user at compile time by
1746defining SK_ABORT.
1747
1748Use to create Bitmap that matches SkPMColor, the native pixel arrangement on
1749the platform. Bitmap drawn to output device skips converting its pixel format.
1750
1751#Param width  pixel column count; must be zero or greater ##
1752#Param height  pixel row count; must be zero or greater ##
1753#Param isOpaque  true if pixels do not have transparency ##
1754
1755#Example
1756    SkRandom random;
1757    SkBitmap bitmap;
1758    bitmap.allocN32Pixels(64, 64);
1759    bitmap.eraseColor(SK_ColorTRANSPARENT);
1760    for (int y = 0; y < 256; y += 64) {
1761        for (int x = 0; x < 256; x += 64) {
1762            SkColor color = random.nextU();
1763            uint32_t w = random.nextRangeU(4, 32);
1764            uint32_t cx = random.nextRangeU(0, 64 - w);
1765            uint32_t h = random.nextRangeU(4, 32);
1766            uint32_t cy = random.nextRangeU(0, 64 - h);
1767            bitmap.erase(color, SkIRect::MakeXYWH(cx, cy, w, h));
1768            canvas->drawBitmap(bitmap, x, y);
1769        }
1770    }
1771##
1772
1773#SeeAlso allocPixels tryAllocN32Pixels SkMallocPixelRef::MakeAllocate
1774
1775##
1776
1777# ------------------------------------------------------------------------------
1778
1779#Method bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
1780                       void (*releaseProc)(void* addr, void* context), void* context)
1781#In Allocate
1782#Line # creates Pixel_Ref, with optional release function ##
1783
1784Sets Image_Info to info following the rules in setInfo, and creates Pixel_Ref
1785containing pixels and rowBytes. releaseProc, if not nullptr, is called
1786immediately on failure or when pixels are no longer referenced. context may be
1787nullptr.
1788
1789If Image_Info could not be set, or rowBytes is less than info.minRowBytes:
1790calls releaseProc if present, calls reset(), and returns false.
1791
1792Otherwise, if pixels equals nullptr: sets Image_Info, calls releaseProc if
1793present, returns true.
1794
1795If Image_Info is set, pixels is not nullptr, and releaseProc is not nullptr:
1796when pixels are no longer referenced, calls releaseProc with pixels and context
1797as parameters.
1798
1799#Param info  contains width, height, Alpha_Type, Color_Type, Color_Space ##
1800#Param pixels   address or pixel storage; may be nullptr ##
1801#Param rowBytes  size of pixel row or larger ##
1802#Param releaseProc  function called when pixels can be deleted; may be nullptr ##
1803#Param context   caller state passed to releaseProc; may be nullptr ##
1804
1805#Return  true if Image_Info is set to info ##
1806
1807#Example
1808#Description
1809releaseProc is called immediately because rowBytes is too small for Pixel_Ref.
1810##
1811#Function
1812static void releaseProc(void* addr, void* ) {
1813    SkDebugf("releaseProc called\n");
1814    delete[] (uint32_t*) addr;
1815}
1816
1817##
1818
1819void draw(SkCanvas* canvas) {
1820   SkBitmap bitmap;
1821   void* pixels = new uint32_t[8 * 8];
1822   SkImageInfo info = SkImageInfo::MakeN32(8, 8, kOpaque_SkAlphaType);
1823   SkDebugf("before installPixels\n");
1824   bool installed = bitmap.installPixels(info, pixels, 16, releaseProc, nullptr);
1825   SkDebugf("install " "%s" "successful\n", installed ? "" : "not ");
1826}
1827#StdOut
1828before installPixels
1829releaseProc called
1830install not successful
1831##
1832##
1833
1834#SeeAlso allocPixels
1835
1836##
1837
1838# ------------------------------------------------------------------------------
1839
1840#Method bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes)
1841
1842Sets Image_Info to info following the rules in setInfo, and creates Pixel_Ref
1843containing pixels and rowBytes.
1844
1845If Image_Info could not be set, or rowBytes is less than info.minRowBytes:
1846calls reset(), and returns false.
1847
1848Otherwise, if pixels equals nullptr: sets Image_Info, returns true.
1849
1850Caller must ensure that pixels are valid for the lifetime of Bitmap and Pixel_Ref.
1851
1852#Param info  contains width, height, Alpha_Type, Color_Type, Color_Space ##
1853#Param pixels  address or pixel storage; may be nullptr ##
1854#Param rowBytes  size of pixel row or larger ##
1855
1856#Return  true if Image_Info is set to info ##
1857
1858#Example
1859#Bug 7079
1860#Description
1861GPU does not support kUnpremul_SkAlphaType, does not assert that it does not.
1862##
1863void draw(SkCanvas* canvas) {
1864   SkRandom random;
1865   SkBitmap bitmap;
1866   const int width = 8;
1867   const int height = 8;
1868   uint32_t pixels[width * height];
1869   for (unsigned x = 0; x < width * height; ++x) {
1870       pixels[x] = random.nextU();
1871   }
1872   SkImageInfo info = SkImageInfo::MakeN32(width, height, kUnpremul_SkAlphaType);
1873   if (bitmap.installPixels(info, pixels, info.minRowBytes())) {
1874       canvas->scale(32, 32);
1875       canvas->drawBitmap(bitmap, 0, 0);
1876   }
1877}
1878##
1879
1880#SeeAlso allocPixels
1881
1882##
1883
1884# ------------------------------------------------------------------------------
1885
1886#Method bool installPixels(const SkPixmap& pixmap)
1887
1888Sets Image_Info to pixmap.info() following the rules in setInfo, and creates
1889Pixel_Ref containing pixmap.addr() and pixmap.rowBytes.
1890
1891If Image_Info could not be set, or pixmap.rowBytes is less than
1892SkImageInfo::minRowBytes: calls reset(), and returns false.
1893
1894Otherwise, if pixmap.addr() equals nullptr: sets Image_Info, returns true.
1895
1896Caller must ensure that pixmap is valid for the lifetime of Bitmap and Pixel_Ref.
1897
1898#Param pixmap  Image_Info, pixel address, and rowBytes ##
1899
1900#Return  true if Image_Info was set to pixmap.info() ##
1901
1902#Example
1903#Description
1904Draw a five by five bitmap, and draw it again with a center white pixel.
1905##
1906#Height 64
1907    uint8_t storage[][5] = {{ 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 },
1908                            { 0xAC, 0xA8, 0x89, 0x47, 0x87 },
1909                            { 0x4B, 0x25, 0x25, 0x25, 0x46 },
1910                            { 0x90, 0x81, 0x25, 0x41, 0x33 },
1911                            { 0x75, 0x55, 0x44, 0x20, 0x00 }};
1912    SkImageInfo imageInfo = SkImageInfo::Make(5, 5, kGray_8_SkColorType, kOpaque_SkAlphaType);
1913    SkPixmap pixmap(imageInfo, storage[0], sizeof(storage) / 5);
1914    SkBitmap bitmap;
1915    bitmap.installPixels(pixmap);
1916    canvas->scale(10, 10);
1917    canvas->drawBitmap(bitmap, 0, 0);
1918    *pixmap.writable_addr8(2, 2) = 0xFF;
1919    bitmap.installPixels(pixmap);
1920    canvas->drawBitmap(bitmap, 10, 0);
1921##
1922
1923#SeeAlso allocPixels
1924
1925##
1926
1927# ------------------------------------------------------------------------------
1928
1929#Method bool installMaskPixels(const SkMask& mask)
1930#Deprecated soon
1931##
1932
1933# ------------------------------------------------------------------------------
1934#Subtopic Pixels
1935#Populate
1936#Line # read and write pixel values ##
1937##
1938
1939#Method void setPixels(void* pixels)
1940#In Pixels
1941#Line # sets Pixel_Ref without an offset ##
1942Replaces Pixel_Ref with pixels, preserving Image_Info and rowBytes.
1943Sets Pixel_Ref origin to (0, 0).
1944
1945If pixels is nullptr, or if info().colorType equals kUnknown_SkColorType;
1946release reference to Pixel_Ref, and set Pixel_Ref to nullptr.
1947
1948Caller is responsible for handling ownership pixel memory for the lifetime
1949of Bitmap and Pixel_Ref.
1950
1951#Param pixels  address of pixel storage, managed by caller ##
1952
1953#Example
1954#Height 50
1955    uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 };
1956    uint8_t set2[5] = { 0xAC, 0xA8, 0x89, 0x47, 0x87 };
1957    SkBitmap bitmap;
1958    bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5);
1959    canvas->scale(10, 50);
1960    canvas->drawBitmap(bitmap, 0, 0);
1961    bitmap.setPixels(set2);
1962    canvas->drawBitmap(bitmap, 10, 0);
1963##
1964
1965#SeeAlso installPixels allocPixels
1966
1967##
1968
1969# ------------------------------------------------------------------------------
1970
1971#Method bool SK_WARN_UNUSED_RESULT tryAllocPixels()
1972#In Allocate
1973Allocates pixel memory with HeapAllocator, and replaces existing Pixel_Ref.
1974The allocation size is determined by Image_Info width, height, and Color_Type.
1975
1976Returns false if info().colorType is kUnknown_SkColorType, or allocation fails.
1977
1978#Return  true if the allocation succeeds
1979##
1980
1981#Example
1982#Height 50
1983#Description
1984Bitmap hosts and draws gray values in set1. tryAllocPixels replaces Pixel_Ref
1985and erases it to black, but does not alter set1. setPixels replaces black
1986Pixel_Ref with set1.
1987##
1988    uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 };
1989    SkBitmap bitmap;
1990    bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5);
1991    canvas->scale(10, 50);
1992    canvas->drawBitmap(bitmap, 0, 0);
1993    if (bitmap.tryAllocPixels()) {
1994        bitmap.eraseColor(SK_ColorBLACK);
1995        canvas->drawBitmap(bitmap, 8, 0);
1996        bitmap.setPixels(set1);
1997        canvas->drawBitmap(bitmap, 16, 0);
1998    }
1999##
2000
2001#SeeAlso allocPixels installPixels setPixels
2002
2003##
2004
2005# ------------------------------------------------------------------------------
2006
2007#Method void allocPixels()
2008#In Allocate
2009Allocates pixel memory with HeapAllocator, and replaces existing Pixel_Ref.
2010The allocation size is determined by Image_Info width, height, and Color_Type.
2011
2012Aborts if info().colorType is kUnknown_SkColorType, or allocation fails.
2013Abort steps may be provided by the user at compile
2014time by defining SK_ABORT.
2015
2016#Example
2017#Height 50
2018#Description
2019Bitmap hosts and draws gray values in set1. allocPixels replaces Pixel_Ref
2020and erases it to black, but does not alter set1. setPixels replaces black
2021Pixel_Ref with set2.
2022##
2023    uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 };
2024    uint8_t set2[5] = { 0xAC, 0xA8, 0x89, 0x47, 0x87 };
2025    SkBitmap bitmap;
2026    bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5);
2027    canvas->scale(10, 50);
2028    canvas->drawBitmap(bitmap, 0, 0);
2029    bitmap.allocPixels();
2030    bitmap.eraseColor(SK_ColorBLACK);
2031    canvas->drawBitmap(bitmap, 8, 0);
2032    bitmap.setPixels(set2);
2033    canvas->drawBitmap(bitmap, 16, 0);
2034##
2035
2036#SeeAlso tryAllocPixels installPixels setPixels
2037
2038##
2039
2040# ------------------------------------------------------------------------------
2041
2042#Method bool SK_WARN_UNUSED_RESULT tryAllocPixels(Allocator* allocator)
2043
2044Allocates pixel memory with allocator, and replaces existing Pixel_Ref.
2045The allocation size is determined by Image_Info width, height, and Color_Type.
2046If allocator is nullptr, use HeapAllocator instead.
2047
2048Returns false if Allocator::allocPixelRef return false.
2049
2050#Param allocator  instance of SkBitmap::Allocator instantiation ##
2051
2052#Return  true if custom allocator reports success
2053##
2054
2055#Example
2056#Height 100
2057#Description
2058HeapAllocator limits the maximum size of Bitmap to two gigabytes. Using
2059a custom allocator, this limitation may be relaxed. This example can be
2060modified to allocate an eight gigabyte Bitmap on a 64 bit platform with
2061sufficient memory.
2062##
2063#Function
2064class LargePixelRef : public SkPixelRef {
2065public:
2066    LargePixelRef(const SkImageInfo& info, char* storage, size_t rowBytes)
2067        : SkPixelRef(info.width(), info.height(), storage, rowBytes) {
2068    }
2069
2070    ~LargePixelRef() override {
2071        delete[] (char* ) this->pixels();
2072    }
2073};
2074
2075class LargeAllocator : public SkBitmap::Allocator {
2076public:
2077    bool allocPixelRef(SkBitmap* bitmap) override {
2078        const SkImageInfo& info = bitmap->info();
2079        uint64_t rowBytes = info.minRowBytes64();
2080        uint64_t size = info.height() * rowBytes;
2081        char* addr = new char[size];
2082        if (nullptr == addr) {
2083            return false;
2084        }
2085        sk_sp<SkPixelRef> pr = sk_sp<SkPixelRef>(new LargePixelRef(info, addr, rowBytes));
2086        if (!pr) {
2087            return false;
2088        }
2089        bitmap->setPixelRef(std::move(pr), 0, 0);
2090        return true;
2091    }
2092};
2093
2094##
2095
2096void draw(SkCanvas* canvas) {
2097   LargeAllocator largeAllocator;
2098   SkBitmap bitmap;
2099   int width = 100; // make this 20000
2100   int height = 100; // and this 100000 to allocate 8 gigs on a 64-bit platform
2101   bitmap.setInfo(SkImageInfo::MakeN32(width, height, kOpaque_SkAlphaType));
2102   if (bitmap.tryAllocPixels(&largeAllocator)) {
2103       bitmap.eraseColor(0xff55aa33);
2104       canvas->drawBitmap(bitmap, 0, 0);
2105   }
2106}
2107
2108##
2109
2110#SeeAlso allocPixels Allocator Pixel_Ref
2111
2112##
2113
2114# ------------------------------------------------------------------------------
2115
2116#Method void allocPixels(Allocator* allocator)
2117
2118Allocates pixel memory with allocator, and replaces existing Pixel_Ref.
2119The allocation size is determined by Image_Info width, height, and Color_Type.
2120If allocator is nullptr, use HeapAllocator instead.
2121
2122Aborts if Allocator::allocPixelRef return false. Abort steps may be provided by
2123the user at compile time by defining SK_ABORT.
2124
2125#Param allocator  instance of SkBitmap::Allocator instantiation ##
2126
2127#Example
2128#Height 32
2129#Function
2130class TinyAllocator : public SkBitmap::Allocator {
2131public:
2132    bool allocPixelRef(SkBitmap* bitmap) override {
2133        const SkImageInfo& info = bitmap->info();
2134        if (info.height() * info.minRowBytes() > sizeof(storage)) {
2135            return false;
2136        }
2137        sk_sp<SkPixelRef> pr = sk_sp<SkPixelRef>(
2138                new SkPixelRef(info.width(), info.height(), storage, info.minRowBytes()));
2139        bitmap->setPixelRef(std::move(pr), 0, 0);
2140        return true;
2141    }
2142
2143    char storage[16];
2144};
2145
2146##
2147
2148void draw(SkCanvas* canvas) {
2149   TinyAllocator tinyAllocator;
2150   SkBitmap bitmap;
2151   bitmap.setInfo(SkImageInfo::MakeN32(2, 2, kOpaque_SkAlphaType));
2152   if (bitmap.tryAllocPixels(&tinyAllocator)) {
2153       bitmap.eraseColor(0xff55aa33);
2154       bitmap.erase(0xffaa3355, SkIRect::MakeXYWH(1, 1, 1, 1));
2155       canvas->scale(16, 16);
2156       canvas->drawBitmap(bitmap, 0, 0);
2157   }
2158}
2159##
2160
2161#SeeAlso allocPixels Allocator Pixel_Ref
2162
2163##
2164
2165# ------------------------------------------------------------------------------
2166
2167#Method SkPixelRef* pixelRef() const
2168#In Property
2169#Line # returns Pixel_Ref, or nullptr ##
2170Returns Pixel_Ref, which contains: pixel base address; its dimensions; and
2171rowBytes, the interval from one row to the next. Does not change Pixel_Ref
2172reference count. Pixel_Ref may be shared by multiple bitmaps.
2173If Pixel_Ref has not been set, returns nullptr.
2174
2175#Return  Pixel_Ref, or nullptr ##
2176
2177#Example
2178#Image 3
2179   SkBitmap subset;
2180   source.extractSubset(&subset, SkIRect::MakeXYWH(32, 64, 128, 256));
2181   SkDebugf("src ref %c= sub ref\n", source.pixelRef() == subset.pixelRef() ? '=' : '!');
2182   SkDebugf("src pixels %c= sub pixels\n", source.getPixels() == subset.getPixels() ? '=' : '!');
2183   SkDebugf("src addr %c= sub addr\n", source.getAddr(32, 64) == subset.getAddr(0, 0) ? '=' : '!');
2184##
2185
2186#SeeAlso getPixels getAddr
2187
2188##
2189
2190# ------------------------------------------------------------------------------
2191
2192#Method SkIPoint pixelRefOrigin() const
2193#In Property
2194#Line # returns offset within Pixel_Ref ##
2195Returns origin of pixels within Pixel_Ref. Bitmap bounds is always contained
2196by Pixel_Ref bounds, which may be the same size or larger. Multiple Bitmaps
2197can share the same Pixel_Ref, where each Bitmap has different bounds.
2198
2199The returned origin added to Bitmap dimensions equals or is smaller than the
2200Pixel_Ref dimensions.
2201
2202Returns (0, 0) if Pixel_Ref is nullptr.
2203
2204#Return  pixel origin within Pixel_Ref ##
2205
2206#Example
2207#Image 3
2208   SkBitmap subset;
2209   source.extractSubset(&subset, SkIRect::MakeXYWH(32, 64, 128, 256));
2210   SkIPoint sourceOrigin = source.pixelRefOrigin();
2211   SkIPoint subsetOrigin = subset.pixelRefOrigin();
2212   SkDebugf("source origin: %d, %d\n", sourceOrigin.fX, sourceOrigin.fY);
2213   SkDebugf("subset origin: %d, %d\n", subsetOrigin.fX, subsetOrigin.fY);
2214#StdOut
2215source origin: 0, 0
2216subset origin: 32, 64
2217##
2218##
2219
2220#SeeAlso SkPixelRef getSubset setPixelRef
2221
2222##
2223
2224# ------------------------------------------------------------------------------
2225#Subtopic Set
2226#Line # updates values and attributes ##
2227#Populate
2228##
2229
2230#Method void setPixelRef(sk_sp<SkPixelRef> pixelRef, int dx, int dy)
2231#In Set
2232#Line # sets Pixel_Ref and offset ##
2233Replaces pixelRef and origin in Bitmap.  dx and dy specify the offset
2234within the Pixel_Ref pixels for the top-left corner of the bitmap.
2235
2236Asserts in debug builds if dx or dy are out of range. Pins dx and dy
2237to legal range in release builds.
2238
2239The caller is responsible for ensuring that the pixels match the
2240Color_Type and Alpha_Type in Image_Info.
2241
2242#Param pixelRef  Pixel_Ref describing pixel address and rowBytes ##
2243#Param dx   column offset in Pixel_Ref for bitmap origin ##
2244#Param dy   row offset in Pixel_Ref for bitmap origin ##
2245
2246#Example
2247#Height 140
2248#Image 5
2249#Description
2250Treating 32 bit data as 8 bit data is unlikely to produce useful results.
2251##
2252    SkBitmap bitmap;
2253    bitmap.setInfo(SkImageInfo::Make(source.width() - 5, source.height() - 5,
2254                   kGray_8_SkColorType, kOpaque_SkAlphaType), source.rowBytes());
2255    bitmap.setPixelRef(sk_ref_sp(source.pixelRef()), 5, 5);
2256    canvas->drawBitmap(bitmap, 10, 10);
2257##
2258
2259#SeeAlso setInfo
2260
2261##
2262
2263# ------------------------------------------------------------------------------
2264
2265#Method bool readyToDraw() const
2266#In Utility
2267#Line # returns true if address of pixels is not nullptr ##
2268Returns true if Bitmap is can be drawn.
2269
2270#Return  true if getPixels() is not nullptr ##
2271
2272#Example
2273#Image 5
2274#Height 160
2275    if (source.readyToDraw()) {
2276        canvas->drawBitmap(source, 10, 10);
2277    }
2278##
2279
2280#SeeAlso getPixels drawsNothing
2281
2282##
2283
2284# ------------------------------------------------------------------------------
2285
2286#Method uint32_t getGenerationID() const
2287#In Utility
2288#Line # returns unique ID ##
2289Returns a unique value corresponding to the pixels in Pixel_Ref.
2290Returns a different value after notifyPixelsChanged has been called.
2291Returns zero if Pixel_Ref is nullptr.
2292
2293Determines if pixels have changed since last examined.
2294
2295#Return unique value for pixels in Pixel_Ref ##
2296
2297#Example
2298    SkBitmap bitmap;
2299    SkDebugf("empty id %u\n", bitmap.getGenerationID());
2300    bitmap.allocPixels(SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType));
2301    SkDebugf("alloc id %u\n", bitmap.getGenerationID());
2302    bitmap.eraseColor(SK_ColorRED);
2303    SkDebugf("erase id %u\n", bitmap.getGenerationID());
2304#StdOut
2305#Volatile
2306empty id 0
2307alloc id 4
2308erase id 6
2309##
2310##
2311
2312#SeeAlso notifyPixelsChanged Pixel_Ref
2313
2314##
2315
2316# ------------------------------------------------------------------------------
2317
2318#Method void notifyPixelsChanged() const
2319#In Pixels
2320#Line # marks pixels as changed, altering the unique ID ##
2321Marks that pixels in Pixel_Ref have changed. Subsequent calls to
2322getGenerationID() return a different value.
2323
2324#Example
2325#Height 20
2326    SkBitmap bitmap;
2327    bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
2328    bitmap.allocPixels();
2329    bitmap.eraseColor(SK_ColorRED);
2330    canvas->scale(16, 16);
2331    canvas->drawBitmap(bitmap, 0, 0);
2332    *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorBLUE);
2333    canvas->drawBitmap(bitmap, 2, 0);
2334    bitmap.notifyPixelsChanged();
2335    *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorGREEN);
2336    canvas->drawBitmap(bitmap, 4, 0);
2337##
2338
2339#SeeAlso getGenerationID isVolatile Pixel_Ref
2340
2341##
2342
2343# ------------------------------------------------------------------------------
2344#Subtopic Draw
2345#Populate
2346#Line # set pixels to Color ##
2347##
2348
2349#Method void eraseColor(SkColor c) const
2350#In Draw
2351#Line # writes Color to pixels ##
2352Replaces pixel values with c. All pixels contained by bounds() are affected.
2353If the colorType is kGray_8_SkColorType or k565_SkColorType, then Color_Alpha
2354is ignored; Color_RGB is treated as opaque. If colorType is kAlpha_8_SkColorType,
2355then Color_RGB is ignored.
2356
2357#Param c  Unpremultiplied Color ##
2358
2359#Example
2360#Height 20
2361    SkBitmap bitmap;
2362    bitmap.allocPixels(SkImageInfo::MakeN32(1, 1, kOpaque_SkAlphaType));
2363    bitmap.eraseColor(SK_ColorRED);
2364    canvas->scale(16, 16);
2365    canvas->drawBitmap(bitmap, 0, 0);
2366##
2367
2368#SeeAlso eraseARGB erase
2369
2370##
2371
2372# ------------------------------------------------------------------------------
2373
2374#Method void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const
2375#In Draw
2376#Line # writes Color to pixels ##
2377Replaces pixel values with Unpremultiplied Color built from a, r, g, and b.
2378All pixels contained by bounds() are affected.
2379If the colorType is kGray_8_SkColorType or k565_SkColorType, then a
2380is ignored; r, g, and b are treated as opaque. If colorType is kAlpha_8_SkColorType,
2381then r, g, and b are ignored.
2382
2383#Param a    amount of Color_Alpha, from fully transparent (0) to fully opaque (255) ##
2384#Param r    amount of Color_RGB_Red, from no red (0) to full red (255) ##
2385#Param g    amount of Color_RGB_Green, from no green (0) to full green (255) ##
2386#Param b    amount of Color_RGB_Blue, from no blue (0) to full blue (255) ##
2387
2388#Example
2389#Height 80
2390    SkBitmap bitmap;
2391    bitmap.allocPixels(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType));
2392    bitmap.eraseARGB(0x7f, 0xff, 0x7f, 0x3f);
2393    canvas->scale(50, 50);
2394    canvas->drawBitmap(bitmap, 0, 0);
2395    canvas->drawBitmap(bitmap, .5f, .5f);
2396##
2397
2398#SeeAlso eraseColor erase
2399
2400##
2401
2402# ------------------------------------------------------------------------------
2403
2404#Method void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const
2405#In Draw
2406#Line # deprecated ##
2407Deprecated. Use eraseARGB or eraseColor.
2408
2409#Param r    amount of red ##
2410#Param g    amount of green ##
2411#Param b    amount of blue ##
2412
2413#NoExample
2414##
2415
2416#SeeAlso eraseColor eraseARGB erase
2417
2418##
2419
2420# ------------------------------------------------------------------------------
2421
2422#Method void erase(SkColor c, const SkIRect& area) const
2423#In Draw
2424#Line # writes Color to rectangle of pixels ##
2425Replaces pixel values inside area with c. If area does not intersect bounds(),
2426call has no effect.
2427
2428If the colorType is kGray_8_SkColorType or k565_SkColorType, then Color_Alpha
2429is ignored; Color_RGB is treated as opaque. If colorType is kAlpha_8_SkColorType,
2430then Color_RGB is ignored.
2431
2432#Param c  Unpremultiplied Color ##
2433#Param area  rectangle to fill ##
2434
2435#Example
2436#Height 70
2437    SkBitmap bitmap;
2438    bitmap.allocPixels(SkImageInfo::MakeN32(2, 2, kPremul_SkAlphaType));
2439    bitmap.erase(0x7fff7f3f, SkIRect::MakeWH(1, 1));
2440    bitmap.erase(0x7f7f3fff, SkIRect::MakeXYWH(0, 1, 1, 1));
2441    bitmap.erase(0x7f3fff7f, SkIRect::MakeXYWH(1, 0, 1, 1));
2442    bitmap.erase(0x7f1fbf5f, SkIRect::MakeXYWH(1, 1, 1, 1));
2443    canvas->scale(25, 25);
2444    canvas->drawBitmap(bitmap, 0, 0);
2445    canvas->drawBitmap(bitmap, .5f, .5f);
2446
2447##
2448
2449#SeeAlso eraseColor eraseARGB eraseRGB SkCanvas::drawRect
2450
2451##
2452
2453# ------------------------------------------------------------------------------
2454
2455#Method void eraseArea(const SkIRect& area, SkColor c) const
2456#Deprecated
2457##
2458
2459# ------------------------------------------------------------------------------
2460
2461#Method SkColor getColor(int x, int y) const
2462#In Property
2463#In Pixels
2464#Line # returns one pixel as Unpremultiplied Color ##
2465Returns pixel at (x, y) as Unpremultiplied Color.
2466Returns black with Alpha if Color_Type is kAlpha_8_SkColorType.
2467
2468Input is not validated: out of bounds values of x or y trigger an assert() if
2469built with SK_DEBUG defined; and returns undefined values or may crash if
2470SK_RELEASE is defined. Fails if Color_Type is kUnknown_SkColorType or
2471pixel address is nullptr.
2472
2473Color_Space in Image_Info is ignored. Some Color precision may be lost in the
2474conversion to Unpremultiplied Color; original pixel data may have additional
2475precision.
2476
2477#Param x  column index, zero or greater, and less than width() ##
2478#Param y  row index, zero or greater, and less than height() ##
2479
2480#Return  pixel converted to Unpremultiplied Color ##
2481
2482#Example
2483    const int w = 4;
2484    const int h = 4;
2485    SkColor colors[][w] = {
2486        0x00000000, 0x2a0e002a, 0x55380055, 0x7f7f007f,
2487        0x2a000e2a, 0x551c1c55, 0x7f542a7f, 0xaaaa38aa,
2488        0x55003855, 0x7f2a547f, 0xaa7171aa, 0xd4d48dd4,
2489        0x7f007f7f, 0xaa38aaaa, 0xd48dd4d4, 0xffffffff,
2490    };
2491    SkDebugf("Premultiplied:\n");
2492    for (int y = 0; y < h; ++y) {
2493        SkDebugf("(0, %d) ", y);
2494        for (int x = 0; x < w; ++x) {
2495            SkDebugf("0x%08x%c", colors[y][x], x == w - 1 ? '\n' : ' ');
2496        }
2497    }
2498    SkPixmap pixmap(SkImageInfo::MakeN32(w, h, kPremul_SkAlphaType), colors, w * 4);
2499    SkBitmap bitmap;
2500    bitmap.installPixels(pixmap);
2501    SkDebugf("Unpremultiplied:\n");
2502    for (int y = 0; y < h; ++y) {
2503        SkDebugf("(0, %d) ", y);
2504        for (int x = 0; x < w; ++x) {
2505            SkDebugf("0x%08x%c", bitmap.getColor(x, y), x == w - 1 ? '\n' : ' ');
2506        }
2507    }
2508#StdOut
2509Premultiplied:
2510(0, 0) 0x00000000 0x2a0e002a 0x55380055 0x7f7f007f
2511(0, 1) 0x2a000e2a 0x551c1c55 0x7f542a7f 0xaaaa38aa
2512(0, 2) 0x55003855 0x7f2a547f 0xaa7171aa 0xd4d48dd4
2513(0, 3) 0x7f007f7f 0xaa38aaaa 0xd48dd4d4 0xffffffff
2514Unpremultiplied:
2515(0, 0) 0x00000000 0x2a5500ff 0x55a800ff 0x7fff00ff
2516(0, 1) 0x2a0055ff 0x555454ff 0x7fa954ff 0xaaff54ff
2517(0, 2) 0x5500a8ff 0x7f54a9ff 0xaaaaaaff 0xd4ffaaff
2518(0, 3) 0x7f00ffff 0xaa54ffff 0xd4aaffff 0xffffffff
2519##
2520##
2521
2522#SeeAlso getAddr readPixels
2523
2524##
2525
2526# ------------------------------------------------------------------------------
2527
2528#Method void* getAddr(int x, int y) const
2529#In Property
2530#Line # returns readable pixel address as void pointer ##
2531Returns pixel address at (x, y).
2532
2533Input is not validated: out of bounds values of x or y, or kUnknown_SkColorType,
2534trigger an assert() if built with SK_DEBUG defined. Returns nullptr if
2535Color_Type is kUnknown_SkColorType, or Pixel_Ref is nullptr.
2536
2537Performs a lookup of pixel size; for better performance, call
2538one of: getAddr8, getAddr16, or getAddr32.
2539
2540#Param x  column index, zero or greater, and less than width() ##
2541#Param y  row index, zero or greater, and less than height() ##
2542
2543#Return  generic pointer to pixel ##
2544
2545#Example
2546#Image 3
2547    char* row0 = (char* ) source.getAddr(0, 0);
2548    char* row1 = (char* ) source.getAddr(0, 1);
2549    SkDebugf("addr interval %c= rowBytes\n", row1 - row0 == source.rowBytes() ? '=' : '!');
2550#StdOut
2551addr interval == rowBytes
2552##
2553##
2554
2555#SeeAlso getAddr8 getAddr16 getAddr32 readPixels SkPixmap::addr
2556
2557##
2558
2559# ------------------------------------------------------------------------------
2560
2561#Method inline uint32_t* getAddr32(int x, int y) const
2562#In Property
2563#Line # returns readable pixel address as 32-bit pointer ##
2564Returns address at (x, y).
2565
2566Input is not validated. Triggers an assert() if built with SK_DEBUG defined and:
2567#List
2568# Pixel_Ref is nullptr ##
2569# bytesPerPixel() is not four ##
2570# x is negative, or not less than width() ##
2571# y is negative, or not less than height() ##
2572##
2573
2574#Param x  column index, zero or greater, and less than width() ##
2575#Param y  row index, zero or greater, and less than height() ##
2576
2577#Return  unsigned 32-bit pointer to pixel at (x, y) ##
2578
2579#Example
2580#Image 3
2581    uint32_t* row0 = source.getAddr32(0, 0);
2582    uint32_t* row1 = source.getAddr32(0, 1);
2583    size_t interval = (row1 - row0) * source.bytesPerPixel();
2584    SkDebugf("addr interval %c= rowBytes\n", interval == source.rowBytes() ? '=' : '!');
2585#StdOut
2586addr interval == rowBytes
2587##
2588##
2589
2590#SeeAlso getAddr8 getAddr16 getAddr readPixels SkPixmap::addr32
2591
2592##
2593
2594# ------------------------------------------------------------------------------
2595
2596#Method inline uint16_t* getAddr16(int x, int y) const
2597#In Property
2598#Line # returns readable pixel address as 16-bit pointer ##
2599Returns address at (x, y).
2600
2601Input is not validated. Triggers an assert() if built with SK_DEBUG defined and:
2602#List
2603# Pixel_Ref is nullptr ##
2604# bytesPerPixel() is not two ##
2605# x is negative, or not less than width() ##
2606# y is negative, or not less than height() ##
2607##
2608
2609#Param x  column index, zero or greater, and less than width() ##
2610#Param y  row index, zero or greater, and less than height() ##
2611
2612#Return  unsigned 16-bit pointer to pixel at (x, y)##
2613
2614#Example
2615#Image 3
2616    SkBitmap bitmap16;
2617    SkImageInfo dstInfo = SkImageInfo::Make(source.width(), source.height(), kARGB_4444_SkColorType,
2618                     kPremul_SkAlphaType);
2619    bitmap16.allocPixels(dstInfo);
2620    if (source.readPixels(dstInfo, bitmap16.getPixels(), bitmap16.rowBytes(), 0, 0)) {
2621        uint16_t* row0 = bitmap16.getAddr16(0, 0);
2622        uint16_t* row1 = bitmap16.getAddr16(0, 1);
2623        size_t interval = (row1 - row0) * bitmap16.bytesPerPixel();
2624        SkDebugf("addr interval %c= rowBytes\n", interval == bitmap16.rowBytes() ? '=' : '!');
2625    }
2626#StdOut
2627addr interval == rowBytes
2628##
2629##
2630
2631#SeeAlso getAddr8 getAddr getAddr32 readPixels SkPixmap::addr16
2632
2633##
2634
2635# ------------------------------------------------------------------------------
2636
2637#Method inline uint8_t* getAddr8(int x, int y) const
2638#In Property
2639#Line # returns readable pixel address as 8-bit pointer ##
2640Returns address at (x, y).
2641
2642Input is not validated. Triggers an assert() if built with SK_DEBUG defined and:
2643#List
2644# Pixel_Ref is nullptr ##
2645# bytesPerPixel() is not one ##
2646# x is negative, or not less than width() ##
2647# y is negative, or not less than height() ##
2648##
2649
2650#Param x  column index, zero or greater, and less than width() ##
2651#Param y  row index, zero or greater, and less than height() ##
2652
2653#Return unsigned 8-bit pointer to pixel at (x, y) ##
2654
2655#Example
2656   SkBitmap bitmap;
2657   const int width = 8;
2658   const int height = 8;
2659   uint8_t pixels[height][width];
2660   SkImageInfo info = SkImageInfo::Make(width, height, kGray_8_SkColorType, kOpaque_SkAlphaType);
2661   if (bitmap.installPixels(info, pixels, info.minRowBytes())) {
2662       SkDebugf("&pixels[4][2] %c= bitmap.getAddr8(2, 4)\n",
2663                 &pixels[4][2]  == bitmap.getAddr8(2, 4) ? '=' : '!');
2664   }
2665#StdOut
2666&pixels[4][2] == bitmap.getAddr8(2, 4)
2667##
2668##
2669
2670#SeeAlso getAddr getAddr16 getAddr32 readPixels SkPixmap::addr8
2671
2672##
2673
2674# ------------------------------------------------------------------------------
2675
2676#Method bool extractSubset(SkBitmap* dst, const SkIRect& subset) const
2677#In Constructor
2678#Line # creates Bitmap, sharing pixels if possible ##
2679Shares Pixel_Ref with dst. Pixels are not copied; Bitmap and dst point
2680to the same pixels; dst bounds() are set to the intersection of subset
2681and the original bounds().
2682
2683subset may be larger than bounds(). Any area outside of bounds() is ignored.
2684
2685Any contents of dst are discarded. isVolatile setting is copied to dst.
2686dst is set to colorType, alphaType, and colorSpace.
2687
2688Return false if:
2689#List
2690# dst is nullptr ##
2691# Pixel_Ref is nullptr ##
2692# subset does not intersect bounds() ##
2693##
2694
2695
2696#Param dst  Bitmap set to subset ##
2697#Param subset  rectangle of pixels to reference ##
2698
2699#Return  true if dst is replaced by subset
2700##
2701
2702#Example
2703#Image 3
2704    SkIRect bounds, s;
2705    source.getBounds(&bounds);
2706    SkDebugf("bounds: %d, %d, %d, %d\n", bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2707    SkBitmap subset;
2708    for (int left: { -100, 0, 100, 1000 } ) {
2709         for (int right: { 0, 100, 1000 } ) {
2710             SkIRect b = SkIRect::MakeLTRB(left, 100, right, 200);
2711             bool success = source.extractSubset(&subset, b);
2712             SkDebugf("subset: %4d, %4d, %4d, %4d  ", b.fLeft, b.fTop, b.fRight, b.fBottom);
2713             SkDebugf("success; %s", success ? "true" : "false");
2714             if (success) {
2715                 subset.getBounds(&s);
2716                 SkDebugf("  subset: %d, %d, %d, %d", s.fLeft, s.fTop, s.fRight, s.fBottom);
2717             }
2718             SkDebugf("\n");
2719         }
2720    }
2721#StdOut
2722bounds: 0, 0, 512, 512
2723subset: -100,  100,    0,  200  success; false
2724subset: -100,  100,  100,  200  success; true  subset: 0, 0, 100, 100
2725subset: -100,  100, 1000,  200  success; true  subset: 0, 0, 512, 100
2726subset:    0,  100,    0,  200  success; false
2727subset:    0,  100,  100,  200  success; true  subset: 0, 0, 100, 100
2728subset:    0,  100, 1000,  200  success; true  subset: 0, 0, 512, 100
2729subset:  100,  100,    0,  200  success; false
2730subset:  100,  100,  100,  200  success; false
2731subset:  100,  100, 1000,  200  success; true  subset: 0, 0, 412, 100
2732subset: 1000,  100,    0,  200  success; false
2733subset: 1000,  100,  100,  200  success; false
2734subset: 1000,  100, 1000,  200  success; false
2735##
2736##
2737
2738#SeeAlso readPixels writePixels SkCanvas::drawBitmap
2739
2740##
2741
2742# ------------------------------------------------------------------------------
2743
2744#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
2745                    int srcX, int srcY, SkTransferFunctionBehavior behavior) const
2746#In Pixels
2747#Line # copies and converts pixels ##
2748
2749Copies Rect of pixels from Bitmap pixels to dstPixels. Copy starts at (srcX, srcY),
2750and does not exceed Bitmap (width(), height()).
2751
2752dstInfo specifies width, height, Color_Type, Alpha_Type, and
2753Color_Space of destination. dstRowBytes specifics the gap from one destination
2754row to the next. Returns true if pixels are copied. Returns false if:
2755#List
2756# dstInfo.addr() equals nullptr ##
2757# dstRowBytes is less than dstInfo.minRowBytes ##
2758# Pixel_Ref is nullptr ##
2759##
2760
2761Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
2762kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType must match.
2763If Bitmap colorType is kGray_8_SkColorType, dstInfo.colorSpace must match.
2764If Bitmap alphaType is kOpaque_SkAlphaType, dstInfo.alphaType must
2765match. If Bitmap colorSpace is nullptr, dstInfo.colorSpace must match. Returns
2766false if pixel conversion is not possible.
2767
2768srcX and srcY may be negative to copy only top or left of source. Returns
2769false if width() or height() is zero or negative.
2770Returns false if
2771#Formula
2772abs(srcX) >= Bitmap width()
2773##
2774, or if
2775#Formula
2776abs(srcY) >= Bitmap height()
2777##
2778.
2779
2780If behavior is SkTransferFunctionBehavior::kRespect: converts source
2781pixels to a linear space before converting to dstInfo.
2782If behavior is SkTransferFunctionBehavior::kIgnore: source
2783pixels are treated as if they are linear, regardless of how they are encoded.
2784
2785#Param dstInfo  destination width, height, Color_Type, Alpha_Type, Color_Space ##
2786#Param dstPixels  destination pixel storage ##
2787#Param dstRowBytes  destination row length ##
2788#Param srcX  column index whose absolute value is less than width() ##
2789#Param srcY  row index whose absolute value is less than height() ##
2790#Param behavior  one of: SkTransferFunctionBehavior::kRespect,
2791                         SkTransferFunctionBehavior::kIgnore
2792##
2793
2794#Return  true if pixels are copied to dstPixels ##
2795
2796#Example
2797#Height 64
2798void draw(SkCanvas* canvas) {
2799    const int width = 256;
2800    const int height = 32;
2801    std::vector<int32_t> dstPixels;
2802    dstPixels.resize(height * width * 4);
2803    SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
2804    SkColor  gradColors[] = { 0xFFAA3300, 0x7F881122 };
2805    SkPoint  gradPoints[] = { { 0, 0 }, { width, 0 } };
2806    SkPaint gradPaint;
2807    gradPaint.setShader(SkGradientShader::MakeLinear(gradPoints, gradColors, nullptr,
2808                    SK_ARRAY_COUNT(gradColors), SkShader::kClamp_TileMode));
2809    for (auto behavior : { SkTransferFunctionBehavior::kRespect,
2810                           SkTransferFunctionBehavior::kIgnore} ) {
2811        SkBitmap bitmap;
2812        bitmap.allocPixels(info);
2813        SkCanvas srcCanvas(bitmap);
2814        srcCanvas.drawRect(SkRect::MakeWH(width, height), gradPaint);
2815        if (bitmap.readPixels(info, &dstPixels.front(), width * 4, 0, 0, behavior)) {
2816            SkPixmap dstPixmap(info, &dstPixels.front(), width * 4);
2817            bitmap.installPixels(dstPixmap);
2818            canvas->drawBitmap(bitmap, 0, 0);
2819        }
2820        canvas->translate(0, height);
2821    }
2822}
2823##
2824
2825#SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels
2826
2827##
2828
2829# ------------------------------------------------------------------------------
2830
2831#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
2832                    int srcX, int srcY) const
2833
2834Copies a Rect of pixels from Bitmap to dstPixels. Copy starts at (srcX, srcY),
2835and does not exceed Bitmap (width(), height()).
2836
2837dstInfo specifies width, height, Color_Type, Alpha_Type, and Color_Space of
2838destination. dstRowBytes specifics the gap from one destination row to the next.
2839Returns true if pixels are copied. Returns false if:
2840#List
2841# dstInfo.addr() equals nullptr ##
2842# dstRowBytes is less than dstInfo.minRowBytes ##
2843# Pixel_Ref is nullptr ##
2844##
2845
2846Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
2847kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType must match.
2848If Bitmap colorType is kGray_8_SkColorType, dstInfo.colorSpace must match.
2849If Bitmap alphaType is kOpaque_SkAlphaType, dstInfo.alphaType must
2850match. If Bitmap colorSpace is nullptr, dstInfo.colorSpace must match. Returns
2851false if pixel conversion is not possible.
2852
2853srcX and srcY may be negative to copy only top or left of source. Returns
2854false if width() or height() is zero or negative.
2855Returns false if
2856#Formula
2857abs(srcX) >= Bitmap width()
2858##
2859, or if
2860#Formula
2861abs(srcY) >= Bitmap height()
2862##
2863.
2864
2865#Param dstInfo  destination width, height, Color_Type, Alpha_Type, Color_Space ##
2866#Param dstPixels  destination pixel storage ##
2867#Param dstRowBytes  destination row length ##
2868#Param srcX  column index whose absolute value is less than width() ##
2869#Param srcY  row index whose absolute value is less than height() ##
2870
2871#Return  true if pixels are copied to dstPixels ##
2872
2873#Example
2874#Height 128
2875#Description
2876Transferring the gradient from 8 bits per component to 4 bits per component
2877creates visible banding.
2878##
2879    const int width = 256;
2880    const int height = 64;
2881    SkImageInfo srcInfo = SkImageInfo::MakeN32Premul(width, height);
2882    SkColor  gradColors[] = { 0xFFAA3300, 0x7F881122 };
2883    SkPoint  gradPoints[] = { { 0, 0 }, { 256, 0 } };
2884    SkPaint paint;
2885    paint.setShader(SkGradientShader::MakeLinear(gradPoints, gradColors, nullptr,
2886                    SK_ARRAY_COUNT(gradColors), SkShader::kClamp_TileMode));
2887    SkBitmap bitmap;
2888    bitmap.allocPixels(srcInfo);
2889    SkCanvas srcCanvas(bitmap);
2890    srcCanvas.drawRect(SkRect::MakeWH(width, height), paint);
2891    canvas->drawBitmap(bitmap, 0, 0);
2892    SkImageInfo dstInfo = srcInfo.makeColorType(kARGB_4444_SkColorType);
2893    std::vector<int16_t> dstPixels;
2894    dstPixels.resize(height * width);
2895    bitmap.readPixels(dstInfo, &dstPixels.front(), width * 2, 0, 0);
2896    SkPixmap dstPixmap(dstInfo, &dstPixels.front(), width * 2);
2897    bitmap.installPixels(dstPixmap);
2898    canvas->drawBitmap(bitmap, 0, 64);
2899##
2900
2901#SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels
2902
2903##
2904
2905# ------------------------------------------------------------------------------
2906
2907#Method bool readPixels(const SkPixmap& dst, int srcX, int srcY) const
2908
2909Copies a Rect of pixels from Bitmap to dst. Copy starts at (srcX, srcY), and
2910does not exceed Bitmap (width(), height()).
2911
2912dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
2913and row bytes of destination. dst.rowBytes specifics the gap from one destination
2914row to the next. Returns true if pixels are copied. Returns false if:
2915#List
2916# dst pixel storage equals nullptr ##
2917# dst.rowBytes is less than SkImageInfo::minRowBytes ##
2918# Pixel_Ref is nullptr ##
2919##
2920
2921Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
2922kGray_8_SkColorType, or kAlpha_8_SkColorType; dst Color_Type must match.
2923If Bitmap colorType is kGray_8_SkColorType, dst Color_Space must match.
2924If Bitmap alphaType is kOpaque_SkAlphaType, dst Alpha_Type must
2925match. If Bitmap colorSpace is nullptr, dst Color_Space must match. Returns
2926false if pixel conversion is not possible.
2927
2928srcX and srcY may be negative to copy only top or left of source. Returns
2929false if width() or height() is zero or negative.
2930Returns false if
2931#Formula
2932abs(srcX) >= Bitmap width()
2933##
2934, or if
2935#Formula
2936abs(srcY) >= Bitmap height()
2937##
2938.
2939
2940#Param dst  destination Pixmap: Image_Info, pixels, row bytes ##
2941#Param srcX  column index whose absolute value is less than width() ##
2942#Param srcY  row index whose absolute value is less than height() ##
2943
2944#Return  true if pixels are copied to dst ##
2945
2946#Example
2947#Image 3
2948    std::vector<int32_t> srcPixels;
2949    srcPixels.resize(source.height() * source.rowBytes());
2950    for (int y = 0; y < 4; ++y) {
2951        for (int x = 0; x < 4; ++x) {
2952            SkPixmap pixmap(SkImageInfo::MakeN32Premul(source.width() / 4, source.height() / 4),
2953                    &srcPixels.front() + x * source.height() * source.width() / 4 +
2954                    y * source.width() / 4, source.rowBytes());
2955            source.readPixels(pixmap, x * source.width() / 4, y * source.height() / 4);
2956        }
2957    }
2958    canvas->scale(.5f, .5f);
2959    SkBitmap bitmap;
2960    bitmap.installPixels(SkImageInfo::MakeN32Premul(source.width(), source.height()),
2961                             &srcPixels.front(), source.rowBytes());
2962    canvas->drawBitmap(bitmap, 0, 0);
2963##
2964
2965#SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels
2966
2967##
2968
2969# ------------------------------------------------------------------------------
2970
2971#Method bool readPixels(const SkPixmap& dst) const
2972
2973Copies a Rect of pixels from Bitmap to dst. Copy starts at (0, 0), and
2974does not exceed Bitmap (width(), height()).
2975
2976dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
2977and row bytes of destination. dst.rowBytes specifics the gap from one destination
2978row to the next. Returns true if pixels are copied. Returns false if:
2979#List
2980# dst pixel storage equals nullptr ##
2981# dst.rowBytes is less than SkImageInfo::minRowBytes ##
2982# Pixel_Ref is nullptr ##
2983##
2984
2985Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
2986kGray_8_SkColorType, or kAlpha_8_SkColorType; dst Color_Type must match.
2987If Bitmap colorType is kGray_8_SkColorType, dst Color_Space must match.
2988If Bitmap alphaType is kOpaque_SkAlphaType, dst Alpha_Type must
2989match. If Bitmap colorSpace is nullptr, dst Color_Space must match. Returns
2990false if pixel conversion is not possible.
2991
2992#Param dst  destination Pixmap: Image_Info, pixels, row bytes ##
2993
2994#Return  true if pixels are copied to dst ##
2995
2996#Example
2997#Height 128
2998#Image 3
2999    std::vector<int32_t> srcPixels;
3000    srcPixels.resize(source.height() * source.width() * 8);
3001    for (int i = 0;  i < 2; ++i) {
3002    SkPixmap pixmap(SkImageInfo::Make(source.width() * 2, source.height(),
3003                    i ? kRGBA_8888_SkColorType : kBGRA_8888_SkColorType, kPremul_SkAlphaType),
3004                    &srcPixels.front() + i * source.width(), source.rowBytes() * 2);
3005        source.readPixels(pixmap);
3006    }
3007    canvas->scale(.25f, .25f);
3008    SkBitmap bitmap;
3009    bitmap.installPixels(SkImageInfo::MakeN32Premul(source.width() * 2, source.height()),
3010                         &srcPixels.front(), source.rowBytes() * 2);
3011    canvas->drawBitmap(bitmap, 0, 0);
3012##
3013
3014#SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels
3015
3016##
3017
3018# ------------------------------------------------------------------------------
3019
3020#Method bool writePixels(const SkPixmap& src, int dstX, int dstY)
3021#In Pixels
3022#Line # copies and converts pixels ##
3023Copies a Rect of pixels from src. Copy starts at (dstX, dstY), and does not exceed
3024(src.width(), src.height()).
3025
3026src specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
3027and row bytes of source. src.rowBytes specifics the gap from one source
3028row to the next. Returns true if pixels are copied. Returns false if:
3029#List
3030# src pixel storage equals nullptr ##
3031# src.rowBytes is less than SkImageInfo::minRowBytes ##
3032# Pixel_Ref is nullptr ##
3033##
3034
3035Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
3036kGray_8_SkColorType, or kAlpha_8_SkColorType; src Color_Type must match.
3037If Bitmap colorType is kGray_8_SkColorType, src Color_Space must match.
3038If Bitmap alphaType is kOpaque_SkAlphaType, src Alpha_Type must
3039match. If Bitmap colorSpace is nullptr, src Color_Space must match. Returns
3040false if pixel conversion is not possible.
3041
3042dstX and dstY may be negative to copy only top or left of source. Returns
3043false if width() or height() is zero or negative.
3044Returns false if
3045#Formula
3046abs(dstX) >= Bitmap width()
3047##
3048, or if
3049#Formula
3050abs(dstY) >= Bitmap height()
3051##
3052.
3053
3054#Param src  source Pixmap: Image_Info, pixels, row bytes ##
3055#Param dstX  column index whose absolute value is less than width() ##
3056#Param dstY  row index whose absolute value is less than height() ##
3057
3058#Return  true if src pixels are copied to Bitmap ##
3059
3060#Example
3061#Image 3
3062    std::vector<int32_t> srcPixels;
3063    int width = image->width();
3064    int height = image->height();
3065    srcPixels.resize(height * width  * 4);
3066    SkPixmap pixmap(SkImageInfo::MakeN32Premul(width, height), (const void*) &srcPixels.front(),
3067                    width * 4);
3068    image->readPixels(pixmap, 0, 0);
3069    canvas->scale(.5f, .5f);
3070    width /= 4;
3071    height /= 4;
3072    for (int y = 0; y < 4; ++y) {
3073        for (int x = 0; x < 4; ++x) {
3074            SkBitmap bitmap;
3075            bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height));
3076            bitmap.writePixels(pixmap, -y * width, -x * height);
3077            canvas->drawBitmap(bitmap, x * width, y * height);
3078        }
3079    }
3080##
3081
3082#SeeAlso readPixels
3083
3084##
3085
3086# ------------------------------------------------------------------------------
3087
3088#Method bool writePixels(const SkPixmap& src)
3089
3090Copies a Rect of pixels from src. Copy starts at (0, 0), and does not exceed
3091(src.width(), src.height()).
3092
3093src specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
3094and row bytes of source. src.rowBytes specifics the gap from one source
3095row to the next. Returns true if pixels are copied. Returns false if:
3096#List
3097# src pixel storage equals nullptr ##
3098# src.rowBytes is less than SkImageInfo::minRowBytes ##
3099# Pixel_Ref is nullptr ##
3100##
3101
3102Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
3103kGray_8_SkColorType, or kAlpha_8_SkColorType; src Color_Type must match.
3104If Bitmap colorType is kGray_8_SkColorType, src Color_Space must match.
3105If Bitmap alphaType is kOpaque_SkAlphaType, src Alpha_Type must
3106match. If Bitmap colorSpace is nullptr, src Color_Space must match. Returns
3107false if pixel conversion is not possible.
3108
3109#Param src  source Pixmap: Image_Info, pixels, row bytes ##
3110
3111#Return  true if src pixels are copied to Bitmap ##
3112
3113#Example
3114#Height 80
3115    SkBitmap bitmap;
3116    bitmap.allocPixels(SkImageInfo::MakeN32Premul(2, 2));
3117    bitmap.eraseColor(SK_ColorGREEN);
3118    SkPMColor color = 0xFF5599BB;
3119    SkPixmap src(SkImageInfo::MakeN32Premul(1, 1), &color, 4);
3120    bitmap.writePixels(src);
3121    canvas->scale(40, 40);
3122    canvas->drawBitmap(bitmap, 0, 0);
3123##
3124
3125#SeeAlso readPixels
3126
3127##
3128
3129# ------------------------------------------------------------------------------
3130
3131#Method bool writePixels(const SkPixmap& src, int x, int y, SkTransferFunctionBehavior behavior)
3132
3133Copies a Rect of pixels from src. Copy starts at (0, 0), and does not exceed
3134(src.width(), src.height()).
3135
3136src specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
3137and row bytes of source. src.rowBytes specifics the gap from one source
3138row to the next. Returns true if pixels are copied. Returns false if:
3139#List
3140# src pixel storage equals nullptr ##
3141# src.rowBytes is less than SkImageInfo::minRowBytes ##
3142# Pixel_Ref is nullptr ##
3143##
3144
3145Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
3146kGray_8_SkColorType, or kAlpha_8_SkColorType; src Color_Type must match.
3147If Bitmap colorType is kGray_8_SkColorType, src Color_Space must match.
3148If Bitmap alphaType is kOpaque_SkAlphaType, src Alpha_Type must
3149match. If Bitmap colorSpace is nullptr, src Color_Space must match. Returns
3150false if pixel conversion is not possible. Returns false if width() or height()
3151is zero or negative.
3152
3153If behavior is SkTransferFunctionBehavior::kRespect: converts src
3154pixels to a linear space before converting to Image_Info.
3155If behavior is SkTransferFunctionBehavior::kIgnore: src
3156pixels are treated as if they are linear, regardless of how they are encoded.
3157
3158#Param src  source Pixmap: Image_Info, pixels, row bytes ##
3159#Param x  column index whose absolute value is less than width() ##
3160#Param y  row index whose absolute value is less than height() ##
3161#Param behavior  one of: SkTransferFunctionBehavior::kRespect,
3162                         SkTransferFunctionBehavior::kIgnore
3163##
3164
3165#Return  true if src pixels are copied to Bitmap ##
3166
3167#Example
3168#Height 64
3169    const int width = 256;
3170    const int height = 32;
3171    std::vector<int32_t> dstPixels;
3172    dstPixels.resize(height * width * 4);
3173    SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
3174    SkColor  gradColors[] = { 0xFFAA3300, 0x7F881122 };
3175    SkPoint  gradPoints[] = { { 0, 0 }, { width, 0 } };
3176    SkPaint gradPaint;
3177    gradPaint.setShader(SkGradientShader::MakeLinear(gradPoints, gradColors, nullptr,
3178                    SK_ARRAY_COUNT(gradColors), SkShader::kClamp_TileMode));
3179    for (auto behavior : { SkTransferFunctionBehavior::kRespect,
3180                           SkTransferFunctionBehavior::kIgnore} ) {
3181        SkPixmap dstPixmap(info, &dstPixels.front(), width * 4);
3182        SkBitmap bitmap;
3183        bitmap.installPixels(dstPixmap);
3184        SkCanvas srcCanvas(bitmap);
3185        srcCanvas.drawRect(SkRect::MakeWH(width, height), gradPaint);
3186        if (bitmap.writePixels(dstPixmap, 0, 0, behavior)) {
3187            canvas->drawBitmap(bitmap, 0, 0);
3188        }
3189        canvas->translate(0, height);
3190    }
3191##
3192
3193#SeeAlso readPixels
3194
3195##
3196
3197# ------------------------------------------------------------------------------
3198
3199#Method bool hasHardwareMipMap() const
3200#In Property
3201#Line # returns Mip_Map support present; Android only ##
3202#Private
3203Android framework only.
3204##
3205
3206#Return  true if setHasHardwareMipMap has been called with true ##
3207
3208#NoExample
3209##
3210
3211#SeeAlso setHasHardwareMipMap
3212
3213##
3214
3215# ------------------------------------------------------------------------------
3216
3217#Method void setHasHardwareMipMap(bool hasHardwareMipMap)
3218#In Set
3219#Line # sets Mip_Map support present; Android only ##
3220#Private
3221Android framework only.
3222##
3223
3224#Param hasHardwareMipMap  sets state ##
3225
3226#NoExample
3227##
3228
3229#SeeAlso hasHardwareMipMap
3230
3231##
3232
3233# ------------------------------------------------------------------------------
3234
3235#Method bool extractAlpha(SkBitmap* dst) const
3236#In Constructor
3237#Line # creates Bitmap containing Alpha of pixels ##
3238Sets dst to Alpha described by pixels. Returns false if dst cannot be written to
3239or dst pixels cannot be allocated.
3240
3241Uses HeapAllocator to reserve memory for dst Pixel_Ref.
3242
3243#Param dst  holds Pixel_Ref to fill with alpha layer ##
3244
3245#Return  true if Alpha layer was constructed in dst Pixel_Ref ##
3246
3247#Example
3248#Height 100
3249    SkBitmap alpha, bitmap;
3250    bitmap.allocN32Pixels(100, 100);
3251    SkCanvas offscreen(bitmap);
3252    offscreen.clear(0);
3253    SkPaint paint;
3254    paint.setAntiAlias(true);
3255    paint.setColor(SK_ColorBLUE);
3256    paint.setStyle(SkPaint::kStroke_Style);
3257    paint.setStrokeWidth(20);
3258    offscreen.drawCircle(50, 50, 39, paint);
3259    offscreen.flush();
3260    bitmap.extractAlpha(&alpha);
3261    paint.setColor(SK_ColorRED);
3262    canvas->drawBitmap(bitmap, 0, 0, &paint);
3263    canvas->drawBitmap(alpha, 100, 0, &paint);
3264##
3265
3266#SeeAlso extractSubset
3267
3268##
3269
3270# ------------------------------------------------------------------------------
3271
3272#Method bool extractAlpha(SkBitmap* dst, const SkPaint* paint,
3273                      SkIPoint* offset) const
3274
3275Sets dst to Alpha described by pixels. Returns false if dst cannot be written to
3276or dst pixels cannot be allocated.
3277
3278If paint is not nullptr and contains Mask_Filter, SkMaskFilter
3279generates Mask_Alpha from Bitmap. Uses HeapAllocator to reserve memory for dst
3280Pixel_Ref. Sets offset to top-left position for dst for alignment with Bitmap;
3281(0, 0) unless SkMaskFilter generates mask.
3282
3283#Param dst  holds Pixel_Ref to fill with alpha layer ##
3284#Param paint  holds optional Mask_Filter; may be nullptr ##
3285#Param offset  top-left position for dst; may be nullptr ##
3286
3287#Return  true if Alpha layer was constructed in dst Pixel_Ref ##
3288
3289#Bug 7103
3290#Example
3291#Height 160
3292    SkBitmap alpha, bitmap;
3293    bitmap.allocN32Pixels(100, 100);
3294    SkCanvas offscreen(bitmap);
3295    offscreen.clear(0);
3296    SkPaint paint;
3297    paint.setAntiAlias(true);
3298    paint.setColor(SK_ColorBLUE);
3299    paint.setStyle(SkPaint::kStroke_Style);
3300    paint.setStrokeWidth(20);
3301    offscreen.drawCircle(50, 50, 39, paint);
3302    offscreen.flush();
3303    const SkScalar kBlurSigma = SkBlurMaskFilter::ConvertRadiusToSigma(SkIntToScalar(25));
3304    paint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, kBlurSigma,
3305                                    SkBlurMaskFilter::kHighQuality_BlurFlag));
3306    SkIPoint offset;
3307    bitmap.extractAlpha(&alpha, &paint, &offset);
3308    paint.setColor(SK_ColorRED);
3309    canvas->drawBitmap(bitmap, 0, -offset.fY, &paint);
3310    canvas->drawBitmap(alpha, 100 + offset.fX, 0, &paint);
3311##
3312
3313#SeeAlso extractSubset
3314
3315##
3316
3317# ------------------------------------------------------------------------------
3318
3319#Method bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
3320                      SkIPoint* offset) const
3321
3322Sets dst to Alpha described by pixels. Returns false if dst cannot be written to
3323or dst pixels cannot be allocated.
3324
3325If paint is not nullptr and contains Mask_Filter, SkMaskFilter
3326generates Mask_Alpha from Bitmap. allocator may reference a custom allocation
3327class or be set to nullptr to use HeapAllocator. Sets offset to top-left
3328position for dst for alignment with Bitmap; (0, 0) unless SkMaskFilter generates
3329mask.
3330
3331#Param dst  holds Pixel_Ref to fill with alpha layer ##
3332#Param paint  holds optional Mask_Filter; may be nullptr ##
3333#Param allocator   method to reserve memory for Pixel_Ref; may be nullptr ##
3334#Param offset  top-left position for dst; may be nullptr ##
3335
3336#Return  true if Alpha layer was constructed in dst Pixel_Ref ##
3337
3338#Bug 7104
3339#Example
3340#Height 128
3341    SkBitmap alpha, bitmap;
3342    bitmap.allocN32Pixels(100, 100);
3343    SkCanvas offscreen(bitmap);
3344    offscreen.clear(0);
3345    SkPaint paint;
3346    paint.setAntiAlias(true);
3347    paint.setColor(SK_ColorBLUE);
3348    paint.setStyle(SkPaint::kStroke_Style);
3349    paint.setStrokeWidth(20);
3350    offscreen.drawCircle(50, 50, 39, paint);
3351    offscreen.flush();
3352    paint.setMaskFilter(SkBlurMaskFilter::Make(kOuter_SkBlurStyle, 3));
3353    SkIPoint offset;
3354    bitmap.extractAlpha(&alpha, &paint, nullptr, &offset);
3355    paint.setColor(SK_ColorRED);
3356    canvas->drawBitmap(bitmap, 0, -offset.fY, &paint);
3357    canvas->drawBitmap(alpha, 100 + offset.fX, 0, &paint);
3358##
3359
3360#SeeAlso extractSubset
3361
3362##
3363
3364# ------------------------------------------------------------------------------
3365
3366#Method bool peekPixels(SkPixmap* pixmap) const
3367#In Pixels
3368#Line # returns Pixmap if possible ##
3369Copies Bitmap pixel address, row bytes, and Image_Info to pixmap, if address
3370is available, and returns true. If pixel address is not available, return
3371false and leave pixmap unchanged.
3372
3373pixmap contents become invalid on any future change to Bitmap.
3374
3375#Param pixmap  storage for pixel state if pixels are readable; otherwise, ignored ##
3376
3377#Return true if Bitmap has direct access to pixels ##
3378
3379#Example
3380    SkBitmap bitmap;
3381    bitmap.allocPixels(SkImageInfo::MakeN32Premul(6, 11));
3382    SkCanvas offscreen(bitmap);
3383    offscreen.clear(SK_ColorWHITE);
3384    SkPaint paint;
3385    offscreen.drawString("?", 0, 10, paint);
3386    SkPixmap pixmap;
3387    if (bitmap.peekPixels(&pixmap)) {
3388        const SkPMColor* pixels = pixmap.addr32();
3389        SkPMColor pmWhite = pixels[0];
3390        for (int y = 0; y < bitmap.height(); ++y) {
3391            for (int x = 0; x < bitmap.width(); ++x) {
3392                SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
3393            }
3394            SkDebugf("\n");
3395        }
3396    }
3397    #StdOut
3398------
3399-xxx--
3400x---x-
3401----x-
3402---x--
3403--x---
3404--x---
3405------
3406--x---
3407--x---
3408------
3409    #StdOut ##
3410##
3411
3412#SeeAlso pixmap() installPixels readPixels writePixels
3413
3414##
3415
3416# ------------------------------------------------------------------------------
3417#Subtopic Utility
3418#Populate
3419#Line # rarely called management functions ##
3420##
3421
3422#Method void validate() const;
3423#In Utility
3424#Line # asserts if Bitmap is invalid (debug only) ##
3425Asserts if internal values are illegal or inconsistent. Only available if
3426SK_DEBUG is defined at compile time.
3427
3428#NoExample
3429##
3430
3431#SeeAlso SkImageInfo::validate()
3432
3433##
3434
3435# ------------------------------------------------------------------------------
3436
3437#Method void toString(SkString* str) const;
3438#In Utility
3439#Line # converts Bitmap to machine readable form ##
3440#DefinedBy SK_TO_STRING_NONVIRT() ##
3441
3442#Private
3443macro expands to: void toString(SkString* str) const;
3444##
3445
3446Creates string representation of Bitmap. The representation is read by
3447internal debugging tools. The interface and implementation may be
3448suppressed by defining SK_IGNORE_TO_STRING.
3449
3450#Param str  storage for string representation ##
3451
3452#Example
3453    SkBitmap bitmap;
3454    int width = 6;
3455    int height = 11;
3456    bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height));
3457    SkString string;
3458    bitmap.toString(&string);
3459    SkString match;
3460    match.printf("(%d, %d)", width, height);
3461    int start = string.find(match.c_str());
3462    if (start >= 0) {
3463        SkString whStr(&string.c_str()[start], match.size());
3464        SkDebugf("bitmap dimensions %s\n", whStr.c_str());
3465    }
3466    #StdOut
3467    bitmap dimensions (6, 11)
3468    ##
3469##
3470
3471#SeeAlso SkPaint::toString
3472
3473##
3474
3475#Class SkBitmap ##
3476
3477#Topic Bitmap ##
3478
3479