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/SkUnPreMultiply.h"
14 #include "include/private/SkColorData.h"
15 #include "include/private/base/SkFloatingPoint.h"
16 #include "include/private/base/SkTPin.h"
17 #include "src/base/SkHalf.h"
18 #include "src/base/SkVx.h"
19 #include "src/core/SkConvertPixels.h"
20 #include "src/core/SkImageInfoPriv.h"
21 #include "src/core/SkMask.h"
22 #include "src/core/SkReadPixelsRec.h"
23 #include "src/core/SkSwizzlePriv.h"
24
25 #include <cstring>
26 #include <utility>
27
reset()28 void SkPixmap::reset() {
29 fPixels = nullptr;
30 fRowBytes = 0;
31 fInfo = SkImageInfo::MakeUnknown();
32 }
33
reset(const SkImageInfo & info,const void * addr,size_t rowBytes)34 void SkPixmap::reset(const SkImageInfo& info, const void* addr, size_t rowBytes) {
35 if (addr) {
36 SkASSERT(info.validRowBytes(rowBytes));
37 }
38 fPixels = addr;
39 fRowBytes = rowBytes;
40 fInfo = info;
41 }
42
reset(const SkMask & src)43 bool SkPixmap::reset(const SkMask& src) {
44 if (SkMask::kA8_Format == src.fFormat) {
45 this->reset(SkImageInfo::MakeA8(src.fBounds.width(), src.fBounds.height()),
46 src.fImage, src.fRowBytes);
47 return true;
48 }
49 this->reset();
50 return false;
51 }
52
setColorSpace(sk_sp<SkColorSpace> cs)53 void SkPixmap::setColorSpace(sk_sp<SkColorSpace> cs) {
54 fInfo = fInfo.makeColorSpace(std::move(cs));
55 }
56
colorSpace() const57 SkColorSpace* SkPixmap::colorSpace() const { return fInfo.colorSpace(); }
58
refColorSpace() const59 sk_sp<SkColorSpace> SkPixmap::refColorSpace() const { return fInfo.refColorSpace(); }
60
extractSubset(SkPixmap * result,const SkIRect & subset) const61 bool SkPixmap::extractSubset(SkPixmap* result, const SkIRect& subset) const {
62 SkIRect srcRect, r;
63 srcRect.setWH(this->width(), this->height());
64 if (!r.intersect(srcRect, subset)) {
65 return false; // r is empty (i.e. no intersection)
66 }
67
68 // If the upper left of the rectangle was outside the bounds of this SkBitmap, we should have
69 // exited above.
70 SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width()));
71 SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height()));
72
73 const void* pixels = nullptr;
74 if (fPixels) {
75 const size_t bpp = fInfo.bytesPerPixel();
76 pixels = (const uint8_t*)fPixels + r.fTop * fRowBytes + r.fLeft * bpp;
77 }
78 result->reset(fInfo.makeDimensions(r.size()), pixels, fRowBytes);
79 return true;
80 }
81
82 // This is the same as SkPixmap::addr(x,y), but this version gets inlined, while the public
83 // method does not. Perhaps we could bloat it so it can be inlined, but that would grow code-size
84 // everywhere, instead of just here (on behalf of getAlphaf()).
fast_getaddr(const SkPixmap & pm,int x,int y)85 static const void* fast_getaddr(const SkPixmap& pm, int x, int y) {
86 x <<= SkColorTypeShiftPerPixel(pm.colorType());
87 return static_cast<const char*>(pm.addr()) + y * pm.rowBytes() + x;
88 }
89
getAlphaf(int x,int y) const90 float SkPixmap::getAlphaf(int x, int y) const {
91 SkASSERT(this->addr());
92 SkASSERT((unsigned)x < (unsigned)this->width());
93 SkASSERT((unsigned)y < (unsigned)this->height());
94
95 float value = 0;
96 const void* srcPtr = fast_getaddr(*this, x, y);
97
98 switch (this->colorType()) {
99 case kUnknown_SkColorType:
100 return 0;
101 case kGray_8_SkColorType:
102 case kR8G8_unorm_SkColorType:
103 case kR16G16_unorm_SkColorType:
104 case kR16G16_float_SkColorType:
105 case kRGB_565_SkColorType:
106 case kRGB_888x_SkColorType:
107 case kRGB_101010x_SkColorType:
108 case kBGR_101010x_SkColorType:
109 case kBGR_101010x_XR_SkColorType:
110 case kR8_unorm_SkColorType:
111 return 1;
112 case kAlpha_8_SkColorType:
113 value = static_cast<const uint8_t*>(srcPtr)[0] * (1.0f/255);
114 break;
115 case kA16_unorm_SkColorType:
116 value = static_cast<const uint16_t*>(srcPtr)[0] * (1.0f/65535);
117 break;
118 case kA16_float_SkColorType: {
119 SkHalf half = static_cast<const SkHalf*>(srcPtr)[0];
120 value = SkHalfToFloat(half);
121 break;
122 }
123 case kARGB_4444_SkColorType: {
124 uint16_t u16 = static_cast<const uint16_t*>(srcPtr)[0];
125 value = SkGetPackedA4444(u16) * (1.0f/15);
126 break;
127 }
128 case kRGBA_8888_SkColorType:
129 case kBGRA_8888_SkColorType:
130 case kSRGBA_8888_SkColorType:
131 value = static_cast<const uint8_t*>(srcPtr)[3] * (1.0f/255);
132 break;
133 case kRGBA_1010102_SkColorType:
134 case kBGRA_1010102_SkColorType: {
135 uint32_t u32 = static_cast<const uint32_t*>(srcPtr)[0];
136 value = (u32 >> 30) * (1.0f/3);
137 break;
138 }
139 case kR16G16B16A16_unorm_SkColorType: {
140 uint64_t u64 = static_cast<const uint64_t*>(srcPtr)[0];
141 value = (u64 >> 48) * (1.0f/65535);
142 break;
143 }
144 case kRGBA_F16Norm_SkColorType:
145 case kRGBA_F16_SkColorType: {
146 uint64_t px;
147 memcpy(&px, srcPtr, sizeof(px));
148 value = SkHalfToFloat_finite_ftz(px)[3];
149 break;
150 }
151 case kRGBA_F32_SkColorType:
152 value = static_cast<const float*>(srcPtr)[3];
153 break;
154 }
155 return value;
156 }
157
readPixels(const SkImageInfo & dstInfo,void * dstPixels,size_t dstRB,int x,int y) const158 bool SkPixmap::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
159 int x, int y) const {
160 if (!SkImageInfoValidConversion(dstInfo, fInfo)) {
161 return false;
162 }
163
164 SkReadPixelsRec rec(dstInfo, dstPixels, dstRB, x, y);
165 if (!rec.trim(fInfo.width(), fInfo.height())) {
166 return false;
167 }
168
169 const void* srcPixels = this->addr(rec.fX, rec.fY);
170 const SkImageInfo srcInfo = fInfo.makeDimensions(rec.fInfo.dimensions());
171 return SkConvertPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, srcInfo, srcPixels,
172 this->rowBytes());
173 }
174
getColor(int x,int y) const175 SkColor SkPixmap::getColor(int x, int y) const {
176 SkASSERT(this->addr());
177 SkASSERT((unsigned)x < (unsigned)this->width());
178 SkASSERT((unsigned)y < (unsigned)this->height());
179
180 const bool needsUnpremul = (kPremul_SkAlphaType == fInfo.alphaType());
181 auto toColor = [needsUnpremul](uint32_t maybePremulColor) {
182 return needsUnpremul ? SkUnPreMultiply::PMColorToColor(maybePremulColor)
183 : SkSwizzle_BGRA_to_PMColor(maybePremulColor);
184 };
185
186 switch (this->colorType()) {
187 case kGray_8_SkColorType: {
188 uint8_t value = *this->addr8(x, y);
189 return SkColorSetRGB(value, value, value);
190 }
191 case kR8_unorm_SkColorType: {
192 uint8_t value = *this->addr8(x, y);
193 return SkColorSetRGB(value, 0, 0);
194 }
195 case kAlpha_8_SkColorType: {
196 return SkColorSetA(0, *this->addr8(x, y));
197 }
198 case kA16_unorm_SkColorType: {
199 uint16_t value = *this->addr16(x, y);
200 return SkColorSetA(0, value * (255 / 65535.0f));
201 }
202 case kA16_float_SkColorType: {
203 SkHalf value = *this->addr16(x, y);
204 return SkColorSetA(0, 255 * SkHalfToFloat(value));
205 }
206 case kRGB_565_SkColorType: {
207 return SkPixel16ToColor(*this->addr16(x, y));
208 }
209 case kARGB_4444_SkColorType: {
210 uint16_t value = *this->addr16(x, y);
211 SkPMColor c = SkPixel4444ToPixel32(value);
212 return toColor(c);
213 }
214 case kR8G8_unorm_SkColorType: {
215 uint16_t value = *this->addr16(x, y);
216 return (uint32_t)( ((value >> 0) & 0xff) ) << 16
217 | (uint32_t)( ((value >> 8) & 0xff) ) << 8
218 | 0xff000000;
219 }
220 case kR16G16_unorm_SkColorType: {
221 uint32_t value = *this->addr32(x, y);
222 return (uint32_t)( ((value >> 0) & 0xffff) * (255/65535.0f) ) << 16
223 | (uint32_t)( ((value >> 16) & 0xffff) * (255/65535.0f) ) << 8
224 | 0xff000000;
225 }
226 case kR16G16_float_SkColorType: {
227 uint32_t value = *this->addr32(x, y);
228 uint32_t r = 255 * SkHalfToFloat((value >> 0) & 0xffff);
229 uint32_t g = 255 * SkHalfToFloat((value >> 16) & 0xffff);
230 return (r << 16) | (g << 8) | 0xff000000;
231 }
232 case kRGB_888x_SkColorType: {
233 uint32_t value = *this->addr32(x, y);
234 return SkSwizzle_RB(value | 0xff000000);
235 }
236 case kBGRA_8888_SkColorType: {
237 uint32_t value = *this->addr32(x, y);
238 SkPMColor c = SkSwizzle_BGRA_to_PMColor(value);
239 return toColor(c);
240 }
241 case kRGBA_8888_SkColorType: {
242 uint32_t value = *this->addr32(x, y);
243 SkPMColor c = SkSwizzle_RGBA_to_PMColor(value);
244 return toColor(c);
245 }
246 case kSRGBA_8888_SkColorType: {
247 auto srgb_to_linear = [](float x) {
248 return (x <= 0.04045f) ? x * (1 / 12.92f)
249 : sk_float_pow(x * (1 / 1.055f) + (0.055f / 1.055f), 2.4f);
250 };
251
252 uint32_t value = *this->addr32(x, y);
253 float r = ((value >> 0) & 0xff) * (1/255.0f),
254 g = ((value >> 8) & 0xff) * (1/255.0f),
255 b = ((value >> 16) & 0xff) * (1/255.0f),
256 a = ((value >> 24) & 0xff) * (1/255.0f);
257 r = srgb_to_linear(r);
258 g = srgb_to_linear(g);
259 b = srgb_to_linear(b);
260 if (a != 0 && needsUnpremul) {
261 r = SkTPin(r/a, 0.0f, 1.0f);
262 g = SkTPin(g/a, 0.0f, 1.0f);
263 b = SkTPin(b/a, 0.0f, 1.0f);
264 }
265 return (uint32_t)( r * 255.0f ) << 16
266 | (uint32_t)( g * 255.0f ) << 8
267 | (uint32_t)( b * 255.0f ) << 0
268 | (uint32_t)( a * 255.0f ) << 24;
269 }
270 case kRGB_101010x_SkColorType: {
271 uint32_t value = *this->addr32(x, y);
272 // Convert 10-bit rgb to 8-bit bgr, and mask in 0xff alpha at the top.
273 return (uint32_t)( ((value >> 0) & 0x3ff) * (255/1023.0f) ) << 16
274 | (uint32_t)( ((value >> 10) & 0x3ff) * (255/1023.0f) ) << 8
275 | (uint32_t)( ((value >> 20) & 0x3ff) * (255/1023.0f) ) << 0
276 | 0xff000000;
277 }
278 case kBGR_101010x_XR_SkColorType: {
279 SkASSERT(false);
280 return 0;
281 }
282 case kBGR_101010x_SkColorType: {
283 uint32_t value = *this->addr32(x, y);
284 // Convert 10-bit bgr to 8-bit bgr, and mask in 0xff alpha at the top.
285 return (uint32_t)( ((value >> 0) & 0x3ff) * (255/1023.0f) ) << 0
286 | (uint32_t)( ((value >> 10) & 0x3ff) * (255/1023.0f) ) << 8
287 | (uint32_t)( ((value >> 20) & 0x3ff) * (255/1023.0f) ) << 16
288 | 0xff000000;
289 }
290 case kRGBA_1010102_SkColorType:
291 case kBGRA_1010102_SkColorType: {
292 uint32_t value = *this->addr32(x, y);
293
294 float r = ((value >> 0) & 0x3ff) * (1/1023.0f),
295 g = ((value >> 10) & 0x3ff) * (1/1023.0f),
296 b = ((value >> 20) & 0x3ff) * (1/1023.0f),
297 a = ((value >> 30) & 0x3 ) * (1/ 3.0f);
298 if (this->colorType() == kBGRA_1010102_SkColorType) {
299 std::swap(r,b);
300 }
301 if (a != 0 && needsUnpremul) {
302 r = SkTPin(r/a, 0.0f, 1.0f);
303 g = SkTPin(g/a, 0.0f, 1.0f);
304 b = SkTPin(b/a, 0.0f, 1.0f);
305 }
306 return (uint32_t)( r * 255.0f ) << 16
307 | (uint32_t)( g * 255.0f ) << 8
308 | (uint32_t)( b * 255.0f ) << 0
309 | (uint32_t)( a * 255.0f ) << 24;
310 }
311 case kR16G16B16A16_unorm_SkColorType: {
312 uint64_t value = *this->addr64(x, y);
313
314 float r = ((value ) & 0xffff) * (1/65535.0f),
315 g = ((value >> 16) & 0xffff) * (1/65535.0f),
316 b = ((value >> 32) & 0xffff) * (1/65535.0f),
317 a = ((value >> 48) & 0xffff) * (1/65535.0f);
318 if (a != 0 && needsUnpremul) {
319 r *= (1.0f/a);
320 g *= (1.0f/a);
321 b *= (1.0f/a);
322 }
323 return (uint32_t)( r * 255.0f ) << 16
324 | (uint32_t)( g * 255.0f ) << 8
325 | (uint32_t)( b * 255.0f ) << 0
326 | (uint32_t)( a * 255.0f ) << 24;
327 }
328 case kRGBA_F16Norm_SkColorType:
329 case kRGBA_F16_SkColorType: {
330 const uint64_t* addr =
331 (const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
332 skvx::float4 p4 = SkHalfToFloat_finite_ftz(*addr);
333 if (p4[3] && needsUnpremul) {
334 float inva = 1 / p4[3];
335 p4 = p4 * skvx::float4(inva, inva, inva, 1);
336 }
337 // p4 is RGBA, but we want BGRA, so we need to swap next
338 return Sk4f_toL32(swizzle_rb(p4));
339 }
340 case kRGBA_F32_SkColorType: {
341 const float* rgba =
342 (const float*)fPixels + 4*y*(fRowBytes >> 4) + 4*x;
343 skvx::float4 p4 = skvx::float4::Load(rgba);
344 // From here on, just like F16:
345 if (p4[3] && needsUnpremul) {
346 float inva = 1 / p4[3];
347 p4 = p4 * skvx::float4(inva, inva, inva, 1);
348 }
349 // p4 is RGBA, but we want BGRA, so we need to swap next
350 return Sk4f_toL32(swizzle_rb(p4));
351 }
352 case kUnknown_SkColorType:
353 break;
354 }
355 SkDEBUGFAIL("");
356 return SkColorSetARGB(0, 0, 0, 0);
357 }
358
359 //////////////////////////////////////////////////////////////////////////////////////////////////
360
getColor4f(int x,int y) const361 SkColor4f SkPixmap::getColor4f(int x, int y) const {
362 SkASSERT(this->addr());
363 SkASSERT((unsigned)x < (unsigned)this->width());
364 SkASSERT((unsigned)y < (unsigned)this->height());
365
366 const bool needsUnpremul = (kPremul_SkAlphaType == fInfo.alphaType());
367 auto toColor = [needsUnpremul](uint32_t maybePremulColor) {
368 return needsUnpremul ? SkUnPreMultiply::PMColorToColor(maybePremulColor)
369 : SkSwizzle_BGRA_to_PMColor(maybePremulColor);
370 };
371
372 switch (this->colorType()) {
373 case kGray_8_SkColorType: {
374 float value = *this->addr8(x, y) / 255.0f;
375 return SkColor4f{value, value, value, 1.0};
376 }
377 case kR8_unorm_SkColorType: {
378 float value = *this->addr8(x, y) / 255.0f;
379 return SkColor4f{value, 0.0f, 0.0f, 1.0f};
380 }
381 case kAlpha_8_SkColorType: {
382 float value = *this->addr8(x, y) / 255.0f;
383 return SkColor4f{0.0f, 0.0f, 0.0f, value};
384 }
385 case kA16_unorm_SkColorType: {
386 float value = *this->addr16(x, y) / 65535.0f;
387 return SkColor4f{0.0f, 0.0f, 0.0f, value};
388 }
389 case kA16_float_SkColorType: {
390 SkHalf value = *this->addr16(x, y);
391 return SkColor4f{0.0f, 0.0f, 0.0f, SkHalfToFloat(value)};
392 }
393 case kRGB_565_SkColorType: {
394 SkColor c = SkPixel16ToColor(*this->addr16(x, y));
395 return SkColor4f::FromColor(c);
396 }
397 case kARGB_4444_SkColorType: {
398 uint16_t value = *this->addr16(x, y);
399 SkPMColor c = SkPixel4444ToPixel32(value);
400 return SkColor4f::FromColor(toColor(c));
401 }
402 case kR8G8_unorm_SkColorType: {
403 uint16_t value = *this->addr16(x, y);
404 SkColor c = (uint32_t)(((value >> 0) & 0xff)) << 16 |
405 (uint32_t)(((value >> 8) & 0xff)) << 8 | 0xff000000;
406 return SkColor4f::FromColor(c);
407 }
408 case kR16G16_unorm_SkColorType: {
409 uint32_t value = *this->addr32(x, y);
410 SkColor c = (uint32_t)(((value >> 0) & 0xffff) * (255 / 65535.0f)) << 16 |
411 (uint32_t)(((value >> 16) & 0xffff) * (255 / 65535.0f)) << 8 | 0xff000000;
412 return SkColor4f::FromColor(c);
413 }
414 case kR16G16_float_SkColorType: {
415 uint32_t value = *this->addr32(x, y);
416 float r = SkHalfToFloat((value >> 0) & 0xffff);
417 float g = SkHalfToFloat((value >> 16) & 0xffff);
418 return SkColor4f{r, g, 0.0, 1.0};
419 }
420 case kRGB_888x_SkColorType: {
421 uint32_t value = *this->addr32(x, y);
422 SkColor c = SkSwizzle_RB(value | 0xff000000);
423 return SkColor4f::FromColor(c);
424 }
425 case kBGRA_8888_SkColorType: {
426 uint32_t value = *this->addr32(x, y);
427 SkPMColor c = SkSwizzle_BGRA_to_PMColor(value);
428 return SkColor4f::FromColor(toColor(c));
429 }
430 case kRGBA_8888_SkColorType: {
431 uint32_t value = *this->addr32(x, y);
432 SkPMColor c = SkSwizzle_RGBA_to_PMColor(value);
433 return SkColor4f::FromColor(toColor(c));
434 }
435 case kSRGBA_8888_SkColorType: {
436 auto srgb_to_linear = [](float x) {
437 return (x <= 0.04045f) ? x * (1 / 12.92f)
438 : sk_float_pow(x * (1 / 1.055f) + (0.055f / 1.055f), 2.4f);
439 };
440
441 uint32_t value = *this->addr32(x, y);
442 float r = ((value >> 0) & 0xff) * (1 / 255.0f),
443 g = ((value >> 8) & 0xff) * (1 / 255.0f),
444 b = ((value >> 16) & 0xff) * (1 / 255.0f),
445 a = ((value >> 24) & 0xff) * (1 / 255.0f);
446 r = srgb_to_linear(r);
447 g = srgb_to_linear(g);
448 b = srgb_to_linear(b);
449 if (a != 0 && needsUnpremul) {
450 r = SkTPin(r / a, 0.0f, 1.0f);
451 g = SkTPin(g / a, 0.0f, 1.0f);
452 b = SkTPin(b / a, 0.0f, 1.0f);
453 }
454 return SkColor4f{r, g, b, a};
455 }
456 case kBGR_101010x_XR_SkColorType: {
457 SkASSERT(false);
458 return {};
459 }
460 case kRGB_101010x_SkColorType: {
461 uint32_t value = *this->addr32(x, y);
462 // Convert 10-bit rgb to float rgb, and mask in 0xff alpha at the top.
463 float r = (uint32_t)((value >> 0) & 0x3ff) / (1023.0f);
464 float g = (uint32_t)((value >> 10) & 0x3ff) / (1023.0f);
465 float b = (uint32_t)((value >> 20) & 0x3ff) / (1023.0f);
466 float a = 1.0f;
467 return SkColor4f{r, g, b, a};
468 }
469 case kBGR_101010x_SkColorType: {
470 uint32_t value = *this->addr32(x, y);
471 // Convert 10-bit bgr to float rgb, and mask in 0xff alpha at the top.
472 float r = (uint32_t)((value >> 20) & 0x3ff) / (1023.0f);
473 float g = (uint32_t)((value >> 10) & 0x3ff) / (1023.0f);
474 float b = (uint32_t)((value >> 0) & 0x3ff) / (1023.0f);
475 float a = 1.0f;
476 return SkColor4f{r, g, b, a};
477 }
478 case kRGBA_1010102_SkColorType:
479 case kBGRA_1010102_SkColorType: {
480 uint32_t value = *this->addr32(x, y);
481
482 float r = ((value >> 0) & 0x3ff) * (1 / 1023.0f),
483 g = ((value >> 10) & 0x3ff) * (1 / 1023.0f),
484 b = ((value >> 20) & 0x3ff) * (1 / 1023.0f),
485 a = ((value >> 30) & 0x3) * (1 / 3.0f);
486 if (this->colorType() == kBGRA_1010102_SkColorType) {
487 std::swap(r, b);
488 }
489 if (a != 0 && needsUnpremul) {
490 r = SkTPin(r / a, 0.0f, 1.0f);
491 g = SkTPin(g / a, 0.0f, 1.0f);
492 b = SkTPin(b / a, 0.0f, 1.0f);
493 }
494 return SkColor4f{r, g, b, a};
495 }
496 case kR16G16B16A16_unorm_SkColorType: {
497 uint64_t value = *this->addr64(x, y);
498
499 float r = ((value)&0xffff) * (1 / 65535.0f),
500 g = ((value >> 16) & 0xffff) * (1 / 65535.0f),
501 b = ((value >> 32) & 0xffff) * (1 / 65535.0f),
502 a = ((value >> 48) & 0xffff) * (1 / 65535.0f);
503 if (a != 0 && needsUnpremul) {
504 r *= (1.0f / a);
505 g *= (1.0f / a);
506 b *= (1.0f / a);
507 }
508 return SkColor4f{r, g, b, a};
509 }
510 case kRGBA_F16Norm_SkColorType:
511 case kRGBA_F16_SkColorType: {
512 const uint64_t* addr = (const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
513 skvx::float4 p4 = SkHalfToFloat_finite_ftz(*addr);
514 if (p4[3] && needsUnpremul) {
515 float inva = 1 / p4[3];
516 p4 = p4 * skvx::float4(inva, inva, inva, 1);
517 }
518 return SkColor4f{p4[0], p4[1], p4[2], p4[3]};
519 }
520 case kRGBA_F32_SkColorType: {
521 const float* rgba = (const float*)fPixels + 4 * y * (fRowBytes >> 4) + 4 * x;
522 skvx::float4 p4 = skvx::float4::Load(rgba);
523 // From here on, just like F16:
524 if (p4[3] && needsUnpremul) {
525 float inva = 1 / p4[3];
526 p4 = p4 * skvx::float4(inva, inva, inva, 1);
527 }
528 return SkColor4f{p4[0], p4[1], p4[2], p4[3]};
529 }
530 case kUnknown_SkColorType:
531 break;
532 }
533 SkDEBUGFAIL("");
534 return SkColors::kTransparent;
535 }
536
computeIsOpaque() const537 bool SkPixmap::computeIsOpaque() const {
538 const int height = this->height();
539 const int width = this->width();
540
541 switch (this->colorType()) {
542 case kAlpha_8_SkColorType: {
543 unsigned a = 0xFF;
544 for (int y = 0; y < height; ++y) {
545 const uint8_t* row = this->addr8(0, y);
546 for (int x = 0; x < width; ++x) {
547 a &= row[x];
548 }
549 if (0xFF != a) {
550 return false;
551 }
552 }
553 return true;
554 }
555 case kA16_unorm_SkColorType: {
556 unsigned a = 0xFFFF;
557 for (int y = 0; y < height; ++y) {
558 const uint16_t* row = this->addr16(0, y);
559 for (int x = 0; x < width; ++x) {
560 a &= row[x];
561 }
562 if (0xFFFF != a) {
563 return false;
564 }
565 }
566 return true;
567 }
568 case kA16_float_SkColorType: {
569 for (int y = 0; y < height; ++y) {
570 const SkHalf* row = this->addr16(0, y);
571 for (int x = 0; x < width; ++x) {
572 if (row[x] < SK_Half1) {
573 return false;
574 }
575 }
576 }
577 return true;
578 }
579 case kRGB_565_SkColorType:
580 case kGray_8_SkColorType:
581 case kR8G8_unorm_SkColorType:
582 case kR16G16_unorm_SkColorType:
583 case kR16G16_float_SkColorType:
584 case kRGB_888x_SkColorType:
585 case kRGB_101010x_SkColorType:
586 case kBGR_101010x_SkColorType:
587 case kBGR_101010x_XR_SkColorType:
588 case kR8_unorm_SkColorType:
589 return true;
590 case kARGB_4444_SkColorType: {
591 unsigned c = 0xFFFF;
592 for (int y = 0; y < height; ++y) {
593 const SkPMColor16* row = this->addr16(0, y);
594 for (int x = 0; x < width; ++x) {
595 c &= row[x];
596 }
597 if (0xF != SkGetPackedA4444(c)) {
598 return false;
599 }
600 }
601 return true;
602 }
603 case kBGRA_8888_SkColorType:
604 case kRGBA_8888_SkColorType:
605 case kSRGBA_8888_SkColorType: {
606 SkPMColor c = (SkPMColor)~0;
607 for (int y = 0; y < height; ++y) {
608 const SkPMColor* row = this->addr32(0, y);
609 for (int x = 0; x < width; ++x) {
610 c &= row[x];
611 }
612 if (0xFF != SkGetPackedA32(c)) {
613 return false;
614 }
615 }
616 return true;
617 }
618 case kRGBA_F16Norm_SkColorType:
619 case kRGBA_F16_SkColorType: {
620 const SkHalf* row = (const SkHalf*)this->addr();
621 for (int y = 0; y < height; ++y) {
622 for (int x = 0; x < width; ++x) {
623 if (row[4 * x + 3] < SK_Half1) {
624 return false;
625 }
626 }
627 row += this->rowBytes() >> 1;
628 }
629 return true;
630 }
631 case kRGBA_F32_SkColorType: {
632 const float* row = (const float*)this->addr();
633 for (int y = 0; y < height; ++y) {
634 for (int x = 0; x < width; ++x) {
635 if (row[4 * x + 3] < 1.0f) {
636 return false;
637 }
638 }
639 row += this->rowBytes() >> 2;
640 }
641 return true;
642 }
643 case kRGBA_1010102_SkColorType:
644 case kBGRA_1010102_SkColorType: {
645 uint32_t c = ~0;
646 for (int y = 0; y < height; ++y) {
647 const uint32_t* row = this->addr32(0, y);
648 for (int x = 0; x < width; ++x) {
649 c &= row[x];
650 }
651 if (0b11 != c >> 30) {
652 return false;
653 }
654 }
655 return true;
656 }
657 case kR16G16B16A16_unorm_SkColorType: {
658 uint16_t acc = 0xFFFF;
659 for (int y = 0; y < height; ++y) {
660 const uint64_t* row = this->addr64(0, y);
661 for (int x = 0; x < width; ++x) {
662 acc &= (row[x] >> 48);
663 }
664 if (0xFFFF != acc) {
665 return false;
666 }
667 }
668 return true;
669 }
670 case kUnknown_SkColorType:
671 SkDEBUGFAIL("");
672 break;
673 }
674 return false;
675 }
676