// File: /workspace/github_cpp_makefile_star2_O2/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, 0x1d8bf(%rip)     # 0x32b88
jne 0x15410
pushq %rax
movb $0x1, 0x1d8b1(%rip)     # 0x32b88
callq 0x15bc4
leaq 0x1d7b5(%rip), %rdi     # 0x32a98
leaq 0x10052(%rip), %rsi     # 0x2533c
callq 0x80ee
testb %al, %al
je 0x1536f
movq 0x1d826(%rip), %rax     # 0x32b20
movq 0x1d817(%rip), %rcx     # 0x32b18
xorl %edx, %edx
movsd 0xfe65(%rip), %xmm0     # 0x25170
movsd 0xfe65(%rip), %xmm1     # 0x25178
leaq 0x1d7f6(%rip), %rsi     # 0x32b10
movsd 0xfe5e(%rip), %xmm2     # 0x25180
cmpq $0x7, %rdx
je 0x1536f
xorl %edi, %edi
cmpq $0x121, %rdi            # imm = 0x121
je 0x1536a
movq %rcx, %r8
movapd %xmm0, %xmm3
cmpl $0x1, %edx
je 0x15355
cmpl $0x2, %edx
jne 0x1534d
movq %rax, %r8
movapd %xmm1, %xmm3
jmp 0x15355
movq (%rsi,%rdx,8), %r8
movapd %xmm2, %xmm3
movsd (%r8,%rdi,8), %xmm4
divsd %xmm3, %xmm4
movsd %xmm4, (%r8,%rdi,8)
incq %rdi
jmp 0x1532a
incq %rdx
jmp 0x15322
leaq 0x1d722(%rip), %rdi     # 0x32a98
leaq 0xfe53(%rip), %rsi      # 0x251d0
callq 0x80ee
testb %al, %al
je 0x153b3
movq 0x1d793(%rip), %rax     # 0x32b20
xorl %ecx, %ecx
movsd 0xccb1(%rip), %xmm0     # 0x22048
cmpq $0x121, %rcx            # imm = 0x121
je 0x153b3
movsd (%rax,%rcx,8), %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, (%rax,%rcx,8)
incq %rcx
jmp 0x15397
xorl %eax, %eax
leaq 0x1d734(%rip), %rcx     # 0x32af0
leaq 0x1d74d(%rip), %rdx     # 0x32b10
leaq 0x1d786(%rip), %rsi     # 0x32b50
cmpq $0x7, %rax
je 0x1540c
movl (%rcx,%rax,4), %edi
imull %edi, %edi
leaq (,%rdi,8), %r8
decl %edi
xorl %r9d, %r9d
cmpq %r9, %r8
je 0x15407
movq (%rdx,%rax,8), %r10
movslq %edi, %rdi
movsd (%r10,%rdi,8), %xmm0
movq (%rsi,%rax,8), %r10
movsd %xmm0, (%r10,%r9)
addq $0x8, %r9
decl %edi
jmp 0x153e3
incq %rax
jmp 0x153ca
addq $0x8, %rsp
retq
nop