/* Copyright 2020 Emmanuel Gil Peyrot. All rights reserved.
   SPDX-License-Identifier: BSD-2-Clause
*/

#include <avif/avif.h>
#include <stdlib.h>

#define GDK_PIXBUF_ENABLE_BACKEND
#include <gdk-pixbuf/gdk-pixbuf-io.h>
#include <gdk-pixbuf/gdk-pixbuf.h>

G_MODULE_EXPORT void fill_vtable (GdkPixbufModule *module);
G_MODULE_EXPORT void fill_info (GdkPixbufFormat *info);

struct avif_context
{
    GdkPixbuf *pixbuf;

    GdkPixbufModuleSizeFunc size_func;
    GdkPixbufModuleUpdatedFunc updated_func;
    GdkPixbufModulePreparedFunc prepared_func;
    gpointer user_data;

    avifDecoder *decoder;
    GByteArray *data;
    GBytes *bytes;
};

static void
avif_context_free (struct avif_context *context)
{
    if (!context)
        return;

    if (context->decoder) {
        avifDecoderDestroy (context->decoder);
        context->decoder = NULL;
    }

    if (context->data) {
        g_byte_array_unref (context->data);
        context->bytes = NULL;
    }

    if (context->bytes) {
        g_bytes_unref (context->bytes);
        context->bytes = NULL;
    }

    if (context->pixbuf) {
        g_object_unref (context->pixbuf);
        context->pixbuf = NULL;
    }

    g_free (context);
}

static gboolean
avif_context_try_load (struct avif_context *context, GError **error)
{
    avifResult ret;
    avifDecoder *decoder = context->decoder;
    avifImage *image;
    avifRGBImage rgb;
    const uint8_t *data;
    size_t size;
    int width, height;
    GdkPixbuf *output;

    data = g_bytes_get_data (context->bytes, &size);

    ret = avifDecoderSetIOMemory (decoder, data, size);
    if (ret != AVIF_RESULT_OK) {
        g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
                     "Couldn't decode image: %s", avifResultToString (ret));
        return FALSE;
    }

    ret = avifDecoderParse (decoder);
    if (ret != AVIF_RESULT_OK) {
        g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
                     "Couldn't decode image: %s", avifResultToString (ret));
        return FALSE;
    }

    if (decoder->imageCount > 1) {
        g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_FAILED,
                             "Image sequences not yet implemented");
        return FALSE;
    }

    ret = avifDecoderNextImage (decoder);
    if (ret == AVIF_RESULT_NO_IMAGES_REMAINING) {
        /* No more images, bail out. Verify that you got the expected amount of images decoded. */
        return TRUE;
    } else if (ret != AVIF_RESULT_OK) {
        g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_FAILED,
                     "Failed to decode all frames: %s", avifResultToString (ret));
        return FALSE;
    }

    image = decoder->image;
    width = image->width;
    height = image->height;

    avifRGBImageSetDefaults (&rgb, image);
    rgb.depth = 8;

    if (image->alphaPlane) {
        rgb.format = AVIF_RGB_FORMAT_RGBA;
        output = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
                                 TRUE, 8, width, height);
    } else {
        rgb.format = AVIF_RGB_FORMAT_RGB;
        output = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
                                 FALSE, 8, width, height);
    }

    if (output == NULL) {
        g_set_error_literal (error,
                             GDK_PIXBUF_ERROR,
                             GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
                             "Insufficient memory to open AVIF file");
        return FALSE;
    }

    rgb.pixels = gdk_pixbuf_get_pixels (output);
    rgb.rowBytes = gdk_pixbuf_get_rowstride (output);

    ret = avifImageYUVToRGB (image, &rgb);
    if (ret != AVIF_RESULT_OK) {
        g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_FAILED,
                     "Failed to convert YUV to RGB: %s", avifResultToString (ret));
        g_object_unref (output);
        return FALSE;
    }

    /* transformations */
    if (image->transformFlags & AVIF_TRANSFORM_CLAP) {
        if ((image->clap.widthD > 0) && (image->clap.heightD > 0) && (image->clap.horizOffD > 0) && (image->clap.vertOffD > 0)) {

            int new_width, new_height;

            new_width = (int) ((double) (image->clap.widthN) / (image->clap.widthD) + 0.5);
            if (new_width > width) {
                new_width = width;
            }

            new_height = (int) ((double) (image->clap.heightN) / (image->clap.heightD) + 0.5);
            if (new_height > height) {
                new_height = height;
            }

            if (new_width > 0 && new_height > 0) {
                int offx, offy;
                GdkPixbuf *output_cropped;
                GdkPixbuf *cropped_copy;

                offx = ((double) ((int32_t) image->clap.horizOffN)) / (image->clap.horizOffD) + (width - new_width) / 2.0 + 0.5;
                if (offx < 0) {
                    offx = 0;
                } else if (offx > (width - new_width)) {
                    offx = width - new_width;
                }

                offy = ((double) ((int32_t) image->clap.vertOffN)) / (image->clap.vertOffD) + (height - new_height) / 2.0 + 0.5;
                if (offy < 0) {
                    offy = 0;
                } else if (offy > (height - new_height)) {
                    offy = height - new_height;
                }

                output_cropped = gdk_pixbuf_new_subpixbuf (output, offx, offy, new_width, new_height);
                cropped_copy = gdk_pixbuf_copy (output_cropped);
                g_clear_object (&output_cropped);

                if (cropped_copy) {
                    g_object_unref (output);
                    output = cropped_copy;
                }
            }
        } else {
            /* Zero values, we need to avoid 0 divide. */
            g_warning ("Wrong values in avifCleanApertureBox\n");
        }
    }

    if (image->transformFlags & AVIF_TRANSFORM_IROT) {
        GdkPixbuf *output_rotated = NULL;

        switch (image->irot.angle) {
        case 1:
            output_rotated = gdk_pixbuf_rotate_simple (output, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
            break;
        case 2:
            output_rotated = gdk_pixbuf_rotate_simple (output, GDK_PIXBUF_ROTATE_UPSIDEDOWN);
            break;
        case 3:
            output_rotated = gdk_pixbuf_rotate_simple (output, GDK_PIXBUF_ROTATE_CLOCKWISE);
            break;
        }

        if (output_rotated) {
            g_object_unref (output);
            output = output_rotated;
        }
    }

    if (image->transformFlags & AVIF_TRANSFORM_IMIR) {
        GdkPixbuf *output_mirrored = NULL;

        switch (image->imir.axis) {
        case 0:
            output_mirrored = gdk_pixbuf_flip (output, FALSE);
            break;
        case 1:
            output_mirrored = gdk_pixbuf_flip (output, TRUE);
            break;
        }

        if (output_mirrored) {
            g_object_unref (output);
            output = output_mirrored;
        }
    }

    /* width, height could be different after applied transformations */
    width = gdk_pixbuf_get_width (output);
    height = gdk_pixbuf_get_height (output);

    if (context->size_func) {
        (*context->size_func) (&width, &height, context->user_data);
    }

    if (width == 0 || height == 0) {
        g_set_error_literal (error,
                             GDK_PIXBUF_ERROR,
                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
                             "Transformed AVIF has zero width or height");
        g_object_unref (output);
        return FALSE;
    }

    if (width < gdk_pixbuf_get_width (output) || height < gdk_pixbuf_get_height (output)) {
        GdkPixbuf *output_scaled = NULL;

        output_scaled = gdk_pixbuf_scale_simple (output, width, height, GDK_INTERP_HYPER);
        if (output_scaled) {
            g_object_unref (output);
            output = output_scaled;
        }
    }

    if (image->icc.size != 0) {
        gchar *icc_base64 = g_base64_encode ((const guchar *) image->icc.data, image->icc.size);
        gdk_pixbuf_set_option (output, "icc-profile", icc_base64);
        g_free (icc_base64);
    }

    if (context->pixbuf) {
        g_object_unref (context->pixbuf);
        context->pixbuf = NULL;
    }

    context->pixbuf = output;
    context->prepared_func (context->pixbuf, NULL, context->user_data);

    return TRUE;
}

static gpointer
begin_load (GdkPixbufModuleSizeFunc size_func,
            GdkPixbufModulePreparedFunc prepared_func,
            GdkPixbufModuleUpdatedFunc updated_func,
            gpointer user_data,
            GError **error)
{
    struct avif_context *context;
    avifDecoder *decoder;

    g_assert (prepared_func != NULL);

    decoder = avifDecoderCreate ();
    if (!decoder) {
        g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
                             "Couldn't allocate memory for decoder");
        return NULL;
    }

    context = g_new0 (struct avif_context, 1);
    if (!context)
        return NULL;

    context->size_func = size_func;
    context->updated_func = updated_func;
    context->prepared_func = prepared_func;
    context->user_data = user_data;

    context->decoder = decoder;
    context->data = g_byte_array_sized_new (40000);

    return context;
}

static gboolean
stop_load (gpointer data, GError **error)
{
    struct avif_context *context = (struct avif_context *) data;
    gboolean ret;

    context->bytes = g_byte_array_free_to_bytes (context->data);
    context->data = NULL;
    ret = avif_context_try_load (context, error);

    avif_context_free (context);

    return ret;
}

static gboolean
load_increment (gpointer data, const guchar *buf, guint size, GError **error)
{
    struct avif_context *context = (struct avif_context *) data;
    g_byte_array_append (context->data, buf, size);
    if (error)
        *error = NULL;
    return TRUE;
}

static gboolean
avif_is_save_option_supported (const gchar *option_key)
{
    if (g_strcmp0 (option_key, "quality") == 0) {
        return TRUE;
    }

    return FALSE;
}

