// Copyright 2020 Joe Drago. All rights reserved.
// SPDX-License-Identifier: BSD-2-Clause

#include "avifjpeg.h"
#include "avifexif.h"
#include "avifutil.h"

#include <assert.h>
#include <setjmp.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "jpeglib.h"

#include "iccjpeg.h"

#define AVIF_MIN(a, b) (((a) < (b)) ? (a) : (b))
#define AVIF_MAX(a, b) (((a) > (b)) ? (a) : (b))

struct my_error_mgr
{
    struct jpeg_error_mgr pub;
    jmp_buf setjmp_buffer;
};
typedef struct my_error_mgr * my_error_ptr;
static void my_error_exit(j_common_ptr cinfo)
{
    my_error_ptr myerr = (my_error_ptr)cinfo->err;
    (*cinfo->err->output_message)(cinfo);
    longjmp(myerr->setjmp_buffer, 1);
}

#if JPEG_LIB_VERSION >= 70
#define AVIF_LIBJPEG_DCT_v_scaled_size DCT_v_scaled_size
#define AVIF_LIBJPEG_DCT_h_scaled_size DCT_h_scaled_size
#else
#define AVIF_LIBJPEG_DCT_h_scaled_size DCT_scaled_size
#define AVIF_LIBJPEG_DCT_v_scaled_size DCT_scaled_size
#endif

// An internal function used by avifJPEGReadCopy(), this is the shared libjpeg decompression code
// for all paths avifJPEGReadCopy() takes.
static avifBool avifJPEGCopyPixels(avifImage * avif, struct jpeg_decompress_struct * cinfo)
{
    cinfo->raw_data_out = TRUE;
    jpeg_start_decompress(cinfo);

    avif->width = cinfo->image_width;
    avif->height = cinfo->image_height;

    JSAMPIMAGE buffer = (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_IMAGE, sizeof(JSAMPARRAY) * cinfo->num_components);

    // lines of output image to be read per jpeg_read_raw_data call
    int readLines = 0;
    // lines of samples to be read per call (for each channel)
    int linesPerCall[3] = { 0, 0, 0 };
    // expected count of sample lines (for each channel)
    int targetRead[3] = { 0, 0, 0 };
    for (int i = 0; i < cinfo->num_components; ++i) {
        jpeg_component_info * comp = &cinfo->comp_info[i];

        linesPerCall[i] = comp->v_samp_factor * comp->AVIF_LIBJPEG_DCT_v_scaled_size;
        targetRead[i] = comp->downsampled_height;
        buffer[i] = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo,
                                                JPOOL_IMAGE,
                                                comp->width_in_blocks * comp->AVIF_LIBJPEG_DCT_h_scaled_size,
                                                linesPerCall[i]);
        readLines = AVIF_MAX(readLines, linesPerCall[i]);
    }

    if (avifImageAllocatePlanes(avif, AVIF_PLANES_YUV) != AVIF_RESULT_OK) {
        return AVIF_FALSE;
    }

    // destination avif channel for each jpeg channel
    avifChannelIndex targetChannel[3] = { AVIF_CHAN_Y, AVIF_CHAN_Y, AVIF_CHAN_Y };
    if (cinfo->jpeg_color_space == JCS_YCbCr) {
        targetChannel[0] = AVIF_CHAN_Y;
        targetChannel[1] = AVIF_CHAN_U;
        targetChannel[2] = AVIF_CHAN_V;
    } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
        targetChannel[0] = AVIF_CHAN_Y;
    } else {
        // cinfo->jpeg_color_space == JCS_RGB
        targetChannel[0] = AVIF_CHAN_V;
        targetChannel[1] = AVIF_CHAN_Y;
        targetChannel[2] = AVIF_CHAN_U;
    }

    int workComponents = avif->yuvFormat == AVIF_PIXEL_FORMAT_YUV400 ? 1 : cinfo->num_components;

    // count of already-read lines (for each channel)
    int alreadyRead[3] = { 0, 0, 0 };
    while (cinfo->output_scanline < cinfo->output_height) {
        jpeg_read_raw_data(cinfo, buffer, readLines);

        for (int i = 0; i < workComponents; ++i) {
            int linesRead = AVIF_MIN(targetRead[i] - alreadyRead[i], linesPerCall[i]);
            for (int j = 0; j < linesRead; ++j) {
                memcpy(&avif->yuvPlanes[targetChannel[i]][avif->yuvRowBytes[targetChannel[i]] * (alreadyRead[i] + j)],
                       buffer[i][j],
                       avif->yuvRowBytes[targetChannel[i]]);
            }
            alreadyRead[i] += linesPerCall[i];
        }
    }
    return AVIF_TRUE;
}

static avifBool avifJPEGHasCompatibleMatrixCoefficients(avifMatrixCoefficients matrixCoefficients)
{
    switch (matrixCoefficients) {
        case AVIF_MATRIX_COEFFICIENTS_BT470BG:
        case AVIF_MATRIX_COEFFICIENTS_BT601:
            // JPEG always uses [Kr:0.299, Kb:0.114], which matches these MCs.
            return AVIF_TRUE;
    }
    return AVIF_FALSE;
}

