// File: tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Grid.cpp
// Function: gaps::R2Grid::ConnectedComponentFilter(double, double, double, double, double, double)
void R2Grid::
ConnectedComponentFilter(RNScalar isolevel, RNArea min_grid_area, RNArea max_grid_area, 
  RNScalar under_isolevel_value, RNScalar too_small_value, RNScalar too_large_value)
{
  // Compute connected components
  int *sizes = new int [ grid_size ];
  int *components = new int [ grid_size ];
  int ncomponents = ConnectedComponents(isolevel, grid_size, NULL, sizes, components);

  // Mask values under isolevel
  if (under_isolevel_value != R2_GRID_KEEP_VALUE) {
    for (int i = 0; i < grid_size; i++) {
      if (grid_values[i] == R2_GRID_UNKNOWN_VALUE) continue;
      if (grid_values[i] < isolevel) grid_values[i] = under_isolevel_value;
    }
  }

  // Mask components with areas too small 
  if (too_small_value != R2_GRID_KEEP_VALUE) {
    for (int component = 0; component < ncomponents; component++) {
      int area = sizes[component];
      if (area < min_grid_area) {
        for (int i = 0; i < grid_size; i++) {
          if (components[i] == component) grid_values[i] = too_small_value;
        }
      }
    }
  }

  // Mask components with areas too large 
  if (too_large_value != R2_GRID_KEEP_VALUE) {
    for (int component = 0; component < ncomponents; component++) {
      int area = sizes[component];
      if (area > max_grid_area) {
        for (int i = 0; i < grid_size; i++) {
          if (components[i] == component) grid_values[i] = too_large_value;
        }
      }
    }
  }

  // Delete temporary memory
  delete [] components;
  delete [] sizes;
}

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x80(%rsp)
movsd %xmm0, 0x78(%rsp)
movsd %xmm1, 0x70(%rsp)
movsd %xmm2, 0x68(%rsp)
movsd %xmm3, 0x60(%rsp)
movsd %xmm4, 0x58(%rsp)
movsd %xmm5, 0x50(%rsp)
movq 0x80(%rsp), %rax
movq %rax, 0x18(%rsp)
movslq 0xcc(%rax), %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 0x18(%rsp), %rax
movq %rcx, 0x48(%rsp)
movslq 0xcc(%rax), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0xf030
movq 0x18(%rsp), %rdi
movq %rax, 0x40(%rsp)
movsd 0x78(%rsp), %xmm0
movl 0xcc(%rdi), %esi
movq 0x48(%rsp), %rcx
movq 0x40(%rsp), %r8
xorl %eax, %eax
movl %eax, %edx
callq 0xb45c0
movl %eax, 0x3c(%rsp)
movsd 0x60(%rsp), %xmm0
movsd 0x7e380(%rip), %xmm1    # 0x133e88
ucomisd %xmm1, %xmm0
jne 0xb5b15
jp 0xb5b15
jmp 0xb5ba8
movl $0x0, 0x38(%rsp)
movq 0x18(%rsp), %rcx
movl 0x38(%rsp), %eax
cmpl 0xcc(%rcx), %eax
jge 0xb5ba6
movq 0x18(%rsp), %rax
movq 0xb8(%rax), %rax
movslq 0x38(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd 0x7e364(%rip), %xmm1    # 0x133eb0
ucomisd %xmm1, %xmm0
jne 0xb5b56
jp 0xb5b56
jmp 0xb5b96
movq 0x18(%rsp), %rax
movq 0xb8(%rax), %rax
movslq 0x38(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
movsd 0x78(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0xb5b94
movq 0x18(%rsp), %rax
movsd 0x60(%rsp), %xmm0
movq 0xb8(%rax), %rax
movslq 0x38(%rsp), %rcx
movsd %xmm0, (%rax,%rcx,8)
jmp 0xb5b96
movl 0x38(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0xb5b1d
jmp 0xb5ba8
movsd 0x58(%rsp), %xmm0
movsd 0x7e2d2(%rip), %xmm1    # 0x133e88
ucomisd %xmm1, %xmm0
jne 0xb5bc3
jp 0xb5bc3
jmp 0xb5c69
movl $0x0, 0x34(%rsp)
movl 0x34(%rsp), %eax
cmpl 0x3c(%rsp), %eax
jge 0xb5c67
movq 0x48(%rsp), %rax
movslq 0x34(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0x30(%rsp)
cvtsi2sdl 0x30(%rsp), %xmm1
movsd 0x70(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0xb5c55
movl $0x0, 0x2c(%rsp)
movq 0x18(%rsp), %rcx
movl 0x2c(%rsp), %eax
cmpl 0xcc(%rcx), %eax
jge 0xb5c53
movq 0x40(%rsp), %rax
movslq 0x2c(%rsp), %rcx
movl (%rax,%rcx,4), %eax
cmpl 0x34(%rsp), %eax
jne 0xb5c44
movq 0x18(%rsp), %rax
movsd 0x58(%rsp), %xmm0
movq 0xb8(%rax), %rax
movslq 0x2c(%rsp), %rcx
movsd %xmm0, (%rax,%rcx,8)
jmp 0xb5c46
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0xb5c04
jmp 0xb5c55
jmp 0xb5c57
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0xb5bcb
jmp 0xb5c69
movsd 0x50(%rsp), %xmm0
movsd 0x7e211(%rip), %xmm1    # 0x133e88
ucomisd %xmm1, %xmm0
jne 0xb5c84
jp 0xb5c84
jmp 0xb5d26
movl $0x0, 0x28(%rsp)
movl 0x28(%rsp), %eax
cmpl 0x3c(%rsp), %eax
jge 0xb5d24
movq 0x48(%rsp), %rax
movslq 0x28(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0x24(%rsp)
cvtsi2sdl 0x24(%rsp), %xmm0
ucomisd 0x68(%rsp), %xmm0
jbe 0xb5d12
movl $0x0, 0x20(%rsp)
movq 0x18(%rsp), %rcx
movl 0x20(%rsp), %eax
cmpl 0xcc(%rcx), %eax
jge 0xb5d10
movq 0x40(%rsp), %rax
movslq 0x20(%rsp), %rcx
movl (%rax,%rcx,4), %eax
cmpl 0x28(%rsp), %eax
jne 0xb5d01
movq 0x18(%rsp), %rax
movsd 0x50(%rsp), %xmm0
movq 0xb8(%rax), %rax
movslq 0x20(%rsp), %rcx
movsd %xmm0, (%rax,%rcx,8)
jmp 0xb5d03
movl 0x20(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
jmp 0xb5cc1
jmp 0xb5d12
jmp 0xb5d14
movl 0x28(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x28(%rsp)
jmp 0xb5c8c
jmp 0xb5d26
movq 0x40(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0xb5d40
movq 0x10(%rsp), %rdi
callq 0xf670
movq 0x48(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0xb5d5a
movq 0x8(%rsp), %rdi
callq 0xf670
addq $0x88, %rsp
retq
nopw %cs:(%rax,%rax)