// File: /workspace/github_cpp_makefile_star2_O2/kebwi[P]Trifid/src/FourierTransform.cpp
// Function: convolveImages(ImageReal const&, ImageReal const&, ImageReal&)
bool convolveImages(const ImageReal &img1, const ImageReal &img2, ImageReal &imgConv)
{
	int maxWidth = max(img1.width(), img2.width());
	int maxHeight = max(img1.height(), img2.height());
	int maxHalfWidth = maxWidth / 2, maxHalfHeight = maxHeight / 2;
	
	if (!assertValidDims(maxWidth, maxHeight))
		return false;
	
	ImageReal img1Temp;
	int offsetX, offsetY;
	assert(embedImageInPow2Bounds(img1, maxWidth, maxHeight, img1Temp, offsetX, offsetY));
	ImageReal img2Temp;
	assert(embedImageInPow2Bounds(img2, maxWidth, maxHeight, img2Temp, offsetX, offsetY));
	
	//Half shift the second image
	ImageReal img2Shifted(maxWidth, maxHeight);
	for (int y = 0; y < maxHeight; y++)
		for (int x = 0; x < maxWidth; x++)
			img2Shifted(x, y) =
				img2Temp((x + maxHalfWidth) % maxWidth, (y + maxHalfHeight) % maxHeight);
	
	//Get the Fourier Transform of the images
	ImageReal img1Ft(maxWidth, maxHeight);
	assert(doFourierAnalysis(img1Temp, img1Ft));
	ImageReal img2Ft(maxWidth, maxHeight);
	assert(doFourierAnalysis(img2Shifted, img2Ft));
	
	//Multiplty the Fourier Transforms
	imgConv.resize(maxWidth, maxHeight);
	rspect2dprod(img1Ft.img(), img2Ft.img(), imgConv.img(), maxHeight, maxWidth);
	
	int err = fft2dInit(log2(maxHeight), log2(maxWidth));
	if (err != 0)
		return false;
	
	//Invert the Fourier Transform
	rifft2d(imgConv.img(), log2(maxHeight), log2(maxWidth));
	
	return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x168, %rsp            # imm = 0x168
movq %rdx, %r15
movq %rsi, %r13
movq %rdi, %r14
movl 0x28(%rdi), %eax
movl 0x2c(%rdi), %ecx
movl 0x28(%rsi), %ebx
movl 0x2c(%rsi), %ebp
cmpl %ebx, %eax
cmovgl %eax, %ebx
cmpl %ebp, %ecx
cmovgl %ecx, %ebp
pushq $0x2
popq %rcx
movl %ebx, %eax
cltd
idivl %ecx
movl %eax, 0xc(%rsp)
movl %ebp, %eax
cltd
idivl %ecx
movq %rax, 0x20(%rsp)
movl %ebx, %edi
movl %ebp, %esi
callq 0x13ae0
testb %al, %al
je 0x14b02
leaq 0x128(%rsp), %r12
movq %r12, %rdi
callq 0xa588
leaq 0x14(%rsp), %r8
leaq 0x10(%rsp), %r9
movq %r14, %rdi
movl %ebx, %esi
movl %ebp, %edx
movq %r12, %rcx
callq 0x143d6
testb %al, %al
je 0x14c36
leaq 0x68(%rsp), %rdi
callq 0xa588
leaq 0x68(%rsp), %rcx
leaq 0x14(%rsp), %r8
leaq 0x10(%rsp), %r9
movq %r13, %rdi
movl %ebx, %esi
movl %ebp, %edx
callq 0x143d6
testb %al, %al
je 0x14c55
movq %r15, 0x18(%rsp)
leaq 0x28(%rsp), %rdi
movl %ebx, %esi
movl %ebp, %edx
callq 0xa62e
xorl %r8d, %r8d
testl %ebx, %ebx
movl $0x0, %r12d
cmovgl %ebx, %r12d
testl %ebp, %ebp
movl $0x0, %r10d
cmovgl %ebp, %r10d
cmpl %r10d, %r8d
je 0x14b0a
movq 0x20(%rsp), %rax
leal (%r8,%rax), %ecx
movq 0xa0(%rsp), %r11
movl 0x90(%rsp), %r14d
movq 0x60(%rsp), %r13
movl 0x50(%rsp), %r15d
imull %r8d, %r15d
movq %r12, %r9
movl 0xc(%rsp), %esi
subq $0x1, %r9
jb 0x14afd
movl %esi, %eax
cltd
idivl %ebx
movl %edx, %edi
movl %ecx, %eax
cltd
idivl %ebp
imull %r14d, %edx
addl %edi, %edx
movsd (%r11,%rdx,8), %xmm0
movl %r15d, %eax
movsd %xmm0, (%r13,%rax,8)
incl %esi
incl %r15d
jmp 0x14ace
incl %r8d
jmp 0x14a9b
xorl %r15d, %r15d
jmp 0x14c21
leaq 0xe8(%rsp), %rdi
movl %ebx, %esi
movl %ebp, %edx
callq 0xa62e
leaq 0x128(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x141c3
movq 0x18(%rsp), %r12
testb %al, %al
je 0x14c74
leaq 0xa8(%rsp), %rdi
movl %ebx, %esi
movl %ebp, %edx
callq 0xa62e
leaq 0x28(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x141c3
testb %al, %al
je 0x14c93
movq (%r12), %rax
movq %r12, %rdi
movl %ebx, %esi
movl %ebp, %edx
callq *0x28(%rax)
movq 0x120(%rsp), %rdi
movq 0xe0(%rsp), %rsi
movq 0x38(%r12), %rdx
movslq %ebp, %rcx
movslq %ebx, %r8
callq 0x1d52c
movl %ebp, %edi
callq 0x1528a
cvttsd2si %xmm0, %r14
movl %ebx, %edi
callq 0x1528a
cvttsd2si %xmm0, %rsi
movq %r14, %rdi
callq 0x1c4a0
testl %eax, %eax
sete %r15b
jne 0x14be6
movq 0x38(%r12), %r14
movl %ebp, %edi
callq 0x1528a
cvttsd2si %xmm0, %r12
movl %ebx, %edi
callq 0x1528a
cvttsd2si %xmm0, %rdx
movq %r14, %rdi
movq %r12, %rsi
callq 0x1d1be
leaq 0xa8(%rsp), %rdi
callq 0xa6a6
leaq 0xe8(%rsp), %rdi
callq 0xa6a6
leaq 0x28(%rsp), %rdi
callq 0xa6a6
leaq 0x68(%rsp), %rdi
callq 0xa6a6
leaq 0x128(%rsp), %rdi
callq 0xa6a6
movl %r15d, %eax
addq $0x168, %rsp            # imm = 0x168
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x101e6(%rip), %rdi     # 0x24e23
leaq 0xff77(%rip), %rsi      # 0x24bbb
leaq 0x10226(%rip), %rcx     # 0x24e71
movl $0x18a, %edx            # imm = 0x18A
callq 0x31a0
leaq 0x1025c(%rip), %rdi     # 0x24eb8
leaq 0xff58(%rip), %rsi      # 0x24bbb
leaq 0x10207(%rip), %rcx     # 0x24e71
movl $0x18c, %edx            # imm = 0x18C
callq 0x31a0
leaq 0x1028b(%rip), %rdi     # 0x24f06
leaq 0xff39(%rip), %rsi      # 0x24bbb
leaq 0x101e8(%rip), %rcx     # 0x24e71
movl $0x197, %edx            # imm = 0x197
callq 0x31a0
leaq 0x10290(%rip), %rdi     # 0x24f2a
leaq 0xff1a(%rip), %rsi      # 0x24bbb
leaq 0x101c9(%rip), %rcx     # 0x24e71
movl $0x199, %edx            # imm = 0x199
callq 0x31a0
jmp 0x14cb4
movq %rax, %rbx
jmp 0x14cde
movq %rax, %rbx
jmp 0x14ceb
jmp 0x14cc0
movq %rax, %rbx
jmp 0x14cf5
jmp 0x14cc7
movq %rax, %rbx
jmp 0x14cff
jmp 0x14cce
movq %rax, %rbx
leaq 0xa8(%rsp), %rdi
callq 0xa6a6
leaq 0xe8(%rsp), %rdi
callq 0xa6a6
leaq 0x28(%rsp), %rdi
callq 0xa6a6
leaq 0x68(%rsp), %rdi
callq 0xa6a6
leaq 0x128(%rsp), %rdi
callq 0xa6a6
movq %rbx, %rdi
callq 0x34d0