// File: /workspace/github_c_makefile_star2_O0/imaya[P]zopfli-for-emscripten/squeeze.c
// Function: ZopfliLZ77Optimal
void ZopfliLZ77Optimal(ZopfliBlockState *s,
                       const unsigned char* in, size_t instart, size_t inend,
                       ZopfliLZ77Store* store) {
  /* Dist to get to here with smallest cost. */
  size_t blocksize = inend - instart;
  unsigned short* length_array =
      (unsigned short*)malloc(sizeof(unsigned short) * (blocksize + 1));
  unsigned short* path = 0;
  size_t pathsize = 0;
  ZopfliLZ77Store currentstore;
  SymbolStats stats, beststats, laststats;
  int i;
  double cost;
  double bestcost = ZOPFLI_LARGE_FLOAT;
  double lastcost = 0;
  /* Try randomizing the costs a bit once the size stabilizes. */
  RanState ran_state;
  int lastrandomstep = -1;

  if (!length_array) exit(-1); /* Allocation failed. */

  InitRanState(&ran_state);
  InitStats(&stats);
  ZopfliInitLZ77Store(&currentstore);

  /* Do regular deflate, then loop multiple shortest path runs, each time using
  the statistics of the previous run. */

  /* Initial run. */
  ZopfliLZ77Greedy(s, in, instart, inend, &currentstore);
  GetStatistics(&currentstore, &stats);

  /* Repeat statistics with each time the cost model from the previous stat
  run. */
  for (i = 0; i < s->options->numiterations; i++) {
    ZopfliCleanLZ77Store(&currentstore);
    ZopfliInitLZ77Store(&currentstore);
    LZ77OptimalRun(s, in, instart, inend, &path, &pathsize,
                   length_array, GetCostStat, (void*)&stats,
                   &currentstore);
    cost = ZopfliCalculateBlockSize(currentstore.litlens, currentstore.dists,
                                    0, currentstore.size, 2);
    if (cost < bestcost) {
      /* Copy to the output store. */
      ZopfliCopyLZ77Store(&currentstore, store);
      CopyStats(&stats, &beststats);
      bestcost = cost;
    }
    CopyStats(&stats, &laststats);
    ClearStatFreqs(&stats);
    GetStatistics(&currentstore, &stats);
    if (lastrandomstep != -1) {
      /* This makes it converge slower but better. Do it only once the
      randomness kicks in so that if the user does few iterations, it gives a
      better result sooner. */
      AddWeighedStatFreqs(&stats, 1.0, &laststats, 0.5, &stats);
      CalculateStatistics(&stats);
    }
    if (i > 5 && cost == lastcost) {
      CopyStats(&beststats, &stats);
      RandomizeStatFreqs(&ran_state, &stats);
      CalculateStatistics(&stats);
      lastrandomstep = i;
    }
    lastcost = cost;
  }

  free(length_array);
  free(path);
  ZopfliCleanLZ77Store(&currentstore);
}

