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

#include "SkAutoMalloc.h"
#include "SkColorSpace.h"
#include "SkColorSpacePriv.h"
#include "SkColorSpace_A2B.h"
#include "SkColorSpace_XYZ.h"
#include "SkEndian.h"
#include "SkFixed.h"
#include "SkICCPriv.h"
#include "SkTemplates.h"
#include "../../third_party/skcms/skcms.h"

#define return_if_false(pred, msg)                                   \
    do {                                                             \
        if (!(pred)) {                                               \
            SkColorSpacePrintf("Invalid ICC Profile: %s.\n", (msg)); \
            return false;                                            \
        }                                                            \
    } while (0)

#define return_null(msg)                                             \
    do {                                                             \
        SkColorSpacePrintf("Invalid ICC Profile: %s.\n", (msg));     \
        return nullptr;                                              \
    } while (0)

static uint16_t read_big_endian_u16(const uint8_t* ptr) {
    return ptr[0] << 8 | ptr[1];
}

static uint32_t read_big_endian_u32(const uint8_t* ptr) {
    return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
}

static int32_t read_big_endian_i32(const uint8_t* ptr) {
    return (int32_t) read_big_endian_u32(ptr);
}

static constexpr float kWhitePointD50[] = { 0.96420f, 1.00000f, 0.82491f, };

struct ICCProfileHeader {
    uint32_t fSize;

    // No reason to care about the preferred color management module (ex: Adobe, Apple, etc.).
    // We're always going to use this one.
    uint32_t fCMMType_ignored;

    uint32_t fVersion;
    uint32_t fProfileClass;
    uint32_t fInputColorSpace;
    uint32_t fPCS;
    uint32_t fDateTime_ignored[3];
    uint32_t fSignature;

    // Indicates the platform that this profile was created for (ex: Apple, Microsoft).  This
    // doesn't really matter to us.
    uint32_t fPlatformTarget_ignored;

    // Flags can indicate:
    // (1) Whether this profile was embedded in a file.  This flag is consistently wrong.
    //     Ex: The profile came from a file but indicates that it did not.
    // (2) Whether we are allowed to use the profile independently of the color data.  If set,
    //     this may allow us to use the embedded profile for testing separate from the original
    //     image.
    uint32_t fFlags_ignored;

    // We support many output devices.  It doesn't make sense to think about the attributes of
    // the device in the context of the image profile.
    uint32_t fDeviceManufacturer_ignored;
    uint32_t fDeviceModel_ignored;
    uint32_t fDeviceAttributes_ignored[2];

    uint32_t fRenderingIntent;
    int32_t  fIlluminantXYZ[3];

    // We don't care who created the profile.
    uint32_t fCreator_ignored;

    // This is an MD5 checksum.  Could be useful for checking if profiles are equal.
    uint32_t fProfileId_ignored[4];

    // Reserved for future use.
    uint32_t fReserved_ignored[7];

    uint32_t fTagCount;

    void init(const uint8_t* src, size_t len) {
        SkASSERT(kICCHeaderSize == sizeof(*this));

        uint32_t* dst = (uint32_t*) this;
        for (uint32_t i = 0; i < kICCHeaderSize / 4; i++, src+=4) {
            dst[i] = read_big_endian_u32(src);
        }
    }

    bool valid() const {
        return_if_false(fSize >= kICCHeaderSize, "Size is too small");

        uint8_t majorVersion = fVersion >> 24;
        return_if_false(majorVersion <= 4, "Unsupported version");

        // These are the four basic classes of profiles that we might expect to see embedded
        // in images.  Additional classes exist, but they generally are used as a convenient
        // way for CMMs to store calculated transforms.
        return_if_false(fProfileClass == kDisplay_Profile ||
                        fProfileClass == kInput_Profile ||
                        fProfileClass == kOutput_Profile ||
                        fProfileClass == kColorSpace_Profile,
                        "Unsupported profile");

        switch (fInputColorSpace) {
            case kRGB_ColorSpace:
                SkColorSpacePrintf("RGB Input Color Space");
                break;
            case kCMYK_ColorSpace:
                SkColorSpacePrintf("CMYK Input Color Space\n");
                break;
            case kGray_ColorSpace:
                SkColorSpacePrintf("Gray Input Color Space\n");
                break;
            default:
                SkColorSpacePrintf("Unsupported Input Color Space: %c%c%c%c\n",
                                   (fInputColorSpace>>24)&0xFF, (fInputColorSpace>>16)&0xFF,
                                   (fInputColorSpace>> 8)&0xFF, (fInputColorSpace>> 0)&0xFF);
                return false;
        }

        switch (fPCS) {
            case kXYZ_PCSSpace:
                SkColorSpacePrintf("XYZ PCS\n");
                break;
            case kLAB_PCSSpace:
                SkColorSpacePrintf("Lab PCS\n");
                break;
            default:
                // ICC currently (V4.3) only specifices XYZ and Lab PCS spaces
                SkColorSpacePrintf("Unsupported PCS space: %c%c%c%c\n",
                                   (fPCS>>24)&0xFF, (fPCS>>16)&0xFF,
                                   (fPCS>> 8)&0xFF, (fPCS>> 0)&0xFF);
                return false;
        }

        return_if_false(fSignature == kACSP_Signature, "Bad signature");

        // TODO (msarett):
        // Should we treat different rendering intents differently?
        // Valid rendering intents include kPerceptual (0), kRelative (1),
        // kSaturation (2), and kAbsolute (3).
        if (fRenderingIntent > 3) {
            // Warn rather than fail here.  Occasionally, we see perfectly
            // normal profiles with wacky rendering intents.
            SkColorSpacePrintf("Warning, bad rendering intent.\n");
        }

        return_if_false(
                color_space_almost_equal(SkFixedToFloat(fIlluminantXYZ[0]), kWhitePointD50[0]) &&
                color_space_almost_equal(SkFixedToFloat(fIlluminantXYZ[1]), kWhitePointD50[1]) &&
                color_space_almost_equal(SkFixedToFloat(fIlluminantXYZ[2]), kWhitePointD50[2]),
                "Illuminant must be D50");

        return_if_false(fTagCount <= 100, "Too many tags");

        return true;
    }
};

template <class T>
static bool safe_add(T arg1, T arg2, size_t* result) {
    SkASSERT(arg1 >= 0);
    SkASSERT(arg2 >= 0);
    if (arg1 >= 0 && arg2 <= std::numeric_limits<T>::max() - arg1) {
        T sum = arg1 + arg2;
        if (sum <= std::numeric_limits<size_t>::max()) {
            *result = static_cast<size_t>(sum);
            return true;
        }
    }
    return false;
}

static bool safe_mul(uint32_t arg1, uint32_t arg2, uint32_t* result) {
    uint64_t product64 = (uint64_t) arg1 * (uint64_t) arg2;
    uint32_t product32 = (uint32_t) product64;
    if (product32 != product64) {
        return false;
    }

    *result = product32;
    return true;
}

struct ICCTag {
    uint32_t fSignature;
    uint32_t fOffset;
    uint32_t fLength;

    const uint8_t* init(const uint8_t* src) {
        fSignature = read_big_endian_u32(src);
        fOffset = read_big_endian_u32(src + 4);
        fLength = read_big_endian_u32(src + 8);
        return src + 12;
    }

    bool valid(size_t len) {
        size_t tagEnd;
        return_if_false(safe_add(fOffset, fLength, &tagEnd),
                        "Tag too large, overflows integer addition");
        return_if_false(tagEnd <= len, "Tag too large for ICC profile");
        return true;
    }

    const uint8_t* addr(const uint8_t* src) const {
        return src + fOffset;
    }

    static const ICCTag* Find(const ICCTag tags[], int count, uint32_t signature) {
        for (int i = 0; i < count; ++i) {
            if (tags[i].fSignature == signature) {
                return &tags[i];
            }
        }
        return nullptr;
    }
};

