// File: tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Grid.cpp
// Function: gaps::R2Grid::SquaredDistanceTransform()
void R2Grid::
SquaredDistanceTransform(void)
{
  int x,y,s,t;
  int dist,square,new_dist;
  int* oldBuffer;
  int* newBuffer;
  int first;
  int i;

  // Allocate temporary buffers
  int res = XResolution();
  if (res < YResolution()) res = YResolution();
  oldBuffer = new int[res];
  assert(oldBuffer);
  newBuffer = new int[res];
  assert(newBuffer);

  // Initalize values (0 if was set, max_value if not)
  RNScalar max_value = 2 * (res+1) * (res+1);
  RNScalar *grid_valuesp = grid_values;
  for (i = 0; i < grid_size; i++) {
    if (*grid_valuesp == 0.0) *grid_valuesp = max_value;
    else if (*grid_valuesp == R2_GRID_UNKNOWN_VALUE) *grid_valuesp = max_value;
    else *grid_valuesp = 0.0;
    grid_valuesp++;
  }

  // Scan along x axis
  for (y = 0; y < YResolution(); y++) {
    first = 1;
    dist = 0;
    for (x = 0; x < XResolution(); x++) {
      if (GridValue(x,y) == 0.0) {
        dist=0;
        first=0;
        SetGridValue(x, y, 0);
      }
      else if (first == 0) {
        dist++;
        square = dist*dist;
        SetGridValue(x, y, square);
      }
    }
      		
    // backward scan
    dist = 0;
    first = 1;
    for (x = XResolution()-1; x >= 0; x--) {
      if (GridValue(x,y) == 0.0) {
        dist = 0;
        first = 0;
        SetGridValue(x, y, 0);
      }
      else if (first == 0) {
        dist++;
        square = dist*dist;
        if (square < GridValue(x, y)) {
          SetGridValue(x, y, square);
        }
      }
    }
  }

  // Scan along y axis
  for (x = 0; x < XResolution(); x++) {
    // Copy grid values
    for (y = 0; y < YResolution(); y++) 
      oldBuffer[y] = (int) (GridValue(x, y) + 0.5);
      		
    // forward scan
    s = 0;
    for (y = 0; y < YResolution(); y++) {
      dist = oldBuffer[y];
      if (dist) {
        for (t = s; t <= y ; t++) {
          new_dist = oldBuffer[t] + (y - t) * (y - t);
          if (new_dist <= dist){
            dist = new_dist;
            s = t;
          }
        }
      }
      else { 
        s = y;
      }
      newBuffer[y] = dist;
    }
  
    // backward scan
    s = YResolution() - 1;
    for(y = YResolution()-1; y >=0 ; y--) {
      dist = newBuffer[y];
      if (dist) {
        for (t = s; t > y ; t--) {
          new_dist = oldBuffer[t] + (y - t) * (y - t);
          if (new_dist <= dist){
            dist = new_dist;
            s = t;
          }
        }
        SetGridValue(x, y, dist);
      }
      else { 
        s = y; 
      }
    }
  }
	
  // Delete temporary buffers
  delete[] oldBuffer;
  delete[] newBuffer;
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x90(%rsp)
movq 0x90(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0xb9260
movq 0x30(%rsp), %rdi
movl %eax, 0x54(%rsp)
movl 0x54(%rsp), %eax
movl %eax, 0x3c(%rsp)
callq 0xb9280
movl %eax, %ecx
movl 0x3c(%rsp), %eax
cmpl %ecx, %eax
jge 0xa9eef
movq 0x30(%rsp), %rdi
callq 0xb9280
movl %eax, 0x54(%rsp)
movslq 0x54(%rsp), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0xf030
movq %rax, 0x68(%rsp)
movslq 0x54(%rsp), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0xf030
movq %rax, %rcx
movq 0x30(%rsp), %rax
movq %rcx, 0x60(%rsp)
movl 0x54(%rsp), %ecx
addl $0x1, %ecx
shll %ecx
movl 0x54(%rsp), %edx
addl $0x1, %edx
imull %edx, %ecx
cvtsi2sd %ecx, %xmm0
movsd %xmm0, 0x48(%rsp)
movq 0xb8(%rax), %rax
movq %rax, 0x40(%rsp)
movl $0x0, 0x58(%rsp)
movq 0x30(%rsp), %rcx
movl 0x58(%rsp), %eax
cmpl 0xcc(%rcx), %eax
jge 0xaa00a
movq 0x40(%rsp), %rax
movsd (%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xa9fb4
jp 0xa9fb4
movsd 0x48(%rsp), %xmm0
movq 0x40(%rsp), %rax
movsd %xmm0, (%rax)
jmp 0xa9fec
movq 0x40(%rsp), %rax
movsd (%rax), %xmm0
movsd 0x89eeb(%rip), %xmm1    # 0x133eb0
ucomisd %xmm1, %xmm0
jne 0xa9fde
jp 0xa9fde
movsd 0x48(%rsp), %xmm0
movq 0x40(%rsp), %rax
movsd %xmm0, (%rax)
jmp 0xa9fea
movq 0x40(%rsp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
jmp 0xa9fec
movq 0x40(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x40(%rsp)
movl 0x58(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x58(%rsp)
jmp 0xa9f7e
movl $0x0, 0x88(%rsp)
movq 0x30(%rsp), %rdi
movl 0x88(%rsp), %eax
movl %eax, 0x2c(%rsp)
callq 0xb9280
movl %eax, %ecx
movl 0x2c(%rsp), %eax
cmpl %ecx, %eax
jge 0xaa240
movl $0x1, 0x5c(%rsp)
movl $0x0, 0x7c(%rsp)
movl $0x0, 0x8c(%rsp)
movq 0x30(%rsp), %rdi
movl 0x8c(%rsp), %eax
movl %eax, 0x28(%rsp)
callq 0xb9260
movl %eax, %ecx
movl 0x28(%rsp), %eax
cmpl %ecx, %eax
jge 0xaa11d
movq 0x30(%rsp), %rdi
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
callq 0xb92a0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xaa0c6
jp 0xaa0c6
movq 0x30(%rsp), %rdi
movl $0x0, 0x7c(%rsp)
movl $0x0, 0x5c(%rsp)
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
xorps %xmm0, %xmm0
callq 0x6bc00
jmp 0xaa105
cmpl $0x0, 0x5c(%rsp)
jne 0xaa103
movq 0x30(%rsp), %rdi
movl 0x7c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x7c(%rsp)
movl 0x7c(%rsp), %eax
imull 0x7c(%rsp), %eax
movl %eax, 0x78(%rsp)
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
cvtsi2sdl 0x78(%rsp), %xmm0
callq 0x6bc00
jmp 0xaa105
jmp 0xaa107
movl 0x8c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8c(%rsp)
jmp 0xaa053
movq 0x30(%rsp), %rdi
movl $0x0, 0x7c(%rsp)
movl $0x1, 0x5c(%rsp)
callq 0xb9260
subl $0x1, %eax
movl %eax, 0x8c(%rsp)
cmpl $0x0, 0x8c(%rsp)
jl 0xaa228
movq 0x30(%rsp), %rdi
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
callq 0xb92a0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xaa19f
jp 0xaa19f
movq 0x30(%rsp), %rdi
movl $0x0, 0x7c(%rsp)
movl $0x0, 0x5c(%rsp)
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
xorps %xmm0, %xmm0
callq 0x6bc00
jmp 0xaa210
cmpl $0x0, 0x5c(%rsp)
jne 0xaa20e
movq 0x30(%rsp), %rdi
movl 0x7c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x7c(%rsp)
movl 0x7c(%rsp), %eax
imull 0x7c(%rsp), %eax
movl %eax, 0x78(%rsp)
cvtsi2sdl 0x78(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
callq 0xb92a0
movsd 0x20(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0xaa20c
movq 0x30(%rsp), %rdi
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
cvtsi2sdl 0x78(%rsp), %xmm0
callq 0x6bc00
jmp 0xaa20e
jmp 0xaa210
jmp 0xaa212
movl 0x8c(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x8c(%rsp)
jmp 0xaa141
jmp 0xaa22a
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0xaa015
movl $0x0, 0x8c(%rsp)
movq 0x30(%rsp), %rdi
movl 0x8c(%rsp), %eax
movl %eax, 0x1c(%rsp)
callq 0xb9260
movl %eax, %ecx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jge 0xaa538
movl $0x0, 0x88(%rsp)
movq 0x30(%rsp), %rdi
movl 0x88(%rsp), %eax
movl %eax, 0x18(%rsp)
callq 0xb9280
movl %eax, %ecx
movl 0x18(%rsp), %eax
cmpl %ecx, %eax
jge 0xaa2e3
movq 0x30(%rsp), %rdi
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
callq 0xb92a0
movsd 0x88d58(%rip), %xmm1    # 0x133010
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %edx
movq 0x68(%rsp), %rax
movslq 0x88(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0xaa279
movl $0x0, 0x84(%rsp)
movl $0x0, 0x88(%rsp)
movq 0x30(%rsp), %rdi
movl 0x88(%rsp), %eax
movl %eax, 0x14(%rsp)
callq 0xb9280
movl %eax, %ecx
movl 0x14(%rsp), %eax
cmpl %ecx, %eax
jge 0xaa3fd
movq 0x68(%rsp), %rax
movslq 0x88(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0x7c(%rsp)
cmpl $0x0, 0x7c(%rsp)
je 0xaa3c5
movl 0x84(%rsp), %eax
movl %eax, 0x80(%rsp)
movl 0x80(%rsp), %eax
cmpl 0x88(%rsp), %eax
jg 0xaa3c3
movq 0x68(%rsp), %rax
movslq 0x80(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl 0x88(%rsp), %ecx
subl 0x80(%rsp), %ecx
movl 0x88(%rsp), %edx
subl 0x80(%rsp), %edx
imull %edx, %ecx
addl %ecx, %eax
movl %eax, 0x74(%rsp)
movl 0x74(%rsp), %eax
cmpl 0x7c(%rsp), %eax
jg 0xaa3ae
movl 0x74(%rsp), %eax
movl %eax, 0x7c(%rsp)
movl 0x80(%rsp), %eax
movl %eax, 0x84(%rsp)
jmp 0xaa3b0
movl 0x80(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x80(%rsp)
jmp 0xaa349
jmp 0xaa3d3
movl 0x88(%rsp), %eax
movl %eax, 0x84(%rsp)
movl 0x7c(%rsp), %edx
movq 0x60(%rsp), %rax
movslq 0x88(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0xaa2f9
movq 0x30(%rsp), %rdi
callq 0xb9280
movq 0x30(%rsp), %rdi
subl $0x1, %eax
movl %eax, 0x84(%rsp)
callq 0xb9280
subl $0x1, %eax
movl %eax, 0x88(%rsp)
cmpl $0x0, 0x88(%rsp)
jl 0xaa520
movq 0x60(%rsp), %rax
movslq 0x88(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0x7c(%rsp)
cmpl $0x0, 0x7c(%rsp)
je 0xaa4fa
movl 0x84(%rsp), %eax
movl %eax, 0x80(%rsp)
movl 0x80(%rsp), %eax
cmpl 0x88(%rsp), %eax
jle 0xaa4da
movq 0x68(%rsp), %rax
movslq 0x80(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl 0x88(%rsp), %ecx
subl 0x80(%rsp), %ecx
movl 0x88(%rsp), %edx
subl 0x80(%rsp), %edx
imull %edx, %ecx
addl %ecx, %eax
movl %eax, 0x74(%rsp)
movl 0x74(%rsp), %eax
cmpl 0x7c(%rsp), %eax
jg 0xaa4c5
movl 0x74(%rsp), %eax
movl %eax, 0x7c(%rsp)
movl 0x80(%rsp), %eax
movl %eax, 0x84(%rsp)
jmp 0xaa4c7
movl 0x80(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x80(%rsp)
jmp 0xaa460
movq 0x30(%rsp), %rdi
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
cvtsi2sdl 0x7c(%rsp), %xmm0
callq 0x6bc00
jmp 0xaa508
movl 0x88(%rsp), %eax
movl %eax, 0x84(%rsp)
jmp 0xaa50a
movl 0x88(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0xaa425
jmp 0xaa522
movl 0x8c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8c(%rsp)
jmp 0xaa24b
movq 0x68(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0xaa552
movq 0x8(%rsp), %rdi
callq 0xf670
movq 0x60(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0xaa56a
movq (%rsp), %rdi
callq 0xf670
addq $0x98, %rsp
retq
nopw %cs:(%rax,%rax)