// File: tomfunkhouser[P]gaps/pkgs/png/pngwrite.c
// Function: png_create_write_struct_2
png_structp PNGAPI
png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
{
#endif /* PNG_USER_MEM_SUPPORTED */
   volatile int png_cleanup_needed = 0;
#ifdef PNG_SETJMP_SUPPORTED
   volatile
#endif
   png_structp png_ptr;
#ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD
   jmp_buf jmpbuf;
#endif
#endif
   int i;

   png_debug(1, "in png_create_write_struct");

#ifdef PNG_USER_MEM_SUPPORTED
   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
      (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
#else
   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
#endif /* PNG_USER_MEM_SUPPORTED */
   if (png_ptr == NULL)
      return (NULL);

   /* Added at libpng-1.2.6 */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
   png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
   png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
#endif

#ifdef PNG_SETJMP_SUPPORTED
/* Applications that neglect to set up their own setjmp() and then
   encounter a png_error() will longjmp here.  Since the jmpbuf is
   then meaningless we abort instead of returning. */
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
#else
   if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */
#endif
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_jmpbuf(png_ptr), jmpbuf, png_sizeof(jmp_buf));
#endif
      PNG_ABORT();
#endif

#ifdef PNG_USER_MEM_SUPPORTED
   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
#endif /* PNG_USER_MEM_SUPPORTED */
   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);

   if (user_png_ver)
   {
      i = 0;
      do
      {
         if (user_png_ver[i] != png_libpng_ver[i])
            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
      } while (png_libpng_ver[i++]);
   }

   if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
   {
     /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
      * we must recompile any applications that use any older library version.
      * For versions after libpng 1.0, we will be compatible, so we need
      * only check the first digit.
      */
     if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
         (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
         (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
     {
#ifdef PNG_STDIO_SUPPORTED
        char msg[80];
        if (user_png_ver)
        {
           png_snprintf(msg, 80,
              "Application was compiled with png.h from libpng-%.20s",
              user_png_ver);
           png_warning(png_ptr, msg);
        }
        png_snprintf(msg, 80,
           "Application  is  running with png.c from libpng-%.20s",
           png_libpng_ver);
        png_warning(png_ptr, msg);
#endif
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
        png_ptr->flags = 0;
#endif
        png_warning(png_ptr,
           "Incompatible libpng version in application and library");
        png_cleanup_needed = 1;
     }
   }

   /* Initialize zbuf - compression buffer */
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
   if (!png_cleanup_needed)
   {
      png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr,
         png_ptr->zbuf_size);
      if (png_ptr->zbuf == NULL)
         png_cleanup_needed = 1;
   }
   if (png_cleanup_needed)
   {
       /* Clean up PNG structure and deallocate any memory. */
       png_free(png_ptr, png_ptr->zbuf);
       png_ptr->zbuf = NULL;
#ifdef PNG_USER_MEM_SUPPORTED
       png_destroy_struct_2((png_voidp)png_ptr,
          (png_free_ptr)free_fn, (png_voidp)mem_ptr);
#else
       png_destroy_struct((png_voidp)png_ptr);
#endif
       return (NULL);
   }

   png_set_write_fn(png_ptr, NULL, NULL, NULL);

#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
   png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
      1, NULL, NULL);
#endif

   return (png_ptr);
}

// Assembly:
subq $0xc8, %rsp
movq 0xd0(%rsp), %rax
movq %rdi, 0xb8(%rsp)
movq %rsi, 0xb0(%rsp)
movq %rdx, 0xa8(%rsp)
movq %rcx, 0xa0(%rsp)
movq %r8, 0x98(%rsp)
movq %r9, 0x90(%rsp)
movl $0x0, 0x8c(%rsp)
movq 0x90(%rsp), %rsi
movq 0x98(%rsp), %rdx
movl $0x1, %edi
callq 0x113380
movq %rax, 0x80(%rsp)
movq 0x80(%rsp), %rax
cmpq $0x0, %rax
jne 0x10461b
movq $0x0, 0xc0(%rsp)
jmp 0x10499e
movq 0x80(%rsp), %rax
movl $0xf4240, 0x454(%rax)   # imm = 0xF4240
movq 0x80(%rsp), %rax
movl $0xf4240, 0x458(%rax)   # imm = 0xF4240
movq 0x80(%rsp), %rdi
movq 0x6a94a(%rip), %rsi     # 0x16ef98
movl $0xc8, %edx
callq 0x113cb0
movq %rax, %rdi
callq 0xf740
cmpl $0x0, %eax
je 0x10466a
callq 0xf290
movq 0x80(%rsp), %rdi
movq 0x98(%rsp), %rsi
movq 0x90(%rsp), %rdx
movq 0xd0(%rsp), %rcx
callq 0x1137e0
movq 0x80(%rsp), %rdi
movq 0xb0(%rsp), %rsi
movq 0xa8(%rsp), %rdx
movq 0xa0(%rsp), %rcx
callq 0x113d00
cmpq $0x0, 0xb8(%rsp)
je 0x104737
movl $0x0, 0x7c(%rsp)
movq 0xb8(%rsp), %rax
movslq 0x7c(%rsp), %rcx
movsbl (%rax,%rcx), %eax
movl %eax, 0x1c(%rsp)
xorl %eax, %eax
movl %eax, %edi
callq 0xfc3a0
movq %rax, %rcx
movl 0x1c(%rsp), %eax
movslq 0x7c(%rsp), %rdx
movsbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
je 0x104714
movq 0x80(%rsp), %rax
movl 0x120(%rax), %ecx
orq $0x20000, %rcx          # imm = 0x20000
movl %ecx, 0x120(%rax)
jmp 0x104716
xorl %eax, %eax
movl %eax, %edi
callq 0xfc3a0
movl 0x7c(%rsp), %ecx
movl %ecx, %edx
addl $0x1, %edx
movl %edx, 0x7c(%rsp)
movslq %ecx, %rcx
cmpb $0x0, (%rax,%rcx)
jne 0x1046c7
jmp 0x104737
movq 0x80(%rsp), %rax
movl 0x120(%rax), %eax
andq $0x20000, %rax          # imm = 0x20000
cmpq $0x0, %rax
je 0x104889
cmpq $0x0, 0xb8(%rsp)
je 0x1047eb
movq 0xb8(%rsp), %rax
movsbl (%rax), %eax
movl %eax, 0x18(%rsp)
xorl %eax, %eax
movl %eax, %edi
callq 0xfc3a0
movq %rax, %rcx
movl 0x18(%rsp), %eax
movsbl (%rcx), %ecx
cmpl %ecx, %eax
jne 0x1047eb
movq 0xb8(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x31, %eax
jne 0x1047c2
movq 0xb8(%rsp), %rax
movsbl 0x2(%rax), %eax
movl %eax, 0x14(%rsp)
xorl %eax, %eax
movl %eax, %edi
callq 0xfc3a0
movq %rax, %rcx
movl 0x14(%rsp), %eax
movsbl 0x2(%rcx), %ecx
cmpl %ecx, %eax
jne 0x1047eb
movq 0xb8(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x30, %eax
jne 0x104887
movq 0xb8(%rsp), %rax
movsbl 0x2(%rax), %eax
cmpl $0x39, %eax
jge 0x104887
cmpq $0x0, 0xb8(%rsp)
je 0x104828
leaq 0x20(%rsp), %rdi
movq 0xb8(%rsp), %rcx
movl $0x50, %esi
leaq 0x3488d(%rip), %rdx     # 0x13909c
movb $0x0, %al
callq 0xf800
movq 0x80(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x113940
leaq 0x20(%rsp), %rax
movq %rax, 0x8(%rsp)
xorl %eax, %eax
movl %eax, %edi
callq 0xfc3a0
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl $0x50, %esi
leaq 0x34883(%rip), %rdx     # 0x1390d2
movb $0x0, %al
callq 0xf800
movq 0x80(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x113940
movq 0x80(%rsp), %rdi
leaq 0x34891(%rip), %rsi     # 0x139108
callq 0x113940
movl $0x1, 0x8c(%rsp)
jmp 0x104889
movq 0x80(%rsp), %rax
movq $0x2000, 0x1a0(%rax) # imm = 0x2000
movl 0x8c(%rsp), %eax
cmpl $0x0, %eax
jne 0x1048f5
movq 0x80(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x1a0(%rax), %rsi
callq 0x113760
movq %rax, %rcx
movq 0x80(%rsp), %rax
movq %rcx, 0x198(%rax)
movq 0x80(%rsp), %rax
cmpq $0x0, 0x198(%rax)
jne 0x1048f3
movl $0x1, 0x8c(%rsp)
jmp 0x1048f5
movl 0x8c(%rsp), %eax
cmpl $0x0, %eax
je 0x10495b
movq 0x80(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x198(%rax), %rsi
callq 0x1136d0
movq 0x80(%rsp), %rax
movq $0x0, 0x198(%rax)
movq 0x80(%rsp), %rdi
movq 0xd0(%rsp), %rsi
movq 0x98(%rsp), %rdx
callq 0x1134e0
movq $0x0, 0xc0(%rsp)
jmp 0x10499e
movq 0x80(%rsp), %rdi
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rsi
movq %rcx, %rdx
callq 0x131320
movq 0x80(%rsp), %rdi
xorl %esi, %esi
movl $0x1, %edx
xorl %eax, %eax
movl %eax, %r8d
movq %r8, %rcx
callq 0x1049b0
movq 0x80(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0xc0(%rsp), %rax
addq $0xc8, %rsp
retq
nop