mirror of
https://github.com/javl/image2cpp.git
synced 2026-09-11 09:03:04 +00:00
Fix issue with bin file not using the proper byte values. Also added tests to catch these in the future.
This commit is contained in:
+39
-10
@@ -155,6 +155,18 @@ const ConversionFunctions = {
|
|||||||
};
|
};
|
||||||
settings.conversionFunction = ConversionFunctions.horizontal1bit;
|
settings.conversionFunction = ConversionFunctions.horizontal1bit;
|
||||||
|
|
||||||
|
// Bytes per output value for each conversion function, matching the
|
||||||
|
// hexWidth passed to writer.push() in that function (hexWidth / 2).
|
||||||
|
// Needed by downloadBinFile() to reconstruct the true byte stream instead
|
||||||
|
// of truncating multi-byte values (565/888) down to a single byte.
|
||||||
|
const CONVERSION_BYTES_PER_VALUE = new Map([
|
||||||
|
[ConversionFunctions.horizontal1bit, 1],
|
||||||
|
[ConversionFunctions.vertical1bit, 1],
|
||||||
|
[ConversionFunctions.horizontal565, 2],
|
||||||
|
[ConversionFunctions.horizontal888, 4],
|
||||||
|
[ConversionFunctions.horizontalAlpha, 1],
|
||||||
|
]);
|
||||||
|
|
||||||
// An images collection with helper methods
|
// An images collection with helper methods
|
||||||
function Images() {
|
function Images() {
|
||||||
const collection = [];
|
const collection = [];
|
||||||
@@ -983,20 +995,37 @@ function copyOutput() {
|
|||||||
navigator.clipboard.writeText(output.value);
|
navigator.clipboard.writeText(output.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rebuilds the true byte stream for the current images/conversion mode by
|
||||||
|
// re-splitting each formatted output value (which may be 1, 2 or 4 bytes
|
||||||
|
// wide, depending on drawMode) back into its individual bytes, most-
|
||||||
|
// significant first. Exposed standalone so it can be exercised directly in
|
||||||
|
// tests without going through a real browser file download.
|
||||||
|
function computeBinData() {
|
||||||
|
const bytesPerValue = CONVERSION_BYTES_PER_VALUE.get(settings.conversionFunction) || 1;
|
||||||
|
const raw = [];
|
||||||
|
images.each((image) => {
|
||||||
|
const values = imageToString(image)
|
||||||
|
.split(',')
|
||||||
|
.map((s) => s.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
.map((token) => parseInt(token, 16));
|
||||||
|
values.forEach((value) => {
|
||||||
|
// Split back into individual bytes, most-significant first, matching
|
||||||
|
// the left-to-right digit order produced by toString(16).padStart().
|
||||||
|
for (let shift = (bytesPerValue - 1) * 8; shift >= 0; shift -= 8) {
|
||||||
|
// eslint-disable-next-line no-bitwise
|
||||||
|
raw.push((value >> shift) & 0xff);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return new Uint8Array(raw);
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
function downloadBinFile() {
|
function downloadBinFile() {
|
||||||
if (!checkImagesAvailable()) return;
|
if (!checkImagesAvailable()) return;
|
||||||
|
|
||||||
let raw = [];
|
const data = computeBinData();
|
||||||
images.each((image) => {
|
|
||||||
const data = imageToString(image)
|
|
||||||
.split(',')
|
|
||||||
.map((s) => s.trim())
|
|
||||||
.filter(Boolean)
|
|
||||||
.map((byte) => parseInt(byte, 16));
|
|
||||||
raw = raw.concat(data);
|
|
||||||
});
|
|
||||||
const data = new Uint8Array(raw);
|
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
a.style = 'display: none';
|
a.style = 'display: none';
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
|
|||||||
@@ -129,6 +129,45 @@ SCENARIOS = [
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Bytes per output value per drawMode, mirroring CONVERSION_BYTES_PER_VALUE in
|
||||||
|
# js/script.js. Used to verify downloadBinFile()'s byte stream (via the
|
||||||
|
# computeBinData() helper) matches the hex values shown in the text output,
|
||||||
|
# instead of the multi-byte values (565/888) getting truncated to one byte.
|
||||||
|
BYTES_PER_VALUE = {
|
||||||
|
"horizontal1bit": 1,
|
||||||
|
"vertical1bit": 1,
|
||||||
|
"horizontal565": 2,
|
||||||
|
"horizontal888": 4,
|
||||||
|
"horizontalAlpha": 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Scenario names to also verify against computeBinData(); restricted to ones
|
||||||
|
# using the default plain/comma-separated output (outputFormat and separator
|
||||||
|
# untouched), since that's the format downloadBinFile's parser expects.
|
||||||
|
BIN_CHECK_NAMES = {
|
||||||
|
"default",
|
||||||
|
"draw_mode_vertical1bit",
|
||||||
|
"draw_mode_horizontal565",
|
||||||
|
"draw_mode_horizontal888",
|
||||||
|
"draw_mode_horizontal_alpha",
|
||||||
|
"rotate_90_horizontal565",
|
||||||
|
"rotate_90_horizontal888",
|
||||||
|
"rotate_90_horizontal_alpha",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def expected_bin_bytes(output, draw_mode):
|
||||||
|
"""Reconstruct the byte stream a correct downloadBinFile() should produce
|
||||||
|
from the plain-format hex text output, expanding each value back to its
|
||||||
|
full byte width (MSB first) instead of assuming one byte per value."""
|
||||||
|
bytes_per_value = BYTES_PER_VALUE[draw_mode]
|
||||||
|
values = (int(tok, 16) for tok in re.findall(r"0x[0-9a-fA-F]+", output))
|
||||||
|
result = []
|
||||||
|
for value in values:
|
||||||
|
for shift in range((bytes_per_value - 1) * 8, -1, -8):
|
||||||
|
result.append((value >> shift) & 0xFF)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def reset_canvas_size(page, width, height):
|
def reset_canvas_size(page, width, height):
|
||||||
"""Set canvas size through the real width/height text inputs."""
|
"""Set canvas size through the real width/height text inputs."""
|
||||||
@@ -272,6 +311,15 @@ def main():
|
|||||||
|
|
||||||
print(f"ok {name}")
|
print(f"ok {name}")
|
||||||
|
|
||||||
|
if name in BIN_CHECK_NAMES:
|
||||||
|
expected_bytes = expected_bin_bytes(output, settings["drawMode"])
|
||||||
|
actual_bytes = page.evaluate("Array.from(computeBinData())")
|
||||||
|
if actual_bytes != expected_bytes:
|
||||||
|
failures.append(f"{name}: bin data mismatch")
|
||||||
|
print(f"FAIL {name} (bin)")
|
||||||
|
else:
|
||||||
|
print(f"ok {name} (bin)")
|
||||||
|
|
||||||
if roundtrip_eligible(settings):
|
if roundtrip_eligible(settings):
|
||||||
width, height = resize or (NATIVE_WIDTH, NATIVE_HEIGHT)
|
width, height = resize or (NATIVE_WIDTH, NATIVE_HEIGHT)
|
||||||
roundtripped = run_roundtrip(page, output, settings["drawMode"], width, height)
|
roundtripped = run_roundtrip(page, output, settings["drawMode"], width, height)
|
||||||
|
|||||||
Reference in New Issue
Block a user