// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movq %r8, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x38(%rbp)
movl -0x14(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, -0x3c(%rbp)
leaq -0x90(%rbp), %rdi
xorl %esi, %esi
movl $0x40, %edx
callq 0x5a200
cmpl $0x0, -0x24(%rbp)
je 0x182a9d
jmp 0x182abc
leaq 0x3ebff(%rip), %rdi     # 0x1c16a3
leaq 0x3eb48(%rip), %rsi     # 0x1c15f3
movl $0x5c, %edx
leaq 0x3ec03(%rip), %rcx     # 0x1c16ba
callq 0x598a0
cmpq $0x0, -0x20(%rbp)
je 0x182ac5
jmp 0x182ae4
leaq 0x3ec3b(%rip), %rdi     # 0x1c1707
leaq 0x3eb20(%rip), %rsi     # 0x1c15f3
movl $0x5d, %edx
leaq 0x3ebdb(%rip), %rcx     # 0x1c16ba
callq 0x598a0
cmpq $0x0, -0x10(%rbp)
je 0x182af2
cmpq $0x0, -0x30(%rbp)
jne 0x182b00
cmpq $0x0, -0x10(%rbp)
jne 0x182b02
cmpq $0x0, -0x30(%rbp)
jne 0x182b02
jmp 0x182b21
leaq 0x3ec13(%rip), %rdi     # 0x1c171c
leaq 0x3eae3(%rip), %rsi     # 0x1c15f3
movl $0x5f, %edx
leaq 0x3eb9e(%rip), %rcx     # 0x1c16ba
callq 0x598a0
cmpl $0x0, -0x14(%rbp)
jle 0x182b29
jmp 0x182b48
leaq 0x3ec3d(%rip), %rdi     # 0x1c176d
leaq 0x3eabc(%rip), %rsi     # 0x1c15f3
movl $0x60, %edx
leaq 0x3eb77(%rip), %rcx     # 0x1c16ba
callq 0x598a0
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0x182b99
movq -0x20(%rbp), %rax
movslq -0x44(%rbp), %rcx
cmpl $0xf, (%rax,%rcx,4)
jle 0x182b71
movl $0x0, -0x4(%rbp)
jmp 0x1830a5
movq -0x20(%rbp), %rax
movslq -0x44(%rbp), %rcx
movslq (%rax,%rcx,4), %rax
movl -0x90(%rbp,%rax,4), %ecx
addl $0x1, %ecx
movl %ecx, -0x90(%rbp,%rax,4)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x182b4f
movl -0x90(%rbp), %eax
cmpl -0x24(%rbp), %eax
jne 0x182bb0
movl $0x0, -0x4(%rbp)
jmp 0x1830a5
movl $0x0, -0xcc(%rbp)
movl $0x1, -0x40(%rbp)
cmpl $0xf, -0x40(%rbp)
jge 0x182c1e
movslq -0x40(%rbp), %rax
movl -0x90(%rbp,%rax,4), %eax
movl -0x40(%rbp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
cmpl %ecx, %eax
jle 0x182bee
movl $0x0, -0x4(%rbp)
jmp 0x1830a5
movslq -0x40(%rbp), %rax
movl -0xd0(%rbp,%rax,4), %ecx
movslq -0x40(%rbp), %rax
addl -0x90(%rbp,%rax,4), %ecx
movl -0x40(%rbp), %eax
addl $0x1, %eax
cltq
movl %ecx, -0xd0(%rbp,%rax,4)
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x182bc1
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0x182ccd
movq -0x20(%rbp), %rax
movslq -0x44(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0xd4(%rbp)
movq -0x20(%rbp), %rax
movslq -0x44(%rbp), %rcx
cmpl $0x0, (%rax,%rcx,4)
jle 0x182cbd
cmpq $0x0, -0x30(%rbp)
je 0x182ca3
movslq -0xd4(%rbp), %rax
movl -0xd0(%rbp,%rax,4), %eax
cmpl -0x24(%rbp), %eax
jl 0x182c76
movl $0x0, -0x4(%rbp)
jmp 0x1830a5
movl -0x44(%rbp), %eax
movw %ax, %dx
movq -0x30(%rbp), %rax
movslq -0xd4(%rbp), %rsi
movl -0xd0(%rbp,%rsi,4), %ecx
movl %ecx, %edi
addl $0x1, %edi
movl %edi, -0xd0(%rbp,%rsi,4)
movslq %ecx, %rcx
movw %dx, (%rax,%rcx,2)
jmp 0x182cbb
movslq -0xd4(%rbp), %rax
movl -0xd0(%rbp,%rax,4), %ecx
addl $0x1, %ecx
movl %ecx, -0xd0(%rbp,%rax,4)
jmp 0x182cbd
jmp 0x182cbf
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x182c25
cmpl $0x1, -0x94(%rbp)
jne 0x182d14
cmpq $0x0, -0x30(%rbp)
je 0x182d09
movb $0x0, -0xd8(%rbp)
movq -0x30(%rbp), %rax
movw (%rax), %ax
movw %ax, -0xd6(%rbp)
movq -0x38(%rbp), %rdi
movl -0x3c(%rbp), %edx
movl -0xd8(%rbp), %ecx
movl $0x1, %esi
callq 0x1831e0
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1830a5
movl $0xffffffff, -0xe0(%rbp) # imm = 0xFFFFFFFF
movl -0x3c(%rbp), %eax
subl $0x1, %eax
movl %eax, -0xe4(%rbp)
movl $0x0, -0xe8(%rbp)
movl $0x1, -0xec(%rbp)
movl $0x1, -0xf0(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0xf4(%rbp)
movl -0xf4(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, -0xf8(%rbp)
movl $0x0, -0x44(%rbp)
movl $0x1, -0x40(%rbp)
movl $0x2, -0xdc(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x14(%rbp), %eax
jg 0x182e8c
movl -0xf0(%rbp), %eax
shll %eax
movl %eax, -0xf0(%rbp)
movl -0xf0(%rbp), %eax
addl -0xec(%rbp), %eax
movl %eax, -0xec(%rbp)
movslq -0x40(%rbp), %rax
movl -0x90(%rbp,%rax,4), %ecx
movl -0xf0(%rbp), %eax
subl %ecx, %eax
movl %eax, -0xf0(%rbp)
cmpl $0x0, -0xf0(%rbp)
jge 0x182dd6
movl $0x0, -0x4(%rbp)
jmp 0x1830a5
cmpq $0x0, -0x10(%rbp)
jne 0x182de2
jmp 0x182e70
jmp 0x182de4
movslq -0x40(%rbp), %rax
cmpl $0x0, -0x90(%rbp,%rax,4)
jle 0x182e6e
movl -0x40(%rbp), %eax
movb %al, -0xfc(%rbp)
movq -0x30(%rbp), %rax
movl -0x44(%rbp), %ecx
movl %ecx, %edx
addl $0x1, %edx
movl %edx, -0x44(%rbp)
movslq %ecx, %rcx
movw (%rax,%rcx,2), %ax
movw %ax, -0xfa(%rbp)
movq -0x38(%rbp), %rdi
movl -0xe8(%rbp), %eax
shlq $0x2, %rax
addq %rax, %rdi
movl -0xdc(%rbp), %esi
movl -0xf8(%rbp), %edx
movl -0xfc(%rbp), %ecx
callq 0x1831e0
movl -0xe8(%rbp), %edi
movl -0x40(%rbp), %esi
callq 0x183250
movl %eax, -0xe8(%rbp)
movslq -0x40(%rbp), %rax
movl -0x90(%rbp,%rax,4), %ecx
addl $-0x1, %ecx
movl %ecx, -0x90(%rbp,%rax,4)
jmp 0x182de4
jmp 0x182e70
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
movl -0xdc(%rbp), %eax
shll %eax
movl %eax, -0xdc(%rbp)
jmp 0x182d7c
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
movl $0x2, -0xdc(%rbp)
cmpl $0xf, -0x40(%rbp)
jg 0x183081
movl -0xf0(%rbp), %eax
shll %eax
movl %eax, -0xf0(%rbp)
movl -0xf0(%rbp), %eax
addl -0xec(%rbp), %eax
movl %eax, -0xec(%rbp)
movslq -0x40(%rbp), %rax
movl -0x90(%rbp,%rax,4), %ecx
movl -0xf0(%rbp), %eax
subl %ecx, %eax
movl %eax, -0xf0(%rbp)
cmpl $0x0, -0xf0(%rbp)
jge 0x182ef7
movl $0x0, -0x4(%rbp)
jmp 0x1830a5
jmp 0x182ef9
movslq -0x40(%rbp), %rax
cmpl $0x0, -0x90(%rbp,%rax,4)
jle 0x183063
movl -0xe8(%rbp), %eax
andl -0xe4(%rbp), %eax
cmpl -0xe0(%rbp), %eax
je 0x182fd6
cmpq $0x0, -0x10(%rbp)
je 0x182f42
movl -0xf8(%rbp), %ecx
movq -0x38(%rbp), %rax
movslq %ecx, %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
leaq -0x90(%rbp), %rdi
movl -0x40(%rbp), %esi
movl -0x14(%rbp), %edx
callq 0x1832b0
movl %eax, -0xf4(%rbp)
movl -0xf4(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, -0xf8(%rbp)
movl -0xf8(%rbp), %eax
addl -0x3c(%rbp), %eax
movl %eax, -0x3c(%rbp)
movl -0xe8(%rbp), %eax
andl -0xe4(%rbp), %eax
movl %eax, -0xe0(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x182fd4
movl -0xf4(%rbp), %eax
addl -0x14(%rbp), %eax
movb %al, %dl
movq -0x10(%rbp), %rax
movl -0xe0(%rbp), %ecx
movb %dl, (%rax,%rcx,4)
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
subq %rcx, %rax
sarq $0x2, %rax
movl -0xe0(%rbp), %ecx
subq %rcx, %rax
movw %ax, %dx
movq -0x10(%rbp), %rax
movl -0xe0(%rbp), %ecx
movw %dx, 0x2(%rax,%rcx,4)
jmp 0x182fd6
cmpq $0x0, -0x10(%rbp)
je 0x183035
movl -0x40(%rbp), %eax
subl -0x14(%rbp), %eax
movb %al, -0x100(%rbp)
movq -0x30(%rbp), %rax
movl -0x44(%rbp), %ecx
movl %ecx, %edx
addl $0x1, %edx
movl %edx, -0x44(%rbp)
movslq %ecx, %rcx
movw (%rax,%rcx,2), %ax
movw %ax, -0xfe(%rbp)
movq -0x38(%rbp), %rdi
movl -0xe8(%rbp), %eax
movl -0x14(%rbp), %ecx
shrl %cl, %eax
movl %eax, %eax
shlq $0x2, %rax
addq %rax, %rdi
movl -0xdc(%rbp), %esi
movl -0xf8(%rbp), %edx
movl -0x100(%rbp), %ecx
callq 0x1831e0
movl -0xe8(%rbp), %edi
movl -0x40(%rbp), %esi
callq 0x183250
movl %eax, -0xe8(%rbp)
movslq -0x40(%rbp), %rax
movl -0x90(%rbp,%rax,4), %ecx
addl $-0x1, %ecx
movl %ecx, -0x90(%rbp,%rax,4)
jmp 0x182ef9
jmp 0x183065
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
movl -0xdc(%rbp), %eax
shll %eax
movl %eax, -0xdc(%rbp)
jmp 0x182e9f
movl -0xec(%rbp), %eax
movl -0x94(%rbp), %ecx
shll %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
je 0x18309f
movl $0x0, -0x4(%rbp)
jmp 0x1830a5
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nopw %cs:(%rax,%rax)