// File: tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelBlock.cpp
// Function: gaps::R3SurfelBlock::ReadUPC(_IO_FILE*)
int R3SurfelBlock::
ReadUPC(FILE *fp)
{
  // Read header
  UPCHeader header;
  if (!ReadUPCHeader(fp, header)) return 0;

  // Compute scale and offset
  double xoffset = header.xOffset;
  double yoffset = header.yOffset;
  double zoffset = header.zOffset;
  double xscale = header.xScale;
  double yscale = header.yScale;
  double zscale = header.zScale;
 
  // XXX THIS IS A HACK FOR OTTAWA XXX
  xoffset -= 444965;
  yoffset -= 5029450;

  // Set position_origin
  position_origin = R3Point(xoffset, yoffset, zoffset);

  // Allocate memory for surfels
  int target_count = (int) header.numOfPts;
  surfels = new R3Surfel [ target_count ];
  if (!surfels) {
    RNFail("Unable to allocate surfel block\n");
    return 0;
  }

  // Allocate memory for UPC points
  const int upc_point_size = 36;
  char *upc_points = new char [ target_count * upc_point_size ];

  // Read upc points
  int upc_count = 0;
  while (upc_count < target_count) {
    int status = fread(&upc_points[upc_count], upc_point_size, target_count - upc_count, fp);
    if (status <= 0) break;
    upc_count += status;
  }

  // Assign surfels
  nsurfels = 0;
  for (int i = 0; i < upc_count; i++) {
    char *upc_point = &upc_points[i * upc_point_size];
    double x = *((RNInt32 *) &upc_point[16]) * xscale;
    double y = *((RNInt32 *) &upc_point[20]) * yscale;
    double z = *((RNInt32 *) &upc_point[24]) * zscale;
    RNUInt16 r = *((RNUInt16 *) &upc_point[29]);
    RNUInt16 g = *((RNUInt16 *) &upc_point[31]);
    RNUInt16 b = *((RNUInt16 *) &upc_point[33]);
    if (r > 255) r = 255;
    if (g > 255) g = 255;
    if (b > 255) b = 255;
    surfels[nsurfels].SetPosition(x, y, z);
    surfels[nsurfels].SetColor(r, g, b);
    surfels[nsurfels].SetAerial(upc_point[9] == '0');
    nsurfels++;
  }

  // Delete memory for UPC points
  delete [] upc_points;

  // Return success
  return 1;
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x128(%rsp)
movq %rsi, 0x120(%rsp)
movq 0x128(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x120(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x4f3a0
cmpl $0x0, %eax
jne 0x4ef6e
movl $0x0, 0x134(%rsp)
jmp 0x4f382
movsd 0x108(%rsp), %xmm0
movsd %xmm0, 0xd8(%rsp)
movsd 0x110(%rsp), %xmm0
movsd %xmm0, 0xd0(%rsp)
movsd 0x118(%rsp), %xmm0
movsd %xmm0, 0xc8(%rsp)
movsd 0xf0(%rsp), %xmm0
movsd %xmm0, 0xc0(%rsp)
movsd 0xf8(%rsp), %xmm0
movsd %xmm0, 0xb8(%rsp)
movsd 0x100(%rsp), %xmm0
movsd %xmm0, 0xb0(%rsp)
movsd 0xd8(%rsp), %xmm0
movsd 0x155f0d(%rip), %xmm1   # 0x1a4ef8
subsd %xmm1, %xmm0
movsd %xmm0, 0xd8(%rsp)
movsd 0xd0(%rsp), %xmm0
movsd 0x155ee7(%rip), %xmm1   # 0x1a4ef0
subsd %xmm1, %xmm0
movsd %xmm0, 0xd0(%rsp)
movsd 0xd8(%rsp), %xmm0
movsd 0xd0(%rsp), %xmm1
movsd 0xc8(%rsp), %xmm2
leaq 0x98(%rsp), %rdi
callq 0xf8350
movq 0x38(%rsp), %rdi
addq $0x10, %rdi
leaq 0x98(%rsp), %rsi
callq 0xf89e0
movq 0xe8(%rsp), %rax
movl %eax, 0x94(%rsp)
movslq 0x94(%rsp), %rax
movq %rax, 0x28(%rsp)
movl $0x30, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, 0x20(%rsp)
callq 0x13030
movq %rax, %rcx
movq 0x28(%rsp), %rax
movq %rcx, 0x30(%rsp)
cmpq $0x0, %rax
je 0x4f0f0
movq 0x30(%rsp), %rax
movq 0x28(%rsp), %rcx
imulq $0x30, %rcx, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x47310
jmp 0x4f0d8
movq 0x10(%rsp), %rcx
movq 0x8(%rsp), %rax
addq $0x30, %rax
cmpq %rcx, %rax
movq %rax, 0x18(%rsp)
jne 0x4f0c7
movq 0x38(%rsp), %rax
movq 0x30(%rsp), %rcx
movq %rcx, (%rax)
cmpq $0x0, (%rax)
jne 0x4f149
leaq 0x155ed4(%rip), %rdi    # 0x1a4fde
movb $0x0, %al
callq 0x1464b0
movl $0x0, 0x134(%rsp)
jmp 0x4f382
movq 0x20(%rsp), %rsi
movq 0x30(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x88(%rsp)
movl %eax, 0x84(%rsp)
callq 0x13a90
jmp 0x4f391
movl $0x24, 0x80(%rsp)
imull $0x24, 0x94(%rsp), %eax
movslq %eax, %rdi
callq 0x13030
movq %rax, 0x78(%rsp)
movl $0x0, 0x74(%rsp)
movl 0x74(%rsp), %eax
cmpl 0x94(%rsp), %eax
jge 0x4f1c6
movq 0x78(%rsp), %rdi
movslq 0x74(%rsp), %rax
addq %rax, %rdi
movl 0x94(%rsp), %eax
subl 0x74(%rsp), %eax
movslq %eax, %rdx
movq 0x120(%rsp), %rcx
movl $0x24, %esi
callq 0x13860
movl %eax, 0x70(%rsp)
cmpl $0x0, 0x70(%rsp)
jg 0x4f1b8
jmp 0x4f1c6
movl 0x70(%rsp), %eax
addl 0x74(%rsp), %eax
movl %eax, 0x74(%rsp)
jmp 0x4f171
movq 0x38(%rsp), %rax
movl $0x0, 0x8(%rax)
movl $0x0, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
cmpl 0x74(%rsp), %eax
jge 0x4f35f
movq 0x78(%rsp), %rax
imull $0x24, 0x6c(%rsp), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
cvtsi2sdl 0x10(%rax), %xmm0
mulsd 0xc0(%rsp), %xmm0
movsd %xmm0, 0x58(%rsp)
movq 0x60(%rsp), %rax
cvtsi2sdl 0x14(%rax), %xmm0
mulsd 0xb8(%rsp), %xmm0
movsd %xmm0, 0x50(%rsp)
movq 0x60(%rsp), %rax
cvtsi2sdl 0x18(%rax), %xmm0
mulsd 0xb0(%rsp), %xmm0
movsd %xmm0, 0x48(%rsp)
movq 0x60(%rsp), %rax
movw 0x1d(%rax), %ax
movw %ax, 0x46(%rsp)
movq 0x60(%rsp), %rax
movw 0x1f(%rax), %ax
movw %ax, 0x44(%rsp)
movq 0x60(%rsp), %rax
movw 0x21(%rax), %ax
movw %ax, 0x42(%rsp)
movzwl 0x46(%rsp), %eax
cmpl $0xff, %eax
jle 0x4f285
movw $0xff, 0x46(%rsp)
movzwl 0x44(%rsp), %eax
cmpl $0xff, %eax
jle 0x4f298
movw $0xff, 0x44(%rsp)
movzwl 0x42(%rsp), %eax
cmpl $0xff, %eax
jle 0x4f2ab
movw $0xff, 0x42(%rsp)
movq 0x38(%rsp), %rax
movq (%rax), %rdi
movslq 0x8(%rax), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
movsd 0x58(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movsd 0x50(%rsp), %xmm1
cvtsd2ss %xmm1, %xmm1
movsd 0x48(%rsp), %xmm2
cvtsd2ss %xmm2, %xmm2
callq 0x44cd0
movq 0x38(%rsp), %rax
movq (%rax), %rdi
movslq 0x8(%rax), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
movw 0x46(%rsp), %ax
movb %al, %dl
movw 0x44(%rsp), %ax
movb %al, %cl
movw 0x42(%rsp), %ax
movzbl %dl, %esi
movzbl %cl, %edx
movzbl %al, %ecx
callq 0x47a50
movq 0x38(%rsp), %rax
movq (%rax), %rdi
movslq 0x8(%rax), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
movq 0x60(%rsp), %rax
movsbl 0x9(%rax), %eax
cmpl $0x30, %eax
sete %al
andb $0x1, %al
movzbl %al, %esi
callq 0x44d50
movq 0x38(%rsp), %rax
movl 0x8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x8(%rax)
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x4f1da
movq 0x78(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x4f377
movq (%rsp), %rdi
callq 0x13750
movl $0x1, 0x134(%rsp)
movl 0x134(%rsp), %eax
addq $0x138, %rsp            # imm = 0x138
retq
movq 0x88(%rsp), %rdi
callq 0x13970
nop