// File: tomfunkhouser[P]gaps/pkgs/png/pngrutil.c
// Function: png_decompress_chunk
void /* PRIVATE */
png_decompress_chunk(png_structp png_ptr, int comp_type,
    png_size_t chunklength,
    png_size_t prefix_size, png_size_t *newlength)
{
   /* The caller should guarantee this */
   if (prefix_size > chunklength)
   {
      /* The recovery is to delete the chunk. */
      png_warning(png_ptr, "invalid chunklength");
      prefix_size = 0; /* To delete everything */
   }

   else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
   {
      png_size_t expanded_size = png_inflate(png_ptr,
                (png_bytep)(png_ptr->chunkdata + prefix_size),
                chunklength - prefix_size,
                0/*output*/, 0/*output size*/);

      /* Now check the limits on this chunk - if the limit fails the
       * compressed data will be removed, the prefix will remain.
       */
#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
      if (png_ptr->user_chunk_malloc_max &&
          (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
#else
#  ifdef PNG_USER_CHUNK_MALLOC_MAX
      if ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
          prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
#  endif
#endif
         png_warning(png_ptr, "Exceeded size limit while expanding chunk");

      /* If the size is zero either there was an error and a message
       * has already been output (warning) or the size really is zero
       * and we have nothing to do - the code will exit through the
       * error case below.
       */
#if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \
    defined(PNG_USER_CHUNK_MALLOC_MAX)
      else
#endif
      if (expanded_size > 0)
      {
         /* Success (maybe) - really uncompress the chunk. */
         png_size_t new_size = 0;
         png_charp text = png_malloc_warn(png_ptr,
                        prefix_size + expanded_size + 1);

         if (text != NULL)
         {
            png_memcpy(text, png_ptr->chunkdata, prefix_size);
            new_size = png_inflate(png_ptr,
                (png_bytep)(png_ptr->chunkdata + prefix_size),
                chunklength - prefix_size,
                (png_bytep)(text + prefix_size), expanded_size);
            text[prefix_size + expanded_size] = 0; /* just in case */

            if (new_size == expanded_size)
            {
               png_free(png_ptr, png_ptr->chunkdata);
               png_ptr->chunkdata = text;
               *newlength = prefix_size + expanded_size;
               return; /* The success return! */
            }

            png_warning(png_ptr, "png_inflate logic error");
            png_free(png_ptr, text);
         }
         else
          png_warning(png_ptr, "Not enough memory to decompress chunk");
      }
   }

   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
   {
#ifdef PNG_STDIO_SUPPORTED
      char umsg[50];

      png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d",
          comp_type);
      png_warning(png_ptr, umsg);
#else
      png_warning(png_ptr, "Unknown zTXt compression type");
#endif

      /* The recovery is to simply drop the data. */
   }

   /* Generic error return - leave the prefix, delete the compressed
    * data, reallocate the chunkdata to remove the potentially large
    * amount of compressed data.
    */
   {
      png_charp text = png_malloc_warn(png_ptr, prefix_size + 1);
      if (text != NULL)
      {
         if (prefix_size > 0)
            png_memcpy(text, png_ptr->chunkdata, prefix_size);
         png_free(png_ptr, png_ptr->chunkdata);
         png_ptr->chunkdata = text;

         /* This is an extra zero in the 'uncompressed' part. */
         *(png_ptr->chunkdata + prefix_size) = 0x00;
      }
      /* Ignore a malloc error here - it is safe. */
   }

   *newlength = prefix_size;
}

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x80(%rsp)
movl %esi, 0x7c(%rsp)
movq %rdx, 0x70(%rsp)
movq %rcx, 0x68(%rsp)
movq %r8, 0x60(%rsp)
movq 0x68(%rsp), %rax
cmpq 0x70(%rsp), %rax
jbe 0x122e10
movq 0x80(%rsp), %rdi
leaq 0x1c385(%rip), %rsi     # 0x13f182
callq 0x113940
movq $0x0, 0x68(%rsp)
jmp 0x123016
cmpl $0x0, 0x7c(%rsp)
jne 0x122fe6
movq 0x80(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rsi
addq 0x68(%rsp), %rsi
movq 0x70(%rsp), %rdx
subq 0x68(%rsp), %rdx
xorl %eax, %eax
movl %eax, %r8d
movq %r8, %rcx
callq 0x1230c0
movq %rax, 0x58(%rsp)
movq 0x80(%rsp), %rax
cmpq $0x0, 0x1d8(%rax)
je 0x122ea0
movq 0x68(%rsp), %rax
addq 0x58(%rsp), %rax
movq 0x80(%rsp), %rcx
movq 0x1d8(%rcx), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jb 0x122ea0
movq 0x80(%rsp), %rdi
leaq 0x1c300(%rip), %rsi     # 0x13f196
callq 0x113940
jmp 0x122fe4
cmpq $0x0, 0x58(%rsp)
jbe 0x122fe2
movq $0x0, 0x50(%rsp)
movq 0x80(%rsp), %rdi
movq 0x68(%rsp), %rsi
addq 0x58(%rsp), %rsi
addq $0x1, %rsi
callq 0x113760
movq %rax, 0x48(%rsp)
cmpq $0x0, 0x48(%rsp)
je 0x122fcc
movq 0x48(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rsi
movq 0x68(%rsp), %rdx
callq 0xf3d0
movq 0x80(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rsi
addq 0x68(%rsp), %rsi
movq 0x70(%rsp), %rdx
subq 0x68(%rsp), %rdx
movq 0x48(%rsp), %rcx
addq 0x68(%rsp), %rcx
movq 0x58(%rsp), %r8
callq 0x1230c0
movq %rax, 0x50(%rsp)
movq 0x48(%rsp), %rax
movq 0x68(%rsp), %rcx
addq 0x58(%rsp), %rcx
movb $0x0, (%rax,%rcx)
movq 0x50(%rsp), %rax
cmpq 0x58(%rsp), %rax
jne 0x122fa4
movq 0x80(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x48(%rsp), %rcx
movq 0x80(%rsp), %rax
movq %rcx, 0x488(%rax)
movq 0x68(%rsp), %rcx
addq 0x58(%rsp), %rcx
movq 0x60(%rsp), %rax
movq %rcx, (%rax)
jmp 0x1230b4
movq 0x80(%rsp), %rdi
leaq 0x1c20d(%rip), %rsi     # 0x13f1c0
callq 0x113940
movq 0x80(%rsp), %rdi
movq 0x48(%rsp), %rsi
callq 0x1136d0
jmp 0x122fe0
movq 0x80(%rsp), %rdi
leaq 0x1c1fd(%rip), %rsi     # 0x13f1d8
callq 0x113940
jmp 0x122fe2
jmp 0x122fe4
jmp 0x123014
leaq 0x10(%rsp), %rdi
movl 0x7c(%rsp), %ecx
movl $0x32, %esi
leaq 0x1c203(%rip), %rdx     # 0x13f1fe
movb $0x0, %al
callq 0xf800
movq 0x80(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x113940
jmp 0x123016
movq 0x80(%rsp), %rdi
movq 0x68(%rsp), %rsi
addq $0x1, %rsi
callq 0x113760
movq %rax, 0x8(%rsp)
cmpq $0x0, 0x8(%rsp)
je 0x1230a7
cmpq $0x0, 0x68(%rsp)
jbe 0x12305f
movq 0x8(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rsi
movq 0x68(%rsp), %rdx
callq 0xf3d0
movq 0x80(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x8(%rsp), %rcx
movq 0x80(%rsp), %rax
movq %rcx, 0x488(%rax)
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rax
movq 0x68(%rsp), %rcx
movb $0x0, (%rax,%rcx)
movq 0x68(%rsp), %rcx
movq 0x60(%rsp), %rax
movq %rcx, (%rax)
addq $0x88, %rsp
retq
nopl (%rax)