cross-image 0.2.3 → 0.4.0

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.
Files changed (105) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +292 -74
  3. package/esm/mod.d.ts +6 -4
  4. package/esm/mod.js +4 -2
  5. package/esm/src/formats/apng.d.ts +17 -5
  6. package/esm/src/formats/apng.js +104 -9
  7. package/esm/src/formats/ascii.d.ts +13 -3
  8. package/esm/src/formats/ascii.js +25 -1
  9. package/esm/src/formats/avif.d.ts +96 -0
  10. package/esm/src/formats/avif.js +607 -0
  11. package/esm/src/formats/bmp.d.ts +13 -3
  12. package/esm/src/formats/bmp.js +75 -2
  13. package/esm/src/formats/dng.d.ts +14 -2
  14. package/esm/src/formats/dng.js +27 -5
  15. package/esm/src/formats/gif.d.ts +18 -5
  16. package/esm/src/formats/gif.js +160 -14
  17. package/esm/src/formats/heic.d.ts +96 -0
  18. package/esm/src/formats/heic.js +608 -0
  19. package/esm/src/formats/ico.d.ts +13 -3
  20. package/esm/src/formats/ico.js +32 -4
  21. package/esm/src/formats/jpeg.d.ts +10 -3
  22. package/esm/src/formats/jpeg.js +99 -11
  23. package/esm/src/formats/pam.d.ts +13 -3
  24. package/esm/src/formats/pam.js +68 -2
  25. package/esm/src/formats/pcx.d.ts +13 -3
  26. package/esm/src/formats/pcx.js +47 -2
  27. package/esm/src/formats/png.d.ts +15 -3
  28. package/esm/src/formats/png.js +89 -2
  29. package/esm/src/formats/png_base.js +2 -5
  30. package/esm/src/formats/ppm.d.ts +13 -3
  31. package/esm/src/formats/ppm.js +36 -2
  32. package/esm/src/formats/tiff.d.ts +14 -18
  33. package/esm/src/formats/tiff.js +219 -20
  34. package/esm/src/formats/webp.d.ts +10 -3
  35. package/esm/src/formats/webp.js +103 -8
  36. package/esm/src/image.d.ts +20 -3
  37. package/esm/src/image.js +65 -21
  38. package/esm/src/types.d.ts +74 -4
  39. package/esm/src/utils/gif_decoder.d.ts +4 -1
  40. package/esm/src/utils/gif_decoder.js +91 -65
  41. package/esm/src/utils/image_processing.js +144 -70
  42. package/esm/src/utils/jpeg_decoder.d.ts +17 -4
  43. package/esm/src/utils/jpeg_decoder.js +448 -83
  44. package/esm/src/utils/jpeg_encoder.d.ts +15 -1
  45. package/esm/src/utils/jpeg_encoder.js +263 -24
  46. package/esm/src/utils/resize.js +51 -20
  47. package/esm/src/utils/tiff_deflate.d.ts +18 -0
  48. package/esm/src/utils/tiff_deflate.js +27 -0
  49. package/esm/src/utils/tiff_packbits.d.ts +24 -0
  50. package/esm/src/utils/tiff_packbits.js +90 -0
  51. package/esm/src/utils/webp_decoder.d.ts +3 -1
  52. package/esm/src/utils/webp_decoder.js +144 -63
  53. package/esm/src/utils/webp_encoder.js +5 -11
  54. package/package.json +18 -1
  55. package/script/mod.d.ts +6 -4
  56. package/script/mod.js +7 -3
  57. package/script/src/formats/apng.d.ts +17 -5
  58. package/script/src/formats/apng.js +104 -9
  59. package/script/src/formats/ascii.d.ts +13 -3
  60. package/script/src/formats/ascii.js +25 -1
  61. package/script/src/formats/avif.d.ts +96 -0
  62. package/script/src/formats/avif.js +611 -0
  63. package/script/src/formats/bmp.d.ts +13 -3
  64. package/script/src/formats/bmp.js +75 -2
  65. package/script/src/formats/dng.d.ts +14 -2
  66. package/script/src/formats/dng.js +27 -5
  67. package/script/src/formats/gif.d.ts +18 -5
  68. package/script/src/formats/gif.js +160 -14
  69. package/script/src/formats/heic.d.ts +96 -0
  70. package/script/src/formats/heic.js +612 -0
  71. package/script/src/formats/ico.d.ts +13 -3
  72. package/script/src/formats/ico.js +32 -4
  73. package/script/src/formats/jpeg.d.ts +10 -3
  74. package/script/src/formats/jpeg.js +99 -11
  75. package/script/src/formats/pam.d.ts +13 -3
  76. package/script/src/formats/pam.js +68 -2
  77. package/script/src/formats/pcx.d.ts +13 -3
  78. package/script/src/formats/pcx.js +47 -2
  79. package/script/src/formats/png.d.ts +15 -3
  80. package/script/src/formats/png.js +89 -2
  81. package/script/src/formats/png_base.js +2 -5
  82. package/script/src/formats/ppm.d.ts +13 -3
  83. package/script/src/formats/ppm.js +36 -2
  84. package/script/src/formats/tiff.d.ts +14 -18
  85. package/script/src/formats/tiff.js +219 -20
  86. package/script/src/formats/webp.d.ts +10 -3
  87. package/script/src/formats/webp.js +103 -8
  88. package/script/src/image.d.ts +20 -3
  89. package/script/src/image.js +64 -20
  90. package/script/src/types.d.ts +74 -4
  91. package/script/src/utils/gif_decoder.d.ts +4 -1
  92. package/script/src/utils/gif_decoder.js +91 -65
  93. package/script/src/utils/image_processing.js +144 -70
  94. package/script/src/utils/jpeg_decoder.d.ts +17 -4
  95. package/script/src/utils/jpeg_decoder.js +448 -83
  96. package/script/src/utils/jpeg_encoder.d.ts +15 -1
  97. package/script/src/utils/jpeg_encoder.js +263 -24
  98. package/script/src/utils/resize.js +51 -20
  99. package/script/src/utils/tiff_deflate.d.ts +18 -0
  100. package/script/src/utils/tiff_deflate.js +31 -0
  101. package/script/src/utils/tiff_packbits.d.ts +24 -0
  102. package/script/src/utils/tiff_packbits.js +94 -0
  103. package/script/src/utils/webp_decoder.d.ts +3 -1
  104. package/script/src/utils/webp_decoder.js +144 -63
  105. package/script/src/utils/webp_encoder.js +5 -11
@@ -19,9 +19,11 @@
19
19
  * @see https://developers.google.com/speed/webp/docs/riff_container
20
20
  * @see https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification
21
21
  */
22
+ import type { ImageDecoderOptions } from "../types.js";
22
23
  export declare class WebPDecoder {
23
24
  private data;
24
- constructor(data: Uint8Array);
25
+ private options;
26
+ constructor(data: Uint8Array, settings?: ImageDecoderOptions);
25
27
  decode(): {
26
28
  width: number;
27
29
  height: number;
@@ -93,7 +93,6 @@ class HuffmanTable {
93
93
  const bit = reader.readBits(1);
94
94
  node = bit === 0 ? node.left : node.right;
95
95
  if (!node) {
96
- // console.log("Invalid Huffman code - walked off tree");
97
96
  throw new Error("Invalid Huffman code");
98
97
  }
99
98
  }
@@ -164,14 +163,24 @@ class BitReader {
164
163
  }
165
164
  }
166
165
  export class WebPDecoder {
167
- constructor(data) {
166
+ constructor(data, settings = {}) {
168
167
  Object.defineProperty(this, "data", {
169
168
  enumerable: true,
170
169
  configurable: true,
171
170
  writable: true,
172
171
  value: void 0
173
172
  });
173
+ Object.defineProperty(this, "options", {
174
+ enumerable: true,
175
+ configurable: true,
176
+ writable: true,
177
+ value: void 0
178
+ });
174
179
  this.data = data;
180
+ this.options = {
181
+ tolerantDecoding: settings.tolerantDecoding ?? true,
182
+ onWarning: settings.onWarning,
183
+ };
175
184
  }
176
185
  decode() {
177
186
  // Verify WebP signature
@@ -278,66 +287,142 @@ export class WebPDecoder {
278
287
  const numPixels = width * height;
279
288
  // Color cache for repeated colors
280
289
  const colorCache = new Uint32Array(colorCacheSize);
281
- for (let i = 0; i < numPixels;) {
282
- // Read green channel (which determines the code type)
283
- const green = huffmanTables.green.readSymbol(reader);
284
- if (green < 256) {
285
- // Literal pixel
286
- const red = huffmanTables.red.readSymbol(reader);
287
- const blue = huffmanTables.blue.readSymbol(reader);
288
- const alpha = alphaUsed !== 0
289
- ? huffmanTables.alpha.readSymbol(reader)
290
- : 255;
291
- pixelData[pixelIndex++] = red;
292
- pixelData[pixelIndex++] = green;
293
- pixelData[pixelIndex++] = blue;
294
- pixelData[pixelIndex++] = alpha;
295
- // Add to color cache if enabled
296
- if (useColorCache) {
297
- const color = (alpha << 24) | (blue << 16) | (green << 8) | red;
298
- colorCache[i % colorCacheSize] = color;
290
+ if (this.options.tolerantDecoding) {
291
+ // Tolerant mode: continue decoding even if errors occur
292
+ try {
293
+ for (let i = 0; i < numPixels;) {
294
+ // Read green channel (which determines the code type)
295
+ const green = huffmanTables.green.readSymbol(reader);
296
+ if (green < 256) {
297
+ // Literal pixel
298
+ const red = huffmanTables.red.readSymbol(reader);
299
+ const blue = huffmanTables.blue.readSymbol(reader);
300
+ const alpha = alphaUsed !== 0 ? huffmanTables.alpha.readSymbol(reader) : 255;
301
+ pixelData[pixelIndex++] = red;
302
+ pixelData[pixelIndex++] = green;
303
+ pixelData[pixelIndex++] = blue;
304
+ pixelData[pixelIndex++] = alpha;
305
+ // Add to color cache if enabled
306
+ if (useColorCache) {
307
+ const color = (alpha << 24) | (blue << 16) | (green << 8) | red;
308
+ colorCache[i % colorCacheSize] = color;
309
+ }
310
+ i++;
311
+ }
312
+ else if (green < 256 + 24) {
313
+ // Backward reference (LZ77)
314
+ const lengthSymbol = green - 256;
315
+ const length = this.getLength(lengthSymbol, reader);
316
+ const distancePrefix = huffmanTables.distance.readSymbol(reader);
317
+ const distance = this.getDistance(distancePrefix, reader);
318
+ // Copy pixels from earlier in the stream
319
+ const srcIndex = pixelIndex - distance * 4;
320
+ if (srcIndex < 0) {
321
+ throw new Error("Invalid backward reference");
322
+ }
323
+ for (let j = 0; j < length; j++) {
324
+ pixelData[pixelIndex++] = pixelData[srcIndex + j * 4];
325
+ pixelData[pixelIndex++] = pixelData[srcIndex + j * 4 + 1];
326
+ pixelData[pixelIndex++] = pixelData[srcIndex + j * 4 + 2];
327
+ pixelData[pixelIndex++] = pixelData[srcIndex + j * 4 + 3];
328
+ // Add to color cache
329
+ if (useColorCache) {
330
+ const color = (pixelData[pixelIndex - 1] << 24) |
331
+ (pixelData[pixelIndex - 2] << 16) |
332
+ (pixelData[pixelIndex - 3] << 8) |
333
+ pixelData[pixelIndex - 4];
334
+ colorCache[(i + j) % colorCacheSize] = color;
335
+ }
336
+ }
337
+ i += length;
338
+ }
339
+ else {
340
+ // Color cache reference
341
+ const cacheIndex = green - 256 - 24;
342
+ if (cacheIndex >= colorCacheSize) {
343
+ throw new Error("Invalid color cache index");
344
+ }
345
+ const color = colorCache[cacheIndex];
346
+ pixelData[pixelIndex++] = color & 0xff; // R
347
+ pixelData[pixelIndex++] = (color >> 8) & 0xff; // G
348
+ pixelData[pixelIndex++] = (color >> 16) & 0xff; // B
349
+ pixelData[pixelIndex++] = (color >> 24) & 0xff; // A
350
+ i++;
351
+ }
299
352
  }
300
- i++;
301
353
  }
302
- else if (green < 256 + 24) {
303
- // Backward reference (LZ77)
304
- const lengthSymbol = green - 256;
305
- const length = this.getLength(lengthSymbol, reader);
306
- const distancePrefix = huffmanTables.distance.readSymbol(reader);
307
- const distance = this.getDistance(distancePrefix, reader);
308
- // Copy pixels from earlier in the stream
309
- const srcIndex = pixelIndex - distance * 4;
310
- if (srcIndex < 0) {
311
- throw new Error("Invalid backward reference");
354
+ catch (e) {
355
+ // Tolerant decoding: fill remaining pixels with gray (128, 128, 128, 255)
356
+ this.options.onWarning?.(`WebP VP8L: Partial decode at pixel ${pixelIndex / 4}/${numPixels}`, e);
357
+ while (pixelIndex < pixelData.length) {
358
+ pixelData[pixelIndex++] = 128; // R
359
+ pixelData[pixelIndex++] = 128; // G
360
+ pixelData[pixelIndex++] = 128; // B
361
+ pixelData[pixelIndex++] = 255; // A
312
362
  }
313
- for (let j = 0; j < length; j++) {
314
- pixelData[pixelIndex++] = pixelData[srcIndex + j * 4];
315
- pixelData[pixelIndex++] = pixelData[srcIndex + j * 4 + 1];
316
- pixelData[pixelIndex++] = pixelData[srcIndex + j * 4 + 2];
317
- pixelData[pixelIndex++] = pixelData[srcIndex + j * 4 + 3];
318
- // Add to color cache
363
+ }
364
+ }
365
+ else {
366
+ // Non-tolerant mode: throw on first error
367
+ for (let i = 0; i < numPixels;) {
368
+ // Read green channel (which determines the code type)
369
+ const green = huffmanTables.green.readSymbol(reader);
370
+ if (green < 256) {
371
+ // Literal pixel
372
+ const red = huffmanTables.red.readSymbol(reader);
373
+ const blue = huffmanTables.blue.readSymbol(reader);
374
+ const alpha = alphaUsed !== 0 ? huffmanTables.alpha.readSymbol(reader) : 255;
375
+ pixelData[pixelIndex++] = red;
376
+ pixelData[pixelIndex++] = green;
377
+ pixelData[pixelIndex++] = blue;
378
+ pixelData[pixelIndex++] = alpha;
379
+ // Add to color cache if enabled
319
380
  if (useColorCache) {
320
- const color = (pixelData[pixelIndex - 1] << 24) |
321
- (pixelData[pixelIndex - 2] << 16) |
322
- (pixelData[pixelIndex - 3] << 8) |
323
- pixelData[pixelIndex - 4];
324
- colorCache[(i + j) % colorCacheSize] = color;
381
+ const color = (alpha << 24) | (blue << 16) | (green << 8) | red;
382
+ colorCache[i % colorCacheSize] = color;
325
383
  }
384
+ i++;
326
385
  }
327
- i += length;
328
- }
329
- else {
330
- // Color cache reference
331
- const cacheIndex = green - 256 - 24;
332
- if (cacheIndex >= colorCacheSize) {
333
- throw new Error("Invalid color cache index");
386
+ else if (green < 256 + 24) {
387
+ // Backward reference (LZ77)
388
+ const lengthSymbol = green - 256;
389
+ const length = this.getLength(lengthSymbol, reader);
390
+ const distancePrefix = huffmanTables.distance.readSymbol(reader);
391
+ const distance = this.getDistance(distancePrefix, reader);
392
+ // Copy pixels from earlier in the stream
393
+ const srcIndex = pixelIndex - distance * 4;
394
+ if (srcIndex < 0) {
395
+ throw new Error("Invalid backward reference");
396
+ }
397
+ for (let j = 0; j < length; j++) {
398
+ pixelData[pixelIndex++] = pixelData[srcIndex + j * 4];
399
+ pixelData[pixelIndex++] = pixelData[srcIndex + j * 4 + 1];
400
+ pixelData[pixelIndex++] = pixelData[srcIndex + j * 4 + 2];
401
+ pixelData[pixelIndex++] = pixelData[srcIndex + j * 4 + 3];
402
+ // Add to color cache
403
+ if (useColorCache) {
404
+ const color = (pixelData[pixelIndex - 1] << 24) |
405
+ (pixelData[pixelIndex - 2] << 16) |
406
+ (pixelData[pixelIndex - 3] << 8) |
407
+ pixelData[pixelIndex - 4];
408
+ colorCache[(i + j) % colorCacheSize] = color;
409
+ }
410
+ }
411
+ i += length;
412
+ }
413
+ else {
414
+ // Color cache reference
415
+ const cacheIndex = green - 256 - 24;
416
+ if (cacheIndex >= colorCacheSize) {
417
+ throw new Error("Invalid color cache index");
418
+ }
419
+ const color = colorCache[cacheIndex];
420
+ pixelData[pixelIndex++] = color & 0xff; // R
421
+ pixelData[pixelIndex++] = (color >> 8) & 0xff; // G
422
+ pixelData[pixelIndex++] = (color >> 16) & 0xff; // B
423
+ pixelData[pixelIndex++] = (color >> 24) & 0xff; // A
424
+ i++;
334
425
  }
335
- const color = colorCache[cacheIndex];
336
- pixelData[pixelIndex++] = color & 0xff; // R
337
- pixelData[pixelIndex++] = (color >> 8) & 0xff; // G
338
- pixelData[pixelIndex++] = (color >> 16) & 0xff; // B
339
- pixelData[pixelIndex++] = (color >> 24) & 0xff; // A
340
- i++;
341
426
  }
342
427
  }
343
428
  return pixelData;
@@ -378,9 +463,7 @@ export class WebPDecoder {
378
463
  const isFirstEightBits = reader.readBits(1);
379
464
  const symbols = [];
380
465
  for (let i = 0; i < numSymbols; i++) {
381
- const symbolBits = isFirstEightBits
382
- ? reader.readBits(8)
383
- : reader.readBits(1);
466
+ const symbolBits = isFirstEightBits ? reader.readBits(8) : reader.readBits(1);
384
467
  symbols.push(symbolBits);
385
468
  }
386
469
  // Build simple Huffman table
@@ -396,9 +479,7 @@ export class WebPDecoder {
396
479
  }
397
480
  else {
398
481
  // Complex code - read code lengths
399
- const maxSymbol = isGreen
400
- ? (256 + 24 + (useColorCache ? (1 << colorCacheBits) : 0))
401
- : 256;
482
+ const maxSymbol = isGreen ? (256 + 24 + (useColorCache ? (1 << colorCacheBits) : 0)) : 256;
402
483
  const codeLengths = this.readCodeLengths(reader, maxSymbol);
403
484
  this.buildHuffmanTable(table, codeLengths);
404
485
  }
@@ -406,7 +487,7 @@ export class WebPDecoder {
406
487
  readCodeLengths(reader, maxSymbol) {
407
488
  // Read code length codes (used to encode the actual code lengths)
408
489
  const numCodeLengthCodes = reader.readBits(4) + 4;
409
- const codeLengthCodeLengths = new Array(19).fill(0);
490
+ const codeLengthCodeLengths = new Uint8Array(19);
410
491
  // Code length code order
411
492
  const codeLengthCodeOrder = [
412
493
  17,
@@ -442,7 +523,7 @@ export class WebPDecoder {
442
523
  const codeLengthTable = new HuffmanTable();
443
524
  this.buildHuffmanTable(codeLengthTable, codeLengthCodeLengths);
444
525
  // Read actual code lengths
445
- const codeLengths = new Array(maxSymbol).fill(0);
526
+ const codeLengths = new Uint8Array(maxSymbol);
446
527
  let i = 0;
447
528
  while (i < maxSymbol) {
448
529
  const code = codeLengthTable.readSymbol(reader);
@@ -369,7 +369,7 @@ export class WebPEncoder {
369
369
  * Returns an array where index is the symbol and value is the code length
370
370
  */
371
371
  calculateCodeLengths(frequencies, maxSymbol, maxCodeLength = 15) {
372
- const codeLengths = new Array(maxSymbol).fill(0);
372
+ const codeLengths = new Uint8Array(maxSymbol);
373
373
  // Get symbols with non-zero frequencies
374
374
  const symbols = Array.from(frequencies.keys()).sort((a, b) => a - b);
375
375
  if (symbols.length === 0)
@@ -377,7 +377,6 @@ export class WebPEncoder {
377
377
  // For a single symbol, use code length 1
378
378
  // (Canonical Huffman codes require length >= 1)
379
379
  if (symbols.length === 1) {
380
- // console.log(`Single symbol ${symbols[0]}, forcing length 1`);
381
380
  codeLengths[symbols[0]] = 1;
382
381
  return codeLengths;
383
382
  }
@@ -424,7 +423,6 @@ export class WebPEncoder {
424
423
  // If tree is too deep, flatten frequencies and rebuild
425
424
  let attempts = 0;
426
425
  while (maxDepth > maxCodeLength && attempts < 5) {
427
- // console.log(`Tree too deep (${maxDepth} > ${maxCodeLength}), flattening...`);
428
426
  attempts++;
429
427
  // Add bias to frequencies to flatten the tree
430
428
  // Increase bias with each attempt
@@ -439,11 +437,8 @@ export class WebPEncoder {
439
437
  maxDepth = 0;
440
438
  checkDepth(root, 0);
441
439
  }
442
- if (maxDepth > maxCodeLength) {
443
- console.warn(`Failed to reduce Huffman tree depth to ${maxCodeLength} (current: ${maxDepth})`);
444
- // Force hard limit by sorting and assigning lengths?
445
- // For now, let's just see if this is happening.
446
- }
440
+ // If tree depth couldn't be reduced, encoding may fail but we'll try anyway
441
+ // This is an internal limitation that doesn't affect most images
447
442
  // Calculate code lengths by traversing tree (iterative to avoid deep recursion)
448
443
  const stack = [{
449
444
  node: root,
@@ -485,7 +480,7 @@ export class WebPEncoder {
485
480
  }
486
481
  }
487
482
  // Count symbols at each length
488
- const lengthCounts = new Array(maxLength + 1).fill(0);
483
+ const lengthCounts = new Uint32Array(maxLength + 1);
489
484
  for (let i = 0; i < codeLengths.length; i++) {
490
485
  if (codeLengths[i] > 0) {
491
486
  lengthCounts[codeLengths[i]]++;
@@ -493,7 +488,7 @@ export class WebPEncoder {
493
488
  }
494
489
  // Generate first code for each length
495
490
  let code = 0;
496
- const nextCode = new Array(maxLength + 1).fill(0);
491
+ const nextCode = new Uint32Array(maxLength + 1);
497
492
  for (let len = 1; len <= maxLength; len++) {
498
493
  code = (code + lengthCounts[len - 1]) << 1;
499
494
  nextCode[len] = code;
@@ -625,7 +620,6 @@ export class WebPEncoder {
625
620
  }
626
621
  numCodeLengthCodes = Math.max(4, numCodeLengthCodes);
627
622
  // Write number of code length codes
628
- // console.log(`Complex Huffman: numCodeLengthCodes=${numCodeLengthCodes}, rleEncoded.length=${rleEncoded.length}`);
629
623
  writer.writeBits(numCodeLengthCodes - 4, 4);
630
624
  // Write code length code lengths
631
625
  for (let i = 0; i < numCodeLengthCodes; i++) {
package/package.json CHANGED
@@ -1,20 +1,34 @@
1
1
  {
2
2
  "name": "cross-image",
3
- "version": "0.2.3",
3
+ "version": "0.4.0",
4
4
  "description": "A pure JavaScript, dependency-free, cross-runtime image processing library for Deno, Node.js, and Bun.",
5
5
  "keywords": [
6
6
  "image",
7
7
  "image-processing",
8
+ "image-manipulation",
9
+ "image-resize",
10
+ "image-decode",
11
+ "image-encode",
8
12
  "png",
13
+ "apng",
9
14
  "jpeg",
10
15
  "webp",
11
16
  "gif",
12
17
  "tiff",
13
18
  "bmp",
19
+ "ico",
14
20
  "dng",
21
+ "heic",
22
+ "avif",
15
23
  "pam",
24
+ "ppm",
16
25
  "pcx",
26
+ "ascii-art",
27
+ "metadata",
28
+ "exif",
17
29
  "cross-runtime",
30
+ "pure-javascript",
31
+ "no-dependencies",
18
32
  "deno",
19
33
  "node",
20
34
  "bun"
@@ -37,5 +51,8 @@
37
51
  }
38
52
  },
39
53
  "scripts": {},
54
+ "engines": {
55
+ "node": ">=18.0.0"
56
+ },
40
57
  "_generatedBy": "dnt@dev"
41
58
  }
package/script/mod.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * @example
9
9
  * ```ts
10
- * import { Image } from "@cross/image";
10
+ * import { Image } from "jsr:@cross/image";
11
11
  *
12
12
  * // Decode an image
13
13
  * const data = await Deno.readFile("input.png");
@@ -26,7 +26,7 @@
26
26
  *
27
27
  * @example
28
28
  * ```ts
29
- * import { Image } from "@cross/image";
29
+ * import { Image } from "jsr:@cross/image";
30
30
  *
31
31
  * // Create a blank canvas
32
32
  * const canvas = Image.create(400, 300, 255, 255, 255);
@@ -43,13 +43,13 @@
43
43
  * ```
44
44
  */
45
45
  export { Image } from "./src/image.js";
46
- export type { ASCIIOptions, FrameMetadata, ImageData, ImageFormat, ImageFrame, ImageMetadata, MultiFrameImageData, ResizeOptions, WebPEncodeOptions, } from "./src/types.js";
46
+ export type { ASCIIEncoderOptions, FrameMetadata, ImageData, ImageDecoderOptions, ImageFormat, ImageFrame, ImageMetadata, JPEGEncoderOptions, MultiFrameImageData, ResizeOptions, TIFFEncoderOptions, WebPEncoderOptions, } from "./src/types.js";
47
47
  export { PNGFormat } from "./src/formats/png.js";
48
48
  export { APNGFormat } from "./src/formats/apng.js";
49
49
  export { JPEGFormat } from "./src/formats/jpeg.js";
50
50
  export { WebPFormat } from "./src/formats/webp.js";
51
51
  export { GIFFormat } from "./src/formats/gif.js";
52
- export { type TIFFEncodeOptions, TIFFFormat } from "./src/formats/tiff.js";
52
+ export { TIFFFormat } from "./src/formats/tiff.js";
53
53
  export { BMPFormat } from "./src/formats/bmp.js";
54
54
  export { ICOFormat } from "./src/formats/ico.js";
55
55
  export { DNGFormat } from "./src/formats/dng.js";
@@ -57,4 +57,6 @@ export { PAMFormat } from "./src/formats/pam.js";
57
57
  export { PCXFormat } from "./src/formats/pcx.js";
58
58
  export { PPMFormat } from "./src/formats/ppm.js";
59
59
  export { ASCIIFormat } from "./src/formats/ascii.js";
60
+ export { HEICFormat } from "./src/formats/heic.js";
61
+ export { AVIFFormat } from "./src/formats/avif.js";
60
62
  //# sourceMappingURL=mod.d.ts.map
package/script/mod.js CHANGED
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * @example
10
10
  * ```ts
11
- * import { Image } from "@cross/image";
11
+ * import { Image } from "jsr:@cross/image";
12
12
  *
13
13
  * // Decode an image
14
14
  * const data = await Deno.readFile("input.png");
@@ -27,7 +27,7 @@
27
27
  *
28
28
  * @example
29
29
  * ```ts
30
- * import { Image } from "@cross/image";
30
+ * import { Image } from "jsr:@cross/image";
31
31
  *
32
32
  * // Create a blank canvas
33
33
  * const canvas = Image.create(400, 300, 255, 255, 255);
@@ -44,7 +44,7 @@
44
44
  * ```
45
45
  */
46
46
  Object.defineProperty(exports, "__esModule", { value: true });
47
- exports.ASCIIFormat = exports.PPMFormat = exports.PCXFormat = exports.PAMFormat = exports.DNGFormat = exports.ICOFormat = exports.BMPFormat = exports.TIFFFormat = exports.GIFFormat = exports.WebPFormat = exports.JPEGFormat = exports.APNGFormat = exports.PNGFormat = exports.Image = void 0;
47
+ exports.AVIFFormat = exports.HEICFormat = exports.ASCIIFormat = exports.PPMFormat = exports.PCXFormat = exports.PAMFormat = exports.DNGFormat = exports.ICOFormat = exports.BMPFormat = exports.TIFFFormat = exports.GIFFormat = exports.WebPFormat = exports.JPEGFormat = exports.APNGFormat = exports.PNGFormat = exports.Image = void 0;
48
48
  var image_js_1 = require("./src/image.js");
49
49
  Object.defineProperty(exports, "Image", { enumerable: true, get: function () { return image_js_1.Image; } });
50
50
  var png_js_1 = require("./src/formats/png.js");
@@ -73,3 +73,7 @@ var ppm_js_1 = require("./src/formats/ppm.js");
73
73
  Object.defineProperty(exports, "PPMFormat", { enumerable: true, get: function () { return ppm_js_1.PPMFormat; } });
74
74
  var ascii_js_1 = require("./src/formats/ascii.js");
75
75
  Object.defineProperty(exports, "ASCIIFormat", { enumerable: true, get: function () { return ascii_js_1.ASCIIFormat; } });
76
+ var heic_js_1 = require("./src/formats/heic.js");
77
+ Object.defineProperty(exports, "HEICFormat", { enumerable: true, get: function () { return heic_js_1.HEICFormat; } });
78
+ var avif_js_1 = require("./src/formats/avif.js");
79
+ Object.defineProperty(exports, "AVIFFormat", { enumerable: true, get: function () { return avif_js_1.AVIFFormat; } });
@@ -1,4 +1,4 @@
1
- import type { ImageData, ImageFormat, MultiFrameImageData } from "../types.js";
1
+ import type { ImageData, ImageDecoderOptions, ImageFormat, ImageMetadata, MultiFrameImageData } from "../types.js";
2
2
  import { PNGBase } from "./png_base.js";
3
3
  /**
4
4
  * APNG (Animated PNG) format handler
@@ -26,25 +26,37 @@ export declare class APNGFormat extends PNGBase implements ImageFormat {
26
26
  * @param data Raw APNG image data
27
27
  * @returns Decoded image data with RGBA pixels of first frame
28
28
  */
29
- decode(data: Uint8Array): Promise<ImageData>;
29
+ decode(data: Uint8Array, settings?: ImageDecoderOptions): Promise<ImageData>;
30
30
  /**
31
31
  * Decode all frames from APNG image
32
32
  * @param data Raw APNG image data
33
33
  * @returns Decoded multi-frame image data
34
34
  */
35
- decodeFrames(data: Uint8Array): Promise<MultiFrameImageData>;
35
+ decodeFrames(data: Uint8Array, _settings?: ImageDecoderOptions): Promise<MultiFrameImageData>;
36
36
  /**
37
37
  * Encode RGBA image data to APNG format (single frame)
38
38
  * @param imageData Image data to encode
39
39
  * @returns Encoded APNG image bytes
40
40
  */
41
- encode(imageData: ImageData): Promise<Uint8Array>;
41
+ encode(imageData: ImageData, _options?: unknown): Promise<Uint8Array>;
42
42
  /**
43
43
  * Encode multi-frame image data to APNG format
44
44
  * @param imageData Multi-frame image data to encode
45
45
  * @returns Encoded APNG image bytes
46
46
  */
47
- encodeFrames(imageData: MultiFrameImageData): Promise<Uint8Array>;
47
+ encodeFrames(imageData: MultiFrameImageData, _options?: unknown): Promise<Uint8Array>;
48
48
  private decodeFrameData;
49
+ /**
50
+ * Get the list of metadata fields supported by APNG format
51
+ * Includes all PNG fields plus frame count
52
+ */
53
+ getSupportedMetadata(): Array<keyof ImageMetadata>;
54
+ /**
55
+ * Extract metadata from APNG data without fully decoding the pixel data
56
+ * This quickly parses PNG chunks to extract metadata including frame count
57
+ * @param data Raw APNG data
58
+ * @returns Extracted metadata or undefined
59
+ */
60
+ extractMetadata(data: Uint8Array): Promise<ImageMetadata | undefined>;
49
61
  }
50
62
  //# sourceMappingURL=apng.d.ts.map