/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkPixmap.h"

#include "include/core/SkAlphaType.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkUnPreMultiply.h"
#include "include/private/SkFloatingPoint.h"
#include "include/private/SkTPin.h"
#include "src/core/SkColorData.h"
#include "src/core/SkColorPriv.h"
#include "src/core/SkConvertPixels.h"
#include "src/core/SkHalf.h"
#include "src/core/SkImageInfoPriv.h"
#include "src/core/SkMask.h"
#include "src/core/SkReadPixelsRec.h"
#include "src/core/SkSwizzlePriv.h"
#include "src/core/SkVx.h"
#include "src/opts/SkMemset_opts.h"

#include <array>
#include <cstdint>
#include <cstring>
#include <iterator>
#include <utility>

void SkPixmap::reset() {
    fPixels = nullptr;
    fRowBytes = 0;
    fInfo = SkImageInfo::MakeUnknown();
}

void SkPixmap::reset(const SkImageInfo& info, const void* addr, size_t rowBytes) {
    if (addr) {
        SkDEBUGCODE(info.validate());
        SkASSERT(info.validRowBytes(rowBytes));
    }
    fPixels = addr;
    fRowBytes = rowBytes;
    fInfo = info;
}

bool SkPixmap::reset(const SkMask& src) {
    if (SkMask::kA8_Format == src.fFormat) {
        this->reset(SkImageInfo::MakeA8(src.fBounds.width(), src.fBounds.height()),
                    src.fImage, src.fRowBytes);
        return true;
    }
    this->reset();
    return false;
}

void SkPixmap::setColorSpace(sk_sp<SkColorSpace> cs) {
    fInfo = fInfo.makeColorSpace(std::move(cs));
}

SkColorSpace* SkPixmap::colorSpace() const { return fInfo.colorSpace(); }

sk_sp<SkColorSpace> SkPixmap::refColorSpace() const { return fInfo.refColorSpace(); }

bool SkPixmap::extractSubset(SkPixmap* result, const SkIRect& subset) const {
    SkIRect srcRect, r;
    srcRect.setWH(this->width(), this->height());
    if (!r.intersect(srcRect, subset)) {
        return false;   // r is empty (i.e. no intersection)
    }

    // If the upper left of the rectangle was outside the bounds of this SkBitmap, we should have
    // exited above.
    SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width()));
    SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height()));

    const void* pixels = nullptr;
    if (fPixels) {
        const size_t bpp = fInfo.bytesPerPixel();
        pixels = (const uint8_t*)fPixels + r.fTop * fRowBytes + r.fLeft * bpp;
    }
    result->reset(fInfo.makeDimensions(r.size()), pixels, fRowBytes);
    return true;
}

// This is the same as SkPixmap::addr(x,y), but this version gets inlined, while the public
// method does not. Perhaps we could bloat it so it can be inlined, but that would grow code-size
// everywhere, instead of just here (on behalf of getAlphaf()).
static const void* fast_getaddr(const SkPixmap& pm, int x, int y) {
    x <<= SkColorTypeShiftPerPixel(pm.colorType());
    return static_cast<const char*>(pm.addr()) + y * pm.rowBytes() + x;
}

float SkPixmap::getAlphaf(int x, int y) const {
    SkASSERT(this->addr());
    SkASSERT((unsigned)x < (unsigned)this->width());
    SkASSERT((unsigned)y < (unsigned)this->height());

    float value = 0;
    const void* srcPtr = fast_getaddr(*this, x, y);

    switch (this->colorType()) {
        case kUnknown_SkColorType:
            return 0;
        case kGray_8_SkColorType:
        case kR8G8_unorm_SkColorType:
        case kR16_unorm_SkColorType:
        case kR16_float_SkColorType:
        case kR16G16_unorm_SkColorType:
        case kR16G16_float_SkColorType:
        case kRGB_565_SkColorType:
        case kRGB_888x_SkColorType:
        case kRGB_101010x_SkColorType:
        case kBGR_101010x_SkColorType:
        case kBGR_101010x_XR_SkColorType:
        case kRGB_F16F16F16x_SkColorType:
        case kR8_unorm_SkColorType:
            return 1;
        case kAlpha_8_SkColorType:
            value = static_cast<const uint8_t*>(srcPtr)[0] * (1.0f/255);
            break;
        case kA16_unorm_SkColorType:
            value = static_cast<const uint16_t*>(srcPtr)[0] * (1.0f/65535);
            break;
        case kA16_float_SkColorType: {
            SkHalf half = static_cast<const SkHalf*>(srcPtr)[0];
            value = SkHalfToFloat(half);
            break;
        }
        case kARGB_4444_SkColorType: {
            uint16_t u16 = static_cast<const uint16_t*>(srcPtr)[0];
            value = SkGetPackedA4444(u16) * (1.0f/15);
            break;
        }
        case kRGBA_8888_SkColorType:
        case kBGRA_8888_SkColorType:
        case kSRGBA_8888_SkColorType:
            value = static_cast<const uint8_t*>(srcPtr)[3] * (1.0f/255);
            break;
        case kRGBA_1010102_SkColorType:
        case kBGRA_1010102_SkColorType: {
            uint32_t u32 = static_cast<const uint32_t*>(srcPtr)[0];
            value = (u32 >> 30) * (1.0f/3);
            break;
        }
        case kBGRA_10101010_XR_SkColorType: {
            uint64_t u64 = static_cast<const uint64_t*>(srcPtr)[0];
            value = ((u64 >> 54) - 384) / 510.f;
            break;
        }
        case kRGBA_10x6_SkColorType: {
            uint64_t u64 = static_cast<const uint64_t*>(srcPtr)[0];
            value = (u64 >> 54) * (1.0f/1023);
            break;
        }
        case kR16G16B16A16_unorm_SkColorType: {
            uint64_t u64 = static_cast<const uint64_t*>(srcPtr)[0];
            value = (u64 >> 48) * (1.0f/65535);
            break;
        }
        case kRGBA_F16Norm_SkColorType:
        case kRGBA_F16_SkColorType: {
            value = from_half(skvx::half4::Load(srcPtr))[3];
            break;
        }
        case kRGBA_F32_SkColorType:
            value = static_cast<const float*>(srcPtr)[3];
            break;
    }
    return value;
}

bool SkPixmap::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
                          int x, int y) const {
    if (!SkImageInfoValidConversion(dstInfo, fInfo)) {
        return false;
    }

    SkReadPixelsRec rec(dstInfo, dstPixels, dstRB, x, y);
    if (!rec.trim(fInfo.width(), fInfo.height())) {
        return false;
    }

    const void* srcPixels = this->addr(rec.fX, rec.fY);
    const SkImageInfo srcInfo = fInfo.makeDimensions(rec.fInfo.dimensions());
    return SkConvertPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, srcInfo, srcPixels,
                           this->rowBytes());
}

SkColor SkPixmap::getColor(int x, int y) const {
    SkASSERT(this->addr());
    SkASSERT((unsigned)x < (unsigned)this->width());
    SkASSERT((unsigned)y < (unsigned)this->height());

    const bool needsUnpremul = (kPremul_SkAlphaType == fInfo.alphaType());
    auto toColor = [needsUnpremul](uint32_t maybePremulColor) {
        return needsUnpremul ? SkUnPreMultiply::PMColorToColor(maybePremulColor)
                             : SkSwizzle_BGRA_to_PMColor(maybePremulColor);
    };

    switch (this->colorType()) {
        case kGray_8_SkColorType: {
            uint8_t value = *this->addr8(x, y);
            return SkColorSetRGB(value, value, value);
        }
        case kR8_unorm_SkColorType: {
            return SkColorSetRGB(*this->addr8(x, y), 0, 0);
        }
        case kAlpha_8_SkColorType: {
            return SkColorSetA(0, *this->addr8(x, y));
        }
        case kA16_unorm_SkColorType: {
            return SkColorSetA(0, (*this->addr16(x, y)) * (255 / 65535.0f));
        }
        case kA16_float_SkColorType: {
            return SkColorSetA(0, 255 * SkHalfToFloat(*this->addr16(x, y)));
        }
        case kR16_float_SkColorType: {
            return SkColorSetRGB(255 * SkHalfToFloat(*this->addr16(x, y)), 0, 0);
        }
        case kRGB_565_SkColorType: {
            return SkPixel16ToColor(*this->addr16(x, y));
        }
        case kARGB_4444_SkColorType: {
            SkPMColor c = SkPixel4444ToPixel32(*this->addr16(x, y));
            return toColor(c);
        }
        case kR8G8_unorm_SkColorType: {
            uint16_t value = *this->addr16(x, y);
            return SkColorSetRGB((uint8_t)(value & 0xffff), (uint8_t)((value >> 8) & 0xffff), 0);
        }
        case kR16_unorm_SkColorType: {
            uint16_t value = *this->addr16(x, y);
            return SkColorSetRGB(value * (255 / 65535.0f), 0, 0);
        }
        case kR16G16_unorm_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            uint8_t r = ((value >>  0) & 0xffff) * (255.0f / 65535.0f),
                    g = ((value >> 16) & 0xffff) * (255.0f / 65535.0f);
            return SkColorSetRGB(r, g, 0);
        }
        case kR16G16_float_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            float r = SkHalfToFloat((uint16_t)(value >>  0) & 0xffff),
                  g = SkHalfToFloat((uint16_t)(value >> 16) & 0xffff);
            return SkColorSetRGB((uint8_t)(255 * r), (uint8_t)(255 * g), 0);
        }
        case kRGB_888x_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            return SkSwizzle_RB(value | 0xff000000);
        }
        case kBGRA_8888_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            return toColor(SkSwizzle_BGRA_to_PMColor(value));
        }
        case kRGBA_8888_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            return toColor(SkSwizzle_RGBA_to_PMColor(value));
        }
        case kSRGBA_8888_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            float r = ((value >>  0) & 0xff) * (1/255.0f),
                  g = ((value >>  8) & 0xff) * (1/255.0f),
                  b = ((value >> 16) & 0xff) * (1/255.0f),
                  a = ((value >> 24) & 0xff) * (1/255.0f);

            auto srgb_to_linear = [](float x) {
                return (x <= 0.04045f) ? x * (1 / 12.92f)
                                       : std::pow(x * (1 / 1.055f) + (0.055f / 1.055f), 2.4f);
            };
            r = srgb_to_linear(r);
            g = srgb_to_linear(g);
            b = srgb_to_linear(b);
            if (a != 0 && needsUnpremul) {
                r = SkTPin(r/a, 0.0f, 1.0f);
                g = SkTPin(g/a, 0.0f, 1.0f);
                b = SkTPin(b/a, 0.0f, 1.0f);
            }
            r *= 255.0f;
            g *= 255.0f;
            b *= 255.0f;
            a *= 255.0f;
            return SkColorSetARGB(a, r, g, b);
        }
        case kRGB_101010x_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            // Convert 10-bit rgb to 8-bit rgb
            return SkColorSetRGB(((value >>  0) & 0x3ff) * (255/1023.0f),
                                 ((value >> 10) & 0x3ff) * (255/1023.0f),
                                 ((value >> 20) & 0x3ff) * (255/1023.0f));
        }
        case kBGR_101010x_XR_SkColorType: {
            SkASSERT(false);
            return 0;
        }
        case kBGR_101010x_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            // Convert 10-bit bgr to 8-bit rgb
            return SkColorSetRGB(((value >> 20) & 0x3ff) * (255/1023.0f),
                                 ((value >> 10) & 0x3ff) * (255/1023.0f),
                                 ((value >>  0) & 0x3ff) * (255/1023.0f));
        }
        case kBGRA_1010102_SkColorType:
        case kRGBA_1010102_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            float r = ((value >>  0) & 0x3ff) * (1/1023.0f),
                  g = ((value >> 10) & 0x3ff) * (1/1023.0f),
                  b = ((value >> 20) & 0x3ff) * (1/1023.0f),
                  a = ((value >> 30) & 0x3  ) * (1/   3.0f);
            if (this->colorType() == kBGRA_1010102_SkColorType) {
                std::swap(r, b);
            }
            if (a != 0 && needsUnpremul) {
                r = SkTPin(r/a, 0.0f, 1.0f);
                g = SkTPin(g/a, 0.0f, 1.0f);
                b = SkTPin(b/a, 0.0f, 1.0f);
            }
            b *= 255.0f;
            g *= 255.0f;
            r *= 255.0f;
            a *= 255.0f;
            return SkColorSetARGB(a, r, g, b);
        }
        case kBGRA_10101010_XR_SkColorType: {
            SkASSERT(false);
            return 0;
        }
        case kRGBA_10x6_SkColorType: {
            uint64_t value = *this->addr64(x, y);
            return SkColorSetARGB(((value >> 54) & 0x3ff) * (255/1023.0f),
                                  ((value >>  6) & 0x3ff) * (255/1023.0f),
                                  ((value >> 22) & 0x3ff) * (255/1023.0f),
                                  ((value >> 38) & 0x3ff) * (255/1023.0f));
        }
        case kR16G16B16A16_unorm_SkColorType: {
            uint64_t value = *this->addr64(x, y);
            float r = ((value >>  0) & 0xffff) * (1/65535.0f),
                  g = ((value >> 16) & 0xffff) * (1/65535.0f),
                  b = ((value >> 32) & 0xffff) * (1/65535.0f),
                  a = ((value >> 48) & 0xffff) * (1/65535.0f);
            if (a != 0 && needsUnpremul) {
                r *= (1.0f/a);
                g *= (1.0f/a);
                b *= (1.0f/a);
            }
            r *= 255.0f;
            g *= 255.0f;
            b *= 255.0f;
            a *= 255.0f;
            return SkColorSetARGB(a, r, g, b);
        }
        case kRGB_F16F16F16x_SkColorType: {
            const uint64_t* addr =
                (const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
            skvx::float4 p4 = from_half(skvx::half4::Load(addr));
            p4[3] = 1.0f;
            // p4 is RGBA, but we want BGRA, so we need to swap next
            return Sk4f_toL32(swizzle_rb(p4));
        }
        case kRGBA_F16Norm_SkColorType:
        case kRGBA_F16_SkColorType: {
            const uint64_t* addr =
                (const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
            skvx::float4 p4 = from_half(skvx::half4::Load(addr));
            if (p4[3] && needsUnpremul) {
                float inva = 1 / p4[3];
                p4 = p4 * skvx::float4(inva, inva, inva, 1);
            }
            // p4 is RGBA, but we want BGRA, so we need to swap next
            return Sk4f_toL32(swizzle_rb(p4));
        }
        case kRGBA_F32_SkColorType: {
            const float* rgba =
                (const float*)fPixels + 4*y*(fRowBytes >> 4) + 4*x;
            skvx::float4 p4 = skvx::float4::Load(rgba);
            // From here on, just like F16:
            if (p4[3] && needsUnpremul) {
                float inva = 1 / p4[3];
                p4 = p4 * skvx::float4(inva, inva, inva, 1);
            }
            // p4 is RGBA, but we want BGRA, so we need to swap next
            return Sk4f_toL32(swizzle_rb(p4));
        }
        case kUnknown_SkColorType:
            break;
    }
    SkDEBUGFAIL("");
    return SkColorSetARGB(0, 0, 0, 0);
}

//////////////////////////////////////////////////////////////////////////////////////////////////

SkColor4f SkPixmap::getColor4f(int x, int y) const {
    SkASSERT(this->addr());
    SkASSERT((unsigned)x < (unsigned)this->width());
    SkASSERT((unsigned)y < (unsigned)this->height());

    const bool needsUnpremul = (kPremul_SkAlphaType == fInfo.alphaType());
    auto toColor = [needsUnpremul](uint32_t maybePremulColor) {
        return needsUnpremul ? SkUnPreMultiply::PMColorToColor(maybePremulColor)
                             : SkSwizzle_BGRA_to_PMColor(maybePremulColor);
    };

    switch (this->colorType()) {
        case kGray_8_SkColorType: {
            float value = *this->addr8(x, y) / 255.0f;
            return SkColor4f{value, value, value, 1.0f};
        }
        case kR8_unorm_SkColorType: {
            return SkColor4f{(*this->addr8(x, y) / 255.0f), 0.0f, 0.0f, 1.0f};
        }
        case kAlpha_8_SkColorType: {
            return SkColor4f{0.0f, 0.0f, 0.0f, (*this->addr8(x, y) / 255.0f)};
        }
        case kR16_unorm_SkColorType: {
            return SkColor4f{*this->addr16(x, y) / 65535.0f, 0.0f, 0.0f, 1.0f};
        }
        case kA16_unorm_SkColorType: {
            return SkColor4f{0.0f, 0.0f, 0.0f, (*this->addr16(x, y) / 65535.0f)};
        }
        case kR16_float_SkColorType: {
            return SkColor4f{SkHalfToFloat(*this->addr16(x, y)), 0.f, 0.f, 1.f};
        }
        case kA16_float_SkColorType: {
            return SkColor4f{0.0f, 0.0f, 0.0f, SkHalfToFloat(*this->addr16(x, y))};
        }
        case kRGB_565_SkColorType: {
            return SkColor4f::FromColor(SkPixel16ToColor(*this->addr16(x, y)));
        }
        case kARGB_4444_SkColorType: {
            SkPMColor c = SkPixel4444ToPixel32(*this->addr16(x, y));
            return SkColor4f::FromColor(toColor(c));
        }
        case kR8G8_unorm_SkColorType: {
            uint16_t value = *this->addr16(x, y);
            return SkColor4f::FromColor(SkColorSetRGB((uint8_t)(value), (uint8_t)(value >> 8), 0));
        }
        case kR16G16_unorm_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            float r = ((value >>  0) & 0xffff) * (1.0f / 65535.0f),
                  g = ((value >> 16) & 0xffff) * (1.0f / 65535.0f);
            return SkColor4f{r, g, 0.0, 1.0};
        }
        case kR16G16_float_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            float r = SkHalfToFloat((value >> 0 ) & 0xffff);
            float g = SkHalfToFloat((value >> 16) & 0xffff);
            return SkColor4f{r, g, 0.0, 1.0};
        }
        case kRGB_888x_SkColorType: {
            SkColor c = SkSwizzle_RB(*this->addr32(x, y) | 0xff000000);
            return SkColor4f::FromColor(c);
        }
        case kBGRA_8888_SkColorType: {
            SkPMColor c = SkSwizzle_BGRA_to_PMColor(*this->addr32(x, y));
            return SkColor4f::FromColor(toColor(c));
        }
        case kRGBA_8888_SkColorType: {
            SkPMColor c = SkSwizzle_RGBA_to_PMColor(*this->addr32(x, y));
            return SkColor4f::FromColor(toColor(c));
        }
        case kSRGBA_8888_SkColorType: {
            auto srgb_to_linear = [](float x) {
                return (x <= 0.04045f) ? x * (1 / 12.92f)
                                       : std::pow(x * (1 / 1.055f) + (0.055f / 1.055f), 2.4f);
            };

            uint32_t value = *this->addr32(x, y);
            float r = ((value >>  0) & 0xff) * (1 / 255.0f),
                  g = ((value >>  8) & 0xff) * (1 / 255.0f),
                  b = ((value >> 16) & 0xff) * (1 / 255.0f),
                  a = ((value >> 24) & 0xff) * (1 / 255.0f);
            r = srgb_to_linear(r);
            g = srgb_to_linear(g);
            b = srgb_to_linear(b);
            if (a != 0 && needsUnpremul) {
                r = SkTPin(r / a, 0.0f, 1.0f);
                g = SkTPin(g / a, 0.0f, 1.0f);
                b = SkTPin(b / a, 0.0f, 1.0f);
            }
            return SkColor4f{r, g, b, a};
        }
        case kBGR_101010x_XR_SkColorType: {
            SkASSERT(false);
            return {};
        }
        case kRGB_101010x_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            // Convert 10-bit RGB to floats
            return SkColor4f{((value >>  0) & 0x3ff) / (1023.0f),
                             ((value >> 10) & 0x3ff) / (1023.0f),
                             ((value >> 20) & 0x3ff) / (1023.0f),
                             1.0f};
        }
        case kBGR_101010x_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            // Convert 10-bit BGR color values to RGBA floats
            return SkColor4f{((value >> 20) & 0x3ff) / (1023.0f),
                             ((value >> 10) & 0x3ff) / (1023.0f),
                             ((value >>  0) & 0x3ff) / (1023.0f),
                             1.0f};
        }
        case kRGBA_1010102_SkColorType:
        case kBGRA_1010102_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            // Convert 10-bit color values to floats
            float b = ((value >>  0) & 0x3ff) * (1 / 1023.0f),
                  g = ((value >> 10) & 0x3ff) * (1 / 1023.0f),
                  r = ((value >> 20) & 0x3ff) * (1 / 1023.0f),
                  a = ((value >> 30) & 0x3  ) * (1 / 3.0f   );
            if (a != 0 && needsUnpremul) {
                r = SkTPin(r / a, 0.0f, 1.0f);
                g = SkTPin(g / a, 0.0f, 1.0f);
                b = SkTPin(b / a, 0.0f, 1.0f);
            }
            return SkColor4f{r, g, b, a};
        }
        case kBGRA_10101010_XR_SkColorType: {
            SkASSERT(false);
            return {};
        }
        case kRGBA_10x6_SkColorType: {
            uint64_t value = *this->addr64(x, y);
            return SkColor4f{((value >>  6) & 0x3ff) * (1/1023.0f),
                             ((value >> 22) & 0x3ff) * (1/1023.0f),
                             ((value >> 38) & 0x3ff) * (1/1023.0f),
                             ((value >> 54) & 0x3ff) * (1/1023.0f)};
        }
        case kR16G16B16A16_unorm_SkColorType: {
            uint64_t value = *this->addr64(x, y);

            float r = ((value >>  0) & 0xffff) * (1 / 65535.0f),
                  g = ((value >> 16) & 0xffff) * (1 / 65535.0f),
                  b = ((value >> 32) & 0xffff) * (1 / 65535.0f),
                  a = ((value >> 48) & 0xffff) * (1 / 65535.0f);
            if (a != 0 && needsUnpremul) {
                r *= (1.0f / a);
                g *= (1.0f / a);
                b *= (1.0f / a);
            }
            return SkColor4f{r, g, b, a};
        }
        case kRGBA_F16Norm_SkColorType:
        case kRGBA_F16_SkColorType: {
            const uint64_t* addr = (const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
            skvx::float4 p4 = from_half(skvx::half4::Load(addr));
            if (p4[3] && needsUnpremul) {
                float inva = 1 / p4[3];
                p4 = p4 * skvx::float4(inva, inva, inva, 1);
            }
            return SkColor4f{p4[0], p4[1], p4[2], p4[3]};
        }
        case kRGB_F16F16F16x_SkColorType: {
            const uint64_t* addr = (const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
            skvx::float4 p4 = from_half(skvx::half4::Load(addr));
            p4[3] = 1.0f;
            return SkColor4f{p4[0], p4[1], p4[2], p4[3]};
        }
        case kRGBA_F32_SkColorType: {
            const float* rgba = (const float*)fPixels + 4 * y * (fRowBytes >> 4) + 4 * x;
            skvx::float4 p4 = skvx::float4::Load(rgba);
            // From here on, just like F16:
            if (p4[3] && needsUnpremul) {
                float inva = 1 / p4[3];
                p4 = p4 * skvx::float4(inva, inva, inva, 1);
            }
            return SkColor4f{p4[0], p4[1], p4[2], p4[3]};
        }
        case kUnknown_SkColorType:
            break;
    }
    SkDEBUGFAIL("");
    return SkColors::kTransparent;
}

bool SkPixmap::computeIsOpaque() const {
    const int height = this->height();
    const int width = this->width();

    switch (this->colorType()) {
        case kAlpha_8_SkColorType: {
            unsigned a = 0xFF;
            for (int y = 0; y < height; ++y) {
                const uint8_t* row = this->addr8(0, y);
                for (int x = 0; x < width; ++x) {
                    a &= row[x];
                }
                if (0xFF != a) {
                    return false;
                }
            }
            return true;
        }
        case kA16_unorm_SkColorType: {
            unsigned a = 0xFFFF;
            for (int y = 0; y < height; ++y) {
                const uint16_t* row = this->addr16(0, y);
                for (int x = 0; x < width; ++x) {
                    a &= row[x];
                }
                if (0xFFFF != a) {
                    return false;
                }
            }
            return true;
        }
        case kA16_float_SkColorType: {
            for (int y = 0; y < height; ++y) {
                const SkHalf* row = this->addr16(0, y);
                for (int x = 0; x < width; ++x) {
                    if (row[x] < SK_Half1) {
                        return false;
                    }
                }
            }
            return true;
        }
        case kRGB_565_SkColorType:
        case kGray_8_SkColorType:
        case kR8G8_unorm_SkColorType:
        case kR16_unorm_SkColorType:
        case kR16_float_SkColorType:
        case kR16G16_unorm_SkColorType:
        case kR16G16_float_SkColorType:
        case kRGB_888x_SkColorType:
        case kRGB_101010x_SkColorType:
        case kBGR_101010x_SkColorType:
        case kRGB_F16F16F16x_SkColorType:
        case kBGR_101010x_XR_SkColorType:
        case kR8_unorm_SkColorType:
            return true;
        case kARGB_4444_SkColorType: {
            unsigned c = 0xFFFF;
            for (int y = 0; y < height; ++y) {
                const SkPMColor16* row = this->addr16(0, y);
                for (int x = 0; x < width; ++x) {
                    c &= row[x];
                }
                if (0xF != SkGetPackedA4444(c)) {
                    return false;
                }
            }
            return true;
        }
        case kBGRA_8888_SkColorType:
        case kRGBA_8888_SkColorType:
        case kSRGBA_8888_SkColorType: {
            SkPMColor c = (SkPMColor)~0;
            for (int y = 0; y < height; ++y) {
                const SkPMColor* row = this->addr32(0, y);
                for (int x = 0; x < width; ++x) {
                    c &= row[x];
                }
                if (0xFF != SkGetPackedA32(c)) {
                    return false;
                }
            }
            return true;
        }
        case kRGBA_F16Norm_SkColorType:
        case kRGBA_F16_SkColorType: {
            const SkHalf* row = (const SkHalf*)this->addr();
            for (int y = 0; y < height; ++y) {
                for (int x = 0; x < width; ++x) {
                    if (row[4 * x + 3] < SK_Half1) {
                        return false;
                    }
                }
                row += this->rowBytes() >> 1;
            }
            return true;
        }
        case kRGBA_F32_SkColorType: {
            const float* row = (const float*)this->addr();
            for (int y = 0; y < height; ++y) {
                for (int x = 0; x < width; ++x) {
                    if (row[4 * x + 3] < 1.0f) {
                        return false;
                    }
                }
                row += this->rowBytes() >> 2;
            }
            return true;
        }
        case kRGBA_1010102_SkColorType:
        case kBGRA_1010102_SkColorType: {
            uint32_t c = ~0;
            for (int y = 0; y < height; ++y) {
                const uint32_t* row = this->addr32(0, y);
                for (int x = 0; x < width; ++x) {
                    c &= row[x];
                }
                if (0b11 != c >> 30) {
                    return false;
                }
            }
            return true;
        }
        case kBGRA_10101010_XR_SkColorType:{
            static constexpr uint64_t kOne = 510 + 384;
            for (int y = 0; y < height; ++y) {
                const uint64_t* row = this->addr64(0, y);
                for (int x = 0; x < width; ++x) {
                    if ((row[x] >> 54) < kOne) {
                        return false;
                    }
                }
            }
            return true;
        }
        case kRGBA_10x6_SkColorType: {
            uint16_t acc = 0xFFC0;  // Ignore bottom six bits
            for (int y = 0; y < height; ++y) {
                const uint64_t* row = this->addr64(0, y);
                for (int x = 0; x < width; ++x) {
                    acc &= (row[x] >> 48);
                }
                if (0xFFC0 != acc) {
                    return false;
                }
            }
            return true;
        }
        case kR16G16B16A16_unorm_SkColorType: {
            uint16_t acc = 0xFFFF;
            for (int y = 0; y < height; ++y) {
                const uint64_t* row = this->addr64(0, y);
                for (int x = 0; x < width; ++x) {
                    acc &= (row[x] >> 48);
                }
                if (0xFFFF != acc) {
                    return false;
                }
            }
            return true;
        }
        case kUnknown_SkColorType:
            SkDEBUGFAIL("");
            break;
    }
    return false;
}

bool SkPixmap::erase(SkColor color, const SkIRect& subset) const {
    return this->erase(SkColor4f::FromColor(color), &subset);
}

bool SkPixmap::erase(const SkColor4f& color, const SkIRect* subset) const {
    if (this->colorType() == kUnknown_SkColorType) {
        return false;
    }

    const SkIRect thisBounds = this->bounds();
    SkIRect clip = thisBounds;
    if (subset && !clip.intersect(*subset)) {
        return false;   // is this check really needed (i.e. to return false in this case?)
    }
    SkASSERT_RELEASE(!clip.isEmpty());
    SkASSERTF_RELEASE(thisBounds.contains(clip),
                      "clip bounds: [%d, %d, %d, %d], this bounds: [%d, %d, %d, %d]",
                      clip.fLeft, clip.fTop, clip.fRight, clip.fBottom,
                      thisBounds.fLeft, thisBounds.fTop, thisBounds.fRight, thisBounds.fBottom);

    // Erase is meant to simulate drawing in kSRC mode -- which means we have to convert out
    // unpremul input into premul (which we always do when we draw).
    const auto c = color.premul();

    const auto dst = SkImageInfo::Make(1, 1, this->colorType(), this->alphaType(),
                                       sk_ref_sp(this->colorSpace()));
    const auto src = SkImageInfo::Make(1, 1, kRGBA_F32_SkColorType, kPremul_SkAlphaType, nullptr);

    uint64_t dstPixel[2] = {};   // be large enough for our widest config (F32 x 4)
    SkASSERT((size_t)dst.bytesPerPixel() <= sizeof(dstPixel));

    if (!SkConvertPixels(dst, dstPixel, sizeof(dstPixel), src, &c, sizeof(c))) {
        return false;
    }

    if (this->colorType() == kRGBA_F32_SkColorType) {
        SkColor4f dstColor;
        memcpy(&dstColor, dstPixel, sizeof(dstColor));
        for (int y = clip.fTop; y < clip.fBottom; ++y) {
            SkColor4f* addr = (SkColor4f*)this->writable_addr(clip.fLeft, y);
            SK_OPTS_NS::memsetT(addr, dstColor, clip.width());
        }
    } else {
        using MemSet = void(*)(void*, uint64_t c, int count);
        static constexpr auto procs = std::to_array<MemSet>({
            MemSet([](void* addr, uint64_t c, int count) {
                SkASSERT(c == (uint8_t)c);
                SK_OPTS_NS::memsetT((uint8_t*)addr, (uint8_t)c, count);
            }),
            MemSet([](void* addr, uint64_t c, int count) {
                SkASSERT(c == (uint16_t)c);
                SK_OPTS_NS::memsetT((uint16_t*)addr, (uint16_t)c, count);
            }),
            MemSet([](void* addr, uint64_t c, int count) {
                SkASSERT(c == (uint32_t)c);
                SK_OPTS_NS::memsetT((uint32_t*)addr, (uint32_t)c, count);
            }),
            MemSet([](void* addr, uint64_t c, int count) {
                SK_OPTS_NS::memsetT((uint64_t*)addr, c, count);
            }),
        });

        unsigned shift = SkColorTypeShiftPerPixel(this->colorType());
        SkASSERT(shift < std::size(procs));
        auto proc = procs[shift];

        for (int y = clip.fTop; y < clip.fBottom; ++y) {
            proc(this->writable_addr(clip.fLeft, y), dstPixel[0], clip.width());
        }
    }
    return true;
}
