gbp-decode
Advanced tools
+2
-2
| { | ||
| "name": "gbp-decode", | ||
| "version": "1.3.12", | ||
| "version": "1.3.13", | ||
| "description": "A set of functions to decode gameboy printer code", | ||
@@ -24,3 +24,3 @@ "scripts": { | ||
| "type": "git", | ||
| "url": "https://github.com/HerrZatacke/gbp-decode.git" | ||
| "url": "git+https://github.com/HerrZatacke/gbp-decode.git" | ||
| }, | ||
@@ -27,0 +27,0 @@ "keywords": [ |
| 'use strict'; | ||
| const completeFrame = require('./shared/gbp-decode.ccdfabeb.cjs'); | ||
| const commandName = (command) => { | ||
| switch (command) { | ||
| case completeFrame.COMMAND.INIT: | ||
| return "INIT"; | ||
| case completeFrame.COMMAND.PRINT: | ||
| return "PRINT"; | ||
| case completeFrame.COMMAND.DATA: | ||
| return "DATA"; | ||
| case completeFrame.COMMAND.STATUS: | ||
| return "STATUS"; | ||
| default: | ||
| return "-"; | ||
| } | ||
| }; | ||
| const logPackets = (packets) => { | ||
| console.log( | ||
| packets.map(({ command, data, hasCompression, dataLength }) => ({ | ||
| command: commandName(command), | ||
| hasCompression: hasCompression ? "yes" : "no", | ||
| dataLength, | ||
| data: data.margins ? `marginUpper: ${data.marginUpper} - marginLower: ${data.marginLower}` : data.slice(0, 20).join(",") | ||
| })) | ||
| ); | ||
| return packets; | ||
| }; | ||
| const main = { | ||
| parsePackets: completeFrame.parsePackets, | ||
| parseReducedPackets: completeFrame.parseReducedPackets, | ||
| inflateTransferPackages: completeFrame.inflateTransferPackages, | ||
| getImageDataStream: completeFrame.getImageDataStream, | ||
| decompressDataStream: completeFrame.decompressDataStream, | ||
| decodePrintCommands: completeFrame.decodePrintCommands, | ||
| harmonizePalettes: completeFrame.harmonizePalettes, | ||
| transformToClassic: completeFrame.transformToClassic, | ||
| unpack: completeFrame.unpack, | ||
| parsePaletteByte: completeFrame.parsePaletteByte, | ||
| harmonizePalette: completeFrame.harmonizePalette, | ||
| completeFrame: completeFrame.completeFrame, | ||
| logPackets | ||
| }; | ||
| module.exports = main; |
| declare enum COMMAND { | ||
| INIT = 1, | ||
| PRINT = 2, | ||
| DATA = 4, | ||
| STATUS = 15, | ||
| TRANSFER = 16 | ||
| } | ||
| type PaletteData = [number, number, number, number]; | ||
| type HarmonisedPalette = [number, number]; | ||
| interface PrintData { | ||
| margins: number; | ||
| marginUpper: number; | ||
| marginLower: number; | ||
| palette: number; | ||
| paletteData: PaletteData; | ||
| } | ||
| interface Packet { | ||
| command: null | COMMAND; | ||
| buffer: number[]; | ||
| data: number[]; | ||
| hasCompression: number; | ||
| dataLength: number; | ||
| checksum?: number; | ||
| } | ||
| type ParsedPacket = Omit<Packet, 'buffer'>; | ||
| interface PrintPacket extends Omit<Packet, 'data'> { | ||
| command: COMMAND.PRINT; | ||
| data: PrintData; | ||
| } | ||
| interface TransformedImage { | ||
| transformed: string[]; | ||
| palette?: PaletteData; | ||
| } | ||
| declare const _default: { | ||
| parsePackets: (bytes: number[]) => ParsedPacket[]; | ||
| parseReducedPackets: (bytes: number[]) => ParsedPacket[]; | ||
| inflateTransferPackages: (packets: ParsedPacket[]) => ParsedPacket[]; | ||
| getImageDataStream: (packets: ParsedPacket[]) => ParsedPacket[]; | ||
| decompressDataStream: (packets: ParsedPacket[]) => ParsedPacket[]; | ||
| decodePrintCommands: (packets: ParsedPacket[]) => (ParsedPacket | PrintPacket)[]; | ||
| harmonizePalettes: (packets: (ParsedPacket | PrintPacket)[]) => (ParsedPacket | PrintPacket)[]; | ||
| transformToClassic: (packets: (ParsedPacket | PrintPacket)[]) => string[][]; | ||
| unpack: (data: number[]) => number[]; | ||
| parsePaletteByte: (paletteRaw: number) => PaletteData; | ||
| harmonizePalette: (charA: number, charB: number, paletteDefinition?: PaletteData) => HarmonisedPalette; | ||
| completeFrame: (images: string[][]) => string[][]; | ||
| logPackets: (packets: ParsedPacket[]) => ParsedPacket[]; | ||
| }; | ||
| export { type HarmonisedPalette, type Packet, type PaletteData, type ParsedPacket, type PrintData, type PrintPacket, type TransformedImage, _default as default }; |
| declare enum COMMAND { | ||
| INIT = 1, | ||
| PRINT = 2, | ||
| DATA = 4, | ||
| STATUS = 15, | ||
| TRANSFER = 16 | ||
| } | ||
| type PaletteData = [number, number, number, number]; | ||
| type HarmonisedPalette = [number, number]; | ||
| interface PrintData { | ||
| margins: number; | ||
| marginUpper: number; | ||
| marginLower: number; | ||
| palette: number; | ||
| paletteData: PaletteData; | ||
| } | ||
| interface Packet { | ||
| command: null | COMMAND; | ||
| buffer: number[]; | ||
| data: number[]; | ||
| hasCompression: number; | ||
| dataLength: number; | ||
| checksum?: number; | ||
| } | ||
| type ParsedPacket = Omit<Packet, 'buffer'>; | ||
| interface PrintPacket extends Omit<Packet, 'data'> { | ||
| command: COMMAND.PRINT; | ||
| data: PrintData; | ||
| } | ||
| interface TransformedImage { | ||
| transformed: string[]; | ||
| palette?: PaletteData; | ||
| } | ||
| declare const _default: { | ||
| parsePackets: (bytes: number[]) => ParsedPacket[]; | ||
| parseReducedPackets: (bytes: number[]) => ParsedPacket[]; | ||
| inflateTransferPackages: (packets: ParsedPacket[]) => ParsedPacket[]; | ||
| getImageDataStream: (packets: ParsedPacket[]) => ParsedPacket[]; | ||
| decompressDataStream: (packets: ParsedPacket[]) => ParsedPacket[]; | ||
| decodePrintCommands: (packets: ParsedPacket[]) => (ParsedPacket | PrintPacket)[]; | ||
| harmonizePalettes: (packets: (ParsedPacket | PrintPacket)[]) => (ParsedPacket | PrintPacket)[]; | ||
| transformToClassic: (packets: (ParsedPacket | PrintPacket)[]) => string[][]; | ||
| unpack: (data: number[]) => number[]; | ||
| parsePaletteByte: (paletteRaw: number) => PaletteData; | ||
| harmonizePalette: (charA: number, charB: number, paletteDefinition?: PaletteData) => HarmonisedPalette; | ||
| completeFrame: (images: string[][]) => string[][]; | ||
| logPackets: (packets: ParsedPacket[]) => ParsedPacket[]; | ||
| }; | ||
| export { type HarmonisedPalette, type Packet, type PaletteData, type ParsedPacket, type PrintData, type PrintPacket, type TransformedImage, _default as default }; |
| declare enum COMMAND { | ||
| INIT = 1, | ||
| PRINT = 2, | ||
| DATA = 4, | ||
| STATUS = 15, | ||
| TRANSFER = 16 | ||
| } | ||
| type PaletteData = [number, number, number, number]; | ||
| type HarmonisedPalette = [number, number]; | ||
| interface PrintData { | ||
| margins: number; | ||
| marginUpper: number; | ||
| marginLower: number; | ||
| palette: number; | ||
| paletteData: PaletteData; | ||
| } | ||
| interface Packet { | ||
| command: null | COMMAND; | ||
| buffer: number[]; | ||
| data: number[]; | ||
| hasCompression: number; | ||
| dataLength: number; | ||
| checksum?: number; | ||
| } | ||
| type ParsedPacket = Omit<Packet, 'buffer'>; | ||
| interface PrintPacket extends Omit<Packet, 'data'> { | ||
| command: COMMAND.PRINT; | ||
| data: PrintData; | ||
| } | ||
| interface TransformedImage { | ||
| transformed: string[]; | ||
| palette?: PaletteData; | ||
| } | ||
| declare const _default: { | ||
| parsePackets: (bytes: number[]) => ParsedPacket[]; | ||
| parseReducedPackets: (bytes: number[]) => ParsedPacket[]; | ||
| inflateTransferPackages: (packets: ParsedPacket[]) => ParsedPacket[]; | ||
| getImageDataStream: (packets: ParsedPacket[]) => ParsedPacket[]; | ||
| decompressDataStream: (packets: ParsedPacket[]) => ParsedPacket[]; | ||
| decodePrintCommands: (packets: ParsedPacket[]) => (ParsedPacket | PrintPacket)[]; | ||
| harmonizePalettes: (packets: (ParsedPacket | PrintPacket)[]) => (ParsedPacket | PrintPacket)[]; | ||
| transformToClassic: (packets: (ParsedPacket | PrintPacket)[]) => string[][]; | ||
| unpack: (data: number[]) => number[]; | ||
| parsePaletteByte: (paletteRaw: number) => PaletteData; | ||
| harmonizePalette: (charA: number, charB: number, paletteDefinition?: PaletteData) => HarmonisedPalette; | ||
| completeFrame: (images: string[][]) => string[][]; | ||
| logPackets: (packets: ParsedPacket[]) => ParsedPacket[]; | ||
| }; | ||
| export { type HarmonisedPalette, type Packet, type PaletteData, type ParsedPacket, type PrintData, type PrintPacket, type TransformedImage, _default as default }; |
| import { C as COMMAND, p as parsePackets, b as parseReducedPackets, i as inflateTransferPackages, g as getImageDataStream, d as decompressDataStream, a as decodePrintCommands, h as harmonizePalettes, t as transformToClassic, u as unpack, e as parsePaletteByte, f as harmonizePalette, c as completeFrame } from './shared/gbp-decode.1cf0b17c.mjs'; | ||
| const commandName = (command) => { | ||
| switch (command) { | ||
| case COMMAND.INIT: | ||
| return "INIT"; | ||
| case COMMAND.PRINT: | ||
| return "PRINT"; | ||
| case COMMAND.DATA: | ||
| return "DATA"; | ||
| case COMMAND.STATUS: | ||
| return "STATUS"; | ||
| default: | ||
| return "-"; | ||
| } | ||
| }; | ||
| const logPackets = (packets) => { | ||
| console.log( | ||
| packets.map(({ command, data, hasCompression, dataLength }) => ({ | ||
| command: commandName(command), | ||
| hasCompression: hasCompression ? "yes" : "no", | ||
| dataLength, | ||
| data: data.margins ? `marginUpper: ${data.marginUpper} - marginLower: ${data.marginLower}` : data.slice(0, 20).join(",") | ||
| })) | ||
| ); | ||
| return packets; | ||
| }; | ||
| const main = { | ||
| parsePackets, | ||
| parseReducedPackets, | ||
| inflateTransferPackages, | ||
| getImageDataStream, | ||
| decompressDataStream, | ||
| decodePrintCommands, | ||
| harmonizePalettes, | ||
| transformToClassic, | ||
| unpack, | ||
| parsePaletteByte, | ||
| harmonizePalette, | ||
| completeFrame, | ||
| logPackets | ||
| }; | ||
| export { main as default }; |
| var COMMAND = /* @__PURE__ */ ((COMMAND2) => { | ||
| COMMAND2[COMMAND2["INIT"] = 1] = "INIT"; | ||
| COMMAND2[COMMAND2["PRINT"] = 2] = "PRINT"; | ||
| COMMAND2[COMMAND2["DATA"] = 4] = "DATA"; | ||
| COMMAND2[COMMAND2["STATUS"] = 15] = "STATUS"; | ||
| COMMAND2[COMMAND2["TRANSFER"] = 16] = "TRANSFER"; | ||
| return COMMAND2; | ||
| })(COMMAND || {}); | ||
| var STATE = /* @__PURE__ */ ((STATE2) => { | ||
| STATE2[STATE2["AWAIT_MAGIC_BYTES"] = 0] = "AWAIT_MAGIC_BYTES"; | ||
| STATE2[STATE2["AWAIT_COMMAND"] = 1] = "AWAIT_COMMAND"; | ||
| STATE2[STATE2["AWAIT_COMPRESSION_INFO"] = 2] = "AWAIT_COMPRESSION_INFO"; | ||
| STATE2[STATE2["AWAIT_PACKET_DATA_LENGTH"] = 3] = "AWAIT_PACKET_DATA_LENGTH"; | ||
| STATE2[STATE2["AWAIT_DATA"] = 4] = "AWAIT_DATA"; | ||
| STATE2[STATE2["AWAIT_CHECKSUM"] = 5] = "AWAIT_CHECKSUM"; | ||
| STATE2[STATE2["AWAIT_KEEPALIVE"] = 6] = "AWAIT_KEEPALIVE"; | ||
| STATE2[STATE2["AWAIT_STATUS_QUERY"] = 7] = "AWAIT_STATUS_QUERY"; | ||
| return STATE2; | ||
| })(STATE || {}); | ||
| const EMPTY_PACKET = { | ||
| command: null, | ||
| buffer: [], | ||
| data: [], | ||
| hasCompression: 0, | ||
| dataLength: 0, | ||
| checksum: 0 | ||
| }; | ||
| var DECOMP_MODE = /* @__PURE__ */ ((DECOMP_MODE2) => { | ||
| DECOMP_MODE2[DECOMP_MODE2["DETECT_LENGTH"] = 0] = "DETECT_LENGTH"; | ||
| DECOMP_MODE2[DECOMP_MODE2["COMPRESSED"] = 1] = "COMPRESSED"; | ||
| DECOMP_MODE2[DECOMP_MODE2["UNCOMPRESSED"] = 2] = "UNCOMPRESSED"; | ||
| return DECOMP_MODE2; | ||
| })(DECOMP_MODE || {}); | ||
| const parsePackets = (bytes) => { | ||
| let state = STATE.AWAIT_MAGIC_BYTES; | ||
| let packet = { ...EMPTY_PACKET }; | ||
| const packets = []; | ||
| bytes.forEach((byte) => { | ||
| switch (state) { | ||
| case STATE.AWAIT_MAGIC_BYTES: | ||
| if (packet.buffer.length === 0 && byte === 136) { | ||
| packet.buffer.push(byte); | ||
| return; | ||
| } else if (packet.buffer.length === 1 && byte === 51) { | ||
| packet.buffer = []; | ||
| state = STATE.AWAIT_COMMAND; | ||
| return; | ||
| } else { | ||
| packet = { ...EMPTY_PACKET }; | ||
| return; | ||
| } | ||
| case STATE.AWAIT_COMMAND: | ||
| packet.command = byte; | ||
| state = STATE.AWAIT_COMPRESSION_INFO; | ||
| return; | ||
| case STATE.AWAIT_COMPRESSION_INFO: | ||
| packet.hasCompression = byte; | ||
| state = STATE.AWAIT_PACKET_DATA_LENGTH; | ||
| return; | ||
| case STATE.AWAIT_PACKET_DATA_LENGTH: | ||
| if (packet.buffer.length === 0) { | ||
| packet.buffer.push(byte); | ||
| return; | ||
| } | ||
| packet.dataLength = packet.buffer[0] + (byte << 8); | ||
| packet.buffer = []; | ||
| if (packet.dataLength === 0) { | ||
| state = STATE.AWAIT_CHECKSUM; | ||
| } else { | ||
| state = STATE.AWAIT_DATA; | ||
| } | ||
| return; | ||
| case STATE.AWAIT_DATA: | ||
| if (packet.buffer.length < packet.dataLength) { | ||
| packet.buffer.push(byte); | ||
| return; | ||
| } | ||
| packet.data = packet.buffer; | ||
| packet.buffer = []; | ||
| state = STATE.AWAIT_CHECKSUM; | ||
| return; | ||
| case STATE.AWAIT_CHECKSUM: | ||
| if (packet.buffer.length === 0) { | ||
| packet.buffer.push(byte); | ||
| return; | ||
| } | ||
| packet.checksum = packet.buffer[0] + (byte << 8); | ||
| packet.buffer = []; | ||
| state = STATE.AWAIT_KEEPALIVE; | ||
| return; | ||
| case STATE.AWAIT_KEEPALIVE: | ||
| state = STATE.AWAIT_STATUS_QUERY; | ||
| return; | ||
| case STATE.AWAIT_STATUS_QUERY: | ||
| state = STATE.AWAIT_MAGIC_BYTES; | ||
| packets.push({ | ||
| checksum: packet.checksum, | ||
| command: packet.command, | ||
| data: packet.data, | ||
| dataLength: packet.dataLength, | ||
| hasCompression: packet.hasCompression | ||
| }); | ||
| packet = { ...EMPTY_PACKET }; | ||
| return; | ||
| } | ||
| }); | ||
| return packets; | ||
| }; | ||
| const getImageDataStream = (packets) => { | ||
| return packets.filter(({ command }) => command === COMMAND.DATA || command === COMMAND.PRINT); | ||
| }; | ||
| const unpack = (data) => { | ||
| const dataOut = []; | ||
| let mode = DECOMP_MODE.DETECT_LENGTH; | ||
| let length = 0; | ||
| data.forEach((byte) => { | ||
| switch (mode) { | ||
| case DECOMP_MODE.DETECT_LENGTH: | ||
| if (byte & 128) { | ||
| mode = DECOMP_MODE.COMPRESSED; | ||
| length = (byte & 127) + 2; | ||
| } else { | ||
| mode = DECOMP_MODE.UNCOMPRESSED; | ||
| length = byte + 1; | ||
| } | ||
| return; | ||
| case DECOMP_MODE.UNCOMPRESSED: | ||
| length -= 1; | ||
| if (length === 0) { | ||
| mode = DECOMP_MODE.DETECT_LENGTH; | ||
| } | ||
| dataOut.push(byte); | ||
| return; | ||
| case DECOMP_MODE.COMPRESSED: | ||
| dataOut.push(...[...Array(length)].map(() => byte)); | ||
| mode = DECOMP_MODE.DETECT_LENGTH; | ||
| length = 0; | ||
| return; | ||
| } | ||
| }); | ||
| return dataOut; | ||
| }; | ||
| const decompressDataStream = (packets) => { | ||
| return packets.map((packet) => { | ||
| if (packet.command === COMMAND.DATA) { | ||
| return { | ||
| ...packet, | ||
| hasCompression: 0, | ||
| data: packet.hasCompression ? unpack(packet.data) : packet.data | ||
| }; | ||
| } | ||
| return packet; | ||
| }); | ||
| }; | ||
| const parsePaletteByte = (paletteRaw) => { | ||
| return [ | ||
| paletteRaw >> 6 & 3, | ||
| paletteRaw >> 4 & 3, | ||
| paletteRaw >> 2 & 3, | ||
| paletteRaw >> 0 & 3 | ||
| ]; | ||
| }; | ||
| const decodePrintCommands = (packets) => { | ||
| return packets.map((packet) => { | ||
| if (packet.command === COMMAND.PRINT) { | ||
| const printData = { | ||
| margins: packet.data[1], | ||
| marginUpper: packet.data[1] >> 4, | ||
| marginLower: packet.data[1] & 15, | ||
| palette: packet.data[2], | ||
| paletteData: parsePaletteByte(packet.data[2]) | ||
| }; | ||
| return { | ||
| ...packet, | ||
| data: printData | ||
| }; | ||
| } | ||
| return packet; | ||
| }); | ||
| }; | ||
| const harmonizePalette = (charA, charB, paletteDefinition = [3, 2, 1, 0]) => { | ||
| const bits = [...Array(8)].map((_, index) => ({ | ||
| a: (charB >> 7 - index) % 2, | ||
| b: (charA >> 7 - index) % 2 | ||
| })); | ||
| const res = bits.map(({ a, b }) => (a << 1) + b).map((val) => paletteDefinition[3 - val]).map((mapped) => ({ | ||
| a: (mapped >> 1) % 2, | ||
| b: mapped % 2 | ||
| })).reduce((acc, current, index) => ({ | ||
| a: acc.a + (current.a << 7 - index), | ||
| b: acc.b + (current.b << 7 - index) | ||
| }), { | ||
| a: 0, | ||
| b: 0 | ||
| }); | ||
| return [ | ||
| res.b & 255, | ||
| res.a & 255 | ||
| ]; | ||
| }; | ||
| const harmonizePalettes = (packets) => { | ||
| let unharmonizedPackets = []; | ||
| return packets.map((packet) => { | ||
| switch (packet.command) { | ||
| case COMMAND.DATA: | ||
| unharmonizedPackets.push(packet); | ||
| break; | ||
| case COMMAND.PRINT: | ||
| if (packet.data.palette === 0) { | ||
| unharmonizedPackets = []; | ||
| break; | ||
| } | ||
| while (unharmonizedPackets.length) { | ||
| let unharmonizedPacket = unharmonizedPackets.shift(); | ||
| const data = []; | ||
| if (!unharmonizedPacket) { | ||
| throw Error("error harmonizing"); | ||
| } | ||
| for (let i = 0; i < unharmonizedPacket.data.length; i += 2) { | ||
| data.push( | ||
| ...harmonizePalette( | ||
| unharmonizedPacket.data[i], | ||
| unharmonizedPacket.data[i + 1], | ||
| packet.data.paletteData | ||
| ) | ||
| ); | ||
| } | ||
| Object.assign(unharmonizedPacket, { data }); | ||
| } | ||
| break; | ||
| } | ||
| return packet; | ||
| }); | ||
| }; | ||
| const transformToClassic = (packets) => { | ||
| let image = { | ||
| transformed: [] | ||
| }; | ||
| let currentLine = []; | ||
| const images = []; | ||
| packets.forEach((packet) => { | ||
| switch (packet.command) { | ||
| case COMMAND.DATA: | ||
| for (let i = 0; i < packet.data.length; i += 1) { | ||
| currentLine.push(packet.data[i].toString(16).padStart(2, "0")); | ||
| if (i % 16 === 15) { | ||
| image.transformed.push(currentLine.join(" ")); | ||
| currentLine = []; | ||
| } | ||
| } | ||
| break; | ||
| case COMMAND.PRINT: | ||
| image.palette = packet.data.paletteData || image.palette; | ||
| if (packet.data.marginLower !== 0) { | ||
| images.push(image.transformed); | ||
| image = { | ||
| transformed: [] | ||
| }; | ||
| currentLine = []; | ||
| } | ||
| break; | ||
| } | ||
| }); | ||
| if (image.transformed.length) { | ||
| images.push(image.transformed); | ||
| } | ||
| return images; | ||
| }; | ||
| const parseReducedPackets = (bytes) => { | ||
| let state = STATE.AWAIT_COMMAND; | ||
| let packet = { | ||
| command: null, | ||
| buffer: [], | ||
| data: [], | ||
| hasCompression: 0, | ||
| dataLength: 0 | ||
| }; | ||
| const packets = []; | ||
| const nextPacket = () => { | ||
| packets.push({ | ||
| command: packet.command, | ||
| data: packet.data, | ||
| dataLength: packet.dataLength, | ||
| hasCompression: packet.hasCompression | ||
| }); | ||
| packet = { | ||
| command: null, | ||
| buffer: [], | ||
| data: [], | ||
| hasCompression: 0, | ||
| dataLength: 0 | ||
| }; | ||
| state = STATE.AWAIT_COMMAND; | ||
| }; | ||
| bytes.forEach((byte, index) => { | ||
| switch (state) { | ||
| case STATE.AWAIT_COMMAND: | ||
| packet.command = byte; | ||
| switch (packet.command) { | ||
| case COMMAND.INIT: | ||
| nextPacket(); | ||
| return; | ||
| case COMMAND.DATA: | ||
| state = STATE.AWAIT_COMPRESSION_INFO; | ||
| return; | ||
| case COMMAND.PRINT: | ||
| state = STATE.AWAIT_PACKET_DATA_LENGTH; | ||
| return; | ||
| case COMMAND.TRANSFER: | ||
| state = STATE.AWAIT_PACKET_DATA_LENGTH; | ||
| return; | ||
| default: | ||
| throw new Error(`Unknown packet command: 0x${packet.command.toString(16)} at index ${index}`); | ||
| } | ||
| case STATE.AWAIT_COMPRESSION_INFO: | ||
| packet.hasCompression = byte; | ||
| state = STATE.AWAIT_PACKET_DATA_LENGTH; | ||
| return; | ||
| case STATE.AWAIT_PACKET_DATA_LENGTH: | ||
| if (packet.buffer.length === 0) { | ||
| packet.buffer.push(byte); | ||
| return; | ||
| } | ||
| packet.dataLength = packet.buffer[0] + (byte << 8); | ||
| packet.buffer = []; | ||
| if (packet.dataLength === 0) { | ||
| state = STATE.AWAIT_COMMAND; | ||
| nextPacket(); | ||
| return; | ||
| } | ||
| state = STATE.AWAIT_DATA; | ||
| return; | ||
| case STATE.AWAIT_DATA: | ||
| packet.buffer.push(byte); | ||
| if (packet.buffer.length === packet.dataLength) { | ||
| packet.data = packet.buffer; | ||
| state = STATE.AWAIT_COMMAND; | ||
| if (packet.command === COMMAND.TRANSFER) { | ||
| nextPacket(); | ||
| packet = { | ||
| buffer: [], | ||
| command: COMMAND.PRINT, | ||
| data: [1, 3, 228, 127], | ||
| hasCompression: 0, | ||
| dataLength: 4 | ||
| }; | ||
| } | ||
| nextPacket(); | ||
| } | ||
| break; | ||
| } | ||
| }); | ||
| return packets; | ||
| }; | ||
| const twoTiles = new Array(2 * 16).fill(0); | ||
| const inflate = (arr) => { | ||
| const chunks = []; | ||
| let i = 0; | ||
| const n = arr.length; | ||
| while (i < n) { | ||
| chunks.push(...twoTiles, ...arr.slice(i, i += 256), ...twoTiles); | ||
| } | ||
| return chunks; | ||
| }; | ||
| const inflateTransferPackages = (packets) => packets.map((packet) => { | ||
| if (packet.command !== COMMAND.TRANSFER) { | ||
| return packet; | ||
| } | ||
| return { | ||
| ...packet, | ||
| command: COMMAND.DATA, | ||
| data: inflate(packet.data) | ||
| }; | ||
| }); | ||
| const fourtyLines = new Array(40).fill("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"); | ||
| const completeFrame = (images) => images.map((image) => { | ||
| if (image.length !== 280) { | ||
| return image; | ||
| } | ||
| return [ | ||
| ...fourtyLines, | ||
| ...image, | ||
| ...fourtyLines | ||
| ]; | ||
| }); | ||
| export { COMMAND as C, decodePrintCommands as a, parseReducedPackets as b, completeFrame as c, decompressDataStream as d, parsePaletteByte as e, harmonizePalette as f, getImageDataStream as g, harmonizePalettes as h, inflateTransferPackages as i, parsePackets as p, transformToClassic as t, unpack as u }; |
| 'use strict'; | ||
| var COMMAND = /* @__PURE__ */ ((COMMAND2) => { | ||
| COMMAND2[COMMAND2["INIT"] = 1] = "INIT"; | ||
| COMMAND2[COMMAND2["PRINT"] = 2] = "PRINT"; | ||
| COMMAND2[COMMAND2["DATA"] = 4] = "DATA"; | ||
| COMMAND2[COMMAND2["STATUS"] = 15] = "STATUS"; | ||
| COMMAND2[COMMAND2["TRANSFER"] = 16] = "TRANSFER"; | ||
| return COMMAND2; | ||
| })(COMMAND || {}); | ||
| var STATE = /* @__PURE__ */ ((STATE2) => { | ||
| STATE2[STATE2["AWAIT_MAGIC_BYTES"] = 0] = "AWAIT_MAGIC_BYTES"; | ||
| STATE2[STATE2["AWAIT_COMMAND"] = 1] = "AWAIT_COMMAND"; | ||
| STATE2[STATE2["AWAIT_COMPRESSION_INFO"] = 2] = "AWAIT_COMPRESSION_INFO"; | ||
| STATE2[STATE2["AWAIT_PACKET_DATA_LENGTH"] = 3] = "AWAIT_PACKET_DATA_LENGTH"; | ||
| STATE2[STATE2["AWAIT_DATA"] = 4] = "AWAIT_DATA"; | ||
| STATE2[STATE2["AWAIT_CHECKSUM"] = 5] = "AWAIT_CHECKSUM"; | ||
| STATE2[STATE2["AWAIT_KEEPALIVE"] = 6] = "AWAIT_KEEPALIVE"; | ||
| STATE2[STATE2["AWAIT_STATUS_QUERY"] = 7] = "AWAIT_STATUS_QUERY"; | ||
| return STATE2; | ||
| })(STATE || {}); | ||
| const EMPTY_PACKET = { | ||
| command: null, | ||
| buffer: [], | ||
| data: [], | ||
| hasCompression: 0, | ||
| dataLength: 0, | ||
| checksum: 0 | ||
| }; | ||
| var DECOMP_MODE = /* @__PURE__ */ ((DECOMP_MODE2) => { | ||
| DECOMP_MODE2[DECOMP_MODE2["DETECT_LENGTH"] = 0] = "DETECT_LENGTH"; | ||
| DECOMP_MODE2[DECOMP_MODE2["COMPRESSED"] = 1] = "COMPRESSED"; | ||
| DECOMP_MODE2[DECOMP_MODE2["UNCOMPRESSED"] = 2] = "UNCOMPRESSED"; | ||
| return DECOMP_MODE2; | ||
| })(DECOMP_MODE || {}); | ||
| const parsePackets = (bytes) => { | ||
| let state = STATE.AWAIT_MAGIC_BYTES; | ||
| let packet = { ...EMPTY_PACKET }; | ||
| const packets = []; | ||
| bytes.forEach((byte) => { | ||
| switch (state) { | ||
| case STATE.AWAIT_MAGIC_BYTES: | ||
| if (packet.buffer.length === 0 && byte === 136) { | ||
| packet.buffer.push(byte); | ||
| return; | ||
| } else if (packet.buffer.length === 1 && byte === 51) { | ||
| packet.buffer = []; | ||
| state = STATE.AWAIT_COMMAND; | ||
| return; | ||
| } else { | ||
| packet = { ...EMPTY_PACKET }; | ||
| return; | ||
| } | ||
| case STATE.AWAIT_COMMAND: | ||
| packet.command = byte; | ||
| state = STATE.AWAIT_COMPRESSION_INFO; | ||
| return; | ||
| case STATE.AWAIT_COMPRESSION_INFO: | ||
| packet.hasCompression = byte; | ||
| state = STATE.AWAIT_PACKET_DATA_LENGTH; | ||
| return; | ||
| case STATE.AWAIT_PACKET_DATA_LENGTH: | ||
| if (packet.buffer.length === 0) { | ||
| packet.buffer.push(byte); | ||
| return; | ||
| } | ||
| packet.dataLength = packet.buffer[0] + (byte << 8); | ||
| packet.buffer = []; | ||
| if (packet.dataLength === 0) { | ||
| state = STATE.AWAIT_CHECKSUM; | ||
| } else { | ||
| state = STATE.AWAIT_DATA; | ||
| } | ||
| return; | ||
| case STATE.AWAIT_DATA: | ||
| if (packet.buffer.length < packet.dataLength) { | ||
| packet.buffer.push(byte); | ||
| return; | ||
| } | ||
| packet.data = packet.buffer; | ||
| packet.buffer = []; | ||
| state = STATE.AWAIT_CHECKSUM; | ||
| return; | ||
| case STATE.AWAIT_CHECKSUM: | ||
| if (packet.buffer.length === 0) { | ||
| packet.buffer.push(byte); | ||
| return; | ||
| } | ||
| packet.checksum = packet.buffer[0] + (byte << 8); | ||
| packet.buffer = []; | ||
| state = STATE.AWAIT_KEEPALIVE; | ||
| return; | ||
| case STATE.AWAIT_KEEPALIVE: | ||
| state = STATE.AWAIT_STATUS_QUERY; | ||
| return; | ||
| case STATE.AWAIT_STATUS_QUERY: | ||
| state = STATE.AWAIT_MAGIC_BYTES; | ||
| packets.push({ | ||
| checksum: packet.checksum, | ||
| command: packet.command, | ||
| data: packet.data, | ||
| dataLength: packet.dataLength, | ||
| hasCompression: packet.hasCompression | ||
| }); | ||
| packet = { ...EMPTY_PACKET }; | ||
| return; | ||
| } | ||
| }); | ||
| return packets; | ||
| }; | ||
| const getImageDataStream = (packets) => { | ||
| return packets.filter(({ command }) => command === COMMAND.DATA || command === COMMAND.PRINT); | ||
| }; | ||
| const unpack = (data) => { | ||
| const dataOut = []; | ||
| let mode = DECOMP_MODE.DETECT_LENGTH; | ||
| let length = 0; | ||
| data.forEach((byte) => { | ||
| switch (mode) { | ||
| case DECOMP_MODE.DETECT_LENGTH: | ||
| if (byte & 128) { | ||
| mode = DECOMP_MODE.COMPRESSED; | ||
| length = (byte & 127) + 2; | ||
| } else { | ||
| mode = DECOMP_MODE.UNCOMPRESSED; | ||
| length = byte + 1; | ||
| } | ||
| return; | ||
| case DECOMP_MODE.UNCOMPRESSED: | ||
| length -= 1; | ||
| if (length === 0) { | ||
| mode = DECOMP_MODE.DETECT_LENGTH; | ||
| } | ||
| dataOut.push(byte); | ||
| return; | ||
| case DECOMP_MODE.COMPRESSED: | ||
| dataOut.push(...[...Array(length)].map(() => byte)); | ||
| mode = DECOMP_MODE.DETECT_LENGTH; | ||
| length = 0; | ||
| return; | ||
| } | ||
| }); | ||
| return dataOut; | ||
| }; | ||
| const decompressDataStream = (packets) => { | ||
| return packets.map((packet) => { | ||
| if (packet.command === COMMAND.DATA) { | ||
| return { | ||
| ...packet, | ||
| hasCompression: 0, | ||
| data: packet.hasCompression ? unpack(packet.data) : packet.data | ||
| }; | ||
| } | ||
| return packet; | ||
| }); | ||
| }; | ||
| const parsePaletteByte = (paletteRaw) => { | ||
| return [ | ||
| paletteRaw >> 6 & 3, | ||
| paletteRaw >> 4 & 3, | ||
| paletteRaw >> 2 & 3, | ||
| paletteRaw >> 0 & 3 | ||
| ]; | ||
| }; | ||
| const decodePrintCommands = (packets) => { | ||
| return packets.map((packet) => { | ||
| if (packet.command === COMMAND.PRINT) { | ||
| const printData = { | ||
| margins: packet.data[1], | ||
| marginUpper: packet.data[1] >> 4, | ||
| marginLower: packet.data[1] & 15, | ||
| palette: packet.data[2], | ||
| paletteData: parsePaletteByte(packet.data[2]) | ||
| }; | ||
| return { | ||
| ...packet, | ||
| data: printData | ||
| }; | ||
| } | ||
| return packet; | ||
| }); | ||
| }; | ||
| const harmonizePalette = (charA, charB, paletteDefinition = [3, 2, 1, 0]) => { | ||
| const bits = [...Array(8)].map((_, index) => ({ | ||
| a: (charB >> 7 - index) % 2, | ||
| b: (charA >> 7 - index) % 2 | ||
| })); | ||
| const res = bits.map(({ a, b }) => (a << 1) + b).map((val) => paletteDefinition[3 - val]).map((mapped) => ({ | ||
| a: (mapped >> 1) % 2, | ||
| b: mapped % 2 | ||
| })).reduce((acc, current, index) => ({ | ||
| a: acc.a + (current.a << 7 - index), | ||
| b: acc.b + (current.b << 7 - index) | ||
| }), { | ||
| a: 0, | ||
| b: 0 | ||
| }); | ||
| return [ | ||
| res.b & 255, | ||
| res.a & 255 | ||
| ]; | ||
| }; | ||
| const harmonizePalettes = (packets) => { | ||
| let unharmonizedPackets = []; | ||
| return packets.map((packet) => { | ||
| switch (packet.command) { | ||
| case COMMAND.DATA: | ||
| unharmonizedPackets.push(packet); | ||
| break; | ||
| case COMMAND.PRINT: | ||
| if (packet.data.palette === 0) { | ||
| unharmonizedPackets = []; | ||
| break; | ||
| } | ||
| while (unharmonizedPackets.length) { | ||
| let unharmonizedPacket = unharmonizedPackets.shift(); | ||
| const data = []; | ||
| if (!unharmonizedPacket) { | ||
| throw Error("error harmonizing"); | ||
| } | ||
| for (let i = 0; i < unharmonizedPacket.data.length; i += 2) { | ||
| data.push( | ||
| ...harmonizePalette( | ||
| unharmonizedPacket.data[i], | ||
| unharmonizedPacket.data[i + 1], | ||
| packet.data.paletteData | ||
| ) | ||
| ); | ||
| } | ||
| Object.assign(unharmonizedPacket, { data }); | ||
| } | ||
| break; | ||
| } | ||
| return packet; | ||
| }); | ||
| }; | ||
| const transformToClassic = (packets) => { | ||
| let image = { | ||
| transformed: [] | ||
| }; | ||
| let currentLine = []; | ||
| const images = []; | ||
| packets.forEach((packet) => { | ||
| switch (packet.command) { | ||
| case COMMAND.DATA: | ||
| for (let i = 0; i < packet.data.length; i += 1) { | ||
| currentLine.push(packet.data[i].toString(16).padStart(2, "0")); | ||
| if (i % 16 === 15) { | ||
| image.transformed.push(currentLine.join(" ")); | ||
| currentLine = []; | ||
| } | ||
| } | ||
| break; | ||
| case COMMAND.PRINT: | ||
| image.palette = packet.data.paletteData || image.palette; | ||
| if (packet.data.marginLower !== 0) { | ||
| images.push(image.transformed); | ||
| image = { | ||
| transformed: [] | ||
| }; | ||
| currentLine = []; | ||
| } | ||
| break; | ||
| } | ||
| }); | ||
| if (image.transformed.length) { | ||
| images.push(image.transformed); | ||
| } | ||
| return images; | ||
| }; | ||
| const parseReducedPackets = (bytes) => { | ||
| let state = STATE.AWAIT_COMMAND; | ||
| let packet = { | ||
| command: null, | ||
| buffer: [], | ||
| data: [], | ||
| hasCompression: 0, | ||
| dataLength: 0 | ||
| }; | ||
| const packets = []; | ||
| const nextPacket = () => { | ||
| packets.push({ | ||
| command: packet.command, | ||
| data: packet.data, | ||
| dataLength: packet.dataLength, | ||
| hasCompression: packet.hasCompression | ||
| }); | ||
| packet = { | ||
| command: null, | ||
| buffer: [], | ||
| data: [], | ||
| hasCompression: 0, | ||
| dataLength: 0 | ||
| }; | ||
| state = STATE.AWAIT_COMMAND; | ||
| }; | ||
| bytes.forEach((byte, index) => { | ||
| switch (state) { | ||
| case STATE.AWAIT_COMMAND: | ||
| packet.command = byte; | ||
| switch (packet.command) { | ||
| case COMMAND.INIT: | ||
| nextPacket(); | ||
| return; | ||
| case COMMAND.DATA: | ||
| state = STATE.AWAIT_COMPRESSION_INFO; | ||
| return; | ||
| case COMMAND.PRINT: | ||
| state = STATE.AWAIT_PACKET_DATA_LENGTH; | ||
| return; | ||
| case COMMAND.TRANSFER: | ||
| state = STATE.AWAIT_PACKET_DATA_LENGTH; | ||
| return; | ||
| default: | ||
| throw new Error(`Unknown packet command: 0x${packet.command.toString(16)} at index ${index}`); | ||
| } | ||
| case STATE.AWAIT_COMPRESSION_INFO: | ||
| packet.hasCompression = byte; | ||
| state = STATE.AWAIT_PACKET_DATA_LENGTH; | ||
| return; | ||
| case STATE.AWAIT_PACKET_DATA_LENGTH: | ||
| if (packet.buffer.length === 0) { | ||
| packet.buffer.push(byte); | ||
| return; | ||
| } | ||
| packet.dataLength = packet.buffer[0] + (byte << 8); | ||
| packet.buffer = []; | ||
| if (packet.dataLength === 0) { | ||
| state = STATE.AWAIT_COMMAND; | ||
| nextPacket(); | ||
| return; | ||
| } | ||
| state = STATE.AWAIT_DATA; | ||
| return; | ||
| case STATE.AWAIT_DATA: | ||
| packet.buffer.push(byte); | ||
| if (packet.buffer.length === packet.dataLength) { | ||
| packet.data = packet.buffer; | ||
| state = STATE.AWAIT_COMMAND; | ||
| if (packet.command === COMMAND.TRANSFER) { | ||
| nextPacket(); | ||
| packet = { | ||
| buffer: [], | ||
| command: COMMAND.PRINT, | ||
| data: [1, 3, 228, 127], | ||
| hasCompression: 0, | ||
| dataLength: 4 | ||
| }; | ||
| } | ||
| nextPacket(); | ||
| } | ||
| break; | ||
| } | ||
| }); | ||
| return packets; | ||
| }; | ||
| const twoTiles = new Array(2 * 16).fill(0); | ||
| const inflate = (arr) => { | ||
| const chunks = []; | ||
| let i = 0; | ||
| const n = arr.length; | ||
| while (i < n) { | ||
| chunks.push(...twoTiles, ...arr.slice(i, i += 256), ...twoTiles); | ||
| } | ||
| return chunks; | ||
| }; | ||
| const inflateTransferPackages = (packets) => packets.map((packet) => { | ||
| if (packet.command !== COMMAND.TRANSFER) { | ||
| return packet; | ||
| } | ||
| return { | ||
| ...packet, | ||
| command: COMMAND.DATA, | ||
| data: inflate(packet.data) | ||
| }; | ||
| }); | ||
| const fourtyLines = new Array(40).fill("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"); | ||
| const completeFrame = (images) => images.map((image) => { | ||
| if (image.length !== 280) { | ||
| return image; | ||
| } | ||
| return [ | ||
| ...fourtyLines, | ||
| ...image, | ||
| ...fourtyLines | ||
| ]; | ||
| }); | ||
| exports.COMMAND = COMMAND; | ||
| exports.completeFrame = completeFrame; | ||
| exports.decodePrintCommands = decodePrintCommands; | ||
| exports.decompressDataStream = decompressDataStream; | ||
| exports.getImageDataStream = getImageDataStream; | ||
| exports.harmonizePalette = harmonizePalette; | ||
| exports.harmonizePalettes = harmonizePalettes; | ||
| exports.inflateTransferPackages = inflateTransferPackages; | ||
| exports.parsePackets = parsePackets; | ||
| exports.parsePaletteByte = parsePaletteByte; | ||
| exports.parseReducedPackets = parseReducedPackets; | ||
| exports.transformToClassic = transformToClassic; | ||
| exports.unpack = unpack; |
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
6579
-82.67%2
-77.78%0
-100%2
Infinity%