ef80854d868978e0da8e60f4ec0aad06b10f8a82
braney
  Thu Sep 28 09:42:31 2023 -0700
allow bedToBigBed to use compressed input

diff --git src/utils/bedToBigBed/bedToBigBed.c src/utils/bedToBigBed/bedToBigBed.c
index 1013687..4ac7bed 100644
--- src/utils/bedToBigBed/bedToBigBed.c
+++ src/utils/bedToBigBed/bedToBigBed.c
@@ -114,30 +114,45 @@
    {"itemsPerSlot", OPTION_INT},
    {"type", OPTION_STRING},
    {"as", OPTION_STRING},
    {"unc", OPTION_BOOLEAN},
    {"tab", OPTION_BOOLEAN},
    {"sizesIs2Bit", OPTION_BOOLEAN},
    {"sizesIsChromAliasBb", OPTION_BOOLEAN},
    {"sizesIsBb", OPTION_BOOLEAN},
    {"extraIndex", OPTION_STRING},
    {"udcDir", OPTION_STRING},
    {"allow1bpOverlap", OPTION_BOOLEAN},
    {"maxAlloc", OPTION_LONG_LONG},
    {NULL, 0},
 };
 
+static struct lineFile *rewindFile(char *inName, struct lineFile *lf)
+/* set up lineFile to point at the beginning of the file.  It we're reading from a decompressing
+ * pipe, we need to close and reopen the pipe. */
+{
+if (lf->pl)
+    {
+    lineFileClose(&lf);
+    lf = lineFileOpen(inName, TRUE);
+    }
+else
+    lineFileRewind(lf);
+
+return lf;
+}
+
 int bbNamedFileChunkCmpByName(const void *va, const void *vb)
 /* Compare two named offset object to facilitate qsorting by name. */
 {
 const struct bbNamedFileChunk *a = va, *b = vb;
 return strcmp(a->name, b->name);
 }
 
 static int maxBedNameSize;
 
 void bbNamedFileChunkKey(const void *va, char *keyBuf)
 /* Copy name to keyBuf for bPlusTree maker */
 {
 const struct bbNamedFileChunk *item = va;
 strncpy(keyBuf,item->name, maxBedNameSize);
 }
@@ -672,56 +687,57 @@
 
 /* Set up to keep track of possible initial reduction levels. */
 int resScales[bbiMaxZoomLevels], resSizes[bbiMaxZoomLevels];
 int resTryCount = bbiCalcResScalesAndSizes(aveSize, resScales, resSizes);
 
 /* Write out primary full resolution data in sections, collect stats to use for reductions. */
 bits64 dataOffset = ftell(f);
 bits32 blockCount = 0;
 bits32 maxBlockSize = 0;
 struct bbiBoundsArray *boundsArray = NULL;
 writeOne(f, bedCount);
 if (bedCount > 0)
     {
     blockCount = bbiCountSectionsNeeded(usageList, itemsPerSlot);
     AllocArray(boundsArray, blockCount);
-    lineFileRewind(lf);
+    lf = rewindFile(inName, lf);
     if (eim)
 	bbExIndexMakerAllocChunkArrays(eim, bedCount);
     writeBlocks(usageList, lf, as, itemsPerSlot, boundsArray, blockCount, doCompress,
 	    f, resTryCount, resScales, resSizes, eim, bedCount, fieldCount, &maxBlockSize);
     }
 verboseTime(1, "pass2 - checking and writing primary data (%lld records, %d fields)", 
 	(long long)bedCount, fieldCount);
 
 /* Write out primary data index. */
 bits64 indexOffset = ftell(f);
 cirTreeFileBulkIndexToOpenFile(boundsArray, sizeof(boundsArray[0]), blockCount,
     blockSize, 1, NULL, bbiBoundsArrayFetchKey, bbiBoundsArrayFetchOffset, 
     indexOffset, f);
 freez(&boundsArray);
 verboseTime(2, "index write");
 
 /* Declare arrays and vars that track the zoom levels we actually output. */
 bits32 zoomAmounts[bbiMaxZoomLevels];
 bits64 zoomDataOffsets[bbiMaxZoomLevels];
 bits64 zoomIndexOffsets[bbiMaxZoomLevels];
 
 /* Call monster zoom maker library function that bedGraphToBigWig also uses. */
 int zoomLevels = 0;
 if (bedCount > 0)
     {
+    lf = rewindFile(inName, lf); // rewind here so bbiWriteZoomLevels() won't have to
     zoomLevels = bbiWriteZoomLevels(lf, f, blockSize, itemsPerSlot,
 	bedWriteReducedOnceReturnReducedTwice, fieldCount,
 	doCompress, indexOffset - dataOffset, 
 	usageList, resTryCount, resScales, resSizes, 
 	zoomAmounts, zoomDataOffsets, zoomIndexOffsets, &totalSum);
     }
 
 /* Write out extra indexes if need be. */
 if (eim)
     {
     int i;
     for (i=0; i < eim->indexCount; ++i)
         {
 	eim->fileOffsets[i] = ftell(f);
 	maxBedNameSize = eim->maxFieldSize[i];