/*
 * Copyright 2023 Rive
 */

#include "rive/decoders/bitmap_decoder.hpp"
#include "rive/rive_types.hpp"
#include "rive/math/simd.hpp"
#include "rive/math/math_types.hpp"
#include "rive/core/type_conversions.hpp"
#include "utils/auto_cf.hpp"

#include <TargetConditionals.h>

#if TARGET_OS_IPHONE
#include <CoreGraphics/CoreGraphics.h>
#include <ImageIO/ImageIO.h>
#elif TARGET_OS_MAC
#include <ApplicationServices/ApplicationServices.h>
#endif

#include <stdio.h>
#include <string.h>
#include <vector>

// Represents raw, premultiplied, RGBA image data with tightly packed rows
// (width * 4 bytes).
struct PlatformCGImage
{
    uint32_t width = 0;
    uint32_t height = 0;
    bool opaque = false;
    std::unique_ptr<uint8_t[]> pixels;
};

bool cg_image_decode(const uint8_t* encodedBytes,
                     size_t encodedSizeInBytes,
                     PlatformCGImage* platformImage)
{
    AutoCF data =
        CFDataCreate(kCFAllocatorDefault, encodedBytes, encodedSizeInBytes);
    if (!data)
    {
        return false;
    }

    AutoCF source = CGImageSourceCreateWithData(data, nullptr);
    if (!source)
    {
        return false;
    }

    AutoCF image = CGImageSourceCreateImageAtIndex(source, 0, nullptr);
    if (!image)
    {
        return false;
    }

    bool isOpaque = false;
    switch (CGImageGetAlphaInfo(image.get()))
    {
        case kCGImageAlphaNone:
        case kCGImageAlphaNoneSkipFirst:
        case kCGImageAlphaNoneSkipLast:
            isOpaque = true;
            break;
        default:
            break;
    }

    const size_t width = CGImageGetWidth(image);
    const size_t height = CGImageGetHeight(image);
    const size_t rowBytes = width * 4; // 4 bytes per pixel
    const size_t size = rowBytes * height;

    const size_t bitsPerComponent = 8;
    CGBitmapInfo cgInfo = kCGBitmapByteOrder32Big; // rgba
    if (isOpaque)
    {
        cgInfo |= kCGImageAlphaNoneSkipLast;
    }
    else
    {
        cgInfo |= kCGImageAlphaPremultipliedLast;
    }

    std::unique_ptr<uint8_t[]> pixels(new uint8_t[size]);

    AutoCF cs = CGColorSpaceCreateDeviceRGB();
    AutoCF cg = CGBitmapContextCreate(
        pixels.get(), width, height, bitsPerComponent, rowBytes, cs, cgInfo);
    if (!cg)
    {
        return false;
    }

    CGContextSetBlendMode(cg, kCGBlendModeCopy);
    CGContextDrawImage(cg, CGRectMake(0, 0, width, height), image);

    platformImage->width = rive::castTo<uint32_t>(width);
    platformImage->height = rive::castTo<uint32_t>(height);
    platformImage->opaque = isOpaque;
    platformImage->pixels = std::move(pixels);

    return true;
}

std::unique_ptr<Bitmap> Bitmap::decode(const uint8_t bytes[], size_t byteCount)
{
    PlatformCGImage image;
    if (!cg_image_decode(bytes, byteCount, &image))
    {
        return nullptr;
    }

    // CG only supports premultiplied alpha. Unmultiply now.
    size_t imageNumPixels = image.height * image.width;
    size_t imageSizeInBytes = imageNumPixels * 4;
    // Process 2 pixels at once, deal with odd number of pixels
    if (imageNumPixels & 1)
    {
        imageSizeInBytes -= 4;
    }
    size_t i;
    for (i = 0; i < imageSizeInBytes; i += 8)
    {
        // Load 2 pixels into 64 bits
        auto twoPixels = rive::simd::load<uint8_t, 8>(&image.pixels[i]);
        auto a0 = twoPixels[3];
        auto a1 = twoPixels[7];
        // Avoid computation if both pixels are either fully transparent or
        // opaque pixels
        if ((a0 > 0 && a0 < 255) || (a1 > 0 && a1 < 255))
        {
            // Avoid potential division by zero
            a0 = std::max<uint8_t>(a0, 1);
            a1 = std::max<uint8_t>(a1, 1);
            // Cast to 16 bits to avoid overflow
            rive::uint16x8 rgbaWidex2 = rive::simd::cast<uint16_t>(twoPixels);
            // Unpremult: multiply by RGB by "255.0 / alpha"
            rgbaWidex2 *= rive::uint16x8{255, 255, 255, 1, 255, 255, 255, 1};
            rgbaWidex2 /= rive::uint16x8{a0, a0, a0, 1, a1, a1, a1, 1};
            // Cast back to 8 bits and store
            twoPixels = rive::simd::cast<uint8_t>(rgbaWidex2);
            rive::simd::store(&image.pixels[i], twoPixels);
        }
    }
    // Process last odd pixel if needed
    if (imageNumPixels & 1)
    {
        // Load 1 pixel into 32 bits
        auto rgba = rive::simd::load<uint8_t, 4>(&image.pixels[i]);
        // Avoid computation for fully transparent or opaque pixels
        if (rgba.a > 0 && rgba.a < 255)
        {
            // Cast to 16 bits to avoid overflow
            rive::uint16x4 rgbaWide = rive::simd::cast<uint16_t>(rgba);
            // Unpremult: multiply by RGB by "255.0 / alpha"
            rgbaWide *= rive::uint16x4{255, 255, 255, 1};
            rgbaWide /= rive::uint16x4{rgba.a, rgba.a, rgba.a, 1};
            // Cast back to 8 bits and store
            rgba = rive::simd::cast<uint8_t>(rgbaWide);
            rive::simd::store(&image.pixels[i], rgba);
        }
    }

    return std::make_unique<Bitmap>(
        image.width, image.height, PixelFormat::RGBA, std::move(image.pixels));
}
