// File: /workspace/github_c_makefile_star2_O1/Joy-Division[P]tools-mgs/lodepng/lodepng.c
// Function: lodepng_huffman_code_lengths
unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies,
                                      size_t numcodes, unsigned maxbitlen)
{
  unsigned error = 0;
  unsigned i;
  size_t numpresent = 0; /*number of symbols with non-zero frequency*/
  BPMNode* leaves; /*the symbols, only those with > 0 frequency*/

  if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/
  if((1u << maxbitlen) < numcodes) return 80; /*error: represent all symbols*/

  leaves = (BPMNode*)lodepng_malloc(numcodes * sizeof(*leaves));
  if(!leaves) return 83; /*alloc fail*/

  for(i = 0; i != numcodes; ++i)
  {
    if(frequencies[i] > 0)
    {
      leaves[numpresent].weight = (int)frequencies[i];
      leaves[numpresent].index = i;
      ++numpresent;
    }
  }

  for(i = 0; i != numcodes; ++i) lengths[i] = 0;

  /*ensure at least two present symbols. There should be at least one symbol
  according to RFC 1951 section 3.2.7. Some decoders incorrectly require two. To
  make these work as well ensure there are at least two symbols. The
  Package-Merge code below also doesn't work correctly if there's only one
  symbol, it'd give it the theoritical 0 bits but in practice zlib wants 1 bit*/
  if(numpresent == 0)
  {
    lengths[0] = lengths[1] = 1; /*note that for RFC 1951 section 3.2.7, only lengths[0] = 1 is needed*/
  }
  else if(numpresent == 1)
  {
    lengths[leaves[0].index] = 1;
    lengths[leaves[0].index == 0 ? 1 : 0] = 1;
  }
  else
  {
    BPMLists lists;
    BPMNode* node;

    bpmnode_sort(leaves, numpresent);

    lists.listsize = maxbitlen;
    lists.memsize = 2 * maxbitlen * (maxbitlen + 1);
    lists.nextfree = 0;
    lists.numfree = lists.memsize;
    lists.memory = (BPMNode*)lodepng_malloc(lists.memsize * sizeof(*lists.memory));
    lists.freelist = (BPMNode**)lodepng_malloc(lists.memsize * sizeof(BPMNode*));
    lists.chains0 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*));
    lists.chains1 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*));
    if(!lists.memory || !lists.freelist || !lists.chains0 || !lists.chains1) error = 83; /*alloc fail*/

    if(!error)
    {
      for(i = 0; i != lists.memsize; ++i) lists.freelist[i] = &lists.memory[i];

      bpmnode_create(&lists, leaves[0].weight, 1, 0);
      bpmnode_create(&lists, leaves[1].weight, 2, 0);

      for(i = 0; i != lists.listsize; ++i)
      {
        lists.chains0[i] = &lists.memory[0];
        lists.chains1[i] = &lists.memory[1];
      }

      /*each boundaryPM call adds one chain to the last list, and we need 2 * numpresent - 2 chains.*/
      for(i = 2; i != 2 * numpresent - 2; ++i) boundaryPM(&lists, leaves, numpresent, (int)maxbitlen - 1, (int)i);

      for(node = lists.chains1[maxbitlen - 1]; node; node = node->tail)
      {
        for(i = 0; i != node->index; ++i) ++lengths[leaves[i].index];
      }
    }

    lodepng_free(lists.memory);
    lodepng_free(lists.freelist);
    lodepng_free(lists.chains0);
    lodepng_free(lists.chains1);
  }

  lodepng_free(leaves);
  return error;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %ecx, %r12d
movl $0x1, %eax
shll %cl, %eax
movl %eax, %eax
leaq -0x1(%rdx), %rcx
movl $0x50, %ebp
cmpq %rax, %rcx
jae 0x177f
movq %rdx, %r13
movq %rsi, %r15
movq %rdi, %rbx
leaq (,%rdx,8), %rax
leaq (%rax,%rax,2), %rdi
callq 0x10f0
testq %rax, %rax
je 0x1423
movq %rax, %r14
movq %r12, (%rsp)
testq %r13, %r13
je 0x142d
xorl %eax, %eax
xorl %r12d, %r12d
movl (%r15,%rax,4), %ecx
testl %ecx, %ecx
je 0x1417
leaq (%r12,%r12,2), %rdx
movl %ecx, (%r14,%rdx,8)
movl %eax, 0x4(%r14,%rdx,8)
incq %r12
incq %rax
movl %eax, %ecx
cmpq %r13, %rcx
jne 0x13ff
jmp 0x1430
movl $0x53, %ebp
jmp 0x177f
xorl %r12d, %r12d
testq %r13, %r13
je 0x1448
xorl %eax, %eax
movl $0x0, (%rbx,%rax,4)
incq %rax
movl %eax, %ecx
cmpq %r13, %rcx
jne 0x1437
cmpq $0x1, %r12
je 0x1462
testq %r12, %r12
jne 0x1480
movabsq $0x100000001, %rax      # imm = 0x100000001
movq %rax, (%rbx)
jmp 0x1479
movl 0x4(%r14), %eax
xorl %ecx, %ecx
testq %rax, %rax
sete %cl
movl $0x1, %edx
movl %edx, (%rbx,%rax,4)
movl %edx, (%rbx,%rcx,4)
xorl %ebp, %ebp
jmp 0x1777
movq %rbx, 0x50(%rsp)
leaq (,%r12,8), %rax
leaq (%rax,%rax,2), %rbx
movq %rbx, %rdi
callq 0x10f0
movq %rax, %r15
cmpq $0x2, %r12
jb 0x15a0
movq %rbx, 0x48(%rsp)
movl $0x1, %eax
xorl %ecx, %ecx
movq %r14, 0x60(%rsp)
movq %r15, 0x58(%rsp)
movq %rcx, 0x8(%rsp)
testb $0x1, %cl
movq %r15, %rsi
cmoveq %r14, %rsi
movq %r14, %rbx
cmoveq %r15, %rbx
leaq (%rax,%rax), %rdx
movq %rax, %rcx
shlq $0x4, %rcx
leaq (%rcx,%rcx,2), %r8
xorl %r9d, %r9d
movq %r9, %r10
leaq (%r9,%rax), %r14
cmpq %r12, %r14
cmovaeq %r12, %r14
addq %rdx, %r9
cmpq %r12, %r9
movq %r12, %r15
cmovbq %r9, %r15
cmpq %r15, %r10
jae 0x155f
movq %rbx, %rdi
movq %r14, %r13
movq %r10, %rcx
cmpq %r14, %rcx
jae 0x1530
cmpq %r15, %r13
jae 0x1538
leaq (%rcx,%rcx,2), %r11
movl (%rsi,%r11,8), %r11d
leaq (,%r13,2), %rbp
addq %r13, %rbp
cmpl (%rsi,%rbp,8), %r11d
jle 0x1538
movq %r13, %r11
incq %r13
jmp 0x153e
movq %rcx, %r11
incq %rcx
leaq (%r11,%r11,2), %r11
movq 0x10(%rsi,%r11,8), %rbp
movq %rbp, 0x10(%rdi)
movups (%rsi,%r11,8), %xmm0
movups %xmm0, (%rdi)
incq %r10
addq $0x18, %rdi
cmpq %r15, %r10
jb 0x150d
addq %r8, %rbx
cmpq %r12, %r9
jb 0x14e4
movq 0x8(%rsp), %rsi
leaq 0x1(%rsi), %rcx
movq %rdx, %rax
cmpq %r12, %rdx
movq 0x60(%rsp), %r14
movq 0x58(%rsp), %r15
jb 0x14bc
testb $0x1, %sil
movq 0x48(%rsp), %rdx
jne 0x15a0
movq %r14, %rdi
movq %r15, %rsi
callq 0x10e0
movq %r15, %rdi
callq 0x1030
movq (%rsp), %rbx
movl %ebx, 0x30(%rsp)
leal 0x1(%rbx), %r13d
imull %ebx, %r13d
addl %r13d, %r13d
movl %r13d, 0x10(%rsp)
xorl %eax, %eax
movl %eax, 0x24(%rsp)
movl %r13d, 0x20(%rsp)
leaq (,%r13,8), %r15
leaq (%r15,%r15,2), %rdi
callq 0x10f0
movq %rax, %rbp
movq %rax, 0x18(%rsp)
movq %r15, %rdi
callq 0x10f0
movq %rax, 0x8(%rsp)
movq %rax, 0x28(%rsp)
movl %ebx, %ebx
shlq $0x3, %rbx
movq %rbx, %rdi
callq 0x10f0
movq %rax, %r15
movq %rax, 0x38(%rsp)
movq %rbx, %rdi
callq 0x10f0
movq %rax, 0x40(%rsp)
testq %rbp, %rbp
setne %cl
cmpq $0x0, 0x8(%rsp)
setne %dl
testq %r15, %r15
setne %sil
andb %dl, %sil
andb %cl, %sil
testq %rax, %rax
setne %al
movl $0x53, %ebp
testb %al, %sil
movl $0x0, %eax
cmovnel %eax, %ebp
je 0x174f
testl %r13d, %r13d
je 0x1679
movl %r13d, %eax
xorl %ecx, %ecx
leaq (%rcx,%rcx,2), %rdx
shlq $0x3, %rdx
addq 0x18(%rsp), %rdx
movq 0x28(%rsp), %rsi
movq %rdx, (%rsi,%rcx,8)
incq %rcx
cmpq %rax, %rcx
jne 0x165b
movl (%r14), %esi
leaq 0x10(%rsp), %r15
movq %r15, %rdi
movl $0x1, %edx
xorl %ecx, %ecx
callq 0x1790
movl 0x18(%r14), %esi
movq %r15, %rdi
movl $0x2, %edx
xorl %ecx, %ecx
callq 0x1790
movl 0x20(%r15), %eax
testq %rax, %rax
je 0x16d6
xorl %ecx, %ecx
movq 0x18(%rsp), %rdx
movq 0x38(%rsp), %rsi
movq %rdx, (%rsi,%rcx,8)
movq 0x18(%rsp), %rdx
movq 0x40(%rsp), %rsi
addq $0x18, %rdx
movq %rdx, (%rsi,%rcx,8)
incq %rcx
cmpq %rcx, %rax
jne 0x16ae
leaq -0x2(,%r12,2), %rbx
cmpq $0x2, %rbx
je 0x1710
movq (%rsp), %rax
leal -0x1(%rax), %r15d
movl $0x2, %r13d
leaq 0x10(%rsp), %rdi
movq %r14, %rsi
movq %r12, %rdx
movl %r15d, %ecx
movl %r13d, %r8d
callq 0x1879
incl %r13d
cmpq %r13, %rbx
jne 0x16f2
movq 0x40(%rsp), %rax
movq (%rsp), %rcx
decl %ecx
movq (%rax,%rcx,8), %rax
testq %rax, %rax
movq 0x50(%rsp), %rsi
je 0x174f
cmpl $0x0, 0x4(%rax)
je 0x1746
xorl %ecx, %ecx
movl %ecx, %edx
leaq (%rdx,%rdx,2), %rdx
movl 0x4(%r14,%rdx,8), %edx
incl (%rsi,%rdx,4)
incl %ecx
cmpl 0x4(%rax), %ecx
jne 0x1731
movq 0x8(%rax), %rax
testq %rax, %rax
jne 0x1729
movq 0x18(%rsp), %rdi
callq 0x1030
movq 0x28(%rsp), %rdi
callq 0x1030
movq 0x38(%rsp), %rdi
callq 0x1030
movq 0x40(%rsp), %rdi
callq 0x1030
movq %r14, %rdi
callq 0x1030
movl %ebp, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq