/*
 * 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.
 */

#include "aassetstreamadaptor.h"

#include <android/asset_manager.h>
#include <android/bitmap.h>
#include <android/imagedecoder.h>
#include <android/graphics/MimeType.h>
#include <android/rect.h>
#include <hwui/ImageDecoder.h>
#include <log/log.h>
#include <SkAndroidCodec.h>

#include <fcntl.h>
#include <optional>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

using namespace android;

int ResultToErrorCode(SkCodec::Result result) {
    switch (result) {
        case SkCodec::kIncompleteInput:
            return ANDROID_IMAGE_DECODER_INCOMPLETE;
        case SkCodec::kErrorInInput:
            return ANDROID_IMAGE_DECODER_ERROR;
        case SkCodec::kInvalidInput:
            return ANDROID_IMAGE_DECODER_INVALID_INPUT;
        case SkCodec::kCouldNotRewind:
            return ANDROID_IMAGE_DECODER_SEEK_ERROR;
        case SkCodec::kUnimplemented:
            return ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT;
        case SkCodec::kInvalidConversion:
            return ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
        case SkCodec::kInvalidParameters:
            return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
        case SkCodec::kSuccess:
            return ANDROID_IMAGE_DECODER_SUCCESS;
        case SkCodec::kInvalidScale:
            return ANDROID_IMAGE_DECODER_INVALID_SCALE;
        case SkCodec::kInternalError:
            return ANDROID_IMAGE_DECODER_INTERNAL_ERROR;
    }
}

static int createFromStream(std::unique_ptr<SkStreamRewindable> stream, AImageDecoder** outDecoder) {
    SkCodec::Result result;
    auto codec = SkCodec::MakeFromStream(std::move(stream), &result, nullptr,
                                         SkCodec::SelectionPolicy::kPreferAnimation);
    auto androidCodec = SkAndroidCodec::MakeFromCodec(std::move(codec),
            SkAndroidCodec::ExifOrientationBehavior::kRespect);
    if (!androidCodec) {
        return ResultToErrorCode(result);
    }

    *outDecoder = reinterpret_cast<AImageDecoder*>(new ImageDecoder(std::move(androidCodec)));
    return ANDROID_IMAGE_DECODER_SUCCESS;
}

int AImageDecoder_createFromAAsset(AAsset* asset, AImageDecoder** outDecoder) {
    if (!asset || !outDecoder) {
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }
    *outDecoder = nullptr;

    auto stream = std::make_unique<AAssetStreamAdaptor>(asset);
    return createFromStream(std::move(stream), outDecoder);
}

static bool isSeekable(int descriptor) {
    return ::lseek64(descriptor, 0, SEEK_CUR) != -1;
}

int AImageDecoder_createFromFd(int fd, AImageDecoder** outDecoder) {
    if (fd <= 0 || !outDecoder) {
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }

    struct stat fdStat;
    if (fstat(fd, &fdStat) == -1) {
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }

    if (!isSeekable(fd)) {
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }

    // SkFILEStream will close its descriptor. Duplicate it so the client will
    // still be responsible for closing the original.
    int dupDescriptor = fcntl(fd, F_DUPFD_CLOEXEC, 0);
    FILE* file = fdopen(dupDescriptor, "r");
    if (!file) {
        close(dupDescriptor);
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }

    auto stream = std::unique_ptr<SkStreamRewindable>(new SkFILEStream(file));
    return createFromStream(std::move(stream), outDecoder);
}

int AImageDecoder_createFromBuffer(const void* buffer, size_t length,
                                   AImageDecoder** outDecoder) {
    if (!buffer || !length  || !outDecoder) {
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }
    *outDecoder = nullptr;

    // The client is expected to keep the buffer alive as long as the
    // AImageDecoder, so we do not need to copy the buffer.
    auto stream = std::unique_ptr<SkStreamRewindable>(
            new SkMemoryStream(buffer, length, false /* copyData */));
    return createFromStream(std::move(stream), outDecoder);
}

static ImageDecoder* toDecoder(AImageDecoder* d) {
    return reinterpret_cast<ImageDecoder*>(d);
}

// Note: This differs from the version in android_bitmap.cpp in that this
// version returns kGray_8_SkColorType for ANDROID_BITMAP_FORMAT_A_8. SkCodec
// allows decoding single channel images to gray, which Android then treats
// as A_8/ALPHA_8.
static SkColorType getColorType(AndroidBitmapFormat format) {
    switch (format) {
        case ANDROID_BITMAP_FORMAT_RGBA_8888:
            return kN32_SkColorType;
        case ANDROID_BITMAP_FORMAT_RGB_565:
            return kRGB_565_SkColorType;
        case ANDROID_BITMAP_FORMAT_RGBA_4444:
            return kARGB_4444_SkColorType;
        case ANDROID_BITMAP_FORMAT_A_8:
            return kGray_8_SkColorType;
        case ANDROID_BITMAP_FORMAT_RGBA_F16:
            return kRGBA_F16_SkColorType;
        default:
            return kUnknown_SkColorType;
    }
}

int AImageDecoder_setAndroidBitmapFormat(AImageDecoder* decoder, int32_t format) {
    if (!decoder || format < ANDROID_BITMAP_FORMAT_NONE
            || format > ANDROID_BITMAP_FORMAT_RGBA_F16) {
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }
    return toDecoder(decoder)->setOutColorType(getColorType((AndroidBitmapFormat) format))
            ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
}

