// File: tomfunkhouser[P]gaps/pkgs/GSV/GSVCamera.cpp
// Function: gaps::GSVCamera::DistortImage(gaps::R2Image const&, gaps::R2Image&) const
int GSVCamera::
DistortImage(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 distorted image (output) from undistorted image (input)
  // Adds 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 = UndistortedPosition(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 0x4dd6d
movl 0x80(%rsp), %eax
movl 0x84(%rsp), %ecx
cmpl %ecx, %eax
jge 0x4e293
movl $0x0, 0x220(%rsp)
movl 0x220(%rsp), %eax
movl %eax, 0x78(%rsp)
movq 0x270(%rsp), %rdi
callq 0x39d20
movl %eax, 0x7c(%rsp)
jmp 0x4ddac
movl 0x78(%rsp), %eax
movl 0x7c(%rsp), %ecx
cmpl %ecx, %eax
jge 0x4e27b
cvtsi2sdl 0x234(%rsp), %xmm0
cvtsi2sdl 0x220(%rsp), %xmm1
leaq 0x210(%rsp), %rdi
callq 0x1b9a30
jmp 0x4dddd
movsd 0x268(%rsp), %xmm0
movsd %xmm0, 0x68(%rsp)
leaq 0x210(%rsp), %rdi
xorl %esi, %esi
callq 0x4e320
movq %rax, 0x70(%rsp)
jmp 0x4de02
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 0x4de41
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 0x4d4f0
jmp 0x4de77
leaq 0x238(%rsp), %rdi
leaq 0x200(%rsp), %rsi
callq 0x1933d0
movl %eax, 0x54(%rsp)
jmp 0x4de92
movl 0x54(%rsp), %eax
cmpl $0x0, %eax
je 0x4e23d
leaq 0x200(%rsp), %rdi
xorl %esi, %esi
callq 0x4e320
movq %rax, 0x48(%rsp)
jmp 0x4deb5
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 0x4dede
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 0x4df2c
movl 0x38(%rsp), %eax
movl 0x3c(%rsp), %ecx
cmpl %ecx, %eax
jl 0x4df6e
movl 0x1fc(%rsp), %eax
movl %eax, 0x1f4(%rsp)
jmp 0x4df6e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x228(%rsp)
movl %eax, 0x224(%rsp)
leaq 0x238(%rsp), %rdi
callq 0x39f60
jmp 0x4e2ad
movl 0x1f0(%rsp), %eax
movl %eax, 0x30(%rsp)
movq 0x278(%rsp), %rdi
callq 0x39d20
movl %eax, 0x34(%rsp)
jmp 0x4df8c
movl 0x30(%rsp), %eax
movl 0x34(%rsp), %ecx
cmpl %ecx, %eax
jl 0x4dfa6
movl 0x1f8(%rsp), %eax
movl %eax, 0x1f0(%rsp)
leaq 0x200(%rsp), %rdi
xorl %esi, %esi
callq 0x4e320
movq %rax, 0x28(%rsp)
jmp 0x4dfbc
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 0x4dff4
movq 0x20(%rsp), %rax
movsd (%rax), %xmm0
cvtsi2sdl 0x1f8(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x1e0(%rsp)
movsd 0x1e8(%rsp), %xmm1
movsd 0x217fec(%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 0x4e053
movsd 0x18(%rsp), %xmm0
leaq 0x1b0(%rsp), %rdi
leaq 0x198(%rsp), %rsi
callq 0x4e3b0
jmp 0x4e070
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 0x4e0a4
movsd 0x10(%rsp), %xmm0
leaq 0x180(%rsp), %rdi
leaq 0x168(%rsp), %rsi
callq 0x4e3b0
jmp 0x4e0c1
leaq 0x1c8(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
leaq 0x180(%rsp), %rdx
callq 0x4e340
jmp 0x4e0e0
movsd 0x1e8(%rsp), %xmm1
movsd 0x217f1f(%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 0x4e120
movsd 0x8(%rsp), %xmm0
leaq 0x138(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x4e3b0
jmp 0x4e13d
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 0x4e170
movsd (%rsp), %xmm0
leaq 0x108(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x4e3b0
jmp 0x4e18c
leaq 0x150(%rsp), %rdi
leaq 0x138(%rsp), %rsi
leaq 0x108(%rsp), %rdx
callq 0x4e340
jmp 0x4e1ab
movsd 0x1e0(%rsp), %xmm1
movsd 0x217e54(%rip), %xmm0   # 0x266010
subsd %xmm1, %xmm0
leaq 0xc0(%rsp), %rdi
leaq 0x1c8(%rsp), %rsi
callq 0x4e3b0
jmp 0x4e1d7
movsd 0x1e0(%rsp), %xmm0
leaq 0xa8(%rsp), %rdi
leaq 0x150(%rsp), %rsi
callq 0x4e3b0
jmp 0x4e1f7
leaq 0xd8(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
leaq 0xa8(%rsp), %rdx
callq 0x4e340
jmp 0x4e216
movq 0x270(%rsp), %rdi
movl 0x234(%rsp), %esi
movl 0x220(%rsp), %edx
leaq 0xd8(%rsp), %rcx
callq 0x1bc140
jmp 0x4e23b
jmp 0x4e263
movq 0x270(%rsp), %rdi
movl 0x234(%rsp), %esi
movl 0x220(%rsp), %edx
leaq 0x6b5c06(%rip), %rcx    # 0x703e60
callq 0x1bc140
jmp 0x4e261
jmp 0x4e263
jmp 0x4e265
movl 0x220(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x220(%rsp)
jmp 0x4dd8e
jmp 0x4e27d
movl 0x234(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x234(%rsp)
jmp 0x4dd49
leaq 0x238(%rsp), %rdi
callq 0x39f60
movl $0x1, %eax
addq $0x288, %rsp            # imm = 0x288
retq
movq 0x228(%rsp), %rdi
callq 0x29c10
nopw (%rax,%rax)