/*
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

static int FUNC(sequence_header)(CodedBitstreamContext *ctx, RWContext *rw,
                                 MPEG2RawSequenceHeader *current)
{
    CodedBitstreamMPEG2Context *mpeg2 = ctx->priv_data;
    int err, i;

    HEADER("Sequence Header");

    ui(8,  sequence_header_code);

    ui(12, horizontal_size_value);
    ui(12, vertical_size_value);

    mpeg2->horizontal_size = current->horizontal_size_value;
    mpeg2->vertical_size   = current->vertical_size_value;

    ui(4,  aspect_ratio_information);
    ui(4,  frame_rate_code);
    ui(18, bit_rate_value);

    marker_bit();

    ui(10, vbv_buffer_size_value);
    ui(1,  constrained_parameters_flag);

    ui(1, load_intra_quantiser_matrix);
    if (current->load_intra_quantiser_matrix) {
        for (i = 0; i < 64; i++)
            ui(8, intra_quantiser_matrix[i]);
    }

    ui(1, load_non_intra_quantiser_matrix);
    if (current->load_non_intra_quantiser_matrix) {
        for (i = 0; i < 64; i++)
            ui(8, non_intra_quantiser_matrix[i]);
    }

    return 0;
}

static int FUNC(user_data)(CodedBitstreamContext *ctx, RWContext *rw,
                           MPEG2RawUserData *current)
{
    size_t k;
    int err;

    HEADER("User Data");

    ui(8, user_data_start_code);

#ifdef READ
    k = get_bits_left(rw);
    av_assert0(k % 8 == 0);
    current->user_data_length = k /= 8;
    if (k > 0) {
        current->user_data_ref = av_buffer_allocz(k + AV_INPUT_BUFFER_PADDING_SIZE);
        if (!current->user_data_ref)
            return AVERROR(ENOMEM);
        current->user_data = current->user_data_ref->data;
    }
#endif

    for (k = 0; k < current->user_data_length; k++)
        xui(8, user_data, current->user_data[k]);

    return 0;
}

static int FUNC(sequence_extension)(CodedBitstreamContext *ctx, RWContext *rw,
                                    MPEG2RawSequenceExtension *current)
{
    CodedBitstreamMPEG2Context *mpeg2 = ctx->priv_data;
    int err;

    HEADER("Sequence Extension");

    ui(8,  profile_and_level_indication);
    ui(1,  progressive_sequence);
    ui(2,  chroma_format);
    ui(2,  horizontal_size_extension);
    ui(2,  vertical_size_extension);

    mpeg2->horizontal_size = (mpeg2->horizontal_size & 0xfff) |
        current->horizontal_size_extension << 12;
    mpeg2->vertical_size = (mpeg2->vertical_size & 0xfff) |
        current->vertical_size_extension << 12;
    mpeg2->progressive_sequence = current->progressive_sequence;

    ui(12, bit_rate_extension);
    marker_bit();
    ui(8,  vbv_buffer_size_extension);
    ui(1,  low_delay);
    ui(2,  frame_rate_extension_n);
    ui(5,  frame_rate_extension_d);

    return 0;
}

static int FUNC(sequence_display_extension)(CodedBitstreamContext *ctx, RWContext *rw,
                                            MPEG2RawSequenceDisplayExtension *current)
{
    int err;

    HEADER("Sequence Display Extension");

    ui(3, video_format);

    ui(1, colour_description);
    if (current->colour_description) {
        ui(8, colour_primaries);
        ui(8, transfer_characteristics);
        ui(8, matrix_coefficients);
    }

    ui(14, display_horizontal_size);
    marker_bit();
    ui(14, display_vertical_size);

    return 0;
}

static int FUNC(group_of_pictures_header)(CodedBitstreamContext *ctx, RWContext *rw,
                                          MPEG2RawGroupOfPicturesHeader *current)
{
    int err;

    HEADER("Group of Pictures Header");

    ui(8,  group_start_code);

    ui(25, time_code);
    ui(1,  closed_gop);
    ui(1,  broken_link);

    return 0;
}

static int FUNC(picture_header)(CodedBitstreamContext *ctx, RWContext *rw,
                                MPEG2RawPictureHeader *current)
{
    int err;

    HEADER("Picture Header");

    ui(8,  picture_start_code);

    ui(10, temporal_reference);
    ui(3,  picture_coding_type);
    ui(16, vbv_delay);

    if (current->picture_coding_type == 2 ||
        current->picture_coding_type == 3) {
        ui(1, full_pel_forward_vector);
        ui(3, forward_f_code);
    }

    if (current->picture_coding_type == 3) {
        ui(1, full_pel_backward_vector);
        ui(3, backward_f_code);
    }

    ui(1, extra_bit_picture);

    return 0;
}

static int FUNC(picture_coding_extension)(CodedBitstreamContext *ctx, RWContext *rw,
                                          MPEG2RawPictureCodingExtension *current)
{
    CodedBitstreamMPEG2Context *mpeg2 = ctx->priv_data;
    int err;

    HEADER("Picture Coding Extension");

    ui(4, f_code[0][0]);
    ui(4, f_code[0][1]);
    ui(4, f_code[1][0]);
    ui(4, f_code[1][1]);

    ui(2, intra_dc_precision);
    ui(2, picture_structure);
    ui(1, top_field_first);
    ui(1, frame_pred_frame_dct);
    ui(1, concealment_motion_vectors);
    ui(1, q_scale_type);
    ui(1, intra_vlc_format);
    ui(1, alternate_scan);
    ui(1, repeat_first_field);
    ui(1, chroma_420_type);
    ui(1, progressive_frame);

    if (mpeg2->progressive_sequence) {
        if (current->repeat_first_field) {
            if (current->top_field_first)
                mpeg2->number_of_frame_centre_offsets = 3;
            else
                mpeg2->number_of_frame_centre_offsets = 2;
        } else {
            mpeg2->number_of_frame_centre_offsets = 1;
        }
    } else {
        if (current->picture_structure == 1 || // Top field.
            current->picture_structure == 2) { // Bottom field.
            mpeg2->number_of_frame_centre_offsets = 1;
        } else {
            if (current->repeat_first_field)
                mpeg2->number_of_frame_centre_offsets = 3;
            else
                mpeg2->number_of_frame_centre_offsets = 2;
        }
    }

    ui(1, composite_display_flag);
    if (current->composite_display_flag) {
        ui(1, v_axis);
        ui(3, field_sequence);
        ui(1, sub_carrier);
        ui(7, burst_amplitude);
        ui(8, sub_carrier_phase);
    }

    return 0;
}

static int FUNC(quant_matrix_extension)(CodedBitstreamContext *ctx, RWContext *rw,
                                        MPEG2RawQuantMatrixExtension *current)
{
    int err, i;

    HEADER("Quant Matrix Extension");

    ui(1, load_intra_quantiser_matrix);
    if (current->load_intra_quantiser_matrix) {
        for (i = 0; i < 64; i++)
            ui(8, intra_quantiser_matrix[i]);
    }

    ui(1, load_non_intra_quantiser_matrix);
    if (current->load_non_intra_quantiser_matrix) {
        for (i = 0; i < 64; i++)
            ui(8, non_intra_quantiser_matrix[i]);
    }

    ui(1, load_chroma_intra_quantiser_matrix);
    if (current->load_chroma_intra_quantiser_matrix) {
        for (i = 0; i < 64; i++)
            ui(8, intra_quantiser_matrix[i]);
    }

    ui(1, load_chroma_non_intra_quantiser_matrix);
    if (current->load_chroma_non_intra_quantiser_matrix) {
        for (i = 0; i < 64; i++)
            ui(8, chroma_non_intra_quantiser_matrix[i]);
    }

    return 0;
}

static int FUNC(picture_display_extension)(CodedBitstreamContext *ctx, RWContext *rw,
                                           MPEG2RawPictureDisplayExtension *current)
{
    CodedBitstreamMPEG2Context *mpeg2 = ctx->priv_data;
    int err, i;

    HEADER("Picture Display Extension");

    for (i = 0; i < mpeg2->number_of_frame_centre_offsets; i++) {
        ui(16, frame_centre_horizontal_offset[i]);
        marker_bit();
        ui(16, frame_centre_vertical_offset[i]);
        marker_bit();
    }

    return 0;
}

static int FUNC(extension_data)(CodedBitstreamContext *ctx, RWContext *rw,
                                MPEG2RawExtensionData *current)
{
    int err;

    HEADER("Extension Data");

    ui(8, extension_start_code);
    ui(4, extension_start_code_identifier);

    switch (current->extension_start_code_identifier) {
    case 1:
        return FUNC(sequence_extension)
            (ctx, rw, &current->data.sequence);
    case 2:
        return FUNC(sequence_display_extension)
            (ctx, rw, &current->data.sequence_display);
    case 3:
        return FUNC(quant_matrix_extension)
            (ctx, rw, &current->data.quant_matrix);
    case 7:
        return FUNC(picture_display_extension)
            (ctx, rw, &current->data.picture_display);
    case 8:
        return FUNC(picture_coding_extension)
            (ctx, rw, &current->data.picture_coding);
    default:
        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid extension ID %d.\n",
               current->extension_start_code_identifier);
        return AVERROR_INVALIDDATA;
    }
}

static int FUNC(slice_header)(CodedBitstreamContext *ctx, RWContext *rw,
                              MPEG2RawSliceHeader *current)
{
    CodedBitstreamMPEG2Context *mpeg2 = ctx->priv_data;
    int err;

    HEADER("Slice Header");

    ui(8, slice_vertical_position);

    if (mpeg2->vertical_size > 2800)
        ui(3, slice_vertical_position_extension);
    if (mpeg2->scalable) {
        if (mpeg2->scalable_mode == 0)
            ui(7, priority_breakpoint);
    }

    ui(5, quantiser_scale_code);

    if (nextbits(1, 1, current->slice_extension_flag)) {
        ui(1, slice_extension_flag);
        ui(1, intra_slice);
        ui(1, slice_picture_id_enable);
        ui(6, slice_picture_id);

        {
            size_t k;
#ifdef READ
            GetBitContext start;
            uint8_t bit;
            start = *rw;
            for (k = 0; nextbits(1, 1, bit); k++)
                skip_bits(rw, 8);
            current->extra_information_length = k;
            if (k > 0) {
                *rw = start;
                current->extra_information =
                    av_malloc(current->extra_information_length);
                if (!current->extra_information)
                    return AVERROR(ENOMEM);
                for (k = 0; k < current->extra_information_length; k++) {
                    xui(1, extra_bit_slice, bit);
                    xui(8, extra_information_slice,
                        current->extra_information[k]);
                }
            }
#else
            for (k = 0; k < current->extra_information_length; k++) {
                xui(1, extra_bit_slice, 1);
                xui(8, extra_information_slice, current->extra_information[k]);
            }
#endif
        }
    }
    ui(1, extra_bit_slice);

    return 0;
}
