// File: mhe[P]raytracerframework_cpp/lodepng.cpp
// Function: inflateHuffmanBlock(ucvector*, unsigned char const*, unsigned long*, unsigned long*, unsigned long, unsigned int)
static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size_t* bp, size_t* pos, size_t inlength, unsigned btype)
{
  unsigned endreached = 0, error = 0;
  HuffmanTree codetree; /*287, the code tree for Huffman codes*/
  HuffmanTree codetreeD; /*31, the code tree for distance codes*/
  
  HuffmanTree_init(&codetree);
  HuffmanTree_init(&codetreeD);
  
  if(btype == 1) getTreeInflateFixed(&codetree, &codetreeD);
  else if(btype == 2)
  {
    HuffmanTree codelengthcodetree; /*18, the code tree for code length codes*/
    HuffmanTree_init(&codelengthcodetree);
    error = getTreeInflateDynamic(&codetree, &codetreeD, &codelengthcodetree, in, bp, inlength);
    HuffmanTree_cleanup(&codelengthcodetree);
  }
  
  while(!endreached && !error)
  {
    unsigned code = huffmanDecodeSymbol(&error, in, bp, &codetree, inlength);
    if(error) break; /*some error happened in the above function*/
    if(code == 256) endreached = 1; /*end code*/
    else if(code <= 255) /*literal symbol*/
    {
      if((*pos) >= out->size) ucvector_resize(out, ((*pos) + 1) * 2); /*reserve more room at once*/
      if((*pos) >= out->size) { error = 9913; break; } /*not enough memory*/
      out->data[(*pos)] = (unsigned char)(code);
      (*pos)++;
    }
    else if(code >= FIRST_LENGTH_CODE_INDEX && code <= LAST_LENGTH_CODE_INDEX) /*length code*/
    {
      /*part 1: get length base*/
      size_t length = LENGTHBASE[code - FIRST_LENGTH_CODE_INDEX];
      unsigned codeD, distance, numextrabitsD;
      size_t start, forward, backward, numextrabits;
      
      /*part 2: get extra bits and add the value of that to length*/
      numextrabits = LENGTHEXTRA[code - FIRST_LENGTH_CODE_INDEX];
      if(((*bp) >> 3) >= inlength) { error = 51; break; } /*error, bit pointer will jump past memory*/
      length += readBitsFromStream(bp, in, numextrabits);
      
      /*part 3: get distance code*/
      codeD = huffmanDecodeSymbol(&error, in, bp, &codetreeD, inlength);
      if(error) break;
      if(codeD > 29) { error = 18; break; } /*error: invalid distance code (30-31 are never used)*/
      distance = DISTANCEBASE[codeD];
      
      /*part 4: get extra bits from distance*/
      numextrabitsD = DISTANCEEXTRA[codeD];
      if(((*bp) >> 3) >= inlength) { error = 51; break; } /*error, bit pointer will jump past memory*/
      distance += readBitsFromStream(bp, in, numextrabitsD);
      
      /*part 5: fill in all the out[n] values based on the length and dist*/
      start = (*pos);
      backward = start - distance;
      if((*pos) + length >= out->size) ucvector_resize(out, ((*pos) + length) * 2); /*reserve more room at once*/
      if((*pos) + length >= out->size) { error = 9914; break; } /*not enough memory*/
      
      for(forward = 0; forward < length; forward++)
      {
        out->data[(*pos)] = out->data[backward];
        (*pos)++;
        backward++;
        if(backward >= start) backward = start - distance;
      }
    }
  }
  
  HuffmanTree_cleanup(&codetree);
  HuffmanTree_cleanup(&codetreeD);
  
  return error;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movl %r9d, -0x2c(%rbp)
movl $0x0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x2cf70
leaq -0xd8(%rbp), %rdi
callq 0x2cf70
cmpl $0x1, -0x2c(%rbp)
jne 0x24094
leaq -0x88(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x2cfb0
jmp 0x240dd
cmpl $0x2, -0x2c(%rbp)
jne 0x240db
leaq -0x128(%rbp), %rdi
callq 0x2cf70
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %r8
movq -0x28(%rbp), %r9
leaq -0x88(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
leaq -0x128(%rbp), %rdx
callq 0x2cfe0
movl %eax, -0x34(%rbp)
leaq -0x128(%rbp), %rdi
callq 0x2d540
jmp 0x240dd
jmp 0x240df
xorl %eax, %eax
cmpl $0x0, -0x30(%rbp)
movb %al, -0x169(%rbp)
jne 0x240fc
cmpl $0x0, -0x34(%rbp)
setne %al
xorb $-0x1, %al
movb %al, -0x169(%rbp)
movb -0x169(%rbp), %al
testb $0x1, %al
jne 0x2410b
jmp 0x24445
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x28(%rbp), %r8
leaq -0x34(%rbp), %rdi
leaq -0x88(%rbp), %rcx
callq 0x2d580
movl %eax, -0x12c(%rbp)
cmpl $0x0, -0x34(%rbp)
je 0x24138
jmp 0x24445
cmpl $0x100, -0x12c(%rbp)    # imm = 0x100
jne 0x24150
movl $0x1, -0x30(%rbp)
jmp 0x24440
cmpl $0xff, -0x12c(%rbp)
ja 0x241cd
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x8(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jb 0x24184
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rax
movq (%rax), %rsi
addq $0x1, %rsi
shlq %rsi
callq 0x24470
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x8(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jb 0x241a1
movl $0x26b9, -0x34(%rbp)    # imm = 0x26B9
jmp 0x24445
movl -0x12c(%rbp), %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq -0x20(%rbp), %rcx
movq (%rcx), %rcx
movb %dl, (%rax,%rcx)
movq -0x20(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
jmp 0x2443e
cmpl $0x101, -0x12c(%rbp)    # imm = 0x101
jb 0x2443c
cmpl $0x11d, -0x12c(%rbp)    # imm = 0x11D
ja 0x2443c
movl -0x12c(%rbp), %eax
subl $0x101, %eax            # imm = 0x101
movl %eax, %eax
movl %eax, %ecx
leaq 0x2766d(%rip), %rax     # 0x4b870
movl (%rax,%rcx,4), %eax
movq %rax, -0x138(%rbp)
movl -0x12c(%rbp), %eax
subl $0x101, %eax            # imm = 0x101
movl %eax, %eax
movl %eax, %ecx
leaq 0x276cd(%rip), %rax     # 0x4b8f0
movl (%rax,%rcx,4), %eax
movq %rax, -0x168(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
shrq $0x3, %rax
cmpq -0x28(%rbp), %rax
jb 0x2424a
movl $0x33, -0x34(%rbp)
jmp 0x24445
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x168(%rbp), %rdx
callq 0x2d640
movl %eax, %eax
addq -0x138(%rbp), %rax
movq %rax, -0x138(%rbp)
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x28(%rbp), %r8
leaq -0x34(%rbp), %rdi
leaq -0xd8(%rbp), %rcx
callq 0x2d580
movl %eax, -0x13c(%rbp)
cmpl $0x0, -0x34(%rbp)
je 0x2429b
jmp 0x24445
cmpl $0x1d, -0x13c(%rbp)
jbe 0x242b0
movl $0x12, -0x34(%rbp)
jmp 0x24445
movl -0x13c(%rbp), %eax
movl %eax, %ecx
leaq 0x276b1(%rip), %rax     # 0x4b970
movl (%rax,%rcx,4), %eax
movl %eax, -0x140(%rbp)
movl -0x13c(%rbp), %eax
movl %eax, %ecx
leaq 0x27719(%rip), %rax     # 0x4b9f0
movl (%rax,%rcx,4), %eax
movl %eax, -0x144(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
shrq $0x3, %rax
cmpq -0x28(%rbp), %rax
jb 0x242fd
movl $0x33, -0x34(%rbp)
jmp 0x24445
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x144(%rbp), %eax
movl %eax, %edx
callq 0x2d640
addl -0x140(%rbp), %eax
movl %eax, -0x140(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x150(%rbp)
movq -0x150(%rbp), %rax
movl -0x140(%rbp), %ecx
subq %rcx, %rax
movq %rax, -0x160(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
addq -0x138(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jb 0x24375
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rax
movq (%rax), %rsi
addq -0x138(%rbp), %rsi
shlq %rsi
callq 0x24470
movq -0x20(%rbp), %rax
movq (%rax), %rax
addq -0x138(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jb 0x24399
movl $0x26ba, -0x34(%rbp)    # imm = 0x26BA
jmp 0x24445
movq $0x0, -0x158(%rbp)
movq -0x158(%rbp), %rax
cmpq -0x138(%rbp), %rax
jae 0x2443a
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq -0x160(%rbp), %rcx
movb (%rax,%rcx), %dl
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq -0x20(%rbp), %rcx
movq (%rcx), %rcx
movb %dl, (%rax,%rcx)
movq -0x20(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq -0x160(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x160(%rbp)
movq -0x160(%rbp), %rax
cmpq -0x150(%rbp), %rax
jb 0x24421
movq -0x150(%rbp), %rax
movl -0x140(%rbp), %ecx
subq %rcx, %rax
movq %rax, -0x160(%rbp)
jmp 0x24423
movq -0x158(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x158(%rbp)
jmp 0x243a4
jmp 0x2443c
jmp 0x2443e
jmp 0x24440
jmp 0x240df
leaq -0x88(%rbp), %rdi
callq 0x2d540
leaq -0xd8(%rbp), %rdi
callq 0x2d540
movl -0x34(%rbp), %eax
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
nopl (%rax)