// File: tomfunkhouser[P]gaps/pkgs/GSV/GSVCamera.cpp
// Function: gaps::GSVCamera::UndistortImage(gaps::R2Image const&, gaps::R2Image&) const
int GSVCamera::
UndistortImage(const R2Image& input, R2Image& output) const
{
  // Get convenient variables
  double xscale = (double) output.Width() / (double) input.Width();
  double yscale = (double) output.Height() / (double) input.Height();
  R2Box input_bbox(0, 0, input.Width()-1, input.Height()-1);

  // Create undistorted image (output) from distorted image (input)
  // Removes radial distortion
  for (int x = 0; x < output.Width(); x++) {
    for (int y = 0; y < output.Height(); y++) {
      R2Point output_position(x,y);
      output_position[0] *= xscale;
      output_position[1] *= yscale;
      R2Point input_position = DistortedPosition(output_position);
      if (R2Contains(input_bbox, input_position)) {
        int ix1 = (int) input_position[0];
        int iy1 = (int) input_position[1];
        int ix2 = ix1 + 1;
        int iy2 = iy1 + 1;
        if (ix2 >= input.Width()) ix2 = ix1;
        if (iy2 >= input.Height()) iy2 = iy1;
        double dx = input_position[0] - ix1;
        double dy = input_position[1] - iy1;
        RNRgb pixel1 = (1-dx) * input.PixelRGB(ix1, iy1) + dx * input.PixelRGB(ix2, iy1);
        RNRgb pixel2 = (1-dx) * input.PixelRGB(ix1, iy2) + dx * input.PixelRGB(ix2, iy2);
        RNRgb pixel = (1-dy) * pixel1 + dy * pixel2;
        output.SetPixelRGB(x, y, pixel);
      }
      else {
        output.SetPixelRGB(x, y, RNblack_rgb);
      }
    }
  }

  // Return success
  return 1;
}

// Assembly:
subq $0x288, %rsp            # imm = 0x288
movq %rdi, 0x280(%rsp)
movq %rsi, 0x278(%rsp)
movq %rdx, 0x270(%rsp)
movq 0x280(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x270(%rsp), %rdi
callq 0x39d10
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x90(%rsp)
movq 0x278(%rsp), %rdi
callq 0x39d10
movsd 0x90(%rsp), %xmm0
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x268(%rsp)
movq 0x270(%rsp), %rdi
callq 0x39d20
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x98(%rsp)
movq 0x278(%rsp), %rdi
callq 0x39d20
movsd 0x98(%rsp), %xmm0
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x260(%rsp)
movq 0x278(%rsp), %rdi
callq 0x39d10
subl $0x1, %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0xa0(%rsp)
movq 0x278(%rsp), %rdi
callq 0x39d20
movsd 0xa0(%rsp), %xmm2
subl $0x1, %eax
cvtsi2sd %eax, %xmm3
leaq 0x238(%rsp), %rdi
xorps %xmm1, %xmm1
movaps %xmm1, %xmm0
callq 0x1b3f70
movl $0x0, 0x234(%rsp)
movl 0x234(%rsp), %eax
movl %eax, 0x80(%rsp)
movq 0x270(%rsp), %rdi
callq 0x39d10
movl %eax, 0x84(%rsp)
jmp 0x4d6ed
movl 0x80(%rsp), %eax
movl 0x84(%rsp), %ecx
cmpl %ecx, %eax
jge 0x4dc13
movl $0x0, 0x220(%rsp)
movl 0x220(%rsp), %eax
movl %eax, 0x78(%rsp)
movq 0x270(%rsp), %rdi
callq 0x39d20
movl %eax, 0x7c(%rsp)
jmp 0x4d72c
movl 0x78(%rsp), %eax
movl 0x7c(%rsp), %ecx
cmpl %ecx, %eax
jge 0x4dbfb
cvtsi2sdl 0x234(%rsp), %xmm0
cvtsi2sdl 0x220(%rsp), %xmm1
leaq 0x210(%rsp), %rdi
callq 0x1b9a30
jmp 0x4d75d
movsd 0x268(%rsp), %xmm0
movsd %xmm0, 0x68(%rsp)
leaq 0x210(%rsp), %rdi
xorl %esi, %esi
callq 0x4e320
movq %rax, 0x70(%rsp)
jmp 0x4d782
movq 0x70(%rsp), %rax
movsd 0x68(%rsp), %xmm1
movsd (%rax), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movsd 0x260(%rsp), %xmm0
movsd %xmm0, 0x58(%rsp)
leaq 0x210(%rsp), %rdi
movl $0x1, %esi
callq 0x4e320
movq %rax, 0x60(%rsp)
jmp 0x4d7c1
movq 0x88(%rsp), %rsi
movq 0x60(%rsp), %rax
movsd 0x58(%rsp), %xmm1
movsd (%rax), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, (%rax)
leaq 0x200(%rsp), %rdi
leaq 0x210(%rsp), %rdx
callq 0x4d380
jmp 0x4d7f7
leaq 0x238(%rsp), %rdi
leaq 0x200(%rsp), %rsi
callq 0x1933d0
movl %eax, 0x54(%rsp)
jmp 0x4d812
movl 0x54(%rsp), %eax
cmpl $0x0, %eax
je 0x4dbbd
leaq 0x200(%rsp), %rdi
xorl %esi, %esi
callq 0x4e320
movq %rax, 0x48(%rsp)
jmp 0x4d835
movq 0x48(%rsp), %rax
cvttsd2si (%rax), %eax
movl %eax, 0x1fc(%rsp)
leaq 0x200(%rsp), %rdi
movl $0x1, %esi
callq 0x4e320
movq %rax, 0x40(%rsp)
jmp 0x4d85e
movq 0x40(%rsp), %rax
cvttsd2si (%rax), %eax
movl %eax, 0x1f8(%rsp)
movl 0x1fc(%rsp), %eax
incl %eax
movl %eax, 0x1f4(%rsp)
movl 0x1f8(%rsp), %eax
incl %eax
movl %eax, 0x1f0(%rsp)
movl 0x1f4(%rsp), %eax
movl %eax, 0x38(%rsp)
movq 0x278(%rsp), %rdi
callq 0x39d10
movl %eax, 0x3c(%rsp)
jmp 0x4d8ac
movl 0x38(%rsp), %eax
movl 0x3c(%rsp), %ecx
cmpl %ecx, %eax
jl 0x4d8ee
movl 0x1fc(%rsp), %eax
movl %eax, 0x1f4(%rsp)
jmp 0x4d8ee
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x228(%rsp)
movl %eax, 0x224(%rsp)
leaq 0x238(%rsp), %rdi
callq 0x39f60
jmp 0x4dc2d
movl 0x1f0(%rsp), %eax
movl %eax, 0x30(%rsp)
movq 0x278(%rsp), %rdi
callq 0x39d20
movl %eax, 0x34(%rsp)
jmp 0x4d90c
movl 0x30(%rsp), %eax
movl 0x34(%rsp), %ecx
cmpl %ecx, %eax
jl 0x4d926
movl 0x1f8(%rsp), %eax
movl %eax, 0x1f0(%rsp)
leaq 0x200(%rsp), %rdi
xorl %esi, %esi
callq 0x4e320
movq %rax, 0x28(%rsp)
jmp 0x4d93c
movq 0x28(%rsp), %rax
movsd (%rax), %xmm0
cvtsi2sdl 0x1fc(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x1e8(%rsp)
leaq 0x200(%rsp), %rdi
movl $0x1, %esi
callq 0x4e320
movq %rax, 0x20(%rsp)
jmp 0x4d974
movq 0x20(%rsp), %rax
movsd (%rax), %xmm0
cvtsi2sdl 0x1f8(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x1e0(%rsp)
movsd 0x1e8(%rsp), %xmm1
movsd 0x21866c(%rip), %xmm0   # 0x266010
subsd %xmm1, %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0x278(%rsp), %rsi
movl 0x1fc(%rsp), %edx
movl 0x1f8(%rsp), %ecx
leaq 0x198(%rsp), %rdi
callq 0x1bbe50
jmp 0x4d9d3
movsd 0x18(%rsp), %xmm0
leaq 0x1b0(%rsp), %rdi
leaq 0x198(%rsp), %rsi
callq 0x4e3b0
jmp 0x4d9f0
movsd 0x1e8(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x278(%rsp), %rsi
movl 0x1f4(%rsp), %edx
movl 0x1f8(%rsp), %ecx
leaq 0x168(%rsp), %rdi
callq 0x1bbe50
jmp 0x4da24
movsd 0x10(%rsp), %xmm0
leaq 0x180(%rsp), %rdi
leaq 0x168(%rsp), %rsi
callq 0x4e3b0
jmp 0x4da41
leaq 0x1c8(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
leaq 0x180(%rsp), %rdx
callq 0x4e340
jmp 0x4da60
movsd 0x1e8(%rsp), %xmm1
movsd 0x21859f(%rip), %xmm0   # 0x266010
subsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0x278(%rsp), %rsi
movl 0x1fc(%rsp), %edx
movl 0x1f0(%rsp), %ecx
leaq 0x120(%rsp), %rdi
callq 0x1bbe50
jmp 0x4daa0
movsd 0x8(%rsp), %xmm0
leaq 0x138(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x4e3b0
jmp 0x4dabd
movsd 0x1e8(%rsp), %xmm0
movsd %xmm0, (%rsp)
movq 0x278(%rsp), %rsi
movl 0x1f4(%rsp), %edx
movl 0x1f0(%rsp), %ecx
leaq 0xf0(%rsp), %rdi
callq 0x1bbe50
jmp 0x4daf0
movsd (%rsp), %xmm0
leaq 0x108(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x4e3b0
jmp 0x4db0c
leaq 0x150(%rsp), %rdi
leaq 0x138(%rsp), %rsi
leaq 0x108(%rsp), %rdx
callq 0x4e340
jmp 0x4db2b
movsd 0x1e0(%rsp), %xmm1
movsd 0x2184d4(%rip), %xmm0   # 0x266010
subsd %xmm1, %xmm0
leaq 0xc0(%rsp), %rdi
leaq 0x1c8(%rsp), %rsi
callq 0x4e3b0
jmp 0x4db57
movsd 0x1e0(%rsp), %xmm0
leaq 0xa8(%rsp), %rdi
leaq 0x150(%rsp), %rsi
callq 0x4e3b0
jmp 0x4db77
leaq 0xd8(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
leaq 0xa8(%rsp), %rdx
callq 0x4e340
jmp 0x4db96
movq 0x270(%rsp), %rdi
movl 0x234(%rsp), %esi
movl 0x220(%rsp), %edx
leaq 0xd8(%rsp), %rcx
callq 0x1bc140
jmp 0x4dbbb
jmp 0x4dbe3
movq 0x270(%rsp), %rdi
movl 0x234(%rsp), %esi
movl 0x220(%rsp), %edx
leaq 0x6b6286(%rip), %rcx    # 0x703e60
callq 0x1bc140
jmp 0x4dbe1
jmp 0x4dbe3
jmp 0x4dbe5
movl 0x220(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x220(%rsp)
jmp 0x4d70e
jmp 0x4dbfd
movl 0x234(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x234(%rsp)
jmp 0x4d6c9
leaq 0x238(%rsp), %rdi
callq 0x39f60
movl $0x1, %eax
addq $0x288, %rsp            # imm = 0x288
retq
movq 0x228(%rsp), %rdi
callq 0x29c10
nopw (%rax,%rax)