// File: tomfunkhouser[P]gaps/pkgs/png/pngrutil.c
// Function: png_handle_pCAL
void /* PRIVATE */
png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
   png_int_32 X0, X1;
   png_byte type, nparams;
   png_charp buf, units, endptr;
   png_charpp params;
   png_size_t slength;
   int i;

   png_debug(1, "in png_handle_pCAL");

   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before pCAL");
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid pCAL after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
   {
      png_warning(png_ptr, "Duplicate pCAL chunk");
      png_crc_finish(png_ptr, length);
      return;
   }

   png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
      length + 1);
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
   if (png_ptr->chunkdata == NULL)
     {
       png_warning(png_ptr, "No memory for pCAL purpose");
       return;
     }
   slength = (png_size_t)length;
   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);

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

   png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */

   png_debug(3, "Finding end of pCAL purpose string");
   for (buf = png_ptr->chunkdata; *buf; buf++)
      /* Empty loop */ ;

   endptr = png_ptr->chunkdata + slength;

   /* We need to have at least 12 bytes after the purpose string
      in order to get the parameter information. */
   if (endptr <= buf + 12)
   {
      png_warning(png_ptr, "Invalid pCAL data");
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      return;
   }

   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
   X0 = png_get_int_32((png_bytep)buf+1);
   X1 = png_get_int_32((png_bytep)buf+5);
   type = buf[9];
   nparams = buf[10];
   units = buf + 11;

   png_debug(3, "Checking pCAL equation type and number of parameters");
   /* Check that we have the right number of parameters for known
      equation types. */
   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
   {
      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      return;
   }
   else if (type >= PNG_EQUATION_LAST)
   {
      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
   }

   for (buf = units; *buf; buf++)
      /* Empty loop to move past the units string. */ ;

   png_debug(3, "Allocating pCAL parameters array");
   params = (png_charpp)png_malloc_warn(png_ptr,
      (png_size_t)(nparams * png_sizeof(png_charp)));
   if (params == NULL)
     {
       png_free(png_ptr, png_ptr->chunkdata);
       png_ptr->chunkdata = NULL;
       png_warning(png_ptr, "No memory for pCAL params");
       return;
     }

   /* Get pointers to the start of each parameter string. */
   for (i = 0; i < (int)nparams; i++)
   {
      buf++; /* Skip the null string terminator from previous parameter. */

      png_debug1(3, "Reading pCAL parameter %d", i);
      for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
         /* Empty loop to move past each parameter string */ ;

      /* Make sure we haven't run out of data yet */
      if (buf > endptr)
      {
         png_warning(png_ptr, "Invalid pCAL data");
         png_free(png_ptr, png_ptr->chunkdata);
         png_ptr->chunkdata = NULL;
         png_free(png_ptr, params);
         return;
      }
   }

   png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
      units, params);

   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = NULL;
   png_free(png_ptr, params);
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movl %edx, 0x64(%rsp)
movq 0x70(%rsp), %rax
movl 0x11c(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x125ea8
movq 0x70(%rsp), %rdi
leaq 0x19c11(%rip), %rsi     # 0x13fab2
callq 0x113860
jmp 0x125f21
movq 0x70(%rsp), %rax
movl 0x11c(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x125edf
movq 0x70(%rsp), %rdi
leaq 0x19c04(%rip), %rsi     # 0x13facb
callq 0x113940
movq 0x70(%rsp), %rdi
movl 0x64(%rsp), %esi
callq 0x122b90
jmp 0x126464
cmpq $0x0, 0x68(%rsp)
je 0x125f1d
movq 0x68(%rsp), %rax
movl 0x8(%rax), %eax
andl $0x400, %eax            # imm = 0x400
cmpl $0x0, %eax
je 0x125f1d
movq 0x70(%rsp), %rdi
leaq 0x19bde(%rip), %rsi     # 0x13fae3
callq 0x113940
movq 0x70(%rsp), %rdi
movl 0x64(%rsp), %esi
callq 0x122b90
jmp 0x126464
jmp 0x125f1f
jmp 0x125f21
movq 0x70(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x70(%rsp), %rdi
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
callq 0x113760
movq %rax, %rcx
movq 0x70(%rsp), %rax
movq %rcx, 0x488(%rax)
movq 0x70(%rsp), %rax
cmpq $0x0, 0x488(%rax)
jne 0x125f80
movq 0x70(%rsp), %rdi
leaq 0x19b82(%rip), %rsi     # 0x13faf8
callq 0x113940
jmp 0x126464
movl 0x64(%rsp), %eax
movq %rax, 0x30(%rsp)
movq 0x70(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x488(%rax), %rsi
movq 0x30(%rsp), %rdx
callq 0x122b40
movq 0x70(%rsp), %rdi
xorl %esi, %esi
callq 0x122b90
cmpl $0x0, %eax
je 0x125fe0
movq 0x70(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x70(%rsp), %rax
movq $0x0, 0x488(%rax)
jmp 0x126464
movq 0x70(%rsp), %rax
movq 0x488(%rax), %rax
movq 0x30(%rsp), %rcx
movb $0x0, (%rax,%rcx)
movq 0x70(%rsp), %rax
movq 0x488(%rax), %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rax
cmpb $0x0, (%rax)
je 0x126022
jmp 0x126012
movq 0x50(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x50(%rsp)
jmp 0x126006
movq 0x70(%rsp), %rax
movq 0x488(%rax), %rax
addq 0x30(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rax
movq 0x50(%rsp), %rcx
addq $0xc, %rcx
cmpq %rcx, %rax
ja 0x126087
movq 0x70(%rsp), %rdi
leaq 0x19abc(%rip), %rsi     # 0x13fb13
callq 0x113940
movq 0x70(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x70(%rsp), %rax
movq $0x0, 0x488(%rax)
jmp 0x126464
movq 0x50(%rsp), %rax
movzbl 0x1(%rax), %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0x1260dd
movq 0x50(%rsp), %rax
movzbl 0x1(%rax), %ecx
shll $0x18, %ecx
movq 0x50(%rsp), %rax
movzbl 0x2(%rax), %eax
shll $0x10, %eax
addl %eax, %ecx
movq 0x50(%rsp), %rax
movzbl 0x3(%rax), %eax
shll $0x8, %eax
addl %eax, %ecx
movq 0x50(%rsp), %rax
movzbl 0x4(%rax), %eax
addl %eax, %ecx
xorl $-0x1, %ecx
addl $0x1, %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, 0x28(%rsp)
jmp 0x126114
movq 0x50(%rsp), %rax
movzbl 0x1(%rax), %eax
shll $0x18, %eax
movq 0x50(%rsp), %rcx
movzbl 0x2(%rcx), %ecx
shll $0x10, %ecx
addl %ecx, %eax
movq 0x50(%rsp), %rcx
movzbl 0x3(%rcx), %ecx
shll $0x8, %ecx
addl %ecx, %eax
movq 0x50(%rsp), %rcx
movzbl 0x4(%rcx), %ecx
addl %ecx, %eax
movl %eax, 0x28(%rsp)
movl 0x28(%rsp), %eax
movl %eax, 0x60(%rsp)
movq 0x50(%rsp), %rax
movzbl 0x5(%rax), %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0x126172
movq 0x50(%rsp), %rax
movzbl 0x5(%rax), %ecx
shll $0x18, %ecx
movq 0x50(%rsp), %rax
movzbl 0x6(%rax), %eax
shll $0x10, %eax
addl %eax, %ecx
movq 0x50(%rsp), %rax
movzbl 0x7(%rax), %eax
shll $0x8, %eax
addl %eax, %ecx
movq 0x50(%rsp), %rax
movzbl 0x8(%rax), %eax
addl %eax, %ecx
xorl $-0x1, %ecx
addl $0x1, %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, 0x24(%rsp)
jmp 0x1261a9
movq 0x50(%rsp), %rax
movzbl 0x5(%rax), %eax
shll $0x18, %eax
movq 0x50(%rsp), %rcx
movzbl 0x6(%rcx), %ecx
shll $0x10, %ecx
addl %ecx, %eax
movq 0x50(%rsp), %rcx
movzbl 0x7(%rcx), %ecx
shll $0x8, %ecx
addl %ecx, %eax
movq 0x50(%rsp), %rcx
movzbl 0x8(%rcx), %ecx
addl %ecx, %eax
movl %eax, 0x24(%rsp)
movl 0x24(%rsp), %eax
movl %eax, 0x5c(%rsp)
movq 0x50(%rsp), %rax
movb 0x9(%rax), %al
movb %al, 0x5b(%rsp)
movq 0x50(%rsp), %rax
movb 0xa(%rax), %al
movb %al, 0x5a(%rsp)
movq 0x50(%rsp), %rax
addq $0xb, %rax
movq %rax, 0x48(%rsp)
movzbl 0x5b(%rsp), %eax
cmpl $0x0, %eax
jne 0x1261eb
movzbl 0x5a(%rsp), %eax
cmpl $0x2, %eax
jne 0x126227
movzbl 0x5b(%rsp), %eax
cmpl $0x1, %eax
jne 0x1261ff
movzbl 0x5a(%rsp), %eax
cmpl $0x3, %eax
jne 0x126227
movzbl 0x5b(%rsp), %eax
cmpl $0x2, %eax
jne 0x126213
movzbl 0x5a(%rsp), %eax
cmpl $0x3, %eax
jne 0x126227
movzbl 0x5b(%rsp), %eax
cmpl $0x3, %eax
jne 0x126263
movzbl 0x5a(%rsp), %eax
cmpl $0x4, %eax
je 0x126263
movq 0x70(%rsp), %rdi
leaq 0x198f2(%rip), %rsi     # 0x13fb25
callq 0x113940
movq 0x70(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x70(%rsp), %rax
movq $0x0, 0x488(%rax)
jmp 0x126464
movzbl 0x5b(%rsp), %eax
cmpl $0x4, %eax
jl 0x12627e
movq 0x70(%rsp), %rdi
leaq 0x198d6(%rip), %rsi     # 0x13fb4f
callq 0x113940
jmp 0x126280
movq 0x48(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rax
cmpb $0x0, (%rax)
je 0x1262a6
jmp 0x126296
movq 0x50(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x50(%rsp)
jmp 0x12628a
movq 0x70(%rsp), %rdi
movzbl 0x5a(%rsp), %eax
movl %eax, %esi
shlq $0x3, %rsi
callq 0x113760
movq %rax, 0x38(%rsp)
cmpq $0x0, 0x38(%rsp)
jne 0x126304
movq 0x70(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x70(%rsp), %rax
movq $0x0, 0x488(%rax)
movq 0x70(%rsp), %rdi
leaq 0x1987f(%rip), %rsi     # 0x13fb79
callq 0x113940
jmp 0x126464
movl $0x0, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
movzbl 0x5a(%rsp), %ecx
cmpl %ecx, %eax
jge 0x1263e7
movq 0x50(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rdx
movq 0x38(%rsp), %rax
movslq 0x2c(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movq 0x50(%rsp), %rcx
xorl %eax, %eax
cmpq 0x40(%rsp), %rcx
movb %al, 0x23(%rsp)
ja 0x126362
movq 0x50(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
setne %al
movb %al, 0x23(%rsp)
movb 0x23(%rsp), %al
testb $0x1, %al
jne 0x12636c
jmp 0x12637e
jmp 0x12636e
movq 0x50(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x50(%rsp)
jmp 0x12633e
movq 0x50(%rsp), %rax
cmpq 0x40(%rsp), %rax
jbe 0x1263d5
movq 0x70(%rsp), %rdi
leaq 0x1977d(%rip), %rsi     # 0x13fb13
callq 0x113940
movq 0x70(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x70(%rsp), %rax
movq $0x0, 0x488(%rax)
movq 0x70(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x1136d0
jmp 0x126464
jmp 0x1263d7
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x12630c
movq 0x70(%rsp), %rdi
movq 0x68(%rsp), %rsi
movq 0x70(%rsp), %rax
movq 0x488(%rax), %rdx
movl 0x60(%rsp), %ecx
movl 0x5c(%rsp), %r8d
movzbl 0x5b(%rsp), %r9d
movzbl 0x5a(%rsp), %r11d
movq 0x48(%rsp), %r10
movq 0x38(%rsp), %rax
movl %r11d, (%rsp)
movq %r10, 0x8(%rsp)
movq %rax, 0x10(%rsp)
callq 0xfd5d0
movq 0x70(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x70(%rsp), %rax
movq $0x0, 0x488(%rax)
movq 0x70(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x1136d0
addq $0x78, %rsp
retq
nopl (%rax)