// File: karel-brinda[P]ococo/ext/htslib/hts.c
// Function: hts_detect_format
int hts_detect_format(hFILE *hfile, htsFormat *fmt)
{
    unsigned char s[21];
    ssize_t len = hpeek(hfile, s, 18);
    if (len < 0) return -1;

    if (len >= 2 && s[0] == 0x1f && s[1] == 0x8b) {
        // The stream is either gzip-compressed or BGZF-compressed.
        // Determine which, and decompress the first few bytes.
        fmt->compression = (len >= 18 && (s[3] & 4) &&
                            memcmp(&s[12], "BC\2\0", 4) == 0)? bgzf : gzip;
        len = decompress_peek(hfile, s, sizeof s);
    }
    else {
        fmt->compression = no_compression;
        len = hpeek(hfile, s, sizeof s);
    }
    if (len < 0) return -1;

    fmt->compression_level = -1;
    fmt->specific = NULL;

    if (len >= 6 && memcmp(s,"CRAM",4) == 0 && s[4]>=1 && s[4]<=3 && s[5]<=1) {
        fmt->category = sequence_data;
        fmt->format = cram;
        fmt->version.major = s[4], fmt->version.minor = s[5];
        fmt->compression = custom;
        return 0;
    }
    else if (len >= 4 && s[3] <= '\4') {
        if (memcmp(s, "BAM\1", 4) == 0) {
            fmt->category = sequence_data;
            fmt->format = bam;
            // TODO Decompress enough to pick version from @HD-VN header
            fmt->version.major = 1, fmt->version.minor = -1;
            return 0;
        }
        else if (memcmp(s, "BAI\1", 4) == 0) {
            fmt->category = index_file;
            fmt->format = bai;
            fmt->version.major = -1, fmt->version.minor = -1;
            return 0;
        }
        else if (memcmp(s, "BCF\4", 4) == 0) {
            fmt->category = variant_data;
            fmt->format = bcf;
            fmt->version.major = 1, fmt->version.minor = -1;
            return 0;
        }
        else if (memcmp(s, "BCF\2", 4) == 0) {
            fmt->category = variant_data;
            fmt->format = bcf;
            fmt->version.major = s[3];
            fmt->version.minor = (len >= 5 && s[4] <= 2)? s[4] : 0;
            return 0;
        }
        else if (memcmp(s, "CSI\1", 4) == 0) {
            fmt->category = index_file;
            fmt->format = csi;
            fmt->version.major = 1, fmt->version.minor = -1;
            return 0;
        }
        else if (memcmp(s, "TBI\1", 4) == 0) {
            fmt->category = index_file;
            fmt->format = tbi;
            fmt->version.major = -1, fmt->version.minor = -1;
            return 0;
        }
    }
    else if (len >= 16 && memcmp(s, "##fileformat=VCF", 16) == 0) {
        fmt->category = variant_data;
        fmt->format = vcf;
        if (len >= 21 && s[16] == 'v')
            parse_version(fmt, &s[17], &s[len]);
        else
            fmt->version.major = fmt->version.minor = -1;
        return 0;
    }
    else if (len >= 4 && s[0] == '@' &&
             (memcmp(s, "@HD\t", 4) == 0 || memcmp(s, "@SQ\t", 4) == 0 ||
              memcmp(s, "@RG\t", 4) == 0 || memcmp(s, "@PG\t", 4) == 0)) {
        fmt->category = sequence_data;
        fmt->format = sam;
        // @HD-VN is not guaranteed to be the first tag, but then @HD is
        // not guaranteed to be present at all...
        if (len >= 9 && memcmp(s, "@HD\tVN:", 7) == 0)
            parse_version(fmt, &s[7], &s[len]);
        else
            fmt->version.major = 1, fmt->version.minor = -1;
        return 0;
    }
    else {
        // Various possibilities for tab-delimited text:
        // .crai   (gzipped tab-delimited six columns: seqid 5*number)
        // .bed    ([3..12] tab-delimited columns)
        // .bedpe  (>= 10 tab-delimited columns)
        // .sam    (tab-delimited >= 11 columns: seqid number seqid...)
        // FIXME For now, assume it's SAM
        fmt->category = sequence_data;
        fmt->format = sam;
        fmt->version.major = 1, fmt->version.minor = -1;
        return 0;
    }

    fmt->category = unknown_category;
    fmt->format = unknown_format;
    fmt->version.major = fmt->version.minor = -1;
    fmt->compression = no_compression;
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x30(%rbp), %rsi
movl $0x12, %edx
callq 0x6a630
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jge 0x11d29
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x12271
cmpq $0x2, -0x38(%rbp)
jl 0x11db5
movzbl -0x30(%rbp), %eax
cmpl $0x1f, %eax
jne 0x11db5
movzbl -0x2f(%rbp), %eax
cmpl $0x8b, %eax
jne 0x11db5
xorl %eax, %eax
cmpq $0x12, -0x38(%rbp)
movb %al, -0x39(%rbp)
jl 0x11d83
movzbl -0x2d(%rbp), %ecx
andl $0x4, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x39(%rbp)
je 0x11d83
leaq -0x30(%rbp), %rax
addq $0xc, %rax
movl (%rax), %eax
subl $0x24342, %eax          # imm = 0x24342
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
sete %al
movb %al, -0x39(%rbp)
movb -0x39(%rbp), %dl
movl $0x1, %ecx
movl $0x2, %eax
testb $0x1, %dl
cmovnel %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x10(%rbp), %rdi
leaq -0x30(%rbp), %rsi
movl $0x15, %edx
callq 0x12280
movq %rax, -0x38(%rbp)
jmp 0x11dd6
movq -0x18(%rbp), %rax
movl $0x0, 0xc(%rax)
movq -0x10(%rbp), %rdi
leaq -0x30(%rbp), %rsi
movl $0x15, %edx
callq 0x6a630
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jge 0x11de9
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x12271
movq -0x18(%rbp), %rax
movw $0xffff, 0x10(%rax)     # imm = 0xFFFF
movq -0x18(%rbp), %rax
movq $0x0, 0x18(%rax)
cmpq $0x6, -0x38(%rbp)
jl 0x11e81
leaq -0x30(%rbp), %rax
movl (%rax), %eax
subl $0x4d415243, %eax       # imm = 0x4D415243
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x11e81
movzbl -0x2c(%rbp), %eax
cmpl $0x1, %eax
jl 0x11e81
movzbl -0x2c(%rbp), %eax
cmpl $0x3, %eax
jg 0x11e81
movzbl -0x2b(%rbp), %eax
cmpl $0x1, %eax
jg 0x11e81
movq -0x18(%rbp), %rax
movl $0x1, (%rax)
movq -0x18(%rbp), %rax
movl $0x6, 0x4(%rax)
movzbl -0x2c(%rbp), %eax
movw %ax, %cx
movq -0x18(%rbp), %rax
movw %cx, 0x8(%rax)
movzbl -0x2b(%rbp), %eax
movw %ax, %cx
movq -0x18(%rbp), %rax
movw %cx, 0xa(%rax)
movq -0x18(%rbp), %rax
movl $0x3, 0xc(%rax)
movl $0x0, -0x4(%rbp)
jmp 0x12271
cmpq $0x4, -0x38(%rbp)
jl 0x12093
movzbl -0x2d(%rbp), %eax
cmpl $0x4, %eax
jg 0x12093
leaq -0x30(%rbp), %rax
movl (%rax), %eax
subl $0x14d4142, %eax        # imm = 0x14D4142
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x11ee4
movq -0x18(%rbp), %rax
movl $0x1, (%rax)
movq -0x18(%rbp), %rax
movl $0x4, 0x4(%rax)
movq -0x18(%rbp), %rax
movw $0x1, 0x8(%rax)
movq -0x18(%rbp), %rax
movw $0xffff, 0xa(%rax)      # imm = 0xFFFF
movl $0x0, -0x4(%rbp)
jmp 0x12271
leaq -0x30(%rbp), %rax
movl (%rax), %eax
subl $0x1494142, %eax        # imm = 0x1494142
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x11f2f
movq -0x18(%rbp), %rax
movl $0x3, (%rax)
movq -0x18(%rbp), %rax
movl $0x5, 0x4(%rax)
movq -0x18(%rbp), %rax
movw $0xffff, 0x8(%rax)      # imm = 0xFFFF
movq -0x18(%rbp), %rax
movw $0xffff, 0xa(%rax)      # imm = 0xFFFF
movl $0x0, -0x4(%rbp)
jmp 0x12271
leaq -0x30(%rbp), %rax
movl (%rax), %eax
subl $0x4464342, %eax        # imm = 0x4464342
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x11f7a
movq -0x18(%rbp), %rax
movl $0x2, (%rax)
movq -0x18(%rbp), %rax
movl $0x9, 0x4(%rax)
movq -0x18(%rbp), %rax
movw $0x1, 0x8(%rax)
movq -0x18(%rbp), %rax
movw $0xffff, 0xa(%rax)      # imm = 0xFFFF
movl $0x0, -0x4(%rbp)
jmp 0x12271
leaq -0x30(%rbp), %rax
movl (%rax), %eax
subl $0x2464342, %eax        # imm = 0x2464342
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x11fee
movq -0x18(%rbp), %rax
movl $0x2, (%rax)
movq -0x18(%rbp), %rax
movl $0x9, 0x4(%rax)
movzbl -0x2d(%rbp), %eax
movw %ax, %cx
movq -0x18(%rbp), %rax
movw %cx, 0x8(%rax)
cmpq $0x5, -0x38(%rbp)
jl 0x11fcd
movzbl -0x2c(%rbp), %eax
cmpl $0x2, %eax
jg 0x11fcd
movzbl -0x2c(%rbp), %eax
movl %eax, -0x40(%rbp)
jmp 0x11fd4
xorl %eax, %eax
movl %eax, -0x40(%rbp)
jmp 0x11fd4
movl -0x40(%rbp), %eax
movw %ax, %cx
movq -0x18(%rbp), %rax
movw %cx, 0xa(%rax)
movl $0x0, -0x4(%rbp)
jmp 0x12271
leaq -0x30(%rbp), %rax
movl (%rax), %eax
subl $0x1495343, %eax        # imm = 0x1495343
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x12039
movq -0x18(%rbp), %rax
movl $0x3, (%rax)
movq -0x18(%rbp), %rax
movl $0xa, 0x4(%rax)
movq -0x18(%rbp), %rax
movw $0x1, 0x8(%rax)
movq -0x18(%rbp), %rax
movw $0xffff, 0xa(%rax)      # imm = 0xFFFF
movl $0x0, -0x4(%rbp)
jmp 0x12271
leaq -0x30(%rbp), %rax
movl (%rax), %eax
subl $0x1494254, %eax        # imm = 0x1494254
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x12084
movq -0x18(%rbp), %rax
movl $0x3, (%rax)
movq -0x18(%rbp), %rax
movl $0xc, 0x4(%rax)
movq -0x18(%rbp), %rax
movw $0xffff, 0x8(%rax)      # imm = 0xFFFF
movq -0x18(%rbp), %rax
movw $0xffff, 0xa(%rax)      # imm = 0xFFFF
movl $0x0, -0x4(%rbp)
jmp 0x12271
jmp 0x12086
jmp 0x12088
jmp 0x1208a
jmp 0x1208c
jmp 0x1208e
jmp 0x12234
cmpq $0x10, -0x38(%rbp)
jl 0x12124
leaq -0x30(%rbp), %rax
movups (%rax), %xmm0
movaps 0x68a24(%rip), %xmm1    # 0x7aad0
pcmpeqb %xmm1, %xmm0
pmovmskb %xmm0, %eax
subl $0xffff, %eax           # imm = 0xFFFF
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x12124
movq -0x18(%rbp), %rax
movl $0x2, (%rax)
movq -0x18(%rbp), %rax
movl $0x8, 0x4(%rax)
cmpq $0x15, -0x38(%rbp)
jl 0x12104
movzbl -0x20(%rbp), %eax
cmpl $0x76, %eax
jne 0x12104
movq -0x18(%rbp), %rdi
leaq -0x30(%rbp), %rsi
addq $0x11, %rsi
leaq -0x30(%rbp), %rdx
addq -0x38(%rbp), %rdx
callq 0x123a0
jmp 0x12118
movq -0x18(%rbp), %rax
movw $0xffff, 0xa(%rax)      # imm = 0xFFFF
movq -0x18(%rbp), %rax
movw $0xffff, 0x8(%rax)      # imm = 0xFFFF
movl $0x0, -0x4(%rbp)
jmp 0x12271
cmpq $0x4, -0x38(%rbp)
jl 0x12202
movzbl -0x30(%rbp), %eax
cmpl $0x40, %eax
jne 0x12202
leaq -0x30(%rbp), %rax
movl (%rax), %eax
subl $0x9444840, %eax        # imm = 0x9444840
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x12194
leaq -0x30(%rbp), %rax
movl (%rax), %eax
subl $0x9515340, %eax        # imm = 0x9515340
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x12194
leaq -0x30(%rbp), %rax
movl (%rax), %eax
subl $0x9475240, %eax        # imm = 0x9475240
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x12194
leaq -0x30(%rbp), %rax
movl (%rax), %eax
subl $0x9475040, %eax        # imm = 0x9475040
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x12202
movq -0x18(%rbp), %rax
movl $0x1, (%rax)
movq -0x18(%rbp), %rax
movl $0x3, 0x4(%rax)
cmpq $0x9, -0x38(%rbp)
jl 0x121e5
leaq -0x30(%rbp), %rdi
leaq 0x68b94(%rip), %rsi     # 0x7ad4f
movl $0x7, %edx
callq 0x4240
cmpl $0x0, %eax
jne 0x121e5
movq -0x18(%rbp), %rdi
leaq -0x30(%rbp), %rsi
addq $0x7, %rsi
leaq -0x30(%rbp), %rdx
addq -0x38(%rbp), %rdx
callq 0x123a0
jmp 0x121f9
movq -0x18(%rbp), %rax
movw $0x1, 0x8(%rax)
movq -0x18(%rbp), %rax
movw $0xffff, 0xa(%rax)      # imm = 0xFFFF
movl $0x0, -0x4(%rbp)
jmp 0x12271
movq -0x18(%rbp), %rax
movl $0x1, (%rax)
movq -0x18(%rbp), %rax
movl $0x3, 0x4(%rax)
movq -0x18(%rbp), %rax
movw $0x1, 0x8(%rax)
movq -0x18(%rbp), %rax
movw $0xffff, 0xa(%rax)      # imm = 0xFFFF
movl $0x0, -0x4(%rbp)
jmp 0x12271
jmp 0x12236
movq -0x18(%rbp), %rax
movl $0x0, (%rax)
movq -0x18(%rbp), %rax
movl $0x0, 0x4(%rax)
movq -0x18(%rbp), %rax
movw $0xffff, 0xa(%rax)      # imm = 0xFFFF
movq -0x18(%rbp), %rax
movw $0xffff, 0x8(%rax)      # imm = 0xFFFF
movq -0x18(%rbp), %rax
movl $0x0, 0xc(%rax)
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopw (%rax,%rax)