// File: /workspace/github_cpp_makefile_star2_O2/matthewarcus[P]mmps/transform.cpp
// Function: Transform::SetDataInv(Image const&, Image&, TransformParams const&, double, double, double, double, unsigned int)
bool Transform::SetDataInv(const Image& inImage, Image& outImage,
			   const TransformParams& params,
			   double ox, double oy, // Coordinates in output image
			   double x, double y,   // scaled coordinates in input image
			   unsigned int outIndex)	     
{
  (void(ox));
  (void(oy));
  int iw = inImage.Width();
  int ih = inImage.Height();
  double orgx = 0.5 * iw;
  double orgy = 0.5 * ih;

  // Scale so that half width is 1
  double scaleFactor = BasicScale(iw,ih) / params.scale;

  // This is what we are inverting
  //double x = scaleFactor * (ix - orgx) + params.xoff;
  //double y = scaleFactor * (orgy - iy) + params.yoff;
  //applyRotation(-params.rotate,x,y)
  
  if (params.rotate != 0) {
    applyRotation(params.rotate,x,y);
  }
  int ix = int(floor(orgx + (x - params.xoff) / scaleFactor));
  int iy = int(floor(orgy - (y - params.yoff) / scaleFactor));

  if (ix < 0 || ix >= iw || iy < 0 || iy >= ih) {
    return false;
  } else {
    Rgb rgb;
    unsigned int inIndex = iy * iw + ix;
    inImage.GetRgb(inIndex, rgb);
    outImage.SetRgb(outIndex, rgb);
    return true;
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x90, %rsp
movl %r8d, %ebx
movapd %xmm3, (%rsp)
movapd %xmm2, 0x10(%rsp)
movq %rcx, %r12
movq %rdx, %r14
movq %rsi, %r15
movdqu (%rsi), %xmm0
movl (%rsi), %ebp
pshufd $0xe8, %xmm0, %xmm0     # xmm0 = xmm0[0,2,2,3]
movdqa %xmm0, 0x70(%rsp)
cvtdq2pd %xmm0, %xmm0
movl 0x8(%rsi), %edx
mulpd 0x5ff8(%rip), %xmm0     # 0xc4c0
movapd %xmm0, 0x80(%rsp)
movq (%rdi), %rax
movl %ebp, %esi
callq *0x18(%rax)
movapd %xmm0, %xmm1
divsd 0x28(%r12), %xmm1
movsd 0x10(%r12), %xmm0
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm0
movapd 0x10(%rsp), %xmm2
unpcklpd (%rsp), %xmm2           # xmm2 = xmm2[0],mem[0]
jne 0x6506
jnp 0x659b
movapd %xmm1, 0x60(%rsp)
movapd %xmm2, 0x40(%rsp)
movsd %xmm0, (%rsp)
callq 0x43a0
movapd %xmm0, 0x50(%rsp)
movsd (%rsp), %xmm0
callq 0x4070
movaps %xmm0, 0x20(%rsp)
movaps 0x10(%rsp), %xmm0
xorps 0x5b33(%rip), %xmm0     # 0xc070
movaps %xmm0, 0x10(%rsp)
movsd (%rsp), %xmm0
callq 0x4070
movaps %xmm0, 0x30(%rsp)
movsd (%rsp), %xmm0
callq 0x43a0
movapd 0x60(%rsp), %xmm1
movapd 0x20(%rsp), %xmm3
unpcklpd %xmm0, %xmm3            # xmm3 = xmm3[0],xmm0[0]
movapd 0x40(%rsp), %xmm2
movapd %xmm2, %xmm0
unpckhpd %xmm2, %xmm0            # xmm0 = xmm0[1],xmm2[1]
mulpd %xmm3, %xmm0
unpcklpd 0x10(%rsp), %xmm2       # xmm2 = xmm2[0],mem[0]
movapd %xmm2, %xmm3
movapd 0x50(%rsp), %xmm2
unpcklpd 0x30(%rsp), %xmm2       # xmm2 = xmm2[0],mem[0]
mulpd %xmm3, %xmm2
addpd %xmm0, %xmm2
movupd 0xb0(%r12), %xmm0
subpd %xmm0, %xmm2
unpcklpd %xmm1, %xmm1            # xmm1 = xmm1[0,0]
divpd %xmm1, %xmm2
movapd 0x80(%rsp), %xmm0
movapd %xmm0, %xmm1
subpd %xmm2, %xmm1
movapd %xmm1, (%rsp)
addsd %xmm0, %xmm2
movapd %xmm2, %xmm0
callq 0x4340
movapd %xmm0, 0x10(%rsp)
movapd (%rsp), %xmm0
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
callq 0x4340
movapd 0x10(%rsp), %xmm1
unpcklpd %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
cvttpd2dq %xmm1, %xmm0
movd %xmm0, %ecx
testl %ecx, %ecx
js 0x665d
movdqa 0x70(%rsp), %xmm1
pcmpgtd %xmm0, %xmm1
pshufd $0x50, %xmm1, %xmm1     # xmm1 = xmm1[0,0,1,1]
movmskpd %xmm1, %esi
xorl %eax, %eax
testb $0x1, %sil
je 0x665f
pshufd $0x55, %xmm0, %xmm0     # xmm0 = xmm0[1,1,1,1]
movd %xmm0, %edx
testl %edx, %edx
js 0x665f
shrb %sil
je 0x665f
imull %ebp, %edx
movl %ecx, %eax
addq %rdx, %rax
movq 0x10(%r15), %rcx
addq %rax, %rcx
addq %rax, %rcx
movzwl (%rcx,%rax), %edx
movb 0x2(%rcx,%rax), %al
movl %ebx, %ecx
movq 0x10(%r14), %rsi
addq %rcx, %rsi
addq %rcx, %rsi
movw %dx, (%rcx,%rsi)
movb %al, 0x2(%rcx,%rsi)
movb $0x1, %al
jmp 0x665f
xorl %eax, %eax
addq $0x90, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nop