@flighthq/texture-formats 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/byteReader.d.ts +14 -0
  2. package/dist/byteReader.d.ts.map +1 -0
  3. package/dist/byteReader.js +51 -0
  4. package/dist/byteReader.js.map +1 -0
  5. package/dist/detectTextureContainer.d.ts +2 -0
  6. package/dist/detectTextureContainer.d.ts.map +1 -0
  7. package/dist/detectTextureContainer.js +31 -0
  8. package/dist/detectTextureContainer.js.map +1 -0
  9. package/dist/index.d.ts +7 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +7 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/parseAtf.d.ts +3 -0
  14. package/dist/parseAtf.d.ts.map +1 -0
  15. package/dist/parseAtf.js +139 -0
  16. package/dist/parseAtf.js.map +1 -0
  17. package/dist/parseBasis.d.ts +3 -0
  18. package/dist/parseBasis.d.ts.map +1 -0
  19. package/dist/parseBasis.js +82 -0
  20. package/dist/parseBasis.js.map +1 -0
  21. package/dist/parseDds.d.ts +3 -0
  22. package/dist/parseDds.d.ts.map +1 -0
  23. package/dist/parseDds.js +151 -0
  24. package/dist/parseDds.js.map +1 -0
  25. package/dist/parseKtx2.d.ts +3 -0
  26. package/dist/parseKtx2.d.ts.map +1 -0
  27. package/dist/parseKtx2.js +173 -0
  28. package/dist/parseKtx2.js.map +1 -0
  29. package/dist/selectTextureContainer.d.ts +4 -0
  30. package/dist/selectTextureContainer.d.ts.map +1 -0
  31. package/dist/selectTextureContainer.js +15 -0
  32. package/dist/selectTextureContainer.js.map +1 -0
  33. package/dist/textureLevelLayout.d.ts +8 -0
  34. package/dist/textureLevelLayout.d.ts.map +1 -0
  35. package/dist/textureLevelLayout.js +109 -0
  36. package/dist/textureLevelLayout.js.map +1 -0
  37. package/package.json +37 -0
  38. package/src/byteReader.test.ts +105 -0
  39. package/src/detectTextureContainer.test.ts +33 -0
  40. package/src/parseAtf.test.ts +288 -0
  41. package/src/parseBasis.test.ts +124 -0
  42. package/src/parseDds.test.ts +146 -0
  43. package/src/parseKtx2.test.ts +135 -0
  44. package/src/selectTextureContainer.test.ts +38 -0
  45. package/src/textureLevelLayout.test.ts +45 -0
@@ -0,0 +1,38 @@
1
+ import type { TextureContainer } from '@flighthq/types';
2
+ import type { TextureContainerFormat } from '@flighthq/types';
3
+ import { describe, expect, it } from 'vitest';
4
+
5
+ import { selectTextureContainer } from './selectTextureContainer';
6
+
7
+ function container(format: TextureContainerFormat): TextureContainer {
8
+ return {
9
+ depth: 1,
10
+ faces: 1,
11
+ format,
12
+ height: 4,
13
+ layers: 1,
14
+ levels: [{ byteLength: 8, byteOffset: 0, height: 4, width: 4 }],
15
+ mipLevels: 1,
16
+ supercompression: 'None',
17
+ width: 4,
18
+ };
19
+ }
20
+
21
+ describe('selectTextureContainer', () => {
22
+ it('returns the first container whose format is supported', () => {
23
+ const peers = [container('pvrtc4bppRgb'), container('etc1'), container('bc3')];
24
+ const chosen = selectTextureContainer(peers, ['bc3', 'etc1']);
25
+ expect(chosen).not.toBeNull();
26
+ // etc1 comes before bc3 in the peer list, so it wins even though both are supported.
27
+ expect(chosen!.format).toBe('etc1');
28
+ });
29
+
30
+ it('returns null when no peer format is supported', () => {
31
+ const peers = [container('pvrtc4bppRgb'), container('etc1')];
32
+ expect(selectTextureContainer(peers, ['bc3', 'astc4x4'])).toBeNull();
33
+ });
34
+
35
+ it('returns null for an empty container set', () => {
36
+ expect(selectTextureContainer([], ['bc3'])).toBeNull();
37
+ });
38
+ });
@@ -0,0 +1,45 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { computeTextureContainerLevels, getTextureContainerLevelByteLength } from './textureLevelLayout';
4
+
5
+ describe('computeTextureContainerLevels', () => {
6
+ it('builds a contiguous mip chain with descending dimensions and offsets', () => {
7
+ const result = computeTextureContainerLevels('bc1', 8, 8, 4, 1, 1, 100);
8
+ expect(result).not.toBeNull();
9
+ const levels = result!.levels;
10
+ expect(levels.map((l) => l.width)).toEqual([8, 4, 2, 1]);
11
+ // bc1 = 8 bytes/block, 4x4 blocks: 8x8 -> 2x2 blocks -> 32; 4x4 -> 8; 2x2/1x1 floor to 1 block -> 8.
12
+ expect(levels.map((l) => l.byteLength)).toEqual([32, 8, 8, 8]);
13
+ expect(levels.map((l) => l.byteOffset)).toEqual([100, 132, 140, 148]);
14
+ expect(result!.endOffset).toBe(156);
15
+ });
16
+
17
+ it('nests layer -> face -> mip so each face holds a full mip chain', () => {
18
+ const result = computeTextureContainerLevels('bc3', 4, 4, 1, 1, 6, 0);
19
+ expect(result).not.toBeNull();
20
+ expect(result!.levels).toHaveLength(6);
21
+ // bc3 = 16 bytes/block, one 4x4 block per face.
22
+ expect(result!.levels.map((l) => l.byteOffset)).toEqual([0, 16, 32, 48, 64, 80]);
23
+ });
24
+
25
+ it('returns null for a format without a fixed block size', () => {
26
+ expect(computeTextureContainerLevels('etc1s', 4, 4, 1, 1, 1, 0)).toBeNull();
27
+ });
28
+ });
29
+
30
+ describe('getTextureContainerLevelByteLength', () => {
31
+ it('multiplies bytes-per-pixel for uncompressed formats', () => {
32
+ expect(getTextureContainerLevelByteLength('rgba8unorm', 4, 4)).toBe(64);
33
+ expect(getTextureContainerLevelByteLength('r8unorm', 4, 4)).toBe(16);
34
+ });
35
+
36
+ it('rounds up to whole blocks for block-compressed formats', () => {
37
+ expect(getTextureContainerLevelByteLength('bc1', 4, 4)).toBe(8);
38
+ expect(getTextureContainerLevelByteLength('bc7', 5, 5)).toBe(64); // 2x2 blocks * 16
39
+ expect(getTextureContainerLevelByteLength('astc6x6', 6, 6)).toBe(16);
40
+ });
41
+
42
+ it('returns -1 for a variable-rate format', () => {
43
+ expect(getTextureContainerLevelByteLength('etc1s', 4, 4)).toBe(-1);
44
+ });
45
+ });