// File: /workspace/github_cpp_makefile_star2_O3/phillip-h[P]fractal-gen/lodepng.cpp
// Function: lodepng_huffman_code_lengths(unsigned int*, unsigned int const*, unsigned long, unsigned int)
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 $0x1, %eax
leaq -0x1(%rdx), %r8
movl $0x50, %ebx
movl %ecx, %r12d
shlxl %ecx, %eax, %eax
movl %eax, %eax
cmpq %rax, %r8
jae 0x45fb
leaq (,%rdx,8), %rax
movq %rdi, 0x18(%rsp)
movq %rdx, %r13
movq %rsi, %r15
leaq (%rax,%rax,2), %rdi
callq 0x21e0
testq %rax, %rax
je 0x42ae
movq 0x18(%rsp), %rsi
movq %rax, %r14
movq %r12, 0x10(%rsp)
xorl %eax, %eax
xorl %r12d, %r12d
movl (%r15,%rax,4), %ecx
testl %ecx, %ecx
je 0x4272
leaq (%r12,%r12,2), %rdx
incq %r12
movl %ecx, (%r14,%rdx,8)
movl %eax, 0x4(%r14,%rdx,8)
incq %rax
movl %eax, %ecx
cmpq %r13, %rcx
jne 0x425a
xorl %eax, %eax
movl $0x0, (%rsi,%rax,4)
incq %rax
movl %eax, %ecx
cmpq %r13, %rcx
jne 0x427e
cmpq $0x1, %r12
je 0x42b8
testq %r12, %r12
jne 0x42d6
movabsq $0x100000001, %rax      # imm = 0x100000001
xorl %ebx, %ebx
movq %rax, (%rsi)
jmp 0x45f3
movl $0x53, %ebx
jmp 0x45fb
movl 0x4(%r14), %eax
xorl %ecx, %ecx
movl $0x1, %edx
testq %rax, %rax
movl %edx, (%rsi,%rax,4)
sete %cl
xorl %ebx, %ebx
movl %edx, (%rsi,%rcx,4)
jmp 0x45f3
leaq (,%r12,8), %rax
leaq (%rax,%rax,2), %rdi
movq %rdi, 0x58(%rsp)
callq 0x21e0
movq %rax, 0x8(%rsp)
movl $0x1, %eax
xorl %esi, %esi
movq %r14, (%rsp)
movq 0x8(%rsp), %rcx
testb $0x1, %sil
movq %r14, %rbx
movq %rsi, 0x60(%rsp)
leaq (%rax,%rax), %rdx
movq %rcx, %rsi
cmoveq %rcx, %rbx
cmoveq %r14, %rsi
movq %rax, %rcx
shlq $0x4, %rcx
xorl %r9d, %r9d
leaq (%rcx,%rcx,2), %r8
leaq (%r9,%rax), %rcx
movq %r9, %r10
addq %rdx, %r9
movq %r12, %r15
cmpq %r12, %rcx
cmovaeq %r12, %rcx
cmpq %r12, %r9
cmovbq %r9, %r15
cmpq %r15, %r10
jae 0x43a1
movq %rbx, %rdi
movq %rcx, %r13
movq %r10, %r14
cmpq %rcx, %r14
jae 0x4370
cmpq %r15, %r13
jae 0x4378
leaq (%r14,%r14,2), %r11
leaq (%r13,%r13,2), %rbp
movl (%rsi,%r11,8), %r11d
cmpl (%rsi,%rbp,8), %r11d
jle 0x4378
movq %r13, %r11
incq %r13
jmp 0x437e
movq %r14, %r11
incq %r14
leaq (%r11,%r11,2), %r11
incq %r10
movq 0x10(%rsi,%r11,8), %rbp
movq %rbp, 0x10(%rdi)
vmovdqu (%rsi,%r11,8), %xmm0
vmovdqu %xmm0, (%rdi)
addq $0x18, %rdi
cmpq %r15, %r10
jb 0x4353
addq %r8, %rbx
cmpq %r12, %r9
jb 0x432a
movq 0x60(%rsp), %rcx
movq (%rsp), %r14
movq %rdx, %rax
leaq 0x1(%rcx), %rsi
cmpq %r12, %rdx
jb 0x42fc
testb $0x1, %cl
jne 0x43d9
movq 0x8(%rsp), %rsi
movq 0x58(%rsp), %rdx
movq %r14, %rdi
callq 0x2100
movq 0x8(%rsp), %rdi
callq 0x21b0
movq 0x10(%rsp), %rbx
xorl %eax, %eax
leal 0x1(%rbx), %ebp
movl %ebx, 0x40(%rsp)
imull %ebx, %ebp
addl %ebp, %ebp
leaq (,%rbp,8), %r15
movl %ebp, 0x20(%rsp)
movl %eax, 0x34(%rsp)
movl %ebp, 0x30(%rsp)
leaq (%r15,%r15,2), %rdi
callq 0x21e0
movq %r15, %rdi
movq %rax, %r14
movq %rax, 0x28(%rsp)
callq 0x21e0
movl %ebx, %r15d
shlq $0x3, %r15
movq %rax, %r13
movq %rax, 0x38(%rsp)
movq %r15, %rdi
callq 0x21e0
movq %r15, %rdi
movq %rax, %rbx
movq %rax, 0x48(%rsp)
callq 0x21e0
testq %r14, %r14
movq %rax, %r15
movq %rax, 0x50(%rsp)
movq %r14, %rsi
movq (%rsp), %r14
setne %al
testq %r13, %r13
setne %cl
testq %rbx, %rbx
movl $0x53, %ebx
setne %dl
andb %cl, %dl
movl $0x0, %ecx
andb %al, %dl
testq %r15, %r15
setne %al
testb %al, %dl
cmovnel %ecx, %ebx
je 0x45cd
testq %rbp, %rbp
je 0x44f0
vpmovsxbq 0xdd57(%rip), %zmm1 # 0x121f0
vpbroadcastq 0xdd3d(%rip), %zmm2 # 0x121e0
vpbroadcastq 0xdd3b(%rip), %zmm4 # 0x121e8
leaq 0x7(%rbp), %rax
decq %rbp
vpbroadcastq %rsi, %zmm3
xorl %ecx, %ecx
andq $-0x8, %rax
vpbroadcastq %rbp, %zmm0
vpmullq %zmm2, %zmm1, %zmm5
vpcmpleuq %zmm0, %zmm1, %k1
vpaddq %zmm4, %zmm1, %zmm1
vpaddq %zmm5, %zmm3, %zmm5
vmovdqu64 %zmm5, (%r13,%rcx,8) {%k1}
addq $0x8, %rcx
cmpq %rcx, %rax
jne 0x44c6
movl (%r14), %esi
leaq 0x20(%rsp), %r15
movl $0x1, %edx
xorl %ecx, %ecx
movq %r15, %rdi
vzeroupper
callq 0x460c
movl 0x18(%r14), %esi
movl $0x2, %edx
movq %r15, %rdi
xorl %ecx, %ecx
callq 0x460c
movl 0x20(%r15), %eax
testq %rax, %rax
je 0x454c
movq 0x28(%rsp), %rcx
movq 0x48(%rsp), %rdx
movq 0x50(%rsp), %rdi
xorl %r8d, %r8d
leaq 0x18(%rcx), %rsi
movq %rcx, (%rdx,%r8,8)
movq %rsi, (%rdi,%r8,8)
incq %r8
cmpq %r8, %rax
jne 0x453c
movq 0x10(%rsp), %r13
movq (%rsp), %rbp
leaq -0x2(%r12,%r12), %r14
decl %r13d
cmpq $0x2, %r14
je 0x4587
movl $0x2, %r15d
leaq 0x20(%rsp), %rdi
movq %rbp, %rsi
movq %r12, %rdx
movl %r13d, %ecx
movl %r15d, %r8d
callq 0x474c
incl %r15d
cmpq %r15, %r14
jne 0x4569
movq 0x50(%rsp), %r15
movl %r13d, %eax
movq (%r15,%rax,8), %rax
testq %rax, %rax
je 0x45c9
movq (%rsp), %r14
movq 0x18(%rsp), %rsi
cmpl $0x0, 0x4(%rax)
je 0x45be
xorl %ecx, %ecx
movl %ecx, %edx
leaq (%rdx,%rdx,2), %rdx
incl %ecx
movl 0x4(%r14,%rdx,8), %edx
incl (%rsi,%rdx,4)
cmpl 0x4(%rax), %ecx
jne 0x45a9
movq 0x8(%rax), %rax
testq %rax, %rax
jne 0x45a1
jmp 0x45cd
movq (%rsp), %r14
movq 0x28(%rsp), %rdi
callq 0x21b0
movq 0x38(%rsp), %rdi
callq 0x21b0
movq 0x48(%rsp), %rdi
callq 0x21b0
movq %r15, %rdi
callq 0x21b0
movq %r14, %rdi
callq 0x21b0
movl %ebx, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq