// File: mhe[P]raytracerframework_cpp/lodepng.cpp
// Function: HuffmanTree_make2DTree(HuffmanTree*)
static unsigned HuffmanTree_make2DTree(HuffmanTree* tree)
{
  unsigned nodefilled = 0; /*up to which node it is filled*/
  unsigned treepos = 0; /*position in the tree (1 of the numcodes columns)*/
  unsigned n, i;
  
  if(!uivector_resize(&tree->tree2d, tree->numcodes * 2)) return 9901; /*if failed return not enough memory error*/
  /*convert tree1d[] to tree2d[][]. In the 2D array, a value of 32767 means uninited, a value >= numcodes is an address to another bit, a value < numcodes is a code. The 2 rows are the 2 possible bit values (0 or 1), there are as many columns as codes - 1
  a good huffmann tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. Here, the internal nodes are stored (what their 0 and 1 option point to). There is only memory for such good tree currently, if there are more nodes (due to too long length codes), error 55 will happen*/
  for(n = 0;  n < tree->numcodes * 2; n++) tree->tree2d.data[n] = 32767; /*32767 here means the tree2d isn't filled there yet*/

  for(n = 0; n < tree->numcodes; n++) /*the codes*/
  for(i = 0; i < tree->lengths.data[n]; i++) /*the bits for this code*/
  {
    unsigned char bit = (unsigned char)((tree->tree1d.data[n] >> (tree->lengths.data[n] - i - 1)) & 1);
    if(treepos > tree->numcodes - 2) return 55; /*error 55: oversubscribed; see description in header*/
    if(tree->tree2d.data[2 * treepos + bit] == 32767) /*not yet filled in*/
    {
      if(i + 1 == tree->lengths.data[n]) /*last bit*/
      {
        tree->tree2d.data[2 * treepos + bit] = n; /*put the current code in it*/
        treepos = 0;
      }
      else /*put address of the next step in here, first that address has to be found of course (it's just nodefilled + 1)...*/
      {
        nodefilled++;
        tree->tree2d.data[2 * treepos + bit] = nodefilled + tree->numcodes; /*addresses encoded with numcodes added to it*/
        treepos = nodefilled;
      }
    }
    else treepos = tree->tree2d.data[2 * treepos + bit] - tree->numcodes;
  }
  for(n = 0;  n < tree->numcodes * 2; n++) if(tree->tree2d.data[n] == 32767) tree->tree2d.data[n] = 0; /*remove possible remaining 32767's*/
  
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movl $0x0, -0x18(%rbp)
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x4c(%rax), %eax
shll %eax
movl %eax, %eax
movl %eax, %esi
callq 0x2d870
cmpl $0x0, %eax
jne 0x2dc71
movl $0x26ad, -0x4(%rbp)     # imm = 0x26AD
jmp 0x2de38
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movq -0x10(%rbp), %rcx
movl 0x4c(%rcx), %ecx
shll %ecx
cmpl %ecx, %eax
jae 0x2dca4
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl -0x1c(%rbp), %ecx
movl $0x7fff, (%rax,%rcx,4)  # imm = 0x7FFF
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x2dc78
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x4c(%rcx), %eax
jae 0x2dde9
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
movq -0x10(%rbp), %rcx
movq 0x30(%rcx), %rcx
movl -0x1c(%rbp), %edx
cmpl (%rcx,%rdx,4), %eax
jae 0x2ddd9
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movl -0x1c(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movq -0x10(%rbp), %rcx
movq 0x30(%rcx), %rcx
movl -0x1c(%rbp), %edx
movl (%rcx,%rdx,4), %ecx
subl -0x20(%rbp), %ecx
subl $0x1, %ecx
shrl %cl, %eax
andl $0x1, %eax
movb %al, -0x21(%rbp)
movl -0x18(%rbp), %eax
movq -0x10(%rbp), %rcx
movl 0x4c(%rcx), %ecx
subl $0x2, %ecx
cmpl %ecx, %eax
jbe 0x2dd20
movl $0x37, -0x4(%rbp)
jmp 0x2de38
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl -0x18(%rbp), %ecx
shll %ecx
movzbl -0x21(%rbp), %edx
addl %edx, %ecx
movl %ecx, %ecx
cmpl $0x7fff, (%rax,%rcx,4)  # imm = 0x7FFF
jne 0x2dda8
movl -0x20(%rbp), %eax
addl $0x1, %eax
movq -0x10(%rbp), %rcx
movq 0x30(%rcx), %rcx
movl -0x1c(%rbp), %edx
cmpl (%rcx,%rdx,4), %eax
jne 0x2dd76
movl -0x1c(%rbp), %edx
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl -0x18(%rbp), %ecx
shll %ecx
movzbl -0x21(%rbp), %esi
addl %esi, %ecx
movl %ecx, %ecx
movl %edx, (%rax,%rcx,4)
movl $0x0, -0x18(%rbp)
jmp 0x2dda6
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %edx
movq -0x10(%rbp), %rax
addl 0x4c(%rax), %edx
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl -0x18(%rbp), %ecx
shll %ecx
movzbl -0x21(%rbp), %esi
addl %esi, %ecx
movl %ecx, %ecx
movl %edx, (%rax,%rcx,4)
movl -0x14(%rbp), %eax
movl %eax, -0x18(%rbp)
jmp 0x2ddc9
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl -0x18(%rbp), %ecx
shll %ecx
movzbl -0x21(%rbp), %edx
addl %edx, %ecx
movl %ecx, %ecx
movl (%rax,%rcx,4), %eax
movq -0x10(%rbp), %rcx
subl 0x4c(%rcx), %eax
movl %eax, -0x18(%rbp)
jmp 0x2ddcb
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x2dcc2
jmp 0x2dddb
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x2dcab
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movq -0x10(%rbp), %rcx
movl 0x4c(%rcx), %ecx
shll %ecx
cmpl %ecx, %eax
jae 0x2de31
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl -0x1c(%rbp), %ecx
cmpl $0x7fff, (%rax,%rcx,4)  # imm = 0x7FFF
jne 0x2de24
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl -0x1c(%rbp), %ecx
movl $0x0, (%rax,%rcx,4)
jmp 0x2de26
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x2ddf0
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)