// File: /workspace/github_cpp_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x438, %rsp            # imm = 0x438
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x6076d(%rip), %rsi     # 0x9355b
movq %rbx, %rdi
callq 0xe550
testq %rax, %rax
je 0x32e5e
movq %rax, %r15
leaq 0x38(%rsp), %rdi
pushq $0x1
popq %rdx
movl $0x400, %esi            # imm = 0x400
movq %rax, %rcx
callq 0xe6f0
cmpq $0x1, %rax
jne 0x32e67
movl 0x38(%rsp), %r8d
movl 0x3c(%rsp), %r13d
testl %r8d, %r8d
setle %al
testl %r13d, %r13d
setle %cl
orb %al, %cl
movl 0x40(%rsp), %ebp
testl %ebp, %ebp
setle %al
orb %cl, %al
cmpb $0x1, %al
jne 0x32e90
leaq 0x65f5f(%rip), %rdi     # 0x98da6
xorl %r14d, %r14d
movl %r8d, %esi
movl %r13d, %edx
movl %ebp, %ecx
movq %rbx, %r8
xorl %eax, %eax
callq 0x681ca
jmp 0x32e7b
leaq 0x65efb(%rip), %rdi     # 0x98d60
jmp 0x32e6e
leaq 0x65f0f(%rip), %rdi     # 0x98d7d
xorl %r14d, %r14d
movq %rbx, %rsi
xorl %eax, %eax
callq 0x681ca
movl %r14d, %eax
addq $0x438, %rsp            # imm = 0x438
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl 0x44(%rsp), %esi
cmpl $0x2, %esi
jne 0x32f09
movl 0x94(%rsp), %esi
testl %esi, %esi
js 0x32f12
movq %rbx, 0x30(%rsp)
movl %r13d, %ebx
imull %r8d, %ebx
imull %ebp, %ebx
movq 0x230(%r14), %rdi
testq %rdi, %rdi
movl %r8d, 0x1c(%rsp)
je 0x32ecd
cmpl 0x24c(%r14), %ebx
jle 0x32eee
testq %rdi, %rdi
je 0x32ed7
callq 0xe5d0
movl %ebx, %edi
shlq $0x3, %rdi
callq 0xe030
movq %rax, 0x230(%r14)
movl 0x1c(%rsp), %r8d
movl 0x78(%rsp), %r12d
cmpl $0x1, %r12d
jne 0x32f2b
movl %r8d, 0x238(%r14)
movl 0x7c(%rsp), %ecx
movl %r8d, %eax
jmp 0x32f59
leaq 0x65ec5(%rip), %rdi     # 0x98dd5
jmp 0x32f19
leaq 0x65eed(%rip), %rdi     # 0x98e06
xorl %r14d, %r14d
movq %rbx, %rdx
xorl %eax, %eax
callq 0x681ca
jmp 0x32e7b
movl 0x7c(%rsp), %eax
movl %eax, 0xc(%rsp)
cmpl $0x1, %eax
movl %ebp, %eax
cmovel %r13d, %eax
movl %eax, 0x238(%r14)
cmpl $0x2, %r12d
jne 0x32f55
movl %r8d, 0x23c(%r14)
movl %r8d, %ecx
jmp 0x32f76
movl 0xc(%rsp), %ecx
movl %ecx, 0xc(%rsp)
cmpl $0x2, %ecx
movl %ebp, %ecx
cmovel %r13d, %ecx
movl %ecx, 0x23c(%r14)
movl %r8d, %edx
cmpl $0x3, %r12d
je 0x32f81
cmpl $0x3, 0xc(%rsp)
movl %ebp, %edx
cmovel %r13d, %edx
movl %ebp, 0x24(%rsp)
movl %edx, 0x240(%r14)
movl %eax, 0x244(%r14)
imull %eax, %ecx
movl %ecx, 0x248(%r14)
imull %edx, %ecx
movl %ecx, 0x24c(%r14)
movl $0x0, 0x14(%rsp)
movl 0x80(%rsp), %ecx
movl $0x0, 0x10(%rsp)
xorl %ebx, %ebx
xorl %edx, %edx
movl %r13d, 0x20(%rsp)
movl %ecx, 0x28(%rsp)
cmpl 0x24(%rsp), %edx
je 0x330e3
cmpl $0x1, %ecx
je 0x32fee
cmpl $0x3, %ecx
je 0x32fea
cmpl $0x2, %ecx
jne 0x32ff2
movl %edx, 0x10(%rsp)
jmp 0x32ff2
movl %edx, %ebx
jmp 0x32ff2
movl %edx, 0x14(%rsp)
xorl %eax, %eax
movl %edx, %ebp
movl %eax, 0x18(%rsp)
cmpl %r13d, %eax
je 0x330c8
movl 0xc(%rsp), %eax
cmpl $0x1, %eax
je 0x33024
cmpl $0x3, %eax
movl 0x18(%rsp), %esi
je 0x33020
cmpl $0x2, %eax
jne 0x3302c
movl %esi, 0x10(%rsp)
jmp 0x3302c
movl %esi, %ebx
jmp 0x3302c
movl 0x18(%rsp), %eax
movl %eax, 0x14(%rsp)
xorl %r13d, %r13d
cmpl %r13d, %r8d
je 0x330b8
cmpl $0x3, %r12d
je 0x33058
cmpl $0x2, %r12d
je 0x33051
cmpl $0x1, %r12d
jne 0x3305b
movl %r13d, 0x14(%rsp)
jmp 0x3305b
movl %r13d, 0x10(%rsp)
jmp 0x3305b
movl %r13d, %ebx
leaq 0x2c(%rsp), %rdi
pushq $0x4
popq %rsi
pushq $0x1
popq %rdx
movq %r15, %rcx
callq 0xe6f0
cmpq $0x1, %rax
jne 0x330cf
cvtss2sd 0x2c(%rsp), %xmm0
movq 0x230(%r14), %rax
movl 0x248(%r14), %ecx
imull %ebx, %ecx
movl 0x244(%r14), %edx
imull 0x10(%rsp), %edx
addl 0x14(%rsp), %ecx
addl %edx, %ecx
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
incl %r13d
movl 0x1c(%rsp), %r8d
movl 0x28(%rsp), %ecx
movl %ebp, %edx
jmp 0x3302f
movl 0x18(%rsp), %eax
incl %eax
movl 0x20(%rsp), %r13d
jmp 0x32ff6
incl %edx
jmp 0x32fcb
leaq 0x65d67(%rip), %rdi     # 0x98e3d
xorl %r14d, %r14d
movq 0x30(%rsp), %rsi
jmp 0x32e74
movq %r15, %rdi
callq 0xe440
pushq $0x1
popq %r14
jmp 0x32e7b