// File: /workspace/github_cpp_makefile_star2_O1/tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Image.cpp
// Function: gaps::R2Image::ReadGRDFile(char const*)
int R2Image::
ReadGRDFile(const char *filename)
{
  // Open file
  FILE *fp = fopen(filename, "rb");
  if (!fp) {
    RNFail("Unable to open file %s", filename);
    return 0;
  }

  // Read grid resolution from file
  int grid_resolution[2];
  if (fread(&grid_resolution, sizeof(int), 2, fp) != 2) {
    RNFail("Unable to read resolution from grid file");
    return 0;
  }

  // Read world_to_grid transformation from file
  RNScalar m[9];
  if (fread(m, sizeof(RNScalar), 9, fp) != 9) {
    RNFail("Unable to read transformation matrix from file");
    return 0;
  }

  // Allocate grid values
  int grid_size = grid_resolution[0] * grid_resolution[1];
  RNScalar *grid_values = new RNScalar [ grid_size ];
  assert(grid_values);

  // Read grid values
  if (fread(grid_values, sizeof(RNScalar), grid_size, fp) != (unsigned int) grid_size) {
    RNFail("Unable to read %d grid values from file", grid_size);
    return 0;
  }

  // Close file
  fclose(fp);

  // Determine offset and scale
  RNScalar offset = 0;
  RNScalar scale = 1;
  if (grid_size > 0) {
    RNScalar sum = 0;
    RNScalar min_value = FLT_MAX;
    RNScalar max_value = -FLT_MAX;
    for (int i = 0; i < grid_size; i++) {
      if (grid_values[i] == R2_GRID_UNKNOWN_VALUE) continue;
      if (grid_values[i] > max_value) max_value = grid_values[i];
      if (grid_values[i] < min_value) min_value = grid_values[i];
      sum += grid_values[i];
    }
    RNScalar mean = sum / grid_size;
    RNScalar ssd = 0;
    for (int i = 0; i < grid_size; i++) {
      if (grid_values[i] == R2_GRID_UNKNOWN_VALUE) continue;
      RNScalar delta = grid_values[i] - mean;
      ssd += delta * delta;
    }
    RNScalar stddev = sqrt(ssd);
    RNScalar min_clamped = mean - 3 * stddev;
    if (min_clamped < min_value) min_clamped = min_value;
    RNScalar max_clamped = mean + 3 * stddev;
    if (max_clamped > max_value) max_clamped = max_value;
    RNScalar range = max_clamped - min_clamped;
    if (range > 0) {
      offset = min_clamped;
      scale = 1.0 / range;
    }
  }

  // Allocate pixels
  ncomponents = 3;
  width = grid_resolution[0];
  height = grid_resolution[1];
  rowsize = ncomponents * width;
  if ((rowsize % 4) != 0) rowsize = (rowsize / 4 + 1) * 4;
  int nbytes = rowsize * height;
  pixels = new unsigned char [nbytes];
  assert(pixels);

  // Fill in pixels
  RNScalar *grid_valuesp = grid_values;
  for (int j = 0; j < height; j++) {
    unsigned char *pixelsp = &pixels[j*rowsize];
    for (int i = 0; i < width; i++) {
      int value = (int) ((*(grid_valuesp++) - offset) * 255.0 * scale);
      if (value < 0) value = 0;
      if (value > 255) value = 255;
      unsigned char p = (unsigned char) value;
      *(pixelsp++) = p;
      *(pixelsp++) = p;
      *(pixelsp++) = p;
    }
  }

  // Delete grid values
  delete [] grid_values;

  // Return number of bytes
  return nbytes;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rsi, %r15
movq %rdi, %r14
leaq 0x3703c(%rip), %rsi     # 0xa25ae
movq %r15, %rdi
callq 0xe530
testq %rax, %rax
je 0x6b6d0
movq %rax, %r13
leaq 0x18(%rsp), %rdi
movl $0x4, %esi
movl $0x2, %edx
movq %rax, %rcx
callq 0xe6c0
cmpq $0x2, %rax
jne 0x6b6e5
leaq 0x40(%rsp), %rdi
movl $0x8, %esi
movl $0x9, %edx
movq %r13, %rcx
callq 0xe6c0
cmpq $0x9, %rax
jne 0x6b6ee
movl 0x18(%rsp), %eax
movl 0x1c(%rsp), %ebx
movl %ebx, %r12d
movq %rax, (%rsp)
imull %eax, %r12d
movslq %r12d, %rbp
leaq (,%rbp,8), %rax
testl %ebp, %ebp
movq $-0x1, %rdi
cmovnsq %rax, %rdi
callq 0xe030
movq %rax, %r15
movl $0x8, %esi
movq %rax, %rdi
movq %rbp, %rdx
movq %r13, %rcx
callq 0xe6c0
cmpq %r12, %rax
jne 0x6b712
movq %r13, %rdi
callq 0xe430
testl %r12d, %r12d
jle 0x6b727
movsd 0x37690(%rip), %xmm6    # 0xa2cc0
movsd 0x36a08(%rip), %xmm5    # 0xa2040
xorpd %xmm7, %xmm7
xorl %eax, %eax
movsd 0x37972(%rip), %xmm1    # 0xa2fb8
movsd (%r15,%rax,8), %xmm0
ucomisd %xmm1, %xmm0
jne 0x6b654
jnp 0x6b66c
movapd %xmm0, %xmm2
maxsd %xmm6, %xmm2
addsd %xmm0, %xmm7
minsd %xmm5, %xmm0
movapd %xmm2, %xmm6
movapd %xmm0, %xmm5
incq %rax
cmpq %rax, %r12
jne 0x6b646
xorps %xmm0, %xmm0
cvtsi2sd %r12d, %xmm0
divsd %xmm0, %xmm7
xorpd %xmm0, %xmm0
xorl %eax, %eax
movsd (%r15,%rax,8), %xmm2
movapd %xmm2, %xmm3
subsd %xmm7, %xmm3
mulsd %xmm3, %xmm3
addsd %xmm0, %xmm3
cmpeqsd %xmm1, %xmm2
movapd %xmm2, %xmm4
andnpd %xmm3, %xmm4
andpd %xmm0, %xmm2
orpd %xmm4, %xmm2
movapd %xmm2, %xmm0
incq %rax
cmpq %rax, %r12
jne 0x6b686
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm0
jb 0x6b739
sqrtsd %xmm0, %xmm0
jmp 0x6b766
leaq 0x36ce6(%rip), %rdi     # 0xa23bd
xorl %ebx, %ebx
movq %r15, %rsi
xorl %eax, %eax
callq 0x72a1e
jmp 0x6b6fe
leaq 0x3dfb5(%rip), %rdi     # 0xa96a1
jmp 0x6b6f5
leaq 0x3dfd5(%rip), %rdi     # 0xa96ca
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x72a1e
movl %ebx, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x3e794(%rip), %rdi     # 0xa9ead
xorl %ebx, %ebx
movl %r12d, %esi
xorl %eax, %eax
callq 0x72a1e
jmp 0x6b6fe
xorpd %xmm2, %xmm2
movsd 0x36905(%rip), %xmm0    # 0xa2038
movq (%rsp), %rax
jmp 0x6b7ad
movapd %xmm5, 0x20(%rsp)
movsd %xmm6, 0x38(%rsp)
movsd %xmm7, 0x30(%rsp)
callq 0xe340
movsd 0x30(%rsp), %xmm7
movsd 0x38(%rsp), %xmm6
movapd 0x20(%rsp), %xmm5
xorpd %xmm2, %xmm2
movq (%rsp), %rax
movsd 0x3d8a6(%rip), %xmm1    # 0xa9018
mulsd %xmm0, %xmm1
addsd %xmm7, %xmm1
maxsd %xmm1, %xmm5
mulsd 0x36a52(%rip), %xmm0    # 0xa21d8
addsd %xmm7, %xmm0
minsd %xmm0, %xmm6
subsd %xmm5, %xmm6
ucomisd %xmm2, %xmm6
movsd 0x3689a(%rip), %xmm0    # 0xa2038
jbe 0x6b7a4
divsd %xmm6, %xmm0
cmpltsd %xmm6, %xmm2
andpd %xmm5, %xmm2
movl $0x3, 0x8(%r14)
movl %eax, (%r14)
movl %ebx, 0x4(%r14)
leal (%rax,%rax,2), %eax
testb $0x3, %al
movapd %xmm2, (%rsp)
movsd %xmm0, 0x20(%rsp)
je 0x6b7de
leal 0x3(%rax), %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
andl $-0x4, %ecx
addl $0x4, %ecx
movl %ecx, %eax
movl %eax, 0xc(%r14)
imull %eax, %ebx
movslq %ebx, %rdi
callq 0xe030
movq %rax, 0x10(%r14)
cmpl $0x0, 0x4(%r14)
movapd (%rsp), %xmm2
movsd 0x20(%rsp), %xmm3
jle 0x6b873
xorl %eax, %eax
movsd 0x36a0b(%rip), %xmm0    # 0xa2218
movq %r15, %rcx
movl $0xff, %r8d
cmpl $0x0, (%r14)
jle 0x6b86b
movslq 0xc(%r14), %rsi
movslq %eax, %rdx
imulq %rsi, %rdx
addq 0x10(%r14), %rdx
xorl %esi, %esi
movsd (%rcx), %xmm1
subsd %xmm2, %xmm1
mulsd %xmm0, %xmm1
mulsd %xmm3, %xmm1
cvttsd2si %xmm1, %edi
testl %edi, %edi
jg 0x6b847
xorl %edi, %edi
cmpl %r8d, %edi
jl 0x6b851
movl $0xff, %edi
addq $0x8, %rcx
movb %dil, (%rdx)
movb %dil, 0x1(%rdx)
movb %dil, 0x2(%rdx)
addq $0x3, %rdx
incl %esi
cmpl (%r14), %esi
jl 0x6b82d
incl %eax
cmpl 0x4(%r14), %eax
jl 0x6b816
movq %r15, %rdi
callq 0xe5b0
jmp 0x6b6fe