/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#define LOG_TAG "AImageDecoderTest"

#include <jni.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <android/data_space.h>
#include <android/bitmap.h>
#include <android/imagedecoder.h>
#include <android/rect.h>

#include "NativeTestHelpers.h"

#include <cstdlib>
#include <cstring>
#include <initializer_list>
#include <limits>
#include <memory>
#include <stdio.h>
#include <unistd.h>
#include <vector>

#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

using AssetCloser = std::unique_ptr<AAsset, decltype(&AAsset_close)>;
using DecoderDeleter = std::unique_ptr<AImageDecoder, decltype(&AImageDecoder_delete)>;

static void testEmptyCreate(JNIEnv* env, jclass) {
    AImageDecoder* decoderPtr = nullptr;
    for (AImageDecoder** outDecoder : { &decoderPtr, (AImageDecoder**) nullptr }) {
        for (AAsset* asset : { nullptr }) {
            int result = AImageDecoder_createFromAAsset(asset, outDecoder);
            ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
            if (outDecoder) {
                ASSERT_EQ(nullptr, *outDecoder);
            }
        }

        for (int fd : { 0, -1 }) {
            int result = AImageDecoder_createFromFd(fd, outDecoder);
            ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
            if (outDecoder) {
                ASSERT_EQ(nullptr, *outDecoder);
            }
        }

        auto testEmptyBuffer = [env, outDecoder](void* buffer, size_t length) {
            int result = AImageDecoder_createFromBuffer(buffer, length, outDecoder);
            ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
            if (outDecoder) {
                ASSERT_EQ(nullptr, *outDecoder);
            }
        };
        testEmptyBuffer(nullptr, 0);
        char buf[4];
        testEmptyBuffer(buf, 0);
    }
}

static AAsset* openAsset(JNIEnv* env, jobject jAssets, jstring jFile, int mode) {
    AAssetManager* nativeManager = AAssetManager_fromJava(env, jAssets);
    const char* file = env->GetStringUTFChars(jFile, nullptr);
    AAsset* asset = AAssetManager_open(nativeManager, file, mode);
    if (!asset) {
        ALOGE("Could not open %s", file);
    } else {
        ALOGD("Testing %s", file);
    }
    env->ReleaseStringUTFChars(jFile, file);
    return asset;
}

static void testNullDecoder(JNIEnv* env, jclass, jobject jAssets, jstring jFile) {
    AAsset* asset = openAsset(env, jAssets, jFile, AASSET_MODE_BUFFER);
    ASSERT_NE(asset, nullptr);
    AssetCloser assetCloser(asset, AAsset_close);

    AImageDecoder_delete(nullptr);

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull"
    {
        int result = AImageDecoder_createFromAAsset(asset, nullptr);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
    }

    {
        const void* buffer = AAsset_getBuffer(asset);
        ASSERT_NE(buffer, nullptr);

        int result = AImageDecoder_createFromBuffer(buffer, AAsset_getLength(asset), nullptr);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
    }

    {
        off_t start, length;
        int fd = AAsset_openFileDescriptor(asset, &start, &length);
        ASSERT_GT(fd, 0);

        off_t offset = ::lseek(fd, start, SEEK_SET);
        ASSERT_EQ(start, offset);

        int result = AImageDecoder_createFromFd(fd, nullptr);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
        close(fd);
    }

    {
        auto stride = AImageDecoder_getMinimumStride(nullptr);
        ASSERT_EQ(0, stride);
    }

    {
        char buf[4];
        int result = AImageDecoder_decodeImage(nullptr, buf, 4, 4);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
    }

    {
        int result = AImageDecoder_setAndroidBitmapFormat(nullptr, ANDROID_BITMAP_FORMAT_RGBA_8888);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);

        auto format = AImageDecoderHeaderInfo_getAndroidBitmapFormat(nullptr);
        ASSERT_EQ(ANDROID_BITMAP_FORMAT_NONE, format);
    }

    {
        int result = AImageDecoder_setUnpremultipliedRequired(nullptr, true);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);

        int alpha = AImageDecoderHeaderInfo_getAlphaFlags(nullptr);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, alpha);
    }

    ASSERT_EQ(0, AImageDecoderHeaderInfo_getWidth(nullptr));
    ASSERT_EQ(0, AImageDecoderHeaderInfo_getHeight(nullptr));
    ASSERT_EQ(nullptr, AImageDecoderHeaderInfo_getMimeType(nullptr));
    ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, AImageDecoderHeaderInfo_getDataSpace(nullptr));

    {
        int result = AImageDecoder_setTargetSize(nullptr, 1, 1);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
    }
    {
        ARect rect {0, 0, 10, 10};
        int result = AImageDecoder_setCrop(nullptr, rect);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
    }

    for (ADataSpace dataSpace : { ADATASPACE_UNKNOWN, ADATASPACE_SCRGB_LINEAR, ADATASPACE_SRGB,
                                  ADATASPACE_SCRGB, ADATASPACE_DISPLAY_P3, ADATASPACE_BT2020_PQ,
                                  ADATASPACE_ADOBE_RGB, ADATASPACE_BT2020, ADATASPACE_BT709,
                                  ADATASPACE_DCI_P3, ADATASPACE_SRGB_LINEAR }) {
        int result = AImageDecoder_setDataSpace(nullptr, dataSpace);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
    }

    ASSERT_FALSE(AImageDecoder_isAnimated(nullptr));

    {
        int result = AImageDecoder_getRepeatCount(nullptr);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
    }
#pragma clang diagnostic pop
}

static void testInfo(JNIEnv* env, jclass, jlong imageDecoderPtr, jint width, jint height,
                     jstring jMimeType, jboolean isF16, jint dataSpace) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    ASSERT_NE(decoder, nullptr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
    ASSERT_NE(info, nullptr);
    int32_t actualWidth = AImageDecoderHeaderInfo_getWidth(info);
    ASSERT_EQ(width, actualWidth);
    int32_t actualHeight = AImageDecoderHeaderInfo_getHeight(info);
    ASSERT_EQ(height, actualHeight);

    const char* mimeType = env->GetStringUTFChars(jMimeType, nullptr);
    ASSERT_NE(mimeType, nullptr);
    ASSERT_EQ(0, strcmp(mimeType, AImageDecoderHeaderInfo_getMimeType(info)));
    env->ReleaseStringUTFChars(jMimeType, mimeType);
    auto format = AImageDecoderHeaderInfo_getAndroidBitmapFormat(info);
    if (isF16) {
        ASSERT_EQ(ANDROID_BITMAP_FORMAT_RGBA_F16, format);
    } else {
        ASSERT_EQ(ANDROID_BITMAP_FORMAT_RGBA_8888, format);
    }

    ASSERT_EQ(dataSpace, AImageDecoderHeaderInfo_getDataSpace(info));
}

static jlong openAssetNative(JNIEnv* env, jclass, jobject jAssets, jstring jFile) {
    // FIXME: Test the other modes? Or more to the point, pass in the mode? It
    // seems that when we want a buffer we should use AASSET_MODE_BUFFER.
    AAsset* asset = openAsset(env, jAssets, jFile, AASSET_MODE_UNKNOWN);
    if (!asset) {
        fail(env, "Failed to open native asset!");
    }
    return reinterpret_cast<jlong>(asset);
}

static void closeAsset(JNIEnv*, jclass, jlong asset) {
    AAsset_close(reinterpret_cast<AAsset*>(asset));
}

static jlong createFromAsset(JNIEnv* env, jclass, jlong asset) {
    AImageDecoder* decoder = nullptr;
    int result = AImageDecoder_createFromAAsset(reinterpret_cast<AAsset*>(asset), &decoder);
    if (ANDROID_IMAGE_DECODER_SUCCESS != result || !decoder) {
        fail(env, "Failed to create AImageDecoder!");
    }
    return reinterpret_cast<jlong>(decoder);
}

static jlong createFromFd(JNIEnv* env, jclass, int fd) {
    AImageDecoder* decoder = nullptr;
    int result = AImageDecoder_createFromFd(fd, &decoder);
    if (ANDROID_IMAGE_DECODER_SUCCESS != result || !decoder) {
        fail(env, "Failed to create AImageDecoder!");
    }
    return reinterpret_cast<jlong>(decoder);
}

static jlong createFromAssetFd(JNIEnv* env, jclass, jlong assetPtr) {
    AAsset* asset = reinterpret_cast<AAsset*>(assetPtr);
    off_t start, length;
    int fd = AAsset_openFileDescriptor(asset, &start, &length);
    if (fd <= 0) {
        fail(env, "Failed to open file descriptor!");
        return -1;
    }

    off_t offset = ::lseek(fd, start, SEEK_SET);
    if (offset != start) {
        fail(env, "Failed to seek file descriptor!");
        return -1;
    }

    return createFromFd(env, nullptr, fd);
}

static jlong createFromAssetBuffer(JNIEnv* env, jclass, jlong assetPtr) {
    AAsset* asset = reinterpret_cast<AAsset*>(assetPtr);
    const void* buffer = AAsset_getBuffer(asset);
    if (!buffer) {
        fail(env, "AAsset_getBuffer failed!");
        return -1;
    }

    AImageDecoder* decoder = nullptr;
    int result = AImageDecoder_createFromBuffer(buffer, AAsset_getLength(asset), &decoder);
    if (ANDROID_IMAGE_DECODER_SUCCESS != result || !decoder) {
        fail(env, "AImageDecoder_createFromBuffer failed!");
        return -1;
    }
    return reinterpret_cast<jlong>(decoder);
}

static void testCreateIncomplete(JNIEnv* env, jclass, jobject jAssets, jstring jFile,
                                 jint truncatedLength) {
    AAsset* asset = openAsset(env, jAssets, jFile, AASSET_MODE_UNKNOWN);
    ASSERT_NE(asset, nullptr);
    AssetCloser assetCloser(asset, AAsset_close);

    const void* buffer = AAsset_getBuffer(asset);
    ASSERT_NE(buffer, nullptr);

    AImageDecoder* decoder;
    int result = AImageDecoder_createFromBuffer(buffer, truncatedLength, &decoder);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_INCOMPLETE, result);
    ASSERT_EQ(decoder, nullptr);
}

static void testCreateUnsupported(JNIEnv* env, jclass, jobject jAssets, jstring jFile) {
    AAsset* asset = openAsset(env, jAssets, jFile, AASSET_MODE_UNKNOWN);
    ASSERT_NE(asset, nullptr);
    AssetCloser assetCloser(asset, AAsset_close);

    AImageDecoder* decoder;
    int result = AImageDecoder_createFromAAsset(asset, &decoder);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT, result);
    ASSERT_EQ(decoder, nullptr);
}

static void testSetFormat(JNIEnv* env, jclass, jlong imageDecoderPtr,
                          jboolean isF16, jboolean isGray) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
    ASSERT_NE(info, nullptr);

    // Store the format so we can ensure that it doesn't change when we call
    // AImageDecoder_setAndroidBitmapFormat.
    const auto format = AImageDecoderHeaderInfo_getAndroidBitmapFormat(info);
    if (isF16) {
        ASSERT_EQ(ANDROID_BITMAP_FORMAT_RGBA_F16, format);
    } else {
        ASSERT_EQ(ANDROID_BITMAP_FORMAT_RGBA_8888, format);
    }

    int result = AImageDecoder_setAndroidBitmapFormat(decoder, ANDROID_BITMAP_FORMAT_A_8);
    if (isGray) {
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
    } else {
        ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_CONVERSION, result);
    }
    ASSERT_EQ(format, AImageDecoderHeaderInfo_getAndroidBitmapFormat(info));

    result = AImageDecoder_setAndroidBitmapFormat(decoder, ANDROID_BITMAP_FORMAT_RGB_565);
    int alpha = AImageDecoderHeaderInfo_getAlphaFlags(info);
    if (alpha == ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE) {
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
    } else {
        ASSERT_EQ(ANDROID_BITMAP_FLAGS_ALPHA_PREMUL, alpha);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_CONVERSION, result);
    }
    ASSERT_EQ(format, AImageDecoderHeaderInfo_getAndroidBitmapFormat(info));

    for (auto newFormat : { ANDROID_BITMAP_FORMAT_RGBA_4444, ANDROID_BITMAP_FORMAT_NONE }) {
        result = AImageDecoder_setAndroidBitmapFormat(decoder, newFormat);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_CONVERSION, result);
        ASSERT_EQ(format, AImageDecoderHeaderInfo_getAndroidBitmapFormat(info));
    }

    for (auto newFormat : { ANDROID_BITMAP_FORMAT_RGBA_8888, ANDROID_BITMAP_FORMAT_RGBA_F16 }) {
        result = AImageDecoder_setAndroidBitmapFormat(decoder, newFormat);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
        ASSERT_EQ(format, AImageDecoderHeaderInfo_getAndroidBitmapFormat(info));
    }

    for (auto invalidFormat : { -1, 42, 67 }) {
        result = AImageDecoder_setAndroidBitmapFormat(decoder, invalidFormat);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
        ASSERT_EQ(format, AImageDecoderHeaderInfo_getAndroidBitmapFormat(info));
    }
}

static void testSetUnpremul(JNIEnv* env, jclass, jlong imageDecoderPtr, jboolean hasAlpha) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
    ASSERT_NE(info, nullptr);

    // Store the alpha so we can ensure that it doesn't change when we call
    // AImageDecoder_setUnpremultipliedRequired.
    const int alpha = AImageDecoderHeaderInfo_getAlphaFlags(info);
    if (hasAlpha) {
        ASSERT_EQ(ANDROID_BITMAP_FLAGS_ALPHA_PREMUL, alpha);
    } else {
        ASSERT_EQ(ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE, alpha);
    }

    for (bool required : { true, false }) {
        int result = AImageDecoder_setUnpremultipliedRequired(decoder, required);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
        ASSERT_EQ(alpha, AImageDecoderHeaderInfo_getAlphaFlags(info));
    }
}

static int bytesPerPixel(int32_t format) {
    switch (format) {
        case ANDROID_BITMAP_FORMAT_RGBA_8888:
            return 4;
        case ANDROID_BITMAP_FORMAT_RGB_565:
            return 2;
        case ANDROID_BITMAP_FORMAT_A_8:
            return 1;
        case ANDROID_BITMAP_FORMAT_RGBA_F16:
            return 8;
        case ANDROID_BITMAP_FORMAT_NONE:
        case ANDROID_BITMAP_FORMAT_RGBA_4444:
        default:
            return 0;
    }
}

static void testGetMinimumStride(JNIEnv* env, jclass, jlong imageDecoderPtr,
                                 jboolean isF16, jboolean isGray) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
    ASSERT_NE(info, nullptr);

    const int32_t width = AImageDecoderHeaderInfo_getWidth(info);
    size_t stride = AImageDecoder_getMinimumStride(decoder);

    if (isF16) {
        ASSERT_EQ(bytesPerPixel(ANDROID_BITMAP_FORMAT_RGBA_F16) * width, stride);
    } else {
        ASSERT_EQ(bytesPerPixel(ANDROID_BITMAP_FORMAT_RGBA_8888) * width, stride);
    }

    auto setFormatAndCheckStride = [env, decoder, width, &stride](AndroidBitmapFormat format) {
        int result = AImageDecoder_setAndroidBitmapFormat(decoder, format);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

        stride = AImageDecoder_getMinimumStride(decoder);
        ASSERT_EQ(bytesPerPixel(format) * width, stride);
    };

    int alpha = AImageDecoderHeaderInfo_getAlphaFlags(info);
    if (alpha == ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE) {
        setFormatAndCheckStride(ANDROID_BITMAP_FORMAT_RGB_565);
    }

    if (isGray) {
        setFormatAndCheckStride(ANDROID_BITMAP_FORMAT_A_8);
    }

    for (auto newFormat : { ANDROID_BITMAP_FORMAT_RGBA_8888, ANDROID_BITMAP_FORMAT_RGBA_F16 }) {
        setFormatAndCheckStride(newFormat);
    }

    for (auto badFormat : { ANDROID_BITMAP_FORMAT_RGBA_4444, ANDROID_BITMAP_FORMAT_NONE }) {
        int result = AImageDecoder_setAndroidBitmapFormat(decoder, badFormat);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_CONVERSION, result);

        // Stride is unchanged.
        ASSERT_EQ(stride, AImageDecoder_getMinimumStride(decoder));
    }
}

static bool bitmapsEqual(size_t minStride, int height,
                         void* pixelsA, size_t strideA,
                         void* pixelsB, size_t strideB) {
    for (int y = 0; y < height; ++y) {
        auto* rowA = reinterpret_cast<char*>(pixelsA) + strideA * y;
        auto* rowB = reinterpret_cast<char*>(pixelsB) + strideB * y;
        if (memcmp(rowA, rowB, minStride) != 0) {
            ALOGE("Bitmap mismatch on line %i", y);
            return false;
        }
    }
    return true;
}

#define EXPECT_EQ(msg, a, b)    \
    if ((a) != (b)) {           \
        ALOGE(msg);             \
        return false;           \
    }

#define EXPECT_GE(msg, a, b)    \
    if ((a) < (b)) {            \
        ALOGE(msg);             \
        return false;           \
    }

static bool bitmapsEqual(JNIEnv* env, jobject jbitmap, int32_t androidBitmapFormat,
                         int width, int height, int alphaFlags, size_t minStride,
                         void* pixelsA, size_t strideA) {
    AndroidBitmapInfo jInfo;
    int bitmapResult = AndroidBitmap_getInfo(env, jbitmap, &jInfo);
    EXPECT_EQ("Failed to getInfo on Bitmap", ANDROID_BITMAP_RESULT_SUCCESS, bitmapResult);

    EXPECT_EQ("Wrong format", jInfo.format, androidBitmapFormat);

    // If the image is truly opaque, the Java Bitmap will report OPAQUE, even if
    // the AImageDecoder requested PREMUL/UNPREMUL. In that case, it is okay for
    // the two to disagree. We must ensure that we don't end up with one PREMUL
    // and the other UNPREMUL, though.
    int jAlphaFlags = jInfo.flags & ANDROID_BITMAP_FLAGS_ALPHA_MASK;
    if (jAlphaFlags != ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE
            && alphaFlags != ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE) {
        EXPECT_EQ("Wrong alpha type", jAlphaFlags, alphaFlags);
    }

    EXPECT_EQ("Wrong width", jInfo.width, width);
    EXPECT_EQ("Wrong height", jInfo.height, height);

    EXPECT_GE("Stride too small", jInfo.stride, minStride);

    void* jPixels;
    bitmapResult = AndroidBitmap_lockPixels(env, jbitmap, &jPixels);
    EXPECT_EQ("Failed to lockPixels", ANDROID_BITMAP_RESULT_SUCCESS, bitmapResult);

    bool equal = bitmapsEqual(minStride, height, pixelsA, strideA, jPixels, jInfo.stride);

    bitmapResult = AndroidBitmap_unlockPixels(env, jbitmap);
    EXPECT_EQ("Failed to unlockPixels", ANDROID_BITMAP_RESULT_SUCCESS, bitmapResult);

    return equal;
}

static void testDecode(JNIEnv* env, jclass, jlong imageDecoderPtr,
                       jint androidBitmapFormat, jboolean unpremul, jobject jbitmap) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
    ASSERT_NE(info, nullptr);

    int result;
    int alphaFlags = AImageDecoderHeaderInfo_getAlphaFlags(info);
    if (androidBitmapFormat == ANDROID_BITMAP_FORMAT_NONE) {
        androidBitmapFormat = AImageDecoderHeaderInfo_getAndroidBitmapFormat(info);
    } else {
        result = AImageDecoder_setAndroidBitmapFormat(decoder, androidBitmapFormat);
        if (androidBitmapFormat == ANDROID_BITMAP_FORMAT_RGB_565) {
            if (alphaFlags != ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE) {
                ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_CONVERSION, result);

                // The caller only passes down the Bitmap if it is opaque.
                ASSERT_EQ(nullptr, jbitmap);
                return;
            }
        }
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
    }

    if (unpremul) {
        result = AImageDecoder_setUnpremultipliedRequired(decoder, true);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
        alphaFlags = ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL;
    }

    const int32_t width = AImageDecoderHeaderInfo_getWidth(info);
    const int32_t height = AImageDecoderHeaderInfo_getHeight(info);
    size_t minStride = AImageDecoder_getMinimumStride(decoder);

    size_t size = minStride * height;
    std::unique_ptr<char[]> pixelsBuffer(new char[size]);
    void* pixels = (void*) pixelsBuffer.get();

    {
        // Try some invalid parameters.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull"
        result = AImageDecoder_decodeImage(decoder, nullptr, minStride, size);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
#pragma clang diagnostic pop

        result = AImageDecoder_decodeImage(decoder, pixels, minStride - 1, size);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);

        result = AImageDecoder_decodeImage(decoder, pixels, minStride, size - minStride);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);

        result = AImageDecoder_decodeImage(decoder, pixels, 0, size);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
    }

    result = AImageDecoder_decodeImage(decoder, pixels, minStride, size);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

    ASSERT_NE(jbitmap, nullptr);
    ASSERT_TRUE(bitmapsEqual(env, jbitmap, (AndroidBitmapFormat) androidBitmapFormat,
                             width, height, alphaFlags, minStride, pixels, minStride));

    // Setting to an invalid data space is unsupported, and has no effect on the
    // decodes below.
    for (int32_t dataSpace : std::initializer_list<int32_t>{ -1, ADATASPACE_UNKNOWN, 400 }) {
        result = AImageDecoder_setDataSpace(decoder, dataSpace);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
    }

    // Used for subsequent decodes, to ensure they are identical to the
    // original. For opaque images, this verifies that using PREMUL or UNPREMUL
    // look the same. For all images, this verifies that decodeImage can be
    // called multiple times.
    auto decodeAgain = [=](bool unpremultipliedRequired) {
        int r = AImageDecoder_setUnpremultipliedRequired(decoder, unpremultipliedRequired);
        if (ANDROID_IMAGE_DECODER_SUCCESS != r) {
            fail(env, "Failed to set alpha");
            return false;
        }

        std::unique_ptr<char[]> otherPixelsBuffer(new char[size]);
        void* otherPixels = (void*) otherPixelsBuffer.get();
        r = AImageDecoder_decodeImage(decoder, otherPixels, minStride, size);
        if (ANDROID_IMAGE_DECODER_SUCCESS != r) {
            fail(env, "Failed to decode again with different settings");
            return false;
        }

        if (!bitmapsEqual(minStride, height, pixels, minStride, otherPixels, minStride)) {
            fail(env, "Decoding again with different settings did not match!");
            return false;
        }
        return true;
    };
    if (alphaFlags == ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE) {
        for (bool unpremultipliedRequired: { true, false }) {
            if (!decodeAgain(unpremultipliedRequired)) return;
        }
    } else {
        if (!decodeAgain(unpremul)) return;
    }

    if (androidBitmapFormat == ANDROID_BITMAP_FORMAT_A_8) {
        // Attempting to set an ADataSpace is ignored by an A_8 decode.
        for (ADataSpace dataSpace : { ADATASPACE_DCI_P3, ADATASPACE_ADOBE_RGB }) {
            result = AImageDecoder_setDataSpace(decoder, dataSpace);
            ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
            if (!decodeAgain(alphaFlags)) return;
        }
    }
}

static void testDecodeStride(JNIEnv* env, jclass, jlong imageDecoderPtr) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
    ASSERT_NE(info, nullptr);

    const int height = AImageDecoderHeaderInfo_getHeight(info);
    const int origWidth = AImageDecoderHeaderInfo_getWidth(info);

    for (int width : { origWidth, origWidth / 3 }) {
        if (width == 0) {
            // The 1 x 1 image cannot be downscaled.
            continue;
        }
        int result = AImageDecoder_setTargetSize(decoder, width, height);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
        for (AndroidBitmapFormat format : {
            ANDROID_BITMAP_FORMAT_RGBA_8888,
            ANDROID_BITMAP_FORMAT_RGB_565,
            ANDROID_BITMAP_FORMAT_A_8,
            ANDROID_BITMAP_FORMAT_RGBA_F16,
        }) {
            result = AImageDecoder_setAndroidBitmapFormat(decoder, format);
            if (result != ANDROID_IMAGE_DECODER_SUCCESS) {
                // Not all images can be decoded to all formats. This is okay, and
                // we've tested that we can decode to the expected formats elsewhere.
                continue;
            }

            size_t minStride = AImageDecoder_getMinimumStride(decoder);
            void* pixels = nullptr;

            // The code in the below loop relies on minStride being used first.
            std::vector<size_t> strides;
            strides.push_back(minStride);
            for (int i = 1; i <= 16; i++) {
                strides.push_back(i + minStride);
            }
            strides.push_back(minStride * 2);
            strides.push_back(minStride * 3);
            for (size_t stride : strides) {
                size_t size = stride * (height - 1) + minStride;
                std::unique_ptr<char[]> decodePixelsBuffer(new char[size]);
                void* decodePixels = (void*) decodePixelsBuffer.get();
                result = AImageDecoder_decodeImage(decoder, decodePixels, stride, size);
                if ((stride - minStride) % bytesPerPixel(format) != 0) {
                    // The stride is not pixel aligned.
                    ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
                    continue;
                }
                ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

                if (pixels == nullptr) {
                    pixels = (void*) decodePixelsBuffer.release();
                } else {
                    ASSERT_TRUE(bitmapsEqual(minStride, height, pixels, minStride, decodePixels,
                                             stride));
                }
            }
        }
    }
}

