From 4165aefde6b3ccc50ccd26d1cd7522a3091548d9 Mon Sep 17 00:00:00 2001 From: Julian Waller Date: Sat, 17 Feb 2024 19:26:07 +0000 Subject: [PATCH] wip --- packages/core/src/models/base-gen1.ts | 12 +++--- packages/core/src/models/base-gen2.ts | 8 ++-- packages/core/src/models/base.ts | 12 ++++-- packages/core/src/models/pedal.ts | 4 +- packages/core/src/util.ts | 59 +++++++++++++++------------ packages/node/src/jpeg.ts | 2 +- 6 files changed, 54 insertions(+), 43 deletions(-) diff --git a/packages/core/src/models/base-gen1.ts b/packages/core/src/models/base-gen1.ts index b11515d..b521008 100644 --- a/packages/core/src/models/base-gen1.ts +++ b/packages/core/src/models/base-gen1.ts @@ -33,7 +33,7 @@ export abstract class StreamDeckGen1Base extends StreamDeckBase { } // prettier-ignore - const brightnessCommandBuffer = Buffer.from([ + const brightnessCommandBuffer = Uint8Array.from([ 0x05, 0x55, 0xaa, 0xd1, 0x01, percentage, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 @@ -43,7 +43,7 @@ export abstract class StreamDeckGen1Base extends StreamDeckBase { public async resetToLogo(): Promise { // prettier-ignore - const resetCommandBuffer = Buffer.from([ + const resetCommandBuffer = Uint8Array.from([ 0x0b, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 @@ -52,7 +52,7 @@ export abstract class StreamDeckGen1Base extends StreamDeckBase { } public async getFirmwareVersion(): Promise { - let val: Buffer + let val: Uint8Array try { val = await this.device.getFeatureReport(4, 32) } catch (e) { @@ -60,17 +60,17 @@ export abstract class StreamDeckGen1Base extends StreamDeckBase { val = await this.device.getFeatureReport(4, 17) } const end = val.indexOf(0, 5) - return val.toString('ascii', 5, end === -1 ? undefined : end) + return new TextDecoder('ascii').decode(val.subarray(5, end === -1 ? undefined : end)) } public async getSerialNumber(): Promise { - let val: Buffer + let val: Uint8Array try { val = await this.device.getFeatureReport(3, 32) } catch (e) { // In case some devices can't handle the different report length val = await this.device.getFeatureReport(3, 17) } - return val.toString('ascii', 5, 17) + return new TextDecoder('ascii').decode(val.subarray(5, 17)) } } diff --git a/packages/core/src/models/base-gen2.ts b/packages/core/src/models/base-gen2.ts index ec19119..04d1a89 100644 --- a/packages/core/src/models/base-gen2.ts +++ b/packages/core/src/models/base-gen2.ts @@ -64,14 +64,14 @@ export abstract class StreamDeckGen2Base extends StreamDeckBase { public async getFirmwareVersion(): Promise { const val = await this.device.getFeatureReport(5, 32) - const end = val.readUInt8(1) + 2 - return val.toString('ascii', 6, end) + const end = val[1] + 2 + return new TextDecoder('ascii').decode(val.subarray(6, end)) } public async getSerialNumber(): Promise { const val = await this.device.getFeatureReport(6, 32) - const end = val.readUInt8(1) + 2 - return val.toString('ascii', 2, end) + const end = val[1] + 2 + return new TextDecoder('ascii').decode(val.subarray(2, end)) } protected async convertFillImage( diff --git a/packages/core/src/models/base.ts b/packages/core/src/models/base.ts index 4229e91..e5faccf 100644 --- a/packages/core/src/models/base.ts +++ b/packages/core/src/models/base.ts @@ -206,7 +206,9 @@ export abstract class StreamDeckBase extends StreamDeckInputBase { if (keyIndex >= this.NUM_KEYS) { await this.device.sendFeatureReport(Buffer.from([0x03, 0x06, keyIndex, r, g, b])) } else { - const pixels = Buffer.alloc(this.ICON_BYTES, Buffer.from([r, g, b])) + const pixels = new Uint8Array(this.ICON_BYTES) + pixels.fill([r, g, b]) + const keyIndex2 = this.transformKeyIndex(keyIndex) await this.fillImageRange(keyIndex2, pixels, { format: 'rgb', @@ -279,7 +281,9 @@ export abstract class StreamDeckBase extends StreamDeckInputBase { if (keyIndex >= this.NUM_KEYS) { await this.device.sendFeatureReport(Buffer.from([0x03, 0x06, keyIndex, 0, 0, 0])) } else { - const pixels = Buffer.alloc(this.ICON_BYTES, 0) + const pixels = new Uint8Array(this.ICON_BYTES) + pixels.fill(0) + const keyIndex2 = this.transformKeyIndex(keyIndex) await this.fillImageRange(keyIndex2, pixels, { format: 'rgb', @@ -290,7 +294,9 @@ export abstract class StreamDeckBase extends StreamDeckInputBase { } public async clearPanel(): Promise { - const pixels = Buffer.alloc(this.ICON_BYTES, 0) + const pixels = new Uint8Array(this.ICON_BYTES) + pixels.fill(0) + const ps: Array> = [] for (let keyIndex = 0; keyIndex < this.NUM_KEYS; keyIndex++) { ps.push( diff --git a/packages/core/src/models/pedal.ts b/packages/core/src/models/pedal.ts index a0a3f25..9e4d782 100644 --- a/packages/core/src/models/pedal.ts +++ b/packages/core/src/models/pedal.ts @@ -38,12 +38,12 @@ export class StreamDeckPedal extends StreamDeckInputBase { public async getFirmwareVersion(): Promise { const val = await this.device.getFeatureReport(5, 32) const end = val.indexOf(0, 6) - return val.toString('ascii', 6, end === -1 ? undefined : end) + return new TextDecoder('ascii').decode(val.subarray(6, end === -1 ? undefined : end)) } public async getSerialNumber(): Promise { const val = await this.device.getFeatureReport(6, 32) - return val.toString('ascii', 2, 14) + return new TextDecoder('ascii').decode(val.subarray(2, 14)) } public async fillKeyColor(_keyIndex: number, _r: number, _g: number, _b: number): Promise { diff --git a/packages/core/src/util.ts b/packages/core/src/util.ts index 50665e3..086a41f 100644 --- a/packages/core/src/util.ts +++ b/packages/core/src/util.ts @@ -17,7 +17,10 @@ export function transformImageBuffer( ): Uint8Array { if (!imageHeight) imageHeight = imageWidth - const byteBuffer = Buffer.alloc(destPadding + imageWidth * imageHeight * targetOptions.colorMode.length) + const imageBufferView = new DataView(imageBuffer) + + const byteBuffer = new Uint8Array(destPadding + imageWidth * imageHeight * targetOptions.colorMode.length) + const byteBufferView = new DataView(byteBuffer) const flipColours = sourceOptions.format.substring(0, 3) !== targetOptions.colorMode.substring(0, 3) @@ -37,22 +40,22 @@ export function transformImageBuffer( const srcOffset = y2 * sourceOptions.stride + sourceOptions.offset + x2 * sourceOptions.format.length - const red = imageBuffer[srcOffset] - const green = imageBuffer[srcOffset + 1] - const blue = imageBuffer[srcOffset + 2] + const red = imageBufferView.getUint8(srcOffset) + const green = imageBufferView.getUint8(srcOffset + 1) + const blue = imageBufferView.getUint8(srcOffset + 2) const targetOffset = rowOffset + x * targetOptions.colorMode.length if (flipColours) { - byteBuffer.writeUInt8(blue, targetOffset) - byteBuffer.writeUInt8(green, targetOffset + 1) - byteBuffer.writeUInt8(red, targetOffset + 2) + byteBufferView.setUint8(targetOffset, blue) + byteBufferView.setUint8(targetOffset + 1, green) + byteBufferView.setUint8(targetOffset + 2, red) } else { - byteBuffer.writeUInt8(red, targetOffset) - byteBuffer.writeUInt8(green, targetOffset + 1) - byteBuffer.writeUInt8(blue, targetOffset + 2) + byteBufferView.setUint8(targetOffset, red) + byteBufferView.setUint8(targetOffset + 1, green) + byteBufferView.setUint8(targetOffset + 2, blue) } if (targetOptions.colorMode.length === 4) { - byteBuffer.writeUInt8(255, targetOffset + 3) + byteBufferView.setUint8(targetOffset + 3, 255) } } } @@ -62,25 +65,27 @@ export function transformImageBuffer( export const BMP_HEADER_LENGTH = 54 export function writeBMPHeader(buf: Uint8Array, iconSize: number, iconBytes: number, imagePPM: number): void { + const bufView = new DataView(buf) // Uses header format BITMAPINFOHEADER https://en.wikipedia.org/wiki/BMP_file_format // Bitmap file header - buf.write('BM') - buf.writeUInt32LE(iconBytes + 54, 2) - buf.writeInt16LE(0, 6) - buf.writeInt16LE(0, 8) - buf.writeUInt32LE(54, 10) // Full header size + bufView.setUint8(0, 0x42) // B + bufView.setUint8(1, 0x4d) // M + bufView.setUint32(2, iconBytes + 54, true) + bufView.setInt16(6, 0, true) + bufView.setInt16(8, 0, true) + bufView.setUint32(10, 54, true) // Full header size // DIB header (BITMAPINFOHEADER) - buf.writeUInt32LE(40, 14) // DIB header size - buf.writeInt32LE(iconSize, 18) - buf.writeInt32LE(iconSize, 22) - buf.writeInt16LE(1, 26) // Color planes - buf.writeInt16LE(24, 28) // Bit depth - buf.writeInt32LE(0, 30) // Compression - buf.writeInt32LE(iconBytes, 34) // Image size - buf.writeInt32LE(imagePPM, 38) // Horizontal resolution ppm - buf.writeInt32LE(imagePPM, 42) // Vertical resolution ppm - buf.writeInt32LE(0, 46) // Colour pallette size - buf.writeInt32LE(0, 50) // 'Important' Colour count + bufView.setUint32(14, 40, true) // DIB header size + bufView.setInt32(18, iconSize, true) + bufView.setInt32(22, iconSize, true) + bufView.setInt16(26, 1, true) // Color planes + bufView.setInt16(28, 24, true) // Bit depth + bufView.setInt32(30, 0, true) // Compression + bufView.setInt32(34, iconBytes, true) // Image size + bufView.setInt32(38, imagePPM, true) // Horizontal resolution ppm + bufView.setInt32(42, imagePPM, true) // Vertical resolution ppm + bufView.setInt32(46, 0, true) // Colour pallette size + bufView.setInt32(50, 0, true) // 'Important' Colour count } diff --git a/packages/node/src/jpeg.ts b/packages/node/src/jpeg.ts index 3fe5d3d..d3af028 100644 --- a/packages/node/src/jpeg.ts +++ b/packages/node/src/jpeg.ts @@ -41,7 +41,7 @@ export async function encodeJPEG( } if (buffer.length === width * height * 4) { const tmpBuffer = Buffer.alloc(jpegTurbo.bufferSize(encodeOptions)) - return jpegTurbo.compress(buffer, tmpBuffer, encodeOptions) + return jpegTurbo.compress(Buffer.from(buffer.buffer), tmpBuffer, encodeOptions) } } } catch (e) {