// File: /workspace/github_cpp_makefile_star2_O2/manikandan5[P]Image-Matching-Stitching-Warping/siftpp/sift.cpp
// Function: VL::Sift::getKeypoint(float, float, float) const
Sift::Keypoint
Sift::getKeypoint(VL::float_t x, VL::float_t y, VL::float_t sigma) const
{

  /*
    The formula linking the keypoint scale sigma to the octave and
    scale index is

    (1) sigma(o,s) = sigma0 2^(o+s/S)

    for which
    
    (2) o + s/S = log2 sigma/sigma0 == phi.

    In addition to the scale index s (which can be fractional due to
    scale interpolation) a keypoint has an integer scale index is too
    (which is the index of the scale level where it was detected in
    the DoG scale space). We have the constraints:
 
    - o and is are integer

    - is is in the range [smin+1, smax-2  ]

    - o  is in the range [omin,   omin+O-1]

    - is = rand(s) most of the times (but not always, due to the way s
      is obtained by quadratic interpolation of the DoG scale space).

    Depending on the values of smin and smax, often (2) has multiple
    solutions is,o that satisfy all constraints.  In this case we
    choose the one with biggest index o (this saves a bit of
    computation).

    DETERMINING THE OCTAVE INDEX O

    From (2) we have o = phi - s/S and we want to pick the biggest
    possible index o in the feasible range. This corresponds to
    selecting the smallest possible index s. We write s = is + ds
    where in most cases |ds|<.5 (but in general |ds|<1). So we have

       o = phi - s/S,   s = is + ds ,   |ds| < .5 (or |ds| < 1).

    Since is is in the range [smin+1,smax-2], s is in the range
    [smin+.5,smax-1.5] (or [smin,smax-1]), the number o is an integer
    in the range phi+[-smax+1.5,-smin-.5] (or
    phi+[-smax+1,-smin]). Thus the maximum value of o is obtained for
    o = floor(phi-smin-.5) (or o = floor(phi-smin)).

    Finally o is clamped to make sure it is contained in the feasible
    range.

    DETERMINING THE SCALE INDEXES S AND IS

    Given o we can derive is by writing (2) as

      s = is + ds = S(phi - o).

    We then take is = round(s) and clamp its value to be in the
    feasible range.
  */

  int o,ix,iy,is ;
  VL::float_t s,phi ;

  phi = log2(sigma/sigma0) ;
  o   = fast_floor( phi -  (VL::float_t(smin)+.5)/S ) ;
  o   = std::min(o, omin+O-1) ;
  o   = std::max(o, omin    ) ;
  s   = S * (phi - o) ;

  is  = int(s + 0.5) ;
  is  = std::min(is, smax - 2) ;
  is  = std::max(is, smin + 1) ;
  
  VL::float_t per = getOctaveSamplingPeriod(o) ;
  ix = int(x / per + 0.5) ;
  iy = int(y / per + 0.5) ;
  
  Keypoint key ;
  key.o  = o ;

  key.ix = ix ;
  key.iy = iy ;
  key.is = is ;

  key.x = x ;
  key.y = y ;
  key.s = s ;
  
  key.sigma = sigma ;
  
  return key ;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x30, %rsp
movaps %xmm1, 0x20(%rsp)
movaps %xmm0, 0x10(%rsp)
movq %rsi, %r14
movq %rdi, %rbx
movss %xmm2, 0xc(%rsp)
movaps %xmm2, %xmm0
divss 0x4(%rsi), %xmm0
cvtss2sd %xmm0, %xmm0
callq 0x4970
cvtsd2ss %xmm0, %xmm1
movl 0x18(%r14), %ebp
cvtsi2ss %ebp, %xmm0
movss %xmm1, 0x8(%rsp)
cvtss2sd %xmm1, %xmm1
cvtss2sd %xmm0, %xmm0
addsd 0x2b8b(%rip), %xmm0     # 0x54068
movl 0xc(%r14), %r12d
movl 0x10(%r14), %r15d
cvtsi2sd %r15d, %xmm2
divsd %xmm2, %xmm0
subsd %xmm0, %xmm1
cvtsd2ss %xmm1, %xmm0
callq 0x41b0
cvttss2si %xmm0, %eax
movl 0x14(%r14), %ecx
leal (%rcx,%r12), %edx
decl %edx
cmpl %eax, %edx
cmovll %edx, %eax
cmpl %ecx, %eax
cmovlel %ecx, %eax
movl 0x1c(%r14), %edx
testl %eax, %eax
js 0x51528
pushq $0x1
popq %rsi
movl %eax, %ecx
shll %cl, %esi
cvtsi2ss %esi, %xmm0
jmp 0x51541
movl %eax, %ecx
negb %cl
pushq $0x1
popq %rsi
shll %cl, %esi
cvtsi2ss %esi, %xmm1
movss 0x2ce3(%rip), %xmm0     # 0x54220
divss %xmm1, %xmm0
cvtsi2ss %eax, %xmm1
movss 0x8(%rsp), %xmm2
subss %xmm1, %xmm2
cvtsi2ss %r15d, %xmm1
incl %ebp
addl $-0x2, %edx
mulss %xmm2, %xmm1
cvtss2sd %xmm1, %xmm2
addsd 0x2aff(%rip), %xmm2     # 0x54068
cvttsd2si %xmm2, %ecx
cmpl %ecx, %edx
cmovgel %ecx, %edx
cmpl %ebp, %edx
cmovlel %ebp, %edx
movaps 0x10(%rsp), %xmm4
movaps %xmm4, %xmm2
movaps 0x20(%rsp), %xmm3
unpcklps %xmm3, %xmm2            # xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
shufps $0x0, %xmm0, %xmm0      # xmm0 = xmm0[0,0,0,0]
divps %xmm0, %xmm2
cvtps2pd %xmm2, %xmm0
addpd 0x27fa7(%rip), %xmm0    # 0x79540
cvttpd2dq %xmm0, %xmm0
movl %eax, (%rbx)
movlpd %xmm0, 0x4(%rbx)
movl %edx, 0xc(%rbx)
movss %xmm4, 0x10(%rbx)
movss %xmm3, 0x14(%rbx)
movss %xmm1, 0x18(%rbx)
movss 0xc(%rsp), %xmm0
movss %xmm0, 0x1c(%rbx)
movq %rbx, %rax
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nop