// File: lucaong[P]elixir_mlx90640/src/MLX90640_API.cpp
// Function: ExtractDeviatingPixels(unsigned short*, paramsMLX90640*)
int ExtractDeviatingPixels(uint16_t *eeData, paramsMLX90640 *mlx90640)
{
    uint16_t pixCnt = 0;
    uint16_t brokenPixCnt = 0;
    uint16_t outlierPixCnt = 0;
    int warn = 0;
    int i;
    
    for(pixCnt = 0; pixCnt<5; pixCnt++)
    {
        mlx90640->brokenPixels[pixCnt] = 0xFFFF;
        mlx90640->outlierPixels[pixCnt] = 0xFFFF;
    }
        
    pixCnt = 0;    
    while (pixCnt < 768 && brokenPixCnt < 5 && outlierPixCnt < 5)
    {
        if(eeData[pixCnt+64] == 0)
        {
            mlx90640->brokenPixels[brokenPixCnt] = pixCnt;
            brokenPixCnt = brokenPixCnt + 1;
        }    
        else if((eeData[pixCnt+64] & 0x0001) != 0)
        {
            mlx90640->outlierPixels[outlierPixCnt] = pixCnt;
            outlierPixCnt = outlierPixCnt + 1;
        }    
        
        pixCnt = pixCnt + 1;
        
    } 
    
    if(brokenPixCnt > 4)  
    {
        warn = -3;
    }         
    else if(outlierPixCnt > 4)  
    {
        warn = -4;
    }
    else if((brokenPixCnt + outlierPixCnt) > 4)  
    {
        warn = -5;
    } 
    else
    {
        for(pixCnt=0; pixCnt<brokenPixCnt; pixCnt++)
        {
            for(i=pixCnt+1; i<brokenPixCnt; i++)
            {
                warn = CheckAdjacentPixels(mlx90640->brokenPixels[pixCnt],mlx90640->brokenPixels[i]);
                if(warn != 0)
                {
                    return warn;
                }    
            }    
        }
        
        for(pixCnt=0; pixCnt<outlierPixCnt; pixCnt++)
        {
            for(i=pixCnt+1; i<outlierPixCnt; i++)
            {
                warn = CheckAdjacentPixels(mlx90640->outlierPixels[pixCnt],mlx90640->outlierPixels[i]);
                if(warn != 0)
                {
                    return warn;
                }    
            }    
        } 
        
        for(pixCnt=0; pixCnt<brokenPixCnt; pixCnt++)
        {
            for(i=0; i<outlierPixCnt; i++)
            {
                warn = CheckAdjacentPixels(mlx90640->brokenPixels[pixCnt],mlx90640->outlierPixels[i]);
                if(warn != 0)
                {
                    return warn;
                }    
            }    
        }    
        
    }    
    
    
    return warn;
       
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movw $0x0, -0x1a(%rbp)
movw $0x0, -0x1c(%rbp)
movw $0x0, -0x1e(%rbp)
movl $0x0, -0x24(%rbp)
movw $0x0, -0x1a(%rbp)
movzwl -0x1a(%rbp), %eax
cmpl $0x5, %eax
jge 0x380a
movq -0x18(%rbp), %rax
movzwl -0x1a(%rbp), %ecx
movw $0xffff, 0x2a5c(%rax,%rcx,2) # imm = 0xFFFF
movq -0x18(%rbp), %rax
movzwl -0x1a(%rbp), %ecx
movw $0xffff, 0x2a66(%rax,%rcx,2) # imm = 0xFFFF
movw -0x1a(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x1a(%rbp)
jmp 0x37cf
movw $0x0, -0x1a(%rbp)
movzwl -0x1a(%rbp), %ecx
xorl %eax, %eax
cmpl $0x300, %ecx            # imm = 0x300
movb %al, -0x29(%rbp)
jge 0x383c
movzwl -0x1c(%rbp), %ecx
xorl %eax, %eax
cmpl $0x5, %ecx
movb %al, -0x29(%rbp)
jge 0x383c
movzwl -0x1e(%rbp), %eax
cmpl $0x5, %eax
setl %al
movb %al, -0x29(%rbp)
movb -0x29(%rbp), %al
testb $0x1, %al
jne 0x3848
jmp 0x38cb
movq -0x10(%rbp), %rax
movzwl -0x1a(%rbp), %ecx
addl $0x40, %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
cmpl $0x0, %eax
jne 0x3880
movw -0x1a(%rbp), %dx
movq -0x18(%rbp), %rax
movzwl -0x1c(%rbp), %ecx
movw %dx, 0x2a5c(%rax,%rcx,2)
movzwl -0x1c(%rbp), %eax
addl $0x1, %eax
movw %ax, -0x1c(%rbp)
jmp 0x38bb
movq -0x10(%rbp), %rax
movzwl -0x1a(%rbp), %ecx
addl $0x40, %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x38b9
movw -0x1a(%rbp), %dx
movq -0x18(%rbp), %rax
movzwl -0x1e(%rbp), %ecx
movw %dx, 0x2a66(%rax,%rcx,2)
movzwl -0x1e(%rbp), %eax
addl $0x1, %eax
movw %ax, -0x1e(%rbp)
jmp 0x38bb
movzwl -0x1a(%rbp), %eax
addl $0x1, %eax
movw %ax, -0x1a(%rbp)
jmp 0x3810
movzwl -0x1c(%rbp), %eax
cmpl $0x4, %eax
jle 0x38e0
movl $0xfffffffd, -0x24(%rbp) # imm = 0xFFFFFFFD
jmp 0x3a90
movzwl -0x1e(%rbp), %eax
cmpl $0x4, %eax
jle 0x38f5
movl $0xfffffffc, -0x24(%rbp) # imm = 0xFFFFFFFC
jmp 0x3a8e
movzwl -0x1c(%rbp), %eax
movzwl -0x1e(%rbp), %ecx
addl %ecx, %eax
cmpl $0x4, %eax
jle 0x3910
movl $0xfffffffb, -0x24(%rbp) # imm = 0xFFFFFFFB
jmp 0x3a8c
movw $0x0, -0x1a(%rbp)
movzwl -0x1a(%rbp), %eax
movzwl -0x1c(%rbp), %ecx
cmpl %ecx, %eax
jge 0x3990
movzwl -0x1a(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %eax
movzwl -0x1c(%rbp), %ecx
cmpl %ecx, %eax
jge 0x3980
movq -0x18(%rbp), %rax
movzwl -0x1a(%rbp), %ecx
movw 0x2a5c(%rax,%rcx,2), %dx
movq -0x18(%rbp), %rax
movslq -0x28(%rbp), %rcx
movzwl %dx, %edi
movzwl 0x2a5c(%rax,%rcx,2), %esi
callq 0x5840
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
je 0x3973
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x3a96
jmp 0x3975
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x392c
jmp 0x3982
movw -0x1a(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x1a(%rbp)
jmp 0x3916
movw $0x0, -0x1a(%rbp)
movzwl -0x1a(%rbp), %eax
movzwl -0x1e(%rbp), %ecx
cmpl %ecx, %eax
jge 0x3a10
movzwl -0x1a(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %eax
movzwl -0x1e(%rbp), %ecx
cmpl %ecx, %eax
jge 0x3a00
movq -0x18(%rbp), %rax
movzwl -0x1a(%rbp), %ecx
movw 0x2a66(%rax,%rcx,2), %dx
movq -0x18(%rbp), %rax
movslq -0x28(%rbp), %rcx
movzwl %dx, %edi
movzwl 0x2a66(%rax,%rcx,2), %esi
callq 0x5840
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
je 0x39f3
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x3a96
jmp 0x39f5
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x39ac
jmp 0x3a02
movw -0x1a(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x1a(%rbp)
jmp 0x3996
movw $0x0, -0x1a(%rbp)
movzwl -0x1a(%rbp), %eax
movzwl -0x1c(%rbp), %ecx
cmpl %ecx, %eax
jge 0x3a8a
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
movzwl -0x1e(%rbp), %ecx
cmpl %ecx, %eax
jge 0x3a7a
movq -0x18(%rbp), %rax
movzwl -0x1a(%rbp), %ecx
movw 0x2a5c(%rax,%rcx,2), %dx
movq -0x18(%rbp), %rax
movslq -0x28(%rbp), %rcx
movzwl %dx, %edi
movzwl 0x2a66(%rax,%rcx,2), %esi
callq 0x5840
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
je 0x3a6d
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x3a96
jmp 0x3a6f
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x3a29
jmp 0x3a7c
movw -0x1a(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x1a(%rbp)
jmp 0x3a16
jmp 0x3a8c
jmp 0x3a8e
jmp 0x3a90
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq
nop