WIP trying to redo some stuff

This commit is contained in:
Brooke Vibber 2023-03-19 00:17:53 -07:00
parent bc354d9f05
commit 801c6ee0a6

View file

@ -110,16 +110,10 @@ class RGB {
);
}
magnitude() {
return Math.sqrt(
this.r * this.r +
magnitude2() {
return this.r * this.r +
this.g * this.g +
this.b * this.b
);
}
distance(other) {
return this.difference(other).magnitude();
this.b * this.b;
}
}
@ -437,6 +431,7 @@ function decimate(input, palette, n, inputError) {
let output = new Uint8Array(width);
let popularity = new Int32Array(width);
let distance2 = 0;
let nextError = new RGB(0, 0, 0);
@ -451,7 +446,7 @@ function decimate(input, palette, n, inputError) {
for (let i = 0; i < palette.length; i++) {
let diff = rgb.difference(atariRGB[palette[i]]);
let dist = diff.magnitude();
let dist = diff.magnitude2();
if (dist < shortest) {
nextError = diff;
shortest = dist;
@ -472,15 +467,16 @@ function decimate(input, palette, n, inputError) {
error.next[x]?.inc(double);
error.next[x + 1]?.inc(double);
// 442 is the 3d distance across the rgb cube
//fitness[x] = 442 - (nextError.magnitude());
//fitness[x] = 442 / (442 - nextError.magnitude());
fitness[x] = 255 / (256 - Math.max(0, nextError.r, nextError.g, nextError.b));
// just store the distance2
let mag2 = nextError.magnitude2();
fitness[x] = mag2;
distance2 += mag2;
}
return {
output,
palette,
fitness,
distance2,
popularity,
error: error.next
};
@ -510,43 +506,34 @@ function decimate(input, palette, n, inputError) {
}
while (decimated.length > n) {
let {popularity, fitness, output} = dither(decimated);
// Try dropping least used color on each iteration
let least = Infinity;
let pick = -1;
for (let i = 1; i < decimated.length; i++) {
// Try dithering to every possible subset
// See which has the worst overall fit and drop it
let farthest = -1;
let worstIndex = -1;
for (let i = 0; i < decimated.length; i++) {
let color = decimated[i];
if (keepers[color]) {
continue;
}
let coolFactor = fitness[i] * popularity[i];
//let coolFactor = popularity[i];
//let coolFactor = (fitness[i] ** 2) * popularity[i];
let shorter = decimated.filter((x) => x != i);
let {distance2} = dither(shorter);
if (coolFactor < least) {
pick = i;
least = coolFactor;
if (distance2 >= farthest) {
farthest = distance2;
worstIndex = i;
}
}
let last = decimated.length;
decimated = decimated.filter((color, i) => {
if (keepers[color]) {
return true;
}
if (i == pick) {
return false;
}
return true;
});
if (decimated.length == last && last > n) {
console.log(decimated);
console.log(`worstIndex ${worstIndex} farthest ${farthest}`);
let foo = decimated.length;
decimated.splice(worstIndex, 1);
//console.log(decimated.length);
if (decimated.length == foo) {
throw new Error('this should not happen');
}
//console.log('n ', decimated);
}
console.log('end', decimated);
// Palette fits
return dither(decimated);
@ -639,6 +626,7 @@ async function convert(source, nbits) {
let lines = [];
for (let y = 0; y < height; y++) {
console.log(`y ${y}`);
let error = lines[y - 1]?.error;
let inputLine = input.slice(y * width, (y + 1) * width);
let line = decimate(inputLine, allColors, 4, error);