wip mostly fixed

This commit is contained in:
Brooke Vibber 2023-03-25 20:15:34 -07:00
parent 9631e2e026
commit b0e7d1f579
2 changed files with 57 additions and 25 deletions

View file

@ -5,14 +5,18 @@ import {
import Jimp from 'Jimp';
function zeroes(n) {
function repeat(val, n) {
let arr = [];
for (let i = 0; i < n; i++) {
arr.push(0);
arr.push(val);
}
return arr;
}
function zeroes(n) {
return repeat(0, n);
}
function toLinear(val) {
// use a 2.4 gamma approximation
// this is BT.1886 compatible
@ -584,6 +588,10 @@ function decimate(input, palette, n) {
// preface the reserved bits
let buckets = reserved.slice().map((c) => [atariRGB[c]]).concat([input.slice()]);
if (input.length != 160) {
console.log(input.length);
throw new Error('xxx bad input size');
}
/*
let buckets = [input.slice()];
@ -633,6 +641,10 @@ function decimate(input, palette, n) {
while (buckets.length < n) {
// Find the bucket with the greatest range in any channel
let ranges = buckets.map((bucket) => {
if (bucket.length == 0) {
console.log(buckets);
throw new Error('xxx empty bucket');
}
let red = bucket.map((rgb) => rgb.r);
let green = bucket.map((rgb) => rgb.g);
let blue = bucket.map((rgb) => rgb.b);
@ -648,16 +660,17 @@ function decimate(input, palette, n) {
let greatest = 0;
let index = -1;
for (let i = 0; i < topRanges.length; i++) {
if (topRanges[i] >= greatest) {
//if (topRanges[i] >= greatest) {
if (topRanges[i] > greatest) {
greatest = topRanges[i];
index = i;
}
}
if (index == -1) {
// We just ran out of colors! Pad the buckets.
while (buckets.length < n) {
buckets.push([new RGB(0, 0, 0)]);
}
//while (buckets.length < n) {
// buckets.push([new RGB(0, 0, 0)]);
//}
break;
}
let [lo, hi] = medianCut(buckets[index], ranges[index]);
@ -775,19 +788,25 @@ async function loadImage(src) {
let width = image.bitmap.width;
let height = image.bitmap.height;
//if (width != 160 || height != 160) {
if (width != 160) {
let aspect = width / height;
let dar = 2 / 1.2;
if (aspect > ((320 / 1.2) / 192)) {
// wide
width = 160;
//height = 160;
//height = 192;
let dar = 1.2 / 2;
height = (width * image.bitmap.width / image.bitmap.height) * dar;
height = Math.round(height);
height = Math.round((width * image.bitmap.height / image.bitmap.width) * dar);
if (height & 1) {
height++;
}
image = image.resize(width, height);
} else {
// tall
height = 192;
width = Math.round((height * image.bitmap.width / image.bitmap.height) / dar);
if (width & 1) {
width++;
}
}
image = image.resize(width, height);
let rgba = image.bitmap.data.slice();
return {
@ -823,17 +842,15 @@ async function convert(source) {
height,
rgba
} = await loadImage(source);
console.log({width,height});
if (width !== 160) {
throw new Error(`expected 160px-compatible width, got ${width} pixels`);
if (width > 160) {
throw new Error(`expected <160px width, got ${width} pixels`);
}
/*
if (height !== 160) {
// @fixme support up to 240px
throw new Error(`expected 160px height, got ${height} pixels`);
if (height > 192) {
throw new Error(`expected <192px height, got ${height} pixels`);
}
*/
if (rgba.length != width * 4 * height) {
console.log(`
@ -860,10 +877,26 @@ async function convert(source) {
allColors.push(i);
}
let left = [], right = [];
let padding = 0;
if (width < 160) {
padding = 160 - width;
let black = new RGB(0, 0, 0);
left = repeat(black, padding >> 1);
right = repeat(black, padding + 1 >> 1);
}
let lines = [];
for (let y = 0; y < height; y++) {
let inputLine = input
.slice(y * width, (y + 1) * width);
if (padding) {
console.log(`length was ${inputLine.length}`);
inputLine = left.concat(inputLine, right);
console.log(`length is now ${inputLine.length}`);
}
if (y > 0) {
let error = lines[y - 1].error;
inputLine = inputLine.map((rgb, x) => rgb.add(error[x]).clamp());
@ -872,7 +905,7 @@ async function convert(source) {
lines.push(line);
}
return {
width,
width: width + padding,
height,
lines
};
@ -983,7 +1016,7 @@ ${byte2byte(odd(frame.palette3))}
.align 1024
displaylist:
; 24 lines overscan
.repeat 4
.repeat 3
.byte $70 ; 8 blank lines
.endrep
; include a DLI to mark us as frame 0

View file

@ -34,8 +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_offset = 38
scanline_max = (lines_per_frame - scanline_offset) / 2
.data