// File: /workspace/github_c_makefile_star2_O3/enzo1982[P]smooth/libraries/libwebp/src/utils/huffman_utils.c
// Function: BuildHuffmanTable
static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
                             const int code_lengths[], int code_lengths_size,
                             uint16_t sorted[]) {
  HuffmanCode* table = root_table;  // next available space in table
  int total_size = 1 << root_bits;  // total size root table + 2nd level table
  int len;                          // current code length
  int symbol;                       // symbol index in original or sorted table
  // number of codes of each length:
  int count[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 };
  // offsets in sorted table for each length:
  int offset[MAX_ALLOWED_CODE_LENGTH + 1];

  assert(code_lengths_size != 0);
  assert(code_lengths != NULL);
  assert((root_table != NULL && sorted != NULL) ||
         (root_table == NULL && sorted == NULL));
  assert(root_bits > 0);

  // Build histogram of code lengths.
  for (symbol = 0; symbol < code_lengths_size; ++symbol) {
    if (code_lengths[symbol] > MAX_ALLOWED_CODE_LENGTH) {
      return 0;
    }
    ++count[code_lengths[symbol]];
  }

  // Error, all code lengths are zeros.
  if (count[0] == code_lengths_size) {
    return 0;
  }

  // Generate offsets into sorted symbol table by code length.
  offset[1] = 0;
  for (len = 1; len < MAX_ALLOWED_CODE_LENGTH; ++len) {
    if (count[len] > (1 << len)) {
      return 0;
    }
    offset[len + 1] = offset[len] + count[len];
  }

  // Sort symbols by length, by symbol order within each length.
  for (symbol = 0; symbol < code_lengths_size; ++symbol) {
    const int symbol_code_length = code_lengths[symbol];
    if (code_lengths[symbol] > 0) {
      if (sorted != NULL) {
        if(offset[symbol_code_length] >= code_lengths_size) {
            return 0;
        }
        sorted[offset[symbol_code_length]++] = symbol;
      } else {
        offset[symbol_code_length]++;
      }
    }
  }

  // Special case code with only one value.
  if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) {
    if (sorted != NULL) {
      HuffmanCode code;
      code.bits = 0;
      code.value = (uint16_t)sorted[0];
      ReplicateValue(table, 1, total_size, code);
    }
    return total_size;
  }

  {
    int step;              // step size to replicate values in current table
    uint32_t low = 0xffffffffu;        // low bits for current root entry
    uint32_t mask = total_size - 1;    // mask for low bits
    uint32_t key = 0;      // reversed prefix code
    int num_nodes = 1;     // number of Huffman tree nodes
    int num_open = 1;      // number of open branches in current tree level
    int table_bits = root_bits;        // key length of current table
    int table_size = 1 << table_bits;  // size of current table
    symbol = 0;
    // Fill in root table.
    for (len = 1, step = 2; len <= root_bits; ++len, step <<= 1) {
      num_open <<= 1;
      num_nodes += num_open;
      num_open -= count[len];
      if (num_open < 0) {
        return 0;
      }
      if (root_table == NULL) continue;
      for (; count[len] > 0; --count[len]) {
        HuffmanCode code;
        code.bits = (uint8_t)len;
        code.value = (uint16_t)sorted[symbol++];
        ReplicateValue(&table[key], step, table_size, code);
        key = GetNextKey(key, len);
      }
    }

    // Fill in 2nd level tables and add pointers to root table.
    for (len = root_bits + 1, step = 2; len <= MAX_ALLOWED_CODE_LENGTH;
         ++len, step <<= 1) {
      num_open <<= 1;
      num_nodes += num_open;
      num_open -= count[len];
      if (num_open < 0) {
        return 0;
      }
      for (; count[len] > 0; --count[len]) {
        HuffmanCode code;
        if ((key & mask) != low) {
          if (root_table != NULL) table += table_size;
          table_bits = NextTableBitSize(count, len, root_bits);
          table_size = 1 << table_bits;
          total_size += table_size;
          low = key & mask;
          if (root_table != NULL) {
            root_table[low].bits = (uint8_t)(table_bits + root_bits);
            root_table[low].value = (uint16_t)((table - root_table) - low);
          }
        }
        if (root_table != NULL) {
          code.bits = (uint8_t)(len - root_bits);
          code.value = (uint16_t)sorted[symbol++];
          ReplicateValue(&table[key >> root_bits], step, table_size, code);
        }
        key = GetNextKey(key, len);
      }
    }

    // Check if tree is full.
    if (num_nodes != 2 * offset[MAX_ALLOWED_CODE_LENGTH] - 1) {
      return 0;
    }
  }

  return total_size;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movl %ecx, %r9d
movl %esi, %ecx
movl $0x1, %eax
shll %cl, %eax
movq %rax, (%rsp)
pxor %xmm0, %xmm0
movdqa %xmm0, 0x80(%rsp)
movdqa %xmm0, 0x70(%rsp)
movdqa %xmm0, 0x60(%rsp)
movdqa %xmm0, 0x50(%rsp)
testl %r9d, %r9d
je 0xf08ab
testq %rdx, %rdx
je 0xf08ca
testq %rdi, %rdi
setne %al
testq %r8, %r8
setne %sil
testb %sil, %al
jne 0xf0377
movq %rdi, %rax
orq %r8, %rax
jne 0xf0908
testl %ecx, %ecx
jle 0xf08e9
movl %r9d, %ebx
xorl %eax, %eax
movl $0x0, %esi
testl %r9d, %r9d
jle 0xf03af
xorl %r10d, %r10d
movslq (%rdx,%r10,4), %rsi
cmpq $0xf, %rsi
jg 0xf0861
incl 0x50(%rsp,%rsi,4)
incq %r10
cmpq %r10, %rbx
jne 0xf0391
movl 0x50(%rsp), %esi
cmpl %r9d, %esi
je 0xf0863
movq %rcx, 0x10(%rsp)
movl $0x0, 0x94(%rsp)
xorl %eax, %eax
xorl %esi, %esi
movl 0x54(%rsp,%rsi,4), %r11d
leal 0x1(%rsi), %ecx
movl $0x1, %r10d
shll %cl, %r10d
cmpl %r10d, %r11d
jg 0xf0863
addl 0x94(%rsp,%rsi,4), %r11d
movl %r11d, 0x98(%rsp,%rsi,4)
incq %rsi
cmpq $0xe, %rsi
jne 0xf03cc
testl %r9d, %r9d
movq 0x10(%rsp), %r11
jle 0xf0450
xorl %ecx, %ecx
movslq (%rdx,%rcx,4), %rsi
testq %rsi, %rsi
jle 0xf0448
movslq 0x90(%rsp,%rsi,4), %r9
testq %r8, %r8
je 0xf043d
cmpl %ebx, %r9d
jge 0xf0861
leal 0x1(%r9), %r10d
movl %r10d, 0x90(%rsp,%rsi,4)
movw %cx, (%r8,%r9,2)
jmp 0xf0448
incl %r9d
movl %r9d, 0x90(%rsp,%rsi,4)
incq %rcx
cmpq %rcx, %rbx
jne 0xf040b
movl 0xcc(%rsp), %eax
cmpl $0x1, %eax
jne 0xf0575
testq %r8, %r8
je 0xf056c
movzwl (%r8), %eax
shll $0x10, %eax
movslq (%rsp), %rdx
cmpq $0x2, %rdx
movl $0x1, %esi
cmovgeq %rdx, %rsi
leal 0x3(%rsi), %ecx
andl $-0x4, %ecx
decq %rsi
movq %rsi, %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
leaq (%rdi,%rdx,4), %rdx
addq $-0x4, %rdx
xorl %esi, %esi
movdqa 0x228ba(%rip), %xmm1    # 0x112d60
movdqa 0x228c2(%rip), %xmm2    # 0x112d70
movdqa 0x228ca(%rip), %xmm3    # 0x112d80
pxor %xmm3, %xmm0
pcmpeqd %xmm4, %xmm4
movq %rsi, %xmm5
pshufd $0x44, %xmm5, %xmm5     # xmm5 = xmm5[0,1,0,1]
movdqa %xmm5, %xmm6
por %xmm2, %xmm6
pxor %xmm3, %xmm6
movdqa %xmm6, %xmm7
pcmpgtd %xmm0, %xmm7
pcmpeqd %xmm0, %xmm6
pshufd $0xf5, %xmm6, %xmm8     # xmm8 = xmm6[1,1,3,3]
pand %xmm7, %xmm8
pshufd $0xf5, %xmm7, %xmm6     # xmm6 = xmm7[1,1,3,3]
por %xmm8, %xmm6
movd %xmm6, %edi
notl %edi
testb $0x1, %dil
je 0xf0503
movl %eax, (%rdx)
pxor %xmm4, %xmm6
pextrw $0x4, %xmm6, %edi
testb $0x1, %dil
je 0xf0515
movl %eax, -0x4(%rdx)
por %xmm1, %xmm5
pxor %xmm3, %xmm5
movdqa %xmm5, %xmm6
pcmpgtd %xmm0, %xmm6
pcmpeqd %xmm0, %xmm5
pshufd $0xf5, %xmm5, %xmm7     # xmm7 = xmm5[1,1,3,3]
pand %xmm6, %xmm7
pshufd $0xf5, %xmm6, %xmm5     # xmm5 = xmm6[1,1,3,3]
por %xmm7, %xmm5
pxor %xmm4, %xmm5
pextrw $0x0, %xmm5, %edi
testb $0x1, %dil
je 0xf054d
movl %eax, -0x8(%rdx)
pextrw $0x4, %xmm5, %edi
testb $0x1, %dil
je 0xf055b
movl %eax, -0xc(%rdx)
addq $0x4, %rsi
addq $-0x10, %rdx
cmpq %rsi, %rcx
jne 0xf04be
movq (%rsp), %rax
jmp 0xf0863
movq %rax, 0x18(%rsp)
movq (%rsp), %rax
decl %eax
movl %eax, 0x44(%rsp)
leal 0x1(%r11), %edx
movl $0x2, %esi
movl $0x1, %r11d
movl $0x1, %r9d
xorl %r14d, %r14d
movl $0x1, %r10d
xorl %ebp, %ebp
movq %rdx, 0x8(%rsp)
leal (%r11,%r11), %r13d
movl 0x50(%rsp,%r9,4), %ebx
subl %ebx, %r13d
js 0xf0861
testq %rdi, %rdi
sete %al
testl %ebx, %ebx
setle %cl
orb %al, %cl
jne 0xf065c
movq %r13, 0x20(%rsp)
movq %r10, 0x28(%rsp)
leal -0x1(%rsi), %eax
leal -0x1(%r9), %ecx
movl $0x1, %r12d
shll %cl, %r12d
testl %eax, (%rsp)
jne 0xf088c
movzbl %r9b, %ecx
movslq %r14d, %r14
movl %esi, %r13d
negl %r13d
movl %ebp, %eax
leaq (%rdi,%rax,4), %rax
movzwl (%r8,%r14,2), %edx
shll $0x10, %edx
orl %ecx, %edx
movq (%rsp), %r10
leal (%r10,%r13), %r15d
subl %esi, %r10d
movslq %r15d, %r15
movl %edx, (%rax,%r15,4)
testl %r10d, %r10d
jg 0xf0612
movl %r12d, %edx
movl %edx, %eax
shrl %edx
testl %ebp, %eax
jne 0xf0628
incq %r14
leal -0x1(%rax), %edx
andl %edx, %ebp
addl %eax, %ebp
leal -0x1(%rbx), %eax
cmpl $0x1, %ebx
movl %eax, %ebx
jg 0xf05fe
movl $0x0, 0x50(%rsp,%r9,4)
movq 0x28(%rsp), %r10
movq 0x20(%rsp), %r13
movq 0x8(%rsp), %rdx
leal (%r10,%r11,2), %r10d
incq %r9
addl %esi, %esi
movl %r13d, %r11d
cmpq %rdx, %r9
jne 0xf05a9
movq 0x10(%rsp), %r11
cmpl $0xe, %r11d
jg 0xf0875
movl %r11d, %r9d
leaq (%rsp,%r9,4), %rax
addq $0x54, %rax
movq %rax, 0x48(%rsp)
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl $0x2, %ebx
movq %rdi, %r12
movq (%rsp), %rax
leal (,%r13,2), %edx
movl 0x54(%rsp,%r9,4), %ecx
subl %ecx, %edx
js 0xf0861
movl %edx, 0x34(%rsp)
leaq 0x1(%r9), %rdx
testl %ecx, %ecx
jle 0xf0838
movq %r13, 0x20(%rsp)
movq %r10, 0x28(%rsp)
movl %edx, %r10d
subl %r11d, %r10d
movl $0x1, %r11d
movl %r10d, %ecx
shll %cl, %r11d
movl %r11d, 0x18(%rsp)
movq 0x10(%rsp), %r11
movl $0x1, %r15d
movq %r9, 0x8(%rsp)
movl %r9d, %ecx
shll %cl, %r15d
movl %r10d, 0x38(%rsp)
movzbl %r10b, %ecx
movl %ecx, 0x3c(%rsp)
leal -0x1(%rbx), %ecx
movl %ecx, 0x40(%rsp)
movl %ebx, %r13d
negl %r13d
movl %ebp, %r9d
andl 0x44(%rsp), %r9d
cmpl %esi, %r9d
jne 0xf0732
testq %rdi, %rdi
jne 0xf07b0
jmp 0xf07fd
movl 0x18(%rsp), %esi
movl 0x38(%rsp), %ecx
cmpq $0xe, 0x8(%rsp)
je 0xf077c
movq 0x48(%rsp), %rsi
movq 0x8(%rsp), %rcx
movl 0x18(%rsp), %r11d
subl (%rsi), %r11d
jle 0xf076b
addl %r11d, %r11d
incl %ecx
addq $0x4, %rsi
cmpl $0xe, %ecx
jl 0xf0751
movl $0xf, %ecx
jmp 0xf076d
incl %ecx
movq 0x10(%rsp), %r11
subl %r11d, %ecx
movl $0x1, %esi
shll %cl, %esi
movq (%rsp), %r10
addl %esi, %r10d
movq %r10, (%rsp)
testq %rdi, %rdi
je 0xf07f8
cltq
leaq (%r12,%rax,4), %r12
addl %r11d, %ecx
movl %r9d, %eax
movb %cl, (%rdi,%rax,4)
movl %r12d, %ecx
subl %edi, %ecx
shrl $0x2, %ecx
subl %r9d, %ecx
movw %cx, 0x2(%rdi,%rax,4)
movl %esi, %eax
movl %r9d, %esi
movl %ebp, %r9d
movl %r11d, %ecx
shrl %cl, %r9d
testl %eax, 0x40(%rsp)
jne 0xf088c
movslq %r14d, %r10
incl %r14d
leaq (%r12,%r9,4), %rcx
movzwl (%r8,%r10,2), %r9d
shll $0x10, %r9d
addl 0x3c(%rsp), %r9d
movl %eax, %r10d
leal (%r10,%r13), %r11d
subl %ebx, %r10d
movslq %r11d, %r11
movl %r9d, (%rcx,%r11,4)
testl %r10d, %r10d
jg 0xf07de
movq 0x10(%rsp), %r11
jmp 0xf07fd
movl %esi, %eax
movl %r9d, %esi
movl %r15d, %r9d
movl %r9d, %ecx
shrl %r9d
testl %ebp, %ecx
jne 0xf0800
leal -0x1(%rcx), %r9d
andl %r9d, %ebp
addl %ecx, %ebp
movl 0x50(%rsp,%rdx,4), %ecx
leal -0x1(%rcx), %r9d
movl %r9d, 0x50(%rsp,%rdx,4)
cmpl $0x1, %ecx
jg 0xf0717
movq 0x28(%rsp), %r10
movq 0x20(%rsp), %r13
movq 0x8(%rsp), %r9
leal (%r10,%r13,2), %r10d
addl %ebx, %ebx
addq $0x4, 0x48(%rsp)
movl 0x34(%rsp), %ecx
movl %ecx, %r13d
cmpl $0xe, %r9d
movq %rdx, %r9
jl 0xf06a1
movl 0xcc(%rsp), %eax
jmp 0xf087a
xorl %eax, %eax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x18(%rsp), %rax
leal -0x1(,%rax,2), %ecx
xorl %eax, %eax
cmpl %ecx, %r10d
cmovel (%rsp), %eax
jmp 0xf0863
leaq 0x3d54c(%rip), %rdi     # 0x12dddf
leaq 0x3d3bd(%rip), %rsi     # 0x12dc57
leaq 0x3d54e(%rip), %rcx     # 0x12ddef
movl $0x38, %edx
callq 0x55710
leaq 0x3d455(%rip), %rdi     # 0x12dd07
leaq 0x3d39e(%rip), %rsi     # 0x12dc57
leaq 0x3d45e(%rip), %rcx     # 0x12dd1e
movl $0x5c, %edx
callq 0x55710
leaq 0x3d49a(%rip), %rdi     # 0x12dd6b
leaq 0x3d37f(%rip), %rsi     # 0x12dc57
leaq 0x3d43f(%rip), %rcx     # 0x12dd1e
movl $0x5d, %edx
callq 0x55710
leaq 0x3d4e1(%rip), %rdi     # 0x12ddd1
leaq 0x3d360(%rip), %rsi     # 0x12dc57
leaq 0x3d420(%rip), %rcx     # 0x12dd1e
movl $0x60, %edx
callq 0x55710
leaq 0x3d471(%rip), %rdi     # 0x12dd80
leaq 0x3d341(%rip), %rsi     # 0x12dc57
leaq 0x3d401(%rip), %rcx     # 0x12dd1e
movl $0x5f, %edx
callq 0x55710