def test_completeness(
    tmpdir,
    extra_args,
    exp_encoder,
    exp_decoder,
    expected_files,
):
    with alternative_real_pictures():
        assert (
            main(
                [CODEC_FEATURES_CSV, "--output", str(tmpdir), "--codecs", "minimal"]
                + extra_args
            )
            == 0
        )

    generated_files = set(
        # Get relative paths within output dir
        os.path.abspath(os.path.join(root, filename))[
            len(os.path.abspath(str(tmpdir))) + 1 :
        ]
        for root, dirs, files in os.walk(str(tmpdir))
        for filename in files
    )

    if exp_encoder:
        assert expected_files[0].issubset(generated_files)
    else:
        assert expected_files[0].isdisjoint(generated_files)

    if exp_decoder:
        assert expected_files[1].issubset(generated_files)
    else:
        assert expected_files[1].isdisjoint(generated_files)
def test_real_pictures(codec_features):
    picture, video_parameters, picture_coding_mode = file_format.read(
        LOVELL_IMAGE_PATH, )

    codec_features["wavelet_index"] = WaveletFilters.le_gall_5_3
    codec_features["wavelet_index_ho"] = WaveletFilters.le_gall_5_3
    codec_features["dwt_depth"] = 2
    codec_features["dwt_depth_ho"] = 0

    codec_features["slices_x"] = 8
    codec_features["slices_y"] = 16
    codec_features["lossless"] = False
    codec_features["picture_bytes"] = (64 * 64 * 2) // 2  # ~2:1 compression

    codec_features["video_parameters"] = video_parameters

    with alternative_real_pictures([LOVELL_IMAGE_PATH]):
        stream = real_pictures(codec_features)

    coded_pictures = encode_and_decode(stream)

    assert len(coded_pictures) == 1
    coded_picture = coded_pictures[0]

    for component in ["Y", "C1", "C2"]:
        before = np.array(picture[component])
        after = np.array(coded_picture[component])

        # Coding should be lossy
        assert not np.array_equal(before, after)

        # PSNR should be reasonable
        error = after - before
        square_error = error * error
        mean_square_error = np.mean(square_error)
        max_value = 255.0
        peak_signal_to_noise_ratio = (20 * np.log(max_value) / np.log(10)) - (
            10 * np.log(mean_square_error) / np.log(10))

        # NB: This is a pretty low PSNR threshold but appropriate here since
        # we're encoding a very small (and, for its size, very detailed) image.
        assert peak_signal_to_noise_ratio > 45.0
def test_force(
    tmpdir,
    extra_args,
    exp_fail,
):
    with alternative_real_pictures():
        fn = partial(
            main,
            [CODEC_FEATURES_CSV, "--output", str(tmpdir), "--codecs", "minimal"]
            + extra_args,
        )

        # First time should always work
        fn()

        if exp_fail:
            with pytest.raises(SystemExit):
                fn()
        else:
            fn()
from vc2_conformance.codec_features import CodecFeatures

from vc2_conformance.pseudocode.video_parameters import VideoParameters

from vc2_conformance.test_cases import ENCODER_TEST_CASE_GENERATOR_REGISTRY

from vc2_conformance.dimensions_and_depths import compute_dimensions_and_depths

from vc2_data_tables import PictureCodingModes

from sample_codec_features import MINIMAL_CODEC_FEATURES
from smaller_real_pictures import alternative_real_pictures

# NB: Test case generators run during test collection so we must replace the
# pictures with smaller ones (for performance reasons) during tests
with alternative_real_pictures():
    ALL_TEST_CASES = [
        (
            codec_features,
            list(
                ENCODER_TEST_CASE_GENERATOR_REGISTRY.generate_test_cases(
                    codec_features, )),
        ) for codec_features in [
            # Both picture coding modes
            CodecFeatures(
                MINIMAL_CODEC_FEATURES,
                picture_coding_mode=PictureCodingModes.pictures_are_frames,
            ),
            CodecFeatures(
                MINIMAL_CODEC_FEATURES,
                picture_coding_mode=PictureCodingModes.pictures_are_fields,
def expected_files():
    """
    The (minimum) expected filenames which demonstrates all test cases were
    tried.
    """
    codec_feature_sets = {
        "minimal": MINIMAL_CODEC_FEATURES,
    }

    encoder_test_files = set()
    decoder_test_files = set()
    with alternative_real_pictures():
        for name, codec_features in codec_feature_sets.items():
            for test_case in ENCODER_TEST_CASE_GENERATOR_REGISTRY.generate_test_cases(
                codec_features
            ):
                encoder_test_files.add(
                    os.path.join(
                        name,
                        "encoder",
                        test_case.name,
                        "picture_0.raw",
                    )
                )
                if test_case.metadata is not None:
                    encoder_test_files.add(
                        os.path.join(
                            name,
                            "encoder",
                            "{}_metadata.json".format(test_case.name),
                        )
                    )

            for test_case in DECODER_TEST_CASE_GENERATOR_REGISTRY.generate_test_cases(
                codec_features
            ):
                decoder_test_files.add(
                    os.path.join(
                        name,
                        "decoder",
                        "{}.vc2".format(test_case.name),
                    )
                )
                decoder_test_files.add(
                    os.path.join(
                        name,
                        "decoder",
                        "{}_expected".format(test_case.name),
                        "picture_0.raw",
                    )
                )
                if test_case.metadata is not None:
                    decoder_test_files.add(
                        os.path.join(
                            name,
                            "decoder",
                            "{}_metadata.json".format(test_case.name),
                        )
                    )

        return (encoder_test_files, decoder_test_files)