// File: /workspace/github_c_makefile_star2_O1/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 0x63efc
xorl %eax, %eax
movzbl (%r14,%rax), %ecx
movl $0x1, (%rsp,%rcx,4)
incq %rax
cmpq %rax, %r15
jne 0x63ee8
xorl %eax, %eax
cmpl $0x0, (%rsp,%rax,4)
je 0x63f13
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 0x63efe
movb %bpl, (%r13)
cmpl $0x10, %ebp
jg 0x63fc4
leaq 0x1(%r15), %rdi
callq 0x4680
testq %rax, %rax
je 0x63fc4
leal 0x1(%rbp), %ecx
movl $0x2, %edx
cmpl $0x4, %ebp
jg 0x63f5d
movl $0x4, %edx
cmpl $0x2, %ebp
jg 0x63f5d
sete %dl
movzbl %dl, %edx
shll $0x3, %edx
movl %ecx, (%r12)
xorl %ecx, %ecx
cmpl $0x8, %edx
ja 0x64223
movl %edx, %edx
leaq 0x3ab83(%rip), %rsi     # 0x9eaf8
movslq (%rsi,%rdx,4), %rdi
addq %rsi, %rdi
jmpq *%rdi
movq %r15, %rcx
andq $-0x2, %rcx
je 0x64137
decq %rcx
shrq %rcx
incq %rcx
xorl %esi, %esi
xorl %edx, %edx
movzbl (%r14,%rsi), %edi
movzbl 0x1(%r14,%rsi), %r8d
movl (%rsp,%r8,4), %r8d
shll $0x4, %r8d
orl (%rsp,%rdi,4), %r8d
movb %r8b, (%rax,%rdx)
incq %rdx
addq $0x2, %rsi
cmpq %rdx, %rcx
jne 0x63f98
jmp 0x6413b
xorl %ecx, %ecx
jmp 0x64223
xorl %ecx, %ecx
movq %r15, %rdi
andq $-0x4, %rdi
je 0x640e5
decq %rdi
shrq $0x2, %rdi
incq %rdi
xorl %esi, %esi
xorl %edx, %edx
movzbl (%r14,%rsi), %r8d
movzbl 0x1(%r14,%rsi), %r9d
movl (%rsp,%r9,4), %r9d
shll $0x2, %r9d
orl (%rsp,%r8,4), %r9d
movzbl 0x2(%r14,%rsi), %r8d
movl (%rsp,%r8,4), %r8d
shll $0x4, %r8d
movzbl 0x3(%r14,%rsi), %r10d
movl (%rsp,%r10,4), %r10d
shll $0x6, %r10d
orl %r8d, %r10d
orl %r9d, %r10d
movb %r10b, (%rax,%rdx)
incq %rdx
addq $0x4, %rsi
cmpq %rdx, %rdi
jne 0x63fe8
jmp 0x640e9
xorl %ecx, %ecx
movq %r15, %rdi
andq $-0x8, %rdi
je 0x64158
decq %rdi
shrq $0x3, %rdi
incq %rdi
xorl %esi, %esi
xorl %edx, %edx
movzbl (%r14,%rsi), %r9d
movzbl 0x1(%r14,%rsi), %r8d
movl (%rsp,%r8,4), %r8d
addl %r8d, %r8d
orl (%rsp,%r9,4), %r8d
movzbl 0x2(%r14,%rsi), %r9d
movl (%rsp,%r9,4), %r9d
shll $0x2, %r9d
movzbl 0x3(%r14,%rsi), %r10d
movl (%rsp,%r10,4), %r10d
shll $0x3, %r10d
orl %r9d, %r10d
movzbl 0x4(%r14,%rsi), %r9d
movl (%rsp,%r9,4), %r9d
shll $0x4, %r9d
orl %r10d, %r9d
movzbl 0x5(%r14,%rsi), %r10d
movl (%rsp,%r10,4), %r10d
shll $0x5, %r10d
orl %r9d, %r10d
movzbl 0x6(%r14,%rsi), %r9d
movl (%rsp,%r9,4), %r9d
shll $0x6, %r9d
orl %r10d, %r9d
movzbl 0x7(%r14,%rsi), %r10d
movl (%rsp,%r10,4), %r10d
shll $0x7, %r10d
orl %r9d, %r10d
orl %r8d, %r10d
movb %r10b, (%rax,%rdx)
incq %rdx
addq $0x8, %rsi
cmpq %rdx, %rdi
jne 0x64053
jmp 0x6415c
xorl %edx, %edx
xorl %esi, %esi
movb $0x0, (%rax,%rdx)
subl %esi, %r15d
cmpl $0x1, %r15d
je 0x6420c
cmpl $0x2, %r15d
je 0x6411e
cmpl $0x3, %r15d
jne 0x6421d
movzbl (%r14,%rsi), %ecx
orq $0x1, %rsi
movb (%rsp,%rcx,4), %cl
movb %cl, (%rax,%rdx)
movl $0x2, %ecx
movzbl (%r14,%rsi), %edi
incq %rsi
movl (%rsp,%rdi,4), %edi
shll %cl, %edi
orb %dil, (%rax,%rdx)
addl $0x2, %ecx
jmp 0x6420c
xorl %edx, %edx
xorl %esi, %esi
subq %rsi, %r15
cmpq $0x1, %r15
jne 0x6421d
movzbl (%r14,%rsi), %ecx
movb (%rsp,%rcx,4), %cl
movb %cl, (%rax,%rdx)
jmp 0x6421a
xorl %edx, %edx
xorl %esi, %esi
movb $0x0, (%rax,%rdx)
movl %esi, %edi
notl %edi
addl %r15d, %edi
cmpl $0x6, %edi
ja 0x6421d
leaq 0x3a9a5(%rip), %r8      # 0x9eb1c
movslq (%r8,%rdi,4), %rdi
addq %r8, %rdi
jmpq *%rdi
movzbl (%r14,%rsi), %ecx
orq $0x1, %rsi
movb (%rsp,%rcx,4), %cl
movb %cl, (%rax,%rdx)
movl $0x1, %ecx
movzbl (%r14,%rsi), %edi
incq %rsi
movl (%rsp,%rdi,4), %edi
leal 0x1(%rcx), %r8d
shll %cl, %edi
orb %dil, (%rax,%rdx)
movl %r8d, %ecx
movzbl (%r14,%rsi), %edi
incq %rsi
movl (%rsp,%rdi,4), %edi
leal 0x1(%rcx), %r8d
shll %cl, %edi
orb %dil, (%rax,%rdx)
movl %r8d, %ecx
movzbl (%r14,%rsi), %edi
incq %rsi
movl (%rsp,%rdi,4), %edi
leal 0x1(%rcx), %r8d
shll %cl, %edi
orb %dil, (%rax,%rdx)
movl %r8d, %ecx
movzbl (%r14,%rsi), %edi
incq %rsi
movl (%rsp,%rdi,4), %edi
leal 0x1(%rcx), %r8d
shll %cl, %edi
orb %dil, (%rax,%rdx)
movl %r8d, %ecx
movzbl (%r14,%rsi), %edi
incq %rsi
movl (%rsp,%rdi,4), %edi
leal 0x1(%rcx), %r8d
shll %cl, %edi
orb %dil, (%rax,%rdx)
movl %r8d, %ecx
movzbl (%r14,%rsi), %esi
movl (%rsp,%rsi,4), %esi
shll %cl, %esi
orb %sil, (%rax,%rdx)
incq %rdx
movq %rdx, (%rbx)
movq %rax, %rcx
movq %rcx, %rax
addq $0x408, %rsp            # imm = 0x408
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq