roxify 1.2.3 → 1.2.5
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.
- package/dist/cli.js +90 -51
- package/dist/index.d.ts +11 -127
- package/dist/index.js +11 -2547
- package/dist/minpng.js +31 -24
- package/dist/pack.d.ts +11 -10
- package/dist/pack.js +104 -62
- package/dist/utils/constants.d.ts +38 -0
- package/dist/utils/constants.js +22 -0
- package/dist/utils/crc.d.ts +4 -0
- package/dist/utils/crc.js +29 -0
- package/dist/utils/decoder.d.ts +4 -0
- package/dist/utils/decoder.js +626 -0
- package/dist/utils/encoder.d.ts +4 -0
- package/dist/utils/encoder.js +305 -0
- package/dist/utils/errors.d.ts +9 -0
- package/dist/utils/errors.js +18 -0
- package/dist/utils/helpers.d.ts +11 -0
- package/dist/utils/helpers.js +76 -0
- package/dist/utils/inspection.d.ts +14 -0
- package/dist/utils/inspection.js +388 -0
- package/dist/utils/optimization.d.ts +3 -0
- package/dist/utils/optimization.js +636 -0
- package/dist/utils/reconstitution.d.ts +3 -0
- package/dist/utils/reconstitution.js +266 -0
- package/dist/utils/types.d.ts +41 -0
- package/dist/utils/types.js +1 -0
- package/dist/utils/zstd.d.ts +17 -0
- package/dist/utils/zstd.js +118 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import cliProgress from 'cli-progress';
|
|
3
3
|
import { mkdirSync, readFileSync, statSync, writeFileSync } from 'fs';
|
|
4
4
|
import { basename, dirname, join, resolve } from 'path';
|
|
5
|
-
import { DataFormatError, decodePngToBinary, encodeBinaryToPng, IncorrectPassphraseError, listFilesInPng, PassphraseRequiredError, } from './index.js';
|
|
6
|
-
import {
|
|
7
|
-
const VERSION = '1.2.
|
|
5
|
+
import { DataFormatError, decodePngToBinary, encodeBinaryToPng, hasPassphraseInPng, IncorrectPassphraseError, listFilesInPng, PassphraseRequiredError, } from './index.js';
|
|
6
|
+
import { packPathsGenerator, unpackBuffer } from './pack.js';
|
|
7
|
+
const VERSION = '1.2.4';
|
|
8
8
|
function showHelp() {
|
|
9
9
|
console.log(`
|
|
10
10
|
ROX CLI — Encode/decode binary in PNG
|
|
@@ -15,12 +15,12 @@ Usage:
|
|
|
15
15
|
Commands:
|
|
16
16
|
encode <input>... [output] Encode one or more files/directories into a PNG
|
|
17
17
|
decode <input> [output] Decode PNG to original file
|
|
18
|
-
list <input> List files in a Rox PNG archive
|
|
18
|
+
list <input> List files in a Rox PNG archive
|
|
19
|
+
havepassphrase <input> Check whether the PNG requires a passphrase
|
|
19
20
|
|
|
20
21
|
Options:
|
|
21
22
|
-p, --passphrase <pass> Use passphrase (AES-256-GCM)
|
|
22
|
-
-m, --mode <mode> Mode:
|
|
23
|
-
-q, --quality <0-11> Brotli quality (default: 11)
|
|
23
|
+
-m, --mode <mode> Mode: screenshot (default)
|
|
24
24
|
-e, --encrypt <type> auto|aes|xor|none
|
|
25
25
|
--no-compress Disable compression
|
|
26
26
|
-o, --output <path> Output file path
|
|
@@ -78,11 +78,6 @@ function parseArgs(args) {
|
|
|
78
78
|
i += 2;
|
|
79
79
|
break;
|
|
80
80
|
case 'm':
|
|
81
|
-
parsed.mode = value;
|
|
82
|
-
i += 2;
|
|
83
|
-
break;
|
|
84
|
-
case 'q':
|
|
85
|
-
parsed.quality = parseInt(value, 10);
|
|
86
81
|
i += 2;
|
|
87
82
|
break;
|
|
88
83
|
case 'e':
|
|
@@ -143,8 +138,6 @@ async function encodeCommand(args) {
|
|
|
143
138
|
const resolvedOutput = parsed.output || outputPath || outputName;
|
|
144
139
|
let options = {};
|
|
145
140
|
try {
|
|
146
|
-
let inputBuffer;
|
|
147
|
-
let displayName;
|
|
148
141
|
const encodeBar = new cliProgress.SingleBar({
|
|
149
142
|
format: ' {bar} {percentage}% | {step} | {elapsed}s',
|
|
150
143
|
}, cliProgress.Presets.shades_classic);
|
|
@@ -175,69 +168,63 @@ async function encodeCommand(args) {
|
|
|
175
168
|
elapsed: String(Math.floor(elapsed / 1000)),
|
|
176
169
|
});
|
|
177
170
|
}, TICK_MS);
|
|
171
|
+
const mode = 'screenshot';
|
|
172
|
+
Object.assign(options, {
|
|
173
|
+
mode,
|
|
174
|
+
name: parsed.outputName || 'archive',
|
|
175
|
+
});
|
|
176
|
+
if (parsed.verbose)
|
|
177
|
+
options.verbose = true;
|
|
178
|
+
if (parsed.noCompress)
|
|
179
|
+
options.compression = 'none';
|
|
180
|
+
if (parsed.passphrase) {
|
|
181
|
+
options.passphrase = parsed.passphrase;
|
|
182
|
+
options.encrypt = parsed.encrypt || 'aes';
|
|
183
|
+
}
|
|
184
|
+
console.log(`Encoding to ${resolvedOutput} (Mode: ${mode})\n`);
|
|
185
|
+
let inputData;
|
|
186
|
+
let inputSizeVal = 0;
|
|
187
|
+
let displayName;
|
|
178
188
|
let totalBytes = 0;
|
|
179
|
-
let lastShownFile;
|
|
180
189
|
const onProgress = (readBytes, total, currentFile) => {
|
|
181
190
|
if (totalBytes === 0)
|
|
182
191
|
totalBytes = total;
|
|
183
192
|
const packPct = Math.floor((readBytes / totalBytes) * 25);
|
|
184
193
|
targetPct = Math.max(targetPct, packPct);
|
|
185
|
-
if (currentFile && currentFile !== lastShownFile) {
|
|
186
|
-
lastShownFile = currentFile;
|
|
187
|
-
}
|
|
188
194
|
currentEncodeStep = currentFile
|
|
189
195
|
? `Reading files: ${currentFile}`
|
|
190
196
|
: 'Reading files';
|
|
191
197
|
};
|
|
192
198
|
if (inputPaths.length > 1) {
|
|
193
199
|
currentEncodeStep = 'Reading files';
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
console.log(`Packed ${packResult.list.length} files -> ${(inputBuffer.length /
|
|
198
|
-
1024 /
|
|
199
|
-
1024).toFixed(2)} MB`);
|
|
200
|
+
const { index, stream, totalSize } = await packPathsGenerator(inputPaths, undefined, onProgress);
|
|
201
|
+
inputData = stream;
|
|
202
|
+
inputSizeVal = totalSize;
|
|
200
203
|
displayName = parsed.outputName || 'archive';
|
|
201
204
|
options.includeFileList = true;
|
|
202
|
-
options.fileList =
|
|
205
|
+
options.fileList = index.map((e) => e.path);
|
|
203
206
|
}
|
|
204
207
|
else {
|
|
205
208
|
const resolvedInput = resolvedInputs[0];
|
|
206
209
|
const st = statSync(resolvedInput);
|
|
207
210
|
if (st.isDirectory()) {
|
|
208
|
-
console.log(`Packing directory...`);
|
|
209
211
|
currentEncodeStep = 'Reading files';
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
console.log(`Packed ${packResult.list.length} files -> ${(inputBuffer.length /
|
|
214
|
-
1024 /
|
|
215
|
-
1024).toFixed(2)} MB`);
|
|
212
|
+
const { index, stream, totalSize } = await packPathsGenerator([resolvedInput], dirname(resolvedInput), onProgress);
|
|
213
|
+
inputData = stream;
|
|
214
|
+
inputSizeVal = totalSize;
|
|
216
215
|
displayName = parsed.outputName || basename(resolvedInput);
|
|
217
216
|
options.includeFileList = true;
|
|
218
|
-
options.fileList =
|
|
217
|
+
options.fileList = index.map((e) => e.path);
|
|
219
218
|
}
|
|
220
219
|
else {
|
|
221
|
-
|
|
222
|
-
|
|
220
|
+
inputData = readFileSync(resolvedInput);
|
|
221
|
+
inputSizeVal = inputData.length;
|
|
223
222
|
displayName = basename(resolvedInput);
|
|
224
223
|
options.includeFileList = true;
|
|
225
224
|
options.fileList = [basename(resolvedInput)];
|
|
226
225
|
}
|
|
227
226
|
}
|
|
228
|
-
|
|
229
|
-
mode: parsed.mode || 'screenshot',
|
|
230
|
-
name: displayName,
|
|
231
|
-
brQuality: parsed.quality !== undefined ? parsed.quality : 11,
|
|
232
|
-
});
|
|
233
|
-
if (parsed.noCompress) {
|
|
234
|
-
options.compression = 'none';
|
|
235
|
-
}
|
|
236
|
-
if (parsed.passphrase) {
|
|
237
|
-
options.passphrase = parsed.passphrase;
|
|
238
|
-
options.encrypt = parsed.encrypt || 'aes';
|
|
239
|
-
}
|
|
240
|
-
console.log(`Encoding ${displayName} -> ${resolvedOutput}\n`);
|
|
227
|
+
options.name = displayName;
|
|
241
228
|
options.onProgress = (info) => {
|
|
242
229
|
let stepLabel = 'Processing';
|
|
243
230
|
let pct = 0;
|
|
@@ -290,6 +277,17 @@ async function encodeCommand(args) {
|
|
|
290
277
|
targetPct = Math.max(targetPct, pct);
|
|
291
278
|
currentEncodeStep = stepLabel;
|
|
292
279
|
};
|
|
280
|
+
let inputBuffer;
|
|
281
|
+
if (typeof inputData[Symbol.asyncIterator] === 'function') {
|
|
282
|
+
const chunks = [];
|
|
283
|
+
for await (const chunk of inputData) {
|
|
284
|
+
chunks.push(chunk);
|
|
285
|
+
}
|
|
286
|
+
inputBuffer = Buffer.concat(chunks);
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
inputBuffer = inputData;
|
|
290
|
+
}
|
|
293
291
|
const output = await encodeBinaryToPng(inputBuffer, options);
|
|
294
292
|
const encodeTime = Date.now() - startEncode;
|
|
295
293
|
clearInterval(encodeHeartbeat);
|
|
@@ -302,8 +300,8 @@ async function encodeCommand(args) {
|
|
|
302
300
|
}
|
|
303
301
|
writeFileSync(resolvedOutput, output);
|
|
304
302
|
const outputSize = (output.length / 1024 / 1024).toFixed(2);
|
|
305
|
-
const inputSize = (
|
|
306
|
-
const ratio = ((output.length /
|
|
303
|
+
const inputSize = (inputSizeVal / 1024 / 1024).toFixed(2);
|
|
304
|
+
const ratio = ((output.length / inputSizeVal) * 100).toFixed(1);
|
|
307
305
|
console.log(`\nSuccess!`);
|
|
308
306
|
console.log(` Input: ${inputSize} MB`);
|
|
309
307
|
console.log(` Output: ${outputSize} MB (${ratio}% of original)`);
|
|
@@ -404,12 +402,20 @@ async function decodeCommand(args) {
|
|
|
404
402
|
}
|
|
405
403
|
if (result.files) {
|
|
406
404
|
const baseDir = parsed.output || outputPath || '.';
|
|
405
|
+
const totalBytes = result.files.reduce((s, f) => s + f.buf.length, 0);
|
|
406
|
+
const extractBar = new cliProgress.SingleBar({ format: ' {bar} {percentage}% | {step} | {elapsed}s' }, cliProgress.Presets.shades_classic);
|
|
407
|
+
extractBar.start(totalBytes, 0, { step: 'Writing files' });
|
|
408
|
+
let written = 0;
|
|
407
409
|
for (const file of result.files) {
|
|
408
410
|
const fullPath = join(baseDir, file.path);
|
|
409
411
|
const dir = dirname(fullPath);
|
|
410
412
|
mkdirSync(dir, { recursive: true });
|
|
411
413
|
writeFileSync(fullPath, file.buf);
|
|
414
|
+
written += file.buf.length;
|
|
415
|
+
extractBar.update(written, { step: `Writing ${file.path}` });
|
|
412
416
|
}
|
|
417
|
+
extractBar.update(totalBytes, { step: 'Done' });
|
|
418
|
+
extractBar.stop();
|
|
413
419
|
console.log(`\nSuccess!`);
|
|
414
420
|
console.log(`Unpacked ${result.files.length} files to directory : ${resolve(baseDir)}`);
|
|
415
421
|
console.log(`Time: ${decodeTime}ms`);
|
|
@@ -418,12 +424,20 @@ async function decodeCommand(args) {
|
|
|
418
424
|
const unpacked = unpackBuffer(result.buf);
|
|
419
425
|
if (unpacked) {
|
|
420
426
|
const baseDir = parsed.output || outputPath || '.';
|
|
427
|
+
const totalBytes = unpacked.files.reduce((s, f) => s + f.buf.length, 0);
|
|
428
|
+
const extractBar = new cliProgress.SingleBar({ format: ' {bar} {percentage}% | {step} | {elapsed}s' }, cliProgress.Presets.shades_classic);
|
|
429
|
+
extractBar.start(totalBytes, 0, { step: 'Writing files' });
|
|
430
|
+
let written = 0;
|
|
421
431
|
for (const file of unpacked.files) {
|
|
422
432
|
const fullPath = join(baseDir, file.path);
|
|
423
433
|
const dir = dirname(fullPath);
|
|
424
434
|
mkdirSync(dir, { recursive: true });
|
|
425
435
|
writeFileSync(fullPath, file.buf);
|
|
436
|
+
written += file.buf.length;
|
|
437
|
+
extractBar.update(written, { step: `Writing ${file.path}` });
|
|
426
438
|
}
|
|
439
|
+
extractBar.update(totalBytes, { step: 'Done' });
|
|
440
|
+
extractBar.stop();
|
|
427
441
|
console.log(`\nSuccess!`);
|
|
428
442
|
console.log(`Time: ${decodeTime}ms`);
|
|
429
443
|
console.log(`Unpacked ${unpacked.files.length} files to current directory`);
|
|
@@ -466,8 +480,7 @@ async function decodeCommand(args) {
|
|
|
466
480
|
(err.message.includes('decompression failed') ||
|
|
467
481
|
err.message.includes('missing ROX1') ||
|
|
468
482
|
err.message.includes('Pixel payload truncated') ||
|
|
469
|
-
err.message.includes('Marker START not found')
|
|
470
|
-
err.message.includes('Brotli decompression failed')))) {
|
|
483
|
+
err.message.includes('Marker START not found')))) {
|
|
471
484
|
console.log(' ');
|
|
472
485
|
console.error('Data corrupted or unsupported format. Use --verbose for details.');
|
|
473
486
|
}
|
|
@@ -513,6 +526,29 @@ async function listCommand(args) {
|
|
|
513
526
|
process.exit(1);
|
|
514
527
|
}
|
|
515
528
|
}
|
|
529
|
+
async function havePassphraseCommand(args) {
|
|
530
|
+
const parsed = parseArgs(args);
|
|
531
|
+
const [inputPath] = parsed._;
|
|
532
|
+
if (!inputPath) {
|
|
533
|
+
console.log(' ');
|
|
534
|
+
console.error('Error: Input PNG file required');
|
|
535
|
+
console.log('Usage: npx rox havepassphrase <input>');
|
|
536
|
+
process.exit(1);
|
|
537
|
+
}
|
|
538
|
+
const resolvedInput = resolve(inputPath);
|
|
539
|
+
try {
|
|
540
|
+
const inputBuffer = readFileSync(resolvedInput);
|
|
541
|
+
const has = await hasPassphraseInPng(inputBuffer);
|
|
542
|
+
console.log(has ? 'Passphrase detected.' : 'No passphrase detected.');
|
|
543
|
+
}
|
|
544
|
+
catch (err) {
|
|
545
|
+
console.log(' ');
|
|
546
|
+
console.error('Failed to check passphrase. Use --verbose for details.');
|
|
547
|
+
if (parsed.verbose)
|
|
548
|
+
console.error('Details:', err.stack || err.message);
|
|
549
|
+
process.exit(1);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
516
552
|
async function main() {
|
|
517
553
|
const args = process.argv.slice(2);
|
|
518
554
|
if (args.length === 0 || args[0] === 'help' || args[0] === '--help') {
|
|
@@ -535,6 +571,9 @@ async function main() {
|
|
|
535
571
|
case 'list':
|
|
536
572
|
await listCommand(commandArgs);
|
|
537
573
|
break;
|
|
574
|
+
case 'havepassphrase':
|
|
575
|
+
await havePassphraseCommand(commandArgs);
|
|
576
|
+
break;
|
|
538
577
|
default:
|
|
539
578
|
console.error(`Unknown command: ${command}`);
|
|
540
579
|
console.log('Run "npx rox help" for usage information');
|
package/dist/index.d.ts
CHANGED
|
@@ -1,129 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Options for encoding binary data into PNG format.
|
|
15
|
-
* @public
|
|
16
|
-
*/
|
|
17
|
-
export interface EncodeOptions {
|
|
18
|
-
compression?: 'zstd';
|
|
19
|
-
passphrase?: string;
|
|
20
|
-
name?: string;
|
|
21
|
-
mode?: 'compact' | 'pixel' | 'screenshot';
|
|
22
|
-
encrypt?: 'auto' | 'aes' | 'xor' | 'none';
|
|
23
|
-
_skipAuto?: boolean;
|
|
24
|
-
output?: 'auto' | 'png' | 'rox';
|
|
25
|
-
includeName?: boolean;
|
|
26
|
-
includeFileList?: boolean;
|
|
27
|
-
fileList?: string[];
|
|
28
|
-
brQuality?: number;
|
|
29
|
-
onProgress?: (info: {
|
|
30
|
-
phase: string;
|
|
31
|
-
loaded?: number;
|
|
32
|
-
total?: number;
|
|
33
|
-
}) => void;
|
|
34
|
-
showProgress?: boolean;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Result of decoding a PNG back to binary data.
|
|
38
|
-
* @public
|
|
39
|
-
*/
|
|
40
|
-
export interface DecodeResult {
|
|
41
|
-
buf?: Buffer;
|
|
42
|
-
meta?: {
|
|
43
|
-
name?: string;
|
|
44
|
-
};
|
|
45
|
-
files?: PackedFile[];
|
|
46
|
-
}
|
|
47
|
-
export declare function optimizePngBuffer(pngBuf: Buffer, fast?: boolean): Promise<Buffer>;
|
|
48
|
-
/**
|
|
49
|
-
* Path to write decoded output directly to disk (streamed) to avoid high memory usage.
|
|
50
|
-
*/
|
|
51
|
-
export interface DecodeOptions {
|
|
52
|
-
/**
|
|
53
|
-
* Passphrase for encrypted inputs.
|
|
54
|
-
*/
|
|
55
|
-
passphrase?: string;
|
|
56
|
-
/**
|
|
57
|
-
* Directory to save debug images (doubled.png, reconstructed.png).
|
|
58
|
-
*/
|
|
59
|
-
debugDir?: string;
|
|
60
|
-
/**
|
|
61
|
-
* Path to write decoded output directly to disk (streamed) to avoid high memory usage.
|
|
62
|
-
*/
|
|
63
|
-
outPath?: string;
|
|
64
|
-
/**
|
|
65
|
-
* List of files to extract selectively from archives.
|
|
66
|
-
*/
|
|
67
|
-
files?: string[];
|
|
68
|
-
/**
|
|
69
|
-
* Progress callback for decoding phases.
|
|
70
|
-
*/
|
|
71
|
-
onProgress?: (info: {
|
|
72
|
-
phase: string;
|
|
73
|
-
loaded?: number;
|
|
74
|
-
total?: number;
|
|
75
|
-
}) => void;
|
|
76
|
-
/**
|
|
77
|
-
* Whether to display a progress bar in the console.
|
|
78
|
-
* @defaultValue `false`
|
|
79
|
-
*/
|
|
80
|
-
showProgress?: boolean;
|
|
81
|
-
}
|
|
82
|
-
export declare function cropAndReconstitute(input: Buffer, debugDir?: string): Promise<Buffer>;
|
|
83
|
-
/**
|
|
84
|
-
* Encode a Buffer into a PNG wrapper. Supports optional compression and
|
|
85
|
-
* encryption. Defaults are chosen for a good balance between speed and size.
|
|
86
|
-
*
|
|
87
|
-
* @param input - Data to encode
|
|
88
|
-
* @param opts - Encoding options
|
|
89
|
-
* @public
|
|
90
|
-
* @example
|
|
91
|
-
* ```typescript
|
|
92
|
-
* import { readFileSync, writeFileSync } from 'fs';
|
|
93
|
-
* import { encodeBinaryToPng } from 'roxify';
|
|
94
|
-
*
|
|
95
|
-
* const fileName = 'input.bin'; //Path of your input file here
|
|
96
|
-
* const inputBuffer = readFileSync(fileName);
|
|
97
|
-
* const pngBuffer = await encodeBinaryToPng(inputBuffer, {
|
|
98
|
-
* name: fileName,
|
|
99
|
-
* });
|
|
100
|
-
* writeFileSync('output.png', pngBuffer);
|
|
101
|
-
|
|
102
|
-
* ```
|
|
103
|
-
*/
|
|
104
|
-
export declare function encodeBinaryToPng(input: Buffer, opts?: EncodeOptions): Promise<Buffer>;
|
|
105
|
-
/**
|
|
106
|
-
* Decode a PNG produced by this library back to the original Buffer.
|
|
107
|
-
* Supports the ROX binary format, rXDT chunk, and pixel encodings.
|
|
108
|
-
*
|
|
109
|
-
* @param pngBuf - PNG data
|
|
110
|
-
* @param opts - Options (passphrase for encrypted inputs)
|
|
111
|
-
* @public
|
|
112
|
-
* @example
|
|
113
|
-
* import { readFileSync, writeFileSync } from 'fs';
|
|
114
|
-
* import { decodePngToBinary } from 'roxify';
|
|
115
|
-
*
|
|
116
|
-
* const pngFromDisk = readFileSync('output.png'); //Path of the encoded PNG here
|
|
117
|
-
* const { buf, meta } = await decodePngToBinary(pngFromDisk);
|
|
118
|
-
* writeFileSync(meta?.name ?? 'decoded.txt', buf);
|
|
119
|
-
*/
|
|
120
|
-
export declare function decodePngToBinary(pngBuf: Buffer, opts?: DecodeOptions): Promise<DecodeResult>;
|
|
1
|
+
export * from './utils/constants.js';
|
|
2
|
+
export * from './utils/crc.js';
|
|
3
|
+
export * from './utils/decoder.js';
|
|
4
|
+
export * from './utils/encoder.js';
|
|
5
|
+
export * from './utils/errors.js';
|
|
6
|
+
export * from './utils/helpers.js';
|
|
7
|
+
export * from './utils/inspection.js';
|
|
8
|
+
export * from './utils/optimization.js';
|
|
9
|
+
export * from './utils/reconstitution.js';
|
|
10
|
+
export * from './utils/types.js';
|
|
11
|
+
export * from './utils/zstd.js';
|
|
121
12
|
export { decodeMinPng, encodeMinPng } from './minpng.js';
|
|
122
13
|
export { packPaths, unpackBuffer } from './pack.js';
|
|
123
|
-
/**
|
|
124
|
-
* List files in a Rox PNG archive without decoding the full payload.
|
|
125
|
-
* Returns the file list if available, otherwise null.
|
|
126
|
-
* @param pngBuf - PNG data
|
|
127
|
-
* @public
|
|
128
|
-
*/
|
|
129
|
-
export declare function listFilesInPng(pngBuf: Buffer): Promise<string[] | null>;
|