// File: phillip-h[P]fractal-gen/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*)lodepng_malloc(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 huffman 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);
      /*oversubscribed, see comment in lodepng_error_text*/
      if(treepos > 2147483647 || treepos + 2 > tree->numcodes) return 55;
      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:
subq $0x28, %rsp
movq %rdi, 0x18(%rsp)
movl $0x0, 0x14(%rsp)
movl $0x0, 0x10(%rsp)
movq 0x18(%rsp), %rax
movl 0x1c(%rax), %eax
shll %eax
movl %eax, %eax
movl %eax, %edi
shlq $0x2, %rdi
callq 0x6cd0
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, (%rax)
movq 0x18(%rsp), %rax
cmpq $0x0, (%rax)
jne 0x132b3
movl $0x53, 0x24(%rsp)
jmp 0x134c0
movl $0x0, 0xc(%rsp)
movl 0xc(%rsp), %eax
movq 0x18(%rsp), %rcx
movl 0x1c(%rcx), %ecx
shll %ecx
cmpl %ecx, %eax
jae 0x132ed
movq 0x18(%rsp), %rax
movq (%rax), %rax
movl 0xc(%rsp), %ecx
movl $0x7fff, (%rax,%rcx,4)  # imm = 0x7FFF
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
jmp 0x132bb
movl $0x0, 0xc(%rsp)
movl 0xc(%rsp), %eax
movq 0x18(%rsp), %rcx
cmpl 0x1c(%rcx), %eax
jae 0x13467
movl $0x0, 0x8(%rsp)
movl 0x8(%rsp), %eax
movq 0x18(%rsp), %rcx
movq 0x10(%rcx), %rcx
movl 0xc(%rsp), %edx
cmpl (%rcx,%rdx,4), %eax
je 0x13455
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rax
movl 0xc(%rsp), %ecx
movl (%rax,%rcx,4), %eax
movq 0x18(%rsp), %rcx
movq 0x10(%rcx), %rcx
movl 0xc(%rsp), %edx
movl (%rcx,%rdx,4), %ecx
subl 0x8(%rsp), %ecx
subl $0x1, %ecx
shrl %cl, %eax
andl $0x1, %eax
movb %al, 0x7(%rsp)
cmpl $0x7fffffff, 0x10(%rsp) # imm = 0x7FFFFFFF
ja 0x13374
movl 0x10(%rsp), %eax
addl $0x2, %eax
movq 0x18(%rsp), %rcx
cmpl 0x1c(%rcx), %eax
jbe 0x13381
movl $0x37, 0x24(%rsp)
jmp 0x134c0
movq 0x18(%rsp), %rax
movq (%rax), %rax
movl 0x10(%rsp), %ecx
shll %ecx
movzbl 0x7(%rsp), %edx
addl %edx, %ecx
movl %ecx, %ecx
cmpl $0x7fff, (%rax,%rcx,4)  # imm = 0x7FFF
jne 0x1341d
movl 0x8(%rsp), %eax
addl $0x1, %eax
movq 0x18(%rsp), %rcx
movq 0x10(%rcx), %rcx
movl 0xc(%rsp), %edx
cmpl (%rcx,%rdx,4), %eax
jne 0x133e2
movl 0xc(%rsp), %edx
movq 0x18(%rsp), %rax
movq (%rax), %rax
movl 0x10(%rsp), %ecx
shll %ecx
movzbl 0x7(%rsp), %esi
addl %esi, %ecx
movl %ecx, %ecx
movl %edx, (%rax,%rcx,4)
movl $0x0, 0x10(%rsp)
jmp 0x1341b
movl 0x14(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x14(%rsp)
movl 0x14(%rsp), %edx
movq 0x18(%rsp), %rax
addl 0x1c(%rax), %edx
movq 0x18(%rsp), %rax
movq (%rax), %rax
movl 0x10(%rsp), %ecx
shll %ecx
movzbl 0x7(%rsp), %esi
addl %esi, %ecx
movl %ecx, %ecx
movl %edx, (%rax,%rcx,4)
movl 0x14(%rsp), %eax
movl %eax, 0x10(%rsp)
jmp 0x13443
movq 0x18(%rsp), %rax
movq (%rax), %rax
movl 0x10(%rsp), %ecx
shll %ecx
movzbl 0x7(%rsp), %edx
addl %edx, %ecx
movl %ecx, %ecx
movl (%rax,%rcx,4), %eax
movq 0x18(%rsp), %rcx
subl 0x1c(%rcx), %eax
movl %eax, 0x10(%rsp)
jmp 0x13445
movl 0x8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8(%rsp)
jmp 0x1330f
jmp 0x13457
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
jmp 0x132f5
movl $0x0, 0xc(%rsp)
movl 0xc(%rsp), %eax
movq 0x18(%rsp), %rcx
movl 0x1c(%rcx), %ecx
shll %ecx
cmpl %ecx, %eax
jae 0x134b8
movq 0x18(%rsp), %rax
movq (%rax), %rax
movl 0xc(%rsp), %ecx
cmpl $0x7fff, (%rax,%rcx,4)  # imm = 0x7FFF
jne 0x134a9
movq 0x18(%rsp), %rax
movq (%rax), %rax
movl 0xc(%rsp), %ecx
movl $0x0, (%rax,%rcx,4)
jmp 0x134ab
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
jmp 0x1346f
movl $0x0, 0x24(%rsp)
movl 0x24(%rsp), %eax
addq $0x28, %rsp
retq
nopl (%rax)