+ }
+
+ /**
+ * Precalculate the columns that will be used for each pixel in a dense
+ * overview. So we have to skip through the bscol BitSet to pick up one
+ * (representative?) column for each pixel.
+ *
+ * Note that there is no easy solution if we want to do color averaging, but
+ * this method might be adapted to do that. Or it could be adapted to pick the
+ * "most representative color" for a group of columns.
+ *
+ * @author Bob Hanson 2019.09.03
+ * @return a -1 terminated int[]
+ */
+ private int[] calcColumnsToShow()
+ {
+ int[] a = new int[w + 1];
+ float colBuffer = 0;
+ float offset = bscol.nextSetBit(0);
+ if (offset < 0)
+ {
+ return new int[] { -1 };
+ }
+ int pixel = 0;
+ a[pixel++] = (int) offset;
+ // for example, say we have 10 pixels per column:
+ // ...............xxxxxxxx....xxxxxx.........xxxxxx......
+ // nextSet(i).....^...........^..............^...........
+ // nextClear..............^.........^..............^.....
+ // run lengths....|--n1--|....|-n2-|.........|-n3-|......
+ // 10 pixel/col...|---pixel1---||-----pixel2------|......
+ // pixel..........^0............^1.......................
+ for (int i, iClear = -1; pixel < w
+ && (i = bscol.nextSetBit(iClear + 1)) >= 0;)
+ {
+ // find the next clear bit
+ iClear = bscol.nextClearBit(i + 1);
+ // add the run length n1, n2, n3 to grow the column buffer
+ colBuffer += iClear - i; // n1, n2, etc.
+ // add columns if we have accumulated enough pixels
+
+ while (colBuffer > colsPerPixel && pixel < w)
+ {
+ colBuffer -= colsPerPixel;
+ offset += colsPerPixel;
+ a[pixel++] = i + (int) offset;
+ }
+ // set back column pointer relative to the next run
+ offset = -colBuffer;
+ }
+ // add a terminator
+ a[pixel] = -1;
+ return a;
+ }
+
+ /**
+ * The next column is either a precalculated pixel (when there are multiple
+ * pixels per column) or the next set bit for the column that aligns with the
+ * next pixel (when there are more columns than pixels).
+ *
+ * When columns are hidden, this value is precalculated; otherwise it is
+ * calculated here.
+ *
+ * @param icol
+ * @param pixel
+ * pixel pointer into columnsToShow
+ * @return
+ */
+ private int getNextCol(int icol, int pixel)
+ {
+ return (skippingColumns ? columnsToShow[pixel]
+ : bscol.nextSetBit(icol + 1));
+ }