// File: tomfunkhouser[P]gaps/pkgs/png/pngrutil.c
// Function: png_read_filter_row
void /* PRIVATE */
png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
   png_bytep prev_row, int filter)
{
   png_debug(1, "in png_read_filter_row");
   png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
   switch (filter)
   {
      case PNG_FILTER_VALUE_NONE:
         break;
      case PNG_FILTER_VALUE_SUB:
      {
         png_uint_32 i;
         png_uint_32 istop = row_info->rowbytes;
         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
         png_bytep rp = row + bpp;
         png_bytep lp = row;

         for (i = bpp; i < istop; i++)
         {
            *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
            rp++;
         }
         break;
      }
      case PNG_FILTER_VALUE_UP:
      {
         png_uint_32 i;
         png_uint_32 istop = row_info->rowbytes;
         png_bytep rp = row;
         png_bytep pp = prev_row;

         for (i = 0; i < istop; i++)
         {
            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
            rp++;
         }
         break;
      }
      case PNG_FILTER_VALUE_AVG:
      {
         png_uint_32 i;
         png_bytep rp = row;
         png_bytep pp = prev_row;
         png_bytep lp = row;
         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
         png_uint_32 istop = row_info->rowbytes - bpp;

         for (i = 0; i < bpp; i++)
         {
            *rp = (png_byte)(((int)(*rp) +
               ((int)(*pp++) / 2 )) & 0xff);
            rp++;
         }

         for (i = 0; i < istop; i++)
         {
            *rp = (png_byte)(((int)(*rp) +
               (int)(*pp++ + *lp++) / 2 ) & 0xff);
            rp++;
         }
         break;
      }
      case PNG_FILTER_VALUE_PAETH:
      {
         png_uint_32 i;
         png_bytep rp = row;
         png_bytep pp = prev_row;
         png_bytep lp = row;
         png_bytep cp = prev_row;
         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
         png_uint_32 istop=row_info->rowbytes - bpp;

         for (i = 0; i < bpp; i++)
         {
            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
            rp++;
         }

         for (i = 0; i < istop; i++)   /* Use leftover rp,pp */
         {
            int a, b, c, pa, pb, pc, p;

            a = *lp++;
            b = *pp++;
            c = *cp++;

            p = b - c;
            pc = a - c;

#ifdef PNG_USE_ABS
            pa = abs(p);
            pb = abs(pc);
            pc = abs(p + pc);
#else
            pa = p < 0 ? -p : p;
            pb = pc < 0 ? -pc : pc;
            pc = (p + pc) < 0 ? -(p + pc) : p + pc;
#endif

            /*
               if (pa <= pb && pa <= pc)
                  p = a;
               else if (pb <= pc)
                  p = b;
               else
                  p = c;
             */

            p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;

            *rp = (png_byte)(((int)(*rp) + p) & 0xff);
            rp++;
         }
         break;
      }
      default:
         png_warning(png_ptr, "Ignoring bad adaptive filter type");
         *row = 0;
         break;
   }
}

// Assembly:
subq $0xf8, %rsp
movq %rdi, 0xf0(%rsp)
movq %rsi, 0xe8(%rsp)
movq %rdx, 0xe0(%rsp)
movq %rcx, 0xd8(%rsp)
movl %r8d, 0xd4(%rsp)
movl 0xd4(%rsp), %eax
movq %rax, 0x20(%rsp)
subq $0x4, %rax
ja 0x128fcd
movq 0x20(%rsp), %rax
leaq 0x165bb(%rip), %rcx     # 0x13f02c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
jmp 0x128fec
movq 0xe8(%rsp), %rax
movq 0x8(%rax), %rax
movl %eax, 0xcc(%rsp)
movq 0xe8(%rsp), %rax
movzbl 0x13(%rax), %eax
addl $0x7, %eax
sarl $0x3, %eax
movl %eax, 0xc8(%rsp)
movq 0xe0(%rsp), %rax
movl 0xc8(%rsp), %ecx
addq %rcx, %rax
movq %rax, 0xc0(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0xb8(%rsp)
movl 0xc8(%rsp), %eax
movl %eax, 0xd0(%rsp)
movl 0xd0(%rsp), %eax
cmpl 0xcc(%rsp), %eax
jae 0x128b52
movq 0xc0(%rsp), %rax
movzbl (%rax), %eax
movq 0xb8(%rsp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, 0xb8(%rsp)
movzbl (%rcx), %ecx
addl %ecx, %eax
andl $0xff, %eax
movb %al, %cl
movq 0xc0(%rsp), %rax
movb %cl, (%rax)
movq 0xc0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xc0(%rsp)
movl 0xd0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd0(%rsp)
jmp 0x128ae3
jmp 0x128fec
movq 0xe8(%rsp), %rax
movq 0x8(%rax), %rax
movl %eax, 0xb0(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0xa8(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0xa0(%rsp)
movl $0x0, 0xb4(%rsp)
movl 0xb4(%rsp), %eax
cmpl 0xb0(%rsp), %eax
jae 0x128c04
movq 0xa8(%rsp), %rax
movzbl (%rax), %eax
movq 0xa0(%rsp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, 0xa0(%rsp)
movzbl (%rcx), %ecx
addl %ecx, %eax
andl $0xff, %eax
movb %al, %cl
movq 0xa8(%rsp), %rax
movb %cl, (%rax)
movq 0xa8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xa8(%rsp)
movl 0xb4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0x128b95
jmp 0x128fec
movq 0xe0(%rsp), %rax
movq %rax, 0x90(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0xe8(%rsp), %rax
movzbl 0x13(%rax), %eax
addl $0x7, %eax
sarl $0x3, %eax
movl %eax, 0x7c(%rsp)
movq 0xe8(%rsp), %rax
movq 0x8(%rax), %rax
movl 0x7c(%rsp), %ecx
subq %rcx, %rax
movl %eax, 0x78(%rsp)
movl $0x0, 0x9c(%rsp)
movl 0x9c(%rsp), %eax
cmpl 0x7c(%rsp), %eax
jae 0x128cef
movq 0x90(%rsp), %rax
movzbl (%rax), %eax
movl %eax, 0x1c(%rsp)
movq 0x88(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x88(%rsp)
movzbl (%rax), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl 0x1c(%rsp), %eax
addl %ecx, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x90(%rsp), %rax
movb %cl, (%rax)
movq 0x90(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x90(%rsp)
movl 0x9c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x9c(%rsp)
jmp 0x128c71
movl $0x0, 0x9c(%rsp)
movl 0x9c(%rsp), %eax
cmpl 0x78(%rsp), %eax
jae 0x128d9b
movq 0x90(%rsp), %rax
movzbl (%rax), %eax
movl %eax, 0x18(%rsp)
movq 0x88(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x88(%rsp)
movzbl (%rax), %eax
movq 0x80(%rsp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, 0x80(%rsp)
movzbl (%rcx), %ecx
addl %ecx, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl 0x18(%rsp), %eax
addl %ecx, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x90(%rsp), %rax
movb %cl, (%rax)
movq 0x90(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x90(%rsp)
movl 0x9c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x9c(%rsp)
jmp 0x128cfa
jmp 0x128fec
movq 0xe0(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0xe8(%rsp), %rax
movzbl 0x13(%rax), %eax
addl $0x7, %eax
sarl $0x3, %eax
movl %eax, 0x4c(%rsp)
movq 0xe8(%rsp), %rax
movq 0x8(%rax), %rax
movl 0x4c(%rsp), %ecx
subq %rcx, %rax
movl %eax, 0x48(%rsp)
movl $0x0, 0x74(%rsp)
movl 0x74(%rsp), %eax
cmpl 0x4c(%rsp), %eax
jae 0x128e5a
movq 0x68(%rsp), %rax
movzbl (%rax), %eax
movq 0x60(%rsp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, 0x60(%rsp)
movzbl (%rcx), %ecx
addl %ecx, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x68(%rsp), %rax
movb %cl, (%rax)
movq 0x68(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x68(%rsp)
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x128e09
movl $0x0, 0x74(%rsp)
movl 0x74(%rsp), %eax
cmpl 0x48(%rsp), %eax
jae 0x128fcb
movq 0x58(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x58(%rsp)
movzbl (%rax), %eax
movl %eax, 0x44(%rsp)
movq 0x60(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x60(%rsp)
movzbl (%rax), %eax
movl %eax, 0x40(%rsp)
movq 0x50(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x50(%rsp)
movzbl (%rax), %eax
movl %eax, 0x3c(%rsp)
movl 0x40(%rsp), %eax
subl 0x3c(%rsp), %eax
movl %eax, 0x2c(%rsp)
movl 0x44(%rsp), %eax
subl 0x3c(%rsp), %eax
movl %eax, 0x30(%rsp)
cmpl $0x0, 0x2c(%rsp)
jge 0x128ee3
xorl %eax, %eax
subl 0x2c(%rsp), %eax
movl %eax, 0x14(%rsp)
jmp 0x128eeb
movl 0x2c(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x14(%rsp), %eax
movl %eax, 0x38(%rsp)
cmpl $0x0, 0x30(%rsp)
jge 0x128f06
xorl %eax, %eax
subl 0x30(%rsp), %eax
movl %eax, 0x10(%rsp)
jmp 0x128f0e
movl 0x30(%rsp), %eax
movl %eax, 0x10(%rsp)
movl 0x10(%rsp), %eax
movl %eax, 0x34(%rsp)
movl 0x2c(%rsp), %eax
addl 0x30(%rsp), %eax
cmpl $0x0, %eax
jge 0x128f35
movl 0x2c(%rsp), %ecx
addl 0x30(%rsp), %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, 0xc(%rsp)
jmp 0x128f41
movl 0x2c(%rsp), %eax
addl 0x30(%rsp), %eax
movl %eax, 0xc(%rsp)
movl 0xc(%rsp), %eax
movl %eax, 0x30(%rsp)
movl 0x38(%rsp), %eax
cmpl 0x34(%rsp), %eax
jg 0x128f67
movl 0x38(%rsp), %eax
cmpl 0x30(%rsp), %eax
jg 0x128f67
movl 0x44(%rsp), %eax
movl %eax, 0x8(%rsp)
jmp 0x128f8b
movl 0x34(%rsp), %eax
cmpl 0x30(%rsp), %eax
jg 0x128f7b
movl 0x40(%rsp), %eax
movl %eax, 0x4(%rsp)
jmp 0x128f83
movl 0x3c(%rsp), %eax
movl %eax, 0x4(%rsp)
movl 0x4(%rsp), %eax
movl %eax, 0x8(%rsp)
movl 0x8(%rsp), %eax
movl %eax, 0x2c(%rsp)
movq 0x68(%rsp), %rax
movzbl (%rax), %eax
addl 0x2c(%rsp), %eax
andl $0xff, %eax
movb %al, %cl
movq 0x68(%rsp), %rax
movb %cl, (%rax)
movq 0x68(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x68(%rsp)
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x128e62
jmp 0x128fec
movq 0xf0(%rsp), %rdi
leaq 0x16fb4(%rip), %rsi     # 0x13ff90
callq 0x113940
movq 0xe0(%rsp), %rax
movb $0x0, (%rax)
addq $0xf8, %rsp
retq
nopw %cs:(%rax,%rax)