mirx 0.45.0

MIRX binary image format — flat & chunk-based container for ahead-of-time UI assets
Documentation
use super::super::tests::payload;
use super::*;

use crate::{
    coding::{CodingId, Lz4, Pixel, Rle},
    image::{
        ColorDescription, CoverageError, EncodedImageAsset, SampleLayout, SurfaceDescriptor,
        UnitGroupRecord,
        test_support::{data_offset, refresh_crc},
    },
    media::CodingRecord,
};

#[test]
fn shared_surface_admission_accumulates_limits_and_checksums_once() {
    let surface = SurfaceDescriptor::new(2, 2, SampleLayout::A8, ColorDescription::NONE).unwrap();
    let bytes = EncodedImageAsset::new(surface, Rle::new().record(), &[0x83, 42])
        .encode()
        .unwrap();
    let image = EncodedImageView::open(&bytes).unwrap();
    let limits = PayloadLimits::EMBEDDED;
    let mut single = Preflight::new(&limits, 0).unwrap();
    single.image(image).unwrap();
    let work = single.work();
    single.data(image.media, image.checksum_bytes).unwrap();
    assert_eq!(single.work(), work + 2);
    image
        .preflight(&limits.with_max_raster_work(work + 2))
        .unwrap();
    assert!(
        image
            .preflight(&limits.with_max_raster_work(work + 1))
            .is_err()
    );

    let limits = limits
        .with_max_raster_groups(2)
        .with_max_raster_units(2)
        .with_max_raster_work(work * 2 + 2);
    let mut shared = Preflight::new(&limits, 0).unwrap();
    shared.image(image).unwrap();
    shared.image(image).unwrap();
    assert_eq!(shared.total_groups, 2);
    assert_eq!(shared.total_units(), 2);
    assert_eq!(shared.work(), work * 2);
    shared.data(image.media, image.checksum_bytes).unwrap();
    assert_eq!(shared.work(), work * 2 + 2);

    let group_limits = limits.with_max_raster_groups(1);
    let mut groups = Preflight::new(&group_limits, 0).unwrap();
    groups.image(image).unwrap();
    assert_eq!(
        groups.image(image),
        Err(EncodedImageError::TooManyGroups {
            limit: 1,
            actual: 2
        })
    );
    assert_eq!(groups.total_groups, 1);
    assert_eq!(groups.work(), work);
    let unit_limits = limits.with_max_raster_units(1);
    let mut units = Preflight::new(&unit_limits, 0).unwrap();
    units.image(image).unwrap();
    assert_eq!(
        units.image(image),
        Err(EncodedImageError::TooManyUnits {
            limit: 1,
            actual: 2
        })
    );
    let work_limits = limits.with_max_raster_work(work);
    let mut budget = Preflight::new(&work_limits, 0).unwrap();
    budget.image(image).unwrap();
    assert_eq!(
        budget.image(image),
        Err(EncodedImageError::Coverage(CoverageError::BudgetExceeded))
    );
    assert_eq!(
        groups.add_groups(usize::MAX),
        Err(EncodedImageError::SizeOverflow)
    );
    assert_eq!(groups.total_groups, 1);
}

#[test]
fn checksum_budget_exhaustion_precedes_corrupt_data_scans() {
    let surface = SurfaceDescriptor::new(2, 2, SampleLayout::A8, ColorDescription::NONE).unwrap();
    let mut bytes = EncodedImageAsset::new(surface, Rle::new().record(), &[0x83, 42])
        .encode()
        .unwrap();
    let data = data_offset(&bytes);
    bytes[data + 1] ^= 1;
    let image = EncodedImageView::open(&bytes).unwrap();
    let limits = PayloadLimits::EMBEDDED;
    let mut probe = Preflight::new(&limits, 0).unwrap();
    probe.image(image).unwrap();
    probe.image(image).unwrap();
    let work = probe.work();
    for (allowed, checksum_expected) in [(work + 1, false), (work + 2, true)] {
        let limits = limits.with_max_raster_work(allowed);
        let mut preflight = Preflight::new(&limits, 0).unwrap();
        preflight.image(image).unwrap();
        preflight.image(image).unwrap();
        let result = preflight.data(image.media, image.checksum_bytes);
        if checksum_expected {
            assert!(matches!(result, Err(EncodedImageError::Media(_))));
        } else {
            assert_eq!(
                result,
                Err(EncodedImageError::Coverage(CoverageError::BudgetExceeded))
            );
        }
    }
}

#[test]
fn scalar_syntax_and_integrity_are_both_required() {
    let surface =
        SurfaceDescriptor::new(2, 2, SampleLayout::RGB888, ColorDescription::SRGB).unwrap();
    let samples = [42; 12];
    let pixel = Pixel::new(SampleLayout::RGB888).unwrap();
    let rle = Rle::new();
    let lz4 = Lz4::new();
    for coding in [pixel.record(), rle.record(), lz4.record()] {
        let mut stream = [0; 32];
        let len = match coding.id() {
            CodingId::PIXEL => pixel.encode_into(&samples, &mut stream).unwrap(),
            CodingId::RLE => rle.encode_into(&samples, &mut stream).unwrap(),
            _ => lz4
                .encoder(&mut [0; Lz4::TABLE_LEN])
                .unwrap()
                .encode_into(&samples, &mut stream)
                .unwrap(),
        };
        let bytes = EncodedImageAsset::new(surface, coding, &stream[..len])
            .encode()
            .unwrap();
        EncodedImageView::open(&bytes)
            .unwrap()
            .preflight(&PayloadLimits::EMBEDDED)
            .unwrap();
        let malformed = EncodedImageAsset::new(surface, coding, &[0xff])
            .encode()
            .unwrap();
        assert!(matches!(
            EncodedImageView::open(&malformed)
                .unwrap()
                .preflight(&PayloadLimits::EMBEDDED),
            Err(EncodedImageError::Unit {
                group: 0,
                ordinal: 0,
                ..
            })
        ));
    }
    let mut bytes = EncodedImageAsset::new(surface, rle.record(), &[0x8b, 42])
        .encode()
        .unwrap();
    let data = data_offset(&bytes);
    bytes[data + 1] ^= 1;
    assert!(matches!(
        EncodedImageView::open(&bytes)
            .unwrap()
            .preflight(&PayloadLimits::EMBEDDED),
        Err(EncodedImageError::Media(_))
    ));
    refresh_crc(&mut bytes);
    EncodedImageView::open(&bytes)
        .unwrap()
        .preflight(&PayloadLimits::EMBEDDED)
        .unwrap();
}

#[test]
fn limits_bound_independent_units_instead_of_allocating_the_full_surface() {
    let surface = SurfaceDescriptor::new(8, 1, SampleLayout::A8, ColorDescription::NONE).unwrap();
    let record = UnitGroupRecord::new(0, 0..8).unwrap().with_tiles(2, 1);
    let bytes = payload(
        surface,
        &[Rle::new().record()],
        Some(&[record]),
        None,
        &[0x81, 42, 0x81, 43, 0x81, 44, 0x81, 45],
        None,
        None,
    );
    let view = EncodedImageView::open(&bytes).unwrap();
    let limits = PayloadLimits::EMBEDDED
        .with_max_decoded_bytes(2)
        .with_max_raster_groups(1)
        .with_max_raster_units(4);
    assert_eq!(view.preflight(&limits), Ok(()));
    assert_eq!(
        view.preflight(&limits.with_max_decoded_bytes(1)),
        Err(EncodedImageError::DecodedUnitTooLarge {
            group: 0,
            ordinal: 0,
            limit: 1,
            actual: 2
        })
    );
    assert_eq!(
        view.preflight(&limits.with_max_raster_units(3)),
        Err(EncodedImageError::TooManyUnits {
            limit: 3,
            actual: 4
        })
    );
    assert_eq!(
        view.preflight(&limits.with_max_raster_groups(0)),
        Err(EncodedImageError::TooManyGroups {
            limit: 0,
            actual: 1
        })
    );
    let minimum = (0..1024)
        .find(|work| view.preflight(&limits.with_max_raster_work(*work)).is_ok())
        .unwrap();
    assert!(minimum > 8 + 8 + 8);
    assert_eq!(
        view.preflight(&limits.with_max_raster_work(minimum - 1)),
        Err(EncodedImageError::Coverage(CoverageError::BudgetExceeded))
    );
    let indexed = payload(
        surface,
        &[Rle::new().record()],
        Some(&[record]),
        None,
        &[0x81, 42, 0x81, 43, 0x81, 44, 0x81, 45],
        None,
        Some(&[2, 2, 2, 2]),
    );
    EncodedImageView::open(&indexed)
        .unwrap()
        .preflight(&limits)
        .unwrap();
}

