mirrored from https://skia.googlesource.com/skia
/
SkBitmap.h
1275 lines (964 loc) · 53 KB
/
SkBitmap.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkBitmap_DEFINED
#define SkBitmap_DEFINED
#include "include/core/SkAlphaType.h"
#include "include/core/SkColor.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkSize.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkCPUTypes.h"
#include "include/private/base/SkDebug.h"
#include <cstddef>
#include <cstdint>
class SkColorSpace;
class SkImage;
class SkMatrix;
class SkMipmap;
class SkPaint;
class SkPixelRef;
class SkShader;
enum SkColorType : int;
enum class SkTileMode;
struct SkMaskBuilder;
/** \class SkBitmap
SkBitmap describes a two-dimensional raster pixel array. SkBitmap is built on
SkImageInfo, containing integer width and height, SkColorType and SkAlphaType
describing the pixel format, and SkColorSpace describing the range of colors.
SkBitmap points to SkPixelRef, which describes the physical array of pixels.
SkImageInfo bounds may be located anywhere fully inside SkPixelRef bounds.
SkBitmap can be drawn using SkCanvas. SkBitmap can be a drawing destination for SkCanvas
draw member functions. SkBitmap flexibility as a pixel container limits some
optimizations available to the target platform.
If pixel array is primarily read-only, use SkImage for better performance.
If pixel array is primarily written to, use SkSurface for better performance.
Declaring SkBitmap const prevents altering SkImageInfo: the SkBitmap height, width,
and so on cannot change. It does not affect SkPixelRef: a caller may write its
pixels. Declaring SkBitmap const affects SkBitmap configuration, not its contents.
SkBitmap is not thread safe. Each thread must have its own copy of SkBitmap fields,
although threads may share the underlying pixel array.
*/
class SK_API SkBitmap {
public:
class SK_API Allocator;
/** Creates an empty SkBitmap without pixels, with kUnknown_SkColorType,
kUnknown_SkAlphaType, and with a width and height of zero. SkPixelRef origin is
set to (0, 0).
Use setInfo() to associate SkColorType, SkAlphaType, width, and height
after SkBitmap has been created.
@return empty SkBitmap
example: https://fiddle.skia.org/c/@Bitmap_empty_constructor
*/
SkBitmap();
/** Copies settings from src to returned SkBitmap. Shares pixels if src has pixels
allocated, so both bitmaps reference the same pixels.
@param src SkBitmap to copy SkImageInfo, and share SkPixelRef
@return copy of src
example: https://fiddle.skia.org/c/@Bitmap_copy_const_SkBitmap
*/
SkBitmap(const SkBitmap& src);
/** Copies settings from src to returned SkBitmap. Moves ownership of src pixels to
SkBitmap.
@param src SkBitmap to copy SkImageInfo, and reassign SkPixelRef
@return copy of src
example: https://fiddle.skia.org/c/@Bitmap_move_SkBitmap
*/
SkBitmap(SkBitmap&& src);
/** Decrements SkPixelRef reference count, if SkPixelRef is not nullptr.
*/
~SkBitmap();
/** Copies settings from src to returned SkBitmap. Shares pixels if src has pixels
allocated, so both bitmaps reference the same pixels.
@param src SkBitmap to copy SkImageInfo, and share SkPixelRef
@return copy of src
example: https://fiddle.skia.org/c/@Bitmap_copy_operator
*/
SkBitmap& operator=(const SkBitmap& src);
/** Copies settings from src to returned SkBitmap. Moves ownership of src pixels to
SkBitmap.
@param src SkBitmap to copy SkImageInfo, and reassign SkPixelRef
@return copy of src
example: https://fiddle.skia.org/c/@Bitmap_move_operator
*/
SkBitmap& operator=(SkBitmap&& src);
/** Swaps the fields of the two bitmaps.
@param other SkBitmap exchanged with original
example: https://fiddle.skia.org/c/@Bitmap_swap
*/
void swap(SkBitmap& other);
/** Returns a constant reference to the SkPixmap holding the SkBitmap pixel
address, row bytes, and SkImageInfo.
@return reference to SkPixmap describing this SkBitmap
*/
const SkPixmap& pixmap() const { return fPixmap; }
/** Returns width, height, SkAlphaType, SkColorType, and SkColorSpace.
@return reference to SkImageInfo
*/
const SkImageInfo& info() const { return fPixmap.info(); }
/** Returns pixel count in each row. Should be equal or less than
rowBytes() / info().bytesPerPixel().
May be less than pixelRef().width(). Will not exceed pixelRef().width() less
pixelRefOrigin().fX.
@return pixel width in SkImageInfo
*/
int width() const { return fPixmap.width(); }
/** Returns pixel row count.
Maybe be less than pixelRef().height(). Will not exceed pixelRef().height() less
pixelRefOrigin().fY.
@return pixel height in SkImageInfo
*/
int height() const { return fPixmap.height(); }
SkColorType colorType() const { return fPixmap.colorType(); }
SkAlphaType alphaType() const { return fPixmap.alphaType(); }
/** Returns SkColorSpace, the range of colors, associated with SkImageInfo. The
reference count of SkColorSpace is unchanged. The returned SkColorSpace is
immutable.
@return SkColorSpace in SkImageInfo, or nullptr
*/
SkColorSpace* colorSpace() const;
/** Returns smart pointer to SkColorSpace, the range of colors, associated with
SkImageInfo. The smart pointer tracks the number of objects sharing this
SkColorSpace reference so the memory is released when the owners destruct.
The returned SkColorSpace is immutable.
@return SkColorSpace in SkImageInfo wrapped in a smart pointer
*/
sk_sp<SkColorSpace> refColorSpace() const;
/** Returns number of bytes per pixel required by SkColorType.
Returns zero if colorType( is kUnknown_SkColorType.
@return bytes in pixel
*/
int bytesPerPixel() const { return fPixmap.info().bytesPerPixel(); }
/** Returns number of pixels that fit on row. Should be greater than or equal to
width().
@return maximum pixels per row
*/
int rowBytesAsPixels() const { return fPixmap.rowBytesAsPixels(); }
/** Returns bit shift converting row bytes to row pixels.
Returns zero for kUnknown_SkColorType.
@return one of: 0, 1, 2, 3; left shift to convert pixels to bytes
*/
int shiftPerPixel() const { return fPixmap.shiftPerPixel(); }
/** Returns true if either width() or height() are zero.
Does not check if SkPixelRef is nullptr; call drawsNothing() to check width(),
height(), and SkPixelRef.
@return true if dimensions do not enclose area
*/
bool empty() const { return fPixmap.info().isEmpty(); }
/** Returns true if SkPixelRef is nullptr.
Does not check if width() or height() are zero; call drawsNothing() to check
width(), height(), and SkPixelRef.
@return true if no SkPixelRef is associated
*/
bool isNull() const { return nullptr == fPixelRef; }
/** Returns true if width() or height() are zero, or if SkPixelRef is nullptr.
If true, SkBitmap has no effect when drawn or drawn into.
@return true if drawing has no effect
*/
bool drawsNothing() const {
return this->empty() || this->isNull();
}
/** Returns row bytes, the interval from one pixel row to the next. Row bytes
is at least as large as: width() * info().bytesPerPixel().
Returns zero if colorType() is kUnknown_SkColorType, or if row bytes supplied to
setInfo() is not large enough to hold a row of pixels.
@return byte length of pixel row
*/
size_t rowBytes() const { return fPixmap.rowBytes(); }
/** Sets SkAlphaType, if alphaType is compatible with SkColorType.
Returns true unless alphaType is kUnknown_SkAlphaType and current SkAlphaType
is not kUnknown_SkAlphaType.
Returns true if SkColorType is kUnknown_SkColorType. alphaType is ignored, and
SkAlphaType remains kUnknown_SkAlphaType.
Returns true if SkColorType is kRGB_565_SkColorType or kGray_8_SkColorType.
alphaType is ignored, and SkAlphaType remains kOpaque_SkAlphaType.
If SkColorType is kARGB_4444_SkColorType, kRGBA_8888_SkColorType,
kBGRA_8888_SkColorType, or kRGBA_F16_SkColorType: returns true unless
alphaType is kUnknown_SkAlphaType and SkAlphaType is not kUnknown_SkAlphaType.
If SkAlphaType is kUnknown_SkAlphaType, alphaType is ignored.
If SkColorType is kAlpha_8_SkColorType, returns true unless
alphaType is kUnknown_SkAlphaType and SkAlphaType is not kUnknown_SkAlphaType.
If SkAlphaType is kUnknown_SkAlphaType, alphaType is ignored. If alphaType is
kUnpremul_SkAlphaType, it is treated as kPremul_SkAlphaType.
This changes SkAlphaType in SkPixelRef; all bitmaps sharing SkPixelRef
are affected.
@return true if SkAlphaType is set
example: https://fiddle.skia.org/c/@Bitmap_setAlphaType
*/
bool setAlphaType(SkAlphaType alphaType);
/** Sets the SkColorSpace associated with this SkBitmap.
The raw pixel data is not altered by this call; no conversion is
performed.
This changes SkColorSpace in SkPixelRef; all bitmaps sharing SkPixelRef
are affected.
*/
void setColorSpace(sk_sp<SkColorSpace> colorSpace);
/** Returns pixel address, the base address corresponding to the pixel origin.
@return pixel address
*/
void* getPixels() const { return fPixmap.writable_addr(); }
/** Returns minimum memory required for pixel storage.
Does not include unused memory on last row when rowBytesAsPixels() exceeds width().
Returns SIZE_MAX if result does not fit in size_t.
Returns zero if height() or width() is 0.
Returns height() times rowBytes() if colorType() is kUnknown_SkColorType.
@return size in bytes of image buffer
*/
size_t computeByteSize() const { return fPixmap.computeByteSize(); }
/** Returns true if pixels can not change.
Most immutable SkBitmap checks trigger an assert only on debug builds.
@return true if pixels are immutable
example: https://fiddle.skia.org/c/@Bitmap_isImmutable
*/
bool isImmutable() const;
/** Sets internal flag to mark SkBitmap as immutable. Once set, pixels can not change.
Any other bitmap sharing the same SkPixelRef are also marked as immutable.
Once SkPixelRef is marked immutable, the setting cannot be cleared.
Writing to immutable SkBitmap pixels triggers an assert on debug builds.
example: https://fiddle.skia.org/c/@Bitmap_setImmutable
*/
void setImmutable();
/** Returns true if SkAlphaType is set to hint that all pixels are opaque; their
alpha value is implicitly or explicitly 1.0. If true, and all pixels are
not opaque, Skia may draw incorrectly.
Does not check if SkColorType allows alpha, or if any pixel value has
transparency.
@return true if SkImageInfo SkAlphaType is kOpaque_SkAlphaType
*/
bool isOpaque() const {
return SkAlphaTypeIsOpaque(this->alphaType());
}
/** Resets to its initial state; all fields are set to zero, as if SkBitmap had
been initialized by SkBitmap().
Sets width, height, row bytes to zero; pixel address to nullptr; SkColorType to
kUnknown_SkColorType; and SkAlphaType to kUnknown_SkAlphaType.
If SkPixelRef is allocated, its reference count is decreased by one, releasing
its memory if SkBitmap is the sole owner.
example: https://fiddle.skia.org/c/@Bitmap_reset
*/
void reset();
/** Returns true if all pixels are opaque. SkColorType determines how pixels
are encoded, and whether pixel describes alpha. Returns true for SkColorType
without alpha in each pixel; for other SkColorType, returns true if all
pixels have alpha values equivalent to 1.0 or greater.
For SkColorType kRGB_565_SkColorType or kGray_8_SkColorType: always
returns true. For SkColorType kAlpha_8_SkColorType, kBGRA_8888_SkColorType,
kRGBA_8888_SkColorType: returns true if all pixel alpha values are 255.
For SkColorType kARGB_4444_SkColorType: returns true if all pixel alpha values are 15.
For kRGBA_F16_SkColorType: returns true if all pixel alpha values are 1.0 or
greater.
Returns false for kUnknown_SkColorType.
@param bm SkBitmap to check
@return true if all pixels have opaque values or SkColorType is opaque
*/
static bool ComputeIsOpaque(const SkBitmap& bm) {
return bm.pixmap().computeIsOpaque();
}
/** Returns SkRect { 0, 0, width(), height() }.
@param bounds container for floating point rectangle
example: https://fiddle.skia.org/c/@Bitmap_getBounds
*/
void getBounds(SkRect* bounds) const;
/** Returns SkIRect { 0, 0, width(), height() }.
@param bounds container for integral rectangle
example: https://fiddle.skia.org/c/@Bitmap_getBounds_2
*/
void getBounds(SkIRect* bounds) const;
/** Returns SkIRect { 0, 0, width(), height() }.
@return integral rectangle from origin to width() and height()
*/
SkIRect bounds() const { return fPixmap.info().bounds(); }
/** Returns SkISize { width(), height() }.
@return integral size of width() and height()
*/
SkISize dimensions() const { return fPixmap.info().dimensions(); }
/** Returns the bounds of this bitmap, offset by its SkPixelRef origin.
@return bounds within SkPixelRef bounds
*/
SkIRect getSubset() const {
SkIPoint origin = this->pixelRefOrigin();
return SkIRect::MakeXYWH(origin.x(), origin.y(), this->width(), this->height());
}
/** Sets width, height, SkAlphaType, SkColorType, SkColorSpace, and optional
rowBytes. Frees pixels, and returns true if successful.
imageInfo.alphaType() may be altered to a value permitted by imageInfo.colorSpace().
If imageInfo.colorType() is kUnknown_SkColorType, imageInfo.alphaType() is
set to kUnknown_SkAlphaType.
If imageInfo.colorType() is kAlpha_8_SkColorType and imageInfo.alphaType() is
kUnpremul_SkAlphaType, imageInfo.alphaType() is replaced by kPremul_SkAlphaType.
If imageInfo.colorType() is kRGB_565_SkColorType or kGray_8_SkColorType,
imageInfo.alphaType() is set to kOpaque_SkAlphaType.
If imageInfo.colorType() is kARGB_4444_SkColorType, kRGBA_8888_SkColorType,
kBGRA_8888_SkColorType, or kRGBA_F16_SkColorType: imageInfo.alphaType() remains
unchanged.
rowBytes must equal or exceed imageInfo.minRowBytes(). If imageInfo.colorSpace() is
kUnknown_SkColorType, rowBytes is ignored and treated as zero; for all other
SkColorSpace values, rowBytes of zero is treated as imageInfo.minRowBytes().
Calls reset() and returns false if:
- rowBytes exceeds 31 bits
- imageInfo.width() is negative
- imageInfo.height() is negative
- rowBytes is positive and less than imageInfo.width() times imageInfo.bytesPerPixel()
@param imageInfo contains width, height, SkAlphaType, SkColorType, SkColorSpace
@param rowBytes imageInfo.minRowBytes() or larger; or zero
@return true if SkImageInfo set successfully
example: https://fiddle.skia.org/c/@Bitmap_setInfo
*/
bool setInfo(const SkImageInfo& imageInfo, size_t rowBytes = 0);
/** \enum SkBitmap::AllocFlags
AllocFlags is obsolete. We always zero pixel memory when allocated.
*/
enum AllocFlags {
kZeroPixels_AllocFlag = 1 << 0, //!< zero pixel memory. No effect. This is the default.
};
/** Sets SkImageInfo to info following the rules in setInfo() and allocates pixel
memory. Memory is zeroed.
Returns false and calls reset() if SkImageInfo could not be set, or memory could
not be allocated, or memory could not optionally be zeroed.
On most platforms, allocating pixel memory may succeed even though there is
not sufficient memory to hold pixels; allocation does not take place
until the pixels are written to. The actual behavior depends on the platform
implementation of calloc().
@param info contains width, height, SkAlphaType, SkColorType, SkColorSpace
@param flags kZeroPixels_AllocFlag, or zero
@return true if pixels allocation is successful
*/
[[nodiscard]] bool tryAllocPixelsFlags(const SkImageInfo& info, uint32_t flags);
/** Sets SkImageInfo to info following the rules in setInfo() and allocates pixel
memory. Memory is zeroed.
Aborts execution if SkImageInfo could not be set, or memory could
not be allocated, or memory could not optionally
be zeroed. Abort steps may be provided by the user at compile time by defining
SK_ABORT.
On most platforms, allocating pixel memory may succeed even though there is
not sufficient memory to hold pixels; allocation does not take place
until the pixels are written to. The actual behavior depends on the platform
implementation of calloc().
@param info contains width, height, SkAlphaType, SkColorType, SkColorSpace
@param flags kZeroPixels_AllocFlag, or zero
example: https://fiddle.skia.org/c/@Bitmap_allocPixelsFlags
*/
void allocPixelsFlags(const SkImageInfo& info, uint32_t flags);
/** Sets SkImageInfo to info following the rules in setInfo() and allocates pixel
memory. rowBytes must equal or exceed info.width() times info.bytesPerPixel(),
or equal zero. Pass in zero for rowBytes to compute the minimum valid value.
Returns false and calls reset() if SkImageInfo could not be set, or memory could
not be allocated.
On most platforms, allocating pixel memory may succeed even though there is
not sufficient memory to hold pixels; allocation does not take place
until the pixels are written to. The actual behavior depends on the platform
implementation of malloc().
@param info contains width, height, SkAlphaType, SkColorType, SkColorSpace
@param rowBytes size of pixel row or larger; may be zero
@return true if pixel storage is allocated
*/
[[nodiscard]] bool tryAllocPixels(const SkImageInfo& info, size_t rowBytes);
/** Sets SkImageInfo to info following the rules in setInfo() and allocates pixel
memory. rowBytes must equal or exceed info.width() times info.bytesPerPixel(),
or equal zero. Pass in zero for rowBytes to compute the minimum valid value.
Aborts execution if SkImageInfo could not be set, or memory could
not be allocated. Abort steps may be provided by
the user at compile time by defining SK_ABORT.
On most platforms, allocating pixel memory may succeed even though there is
not sufficient memory to hold pixels; allocation does not take place
until the pixels are written to. The actual behavior depends on the platform
implementation of malloc().
@param info contains width, height, SkAlphaType, SkColorType, SkColorSpace
@param rowBytes size of pixel row or larger; may be zero
example: https://fiddle.skia.org/c/@Bitmap_allocPixels
*/
void allocPixels(const SkImageInfo& info, size_t rowBytes);
/** Sets SkImageInfo to info following the rules in setInfo() and allocates pixel
memory.
Returns false and calls reset() if SkImageInfo could not be set, or memory could
not be allocated.
On most platforms, allocating pixel memory may succeed even though there is
not sufficient memory to hold pixels; allocation does not take place
until the pixels are written to. The actual behavior depends on the platform
implementation of malloc().
@param info contains width, height, SkAlphaType, SkColorType, SkColorSpace
@return true if pixel storage is allocated
*/
[[nodiscard]] bool tryAllocPixels(const SkImageInfo& info) {
return this->tryAllocPixels(info, info.minRowBytes());
}
/** Sets SkImageInfo to info following the rules in setInfo() and allocates pixel
memory.
Aborts execution if SkImageInfo could not be set, or memory could
not be allocated. Abort steps may be provided by
the user at compile time by defining SK_ABORT.
On most platforms, allocating pixel memory may succeed even though there is
not sufficient memory to hold pixels; allocation does not take place
until the pixels are written to. The actual behavior depends on the platform
implementation of malloc().
@param info contains width, height, SkAlphaType, SkColorType, SkColorSpace
example: https://fiddle.skia.org/c/@Bitmap_allocPixels_2
*/
void allocPixels(const SkImageInfo& info);
/** Sets SkImageInfo to width, height, and native color type; and allocates
pixel memory. If isOpaque is true, sets SkImageInfo to kOpaque_SkAlphaType;
otherwise, sets to kPremul_SkAlphaType.
Calls reset() and returns false if width exceeds 29 bits or is negative,
or height is negative.
Returns false if allocation fails.
Use to create SkBitmap that matches SkPMColor, the native pixel arrangement on
the platform. SkBitmap drawn to output device skips converting its pixel format.
@param width pixel column count; must be zero or greater
@param height pixel row count; must be zero or greater
@param isOpaque true if pixels do not have transparency
@return true if pixel storage is allocated
*/
[[nodiscard]] bool tryAllocN32Pixels(int width, int height, bool isOpaque = false);
/** Sets SkImageInfo to width, height, and the native color type; and allocates
pixel memory. If isOpaque is true, sets SkImageInfo to kOpaque_SkAlphaType;
otherwise, sets to kPremul_SkAlphaType.
Aborts if width exceeds 29 bits or is negative, or height is negative, or
allocation fails. Abort steps may be provided by the user at compile time by
defining SK_ABORT.
Use to create SkBitmap that matches SkPMColor, the native pixel arrangement on
the platform. SkBitmap drawn to output device skips converting its pixel format.
@param width pixel column count; must be zero or greater
@param height pixel row count; must be zero or greater
@param isOpaque true if pixels do not have transparency
example: https://fiddle.skia.org/c/@Bitmap_allocN32Pixels
*/
void allocN32Pixels(int width, int height, bool isOpaque = false);
/** Sets SkImageInfo to info following the rules in setInfo(), and creates SkPixelRef
containing pixels and rowBytes. releaseProc, if not nullptr, is called
immediately on failure or when pixels are no longer referenced. context may be
nullptr.
If SkImageInfo could not be set, or rowBytes is less than info.minRowBytes():
calls releaseProc if present, calls reset(), and returns false.
Otherwise, if pixels equals nullptr: sets SkImageInfo, calls releaseProc if
present, returns true.
If SkImageInfo is set, pixels is not nullptr, and releaseProc is not nullptr:
when pixels are no longer referenced, calls releaseProc with pixels and context
as parameters.
@param info contains width, height, SkAlphaType, SkColorType, SkColorSpace
@param pixels address or pixel storage; may be nullptr
@param rowBytes size of pixel row or larger
@param releaseProc function called when pixels can be deleted; may be nullptr
@param context caller state passed to releaseProc; may be nullptr
@return true if SkImageInfo is set to info
*/
bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
void (*releaseProc)(void* addr, void* context), void* context);
/** Sets SkImageInfo to info following the rules in setInfo(), and creates SkPixelRef
containing pixels and rowBytes.
If SkImageInfo could not be set, or rowBytes is less than info.minRowBytes():
calls reset(), and returns false.
Otherwise, if pixels equals nullptr: sets SkImageInfo, returns true.
Caller must ensure that pixels are valid for the lifetime of SkBitmap and SkPixelRef.
@param info contains width, height, SkAlphaType, SkColorType, SkColorSpace
@param pixels address or pixel storage; may be nullptr
@param rowBytes size of pixel row or larger
@return true if SkImageInfo is set to info
*/
bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
return this->installPixels(info, pixels, rowBytes, nullptr, nullptr);
}
/** Sets SkImageInfo to pixmap.info() following the rules in setInfo(), and creates
SkPixelRef containing pixmap.addr() and pixmap.rowBytes().
If SkImageInfo could not be set, or pixmap.rowBytes() is less than
SkImageInfo::minRowBytes(): calls reset(), and returns false.
Otherwise, if pixmap.addr() equals nullptr: sets SkImageInfo, returns true.
Caller must ensure that pixmap is valid for the lifetime of SkBitmap and SkPixelRef.
@param pixmap SkImageInfo, pixel address, and rowBytes()
@return true if SkImageInfo was set to pixmap.info()
example: https://fiddle.skia.org/c/@Bitmap_installPixels_3
*/
bool installPixels(const SkPixmap& pixmap);
/** Deprecated.
*/
bool installMaskPixels(SkMaskBuilder& mask);
/** Replaces SkPixelRef with pixels, preserving SkImageInfo and rowBytes().
Sets SkPixelRef origin to (0, 0).
If pixels is nullptr, or if info().colorType() equals kUnknown_SkColorType;
release reference to SkPixelRef, and set SkPixelRef to nullptr.
Caller is responsible for handling ownership pixel memory for the lifetime
of SkBitmap and SkPixelRef.
@param pixels address of pixel storage, managed by caller
example: https://fiddle.skia.org/c/@Bitmap_setPixels
*/
void setPixels(void* pixels);
/** Allocates pixel memory with HeapAllocator, and replaces existing SkPixelRef.
The allocation size is determined by SkImageInfo width, height, and SkColorType.
Returns false if info().colorType() is kUnknown_SkColorType, or allocation fails.
@return true if the allocation succeeds
*/
[[nodiscard]] bool tryAllocPixels() {
return this->tryAllocPixels((Allocator*)nullptr);
}
/** Allocates pixel memory with HeapAllocator, and replaces existing SkPixelRef.
The allocation size is determined by SkImageInfo width, height, and SkColorType.
Aborts if info().colorType() is kUnknown_SkColorType, or allocation fails.
Abort steps may be provided by the user at compile
time by defining SK_ABORT.
example: https://fiddle.skia.org/c/@Bitmap_allocPixels_3
*/
void allocPixels();
/** Allocates pixel memory with allocator, and replaces existing SkPixelRef.
The allocation size is determined by SkImageInfo width, height, and SkColorType.
If allocator is nullptr, use HeapAllocator instead.
Returns false if Allocator::allocPixelRef return false.
@param allocator instance of SkBitmap::Allocator instantiation
@return true if custom allocator reports success
*/
[[nodiscard]] bool tryAllocPixels(Allocator* allocator);
/** Allocates pixel memory with allocator, and replaces existing SkPixelRef.
The allocation size is determined by SkImageInfo width, height, and SkColorType.
If allocator is nullptr, use HeapAllocator instead.
Aborts if Allocator::allocPixelRef return false. Abort steps may be provided by
the user at compile time by defining SK_ABORT.
@param allocator instance of SkBitmap::Allocator instantiation
example: https://fiddle.skia.org/c/@Bitmap_allocPixels_4
*/
void allocPixels(Allocator* allocator);
/** Returns SkPixelRef, which contains: pixel base address; its dimensions; and
rowBytes(), the interval from one row to the next. Does not change SkPixelRef
reference count. SkPixelRef may be shared by multiple bitmaps.
If SkPixelRef has not been set, returns nullptr.
@return SkPixelRef, or nullptr
*/
SkPixelRef* pixelRef() const { return fPixelRef.get(); }
/** Returns origin of pixels within SkPixelRef. SkBitmap bounds is always contained
by SkPixelRef bounds, which may be the same size or larger. Multiple SkBitmap
can share the same SkPixelRef, where each SkBitmap has different bounds.
The returned origin added to SkBitmap dimensions equals or is smaller than the
SkPixelRef dimensions.
Returns (0, 0) if SkPixelRef is nullptr.
@return pixel origin within SkPixelRef
example: https://fiddle.skia.org/c/@Bitmap_pixelRefOrigin
*/
SkIPoint pixelRefOrigin() const;
/** Replaces pixelRef and origin in SkBitmap. dx and dy specify the offset
within the SkPixelRef pixels for the top-left corner of the bitmap.
Asserts in debug builds if dx or dy are out of range. Pins dx and dy
to legal range in release builds.
The caller is responsible for ensuring that the pixels match the
SkColorType and SkAlphaType in SkImageInfo.
@param pixelRef SkPixelRef describing pixel address and rowBytes()
@param dx column offset in SkPixelRef for bitmap origin
@param dy row offset in SkPixelRef for bitmap origin
example: https://fiddle.skia.org/c/@Bitmap_setPixelRef
*/
void setPixelRef(sk_sp<SkPixelRef> pixelRef, int dx, int dy);
/** Returns true if SkBitmap is can be drawn.
@return true if getPixels() is not nullptr
*/
bool readyToDraw() const {
return this->getPixels() != nullptr;
}
/** Returns a unique value corresponding to the pixels in SkPixelRef.
Returns a different value after notifyPixelsChanged() has been called.
Returns zero if SkPixelRef is nullptr.
Determines if pixels have changed since last examined.
@return unique value for pixels in SkPixelRef
example: https://fiddle.skia.org/c/@Bitmap_getGenerationID
*/
uint32_t getGenerationID() const;
/** Marks that pixels in SkPixelRef have changed. Subsequent calls to
getGenerationID() return a different value.
example: https://fiddle.skia.org/c/@Bitmap_notifyPixelsChanged
*/
void notifyPixelsChanged() const;
/** Replaces pixel values with c, interpreted as being in the sRGB SkColorSpace.
All pixels contained by bounds() are affected. If the colorType() is
kGray_8_SkColorType or kRGB_565_SkColorType, then alpha is ignored; RGB is
treated as opaque. If colorType() is kAlpha_8_SkColorType, then RGB is ignored.
@param c unpremultiplied color
example: https://fiddle.skia.org/c/@Bitmap_eraseColor
*/
void eraseColor(SkColor4f) const;
/** Replaces pixel values with c, interpreted as being in the sRGB SkColorSpace.
All pixels contained by bounds() are affected. If the colorType() is
kGray_8_SkColorType or kRGB_565_SkColorType, then alpha is ignored; RGB is
treated as opaque. If colorType() is kAlpha_8_SkColorType, then RGB is ignored.
Input color is ultimately converted to an SkColor4f, so eraseColor(SkColor4f c)
will have higher color resolution.
@param c unpremultiplied color.
example: https://fiddle.skia.org/c/@Bitmap_eraseColor
*/
void eraseColor(SkColor c) const;
/** Replaces pixel values with unpremultiplied color built from a, r, g, and b,
interpreted as being in the sRGB SkColorSpace. All pixels contained by
bounds() are affected. If the colorType() is kGray_8_SkColorType or
kRGB_565_SkColorType, then a is ignored; r, g, and b are treated as opaque.
If colorType() is kAlpha_8_SkColorType, then r, g, and b are ignored.
@param a amount of alpha, from fully transparent (0) to fully opaque (255)
@param r amount of red, from no red (0) to full red (255)
@param g amount of green, from no green (0) to full green (255)
@param b amount of blue, from no blue (0) to full blue (255)
*/
void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const {
this->eraseColor(SkColorSetARGB(a, r, g, b));
}
/** Replaces pixel values inside area with c. interpreted as being in the sRGB
SkColorSpace. If area does not intersect bounds(), call has no effect.
If the colorType() is kGray_8_SkColorType or kRGB_565_SkColorType, then alpha
is ignored; RGB is treated as opaque. If colorType() is kAlpha_8_SkColorType,
then RGB is ignored.
@param c unpremultiplied color
@param area rectangle to fill
example: https://fiddle.skia.org/c/@Bitmap_erase
*/
void erase(SkColor4f c, const SkIRect& area) const;
/** Replaces pixel values inside area with c. interpreted as being in the sRGB
SkColorSpace. If area does not intersect bounds(), call has no effect.
If the colorType() is kGray_8_SkColorType or kRGB_565_SkColorType, then alpha
is ignored; RGB is treated as opaque. If colorType() is kAlpha_8_SkColorType,
then RGB is ignored.
Input color is ultimately converted to an SkColor4f, so erase(SkColor4f c)
will have higher color resolution.
@param c unpremultiplied color
@param area rectangle to fill
example: https://fiddle.skia.org/c/@Bitmap_erase
*/
void erase(SkColor c, const SkIRect& area) const;
/** Deprecated.
*/
void eraseArea(const SkIRect& area, SkColor c) const {
this->erase(c, area);
}
/** Returns pixel at (x, y) as unpremultiplied color.
Returns black with alpha if SkColorType is kAlpha_8_SkColorType.
Input is not validated: out of bounds values of x or y trigger an assert() if
built with SK_DEBUG defined; and returns undefined values or may crash if
SK_RELEASE is defined. Fails if SkColorType is kUnknown_SkColorType or
pixel address is nullptr.
SkColorSpace in SkImageInfo is ignored. Some color precision may be lost in the
conversion to unpremultiplied color; original pixel data may have additional
precision.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return pixel converted to unpremultiplied color
*/
SkColor getColor(int x, int y) const {
return this->pixmap().getColor(x, y);
}
/** Returns pixel at (x, y) as unpremultiplied float color.
Returns black with alpha if SkColorType is kAlpha_8_SkColorType.
Input is not validated: out of bounds values of x or y trigger an assert() if
built with SK_DEBUG defined; and returns undefined values or may crash if
SK_RELEASE is defined. Fails if SkColorType is kUnknown_SkColorType or
pixel address is nullptr.
SkColorSpace in SkImageInfo is ignored. Some color precision may be lost in the
conversion to unpremultiplied color.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return pixel converted to unpremultiplied color
*/
SkColor4f getColor4f(int x, int y) const { return this->pixmap().getColor4f(x, y); }
/** Look up the pixel at (x,y) and return its alpha component, normalized to [0..1].
This is roughly equivalent to SkGetColorA(getColor()), but can be more efficent
(and more precise if the pixels store more than 8 bits per component).
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return alpha converted to normalized float
*/
float getAlphaf(int x, int y) const {
return this->pixmap().getAlphaf(x, y);
}
/** Returns pixel address at (x, y).
Input is not validated: out of bounds values of x or y, or kUnknown_SkColorType,
trigger an assert() if built with SK_DEBUG defined. Returns nullptr if
SkColorType is kUnknown_SkColorType, or SkPixelRef is nullptr.
Performs a lookup of pixel size; for better performance, call
one of: getAddr8(), getAddr16(), or getAddr32().
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return generic pointer to pixel
example: https://fiddle.skia.org/c/@Bitmap_getAddr
*/
void* getAddr(int x, int y) const;
/** Returns address at (x, y).
Input is not validated. Triggers an assert() if built with SK_DEBUG defined and:
- SkPixelRef is nullptr
- bytesPerPixel() is not four
- x is negative, or not less than width()
- y is negative, or not less than height()
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return unsigned 32-bit pointer to pixel at (x, y)
*/
inline uint32_t* getAddr32(int x, int y) const;
/** Returns address at (x, y).
Input is not validated. Triggers an assert() if built with SK_DEBUG defined and:
- SkPixelRef is nullptr
- bytesPerPixel() is not two
- x is negative, or not less than width()
- y is negative, or not less than height()
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return unsigned 16-bit pointer to pixel at (x, y)
*/
inline uint16_t* getAddr16(int x, int y) const;
/** Returns address at (x, y).
Input is not validated. Triggers an assert() if built with SK_DEBUG defined and:
- SkPixelRef is nullptr
- bytesPerPixel() is not one
- x is negative, or not less than width()
- y is negative, or not less than height()
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return unsigned 8-bit pointer to pixel at (x, y)
*/
inline uint8_t* getAddr8(int x, int y) const;
/** Shares SkPixelRef with dst. Pixels are not copied; SkBitmap and dst point
to the same pixels; dst bounds() are set to the intersection of subset
and the original bounds().
subset may be larger than bounds(). Any area outside of bounds() is ignored.
Any contents of dst are discarded.
Return false if:
- dst is nullptr
- SkPixelRef is nullptr
- subset does not intersect bounds()
@param dst SkBitmap set to subset
@param subset rectangle of pixels to reference
@return true if dst is replaced by subset
example: https://fiddle.skia.org/c/@Bitmap_extractSubset
*/
bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
/** Copies a SkRect of pixels from SkBitmap to dstPixels. Copy starts at (srcX, srcY),
and does not exceed SkBitmap (width(), height()).
dstInfo specifies width, height, SkColorType, SkAlphaType, and SkColorSpace of
destination. dstRowBytes specifics the gap from one destination row to the next.
Returns true if pixels are copied. Returns false if:
- dstInfo has no address
- dstRowBytes is less than dstInfo.minRowBytes()
- SkPixelRef is nullptr
Pixels are copied only if pixel conversion is possible. If SkBitmap colorType() is
kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
If SkBitmap colorType() is kGray_8_SkColorType, dstInfo.colorSpace() must match.
If SkBitmap alphaType() is kOpaque_SkAlphaType, dstInfo.alphaType() must