// File: devernay[P]vlpovutils/occlusionmap.cpp
// Function: vlpov_occlusionmap_opticalflow(VLPovImage<double> const&, VLPovImage<double> const&, VLPovImage<double> const&, VLPovImage<double> const&, double, VLPovImage<unsigned char>&)
void vlpov_occlusionmap_opticalflow(const VLPovImage<double> &m1x, const VLPovImage<double> &m1y,
                                    const VLPovImage<double> &m2x, const VLPovImage<double> &m2y,
                                    double t,
                                    VLPovImage<unsigned char> &occ1)
{
    assert(m1x.width() == m1y.width() && m1x.height() == m1y.height());
    assert(m2x.width() == m2y.width() && m2x.height() == m2y.height());
    
    int width1 = m1x.width();
    int height1 = m1x.height();
    int width2 = m2x.width();
    int height2 = m2x.height();

    occ1.resize(width1, height1);
    
    for(int y1 = 0; y1 < height1; ++y1) {
        for(int x1 = 0; x1 < width1; ++x1) {
            double x2 = x1 + m1x(x1,y1);
            double y2 = y1 + m1y(x1,y1);
            
            // check for visibility
            if (x2 < -0.5 || x2 > width2-0.5 ||
                y2 < -0.5 || y2 > height2-0.5) {
                occ1(x1,y1) = 0;
                continue;
            }
            
            double x1b = x2 + m2x.linear_at(x2,y2);
            double y1b = y2 + m2y.linear_at(x2,y2);
            // check for occlusion
            if (std::abs(x1 - x1b) > t ||
                std::abs(y1 - y1b) > t) {
                occ1(x1,y1) = 0;
                continue;
            }
            
            // point is visible
            occ1(x1,y1) = 255;
        }
    }
    
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movsd %xmm0, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq -0x8(%rbp), %rdi
callq 0x6b10
movl %eax, -0x70(%rbp)
movq -0x10(%rbp), %rdi
callq 0x6b10
movl -0x70(%rbp), %ecx
movl %eax, %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x69(%rbp)
jne 0x9b09
movq -0x8(%rbp), %rdi
callq 0x6b20
movl %eax, -0x74(%rbp)
movq -0x10(%rbp), %rdi
callq 0x6b20
movl %eax, %ecx
movl -0x74(%rbp), %eax
cmpl %ecx, %eax
sete %al
movb %al, -0x69(%rbp)
movb -0x69(%rbp), %al
testb $0x1, %al
jne 0x9b12
jmp 0x9b14
jmp 0x9b33
leaq 0x8c75(%rip), %rdi      # 0x12790
leaq 0x8ca9(%rip), %rsi      # 0x127cb
movl $0x22, %edx
leaq 0x8cae(%rip), %rcx      # 0x127dc
callq 0x3140
movq -0x18(%rbp), %rdi
callq 0x6b10
movl %eax, -0x7c(%rbp)
movq -0x20(%rbp), %rdi
callq 0x6b10
movl -0x7c(%rbp), %ecx
movl %eax, %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x75(%rbp)
jne 0x9b78
movq -0x18(%rbp), %rdi
callq 0x6b20
movl %eax, -0x80(%rbp)
movq -0x20(%rbp), %rdi
callq 0x6b20
movl %eax, %ecx
movl -0x80(%rbp), %eax
cmpl %ecx, %eax
sete %al
movb %al, -0x75(%rbp)
movb -0x75(%rbp), %al
testb $0x1, %al
jne 0x9b81
jmp 0x9b83
jmp 0x9ba2
leaq 0x8d0b(%rip), %rdi      # 0x12895
leaq 0x8c3a(%rip), %rsi      # 0x127cb
movl $0x23, %edx
leaq 0x8c3f(%rip), %rcx      # 0x127dc
callq 0x3140
movq -0x8(%rbp), %rdi
callq 0x6b10
movl %eax, -0x34(%rbp)
movq -0x8(%rbp), %rdi
callq 0x6b20
movl %eax, -0x38(%rbp)
movq -0x18(%rbp), %rdi
callq 0x6b10
movl %eax, -0x3c(%rbp)
movq -0x18(%rbp), %rdi
callq 0x6b20
movl %eax, -0x40(%rbp)
movq -0x30(%rbp), %rdi
movl -0x34(%rbp), %esi
movl -0x38(%rbp), %edx
callq 0x9f60
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl -0x38(%rbp), %eax
jge 0x9da6
movl $0x0, -0x48(%rbp)
movl -0x48(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0x9d96
cvtsi2sdl -0x48(%rbp), %xmm0
movsd %xmm0, -0x90(%rbp)
movq -0x8(%rbp), %rdi
movl -0x48(%rbp), %esi
movl -0x44(%rbp), %edx
callq 0x7860
movsd -0x90(%rbp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, -0x50(%rbp)
cvtsi2sdl -0x44(%rbp), %xmm0
movsd %xmm0, -0x88(%rbp)
movq -0x10(%rbp), %rdi
movl -0x48(%rbp), %esi
movl -0x44(%rbp), %edx
callq 0x7860
movsd -0x88(%rbp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, -0x58(%rbp)
movsd 0x8aff(%rip), %xmm0     # 0x12768
ucomisd -0x50(%rbp), %xmm0
ja 0x9cb7
movsd -0x50(%rbp), %xmm0
cvtsi2sdl -0x3c(%rbp), %xmm1
movsd 0x8aee(%rip), %xmm2     # 0x12770
subsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
ja 0x9cb7
movsd 0x8ad4(%rip), %xmm0     # 0x12768
ucomisd -0x58(%rbp), %xmm0
ja 0x9cb7
movsd -0x58(%rbp), %xmm0
cvtsi2sdl -0x40(%rbp), %xmm1
movsd 0x8ac3(%rip), %xmm2     # 0x12770
subsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x9cce
movq -0x30(%rbp), %rdi
movl -0x48(%rbp), %esi
movl -0x44(%rbp), %edx
callq 0x9ff0
movb $0x0, (%rax)
jmp 0x9d88
movsd -0x50(%rbp), %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x18(%rbp), %rdi
movsd -0x50(%rbp), %xmm0
movsd -0x58(%rbp), %xmm1
callq 0xa020
movaps %xmm0, %xmm1
movsd -0xa0(%rbp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x60(%rbp)
movsd -0x58(%rbp), %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x20(%rbp), %rdi
movsd -0x50(%rbp), %xmm0
movsd -0x58(%rbp), %xmm1
callq 0xa020
movaps %xmm0, %xmm1
movsd -0x98(%rbp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x68(%rbp)
cvtsi2sdl -0x48(%rbp), %xmm0
subsd -0x60(%rbp), %xmm0
callq 0xa270
ucomisd -0x28(%rbp), %xmm0
ja 0x9d62
cvtsi2sdl -0x44(%rbp), %xmm0
subsd -0x68(%rbp), %xmm0
callq 0xa270
ucomisd -0x28(%rbp), %xmm0
jbe 0x9d76
movq -0x30(%rbp), %rdi
movl -0x48(%rbp), %esi
movl -0x44(%rbp), %edx
callq 0x9ff0
movb $0x0, (%rax)
jmp 0x9d88
movq -0x30(%rbp), %rdi
movl -0x48(%rbp), %esi
movl -0x44(%rbp), %edx
callq 0x9ff0
movb $-0x1, (%rax)
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x9bfb
jmp 0x9d98
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x9be8
addq $0xa0, %rsp
popq %rbp
retq
nop