/*
 * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "ImageBufferUtilitiesCG.h"

#if USE(CG)

#include "GraphicsContextCG.h"
#include "MIMETypeRegistry.h"
#include "PixelBuffer.h"
#include <ImageIO/ImageIO.h>
#include <wtf/CheckedArithmetic.h>
#include <wtf/ScopedLambda.h>
#include <wtf/text/Base64.h>

#if PLATFORM(COCOA)
#include "UTIUtilities.h"
#endif

namespace WebCore {

using PutBytesCallback = size_t(const void*, size_t);

uint8_t verifyImageBufferIsBigEnough(const void* buffer, size_t bufferSize)
{
    RELEASE_ASSERT(bufferSize);

    uintptr_t lastByte;
    bool isSafe = WTF::safeAdd((uintptr_t)buffer, bufferSize - 1, lastByte);
    RELEASE_ASSERT(isSafe);

    return *(uint8_t*)lastByte;
}

CFStringRef jpegUTI()
{
ALLOW_DEPRECATED_DECLARATIONS_BEGIN
#if PLATFORM(IOS_FAMILY) || PLATFORM(WIN)
    static const CFStringRef kUTTypeJPEG = CFSTR("public.jpeg");
#endif
    return kUTTypeJPEG;
ALLOW_DEPRECATED_DECLARATIONS_END
}

RetainPtr<CFStringRef> utiFromImageBufferMIMEType(const String& mimeType)
{
ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    // FIXME: Why doesn't iOS use the CoreServices version?
#if PLATFORM(MAC)
    return UTIFromMIMEType(mimeType).createCFString();
#else
    // FIXME: Add Windows support for all the supported UTIs when a way to convert from MIMEType to UTI reliably is found.
    // For now, only support PNG, JPEG, and GIF. See <rdar://problem/6095286>.
    static CFStringRef kUTTypePNG;
    static CFStringRef kUTTypeGIF;

    static std::once_flag onceKey;
    std::call_once(onceKey, [&] {
        kUTTypePNG = CFSTR("public.png");
        kUTTypeGIF = CFSTR("com.compuserve.gif");
    });

    if (equalLettersIgnoringASCIICase(mimeType, "image/png"_s))
        return kUTTypePNG;
    if (equalLettersIgnoringASCIICase(mimeType, "image/jpeg"_s))
        return jpegUTI();
    if (equalLettersIgnoringASCIICase(mimeType, "image/gif"_s))
        return kUTTypeGIF;

    ASSERT_NOT_REACHED();
    return kUTTypePNG;
#endif
ALLOW_DEPRECATED_DECLARATIONS_END
}

static bool encode(CGImageRef image, CFStringRef destinationUTI, std::optional<double> quality, const ScopedLambda<PutBytesCallback>& function)
{
    if (!image || !destinationUTI)
        return false;

    CGDataConsumerCallbacks callbacks {
        [](void* context, const void* buffer, size_t count) -> size_t {
            auto functor = *static_cast<const ScopedLambda<PutBytesCallback>*>(context);
            return functor(buffer, count);
        },
        nullptr
    };

    auto consumer = adoptCF(CGDataConsumerCreate(const_cast<ScopedLambda<PutBytesCallback>*>(&function), &callbacks));
    auto destination = adoptCF(CGImageDestinationCreateWithDataConsumer(consumer.get(), destinationUTI, 1, nullptr));
    
    auto imageProperties = [&] () -> RetainPtr<CFDictionaryRef> {
        if (CFEqual(destinationUTI, jpegUTI()) && quality && *quality >= 0.0 && *quality <= 1.0) {
            // Apply the compression quality to the JPEG image destination.
            auto compressionQuality = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &*quality));
            const void* key = kCGImageDestinationLossyCompressionQuality;
            const void* value = compressionQuality.get();
            return adoptCF(CFDictionaryCreate(0, &key, &value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
        }
        return nullptr;
    }();

    // FIXME: Setting kCGImageDestinationBackgroundColor to black for JPEG images in imageProperties would save some math
    // in the calling functions, but it doesn't seem to work.

    CGImageDestinationAddImage(destination.get(), image, imageProperties.get());

    return CGImageDestinationFinalize(destination.get());
}

static bool encode(const PixelBuffer& source, const String& mimeType, std::optional<double> quality, const ScopedLambda<PutBytesCallback>& function)
{
    ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));

    auto destinationUTI = utiFromImageBufferMIMEType(mimeType);

    CGImageAlphaInfo dataAlphaInfo = kCGImageAlphaLast;
    
    auto data = source.bytes();
    auto dataSize = source.sizeInBytes();

    Vector<uint8_t> premultipliedData;

    if (CFEqual(destinationUTI.get(), jpegUTI())) {
        // FIXME: Use PixelBufferConversion for this once it supports RGBX.

        // JPEGs don't have an alpha channel, so we have to manually composite on top of black.
        if (!premultipliedData.tryReserveCapacity(dataSize))
            return false;

        premultipliedData.grow(dataSize);
        unsigned char* buffer = premultipliedData.data();
        for (size_t i = 0; i < dataSize; i += 4) {
            unsigned alpha = data[i + 3];
            if (alpha != 255) {
                buffer[i + 0] = data[i + 0] * alpha / 255;
                buffer[i + 1] = data[i + 1] * alpha / 255;
                buffer[i + 2] = data[i + 2] * alpha / 255;
            } else {
                buffer[i + 0] = data[i + 0];
                buffer[i + 1] = data[i + 1];
                buffer[i + 2] = data[i + 2];
            }
        }

        dataAlphaInfo = kCGImageAlphaNoneSkipLast; // Ignore the alpha channel.
        data = premultipliedData.data();
    }

    verifyImageBufferIsBigEnough(data, dataSize);

    auto dataProvider = adoptCF(CGDataProviderCreateWithData(nullptr, data, dataSize, nullptr));
    if (!dataProvider)
        return false;

    auto imageSize = source.size();
    auto image = adoptCF(CGImageCreate(imageSize.width(), imageSize.height(), 8, 32, 4 * imageSize.width(), source.format().colorSpace.platformColorSpace(), static_cast<uint32_t>(kCGBitmapByteOrderDefault) | static_cast<uint32_t>(dataAlphaInfo), dataProvider.get(), 0, false, kCGRenderingIntentDefault));

    return encode(image.get(), destinationUTI.get(), quality, function);
}

template<typename Source, typename SourceDescription> static Vector<uint8_t> encodeToVector(Source&& source, SourceDescription&& sourceDescription, std::optional<double> quality)
{
    Vector<uint8_t> result;

    bool success = encode(std::forward<Source>(source), std::forward<SourceDescription>(sourceDescription), quality, scopedLambdaRef<PutBytesCallback>([&] (const void* data, size_t length) {
        result.append(static_cast<const uint8_t*>(data), length);
        return length;
    }));
    if (!success)
        return { };

    return result;
}

template<typename Source, typename SourceDescription> static String encodeToDataURL(Source&& source, SourceDescription&& sourceDescription, const String& mimeType, std::optional<double> quality)
{
    // FIXME: This could be done more efficiently with a streaming base64 encoder.

    auto encodedData = encodeToVector(std::forward<Source>(source), std::forward<SourceDescription>(sourceDescription), quality);
    if (encodedData.isEmpty())
        return "data:,"_s;

    return makeString("data:", mimeType, ";base64,", base64Encoded(encodedData));
}

Vector<uint8_t> data(CGImageRef image, CFStringRef destinationUTI, std::optional<double> quality)
{
    return encodeToVector(image, destinationUTI, quality);
}

Vector<uint8_t> data(const PixelBuffer& pixelBuffer, const String& mimeType, std::optional<double> quality)
{
    return encodeToVector(pixelBuffer, mimeType, quality);
}

String dataURL(CGImageRef image, CFStringRef destinationUTI, const String& mimeType, std::optional<double> quality)
{
    return encodeToDataURL(image, destinationUTI, mimeType, quality);
}

String dataURL(const PixelBuffer& pixelBuffer, const String& mimeType, std::optional<double> quality)
{
    return encodeToDataURL(pixelBuffer, mimeType, mimeType, quality);
}

} // namespace WebCore

#endif // USE(CG)
