// File: /workspace/github_c_makefile_star2_O0/imaya[P]zopfli-for-emscripten/katajainen.c
// Function: ZopfliLengthLimitedCodeLengths
int ZopfliLengthLimitedCodeLengths(
    const size_t* frequencies, int n, int maxbits, unsigned* bitlengths) {
  NodePool pool;
  int i;
  int numsymbols = 0;  /* Amount of symbols with frequency > 0. */
  int numBoundaryPMRuns;

  /* Array of lists of chains. Each list requires only two lookahead chains at
  a time, so each list is a array of two Node*'s. */
  Node* (*lists)[2];

  /* One leaf per symbol. Only numsymbols leaves will be used. */
  Node* leaves = (Node*)malloc(n * sizeof(*leaves));

  /* Initialize all bitlengths at 0. */
  for (i = 0; i < n; i++) {
    bitlengths[i] = 0;
  }

  /* Count used symbols and place them in the leaves. */
  for (i = 0; i < n; i++) {
    if (frequencies[i]) {
      leaves[numsymbols].weight = frequencies[i];
      leaves[numsymbols].count = i;  /* Index of symbol this leaf represents. */
      numsymbols++;
    }
  }

  /* Check special cases and error conditions. */
  if ((1 << maxbits) < numsymbols) {
    free(leaves);
    return 1;  /* Error, too few maxbits to represent symbols. */
  }
  if (numsymbols == 0) {
    free(leaves);
    return 0;  /* No symbols at all. OK. */
  }
  if (numsymbols == 1) {
    bitlengths[leaves[0].count] = 1;
    free(leaves);
    return 0;  /* Only one symbol, give it bitlength 1, not 0. OK. */
  }

  /* Sort the leaves from lightest to heaviest. */
  qsort(leaves, numsymbols, sizeof(Node), LeafComparator);

  /* Initialize node memory pool. */
  pool.size = 2 * maxbits * (maxbits + 1);
  pool.nodes = (Node*)malloc(pool.size * sizeof(*pool.nodes));
  pool.next = pool.nodes;
  for (i = 0; i < pool.size; i++) {
    pool.nodes[i].inuse = 0;
  }

  lists = (Node* (*)[2])malloc(maxbits * sizeof(*lists));
  InitLists(&pool, leaves, maxbits, lists);

  /* In the last list, 2 * numsymbols - 2 active chains need to be created. Two
  are already created in the initialization. Each BoundaryPM run creates one. */
  numBoundaryPMRuns = 2 * numsymbols - 4;
  for (i = 0; i < numBoundaryPMRuns; i++) {
    char final = i == numBoundaryPMRuns - 1;
    BoundaryPM(lists, maxbits, leaves, numsymbols, &pool, maxbits - 1, final);
  }

  ExtractBitLengths(lists[maxbits - 1][1], leaves, bitlengths);

  free(lists);
  free(leaves);
  free(pool.nodes);
  return 0;  /* OK. */
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x58(%rsp)
movl %esi, 0x54(%rsp)
movl %edx, 0x50(%rsp)
movq %rcx, 0x48(%rsp)
movl $0x0, 0x28(%rsp)
movslq 0x54(%rsp), %rax
imulq $0x18, %rax, %rdi
callq 0x1120
movq %rax, 0x10(%rsp)
movl $0x0, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
cmpl 0x54(%rsp), %eax
jge 0x7071
movq 0x48(%rsp), %rax
movslq 0x2c(%rsp), %rcx
movl $0x0, (%rax,%rcx,4)
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x7049
movl $0x0, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
cmpl 0x54(%rsp), %eax
jge 0x70e8
movq 0x58(%rsp), %rax
movslq 0x2c(%rsp), %rcx
cmpq $0x0, (%rax,%rcx,8)
je 0x70d9
movq 0x58(%rsp), %rax
movslq 0x2c(%rsp), %rcx
movq (%rax,%rcx,8), %rcx
movq 0x10(%rsp), %rax
movslq 0x28(%rsp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movq %rcx, (%rax)
movl 0x2c(%rsp), %ecx
movq 0x10(%rsp), %rax
movslq 0x28(%rsp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x10(%rax)
movl 0x28(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x28(%rsp)
jmp 0x70db
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x7079
movl 0x50(%rsp), %ecx
movl $0x1, %eax
shll %cl, %eax
cmpl 0x28(%rsp), %eax
jge 0x7110
movq 0x10(%rsp), %rdi
callq 0x1030
movl $0x1, 0x64(%rsp)
jmp 0x72cd
cmpl $0x0, 0x28(%rsp)
jne 0x712e
movq 0x10(%rsp), %rdi
callq 0x1030
movl $0x0, 0x64(%rsp)
jmp 0x72cd
cmpl $0x1, 0x28(%rsp)
jne 0x7161
movq 0x48(%rsp), %rax
movq 0x10(%rsp), %rcx
movslq 0x10(%rcx), %rcx
movl $0x1, (%rax,%rcx,4)
movq 0x10(%rsp), %rdi
callq 0x1030
movl $0x0, 0x64(%rsp)
jmp 0x72cd
movq 0x10(%rsp), %rdi
movslq 0x28(%rsp), %rsi
movl $0x18, %edx
leaq 0x169(%rip), %rcx       # 0x72e0
callq 0x1050
movl 0x50(%rsp), %eax
shll %eax
movl 0x50(%rsp), %ecx
addl $0x1, %ecx
imull %ecx, %eax
movl %eax, 0x40(%rsp)
movslq 0x40(%rsp), %rax
imulq $0x18, %rax, %rdi
callq 0x1120
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rax
movq %rax, 0x38(%rsp)
movl $0x0, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
cmpl 0x40(%rsp), %eax
jge 0x71e1
movq 0x30(%rsp), %rax
movslq 0x2c(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movb $0x0, 0x14(%rax)
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x71b5
movslq 0x50(%rsp), %rdi
shlq $0x4, %rdi
callq 0x1120
movq %rax, 0x18(%rsp)
movq 0x10(%rsp), %rsi
movl 0x50(%rsp), %edx
movq 0x18(%rsp), %rcx
leaq 0x30(%rsp), %rdi
callq 0x7300
movl 0x28(%rsp), %eax
shll %eax
subl $0x4, %eax
movl %eax, 0x24(%rsp)
movl $0x0, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
cmpl 0x24(%rsp), %eax
jge 0x727e
movl 0x2c(%rsp), %eax
movl 0x24(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movb %al, 0xf(%rsp)
movq 0x18(%rsp), %rdi
movl 0x50(%rsp), %esi
movq 0x10(%rsp), %rdx
movl 0x28(%rsp), %ecx
movl 0x50(%rsp), %r9d
subl $0x1, %r9d
leaq 0x30(%rsp), %r8
movsbl 0xf(%rsp), %eax
movl %eax, (%rsp)
callq 0x73d0
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x7221
movq 0x18(%rsp), %rax
movl 0x50(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdi
movq 0x10(%rsp), %rsi
movq 0x48(%rsp), %rdx
callq 0x75f0
movq 0x18(%rsp), %rdi
callq 0x1030
movq 0x10(%rsp), %rdi
callq 0x1030
movq 0x30(%rsp), %rdi
callq 0x1030
movl $0x0, 0x64(%rsp)
movl 0x64(%rsp), %eax
addq $0x68, %rsp
retq
nopw %cs:(%rax,%rax)