feat: switch to array buffer

This commit is contained in:
TrèsAbhi committed 2024-02-07 10:34:13 -06:00
1 parent 9cfa2357b0
commit cb2846a256
7 files changed
+45 -53

No files matched your search

+1 -1
View File
@@ -3,6 +3,6 @@ import { CdonWriteStream } from '../streams/cdon';
export function superCompress(object: any) { export function superCompress(object: any) {
const write = new CdonWriteStream().cdon(object); const write = new CdonWriteStream().cdon(object);
const compressed = compress(write.buffer); const compressed = compress(write.uint8Array);
return Buffer.from(compressed).toString('base64'); return Buffer.from(compressed).toString('base64');
} }
+30 -34
View File
@@ -1,19 +1,27 @@
export class ReadStream { export class ReadStream {
public index = 0; public index = 0;
constructor(public buffer: Buffer) {} private dataView: DataView;
private textDecoderAscii = new TextDecoder('ascii');
private textDecoderUtf8 = new TextDecoder('utf8');
skip(size: number) { constructor(public buffer: ArrayBuffer) {
this.dataView = new DataView(buffer);
}
seek(size: number) {
this.index += size; this.index += size;
} }
read(size: number) { read(size: number) {
return this.buffer.subarray(this.index, this.index + size); return this.buffer.slice(this.index, this.index + size);
} }
consume(size: number) { consume(size: number) {
const subarray = this.read(size); const subarray = this.read(size);
this.skip(size); this.seek(size);
return subarray; return subarray;
} }
consumeUint8Array(size: number) {
return new Uint8Array(this.consume(size));
}
increment(size: number) { increment(size: number) {
return (this.index += size) - size; return (this.index += size) - size;
} }
@@ -21,9 +29,6 @@ export class ReadStream {
readRemaining() { readRemaining() {
return this.read(Number.POSITIVE_INFINITY); return this.read(Number.POSITIVE_INFINITY);
} }
readRemainingLength() {
return this.buffer.length - this.index;
}
consumeRemaining() { consumeRemaining() {
return this.consume(Number.POSITIVE_INFINITY); return this.consume(Number.POSITIVE_INFINITY);
} }
@@ -33,57 +38,54 @@ export class ReadStream {
} }
ascii(size: number) { ascii(size: number) {
return this.buffer.toString('ascii', this.increment(size), this.index); return this.textDecoderAscii.decode(this.consume(size));
} }
utf8(size: number) { utf8(size: number) {
return this.buffer.toString('utf8', this.increment(size), this.index); return this.textDecoderUtf8.decode(this.consume(size));
} }
int8() { int8() {
return this.buffer.readInt8(this.increment(1)); return this.dataView.getInt8(this.increment(1));
} }
int16() { int16() {
return this.buffer.readInt16LE(this.increment(2)); return this.dataView.getInt16(this.increment(2), true);
} }
int32() { int32() {
return this.buffer.readInt32LE(this.increment(4)); return this.dataView.getInt32(this.increment(4), true);
} }
int64() { int64() {
return this.buffer.readBigInt64LE(this.increment(8)); return this.dataView.getBigInt64(this.increment(8), true);
} }
uint8() { uint8() {
return this.buffer.readUInt8(this.increment(1)); return this.dataView.getUint8(this.increment(1));
} }
uint16() { uint16() {
return this.buffer.readUInt16LE(this.increment(2)); return this.dataView.getUint16(this.increment(2), true);
} }
uint32() { uint32() {
return this.buffer.readUInt32LE(this.increment(4)); return this.dataView.getUint32(this.increment(4), true);
} }
uint64() { uint64() {
return this.buffer.readBigUInt64LE(this.increment(8)); return this.dataView.getBigUint64(this.increment(8), true);
} }
float32() { float32() {
return this.buffer.readFloatLE(this.increment(4)); return this.dataView.getFloat32(this.increment(4), true);
} }
float64() { float64() {
return this.buffer.readDoubleLE(this.increment(8)); return this.dataView.getFloat64(this.increment(8), true);
} }
boolean() { boolean() {
return this.buffer.readUInt8(this.increment(1)) === 1; return this.dataView.getUint8(this.increment(1)) === 1;
} }
} }
export class WriteStream { export class WriteStream {
private array: number[] = []; private array: number[] = [];
private textEncoder = new TextEncoder();
get buffer() { get uint8Array() {
return Buffer.from(this.array); return new Uint8Array(this.array);
}
constructor(buffer?: Buffer) {
if (buffer) this.array = Array.from(buffer);
} }
byte(value: Uint8Array) { byte(value: Uint8Array) {
@@ -98,13 +100,7 @@ export class WriteStream {
return this; return this;
} }
utf8(value: string) { utf8(value: string) {
const buffer = Buffer.alloc(Buffer.byteLength(value)); this.array.push(...this.textEncoder.encode(value));
buffer.write(value, 'utf8');
buffer.forEach((value) => {
this.array.push(value);
});
return this; return this;
} }
+5 -5
View File
@@ -331,10 +331,10 @@ export class DdsReadStream extends WindowsReadStream {
} }
readR5G6B5Int() { readR5G6B5Int() {
return this.read(2).readUInt16LE(); return new DataView(this.read(2)).getUint16(0, true);
} }
R5G6B5() { R5G6B5() {
const buffer = this.consume(2); const buffer = this.consumeUint8Array(2);
const r = (buffer[1] & 0b11111000) >>> 3; const r = (buffer[1] & 0b11111000) >>> 3;
const g = ((buffer[1] & 0b111) << 3) | ((buffer[0] & 0b11100000) >>> 5); const g = ((buffer[1] & 0b111) << 3) | ((buffer[0] & 0b11100000) >>> 5);
const b = buffer[0] & 0b11111; const b = buffer[0] & 0b11111;
@@ -375,7 +375,7 @@ export class DdsReadStream extends WindowsReadStream {
} as Record<number, Vector4Tuple>; } as Record<number, Vector4Tuple>;
} }
bc1ColorKeys() { bc1ColorKeys() {
const buffer = this.consume(4); const buffer = this.consumeUint8Array(4);
const d = (buffer[0] & 0b11000000) >>> 6; const d = (buffer[0] & 0b11000000) >>> 6;
const c = (buffer[0] & 0b110000) >>> 4; const c = (buffer[0] & 0b110000) >>> 4;
const b = (buffer[0] & 0b1100) >>> 2; const b = (buffer[0] & 0b1100) >>> 2;
@@ -396,7 +396,7 @@ export class DdsReadStream extends WindowsReadStream {
return [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p]; return [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p];
} }
bc2AlphaInterpolations() { bc2AlphaInterpolations() {
const buffer = this.consume(8); const buffer = this.consumeUint8Array(8);
const d = (buffer[1] & 0b11110000) >>> 4; const d = (buffer[1] & 0b11110000) >>> 4;
const c = buffer[1] & 0b1111; const c = buffer[1] & 0b1111;
const b = (buffer[0] & 0b11110000) >>> 4; const b = (buffer[0] & 0b11110000) >>> 4;
@@ -464,7 +464,7 @@ export class DdsReadStream extends WindowsReadStream {
} as Record<number, number>; } as Record<number, number>;
} }
bc3AlphaKeys() { bc3AlphaKeys() {
const buffer = this.consume(6); const buffer = this.consumeUint8Array(6);
const h = (buffer[2] & 0b11100000) >>> 5; const h = (buffer[2] & 0b11100000) >>> 5;
const g = (buffer[2] & 0b11100) >>> 2; const g = (buffer[2] & 0b11100) >>> 2;
const f = ((buffer[2] & 0b11) << 1) | ((buffer[1] & 0b10000000) >>> 7); const f = ((buffer[2] & 0b11) << 1) | ((buffer[1] & 0b10000000) >>> 7);
+4 -4
View File
@@ -116,7 +116,7 @@ export class PvrReadStream extends ReadStream {
const data = Buffer.alloc(pixelCount * 4); const data = Buffer.alloc(pixelCount * 4);
times(pixelCount, (index) => { times(pixelCount, (index) => {
const buffer = this.consume(2); const buffer = this.consumeUint8Array(2);
const bufferIndex = index * 4; const bufferIndex = index * 4;
const r = ((buffer[1] & 0b11110000) >>> 4) / 15; const r = ((buffer[1] & 0b11110000) >>> 4) / 15;
const g = (buffer[1] & 0b1111) / 15; const g = (buffer[1] & 0b1111) / 15;
@@ -141,7 +141,7 @@ export class PvrReadStream extends ReadStream {
const data = Buffer.alloc(pixelCount * 3); const data = Buffer.alloc(pixelCount * 3);
times(pixelCount, (index) => { times(pixelCount, (index) => {
const buffer = this.consume(2); const buffer = this.consumeUint8Array(2);
const bufferIndex = index * 4; const bufferIndex = index * 4;
const r = ((buffer[1] & 0b11111000) >>> 3) / 31; const r = ((buffer[1] & 0b11111000) >>> 3) / 31;
const g = const g =
@@ -191,9 +191,9 @@ export class PvrReadStream extends ReadStream {
return header; return header;
} }
pixelFormat() { pixelFormat() {
this.skip(4); this.seek(4);
const usesPresetFormat = this.uint32() === 0; const usesPresetFormat = this.uint32() === 0;
this.skip(-8); this.seek(-8);
return usesPresetFormat return usesPresetFormat
? (Number(this.uint64()) as PvrPixelFormat) ? (Number(this.uint64()) as PvrPixelFormat)
+1 -1
View File
@@ -306,7 +306,7 @@ export class Sc2ReadStream extends ScpgReadStream {
const fileType = this.uint32(); const fileType = this.uint32();
// other felids that we don't have any info about // other felids that we don't have any info about
this.skip(size - 4); this.seek(size - 4);
return { size, fileType }; return { size, fileType };
} }
+2 -6
View File
@@ -89,9 +89,9 @@ export class ScgReadStream extends ScpgReadStream {
); );
const strideBasedSize = stride * polygonGroupRaw.vertexCount; const strideBasedSize = stride * polygonGroupRaw.vertexCount;
if (verticesStream.buffer.length !== strideBasedSize) { if (verticesStream.buffer.byteLength !== strideBasedSize) {
console.warn( console.warn(
`Vertex stride mismatch; expected ${strideBasedSize}, got ${verticesStream.buffer.length}; skipping...`, `Vertex stride mismatch; expected ${strideBasedSize}, got ${verticesStream.buffer.byteLength}; skipping...`,
); );
return; return;
@@ -104,10 +104,6 @@ export class ScgReadStream extends ScpgReadStream {
})); }));
} }
if (verticesStream.readRemainingLength() !== 0) {
throw new RangeError('Vertices stream was not fully consumed');
}
polygonGroups.set(polygonGroupRaw['#id'].readBigUInt64LE(), { polygonGroups.set(polygonGroupRaw['#id'].readBigUInt64LE(), {
vertices, vertices,
indices, indices,
+2 -2
View File
@@ -121,7 +121,7 @@ export class ScpgReadStream extends ReadStream {
} }
case KAType.KEYED_ARCHIVE: { case KAType.KEYED_ARCHIVE: {
this.skip(4); // UInt32 length of the nested archive in bytes this.seek(4); // UInt32 length of the nested archive in bytes
return this.ka(stringTable); return this.ka(stringTable);
} }
@@ -195,7 +195,7 @@ export class ScpgReadStream extends ReadStream {
} }
} }
ka(stringTable?: Record<number, string>) { ka(stringTable?: Record<number, string>) {
this.skip(2); // "KA" this.seek(2); // "KA"
const version = this.uint16(); const version = this.uint16();
const pairs: Record<string, any> = {}; const pairs: Record<string, any> = {};