// File: phillip-h[P]fractal-gen/lodepng.cpp
// Function: unfilterScanline(unsigned char*, unsigned char const*, unsigned char const*, unsigned long, unsigned char, unsigned long)
static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon,
                                 size_t bytewidth, unsigned char filterType, size_t length)
{
  /*
  For PNG filter method 0
  unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte,
  the filter works byte per byte (bytewidth = 1)
  precon is the previous unfiltered scanline, recon the result, scanline the current one
  the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead
  recon and scanline MAY be the same memory address! precon must be disjoint.
  */

  size_t i;
  switch(filterType)
  {
    case 0:
      for(i = 0; i != length; ++i) recon[i] = scanline[i];
      break;
    case 1:
      for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
      for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth];
      break;
    case 2:
      if(precon)
      {
        for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i];
      }
      else
      {
        for(i = 0; i != length; ++i) recon[i] = scanline[i];
      }
      break;
    case 3:
      if(precon)
      {
        for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1);
        for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1);
      }
      else
      {
        for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
        for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1);
      }
      break;
    case 4:
      if(precon)
      {
        for(i = 0; i != bytewidth; ++i)
        {
          recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/
        }
        for(i = bytewidth; i < length; ++i)
        {
          recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
        }
      }
      else
      {
        for(i = 0; i != bytewidth; ++i)
        {
          recon[i] = scanline[i];
        }
        for(i = bytewidth; i < length; ++i)
        {
          /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/
          recon[i] = (scanline[i] + recon[i - bytewidth]);
        }
      }
      break;
    default: return 36; /*error: unexisting filter type given*/
  }
  return 0;
}

// Assembly:
subq $0x58, %rsp
movb %r8b, %al
movq %rdi, 0x48(%rsp)
movq %rsi, 0x40(%rsp)
movq %rdx, 0x38(%rsp)
movq %rcx, 0x30(%rsp)
movb %al, 0x2f(%rsp)
movq %r9, 0x20(%rsp)
movzbl 0x2f(%rsp), %eax
movq %rax, 0x10(%rsp)
subq $0x4, %rax
ja 0x181bd
movq 0x10(%rsp), %rax
leaq 0x47c0(%rip), %rcx      # 0x1c4e4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq $0x0, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x20(%rsp), %rax
je 0x17d6c
movq 0x40(%rsp), %rax
movq 0x18(%rsp), %rcx
movb (%rax,%rcx), %dl
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x17d36
jmp 0x181c7
movq $0x0, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x17db0
movq 0x40(%rsp), %rax
movq 0x18(%rsp), %rcx
movb (%rax,%rcx), %dl
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x17d7a
movq 0x30(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x20(%rsp), %rax
jae 0x17e08
movq 0x40(%rsp), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movq 0x48(%rsp), %rcx
movq 0x18(%rsp), %rdx
subq 0x30(%rsp), %rdx
movzbl (%rcx,%rdx), %ecx
addl %ecx, %eax
movb %al, %dl
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x17dba
jmp 0x181c7
cmpq $0x0, 0x38(%rsp)
je 0x17e69
movq $0x0, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x20(%rsp), %rax
je 0x17e67
movq 0x40(%rsp), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movq 0x38(%rsp), %rcx
movq 0x18(%rsp), %rdx
movzbl (%rcx,%rdx), %ecx
addl %ecx, %eax
movb %al, %dl
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x17e1e
jmp 0x17eaa
movq $0x0, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x20(%rsp), %rax
je 0x17ea8
movq 0x40(%rsp), %rax
movq 0x18(%rsp), %rcx
movb (%rax,%rcx), %dl
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x17e72
jmp 0x17eaa
jmp 0x181c7
cmpq $0x0, 0x38(%rsp)
je 0x17f7e
movq $0x0, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x17f0f
movq 0x40(%rsp), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movq 0x38(%rsp), %rcx
movq 0x18(%rsp), %rdx
movzbl (%rcx,%rdx), %ecx
sarl %ecx
addl %ecx, %eax
movb %al, %dl
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x17ec4
movq 0x30(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x20(%rsp), %rax
jae 0x17f79
movq 0x40(%rsp), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movq 0x48(%rsp), %rcx
movq 0x18(%rsp), %rdx
subq 0x30(%rsp), %rdx
movzbl (%rcx,%rdx), %ecx
movq 0x38(%rsp), %rdx
movq 0x18(%rsp), %rsi
movzbl (%rdx,%rsi), %edx
addl %edx, %ecx
sarl %ecx
addl %ecx, %eax
movb %al, %dl
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x17f19
jmp 0x18019
movq $0x0, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x17fbd
movq 0x40(%rsp), %rax
movq 0x18(%rsp), %rcx
movb (%rax,%rcx), %dl
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x17f87
movq 0x30(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x20(%rsp), %rax
jae 0x18017
movq 0x40(%rsp), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movq 0x48(%rsp), %rcx
movq 0x18(%rsp), %rdx
subq 0x30(%rsp), %rdx
movzbl (%rcx,%rdx), %ecx
sarl %ecx
addl %ecx, %eax
movb %al, %dl
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x17fc7
jmp 0x18019
jmp 0x181c7
cmpq $0x0, 0x38(%rsp)
je 0x18122
movq $0x0, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x1807c
movq 0x40(%rsp), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movq 0x38(%rsp), %rcx
movq 0x18(%rsp), %rdx
movzbl (%rcx,%rdx), %ecx
addl %ecx, %eax
movb %al, %dl
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x18033
movq 0x30(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x20(%rsp), %rax
jae 0x1811d
movq 0x40(%rsp), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movl %eax, 0xc(%rsp)
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
subq 0x30(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movw %ax, %dx
movq 0x38(%rsp), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movw %ax, %cx
movq 0x38(%rsp), %rax
movq 0x18(%rsp), %rsi
subq 0x30(%rsp), %rsi
movzbl (%rax,%rsi), %eax
movswl %dx, %edi
movswl %cx, %esi
movswl %ax, %edx
callq 0x181e0
movb %al, %cl
movl 0xc(%rsp), %eax
movzbl %cl, %ecx
addl %ecx, %eax
movb %al, %dl
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x18086
jmp 0x181bb
movq $0x0, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x18161
movq 0x40(%rsp), %rax
movq 0x18(%rsp), %rcx
movb (%rax,%rcx), %dl
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x1812b
movq 0x30(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x20(%rsp), %rax
jae 0x181b9
movq 0x40(%rsp), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movq 0x48(%rsp), %rcx
movq 0x18(%rsp), %rdx
subq 0x30(%rsp), %rdx
movzbl (%rcx,%rdx), %ecx
addl %ecx, %eax
movb %al, %dl
movq 0x48(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x1816b
jmp 0x181bb
jmp 0x181c7
movl $0x24, 0x54(%rsp)
jmp 0x181cf
movl $0x0, 0x54(%rsp)
movl 0x54(%rsp), %eax
addq $0x58, %rsp
retq
nopl (%rax,%rax)