Flutter Engine
The Flutter Engine
SkPixmap.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
18#include "src/base/SkHalf.h"
19#include "src/base/SkVx.h"
22#include "src/core/SkMask.h"
26
27#include <cstdint>
28#include <cstring>
29#include <iterator>
30#include <utility>
31
33 fPixels = nullptr;
34 fRowBytes = 0;
36}
37
38void SkPixmap::reset(const SkImageInfo& info, const void* addr, size_t rowBytes) {
39 if (addr) {
41 }
42 fPixels = addr;
43 fRowBytes = rowBytes;
44 fInfo = info;
45}
46
48 if (SkMask::kA8_Format == src.fFormat) {
49 this->reset(SkImageInfo::MakeA8(src.fBounds.width(), src.fBounds.height()),
50 src.fImage, src.fRowBytes);
51 return true;
52 }
53 this->reset();
54 return false;
55}
56
58 fInfo = fInfo.makeColorSpace(std::move(cs));
59}
60
61SkColorSpace* SkPixmap::colorSpace() const { return fInfo.colorSpace(); }
62
64
65bool SkPixmap::extractSubset(SkPixmap* result, const SkIRect& subset) const {
66 SkIRect srcRect, r;
67 srcRect.setWH(this->width(), this->height());
68 if (!r.intersect(srcRect, subset)) {
69 return false; // r is empty (i.e. no intersection)
70 }
71
72 // If the upper left of the rectangle was outside the bounds of this SkBitmap, we should have
73 // exited above.
74 SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width()));
75 SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height()));
76
77 const void* pixels = nullptr;
78 if (fPixels) {
79 const size_t bpp = fInfo.bytesPerPixel();
80 pixels = (const uint8_t*)fPixels + r.fTop * fRowBytes + r.fLeft * bpp;
81 }
82 result->reset(fInfo.makeDimensions(r.size()), pixels, fRowBytes);
83 return true;
84}
85
86// This is the same as SkPixmap::addr(x,y), but this version gets inlined, while the public
87// method does not. Perhaps we could bloat it so it can be inlined, but that would grow code-size
88// everywhere, instead of just here (on behalf of getAlphaf()).
89static const void* fast_getaddr(const SkPixmap& pm, int x, int y) {
91 return static_cast<const char*>(pm.addr()) + y * pm.rowBytes() + x;
92}
93
94float SkPixmap::getAlphaf(int x, int y) const {
95 SkASSERT(this->addr());
96 SkASSERT((unsigned)x < (unsigned)this->width());
97 SkASSERT((unsigned)y < (unsigned)this->height());
98
99 float value = 0;
100 const void* srcPtr = fast_getaddr(*this, x, y);
101
102 switch (this->colorType()) {
104 return 0;
115 return 1;
117 value = static_cast<const uint8_t*>(srcPtr)[0] * (1.0f/255);
118 break;
120 value = static_cast<const uint16_t*>(srcPtr)[0] * (1.0f/65535);
121 break;
123 SkHalf half = static_cast<const SkHalf*>(srcPtr)[0];
124 value = SkHalfToFloat(half);
125 break;
126 }
128 uint16_t u16 = static_cast<const uint16_t*>(srcPtr)[0];
129 value = SkGetPackedA4444(u16) * (1.0f/15);
130 break;
131 }
135 value = static_cast<const uint8_t*>(srcPtr)[3] * (1.0f/255);
136 break;
139 uint32_t u32 = static_cast<const uint32_t*>(srcPtr)[0];
140 value = (u32 >> 30) * (1.0f/3);
141 break;
142 }
144 uint64_t u64 = static_cast<const uint64_t*>(srcPtr)[0];
145 value = ((u64 >> 54) - 384) / 510.f;
146 break;
147 }
149 uint64_t u64 = static_cast<const uint64_t*>(srcPtr)[0];
150 value = (u64 >> 54) * (1.0f/1023);
151 break;
152 }
154 uint64_t u64 = static_cast<const uint64_t*>(srcPtr)[0];
155 value = (u64 >> 48) * (1.0f/65535);
156 break;
157 }
160 value = from_half(skvx::half4::Load(srcPtr))[3];
161 break;
162 }
164 value = static_cast<const float*>(srcPtr)[3];
165 break;
166 }
167 return value;
168}
169
170bool SkPixmap::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
171 int x, int y) const {
172 if (!SkImageInfoValidConversion(dstInfo, fInfo)) {
173 return false;
174 }
175
176 SkReadPixelsRec rec(dstInfo, dstPixels, dstRB, x, y);
177 if (!rec.trim(fInfo.width(), fInfo.height())) {
178 return false;
179 }
180
181 const void* srcPixels = this->addr(rec.fX, rec.fY);
182 const SkImageInfo srcInfo = fInfo.makeDimensions(rec.fInfo.dimensions());
183 return SkConvertPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, srcInfo, srcPixels,
184 this->rowBytes());
185}
186
187SkColor SkPixmap::getColor(int x, int y) const {
188 SkASSERT(this->addr());
189 SkASSERT((unsigned)x < (unsigned)this->width());
190 SkASSERT((unsigned)y < (unsigned)this->height());
191
192 const bool needsUnpremul = (kPremul_SkAlphaType == fInfo.alphaType());
193 auto toColor = [needsUnpremul](uint32_t maybePremulColor) {
194 return needsUnpremul ? SkUnPreMultiply::PMColorToColor(maybePremulColor)
195 : SkSwizzle_BGRA_to_PMColor(maybePremulColor);
196 };
197
198 switch (this->colorType()) {
199 case kGray_8_SkColorType: {
200 uint8_t value = *this->addr8(x, y);
201 return SkColorSetRGB(value, value, value);
202 }
204 uint8_t value = *this->addr8(x, y);
205 return SkColorSetRGB(value, 0, 0);
206 }
208 return SkColorSetA(0, *this->addr8(x, y));
209 }
211 uint16_t value = *this->addr16(x, y);
212 return SkColorSetA(0, value * (255 / 65535.0f));
213 }
215 SkHalf value = *this->addr16(x, y);
216 return SkColorSetA(0, 255 * SkHalfToFloat(value));
217 }
219 return SkPixel16ToColor(*this->addr16(x, y));
220 }
222 uint16_t value = *this->addr16(x, y);
224 return toColor(c);
225 }
227 uint16_t value = *this->addr16(x, y);
228 return (uint32_t)( ((value >> 0) & 0xff) ) << 16
229 | (uint32_t)( ((value >> 8) & 0xff) ) << 8
230 | 0xff000000;
231 }
233 uint32_t value = *this->addr32(x, y);
234 return (uint32_t)( ((value >> 0) & 0xffff) * (255/65535.0f) ) << 16
235 | (uint32_t)( ((value >> 16) & 0xffff) * (255/65535.0f) ) << 8
236 | 0xff000000;
237 }
239 uint32_t value = *this->addr32(x, y);
240 uint32_t r = 255 * SkHalfToFloat((value >> 0) & 0xffff);
241 uint32_t g = 255 * SkHalfToFloat((value >> 16) & 0xffff);
242 return (r << 16) | (g << 8) | 0xff000000;
243 }
245 uint32_t value = *this->addr32(x, y);
246 return SkSwizzle_RB(value | 0xff000000);
247 }
249 uint32_t value = *this->addr32(x, y);
251 return toColor(c);
252 }
254 uint32_t value = *this->addr32(x, y);
256 return toColor(c);
257 }
259 auto srgb_to_linear = [](float x) {
260 return (x <= 0.04045f) ? x * (1 / 12.92f)
261 : std::pow(x * (1 / 1.055f) + (0.055f / 1.055f), 2.4f);
262 };
263
264 uint32_t value = *this->addr32(x, y);
265 float r = ((value >> 0) & 0xff) * (1/255.0f),
266 g = ((value >> 8) & 0xff) * (1/255.0f),
267 b = ((value >> 16) & 0xff) * (1/255.0f),
268 a = ((value >> 24) & 0xff) * (1/255.0f);
269 r = srgb_to_linear(r);
270 g = srgb_to_linear(g);
271 b = srgb_to_linear(b);
272 if (a != 0 && needsUnpremul) {
273 r = SkTPin(r/a, 0.0f, 1.0f);
274 g = SkTPin(g/a, 0.0f, 1.0f);
275 b = SkTPin(b/a, 0.0f, 1.0f);
276 }
277 return (uint32_t)( r * 255.0f ) << 16
278 | (uint32_t)( g * 255.0f ) << 8
279 | (uint32_t)( b * 255.0f ) << 0
280 | (uint32_t)( a * 255.0f ) << 24;
281 }
283 uint32_t value = *this->addr32(x, y);
284 // Convert 10-bit rgb to 8-bit bgr, and mask in 0xff alpha at the top.
285 return (uint32_t)( ((value >> 0) & 0x3ff) * (255/1023.0f) ) << 16
286 | (uint32_t)( ((value >> 10) & 0x3ff) * (255/1023.0f) ) << 8
287 | (uint32_t)( ((value >> 20) & 0x3ff) * (255/1023.0f) ) << 0
288 | 0xff000000;
289 }
291 SkASSERT(false);
292 return 0;
293 }
295 uint32_t value = *this->addr32(x, y);
296 // Convert 10-bit bgr to 8-bit bgr, and mask in 0xff alpha at the top.
297 return (uint32_t)( ((value >> 0) & 0x3ff) * (255/1023.0f) ) << 0
298 | (uint32_t)( ((value >> 10) & 0x3ff) * (255/1023.0f) ) << 8
299 | (uint32_t)( ((value >> 20) & 0x3ff) * (255/1023.0f) ) << 16
300 | 0xff000000;
301 }
304 uint32_t value = *this->addr32(x, y);
305
306 float r = ((value >> 0) & 0x3ff) * (1/1023.0f),
307 g = ((value >> 10) & 0x3ff) * (1/1023.0f),
308 b = ((value >> 20) & 0x3ff) * (1/1023.0f),
309 a = ((value >> 30) & 0x3 ) * (1/ 3.0f);
310 if (this->colorType() == kBGRA_1010102_SkColorType) {
311 std::swap(r,b);
312 }
313 if (a != 0 && needsUnpremul) {
314 r = SkTPin(r/a, 0.0f, 1.0f);
315 g = SkTPin(g/a, 0.0f, 1.0f);
316 b = SkTPin(b/a, 0.0f, 1.0f);
317 }
318 return (uint32_t)( r * 255.0f ) << 16
319 | (uint32_t)( g * 255.0f ) << 8
320 | (uint32_t)( b * 255.0f ) << 0
321 | (uint32_t)( a * 255.0f ) << 24;
322 }
324 SkASSERT(false);
325 return 0;
326 }
328 uint64_t value = *this->addr64(x, y);
329 float r = ((value >> 6) & 0x3ff) * (1/1023.0f),
330 g = ((value >> 22) & 0x3ff) * (1/1023.0f),
331 b = ((value >> 38) & 0x3ff) * (1/1023.0f),
332 a = ((value >> 54) & 0x3ff) * (1/1023.0f);
333 return (uint32_t)( r * 255.0f ) << 16
334 | (uint32_t)( g * 255.0f ) << 8
335 | (uint32_t)( b * 255.0f ) << 0
336 | (uint32_t)( a * 255.0f ) << 24;
337 }
339 uint64_t value = *this->addr64(x, y);
340
341 float r = ((value ) & 0xffff) * (1/65535.0f),
342 g = ((value >> 16) & 0xffff) * (1/65535.0f),
343 b = ((value >> 32) & 0xffff) * (1/65535.0f),
344 a = ((value >> 48) & 0xffff) * (1/65535.0f);
345 if (a != 0 && needsUnpremul) {
346 r *= (1.0f/a);
347 g *= (1.0f/a);
348 b *= (1.0f/a);
349 }
350 return (uint32_t)( r * 255.0f ) << 16
351 | (uint32_t)( g * 255.0f ) << 8
352 | (uint32_t)( b * 255.0f ) << 0
353 | (uint32_t)( a * 255.0f ) << 24;
354 }
357 const uint64_t* addr =
358 (const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
360 if (p4[3] && needsUnpremul) {
361 float inva = 1 / p4[3];
362 p4 = p4 * skvx::float4(inva, inva, inva, 1);
363 }
364 // p4 is RGBA, but we want BGRA, so we need to swap next
365 return Sk4f_toL32(swizzle_rb(p4));
366 }
368 const float* rgba =
369 (const float*)fPixels + 4*y*(fRowBytes >> 4) + 4*x;
371 // From here on, just like F16:
372 if (p4[3] && needsUnpremul) {
373 float inva = 1 / p4[3];
374 p4 = p4 * skvx::float4(inva, inva, inva, 1);
375 }
376 // p4 is RGBA, but we want BGRA, so we need to swap next
377 return Sk4f_toL32(swizzle_rb(p4));
378 }
380 break;
381 }
382 SkDEBUGFAIL("");
383 return SkColorSetARGB(0, 0, 0, 0);
384}
385
386//////////////////////////////////////////////////////////////////////////////////////////////////
387
389 SkASSERT(this->addr());
390 SkASSERT((unsigned)x < (unsigned)this->width());
391 SkASSERT((unsigned)y < (unsigned)this->height());
392
393 const bool needsUnpremul = (kPremul_SkAlphaType == fInfo.alphaType());
394 auto toColor = [needsUnpremul](uint32_t maybePremulColor) {
395 return needsUnpremul ? SkUnPreMultiply::PMColorToColor(maybePremulColor)
396 : SkSwizzle_BGRA_to_PMColor(maybePremulColor);
397 };
398
399 switch (this->colorType()) {
400 case kGray_8_SkColorType: {
401 float value = *this->addr8(x, y) / 255.0f;
402 return SkColor4f{value, value, value, 1.0};
403 }
405 float value = *this->addr8(x, y) / 255.0f;
406 return SkColor4f{value, 0.0f, 0.0f, 1.0f};
407 }
409 float value = *this->addr8(x, y) / 255.0f;
410 return SkColor4f{0.0f, 0.0f, 0.0f, value};
411 }
413 float value = *this->addr16(x, y) / 65535.0f;
414 return SkColor4f{0.0f, 0.0f, 0.0f, value};
415 }
417 SkHalf value = *this->addr16(x, y);
418 return SkColor4f{0.0f, 0.0f, 0.0f, SkHalfToFloat(value)};
419 }
421 SkColor c = SkPixel16ToColor(*this->addr16(x, y));
422 return SkColor4f::FromColor(c);
423 }
425 uint16_t value = *this->addr16(x, y);
427 return SkColor4f::FromColor(toColor(c));
428 }
430 uint16_t value = *this->addr16(x, y);
431 SkColor c = (uint32_t)(((value >> 0) & 0xff)) << 16 |
432 (uint32_t)(((value >> 8) & 0xff)) << 8 | 0xff000000;
433 return SkColor4f::FromColor(c);
434 }
436 uint32_t value = *this->addr32(x, y);
437 SkColor c = (uint32_t)(((value >> 0) & 0xffff) * (255 / 65535.0f)) << 16 |
438 (uint32_t)(((value >> 16) & 0xffff) * (255 / 65535.0f)) << 8 | 0xff000000;
439 return SkColor4f::FromColor(c);
440 }
442 uint32_t value = *this->addr32(x, y);
443 float r = SkHalfToFloat((value >> 0) & 0xffff);
444 float g = SkHalfToFloat((value >> 16) & 0xffff);
445 return SkColor4f{r, g, 0.0, 1.0};
446 }
448 uint32_t value = *this->addr32(x, y);
449 SkColor c = SkSwizzle_RB(value | 0xff000000);
450 return SkColor4f::FromColor(c);
451 }
453 uint32_t value = *this->addr32(x, y);
455 return SkColor4f::FromColor(toColor(c));
456 }
458 uint32_t value = *this->addr32(x, y);
460 return SkColor4f::FromColor(toColor(c));
461 }
463 auto srgb_to_linear = [](float x) {
464 return (x <= 0.04045f) ? x * (1 / 12.92f)
465 : std::pow(x * (1 / 1.055f) + (0.055f / 1.055f), 2.4f);
466 };
467
468 uint32_t value = *this->addr32(x, y);
469 float r = ((value >> 0) & 0xff) * (1 / 255.0f),
470 g = ((value >> 8) & 0xff) * (1 / 255.0f),
471 b = ((value >> 16) & 0xff) * (1 / 255.0f),
472 a = ((value >> 24) & 0xff) * (1 / 255.0f);
473 r = srgb_to_linear(r);
474 g = srgb_to_linear(g);
475 b = srgb_to_linear(b);
476 if (a != 0 && needsUnpremul) {
477 r = SkTPin(r / a, 0.0f, 1.0f);
478 g = SkTPin(g / a, 0.0f, 1.0f);
479 b = SkTPin(b / a, 0.0f, 1.0f);
480 }
481 return SkColor4f{r, g, b, a};
482 }
484 SkASSERT(false);
485 return {};
486 }
488 uint32_t value = *this->addr32(x, y);
489 // Convert 10-bit rgb to float rgb, and mask in 0xff alpha at the top.
490 float r = (uint32_t)((value >> 0) & 0x3ff) / (1023.0f);
491 float g = (uint32_t)((value >> 10) & 0x3ff) / (1023.0f);
492 float b = (uint32_t)((value >> 20) & 0x3ff) / (1023.0f);
493 float a = 1.0f;
494 return SkColor4f{r, g, b, a};
495 }
497 uint32_t value = *this->addr32(x, y);
498 // Convert 10-bit bgr to float rgb, and mask in 0xff alpha at the top.
499 float r = (uint32_t)((value >> 20) & 0x3ff) / (1023.0f);
500 float g = (uint32_t)((value >> 10) & 0x3ff) / (1023.0f);
501 float b = (uint32_t)((value >> 0) & 0x3ff) / (1023.0f);
502 float a = 1.0f;
503 return SkColor4f{r, g, b, a};
504 }
507 uint32_t value = *this->addr32(x, y);
508
509 float r = ((value >> 0) & 0x3ff) * (1 / 1023.0f),
510 g = ((value >> 10) & 0x3ff) * (1 / 1023.0f),
511 b = ((value >> 20) & 0x3ff) * (1 / 1023.0f),
512 a = ((value >> 30) & 0x3) * (1 / 3.0f);
513 if (this->colorType() == kBGRA_1010102_SkColorType) {
514 std::swap(r, b);
515 }
516 if (a != 0 && needsUnpremul) {
517 r = SkTPin(r / a, 0.0f, 1.0f);
518 g = SkTPin(g / a, 0.0f, 1.0f);
519 b = SkTPin(b / a, 0.0f, 1.0f);
520 }
521 return SkColor4f{r, g, b, a};
522 }
524 SkASSERT(false);
525 return {};
526 }
528 uint64_t value = *this->addr64(x, y);
529
530 float r = ((value >> 6) & 0x3ff) * (1/1023.0f),
531 g = ((value >> 22) & 0x3ff) * (1/1023.0f),
532 b = ((value >> 38) & 0x3ff) * (1/1023.0f),
533 a = ((value >> 54) & 0x3ff) * (1/1023.0f);
534 return SkColor4f{r, g, b, a};
535 }
537 uint64_t value = *this->addr64(x, y);
538
539 float r = ((value)&0xffff) * (1 / 65535.0f),
540 g = ((value >> 16) & 0xffff) * (1 / 65535.0f),
541 b = ((value >> 32) & 0xffff) * (1 / 65535.0f),
542 a = ((value >> 48) & 0xffff) * (1 / 65535.0f);
543 if (a != 0 && needsUnpremul) {
544 r *= (1.0f / a);
545 g *= (1.0f / a);
546 b *= (1.0f / a);
547 }
548 return SkColor4f{r, g, b, a};
549 }
552 const uint64_t* addr = (const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
554 if (p4[3] && needsUnpremul) {
555 float inva = 1 / p4[3];
556 p4 = p4 * skvx::float4(inva, inva, inva, 1);
557 }
558 return SkColor4f{p4[0], p4[1], p4[2], p4[3]};
559 }
561 const float* rgba = (const float*)fPixels + 4 * y * (fRowBytes >> 4) + 4 * x;
563 // From here on, just like F16:
564 if (p4[3] && needsUnpremul) {
565 float inva = 1 / p4[3];
566 p4 = p4 * skvx::float4(inva, inva, inva, 1);
567 }
568 return SkColor4f{p4[0], p4[1], p4[2], p4[3]};
569 }
571 break;
572 }
573 SkDEBUGFAIL("");
575}
576
578 const int height = this->height();
579 const int width = this->width();
580
581 switch (this->colorType()) {
583 unsigned a = 0xFF;
584 for (int y = 0; y < height; ++y) {
585 const uint8_t* row = this->addr8(0, y);
586 for (int x = 0; x < width; ++x) {
587 a &= row[x];
588 }
589 if (0xFF != a) {
590 return false;
591 }
592 }
593 return true;
594 }
596 unsigned a = 0xFFFF;
597 for (int y = 0; y < height; ++y) {
598 const uint16_t* row = this->addr16(0, y);
599 for (int x = 0; x < width; ++x) {
600 a &= row[x];
601 }
602 if (0xFFFF != a) {
603 return false;
604 }
605 }
606 return true;
607 }
609 for (int y = 0; y < height; ++y) {
610 const SkHalf* row = this->addr16(0, y);
611 for (int x = 0; x < width; ++x) {
612 if (row[x] < SK_Half1) {
613 return false;
614 }
615 }
616 }
617 return true;
618 }
629 return true;
631 unsigned c = 0xFFFF;
632 for (int y = 0; y < height; ++y) {
633 const SkPMColor16* row = this->addr16(0, y);
634 for (int x = 0; x < width; ++x) {
635 c &= row[x];
636 }
637 if (0xF != SkGetPackedA4444(c)) {
638 return false;
639 }
640 }
641 return true;
642 }
646 SkPMColor c = (SkPMColor)~0;
647 for (int y = 0; y < height; ++y) {
648 const SkPMColor* row = this->addr32(0, y);
649 for (int x = 0; x < width; ++x) {
650 c &= row[x];
651 }
652 if (0xFF != SkGetPackedA32(c)) {
653 return false;
654 }
655 }
656 return true;
657 }
660 const SkHalf* row = (const SkHalf*)this->addr();
661 for (int y = 0; y < height; ++y) {
662 for (int x = 0; x < width; ++x) {
663 if (row[4 * x + 3] < SK_Half1) {
664 return false;
665 }
666 }
667 row += this->rowBytes() >> 1;
668 }
669 return true;
670 }
672 const float* row = (const float*)this->addr();
673 for (int y = 0; y < height; ++y) {
674 for (int x = 0; x < width; ++x) {
675 if (row[4 * x + 3] < 1.0f) {
676 return false;
677 }
678 }
679 row += this->rowBytes() >> 2;
680 }
681 return true;
682 }
685 uint32_t c = ~0;
686 for (int y = 0; y < height; ++y) {
687 const uint32_t* row = this->addr32(0, y);
688 for (int x = 0; x < width; ++x) {
689 c &= row[x];
690 }
691 if (0b11 != c >> 30) {
692 return false;
693 }
694 }
695 return true;
696 }
698 static constexpr uint64_t kOne = 510 + 384;
699 for (int y = 0; y < height; ++y) {
700 const uint64_t* row = this->addr64(0, y);
701 for (int x = 0; x < width; ++x) {
702 if ((row[x] >> 54) < kOne) {
703 return false;
704 }
705 }
706 }
707 return true;
708 }
710 uint16_t acc = 0xFFC0; // Ignore bottom six bits
711 for (int y = 0; y < height; ++y) {
712 const uint64_t* row = this->addr64(0, y);
713 for (int x = 0; x < width; ++x) {
714 acc &= (row[x] >> 48);
715 }
716 if (0xFFC0 != acc) {
717 return false;
718 }
719 }
720 return true;
721 }
723 uint16_t acc = 0xFFFF;
724 for (int y = 0; y < height; ++y) {
725 const uint64_t* row = this->addr64(0, y);
726 for (int x = 0; x < width; ++x) {
727 acc &= (row[x] >> 48);
728 }
729 if (0xFFFF != acc) {
730 return false;
731 }
732 }
733 return true;
734 }
736 SkDEBUGFAIL("");
737 break;
738 }
739 return false;
740}
741
742bool SkPixmap::erase(SkColor color, const SkIRect& subset) const {
743 return this->erase(SkColor4f::FromColor(color), &subset);
744}
745
746bool SkPixmap::erase(const SkColor4f& color, const SkIRect* subset) const {
747 if (this->colorType() == kUnknown_SkColorType) {
748 return false;
749 }
750
751 SkIRect clip = this->bounds();
752 if (subset && !clip.intersect(*subset)) {
753 return false; // is this check really needed (i.e. to return false in this case?)
754 }
755
756 // Erase is meant to simulate drawing in kSRC mode -- which means we have to convert out
757 // unpremul input into premul (which we always do when we draw).
758 const auto c = color.premul();
759
760 const auto dst = SkImageInfo::Make(1, 1, this->colorType(), this->alphaType(),
761 sk_ref_sp(this->colorSpace()));
763
764 uint64_t dstPixel[2] = {}; // be large enough for our widest config (F32 x 4)
765 SkASSERT((size_t)dst.bytesPerPixel() <= sizeof(dstPixel));
766
767 if (!SkConvertPixels(dst, dstPixel, sizeof(dstPixel), src, &c, sizeof(c))) {
768 return false;
769 }
770
771 if (this->colorType() == kRGBA_F32_SkColorType) {
772 SkColor4f dstColor;
773 memcpy(&dstColor, dstPixel, sizeof(dstColor));
774 for (int y = clip.fTop; y < clip.fBottom; ++y) {
775 SkColor4f* addr = (SkColor4f*)this->writable_addr(clip.fLeft, y);
776 SK_OPTS_NS::memsetT(addr, dstColor, clip.width());
777 }
778 } else {
779 using MemSet = void(*)(void*, uint64_t c, int count);
780 const MemSet procs[] = {
781 [](void* addr, uint64_t c, int count) {
782 SkASSERT(c == (uint8_t)c);
783 SK_OPTS_NS::memsetT((uint8_t*)addr, (uint8_t)c, count);
784 },
785 [](void* addr, uint64_t c, int count) {
786 SkASSERT(c == (uint16_t)c);
787 SK_OPTS_NS::memsetT((uint16_t*)addr, (uint16_t)c, count);
788 },
789 [](void* addr, uint64_t c, int count) {
790 SkASSERT(c == (uint32_t)c);
791 SK_OPTS_NS::memsetT((uint32_t*)addr, (uint32_t)c, count);
792 },
793 [](void* addr, uint64_t c, int count) {
794 SK_OPTS_NS::memsetT((uint64_t*)addr, c, count);
795 },
796 };
797
798 unsigned shift = SkColorTypeShiftPerPixel(this->colorType());
799 SkASSERT(shift < std::size(procs));
800 auto proc = procs[shift];
801
802 for (int y = clip.fTop; y < clip.fBottom; ++y) {
803 proc(this->writable_addr(clip.fLeft, y), dstPixel[0], clip.width());
804 }
805 }
806 return true;
807}
static float srgb_to_linear(float srgb)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
int count
Definition: FontMgrTest.cpp:50
static const uint32_t rgba[kNumPixels]
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SkDEBUGFAIL(message)
Definition: SkAssert.h:118
#define SkASSERT(cond)
Definition: SkAssert.h:116
uint16_t SkPMColor16
Definition: SkColorData.h:348
static SkPMColor SkPixel4444ToPixel32(U16CPU c)
Definition: SkColorData.h:368
static uint32_t SkSwizzle_RB(uint32_t c)
Definition: SkColorData.h:57
static SkColor SkPixel16ToColor(U16CPU src)
Definition: SkColorData.h:332
static SkPMColor SkSwizzle_RGBA_to_PMColor(uint32_t c)
Definition: SkColorData.h:83
static SkPMColor SkSwizzle_BGRA_to_PMColor(uint32_t c)
Definition: SkColorData.h:91
#define SkGetPackedA4444(c)
Definition: SkColorData.h:361
#define SkGetPackedA32(packed)
Definition: SkColorPriv.h:92
@ kR16G16B16A16_unorm_SkColorType
pixel with a little endian uint16_t for red, green, blue
Definition: SkColorType.h:50
@ kRGBA_10x6_SkColorType
pixel with 10 used bits (most significant) followed by 6 unused
Definition: SkColorType.h:33
@ kR8_unorm_SkColorType
Definition: SkColorType.h:54
@ kBGR_101010x_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word
Definition: SkColorType.h:30
@ kARGB_4444_SkColorType
pixel with 4 bits for alpha, red, green, blue; in 16-bit word
Definition: SkColorType.h:23
@ kR8G8_unorm_SkColorType
pixel with a uint8_t for red and green
Definition: SkColorType.h:43
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
@ kA16_unorm_SkColorType
pixel with a little endian uint16_t for alpha
Definition: SkColorType.h:48
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition: SkColorType.h:38
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition: SkColorType.h:21
@ kRGB_101010x_SkColorType
pixel with 10 bits each for red, green, blue; in 32-bit word
Definition: SkColorType.h:29
@ kSRGBA_8888_SkColorType
Definition: SkColorType.h:53
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition: SkColorType.h:35
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition: SkColorType.h:22
@ kBGRA_10101010_XR_SkColorType
pixel with 10 bits each for blue, green, red, alpha; in 64-bit word, extended range
Definition: SkColorType.h:32
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
@ kRGB_888x_SkColorType
pixel with 8 bits each for red, green, blue; in 32-bit word
Definition: SkColorType.h:25
@ kBGRA_1010102_SkColorType
10 bits for blue, green, red; 2 bits for alpha; in 32-bit word
Definition: SkColorType.h:28
@ kA16_float_SkColorType
pixel with a half float for alpha
Definition: SkColorType.h:45
@ kRGBA_F32_SkColorType
pixel using C float for red, green, blue, alpha; in 128-bit word
Definition: SkColorType.h:40
@ kRGBA_1010102_SkColorType
10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
Definition: SkColorType.h:27
@ kBGR_101010x_XR_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word, extended range
Definition: SkColorType.h:31
@ kR16G16_unorm_SkColorType
pixel with a little endian uint16_t for red and green
Definition: SkColorType.h:49
@ kRGBA_F16Norm_SkColorType
pixel with half floats in [0,1] for red, green, blue, alpha;
Definition: SkColorType.h:36
@ kUnknown_SkColorType
uninitialized
Definition: SkColorType.h:20
@ kR16G16_float_SkColorType
pixel with a half float for red and green
Definition: SkColorType.h:46
uint32_t SkColor
Definition: SkColor.h:37
#define SkColorSetRGB(r, g, b)
Definition: SkColor.h:57
uint32_t SkPMColor
Definition: SkColor.h:205
static constexpr SkColor SkColorSetA(SkColor c, U8CPU a)
Definition: SkColor.h:82
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkColor.h:49
bool SkConvertPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRB, const SkImageInfo &srcInfo, const void *srcPixels, size_t srcRB)
float SkHalfToFloat(SkHalf h)
Definition: SkHalf.cpp:24
static constexpr uint16_t SK_Half1
Definition: SkHalf.h:23
uint16_t SkHalf
Definition: SkHalf.h:16
static int SkColorTypeShiftPerPixel(SkColorType ct)
static bool SkImageInfoValidConversion(const SkImageInfo &dst, const SkImageInfo &src)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
static const void * fast_getaddr(const SkPixmap &pm, int x, int y)
Definition: SkPixmap.cpp:89
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341
static uint32_t Sk4f_toL32(const skvx::float4 &px)
Definition: SkSwizzlePriv.h:53
static skvx::float4 swizzle_rb(const skvx::float4 &x)
Definition: SkSwizzlePriv.h:37
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition: SkTPin.h:19
const uint8_t * addr8() const
Definition: SkPixmap.h:326
SkColor getColor(int x, int y) const
Definition: SkPixmap.cpp:187
bool computeIsOpaque() const
Definition: SkPixmap.cpp:577
const uint64_t * addr64() const
Definition: SkPixmap.h:365
const uint32_t * addr32() const
Definition: SkPixmap.h:352
SkIRect bounds() const
Definition: SkPixmap.h:207
bool erase(SkColor color, const SkIRect &subset) const
Definition: SkPixmap.cpp:742
size_t rowBytes() const
Definition: SkPixmap.h:145
int width() const
Definition: SkPixmap.h:160
bool readPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes) const
Definition: SkPixmap.h:592
SkColorType colorType() const
Definition: SkPixmap.h:173
void setColorSpace(sk_sp< SkColorSpace > colorSpace)
Definition: SkPixmap.cpp:57
SkColorSpace * colorSpace() const
Definition: SkPixmap.cpp:61
const SkImageInfo & info() const
Definition: SkPixmap.h:135
const uint16_t * addr16() const
Definition: SkPixmap.h:339
SkColor4f getColor4f(int x, int y) const
Definition: SkPixmap.cpp:388
void * writable_addr() const
Definition: SkPixmap.h:483
float getAlphaf(int x, int y) const
Definition: SkPixmap.cpp:94
const void * addr() const
Definition: SkPixmap.h:153
sk_sp< SkColorSpace > refColorSpace() const
Definition: SkPixmap.cpp:63
int height() const
Definition: SkPixmap.h:166
SkAlphaType alphaType() const
Definition: SkPixmap.h:175
void reset()
Definition: SkPixmap.cpp:32
bool extractSubset(SkPixmap *subset, const SkIRect &area) const
Definition: SkPixmap.cpp:65
static SkColor PMColorToColor(SkPMColor c)
DlColor color
static bool b
struct MyStruct a[10]
uint8_t value
GAsyncResult * result
double y
double x
static void memsetT(T buffer[], T value, int count)
Definition: SkMemset_opts.h:17
constexpr SkColor4f kTransparent
Definition: SkColor.h:434
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
dst
Definition: cp.py:12
flutter::DlColor toColor(const float *components)
Definition: dl_unittests.cc:41
Vec< 4, float > float4
Definition: SkVx.h:1146
SIN Vec< N, float > from_half(const Vec< N, uint16_t > &x)
Definition: SkVx.h:790
Definition: SkRect.h:32
bool intersect(const SkIRect &r)
Definition: SkRect.h:513
constexpr SkISize size() const
Definition: SkRect.h:172
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34
constexpr int32_t width() const
Definition: SkRect.h:158
void setWH(int32_t width, int32_t height)
Definition: SkRect.h:275
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33
sk_sp< SkColorSpace > refColorSpace() const
SkImageInfo makeDimensions(SkISize newSize) const
Definition: SkImageInfo.h:454
SkColorSpace * colorSpace() const
int bytesPerPixel() const
Definition: SkImageInfo.h:492
SkISize dimensions() const
Definition: SkImageInfo.h:421
SkImageInfo makeColorSpace(sk_sp< SkColorSpace > cs) const
static SkImageInfo MakeUnknown()
Definition: SkImageInfo.h:357
int width() const
Definition: SkImageInfo.h:365
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkAlphaType alphaType() const
Definition: SkImageInfo.h:375
int height() const
Definition: SkImageInfo.h:371
bool validRowBytes(size_t rowBytes) const
Definition: SkImageInfo.h:598
static SkImageInfo MakeA8(int width, int height)
Definition: SkMask.h:25
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
Definition: SkMask.h:28
const SkIRect fBounds
Definition: SkMask.h:42
SkImageInfo fInfo
bool trim(int srcWidth, int srcHeight)
Definition: SkVx.h:83
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)
Definition: SkVx.h:109