Beispiel #1
0
    def test_interleave(self):
        a = SymbolArray(2, "a")
        b = SymbolArray(2, "b")

        # 'Horizontal'
        i = InterleavedArray(a, b, 0)
        assert i[-2, 0] == ("a", -1, 0)
        assert i[-1, 0] == ("b", -1, 0)
        assert i[0, 0] == ("a", 0, 0)
        assert i[1, 0] == ("b", 0, 0)
        assert i[2, 0] == ("a", 1, 0)
        assert i[3, 0] == ("b", 1, 0)

        assert i[0, 1] == ("a", 0, 1)
        assert i[1, 1] == ("b", 0, 1)
        assert i[2, 1] == ("a", 1, 1)
        assert i[3, 1] == ("b", 1, 1)

        # 'Vertical'
        i = InterleavedArray(a, b, 1)
        assert i[0, -2] == ("a", 0, -1)
        assert i[0, -1] == ("b", 0, -1)
        assert i[0, 0] == ("a", 0, 0)
        assert i[0, 1] == ("b", 0, 0)
        assert i[0, 2] == ("a", 0, 1)
        assert i[0, 3] == ("b", 0, 1)

        assert i[1, 0] == ("a", 1, 0)
        assert i[1, 1] == ("b", 1, 0)
        assert i[1, 2] == ("a", 1, 1)
        assert i[1, 3] == ("b", 1, 1)
Beispiel #2
0
    def test_period_one_complex(self):
        #       A  A  A       B  B  B
        #   a = A  A  A   b = B  B  B
        #       A  A  A       B  B  B
        a = SymbolArray(2, "A")
        b = SymbolArray(2, "B")

        #        A  B  A
        #   ab = A  B  A
        #        A  B  A
        ab = InterleavedArray(a, b, 0)

        #         A*2  B*2  A*2
        #   ab2 = A*2  B*2  A*2
        #         A*2  B*2  A*2
        ab2 = LeftShiftedArray(ab, 1)

        #        B*2  B*2  B*2
        #   b2 = B*2  B*2  B*2
        #        B*2  B*2  B*2
        b2 = SubsampledArray(ab2, (2, 1), (1, 0))

        spca = SymbolicPeriodicCachingArray(b2, a, b)

        model_answers = {(x, y): b2[x, y] for x in range(3) for y in range(3)}
        ab2._cache.clear()

        # Should produce equivalent results to wrapped array
        for (x, y), exp_answer in model_answers.items():
            assert spca[x, y] == exp_answer

        # Shouldn't have requested anything but the 0th phase of the wrapped
        # array
        assert list(ab2._cache) == [(1, 0)]
Beispiel #3
0
    def test_period_n(self):
        #       A  A  A       B  B  B       C  C  C       D  D  D
        #   a = A  A  A   b = B  B  B   c = C  C  C   d = D  D  D
        #       A  A  A       B  B  B       C  C  C       D  D  D
        a = SymbolArray(2, "A")
        b = SymbolArray(2, "B")
        c = SymbolArray(2, "C")
        d = SymbolArray(2, "D")

        #        A  B  A  B
        #   ab = A  B  A  B
        #        A  B  A  B
        ab = InterleavedArray(a, b, 0)

        #         A  C  B  C  A  C
        #   abc = A  C  B  C  A  C
        #         A  C  B  C  A  C
        abc = InterleavedArray(ab, c, 0)

        #          A  B  C  A  B  C
        #   abcd = D  D  D  D  D  D
        #          A  B  C  A  B  C
        abcd = InterleavedArray(abc, d, 1)

        #           A*2  B*2  C*2  A*2  B*2  C*2
        #   abcd2 = D*2  D*2  D*2  D*2  D*2  D*2
        #           A*2  B*2  C*2  A*2  B*2  C*2
        abcd2 = LeftShiftedArray(abcd, 1)

        spca = SymbolicPeriodicCachingArray(abcd2, a, b, c, d)

        model_answers = {(x, y): abcd2[x, y]
                         for x in range(10) for y in range(10)}
        abcd2._cache.clear()

        # Should produce equivalent results to wrapped array
        for (x, y), exp_answer in model_answers.items():
            assert spca[x, y] == exp_answer

        # Shouldn't have requested anything but the 0th phase of the wrapped
        # array
        assert set(abcd2._cache) == set([(x, y) for x in range(4)
                                         for y in range(2)])
Beispiel #4
0
    def test_relative_step_size_to(self):
        a1 = SymbolArray(2, "a1")
        a2 = SymbolArray(2, "a2")
        i1 = InterleavedArray(a1, a2, 0)
        assert i1.relative_step_size_to(a1) == (0.5, 1)
        assert i1.relative_step_size_to(a2) == (0.5, 1)
        assert i1.relative_step_size_to(i1) == (1, 1)

        # Other dimensions work
        a3 = SymbolArray(2, "a3")
        a4 = SymbolArray(2, "a4")
        i2 = InterleavedArray(a3, a4, 1)
        assert i2.relative_step_size_to(a3) == (1, 0.5)
        assert i2.relative_step_size_to(a4) == (1, 0.5)
        assert i2.relative_step_size_to(i2) == (1, 1)

        # Non-matching arrays work
        assert i2.relative_step_size_to(i1) is None

        # Deep nesting
        i3 = InterleavedArray(i1, i2, 0)
        assert i3.relative_step_size_to(a1) == (0.25, 1)
        assert i3.relative_step_size_to(a2) == (0.25, 1)
        assert i3.relative_step_size_to(a3) == (0.5, 0.5)
        assert i3.relative_step_size_to(a4) == (0.5, 0.5)
        assert i3.relative_step_size_to(i1) == (0.5, 1)
        assert i3.relative_step_size_to(i2) == (0.5, 1)
        assert i3.relative_step_size_to(i3) == (1, 1)

        # Check partial support when the same values appear on both sides of an
        # interleaving
        i4 = InterleavedArray(i1, a1, 1)
        assert i4.relative_step_size_to(SymbolArray(2, "nope")) is None
        assert i4.relative_step_size_to(i4) == (1, 1)
        assert i4.relative_step_size_to(i1) == (1, 0.5)
        assert i4.relative_step_size_to(a2) == (0.5, 0.5)
        with pytest.raises(ValueError):
            i4.relative_step_size_to(a1)
Beispiel #5
0
 def test_period(self, input_a_period, input_b_period, dim, exp_period):
     a = RepeatingSymbolArray(input_a_period, "a")
     b = RepeatingSymbolArray(input_b_period, "b")
     i = InterleavedArray(a, b, dim)
     assert i.period == exp_period
     assert period_empirically_correct(i)
Beispiel #6
0
    def test_interleave_dimension_out_of_range(self):
        a = SymbolArray(2, "a")
        b = SymbolArray(2, "b")

        with pytest.raises(TypeError):
            InterleavedArray(a, b, 2)
Beispiel #7
0
 def test_nop(self):
     a = SymbolArray(2, "a")
     b = SymbolArray(2, "b")
     i = InterleavedArray(a, b, 1)
     assert i.nop is True
Beispiel #8
0
    def test_mismatched_array_dimensions(self):
        a = SymbolArray(2, "a")
        b = SymbolArray(3, "b")

        with pytest.raises(TypeError):
            InterleavedArray(a, b, 0)
Beispiel #9
0
def synthesis_transform(h_filter_params, v_filter_params, dwt_depth,
                        dwt_depth_ho, coeff_arrays):
    """
    Perform a multi-level VC-2 synthesis Inverse Discrete Wavelet Transform
    (IDWT) on a :py:class:`InfiniteArray` in a manner equivalent to the 'idwt'
    pseudocode function in (15.4.1) of the VC-2 standard.
    
    Parameters
    ==========
    h_filter_params, v_filter_params : :py:class:`vc2_data_tables.LiftingFilterParameters`
        Horizontal and vertical filter synthesis filter parameters (e.g. from
        :py:data:`vc2_data_tables.LIFTING_FILTERS`).
    dwt_depth, dwt_depth_ho: int
        Transform depths for 2D and horizontal-only transforms.
    coeff_arrays : {level: {orientation: :py:class:`InfiniteArray`, ...}, ...}
        The transform coefficient arrays to be used for synthesis. These nested
        dictionaries are indexed the same way as 'coeff_data' in the idwt
        pseudocode function in (15.4.1) in the VC-2 specification. See
        :py:func:`make_symbol_coeff_arrays` and
        :py:func:`make_variable_coeff_arrays`.
    
    Returns
    =======
    array : :py:class:`InfiniteArray`
        The final output array (i.e. decoded picture).
    intermediate_arrays : {(level, array_name): :py:class:`InfiniteArray`, ...}
        All intermediate (and output) value arrays, named according to the
        convention described in :ref:`terminology`.
        
        This value is returned as an :py:class:`~collections.OrderedDict`
        giving the arrays in their order of creation; a sensible order for
        display purposes.
    """
    intermediate_arrays = OrderedDict()

    if dwt_depth_ho > 0:
        output = coeff_arrays[0]["L"]
    else:
        output = coeff_arrays[0]["LL"]

    for level in range(1, dwt_depth_ho + dwt_depth + 1):
        if level > dwt_depth_ho:
            ll = intermediate_arrays[(level, "LL")] = output
            lh = intermediate_arrays[(level, "LH")] = coeff_arrays[level]["LH"]
            hl = intermediate_arrays[(level, "HL")] = coeff_arrays[level]["HL"]
            hh = intermediate_arrays[(level, "HH")] = coeff_arrays[level]["HH"]

            # Vertical interleave
            name = "L{}".format("'" * len(v_filter_params.stages))
            l = intermediate_arrays[(level,
                                     name)] = InterleavedArray(ll, lh, 1)
            name = "H{}".format("'" * len(v_filter_params.stages))
            h = intermediate_arrays[(level,
                                     name)] = InterleavedArray(hl, hh, 1)

            # Vertical lifting stages
            for num, stage in enumerate(v_filter_params.stages):
                name = "L{}".format("'" *
                                    (len(v_filter_params.stages) - num - 1))
                l = intermediate_arrays[(level,
                                         name)] = LiftedArray(l, stage, 1)
                name = "H{}".format("'" *
                                    (len(v_filter_params.stages) - num - 1))
                h = intermediate_arrays[(level,
                                         name)] = LiftedArray(h, stage, 1)
        else:
            l = intermediate_arrays[(level, "L")] = output
            h = intermediate_arrays[(level, "H")] = coeff_arrays[level]["H"]

        # Horizontal interleave
        name = "DC{}".format("'" * len(h_filter_params.stages))
        dc = intermediate_arrays[(level, name)] = InterleavedArray(l, h, 0)

        # Horizontal lifting stages
        for num, stage in enumerate(h_filter_params.stages):
            name = "DC{}".format("'" * (len(h_filter_params.stages) - num - 1))
            dc = intermediate_arrays[(level, name)] = LiftedArray(dc, stage, 0)

        # Bit shift
        output = intermediate_arrays[(level, "Output")] = RightShiftedArray(
            dc,
            h_filter_params.filter_bit_shift,
        )

    return output, intermediate_arrays