From 9631e2e026f29f2776a744490c80ff0ae5099f90 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 25 Mar 2023 19:43:57 -0700 Subject: [PATCH] fixes --- dither-image.js | 71 +++++++++++++++++++++++++++++++------------ dither4.s | 1 + video-doom/extract.sh | 2 +- 3 files changed, 53 insertions(+), 21 deletions(-) diff --git a/dither-image.js b/dither-image.js index a481e21..2690485 100644 --- a/dither-image.js +++ b/dither-image.js @@ -585,6 +585,26 @@ function decimate(input, palette, n) { // preface the reserved bits let buckets = reserved.slice().map((c) => [atariRGB[c]]).concat([input.slice()]); + /* + let buckets = [input.slice()]; + if (reserved.length > 0) { + let pxPerReserved = input.length; + for (let c of reserved) { + for (let i = 0; i < pxPerReserved; i++) { + buckets[0].unshift(atariRGB[c]); + } + } + console.log(buckets[0].length, 'xxx'); + } + */ + + let magicSort = (picker) => (a, b) => { + let bychannel = picker(b) - picker(a); + if (bychannel) return bychannel; + + let byluma = b.luma() - a.luma(); + return byluma; + }; let medianCut = (bucket, range) => { if (bucket.length < 2) { console.log(bucket); @@ -594,15 +614,21 @@ function decimate(input, palette, n) { // Sort by the channel with the greatest range, // then cut the bucket in two at the median. if (range.g >= range.r && range.g >= range.b) { - bucket.sort((a, b) => b.g - a.g); + //bucket.sort((a, b) => b.g - a.g); + bucket.sort(magicSort((rgb) => rgb.g)); } else if (range.r >= range.g && range.r >= range.b) { - bucket.sort((a, b) => b.r - a.r); + //bucket.sort((a, b) => b.r - a.r); + bucket.sort(magicSort((rgb) => rgb.r)); } else if (range.b >= range.g && range.b >= range.r) { - bucket.sort((a, b) => b.b - a.b); + //bucket.sort((a, b) => b.b - a.b); + bucket.sort(magicSort((rgb) => rgb.b)); } let half = bucket.length >> 1; //console.log('cutting', half, bucket.length); - return [bucket.slice(0, half), bucket.slice(half)]; + let [bottom, top] = [bucket.slice(0, half), bucket.slice(half)]; + //console.log({bottom, top}); + return [bottom, top]; + //return [bucket.slice(0, half), bucket.slice(half)]; }; while (buckets.length < n) { // Find the bucket with the greatest range in any channel @@ -729,8 +755,11 @@ function decimate(input, palette, n) { }); // hack decimated.sort((a, b) => a - b); - //console.log(decimated); - decimated[0] = 0; + console.log(decimated); + + // we shouldn't have to do this + //decimated[0] = 0; + console.log(decimated); // Palette fits return dither(decimated); @@ -837,7 +866,7 @@ async function convert(source) { .slice(y * width, (y + 1) * width); if (y > 0) { let error = lines[y - 1].error; - inputLine = inputLine.map((rgb, x) => rgb.add(error[x])); + inputLine = inputLine.map((rgb, x) => rgb.add(error[x]).clamp()); } let line = decimate(inputLine, allColors, 4, y); lines.push(line); @@ -904,12 +933,14 @@ function genAssembly(width, height, nbits, lines) { return `.data .export frame1_top .export frame1_bottom + .export frame1_palette1_even .export frame1_palette1_odd .export frame1_palette2_even .export frame1_palette2_odd .export frame1_palette3_even .export frame1_palette3_odd + .export displaylist .segment "BUFFERS" @@ -918,30 +949,30 @@ function genAssembly(width, height, nbits, lines) { frame1_top: ${byte2byte(frame.bitmap.slice(0, half))} -.align 128 -frame1_palette1_even: -${byte2byte(even(frame.palette1))} - -.align 128 -frame1_palette2_even: -${byte2byte(even(frame.palette2))} - -.align 128 -frame1_palette3_even: -${byte2byte(even(frame.palette3))} - .align 4096 frame1_bottom: ${byte2byte(frame.bitmap.slice(half))} +.align 128 +frame1_palette1_even: +${byte2byte(even(frame.palette1))} + .align 128 frame1_palette1_odd: ${byte2byte(odd(frame.palette1))} +.align 128 +frame1_palette2_even: +${byte2byte(even(frame.palette2))} + .align 128 frame1_palette2_odd: ${byte2byte(odd(frame.palette2))} +.align 128 +frame1_palette3_even: +${byte2byte(even(frame.palette3))} + .align 128 frame1_palette3_odd: ${byte2byte(odd(frame.palette3))} @@ -951,7 +982,7 @@ ${byte2byte(odd(frame.palette3))} .align 1024 displaylist: - ; 40 lines overscan + ; 24 lines overscan .repeat 4 .byte $70 ; 8 blank lines .endrep diff --git a/dither4.s b/dither4.s index 6513a16..64a570d 100644 --- a/dither4.s +++ b/dither4.s @@ -34,6 +34,7 @@ bytes_per_line = 40 pages_per_frame = 32 lines_per_frame = 262 ;scanline_offset = 31 + (40 - 24) / 2 +;scanline_offset = 46 scanline_offset = 46 scanline_max = (lines_per_frame - scanline_offset) / 2 diff --git a/video-doom/extract.sh b/video-doom/extract.sh index e3b4107..b34bcea 100644 --- a/video-doom/extract.sh +++ b/video-doom/extract.sh @@ -2,7 +2,7 @@ set -a mkdir -p frames -TIME=37 +TIME=37.5 ffmpeg \ -i 'doom-speedrun.webm' \