/*
 * Copyright © 2018, VideoLAN and dav1d authors
 * Copyright © 2018, Two Orioles, LLC
 * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT OWNER OR 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.
 */

// OBU parsing and bit magic all originally from dav1d's obu.c and getbits.c,
// but heavily modified/reduced down to simply find the Sequence Header OBU
// and pull a few interesting pieces from it.
//
// Any other code in here is under this license:
//
// Copyright 2020 Joe Drago. All rights reserved.
// SPDX-License-Identifier: BSD-2-Clause

#include "avif/internal.h"

#include <stdint.h>
#include <string.h>

#if defined(AVIF_CODEC_AVM)
#include "avm/avm_codec.h"
#endif

// ---------------------------------------------------------------------------
// avifBits - Originally dav1d's GetBits struct (see dav1d's getbits.c)

typedef struct avifBits
{
    int error, eof;
    uint64_t state;
    uint32_t bitsLeft;
    const uint8_t *ptr, *start, *end;
} avifBits;

static inline uint32_t avifBitsReadPos(const avifBits * bits)
{
    return (uint32_t)(bits->ptr - bits->start) * 8 - bits->bitsLeft;
}

static void avifBitsInit(avifBits * const bits, const uint8_t * const data, const size_t size)
{
    bits->ptr = bits->start = data;
    bits->end = &bits->start[size];
    bits->bitsLeft = 0;
    bits->state = 0;
    bits->error = 0;
    bits->eof = (size == 0);
}

static void avifBitsRefill(avifBits * const bits, const uint32_t n)
{
    uint64_t state = 0;
    do {
        state <<= 8;
        bits->bitsLeft += 8;
        if (!bits->eof)
            state |= *bits->ptr++;
        if (bits->ptr >= bits->end) {
            bits->error = bits->eof;
            bits->eof = 1;
        }
    } while (n > bits->bitsLeft);
    bits->state |= state << (64 - bits->bitsLeft);
}

static uint32_t avifBitsRead(avifBits * const bits, const uint32_t n)
{
    if (n > bits->bitsLeft)
        avifBitsRefill(bits, n);

    const uint64_t state = bits->state;
    bits->bitsLeft -= n;
    bits->state <<= n;

    return (uint32_t)(state >> (64 - n));
}

static uint32_t avifBitsReadUleb128(avifBits * bits)
{
    uint64_t val = 0;
    uint32_t more;
    uint32_t i = 0;

    do {
        const uint32_t v = avifBitsRead(bits, 8);
        more = v & 0x80;
        val |= ((uint64_t)(v & 0x7F)) << i;
        i += 7;
    } while (more && i < 56);

    if (val > UINT32_MAX || more) {
        bits->error = 1;
        return 0;
    }

    return (uint32_t)val;
}

static uint32_t avifBitsReadVLC(avifBits * const bits)
{
    int numBits = 0;
    while (!avifBitsRead(bits, 1))
        if (++numBits == 32)
            return 0xFFFFFFFFU;
    return numBits ? ((1U << numBits) - 1) + avifBitsRead(bits, numBits) : 0;
}

#if defined(AVIF_CODEC_AVM)
// Rice-Golomb coding with parameter n.
static uint32_t avifBitsReadRG(avifBits * const bits, const uint32_t n)
{
    for (uint32_t q = 0; q < 32; q++) {
        const uint32_t rgBit = avifBitsRead(bits, 1);
        if (rgBit == 0) {
            const uint32_t remainder = avifBitsRead(bits, n);
            return (q << n) + remainder;
        }
    }
    return 0xFFFFFFFFU;
}
#endif // defined(AVIF_CODEC_AVM)

// ---------------------------------------------------------------------------
// Variables in here use snake_case to self-document from the AV1 spec and the draft AV2 spec:
//
// https://aomediacodec.github.io/av1-spec/av1-spec.pdf
//
// Originally dav1d's parse_seq_hdr() function (heavily modified and split)

static avifBool parseAV1SequenceHeaderProfile(avifBits * bits, avifSequenceHeader * header)
{
    uint32_t seq_profile = avifBitsRead(bits, 3);
    if (seq_profile > 2) {
        return AVIF_FALSE;
    }
    header->av1C.seqProfile = (uint8_t)seq_profile;
    return !bits->error;
}

#if defined(AVIF_CODEC_AVM)
static avifBool parseAV2SequenceHeaderProfile(avifBits * bits, avifSequenceHeader * header)
{
    uint32_t seq_profile = avifBitsRead(bits, 5);
    if (seq_profile >= 32) {
        return AVIF_FALSE;
    }
    header->av1C.seqProfile = (uint8_t)seq_profile;
    return !bits->error;
}
#endif // defined(AVIF_CODEC_AVM)

static avifBool parseSequenceHeaderLevelIdxAndTier(avifBits * bits, avifSequenceHeader * header)
{
    uint32_t still_picture = avifBitsRead(bits, 1);
    header->reduced_still_picture_header = (uint8_t)avifBitsRead(bits, 1);
    if (header->reduced_still_picture_header && !still_picture) {
        return AVIF_FALSE;
    }

    if (header->reduced_still_picture_header) {
        header->av1C.seqLevelIdx0 = (uint8_t)avifBitsRead(bits, 5);
        header->av1C.seqTier0 = 0;
    } else {
        uint32_t timing_info_present_flag = avifBitsRead(bits, 1);
        uint32_t decoder_model_info_present_flag = 0;
        uint32_t buffer_delay_length = 0;
        if (timing_info_present_flag) { // timing_info()
            avifBitsRead(bits, 32);     // num_units_in_display_tick
            avifBitsRead(bits, 32);     // time_scale
            uint32_t equal_picture_interval = avifBitsRead(bits, 1);
            if (equal_picture_interval) {
                uint32_t num_ticks_per_picture_minus_1 = avifBitsReadVLC(bits);
                if (num_ticks_per_picture_minus_1 == 0xFFFFFFFFU)
                    return AVIF_FALSE;
            }

            decoder_model_info_present_flag = avifBitsRead(bits, 1);
            if (decoder_model_info_present_flag) { // decoder_model_info()
                buffer_delay_length = avifBitsRead(bits, 5) + 1;
                avifBitsRead(bits, 32); // num_units_in_decoding_tick
                avifBitsRead(bits, 10); // buffer_removal_time_length_minus_1, frame_presentation_time_length_minus_1
            }
        }

        uint32_t initial_display_delay_present_flag = avifBitsRead(bits, 1);
        uint32_t operating_points_cnt = avifBitsRead(bits, 5) + 1;
        for (uint32_t i = 0; i < operating_points_cnt; i++) {
            avifBitsRead(bits, 12); // operating_point_idc
            uint32_t seq_level_idx = avifBitsRead(bits, 5);
            if (i == 0) {
                header->av1C.seqLevelIdx0 = (uint8_t)seq_level_idx;
                header->av1C.seqTier0 = 0;
            }
            if (seq_level_idx > 7) {
                uint32_t seq_tier = avifBitsRead(bits, 1);
                if (i == 0) {
                    header->av1C.seqTier0 = (uint8_t)seq_tier;
                }
            }
            if (decoder_model_info_present_flag) {
                uint32_t decoder_model_present_for_this_op = avifBitsRead(bits, 1);
                if (decoder_model_present_for_this_op) {     // operating_parameters_info()
                    avifBitsRead(bits, buffer_delay_length); // decoder_buffer_delay
                    avifBitsRead(bits, buffer_delay_length); // encoder_buffer_delay
                    avifBitsRead(bits, 1);                   // low_delay_mode_flag
                }
            }
            if (initial_display_delay_present_flag) {
                uint32_t initial_display_delay_present_for_this_op = avifBitsRead(bits, 1);
                if (initial_display_delay_present_for_this_op) {
                    avifBitsRead(bits, 4); // initial_display_delay_minus_1
                }
            }
        }
    }
    return !bits->error;
}

static avifBool parseSequenceHeaderFrameMaxDimensions(avifBits * bits, avifSequenceHeader * header)
{
    uint32_t frame_width_bits = avifBitsRead(bits, 4) + 1;
    uint32_t frame_height_bits = avifBitsRead(bits, 4) + 1;
    header->maxWidth = avifBitsRead(bits, frame_width_bits) + 1;   // max_frame_width
    header->maxHeight = avifBitsRead(bits, frame_height_bits) + 1; // max_frame_height
    uint32_t frame_id_numbers_present_flag = 0;
    if (!header->reduced_still_picture_header) {
        frame_id_numbers_present_flag = avifBitsRead(bits, 1);
    }
    if (frame_id_numbers_present_flag) {
        avifBitsRead(bits, 7); // delta_frame_id_length_minus_2, additional_frame_id_length_minus_1
    }
    return !bits->error;
}

static avifBool parseSequenceHeaderEnabledFeatures(avifBits * bits, avifSequenceHeader * header)
{
    avifBitsRead(bits, 2); // enable_filter_intra, enable_intra_edge_filter

    if (!header->reduced_still_picture_header) {
        avifBitsRead(bits, 4); // enable_interintra_compound, enable_masked_compound, enable_warped_motion, enable_dual_filter
        uint32_t enable_order_hint = avifBitsRead(bits, 1);
        if (enable_order_hint) {
            avifBitsRead(bits, 2); // enable_jnt_comp, enable_ref_frame_mvs
        }

        uint32_t seq_force_screen_content_tools = 0;
        uint32_t seq_choose_screen_content_tools = avifBitsRead(bits, 1);
        if (seq_choose_screen_content_tools) {
            seq_force_screen_content_tools = 2;
        } else {
            seq_force_screen_content_tools = avifBitsRead(bits, 1);
        }
        if (seq_force_screen_content_tools > 0) {
            uint32_t seq_choose_integer_mv = avifBitsRead(bits, 1);
            if (!seq_choose_integer_mv) {
                avifBitsRead(bits, 1); // seq_force_integer_mv
            }
        }
        if (enable_order_hint) {
            avifBitsRead(bits, 3); // order_hint_bits_minus_1
        }
    }

    return !bits->error;
}

// Note: Does not parse separate_uv_delta_q.
static avifBool parseAV1SequenceHeaderColorConfig(avifBits * bits, avifSequenceHeader * header)
{
    header->bitDepth = 8;
    header->chromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;
    header->av1C.chromaSamplePosition = (uint8_t)header->chromaSamplePosition;
    uint32_t high_bitdepth = avifBitsRead(bits, 1);
    header->av1C.highBitdepth = (uint8_t)high_bitdepth;
    if ((header->av1C.seqProfile == 2) && high_bitdepth) {
        uint32_t twelve_bit = avifBitsRead(bits, 1);
        header->bitDepth = twelve_bit ? 12 : 10;
        header->av1C.twelveBit = (uint8_t)twelve_bit;
    } else /* if (seq_profile <= 2) */ {
        header->bitDepth = high_bitdepth ? 10 : 8;
        header->av1C.twelveBit = 0;
    }
    uint32_t mono_chrome = 0;
    if (header->av1C.seqProfile != 1) {
        mono_chrome = avifBitsRead(bits, 1);
    }
    header->av1C.monochrome = (uint8_t)mono_chrome;
    uint32_t color_description_present_flag = avifBitsRead(bits, 1);
    if (color_description_present_flag) {
        header->colorPrimaries = (avifColorPrimaries)avifBitsRead(bits, 8);                   // color_primaries
        header->transferCharacteristics = (avifTransferCharacteristics)avifBitsRead(bits, 8); // transfer_characteristics
        header->matrixCoefficients = (avifMatrixCoefficients)avifBitsRead(bits, 8);           // matrix_coefficients
    } else {
        header->colorPrimaries = AVIF_COLOR_PRIMARIES_UNSPECIFIED;
        header->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED;
        header->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED;
    }
    if (mono_chrome) {
        header->range = avifBitsRead(bits, 1) ? AVIF_RANGE_FULL : AVIF_RANGE_LIMITED; // color_range
        header->av1C.chromaSubsamplingX = 1;
        header->av1C.chromaSubsamplingY = 1;
        header->yuvFormat = AVIF_PIXEL_FORMAT_YUV400;
    } else if (header->colorPrimaries == AVIF_COLOR_PRIMARIES_BT709 &&
               header->transferCharacteristics == AVIF_TRANSFER_CHARACTERISTICS_SRGB &&
               header->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_IDENTITY) {
        header->range = AVIF_RANGE_FULL;
        header->av1C.chromaSubsamplingX = 0;
        header->av1C.chromaSubsamplingY = 0;
        header->yuvFormat = AVIF_PIXEL_FORMAT_YUV444;
    } else {
        uint32_t subsampling_x = 0;
        uint32_t subsampling_y = 0;
        header->range = avifBitsRead(bits, 1) ? AVIF_RANGE_FULL : AVIF_RANGE_LIMITED; // color_range
        switch (header->av1C.seqProfile) {
            case 0:
                subsampling_x = 1;
                subsampling_y = 1;
                header->yuvFormat = AVIF_PIXEL_FORMAT_YUV420;
                break;
            case 1:
                subsampling_x = 0;
                subsampling_y = 0;
                header->yuvFormat = AVIF_PIXEL_FORMAT_YUV444;
                break;
            case 2:
                if (header->bitDepth == 12) {
                    subsampling_x = avifBitsRead(bits, 1);
                    if (subsampling_x) {
                        subsampling_y = avifBitsRead(bits, 1);
                    }
                } else {
                    subsampling_x = 1;
                    subsampling_y = 0;
                }
                if (subsampling_x) {
                    header->yuvFormat = subsampling_y ? AVIF_PIXEL_FORMAT_YUV420 : AVIF_PIXEL_FORMAT_YUV422;
                } else {
                    header->yuvFormat = AVIF_PIXEL_FORMAT_YUV444;
                }
                break;
            default:
                return AVIF_FALSE;
        }

        if (subsampling_x && subsampling_y) {
            header->chromaSamplePosition = (avifChromaSamplePosition)avifBitsRead(bits, 2); // chroma_sample_position
            header->av1C.chromaSamplePosition = (uint8_t)header->chromaSamplePosition;
        }
        header->av1C.chromaSubsamplingX = (uint8_t)subsampling_x;
        header->av1C.chromaSubsamplingY = (uint8_t)subsampling_y;
    }

    return !bits->error;
}

#if defined(AVIF_CODEC_AVM)
enum
{
    AV2_CHROMA_FORMAT_420 = 0,
    AV2_CHROMA_FORMAT_400 = 1,
    AV2_CHROMA_FORMAT_444 = 2,
    AV2_CHROMA_FORMAT_422 = 3,
};

static avifChromaSamplePosition av2ChromaSamplePositionToAv1ChromaSamplePosition(uint32_t av2ChromaSamplePosition)
{
    if (av2ChromaSamplePosition == 0) {
        // AVM_CSP_LEFT: Horizontal offset 0, vertical offset 0.5
        return AVIF_CHROMA_SAMPLE_POSITION_VERTICAL;
    } else if (av2ChromaSamplePosition == 1) {
        // AVM_CSP_CENTER: Horizontal offset 0.5, vertical offset 0.5
        return AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;
    } else if (av2ChromaSamplePosition == 2) {
        // AVM_CSP_TOPLEFT: Horizontal offset 0, vertical offset 0
        return AVIF_CHROMA_SAMPLE_POSITION_COLOCATED;
    } else {
        return AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;
    }
}

static avifBool parseAV2ChromaFormatBitdepth(avifBits * bits, avifSequenceHeader * header)
{
    const uint32_t chromaFormatIdc = avifBitsReadVLC(bits);

    const uint32_t bitdepthIdx = avifBitsReadVLC(bits);
    if (bitdepthIdx == 0) {
        header->bitDepth = 10;
    } else if (bitdepthIdx == 1) {
        header->bitDepth = 8;
    } else if (bitdepthIdx == 2) {
        header->bitDepth = 12;
    } else {
        return AVIF_FALSE;
    }
    header->av1C.highBitdepth = header->bitDepth > 8;
    header->av1C.twelveBit = header->bitDepth == 12;
    header->av1C.monochrome = chromaFormatIdc == AV2_CHROMA_FORMAT_400;

    if (header->av1C.monochrome) {
        header->av1C.chromaSubsamplingX = 1;
        header->av1C.chromaSubsamplingY = 1;
        header->yuvFormat = AVIF_PIXEL_FORMAT_YUV400;
    } else if (chromaFormatIdc == AV2_CHROMA_FORMAT_420) {
        header->av1C.chromaSubsamplingX = 1;
        header->av1C.chromaSubsamplingY = 1;
        header->yuvFormat = AVIF_PIXEL_FORMAT_YUV420;
    } else if (chromaFormatIdc == AV2_CHROMA_FORMAT_444) {
        header->av1C.chromaSubsamplingX = 0;
        header->av1C.chromaSubsamplingY = 0;
        header->yuvFormat = AVIF_PIXEL_FORMAT_YUV444;
    } else if (chromaFormatIdc == AV2_CHROMA_FORMAT_422) {
        header->av1C.chromaSubsamplingX = 1;
        header->av1C.chromaSubsamplingY = 0;
        header->yuvFormat = AVIF_PIXEL_FORMAT_YUV422;
    } else {
        return AVIF_FALSE;
    }

    return !bits->error;
}
#endif // defined(AVIF_CODEC_AVM)

static avifBool parseAV1SequenceHeader(avifBits * bits, avifSequenceHeader * header)
{
    AVIF_CHECK(parseAV1SequenceHeaderProfile(bits, header));
    AVIF_CHECK(parseSequenceHeaderLevelIdxAndTier(bits, header));

    AVIF_CHECK(parseSequenceHeaderFrameMaxDimensions(bits, header));
    avifBitsRead(bits, 1); // use_128x128_superblock
    AVIF_CHECK(parseSequenceHeaderEnabledFeatures(bits, header));

    avifBitsRead(bits, 3); // enable_superres, enable_cdef, enable_restoration

    AVIF_CHECK(parseAV1SequenceHeaderColorConfig(bits, header));
    if (!header->av1C.monochrome) {
        avifBitsRead(bits, 1); // separate_uv_delta_q
    }

    avifBitsRead(bits, 1); // film_grain_params_present
    return !bits->error;
}

#if defined(AVIF_CODEC_AVM)
static int avifCeilLog2(int x)
{
    if (x < 2)
        return 0;
    int i = 1;
    int p = 2;
    while (p < x) {
        i++;
        p <<= 1;
    }
    return i;
}

// See read_sequence_header_obu() in av2/decoder/obu.c.
static avifBool parseAV2SequenceHeader(avifBits * bits, avifSequenceHeader * header)
{
    uint32_t seqHeaderId = avifBitsReadVLC(bits);
    if (seqHeaderId >= 16) {
        return AVIF_FALSE;
    }

    AVIF_CHECK(parseAV2SequenceHeaderProfile(bits, header));
    header->reduced_still_picture_header = (uint8_t)avifBitsRead(bits, 1); // single_picture_header_flag
    header->av1C.seqLevelIdx0 = (uint8_t)avifBitsRead(bits, 5);
    if (header->av1C.seqLevelIdx0 >= 4 && !header->reduced_still_picture_header) {
        header->av1C.seqTier0 = avifBitsRead(bits, 1);
    } else {
        header->av1C.seqTier0 = 0;
    }

    AVIF_CHECK(parseAV2ChromaFormatBitdepth(bits, header));

    if (!header->reduced_still_picture_header) {
        avifBitsRead(bits, 3);                         // seq_lcr_id
        avifBitsRead(bits, 1);                         // still_picture
        avifBitsRead(bits, 2);                         // max_tlayer_id
        const int maxMlayerId = avifBitsRead(bits, 3); // max_mlayer_id
        if (maxMlayerId > 0) {
            const int n = avifCeilLog2(maxMlayerId + 1);
            avifBitsRead(bits, n); // seq_max_mlayer_cnt_minus_1
        }
        avifBitsRead(bits, 1); // monotonic_output_order_flag
    }

    uint32_t frame_width_bits = avifBitsRead(bits, 4) + 1;
    uint32_t frame_height_bits = avifBitsRead(bits, 4) + 1;
    header->maxWidth = avifBitsRead(bits, frame_width_bits) + 1;   // max_frame_width
    header->maxHeight = avifBitsRead(bits, frame_height_bits) + 1; // max_frame_height

    header->colorPrimaries = AVIF_COLOR_PRIMARIES_UNSPECIFIED;
    header->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED;
    header->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED;
    header->range = AVIF_RANGE_LIMITED;

    header->chromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;
    header->av1C.chromaSamplePosition = (uint8_t)header->chromaSamplePosition;

    // Other ignored fields.
    return !bits->error;
}

// See av2_read_content_interpretation_obu() in av2/decoder/obu_ci.c.
static avifBool parseAV2ContentInterpretation(avifBits * bits, avifSequenceHeader * header)
{
    avifBitsRead(bits, 2);                                              // ci_scan_type_idc
    const uint32_t colorDescriptionPresent = avifBitsRead(bits, 1);     // ci_color_description_present_flag
    const uint32_t chromaSamplePositionPresent = avifBitsRead(bits, 1); // ci_chroma_sample_position_present_flag
    avifBitsRead(bits, 1);                                              // ci_aspect_ratio_info_present_flag
    avifBitsRead(bits, 1);                                              // ci_timing_info_present_flag
    avifBitsRead(bits, 1);                                              // ci_extension_present_flag
    avifBitsRead(bits, 1);                                              // reserved_bit

    if (colorDescriptionPresent) {
        // Override the default CICP values.
        const uint32_t colorDescriptionIdc = avifBitsReadRG(bits, 2); // color_description_idc
        if (colorDescriptionIdc == 0xFFFFFFFFU) {
            return AVIF_FALSE;
        }
        if (colorDescriptionIdc == 0) {
            // Explicitly signaled
            header->colorPrimaries = (avifColorPrimaries)avifBitsRead(bits, 8);                   // color_primaries
            header->transferCharacteristics = (avifTransferCharacteristics)avifBitsRead(bits, 8); // transfer_characteristics
            header->matrixCoefficients = (avifMatrixCoefficients)avifBitsRead(bits, 8);           // matrix_coefficients
        } else if (colorDescriptionIdc == 1) {
            // BT.709 SDR
            header->colorPrimaries = AVIF_COLOR_PRIMARIES_BT709;                   // 1
            header->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_BT709; // 1
            header->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT709;           // 1
        } else if (colorDescriptionIdc == 2) {
            // BT.2100 PQ
            header->colorPrimaries = AVIF_COLOR_PRIMARIES_BT2100;               // 9
            header->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_PQ; // 16
            header->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT2020_NCL;   // 9
        } else if (colorDescriptionIdc == 3) {
            // BT.2100 HLG
            header->colorPrimaries = AVIF_COLOR_PRIMARIES_BT2100;                // 9
            header->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_HLG; // 18
            header->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT2020_NCL;    // 9
        } else if (colorDescriptionIdc == 4) {
            // sRGB
            header->colorPrimaries = AVIF_COLOR_PRIMARIES_BT709;                  // 1
            header->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_SRGB; // 13
            header->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY;       // 0
        } else if (colorDescriptionIdc == 5) {
            // sYCC
            header->colorPrimaries = AVIF_COLOR_PRIMARIES_BT709;                  // 1
            header->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_SRGB; // 13
            header->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT470BG;        // 5
        } else {
            // Reserved
            header->colorPrimaries = AVIF_COLOR_PRIMARIES_UNSPECIFIED;                   // 2
            header->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED; // 2
            header->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED;           // 2
        }
        header->range = avifBitsRead(bits, 1) ? AVIF_RANGE_FULL : AVIF_RANGE_LIMITED; // color_range
    } else {
        // Keep the default CICP values.
    }

    if (chromaSamplePositionPresent) {
        const uint32_t chromaSamplePosition = avifBitsReadVLC(bits); // ci_chroma_sample_position_0
        header->chromaSamplePosition = av2ChromaSamplePositionToAv1ChromaSamplePosition(chromaSamplePosition);
        header->av1C.chromaSamplePosition = (uint8_t)header->chromaSamplePosition;
    }

    // Other ignored fields.
    return !bits->error;
}
#endif // defined(AVIF_CODEC_AVM)

static avifBool av1SequenceHeaderParse(avifSequenceHeader * header, const avifROData * sample)
{
    avifROData obus = *sample;

    // Find the sequence header OBU
    while (obus.size > 0) {
        avifBits bits;
        avifBitsInit(&bits, obus.data, obus.size);

        // obu_header()
        const uint32_t obu_forbidden_bit = avifBitsRead(&bits, 1);
        if (obu_forbidden_bit != 0) {
            return AVIF_FALSE;
        }
        const uint32_t obu_type = avifBitsRead(&bits, 4);
        const uint32_t obu_extension_flag = avifBitsRead(&bits, 1);
        const uint32_t obu_has_size_field = avifBitsRead(&bits, 1);
        avifBitsRead(&bits, 1); // obu_reserved_1bit

        if (obu_extension_flag) {   // obu_extension_header()
            avifBitsRead(&bits, 8); // temporal_id, spatial_id, extension_header_reserved_3bits
        }

        uint32_t obu_size = 0;
        if (obu_has_size_field)
            obu_size = avifBitsReadUleb128(&bits);
        else
            obu_size = (int)obus.size - 1 - obu_extension_flag;

        if (bits.error) {
            return AVIF_FALSE;
        }

        const uint32_t init_bit_pos = avifBitsReadPos(&bits);
        const uint32_t init_byte_pos = init_bit_pos >> 3;
        if (obu_size > obus.size - init_byte_pos)
            return AVIF_FALSE;

        if (obu_type == 1) { // Sequence Header
            avifBits seqHdrBits;
            avifBitsInit(&seqHdrBits, obus.data + init_byte_pos, obu_size);
            return parseAV1SequenceHeader(&seqHdrBits, header);
        }

        // Skip this OBU
        obus.data += (size_t)obu_size + init_byte_pos;
        obus.size -= (size_t)obu_size + init_byte_pos;
    }
    return AVIF_FALSE;
}

#if defined(AVIF_CODEC_AVM)
static avifBool av2SequenceHeaderParse(avifSequenceHeader * header, const avifROData * sample)
{
    avifBool sequenceHeaderFound = AVIF_FALSE;
    avifROData obus = *sample;

    // Find the Sequence Header OBU, and the Content Interpretation OBU if any.
    while (obus.size > 0) {
        avifBits bits;
        avifBitsInit(&bits, obus.data, obus.size);

        const uint32_t obuSize = avifBitsReadUleb128(&bits);

        // obu_header()
        const uint32_t obuHeaderExtensionFlag = avifBitsRead(&bits, 1);
        const uint32_t obuType = avifBitsRead(&bits, 5);
        avifBitsRead(&bits, 2); // obu_tlayer_id

        if (obuHeaderExtensionFlag) {
            avifBitsRead(&bits, 8); // obu_mlayer_id, obu_xlayer_id
        }

        if (bits.error) {
            return AVIF_FALSE;
        }

        const uint32_t obuHeaderSize = 1 + obuHeaderExtensionFlag;
        if (obuSize < obuHeaderSize) {
            return AVIF_FALSE;
        }
        const uint32_t obuPayloadSize = obuSize - obuHeaderSize;
        const uint32_t initBitPos = avifBitsReadPos(&bits);
        const uint32_t initBytePos = initBitPos >> 3;
        if (obuPayloadSize > obus.size - initBytePos) {
            return AVIF_FALSE;
        }

        if (obuType == OBU_SEQUENCE_HEADER) {
            if (sequenceHeaderFound) {
                return AVIF_FALSE;
            }
            avifBits seqHdrBits;
            avifBitsInit(&seqHdrBits, obus.data + initBytePos, obuPayloadSize);
            if (!parseAV2SequenceHeader(&seqHdrBits, header)) {
                return AVIF_FALSE;
            }
            sequenceHeaderFound = AVIF_TRUE;
        } else if (obuType == OBU_CONTENT_INTERPRETATION) { // optional
            if (!sequenceHeaderFound) {
                return AVIF_FALSE;
            }
            avifBits ciBits;
            avifBitsInit(&ciBits, obus.data + initBytePos, obuPayloadSize);
            if (!parseAV2ContentInterpretation(&ciBits, header)) {
                return AVIF_FALSE;
            }
            break;
        }
        obus.data += (size_t)obuPayloadSize + initBytePos;
        obus.size -= (size_t)obuPayloadSize + initBytePos;
    }
    return sequenceHeaderFound;
}
#endif // defined(AVIF_CODEC_AVM)

avifBool avifSequenceHeaderParse(avifSequenceHeader * header, const avifROData * sample, avifCodecType codecType)
{
    switch (codecType) {
        case AVIF_CODEC_TYPE_AV1:
            return av1SequenceHeaderParse(header, sample);
#if defined(AVIF_CODEC_AVM)
        case AVIF_CODEC_TYPE_AV2:
            return av2SequenceHeaderParse(header, sample);
#endif
        default:
            return AVIF_FALSE;
    }
}
