// File: /workspace/github_c_makefile_star2_O3/zpole[P]IICV/vl/hog.c
// Function: vl_hog_new
VlHog *
vl_hog_new (VlHogVariant variant, vl_size numOrientations, vl_bool transposed)
{
  vl_index o, k ;
  VlHog * self = vl_calloc(1, sizeof(VlHog)) ;

  assert(numOrientations >= 1) ;

  self->variant = variant ;
  self->numOrientations = numOrientations ;
  self->glyphSize = 21 ;
  self->transposed = transposed ;
  self->useBilinearOrientationAssigment = VL_FALSE ;
  self->orientationX = vl_malloc(sizeof(float) * self->numOrientations) ;
  self->orientationY = vl_malloc(sizeof(float) * self->numOrientations) ;

  /*
   Create a vector along the center of each orientation bin. These
   are used to map gradients to bins. If the image is transposed,
   then this can be adjusted here by swapping X and Y in these
   vectors.
   */
  for(o = 0 ; o < (signed)self->numOrientations ; ++o) {
    double angle = o * VL_PI / self->numOrientations ;
    if (!self->transposed) {
      self->orientationX[o] = (float) cos(angle) ;
      self->orientationY[o] = (float) sin(angle) ;
    } else {
      self->orientationX[o] = (float) sin(angle) ;
      self->orientationY[o] = (float) cos(angle) ;
    }
  }

  /*
   If the number of orientation is equal to 9, one gets:

   Uoccti:: 18 directed orientations + 9 undirected orientations + 4 texture
   DalalTriggs:: 9 undirected orientations x 4 blocks.
   */
  switch (self->variant) {
    case VlHogVariantUoctti:
      self->dimension = 3*self->numOrientations + 4 ;
      break ;

    case VlHogVariantDalalTriggs:
      self->dimension = 4*self->numOrientations ;
      break ;

    default:
      assert(0) ;
  }

  /*
   A permutation specifies how to permute elements in a HOG
   descriptor to flip it horizontally. Since the first orientation
   of index 0 points to the right, this must be swapped with orientation
   self->numOrientation that points to the left (for the directed case,
   and to itself for the undirected one).
   */

  self->permutation = vl_malloc(self->dimension * sizeof(vl_index)) ;
  switch (self->variant) {
    case VlHogVariantUoctti:
      for(o = 0 ; o < (signed)self->numOrientations ; ++o) {
        vl_index op = self->numOrientations - o ;
        self->permutation[o] = op ;
        self->permutation[o + self->numOrientations] = (op + self->numOrientations) % (2*self->numOrientations) ;
        self->permutation[o + 2*self->numOrientations] = (op % self->numOrientations) + 2*self->numOrientations ;
      }
      for (k = 0 ; k < 4 ; ++k) {
        /* The texture features correspond to four displaced block around
         a cell. These permute with a lr flip as for DalalTriggs. */
        vl_index blockx = k % 2 ;
        vl_index blocky = k / 2 ;
        vl_index q = (1 - blockx) + blocky * 2 ;
        self->permutation[k + self->numOrientations * 3] = q + self->numOrientations * 3 ;
      }
      break ;

    case VlHogVariantDalalTriggs:
      for(k = 0 ; k < 4 ; ++k) {
        /* Find the corresponding block. Blocks are listed in order 1,2,3,4,...
           from left to right and top to bottom */
        vl_index blockx = k % 2 ;
        vl_index blocky = k / 2 ;
        vl_index q = (1 - blockx) + blocky * 2 ;
        for(o = 0 ; o < (signed)self->numOrientations ; ++o) {
          vl_index op = self->numOrientations - o ;
          self->permutation[o + k*self->numOrientations] = (op % self->numOrientations) + q*self->numOrientations ;
        }
      }
      break ;

    default:
      assert(0) ;
  }

  /*
   Create glyphs for representing the HOG features/ filters. The glyphs
   are simple bars, oriented orthogonally to the gradients to represent
   image edges. If the object is configured to work on transposed image,
   the glyphs images are also stored in column-major.
   */
  self->glyphs = vl_calloc(self->glyphSize * self->glyphSize * self->numOrientations, sizeof(float)) ;
#define atglyph(x,y,k) self->glyphs[(x) + self->glyphSize * (y) + self->glyphSize * self->glyphSize * (k)]
  for (o = 0 ; o < (signed)self->numOrientations ; ++o) {
    double angle = fmod(o * VL_PI / self->numOrientations + VL_PI/2, VL_PI) ;
    double x2 = self->glyphSize * cos(angle) / 2 ;
    double y2 = self->glyphSize * sin(angle) / 2 ;

    if (angle <= VL_PI / 4 || angle >= VL_PI * 3 / 4) {
      /* along horizontal direction */
      double slope = y2 / x2 ;
      double offset = (1 - slope) * (self->glyphSize - 1) / 2 ;
      vl_index skip = (1 - fabs(cos(angle))) / 2 * self->glyphSize ;
      vl_index i, j ;
      for (i = skip ; i < (signed)self->glyphSize - skip ; ++i) {
        j = vl_round_d(slope * i + offset) ;
        if (! self->transposed) {
          atglyph(i,j,o) = 1 ;
        } else {
          atglyph(j,i,o) = 1 ;
        }
      }
    } else {
      /* along vertical direction */
      double slope = x2 / y2 ;
      double offset = (1 - slope) * (self->glyphSize - 1) / 2 ;
      vl_index skip = (1 - sin(angle)) / 2 * self->glyphSize ;
      vl_index i, j ;
      for (j = skip ; j < (signed)self->glyphSize - skip; ++j) {
        i = vl_round_d(slope * j + offset) ;
        if (! self->transposed) {
          atglyph(i,j,o) = 1 ;
        } else {
          atglyph(j,i,o) = 1 ;
        }
      }
    }
  }
  return self ;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x40, %rsp
movl %edx, %ebp
movq %rsi, %r14
movl %edi, %r15d
movl $0x1, %edi
movl $0x68, %esi
callq 0x98f0
movq %rax, %rbx
movl %r15d, (%rax)
movq %r14, 0x10(%rax)
movq $0x15, 0x30(%rax)
movl %ebp, 0x18(%rax)
movl $0x0, 0x1c(%rax)
shlq $0x2, %r14
movq %r14, %rdi
callq 0x95b0
movq %rax, 0x38(%rbx)
movq 0x10(%rbx), %rdi
shlq $0x2, %rdi
callq 0x95b0
movq %rax, 0x40(%rbx)
movq 0x10(%rbx), %rdi
testl %edi, %edi
jle 0x14e9c
xorl %r14d, %r14d
xorps %xmm0, %xmm0
cvtsi2sd %r14, %xmm0
mulsd 0x1db79(%rip), %xmm0    # 0x32988
movq %rdi, %xmm2
punpckldq 0x1d364(%rip), %xmm2 # xmm2 = xmm2[0],mem[0],xmm2[1],mem[1]
subpd 0x1d36c(%rip), %xmm2    # 0x32190
movapd %xmm2, %xmm1
unpckhpd %xmm2, %xmm1            # xmm1 = xmm1[1],xmm2[1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
cmpl $0x0, 0x18(%rbx)
movsd %xmm0, (%rsp)
je 0x14e5e
callq 0x9860
cvtsd2ss %xmm0, %xmm0
movq 0x38(%rbx), %rax
movss %xmm0, (%rax,%r14,4)
movsd (%rsp), %xmm0
callq 0x9450
jmp 0x14e7b
callq 0x9450
cvtsd2ss %xmm0, %xmm0
movq 0x38(%rbx), %rax
movss %xmm0, (%rax,%r14,4)
movsd (%rsp), %xmm0
callq 0x9860
cvtsd2ss %xmm0, %xmm0
movq 0x40(%rbx), %rax
movss %xmm0, (%rax,%r14,4)
incq %r14
movq 0x10(%rbx), %rdi
movslq %edi, %rax
cmpq %rax, %r14
jl 0x14dff
movl (%rbx), %eax
testl %eax, %eax
je 0x14eb1
cmpl $0x1, %eax
jne 0x14ebb
leaq (%rdi,%rdi,2), %rdi
addq $0x4, %rdi
jmp 0x14eb5
shlq $0x2, %rdi
movq %rdi, 0x8(%rbx)
jmp 0x14ebf
movq 0x8(%rbx), %rdi
shlq $0x3, %rdi
callq 0x95b0
movq %rax, %rcx
movq %rax, 0x20(%rbx)
movl (%rbx), %eax
cmpl $0x1, %eax
je 0x14f37
testl %eax, %eax
jne 0x14fb3
movq 0x10(%rbx), %rdi
xorl %esi, %esi
xorl %r8d, %r8d
testl %edi, %edi
jle 0x14f28
movq %r8, %r9
xorq $0x1, %r9
xorl %r10d, %r10d
xorl %r11d, %r11d
leaq (%rdi,%r10), %rax
xorl %edx, %edx
divq %rdi
movq %rsi, %rax
imulq %rdi, %rax
imulq %r9, %rdi
addq %rdx, %rdi
addq %rcx, %rax
movq %rdi, (%rax,%r11,8)
incq %r11
movq 0x10(%rbx), %rdi
movslq %edi, %rax
decq %r10
cmpq %rax, %r11
jl 0x14ef8
incq %r8
addq $0x8, %rsi
cmpq $0x4, %r8
jne 0x14ee7
jmp 0x14fb3
movq 0x10(%rbx), %rsi
testl %esi, %esi
jle 0x14f8e
xorl %edi, %edi
xorl %r8d, %r8d
addq %rdi, %rsi
leaq (%rcx,%r8,8), %r9
movq %rsi, (%rcx,%r8,8)
movq 0x10(%rbx), %r10
leaq (%rsi,%r10), %rax
leaq (%r10,%r10), %r11
xorl %edx, %edx
divq %r11
movq %rdx, (%r9,%r10,8)
movq 0x10(%rbx), %r10
movq %rsi, %rax
xorl %edx, %edx
divq %r10
leaq (%rdx,%r10,2), %rax
shlq $0x4, %r10
movq %rax, (%r10,%r9)
incq %r8
movq 0x10(%rbx), %rsi
movslq %esi, %rax
decq %rdi
cmpq %rax, %r8
jl 0x14f44
xorl %eax, %eax
movq %rax, %rdx
xorq $0x1, %rdx
movq 0x10(%rbx), %rsi
leaq (%rsi,%rsi,2), %rsi
addq %rsi, %rdx
leaq (%rcx,%rsi,8), %rsi
movq %rdx, (%rsi,%rax,8)
incq %rax
cmpq $0x4, %rax
jne 0x14f90
movq 0x30(%rbx), %rdi
imulq %rdi, %rdi
imulq 0x10(%rbx), %rdi
movl $0x4, %esi
callq 0x98f0
movq %rax, 0x28(%rbx)
movq 0x10(%rbx), %rax
testl %eax, %eax
jle 0x15304
xorl %r14d, %r14d
xorps %xmm0, %xmm0
cvtsi2sd %r14, %xmm0
movsd 0x1d99b(%rip), %xmm1    # 0x32988
mulsd %xmm1, %xmm0
movq %rax, %xmm3
movq 0x1d182(%rip), %xmm2    # 0x32180
punpckldq %xmm2, %xmm3    # xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
movapd 0x1d186(%rip), %xmm2    # 0x32190
subpd %xmm2, %xmm3
movapd %xmm3, %xmm2
unpckhpd %xmm3, %xmm2            # xmm2 = xmm2[1],xmm3[1]
addsd %xmm3, %xmm2
divsd %xmm2, %xmm0
addsd 0x1d96a(%rip), %xmm0    # 0x32990
callq 0x9440
movsd %xmm0, 0x28(%rsp)
movsd 0x30(%rbx), %xmm1
unpcklps 0x1d143(%rip), %xmm1    # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x1d14b(%rip), %xmm1    # 0x32190
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
movapd %xmm2, (%rsp)
callq 0x9450
movapd %xmm0, %xmm1
mulsd (%rsp), %xmm1
movsd 0x1d174(%rip), %xmm0    # 0x321e0
mulsd %xmm0, %xmm1
movsd %xmm1, (%rsp)
movsd 0x30(%rbx), %xmm0
unpcklps 0x1d0ff(%rip), %xmm0    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1d107(%rip), %xmm0    # 0x32190
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd %xmm1, 0x10(%rsp)
movsd 0x28(%rsp), %xmm0
callq 0x9860
movsd 0x28(%rsp), %xmm2
mulsd 0x10(%rsp), %xmm0
mulsd 0x1d126(%rip), %xmm0    # 0x321e0
movsd %xmm0, 0x10(%rsp)
movq 0x30(%rbx), %rax
decq %rax
movsd 0x1d8c9(%rip), %xmm0    # 0x32998
ucomisd %xmm2, %xmm0
movq %rax, %xmm0
punpckldq 0x1d0a0(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1d0a8(%rip), %xmm0    # 0x32190
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd %xmm1, 0x30(%rsp)
jae 0x151fe
ucomisd 0x1d898(%rip), %xmm2    # 0x329a0
jae 0x151fe
movapd %xmm2, %xmm0
callq 0x9860
movsd 0x1d151(%rip), %xmm1    # 0x32270
subsd %xmm0, %xmm1
mulsd 0x1d0b5(%rip), %xmm1    # 0x321e0
movq 0x30(%rbx), %rax
movq %rax, %xmm0
punpckldq 0x1d044(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1d04c(%rip), %xmm0    # 0x32190
movapd %xmm0, %xmm2
unpckhpd %xmm0, %xmm2            # xmm2 = xmm2[1],xmm0[1]
addsd %xmm0, %xmm2
mulsd %xmm1, %xmm2
cvttsd2si %xmm2, %r15
cltq
subq %r15, %rax
cmpq %r15, %rax
movsd (%rsp), %xmm1
movsd 0x10(%rsp), %xmm0
jle 0x152f1
divsd %xmm0, %xmm1
movsd 0x1d0f2(%rip), %xmm0    # 0x32270
movsd %xmm1, (%rsp)
subsd %xmm1, %xmm0
mulsd 0x30(%rsp), %xmm0
mulsd 0x1d04b(%rip), %xmm0    # 0x321e0
movsd %xmm0, 0x10(%rsp)
movq %r15, %r12
xorps %xmm0, %xmm0
cvtsi2sd %r12, %xmm0
mulsd (%rsp), %xmm0
addsd 0x10(%rsp), %xmm0
callq 0x9230
movq 0x30(%rbx), %rcx
movq %rcx, %rdx
imulq %r14, %rdx
imulq %rcx, %rdx
cmpl $0x0, 0x18(%rbx)
movq %rax, %rsi
cmoveq %r12, %rsi
cmovneq %r12, %rax
imulq %rcx, %rsi
shlq $0x2, %rax
addq 0x28(%rbx), %rax
leaq (%rax,%rsi,4), %rax
movl $0x3f800000, (%rax,%rdx,4) # imm = 0x3F800000
incq %r12
movslq %ecx, %rax
subq %r15, %rax
cmpq %rax, %r12
jl 0x1519e
jmp 0x152f1
movapd %xmm2, %xmm0
callq 0x9450
andpd 0x1cef1(%rip), %xmm0    # 0x32100
movsd 0x1d059(%rip), %xmm1    # 0x32270
subsd %xmm0, %xmm1
mulsd 0x1cfbd(%rip), %xmm1    # 0x321e0
movq 0x30(%rbx), %rax
movq %rax, %xmm0
punpckldq 0x1cf4c(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1cf54(%rip), %xmm0    # 0x32190
movapd %xmm0, %xmm2
unpckhpd %xmm0, %xmm2            # xmm2 = xmm2[1],xmm0[1]
addsd %xmm0, %xmm2
mulsd %xmm1, %xmm2
cvttsd2si %xmm2, %r15
cltq
subq %r15, %rax
cmpq %r15, %rax
movsd (%rsp), %xmm0
movsd 0x10(%rsp), %xmm1
jle 0x152f1
divsd %xmm0, %xmm1
movsd 0x1cffa(%rip), %xmm0    # 0x32270
movsd %xmm1, 0x10(%rsp)
subsd %xmm1, %xmm0
mulsd 0x30(%rsp), %xmm0
mulsd 0x1cf52(%rip), %xmm0    # 0x321e0
movsd %xmm0, (%rsp)
movq %r15, %r12
xorps %xmm0, %xmm0
cvtsi2sd %r12, %xmm0
mulsd 0x10(%rsp), %xmm0
addsd (%rsp), %xmm0
callq 0x9230
movq 0x30(%rbx), %rcx
movq %rcx, %rdx
imulq %r14, %rdx
imulq %rcx, %rdx
cmpl $0x0, 0x18(%rbx)
movq %r12, %rsi
cmoveq %rax, %rsi
cmoveq %r12, %rax
imulq %rcx, %rsi
shlq $0x2, %rax
addq 0x28(%rbx), %rax
leaq (%rax,%rsi,4), %rax
movl $0x3f800000, (%rax,%rdx,4) # imm = 0x3F800000
incq %r12
movslq %ecx, %rax
subq %r15, %rax
cmpq %rax, %r12
jl 0x15296
incq %r14
movq 0x10(%rbx), %rax
movslq %eax, %rcx
cmpq %rcx, %r14
jl 0x14fdd
movq %rbx, %rax
addq $0x40, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq