// File: /workspace/github_cpp_makefile_star2_O1/kebwi[P]Trifid/src/SteerablePyramid.cpp
// Function: SteerablePyramid::InitFilters()
void SteerablePyramid::InitFilters()
{
	//Only init the filters once
	static bool alreadyInited = false;
	if (alreadyInited)
		return;
	alreadyInited = true;
	
	readFilterSet();
	
	//Normalize the filters
	//This is definitely required for the first filter set, which is defined using integers
	//I am unsure why the third filter set used an L0 and L1 that sum to 2 instead of 1.  Perhaps normalizing them is not correct.
	/*
	for (int filter = 0; filter < 7; filter++)
	{
		Float_t divisor = 0;
		int numTaps = skFilterDims[filter] * skFilterDims[filter];
		for (int i = 0; i < numTaps; i++)
			divisor += fabs(skFilters[filter][i]);
		cout << "Filter " << filter << " has " << numTaps << " taps with sum: " << divisor << endl;
		for (int i = 0; i < numTaps; i++)
			skFilters[filter][i] /= divisor;
	}
	cout << endl;
	*/
	if (skFilterSetFilename == "filterSet1.txt")
	{
		//The filters are integers with power 10000.
		//Therefore they must be scaled by 1/10000 to achieve unit power.
		//Note, however, that L0 and L1 do not quite sum to 10000.
		//Therefore, they are scaled slightly differently.
		for (int filter = 0; filter < 7; filter++)
		{
			for (int i = 0; i < 289; i++)
			{
				if (filter == 1)
					skFilters[filter][i] /= 9996.0;
				else if (filter == 2)
					skFilters[filter][i] /= 10005.0;
				else skFilters[filter][i] /= 10000.0;
			}
		}
	}
	if (skFilterSetFilename == "steerablePyramidFilterSet.txt")
	{
		//H0 sums to 0
		//L0 and L1 sum to 2
		//B1-4 sum to 0
		//To get correct reconstruction, it is necessary to scale just L1 to unit power but to leave L0 at power 2.  Why?
		for (int i = 0; i < 289; i++)
			skFilters[2][i] /= 2.0;
	}
	
	//Define the inverted filters
	for (int filter = 0; filter < 7; filter++)
	{
		int numTaps = skFilterDims[filter] * skFilterDims[filter];
		for (int i = 0; i < numTaps; i++)
			skFiltersInv[filter][i] = skFilters[filter][(numTaps - 1) - i];
	}
}

// Assembly:
cmpb $0x0, 0x1eba1(%rip)     # 0x39b98
jne 0x1b141
pushq %rax
movb $0x1, 0x1eb93(%rip)     # 0x39b98
callq 0x1b9e2
leaq 0x1ea97(%rip), %rdi     # 0x39aa8
leaq 0x1331c(%rip), %rsi     # 0x2e334
callq 0x30c0
testl %eax, %eax
jne 0x1b099
movq 0x1eb08(%rip), %rax     # 0x39b30
movq 0x1eaf9(%rip), %rcx     # 0x39b28
xorl %edx, %edx
movsd 0x1312f(%rip), %xmm0    # 0x2e168
movsd 0x1312f(%rip), %xmm1    # 0x2e170
leaq 0x1ead8(%rip), %rsi     # 0x39b20
movsd 0x13128(%rip), %xmm2    # 0x2e178
xorl %edi, %edi
movq %rcx, %r8
movapd %xmm0, %xmm3
cmpl $0x1, %edx
je 0x1b074
cmpl $0x2, %edx
jne 0x1b06c
movq %rax, %r8
movapd %xmm1, %xmm3
jmp 0x1b074
movq (%rsi,%rdx,8), %r8
movapd %xmm2, %xmm3
movsd (%r8,%rdi,8), %xmm4
divsd %xmm3, %xmm4
movsd %xmm4, (%r8,%rdi,8)
incq %rdi
cmpq $0x121, %rdi            # imm = 0x121
jne 0x1b052
incq %rdx
cmpq $0x7, %rdx
jne 0x1b050
leaq 0x1ea08(%rip), %rdi     # 0x39aa8
leaq 0x13121(%rip), %rsi     # 0x2e1c8
callq 0x30c0
testl %eax, %eax
jne 0x1b0db
movq 0x1ea79(%rip), %rax     # 0x39b30
xorl %ecx, %ecx
movsd 0xff87(%rip), %xmm0     # 0x2b048
movsd (%rax,%rcx,8), %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, (%rax,%rcx,8)
incq %rcx
cmpq $0x121, %rcx            # imm = 0x121
jne 0x1b0c1
xorl %eax, %eax
leaq 0x1ea1c(%rip), %rcx     # 0x39b00
leaq 0x1ea35(%rip), %rdx     # 0x39b20
leaq 0x1ea6e(%rip), %rsi     # 0x39b60
movl (%rcx,%rax,4), %r8d
testl %r8d, %r8d
je 0x1b134
imull %r8d, %r8d
movq (%rdx,%rax,8), %r9
movq (%rsi,%rax,8), %rdi
movslq %r8d, %r10
cmpl $0x1, %r10d
leaq -0x8(%r9,%r10,8), %r8
movl %r10d, %r9d
adcl $0x0, %r9d
xorl %r10d, %r10d
movsd (%r8), %xmm0
movsd %xmm0, (%rdi,%r10,8)
incq %r10
addq $-0x8, %r8
cmpq %r10, %r9
jne 0x1b11d
incq %rax
cmpq $0x7, %rax
jne 0x1b0f2
addq $0x8, %rsp
retq