// File: zhangk145[P]video_envalue/Envaluer.cpp
// Function: Envaluer::compute_ssim(unsigned char*, int, unsigned char*, int, int, int)
float Envaluer::compute_ssim(uint8_t *pix1, int stride1,
                   uint8_t *pix2, int stride2,
                   int width, int height)
{
    int x, y, z;
    float ssim = 0.0;
    // printf("[%s:%d]==\n", __FUNCTION__, __LINE__);
    int (*sum0)[4] = (int (*)[4])x264_alloca(4 * (width/4+3) * sizeof(int));
    int (*sum1)[4] = (int (*)[4])x264_alloca(4 * (width/4+3) * sizeof(int));
    // void *sumTmp0 = (void *)sum0;
    // void *sumTmp1 = (void *)sum1;
    width >>= 2;
    height >>= 2;
    z = 0;
    // printf("[%s:%d]width:%d height:%d\n", __FUNCTION__, __LINE__, width, height);
    for( y = 1; y < height; y++ )
    {
        for( ; z <= y; z++ )
        {
            int (*t)[4] = sum0;
            sum0 = sum1;
            sum1 = t;
            // XCHG( , sum0, sum1 );
            for( x = 0; x < width; x+=2 )
                ssim_4x4x2_core( &pix1[4*(x+z*stride1)], stride1, &pix2[4*(x+z*stride2)], stride2, &sum0[x] );
        }
        for( x = 0; x < width-1; x += 4 ) {
            ssim += ssim_end4( sum0+x, sum1+x, X264_MIN(4,width-x-1) );
            // printf("[%s:%d]==ssim:%.3f\n", __FUNCTION__, __LINE__, ssim);
        }
    }
    // printf("[%s:%d]==\n", __FUNCTION__, __LINE__);
    return ssim / ((width-1) * (height-1));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movl 0x10(%rbp), %eax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq %rcx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movl %r9d, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x58(%rbp)
movl $0x0, -0x38(%rbp)
movl -0x28(%rbp), %eax
movl %eax, %ecx
addl $0x3, %ecx
testl %eax, %eax
cmovsl %ecx, %eax
andl $-0x4, %eax
addl $0xc, %eax
cltq
leaq 0x1e(,%rax,4), %rcx
andq $-0x10, %rcx
movq %rsp, %rax
movq %rax, %rdx
subq %rcx, %rdx
movq %rdx, %rsp
negq %rcx
leaq 0xf(%rax,%rcx), %rax
andq $-0x10, %rax
movq %rax, -0x40(%rbp)
movl -0x28(%rbp), %eax
movl %eax, %ecx
addl $0x3, %ecx
testl %eax, %eax
cmovsl %ecx, %eax
andl $-0x4, %eax
addl $0xc, %eax
cltq
leaq 0x1e(,%rax,4), %rcx
andq $-0x10, %rcx
movq %rsp, %rax
subq %rcx, %rax
movq %rax, %rsp
addq $0xf, %rax
andq $-0x10, %rax
movq %rax, -0x48(%rbp)
movl -0x28(%rbp), %eax
sarl $0x2, %eax
movl %eax, -0x28(%rbp)
movl 0x10(%rbp), %eax
sarl $0x2, %eax
movl %eax, 0x10(%rbp)
movl $0x0, -0x34(%rbp)
movl $0x1, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl 0x10(%rbp), %eax
jge 0x3550
jmp 0x3412
movl -0x34(%rbp), %eax
cmpl -0x30(%rbp), %eax
jg 0x34b2
movq -0x40(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x48(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x28(%rbp), %eax
jge 0x34a2
movq -0x58(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x2c(%rbp), %eax
movl -0x34(%rbp), %ecx
imull -0x14(%rbp), %ecx
addl %ecx, %eax
shll $0x2, %eax
cltq
addq %rax, %rsi
movl -0x14(%rbp), %edx
movq -0x20(%rbp), %rcx
movl -0x2c(%rbp), %eax
movl -0x34(%rbp), %r8d
imull -0x24(%rbp), %r8d
addl %r8d, %eax
shll $0x2, %eax
cltq
addq %rax, %rcx
movl -0x24(%rbp), %r8d
movq -0x40(%rbp), %r9
movslq -0x2c(%rbp), %rax
shlq $0x4, %rax
addq %rax, %r9
callq 0x2f70
movl -0x2c(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x2c(%rbp)
jmp 0x343d
jmp 0x34a4
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x3412
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movl -0x28(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x3540
movq -0x40(%rbp), %rax
movslq -0x2c(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, -0x68(%rbp)
movq -0x48(%rbp), %rax
movslq -0x2c(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, -0x60(%rbp)
movl -0x28(%rbp), %ecx
subl -0x2c(%rbp), %ecx
subl $0x1, %ecx
movl $0x4, %eax
cmpl %ecx, %eax
jge 0x3508
movl $0x4, %eax
movl %eax, -0x6c(%rbp)
jmp 0x3514
movl -0x28(%rbp), %eax
subl -0x2c(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x6c(%rbp)
movq -0x60(%rbp), %rdx
movq -0x68(%rbp), %rsi
movq -0x58(%rbp), %rdi
movl -0x6c(%rbp), %ecx
callq 0x3180
addss -0x38(%rbp), %xmm0
movss %xmm0, -0x38(%rbp)
movl -0x2c(%rbp), %eax
addl $0x4, %eax
movl %eax, -0x2c(%rbp)
jmp 0x34b9
jmp 0x3542
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x3404
movss -0x38(%rbp), %xmm0
movl -0x28(%rbp), %eax
subl $0x1, %eax
movl 0x10(%rbp), %ecx
subl $0x1, %ecx
imull %ecx, %eax
cvtsi2ss %eax, %xmm1
divss %xmm1, %xmm0
movq %rbp, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)