// File: /workspace/github_c_makefile_star2_O2/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, %r14d
pushq $0x1
popq %rbx
movl %ebx, %eax
shll %cl, %eax
movl %eax, %eax
leaq -0x1(%rdx), %rcx
cmpq %rax, %rcx
jae 0x1402
movq %rdx, %r15
movq %rsi, %r13
movq %rdi, 0x10(%rsp)
imulq $0x18, %rdx, %rdi
callq 0x10f0
testq %rax, %rax
je 0x1431
movq %rax, %rdi
movq %r14, (%rsp)
xorl %eax, %eax
xorl %r12d, %r12d
movq 0x10(%rsp), %rsi
movl %eax, %ecx
cmpq %r15, %rcx
je 0x1406
movl (%r13,%rcx,4), %ecx
testl %ecx, %ecx
je 0x13fe
imulq $0x18, %r12, %rdx
movl %ecx, (%rdi,%rdx)
movl %eax, 0x4(%rdi,%rdx)
incq %r12
incl %eax
jmp 0x13e0
pushq $0x50
jmp 0x1433
xorl %eax, %eax
movl %eax, %eax
cmpq %r15, %rax
je 0x1417
andl $0x0, (%rsi,%rax,4)
incl %eax
jmp 0x1408
cmpq $0x1, %r12
je 0x1439
testq %r12, %r12
jne 0x1451
movabsq $0x100000001, %rax      # imm = 0x100000001
movq %rax, (%rsi)
jmp 0x144a
pushq $0x53
popq %rbp
jmp 0x1726
movl 0x4(%rdi), %eax
xorl %ecx, %ecx
testq %rax, %rax
sete %cl
movl %ebx, (%rsi,%rax,4)
movl %ebx, (%rsi,%rcx,4)
xorl %ebp, %ebp
jmp 0x1721
movq %rdi, 0x8(%rsp)
imulq $0x18, %r12, %rdi
movq %rdi, 0x20(%rsp)
callq 0x10f0
movq %rax, 0x18(%rsp)
pushq $0x1
popq %rcx
xorl %eax, %eax
cmpq %r12, %rcx
jae 0x152a
movq %rax, 0x28(%rsp)
testb $0x1, %al
movq 0x18(%rsp), %rax
movq %rax, %rsi
movq 0x8(%rsp), %rbx
cmoveq %rbx, %rsi
cmoveq %rax, %rbx
leaq (%rcx,%rcx), %rdx
imulq $0x30, %rcx, %r8
xorl %r10d, %r10d
cmpq %r12, %r10
jae 0x151a
leaq (%r10,%rcx), %r14
cmpq %r12, %r14
cmovaeq %r12, %r14
leaq (%r10,%rdx), %r13
cmpq %r12, %r13
movq %r12, %r15
cmovbq %r13, %r15
movq %rbx, %rdi
movq %r14, %rax
movq %r10, %r9
cmpq %r15, %r9
jae 0x1512
cmpq %r14, %r10
jae 0x14e6
cmpq %r15, %rax
jae 0x14ee
imulq $0x18, %r10, %r11
movl (%rsi,%r11), %r11d
imulq $0x18, %rax, %rbp
cmpl (%rsi,%rbp), %r11d
jle 0x14ee
movq %rax, %r11
incq %rax
jmp 0x14f4
movq %r10, %r11
incq %r10
imulq $0x18, %r11, %r11
movq 0x10(%rsi,%r11), %rbp
movq %rbp, 0x10(%rdi)
movups (%rsi,%r11), %xmm0
movups %xmm0, (%rdi)
incq %r9
addq $0x18, %rdi
jmp 0x14c5
addq %r8, %rbx
movq %r13, %r10
jmp 0x149e
movq 0x28(%rsp), %rax
incq %rax
movq %rdx, %rcx
jmp 0x146e
testb $0x1, %al
je 0x1542
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdx
callq 0x10e0
movq 0x18(%rsp), %rdi
callq 0x1030
movq (%rsp), %r14
movl %r14d, 0x50(%rsp)
leal 0x1(%r14), %ebx
imull %r14d, %ebx
addl %ebx, %ebx
movl %ebx, 0x30(%rsp)
andl $0x0, 0x44(%rsp)
movl %ebx, 0x40(%rsp)
imulq $0x18, %rbx, %rdi
callq 0x10f0
movq %rax, %r13
movq %rax, 0x38(%rsp)
leaq (,%rbx,8), %rdi
callq 0x10f0
movq %rax, %r15
movq %rax, 0x48(%rsp)
movl %r14d, %r14d
shlq $0x3, %r14
movq %r14, %rdi
callq 0x10f0
movq %rax, %rbp
movq %rax, 0x58(%rsp)
movq %r14, %rdi
callq 0x10f0
movq %rax, %r14
movq %rax, 0x60(%rsp)
movq %r13, %xmm0
movq %r15, %xmm1
punpcklqdq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0]
movq %rbp, %rcx
movq %rbp, %xmm1
movq %rax, %xmm2
punpcklqdq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0]
pxor %xmm2, %xmm2
pcmpeqd %xmm2, %xmm0
pcmpeqd %xmm2, %xmm1
movdqa %xmm0, %xmm2
shufps $0xdd, %xmm1, %xmm2     # xmm2 = xmm2[1,3],xmm1[1,3]
shufps $0x88, %xmm1, %xmm0     # xmm0 = xmm0[0,2],xmm1[0,2]
andps %xmm2, %xmm0
movmskps %xmm0, %eax
pushq $0x53
popq %rbp
testl %eax, %eax
cmovel %eax, %ebp
je 0x1608
movq %rcx, %rbx
jmp 0x16fc
xorl %eax, %eax
movq 0x8(%rsp), %rcx
cmpq %rax, %rbx
je 0x1621
movq %r13, (%r15,%rax,8)
incq %rax
addq $0x18, %r13
jmp 0x160f
movq %rcx, %r14
movl (%rcx), %esi
xorl %ebx, %ebx
leaq 0x30(%rsp), %r13
pushq $0x1
popq %rdx
movq %r13, %rdi
xorl %ecx, %ecx
callq 0x1737
movl 0x18(%r14), %esi
pushq $0x2
popq %r15
movq %r13, %rdi
movl %r15d, %edx
xorl %ecx, %ecx
callq 0x1737
movl 0x20(%r13), %eax
movq 0x8(%r13), %rcx
movq 0x28(%r13), %rdx
leaq 0x18(%rcx), %rsi
movq 0x30(%r13), %rdi
movq 0x10(%rsp), %r8
cmpq %rbx, %rax
je 0x167a
movq %rcx, (%rdx,%rbx,8)
movq %rsi, (%rdi,%rbx,8)
incq %rbx
jmp 0x1668
leaq -0x2(,%r12,2), %rbx
movq (%rsp), %rax
decl %eax
movq %rax, (%rsp)
leaq 0x30(%rsp), %r13
movl %r15d, %eax
cmpq %rax, %rbx
movq 0x8(%rsp), %rsi
je 0x16ba
movq %r13, %rdi
movq %r12, %rdx
movq (%rsp), %rcx
movl %r15d, %r8d
callq 0x180f
movq 0x10(%rsp), %r8
incl %r15d
jmp 0x1691
movq 0x60(%rsp), %r14
movl (%rsp), %eax
leaq (%r14,%rax,8), %rax
movq (%rax), %rax
testq %rax, %rax
je 0x16ed
xorl %ecx, %ecx
cmpl 0x4(%rax), %ecx
je 0x16e7
movl %ecx, %edx
imulq $0x18, %rdx, %rdx
movl 0x4(%rsi,%rdx), %edx
incl (%r8,%rdx,4)
incl %ecx
jmp 0x16d0
addq $0x8, %rax
jmp 0x16c6
movq 0x38(%rsp), %r13
movq 0x48(%rsp), %r15
movq 0x58(%rsp), %rbx
movq %r13, %rdi
callq 0x1030
movq %r15, %rdi
callq 0x1030
movq %rbx, %rdi
callq 0x1030
movq %r14, %rdi
callq 0x1030
movq 0x8(%rsp), %rdi
callq 0x1030
movl %ebp, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq