// File: tomfunkhouser[P]gaps/pkgs/png/pngrutil.c
// Function: png_handle_iCCP
void /* PRIVATE */
png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* Note: this does not properly handle chunks that are > 64K under DOS */
{
   png_byte compression_type;
   png_bytep pC;
   png_charp profile;
   png_uint_32 skip = 0;
   png_uint_32 profile_size, profile_length;
   png_size_t slength, prefix_length, data_length;

   png_debug(1, "in png_handle_iCCP");

   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before iCCP");
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid iCCP after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
   else if (png_ptr->mode & PNG_HAVE_PLTE)
      /* Should be an error, but we can cope with it */
      png_warning(png_ptr, "Out of place iCCP chunk");

   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
   {
      png_warning(png_ptr, "Duplicate iCCP chunk");
      png_crc_finish(png_ptr, length);
      return;
   }

#ifdef PNG_MAX_MALLOC_64K
   if (length > (png_uint_32)65535L)
   {
      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
      skip = length - (png_uint_32)65535L;
      length = (png_uint_32)65535L;
   }
#endif

   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
   slength = (png_size_t)length;
   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);

   if (png_crc_finish(png_ptr, skip))
   {
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      return;
   }

   png_ptr->chunkdata[slength] = 0x00;

   for (profile = png_ptr->chunkdata; *profile; profile++)
      /* Empty loop to find end of name */ ;

   ++profile;

   /* There should be at least one zero (the compression type byte)
    * following the separator, and we should be on it
    */
   if ( profile >= png_ptr->chunkdata + slength - 1)
   {
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      png_warning(png_ptr, "Malformed iCCP chunk");
      return;
   }

   /* Compression_type should always be zero */
   compression_type = *profile++;
   if (compression_type)
   {
      png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
      compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
                                 wrote nonzero) */
   }

   prefix_length = profile - png_ptr->chunkdata;
   png_decompress_chunk(png_ptr, compression_type,
     slength, prefix_length, &data_length);

   profile_length = data_length - prefix_length;

   if ( prefix_length > data_length || profile_length < 4)
   {
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      png_warning(png_ptr, "Profile size field missing from iCCP chunk");
      return;
   }

   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
   pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
   profile_size = ((*(pC    ))<<24) |
                  ((*(pC + 1))<<16) |
                  ((*(pC + 2))<< 8) |
                  ((*(pC + 3))    );

   if (profile_size < profile_length)
      profile_length = profile_size;

   if (profile_size > profile_length)
   {
#ifdef PNG_STDIO_SUPPORTED
         char umsg[50];
#endif
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      png_warning(png_ptr, "Ignoring truncated iCCP profile");
#ifdef PNG_STDIO_SUPPORTED

      png_snprintf(umsg, 50, "declared profile size = %lu",
          (unsigned long)profile_size);
      png_warning(png_ptr, umsg);
      png_snprintf(umsg, 50, "actual profile length = %lu",
          (unsigned long)profile_length);
      png_warning(png_ptr, umsg);
#endif
      return;
   }

   png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
     compression_type, png_ptr->chunkdata + prefix_length, profile_length);
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = NULL;
}

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x80(%rsp)
movq %rsi, 0x78(%rsp)
movl %edx, 0x74(%rsp)
movl $0x0, 0x5c(%rsp)
movq 0x80(%rsp), %rax
movl 0x11c(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x12475c
movq 0x80(%rsp), %rdi
leaq 0x1aee7(%rip), %rsi     # 0x13f63c
callq 0x113860
jmp 0x1247ca
movq 0x80(%rsp), %rax
movl 0x11c(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x12479c
movq 0x80(%rsp), %rdi
leaq 0x1aed4(%rip), %rsi     # 0x13f655
callq 0x113940
movq 0x80(%rsp), %rdi
movl 0x74(%rsp), %esi
callq 0x122b90
jmp 0x124bdf
movq 0x80(%rsp), %rax
movl 0x11c(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x1247c6
movq 0x80(%rsp), %rdi
leaq 0x1aeac(%rip), %rsi     # 0x13f66d
callq 0x113940
jmp 0x1247c8
jmp 0x1247ca
cmpq $0x0, 0x78(%rsp)
je 0x12480e
movq 0x78(%rsp), %rax
movl 0x8(%rax), %eax
andl $0x1000, %eax           # imm = 0x1000
cmpl $0x0, %eax
je 0x12480e
movq 0x80(%rsp), %rdi
leaq 0x1ae92(%rip), %rsi     # 0x13f685
callq 0x113940
movq 0x80(%rsp), %rdi
movl 0x74(%rsp), %esi
callq 0x122b90
jmp 0x124bdf
movq 0x80(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x80(%rsp), %rdi
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
callq 0x1135b0
movq %rax, %rcx
movq 0x80(%rsp), %rax
movq %rcx, 0x488(%rax)
movl 0x74(%rsp), %eax
movq %rax, 0x48(%rsp)
movq 0x80(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rsi
movq 0x48(%rsp), %rdx
callq 0x122b40
movq 0x80(%rsp), %rdi
movl 0x5c(%rsp), %esi
callq 0x122b90
cmpl $0x0, %eax
je 0x1248c8
movq 0x80(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x80(%rsp), %rax
movq $0x0, 0x488(%rax)
jmp 0x124bdf
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rax
movq 0x48(%rsp), %rcx
movb $0x0, (%rax,%rcx)
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
cmpb $0x0, (%rax)
je 0x124910
jmp 0x124900
movq 0x60(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x60(%rsp)
jmp 0x1248f4
movq 0x60(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
movq 0x80(%rsp), %rcx
movq 0x488(%rcx), %rcx
addq 0x48(%rsp), %rcx
addq $-0x1, %rcx
cmpq %rcx, %rax
jb 0x124988
movq 0x80(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x80(%rsp), %rax
movq $0x0, 0x488(%rax)
movq 0x80(%rsp), %rdi
leaq 0x1ad1c(%rip), %rsi     # 0x13f69a
callq 0x113940
jmp 0x124bdf
movq 0x60(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x60(%rsp)
movb (%rax), %al
movb %al, 0x73(%rsp)
cmpb $0x0, 0x73(%rsp)
je 0x1249bf
movq 0x80(%rsp), %rdi
leaq 0x1acfa(%rip), %rsi     # 0x13f6af
callq 0x113940
movb $0x0, 0x73(%rsp)
movq 0x60(%rsp), %rax
movq 0x80(%rsp), %rcx
movq 0x488(%rcx), %rcx
subq %rcx, %rax
movq %rax, 0x40(%rsp)
movq 0x80(%rsp), %rdi
movzbl 0x73(%rsp), %esi
movq 0x48(%rsp), %rdx
movq 0x40(%rsp), %rcx
leaq 0x38(%rsp), %r8
callq 0x122dc0
movq 0x38(%rsp), %rax
subq 0x40(%rsp), %rax
movl %eax, 0x54(%rsp)
movq 0x40(%rsp), %rax
cmpq 0x38(%rsp), %rax
ja 0x124a1d
cmpl $0x4, 0x54(%rsp)
jae 0x124a65
movq 0x80(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x80(%rsp), %rax
movq $0x0, 0x488(%rax)
movq 0x80(%rsp), %rdi
leaq 0x1ac84(%rip), %rsi     # 0x13f6df
callq 0x113940
jmp 0x124bdf
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rax
addq 0x40(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rax
movzbl (%rax), %eax
shll $0x18, %eax
movq 0x68(%rsp), %rcx
movzbl 0x1(%rcx), %ecx
shll $0x10, %ecx
orl %ecx, %eax
movq 0x68(%rsp), %rcx
movzbl 0x2(%rcx), %ecx
shll $0x8, %ecx
orl %ecx, %eax
movq 0x68(%rsp), %rcx
movzbl 0x3(%rcx), %ecx
orl %ecx, %eax
movl %eax, 0x58(%rsp)
movl 0x58(%rsp), %eax
cmpl 0x54(%rsp), %eax
jae 0x124ac6
movl 0x58(%rsp), %eax
movl %eax, 0x54(%rsp)
movl 0x58(%rsp), %eax
cmpl 0x54(%rsp), %eax
jbe 0x124b71
movq 0x80(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x80(%rsp), %rax
movq $0x0, 0x488(%rax)
movq 0x80(%rsp), %rdi
leaq 0x1abf8(%rip), %rsi     # 0x13f70a
callq 0x113940
movq %rsp, %rdi
movl 0x58(%rsp), %eax
movl %eax, %ecx
movl $0x32, %esi
leaq 0x1abfe(%rip), %rdx     # 0x13f72a
movb $0x0, %al
callq 0xf800
movq 0x80(%rsp), %rdi
movq %rsp, %rsi
callq 0x113940
movq %rsp, %rdi
movl 0x54(%rsp), %eax
movl %eax, %ecx
movl $0x32, %esi
leaq 0x1abee(%rip), %rdx     # 0x13f746
movb $0x0, %al
callq 0xf800
movq 0x80(%rsp), %rdi
movq %rsp, %rsi
callq 0x113940
jmp 0x124bdf
movq 0x80(%rsp), %rdi
movq 0x78(%rsp), %rsi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rdx
movzbl 0x73(%rsp), %ecx
movq 0x80(%rsp), %rax
movq 0x488(%rax), %r8
addq 0x40(%rsp), %r8
movl 0x54(%rsp), %r9d
callq 0xfdd30
movq 0x80(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x80(%rsp), %rax
movq $0x0, 0x488(%rax)
addq $0x88, %rsp
retq
nopw (%rax,%rax)