#[test]
fn empty_surfaces_still_require_an_understood_active_profile() {
    let surface =
        SurfaceDescriptor::new(0, u32::MAX, SampleLayout::A8, ColorDescription::NONE).unwrap();
    let limits = PayloadLimits::EMBEDDED
        .with_max_raster_units(0)
        .with_max_decoded_bytes(0);
    for coding in [Rle::new().record(), Lz4::new().record()] {
        let bytes = EncodedImageAsset::new(surface, coding, &[])
            .encode()
            .unwrap();
        EncodedImageView::open(&bytes)
            .unwrap()
            .preflight(&limits)
            .unwrap();
    }
    for coding in [
        CodingRecord::new(CodingId::new(511), 1, &[]),
        CodingRecord::new(CodingId::LZ4, 2, &[]),
        CodingRecord::new(CodingId::RLE, 1, &[1]),
        Pixel::new(SampleLayout::RGB888).unwrap().record(),
    ] {
        let bytes = EncodedImageAsset::new(surface, coding, &[])
            .encode()
            .unwrap();
        assert!(matches!(
            EncodedImageView::open(&bytes).unwrap().preflight(&limits),
            Err(EncodedImageError::Coding { group: 0, .. })
        ));
    }
    let rgb =
        SurfaceDescriptor::new(0, u32::MAX, SampleLayout::RGB888, ColorDescription::SRGB).unwrap();
    let bytes =
        EncodedImageAsset::new(rgb, Pixel::new(SampleLayout::RGB888).unwrap().record(), &[])
            .encode()
            .unwrap();
    EncodedImageView::open(&bytes)
        .unwrap()
        .preflight(&limits)
        .unwrap();
}

#[test]
fn coded_limits_and_errors_follow_group_and_unit_locations() {
    use crate::image::{GroupPlanes, ReferenceMode};
    let surface = SurfaceDescriptor::new(
        3,
        3,
        SampleLayout::NV12,
        ColorDescription::BT709_YUV_LIMITED,
    )
    .unwrap();
    let records = [
        UnitGroupRecord::new(0, 0..2)
            .unwrap()
            .with_planes(GroupPlanes::Plane(0)),
        UnitGroupRecord::new(1, 2..4)
            .unwrap()
            .with_planes(GroupPlanes::Plane(1)),
    ];
    let bytes = payload(
        surface,
        &[Rle::new().record(), Rle::new().record()],
        Some(&records),
        None,
        &[0x88, 16, 0x87, 128],
        None,
        None,
    );
    let view = EncodedImageView::open(&bytes).unwrap();
    assert_eq!(
        view.preflight(&PayloadLimits::EMBEDDED.with_max_raster_groups(1)),
        Err(EncodedImageError::TooManyGroups {
            limit: 1,
            actual: 2
        })
    );
    assert_eq!(
        view.preflight(&PayloadLimits::EMBEDDED.with_max_raster_units(1)),
        Err(EncodedImageError::TooManyUnits {
            limit: 1,
            actual: 2
        })
    );
    view.preflight(&PayloadLimits::EMBEDDED).unwrap();
    let malformed = payload(
        surface,
        &[Rle::new().record(), Rle::new().record()],
        Some(&records),
        None,
        &[0x88, 16, 0x86, 128],
        None,
        None,
    );
    assert!(matches!(
        EncodedImageView::open(&malformed)
            .unwrap()
            .preflight(&PayloadLimits::EMBEDDED),
        Err(EncodedImageError::Unit {
            group: 1,
            ordinal: 0,
            ..
        })
    ));
    let mut temporal = records;
    temporal[1] = temporal[1].with_reference(ReferenceMode::Previous);
    let bytes = payload(
        surface,
        &[Rle::new().record(), Rle::new().record()],
        Some(&temporal),
        None,
        &[0x88, 16, 0x87, 128],
        None,
        None,
    );
    assert_eq!(
        EncodedImageView::open(&bytes)
            .unwrap()
            .preflight(&PayloadLimits::EMBEDDED),
        Err(EncodedImageError::ReferenceInStaticImage(1))
    );
}