// File: /workspace/github_cpp_makefile_star2_O3/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 0x6b5d5(%rip), %rsi     # 0xa25ab
movq %rbx, %rdi
callq 0xe530
testq %rax, %rax
je 0x37048
movq %rax, %r15
leaq 0x38(%rsp), %rdi
movl $0x400, %esi            # imm = 0x400
movl $0x1, %edx
movq %rax, %rcx
callq 0xe6c0
cmpq $0x1, %rax
jne 0x37051
movl 0x38(%rsp), %ebp
movl 0x3c(%rsp), %r13d
testl %ebp, %ebp
setle %al
testl %r13d, %r13d
setle %cl
orb %al, %cl
movl 0x40(%rsp), %r12d
testl %r12d, %r12d
setle %al
orb %cl, %al
cmpb $0x1, %al
jne 0x3707a
leaq 0x70dc5(%rip), %rdi     # 0xa7df6
xorl %r14d, %r14d
movl %ebp, %esi
movl %r13d, %edx
movl %r12d, %ecx
movq %rbx, %r8
xorl %eax, %eax
callq 0x719d2
jmp 0x37065
leaq 0x70d61(%rip), %rdi     # 0xa7db0
jmp 0x37058
leaq 0x70d75(%rip), %rdi     # 0xa7dcd
xorl %r14d, %r14d
movq %rbx, %rsi
xorl %eax, %eax
callq 0x719d2
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 0x37100
movl 0x94(%rsp), %esi
testl %esi, %esi
js 0x37109
movq %rbx, 0x30(%rsp)
movl %r13d, %ebx
imull %ebp, %ebx
imull %r12d, %ebx
movq 0x230(%r14), %rdi
testq %rdi, %rdi
je 0x370b2
cmpl 0x24c(%r14), %ebx
jle 0x370ce
testq %rdi, %rdi
je 0x370bc
callq 0xe5b0
movl %ebx, %edi
shlq $0x3, %rdi
callq 0xe030
movq %rax, 0x230(%r14)
movl %r12d, 0x10(%rsp)
movl 0x78(%rsp), %r12d
cmpl $0x1, %r12d
movl %ebp, 0x28(%rsp)
jne 0x37122
movl %ebp, 0x238(%r14)
movl 0x7c(%rsp), %eax
movl %eax, 0x14(%rsp)
cmpl $0x2, %eax
movl 0x10(%rsp), %ecx
cmovel %r13d, %ecx
movl %ebp, %eax
jmp 0x3714a
leaq 0x70d1e(%rip), %rdi     # 0xa7e25
jmp 0x37110
leaq 0x70d46(%rip), %rdi     # 0xa7e56
xorl %r14d, %r14d
movq %rbx, %rdx
xorl %eax, %eax
callq 0x719d2
jmp 0x37065
movl 0x7c(%rsp), %edx
cmpl $0x1, %edx
movl 0x10(%rsp), %ecx
movl %ecx, %eax
cmovel %r13d, %eax
movl %eax, 0x238(%r14)
cmpl $0x2, %r12d
movl %edx, 0x14(%rsp)
jne 0x372bc
movl %ebp, %ecx
movl %ecx, 0x23c(%r14)
cmpl $0x3, 0x14(%rsp)
movl 0x10(%rsp), %ebp
cmovel %r13d, %ebp
movl %ebp, 0x240(%r14)
movl %eax, 0x244(%r14)
imull %eax, %ecx
movl %ecx, 0x248(%r14)
imull %ebp, %ecx
movl %ecx, 0x24c(%r14)
movl $0x0, 0xc(%rsp)
movl 0x80(%rsp), %edx
movl $0x0, 0x18(%rsp)
xorl %ebp, %ebp
xorl %ebx, %ebx
movl %r13d, 0x20(%rsp)
movl 0x14(%rsp), %eax
movl %edx, 0x1c(%rsp)
cmpl $0x1, %edx
je 0x371c7
cmpl $0x3, %edx
je 0x371bd
cmpl $0x2, %edx
jne 0x371cb
movl 0xc(%rsp), %ebp
jmp 0x371cb
movl 0xc(%rsp), %ecx
movl %ecx, 0x18(%rsp)
jmp 0x371cb
movl 0xc(%rsp), %ebx
xorl %ecx, %ecx
cmpl $0x1, %eax
movl %ecx, 0x24(%rsp)
je 0x371ea
cmpl $0x3, %eax
je 0x371e4
cmpl $0x2, %eax
jne 0x371ec
movl %ecx, %ebp
jmp 0x371ec
movl %ecx, 0x18(%rsp)
jmp 0x371ec
movl %ecx, %ebx
xorl %r13d, %r13d
cmpl $0x3, %r12d
je 0x3720b
cmpl $0x2, %r12d
je 0x37206
cmpl $0x1, %r12d
jne 0x37210
movl %r13d, %ebx
jmp 0x37210
movl %r13d, %ebp
jmp 0x37210
movl %r13d, 0x18(%rsp)
movl $0x4, %esi
movl $0x1, %edx
leaq 0x2c(%rsp), %rdi
movq %r15, %rcx
callq 0xe6c0
cmpq $0x1, %rax
jne 0x372a8
xorps %xmm0, %xmm0
cvtss2sd 0x2c(%rsp), %xmm0
movq 0x230(%r14), %rax
movl 0x248(%r14), %ecx
imull 0x18(%rsp), %ecx
movl 0x244(%r14), %edx
imull %ebp, %edx
addl %ebx, %ecx
addl %edx, %ecx
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
incl %r13d
cmpl %r13d, 0x28(%rsp)
jne 0x371ef
movl 0x24(%rsp), %ecx
incl %ecx
cmpl 0x20(%rsp), %ecx
movl 0x14(%rsp), %eax
movl 0x1c(%rsp), %edx
jne 0x371cd
movl 0xc(%rsp), %ecx
incl %ecx
movl %ecx, 0xc(%rsp)
cmpl 0x10(%rsp), %ecx
jne 0x371a8
movq %r15, %rdi
callq 0xe430
movl $0x1, %r14d
jmp 0x37065
leaq 0x70bde(%rip), %rdi     # 0xa7e8d
xorl %r14d, %r14d
movq 0x30(%rsp), %rsi
jmp 0x3705e
cmpl $0x2, %edx
cmovel %r13d, %ecx
movl %ecx, 0x23c(%r14)
cmpl $0x3, %r12d
jne 0x37151
jmp 0x3715e
nop