const AImageDecoderHeaderInfo* AImageDecoder_getHeaderInfo(const AImageDecoder* decoder) {
    return reinterpret_cast<const AImageDecoderHeaderInfo*>(decoder);
}

static const ImageDecoder* toDecoder(const AImageDecoderHeaderInfo* info) {
    return reinterpret_cast<const ImageDecoder*>(info);
}

int32_t AImageDecoderHeaderInfo_getWidth(const AImageDecoderHeaderInfo* info) {
    if (!info) {
        return 0;
    }
    return toDecoder(info)->mCodec->getInfo().width();
}

int32_t AImageDecoderHeaderInfo_getHeight(const AImageDecoderHeaderInfo* info) {
    if (!info) {
        return 0;
    }
    return toDecoder(info)->mCodec->getInfo().height();
}

const char* AImageDecoderHeaderInfo_getMimeType(const AImageDecoderHeaderInfo* info) {
    if (!info) {
        return nullptr;
    }
    return getMimeType(toDecoder(info)->mCodec->getEncodedFormat());
}

bool AImageDecoderHeaderInfo_isAnimated(const AImageDecoderHeaderInfo* info) {
    if (!info) {
        return false;
    }
    return toDecoder(info)->mCodec->codec()->getFrameCount() > 1;
}

// FIXME: Share with getFormat in android_bitmap.cpp?
static AndroidBitmapFormat getFormat(SkColorType colorType) {
    switch (colorType) {
        case kN32_SkColorType:
            return ANDROID_BITMAP_FORMAT_RGBA_8888;
        case kRGB_565_SkColorType:
            return ANDROID_BITMAP_FORMAT_RGB_565;
        case kARGB_4444_SkColorType:
            return ANDROID_BITMAP_FORMAT_RGBA_4444;
        case kAlpha_8_SkColorType:
            return ANDROID_BITMAP_FORMAT_A_8;
        case kRGBA_F16_SkColorType:
            return ANDROID_BITMAP_FORMAT_RGBA_F16;
        default:
            return ANDROID_BITMAP_FORMAT_NONE;
    }
}

AndroidBitmapFormat AImageDecoderHeaderInfo_getAndroidBitmapFormat(
        const AImageDecoderHeaderInfo* info) {
    if (!info) {
        return ANDROID_BITMAP_FORMAT_NONE;
    }
    return getFormat(toDecoder(info)->mCodec->computeOutputColorType(kN32_SkColorType));
}

int AImageDecoderHeaderInfo_getAlphaFlags(const AImageDecoderHeaderInfo* info) {
    if (!info) {
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }
    switch (toDecoder(info)->mCodec->getInfo().alphaType()) {
        case kUnknown_SkAlphaType:
            LOG_ALWAYS_FATAL("Invalid alpha type");
            return ANDROID_IMAGE_DECODER_INTERNAL_ERROR;
        case kUnpremul_SkAlphaType:
            // fall through. premul is the default.
        case kPremul_SkAlphaType:
            return ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
        case kOpaque_SkAlphaType:
            return ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE;
    }
}

SkAlphaType toAlphaType(int androidBitmapFlags) {
    switch (androidBitmapFlags) {
        case ANDROID_BITMAP_FLAGS_ALPHA_PREMUL:
            return kPremul_SkAlphaType;
        case ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL:
            return kUnpremul_SkAlphaType;
        case ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE:
            return kOpaque_SkAlphaType;
        default:
            return kUnknown_SkAlphaType;
    }
}

int AImageDecoder_setAlphaFlags(AImageDecoder* decoder, int alphaFlag) {
    if (!decoder || alphaFlag < ANDROID_BITMAP_FLAGS_ALPHA_PREMUL
            || alphaFlag > ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL) {
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }

    return toDecoder(decoder)->setOutAlphaType(toAlphaType(alphaFlag))
            ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
}

int AImageDecoder_setTargetSize(AImageDecoder* decoder, int width, int height) {
    if (!decoder) {
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }

    return toDecoder(decoder)->setTargetSize(width, height)
            ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_SCALE;
}

int AImageDecoder_setCrop(AImageDecoder* decoder, ARect crop) {
    if (!decoder) {
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }

    SkIRect cropIRect;
    cropIRect.setLTRB(crop.left, crop.top, crop.right, crop.bottom);
    SkIRect* cropPtr = cropIRect == SkIRect::MakeEmpty() ? nullptr : &cropIRect;
    return toDecoder(decoder)->setCropRect(cropPtr)
            ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_BAD_PARAMETER;
}


size_t AImageDecoder_getMinimumStride(AImageDecoder* decoder) {
    if (!decoder) {
        return 0;
    }

    SkImageInfo info = toDecoder(decoder)->getOutputInfo();
    return info.minRowBytes();
}

int AImageDecoder_decodeImage(AImageDecoder* decoder,
                              void* pixels, size_t stride,
                              size_t size) {
    if (!decoder || !pixels || !stride) {
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }

    ImageDecoder* imageDecoder = toDecoder(decoder);

    const int height = imageDecoder->getOutputInfo().height();
    const size_t minStride = AImageDecoder_getMinimumStride(decoder);
    // If this calculation were to overflow, it would have been caught in
    // setTargetSize.
    if (stride < minStride || size < stride * (height - 1) + minStride) {
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }

    return ResultToErrorCode(imageDecoder->decode(pixels, stride));
}

void AImageDecoder_delete(AImageDecoder* decoder) {
    delete toDecoder(decoder);
}
