// File: tomfunkhouser[P]gaps/pkgs/png/pngrutil.c
// Function: png_handle_iTXt
void /* PRIVATE */
png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
   png_textp text_ptr;
   png_charp key, lang, text, lang_key;
   int comp_flag;
   int comp_type = 0;
   int ret;
   png_size_t slength, prefix_len, data_len;

   png_debug(1, "in png_handle_iTXt");

#ifdef PNG_USER_LIMITS_SUPPORTED
   if (png_ptr->user_chunk_cache_max != 0)
   {
      if (png_ptr->user_chunk_cache_max == 1)
      {
         png_crc_finish(png_ptr, length);
         return;
      }
      if (--png_ptr->user_chunk_cache_max == 1)
      {
         png_warning(png_ptr, "No space in chunk cache for iTXt");
         png_crc_finish(png_ptr, length);
         return;
      }
   }
#endif

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

   if (png_ptr->mode & PNG_HAVE_IDAT)
      png_ptr->mode |= PNG_AFTER_IDAT;

#ifdef PNG_MAX_MALLOC_64K
   /* We will no doubt have problems with chunks even half this size, but
      there is no hard and fast rule to tell us where to stop. */
   if (length > (png_uint_32)65535L)
   {
     png_warning(png_ptr, "iTXt chunk too large to fit in memory");
     png_crc_finish(png_ptr, length);
     return;
   }
#endif

   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 to process iTXt chunk");
     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;

   for (lang = png_ptr->chunkdata; *lang; lang++)
      /* Empty loop */ ;
   lang++;        /* Skip NUL separator */

   /* iTXt must have a language tag (possibly empty), two compression bytes,
    * translated keyword (possibly empty), and possibly some text after the
    * keyword
    */

   if (lang >= png_ptr->chunkdata + slength - 3)
   {
      png_warning(png_ptr, "Truncated iTXt chunk");
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      return;
   }
   else
   {
       comp_flag = *lang++;
       comp_type = *lang++;
   }

   for (lang_key = lang; *lang_key; lang_key++)
      /* Empty loop */ ;
   lang_key++;        /* Skip NUL separator */

   if (lang_key >= png_ptr->chunkdata + slength)
   {
      png_warning(png_ptr, "Truncated iTXt chunk");
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      return;
   }

   for (text = lang_key; *text; text++)
      /* Empty loop */ ;
   text++;        /* Skip NUL separator */
   if (text >= png_ptr->chunkdata + slength)
   {
      png_warning(png_ptr, "Malformed iTXt chunk");
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      return;
   }

   prefix_len = text - png_ptr->chunkdata;

   key=png_ptr->chunkdata;
   if (comp_flag)
       png_decompress_chunk(png_ptr, comp_type,
         (size_t)length, prefix_len, &data_len);
   else
       data_len = png_strlen(png_ptr->chunkdata + prefix_len);
   text_ptr = (png_textp)png_malloc_warn(png_ptr,
      png_sizeof(png_text));
   if (text_ptr == NULL)
   {
     png_warning(png_ptr, "Not enough memory to process iTXt chunk");
     png_free(png_ptr, png_ptr->chunkdata);
     png_ptr->chunkdata = NULL;
     return;
   }
   text_ptr->compression = (int)comp_flag + 1;
   text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
   text_ptr->lang = png_ptr->chunkdata + (lang - key);
   text_ptr->itxt_length = data_len;
   text_ptr->text_length = 0;
   text_ptr->key = png_ptr->chunkdata;
   text_ptr->text = png_ptr->chunkdata + prefix_len;

   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);

   png_free(png_ptr, text_ptr);
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = NULL;
   if (ret)
     png_error(png_ptr, "Insufficient memory to store iTXt chunk");
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movl %edx, 0x54(%rsp)
movl $0x0, 0x20(%rsp)
movq 0x60(%rsp), %rax
cmpl $0x0, 0x45c(%rax)
je 0x1270f8
movq 0x60(%rsp), %rax
cmpl $0x1, 0x45c(%rax)
jne 0x1270b9
movq 0x60(%rsp), %rdi
movl 0x54(%rsp), %esi
callq 0x122b90
jmp 0x1275bf
movq 0x60(%rsp), %rcx
movl 0x45c(%rcx), %eax
addl $-0x1, %eax
movl %eax, 0x45c(%rcx)
cmpl $0x1, %eax
jne 0x1270f6
movq 0x60(%rsp), %rdi
leaq 0x18d76(%rip), %rsi     # 0x13fe54
callq 0x113940
movq 0x60(%rsp), %rdi
movl 0x54(%rsp), %esi
callq 0x122b90
jmp 0x1275bf
jmp 0x1270f8
movq 0x60(%rsp), %rax
movl 0x11c(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x12711c
movq 0x60(%rsp), %rdi
leaq 0x18d5e(%rip), %rsi     # 0x13fe75
callq 0x113860
movq 0x60(%rsp), %rax
movl 0x11c(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x127143
movq 0x60(%rsp), %rax
movl 0x11c(%rax), %ecx
orl $0x8, %ecx
movl %ecx, 0x11c(%rax)
movq 0x60(%rsp), %rdi
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x60(%rsp), %rdi
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
callq 0x113760
movq %rax, %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x488(%rax)
movq 0x60(%rsp), %rax
cmpq $0x0, 0x488(%rax)
jne 0x1271a2
movq 0x60(%rsp), %rdi
leaq 0x18cf6(%rip), %rsi     # 0x13fe8e
callq 0x113940
jmp 0x1275bf
movl 0x54(%rsp), %eax
movq %rax, 0x10(%rsp)
movq 0x60(%rsp), %rdi
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rsi
movq 0x10(%rsp), %rdx
callq 0x122b40
movq 0x60(%rsp), %rdi
xorl %esi, %esi
callq 0x122b90
cmpl $0x0, %eax
je 0x127202
movq 0x60(%rsp), %rdi
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x60(%rsp), %rax
movq $0x0, 0x488(%rax)
jmp 0x1275bf
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rax
movq 0x10(%rsp), %rcx
movb $0x0, (%rax,%rcx)
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rax
movq %rax, 0x38(%rsp)
movq 0x38(%rsp), %rax
cmpb $0x0, (%rax)
je 0x127244
jmp 0x127234
movq 0x38(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x38(%rsp)
jmp 0x127228
movq 0x38(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x38(%rsp)
movq 0x38(%rsp), %rax
movq 0x60(%rsp), %rcx
movq 0x488(%rcx), %rcx
addq 0x10(%rsp), %rcx
addq $-0x3, %rcx
cmpq %rcx, %rax
jb 0x1272ad
movq 0x60(%rsp), %rdi
leaq 0x18c31(%rip), %rsi     # 0x13feae
callq 0x113940
movq 0x60(%rsp), %rdi
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x60(%rsp), %rax
movq $0x0, 0x488(%rax)
jmp 0x1275bf
movq 0x38(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x38(%rsp)
movsbl (%rax), %eax
movl %eax, 0x24(%rsp)
movq 0x38(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x38(%rsp)
movsbl (%rax), %eax
movl %eax, 0x20(%rsp)
movq 0x38(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rax
cmpb $0x0, (%rax)
je 0x127303
jmp 0x1272f3
movq 0x28(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x28(%rsp)
jmp 0x1272e7
movq 0x28(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rax
movq 0x60(%rsp), %rcx
movq 0x488(%rcx), %rcx
addq 0x10(%rsp), %rcx
cmpq %rcx, %rax
jb 0x127368
movq 0x60(%rsp), %rdi
leaq 0x18b76(%rip), %rsi     # 0x13feae
callq 0x113940
movq 0x60(%rsp), %rdi
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x60(%rsp), %rax
movq $0x0, 0x488(%rax)
jmp 0x1275bf
movq 0x28(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rax
cmpb $0x0, (%rax)
je 0x12738e
jmp 0x12737e
movq 0x30(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x30(%rsp)
jmp 0x127372
movq 0x30(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rax
movq 0x60(%rsp), %rcx
movq 0x488(%rcx), %rcx
addq 0x10(%rsp), %rcx
cmpq %rcx, %rax
jb 0x1273f3
movq 0x60(%rsp), %rdi
leaq 0x18b00(%rip), %rsi     # 0x13fec3
callq 0x113940
movq 0x60(%rsp), %rdi
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x60(%rsp), %rax
movq $0x0, 0x488(%rax)
jmp 0x1275bf
movq 0x30(%rsp), %rax
movq 0x60(%rsp), %rcx
movq 0x488(%rcx), %rcx
subq %rcx, %rax
movq %rax, 0x8(%rsp)
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rax
movq %rax, 0x40(%rsp)
cmpl $0x0, 0x24(%rsp)
je 0x127442
movq 0x60(%rsp), %rdi
movl 0x20(%rsp), %esi
movl 0x54(%rsp), %eax
movl %eax, %edx
movq 0x8(%rsp), %rcx
movq %rsp, %r8
callq 0x122dc0
jmp 0x12745c
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rdi
addq 0x8(%rsp), %rdi
callq 0xf200
movq %rax, (%rsp)
movq 0x60(%rsp), %rdi
movl $0x38, %esi
callq 0x113760
movq %rax, 0x48(%rsp)
cmpq $0x0, 0x48(%rsp)
jne 0x1274b4
movq 0x60(%rsp), %rdi
leaq 0x18a54(%rip), %rsi     # 0x13fed8
callq 0x113940
movq 0x60(%rsp), %rdi
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x60(%rsp), %rax
movq $0x0, 0x488(%rax)
jmp 0x1275bf
movl 0x24(%rsp), %ecx
addl $0x1, %ecx
movq 0x48(%rsp), %rax
movl %ecx, (%rax)
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rcx
movq 0x28(%rsp), %rax
movq 0x40(%rsp), %rdx
subq %rdx, %rax
addq %rax, %rcx
movq 0x48(%rsp), %rax
movq %rcx, 0x30(%rax)
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rcx
movq 0x38(%rsp), %rax
movq 0x40(%rsp), %rdx
subq %rdx, %rax
addq %rax, %rcx
movq 0x48(%rsp), %rax
movq %rcx, 0x28(%rax)
movq (%rsp), %rcx
movq 0x48(%rsp), %rax
movq %rcx, 0x20(%rax)
movq 0x48(%rsp), %rax
movq $0x0, 0x18(%rax)
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rcx
movq 0x48(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rcx
addq 0x8(%rsp), %rcx
movq 0x48(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x60(%rsp), %rdi
movq 0x58(%rsp), %rsi
movq 0x48(%rsp), %rdx
movl $0x1, %ecx
callq 0xfdf00
movl %eax, 0x1c(%rsp)
movq 0x60(%rsp), %rdi
movq 0x48(%rsp), %rsi
callq 0x1136d0
movq 0x60(%rsp), %rdi
movq 0x60(%rsp), %rax
movq 0x488(%rax), %rsi
callq 0x1136d0
movq 0x60(%rsp), %rax
movq $0x0, 0x488(%rax)
cmpl $0x0, 0x1c(%rsp)
je 0x1275bf
movq 0x60(%rsp), %rdi
leaq 0x18946(%rip), %rsi     # 0x13ff00
callq 0x113860
addq $0x68, %rsp
retq
nopw %cs:(%rax,%rax)