// File: tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Grid.cpp
// Function: gaps::R2Grid::WritePNGStream(_IO_FILE*) const
int R2Grid::
WritePNGStream(FILE *fp) const
{
#ifdef RN_USE_PNG
  // Create and initialize the png_struct 
  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if (png_ptr == NULL) {
    fclose(fp);
    return 0;
  }
  
  // Allocate/initialize the image information data. 
  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (info_ptr == NULL) {
    fclose(fp);
    png_destroy_write_struct(&png_ptr,  NULL);
    return 0;
  }
  
  // Fill in the image data
  int width = grid_resolution[0];
  int height = grid_resolution[1];
  png_set_IHDR(png_ptr, info_ptr, width, height,
    16, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,
    PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

  // Copy the data into RNUInt16
  png_bytep data = new png_byte [ 2*grid_size ];
  png_bytep datap = data;
  for (int i = 0; i < grid_size; i++) {
    RNScalar value = grid_values[i];
    if (value == R2_GRID_UNKNOWN_VALUE) {
      *datap++ = 0;
      *datap++ = 0;
    }
    else {
      if (value > 65535) value = 65535;
      unsigned int ivalue = (unsigned int) value;
      *datap++ = (ivalue >> 8) & 0xFF;
      *datap++ = ivalue & 0xFF;
    }
  }

  // Allocate the row pointers
  png_bytep *row_pointers = (png_bytep *) png_malloc(png_ptr, height * sizeof(png_bytep));
  for (int i = 0; i < height; i++) row_pointers[i] = (png_bytep) &data[(height - i - 1) * 2*width];
  
  // Set up the output control 
  png_init_io(png_ptr, fp);
  
  // Write the png info 
  png_write_info(png_ptr, info_ptr);
  
  // Write the pixels 
  png_write_image(png_ptr, row_pointers);
  
  // Finish writing 
  png_write_end(png_ptr, info_ptr);
  
  // Free the row pointers 
  png_free(png_ptr, row_pointers);

  // Clean up after the write, and free any memory allocated 
  png_destroy_write_struct(&png_ptr, &info_ptr);

  // Delete copy of data
  delete [] data;

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

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movq %rsi, 0x80(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0x28(%rsp)
leaq 0x7d415(%rip), %rdi     # 0x136100
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rsi
movq %rcx, %rdx
callq 0x104540
movq %rax, 0x78(%rsp)
cmpq $0x0, 0x78(%rsp)
jne 0xb8d24
movq 0x80(%rsp), %rdi
callq 0xf4b0
movl $0x0, 0x94(%rsp)
jmp 0xb8fb4
movq 0x78(%rsp), %rdi
callq 0xfb820
movq %rax, 0x70(%rsp)
cmpq $0x0, 0x70(%rsp)
jne 0xb8d66
movq 0x80(%rsp), %rdi
callq 0xf4b0
leaq 0x78(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x105530
movl $0x0, 0x94(%rsp)
jmp 0xb8fb4
movq 0x28(%rsp), %rax
movl 0xc0(%rax), %ecx
movl %ecx, 0x6c(%rsp)
movl 0xc4(%rax), %eax
movl %eax, 0x68(%rsp)
movq 0x78(%rsp), %rdi
movq 0x70(%rsp), %rsi
movl 0x6c(%rsp), %edx
movl 0x68(%rsp), %ecx
movl $0x10, %r8d
xorl %r9d, %r9d
movl $0x0, (%rsp)
movl $0x0, 0x8(%rsp)
movl $0x0, 0x10(%rsp)
callq 0xfd370
movq 0x28(%rsp), %rax
movl 0xcc(%rax), %eax
shll %eax
movslq %eax, %rdi
callq 0xf030
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x58(%rsp)
movl $0x0, 0x54(%rsp)
movq 0x28(%rsp), %rcx
movl 0x54(%rsp), %eax
cmpl 0xcc(%rcx), %eax
jge 0xb8ed1
movq 0x28(%rsp), %rax
movq 0xb8(%rax), %rax
movslq 0x54(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x48(%rsp)
movsd 0x48(%rsp), %xmm0
movsd 0x7b08f(%rip), %xmm1    # 0x133eb0
ucomisd %xmm1, %xmm0
jne 0xb8e53
jp 0xb8e53
movq 0x58(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x58(%rsp)
movb $0x0, (%rax)
movq 0x58(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x58(%rsp)
movb $0x0, (%rax)
jmp 0xb8ebf
movsd 0x48(%rsp), %xmm0
movsd 0x7ce17(%rip), %xmm1    # 0x135c78
ucomisd %xmm1, %xmm0
jbe 0xb8e75
movsd 0x7ce09(%rip), %xmm0    # 0x135c78
movsd %xmm0, 0x48(%rsp)
cvttsd2si 0x48(%rsp), %rax
movl %eax, 0x44(%rsp)
movl 0x44(%rsp), %eax
shrl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x58(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x58(%rsp)
movb %cl, (%rax)
movl 0x44(%rsp), %eax
andl $0xff, %eax
movb %al, %cl
movq 0x58(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x58(%rsp)
movb %cl, (%rax)
jmp 0xb8ec1
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
jmp 0xb8de2
movq 0x78(%rsp), %rdi
movslq 0x68(%rsp), %rsi
shlq $0x3, %rsi
callq 0x1135b0
movq %rax, 0x38(%rsp)
movl $0x0, 0x34(%rsp)
movl 0x34(%rsp), %eax
cmpl 0x68(%rsp), %eax
jge 0xb8f32
movq 0x60(%rsp), %rdx
movl 0x68(%rsp), %eax
subl 0x34(%rsp), %eax
subl $0x1, %eax
shll %eax
imull 0x6c(%rsp), %eax
cltq
addq %rax, %rdx
movq 0x38(%rsp), %rax
movslq 0x34(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0xb8ef1
movq 0x78(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0xfc210
movq 0x78(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x103a80
movq 0x78(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x1052a0
movq 0x78(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x1040f0
movq 0x78(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x1136d0
leaq 0x78(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x105530
movq 0x60(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0xb8fa9
movq 0x20(%rsp), %rdi
callq 0xf670
movl $0x1, 0x94(%rsp)
movl 0x94(%rsp), %eax
addq $0x98, %rsp
retq
nopw %cs:(%rax,%rax)