// File: karel-brinda[P]ococo/ext/htslib/sam.c
// Function: tweak_overlap_quality
static void tweak_overlap_quality(bam1_t *a, bam1_t *b)
{
    uint32_t *a_cigar = bam_get_cigar(a), *a_cigar_max = a_cigar + a->core.n_cigar;
    uint32_t *b_cigar = bam_get_cigar(b), *b_cigar_max = b_cigar + b->core.n_cigar;
    int a_icig = 0, a_iseq = 0;
    int b_icig = 0, b_iseq = 0;
    uint8_t *a_qual = bam_get_qual(a), *b_qual = bam_get_qual(b);
    uint8_t *a_seq  = bam_get_seq(a), *b_seq = bam_get_seq(b);

    int iref   = b->core.pos;
    int a_iref = iref - a->core.pos;
    int b_iref = iref - b->core.pos;
    int a_ret = cigar_iref2iseq_set(&a_cigar, a_cigar_max, &a_icig, &a_iseq, &a_iref);
    if ( a_ret<0 ) return;  // no overlap
    int b_ret = cigar_iref2iseq_set(&b_cigar, b_cigar_max, &b_icig, &b_iseq, &b_iref);
    if ( b_ret<0 ) return;  // no overlap

    #if DBG
        fprintf(stderr,"tweak %s  n_cigar=%d %d  .. %d-%d vs %d-%d\n", bam_get_qname(a), a->core.n_cigar, b->core.n_cigar,
            a->core.pos+1,a->core.pos+bam_cigar2rlen(a->core.n_cigar,bam_get_cigar(a)), b->core.pos+1, b->core.pos+bam_cigar2rlen(b->core.n_cigar,bam_get_cigar(b)));
    #endif

    while ( 1 )
    {
        // Increment reference position
        while ( a_iref>=0 && a_iref < iref - a->core.pos )
            a_ret = cigar_iref2iseq_next(&a_cigar, a_cigar_max, &a_icig, &a_iseq, &a_iref);
        if ( a_ret<0 ) break;   // done
        if ( iref < a_iref + a->core.pos ) iref = a_iref + a->core.pos;

        while ( b_iref>=0 && b_iref < iref - b->core.pos )
            b_ret = cigar_iref2iseq_next(&b_cigar, b_cigar_max, &b_icig, &b_iseq, &b_iref);
        if ( b_ret<0 ) break;   // done
        if ( iref < b_iref + b->core.pos ) iref = b_iref + b->core.pos;

        iref++;
        if ( a_iref+a->core.pos != b_iref+b->core.pos ) continue;   // only CMATCH positions, don't know what to do with indels

        if ( bam_seqi(a_seq,a_iseq) == bam_seqi(b_seq,b_iseq) )
        {
            #if DBG
                fprintf(stderr,"%c",seq_nt16_str[bam_seqi(a_seq,a_iseq)]);
            #endif
            // we are very confident about this base
            int qual = a_qual[a_iseq] + b_qual[b_iseq];
            a_qual[a_iseq] = qual>200 ? 200 : qual;
            b_qual[b_iseq] = 0;
        }
        else
        {
            if ( a_qual[a_iseq] >= b_qual[b_iseq] )
            {
                #if DBG
                    fprintf(stderr,"[%c/%c]",seq_nt16_str[bam_seqi(a_seq,a_iseq)],tolower_c(seq_nt16_str[bam_seqi(b_seq,b_iseq)]));
                #endif
                a_qual[a_iseq] = 0.8 * a_qual[a_iseq];  // not so confident about a_qual anymore given the mismatch
                b_qual[b_iseq] = 0;
            }
            else
            {
                #if DBG
                    fprintf(stderr,"[%c/%c]",tolower_c(seq_nt16_str[bam_seqi(a_seq,a_iseq)]),seq_nt16_str[bam_seqi(b_seq,b_iseq)]);
                #endif
                b_qual[b_iseq] = 0.8 * b_qual[b_iseq];
                a_qual[a_iseq] = 0;
            }
        }
    }
    #if DBG
        fprintf(stderr,"\n");
    #endif
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq $0x18, %rcx
andq $0xff, %rcx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq -0x8(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq $0x30, %rcx
movslq %ecx, %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq $0x18, %rcx
andq $0xff, %rcx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq $0x30, %rcx
movslq %ecx, %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movl $0x0, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movl $0x0, -0x40(%rbp)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq $0x30, %rcx
shll $0x2, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq -0x8(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq $0x18, %rcx
andq $0xff, %rcx
movslq %ecx, %rcx
addq %rcx, %rax
movq -0x8(%rbp), %rcx
movl 0x10(%rcx), %ecx
addl $0x1, %ecx
sarl %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq $0x30, %rcx
shll $0x2, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq -0x10(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq $0x18, %rcx
andq $0xff, %rcx
movslq %ecx, %rcx
addq %rcx, %rax
movq -0x10(%rbp), %rcx
movl 0x10(%rcx), %ecx
addl $0x1, %ecx
sarl %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x50(%rbp)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq $0x30, %rcx
shll $0x2, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq -0x8(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq $0x18, %rcx
andq $0xff, %rcx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq $0x30, %rcx
shll $0x2, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq -0x10(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq $0x18, %rcx
andq $0xff, %rcx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x64(%rbp)
movl -0x64(%rbp), %eax
movq -0x8(%rbp), %rcx
subl 0x4(%rcx), %eax
movl %eax, -0x68(%rbp)
movl -0x64(%rbp), %eax
movq -0x10(%rbp), %rcx
subl 0x4(%rcx), %eax
movl %eax, -0x6c(%rbp)
movq -0x20(%rbp), %rsi
leaq -0x18(%rbp), %rdi
leaq -0x34(%rbp), %rdx
leaq -0x38(%rbp), %rcx
leaq -0x68(%rbp), %r8
callq 0x23d70
movl %eax, -0x70(%rbp)
cmpl $0x0, -0x70(%rbp)
jge 0x2363c
jmp 0x238a5
movq -0x30(%rbp), %rsi
leaq -0x28(%rbp), %rdi
leaq -0x3c(%rbp), %rdx
leaq -0x40(%rbp), %rcx
leaq -0x6c(%rbp), %r8
callq 0x23d70
movl %eax, -0x74(%rbp)
cmpl $0x0, -0x74(%rbp)
jge 0x23663
jmp 0x238a5
jmp 0x23665
jmp 0x23667
xorl %eax, %eax
cmpl $0x0, -0x68(%rbp)
movb %al, -0x79(%rbp)
jl 0x23687
movl -0x68(%rbp), %eax
movl -0x64(%rbp), %ecx
movq -0x8(%rbp), %rdx
subl 0x4(%rdx), %ecx
cmpl %ecx, %eax
setl %al
movb %al, -0x79(%rbp)
movb -0x79(%rbp), %al
testb $0x1, %al
jne 0x23690
jmp 0x236ae
movq -0x20(%rbp), %rsi
leaq -0x18(%rbp), %rdi
leaq -0x34(%rbp), %rdx
leaq -0x38(%rbp), %rcx
leaq -0x68(%rbp), %r8
callq 0x23fa0
movl %eax, -0x70(%rbp)
jmp 0x23667
cmpl $0x0, -0x70(%rbp)
jge 0x236b9
jmp 0x238a5
movl -0x64(%rbp), %eax
movl -0x68(%rbp), %ecx
movq -0x8(%rbp), %rdx
addl 0x4(%rdx), %ecx
cmpl %ecx, %eax
jge 0x236d7
movl -0x68(%rbp), %eax
movq -0x8(%rbp), %rcx
addl 0x4(%rcx), %eax
movl %eax, -0x64(%rbp)
jmp 0x236d9
xorl %eax, %eax
cmpl $0x0, -0x6c(%rbp)
movb %al, -0x7a(%rbp)
jl 0x236f9
movl -0x6c(%rbp), %eax
movl -0x64(%rbp), %ecx
movq -0x10(%rbp), %rdx
subl 0x4(%rdx), %ecx
cmpl %ecx, %eax
setl %al
movb %al, -0x7a(%rbp)
movb -0x7a(%rbp), %al
testb $0x1, %al
jne 0x23702
jmp 0x23720
movq -0x30(%rbp), %rsi
leaq -0x28(%rbp), %rdi
leaq -0x3c(%rbp), %rdx
leaq -0x40(%rbp), %rcx
leaq -0x6c(%rbp), %r8
callq 0x23fa0
movl %eax, -0x74(%rbp)
jmp 0x236d9
cmpl $0x0, -0x74(%rbp)
jge 0x2372b
jmp 0x238a5
movl -0x64(%rbp), %eax
movl -0x6c(%rbp), %ecx
movq -0x10(%rbp), %rdx
addl 0x4(%rdx), %ecx
cmpl %ecx, %eax
jge 0x23749
movl -0x6c(%rbp), %eax
movq -0x10(%rbp), %rcx
addl 0x4(%rcx), %eax
movl %eax, -0x64(%rbp)
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
movl -0x68(%rbp), %eax
movq -0x8(%rbp), %rcx
addl 0x4(%rcx), %eax
movl -0x6c(%rbp), %ecx
movq -0x10(%rbp), %rdx
addl 0x4(%rdx), %ecx
cmpl %ecx, %eax
je 0x2376f
jmp 0x23665
movq -0x58(%rbp), %rax
movl -0x38(%rbp), %ecx
sarl %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %eax
movl -0x38(%rbp), %ecx
xorl $-0x1, %ecx
andl $0x1, %ecx
shll $0x2, %ecx
sarl %cl, %eax
andl $0xf, %eax
movq -0x60(%rbp), %rcx
movl -0x40(%rbp), %edx
sarl %edx
movslq %edx, %rdx
movzbl (%rcx,%rdx), %edx
movl -0x40(%rbp), %ecx
xorl $-0x1, %ecx
andl $0x1, %ecx
shll $0x2, %ecx
sarl %cl, %edx
movl %edx, %ecx
andl $0xf, %ecx
cmpl %ecx, %eax
jne 0x2380e
movq -0x48(%rbp), %rax
movslq -0x38(%rbp), %rcx
movzbl (%rax,%rcx), %eax
movq -0x50(%rbp), %rcx
movslq -0x40(%rbp), %rdx
movzbl (%rcx,%rdx), %ecx
addl %ecx, %eax
movl %eax, -0x78(%rbp)
cmpl $0xc8, -0x78(%rbp)
jle 0x237e7
movl $0xc8, %eax
movl %eax, -0x80(%rbp)
jmp 0x237ed
movl -0x78(%rbp), %eax
movl %eax, -0x80(%rbp)
movl -0x80(%rbp), %eax
movb %al, %dl
movq -0x48(%rbp), %rax
movslq -0x38(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x50(%rbp), %rax
movslq -0x40(%rbp), %rcx
movb $0x0, (%rax,%rcx)
jmp 0x238a0
movq -0x48(%rbp), %rax
movslq -0x38(%rbp), %rcx
movzbl (%rax,%rcx), %eax
movq -0x50(%rbp), %rcx
movslq -0x40(%rbp), %rdx
movzbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
jl 0x23865
movq -0x48(%rbp), %rax
movslq -0x38(%rbp), %rcx
movzbl (%rax,%rcx), %eax
cvtsi2sd %eax, %xmm0
movsd 0x57b36(%rip), %xmm1    # 0x7b378
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movb %al, %dl
movq -0x48(%rbp), %rax
movslq -0x38(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x50(%rbp), %rax
movslq -0x40(%rbp), %rcx
movb $0x0, (%rax,%rcx)
jmp 0x2389e
movq -0x50(%rbp), %rax
movslq -0x40(%rbp), %rcx
movzbl (%rax,%rcx), %eax
cvtsi2sd %eax, %xmm0
movsd 0x57afb(%rip), %xmm1    # 0x7b378
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movb %al, %dl
movq -0x50(%rbp), %rax
movslq -0x40(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x48(%rbp), %rax
movslq -0x38(%rbp), %rcx
movb $0x0, (%rax,%rcx)
jmp 0x238a0
jmp 0x23665
addq $0x80, %rsp
popq %rbp
retq
nop