// File: tomfunkhouser[P]gaps/pkgs/png/pngrutil.c
// Function: png_handle_PLTE
void /* PRIVATE */
png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
   png_color palette[PNG_MAX_PALETTE_LENGTH];
   int num, i;
#ifdef PNG_POINTER_INDEXING_SUPPORTED
   png_colorp pal_ptr;
#endif

   png_debug(1, "in png_handle_PLTE");

   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before PLTE");

   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid PLTE after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }

   else if (png_ptr->mode & PNG_HAVE_PLTE)
      png_error(png_ptr, "Duplicate PLTE chunk");

   png_ptr->mode |= PNG_HAVE_PLTE;

   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
   {
      png_warning(png_ptr,
        "Ignoring PLTE chunk in grayscale PNG");
      png_crc_finish(png_ptr, length);
      return;
   }
#ifndef PNG_READ_OPT_PLTE_SUPPORTED
   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
   {
      png_crc_finish(png_ptr, length);
      return;
   }
#endif

   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
   {
      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
      {
         png_warning(png_ptr, "Invalid palette chunk");
         png_crc_finish(png_ptr, length);
         return;
      }

      else
      {
         png_error(png_ptr, "Invalid palette chunk");
      }
   }

   num = (int)length / 3;

#ifdef PNG_POINTER_INDEXING_SUPPORTED
   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
   {
      png_byte buf[3];

      png_crc_read(png_ptr, buf, 3);
      pal_ptr->red = buf[0];
      pal_ptr->green = buf[1];
      pal_ptr->blue = buf[2];
   }
#else
   for (i = 0; i < num; i++)
   {
      png_byte buf[3];

      png_crc_read(png_ptr, buf, 3);
      /* Don't depend upon png_color being any order */
      palette[i].red = buf[0];
      palette[i].green = buf[1];
      palette[i].blue = buf[2];
   }
#endif

   /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
    * whatever the normal CRC configuration tells us.  However, if we
    * have an RGB image, the PLTE can be considered ancillary, so
    * we will act as though it is.
    */
#ifndef PNG_READ_OPT_PLTE_SUPPORTED
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
#endif
   {
      png_crc_finish(png_ptr, 0);
   }
#ifndef PNG_READ_OPT_PLTE_SUPPORTED
   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
   {
      /* If we don't want to use the data from an ancillary chunk,
         we have two options: an error abort, or a warning and we
         ignore the data in this chunk (which should be OK, since
         it's considered ancillary for a RGB or RGBA image). */
      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
      {
         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
         {
            png_chunk_benign_error(png_ptr, "CRC error");
         }
         else
         {
            png_chunk_warning(png_ptr, "CRC error");
            return;
         }
      }
      /* Otherwise, we (optionally) emit a warning and use the chunk. */
      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
      {
         png_chunk_warning(png_ptr, "CRC error");
      }
   }
#endif

   png_set_PLTE(png_ptr, info_ptr, palette, num);

#ifdef PNG_READ_tRNS_SUPPORTED
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   {
      if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
      {
         if (png_ptr->num_trans > (png_uint_16)num)
         {
            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
            png_ptr->num_trans = (png_uint_16)num;
         }
         if (info_ptr->num_trans > (png_uint_16)num)
         {
            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
            info_ptr->num_trans = (png_uint_16)num;
         }
      }
   }
#endif

}

// Assembly:
subq $0x338, %rsp            # imm = 0x338
movq %rdi, 0x330(%rsp)
movq %rsi, 0x328(%rsp)
movl %edx, 0x324(%rsp)
movq 0x330(%rsp), %rax
movl 0x11c(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x1235aa
movq 0x330(%rsp), %rdi
leaq 0x1bca1(%rip), %rsi     # 0x13f244
callq 0x113860
jmp 0x12361b
movq 0x330(%rsp), %rax
movl 0x11c(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x1235ed
movq 0x330(%rsp), %rdi
leaq 0x1bc8e(%rip), %rsi     # 0x13f25d
callq 0x113940
movq 0x330(%rsp), %rdi
movl 0x324(%rsp), %esi
callq 0x122b90
jmp 0x123864
movq 0x330(%rsp), %rax
movl 0x11c(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x123617
movq 0x330(%rsp), %rdi
leaq 0x1bc63(%rip), %rsi     # 0x13f275
callq 0x113860
jmp 0x123619
jmp 0x12361b
movq 0x330(%rsp), %rax
movl 0x11c(%rax), %ecx
orl $0x2, %ecx
movl %ecx, 0x11c(%rax)
movq 0x330(%rsp), %rax
movzbl 0x24e(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x123676
movq 0x330(%rsp), %rdi
leaq 0x1bc32(%rip), %rsi     # 0x13f28a
callq 0x113940
movq 0x330(%rsp), %rdi
movl 0x324(%rsp), %esi
callq 0x122b90
jmp 0x123864
cmpl $0x300, 0x324(%rsp) # imm = 0x300
ja 0x123698
movl 0x324(%rsp), %eax
movl $0x3, %ecx
xorl %edx, %edx
divl %ecx
cmpl $0x0, %edx
je 0x1236ef
movq 0x330(%rsp), %rax
movzbl 0x24e(%rax), %eax
cmpl $0x3, %eax
je 0x1236d9
movq 0x330(%rsp), %rdi
leaq 0x1bbf4(%rip), %rsi     # 0x13f2af
callq 0x113940
movq 0x330(%rsp), %rdi
movl 0x324(%rsp), %esi
callq 0x122b90
jmp 0x123864
movq 0x330(%rsp), %rdi
leaq 0x1bbc7(%rip), %rsi     # 0x13f2af
callq 0x113860
jmp 0x1236ef
movl 0x324(%rsp), %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %eax, 0x1c(%rsp)
movl $0x0, 0x18(%rsp)
leaq 0x20(%rsp), %rax
movq %rax, 0x10(%rsp)
movl 0x18(%rsp), %eax
cmpl 0x1c(%rsp), %eax
jge 0x123773
movq 0x330(%rsp), %rdi
leaq 0xd(%rsp), %rsi
movl $0x3, %edx
callq 0x122b40
movb 0xd(%rsp), %cl
movq 0x10(%rsp), %rax
movb %cl, (%rax)
movb 0xe(%rsp), %cl
movq 0x10(%rsp), %rax
movb %cl, 0x1(%rax)
movb 0xf(%rsp), %cl
movq 0x10(%rsp), %rax
movb %cl, 0x2(%rax)
movl 0x18(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x18(%rsp)
movq 0x10(%rsp), %rax
addq $0x3, %rax
movq %rax, 0x10(%rsp)
jmp 0x123714
movq 0x330(%rsp), %rdi
xorl %esi, %esi
callq 0x122b90
movq 0x330(%rsp), %rdi
movq 0x328(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movl 0x1c(%rsp), %ecx
callq 0xfd990
movq 0x330(%rsp), %rax
movzbl 0x24e(%rax), %eax
cmpl $0x3, %eax
jne 0x123864
cmpq $0x0, 0x328(%rsp)
je 0x123862
movq 0x328(%rsp), %rax
movl 0x8(%rax), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x123862
movq 0x330(%rsp), %rax
movzwl 0x242(%rax), %eax
movl 0x1c(%rsp), %ecx
movzwl %cx, %ecx
cmpl %ecx, %eax
jle 0x123822
movq 0x330(%rsp), %rdi
leaq 0x1babe(%rip), %rsi     # 0x13f2c5
callq 0x113940
movl 0x1c(%rsp), %eax
movw %ax, %cx
movq 0x330(%rsp), %rax
movw %cx, 0x242(%rax)
movq 0x328(%rsp), %rax
movzwl 0x22(%rax), %eax
movl 0x1c(%rsp), %ecx
movzwl %cx, %ecx
cmpl %ecx, %eax
jle 0x123860
movq 0x330(%rsp), %rdi
leaq 0x1baa4(%rip), %rsi     # 0x13f2ec
callq 0x113940
movl 0x1c(%rsp), %eax
movw %ax, %cx
movq 0x328(%rsp), %rax
movw %cx, 0x22(%rax)
jmp 0x123862
jmp 0x123864
addq $0x338, %rsp            # imm = 0x338
retq
nopl (%rax)