// -*- mode: c++; indent-tabs-mode: nil; -*- // // Copyright 2009 Illumina, Inc. // // This software is covered by the "Illumina Genome Analyzer Software // License Agreement" and the "Illumina Source Code License Agreement", // and certain third party copyright/licenses, and any user of this // source file is bound by the terms therein (see accompanying files // Illumina_Genome_Analyzer_Software_License_Agreement.pdf and // Illumina_Source_Code_License_Agreement.pdf and third party // copyright/license notices). // // /// \file /// /// \author Chris Saunders /// #include "blt_util/bam_util.hh" #include "blt_util/bam_seq.hh" #include "blt_util/log.hh" #include #include static void change_bam_data_len(const int new_len, bam1_t& br){ assert(new_len>=0); if(new_len > br.m_data){ br.m_data = new_len; kroundup32(br.m_data); br.data = (uint8_t*) realloc(br.data,br.m_data); if(NULL == br.data) { log_os << "ERROR: failed to realloc BAM data size to: " << new_len << "\n"; exit(EXIT_FAILURE); } } br.data_len = new_len; } void change_bam_data_segment_len(const int end, const int delta, bam1_t& br){ assert(end>=0); if(0==delta) return; const int old_len(br.data_len); const int new_len(old_len+delta); const int tail_size(old_len-end); assert(tail_size>=0); change_bam_data_len(new_len,br); // move post-segment data to its new position: if(0==tail_size) return; uint8_t* old_tail_ptr(br.data+end); uint8_t* new_tail_ptr(old_tail_ptr+delta); memmove(new_tail_ptr,old_tail_ptr,tail_size); } void edit_bam_qname(const char* name, bam1_t& br){ bam1_core_t& bc(br.core); const uint32_t tmp_size(strlen(name)+1); if(tmp_size & 0xffffff00) { log_os << "ERROR: name is too long to be entered in BAM qname field: " << name << "\n"; exit(EXIT_FAILURE); } const uint8_t new_qname_size(tmp_size); const uint8_t old_qname_size(bc.l_qname); const int delta(new_qname_size-old_qname_size); if(0 != delta) { change_bam_data_segment_len(old_qname_size,delta,br); bc.l_qname=new_qname_size; } strcpy(bam1_qname(&br),name); } static inline int seq_size(const int a) { return a+(a+1)/2; } void edit_bam_read_and_quality(const char* read, const uint8_t* qual, bam1_t& br){ const int new_len(strlen(read)); const int old_size(seq_size(br.core.l_qseq)); const int new_size(seq_size(new_len)); const int delta(new_size-old_size); if(0 != delta) { const int end(bam1_aux(&br)-br.data); change_bam_data_segment_len(end,delta,br); } br.core.l_qseq = new_len; // update seq: uint8_t* p(bam1_seq(&br)); memset(p,0,(new_len+1)/2); for (int i(0);i(&x)); } else if(x & 0xff00) { uint16_t y(x); bam_aux_append(&br,tag,'S',2,reinterpret_cast(&y)); } else { uint8_t z(x); bam_aux_append(&br,tag,'C',1,&z); } }