// File: /workspace/github_c_makefile_star2_O1/zpole[P]IICV/vl/covdet.c
// Function: vl_covdet_extract_laplacian_scales_for_frame
VlCovDetFeatureLaplacianScale *
vl_covdet_extract_laplacian_scales_for_frame (VlCovDet * self,
                                              vl_size * numScales,
                                              VlFrameOrientedEllipse frame)
{
  /*
   We try to explore one octave, with the nominal detection scale 1.0
   (in the patch reference frame) in the middle. Thus the goal is to sample
   the response of the tr-Laplacian operator at logarithmically
   spaced scales in 1/sqrt(2), sqrt(2).

   To this end, the patch is warped with a smoothing of at most
   sigmaImage = 1 / sqrt(2) (beginning of the scale), sampled at
   roughly twice the Nyquist frequency (so step = 1 / (2*sqrt(2))).
   This maes it possible to approximate the Laplacian operator at
   that scale by simple finite differences.

   */
  int err ;
  double const sigmaImage = 1.0 / sqrt(2.0) ;
  double const step = 0.5 * sigmaImage ;
  double actualSigmaImage ;
  vl_size const resolution = VL_COVDET_LAP_PATCH_RESOLUTION ;
  vl_size const num = 2 * resolution + 1 ;
  double extent = step * resolution ;
  double scores [VL_COVDET_LAP_NUM_LEVELS] ;
  double factor = 1.0 ;
  float const * pt ;
  vl_index k ;

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

  assert(self) ;
  assert(numScales) ;

  *numScales = 0 ;

  vl_svd2(D, U, V, A) ;

  err = vl_covdet_extract_patch_helper
  (self, &sigma1, &sigma2, self->lapPatch, resolution, extent, sigmaImage, A, T, D[0], D[3]) ;
  if (err) return NULL ;

  /* the actual smoothing after warping is never the target one */
  if (sigma1 == sigma2) {
    actualSigmaImage = sigma1 ;
  } else {
    /* here we could compensate */
    actualSigmaImage = sqrt(sigma1*sigma2) ;
  }

  /* now multiply by the bank of Laplacians */
  pt = self->laplacians ;
  for (k = 0 ; k < VL_COVDET_LAP_NUM_LEVELS ; ++k) {
    vl_index q ;
    double score = 0 ;
    double sigmaLap = pow(2.0, -0.5 + (double)k / (VL_COVDET_LAP_NUM_LEVELS - 1)) ;
    /* note that the sqrt argument cannot be negative since by construction
     sigmaLap >= sigmaImage */
    sigmaLap = sqrt(sigmaLap*sigmaLap
                    - sigmaImage*sigmaImage
                    + actualSigmaImage*actualSigmaImage) ;

    for (q = 0 ; q < (signed)(num * num) ; ++q) {
      score += (*pt++) * self->lapPatch[q] ;
    }
    scores[k] = score * sigmaLap * sigmaLap ;
  }

  /* find and interpolate maxima */
  for (k = 1 ; k < VL_COVDET_LAP_NUM_LEVELS - 1 ; ++k) {
    double a = scores[k-1] ;
    double b = scores[k] ;
    double c = scores[k+1] ;
    double t = self->lapPeakThreshold ;

    if ((((b > a) && (b > c)) || ((b < a) && (b < c))) && (vl_abs_d(b) >= t)) {
      double dk = - 0.5 * (c - a) / (c + a - 2 * b) ;
      double s = k + dk ;
      double sigmaLap = pow(2.0, -0.5 + s / (VL_COVDET_LAP_NUM_LEVELS - 1)) ;
      double scale ;
      sigmaLap = sqrt(sigmaLap*sigmaLap
                      - sigmaImage*sigmaImage
                      + actualSigmaImage*actualSigmaImage) ;
      scale = sigmaLap / 1.0 ;
      /*
       VL_PRINTF("** k:%d, s:%f, sigmaLapFilter:%f, sigmaLap%f, scale:%f (%f %f %f)\n",
       k,s,sigmaLapFilter,sigmaLap,scale,a,b,c) ;
       */
      if (*numScales < VL_COVDET_MAX_NUM_LAPLACIAN_SCALES) {
        self->scales[*numScales].scale = scale * factor ;
        self->scales[*numScales].score = b + 0.5 * (c - a) * dk ;
        *numScales += 1 ;
      }
    }
  }
  return self->scales ;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x128, %rsp            # imm = 0x128
movq %rsi, %rbx
movq %rdi, %r14
movups 0x168(%rsp), %xmm0
movss 0x170(%rsp), %xmm1
movlhps %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
shufps $0xe2, %xmm0, %xmm1     # xmm1 = xmm1[2,0],xmm0[2,3]
cvtps2pd %xmm1, %xmm0
leaq 0x100(%rsp), %r12
movaps %xmm0, (%r12)
movaps 0x160(%rsp), %xmm0
movss 0x174(%rsp), %xmm1
shufps $0xf4, %xmm0, %xmm1     # xmm1 = xmm1[0,1],xmm0[3,3]
shufps $0xf2, %xmm0, %xmm1     # xmm1 = xmm1[2,0],xmm0[3,3]
cvtps2pd %xmm1, %xmm0
cvtps2pd 0x160(%rsp), %xmm1
movaps %xmm0, 0x10(%r12)
leaq 0x40(%rsp), %rbp
movaps %xmm1, (%rbp)
movq $0x0, (%rsi)
leaq 0xe0(%rsp), %r13
leaq 0xc0(%rsp), %rsi
leaq 0xa0(%rsp), %rdx
movq %r13, %rdi
movq %r12, %rcx
callq 0x9650
leaq 0x6a14(%r14), %r15
movsd (%r13), %xmm2
movsd 0x18(%r13), %xmm3
movq %rbp, (%rsp)
leaq 0x28(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movsd 0x24863(%rip), %xmm0    # 0x33288
movsd 0x24863(%rip), %xmm1    # 0x33290
movl $0x10, %r8d
movq %r14, %rdi
movq %r15, %rcx
movq %r12, %r9
callq 0xd08b
testl %eax, %eax
je 0xea4d
xorl %r15d, %r15d
jmp 0xec45
movsd 0x28(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jne 0xea61
jnp 0xea7a
mulsd %xmm1, %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0xea75
sqrtsd %xmm0, %xmm0
jmp 0xea7a
callq 0x9990
leaq 0x7b18(%r14), %r12
xorl %r13d, %r13d
mulsd %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
xorps %xmm0, %xmm0
cvtsi2sd %r13, %xmm0
divsd 0x24782(%rip), %xmm0    # 0x33220
addsd 0x24772(%rip), %xmm0    # 0x33218
callq 0x9040
mulsd %xmm0, %xmm0
addsd 0x24771(%rip), %xmm0    # 0x33228
addsd 0x8(%rsp), %xmm0
ucomisd 0x2456b(%rip), %xmm0    # 0x33030
jb 0xeacd
sqrtsd %xmm0, %xmm0
jmp 0xead2
callq 0x9990
xorpd %xmm1, %xmm1
xorl %eax, %eax
movss (%r12,%rax,4), %xmm2
mulss (%r15,%rax,4), %xmm2
cvtss2sd %xmm2, %xmm2
addsd %xmm2, %xmm1
incq %rax
cmpq $0x441, %rax            # imm = 0x441
jne 0xead8
addq $0x1104, %r12           # imm = 0x1104
mulsd %xmm0, %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, 0x50(%rsp,%r13,8)
incq %r13
cmpq $0xa, %r13
jne 0xea8e
leaq 0xc0(%r14), %r15
xorl %r12d, %r12d
movsd 0x50(%rsp,%r12,8), %xmm1
movsd 0x58(%rsp,%r12,8), %xmm4
movsd 0x60(%rsp,%r12,8), %xmm0
incq %r12
movsd 0x28(%r14), %xmm2
ucomisd %xmm1, %xmm4
jbe 0xeb4e
ucomisd %xmm0, %xmm4
ja 0xeb62
ucomisd %xmm4, %xmm1
jbe 0xec3b
ucomisd %xmm4, %xmm0
jbe 0xec3b
movapd %xmm4, %xmm3
andpd 0x24592(%rip), %xmm3    # 0x33100
ucomisd %xmm2, %xmm3
jb 0xec3b
movapd %xmm0, %xmm2
subsd %xmm1, %xmm2
movsd %xmm2, 0x18(%rsp)
movapd %xmm2, %xmm3
movsd 0x24686(%rip), %xmm2    # 0x33218
mulsd %xmm2, %xmm3
addsd %xmm0, %xmm1
movapd %xmm4, 0x30(%rsp)
movapd %xmm4, %xmm0
addsd %xmm4, %xmm0
subsd %xmm0, %xmm1
xorps %xmm0, %xmm0
cvtsi2sd %r12, %xmm0
divsd %xmm1, %xmm3
movsd %xmm3, 0x10(%rsp)
addsd %xmm3, %xmm0
divsd 0x24656(%rip), %xmm0    # 0x33220
addsd %xmm2, %xmm0
callq 0x9040
mulsd %xmm0, %xmm0
addsd 0x24649(%rip), %xmm0    # 0x33228
addsd 0x8(%rsp), %xmm0
ucomisd 0x24443(%rip), %xmm0    # 0x33030
jb 0xebf5
sqrtsd %xmm0, %xmm0
jmp 0xebfa
callq 0x9990
movq (%rbx), %rax
cmpq $0x3, %rax
movapd 0x30(%rsp), %xmm1
ja 0xec3b
movq %rax, %rcx
shlq $0x4, %rcx
movsd %xmm0, (%r15,%rcx)
movsd 0x18(%rsp), %xmm0
mulsd 0x245ac(%rip), %xmm0    # 0x331d0
mulsd 0x10(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%r15,%rcx)
incq %rax
movq %rax, (%rbx)
cmpq $0x8, %r12
jne 0xeb24
movq %r15, %rax
addq $0x128, %rsp            # imm = 0x128
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq