roxify 1.1.2 → 1.1.4
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 -20
- package/dist/index.js +193 -179
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { readFileSync, writeFileSync } from 'fs';
|
|
3
|
-
import { basename, dirname,
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
const VERSION = '1.0.4';
|
|
3
|
+
import { basename, dirname, resolve } from 'path';
|
|
4
|
+
import { DataFormatError, decodePngToBinary, encodeBinaryToPng, IncorrectPassphraseError, PassphraseRequiredError, } from './index.js';
|
|
5
|
+
const VERSION = '1.1.4';
|
|
7
6
|
function showHelp() {
|
|
8
7
|
console.log(`
|
|
9
8
|
ROX CLI — Encode/decode binary in PNG
|
|
@@ -167,7 +166,6 @@ async function decodeCommand(args) {
|
|
|
167
166
|
try {
|
|
168
167
|
const inputBuffer = readFileSync(resolvedInput);
|
|
169
168
|
console.log(`Reading: ${resolvedInput}`);
|
|
170
|
-
const info = await sharp(inputBuffer).metadata();
|
|
171
169
|
const options = {};
|
|
172
170
|
if (parsed.passphrase) {
|
|
173
171
|
options.passphrase = parsed.passphrase;
|
|
@@ -177,21 +175,7 @@ async function decodeCommand(args) {
|
|
|
177
175
|
}
|
|
178
176
|
console.log(`Decoding...`);
|
|
179
177
|
const startDecode = Date.now();
|
|
180
|
-
|
|
181
|
-
options.verbose = true;
|
|
182
|
-
const doubledBuffer = await sharp(inputBuffer)
|
|
183
|
-
.resize({
|
|
184
|
-
width: info.width * 2,
|
|
185
|
-
height: info.height * 2,
|
|
186
|
-
kernel: 'nearest',
|
|
187
|
-
})
|
|
188
|
-
.png()
|
|
189
|
-
.toBuffer();
|
|
190
|
-
if (options.debugDir) {
|
|
191
|
-
writeFileSync(join(options.debugDir, 'doubled.png'), doubledBuffer);
|
|
192
|
-
}
|
|
193
|
-
const reconstructedBuffer = await cropAndReconstitute(doubledBuffer, options.debugDir);
|
|
194
|
-
const result = await decodePngToBinary(reconstructedBuffer, options);
|
|
178
|
+
const result = await decodePngToBinary(inputBuffer, options);
|
|
195
179
|
const decodeTime = Date.now() - startDecode;
|
|
196
180
|
const resolvedOutput = parsed.output || outputPath || result.meta?.name || 'decoded.bin';
|
|
197
181
|
writeFileSync(resolvedOutput, result.buf);
|
package/dist/index.js
CHANGED
|
@@ -148,9 +148,8 @@ export async function cropAndReconstitute(input, debugDir) {
|
|
|
148
148
|
await sharp(doubledBuffer).toFile(join(debugDir, 'doubled.png'));
|
|
149
149
|
}
|
|
150
150
|
const { data: doubledData, info: doubledInfo } = await loadRaw(doubledBuffer);
|
|
151
|
-
const w = doubledInfo.width;
|
|
152
|
-
const
|
|
153
|
-
function at(x, y) {
|
|
151
|
+
const w = doubledInfo.width, h = doubledInfo.height;
|
|
152
|
+
const at = (x, y) => {
|
|
154
153
|
const i = idxFor(x, y, w);
|
|
155
154
|
return [
|
|
156
155
|
doubledData[i],
|
|
@@ -158,178 +157,110 @@ export async function cropAndReconstitute(input, debugDir) {
|
|
|
158
157
|
doubledData[i + 2],
|
|
159
158
|
doubledData[i + 3],
|
|
160
159
|
];
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
let endPoint = null;
|
|
193
|
-
for (let y = h - 1; y >= 0 && !endPoint; y--) {
|
|
194
|
-
for (let x = w - 1; x >= 0; x--) {
|
|
195
|
-
const p = at(x, y);
|
|
196
|
-
if (p[0] !== 255 || p[1] !== 0 || p[2] !== 0)
|
|
197
|
-
continue;
|
|
198
|
-
let nx = x - 1;
|
|
199
|
-
while (nx >= 0 && eqRGB(at(nx, y), p))
|
|
200
|
-
nx--;
|
|
201
|
-
if (nx < 0)
|
|
202
|
-
continue;
|
|
203
|
-
const a = at(nx, y);
|
|
204
|
-
let nx2 = nx - 1;
|
|
205
|
-
while (nx2 >= 0 && eqRGB(at(nx2, y), a))
|
|
206
|
-
nx2--;
|
|
207
|
-
if (nx2 < 0)
|
|
208
|
-
continue;
|
|
209
|
-
const b = at(nx2, y);
|
|
210
|
-
const isRgbReverse = a[0] === 0 &&
|
|
211
|
-
a[1] === 255 &&
|
|
212
|
-
a[2] === 0 &&
|
|
213
|
-
b[0] === 0 &&
|
|
214
|
-
b[1] === 0 &&
|
|
215
|
-
b[2] === 255;
|
|
216
|
-
if (isRgbReverse) {
|
|
217
|
-
endPoint = { x, y, type: 'bgr' };
|
|
218
|
-
break;
|
|
160
|
+
};
|
|
161
|
+
const findPattern = (startX, startY, dirX, dirY, pattern) => {
|
|
162
|
+
for (let y = startY; y >= 0 && y < h; y += dirY) {
|
|
163
|
+
for (let x = startX; x >= 0 && x < w; x += dirX) {
|
|
164
|
+
const p = at(x, y);
|
|
165
|
+
if (p[0] !== 255 || p[1] !== 0 || p[2] !== 0)
|
|
166
|
+
continue;
|
|
167
|
+
let nx = x + dirX;
|
|
168
|
+
while (nx >= 0 && nx < w && eqRGB(at(nx, y), p))
|
|
169
|
+
nx += dirX;
|
|
170
|
+
if (nx < 0 || nx >= w)
|
|
171
|
+
continue;
|
|
172
|
+
const a = at(nx, y);
|
|
173
|
+
let nx2 = nx + dirX;
|
|
174
|
+
while (nx2 >= 0 && nx2 < w && eqRGB(at(nx2, y), a))
|
|
175
|
+
nx2 += dirX;
|
|
176
|
+
if (nx2 < 0 || nx2 >= w)
|
|
177
|
+
continue;
|
|
178
|
+
const b = at(nx2, y);
|
|
179
|
+
if (a[0] === pattern[0][0] &&
|
|
180
|
+
a[1] === pattern[0][1] &&
|
|
181
|
+
a[2] === pattern[0][2] &&
|
|
182
|
+
b[0] === pattern[1][0] &&
|
|
183
|
+
b[1] === pattern[1][1] &&
|
|
184
|
+
b[2] === pattern[1][2]) {
|
|
185
|
+
return { x, y };
|
|
186
|
+
}
|
|
219
187
|
}
|
|
220
188
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
189
|
+
return null;
|
|
190
|
+
};
|
|
191
|
+
const startPoint = findPattern(0, 0, 1, 1, [
|
|
192
|
+
[0, 255, 0],
|
|
193
|
+
[0, 0, 255],
|
|
194
|
+
]);
|
|
195
|
+
const endPoint = findPattern(w - 1, h - 1, -1, -1, [
|
|
196
|
+
[0, 255, 0],
|
|
197
|
+
[0, 0, 255],
|
|
198
|
+
]);
|
|
199
|
+
if (!startPoint || !endPoint)
|
|
200
|
+
throw new Error('Patterns not found');
|
|
201
|
+
const sx1 = Math.min(startPoint.x, endPoint.x), sy1 = Math.min(startPoint.y, endPoint.y);
|
|
202
|
+
const sx2 = Math.max(startPoint.x, endPoint.x), sy2 = Math.max(startPoint.y, endPoint.y);
|
|
203
|
+
const cropW = sx2 - sx1 + 1, cropH = sy2 - sy1 + 1;
|
|
232
204
|
if (cropW <= 0 || cropH <= 0)
|
|
233
205
|
throw new Error('Invalid crop dimensions');
|
|
234
206
|
const cropped = await sharp(doubledBuffer)
|
|
235
207
|
.extract({ left: sx1, top: sy1, width: cropW, height: cropH })
|
|
236
208
|
.png()
|
|
237
209
|
.toBuffer();
|
|
238
|
-
const { data: cdata, info: cinfo } = await
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
.toBuffer({ resolveWithObject: true });
|
|
242
|
-
const cw = cinfo.width;
|
|
243
|
-
const ch = cinfo.height;
|
|
244
|
-
function cat(x, y) {
|
|
245
|
-
const i = idxFor(x, y, cw);
|
|
246
|
-
return [cdata[i], cdata[i + 1], cdata[i + 2], cdata[i + 3]];
|
|
247
|
-
}
|
|
248
|
-
function eq(a, b) {
|
|
249
|
-
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3];
|
|
250
|
-
}
|
|
251
|
-
function lineEq(l1, l2) {
|
|
252
|
-
if (l1.length !== l2.length)
|
|
253
|
-
return false;
|
|
254
|
-
for (let i = 0; i < l1.length; i++)
|
|
255
|
-
if (!eq(l1[i], l2[i]))
|
|
256
|
-
return false;
|
|
257
|
-
return true;
|
|
258
|
-
}
|
|
259
|
-
const newWidth = cw;
|
|
260
|
-
const newHeight = ch + 1;
|
|
210
|
+
const { data: cdata, info: cinfo } = await loadRaw(cropped);
|
|
211
|
+
const cw = cinfo.width, ch = cinfo.height;
|
|
212
|
+
const newWidth = cw, newHeight = ch + 1;
|
|
261
213
|
const out = Buffer.alloc(newWidth * newHeight * 4, 0);
|
|
262
214
|
for (let i = 0; i < out.length; i += 4)
|
|
263
215
|
out[i + 3] = 255;
|
|
264
216
|
for (let y = 0; y < ch; y++) {
|
|
265
217
|
for (let x = 0; x < cw; x++) {
|
|
266
|
-
const srcI = (
|
|
267
|
-
const dstI = (
|
|
218
|
+
const srcI = (y * cw + x) * 4;
|
|
219
|
+
const dstI = (y * newWidth + x) * 4;
|
|
268
220
|
out[dstI] = cdata[srcI];
|
|
269
221
|
out[dstI + 1] = cdata[srcI + 1];
|
|
270
222
|
out[dstI + 2] = cdata[srcI + 2];
|
|
271
223
|
out[dstI + 3] = cdata[srcI + 3];
|
|
272
224
|
}
|
|
273
225
|
}
|
|
274
|
-
const targetY = ch - 1;
|
|
275
|
-
for (let x = 0; x < cw; x++) {
|
|
276
|
-
const i = ((targetY * newWidth + x) * 4) | 0;
|
|
277
|
-
out[i] = 0;
|
|
278
|
-
out[i + 1] = 0;
|
|
279
|
-
out[i + 2] = 0;
|
|
280
|
-
out[i + 3] = 255;
|
|
281
|
-
}
|
|
282
|
-
const lastY = ch;
|
|
283
226
|
for (let x = 0; x < newWidth; x++) {
|
|
284
|
-
const i = ((
|
|
285
|
-
out[i] = 0;
|
|
286
|
-
out[i + 1] = 0;
|
|
287
|
-
out[i + 2] = 0;
|
|
227
|
+
const i = ((ch - 1) * newWidth + x) * 4;
|
|
228
|
+
out[i] = out[i + 1] = out[i + 2] = 0;
|
|
288
229
|
out[i + 3] = 255;
|
|
230
|
+
const j = (ch * newWidth + x) * 4;
|
|
231
|
+
out[j] = out[j + 1] = out[j + 2] = 0;
|
|
232
|
+
out[j + 3] = 255;
|
|
289
233
|
}
|
|
290
234
|
if (newWidth >= 3) {
|
|
291
235
|
const bgrStart = newWidth - 3;
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
out[i + 1] = 0;
|
|
305
|
-
out[i + 2] = 0;
|
|
306
|
-
out[i + 3] = 255;
|
|
236
|
+
const bgr = [
|
|
237
|
+
[0, 0, 255],
|
|
238
|
+
[0, 255, 0],
|
|
239
|
+
[255, 0, 0],
|
|
240
|
+
];
|
|
241
|
+
for (let k = 0; k < 3; k++) {
|
|
242
|
+
const i = (ch * newWidth + bgrStart + k) * 4;
|
|
243
|
+
out[i] = bgr[k][0];
|
|
244
|
+
out[i + 1] = bgr[k][1];
|
|
245
|
+
out[i + 2] = bgr[k][2];
|
|
246
|
+
out[i + 3] = 255;
|
|
247
|
+
}
|
|
307
248
|
}
|
|
308
|
-
|
|
309
|
-
const i = (
|
|
249
|
+
const getPixel = (x, y) => {
|
|
250
|
+
const i = (y * newWidth + x) * 4;
|
|
310
251
|
return [out[i], out[i + 1], out[i + 2], out[i + 3]];
|
|
311
|
-
}
|
|
252
|
+
};
|
|
312
253
|
const compressedLines = [];
|
|
313
254
|
for (let y = 0; y < newHeight; y++) {
|
|
314
255
|
const line = [];
|
|
315
|
-
let x = 0;
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
line.push(current);
|
|
323
|
-
let nx = x + 1;
|
|
324
|
-
while (nx < newWidth && eq(getPixel(nx, y), current))
|
|
325
|
-
nx++;
|
|
326
|
-
x = nx;
|
|
327
|
-
}
|
|
328
|
-
if (line.length === 0)
|
|
329
|
-
continue;
|
|
330
|
-
if (compressedLines.length === 0 ||
|
|
331
|
-
!lineEq(compressedLines[compressedLines.length - 1], line))
|
|
256
|
+
for (let x = 0; x < newWidth; x++)
|
|
257
|
+
line.push(getPixel(x, y));
|
|
258
|
+
const isAllBlack = line.every((p) => p[0] === 0 && p[1] === 0 && p[2] === 0 && p[3] === 255);
|
|
259
|
+
if (!isAllBlack &&
|
|
260
|
+
(compressedLines.length === 0 ||
|
|
261
|
+
!line.every((p, i) => p.every((v, j) => v === compressedLines[compressedLines.length - 1][i][j])))) {
|
|
332
262
|
compressedLines.push(line);
|
|
263
|
+
}
|
|
333
264
|
}
|
|
334
265
|
if (compressedLines.length === 0) {
|
|
335
266
|
return sharp({
|
|
@@ -343,49 +274,116 @@ export async function cropAndReconstitute(input, debugDir) {
|
|
|
343
274
|
.png()
|
|
344
275
|
.toBuffer();
|
|
345
276
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
const finalOut = Buffer.alloc(finalWidth * finalHeight * 4, 0);
|
|
277
|
+
let finalWidth = newWidth, finalHeight = compressedLines.length;
|
|
278
|
+
let finalOut = Buffer.alloc(finalWidth * finalHeight * 4, 0);
|
|
349
279
|
for (let i = 0; i < finalOut.length; i += 4)
|
|
350
280
|
finalOut[i + 3] = 255;
|
|
351
|
-
for (let y = 0; y <
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
finalOut[i] =
|
|
358
|
-
finalOut[i + 1] = line[x][1];
|
|
359
|
-
finalOut[i + 2] = line[x][2];
|
|
360
|
-
finalOut[i + 3] = line[x][3] === 0 ? 255 : line[x][3];
|
|
281
|
+
for (let y = 0; y < finalHeight; y++) {
|
|
282
|
+
for (let x = 0; x < finalWidth; x++) {
|
|
283
|
+
const i = (y * finalWidth + x) * 4;
|
|
284
|
+
finalOut[i] = compressedLines[y][x][0];
|
|
285
|
+
finalOut[i + 1] = compressedLines[y][x][1];
|
|
286
|
+
finalOut[i + 2] = compressedLines[y][x][2];
|
|
287
|
+
finalOut[i + 3] = compressedLines[y][x][3] || 255;
|
|
361
288
|
}
|
|
362
289
|
}
|
|
363
|
-
if (finalHeight >=
|
|
364
|
-
const
|
|
290
|
+
if (finalHeight >= 1 && finalWidth >= 3) {
|
|
291
|
+
const lastY = finalHeight - 1;
|
|
292
|
+
for (let k = 0; k < 3; k++) {
|
|
293
|
+
const i = (lastY * finalWidth + finalWidth - 3 + k) * 4;
|
|
294
|
+
finalOut[i] = finalOut[i + 1] = finalOut[i + 2] = 0;
|
|
295
|
+
finalOut[i + 3] = 255;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (finalWidth >= 2) {
|
|
299
|
+
const kept = [];
|
|
365
300
|
for (let x = 0; x < finalWidth; x++) {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
finalOut[
|
|
375
|
-
|
|
301
|
+
if (kept.length === 0) {
|
|
302
|
+
kept.push(x);
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
const prevX = kept[kept.length - 1];
|
|
306
|
+
let same = true;
|
|
307
|
+
for (let y = 0; y < finalHeight; y++) {
|
|
308
|
+
const ia = (y * finalWidth + prevX) * 4, ib = (y * finalWidth + x) * 4;
|
|
309
|
+
if (finalOut[ia] !== finalOut[ib] ||
|
|
310
|
+
finalOut[ia + 1] !== finalOut[ib + 1] ||
|
|
311
|
+
finalOut[ia + 2] !== finalOut[ib + 2] ||
|
|
312
|
+
finalOut[ia + 3] !== finalOut[ib + 3]) {
|
|
313
|
+
same = false;
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (!same)
|
|
318
|
+
kept.push(x);
|
|
319
|
+
}
|
|
320
|
+
if (kept.length !== finalWidth) {
|
|
321
|
+
const newFinalWidth = kept.length;
|
|
322
|
+
const newOut = Buffer.alloc(newFinalWidth * finalHeight * 4, 0);
|
|
323
|
+
for (let i = 0; i < newOut.length; i += 4)
|
|
324
|
+
newOut[i + 3] = 255;
|
|
325
|
+
for (let nx = 0; nx < kept.length; nx++) {
|
|
326
|
+
const sx = kept[nx];
|
|
327
|
+
for (let y = 0; y < finalHeight; y++) {
|
|
328
|
+
const srcI = (y * finalWidth + sx) * 4, dstI = (y * newFinalWidth + nx) * 4;
|
|
329
|
+
newOut[dstI] = finalOut[srcI];
|
|
330
|
+
newOut[dstI + 1] = finalOut[srcI + 1];
|
|
331
|
+
newOut[dstI + 2] = finalOut[srcI + 2];
|
|
332
|
+
newOut[dstI + 3] = finalOut[srcI + 3];
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
finalOut = newOut;
|
|
336
|
+
finalWidth = newFinalWidth;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (finalHeight >= 2 && finalWidth >= 3) {
|
|
340
|
+
const secondLastY = finalHeight - 2;
|
|
341
|
+
const bgrSeq = [
|
|
342
|
+
[0, 0, 255],
|
|
343
|
+
[0, 255, 0],
|
|
344
|
+
[255, 0, 0],
|
|
345
|
+
];
|
|
346
|
+
let hasBGR = true;
|
|
347
|
+
for (let k = 0; k < 3; k++) {
|
|
348
|
+
const i = (secondLastY * finalWidth + finalWidth - 3 + k) * 4;
|
|
349
|
+
if (finalOut[i] !== bgrSeq[k][0] ||
|
|
350
|
+
finalOut[i + 1] !== bgrSeq[k][1] ||
|
|
351
|
+
finalOut[i + 2] !== bgrSeq[k][2]) {
|
|
352
|
+
hasBGR = false;
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (hasBGR) {
|
|
357
|
+
for (let k = 0; k < 3; k++) {
|
|
358
|
+
const i = (secondLastY * finalWidth + finalWidth - 3 + k) * 4;
|
|
359
|
+
finalOut[i] = finalOut[i + 1] = finalOut[i + 2] = 0;
|
|
376
360
|
finalOut[i + 3] = 255;
|
|
377
361
|
}
|
|
378
362
|
}
|
|
379
363
|
}
|
|
380
|
-
|
|
364
|
+
if (finalHeight >= 1 && finalWidth >= 1) {
|
|
365
|
+
const lastYFinal = finalHeight - 1;
|
|
366
|
+
const bgrSeq = [
|
|
367
|
+
[0, 0, 255],
|
|
368
|
+
[0, 255, 0],
|
|
369
|
+
[255, 0, 0],
|
|
370
|
+
];
|
|
371
|
+
for (let k = 0; k < 3; k++) {
|
|
372
|
+
const sx = finalWidth - 3 + k;
|
|
373
|
+
if (sx >= 0) {
|
|
374
|
+
const i = (lastYFinal * finalWidth + sx) * 4;
|
|
375
|
+
finalOut[i] = bgrSeq[k][0];
|
|
376
|
+
finalOut[i + 1] = bgrSeq[k][1];
|
|
377
|
+
finalOut[i + 2] = bgrSeq[k][2];
|
|
378
|
+
finalOut[i + 3] = 255;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return sharp(finalOut, {
|
|
381
383
|
raw: { width: finalWidth, height: finalHeight, channels: 4 },
|
|
382
384
|
})
|
|
383
385
|
.png()
|
|
384
386
|
.toBuffer();
|
|
385
|
-
if (debugDir) {
|
|
386
|
-
await sharp(resultBuffer).toFile(join(debugDir, 'reconstructed.png'));
|
|
387
|
-
}
|
|
388
|
-
return resultBuffer;
|
|
389
387
|
}
|
|
390
388
|
/**
|
|
391
389
|
* Encode a Buffer into a PNG wrapper. Supports optional compression and
|
|
@@ -652,8 +650,24 @@ export async function encodeBinaryToPng(input, opts = {}) {
|
|
|
652
650
|
* @public
|
|
653
651
|
*/
|
|
654
652
|
export async function decodePngToBinary(pngBuf, opts = {}) {
|
|
655
|
-
|
|
656
|
-
|
|
653
|
+
let processedBuf = pngBuf;
|
|
654
|
+
try {
|
|
655
|
+
const info = await sharp(pngBuf).metadata();
|
|
656
|
+
if (info.width && info.height) {
|
|
657
|
+
const doubledBuffer = await sharp(pngBuf)
|
|
658
|
+
.resize({
|
|
659
|
+
width: info.width * 2,
|
|
660
|
+
height: info.height * 2,
|
|
661
|
+
kernel: 'nearest',
|
|
662
|
+
})
|
|
663
|
+
.png()
|
|
664
|
+
.toBuffer();
|
|
665
|
+
processedBuf = await cropAndReconstitute(doubledBuffer, opts.debugDir);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
catch (e) { }
|
|
669
|
+
if (processedBuf.slice(0, MAGIC.length).equals(MAGIC)) {
|
|
670
|
+
const d = processedBuf.slice(MAGIC.length);
|
|
657
671
|
const nameLen = d[0];
|
|
658
672
|
let idx = 1;
|
|
659
673
|
let name;
|
|
@@ -680,7 +694,7 @@ export async function decodePngToBinary(pngBuf, opts = {}) {
|
|
|
680
694
|
}
|
|
681
695
|
let chunks = [];
|
|
682
696
|
try {
|
|
683
|
-
const chunksRaw = extract(
|
|
697
|
+
const chunksRaw = extract(processedBuf);
|
|
684
698
|
chunks = chunksRaw.map((c) => ({
|
|
685
699
|
name: c.name,
|
|
686
700
|
data: Buffer.isBuffer(c.data)
|
|
@@ -733,7 +747,7 @@ export async function decodePngToBinary(pngBuf, opts = {}) {
|
|
|
733
747
|
return { buf: payload, meta: { name } };
|
|
734
748
|
}
|
|
735
749
|
try {
|
|
736
|
-
const { data, info } = await sharp(
|
|
750
|
+
const { data, info } = await sharp(processedBuf)
|
|
737
751
|
.ensureAlpha()
|
|
738
752
|
.raw()
|
|
739
753
|
.toBuffer({ resolveWithObject: true });
|
package/package.json
CHANGED