yes yes hahaha yes
This commit is contained in:
parent
2cc9198e2c
commit
b4e3394809
1 changed files with 27 additions and 20 deletions
|
@ -407,11 +407,10 @@ let atariRGB = [
|
||||||
* @param {RGB[]} input source scanline data, in linear RGB
|
* @param {RGB[]} input source scanline data, in linear RGB
|
||||||
* @param {number[]} palette - current working palette, as Atari 8-bit color values (low nybble luminance, high nybble hue)
|
* @param {number[]} palette - current working palette, as Atari 8-bit color values (low nybble luminance, high nybble hue)
|
||||||
* @param {number} n - target color count
|
* @param {number} n - target color count
|
||||||
* @param {RGB[]} inputError
|
|
||||||
* @param {number} y
|
* @param {number} y
|
||||||
* @returns {{output: number[], palette: number[], error: RGB[]}}
|
* @returns {{output: number[], palette: number[], error: RGB[]}}
|
||||||
*/
|
*/
|
||||||
function decimate(input, palette, n, inputError, y) {
|
function decimate(input, palette, n) {
|
||||||
// to brute-force, the possible palettes are:
|
// to brute-force, the possible palettes are:
|
||||||
// 255 * 254 * 253 = 16,386,810
|
// 255 * 254 * 253 = 16,386,810
|
||||||
//
|
//
|
||||||
|
@ -433,9 +432,6 @@ function decimate(input, palette, n, inputError, y) {
|
||||||
if (error) {
|
if (error) {
|
||||||
rgb.inc(error.cur[x]);
|
rgb.inc(error.cur[x]);
|
||||||
}
|
}
|
||||||
if (inputError) {
|
|
||||||
rgb.inc(inputError[x]);
|
|
||||||
}
|
|
||||||
rgb.cap();
|
rgb.cap();
|
||||||
return rgb;
|
return rgb;
|
||||||
};
|
};
|
||||||
|
@ -540,9 +536,9 @@ function decimate(input, palette, n, inputError, y) {
|
||||||
|
|
||||||
// Median cut!
|
// Median cut!
|
||||||
// https://en.wikipedia.org/wiki/Median_cut
|
// https://en.wikipedia.org/wiki/Median_cut
|
||||||
//let buckets = [input.slice()];
|
let buckets = [input.slice()];
|
||||||
let initial = dither(palette);
|
//let initial = dither(palette);
|
||||||
let buckets = [initial.output.map((i) => atariRGB[palette[i]])];
|
//let buckets = [initial.output.map((i) => atariRGB[palette[i]])];
|
||||||
let medianCut = (bucket, range) => {
|
let medianCut = (bucket, range) => {
|
||||||
if (bucket.length < 2) {
|
if (bucket.length < 2) {
|
||||||
console.log(bucket);
|
console.log(bucket);
|
||||||
|
@ -582,19 +578,25 @@ function decimate(input, palette, n, inputError, y) {
|
||||||
}
|
}
|
||||||
decimated = buckets.map((bucket) => {
|
decimated = buckets.map((bucket) => {
|
||||||
// Average the RGB colors in this chunk
|
// Average the RGB colors in this chunk
|
||||||
//let rgb = bucket
|
let rgb = bucket
|
||||||
// .reduce((acc, rgb) => acc.inc(rgb), new RGB(0, 0, 0))
|
.reduce((acc, rgb) => acc.inc(rgb), new RGB(0, 0, 0))
|
||||||
// .divide(bucket.length);
|
.divide(bucket.length);
|
||||||
|
|
||||||
// scale to the max luma
|
let avg_luma = rgb.luma();
|
||||||
|
let lumas = bucket.map((rgb) => rgb.luma());
|
||||||
|
let brightest = Math.max(...lumas);
|
||||||
|
if (avg_luma > 0) {
|
||||||
|
rgb = rgb.multiply(brightest / avg_luma);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// pick the luma-brightest color in the bucket
|
||||||
// kinda nice but really aggressive with the colors
|
// kinda nice but really aggressive with the colors
|
||||||
|
/*
|
||||||
let lumas = bucket.map((rgb) => rgb.luma());
|
let lumas = bucket.map((rgb) => rgb.luma());
|
||||||
let luma = Math.max(...lumas);
|
let luma = Math.max(...lumas);
|
||||||
let rgb = bucket[lumas.indexOf(luma)];
|
let rgb = bucket[lumas.indexOf(luma)];
|
||||||
let from = rgb.luma();
|
*/
|
||||||
if (from > 0) {
|
|
||||||
rgb = rgb.multiply(luma / rgb.luma());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take the channel-brightest color in the bucket
|
// Take the channel-brightest color in the bucket
|
||||||
// bad
|
// bad
|
||||||
|
@ -615,6 +617,7 @@ function decimate(input, palette, n, inputError, y) {
|
||||||
Math.max(...bucket.map((rgb) => rgb.b))
|
Math.max(...bucket.map((rgb) => rgb.b))
|
||||||
);
|
);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// combine the median of each channel
|
// combine the median of each channel
|
||||||
// sux
|
// sux
|
||||||
/*
|
/*
|
||||||
|
@ -734,9 +737,13 @@ async function convert(source) {
|
||||||
|
|
||||||
let lines = [];
|
let lines = [];
|
||||||
for (let y = 0; y < height; y++) {
|
for (let y = 0; y < height; y++) {
|
||||||
let error = lines[y - 1]?.error;
|
let inputLine = input
|
||||||
let inputLine = input.slice(y * width, (y + 1) * width);
|
.slice(y * width, (y + 1) * width);
|
||||||
let line = decimate(inputLine, allColors, 4, error, y);
|
if (y > 0) {
|
||||||
|
let error = lines[y - 1].error;
|
||||||
|
inputLine = inputLine.map((rgb, x) => RGB.add(rgb, error[x]));
|
||||||
|
}
|
||||||
|
let line = decimate(inputLine, allColors, 4, y);
|
||||||
lines.push(line);
|
lines.push(line);
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Reference in a new issue