// File: /workspace/github_c_makefile_star2_O0/madler[P]pigz/zopfli/src/zopfli/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;
  Node* nodes;

  /* 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. */
  }
  if (numsymbols == 2) {
    bitlengths[leaves[0].count]++;
    bitlengths[leaves[1].count]++;
    free(leaves);
    return 0;
  }

  /* Sort the leaves from lightest to heaviest. Add count into the same
  variable for stable sorting. */
  for (i = 0; i < numsymbols; i++) {
    if (leaves[i].weight >=
        ((size_t)1 << (sizeof(leaves[0].weight) * CHAR_BIT - 9))) {
      free(leaves);
      return 1;  /* Error, we need 9 bits for the count. */
    }
    leaves[i].weight = (leaves[i].weight << 9) | leaves[i].count;
  }
  qsort(leaves, numsymbols, sizeof(Node), LeafComparator);
  for (i = 0; i < numsymbols; i++) {
    leaves[i].weight >>= 9;
  }

  if (numsymbols - 1 < maxbits) {
    maxbits = numsymbols - 1;
  }

  /* Initialize node memory pool. */
  nodes = (Node*)malloc(maxbits * 2 * numsymbols * sizeof(Node));
  pool.next = nodes;

  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 - 1; i++) {
    BoundaryPM(lists, leaves, numsymbols, &pool, maxbits - 1);
  }
  BoundaryPMFinal(lists, leaves, numsymbols, &pool, maxbits - 1);

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

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

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl $0x0, -0x30(%rbp)
movslq -0x14(%rbp), %rax
imulq $0x18, %rax, %rdi
callq 0x33d0
movq %rax, -0x50(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x1b257
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movl $0x0, (%rax,%rcx,4)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x1b235
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x1b2be
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
cmpq $0x0, (%rax,%rcx,8)
je 0x1b2b1
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rcx
movq -0x50(%rbp), %rax
movslq -0x30(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movq %rcx, (%rax)
movl -0x2c(%rbp), %ecx
movq -0x50(%rbp), %rax
movslq -0x30(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x10(%rax)
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x1b2b3
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x1b25e
movl -0x18(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
cmpl -0x30(%rbp), %eax
jge 0x1b2e2
movq -0x50(%rbp), %rdi
callq 0x3050
movl $0x1, -0x4(%rbp)
jmp 0x1b54c
cmpl $0x0, -0x30(%rbp)
jne 0x1b2fd
movq -0x50(%rbp), %rdi
callq 0x3050
movl $0x0, -0x4(%rbp)
jmp 0x1b54c
cmpl $0x1, -0x30(%rbp)
jne 0x1b32b
movq -0x20(%rbp), %rax
movq -0x50(%rbp), %rcx
movslq 0x10(%rcx), %rcx
movl $0x1, (%rax,%rcx,4)
movq -0x50(%rbp), %rdi
callq 0x3050
movl $0x0, -0x4(%rbp)
jmp 0x1b54c
cmpl $0x2, -0x30(%rbp)
jne 0x1b370
movq -0x20(%rbp), %rax
movq -0x50(%rbp), %rcx
movslq 0x10(%rcx), %rcx
movl (%rax,%rcx,4), %edx
addl $0x1, %edx
movl %edx, (%rax,%rcx,4)
movq -0x20(%rbp), %rax
movq -0x50(%rbp), %rcx
movslq 0x28(%rcx), %rcx
movl (%rax,%rcx,4), %edx
addl $0x1, %edx
movl %edx, (%rax,%rcx,4)
movq -0x50(%rbp), %rdi
callq 0x3050
movl $0x0, -0x4(%rbp)
jmp 0x1b54c
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0x1b3fe
movq -0x50(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movabsq $0x80000000000000, %rcx # imm = 0x80000000000000
cmpq %rcx, (%rax)
jb 0x1b3b2
movq -0x50(%rbp), %rdi
callq 0x3050
movl $0x1, -0x4(%rbp)
jmp 0x1b54c
movq -0x50(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rcx
shlq $0x9, %rcx
movq -0x50(%rbp), %rax
movslq -0x2c(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movslq 0x10(%rax), %rax
orq %rax, %rcx
movq -0x50(%rbp), %rax
movslq -0x2c(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movq %rcx, (%rax)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x1b377
movq -0x50(%rbp), %rdi
movslq -0x30(%rbp), %rsi
movl $0x18, %edx
leaq 0x14e(%rip), %rcx       # 0x1b560
callq 0x30e0
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0x1b44a
movq -0x50(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rcx
shrq $0x9, %rcx
movq %rcx, (%rax)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x1b41e
movl -0x30(%rbp), %eax
subl $0x1, %eax
cmpl -0x18(%rbp), %eax
jge 0x1b45e
movl -0x30(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x18(%rbp)
movl -0x18(%rbp), %eax
shll %eax
imull -0x30(%rbp), %eax
cltq
imulq $0x18, %rax, %rdi
callq 0x33d0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x28(%rbp)
movslq -0x18(%rbp), %rdi
shlq $0x4, %rdi
callq 0x33d0
movq %rax, -0x48(%rbp)
movq -0x50(%rbp), %rsi
movl -0x18(%rbp), %edx
movq -0x48(%rbp), %rcx
leaq -0x28(%rbp), %rdi
callq 0x1b580
movl -0x30(%rbp), %eax
shll %eax
subl $0x4, %eax
movl %eax, -0x34(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movl -0x34(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x1b4e9
movq -0x48(%rbp), %rdi
movq -0x50(%rbp), %rsi
movl -0x30(%rbp), %edx
movl -0x18(%rbp), %r8d
subl $0x1, %r8d
leaq -0x28(%rbp), %rcx
callq 0x1b650
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x1b4b5
movq -0x48(%rbp), %rdi
movq -0x50(%rbp), %rsi
movl -0x30(%rbp), %edx
movl -0x18(%rbp), %r8d
subl $0x1, %r8d
leaq -0x28(%rbp), %rcx
callq 0x1b810
movq -0x48(%rbp), %rax
movl -0x18(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdi
movq -0x50(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x1b930
movq -0x48(%rbp), %rdi
callq 0x3050
movq -0x50(%rbp), %rdi
callq 0x3050
movq -0x40(%rbp), %rdi
callq 0x3050
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)