// File: /workspace/github_cpp_makefile_star2_O2/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, 0x4(%rsp)
movq %rdi, %r15
movq %rsi, 0x8(%rsp)
movl %esi, %r13d
movq %r13, 0x18(%rsp)
shlq $0x4, %r13
movq %r13, %rdi
callq 0x1080
movq %rax, %r12
movq %r13, %rdi
callq 0x1080
movq %rax, %r13
movl %ebx, (%rsp)
testl %ebx, %ebx
jne 0x1592
movq 0x18(%rsp), %rax
leaq (%rax,%rax), %rbx
movq 0x8(%rsp), %rax
addl %eax, %eax
movq %rax, 0x20(%rsp)
xorl %ebp, %ebp
xorl %eax, %eax
cmpl 0x4(%rsp), %eax
je 0x1588
movl %eax, 0x10(%rsp)
movl %ebp, %r14d
incq %r14
xorl %eax, %eax
cmpq %rax, %rbx
je 0x1532
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
jmp 0x1503
movq %r12, %rdi
movq %r13, %rsi
movq 0x8(%rsp), %rdx
movl (%rsp), %ecx
callq 0x1373
xorl %eax, %eax
cmpq %rax, %rbx
je 0x1578
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
jmp 0x1547
movl 0x10(%rsp), %eax
incl %eax
addq 0x20(%rsp), %rbp
jmp 0x14ed
cmpl $0x0, (%rsp)
jne 0x164c
movl 0x4(%rsp), %ebx
addq %rbx, %rbx
movq 0x8(%rsp), %rax
leal (%rax,%rax), %ebp
xorl %eax, %eax
pushq $0x1
popq %r14
cmpl 0x8(%rsp), %eax
je 0x1642
movq %rax, 0x10(%rsp)
movl %r14d, %eax
xorl %ecx, %ecx
cmpq %rcx, %rbx
je 0x15ea
leal -0x1(%rax), %edx
movsd (%r15,%rdx,8), %xmm0
movl %ecx, %edx
movsd %xmm0, (%r12,%rdx,8)
movl %eax, %edx
movsd (%r15,%rdx,8), %xmm0
leal 0x1(%rcx), %edx
movsd %xmm0, (%r12,%rdx,8)
addq $0x2, %rcx
addl %ebp, %eax
jmp 0x15bb
movq %r12, %rdi
movq %r13, %rsi
movl 0x4(%rsp), %edx
movl (%rsp), %ecx
callq 0x1373
movl %r14d, %eax
xorl %ecx, %ecx
cmpq %rcx, %rbx
je 0x1632
movl %ecx, %edx
movsd (%r13,%rdx,8), %xmm0
leal -0x1(%rax), %edx
movsd %xmm0, (%r15,%rdx,8)
leal 0x1(%rcx), %edx
movsd (%r13,%rdx,8), %xmm0
movl %eax, %edx
movsd %xmm0, (%r15,%rdx,8)
addq $0x2, %rcx
addl %ebp, %eax
jmp 0x1601
movq 0x10(%rsp), %rax
incl %eax
addl $0x2, %r14d
jmp 0x15a7
cmpl $0x0, (%rsp)
jne 0x14d4
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