// File: kebwi[P]Trifid/src/SteerablePyramid.cpp
// Function: SteerablePyramid::DoFullWaveletSynthesis(double*)
void SteerablePyramid::DoFullWaveletSynthesis(Float_t* pixelValues)
{
	assert(width_ > 0 && height_ > 0);
	
	gT1 = getCurrentTime_ms();
	gT2 = gT3 = gT4 = gT5 = 0;
	
	int totalPixels = width_ * height_;
	
	//Allocate some scratch storage outside the levels loop so it doesn't have to be allocated each time through the loop
	gT4 = getCurrentTime_ms();
	Float_t *upsampledThumbnail = new Float_t[totalPixels];
	gT4 = getCurrentTime_ms() - gT4;
	
	//It shouldn't be necessary to erase the output image here.
	//memset(pixelValues, 0, totalPixels * sizeof(Float_t));
	
	//cout << "  Performing synthesis with " << numLevels_ << " levels" <<  endl;
	for (int i = numLevels_ - 1; i >= 0; i--)
	{
		//cout << "    Synthesizing level " << i << "..." << endl;
		if (!useFTconvolution_)
			DoOneStepWaveletSynthesis(i, pixelValues, upsampledThumbnail);
		else DoOneStepWaveletSynthesisUsingFT(i, pixelValues, upsampledThumbnail);
	}
	/*
	Float_t minPixel = 999999, maxPixel = -999999;
	for (int i = 0; i < totalPixels; i++)
	{
		if (pixelValues[i] < minPixel)
			minPixel = pixelValues[i];
		if (pixelValues[i] > maxPixel)
			maxPixel = pixelValues[i];
	}
	cout << "Synthesis Min/Max Pixels: " << minPixel << "    " << maxPixel << endl;
	*/
	//cout << "  Clipping image" << endl;
	for (int i = 0; i < totalPixels; i++)
		if (pixelValues[i] < 0)
			pixelValues[i] = 0;
		else if (pixelValues[i] > 1.0)
			pixelValues[i] = 1.0;
	/*
	maxPixel = -999999;
	for (int i = 0; i < totalPixels; i++)
		if (pixelValues[i] > maxPixel)
			maxPixel = pixelValues[i];
	string filename = "aaaUpsampleFilteredFinalClipped.pgm";
	GeneratePGMimage(pixelValues, width_, height_, 255.0 / maxPixel, 0, filename);
	*/
	//cout << "  Cleaning up" << endl;
	gT5 = getCurrentTime_ms();
	delete [] upsampledThumbnail;
	gT5 = getCurrentTime_ms() - gT5;
	
	//cout << "  Done" << endl;
	
	gT1 = getCurrentTime_ms() - gT1;
	Float_t t1Secs = (Float_t)gT1 / CURRENT_TIME_PER_SEC_F;
	Float_t t2Secs = (Float_t)gT2 / CURRENT_TIME_PER_SEC_F;
	Float_t t3Secs = (Float_t)gT3 / CURRENT_TIME_PER_SEC_F;
	Float_t t4Secs = (Float_t)gT4 / CURRENT_TIME_PER_SEC_F;
	Float_t t5Secs = (Float_t)gT5 / CURRENT_TIME_PER_SEC_F;
	Float_t t2Fraction = (Float_t)gT2 / (Float_t)gT1;
	Float_t t3Fraction = (Float_t)gT3 / (Float_t)gT1;
	Float_t t4Fraction = (Float_t)gT4 / (Float_t)gT1;
	Float_t t5Fraction = (Float_t)gT5 / (Float_t)gT1;
	/*
	cout << "  Times:" << endl;
	cout << "    Total: " << t1Secs << endl;
	cout << "    T2: ";
	cout << setw(10) << t2Secs << "   Ratio: ";
	cout << setw(10) << t2Fraction << endl;
	cout << "    T3: ";
	cout << setw(10) << t3Secs << "   Ratio: ";
	cout << setw(10) << t3Fraction << endl;
	cout << "    T4: ";
	cout << setw(10) << t4Secs << "   Ratio: ";
	cout << setw(10) << t4Fraction << endl;
	cout << "    T5: ";
	cout << setw(10) << t5Secs << "   Ratio: ";
	cout << setw(10) << t5Fraction << endl;
	*/
	//cout << "  St2 " << t2Fraction << "  St3 " << t3Fraction << "  ";
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rcx
movq %rcx, -0x80(%rbp)
xorl %eax, %eax
cmpl $0x0, 0x30(%rcx)
movb %al, -0x71(%rbp)
jle 0x2e284
movq -0x80(%rbp), %rax
cmpl $0x0, 0x34(%rax)
setg %al
movb %al, -0x71(%rbp)
movb -0x71(%rbp), %al
testb $0x1, %al
jne 0x2e28d
jmp 0x2e28f
jmp 0x2e2ae
leaq 0x1eefb(%rip), %rdi     # 0x4d191
leaq 0x1e0b9(%rip), %rsi     # 0x4c356
movl $0x5a8, %edx            # imm = 0x5A8
leaq 0x1ef02(%rip), %rcx     # 0x4d1ab
callq 0x4240
callq 0x55c0
movq -0x80(%rbp), %rcx
movq %rax, 0x2e9c2(%rip)     # 0x5cc80
movq $0x0, 0x2e9bf(%rip) # 0x5cc88
movq $0x0, 0x2e9bc(%rip) # 0x5cc90
movq $0x0, 0x2e999(%rip) # 0x5cc78
movq $0x0, 0x2e986(%rip) # 0x5cc70
movl 0x30(%rcx), %eax
imull 0x34(%rcx), %eax
movl %eax, -0x14(%rbp)
callq 0x55c0
movq %rax, 0x2e990(%rip)     # 0x5cc90
movslq -0x14(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x4030
movq %rax, -0x20(%rbp)
callq 0x55c0
movq %rax, %rcx
movq -0x80(%rbp), %rax
subq 0x2e954(%rip), %rcx     # 0x5cc90
movq %rcx, 0x2e94d(%rip)     # 0x5cc90
movl 0x38(%rax), %eax
subl $0x1, %eax
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jl 0x2e393
movq -0x80(%rbp), %rax
testb $0x1, 0x48(%rax)
jne 0x2e372
movq -0x80(%rbp), %rdi
movl -0x24(%rbp), %esi
movq -0x10(%rbp), %rdx
movq -0x20(%rbp), %rcx
callq 0x2d5e0
jmp 0x2e386
movq -0x80(%rbp), %rdi
movl -0x24(%rbp), %esi
movq -0x10(%rbp), %rdx
movq -0x20(%rbp), %rcx
callq 0x2d9a0
jmp 0x2e388
movl -0x24(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x2e34c
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x2e405
movq -0x10(%rbp), %rax
movslq -0x28(%rbp), %rcx
xorps %xmm0, %xmm0
ucomisd (%rax,%rcx,8), %xmm0
jbe 0x2e3c6
movq -0x10(%rbp), %rax
movslq -0x28(%rbp), %rcx
xorps %xmm0, %xmm0
movsd %xmm0, (%rax,%rcx,8)
jmp 0x2e3f8
movq -0x10(%rbp), %rax
movslq -0x28(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd 0x1ac45(%rip), %xmm1    # 0x49020
ucomisd %xmm1, %xmm0
jbe 0x2e3f6
movq -0x10(%rbp), %rax
movslq -0x28(%rbp), %rcx
movsd 0x1ac2f(%rip), %xmm0    # 0x49020
movsd %xmm0, (%rax,%rcx,8)
jmp 0x2e3f8
jmp 0x2e3fa
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x2e39a
callq 0x55c0
movq %rax, 0x2e877(%rip)     # 0x5cc88
movq -0x20(%rbp), %rax
movq %rax, -0x88(%rbp)
cmpq $0x0, %rax
je 0x2e42e
movq -0x88(%rbp), %rdi
callq 0x44d0
callq 0x55c0
movq 0x2e84e(%rip), %rcx     # 0x5cc88
subq %rcx, %rax
movq %rax, 0x2e844(%rip)     # 0x5cc88
callq 0x55c0
movq 0x2e830(%rip), %rcx     # 0x5cc80
subq %rcx, %rax
movq %rax, 0x2e826(%rip)     # 0x5cc80
movq 0x2e81e(%rip), %xmm0    # 0x5cc80
movaps 0x1abe7(%rip), %xmm3    # 0x49050
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
movapd 0x1abeb(%rip), %xmm2    # 0x49060
subpd %xmm2, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movsd 0x1d794(%rip), %xmm1    # 0x4bc20
divsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rbp)
movq 0x2e7d3(%rip), %xmm0    # 0x5cc70
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
subpd %xmm2, %xmm0
movaps %xmm0, %xmm4
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm4, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rbp)
movq 0x2e7b7(%rip), %xmm0    # 0x5cc78
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
subpd %xmm2, %xmm0
movaps %xmm0, %xmm4
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm4, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
movq 0x2e7ab(%rip), %xmm0    # 0x5cc90
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
subpd %xmm2, %xmm0
movaps %xmm0, %xmm4
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm4, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x48(%rbp)
movq 0x2e77f(%rip), %xmm0    # 0x5cc88
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
subpd %xmm2, %xmm0
movaps %xmm0, %xmm4
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm4, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x50(%rbp)
movq 0x2e743(%rip), %xmm0    # 0x5cc70
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
subpd %xmm2, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movq 0x2e738(%rip), %xmm1    # 0x5cc80
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm4
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm4, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x58(%rbp)
movq 0x2e70c(%rip), %xmm0    # 0x5cc78
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
subpd %xmm2, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movq 0x2e6f9(%rip), %xmm1    # 0x5cc80
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm4
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm4, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x60(%rbp)
movq 0x2e6e5(%rip), %xmm0    # 0x5cc90
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
subpd %xmm2, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movq 0x2e6ba(%rip), %xmm1    # 0x5cc80
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm4
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm4, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x68(%rbp)
movq 0x2e69e(%rip), %xmm0    # 0x5cc88
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
subpd %xmm2, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movq 0x2e67b(%rip), %xmm1    # 0x5cc80
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x70(%rbp)
addq $0x90, %rsp
popq %rbp
retq
nopw (%rax,%rax)