• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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