// File: /workspace/github_cpp_makefile_star2_O2/tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Grid.cpp
// Function: gaps::R2Grid::ReadPNGStream(_IO_FILE*)
int R2Grid::
ReadPNGStream(FILE *fp)
{
#ifdef RN_USE_PNG
  // Create and initialize the png_struct 
  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if (png_ptr == NULL) {
    fclose(fp);
    return 0;
  }

  // Allocate/initialize the memory for image information. 
  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (info_ptr == NULL) {
    fclose(fp);
    png_destroy_read_struct(&png_ptr, NULL, NULL);
    return 0;
  }

  // Set up the input control if you are using standard C streams 
  png_init_io(png_ptr, fp);

  // Read the png info 
  png_read_info(png_ptr, info_ptr);

  // Extract image info 
  png_byte color_type = png_get_color_type(png_ptr, info_ptr);
  int width = png_get_image_width(png_ptr, info_ptr);
  int height = png_get_image_height(png_ptr, info_ptr);
  int rowsize = png_get_rowbytes(png_ptr, info_ptr);
  if ((rowsize % 4) != 0) rowsize = (rowsize / 4 + 1) * 4;
  png_byte depth = png_get_bit_depth(png_ptr, info_ptr);
  int bytes_per_pixel = depth / 8;
  assert(rowsize >= bytes_per_pixel * width);

  // Set ncomponents
  int ncomponents = 0;
  if (color_type == PNG_COLOR_TYPE_GRAY) ncomponents = 1;
  else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ncomponents = 2;
  else if (color_type == PNG_COLOR_TYPE_RGB) ncomponents = 3;
  else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) ncomponents = 4;
  else { 
    fclose(fp);
    png_destroy_read_struct(&png_ptr, NULL, NULL);
    return 0;
  }

  // Allocate the pixels and row pointers 
  unsigned char *pixels = new unsigned char [ height * rowsize ]; 
  png_bytep *row_pointers = (png_bytep *) png_malloc(png_ptr, height * sizeof(png_bytep));
  for (int i = 0; i < height; i++) row_pointers[i] = &pixels[ (height - i - 1) * rowsize ];

  // Read the pixels 
  png_read_image(png_ptr, row_pointers);

  // Finish reading 
  png_read_end(png_ptr, info_ptr);

  // Fill in grid info
  grid_resolution[0] = width;
  grid_resolution[1] = height;
  grid_row_size = width;
  grid_size = width * height;
  world_to_grid_scale_factor = 1;
  world_to_grid_transform = R2identity_affine;
  grid_to_world_transform = R2identity_affine;
  if (grid_values) delete [] grid_values;
  grid_values = new RNScalar [ grid_size ];
  for (int j = 0; j < height; j++) {
    for (int i = 0; i < width; i++) {
      int rgba[4];
      for (int k = 0; k < ncomponents; k++) {
        rgba[k] = 0;
        for (int d = 0; d < bytes_per_pixel; d++) {
          rgba[k] = rgba[k] << 8;
          rgba[k] += row_pointers[height - 1 - j][bytes_per_pixel*i+d];
        }
      }

      // Compute value
      RNScalar value = 0;
      if (ncomponents == 1) value = rgba[0];
      else if (ncomponents == 2) value = rgba[0];
      else if (ncomponents == 3) value = 0.3*rgba[0] + 0.59*rgba[1] + 0.11*rgba[2];
      else if (ncomponents == 4) value = 0.3*rgba[0] + 0.59*rgba[1] + 0.11*rgba[2];
      SetGridValue(i, j, value);
    }
  }

  // Free the row pointers 
  png_free(png_ptr, row_pointers);

  // Free the pixels
  delete [] pixels;

  // Clean up after the read, and free any memory allocated  
  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

  // Return success 
  return 1;
#else
  RNFail("PNG not supported");
  return 0;
#endif
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rsi, %r15
movq %rdi, %rbp
leaq 0x40192(%rip), %rdi     # 0x9a719
xorl %ebx, %ebx
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x7ca10
movq %rax, 0x30(%rsp)
testq %rax, %rax
je 0x5a665
movq %rax, %r13
movq %rax, %rdi
callq 0x7a260
movq %rax, 0x60(%rsp)
testq %rax, %rax
je 0x5a672
movq %rax, %r12
movq %r13, %rdi
movq %r15, %rsi
callq 0x7a79c
movq %r13, %rdi
movq %r12, %rsi
callq 0x7cd59
movq %r13, %rdi
movq %r12, %rsi
callq 0x7c0ff
movl %eax, %ebx
movq %r13, %rdi
movq %r12, %rsi
callq 0x7c0bd
movl %eax, %r14d
movq %r13, %rdi
movq %r12, %rsi
callq 0x7c0d2
movl %eax, 0x14(%rsp)
movq %r13, %rdi
movq %r12, %rsi
callq 0x7c08a
testb $0x3, %al
je 0x5a61a
pushq $0x4
popq %rcx
cltd
idivl %ecx
leal 0x4(,%rax,4), %eax
movq %rax, 0x8(%rsp)
movq %r13, %rdi
movq %r12, 0x28(%rsp)
movq %r12, %rsi
callq 0x7c0e8
xorl %r12d, %r12d
testb %bl, %bl
je 0x5a68f
cmpb $0x6, %bl
je 0x5a6b2
movzbl %bl, %ecx
cmpl $0x4, %ecx
movq 0x8(%rsp), %rdx
je 0x5a69c
cmpl $0x2, %ecx
jne 0x5a672
movb %bl, 0x6(%rsp)
movq %rbp, 0x18(%rsp)
pushq $0x3
popq %r15
movq $0x0, 0x20(%rsp)
jmp 0x5a6cd
movq %r15, %rdi
callq 0xe440
jmp 0x5a90f
movq %r15, %rdi
callq 0xe440
xorl %ebx, %ebx
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x7daad
jmp 0x5a90f
movb %bl, 0x6(%rsp)
movq %rbp, 0x18(%rsp)
pushq $0x1
jmp 0x5a6bd
movb %bl, 0x6(%rsp)
movq %rbp, 0x18(%rsp)
pushq $0x2
popq %r15
movb $0x1, %cl
movq %rcx, 0x20(%rsp)
jmp 0x5a6cd
movb %bl, 0x6(%rsp)
movq %rbp, 0x18(%rsp)
pushq $0x4
popq %r15
movq $0x0, 0x20(%rsp)
movq 0x8(%rsp), %rdx
shrb $0x3, %al
movb %al, 0x7(%rsp)
movl %edx, %eax
movl 0x14(%rsp), %ebx
imull %ebx, %eax
movslq %eax, %rdi
callq 0xe030
movq %rax, %rbp
movslq %ebx, %rbx
leaq (,%rbx,8), %rsi
movq %r13, 0x38(%rsp)
movq %r13, %rdi
callq 0x848bb
movq 0x8(%rsp), %rdx
movq %rax, %r13
testl %ebx, %ebx
movl $0x0, %ecx
cmovgl %ebx, %ecx
decl %ebx
imull %edx, %ebx
cmpq %r12, %rcx
je 0x5a72f
movslq %ebx, %rbx
leaq (%rbx,%rbp), %rax
movq %rax, (%r13,%r12,8)
incq %r12
subl %edx, %ebx
jmp 0x5a717
movq %rcx, 0x8(%rsp)
movq %rbp, 0x58(%rsp)
movq 0x38(%rsp), %rbx
movq %rbx, %rdi
movq %r13, %rsi
callq 0x7d6fd
movq %rbx, %rdi
movq 0x28(%rsp), %rsi
callq 0x7d765
movq 0x18(%rsp), %r12
movl %r14d, 0xc0(%r12)
movl 0x14(%rsp), %eax
movl %eax, 0xc4(%r12)
movl %r14d, 0xc8(%r12)
imull %r14d, %eax
movl %eax, 0xcc(%r12)
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, 0xb0(%r12)
leaq 0x58(%r12), %rdi
leaq 0x4827c7(%rip), %rbx    # 0x4dcf68
movq %rbx, %rsi
callq 0x5ac32
movq %r12, %rdi
movq %rbx, %rsi
callq 0x5ac32
movq 0xb8(%r12), %rdi
testq %rdi, %rdi
je 0x5a7c6
callq 0xe5d0
cmpb $0x0, 0x6(%rsp)
sete %bl
movslq 0xcc(%r12), %rax
leaq (,%rax,8), %rcx
testq %rax, %rax
pushq $-0x1
popq %rdi
cmovnsq %rcx, %rdi
callq 0xe030
movq %rax, 0x28(%rsp)
movq %rax, 0xb8(%r12)
movslq 0xc8(%r12), %rax
movq %rax, 0x18(%rsp)
xorl %eax, %eax
testl %r14d, %r14d
cmovlel %eax, %r14d
movzbl 0x7(%rsp), %ecx
orb 0x20(%rsp), %bl
movsd 0x3fa7f(%rip), %xmm0    # 0x9a2a0
movsd 0x3fa7f(%rip), %xmm1    # 0x9a2a8
movsd 0x3fa7f(%rip), %xmm2    # 0x9a2b0
movq 0x8(%rsp), %rdx
cmpq %rdx, %rax
je 0x5a8e4
movl %eax, %esi
notl %esi
addl 0x14(%rsp), %esi
movslq %esi, %rdi
movq %rax, %rsi
imulq 0x18(%rsp), %rsi
movq 0x28(%rsp), %rdx
leaq (%rdx,%rsi,8), %r8
xorl %ebp, %ebp
xorl %r10d, %r10d
cmpq %r14, %r10
je 0x5a8dc
movl %ebp, %ebp
xorl %r11d, %r11d
cmpq %r15, %r11
je 0x5a8a5
andl $0x0, 0x40(%rsp,%r11,4)
xorl %r12d, %r12d
movq %rcx, %rsi
movq %rbp, %r9
subq $0x1, %rsi
jb 0x5a8a0
shll $0x8, %r12d
movq (%r13,%rdi,8), %rdx
movzbl (%rdx,%r9), %edx
orl %edx, %r12d
movl %r12d, 0x40(%rsp,%r11,4)
incq %r9
jmp 0x5a87f
incq %r11
jmp 0x5a86b
cvtsi2sdl 0x40(%rsp), %xmm3
testb %bl, %bl
jne 0x5a8cf
cvtsi2sdl 0x44(%rsp), %xmm4
mulsd %xmm0, %xmm4
mulsd %xmm1, %xmm3
addsd %xmm4, %xmm3
cvtsi2sdl 0x48(%rsp), %xmm4
mulsd %xmm2, %xmm4
addsd %xmm4, %xmm3
movsd %xmm3, (%r8,%r10,8)
incq %r10
addl %ecx, %ebp
jmp 0x5a861
incq %rax
jmp 0x5a831
movq 0x38(%rsp), %rdi
movq %r13, %rsi
callq 0x84923
movq 0x58(%rsp), %rdi
callq 0xe5d0
leaq 0x30(%rsp), %rdi
leaq 0x60(%rsp), %rsi
xorl %edx, %edx
callq 0x7daad
pushq $0x1
popq %rbx
movl %ebx, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq