// File: spatialfruitsalad[P]volume2position/./bilateral.hpp
// Function: bilateralFilter::bilateralFilter(unsigned int, double, double)
bilateralFilter(unsigned int masksize, double sigma, double similarity) : m_masksize(masksize), m_sigma(sigma), m_sigmaSimilarity(similarity)
    {
        std::cout << "creating bilateral Filter with parameters:" << std::endl;
        std::cout << "\tmasksize = " << masksize << "\n\tsigma = " << sigma << "\n\tsimilarity = " << similarity;
        // initial checks
        if(masksize <= 1)
        {
            throw std::string("bilateral filter: masksize must be larger than 1!");
        }
        if (sigma <= 0 || similarity <= 0)
        {
            throw std::string("bilateral filter: sigma/similarity must be larger than 0");
        }


        // create mask
        tol = (m_masksize-1)/2;
        std::cout << "\n\ttol = " << tol << std::endl;
        mask.initialise (masksize, masksize, masksize, 0);
        double sum = 0;
        
        // precalculate gaussian mask (this speeds up the process alot
        for (unsigned int k = 0; k != masksize; ++k)
        {
            for (unsigned int j = 0; j != masksize; ++j)
            {
                for (unsigned int i = 0; i != masksize; ++i)
                {
                    double distance_square = (i-tol)*(i-tol) + (j-tol)*(j-tol) + (k-tol)*(k-tol);
                    double val = exp(-1*distance_square/(2*m_sigma*m_sigma));
                    mask.set(i,j,k, val);
                    sum += val;
                }
            }
        }

        // creating gauss table (also a big speedup)
        double x0 = 0;
        double x1 = 4 * m_sigmaSimilarity; // dumb cutoff

        // prerendered version of the gauss
        unsigned int steps = 500;
        double dx = (x1 - x0)/static_cast<double>(steps + 1);
        for (double x = x0; x <= x1; x += dx)
        {
            gaussTable.push_back(gauss(m_sigmaSimilarity, x));
        }

    }

// Assembly:
subq $0x128, %rsp            # imm = 0x128
movq %rdi, 0x120(%rsp)
movl %esi, 0x11c(%rsp)
movsd %xmm0, 0x110(%rsp)
movsd %xmm1, 0x108(%rsp)
movq 0x120(%rsp), %rdi
movq %rdi, 0x88(%rsp)
movl 0x11c(%rsp), %eax
movl %eax, (%rdi)
movsd 0x110(%rsp), %xmm0
movsd %xmm0, 0x8(%rdi)
movsd 0x108(%rsp), %xmm0
movsd %xmm0, 0x10(%rdi)
addq $0x20, %rdi
movq %rdi, 0x80(%rsp)
callq 0xfe90
movq 0x88(%rsp), %rdi
addq $0x50, %rdi
movq %rdi, 0x90(%rsp)
callq 0x9270
movq 0x2cd22(%rip), %rdi     # 0x33fc0
leaq 0x21284(%rip), %rsi     # 0x28529
callq 0x3290
movq %rax, 0x98(%rsp)
jmp 0x72b4
movq 0x98(%rsp), %rdi
movq 0x2ccdd(%rip), %rsi     # 0x33fa0
callq 0x32c0
jmp 0x72ca
movq 0x2ccef(%rip), %rdi     # 0x33fc0
leaq 0x2127c(%rip), %rsi     # 0x28554
callq 0x3290
movq %rax, 0x78(%rsp)
jmp 0x72e4
movq 0x78(%rsp), %rdi
movl 0x11c(%rsp), %esi
callq 0x3350
movq %rax, 0x70(%rsp)
jmp 0x72fc
movq 0x70(%rsp), %rdi
leaq 0x21259(%rip), %rsi     # 0x28561
callq 0x3290
movq %rax, 0x68(%rsp)
jmp 0x7314
movq 0x68(%rsp), %rdi
movsd 0x110(%rsp), %xmm0
callq 0x34e0
movq %rax, 0x60(%rsp)
jmp 0x732e
movq 0x60(%rsp), %rdi
leaq 0x21232(%rip), %rsi     # 0x2856c
callq 0x3290
movq %rax, 0x58(%rsp)
jmp 0x7346
movq 0x58(%rsp), %rdi
movsd 0x108(%rsp), %xmm0
callq 0x34e0
jmp 0x735b
cmpl $0x1, 0x11c(%rsp)
ja 0x7429
movb $0x1, 0xfa(%rsp)
movl $0x20, %edi
callq 0x3150
movq %rax, 0x48(%rsp)
movq %rax, 0x40(%rsp)
leaq 0xfb(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0x34b0
movq 0x48(%rsp), %rdi
movq 0x50(%rsp), %rdx
leaq 0x211d4(%rip), %rsi     # 0x2857c
callq 0x3360
jmp 0x73af
movq 0x40(%rsp), %rdi
movb $0x0, 0xfa(%rsp)
leaq 0x2c9b5(%rip), %rsi     # 0x33d78
movq 0x2cbde(%rip), %rdx     # 0x33fa8
callq 0x3460
jmp 0x781e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x100(%rsp)
movl %eax, 0xfc(%rsp)
jmp 0x77f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x100(%rsp)
movl %eax, 0xfc(%rsp)
leaq 0xfb(%rsp), %rdi
callq 0x32d0
testb $0x1, 0xfa(%rsp)
jne 0x741a
jmp 0x7424
movq 0x40(%rsp), %rdi
callq 0x3210
jmp 0x77f7
xorps %xmm0, %xmm0
ucomisd 0x110(%rsp), %xmm0
jae 0x7449
xorps %xmm0, %xmm0
ucomisd 0x108(%rsp), %xmm0
jb 0x74f0
movb $0x1, 0xf8(%rsp)
movl $0x20, %edi
callq 0x3150
movq %rax, 0x30(%rsp)
movq %rax, 0x28(%rsp)
leaq 0xf9(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x34b0
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rdx
leaq 0x21126(%rip), %rsi     # 0x285ae
callq 0x3360
jmp 0x748f
movq 0x28(%rsp), %rdi
movb $0x0, 0xf8(%rsp)
leaq 0x2c8d5(%rip), %rsi     # 0x33d78
movq 0x2cafe(%rip), %rdx     # 0x33fa8
callq 0x3460
jmp 0x781e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x100(%rsp)
movl %eax, 0xfc(%rsp)
leaq 0xf9(%rsp), %rdi
callq 0x32d0
testb $0x1, 0xf8(%rsp)
jne 0x74e1
jmp 0x74eb
movq 0x28(%rsp), %rdi
callq 0x3210
jmp 0x77f7
movq 0x88(%rsp), %rax
movl (%rax), %ecx
decl %ecx
shrl %ecx
movl %ecx, 0x18(%rax)
movq 0x2cab8(%rip), %rdi     # 0x33fc0
leaq 0x210d8(%rip), %rsi     # 0x285e7
callq 0x3290
movq %rax, 0x20(%rsp)
jmp 0x751b
movq 0x20(%rsp), %rdi
movq 0x88(%rsp), %rax
movl 0x18(%rax), %esi
callq 0x3470
movq %rax, 0x18(%rsp)
jmp 0x7537
movq 0x18(%rsp), %rdi
movq 0x2ca5d(%rip), %rsi     # 0x33fa0
callq 0x32c0
jmp 0x754a
movq 0x88(%rsp), %rdi
addq $0x20, %rdi
movl 0x11c(%rsp), %eax
movl %eax, %ecx
xorps %xmm0, %xmm0
movq %rcx, %rsi
movq %rcx, %rdx
callq 0xfea0
jmp 0x756f
xorps %xmm0, %xmm0
movsd %xmm0, 0xf0(%rsp)
movl $0x0, 0xec(%rsp)
movl 0xec(%rsp), %eax
cmpl 0x11c(%rsp), %eax
je 0x76e7
movl $0x0, 0xe8(%rsp)
movl 0xe8(%rsp), %eax
cmpl 0x11c(%rsp), %eax
je 0x76cf
movl $0x0, 0xe4(%rsp)
movl 0xe4(%rsp), %eax
cmpl 0x11c(%rsp), %eax
je 0x76b7
movq 0x88(%rsp), %rax
movl 0xe4(%rsp), %ecx
movl 0x18(%rax), %esi
subl %esi, %ecx
imull %ecx, %ecx
movl 0xe8(%rsp), %edx
subl %esi, %edx
imull %edx, %edx
addl %edx, %ecx
movl 0xec(%rsp), %edx
subl %esi, %edx
imull %edx, %edx
addl %edx, %ecx
cvtsi2sd %rcx, %xmm0
movsd %xmm0, 0xd8(%rsp)
movaps 0x20a90(%rip), %xmm1    # 0x280b0
movsd 0xd8(%rsp), %xmm0
pxor %xmm1, %xmm0
movsd 0x8(%rax), %xmm2
movaps %xmm2, %xmm1
addsd %xmm1, %xmm1
mulsd %xmm2, %xmm1
divsd %xmm1, %xmm0
callq 0x34c0
movq 0x88(%rsp), %rdi
movsd %xmm0, 0xd0(%rsp)
addq $0x20, %rdi
movl 0xe4(%rsp), %eax
movl %eax, %esi
movl 0xe8(%rsp), %eax
movl %eax, %edx
movl 0xec(%rsp), %eax
movl %eax, %ecx
movsd 0xd0(%rsp), %xmm0
callq 0xfff0
jmp 0x7686
movsd 0xd0(%rsp), %xmm0
addsd 0xf0(%rsp), %xmm0
movsd %xmm0, 0xf0(%rsp)
movl 0xe4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe4(%rsp)
jmp 0x75c4
jmp 0x76b9
movl 0xe8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe8(%rsp)
jmp 0x75a5
jmp 0x76d1
movl 0xec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xec(%rsp)
jmp 0x7586
movq 0x88(%rsp), %rax
movq $0x0, 0xc8(%rsp)
movsd 0x10(%rax), %xmm0
movsd 0x20920(%rip), %xmm1    # 0x28028
mulsd %xmm1, %xmm0
movsd %xmm0, 0xc0(%rsp)
movl $0x1f4, 0xbc(%rsp) # imm = 0x1F4
movsd 0xc0(%rsp), %xmm0
movsd 0xc8(%rsp), %xmm1
subsd %xmm1, %xmm0
movl 0xbc(%rsp), %eax
incl %eax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0xb0(%rsp)
movsd 0xc8(%rsp), %xmm0
movsd %xmm0, 0xa8(%rsp)
movsd 0xa8(%rsp), %xmm1
movsd 0xc0(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x77ef
movq 0x88(%rsp), %rax
movq %rax, %rcx
addq $0x50, %rcx
movq %rcx, 0x8(%rsp)
movsd 0x10(%rax), %xmm0
movsd 0xa8(%rsp), %xmm1
callq 0x103e0
movsd %xmm0, 0x10(%rsp)
jmp 0x77aa
movq 0x8(%rsp), %rdi
movsd 0x10(%rsp), %xmm0
movsd %xmm0, 0xa0(%rsp)
leaq 0xa0(%rsp), %rsi
callq 0x103b0
jmp 0x77cd
jmp 0x77cf
movsd 0xb0(%rsp), %xmm0
addsd 0xa8(%rsp), %xmm0
movsd %xmm0, 0xa8(%rsp)
jmp 0x7763
addq $0x128, %rsp            # imm = 0x128
retq
movq 0x90(%rsp), %rdi
callq 0xfdb0
movq 0x80(%rsp), %rdi
callq 0x10470
movq 0x100(%rsp), %rdi
callq 0x34a0
nop