// File: /workspace/github_cpp_makefile_star2_O3/rishabh-battulwar[P]imageprocessing/./include/ImageProc.h
// Function: ImageProc::otsu_th(Image&, Image&)
void ImageProc::otsu_th(Image &img_orig, Image &img_binary)
{
  int levels = 256;
  int hist[levels];
  double prob[levels], omega[levels]; //prob of graylevels
  double myu[levels];   //mean value for separation
  double max_sigma, sigma[levels]; //inter-class variance
  int i, threshold;

  for (i = 0; i < levels; i++) hist[i] = 0;
  for (int i = 0; i < img_orig.rows; i++)
    for (int j = 0; j < img_orig.cols; j++)
    {
      hist[img_orig.getvalue(i,j,0)]++;
    }


  for ( i = 0; i < levels; i ++ ) 
  {
    prob[i] = (double)hist[i] / (img_orig.rows * img_orig.cols);
  }


  omega[0] = prob[0];
  myu[0] = 0.0;
  for (i = 1; i < levels; i++) {
    omega[i] = omega[i-1] + prob[i];
    myu[i] = myu[i-1] + i*prob[i];

  }


  //threshold = 0;
  max_sigma = 0.0;
  for (i = 0; i < levels-1; i++) {
    if (omega[i] != 0.0 && omega[i] != 1.0)
      sigma[i] = pow(myu[levels-1]*omega[i] - myu[i], 2) /
	(omega[i]*(1.0 - omega[i]));
    else
      sigma[i] = 0.0;
    if (sigma[i] > max_sigma) {
      max_sigma = sigma[i];
      threshold = i;
    }
  }

   printf("\nthreshold value = %d\n", threshold);


  for (int i = 0; i < img_binary.rows; i++)
    for (int j = 0; j < img_binary.cols; j++)
      if (img_orig.getvalue(i,j,0) > threshold)
		img_binary.setvalue(i,j,0,255);
      else
		img_binary.setvalue(i,j,0,0);

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x1c08, %rsp           # imm = 0x1C08
movq %rsi, %rbx
movq %rdi, %r14
movq %rsp, %rdi
xorl %r15d, %r15d
movl $0x400, %edx            # imm = 0x400
xorl %esi, %esi
callq 0x20c0
movslq 0xc(%r14), %rax
movl 0x8(%r14), %ecx
testq %rax, %rax
jle 0xe299
movq 0x18(%r14), %rdx
movl 0x10(%r14), %esi
movl %ecx, %edi
imull %esi, %edi
xorl %r8d, %r8d
movq %rcx, %r9
movl %r15d, %r10d
testl %ecx, %ecx
jle 0xe28e
movslq %r10d, %r10
movzbl (%rdx,%r10), %r11d
incl (%rsp,%r11,4)
addl %esi, %r10d
decq %r9
jne 0xe27a
incq %r8
addl %edi, %r15d
cmpq %rax, %r8
jne 0xe270
imull %ecx, %eax
cvtsi2sd %eax, %xmm0
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
xorl %eax, %eax
cvtdq2pd (%rsp,%rax,4), %xmm1
divpd %xmm0, %xmm1
movapd %xmm1, 0x1400(%rsp,%rax,8)
addq $0x2, %rax
cmpq $0x100, %rax            # imm = 0x100
jne 0xe2a6
movsd 0x1400(%rsp), %xmm0
movsd %xmm0, 0xc00(%rsp)
movq $0x0, 0x400(%rsp)
movl $0x1, %eax
xorpd %xmm1, %xmm1
movsd 0x1400(%rsp,%rax,8), %xmm2
addsd %xmm2, %xmm0
movsd %xmm0, 0xc00(%rsp,%rax,8)
xorps %xmm3, %xmm3
cvtsi2sd %eax, %xmm3
mulsd %xmm2, %xmm3
addsd %xmm3, %xmm1
movsd %xmm1, 0x400(%rsp,%rax,8)
incq %rax
cmpq $0x100, %rax            # imm = 0x100
jne 0xe2eb
xorpd %xmm0, %xmm0
movsd 0xbf8(%rsp), %xmm1
xorl %eax, %eax
movsd 0x2f4d(%rip), %xmm2     # 0x11288
xorpd %xmm3, %xmm3
movsd 0xc00(%rsp,%rax,8), %xmm5
ucomisd %xmm0, %xmm5
xorpd %xmm4, %xmm4
jne 0xe354
jnp 0xe381
ucomisd %xmm2, %xmm5
jne 0xe35c
jnp 0xe381
movapd %xmm1, %xmm4
mulsd %xmm5, %xmm4
subsd 0x400(%rsp,%rax,8), %xmm4
mulsd %xmm4, %xmm4
movapd %xmm2, %xmm6
subsd %xmm5, %xmm6
mulsd %xmm5, %xmm6
divsd %xmm6, %xmm4
ucomisd %xmm3, %xmm4
cmoval %eax, %ebp
maxsd %xmm3, %xmm4
incq %rax
movapd %xmm4, %xmm3
cmpq $0xff, %rax
jne 0xe33f
leaq 0x36b0(%rip), %rdi      # 0x11a52
xorl %r15d, %r15d
movl %ebp, %esi
xorl %eax, %eax
callq 0x2050
movl 0xc(%rbx), %ecx
testl %ecx, %ecx
jle 0xe406
movl 0x8(%rbx), %eax
testl %eax, %eax
jle 0xe3fe
xorl %ecx, %ecx
movl 0x8(%r14), %edx
imull %r15d, %edx
addl %ecx, %edx
imull 0x10(%r14), %edx
movq 0x18(%r14), %rsi
movslq %edx, %rdx
movzbl (%rsi,%rdx), %edx
cmpl %edx, %ebp
setl %dl
movq 0x18(%rbx), %rsi
imull %r15d, %eax
addl %ecx, %eax
imull 0x10(%rbx), %eax
cltq
negb %dl
movb %dl, (%rsi,%rax)
incl %ecx
movl 0x8(%rbx), %eax
cmpl %eax, %ecx
jl 0xe3be
movl 0xc(%rbx), %ecx
incl %r15d
cmpl %ecx, %r15d
jl 0xe3b8
addq $0x1c08, %rsp           # imm = 0x1C08
popq %rbx
popq %r14
popq %r15
popq %rbp
retq