// File: /workspace/github_c_makefile_star2_O3/samtools[P]htslib/htscodecs/htscodecs/pack.c
// Function: hts_pack
uint8_t *hts_pack(uint8_t *data, int64_t len,
                  uint8_t *out_meta, int *out_meta_len, uint64_t *out_len) {
    int p[256] = {0}, n;
    uint64_t i, j;

    // count syms
    for (i = 0; i < len; i++)
        p[data[i]]=1;
    
    for (i = n = 0; i < 256; i++) {
        if (p[i]) {
            p[i] = n++; // p[i] is now the code number
            out_meta[n] = i;
        }
    }
    out_meta[0] = n; // 256 wraps to 0
    j = n+1;

    // 1 value per byte
    if (n > 16)
        return NULL;

    uint8_t *out = malloc(len+1);
    if (!out)
        return NULL;

    // Work out how many values per byte to encode.
    int val_per_byte;
    if (n > 4)
        val_per_byte = 2;
    else if (n > 2)
        val_per_byte = 4;
    else if (n > 1)
        val_per_byte = 8;
    else
        val_per_byte = 0; // infinite

    *out_meta_len = j;
    j = 0;

    switch (val_per_byte) {
    case 2:
        for (i = 0; i < (len & ~1); i+=2)
            out[j++] = (p[data[i]]<<0) | (p[data[i+1]]<<4);
        switch (len-i) {
        case 1: out[j++] = p[data[i]];
        }
        *out_len = j;
        return out;

    case 4: {
        for (i = 0; i < (len & ~3); i+=4)
            out[j++] = (p[data[i]]<<0) | (p[data[i+1]]<<2) | (p[data[i+2]]<<4) | (p[data[i+3]]<<6);
        out[j] = 0;
        int s = len-i, x = 0;
        switch (s) {
        case 3: out[j] |= p[data[i++]] << x; x+=2; // fall-through
        case 2: out[j] |= p[data[i++]] << x; x+=2; // fall-through
        case 1: out[j] |= p[data[i++]] << x; x+=2;
            j++;
        }
        *out_len = j;
        return out;
    }

    case 8: {
        for (i = 0; i < (len & ~7); i+=8)
            out[j++] = (p[data[i+0]]<<0) | (p[data[i+1]]<<1) | (p[data[i+2]]<<2) | (p[data[i+3]]<<3)
                     | (p[data[i+4]]<<4) | (p[data[i+5]]<<5) | (p[data[i+6]]<<6) | (p[data[i+7]]<<7);
        out[j] = 0;
        int s = len-i, x = 0;
        switch (s) {
        case 7: out[j] |= p[data[i++]] << x++; // fall-through
        case 6: out[j] |= p[data[i++]] << x++; // fall-through
        case 5: out[j] |= p[data[i++]] << x++; // fall-through
        case 4: out[j] |= p[data[i++]] << x++; // fall-through
        case 3: out[j] |= p[data[i++]] << x++; // fall-through
        case 2: out[j] |= p[data[i++]] << x++; // fall-through
        case 1: out[j] |= p[data[i++]] << x++;
            j++;
        }
        *out_len = j;
        return out;
    }

    case 0:
        *out_len = j;
        return out;
    }

    return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x408, %rsp            # imm = 0x408
movq %r8, %rbx
movq %rcx, %r12
movq %rdx, %r13
movq %rsi, %r15
movq %rdi, %r14
movq %rsp, %rdi
xorl %ebp, %ebp
movl $0x400, %edx            # imm = 0x400
xorl %esi, %esi
callq 0x4260
testq %r15, %r15
je 0x61574
xorl %eax, %eax
movzbl (%r14,%rax), %ecx
movl $0x1, (%rsp,%rcx,4)
incq %rax
cmpq %rax, %r15
jne 0x61560
xorl %eax, %eax
cmpl $0x0, (%rsp,%rax,4)
je 0x6158b
movslq %ebp, %rcx
leaq 0x1(%rcx), %rbp
movl %ecx, (%rsp,%rax,4)
movb %al, 0x1(%r13,%rcx)
incq %rax
cmpq $0x100, %rax            # imm = 0x100
jne 0x61576
movb %bpl, (%r13)
cmpl $0x10, %ebp
jg 0x615ff
leaq 0x1(%r15), %rdi
callq 0x4680
testq %rax, %rax
je 0x615ff
leal 0x1(%rbp), %ecx
cmpl $0x4, %ebp
jle 0x61606
movl %ecx, (%r12)
movq %r15, %rdx
andq $-0x2, %rdx
je 0x61733
decq %rdx
shrq %rdx
incq %rdx
xorl %ecx, %ecx
xorl %esi, %esi
movzbl (%r14,%rcx), %edi
movzbl 0x1(%r14,%rcx), %r8d
movl (%rsp,%r8,4), %r8d
shll $0x4, %r8d
orl (%rsp,%rdi,4), %r8d
movb %r8b, (%rax,%rsi)
incq %rsi
addq $0x2, %rcx
cmpq %rsi, %rdx
jne 0x615d3
jmp 0x61737
xorl %eax, %eax
jmp 0x6188b
cmpl $0x2, %ebp
jle 0x6167a
movl %ecx, (%r12)
xorl %esi, %esi
movq %r15, %rdx
andq $-0x4, %rdx
je 0x6175b
decq %rdx
shrq $0x2, %rdx
incq %rdx
xorl %edi, %edi
xorl %ecx, %ecx
movzbl (%r14,%rdi), %r8d
movzbl 0x1(%r14,%rdi), %r9d
movl (%rsp,%r9,4), %r9d
shll $0x2, %r9d
orl (%rsp,%r8,4), %r9d
movzbl 0x2(%r14,%rdi), %r8d
movl (%rsp,%r8,4), %r8d
shll $0x4, %r8d
movzbl 0x3(%r14,%rdi), %r10d
movl (%rsp,%r10,4), %r10d
shll $0x6, %r10d
orl %r8d, %r10d
orl %r9d, %r10d
movb %r10b, (%rax,%rcx)
incq %rcx
addq $0x4, %rdi
cmpq %rcx, %rdx
jne 0x6162c
jmp 0x6175f
movl %ecx, (%r12)
jne 0x61754
xorl %esi, %esi
movq %r15, %rdx
andq $-0x8, %rdx
je 0x617ac
decq %rdx
shrq $0x3, %rdx
incq %rdx
xorl %edi, %edi
xorl %ecx, %ecx
movzbl (%r14,%rdi), %r9d
movzbl 0x1(%r14,%rdi), %r8d
movl (%rsp,%r8,4), %r8d
addl %r8d, %r8d
orl (%rsp,%r9,4), %r8d
movzbl 0x2(%r14,%rdi), %r9d
movl (%rsp,%r9,4), %r9d
shll $0x2, %r9d
movzbl 0x3(%r14,%rdi), %r10d
movl (%rsp,%r10,4), %r10d
shll $0x3, %r10d
orl %r9d, %r10d
movzbl 0x4(%r14,%rdi), %r9d
movl (%rsp,%r9,4), %r9d
shll $0x4, %r9d
orl %r10d, %r9d
movzbl 0x5(%r14,%rdi), %r10d
movl (%rsp,%r10,4), %r10d
shll $0x5, %r10d
orl %r9d, %r10d
movzbl 0x6(%r14,%rdi), %r9d
movl (%rsp,%r9,4), %r9d
shll $0x6, %r9d
orl %r10d, %r9d
movzbl 0x7(%r14,%rdi), %r10d
movl (%rsp,%r10,4), %r10d
shll $0x7, %r10d
orl %r9d, %r10d
orl %r8d, %r10d
movb %r10b, (%rax,%rcx)
incq %rcx
addq $0x8, %rdi
cmpq %rcx, %rdx
jne 0x616a1
jmp 0x617b0
xorl %edx, %edx
xorl %ecx, %ecx
subq %rcx, %r15
cmpq $0x1, %r15
jne 0x61888
movzbl (%r14,%rcx), %ecx
movb (%rsp,%rcx,4), %cl
movb %cl, (%rax,%rdx)
jmp 0x61885
xorl %edx, %edx
jmp 0x61888
xorl %edx, %edx
xorl %edi, %edi
movb $0x0, (%rax,%rdx)
subl %edi, %r15d
cmpl $0x1, %r15d
je 0x617d4
cmpl $0x2, %r15d
je 0x61790
cmpl $0x3, %r15d
jne 0x61888
movzbl (%r14,%rdi), %ecx
orq $0x1, %rdi
movb (%rsp,%rcx,4), %sil
movl $0x2, %ecx
jmp 0x61792
xorl %ecx, %ecx
movzbl (%r14,%rdi), %r8d
movl (%rsp,%r8,4), %r8d
shll %cl, %r8d
incq %rdi
orb %sil, %r8b
addl $0x2, %ecx
jmp 0x61871
xorl %edx, %edx
xorl %edi, %edi
movb $0x0, (%rax,%rdx)
movl %edi, %ecx
notl %ecx
addl %r15d, %ecx
cmpl $0x6, %ecx
ja 0x61888
leaq 0x3a5ad(%rip), %r8      # 0x9bd78
movslq (%r8,%rcx,4), %rcx
addq %r8, %rcx
jmpq *%rcx
xorl %ecx, %ecx
jmp 0x61874
xorl %ecx, %ecx
jmp 0x61818
xorl %ecx, %ecx
jmp 0x61846
xorl %ecx, %ecx
jmp 0x6182f
xorl %ecx, %ecx
jmp 0x6185d
xorl %ecx, %ecx
jmp 0x61801
movzbl (%r14,%rdi), %ecx
orq $0x1, %rdi
movb (%rsp,%rcx,4), %sil
movl $0x1, %ecx
movzbl (%r14,%rdi), %r8d
movl (%rsp,%r8,4), %r8d
shll %cl, %r8d
incq %rdi
incl %ecx
orb %sil, %r8b
movl %r8d, %esi
movzbl (%r14,%rdi), %r8d
movl (%rsp,%r8,4), %r8d
shll %cl, %r8d
incq %rdi
incl %ecx
orb %sil, %r8b
movl %r8d, %esi
movzbl (%r14,%rdi), %r8d
movl (%rsp,%r8,4), %r8d
shll %cl, %r8d
incq %rdi
incl %ecx
orb %sil, %r8b
movl %r8d, %esi
movzbl (%r14,%rdi), %r8d
movl (%rsp,%r8,4), %r8d
shll %cl, %r8d
incq %rdi
incl %ecx
orb %sil, %r8b
movl %r8d, %esi
movzbl (%r14,%rdi), %r8d
movl (%rsp,%r8,4), %r8d
shll %cl, %r8d
incq %rdi
incl %ecx
orb %sil, %r8b
movl %r8d, %esi
movzbl (%r14,%rdi), %edi
movl (%rsp,%rdi,4), %edi
shll %cl, %edi
orb %sil, %dil
movb %dil, (%rax,%rdx)
incq %rdx
movq %rdx, (%rbx)
addq $0x408, %rsp            # imm = 0x408
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq