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