import config, math, image

static def split(V *v, int n):
    """
    Split in-place into even values followed by odd values.
    """
    # recursive split&merge
    # In each iteration, a recursion on both halves is done. After that (n / 4)
    # swaps are performed.
    # total we get: (n/4) + 2 * (n/8) + 4 * (n/16)... = (n/4) * log2(n/2)
    # 4: 1 * 2 = 2
    # 8: 2 * 2 = 4
    # 16: 4 * 3 = 12
    # 32: 8 * 4 = 32
    #
    #    a<A b>B c<C d>D e<E f>F g<G h>H
    # 1. a b<A B c d>C D e f<E F g h>G H
    # 2. a b c d<A B C D e f g h>E F G H
    # 3. a b c d e f g h A B C D E F G H
    if n > 2:
        split(v, n / 2)
        split(v + n / 2, n / 2)
        for int i = 0; i < n / 4; i++:
            V temp = v[n / 4 + i]
            v[n / 4 + i] = v[n / 2 + i]
            v[n / 2 + i] = temp

static def predict(V *v, int n):
    """
    Handle high pass.
    """
    for int i = 0; i < n / 2; i++:
        v[n / 2 + i] -= v[i]

static def update(V *v, int n):
    """
    Handle low pass.
    """
    for int i = 0; i < n / 2; i++:
        v[i] += v[n / 2 + i] / 2

static def transform_row_in_place(V *v, int w):
    split(v, w)
    predict(v, w)
    update(v, w)

V *def haar_lifting(V *image, int w, h):
    V *result = duplicate_image(image, w, h)

    for int k= 0; k < 4; k++:
        int s = 1 << k
        
        for int j = 0; j < h / s; j++:
            transform_row_in_place(result + j * w, w / s)

    return result