// File: tomfunkhouser[P]gaps/pkgs/png/pngwrite.c
// Function: png_set_filter
void PNGAPI
png_set_filter(png_structp png_ptr, int method, int filters)
{
   png_debug(1, "in png_set_filter");

   if (png_ptr == NULL)
      return;
#ifdef PNG_MNG_FEATURES_SUPPORTED
   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
      (method == PNG_INTRAPIXEL_DIFFERENCING))
         method = PNG_FILTER_TYPE_BASE;
#endif
   if (method == PNG_FILTER_TYPE_BASE)
   {
      switch (filters & (PNG_ALL_FILTERS | 0x07))
      {
#ifdef PNG_WRITE_FILTER_SUPPORTED
         case 5:
         case 6:
         case 7: png_warning(png_ptr, "Unknown row filter for method 0");
#endif /* PNG_WRITE_FILTER_SUPPORTED */
         case PNG_FILTER_VALUE_NONE:
              png_ptr->do_filter = PNG_FILTER_NONE; break;
#ifdef PNG_WRITE_FILTER_SUPPORTED
         case PNG_FILTER_VALUE_SUB:
              png_ptr->do_filter = PNG_FILTER_SUB; break;
         case PNG_FILTER_VALUE_UP:
              png_ptr->do_filter = PNG_FILTER_UP; break;
         case PNG_FILTER_VALUE_AVG:
              png_ptr->do_filter = PNG_FILTER_AVG; break;
         case PNG_FILTER_VALUE_PAETH:
              png_ptr->do_filter = PNG_FILTER_PAETH; break;
         default: png_ptr->do_filter = (png_byte)filters; break;
#else
         default: png_warning(png_ptr, "Unknown row filter for method 0");
#endif /* PNG_WRITE_FILTER_SUPPORTED */
      }

      /* If we have allocated the row_buf, this means we have already started
       * with the image and we should have allocated all of the filter buffers
       * that have been selected.  If prev_row isn't already allocated, then
       * it is too late to start using the filters that need it, since we
       * will be missing the data in the previous row.  If an application
       * wants to start and stop using particular filters during compression,
       * it should start out with all of the filters, and then add and
       * remove them after the start of compression.
       */
      if (png_ptr->row_buf != NULL)
      {
#ifdef PNG_WRITE_FILTER_SUPPORTED
         if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
         {
            png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
              (png_ptr->rowbytes + 1));
            png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
         }

         if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
         {
            if (png_ptr->prev_row == NULL)
            {
               png_warning(png_ptr, "Can't add Up filter after starting");
               png_ptr->do_filter &= ~PNG_FILTER_UP;
            }
            else
            {
               png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
                  (png_ptr->rowbytes + 1));
               png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
            }
         }

         if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
         {
            if (png_ptr->prev_row == NULL)
            {
               png_warning(png_ptr, "Can't add Average filter after starting");
               png_ptr->do_filter &= ~PNG_FILTER_AVG;
            }
            else
            {
               png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
                  (png_ptr->rowbytes + 1));
               png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
            }
         }

         if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
             png_ptr->paeth_row == NULL)
         {
            if (png_ptr->prev_row == NULL)
            {
               png_warning(png_ptr, "Can't add Paeth filter after starting");
               png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
            }
            else
            {
               png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
                  (png_ptr->rowbytes + 1));
               png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
            }
         }

         if (png_ptr->do_filter == PNG_NO_FILTERS)
#endif /* PNG_WRITE_FILTER_SUPPORTED */
            png_ptr->do_filter = PNG_FILTER_NONE;
      }
   }
   else
      png_error(png_ptr, "Unknown custom filter method");
}

// Assembly:
subq $0x18, %rsp
movq %rdi, 0x10(%rsp)
movl %esi, 0xc(%rsp)
movl %edx, 0x8(%rsp)
cmpq $0x0, 0x10(%rsp)
jne 0x10592e
jmp 0x105c51
movq 0x10(%rsp), %rax
movl 0x408(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x105950
cmpl $0x40, 0xc(%rsp)
jne 0x105950
movl $0x0, 0xc(%rsp)
cmpl $0x0, 0xc(%rsp)
jne 0x105c40
movzbl 0x8(%rsp), %eax
movl %eax, %ecx
movq %rcx, (%rsp)
subl $0x7, %eax
ja 0x1059d6
movq (%rsp), %rax
leaq 0x33a26(%rip), %rcx     # 0x13939c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x10(%rsp), %rdi
leaq 0x33ace(%rip), %rsi     # 0x139459
callq 0x113940
movq 0x10(%rsp), %rax
movb $0x8, 0x24d(%rax)
jmp 0x1059e7
movq 0x10(%rsp), %rax
movb $0x10, 0x24d(%rax)
jmp 0x1059e7
movq 0x10(%rsp), %rax
movb $0x20, 0x24d(%rax)
jmp 0x1059e7
movq 0x10(%rsp), %rax
movb $0x40, 0x24d(%rax)
jmp 0x1059e7
movq 0x10(%rsp), %rax
movb $-0x80, 0x24d(%rax)
jmp 0x1059e7
movl 0x8(%rsp), %eax
movb %al, %cl
movq 0x10(%rsp), %rax
movb %cl, 0x24d(%rax)
movq 0x10(%rsp), %rax
cmpq $0x0, 0x1f0(%rax)
je 0x105c3e
movq 0x10(%rsp), %rax
movzbl 0x24d(%rax), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x105a55
movq 0x10(%rsp), %rax
cmpq $0x0, 0x1f8(%rax)
jne 0x105a55
movq 0x10(%rsp), %rdi
movq 0x10(%rsp), %rax
movq 0x1d0(%rax), %rsi
addq $0x1, %rsi
callq 0x1135b0
movq %rax, %rcx
movq 0x10(%rsp), %rax
movq %rcx, 0x1f8(%rax)
movq 0x10(%rsp), %rax
movq 0x1f8(%rax), %rax
movb $0x1, (%rax)
movq 0x10(%rsp), %rax
movzbl 0x24d(%rax), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x105aed
movq 0x10(%rsp), %rax
cmpq $0x0, 0x200(%rax)
jne 0x105aed
movq 0x10(%rsp), %rax
cmpq $0x0, 0x1e8(%rax)
jne 0x105ab3
movq 0x10(%rsp), %rdi
leaq 0x339e2(%rip), %rsi     # 0x139479
callq 0x113940
movq 0x10(%rsp), %rax
movzbl 0x24d(%rax), %ecx
andl $-0x21, %ecx
movb %cl, 0x24d(%rax)
jmp 0x105aeb
movq 0x10(%rsp), %rdi
movq 0x10(%rsp), %rax
movq 0x1d0(%rax), %rsi
addq $0x1, %rsi
callq 0x1135b0
movq %rax, %rcx
movq 0x10(%rsp), %rax
movq %rcx, 0x200(%rax)
movq 0x10(%rsp), %rax
movq 0x200(%rax), %rax
movb $0x2, (%rax)
jmp 0x105aed
movq 0x10(%rsp), %rax
movzbl 0x24d(%rax), %eax
andl $0x40, %eax
cmpl $0x0, %eax
je 0x105b85
movq 0x10(%rsp), %rax
cmpq $0x0, 0x208(%rax)
jne 0x105b85
movq 0x10(%rsp), %rax
cmpq $0x0, 0x1e8(%rax)
jne 0x105b4b
movq 0x10(%rsp), %rdi
leaq 0x3396d(%rip), %rsi     # 0x13949c
callq 0x113940
movq 0x10(%rsp), %rax
movzbl 0x24d(%rax), %ecx
andl $-0x41, %ecx
movb %cl, 0x24d(%rax)
jmp 0x105b83
movq 0x10(%rsp), %rdi
movq 0x10(%rsp), %rax
movq 0x1d0(%rax), %rsi
addq $0x1, %rsi
callq 0x1135b0
movq %rax, %rcx
movq 0x10(%rsp), %rax
movq %rcx, 0x208(%rax)
movq 0x10(%rsp), %rax
movq 0x208(%rax), %rax
movb $0x3, (%rax)
jmp 0x105b85
movq 0x10(%rsp), %rax
movzbl 0x24d(%rax), %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0x105c1f
movq 0x10(%rsp), %rax
cmpq $0x0, 0x210(%rax)
jne 0x105c1f
movq 0x10(%rsp), %rax
cmpq $0x0, 0x1e8(%rax)
jne 0x105be5
movq 0x10(%rsp), %rdi
leaq 0x338fb(%rip), %rsi     # 0x1394c4
callq 0x113940
movq 0x10(%rsp), %rax
movzbl 0x24d(%rax), %ecx
andl $0x7f, %ecx
movb %cl, 0x24d(%rax)
jmp 0x105c1d
movq 0x10(%rsp), %rdi
movq 0x10(%rsp), %rax
movq 0x1d0(%rax), %rsi
addq $0x1, %rsi
callq 0x1135b0
movq %rax, %rcx
movq 0x10(%rsp), %rax
movq %rcx, 0x210(%rax)
movq 0x10(%rsp), %rax
movq 0x210(%rax), %rax
movb $0x4, (%rax)
jmp 0x105c1f
movq 0x10(%rsp), %rax
movzbl 0x24d(%rax), %eax
cmpl $0x0, %eax
jne 0x105c3c
movq 0x10(%rsp), %rax
movb $0x8, 0x24d(%rax)
jmp 0x105c3e
jmp 0x105c51
movq 0x10(%rsp), %rdi
leaq 0x3389e(%rip), %rsi     # 0x1394ea
callq 0x113860
addq $0x18, %rsp
retq
nopw %cs:(%rax,%rax)