xz-compat 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 (145) hide show
  1. package/LICENSE +42 -0
  2. package/README.md +248 -0
  3. package/dist/cjs/compat.d.cts +1 -0
  4. package/dist/cjs/compat.d.ts +1 -0
  5. package/dist/cjs/compat.js +23 -0
  6. package/dist/cjs/compat.js.map +1 -0
  7. package/dist/cjs/filters/bcj/Bcj.d.cts +16 -0
  8. package/dist/cjs/filters/bcj/Bcj.d.ts +16 -0
  9. package/dist/cjs/filters/bcj/Bcj.js +192 -0
  10. package/dist/cjs/filters/bcj/Bcj.js.map +1 -0
  11. package/dist/cjs/filters/bcj/BcjArm.d.cts +16 -0
  12. package/dist/cjs/filters/bcj/BcjArm.d.ts +16 -0
  13. package/dist/cjs/filters/bcj/BcjArm.js +122 -0
  14. package/dist/cjs/filters/bcj/BcjArm.js.map +1 -0
  15. package/dist/cjs/filters/bcj/BcjArm64.d.cts +21 -0
  16. package/dist/cjs/filters/bcj/BcjArm64.d.ts +21 -0
  17. package/dist/cjs/filters/bcj/BcjArm64.js +65 -0
  18. package/dist/cjs/filters/bcj/BcjArm64.js.map +1 -0
  19. package/dist/cjs/filters/bcj/BcjArmt.d.cts +19 -0
  20. package/dist/cjs/filters/bcj/BcjArmt.d.ts +19 -0
  21. package/dist/cjs/filters/bcj/BcjArmt.js +76 -0
  22. package/dist/cjs/filters/bcj/BcjArmt.js.map +1 -0
  23. package/dist/cjs/filters/bcj/BcjIa64.d.cts +15 -0
  24. package/dist/cjs/filters/bcj/BcjIa64.d.ts +15 -0
  25. package/dist/cjs/filters/bcj/BcjIa64.js +141 -0
  26. package/dist/cjs/filters/bcj/BcjIa64.js.map +1 -0
  27. package/dist/cjs/filters/bcj/BcjPpc.d.cts +20 -0
  28. package/dist/cjs/filters/bcj/BcjPpc.d.ts +20 -0
  29. package/dist/cjs/filters/bcj/BcjPpc.js +64 -0
  30. package/dist/cjs/filters/bcj/BcjPpc.js.map +1 -0
  31. package/dist/cjs/filters/bcj/BcjSparc.d.cts +19 -0
  32. package/dist/cjs/filters/bcj/BcjSparc.d.ts +19 -0
  33. package/dist/cjs/filters/bcj/BcjSparc.js +69 -0
  34. package/dist/cjs/filters/bcj/BcjSparc.js.map +1 -0
  35. package/dist/cjs/filters/delta/Delta.d.cts +16 -0
  36. package/dist/cjs/filters/delta/Delta.d.ts +16 -0
  37. package/dist/cjs/filters/delta/Delta.js +74 -0
  38. package/dist/cjs/filters/delta/Delta.js.map +1 -0
  39. package/dist/cjs/filters/index.d.cts +8 -0
  40. package/dist/cjs/filters/index.d.ts +8 -0
  41. package/dist/cjs/filters/index.js +27 -0
  42. package/dist/cjs/filters/index.js.map +1 -0
  43. package/dist/cjs/index.d.cts +4 -0
  44. package/dist/cjs/index.d.ts +4 -0
  45. package/dist/cjs/index.js +58 -0
  46. package/dist/cjs/index.js.map +1 -0
  47. package/dist/cjs/lzma/Lzma2ChunkParser.d.cts +73 -0
  48. package/dist/cjs/lzma/Lzma2ChunkParser.d.ts +73 -0
  49. package/dist/cjs/lzma/Lzma2ChunkParser.js +148 -0
  50. package/dist/cjs/lzma/Lzma2ChunkParser.js.map +1 -0
  51. package/dist/cjs/lzma/index.d.cts +31 -0
  52. package/dist/cjs/lzma/index.d.ts +31 -0
  53. package/dist/cjs/lzma/index.js +83 -0
  54. package/dist/cjs/lzma/index.js.map +1 -0
  55. package/dist/cjs/lzma/stream/transforms.d.cts +46 -0
  56. package/dist/cjs/lzma/stream/transforms.d.ts +46 -0
  57. package/dist/cjs/lzma/stream/transforms.js +193 -0
  58. package/dist/cjs/lzma/stream/transforms.js.map +1 -0
  59. package/dist/cjs/lzma/sync/Lzma2Decoder.d.cts +63 -0
  60. package/dist/cjs/lzma/sync/Lzma2Decoder.d.ts +63 -0
  61. package/dist/cjs/lzma/sync/Lzma2Decoder.js +231 -0
  62. package/dist/cjs/lzma/sync/Lzma2Decoder.js.map +1 -0
  63. package/dist/cjs/lzma/sync/LzmaDecoder.d.cts +97 -0
  64. package/dist/cjs/lzma/sync/LzmaDecoder.d.ts +97 -0
  65. package/dist/cjs/lzma/sync/LzmaDecoder.js +582 -0
  66. package/dist/cjs/lzma/sync/LzmaDecoder.js.map +1 -0
  67. package/dist/cjs/lzma/sync/RangeDecoder.d.cts +69 -0
  68. package/dist/cjs/lzma/sync/RangeDecoder.d.ts +69 -0
  69. package/dist/cjs/lzma/sync/RangeDecoder.js +162 -0
  70. package/dist/cjs/lzma/sync/RangeDecoder.js.map +1 -0
  71. package/dist/cjs/lzma/types.d.cts +117 -0
  72. package/dist/cjs/lzma/types.d.ts +117 -0
  73. package/dist/cjs/lzma/types.js +264 -0
  74. package/dist/cjs/lzma/types.js.map +1 -0
  75. package/dist/cjs/package.json +1 -0
  76. package/dist/cjs/utils/createBufferingDecoder.d.cts +10 -0
  77. package/dist/cjs/utils/createBufferingDecoder.d.ts +10 -0
  78. package/dist/cjs/utils/createBufferingDecoder.js +41 -0
  79. package/dist/cjs/utils/createBufferingDecoder.js.map +1 -0
  80. package/dist/cjs/xz/Decoder.d.cts +21 -0
  81. package/dist/cjs/xz/Decoder.d.ts +21 -0
  82. package/dist/cjs/xz/Decoder.js +325 -0
  83. package/dist/cjs/xz/Decoder.js.map +1 -0
  84. package/dist/esm/compat.d.ts +1 -0
  85. package/dist/esm/compat.js +7 -0
  86. package/dist/esm/compat.js.map +1 -0
  87. package/dist/esm/filters/bcj/Bcj.d.ts +16 -0
  88. package/dist/esm/filters/bcj/Bcj.js +184 -0
  89. package/dist/esm/filters/bcj/Bcj.js.map +1 -0
  90. package/dist/esm/filters/bcj/BcjArm.d.ts +16 -0
  91. package/dist/esm/filters/bcj/BcjArm.js +114 -0
  92. package/dist/esm/filters/bcj/BcjArm.js.map +1 -0
  93. package/dist/esm/filters/bcj/BcjArm64.d.ts +21 -0
  94. package/dist/esm/filters/bcj/BcjArm64.js +57 -0
  95. package/dist/esm/filters/bcj/BcjArm64.js.map +1 -0
  96. package/dist/esm/filters/bcj/BcjArmt.d.ts +19 -0
  97. package/dist/esm/filters/bcj/BcjArmt.js +66 -0
  98. package/dist/esm/filters/bcj/BcjArmt.js.map +1 -0
  99. package/dist/esm/filters/bcj/BcjIa64.d.ts +15 -0
  100. package/dist/esm/filters/bcj/BcjIa64.js +127 -0
  101. package/dist/esm/filters/bcj/BcjIa64.js.map +1 -0
  102. package/dist/esm/filters/bcj/BcjPpc.d.ts +20 -0
  103. package/dist/esm/filters/bcj/BcjPpc.js +55 -0
  104. package/dist/esm/filters/bcj/BcjPpc.js.map +1 -0
  105. package/dist/esm/filters/bcj/BcjSparc.d.ts +19 -0
  106. package/dist/esm/filters/bcj/BcjSparc.js +59 -0
  107. package/dist/esm/filters/bcj/BcjSparc.js.map +1 -0
  108. package/dist/esm/filters/delta/Delta.d.ts +16 -0
  109. package/dist/esm/filters/delta/Delta.js +66 -0
  110. package/dist/esm/filters/delta/Delta.js.map +1 -0
  111. package/dist/esm/filters/index.d.ts +8 -0
  112. package/dist/esm/filters/index.js +9 -0
  113. package/dist/esm/filters/index.js.map +1 -0
  114. package/dist/esm/index.d.ts +4 -0
  115. package/dist/esm/index.js +5 -0
  116. package/dist/esm/index.js.map +1 -0
  117. package/dist/esm/lzma/Lzma2ChunkParser.d.ts +73 -0
  118. package/dist/esm/lzma/Lzma2ChunkParser.js +137 -0
  119. package/dist/esm/lzma/Lzma2ChunkParser.js.map +1 -0
  120. package/dist/esm/lzma/index.d.ts +31 -0
  121. package/dist/esm/lzma/index.js +44 -0
  122. package/dist/esm/lzma/index.js.map +1 -0
  123. package/dist/esm/lzma/stream/transforms.d.ts +46 -0
  124. package/dist/esm/lzma/stream/transforms.js +190 -0
  125. package/dist/esm/lzma/stream/transforms.js.map +1 -0
  126. package/dist/esm/lzma/sync/Lzma2Decoder.d.ts +63 -0
  127. package/dist/esm/lzma/sync/Lzma2Decoder.js +211 -0
  128. package/dist/esm/lzma/sync/Lzma2Decoder.js.map +1 -0
  129. package/dist/esm/lzma/sync/LzmaDecoder.d.ts +97 -0
  130. package/dist/esm/lzma/sync/LzmaDecoder.js +545 -0
  131. package/dist/esm/lzma/sync/LzmaDecoder.js.map +1 -0
  132. package/dist/esm/lzma/sync/RangeDecoder.d.ts +69 -0
  133. package/dist/esm/lzma/sync/RangeDecoder.js +132 -0
  134. package/dist/esm/lzma/sync/RangeDecoder.js.map +1 -0
  135. package/dist/esm/lzma/types.d.ts +117 -0
  136. package/dist/esm/lzma/types.js +154 -0
  137. package/dist/esm/lzma/types.js.map +1 -0
  138. package/dist/esm/package.json +1 -0
  139. package/dist/esm/utils/createBufferingDecoder.d.ts +10 -0
  140. package/dist/esm/utils/createBufferingDecoder.js +30 -0
  141. package/dist/esm/utils/createBufferingDecoder.js.map +1 -0
  142. package/dist/esm/xz/Decoder.d.ts +21 -0
  143. package/dist/esm/xz/Decoder.js +313 -0
  144. package/dist/esm/xz/Decoder.js.map +1 -0
  145. package/package.json +75 -0
@@ -0,0 +1,114 @@
1
+ // BCJ (ARM 32-bit) filter codec - converts ARM branch instruction addresses
2
+ // This filter makes ARM executables more compressible by LZMA
3
+ //
4
+ // ARM branch instructions (BL) use relative addressing. The filter converts
5
+ // these to absolute addresses during compression, and back during decompression.
6
+ //
7
+ // Reference: https://github.com/tukaani-project/xz/blob/master/src/liblzma/simple/arm.c
8
+ //
9
+ // This implementation uses true streaming - processes data chunk by chunk.
10
+ import { allocBuffer, bufferFrom, Transform } from 'extract-base-iterator';
11
+ /**
12
+ * Core ARM BCJ conversion function (matches reference arm_code)
13
+ * Works for both encoding and decoding based on isEncoder flag
14
+ *
15
+ * ARM BL instruction format:
16
+ * - 4 bytes aligned
17
+ * - Byte pattern: XX XX XX EB (where EB = 0xEB opcode for BL)
18
+ * - Lower 24 bits are signed offset (in words, not bytes)
19
+ * - ARM pipeline adds +8 to the effective address
20
+ *
21
+ * @param nowPos - Current position in the overall stream
22
+ * @param isEncoder - true for encoding, false for decoding
23
+ * @param buffer - Buffer to process (modified in place)
24
+ * @param size - Size of buffer
25
+ * @returns Number of bytes processed
26
+ */ function armCode(nowPos, isEncoder, buffer, size) {
27
+ // Only process complete 4-byte groups
28
+ size = size & ~3;
29
+ let i = 0;
30
+ for(; i < size; i += 4){
31
+ // Check for BL instruction: byte 3 is 0xEB
32
+ if (buffer[i + 3] === 0xeb) {
33
+ // Read 24-bit value (little-endian in bytes 0-2)
34
+ let src = buffer[i + 2] << 16 | buffer[i + 1] << 8 | buffer[i + 0];
35
+ // Left shift by 2 (convert from words to bytes)
36
+ src <<= 2;
37
+ // Sign-extend from 26-bit to 32-bit
38
+ if (src & 0x02000000) {
39
+ src |= 0xfc000000;
40
+ }
41
+ src = src | 0; // Make signed 32-bit
42
+ let dest;
43
+ if (isEncoder) {
44
+ // Encoding: relative to absolute
45
+ // dest = now_pos + i + 8 + src
46
+ dest = nowPos + i + 8 + src;
47
+ } else {
48
+ // Decoding: absolute to relative
49
+ // dest = src - (now_pos + i + 8)
50
+ dest = src - (nowPos + i + 8);
51
+ }
52
+ // Right shift by 2 (convert back from bytes to words)
53
+ dest >>>= 2;
54
+ // Write back lower 24 bits (little-endian)
55
+ buffer[i + 2] = dest >>> 16 & 0xff;
56
+ buffer[i + 1] = dest >>> 8 & 0xff;
57
+ buffer[i + 0] = dest & 0xff;
58
+ }
59
+ }
60
+ return i;
61
+ }
62
+ /**
63
+ * Decode ARM BCJ filtered data (synchronous, for buffered use)
64
+ * Reverses the BCJ transformation by converting absolute addresses back to relative
65
+ *
66
+ * @param input - ARM BCJ filtered data
67
+ * @param _properties - Unused for ARM BCJ
68
+ * @param _unpackSize - Unused for ARM BCJ
69
+ * @returns Unfiltered data
70
+ */ export function decodeBcjArm(input, _properties, _unpackSize) {
71
+ const output = bufferFrom(input); // Copy since we modify in place
72
+ armCode(0, false, output, output.length);
73
+ return output;
74
+ }
75
+ /**
76
+ * Create a streaming ARM BCJ decoder Transform.
77
+ * Processes data in 4-byte aligned chunks.
78
+ */ export function createBcjArmDecoder(_properties, _unpackSize) {
79
+ let globalPos = 0; // Position in the overall stream (in bytes)
80
+ let pending = null; // Incomplete 4-byte group
81
+ const transform = new Transform({
82
+ transform: (chunk, _encoding, callback)=>{
83
+ // Combine pending bytes with new chunk
84
+ let data;
85
+ if (pending && pending.length > 0) {
86
+ data = Buffer.concat([
87
+ pending,
88
+ chunk
89
+ ]);
90
+ } else {
91
+ data = chunk;
92
+ }
93
+ // Process only complete 4-byte groups
94
+ const completeBytes = data.length & ~3;
95
+ if (completeBytes === 0) {
96
+ pending = data;
97
+ callback(null, allocBuffer(0));
98
+ return;
99
+ }
100
+ const output = bufferFrom(data.slice(0, completeBytes));
101
+ pending = data.length > completeBytes ? data.slice(completeBytes) : null;
102
+ armCode(globalPos, false, output, output.length);
103
+ globalPos += completeBytes;
104
+ callback(null, output);
105
+ },
106
+ flush: function(callback) {
107
+ if (pending && pending.length > 0) {
108
+ this.push(pending);
109
+ }
110
+ callback(null);
111
+ }
112
+ });
113
+ return transform;
114
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/filters/bcj/BcjArm.ts"],"sourcesContent":["// BCJ (ARM 32-bit) filter codec - converts ARM branch instruction addresses\n// This filter makes ARM executables more compressible by LZMA\n//\n// ARM branch instructions (BL) use relative addressing. The filter converts\n// these to absolute addresses during compression, and back during decompression.\n//\n// Reference: https://github.com/tukaani-project/xz/blob/master/src/liblzma/simple/arm.c\n//\n// This implementation uses true streaming - processes data chunk by chunk.\n\nimport { allocBuffer, bufferFrom, Transform } from 'extract-base-iterator';\n\n/**\n * Core ARM BCJ conversion function (matches reference arm_code)\n * Works for both encoding and decoding based on isEncoder flag\n *\n * ARM BL instruction format:\n * - 4 bytes aligned\n * - Byte pattern: XX XX XX EB (where EB = 0xEB opcode for BL)\n * - Lower 24 bits are signed offset (in words, not bytes)\n * - ARM pipeline adds +8 to the effective address\n *\n * @param nowPos - Current position in the overall stream\n * @param isEncoder - true for encoding, false for decoding\n * @param buffer - Buffer to process (modified in place)\n * @param size - Size of buffer\n * @returns Number of bytes processed\n */\nfunction armCode(nowPos: number, isEncoder: boolean, buffer: Buffer, size: number): number {\n // Only process complete 4-byte groups\n size = size & ~3;\n\n let i = 0;\n for (; i < size; i += 4) {\n // Check for BL instruction: byte 3 is 0xEB\n if (buffer[i + 3] === 0xeb) {\n // Read 24-bit value (little-endian in bytes 0-2)\n let src = (buffer[i + 2] << 16) | (buffer[i + 1] << 8) | buffer[i + 0];\n\n // Left shift by 2 (convert from words to bytes)\n src <<= 2;\n\n // Sign-extend from 26-bit to 32-bit\n if (src & 0x02000000) {\n src |= 0xfc000000;\n }\n src = src | 0; // Make signed 32-bit\n\n let dest: number;\n if (isEncoder) {\n // Encoding: relative to absolute\n // dest = now_pos + i + 8 + src\n dest = nowPos + i + 8 + src;\n } else {\n // Decoding: absolute to relative\n // dest = src - (now_pos + i + 8)\n dest = src - (nowPos + i + 8);\n }\n\n // Right shift by 2 (convert back from bytes to words)\n dest >>>= 2;\n\n // Write back lower 24 bits (little-endian)\n buffer[i + 2] = (dest >>> 16) & 0xff;\n buffer[i + 1] = (dest >>> 8) & 0xff;\n buffer[i + 0] = dest & 0xff;\n }\n }\n\n return i;\n}\n\n/**\n * Decode ARM BCJ filtered data (synchronous, for buffered use)\n * Reverses the BCJ transformation by converting absolute addresses back to relative\n *\n * @param input - ARM BCJ filtered data\n * @param _properties - Unused for ARM BCJ\n * @param _unpackSize - Unused for ARM BCJ\n * @returns Unfiltered data\n */\nexport function decodeBcjArm(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer {\n const output = bufferFrom(input); // Copy since we modify in place\n\n armCode(0, false, output, output.length);\n\n return output;\n}\n\n/**\n * Create a streaming ARM BCJ decoder Transform.\n * Processes data in 4-byte aligned chunks.\n */\nexport function createBcjArmDecoder(_properties?: Buffer, _unpackSize?: number): InstanceType<typeof Transform> {\n let globalPos = 0; // Position in the overall stream (in bytes)\n let pending: Buffer | null = null; // Incomplete 4-byte group\n\n const transform = new Transform({\n transform: (chunk: Buffer, _encoding: string, callback: (err?: Error | null, data?: Buffer) => void) => {\n // Combine pending bytes with new chunk\n let data: Buffer;\n if (pending && pending.length > 0) {\n data = Buffer.concat([pending, chunk]);\n } else {\n data = chunk;\n }\n\n // Process only complete 4-byte groups\n const completeBytes = data.length & ~3;\n if (completeBytes === 0) {\n pending = data;\n callback(null, allocBuffer(0));\n return;\n }\n\n const output = bufferFrom(data.slice(0, completeBytes));\n pending = data.length > completeBytes ? data.slice(completeBytes) : null;\n\n armCode(globalPos, false, output, output.length);\n globalPos += completeBytes;\n\n callback(null, output);\n },\n flush: function (this: InstanceType<typeof Transform>, callback: (err?: Error | null) => void) {\n if (pending && pending.length > 0) {\n this.push(pending);\n }\n callback(null);\n },\n });\n\n return transform;\n}\n"],"names":["allocBuffer","bufferFrom","Transform","armCode","nowPos","isEncoder","buffer","size","i","src","dest","decodeBcjArm","input","_properties","_unpackSize","output","length","createBcjArmDecoder","globalPos","pending","transform","chunk","_encoding","callback","data","Buffer","concat","completeBytes","slice","flush","push"],"mappings":"AAAA,4EAA4E;AAC5E,8DAA8D;AAC9D,EAAE;AACF,4EAA4E;AAC5E,iFAAiF;AACjF,EAAE;AACF,wFAAwF;AACxF,EAAE;AACF,2EAA2E;AAE3E,SAASA,WAAW,EAAEC,UAAU,EAAEC,SAAS,QAAQ,wBAAwB;AAE3E;;;;;;;;;;;;;;;CAeC,GACD,SAASC,QAAQC,MAAc,EAAEC,SAAkB,EAAEC,MAAc,EAAEC,IAAY;IAC/E,sCAAsC;IACtCA,OAAOA,OAAO,CAAC;IAEf,IAAIC,IAAI;IACR,MAAOA,IAAID,MAAMC,KAAK,EAAG;QACvB,2CAA2C;QAC3C,IAAIF,MAAM,CAACE,IAAI,EAAE,KAAK,MAAM;YAC1B,iDAAiD;YACjD,IAAIC,MAAM,AAACH,MAAM,CAACE,IAAI,EAAE,IAAI,KAAOF,MAAM,CAACE,IAAI,EAAE,IAAI,IAAKF,MAAM,CAACE,IAAI,EAAE;YAEtE,gDAAgD;YAChDC,QAAQ;YAER,oCAAoC;YACpC,IAAIA,MAAM,YAAY;gBACpBA,OAAO;YACT;YACAA,MAAMA,MAAM,GAAG,qBAAqB;YAEpC,IAAIC;YACJ,IAAIL,WAAW;gBACb,iCAAiC;gBACjC,+BAA+B;gBAC/BK,OAAON,SAASI,IAAI,IAAIC;YAC1B,OAAO;gBACL,iCAAiC;gBACjC,iCAAiC;gBACjCC,OAAOD,MAAOL,CAAAA,SAASI,IAAI,CAAA;YAC7B;YAEA,sDAAsD;YACtDE,UAAU;YAEV,2CAA2C;YAC3CJ,MAAM,CAACE,IAAI,EAAE,GAAG,AAACE,SAAS,KAAM;YAChCJ,MAAM,CAACE,IAAI,EAAE,GAAG,AAACE,SAAS,IAAK;YAC/BJ,MAAM,CAACE,IAAI,EAAE,GAAGE,OAAO;QACzB;IACF;IAEA,OAAOF;AACT;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASG,aAAaC,KAAa,EAAEC,WAAoB,EAAEC,WAAoB;IACpF,MAAMC,SAASd,WAAWW,QAAQ,gCAAgC;IAElET,QAAQ,GAAG,OAAOY,QAAQA,OAAOC,MAAM;IAEvC,OAAOD;AACT;AAEA;;;CAGC,GACD,OAAO,SAASE,oBAAoBJ,WAAoB,EAAEC,WAAoB;IAC5E,IAAII,YAAY,GAAG,4CAA4C;IAC/D,IAAIC,UAAyB,MAAM,0BAA0B;IAE7D,MAAMC,YAAY,IAAIlB,UAAU;QAC9BkB,WAAW,CAACC,OAAeC,WAAmBC;YAC5C,uCAAuC;YACvC,IAAIC;YACJ,IAAIL,WAAWA,QAAQH,MAAM,GAAG,GAAG;gBACjCQ,OAAOC,OAAOC,MAAM,CAAC;oBAACP;oBAASE;iBAAM;YACvC,OAAO;gBACLG,OAAOH;YACT;YAEA,sCAAsC;YACtC,MAAMM,gBAAgBH,KAAKR,MAAM,GAAG,CAAC;YACrC,IAAIW,kBAAkB,GAAG;gBACvBR,UAAUK;gBACVD,SAAS,MAAMvB,YAAY;gBAC3B;YACF;YAEA,MAAMe,SAASd,WAAWuB,KAAKI,KAAK,CAAC,GAAGD;YACxCR,UAAUK,KAAKR,MAAM,GAAGW,gBAAgBH,KAAKI,KAAK,CAACD,iBAAiB;YAEpExB,QAAQe,WAAW,OAAOH,QAAQA,OAAOC,MAAM;YAC/CE,aAAaS;YAEbJ,SAAS,MAAMR;QACjB;QACAc,OAAO,SAAgDN,QAAsC;YAC3F,IAAIJ,WAAWA,QAAQH,MAAM,GAAG,GAAG;gBACjC,IAAI,CAACc,IAAI,CAACX;YACZ;YACAI,SAAS;QACX;IACF;IAEA,OAAOH;AACT"}
@@ -0,0 +1,21 @@
1
+ import type { Transform } from 'stream';
2
+ /**
3
+ * Decode ARM64 BCJ filtered data
4
+ * Reverses the BCJ transformation by converting absolute addresses back to relative
5
+ *
6
+ * ARM64 B/BL instruction format (little-endian):
7
+ * - 4 bytes aligned
8
+ * - B: opcode 0x14 (000101xx)
9
+ * - BL: opcode 0x94 (100101xx)
10
+ * - Bits 0-25 are 26-bit signed offset (in words)
11
+ *
12
+ * @param input - ARM64 BCJ filtered data
13
+ * @param _properties - Unused for ARM64 BCJ
14
+ * @param _unpackSize - Unused for ARM64 BCJ
15
+ * @returns Unfiltered data
16
+ */
17
+ export declare function decodeBcjArm64(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer;
18
+ /**
19
+ * Create an ARM64 BCJ decoder Transform stream
20
+ */
21
+ export declare function createBcjArm64Decoder(properties?: Buffer, unpackSize?: number): Transform;
@@ -0,0 +1,57 @@
1
+ // BCJ (ARM64/AArch64) filter codec - converts ARM64 branch instruction addresses
2
+ // This filter makes ARM64 executables more compressible by LZMA
3
+ //
4
+ // ARM64 uses 32-bit fixed-width instructions. Branch instructions use 26-bit signed offsets.
5
+ //
6
+ // Reference: https://github.com/kornelski/7z/blob/main/C/Bra.c
7
+ import { bufferFrom } from 'extract-base-iterator';
8
+ import createBufferingDecoder from '../../utils/createBufferingDecoder.js';
9
+ /**
10
+ * Decode ARM64 BCJ filtered data
11
+ * Reverses the BCJ transformation by converting absolute addresses back to relative
12
+ *
13
+ * ARM64 B/BL instruction format (little-endian):
14
+ * - 4 bytes aligned
15
+ * - B: opcode 0x14 (000101xx)
16
+ * - BL: opcode 0x94 (100101xx)
17
+ * - Bits 0-25 are 26-bit signed offset (in words)
18
+ *
19
+ * @param input - ARM64 BCJ filtered data
20
+ * @param _properties - Unused for ARM64 BCJ
21
+ * @param _unpackSize - Unused for ARM64 BCJ
22
+ * @returns Unfiltered data
23
+ */ export function decodeBcjArm64(input, _properties, _unpackSize) {
24
+ const output = bufferFrom(input); // Copy since we modify in place
25
+ let pos = 0;
26
+ // Process 4-byte aligned positions
27
+ while(pos + 4 <= output.length){
28
+ // Read 32-bit value (little-endian)
29
+ let instr = output[pos] | output[pos + 1] << 8 | output[pos + 2] << 16 | output[pos + 3] << 24 >>> 0;
30
+ // Check for B/BL instruction: (instr & 0x7C000000) === 0x14000000
31
+ // This matches both B (0x14000000) and BL (0x94000000)
32
+ if ((instr & 0x7c000000) === 0x14000000) {
33
+ // Extract 26-bit offset
34
+ let addr = instr & 0x03ffffff;
35
+ // Sign-extend 26-bit to 32-bit
36
+ if (addr & 0x02000000) {
37
+ addr |= 0xfc000000;
38
+ }
39
+ // Convert absolute to relative: subtract current position (in words)
40
+ const relAddr = addr - (pos >>> 2);
41
+ // Clear old offset and write new one, preserve opcode
42
+ instr = instr & 0xfc000000 | relAddr & 0x03ffffff;
43
+ // Write back (little-endian)
44
+ output[pos] = instr & 0xff;
45
+ output[pos + 1] = instr >>> 8 & 0xff;
46
+ output[pos + 2] = instr >>> 16 & 0xff;
47
+ output[pos + 3] = instr >>> 24 & 0xff;
48
+ }
49
+ pos += 4;
50
+ }
51
+ return output;
52
+ }
53
+ /**
54
+ * Create an ARM64 BCJ decoder Transform stream
55
+ */ export function createBcjArm64Decoder(properties, unpackSize) {
56
+ return createBufferingDecoder(decodeBcjArm64, properties, unpackSize);
57
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/filters/bcj/BcjArm64.ts"],"sourcesContent":["// BCJ (ARM64/AArch64) filter codec - converts ARM64 branch instruction addresses\n// This filter makes ARM64 executables more compressible by LZMA\n//\n// ARM64 uses 32-bit fixed-width instructions. Branch instructions use 26-bit signed offsets.\n//\n// Reference: https://github.com/kornelski/7z/blob/main/C/Bra.c\n\nimport { bufferFrom } from 'extract-base-iterator';\nimport type { Transform } from 'stream';\nimport createBufferingDecoder from '../../utils/createBufferingDecoder.ts';\n\n/**\n * Decode ARM64 BCJ filtered data\n * Reverses the BCJ transformation by converting absolute addresses back to relative\n *\n * ARM64 B/BL instruction format (little-endian):\n * - 4 bytes aligned\n * - B: opcode 0x14 (000101xx)\n * - BL: opcode 0x94 (100101xx)\n * - Bits 0-25 are 26-bit signed offset (in words)\n *\n * @param input - ARM64 BCJ filtered data\n * @param _properties - Unused for ARM64 BCJ\n * @param _unpackSize - Unused for ARM64 BCJ\n * @returns Unfiltered data\n */\nexport function decodeBcjArm64(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer {\n const output = bufferFrom(input); // Copy since we modify in place\n let pos = 0;\n\n // Process 4-byte aligned positions\n while (pos + 4 <= output.length) {\n // Read 32-bit value (little-endian)\n let instr = output[pos] | (output[pos + 1] << 8) | (output[pos + 2] << 16) | ((output[pos + 3] << 24) >>> 0);\n\n // Check for B/BL instruction: (instr & 0x7C000000) === 0x14000000\n // This matches both B (0x14000000) and BL (0x94000000)\n if ((instr & 0x7c000000) === 0x14000000) {\n // Extract 26-bit offset\n let addr = instr & 0x03ffffff;\n\n // Sign-extend 26-bit to 32-bit\n if (addr & 0x02000000) {\n addr |= 0xfc000000;\n }\n\n // Convert absolute to relative: subtract current position (in words)\n const relAddr = addr - (pos >>> 2);\n\n // Clear old offset and write new one, preserve opcode\n instr = (instr & 0xfc000000) | (relAddr & 0x03ffffff);\n\n // Write back (little-endian)\n output[pos] = instr & 0xff;\n output[pos + 1] = (instr >>> 8) & 0xff;\n output[pos + 2] = (instr >>> 16) & 0xff;\n output[pos + 3] = (instr >>> 24) & 0xff;\n }\n\n pos += 4;\n }\n\n return output;\n}\n\n/**\n * Create an ARM64 BCJ decoder Transform stream\n */\nexport function createBcjArm64Decoder(properties?: Buffer, unpackSize?: number): Transform {\n return createBufferingDecoder(decodeBcjArm64, properties, unpackSize);\n}\n"],"names":["bufferFrom","createBufferingDecoder","decodeBcjArm64","input","_properties","_unpackSize","output","pos","length","instr","addr","relAddr","createBcjArm64Decoder","properties","unpackSize"],"mappings":"AAAA,iFAAiF;AACjF,gEAAgE;AAChE,EAAE;AACF,6FAA6F;AAC7F,EAAE;AACF,+DAA+D;AAE/D,SAASA,UAAU,QAAQ,wBAAwB;AAEnD,OAAOC,4BAA4B,wCAAwC;AAE3E;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASC,eAAeC,KAAa,EAAEC,WAAoB,EAAEC,WAAoB;IACtF,MAAMC,SAASN,WAAWG,QAAQ,gCAAgC;IAClE,IAAII,MAAM;IAEV,mCAAmC;IACnC,MAAOA,MAAM,KAAKD,OAAOE,MAAM,CAAE;QAC/B,oCAAoC;QACpC,IAAIC,QAAQH,MAAM,CAACC,IAAI,GAAID,MAAM,CAACC,MAAM,EAAE,IAAI,IAAMD,MAAM,CAACC,MAAM,EAAE,IAAI,KAAO,AAACD,MAAM,CAACC,MAAM,EAAE,IAAI,OAAQ;QAE1G,kEAAkE;QAClE,uDAAuD;QACvD,IAAI,AAACE,CAAAA,QAAQ,UAAS,MAAO,YAAY;YACvC,wBAAwB;YACxB,IAAIC,OAAOD,QAAQ;YAEnB,+BAA+B;YAC/B,IAAIC,OAAO,YAAY;gBACrBA,QAAQ;YACV;YAEA,qEAAqE;YACrE,MAAMC,UAAUD,OAAQH,CAAAA,QAAQ,CAAA;YAEhC,sDAAsD;YACtDE,QAAQ,AAACA,QAAQ,aAAeE,UAAU;YAE1C,6BAA6B;YAC7BL,MAAM,CAACC,IAAI,GAAGE,QAAQ;YACtBH,MAAM,CAACC,MAAM,EAAE,GAAG,AAACE,UAAU,IAAK;YAClCH,MAAM,CAACC,MAAM,EAAE,GAAG,AAACE,UAAU,KAAM;YACnCH,MAAM,CAACC,MAAM,EAAE,GAAG,AAACE,UAAU,KAAM;QACrC;QAEAF,OAAO;IACT;IAEA,OAAOD;AACT;AAEA;;CAEC,GACD,OAAO,SAASM,sBAAsBC,UAAmB,EAAEC,UAAmB;IAC5E,OAAOb,uBAAuBC,gBAAgBW,YAAYC;AAC5D"}
@@ -0,0 +1,19 @@
1
+ import type { Transform } from 'stream';
2
+ /**
3
+ * Decode ARM Thumb BCJ filtered data
4
+ * Reverses the BCJ transformation by converting absolute addresses back to relative
5
+ *
6
+ * ARM Thumb BL instruction format (2 x 16-bit):
7
+ * - First half-word: 1111 0xxx xxxx xxxx (high bits of offset)
8
+ * - Second half-word: 1111 1xxx xxxx xxxx (low bits of offset)
9
+ *
10
+ * @param input - ARM Thumb BCJ filtered data
11
+ * @param _properties - Unused for ARM Thumb BCJ
12
+ * @param _unpackSize - Unused for ARM Thumb BCJ
13
+ * @returns Unfiltered data
14
+ */
15
+ export declare function decodeBcjArmt(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer;
16
+ /**
17
+ * Create an ARM Thumb BCJ decoder Transform stream
18
+ */
19
+ export declare function createBcjArmtDecoder(properties?: Buffer, unpackSize?: number): Transform;
@@ -0,0 +1,66 @@
1
+ // BCJ (ARM Thumb) filter codec - converts ARM Thumb branch instruction addresses
2
+ // This filter makes ARM Thumb executables more compressible by LZMA
3
+ //
4
+ // ARM Thumb uses 16-bit instructions, but BL (branch with link) spans two 16-bit words.
5
+ // The filter converts relative addresses to absolute during compression.
6
+ //
7
+ // Reference: https://github.com/kornelski/7z/blob/main/C/Bra.c
8
+ import { bufferFrom } from 'extract-base-iterator';
9
+ import createBufferingDecoder from '../../utils/createBufferingDecoder.js';
10
+ /**
11
+ * Decode ARM Thumb BCJ filtered data
12
+ * Reverses the BCJ transformation by converting absolute addresses back to relative
13
+ *
14
+ * ARM Thumb BL instruction format (2 x 16-bit):
15
+ * - First half-word: 1111 0xxx xxxx xxxx (high bits of offset)
16
+ * - Second half-word: 1111 1xxx xxxx xxxx (low bits of offset)
17
+ *
18
+ * @param input - ARM Thumb BCJ filtered data
19
+ * @param _properties - Unused for ARM Thumb BCJ
20
+ * @param _unpackSize - Unused for ARM Thumb BCJ
21
+ * @returns Unfiltered data
22
+ */ export function decodeBcjArmt(input, _properties, _unpackSize) {
23
+ const output = bufferFrom(input); // Copy since we modify in place
24
+ let pos = 0;
25
+ // Process 2-byte aligned positions
26
+ while(pos + 4 <= output.length){
27
+ // Read two 16-bit values (little-endian)
28
+ const w0 = output[pos] | output[pos + 1] << 8;
29
+ const w1 = output[pos + 2] | output[pos + 3] << 8;
30
+ // Check for BL instruction pair:
31
+ // First word: 0xF000-0xF7FF (1111 0xxx xxxx xxxx)
32
+ // Second word: 0xF800-0xFFFF (1111 1xxx xxxx xxxx)
33
+ if ((w0 & 0xf800) === 0xf000 && (w1 & 0xf800) === 0xf800) {
34
+ // Extract and combine the offset parts
35
+ // High 11 bits from w0, low 11 bits from w1
36
+ const hi = w0 & 0x7ff;
37
+ const lo = w1 & 0x7ff;
38
+ // Combine into 22-bit offset (in half-words)
39
+ let addr = hi << 11 | lo;
40
+ // Sign-extend 22-bit to 32-bit
41
+ if (addr & 0x200000) {
42
+ addr |= 0xffc00000;
43
+ }
44
+ // Convert absolute to relative:
45
+ // Subtract current position (in half-words, so divide by 2)
46
+ // Thumb PC is 2 half-words (4 bytes) ahead
47
+ const relAddr = addr - (pos >>> 1);
48
+ // Write back
49
+ const newHi = relAddr >>> 11 & 0x7ff;
50
+ const newLo = relAddr & 0x7ff;
51
+ output[pos] = newHi & 0xff;
52
+ output[pos + 1] = 0xf0 | newHi >>> 8 & 0x07;
53
+ output[pos + 2] = newLo & 0xff;
54
+ output[pos + 3] = 0xf8 | newLo >>> 8 & 0x07;
55
+ pos += 4;
56
+ } else {
57
+ pos += 2;
58
+ }
59
+ }
60
+ return output;
61
+ }
62
+ /**
63
+ * Create an ARM Thumb BCJ decoder Transform stream
64
+ */ export function createBcjArmtDecoder(properties, unpackSize) {
65
+ return createBufferingDecoder(decodeBcjArmt, properties, unpackSize);
66
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/filters/bcj/BcjArmt.ts"],"sourcesContent":["// BCJ (ARM Thumb) filter codec - converts ARM Thumb branch instruction addresses\n// This filter makes ARM Thumb executables more compressible by LZMA\n//\n// ARM Thumb uses 16-bit instructions, but BL (branch with link) spans two 16-bit words.\n// The filter converts relative addresses to absolute during compression.\n//\n// Reference: https://github.com/kornelski/7z/blob/main/C/Bra.c\n\nimport { bufferFrom } from 'extract-base-iterator';\nimport type { Transform } from 'stream';\nimport createBufferingDecoder from '../../utils/createBufferingDecoder.ts';\n\n/**\n * Decode ARM Thumb BCJ filtered data\n * Reverses the BCJ transformation by converting absolute addresses back to relative\n *\n * ARM Thumb BL instruction format (2 x 16-bit):\n * - First half-word: 1111 0xxx xxxx xxxx (high bits of offset)\n * - Second half-word: 1111 1xxx xxxx xxxx (low bits of offset)\n *\n * @param input - ARM Thumb BCJ filtered data\n * @param _properties - Unused for ARM Thumb BCJ\n * @param _unpackSize - Unused for ARM Thumb BCJ\n * @returns Unfiltered data\n */\nexport function decodeBcjArmt(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer {\n const output = bufferFrom(input); // Copy since we modify in place\n let pos = 0;\n\n // Process 2-byte aligned positions\n while (pos + 4 <= output.length) {\n // Read two 16-bit values (little-endian)\n const w0 = output[pos] | (output[pos + 1] << 8);\n const w1 = output[pos + 2] | (output[pos + 3] << 8);\n\n // Check for BL instruction pair:\n // First word: 0xF000-0xF7FF (1111 0xxx xxxx xxxx)\n // Second word: 0xF800-0xFFFF (1111 1xxx xxxx xxxx)\n if ((w0 & 0xf800) === 0xf000 && (w1 & 0xf800) === 0xf800) {\n // Extract and combine the offset parts\n // High 11 bits from w0, low 11 bits from w1\n const hi = w0 & 0x7ff;\n const lo = w1 & 0x7ff;\n\n // Combine into 22-bit offset (in half-words)\n let addr = (hi << 11) | lo;\n\n // Sign-extend 22-bit to 32-bit\n if (addr & 0x200000) {\n addr |= 0xffc00000;\n }\n\n // Convert absolute to relative:\n // Subtract current position (in half-words, so divide by 2)\n // Thumb PC is 2 half-words (4 bytes) ahead\n const relAddr = addr - (pos >>> 1);\n\n // Write back\n const newHi = (relAddr >>> 11) & 0x7ff;\n const newLo = relAddr & 0x7ff;\n\n output[pos] = newHi & 0xff;\n output[pos + 1] = 0xf0 | ((newHi >>> 8) & 0x07);\n output[pos + 2] = newLo & 0xff;\n output[pos + 3] = 0xf8 | ((newLo >>> 8) & 0x07);\n\n pos += 4;\n } else {\n pos += 2;\n }\n }\n\n return output;\n}\n\n/**\n * Create an ARM Thumb BCJ decoder Transform stream\n */\nexport function createBcjArmtDecoder(properties?: Buffer, unpackSize?: number): Transform {\n return createBufferingDecoder(decodeBcjArmt, properties, unpackSize);\n}\n"],"names":["bufferFrom","createBufferingDecoder","decodeBcjArmt","input","_properties","_unpackSize","output","pos","length","w0","w1","hi","lo","addr","relAddr","newHi","newLo","createBcjArmtDecoder","properties","unpackSize"],"mappings":"AAAA,iFAAiF;AACjF,oEAAoE;AACpE,EAAE;AACF,wFAAwF;AACxF,yEAAyE;AACzE,EAAE;AACF,+DAA+D;AAE/D,SAASA,UAAU,QAAQ,wBAAwB;AAEnD,OAAOC,4BAA4B,wCAAwC;AAE3E;;;;;;;;;;;;CAYC,GACD,OAAO,SAASC,cAAcC,KAAa,EAAEC,WAAoB,EAAEC,WAAoB;IACrF,MAAMC,SAASN,WAAWG,QAAQ,gCAAgC;IAClE,IAAII,MAAM;IAEV,mCAAmC;IACnC,MAAOA,MAAM,KAAKD,OAAOE,MAAM,CAAE;QAC/B,yCAAyC;QACzC,MAAMC,KAAKH,MAAM,CAACC,IAAI,GAAID,MAAM,CAACC,MAAM,EAAE,IAAI;QAC7C,MAAMG,KAAKJ,MAAM,CAACC,MAAM,EAAE,GAAID,MAAM,CAACC,MAAM,EAAE,IAAI;QAEjD,iCAAiC;QACjC,kDAAkD;QAClD,mDAAmD;QACnD,IAAI,AAACE,CAAAA,KAAK,MAAK,MAAO,UAAU,AAACC,CAAAA,KAAK,MAAK,MAAO,QAAQ;YACxD,uCAAuC;YACvC,4CAA4C;YAC5C,MAAMC,KAAKF,KAAK;YAChB,MAAMG,KAAKF,KAAK;YAEhB,6CAA6C;YAC7C,IAAIG,OAAO,AAACF,MAAM,KAAMC;YAExB,+BAA+B;YAC/B,IAAIC,OAAO,UAAU;gBACnBA,QAAQ;YACV;YAEA,gCAAgC;YAChC,4DAA4D;YAC5D,2CAA2C;YAC3C,MAAMC,UAAUD,OAAQN,CAAAA,QAAQ,CAAA;YAEhC,aAAa;YACb,MAAMQ,QAAQ,AAACD,YAAY,KAAM;YACjC,MAAME,QAAQF,UAAU;YAExBR,MAAM,CAACC,IAAI,GAAGQ,QAAQ;YACtBT,MAAM,CAACC,MAAM,EAAE,GAAG,OAAQ,AAACQ,UAAU,IAAK;YAC1CT,MAAM,CAACC,MAAM,EAAE,GAAGS,QAAQ;YAC1BV,MAAM,CAACC,MAAM,EAAE,GAAG,OAAQ,AAACS,UAAU,IAAK;YAE1CT,OAAO;QACT,OAAO;YACLA,OAAO;QACT;IACF;IAEA,OAAOD;AACT;AAEA;;CAEC,GACD,OAAO,SAASW,qBAAqBC,UAAmB,EAAEC,UAAmB;IAC3E,OAAOlB,uBAAuBC,eAAegB,YAAYC;AAC3D"}
@@ -0,0 +1,15 @@
1
+ import type { Transform } from 'stream';
2
+ /**
3
+ * Decode IA64 BCJ filtered data
4
+ * Reverses the BCJ transformation by converting absolute addresses back to relative
5
+ *
6
+ * @param input - IA64 BCJ filtered data
7
+ * @param _properties - Unused for IA64 BCJ
8
+ * @param _unpackSize - Unused for IA64 BCJ
9
+ * @returns Unfiltered data
10
+ */
11
+ export declare function decodeBcjIa64(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer;
12
+ /**
13
+ * Create an IA64 BCJ decoder Transform stream
14
+ */
15
+ export declare function createBcjIa64Decoder(properties?: Buffer, unpackSize?: number): Transform;
@@ -0,0 +1,127 @@
1
+ // BCJ (IA64/Itanium) filter codec - converts IA64 branch instruction addresses
2
+ // This filter makes IA64 executables more compressible by LZMA
3
+ //
4
+ // IA64 uses 128-bit instruction bundles with 3 instructions per bundle.
5
+ // Branch instructions use 21-bit signed offsets (in bundles).
6
+ //
7
+ // Reference: https://github.com/kornelski/7z/blob/main/C/Bra.c
8
+ import { bufferFrom } from 'extract-base-iterator';
9
+ import createBufferingDecoder from '../../utils/createBufferingDecoder.js';
10
+ // IA64 branch instruction slot mask
11
+ // Each bundle has a 5-bit template and 3 x 41-bit instruction slots
12
+ const kBranchTable = [
13
+ 0,
14
+ 0,
15
+ 0,
16
+ 0,
17
+ 0,
18
+ 0,
19
+ 0,
20
+ 0,
21
+ 0,
22
+ 0,
23
+ 0,
24
+ 0,
25
+ 0,
26
+ 0,
27
+ 0,
28
+ 0,
29
+ 4,
30
+ 4,
31
+ 6,
32
+ 6,
33
+ 0,
34
+ 0,
35
+ 7,
36
+ 7,
37
+ 4,
38
+ 4,
39
+ 0,
40
+ 0,
41
+ 4,
42
+ 4,
43
+ 0,
44
+ 0
45
+ ];
46
+ /**
47
+ * Decode IA64 BCJ filtered data
48
+ * Reverses the BCJ transformation by converting absolute addresses back to relative
49
+ *
50
+ * @param input - IA64 BCJ filtered data
51
+ * @param _properties - Unused for IA64 BCJ
52
+ * @param _unpackSize - Unused for IA64 BCJ
53
+ * @returns Unfiltered data
54
+ */ export function decodeBcjIa64(input, _properties, _unpackSize) {
55
+ const output = bufferFrom(input); // Copy since we modify in place
56
+ let pos = 0;
57
+ // Process 16-byte aligned bundles
58
+ while(pos + 16 <= output.length){
59
+ // Get template (low 5 bits of first byte)
60
+ const template = output[pos] & 0x1f;
61
+ const mask = kBranchTable[template];
62
+ // Check each instruction slot (3 slots per bundle)
63
+ for(let slot = 0; slot < 3; slot++){
64
+ if ((mask & 1 << slot) === 0) {
65
+ continue;
66
+ }
67
+ // Calculate bit position for this slot
68
+ // Slot 0: bits 5-45, Slot 1: bits 46-86, Slot 2: bits 87-127
69
+ const bitPos = 5 + slot * 41;
70
+ const bytePos = bitPos >>> 3;
71
+ const bitOffset = bitPos & 7;
72
+ // Read 8 bytes to get the instruction (may span bytes)
73
+ // We need at least 6 bytes for a 41-bit instruction
74
+ if (pos + bytePos + 6 > output.length) {
75
+ break;
76
+ }
77
+ // Extract instruction bytes
78
+ const instr0 = output[pos + bytePos];
79
+ const instr1 = output[pos + bytePos + 1];
80
+ const instr2 = output[pos + bytePos + 2];
81
+ const instr3 = output[pos + bytePos + 3];
82
+ const instr4 = output[pos + bytePos + 4];
83
+ const instr5 = output[pos + bytePos + 5];
84
+ // Build instruction value (we only need the immediate field)
85
+ // The immediate is in bits 13-32 of the instruction (20 bits)
86
+ // Plus bit 36 as the sign bit
87
+ // For decoding, we extract the address that was encoded and convert back
88
+ let instrLo = instr0 >>> bitOffset | instr1 << 8 - bitOffset | instr2 << 16 - bitOffset | instr3 << 24 - bitOffset;
89
+ let instrHi = instr4 >>> bitOffset | instr5 << 8 - bitOffset;
90
+ // Check opcode for branch (opcode 4 or 5 in bits 37-40)
91
+ const opcode = instrHi >>> 37 - 32 - bitOffset & 0xf;
92
+ if (opcode !== 4 && opcode !== 5) {
93
+ continue;
94
+ }
95
+ // Extract 21-bit immediate (bits 13-32 + sign bit 36)
96
+ const imm20 = instrLo >>> 13 & 0xfffff;
97
+ const sign = instrHi >>> 36 - 32 & 1;
98
+ // Combine into 21-bit signed value
99
+ let addr = imm20 | sign << 20;
100
+ if (sign) {
101
+ addr |= 0xffe00000; // Sign-extend
102
+ }
103
+ // Convert absolute to relative: subtract current position (in bundles)
104
+ const relAddr = addr - (pos >>> 4);
105
+ // Write back
106
+ const newImm20 = relAddr & 0xfffff;
107
+ const newSign = relAddr >>> 20 & 1;
108
+ // Clear old immediate and write new one
109
+ instrLo = instrLo & ~(0xfffff << 13) | newImm20 << 13;
110
+ instrHi = instrHi & ~(1 << 36 - 32) | newSign << 36 - 32;
111
+ // Write back bytes
112
+ output[pos + bytePos] = output[pos + bytePos] & (1 << bitOffset) - 1 | (instrLo & 0xff) << bitOffset;
113
+ output[pos + bytePos + 1] = instrLo >>> 8 - bitOffset & 0xff;
114
+ output[pos + bytePos + 2] = instrLo >>> 16 - bitOffset & 0xff;
115
+ output[pos + bytePos + 3] = instrLo >>> 24 - bitOffset & 0xff;
116
+ output[pos + bytePos + 4] = instrLo >>> 32 - bitOffset & (1 << bitOffset) - 1 | (instrHi & 0xff) << bitOffset;
117
+ output[pos + bytePos + 5] = output[pos + bytePos + 5] & ~((1 << bitOffset) - 1) | instrHi >>> 8 - bitOffset & (1 << bitOffset) - 1;
118
+ }
119
+ pos += 16;
120
+ }
121
+ return output;
122
+ }
123
+ /**
124
+ * Create an IA64 BCJ decoder Transform stream
125
+ */ export function createBcjIa64Decoder(properties, unpackSize) {
126
+ return createBufferingDecoder(decodeBcjIa64, properties, unpackSize);
127
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/filters/bcj/BcjIa64.ts"],"sourcesContent":["// BCJ (IA64/Itanium) filter codec - converts IA64 branch instruction addresses\n// This filter makes IA64 executables more compressible by LZMA\n//\n// IA64 uses 128-bit instruction bundles with 3 instructions per bundle.\n// Branch instructions use 21-bit signed offsets (in bundles).\n//\n// Reference: https://github.com/kornelski/7z/blob/main/C/Bra.c\n\nimport { bufferFrom } from 'extract-base-iterator';\nimport type { Transform } from 'stream';\nimport createBufferingDecoder from '../../utils/createBufferingDecoder.ts';\n\n// IA64 branch instruction slot mask\n// Each bundle has a 5-bit template and 3 x 41-bit instruction slots\nconst kBranchTable = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0, 7, 7, 4, 4, 0, 0, 4, 4, 0, 0];\n\n/**\n * Decode IA64 BCJ filtered data\n * Reverses the BCJ transformation by converting absolute addresses back to relative\n *\n * @param input - IA64 BCJ filtered data\n * @param _properties - Unused for IA64 BCJ\n * @param _unpackSize - Unused for IA64 BCJ\n * @returns Unfiltered data\n */\nexport function decodeBcjIa64(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer {\n const output = bufferFrom(input); // Copy since we modify in place\n let pos = 0;\n\n // Process 16-byte aligned bundles\n while (pos + 16 <= output.length) {\n // Get template (low 5 bits of first byte)\n const template = output[pos] & 0x1f;\n const mask = kBranchTable[template];\n\n // Check each instruction slot (3 slots per bundle)\n for (let slot = 0; slot < 3; slot++) {\n if ((mask & (1 << slot)) === 0) {\n continue;\n }\n\n // Calculate bit position for this slot\n // Slot 0: bits 5-45, Slot 1: bits 46-86, Slot 2: bits 87-127\n const bitPos = 5 + slot * 41;\n const bytePos = bitPos >>> 3;\n const bitOffset = bitPos & 7;\n\n // Read 8 bytes to get the instruction (may span bytes)\n // We need at least 6 bytes for a 41-bit instruction\n if (pos + bytePos + 6 > output.length) {\n break;\n }\n\n // Extract instruction bytes\n const instr0 = output[pos + bytePos];\n const instr1 = output[pos + bytePos + 1];\n const instr2 = output[pos + bytePos + 2];\n const instr3 = output[pos + bytePos + 3];\n const instr4 = output[pos + bytePos + 4];\n const instr5 = output[pos + bytePos + 5];\n\n // Build instruction value (we only need the immediate field)\n // The immediate is in bits 13-32 of the instruction (20 bits)\n // Plus bit 36 as the sign bit\n\n // For decoding, we extract the address that was encoded and convert back\n let instrLo = (instr0 >>> bitOffset) | (instr1 << (8 - bitOffset)) | (instr2 << (16 - bitOffset)) | (instr3 << (24 - bitOffset));\n\n let instrHi = (instr4 >>> bitOffset) | (instr5 << (8 - bitOffset));\n\n // Check opcode for branch (opcode 4 or 5 in bits 37-40)\n const opcode = (instrHi >>> (37 - 32 - bitOffset)) & 0xf;\n if (opcode !== 4 && opcode !== 5) {\n continue;\n }\n\n // Extract 21-bit immediate (bits 13-32 + sign bit 36)\n const imm20 = (instrLo >>> 13) & 0xfffff;\n const sign = (instrHi >>> (36 - 32)) & 1;\n\n // Combine into 21-bit signed value\n let addr = imm20 | (sign << 20);\n if (sign) {\n addr |= 0xffe00000; // Sign-extend\n }\n\n // Convert absolute to relative: subtract current position (in bundles)\n const relAddr = addr - (pos >>> 4);\n\n // Write back\n const newImm20 = relAddr & 0xfffff;\n const newSign = (relAddr >>> 20) & 1;\n\n // Clear old immediate and write new one\n instrLo = (instrLo & ~(0xfffff << 13)) | (newImm20 << 13);\n instrHi = (instrHi & ~(1 << (36 - 32))) | (newSign << (36 - 32));\n\n // Write back bytes\n output[pos + bytePos] = (output[pos + bytePos] & ((1 << bitOffset) - 1)) | ((instrLo & 0xff) << bitOffset);\n output[pos + bytePos + 1] = (instrLo >>> (8 - bitOffset)) & 0xff;\n output[pos + bytePos + 2] = (instrLo >>> (16 - bitOffset)) & 0xff;\n output[pos + bytePos + 3] = (instrLo >>> (24 - bitOffset)) & 0xff;\n output[pos + bytePos + 4] = ((instrLo >>> (32 - bitOffset)) & ((1 << bitOffset) - 1)) | ((instrHi & 0xff) << bitOffset);\n output[pos + bytePos + 5] = (output[pos + bytePos + 5] & ~((1 << bitOffset) - 1)) | ((instrHi >>> (8 - bitOffset)) & ((1 << bitOffset) - 1));\n }\n\n pos += 16;\n }\n\n return output;\n}\n\n/**\n * Create an IA64 BCJ decoder Transform stream\n */\nexport function createBcjIa64Decoder(properties?: Buffer, unpackSize?: number): Transform {\n return createBufferingDecoder(decodeBcjIa64, properties, unpackSize);\n}\n"],"names":["bufferFrom","createBufferingDecoder","kBranchTable","decodeBcjIa64","input","_properties","_unpackSize","output","pos","length","template","mask","slot","bitPos","bytePos","bitOffset","instr0","instr1","instr2","instr3","instr4","instr5","instrLo","instrHi","opcode","imm20","sign","addr","relAddr","newImm20","newSign","createBcjIa64Decoder","properties","unpackSize"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { Transform } from 'stream';
2
+ /**
3
+ * Decode PowerPC BCJ filtered data
4
+ * Reverses the BCJ transformation by converting absolute addresses back to relative
5
+ *
6
+ * PowerPC B/BL instruction format (big-endian):
7
+ * - 4 bytes aligned
8
+ * - Opcode 0x48 in high byte with AA=0, LK=1 (0x48000001 mask 0xFC000003)
9
+ * - Bits 6-29 are 24-bit signed offset (in words)
10
+ *
11
+ * @param input - PowerPC BCJ filtered data
12
+ * @param _properties - Unused for PowerPC BCJ
13
+ * @param _unpackSize - Unused for PowerPC BCJ
14
+ * @returns Unfiltered data
15
+ */
16
+ export declare function decodeBcjPpc(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer;
17
+ /**
18
+ * Create a PowerPC BCJ decoder Transform stream
19
+ */
20
+ export declare function createBcjPpcDecoder(properties?: Buffer, unpackSize?: number): Transform;
@@ -0,0 +1,55 @@
1
+ // BCJ (PowerPC) filter codec - converts PowerPC branch instruction addresses
2
+ // This filter makes PowerPC executables more compressible by LZMA
3
+ //
4
+ // PowerPC is big-endian. Branch instructions use 26-bit signed offsets.
5
+ //
6
+ // Reference: https://github.com/kornelski/7z/blob/main/C/Bra.c
7
+ import { bufferFrom } from 'extract-base-iterator';
8
+ import createBufferingDecoder from '../../utils/createBufferingDecoder.js';
9
+ /**
10
+ * Decode PowerPC BCJ filtered data
11
+ * Reverses the BCJ transformation by converting absolute addresses back to relative
12
+ *
13
+ * PowerPC B/BL instruction format (big-endian):
14
+ * - 4 bytes aligned
15
+ * - Opcode 0x48 in high byte with AA=0, LK=1 (0x48000001 mask 0xFC000003)
16
+ * - Bits 6-29 are 24-bit signed offset (in words)
17
+ *
18
+ * @param input - PowerPC BCJ filtered data
19
+ * @param _properties - Unused for PowerPC BCJ
20
+ * @param _unpackSize - Unused for PowerPC BCJ
21
+ * @returns Unfiltered data
22
+ */ export function decodeBcjPpc(input, _properties, _unpackSize) {
23
+ const output = bufferFrom(input); // Copy since we modify in place
24
+ let pos = 0;
25
+ // Process 4-byte aligned positions
26
+ while(pos + 4 <= output.length){
27
+ // Read 32-bit value (big-endian)
28
+ let instr = output[pos] << 24 | output[pos + 1] << 16 | output[pos + 2] << 8 | output[pos + 3];
29
+ // Check for B/BL instruction: (instr & 0xFC000003) === 0x48000001
30
+ if ((instr & 0xfc000003) === 0x48000001) {
31
+ // Extract 26-bit offset (bits 2-27, the LI field)
32
+ let addr = instr & 0x03fffffc;
33
+ // Sign-extend 26-bit to 32-bit
34
+ if (addr & 0x02000000) {
35
+ addr |= 0xfc000000;
36
+ }
37
+ // Convert absolute to relative: subtract current position
38
+ const relAddr = addr - pos;
39
+ // Clear old offset and write new one
40
+ instr = instr & 0xfc000003 | relAddr & 0x03fffffc;
41
+ // Write back (big-endian)
42
+ output[pos] = instr >>> 24 & 0xff;
43
+ output[pos + 1] = instr >>> 16 & 0xff;
44
+ output[pos + 2] = instr >>> 8 & 0xff;
45
+ output[pos + 3] = instr & 0xff;
46
+ }
47
+ pos += 4;
48
+ }
49
+ return output;
50
+ }
51
+ /**
52
+ * Create a PowerPC BCJ decoder Transform stream
53
+ */ export function createBcjPpcDecoder(properties, unpackSize) {
54
+ return createBufferingDecoder(decodeBcjPpc, properties, unpackSize);
55
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/filters/bcj/BcjPpc.ts"],"sourcesContent":["// BCJ (PowerPC) filter codec - converts PowerPC branch instruction addresses\n// This filter makes PowerPC executables more compressible by LZMA\n//\n// PowerPC is big-endian. Branch instructions use 26-bit signed offsets.\n//\n// Reference: https://github.com/kornelski/7z/blob/main/C/Bra.c\n\nimport { bufferFrom } from 'extract-base-iterator';\nimport type { Transform } from 'stream';\nimport createBufferingDecoder from '../../utils/createBufferingDecoder.ts';\n\n/**\n * Decode PowerPC BCJ filtered data\n * Reverses the BCJ transformation by converting absolute addresses back to relative\n *\n * PowerPC B/BL instruction format (big-endian):\n * - 4 bytes aligned\n * - Opcode 0x48 in high byte with AA=0, LK=1 (0x48000001 mask 0xFC000003)\n * - Bits 6-29 are 24-bit signed offset (in words)\n *\n * @param input - PowerPC BCJ filtered data\n * @param _properties - Unused for PowerPC BCJ\n * @param _unpackSize - Unused for PowerPC BCJ\n * @returns Unfiltered data\n */\nexport function decodeBcjPpc(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer {\n const output = bufferFrom(input); // Copy since we modify in place\n let pos = 0;\n\n // Process 4-byte aligned positions\n while (pos + 4 <= output.length) {\n // Read 32-bit value (big-endian)\n let instr = (output[pos] << 24) | (output[pos + 1] << 16) | (output[pos + 2] << 8) | output[pos + 3];\n\n // Check for B/BL instruction: (instr & 0xFC000003) === 0x48000001\n if ((instr & 0xfc000003) === 0x48000001) {\n // Extract 26-bit offset (bits 2-27, the LI field)\n let addr = instr & 0x03fffffc;\n\n // Sign-extend 26-bit to 32-bit\n if (addr & 0x02000000) {\n addr |= 0xfc000000;\n }\n\n // Convert absolute to relative: subtract current position\n const relAddr = addr - pos;\n\n // Clear old offset and write new one\n instr = (instr & 0xfc000003) | (relAddr & 0x03fffffc);\n\n // Write back (big-endian)\n output[pos] = (instr >>> 24) & 0xff;\n output[pos + 1] = (instr >>> 16) & 0xff;\n output[pos + 2] = (instr >>> 8) & 0xff;\n output[pos + 3] = instr & 0xff;\n }\n pos += 4;\n }\n\n return output;\n}\n\n/**\n * Create a PowerPC BCJ decoder Transform stream\n */\nexport function createBcjPpcDecoder(properties?: Buffer, unpackSize?: number): Transform {\n return createBufferingDecoder(decodeBcjPpc, properties, unpackSize);\n}\n"],"names":["bufferFrom","createBufferingDecoder","decodeBcjPpc","input","_properties","_unpackSize","output","pos","length","instr","addr","relAddr","createBcjPpcDecoder","properties","unpackSize"],"mappings":"AAAA,6EAA6E;AAC7E,kEAAkE;AAClE,EAAE;AACF,wEAAwE;AACxE,EAAE;AACF,+DAA+D;AAE/D,SAASA,UAAU,QAAQ,wBAAwB;AAEnD,OAAOC,4BAA4B,wCAAwC;AAE3E;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASC,aAAaC,KAAa,EAAEC,WAAoB,EAAEC,WAAoB;IACpF,MAAMC,SAASN,WAAWG,QAAQ,gCAAgC;IAClE,IAAII,MAAM;IAEV,mCAAmC;IACnC,MAAOA,MAAM,KAAKD,OAAOE,MAAM,CAAE;QAC/B,iCAAiC;QACjC,IAAIC,QAAQ,AAACH,MAAM,CAACC,IAAI,IAAI,KAAOD,MAAM,CAACC,MAAM,EAAE,IAAI,KAAOD,MAAM,CAACC,MAAM,EAAE,IAAI,IAAKD,MAAM,CAACC,MAAM,EAAE;QAEpG,kEAAkE;QAClE,IAAI,AAACE,CAAAA,QAAQ,UAAS,MAAO,YAAY;YACvC,kDAAkD;YAClD,IAAIC,OAAOD,QAAQ;YAEnB,+BAA+B;YAC/B,IAAIC,OAAO,YAAY;gBACrBA,QAAQ;YACV;YAEA,0DAA0D;YAC1D,MAAMC,UAAUD,OAAOH;YAEvB,qCAAqC;YACrCE,QAAQ,AAACA,QAAQ,aAAeE,UAAU;YAE1C,0BAA0B;YAC1BL,MAAM,CAACC,IAAI,GAAG,AAACE,UAAU,KAAM;YAC/BH,MAAM,CAACC,MAAM,EAAE,GAAG,AAACE,UAAU,KAAM;YACnCH,MAAM,CAACC,MAAM,EAAE,GAAG,AAACE,UAAU,IAAK;YAClCH,MAAM,CAACC,MAAM,EAAE,GAAGE,QAAQ;QAC5B;QACAF,OAAO;IACT;IAEA,OAAOD;AACT;AAEA;;CAEC,GACD,OAAO,SAASM,oBAAoBC,UAAmB,EAAEC,UAAmB;IAC1E,OAAOb,uBAAuBC,cAAcW,YAAYC;AAC1D"}
@@ -0,0 +1,19 @@
1
+ import type { Transform } from 'stream';
2
+ /**
3
+ * Decode SPARC BCJ filtered data
4
+ * Reverses the BCJ transformation by converting absolute addresses back to relative
5
+ *
6
+ * SPARC CALL instruction matching (big-endian):
7
+ * - First byte 0x40 and (second byte & 0xC0) == 0x00, OR
8
+ * - First byte 0x7F and (second byte & 0xC0) == 0xC0
9
+ *
10
+ * @param input - SPARC BCJ filtered data
11
+ * @param _properties - Unused for SPARC BCJ
12
+ * @param _unpackSize - Unused for SPARC BCJ
13
+ * @returns Unfiltered data
14
+ */
15
+ export declare function decodeBcjSparc(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer;
16
+ /**
17
+ * Create a SPARC BCJ decoder Transform stream
18
+ */
19
+ export declare function createBcjSparcDecoder(properties?: Buffer, unpackSize?: number): Transform;