static void testSetTargetSize(JNIEnv* env, jclass, jlong imageDecoderPtr) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    const size_t defaultStride = AImageDecoder_getMinimumStride(decoder);

    for (int32_t width : { -1, 0, -500 }) {
        int result = AImageDecoder_setTargetSize(decoder, width, 100);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_SCALE, result);
        // stride is unchanged, as the target size did not change.
        ASSERT_EQ(defaultStride, AImageDecoder_getMinimumStride(decoder));
    }

    for (int32_t height : { -1, 0, -300 }) {
        int result = AImageDecoder_setTargetSize(decoder, 100, height);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_SCALE, result);
        // stride is unchanged, as the target size did not change.
        ASSERT_EQ(defaultStride, AImageDecoder_getMinimumStride(decoder));
    }

    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
    ASSERT_NE(info, nullptr);
    const int bpp = bytesPerPixel(AImageDecoderHeaderInfo_getAndroidBitmapFormat(info));

    for (int32_t width : { 7, 100, 275, 300 }) {
        int result = AImageDecoder_setTargetSize(decoder, width, 100);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

        size_t actualStride = AImageDecoder_getMinimumStride(decoder);
        size_t expectedStride = bpp * width;
        ASSERT_EQ(expectedStride, actualStride);
    }

    // Verify that setting a large enough width to overflow 31 bits fails.
    constexpr auto kMaxInt32 = std::numeric_limits<int32_t>::max();
    int32_t maxWidth = kMaxInt32 / bpp;
    for (int32_t width : { maxWidth / 2, maxWidth - 1, maxWidth }) {
        int result = AImageDecoder_setTargetSize(decoder, width, 1);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

        size_t actualStride = AImageDecoder_getMinimumStride(decoder);
        size_t expectedStride = bpp * width;
        ASSERT_EQ(expectedStride, actualStride);
    }

    for (int32_t width : { maxWidth + 1, (int32_t) (maxWidth * 1.5) }) {
        int result = AImageDecoder_setTargetSize(decoder, width, 1);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_SCALE, result);
    }

    // A height that results in overflowing 31 bits also fails.
    int32_t maxHeight = kMaxInt32 / defaultStride;
    const int32_t width = AImageDecoderHeaderInfo_getWidth(info);
    for (int32_t height : { maxHeight / 2, maxHeight - 1, maxHeight }) {
        int result = AImageDecoder_setTargetSize(decoder, width, height);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

        size_t actualStride = AImageDecoder_getMinimumStride(decoder);
        size_t expectedStride = bpp * width;
        ASSERT_EQ(expectedStride, actualStride);
    }

    for (int32_t height : { maxHeight + 1, (int32_t) (maxHeight * 1.5) }) {
        int result = AImageDecoder_setTargetSize(decoder, width, height);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_SCALE, result);
    }
}

struct SampledSizeParams {
    AImageDecoder* decoder;
    int sampleSize;
    int32_t* width;
    int32_t* height;
};

static void testComputeSampledSize(JNIEnv* env, jclass, jlong imageDecoderPtr,
                                   jobject jbitmap, jint sampleSize) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
    ASSERT_NE(info, nullptr);
    const int32_t origWidth = AImageDecoderHeaderInfo_getWidth(info);
    const int32_t origHeight = AImageDecoderHeaderInfo_getHeight(info);

    int32_t width, height;
    // Test some bad parameters.
    for (SampledSizeParams p : std::initializer_list<SampledSizeParams>{
        { nullptr, 2, &width, &height },
        { decoder, 0, &width, &height },
        { decoder, -1, &width, &height },
        { decoder, 2, nullptr, &height },
        { decoder, 2, &width, nullptr },
    }) {
        int result = AImageDecoder_computeSampledSize(p.decoder, p.sampleSize, p.width, p.height);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
    }

    // Verify that width and height will never be less than one.
    for (SampledSizeParams p : std::initializer_list<SampledSizeParams>{
        { decoder, origWidth, &width, &height },
        { decoder, origWidth + 5, &width, &height },
        { decoder, origWidth * 2, &width, &height },
        { decoder, origHeight, &width, &height },
        { decoder, origHeight + 5, &width, &height },
        { decoder, origHeight * 2, &width, &height },
    }) {
        width = height = 0;
        int result = AImageDecoder_computeSampledSize(p.decoder, p.sampleSize, p.width, p.height);
        if (ANDROID_IMAGE_DECODER_SUCCESS != result) {
            fail(env, "computeSampledSize(%i) failed on image with dims %i x %i",
                 p.sampleSize, origWidth, origHeight);
            return;
        }

        ASSERT_GE(width, 1);
        ASSERT_GE(height, 1);
    }

    // jbitmap was created with the same sampleSize. Verify that AImageDecoder
    // computes the same output dimensions, that using those dimensions succeeds
    // with AImageDecoder, and the output matches.
    AndroidBitmapInfo jInfo;
    int bitmapResult = AndroidBitmap_getInfo(env, jbitmap, &jInfo);
    ASSERT_EQ(ANDROID_BITMAP_RESULT_SUCCESS, bitmapResult);

    width = height = 0;
    int result = AImageDecoder_computeSampledSize(decoder, sampleSize, &width, &height);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

    if (jInfo.width != width) {
        fail(env, "Orig image: %i x %i sampled by %i yields %i x %i expected %i x %i",
             origWidth, origHeight, sampleSize, width, height, jInfo.width, jInfo.height);
        return;
    }
    ASSERT_EQ(jInfo.width, width);
    ASSERT_EQ(jInfo.height, height);
    {

        ASSERT_LT(width, origWidth);
        ASSERT_LT(height, origHeight);

        ASSERT_LT(width, origWidth / sampleSize + sampleSize);
        ASSERT_LT(height, origHeight / sampleSize + sampleSize);
    }

    result = AImageDecoder_setTargetSize(decoder, width, height);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

    size_t minStride = AImageDecoder_getMinimumStride(decoder);
    size_t size = minStride * height;
    std::unique_ptr<char[]> pixelsBuffer(new char[size]);
    void* pixels = (void*) pixelsBuffer.get();
    result = AImageDecoder_decodeImage(decoder, pixels, minStride, size);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

    ASSERT_TRUE(bitmapsEqual(env, jbitmap, AImageDecoderHeaderInfo_getAndroidBitmapFormat(info),
                             width, height, AImageDecoderHeaderInfo_getAlphaFlags(info),
                             minStride, pixels, minStride));
}

static void testDecodeScaled(JNIEnv* env, jclass, jlong imageDecoderPtr,
                             jobject jbitmap) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    AndroidBitmapInfo jInfo;
    int bitmapResult = AndroidBitmap_getInfo(env, jbitmap, &jInfo);
    ASSERT_EQ(ANDROID_BITMAP_RESULT_SUCCESS, bitmapResult);

    int result = AImageDecoder_setTargetSize(decoder, jInfo.width, jInfo.height);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

    size_t minStride = AImageDecoder_getMinimumStride(decoder);
    size_t size = minStride * jInfo.height;
    std::unique_ptr<char[]> pixelsBuffer(new char[size]);
    void* pixels = (void*) pixelsBuffer.get();

    {
        // Try some invalid parameters.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull"
        result = AImageDecoder_decodeImage(decoder, nullptr, minStride, size);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
#pragma clang diagnostic pop

        result = AImageDecoder_decodeImage(decoder, pixels, minStride - 1, size);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);

        result = AImageDecoder_decodeImage(decoder, pixels, minStride, size - minStride);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
    }

    result = AImageDecoder_decodeImage(decoder, pixels, minStride, size);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
    ASSERT_NE(info, nullptr);

    ASSERT_NE(jbitmap, nullptr);
    ASSERT_TRUE(bitmapsEqual(env, jbitmap, AImageDecoderHeaderInfo_getAndroidBitmapFormat(info),
                             jInfo.width, jInfo.height, AImageDecoderHeaderInfo_getAlphaFlags(info),
                             minStride, pixels, minStride));

    // Verify that larger strides still behave as expected.
    for (size_t stride : { minStride * 2, minStride * 3 }) {
        size_t size = stride * (jInfo.height - 1) + minStride;
        std::unique_ptr<char[]> decodePixelsBuffer(new char[size]);
        void* decodePixels = (void*) decodePixelsBuffer.get();
        result = AImageDecoder_decodeImage(decoder, decodePixels, stride, size);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

        ASSERT_TRUE(bitmapsEqual(minStride, jInfo.height, pixels, minStride, decodePixels, stride));
    }
}

static void testSetCrop(JNIEnv* env, jclass, jobject jAssets, jstring jFile) {
    AAsset* asset = openAsset(env, jAssets, jFile, AASSET_MODE_UNKNOWN);
    ASSERT_NE(asset, nullptr);
    AssetCloser assetCloser(asset, AAsset_close);

    AImageDecoder* decoder;
    int result = AImageDecoder_createFromAAsset(asset, &decoder);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
    ASSERT_NE(decoder, nullptr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
    ASSERT_NE(info, nullptr);

    const int32_t width = AImageDecoderHeaderInfo_getWidth(info);
    const int32_t height = AImageDecoderHeaderInfo_getHeight(info);
    const auto format = AImageDecoderHeaderInfo_getAndroidBitmapFormat(info);
    const size_t defaultStride = AImageDecoder_getMinimumStride(decoder);

    if (width == 1 && height == 1) {
        // The more general crop tests do not map well to this image. Test 1 x 1
        // specifically.
        for (ARect invalidCrop : std::initializer_list<ARect> {
                { -1, 0, width, height },
                { 0, -1, width, height },
                { width, 0, 2 * width, height },
                { 0, height, width, 2 * height },
                { 1, 0, width + 1, height },
                { 0, 1, width, height + 1 },
                { 0, 0, 0, height },
                { 0, 0, width, 0 },
        }) {
            int result = AImageDecoder_setCrop(decoder, invalidCrop);
            ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
            ASSERT_EQ(defaultStride, AImageDecoder_getMinimumStride(decoder));
        }
        return;
    }

    for (ARect invalidCrop : std::initializer_list<ARect> {
            { -1, 0, width, height },
            { 0, -1, width, height },
            { width, 0, 2 * width, height },
            { 0, height, width, 2 * height },
            { 1, 0, width + 1, height },
            { 0, 1, width, height + 1 },
            { width - 1, 0, 1, height },
            { 0, height - 1, width, 1 },
            { 0, 0, 0, height },
            { 0, 0, width, 0 },
            { 1, 1, 1, 1 },
            { width, height, 0, 0 },
    }) {
        int result = AImageDecoder_setCrop(decoder, invalidCrop);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
        ASSERT_EQ(defaultStride, AImageDecoder_getMinimumStride(decoder));
    }

    for (ARect validCrop : std::initializer_list<ARect> {
            { 0, 0, width, height },
            { 0, 0, width / 2, height / 2},
            { 0, 0, width / 3, height },
            { 0, 0, width, height / 4},
            { width / 2, 0, width, height / 2},
            { 0, height / 2, width / 2, height },
            { width / 2, height / 2, width, height },
            { 1, 1, width - 1, height - 1 },
    }) {
        int result = AImageDecoder_setCrop(decoder, validCrop);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
        size_t actualStride = AImageDecoder_getMinimumStride(decoder);
        size_t expectedStride = bytesPerPixel(format) * (validCrop.right - validCrop.left);
        ASSERT_EQ(expectedStride, actualStride);
    }

    // Reset the crop, so we can test setting a crop *after* changing the
    // target size.
    result = AImageDecoder_setCrop(decoder, { 0, 0, 0, 0 });
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
    ASSERT_EQ(defaultStride, AImageDecoder_getMinimumStride(decoder));

    int32_t newWidth = width / 2, newHeight = height / 2;
    result = AImageDecoder_setTargetSize(decoder, newWidth, newHeight);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
    const size_t halfStride = AImageDecoder_getMinimumStride(decoder);
    {
        size_t expectedStride = bytesPerPixel(format) * newWidth;
        ASSERT_EQ(expectedStride, halfStride);
    }

    // At the smaller target size, crops that were previously valid no longer
    // are.
    for (ARect invalidCrop : std::initializer_list<ARect> {
            { 0, 0, width / 3, height },
            { 0, 0, width, height / 4},
            { width / 2, 0, width, height / 2},
            { 0, height / 2, width / 2, height },
            { width / 2, height / 2, width, height },
            { 1, 1, width - 1, height - 1 },
    }) {
        int result = AImageDecoder_setCrop(decoder, invalidCrop);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
        ASSERT_EQ(halfStride, AImageDecoder_getMinimumStride(decoder));
    }

    for (ARect validCrop : std::initializer_list<ARect> {
            { 0, 0, newWidth, newHeight },
            { 0, 0, newWidth / 3, newHeight },
            { 0, 0, newWidth, newHeight / 4},
            { newWidth / 2, 0, newWidth, newHeight / 2},
            { 0, newHeight / 2, newWidth / 2, newHeight },
            { newWidth / 2, newHeight / 2, newWidth, newHeight },
            { 1, 1, newWidth - 1, newHeight - 1 },
    }) {
        int result = AImageDecoder_setCrop(decoder, validCrop);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
        size_t actualStride = AImageDecoder_getMinimumStride(decoder);
        size_t expectedStride = bytesPerPixel(format) * (validCrop.right - validCrop.left);
        ASSERT_EQ(expectedStride, actualStride);
    }

    newWidth = width * 2;
    newHeight = height * 2;
    result = AImageDecoder_setTargetSize(decoder, newWidth, newHeight);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

    for (ARect validCrop : std::initializer_list<ARect> {
            { width, 0, newWidth, height },
            { 0, height * 3 / 4, width * 4 / 3, height }
    }) {
        int result = AImageDecoder_setCrop(decoder, validCrop);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
        size_t actualStride = AImageDecoder_getMinimumStride(decoder);
        size_t expectedStride = bytesPerPixel(format) * (validCrop.right - validCrop.left);
        ASSERT_EQ(expectedStride, actualStride);
    }

    // Reset crop and target size, so that we can verify that setting a crop and
    // then setting target size that will not support the crop fails.
    result = AImageDecoder_setCrop(decoder, { 0, 0, 0, 0 });
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
    result = AImageDecoder_setTargetSize(decoder, width, height);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
    ASSERT_EQ(defaultStride, AImageDecoder_getMinimumStride(decoder));

    ARect crop{ width / 2, height / 2, width, height };
    result = AImageDecoder_setCrop(decoder, crop);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
    const size_t croppedStride = AImageDecoder_getMinimumStride(decoder);
    {
        size_t expectedStride = bytesPerPixel(format) * (crop.right - crop.left);
        ASSERT_EQ(expectedStride, croppedStride);
    }
    result = AImageDecoder_setTargetSize(decoder, width / 2, height / 2);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_SCALE, result);
    ASSERT_EQ(croppedStride, AImageDecoder_getMinimumStride(decoder));
}

static void testDecodeCrop(JNIEnv* env, jclass, jlong imageDecoderPtr,
                           jobject jbitmap, jint targetWidth, jint targetHeight,
                           jint left, jint top, jint right, jint bottom) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    int result;
    if (targetWidth != 0 && targetHeight != 0) {
        result = AImageDecoder_setTargetSize(decoder, targetWidth, targetHeight);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
    }

    ARect rect { left, top, right, bottom };
    result = AImageDecoder_setCrop(decoder, rect);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

    const int32_t width = right - left;
    const int32_t height = bottom - top;
    size_t minStride = AImageDecoder_getMinimumStride(decoder);
    size_t size = minStride * height;
    std::unique_ptr<char[]> pixelsBuffer(new char[size]);
    void* pixels = (void*) pixelsBuffer.get();

    {
        // Try some invalid parameters.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull"
        result = AImageDecoder_decodeImage(decoder, nullptr, minStride, size);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
#pragma clang diagnostic pop

        result = AImageDecoder_decodeImage(decoder, pixels, minStride - 1, size);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);

        result = AImageDecoder_decodeImage(decoder, pixels, minStride, size - minStride);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_BAD_PARAMETER, result);
    }

    result = AImageDecoder_decodeImage(decoder, pixels, minStride, size);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
    ASSERT_NE(info, nullptr);

    ASSERT_NE(jbitmap, nullptr);
    ASSERT_TRUE(bitmapsEqual(env, jbitmap, AImageDecoderHeaderInfo_getAndroidBitmapFormat(info),
                             width, height, AImageDecoderHeaderInfo_getAlphaFlags(info),
                             minStride, pixels, minStride));

    // Verify that larger strides still behave as expected.
    for (size_t stride : { minStride * 2, minStride * 3 }) {
        size_t size = stride * (height - 1) + minStride;
        std::unique_ptr<char[]> decodePixelsBuffer(new char[size]);
        void* decodePixels = (void*) decodePixelsBuffer.get();
        result = AImageDecoder_decodeImage(decoder, decodePixels, stride, size);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

        ASSERT_TRUE(bitmapsEqual(minStride, height, pixels, minStride, decodePixels, stride));
    }
}

static void testScalePlusUnpremul(JNIEnv* env, jclass, jlong imageDecoderPtr) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
    ASSERT_NE(nullptr, info);

    const int32_t width = AImageDecoderHeaderInfo_getWidth(info);
    const int32_t height = AImageDecoderHeaderInfo_getHeight(info);
    const int alpha = AImageDecoderHeaderInfo_getAlphaFlags(info);

    if (alpha == ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE) {
        // Set unpremul, then scale. This succeeds for an opaque image.
        int result = AImageDecoder_setUnpremultipliedRequired(decoder, true);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

        result = AImageDecoder_setTargetSize(decoder, width * 2, height * 2);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

        result = AImageDecoder_setTargetSize(decoder, width * 2/3, height * 2/3);
        if (width * 2/3 == 0 || height * 2/3 == 0) {
            // The image that is 1x1 cannot be downscaled.
            ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_SCALE, result);
        } else {
            ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
        }

        // Reset to the original settings to test the other order.
        result = AImageDecoder_setUnpremultipliedRequired(decoder, false);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

        result = AImageDecoder_setTargetSize(decoder, width, height);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

        // Specify scale and then unpremul.
        if (width * 2/3 == 0 || height * 2/3 == 0) {
            // The image that is 1x1 cannot be downscaled. Scale up instead.
            result = AImageDecoder_setTargetSize(decoder, width * 2, height * 2);
        } else {
            result = AImageDecoder_setTargetSize(decoder, width * 2/3, height * 2/3);
        }
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

        result = AImageDecoder_setUnpremultipliedRequired(decoder, true);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
    } else {
        // Use unpremul and then scale. Setting to unpremul is successful, but
        // later calls to change the scale fail.
        int result = AImageDecoder_setUnpremultipliedRequired(decoder, true);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

        result = AImageDecoder_setTargetSize(decoder, width * 2, height * 2);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_SCALE, result);

        result = AImageDecoder_setTargetSize(decoder, width * 2/3, height * 2/3);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_SCALE, result);

        // Set back to premul to verify that the opposite order also fails.
        result = AImageDecoder_setUnpremultipliedRequired(decoder, false);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

        result = AImageDecoder_setTargetSize(decoder, width * 2, height * 2);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
        result = AImageDecoder_setUnpremultipliedRequired(decoder, true);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_CONVERSION, result);

        result = AImageDecoder_setTargetSize(decoder, width * 2/3, height * 2/3);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);
        result = AImageDecoder_setUnpremultipliedRequired(decoder, true);
        ASSERT_EQ(ANDROID_IMAGE_DECODER_INVALID_CONVERSION, result);
    }
}

