byte-codec 1.5.2 → 1.5.3

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 CHANGED
@@ -8,7 +8,6 @@ var ByteWriter = class {
8
8
  return this.byteLength;
9
9
  }
10
10
  writeBytes(bytes) {
11
- if (bytes.length === 0) return;
12
11
  this.chunks.push(bytes);
13
12
  this.byteLength += bytes.length;
14
13
  }
@@ -128,8 +127,8 @@ function inflateTolerant(data) {
128
127
  };
129
128
  } catch {}
130
129
  let offset = 0;
131
- while (offset < data.length && isAsciiWhitespace(data[offset])) offset++;
132
- if (offset > 0) try {
130
+ while (isAsciiWhitespace(data[offset])) offset++;
131
+ try {
133
132
  return {
134
133
  bytes: inflate(data.subarray(offset)),
135
134
  recovered: true
@@ -161,8 +160,9 @@ function paethPredictor(a, b, c) {
161
160
  const pa = Math.abs(p - a);
162
161
  const pb = Math.abs(p - b);
163
162
  const pc = Math.abs(p - c);
164
- if (pa <= pb && pa <= pc) return a;
165
- if (pb <= pc) return b;
163
+ const smallest = Math.min(pa, pb, pc);
164
+ if (smallest === pa) return a;
165
+ if (smallest === pb) return b;
166
166
  return c;
167
167
  }
168
168
  function isPngFilterType(value) {
@@ -185,7 +185,7 @@ function unfilterScanlines(data, height, bytesPerRow, bpp) {
185
185
  const rowStart = y * stride + 1;
186
186
  const outRowStart = y * bytesPerRow;
187
187
  const prevOutRowStart = y > 0 ? outRowStart - bytesPerRow : void 0;
188
- for (let x = 0; x < bytesPerRow; x++) {
188
+ for (const x of Array.from({ length: bytesPerRow }, (_, i) => i)) {
189
189
  const raw = data[rowStart + x];
190
190
  const a = x >= bpp ? out[outRowStart + x - bpp] : 0;
191
191
  const b = prevOutRowStart === void 0 ? 0 : out[prevOutRowStart + x];
@@ -197,11 +197,11 @@ function unfilterScanlines(data, height, bytesPerRow, bpp) {
197
197
  }
198
198
  function sumOfAbsSigned(bytes) {
199
199
  let sum = 0;
200
- for (const byte of bytes) sum += byte < 128 ? byte : 256 - byte;
200
+ for (const byte of bytes) sum += Math.min(byte, 256 - byte);
201
201
  return sum;
202
202
  }
203
203
  function filterRowInto(raw, rowStart, prevRowStart, bytesPerRow, bpp, filterType, out, outOffset) {
204
- for (let x = 0; x < bytesPerRow; x++) {
204
+ for (const x of Array.from({ length: bytesPerRow }, (_, i) => i)) {
205
205
  const rawByte = raw[rowStart + x];
206
206
  const a = x >= bpp ? raw[rowStart + x - bpp] : 0;
207
207
  const b = prevRowStart === void 0 ? 0 : raw[prevRowStart + x];
@@ -305,7 +305,7 @@ function detectPalette(image) {
305
305
  const g = data[base + 1] ?? 0;
306
306
  const b = data[base + 2] ?? 0;
307
307
  const a = alpha === void 0 ? 255 : alpha[i] ?? 0;
308
- const key = r + g * 256 + b * 65536 + a * 16777216;
308
+ const key = r | g << 8 | b << 16 | a << 24;
309
309
  let index = colorToIndex.get(key);
310
310
  if (index === void 0) {
311
311
  if (colorToIndex.size >= MAX_PALETTE_ENTRIES) return;
@@ -348,10 +348,10 @@ function writeTruecolorPng(writer, image, options) {
348
348
  const bytesPerRow = width * outChannels;
349
349
  const pixelCount = width * height;
350
350
  const interleaved = new Uint8Array(pixelCount * outChannels);
351
- for (let i = 0; i < pixelCount; i++) {
351
+ for (const i of Array.from({ length: pixelCount }, (_, index) => index)) {
352
352
  const srcBase = i * channels;
353
353
  const dstBase = i * outChannels;
354
- for (let c = 0; c < channels; c++) interleaved[dstBase + c] = data[srcBase + c];
354
+ for (const c of Array.from({ length: channels }, (_, index) => index)) interleaved[dstBase + c] = data[srcBase + c];
355
355
  if (alpha !== void 0) interleaved[dstBase + channels] = alpha[i];
356
356
  }
357
357
  writeIhdr(writer, width, height, colorTypeFor(image));
@@ -435,19 +435,14 @@ function filterBpp(bitDepth, channels) {
435
435
  }
436
436
  function unpackRow(rowBytes, width, channels, bitDepth) {
437
437
  const sampleCount = width * channels;
438
- const samples = [];
439
- if (bitDepth === 8) for (let i = 0; i < sampleCount; i++) samples[i] = rowBytes[i];
440
- else if (bitDepth === 16) for (let i = 0; i < sampleCount; i++) samples[i] = rowBytes[i * 2];
441
- else {
442
- const mask = (1 << bitDepth) - 1;
443
- for (let i = 0; i < sampleCount; i++) {
444
- const bitOffset = i * bitDepth;
445
- const byteIndex = bitOffset >> 3;
446
- const shift = 8 - bitDepth - (bitOffset & 7);
447
- samples[i] = rowBytes[byteIndex] >> shift & mask;
448
- }
449
- }
450
- return samples;
438
+ if (bitDepth === 16) return Array.from({ length: sampleCount }, (_, i) => rowBytes[i * 2]);
439
+ const mask = (1 << bitDepth) - 1;
440
+ return Array.from({ length: sampleCount }, (_, i) => {
441
+ const bitOffset = i * bitDepth;
442
+ const byteIndex = bitOffset >> 3;
443
+ const shift = 8 - bitDepth - (bitOffset & 7);
444
+ return rowBytes[byteIndex] >> shift & mask;
445
+ });
451
446
  }
452
447
  function readTrnsGrayValue(trns) {
453
448
  return requireDataView(trns).getUint16(0);
@@ -480,7 +475,7 @@ function decodePng(bytes, options = {}) {
480
475
  const { bytes: inflated, recovered } = inflateTolerant(concatBytes(idatChunks));
481
476
  if (recovered && options.onWarning !== void 0) options.onWarning("PNG IDAT stream required tolerant recovery (truncated or malformed)");
482
477
  const unfiltered = unfilterScanlines(inflated, ihdr.height, bytesPerRow, bpp);
483
- const palette = ihdr.colorType === 3 ? chunks.find((c) => c.type === "PLTE")?.data : void 0;
478
+ const palette = chunks.find((c) => c.type === "PLTE")?.data;
484
479
  if (ihdr.colorType === 3 && palette === void 0) throw new Error("indexed-colour PNG has no PLTE chunk");
485
480
  const trns = chunks.find((c) => c.type === "tRNS")?.data;
486
481
  return buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns);
@@ -492,10 +487,10 @@ function buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns) {
492
487
  const alpha = colorType === 4 || colorType === 6 || trns !== void 0 ? new Uint8Array(width * height).fill(255) : void 0;
493
488
  const trnsGray = colorType === 0 && trns !== void 0 ? readTrnsGrayValue(trns) : void 0;
494
489
  const trnsRgb = colorType === 2 && trns !== void 0 ? readTrnsRgbKey(trns) : void 0;
495
- for (let y = 0; y < height; y++) {
490
+ for (const y of Array.from({ length: height }, (_, i) => i)) {
496
491
  const rowStart = y * bytesPerRow;
497
492
  const samples = unpackRow(unfiltered.subarray(rowStart, rowStart + bytesPerRow), width, channels, bitDepth);
498
- for (let x = 0; x < width; x++) {
493
+ for (const x of Array.from({ length: width }, (_, i) => i)) {
499
494
  const pixelBase = x * channels;
500
495
  const outBase = (y * width + x) * outChannels;
501
496
  const alphaIndex = y * width + x;
@@ -584,7 +579,7 @@ function readJpegInfo(bytes) {
584
579
  if (requireByte(bytes, 0) !== 255 || requireByte(bytes, 1) !== SOI) throw new Error("not a valid JPEG file: missing SOI marker");
585
580
  let offset = 2;
586
581
  let adobeTransform;
587
- while (offset < bytes.length) {
582
+ while (bytes[offset] !== void 0) {
588
583
  if (bytes[offset] !== 255) {
589
584
  offset++;
590
585
  continue;
package/dist/index.js CHANGED
@@ -7,7 +7,6 @@ var ByteWriter = class {
7
7
  return this.byteLength;
8
8
  }
9
9
  writeBytes(bytes) {
10
- if (bytes.length === 0) return;
11
10
  this.chunks.push(bytes);
12
11
  this.byteLength += bytes.length;
13
12
  }
@@ -127,8 +126,8 @@ function inflateTolerant(data) {
127
126
  };
128
127
  } catch {}
129
128
  let offset = 0;
130
- while (offset < data.length && isAsciiWhitespace(data[offset])) offset++;
131
- if (offset > 0) try {
129
+ while (isAsciiWhitespace(data[offset])) offset++;
130
+ try {
132
131
  return {
133
132
  bytes: inflate(data.subarray(offset)),
134
133
  recovered: true
@@ -160,8 +159,9 @@ function paethPredictor(a, b, c) {
160
159
  const pa = Math.abs(p - a);
161
160
  const pb = Math.abs(p - b);
162
161
  const pc = Math.abs(p - c);
163
- if (pa <= pb && pa <= pc) return a;
164
- if (pb <= pc) return b;
162
+ const smallest = Math.min(pa, pb, pc);
163
+ if (smallest === pa) return a;
164
+ if (smallest === pb) return b;
165
165
  return c;
166
166
  }
167
167
  function isPngFilterType(value) {
@@ -184,7 +184,7 @@ function unfilterScanlines(data, height, bytesPerRow, bpp) {
184
184
  const rowStart = y * stride + 1;
185
185
  const outRowStart = y * bytesPerRow;
186
186
  const prevOutRowStart = y > 0 ? outRowStart - bytesPerRow : void 0;
187
- for (let x = 0; x < bytesPerRow; x++) {
187
+ for (const x of Array.from({ length: bytesPerRow }, (_, i) => i)) {
188
188
  const raw = data[rowStart + x];
189
189
  const a = x >= bpp ? out[outRowStart + x - bpp] : 0;
190
190
  const b = prevOutRowStart === void 0 ? 0 : out[prevOutRowStart + x];
@@ -196,11 +196,11 @@ function unfilterScanlines(data, height, bytesPerRow, bpp) {
196
196
  }
197
197
  function sumOfAbsSigned(bytes) {
198
198
  let sum = 0;
199
- for (const byte of bytes) sum += byte < 128 ? byte : 256 - byte;
199
+ for (const byte of bytes) sum += Math.min(byte, 256 - byte);
200
200
  return sum;
201
201
  }
202
202
  function filterRowInto(raw, rowStart, prevRowStart, bytesPerRow, bpp, filterType, out, outOffset) {
203
- for (let x = 0; x < bytesPerRow; x++) {
203
+ for (const x of Array.from({ length: bytesPerRow }, (_, i) => i)) {
204
204
  const rawByte = raw[rowStart + x];
205
205
  const a = x >= bpp ? raw[rowStart + x - bpp] : 0;
206
206
  const b = prevRowStart === void 0 ? 0 : raw[prevRowStart + x];
@@ -304,7 +304,7 @@ function detectPalette(image) {
304
304
  const g = data[base + 1] ?? 0;
305
305
  const b = data[base + 2] ?? 0;
306
306
  const a = alpha === void 0 ? 255 : alpha[i] ?? 0;
307
- const key = r + g * 256 + b * 65536 + a * 16777216;
307
+ const key = r | g << 8 | b << 16 | a << 24;
308
308
  let index = colorToIndex.get(key);
309
309
  if (index === void 0) {
310
310
  if (colorToIndex.size >= MAX_PALETTE_ENTRIES) return;
@@ -347,10 +347,10 @@ function writeTruecolorPng(writer, image, options) {
347
347
  const bytesPerRow = width * outChannels;
348
348
  const pixelCount = width * height;
349
349
  const interleaved = new Uint8Array(pixelCount * outChannels);
350
- for (let i = 0; i < pixelCount; i++) {
350
+ for (const i of Array.from({ length: pixelCount }, (_, index) => index)) {
351
351
  const srcBase = i * channels;
352
352
  const dstBase = i * outChannels;
353
- for (let c = 0; c < channels; c++) interleaved[dstBase + c] = data[srcBase + c];
353
+ for (const c of Array.from({ length: channels }, (_, index) => index)) interleaved[dstBase + c] = data[srcBase + c];
354
354
  if (alpha !== void 0) interleaved[dstBase + channels] = alpha[i];
355
355
  }
356
356
  writeIhdr(writer, width, height, colorTypeFor(image));
@@ -434,19 +434,14 @@ function filterBpp(bitDepth, channels) {
434
434
  }
435
435
  function unpackRow(rowBytes, width, channels, bitDepth) {
436
436
  const sampleCount = width * channels;
437
- const samples = [];
438
- if (bitDepth === 8) for (let i = 0; i < sampleCount; i++) samples[i] = rowBytes[i];
439
- else if (bitDepth === 16) for (let i = 0; i < sampleCount; i++) samples[i] = rowBytes[i * 2];
440
- else {
441
- const mask = (1 << bitDepth) - 1;
442
- for (let i = 0; i < sampleCount; i++) {
443
- const bitOffset = i * bitDepth;
444
- const byteIndex = bitOffset >> 3;
445
- const shift = 8 - bitDepth - (bitOffset & 7);
446
- samples[i] = rowBytes[byteIndex] >> shift & mask;
447
- }
448
- }
449
- return samples;
437
+ if (bitDepth === 16) return Array.from({ length: sampleCount }, (_, i) => rowBytes[i * 2]);
438
+ const mask = (1 << bitDepth) - 1;
439
+ return Array.from({ length: sampleCount }, (_, i) => {
440
+ const bitOffset = i * bitDepth;
441
+ const byteIndex = bitOffset >> 3;
442
+ const shift = 8 - bitDepth - (bitOffset & 7);
443
+ return rowBytes[byteIndex] >> shift & mask;
444
+ });
450
445
  }
451
446
  function readTrnsGrayValue(trns) {
452
447
  return requireDataView(trns).getUint16(0);
@@ -479,7 +474,7 @@ function decodePng(bytes, options = {}) {
479
474
  const { bytes: inflated, recovered } = inflateTolerant(concatBytes(idatChunks));
480
475
  if (recovered && options.onWarning !== void 0) options.onWarning("PNG IDAT stream required tolerant recovery (truncated or malformed)");
481
476
  const unfiltered = unfilterScanlines(inflated, ihdr.height, bytesPerRow, bpp);
482
- const palette = ihdr.colorType === 3 ? chunks.find((c) => c.type === "PLTE")?.data : void 0;
477
+ const palette = chunks.find((c) => c.type === "PLTE")?.data;
483
478
  if (ihdr.colorType === 3 && palette === void 0) throw new Error("indexed-colour PNG has no PLTE chunk");
484
479
  const trns = chunks.find((c) => c.type === "tRNS")?.data;
485
480
  return buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns);
@@ -491,10 +486,10 @@ function buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns) {
491
486
  const alpha = colorType === 4 || colorType === 6 || trns !== void 0 ? new Uint8Array(width * height).fill(255) : void 0;
492
487
  const trnsGray = colorType === 0 && trns !== void 0 ? readTrnsGrayValue(trns) : void 0;
493
488
  const trnsRgb = colorType === 2 && trns !== void 0 ? readTrnsRgbKey(trns) : void 0;
494
- for (let y = 0; y < height; y++) {
489
+ for (const y of Array.from({ length: height }, (_, i) => i)) {
495
490
  const rowStart = y * bytesPerRow;
496
491
  const samples = unpackRow(unfiltered.subarray(rowStart, rowStart + bytesPerRow), width, channels, bitDepth);
497
- for (let x = 0; x < width; x++) {
492
+ for (const x of Array.from({ length: width }, (_, i) => i)) {
498
493
  const pixelBase = x * channels;
499
494
  const outBase = (y * width + x) * outChannels;
500
495
  const alphaIndex = y * width + x;
@@ -583,7 +578,7 @@ function readJpegInfo(bytes) {
583
578
  if (requireByte(bytes, 0) !== 255 || requireByte(bytes, 1) !== SOI) throw new Error("not a valid JPEG file: missing SOI marker");
584
579
  let offset = 2;
585
580
  let adobeTransform;
586
- while (offset < bytes.length) {
581
+ while (bytes[offset] !== void 0) {
587
582
  if (bytes[offset] !== 255) {
588
583
  offset++;
589
584
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "byte-codec",
3
- "version": "1.5.2",
3
+ "version": "1.5.3",
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": {