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

#include "include/codec/SkAndroidCodec.h"
#include "include/codec/SkCodec.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkData.h"
#include "include/core/SkEncodedImageFormat.h"
#include "include/core/SkImageGenerator.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "include/third_party/skcms/skcms.h"
#include "src/codec/SkCodecImageGenerator.h"
#include "src/core/SkPixmapPriv.h"
#include "tests/Test.h"
#include "tools/Resources.h"

#include <string.h>
#include <initializer_list>
#include <memory>
#include <utility>

static SkISize times(const SkISize& size, float factor) {
    return { (int) (size.width() * factor), (int) (size.height() * factor) };
}

static SkISize plus(const SkISize& size, int term) {
    return { size.width() + term, size.height() + term };
}

static bool invalid(const SkISize& size) {
    return size.width() < 1 || size.height() < 1;
}

DEF_TEST(AndroidCodec_computeSampleSize, r) {
    if (GetResourcePath().isEmpty()) {
        return;
    }
    for (const char* file : { "images/color_wheel.webp",
                              "images/ship.png",
                              "images/dog.jpg",
                              "images/color_wheel.gif",
                              "images/rle.bmp",
                              "images/google_chrome.ico",
                              "images/mandrill.wbmp",
#ifdef SK_CODEC_DECODES_RAW
                              "images/sample_1mp.dng",
#endif
                              }) {
        auto data = GetResourceAsData(file);
        if (!data) {
            ERRORF(r, "Could not get %s", file);
            continue;
        }

        auto codec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(std::move(data)));
        if (!codec) {
            ERRORF(r, "Could not create codec for %s", file);
            continue;
        }

        const auto dims = codec->getInfo().dimensions();
        const SkISize downscales[] = {
            plus(dims, -1),
            times(dims, .15f),
            times(dims, .6f),
            { (int32_t) (dims.width() * .25f), (int32_t) (dims.height() * .75f ) },
            { 1,  1 },
            { 1,  2 },
            { 2,  1 },
            { 0, -1 },
            { dims.width(), dims.height() - 1 },
        };
        for (SkISize size : downscales) {
            const auto requested = size;
            const int computedSampleSize = codec->computeSampleSize(&size);
            REPORTER_ASSERT(r, size.width() >= 1 && size.height() >= 1);
            if (codec->getEncodedFormat() == SkEncodedImageFormat::kWEBP) {
                // WebP supports arbitrary down-scaling.
                REPORTER_ASSERT(r, size == requested || invalid(requested));
            } else if (computedSampleSize == 1) {
                REPORTER_ASSERT(r, size == dims);
            } else {
                REPORTER_ASSERT(r, computedSampleSize > 1);
                if (size.width() >= dims.width() || size.height() >= dims.height()) {
                    ERRORF(r, "File %s's computed sample size (%i) is bigger than"
                              " original? original: %i x %i\tsampled: %i x %i",
                              file, computedSampleSize, dims.width(), dims.height(),
                              size.width(), size.height());
                }
                REPORTER_ASSERT(r, size.width()  >= requested.width() &&
                                   size.height() >= requested.height());
                REPORTER_ASSERT(r, size.width()  <  dims.width() &&
                                   size.height() <  dims.height());
            }
        }

        const SkISize upscales[] = {
            dims, plus(dims, 5), times(dims, 2),
        };
        for (SkISize size : upscales) {
            const int computedSampleSize = codec->computeSampleSize(&size);
            REPORTER_ASSERT(r, computedSampleSize == 1);
            REPORTER_ASSERT(r, dims == size);
        }

        // This mimics how Android's ImageDecoder uses SkAndroidCodec. A client
        // can choose their dimensions based on calling getSampledDimensions,
        // but the ImageDecoder API takes an arbitrary size. It then uses
        // computeSampleSize to determine the best dimensions and sampleSize.
        // It should return the same dimensions. the sampleSize may be different
        // due to integer division.
        for (int sampleSize : { 1, 2, 3, 4, 8, 16, 32 }) {
            const SkISize sampledDims = codec->getSampledDimensions(sampleSize);
            SkISize size = sampledDims;
            const int computedSampleSize = codec->computeSampleSize(&size);
            if (sampledDims != size) {
                ERRORF(r, "File '%s'->getSampledDimensions(%i) yields computed"
                          " sample size of %i\n\tsampledDimensions: %i x %i\t"
                          "computed dimensions: %i x %i",
                          file, sampleSize, computedSampleSize,
                          sampledDims.width(), sampledDims.height(),
                          size.width(), size.height());
            }
        }
    }
}

DEF_TEST(AndroidCodec_wide, r) {
    if (GetResourcePath().isEmpty()) {
        return;
    }

    const char* path = "images/wide-gamut.png";
    auto data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Missing file %s", path);
        return;
    }

    auto codec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(std::move(data)));
    if (!codec) {
        ERRORF(r, "Failed to create codec from %s", path);
        return;
    }

    auto info = codec->getInfo();
    auto cs = codec->computeOutputColorSpace(info.colorType(), nullptr);
    if (!cs) {
        ERRORF(r, "%s should have a color space", path);
        return;
    }

    auto expected = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3);
    REPORTER_ASSERT(r, SkColorSpace::Equals(cs.get(), expected.get()));
}

DEF_TEST(AndroidCodec_P3, r) {
    if (GetResourcePath().isEmpty()) {
        return;
    }

    const char* path = "images/purple-displayprofile.png";
    auto data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Missing file %s", path);
        return;
    }

    auto codec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(std::move(data)));
    if (!codec) {
        ERRORF(r, "Failed to create codec from %s", path);
        return;
    }

    auto info = codec->getInfo();
    auto cs = codec->computeOutputColorSpace(info.colorType(), nullptr);
    if (!cs) {
        ERRORF(r, "%s should have a color space", path);
        return;
    }

    REPORTER_ASSERT(r, !cs->isSRGB());
    REPORTER_ASSERT(r, cs->gammaCloseToSRGB());

    skcms_Matrix3x3 matrix;
    cs->toXYZD50(&matrix);

    static constexpr skcms_Matrix3x3 kExpected = {{
        { 0.426254272f,  0.369018555f,  0.168914795f  },
        { 0.226013184f,  0.685974121f,  0.0880126953f },
        { 0.0116729736f, 0.0950927734f, 0.71812439f   },
    }};
    REPORTER_ASSERT(r, 0 == memcmp(&matrix, &kExpected, sizeof(skcms_Matrix3x3)));
}

DEF_TEST(AndroidCodec_orientation, r) {
    if (GetResourcePath().isEmpty()) {
        return;
    }

    for (const char* filePathFormatStr : {"images/orientation/%c_420.jpg",
                                          "images/orientation/%c.webp"})
    for (char i = '1'; i <= '8'; ++i) {
        SkString path = SkStringPrintf(filePathFormatStr, i);
        auto data = GetResourceAsData(path.c_str());
        auto gen = SkCodecImageGenerator::MakeFromEncodedCodec(data);
        if (!gen) {
            ERRORF(r, "failed to decode %s", path.c_str());
            return;
        }

        // Dimensions after adjusting for the origin.
        const SkISize expectedDims = { 100, 80 };

        // SkCodecImageGenerator automatically adjusts for the origin.
        REPORTER_ASSERT(r, gen->getInfo().dimensions() == expectedDims);

        auto androidCodec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(data));
        if (!androidCodec) {
            ERRORF(r, "failed to decode %s", path.c_str());
            return;
        }

        // SkAndroidCodec does not adjust for the origin by default. Dimensions may be reversed.
        if (SkEncodedOriginSwapsWidthHeight(androidCodec->codec()->getOrigin())) {
            auto swappedDims = SkPixmapPriv::SwapWidthHeight(androidCodec->getInfo()).dimensions();
            REPORTER_ASSERT(r, expectedDims == swappedDims);
        } else {
            REPORTER_ASSERT(r, expectedDims == androidCodec->getInfo().dimensions());
        }

        // Passing kRespect adjusts for the origin.
        androidCodec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(std::move(data)),
                SkAndroidCodec::ExifOrientationBehavior::kRespect);
        auto info = androidCodec->getInfo();
        REPORTER_ASSERT(r, info.dimensions() == expectedDims);

        SkBitmap fromGenerator;
        fromGenerator.allocPixels(info);
        REPORTER_ASSERT(r, gen->getPixels(info, fromGenerator.getPixels(),
                                          fromGenerator.rowBytes()));

        SkBitmap fromAndroidCodec;
        fromAndroidCodec.allocPixels(info);
        auto result = androidCodec->getPixels(info, fromAndroidCodec.getPixels(),
                                              fromAndroidCodec.rowBytes());
        REPORTER_ASSERT(r, result == SkCodec::kSuccess);

        for (int i = 0; i < info.width();  ++i)
        for (int j = 0; j < info.height(); ++j) {
            SkColor c1 = *fromGenerator   .getAddr32(i, j);
            SkColor c2 = *fromAndroidCodec.getAddr32(i, j);
            if (c1 != c2) {
                ERRORF(r, "Bitmaps for %s do not match starting at position %i, %i\n"
                          "\tfromGenerator: %x\tfromAndroidCodec: %x", path.c_str(), i, j,
                          c1, c2);
                return;
            }
        }
    }
}

DEF_TEST(AndroidCodec_sampledOrientation, r) {
    if (GetResourcePath().isEmpty()) {
        return;
    }

    // kRightTop_SkEncodedOrigin    = 6, // Rotated 90 CW
    auto path = "images/orientation/6_420.jpg";
    auto data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Failed to get resource %s", path);
        return;
    }

    auto androidCodec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(std::move(data)),
                SkAndroidCodec::ExifOrientationBehavior::kRespect);
    constexpr int sampleSize = 7;
    auto sampledDims = androidCodec->getSampledDimensions(sampleSize);

    SkAndroidCodec::AndroidOptions options;
    options.fSampleSize = sampleSize;

    SkBitmap bm;
    auto info = androidCodec->getInfo().makeDimensions(sampledDims);
    bm.allocPixels(info);

    auto result = androidCodec->getAndroidPixels(info, bm.getPixels(), bm.rowBytes(), &options);
    if (result != SkCodec::kSuccess) {
        ERRORF(r, "got result \"%s\"\n", SkCodec::ResultToString(result));
    }
}

DEF_TEST(AndroidCodec_animatedOrientation, r) {
    if (GetResourcePath().isEmpty()) {
        return;
    }

    static const struct {
        const char* path;
        SkEncodedOrigin origin;
    } gRec[] = {
        { "images/stoplight.webp",   kDefault_SkEncodedOrigin },
        { "images/stoplight_h.webp", kLeftBottom_SkEncodedOrigin } // Rotated 90 CCW
    };
    for (auto rec : gRec) {
        auto data = GetResourceAsData(rec.path);
        if (!data) {
            ERRORF(r, "Failed to get resource %s", rec.path);
            return;
        }

        // SkAndroidCodec now allows decoding frames beyond the first, but combining this with
        // kRespect-ing a non-kDefault_SkEncodedOrigin is not supported. If a frame depends on
        // a prior frame, we allow a client to provide that prior frame. But in order to respect
        // the origin, we would need to transform the prior frame back to the original orientation
        // in order to blend (and potentially erase, for a kRestoreBG frame) just to transform it
        // back. Instead, force the client to handle the orientation after the fact.
        for (auto behavior : { SkAndroidCodec::ExifOrientationBehavior::kRespect,
                               SkAndroidCodec::ExifOrientationBehavior::kIgnore   }) {
            auto androidCodec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(data),
                                                              behavior);
            REPORTER_ASSERT(r, androidCodec->codec()->getOrigin() == rec.origin);

            auto info = androidCodec->getInfo();
            SkBitmap bm;
            bm.allocPixels(info);
            auto result = androidCodec->getAndroidPixels(info, bm.getPixels(), bm.rowBytes());
            REPORTER_ASSERT(r, result == SkCodec::kSuccess);

            SkAndroidCodec::AndroidOptions options;
            options.fFrameIndex = 1;
            options.fPriorFrame = 0;
            result = androidCodec->getAndroidPixels(info, bm.getPixels(), bm.rowBytes(), &options);
            switch (behavior) {
                case SkAndroidCodec::ExifOrientationBehavior::kRespect:
                    if (rec.origin != kDefault_SkEncodedOrigin) {
                        REPORTER_ASSERT(r, result == SkCodec::kInvalidParameters,
                                "Should not be able to decode frame 1 with exif orientation"
                                " directly! Result: %s", SkCodec::ResultToString(result));
                        break;
                    }
                    [[fallthrough]];
                case SkAndroidCodec::ExifOrientationBehavior::kIgnore:
                    REPORTER_ASSERT(r, result == SkCodec::kSuccess);
                    break;
            }
        }
    }
}
