#99 take out the garbage

This commit is contained in:
Autumn Lamonte 2022-01-26 16:38:17 -06:00
parent 2d072fc5f5
commit 866f93b6f4

View file

@ -64,13 +64,6 @@ public class HQSixelEncoder implements SixelEncoder {
*/
private static final int FAST_AND_DIRTY = 16;
/**
* If true, try to partition the search space. This is currently not
* working well, but it can be quite a bit faster. The inaccuracy is
* very easy to see on a color wheel: tons of artifacts.
*/
private static final boolean SEARCH_BUCKETS = true;
/**
* When run from the command line, we need both the image, and to know if
* the image is transparent in order to set to correct sixel introducer.
@ -883,133 +876,6 @@ public class HQSixelEncoder implements SixelEncoder {
int red = (rgb >>> 16) & 0xFF;
int green = (rgb >>> 8) & 0xFF;
int blue = rgb & 0xFF;
if (SEARCH_BUCKETS) {
// We compute an "online" version of the mean and variance.
count++;
double redDelta = red - redMean;
redMean += redDelta / count;
double redDelta2 = red - redMean;
redDeltaSum += redDelta * redDelta2;
double greenDelta = green - greenMean;
greenMean += greenDelta / count;
double greenDelta2 = green - greenMean;
greenDeltaSum += greenDelta * greenDelta2;
double blueDelta = blue - blueMean;
blueMean += blueDelta / count;
double blueDelta2 = blue - blueMean;
blueDeltaSum += blueDelta * blueDelta2;
}
}
if (SEARCH_BUCKETS) {
int colorN = colorMap.size();
if (colorN > 2) {
double redSq = redDeltaSum / (colorN - 1);
double greenSq = greenDeltaSum / (colorN - 1);
double blueSq = blueDeltaSum / (colorN - 1);
double totalSq = redSq + greenSq + blueSq;
double redFrac = redSq / totalSq;
double greenFrac = greenSq / totalSq;
double blueFrac = blueSq / totalSq;
// Assign the MOST bits to the SMALLEST variance.
// Smaller variance means more colors are in that range
// -- it's going to have more buckets accordingly.
int redBits = Math.max(1,
Math.min((int) ((1.0 - redFrac) * 6.0), 6));
int greenBits = Math.max(1,
Math.min((int) ((1.0 - greenFrac) * 6.0), 6));
// Must have at least 1 bit for blue.
int blueBits = Math.max(1, 8 - redBits - greenBits);
if (redFrac < greenFrac) {
// Steal it from green.
greenBits = 8 - redBits - blueBits;
} else {
// Steal it from red.
redBits = 8 - greenBits - blueBits;
}
assert (redBits + greenBits + blueBits == 8);
assert ((redBits >= 1) && (redBits <= 6));
assert ((greenBits >= 1) && (greenBits <= 6));
assert ((blueBits >= 1) && (blueBits <= 6));
if (verbosity >= 1) {
System.err.printf("Variance: %4.2f%% red %4.2f%% green %4.2f%% blue\n",
redFrac * 100.0, greenFrac * 100.0, blueFrac * 100.0);
System.err.printf(" Bits: %d red %d green %d blue\n",
redBits, greenBits, blueBits);
}
// There is a faster way to do this surely.
switch (redBits) {
case 1:
redMask = 0x800000;
break;
case 2:
redMask = 0xC00000;
break;
case 3:
redMask = 0xE00000;
break;
case 4:
redMask = 0xF00000;
break;
case 5:
redMask = 0xF80000;
break;
case 6:
redMask = 0xFC0000;
break;
default:
break;
}
switch (greenBits) {
case 1:
greenMask = 0x8000;
break;
case 2:
greenMask = 0xC000;
break;
case 3:
greenMask = 0xE000;
break;
case 4:
greenMask = 0xF000;
break;
case 5:
greenMask = 0xF800;
break;
case 6:
greenMask = 0xFC00;
break;
default:
break;
}
switch (blueBits) {
case 1:
blueMask = 0x80;
break;
case 2:
blueMask = 0xC0;
break;
case 3:
blueMask = 0xE0;
break;
case 4:
blueMask = 0xF0;
break;
case 5:
blueMask = 0xF8;
break;
case 6:
blueMask = 0xFC;
break;
default:
break;
}
}
}
int numColors = paletteSize;
@ -1083,25 +949,6 @@ public class HQSixelEncoder implements SixelEncoder {
sixelColors.set(lightestIdx, 0xFF646464);
}
// This provides a modest speedup: partition the bucket colors by
// 3 bits red, 3 bits green, 2 bits blue. Next stage is to
// assign the number of bits to each channel to maximize coverage
// of the palette space and make each searchBucket as small as
// possible.
if (SEARCH_BUCKETS) {
searchBuckets = new ArrayList<ArrayList<Bucket>>(256);
for (int i = 0; i < 256; i++) {
searchBuckets.add(new ArrayList<Bucket>());
}
for (Bucket b: buckets) {
int averageColor = b.average();
int maskedColor = ((averageColor & redMask ) >>> 16)
| ((averageColor & greenMask) >>> 8)
| (averageColor & blueMask );
searchBuckets.get(maskedColor).add(b);
}
}
quantizationDone = true;
if (verbosity >= 5) {
System.err.printf("COLOR MAP: %d entries\n",
@ -1110,14 +957,6 @@ public class HQSixelEncoder implements SixelEncoder {
System.err.printf(" %03d %08x\n", i,
sixelColors.get(i));
}
if (SEARCH_BUCKETS) {
System.err.printf("searchBuckets\n",
sixelColors.size());
for (int i = 0; i < searchBuckets.size(); i++) {
System.err.printf(" %03d\n",
searchBuckets.get(i).size());
}
}
}
if (timings != null) {
@ -1198,21 +1037,9 @@ public class HQSixelEncoder implements SixelEncoder {
//
// https://github.com/hpjansson/chafa/issues/27#issuecomment-647584817
// See first if there are buckets on the same masked color.
// TODO: find a short list of buckets that are likely to have
// a very close match.
ArrayList<Bucket> bucketsToSearch = buckets;
if (SEARCH_BUCKETS) {
int maskedColor = ((color & redMask ) >>> 16)
| ((color & greenMask) >>> 8)
| (color & blueMask );
if (searchBuckets.get(maskedColor).size() > 0) {
bucketsToSearch = searchBuckets.get(maskedColor);
if (verbosity >= 5) {
System.err.printf("Can search fast: %d buckets\n",
searchBuckets.get(maskedColor).size());
}
}
}
int red = (color >>> 16) & 0xFF;
int green = (color >>> 8) & 0xFF;
int blue = color & 0xFF;