// File: akdess[P]BAFExtract/src/main.cpp
// Function: load_compressed_pileups(char*, int&)
unsigned short** load_compressed_pileups(char* cur_comp_allele_fp, int& l_pileup)
{
  FILE* f_comp = NULL;
  if(t_string::ends_with(cur_comp_allele_fp, ".bin"))
  {
    f_comp = open_f(cur_comp_allele_fp, "rb");
  }
  else if(t_string::ends_with(cur_comp_allele_fp, ".bin.gz"))
  {
    char ungzip_cmd[1000];
    sprintf(ungzip_cmd, "gzip -cd %s", cur_comp_allele_fp);
#ifdef WIN32
    f_comp = _popen(ungzip_cmd, "r");
#else 
    f_comp = popen(ungzip_cmd, "r");
#endif
  }

  if(f_comp == NULL)
  {
    fprintf(stderr, "Could not open %s\n", cur_comp_allele_fp);
    exit(0);
  }

  int l_read_sig = 0;
  fread(&l_read_sig, sizeof(int), 1, f_comp);
  int l_sig = l_read_sig;

  l_pileup = l_sig;

  fprintf(stderr, "Loading pileup of length %d\n", l_sig);

  unsigned short** loaded_pileup = allocate_pileup(l_sig);

  // Go over all the positions.
  int i = 1;
  while(i <= l_sig)
  {
    // Read the existence flag.
    unsigned char existence_flag = 0;
    fread(&existence_flag, sizeof(unsigned char), 1, f_comp);


    // Check an RLE case.
    if(existence_flag == 0xFF)
    {
      unsigned int l_RLE = 0;
      fread(&l_RLE, sizeof(unsigned int), 1, f_comp);

if(__DUMP_MAPPED_READ_TOOLS_MSGS__)
      fprintf(stderr, "Loading RLE of length %d @ %d\n", l_RLE, i);

      // When we add this, we move upto the location where a 0-run ends.
      i += l_RLE;
    } // RLE check.
    else
    {
      // Read the first byte, parse the data range and which alleles exist.
      unsigned char drange_flag = ((existence_flag & (1 << 5)) >> 5);

      for(int allele_i = 0; allele_i < 5; allele_i++)
      {
        // Do we have an entry here?
        if((existence_flag & (1 << allele_i)) > 0)
        {
          if(drange_flag == 1)
          { 
            unsigned short current_count_short = 0;
            fread(&(current_count_short), sizeof(unsigned short), 1, f_comp);
            loaded_pileup[allele_i][i] = current_count_short;
          }
          else
          {
            unsigned char current_count_char = 0;
            fread(&(current_count_char), sizeof(unsigned char), 1, f_comp);
            loaded_pileup[allele_i][i] = (unsigned short)current_count_char;
          }
        } // count check for current position.
      } // allele_i loop.

      i++;
    }
  } // i loop.

  if(t_string::ends_with(cur_comp_allele_fp, ".bin"))
  {
    fclose(f_comp);
  }
  else if(t_string::ends_with(cur_comp_allele_fp, ".bin.gz"))
  {
#ifdef WIN32
    _pclose(f_comp);
#else 
    pclose(f_comp);
#endif
  }

  // Free memory.
  return(loaded_pileup);
}

// Assembly:
subq $0x438, %rsp            # imm = 0x438
movq %rdi, 0x430(%rsp)
movq %rsi, 0x428(%rsp)
movq $0x0, 0x420(%rsp)
movq 0x430(%rsp), %rdi
leaq 0x11f25(%rip), %rsi     # 0x146b7
callq 0xce40
testb $0x1, %al
jne 0x279d
jmp 0x27bb
movq 0x430(%rsp), %rdi
leaq 0x11896(%rip), %rsi     # 0x14042
callq 0x6f40
movq %rax, 0x420(%rsp)
jmp 0x280b
movq 0x430(%rsp), %rdi
leaq 0x12151(%rip), %rsi     # 0x1491b
callq 0xce40
testb $0x1, %al
jne 0x27d5
jmp 0x2809
leaq 0x30(%rsp), %rdi
movq 0x430(%rsp), %rdx
leaq 0x1185c(%rip), %rsi     # 0x14045
movb $0x0, %al
callq 0x2070
leaq 0x30(%rsp), %rdi
leaq 0x1180e(%rip), %rsi     # 0x1400a
callq 0x20a0
movq %rax, 0x420(%rsp)
jmp 0x280b
cmpq $0x0, 0x420(%rsp)
jne 0x283d
movq 0x187c3(%rip), %rax     # 0x1afe0
movq (%rax), %rdi
movq 0x430(%rsp), %rdx
leaq 0x11822(%rip), %rsi     # 0x14051
movb $0x0, %al
callq 0x2240
xorl %edi, %edi
callq 0x21d0
movl $0x0, 0x2c(%rsp)
movq 0x420(%rsp), %rcx
leaq 0x2c(%rsp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x2260
movl 0x2c(%rsp), %eax
movl %eax, 0x28(%rsp)
movl 0x28(%rsp), %ecx
movq 0x428(%rsp), %rax
movl %ecx, (%rax)
movq 0x18762(%rip), %rax     # 0x1afe0
movq (%rax), %rdi
movl 0x28(%rsp), %edx
leaq 0x117d8(%rip), %rsi     # 0x14064
movb $0x0, %al
callq 0x2240
movl 0x28(%rsp), %edi
callq 0x2420
movq %rax, 0x20(%rsp)
movl $0x1, 0x1c(%rsp)
movl 0x1c(%rsp), %eax
cmpl 0x28(%rsp), %eax
jg 0x2a2c
movb $0x0, 0x1b(%rsp)
movq 0x420(%rsp), %rcx
leaq 0x1b(%rsp), %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0x2260
movzbl 0x1b(%rsp), %eax
cmpl $0xff, %eax
jne 0x2940
movl $0x0, 0x14(%rsp)
movq 0x420(%rsp), %rcx
leaq 0x14(%rsp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x2260
testb $0x1, 0x1889c(%rip)     # 0x1b1a9
je 0x292f
movq 0x186ca(%rip), %rax     # 0x1afe0
movq (%rax), %rdi
movl 0x14(%rsp), %edx
movl 0x1c(%rsp), %ecx
leaq 0x11759(%rip), %rsi     # 0x14081
movb $0x0, %al
callq 0x2240
movl 0x14(%rsp), %eax
addl 0x1c(%rsp), %eax
movl %eax, 0x1c(%rsp)
jmp 0x2a27
movzbl 0x1b(%rsp), %eax
andl $0x20, %eax
sarl $0x5, %eax
movb %al, 0x13(%rsp)
movl $0x0, 0xc(%rsp)
cmpl $0x5, 0xc(%rsp)
jge 0x2a1c
movzbl 0x1b(%rsp), %eax
movl 0xc(%rsp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
jle 0x2a0a
movzbl 0x13(%rsp), %eax
cmpl $0x1, %eax
jne 0x29ca
movw $0x0, 0xa(%rsp)
movq 0x420(%rsp), %rcx
leaq 0xa(%rsp), %rdi
movl $0x2, %esi
movl $0x1, %edx
callq 0x2260
movw 0xa(%rsp), %dx
movq 0x20(%rsp), %rax
movslq 0xc(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0x1c(%rsp), %rcx
movw %dx, (%rax,%rcx,2)
jmp 0x2a08
movb $0x0, 0x9(%rsp)
movq 0x420(%rsp), %rcx
leaq 0x9(%rsp), %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0x2260
movzbl 0x9(%rsp), %eax
movw %ax, %dx
movq 0x20(%rsp), %rax
movslq 0xc(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0x1c(%rsp), %rcx
movw %dx, (%rax,%rcx,2)
jmp 0x2a0a
jmp 0x2a0c
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
jmp 0x2957
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x28a9
movq 0x430(%rsp), %rdi
leaq 0x11c7c(%rip), %rsi     # 0x146b7
callq 0xce40
testb $0x1, %al
jne 0x2a46
jmp 0x2a55
movq 0x420(%rsp), %rdi
callq 0x2170
jmp 0x2a7e
movq 0x430(%rsp), %rdi
leaq 0x11eb7(%rip), %rsi     # 0x1491b
callq 0xce40
testb $0x1, %al
jne 0x2a6f
jmp 0x2a7c
movq 0x420(%rsp), %rdi
callq 0x2230
jmp 0x2a7e
movq 0x20(%rsp), %rax
addq $0x438, %rsp            # imm = 0x438
retq
nopl (%rax,%rax)