// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crabby_avif::decoder::track::RepetitionCount;
use crabby_avif::decoder::CompressionFormat;
use crabby_avif::decoder::ImageContentType;
use crabby_avif::image::*;
use crabby_avif::reformat::rgb;
use crabby_avif::*;

#[path = "./mod.rs"]
mod tests;

use std::cell::RefCell;
use std::rc::Rc;
use tests::*;

// From avifalphanoispetest.cc
#[test]
fn alpha_no_ispe() {
    // See https://github.com/AOMediaCodec/libavif/pull/745.
    let mut decoder = get_decoder("alpha_noispe.avif");
    // By default, non-strict files are refused.
    assert!(matches!(
        decoder.settings.strictness,
        decoder::Strictness::All
    ));
    let res = decoder.parse();
    assert!(matches!(res, Err(AvifError::BmffParseFailed(_))));
    // Allow this kind of file specifically.
    decoder.settings.strictness =
        decoder::Strictness::SpecificExclude(vec![decoder::StrictnessFlag::AlphaIspeRequired]);
    let res = decoder.parse();
    assert!(res.is_ok());
    let image = decoder.image().expect("image was none");
    assert!(image.alpha_present);
    assert!(!image.image_sequence_track_present);
    if !HAS_DECODER {
        return;
    }
    let res = decoder.next_image();
    assert!(res.is_ok());
    let image = decoder.image().expect("image was none");
    let alpha_plane = image.plane_data(Plane::A);
    assert!(alpha_plane.is_some());
    assert!(alpha_plane.unwrap().row_bytes > 0);
}

#[test]
fn alpha_premultiplied() {
    let mut decoder = get_decoder("alpha_premultiplied.avif");
    let res = decoder.parse();
    assert!(res.is_ok());
    let image = decoder.image().expect("image was none");
    assert!(image.alpha_present);
    assert!(image.alpha_premultiplied);
    if !HAS_DECODER {
        return;
    }
    let res = decoder.next_image();
    assert!(res.is_ok());
    let image = decoder.image().expect("image was none");
    assert!(image.alpha_present);
    assert!(image.alpha_premultiplied);
    let alpha_plane = image.plane_data(Plane::A);
    assert!(alpha_plane.is_some());
    assert!(alpha_plane.unwrap().row_bytes > 0);
}

// From avifanimationtest.cc
#[test_case::test_case("colors-animated-8bpc.avif")]
#[test_case::test_case("colors-animated-8bpc-audio.avif")]
fn animated_image(filename: &str) {
    let mut decoder = get_decoder(filename);
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    assert!(!image.alpha_present);
    assert!(image.image_sequence_track_present);
    assert_eq!(decoder.image_count(), 5);
    assert_eq!(decoder.repetition_count(), RepetitionCount::Finite(0));
    for i in 0..5 {
        assert_eq!(decoder.nearest_keyframe(i), 0);
    }
    if !HAS_DECODER {
        return;
    }
    for _ in 0..5 {
        assert!(decoder.next_image().is_ok());
    }
}

// From avifanimationtest.cc
#[test_case::test_case("colors-animated-8bpc.avif")]
#[test_case::test_case("colors-animated-8bpc-audio.avif")]
fn animated_image_with_source_set_to_primary_item(filename: &str) {
    let mut decoder = get_decoder(filename);
    decoder.settings.source = decoder::Source::PrimaryItem;
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    assert!(!image.alpha_present);
    // This will be reported as true irrespective of the preferred source.
    assert!(image.image_sequence_track_present);
    // imageCount is expected to be 1 because we are using primary item as the
    // preferred source.
    assert_eq!(decoder.image_count(), 1);
    assert_eq!(decoder.repetition_count(), RepetitionCount::Finite(0));
    if !HAS_DECODER {
        return;
    }
    // Get the first (and only) image.
    assert!(decoder.next_image().is_ok());
    // Subsequent calls should not return anything since there is only one
    // image in the preferred source.
    assert!(decoder.next_image().is_err());
}

// From avifanimationtest.cc
#[test]
fn animated_image_with_alpha_and_metadata() {
    let mut decoder = get_decoder("colors-animated-8bpc-alpha-exif-xmp.avif");
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    assert!(image.alpha_present);
    assert!(image.image_sequence_track_present);
    assert_eq!(decoder.image_count(), 5);
    assert_eq!(decoder.repetition_count(), RepetitionCount::Infinite);
    assert_eq!(image.exif.len(), 1126);
    assert_eq!(image.xmp.len(), 3898);
    if !HAS_DECODER {
        return;
    }
    for _ in 0..5 {
        assert!(decoder.next_image().is_ok());
    }
}

#[test]
fn animated_image_with_depth_and_metadata() {
    // Depth map data is not supported and should be ignored.
    let mut decoder = get_decoder("colors-animated-8bpc-depth-exif-xmp.avif");
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    assert!(!image.alpha_present);
    assert!(image.image_sequence_track_present);
    assert_eq!(decoder.image_count(), 5);
    assert_eq!(decoder.repetition_count(), RepetitionCount::Infinite);
    assert_eq!(image.exif.len(), 1126);
    assert_eq!(image.xmp.len(), 3898);
    if !HAS_DECODER {
        return;
    }
    for _ in 0..5 {
        assert!(decoder.next_image().is_ok());
    }
}

#[test]
fn animated_image_with_depth_and_metadata_source_set_to_primary_item() {
    // Depth map data is not supported and should be ignored.
    let mut decoder = get_decoder("colors-animated-8bpc-depth-exif-xmp.avif");
    decoder.settings.source = decoder::Source::PrimaryItem;
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    assert!(!image.alpha_present);
    // This will be reported as true irrespective of the preferred source.
    assert!(image.image_sequence_track_present);
    // imageCount is expected to be 1 because we are using primary item as the
    // preferred source.
    assert_eq!(decoder.image_count(), 1);
    assert_eq!(decoder.repetition_count(), RepetitionCount::Finite(0));
    if !HAS_DECODER {
        return;
    }
    // Get the first (and only) image.
    assert!(decoder.next_image().is_ok());
    // Subsequent calls should not return anything since there is only one
    // image in the preferred source.
    assert!(decoder.next_image().is_err());
}

// From avifkeyframetest.cc
#[test]
fn keyframes() {
    let mut decoder = get_decoder("colors-animated-12bpc-keyframes-0-2-3.avif");
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    assert!(image.image_sequence_track_present);
    assert_eq!(decoder.image_count(), 5);

    // First frame is always a keyframe.
    assert!(decoder.is_keyframe(0));
    assert_eq!(decoder.nearest_keyframe(0), 0);

    assert!(!decoder.is_keyframe(1));
    assert_eq!(decoder.nearest_keyframe(1), 0);

    assert!(decoder.is_keyframe(2));
    assert_eq!(decoder.nearest_keyframe(2), 2);

    assert!(decoder.is_keyframe(3));
    assert_eq!(decoder.nearest_keyframe(3), 3);

    assert!(!decoder.is_keyframe(4));
    assert_eq!(decoder.nearest_keyframe(4), 3);

    // Not an existing frame.
    assert!(!decoder.is_keyframe(15));
    assert_eq!(decoder.nearest_keyframe(15), 3);
}

// From avifdecodetest.cc
#[test]
fn color_grid_alpha_no_grid() {
    // Test case from https://github.com/AOMediaCodec/libavif/issues/1203.
    let mut decoder = get_decoder("color_grid_alpha_nogrid.avif");
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    assert!(image.alpha_present);
    assert!(!image.image_sequence_track_present);
    if !HAS_DECODER {
        return;
    }
    let res = decoder.next_image();
    assert!(res.is_ok());
    let image = decoder.image().expect("image was none");
    let alpha_plane = image.plane_data(Plane::A);
    assert!(alpha_plane.is_some());
    assert!(alpha_plane.unwrap().row_bytes > 0);
}

// From avifprogressivetest.cc
#[test_case::test_case("progressive_dimension_change.avif", 2, 256, 256; "progressive_dimension_change")]
#[test_case::test_case("progressive_layered_grid.avif", 2, 512, 256; "progressive_layered_grid")]
#[test_case::test_case("progressive_quality_change.avif", 2, 256, 256; "progressive_quality_change")]
#[test_case::test_case("progressive_same_layers.avif", 4, 256, 256; "progressive_same_layers")]
#[test_case::test_case("tiger_3layer_1res.avif", 3, 1216, 832; "tiger_3layer_1res")]
#[test_case::test_case("tiger_3layer_3res.avif", 3, 1216, 832; "tiger_3layer_3res")]
fn progressive(filename: &str, layer_count: u32, width: u32, height: u32) {
    let mut filename_with_prefix = String::from("progressive/");
    filename_with_prefix.push_str(filename);
    let mut decoder = get_decoder(&filename_with_prefix);

    decoder.settings.allow_progressive = false;
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    assert!(matches!(
        image.progressive_state,
        decoder::ProgressiveState::Available
    ));

    decoder.settings.allow_progressive = true;
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    assert!(matches!(
        image.progressive_state,
        decoder::ProgressiveState::Active
    ));
    assert_eq!(image.width, width);
    assert_eq!(image.height, height);
    assert_eq!(decoder.image_count(), layer_count);
    if !HAS_DECODER {
        return;
    }
    for _i in 0..decoder.image_count() {
        let res = decoder.next_image();
        assert!(res.is_ok());
        let image = decoder.image().expect("image was none");
        assert_eq!(image.width, width);
        assert_eq!(image.height, height);
    }
}

// From avifmetadatatest.cc
#[test]
fn decoder_parse_icc_exif_xmp() {
    // Test case from https://github.com/AOMediaCodec/libavif/issues/1086.
    let mut decoder = get_decoder("paris_icc_exif_xmp.avif");

    decoder.settings.ignore_xmp = true;
    decoder.settings.ignore_exif = true;
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");

    assert_eq!(image.icc.len(), 596);
    assert_eq!(image.icc[0], 0);
    assert_eq!(image.icc[1], 0);
    assert_eq!(image.icc[2], 2);
    assert_eq!(image.icc[3], 84);

    assert!(image.exif.is_empty());
    assert!(image.xmp.is_empty());

    decoder.settings.ignore_xmp = false;
    decoder.settings.ignore_exif = false;
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");

    assert_eq!(image.exif.len(), 1126);
    assert_eq!(image.exif[0], 73);
    assert_eq!(image.exif[1], 73);
    assert_eq!(image.exif[2], 42);
    assert_eq!(image.exif[3], 0);

    assert_eq!(image.xmp.len(), 3898);
    assert_eq!(image.xmp[0], 60);
    assert_eq!(image.xmp[1], 63);
    assert_eq!(image.xmp[2], 120);
    assert_eq!(image.xmp[3], 112);
}

// From avifgainmaptest.cc
#[test]
fn color_grid_gainmap_different_grid() {
    let mut decoder = get_decoder("color_grid_gainmap_different_grid.avif");
    decoder.settings.image_content_to_decode = ImageContentType::All;
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    // Color+alpha: 4x3 grid of 128x200 tiles.
    assert_eq!(image.width, 128 * 4);
    assert_eq!(image.height, 200 * 3);
    assert_eq!(image.depth, 10);
    // Gain map: 2x2 grid of 64x80 tiles.
    assert!(decoder.gainmap_present());
    assert_eq!(decoder.gainmap().image.width, 64 * 2);
    assert_eq!(decoder.gainmap().image.height, 80 * 2);
    assert_eq!(decoder.gainmap().image.depth, 8);
    assert_eq!(decoder.gainmap().metadata.base_hdr_headroom.0, 6);
    assert_eq!(decoder.gainmap().metadata.base_hdr_headroom.1, 2);
    if !HAS_DECODER {
        return;
    }
    let res = decoder.next_image();
    assert!(res.is_ok());
    assert!(decoder.gainmap().image.row_bytes[0] > 0);
}

// From avifgainmaptest.cc
#[test]
fn color_grid_alpha_grid_gainmap_nogrid() {
    let mut decoder = get_decoder("color_grid_alpha_grid_gainmap_nogrid.avif");
    decoder.settings.image_content_to_decode = ImageContentType::All;
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    // Color+alpha: 4x3 grid of 128x200 tiles.
    assert_eq!(image.width, 128 * 4);
    assert_eq!(image.height, 200 * 3);
    assert_eq!(image.depth, 10);
    // Gain map: single image of size 64x80.
    assert!(decoder.gainmap_present());
    assert_eq!(decoder.gainmap().image.width, 64);
    assert_eq!(decoder.gainmap().image.height, 80);
    assert_eq!(decoder.gainmap().image.depth, 8);
    assert_eq!(decoder.gainmap().metadata.base_hdr_headroom.0, 6);
    assert_eq!(decoder.gainmap().metadata.base_hdr_headroom.1, 2);
    if !HAS_DECODER {
        return;
    }
    let res = decoder.next_image();
    assert!(res.is_ok());
    assert!(decoder.gainmap().image.row_bytes[0] > 0);
}

// From avifgainmaptest.cc
#[test]
fn color_nogrid_alpha_nogrid_gainmap_grid() {
    let mut decoder = get_decoder("color_nogrid_alpha_nogrid_gainmap_grid.avif");
    decoder.settings.image_content_to_decode = ImageContentType::All;
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    // Color+alpha: single image of size 128x200.
    assert_eq!(image.width, 128);
    assert_eq!(image.height, 200);
    assert_eq!(image.depth, 10);
    // Gain map: 2x2 grid of 64x80 tiles.
    assert!(decoder.gainmap_present());
    assert_eq!(decoder.gainmap().image.width, 64 * 2);
    assert_eq!(decoder.gainmap().image.height, 80 * 2);
    assert_eq!(decoder.gainmap().image.depth, 8);
    assert_eq!(decoder.gainmap().metadata.base_hdr_headroom.0, 6);
    assert_eq!(decoder.gainmap().metadata.base_hdr_headroom.1, 2);
    if !HAS_DECODER {
        return;
    }
    let res = decoder.next_image();
    assert!(res.is_ok());
    assert!(decoder.gainmap().image.row_bytes[0] > 0);
}

// From avifgainmaptest.cc
#[test]
fn gainmap_oriented() {
    let mut decoder = get_decoder("gainmap_oriented.avif");
    decoder.settings.image_content_to_decode = ImageContentType::All;
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    assert_eq!(image.irot_angle, Some(1));
    assert_eq!(image.imir_axis, Some(0));
    assert!(decoder.gainmap_present());
    assert_eq!(decoder.gainmap().image.irot_angle, None);
    assert_eq!(decoder.gainmap().image.imir_axis, None);
}

// The two test files should produce the same results:
// One has an unsupported 'version' field, the other an unsupported
// 'minimum_version' field, but the behavior of these two files is the same.
// From avifgainmaptest.cc
#[test_case::test_case("unsupported_gainmap_version.avif")]
#[test_case::test_case("unsupported_gainmap_minimum_version.avif")]
fn decode_unsupported_version(filename: &str) {
    // Parse with various settings.
    let mut decoder = get_decoder(filename);
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    // Gain map marked as not present because the metadata is not supported.
    assert!(!decoder.gainmap_present());
    assert_eq!(decoder.gainmap().image.width, 0);
    assert_eq!(decoder.gainmap().metadata.base_hdr_headroom.0, 0);
    assert_eq!(decoder.gainmap().metadata.alternate_hdr_headroom.0, 0);

    decoder = get_decoder(filename);
    decoder.settings.image_content_to_decode = ImageContentType::All;
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    // Gainmap not found: its metadata is not supported.
    assert!(!decoder.gainmap_present());
    assert_eq!(decoder.gainmap().image.width, 0);
    assert_eq!(decoder.gainmap().metadata.base_hdr_headroom.0, 0);
    assert_eq!(decoder.gainmap().metadata.alternate_hdr_headroom.0, 0);
}

// From avifgainmaptest.cc
#[test]
fn decode_unsupported_writer_version_with_extra_bytes() {
    let mut decoder = get_decoder("unsupported_gainmap_writer_version_with_extra_bytes.avif");
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    // Decodes successfully: there are extra bytes at the end of the gain map
    // metadata but that's expected as the writer_version field is higher
    // that supported.
    assert!(decoder.gainmap_present());
    assert_eq!(decoder.gainmap().metadata.base_hdr_headroom.0, 6);
    assert_eq!(decoder.gainmap().metadata.base_hdr_headroom.1, 2);
}

// From avifgainmaptest.cc
#[test]
fn decode_supported_writer_version_with_extra_bytes() {
    let mut decoder = get_decoder("supported_gainmap_writer_version_with_extra_bytes.avif");
    let res = decoder.parse();
    // Fails to decode: there are extra bytes at the end of the gain map metadata
    // that shouldn't be there.
    assert!(matches!(res, Err(AvifError::InvalidToneMappedImage(_))));
}

// From avifgainmaptest.cc
#[test]
fn decode_ignore_gain_map_but_read_metadata() {
    let mut decoder = get_decoder("seine_sdr_gainmap_srgb.avif");

    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    decoder.image().expect("image was none");
    // Gain map not decoded.
    assert!(decoder.gainmap_present());
    // ... but not decoded because enableDecodingGainMap is false by default.
    assert_eq!(decoder.gainmap().image.width, 0);
    assert_eq!(decoder.gainmap().image.row_bytes[0], 0);
    // Check that the gain map metadata WAS populated.
    assert_eq!(decoder.gainmap().metadata.alternate_hdr_headroom.0, 13);
    assert_eq!(decoder.gainmap().metadata.alternate_hdr_headroom.1, 10);
}

// From avifgainmaptest.cc
#[test]
fn decode_ignore_color_and_alpha() {
    let mut decoder = get_decoder("seine_sdr_gainmap_srgb.avif");
    decoder.settings.image_content_to_decode = ImageContentType::GainMap;

    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);

    let image = decoder.image().expect("image was none");
    // Main image metadata is available.
    assert_eq!(image.width, 400);
    // The gain map metadata is available.
    assert!(decoder.gainmap_present());
    assert_eq!(decoder.gainmap().image.width, 400);
    assert_eq!(decoder.gainmap().metadata.alternate_hdr_headroom.0, 13);

    if !HAS_DECODER {
        return;
    }
    let res = decoder.next_image();
    let image = decoder.image().expect("image was none");
    assert!(res.is_ok());
    // Main image pixels are not available.
    assert_eq!(image.row_bytes[0], 0);
    // Gain map pixels are available.
    assert!(decoder.gainmap().image.row_bytes[0] > 0);
}

// From avifgainmaptest.cc
#[test_case::test_case("paris_icc_exif_xmp.avif")]
#[test_case::test_case("sofa_grid1x5_420.avif")]
#[test_case::test_case("color_grid_alpha_nogrid.avif")]
#[test_case::test_case("seine_sdr_gainmap_srgb.avif")]
fn decode_ignore_all(filename: &str) {
    let mut decoder = get_decoder(filename);
    // Ignore both the main image and the gain map.
    decoder.settings.image_content_to_decode = ImageContentType::None;
    // But do read the gain map metadata

    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    // Main image metadata is available.
    assert!(image.width > 0);
    // But trying to access the next image should give an error because both
    // ignoreColorAndAlpha and enableDecodingGainMap are set.
    let res = decoder.next_image();
    assert!(res.is_err());
}

// From avifcllitest.cc
#[test_case::test_case("clli_0_0.avif", 0, 0; "clli_0_0")]
#[test_case::test_case("clli_0_1.avif", 0, 1; "clli_0_1")]
#[test_case::test_case("clli_0_65535.avif", 0, 65535; "clli_0_65535")]
#[test_case::test_case("clli_1_0.avif", 1, 0; "clli_1_0")]
#[test_case::test_case("clli_1_1.avif", 1, 1; "clli_1_1")]
#[test_case::test_case("clli_1_65535.avif", 1, 65535; "clli_1_65535")]
#[test_case::test_case("clli_65535_0.avif", 65535, 0; "clli_65535_0")]
#[test_case::test_case("clli_65535_1.avif", 65535, 1; "clli_65535_1")]
#[test_case::test_case("clli_65535_65535.avif", 65535, 65535; "clli_65535_65535")]
fn clli(filename: &str, max_cll: u16, max_pall: u16) {
    let mut filename_with_prefix = String::from("clli/");
    filename_with_prefix.push_str(filename);
    let mut decoder = get_decoder(&filename_with_prefix);
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    if max_cll == 0 && max_pall == 0 {
        assert!(image.clli.is_none());
    } else {
        assert!(image.clli.is_some());
        let clli = image.clli.as_ref().unwrap();
        assert_eq!(clli.max_cll, max_cll);
        assert_eq!(clli.max_pall, max_pall);
    }
}

#[test]
fn raw_io() {
    let data =
        std::fs::read(get_test_file("colors-animated-8bpc.avif")).expect("Unable to read file");
    let mut decoder = decoder::Decoder::default();
    let _ = unsafe {
        decoder
            .set_io_raw(data.as_ptr(), data.len())
            .expect("Failed to set IO")
    };
    assert!(decoder.parse().is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    assert_eq!(decoder.image_count(), 5);
    if !HAS_DECODER {
        return;
    }
    for _ in 0..5 {
        assert!(decoder.next_image().is_ok());
    }
}

struct CustomIO {
    data: Vec<u8>,
    available_size_rc: Rc<RefCell<usize>>,
}

impl decoder::IO for CustomIO {
    fn read(&mut self, offset: u64, max_read_size: usize) -> AvifResult<&[u8]> {
        let available_size = self.available_size_rc.borrow();
        let start = usize::try_from(offset).unwrap();
        let end = start + max_read_size;
        if start > self.data.len() || end > self.data.len() {
            return Err(AvifError::IoError);
        }
        let mut ssize = max_read_size;
        if ssize > self.data.len() - start {
            ssize = self.data.len() - start;
        }
        let end = start + ssize;
        if *available_size < end {
            return Err(AvifError::WaitingOnIo);
        }
        Ok(&self.data[start..end])
    }

    fn size_hint(&self) -> u64 {
        self.data.len() as u64
    }

    fn persistent(&self) -> bool {
        false
    }
}

#[test]
fn custom_io() {
    let data =
        std::fs::read(get_test_file("colors-animated-8bpc.avif")).expect("Unable to read file");
    let mut decoder = decoder::Decoder::default();
    let available_size_rc = Rc::new(RefCell::new(data.len()));
    let io = Box::new(CustomIO {
        available_size_rc: available_size_rc.clone(),
        data,
    });
    decoder.set_io(io);
    assert!(decoder.parse().is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    assert_eq!(decoder.image_count(), 5);
    if !HAS_DECODER {
        return;
    }
    for _ in 0..5 {
        assert!(decoder.next_image().is_ok());
    }
}

fn expected_min_decoded_row_count(
    height: u32,
    cell_height: u32,
    cell_columns: u32,
    available_size: usize,
    size: usize,
    grid_cell_offsets: &Vec<usize>,
) -> u32 {
    if available_size >= size {
        return height;
    }
    let mut cell_index: Option<usize> = None;
    for (index, offset) in grid_cell_offsets.iter().enumerate().rev() {
        if available_size >= *offset {
            cell_index = Some(index);
            break;
        }
    }
    if cell_index.is_none() {
        return 0;
    }
    let cell_index = cell_index.unwrap() as u32;
    let cell_row = cell_index / cell_columns;
    let cell_column = cell_index % cell_columns;
    let cell_rows_decoded = if cell_column == cell_columns - 1 { cell_row + 1 } else { cell_row };
    cell_rows_decoded * cell_height
}

#[test]
fn expected_min_decoded_row_count_computation() {
    let grid_cell_offsets: Vec<usize> = vec![3258, 10643, 17846, 22151, 25409, 30000];
    let cell_height = 154;
    assert_eq!(
        0,
        expected_min_decoded_row_count(770, cell_height, 1, 1000, 30000, &grid_cell_offsets)
    );
    assert_eq!(
        1 * cell_height,
        expected_min_decoded_row_count(770, cell_height, 1, 4000, 30000, &grid_cell_offsets)
    );
    assert_eq!(
        2 * cell_height,
        expected_min_decoded_row_count(770, cell_height, 1, 12000, 30000, &grid_cell_offsets)
    );
    assert_eq!(
        3 * cell_height,
        expected_min_decoded_row_count(770, cell_height, 1, 17846, 30000, &grid_cell_offsets)
    );
    assert_eq!(
        1 * cell_height,
        expected_min_decoded_row_count(462, cell_height, 2, 17846, 30000, &grid_cell_offsets)
    );
    assert_eq!(
        2 * cell_height,
        expected_min_decoded_row_count(462, cell_height, 2, 23000, 30000, &grid_cell_offsets)
    );
    assert_eq!(
        1 * cell_height,
        expected_min_decoded_row_count(308, cell_height, 3, 23000, 30000, &grid_cell_offsets)
    );
    assert_eq!(
        2 * cell_height,
        expected_min_decoded_row_count(308, cell_height, 3, 30000, 30000, &grid_cell_offsets)
    );
}

#[test]
fn incremental_decode() {
    // Grid item offsets for sofa_grid1x5_420.avif:
    // Each line is "$extent_offset + $extent_length".
    let grid_cell_offsets: Vec<usize> = vec![
        578 + 2680,
        3258 + 7385,
        10643 + 7203,
        17846 + 4305,
        22151 + 3258,
    ];

    let data = std::fs::read(get_test_file("sofa_grid1x5_420.avif")).expect("Unable to read file");
    let len = data.len();
    let available_size_rc = Rc::new(RefCell::new(0usize));
    let mut decoder = decoder::Decoder::default();
    decoder.settings.allow_incremental = true;
    let io = Box::new(CustomIO {
        available_size_rc: available_size_rc.clone(),
        data,
    });
    decoder.set_io(io);
    let step: usize = std::cmp::max(1, len / 10000) as usize;

    // Parsing is not incremental.
    let mut parse_result = decoder.parse();
    while parse_result.is_err()
        && matches!(parse_result.as_ref().err().unwrap(), AvifError::WaitingOnIo)
    {
        {
            let mut available_size = available_size_rc.borrow_mut();
            if *available_size >= len {
                println!("parse returned waiting on io after full file.");
                assert!(false);
            }
            *available_size = std::cmp::min(*available_size + step, len);
        }
        parse_result = decoder.parse();
    }
    assert!(parse_result.is_ok());
    if !HAS_DECODER {
        return;
    }

    // Decoding is incremental.
    let mut previous_decoded_row_count = 0;
    let mut decode_result = decoder.next_image();
    while decode_result.is_err()
        && matches!(
            decode_result.as_ref().err().unwrap(),
            AvifError::WaitingOnIo
        )
    {
        {
            let mut available_size = available_size_rc.borrow_mut();
            if *available_size >= len {
                println!("next_image returned waiting on io after full file.");
                assert!(false);
            }
            let decoded_row_count = decoder.decoded_row_count();
            assert!(decoded_row_count >= previous_decoded_row_count);
            let expected_min_decoded_row_count = expected_min_decoded_row_count(
                decoder.image().unwrap().height,
                154,
                1,
                *available_size,
                len,
                &grid_cell_offsets,
            );
            assert!(decoded_row_count >= expected_min_decoded_row_count);
            previous_decoded_row_count = decoded_row_count;
            *available_size = std::cmp::min(*available_size + step, len);
        }
        decode_result = decoder.next_image();
    }
    assert!(decode_result.is_ok());
    assert_eq!(decoder.decoded_row_count(), decoder.image().unwrap().height);

    // TODO: check if incremental and non incremental produces same output.
}

#[test]
fn nth_image() {
    let mut decoder = get_decoder("colors-animated-8bpc.avif");
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    assert_eq!(decoder.image_count(), 5);
    if !HAS_DECODER {
        return;
    }
    assert!(decoder.nth_image(3).is_ok());
    assert!(decoder.next_image().is_ok());
    assert!(decoder.next_image().is_err());
    assert!(decoder.nth_image(1).is_ok());
    assert!(decoder.nth_image(4).is_ok());
    assert!(decoder.nth_image(50).is_err());
}

#[test]
fn color_and_alpha_dimensions_do_not_match() {
    let mut decoder = get_decoder("invalid_color10x10_alpha5x5.avif");
    // Parsing should succeed.
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    assert_eq!(image.width, 10);
    assert_eq!(image.height, 10);
    if !HAS_DECODER {
        return;
    }
    // Decoding should fail.
    let res = decoder.next_image();
    assert!(res.is_err());
}

#[test]
fn rgb_conversion_alpha_premultiply() -> AvifResult<()> {
    let mut decoder = get_decoder("alpha.avif");
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    if !HAS_DECODER {
        return Ok(());
    }
    let res = decoder.next_image();
    assert!(res.is_ok());
    let image = decoder.image().expect("image was none");
    let mut rgb = rgb::Image::create_from_yuv(image);
    rgb.premultiply_alpha = true;
    rgb.allocate()?;
    assert!(rgb.convert_from_yuv(image).is_ok());
    Ok(())
}

#[test]
fn white_1x1() -> AvifResult<()> {
    let mut decoder = get_decoder("white_1x1.avif");
    assert_eq!(decoder.parse(), Ok(()));
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    if !HAS_DECODER {
        return Ok(());
    }
    assert_eq!(decoder.next_image(), Ok(()));

    let image = decoder.image().expect("image was none");
    let mut rgb = rgb::Image::create_from_yuv(image);
    rgb.allocate()?;
    assert!(rgb.convert_from_yuv(image).is_ok());
    assert_eq!(rgb.width * rgb.height, 1);
    let format = rgb.format;
    for i in [format.r_offset(), format.g_offset(), format.b_offset()] {
        assert_eq!(rgb.row(0)?[i], 253); // Compressed with loss, not pure white.
    }
    if rgb.has_alpha() {
        assert_eq!(rgb.row(0)?[rgb.format.alpha_offset()], 255);
    }
    Ok(())
}

#[test]
fn white_1x1_mdat_size0() -> AvifResult<()> {
    // Edit the file to simulate an 'mdat' box with size 0 (meaning it ends at EOF).
    let mut file_bytes = std::fs::read(get_test_file("white_1x1.avif")).unwrap();
    let mdat = [b'm', b'd', b'a', b't'];
    let mdat_size_pos = file_bytes.windows(4).position(|w| w == mdat).unwrap() - 4;
    file_bytes[mdat_size_pos + 3] = b'\0';

    let mut decoder = decoder::Decoder::default();
    decoder.set_io_vec(file_bytes);
    assert_eq!(decoder.parse(), Ok(()));
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    Ok(())
}

#[test]
fn white_1x1_meta_size0() -> AvifResult<()> {
    // Edit the file to simulate a 'meta' box with size 0 (invalid).
    let mut file_bytes = std::fs::read(get_test_file("white_1x1.avif")).unwrap();
    let meta = [b'm', b'e', b't', b'a'];
    let meta_size_pos = file_bytes.windows(4).position(|w| w == meta).unwrap() - 4;
    file_bytes[meta_size_pos + 3] = b'\0';

    let mut decoder = decoder::Decoder::default();
    decoder.set_io_vec(file_bytes);

    // This should fail because the meta box contains the mdat box.
    // However, the section 8.11.3.1 of ISO/IEC 14496-12 does not explicitly require the coded image
    // item extents to be read from the MediaDataBox if the construction_method is 0.
    // Maybe another section or specification enforces that.
    assert_eq!(decoder.parse(), Ok(()));
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    if !HAS_DECODER {
        return Ok(());
    }
    assert_eq!(decoder.next_image(), Ok(()));
    Ok(())
}

#[test]
fn white_1x1_ftyp_size0() -> AvifResult<()> {
    // Edit the file to simulate a 'ftyp' box with size 0 (invalid).
    let mut file_bytes = std::fs::read(get_test_file("white_1x1.avif")).unwrap();
    file_bytes[3] = b'\0';

    let mut decoder = decoder::Decoder::default();
    decoder.set_io_vec(file_bytes);
    assert!(matches!(
        decoder.parse(),
        Err(AvifError::BmffParseFailed(_))
    ));
    Ok(())
}

#[test]
fn dimg_repetition() {
    let mut decoder = get_decoder("sofa_grid1x5_420_dimg_repeat.avif");
    assert_eq!(
        decoder.parse(),
        Err(AvifError::BmffParseFailed(
            "multiple dimg references for item ID 1".into()
        ))
    );
}

#[test]
fn dimg_shared() {
    let mut decoder = get_decoder("color_grid_alpha_grid_tile_shared_in_dimg.avif");
    assert_eq!(decoder.parse(), Err(AvifError::NotImplemented));
}

#[test]
fn dimg_ordering() {
    if !HAS_DECODER {
        return;
    }
    let mut decoder1 = get_decoder("sofa_grid1x5_420.avif");
    let res = decoder1.parse();
    assert!(res.is_ok());
    let res = decoder1.next_image();
    assert!(res.is_ok());
    let mut decoder2 = get_decoder("sofa_grid1x5_420_random_dimg_order.avif");
    let res = decoder2.parse();
    assert!(res.is_ok());
    let res = decoder2.next_image();
    assert!(res.is_ok());
    let image1 = decoder1.image().expect("image1 was none");
    let image2 = decoder2.image().expect("image2 was none");
    // Ensure that the pixels in image1 and image2 are not the same.
    let row1 = image1.row(Plane::Y, 0).expect("row1 was none");
    let row2 = image2.row(Plane::Y, 0).expect("row2 was none");
    assert_ne!(row1, row2);
}

#[test]
fn heic_peek() {
    let file_data = std::fs::read(get_test_file("blue.heic")).expect("could not read file");
    assert_eq!(
        decoder::Decoder::peek_compatible_file_type(&file_data),
        cfg!(feature = "heic")
    );
}

#[test]
fn heic_parsing() {
    let mut decoder = get_decoder("blue.heic");
    let res = decoder.parse();
    if cfg!(feature = "heic") {
        assert!(res.is_ok());
        let image = decoder.image().expect("image was none");
        assert_eq!(image.width, 320);
        assert_eq!(image.height, 240);
        assert_eq!(decoder.compression_format(), CompressionFormat::Heic);
        if cfg!(feature = "android_mediacodec") {
            // Decoding is available only via android_mediacodec.
            assert!(!matches!(
                decoder.next_image(),
                Err(AvifError::NoCodecAvailable)
            ));
        }
    } else {
        assert!(res.is_err());
    }
}

#[test]
fn clap_irot_imir_non_essential() {
    let mut decoder = get_decoder("clap_irot_imir_non_essential.avif");
    let res = decoder.parse();
    assert!(res.is_err());
}

#[derive(Clone)]
struct ExpectedOverlayImageInfo<'a> {
    filename: &'a str,
    width: u32,
    height: u32,
    expected_pixels: &'a [(usize, u32, [u8; 4])], // (x, y, [rgba]).
}

const RED: [u8; 4] = [255, 0, 0, 255];
const GREEN: [u8; 4] = [0, 255, 0, 255];
const BLUE: [u8; 4] = [0, 0, 255, 255];
const BLACK: [u8; 4] = [0, 0, 0, 255];
const YELLOW: [u8; 4] = [255, 255, 0, 255];

const EXPECTED_OVERLAY_IMAGE_INFOS: [ExpectedOverlayImageInfo; 4] = [
    ExpectedOverlayImageInfo {
        // Three 80x60 sub-images with the following offsets:
        // horizontal_offsets: [0, 40, 80]
        // vertical_offsets: [0, 40, 80]
        filename: "overlay_exact_bounds.avif",
        width: 160,
        height: 140,
        expected_pixels: &[
            // Top left should be red.
            (0, 0, RED),
            (10, 10, RED),
            (20, 20, RED),
            // Green should be overlaid on top of the red block starting at (40, 40).
            (40, 40, GREEN),
            (50, 50, GREEN),
            (60, 60, GREEN),
            // Blue should be overlaid on top of the green block starting at (80, 80).
            (80, 80, BLUE),
            (90, 90, BLUE),
            (100, 100, BLUE),
            // Top right should be background color.
            (159, 0, BLACK),
            // Bottom left should be background color.
            (0, 139, BLACK),
        ],
    },
    ExpectedOverlayImageInfo {
        // Three 80x60 sub-images with the following offsets:
        // horizontal_offsets: [20, 60, 100]
        // vertical_offsets: [20, 60, 100]
        filename: "overlay_with_border.avif",
        width: 200,
        height: 180,
        expected_pixels: &[
            // Top left should be background color.
            (0, 0, BLACK),
            // Red should be overlaid starting at (20, 20).
            (20, 20, RED),
            (30, 30, RED),
            (40, 40, RED),
            // Green should be overlaid on top of the red block starting at (60, 60).
            (60, 60, GREEN),
            (70, 70, GREEN),
            (80, 80, GREEN),
            // Blue should be overlaid on top of the green block starting at (100, 100).
            (100, 100, BLUE),
            (110, 110, BLUE),
            (120, 120, BLUE),
            // Top right should be background color.
            (199, 0, BLACK),
            // Bottom left should be background color.
            (0, 179, BLACK),
            // Bottom right should be background color.
            (199, 179, BLACK),
        ],
    },
    ExpectedOverlayImageInfo {
        // Two 80x60 sub-images with the following offsets:
        // horizontal_offsets: [-40, 120]
        // vertical_offsets: [-40, 100]
        filename: "overlay_outside_bounds.avif",
        width: 160,
        height: 140,
        expected_pixels: &[
            // Red overlay is 40x20 in the top left.
            (0, 0, RED),
            (15, 15, RED),
            (39, 19, RED),
            (40, 20, BLACK),
            // Blue overlay is 40x40 in the bottom right.
            (119, 99, BLACK),
            (120, 100, BLUE),
            (140, 120, BLUE),
            (159, 139, BLUE),
            // Center of the image should be background color.
            (80, 70, BLACK),
            // Top right should be background color.
            (159, 0, BLACK),
            // Bottom left should be background color.
            (0, 139, BLACK),
        ],
    },
    ExpectedOverlayImageInfo {
        // Three 80x60 sub-images with the following offsets:
        // horizontal_offsets: [0, 40, 80]
        // vertical_offsets: [0, 40, 80]
        // canvas background color: yellow.
        filename: "overlay_yellow_bg.avif",
        width: 160,
        height: 140,
        expected_pixels: &[
            // Top left should be red.
            (0, 0, RED),
            (10, 10, RED),
            (20, 20, RED),
            // Green should be overlaid on top of the red block starting at (40, 40).
            (40, 40, GREEN),
            (50, 50, GREEN),
            (60, 60, GREEN),
            // Blue should be overlaid on top of the green block starting at (80, 80).
            (80, 80, BLUE),
            (90, 90, BLUE),
            (100, 100, BLUE),
            // Top right should be background color.
            (159, 0, YELLOW),
            // Bottom left should be background color.
            (0, 139, YELLOW),
        ],
    },
];

macro_rules! pixel_eq {
    ($a:expr, $b:expr) => {
        assert!((i32::from($a) - i32::from($b)).abs() <= 3);
    };
}

#[test_case::test_matrix(0usize..4)]
fn overlay(index: usize) {
    let info = &EXPECTED_OVERLAY_IMAGE_INFOS[index];
    let mut decoder = get_decoder(info.filename);
    decoder.settings.strictness = decoder::Strictness::None;
    let res = decoder.parse();
    assert!(res.is_ok());
    assert_eq!(decoder.compression_format(), CompressionFormat::Avif);
    let image = decoder.image().expect("image was none");
    assert_eq!(image.width, info.width);
    assert_eq!(image.height, info.height);
    if !HAS_DECODER {
        return;
    }
    let res = decoder.next_image();
    assert!(res.is_ok());
    let image = decoder.image().expect("image was none");
    assert_eq!(image.width, info.width);
    assert_eq!(image.height, info.height);
    let mut rgb = rgb::Image::create_from_yuv(image);
    rgb.format = rgb::Format::Rgba;
    assert!(rgb.allocate().is_ok());
    assert!(rgb.convert_from_yuv(image).is_ok());
    for expected_pixel in info.expected_pixels {
        let column = expected_pixel.0;
        let row = expected_pixel.1;
        let pixels = rgb.row(row).expect("row was none");
        let r = pixels[column * 4];
        let g = pixels[(column * 4) + 1];
        let b = pixels[(column * 4) + 2];
        let a = pixels[(column * 4) + 3];
        pixel_eq!(r, expected_pixel.2[0]);
        pixel_eq!(g, expected_pixel.2[1]);
        pixel_eq!(b, expected_pixel.2[2]);
        pixel_eq!(a, expected_pixel.2[3]);
    }
}
