// File: /workspace/github_cpp_makefile_star2_O3/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, 0x1f02d(%rip)     # 0x39b98
jne 0x1acb5
pushq %rax
movb $0x1, 0x1f01f(%rip)     # 0x39b98
callq 0x1b4f6
leaq 0x1ef23(%rip), %rdi     # 0x39aa8
leaq 0x12810(%rip), %rsi     # 0x2d39c
callq 0x30c0
testl %eax, %eax
jne 0x1ac0d
movq 0x1ef94(%rip), %rax     # 0x39b30
movq 0x1ef85(%rip), %rcx     # 0x39b28
xorl %edx, %edx
movsd 0x125f3(%rip), %xmm0    # 0x2d1a0
movsd 0x125f3(%rip), %xmm1    # 0x2d1a8
leaq 0x1ef64(%rip), %rsi     # 0x39b20
movsd 0x125ec(%rip), %xmm2    # 0x2d1b0
xorl %edi, %edi
movq %rcx, %r8
movapd %xmm0, %xmm3
cmpl $0x1, %edx
je 0x1abe8
cmpl $0x2, %edx
jne 0x1abe0
movq %rax, %r8
movapd %xmm1, %xmm3
jmp 0x1abe8
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 0x1abc6
incq %rdx
cmpq $0x7, %rdx
jne 0x1abc4
leaq 0x1ee94(%rip), %rdi     # 0x39aa8
leaq 0x12615(%rip), %rsi     # 0x2d230
callq 0x30c0
testl %eax, %eax
jne 0x1ac4f
movq 0x1ef05(%rip), %rax     # 0x39b30
xorl %ecx, %ecx
movsd 0xf413(%rip), %xmm0     # 0x2a048
movsd (%rax,%rcx,8), %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, (%rax,%rcx,8)
incq %rcx
cmpq $0x121, %rcx            # imm = 0x121
jne 0x1ac35
xorl %eax, %eax
leaq 0x1eea8(%rip), %rcx     # 0x39b00
leaq 0x1eec1(%rip), %rdx     # 0x39b20
leaq 0x1eefa(%rip), %rsi     # 0x39b60
movl (%rcx,%rax,4), %r8d
testl %r8d, %r8d
je 0x1aca8
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 0x1ac91
incq %rax
cmpq $0x7, %rax
jne 0x1ac66
addq $0x8, %rsp
retq