feat: r5g6b5a0 format compatibility

This commit is contained in:
TrèsAbhi committed 2024-01-20 13:27:56 -06:00
1 parent 86fd714923
commit a362301515
5 files changed
+43 -10

No files matched your search

+37 -4
View File
@@ -1,5 +1,4 @@
import { clamp, isEqual, times } from 'lodash';
import { Vector4Tuple } from 'three';
import { BufferStream } from './buffer';
export enum PvrFlags {
@@ -89,12 +88,13 @@ enum PvrChannelType {
enum ResolvedBitRatePixelFormat {
R4G4B4A4,
R5G6B5A0,
}
export class PvrStream extends BufferStream {
pvr() {
const header = this.header();
const metadata = this.metadata();
this.metadata();
if (typeof header.pixelFormat === 'number') {
switch (header.pixelFormat) {
@@ -114,7 +114,6 @@ export class PvrStream extends BufferStream {
switch (resolvedPixelFormat) {
case ResolvedBitRatePixelFormat.R4G4B4A4: {
const data = Buffer.alloc(pixelCount * 4);
let lastPixel: Vector4Tuple;
times(pixelCount, (index) => {
const buffer = this.consume(2);
@@ -138,6 +137,31 @@ export class PvrStream extends BufferStream {
};
}
case ResolvedBitRatePixelFormat.R5G6B5A0: {
const data = Buffer.alloc(pixelCount * 3);
times(pixelCount, (index) => {
const buffer = this.consume(2);
const bufferIndex = index * 4;
const r = ((buffer[1] & 0b11111000) >>> 3) / 31;
const g =
((buffer[1] & 0b111) << 3) |
(((buffer[0] & 0b11100000) >>> 5) / 31);
const b = buffer[0] & 0b11111;
data[bufferIndex] = Math.round(clamp(r * 255, 0, 255));
data[bufferIndex + 1] = Math.round(clamp(g * 255, 0, 255));
data[bufferIndex + 2] = Math.round(clamp(b * 255, 0, 255));
});
return {
data,
width: header.width,
height: header.height,
channels: 3 as const,
};
}
default:
throw new TypeError(
`Unhandled resolved pixel format ${resolvedPixelFormat} (${header.pixelFormat})`,
@@ -188,7 +212,16 @@ export class PvrStream extends BufferStream {
throw new TypeError(
`Unhandled rgba bit rate ${pixelFormat.bitRates.join(', ')}`,
);
} else throw new TypeError(`Unhandled pixel order ${pixelFormat.order}`);
} else if (pixelFormat.order === 'rgb\0') {
if (isEqual(pixelFormat.bitRates, [5, 6, 5, 0])) {
return ResolvedBitRatePixelFormat.R5G6B5A0;
} else
throw new TypeError(
`Unhandled rgb bit rate ${pixelFormat.bitRates.join(', ')}`,
);
} else {
throw new TypeError(`Unhandled pixel order ${pixelFormat.order}`);
}
}
metadata() {
const fourCC = this.ascii(4);