// File: /workspace/github_c_makefile_star2_O0/zpole[P]IICV/vl/covdet.c
// Function: vl_covdet_extract_orientations_for_frame
VlCovDetFeatureOrientation *
vl_covdet_extract_orientations_for_frame (VlCovDet * self,
                                          vl_size * numOrientations,
                                          VlFrameOrientedEllipse frame)
{
  int err ;
  vl_index k, i ;
  vl_index iter ;

  double extent = VL_COVDET_AA_PATCH_EXTENT ;
  vl_size resolution = VL_COVDET_AA_PATCH_RESOLUTION ;
  vl_size side = 2 * resolution + 1  ;

  vl_size const numBins = VL_COVDET_OR_NUM_ORIENTATION_HISTOGAM_BINS ;
  double hist [VL_COVDET_OR_NUM_ORIENTATION_HISTOGAM_BINS] ;
  double const binExtent = 2 * VL_PI / VL_COVDET_OR_NUM_ORIENTATION_HISTOGAM_BINS ;
  double const peakRelativeSize = VL_COVDET_OR_ADDITIONAL_PEAKS_RELATIVE_SIZE ;
  double maxPeakValue ;

  double A [2*2] = {frame.a11, frame.a21, frame.a12, frame.a22} ;
  double T [2] = {frame.x, frame.y} ;
  double U [2*2] ;
  double V [2*2] ;
  double D [2*2] ;
  double sigma1, sigma2 ;
  double sigmaD = 1.0 ;
  double theta0 ;

  assert(self);
  assert(numOrientations) ;

  /*
   The goal is to estimate a rotation R(theta) such that the patch given
   by the transformation A R(theta) has the strongest average
   gradient pointing right (or down for transposed conventions).

   To compensate for tha anisotropic smoothing due to warping,
   A is decomposed as A = U D V' and the patch is warped by
   U D only, meaning that the matrix R_(theta) will be estimated instead,
   where:

      A R(theta) = U D V' R(theta) = U D R_(theta)

   such that R(theta) = V R(theta). That is an extra rotation of
   theta0 = atan2(V(2,1),V(1,1)).
   */

  /* axis aligned anisotropic smoothing for easier compensation */
  vl_svd2(D, U, V, A) ;

  A[0] = U[0] * D[0] ;
  A[1] = U[1] * D[0] ;
  A[2] = U[2] * D[3] ;
  A[3] = U[3] * D[3] ;

  theta0 = atan2(V[1],V[0]) ;

  err = vl_covdet_extract_patch_helper(self,
                                       &sigma1, &sigma2,
                                       self->aaPatch,
                                       resolution,
                                       extent,
                                       sigmaD,
                                       A, T, D[0], D[3]) ;

  if (err) {
    *numOrientations = 0 ;
    return NULL ;
  }

  if (1) {
    double deltaSigma1 = sqrt(VL_MAX(sigmaD*sigmaD - sigma1*sigma1,0)) ;
    double deltaSigma2 = sqrt(VL_MAX(sigmaD*sigmaD - sigma2*sigma2,0)) ;
    double stephat = extent / resolution ;
    vl_imsmooth_f(self->aaPatch, side,
                  self->aaPatch, side, side, side,
                  deltaSigma1 / stephat, deltaSigma2 / stephat) ;
  }

  /* histogram of oriented gradients */
  vl_imgradient_polar_f (self->aaPatchX, self->aaPatchY, 1, side,
                         self->aaPatch, side, side, side) ;

  memset (hist, 0, sizeof(double) * numBins) ;

  for (k = 0 ; k < (signed)(side*side) ; ++k) {
    double modulus = self->aaPatchX[k] ;
    double angle = self->aaPatchY[k] ;
    double weight = self->aaMask[k] ;

    double x = angle / binExtent ;
    vl_index bin = vl_floor_d(x) ;
    double w2 = x - bin ;
    double w1 = 1.0 - w2 ;

    hist[(bin + numBins) % numBins] += w1 * (modulus * weight) ;
    hist[(bin + numBins + 1) % numBins] += w2 * (modulus * weight) ;
  }

  /* smooth histogram */
  for (iter = 0; iter < 6; iter ++) {
    double prev = hist [numBins - 1] ;
    double first = hist [0] ;
    vl_index i ;
    for (i = 0; i < (signed)numBins - 1; ++i) {
      double curr = (prev + hist[i] + hist[(i + 1) % numBins]) / 3.0 ;
      prev = hist[i] ;
      hist[i] = curr ;
    }
    hist[i] = (prev + hist[i] + first) / 3.0 ;
  }

  /* find the histogram maximum */
  maxPeakValue = 0 ;
  for (i = 0 ; i < (signed)numBins ; ++i) {
    maxPeakValue = VL_MAX (maxPeakValue, hist[i]) ;
  }

  /* find peaks within 80% from max */
  *numOrientations = 0 ;
  for(i = 0 ; i < (signed)numBins ; ++i) {
    double h0 = hist [i] ;
    double hm = hist [(i - 1 + numBins) % numBins] ;
    double hp = hist [(i + 1 + numBins) % numBins] ;

    /* is this a peak? */
    if (h0 > peakRelativeSize * maxPeakValue && h0 > hm && h0 > hp) {
      /* quadratic interpolation */
      double di = - 0.5 * (hp - hm) / (hp + hm - 2 * h0) ;
      double th = binExtent * (i + di) + theta0 ;
      if (self->transposed) {
        /* the axis to the right is y, measure orientations from this */
        th = th - VL_PI/2 ;
      }
      self->orientations[*numOrientations].angle = th ;
      self->orientations[*numOrientations].score = h0 ;
      *numOrientations += 1 ;
      //VL_PRINTF("%d %g\n", *numOrientations, th) ;

      if (*numOrientations >= VL_COVDET_MAX_NUM_ORIENTATIONS) break ;
    }
  }

  /* sort the orientations by decreasing scores */
  qsort(self->orientations,
        *numOrientations,
        sizeof(VlCovDetFeatureOrientation),
        _vl_covdet_compare_orientations_descending) ;

  return self->orientations ;
}

// Assembly:
subq $0x308, %rsp            # imm = 0x308
leaq 0x310(%rsp), %rax
movq %rdi, 0x2f8(%rsp)
movq %rsi, 0x2f0(%rsp)
movsd 0x46f09(%rip), %xmm0    # 0x590f0
movsd %xmm0, 0x2c8(%rsp)
movq $0x14, 0x2c0(%rsp)
movq 0x2c0(%rsp), %rcx
shlq %rcx
addq $0x1, %rcx
movq %rcx, 0x2b8(%rsp)
movq $0x24, 0x2b0(%rsp)
movsd 0x46f11(%rip), %xmm0    # 0x59138
movsd %xmm0, 0x188(%rsp)
movsd 0x46ec8(%rip), %xmm0    # 0x59100
movsd %xmm0, 0x180(%rsp)
movss 0x8(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x150(%rsp)
movss 0x10(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x158(%rsp)
movss 0xc(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x160(%rsp)
movss 0x14(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x168(%rsp)
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x140(%rsp)
movss 0x4(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x148(%rsp)
movsd 0x46e24(%rip), %xmm0    # 0x590d8
movsd %xmm0, 0xc8(%rsp)
leaq 0xe0(%rsp), %rdi
leaq 0x120(%rsp), %rsi
leaq 0x100(%rsp), %rdx
leaq 0x150(%rsp), %rcx
callq 0x9730
movsd 0x120(%rsp), %xmm0
mulsd 0xe0(%rsp), %xmm0
movsd %xmm0, 0x150(%rsp)
movsd 0x128(%rsp), %xmm0
mulsd 0xe0(%rsp), %xmm0
movsd %xmm0, 0x158(%rsp)
movsd 0x130(%rsp), %xmm0
mulsd 0xf8(%rsp), %xmm0
movsd %xmm0, 0x160(%rsp)
movsd 0x138(%rsp), %xmm0
mulsd 0xf8(%rsp), %xmm0
movsd %xmm0, 0x168(%rsp)
movsd 0x108(%rsp), %xmm0
movsd 0x100(%rsp), %xmm1
callq 0x9820
movsd %xmm0, 0xc0(%rsp)
movq 0x2f8(%rsp), %rdi
movq 0x2f8(%rsp), %rcx
addq $0x104, %rcx            # imm = 0x104
movq 0x2c0(%rsp), %r8
movsd 0x2c8(%rsp), %xmm0
movsd 0xc8(%rsp), %xmm1
leaq 0x150(%rsp), %r9
leaq 0x140(%rsp), %rax
movsd 0xe0(%rsp), %xmm2
movsd 0xf8(%rsp), %xmm3
leaq 0xd8(%rsp), %rsi
leaq 0xd0(%rsp), %rdx
movq %rax, (%rsp)
callq 0xfdd0
movl %eax, 0x2ec(%rsp)
cmpl $0x0, 0x2ec(%rsp)
je 0x1240b
movq 0x2f0(%rsp), %rax
movq $0x0, (%rax)
movq $0x0, 0x300(%rsp)
jmp 0x12c26
movsd 0xc8(%rsp), %xmm0
movsd 0xc8(%rsp), %xmm2
movsd 0xd8(%rsp), %xmm1
mulsd 0xd8(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x124a2
movsd 0xc8(%rsp), %xmm0
movsd 0xc8(%rsp), %xmm2
movsd 0xd8(%rsp), %xmm1
mulsd 0xd8(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x20(%rsp)
jmp 0x124ad
xorps %xmm0, %xmm0
movsd %xmm0, 0x20(%rsp)
jmp 0x124ad
movsd 0x20(%rsp), %xmm0
callq 0x9b20
movsd %xmm0, 0xb8(%rsp)
movsd 0xc8(%rsp), %xmm0
movsd 0xc8(%rsp), %xmm2
movsd 0xd0(%rsp), %xmm1
mulsd 0xd0(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x12558
movsd 0xc8(%rsp), %xmm0
movsd 0xc8(%rsp), %xmm2
movsd 0xd0(%rsp), %xmm1
mulsd 0xd0(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x18(%rsp)
jmp 0x12563
xorps %xmm0, %xmm0
movsd %xmm0, 0x18(%rsp)
jmp 0x12563
movsd 0x18(%rsp), %xmm0
callq 0x9b20
movsd %xmm0, 0xb0(%rsp)
movsd 0x2c8(%rsp), %xmm0
movaps 0x46bd9(%rip), %xmm2    # 0x59160
movq 0x2c0(%rsp), %xmm1
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x46bd4(%rip), %xmm2    # 0x59170
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0xa8(%rsp)
movq 0x2f8(%rsp), %rdi
addq $0x104, %rdi            # imm = 0x104
movq 0x2b8(%rsp), %rsi
movq 0x2f8(%rsp), %rdx
addq $0x104, %rdx            # imm = 0x104
movq 0x2b8(%rsp), %rcx
movq 0x2b8(%rsp), %r8
movq 0x2b8(%rsp), %r9
movsd 0xb8(%rsp), %xmm0
divsd 0xa8(%rsp), %xmm0
movsd 0xb0(%rsp), %xmm1
divsd 0xa8(%rsp), %xmm1
callq 0x98e0
movq 0x2f8(%rsp), %rdi
addq $0x1b48, %rdi           # imm = 0x1B48
movq 0x2f8(%rsp), %rsi
addq $0x358c, %rsi           # imm = 0x358C
movq 0x2b8(%rsp), %rcx
movq 0x2f8(%rsp), %r8
addq $0x104, %r8             # imm = 0x104
movq 0x2b8(%rsp), %r9
movq 0x2b8(%rsp), %r10
movq 0x2b8(%rsp), %rax
movl $0x1, %edx
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x9140
leaq 0x190(%rsp), %rdi
xorl %esi, %esi
movl $0x120, %edx            # imm = 0x120
callq 0x9480
movq $0x0, 0x2e0(%rsp)
movq 0x2e0(%rsp), %rax
movq 0x2b8(%rsp), %rcx
imulq 0x2b8(%rsp), %rcx
movslq %ecx, %rcx
cmpq %rcx, %rax
jge 0x12848
movq 0x2f8(%rsp), %rax
movq 0x2e0(%rsp), %rcx
movss 0x1b48(%rax,%rcx,4), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0xa0(%rsp)
movq 0x2f8(%rsp), %rax
movq 0x2e0(%rsp), %rcx
movss 0x358c(%rax,%rcx,4), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x98(%rsp)
movq 0x2f8(%rsp), %rax
movq 0x2e0(%rsp), %rcx
movss 0x4fd0(%rax,%rcx,4), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x90(%rsp)
movsd 0x98(%rsp), %xmm0
movsd 0x469f1(%rip), %xmm1    # 0x59138
divsd %xmm1, %xmm0
movsd %xmm0, 0x88(%rsp)
movsd 0x88(%rsp), %xmm0
callq 0xdf80
movq %rax, 0x80(%rsp)
movsd 0x88(%rsp), %xmm0
cvtsi2sdq 0x80(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x78(%rsp)
movsd 0x46949(%rip), %xmm0    # 0x590d8
subsd 0x78(%rsp), %xmm0
movsd %xmm0, 0x70(%rsp)
movsd 0x70(%rsp), %xmm0
movsd 0xa0(%rsp), %xmm2
mulsd 0x90(%rsp), %xmm2
movq 0x80(%rsp), %rax
addq $0x24, %rax
movl $0x24, %ecx
xorl %edx, %edx
divq %rcx
movsd 0x190(%rsp,%rdx,8), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x190(%rsp,%rdx,8)
movsd 0x78(%rsp), %xmm0
movsd 0xa0(%rsp), %xmm2
mulsd 0x90(%rsp), %xmm2
movq 0x80(%rsp), %rax
addq $0x24, %rax
addq $0x1, %rax
movl $0x24, %ecx
xorl %edx, %edx
divq %rcx
movsd 0x190(%rsp,%rdx,8), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x190(%rsp,%rdx,8)
movq 0x2e0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x2e0(%rsp)
jmp 0x1269f
movq $0x0, 0x2d0(%rsp)
cmpq $0x6, 0x2d0(%rsp)
jge 0x1295c
movsd 0x2a8(%rsp), %xmm0
movsd %xmm0, 0x68(%rsp)
movsd 0x190(%rsp), %xmm0
movsd %xmm0, 0x60(%rsp)
movq $0x0, 0x58(%rsp)
cmpq $0x23, 0x58(%rsp)
jge 0x1290f
movsd 0x68(%rsp), %xmm0
movq 0x58(%rsp), %rax
addsd 0x190(%rsp,%rax,8), %xmm0
movq 0x58(%rsp), %rax
addq $0x1, %rax
movl $0x24, %ecx
xorl %edx, %edx
divq %rcx
addsd 0x190(%rsp,%rdx,8), %xmm0
movsd 0x467fe(%rip), %xmm1    # 0x590c8
divsd %xmm1, %xmm0
movsd %xmm0, 0x50(%rsp)
movq 0x58(%rsp), %rax
movsd 0x190(%rsp,%rax,8), %xmm0
movsd %xmm0, 0x68(%rsp)
movsd 0x50(%rsp), %xmm0
movq 0x58(%rsp), %rax
movsd %xmm0, 0x190(%rsp,%rax,8)
movq 0x58(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x58(%rsp)
jmp 0x1288a
movsd 0x68(%rsp), %xmm0
movq 0x58(%rsp), %rax
addsd 0x190(%rsp,%rax,8), %xmm0
addsd 0x60(%rsp), %xmm0
movsd 0x46797(%rip), %xmm1    # 0x590c8
divsd %xmm1, %xmm0
movq 0x58(%rsp), %rax
movsd %xmm0, 0x190(%rsp,%rax,8)
movq 0x2d0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x2d0(%rsp)
jmp 0x12854
xorps %xmm0, %xmm0
movsd %xmm0, 0x178(%rsp)
movq $0x0, 0x2d8(%rsp)
cmpq $0x24, 0x2d8(%rsp)
jge 0x129e8
movsd 0x178(%rsp), %xmm0
movq 0x2d8(%rsp), %rax
ucomisd 0x190(%rsp,%rax,8), %xmm0
jbe 0x129ac
movsd 0x178(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
jmp 0x129c3
movq 0x2d8(%rsp), %rax
movsd 0x190(%rsp,%rax,8), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x10(%rsp), %xmm0
movsd %xmm0, 0x178(%rsp)
movq 0x2d8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x2d8(%rsp)
jmp 0x12974
movq 0x2f0(%rsp), %rax
movq $0x0, (%rax)
movq $0x0, 0x2d8(%rsp)
cmpq $0x24, 0x2d8(%rsp)
jge 0x12be5
movq 0x2d8(%rsp), %rax
movsd 0x190(%rsp,%rax,8), %xmm0
movsd %xmm0, 0x48(%rsp)
movq 0x2d8(%rsp), %rax
subq $0x1, %rax
addq $0x24, %rax
movl $0x24, %ecx
xorl %edx, %edx
divq %rcx
movsd 0x190(%rsp,%rdx,8), %xmm0
movsd %xmm0, 0x40(%rsp)
movq 0x2d8(%rsp), %rax
addq $0x1, %rax
addq $0x24, %rax
movl $0x24, %ecx
xorl %edx, %edx
divq %rcx
movsd 0x190(%rsp,%rdx,8), %xmm0
movsd %xmm0, 0x38(%rsp)
movsd 0x48(%rsp), %xmm0
movsd 0x46677(%rip), %xmm1    # 0x59100
mulsd 0x178(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x12bca
movsd 0x48(%rsp), %xmm0
ucomisd 0x40(%rsp), %xmm0
jbe 0x12bca
movsd 0x48(%rsp), %xmm0
ucomisd 0x38(%rsp), %xmm0
jbe 0x12bca
movsd 0x38(%rsp), %xmm1
subsd 0x40(%rsp), %xmm1
movsd 0x46614(%rip), %xmm0    # 0x590e8
mulsd %xmm1, %xmm0
movsd 0x38(%rsp), %xmm1
addsd 0x40(%rsp), %xmm1
movsd 0x48(%rsp), %xmm2
addsd %xmm2, %xmm2
subsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x30(%rsp)
cvtsi2sdq 0x2d8(%rsp), %xmm0
addsd 0x30(%rsp), %xmm0
movsd 0xc0(%rsp), %xmm1
movsd 0x4661b(%rip), %xmm2    # 0x59138
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x28(%rsp)
movq 0x2f8(%rsp), %rax
cmpl $0x0, 0x78(%rax)
je 0x12b51
movsd 0x28(%rsp), %xmm0
movsd 0x465f9(%rip), %xmm1    # 0x59140
subsd %xmm1, %xmm0
movsd %xmm0, 0x28(%rsp)
movsd 0x28(%rsp), %xmm0
movq 0x2f8(%rsp), %rax
addq $0x80, %rax
movq 0x2f0(%rsp), %rcx
movq (%rcx), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movsd %xmm0, (%rax)
movsd 0x48(%rsp), %xmm0
movq 0x2f8(%rsp), %rax
addq $0x80, %rax
movq 0x2f0(%rsp), %rcx
movq (%rcx), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movsd %xmm0, 0x8(%rax)
movq 0x2f0(%rsp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq 0x2f0(%rsp), %rax
cmpq $0x4, (%rax)
jb 0x12bc8
jmp 0x12be5
jmp 0x12bca
jmp 0x12bcc
movq 0x2d8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x2d8(%rsp)
jmp 0x12a03
movq 0x2f8(%rsp), %rdi
addq $0x80, %rdi
movq 0x2f0(%rsp), %rax
movq (%rax), %rsi
movl $0x10, %edx
leaq 0x35(%rip), %rcx        # 0x12c40
callq 0x91b0
movq 0x2f8(%rsp), %rax
addq $0x80, %rax
movq %rax, 0x300(%rsp)
movq 0x300(%rsp), %rax
addq $0x308, %rsp            # imm = 0x308
retq
nopw %cs:(%rax,%rax)