// File: /workspace/github_cpp_makefile_star2_O3/markondej[P]phase_correl/phase_correl.c
// Function: fft2D
void fft2D(double *data, unsigned width, unsigned height, int inverse) {
    unsigned i, j;

    double *fft_input = (double *)malloc((sizeof(double) * width) << 1);
    double *fft_output = (double *)malloc((sizeof(double) * width) << 1);

    if (inverse) {
        goto horizontal_fft;
    }

vertical_fft:
    for (j = 0; j < height; j++) {
        unsigned offset = j * width;
        for (i = 0; i < width; i++) {
            fft_input[i << 1] = data[offset << 1];
            fft_input[(i << 1) + 1] = data[(offset << 1) + 1];
            offset++;
        }
        dit2fft(fft_input, fft_output, width, inverse);
        offset = j * width;
        for (i = 0; i < width; i++) {
            data[offset << 1] = fft_output[i << 1];
            data[(offset << 1) + 1] = fft_output[(i << 1) + 1];
            offset++;
        }
    }

    if (inverse) {
        goto done;
    }

horizontal_fft:
    for (i = 0; i < width; i++) {
        unsigned offset = i;
        for (j = 0; j < height; j++) {
            fft_input[j << 1] = data[offset << 1];
            fft_input[(j << 1) + 1] = data[(offset << 1) + 1];
            offset += width;
        }
        dit2fft(fft_input, fft_output, height, inverse);
        offset = i;
        for (j = 0; j < height; j++) {
            data[offset << 1] = fft_output[j << 1];
            data[(offset << 1) + 1] = fft_output[(j << 1) + 1];
            offset += width;
        }
    }

    if (inverse) {
        goto vertical_fft;
    }

done:
    free(fft_input);
    free(fft_output);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movl %ecx, %ebx
movl %edx, %ebp
movl %esi, %r14d
movq %rdi, %r15
movl %esi, %r13d
movq %r13, 0x18(%rsp)
shlq $0x4, %r13
movq %r13, %rdi
callq 0x1080
movq %rax, %r12
movq %r13, %rdi
callq 0x1080
movq %r14, %r8
movl %ebp, %edx
movq %rax, %r13
movl %ebx, (%rsp)
testl %ebx, %ebx
movl %ebp, 0x4(%rsp)
movq %r14, 0x10(%rsp)
jne 0x1654
testl %edx, %edx
je 0x164a
movq 0x18(%rsp), %rax
leaq (%rax,%rax), %rbx
leal (%r8,%r8), %eax
movq %rax, 0x20(%rsp)
xorl %ebp, %ebp
xorl %eax, %eax
movl %eax, 0x8(%rsp)
testl %r8d, %r8d
je 0x161d
movl %ebp, %r14d
incq %r14
xorl %eax, %eax
leal (%rax,%rbp), %ecx
movsd (%r15,%rcx,8), %xmm0
movl %eax, %ecx
movsd %xmm0, (%r12,%rcx,8)
leal (%r14,%rax), %ecx
movsd (%r15,%rcx,8), %xmm0
leal 0x1(%rax), %ecx
movsd %xmm0, (%r12,%rcx,8)
addq $0x2, %rax
cmpq %rax, %rbx
jne 0x15a2
movq %r12, %rdi
movq %r13, %rsi
movl %r8d, %edx
movl (%rsp), %ecx
callq 0x1382
movq 0x10(%rsp), %r8
testl %r8d, %r8d
je 0x1633
xorl %eax, %eax
movl %eax, %ecx
movsd (%r13,%rcx,8), %xmm0
leal (%rax,%rbp), %ecx
movsd %xmm0, (%r15,%rcx,8)
leal 0x1(%rax), %ecx
movsd (%r13,%rcx,8), %xmm0
leal (%r14,%rax), %ecx
movsd %xmm0, (%r15,%rcx,8)
addq $0x2, %rax
cmpq %rax, %rbx
jne 0x15ec
jmp 0x1633
movq %r12, %rdi
movq %r13, %rsi
movl %r8d, %edx
movl (%rsp), %ecx
callq 0x1382
movq 0x10(%rsp), %r8
movl 0x8(%rsp), %eax
incl %eax
addq 0x20(%rsp), %rbp
movl 0x4(%rsp), %edx
cmpl %edx, %eax
jne 0x158d
cmpl $0x0, (%rsp)
jne 0x172a
testl %r8d, %r8d
je 0x1720
movl %edx, %ebx
addq %rbx, %rbx
leal (%r8,%r8), %ebp
xorl %eax, %eax
movl $0x1, %r14d
movq %rax, 0x8(%rsp)
testl %edx, %edx
je 0x16f5
movl %r14d, %eax
xorl %ecx, %ecx
leal -0x1(%rax), %esi
movsd (%r15,%rsi,8), %xmm0
movl %ecx, %esi
movsd %xmm0, (%r12,%rsi,8)
movl %eax, %esi
movsd (%r15,%rsi,8), %xmm0
leal 0x1(%rcx), %esi
movsd %xmm0, (%r12,%rsi,8)
addq $0x2, %rcx
addl %ebp, %eax
cmpq %rcx, %rbx
jne 0x167c
movq %r12, %rdi
movq %r13, %rsi
movl (%rsp), %ecx
callq 0x1382
movl 0x4(%rsp), %edx
testl %edx, %edx
je 0x1707
movl %r14d, %eax
xorl %ecx, %ecx
movl %ecx, %esi
movsd (%r13,%rsi,8), %xmm0
leal -0x1(%rax), %esi
movsd %xmm0, (%r15,%rsi,8)
leal 0x1(%rcx), %esi
movsd (%r13,%rsi,8), %xmm0
movl %eax, %esi
movsd %xmm0, (%r15,%rsi,8)
addq $0x2, %rcx
addl %ebp, %eax
cmpq %rcx, %rbx
jne 0x16c4
jmp 0x1707
movq %r12, %rdi
movq %r13, %rsi
movl (%rsp), %ecx
callq 0x1382
movl 0x4(%rsp), %edx
movq 0x8(%rsp), %rax
incl %eax
addl $0x2, %r14d
movq 0x10(%rsp), %r8
cmpl %r8d, %eax
jne 0x166e
cmpl $0x0, (%rsp)
jne 0x156f
movq %r12, %rdi
callq 0x1030
movq %r13, %rdi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1030