// File: 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
movq %rsp, %rbp
subq $0x240, %rsp            # imm = 0x240
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq -0x20(%rbp), %rdi
callq 0xedd0
movl %eax, -0x34(%rbp)
movq -0x20(%rbp), %rdi
callq 0xedf0
movl %eax, -0x38(%rbp)
movq -0x28(%rbp), %rdi
callq 0xedd0
movl %eax, %ecx
xorl %eax, %eax
cmpl -0x34(%rbp), %ecx
movb %al, -0x139(%rbp)
jne 0x1c55c
movq -0x28(%rbp), %rdi
callq 0xedf0
cmpl -0x38(%rbp), %eax
sete %al
movb %al, -0x139(%rbp)
movb -0x139(%rbp), %al
testb $0x1, %al
jne 0x1c568
jmp 0x1c56a
jmp 0x1c589
leaq 0x2e400(%rip), %rdi     # 0x4a971
leaq 0x2dff8(%rip), %rsi     # 0x4a570
movl $0x2be, %edx            # imm = 0x2BE
leaq 0x2e418(%rip), %rcx     # 0x4a99c
callq 0x4240
movq -0x10(%rbp), %rdi
callq 0x2bac0
movl %eax, -0x3c(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x170(%rbp)
movq -0x20(%rbp), %rdi
callq 0xf2c0
movq -0x170(%rbp), %rdi
movq %rax, %rsi
movl -0x34(%rbp), %edx
movl -0x38(%rbp), %ecx
movl $0x1, %r8d
movl %r8d, -0x15c(%rbp)
callq 0x2d2c0
movq 0x3d9fe(%rip), %rdi     # 0x59fd0
movq %rdi, -0x150(%rbp)
leaq 0x2dcfd(%rip), %rsi     # 0x4a2dd
movq %rsi, -0x158(%rbp)
callq 0x4390
movq -0x150(%rbp), %rdi
callq 0x4250
movq -0x18(%rbp), %rax
movq %rax, -0x168(%rbp)
movq -0x28(%rbp), %rdi
callq 0xf2c0
movq -0x168(%rbp), %rdi
movl -0x15c(%rbp), %r8d
movq %rax, %rsi
movl -0x34(%rbp), %edx
movl -0x38(%rbp), %ecx
callq 0x2d2c0
movq -0x158(%rbp), %rsi
movq -0x150(%rbp), %rdi
callq 0x4390
movq -0x150(%rbp), %rdi
callq 0x4250
leaq -0x58(%rbp), %rdi
movq %rdi, -0x148(%rbp)
callq 0xe240
leaq -0x70(%rbp), %rdi
callq 0xe240
movq -0x148(%rbp), %rdx
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0x2f2e0
jmp 0x1c676
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq -0x70(%rbp), %rdx
callq 0x2f2e0
jmp 0x1c689
movl $0x1, -0x80(%rbp)
leaq -0x98(%rbp), %rdi
movq %rdi, -0x180(%rbp)
callq 0xe240
leaq -0xb0(%rbp), %rdi
movq %rdi, -0x178(%rbp)
callq 0xe240
movq -0x180(%rbp), %rsi
movq -0x178(%rbp), %rdx
movq -0x10(%rbp), %rdi
callq 0x2e630
jmp 0x1c6cf
leaq -0x98(%rbp), %rdi
callq 0xe5c0
movq %rax, -0x190(%rbp)
movq -0x10(%rbp), %rdi
callq 0x2bac0
movl %eax, -0x184(%rbp)
jmp 0x1c6f3
movq -0x190(%rbp), %rax
movl -0x184(%rbp), %ecx
addl -0x80(%rbp), %ecx
movslq %ecx, %rcx
cmpq %rcx, %rax
jne 0x1c70d
jmp 0x1c74e
leaq 0x2e325(%rip), %rdi     # 0x4aa39
leaq 0x2de55(%rip), %rsi     # 0x4a570
movl $0x2dc, %edx            # imm = 0x2DC
leaq 0x2e275(%rip), %rcx     # 0x4a99c
callq 0x4240
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x1cd4e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x1cd36
movslq -0x3c(%rbp), %rax
movq %rax, -0x1a0(%rbp)
leaq -0xc9(%rbp), %rdi
movq %rdi, -0x198(%rbp)
callq 0xf440
movq -0x1a0(%rbp), %rsi
movq -0x198(%rbp), %rdx
leaq -0xc8(%rbp), %rdi
callq 0x1d820
jmp 0x1c788
leaq -0xc9(%rbp), %rdi
callq 0xff00
movslq -0x3c(%rbp), %rax
movq %rax, -0x1b0(%rbp)
leaq -0xe9(%rbp), %rdi
movq %rdi, -0x1a8(%rbp)
callq 0xf440
movq -0x1b0(%rbp), %rsi
movq -0x1a8(%rbp), %rdx
leaq -0xe8(%rbp), %rdi
callq 0x1d820
jmp 0x1c7ce
leaq -0xe9(%rbp), %rdi
callq 0xff00
movl $0x0, -0xf0(%rbp)
movl -0xf0(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jge 0x1c986
cmpl $0x0, -0xf0(%rbp)
jne 0x1c932
movslq -0xf0(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0xe670
movsd 0x2c808(%rip), %xmm0    # 0x49020
addsd (%rax), %xmm0
movsd 0x2dd24(%rip), %xmm1    # 0x4a548
divsd %xmm1, %xmm0
movsd %xmm0, -0x1d0(%rbp)
movl -0xf0(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
leaq -0x98(%rbp), %rdi
callq 0xe670
movsd -0x1d0(%rbp), %xmm0
mulsd (%rax), %xmm0
movsd %xmm0, -0x1c8(%rbp)
movslq -0xf0(%rbp), %rsi
leaq -0xc8(%rbp), %rdi
callq 0xe670
movsd -0x1c8(%rbp), %xmm0
movsd %xmm0, (%rax)
movslq -0xf0(%rbp), %rsi
leaq -0x70(%rbp), %rdi
callq 0xe670
movsd 0x2c78d(%rip), %xmm0    # 0x49020
addsd (%rax), %xmm0
movsd 0x2dca9(%rip), %xmm1    # 0x4a548
divsd %xmm1, %xmm0
movsd %xmm0, -0x1c0(%rbp)
movl -0xf0(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
leaq -0x98(%rbp), %rdi
callq 0xe670
movsd -0x1c0(%rbp), %xmm0
mulsd (%rax), %xmm0
movsd %xmm0, -0x1b8(%rbp)
movslq -0xf0(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
callq 0xe670
movsd -0x1b8(%rbp), %xmm0
movsd %xmm0, (%rax)
jmp 0x1c970
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0xc9(%rbp), %rdi
callq 0xff00
jmp 0x1cd36
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0xe9(%rbp), %rdi
callq 0xff00
jmp 0x1cd2a
movslq -0xf0(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
callq 0xe670
movsd 0x2c6eb(%rip), %xmm0    # 0x49038
movsd %xmm0, (%rax)
movslq -0xf0(%rbp), %rsi
leaq -0xc8(%rbp), %rdi
callq 0xe670
movsd 0x2c6cc(%rip), %xmm0    # 0x49038
movsd %xmm0, (%rax)
jmp 0x1c972
movl -0xf0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xf0(%rbp)
jmp 0x1c7e4
movq -0x8(%rbp), %rax
movq %rax, -0x1e0(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1d8(%rbp)
leaq -0x108(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x1d890
jmp 0x1c9b1
movq -0x1d8(%rbp), %rsi
movq -0x1e0(%rbp), %rdi
leaq -0x108(%rbp), %rdx
callq 0x2fa20
jmp 0x1c9cd
leaq -0x108(%rbp), %rdi
callq 0xe260
movq -0x18(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1e8(%rbp)
leaq -0x120(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x1d890
jmp 0x1ca04
movq -0x1e8(%rbp), %rsi
movq -0x1f0(%rbp), %rdi
leaq -0x120(%rbp), %rdx
callq 0x2fa20
jmp 0x1ca20
leaq -0x120(%rbp), %rdi
callq 0xe260
movq -0x8(%rbp), %rax
movq %rax, -0x200(%rbp)
movq -0x20(%rbp), %rdi
callq 0xf2c0
movq %rax, -0x1f8(%rbp)
jmp 0x1ca49
movq -0x1f8(%rbp), %rsi
movq -0x200(%rbp), %rdi
callq 0x2e250
jmp 0x1ca5e
movq 0x3d56b(%rip), %rdi     # 0x59fd0
leaq 0x2d871(%rip), %rsi     # 0x4a2dd
callq 0x4390
jmp 0x1ca73
movq 0x3d556(%rip), %rdi     # 0x59fd0
callq 0x4250
jmp 0x1ca81
movq -0x18(%rbp), %rax
movq %rax, -0x210(%rbp)
movq -0x28(%rbp), %rdi
callq 0xf2c0
movq %rax, -0x208(%rbp)
jmp 0x1ca9e
movq -0x208(%rbp), %rsi
movq -0x210(%rbp), %rdi
callq 0x2e250
jmp 0x1cab3
movq 0x3d516(%rip), %rdi     # 0x59fd0
leaq 0x2d81c(%rip), %rsi     # 0x4a2dd
callq 0x4390
jmp 0x1cac8
movq 0x3d501(%rip), %rdi     # 0x59fd0
callq 0x4250
jmp 0x1cad6
xorl %edi, %edi
leaq -0x124(%rbp), %rsi
leaq -0x128(%rbp), %rdx
callq 0x38180
jmp 0x1caed
movl -0x128(%rbp), %eax
movl %eax, -0x12c(%rbp)
movl -0x12c(%rbp), %eax
cmpl -0x38(%rbp), %eax
jge 0x1cbfa
movl -0x124(%rbp), %eax
movl %eax, -0x130(%rbp)
movl -0x130(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0x1cbe4
movq -0x30(%rbp), %rdi
movl -0x130(%rbp), %esi
movl -0x12c(%rbp), %edx
callq 0x1d980
movq %rax, -0x218(%rbp)
jmp 0x1cb41
movq -0x218(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x228(%rbp)
movq -0x20(%rbp), %rdi
movl -0x130(%rbp), %esi
movl -0x12c(%rbp), %edx
callq 0x16fd0
movq %rax, -0x220(%rbp)
jmp 0x1cb72
movq -0x220(%rbp), %rax
movsd -0x228(%rbp), %xmm0
movsd %xmm0, (%rax)
movl -0x130(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x130(%rbp)
jmp 0x1cb14
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x1cd1e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x108(%rbp), %rdi
callq 0xe260
jmp 0x1cd1e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x120(%rbp), %rdi
callq 0xe260
jmp 0x1cd1e
jmp 0x1cbe6
movl -0x12c(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x12c(%rbp)
jmp 0x1caf9
movl $0x2, %edi
leaq -0x124(%rbp), %rsi
leaq -0x128(%rbp), %rdx
callq 0x38180
jmp 0x1cc14
movl -0x128(%rbp), %eax
movl %eax, -0x134(%rbp)
movl -0x134(%rbp), %eax
cmpl -0x38(%rbp), %eax
jge 0x1cccf
movl -0x124(%rbp), %eax
movl %eax, -0x138(%rbp)
movl -0x138(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0x1ccb9
movq 0x10(%rbp), %rdi
movl -0x138(%rbp), %esi
movl -0x134(%rbp), %edx
callq 0x1d980
movq %rax, -0x230(%rbp)
jmp 0x1cc64
movq -0x230(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x240(%rbp)
movq -0x28(%rbp), %rdi
movl -0x138(%rbp), %esi
movl -0x134(%rbp), %edx
callq 0x16fd0
movq %rax, -0x238(%rbp)
jmp 0x1cc95
movq -0x238(%rbp), %rax
movsd -0x240(%rbp), %xmm0
movsd %xmm0, (%rax)
movl -0x138(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x138(%rbp)
jmp 0x1cc3b
jmp 0x1ccbb
movl -0x134(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x134(%rbp)
jmp 0x1cc20
leaq -0xe8(%rbp), %rdi
callq 0xe260
leaq -0xc8(%rbp), %rdi
callq 0xe260
leaq -0xb0(%rbp), %rdi
callq 0xe260
leaq -0x98(%rbp), %rdi
callq 0xe260
leaq -0x70(%rbp), %rdi
callq 0xe260
leaq -0x58(%rbp), %rdi
callq 0xe260
movb $0x1, %al
andb $0x1, %al
addq $0x240, %rsp            # imm = 0x240
popq %rbp
retq
leaq -0xe8(%rbp), %rdi
callq 0xe260
leaq -0xc8(%rbp), %rdi
callq 0xe260
leaq -0xb0(%rbp), %rdi
callq 0xe260
leaq -0x98(%rbp), %rdi
callq 0xe260
leaq -0x70(%rbp), %rdi
callq 0xe260
leaq -0x58(%rbp), %rdi
callq 0xe260
movq -0x78(%rbp), %rdi
callq 0x4620
nopl (%rax)