static bool load_xyz(float dst[3], const uint8_t* src, size_t len) {
    if (len < 20) {
        SkColorSpacePrintf("XYZ tag is too small (%d bytes)", len);
        return false;
    }

    dst[0] = SkFixedToFloat(read_big_endian_i32(src + 8));
    dst[1] = SkFixedToFloat(read_big_endian_i32(src + 12));
    dst[2] = SkFixedToFloat(read_big_endian_i32(src + 16));
    SkColorSpacePrintf("XYZ %g %g %g\n", dst[0], dst[1], dst[2]);
    return true;
}

static SkGammas::Type set_gamma_value(SkGammas::Data* data, float value) {
    if (color_space_almost_equal(2.2f, value)) {
        data->fNamed = k2Dot2Curve_SkGammaNamed;
        return SkGammas::Type::kNamed_Type;
    }

    if (color_space_almost_equal(1.0f, value)) {
        data->fNamed = kLinear_SkGammaNamed;
        return SkGammas::Type::kNamed_Type;
    }

    if (color_space_almost_equal(0.0f, value)) {
        return SkGammas::Type::kNone_Type;
    }

    data->fValue = value;
    return SkGammas::Type::kValue_Type;
}

static float read_big_endian_16_dot_16(const uint8_t buf[4]) {
    // It just so happens that SkFixed is also 16.16!
    return SkFixedToFloat(read_big_endian_i32(buf));
}

/**
 *  @param outData     Set to the appropriate value on success.  If we have table or
 *                     parametric gamma, it is the responsibility of the caller to set
 *                     fOffset.
 *  @param outParams   If this is a parametric gamma, this is set to the appropriate
 *                     parameters on success.
 *  @param outTagBytes Will be set to the length of the tag on success.
 *  @src               Pointer to tag data.
 *  @len               Length of tag data in bytes.
 *
 *  @return            kNone_Type on failure, otherwise the type of the gamma tag.
 */
static SkGammas::Type parse_gamma(SkGammas::Data* outData, SkColorSpaceTransferFn* outParams,
                                  size_t* outTagBytes, const uint8_t* src, size_t len) {
    if (len < 12) {
        SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
        return SkGammas::Type::kNone_Type;
    }

    // In the case of consecutive gamma tags, we need to count the number of bytes in the
    // tag, so that we can move on to the next tag.
    size_t tagBytes;

    uint32_t type = read_big_endian_u32(src);
    // Bytes 4-7 are reserved and should be set to zero.
    switch (type) {
        case kTAG_CurveType: {
            uint32_t count = read_big_endian_u32(src + 8);

            // tagBytes = 12 + 2 * count
            // We need to do safe addition here to avoid integer overflow.
            if (!safe_add(count, count, &tagBytes) ||
                !safe_add((size_t) 12, tagBytes, &tagBytes))
            {
                SkColorSpacePrintf("Invalid gamma count");
                return SkGammas::Type::kNone_Type;
            }

            if (len < tagBytes) {
                SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
                return SkGammas::Type::kNone_Type;
            }
            *outTagBytes = tagBytes;

            if (0 == count) {
                // Some tags require a gamma curve, but the author doesn't actually want
                // to transform the data.  In this case, it is common to see a curve with
                // a count of 0.
                outData->fNamed = kLinear_SkGammaNamed;
                return SkGammas::Type::kNamed_Type;
            }

            const uint16_t* table = (const uint16_t*) (src + 12);
            if (1 == count) {
                // The table entry is the gamma (with a bias of 256).
                float value = (read_big_endian_u16((const uint8_t*) table)) / 256.0f;
                SkColorSpacePrintf("gamma %g\n", value);

                return set_gamma_value(outData, value);
            }

            // This optimization is especially important for A2B profiles, where we do
            // not resize tables or interpolate lookups.
            if (2 == count) {
                if (0 == read_big_endian_u16((const uint8_t*) &table[0]) &&
                        65535 == read_big_endian_u16((const uint8_t*) &table[1])) {
                    outData->fNamed = kLinear_SkGammaNamed;
                    return SkGammas::Type::kNamed_Type;
                }
            }

            // Check for frequently occurring sRGB curves.
            // We do this by sampling a few values and see if they match our expectation.
            // A more robust solution would be to compare each value in this curve against
            // an sRGB curve to see if we remain below an error threshold.  At this time,
            // we haven't seen any images in the wild that make this kind of
            // calculation necessary.  We encounter identical gamma curves over and
            // over again, but relatively few variations.
            if (1024 == count) {
                // The magic values were chosen because they match both the very common
                // HP sRGB gamma table and the less common Canon sRGB gamma table (which use
                // different rounding rules).
                if (0 == read_big_endian_u16((const uint8_t*) &table[0]) &&
                        3366 == read_big_endian_u16((const uint8_t*) &table[257]) &&
                        14116 == read_big_endian_u16((const uint8_t*) &table[513]) &&
                        34318 == read_big_endian_u16((const uint8_t*) &table[768]) &&
                        65535 == read_big_endian_u16((const uint8_t*) &table[1023])) {
                    outData->fNamed = kSRGB_SkGammaNamed;
                    return SkGammas::Type::kNamed_Type;
                }
            }

            if (26 == count) {
                // The magic values match a clever "minimum size" approach to representing sRGB.
                // code.facebook.com/posts/411525055626587/under-the-hood-improving-facebook-photos
                if (0 == read_big_endian_u16((const uint8_t*) &table[0]) &&
                        3062 == read_big_endian_u16((const uint8_t*) &table[6]) &&
                        12824 == read_big_endian_u16((const uint8_t*) &table[12]) &&
                        31237 == read_big_endian_u16((const uint8_t*) &table[18]) &&
                        65535 == read_big_endian_u16((const uint8_t*) &table[25])) {
                    outData->fNamed = kSRGB_SkGammaNamed;
                    return SkGammas::Type::kNamed_Type;
                }
            }

            if (4096 == count) {
                // The magic values were chosen because they match Nikon, Epson, and
                // lcms2 sRGB gamma tables (all of which use different rounding rules).
                if (0 == read_big_endian_u16((const uint8_t*) &table[0]) &&
                        950 == read_big_endian_u16((const uint8_t*) &table[515]) &&
                        3342 == read_big_endian_u16((const uint8_t*) &table[1025]) &&
                        14079 == read_big_endian_u16((const uint8_t*) &table[2051]) &&
                        65535 == read_big_endian_u16((const uint8_t*) &table[4095])) {
                    outData->fNamed = kSRGB_SkGammaNamed;
                    return SkGammas::Type::kNamed_Type;
                }
            }

            // Otherwise, we will represent gamma with a table.
            outData->fTable.fSize = count;
            return SkGammas::Type::kTable_Type;
        }
        case kTAG_ParaCurveType: {
            // Determine the format of the parametric curve tag.
            uint16_t format = read_big_endian_u16(src + 8);
            if (format > kGABCDEF_ParaCurveType) {
                SkColorSpacePrintf("Unsupported gamma tag type %d\n", type);
                return SkGammas::Type::kNone_Type;
            }

            if (kExponential_ParaCurveType == format) {
                tagBytes = 12 + 4;
                if (len < tagBytes) {
                    SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
                    return SkGammas::Type::kNone_Type;
                }

                // Y = X^g
                float g = read_big_endian_16_dot_16(src + 12);

                *outTagBytes = tagBytes;
                return set_gamma_value(outData, g);
            }

            // Here's where the real parametric gammas start.  There are many
            // permutations of the same equations.
            //
            // Y = (aX + b)^g + e  for X >= d
            // Y = cX + f          otherwise
            //
            // We will fill in with zeros as necessary to always match the above form.
            if (len < 24) {
                SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
                return SkGammas::Type::kNone_Type;
            }
            float g = read_big_endian_16_dot_16(src + 12);
            float a = read_big_endian_16_dot_16(src + 16);
            float b = read_big_endian_16_dot_16(src + 20);
            float c = 0.0f, d = 0.0f, e = 0.0f, f = 0.0f;
            switch(format) {
                case kGAB_ParaCurveType:
                    tagBytes = 12 + 12;

                    // Y = (aX + b)^g  for X >= -b/a
                    // Y = 0           otherwise
                    d = -b / a;
                    break;
                case kGABC_ParaCurveType:
                    tagBytes = 12 + 16;
                    if (len < tagBytes) {
                        SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
                        return SkGammas::Type::kNone_Type;
                    }

                    // Y = (aX + b)^g + e  for X >= -b/a
                    // Y = e               otherwise
                    e = read_big_endian_16_dot_16(src + 24);
                    d = -b / a;
                    f = e;
                    break;
                case kGABDE_ParaCurveType:
                    tagBytes = 12 + 20;
                    if (len < tagBytes) {
                        SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
                        return SkGammas::Type::kNone_Type;
                    }

                    // Y = (aX + b)^g  for X >= d
                    // Y = cX          otherwise
                    c = read_big_endian_16_dot_16(src + 24);
                    d = read_big_endian_16_dot_16(src + 28);
                    break;
                case kGABCDEF_ParaCurveType:
                    tagBytes = 12 + 28;
                    if (len < tagBytes) {
                        SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
                        return SkGammas::Type::kNone_Type;
                    }

                    // Y = (aX + b)^g + e  for X >= d
                    // Y = cX + f          otherwise
                    c = read_big_endian_16_dot_16(src + 24);
                    d = read_big_endian_16_dot_16(src + 28);
                    e = read_big_endian_16_dot_16(src + 32);
                    f = read_big_endian_16_dot_16(src + 36);
                    break;
                default:
                    SkASSERT(false);
                    return SkGammas::Type::kNone_Type;
            }

            outParams->fG = g;
            outParams->fA = a;
            outParams->fB = b;
            outParams->fC = c;
            outParams->fD = d;
            outParams->fE = e;
            outParams->fF = f;

            if (!is_valid_transfer_fn(*outParams)) {
                return SkGammas::Type::kNone_Type;
            }

            if (is_almost_srgb(*outParams)) {
                outData->fNamed = kSRGB_SkGammaNamed;
                return SkGammas::Type::kNamed_Type;
            }

            if (is_almost_2dot2(*outParams)) {
                outData->fNamed = k2Dot2Curve_SkGammaNamed;
                return SkGammas::Type::kNamed_Type;
            }

            *outTagBytes = tagBytes;
            return SkGammas::Type::kParam_Type;
        }
        default:
            SkColorSpacePrintf("Unsupported gamma tag type %d\n", type);
            return SkGammas::Type::kNone_Type;
    }
}

/**
 *  Returns the additional size in bytes needed to store the gamma tag.
 */
static size_t gamma_alloc_size(SkGammas::Type type, const SkGammas::Data& data) {
    switch (type) {
        case SkGammas::Type::kNamed_Type:
        case SkGammas::Type::kValue_Type:
            return 0;
        case SkGammas::Type::kTable_Type:
            return sizeof(float) * data.fTable.fSize;
        case SkGammas::Type::kParam_Type:
            return sizeof(SkColorSpaceTransferFn);
        default:
            SkASSERT(false);
            return 0;
    }
}

/**
 *  Sets invalid gamma to the default value.
 */
static void handle_invalid_gamma(SkGammas::Type* type, SkGammas::Data* data) {
    if (SkGammas::Type::kNone_Type == *type) {
        *type = SkGammas::Type::kNamed_Type;

        // Guess sRGB in the case of a malformed transfer function.
        data->fNamed = kSRGB_SkGammaNamed;
    }
}

/**
 *  Finish loading the gammas, now that we have allocated memory for the SkGammas struct.
 *
 *  There's nothing to do for the simple cases, but for table gammas we need to actually
 *  read the table into heap memory.  And for parametric gammas, we need to copy over the
 *  parameter values.
 *
 *  @param memory Pointer to start of the SkGammas memory block
 *  @param offset Bytes of memory (after the SkGammas struct) that are already in use.
 *  @param data   In-out variable.  Will fill in the offset to the table or parameters
 *                if necessary.
 *  @param params Parameters for gamma curve.  Only initialized/used when we have a
 *                parametric gamma.
 *  @param src    Pointer to start of the gamma tag.
 *
 *  @return       Additional bytes of memory that are being used by this gamma curve.
 */
static size_t load_gammas(void* memory, size_t offset, SkGammas::Type type,
                        SkGammas::Data* data, const SkColorSpaceTransferFn& params,
                        const uint8_t* src) {
    void* storage = SkTAddOffset<void>(memory, offset + sizeof(SkGammas));

    switch (type) {
        case SkGammas::Type::kNamed_Type:
        case SkGammas::Type::kValue_Type:
            // Nothing to do here.
            return 0;
        case SkGammas::Type::kTable_Type: {
            data->fTable.fOffset = offset;

            float* outTable = (float*) storage;
            const uint16_t* inTable = (const uint16_t*) (src + 12);
            for (int i = 0; i < data->fTable.fSize; i++) {
                outTable[i] = (read_big_endian_u16((const uint8_t*) &inTable[i])) / 65535.0f;
            }

            return sizeof(float) * data->fTable.fSize;
        }
        case SkGammas::Type::kParam_Type:
            data->fTable.fOffset = offset;
            memcpy(storage, &params, sizeof(SkColorSpaceTransferFn));
            return sizeof(SkColorSpaceTransferFn);
        default:
            SkASSERT(false);
            return 0;
    }
}

static constexpr uint32_t kTAG_AtoBType  = SkSetFourByteTag('m', 'A', 'B', ' ');
static constexpr uint32_t kTAG_lut8Type  = SkSetFourByteTag('m', 'f', 't', '1');
static constexpr uint32_t kTAG_lut16Type = SkSetFourByteTag('m', 'f', 't', '2');

static bool load_color_lut(sk_sp<SkColorLookUpTable>* colorLUT, uint32_t inputChannels,
                           size_t precision, const uint8_t gridPoints[3], const uint8_t* src,
                           size_t len) {
    switch (precision) {
        case 1: //  8-bit data
        case 2: // 16-bit data
            break;
        default:
            SkColorSpacePrintf("Color LUT precision must be 8-bit or 16-bit. Found: %d-bit\n",
                               8*precision);
            return false;
    }

    uint32_t numEntries = SkColorLookUpTable::kOutputChannels;
    for (uint32_t i = 0; i < inputChannels; i++) {
        if (1 >= gridPoints[i]) {
            SkColorSpacePrintf("Each input channel must have at least two grid points.");
            return false;
        }

        if (!safe_mul(numEntries, gridPoints[i], &numEntries)) {
            SkColorSpacePrintf("Too many entries in Color LUT.");
            return false;
        }
    }

    uint32_t clutBytes;
    if (!safe_mul(numEntries, precision, &clutBytes)) {
        SkColorSpacePrintf("Too many entries in Color LUT.\n");
        return false;
    }

    if (len < clutBytes) {
        SkColorSpacePrintf("Color LUT tag is too small (%d / %d bytes).\n", len, clutBytes);
        return false;
    }

    // Movable struct colorLUT has ownership of fTable.
    void* memory = sk_malloc_throw(sizeof(SkColorLookUpTable) + sizeof(float) * numEntries);
    *colorLUT = sk_sp<SkColorLookUpTable>(new (memory) SkColorLookUpTable(inputChannels,
                                                                          gridPoints));

    float* table = SkTAddOffset<float>(memory, sizeof(SkColorLookUpTable));
    const uint8_t* ptr = src;
    for (uint32_t i = 0; i < numEntries; i++, ptr += precision) {
        if (1 == precision) {
            table[i] = ((float) *ptr) / 255.0f;
        } else {
            table[i] = ((float) read_big_endian_u16(ptr)) / 65535.0f;
        }
    }

    return true;
}

/**
 *  Reads a matrix out of an A2B tag of an ICC profile.
 *  If |translate| is true, it will load a 3x4 matrix out that corresponds to a XYZ
 *  transform as well as a translation, and if |translate| is false it only loads a
 *  3x3 matrix with no translation
 *
 *  @param matrix    The matrix to store the result in
 *  @param src       Data to load the matrix out of.
 *  @param len       The length of |src|.
 *                   Must have 48 bytes if |translate| is set and 36 bytes otherwise.
 *  @param translate Whether to read the translation column or not
 *  @param pcs       The profile connection space of the profile this matrix is for
 *
 *  @return          false on failure, true on success
 */
static bool load_matrix(SkMatrix44* matrix, const uint8_t* src, size_t len, bool translate,
                        SkColorSpace_A2B::PCS pcs) {
    const size_t minLen = translate ? 48 : 36;
    if (len < minLen) {
        SkColorSpacePrintf("Matrix tag is too small (%d bytes).", len);
        return false;
    }

    float encodingFactor;
    switch (pcs) {
        case SkColorSpace_A2B::PCS::kLAB:
            encodingFactor = 1.f;
            break;
        case SkColorSpace_A2B::PCS::kXYZ:
            encodingFactor = 65535 / 32768.f;
            break;
        default:
            encodingFactor = 1.f;
            SkASSERT(false);
            break;
    }
    float array[16];
    array[ 0] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src));
    array[ 1] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 4));
    array[ 2] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 8));

    array[ 4] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 12));
    array[ 5] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 16));
    array[ 6] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 20));

    array[ 8] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 24));
    array[ 9] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 28));
    array[10] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 32));

    if (translate) {
        array[ 3] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 36)); // translate R
        array[ 7] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 40)); // translate G
        array[11] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 44)); // translate B
    } else {
        array[ 3] = 0.0f;
        array[ 7] = 0.0f;
        array[11] = 0.0f;
    }

    array[12] = 0.0f;
    array[13] = 0.0f;
    array[14] = 0.0f;
    array[15] = 1.0f;
    matrix->setRowMajorf(array);
    SkColorSpacePrintf("A2B0 matrix loaded:\n");
    for (int r = 0; r < 4; ++r) {
        SkColorSpacePrintf("|");
        for (int c = 0; c < 4; ++c) {
            SkColorSpacePrintf(" %f ", matrix->get(r, c));
        }
        SkColorSpacePrintf("|\n");
    }
    return true;
}

static inline SkGammaNamed is_named(const sk_sp<SkGammas>& gammas) {
    for (uint8_t i = 0; i < gammas->channels(); ++i) {
        if (!gammas->isNamed(i) || gammas->data(i).fNamed != gammas->data(0).fNamed) {
            return kNonStandard_SkGammaNamed;
        }
    }
    return gammas->data(0).fNamed;
}

/**
 *  Parse and load an entire stored curve. Handles invalid gammas as well.
 *
 *  There's nothing to do for the simple cases, but for table gammas we need to actually
 *  read the table into heap memory.  And for parametric gammas, we need to copy over the
 *  parameter values.
 *
 *  @param gammaNamed    Out-variable. The named gamma curve.
 *  @param gammas        Out-variable. The stored gamma curve information. Can be null if
 *                       gammaNamed is a named curve
 *  @param inputChannels The number of gamma input channels
 *  @param rTagPtr       Pointer to start of the gamma tag.
 *  @param taglen        The size in bytes of the tag
 *
 *  @return              false on failure, true on success
 */
static bool parse_and_load_gamma(SkGammaNamed* gammaNamed, sk_sp<SkGammas>* gammas,
                                 uint8_t inputChannels, const uint8_t* tagSrc, size_t tagLen) {
    SkGammas::Data data[kMaxColorChannels];
    SkColorSpaceTransferFn params[kMaxColorChannels];
    SkGammas::Type type[kMaxColorChannels];
    const uint8_t* tagPtr[kMaxColorChannels];

    tagPtr[0] = tagSrc;

    *gammaNamed = kNonStandard_SkGammaNamed;

    // On an invalid first gamma, tagBytes remains set as zero.  This causes the two
    // subsequent to be treated as identical (which is what we want).
    size_t tagBytes = 0;
    type[0] = parse_gamma(&data[0], &params[0], &tagBytes, tagPtr[0], tagLen);
    handle_invalid_gamma(&type[0], &data[0]);
    size_t alignedTagBytes = SkAlign4(tagBytes);

    bool allChannelsSame = false;
    if (inputChannels * alignedTagBytes <= tagLen) {
        allChannelsSame = true;
        for (uint8_t i = 1; i < inputChannels; ++i) {
            if (0 != memcmp(tagSrc, tagSrc + i * alignedTagBytes, tagBytes)) {
                allChannelsSame = false;
                break;
            }
        }
    }
    if (allChannelsSame) {
        if (SkGammas::Type::kNamed_Type == type[0]) {
            *gammaNamed = data[0].fNamed;
        } else {
            size_t allocSize = sizeof(SkGammas);
            return_if_false(safe_add(allocSize, gamma_alloc_size(type[0], data[0]), &allocSize),
                            "SkGammas struct is too large to allocate");
            void* memory = sk_malloc_throw(allocSize);
            *gammas = sk_sp<SkGammas>(new (memory) SkGammas(inputChannels));
            load_gammas(memory, 0, type[0], &data[0], params[0], tagPtr[0]);

            for (uint8_t channel = 0; channel < inputChannels; ++channel) {
                (*gammas)->fType[channel] = type[0];
                (*gammas)->fData[channel] = data[0];
            }
        }
    } else {
        for (uint8_t channel = 1; channel < inputChannels; ++channel) {
            tagPtr[channel] = tagPtr[channel - 1] + alignedTagBytes;
            tagLen = tagLen > alignedTagBytes ? tagLen - alignedTagBytes : 0;
            tagBytes = 0;
            type[channel] = parse_gamma(&data[channel], &params[channel], &tagBytes,
                                        tagPtr[channel], tagLen);
            handle_invalid_gamma(&type[channel], &data[channel]);
            alignedTagBytes = SkAlign4(tagBytes);
        }

        size_t allocSize = sizeof(SkGammas);
        for (uint8_t channel = 0; channel < inputChannels; ++channel) {
            return_if_false(safe_add(allocSize, gamma_alloc_size(type[channel], data[channel]),
                                     &allocSize),
                            "SkGammas struct is too large to allocate");
        }
        void* memory = sk_malloc_throw(allocSize);
        *gammas = sk_sp<SkGammas>(new (memory) SkGammas(inputChannels));

        uint32_t offset = 0;
        for (uint8_t channel = 0; channel < inputChannels; ++channel) {
            (*gammas)->fType[channel] = type[channel];
            offset += load_gammas(memory,offset, type[channel], &data[channel], params[channel],
                                  tagPtr[channel]);
            (*gammas)->fData[channel] = data[channel];

        }
    }

    if (kNonStandard_SkGammaNamed == *gammaNamed) {
        *gammaNamed = is_named(*gammas);
        if (kNonStandard_SkGammaNamed != *gammaNamed) {
            // No need to keep the gammas struct, the enum is enough.
            *gammas = nullptr;
        }
    }
    return true;
}

static bool is_lut_gamma_linear(const uint8_t* src, size_t count, size_t precision) {
    // check for linear gamma (this is very common in lut gammas, as they aren't optional)
    const float normalizeX = 1.f / (count - 1);
    for (uint32_t x = 0; x < count; ++x) {
        const float y = precision == 1 ? (src[x] / 255.f)
                                       : (read_big_endian_u16(src + 2*x) / 65535.f);
        if (!color_space_almost_equal(x * normalizeX, y)) {
            return false;
        }
    }
    return true;
}

static bool load_lut_gammas(sk_sp<SkGammas>* gammas, SkGammaNamed* gammaNamed, size_t numTables,
                            size_t entriesPerTable, size_t precision, const uint8_t* src,
                            size_t len) {
    if (precision != 1 && precision != 2) {
        SkColorSpacePrintf("Invalid gamma table precision %d\n", precision);
        return false;
    }
    uint32_t totalEntries;
    return_if_false(safe_mul(entriesPerTable, numTables, &totalEntries),
                    "Too many entries in gamma table.");
    uint32_t readBytes;
    return_if_false(safe_mul(precision, totalEntries, &readBytes),
                    "SkGammas struct is too large to read");
    if (len < readBytes) {
        SkColorSpacePrintf("Gamma table is too small. Provided: %d. Required: %d\n",
                           len, readBytes);
        return false;
    }

    uint32_t writeBytesPerChannel;
    return_if_false(safe_mul(sizeof(float), entriesPerTable, &writeBytesPerChannel),
                    "SkGammas struct is too large to allocate");
    const size_t readBytesPerChannel = precision * entriesPerTable;
    size_t numTablesToUse = 1;
    for (size_t tableIndex = 1; tableIndex < numTables; ++tableIndex) {
        if (0 != memcmp(src, src + readBytesPerChannel * tableIndex, readBytesPerChannel)) {
            numTablesToUse = numTables;
            break;
        }
    }

    if (1 == numTablesToUse) {
        if (is_lut_gamma_linear(src, entriesPerTable, precision)) {
            *gammaNamed = kLinear_SkGammaNamed;
            return true;
        }
    }
    *gammaNamed = kNonStandard_SkGammaNamed;

    uint32_t writetableBytes;
    return_if_false(safe_mul(numTablesToUse, writeBytesPerChannel, &writetableBytes),
                    "SkGammas struct is too large to allocate");
    size_t allocSize = sizeof(SkGammas);
    return_if_false(safe_add(allocSize, (size_t)writetableBytes, &allocSize),
                    "SkGammas struct is too large to allocate");

    void* memory = sk_malloc_throw(allocSize);
    *gammas = sk_sp<SkGammas>(new (memory) SkGammas(numTables));

    for (size_t tableIndex = 0; tableIndex < numTablesToUse; ++tableIndex) {
        const uint8_t* ptr = src + readBytesPerChannel * tableIndex;
        const size_t offset = sizeof(SkGammas) + tableIndex * writeBytesPerChannel;
        float* table = SkTAddOffset<float>(memory, offset);
        if (1 == precision) {
            for (uint32_t i = 0; i < entriesPerTable; ++i, ptr += 1) {
                table[i] = ((float) *ptr) / 255.0f;
            }
        } else if (2 == precision) {
            for (uint32_t i = 0; i < entriesPerTable; ++i, ptr += 2) {
                table[i] = ((float) read_big_endian_u16(ptr)) / 65535.0f;
            }
        }
    }

    SkASSERT(1 == numTablesToUse|| numTables == numTablesToUse);

    size_t tableOffset = 0;
    for (size_t tableIndex = 0; tableIndex < numTables; ++tableIndex) {
        (*gammas)->fType[tableIndex]                = SkGammas::Type::kTable_Type;
        (*gammas)->fData[tableIndex].fTable.fOffset = tableOffset;
        (*gammas)->fData[tableIndex].fTable.fSize   = entriesPerTable;
        if (numTablesToUse > 1) {
            tableOffset += writeBytesPerChannel;
        }
    }

    return true;
}

bool load_a2b0_a_to_b_type(std::vector<SkColorSpace_A2B::Element>* elements, const uint8_t* src,
                           size_t len, SkColorSpace_A2B::PCS pcs) {
    SkASSERT(len >= 32);
    // Read the number of channels.  The four bytes (4-7) that we skipped are reserved and
    // must be zero.
    const uint8_t inputChannels = src[8];
    const uint8_t outputChannels = src[9];
    if (SkColorLookUpTable::kOutputChannels != outputChannels) {
        // We only handle RGB outputs. The number of output channels must be 3.
        SkColorSpacePrintf("Output channels (%d) must equal 3 in A to B tag.\n", outputChannels);
        return false;
    }
    if (inputChannels == 0 || inputChannels > 4) {
        // And we only support 4 input channels.
        // ICC says up to 16 but our decode can only handle 4.
        // It could easily be extended to support up to 8, but we only allow CMYK/RGB
        // input color spaces which are 3 and 4 so let's restrict it to 4 instead of 8.
        // We can always change this check when we support bigger input spaces.
        SkColorSpacePrintf("Input channels (%d) must be between 1 and 4 in A to B tag.\n",
                           inputChannels);
        return false;
    }


    // It is important that these are loaded in the order of application, as the
    // order you construct an A2B color space's elements is the order it is applied

    // If the offset is non-zero it indicates that the element is present.
    const uint32_t offsetToACurves = read_big_endian_i32(src + 28);
    if (0 != offsetToACurves && offsetToACurves < len) {
        const size_t tagLen = len - offsetToACurves;
        SkGammaNamed gammaNamed;
        sk_sp<SkGammas> gammas;
        if (!parse_and_load_gamma(&gammaNamed, &gammas, inputChannels, src + offsetToACurves,
                                  tagLen)) {
            return false;
        }
        if (gammas) {
            elements->push_back(SkColorSpace_A2B::Element(std::move(gammas)));
        } else if (kLinear_SkGammaNamed != gammaNamed) {
            elements->push_back(SkColorSpace_A2B::Element(gammaNamed, inputChannels));
        }
    }

    const uint32_t offsetToColorLUT = read_big_endian_i32(src + 24);
    if (0 != offsetToColorLUT && offsetToColorLUT < len) {
        sk_sp<SkColorLookUpTable> colorLUT;
        const uint8_t* clutSrc = src + offsetToColorLUT;
        const size_t clutLen = len - offsetToColorLUT;
        // 16 bytes reserved for grid points, 1 for precision, 3 for padding.
        // The color LUT data follows after this header.
        static constexpr uint32_t kColorLUTHeaderSize = 20;
        if (clutLen < kColorLUTHeaderSize) {
            SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", clutLen);
            return false;
        }

        SkASSERT(inputChannels <= kMaxColorChannels);
        uint8_t gridPoints[kMaxColorChannels];
        for (uint32_t i = 0; i < inputChannels; ++i) {
            gridPoints[i] = clutSrc[i];
        }
        // Space is provided for a maximum of 16 input channels.
        // Now we determine the precision of the table values.
        const uint8_t precision = clutSrc[16];
        if (!load_color_lut(&colorLUT, inputChannels, precision, gridPoints,
                            clutSrc + kColorLUTHeaderSize, clutLen - kColorLUTHeaderSize)) {
            SkColorSpacePrintf("Failed to read color LUT from A to B tag.\n");
            return false;
        }
        elements->push_back(SkColorSpace_A2B::Element(std::move(colorLUT)));
    }

    const uint32_t offsetToMCurves = read_big_endian_i32(src + 20);
    if (0 != offsetToMCurves && offsetToMCurves < len) {
        const size_t tagLen = len - offsetToMCurves;
        SkGammaNamed gammaNamed;
        sk_sp<SkGammas> gammas;
        if (!parse_and_load_gamma(&gammaNamed, &gammas, outputChannels, src + offsetToMCurves,
                                  tagLen)) {
            return false;
        }
        if (gammas) {
            elements->push_back(SkColorSpace_A2B::Element(std::move(gammas)));
        } else if (kLinear_SkGammaNamed != gammaNamed) {
            elements->push_back(SkColorSpace_A2B::Element(gammaNamed, outputChannels));
        }
    }

    const uint32_t offsetToMatrix = read_big_endian_i32(src + 16);
    if (0 != offsetToMatrix && offsetToMatrix < len) {
        SkMatrix44 matrix(SkMatrix44::kUninitialized_Constructor);
        if (!load_matrix(&matrix, src + offsetToMatrix, len - offsetToMatrix, true, pcs)) {
            SkColorSpacePrintf("Failed to read matrix from A to B tag.\n");
        } else if (!matrix.isIdentity()) {
            elements->push_back(SkColorSpace_A2B::Element(matrix));
        }
    }

    const uint32_t offsetToBCurves = read_big_endian_i32(src + 12);
    if (0 != offsetToBCurves && offsetToBCurves < len) {
        const size_t tagLen = len - offsetToBCurves;
        SkGammaNamed gammaNamed;
        sk_sp<SkGammas> gammas;
        if (!parse_and_load_gamma(&gammaNamed, &gammas, outputChannels, src + offsetToBCurves,
                                  tagLen)) {
            return false;
        }
        if (gammas) {
            elements->push_back(SkColorSpace_A2B::Element(std::move(gammas)));
        } else if (kLinear_SkGammaNamed != gammaNamed) {
            elements->push_back(SkColorSpace_A2B::Element(gammaNamed, outputChannels));
        }
    }

    return true;
}

bool load_a2b0_lutn_type(std::vector<SkColorSpace_A2B::Element>* elements, const uint8_t* src,
                         size_t len, SkColorSpace_A2B::PCS pcs) {
    const uint32_t type = read_big_endian_u32(src);
    switch (type) {
        case kTAG_lut8Type:
            SkASSERT(len >= 48);
            break;
        case kTAG_lut16Type:
            SkASSERT(len >= 52);
            break;
        default:
            SkASSERT(false);
            return false;
    }
    // Read the number of channels.
    // The four bytes (4-7) that we skipped are reserved and must be zero.
    const uint8_t inputChannels = src[8];
    const uint8_t outputChannels = src[9];
    if (SkColorLookUpTable::kOutputChannels != outputChannels) {
        // We only handle RGB outputs. The number of output channels must be 3.
        SkColorSpacePrintf("Output channels (%d) must equal 3 in A to B tag.\n", outputChannels);
        return false;
    }
    if (inputChannels == 0 || inputChannels > 4) {
        // And we only support 4 input channels.
        // ICC says up to 16 but our decode can only handle 4.
        // It could easily be extended to support up to 8, but we only allow CMYK/RGB
        // input color spaces which are 3 and 4 so let's restrict it to 4 instead of 8.
        // We can always change this check when we support bigger input spaces.
        SkColorSpacePrintf("Input channels (%d) must be between 1 and 4 in A to B tag.\n",
                           inputChannels);
        return false;
    }

    const uint8_t clutGridPoints = src[10];
    // 11th byte reserved for padding (required to be zero)

    SkMatrix44 matrix(SkMatrix44::kUninitialized_Constructor);
    load_matrix(&matrix, &src[12], len - 12, false, pcs);
    if (!matrix.isIdentity()) {
        // ICC specs (10.8/10.9) say lut8/16Type profiles must have identity matrices
        // if the input color space is not PCSXYZ, and we do not support PCSXYZ input color spaces
        // so we should never encounter a non-identity matrix here.
        // However, 2 test images from the ICC website have RGB input spaces and non-identity
        // matrices so we're not going to fail here, despite being against the spec.
        SkColorSpacePrintf("Warning: non-Identity matrix found in non-XYZ input color space"
                           "lut profile");
        elements->push_back(SkColorSpace_A2B::Element(matrix));
    }

    size_t dataOffset      = 48;
    // # of input table entries
    size_t inTableEntries  = 256;
    // # of output table entries
    size_t outTableEntries = 256;
    size_t precision       = 1;
    if (kTAG_lut16Type == type) {
        dataOffset      = 52;
        inTableEntries  = read_big_endian_u16(src + 48);
        outTableEntries = read_big_endian_u16(src + 50);
        precision       = 2;

        constexpr size_t kMaxLut16GammaEntries = 4096;
        if (inTableEntries < 2) {
            SkColorSpacePrintf("Too few (%d) input gamma table entries. Must have at least 2.\n",
                               inTableEntries);
            return false;
        } else if (inTableEntries > kMaxLut16GammaEntries) {
            SkColorSpacePrintf("Too many (%d) input gamma table entries. Must have at most %d.\n",
                               inTableEntries, kMaxLut16GammaEntries);
            return false;
        }

        if (outTableEntries < 2) {
            SkColorSpacePrintf("Too few (%d) output gamma table entries. Must have at least 2.\n",
                               outTableEntries);
            return false;
        } else if (outTableEntries > kMaxLut16GammaEntries) {
            SkColorSpacePrintf("Too many (%d) output gamma table entries. Must have at most %d.\n",
                               outTableEntries, kMaxLut16GammaEntries);
            return false;
        }
    }

    const size_t inputOffset = dataOffset;
    return_if_false(len >= inputOffset, "A2B0 lutnType tag too small for input gamma table");
    sk_sp<SkGammas> inputGammas;
    SkGammaNamed inputGammaNamed;
    if (!load_lut_gammas(&inputGammas, &inputGammaNamed, inputChannels, inTableEntries, precision,
                         src + inputOffset, len - inputOffset)) {
        SkColorSpacePrintf("Failed to read input gammas from lutnType tag.\n");
        return false;
    }
    SkASSERT(inputGammas || inputGammaNamed != kNonStandard_SkGammaNamed);
    if (kLinear_SkGammaNamed != inputGammaNamed) {
        if (kNonStandard_SkGammaNamed != inputGammaNamed) {
            elements->push_back(SkColorSpace_A2B::Element(inputGammaNamed, inputChannels));
        } else {
            elements->push_back(SkColorSpace_A2B::Element(std::move(inputGammas)));
        }
    }

    const size_t clutOffset = inputOffset + precision*inTableEntries*inputChannels;
    return_if_false(len >= clutOffset, "A2B0 lutnType tag too small for CLUT");
    sk_sp<SkColorLookUpTable> colorLUT;
    const uint8_t gridPoints[kMaxColorChannels] = {
        clutGridPoints, clutGridPoints, clutGridPoints, clutGridPoints
    };
    if (!load_color_lut(&colorLUT, inputChannels, precision, gridPoints, src + clutOffset,
                        len - clutOffset)) {
        SkColorSpacePrintf("Failed to read color LUT from lutnType tag.\n");
        return false;
    }
    SkASSERT(colorLUT);
    elements->push_back(SkColorSpace_A2B::Element(std::move(colorLUT)));

    size_t clutSize = precision * outputChannels;
    for (int i = 0; i < inputChannels; ++i) {
        clutSize *= clutGridPoints;
    }
    const size_t outputOffset = clutOffset + clutSize;
    return_if_false(len >= outputOffset, "A2B0 lutnType tag too small for output gamma table");
    sk_sp<SkGammas> outputGammas;
    SkGammaNamed outputGammaNamed;
    if (!load_lut_gammas(&outputGammas, &outputGammaNamed, outputChannels, outTableEntries,
                         precision, src + outputOffset, len - outputOffset)) {
        SkColorSpacePrintf("Failed to read output gammas from lutnType tag.\n");
        return false;
    }
    SkASSERT(outputGammas || outputGammaNamed != kNonStandard_SkGammaNamed);
    if (kLinear_SkGammaNamed != outputGammaNamed) {
        if (kNonStandard_SkGammaNamed != outputGammaNamed) {
            elements->push_back(SkColorSpace_A2B::Element(outputGammaNamed, outputChannels));
        } else {
            elements->push_back(SkColorSpace_A2B::Element(std::move(outputGammas)));
        }
    }

    return true;
}

