roxify 1.1.0 → 1.1.1
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 +1 -1
- package/dist/index.js +102 -89
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -173,7 +173,7 @@ async function decodeCommand(args) {
|
|
|
173
173
|
catch (e) {
|
|
174
174
|
console.log('Could not generate reconst PNG:', e.message);
|
|
175
175
|
}
|
|
176
|
-
console.log(`Reading: ${resolvedInputPath}`);
|
|
176
|
+
console.log(`Reading: ${resolvedInputPath.replace('_reconst.png', '.png')}`);
|
|
177
177
|
const options = {};
|
|
178
178
|
if (parsed.passphrase) {
|
|
179
179
|
options.passphrase = parsed.passphrase;
|
package/dist/index.js
CHANGED
|
@@ -108,6 +108,19 @@ async function loadRaw(imgInput) {
|
|
|
108
108
|
return { data, info };
|
|
109
109
|
}
|
|
110
110
|
export async function cropAndReconstitute(input) {
|
|
111
|
+
async function loadRaw(imgInput) {
|
|
112
|
+
const { data, info } = await sharp(imgInput)
|
|
113
|
+
.ensureAlpha()
|
|
114
|
+
.raw()
|
|
115
|
+
.toBuffer({ resolveWithObject: true });
|
|
116
|
+
return { data, info };
|
|
117
|
+
}
|
|
118
|
+
function idxFor(x, y, width) {
|
|
119
|
+
return (y * width + x) * 4;
|
|
120
|
+
}
|
|
121
|
+
function eqRGB(a, b) {
|
|
122
|
+
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2];
|
|
123
|
+
}
|
|
111
124
|
const { data, info } = await loadRaw(input);
|
|
112
125
|
const w = info.width;
|
|
113
126
|
const h = info.height;
|
|
@@ -183,8 +196,8 @@ export async function cropAndReconstitute(input) {
|
|
|
183
196
|
const sy1 = Math.min(startPoint.y, endPoint.y);
|
|
184
197
|
const sx2 = Math.max(startPoint.x, endPoint.x);
|
|
185
198
|
const sy2 = Math.max(startPoint.y, endPoint.y);
|
|
186
|
-
const cropW = sx2 - sx1;
|
|
187
|
-
const cropH = sy2 - sy1;
|
|
199
|
+
const cropW = sx2 - sx1 + 1;
|
|
200
|
+
const cropH = sy2 - sy1 + 1;
|
|
188
201
|
if (cropW <= 0 || cropH <= 0)
|
|
189
202
|
throw new Error('Invalid crop dimensions');
|
|
190
203
|
const cropped = await sharp(input)
|
|
@@ -212,19 +225,84 @@ export async function cropAndReconstitute(input) {
|
|
|
212
225
|
return false;
|
|
213
226
|
return true;
|
|
214
227
|
}
|
|
215
|
-
const
|
|
228
|
+
const newWidth = cw;
|
|
229
|
+
const newHeight = ch + 1;
|
|
230
|
+
const out = Buffer.alloc(newWidth * newHeight * 4, 0);
|
|
231
|
+
for (let i = 0; i < out.length; i += 4)
|
|
232
|
+
out[i + 3] = 255;
|
|
216
233
|
for (let y = 0; y < ch; y++) {
|
|
234
|
+
for (let x = 0; x < cw; x++) {
|
|
235
|
+
const srcI = ((y * cw + x) * 4) | 0;
|
|
236
|
+
const dstI = ((y * newWidth + x) * 4) | 0;
|
|
237
|
+
out[dstI] = cdata[srcI];
|
|
238
|
+
out[dstI + 1] = cdata[srcI + 1];
|
|
239
|
+
out[dstI + 2] = cdata[srcI + 2];
|
|
240
|
+
out[dstI + 3] = cdata[srcI + 3];
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (cw >= 3) {
|
|
244
|
+
const targetY = ch - 1;
|
|
245
|
+
for (let x = cw - 3; x < cw; x++) {
|
|
246
|
+
const i = ((targetY * newWidth + x) * 4) | 0;
|
|
247
|
+
out[i] = 0;
|
|
248
|
+
out[i + 1] = 0;
|
|
249
|
+
out[i + 2] = 0;
|
|
250
|
+
out[i + 3] = 255;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
const targetY = ch - 1;
|
|
255
|
+
for (let x = 0; x < cw; x++) {
|
|
256
|
+
const i = ((targetY * newWidth + x) * 4) | 0;
|
|
257
|
+
out[i] = 0;
|
|
258
|
+
out[i + 1] = 0;
|
|
259
|
+
out[i + 2] = 0;
|
|
260
|
+
out[i + 3] = 255;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
const lastY = ch;
|
|
264
|
+
for (let x = 0; x < newWidth; x++) {
|
|
265
|
+
const i = ((lastY * newWidth + x) * 4) | 0;
|
|
266
|
+
out[i] = 0;
|
|
267
|
+
out[i + 1] = 0;
|
|
268
|
+
out[i + 2] = 0;
|
|
269
|
+
out[i + 3] = 255;
|
|
270
|
+
}
|
|
271
|
+
if (newWidth >= 3) {
|
|
272
|
+
const bgrStart = newWidth - 3;
|
|
273
|
+
let i = ((lastY * newWidth + bgrStart) * 4) | 0;
|
|
274
|
+
out[i] = 0;
|
|
275
|
+
out[i + 1] = 0;
|
|
276
|
+
out[i + 2] = 255;
|
|
277
|
+
out[i + 3] = 255;
|
|
278
|
+
i = ((lastY * newWidth + bgrStart + 1) * 4) | 0;
|
|
279
|
+
out[i] = 0;
|
|
280
|
+
out[i + 1] = 255;
|
|
281
|
+
out[i + 2] = 0;
|
|
282
|
+
out[i + 3] = 255;
|
|
283
|
+
i = ((lastY * newWidth + bgrStart + 2) * 4) | 0;
|
|
284
|
+
out[i] = 255;
|
|
285
|
+
out[i + 1] = 0;
|
|
286
|
+
out[i + 2] = 0;
|
|
287
|
+
out[i + 3] = 255;
|
|
288
|
+
}
|
|
289
|
+
function getPixel(x, y) {
|
|
290
|
+
const i = ((y * newWidth + x) * 4) | 0;
|
|
291
|
+
return [out[i], out[i + 1], out[i + 2], out[i + 3]];
|
|
292
|
+
}
|
|
293
|
+
const compressedLines = [];
|
|
294
|
+
for (let y = 0; y < newHeight; y++) {
|
|
217
295
|
const line = [];
|
|
218
296
|
let x = 0;
|
|
219
|
-
while (x <
|
|
220
|
-
const current =
|
|
297
|
+
while (x < newWidth) {
|
|
298
|
+
const current = getPixel(x, y);
|
|
221
299
|
if (current[0] === 0 && current[1] === 0 && current[2] === 0) {
|
|
222
300
|
x++;
|
|
223
301
|
continue;
|
|
224
302
|
}
|
|
225
303
|
line.push(current);
|
|
226
304
|
let nx = x + 1;
|
|
227
|
-
while (nx <
|
|
305
|
+
while (nx < newWidth && eq(getPixel(nx, y), current))
|
|
228
306
|
nx++;
|
|
229
307
|
x = nx;
|
|
230
308
|
}
|
|
@@ -246,90 +324,25 @@ export async function cropAndReconstitute(input) {
|
|
|
246
324
|
.png()
|
|
247
325
|
.toBuffer();
|
|
248
326
|
}
|
|
249
|
-
const
|
|
250
|
-
const
|
|
251
|
-
const
|
|
252
|
-
for (let i = 0; i <
|
|
253
|
-
|
|
327
|
+
const finalWidth = Math.max(...compressedLines.map((l) => l.length));
|
|
328
|
+
const finalHeight = compressedLines.length;
|
|
329
|
+
const finalOut = Buffer.alloc(finalWidth * finalHeight * 4, 0);
|
|
330
|
+
for (let i = 0; i < finalOut.length; i += 4)
|
|
331
|
+
finalOut[i + 3] = 255;
|
|
254
332
|
for (let y = 0; y < compressedLines.length; y++) {
|
|
255
333
|
const line = compressedLines[y];
|
|
256
|
-
const
|
|
257
|
-
const startX = 0;
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
out[i + 1] = line[x][1];
|
|
265
|
-
out[i + 2] = line[x][2];
|
|
266
|
-
out[i + 3] = line[x][3] === 0 ? 255 : line[x][3];
|
|
267
|
-
}
|
|
268
|
-
if (isSecondToLast) {
|
|
269
|
-
for (let x = effectiveLength; x < Math.min(effectiveLength + 3, newWidth); x++) {
|
|
270
|
-
const i = ((y * newWidth + x) * 4) | 0;
|
|
271
|
-
out[i] = 0;
|
|
272
|
-
out[i + 1] = 0;
|
|
273
|
-
out[i + 2] = 0;
|
|
274
|
-
out[i + 3] = 255;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
const secondToLastY = newHeight - 2;
|
|
279
|
-
let secondToLastIsBlack = true;
|
|
280
|
-
for (let x = 0; x < newWidth; x++) {
|
|
281
|
-
const i = ((secondToLastY * newWidth + x) * 4) | 0;
|
|
282
|
-
if (out[i] !== 0 || out[i + 1] !== 0 || out[i + 2] !== 0) {
|
|
283
|
-
secondToLastIsBlack = false;
|
|
284
|
-
break;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
let finalHeight = newHeight;
|
|
288
|
-
let finalOut = out;
|
|
289
|
-
if (secondToLastIsBlack) {
|
|
290
|
-
finalHeight = newHeight - 1;
|
|
291
|
-
finalOut = Buffer.alloc(newWidth * finalHeight * 4, 0);
|
|
292
|
-
for (let i = 0; i < finalOut.length; i += 4)
|
|
293
|
-
finalOut[i + 3] = 255;
|
|
294
|
-
for (let y = 0; y < newHeight - 2; y++) {
|
|
295
|
-
for (let x = 0; x < newWidth; x++) {
|
|
296
|
-
const srcI = ((y * newWidth + x) * 4) | 0;
|
|
297
|
-
const dstI = ((y * newWidth + x) * 4) | 0;
|
|
298
|
-
finalOut[dstI] = out[srcI];
|
|
299
|
-
finalOut[dstI + 1] = out[srcI + 1];
|
|
300
|
-
finalOut[dstI + 2] = out[srcI + 2];
|
|
301
|
-
finalOut[dstI + 3] = out[srcI + 3];
|
|
302
|
-
}
|
|
334
|
+
const isLastLine = y === compressedLines.length - 1;
|
|
335
|
+
const startX = isLastLine ? finalWidth - line.length : 0;
|
|
336
|
+
for (let x = 0; x < line.length; x++) {
|
|
337
|
+
const i = ((y * finalWidth + startX + x) * 4) | 0;
|
|
338
|
+
finalOut[i] = line[x][0];
|
|
339
|
+
finalOut[i + 1] = line[x][1];
|
|
340
|
+
finalOut[i + 2] = line[x][2];
|
|
341
|
+
finalOut[i + 3] = line[x][3] === 0 ? 255 : line[x][3];
|
|
303
342
|
}
|
|
304
343
|
}
|
|
305
|
-
const lastY = finalHeight - 1;
|
|
306
|
-
for (let x = 0; x < newWidth; x++) {
|
|
307
|
-
const i = ((lastY * newWidth + x) * 4) | 0;
|
|
308
|
-
finalOut[i] = 0;
|
|
309
|
-
finalOut[i + 1] = 0;
|
|
310
|
-
finalOut[i + 2] = 0;
|
|
311
|
-
finalOut[i + 3] = 255;
|
|
312
|
-
}
|
|
313
|
-
if (newWidth >= 3) {
|
|
314
|
-
const bgrStart = newWidth - 3;
|
|
315
|
-
let i = ((lastY * newWidth + bgrStart) * 4) | 0;
|
|
316
|
-
finalOut[i] = 0;
|
|
317
|
-
finalOut[i + 1] = 0;
|
|
318
|
-
finalOut[i + 2] = 255;
|
|
319
|
-
finalOut[i + 3] = 255;
|
|
320
|
-
i = ((lastY * newWidth + bgrStart + 1) * 4) | 0;
|
|
321
|
-
finalOut[i] = 0;
|
|
322
|
-
finalOut[i + 1] = 255;
|
|
323
|
-
finalOut[i + 2] = 0;
|
|
324
|
-
finalOut[i + 3] = 255;
|
|
325
|
-
i = ((lastY * newWidth + bgrStart + 2) * 4) | 0;
|
|
326
|
-
finalOut[i] = 255;
|
|
327
|
-
finalOut[i + 1] = 0;
|
|
328
|
-
finalOut[i + 2] = 0;
|
|
329
|
-
finalOut[i + 3] = 255;
|
|
330
|
-
}
|
|
331
344
|
return sharp(finalOut, {
|
|
332
|
-
raw: { width:
|
|
345
|
+
raw: { width: finalWidth, height: finalHeight, channels: 4 },
|
|
333
346
|
})
|
|
334
347
|
.png()
|
|
335
348
|
.toBuffer();
|
|
@@ -442,7 +455,7 @@ export async function encodeBinaryToPng(input, opts = {}) {
|
|
|
442
455
|
const spaceInLastRow = pixelsInLastRow === 0 ? logicalWidth : logicalWidth - pixelsInLastRow;
|
|
443
456
|
const needsExtraRow = spaceInLastRow < MARKER_END.length;
|
|
444
457
|
const logicalHeight = needsExtraRow ? dataRows + 1 : dataRows;
|
|
445
|
-
const scale =
|
|
458
|
+
const scale = 2;
|
|
446
459
|
const width = logicalWidth * scale;
|
|
447
460
|
const height = logicalHeight * scale;
|
|
448
461
|
const raw = Buffer.alloc(width * height * bytesPerPixel);
|
|
@@ -489,10 +502,10 @@ export async function encodeBinaryToPng(input, opts = {}) {
|
|
|
489
502
|
raw: { width, height, channels: 3 },
|
|
490
503
|
})
|
|
491
504
|
.png({
|
|
492
|
-
compressionLevel:
|
|
505
|
+
compressionLevel: 9,
|
|
493
506
|
palette: false,
|
|
494
|
-
effort:
|
|
495
|
-
adaptiveFiltering:
|
|
507
|
+
effort: 10,
|
|
508
|
+
adaptiveFiltering: true,
|
|
496
509
|
})
|
|
497
510
|
.toBuffer();
|
|
498
511
|
}
|