// Assembly:
pushq %rbx
subq $0x3cb0, %rsp           # imm = 0x3CB0
movq %rdi, 0x3ca8(%rsp)
movq %rsi, 0x3ca0(%rsp)
movq %rdx, 0x3c98(%rsp)
movq %rcx, 0x3c90(%rsp)
movq %r8, 0x3c88(%rsp)
movq 0x3c90(%rsp), %rax
subq 0x3c98(%rsp), %rax
movq %rax, 0x3c80(%rsp)
movq 0x3c80(%rsp), %rdi
addq $0x1, %rdi
shlq %rdi
callq 0x1120
movq %rax, 0x3c78(%rsp)
movq $0x0, 0x3c70(%rsp)
movq $0x0, 0x3c68(%rsp)
movsd 0x3cd4(%rip), %xmm0     # 0xd008
movsd %xmm0, 0x38(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x30(%rsp)
movl $0xffffffff, 0x24(%rsp) # imm = 0xFFFFFFFF
cmpq $0x0, 0x3c78(%rsp)
jne 0x9360
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x1170
leaq 0x28(%rsp), %rdi
callq 0x95f0
leaq 0x2850(%rsp), %rdi
callq 0x9610
leaq 0x3c50(%rsp), %rdi
callq 0x7820
movq 0x3ca8(%rsp), %rdi
movq 0x3ca0(%rsp), %rsi
movq 0x3c98(%rsp), %rdx
movq 0x3c90(%rsp), %rcx
leaq 0x3c50(%rsp), %r8
callq 0x8bb0
leaq 0x3c50(%rsp), %rdi
leaq 0x2850(%rsp), %rsi
callq 0x9670
movl $0x0, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
movq 0x3ca8(%rsp), %rcx
movq (%rcx), %rcx
cmpl 0x4(%rcx), %eax
jge 0x95b8
leaq 0x3c50(%rsp), %rdi
callq 0x7850
leaq 0x3c50(%rsp), %rdi
callq 0x7820
movq 0x3ca8(%rsp), %rdi
movq 0x3ca0(%rsp), %rsi
movq 0x3c98(%rsp), %rdx
movq 0x3c90(%rsp), %rcx
movq 0x3c78(%rsp), %rbx
leaq 0x3c70(%rsp), %r8
leaq 0x3c68(%rsp), %r9
leaq 0x461(%rip), %r11       # 0x98a0
leaq 0x2850(%rsp), %r10
leaq 0x3c50(%rsp), %rax
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movq %rax, 0x18(%rsp)
callq 0x9780
movq 0x3c50(%rsp), %rdi
movq 0x3c58(%rsp), %rsi
movq 0x3c60(%rsp), %rcx
xorl %eax, %eax
movl %eax, %edx
movl $0x2, %r8d
callq 0x2780
movsd %xmm0, 0x40(%rsp)
movsd 0x40(%rsp), %xmm1
movsd 0x38(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x94dc
movq 0x3c88(%rsp), %rsi
leaq 0x3c50(%rsp), %rdi
callq 0x7870
leaq 0x2850(%rsp), %rdi
leaq 0x1450(%rsp), %rsi
callq 0x9960
movsd 0x40(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
leaq 0x2850(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x9960
leaq 0x2850(%rsp), %rdi
callq 0x99f0
leaq 0x3c50(%rsp), %rdi
leaq 0x2850(%rsp), %rsi
callq 0x9670
cmpl $-0x1, 0x24(%rsp)
je 0x9549
leaq 0x2850(%rsp), %rdx
movsd 0x4801(%rip), %xmm0     # 0xdd28
leaq 0x50(%rsp), %rsi
movsd 0x47fc(%rip), %xmm1     # 0xdd30
movq %rdx, %rdi
callq 0x9a70
leaq 0x2850(%rsp), %rdi
callq 0x9c30
cmpl $0x5, 0x4c(%rsp)
jle 0x959c
movsd 0x40(%rsp), %xmm0
ucomisd 0x30(%rsp), %xmm0
jne 0x959c
jp 0x959c
leaq 0x1450(%rsp), %rdi
leaq 0x2850(%rsp), %rsi
callq 0x9960
leaq 0x28(%rsp), %rdi
leaq 0x2850(%rsp), %rsi
callq 0x9c70
leaq 0x2850(%rsp), %rdi
callq 0x9c30
movl 0x4c(%rsp), %eax
movl %eax, 0x24(%rsp)
movsd 0x40(%rsp), %xmm0
movsd %xmm0, 0x30(%rsp)
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0x93ce
movq 0x3c78(%rsp), %rdi
callq 0x1030
movq 0x3c70(%rsp), %rdi
callq 0x1030
leaq 0x3c50(%rsp), %rdi
callq 0x7850
addq $0x3cb0, %rsp           # imm = 0x3CB0
popq %rbx
retq
nopl (%rax,%rax)