// File: tomfunkhouser[P]gaps/pkgs/png/pngrutil.c
// Function: png_inflate
static png_size_t
png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size,
        png_bytep output, png_size_t output_size)
{
   png_size_t count = 0;

   png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */
   png_ptr->zstream.avail_in = size;

   while (1)
   {
      int ret, avail;

      /* Reset the output buffer each time round - we empty it
       * after every inflate call.
       */
      png_ptr->zstream.next_out = png_ptr->zbuf;
      png_ptr->zstream.avail_out = png_ptr->zbuf_size;

      ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
      avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;

      /* First copy/count any new output - but only if we didn't
       * get an error code.
       */
      if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
      {
         if (output != 0 && output_size > count)
         {
            int copy = output_size - count;
            if (avail < copy) copy = avail;
            png_memcpy(output + count, png_ptr->zbuf, copy);
         }
         count += avail;
      }

      if (ret == Z_OK)
         continue;

      /* Termination conditions - always reset the zstream, it
       * must be left in inflateInit state.
       */
      png_ptr->zstream.avail_in = 0;
      inflateReset(&png_ptr->zstream);

      if (ret == Z_STREAM_END)
         return count; /* NOTE: may be zero. */

      /* Now handle the error codes - the API always returns 0
       * and the error message is dumped into the uncompressed
       * buffer if available.
       */
      {
         PNG_CONST char *msg;
         if (png_ptr->zstream.msg != 0)
            msg = png_ptr->zstream.msg;
         else
         {
#ifdef PNG_STDIO_SUPPORTED
            static char umsg[52];

            switch (ret)
            {
               case Z_BUF_ERROR:
                  msg = "Buffer error in compressed datastream in %s chunk";
                  break;
               case Z_DATA_ERROR:
                  msg = "Data error in compressed datastream in %s chunk";
                  break;
               default:
                  msg = "Incomplete compressed datastream in %s chunk";
                  break;
            }

            png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name);
            msg = umsg;
#else
            msg = "Damaged compressed datastream in chunk other than IDAT";
#endif
         }

         png_warning(png_ptr, msg);
      }

      /* 0 means an error - notice that this code simple ignores
       * zero length compressed chunks as a result.
       */
      return 0;
   }
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x48(%rsp)
movq %rsi, 0x40(%rsp)
movq %rdx, 0x38(%rsp)
movq %rcx, 0x30(%rsp)
movq %r8, 0x28(%rsp)
movq $0x0, 0x20(%rsp)
movq 0x40(%rsp), %rcx
movq 0x48(%rsp), %rax
movq %rcx, 0x128(%rax)
movq 0x38(%rsp), %rax
movl %eax, %ecx
movq 0x48(%rsp), %rax
movl %ecx, 0x130(%rax)
movq 0x48(%rsp), %rax
movq 0x198(%rax), %rcx
movq 0x48(%rsp), %rax
movq %rcx, 0x140(%rax)
movq 0x48(%rsp), %rax
movq 0x1a0(%rax), %rax
movl %eax, %ecx
movq 0x48(%rsp), %rax
movl %ecx, 0x148(%rax)
movq 0x48(%rsp), %rdi
addq $0x128, %rdi            # imm = 0x128
xorl %esi, %esi
callq 0x11a290
movl %eax, 0x1c(%rsp)
movq 0x48(%rsp), %rax
movq 0x1a0(%rax), %rax
movq 0x48(%rsp), %rcx
movl 0x148(%rcx), %ecx
subq %rcx, %rax
movl %eax, 0x18(%rsp)
cmpl $0x0, 0x1c(%rsp)
je 0x12317d
cmpl $0x1, 0x1c(%rsp)
jne 0x1231e7
cmpl $0x0, 0x18(%rsp)
jle 0x1231e7
cmpq $0x0, 0x30(%rsp)
je 0x1231d8
movq 0x28(%rsp), %rax
cmpq 0x20(%rsp), %rax
jbe 0x1231d8
movq 0x28(%rsp), %rax
subq 0x20(%rsp), %rax
movl %eax, 0x14(%rsp)
movl 0x18(%rsp), %eax
cmpl 0x14(%rsp), %eax
jge 0x1231b8
movl 0x18(%rsp), %eax
movl %eax, 0x14(%rsp)
movq 0x30(%rsp), %rdi
addq 0x20(%rsp), %rdi
movq 0x48(%rsp), %rax
movq 0x198(%rax), %rsi
movslq 0x14(%rsp), %rdx
callq 0xf3d0
movslq 0x18(%rsp), %rax
addq 0x20(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpl $0x0, 0x1c(%rsp)
jne 0x1231f3
jmp 0x123109
movq 0x48(%rsp), %rax
movl $0x0, 0x130(%rax)
movq 0x48(%rsp), %rdi
addq $0x128, %rdi            # imm = 0x128
callq 0x119dc0
cmpl $0x1, 0x1c(%rsp)
jne 0x123229
movq 0x20(%rsp), %rax
movq %rax, 0x50(%rsp)
jmp 0x1232d5
movq 0x48(%rsp), %rax
cmpq $0x0, 0x158(%rax)
je 0x12324b
movq 0x48(%rsp), %rax
movq 0x158(%rax), %rax
movq %rax, 0x8(%rsp)
jmp 0x1232bd
movl 0x1c(%rsp), %eax
movl %eax, 0x4(%rsp)
subl $-0x5, %eax
je 0x123265
jmp 0x12325a
movl 0x4(%rsp), %eax
subl $-0x3, %eax
je 0x123273
jmp 0x123281
leaq 0x1cd9e(%rip), %rax     # 0x14000a
movq %rax, 0x8(%rsp)
jmp 0x12328d
leaq 0x1cdc2(%rip), %rax     # 0x14003c
movq %rax, 0x8(%rsp)
jmp 0x12328d
leaq 0x1cde4(%rip), %rax     # 0x14006c
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rdx
movq 0x48(%rsp), %rcx
addq $0x244, %rcx            # imm = 0x244
leaq 0x45823b(%rip), %rdi    # 0x57b4e0
movl $0x34, %esi
movb $0x0, %al
callq 0xf800
leaq 0x458228(%rip), %rax    # 0x57b4e0
movq %rax, 0x8(%rsp)
movq 0x48(%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x113940
movq $0x0, 0x50(%rsp)
movq 0x50(%rsp), %rax
addq $0x58, %rsp
retq
nop