byte-codec 1.5.0 → 1.5.2

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
@@ -261,6 +261,9 @@ const PNG_SIGNATURE$1 = new Uint8Array([
261
261
  const MAX_PALETTE_ENTRIES = 256;
262
262
  const PNG_MAX_DIMENSION = 2147483647;
263
263
  const PNG_MAX_PIXELS = 1e8;
264
+ function exceedsMaxPixelCount(pixelCount) {
265
+ return pixelCount > PNG_MAX_PIXELS;
266
+ }
264
267
  function u32be(value) {
265
268
  const bytes = /* @__PURE__ */ new Uint8Array(4);
266
269
  new DataView(bytes.buffer).setUint32(0, value);
@@ -357,7 +360,7 @@ function writeTruecolorPng(writer, image, options) {
357
360
  function encodePng(image, options = {}) {
358
361
  if (!Number.isInteger(image.width) || image.width <= 0 || image.width > 2147483647 || !Number.isInteger(image.height) || image.height <= 0 || image.height > 2147483647) throw new Error(`cannot encode a PNG with an invalid dimension (width=${image.width}, height=${image.height}); the PNG spec's IHDR section requires both width and height to be positive integers no greater than ${PNG_MAX_DIMENSION}`);
359
362
  const pixelCount = image.width * image.height;
360
- if (pixelCount > 1e8) throw new Error(`cannot encode a PNG with ${pixelCount} pixels (width=${image.width}, height=${image.height}); each dimension is individually within the PNG spec's own limit, but this encoder bounds their product to ${PNG_MAX_PIXELS} to avoid an unbounded per-pixel scan and allocation`);
363
+ if (exceedsMaxPixelCount(pixelCount)) throw new Error(`cannot encode a PNG with ${pixelCount} pixels (width=${image.width}, height=${image.height}); each dimension is individually within the PNG spec's own limit, but this encoder bounds their product to ${PNG_MAX_PIXELS} to avoid an unbounded per-pixel scan and allocation`);
361
364
  const paletteEncoding = image.channels === 3 ? detectPalette(image) : void 0;
362
365
  if (paletteEncoding === void 0) return buildPng((writer) => {
363
366
  writeTruecolorPng(writer, image, options);
@@ -432,7 +435,7 @@ function filterBpp(bitDepth, channels) {
432
435
  }
433
436
  function unpackRow(rowBytes, width, channels, bitDepth) {
434
437
  const sampleCount = width * channels;
435
- const samples = new Array(sampleCount);
438
+ const samples = [];
436
439
  if (bitDepth === 8) for (let i = 0; i < sampleCount; i++) samples[i] = rowBytes[i];
437
440
  else if (bitDepth === 16) for (let i = 0; i < sampleCount; i++) samples[i] = rowBytes[i * 2];
438
441
  else {
@@ -499,7 +502,7 @@ function buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns) {
499
502
  if (colorType === 0) {
500
503
  const g = samples[pixelBase];
501
504
  data[outBase] = scaleToByte(g, bitDepth);
502
- if (alpha !== void 0 && trnsGray !== void 0) alpha[alphaIndex] = g === trnsGray ? 0 : 255;
505
+ if (trnsGray !== void 0) alpha[alphaIndex] = g === trnsGray ? 0 : 255;
503
506
  } else if (colorType === 2) {
504
507
  const r = samples[pixelBase];
505
508
  const g = samples[pixelBase + 1];
@@ -513,7 +516,6 @@ function buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns) {
513
516
  }
514
517
  } else if (colorType === 3) {
515
518
  const index = samples[pixelBase];
516
- if (palette === void 0) throw new Error("indexed-colour PNG has no PLTE chunk");
517
519
  data[outBase] = palette[index * 3];
518
520
  data[outBase + 1] = palette[index * 3 + 1];
519
521
  data[outBase + 2] = palette[index * 3 + 2];
@@ -624,6 +626,7 @@ exports.crc32 = crc32;
624
626
  exports.decodePng = decodePng;
625
627
  exports.deflate = deflate;
626
628
  exports.encodePng = encodePng;
629
+ exports.exceedsMaxPixelCount = exceedsMaxPixelCount;
627
630
  exports.filterScanlines = filterScanlines;
628
631
  exports.inflate = inflate;
629
632
  exports.inflateTolerant = inflateTolerant;
package/dist/index.d.cts CHANGED
@@ -59,6 +59,7 @@ declare function decodePng(bytes: Uint8Array<ArrayBuffer>, options?: PngDecodeOp
59
59
  //#region src/image/png-encode.d.ts
60
60
  declare const PNG_MAX_DIMENSION = 2147483647;
61
61
  declare const PNG_MAX_PIXELS = 100000000;
62
+ declare function exceedsMaxPixelCount(pixelCount: number): boolean;
62
63
  interface PngEncodeOptions {
63
64
  readonly filter?: "none" | "adaptive";
64
65
  }
@@ -80,4 +81,4 @@ interface JpegInfo {
80
81
  }
81
82
  declare function readJpegInfo(bytes: Uint8Array<ArrayBuffer>): JpegInfo;
82
83
  //#endregion
83
- export { ByteReader, ByteWriter, DeflateLevel, InflateResult, JpegInfo, MAX_INFLATE_OUTPUT_BYTES, PNG_MAX_DIMENSION, PNG_MAX_PIXELS, PngDecodeOptions, PngEncodeOptions, PngFilterType, RawImage, concatBytes, crc32, decodePng, deflate, encodePng, filterScanlines, inflate, inflateTolerant, isAsciiWhitespace, readJpegInfo, unfilterScanlines };
84
+ export { ByteReader, ByteWriter, DeflateLevel, InflateResult, JpegInfo, MAX_INFLATE_OUTPUT_BYTES, PNG_MAX_DIMENSION, PNG_MAX_PIXELS, PngDecodeOptions, PngEncodeOptions, PngFilterType, RawImage, concatBytes, crc32, decodePng, deflate, encodePng, exceedsMaxPixelCount, filterScanlines, inflate, inflateTolerant, isAsciiWhitespace, readJpegInfo, unfilterScanlines };
package/dist/index.d.ts CHANGED
@@ -59,6 +59,7 @@ declare function decodePng(bytes: Uint8Array<ArrayBuffer>, options?: PngDecodeOp
59
59
  //#region src/image/png-encode.d.ts
60
60
  declare const PNG_MAX_DIMENSION = 2147483647;
61
61
  declare const PNG_MAX_PIXELS = 100000000;
62
+ declare function exceedsMaxPixelCount(pixelCount: number): boolean;
62
63
  interface PngEncodeOptions {
63
64
  readonly filter?: "none" | "adaptive";
64
65
  }
@@ -80,4 +81,4 @@ interface JpegInfo {
80
81
  }
81
82
  declare function readJpegInfo(bytes: Uint8Array<ArrayBuffer>): JpegInfo;
82
83
  //#endregion
83
- export { ByteReader, ByteWriter, DeflateLevel, InflateResult, JpegInfo, MAX_INFLATE_OUTPUT_BYTES, PNG_MAX_DIMENSION, PNG_MAX_PIXELS, PngDecodeOptions, PngEncodeOptions, PngFilterType, RawImage, concatBytes, crc32, decodePng, deflate, encodePng, filterScanlines, inflate, inflateTolerant, isAsciiWhitespace, readJpegInfo, unfilterScanlines };
84
+ export { ByteReader, ByteWriter, DeflateLevel, InflateResult, JpegInfo, MAX_INFLATE_OUTPUT_BYTES, PNG_MAX_DIMENSION, PNG_MAX_PIXELS, PngDecodeOptions, PngEncodeOptions, PngFilterType, RawImage, concatBytes, crc32, decodePng, deflate, encodePng, exceedsMaxPixelCount, filterScanlines, inflate, inflateTolerant, isAsciiWhitespace, readJpegInfo, unfilterScanlines };
package/dist/index.js CHANGED
@@ -260,6 +260,9 @@ const PNG_SIGNATURE$1 = new Uint8Array([
260
260
  const MAX_PALETTE_ENTRIES = 256;
261
261
  const PNG_MAX_DIMENSION = 2147483647;
262
262
  const PNG_MAX_PIXELS = 1e8;
263
+ function exceedsMaxPixelCount(pixelCount) {
264
+ return pixelCount > PNG_MAX_PIXELS;
265
+ }
263
266
  function u32be(value) {
264
267
  const bytes = /* @__PURE__ */ new Uint8Array(4);
265
268
  new DataView(bytes.buffer).setUint32(0, value);
@@ -356,7 +359,7 @@ function writeTruecolorPng(writer, image, options) {
356
359
  function encodePng(image, options = {}) {
357
360
  if (!Number.isInteger(image.width) || image.width <= 0 || image.width > 2147483647 || !Number.isInteger(image.height) || image.height <= 0 || image.height > 2147483647) throw new Error(`cannot encode a PNG with an invalid dimension (width=${image.width}, height=${image.height}); the PNG spec's IHDR section requires both width and height to be positive integers no greater than ${PNG_MAX_DIMENSION}`);
358
361
  const pixelCount = image.width * image.height;
359
- if (pixelCount > 1e8) throw new Error(`cannot encode a PNG with ${pixelCount} pixels (width=${image.width}, height=${image.height}); each dimension is individually within the PNG spec's own limit, but this encoder bounds their product to ${PNG_MAX_PIXELS} to avoid an unbounded per-pixel scan and allocation`);
362
+ if (exceedsMaxPixelCount(pixelCount)) throw new Error(`cannot encode a PNG with ${pixelCount} pixels (width=${image.width}, height=${image.height}); each dimension is individually within the PNG spec's own limit, but this encoder bounds their product to ${PNG_MAX_PIXELS} to avoid an unbounded per-pixel scan and allocation`);
360
363
  const paletteEncoding = image.channels === 3 ? detectPalette(image) : void 0;
361
364
  if (paletteEncoding === void 0) return buildPng((writer) => {
362
365
  writeTruecolorPng(writer, image, options);
@@ -431,7 +434,7 @@ function filterBpp(bitDepth, channels) {
431
434
  }
432
435
  function unpackRow(rowBytes, width, channels, bitDepth) {
433
436
  const sampleCount = width * channels;
434
- const samples = new Array(sampleCount);
437
+ const samples = [];
435
438
  if (bitDepth === 8) for (let i = 0; i < sampleCount; i++) samples[i] = rowBytes[i];
436
439
  else if (bitDepth === 16) for (let i = 0; i < sampleCount; i++) samples[i] = rowBytes[i * 2];
437
440
  else {
@@ -498,7 +501,7 @@ function buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns) {
498
501
  if (colorType === 0) {
499
502
  const g = samples[pixelBase];
500
503
  data[outBase] = scaleToByte(g, bitDepth);
501
- if (alpha !== void 0 && trnsGray !== void 0) alpha[alphaIndex] = g === trnsGray ? 0 : 255;
504
+ if (trnsGray !== void 0) alpha[alphaIndex] = g === trnsGray ? 0 : 255;
502
505
  } else if (colorType === 2) {
503
506
  const r = samples[pixelBase];
504
507
  const g = samples[pixelBase + 1];
@@ -512,7 +515,6 @@ function buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns) {
512
515
  }
513
516
  } else if (colorType === 3) {
514
517
  const index = samples[pixelBase];
515
- if (palette === void 0) throw new Error("indexed-colour PNG has no PLTE chunk");
516
518
  data[outBase] = palette[index * 3];
517
519
  data[outBase + 1] = palette[index * 3 + 1];
518
520
  data[outBase + 2] = palette[index * 3 + 2];
@@ -613,4 +615,4 @@ function readJpegInfo(bytes) {
613
615
  throw new Error("no SOF marker found in JPEG file");
614
616
  }
615
617
  //#endregion
616
- export { ByteReader, ByteWriter, MAX_INFLATE_OUTPUT_BYTES, PNG_MAX_DIMENSION, PNG_MAX_PIXELS, concatBytes, crc32, decodePng, deflate, encodePng, filterScanlines, inflate, inflateTolerant, isAsciiWhitespace, readJpegInfo, unfilterScanlines };
618
+ export { ByteReader, ByteWriter, MAX_INFLATE_OUTPUT_BYTES, PNG_MAX_DIMENSION, PNG_MAX_PIXELS, concatBytes, crc32, decodePng, deflate, encodePng, exceedsMaxPixelCount, filterScanlines, inflate, inflateTolerant, isAsciiWhitespace, readJpegInfo, unfilterScanlines };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "byte-codec",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
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": {
@@ -60,7 +60,7 @@
60
60
  "_test": "vitest run",
61
61
  "_test:coverage": "vitest run --coverage",
62
62
  "test:mutation": "turbo run _test:mutation",
63
- "_test:mutation": "stryker run stryker.config.mjs",
63
+ "_test:mutation": "stryker run stryker.config.ts",
64
64
  "test:watch": "vitest",
65
65
  "test:workers": "turbo run _test:workers",
66
66
  "_test:workers": "vitest run --config vitest.workers.config.ts",