// File: /workspace/github_c_makefile_star2_O3/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, %ebx
cmpq %rax, %rcx
jae 0x17cc
movq %rdx, %r13
movq %rsi, %r15
movq %rdi, %r14
leaq (,%rdx,8), %rax
leaq (%rax,%rax,2), %rdi
callq 0x1100
testq %rax, %rax
je 0x146f
movq %rax, %rbp
movq %r12, 0x10(%rsp)
xorl %eax, %eax
xorl %r12d, %r12d
movl (%r15,%rax,4), %ecx
testl %ecx, %ecx
je 0x1437
leaq (%r12,%r12,2), %rdx
movl %ecx, (%rbp,%rdx,8)
movl %eax, 0x4(%rbp,%rdx,8)
incq %r12
incq %rax
movl %eax, %ecx
cmpq %r13, %rcx
jne 0x1420
xorl %eax, %eax
movl $0x0, (%r14,%rax,4)
incq %rax
movl %eax, %ecx
cmpq %r13, %rcx
jne 0x1443
cmpq $0x1, %r12
je 0x1479
testq %r12, %r12
jne 0x1498
movabsq $0x100000001, %rax      # imm = 0x100000001
movq %rax, (%r14)
jmp 0x1491
movl $0x53, %ebx
jmp 0x17cc
movl 0x4(%rbp), %eax
xorl %ecx, %ecx
testq %rax, %rax
sete %cl
movl $0x1, %edx
movl %edx, (%r14,%rax,4)
movl %edx, (%r14,%rcx,4)
xorl %ebx, %ebx
jmp 0x17c4
movq %r14, 0x50(%rsp)
leaq (,%r12,8), %rax
leaq (%rax,%rax,2), %rdi
movq %rdi, 0x58(%rsp)
callq 0x1100
movq %rax, (%rsp)
movl $0x1, %eax
xorl %esi, %esi
movq %rbp, 0x60(%rsp)
movq %rsi, 0x8(%rsp)
testb $0x1, %sil
movq (%rsp), %rcx
movq %rcx, %rsi
cmoveq %rbp, %rsi
movq %rbp, %rbx
cmoveq %rcx, %rbx
leaq (%rax,%rax), %rdx
movq %rax, %rdi
shlq $0x4, %rdi
leaq (%rdi,%rdi,2), %r8
xorl %r9d, %r9d
movq %r9, %r10
leaq (%r9,%rax), %rbp
cmpq %r12, %rbp
cmovaeq %r12, %rbp
addq %rdx, %r9
cmpq %r12, %r9
movq %r12, %r15
cmovbq %r9, %r15
cmpq %r15, %r10
jae 0x156a
movq %rbx, %rdi
movq %rbp, %r13
movq %r10, %r14
cmpq %rbp, %r14
jae 0x153c
cmpq %r15, %r13
jae 0x1544
leaq (%r14,%r14,2), %r11
movl (%rsi,%r11,8), %r11d
leaq (,%r13,2), %rcx
addq %r13, %rcx
cmpl (%rsi,%rcx,8), %r11d
jle 0x1544
movq %r13, %r11
incq %r13
jmp 0x154a
movq %r14, %r11
incq %r14
leaq (%r11,%r11,2), %rcx
movq 0x10(%rsi,%rcx,8), %r11
movq %r11, 0x10(%rdi)
movups (%rsi,%rcx,8), %xmm0
movups %xmm0, (%rdi)
incq %r10
addq $0x18, %rdi
cmpq %r15, %r10
jb 0x1519
addq %r8, %rbx
cmpq %r12, %r9
jb 0x14f0
movq 0x8(%rsp), %rcx
leaq 0x1(%rcx), %rsi
movq %rdx, %rax
cmpq %r12, %rdx
movq 0x60(%rsp), %rbp
jb 0x14c3
testb $0x1, %cl
jne 0x15a6
movq %rbp, %rdi
movq (%rsp), %rsi
movq 0x58(%rsp), %rdx
callq 0x10f0
movq (%rsp), %rdi
callq 0x1030
movq 0x10(%rsp), %rbx
movl %ebx, 0x38(%rsp)
leal 0x1(%rbx), %r13d
imull %ebx, %r13d
addl %r13d, %r13d
movl %r13d, 0x18(%rsp)
movl $0x0, 0x2c(%rsp)
movl %r13d, 0x28(%rsp)
leaq (,%r13,8), %r15
leaq (%r15,%r15,2), %rdi
callq 0x1100
movq %rax, 0x8(%rsp)
movq %rax, 0x20(%rsp)
movq %r15, %rdi
callq 0x1100
movq %rax, %r14
movq %rax, 0x30(%rsp)
movl %ebx, %r15d
shlq $0x3, %r15
movq %r15, %rdi
callq 0x1100
movq %rax, %rbx
movq %rax, 0x40(%rsp)
movq %r15, %rdi
callq 0x1100
movq %r14, %rcx
movq %rax, %r14
movq %rax, 0x48(%rsp)
movq 0x8(%rsp), %xmm0
movq %rcx, %xmm1
movdqa %xmm0, %xmm2
punpcklqdq %xmm1, %xmm2    # xmm2 = xmm2[0],xmm1[0]
movq %rbx, %xmm1
movq %rax, %xmm3
punpcklqdq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0]
pxor %xmm3, %xmm3
pcmpeqd %xmm3, %xmm2
pcmpeqd %xmm3, %xmm1
movdqa %xmm2, %xmm3
shufps $0xdd, %xmm1, %xmm3     # xmm3 = xmm3[1,3],xmm1[1,3]
shufps $0x88, %xmm1, %xmm2     # xmm2 = xmm2[0,2],xmm1[0,2]
andps %xmm3, %xmm2
movmskps %xmm2, %eax
movl $0x53, %ebx
testl %eax, %eax
cmovel %eax, %ebx
jne 0x179e
testq %r13, %r13
je 0x16d1
movdqa 0xc98a(%rip), %xmm1     # 0xe010
xorl %eax, %eax
movdqa 0xc990(%rip), %xmm2     # 0xe020
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
movdqa 0xc993(%rip), %xmm3     # 0xe030
movdqa %xmm1, %xmm4
pmuludq %xmm2, %xmm4
paddq %xmm0, %xmm4
movdqa %xmm1, %xmm5
psrlq $0x20, %xmm5
pmuludq %xmm2, %xmm5
psllq $0x20, %xmm5
paddq %xmm4, %xmm5
movdqu %xmm5, (%rcx,%rax,8)
addq $0x2, %rax
paddq %xmm3, %xmm1
cmpq %rax, %r13
jne 0x169d
movl (%rbp), %esi
leaq 0x18(%rsp), %r15
movq %r15, %rdi
movl $0x1, %edx
xorl %ecx, %ecx
callq 0x17dd
movl 0x18(%rbp), %esi
movq %r15, %rdi
movl $0x2, %edx
xorl %ecx, %ecx
callq 0x17dd
movl 0x20(%r15), %eax
testq %rax, %rax
je 0x1729
movq 0x20(%rsp), %rcx
movq 0x40(%rsp), %rdx
leaq 0x18(%rcx), %rsi
movq 0x48(%rsp), %rdi
xorl %r8d, %r8d
movq %rcx, (%rdx,%r8,8)
movq %rsi, (%rdi,%r8,8)
incq %r8
cmpq %r8, %rax
jne 0x1719
leaq -0x2(,%r12,2), %r14
movq 0x10(%rsp), %r13
decl %r13d
cmpq $0x2, %r14
je 0x1763
movl $0x2, %r15d
leaq 0x18(%rsp), %rdi
movq %rbp, %rsi
movq %r12, %rdx
movl %r13d, %ecx
movl %r15d, %r8d
callq 0x19b2
incl %r15d
cmpq %r15, %r14
jne 0x1745
movq 0x48(%rsp), %r14
movl %r13d, %eax
movq (%r14,%rax,8), %rax
testq %rax, %rax
je 0x179e
movq 0x50(%rsp), %rsi
cmpl $0x0, 0x4(%rax)
je 0x1795
xorl %ecx, %ecx
movl %ecx, %edx
leaq (%rdx,%rdx,2), %rdx
movl 0x4(%rbp,%rdx,8), %edx
incl (%rsi,%rdx,4)
incl %ecx
cmpl 0x4(%rax), %ecx
jne 0x1781
movq 0x8(%rax), %rax
testq %rax, %rax
jne 0x1779
movq 0x20(%rsp), %rdi
callq 0x1030
movq 0x30(%rsp), %rdi
callq 0x1030
movq 0x40(%rsp), %rdi
callq 0x1030
movq %r14, %rdi
callq 0x1030
movq %rbp, %rdi
callq 0x1030
movl %ebx, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq