// File: 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
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x30d0
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
addq $0x5, %rdi
callq 0x3040
movq %rax, -0x38(%rbp)
leaq 0x7d94(%rip), %rax      # 0x128f0
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
callq 0xaf50
movq -0x40(%rbp), %rdi
movq -0x40(%rbp), %rsi
addq $0x5, %rsi
movq -0x38(%rbp), %rdx
addq -0x30(%rbp), %rdx
callq 0xaf50
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0xa330
movl %eax, -0x24(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0xc0(%rbp)
cmpq $0x0, %rax
je 0xabbb
movq -0xc0(%rbp), %rdi
callq 0x32e0
cmpl $0x0, -0x24(%rbp)
je 0xabcc
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xaf3e
movq -0x30(%rbp), %rdi
addq $0x7, %rdi
callq 0x3040
movq %rax, -0x48(%rbp)
leaq 0x7d11(%rip), %rax      # 0x128f5
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq -0x30(%rbp), %rsi
movq -0x48(%rbp), %rdx
callq 0xaf50
movq -0x50(%rbp), %rdi
movq -0x50(%rbp), %rsi
addq $0x7, %rsi
movq -0x48(%rbp), %rdx
addq -0x30(%rbp), %rdx
callq 0xaf50
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rax
movl (%rax), %esi
movq -0x20(%rbp), %rax
movl 0x4(%rax), %edx
callq 0x7760
movq -0x18(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0xaf90
movl %eax, -0x24(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0xc8(%rbp)
cmpq $0x0, %rax
je 0xac59
movq -0xc8(%rbp), %rdi
callq 0x32e0
cmpl $0x0, -0x24(%rbp)
je 0xac6a
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xaf3e
movq -0x20(%rbp), %rdi
addq $0xf8, %rdi
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0xb0b0
movsd (%rax), %xmm0
movsd %xmm0, -0x58(%rbp)
movq -0x20(%rbp), %rdi
addq $0xf8, %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0xb0b0
movsd (%rax), %xmm0
movsd %xmm0, -0x60(%rbp)
movq -0x20(%rbp), %rdi
addq $0xf8, %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x1, %edx
callq 0xb0b0
movsd (%rax), %xmm0
movsd %xmm0, -0x68(%rbp)
movq -0x20(%rbp), %rdi
addq $0xf8, %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
callq 0xb0b0
movsd (%rax), %xmm0
movsd %xmm0, -0x70(%rbp)
movq -0x20(%rbp), %rdi
addq $0xf8, %rdi
movl $0x1, %esi
movl $0x2, %edx
callq 0xb0b0
movsd (%rax), %xmm0
movsd %xmm0, -0x78(%rbp)
movsd 0x72ee(%rip), %xmm0     # 0x12008
divsd -0x58(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
movsd 0x72dc(%rip), %xmm0     # 0x12008
divsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x88(%rbp)
movsd -0x68(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd -0x58(%rbp), %xmm1
mulsd -0x60(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x90(%rbp)
movsd -0x90(%rbp), %xmm0
movsd -0x78(%rbp), %xmm2
movsd -0x70(%rbp), %xmm1
divsd -0x58(%rbp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movsd -0x78(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
divsd -0x60(%rbp), %xmm0
movsd %xmm0, -0xa0(%rbp)
movl $0x0, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
movl %eax, -0xcc(%rbp)
movq -0x18(%rbp), %rdi
callq 0x6b20
movl %eax, %ecx
movl -0xcc(%rbp), %eax
cmpl %ecx, %eax
jge 0xaf38
movl $0x0, -0xa8(%rbp)
movl -0xa8(%rbp), %eax
movl %eax, -0xd0(%rbp)
movq -0x18(%rbp), %rdi
callq 0x6b10
movl %eax, %ecx
movl -0xd0(%rbp), %eax
cmpl %ecx, %eax
jge 0xaf22
movsd -0x80(%rbp), %xmm0
cvtsi2sdl -0xa8(%rbp), %xmm2
movsd -0x90(%rbp), %xmm1
cvtsi2sdl -0xa4(%rbp), %xmm3
mulsd %xmm3, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
addsd -0x98(%rbp), %xmm0
movsd %xmm0, -0xb0(%rbp)
movsd -0x88(%rbp), %xmm0
cvtsi2sdl -0xa4(%rbp), %xmm2
movsd -0xa0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xb8(%rbp)
movsd -0xb0(%rbp), %xmm0
movl $0x2, %edi
callq 0xb0e0
movsd %xmm0, -0xe0(%rbp)
movsd -0xb8(%rbp), %xmm0
movl $0x2, %edi
callq 0xb0e0
movaps %xmm0, %xmm1
movsd -0xe0(%rbp), %xmm0
addsd %xmm1, %xmm0
movsd 0x7134(%rip), %xmm1     # 0x12008
addsd %xmm1, %xmm0
callq 0x3180
movsd %xmm0, -0xd8(%rbp)
movq -0x18(%rbp), %rdi
movl -0xa8(%rbp), %esi
movl -0xa4(%rbp), %edx
callq 0x7c20
movsd -0xd8(%rbp), %xmm1
movsd (%rax), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movl -0xa8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa8(%rbp)
jmp 0xae0b
jmp 0xaf24
movl -0xa4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa4(%rbp)
jmp 0xaddc
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xe0, %rsp
popq %rbp
retq
nopw (%rax,%rax)