// File: iibrahimli[P]adsa_project/src/../include/util.hpp
// Function: calc_psf(BMP_image const&, BMP_image const&, int*, unsigned int)
std::vector<float> calc_psf(const BMP_image& img1, const BMP_image& img2, int* maxshift, unsigned int th /* = 100 */){
    int n_strips = (int) ceil((float) img1.info_h.height / th);
    std::vector<int> sh;
    std::vector<float> psf;
    sh.reserve(n_strips);
    psf.reserve(n_strips);
    unsigned int w = img1.info_h.width;
    unsigned int h = img1.info_h.height;
    int max_shift = 0;

    for(int i=0; i<n_strips; ++i){
        auto corr = x_correlate(img1, {0, i*th}, {w-1, std::min((i+1)*th-1, h-1)}, img2, {0, i*th}, {w-1, std::min((i+1)*th-1, h-1)});
        sh.push_back(corr.first);
        if(corr.first > max_shift) max_shift = corr.first;
        // std::cout << std::setw(4) << i*th << " - " << std::setw(4) << min((i+1)*th-1, h-1) << " : " << corr.first << ", " << corr.second << endl;
    }

    *maxshift = max_shift;

    for(const int& s : sh) psf.push_back((float) max_shift/s);

    // handle +- inf or nan values
    for(int i=0; i<psf.size(); ++i) if(std::isinf(psf[i]) || std::isnan(psf[i])) psf[i] = (i == 0) ? 0 : psf[i-1];

    return psf;
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x48(%rsp)
movq %rdi, %rax
movq %rax, 0x40(%rsp)
movq %rdi, 0x130(%rsp)
movq %rsi, 0x128(%rsp)
movq %rdx, 0x120(%rsp)
movq %rcx, 0x118(%rsp)
movl %r8d, 0x114(%rsp)
movq 0x128(%rsp), %rax
cvtsi2ssl 0x16(%rax), %xmm0
movl 0x114(%rsp), %eax
cvtsi2ss %rax, %xmm1
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
callq 0x3070
cvttsd2si %xmm0, %eax
movl %eax, 0x110(%rsp)
leaq 0xf8(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0x7a10
movq 0x48(%rsp), %rdi
movb $0x0, 0xf7(%rsp)
callq 0x7a20
movq 0x50(%rsp), %rdi
movslq 0x110(%rsp), %rsi
callq 0x7a30
jmp 0x4d95
movq 0x48(%rsp), %rdi
movslq 0x110(%rsp), %rsi
callq 0x7b40
jmp 0x4da9
movq 0x128(%rsp), %rax
movl 0x12(%rax), %eax
movl %eax, 0xe0(%rsp)
movq 0x128(%rsp), %rax
movl 0x16(%rax), %eax
movl %eax, 0xdc(%rsp)
movl $0x0, 0xd8(%rsp)
movl $0x0, 0xd4(%rsp)
movl 0xd4(%rsp), %eax
cmpl 0x110(%rsp), %eax
jge 0x503f
movq 0x128(%rsp), %rax
movq %rax, 0x38(%rsp)
movl $0x0, 0xc0(%rsp)
movl 0xd4(%rsp), %eax
movl 0x114(%rsp), %ecx
imull %ecx, %eax
movl %eax, 0xbc(%rsp)
leaq 0xc4(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
leaq 0xbc(%rsp), %rdx
callq 0x7c50
jmp 0x4e46
movl 0xe0(%rsp), %eax
decl %eax
movl %eax, 0xb0(%rsp)
movl 0xd4(%rsp), %eax
incl %eax
movl 0x114(%rsp), %ecx
imull %ecx, %eax
decl %eax
movl %eax, 0xac(%rsp)
movl 0xdc(%rsp), %eax
decl %eax
movl %eax, 0xa8(%rsp)
leaq 0xac(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x7c80
movq %rax, 0x30(%rsp)
jmp 0x4e9e
movq 0x30(%rsp), %rdx
leaq 0xb4(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x7cc0
jmp 0x4eba
movq 0x120(%rsp), %rax
movq %rax, 0x28(%rsp)
movl $0x0, 0x9c(%rsp)
movl 0xd4(%rsp), %eax
movl 0x114(%rsp), %ecx
imull %ecx, %eax
movl %eax, 0x98(%rsp)
leaq 0xa0(%rsp), %rdi
leaq 0x9c(%rsp), %rsi
leaq 0x98(%rsp), %rdx
callq 0x7c50
jmp 0x4f09
movl 0xe0(%rsp), %eax
decl %eax
movl %eax, 0x8c(%rsp)
movl 0xd4(%rsp), %eax
incl %eax
movl 0x114(%rsp), %ecx
imull %ecx, %eax
decl %eax
movl %eax, 0x88(%rsp)
movl 0xdc(%rsp), %eax
decl %eax
movl %eax, 0x84(%rsp)
leaq 0x88(%rsp), %rdi
leaq 0x84(%rsp), %rsi
callq 0x7c80
movq %rax, 0x20(%rsp)
jmp 0x4f61
movq 0x20(%rsp), %rdx
leaq 0x90(%rsp), %rdi
leaq 0x8c(%rsp), %rsi
callq 0x7cc0
jmp 0x4f7d
movq 0x28(%rsp), %rcx
movq 0x38(%rsp), %rdi
movq 0xc4(%rsp), %rsi
movq 0xb4(%rsp), %rdx
movq 0xa0(%rsp), %r8
movq 0x90(%rsp), %r9
callq 0x4250
movq %rax, 0x18(%rsp)
jmp 0x4fb3
movq 0x18(%rsp), %rax
movq %rax, 0xcc(%rsp)
leaq 0xf8(%rsp), %rdi
leaq 0xcc(%rsp), %rsi
callq 0x7cf0
jmp 0x4fd7
movl 0xcc(%rsp), %eax
cmpl 0xd8(%rsp), %eax
jle 0x5027
movl 0xcc(%rsp), %eax
movl %eax, 0xd8(%rsp)
jmp 0x5027
movq 0x48(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xe8(%rsp)
movl %eax, 0xe4(%rsp)
callq 0x7ee0
leaq 0xf8(%rsp), %rdi
callq 0x7f40
jmp 0x51f4
jmp 0x5029
movl 0xd4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd4(%rsp)
jmp 0x4de3
movl 0xd8(%rsp), %ecx
movq 0x118(%rsp), %rax
movl %ecx, (%rax)
leaq 0xf8(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0x78(%rsp), %rdi
callq 0x7d60
movq %rax, 0x70(%rsp)
movq 0x78(%rsp), %rdi
callq 0x7d90
movq %rax, 0x68(%rsp)
leaq 0x70(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0x7dc0
testb $0x1, %al
jne 0x5090
jmp 0x50da
leaq 0x70(%rsp), %rdi
callq 0x7e00
movq 0x48(%rsp), %rdi
movq %rax, 0x60(%rsp)
cvtsi2ssl 0xd8(%rsp), %xmm0
movq 0x60(%rsp), %rax
cvtsi2ssl (%rax), %xmm1
divss %xmm1, %xmm0
movss %xmm0, 0x5c(%rsp)
leaq 0x5c(%rsp), %rsi
callq 0x7e10
jmp 0x50cc
jmp 0x50ce
leaq 0x70(%rsp), %rdi
callq 0x7e40
jmp 0x507b
movl $0x0, 0x58(%rsp)
movq 0x48(%rsp), %rdi
movslq 0x58(%rsp), %rax
movq %rax, 0x10(%rsp)
callq 0x7e60
movq %rax, %rcx
movq 0x10(%rsp), %rax
cmpq %rcx, %rax
jae 0x51be
movq 0x48(%rsp), %rdi
movslq 0x58(%rsp), %rsi
callq 0x7ea0
movss (%rax), %xmm0
callq 0x7e80
movb %al, 0xf(%rsp)
jmp 0x5125
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0x5157
jmp 0x512f
movq 0x48(%rsp), %rdi
movslq 0x58(%rsp), %rsi
callq 0x7ea0
movss (%rax), %xmm0
callq 0x7ec0
movb %al, 0xe(%rsp)
jmp 0x514d
movb 0xe(%rsp), %al
testb $0x1, %al
jne 0x5157
jmp 0x51ac
cmpl $0x0, 0x58(%rsp)
jne 0x5169
xorps %xmm0, %xmm0
movss %xmm0, 0x8(%rsp)
jmp 0x5187
movq 0x48(%rsp), %rdi
movl 0x58(%rsp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x7ea0
movss (%rax), %xmm0
movss %xmm0, 0x8(%rsp)
movq 0x48(%rsp), %rdi
movss 0x8(%rsp), %xmm0
movss %xmm0, 0x4(%rsp)
movslq 0x58(%rsp), %rsi
callq 0x7ea0
movss 0x4(%rsp), %xmm0
movss %xmm0, (%rax)
jmp 0x51ae
movl 0x58(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x58(%rsp)
jmp 0x50e2
movb $0x1, 0xf7(%rsp)
testb $0x1, 0xf7(%rsp)
jne 0x51da
movq 0x48(%rsp), %rdi
callq 0x7ee0
leaq 0xf8(%rsp), %rdi
callq 0x7f40
movq 0x40(%rsp), %rax
addq $0x138, %rsp            # imm = 0x138
retq
movq 0xe8(%rsp), %rdi
callq 0x3460
nopw %cs:(%rax,%rax)