static gboolean
avif_image_saver (FILE *f,
                  GdkPixbuf *pixbuf,
                  gchar **keys,
                  gchar **values,
                  GError **error)
{
    int width, height;
    long quality = 68; /* default; must be between 0 and 100 */
    gboolean save_alpha;
    avifImage *avif;
    avifRGBImage rgb;
    avifResult res;
    avifRWData raw = AVIF_DATA_EMPTY;
    avifEncoder *encoder;
    guint maxThreads;

    if (f == NULL || pixbuf == NULL) {
        return FALSE;
    }

    if (keys && *keys) {
        gchar **kiter = keys;
        gchar **viter = values;

        while (*kiter) {
            if (strcmp (*kiter, "quality") == 0) {
                char *endptr = NULL;
                quality = strtol (*viter, &endptr, 10);

                if (endptr == *viter) {
                    g_set_error (error,
                                 GDK_PIXBUF_ERROR,
                                 GDK_PIXBUF_ERROR_BAD_OPTION,
                                 "AVIF quality must be a value between 0 and 100; value \"%s\" could not be parsed.",
                                 *viter);

                    return FALSE;
                }

                if (quality < 0 || quality > 100) {
                    g_set_error (error,
                                 GDK_PIXBUF_ERROR,
                                 GDK_PIXBUF_ERROR_BAD_OPTION,
                                 "AVIF quality must be a value between 0 and 100; value \"%ld\" is not allowed.",
                                 quality);

                    return FALSE;
                }
            } else {
                g_warning ("Unrecognized parameter (%s) passed to AVIF saver.", *kiter);
            }

            ++kiter;
            ++viter;
        }
    }

    if (gdk_pixbuf_get_bits_per_sample (pixbuf) != 8) {
        g_set_error (error,
                     GDK_PIXBUF_ERROR,
                     GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
                     "Sorry, only 8bit images are supported by this AVIF saver");
        return FALSE;
    }

    width = gdk_pixbuf_get_width (pixbuf);
    height = gdk_pixbuf_get_height (pixbuf);

    if (width == 0 || height == 0) {
        g_set_error (error,
                     GDK_PIXBUF_ERROR,
                     GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
                     "Empty image, nothing to save");
        return FALSE;
    }

    save_alpha = gdk_pixbuf_get_has_alpha (pixbuf);

    if (save_alpha) {
        if (gdk_pixbuf_get_n_channels (pixbuf) != 4) {
            g_set_error (error,
                         GDK_PIXBUF_ERROR,
                         GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
                         "Unsupported number of channels");
            return FALSE;
        }
    } else {
        if (gdk_pixbuf_get_n_channels (pixbuf) != 3) {
            g_set_error (error,
                         GDK_PIXBUF_ERROR,
                         GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
                         "Unsupported number of channels");
            return FALSE;
        }
    }

    avif = avifImageCreate (width, height, 8, quality >= 90 ? AVIF_PIXEL_FORMAT_YUV444 : AVIF_PIXEL_FORMAT_YUV420);
    avif->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT601;
    avifRGBImageSetDefaults (&rgb, avif);

    rgb.depth = 8;
    rgb.pixels = (uint8_t *) gdk_pixbuf_read_pixels (pixbuf);
    rgb.rowBytes = gdk_pixbuf_get_rowstride (pixbuf);

    if (save_alpha) {
        rgb.format = AVIF_RGB_FORMAT_RGBA;
    } else {
        rgb.format = AVIF_RGB_FORMAT_RGB;
    }

    res = avifImageRGBToYUV (avif, &rgb);
    if (res != AVIF_RESULT_OK) {
        g_set_error (error,
                     GDK_PIXBUF_ERROR,
                     GDK_PIXBUF_ERROR_FAILED,
                     "Problem in RGB->YUV conversion: %s", avifResultToString (res));
        avifImageDestroy (avif);
        return FALSE;
    }

    maxThreads = g_get_num_processors ();
    encoder = avifEncoderCreate ();

    encoder->maxThreads = CLAMP (maxThreads, 1, 64);
    encoder->quality = (int) quality;
    if (save_alpha) {
        if (quality >= 50) {
            encoder->qualityAlpha = 100;
        } else {
            encoder->qualityAlpha = 75 + (int) quality / 2;
        }
    }
    encoder->speed = 6;

    res = avifEncoderWrite (encoder, avif, &raw);
    avifEncoderDestroy (encoder);
    avifImageDestroy (avif);

    if (res == AVIF_RESULT_OK) {
        fwrite (raw.data, 1, raw.size, f);
        avifRWDataFree (&raw);
        return TRUE;
    }

    g_set_error (error,
                 GDK_PIXBUF_ERROR,
                 GDK_PIXBUF_ERROR_FAILED,
                 "AVIF encoder problem: %s", avifResultToString (res));
    return FALSE;
}

G_MODULE_EXPORT void
fill_vtable (GdkPixbufModule *module)
{
    module->begin_load = begin_load;
    module->stop_load = stop_load;
    module->load_increment = load_increment;
    module->is_save_option_supported = avif_is_save_option_supported;
    module->save = avif_image_saver;
}

G_MODULE_EXPORT void
fill_info (GdkPixbufFormat *info)
{
    static GdkPixbufModulePattern signature[] = {
        { "    ftypavif", "zzz         ", 100 }, /* file begins with 'ftypavif' at offset 4 */
        { NULL, NULL, 0 }
    };
    static gchar *mime_types[] = {
        "image/avif",
        NULL
    };
    static gchar *extensions[] = {
        "avif",
        NULL
    };

    info->name = "avif";
    info->signature = (GdkPixbufModulePattern *) signature;
    info->description = "AV1 Image File Format";
    info->mime_types = (gchar **) mime_types;
    info->extensions = (gchar **) extensions;
    info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
    info->license = "BSD";
    info->disabled = FALSE;
}
