b29f1fbf93c9df5aa65fed050d9f8132dc6a2c73
braney
  Tue Nov 24 14:20:10 2015 -0800
support htslib for sam/bam/cram/tabix support  #14717

diff --git src/hg/lib/hgBam.c src/hg/lib/hgBam.c
index 41fb505..b59ab97 100644
--- src/hg/lib/hgBam.c
+++ src/hg/lib/hgBam.c
@@ -122,57 +122,69 @@
 int i;
 for (i=0; i<size; ++i)
     s[i] += amount;
 }
 
 static boolean isAllSameChar(char *s, int size, char c)
 /* Return TRUE if first size chars of s are 0 */
 {
 int i;
 for (i=0; i<size; ++i)
     if (s[i] != c)
 	return FALSE;
 return TRUE;
 }
 
+#ifdef USE_HTS
+int bamAddOneSamAlignment(const bam1_t *bam, void *data, bam_hdr_t *header)
+#else
 int bamAddOneSamAlignment(const bam1_t *bam, void *data)
+#endif
 /* bam_fetch() calls this on each bam alignment retrieved.  Translate each bam
  * into a samAlignment. */
 {
 struct bamToSamHelper *helper = (struct bamToSamHelper *)data;
 struct lm *lm = helper->lm;
 struct samAlignment *sam;
 lmAllocVar(lm, sam);
 const bam1_core_t *core = &bam->core;
 struct dyString *dy = helper->dy;
 sam->qName = lmCloneString(lm, bam1_qname(bam));
 sam->flag = core->flag;
 if (helper->chrom != NULL)
     sam->rName = helper->chrom;
 else
+#ifdef USE_HTS
+    sam->rName = lmCloneString(lm, header->target_name[core->tid]);
+#else
     sam->rName = lmCloneString(lm, helper->samFile->header->target_name[core->tid]);
+#endif
 sam->pos = core->pos + 1;
 sam->mapQ = core->qual;
 dyStringClear(dy);
 bamUnpackCigar(bam, dy);
 sam->cigar = lmCloneStringZ(lm, dy->string, dy->stringSize);
 if (core->mtid >= 0)
     {
     if (core->tid == core->mtid)
 	sam->rNext = "=";
     else
+#ifdef USE_HTS
+	sam->rNext = lmCloneString(lm, header->target_name[core->mtid]);
+#else
 	sam->rNext = lmCloneString(lm, helper->samFile->header->target_name[core->mtid]);
+#endif
     }
 else
     sam->rNext = "*";
 sam->pNext = core->mpos + 1;
 sam->tLen = core->isize;
 sam->seq = lmAlloc(lm, core->l_qseq + 1);
 bamUnpackQuerySequence(bam, FALSE, sam->seq);
 char *bamQual = (char *)bam1_qual(bam);
 if (isAllSameChar(bamQual, core->l_qseq, -1))
     sam->qual = "*";
 else
     {
     sam->qual = lmCloneStringZ(lm, bamQual, core->l_qseq);
     addToChars(sam->qual, core->l_qseq, 33);
     }
@@ -189,50 +201,60 @@
  * bam record.  Results is allocated out of lm, since it tends to be large... */
 {
 struct bamToSamHelper helper;
 helper.lm = lm;
 helper.chrom = chrom;
 helper.dy = dyStringNew(0);
 helper.samList = NULL;
 char posForBam[256];
 safef(posForBam, sizeof(posForBam), "%s:%d-%d", chrom, start+1, end);
 bamFetch(fileOrUrl, posForBam, bamAddOneSamAlignment, &helper, &helper.samFile);
 dyStringFree(&helper.dy);
 slReverse(&helper.samList);
 return helper.samList;
 }
 
+#ifdef USE_HTS
+struct samAlignment *bamReadNextSamAlignments(samfile_t *fh, bam_hdr_t *header,  int count, struct lm *lm)
+#else
 struct samAlignment *bamReadNextSamAlignments(samfile_t *fh, int count, struct lm *lm)
+#endif
 /* Read next count alignments in SAM format, allocated in lm.  May return less than
  * count at end of file. */
 {
 /* Set up helper. */
 struct bamToSamHelper helper;
 helper.lm = lm;
 helper.chrom = NULL;
 helper.dy = dyStringNew(0);
 helper.samFile = fh;
 helper.samList = NULL;
 
 /* Loop through calling our own fetch function */
 int i;
 bam1_t *b = bam_init1();
 for (i=0; i<count; ++i)
     {
+#ifdef USE_HTS
+    if (sam_read1(fh,   header,  b) < 0)
+       break;
+    bamAddOneSamAlignment(b, &helper, header);
+#else
     if (samread(fh, b) < 0)
        break;
     bamAddOneSamAlignment(b, &helper);
+#endif
     }
 bam_destroy1(b);
 
 /* Clean up and go home. */
 dyStringFree(&helper.dy);
 slReverse(&helper.samList);
 return helper.samList;
 }
 
 #else
 // If we're not compiling with samtools, make stub routines so compile won't fail:
 
 char *bamFileNameFromTable(struct sqlConnection *conn, char *table, char *bamSeqName)
 /* Return file name from table.  If table has a seqName column, then grab the
  * row associated with bamSeqName (which is not nec. in chromInfo, e.g.