#include <getopt.h>
#include <libgen.h>
#include <unistd.h>
#include <htslib/sam.h>
static void print_usage(FILE *fp)
{
fprintf(fp, "Usage: idx_on_write infile shiftsize outdir\n\
Creates compressed sam file and index file for it in given directory\n");
return;
}
int main(int argc, char *argv[])
{
const char *outdir = NULL;
char *inname = NULL, *fileidx = NULL, *outname = NULL, outmode[4] = "w";
int c = 0, ret = EXIT_FAILURE, size = 0;
samFile *infile = NULL, *outfile = NULL;
sam_hdr_t *in_samhdr = NULL;
bam1_t *bamdata = NULL;
if (argc != 4) {
print_usage(stderr);
goto end;
}
inname = argv[1];
size = atoi(argv[2]);
outdir = argv[3];
c = strlen(basename(inname)) + strlen(outdir) + 10;
fileidx = malloc(sizeof(char) * c);
outname = malloc(sizeof(char) * c);
if (!fileidx || !outname) {
printf("Couldnt allocate memory\n");
goto end;
}
if (!(bamdata = bam_init1())) {
printf("Failed to initialize bamdata\n");
goto end;
}
if ((infile = sam_open(inname, "r"))) {
if (infile->format.format == cram) {
snprintf(fileidx, c, "%s/%s.crai", outdir, basename(inname));
snprintf(outname, c, "%s/%s", outdir, basename(inname));
}
else {
if (infile->format.format == sam && infile->format.compression == no_compression) {
snprintf(outname, c, "%s/%s.gz", outdir, basename(inname));
snprintf(fileidx, c, "%s/%s.gz.%s", outdir, basename(inname), !size ? "bai" : "csi");
}
else {
snprintf(outname, c, "%s/%s", outdir, basename(inname));
snprintf(fileidx, c, "%s/%s.%s", outdir, basename(inname), !size ? "bai" : "csi");
}
}
}
c = 0;
sam_open_mode(outmode + 1, outname, NULL); outfile = sam_open(outname, outmode);
if (!outfile || !infile) {
printf("Could not open files\n");
goto end;
}
if (!(in_samhdr = sam_hdr_read(infile))) {
printf("Failed to read header from file!\n");
goto end;
}
if (sam_hdr_write(outfile, in_samhdr)) {
printf("Failed to write header\n");
goto end;
}
if (sam_idx_init(outfile, in_samhdr, size, fileidx)) {
printf("idx initialization failed\n");
goto end;
}
while ((c = sam_read1(infile, in_samhdr, bamdata)) >= 0) {
if (sam_write1(outfile, in_samhdr, bamdata) < 0) {
printf("Failed to write data\n");
goto end;
}
}
if (c != -1) {
printf("Error in reading data\n");
goto end;
}
if (sam_idx_save(outfile)) {
printf("Could not save index\n");
goto end;
}
ret = EXIT_SUCCESS;
end:
if (in_samhdr) {
sam_hdr_destroy(in_samhdr);
}
if (infile) {
sam_close(infile);
}
if (bamdata) {
bam_destroy1(bamdata);
}
if (fileidx) {
free(fileidx);
}
if (outname) {
free(outname);
}
if (outfile) {
sam_close(outfile);
}
return ret;
}