@poe2-toolkit/ggpk 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.
@@ -0,0 +1,157 @@
1
+ /**
2
+ * In-process DDS decode (BC1/BC2/BC3/BC7) to straight RGBA8. No system
3
+ * ImageMagick and no native dependencies, which keeps extraction portable in
4
+ * CI. PoE2 tree art is DX10/BC1 (icons) with some BC3; UI art is BC7.
5
+ */
6
+ import { decodeBc7Block } from './bc7.js';
7
+ const DXGI_BC1 = new Set([70, 71, 72]);
8
+ const DXGI_BC2 = new Set([73, 74, 75]);
9
+ const DXGI_BC3 = new Set([76, 77, 78]);
10
+ const DXGI_BC7 = new Set([97, 98, 99]);
11
+ /** Decode a DDS buffer to straight RGBA8. */
12
+ export function decodeDds(buf) {
13
+ const dv = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
14
+ if (dv.getUint32(0, true) !== 0x20534444) {
15
+ throw new Error('not a DDS');
16
+ }
17
+ const height = dv.getUint32(12, true);
18
+ const width = dv.getUint32(16, true);
19
+ const fourCC = String.fromCharCode(buf[84], buf[85], buf[86], buf[87]);
20
+ let kind;
21
+ let dataOffset;
22
+ if (fourCC === 'DX10') {
23
+ const dxgi = dv.getUint32(128, true);
24
+ dataOffset = 148;
25
+ if (DXGI_BC1.has(dxgi)) {
26
+ kind = 'bc1';
27
+ }
28
+ else if (DXGI_BC2.has(dxgi)) {
29
+ kind = 'bc2';
30
+ }
31
+ else if (DXGI_BC3.has(dxgi)) {
32
+ kind = 'bc3';
33
+ }
34
+ else if (DXGI_BC7.has(dxgi)) {
35
+ kind = 'bc7';
36
+ }
37
+ else {
38
+ throw new Error(`unsupported DXGI format ${dxgi}`);
39
+ }
40
+ }
41
+ else {
42
+ dataOffset = 128;
43
+ if (fourCC === 'DXT1') {
44
+ kind = 'bc1';
45
+ }
46
+ else if (fourCC === 'DXT3') {
47
+ kind = 'bc2';
48
+ }
49
+ else if (fourCC === 'DXT5') {
50
+ kind = 'bc3';
51
+ }
52
+ else {
53
+ throw new Error(`unsupported FourCC ${fourCC}`);
54
+ }
55
+ }
56
+ const rgba = new Uint8Array(width * height * 4);
57
+ const blocksX = Math.max(1, width >> 2);
58
+ const blocksY = Math.max(1, height >> 2);
59
+ let p = dataOffset;
60
+ for (let by = 0; by < blocksY; by++) {
61
+ for (let bx = 0; bx < blocksX; bx++) {
62
+ if (kind === 'bc7') {
63
+ decodeBc7Block(buf, p, rgba, width, height, bx, by);
64
+ p += 16;
65
+ continue;
66
+ }
67
+ let alpha = null;
68
+ if (kind === 'bc2') {
69
+ alpha = readBc2Alpha(buf, p);
70
+ p += 8;
71
+ }
72
+ else if (kind === 'bc3') {
73
+ alpha = readBc3Alpha(buf, p);
74
+ p += 8;
75
+ }
76
+ const colors = readColorBlock(buf, p, kind === 'bc1');
77
+ p += 8;
78
+ blitBlock(rgba, width, height, bx, by, colors, alpha);
79
+ }
80
+ }
81
+ return { width, height, rgba };
82
+ }
83
+ /** Decode the 4-colour RGB565 + 2-bit index block (shared by BC1/2/3). */
84
+ function readColorBlock(buf, o, isBc1) {
85
+ const c0 = buf[o] | (buf[o + 1] << 8);
86
+ const c1 = buf[o + 2] | (buf[o + 3] << 8);
87
+ const r0 = ((c0 >> 11) & 0x1f) * 255 / 31, g0 = ((c0 >> 5) & 0x3f) * 255 / 63, b0 = (c0 & 0x1f) * 255 / 31;
88
+ const r1 = ((c1 >> 11) & 0x1f) * 255 / 31, g1 = ((c1 >> 5) & 0x3f) * 255 / 63, b1 = (c1 & 0x1f) * 255 / 31;
89
+ const pal = [[r0, g0, b0, 255], [r1, g1, b1, 255], [0, 0, 0, 255], [0, 0, 0, 255]];
90
+ if (!isBc1 || c0 > c1) {
91
+ pal[2] = [(2 * r0 + r1) / 3, (2 * g0 + g1) / 3, (2 * b0 + b1) / 3, 255];
92
+ pal[3] = [(r0 + 2 * r1) / 3, (g0 + 2 * g1) / 3, (b0 + 2 * b1) / 3, 255];
93
+ }
94
+ else {
95
+ pal[2] = [(r0 + r1) / 2, (g0 + g1) / 2, (b0 + b1) / 2, 255];
96
+ pal[3] = [0, 0, 0, 0]; // BC1 1-bit transparency
97
+ }
98
+ const bits = buf[o + 4] | (buf[o + 5] << 8) | (buf[o + 6] << 16) | (buf[o + 7] << 24);
99
+ const idx = new Array(16);
100
+ for (let i = 0; i < 16; i++) {
101
+ idx[i] = (bits >> (i * 2)) & 0x3;
102
+ }
103
+ return { pal, idx };
104
+ }
105
+ /** BC2: 4-bit explicit alpha per texel. */
106
+ function readBc2Alpha(buf, o) {
107
+ const a = new Array(16);
108
+ for (let i = 0; i < 8; i++) {
109
+ a[i * 2] = (buf[o + i] & 0x0f) * 17;
110
+ a[i * 2 + 1] = (buf[o + i] >> 4) * 17;
111
+ }
112
+ return a;
113
+ }
114
+ /** BC3: two alpha endpoints + 3-bit interpolated indices. */
115
+ function readBc3Alpha(buf, o) {
116
+ const a0 = buf[o], a1 = buf[o + 1];
117
+ const al = [a0, a1, 0, 0, 0, 0, 0, 0];
118
+ if (a0 > a1) {
119
+ for (let i = 1; i <= 6; i++) {
120
+ al[i + 1] = ((7 - i) * a0 + i * a1) / 7;
121
+ }
122
+ }
123
+ else {
124
+ for (let i = 1; i <= 4; i++) {
125
+ al[i + 1] = ((5 - i) * a0 + i * a1) / 5;
126
+ }
127
+ al[6] = 0;
128
+ al[7] = 255;
129
+ }
130
+ let bits = 0n;
131
+ for (let i = 0; i < 6; i++) {
132
+ bits |= BigInt(buf[o + 2 + i]) << BigInt(i * 8);
133
+ }
134
+ const out = new Array(16);
135
+ for (let i = 0; i < 16; i++) {
136
+ out[i] = al[Number((bits >> BigInt(i * 3)) & 7n)];
137
+ }
138
+ return out;
139
+ }
140
+ function blitBlock(rgba, width, height, bx, by, colors, alpha) {
141
+ for (let ty = 0; ty < 4; ty++) {
142
+ for (let tx = 0; tx < 4; tx++) {
143
+ const px = bx * 4 + tx, py = by * 4 + ty;
144
+ if (px >= width || py >= height) {
145
+ continue;
146
+ }
147
+ const t = ty * 4 + tx;
148
+ const c = colors.pal[colors.idx[t]];
149
+ const di = (py * width + px) * 4;
150
+ rgba[di] = c[0];
151
+ rgba[di + 1] = c[1];
152
+ rgba[di + 2] = c[2];
153
+ rgba[di + 3] = alpha ? alpha[t] : c[3];
154
+ }
155
+ }
156
+ }
157
+ //# sourceMappingURL=dds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dds.js","sourceRoot":"","sources":["../../src/image/dds.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAK1C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;AACvC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;AACvC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;AACvC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;AAEvC,6CAA6C;AAC7C,MAAM,UAAU,SAAS,CAAC,GAAe;IACvC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IAEpE,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAE,EAAE,GAAG,CAAC,EAAE,CAAE,EAAE,GAAG,CAAC,EAAE,CAAE,EAAE,GAAG,CAAC,EAAE,CAAE,CAAC,CAAC;IAE3E,IAAI,IAAe,CAAC;IACpB,IAAI,UAAkB,CAAC;IAEvB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACrC,UAAU,GAAG,GAAG,CAAC;QAEjB,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,IAAI,GAAG,KAAK,CAAC;QACf,CAAC;aAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,IAAI,GAAG,KAAK,CAAC;QACf,CAAC;aAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,IAAI,GAAG,KAAK,CAAC;QACf,CAAC;aAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,IAAI,GAAG,KAAK,CAAC;QACf,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,UAAU,GAAG,GAAG,CAAC;QAEjB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,IAAI,GAAG,KAAK,CAAC;QACf,CAAC;aAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YAC7B,IAAI,GAAG,KAAK,CAAC;QACf,CAAC;aAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YAC7B,IAAI,GAAG,KAAK,CAAC;QACf,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;IACzC,IAAI,CAAC,GAAG,UAAU,CAAC;IAEnB,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC;QACpC,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC;YACpC,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;gBACnB,cAAc,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;gBACpD,CAAC,IAAI,EAAE,CAAC;gBACR,SAAS;YACX,CAAC;YAED,IAAI,KAAK,GAAoB,IAAI,CAAC;YAElC,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;gBACnB,KAAK,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAC7B,CAAC,IAAI,CAAC,CAAC;YACT,CAAC;iBAAM,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;gBAC1B,KAAK,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAC7B,CAAC,IAAI,CAAC,CAAC;YACT,CAAC;YAED,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,KAAK,KAAK,CAAC,CAAC;YACtD,CAAC,IAAI,CAAC,CAAC;YACP,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC;AAOD,0EAA0E;AAC1E,SAAS,cAAc,CAAC,GAAe,EAAE,CAAS,EAAE,KAAc;IAChE,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,CAAC,CAAC,CAAC;IACxC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,CAAC,CAAC,CAAC;IAC5C,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC;IAC3G,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC;IAC3G,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAEnF,IAAI,CAAC,KAAK,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;QACtB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QACxE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1E,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QAC5D,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,yBAAyB;IAClD,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC,CAAC;IAC1F,MAAM,GAAG,GAAG,IAAI,KAAK,CAAS,EAAE,CAAC,CAAC;IAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IACnC,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACtB,CAAC;AAED,2CAA2C;AAC3C,SAAS,YAAY,CAAC,GAAe,EAAE,CAAS;IAC9C,MAAM,CAAC,GAAG,IAAI,KAAK,CAAS,EAAE,CAAC,CAAC;IAEhC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACrC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;IACzC,CAAC;IAED,OAAO,CAAC,CAAC;AACX,CAAC;AAED,6DAA6D;AAC7D,SAAS,YAAY,CAAC,GAAe,EAAE,CAAS;IAC9C,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAE,EAAE,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;IACrC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAEtC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QAC1C,CAAC;QAED,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACV,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IACd,CAAC;IAED,IAAI,IAAI,GAAG,EAAE,CAAC;IAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,KAAK,CAAS,EAAE,CAAC,CAAC;IAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAE,CAAC;IACrD,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,SAAS,CAChB,IAAgB,EAChB,KAAa,EACb,MAAc,EACd,EAAU,EACV,EAAU,EACV,MAAkB,EAClB,KAAsB;IAEtB,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;QAC9B,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;YAC9B,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;YAEzC,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;gBAChC,SAAS;YACX,CAAC;YAED,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAE,CAAE,CAAC;YACtC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;YACjC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;YACjB,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;YACrB,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;YACrB,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC;QAC3C,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Minimal PNG encode/decode on Node's zlib — no native dependencies. Encoding
3
+ * emits 8-bit RGBA with filter-none rows; decoding handles 8-bit RGBA or RGB,
4
+ * no interlace. Enough for GGPK art round-trips and atlas output.
5
+ */
6
+ import type { RgbaImage } from './types.js';
7
+ /** Encode RGBA8 to a PNG buffer (Node zlib, no deps). */
8
+ export declare function encodePng(width: number, height: number, rgba: Uint8Array): Buffer;
9
+ /** Decode a PNG buffer (8-bit RGBA or RGB, no interlace) to RGBA8. */
10
+ export declare function decodePng(buf: Uint8Array): RgbaImage;
11
+ //# sourceMappingURL=png.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"png.d.ts","sourceRoot":"","sources":["../../src/image/png.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA4B5C,yDAAyD;AACzD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAgCjF;AAED,sEAAsE;AACtE,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,SAAS,CAgFpD"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Minimal PNG encode/decode on Node's zlib — no native dependencies. Encoding
3
+ * emits 8-bit RGBA with filter-none rows; decoding handles 8-bit RGBA or RGB,
4
+ * no interlace. Enough for GGPK art round-trips and atlas output.
5
+ */
6
+ import { deflateSync, inflateSync } from 'node:zlib';
7
+ const CRC_TABLE = (() => {
8
+ const t = new Uint32Array(256);
9
+ for (let n = 0; n < 256; n++) {
10
+ let c = n;
11
+ for (let k = 0; k < 8; k++) {
12
+ c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
13
+ }
14
+ t[n] = c >>> 0;
15
+ }
16
+ return t;
17
+ })();
18
+ function crc32(buf) {
19
+ let c = 0xffffffff;
20
+ for (let i = 0; i < buf.length; i++) {
21
+ c = CRC_TABLE[(c ^ buf[i]) & 0xff] ^ (c >>> 8);
22
+ }
23
+ return (c ^ 0xffffffff) >>> 0;
24
+ }
25
+ /** Encode RGBA8 to a PNG buffer (Node zlib, no deps). */
26
+ export function encodePng(width, height, rgba) {
27
+ const stride = width * 4;
28
+ const raw = Buffer.alloc((stride + 1) * height);
29
+ for (let y = 0; y < height; y++) {
30
+ raw[y * (stride + 1)] = 0; // filter: none
31
+ Buffer.from(rgba.buffer, rgba.byteOffset + y * stride, stride).copy(raw, y * (stride + 1) + 1);
32
+ }
33
+ const idat = deflateSync(raw, { level: 9 });
34
+ const chunk = (type, data) => {
35
+ const out = Buffer.alloc(12 + data.length);
36
+ out.writeUInt32BE(data.length, 0);
37
+ out.write(type, 4, 'ascii');
38
+ data.copy(out, 8);
39
+ out.writeUInt32BE(crc32(out.subarray(4, 8 + data.length)) >>> 0, 8 + data.length);
40
+ return out;
41
+ };
42
+ const ihdr = Buffer.alloc(13);
43
+ ihdr.writeUInt32BE(width, 0);
44
+ ihdr.writeUInt32BE(height, 4);
45
+ ihdr[8] = 8; // 8-bit
46
+ ihdr[9] = 6; // RGBA
47
+ return Buffer.concat([
48
+ Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
49
+ chunk('IHDR', ihdr),
50
+ chunk('IDAT', idat),
51
+ chunk('IEND', Buffer.alloc(0)),
52
+ ]);
53
+ }
54
+ /** Decode a PNG buffer (8-bit RGBA or RGB, no interlace) to RGBA8. */
55
+ export function decodePng(buf) {
56
+ const dv = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
57
+ let o = 8; // skip signature
58
+ let width = 0, height = 0, colorType = 0;
59
+ const idat = [];
60
+ while (o < buf.length) {
61
+ const len = dv.getUint32(o, false);
62
+ const type = String.fromCharCode(buf[o + 4], buf[o + 5], buf[o + 6], buf[o + 7]);
63
+ const data = buf.subarray(o + 8, o + 8 + len);
64
+ if (type === 'IHDR') {
65
+ width = dv.getUint32(o + 8, false);
66
+ height = dv.getUint32(o + 12, false);
67
+ colorType = buf[o + 17];
68
+ }
69
+ else if (type === 'IDAT') {
70
+ idat.push(data);
71
+ }
72
+ else if (type === 'IEND') {
73
+ break;
74
+ }
75
+ o += 12 + len;
76
+ }
77
+ const channels = colorType === 6 ? 4 : colorType === 2 ? 3 : 1;
78
+ const raw = inflateSync(Buffer.concat(idat));
79
+ const stride = width * channels;
80
+ const rgba = new Uint8Array(width * height * 4);
81
+ const line = new Uint8Array(stride);
82
+ const prev = new Uint8Array(stride);
83
+ let p = 0;
84
+ for (let y = 0; y < height; y++) {
85
+ const filter = raw[p++];
86
+ for (let i = 0; i < stride; i++) {
87
+ const x = raw[p + i];
88
+ const a = i >= channels ? line[i - channels] : 0;
89
+ const b = prev[i];
90
+ const c = i >= channels ? prev[i - channels] : 0;
91
+ let v;
92
+ switch (filter) {
93
+ case 1:
94
+ v = x + a;
95
+ break;
96
+ case 2:
97
+ v = x + b;
98
+ break;
99
+ case 3:
100
+ v = x + ((a + b) >> 1);
101
+ break;
102
+ case 4: {
103
+ const pp = a + b - c, pa = Math.abs(pp - a), pb = Math.abs(pp - b), pc = Math.abs(pp - c);
104
+ v = x + (pa <= pb && pa <= pc ? a : pb <= pc ? b : c);
105
+ break;
106
+ }
107
+ default:
108
+ v = x;
109
+ }
110
+ line[i] = v & 0xff;
111
+ }
112
+ p += stride;
113
+ for (let x = 0; x < width; x++) {
114
+ const di = (y * width + x) * 4, si = x * channels;
115
+ rgba[di] = line[si];
116
+ rgba[di + 1] = line[si + Math.min(1, channels - 1)];
117
+ rgba[di + 2] = line[si + Math.min(2, channels - 1)];
118
+ rgba[di + 3] = channels === 4 ? line[si + 3] : 255;
119
+ }
120
+ line.forEach((value, i) => {
121
+ prev[i] = value;
122
+ });
123
+ }
124
+ return { width, height, rgba };
125
+ }
126
+ //# sourceMappingURL=png.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"png.js","sourceRoot":"","sources":["../../src/image/png.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /** A decoded, straight (non-premultiplied) RGBA8 image. */
2
+ export interface RgbaImage {
3
+ width: number;
4
+ height: number;
5
+ /** Row-major RGBA bytes, length `width * height * 4`. */
6
+ rgba: Uint8Array;
7
+ }
8
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/image/types.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,IAAI,EAAE,UAAU,CAAC;CAClB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/image/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @poe2-toolkit/ggpk — the shared access layer for Path of Exile 2's official GGPK /
3
+ * patch server. Provides the {@link GgpkSource} boundary plus the format
4
+ * decoders (images, stat descriptions) every PoE2 extractor reuses.
5
+ */
6
+ export type { GgpkSource, TableRow } from './source.js';
7
+ export type { RgbaImage } from './image/types.js';
8
+ export { createCdnSource } from './cdnSource.js';
9
+ export type { CdnSource, CdnSourceOptions, GgpkImageSource, SpriteRef } from './cdnSource.js';
10
+ export { decodeDds } from './image/dds.js';
11
+ export { encodePng, decodePng } from './image/png.js';
12
+ export { buildStatIndex, renderBlock } from './statDescriptions.js';
13
+ export type { StatIndex, RenderedBlock } from './statDescriptions.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE9F,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @poe2-toolkit/ggpk — the shared access layer for Path of Exile 2's official GGPK /
3
+ * patch server. Provides the {@link GgpkSource} boundary plus the format
4
+ * decoders (images, stat descriptions) every PoE2 extractor reuses.
5
+ */
6
+ export { createCdnSource } from './cdnSource.js';
7
+ export { decodeDds } from './image/dds.js';
8
+ export { encodePng, decodePng } from './image/png.js';
9
+ export { buildStatIndex, renderBlock } from './statDescriptions.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The boundary every PoE2 data extractor depends on, and the only thing that
3
+ * knows where bytes come from. An extractor asks a {@link GgpkSource} for
4
+ * decoded tables and raw files; whether those are served from the patch CDN, a
5
+ * local game install, or a pre-extracted cache is the source's concern, never
6
+ * the extractor's.
7
+ *
8
+ * Keeping this interface dependency-free is deliberate: the extractor packages
9
+ * import only the type, so none of them pull in the (heavy) acquisition stack.
10
+ */
11
+ /** One decoded row of a GGPK data table, keyed by column name. */
12
+ export type TableRow = Record<string, unknown>;
13
+ /** A read-only view over the GGPK, abstracted from how the data is acquired. */
14
+ export interface GgpkSource {
15
+ /**
16
+ * Decoded rows of a GGPK data table (e.g. `PassiveSkills`), in table order.
17
+ * Column selection is the source's concern — typically driven by an extract
18
+ * config shared with the underlying `pathofexile-dat` tooling.
19
+ */
20
+ table(name: string): Promise<TableRow[]>;
21
+ /**
22
+ * Raw bytes of a GGPK file by its logical path (e.g.
23
+ * `metadata/passiveskillgraph.psg`), or `null` if the source cannot serve it
24
+ * (for instance a texture bundle the patch CDN does not host).
25
+ */
26
+ file(path: string): Promise<Uint8Array | null>;
27
+ }
28
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,kEAAkE;AAClE,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C,gFAAgF;AAChF,MAAM,WAAW,UAAU;IACzB;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAEzC;;;;OAIG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;CAChD"}
package/dist/source.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The boundary every PoE2 data extractor depends on, and the only thing that
3
+ * knows where bytes come from. An extractor asks a {@link GgpkSource} for
4
+ * decoded tables and raw files; whether those are served from the patch CDN, a
5
+ * local game install, or a pre-extracted cache is the source's concern, never
6
+ * the extractor's.
7
+ *
8
+ * Keeping this interface dependency-free is deliberate: the extractor packages
9
+ * import only the type, so none of them pull in the (heavy) acquisition stack.
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * StatDescriptions engine — renders GGG's numeric `(stat_id, value)` pairs into
3
+ * human-readable text, using GGG's own `stat_descriptions.csd` straight from the
4
+ * GGPK. Despite the `.csd` extension the file is plain UTF-16 text, not compiled
5
+ * binary. Shared across domains: passive nodes, item mods and gem stats all
6
+ * render through it.
7
+ *
8
+ * File format (one block per description):
9
+ *
10
+ * ```
11
+ * description
12
+ * \t<N> <stat_id_1> ... <stat_id_N>
13
+ * \t<lineCount>
14
+ * \t\t<cond_1> ... <cond_N> "text with {0} {1}" [handler index]...
15
+ * \tlang "French" <- other languages follow; English is read here
16
+ * ```
17
+ *
18
+ * Every stat id is indexed to the block that renders it (a multi-stat block is
19
+ * indexed under each of its stats); rendering picks the line whose per-stat
20
+ * conditions all accept the supplied values.
21
+ */
22
+ /** An inclusive numeric range a stat value must fall in for a line to apply. */
23
+ interface Condition {
24
+ min: number;
25
+ max: number;
26
+ }
27
+ /** One renderable line of a description block. */
28
+ interface Variant {
29
+ conditions: Condition[];
30
+ text: string;
31
+ /** Flat `name index name index …` handler tokens applied to the values. */
32
+ handlers: string[];
33
+ }
34
+ /** A description block: the stats it renders together and its candidate lines. */
35
+ interface StatRecord {
36
+ statIds: string[];
37
+ variants: Variant[];
38
+ }
39
+ /** Per-stat lookup from a parsed `.csd` file. */
40
+ export interface StatIndex {
41
+ byStat: Map<string, StatRecord>;
42
+ }
43
+ /** The rendered lines of a stat block, plus any stat ids that had no block. */
44
+ export interface RenderedBlock {
45
+ lines: string[];
46
+ unresolved: string[];
47
+ }
48
+ /**
49
+ * Build a per-stat lookup from the raw text of a GGG `stat_descriptions.csd`
50
+ * file (decoded from UTF-16). The first language block (English) is kept; later
51
+ * `lang "..."` blocks are skipped by the outer loop, which only resumes on the
52
+ * next `description` marker.
53
+ */
54
+ export declare function buildStatIndex(csd: string): StatIndex;
55
+ /**
56
+ * Render a full stat block. Each stat resolves to its block; a block may render
57
+ * several stats together (e.g. min/max added damage), so its placeholders are
58
+ * filled from whichever of those stats it provides (others default to 0) and all
59
+ * are marked consumed so the line is not repeated.
60
+ */
61
+ export declare function renderBlock(index: StatIndex, statIds: string[], vals: number[]): RenderedBlock;
62
+ export {};
63
+ //# sourceMappingURL=statDescriptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statDescriptions.d.ts","sourceRoot":"","sources":["../src/statDescriptions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,gFAAgF;AAChF,UAAU,SAAS;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,kDAAkD;AAClD,UAAU,OAAO;IACf,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,kFAAkF;AAClF,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,iDAAiD;AACjD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACjC;AAED,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAmCD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAwCrD;AAkFD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CA4C9F"}