static inline int icf_channels(SkColorSpace::Type iccType) {
    switch (iccType) {
        case SkColorSpace::kRGB_Type:
            return 3;
        case SkColorSpace::kCMYK_Type:
            return 4;
        default:
            SkASSERT(false);
            return 0;
    }
}

static bool load_a2b0(std::vector<SkColorSpace_A2B::Element>* elements, const uint8_t* src,
                      size_t len, SkColorSpace_A2B::PCS pcs,
                      SkColorSpace::Type iccType) {
    if (len < 4) {
        return false;
    }
    const uint32_t type = read_big_endian_u32(src);

    switch (type) {
        case kTAG_AtoBType:
            if (len < 32) {
                SkColorSpacePrintf("A to B tag is too small (%d bytes).", len);
                return false;
            }
            SkColorSpacePrintf("A2B0 tag is of type lutAtoBType\n");
            if (!load_a2b0_a_to_b_type(elements, src, len, pcs)) {
                return false;
            }
            break;
        case kTAG_lut8Type:
            if (len < 48) {
                SkColorSpacePrintf("lut8 tag is too small (%d bytes).", len);
                return false;
            }
            SkColorSpacePrintf("A2B0 tag of type lut8Type\n");
            if (!load_a2b0_lutn_type(elements, src, len, pcs)) {
                return false;
            }
            break;
        case kTAG_lut16Type:
            if (len < 52) {
                SkColorSpacePrintf("lut16 tag is too small (%d bytes).", len);
                return false;
            }
            SkColorSpacePrintf("A2B0 tag of type lut16Type\n");
            if (!load_a2b0_lutn_type(elements, src, len, pcs)) {
                return false;
            }
            break;
        default:
            SkColorSpacePrintf("Unsupported A to B tag type: %c%c%c%c\n", (type>>24)&0xFF,
                               (type>>16)&0xFF, (type>>8)&0xFF, type&0xFF);
            return false;
    }
    SkASSERT(SkColorSpace_A2B::PCS::kLAB == pcs || SkColorSpace_A2B::PCS::kXYZ == pcs);
    static constexpr int kPCSChannels = 3; // must be PCSLAB or PCSXYZ
    if (elements->empty()) {
        return kPCSChannels == icf_channels(iccType);
    }
    // now let's verify that the input/output channels of each A2B element actually match up
    if (icf_channels(iccType) != elements->front().inputChannels()) {
        SkColorSpacePrintf("Input channel count does not match first A2B element's input count");
        return false;
    }
    for (size_t i = 1; i < elements->size(); ++i) {
        if ((*elements)[i - 1].outputChannels() != (*elements)[i].inputChannels()) {
            SkColorSpacePrintf("A2B elements don't agree in input/output channel counts");
            return false;
        }
    }
    if (kPCSChannels != elements->back().outputChannels()) {
        SkColorSpacePrintf("PCS channel count doesn't match last A2B element's output count");
        return false;
    }
    return true;
}

static bool tag_equals(const ICCTag* a, const ICCTag* b, const uint8_t* base) {
    if (!a || !b) {
        return a == b;
    }

    if (a->fLength != b->fLength) {
        return false;
    }

    if (a->fOffset == b->fOffset) {
        return true;
    }

    return !memcmp(a->addr(base), b->addr(base), a->fLength);
}

static inline bool is_close_to_d50(const SkMatrix44& matrix) {
    // rX + gX + bX
    float X = matrix.getFloat(0, 0) + matrix.getFloat(0, 1) + matrix.getFloat(0, 2);

    // rY + gY + bY
    float Y = matrix.getFloat(1, 0) + matrix.getFloat(1, 1) + matrix.getFloat(1, 2);

    // rZ + gZ + bZ
    float Z = matrix.getFloat(2, 0) + matrix.getFloat(2, 1) + matrix.getFloat(2, 2);

    static const float kD50_WhitePoint[3] = { 0.96420f, 1.00000f, 0.82491f };

    // This is a bit more lenient than QCMS and Adobe.  Is there a reason to be stricter here?
    return (SkTAbs(X - kD50_WhitePoint[0]) <= 0.04f) &&
           (SkTAbs(Y - kD50_WhitePoint[1]) <= 0.04f) &&
           (SkTAbs(Z - kD50_WhitePoint[2]) <= 0.04f);
}

static sk_sp<SkColorSpace> make_xyz(const ICCProfileHeader& header, ICCTag* tags, int tagCount,
                                    const uint8_t* base, sk_sp<SkData> profileData) {
    if (kLAB_PCSSpace == header.fPCS) {
        return nullptr;
    }

    // Recognize the rXYZ, gXYZ, and bXYZ tags.
    const ICCTag* r = ICCTag::Find(tags, tagCount, kTAG_rXYZ);
    const ICCTag* g = ICCTag::Find(tags, tagCount, kTAG_gXYZ);
    const ICCTag* b = ICCTag::Find(tags, tagCount, kTAG_bXYZ);
    if (!r || !g || !b) {
        return nullptr;
    }

    float toXYZ[9];
    if (!load_xyz(&toXYZ[0], r->addr(base), r->fLength) ||
        !load_xyz(&toXYZ[3], g->addr(base), g->fLength) ||
        !load_xyz(&toXYZ[6], b->addr(base), b->fLength))
    {
        return_null("Need valid rgb tags for XYZ space");
    }
    SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
    mat.set3x3(toXYZ[0], toXYZ[1], toXYZ[2],
               toXYZ[3], toXYZ[4], toXYZ[5],
               toXYZ[6], toXYZ[7], toXYZ[8]);
    if (!is_close_to_d50(mat)) {
        return_null("XYZ matrix is not D50");
    }

    // If some, but not all, of the gamma tags are missing, assume that all
    // gammas are meant to be the same.
    r = ICCTag::Find(tags, tagCount, kTAG_rTRC);
    g = ICCTag::Find(tags, tagCount, kTAG_gTRC);
    b = ICCTag::Find(tags, tagCount, kTAG_bTRC);
    if (!r || !g || !b) {
        return_null("Need valid TRC tags for XYZ space");
    }

    SkGammaNamed gammaNamed = kNonStandard_SkGammaNamed;
    sk_sp<SkGammas> gammas = nullptr;
    size_t tagBytes;
    if (tag_equals(r, g, base) && tag_equals(g, b, base)) {
        SkGammas::Data data;
        SkColorSpaceTransferFn params;
        SkGammas::Type type =
                parse_gamma(&data, &params, &tagBytes, r->addr(base), r->fLength);
        handle_invalid_gamma(&type, &data);

        if (SkGammas::Type::kNamed_Type == type) {
            gammaNamed = data.fNamed;
        } else {
            size_t allocSize = sizeof(SkGammas);
            if (!safe_add(allocSize, gamma_alloc_size(type, data), &allocSize)) {
                return_null("SkGammas struct is too large to allocate");
            }
            void* memory = sk_malloc_throw(allocSize);
            gammas = sk_sp<SkGammas>(new (memory) SkGammas(3));
            load_gammas(memory, 0, type, &data, params, r->addr(base));

            for (int i = 0; i < 3; ++i) {
                gammas->fType[i] = type;
                gammas->fData[i] = data;
            }
        }
    } else {
        SkGammas::Data rData;
        SkColorSpaceTransferFn rParams;
        SkGammas::Type rType =
                parse_gamma(&rData, &rParams, &tagBytes, r->addr(base), r->fLength);
        handle_invalid_gamma(&rType, &rData);

        SkGammas::Data gData;
        SkColorSpaceTransferFn gParams;
        SkGammas::Type gType =
                parse_gamma(&gData, &gParams, &tagBytes, g->addr(base), g->fLength);
        handle_invalid_gamma(&gType, &gData);

        SkGammas::Data bData;
        SkColorSpaceTransferFn bParams;
        SkGammas::Type bType =
                parse_gamma(&bData, &bParams, &tagBytes, b->addr(base), b->fLength);
        handle_invalid_gamma(&bType, &bData);

        size_t allocSize = sizeof(SkGammas);
        if (!safe_add(allocSize, gamma_alloc_size(rType, rData), &allocSize) ||
            !safe_add(allocSize, gamma_alloc_size(gType, gData), &allocSize) ||
            !safe_add(allocSize, gamma_alloc_size(bType, bData), &allocSize)) {
            return_null("SkGammas struct is too large to allocate");
        }
        void* memory = sk_malloc_throw(allocSize);
        gammas = sk_sp<SkGammas>(new (memory) SkGammas(3));

        uint32_t offset = 0;
        gammas->fType[0] = rType;
        offset += load_gammas(memory, offset, rType, &rData, rParams,
                                r->addr(base));

        gammas->fType[1] = gType;
        offset += load_gammas(memory, offset, gType, &gData, gParams,
                                g->addr(base));

        gammas->fType[2] = bType;
        load_gammas(memory, offset, bType, &bData, bParams, b->addr(base));

        gammas->fData[0] = rData;
        gammas->fData[1] = gData;
        gammas->fData[2] = bData;
    }


    if (kNonStandard_SkGammaNamed == gammaNamed) {
        // It's possible that we'll initially detect non-matching gammas, only for
        // them to evaluate to the same named gamma curve.
        gammaNamed = is_named(gammas);
    }

    if (kNonStandard_SkGammaNamed == gammaNamed) {
        return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(gammaNamed,
                                                        std::move(gammas),
                                                        mat, std::move(profileData)));
    }

    return SkColorSpace::MakeRGB(gammaNamed, mat);
}

