// File: /workspace/github_cpp_makefile_star2_O3/devernay[P]vlpovutils/povread.cpp
// Function: vlpov_povread(char const*, VLPovImage<double>&, VLPovCamera&)
int vlpov_povread(const char* file, VLPovImage<double> &z, VLPovCamera &cam)
{
    int retval;
     
    size_t file_len = strlen(file);
    
    // % --------------------------------------------------------------------
    // %                                                               Camera
    // % --------------------------------------------------------------------
    
    char *info_file = new char[file_len+5];
    const char *info_suffix = ".txt";
    std::copy(file, file+file_len, info_file);
    std::copy(info_suffix, info_suffix+5, info_file+file_len);
    retval = vlpov_get_cam(info_file, cam);
    delete [] info_file;
    if(retval != 0) {
        return retval;
    }
    
    // % --------------------------------------------------------------------
    // %                                                             Z-buffer
    // % --------------------------------------------------------------------
        
    char *depth_file = new char[file_len+7];
    const char *depth_suffix = ".depth";
    std::copy(file, file+file_len, depth_file);
    std::copy(depth_suffix, depth_suffix+7, depth_file+file_len);
    z.resize(cam.width, cam.height);
    retval = z.load(depth_file);
    delete [] depth_file;
    if(retval != 0) {
        return retval;
    }
    
    // % The z stored by POV is the euclidean distance from the camera
    // % center. Recover the right one.

    double fx = cam.K(0,0);
    double fy = cam.K(1,1);
    double s = cam.K(0,1);
    double cx = cam.K(0,2);
    double cy = cam.K(1,2);
    
    // compute inverse intrinsic matrix;
    double ifx = 1./fx;
    double ify = 1./fy;
    double is = -s/(fx*fy);
    double icx = is*cy -cx/fx;
    double icy = -cy/fy;

    for(int y = 0; y < z.height(); ++y) {
        for(int x = 0; x < z.width(); ++x) {
            // apply inverse intrisics
            double xi = ifx*x + is*y + icx;
            double yi = ify*y + icy;
            // Z is a distance from optical center, transform it to Z in camera frame
            z(x,y) /= sqrt(pow(xi,2)+pow(yi,2)+1.);
        }
    }

    return retval;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdx, %r14
movq %rsi, %rbx
movq %rdi, %r13
callq 0x2080
movq %rax, %r12
leaq 0x5(%rax), %rdi
callq 0x2040
movq %rax, %r15
testq %r12, %r12
je 0x6cff
movq %r15, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0x2100
movb $0x0, 0x4(%r15,%r12)
movl $0x7478742e, (%r15,%r12) # imm = 0x7478742E
movq %r15, %rdi
movq %r14, %rsi
callq 0x6776
movl %eax, %ebp
movq %r15, %rdi
callq 0x21e0
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
testl %ebp, %ebp
jne 0x6f6c
leaq 0x7(%r12), %rdi
callq 0x2040
movq %rax, %rbp
testq %r12, %r12
je 0x6d50
movq %rbp, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0x2100
movl $0x687470, 0x3(%rbp,%r12) # imm = 0x687470
movl $0x7065642e, (%rbp,%r12) # imm = 0x7065642E
movl (%r14), %esi
movl 0x4(%r14), %edx
movq %rbx, %rdi
callq 0x526e
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x6f7e
movl %eax, %r15d
movq %rbp, %rdi
callq 0x21e0
testl %r15d, %r15d
jne 0x6f6c
leaq 0x108(%r14), %r12
movq 0xf8(%r14), %rsi
movq 0x100(%r14), %rcx
xorl %r15d, %r15d
xorl %edi, %edi
xorl %edx, %edx
callq 0x5792
movq %r12, %rdi
movq %rax, %rsi
callq 0x75be
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0xf8(%r14), %rsi
movq 0x100(%r14), %rcx
movl $0x1, %edi
movl $0x1, %edx
callq 0x5792
movq %r12, %rdi
movq %rax, %rsi
callq 0x75be
movsd (%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0xf8(%r14), %rsi
movq 0x100(%r14), %rcx
movl $0x1, %edx
xorl %edi, %edi
callq 0x5792
movq %r12, %rdi
movq %rax, %rsi
callq 0x75be
movq 0xf8(%r14), %rsi
movq 0x100(%r14), %rcx
movsd (%rax), %xmm0
movaps %xmm0, 0x20(%rsp)
movl $0x2, %edx
xorl %edi, %edi
callq 0x5792
movq %r12, %rdi
movq %rax, %rsi
callq 0x75be
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0xf8(%r14), %rsi
movq 0x100(%r14), %rcx
movl $0x1, %edi
movl $0x2, %edx
callq 0x5792
movq %r12, %rdi
movq %rax, %rsi
callq 0x75be
movslq 0x4(%rbx), %rcx
testq %rcx, %rcx
jle 0x6f6c
movsd (%rax), %xmm0
movsd 0x4172(%rip), %xmm1     # 0xb008
movapd %xmm1, %xmm2
movsd 0x18(%rsp), %xmm4
divsd %xmm4, %xmm2
movapd %xmm1, %xmm3
movsd 0x10(%rsp), %xmm6
divsd %xmm6, %xmm3
movapd 0x4616(%rip), %xmm5     # 0xb4d0
movapd 0x20(%rsp), %xmm9
xorpd %xmm5, %xmm9
movsd 0x8(%rsp), %xmm7
divsd %xmm4, %xmm7
mulsd %xmm6, %xmm4
divsd %xmm4, %xmm9
movapd %xmm9, %xmm4
mulsd %xmm0, %xmm4
subsd %xmm7, %xmm4
xorpd %xmm5, %xmm0
divsd %xmm6, %xmm0
movl (%rbx), %eax
movq 0x8(%rbx), %rdx
leaq (,%rax,8), %rsi
xorl %edi, %edi
testl %eax, %eax
jle 0x6f5e
xorps %xmm5, %xmm5
cvtsi2sd %edi, %xmm5
movapd %xmm9, %xmm6
mulsd %xmm5, %xmm6
mulsd %xmm3, %xmm5
addsd %xmm0, %xmm5
mulsd %xmm5, %xmm5
xorl %r8d, %r8d
xorps %xmm7, %xmm7
cvtsi2sd %r8d, %xmm7
mulsd %xmm2, %xmm7
addsd %xmm6, %xmm7
addsd %xmm4, %xmm7
mulsd %xmm7, %xmm7
addsd %xmm5, %xmm7
addsd %xmm1, %xmm7
sqrtsd %xmm7, %xmm7
movsd (%rdx,%r8,8), %xmm8
divsd %xmm7, %xmm8
movsd %xmm8, (%rdx,%r8,8)
incq %r8
cmpq %r8, %rax
jne 0x6f21
incq %rdi
addq %rsi, %rdx
cmpq %rcx, %rdi
jne 0x6efe
xorl %r15d, %r15d
movl %r15d, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq