Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
47bool SkPixmap::reset(const SkMask& src) {
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;
359 skvx::float4 p4 = from_half(skvx::half4::Load(addr));
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;
553 skvx::float4 p4 = from_half(skvx::half4::Load(addr));
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()));
762 const auto src = SkImageInfo::Make(1, 1, kRGBA_F32_SkColorType, kPremul_SkAlphaType, nullptr);
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
SkColor4f color
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
static SkPMColor SkPixel4444ToPixel32(U16CPU c)
static uint32_t SkSwizzle_RB(uint32_t c)
Definition SkColorData.h:57
static SkColor SkPixel16ToColor(U16CPU src)
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)
#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:3824
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
static uint32_t Sk4f_toL32(const skvx::float4 &px)
static skvx::float4 swizzle_rb(const skvx::float4 &x)
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)
static bool b
struct MyStruct a[10]
uint8_t value
GAsyncResult * result
double y
double x
constexpr SkColor4f kTransparent
Definition SkColor.h:434
Vec< 4, float > float4
Definition SkVx.h:1146
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
SkColorSpace * colorSpace() const
int bytesPerPixel() const
SkISize dimensions() const
SkImageInfo makeColorSpace(sk_sp< SkColorSpace > cs) const
static SkImageInfo MakeUnknown()
int width() const
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkAlphaType alphaType() const
int height() const
bool validRowBytes(size_t rowBytes) const
static SkImageInfo MakeA8(int width, int height)
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
Definition SkMask.h:28
const SkIRect fBounds
Definition SkMask.h:42
static SkRGBA4f FromColor(SkColor color)
SkImageInfo fInfo
bool trim(int srcWidth, int srcHeight)
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)
Definition SkVx.h:109