// File: /workspace/github_cpp_makefile_star2_O1/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 $0x68, %rsp
movq %rdx, %r14
movq %rsi, %rbx
movq %rdi, %r12
callq 0x2080
movq %rax, %r15
leaq 0x5(%rax), %rdi
callq 0x2040
movq %rax, %r13
testq %r15, %r15
je 0x6dd1
movq %r13, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x2110
movb $0x0, 0x4(%r13,%r15)
movl $0x7478742e, (%r13,%r15) # imm = 0x7478742E
movq %r13, %rdi
movq %r14, %rsi
callq 0x6816
movl %eax, %ebp
movq %r13, %rdi
callq 0x21f0
testl %ebp, %ebp
jne 0x70aa
leaq 0x7(%r15), %rdi
callq 0x2040
movq %rax, %r13
testq %r15, %r15
je 0x6e1c
movq %r13, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x2110
movl $0x687470, 0x3(%r13,%r15) # imm = 0x687470
movl $0x7065642e, (%r13,%r15) # imm = 0x7065642E
movl (%r14), %esi
movl 0x4(%r14), %edx
movq %rbx, %rdi
callq 0x530c
movq %rbx, %rdi
movq %r13, %rsi
callq 0x70bc
movl %eax, %ebp
movq %r13, %rdi
callq 0x21f0
testl %ebp, %ebp
jne 0x70aa
leaq 0x108(%r14), %r15
movq 0xf8(%r14), %rsi
movq 0x100(%r14), %rcx
xorl %r12d, %r12d
xorl %edi, %edi
xorl %edx, %edx
callq 0x5830
movq %r15, %rdi
movq %rax, %rsi
callq 0x76fc
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0xf8(%r14), %rsi
movq 0x100(%r14), %rcx
movl $0x1, %edi
movl $0x1, %edx
callq 0x5830
movq %r15, %rdi
movq %rax, %rsi
callq 0x76fc
movsd (%rax), %xmm0
movsd %xmm0, 0x30(%rsp)
movq 0xf8(%r14), %rsi
movq 0x100(%r14), %rcx
movl $0x1, %edx
xorl %edi, %edi
callq 0x5830
movq %r15, %rdi
movq %rax, %rsi
callq 0x76fc
movq 0xf8(%r14), %rsi
movq 0x100(%r14), %rcx
movsd (%rax), %xmm0
movaps %xmm0, 0x20(%rsp)
movl $0x2, %edx
xorl %edi, %edi
callq 0x5830
movq %r15, %rdi
movq %rax, %rsi
callq 0x76fc
movsd (%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0xf8(%r14), %rsi
movq 0x100(%r14), %rcx
movl $0x1, %edi
movl $0x2, %edx
callq 0x5830
movq %r15, %rdi
movq %rax, %rsi
callq 0x76fc
cmpl $0x0, 0x4(%rbx)
jle 0x70aa
movsd (%rax), %xmm1
movsd 0x40ab(%rip), %xmm3     # 0xb008
movapd %xmm3, %xmm4
movsd 0x8(%rsp), %xmm2
divsd %xmm2, %xmm4
movapd %xmm3, %xmm0
movsd 0x30(%rsp), %xmm6
divsd %xmm6, %xmm0
movsd %xmm0, 0x40(%rsp)
movapd 0x4549(%rip), %xmm0     # 0xb4d0
movapd 0x20(%rsp), %xmm7
xorpd %xmm0, %xmm7
movsd 0x10(%rsp), %xmm8
divsd %xmm2, %xmm8
mulsd %xmm6, %xmm2
divsd %xmm2, %xmm7
movapd %xmm7, %xmm5
mulsd %xmm1, %xmm5
subsd %xmm8, %xmm5
xorpd %xmm0, %xmm1
divsd %xmm6, %xmm1
movapd %xmm1, 0x50(%rsp)
xorpd %xmm6, %xmm6
movapd %xmm7, %xmm2
movapd %xmm7, 0x20(%rsp)
movsd %xmm4, 0x48(%rsp)
movapd %xmm5, 0x10(%rsp)
cmpl $0x0, (%rbx)
jle 0x709d
xorps %xmm7, %xmm7
cvtsi2sd %r12d, %xmm7
movapd %xmm2, %xmm8
mulsd %xmm7, %xmm8
mulsd 0x40(%rsp), %xmm7
addsd 0x50(%rsp), %xmm7
mulsd %xmm7, %xmm7
movslq %r12d, %r14
xorl %r15d, %r15d
movsd %xmm7, 0x8(%rsp)
movapd %xmm8, 0x30(%rsp)
xorps %xmm0, %xmm0
cvtsi2sd %r15d, %xmm0
mulsd %xmm4, %xmm0
addsd %xmm8, %xmm0
addsd %xmm5, %xmm0
mulsd %xmm0, %xmm0
addsd %xmm7, %xmm0
addsd %xmm3, %xmm0
ucomisd %xmm6, %xmm0
jb 0x7045
sqrtsd %xmm0, %xmm0
jmp 0x7075
callq 0x2100
movapd 0x30(%rsp), %xmm8
movsd 0x8(%rsp), %xmm7
xorpd %xmm6, %xmm6
movapd 0x10(%rsp), %xmm5
movsd 0x48(%rsp), %xmm4
movsd 0x3f99(%rip), %xmm3     # 0xb008
movapd 0x20(%rsp), %xmm2
movq 0x8(%rbx), %rax
movslq (%rbx), %rcx
imulq %r14, %rcx
addq %r15, %rcx
movsd (%rax,%rcx,8), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, (%rax,%rcx,8)
incq %r15
cmpl (%rbx), %r15d
jl 0x7018
incl %r12d
cmpl 0x4(%rbx), %r12d
jl 0x6fda
movl %ebp, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop