+
+int8_t seq_comp_table[16] = { 0, 8, 4, 12, 2, 10, 9, 14, 1, 6, 5, 13, 3, 11, 7, 15 };
+
+int main_bam2fq(int argc, char *argv[])
+{
+ bamFile fp;
+ bam_header_t *h;
+ bam1_t *b;
+ int8_t *buf;
+ int max_buf, c, no12 = 0;
+ while ((c = getopt(argc, argv, "n")) > 0)
+ if (c == 'n') no12 = 1;
+ if (argc == 1) {
+ fprintf(stderr, "Usage: samtools bam2fq <in.bam>\n");
+ return 1;
+ }
+ fp = strcmp(argv[optind], "-")? bam_open(argv[optind], "r") : bam_dopen(fileno(stdin), "r");
+ if (fp == 0) return 1;
+ h = bam_header_read(fp);
+ b = bam_init1();
+ buf = 0;
+ max_buf = 0;
+ while (bam_read1(fp, b) >= 0) {
+ int i, qlen = b->core.l_qseq;
+ uint8_t *seq;
+ putchar('@'); fputs(bam1_qname(b), stdout);
+ if (no12) putchar('\n');
+ else {
+ if ((b->core.flag & 0x40) && !(b->core.flag & 0x80)) puts("/1");
+ else if ((b->core.flag & 0x80) && !(b->core.flag & 0x40)) puts("/2");
+ else putchar('\n');
+ }
+ if (max_buf < qlen + 1) {
+ max_buf = qlen + 1;
+ kroundup32(max_buf);
+ buf = realloc(buf, max_buf);
+ }
+ buf[qlen] = 0;
+ seq = bam1_seq(b);
+ for (i = 0; i < qlen; ++i)
+ buf[i] = bam1_seqi(seq, i);
+ if (b->core.flag & 16) { // reverse complement
+ for (i = 0; i < qlen>>1; ++i) {
+ int8_t t = seq_comp_table[buf[qlen - 1 - i]];
+ buf[qlen - 1 - i] = seq_comp_table[buf[i]];
+ buf[i] = t;
+ }
+ if (qlen&1) buf[i] = seq_comp_table[buf[i]];
+ }
+ for (i = 0; i < qlen; ++i)
+ buf[i] = bam_nt16_rev_table[buf[i]];
+ puts((char*)buf);
+ puts("+");
+ seq = bam1_qual(b);
+ for (i = 0; i < qlen; ++i)
+ buf[i] = 33 + seq[i];
+ if (b->core.flag & 16) { // reverse
+ for (i = 0; i < qlen>>1; ++i) {
+ int8_t t = buf[qlen - 1 - i];
+ buf[qlen - 1 - i] = buf[i];
+ buf[i] = t;
+ }
+ }
+ puts((char*)buf);
+ }
+ free(buf);
+ bam_destroy1(b);
+ bam_header_destroy(h);
+ bam_close(fp);
+ return 0;
+}