mirx 0.43.0

MIRX binary image format — flat & chunk-based container for ahead-of-time UI assets
Documentation
use super::*;
use crate::{
    PayloadLimits,
    image::{CoverageError, GroupPlanes, ReferenceMode},
    media::UnitIndexEncoding,
};

#[test]
fn planar_groups_share_profiles_and_preserve_alignment_without_unit_tables() {
    let surface = SurfaceDescriptor::new(
        3,
        3,
        SampleLayout::NV12,
        ColorDescription::BT709_YUV_LIMITED,
    )
    .unwrap();
    let codings = [Rle::new().record()];
    let records = [
        UnitGroupRecord::new(0, 0..2)
            .unwrap()
            .with_planes(GroupPlanes::Plane(0)),
        UnitGroupRecord::new(0, 64..66)
            .unwrap()
            .with_planes(GroupPlanes::Plane(1))
            .with_input_alignment(crate::ByteAlignment::new(64).unwrap()),
    ];
    let mut data = [0xa5; 66];
    data[..2].copy_from_slice(&[0x88, 16]);
    data[64..].copy_from_slice(&[0x87, 128]);
    let asset = EncodedImageAsset::from_groups(surface, &codings, &records, &data);
    assert_eq!(asset.codings().collect::<Vec<_>>(), &codings);
    assert_eq!(asset.groups(), Some(records.as_slice()));
    assert_eq!(asset.unit_index(), &[]);
    assert_eq!(
        asset.input_alignment().map(crate::ByteAlignment::get),
        Ok(64)
    );
    asset.preflight(&PayloadLimits::EMBEDDED).unwrap();
    let payload = asset.encode().unwrap();
    let view = EncodedImageView::open_at(&payload, 0).unwrap();
    view.preflight(&PayloadLimits::EMBEDDED).unwrap();
    assert_eq!(view.codings().len(), 1);
    assert_eq!(view.group_count(), 2);
    assert_eq!(
        view.input_alignment().map(crate::ByteAlignment::get),
        Ok(64)
    );
    assert!(view.media().section(MediaSectionKind::UNIT_INDEX).is_none());
    assert_eq!(
        view.media()
            .section(MediaSectionKind::DATA)
            .unwrap()
            .bytes(),
        data
    );
    let mut slots = [None; 2];
    let groups = view
        .groups_into(&mut slots, &mut CoverageBudget::new(1024))
        .unwrap();
    for (index, value, expected) in [(0, 16, 9), (1, 128, 8)] {
        let unit = groups.get(index).unwrap().get(0).unwrap();
        let plan = unit
            .decode_plan(SurfaceRequirements::new().with_stride_multiple(64))
            .unwrap();
        let mut output = [0xad; 256];
        let decoded = plan.decode_into(&mut output).unwrap();
        let plane = decoded.plane(index as u8).unwrap();
        assert_eq!(
            plane.rows().unwrap().map(|r| r.len()).sum::<usize>(),
            expected
        );
        assert!(plane.rows().unwrap().flatten().all(|b| *b == value));
    }
    assert_eq!(asset.matches_payload(&payload), Ok(true));
    let mut output = [0xad; 512];
    let len = asset.encode_into(&mut output).unwrap();
    assert_eq!(&output[..len], payload);
    assert!(output[len..].iter().all(|b| *b == 0xad));
    for index in 0..len {
        output[index] ^= 1;
        assert_eq!(asset.matches_payload(&output[..len]), Ok(false));
        output[index] ^= 1;
    }
}

#[test]
fn variable_indexes_preserve_exact_lengths_padding_and_canonical_work() {
    let surface = SurfaceDescriptor::new(5, 1, SampleLayout::A8, ColorDescription::NONE).unwrap();
    let codings = [Rle::new().record()];
    for encoding in [
        UnitIndexEncoding::Offsets,
        UnitIndexEncoding::Lengths16,
        UnitIndexEncoding::Lengths32,
    ] {
        let alignment = crate::ByteAlignment::new(if encoding == UnitIndexEncoding::Offsets {
            1
        } else {
            64
        })
        .unwrap();
        let lengths = [3, 2, 2];
        let mut index_bytes = [0; 32];
        let index_len = encoding
            .encode_into(&lengths, alignment, &mut index_bytes)
            .unwrap();
        let mut data = [0xa5; 130];
        let mut end = 0usize;
        for stream in [&[1, 1, 2][..], &[0x81, 3][..], &[0, 4][..]] {
            let start = UnitIndex::aligned(end as u32, alignment).unwrap() as usize;
            end = start + stream.len();
            data[start..end].copy_from_slice(stream);
        }
        let records = [UnitGroupRecord::new(0, 0..end as u32)
            .unwrap()
            .with_tiles(2, 1)
            .with_input_alignment(alignment)
            .with_index_encoding(encoding)];
        let asset = EncodedImageAsset::from_groups(surface, &codings, &records, &data[..end])
            .with_unit_index(&index_bytes[..index_len]);
        let payload = asset.encode().unwrap();
        let image = EncodedImageView::open(&payload).unwrap();
        assert_eq!(
            image
                .media()
                .section(MediaSectionKind::UNIT_INDEX)
                .unwrap()
                .bytes(),
            asset.unit_index()
        );
        let minimum = (0..8192)
            .find(|work| {
                image
                    .preflight(&PayloadLimits::EMBEDDED.with_max_raster_work(*work))
                    .is_ok()
            })
            .unwrap();
        let combined = minimum + payload.len() as u64;
        assert!(
            asset
                .preflight(&PayloadLimits::EMBEDDED.with_max_raster_work(combined - 1))
                .is_err()
        );
        asset
            .preflight(&PayloadLimits::EMBEDDED.with_max_raster_work(combined))
            .unwrap();
        let mut slots = [None];
        let groups = image
            .groups_into(&mut slots, &mut CoverageBudget::new(1024))
            .unwrap();
        for (ordinal, expected) in [&[1, 2][..], &[3, 3][..], &[4][..]].into_iter().enumerate() {
            let unit = groups.get(0).unwrap().get(ordinal).unwrap();
            assert_eq!(unit.data().len(), lengths[ordinal] as usize);
            let plan = unit.decode_plan(SurfaceRequirements::new()).unwrap();
            let mut output = [0; 2];
            assert_eq!(
                plan.decode_into(&mut output)
                    .unwrap()
                    .plane(0)
                    .unwrap()
                    .bytes(),
                expected
            );
        }
    }
}

#[test]
fn structural_errors_preserve_output_and_coverage_requires_bounded_admission() {
    let surface = SurfaceDescriptor::new(2, 1, SampleLayout::A8, ColorDescription::NONE).unwrap();
    let codings = [Rle::new().record()];
    let records = [UnitGroupRecord::new(0, 0..2).unwrap()];
    let valid = EncodedImageAsset::from_groups(surface, &codings, &records, &[0x81, 42]);
    let reference = [records[0].with_reference(ReferenceMode::Previous)];
    let missing_coding = [UnitGroupRecord::new(1, 0..2).unwrap()];
    let unreferenced = [UnitGroupRecord::new(0, 0..1).unwrap()];
    let mut output = [0xad; 512];
    for invalid in [
        EncodedImageAsset::from_groups(surface, &[], &records, &[0x81, 42]),
        EncodedImageAsset::from_groups(surface, &codings, &[], &[0x81, 42]),
        EncodedImageAsset::from_groups(surface, &codings, &reference, &[0x81, 42]),
        EncodedImageAsset::from_groups(surface, &codings, &missing_coding, &[0x81, 42]),
        EncodedImageAsset::from_groups(surface, &codings, &unreferenced, &[0x81, 42]),
        valid.with_input_alignment(crate::ByteAlignment::new(64).unwrap()),
        valid.with_unit_index(&[0]),
        EncodedImageAsset::new(surface, codings[0], &[0x81, 42]).with_unit_index(&[0]),
    ] {
        assert!(invalid.encode_into(&mut output).is_err());
        assert_eq!(output, [0xad; 512]);
    }
    assert!(crate::ByteAlignment::new(3).is_err());
    assert_eq!(
        valid
            .with_input_alignment(crate::ByteAlignment::new(64).unwrap())
            .encoded_len(),
        Err(ImageEncodeError::ConflictingAlignment)
    );
    let overlapping = [records[0], UnitGroupRecord::new(0, 2..4).unwrap()];
    let asset =
        EncodedImageAsset::from_groups(surface, &codings, &overlapping, &[0x81, 42, 0x81, 43]);
    let bytes = asset.encode().unwrap();
    assert!(matches!(
        asset.preflight(&PayloadLimits::EMBEDDED),
        Err(ImageEncodeError::Preflight(EncodedImageError::Coverage(_)))
    ));
    assert!(
        EncodedImageView::open(&bytes)
            .unwrap()
            .preflight(&PayloadLimits::EMBEDDED)
            .is_err()
    );
    let many_codings = [codings[0]; 32];
    let asset = EncodedImageAsset::from_groups(surface, &many_codings, &reference, &[0x81, 42]);
    // Resource gates must run before scanning even malformed native records.
    assert!(matches!(
        asset.preflight(&PayloadLimits::EMBEDDED.with_max_raster_groups(0)),
        Err(ImageEncodeError::Preflight(
            EncodedImageError::TooManyGroups { .. }
        ))
    ));
    assert_eq!(
        asset.preflight(&PayloadLimits::EMBEDDED.with_max_raster_work(255)),
        Err(ImageEncodeError::Preflight(EncodedImageError::Coverage(
            CoverageError::BudgetExceeded
        )))
    );
}