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
8 #include "include/core/SkPixmap.h"
9
10 #include "include/core/SkAlphaType.h"
11 #include "include/core/SkColorPriv.h"
12 #include "include/core/SkColorSpace.h"
13 #include "include/core/SkColorType.h"
14 #include "include/core/SkUnPreMultiply.h"
15 #include "include/private/SkColorData.h"
16 #include "include/private/base/SkFloatingPoint.h"
17 #include "include/private/base/SkTPin.h"
18 #include "src/base/SkHalf.h"
19 #include "src/base/SkVx.h"
20 #include "src/core/SkConvertPixels.h"
21 #include "src/core/SkImageInfoPriv.h"
22 #include "src/core/SkMask.h"
23 #include "src/core/SkReadPixelsRec.h"
24 #include "src/core/SkSwizzlePriv.h"
25 #include "src/opts/SkMemset_opts.h"
26
27 #include <cstdint>
28 #include <cstring>
29 #include <iterator>
30 #include <utility>
31
reset()32 void SkPixmap::reset() {
33 fPixels = nullptr;
34 fRowBytes = 0;
35 fInfo = SkImageInfo::MakeUnknown();
36 }
37
reset(const SkImageInfo & info,const void * addr,size_t rowBytes)38 void SkPixmap::reset(const SkImageInfo& info, const void* addr, size_t rowBytes) {
39 if (addr) {
40 SkASSERT(info.validRowBytes(rowBytes));
41 }
42 fPixels = addr;
43 fRowBytes = rowBytes;
44 fInfo = info;
45 }
46
reset(const SkMask & src)47 bool 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
setColorSpace(sk_sp<SkColorSpace> cs)57 void SkPixmap::setColorSpace(sk_sp<SkColorSpace> cs) {
58 fInfo = fInfo.makeColorSpace(std::move(cs));
59 }
60
colorSpace() const61 SkColorSpace* SkPixmap::colorSpace() const { return fInfo.colorSpace(); }
62
refColorSpace() const63 sk_sp<SkColorSpace> SkPixmap::refColorSpace() const { return fInfo.refColorSpace(); }
64
extractSubset(SkPixmap * result,const SkIRect & subset) const65 bool 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()).
fast_getaddr(const SkPixmap & pm,int x,int y)89 static const void* fast_getaddr(const SkPixmap& pm, int x, int y) {
90 x <<= SkColorTypeShiftPerPixel(pm.colorType());
91 return static_cast<const char*>(pm.addr()) + y * pm.rowBytes() + x;
92 }
93
getAlphaf(int x,int y) const94 float 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()) {
103 case kUnknown_SkColorType:
104 return 0;
105 case kGray_8_SkColorType:
106 case kR8G8_unorm_SkColorType:
107 case kR16G16_unorm_SkColorType:
108 case kR16G16_float_SkColorType:
109 case kRGB_565_SkColorType:
110 case kRGB_888x_SkColorType:
111 case kRGB_101010x_SkColorType:
112 case kBGR_101010x_SkColorType:
113 case kBGR_101010x_XR_SkColorType:
114 case kRGB_F16F16F16x_SkColorType:
115 case kR8_unorm_SkColorType:
116 return 1;
117 case kAlpha_8_SkColorType:
118 value = static_cast<const uint8_t*>(srcPtr)[0] * (1.0f/255);
119 break;
120 case kA16_unorm_SkColorType:
121 value = static_cast<const uint16_t*>(srcPtr)[0] * (1.0f/65535);
122 break;
123 case kA16_float_SkColorType: {
124 SkHalf half = static_cast<const SkHalf*>(srcPtr)[0];
125 value = SkHalfToFloat(half);
126 break;
127 }
128 case kARGB_4444_SkColorType: {
129 uint16_t u16 = static_cast<const uint16_t*>(srcPtr)[0];
130 value = SkGetPackedA4444(u16) * (1.0f/15);
131 break;
132 }
133 case kRGBA_8888_SkColorType:
134 case kBGRA_8888_SkColorType:
135 case kSRGBA_8888_SkColorType:
136 value = static_cast<const uint8_t*>(srcPtr)[3] * (1.0f/255);
137 break;
138 case kRGBA_1010102_SkColorType:
139 case kBGRA_1010102_SkColorType: {
140 uint32_t u32 = static_cast<const uint32_t*>(srcPtr)[0];
141 value = (u32 >> 30) * (1.0f/3);
142 break;
143 }
144 case kBGRA_10101010_XR_SkColorType: {
145 uint64_t u64 = static_cast<const uint64_t*>(srcPtr)[0];
146 value = ((u64 >> 54) - 384) / 510.f;
147 break;
148 }
149 case kRGBA_10x6_SkColorType: {
150 uint64_t u64 = static_cast<const uint64_t*>(srcPtr)[0];
151 value = (u64 >> 54) * (1.0f/1023);
152 break;
153 }
154 case kR16G16B16A16_unorm_SkColorType: {
155 uint64_t u64 = static_cast<const uint64_t*>(srcPtr)[0];
156 value = (u64 >> 48) * (1.0f/65535);
157 break;
158 }
159 case kRGBA_F16Norm_SkColorType:
160 case kRGBA_F16_SkColorType: {
161 value = from_half(skvx::half4::Load(srcPtr))[3];
162 break;
163 }
164 case kRGBA_F32_SkColorType:
165 value = static_cast<const float*>(srcPtr)[3];
166 break;
167 }
168 return value;
169 }
170
readPixels(const SkImageInfo & dstInfo,void * dstPixels,size_t dstRB,int x,int y) const171 bool SkPixmap::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
172 int x, int y) const {
173 if (!SkImageInfoValidConversion(dstInfo, fInfo)) {
174 return false;
175 }
176
177 SkReadPixelsRec rec(dstInfo, dstPixels, dstRB, x, y);
178 if (!rec.trim(fInfo.width(), fInfo.height())) {
179 return false;
180 }
181
182 const void* srcPixels = this->addr(rec.fX, rec.fY);
183 const SkImageInfo srcInfo = fInfo.makeDimensions(rec.fInfo.dimensions());
184 return SkConvertPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, srcInfo, srcPixels,
185 this->rowBytes());
186 }
187
getColor(int x,int y) const188 SkColor SkPixmap::getColor(int x, int y) const {
189 SkASSERT(this->addr());
190 SkASSERT((unsigned)x < (unsigned)this->width());
191 SkASSERT((unsigned)y < (unsigned)this->height());
192
193 const bool needsUnpremul = (kPremul_SkAlphaType == fInfo.alphaType());
194 auto toColor = [needsUnpremul](uint32_t maybePremulColor) {
195 return needsUnpremul ? SkUnPreMultiply::PMColorToColor(maybePremulColor)
196 : SkSwizzle_BGRA_to_PMColor(maybePremulColor);
197 };
198
199 switch (this->colorType()) {
200 case kGray_8_SkColorType: {
201 uint8_t value = *this->addr8(x, y);
202 return SkColorSetRGB(value, value, value);
203 }
204 case kR8_unorm_SkColorType: {
205 uint8_t value = *this->addr8(x, y);
206 return SkColorSetRGB(value, 0, 0);
207 }
208 case kAlpha_8_SkColorType: {
209 return SkColorSetA(0, *this->addr8(x, y));
210 }
211 case kA16_unorm_SkColorType: {
212 uint16_t value = *this->addr16(x, y);
213 return SkColorSetA(0, value * (255 / 65535.0f));
214 }
215 case kA16_float_SkColorType: {
216 SkHalf value = *this->addr16(x, y);
217 return SkColorSetA(0, 255 * SkHalfToFloat(value));
218 }
219 case kRGB_565_SkColorType: {
220 return SkPixel16ToColor(*this->addr16(x, y));
221 }
222 case kARGB_4444_SkColorType: {
223 uint16_t value = *this->addr16(x, y);
224 SkPMColor c = SkPixel4444ToPixel32(value);
225 return toColor(c);
226 }
227 case kR8G8_unorm_SkColorType: {
228 uint16_t value = *this->addr16(x, y);
229 return (uint32_t)( ((value >> 0) & 0xff) ) << 16
230 | (uint32_t)( ((value >> 8) & 0xff) ) << 8
231 | 0xff000000;
232 }
233 case kR16G16_unorm_SkColorType: {
234 uint32_t value = *this->addr32(x, y);
235 return (uint32_t)( ((value >> 0) & 0xffff) * (255/65535.0f) ) << 16
236 | (uint32_t)( ((value >> 16) & 0xffff) * (255/65535.0f) ) << 8
237 | 0xff000000;
238 }
239 case kR16G16_float_SkColorType: {
240 uint32_t value = *this->addr32(x, y);
241 uint32_t r = 255 * SkHalfToFloat((value >> 0) & 0xffff);
242 uint32_t g = 255 * SkHalfToFloat((value >> 16) & 0xffff);
243 return (r << 16) | (g << 8) | 0xff000000;
244 }
245 case kRGB_888x_SkColorType: {
246 uint32_t value = *this->addr32(x, y);
247 return SkSwizzle_RB(value | 0xff000000);
248 }
249 case kBGRA_8888_SkColorType: {
250 uint32_t value = *this->addr32(x, y);
251 SkPMColor c = SkSwizzle_BGRA_to_PMColor(value);
252 return toColor(c);
253 }
254 case kRGBA_8888_SkColorType: {
255 uint32_t value = *this->addr32(x, y);
256 SkPMColor c = SkSwizzle_RGBA_to_PMColor(value);
257 return toColor(c);
258 }
259 case kSRGBA_8888_SkColorType: {
260 auto srgb_to_linear = [](float x) {
261 return (x <= 0.04045f) ? x * (1 / 12.92f)
262 : std::pow(x * (1 / 1.055f) + (0.055f / 1.055f), 2.4f);
263 };
264
265 uint32_t value = *this->addr32(x, y);
266 float r = ((value >> 0) & 0xff) * (1/255.0f),
267 g = ((value >> 8) & 0xff) * (1/255.0f),
268 b = ((value >> 16) & 0xff) * (1/255.0f),
269 a = ((value >> 24) & 0xff) * (1/255.0f);
270 r = srgb_to_linear(r);
271 g = srgb_to_linear(g);
272 b = srgb_to_linear(b);
273 if (a != 0 && needsUnpremul) {
274 r = SkTPin(r/a, 0.0f, 1.0f);
275 g = SkTPin(g/a, 0.0f, 1.0f);
276 b = SkTPin(b/a, 0.0f, 1.0f);
277 }
278 return (uint32_t)( r * 255.0f ) << 16
279 | (uint32_t)( g * 255.0f ) << 8
280 | (uint32_t)( b * 255.0f ) << 0
281 | (uint32_t)( a * 255.0f ) << 24;
282 }
283 case kRGB_101010x_SkColorType: {
284 uint32_t value = *this->addr32(x, y);
285 // Convert 10-bit rgb to 8-bit bgr, and mask in 0xff alpha at the top.
286 return (uint32_t)( ((value >> 0) & 0x3ff) * (255/1023.0f) ) << 16
287 | (uint32_t)( ((value >> 10) & 0x3ff) * (255/1023.0f) ) << 8
288 | (uint32_t)( ((value >> 20) & 0x3ff) * (255/1023.0f) ) << 0
289 | 0xff000000;
290 }
291 case kBGR_101010x_XR_SkColorType: {
292 SkASSERT(false);
293 return 0;
294 }
295 case kBGR_101010x_SkColorType: {
296 uint32_t value = *this->addr32(x, y);
297 // Convert 10-bit bgr to 8-bit bgr, and mask in 0xff alpha at the top.
298 return (uint32_t)( ((value >> 0) & 0x3ff) * (255/1023.0f) ) << 0
299 | (uint32_t)( ((value >> 10) & 0x3ff) * (255/1023.0f) ) << 8
300 | (uint32_t)( ((value >> 20) & 0x3ff) * (255/1023.0f) ) << 16
301 | 0xff000000;
302 }
303 case kRGBA_1010102_SkColorType:
304 case kBGRA_1010102_SkColorType: {
305 uint32_t value = *this->addr32(x, y);
306
307 float r = ((value >> 0) & 0x3ff) * (1/1023.0f),
308 g = ((value >> 10) & 0x3ff) * (1/1023.0f),
309 b = ((value >> 20) & 0x3ff) * (1/1023.0f),
310 a = ((value >> 30) & 0x3 ) * (1/ 3.0f);
311 if (this->colorType() == kBGRA_1010102_SkColorType) {
312 std::swap(r,b);
313 }
314 if (a != 0 && needsUnpremul) {
315 r = SkTPin(r/a, 0.0f, 1.0f);
316 g = SkTPin(g/a, 0.0f, 1.0f);
317 b = SkTPin(b/a, 0.0f, 1.0f);
318 }
319 return (uint32_t)( r * 255.0f ) << 16
320 | (uint32_t)( g * 255.0f ) << 8
321 | (uint32_t)( b * 255.0f ) << 0
322 | (uint32_t)( a * 255.0f ) << 24;
323 }
324 case kBGRA_10101010_XR_SkColorType: {
325 SkASSERT(false);
326 return 0;
327 }
328 case kRGBA_10x6_SkColorType: {
329 uint64_t value = *this->addr64(x, y);
330 float r = ((value >> 6) & 0x3ff) * (1/1023.0f),
331 g = ((value >> 22) & 0x3ff) * (1/1023.0f),
332 b = ((value >> 38) & 0x3ff) * (1/1023.0f),
333 a = ((value >> 54) & 0x3ff) * (1/1023.0f);
334 return (uint32_t)( r * 255.0f ) << 16
335 | (uint32_t)( g * 255.0f ) << 8
336 | (uint32_t)( b * 255.0f ) << 0
337 | (uint32_t)( a * 255.0f ) << 24;
338 }
339 case kR16G16B16A16_unorm_SkColorType: {
340 uint64_t value = *this->addr64(x, y);
341
342 float r = ((value ) & 0xffff) * (1/65535.0f),
343 g = ((value >> 16) & 0xffff) * (1/65535.0f),
344 b = ((value >> 32) & 0xffff) * (1/65535.0f),
345 a = ((value >> 48) & 0xffff) * (1/65535.0f);
346 if (a != 0 && needsUnpremul) {
347 r *= (1.0f/a);
348 g *= (1.0f/a);
349 b *= (1.0f/a);
350 }
351 return (uint32_t)( r * 255.0f ) << 16
352 | (uint32_t)( g * 255.0f ) << 8
353 | (uint32_t)( b * 255.0f ) << 0
354 | (uint32_t)( a * 255.0f ) << 24;
355 }
356 case kRGB_F16F16F16x_SkColorType: {
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 p4[3] = 1.0f;
361 // p4 is RGBA, but we want BGRA, so we need to swap next
362 return Sk4f_toL32(swizzle_rb(p4));
363 }
364 case kRGBA_F16Norm_SkColorType:
365 case kRGBA_F16_SkColorType: {
366 const uint64_t* addr =
367 (const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
368 skvx::float4 p4 = from_half(skvx::half4::Load(addr));
369 if (p4[3] && needsUnpremul) {
370 float inva = 1 / p4[3];
371 p4 = p4 * skvx::float4(inva, inva, inva, 1);
372 }
373 // p4 is RGBA, but we want BGRA, so we need to swap next
374 return Sk4f_toL32(swizzle_rb(p4));
375 }
376 case kRGBA_F32_SkColorType: {
377 const float* rgba =
378 (const float*)fPixels + 4*y*(fRowBytes >> 4) + 4*x;
379 skvx::float4 p4 = skvx::float4::Load(rgba);
380 // From here on, just like F16:
381 if (p4[3] && needsUnpremul) {
382 float inva = 1 / p4[3];
383 p4 = p4 * skvx::float4(inva, inva, inva, 1);
384 }
385 // p4 is RGBA, but we want BGRA, so we need to swap next
386 return Sk4f_toL32(swizzle_rb(p4));
387 }
388 case kUnknown_SkColorType:
389 break;
390 }
391 SkDEBUGFAIL("");
392 return SkColorSetARGB(0, 0, 0, 0);
393 }
394
395 //////////////////////////////////////////////////////////////////////////////////////////////////
396
getColor4f(int x,int y) const397 SkColor4f SkPixmap::getColor4f(int x, int y) const {
398 SkASSERT(this->addr());
399 SkASSERT((unsigned)x < (unsigned)this->width());
400 SkASSERT((unsigned)y < (unsigned)this->height());
401
402 const bool needsUnpremul = (kPremul_SkAlphaType == fInfo.alphaType());
403 auto toColor = [needsUnpremul](uint32_t maybePremulColor) {
404 return needsUnpremul ? SkUnPreMultiply::PMColorToColor(maybePremulColor)
405 : SkSwizzle_BGRA_to_PMColor(maybePremulColor);
406 };
407
408 switch (this->colorType()) {
409 case kGray_8_SkColorType: {
410 float value = *this->addr8(x, y) / 255.0f;
411 return SkColor4f{value, value, value, 1.0};
412 }
413 case kR8_unorm_SkColorType: {
414 float value = *this->addr8(x, y) / 255.0f;
415 return SkColor4f{value, 0.0f, 0.0f, 1.0f};
416 }
417 case kAlpha_8_SkColorType: {
418 float value = *this->addr8(x, y) / 255.0f;
419 return SkColor4f{0.0f, 0.0f, 0.0f, value};
420 }
421 case kA16_unorm_SkColorType: {
422 float value = *this->addr16(x, y) / 65535.0f;
423 return SkColor4f{0.0f, 0.0f, 0.0f, value};
424 }
425 case kA16_float_SkColorType: {
426 SkHalf value = *this->addr16(x, y);
427 return SkColor4f{0.0f, 0.0f, 0.0f, SkHalfToFloat(value)};
428 }
429 case kRGB_565_SkColorType: {
430 SkColor c = SkPixel16ToColor(*this->addr16(x, y));
431 return SkColor4f::FromColor(c);
432 }
433 case kARGB_4444_SkColorType: {
434 uint16_t value = *this->addr16(x, y);
435 SkPMColor c = SkPixel4444ToPixel32(value);
436 return SkColor4f::FromColor(toColor(c));
437 }
438 case kR8G8_unorm_SkColorType: {
439 uint16_t value = *this->addr16(x, y);
440 SkColor c = (uint32_t)(((value >> 0) & 0xff)) << 16 |
441 (uint32_t)(((value >> 8) & 0xff)) << 8 | 0xff000000;
442 return SkColor4f::FromColor(c);
443 }
444 case kR16G16_unorm_SkColorType: {
445 uint32_t value = *this->addr32(x, y);
446 SkColor c = (uint32_t)(((value >> 0) & 0xffff) * (255 / 65535.0f)) << 16 |
447 (uint32_t)(((value >> 16) & 0xffff) * (255 / 65535.0f)) << 8 | 0xff000000;
448 return SkColor4f::FromColor(c);
449 }
450 case kR16G16_float_SkColorType: {
451 uint32_t value = *this->addr32(x, y);
452 float r = SkHalfToFloat((value >> 0) & 0xffff);
453 float g = SkHalfToFloat((value >> 16) & 0xffff);
454 return SkColor4f{r, g, 0.0, 1.0};
455 }
456 case kRGB_888x_SkColorType: {
457 uint32_t value = *this->addr32(x, y);
458 SkColor c = SkSwizzle_RB(value | 0xff000000);
459 return SkColor4f::FromColor(c);
460 }
461 case kBGRA_8888_SkColorType: {
462 uint32_t value = *this->addr32(x, y);
463 SkPMColor c = SkSwizzle_BGRA_to_PMColor(value);
464 return SkColor4f::FromColor(toColor(c));
465 }
466 case kRGBA_8888_SkColorType: {
467 uint32_t value = *this->addr32(x, y);
468 SkPMColor c = SkSwizzle_RGBA_to_PMColor(value);
469 return SkColor4f::FromColor(toColor(c));
470 }
471 case kSRGBA_8888_SkColorType: {
472 auto srgb_to_linear = [](float x) {
473 return (x <= 0.04045f) ? x * (1 / 12.92f)
474 : std::pow(x * (1 / 1.055f) + (0.055f / 1.055f), 2.4f);
475 };
476
477 uint32_t value = *this->addr32(x, y);
478 float r = ((value >> 0) & 0xff) * (1 / 255.0f),
479 g = ((value >> 8) & 0xff) * (1 / 255.0f),
480 b = ((value >> 16) & 0xff) * (1 / 255.0f),
481 a = ((value >> 24) & 0xff) * (1 / 255.0f);
482 r = srgb_to_linear(r);
483 g = srgb_to_linear(g);
484 b = srgb_to_linear(b);
485 if (a != 0 && needsUnpremul) {
486 r = SkTPin(r / a, 0.0f, 1.0f);
487 g = SkTPin(g / a, 0.0f, 1.0f);
488 b = SkTPin(b / a, 0.0f, 1.0f);
489 }
490 return SkColor4f{r, g, b, a};
491 }
492 case kBGR_101010x_XR_SkColorType: {
493 SkASSERT(false);
494 return {};
495 }
496 case kRGB_101010x_SkColorType: {
497 uint32_t value = *this->addr32(x, y);
498 // Convert 10-bit rgb to float rgb, and mask in 0xff alpha at the top.
499 float r = (uint32_t)((value >> 0) & 0x3ff) / (1023.0f);
500 float g = (uint32_t)((value >> 10) & 0x3ff) / (1023.0f);
501 float b = (uint32_t)((value >> 20) & 0x3ff) / (1023.0f);
502 float a = 1.0f;
503 return SkColor4f{r, g, b, a};
504 }
505 case kBGR_101010x_SkColorType: {
506 uint32_t value = *this->addr32(x, y);
507 // Convert 10-bit bgr to float rgb, and mask in 0xff alpha at the top.
508 float r = (uint32_t)((value >> 20) & 0x3ff) / (1023.0f);
509 float g = (uint32_t)((value >> 10) & 0x3ff) / (1023.0f);
510 float b = (uint32_t)((value >> 0) & 0x3ff) / (1023.0f);
511 float a = 1.0f;
512 return SkColor4f{r, g, b, a};
513 }
514 case kRGBA_1010102_SkColorType:
515 case kBGRA_1010102_SkColorType: {
516 uint32_t value = *this->addr32(x, y);
517
518 float r = ((value >> 0) & 0x3ff) * (1 / 1023.0f),
519 g = ((value >> 10) & 0x3ff) * (1 / 1023.0f),
520 b = ((value >> 20) & 0x3ff) * (1 / 1023.0f),
521 a = ((value >> 30) & 0x3) * (1 / 3.0f);
522 if (this->colorType() == kBGRA_1010102_SkColorType) {
523 std::swap(r, b);
524 }
525 if (a != 0 && needsUnpremul) {
526 r = SkTPin(r / a, 0.0f, 1.0f);
527 g = SkTPin(g / a, 0.0f, 1.0f);
528 b = SkTPin(b / a, 0.0f, 1.0f);
529 }
530 return SkColor4f{r, g, b, a};
531 }
532 case kBGRA_10101010_XR_SkColorType: {
533 SkASSERT(false);
534 return {};
535 }
536 case kRGBA_10x6_SkColorType: {
537 uint64_t value = *this->addr64(x, y);
538
539 float r = ((value >> 6) & 0x3ff) * (1/1023.0f),
540 g = ((value >> 22) & 0x3ff) * (1/1023.0f),
541 b = ((value >> 38) & 0x3ff) * (1/1023.0f),
542 a = ((value >> 54) & 0x3ff) * (1/1023.0f);
543 return SkColor4f{r, g, b, a};
544 }
545 case kR16G16B16A16_unorm_SkColorType: {
546 uint64_t value = *this->addr64(x, y);
547
548 float r = ((value)&0xffff) * (1 / 65535.0f),
549 g = ((value >> 16) & 0xffff) * (1 / 65535.0f),
550 b = ((value >> 32) & 0xffff) * (1 / 65535.0f),
551 a = ((value >> 48) & 0xffff) * (1 / 65535.0f);
552 if (a != 0 && needsUnpremul) {
553 r *= (1.0f / a);
554 g *= (1.0f / a);
555 b *= (1.0f / a);
556 }
557 return SkColor4f{r, g, b, a};
558 }
559 case kRGBA_F16Norm_SkColorType:
560 case kRGBA_F16_SkColorType: {
561 const uint64_t* addr = (const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
562 skvx::float4 p4 = from_half(skvx::half4::Load(addr));
563 if (p4[3] && needsUnpremul) {
564 float inva = 1 / p4[3];
565 p4 = p4 * skvx::float4(inva, inva, inva, 1);
566 }
567 return SkColor4f{p4[0], p4[1], p4[2], p4[3]};
568 }
569 case kRGB_F16F16F16x_SkColorType: {
570 const uint64_t* addr = (const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
571 skvx::float4 p4 = from_half(skvx::half4::Load(addr));
572 p4[3] = 1.0f;
573 return SkColor4f{p4[0], p4[1], p4[2], p4[3]};
574 }
575 case kRGBA_F32_SkColorType: {
576 const float* rgba = (const float*)fPixels + 4 * y * (fRowBytes >> 4) + 4 * x;
577 skvx::float4 p4 = skvx::float4::Load(rgba);
578 // From here on, just like F16:
579 if (p4[3] && needsUnpremul) {
580 float inva = 1 / p4[3];
581 p4 = p4 * skvx::float4(inva, inva, inva, 1);
582 }
583 return SkColor4f{p4[0], p4[1], p4[2], p4[3]};
584 }
585 case kUnknown_SkColorType:
586 break;
587 }
588 SkDEBUGFAIL("");
589 return SkColors::kTransparent;
590 }
591
computeIsOpaque() const592 bool SkPixmap::computeIsOpaque() const {
593 const int height = this->height();
594 const int width = this->width();
595
596 switch (this->colorType()) {
597 case kAlpha_8_SkColorType: {
598 unsigned a = 0xFF;
599 for (int y = 0; y < height; ++y) {
600 const uint8_t* row = this->addr8(0, y);
601 for (int x = 0; x < width; ++x) {
602 a &= row[x];
603 }
604 if (0xFF != a) {
605 return false;
606 }
607 }
608 return true;
609 }
610 case kA16_unorm_SkColorType: {
611 unsigned a = 0xFFFF;
612 for (int y = 0; y < height; ++y) {
613 const uint16_t* row = this->addr16(0, y);
614 for (int x = 0; x < width; ++x) {
615 a &= row[x];
616 }
617 if (0xFFFF != a) {
618 return false;
619 }
620 }
621 return true;
622 }
623 case kA16_float_SkColorType: {
624 for (int y = 0; y < height; ++y) {
625 const SkHalf* row = this->addr16(0, y);
626 for (int x = 0; x < width; ++x) {
627 if (row[x] < SK_Half1) {
628 return false;
629 }
630 }
631 }
632 return true;
633 }
634 case kRGB_565_SkColorType:
635 case kGray_8_SkColorType:
636 case kR8G8_unorm_SkColorType:
637 case kR16G16_unorm_SkColorType:
638 case kR16G16_float_SkColorType:
639 case kRGB_888x_SkColorType:
640 case kRGB_101010x_SkColorType:
641 case kBGR_101010x_SkColorType:
642 case kRGB_F16F16F16x_SkColorType:
643 case kBGR_101010x_XR_SkColorType:
644 case kR8_unorm_SkColorType:
645 return true;
646 case kARGB_4444_SkColorType: {
647 unsigned c = 0xFFFF;
648 for (int y = 0; y < height; ++y) {
649 const SkPMColor16* row = this->addr16(0, y);
650 for (int x = 0; x < width; ++x) {
651 c &= row[x];
652 }
653 if (0xF != SkGetPackedA4444(c)) {
654 return false;
655 }
656 }
657 return true;
658 }
659 case kBGRA_8888_SkColorType:
660 case kRGBA_8888_SkColorType:
661 case kSRGBA_8888_SkColorType: {
662 SkPMColor c = (SkPMColor)~0;
663 for (int y = 0; y < height; ++y) {
664 const SkPMColor* row = this->addr32(0, y);
665 for (int x = 0; x < width; ++x) {
666 c &= row[x];
667 }
668 if (0xFF != SkGetPackedA32(c)) {
669 return false;
670 }
671 }
672 return true;
673 }
674 case kRGBA_F16Norm_SkColorType:
675 case kRGBA_F16_SkColorType: {
676 const SkHalf* row = (const SkHalf*)this->addr();
677 for (int y = 0; y < height; ++y) {
678 for (int x = 0; x < width; ++x) {
679 if (row[4 * x + 3] < SK_Half1) {
680 return false;
681 }
682 }
683 row += this->rowBytes() >> 1;
684 }
685 return true;
686 }
687 case kRGBA_F32_SkColorType: {
688 const float* row = (const float*)this->addr();
689 for (int y = 0; y < height; ++y) {
690 for (int x = 0; x < width; ++x) {
691 if (row[4 * x + 3] < 1.0f) {
692 return false;
693 }
694 }
695 row += this->rowBytes() >> 2;
696 }
697 return true;
698 }
699 case kRGBA_1010102_SkColorType:
700 case kBGRA_1010102_SkColorType: {
701 uint32_t c = ~0;
702 for (int y = 0; y < height; ++y) {
703 const uint32_t* row = this->addr32(0, y);
704 for (int x = 0; x < width; ++x) {
705 c &= row[x];
706 }
707 if (0b11 != c >> 30) {
708 return false;
709 }
710 }
711 return true;
712 }
713 case kBGRA_10101010_XR_SkColorType:{
714 static constexpr uint64_t kOne = 510 + 384;
715 for (int y = 0; y < height; ++y) {
716 const uint64_t* row = this->addr64(0, y);
717 for (int x = 0; x < width; ++x) {
718 if ((row[x] >> 54) < kOne) {
719 return false;
720 }
721 }
722 }
723 return true;
724 }
725 case kRGBA_10x6_SkColorType: {
726 uint16_t acc = 0xFFC0; // Ignore bottom six bits
727 for (int y = 0; y < height; ++y) {
728 const uint64_t* row = this->addr64(0, y);
729 for (int x = 0; x < width; ++x) {
730 acc &= (row[x] >> 48);
731 }
732 if (0xFFC0 != acc) {
733 return false;
734 }
735 }
736 return true;
737 }
738 case kR16G16B16A16_unorm_SkColorType: {
739 uint16_t acc = 0xFFFF;
740 for (int y = 0; y < height; ++y) {
741 const uint64_t* row = this->addr64(0, y);
742 for (int x = 0; x < width; ++x) {
743 acc &= (row[x] >> 48);
744 }
745 if (0xFFFF != acc) {
746 return false;
747 }
748 }
749 return true;
750 }
751 case kUnknown_SkColorType:
752 SkDEBUGFAIL("");
753 break;
754 }
755 return false;
756 }
757
erase(SkColor color,const SkIRect & subset) const758 bool SkPixmap::erase(SkColor color, const SkIRect& subset) const {
759 return this->erase(SkColor4f::FromColor(color), &subset);
760 }
761
erase(const SkColor4f & color,const SkIRect * subset) const762 bool SkPixmap::erase(const SkColor4f& color, const SkIRect* subset) const {
763 if (this->colorType() == kUnknown_SkColorType) {
764 return false;
765 }
766
767 SkIRect clip = this->bounds();
768 if (subset && !clip.intersect(*subset)) {
769 return false; // is this check really needed (i.e. to return false in this case?)
770 }
771
772 // Erase is meant to simulate drawing in kSRC mode -- which means we have to convert out
773 // unpremul input into premul (which we always do when we draw).
774 const auto c = color.premul();
775
776 const auto dst = SkImageInfo::Make(1, 1, this->colorType(), this->alphaType(),
777 sk_ref_sp(this->colorSpace()));
778 const auto src = SkImageInfo::Make(1, 1, kRGBA_F32_SkColorType, kPremul_SkAlphaType, nullptr);
779
780 uint64_t dstPixel[2] = {}; // be large enough for our widest config (F32 x 4)
781 SkASSERT((size_t)dst.bytesPerPixel() <= sizeof(dstPixel));
782
783 if (!SkConvertPixels(dst, dstPixel, sizeof(dstPixel), src, &c, sizeof(c))) {
784 return false;
785 }
786
787 if (this->colorType() == kRGBA_F32_SkColorType) {
788 SkColor4f dstColor;
789 memcpy(&dstColor, dstPixel, sizeof(dstColor));
790 for (int y = clip.fTop; y < clip.fBottom; ++y) {
791 SkColor4f* addr = (SkColor4f*)this->writable_addr(clip.fLeft, y);
792 SK_OPTS_NS::memsetT(addr, dstColor, clip.width());
793 }
794 } else {
795 using MemSet = void(*)(void*, uint64_t c, int count);
796 const MemSet procs[] = {
797 [](void* addr, uint64_t c, int count) {
798 SkASSERT(c == (uint8_t)c);
799 SK_OPTS_NS::memsetT((uint8_t*)addr, (uint8_t)c, count);
800 },
801 [](void* addr, uint64_t c, int count) {
802 SkASSERT(c == (uint16_t)c);
803 SK_OPTS_NS::memsetT((uint16_t*)addr, (uint16_t)c, count);
804 },
805 [](void* addr, uint64_t c, int count) {
806 SkASSERT(c == (uint32_t)c);
807 SK_OPTS_NS::memsetT((uint32_t*)addr, (uint32_t)c, count);
808 },
809 [](void* addr, uint64_t c, int count) {
810 SK_OPTS_NS::memsetT((uint64_t*)addr, c, count);
811 },
812 };
813
814 unsigned shift = SkColorTypeShiftPerPixel(this->colorType());
815 SkASSERT(shift < std::size(procs));
816 auto proc = procs[shift];
817
818 for (int y = clip.fTop; y < clip.fBottom; ++y) {
819 proc(this->writable_addr(clip.fLeft, y), dstPixel[0], clip.width());
820 }
821 }
822 return true;
823 }
824