// File: kebwi[P]Trifid/src/DebayerProcs.cpp
// Function: hue_constructGreenChannelEdgeSensitive(ImageReal&, Image3ChnlReal&, int, int)
void hue_constructGreenChannelEdgeSensitive(
	ImageReal &grayImage, Image3ChnlReal &rgbImage,
	int x, int y)
{
	assert(determineBayerColor(x, y) != G);
	
	//Use bilinear interpolation along the edges of the image
	if (x == 0 || y == 0 || x == grayImage.width() - 1 || y == grayImage.height() - 1)
		return hue_constructGreenChannel(grayImage, rgbImage, x, y);
	
	//Use only two of the surrounding four green pixels to interpolate,
	//either the two horizontal neighbors or the two vertical neighbors,
	//depending on which pair preserves the edge best, i.e., interpolate
	//along the edge instead of across it.  If there is no edge here,
	//use all four pixels, i.e., bilinear interpolation.
	
	Float_t horDiff = grayImage(x - 1, y) - grayImage(x + 1, y);
	if (horDiff < 0)
		horDiff = -horDiff;
	Float_t verDiff = grayImage(x, y - 1) - grayImage(x, y + 1);
	if (verDiff < 0)
		verDiff = -verDiff;
	
	//If the horizontal and vertical differences are similar, then assume no edge and bilinear interpolate.
	//For unnoisy lena128, edgeRatioThreshold=.25 yields the best PSNR and edgeRatioThreshold=.75 yields
	//the best lab delta error.  Nonedge hue yields better PSNR than .75, but worst lab delta error than
	//either .25 or .75.  Overall, I like the appearance .75 best. Not sure if this will hold for other
	//images or for noisy bayered images.
	Float_t edgeRatioThreshold = .75;
	if ((horDiff < verDiff && horDiff > verDiff * edgeRatioThreshold) ||
		(verDiff < horDiff && verDiff > horDiff * edgeRatioThreshold))
		return hue_constructGreenChannel(grayImage, rgbImage, x, y);
	
	Float_t colorL = 0;
	if (horDiff < verDiff)	//The edge is vertical, so interpolate horizontally
	{
		colorL += grayImage(x - 1, y);
		colorL += grayImage(x + 1, y);
	}
	else if (verDiff < horDiff)	//The edge is horizontal, so interpolate vertically
	{
		colorL += grayImage(x, y - 1);
		colorL += grayImage(x, y + 1);
	}
	else return hue_constructGreenChannel(grayImage, rgbImage, x, y);
	
	rgbImage(G, x, y) = colorL / 2.0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movl -0x14(%rbp), %edi
movl -0x18(%rbp), %esi
callq 0x380a0
cmpl $0x1, %eax
je 0x1a878
jmp 0x1a897
leaq 0x2fdab(%rip), %rdi     # 0x4a62a
leaq 0x2fcea(%rip), %rsi     # 0x4a570
movl $0x179, %edx            # imm = 0x179
leaq 0x2fdff(%rip), %rcx     # 0x4a691
callq 0x4240
cmpl $0x0, -0x14(%rbp)
je 0x1a8d9
cmpl $0x0, -0x18(%rbp)
je 0x1a8d9
movl -0x14(%rbp), %eax
movl %eax, -0x3c(%rbp)
movq -0x8(%rbp), %rdi
callq 0xedd0
movl %eax, %ecx
movl -0x3c(%rbp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
je 0x1a8d9
movl -0x18(%rbp), %eax
movl %eax, -0x40(%rbp)
movq -0x8(%rbp), %rdi
callq 0xedf0
movl %eax, %ecx
movl -0x40(%rbp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x1a8f1
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
callq 0x1a6b0
jmp 0x1ab22
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
subl $0x1, %esi
movl -0x18(%rbp), %edx
callq 0x16fd0
movsd (%rax), %xmm0
movsd %xmm0, -0x48(%rbp)
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
addl $0x1, %esi
movl -0x18(%rbp), %edx
callq 0x16fd0
movsd -0x48(%rbp), %xmm0
subsd (%rax), %xmm0
movsd %xmm0, -0x20(%rbp)
xorps %xmm0, %xmm0
ucomisd -0x20(%rbp), %xmm0
jbe 0x1a957
movsd -0x20(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
subl $0x1, %edx
callq 0x16fd0
movsd (%rax), %xmm0
movsd %xmm0, -0x50(%rbp)
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
addl $0x1, %edx
callq 0x16fd0
movsd -0x50(%rbp), %xmm0
subsd (%rax), %xmm0
movsd %xmm0, -0x28(%rbp)
xorps %xmm0, %xmm0
ucomisd -0x28(%rbp), %xmm0
jbe 0x1a9bd
movsd -0x28(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, -0x28(%rbp)
movsd 0x2fb7b(%rip), %xmm0    # 0x4a540
movsd %xmm0, -0x30(%rbp)
movsd -0x20(%rbp), %xmm1
movsd -0x28(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1a9ef
movsd -0x20(%rbp), %xmm0
movsd -0x28(%rbp), %xmm1
mulsd -0x30(%rbp), %xmm1
ucomisd %xmm1, %xmm0
ja 0x1aa14
movsd -0x28(%rbp), %xmm1
movsd -0x20(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1aa2c
movsd -0x28(%rbp), %xmm0
movsd -0x20(%rbp), %xmm1
mulsd -0x30(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1aa2c
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
callq 0x1a6b0
jmp 0x1ab22
xorps %xmm0, %xmm0
movsd %xmm0, -0x38(%rbp)
movsd -0x20(%rbp), %xmm1
movsd -0x28(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1aa86
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
subl $0x1, %esi
movl -0x18(%rbp), %edx
callq 0x16fd0
movsd (%rax), %xmm0
addsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
addl $0x1, %esi
movl -0x18(%rbp), %edx
callq 0x16fd0
movsd (%rax), %xmm0
addsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
jmp 0x1aaef
movsd -0x28(%rbp), %xmm1
movsd -0x20(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1aad8
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
subl $0x1, %edx
callq 0x16fd0
movsd (%rax), %xmm0
addsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
addl $0x1, %edx
callq 0x16fd0
movsd (%rax), %xmm0
addsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
jmp 0x1aaed
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
callq 0x1a6b0
jmp 0x1ab22
jmp 0x1aaef
movsd -0x38(%rbp), %xmm0
movsd 0x2fa4c(%rip), %xmm1    # 0x4a548
divsd %xmm1, %xmm0
movsd %xmm0, -0x58(%rbp)
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movl $0x1, %esi
callq 0x17990
movsd -0x58(%rbp), %xmm0
movsd %xmm0, (%rax)
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax,%rax)