// File: /workspace/github_c_makefile_star2_O0/zpole[P]IICV/vl/imopv.c
// Function: vl_image_distance_transform_f
VL_EXPORT void
VL_XCAT(vl_image_distance_transform_,SFX)
(T const * image,
 vl_size numColumns,
 vl_size numRows,
 vl_size columnStride,
 vl_size rowStride,
 T * distanceTransform,
 vl_uindex * indexes,
 T coeff,
 T offset)
{
  /* Each image pixel corresponds to a parabola. The algorithm scans
   such parabolas from left to right, keeping track of which
   parabolas belong to the lower envelope and in which interval. There are
   NUM active parabolas, FROM stores the beginning of the interval
   for which a certain parabola is part of the envoelope, and WHICH store
   the index of the parabola (that is, the pixel x from which the parabola
   originated).
   */
  vl_uindex x, y ;
  T * from = vl_malloc (sizeof(T) * (numColumns + 1)) ;
  T * base = vl_malloc (sizeof(T) * numColumns) ;
  vl_uindex * baseIndexes = vl_malloc (sizeof(vl_uindex) * numColumns) ;
  vl_uindex * which = vl_malloc (sizeof(vl_uindex) * numColumns) ;
  vl_uindex num = 0 ;

  for (y = 0 ; y < numRows ; ++y) {
    num = 0 ;
    for (x = 0 ; x < numColumns ; ++x) {
      T r = image[x  * columnStride + y * rowStride] ;
      T x2 = x * x ;
#if (FLT == VL_TYPE_FLOAT)
      T from_ = - VL_INFINITY_F ;
#else
      T from_ = - VL_INFINITY_D ;
#endif

      /*
       Add next parabola (there are NUM so far). The algorithm finds
       intersection INTERS with the previously added parabola. If
       the intersection is on the right of the "starting point" of
       this parabola, then the previous parabola is kept, and the
       new one is added to its right. Otherwise the new parabola
       "eats" the old one, which gets deleted and the check is
       repeated with the parabola added before the deleted one.
       */

      while (num >= 1) {
        vl_uindex x_ = which[num - 1] ;
        T x2_ = x_ * x_ ;
        T r_ = image[x_ * columnStride + y * rowStride] ;
        T inters ;
        if (r == r_) {
          /* handles the case r = r_ = \pm inf */
          inters = (x + x_) / 2.0 + offset ;
        }
#if (FLT == VL_TYPE_FLOAT)
        else if (coeff > VL_EPSILON_F)
#else
        else if (coeff > VL_EPSILON_D)
#endif
        {
          inters = ((r - r_) + coeff * (x2 - x2_)) / (x - x_) / (2*coeff) + offset ;
        } else {
          /* If coeff is very small, the parabolas are flat (= lines).
           In this case the previous parabola should be deleted if the current
           pixel has lower score */
#if (FLT == VL_TYPE_FLOAT)
          inters = (r < r_) ? - VL_INFINITY_F : VL_INFINITY_F ;
#else
          inters = (r < r_) ? - VL_INFINITY_D : VL_INFINITY_D ;
#endif
        }
        if (inters <= from [num - 1]) {
          /* delete a previous parabola */
          -- num ;
        } else {
          /* accept intersection */
          from_ = inters ;
          break ;
        }
      }

      /* add a new parabola */
      which[num] = x ;
      from[num] = from_ ;
      base[num] = r ;
      if (indexes) baseIndexes[num] = indexes[x  * columnStride + y * rowStride] ;
      num ++ ;
    } /* next column */

#if (FLT == VL_TYPE_FLOAT)
    from[num] = VL_INFINITY_F ;
#else
    from[num] = VL_INFINITY_D ;
#endif

    /* fill in */
    num = 0 ;
    for (x = 0 ; x < numColumns ; ++x) {
      double delta ;
      while (x >= from[num + 1]) ++ num ;
      delta = (double) x - (double) which[num] - offset ;
      distanceTransform[x  * columnStride + y * rowStride]
      = base[num] + coeff * delta * delta ;
      if (indexes) {
        indexes[x  * columnStride + y * rowStride]
        = baseIndexes[num] ;
      }
    }
  } /* next row */

  vl_free (from) ;
  vl_free (which) ;
  vl_free (base) ;
  vl_free (baseIndexes) ;
}

// Assembly:
subq $0xc8, %rsp
movq 0xd0(%rsp), %rax
movq %rdi, 0xc0(%rsp)
movq %rsi, 0xb8(%rsp)
movq %rdx, 0xb0(%rsp)
movq %rcx, 0xa8(%rsp)
movq %r8, 0xa0(%rsp)
movq %r9, 0x98(%rsp)
movss %xmm0, 0x94(%rsp)
movss %xmm1, 0x90(%rsp)
movq 0xb8(%rsp), %rdi
addq $0x1, %rdi
shlq $0x2, %rdi
callq 0x9660
movq %rax, 0x78(%rsp)
movq 0xb8(%rsp), %rdi
shlq $0x2, %rdi
callq 0x9660
movq %rax, 0x70(%rsp)
movq 0xb8(%rsp), %rdi
shlq $0x3, %rdi
callq 0x9660
movq %rax, 0x68(%rsp)
movq 0xb8(%rsp), %rdi
shlq $0x3, %rdi
callq 0x9660
movq %rax, 0x60(%rsp)
movq $0x0, 0x58(%rsp)
movq $0x0, 0x80(%rsp)
movq 0x80(%rsp), %rax
cmpq 0xb0(%rsp), %rax
jae 0x2611a
movq $0x0, 0x58(%rsp)
movq $0x0, 0x88(%rsp)
movq 0x88(%rsp), %rax
cmpq 0xb8(%rsp), %rax
jae 0x25f1e
movq 0xc0(%rsp), %rax
movq 0x88(%rsp), %rcx
movq 0xa8(%rsp), %rdx
imulq %rdx, %rcx
movq 0x80(%rsp), %rdx
movq 0xa0(%rsp), %rsi
imulq %rsi, %rdx
addq %rdx, %rcx
movss (%rax,%rcx,4), %xmm0
movss %xmm0, 0x54(%rsp)
movq 0x88(%rsp), %rax
imulq %rax, %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, 0x20(%rsp)
testq %rax, %rax
movss %xmm0, 0x24(%rsp)
js 0x25bd6
movss 0x20(%rsp), %xmm0
movss %xmm0, 0x24(%rsp)
movss 0x24(%rsp), %xmm0
movss %xmm0, 0x50(%rsp)
movss 0x33de6(%rip), %xmm0    # 0x599d0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movss %xmm0, 0x4c(%rsp)
cmpq $0x1, 0x58(%rsp)
jb 0x25e6d
movq 0x60(%rsp), %rax
movq 0x58(%rsp), %rcx
movq -0x8(%rax,%rcx,8), %rax
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rax
imulq %rax, %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, 0x18(%rsp)
testq %rax, %rax
movss %xmm0, 0x1c(%rsp)
js 0x25c5f
movss 0x18(%rsp), %xmm0
movss %xmm0, 0x1c(%rsp)
movss 0x1c(%rsp), %xmm0
movss %xmm0, 0x3c(%rsp)
movq 0xc0(%rsp), %rax
movq 0x40(%rsp), %rcx
imulq 0xa8(%rsp), %rcx
movq 0x80(%rsp), %rdx
imulq 0xa0(%rsp), %rdx
addq %rdx, %rcx
movss (%rax,%rcx,4), %xmm0
movss %xmm0, 0x38(%rsp)
movss 0x54(%rsp), %xmm0
ucomiss 0x38(%rsp), %xmm0
jne 0x25d12
jp 0x25d12
movq 0x88(%rsp), %rax
movq 0x40(%rsp), %rcx
addq %rcx, %rax
movq %rax, %xmm0
movaps 0x33495(%rip), %xmm1    # 0x59160
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x33499(%rip), %xmm1    # 0x59170
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movsd 0x333f2(%rip), %xmm1    # 0x590e0
divsd %xmm1, %xmm0
movss 0x90(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x34(%rsp)
jmp 0x25e2c
movss 0x94(%rsp), %xmm0
movss 0x334d5(%rip), %xmm1    # 0x591f8
ucomiss %xmm1, %xmm0
jbe 0x25de2
movss 0x54(%rsp), %xmm1
movss 0x38(%rsp), %xmm0
subss %xmm0, %xmm1
movss 0x94(%rsp), %xmm0
movss 0x50(%rsp), %xmm2
movss 0x3c(%rsp), %xmm3
subss %xmm3, %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, 0xc(%rsp)
movq 0x88(%rsp), %rax
movq 0x40(%rsp), %rcx
subq %rcx, %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, 0x10(%rsp)
testq %rax, %rax
movss %xmm0, 0x14(%rsp)
js 0x25dac
movss 0x10(%rsp), %xmm0
movss %xmm0, 0x14(%rsp)
movss 0xc(%rsp), %xmm0
movss 0x14(%rsp), %xmm1
divss %xmm1, %xmm0
movss 0x3348c(%rip), %xmm1    # 0x59250
mulss 0x94(%rsp), %xmm1
divss %xmm1, %xmm0
addss 0x90(%rsp), %xmm0
movss %xmm0, 0x34(%rsp)
jmp 0x25e2a
movss 0x54(%rsp), %xmm1
movss 0x38(%rsp), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x25e10
movss 0x33bd5(%rip), %xmm0    # 0x599d0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movss %xmm0, 0x8(%rsp)
jmp 0x25e1e
movss 0x33bb8(%rip), %xmm0    # 0x599d0
movss %xmm0, 0x8(%rsp)
movss 0x8(%rsp), %xmm0
movss %xmm0, 0x34(%rsp)
jmp 0x25e2c
movss 0x34(%rsp), %xmm1
movq 0x78(%rsp), %rax
movq 0x58(%rsp), %rcx
subq $0x1, %rcx
movss (%rax,%rcx,4), %xmm0
ucomiss %xmm1, %xmm0
jb 0x25e5a
movq 0x58(%rsp), %rax
addq $-0x1, %rax
movq %rax, 0x58(%rsp)
jmp 0x25e68
movss 0x34(%rsp), %xmm0
movss %xmm0, 0x4c(%rsp)
jmp 0x25e6d
jmp 0x25bfd
movq 0x88(%rsp), %rdx
movq 0x60(%rsp), %rax
movq 0x58(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movss 0x4c(%rsp), %xmm0
movq 0x78(%rsp), %rax
movq 0x58(%rsp), %rcx
movss %xmm0, (%rax,%rcx,4)
movss 0x54(%rsp), %xmm0
movq 0x70(%rsp), %rax
movq 0x58(%rsp), %rcx
movss %xmm0, (%rax,%rcx,4)
cmpq $0x0, 0xd0(%rsp)
je 0x25ef7
movq 0xd0(%rsp), %rax
movq 0x88(%rsp), %rcx
imulq 0xa8(%rsp), %rcx
movq 0x80(%rsp), %rdx
imulq 0xa0(%rsp), %rdx
addq %rdx, %rcx
movq (%rax,%rcx,8), %rdx
movq 0x68(%rsp), %rax
movq 0x58(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movq 0x58(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x58(%rsp)
movq 0x88(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x88(%rsp)
jmp 0x25b3d
movss 0x33aaa(%rip), %xmm0    # 0x599d0
movq 0x78(%rsp), %rax
movq 0x58(%rsp), %rcx
movss %xmm0, (%rax,%rcx,4)
movq $0x0, 0x58(%rsp)
movq $0x0, 0x88(%rsp)
movq 0x88(%rsp), %rax
cmpq 0xb8(%rsp), %rax
jae 0x260ff
jmp 0x25f62
movq 0x88(%rsp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, (%rsp)
testq %rax, %rax
movss %xmm0, 0x4(%rsp)
js 0x25fa1
movss (%rsp), %xmm0
movss %xmm0, 0x4(%rsp)
movss 0x4(%rsp), %xmm0
movq 0x78(%rsp), %rax
movq 0x58(%rsp), %rcx
ucomiss 0x4(%rax,%rcx,4), %xmm0
jb 0x25fc8
movq 0x58(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x58(%rsp)
jmp 0x25f62
movq 0x88(%rsp), %xmm0
movaps 0x33188(%rip), %xmm3    # 0x59160
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
movapd 0x3318c(%rip), %xmm2    # 0x59170
subpd %xmm2, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movq 0x60(%rsp), %rax
movq 0x58(%rsp), %rcx
movq (%rax,%rcx,8), %xmm1
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
subsd %xmm1, %xmm0
movss 0x90(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x28(%rsp)
movq 0x70(%rsp), %rax
movq 0x58(%rsp), %rcx
movss (%rax,%rcx,4), %xmm0
cvtss2sd %xmm0, %xmm1
movss 0x94(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
mulsd 0x28(%rsp), %xmm0
movsd 0x28(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x98(%rsp), %rax
movq 0x88(%rsp), %rcx
imulq 0xa8(%rsp), %rcx
movq 0x80(%rsp), %rdx
imulq 0xa0(%rsp), %rdx
addq %rdx, %rcx
movss %xmm0, (%rax,%rcx,4)
cmpq $0x0, 0xd0(%rsp)
je 0x260e4
movq 0x68(%rsp), %rax
movq 0x58(%rsp), %rcx
movq (%rax,%rcx,8), %rdx
movq 0xd0(%rsp), %rax
movq 0x88(%rsp), %rcx
imulq 0xa8(%rsp), %rcx
movq 0x80(%rsp), %rsi
imulq 0xa0(%rsp), %rsi
addq %rsi, %rcx
movq %rdx, (%rax,%rcx,8)
jmp 0x260e6
movq 0x88(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x88(%rsp)
jmp 0x25f4a
jmp 0x26101
movq 0x80(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x80(%rsp)
jmp 0x25b12
movq 0x78(%rsp), %rdi
callq 0x9620
movq 0x60(%rsp), %rdi
callq 0x9620
movq 0x70(%rsp), %rdi
callq 0x9620
movq 0x68(%rsp), %rdi
callq 0x9620
addq $0xc8, %rsp
retq
nopw (%rax,%rax)