// This attempts to copy the internal representation of the JPEG directly into avifImage without
// YUV->RGB conversion. If it returns AVIF_FALSE, a typical RGB->YUV conversion is required.
static avifBool avifJPEGReadCopy(avifImage * avif, struct jpeg_decompress_struct * cinfo)
{
    if ((avif->depth != 8) || (avif->yuvRange != AVIF_RANGE_FULL)) {
        return AVIF_FALSE;
    }

    if (cinfo->jpeg_color_space == JCS_YCbCr) {
        // Import from YUV: must use compatible matrixCoefficients.
        if (avifJPEGHasCompatibleMatrixCoefficients(avif->matrixCoefficients)) {
            // YUV->YUV: require precise match for pixel format.
            avifPixelFormat jpegFormat = AVIF_PIXEL_FORMAT_NONE;
            if (cinfo->comp_info[0].h_samp_factor == 1 && cinfo->comp_info[0].v_samp_factor == 1 &&
                cinfo->comp_info[1].h_samp_factor == 1 && cinfo->comp_info[1].v_samp_factor == 1 &&
                cinfo->comp_info[2].h_samp_factor == 1 && cinfo->comp_info[2].v_samp_factor == 1) {
                jpegFormat = AVIF_PIXEL_FORMAT_YUV444;
            } else if (cinfo->comp_info[0].h_samp_factor == 2 && cinfo->comp_info[0].v_samp_factor == 1 &&
                       cinfo->comp_info[1].h_samp_factor == 1 && cinfo->comp_info[1].v_samp_factor == 1 &&
                       cinfo->comp_info[2].h_samp_factor == 1 && cinfo->comp_info[2].v_samp_factor == 1) {
                jpegFormat = AVIF_PIXEL_FORMAT_YUV422;
            } else if (cinfo->comp_info[0].h_samp_factor == 2 && cinfo->comp_info[0].v_samp_factor == 2 &&
                       cinfo->comp_info[1].h_samp_factor == 1 && cinfo->comp_info[1].v_samp_factor == 1 &&
                       cinfo->comp_info[2].h_samp_factor == 1 && cinfo->comp_info[2].v_samp_factor == 1) {
                jpegFormat = AVIF_PIXEL_FORMAT_YUV420;
            }
            if (jpegFormat != AVIF_PIXEL_FORMAT_NONE) {
                if (avif->yuvFormat == AVIF_PIXEL_FORMAT_NONE) {
                    // The requested format is "auto": Adopt JPEG's internal format.
                    avif->yuvFormat = jpegFormat;
                }
                if (avif->yuvFormat == jpegFormat) {
                    cinfo->out_color_space = JCS_YCbCr;
                    return avifJPEGCopyPixels(avif, cinfo);
                }
            }

            // YUV->Grayscale: subsample Y plane not allowed.
            if ((avif->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) && (cinfo->comp_info[0].h_samp_factor == cinfo->max_h_samp_factor &&
                                                                  cinfo->comp_info[0].v_samp_factor == cinfo->max_v_samp_factor)) {
                cinfo->out_color_space = JCS_YCbCr;
                return avifJPEGCopyPixels(avif, cinfo);
            }
        }
    } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
        // Import from Grayscale: subsample not allowed.
        if ((cinfo->comp_info[0].h_samp_factor == cinfo->max_h_samp_factor &&
             cinfo->comp_info[0].v_samp_factor == cinfo->max_v_samp_factor)) {
            // Import to YUV/Grayscale: must use compatible matrixCoefficients.
            if (avifJPEGHasCompatibleMatrixCoefficients(avif->matrixCoefficients)) {
                // Grayscale->Grayscale: direct copy.
                if ((avif->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) || (avif->yuvFormat == AVIF_PIXEL_FORMAT_NONE)) {
                    avif->yuvFormat = AVIF_PIXEL_FORMAT_YUV400;
                    cinfo->out_color_space = JCS_GRAYSCALE;
                    return avifJPEGCopyPixels(avif, cinfo);
                }

                // Grayscale->YUV: copy Y, fill UV with monochrome value.
                if ((avif->yuvFormat == AVIF_PIXEL_FORMAT_YUV444) || (avif->yuvFormat == AVIF_PIXEL_FORMAT_YUV422) ||
                    (avif->yuvFormat == AVIF_PIXEL_FORMAT_YUV420)) {
                    cinfo->out_color_space = JCS_GRAYSCALE;
                    if (!avifJPEGCopyPixels(avif, cinfo)) {
                        return AVIF_FALSE;
                    }

                    uint32_t uvHeight = avifImagePlaneHeight(avif, AVIF_CHAN_U);
                    memset(avif->yuvPlanes[AVIF_CHAN_U], 128, (size_t)avif->yuvRowBytes[AVIF_CHAN_U] * uvHeight);
                    memset(avif->yuvPlanes[AVIF_CHAN_V], 128, (size_t)avif->yuvRowBytes[AVIF_CHAN_V] * uvHeight);

                    return AVIF_TRUE;
                }
            }

            // Grayscale->RGB: copy Y to G, duplicate to B and R.
            if ((avif->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_IDENTITY) &&
                ((avif->yuvFormat == AVIF_PIXEL_FORMAT_YUV444) || (avif->yuvFormat == AVIF_PIXEL_FORMAT_NONE))) {
                avif->yuvFormat = AVIF_PIXEL_FORMAT_YUV444;
                cinfo->out_color_space = JCS_GRAYSCALE;
                if (!avifJPEGCopyPixels(avif, cinfo)) {
                    return AVIF_FALSE;
                }

                memcpy(avif->yuvPlanes[AVIF_CHAN_U], avif->yuvPlanes[AVIF_CHAN_Y], (size_t)avif->yuvRowBytes[AVIF_CHAN_U] * avif->height);
                memcpy(avif->yuvPlanes[AVIF_CHAN_V], avif->yuvPlanes[AVIF_CHAN_Y], (size_t)avif->yuvRowBytes[AVIF_CHAN_V] * avif->height);

                return AVIF_TRUE;
            }
        }
    } else if (cinfo->jpeg_color_space == JCS_RGB) {
        // RGB->RGB: subsample not allowed.
        if ((avif->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_IDENTITY) &&
            ((avif->yuvFormat == AVIF_PIXEL_FORMAT_YUV444) || (avif->yuvFormat == AVIF_PIXEL_FORMAT_NONE)) &&
            (cinfo->comp_info[0].h_samp_factor == 1 && cinfo->comp_info[0].v_samp_factor == 1 &&
             cinfo->comp_info[1].h_samp_factor == 1 && cinfo->comp_info[1].v_samp_factor == 1 &&
             cinfo->comp_info[2].h_samp_factor == 1 && cinfo->comp_info[2].v_samp_factor == 1)) {
            avif->yuvFormat = AVIF_PIXEL_FORMAT_YUV444;
            cinfo->out_color_space = JCS_RGB;
            return avifJPEGCopyPixels(avif, cinfo);
        }
    }

    // A typical RGB->YUV conversion is required.
    return AVIF_FALSE;
}

// Reads 4-byte unsigned integer in big-endian format from the raw bitstream src.
static uint32_t avifJPEGReadUint32BigEndian(const uint8_t * src)
{
    return ((uint32_t)src[0] << 24) | ((uint32_t)src[1] << 16) | ((uint32_t)src[2] << 8) | ((uint32_t)src[3] << 0);
}

// Returns the pointer in str to the first occurrence of substr. Returns NULL if substr cannot be found in str.
static const uint8_t * avifJPEGFindSubstr(const uint8_t * str, size_t strLength, const uint8_t * substr, size_t substrLength)
{
    for (size_t index = 0; index + substrLength <= strLength; ++index) {
        if (!memcmp(&str[index], substr, substrLength)) {
            return &str[index];
        }
    }
    return NULL;
}

#define AVIF_JPEG_MAX_MARKER_DATA_LENGTH 65533

// Exif tag
#define AVIF_JPEG_EXIF_HEADER "Exif\0\0"
#define AVIF_JPEG_EXIF_HEADER_LENGTH 6

// XMP tags
#define AVIF_JPEG_STANDARD_XMP_TAG "http://ns.adobe.com/xap/1.0/\0"
#define AVIF_JPEG_STANDARD_XMP_TAG_LENGTH 29
#define AVIF_JPEG_EXTENDED_XMP_TAG "http://ns.adobe.com/xmp/extension/\0"
#define AVIF_JPEG_EXTENDED_XMP_TAG_LENGTH 35

// One way of storing the Extended XMP GUID (generated by a camera for example).
#define AVIF_JPEG_XMP_NOTE_TAG "xmpNote:HasExtendedXMP=\""
#define AVIF_JPEG_XMP_NOTE_TAG_LENGTH 24
// Another way of storing the Extended XMP GUID (generated by exiftool for example).
#define AVIF_JPEG_ALTERNATIVE_XMP_NOTE_TAG "<xmpNote:HasExtendedXMP>"
#define AVIF_JPEG_ALTERNATIVE_XMP_NOTE_TAG_LENGTH 24

#define AVIF_JPEG_EXTENDED_XMP_GUID_LENGTH 32

// Offset in APP1 segment (skip tag + guid + size + offset).
#define AVIF_JPEG_OFFSET_TILL_EXTENDED_XMP (AVIF_JPEG_EXTENDED_XMP_TAG_LENGTH + AVIF_JPEG_EXTENDED_XMP_GUID_LENGTH + 4 + 4)

// Note on setjmp() and volatile variables:
//
// K & R, The C Programming Language 2nd Ed, p. 254 says:
//   ... Accessible objects have the values they had when longjmp was called,
//   except that non-volatile automatic variables in the function calling setjmp
//   become undefined if they were changed after the setjmp call.
//
// Therefore, 'iccData' is declared as volatile. 'rgb' should be declared as
// volatile, but doing so would be inconvenient (try it) and since it is a
// struct, the compiler is unlikely to put it in a register. 'ret' does not need
// to be declared as volatile because it is not modified between setjmp and
// longjmp. But GCC's -Wclobbered warning may have trouble figuring that out, so
// we preemptively declare it as volatile.

avifBool avifJPEGRead(const char * inputFilename,
                      avifImage * avif,
                      avifPixelFormat requestedFormat,
                      uint32_t requestedDepth,
                      avifChromaDownsampling chromaDownsampling,
                      avifBool ignoreColorProfile,
                      avifBool ignoreExif,
                      avifBool ignoreXMP)
{
    volatile avifBool ret = AVIF_FALSE;
    uint8_t * volatile iccData = NULL;

    avifRGBImage rgb;
    memset(&rgb, 0, sizeof(avifRGBImage));

    // Standard XMP segment followed by all extended XMP segments.
    avifRWData totalXMP = { NULL, 0 };
    // Each byte set to 0 is a missing byte. Each byte set to 1 was read and copied to totalXMP.
    avifRWData extendedXMPReadBytes = { NULL, 0 };

    FILE * f = fopen(inputFilename, "rb");
    if (!f) {
        fprintf(stderr, "Can't open JPEG file for read: %s\n", inputFilename);
        return ret;
    }

    struct my_error_mgr jerr;
    struct jpeg_decompress_struct cinfo;
    cinfo.err = jpeg_std_error(&jerr.pub);
    jerr.pub.error_exit = my_error_exit;
    if (setjmp(jerr.setjmp_buffer)) {
        goto cleanup;
    }

    jpeg_create_decompress(&cinfo);

    if (!ignoreExif || !ignoreXMP) {
        jpeg_save_markers(&cinfo, JPEG_APP0 + 1, /*length_limit=*/0xFFFF); // Exif/XMP
    }
    if (!ignoreColorProfile) {
        setup_read_icc_profile(&cinfo);
    }
    jpeg_stdio_src(&cinfo, f);
    jpeg_read_header(&cinfo, TRUE);

    if (!ignoreColorProfile) {
        uint8_t * iccDataTmp;
        unsigned int iccDataLen;
        if (read_icc_profile(&cinfo, &iccDataTmp, &iccDataLen)) {
            iccData = iccDataTmp;
            if (avifImageSetProfileICC(avif, iccDataTmp, (size_t)iccDataLen) != AVIF_RESULT_OK) {
                fprintf(stderr, "Setting ICC profile failed: %s (out of memory)\n", inputFilename);
                goto cleanup;
            }
        }
    }

    avif->yuvFormat = requestedFormat; // This may be AVIF_PIXEL_FORMAT_NONE, which is "auto" to avifJPEGReadCopy()
    avif->depth = requestedDepth ? requestedDepth : 8;
    // JPEG doesn't have alpha. Prevent confusion.
    avif->alphaPremultiplied = AVIF_FALSE;

    if (avifJPEGReadCopy(avif, &cinfo)) {
        // JPEG pixels were successfully copied without conversion. Notify the enduser.

        assert(inputFilename); // JPEG read doesn't support stdin
        printf("Directly copied JPEG pixel data (no YUV conversion): %s\n", inputFilename);
    } else {
        // JPEG pixels could not be copied without conversion. Request (converted) RGB pixels from
        // libjpeg and convert to YUV with libavif instead.

        cinfo.out_color_space = JCS_RGB;
        jpeg_start_decompress(&cinfo);

        int row_stride = cinfo.output_width * cinfo.output_components;
        JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);

        avif->width = cinfo.output_width;
        avif->height = cinfo.output_height;
#if defined(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R)
        const avifBool useYCgCoR = (avif->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_YCGCO_RE ||
                                    avif->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_YCGCO_RO);
#else
        const avifBool useYCgCoR = AVIF_FALSE;
#endif
        if (avif->yuvFormat == AVIF_PIXEL_FORMAT_NONE) {
            // Identity and YCgCo-R are only valid with YUV444.
            avif->yuvFormat = (avif->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_IDENTITY || useYCgCoR)
                                  ? AVIF_PIXEL_FORMAT_YUV444
                                  : AVIF_APP_DEFAULT_PIXEL_FORMAT;
        }
        avif->depth = requestedDepth ? requestedDepth : 8;
#if defined(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R)
        if (useYCgCoR) {
            if (avif->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_YCGCO_RO) {
                fprintf(stderr, "AVIF_MATRIX_COEFFICIENTS_YCGCO_RO cannot be used with JPEG because it has an even bit depth.\n");
                goto cleanup;
            }
            if (requestedDepth && requestedDepth != 10) {
                fprintf(stderr, "Cannot request %u bits for YCgCo-Re as it uses 2 extra bits.\n", requestedDepth);
                goto cleanup;
            }
            avif->depth = 10;
        }
#endif
        avifRGBImageSetDefaults(&rgb, avif);
        rgb.format = AVIF_RGB_FORMAT_RGB;
        rgb.chromaDownsampling = chromaDownsampling;
        rgb.depth = 8;
        if (avifRGBImageAllocatePixels(&rgb) != AVIF_RESULT_OK) {
            fprintf(stderr, "Conversion to YUV failed: %s (out of memory)\n", inputFilename);
            goto cleanup;
        }

        int row = 0;
        while (cinfo.output_scanline < cinfo.output_height) {
            jpeg_read_scanlines(&cinfo, buffer, 1);
            uint8_t * pixelRow = &rgb.pixels[row * rgb.rowBytes];
            memcpy(pixelRow, buffer[0], rgb.rowBytes);
            ++row;
        }
        if (avifImageRGBToYUV(avif, &rgb) != AVIF_RESULT_OK) {
            fprintf(stderr, "Conversion to YUV failed: %s\n", inputFilename);
            goto cleanup;
        }
    }

    if (!ignoreExif) {
        const avifROData tagExif = { (const uint8_t *)AVIF_JPEG_EXIF_HEADER, AVIF_JPEG_EXIF_HEADER_LENGTH };
        avifBool found = AVIF_FALSE;
        for (jpeg_saved_marker_ptr marker = cinfo.marker_list; marker != NULL; marker = marker->next) {
            if ((marker->marker == (JPEG_APP0 + 1)) && (marker->data_length > tagExif.size) &&
                !memcmp(marker->data, tagExif.data, tagExif.size)) {
                if (found) {
                    // TODO(yguyon): Implement instead of outputting an error.
                    fprintf(stderr, "Exif extraction failed: unsupported Exif split into multiple segments or invalid multiple Exif segments\n");
                    goto cleanup;
                }
                // Exif orientation, if any, is imported to avif->irot/imir and kept in avif->exif.
                // libheif has the same behavior, see
                // https://github.com/strukturag/libheif/blob/ea78603d8e47096606813d221725621306789ff2/examples/heif_enc.cc#L403
                if (avifImageSetMetadataExif(avif, marker->data + tagExif.size, marker->data_length - tagExif.size) != AVIF_RESULT_OK) {
                    fprintf(stderr, "Setting Exif metadata failed: %s (out of memory)\n", inputFilename);
                    goto cleanup;
                }
                found = AVIF_TRUE;
            }
        }
    }
    if (!ignoreXMP) {
        const uint8_t * standardXMPData = NULL;
        uint32_t standardXMPSize = 0; // At most 64kB as defined by Adobe XMP Specification Part 3.
        for (jpeg_saved_marker_ptr marker = cinfo.marker_list; marker != NULL; marker = marker->next) {
            if ((marker->marker == (JPEG_APP0 + 1)) && (marker->data_length > AVIF_JPEG_STANDARD_XMP_TAG_LENGTH) &&
                !memcmp(marker->data, AVIF_JPEG_STANDARD_XMP_TAG, AVIF_JPEG_STANDARD_XMP_TAG_LENGTH)) {
                if (standardXMPData) {
                    fprintf(stderr, "XMP extraction failed: invalid multiple standard XMP segments\n");
                    goto cleanup;
                }
                standardXMPData = marker->data + AVIF_JPEG_STANDARD_XMP_TAG_LENGTH;
                standardXMPSize = (uint32_t)(marker->data_length - AVIF_JPEG_STANDARD_XMP_TAG_LENGTH);
            }
        }

        avifBool foundExtendedXMP = AVIF_FALSE;
        uint8_t extendedXMPGUID[AVIF_JPEG_EXTENDED_XMP_GUID_LENGTH]; // The value is common to all extended XMP segments.
        for (jpeg_saved_marker_ptr marker = cinfo.marker_list; marker != NULL; marker = marker->next) {
            if ((marker->marker == (JPEG_APP0 + 1)) && (marker->data_length > AVIF_JPEG_EXTENDED_XMP_TAG_LENGTH) &&
                !memcmp(marker->data, AVIF_JPEG_EXTENDED_XMP_TAG, AVIF_JPEG_EXTENDED_XMP_TAG_LENGTH)) {
                if (!standardXMPData) {
                    fprintf(stderr, "XMP extraction failed: extended XMP segment found, missing standard XMP segment\n");
                    goto cleanup;
                }

                if (marker->data_length < AVIF_JPEG_OFFSET_TILL_EXTENDED_XMP) {
                    fprintf(stderr, "XMP extraction failed: truncated extended XMP segment\n");
                    goto cleanup;
                }
                const uint8_t * guid = &marker->data[AVIF_JPEG_EXTENDED_XMP_TAG_LENGTH];
                for (size_t c = 0; c < AVIF_JPEG_EXTENDED_XMP_GUID_LENGTH; ++c) {
                    // According to Adobe XMP Specification Part 3 section 1.1.3.1:
                    //   "128-bit GUID stored as a 32-byte ASCII hex string, capital A-F, no null termination"
                    if (((guid[c] < '0') || (guid[c] > '9')) && ((guid[c] < 'A') || (guid[c] > 'F'))) {
                        fprintf(stderr, "XMP extraction failed: invalid XMP segment GUID\n");
                        goto cleanup;
                    }
                }
                // Size of the current extended segment.
                const size_t extendedXMPSize = marker->data_length - AVIF_JPEG_OFFSET_TILL_EXTENDED_XMP;
                // Expected size of the sum of all extended segments.
                // According to Adobe XMP Specification Part 3 section 1.1.3.1:
                //   "full length of the ExtendedXMP serialization as a 32-bit unsigned integer"
                const uint32_t totalExtendedXMPSize =
                    avifJPEGReadUint32BigEndian(&marker->data[AVIF_JPEG_EXTENDED_XMP_TAG_LENGTH + AVIF_JPEG_EXTENDED_XMP_GUID_LENGTH]);
                // Offset in totalXMP after standardXMP.
                // According to Adobe XMP Specification Part 3 section 1.1.3.1:
                //   "offset of this portion as a 32-bit unsigned integer"
                const uint32_t extendedXMPOffset = avifJPEGReadUint32BigEndian(
                    &marker->data[AVIF_JPEG_EXTENDED_XMP_TAG_LENGTH + AVIF_JPEG_EXTENDED_XMP_GUID_LENGTH + 4]);
                if (((uint64_t)standardXMPSize + totalExtendedXMPSize) > SIZE_MAX) {
                    fprintf(stderr, "XMP extraction failed: total XMP size is too large\n");
                    goto cleanup;
                }
                if ((extendedXMPSize == 0) || (((uint64_t)extendedXMPOffset + extendedXMPSize) > totalExtendedXMPSize)) {
                    fprintf(stderr, "XMP extraction failed: invalid extended XMP segment size or offset\n");
                    goto cleanup;
                }
                if (foundExtendedXMP) {
                    if (memcmp(guid, extendedXMPGUID, AVIF_JPEG_EXTENDED_XMP_GUID_LENGTH)) {
                        fprintf(stderr, "XMP extraction failed: extended XMP segment GUID mismatch\n");
                        goto cleanup;
                    }
                    if (totalExtendedXMPSize != (totalXMP.size - standardXMPSize)) {
                        fprintf(stderr, "XMP extraction failed: extended XMP total size mismatch\n");
                        goto cleanup;
                    }
                } else {
                    memcpy(extendedXMPGUID, guid, AVIF_JPEG_EXTENDED_XMP_GUID_LENGTH);

                    if (avifRWDataRealloc(&totalXMP, (size_t)standardXMPSize + totalExtendedXMPSize) != AVIF_RESULT_OK) {
                        fprintf(stderr, "XMP extraction failed: out of memory\n");
                        goto cleanup;
                    }
                    memcpy(totalXMP.data, standardXMPData, standardXMPSize);

                    // Keep track of the bytes that were set.
                    if (avifRWDataRealloc(&extendedXMPReadBytes, totalExtendedXMPSize) != AVIF_RESULT_OK) {
                        fprintf(stderr, "XMP extraction failed: out of memory\n");
                        goto cleanup;
                    }
                    memset(extendedXMPReadBytes.data, 0, extendedXMPReadBytes.size);

                    foundExtendedXMP = AVIF_TRUE;
                }
                // According to Adobe XMP Specification Part 3 section 1.1.3.1:
                //   "A robust JPEG reader should tolerate the marker segments in any order."
                memcpy(&totalXMP.data[standardXMPSize + extendedXMPOffset], &marker->data[AVIF_JPEG_OFFSET_TILL_EXTENDED_XMP], extendedXMPSize);

                // Make sure no previously read data was overwritten by the current segment.
                if (memchr(&extendedXMPReadBytes.data[extendedXMPOffset], 1, extendedXMPSize)) {
                    fprintf(stderr, "XMP extraction failed: overlapping extended XMP segments\n");
                    goto cleanup;
                }
                // Keep track of the bytes that were set.
                memset(&extendedXMPReadBytes.data[extendedXMPOffset], 1, extendedXMPSize);
            }
        }

        if (foundExtendedXMP) {
            // Make sure there is no missing byte.
            if (memchr(extendedXMPReadBytes.data, 0, extendedXMPReadBytes.size)) {
                fprintf(stderr, "XMP extraction failed: missing extended XMP segments\n");
                goto cleanup;
            }

            // According to Adobe XMP Specification Part 3 section 1.1.3.1:
            //   "A reader must incorporate only ExtendedXMP blocks whose GUID matches the value of xmpNote:HasExtendedXMP."
            uint8_t xmpNote[AVIF_JPEG_XMP_NOTE_TAG_LENGTH + AVIF_JPEG_EXTENDED_XMP_GUID_LENGTH];
            memcpy(xmpNote, AVIF_JPEG_XMP_NOTE_TAG, AVIF_JPEG_XMP_NOTE_TAG_LENGTH);
            memcpy(xmpNote + AVIF_JPEG_XMP_NOTE_TAG_LENGTH, extendedXMPGUID, AVIF_JPEG_EXTENDED_XMP_GUID_LENGTH);
            if (!avifJPEGFindSubstr(standardXMPData, standardXMPSize, xmpNote, sizeof(xmpNote))) {
                // Try the alternative before returning an error.
                uint8_t alternativeXmpNote[AVIF_JPEG_ALTERNATIVE_XMP_NOTE_TAG_LENGTH + AVIF_JPEG_EXTENDED_XMP_GUID_LENGTH];
                memcpy(alternativeXmpNote, AVIF_JPEG_ALTERNATIVE_XMP_NOTE_TAG, AVIF_JPEG_ALTERNATIVE_XMP_NOTE_TAG_LENGTH);
                memcpy(alternativeXmpNote + AVIF_JPEG_ALTERNATIVE_XMP_NOTE_TAG_LENGTH, extendedXMPGUID, AVIF_JPEG_EXTENDED_XMP_GUID_LENGTH);
                if (!avifJPEGFindSubstr(standardXMPData, standardXMPSize, alternativeXmpNote, sizeof(alternativeXmpNote))) {
                    fprintf(stderr, "XMP extraction failed: standard and extended XMP GUID mismatch\n");
                    goto cleanup;
                }
            }

            // According to Adobe XMP Specification Part 3 section 1.1.3.1:
            //   "A JPEG reader must [...] remove the xmpNote:HasExtendedXMP property."
            // This constraint is ignored here because leaving the xmpNote:HasExtendedXMP property is rather harmless
            // and editing XMP metadata is quite involved.

            avifRWDataFree(&avif->xmp);
            avif->xmp = totalXMP;
            totalXMP.data = NULL;
            totalXMP.size = 0;
        } else if (standardXMPData) {
            if (avifImageSetMetadataXMP(avif, standardXMPData, standardXMPSize) != AVIF_RESULT_OK) {
                fprintf(stderr, "XMP extraction failed: out of memory\n");
                goto cleanup;
            }
        }
        avifImageFixXMP(avif); // Remove one trailing null character if any.
    }
    jpeg_finish_decompress(&cinfo);
    ret = AVIF_TRUE;
cleanup:
    jpeg_destroy_decompress(&cinfo);
    fclose(f);
    free(iccData);
    avifRGBImageFreePixels(&rgb);
    avifRWDataFree(&totalXMP);
    avifRWDataFree(&extendedXMPReadBytes);
    return ret;
}

avifBool avifJPEGWrite(const char * outputFilename, const avifImage * avif, int jpegQuality, avifChromaUpsampling chromaUpsampling)
{
    avifBool ret = AVIF_FALSE;
    FILE * f = NULL;

    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPROW row_pointer[1];
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);

    avifRGBImage rgb;
    avifRGBImageSetDefaults(&rgb, avif);
    rgb.format = AVIF_RGB_FORMAT_RGB;
    rgb.chromaUpsampling = chromaUpsampling;
    rgb.depth = 8;
    if (avifRGBImageAllocatePixels(&rgb) != AVIF_RESULT_OK) {
        fprintf(stderr, "Conversion to RGB failed: %s (out of memory)\n", outputFilename);
        goto cleanup;
    }
    if (avifImageYUVToRGB(avif, &rgb) != AVIF_RESULT_OK) {
        fprintf(stderr, "Conversion to RGB failed: %s\n", outputFilename);
        goto cleanup;
    }

    f = fopen(outputFilename, "wb");
    if (!f) {
        fprintf(stderr, "Can't open JPEG file for write: %s\n", outputFilename);
        goto cleanup;
    }

    jpeg_stdio_dest(&cinfo, f);
    cinfo.image_width = avif->width;
    cinfo.image_height = avif->height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, jpegQuality, TRUE);
    jpeg_start_compress(&cinfo, TRUE);

    if (avif->icc.data && (avif->icc.size > 0)) {
        // TODO(yguyon): Use jpeg_write_icc_profile() instead?
        write_icc_profile(&cinfo, avif->icc.data, (unsigned int)avif->icc.size);
    }

    if (avif->exif.data && (avif->exif.size > 0)) {
        size_t exifTiffHeaderOffset;
        avifResult result = avifGetExifTiffHeaderOffset(avif->exif.data, avif->exif.size, &exifTiffHeaderOffset);
        if (result != AVIF_RESULT_OK) {
            fprintf(stderr, "Error writing JPEG metadata: %s\n", avifResultToString(result));
            goto cleanup;
        }

        avifRWData exif = { NULL, 0 };
        if (avifRWDataRealloc(&exif, AVIF_JPEG_EXIF_HEADER_LENGTH + avif->exif.size - exifTiffHeaderOffset) != AVIF_RESULT_OK) {
            fprintf(stderr, "Error writing JPEG metadata: out of memory\n");
            goto cleanup;
        }
        memcpy(exif.data, AVIF_JPEG_EXIF_HEADER, AVIF_JPEG_EXIF_HEADER_LENGTH);
        memcpy(exif.data + AVIF_JPEG_EXIF_HEADER_LENGTH, avif->exif.data + exifTiffHeaderOffset, avif->exif.size - exifTiffHeaderOffset);
        // Make sure the Exif orientation matches the irot/imir values.
        // libheif does not have the same behavior. The orientation is applied to samples and orientation data is discarded there,
        // see https://github.com/strukturag/libheif/blob/ea78603d8e47096606813d221725621306789ff2/examples/encoder_jpeg.cc#L187
        const uint8_t orientation = avifImageGetExifOrientationFromIrotImir(avif);
        result = avifSetExifOrientation(&exif, orientation);
        if (result != AVIF_RESULT_OK) {
            // Ignore errors if the orientation is the default one because not being able to set Exif orientation now
            // means a reader will not be able to parse it later either.
            if (orientation != 1) {
                fprintf(stderr, "Error writing JPEG metadata: %s\n", avifResultToString(result));
                avifRWDataFree(&exif);
                goto cleanup;
            }
        }

        avifROData remainingExif = { exif.data, exif.size };
        while (remainingExif.size > AVIF_JPEG_MAX_MARKER_DATA_LENGTH) {
            jpeg_write_marker(&cinfo, JPEG_APP0 + 1, remainingExif.data, AVIF_JPEG_MAX_MARKER_DATA_LENGTH);
            remainingExif.data += AVIF_JPEG_MAX_MARKER_DATA_LENGTH;
            remainingExif.size -= AVIF_JPEG_MAX_MARKER_DATA_LENGTH;
        }
        jpeg_write_marker(&cinfo, JPEG_APP0 + 1, remainingExif.data, (unsigned int)remainingExif.size);
        avifRWDataFree(&exif);
    } else if (avifImageGetExifOrientationFromIrotImir(avif) != 1) {
        // There is no Exif yet, but we need to store the orientation.
        // TODO(yguyon): Add a valid Exif payload or rotate the samples.
    }

    if (avif->xmp.data && (avif->xmp.size > 0)) {
        // See XMP specification part 3.
        if (avif->xmp.size > 65502) {
            // libheif just refuses to export JPEG with long XMP, see
            // https://github.com/strukturag/libheif/blob/18291ddebc23c924440a8a3c9a7267fe3beb5901/examples/encoder_jpeg.cc#L227
            // But libheif also ignores extended XMP at reading, so converting a JPEG with extended XMP to HEIC and back to JPEG
            // works, with the extended XMP part dropped, even if it had fit into a single JPEG marker.

            // In libavif the whole XMP payload is dropped if it exceeds a single JPEG marker size limit, with a warning.
            // The advantage is that it keeps the whole XMP payload, including the extended part, if it fits into a single JPEG
            // marker. This is acceptable because section 1.1.3.1 of XMP specification part 3 says
            //   "It is unusual for XMP to exceed 65502 bytes; typically, it is around 2 KB."
            fprintf(stderr, "Warning writing JPEG metadata: XMP payload is too big and was dropped\n");
        } else {
            avifRWData xmp = { NULL, 0 };
            if (avifRWDataRealloc(&xmp, AVIF_JPEG_STANDARD_XMP_TAG_LENGTH + avif->xmp.size) != AVIF_RESULT_OK) {
                fprintf(stderr, "Error writing JPEG metadata: out of memory\n");
                goto cleanup;
            }
            memcpy(xmp.data, AVIF_JPEG_STANDARD_XMP_TAG, AVIF_JPEG_STANDARD_XMP_TAG_LENGTH);
            memcpy(xmp.data + AVIF_JPEG_STANDARD_XMP_TAG_LENGTH, avif->xmp.data, avif->xmp.size);
            jpeg_write_marker(&cinfo, JPEG_APP0 + 1, xmp.data, (unsigned int)xmp.size);
            avifRWDataFree(&xmp);
        }
    }

    while (cinfo.next_scanline < cinfo.image_height) {
        row_pointer[0] = &rgb.pixels[cinfo.next_scanline * rgb.rowBytes];
        (void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }

    jpeg_finish_compress(&cinfo);
    ret = AVIF_TRUE;
    printf("Wrote JPEG: %s\n", outputFilename);
cleanup:
    if (f) {
        fclose(f);
    }
    jpeg_destroy_compress(&cinfo);
    avifRGBImageFreePixels(&rgb);
    return ret;
}
