From ece161d6d6d972514bd8fc187e4c7e79d036c152 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sun, 4 Dec 2022 14:21:46 -0800 Subject: [PATCH] WIP 4-frame output --- Makefile | 4 +++- dither-image.js | 33 ++++++++++++++++++++++++--------- pack-wav.js | 2 ++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 69ad089..576d4f3 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ all : sample0.xex sample1.xex sample2.xex sample3.xex sample4.xex sample5.xex sa # $@ is output %.s : %.jpg dither-image.js - node dither-image.js $< $@ $@.png + node dither-image.js $< $@ chickens.s : chickens.wav pack-wav.js node pack-wav.js $< $@ @@ -24,6 +24,8 @@ clean : rm -f sample[0-6].o rm -f sample[0-6].xex rm -f sample[0-6].s.png + rm -f sample[0-6].s.0.png + rm -f sample[0-6].s.1.png rm -f chickens.s rm -f chickens.o diff --git a/dither-image.js b/dither-image.js index e502cfe..717f1ef 100644 --- a/dither-image.js +++ b/dither-image.js @@ -383,8 +383,8 @@ let atariRGB = [ * @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} n - target color count - * @param {Object} inputError - * @returns {{output: Uint8Array, palette: number[], error: {red: Float64Array, green: Float64Array, blue: Float64Array}}} + * @param {RGB[]} inputError + * @returns {{output: Uint8Array, palette: number[], error: RGB[]}} */ function decimate(input, palette, n, inputError) { // to brute-force, the possible palettes are: @@ -446,9 +446,10 @@ function decimate(input, palette, n, inputError) { popularity[pick]++; if (x == width - 1) { - let half = nextError.divide(2); + let half = nextError.divide(4); error.next[x - 1].inc(half); error.next[x].inc(half); + // drop half the error on the floor at the edge ;_; } else { let quarter = nextError.divide(4); error.right = quarter; @@ -565,7 +566,7 @@ function imageToLinearRGB(rgba) { * @param {string} source path to source image file * @returns {{width: number, height: number, lines: {palette: Array, output: Uint8Array}[]}} */ -async function convert(source, nbits) { +async function convert(source, nbits, reps) { let { width, @@ -590,6 +591,15 @@ async function convert(source, nbits) { throw new Error('inconsistent data size'); } + if (reps > 1) { + height *= reps; + let rgba2 = new Uint8Array(rgba.length * reps); + for (let i = 0; i < reps; i++) { + rgba2.set(rgba, rgba.length * i); + } + rgba = rgba2; + } + let input = imageToLinearRGB(rgba); if (input.length != width * height) { @@ -649,7 +659,7 @@ function genAssembly(width, height, nbits, lines) { let palette2 = new Uint8Array(height); let palette3 = new Uint8Array(height); let bitmap = new Uint8Array(stride * height); - for (let y = 0; y < height; y++) { + for (let y = 0; y < lines.length; y++) { palette1[y] = lines[y].palette[1]; palette2[y] = lines[y].palette[2]; palette3[y] = lines[y].palette[3]; @@ -723,19 +733,24 @@ async function saveImage(width, height, lines, dest) { } async function main() { - if (process.argv.length < 5) { - console.error("Usage: node dither-image.js source-image.jpg dest-asm.s dest-preview.png"); + if (process.argv.length < 3) { + console.error("Usage: node dither-image.js source-image.jpg dest-asm.s"); process.exit(1); } let nbits = 2; + let reps = 4; - let {width, height, lines} = await convert(process.argv[2], nbits); + let {width, height, lines} = await convert(process.argv[2], nbits, reps); let asm = genAssembly(width, height, nbits, lines); writeFileSync(process.argv[3], asm, "utf-8"); - await saveImage(width, height, lines, process.argv[4]); + let heightPerFrame = height / reps; + for (let i = 0; i < reps; i++) { + let slice = lines.slice(i * heightPerFrame, (i + 1) * heightPerFrame); + await saveImage(width, heightPerFrame, slice, `${process.argv[3]}.${i}.png`); + } process.exit(0); } diff --git a/pack-wav.js b/pack-wav.js index c60cca5..614aefe 100644 --- a/pack-wav.js +++ b/pack-wav.js @@ -62,6 +62,8 @@ let infile = process.argv[2]; let outfile = process.argv[3]; let buffer = readFileSync(infile); +// @FIXME fix +buffer = buffer.slice(0, 262); let asm = wav2assembly(buffer); writeFileSync(outfile, asm, 'utf-8');