byte-codec 1.5.6 → 1.5.7
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/index.cjs +50 -29
- package/dist/index.js +50 -29
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -195,20 +195,45 @@ function unfilterScanlines(data, height, bytesPerRow, bpp) {
|
|
|
195
195
|
}
|
|
196
196
|
return out;
|
|
197
197
|
}
|
|
198
|
-
function
|
|
198
|
+
function filterRowInto(current, previous, bpp, filterType, target) {
|
|
199
199
|
let sum = 0;
|
|
200
|
-
|
|
200
|
+
switch (filterType) {
|
|
201
|
+
case 1:
|
|
202
|
+
target.forEach((_byte, x) => {
|
|
203
|
+
const filtered = current[x + bpp] - current[x] & 255;
|
|
204
|
+
target[x] = filtered;
|
|
205
|
+
sum += Math.min(filtered, 256 - filtered);
|
|
206
|
+
});
|
|
207
|
+
break;
|
|
208
|
+
case 2:
|
|
209
|
+
target.forEach((_byte, x) => {
|
|
210
|
+
const filtered = current[x + bpp] - previous[x + bpp] & 255;
|
|
211
|
+
target[x] = filtered;
|
|
212
|
+
sum += Math.min(filtered, 256 - filtered);
|
|
213
|
+
});
|
|
214
|
+
break;
|
|
215
|
+
case 3:
|
|
216
|
+
target.forEach((_byte, x) => {
|
|
217
|
+
const filtered = current[x + bpp] - Math.floor((current[x] + previous[x + bpp]) / 2) & 255;
|
|
218
|
+
target[x] = filtered;
|
|
219
|
+
sum += Math.min(filtered, 256 - filtered);
|
|
220
|
+
});
|
|
221
|
+
break;
|
|
222
|
+
case 4:
|
|
223
|
+
target.forEach((_byte, x) => {
|
|
224
|
+
const filtered = current[x + bpp] - paethPredictor(current[x], previous[x + bpp], previous[x]) & 255;
|
|
225
|
+
target[x] = filtered;
|
|
226
|
+
sum += Math.min(filtered, 256 - filtered);
|
|
227
|
+
});
|
|
228
|
+
break;
|
|
229
|
+
case 0: target.forEach((_byte, x) => {
|
|
230
|
+
const filtered = current[x + bpp];
|
|
231
|
+
target[x] = filtered;
|
|
232
|
+
sum += Math.min(filtered, 256 - filtered);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
201
235
|
return sum;
|
|
202
236
|
}
|
|
203
|
-
function filterRowInto(raw, rowStart, prevRowStart, bytesPerRow, bpp, filterType, out, outOffset) {
|
|
204
|
-
out.subarray(outOffset, outOffset + bytesPerRow).forEach((_byte, x) => {
|
|
205
|
-
const rawByte = raw[rowStart + x];
|
|
206
|
-
const a = x >= bpp ? raw[rowStart + x - bpp] : 0;
|
|
207
|
-
const b = prevRowStart === void 0 ? 0 : raw[prevRowStart + x];
|
|
208
|
-
const c = x >= bpp && prevRowStart !== void 0 ? raw[prevRowStart + x - bpp] : 0;
|
|
209
|
-
out[outOffset + x] = rawByte - predictorValue(filterType, a, b, c) & 255;
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
237
|
const ALL_FILTER_TYPES = [
|
|
213
238
|
0,
|
|
214
239
|
1,
|
|
@@ -219,31 +244,27 @@ const ALL_FILTER_TYPES = [
|
|
|
219
244
|
function filterScanlines(raw, height, bytesPerRow, bpp, strategy = "adaptive") {
|
|
220
245
|
const stride = bytesPerRow + 1;
|
|
221
246
|
const out = new Uint8Array(height * stride);
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
filterRowInto(raw, rowStart, prevRowStart, bytesPerRow, bpp, 0, out, outRowStart + 1);
|
|
230
|
-
continue;
|
|
231
|
-
}
|
|
247
|
+
let current = new Uint8Array(bytesPerRow + bpp);
|
|
248
|
+
let previous = new Uint8Array(bytesPerRow + bpp);
|
|
249
|
+
let candidate = new Uint8Array(bytesPerRow);
|
|
250
|
+
let best = new Uint8Array(bytesPerRow);
|
|
251
|
+
const filterTypes = strategy === "none" ? [0] : ALL_FILTER_TYPES;
|
|
252
|
+
Array.from({ length: height }).forEach((_row, y) => {
|
|
253
|
+
current.set(raw.subarray(y * bytesPerRow, (y + 1) * bytesPerRow), bpp);
|
|
232
254
|
let bestType = 0;
|
|
233
255
|
let bestSum = Number.POSITIVE_INFINITY;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
filterRowInto(raw, rowStart, prevRowStart, bytesPerRow, bpp, filterType, candidate, 0);
|
|
237
|
-
const sum = sumOfAbsSigned(candidate);
|
|
256
|
+
for (const filterType of filterTypes) {
|
|
257
|
+
const sum = filterRowInto(current, previous, bpp, filterType, candidate);
|
|
238
258
|
if (sum < bestSum) {
|
|
239
259
|
bestSum = sum;
|
|
240
260
|
bestType = filterType;
|
|
241
|
-
best = candidate
|
|
261
|
+
[best, candidate] = [candidate, best];
|
|
242
262
|
}
|
|
243
263
|
}
|
|
244
|
-
out[
|
|
245
|
-
|
|
246
|
-
|
|
264
|
+
out[y * stride] = bestType;
|
|
265
|
+
out.set(best, y * stride + 1);
|
|
266
|
+
[previous, current] = [current, previous];
|
|
267
|
+
});
|
|
247
268
|
return out;
|
|
248
269
|
}
|
|
249
270
|
//#endregion
|
package/dist/index.js
CHANGED
|
@@ -194,20 +194,45 @@ function unfilterScanlines(data, height, bytesPerRow, bpp) {
|
|
|
194
194
|
}
|
|
195
195
|
return out;
|
|
196
196
|
}
|
|
197
|
-
function
|
|
197
|
+
function filterRowInto(current, previous, bpp, filterType, target) {
|
|
198
198
|
let sum = 0;
|
|
199
|
-
|
|
199
|
+
switch (filterType) {
|
|
200
|
+
case 1:
|
|
201
|
+
target.forEach((_byte, x) => {
|
|
202
|
+
const filtered = current[x + bpp] - current[x] & 255;
|
|
203
|
+
target[x] = filtered;
|
|
204
|
+
sum += Math.min(filtered, 256 - filtered);
|
|
205
|
+
});
|
|
206
|
+
break;
|
|
207
|
+
case 2:
|
|
208
|
+
target.forEach((_byte, x) => {
|
|
209
|
+
const filtered = current[x + bpp] - previous[x + bpp] & 255;
|
|
210
|
+
target[x] = filtered;
|
|
211
|
+
sum += Math.min(filtered, 256 - filtered);
|
|
212
|
+
});
|
|
213
|
+
break;
|
|
214
|
+
case 3:
|
|
215
|
+
target.forEach((_byte, x) => {
|
|
216
|
+
const filtered = current[x + bpp] - Math.floor((current[x] + previous[x + bpp]) / 2) & 255;
|
|
217
|
+
target[x] = filtered;
|
|
218
|
+
sum += Math.min(filtered, 256 - filtered);
|
|
219
|
+
});
|
|
220
|
+
break;
|
|
221
|
+
case 4:
|
|
222
|
+
target.forEach((_byte, x) => {
|
|
223
|
+
const filtered = current[x + bpp] - paethPredictor(current[x], previous[x + bpp], previous[x]) & 255;
|
|
224
|
+
target[x] = filtered;
|
|
225
|
+
sum += Math.min(filtered, 256 - filtered);
|
|
226
|
+
});
|
|
227
|
+
break;
|
|
228
|
+
case 0: target.forEach((_byte, x) => {
|
|
229
|
+
const filtered = current[x + bpp];
|
|
230
|
+
target[x] = filtered;
|
|
231
|
+
sum += Math.min(filtered, 256 - filtered);
|
|
232
|
+
});
|
|
233
|
+
}
|
|
200
234
|
return sum;
|
|
201
235
|
}
|
|
202
|
-
function filterRowInto(raw, rowStart, prevRowStart, bytesPerRow, bpp, filterType, out, outOffset) {
|
|
203
|
-
out.subarray(outOffset, outOffset + bytesPerRow).forEach((_byte, x) => {
|
|
204
|
-
const rawByte = raw[rowStart + x];
|
|
205
|
-
const a = x >= bpp ? raw[rowStart + x - bpp] : 0;
|
|
206
|
-
const b = prevRowStart === void 0 ? 0 : raw[prevRowStart + x];
|
|
207
|
-
const c = x >= bpp && prevRowStart !== void 0 ? raw[prevRowStart + x - bpp] : 0;
|
|
208
|
-
out[outOffset + x] = rawByte - predictorValue(filterType, a, b, c) & 255;
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
236
|
const ALL_FILTER_TYPES = [
|
|
212
237
|
0,
|
|
213
238
|
1,
|
|
@@ -218,31 +243,27 @@ const ALL_FILTER_TYPES = [
|
|
|
218
243
|
function filterScanlines(raw, height, bytesPerRow, bpp, strategy = "adaptive") {
|
|
219
244
|
const stride = bytesPerRow + 1;
|
|
220
245
|
const out = new Uint8Array(height * stride);
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
filterRowInto(raw, rowStart, prevRowStart, bytesPerRow, bpp, 0, out, outRowStart + 1);
|
|
229
|
-
continue;
|
|
230
|
-
}
|
|
246
|
+
let current = new Uint8Array(bytesPerRow + bpp);
|
|
247
|
+
let previous = new Uint8Array(bytesPerRow + bpp);
|
|
248
|
+
let candidate = new Uint8Array(bytesPerRow);
|
|
249
|
+
let best = new Uint8Array(bytesPerRow);
|
|
250
|
+
const filterTypes = strategy === "none" ? [0] : ALL_FILTER_TYPES;
|
|
251
|
+
Array.from({ length: height }).forEach((_row, y) => {
|
|
252
|
+
current.set(raw.subarray(y * bytesPerRow, (y + 1) * bytesPerRow), bpp);
|
|
231
253
|
let bestType = 0;
|
|
232
254
|
let bestSum = Number.POSITIVE_INFINITY;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
filterRowInto(raw, rowStart, prevRowStart, bytesPerRow, bpp, filterType, candidate, 0);
|
|
236
|
-
const sum = sumOfAbsSigned(candidate);
|
|
255
|
+
for (const filterType of filterTypes) {
|
|
256
|
+
const sum = filterRowInto(current, previous, bpp, filterType, candidate);
|
|
237
257
|
if (sum < bestSum) {
|
|
238
258
|
bestSum = sum;
|
|
239
259
|
bestType = filterType;
|
|
240
|
-
best = candidate
|
|
260
|
+
[best, candidate] = [candidate, best];
|
|
241
261
|
}
|
|
242
262
|
}
|
|
243
|
-
out[
|
|
244
|
-
|
|
245
|
-
|
|
263
|
+
out[y * stride] = bestType;
|
|
264
|
+
out.set(best, y * stride + 1);
|
|
265
|
+
[previous, current] = [current, previous];
|
|
266
|
+
});
|
|
246
267
|
return out;
|
|
247
268
|
}
|
|
248
269
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "byte-codec",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.7",
|
|
4
4
|
"description": "Generic byte-level primitives (ByteWriter, ByteReader, CRC-32, deflate/inflate) and PNG/JPEG image encoding/decoding with zero PDF knowledge — the shared utility package for the documents.js family.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|