// File: lukasz-wiecaszek[P]h264iframedecoder/picture.cpp
// Function: ymn::h264::picture::calculate_neighbours_part2()
void picture::calculate_neighbours_part2()
{
    mb* curr_mb = m_context_variables.curr_mb;
    int mb_width = m_decoder.m_dimensions.mb_width;

    static const int left_blocks[4][4] =
    {
        {0, 1, 2, 3},
        {2, 2, 3, 3},
        {0, 0, 1, 1},
        {0, 2, 0, 2}
    };

    static const int left_blocks_nzc[4][8] =
    {
        {3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4, 3 + 3 * 4, 1 + 4 * 4, 1 + 8 * 4, 1 + 5 * 4, 1 + 9 * 4},
        {3 + 2 * 4, 3 + 2 * 4, 3 + 3 * 4, 3 + 3 * 4, 1 + 5 * 4, 1 + 9 * 4, 1 + 5 * 4, 1 + 9 * 4},
        {3 + 0 * 4, 3 + 0 * 4, 3 + 1 * 4, 3 + 1 * 4, 1 + 4 * 4, 1 + 8 * 4, 1 + 4 * 4, 1 + 8 * 4},
        {3 + 0 * 4, 3 + 2 * 4, 3 + 0 * 4, 3 + 2 * 4, 1 + 4 * 4, 1 + 8 * 4, 1 + 4 * 4, 1 + 8 * 4}
    };

    if (m_context_variables.mb_aff_frame) {
        mb* mb_ax;
        mb* mb_bx;
        if (m_context_variables.mb_field_decoding_flag == 0) { /* currMbFrameFlag '1' */
            if ((curr_mb->y & 1) == 0) { /* mbIsTopMbFlag '1' */
                mb_ax = curr_mb->A;
                mb_bx = curr_mb->B;
                if (mb_ax) {
                    if (MB_IS_INTERLACED(mb_ax->type)) { /* current - frame(top), left - field */
                        curr_mb->left_pair[0] = mb_ax;
                        curr_mb->left_pair[1] = mb_ax;
                        m_context_variables.left_blocks = left_blocks[2];
                        m_context_variables.left_blocks_nzc = left_blocks_nzc[2];
                    }
                    else { /* current - frame(top), left - frame */
                        curr_mb->left_pair[0] = mb_ax;
                        curr_mb->left_pair[1] = mb_ax;
                        m_context_variables.left_blocks = left_blocks[0];
                        m_context_variables.left_blocks_nzc = left_blocks_nzc[0];
                    }
                }
                if (mb_bx)
                    curr_mb->top = mb_bx + mb_width;
            }
            else { /* mbIsTopMbFlag '0' */
                mb_ax = curr_mb->A;
                mb_bx = curr_mb;
                if (mb_ax) {
                    if (MB_IS_INTERLACED(mb_ax->type)) { /* current - frame(bottom), left - field */
                        curr_mb->left_pair[0] = mb_ax;
                        curr_mb->left_pair[1] = mb_ax;
                        m_context_variables.left_blocks = left_blocks[1];
                        m_context_variables.left_blocks_nzc = left_blocks_nzc[1];
                    }
                    else { /* current - frame(bottom), left - frame */
                        curr_mb->left_pair[0] = mb_ax + mb_width;
                        curr_mb->left_pair[1] = mb_ax + mb_width;
                        m_context_variables.left_blocks = left_blocks[0];
                        m_context_variables.left_blocks_nzc = left_blocks_nzc[0];
                    }
                }
                if (mb_bx)
                    curr_mb->top = mb_bx - mb_width;
            }
        }
        else { /* currMbFrameFlag '0' */
            if ((curr_mb->y & 1) == 0) { /* mbIsTopMbFlag '1' */
                mb_ax = curr_mb->A;
                mb_bx = curr_mb->B;
                if (mb_ax) {
                    if (MB_IS_INTERLACED(mb_ax->type)) { /* current - field(top), left - field */
                        curr_mb->left_pair[0] = mb_ax;
                        curr_mb->left_pair[1] = mb_ax;
                        m_context_variables.left_blocks = left_blocks[0];
                        m_context_variables.left_blocks_nzc = left_blocks_nzc[0];
                    }
                    else { /* current - field(top), left - frame */
                        curr_mb->left_pair[0] = mb_ax;
                        curr_mb->left_pair[1] = mb_ax + mb_width;
                        m_context_variables.left_blocks = left_blocks[3];
                        m_context_variables.left_blocks_nzc = left_blocks_nzc[3];
                    }
                }
                if (mb_bx) {
                    if (MB_IS_INTERLACED(mb_bx->type))
                        curr_mb->top = mb_bx;
                    else
                        curr_mb->top = mb_bx + mb_width;
                }
            }
            else { /* mbIsTopMbFlag '0' */
                mb_ax = curr_mb->A;
                mb_bx = curr_mb->B;
                if (mb_ax) {
                    if (MB_IS_INTERLACED(mb_ax->type)) { /* current - field(bottom), left - field */
                        curr_mb->left_pair[0] = mb_ax + mb_width;
                        curr_mb->left_pair[1] = mb_ax + mb_width;
                        m_context_variables.left_blocks = left_blocks[0];
                        m_context_variables.left_blocks_nzc = left_blocks_nzc[0];
                    }
                    else { /* current - field(bottom), left - frame */
                        curr_mb->left_pair[0] = mb_ax;
                        curr_mb->left_pair[1] = mb_ax + mb_width;
                        m_context_variables.left_blocks = left_blocks[3];
                        m_context_variables.left_blocks_nzc = left_blocks_nzc[3];
                    }
                }
                if (mb_bx)
                    curr_mb->top = mb_bx + mb_width;
            }
        }
        curr_mb->left = curr_mb->left_pair[0];
    }
    else {
        curr_mb->left = curr_mb->A;
        curr_mb->left_pair[0] = curr_mb->A;
        curr_mb->left_pair[1] = curr_mb->A;
        curr_mb->top = curr_mb->B;
        m_context_variables.left_blocks = left_blocks[0];
        m_context_variables.left_blocks_nzc = left_blocks_nzc[0];
    }
}

// Assembly:
movq %rdi, -0x8(%rsp)
movq -0x8(%rsp), %rax
movq %rax, -0x30(%rsp)
movq 0x28(%rax), %rcx
movq %rcx, -0x10(%rsp)
movq 0x8(%rax), %rcx
movl 0x88340(%rcx), %ecx
movl %ecx, -0x14(%rsp)
testb $0x1, 0x18(%rax)
je 0x1d75a
movq -0x30(%rsp), %rax
movb 0x19(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x1d517
movq -0x10(%rsp), %rax
movl 0x4(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x1d418
movq -0x10(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x20(%rsp)
movq -0x10(%rsp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x28(%rsp)
cmpq $0x0, -0x20(%rsp)
je 0x1d3ee
movq -0x20(%rsp), %rax
movl 0x10(%rax), %eax
andl $0x100, %eax            # imm = 0x100
cmpl $0x0, %eax
je 0x1d3b5
movq -0x30(%rsp), %rax
movq -0x20(%rsp), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x40(%rcx)
movq -0x20(%rsp), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x48(%rcx)
leaq 0xb044(%rip), %rcx      # 0x283e0
addq $0x20, %rcx
movq %rcx, 0x48(%rax)
leaq 0xb075(%rip), %rcx      # 0x28420
addq $0x40, %rcx
movq %rcx, 0x50(%rax)
jmp 0x1d3ec
movq -0x30(%rsp), %rax
movq -0x20(%rsp), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x40(%rcx)
movq -0x20(%rsp), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x48(%rcx)
leaq 0xb003(%rip), %rcx      # 0x283e0
movq %rcx, 0x48(%rax)
leaq 0xb038(%rip), %rcx      # 0x28420
movq %rcx, 0x50(%rax)
jmp 0x1d3ee
cmpq $0x0, -0x28(%rsp)
je 0x1d413
movq -0x28(%rsp), %rcx
movslq -0x14(%rsp), %rax
imulq $0xb0, %rax, %rax
addq %rax, %rcx
movq -0x10(%rsp), %rax
movq %rcx, 0x50(%rax)
jmp 0x1d512
movq -0x10(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x20(%rsp)
movq -0x10(%rsp), %rax
movq %rax, -0x28(%rsp)
cmpq $0x0, -0x20(%rsp)
je 0x1d4e6
movq -0x20(%rsp), %rax
movl 0x10(%rax), %eax
andl $0x100, %eax            # imm = 0x100
cmpl $0x0, %eax
je 0x1d48f
movq -0x30(%rsp), %rax
movq -0x20(%rsp), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x40(%rcx)
movq -0x20(%rsp), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x48(%rcx)
leaq 0xaf6a(%rip), %rcx      # 0x283e0
addq $0x10, %rcx
movq %rcx, 0x48(%rax)
leaq 0xaf9b(%rip), %rcx      # 0x28420
addq $0x20, %rcx
movq %rcx, 0x50(%rax)
jmp 0x1d4e4
movq -0x30(%rsp), %rax
movq -0x20(%rsp), %rdx
movslq -0x14(%rsp), %rcx
imulq $0xb0, %rcx, %rcx
addq %rcx, %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x40(%rcx)
movq -0x20(%rsp), %rdx
movslq -0x14(%rsp), %rcx
imulq $0xb0, %rcx, %rcx
addq %rcx, %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x48(%rcx)
leaq 0xaf0b(%rip), %rcx      # 0x283e0
movq %rcx, 0x48(%rax)
leaq 0xaf40(%rip), %rcx      # 0x28420
movq %rcx, 0x50(%rax)
jmp 0x1d4e6
cmpq $0x0, -0x28(%rsp)
je 0x1d510
movq -0x28(%rsp), %rcx
movslq -0x14(%rsp), %rdx
xorl %eax, %eax
subq %rdx, %rax
imulq $0xb0, %rax, %rax
addq %rax, %rcx
movq -0x10(%rsp), %rax
movq %rcx, 0x50(%rax)
jmp 0x1d512
jmp 0x1d746
movq -0x10(%rsp), %rax
movl 0x4(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x1d63c
movq -0x10(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x20(%rsp)
movq -0x10(%rsp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x28(%rsp)
cmpq $0x0, -0x20(%rsp)
je 0x1d5ee
movq -0x20(%rsp), %rax
movl 0x10(%rax), %eax
andl $0x100, %eax            # imm = 0x100
cmpl $0x0, %eax
je 0x1d59e
movq -0x30(%rsp), %rax
movq -0x20(%rsp), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x40(%rcx)
movq -0x20(%rsp), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x48(%rcx)
leaq 0xae53(%rip), %rcx      # 0x283e0
movq %rcx, 0x48(%rax)
leaq 0xae88(%rip), %rcx      # 0x28420
movq %rcx, 0x50(%rax)
jmp 0x1d5ec
movq -0x30(%rsp), %rax
movq -0x20(%rsp), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x40(%rcx)
movq -0x20(%rsp), %rdx
movslq -0x14(%rsp), %rcx
imulq $0xb0, %rcx, %rcx
addq %rcx, %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x48(%rcx)
leaq 0xae0b(%rip), %rcx      # 0x283e0
addq $0x30, %rcx
movq %rcx, 0x48(%rax)
leaq 0xae3c(%rip), %rcx      # 0x28420
addq $0x60, %rcx
movq %rcx, 0x50(%rax)
jmp 0x1d5ee
cmpq $0x0, -0x28(%rsp)
je 0x1d637
movq -0x28(%rsp), %rax
movl 0x10(%rax), %eax
andl $0x100, %eax            # imm = 0x100
cmpl $0x0, %eax
je 0x1d618
movq -0x28(%rsp), %rcx
movq -0x10(%rsp), %rax
movq %rcx, 0x50(%rax)
jmp 0x1d635
movq -0x28(%rsp), %rcx
movslq -0x14(%rsp), %rax
imulq $0xb0, %rax, %rax
addq %rax, %rcx
movq -0x10(%rsp), %rax
movq %rcx, 0x50(%rax)
jmp 0x1d637
jmp 0x1d744
movq -0x10(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x20(%rsp)
movq -0x10(%rsp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x28(%rsp)
cmpq $0x0, -0x20(%rsp)
je 0x1d71d
movq -0x20(%rsp), %rax
movl 0x10(%rax), %eax
andl $0x100, %eax            # imm = 0x100
cmpl $0x0, %eax
je 0x1d6cd
movq -0x30(%rsp), %rax
movq -0x20(%rsp), %rdx
movslq -0x14(%rsp), %rcx
imulq $0xb0, %rcx, %rcx
addq %rcx, %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x40(%rcx)
movq -0x20(%rsp), %rdx
movslq -0x14(%rsp), %rcx
imulq $0xb0, %rcx, %rcx
addq %rcx, %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x48(%rcx)
leaq 0xad24(%rip), %rcx      # 0x283e0
movq %rcx, 0x48(%rax)
leaq 0xad59(%rip), %rcx      # 0x28420
movq %rcx, 0x50(%rax)
jmp 0x1d71b
movq -0x30(%rsp), %rax
movq -0x20(%rsp), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x40(%rcx)
movq -0x20(%rsp), %rdx
movslq -0x14(%rsp), %rcx
imulq $0xb0, %rcx, %rcx
addq %rcx, %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x48(%rcx)
leaq 0xacdc(%rip), %rcx      # 0x283e0
addq $0x30, %rcx
movq %rcx, 0x48(%rax)
leaq 0xad0d(%rip), %rcx      # 0x28420
addq $0x60, %rcx
movq %rcx, 0x50(%rax)
jmp 0x1d71d
cmpq $0x0, -0x28(%rsp)
je 0x1d742
movq -0x28(%rsp), %rcx
movslq -0x14(%rsp), %rax
imulq $0xb0, %rax, %rax
addq %rax, %rcx
movq -0x10(%rsp), %rax
movq %rcx, 0x50(%rax)
jmp 0x1d744
jmp 0x1d746
movq -0x10(%rsp), %rax
movq 0x40(%rax), %rcx
movq -0x10(%rsp), %rax
movq %rcx, 0x38(%rax)
jmp 0x1d7bd
movq -0x30(%rsp), %rax
movq -0x10(%rsp), %rcx
movq 0x18(%rcx), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x38(%rcx)
movq -0x10(%rsp), %rcx
movq 0x18(%rcx), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x40(%rcx)
movq -0x10(%rsp), %rcx
movq 0x18(%rcx), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x48(%rcx)
movq -0x10(%rsp), %rcx
movq 0x20(%rcx), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x50(%rcx)
leaq 0xac32(%rip), %rcx      # 0x283e0
movq %rcx, 0x48(%rax)
leaq 0xac67(%rip), %rcx      # 0x28420
movq %rcx, 0x50(%rax)
retq
nop