// File: /workspace/github_cpp_makefile_star2_O2/kebwi[P]Trifid/src/DebayerProcs.cpp
// Function: altProj_repairRedBlue(SteerablePyramid&, SteerablePyramid const&, SteerablePyramid&, ImageReal&, ImageReal&, ImageReal const&, ImageReal const&)
bool altProj_repairRedBlue(SteerablePyramid &steerPyrR, const SteerablePyramid &steerPyrG, SteerablePyramid &steerPyrB,
							ImageReal &r, ImageReal &b,
							const ImageReal &rRealOri, const ImageReal &bRealOri)
{
	int width = r.width(), height = r.height();
	assert(b.width() == width && b.height() == height);
	
	int numLevels = steerPyrG.NumLevels();
	
	//Perform a wavelet analysis of red and blue
	steerPyrR.DoFullWaveletAnalysis(r.img(), width, height, true);
	cout << ".";	cout.flush();
	steerPyrB.DoFullWaveletAnalysis(b.img(), width, height, true);
	cout << ".";	cout.flush();
	
	//Compare the high frequency components of red and blue with green.
	//Use the similarity/correlation between high frequency red/green and blue/green
	//to derive thresholds to be used below.
	vector<Float_t> greenRedCorrs, greenBlueCorrs;	//One correlation per level
	steerPyrG.findCorrelations(steerPyrR, greenRedCorrs);
	steerPyrG.findCorrelations(steerPyrB, greenBlueCorrs);
	/*
	cout << "Green/Red correlations: ";
	for (int i = 0; i < greenRedCorrs.size(); i++)
		cout << setw(15) << greenRedCorrs[i];
	cout << endl;
	cout << "Green/Blue correlations:";
	for (int i = 0; i < greenBlueCorrs.size(); i++)
		cout << setw(15) << greenBlueCorrs[i];
	cout << endl;
	*/
	int arrayOffset = 1;	//1 for Steerable Pyramid, 0 for Daubechies
	
	vector<Float_t> means, stdDevs;
	steerPyrG.CalcStats(means, stdDevs);
	assert(means.size() == steerPyrG.NumLevels() + arrayOffset);
	
	vector<Float_t> thresholdsR(numLevels), thresholdsB(numLevels);
	for (int i = 0; i < numLevels; i++)
	{
		if (i == 0)
		{
			thresholdsR[i] = (((greenRedCorrs[i] + 1) / 2) * means[i + 1]);
			thresholdsB[i] = (((greenBlueCorrs[i] + 1) / 2) * means[i + 1]);
		}
		else thresholdsR[i] = thresholdsB[i] = -1;
	}
	
	//for (int i = 0; i < numLevels; i++)
	//	cout << "Red/Blue thresholds: " << thresholdsR[i] << "    " << thresholdsB[i] << endl;
	
	//Push the high frequency coefficients of red and blue toward those of green
	steerPyrR.CopyCoefficients(steerPyrG, thresholdsR);
	steerPyrB.CopyCoefficients(steerPyrG, thresholdsB);
	
	//Reconstruct red and blue
	steerPyrR.DoFullWaveletSynthesis(r.img());
	cout << ".";	cout.flush();
	steerPyrB.DoFullWaveletSynthesis(b.img());
	cout << ".";	cout.flush();
	
	//Copy original red and blue pixels into the reconstruction
	int startX, startY;
	determineBlockCoord(R, startX, startY);
	for (int y = startY; y < height; y += 2)
		for (int x = startX; x < width; x += 2)
			r(x, y) = rRealOri(x, y);
	
	determineBlockCoord(B, startX, startY);
	for (int y = startY; y < height; y += 2)
		for (int x = startX; x < width; x += 2)
			b(x, y) = bRealOri(x, y);
	
	//Determine if convergence has been attained
	return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x108, %rsp            # imm = 0x108
movq %rdx, 0x28(%rsp)
movq %rdi, 0x18(%rsp)
movl 0x28(%rcx), %ebp
cmpl %ebp, 0x28(%r8)
jne 0xe675
movq %r8, %rbx
movq %rcx, %r12
movl 0x2c(%rcx), %r14d
cmpl %r14d, 0x2c(%r8)
jne 0xe675
movq %r9, %r15
movq %rsi, %rdi
movq %rsi, 0x10(%rsp)
callq 0x16762
movl %eax, %r13d
movq 0x38(%r12), %rsi
pushq $0x1
popq %r8
movq 0x18(%rsp), %rdi
movl %ebp, %edx
movl %r14d, %ecx
callq 0x17960
movq 0x21ced(%rip), %rdi     # 0x2ffd0
leaq 0x14f0b(%rip), %rsi     # 0x231f5
callq 0x32c0
movq 0x21cda(%rip), %rdi     # 0x2ffd0
callq 0x31d0
movq 0x38(%rbx), %rsi
movq 0x28(%rsp), %rdi
movl %ebp, %edx
movl %r14d, %ecx
pushq $0x1
popq %r8
callq 0x17960
movq 0x21cb7(%rip), %rdi     # 0x2ffd0
leaq 0x14ed5(%rip), %rsi     # 0x231f5
callq 0x32c0
movq 0x21ca4(%rip), %rdi     # 0x2ffd0
callq 0x31d0
xorpd %xmm0, %xmm0
leaq 0xa0(%rsp), %rdx
movapd %xmm0, (%rdx)
andq $0x0, 0x10(%rdx)
movapd %xmm0, 0x50(%rsp)
andq $0x0, 0x60(%rsp)
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rsi
callq 0x18b3a
leaq 0x50(%rsp), %rdx
movq 0x10(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0x18b3a
xorpd %xmm0, %xmm0
leaq 0x30(%rsp), %rsi
movapd %xmm0, (%rsi)
andq $0x0, 0x10(%rsi)
leaq 0xf0(%rsp), %rdx
movapd %xmm0, (%rdx)
andq $0x0, 0x10(%rdx)
movq 0x10(%rsp), %rdi
callq 0x1853a
movq 0x30(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x38(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x10(%rsp), %rdi
callq 0x16762
movq 0x20(%rsp), %rcx
subq 0x68(%rsp), %rcx
sarq $0x3, %rcx
incl %eax
cltq
cmpq %rax, %rcx
jne 0xe694
movslq %r13d, %rsi
leaq 0x88(%rsp), %rdi
leaq 0x70(%rsp), %rdx
movq %rsi, 0x20(%rsp)
callq 0xed70
leaq 0x70(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movq 0x20(%rsp), %rsi
callq 0xed70
movq 0x70(%rsp), %rax
movq 0x88(%rsp), %rcx
movq 0xa0(%rsp), %rdx
movq 0x30(%rsp), %rsi
xorl %edi, %edi
testl %r13d, %r13d
cmovlel %edi, %r13d
movq 0x50(%rsp), %r8
movsd 0x13c1f(%rip), %xmm0    # 0x22058
movsd 0x13c07(%rip), %xmm1    # 0x22048
movabsq $-0x4010000000000000, %r9 # imm = 0xBFF0000000000000
cmpq %rdi, %r13
je 0xe48f
testq %rdi, %rdi
je 0xe45f
movq %r9, (%rax,%rdi,8)
movq %r9, (%rcx,%rdi,8)
jmp 0xe48a
movsd (%rdx), %xmm2
addsd %xmm0, %xmm2
mulsd %xmm1, %xmm2
mulsd 0x8(%rsi), %xmm2
movsd %xmm2, (%rcx)
movsd (%r8), %xmm2
addsd %xmm0, %xmm2
mulsd %xmm1, %xmm2
mulsd 0x8(%rsi), %xmm2
movsd %xmm2, (%rax)
incq %rdi
jmp 0xe44b
leaq 0xd8(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0xedc2
movq 0x28(%rsp), %r13
leaq 0xd8(%rsp), %rdx
movq 0x18(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x18f56
leaq 0xd8(%rsp), %rdi
callq 0x8a42
leaq 0xc0(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0xedc2
leaq 0xc0(%rsp), %rdx
movq %r13, %rdi
movq 0x10(%rsp), %rsi
callq 0x18f56
leaq 0xc0(%rsp), %rdi
callq 0x8a42
movq 0x38(%r12), %rsi
movq 0x18(%rsp), %rdi
callq 0x183d8
movq 0x21ab9(%rip), %rdi     # 0x2ffd0
leaq 0x14cd7(%rip), %rsi     # 0x231f5
callq 0x32c0
movq 0x21aa6(%rip), %rdi     # 0x2ffd0
callq 0x31d0
movq 0x38(%rbx), %rsi
movq %r13, %rdi
callq 0x183d8
movq 0x21a8e(%rip), %rdi     # 0x2ffd0
leaq 0x14cac(%rip), %rsi     # 0x231f5
callq 0x32c0
movq 0x21a7b(%rip), %rdi     # 0x2ffd0
callq 0x31d0
leaq 0x8(%rsp), %rsi
leaq 0xc(%rsp), %rdx
xorl %edi, %edi
callq 0x1c2ea
movl 0xc(%rsp), %eax
movl 0x8(%rsp), %ecx
cmpl %r14d, %eax
jge 0xe5b8
movq 0x38(%r15), %rdx
movl 0x28(%r15), %esi
imull %eax, %esi
movq 0x38(%r12), %rdi
movl 0x28(%r12), %r8d
imull %eax, %r8d
movl %ecx, %r9d
cmpl %ebp, %r9d
jge 0xe5b3
leal (%rsi,%r9), %r10d
movsd (%rdx,%r10,8), %xmm0
leal (%r8,%r9), %r10d
movsd %xmm0, (%rdi,%r10,8)
addl $0x2, %r9d
jmp 0xe594
addl $0x2, %eax
jmp 0xe573
pushq $0x2
popq %rdi
leaq 0x8(%rsp), %rsi
leaq 0xc(%rsp), %rdx
callq 0x1c2ea
movl 0xc(%rsp), %eax
movl 0x8(%rsp), %ecx
cmpl %r14d, %eax
jge 0xe61c
movq 0x140(%rsp), %rsi
movq 0x38(%rsi), %rdx
movl 0x28(%rsi), %esi
imull %eax, %esi
movq 0x38(%rbx), %rdi
movl 0x28(%rbx), %r8d
imull %eax, %r8d
movl %ecx, %r9d
cmpl %ebp, %r9d
jge 0xe617
leal (%rsi,%r9), %r10d
movsd (%rdx,%r10,8), %xmm0
leal (%r8,%r9), %r10d
movsd %xmm0, (%rdi,%r10,8)
addl $0x2, %r9d
jmp 0xe5f8
addl $0x2, %eax
jmp 0xe5d2
leaq 0x70(%rsp), %rdi
callq 0x8a42
leaq 0x88(%rsp), %rdi
callq 0x8a42
leaq 0xf0(%rsp), %rdi
callq 0x8a42
leaq 0x30(%rsp), %rdi
callq 0x8a42
leaq 0x50(%rsp), %rdi
callq 0x8a42
leaq 0xa0(%rsp), %rdi
callq 0x8a42
movb $0x1, %al
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x15225(%rip), %rdi     # 0x238a1
leaq 0x14e1d(%rip), %rsi     # 0x234a0
leaq 0x15242(%rip), %rcx     # 0x238cc
movl $0x2be, %edx            # imm = 0x2BE
callq 0x31a0
leaq 0x152ce(%rip), %rdi     # 0x23969
leaq 0x14dfe(%rip), %rsi     # 0x234a0
leaq 0x15223(%rip), %rcx     # 0x238cc
movl $0x2dc, %edx            # imm = 0x2DC
callq 0x31a0
movq %rax, %rbx
leaq 0xc0(%rsp), %rdi
jmp 0xe6cb
movq %rax, %rbx
leaq 0xd8(%rsp), %rdi
callq 0x8a42
jmp 0xe6e8
movq %rax, %rbx
jmp 0xe6f2
jmp 0xe6db
jmp 0xe6e5
movq %rax, %rbx
jmp 0xe6ff
movq %rax, %rbx
jmp 0xe716
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x8a42
leaq 0x88(%rsp), %rdi
callq 0x8a42
leaq 0xf0(%rsp), %rdi
callq 0x8a42
leaq 0x30(%rsp), %rdi
callq 0x8a42
leaq 0x50(%rsp), %rdi
callq 0x8a42
leaq 0xa0(%rsp), %rdi
callq 0x8a42
movq %rbx, %rdi
callq 0x34d0