byte-codec 1.5.1 → 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];
@@ -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);
@@ -302,7 +305,7 @@ function detectPalette(image) {
302
305
  const g = data[base + 1] ?? 0;
303
306
  const b = data[base + 2] ?? 0;
304
307
  const a = alpha === void 0 ? 255 : alpha[i] ?? 0;
305
- const key = r + g * 256 + b * 65536 + a * 16777216;
308
+ const key = r | g << 8 | b << 16 | a << 24;
306
309
  let index = colorToIndex.get(key);
307
310
  if (index === void 0) {
308
311
  if (colorToIndex.size >= MAX_PALETTE_ENTRIES) return;
@@ -345,10 +348,10 @@ function writeTruecolorPng(writer, image, options) {
345
348
  const bytesPerRow = width * outChannels;
346
349
  const pixelCount = width * height;
347
350
  const interleaved = new Uint8Array(pixelCount * outChannels);
348
- for (let i = 0; i < pixelCount; i++) {
351
+ for (const i of Array.from({ length: pixelCount }, (_, index) => index)) {
349
352
  const srcBase = i * channels;
350
353
  const dstBase = i * outChannels;
351
- 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];
352
355
  if (alpha !== void 0) interleaved[dstBase + channels] = alpha[i];
353
356
  }
354
357
  writeIhdr(writer, width, height, colorTypeFor(image));
@@ -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,19 +435,14 @@ 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);
436
- if (bitDepth === 8) for (let i = 0; i < sampleCount; i++) samples[i] = rowBytes[i];
437
- else if (bitDepth === 16) for (let i = 0; i < sampleCount; i++) samples[i] = rowBytes[i * 2];
438
- else {
439
- const mask = (1 << bitDepth) - 1;
440
- for (let i = 0; i < sampleCount; i++) {
441
- const bitOffset = i * bitDepth;
442
- const byteIndex = bitOffset >> 3;
443
- const shift = 8 - bitDepth - (bitOffset & 7);
444
- samples[i] = rowBytes[byteIndex] >> shift & mask;
445
- }
446
- }
447
- 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
+ });
448
446
  }
449
447
  function readTrnsGrayValue(trns) {
450
448
  return requireDataView(trns).getUint16(0);
@@ -477,7 +475,7 @@ function decodePng(bytes, options = {}) {
477
475
  const { bytes: inflated, recovered } = inflateTolerant(concatBytes(idatChunks));
478
476
  if (recovered && options.onWarning !== void 0) options.onWarning("PNG IDAT stream required tolerant recovery (truncated or malformed)");
479
477
  const unfiltered = unfilterScanlines(inflated, ihdr.height, bytesPerRow, bpp);
480
- const palette = ihdr.colorType === 3 ? chunks.find((c) => c.type === "PLTE")?.data : void 0;
478
+ const palette = chunks.find((c) => c.type === "PLTE")?.data;
481
479
  if (ihdr.colorType === 3 && palette === void 0) throw new Error("indexed-colour PNG has no PLTE chunk");
482
480
  const trns = chunks.find((c) => c.type === "tRNS")?.data;
483
481
  return buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns);
@@ -489,17 +487,17 @@ function buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns) {
489
487
  const alpha = colorType === 4 || colorType === 6 || trns !== void 0 ? new Uint8Array(width * height).fill(255) : void 0;
490
488
  const trnsGray = colorType === 0 && trns !== void 0 ? readTrnsGrayValue(trns) : void 0;
491
489
  const trnsRgb = colorType === 2 && trns !== void 0 ? readTrnsRgbKey(trns) : void 0;
492
- for (let y = 0; y < height; y++) {
490
+ for (const y of Array.from({ length: height }, (_, i) => i)) {
493
491
  const rowStart = y * bytesPerRow;
494
492
  const samples = unpackRow(unfiltered.subarray(rowStart, rowStart + bytesPerRow), width, channels, bitDepth);
495
- for (let x = 0; x < width; x++) {
493
+ for (const x of Array.from({ length: width }, (_, i) => i)) {
496
494
  const pixelBase = x * channels;
497
495
  const outBase = (y * width + x) * outChannels;
498
496
  const alphaIndex = y * width + x;
499
497
  if (colorType === 0) {
500
498
  const g = samples[pixelBase];
501
499
  data[outBase] = scaleToByte(g, bitDepth);
502
- if (alpha !== void 0 && trnsGray !== void 0) alpha[alphaIndex] = g === trnsGray ? 0 : 255;
500
+ if (trnsGray !== void 0) alpha[alphaIndex] = g === trnsGray ? 0 : 255;
503
501
  } else if (colorType === 2) {
504
502
  const r = samples[pixelBase];
505
503
  const g = samples[pixelBase + 1];
@@ -513,7 +511,6 @@ function buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns) {
513
511
  }
514
512
  } else if (colorType === 3) {
515
513
  const index = samples[pixelBase];
516
- if (palette === void 0) throw new Error("indexed-colour PNG has no PLTE chunk");
517
514
  data[outBase] = palette[index * 3];
518
515
  data[outBase + 1] = palette[index * 3 + 1];
519
516
  data[outBase + 2] = palette[index * 3 + 2];
@@ -582,7 +579,7 @@ function readJpegInfo(bytes) {
582
579
  if (requireByte(bytes, 0) !== 255 || requireByte(bytes, 1) !== SOI) throw new Error("not a valid JPEG file: missing SOI marker");
583
580
  let offset = 2;
584
581
  let adobeTransform;
585
- while (offset < bytes.length) {
582
+ while (bytes[offset] !== void 0) {
586
583
  if (bytes[offset] !== 255) {
587
584
  offset++;
588
585
  continue;
@@ -624,6 +621,7 @@ exports.crc32 = crc32;
624
621
  exports.decodePng = decodePng;
625
622
  exports.deflate = deflate;
626
623
  exports.encodePng = encodePng;
624
+ exports.exceedsMaxPixelCount = exceedsMaxPixelCount;
627
625
  exports.filterScanlines = filterScanlines;
628
626
  exports.inflate = inflate;
629
627
  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
@@ -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];
@@ -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);
@@ -301,7 +304,7 @@ function detectPalette(image) {
301
304
  const g = data[base + 1] ?? 0;
302
305
  const b = data[base + 2] ?? 0;
303
306
  const a = alpha === void 0 ? 255 : alpha[i] ?? 0;
304
- const key = r + g * 256 + b * 65536 + a * 16777216;
307
+ const key = r | g << 8 | b << 16 | a << 24;
305
308
  let index = colorToIndex.get(key);
306
309
  if (index === void 0) {
307
310
  if (colorToIndex.size >= MAX_PALETTE_ENTRIES) return;
@@ -344,10 +347,10 @@ function writeTruecolorPng(writer, image, options) {
344
347
  const bytesPerRow = width * outChannels;
345
348
  const pixelCount = width * height;
346
349
  const interleaved = new Uint8Array(pixelCount * outChannels);
347
- for (let i = 0; i < pixelCount; i++) {
350
+ for (const i of Array.from({ length: pixelCount }, (_, index) => index)) {
348
351
  const srcBase = i * channels;
349
352
  const dstBase = i * outChannels;
350
- 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];
351
354
  if (alpha !== void 0) interleaved[dstBase + channels] = alpha[i];
352
355
  }
353
356
  writeIhdr(writer, width, height, colorTypeFor(image));
@@ -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,19 +434,14 @@ 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);
435
- if (bitDepth === 8) for (let i = 0; i < sampleCount; i++) samples[i] = rowBytes[i];
436
- else if (bitDepth === 16) for (let i = 0; i < sampleCount; i++) samples[i] = rowBytes[i * 2];
437
- else {
438
- const mask = (1 << bitDepth) - 1;
439
- for (let i = 0; i < sampleCount; i++) {
440
- const bitOffset = i * bitDepth;
441
- const byteIndex = bitOffset >> 3;
442
- const shift = 8 - bitDepth - (bitOffset & 7);
443
- samples[i] = rowBytes[byteIndex] >> shift & mask;
444
- }
445
- }
446
- 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
+ });
447
445
  }
448
446
  function readTrnsGrayValue(trns) {
449
447
  return requireDataView(trns).getUint16(0);
@@ -476,7 +474,7 @@ function decodePng(bytes, options = {}) {
476
474
  const { bytes: inflated, recovered } = inflateTolerant(concatBytes(idatChunks));
477
475
  if (recovered && options.onWarning !== void 0) options.onWarning("PNG IDAT stream required tolerant recovery (truncated or malformed)");
478
476
  const unfiltered = unfilterScanlines(inflated, ihdr.height, bytesPerRow, bpp);
479
- const palette = ihdr.colorType === 3 ? chunks.find((c) => c.type === "PLTE")?.data : void 0;
477
+ const palette = chunks.find((c) => c.type === "PLTE")?.data;
480
478
  if (ihdr.colorType === 3 && palette === void 0) throw new Error("indexed-colour PNG has no PLTE chunk");
481
479
  const trns = chunks.find((c) => c.type === "tRNS")?.data;
482
480
  return buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns);
@@ -488,17 +486,17 @@ function buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns) {
488
486
  const alpha = colorType === 4 || colorType === 6 || trns !== void 0 ? new Uint8Array(width * height).fill(255) : void 0;
489
487
  const trnsGray = colorType === 0 && trns !== void 0 ? readTrnsGrayValue(trns) : void 0;
490
488
  const trnsRgb = colorType === 2 && trns !== void 0 ? readTrnsRgbKey(trns) : void 0;
491
- for (let y = 0; y < height; y++) {
489
+ for (const y of Array.from({ length: height }, (_, i) => i)) {
492
490
  const rowStart = y * bytesPerRow;
493
491
  const samples = unpackRow(unfiltered.subarray(rowStart, rowStart + bytesPerRow), width, channels, bitDepth);
494
- for (let x = 0; x < width; x++) {
492
+ for (const x of Array.from({ length: width }, (_, i) => i)) {
495
493
  const pixelBase = x * channels;
496
494
  const outBase = (y * width + x) * outChannels;
497
495
  const alphaIndex = y * width + x;
498
496
  if (colorType === 0) {
499
497
  const g = samples[pixelBase];
500
498
  data[outBase] = scaleToByte(g, bitDepth);
501
- if (alpha !== void 0 && trnsGray !== void 0) alpha[alphaIndex] = g === trnsGray ? 0 : 255;
499
+ if (trnsGray !== void 0) alpha[alphaIndex] = g === trnsGray ? 0 : 255;
502
500
  } else if (colorType === 2) {
503
501
  const r = samples[pixelBase];
504
502
  const g = samples[pixelBase + 1];
@@ -512,7 +510,6 @@ function buildRawImage(ihdr, channels, bytesPerRow, unfiltered, palette, trns) {
512
510
  }
513
511
  } else if (colorType === 3) {
514
512
  const index = samples[pixelBase];
515
- if (palette === void 0) throw new Error("indexed-colour PNG has no PLTE chunk");
516
513
  data[outBase] = palette[index * 3];
517
514
  data[outBase + 1] = palette[index * 3 + 1];
518
515
  data[outBase + 2] = palette[index * 3 + 2];
@@ -581,7 +578,7 @@ function readJpegInfo(bytes) {
581
578
  if (requireByte(bytes, 0) !== 255 || requireByte(bytes, 1) !== SOI) throw new Error("not a valid JPEG file: missing SOI marker");
582
579
  let offset = 2;
583
580
  let adobeTransform;
584
- while (offset < bytes.length) {
581
+ while (bytes[offset] !== void 0) {
585
582
  if (bytes[offset] !== 255) {
586
583
  offset++;
587
584
  continue;
@@ -613,4 +610,4 @@ function readJpegInfo(bytes) {
613
610
  throw new Error("no SOF marker found in JPEG file");
614
611
  }
615
612
  //#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 };
613
+ 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.1",
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": {