static void testDecodeSetDataSpace(JNIEnv* env, jclass, jlong imageDecoderPtr,
                                   jobject jbitmap, jint dataSpace) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    ASSERT_EQ(dataSpace, AndroidBitmap_getDataSpace(env, jbitmap));

    int result = AImageDecoder_setDataSpace(decoder, dataSpace);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

    AndroidBitmapInfo jInfo;
    int bitmapResult = AndroidBitmap_getInfo(env, jbitmap, &jInfo);
    ASSERT_EQ(ANDROID_BITMAP_RESULT_SUCCESS, bitmapResult);

    result = AImageDecoder_setAndroidBitmapFormat(decoder, jInfo.format);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
    ASSERT_NE(info, nullptr);

    const int32_t width = AImageDecoderHeaderInfo_getWidth(info);
    const int32_t height = AImageDecoderHeaderInfo_getHeight(info);
    int alphaFlags = AImageDecoderHeaderInfo_getAlphaFlags(info);

    size_t minStride = AImageDecoder_getMinimumStride(decoder);
    size_t size = minStride * height;
    std::unique_ptr<char[]> pixelsBuffer(new char[size]);
    void* pixels = (void*) pixelsBuffer.get();

    result = AImageDecoder_decodeImage(decoder, pixels, minStride, size);
    ASSERT_EQ(ANDROID_IMAGE_DECODER_SUCCESS, result);

    ASSERT_TRUE(bitmapsEqual(env, jbitmap, (AndroidBitmapFormat) jInfo.format,
                             width, height, alphaFlags, minStride, pixels, minStride));
}

static void testIsAnimated(JNIEnv* env, jclass, jlong imageDecoderPtr, jboolean animated) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    ASSERT_TRUE(decoder);
    ASSERT_EQ(animated, AImageDecoder_isAnimated(decoder));
}

static void testRepeatCount(JNIEnv* env, jclass, jlong imageDecoderPtr, jint repeatCount) {
    AImageDecoder* decoder = reinterpret_cast<AImageDecoder*>(imageDecoderPtr);
    DecoderDeleter decoderDeleter(decoder, AImageDecoder_delete);

    if (repeatCount == -1) { // AnimatedImageDrawable.REPEAT_INFINITE
        repeatCount = ANDROID_IMAGE_DECODER_INFINITE;
    }

    ASSERT_TRUE(decoder);
    ASSERT_EQ(repeatCount, AImageDecoder_getRepeatCount(decoder));
}

#define ASSET_MANAGER "Landroid/content/res/AssetManager;"
#define STRING "Ljava/lang/String;"
#define BITMAP "Landroid/graphics/Bitmap;"

static JNINativeMethod gMethods[] = {
    { "nTestEmptyCreate", "()V", (void*) testEmptyCreate },
    { "nTestNullDecoder", "(" ASSET_MANAGER STRING ")V", (void*) testNullDecoder },
    { "nTestInfo", "(JII" STRING "ZI)V", (void*) testInfo },
    { "nOpenAsset", "(" ASSET_MANAGER STRING ")J", (void*) openAssetNative },
    { "nCloseAsset", "(J)V", (void*) closeAsset },
    { "nCreateFromAsset", "(J)J", (void*) createFromAsset },
    { "nCreateFromAssetFd", "(J)J", (void*) createFromAssetFd },
    { "nCreateFromAssetBuffer", "(J)J", (void*) createFromAssetBuffer },
    { "nCreateFromFd", "(I)J", (void*) createFromFd },
    { "nTestCreateIncomplete", "(" ASSET_MANAGER STRING "I)V", (void*) testCreateIncomplete },
    { "nTestCreateUnsupported", "(" ASSET_MANAGER STRING ")V", (void*) testCreateUnsupported },
    { "nTestSetFormat", "(JZZ)V", (void*) testSetFormat },
    { "nTestSetUnpremul", "(JZ)V", (void*) testSetUnpremul },
    { "nTestGetMinimumStride", "(JZZ)V", (void*) testGetMinimumStride },
    { "nTestDecode", "(JIZ" BITMAP ")V", (void*) testDecode },
    { "nTestDecodeStride", "(J)V", (void*) testDecodeStride },
    { "nTestSetTargetSize", "(J)V", (void*) testSetTargetSize },
    { "nTestComputeSampledSize", "(J" BITMAP "I)V", (void*) testComputeSampledSize },
    { "nTestDecodeScaled", "(J" BITMAP ")V", (void*) testDecodeScaled },
    { "nTestSetCrop", "(" ASSET_MANAGER STRING ")V", (void*) testSetCrop },
    { "nTestDecodeCrop", "(J" BITMAP "IIIIII)V", (void*) testDecodeCrop },
    { "nTestScalePlusUnpremul", "(J)V", (void*) testScalePlusUnpremul },
    { "nTestDecode", "(J" BITMAP "I)V", (void*) testDecodeSetDataSpace },
    { "nTestIsAnimated", "(JZ)V", (void*) testIsAnimated },
    { "nTestRepeatCount", "(JI)V", (void*) testRepeatCount },
};

int register_android_graphics_cts_AImageDecoderTest(JNIEnv* env) {
    jclass clazz = env->FindClass("android/graphics/cts/AImageDecoderTest");
    return env->RegisterNatives(clazz, gMethods,
            sizeof(gMethods) / sizeof(JNINativeMethod));
}