static sk_sp<SkColorSpace> make_gray(const ICCProfileHeader& header, ICCTag* tags, int tagCount,
                                     const uint8_t* base, sk_sp<SkData> profileData) {
    if (kLAB_PCSSpace == header.fPCS) {
        return nullptr;
    }

    const ICCTag* grayTRC = ICCTag::Find(tags, tagCount, kTAG_kTRC);
    if (!grayTRC) {
        return_null("grayTRC tag required for monochrome profiles.");
    }
    SkGammas::Data data;
    SkColorSpaceTransferFn params;
    size_t tagBytes;
    SkGammas::Type type =
            parse_gamma(&data, &params, &tagBytes, grayTRC->addr(base), grayTRC->fLength);
    handle_invalid_gamma(&type, &data);

    SkMatrix44 toXYZD50(SkMatrix44::kIdentity_Constructor);
    toXYZD50.setFloat(0, 0, kWhitePointD50[0]);
    toXYZD50.setFloat(1, 1, kWhitePointD50[1]);
    toXYZD50.setFloat(2, 2, kWhitePointD50[2]);
    if (SkGammas::Type::kNamed_Type == type) {
        return SkColorSpace::MakeRGB(data.fNamed, toXYZD50);
    }

    size_t allocSize = sizeof(SkGammas);
    if (!safe_add(allocSize, gamma_alloc_size(type, data), &allocSize)) {
        return_null("SkGammas struct is too large to allocate");
    }
    void* memory = sk_malloc_throw(allocSize);
    sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas(3));
    load_gammas(memory, 0, type, &data, params, grayTRC->addr(base));
    for (int i = 0; i < 3; ++i) {
        gammas->fType[i] = type;
        gammas->fData[i] = data;
    }

    return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(kNonStandard_SkGammaNamed,
                                                    std::move(gammas),
                                                    toXYZD50, std::move(profileData)));
}

static sk_sp<SkColorSpace> make_a2b(SkColorSpace::Type iccType,
                                    const ICCProfileHeader& header, ICCTag* tags, int tagCount,
                                    const uint8_t* base, sk_sp<SkData> profileData) {
    const ICCTag* a2b0 = ICCTag::Find(tags, tagCount, kTAG_A2B0);
    if (a2b0) {
        const SkColorSpace_A2B::PCS pcs = kXYZ_PCSSpace == header.fPCS
                                        ? SkColorSpace_A2B::PCS::kXYZ
                                        : SkColorSpace_A2B::PCS::kLAB;
        std::vector<SkColorSpace_A2B::Element> elements;
        if (load_a2b0(&elements, a2b0->addr(base), a2b0->fLength, pcs, iccType)) {
            return sk_sp<SkColorSpace>(new SkColorSpace_A2B(iccType, std::move(elements),
                                                            pcs, std::move(profileData)));
        }
    }

    return nullptr;
}

sk_sp<SkColorSpace> SkColorSpace::MakeICC(const void* input, size_t len) {
    if (!input || len < kICCHeaderSize) {
        return_null("Data is null or not large enough to contain an ICC profile");
    }

    // Make sure we're at least as strict as skcms_Parse().
    skcms_ICCProfile p;
    if (!skcms_Parse(input, len, &p)) {
        return nullptr;
    }

    // Create our own copy of the input.
    void* memory = sk_malloc_throw(len);
    memcpy(memory, input, len);
    sk_sp<SkData> profileData = SkData::MakeFromMalloc(memory, len);
    const uint8_t* base = profileData->bytes();
    const uint8_t* ptr = base;

    // Read the ICC profile header and check to make sure that it is valid.
    ICCProfileHeader header;
    header.init(ptr, len);
    if (!header.valid()) {
        return nullptr;
    }

    // Adjust ptr and len before reading the tags.
    if (len < header.fSize) {
        SkColorSpacePrintf("ICC profile might be truncated.\n");
    } else if (len > header.fSize) {
        SkColorSpacePrintf("Caller provided extra data beyond the end of the ICC profile.\n");
        len = header.fSize;
    }
    ptr += kICCHeaderSize;
    len -= kICCHeaderSize;

    // Parse tag headers.
    uint32_t tagCount = header.fTagCount;
    SkColorSpacePrintf("ICC profile contains %d tags.\n", tagCount);
    if (len < kICCTagTableEntrySize * tagCount) {
        return_null("Not enough input data to read tag table entries");
    }

    SkAutoTArray<ICCTag> tags(tagCount);
    for (uint32_t i = 0; i < tagCount; i++) {
        ptr = tags[i].init(ptr);
        SkColorSpacePrintf("[%d] %c%c%c%c %d %d\n", i, (tags[i].fSignature >> 24) & 0xFF,
                (tags[i].fSignature >> 16) & 0xFF, (tags[i].fSignature >>  8) & 0xFF,
                (tags[i].fSignature >>  0) & 0xFF, tags[i].fOffset, tags[i].fLength);

        if (!tags[i].valid(kICCHeaderSize + len)) {
            return_null("Tag is too large to fit in ICC profile");
        }
    }

    Type a2b_type = kRGB_Type;
    switch (header.fInputColorSpace) {
        case kRGB_ColorSpace: {
            sk_sp<SkColorSpace> colorSpace =
                    make_xyz(header, tags.get(), tagCount, base, profileData);
            if (colorSpace) {
                return colorSpace;
            }
            break;
        }
        case kGray_ColorSpace: {
            return make_gray(header, tags.get(), tagCount, base, profileData);
        }
        case kCMYK_ColorSpace:
            a2b_type = kCMYK_Type;
            break;
        default:
            return_null("ICC profile contains unsupported colorspace");
    }

    return make_a2b(a2b_type, header, tags.get(), tagCount, base, profileData);
}
