roxify 1.4.0 → 1.5.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.
- package/dist/cli.js +4 -3
- package/dist/hybrid-compression.d.ts +0 -2
- package/dist/hybrid-compression.js +1 -1
- package/dist/minpng.d.ts +0 -2
- package/dist/minpng.js +45 -12
- package/dist/pack.d.ts +0 -2
- package/dist/roxify-cli +0 -0
- package/dist/stub-progress.d.ts +9 -0
- package/dist/stub-progress.js +9 -0
- package/dist/utils/constants.d.ts +22 -7
- package/dist/utils/constants.js +5 -0
- package/dist/utils/crc.d.ts +0 -2
- package/dist/utils/decoder.d.ts +0 -2
- package/dist/utils/decoder.js +121 -123
- package/dist/utils/encoder.d.ts +0 -2
- package/dist/utils/encoder.js +12 -57
- package/dist/utils/helpers.d.ts +0 -2
- package/dist/utils/helpers.js +2 -4
- package/dist/utils/inspection.d.ts +0 -2
- package/dist/utils/inspection.js +23 -40
- package/dist/utils/native.d.ts +1 -0
- package/dist/utils/native.js +7 -0
- package/dist/utils/optimization.d.ts +0 -2
- package/dist/utils/optimization.js +19 -15
- package/dist/utils/reconstitution.d.ts +0 -2
- package/dist/utils/reconstitution.js +1 -264
- package/dist/utils/rust-cli-wrapper.d.ts +1 -1
- package/dist/utils/rust-cli-wrapper.js +6 -8
- package/dist/utils/types.d.ts +1 -2
- package/dist/utils/zstd.d.ts +0 -2
- package/dist/utils/zstd.js +32 -37
- package/libroxify_native.node +0 -0
- package/package.json +21 -23
- package/README.md +0 -391
package/dist/utils/encoder.js
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import cliProgress from 'cli-progress';
|
|
2
1
|
import { createCipheriv, pbkdf2Sync, randomBytes } from 'crypto';
|
|
3
|
-
import sharp from 'sharp';
|
|
4
2
|
import * as zlib from 'zlib';
|
|
5
3
|
import { unpackBuffer } from '../pack.js';
|
|
6
4
|
import { COMPRESSION_MARKERS, ENC_AES, ENC_NONE, ENC_XOR, MAGIC, MARKER_END, MARKER_START, PIXEL_MAGIC, PIXEL_MAGIC_BLOCK, PNG_HEADER, } from './constants.js';
|
|
7
5
|
import { crc32 } from './crc.js';
|
|
8
6
|
import { colorsToBytes } from './helpers.js';
|
|
9
|
-
import {
|
|
7
|
+
import { native } from './native.js';
|
|
10
8
|
import { parallelZstdCompress } from './zstd.js';
|
|
11
9
|
export async function encodeBinaryToPng(input, opts = {}) {
|
|
12
10
|
let progressBar = null;
|
|
13
11
|
if (opts.showProgress) {
|
|
14
|
-
progressBar =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
progressBar = {
|
|
13
|
+
start: () => { },
|
|
14
|
+
update: () => { },
|
|
15
|
+
stop: () => { },
|
|
16
|
+
};
|
|
18
17
|
const startTime = Date.now();
|
|
19
18
|
if (!opts.onProgress) {
|
|
20
19
|
opts.onProgress = (info) => {
|
|
@@ -34,10 +33,6 @@ export async function encodeBinaryToPng(input, opts = {}) {
|
|
|
34
33
|
else if (info.phase === 'done') {
|
|
35
34
|
pct = 100;
|
|
36
35
|
}
|
|
37
|
-
progressBar.update(Math.floor(pct), {
|
|
38
|
-
step: info.phase.replace('_', ' '),
|
|
39
|
-
elapsed: String(Math.floor((Date.now() - startTime) / 1000)),
|
|
40
|
-
});
|
|
41
36
|
};
|
|
42
37
|
}
|
|
43
38
|
}
|
|
@@ -220,7 +215,7 @@ export async function encodeBinaryToPng(input, opts = {}) {
|
|
|
220
215
|
lenBuf.writeUInt32BE(jsonBuf.length, 0);
|
|
221
216
|
metaPixel = [...metaPixel, Buffer.from('rXFL', 'utf8'), lenBuf, jsonBuf];
|
|
222
217
|
}
|
|
223
|
-
const useBlockEncoding =
|
|
218
|
+
const useBlockEncoding = false;
|
|
224
219
|
const pixelMagic = useBlockEncoding ? PIXEL_MAGIC_BLOCK : PIXEL_MAGIC;
|
|
225
220
|
const dataWithoutMarkers = [pixelMagic, ...metaPixel];
|
|
226
221
|
const dataWithoutMarkersLen = dataWithoutMarkers.reduce((a, b) => a + b.length, 0);
|
|
@@ -261,15 +256,7 @@ export async function encodeBinaryToPng(input, opts = {}) {
|
|
|
261
256
|
}
|
|
262
257
|
}
|
|
263
258
|
}
|
|
264
|
-
bufScr =
|
|
265
|
-
raw: { width, height, channels: 3 },
|
|
266
|
-
})
|
|
267
|
-
.png({
|
|
268
|
-
compressionLevel: 9,
|
|
269
|
-
adaptiveFiltering: true,
|
|
270
|
-
effort: 9,
|
|
271
|
-
})
|
|
272
|
-
.toBuffer();
|
|
259
|
+
bufScr = Buffer.from(native.rgbToPng(rgbBuffer, width, height));
|
|
273
260
|
}
|
|
274
261
|
else {
|
|
275
262
|
const bytesPerPixel = 3;
|
|
@@ -394,27 +381,10 @@ export async function encodeBinaryToPng(input, opts = {}) {
|
|
|
394
381
|
else {
|
|
395
382
|
const outputFormat = opts.outputFormat || 'png';
|
|
396
383
|
if (outputFormat === 'webp') {
|
|
397
|
-
|
|
398
|
-
raw: { width, height, channels: 3 },
|
|
399
|
-
})
|
|
400
|
-
.webp({
|
|
401
|
-
lossless: true,
|
|
402
|
-
quality: 100,
|
|
403
|
-
effort: 6,
|
|
404
|
-
})
|
|
405
|
-
.toBuffer();
|
|
384
|
+
throw new Error('WebP output format not supported with native backend');
|
|
406
385
|
}
|
|
407
386
|
else {
|
|
408
|
-
bufScr =
|
|
409
|
-
raw: { width, height, channels: 3 },
|
|
410
|
-
})
|
|
411
|
-
.png({
|
|
412
|
-
compressionLevel: 3,
|
|
413
|
-
palette: false,
|
|
414
|
-
effort: 1,
|
|
415
|
-
adaptiveFiltering: false,
|
|
416
|
-
})
|
|
417
|
-
.toBuffer();
|
|
387
|
+
bufScr = Buffer.from(native.rgbToPng(raw, width, height));
|
|
418
388
|
}
|
|
419
389
|
}
|
|
420
390
|
}
|
|
@@ -426,22 +396,7 @@ export async function encodeBinaryToPng(input, opts = {}) {
|
|
|
426
396
|
dataWithoutMarkers.length = 0;
|
|
427
397
|
if (opts.onProgress)
|
|
428
398
|
opts.onProgress({ phase: 'png_compress', loaded: 100, total: 100 });
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
return bufScr;
|
|
432
|
-
}
|
|
433
|
-
if (opts.onProgress)
|
|
434
|
-
opts.onProgress({ phase: 'optimizing', loaded: 0, total: 100 });
|
|
435
|
-
try {
|
|
436
|
-
const optimized = await optimizePngBuffer(bufScr, true);
|
|
437
|
-
if (opts.onProgress)
|
|
438
|
-
opts.onProgress({ phase: 'optimizing', loaded: 100, total: 100 });
|
|
439
|
-
progressBar?.stop();
|
|
440
|
-
return optimized;
|
|
441
|
-
}
|
|
442
|
-
catch (e) {
|
|
443
|
-
progressBar?.stop();
|
|
444
|
-
return bufScr;
|
|
445
|
-
}
|
|
399
|
+
progressBar?.stop();
|
|
400
|
+
return bufScr;
|
|
446
401
|
}
|
|
447
402
|
}
|
package/dist/utils/helpers.d.ts
CHANGED
package/dist/utils/helpers.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import { createDecipheriv, pbkdf2Sync } from 'crypto';
|
|
2
2
|
import { ENC_AES, ENC_NONE, ENC_XOR } from './constants.js';
|
|
3
3
|
import { IncorrectPassphraseError, PassphraseRequiredError } from './errors.js';
|
|
4
|
+
import { native } from './native.js';
|
|
4
5
|
let nativeDeltaEncode = null;
|
|
5
6
|
let nativeDeltaDecode = null;
|
|
6
7
|
let hasNative = false;
|
|
7
8
|
try {
|
|
8
|
-
const native = require('../../libroxify_native.node');
|
|
9
9
|
if (native?.nativeDeltaEncode && native?.nativeDeltaDecode) {
|
|
10
10
|
nativeDeltaEncode = native.nativeDeltaEncode;
|
|
11
11
|
nativeDeltaDecode = native.nativeDeltaDecode;
|
|
12
12
|
hasNative = true;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
catch (e) {
|
|
16
|
-
// Native module not available, will use TS fallback
|
|
17
|
-
}
|
|
15
|
+
catch (e) { }
|
|
18
16
|
export function colorsToBytes(colors) {
|
|
19
17
|
const buf = Buffer.alloc(colors.length * 3);
|
|
20
18
|
for (let i = 0; i < colors.length; i++) {
|
package/dist/utils/inspection.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import extract from 'png-chunks-extract';
|
|
2
|
-
import sharp from 'sharp';
|
|
3
1
|
import * as zlib from 'zlib';
|
|
4
2
|
import { unpackBuffer } from '../pack.js';
|
|
5
3
|
import { CHUNK_TYPE, ENC_AES, ENC_XOR, MAGIC, MARKER_COLORS, PIXEL_MAGIC, } from './constants.js';
|
|
6
4
|
import { decodePngToBinary } from './decoder.js';
|
|
7
5
|
import { PassphraseRequiredError } from './errors.js';
|
|
6
|
+
import { native } from './native.js';
|
|
8
7
|
import { cropAndReconstitute } from './reconstitution.js';
|
|
9
8
|
/**
|
|
10
9
|
* List files in a Rox PNG archive without decoding the full payload.
|
|
@@ -14,7 +13,7 @@ import { cropAndReconstitute } from './reconstitution.js';
|
|
|
14
13
|
*/
|
|
15
14
|
export async function listFilesInPng(pngBuf, opts = {}) {
|
|
16
15
|
try {
|
|
17
|
-
const chunks =
|
|
16
|
+
const chunks = native.extractPngChunks(pngBuf);
|
|
18
17
|
const ihdr = chunks.find((c) => c.name === 'IHDR');
|
|
19
18
|
const idatChunks = chunks.filter((c) => c.name === 'IDAT');
|
|
20
19
|
if (ihdr && idatChunks.length > 0) {
|
|
@@ -147,15 +146,13 @@ export async function listFilesInPng(pngBuf, opts = {}) {
|
|
|
147
146
|
}
|
|
148
147
|
try {
|
|
149
148
|
try {
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const currentWidth = info.width;
|
|
155
|
-
const currentHeight = info.height;
|
|
149
|
+
const rawData = native.sharpToRaw(pngBuf);
|
|
150
|
+
const data = rawData.pixels;
|
|
151
|
+
const currentWidth = rawData.width;
|
|
152
|
+
const currentHeight = rawData.height;
|
|
156
153
|
const rawRGB = Buffer.alloc(currentWidth * currentHeight * 3);
|
|
157
154
|
for (let i = 0; i < currentWidth * currentHeight; i++) {
|
|
158
|
-
rawRGB[i * 3] = data[i *
|
|
155
|
+
rawRGB[i * 3] = data[i * 3];
|
|
159
156
|
rawRGB[i * 3 + 1] = data[i * 4 + 1];
|
|
160
157
|
rawRGB[i * 3 + 2] = data[i * 4 + 2];
|
|
161
158
|
}
|
|
@@ -219,17 +216,15 @@ export async function listFilesInPng(pngBuf, opts = {}) {
|
|
|
219
216
|
try {
|
|
220
217
|
const reconstructed = await cropAndReconstitute(pngBuf);
|
|
221
218
|
try {
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const currentWidth = info.width;
|
|
227
|
-
const currentHeight = info.height;
|
|
219
|
+
const rawData = native.sharpToRaw(reconstructed);
|
|
220
|
+
const data = rawData.pixels;
|
|
221
|
+
const currentWidth = rawData.width;
|
|
222
|
+
const currentHeight = rawData.height;
|
|
228
223
|
const rawRGB = Buffer.alloc(currentWidth * currentHeight * 3);
|
|
229
224
|
for (let i = 0; i < currentWidth * currentHeight; i++) {
|
|
230
|
-
rawRGB[i * 3] = data[i *
|
|
231
|
-
rawRGB[i * 3 + 1] = data[i *
|
|
232
|
-
rawRGB[i * 3 + 2] = data[i *
|
|
225
|
+
rawRGB[i * 3] = data[i * 3];
|
|
226
|
+
rawRGB[i * 3 + 1] = data[i * 3 + 1];
|
|
227
|
+
rawRGB[i * 3 + 2] = data[i * 3 + 2];
|
|
233
228
|
}
|
|
234
229
|
const found = rawRGB.indexOf(PIXEL_MAGIC);
|
|
235
230
|
if (found !== -1) {
|
|
@@ -287,12 +282,10 @@ export async function listFilesInPng(pngBuf, opts = {}) {
|
|
|
287
282
|
}
|
|
288
283
|
catch (e) { }
|
|
289
284
|
try {
|
|
290
|
-
const chunks =
|
|
285
|
+
const chunks = native.extractPngChunks(reconstructed);
|
|
291
286
|
const fileListChunk = chunks.find((c) => c.name === 'rXFL');
|
|
292
287
|
if (fileListChunk) {
|
|
293
|
-
const data = Buffer.
|
|
294
|
-
? fileListChunk.data
|
|
295
|
-
: Buffer.from(fileListChunk.data);
|
|
288
|
+
const data = Buffer.from(fileListChunk.data);
|
|
296
289
|
const parsedFiles = JSON.parse(data.toString('utf8'));
|
|
297
290
|
if (parsedFiles.length > 0 &&
|
|
298
291
|
typeof parsedFiles[0] === 'object' &&
|
|
@@ -316,9 +309,7 @@ export async function listFilesInPng(pngBuf, opts = {}) {
|
|
|
316
309
|
}
|
|
317
310
|
const metaChunk = chunks.find((c) => c.name === CHUNK_TYPE);
|
|
318
311
|
if (metaChunk) {
|
|
319
|
-
const dataBuf = Buffer.
|
|
320
|
-
? metaChunk.data
|
|
321
|
-
: Buffer.from(metaChunk.data);
|
|
312
|
+
const dataBuf = Buffer.from(metaChunk.data);
|
|
322
313
|
const markerIdx = dataBuf.indexOf(Buffer.from('rXFL'));
|
|
323
314
|
if (markerIdx !== -1 && markerIdx + 8 <= dataBuf.length) {
|
|
324
315
|
const jsonLen = dataBuf.readUInt32BE(markerIdx + 4);
|
|
@@ -345,12 +336,10 @@ export async function listFilesInPng(pngBuf, opts = {}) {
|
|
|
345
336
|
}
|
|
346
337
|
catch (e) { }
|
|
347
338
|
try {
|
|
348
|
-
const chunks =
|
|
339
|
+
const chunks = native.extractPngChunks(pngBuf);
|
|
349
340
|
const fileListChunk = chunks.find((c) => c.name === 'rXFL');
|
|
350
341
|
if (fileListChunk) {
|
|
351
|
-
const data = Buffer.
|
|
352
|
-
? fileListChunk.data
|
|
353
|
-
: Buffer.from(fileListChunk.data);
|
|
342
|
+
const data = Buffer.from(fileListChunk.data);
|
|
354
343
|
const parsedFiles = JSON.parse(data.toString('utf8'));
|
|
355
344
|
if (parsedFiles.length > 0 &&
|
|
356
345
|
typeof parsedFiles[0] === 'object' &&
|
|
@@ -374,9 +363,7 @@ export async function listFilesInPng(pngBuf, opts = {}) {
|
|
|
374
363
|
}
|
|
375
364
|
const metaChunk = chunks.find((c) => c.name === CHUNK_TYPE);
|
|
376
365
|
if (metaChunk) {
|
|
377
|
-
const dataBuf = Buffer.
|
|
378
|
-
? metaChunk.data
|
|
379
|
-
: Buffer.from(metaChunk.data);
|
|
366
|
+
const dataBuf = Buffer.from(metaChunk.data);
|
|
380
367
|
const markerIdx = dataBuf.indexOf(Buffer.from('rXFL'));
|
|
381
368
|
if (markerIdx !== -1 && markerIdx + 8 <= dataBuf.length) {
|
|
382
369
|
const jsonLen = dataBuf.readUInt32BE(markerIdx + 4);
|
|
@@ -442,7 +429,7 @@ export async function hasPassphraseInPng(pngBuf) {
|
|
|
442
429
|
return flag === ENC_AES || flag === ENC_XOR;
|
|
443
430
|
}
|
|
444
431
|
try {
|
|
445
|
-
const chunksRaw =
|
|
432
|
+
const chunksRaw = native.extractPngChunks(pngBuf);
|
|
446
433
|
const target = chunksRaw.find((c) => c.name === CHUNK_TYPE);
|
|
447
434
|
if (target) {
|
|
448
435
|
const data = Buffer.isBuffer(target.data)
|
|
@@ -460,12 +447,8 @@ export async function hasPassphraseInPng(pngBuf) {
|
|
|
460
447
|
}
|
|
461
448
|
catch (e) { }
|
|
462
449
|
try {
|
|
463
|
-
const
|
|
464
|
-
const
|
|
465
|
-
.default(pngBuf)
|
|
466
|
-
.raw()
|
|
467
|
-
.toBuffer({ resolveWithObject: true });
|
|
468
|
-
const rawRGB = Buffer.from(data);
|
|
450
|
+
const rawData = native.sharpToRaw(pngBuf);
|
|
451
|
+
const rawRGB = Buffer.from(rawData.pixels);
|
|
469
452
|
const markerLen = MARKER_COLORS.length * 3;
|
|
470
453
|
for (let i = 0; i <= rawRGB.length - markerLen; i += 3) {
|
|
471
454
|
let ok = true;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const native: any;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
import { dirname, join } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
5
|
+
const __dirname = dirname(__filename);
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
export const native = require(join(__dirname, '../../libroxify_native.node'));
|
|
@@ -2,8 +2,6 @@ import { spawn, spawnSync } from 'child_process';
|
|
|
2
2
|
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'fs';
|
|
3
3
|
import { tmpdir } from 'os';
|
|
4
4
|
import { join } from 'path';
|
|
5
|
-
import encode from 'png-chunks-encode';
|
|
6
|
-
import extract from 'png-chunks-extract';
|
|
7
5
|
import * as zlib from 'zlib';
|
|
8
6
|
import { PNG_HEADER, PNG_HEADER_HEX } from './constants.js';
|
|
9
7
|
export async function optimizePngBuffer(pngBuf, fast = false) {
|
|
@@ -11,6 +9,9 @@ export async function optimizePngBuffer(pngBuf, fast = false) {
|
|
|
11
9
|
if (pngBuf.length > MAX_OPTIMIZE_SIZE) {
|
|
12
10
|
return pngBuf;
|
|
13
11
|
}
|
|
12
|
+
if (fast) {
|
|
13
|
+
return pngBuf;
|
|
14
|
+
}
|
|
14
15
|
const runCommandAsync = (cmd, args, timeout = 120000) => {
|
|
15
16
|
return new Promise((resolve) => {
|
|
16
17
|
try {
|
|
@@ -67,13 +68,12 @@ export async function optimizePngBuffer(pngBuf, fast = false) {
|
|
|
67
68
|
}
|
|
68
69
|
catch (e) { }
|
|
69
70
|
try {
|
|
70
|
-
const
|
|
71
|
+
const nativeExtract = require('../../libroxify_native.node');
|
|
72
|
+
const chunksRaw = nativeExtract.extractPngChunks(pngBuf);
|
|
71
73
|
const ihdr = chunksRaw.find((c) => c.name === 'IHDR');
|
|
72
74
|
if (!ihdr)
|
|
73
75
|
return pngBuf;
|
|
74
|
-
const ihdrData = Buffer.
|
|
75
|
-
? ihdr.data
|
|
76
|
-
: Buffer.from(ihdr.data);
|
|
76
|
+
const ihdrData = Buffer.from(ihdr.data);
|
|
77
77
|
const width = ihdrData.readUInt32BE(0);
|
|
78
78
|
const height = ihdrData.readUInt32BE(4);
|
|
79
79
|
const bitDepth = ihdrData[8];
|
|
@@ -81,9 +81,7 @@ export async function optimizePngBuffer(pngBuf, fast = false) {
|
|
|
81
81
|
if (bitDepth !== 8 || colorType !== 2)
|
|
82
82
|
return pngBuf;
|
|
83
83
|
const idatChunks = chunksRaw.filter((c) => c.name === 'IDAT');
|
|
84
|
-
const idatData = Buffer.concat(idatChunks.map((c) => Buffer.
|
|
85
|
-
? c.data
|
|
86
|
-
: Buffer.from(c.data)));
|
|
84
|
+
const idatData = Buffer.concat(idatChunks.map((c) => Buffer.from(c.data)));
|
|
87
85
|
let raw;
|
|
88
86
|
try {
|
|
89
87
|
raw = zlib.inflateSync(idatData);
|
|
@@ -204,7 +202,8 @@ export async function optimizePngBuffer(pngBuf, fast = false) {
|
|
|
204
202
|
? buf
|
|
205
203
|
: Buffer.concat([PNG_HEADER, buf]);
|
|
206
204
|
}
|
|
207
|
-
const
|
|
205
|
+
const nativeEnc = require('../../libroxify_native.node');
|
|
206
|
+
const out = ensurePng(Buffer.from(nativeEnc.encodePngChunks(newChunks)));
|
|
208
207
|
let bestBuf = out.length < pngBuf.length ? out : pngBuf;
|
|
209
208
|
const strategies = [
|
|
210
209
|
zlib.constants.Z_DEFAULT_STRATEGY,
|
|
@@ -227,7 +226,8 @@ export async function optimizePngBuffer(pngBuf, fast = false) {
|
|
|
227
226
|
const idx = altChunks.findIndex((c) => c.name === 'IDAT');
|
|
228
227
|
if (idx !== -1)
|
|
229
228
|
altChunks[idx] = { name: 'IDAT', data: comp };
|
|
230
|
-
const
|
|
229
|
+
const nativeOptim = require('../../libroxify_native.node');
|
|
230
|
+
const candidate = ensurePng(Buffer.from(nativeOptim.encodePngChunks(altChunks)));
|
|
231
231
|
if (candidate.length < bestBuf.length)
|
|
232
232
|
bestBuf = candidate;
|
|
233
233
|
}
|
|
@@ -245,7 +245,8 @@ export async function optimizePngBuffer(pngBuf, fast = false) {
|
|
|
245
245
|
const idx = altChunks.findIndex((c) => c.name === 'IDAT');
|
|
246
246
|
if (idx !== -1)
|
|
247
247
|
altChunks[idx] = { name: 'IDAT', data: Buffer.from(comp) };
|
|
248
|
-
const
|
|
248
|
+
const native = require('../../libroxify_native.node');
|
|
249
|
+
const candidate = ensurePng(Buffer.from(native.encodePngChunks(altChunks)));
|
|
249
250
|
if (candidate.length < bestBuf.length)
|
|
250
251
|
bestBuf = candidate;
|
|
251
252
|
}
|
|
@@ -303,7 +304,8 @@ export async function optimizePngBuffer(pngBuf, fast = false) {
|
|
|
303
304
|
const idx = altChunks.findIndex((c) => c.name === 'IDAT');
|
|
304
305
|
if (idx !== -1)
|
|
305
306
|
altChunks[idx] = { name: 'IDAT', data: comp };
|
|
306
|
-
const
|
|
307
|
+
const native = require('../../libroxify_native.node');
|
|
308
|
+
const candidate = ensurePng(Buffer.from(native.encodePngChunks(altChunks)));
|
|
307
309
|
if (candidate.length < bestBuf.length)
|
|
308
310
|
bestBuf = candidate;
|
|
309
311
|
}
|
|
@@ -383,7 +385,8 @@ export async function optimizePngBuffer(pngBuf, fast = false) {
|
|
|
383
385
|
const idx = altChunks.findIndex((c) => c.name === 'IDAT');
|
|
384
386
|
if (idx !== -1)
|
|
385
387
|
altChunks[idx] = { name: 'IDAT', data: comp };
|
|
386
|
-
const
|
|
388
|
+
const nativeOptim2 = require('../../libroxify_native.node');
|
|
389
|
+
const candidate = ensurePng(Buffer.from(nativeOptim2.encodePngChunks(altChunks)));
|
|
387
390
|
if (candidate.length < bestBuf.length)
|
|
388
391
|
bestBuf = candidate;
|
|
389
392
|
}
|
|
@@ -589,7 +592,8 @@ export async function optimizePngBuffer(pngBuf, fast = false) {
|
|
|
589
592
|
data: zlib.deflateSync(idxFilteredAllVar, { level: 9 }),
|
|
590
593
|
});
|
|
591
594
|
palChunksVar.push({ name: 'IEND', data: Buffer.alloc(0) });
|
|
592
|
-
const
|
|
595
|
+
const native = require('../../libroxify_native.node');
|
|
596
|
+
const palOutVar = ensurePng(Buffer.from(native.encodePngChunks(palChunksVar)));
|
|
593
597
|
if (palOutVar.length < bestBuf.length)
|
|
594
598
|
bestBuf = palOutVar;
|
|
595
599
|
}
|