// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Grid.cpp
// Function: gaps::R3Grid::ReadCCP4File(char const*)
int R3Grid::
ReadCCP4File(const char *filename)
{
  // Open file
  FILE *fp = fopen(filename, "rb");
  if (!fp) {
    RNFail("Unable to open CCP4 file %s\n", filename);
    return 0;
  }

  // Read header
  R3GridCCP4Header header;
  if (fread(&header, sizeof(R3GridCCP4Header), 1, fp) != 1) {
    RNFail("Unable to read header from CCP4 file: %s", filename);
    return 0;
  }

  // Check dimensions
  if ((header.nc <= 0) || (header.nr <= 0) || (header.ns <= 0)) {
    RNFail("Invalid dimensions (%d %d %d) in CCP4 file: %s", header.nc, header.nr, header.ns, filename);
    return 0;
  }


  // Check mode
  if (header.mode != 2) { // Reals
    RNFail("Invalid mode (%d rather than 2) in CCP4 file: %s", header.mode, filename);
    return 0;
  }

  // Check symmetry information
  if (header.nsymbt < 0) {
    RNFail("Invalid number of symmetry bytes (%d) in CCP4 file: %s", header.nsymbt, filename);
    return 0;
  }

#if 0
  // Read symmetry information
  for (int i = 0; i < header.nsymbt; i++) {
    char c;
    if (fread(&c, sizeof(char), 1, fp) != 1) {
      RNFail("Unable to read symmetry info from CCP4 file: %s", filename);
      return 0;
    }
  }
#endif

  // Re-allocate grid values
  int new_size = header.nc * header.nr * header.ns;
  if (!grid_values || (new_size > grid_size)) { 
    if (grid_values) delete [] grid_values;
    grid_values = new RNScalar [ new_size ];
    assert(grid_values);
  }

  // Update grid resolution variables
  grid_resolution[0] = (header.mapc == 1) ? header.nc : ((header.mapr == 1) ? header.nr : header.ns);
  grid_resolution[1] = (header.mapc == 2) ? header.nc : ((header.mapr == 2) ? header.nr : header.ns);
  grid_resolution[2] = (header.mapc == 3) ? header.nc : ((header.mapr == 3) ? header.nr : header.ns);
  grid_row_size = grid_resolution[0];
  grid_sheet_size = grid_row_size * grid_resolution[1];
  grid_size = grid_sheet_size * grid_resolution[2];
  if (grid_size <= 0) {
    RNFail("Invalid grid size (%d) in file", grid_size);
    return 0;
  }

  // Read map 
  int x = 0;
  int y = 0;
  int z = 0;
  for (int k = 0; k < header.ns; k++) {
    if (header.maps == 1) x = k;
    else if (header.maps == 2) y = k;
    else if (header.maps == 3) z = k;
    for (int j = 0; j < header.nr; j++) {
      if (header.mapr == 1) x = j;
      else if (header.mapr == 2) y = j;
      else if (header.mapr == 3) z = j;
      for (int i = 0; i < header.nc; i++) {
        if (header.mapc == 1) x = i;
        else if (header.mapc == 2) y = i;
        else if (header.mapc == 3) z = i;

        // Read float
        float value;
        if (fread(&value, sizeof(float), 1, fp) != 1) {
          RNFail("Unable to read map from CCP4 file: %s", filename);
          return 0;
        }

        // Store in grid as double
        SetGridValue(x, y, z, value);
      }
    }
  }

  // Close file
  fclose(fp);

  // Return success
  return 1;
}

// Assembly:
subq $0x468, %rsp            # imm = 0x468
movq %rdi, 0x458(%rsp)
movq %rsi, 0x450(%rsp)
movq 0x458(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x450(%rsp), %rdi
leaq 0xce496(%rip), %rsi     # 0x1335d9
callq 0xf5e0
movq %rax, 0x448(%rsp)
cmpq $0x0, 0x448(%rsp)
jne 0x65181
movq 0x450(%rsp), %rsi
leaq 0xcf784(%rip), %rdi     # 0x1348ee
movb $0x0, %al
callq 0xd4f30
movl $0x0, 0x464(%rsp)
jmp 0x6560c
movq 0x448(%rsp), %rcx
leaq 0x48(%rsp), %rdi
movl $0x400, %esi            # imm = 0x400
movl $0x1, %edx
callq 0xf780
cmpq $0x1, %rax
je 0x651c9
movq 0x450(%rsp), %rsi
leaq 0xcf759(%rip), %rdi     # 0x13490b
movb $0x0, %al
callq 0xd4f30
movl $0x0, 0x464(%rsp)
jmp 0x6560c
cmpl $0x0, 0x48(%rsp)
jle 0x651de
cmpl $0x0, 0x4c(%rsp)
jle 0x651de
cmpl $0x0, 0x50(%rsp)
jg 0x65210
movl 0x48(%rsp), %esi
movl 0x4c(%rsp), %edx
movl 0x50(%rsp), %ecx
movq 0x450(%rsp), %r8
leaq 0xcf73b(%rip), %rdi     # 0x134934
movb $0x0, %al
callq 0xd4f30
movl $0x0, 0x464(%rsp)
jmp 0x6560c
cmpl $0x2, 0x54(%rsp)
je 0x65241
movl 0x54(%rsp), %esi
movq 0x450(%rsp), %rdx
leaq 0xcf739(%rip), %rdi     # 0x134963
movb $0x0, %al
callq 0xd4f30
movl $0x0, 0x464(%rsp)
jmp 0x6560c
cmpl $0x0, 0xa4(%rsp)
jge 0x65278
movl 0xa4(%rsp), %esi
movq 0x450(%rsp), %rdx
leaq 0xcf733(%rip), %rdi     # 0x134994
movb $0x0, %al
callq 0xd4f30
movl $0x0, 0x464(%rsp)
jmp 0x6560c
movq 0x20(%rsp), %rax
movl 0x48(%rsp), %ecx
imull 0x4c(%rsp), %ecx
imull 0x50(%rsp), %ecx
movl %ecx, 0x44(%rsp)
cmpq $0x0, 0x230(%rax)
je 0x652aa
movq 0x20(%rsp), %rcx
movl 0x44(%rsp), %eax
cmpl 0x24c(%rcx), %eax
jle 0x65311
movq 0x20(%rsp), %rax
cmpq $0x0, 0x230(%rax)
je 0x652dc
movq 0x20(%rsp), %rax
movq 0x230(%rax), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, %rax
je 0x652da
movq 0x18(%rsp), %rdi
callq 0xf670
jmp 0x652dc
movslq 0x44(%rsp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0xf030
movq %rax, %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x230(%rax)
cmpl $0x1, 0x88(%rsp)
jne 0x65325
movl 0x48(%rsp), %eax
movl %eax, 0x14(%rsp)
jmp 0x65349
cmpl $0x1, 0x8c(%rsp)
jne 0x65339
movl 0x4c(%rsp), %eax
movl %eax, 0x10(%rsp)
jmp 0x65341
movl 0x50(%rsp), %eax
movl %eax, 0x10(%rsp)
movl 0x10(%rsp), %eax
movl %eax, 0x14(%rsp)
movq 0x20(%rsp), %rax
movl 0x14(%rsp), %ecx
movl %ecx, 0x238(%rax)
cmpl $0x2, 0x88(%rsp)
jne 0x6536c
movl 0x48(%rsp), %eax
movl %eax, 0xc(%rsp)
jmp 0x65390
cmpl $0x2, 0x8c(%rsp)
jne 0x65380
movl 0x4c(%rsp), %eax
movl %eax, 0x8(%rsp)
jmp 0x65388
movl 0x50(%rsp), %eax
movl %eax, 0x8(%rsp)
movl 0x8(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0x20(%rsp), %rax
movl 0xc(%rsp), %ecx
movl %ecx, 0x23c(%rax)
cmpl $0x3, 0x88(%rsp)
jne 0x653b3
movl 0x48(%rsp), %eax
movl %eax, 0x4(%rsp)
jmp 0x653d4
cmpl $0x3, 0x8c(%rsp)
jne 0x653c6
movl 0x4c(%rsp), %eax
movl %eax, (%rsp)
jmp 0x653cd
movl 0x50(%rsp), %eax
movl %eax, (%rsp)
movl (%rsp), %eax
movl %eax, 0x4(%rsp)
movq 0x20(%rsp), %rax
movl 0x4(%rsp), %ecx
movl %ecx, 0x240(%rax)
movl 0x238(%rax), %ecx
movl %ecx, 0x244(%rax)
movl 0x244(%rax), %ecx
imull 0x23c(%rax), %ecx
movl %ecx, 0x248(%rax)
movl 0x248(%rax), %ecx
imull 0x240(%rax), %ecx
movl %ecx, 0x24c(%rax)
cmpl $0x0, 0x24c(%rax)
jg 0x65447
movq 0x20(%rsp), %rax
movl 0x24c(%rax), %esi
leaq 0xcef49(%rip), %rdi     # 0x134379
movb $0x0, %al
callq 0xd4f30
movl $0x0, 0x464(%rsp)
jmp 0x6560c
movl $0x0, 0x40(%rsp)
movl $0x0, 0x3c(%rsp)
movl $0x0, 0x38(%rsp)
movl $0x0, 0x34(%rsp)
movl 0x34(%rsp), %eax
cmpl 0x50(%rsp), %eax
jge 0x655f4
cmpl $0x1, 0x90(%rsp)
jne 0x65489
movl 0x34(%rsp), %eax
movl %eax, 0x40(%rsp)
jmp 0x654b3
cmpl $0x2, 0x90(%rsp)
jne 0x6549d
movl 0x34(%rsp), %eax
movl %eax, 0x3c(%rsp)
jmp 0x654b1
cmpl $0x3, 0x90(%rsp)
jne 0x654af
movl 0x34(%rsp), %eax
movl %eax, 0x38(%rsp)
jmp 0x654b1
jmp 0x654b3
movl $0x0, 0x30(%rsp)
movl 0x30(%rsp), %eax
cmpl 0x4c(%rsp), %eax
jge 0x655e2
cmpl $0x1, 0x8c(%rsp)
jne 0x654dd
movl 0x30(%rsp), %eax
movl %eax, 0x40(%rsp)
jmp 0x65507
cmpl $0x2, 0x8c(%rsp)
jne 0x654f1
movl 0x30(%rsp), %eax
movl %eax, 0x3c(%rsp)
jmp 0x65505
cmpl $0x3, 0x8c(%rsp)
jne 0x65503
movl 0x30(%rsp), %eax
movl %eax, 0x38(%rsp)
jmp 0x65505
jmp 0x65507
movl $0x0, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
cmpl 0x48(%rsp), %eax
jge 0x655d0
cmpl $0x1, 0x88(%rsp)
jne 0x65531
movl 0x2c(%rsp), %eax
movl %eax, 0x40(%rsp)
jmp 0x6555b
cmpl $0x2, 0x88(%rsp)
jne 0x65545
movl 0x2c(%rsp), %eax
movl %eax, 0x3c(%rsp)
jmp 0x65559
cmpl $0x3, 0x88(%rsp)
jne 0x65557
movl 0x2c(%rsp), %eax
movl %eax, 0x38(%rsp)
jmp 0x65559
jmp 0x6555b
movq 0x448(%rsp), %rcx
leaq 0x28(%rsp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0xf780
cmpq $0x1, %rax
je 0x655a0
movq 0x450(%rsp), %rsi
leaq 0xcf43f(%rip), %rdi     # 0x1349cb
movb $0x0, %al
callq 0xd4f30
movl $0x0, 0x464(%rsp)
jmp 0x6560c
movq 0x20(%rsp), %rdi
movl 0x40(%rsp), %esi
movl 0x3c(%rsp), %edx
movl 0x38(%rsp), %ecx
movss 0x28(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
callq 0x6bc60
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x6550f
jmp 0x655d2
movl 0x30(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x30(%rsp)
jmp 0x654bb
jmp 0x655e4
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0x65467
movq 0x448(%rsp), %rdi
callq 0xf4b0
movl $0x1, 0x464(%rsp)
movl 0x464(%rsp), %eax
addq $0x468, %rsp            # imm = 0x468
retq
nopl (%rax,%rax)