// File: tomfunkhouser[P]gaps/pkgs/png/pngwutil.c
// Function: png_write_IHDR
void /* PRIVATE */
png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
   int bit_depth, int color_type, int compression_type, int filter_type,
   int interlace_type)
{
   PNG_IHDR;
   int ret;

   png_byte buf[13]; /* Buffer to store the IHDR info */

   png_debug(1, "in png_write_IHDR");

   /* Check that we have valid input data from the application info */
   switch (color_type)
   {
      case PNG_COLOR_TYPE_GRAY:
         switch (bit_depth)
         {
            case 1:
            case 2:
            case 4:
            case 8:
            case 16: png_ptr->channels = 1; break;
            default: png_error(png_ptr,
                         "Invalid bit depth for grayscale image");
         }
         break;
      case PNG_COLOR_TYPE_RGB:
         if (bit_depth != 8 && bit_depth != 16)
            png_error(png_ptr, "Invalid bit depth for RGB image");
         png_ptr->channels = 3;
         break;
      case PNG_COLOR_TYPE_PALETTE:
         switch (bit_depth)
         {
            case 1:
            case 2:
            case 4:
            case 8: png_ptr->channels = 1; break;
            default: png_error(png_ptr, "Invalid bit depth for paletted image");
         }
         break;
      case PNG_COLOR_TYPE_GRAY_ALPHA:
         if (bit_depth != 8 && bit_depth != 16)
            png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
         png_ptr->channels = 2;
         break;
      case PNG_COLOR_TYPE_RGB_ALPHA:
         if (bit_depth != 8 && bit_depth != 16)
            png_error(png_ptr, "Invalid bit depth for RGBA image");
         png_ptr->channels = 4;
         break;
      default:
         png_error(png_ptr, "Invalid image color type specified");
   }

   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
   {
      png_warning(png_ptr, "Invalid compression type specified");
      compression_type = PNG_COMPRESSION_TYPE_BASE;
   }

   /* Write filter_method 64 (intrapixel differencing) only if
    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
    * 2. Libpng did not write a PNG signature (this filter_method is only
    *    used in PNG datastreams that are embedded in MNG datastreams) and
    * 3. The application called png_permit_mng_features with a mask that
    *    included PNG_FLAG_MNG_FILTER_64 and
    * 4. The filter_method is 64 and
    * 5. The color_type is RGB or RGBA
    */
   if (
#ifdef PNG_MNG_FEATURES_SUPPORTED
      !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
      ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
      (color_type == PNG_COLOR_TYPE_RGB ||
       color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
      (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
#endif
      filter_type != PNG_FILTER_TYPE_BASE)
   {
      png_warning(png_ptr, "Invalid filter type specified");
      filter_type = PNG_FILTER_TYPE_BASE;
   }

#ifdef PNG_WRITE_INTERLACING_SUPPORTED
   if (interlace_type != PNG_INTERLACE_NONE &&
      interlace_type != PNG_INTERLACE_ADAM7)
   {
      png_warning(png_ptr, "Invalid interlace type specified");
      interlace_type = PNG_INTERLACE_ADAM7;
   }
#else
   interlace_type=PNG_INTERLACE_NONE;
#endif

   /* Save the relevent information */
   png_ptr->bit_depth = (png_byte)bit_depth;
   png_ptr->color_type = (png_byte)color_type;
   png_ptr->interlaced = (png_byte)interlace_type;
#ifdef PNG_MNG_FEATURES_SUPPORTED
   png_ptr->filter_type = (png_byte)filter_type;
#endif
   png_ptr->compression_type = (png_byte)compression_type;
   png_ptr->width = width;
   png_ptr->height = height;

   png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
   /* Set the usr info, so any transformations can modify it */
   png_ptr->usr_width = png_ptr->width;
   png_ptr->usr_bit_depth = png_ptr->bit_depth;
   png_ptr->usr_channels = png_ptr->channels;

   /* Pack the header information into the buffer */
   png_save_uint_32(buf, width);
   png_save_uint_32(buf + 4, height);
   buf[8] = (png_byte)bit_depth;
   buf[9] = (png_byte)color_type;
   buf[10] = (png_byte)compression_type;
   buf[11] = (png_byte)filter_type;
   buf[12] = (png_byte)interlace_type;

   /* Write the chunk */
   png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);

   /* Initialize zlib with PNG info */
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;
   if (!(png_ptr->do_filter))
   {
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
         png_ptr->bit_depth < 8)
         png_ptr->do_filter = PNG_FILTER_NONE;
      else
         png_ptr->do_filter = PNG_ALL_FILTERS;
   }
   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
   {
      if (png_ptr->do_filter != PNG_FILTER_NONE)
         png_ptr->zlib_strategy = Z_FILTERED;
      else
         png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
   }
   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
      png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
      png_ptr->zlib_mem_level = 8;
   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
      png_ptr->zlib_window_bits = 15;
   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
      png_ptr->zlib_method = 8;
   ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
         png_ptr->zlib_method, png_ptr->zlib_window_bits,
         png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
   if (ret != Z_OK)
   {
      if (ret == Z_VERSION_ERROR) png_error(png_ptr,
          "zlib failed to initialize compressor -- version error");
      if (ret == Z_STREAM_ERROR) png_error(png_ptr,
           "zlib failed to initialize compressor -- stream error");
      if (ret == Z_MEM_ERROR) png_error(png_ptr,
           "zlib failed to initialize compressor -- mem error");
      png_error(png_ptr, "zlib failed to initialize compressor");
   }
   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
   /* libpng is not interested in zstream.data_type */
   /* Set it to a predefined value, to avoid its evaluation inside zlib */
   png_ptr->zstream.data_type = Z_BINARY;

   png_ptr->mode = PNG_HAVE_IHDR;
}

// Assembly:
subq $0x68, %rsp
movl 0x78(%rsp), %eax
movl 0x70(%rsp), %eax
movq %rdi, 0x60(%rsp)
movl %esi, 0x5c(%rsp)
movl %edx, 0x58(%rsp)
movl %ecx, 0x54(%rsp)
movl %r8d, 0x50(%rsp)
movl %r9d, 0x4c(%rsp)
movb $0x0, 0x48(%rsp)
movl $0x52444849, 0x44(%rsp) # imm = 0x52444849
movl 0x50(%rsp), %eax
movq %rax, 0x28(%rsp)
subq $0x6, %rax
ja 0x12b374
movq 0x28(%rsp), %rax
leaq 0x1515d(%rip), %rcx     # 0x1403a0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl 0x54(%rsp), %eax
movl %eax, 0x24(%rsp)
decl %eax
subl $0x2, %eax
jb 0x12b27e
jmp 0x12b25d
movl 0x24(%rsp), %eax
subl $0x4, %eax
je 0x12b27e
jmp 0x12b268
movl 0x24(%rsp), %eax
subl $0x8, %eax
je 0x12b27e
jmp 0x12b273
movl 0x24(%rsp), %eax
subl $0x10, %eax
jne 0x12b28c
jmp 0x12b27e
movq 0x60(%rsp), %rax
movb $0x1, 0x252(%rax)
jmp 0x12b29d
movq 0x60(%rsp), %rdi
leaq 0x15270(%rip), %rsi     # 0x140508
callq 0x113860
jmp 0x12b385
cmpl $0x8, 0x54(%rsp)
je 0x12b2c1
cmpl $0x10, 0x54(%rsp)
je 0x12b2c1
movq 0x60(%rsp), %rdi
leaq 0x15272(%rip), %rsi     # 0x14052e
callq 0x113860
movq 0x60(%rsp), %rax
movb $0x3, 0x252(%rax)
jmp 0x12b385
movl 0x54(%rsp), %eax
movl %eax, 0x20(%rsp)
decl %eax
subl $0x2, %eax
jb 0x12b2f9
jmp 0x12b2e3
movl 0x20(%rsp), %eax
subl $0x4, %eax
je 0x12b2f9
jmp 0x12b2ee
movl 0x20(%rsp), %eax
subl $0x8, %eax
jne 0x12b307
jmp 0x12b2f9
movq 0x60(%rsp), %rax
movb $0x1, 0x252(%rax)
jmp 0x12b318
movq 0x60(%rsp), %rdi
leaq 0x1523b(%rip), %rsi     # 0x14054e
callq 0x113860
jmp 0x12b385
cmpl $0x8, 0x54(%rsp)
je 0x12b339
cmpl $0x10, 0x54(%rsp)
je 0x12b339
movq 0x60(%rsp), %rdi
leaq 0x1523f(%rip), %rsi     # 0x140573
callq 0x113860
movq 0x60(%rsp), %rax
movb $0x2, 0x252(%rax)
jmp 0x12b385
cmpl $0x8, 0x54(%rsp)
je 0x12b366
cmpl $0x10, 0x54(%rsp)
je 0x12b366
movq 0x60(%rsp), %rdi
leaq 0x1523e(%rip), %rsi     # 0x14059f
callq 0x113860
movq 0x60(%rsp), %rax
movb $0x4, 0x252(%rax)
jmp 0x12b385
movq 0x60(%rsp), %rdi
leaq 0x15240(%rip), %rsi     # 0x1405c0
callq 0x113860
cmpl $0x0, 0x4c(%rsp)
je 0x12b3a5
movq 0x60(%rsp), %rdi
leaq 0x1524b(%rip), %rsi     # 0x1405e3
callq 0x113940
movl $0x0, 0x4c(%rsp)
movq 0x60(%rsp), %rax
movl 0x408(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x12b3e2
movq 0x60(%rsp), %rax
movl 0x11c(%rax), %eax
andl $0x1000, %eax           # imm = 0x1000
cmpl $0x0, %eax
jne 0x12b3e2
cmpl $0x2, 0x50(%rsp)
je 0x12b3db
cmpl $0x6, 0x50(%rsp)
jne 0x12b3e2
cmpl $0x40, 0x70(%rsp)
je 0x12b402
cmpl $0x0, 0x70(%rsp)
je 0x12b402
movq 0x60(%rsp), %rdi
leaq 0x15211(%rip), %rsi     # 0x140606
callq 0x113940
movl $0x0, 0x70(%rsp)
cmpl $0x0, 0x78(%rsp)
je 0x12b429
cmpl $0x1, 0x78(%rsp)
je 0x12b429
movq 0x60(%rsp), %rdi
leaq 0x15208(%rip), %rsi     # 0x140624
callq 0x113940
movl $0x1, 0x78(%rsp)
movl 0x54(%rsp), %eax
movb %al, %cl
movq 0x60(%rsp), %rax
movb %cl, 0x24f(%rax)
movl 0x50(%rsp), %eax
movb %al, %cl
movq 0x60(%rsp), %rax
movb %cl, 0x24e(%rax)
movl 0x78(%rsp), %eax
movb %al, %cl
movq 0x60(%rsp), %rax
movb %cl, 0x24b(%rax)
movl 0x70(%rsp), %eax
movb %al, %cl
movq 0x60(%rsp), %rax
movb %cl, 0x410(%rax)
movl 0x4c(%rsp), %eax
movb %al, %cl
movq 0x60(%rsp), %rax
movb %cl, 0x450(%rax)
movl 0x5c(%rsp), %ecx
movq 0x60(%rsp), %rax
movl %ecx, 0x1bc(%rax)
movl 0x58(%rsp), %ecx
movq 0x60(%rsp), %rax
movl %ecx, 0x1c0(%rax)
movl 0x54(%rsp), %eax
movq 0x60(%rsp), %rcx
movzbl 0x252(%rcx), %ecx
imull %ecx, %eax
movb %al, %cl
movq 0x60(%rsp), %rax
movb %cl, 0x251(%rax)
movq 0x60(%rsp), %rax
movzbl 0x251(%rax), %eax
cmpl $0x8, %eax
jl 0x12b4ec
movl 0x5c(%rsp), %eax
movq 0x60(%rsp), %rcx
movzbl 0x251(%rcx), %ecx
shrq $0x3, %rcx
imulq %rcx, %rax
movq %rax, 0x18(%rsp)
jmp 0x12b50d
movl 0x5c(%rsp), %eax
movq 0x60(%rsp), %rcx
movzbl 0x251(%rcx), %ecx
imulq %rcx, %rax
addq $0x7, %rax
shrq $0x3, %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x1d0(%rax)
movq 0x60(%rsp), %rax
movl 0x1bc(%rax), %ecx
movq 0x60(%rsp), %rax
movl %ecx, 0x1c8(%rax)
movq 0x60(%rsp), %rax
movb 0x24f(%rax), %cl
movq 0x60(%rsp), %rax
movb %cl, 0x250(%rax)
movq 0x60(%rsp), %rax
movb 0x252(%rax), %cl
movq 0x60(%rsp), %rax
movb %cl, 0x253(%rax)
leaq 0x33(%rsp), %rdi
movl 0x5c(%rsp), %esi
callq 0x12aeb0
leaq 0x33(%rsp), %rdi
addq $0x4, %rdi
movl 0x58(%rsp), %esi
callq 0x12aeb0
movl 0x54(%rsp), %eax
movb %al, 0x3b(%rsp)
movl 0x50(%rsp), %eax
movb %al, 0x3c(%rsp)
movl 0x4c(%rsp), %eax
movb %al, 0x3d(%rsp)
movl 0x70(%rsp), %eax
movb %al, 0x3e(%rsp)
movl 0x78(%rsp), %eax
movb %al, 0x3f(%rsp)
movq 0x60(%rsp), %rdi
leaq 0x44(%rsp), %rsi
leaq 0x33(%rsp), %rdx
movl $0xd, %ecx
callq 0x12b040
movq 0x60(%rsp), %rax
leaq -0x2ff9d(%rip), %rcx    # 0xfb630
movq %rcx, 0x168(%rax)
movq 0x60(%rsp), %rax
leaq -0x2fed0(%rip), %rcx    # 0xfb710
movq %rcx, 0x170(%rax)
movq 0x60(%rsp), %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x178(%rax)
movq 0x60(%rsp), %rax
cmpb $0x0, 0x24d(%rax)
jne 0x12b644
movq 0x60(%rsp), %rax
movzbl 0x24e(%rax), %eax
cmpl $0x3, %eax
je 0x12b628
movq 0x60(%rsp), %rax
movzbl 0x24f(%rax), %eax
cmpl $0x8, %eax
jge 0x12b636
movq 0x60(%rsp), %rax
movb $0x8, 0x24d(%rax)
jmp 0x12b642
movq 0x60(%rsp), %rax
movb $-0x8, 0x24d(%rax)
jmp 0x12b644
movq 0x60(%rsp), %rax
movl 0x120(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x12b68a
movq 0x60(%rsp), %rax
movzbl 0x24d(%rax), %eax
cmpl $0x8, %eax
je 0x12b679
movq 0x60(%rsp), %rax
movl $0x1, 0x1b8(%rax)
jmp 0x12b688
movq 0x60(%rsp), %rax
movl $0x0, 0x1b8(%rax)
jmp 0x12b68a
movq 0x60(%rsp), %rax
movl 0x120(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x12b6ac
movq 0x60(%rsp), %rax
movl $0xffffffff, 0x1a8(%rax) # imm = 0xFFFFFFFF
movq 0x60(%rsp), %rax
movl 0x120(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
jne 0x12b6ce
movq 0x60(%rsp), %rax
movl $0x8, 0x1b4(%rax)
movq 0x60(%rsp), %rax
movl 0x120(%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
jne 0x12b6f0
movq 0x60(%rsp), %rax
movl $0xf, 0x1b0(%rax)
movq 0x60(%rsp), %rax
movl 0x120(%rax), %eax
andl $0x10, %eax
cmpl $0x0, %eax
jne 0x12b712
movq 0x60(%rsp), %rax
movl $0x8, 0x1ac(%rax)
movq 0x60(%rsp), %rdi
addq $0x128, %rdi            # imm = 0x128
movq 0x60(%rsp), %rax
movl 0x1a8(%rax), %esi
movq 0x60(%rsp), %rax
movl 0x1ac(%rax), %edx
movq 0x60(%rsp), %rax
movl 0x1b0(%rax), %ecx
movq 0x60(%rsp), %rax
movl 0x1b4(%rax), %r8d
movq 0x60(%rsp), %rax
movl 0x1b8(%rax), %r9d
leaq 0xd9e1(%rip), %rax      # 0x13913f
movq %rax, (%rsp)
movl $0x70, 0x8(%rsp)
callq 0x114ee0
movl %eax, 0x40(%rsp)
cmpl $0x0, 0x40(%rsp)
je 0x12b7d3
cmpl $-0x6, 0x40(%rsp)
jne 0x12b792
movq 0x60(%rsp), %rdi
leaq 0x14eb8(%rip), %rsi     # 0x140645
callq 0x113860
cmpl $-0x2, 0x40(%rsp)
jne 0x12b7aa
movq 0x60(%rsp), %rdi
leaq 0x14ed6(%rip), %rsi     # 0x14067b
callq 0x113860
cmpl $-0x4, 0x40(%rsp)
jne 0x12b7c2
movq 0x60(%rsp), %rdi
leaq 0x14ef3(%rip), %rsi     # 0x1406b0
callq 0x113860
movq 0x60(%rsp), %rdi
leaq 0x14f14(%rip), %rsi     # 0x1406e2
callq 0x113860
movq 0x60(%rsp), %rax
movq 0x198(%rax), %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x140(%rax)
movq 0x60(%rsp), %rax
movq 0x1a0(%rax), %rax
movl %eax, %ecx
movq 0x60(%rsp), %rax
movl %ecx, 0x148(%rax)
movq 0x60(%rsp), %rax
movl $0x0, 0x180(%rax)
movq 0x60(%rsp), %rax
movl $0x1, 0x11c(%rax)
addq $0x68, %rsp
retq
nopw (%rax,%rax)