bam1_t
memory!htslib expects bam1_t
to be initially zeroed, e.g.
// on the stack
bam1_t badbamrecord; // any attempts to use this will likely crash!
bam1_t goodbamrecord = {0}; // this works.
// on the heap
bam1_t* badbamrecord_ptr = malloc(sizeof(bam1_t)); // will likely fail
bam1_t* goodbamrecord_ptr = calloc(1, sizeof(bam1_t)); // good.
When iterating over a file sans index, i.e. by invoking sam_itr_queryi
with idx == NULL
and tid == HTS_IDX_REST
, you need to access the header via sam_hdr_read
(even if nothing is being done with it) in order to advance the file pointer up to the first read:
htsFile* bam = hts_open(<path/to/bam>, "r");
hts_itr_t* bamiter = sam_itr_queryi(NULL, HTS_IDX_REST, 0, 0);
bam1_t bamrecord = {0};
//sam_hdr_read(bam); // uncomment for iterator to work
while(sam_itr_next(bam, bamiter, &bamrecord) >= 0) {
// process read
}
If the header is not read, then the first call to sam_itr_next
will try unpacking a read from the start of the file, which will fail.
To output an uncompressed BAM, you cannot use
htsFile* bam_out = hts_open("-", "wbu");
as you might expect; this will segfault. You must instead use
htsFile* bam_out = hts_open("-", "wb0");
This is because a BAM must still be in block GZIP format, even if no compression is applied.
Note that specifying output "wu"
will output a plaintext SAM file.