// File: /workspace/github_c_makefile_star2_O1/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), %rax
testl %eax, %eax
jle 0x14ee4
xorl %r14d, %r14d
xorps %xmm0, %xmm0
cvtsi2sd %r14, %xmm0
mulsd 0x1eb31(%rip), %xmm0    # 0x33988
movq %rax, %xmm2
punpckldq 0x1e31c(%rip), %xmm2 # xmm2 = xmm2[0],mem[0],xmm2[1],mem[1]
subpd 0x1e324(%rip), %xmm2    # 0x33190
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 0x14ea6
callq 0x9860
cvtsd2ss %xmm0, %xmm0
movq 0x38(%rbx), %rax
movss %xmm0, (%rax,%r14,4)
movsd (%rsp), %xmm0
callq 0x9450
jmp 0x14ec3
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), %rax
movslq %eax, %rcx
cmpq %rcx, %r14
jl 0x14e47
movl (%rbx), %ecx
testl %ecx, %ecx
je 0x14ef9
cmpl $0x1, %ecx
jne 0x14f01
leaq (%rax,%rax,2), %rax
addq $0x4, %rax
jmp 0x14efd
shlq $0x2, %rax
movq %rax, 0x8(%rbx)
movq 0x8(%rbx), %rdi
shlq $0x3, %rdi
callq 0x95b0
movq %rax, %rcx
movq %rax, 0x20(%rbx)
movl (%rbx), %eax
cmpl $0x1, %eax
je 0x14f7d
testl %eax, %eax
jne 0x14ff9
xorl %esi, %esi
xorl %edi, %edi
movq 0x10(%rbx), %r8
testl %r8d, %r8d
jle 0x14f6e
movq %rdi, %r9
xorq $0x1, %r9
xorl %r10d, %r10d
xorl %r11d, %r11d
leaq (%r8,%r10), %rax
xorl %edx, %edx
divq %r8
movq %rsi, %rax
imulq %r8, %rax
imulq %r9, %r8
addq %rdx, %r8
addq %rcx, %rax
movq %r8, (%rax,%r11,8)
incq %r11
movq 0x10(%rbx), %r8
movslq %r8d, %rax
decq %r10
cmpq %rax, %r11
jl 0x14f3e
incq %rdi
addq $0x8, %rsi
cmpq $0x4, %rdi
jne 0x14f28
jmp 0x14ff9
movq 0x10(%rbx), %rsi
testl %esi, %esi
jle 0x14fd4
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 0x14f8a
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 0x14fd6
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 0x1534c
xorl %r14d, %r14d
xorps %xmm0, %xmm0
cvtsi2sd %r14, %xmm0
movsd 0x1e955(%rip), %xmm1    # 0x33988
mulsd %xmm1, %xmm0
movq %rax, %xmm3
movq 0x1e13c(%rip), %xmm2    # 0x33180
punpckldq %xmm2, %xmm3    # xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
movapd 0x1e140(%rip), %xmm2    # 0x33190
subpd %xmm2, %xmm3
movapd %xmm3, %xmm2
unpckhpd %xmm3, %xmm2            # xmm2 = xmm2[1],xmm3[1]
addsd %xmm3, %xmm2
divsd %xmm2, %xmm0
addsd 0x1e924(%rip), %xmm0    # 0x33990
callq 0x9440
movsd %xmm0, 0x28(%rsp)
movsd 0x30(%rbx), %xmm1
unpcklps 0x1e0fd(%rip), %xmm1    # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x1e105(%rip), %xmm1    # 0x33190
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 0x1e11e(%rip), %xmm0    # 0x331d0
mulsd %xmm0, %xmm1
movsd %xmm1, (%rsp)
movsd 0x30(%rbx), %xmm0
unpcklps 0x1e0b9(%rip), %xmm0    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1e0c1(%rip), %xmm0    # 0x33190
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 0x1e0d0(%rip), %xmm0    # 0x331d0
movsd %xmm0, 0x10(%rsp)
movq 0x30(%rbx), %rax
decq %rax
movsd 0x1e883(%rip), %xmm0    # 0x33998
ucomisd %xmm2, %xmm0
movq %rax, %xmm0
punpckldq 0x1e05a(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1e062(%rip), %xmm0    # 0x33190
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd %xmm1, 0x30(%rsp)
jae 0x15245
ucomisd 0x1e852(%rip), %xmm2    # 0x339a0
jae 0x15245
movapd %xmm2, %xmm0
callq 0x9860
movsd 0x1e0fb(%rip), %xmm1    # 0x33260
subsd %xmm0, %xmm1
mulsd 0x1e05f(%rip), %xmm1    # 0x331d0
movq 0x30(%rbx), %rax
movq %rax, %xmm0
punpckldq 0x1dffe(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1e006(%rip), %xmm0    # 0x33190
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 0x15339
divsd %xmm0, %xmm1
movsd 0x1e09c(%rip), %xmm0    # 0x33260
movsd %xmm1, (%rsp)
subsd %xmm1, %xmm0
mulsd 0x30(%rsp), %xmm0
mulsd 0x1dff5(%rip), %xmm0    # 0x331d0
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 0x30(%rbx), %rax
subq %r15, %rax
cmpq %rax, %r12
jl 0x151e4
jmp 0x15339
movapd %xmm2, %xmm0
callq 0x9450
andpd 0x1deaa(%rip), %xmm0    # 0x33100
movsd 0x1e002(%rip), %xmm1    # 0x33260
subsd %xmm0, %xmm1
mulsd 0x1df66(%rip), %xmm1    # 0x331d0
movq 0x30(%rbx), %rax
movq %rax, %xmm0
punpckldq 0x1df05(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1df0d(%rip), %xmm0    # 0x33190
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 0x15339
divsd %xmm0, %xmm1
movsd 0x1dfa3(%rip), %xmm0    # 0x33260
movsd %xmm1, 0x10(%rsp)
subsd %xmm1, %xmm0
mulsd 0x30(%rsp), %xmm0
mulsd 0x1defb(%rip), %xmm0    # 0x331d0
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 0x30(%rbx), %rax
subq %r15, %rax
cmpq %rax, %r12
jl 0x152dd
incq %r14
movq 0x10(%rbx), %rax
movslq %eax, %rcx
cmpq %rcx, %r14
jl 0x15023
movq %rbx, %rax
addq $0x40, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq