// File: phillip-h[P]fractal-gen/lodepng.cpp
// Function: filter(unsigned char*, unsigned char const*, unsigned int, unsigned int, LodePNGColorMode const*, LodePNGEncoderSettings const*)
static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h,
                       const LodePNGColorMode* info, const LodePNGEncoderSettings* settings)
{
  /*
  For PNG filter method 0
  out must be a buffer with as size: h + (w * h * bpp + 7) / 8, because there are
  the scanlines with 1 extra byte per scanline
  */

  unsigned bpp = lodepng_get_bpp(info);
  /*the width of a scanline in bytes, not including the filter type*/
  size_t linebytes = (w * bpp + 7) / 8;
  /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/
  size_t bytewidth = (bpp + 7) / 8;
  const unsigned char* prevline = 0;
  unsigned x, y;
  unsigned error = 0;
  LodePNGFilterStrategy strategy = settings->filter_strategy;

  /*
  There is a heuristic called the minimum sum of absolute differences heuristic, suggested by the PNG standard:
   *  If the image type is Palette, or the bit depth is smaller than 8, then do not filter the image (i.e.
      use fixed filtering, with the filter None).
   * (The other case) If the image type is Grayscale or RGB (with or without Alpha), and the bit depth is
     not smaller than 8, then use adaptive filtering heuristic as follows: independently for each row, apply
     all five filters and select the filter that produces the smallest sum of absolute values per row.
  This heuristic is used if filter strategy is LFS_MINSUM and filter_palette_zero is true.

  If filter_palette_zero is true and filter_strategy is not LFS_MINSUM, the above heuristic is followed,
  but for "the other case", whatever strategy filter_strategy is set to instead of the minimum sum
  heuristic is used.
  */
  if(settings->filter_palette_zero &&
     (info->colortype == LCT_PALETTE || info->bitdepth < 8)) strategy = LFS_ZERO;

  if(bpp == 0) return 31; /*error: invalid color type*/

  if(strategy == LFS_ZERO)
  {
    for(y = 0; y != h; ++y)
    {
      size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
      size_t inindex = linebytes * y;
      out[outindex] = 0; /*filter type byte*/
      filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, 0);
      prevline = &in[inindex];
    }
  }
  else if(strategy == LFS_MINSUM)
  {
    /*adaptive filtering*/
    size_t sum[5];
    unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/
    size_t smallest = 0;
    unsigned char type, bestType = 0;

    for(type = 0; type != 5; ++type)
    {
      attempt[type] = (unsigned char*)lodepng_malloc(linebytes);
      if(!attempt[type]) return 83; /*alloc fail*/
    }

    if(!error)
    {
      for(y = 0; y != h; ++y)
      {
        /*try the 5 filter types*/
        for(type = 0; type != 5; ++type)
        {
          filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type);

          /*calculate the sum of the result*/
          sum[type] = 0;
          if(type == 0)
          {
            for(x = 0; x != linebytes; ++x) sum[type] += (unsigned char)(attempt[type][x]);
          }
          else
          {
            for(x = 0; x != linebytes; ++x)
            {
              /*For differences, each byte should be treated as signed, values above 127 are negative
              (converted to signed char). Filtertype 0 isn't a difference though, so use unsigned there.
              This means filtertype 0 is almost never chosen, but that is justified.*/
              unsigned char s = attempt[type][x];
              sum[type] += s < 128 ? s : (255U - s);
            }
          }

          /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/
          if(type == 0 || sum[type] < smallest)
          {
            bestType = type;
            smallest = sum[type];
          }
        }

        prevline = &in[y * linebytes];

        /*now fill the out values*/
        out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
        for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x];
      }
    }

    for(type = 0; type != 5; ++type) lodepng_free(attempt[type]);
  }
  else if(strategy == LFS_ENTROPY)
  {
    float sum[5];
    unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/
    float smallest = 0;
    unsigned type, bestType = 0;
    unsigned count[256];

    for(type = 0; type != 5; ++type)
    {
      attempt[type] = (unsigned char*)lodepng_malloc(linebytes);
      if(!attempt[type]) return 83; /*alloc fail*/
    }

    for(y = 0; y != h; ++y)
    {
      /*try the 5 filter types*/
      for(type = 0; type != 5; ++type)
      {
        filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type);
        for(x = 0; x != 256; ++x) count[x] = 0;
        for(x = 0; x != linebytes; ++x) ++count[attempt[type][x]];
        ++count[type]; /*the filter type itself is part of the scanline*/
        sum[type] = 0;
        for(x = 0; x != 256; ++x)
        {
          float p = count[x] / (float)(linebytes + 1);
          sum[type] += count[x] == 0 ? 0 : flog2(1 / p) * p;
        }
        /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/
        if(type == 0 || sum[type] < smallest)
        {
          bestType = type;
          smallest = sum[type];
        }
      }

      prevline = &in[y * linebytes];

      /*now fill the out values*/
      out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
      for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x];
    }

    for(type = 0; type != 5; ++type) lodepng_free(attempt[type]);
  }
  else if(strategy == LFS_PREDEFINED)
  {
    for(y = 0; y != h; ++y)
    {
      size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
      size_t inindex = linebytes * y;
      unsigned char type = settings->predefined_filters[y];
      out[outindex] = type; /*filter type byte*/
      filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type);
      prevline = &in[inindex];
    }
  }
  else if(strategy == LFS_BRUTE_FORCE)
  {
    /*brute force filter chooser.
    deflate the scanline after every filter attempt to see which one deflates best.
    This is very slow and gives only slightly smaller, sometimes even larger, result*/
    size_t size[5];
    unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/
    size_t smallest = 0;
    unsigned type = 0, bestType = 0;
    unsigned char* dummy;
    LodePNGCompressSettings zlibsettings = settings->zlibsettings;
    /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose,
    to simulate the true case where the tree is the same for the whole image. Sometimes it gives
    better result with dynamic tree anyway. Using the fixed tree sometimes gives worse, but in rare
    cases better compression. It does make this a bit less slow, so it's worth doing this.*/
    zlibsettings.btype = 1;
    /*a custom encoder likely doesn't read the btype setting and is optimized for complete PNG
    images only, so disable it*/
    zlibsettings.custom_zlib = 0;
    zlibsettings.custom_deflate = 0;
    for(type = 0; type != 5; ++type)
    {
      attempt[type] = (unsigned char*)lodepng_malloc(linebytes);
      if(!attempt[type]) return 83; /*alloc fail*/
    }
    for(y = 0; y != h; ++y) /*try the 5 filter types*/
    {
      for(type = 0; type != 5; ++type)
      {
        unsigned testsize = linebytes;
        /*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/

        filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type);
        size[type] = 0;
        dummy = 0;
        zlib_compress(&dummy, &size[type], attempt[type], testsize, &zlibsettings);
        lodepng_free(dummy);
        /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/
        if(type == 0 || size[type] < smallest)
        {
          bestType = type;
          smallest = size[type];
        }
      }
      prevline = &in[y * linebytes];
      out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
      for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x];
    }
    for(type = 0; type != 5; ++type) lodepng_free(attempt[type]);
  }
  else return 88; /* unknown filter strategy */

  return error;
}

// Assembly:
subq $0x608, %rsp            # imm = 0x608
movq %rdi, 0x5f8(%rsp)
movq %rsi, 0x5f0(%rsp)
movl %edx, 0x5ec(%rsp)
movl %ecx, 0x5e8(%rsp)
movq %r8, 0x5e0(%rsp)
movq %r9, 0x5d8(%rsp)
movq 0x5e0(%rsp), %rdi
callq 0x8cd0
movl %eax, 0x5d4(%rsp)
movl 0x5ec(%rsp), %eax
imull 0x5d4(%rsp), %eax
addl $0x7, %eax
shrl $0x3, %eax
movl %eax, %eax
movq %rax, 0x5c8(%rsp)
movl 0x5d4(%rsp), %eax
addl $0x7, %eax
shrl $0x3, %eax
movl %eax, %eax
movq %rax, 0x5c0(%rsp)
movq $0x0, 0x5b8(%rsp)
movl $0x0, 0x5ac(%rsp)
movq 0x5d8(%rsp), %rax
movl 0x38(%rax), %eax
movl %eax, 0x5a8(%rsp)
movq 0x5d8(%rsp), %rax
cmpl $0x0, 0x34(%rax)
je 0x1856c
movq 0x5e0(%rsp), %rax
cmpl $0x3, (%rax)
je 0x18561
movq 0x5e0(%rsp), %rax
cmpl $0x8, 0x4(%rax)
jae 0x1856c
movl $0x0, 0x5a8(%rsp)
cmpl $0x0, 0x5d4(%rsp)
jne 0x18586
movl $0x1f, 0x604(%rsp)
jmp 0x1928a
cmpl $0x0, 0x5a8(%rsp)
jne 0x1867b
movl $0x0, 0x5b0(%rsp)
movl 0x5b0(%rsp), %eax
cmpl 0x5e8(%rsp), %eax
je 0x18676
movq 0x5c8(%rsp), %rax
addq $0x1, %rax
movl 0x5b0(%rsp), %ecx
imulq %rcx, %rax
movq %rax, 0x5a0(%rsp)
movq 0x5c8(%rsp), %rax
movl 0x5b0(%rsp), %ecx
imulq %rcx, %rax
movq %rax, 0x598(%rsp)
movq 0x5f8(%rsp), %rax
movq 0x5a0(%rsp), %rcx
movb $0x0, (%rax,%rcx)
movq 0x5f8(%rsp), %rdi
movq 0x5a0(%rsp), %rax
addq $0x1, %rax
addq %rax, %rdi
movq 0x5f0(%rsp), %rsi
addq 0x598(%rsp), %rsi
movq 0x5b8(%rsp), %rdx
movq 0x5c8(%rsp), %rcx
movq 0x5c0(%rsp), %r8
xorl %r9d, %r9d
callq 0x19640
movq 0x5f0(%rsp), %rax
addq 0x598(%rsp), %rax
movq %rax, 0x5b8(%rsp)
movl 0x5b0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5b0(%rsp)
jmp 0x1859f
jmp 0x1927c
cmpl $0x1, 0x5a8(%rsp)
jne 0x18a57
movq $0x0, 0x538(%rsp)
movb $0x0, 0x536(%rsp)
movb $0x0, 0x537(%rsp)
movzbl 0x537(%rsp), %eax
cmpl $0x5, %eax
je 0x18709
movq 0x5c8(%rsp), %rdi
callq 0x6cd0
movq %rax, %rcx
movzbl 0x537(%rsp), %eax
movq %rcx, 0x540(%rsp,%rax,8)
movzbl 0x537(%rsp), %eax
cmpq $0x0, 0x540(%rsp,%rax,8)
jne 0x186f5
movl $0x53, 0x604(%rsp)
jmp 0x1928a
jmp 0x186f7
movb 0x537(%rsp), %al
addb $0x1, %al
movb %al, 0x537(%rsp)
jmp 0x186a5
cmpl $0x0, 0x5ac(%rsp)
jne 0x18a16
movl $0x0, 0x5b0(%rsp)
movl 0x5b0(%rsp), %eax
cmpl 0x5e8(%rsp), %eax
je 0x18a14
movb $0x0, 0x537(%rsp)
movzbl 0x537(%rsp), %eax
cmpl $0x5, %eax
je 0x18937
movzbl 0x537(%rsp), %eax
movq 0x540(%rsp,%rax,8), %rdi
movq 0x5f0(%rsp), %rsi
movl 0x5b0(%rsp), %eax
imulq 0x5c8(%rsp), %rax
addq %rax, %rsi
movq 0x5b8(%rsp), %rdx
movq 0x5c8(%rsp), %rcx
movq 0x5c0(%rsp), %r8
movzbl 0x537(%rsp), %r9d
callq 0x19640
movzbl 0x537(%rsp), %eax
movq $0x0, 0x570(%rsp,%rax,8)
movzbl 0x537(%rsp), %eax
cmpl $0x0, %eax
jne 0x1882a
movl $0x0, 0x5b4(%rsp)
movl 0x5b4(%rsp), %eax
cmpq 0x5c8(%rsp), %rax
je 0x18825
movzbl 0x537(%rsp), %eax
movq 0x540(%rsp,%rax,8), %rax
movl 0x5b4(%rsp), %ecx
movzbl (%rax,%rcx), %eax
movl %eax, %ecx
movzbl 0x537(%rsp), %eax
addq 0x570(%rsp,%rax,8), %rcx
movq %rcx, 0x570(%rsp,%rax,8)
movl 0x5b4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5b4(%rsp)
jmp 0x187cc
jmp 0x188d3
movl $0x0, 0x5b4(%rsp)
movl 0x5b4(%rsp), %eax
cmpq 0x5c8(%rsp), %rax
je 0x188d1
movzbl 0x537(%rsp), %eax
movq 0x540(%rsp,%rax,8), %rax
movl 0x5b4(%rsp), %ecx
movb (%rax,%rcx), %al
movb %al, 0x535(%rsp)
movzbl 0x535(%rsp), %eax
cmpl $0x80, %eax
jge 0x18888
movzbl 0x535(%rsp), %eax
movl %eax, 0x10(%rsp)
jmp 0x1889b
movzbl 0x535(%rsp), %ecx
movl $0xff, %eax
subl %ecx, %eax
movl %eax, 0x10(%rsp)
movl 0x10(%rsp), %eax
movl %eax, %eax
movl %eax, %ecx
movzbl 0x537(%rsp), %eax
addq 0x570(%rsp,%rax,8), %rcx
movq %rcx, 0x570(%rsp,%rax,8)
movl 0x5b4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5b4(%rsp)
jmp 0x18835
jmp 0x188d3
movzbl 0x537(%rsp), %eax
cmpl $0x0, %eax
je 0x188fa
movzbl 0x537(%rsp), %eax
movq 0x570(%rsp,%rax,8), %rax
cmpq 0x538(%rsp), %rax
jae 0x18920
movb 0x537(%rsp), %al
movb %al, 0x536(%rsp)
movzbl 0x537(%rsp), %eax
movq 0x570(%rsp,%rax,8), %rax
movq %rax, 0x538(%rsp)
jmp 0x18922
movb 0x537(%rsp), %al
addb $0x1, %al
movb %al, 0x537(%rsp)
jmp 0x1873e
movq 0x5f0(%rsp), %rax
movl 0x5b0(%rsp), %ecx
imulq 0x5c8(%rsp), %rcx
addq %rcx, %rax
movq %rax, 0x5b8(%rsp)
movb 0x536(%rsp), %dl
movq 0x5f8(%rsp), %rax
movl 0x5b0(%rsp), %ecx
movq 0x5c8(%rsp), %rsi
addq $0x1, %rsi
imulq %rsi, %rcx
movb %dl, (%rax,%rcx)
movl $0x0, 0x5b4(%rsp)
movl 0x5b4(%rsp), %eax
cmpq 0x5c8(%rsp), %rax
je 0x189fc
movzbl 0x536(%rsp), %eax
movq 0x540(%rsp,%rax,8), %rax
movl 0x5b4(%rsp), %ecx
movb (%rax,%rcx), %dl
movq 0x5f8(%rsp), %rax
movl 0x5b0(%rsp), %ecx
movq 0x5c8(%rsp), %rsi
addq $0x1, %rsi
imulq %rsi, %rcx
addq $0x1, %rcx
movl 0x5b4(%rsp), %esi
addq %rsi, %rcx
movb %dl, (%rax,%rcx)
movl 0x5b4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5b4(%rsp)
jmp 0x1898e
jmp 0x189fe
movl 0x5b0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5b0(%rsp)
jmp 0x18722
jmp 0x18a16
movb $0x0, 0x537(%rsp)
movzbl 0x537(%rsp), %eax
cmpl $0x5, %eax
je 0x18a52
movzbl 0x537(%rsp), %eax
movq 0x540(%rsp,%rax,8), %rdi
callq 0x78b0
movb 0x537(%rsp), %al
addb $0x1, %al
movb %al, 0x537(%rsp)
jmp 0x18a1e
jmp 0x1927a
cmpl $0x2, 0x5a8(%rsp)
jne 0x18e7d
vpxor %xmm0, %xmm0, %xmm0
vmovss %xmm0, 0x4ec(%rsp)
movl $0x0, 0x4e4(%rsp)
movl $0x0, 0x4e8(%rsp)
cmpl $0x5, 0x4e8(%rsp)
je 0x18ae8
movq 0x5c8(%rsp), %rdi
callq 0x6cd0
movq %rax, %rcx
movl 0x4e8(%rsp), %eax
movq %rcx, 0x4f0(%rsp,%rax,8)
movl 0x4e8(%rsp), %eax
cmpq $0x0, 0x4f0(%rsp,%rax,8)
jne 0x18ad3
movl $0x53, 0x604(%rsp)
jmp 0x1928a
jmp 0x18ad5
movl 0x4e8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4e8(%rsp)
jmp 0x18a88
movl $0x0, 0x5b0(%rsp)
movl 0x5b0(%rsp), %eax
cmpl 0x5e8(%rsp), %eax
je 0x18e3c
movl $0x0, 0x4e8(%rsp)
cmpl $0x5, 0x4e8(%rsp)
je 0x18d5e
movl 0x4e8(%rsp), %eax
movq 0x4f0(%rsp,%rax,8), %rdi
movq 0x5f0(%rsp), %rsi
movl 0x5b0(%rsp), %eax
imulq 0x5c8(%rsp), %rax
addq %rax, %rsi
movq 0x5b8(%rsp), %rdx
movq 0x5c8(%rsp), %rcx
movq 0x5c0(%rsp), %r8
movl 0x4e8(%rsp), %eax
movzbl %al, %r9d
callq 0x19640
movl $0x0, 0x5b4(%rsp)
cmpl $0x100, 0x5b4(%rsp) # imm = 0x100
je 0x18baf
movl 0x5b4(%rsp), %eax
movl $0x0, 0xe0(%rsp,%rax,4)
movl 0x5b4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5b4(%rsp)
jmp 0x18b7d
movl $0x0, 0x5b4(%rsp)
movl 0x5b4(%rsp), %eax
cmpq 0x5c8(%rsp), %rax
je 0x18c09
movl 0x4e8(%rsp), %eax
movq 0x4f0(%rsp,%rax,8), %rax
movl 0x5b4(%rsp), %ecx
movzbl (%rax,%rcx), %eax
movl 0xe0(%rsp,%rax,4), %ecx
addl $0x1, %ecx
movl %ecx, 0xe0(%rsp,%rax,4)
movl 0x5b4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5b4(%rsp)
jmp 0x18bba
movl 0x4e8(%rsp), %eax
movl 0xe0(%rsp,%rax,4), %ecx
addl $0x1, %ecx
movl %ecx, 0xe0(%rsp,%rax,4)
movl 0x4e8(%rsp), %eax
vpxor %xmm0, %xmm0, %xmm0
vmovss %xmm0, 0x520(%rsp,%rax,4)
movl $0x0, 0x5b4(%rsp)
cmpl $0x100, 0x5b4(%rsp) # imm = 0x100
je 0x18cf6
movl 0x5b4(%rsp), %eax
vcvtusi2ssl 0xe0(%rsp,%rax,4), %xmm0, %xmm0
movq 0x5c8(%rsp), %rax
addq $0x1, %rax
vcvtusi2ss %rax, %xmm1, %xmm1
vdivss %xmm1, %xmm0, %xmm0
vmovss %xmm0, 0xdc(%rsp)
movl 0x5b4(%rsp), %eax
cmpl $0x0, 0xe0(%rsp,%rax,4)
jne 0x18c9c
vpxor %xmm0, %xmm0, %xmm0
vmovss %xmm0, 0xc(%rsp)
jmp 0x18cc1
vmovss 0x3ba8(%rip), %xmm0     # 0x1c84c
vdivss 0xdc(%rsp), %xmm0, %xmm0
callq 0x19b30
vmulss 0xdc(%rsp), %xmm0, %xmm0
vmovss %xmm0, 0xc(%rsp)
vmovss 0xc(%rsp), %xmm0
movl 0x4e8(%rsp), %eax
vaddss 0x520(%rsp,%rax,4), %xmm0, %xmm0
vmovss %xmm0, 0x520(%rsp,%rax,4)
movl 0x5b4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5b4(%rsp)
jmp 0x18c40
cmpl $0x0, 0x4e8(%rsp)
je 0x18d1f
movl 0x4e8(%rsp), %eax
vmovss 0x520(%rsp,%rax,4), %xmm1
vmovss 0x4ec(%rsp), %xmm0
vucomiss %xmm1, %xmm0
jbe 0x18d46
movl 0x4e8(%rsp), %eax
movl %eax, 0x4e4(%rsp)
movl 0x4e8(%rsp), %eax
vmovss 0x520(%rsp,%rax,4), %xmm0
vmovss %xmm0, 0x4ec(%rsp)
jmp 0x18d48
movl 0x4e8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4e8(%rsp)
jmp 0x18b12
movq 0x5f0(%rsp), %rax
movl 0x5b0(%rsp), %ecx
imulq 0x5c8(%rsp), %rcx
addq %rcx, %rax
movq %rax, 0x5b8(%rsp)
movl 0x4e4(%rsp), %eax
movb %al, %dl
movq 0x5f8(%rsp), %rax
movl 0x5b0(%rsp), %ecx
movq 0x5c8(%rsp), %rsi
addq $0x1, %rsi
imulq %rsi, %rcx
movb %dl, (%rax,%rcx)
movl $0x0, 0x5b4(%rsp)
movl 0x5b4(%rsp), %eax
cmpq 0x5c8(%rsp), %rax
je 0x18e24
movl 0x4e4(%rsp), %eax
movq 0x4f0(%rsp,%rax,8), %rax
movl 0x5b4(%rsp), %ecx
movb (%rax,%rcx), %dl
movq 0x5f8(%rsp), %rax
movl 0x5b0(%rsp), %ecx
movq 0x5c8(%rsp), %rsi
addq $0x1, %rsi
imulq %rsi, %rcx
addq $0x1, %rcx
movl 0x5b4(%rsp), %esi
addq %rsi, %rcx
movb %dl, (%rax,%rcx)
movl 0x5b4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5b4(%rsp)
jmp 0x18db7
jmp 0x18e26
movl 0x5b0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5b0(%rsp)
jmp 0x18af3
movl $0x0, 0x4e8(%rsp)
cmpl $0x5, 0x4e8(%rsp)
je 0x18e78
movl 0x4e8(%rsp), %eax
movq 0x4f0(%rsp,%rax,8), %rdi
callq 0x78b0
movl 0x4e8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4e8(%rsp)
jmp 0x18e47
jmp 0x19278
cmpl $0x4, 0x5a8(%rsp)
jne 0x18f9b
movl $0x0, 0x5b0(%rsp)
movl 0x5b0(%rsp), %eax
cmpl 0x5e8(%rsp), %eax
je 0x18f96
movq 0x5c8(%rsp), %rax
addq $0x1, %rax
movl 0x5b0(%rsp), %ecx
imulq %rcx, %rax
movq %rax, 0xd0(%rsp)
movq 0x5c8(%rsp), %rax
movl 0x5b0(%rsp), %ecx
imulq %rcx, %rax
movq %rax, 0xc8(%rsp)
movq 0x5d8(%rsp), %rax
movq 0x40(%rax), %rax
movl 0x5b0(%rsp), %ecx
movb (%rax,%rcx), %al
movb %al, 0xc7(%rsp)
movb 0xc7(%rsp), %dl
movq 0x5f8(%rsp), %rax
movq 0xd0(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x5f8(%rsp), %rdi
movq 0xd0(%rsp), %rax
addq $0x1, %rax
addq %rax, %rdi
movq 0x5f0(%rsp), %rsi
addq 0xc8(%rsp), %rsi
movq 0x5b8(%rsp), %rdx
movq 0x5c8(%rsp), %rcx
movq 0x5c0(%rsp), %r8
movzbl 0xc7(%rsp), %r9d
callq 0x19640
movq 0x5f0(%rsp), %rax
addq 0xc8(%rsp), %rax
movq %rax, 0x5b8(%rsp)
movl 0x5b0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5b0(%rsp)
jmp 0x18e96
jmp 0x19276
cmpl $0x3, 0x5a8(%rsp)
jne 0x19267
movq $0x0, 0x58(%rsp)
movl $0x0, 0x54(%rsp)
movl $0x0, 0x50(%rsp)
movq 0x5d8(%rsp), %rsi
leaq 0x18(%rsp), %rdi
movl $0x30, %edx
callq 0x3170
movl $0x1, 0x18(%rsp)
movq $0x0, 0x30(%rsp)
movq $0x0, 0x38(%rsp)
movl $0x0, 0x54(%rsp)
cmpl $0x5, 0x54(%rsp)
je 0x19046
movq 0x5c8(%rsp), %rdi
callq 0x6cd0
movq %rax, %rcx
movl 0x54(%rsp), %eax
movq %rcx, 0x60(%rsp,%rax,8)
movl 0x54(%rsp), %eax
cmpq $0x0, 0x60(%rsp,%rax,8)
jne 0x19037
movl $0x53, 0x604(%rsp)
jmp 0x1928a
jmp 0x19039
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
jmp 0x18ffb
movl $0x0, 0x5b0(%rsp)
movl 0x5b0(%rsp), %eax
cmpl 0x5e8(%rsp), %eax
je 0x1923b
movl $0x0, 0x54(%rsp)
cmpl $0x5, 0x54(%rsp)
je 0x19166
movq 0x5c8(%rsp), %rax
movl %eax, 0x14(%rsp)
movl 0x54(%rsp), %eax
movq 0x60(%rsp,%rax,8), %rdi
movq 0x5f0(%rsp), %rsi
movl 0x5b0(%rsp), %eax
imulq 0x5c8(%rsp), %rax
addq %rax, %rsi
movq 0x5b8(%rsp), %rdx
movq 0x5c8(%rsp), %rcx
movq 0x5c0(%rsp), %r8
movl 0x54(%rsp), %eax
movzbl %al, %r9d
callq 0x19640
movl 0x54(%rsp), %eax
movq $0x0, 0x90(%rsp,%rax,8)
movq $0x0, 0x48(%rsp)
movl 0x54(%rsp), %eax
leaq 0x90(%rsp), %rsi
shlq $0x3, %rax
addq %rax, %rsi
movl 0x54(%rsp), %eax
movq 0x60(%rsp,%rax,8), %rdx
movl 0x14(%rsp), %eax
movl %eax, %ecx
leaq 0x48(%rsp), %rdi
leaq 0x18(%rsp), %r8
callq 0x110c0
movq 0x48(%rsp), %rdi
callq 0x78b0
cmpl $0x0, 0x54(%rsp)
je 0x1913b
movl 0x54(%rsp), %eax
movq 0x90(%rsp,%rax,8), %rax
cmpq 0x58(%rsp), %rax
jae 0x19154
movl 0x54(%rsp), %eax
movl %eax, 0x50(%rsp)
movl 0x54(%rsp), %eax
movq 0x90(%rsp,%rax,8), %rax
movq %rax, 0x58(%rsp)
jmp 0x19156
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
jmp 0x1906d
movq 0x5f0(%rsp), %rax
movl 0x5b0(%rsp), %ecx
imulq 0x5c8(%rsp), %rcx
addq %rcx, %rax
movq %rax, 0x5b8(%rsp)
movl 0x50(%rsp), %eax
movb %al, %dl
movq 0x5f8(%rsp), %rax
movl 0x5b0(%rsp), %ecx
movq 0x5c8(%rsp), %rsi
addq $0x1, %rsi
imulq %rsi, %rcx
movb %dl, (%rax,%rcx)
movl $0x0, 0x5b4(%rsp)
movl 0x5b4(%rsp), %eax
cmpq 0x5c8(%rsp), %rax
je 0x19223
movl 0x50(%rsp), %eax
movq 0x60(%rsp,%rax,8), %rax
movl 0x5b4(%rsp), %ecx
movb (%rax,%rcx), %dl
movq 0x5f8(%rsp), %rax
movl 0x5b0(%rsp), %ecx
movq 0x5c8(%rsp), %rsi
addq $0x1, %rsi
imulq %rsi, %rcx
addq $0x1, %rcx
movl 0x5b4(%rsp), %esi
addq %rsi, %rcx
movb %dl, (%rax,%rcx)
movl 0x5b4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5b4(%rsp)
jmp 0x191bc
jmp 0x19225
movl 0x5b0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5b0(%rsp)
jmp 0x19051
movl $0x0, 0x54(%rsp)
cmpl $0x5, 0x54(%rsp)
je 0x19265
movl 0x54(%rsp), %eax
movq 0x60(%rsp,%rax,8), %rdi
callq 0x78b0
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
jmp 0x19243
jmp 0x19274
movl $0x58, 0x604(%rsp)
jmp 0x1928a
jmp 0x19276
jmp 0x19278
jmp 0x1927a
jmp 0x1927c
movl 0x5ac(%rsp), %eax
movl %eax, 0x604(%rsp)
movl 0x604(%rsp), %eax
addq $0x608, %rsp            # imm = 0x608
retq
nopl (%rax)