// File: /workspace/github_cpp_makefile_star2_O2/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, %r15
movq %rsi, %rbx
movq %rdi, %r12
callq 0x2070
movq %rax, %r14
leaq 0x5(%rax), %rdi
callq 0x2040
movq %rax, %r13
testq %r14, %r14
je 0x56eb
movq %r13, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x2100
movb $0x0, 0x4(%r13,%r14)
movl $0x7478742e, (%r13,%r14) # imm = 0x7478742E
movq %r13, %rdi
movq %r15, %rsi
callq 0x520e
movl %eax, %ebp
movq %r13, %rdi
callq 0x21c0
testl %ebp, %ebp
je 0x5719
pushq $-0x1
popq %r14
jmp 0x5774
leaq 0x7(%r14), %rdi
callq 0x2040
movq %rax, %r13
testq %r14, %r14
je 0x5738
movq %r13, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x2100
movl $0x687470, 0x3(%r13,%r14) # imm = 0x687470
movl $0x7065642e, (%r13,%r14) # imm = 0x7065642E
movl (%r15), %esi
movl 0x4(%r15), %edx
movq %rbx, %rdi
callq 0x4032
movq %rbx, %rdi
movq %r13, %rsi
callq 0x58fa
movl %eax, %r14d
movq %r13, %rdi
callq 0x21c0
testl %r14d, %r14d
je 0x5786
movl %r14d, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
addq $0xf8, %r15
xorl %r14d, %r14d
movq %r15, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x5bba
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
pushq $0x1
popq %r12
movq %r15, %rdi
movq %r12, %rsi
movq %r12, %rdx
callq 0x5bba
movsd (%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq %r15, %rdi
xorl %esi, %esi
movq %r12, %rdx
callq 0x5bba
movsd (%rax), %xmm0
movaps %xmm0, 0x20(%rsp)
pushq $0x2
popq %r13
movq %r15, %rdi
xorl %esi, %esi
movq %r13, %rdx
callq 0x5bba
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq %r15, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0x5bba
movapd 0x20(%rsp), %xmm10
movsd (%rax), %xmm0
movsd 0x27f4(%rip), %xmm1     # 0x8008
movapd %xmm1, %xmm2
movsd 0x18(%rsp), %xmm4
divsd %xmm4, %xmm2
movapd %xmm1, %xmm3
movsd 0x10(%rsp), %xmm6
divsd %xmm6, %xmm3
movapd 0x2da8(%rip), %xmm5     # 0x85e0
xorpd %xmm5, %xmm10
movsd 0x8(%rsp), %xmm7
divsd %xmm4, %xmm7
mulsd %xmm6, %xmm4
divsd %xmm4, %xmm10
movapd %xmm10, %xmm4
mulsd %xmm0, %xmm4
subsd %xmm7, %xmm4
xorpd %xmm5, %xmm0
divsd %xmm6, %xmm0
movl (%rbx), %eax
movl 0x4(%rbx), %ecx
testl %eax, %eax
cmovlel %r14d, %eax
testl %ecx, %ecx
cmovlel %r14d, %ecx
xorpd %xmm5, %xmm5
xorl %edx, %edx
cmpl %ecx, %edx
je 0x5774
movapd %xmm10, %xmm6
mulsd %xmm5, %xmm6
movapd %xmm3, %xmm7
mulsd %xmm5, %xmm7
addsd %xmm0, %xmm7
mulsd %xmm7, %xmm7
movl (%rbx), %esi
imull %edx, %esi
movslq %esi, %rsi
shlq $0x3, %rsi
addq 0x8(%rbx), %rsi
xorl %edi, %edi
cmpq %rdi, %rax
je 0x58f2
cvtsi2sd %edi, %xmm8
mulsd %xmm2, %xmm8
addsd %xmm6, %xmm8
addsd %xmm4, %xmm8
mulsd %xmm8, %xmm8
addsd %xmm7, %xmm8
addsd %xmm1, %xmm8
sqrtsd %xmm8, %xmm8
movsd (%rsi,%rdi,8), %xmm9
divsd %xmm8, %xmm9
movsd %xmm9, (%rsi,%rdi,8)
incq %rdi
jmp 0x58af
addsd %xmm1, %xmm5
incl %edx
jmp 0x587c