/*
 * 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/SkBitmap.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkData.h"
#include "include/core/SkSurface.h"
#include "include/core/SkUnPreMultiply.h"
#include "include/private/SkColorData.h"
#include "include/private/SkHalf.h"
#include "include/private/SkTPin.h"
#include "include/private/SkTemplates.h"
#include "include/private/SkVx.h"
#include "include/private/base/SkTo.h"
#include "src/core/SkConvertPixels.h"
#include "src/core/SkDraw.h"
#include "src/core/SkImageInfoPriv.h"
#include "src/core/SkMask.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkPixmapPriv.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkUtils.h"
#include "src/image/SkReadPixelsRec.h"
#include "src/shaders/SkImageShader.h"

#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) {
        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 kR16G16_unorm_SkColorType:
        case kR16G16_float_SkColorType:
        case kRGB_565_SkColorType:
        case kRGB_888x_SkColorType:
        case kRGB_101010x_SkColorType:
        case kBGR_101010x_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 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: {
            uint64_t px;
            memcpy(&px, srcPtr, sizeof(px));
            value = SkHalfToFloat_finite_ftz(px)[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());
}

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

bool SkPixmap::erase(const SkColor4f& color, SkColorSpace* cs, const SkIRect* subset) const {
    SkPaint paint;
    paint.setBlendMode(SkBlendMode::kSrc);
    paint.setColor4f(color, cs);

    SkIRect clip = this->bounds();
    if (subset && !clip.intersect(*subset)) {
        return false;
    }
    SkRasterClip rc{clip};

    SkDraw draw;
    SkMatrixProvider matrixProvider(SkMatrix::I());
    draw.fDst            = *this;
    draw.fMatrixProvider = &matrixProvider;
    draw.fRC             = &rc;

    draw.drawPaint(paint);
    return true;
}

bool SkPixmap::scalePixels(const SkPixmap& actualDst, const SkSamplingOptions& sampling) const {
    // We may need to tweak how we interpret these just a little below, so we make copies.
    SkPixmap src = *this,
             dst = actualDst;

    // Can't do anthing with empty src or dst
    if (src.width() <= 0 || src.height() <= 0 ||
        dst.width() <= 0 || dst.height() <= 0) {
        return false;
    }

    // no scaling involved?
    if (src.width() == dst.width() && src.height() == dst.height()) {
        return src.readPixels(dst);
    }

    // If src and dst are both unpremul, we'll fake the source out to appear as if premul,
    // and mark the destination as opaque.  This odd combination allows us to scale unpremul
    // pixels without ever premultiplying them (perhaps losing information in the color channels).
    // This is an idiosyncratic feature of scalePixels(), and is tested by scalepixels_unpremul GM.
    bool clampAsIfUnpremul = false;
    if (src.alphaType() == kUnpremul_SkAlphaType &&
        dst.alphaType() == kUnpremul_SkAlphaType) {
        src.reset(src.info().makeAlphaType(kPremul_SkAlphaType), src.addr(), src.rowBytes());
        dst.reset(dst.info().makeAlphaType(kOpaque_SkAlphaType), dst.addr(), dst.rowBytes());

        // We'll need to tell the image shader to clamp to [0,1] instead of the
        // usual [0,a] when using a bicubic scaling (kHigh_SkFilterQuality).
        clampAsIfUnpremul = true;
    }

    SkBitmap bitmap;
    if (!bitmap.installPixels(src)) {
        return false;
    }
    bitmap.setImmutable();        // Don't copy when we create an image.

    SkMatrix scale = SkMatrix::RectToRect(SkRect::Make(src.bounds()), SkRect::Make(dst.bounds()));

    sk_sp<SkShader> shader = SkImageShader::Make(bitmap.asImage(),
                                                 SkTileMode::kClamp,
                                                 SkTileMode::kClamp,
                                                 sampling,
                                                 &scale,
                                                 clampAsIfUnpremul);

    sk_sp<SkSurface> surface = SkSurface::MakeRasterDirect(dst.info(),
                                                           dst.writable_addr(),
                                                           dst.rowBytes());
    if (!shader || !surface) {
        return false;
    }

    SkPaint paint;
    paint.setBlendMode(SkBlendMode::kSrc);
    paint.setShader(std::move(shader));
    surface->getCanvas()->drawPaint(paint);
    return true;
}

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

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: {
            uint8_t value = *this->addr8(x, y);
            return SkColorSetRGB(value, 0, 0);
        }
        case kAlpha_8_SkColorType: {
            return SkColorSetA(0, *this->addr8(x, y));
        }
        case kA16_unorm_SkColorType: {
            uint16_t value = *this->addr16(x, y);
            return SkColorSetA(0, value * (255 / 65535.0f));
        }
        case kA16_float_SkColorType: {
            SkHalf value = *this->addr16(x, y);
            return SkColorSetA(0, 255 * SkHalfToFloat(value));
        }
        case kRGB_565_SkColorType: {
            return SkPixel16ToColor(*this->addr16(x, y));
        }
        case kARGB_4444_SkColorType: {
            uint16_t value = *this->addr16(x, y);
            SkPMColor c = SkPixel4444ToPixel32(value);
            return toColor(c);
        }
        case kR8G8_unorm_SkColorType: {
            uint16_t value = *this->addr16(x, y);
            return (uint32_t)( ((value >>  0) & 0xff) ) << 16
                 | (uint32_t)( ((value >>  8) & 0xff) ) <<  8
                 | 0xff000000;
        }
        case kR16G16_unorm_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            return (uint32_t)( ((value >>  0) & 0xffff) * (255/65535.0f) ) << 16
                 | (uint32_t)( ((value >> 16) & 0xffff) * (255/65535.0f) ) <<  8
                 | 0xff000000;
        }
        case kR16G16_float_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            uint32_t r = 255 * SkHalfToFloat((value >>  0) & 0xffff);
            uint32_t g = 255 * SkHalfToFloat((value >> 16) & 0xffff);
            return (r << 16) | (g << 8) | 0xff000000;
        }
        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);
            SkPMColor c = SkSwizzle_BGRA_to_PMColor(value);
            return toColor(c);
        }
        case kRGBA_8888_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            SkPMColor c = SkSwizzle_RGBA_to_PMColor(value);
            return toColor(c);
        }
        case kSRGBA_8888_SkColorType: {
            auto srgb_to_linear = [](float x) {
                return (x <= 0.04045f) ? x * (1 / 12.92f)
                                       : sk_float_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 (uint32_t)( r * 255.0f ) << 16
                 | (uint32_t)( g * 255.0f ) <<  8
                 | (uint32_t)( b * 255.0f ) <<  0
                 | (uint32_t)( a * 255.0f ) << 24;
        }
        case kRGB_101010x_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            // Convert 10-bit rgb to 8-bit bgr, and mask in 0xff alpha at the top.
            return (uint32_t)( ((value >>  0) & 0x3ff) * (255/1023.0f) ) << 16
                 | (uint32_t)( ((value >> 10) & 0x3ff) * (255/1023.0f) ) <<  8
                 | (uint32_t)( ((value >> 20) & 0x3ff) * (255/1023.0f) ) <<  0
                 | 0xff000000;
        }
        case kBGR_101010x_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            // Convert 10-bit bgr to 8-bit bgr, and mask in 0xff alpha at the top.
            return (uint32_t)( ((value >>  0) & 0x3ff) * (255/1023.0f) ) <<  0
                 | (uint32_t)( ((value >> 10) & 0x3ff) * (255/1023.0f) ) <<  8
                 | (uint32_t)( ((value >> 20) & 0x3ff) * (255/1023.0f) ) << 16
                 | 0xff000000;
        }
        case kRGBA_1010102_SkColorType:
        case kBGRA_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);
            }
            return (uint32_t)( r * 255.0f ) << 16
                 | (uint32_t)( g * 255.0f ) <<  8
                 | (uint32_t)( b * 255.0f ) <<  0
                 | (uint32_t)( a * 255.0f ) << 24;
        }
        case kR16G16B16A16_unorm_SkColorType: {
            uint64_t value = *this->addr64(x, y);

            float r = ((value      ) & 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 (uint32_t)( r * 255.0f ) << 16
                 | (uint32_t)( g * 255.0f ) <<  8
                 | (uint32_t)( b * 255.0f ) <<  0
                 | (uint32_t)( a * 255.0f ) << 24;
        }
        case kRGBA_F16Norm_SkColorType:
        case kRGBA_F16_SkColorType: {
            const uint64_t* addr =
                (const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
            skvx::float4 p4 = SkHalfToFloat_finite_ftz(*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.0};
        }
        case kR8_unorm_SkColorType: {
            float value = *this->addr8(x, y) / 255.0f;
            return SkColor4f{value, 0.0f, 0.0f, 1.0f};
        }
        case kAlpha_8_SkColorType: {
            float value = *this->addr8(x, y) / 255.0f;
            return SkColor4f{0.0f, 0.0f, 0.0f, value};
        }
        case kA16_unorm_SkColorType: {
            float value = *this->addr16(x, y) / 65535.0f;
            return SkColor4f{0.0f, 0.0f, 0.0f, value};
        }
        case kA16_float_SkColorType: {
            SkHalf value = *this->addr16(x, y);
            return SkColor4f{0.0f, 0.0f, 0.0f, SkHalfToFloat(value)};
        }
        case kRGB_565_SkColorType: {
            SkColor c = SkPixel16ToColor(*this->addr16(x, y));
            return SkColor4f::FromColor(c);
        }
        case kARGB_4444_SkColorType: {
            uint16_t value = *this->addr16(x, y);
            SkPMColor c = SkPixel4444ToPixel32(value);
            return SkColor4f::FromColor(toColor(c));
        }
        case kR8G8_unorm_SkColorType: {
            uint16_t value = *this->addr16(x, y);
            SkColor c = (uint32_t)(((value >> 0) & 0xff)) << 16 |
                        (uint32_t)(((value >> 8) & 0xff)) << 8 | 0xff000000;
            return SkColor4f::FromColor(c);
        }
        case kR16G16_unorm_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            SkColor c = (uint32_t)(((value >> 0) & 0xffff) * (255 / 65535.0f)) << 16 |
                        (uint32_t)(((value >> 16) & 0xffff) * (255 / 65535.0f)) << 8 | 0xff000000;
            return SkColor4f::FromColor(c);
        }
        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: {
            uint32_t value = *this->addr32(x, y);
            SkColor c = SkSwizzle_RB(value | 0xff000000);
            return SkColor4f::FromColor(c);
        }
        case kBGRA_8888_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            SkPMColor c = SkSwizzle_BGRA_to_PMColor(value);
            return SkColor4f::FromColor(toColor(c));
        }
        case kRGBA_8888_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            SkPMColor c = SkSwizzle_RGBA_to_PMColor(value);
            return SkColor4f::FromColor(toColor(c));
        }
        case kSRGBA_8888_SkColorType: {
            auto srgb_to_linear = [](float x) {
                return (x <= 0.04045f) ? x * (1 / 12.92f)
                                       : sk_float_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 kRGB_101010x_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            // Convert 10-bit rgb to float rgb, and mask in 0xff alpha at the top.
            float r = (uint32_t)((value >> 0) & 0x3ff) / (1023.0f);
            float g = (uint32_t)((value >> 10) & 0x3ff) / (1023.0f);
            float b = (uint32_t)((value >> 20) & 0x3ff) / (1023.0f);
            float a = 1.0f;
            return SkColor4f{r, g, b, a};
        }
        case kBGR_101010x_SkColorType: {
            uint32_t value = *this->addr32(x, y);
            // Convert 10-bit bgr to float rgb, and mask in 0xff alpha at the top.
            float r = (uint32_t)((value >> 20) & 0x3ff) / (1023.0f);
            float g = (uint32_t)((value >> 10) & 0x3ff) / (1023.0f);
            float b = (uint32_t)((value >> 0) & 0x3ff) / (1023.0f);
            float a = 1.0f;
            return SkColor4f{r, g, b, a};
        }
        case kRGBA_1010102_SkColorType:
        case kBGRA_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);
            }
            return SkColor4f{r, g, b, a};
        }
        case kR16G16B16A16_unorm_SkColorType: {
            uint64_t value = *this->addr64(x, y);

            float r = ((value)&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 = SkHalfToFloat_finite_ftz(*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 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 kR16G16_unorm_SkColorType:
        case kR16G16_float_SkColorType:
        case kRGB_888x_SkColorType:
        case kRGB_101010x_SkColorType:
        case kBGR_101010x_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 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;
}

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

static bool draw_orientation(const SkPixmap& dst, const SkPixmap& src, SkEncodedOrigin origin) {
    auto surf = SkSurface::MakeRasterDirect(dst.info(), dst.writable_addr(), dst.rowBytes());
    if (!surf) {
        return false;
    }

    SkBitmap bm;
    bm.installPixels(src);

    SkMatrix m = SkEncodedOriginToMatrix(origin, dst.width(), dst.height());

    SkPaint p;
    p.setBlendMode(SkBlendMode::kSrc);
    surf->getCanvas()->concat(m);
    surf->getCanvas()->drawImage(SkImage::MakeFromBitmap(bm), 0, 0, SkSamplingOptions(), &p);
    return true;
}

bool SkPixmapPriv::Orient(const SkPixmap& dst, const SkPixmap& src, SkEncodedOrigin origin) {
    if (src.colorType() != dst.colorType()) {
        return false;
    }
    // note: we just ignore alphaType and colorSpace for this transformation

    int w = src.width();
    int h = src.height();
    if (SkEncodedOriginSwapsWidthHeight(origin)) {
        using std::swap;
        swap(w, h);
    }
    if (dst.width() != w || dst.height() != h) {
        return false;
    }
    if (w == 0 || h == 0) {
        return true;
    }

    // check for aliasing to self
    if (src.addr() == dst.addr()) {
        return kTopLeft_SkEncodedOrigin == origin;
    }
    return draw_orientation(dst, src, origin);
}

SkImageInfo SkPixmapPriv::SwapWidthHeight(const SkImageInfo& info) {
    return info.makeWH(info.height(), info.width());
}
