// File: /workspace/github_c_makefile_star2_O2/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 $0x30, %rsp
movl %edx, %ebp
movq %rsi, %r14
movl %edi, %r15d
pushq $0x1
popq %rdi
pushq $0x68
popq %rsi
callq 0x9960
movq %rax, %rbx
movl %r15d, (%rax)
movq %r14, 0x10(%rax)
movq $0x15, 0x30(%rax)
movl %ebp, 0x18(%rax)
andl $0x0, 0x1c(%rax)
shlq $0x2, %r14
movq %r14, %rdi
callq 0x95e0
movq %rax, 0x38(%rbx)
movq 0x10(%rbx), %rdi
shlq $0x2, %rdi
callq 0x95e0
movq %rax, 0x40(%rbx)
xorl %r14d, %r14d
movq 0x10(%rbx), %rdi
movslq %edi, %rax
cmpq %rax, %r14
jge 0x138f7
cvtsi2sd %r14, %xmm0
mulsd 0x1a0d3(%rip), %xmm0    # 0x2d948
movq %rdi, %xmm2
punpckldq 0x198de(%rip), %xmm2 # xmm2 = xmm2[0],mem[0],xmm2[1],mem[1]
subpd 0x198e6(%rip), %xmm2    # 0x2d170
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 0x138c4
callq 0x98d0
cvtsd2ss %xmm0, %xmm0
movq 0x38(%rbx), %rax
movss %xmm0, (%rax,%r14,4)
movsd (%rsp), %xmm0
callq 0x9470
jmp 0x138e1
callq 0x9470
cvtsd2ss %xmm0, %xmm0
movq 0x38(%rbx), %rax
movss %xmm0, (%rax,%r14,4)
movsd (%rsp), %xmm0
callq 0x98d0
cvtsd2ss %xmm0, %xmm0
movq 0x40(%rbx), %rax
movss %xmm0, (%rax,%r14,4)
incq %r14
jmp 0x13858
movl (%rbx), %eax
testl %eax, %eax
je 0x1390c
cmpl $0x1, %eax
jne 0x13916
leaq (%rdi,%rdi,2), %rdi
addq $0x4, %rdi
jmp 0x13910
shlq $0x2, %rdi
movq %rdi, 0x8(%rbx)
jmp 0x1391a
movq 0x8(%rbx), %rdi
shlq $0x3, %rdi
callq 0x95e0
movq %rax, %rcx
movq %rax, 0x20(%rbx)
movl (%rbx), %eax
cmpl $0x1, %eax
je 0x1398f
testl %eax, %eax
jne 0x13a0f
xorl %esi, %esi
xorl %edi, %edi
cmpq $0x4, %rdi
je 0x13a0f
movq %rdi, %r8
xorq $0x1, %r8
xorl %r9d, %r9d
xorl %r10d, %r10d
movq 0x10(%rbx), %r11
movslq %r11d, %rax
cmpq %rax, %r10
jge 0x13986
leaq (%r9,%r11), %rax
xorl %edx, %edx
divq %r11
movq %rsi, %rax
imulq %r11, %rax
imulq %r8, %r11
addq %rdx, %r11
addq %rcx, %rax
movq %r11, (%rax,%r10,8)
incq %r10
decq %r9
jmp 0x13954
incq %rdi
addq $0x8, %rsi
jmp 0x1393d
xorl %edi, %edi
movq %rcx, %r8
xorl %r9d, %r9d
movq 0x10(%rbx), %rax
movslq %eax, %rdx
cmpq %rdx, %r9
jge 0x139e5
leaq (%rdi,%rax), %rsi
movq %rsi, (%r8)
movq 0x10(%rbx), %r10
addq %r10, %rax
addq %rdi, %rax
leaq (%r10,%r10), %r11
xorl %edx, %edx
divq %r11
movq %rdx, (%r8,%r10,8)
movq 0x10(%rbx), %r10
movq %rsi, %rax
xorl %edx, %edx
divq %r10
leaq (%rdx,%r10,2), %rax
shlq $0x4, %r10
movq %rax, (%r8,%r10)
incq %r9
decq %rdi
addq $0x8, %r8
jmp 0x13997
xorl %eax, %eax
cmpq $0x4, %rax
je 0x13a0f
movq %rax, %rdx
xorq $0x1, %rdx
movq 0x10(%rbx), %rsi
leaq (%rsi,%rsi,2), %rdi
addq %rdx, %rdi
imulq $0x18, %rsi, %rdx
addq %rcx, %rdx
movq %rdi, (%rdx,%rax,8)
incq %rax
jmp 0x139e7
movq 0x30(%rbx), %rdi
imulq %rdi, %rdi
imulq 0x10(%rbx), %rdi
pushq $0x4
popq %rsi
callq 0x9960
movq %rax, 0x28(%rbx)
xorl %r14d, %r14d
movq 0x10(%rbx), %rax
movslq %eax, %rcx
cmpq %rcx, %r14
jge 0x13d21
cvtsi2sd %r14, %xmm0
movsd 0x19f00(%rip), %xmm1    # 0x2d948
mulsd %xmm1, %xmm0
movq %rax, %xmm3
movq 0x19707(%rip), %xmm2    # 0x2d160
punpckldq %xmm2, %xmm3    # xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
movapd 0x1970b(%rip), %xmm2    # 0x2d170
subpd %xmm2, %xmm3
movapd %xmm3, %xmm2
unpckhpd %xmm3, %xmm2            # xmm2 = xmm2[1],xmm3[1]
addsd %xmm3, %xmm2
divsd %xmm2, %xmm0
addsd 0x19ecf(%rip), %xmm0    # 0x2d950
callq 0x9460
movsd %xmm0, 0x28(%rsp)
movsd 0x30(%rbx), %xmm1
unpcklps 0x196c8(%rip), %xmm1    # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x196d0(%rip), %xmm1    # 0x2d170
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
movapd %xmm2, (%rsp)
callq 0x9470
movapd %xmm0, %xmm1
mulsd (%rsp), %xmm1
movsd 0x196f9(%rip), %xmm0    # 0x2d1c0
mulsd %xmm0, %xmm1
movsd %xmm1, (%rsp)
movsd 0x30(%rbx), %xmm0
unpcklps 0x19684(%rip), %xmm0    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1968c(%rip), %xmm0    # 0x2d170
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd %xmm1, 0x10(%rsp)
movsd 0x28(%rsp), %xmm0
callq 0x98d0
movsd 0x28(%rsp), %xmm4
mulsd 0x10(%rsp), %xmm0
mulsd 0x196ab(%rip), %xmm0    # 0x2d1c0
movapd %xmm0, %xmm3
movq 0x30(%rbx), %rax
decq %rax
movsd 0x19e30(%rip), %xmm0    # 0x2d958
ucomisd %xmm4, %xmm0
movq %rax, %xmm1
punpckldq 0x19627(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x1962f(%rip), %xmm1    # 0x2d170
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
jae 0x13c3d
ucomisd 0x19e05(%rip), %xmm4    # 0x2d960
jae 0x13c3d
movsd (%rsp), %xmm2
divsd %xmm3, %xmm2
movsd 0x196c6(%rip), %xmm1    # 0x2d238
movsd %xmm2, (%rsp)
subsd %xmm2, %xmm1
mulsd %xmm0, %xmm1
movsd 0x19639(%rip), %xmm0    # 0x2d1c0
mulsd %xmm0, %xmm1
movsd %xmm1, 0x10(%rsp)
movapd %xmm4, %xmm0
callq 0x98d0
movsd 0x19696(%rip), %xmm1    # 0x2d238
subsd %xmm0, %xmm1
mulsd 0x19612(%rip), %xmm1    # 0x2d1c0
movq 0x30(%rbx), %rcx
movq %rcx, %xmm0
punpckldq 0x195a1(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x195a9(%rip), %xmm0    # 0x2d170
movapd %xmm0, %xmm2
unpckhpd %xmm0, %xmm2            # xmm2 = xmm2[1],xmm0[1]
addsd %xmm0, %xmm2
mulsd %xmm1, %xmm2
cvttsd2si %xmm2, %r15
movq %r15, %r12
movslq %ecx, %rax
subq %r15, %rax
cmpq %rax, %r12
jge 0x13d19
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
shlq $0x2, %rax
addq 0x28(%rbx), %rax
imulq %rcx, %rsi
leaq (%rax,%rsi,4), %rax
movl $0x3f800000, (%rax,%rdx,4) # imm = 0x3F800000
incq %r12
jmp 0x13bdf
divsd (%rsp), %xmm3
movsd 0x195ee(%rip), %xmm1    # 0x2d238
movsd %xmm3, (%rsp)
subsd %xmm3, %xmm1
mulsd %xmm0, %xmm1
movsd 0x19561(%rip), %xmm0    # 0x2d1c0
mulsd %xmm0, %xmm1
movsd %xmm1, 0x10(%rsp)
movapd %xmm4, %xmm0
callq 0x9470
andpd 0x19466(%rip), %xmm0    # 0x2d0e0
movsd 0x195b6(%rip), %xmm1    # 0x2d238
subsd %xmm0, %xmm1
mulsd 0x19532(%rip), %xmm1    # 0x2d1c0
movq 0x30(%rbx), %rcx
movq %rcx, %xmm0
punpckldq 0x194c1(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x194c9(%rip), %xmm0    # 0x2d170
movapd %xmm0, %xmm2
unpckhpd %xmm0, %xmm2            # xmm2 = xmm2[1],xmm0[1]
addsd %xmm0, %xmm2
mulsd %xmm1, %xmm2
cvttsd2si %xmm2, %r15
movq %r15, %r12
movslq %ecx, %rax
subq %r15, %rax
cmpq %rax, %r12
jge 0x13d19
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 %r12, %rsi
cmoveq %rax, %rsi
cmoveq %r12, %rax
shlq $0x2, %rax
addq 0x28(%rbx), %rax
imulq %rcx, %rsi
leaq (%rax,%rsi,4), %rax
movl $0x3f800000, (%rax,%rdx,4) # imm = 0x3F800000
incq %r12
jmp 0x13cbf
incq %r14
jmp 0x13a2b
movq %rbx, %rax
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq