// File: /workspace/github_c_makefile_star2_O2/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
cmpq %rbp, %r15
je 0x4e5eb
movzbl (%r14,%rbp), %eax
movl $0x1, (%rsp,%rax,4)
incq %rbp
jmp 0x4e5d5
xorl %eax, %eax
xorl %ebp, %ebp
cmpq $0x100, %rax            # imm = 0x100
je 0x4e611
cmpl $0x0, (%rsp,%rax,4)
je 0x4e60c
movslq %ebp, %rcx
leaq 0x1(%rcx), %rbp
movl %ecx, (%rsp,%rax,4)
movb %al, 0x1(%r13,%rcx)
incq %rax
jmp 0x4e5ef
movb %bpl, (%r13)
cmpl $0x10, %ebp
jg 0x4e669
leaq 0x1(%r15), %rdi
callq 0x4680
testq %rax, %rax
je 0x4e669
leal 0x1(%rbp), %ecx
cmpl $0x4, %ebp
jle 0x4e670
movl %ecx, (%r12)
movq %r15, %rsi
shrq %rsi
decq %r15
xorl %ecx, %ecx
cmpq %rcx, %rsi
je 0x4e6d7
movzbl (%r14,%rcx,2), %edx
movzbl 0x1(%r14,%rcx,2), %edi
movl (%rsp,%rdi,4), %edi
shll $0x4, %edi
orl (%rsp,%rdx,4), %edi
movb %dil, (%rax,%rcx)
incq %rcx
addq $-0x2, %r15
jmp 0x4e63f
xorl %eax, %eax
jmp 0x4e8db
cmpl $0x2, %ebp
jle 0x4e6f0
movl %ecx, (%r12)
movq %r15, %rsi
shrq $0x2, %rsi
xorl %edx, %edx
movq %rax, %rcx
movq %rsi, %rdi
subq $0x1, %rdi
jb 0x4e79e
movzbl (%r14,%rdx), %r8d
movzbl 0x1(%r14,%rdx), %r9d
movl (%rsp,%r9,4), %r9d
shll $0x2, %r9d
orl (%rsp,%r8,4), %r9d
movzbl 0x2(%r14,%rdx), %r8d
movl (%rsp,%r8,4), %r8d
shll $0x4, %r8d
movzbl 0x3(%r14,%rdx), %r10d
movl (%rsp,%r10,4), %r10d
shll $0x6, %r10d
orl %r8d, %r10d
orl %r9d, %r10d
movb %r10b, (%rcx)
addq $0x4, %rdx
incq %rcx
jmp 0x4e688
testq %r15, %r15
jne 0x4e8d8
movzbl (%r14,%rcx,2), %ecx
movb (%rsp,%rcx,4), %cl
movb %cl, (%rax,%rsi)
jmp 0x4e8d5
movl %ecx, (%r12)
jne 0x4e7c2
movq %r15, %rsi
shrq $0x3, %rsi
xorl %edi, %edi
movq %rax, %rcx
movq %rsi, %rdx
subq $0x1, %rdx
jb 0x4e7c9
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, (%rcx)
addq $0x8, %rdi
incq %rcx
jmp 0x4e709
movb $0x0, (%rax,%rsi)
subl %edx, %r15d
cmpl $0x1, %r15d
je 0x4e81b
cmpl $0x3, %r15d
je 0x4e7f7
cmpl $0x2, %r15d
jne 0x4e8d8
xorl %r8d, %r8d
xorl %ecx, %ecx
jmp 0x4e806
xorl %esi, %esi
jmp 0x4e8d8
movb $0x0, (%rax,%rsi)
movl %edi, %ecx
notl %ecx
addl %r15d, %ecx
cmpl $0x6, %ecx
ja 0x4e8d8
xorl %r8d, %r8d
leaq 0x2f321(%rip), %rdx     # 0x7db08
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
xorl %ecx, %ecx
jmp 0x4e8c5
movzbl (%r14,%rdx), %ecx
incq %rdx
movb (%rsp,%rcx,4), %r8b
pushq $0x2
popq %rcx
movzbl (%r14,%rdx), %edi
movl (%rsp,%rdi,4), %edi
shll %cl, %edi
incq %rdx
orb %r8b, %dil
addl $0x2, %ecx
jmp 0x4e81f
xorl %edi, %edi
xorl %ecx, %ecx
movzbl (%r14,%rdx), %edx
movl (%rsp,%rdx,4), %edx
shll %cl, %edx
orb %dil, %dl
jmp 0x4e8d2
xorl %edx, %edx
jmp 0x4e86c
xorl %ecx, %ecx
jmp 0x4e89b
xorl %ecx, %ecx
jmp 0x4e886
xorl %ecx, %ecx
jmp 0x4e8b0
xorl %r9d, %r9d
xorl %ecx, %ecx
jmp 0x4e857
movzbl (%r14,%rdi), %ecx
incq %rdi
movb (%rsp,%rcx,4), %r9b
pushq $0x1
popq %rcx
movzbl (%r14,%rdi), %edx
incq %rdi
movl (%rsp,%rdx,4), %r8d
leal 0x1(%rcx), %edx
shll %cl, %r8d
orb %r9b, %r8b
movzbl (%r14,%rdi), %ecx
movl (%rsp,%rcx,4), %r9d
movl %edx, %ecx
shll %cl, %r9d
incq %rdi
leal 0x1(%rdx), %ecx
orb %r8b, %r9b
movl %r9d, %r8d
movzbl (%r14,%rdi), %edx
movl (%rsp,%rdx,4), %edx
shll %cl, %edx
incq %rdi
incl %ecx
orb %r8b, %dl
movl %edx, %r8d
movzbl (%r14,%rdi), %edx
movl (%rsp,%rdx,4), %edx
shll %cl, %edx
incq %rdi
incl %ecx
orb %r8b, %dl
movl %edx, %r8d
movzbl (%r14,%rdi), %edx
movl (%rsp,%rdx,4), %edx
shll %cl, %edx
incq %rdi
incl %ecx
orb %r8b, %dl
movl %edx, %r8d
movzbl (%r14,%rdi), %edx
movl (%rsp,%rdx,4), %edx
shll %cl, %edx
orb %r8b, %dl
movb %dl, (%rax,%rsi)
incq %rsi
movq %rsi, (%rbx)
addq $0x408, %rsp            # imm = 0x408
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq