// File: drummyfish[P]flowchart/src/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;

  tree->tree2d = (unsigned*)mymalloc(tree->numcodes * 2 * sizeof(unsigned));
  if(!tree->tree2d) return 83; /*alloc fail*/

  /*
  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[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[n]; i++) /*the bits for this code*/
    {
      unsigned char bit = (unsigned char)((tree->tree1d[n] >> (tree->lengths[n] - i - 1)) & 1);
      if(treepos > tree->numcodes - 2) return 55; /*oversubscribed, see comment in lodepng_error_text*/
      if(tree->tree2d[2 * treepos + bit] == 32767) /*not yet filled in*/
      {
        if(i + 1 == tree->lengths[n]) /*last bit*/
        {
          tree->tree2d[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++;
          /*addresses encoded with numcodes added to it*/
          tree->tree2d[2 * treepos + bit] = nodefilled + tree->numcodes;
          treepos = nodefilled;
        }
      }
      else treepos = tree->tree2d[2 * treepos + bit] - tree->numcodes;
    }
  }

  for(n = 0;  n < tree->numcodes * 2; n++)
  {
    if(tree->tree2d[n] == 32767) tree->tree2d[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), %rax
movl 0x1c(%rax), %eax
shll %eax
movl %eax, %eax
movl %eax, %edi
shlq $0x2, %rdi
callq 0x3840
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, (%rax)
jne 0xe480
movl $0x53, -0x4(%rbp)
jmp 0xe647
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movq -0x10(%rbp), %rcx
movl 0x1c(%rcx), %ecx
shll %ecx
cmpl %ecx, %eax
jae 0xe4b3
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 0xe487
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x1c(%rcx), %eax
jae 0xe5f8
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
movq -0x10(%rbp), %rcx
movq 0x10(%rcx), %rcx
movl -0x1c(%rbp), %edx
cmpl (%rcx,%rdx,4), %eax
jae 0xe5e8
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movl -0x1c(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movq -0x10(%rbp), %rcx
movq 0x10(%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 0x1c(%rcx), %ecx
subl $0x2, %ecx
cmpl %ecx, %eax
jbe 0xe52f
movl $0x37, -0x4(%rbp)
jmp 0xe647
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 0xe5b7
movl -0x20(%rbp), %eax
addl $0x1, %eax
movq -0x10(%rbp), %rcx
movq 0x10(%rcx), %rcx
movl -0x1c(%rbp), %edx
cmpl (%rcx,%rdx,4), %eax
jne 0xe585
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 0xe5b5
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %edx
movq -0x10(%rbp), %rax
addl 0x1c(%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 0xe5d8
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 0x1c(%rcx), %eax
movl %eax, -0x18(%rbp)
jmp 0xe5da
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0xe4d1
jmp 0xe5ea
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0xe4ba
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movq -0x10(%rbp), %rcx
movl 0x1c(%rcx), %ecx
shll %ecx
cmpl %ecx, %eax
jae 0xe640
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl -0x1c(%rbp), %ecx
cmpl $0x7fff, (%rax,%rcx,4)  # imm = 0x7FFF
jne 0xe633
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl -0x1c(%rbp), %ecx
movl $0x0, (%rax,%rcx,4)
jmp 0xe635
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0xe5ff
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq