// File: tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Grid.cpp
// Function: gaps::R2Grid::FillHoles(int)
void R2Grid::
FillHoles(int max_hole_size)
{
  // Interpolate vertically
  for (int ix = 0; ix < XResolution(); ix++) {
    int iy0 = -1;
    for (int iy1 = 0; iy1 < YResolution(); iy1++) {
      if (GridValue(ix, iy1) != R2_GRID_UNKNOWN_VALUE) { 
        if ((iy0 >= 0) && (iy0 < iy1-1) && (iy1-iy0 < max_hole_size)) {
          RNScalar value0 = GridValue(ix, iy0);
          if (value0 == R2_GRID_UNKNOWN_VALUE) continue;
          RNScalar value1 = GridValue(ix, iy1);
          if (value1 == R2_GRID_UNKNOWN_VALUE) continue;
          for (int iy = iy0+1; iy < iy1; iy++) {
            RNScalar t = (double) (iy - iy0) / (double) (iy1 - iy0);
            RNScalar value = (1-t)*value0 + t*value1;
            SetGridValue(ix, iy, value);
          }
        }
        iy0 = iy1;
      }
    }
  }

  // Interpolate horizontally
  for (int iy = 0; iy < YResolution(); iy++) {
    int ix0 = -1;
    for (int ix1 = 0; ix1 < XResolution(); ix1++) {
      if (GridValue(ix1, iy) != R2_GRID_UNKNOWN_VALUE) { 
        if ((ix0 >= 0) && (ix0 < ix1-1) && (ix1-ix0 < max_hole_size)) {
          RNScalar value0 = GridValue(ix0, iy);
          if (value0 == R2_GRID_UNKNOWN_VALUE) continue;
          RNScalar value1 = GridValue(ix1, iy);
          if (value1 == R2_GRID_UNKNOWN_VALUE) continue;
          for (int ix = ix0+1; ix < ix1; ix++) {
            RNScalar t = (double) (ix - ix0) / (double) (ix1 - ix0);
            RNScalar value = (1-t)*value0 + t*value1;
            SetGridValue(ix, iy, value);
          }
        }
        ix0 = ix1;
      }
    }
  }
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x90(%rsp)
movl %esi, 0x8c(%rsp)
movq 0x90(%rsp), %rax
movq %rax, 0x18(%rsp)
movl $0x0, 0x88(%rsp)
movq 0x18(%rsp), %rdi
movl 0x88(%rsp), %eax
movl %eax, 0x14(%rsp)
callq 0xb9260
movl %eax, %ecx
movl 0x14(%rsp), %eax
cmpl %ecx, %eax
jge 0xa9b3e
movl $0xffffffff, 0x84(%rsp) # imm = 0xFFFFFFFF
movl $0x0, 0x80(%rsp)
movq 0x18(%rsp), %rdi
movl 0x80(%rsp), %eax
movl %eax, 0x10(%rsp)
callq 0xb9280
movl %eax, %ecx
movl 0x10(%rsp), %eax
cmpl %ecx, %eax
jge 0xa9b26
movq 0x18(%rsp), %rdi
movl 0x88(%rsp), %esi
movl 0x80(%rsp), %edx
callq 0xb92a0
movsd 0x8a516(%rip), %xmm1    # 0x133eb0
ucomisd %xmm1, %xmm0
jne 0xa99a7
jp 0xa99a7
jmp 0xa9b0e
cmpl $0x0, 0x84(%rsp)
jl 0xa9b00
movl 0x84(%rsp), %eax
movl 0x80(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0xa9b00
movl 0x80(%rsp), %eax
subl 0x84(%rsp), %eax
cmpl 0x8c(%rsp), %eax
jge 0xa9b00
movq 0x18(%rsp), %rdi
movl 0x88(%rsp), %esi
movl 0x84(%rsp), %edx
callq 0xb92a0
movsd %xmm0, 0x78(%rsp)
movsd 0x78(%rsp), %xmm0
movsd 0x8a49b(%rip), %xmm1    # 0x133eb0
ucomisd %xmm1, %xmm0
jne 0xa9a22
jp 0xa9a22
jmp 0xa9b10
movq 0x18(%rsp), %rdi
movl 0x88(%rsp), %esi
movl 0x80(%rsp), %edx
callq 0xb92a0
movsd %xmm0, 0x70(%rsp)
movsd 0x70(%rsp), %xmm0
movsd 0x8a462(%rip), %xmm1    # 0x133eb0
ucomisd %xmm1, %xmm0
jne 0xa9a5b
jp 0xa9a5b
jmp 0xa9b10
movl 0x84(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
cmpl 0x80(%rsp), %eax
jge 0xa9afe
movq 0x18(%rsp), %rdi
movl 0x6c(%rsp), %eax
subl 0x84(%rsp), %eax
cvtsi2sd %eax, %xmm0
movl 0x80(%rsp), %eax
subl 0x84(%rsp), %eax
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x60(%rsp)
movsd 0x89556(%rip), %xmm0    # 0x133008
subsd 0x60(%rsp), %xmm0
movsd 0x78(%rsp), %xmm2
movsd 0x60(%rsp), %xmm1
mulsd 0x70(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x58(%rsp)
movl 0x88(%rsp), %esi
movl 0x6c(%rsp), %edx
movsd 0x58(%rsp), %xmm0
callq 0x6bc00
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0xa9a69
jmp 0xa9b00
movl 0x80(%rsp), %eax
movl %eax, 0x84(%rsp)
jmp 0xa9b10
movl 0x80(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x80(%rsp)
jmp 0xa9957
jmp 0xa9b28
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0xa991e
movl $0x0, 0x54(%rsp)
movq 0x18(%rsp), %rdi
movl 0x54(%rsp), %eax
movl %eax, 0xc(%rsp)
callq 0xb9280
movl %eax, %ecx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jge 0xa9d0e
movl $0xffffffff, 0x50(%rsp) # imm = 0xFFFFFFFF
movl $0x0, 0x4c(%rsp)
movq 0x18(%rsp), %rdi
movl 0x4c(%rsp), %eax
movl %eax, 0x8(%rsp)
callq 0xb9260
movl %eax, %ecx
movl 0x8(%rsp), %eax
cmpl %ecx, %eax
jge 0xa9cfc
movq 0x18(%rsp), %rdi
movl 0x4c(%rsp), %esi
movl 0x54(%rsp), %edx
callq 0xb92a0
movsd 0x8a300(%rip), %xmm1    # 0x133eb0
ucomisd %xmm1, %xmm0
jne 0xa9bbd
jp 0xa9bbd
jmp 0xa9cea
cmpl $0x0, 0x50(%rsp)
jl 0xa9ce2
movl 0x50(%rsp), %eax
movl 0x4c(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0xa9ce2
movl 0x4c(%rsp), %eax
subl 0x50(%rsp), %eax
cmpl 0x8c(%rsp), %eax
jge 0xa9ce2
movq 0x18(%rsp), %rdi
movl 0x50(%rsp), %esi
movl 0x54(%rsp), %edx
callq 0xb92a0
movsd %xmm0, 0x40(%rsp)
movsd 0x40(%rsp), %xmm0
movsd 0x8a29a(%rip), %xmm1    # 0x133eb0
ucomisd %xmm1, %xmm0
jne 0xa9c23
jp 0xa9c23
jmp 0xa9cec
movq 0x18(%rsp), %rdi
movl 0x4c(%rsp), %esi
movl 0x54(%rsp), %edx
callq 0xb92a0
movsd %xmm0, 0x38(%rsp)
movsd 0x38(%rsp), %xmm0
movsd 0x8a267(%rip), %xmm1    # 0x133eb0
ucomisd %xmm1, %xmm0
jne 0xa9c56
jp 0xa9c56
jmp 0xa9cec
movl 0x50(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
movl 0x34(%rsp), %eax
cmpl 0x4c(%rsp), %eax
jge 0xa9ce0
movq 0x18(%rsp), %rdi
movl 0x34(%rsp), %eax
subl 0x50(%rsp), %eax
cvtsi2sd %eax, %xmm0
movl 0x4c(%rsp), %eax
subl 0x50(%rsp), %eax
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x28(%rsp)
movsd 0x8936e(%rip), %xmm0    # 0x133008
subsd 0x28(%rsp), %xmm0
movsd 0x40(%rsp), %xmm2
movsd 0x28(%rsp), %xmm1
mulsd 0x38(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x20(%rsp)
movl 0x34(%rsp), %esi
movl 0x54(%rsp), %edx
movsd 0x20(%rsp), %xmm0
callq 0x6bc00
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0xa9c61
jmp 0xa9ce2
movl 0x4c(%rsp), %eax
movl %eax, 0x50(%rsp)
jmp 0xa9cec
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0xa9b76
jmp 0xa9cfe
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
jmp 0xa9b46
addq $0x98, %rsp
retq
nopw %cs:(%rax,%rax)