// File: cloudinary[P]fuif/./export/write_png.h
// Function: write_PNG_file(char const*, Image const&)
bool write_PNG_file(const char *output_image, const Image &image) {

  int nb_channels = image.channel.size();
  bool debugstuff = false;

  if (nb_channels > ((image.colormodel & 48) == 16 ? 5 : 4)) {
    e_printf("Too many channels. Saving just the first 3 channels (instead of %i)\n",nb_channels);
    nb_channels = 3; // just use the first 3. debug stuff
    debugstuff = true;
  }
  if (nb_channels == 0) {
    e_printf("Cannot save a zero-channel 'image' as PNG.\n");
    return false;
  }


  int w = image.channel[0].w;
  int h = image.channel[0].h;
  if (image.w < w) w = image.w;
  if (image.h < h) h = image.h;
  for (int i=1; i<nb_channels; i++) {
    if (image.channel[i].w < w) nb_channels = 1;
    if (image.channel[i].h < h) nb_channels = 1;
    if (nb_channels == 1) e_printf("Not saving channel %i since dimensions (%ix%i) do not correspond with the image dimensions (%ix%i).\n",i,image.channel[i].w,image.channel[i].h,w,h);
  }

  if (nb_channels > image.nb_channels) {debugstuff=true; nb_channels=1;}

  if (w > 0x7fffffffL || h > 0x7fffffffL) {
    printf("Image too large to be saved as PNG.\n");
    return false;
  }

  FILE *fp = fopen(output_image,"wb");
  if (!fp) {
    return false;
  }
  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,(png_voidp) NULL,NULL,NULL);
  if (!png_ptr) {
    fclose(fp);
    return false;
  }

  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    png_destroy_write_struct(&png_ptr,(png_infopp) NULL);
    fclose(fp);
    return false;
  }

  png_init_io(png_ptr,fp);
  png_set_user_limits(png_ptr, 0x7fffffffL, 0x7fffffffL);
//  png_set_filter(png_ptr,0,PNG_FILTER_PAETH);
//  png_set_compression_level(png_ptr,Z_BEST_COMPRESSION);


  int colortype=PNG_COLOR_TYPE_RGB;
  bool cmyk = false;
  if ((image.colormodel & 48) == 0) { // RGB
    if (nb_channels == 4) colortype=PNG_COLOR_TYPE_RGB_ALPHA;
  } else if ((image.colormodel & 48) == 16) { // CMYK
    if (nb_channels == 5) colortype=PNG_COLOR_TYPE_RGB_ALPHA;
    if (nb_channels > 3) cmyk = true;
  }

  if (nb_channels == 1) colortype=PNG_COLOR_TYPE_GRAY;
  if (nb_channels == 2) colortype=PNG_COLOR_TYPE_GRAY_ALPHA;
  int bit_depth = 8, bytes_per_value=1;
  if (image.channel[0].minval < 0) {bit_depth = 8; bytes_per_value=1;} // this is just for debugging things

  if (image.maxval > 255) {bit_depth = 16; bytes_per_value=2;}
  if (image.maxval > 65535) { e_printf("Cannot save as PNG since bit depth is higher than 16-bit.\n");    return false; }

  if (image.channel[0].maxval > 255 && debugstuff && nb_channels == 1) {colortype=PNG_COLOR_TYPE_RGB; nb_channels=3;}

  int shift = 0;
//  if (image.channel[0].maxval == 2048) shift = 5;  // could use something like this to debug DCT values

  png_set_IHDR(png_ptr,info_ptr,w,h,bit_depth,colortype,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

  png_write_info(png_ptr,info_ptr);

  png_bytep row = (png_bytep) png_malloc(png_ptr,nb_channels * bytes_per_value * w);

  v_printf(10,"Writing PNG file (range %i..%i)\n",image.minval,image.maxval);
  if (image.channel[0].maxval > 255 && debugstuff) {
    v_printf(10,"Writing PNG file with false colors for debug purposes\n");
    for (size_t r = 0; r < (size_t) h; r++) {
     for (size_t c = 0; c < (size_t) w; c++) {
        row[c * 3 + 0] = (png_byte) (CLAMP((image.channel[0].value(r,c)%10)*26,0,255));
        row[c * 3 + 1] = (png_byte) (CLAMP(image.channel[0].value(r,c)/10,0,255));
        row[c * 3 + 2] = (png_byte) (CLAMP(image.channel[0].value(r,c)/500,0,255));
     }
     png_write_row(png_ptr,row);
    }
  } else if (false && image.channel[0].minval < 0) {
    v_printf(10,"Writing PNG file with negative pixels\n");
   // visualize the negative pixels somehow, for debugging.
   for (size_t r = 0; r < (size_t) h; r++) {
     for (size_t c = 0; c < (size_t) w; c++) {
      for (int p=0; p<nb_channels; p++) {
        row[c * nb_channels + p] = (png_byte) (CLAMP(127+(image.channel[p].value(r,c)),0,255));
      }
     }
    png_write_row(png_ptr,row);
    }
  } else if (cmyk) {
   v_printf(1,"Warning: converting CMYK image to RGB in order to save it as PNG.\n");
   for (size_t r = 0; r < (size_t) h; r++) {
     for (size_t c = 0; c < (size_t) w; c++) {
      for (int p=0; p<3; p++) {
        row[c * (nb_channels-1) + p] = (png_byte) (CLAMP( (255-image.channel[p].value(r,c))*(image.channel[3].value(r,c))/255,0,255));
      }
      if (nb_channels == 5) row[c * (nb_channels-1) + 3] = (png_byte) (CLAMP(image.channel[4].value(r,c),0,255)); // cmyk+alpha

     }
    png_write_row(png_ptr,row);
    }
  } else for (size_t r = 0; r < (size_t) h; r++) {
    if (bytes_per_value == 1) {
     for (size_t c = 0; c < (size_t) w; c++) {
      for (int p=0; p<nb_channels; p++) {
        row[c * nb_channels + p] = (png_byte) (CLAMP(image.channel[p].value(r,c),image.minval,image.maxval));
      }
     }
    } else {
     if (!debugstuff) {
     for (size_t c = 0; c < (size_t) w; c++) {
      for (int p=0; p<nb_channels; p++) {
        row[c * nb_channels * 2 + 2*p] = (png_byte) ((CLAMP(image.channel[p].value(r,c),image.minval,image.maxval)<<shift) >> 8);
        row[c * nb_channels * 2 + 2*p + 1] = (png_byte) ((CLAMP(image.channel[p].value(r,c),image.minval,image.maxval)<<shift) & 0xff);
      }
     }
     } else {
     for (size_t c = 0; c < (size_t) w; c++) {
      for (int p=0; p<nb_channels; p++) {
        row[c * nb_channels * 2 + 2*p] = (png_byte) ((image.channel[p].value(r,c)) >> 8);
        row[c * nb_channels * 2 + 2*p + 1] = (png_byte) ((image.channel[p].value(r,c)) & 0xff);
      }
     }
     }
    }
    png_write_row(png_ptr,row);
  }

  png_free(png_ptr,row);
  png_write_end(png_ptr,info_ptr);
  png_destroy_write_struct(&png_ptr,&info_ptr);
  fclose(fp);
  return 0;
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x128(%rsp)
movq %rsi, 0x120(%rsp)
movq 0x120(%rsp), %rdi
callq 0x4b80
movl %eax, 0x11c(%rsp)
movb $0x0, 0x11b(%rsp)
movl 0x11c(%rsp), %eax
movq 0x120(%rsp), %rcx
movl 0x70(%rcx), %esi
andl $0x30, %esi
movl $0x4, %ecx
movl $0x5, %edx
cmpl $0x10, %esi
cmovel %edx, %ecx
cmpl %ecx, %eax
jle 0x3e294
movl 0x11c(%rsp), %esi
leaq 0xa093(%rip), %rdi      # 0x4830d
movb $0x0, %al
callq 0x3a670
movl $0x3, 0x11c(%rsp)
movb $0x1, 0x11b(%rsp)
cmpl $0x0, 0x11c(%rsp)
jne 0x3e2b9
leaq 0xa0ad(%rip), %rdi      # 0x48352
movb $0x0, %al
callq 0x3a670
movb $0x0, 0x137(%rsp)
jmp 0x3f566
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movl 0x18(%rax), %eax
movl %eax, 0x114(%rsp)
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movl 0x1c(%rax), %eax
movl %eax, 0x110(%rsp)
movq 0x120(%rsp), %rax
movl 0x30(%rax), %eax
cmpl 0x114(%rsp), %eax
jge 0x3e315
movq 0x120(%rsp), %rax
movl 0x30(%rax), %eax
movl %eax, 0x114(%rsp)
movq 0x120(%rsp), %rax
movl 0x34(%rax), %eax
cmpl 0x110(%rsp), %eax
jge 0x3e33b
movq 0x120(%rsp), %rax
movl 0x34(%rax), %eax
movl %eax, 0x110(%rsp)
movl $0x1, 0x10c(%rsp)
movl 0x10c(%rsp), %eax
cmpl 0x11c(%rsp), %eax
jge 0x3e439
movq 0x120(%rsp), %rdi
movslq 0x10c(%rsp), %rsi
callq 0x13390
movl 0x18(%rax), %eax
cmpl 0x114(%rsp), %eax
jge 0x3e386
movl $0x1, 0x11c(%rsp)
movq 0x120(%rsp), %rdi
movslq 0x10c(%rsp), %rsi
callq 0x13390
movl 0x1c(%rax), %eax
cmpl 0x110(%rsp), %eax
jge 0x3e3b2
movl $0x1, 0x11c(%rsp)
cmpl $0x1, 0x11c(%rsp)
jne 0x3e421
movl 0x10c(%rsp), %eax
movl %eax, 0x6c(%rsp)
movq 0x120(%rsp), %rdi
movslq 0x10c(%rsp), %rsi
callq 0x13390
movl 0x18(%rax), %eax
movl %eax, 0x70(%rsp)
movq 0x120(%rsp), %rdi
movslq 0x10c(%rsp), %rsi
callq 0x13390
movl 0x6c(%rsp), %esi
movl 0x70(%rsp), %edx
movl 0x1c(%rax), %ecx
movl 0x114(%rsp), %r8d
movl 0x110(%rsp), %r9d
leaq 0x9f64(%rip), %rdi      # 0x4837e
movb $0x0, %al
callq 0x3a670
jmp 0x3e423
movl 0x10c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x10c(%rsp)
jmp 0x3e346
movl 0x11c(%rsp), %eax
movq 0x120(%rsp), %rcx
cmpl 0x64(%rcx), %eax
jle 0x3e460
movb $0x1, 0x11b(%rsp)
movl $0x1, 0x11c(%rsp)
movslq 0x114(%rsp), %rax
cmpq $0x7fffffff, %rax       # imm = 0x7FFFFFFF
jg 0x3e480
movslq 0x110(%rsp), %rax
cmpq $0x7fffffff, %rax       # imm = 0x7FFFFFFF
jle 0x3e49b
leaq 0x9f5c(%rip), %rdi      # 0x483e3
movb $0x0, %al
callq 0x3070
movb $0x0, 0x137(%rsp)
jmp 0x3f566
movq 0x128(%rsp), %rdi
leaq 0x94ad(%rip), %rsi      # 0x47957
callq 0x3460
movq %rax, 0x100(%rsp)
cmpq $0x0, 0x100(%rsp)
jne 0x3e4cf
movb $0x0, 0x137(%rsp)
jmp 0x3f566
leaq 0x9b7e(%rip), %rdi      # 0x48054
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rsi
movq %rcx, %rdx
callq 0x3130
movq %rax, 0xf8(%rsp)
cmpq $0x0, 0xf8(%rsp)
jne 0x3e512
movq 0x100(%rsp), %rdi
callq 0x3350
movb $0x0, 0x137(%rsp)
jmp 0x3f566
movq 0xf8(%rsp), %rdi
callq 0x3690
movq %rax, 0xf0(%rsp)
cmpq $0x0, 0xf0(%rsp)
jne 0x3e55d
leaq 0xf8(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x32c0
movq 0x100(%rsp), %rdi
callq 0x3350
movb $0x0, 0x137(%rsp)
jmp 0x3f566
movq 0xf8(%rsp), %rdi
movq 0x100(%rsp), %rsi
callq 0x36e0
movq 0xf8(%rsp), %rdi
movl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
movl %edx, %esi
callq 0x35a0
movl $0x2, 0xec(%rsp)
movb $0x0, 0xeb(%rsp)
movq 0x120(%rsp), %rax
movl 0x70(%rax), %eax
andl $0x30, %eax
cmpl $0x0, %eax
jne 0x3e5c3
cmpl $0x4, 0x11c(%rsp)
jne 0x3e5c1
movl $0x6, 0xec(%rsp)
jmp 0x3e601
movq 0x120(%rsp), %rax
movl 0x70(%rax), %eax
andl $0x30, %eax
cmpl $0x10, %eax
jne 0x3e5ff
cmpl $0x5, 0x11c(%rsp)
jne 0x3e5eb
movl $0x6, 0xec(%rsp)
cmpl $0x3, 0x11c(%rsp)
jle 0x3e5fd
movb $0x1, 0xeb(%rsp)
jmp 0x3e5ff
jmp 0x3e601
cmpl $0x1, 0x11c(%rsp)
jne 0x3e616
movl $0x0, 0xec(%rsp)
cmpl $0x2, 0x11c(%rsp)
jne 0x3e62b
movl $0x4, 0xec(%rsp)
movl $0x8, 0xe4(%rsp)
movl $0x1, 0xe0(%rsp)
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movswl 0x20(%rax), %eax
cmpl $0x0, %eax
jge 0x3e671
movl $0x8, 0xe4(%rsp)
movl $0x1, 0xe0(%rsp)
movq 0x120(%rsp), %rax
cmpl $0xff, 0x60(%rax)
jle 0x3e698
movl $0x10, 0xe4(%rsp)
movl $0x2, 0xe0(%rsp)
movq 0x120(%rsp), %rax
cmpl $0xffff, 0x60(%rax)     # imm = 0xFFFF
jle 0x3e6c4
leaq 0x9d58(%rip), %rdi      # 0x48408
movb $0x0, %al
callq 0x3a670
movb $0x0, 0x137(%rsp)
jmp 0x3f566
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movswl 0x22(%rax), %eax
cmpl $0xff, %eax
jle 0x3e70a
testb $0x1, 0x11b(%rsp)
je 0x3e70a
cmpl $0x1, 0x11c(%rsp)
jne 0x3e70a
movl $0x2, 0xec(%rsp)
movl $0x3, 0x11c(%rsp)
movl $0x0, 0xdc(%rsp)
movq 0xf8(%rsp), %rdi
movq 0xf0(%rsp), %rsi
movl 0x114(%rsp), %edx
movl 0x110(%rsp), %ecx
movl 0xe4(%rsp), %r8d
movl 0xec(%rsp), %r9d
xorl %eax, %eax
movl $0x0, (%rsp)
movl $0x0, 0x8(%rsp)
movl $0x0, 0x10(%rsp)
callq 0x3640
movq 0xf8(%rsp), %rdi
movq 0xf0(%rsp), %rsi
callq 0x3230
movq 0xf8(%rsp), %rdi
movl 0x11c(%rsp), %eax
imull 0xe0(%rsp), %eax
imull 0x114(%rsp), %eax
movslq %eax, %rsi
callq 0x3650
movq %rax, 0xd0(%rsp)
movq 0x120(%rsp), %rax
movl 0x5c(%rax), %edx
movq 0x120(%rsp), %rax
movl 0x60(%rax), %ecx
movl $0xa, %edi
leaq 0x9c7c(%rip), %rsi      # 0x48443
movb $0x0, %al
callq 0x3a770
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movswl 0x22(%rax), %eax
cmpl $0xff, %eax
jle 0x3eb6e
testb $0x1, 0x11b(%rsp)
je 0x3eb6e
movl $0xa, %edi
leaq 0x9c5c(%rip), %rsi      # 0x48464
movb $0x0, %al
callq 0x3a770
movq $0x0, 0xc8(%rsp)
movq 0xc8(%rsp), %rax
movslq 0x110(%rsp), %rcx
cmpq %rcx, %rax
jae 0x3eb69
movq $0x0, 0xc0(%rsp)
movq 0xc0(%rsp), %rax
movslq 0x114(%rsp), %rcx
cmpq %rcx, %rax
jae 0x3eb3b
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movq %rax, %rdi
movq 0xc8(%rsp), %rax
movl %eax, %esi
movq 0xc0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movl $0xa, %ecx
cltd
idivl %ecx
imull $0x1a, %edx, %eax
cmpl $0x0, %eax
jge 0x3e8a2
xorl %eax, %eax
movl %eax, 0x68(%rsp)
jmp 0x3e932
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movq %rax, %rdi
movq 0xc8(%rsp), %rax
movl %eax, %esi
movq 0xc0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movl $0xa, %ecx
cltd
idivl %ecx
imull $0x1a, %edx, %eax
cmpl $0xff, %eax
jle 0x3e8ed
movl $0xff, %eax
movl %eax, 0x64(%rsp)
jmp 0x3e92a
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movq %rax, %rdi
movq 0xc8(%rsp), %rax
movl %eax, %esi
movq 0xc0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movl $0xa, %ecx
cltd
idivl %ecx
imull $0x1a, %edx, %eax
movl %eax, 0x64(%rsp)
movl 0x64(%rsp), %eax
movl %eax, 0x68(%rsp)
movl 0x68(%rsp), %eax
movb %al, %dl
movq 0xd0(%rsp), %rax
imulq $0x3, 0xc0(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movq %rax, %rdi
movq 0xc8(%rsp), %rax
movl %eax, %esi
movq 0xc0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movl $0xa, %ecx
cltd
idivl %ecx
cmpl $0x0, %eax
jge 0x3e992
xorl %eax, %eax
movl %eax, 0x60(%rsp)
jmp 0x3ea1c
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movq %rax, %rdi
movq 0xc8(%rsp), %rax
movl %eax, %esi
movq 0xc0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movl $0xa, %ecx
cltd
idivl %ecx
cmpl $0xff, %eax
jle 0x3e9da
movl $0xff, %eax
movl %eax, 0x5c(%rsp)
jmp 0x3ea14
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movq %rax, %rdi
movq 0xc8(%rsp), %rax
movl %eax, %esi
movq 0xc0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movl $0xa, %ecx
cltd
idivl %ecx
movl %eax, 0x5c(%rsp)
movl 0x5c(%rsp), %eax
movl %eax, 0x60(%rsp)
movl 0x60(%rsp), %eax
movb %al, %dl
movq 0xd0(%rsp), %rax
imulq $0x3, 0xc0(%rsp), %rcx
movb %dl, 0x1(%rax,%rcx)
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movq %rax, %rdi
movq 0xc8(%rsp), %rax
movl %eax, %esi
movq 0xc0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movl $0x1f4, %ecx            # imm = 0x1F4
cltd
idivl %ecx
cmpl $0x0, %eax
jge 0x3ea7d
xorl %eax, %eax
movl %eax, 0x58(%rsp)
jmp 0x3eb07
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movq %rax, %rdi
movq 0xc8(%rsp), %rax
movl %eax, %esi
movq 0xc0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movl $0x1f4, %ecx            # imm = 0x1F4
cltd
idivl %ecx
cmpl $0xff, %eax
jle 0x3eac5
movl $0xff, %eax
movl %eax, 0x54(%rsp)
jmp 0x3eaff
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13390
movq %rax, %rdi
movq 0xc8(%rsp), %rax
movl %eax, %esi
movq 0xc0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movl $0x1f4, %ecx            # imm = 0x1F4
cltd
idivl %ecx
movl %eax, 0x54(%rsp)
movl 0x54(%rsp), %eax
movl %eax, 0x58(%rsp)
movl 0x58(%rsp), %eax
movb %al, %dl
movq 0xd0(%rsp), %rax
imulq $0x3, 0xc0(%rsp), %rcx
movb %dl, 0x2(%rax,%rcx)
movq 0xc0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xc0(%rsp)
jmp 0x3e840
movq 0xf8(%rsp), %rdi
movq 0xd0(%rsp), %rsi
callq 0x31d0
movq 0xc8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xc8(%rsp)
jmp 0x3e81b
jmp 0x3f512
testb $0x1, 0xeb(%rsp)
je 0x3ef33
movl $0x1, %edi
leaq 0x9913(%rip), %rsi      # 0x4849b
movb $0x0, %al
callq 0x3a770
movq $0x0, 0xb8(%rsp)
movq 0xb8(%rsp), %rax
movslq 0x110(%rsp), %rcx
cmpq %rcx, %rax
jae 0x3ef2e
movq $0x0, 0xb0(%rsp)
movq 0xb0(%rsp), %rax
movslq 0x114(%rsp), %rcx
cmpq %rcx, %rax
jae 0x3ef00
movl $0x0, 0xac(%rsp)
cmpl $0x3, 0xac(%rsp)
jge 0x3edf4
movq 0x120(%rsp), %rdi
movslq 0xac(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xb8(%rsp), %rax
movl %eax, %esi
movq 0xb0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
movswl %ax, %ecx
movl $0xff, %eax
subl %ecx, %eax
movl %eax, 0x50(%rsp)
movq 0x120(%rsp), %rdi
movl $0x3, %esi
callq 0x13390
movq %rax, %rdi
movq 0xb8(%rsp), %rax
movl %eax, %esi
movq 0xb0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
movw %ax, %cx
movl 0x50(%rsp), %eax
movswl %cx, %ecx
imull %ecx, %eax
movl $0xff, %ecx
cltd
idivl %ecx
cmpl $0x0, %eax
jge 0x3ec84
xorl %eax, %eax
movl %eax, 0x4c(%rsp)
jmp 0x3eda9
movq 0x120(%rsp), %rdi
movslq 0xac(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xb8(%rsp), %rax
movl %eax, %esi
movq 0xb0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
movswl %ax, %ecx
movl $0xff, %eax
subl %ecx, %eax
movl %eax, 0x48(%rsp)
movq 0x120(%rsp), %rdi
movl $0x3, %esi
callq 0x13390
movq %rax, %rdi
movq 0xb8(%rsp), %rax
movl %eax, %esi
movq 0xb0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
movw %ax, %cx
movl 0x48(%rsp), %eax
movswl %cx, %ecx
imull %ecx, %eax
movl $0xff, %ecx
cltd
idivl %ecx
cmpl $0xff, %eax
jle 0x3ed1b
movl $0xff, %eax
movl %eax, 0x44(%rsp)
jmp 0x3eda1
movq 0x120(%rsp), %rdi
movslq 0xac(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xb8(%rsp), %rax
movl %eax, %esi
movq 0xb0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
movswl %ax, %ecx
movl $0xff, %eax
subl %ecx, %eax
movl %eax, 0x40(%rsp)
movq 0x120(%rsp), %rdi
movl $0x3, %esi
callq 0x13390
movq %rax, %rdi
movq 0xb8(%rsp), %rax
movl %eax, %esi
movq 0xb0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
movw %ax, %cx
movl 0x40(%rsp), %eax
movswl %cx, %ecx
imull %ecx, %eax
movl $0xff, %ecx
cltd
idivl %ecx
movl %eax, 0x44(%rsp)
movl 0x44(%rsp), %eax
movl %eax, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
movb %al, %dl
movq 0xd0(%rsp), %rax
movq 0xb0(%rsp), %rcx
movl 0x11c(%rsp), %esi
subl $0x1, %esi
movslq %esi, %rsi
imulq %rsi, %rcx
movslq 0xac(%rsp), %rsi
addq %rsi, %rcx
movb %dl, (%rax,%rcx)
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0x3ebe4
cmpl $0x5, 0x11c(%rsp)
jne 0x3eee5
movq 0x120(%rsp), %rdi
movl $0x4, %esi
callq 0x13390
movq %rax, %rdi
movq 0xb8(%rsp), %rax
movl %eax, %esi
movq 0xb0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
cmpl $0x0, %eax
jge 0x3ee3e
xorl %eax, %eax
movl %eax, 0x3c(%rsp)
jmp 0x3eeba
movq 0x120(%rsp), %rdi
movl $0x4, %esi
callq 0x13390
movq %rax, %rdi
movq 0xb8(%rsp), %rax
movl %eax, %esi
movq 0xb0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
cmpl $0xff, %eax
jle 0x3ee7f
movl $0xff, %eax
movl %eax, 0x38(%rsp)
jmp 0x3eeb2
movq 0x120(%rsp), %rdi
movl $0x4, %esi
callq 0x13390
movq %rax, %rdi
movq 0xb8(%rsp), %rax
movl %eax, %esi
movq 0xb0(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movl %eax, 0x38(%rsp)
movl 0x38(%rsp), %eax
movl %eax, 0x3c(%rsp)
movl 0x3c(%rsp), %eax
movb %al, %dl
movq 0xd0(%rsp), %rax
movq 0xb0(%rsp), %rcx
movl 0x11c(%rsp), %esi
subl $0x1, %esi
movslq %esi, %rsi
imulq %rsi, %rcx
movb %dl, 0x3(%rax,%rcx)
jmp 0x3eee7
movq 0xb0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xb0(%rsp)
jmp 0x3ebc0
movq 0xf8(%rsp), %rdi
movq 0xd0(%rsp), %rsi
callq 0x31d0
movq 0xb8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xb8(%rsp)
jmp 0x3eb9b
jmp 0x3f510
movq $0x0, 0xa0(%rsp)
movq 0xa0(%rsp), %rax
movslq 0x110(%rsp), %rcx
cmpq %rcx, %rax
jae 0x3f50e
cmpl $0x1, 0xe0(%rsp)
jne 0x3f0f1
movq $0x0, 0x98(%rsp)
movq 0x98(%rsp), %rax
movslq 0x114(%rsp), %rcx
cmpq %rcx, %rax
jae 0x3f0ec
movl $0x0, 0x94(%rsp)
movl 0x94(%rsp), %eax
cmpl 0x11c(%rsp), %eax
jge 0x3f0d1
movq 0x120(%rsp), %rdi
movslq 0x94(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xa0(%rsp), %rax
movl %eax, %esi
movq 0x98(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movq 0x120(%rsp), %rcx
cmpl 0x5c(%rcx), %eax
jge 0x3effd
movq 0x120(%rsp), %rax
movl 0x5c(%rax), %eax
movl %eax, 0x34(%rsp)
jmp 0x3f08b
movq 0x120(%rsp), %rdi
movslq 0x94(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xa0(%rsp), %rax
movl %eax, %esi
movq 0x98(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movq 0x120(%rsp), %rcx
cmpl 0x60(%rcx), %eax
jle 0x3f04d
movq 0x120(%rsp), %rax
movl 0x60(%rax), %eax
movl %eax, 0x30(%rsp)
jmp 0x3f083
movq 0x120(%rsp), %rdi
movslq 0x94(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xa0(%rsp), %rax
movl %eax, %esi
movq 0x98(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movl %eax, 0x30(%rsp)
movl 0x30(%rsp), %eax
movl %eax, 0x34(%rsp)
movl 0x34(%rsp), %eax
movb %al, %dl
movq 0xd0(%rsp), %rax
movq 0x98(%rsp), %rcx
movslq 0x11c(%rsp), %rsi
imulq %rsi, %rcx
movslq 0x94(%rsp), %rsi
addq %rsi, %rcx
movb %dl, (%rax,%rcx)
movl 0x94(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x94(%rsp)
jmp 0x3ef96
jmp 0x3f0d3
movq 0x98(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x98(%rsp)
jmp 0x3ef72
jmp 0x3f4e0
testb $0x1, 0x11b(%rsp)
jne 0x3f3c4
movq $0x0, 0x88(%rsp)
movq 0x88(%rsp), %rax
movslq 0x114(%rsp), %rcx
cmpq %rcx, %rax
jae 0x3f3bf
movl $0x0, 0x84(%rsp)
movl 0x84(%rsp), %eax
cmpl 0x11c(%rsp), %eax
jge 0x3f3a4
movq 0x120(%rsp), %rdi
movslq 0x84(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xa0(%rsp), %rax
movl %eax, %esi
movq 0x88(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movq 0x120(%rsp), %rcx
cmpl 0x5c(%rcx), %eax
jge 0x3f196
movq 0x120(%rsp), %rax
movl 0x5c(%rax), %eax
movl %eax, 0x2c(%rsp)
jmp 0x3f224
movq 0x120(%rsp), %rdi
movslq 0x84(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xa0(%rsp), %rax
movl %eax, %esi
movq 0x88(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movq 0x120(%rsp), %rcx
cmpl 0x60(%rcx), %eax
jle 0x3f1e6
movq 0x120(%rsp), %rax
movl 0x60(%rax), %eax
movl %eax, 0x28(%rsp)
jmp 0x3f21c
movq 0x120(%rsp), %rdi
movslq 0x84(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xa0(%rsp), %rax
movl %eax, %esi
movq 0x88(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movl %eax, 0x28(%rsp)
movl 0x28(%rsp), %eax
movl %eax, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
movl 0xdc(%rsp), %ecx
shll %cl, %eax
sarl $0x8, %eax
movb %al, %dl
movq 0xd0(%rsp), %rax
movq 0x88(%rsp), %rcx
movslq 0x11c(%rsp), %rsi
imulq %rsi, %rcx
shlq %rcx
movl 0x84(%rsp), %esi
shll %esi
movslq %esi, %rsi
addq %rsi, %rcx
movb %dl, (%rax,%rcx)
movq 0x120(%rsp), %rdi
movslq 0x84(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xa0(%rsp), %rax
movl %eax, %esi
movq 0x88(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movq 0x120(%rsp), %rcx
cmpl 0x5c(%rcx), %eax
jge 0x3f2ba
movq 0x120(%rsp), %rax
movl 0x5c(%rax), %eax
movl %eax, 0x24(%rsp)
jmp 0x3f348
movq 0x120(%rsp), %rdi
movslq 0x84(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xa0(%rsp), %rax
movl %eax, %esi
movq 0x88(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movq 0x120(%rsp), %rcx
cmpl 0x60(%rcx), %eax
jle 0x3f30a
movq 0x120(%rsp), %rax
movl 0x60(%rax), %eax
movl %eax, 0x20(%rsp)
jmp 0x3f340
movq 0x120(%rsp), %rdi
movslq 0x84(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xa0(%rsp), %rax
movl %eax, %esi
movq 0x88(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
movl %eax, 0x20(%rsp)
movl 0x20(%rsp), %eax
movl %eax, 0x24(%rsp)
movl 0x24(%rsp), %eax
movl 0xdc(%rsp), %ecx
shll %cl, %eax
andl $0xff, %eax
movb %al, %dl
movq 0xd0(%rsp), %rax
movq 0x88(%rsp), %rcx
movslq 0x11c(%rsp), %rsi
imulq %rsi, %rcx
shlq %rcx
movl 0x84(%rsp), %esi
shll %esi
movslq %esi, %rsi
addq %rsi, %rcx
movb %dl, 0x1(%rax,%rcx)
movl 0x84(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x84(%rsp)
jmp 0x3f12f
jmp 0x3f3a6
movq 0x88(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x88(%rsp)
jmp 0x3f10b
jmp 0x3f4de
movq $0x0, 0x78(%rsp)
movq 0x78(%rsp), %rax
movslq 0x114(%rsp), %rcx
cmpq %rcx, %rax
jae 0x3f4dc
movl $0x0, 0x74(%rsp)
movl 0x74(%rsp), %eax
cmpl 0x11c(%rsp), %eax
jge 0x3f4c7
movq 0x120(%rsp), %rdi
movslq 0x74(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xa0(%rsp), %rax
movl %eax, %esi
movq 0x78(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
sarl $0x8, %eax
movb %al, %dl
movq 0xd0(%rsp), %rax
movq 0x78(%rsp), %rcx
movslq 0x11c(%rsp), %rsi
imulq %rsi, %rcx
shlq %rcx
movl 0x74(%rsp), %esi
shll %esi
movslq %esi, %rsi
addq %rsi, %rcx
movb %dl, (%rax,%rcx)
movq 0x120(%rsp), %rdi
movslq 0x74(%rsp), %rsi
callq 0x13390
movq %rax, %rdi
movq 0xa0(%rsp), %rax
movl %eax, %esi
movq 0x78(%rsp), %rax
movl %eax, %edx
callq 0x12ba0
cwtl
andl $0xff, %eax
movb %al, %dl
movq 0xd0(%rsp), %rax
movq 0x78(%rsp), %rcx
movslq 0x11c(%rsp), %rsi
imulq %rsi, %rcx
shlq %rcx
movl 0x74(%rsp), %esi
shll %esi
movslq %esi, %rsi
addq %rsi, %rcx
movb %dl, 0x1(%rax,%rcx)
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x3f3eb
jmp 0x3f4c9
movq 0x78(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x78(%rsp)
jmp 0x3f3cd
jmp 0x3f4de
jmp 0x3f4e0
movq 0xf8(%rsp), %rdi
movq 0xd0(%rsp), %rsi
callq 0x31d0
movq 0xa0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xa0(%rsp)
jmp 0x3ef3f
jmp 0x3f510
jmp 0x3f512
movq 0xf8(%rsp), %rdi
movq 0xd0(%rsp), %rsi
callq 0x3250
movq 0xf8(%rsp), %rdi
movq 0xf0(%rsp), %rsi
callq 0x3380
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x32c0
movq 0x100(%rsp), %rdi
callq 0x3350
movb $0x0, 0x137(%rsp)
movb 0x137(%rsp), %al
andb $0x1, %al
addq $0x138, %rsp            # imm = 0x138
retq
nopw (%rax,%rax)