From 20b40d89f377b436ef201b7c0178ddad52e59851 Mon Sep 17 00:00:00 2001 From: Yegor Pelykh Date: Sat, 11 Feb 2023 10:03:08 +0200 Subject: [PATCH] Many fundamental changes in the project - reworked and added new Draw functions, Filters and Transforms - reworked MemoryImage - reworked Colors, Pixels and Palettes - reworked working with EXIF data - introduced pixel iterators --- .eslintrc.json | 3 +- .gitignore | 3 +- .vscode/settings.json | 4 +- README.md | 956 +- lib-compact/index.d.ts | 10988 +++++++++----- lib-compact/index.js | 14 +- lib-compact/index.js.map | 8 +- package-lock.json | 12306 +++++----------- package.json | 49 +- src/color/channel-order.ts | 26 + src/color/channel.ts | 27 + src/color/color-float16.ts | 238 + src/color/color-float32.ts | 221 + src/color/color-float64.ts | 221 + src/color/color-int16.ts | 230 + src/color/color-int32.ts | 230 + src/color/color-int8.ts | 230 + src/color/color-rgb8.ts | 19 + src/color/color-rgba8.ts | 20 + src/color/color-uint1.ts | 221 + src/color/color-uint16.ts | 221 + src/color/color-uint2.ts | 226 + src/color/color-uint32.ts | 221 + src/color/color-uint4.ts | 233 + src/color/color-uint8.ts | 221 + src/color/color-utils.ts | 595 + src/color/color.ts | 145 + src/color/format.ts | 343 + src/common/array-utils.ts | 91 +- src/common/bit-operators.ts | 131 - src/common/bit-utils.ts | 191 + src/common/color-channel.ts | 28 - src/common/color-model.ts | 11 - src/common/color.ts | 702 - src/common/crc32.ts | 16 +- src/common/dispose-mode.ts | 18 - src/common/dither-kernel.ts | 9 - src/common/dither-pixel.ts | 135 - src/{hdr/half.ts => common/float16.ts} | 229 +- src/common/frame-animation.ts | 165 - src/common/frame-type.ts | 13 - src/common/input-buffer.ts | 65 +- src/common/interpolation.ts | 18 + src/common/line.ts | 84 +- src/common/math-operators.ts | 38 - src/common/math-utils.ts | 64 + src/common/memory-image.ts | 1027 -- src/common/neural-quantizer.ts | 610 - src/common/output-buffer.ts | 49 +- src/common/point.ts | 16 +- src/common/quantizer.ts | 8 - src/common/random-utils.ts | 11 +- src/common/rational.ts | 14 +- src/common/rectangle.ts | 46 +- src/common/rgb-channel-set.ts | 6 - src/common/{text-codec.ts => string-utils.ts} | 8 +- src/draw/blend-mode.ts | 19 + src/draw/circle-quadrant.ts | 9 + src/draw/draw-image-options.ts | 17 - src/draw/draw-line-options.ts | 12 - src/draw/draw.ts | 2303 ++- src/draw/fill-flood-options.ts | 12 - src/draw/mask-flood-options.ts | 12 - src/error/image-error.ts | 10 - src/error/lib-error.ts | 10 + src/error/not-implemented-error.ts | 12 - src/exif/exif-data.ts | 159 +- src/exif/exif-entry.ts | 10 +- src/exif/exif-ifd.ts | 510 - src/exif/exif-tag.ts | 234 +- src/exif/exif-value-type.ts | 43 - src/exif/exif-value/exif-ascii-value.ts | 58 - src/exif/exif-value/exif-byte-value.ts | 61 - src/exif/exif-value/exif-double-value.ts | 66 - src/exif/exif-value/exif-long-value.ts | 66 - src/exif/exif-value/exif-rational-value.ts | 77 - src/exif/exif-value/exif-sbyte-value.ts | 63 - src/exif/exif-value/exif-short-value.ts | 62 - src/exif/exif-value/exif-single-value.ts | 66 - src/exif/exif-value/exif-slong-value.ts | 67 - src/exif/exif-value/exif-srational-value.ts | 78 - src/exif/exif-value/exif-sshort-value.ts | 69 - src/exif/exif-value/exif-undefined-value.ts | 53 - ...exif-ifd-container.ts => ifd-container.ts} | 23 +- src/exif/ifd-directory.ts | 490 + src/exif/ifd-value-type.ts | 27 + src/exif/ifd-value/ifd-ascii-value.ts | 65 + src/exif/ifd-value/ifd-byte-value.ts | 68 + src/exif/ifd-value/ifd-double-value.ts | 73 + src/exif/ifd-value/ifd-long-value.ts | 73 + src/exif/ifd-value/ifd-rational-value.ts | 84 + src/exif/ifd-value/ifd-sbyte-value.ts | 70 + src/exif/ifd-value/ifd-short-value.ts | 69 + src/exif/ifd-value/ifd-single-value.ts | 73 + src/exif/ifd-value/ifd-slong-value.ts | 74 + src/exif/ifd-value/ifd-srational-value.ts | 85 + src/exif/ifd-value/ifd-sshort-value.ts | 76 + src/exif/ifd-value/ifd-undefined-value.ts | 58 + .../exif-value.ts => ifd-value/ifd-value.ts} | 40 +- src/filter/adjust-color-options.ts | 17 - src/filter/color-offset-options.ts | 11 - src/filter/convolution-options.ts | 10 - src/filter/dither-kernel.ts | 57 + src/filter/filter.ts | 2588 ++++ src/filter/image-filter.ts | 949 -- src/filter/noise-type.ts | 2 +- src/filter/quantize-options.ts | 10 - src/filter/remap-colors-options.ts | 12 - src/filter/separable-kernel.ts | 102 +- src/filter/vignette-options.ts | 10 - src/formats/bmp-decoder.ts | 152 +- src/formats/bmp-encoder.ts | 380 +- src/formats/bmp/bitmap-compression-mode.ts | 6 - src/formats/bmp/bitmap-file-header.ts | 49 - src/formats/bmp/bmp-compression-mode.ts | 18 + src/formats/bmp/bmp-file-header.ts | 41 + src/formats/bmp/bmp-info.ts | 393 +- src/formats/decode-info.ts | 4 +- src/formats/decoder.ts | 88 +- src/formats/dib-decoder.ts | 8 +- src/formats/encoder.ts | 18 +- src/formats/gif-decoder.ts | 605 +- src/formats/gif-encoder.ts | 573 +- src/formats/gif/gif-color-map.ts | 95 +- src/formats/gif/gif-image-desc.ts | 4 +- src/formats/gif/gif-info.ts | 27 +- src/formats/ico-decoder.ts | 136 +- src/formats/ico/ico-bmp-info.ts | 2 +- src/formats/ico/ico-info-image.ts | 34 +- src/formats/ico/ico-info.ts | 92 +- src/formats/ico/ico-type.ts | 9 + src/formats/jpeg-decoder.ts | 61 +- src/formats/jpeg-encoder.ts | 412 +- src/formats/jpeg/huffman-node.ts | 3 + src/formats/jpeg/huffman-parent.ts | 15 + src/formats/jpeg/huffman-value.ts | 15 + ...mponent-data.ts => jpeg-component-data.ts} | 8 +- src/formats/jpeg/jpeg-component.ts | 14 +- src/formats/jpeg/jpeg-data.ts | 353 +- src/formats/jpeg/jpeg-frame.ts | 28 +- src/formats/jpeg/jpeg-huffman.ts | 6 +- src/formats/jpeg/jpeg-info.ts | 11 +- src/formats/jpeg/jpeg-marker.ts | 83 + src/formats/jpeg/jpeg-quantize.ts | 653 +- src/formats/jpeg/jpeg-scan.ts | 46 +- src/formats/jpeg/jpeg-utils.ts | 204 + src/formats/jpeg/jpeg.ts | 108 - src/formats/png-decoder.ts | 818 +- src/formats/png-encoder.ts | 640 +- .../png/png-blend-mode.ts} | 2 +- src/formats/png/png-color-type.ts | 9 + src/formats/png/png-dispose-mode.ts | 7 + src/formats/png/png-filter-type.ts | 9 + src/formats/png/png-frame.ts | 71 +- src/formats/png/png-info.ts | 135 +- src/formats/tga-decoder.ts | 344 +- src/formats/tga-encoder.ts | 39 +- src/formats/tga/tga-image-type.ts | 18 + src/formats/tga/tga-info.ts | 170 +- src/formats/tiff-decoder.ts | 108 +- src/formats/tiff-encoder.ts | 228 +- src/formats/tiff/tiff-bit-reader.ts | 42 +- src/formats/tiff/tiff-compression.ts | 28 + src/formats/tiff/tiff-entry.ts | 231 +- src/formats/tiff/tiff-fax-decoder.ts | 311 +- src/formats/tiff/tiff-format.ts | 8 + src/formats/tiff/tiff-image-type.ts | 14 + src/formats/tiff/tiff-image.ts | 1060 +- src/formats/tiff/tiff-info.ts | 15 +- src/formats/tiff/tiff-lzw-decoder.ts | 140 +- src/formats/tiff/tiff-photometric-type.ts | 39 + src/formats/win-encoder.ts | 51 +- src/hdr/hdr-image.ts | 474 - src/hdr/hdr-slice.ts | 208 - src/hdr/hdr-to-image.ts | 93 - src/image/frame-type.ts | 22 + src/{common => image}/heap-node.ts | 0 .../icc-profile-compression.ts} | 2 +- .../icc-profile.ts} | 30 +- src/image/image-data-float16.ts | 305 + src/image/image-data-float32.ts | 304 + src/image/image-data-float64.ts | 305 + src/image/image-data-int16.ts | 307 + src/image/image-data-int32.ts | 308 + src/image/image-data-int8.ts | 307 + src/image/image-data-uint1.ts | 326 + src/image/image-data-uint16.ts | 307 + src/image/image-data-uint2.ts | 326 + src/image/image-data-uint32.ts | 307 + src/image/image-data-uint4.ts | 333 + src/image/image-data-uint8.ts | 360 + src/image/image-data.ts | 183 + src/image/image-utils.ts | 182 + src/image/image.ts | 1333 ++ src/image/neural-quantizer.ts | 633 + src/{common => image}/octree-node.ts | 14 +- src/{common => image}/octree-quantizer.ts | 120 +- src/image/palette-float16.ts | 152 + src/image/palette-float32.ts | 151 + src/image/palette-float64.ts | 151 + src/image/palette-int16.ts | 151 + src/image/palette-int32.ts | 151 + src/image/palette-int8.ts | 151 + src/image/palette-uint16.ts | 151 + src/image/palette-uint32.ts | 151 + src/image/palette-uint8.ts | 163 + src/image/palette.ts | 96 + src/image/pixel-float16.ts | 335 + src/image/pixel-float32.ts | 326 + src/image/pixel-float64.ts | 326 + src/image/pixel-int16.ts | 326 + src/image/pixel-int32.ts | 326 + src/image/pixel-int8.ts | 321 + src/image/pixel-range-iterator.ts | 41 + src/image/pixel-uint1.ts | 388 + src/image/pixel-uint16.ts | 326 + src/image/pixel-uint2.ts | 385 + src/image/pixel-uint32.ts | 326 + src/image/pixel-uint4.ts | 385 + src/image/pixel-uint8.ts | 353 + src/image/pixel-undefined.ts | 193 + src/image/pixel.ts | 57 + src/image/quantizer-type.ts | 6 + src/image/quantizer.ts | 28 + src/index.ts | 766 +- src/transform/copy-into-options.ts | 16 - src/transform/copy-resize-options.ts | 18 - src/transform/image-transform.ts | 578 - src/transform/transform.ts | 1061 ++ src/transform/trim-mode.ts | 10 +- src/transform/trim-side.ts | 44 +- src/transform/trim.ts | 133 - test/_examples/create-thumbnail.ts | 35 + test/{res/png => _input/apng}/test_apng.png | Bin test/{res/png => _input/apng}/test_apng2.png | Bin test/{res/png => _input/apng}/test_apng3.png | Bin .../ico/child.ico => _input/bmp/alpha.bmp} | Bin 67646 -> 73146 bytes test/_input/bmp/alpha_bmp.bmp | Bin 0 -> 2870 bytes test/{res => _input}/bmp/buck_1.bmp | Bin test/{res => _input}/bmp/buck_24.bmp | Bin test/{res => _input}/bmp/buck_32.bmp | Bin test/_input/bmp/buck_4.bmp | Bin 0 -> 28396 bytes test/_input/bmp/buck_8.bmp | Bin 0 -> 56876 bytes test/_input/bmp/rgba16.bmp | Bin 0 -> 131128 bytes test/_input/bmp/rgba24.bmp | Bin 0 -> 196664 bytes test/_input/bmp/rgba32.bmp | Bin 0 -> 262282 bytes test/_input/gif/buck_24.gif | Bin 0 -> 39289 bytes test/{res => _input}/gif/cars.gif | Bin test/{res => _input}/gif/laser.gif | Bin test/{res => _input}/gif/wedge.gif | Bin test/_input/ico/microsoft-favicon.ico | Bin 0 -> 17174 bytes test/_input/ico/orf-favicon.ico | Bin 0 -> 22382 bytes test/_input/ico/wikipedia-favicon.ico | Bin 0 -> 2734 bytes test/{res => _input}/jpg/b2.jpg | Bin test/{res => _input}/jpg/big_buck_bunny.jpg | Bin test/_input/jpg/buck_24.jpg | Bin 0 -> 44519 bytes test/{res => _input}/jpg/cmyk.jpg | Bin test/{res => _input}/jpg/comment.jpg | Bin test/{res => _input}/jpg/j0.jpg | Bin test/{res => _input}/jpg/j0_2.jpg | Bin test/{res => _input}/jpg/j0_3.jpg | Bin test/{res => _input}/jpg/j0_4.jpg | Bin test/{res => _input}/jpg/j1.jpg | Bin test/{res => _input}/jpg/j2.jpg | Bin test/{res => _input}/jpg/j3.jpg | Bin test/{res => _input}/jpg/jpeg444.jpg | Bin test/{res => _input}/jpg/jpg-cmyk-1.jpg | Bin test/{res => _input}/jpg/jpg-cmyk-2.jpg | Bin test/{res => _input}/jpg/jpg-gray.jpg | Bin test/{res => _input}/jpg/jpg-progressive.jpg | Bin test/{res => _input}/jpg/jpg-size-15x15.jpg | Bin test/{res => _input}/jpg/jpg-size-16x16.jpg | Bin test/{res => _input}/jpg/jpg-size-17x17.jpg | Bin test/{res => _input}/jpg/jpg-size-1x1.jpg | Bin test/{res => _input}/jpg/jpg-size-2x2.jpg | Bin test/{res => _input}/jpg/jpg-size-31x31.jpg | Bin test/{res => _input}/jpg/jpg-size-32x32.jpg | Bin test/{res => _input}/jpg/jpg-size-33x33.jpg | Bin test/{res => _input}/jpg/jpg-size-3x3.jpg | Bin test/{res => _input}/jpg/jpg-size-4x4.jpg | Bin test/{res => _input}/jpg/jpg-size-5x5.jpg | Bin test/{res => _input}/jpg/jpg-size-7x7.jpg | Bin test/{res => _input}/jpg/jpg-size-8x8.jpg | Bin test/{res => _input}/jpg/jpg-size-9x9.jpg | Bin test/_input/jpg/kodak-dc210.jpg | Bin 0 -> 79837 bytes test/{res => _input}/jpg/landscape_1.jpg | Bin test/{res => _input}/jpg/landscape_2.jpg | Bin test/{res => _input}/jpg/landscape_3.jpg | Bin test/{res => _input}/jpg/landscape_4.jpg | Bin test/{res => _input}/jpg/landscape_5.jpg | Bin test/{res => _input}/jpg/landscape_6.jpg | Bin test/{res => _input}/jpg/landscape_7.jpg | Bin test/{res => _input}/jpg/landscape_8.jpg | Bin test/_input/jpg/oblique.jpg | Bin 0 -> 12529 bytes test/{res => _input}/jpg/portrait_1.jpg | Bin test/{res => _input}/jpg/portrait_2.jpg | Bin test/{res => _input}/jpg/portrait_3.jpg | Bin test/{res => _input}/jpg/portrait_4.jpg | Bin test/{res => _input}/jpg/portrait_5.jpg | Bin test/{res => _input}/jpg/portrait_6.jpg | Bin test/{res => _input}/jpg/portrait_7.jpg | Bin test/{res => _input}/jpg/portrait_8.jpg | Bin test/{res => _input}/jpg/progress.jpg | Bin test/{res => _input}/jpg/testimg.jpg | Bin test/{res => _input}/jpg/testimg.png | Bin test/{res => _input}/jpg/testimgp.jpg | Bin test/{res => _input}/jpg/testorig.jpg | Bin test/{res => _input}/jpg/testprog.jpg | Bin test/{res => _input}/png/PngSuite.LICENSE | 0 test/_input/png/alpha.png | Bin 0 -> 2439 bytes test/_input/png/alpha_bmp.png | Bin 0 -> 4543 bytes test/{res => _input}/png/alpha_edge.png | Bin test/{res => _input}/png/animated.png | Bin test/{res => _input}/png/basi0g01.png | Bin test/{res => _input}/png/basi0g02.png | Bin test/{res => _input}/png/basi0g04.png | Bin test/{res => _input}/png/basi0g08.png | Bin test/{res => _input}/png/basi0g16.png | Bin test/{res => _input}/png/basi2c08.png | Bin test/{res => _input}/png/basi2c16.png | Bin test/{res => _input}/png/basi3p01.png | Bin test/{res => _input}/png/basi3p02.png | Bin test/{res => _input}/png/basi3p04.png | Bin test/{res => _input}/png/basi3p08.png | Bin test/{res => _input}/png/basi4a08.png | Bin test/{res => _input}/png/basi4a16.png | Bin test/{res => _input}/png/basi6a08.png | Bin test/{res => _input}/png/basi6a16.png | Bin test/{res => _input}/png/basn0g01.png | Bin test/{res => _input}/png/basn0g02.png | Bin test/{res => _input}/png/basn0g04.png | Bin test/{res => _input}/png/basn0g08.png | Bin test/{res => _input}/png/basn0g16.png | Bin test/{res => _input}/png/basn2c08.png | Bin test/{res => _input}/png/basn2c16.png | Bin test/{res => _input}/png/basn3p01.png | Bin test/{res => _input}/png/basn3p02.png | Bin test/{res => _input}/png/basn3p04.png | Bin test/{res => _input}/png/basn3p08.png | Bin test/{res => _input}/png/basn4a08.png | Bin test/{res => _input}/png/basn4a16.png | Bin test/{res => _input}/png/basn6a08.png | Bin test/{res => _input}/png/basn6a16.png | Bin test/{res => _input}/png/bgai4a08.png | Bin test/{res => _input}/png/bgai4a16.png | Bin test/{res => _input}/png/bgan6a08.png | Bin test/{res => _input}/png/bgan6a16.png | Bin test/{res => _input}/png/bgbn4a08.png | Bin test/{res => _input}/png/bggn4a16.png | Bin test/{res => _input}/png/bgwn6a08.png | Bin test/{res => _input}/png/bgyn6a16.png | Bin test/{res => _input}/png/bkgd.png | Bin test/{res => _input}/png/broken/s01i3p01.png | Bin test/{res => _input}/png/broken/s02i3p01.png | Bin test/{res => _input}/png/broken/s03i3p01.png | Bin test/{res => _input}/png/broken/s04i3p01.png | Bin test/_input/png/buck_24.png | Bin 0 -> 102499 bytes test/_input/png/buck_8.png | Bin 0 -> 37926 bytes test/{res => _input}/png/ccwn2c08.png | Bin test/{res => _input}/png/ccwn3p08.png | Bin test/{res => _input}/png/cdfn2c08.png | Bin test/{res => _input}/png/cdhn2c08.png | Bin test/{res => _input}/png/cdsn2c08.png | Bin test/{res => _input}/png/cdun2c08.png | Bin test/{res => _input}/png/ch1n3p04.png | Bin test/{res => _input}/png/ch2n3p08.png | Bin test/{res => _input}/png/cm0n0g04.png | Bin test/{res => _input}/png/cm7n0g04.png | Bin test/{res => _input}/png/cm9n0g04.png | Bin test/_input/png/colors.png | Bin 0 -> 4535 bytes test/{res => _input}/png/cs3n2c16.png | Bin test/{res => _input}/png/cs3n3p08.png | Bin test/{res => _input}/png/cs5n2c08.png | Bin test/{res => _input}/png/cs5n3p08.png | Bin test/{res => _input}/png/cs8n2c08.png | Bin test/{res => _input}/png/cs8n3p08.png | Bin test/{res => _input}/png/ct0n0g04.png | Bin test/{res => _input}/png/ct1n0g04.png | Bin test/{res => _input}/png/cten0g04.png | Bin test/{res => _input}/png/ctfn0g04.png | Bin test/{res => _input}/png/ctgn0g04.png | Bin test/{res => _input}/png/cthn0g04.png | Bin test/{res => _input}/png/ctjn0g04.png | Bin test/{res => _input}/png/ctzn0g04.png | Bin test/{res => _input}/png/f00n0g08.png | Bin test/{res => _input}/png/f00n2c08.png | Bin test/{res => _input}/png/f01n0g08.png | Bin test/{res => _input}/png/f01n2c08.png | Bin test/{res => _input}/png/f02n0g08.png | Bin test/{res => _input}/png/f02n2c08.png | Bin test/{res => _input}/png/f03n0g08.png | Bin test/{res => _input}/png/f03n2c08.png | Bin test/{res => _input}/png/f04n0g08.png | Bin test/{res => _input}/png/f04n2c08.png | Bin test/{res => _input}/png/f99n0g04.png | Bin test/{res => _input}/png/g03n0g16.png | Bin test/{res => _input}/png/g03n2c08.png | Bin test/{res => _input}/png/g03n3p04.png | Bin test/{res => _input}/png/g04n0g16.png | Bin test/{res => _input}/png/g04n2c08.png | Bin test/{res => _input}/png/g04n3p04.png | Bin test/{res => _input}/png/g05n0g16.png | Bin test/{res => _input}/png/g05n2c08.png | Bin test/{res => _input}/png/g05n3p04.png | Bin test/{res => _input}/png/g07n0g16.png | Bin test/{res => _input}/png/g07n2c08.png | Bin test/{res => _input}/png/g07n3p04.png | Bin test/_input/png/g1.png | Bin 0 -> 4392 bytes test/{res => _input}/png/g10n0g16.png | Bin test/{res => _input}/png/g10n2c08.png | Bin test/{res => _input}/png/g10n3p04.png | Bin test/_input/png/g2.png | Bin 0 -> 4450 bytes test/{res => _input}/png/g25n0g16.png | Bin test/{res => _input}/png/g25n2c08.png | Bin test/{res => _input}/png/g25n3p04.png | Bin test/_input/png/g3.png | Bin 0 -> 4457 bytes test/_input/png/hungry_180.png | Bin 0 -> 1954 bytes test/{res => _input}/png/iCCP.png | Bin test/{res => _input}/png/oi1n0g16.png | Bin test/{res => _input}/png/oi1n2c16.png | Bin test/{res => _input}/png/oi2n0g16.png | Bin test/{res => _input}/png/oi2n2c16.png | Bin test/{res => _input}/png/oi4n0g16.png | Bin test/{res => _input}/png/oi4n2c16.png | Bin test/{res => _input}/png/oi9n0g16.png | Bin test/{res => _input}/png/oi9n2c16.png | Bin test/{res => _input}/png/pp0n2c16.png | Bin test/{res => _input}/png/pp0n6a08.png | Bin test/{res => _input}/png/ps1n0g08.png | Bin test/{res => _input}/png/ps1n2c16.png | Bin test/{res => _input}/png/ps2n0g08.png | Bin test/{res => _input}/png/ps2n2c16.png | Bin test/{res => _input}/png/s01n3p01.png | Bin test/{res => _input}/png/s02n3p01.png | Bin test/{res => _input}/png/s03n3p01.png | Bin test/{res => _input}/png/s04n3p01.png | Bin test/{res => _input}/png/s05i3p02.png | Bin test/{res => _input}/png/s05n3p02.png | Bin test/{res => _input}/png/s06i3p02.png | Bin test/{res => _input}/png/s06n3p02.png | Bin test/{res => _input}/png/s07i3p02.png | Bin test/{res => _input}/png/s07n3p02.png | Bin test/{res => _input}/png/s08i3p02.png | Bin test/{res => _input}/png/s08n3p02.png | Bin test/{res => _input}/png/s09i3p02.png | Bin test/{res => _input}/png/s09n3p02.png | Bin test/{res => _input}/png/s32i3p04.png | Bin test/{res => _input}/png/s32n3p04.png | Bin test/{res => _input}/png/s33i3p04.png | Bin test/{res => _input}/png/s33n3p04.png | Bin test/{res => _input}/png/s34i3p04.png | Bin test/{res => _input}/png/s34n3p04.png | Bin test/{res => _input}/png/s35i3p04.png | Bin test/{res => _input}/png/s35n3p04.png | Bin test/{res => _input}/png/s36i3p04.png | Bin test/{res => _input}/png/s36n3p04.png | Bin test/{res => _input}/png/s37i3p04.png | Bin test/{res => _input}/png/s37n3p04.png | Bin test/{res => _input}/png/s38i3p04.png | Bin test/{res => _input}/png/s38n3p04.png | Bin test/{res => _input}/png/s39i3p04.png | Bin test/{res => _input}/png/s39n3p04.png | Bin test/{res => _input}/png/s40i3p04.png | Bin test/{res => _input}/png/s40n3p04.png | Bin test/{res => _input}/png/small.png | Bin test/{res => _input}/png/tbbn0g04.png | Bin test/{res => _input}/png/tbbn2c16.png | Bin test/{res => _input}/png/tbbn3p08.png | Bin test/{res => _input}/png/tbgn2c16.png | Bin test/{res => _input}/png/tbgn3p08.png | Bin test/{res => _input}/png/tbrn2c08.png | Bin test/{res => _input}/png/tbwn0g16.png | Bin test/{res => _input}/png/tbwn3p08.png | Bin test/{res => _input}/png/tbyn3p08.png | Bin test/_input/png/test.png | Bin 0 -> 13297 bytes test/{res => _input}/png/tm3n3p02.png | Bin test/{res => _input}/png/tp0n0g08.png | Bin test/{res => _input}/png/tp0n2c08.png | Bin test/{res => _input}/png/tp0n3p08.png | Bin test/{res => _input}/png/tp1n3p08.png | Bin test/_input/png/trim.png | Bin 0 -> 2250 bytes test/{res => _input}/png/xc1n0g08.png | Bin test/{res => _input}/png/xc9n2c08.png | Bin test/{res => _input}/png/xcrn0g04.png | Bin test/{res => _input}/png/xcsn0g01.png | Bin test/{res => _input}/png/xd0n2c08.png | Bin test/{res => _input}/png/xd3n2c08.png | Bin test/{res => _input}/png/xd9n2c08.png | Bin test/{res => _input}/png/xdtn0g01.png | Bin test/{res => _input}/png/xhdn0g08.png | Bin test/{res => _input}/png/xlfn0g04.png | Bin test/{res => _input}/png/xs1n0g01.png | Bin test/{res => _input}/png/xs2n0g01.png | Bin test/{res => _input}/png/xs4n0g01.png | Bin test/{res => _input}/png/xs7n0g01.png | Bin test/{res => _input}/png/z00n2c08.png | Bin test/{res => _input}/png/z03n2c08.png | Bin test/{res => _input}/png/z06n2c08.png | Bin test/{res => _input}/png/z09n2c08.png | Bin test/_input/tga/buck_16.tga | Bin 0 -> 111644 bytes test/_input/tga/buck_16_rle.tga | Bin 0 -> 88973 bytes test/_input/tga/buck_24.tga | Bin 0 -> 167418 bytes test/_input/tga/buck_24_rle.tga | Bin 0 -> 149751 bytes test/_input/tga/buck_32.tga | Bin 0 -> 223244 bytes test/_input/tga/buck_32_rle.tga | Bin 0 -> 198256 bytes test/_input/tga/buck_8p.tga | Bin 0 -> 56612 bytes test/{res => _input}/tga/globe.tga | Bin test/{res => _input}/tiff/aspect32float.tif | Bin test/{res => _input}/tiff/bitonal_lzw.tif | Bin test/{res => _input}/tiff/bitonal_none.tif | Bin test/{res => _input}/tiff/bitonal_zip.tif | Bin .../{res => _input}/tiff/ccitt_t4_1d_fill.tif | Bin .../{res => _input}/tiff/ccitt_t4_2d_fill.tif | Bin .../tiff/ccitt_t4_2d_nofill.tif | Bin test/{res => _input}/tiff/ccitt_t6.tif | Bin .../tiff/ccittt_t4_1d_nofill.tif | Bin test/{res => _input}/tiff/cmyk.tif | Bin test/{res => _input}/tiff/dtm32float.tif | Bin test/{res => _input}/tiff/dtm64float.tif | Bin test/{res => _input}/tiff/dtm_test.tif | Bin test/{res => _input}/tiff/float16.tif | Bin test/{res => _input}/tiff/float1x32.tif | Bin test/{res => _input}/tiff/float32.tif | Bin test/{res => _input}/tiff/flow16int.tif | Bin test/{res => _input}/tiff/globe.tif | Bin test/{res => _input}/tiff/lzw_strips.tif | Bin test/{res => _input}/tiff/lzw_tiled.tif | Bin test/_input/tiff/palette_ps.tif | Bin 0 -> 89700 bytes test/{res => _input}/tiff/small.tif | Bin test/{res => _input}/tiff/tca32int.tif | Bin test/_utils/file-info.ts | 6 + test/_utils/image-test-utils.ts | 66 + test/_utils/test-folder.ts | 6 + test/_utils/test-section.ts | 18 + .../{test-helpers.ts => _utils/test-utils.ts} | 53 +- test/bmp.test.ts | 41 - test/color/color.float16.test.ts | 15 + test/color/color.float32.test.ts | 15 + test/color/color.float64.test.ts | 15 + test/color/color.int16.test.ts | 15 + test/color/color.int32.test.ts | 15 + test/color/color.int8.test.ts | 15 + test/color/color.uint1.test.ts | 21 + test/color/color.uint16.test.ts | 15 + test/color/color.uint2.test.ts | 21 + test/color/color.uint32.test.ts | 15 + test/color/color.uint4.test.ts | 22 + test/color/color.uint8.test.ts | 51 + test/draw.test.ts | 275 - test/draw/draw.composite-image.test.ts | 161 + test/draw/draw.draw-circle.test.ts | 39 + test/draw/draw.draw-line.test.ts | 73 + test/draw/draw.draw-pixel.test.ts | 40 + test/draw/draw.draw-polygon.test.ts | 53 + test/draw/draw.draw-rect.test.ts | 62 + test/draw/draw.fill-circle.test.ts | 40 + test/draw/draw.fill-flood.test.ts | 39 + test/draw/draw.fill-polygon.test.ts | 38 + test/draw/draw.fill-rect.test.ts | 61 + test/draw/draw.fill.test.ts | 30 + test/exif.test.ts | 76 - test/exif/exif.base.test.ts | 112 + test/filter.test.ts | 462 - test/filter/filter.adjust-color.test.ts | 39 + test/filter/filter.billboard.test.ts | 38 + test/filter/filter.bleach-bypass.test.ts | 38 + test/filter/filter.bulge-distortion.test.ts | 39 + test/filter/filter.bump-to-normal.test.ts | 38 + .../filter.chromatic-aberration.test.ts | 38 + test/filter/filter.color-halftone.test.ts | 38 + test/filter/filter.color-offset.test.ts | 41 + test/filter/filter.contrast.test.ts | 39 + test/filter/filter.convolution.test.ts | 47 + test/filter/filter.copy-image-channel.test.ts | 65 + test/filter/filter.dither-image.test.ts | 99 + test/filter/filter.dot-screen.test.ts | 38 + test/filter/filter.drop-shadow.test.ts | 58 + test/filter/filter.edge-glow.test.ts | 38 + test/filter/filter.emboss.test.ts | 38 + test/filter/filter.gamma.test.ts | 39 + test/filter/filter.gaussian-blur.test.ts | 39 + test/filter/filter.grayscale.test.ts | 38 + test/filter/filter.hexagon-pixelate.test.ts | 39 + test/filter/filter.invert.test.ts | 38 + .../filter/filter.luminance-threshold.test.ts | 38 + test/filter/filter.monochrome.test.ts | 39 + test/filter/filter.noise.test.ts | 39 + test/filter/filter.normalize.test.ts | 40 + test/filter/filter.pixelate.test.ts | 57 + test/filter/filter.quantize.test.ts | 57 + test/filter/filter.remap-colors.test.ts | 41 + test/filter/filter.scale-rgba.test.ts | 39 + .../filter.separable-convolution.test.ts | 56 + test/filter/filter.sepia.test.ts | 38 + test/filter/filter.sketch.test.ts | 38 + test/filter/filter.smooth.test.ts | 39 + test/filter/filter.sobel.test.ts | 38 + test/filter/filter.stretch-distortion.test.ts | 39 + test/filter/filter.vignette.test.ts | 70 + test/format/format.bmp.test.ts | 78 + test/format/format.gif.test.ts | 325 + test/format/format.ico.test.ts | 102 + test/format/format.jpeg.test.ts | 159 + test/format/format.png.test.ts | 920 ++ test/format/format.tga.test.ts | 39 + test/format/format.tiff.test.ts | 807 + test/gif.test.ts | 194 - test/ico.test.ts | 83 - test/image/image.base.test.ts | 221 + test/image/image.float16.test.ts | 89 + test/image/image.float32.test.ts | 89 + test/image/image.float64.test.ts | 89 + test/image/image.int16.test.ts | 89 + test/image/image.int32.test.ts | 89 + test/image/image.int8.test.ts | 89 + test/image/image.uint1.test.ts | 223 + test/image/image.uint16.test.ts | 110 + test/image/image.uint2.test.ts | 194 + test/image/image.uint32.test.ts | 99 + test/image/image.uint4.test.ts | 210 + test/image/image.uint8.test.ts | 200 + test/jpeg.test.ts | 118 - test/png.test.ts | 229 - test/res/.DS_Store | Bin 8196 -> 0 bytes test/res/filter/test.png | Bin 154302 -> 0 bytes test/res/ico/man.ico | Bin 67646 -> 0 bytes test/res/ico/woman.ico | Bin 67646 -> 0 bytes test/res/png/decode.png | Bin 209 -> 0 bytes test/res/png/trim.png | Bin 3785 -> 0 bytes test/tga.test.ts | 62 - test/tiff.test.ts | 280 - .../transform.copy-crop-circle.test.ts | 45 + test/transform/transform.copy-crop.test.ts | 66 + test/transform/transform.copy-flip.test.ts | 74 + test/transform/transform.copy-rectify.test.ts | 54 + .../transform.copy-resize-crop-square.test.ts | 126 + test/transform/transform.copy-resize.test.ts | 72 + test/transform/transform.copy-rotate.test.ts | 42 + test/transform/transform.trim.test.ts | 76 + tsconfig.build.json | 6 + tsconfig.json | 66 +- 641 files changed, 47622 insertions(+), 28123 deletions(-) create mode 100644 src/color/channel-order.ts create mode 100644 src/color/channel.ts create mode 100644 src/color/color-float16.ts create mode 100644 src/color/color-float32.ts create mode 100644 src/color/color-float64.ts create mode 100644 src/color/color-int16.ts create mode 100644 src/color/color-int32.ts create mode 100644 src/color/color-int8.ts create mode 100644 src/color/color-rgb8.ts create mode 100644 src/color/color-rgba8.ts create mode 100644 src/color/color-uint1.ts create mode 100644 src/color/color-uint16.ts create mode 100644 src/color/color-uint2.ts create mode 100644 src/color/color-uint32.ts create mode 100644 src/color/color-uint4.ts create mode 100644 src/color/color-uint8.ts create mode 100644 src/color/color-utils.ts create mode 100644 src/color/color.ts create mode 100644 src/color/format.ts delete mode 100644 src/common/bit-operators.ts create mode 100644 src/common/bit-utils.ts delete mode 100644 src/common/color-channel.ts delete mode 100644 src/common/color-model.ts delete mode 100644 src/common/color.ts delete mode 100644 src/common/dispose-mode.ts delete mode 100644 src/common/dither-kernel.ts delete mode 100644 src/common/dither-pixel.ts rename src/{hdr/half.ts => common/float16.ts} (69%) delete mode 100644 src/common/frame-animation.ts delete mode 100644 src/common/frame-type.ts delete mode 100644 src/common/math-operators.ts create mode 100644 src/common/math-utils.ts delete mode 100644 src/common/memory-image.ts delete mode 100644 src/common/neural-quantizer.ts delete mode 100644 src/common/quantizer.ts delete mode 100644 src/common/rgb-channel-set.ts rename src/common/{text-codec.ts => string-utils.ts} (78%) create mode 100644 src/draw/blend-mode.ts create mode 100644 src/draw/circle-quadrant.ts delete mode 100644 src/draw/draw-image-options.ts delete mode 100644 src/draw/draw-line-options.ts delete mode 100644 src/draw/fill-flood-options.ts delete mode 100644 src/draw/mask-flood-options.ts delete mode 100644 src/error/image-error.ts create mode 100644 src/error/lib-error.ts delete mode 100644 src/error/not-implemented-error.ts delete mode 100644 src/exif/exif-ifd.ts delete mode 100644 src/exif/exif-value-type.ts delete mode 100644 src/exif/exif-value/exif-ascii-value.ts delete mode 100644 src/exif/exif-value/exif-byte-value.ts delete mode 100644 src/exif/exif-value/exif-double-value.ts delete mode 100644 src/exif/exif-value/exif-long-value.ts delete mode 100644 src/exif/exif-value/exif-rational-value.ts delete mode 100644 src/exif/exif-value/exif-sbyte-value.ts delete mode 100644 src/exif/exif-value/exif-short-value.ts delete mode 100644 src/exif/exif-value/exif-single-value.ts delete mode 100644 src/exif/exif-value/exif-slong-value.ts delete mode 100644 src/exif/exif-value/exif-srational-value.ts delete mode 100644 src/exif/exif-value/exif-sshort-value.ts delete mode 100644 src/exif/exif-value/exif-undefined-value.ts rename src/exif/{exif-ifd-container.ts => ifd-container.ts} (58%) create mode 100644 src/exif/ifd-directory.ts create mode 100644 src/exif/ifd-value-type.ts create mode 100644 src/exif/ifd-value/ifd-ascii-value.ts create mode 100644 src/exif/ifd-value/ifd-byte-value.ts create mode 100644 src/exif/ifd-value/ifd-double-value.ts create mode 100644 src/exif/ifd-value/ifd-long-value.ts create mode 100644 src/exif/ifd-value/ifd-rational-value.ts create mode 100644 src/exif/ifd-value/ifd-sbyte-value.ts create mode 100644 src/exif/ifd-value/ifd-short-value.ts create mode 100644 src/exif/ifd-value/ifd-single-value.ts create mode 100644 src/exif/ifd-value/ifd-slong-value.ts create mode 100644 src/exif/ifd-value/ifd-srational-value.ts create mode 100644 src/exif/ifd-value/ifd-sshort-value.ts create mode 100644 src/exif/ifd-value/ifd-undefined-value.ts rename src/exif/{exif-value/exif-value.ts => ifd-value/ifd-value.ts} (63%) delete mode 100644 src/filter/adjust-color-options.ts delete mode 100644 src/filter/color-offset-options.ts delete mode 100644 src/filter/convolution-options.ts create mode 100644 src/filter/dither-kernel.ts create mode 100644 src/filter/filter.ts delete mode 100644 src/filter/image-filter.ts delete mode 100644 src/filter/quantize-options.ts delete mode 100644 src/filter/remap-colors-options.ts delete mode 100644 src/filter/vignette-options.ts delete mode 100644 src/formats/bmp/bitmap-compression-mode.ts delete mode 100644 src/formats/bmp/bitmap-file-header.ts create mode 100644 src/formats/bmp/bmp-compression-mode.ts create mode 100644 src/formats/bmp/bmp-file-header.ts create mode 100644 src/formats/ico/ico-type.ts create mode 100644 src/formats/jpeg/huffman-node.ts create mode 100644 src/formats/jpeg/huffman-parent.ts create mode 100644 src/formats/jpeg/huffman-value.ts rename src/formats/jpeg/{component-data.ts => jpeg-component-data.ts} (86%) create mode 100644 src/formats/jpeg/jpeg-marker.ts create mode 100644 src/formats/jpeg/jpeg-utils.ts delete mode 100644 src/formats/jpeg/jpeg.ts rename src/{common/blend-mode.ts => formats/png/png-blend-mode.ts} (90%) create mode 100644 src/formats/png/png-color-type.ts create mode 100644 src/formats/png/png-dispose-mode.ts create mode 100644 src/formats/png/png-filter-type.ts create mode 100644 src/formats/tga/tga-image-type.ts create mode 100644 src/formats/tiff/tiff-compression.ts create mode 100644 src/formats/tiff/tiff-format.ts create mode 100644 src/formats/tiff/tiff-image-type.ts create mode 100644 src/formats/tiff/tiff-photometric-type.ts delete mode 100644 src/hdr/hdr-image.ts delete mode 100644 src/hdr/hdr-slice.ts delete mode 100644 src/hdr/hdr-to-image.ts create mode 100644 src/image/frame-type.ts rename src/{common => image}/heap-node.ts (100%) rename src/{common/iccp-compression-mode.ts => image/icc-profile-compression.ts} (50%) rename src/{common/icc-profile-data.ts => image/icc-profile.ts} (59%) create mode 100644 src/image/image-data-float16.ts create mode 100644 src/image/image-data-float32.ts create mode 100644 src/image/image-data-float64.ts create mode 100644 src/image/image-data-int16.ts create mode 100644 src/image/image-data-int32.ts create mode 100644 src/image/image-data-int8.ts create mode 100644 src/image/image-data-uint1.ts create mode 100644 src/image/image-data-uint16.ts create mode 100644 src/image/image-data-uint2.ts create mode 100644 src/image/image-data-uint32.ts create mode 100644 src/image/image-data-uint4.ts create mode 100644 src/image/image-data-uint8.ts create mode 100644 src/image/image-data.ts create mode 100644 src/image/image-utils.ts create mode 100644 src/image/image.ts create mode 100644 src/image/neural-quantizer.ts rename src/{common => image}/octree-node.ts (84%) rename src/{common => image}/octree-quantizer.ts (54%) create mode 100644 src/image/palette-float16.ts create mode 100644 src/image/palette-float32.ts create mode 100644 src/image/palette-float64.ts create mode 100644 src/image/palette-int16.ts create mode 100644 src/image/palette-int32.ts create mode 100644 src/image/palette-int8.ts create mode 100644 src/image/palette-uint16.ts create mode 100644 src/image/palette-uint32.ts create mode 100644 src/image/palette-uint8.ts create mode 100644 src/image/palette.ts create mode 100644 src/image/pixel-float16.ts create mode 100644 src/image/pixel-float32.ts create mode 100644 src/image/pixel-float64.ts create mode 100644 src/image/pixel-int16.ts create mode 100644 src/image/pixel-int32.ts create mode 100644 src/image/pixel-int8.ts create mode 100644 src/image/pixel-range-iterator.ts create mode 100644 src/image/pixel-uint1.ts create mode 100644 src/image/pixel-uint16.ts create mode 100644 src/image/pixel-uint2.ts create mode 100644 src/image/pixel-uint32.ts create mode 100644 src/image/pixel-uint4.ts create mode 100644 src/image/pixel-uint8.ts create mode 100644 src/image/pixel-undefined.ts create mode 100644 src/image/pixel.ts create mode 100644 src/image/quantizer-type.ts create mode 100644 src/image/quantizer.ts delete mode 100644 src/transform/copy-into-options.ts delete mode 100644 src/transform/copy-resize-options.ts delete mode 100644 src/transform/image-transform.ts create mode 100644 src/transform/transform.ts delete mode 100644 src/transform/trim.ts create mode 100644 test/_examples/create-thumbnail.ts rename test/{res/png => _input/apng}/test_apng.png (100%) rename test/{res/png => _input/apng}/test_apng2.png (100%) rename test/{res/png => _input/apng}/test_apng3.png (100%) rename test/{res/ico/child.ico => _input/bmp/alpha.bmp} (52%) create mode 100644 test/_input/bmp/alpha_bmp.bmp rename test/{res => _input}/bmp/buck_1.bmp (100%) rename test/{res => _input}/bmp/buck_24.bmp (100%) rename test/{res => _input}/bmp/buck_32.bmp (100%) create mode 100644 test/_input/bmp/buck_4.bmp create mode 100644 test/_input/bmp/buck_8.bmp create mode 100644 test/_input/bmp/rgba16.bmp create mode 100644 test/_input/bmp/rgba24.bmp create mode 100644 test/_input/bmp/rgba32.bmp create mode 100644 test/_input/gif/buck_24.gif rename test/{res => _input}/gif/cars.gif (100%) rename test/{res => _input}/gif/laser.gif (100%) rename test/{res => _input}/gif/wedge.gif (100%) create mode 100644 test/_input/ico/microsoft-favicon.ico create mode 100644 test/_input/ico/orf-favicon.ico create mode 100644 test/_input/ico/wikipedia-favicon.ico rename test/{res => _input}/jpg/b2.jpg (100%) rename test/{res => _input}/jpg/big_buck_bunny.jpg (100%) create mode 100644 test/_input/jpg/buck_24.jpg rename test/{res => _input}/jpg/cmyk.jpg (100%) rename test/{res => _input}/jpg/comment.jpg (100%) rename test/{res => _input}/jpg/j0.jpg (100%) rename test/{res => _input}/jpg/j0_2.jpg (100%) rename test/{res => _input}/jpg/j0_3.jpg (100%) rename test/{res => _input}/jpg/j0_4.jpg (100%) rename test/{res => _input}/jpg/j1.jpg (100%) rename test/{res => _input}/jpg/j2.jpg (100%) rename test/{res => _input}/jpg/j3.jpg (100%) rename test/{res => _input}/jpg/jpeg444.jpg (100%) rename test/{res => _input}/jpg/jpg-cmyk-1.jpg (100%) rename test/{res => _input}/jpg/jpg-cmyk-2.jpg (100%) rename test/{res => _input}/jpg/jpg-gray.jpg (100%) rename test/{res => _input}/jpg/jpg-progressive.jpg (100%) rename test/{res => _input}/jpg/jpg-size-15x15.jpg (100%) rename test/{res => _input}/jpg/jpg-size-16x16.jpg (100%) rename test/{res => _input}/jpg/jpg-size-17x17.jpg (100%) rename test/{res => _input}/jpg/jpg-size-1x1.jpg (100%) rename test/{res => _input}/jpg/jpg-size-2x2.jpg (100%) rename test/{res => _input}/jpg/jpg-size-31x31.jpg (100%) rename test/{res => _input}/jpg/jpg-size-32x32.jpg (100%) rename test/{res => _input}/jpg/jpg-size-33x33.jpg (100%) rename test/{res => _input}/jpg/jpg-size-3x3.jpg (100%) rename test/{res => _input}/jpg/jpg-size-4x4.jpg (100%) rename test/{res => _input}/jpg/jpg-size-5x5.jpg (100%) rename test/{res => _input}/jpg/jpg-size-7x7.jpg (100%) rename test/{res => _input}/jpg/jpg-size-8x8.jpg (100%) rename test/{res => _input}/jpg/jpg-size-9x9.jpg (100%) create mode 100644 test/_input/jpg/kodak-dc210.jpg rename test/{res => _input}/jpg/landscape_1.jpg (100%) rename test/{res => _input}/jpg/landscape_2.jpg (100%) rename test/{res => _input}/jpg/landscape_3.jpg (100%) rename test/{res => _input}/jpg/landscape_4.jpg (100%) rename test/{res => _input}/jpg/landscape_5.jpg (100%) rename test/{res => _input}/jpg/landscape_6.jpg (100%) rename test/{res => _input}/jpg/landscape_7.jpg (100%) rename test/{res => _input}/jpg/landscape_8.jpg (100%) create mode 100644 test/_input/jpg/oblique.jpg rename test/{res => _input}/jpg/portrait_1.jpg (100%) rename test/{res => _input}/jpg/portrait_2.jpg (100%) rename test/{res => _input}/jpg/portrait_3.jpg (100%) rename test/{res => _input}/jpg/portrait_4.jpg (100%) rename test/{res => _input}/jpg/portrait_5.jpg (100%) rename test/{res => _input}/jpg/portrait_6.jpg (100%) rename test/{res => _input}/jpg/portrait_7.jpg (100%) rename test/{res => _input}/jpg/portrait_8.jpg (100%) rename test/{res => _input}/jpg/progress.jpg (100%) rename test/{res => _input}/jpg/testimg.jpg (100%) rename test/{res => _input}/jpg/testimg.png (100%) rename test/{res => _input}/jpg/testimgp.jpg (100%) rename test/{res => _input}/jpg/testorig.jpg (100%) rename test/{res => _input}/jpg/testprog.jpg (100%) rename test/{res => _input}/png/PngSuite.LICENSE (100%) create mode 100644 test/_input/png/alpha.png create mode 100644 test/_input/png/alpha_bmp.png rename test/{res => _input}/png/alpha_edge.png (100%) rename test/{res => _input}/png/animated.png (100%) rename test/{res => _input}/png/basi0g01.png (100%) rename test/{res => _input}/png/basi0g02.png (100%) rename test/{res => _input}/png/basi0g04.png (100%) rename test/{res => _input}/png/basi0g08.png (100%) rename test/{res => _input}/png/basi0g16.png (100%) rename test/{res => _input}/png/basi2c08.png (100%) rename test/{res => _input}/png/basi2c16.png (100%) rename test/{res => _input}/png/basi3p01.png (100%) rename test/{res => _input}/png/basi3p02.png (100%) rename test/{res => _input}/png/basi3p04.png (100%) rename test/{res => _input}/png/basi3p08.png (100%) rename test/{res => _input}/png/basi4a08.png (100%) rename test/{res => _input}/png/basi4a16.png (100%) rename test/{res => _input}/png/basi6a08.png (100%) rename test/{res => _input}/png/basi6a16.png (100%) rename test/{res => _input}/png/basn0g01.png (100%) rename test/{res => _input}/png/basn0g02.png (100%) rename test/{res => _input}/png/basn0g04.png (100%) rename test/{res => _input}/png/basn0g08.png (100%) rename test/{res => _input}/png/basn0g16.png (100%) rename test/{res => _input}/png/basn2c08.png (100%) rename test/{res => _input}/png/basn2c16.png (100%) rename test/{res => _input}/png/basn3p01.png (100%) rename test/{res => _input}/png/basn3p02.png (100%) rename test/{res => _input}/png/basn3p04.png (100%) rename test/{res => _input}/png/basn3p08.png (100%) rename test/{res => _input}/png/basn4a08.png (100%) rename test/{res => _input}/png/basn4a16.png (100%) rename test/{res => _input}/png/basn6a08.png (100%) rename test/{res => _input}/png/basn6a16.png (100%) rename test/{res => _input}/png/bgai4a08.png (100%) rename test/{res => _input}/png/bgai4a16.png (100%) rename test/{res => _input}/png/bgan6a08.png (100%) rename test/{res => _input}/png/bgan6a16.png (100%) rename test/{res => _input}/png/bgbn4a08.png (100%) rename test/{res => _input}/png/bggn4a16.png (100%) rename test/{res => _input}/png/bgwn6a08.png (100%) rename test/{res => _input}/png/bgyn6a16.png (100%) rename test/{res => _input}/png/bkgd.png (100%) rename test/{res => _input}/png/broken/s01i3p01.png (100%) rename test/{res => _input}/png/broken/s02i3p01.png (100%) rename test/{res => _input}/png/broken/s03i3p01.png (100%) rename test/{res => _input}/png/broken/s04i3p01.png (100%) create mode 100644 test/_input/png/buck_24.png create mode 100644 test/_input/png/buck_8.png rename test/{res => _input}/png/ccwn2c08.png (100%) rename test/{res => _input}/png/ccwn3p08.png (100%) rename test/{res => _input}/png/cdfn2c08.png (100%) rename test/{res => _input}/png/cdhn2c08.png (100%) rename test/{res => _input}/png/cdsn2c08.png (100%) rename test/{res => _input}/png/cdun2c08.png (100%) rename test/{res => _input}/png/ch1n3p04.png (100%) rename test/{res => _input}/png/ch2n3p08.png (100%) rename test/{res => _input}/png/cm0n0g04.png (100%) rename test/{res => _input}/png/cm7n0g04.png (100%) rename test/{res => _input}/png/cm9n0g04.png (100%) create mode 100644 test/_input/png/colors.png rename test/{res => _input}/png/cs3n2c16.png (100%) rename test/{res => _input}/png/cs3n3p08.png (100%) rename test/{res => _input}/png/cs5n2c08.png (100%) rename test/{res => _input}/png/cs5n3p08.png (100%) rename test/{res => _input}/png/cs8n2c08.png (100%) rename test/{res => _input}/png/cs8n3p08.png (100%) rename test/{res => _input}/png/ct0n0g04.png (100%) rename test/{res => _input}/png/ct1n0g04.png (100%) rename test/{res => _input}/png/cten0g04.png (100%) rename test/{res => _input}/png/ctfn0g04.png (100%) rename test/{res => _input}/png/ctgn0g04.png (100%) rename test/{res => _input}/png/cthn0g04.png (100%) rename test/{res => _input}/png/ctjn0g04.png (100%) rename test/{res => _input}/png/ctzn0g04.png (100%) rename test/{res => _input}/png/f00n0g08.png (100%) rename test/{res => _input}/png/f00n2c08.png (100%) rename test/{res => _input}/png/f01n0g08.png (100%) rename test/{res => _input}/png/f01n2c08.png (100%) rename test/{res => _input}/png/f02n0g08.png (100%) rename test/{res => _input}/png/f02n2c08.png (100%) rename test/{res => _input}/png/f03n0g08.png (100%) rename test/{res => _input}/png/f03n2c08.png (100%) rename test/{res => _input}/png/f04n0g08.png (100%) rename test/{res => _input}/png/f04n2c08.png (100%) rename test/{res => _input}/png/f99n0g04.png (100%) rename test/{res => _input}/png/g03n0g16.png (100%) rename test/{res => _input}/png/g03n2c08.png (100%) rename test/{res => _input}/png/g03n3p04.png (100%) rename test/{res => _input}/png/g04n0g16.png (100%) rename test/{res => _input}/png/g04n2c08.png (100%) rename test/{res => _input}/png/g04n3p04.png (100%) rename test/{res => _input}/png/g05n0g16.png (100%) rename test/{res => _input}/png/g05n2c08.png (100%) rename test/{res => _input}/png/g05n3p04.png (100%) rename test/{res => _input}/png/g07n0g16.png (100%) rename test/{res => _input}/png/g07n2c08.png (100%) rename test/{res => _input}/png/g07n3p04.png (100%) create mode 100644 test/_input/png/g1.png rename test/{res => _input}/png/g10n0g16.png (100%) rename test/{res => _input}/png/g10n2c08.png (100%) rename test/{res => _input}/png/g10n3p04.png (100%) create mode 100644 test/_input/png/g2.png rename test/{res => _input}/png/g25n0g16.png (100%) rename test/{res => _input}/png/g25n2c08.png (100%) rename test/{res => _input}/png/g25n3p04.png (100%) create mode 100644 test/_input/png/g3.png create mode 100644 test/_input/png/hungry_180.png rename test/{res => _input}/png/iCCP.png (100%) rename test/{res => _input}/png/oi1n0g16.png (100%) rename test/{res => _input}/png/oi1n2c16.png (100%) rename test/{res => _input}/png/oi2n0g16.png (100%) rename test/{res => _input}/png/oi2n2c16.png (100%) rename test/{res => _input}/png/oi4n0g16.png (100%) rename test/{res => _input}/png/oi4n2c16.png (100%) rename test/{res => _input}/png/oi9n0g16.png (100%) rename test/{res => _input}/png/oi9n2c16.png (100%) rename test/{res => _input}/png/pp0n2c16.png (100%) rename test/{res => _input}/png/pp0n6a08.png (100%) rename test/{res => _input}/png/ps1n0g08.png (100%) rename test/{res => _input}/png/ps1n2c16.png (100%) rename test/{res => _input}/png/ps2n0g08.png (100%) rename test/{res => _input}/png/ps2n2c16.png (100%) rename test/{res => _input}/png/s01n3p01.png (100%) rename test/{res => _input}/png/s02n3p01.png (100%) rename test/{res => _input}/png/s03n3p01.png (100%) rename test/{res => _input}/png/s04n3p01.png (100%) rename test/{res => _input}/png/s05i3p02.png (100%) rename test/{res => _input}/png/s05n3p02.png (100%) rename test/{res => _input}/png/s06i3p02.png (100%) rename test/{res => _input}/png/s06n3p02.png (100%) rename test/{res => _input}/png/s07i3p02.png (100%) rename test/{res => _input}/png/s07n3p02.png (100%) rename test/{res => _input}/png/s08i3p02.png (100%) rename test/{res => _input}/png/s08n3p02.png (100%) rename test/{res => _input}/png/s09i3p02.png (100%) rename test/{res => _input}/png/s09n3p02.png (100%) rename test/{res => _input}/png/s32i3p04.png (100%) rename test/{res => _input}/png/s32n3p04.png (100%) rename test/{res => _input}/png/s33i3p04.png (100%) rename test/{res => _input}/png/s33n3p04.png (100%) rename test/{res => _input}/png/s34i3p04.png (100%) rename test/{res => _input}/png/s34n3p04.png (100%) rename test/{res => _input}/png/s35i3p04.png (100%) rename test/{res => _input}/png/s35n3p04.png (100%) rename test/{res => _input}/png/s36i3p04.png (100%) rename test/{res => _input}/png/s36n3p04.png (100%) rename test/{res => _input}/png/s37i3p04.png (100%) rename test/{res => _input}/png/s37n3p04.png (100%) rename test/{res => _input}/png/s38i3p04.png (100%) rename test/{res => _input}/png/s38n3p04.png (100%) rename test/{res => _input}/png/s39i3p04.png (100%) rename test/{res => _input}/png/s39n3p04.png (100%) rename test/{res => _input}/png/s40i3p04.png (100%) rename test/{res => _input}/png/s40n3p04.png (100%) rename test/{res => _input}/png/small.png (100%) rename test/{res => _input}/png/tbbn0g04.png (100%) rename test/{res => _input}/png/tbbn2c16.png (100%) rename test/{res => _input}/png/tbbn3p08.png (100%) rename test/{res => _input}/png/tbgn2c16.png (100%) rename test/{res => _input}/png/tbgn3p08.png (100%) rename test/{res => _input}/png/tbrn2c08.png (100%) rename test/{res => _input}/png/tbwn0g16.png (100%) rename test/{res => _input}/png/tbwn3p08.png (100%) rename test/{res => _input}/png/tbyn3p08.png (100%) create mode 100644 test/_input/png/test.png rename test/{res => _input}/png/tm3n3p02.png (100%) rename test/{res => _input}/png/tp0n0g08.png (100%) rename test/{res => _input}/png/tp0n2c08.png (100%) rename test/{res => _input}/png/tp0n3p08.png (100%) rename test/{res => _input}/png/tp1n3p08.png (100%) create mode 100644 test/_input/png/trim.png rename test/{res => _input}/png/xc1n0g08.png (100%) rename test/{res => _input}/png/xc9n2c08.png (100%) rename test/{res => _input}/png/xcrn0g04.png (100%) rename test/{res => _input}/png/xcsn0g01.png (100%) rename test/{res => _input}/png/xd0n2c08.png (100%) rename test/{res => _input}/png/xd3n2c08.png (100%) rename test/{res => _input}/png/xd9n2c08.png (100%) rename test/{res => _input}/png/xdtn0g01.png (100%) rename test/{res => _input}/png/xhdn0g08.png (100%) rename test/{res => _input}/png/xlfn0g04.png (100%) rename test/{res => _input}/png/xs1n0g01.png (100%) rename test/{res => _input}/png/xs2n0g01.png (100%) rename test/{res => _input}/png/xs4n0g01.png (100%) rename test/{res => _input}/png/xs7n0g01.png (100%) rename test/{res => _input}/png/z00n2c08.png (100%) rename test/{res => _input}/png/z03n2c08.png (100%) rename test/{res => _input}/png/z06n2c08.png (100%) rename test/{res => _input}/png/z09n2c08.png (100%) create mode 100644 test/_input/tga/buck_16.tga create mode 100644 test/_input/tga/buck_16_rle.tga create mode 100644 test/_input/tga/buck_24.tga create mode 100644 test/_input/tga/buck_24_rle.tga create mode 100644 test/_input/tga/buck_32.tga create mode 100644 test/_input/tga/buck_32_rle.tga create mode 100644 test/_input/tga/buck_8p.tga rename test/{res => _input}/tga/globe.tga (100%) rename test/{res => _input}/tiff/aspect32float.tif (100%) rename test/{res => _input}/tiff/bitonal_lzw.tif (100%) rename test/{res => _input}/tiff/bitonal_none.tif (100%) rename test/{res => _input}/tiff/bitonal_zip.tif (100%) rename test/{res => _input}/tiff/ccitt_t4_1d_fill.tif (100%) rename test/{res => _input}/tiff/ccitt_t4_2d_fill.tif (100%) rename test/{res => _input}/tiff/ccitt_t4_2d_nofill.tif (100%) rename test/{res => _input}/tiff/ccitt_t6.tif (100%) rename test/{res => _input}/tiff/ccittt_t4_1d_nofill.tif (100%) rename test/{res => _input}/tiff/cmyk.tif (100%) rename test/{res => _input}/tiff/dtm32float.tif (100%) rename test/{res => _input}/tiff/dtm64float.tif (100%) rename test/{res => _input}/tiff/dtm_test.tif (100%) rename test/{res => _input}/tiff/float16.tif (100%) rename test/{res => _input}/tiff/float1x32.tif (100%) rename test/{res => _input}/tiff/float32.tif (100%) rename test/{res => _input}/tiff/flow16int.tif (100%) rename test/{res => _input}/tiff/globe.tif (100%) rename test/{res => _input}/tiff/lzw_strips.tif (100%) rename test/{res => _input}/tiff/lzw_tiled.tif (100%) create mode 100644 test/_input/tiff/palette_ps.tif rename test/{res => _input}/tiff/small.tif (100%) rename test/{res => _input}/tiff/tca32int.tif (100%) create mode 100644 test/_utils/file-info.ts create mode 100644 test/_utils/image-test-utils.ts create mode 100644 test/_utils/test-folder.ts create mode 100644 test/_utils/test-section.ts rename test/{test-helpers.ts => _utils/test-utils.ts} (83%) delete mode 100644 test/bmp.test.ts create mode 100644 test/color/color.float16.test.ts create mode 100644 test/color/color.float32.test.ts create mode 100644 test/color/color.float64.test.ts create mode 100644 test/color/color.int16.test.ts create mode 100644 test/color/color.int32.test.ts create mode 100644 test/color/color.int8.test.ts create mode 100644 test/color/color.uint1.test.ts create mode 100644 test/color/color.uint16.test.ts create mode 100644 test/color/color.uint2.test.ts create mode 100644 test/color/color.uint32.test.ts create mode 100644 test/color/color.uint4.test.ts create mode 100644 test/color/color.uint8.test.ts delete mode 100644 test/draw.test.ts create mode 100644 test/draw/draw.composite-image.test.ts create mode 100644 test/draw/draw.draw-circle.test.ts create mode 100644 test/draw/draw.draw-line.test.ts create mode 100644 test/draw/draw.draw-pixel.test.ts create mode 100644 test/draw/draw.draw-polygon.test.ts create mode 100644 test/draw/draw.draw-rect.test.ts create mode 100644 test/draw/draw.fill-circle.test.ts create mode 100644 test/draw/draw.fill-flood.test.ts create mode 100644 test/draw/draw.fill-polygon.test.ts create mode 100644 test/draw/draw.fill-rect.test.ts create mode 100644 test/draw/draw.fill.test.ts delete mode 100644 test/exif.test.ts create mode 100644 test/exif/exif.base.test.ts delete mode 100644 test/filter.test.ts create mode 100644 test/filter/filter.adjust-color.test.ts create mode 100644 test/filter/filter.billboard.test.ts create mode 100644 test/filter/filter.bleach-bypass.test.ts create mode 100644 test/filter/filter.bulge-distortion.test.ts create mode 100644 test/filter/filter.bump-to-normal.test.ts create mode 100644 test/filter/filter.chromatic-aberration.test.ts create mode 100644 test/filter/filter.color-halftone.test.ts create mode 100644 test/filter/filter.color-offset.test.ts create mode 100644 test/filter/filter.contrast.test.ts create mode 100644 test/filter/filter.convolution.test.ts create mode 100644 test/filter/filter.copy-image-channel.test.ts create mode 100644 test/filter/filter.dither-image.test.ts create mode 100644 test/filter/filter.dot-screen.test.ts create mode 100644 test/filter/filter.drop-shadow.test.ts create mode 100644 test/filter/filter.edge-glow.test.ts create mode 100644 test/filter/filter.emboss.test.ts create mode 100644 test/filter/filter.gamma.test.ts create mode 100644 test/filter/filter.gaussian-blur.test.ts create mode 100644 test/filter/filter.grayscale.test.ts create mode 100644 test/filter/filter.hexagon-pixelate.test.ts create mode 100644 test/filter/filter.invert.test.ts create mode 100644 test/filter/filter.luminance-threshold.test.ts create mode 100644 test/filter/filter.monochrome.test.ts create mode 100644 test/filter/filter.noise.test.ts create mode 100644 test/filter/filter.normalize.test.ts create mode 100644 test/filter/filter.pixelate.test.ts create mode 100644 test/filter/filter.quantize.test.ts create mode 100644 test/filter/filter.remap-colors.test.ts create mode 100644 test/filter/filter.scale-rgba.test.ts create mode 100644 test/filter/filter.separable-convolution.test.ts create mode 100644 test/filter/filter.sepia.test.ts create mode 100644 test/filter/filter.sketch.test.ts create mode 100644 test/filter/filter.smooth.test.ts create mode 100644 test/filter/filter.sobel.test.ts create mode 100644 test/filter/filter.stretch-distortion.test.ts create mode 100644 test/filter/filter.vignette.test.ts create mode 100644 test/format/format.bmp.test.ts create mode 100644 test/format/format.gif.test.ts create mode 100644 test/format/format.ico.test.ts create mode 100644 test/format/format.jpeg.test.ts create mode 100644 test/format/format.png.test.ts create mode 100644 test/format/format.tga.test.ts create mode 100644 test/format/format.tiff.test.ts delete mode 100644 test/gif.test.ts delete mode 100644 test/ico.test.ts create mode 100644 test/image/image.base.test.ts create mode 100644 test/image/image.float16.test.ts create mode 100644 test/image/image.float32.test.ts create mode 100644 test/image/image.float64.test.ts create mode 100644 test/image/image.int16.test.ts create mode 100644 test/image/image.int32.test.ts create mode 100644 test/image/image.int8.test.ts create mode 100644 test/image/image.uint1.test.ts create mode 100644 test/image/image.uint16.test.ts create mode 100644 test/image/image.uint2.test.ts create mode 100644 test/image/image.uint32.test.ts create mode 100644 test/image/image.uint4.test.ts create mode 100644 test/image/image.uint8.test.ts delete mode 100644 test/jpeg.test.ts delete mode 100644 test/png.test.ts delete mode 100644 test/res/.DS_Store delete mode 100644 test/res/filter/test.png delete mode 100644 test/res/ico/man.ico delete mode 100644 test/res/ico/woman.ico delete mode 100644 test/res/png/decode.png delete mode 100644 test/res/png/trim.png delete mode 100644 test/tga.test.ts delete mode 100644 test/tiff.test.ts create mode 100644 test/transform/transform.copy-crop-circle.test.ts create mode 100644 test/transform/transform.copy-crop.test.ts create mode 100644 test/transform/transform.copy-flip.test.ts create mode 100644 test/transform/transform.copy-rectify.test.ts create mode 100644 test/transform/transform.copy-resize-crop-square.test.ts create mode 100644 test/transform/transform.copy-resize.test.ts create mode 100644 test/transform/transform.copy-rotate.test.ts create mode 100644 test/transform/transform.trim.test.ts create mode 100644 tsconfig.build.json diff --git a/.eslintrc.json b/.eslintrc.json index c68e522..c64bec5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -176,7 +176,8 @@ "error", { "allow": [ - "methods" + "methods", + "setters" ] } ], diff --git a/.gitignore b/.gitignore index 242e7a8..107b139 100644 --- a/.gitignore +++ b/.gitignore @@ -135,4 +135,5 @@ dist ############################################################################# lib/ -test/out/ \ No newline at end of file +test/_built/ +test/_output/ \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index dc3e243..2948322 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,9 +1,9 @@ { - "files.eol": "\n", "editor.tabSize": 2, "editor.insertSpaces": true, "editor.detectIndentation": false, "editor.codeActionsOnSave": { "source.fixAll.eslint": true - } + }, + "files.eol": "\n", } \ No newline at end of file diff --git a/README.md b/README.md index 4a840e7..6b64463 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,18 @@ Table of contents ================= -* [Overview](#overview) -* [Performance Warning](#performance-warning) -* [Supported Image Formats](#supported-image-formats) -* [Example](#example) -* [Format Decoding Functions](#format-decoding-functions) - * [Generic Decoding Functions](#generic-decoding-functions) - * [Format-Specific Decoding Functions](#format-specific-decoding-functions) -* [Format Encoding Functions](#format-encoding-functions) - * [Generic Encoding Functions](#generic-encoding-functions) - * [Format-Specific Encoding Functions](#format-specific-encoding-functions) -* [Image Filter Functions](#image-filter-functions) -* [Image Transform Functions](#image-transform-functions) -* [Drawing Functions](#drawing-functions) -* [Contributing](#contributing) -* [Links](#links) +- [Table of contents](#table-of-contents) +- [Overview](#overview) +- [Performance Warning](#performance-warning) +- [Supported Image Formats](#supported-image-formats) +- [Documentation](#documentation) +- [Contributing](#contributing) +- [Links](#links) Overview ======== -**image-in-browser** is an NPM package providing the ability to load, save and manipulate images of different file formats. +**image-in-browser** is an NPM package providing the ability to load, manipulate and save images of various image file formats. - works both in Node.js and in the browser (no need for server-side Node.js) - written entirely in Typescript with transpiling into Javascript @@ -47,936 +39,10 @@ The following formats are currently supported for encoding / decoding: - TGA, - TIFF -Example -======= - -This example demonstrates sample use cases for the library: -- load a PNG file, -- reduce its size, -- apply a vignette filter, -- save it as an ICO file - -```ts -import { readFileSync, writeFileSync } from 'fs'; - - -function createThumbnail() { - const input = readFileSync('test.png'); - - // decoding PNG bytes to MemoryImage - const image = decodePng(input); - if (image !== undefined) { - - // making resized thumbnail - const thumbnail = ImageTransform.copyResize({ - image: image, - width: 150, - }); - - // applying vignette filter - ImageFilter.vignette({ - src: thumbnail, - }); - - // encoding MemoryImage to ICO bytes - const output = encodeIco(thumbnail); - - writeFileSync('thumbnail.ico', output); - } -} -``` - -Format Decoding Functions -========================= - -Decoding is the process by which the byte content of an image file is converted into an object of type MemoryImage in RAM. - -The following functions provide a high level interface for decoding images. You can also use the format specific Decoder classes to access format-specific data. - -> ℹ️ These methods take input of type `TypedArray`, which is short union of types: `Int8Array` | `Int16Array` | `Int32Array` | `Uint8Array` | `Uint16Array` | `Uint32Array` | `Float32Array` | `Float64Array`. - -## Generic Decoding Functions - -> ⚠️ Because these functions have to determine the format of the image before they can decode it, it is preferable to use a format specific decoding function, such as `decodeJpg`, if you know what the format is. - ---- -```ts -decodeImage(data: TypedArray): MemoryImage | undefined -``` - -Decode an image, determining the format of the file by analyzing the bytes. If the file is an animated image, the first frame is decoded. - -**Parameters**: -- **data**: The content of the image file of type `TypedArray`. - -**Returns:** the decoded `MemoryImage` or `undefined` if the data cannot be decoded. - ---- -```ts -decodeAnimation(data: TypedArray): FrameAnimation | undefined -``` - -Decode a potentially animated image, determining the format of the file by analyzing the bytes. If the image isn't animated (a JPEG image, a non-animated GIF, etc), the returned `FrameAnimation` will contain a single frame containing the decoded image. - -**Parameters**: -- **data**: The content of the image file of type `TypedArray`. - -**Returns:** the decoded `FrameAnimation` or `undefined` if the data cannot be decoded. - ---- -```ts -decodeNamedImage(data: TypedArray, name: string): MemoryImage | undefined -``` - -Identify the format of the image using the file extension provided by `name`, and decode it with the appropriate decoder. For example, `decodeNamedImage(imageData, 'image.jpg')` will decode the image as a JPEG. - -**Parameters**: -- **data**: The content of the image file of type `TypedArray`. -- **data**: The name of the file (used to identify format from the file extension). - -**Returns:** the decoded `MemoryImage` or `undefined` if the data cannot be decoded. - ---- -```ts -findDecoderForData(data: TypedArray): Decoder | undefined -``` - -Returns the Decoder that can decode the given image data. - -**Parameters**: -- **data**: The content of the image file of type `TypedArray`. - -**Returns:** the `Decoder` that can decode the given image data or `undefined` if no matching decoder is found. - -## Format-Specific Decoding Functions - ---- -```ts -decodeBmp(data: TypedArray): MemoryImage | undefined -``` -Decode a BMP formatted image. - -**Parameters**: -- **data**: The contents of the BMP file of type `TypedArray`. - -**Returns:** the decoded `MemoryImage` or `undefined` if the data cannot be decoded. - ---- -```ts -decodeGif(data: TypedArray): MemoryImage | undefined -``` -Decode a GIF formatted image. If the GIF is animated, the first frame is returned. - -**Parameters**: -- **data**: The contents of the GIF file of type `TypedArray`. - -**Returns:** the decoded `MemoryImage` or `undefined` if the data cannot be decoded. - ---- -```ts -decodeGifAnimation(data: TypedArray): FrameAnimation | undefined -``` -Decode an animated GIF file. If the GIF isn't animated, the animation will contain a single frame. - -**Parameters**: -- **data**: The contents of the GIF file of type `TypedArray`. - -**Returns:** the decoded `FrameAnimation` or `undefined` if the data cannot be decoded. - ---- -```ts -decodeIco(data: TypedArray): MemoryImage | undefined -``` -Decode an ICO formatted image. - -**Parameters**: -- **data**: The contents of the ICO file of type `TypedArray`. - -**Returns:** the decoded `MemoryImage` or `undefined` if the data cannot be decoded. - ---- -```ts -decodeJpg(data: TypedArray): MemoryImage | undefined -``` -Decode a JPEG formatted image. - -**Parameters**: -- **data**: The contents of the JPEG file of type `TypedArray`. - -**Returns:** the decoded `MemoryImage` or `undefined` if the data cannot be decoded. - ---- -```ts -decodePng(data: TypedArray): MemoryImage | undefined -``` -Decode a PNG formatted image. If the PNG is animated, the first frame is decoded. - -**Parameters**: -- **data**: The contents of the PNG file of type `TypedArray`. - -**Returns:** the decoded `MemoryImage` or `undefined` if the data cannot be decoded. - ---- -```ts -decodePngAnimation(data: TypedArray): FrameAnimation | undefined -``` -Decode a PNG formatted animation. If the PNG isn't animated, the animation will contain a single frame. - -**Parameters**: -- **data**: The contents of the PNG file of type `TypedArray`. - -**Returns:** the decoded `FrameAnimation` or `undefined` if the data cannot be decoded. - ---- -```ts -decodeTga(data: TypedArray): MemoryImage | undefined -``` -Decode a TGA (Targa) formatted image. - -**Parameters**: -- **data**: The contents of the TGA file of type `TypedArray`. - -**Returns:** the decoded `MemoryImage` or `undefined` if the data cannot be decoded. - ---- -```ts -decodeTiff(data: TypedArray): MemoryImage | undefined -``` -Decode a TIFF formatted image. - -**Parameters**: -- **data**: The contents of the TIFF file of type `TypedArray`. - -**Returns:** the decoded `MemoryImage` or `undefined` if the data cannot be decoded. - ---- -```ts -decodeTiffAnimation(data: TypedArray): FrameAnimation | undefined -``` -Decode a multi-image TIFF file. If the TIFF doesn't have multiple images, the animation will contain a single image. - -**Parameters**: -- **data**: The contents of the TIFF file of type `TypedArray`. - -**Returns:** the decoded `FrameAnimation` or `undefined` if the data cannot be decoded. - -Format Encoding Functions -========================= - -Encoding is the process by which the object of type MemoryImage is converted into the byte content of an image file. - -The following functions provide a high level interface for encoding images. You can also use the format specific Encoder classes to access format-specific data. - -## Generic Encoding Functions - ---- -```ts -encodeNamedImage(image: MemoryImage, name: string): Uint8Array | undefined -``` -Identify the format of the image and encode it with the appropriate encoder. - -**Parameters**: -- **image**: the `MemoryImage` to encode. -- **name**: The name of the image, used to derive the format to encode with from the extension. -Returns: the encoded bytes. - -**Returns:** the encoded bytes of type `Uint8Array` or `undefined` if no matching encoder is found. - -## Format-Specific Encoding Functions - ---- -```ts -encodeBmp(image: MemoryImage): Uint8Array -``` -Encode an image with the BMP format. - -**Parameters**: -- **image**: the `MemoryImage` to encode. - -**Returns:** the encoded bytes of type `Uint8Array`. - ---- -```ts -encodeGif(image: MemoryImage, samplingFactor = 10): Uint8Array -``` -Encode an image with the GIF format. - -**Parameters**: -- **image**: the `MemoryImage` to encode. -- (optional) **samplingFactor**: the sampling factor for image quantization, it is responsible for reducing the amount of unique colors in your images to 256. The default is **10**. - -**Returns:** the encoded bytes of type `Uint8Array`. - ---- -```ts -encodeGifAnimation(animation: FrameAnimation, samplingFactor = 10): Uint8Array | undefined -``` -Encode an animation with the animated GIF format. - -**Parameters**: -- **animation**: the `FrameAnimation` to encode. -- (optional) **samplingFactor**: the sampling factor for image quantization, it is responsible for reducing the amount of unique colors in your images to 256. The default is **10**. - -**Returns:** the encoded bytes of type `Uint8Array` or `undefined` if the animation cannot be encoded. - ---- -```ts -encodeIco(image: MemoryImage): Uint8Array -``` -Encode an image with the ICO format. - -**Parameters**: -- **image**: the `MemoryImage` to encode. - -**Returns:** the encoded bytes of type `Uint8Array`. - ---- -```ts -encodeJpg(image: MemoryImage, quality = 100): Uint8Array -``` -Encode an image with the JPEG format. - -**Parameters**: -- **image**: the `MemoryImage` to encode. -- (optional) **quality**: the JPEG quality, in the range [**0**, **100**] where **100** is highest quality. Default is **100**. - -**Returns:** the encoded bytes of type `Uint8Array`. - ---- -```ts -encodePng(image: MemoryImage, level: CompressionLevel = 6): Uint8Array -``` -Encode an image with the PNG format. - -**Parameters**: -- **image**: the `MemoryImage` to encode. -- (optional) **level**: the compression level, in the range [**0**, **9**] where **9** is the most compressed. Default is **6**. - -**Returns:** the encoded bytes of type `Uint8Array`. - ---- -```ts -encodePngAnimation(animation: FrameAnimation, level: CompressionLevel = 6): Uint8Array | undefined -``` -Encode an animation with the animated PNG format. - -**Parameters**: -- **animation**: the `FrameAnimation` to encode. -- (optional) **level**: the compression level, in the range [**0**, **9**] where **9** is the most compressed. Default is **6**. - -**Returns:** the encoded bytes of type `Uint8Array` or `undefined` if the animation cannot be encoded. - ---- -```ts -encodeTga(image: MemoryImage): Uint8Array -``` -Encode an image with the TGA (Targa) format. - -**Parameters**: -- **image**: the `MemoryImage` to encode. - -**Returns:** the encoded bytes of type `Uint8Array`. - ---- -```ts -encodeTiff(image: MemoryImage): Uint8Array -``` -Encode an image with the TIFF format. - -**Parameters**: -- **image**: the `MemoryImage` to encode. - -**Returns:** the encoded bytes of type `Uint8Array`. - -Image Filter Functions -====================== - -These functions modify images in place and return that image to make merging functions easier. -Image filters can be applied using the static methods of the `ImageFilter` abstract class. - ---- -```ts -ImageFilter.adjustColor(options: AdjustColorOptions): MemoryImage -``` -Adjust the color of the `options.src` image using various color transformations (in place). - -**Parameters** (from **options**): -- **src**: the `MemoryImage` to modify. -- **blacks**: defines the black level of the image, as a color. -- **whites**: defines the white level of the image, as a color. -- **mids**: defines the mid level of hte image, as a color. -- **contrast**: increases (>1) / decreases (<1) the contrast of the image by pushing colors away/toward neutral gray, where at 0 the image is entirely neutral gray (0 contrast), 1 - the image is not adjusted and >1 the image increases contrast. -- **saturation**: scale the saturation of the image, where saturation 1 is the fully saturated color and saturation 0 is fully unsaturated (grayscale) color. -- **brightness**: a linear multiplier for the RGB color values, brightens (>1) or dims (<0) the image. Default is **1**. -- **exposure**: an exponential multiplier for the RGB color values, as RGB *= pow(2, exposure). Default is **0**. -- **gamma**: an exponential multiplier for the RGB color values, as RGB = pow(RGB, gamma). A gamma >1 darkens the image, and gamma <1 brightens the image. Default is **1**. -- **hue**: offset the hue of the image, specified in degrees in the range [**0**, **360**]. Default is **0**. -- **amount**: the strength that this filter is applied to the image, where 1 indicates the filter has full effect, and 0 has no effect (the original image is returned unmodified). Default is **1**. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.brightness(src: MemoryImage, brightness: number): MemoryImage -``` -Adjust the brightness of the image (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify. -- **brightness**: an offset that is added to the red, green, and blue channels of every pixel. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.bumpToNormal(src: MemoryImage, strength = 2): MemoryImage -``` -Generate a normal map from a height-field bump image (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify. -- (optional) **strength**: the strength of the normal image. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.colorOffset(options: ColorOffsetOptions): MemoryImage -``` -Apply an offset to the colors of the image (in place). - -**Parameters** (from **options**): -- **src**: the `MemoryImage` to modify. -- (optional) **r**: offset for the red channel. Default is 0. -- (optional) **g**: offset for the green channel. Default is 0. -- (optional) **b**: offset for the blue channel. Default is 0. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.contrast(src: MemoryImage, contrast: number): MemoryImage -``` -Apply an offset to the colors of the image (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify. -- **contrast**: value below **100** will decrees the contrast of the image, and values above **100** will increase the contrast. A contrast of **100** will have no affect. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.convolution(options: ConvolutionOptions): MemoryImage -``` -Apply a 3x3 convolution filter to the image (in place). - -**Parameters** (from **options**): -- **src**: the `MemoryImage` to modify. -- **filter**: convolution filter coefficients (9 items). -- (options) **div**: the coefficient by which each value will be divided. Default is **1**. -- (options) **offset**: the offset that will be added to each result. Default is **0**. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.emboss(src: MemoryImage): MemoryImage -``` -Apply an emboss convolution filter (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.gaussianBlur(src: MemoryImage, radius: number): MemoryImage -``` -Blur the image (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify. -- **radius**: how many pixels away from the current pixel should contribute to the blur, where 0 is no blur and the larger the radius, the stronger the blur. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.grayscale(src: MemoryImage): MemoryImage -``` -Convert the colors of the image to grayscale (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.invert(src: MemoryImage): MemoryImage -``` -Invert the colors of the image (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.noise(image: MemoryImage, sigma: number, type: NoiseType = NoiseType.gaussian): MemoryImage -``` -Add random noise to pixel values (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify. -- **sigma**: how strong the effect should be. -- (optional) **type**: the noise type. Default is `NoiseType.gaussian`. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.normalize(src: MemoryImage, minValue: number, maxValue: number): MemoryImage -``` -Linearly normalize the pixel values of the image (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify. -- **minValue**: min value of the range of normalizing. -- **maxValue**: max value of the range of normalizing. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.pixelate(src: MemoryImage, blockSize: number, mode: PixelateMode = PixelateMode.upperLeft): MemoryImage -``` -Pixelate the image (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify. -- **blockSize**: the size of the pixelated blocks. -- (optional) **mode**: if is `PixelateMode.upperLeft` then the upper-left corner of the block will be used for the block color, if `mode` is `PixelateMode.average`, the average of all the pixels in the block will be used for the block color. Default is `PixelateMode.upperLeft`. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.quantize(options: QuantizeOptions): MemoryImage -``` -Reduces the number of colors in the image to the given amount (in place). - -**Parameters** (from **options**): -- **src**: the `MemoryImage` to modify. -- (optional) **numberOfColors**: the number of colors. -- (optional) **method**: quantization method. Default is `QuantizeMethod.neuralNet`. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.remapColors(options: RemapColorsOptions): MemoryImage -``` -Remap the color channels of the image. **red**, **green**, **blue** and **alpha** should be set to one of the following: `Channel.red`, `Channel.green`, `Channel.blue`, `Channel.alpha`, or `Channel.luminance`. For example, `remapColors({ src: src, red: Channel.green, green: Channel.red })` will swap the red and green channels of the image. `remapColors({ src: src, alpha: Channel.luminance })` will set the alpha channel to the luminance (grayscale) of the image (in place). - -**Parameters** (from **options**): -- **src**: the `MemoryImage` to modify. -- (optional) **red**: which channel we should remap the **red** channel to. -- (optional) **green**: which channel we should remap the **green** channel to. -- (optional) **blue**: which channel we should remap the **blue** channel to. -- (optional) **alpha**: which channel we should remap the **alpha** channel to. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.scaleRgba(src: MemoryImage, r: number, g: number, b: number, a: number): MemoryImage -``` -Scales the image channels by a specified number (divided by 255) (in place). - -**Parameters** (from **options**): -- **src**: the `MemoryImage` to modify. -- **r**: the amount by which the **red** channel will be changed (after dividing by 255). -- **g**: the amount by which the **green** channel will be changed (after dividing by 255). -- **b**: the amount by which the **blue** channel will be changed (after dividing by 255). -- **a**: the amount by which the **alpha** channel will be changed (after dividing by 255). - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.separableConvolution(src: MemoryImage, kernel: SeparableKernel): MemoryImage -``` -Apply a generic separable convolution filter on the image, using the given separable kernel. -`ImageFilter.gaussianBlur()` is an example of such a filter (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify. -- **kernel**: separable kernel. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.sepia(src: MemoryImage, amount = 1): MemoryImage -``` -Filter the image colors using sepia tone (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify. -- (optional) **amount**: controls the strength of the effect, in the range **0**-**1**. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.smooth(src: MemoryImage, w: number): MemoryImage -``` -Filter the image colors using sepia tone (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify. -- **w**: the weight of the current pixel being filtered. If it's greater than **1**, it will make the image sharper. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.sobel(src: MemoryImage, amount = 1): MemoryImage -``` -Apply a sobel edge detection filter to the image (in place). - -**Parameters**: -- **src**: the `MemoryImage` to modify. -- **w**: the amount, in the range **0**-**1**. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageFilter.vignette(options: VignetteOptions): MemoryImage -``` -Darkens the edges of the image using a elliptical vignette filter (in place). - -**Parameters** (from **options**): -- **src**: the `MemoryImage` to modify. -- (optional) **start**: start edge of the filter. Default is **0.3**. -- (optional) **end**: end edge of the filter. Default is **0.75**. -- (optional) **amount**: filter intensity level. Default is **0.8**. - -**Returns:** the modified `MemoryImage`. - -Image Transform Functions -========================= - -Image transformations can be applied using the static methods of the `ImageTransform` abstract class. -Most image transformation functions work on a copy of the input image, returning the modified copy. Such functions are prefixed with `copy`. Those functions that do not have the `copy` prefix modify the image in place, returning a modified copy. - ---- -```ts -ImageTransform.bakeOrientation(image: MemoryImage): MemoryImage -``` -If **image** has an orientation value in its exif data, this function will rotate the image so that it physically matches its orientation. This can be used to bake the orientation of the image for image formats that don't support exif data. - -**Parameters**: -- **image**: `MemoryImage` source. - -**Returns:** the new `MemoryImage`. - ---- -```ts -ImageTransform.copyRotate(src: MemoryImage, angle: number, interpolation: Interpolation = Interpolation.nearest): MemoryImage -``` -Returns a copy of the image, rotated by `angle` degrees. - -**Parameters**: -- **src**: `MemoryImage` source. -- **angle**: the angle to rotate. -- (optional) **interpolation**: interpolation type. Default is `Interpolation.nearest`. - -**Returns:** the new `MemoryImage`. - ---- -```ts -ImageTransform.copyResize(options: CopyResizeOptionsUsingWidth | CopyResizeOptionsUsingHeight): MemoryImage -``` -Returns a resized copy of the image. - -**Parameters** (from **options**): -- **image**: `MemoryImage` source. -- (optional) **width**: the width of the resized image. -- (optional) **height**: the height of the resized image. -- (optional) **interpolation**: interpolation type. Default is `Interpolation.nearest`. - -**Returns:** the new `MemoryImage`. - ---- -```ts -ImageTransform.copyResizeCropSquare(src: MemoryImage, size: number): MemoryImage -``` -Returns a resized and square cropped copy of the image of specified size. - -**Parameters**: -- **src**: `MemoryImage` source. -- **size**: size of the cropped copy. - -**Returns:** the new `MemoryImage`. - ---- -```ts -ImageTransform.copyInto(options: CopyIntoOptions): MemoryImage -``` -Copy an area of the **src** image into **dst**. - -In other words, it will take an rectangular area from **src** of width **srcW** and height **srcH** at position (**srcX**,**srcY**) and place it in a rectangular area of **dst** of width **dstW** and height **dstH** at position (**dstX**,**dstY**). - -**Parameters** (from **options**): -- **dst**: `MemoryImage` destination. -- **src**: `MemoryImage` source. -- (optional) **dstX**: X coordinate of the destination image. Default is **0**. -- (optional) **dstY**: Y coordinate of the destination image. Default is **0**. -- (optional) **srcX**: X coordinate of the source image. Default is **0**. -- (optional) **srcY**: Y coordinate of the source image. Default is **0**. -- (optional) **srcW**: width of the rectangular to copy from source image. Default is `src.width`. -- (optional) **srcH**: height of the rectangular to copy from source image. Default is `src.height`. -- (optional) **blend**: whether to apply blending. Default is **true**. -- (optional) **center**: if it is true, the **src** will be centered in **dst**. Default is **false**. - -**Returns:** the new `MemoryImage`. - ---- -```ts -ImageTransform.copyCrop(src: MemoryImage, x: number, y: number, w: number, h: number): MemoryImage -``` -Create a cropped copy of the image. - -**Parameters**: -- **src**: `MemoryImage` source. -- **x**: X coordinate of the rectangle from source image. -- **y**: Y coordinate of the rectangle from source image. -- **w**: width of the cropped image. -- **h**: height of the cropped image. - -**Returns:** the new `MemoryImage`. - ---- -```ts -ImageTransform.copyCropCircle(src: MemoryImage, radius?: number, center?: Point): MemoryImage -``` -Returns a round cropped copy of the image. - -**Parameters**: -- **src**: `MemoryImage` source. -- (optional) **radius**: radius of the cropped area. Default is `Math.min(src.width, src.height)`. -- (optional) **center**: center point. Default is the center point of the **src**. - -**Returns:** the new `MemoryImage`. - ---- -```ts -ImageTransform.copyRectify(src: MemoryImage, rect: Rectangle, toImage?: MemoryImage): MemoryImage -``` -Returns a copy of the **src** image, where the given rectangle has been mapped to the full image. - -**Parameters**: -- **src**: `MemoryImage` source. -- **rect**: rectangle to map. -- (optional) **toImage**: the image in which to place the mapped area. Default is the image copied from **src**. - -**Returns:** the new `MemoryImage`. - ---- -```ts -ImageTransform.flip(src: MemoryImage, direction: FlipDirection): MemoryImage -``` -Flip the image using the given direction (in place). - -**Parameters**: -- **src**: `MemoryImage` source. -- **direction**: flip direction. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageTransform.flipVertical(src: MemoryImage): MemoryImage -``` -Flip the image vertically (in place). - -**Parameters**: -- **src**: `MemoryImage` source. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -ImageTransform.flipHorizontal(src: MemoryImage): MemoryImage -``` -Flip the image horizontally (in place). - -**Parameters**: -- **src**: `MemoryImage` source. - -**Returns:** the modified `MemoryImage`. - -Drawing Functions -================= - -These functions allow you to draw on images. -Drawing functions can be applied using the static methods of the `Draw` abstract class. - ---- -```ts -Draw.drawCircle(image: MemoryImage, center: Point, radius: number, color: number): MemoryImage -``` -Draw a circle (in place). - -**Parameters**: -- **image**: `MemoryImage` source. -- **center**: center point of a circle. -- **radius**: radius of a circle. -- **color**: color of a circle. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -Draw.fillCircle(image: MemoryImage, center: Point, radius: number, color: number): MemoryImage -``` -Draw and fill a circle (in place). - -**Parameters**: -- **image**: `MemoryImage` source. -- **center**: center point of a circle. -- **radius**: radius of a circle. -- **color**: color of a circle. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -Draw.drawImage(options: DrawImageOptions): MemoryImage -``` -Draw the image **src** onto the image **dst** (in place). - -In other words, drawImage will take an rectangular area from **src** of width **srcW** and height **srcH** at position (**srcX**,**srY**) and place it in a rectangular area of **dst** of width **dstW** and height **dstH** at position (**dstX**,**dstY**). - -**Parameters** (from **options**): -- **dst**: `MemoryImage` destination. -- **src**: `MemoryImage` source. -- (optional) **dstX**: X coordinate of the destination image. Default is **0**. -- (optional) **dstY**: Y coordinate of the destination image. Default is **0**. -- (optional) **dstW**: width of the rectangle on the destination image. Default is `Math.min(dst.width, src.width)`. -- (optional) **dstH**: height of the rectangle on the destination image. Default is `Math.min(dst.height, src.height)`. -- (optional) **srcX**: X coordinate of the source image. Default is **0**. -- (optional) **srcY**: Y coordinate of the source image. Default is **0**. -- (optional) **srcW**: width of the rectangular to copy from source image. Default is `src.width`. -- (optional) **srcH**: height of the rectangular to copy from source image. Default is `src.height`. -- (optional) **blend**: whether to apply blending. Default is **true**. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -Draw.drawLine(options: DrawLineOptions): MemoryImage -``` -Draw a line (in place). - -**Parameters** (from **options**): -- **image**: `MemoryImage` source. -- **line**: `Line` object with coordinates of the line. -- **color**: line color. -- (optional) **antialias**: if true, then the line is drawn with smooth edges. Default is **false**. -- (optional) **thickness**: determines how thick the line should be drawn, in pixels. Default is **1**. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -Draw.drawPixel(image: MemoryImage, pos: Point, color: number, opacity = 0xff): MemoryImage -``` -Draw a single pixel into the image, applying alpha and opacity blending (in place). - -**Parameters**: -- **image**: `MemoryImage` source. -- **pos**: coordinates of the point. -- **color**: pixel color. -- (optional) **opacity**: fraction of alpha blending. Default is **0xff** (fully opaque). - -**Returns:** the modified `MemoryImage`. - ---- -```ts -Draw.drawRect(dst: MemoryImage, rect: Rectangle, color: number): MemoryImage -``` -Draw a rectangle (in place). - -**Parameters**: -- **dst**: `MemoryImage` source. -- **rect**: rectangle coordinates to draw. -- **color**: rectangle color. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -Draw.fillRect(src: MemoryImage, rect: Rectangle, color: number): MemoryImage -``` -Fill a rectangle with the given color (in place). - -**Parameters**: -- **src**: `MemoryImage` source. -- **rect**: rectangle coordinates to draw. -- **color**: fill color. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -Draw.fillFlood(options: FillFloodOptions): MemoryImage -``` -Fill the 4-connected shape containing (**x**,**y**) in the image **src** with the given **color** (in place). - -**Parameters** (from **options**): -- **src**: `MemoryImage` source. -- **x**: the X coordinate of the point where the fill starts. -- **y**: the Y coordinate of the point where the fill starts. -- **color**: fill color. -- (optional) **threshold**: filling threshold. Default is **0**. -- (optional) **compareAlpha**: whether to take into account the alpha channel. Default is **false**. - -**Returns:** the modified `MemoryImage`. - ---- -```ts -Draw.maskFlood(options: MaskFloodOptions): Uint8Array -``` -Create a mask describing the 4-connected shape containing (**x**,**y**) in the image **src**. - -**Parameters** (from **options**): -- **src**: `MemoryImage` source. -- **x**: the X coordinate of the point where the fill starts. -- **y**: the Y coordinate of the point where the fill starts. -- (optional) **threshold**: filling threshold. Default is **0**. -- (optional) **compareAlpha**: whether to take into account the alpha channel. Default is **false**. -- (optional) **fillValue**: the value of the items corresponding to the filled area. Default is **255**. - -**Returns:** the mask of type `Uint8Array`. - ---- -```ts -Draw.fill(image: MemoryImage, color: number): MemoryImage -``` -Fill the entire image with the given color (in place). - -**Parameters**: -- **src**: `MemoryImage` source. -- **color**: fill color. +Documentation +============ -**Returns:** the modified `MemoryImage`. +To view the documentation for the package, please go to the [Wiki](https://github.com/yegor-pelykh/image-in-browser/wiki). Contributing ============ diff --git a/lib-compact/index.d.ts b/lib-compact/index.d.ts index 6d72011..df66c02 100644 --- a/lib-compact/index.d.ts +++ b/lib-compact/index.d.ts @@ -1,228 +1,19 @@ -declare module "common/frame-type" { - /** @format */ - export enum FrameType { - /** - * The frames of this document are to be interpreted as animation. - */ - animation = 0, - /** - * The frames of this document are to be interpreted as pages of a document. - */ - page = 1 - } -} -declare module "common/iccp-compression-mode" { - /** @format */ - export enum ICCPCompressionMode { - none = 0, - deflate = 1 - } -} -declare module "error/image-error" { - /** @format */ - /** - * An Error thrown when there was a problem in the image library. - */ - export class ImageError extends Error { - toString(): string; - } -} +/// declare module "common/typings" { /** @format */ export type TypedArray = Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Float32Array | Float64Array; export type BufferEncoding = 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'ucs2' | 'ucs-2' | 'base64' | 'latin1' | 'binary' | 'hex'; export type CompressionLevel = -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | undefined; } -declare module "common/array-utils" { - import { TypedArray } from "common/typings"; - export abstract class ArrayUtils { - static copyInt8(from: Int8Array, begin?: number, end?: number): Int8Array; - static copyUint8(from: Uint8Array, begin?: number, end?: number): Uint8Array; - static copyInt16(from: Int16Array, begin?: number, end?: number): Int16Array; - static copyUint16(from: Uint16Array, begin?: number, end?: number): Uint16Array; - static copyInt32(from: Int32Array, begin?: number, end?: number): Int32Array; - static copyUint32(from: Uint32Array, begin?: number, end?: number): Uint32Array; - static copyFloat32(from: Float32Array, begin?: number, end?: number): Float32Array; - static copyFloat64(from: Float64Array, begin?: number, end?: number): Float64Array; - static copy(from: TypedArray, begin?: number, end?: number): TypedArray; - static setRange(to: T, start: number, end: number, from: T, skipCount?: number): void; - } -} -declare module "common/icc-profile-data" { - import { ICCPCompressionMode } from "common/iccp-compression-mode"; - /** - * ICC Profile data stored with an image. - */ - export class ICCProfileData { - private _name; - get name(): string; - private _compression; - get compression(): ICCPCompressionMode; - private _data; - get data(): Uint8Array; - constructor(name: string, compression: ICCPCompressionMode, data: Uint8Array); - static from(other: ICCProfileData): ICCProfileData; - /** - * Returns the compressed data of the ICC Profile, compressing the stored data as necessary. - */ - compressed(): Uint8Array; - /** - * Returns the uncompressed data of the ICC Profile, decompressing the stored data as necessary. - */ - decompressed(): Uint8Array; - } -} -declare module "common/rgb-channel-set" { - /** @format */ - export enum RgbChannelSet { - rgb = 0, - rgba = 1 - } -} -declare module "common/dispose-mode" { - /** @format */ - export enum DisposeMode { - /** - * When drawing a frame, the canvas should be left as it is. - */ - none = 0, - /** - * When drawing a frame, the canvas should be cleared first. - */ - clear = 1, - /** - * When drawing this frame, the canvas should be reverted to how it was before drawing it. - */ - previous = 2 - } -} -declare module "common/blend-mode" { - /** @format */ - export enum BlendMode { - /** - * No alpha blending should be done when drawing this frame (replace pixels in canvas). - */ - source = 0, - /** - * * Alpha blending should be used when drawing this frame (composited over - * the current canvas image). - */ - over = 1 - } -} -declare module "common/color-model" { - /** @format */ - export enum ColorModel { - argb = 0, - abgr = 1, - rgba = 2, - bgra = 3, - rgb = 4, - bgr = 5, - luminance = 6 - } -} -declare module "common/interpolation" { - /** @format */ - export enum Interpolation { - nearest = 0, - linear = 1, - cubic = 2, - average = 3 - } -} -declare module "common/bit-operators" { - /** @format */ - export abstract class BitOperators { - private static readonly uint8arr; - private static readonly uint8ToInt8arr; - private static readonly int8arr; - private static readonly int8ToUint8arr; - private static readonly uint16arr; - private static readonly uint16ToInt16arr; - private static readonly int16arr; - private static readonly int16ToUint16arr; - private static readonly uint32arr; - private static readonly uint32ToInt32arr; - private static readonly int32arr; - private static readonly int32ToUint32arr; - private static readonly uint32ToFloat32arr; - private static readonly uint64arr; - private static readonly uint64ToFloat64arr; - static signed(bits: number, value: number): number; - static shiftR(v: number, n: number): number; - static shiftL(v: number, n: number): number; - /** - * Binary conversion to an int8. This is equivalent in C to - * typecasting to a char. - */ - static toInt8(d: number): number; - /** - * Binary conversion to an uint8. This is equivalent in C to - * typecasting to an unsigned char. - */ - static toUint8(d: number): number; - /** - * Binary conversion to an int16. This is equivalent in C to - * typecasting to a short. - */ - static toInt16(d: number): number; - /** - * Binary conversion to an uint16. This is equivalent in C to - * typecasting to an unsigned short. - */ - static toUint16(d: number): number; - /** - * Binary conversion to an int32. This is equivalent in C to - * typecasting to signed int. - */ - static toInt32(d: number): number; - /** - * Binary conversion of an int32 to a uint32. This is equivalent in C to - * typecasting to unsigned int. - */ - static toUint32(d: number): number; - /** - * Binary conversion to a float32. This is equivalent in C to - * typecasting to float. - */ - static toFloat32(d: number): number; - /** - * Binary conversion to a float64. This is equivalent in C to - * typecasting to double. - */ - static toFloat64(d: bigint): number; - static debugBits32(value?: number): string; - } -} -declare module "common/color-channel" { - /** @format */ - export enum ColorChannel { - /** - * Red channel of a color. - */ - red = 0, - /** - * Green channel of a color. - */ - green = 1, - /** - * Blue channel of a color. - */ - blue = 2, - /** - * Alpha channel of a color. - */ - alpha = 3, - /** - * Luminance (brightness) of a color. - */ - luminance = 4 - } -} -declare module "common/math-operators" { +declare module "common/math-utils" { /** @format */ - export abstract class MathOperators { + export abstract class MathUtils { + static fract(x: number): number; + static smoothStep(edge0: number, edge1: number, x: number): number; + static mix(x: number, y: number, a: number): number; + static sign(x: number): number; + static step(edge: number, x: number): number; + static length3(x: number, y: number, z: number): number; /** * Returns the greatest common divisor of **x** and **y**. */ @@ -232,175 +23,139 @@ declare module "common/math-operators" { */ static clamp(num: number, low: number, high: number): number; /** - * Clamp **num** to [**a**, **b**] and truncate + * Clamp **num** to [**low**, **high**] and truncate */ static clampInt(num: number, low: number, high: number): number; /** - * Clamp **num** to [**0**, **255**] + * Clamp **num** to [0, 255] and truncate */ static clampInt255(num: number): number; } } -declare module "common/color" { - import { ColorChannel } from "common/color-channel"; +declare module "error/lib-error" { + /** @format */ /** - * Image pixel colors are instantiated as an int object rather than an instance - * of the Color class in order to reduce object allocations. + * An Error thrown when there was a problem in the library. */ - export abstract class Color { - /** - * Create a color value from RGB values in the range [**0**, **255**]. - * - * The channel order of a uint32 encoded color is BGRA. - */ - static fromRgb(red: number, green: number, blue: number): number; - /** - * Create a color value from RGBA values in the range [**0**, **255**]. - * - * The channel order of a uint32 encoded color is BGRA. - */ - static fromRgba(red: number, green: number, blue: number, alpha: number): number; - /** - * Create a color value from HSL values in the range [**0**, **1**]. - */ - static fromHsl(hue: number, saturation: number, lightness: number): number; - /** - * Create a color value from HSV values in the range [**0**, **1**]. - */ - static fromHsv(hue: number, saturation: number, value: number): number; - /** - * Create a color value from XYZ values. - */ - static fromXyz(x: number, y: number, z: number): number; - /** - * Create a color value from CIE-L*a*b values. - */ - static fromLab(L: number, a: number, b: number): number; - /** - * Compare colors from a 3 or 4 dimensional color space - */ - static distance(c1: number[], c2: number[], compareAlpha: boolean): number; - /** - * Returns a new color of **src** alpha-blended onto **dst**. The opacity of **src** - * is additionally scaled by **fraction** / **255**. - */ - static alphaBlendColors(dst: number, src: number, fraction?: number): number; - /** - * Get the **channel** from the **color**. - */ - static getChannel(color: number, channel: ColorChannel): number; - /** - * Get the alpha channel from the **color**. - */ - static getAlpha(color: number): number; - /** - * Get the blue channel from the **color**. - */ - static getBlue(color: number): number; - /** - * Get the color with the given **r**, **g**, **b**, and **a** components. - * The channel order of a uint32 encoded color is RGBA. - */ - static getColor(r: number, g: number, b: number, a?: number): number; - /** - * Get the green channel from the **color**. - */ - static getGreen(color: number): number; - /** - * Returns the luminance (grayscale) value of the **color**. - */ - static getLuminance(color: number): number; - /** - * Returns the luminance (grayscale) value of the color. - */ - static getLuminanceRgb(r: number, g: number, b: number): number; - /** - * Get the red channel from the **color**. - */ - static getRed(color: number): number; - /** - * Check if **color** is white - */ - static isBlack(color: number): boolean; - /** - * Check if **color** is white - */ - static isWhite(color: number): boolean; - /** - * Returns a new color where the alpha channel of **color** has been replaced by **value**. - */ - static setAlpha(color: number, value: number): number; - /** - * Returns a new color where the blue channel of **color** has been replaced by **value**. - */ - static setBlue(color: number, value: number): number; - /** - * Returns a new color, where the given **color**'s **channel** has been - * replaced with the given **value**. - */ - static setChannel(color: number, channel: ColorChannel, value: number): number; - /** - * Returns a new color where the green channel of **color** has been replaced - * by **value**. - */ - static setGreen(color: number, value: number): number; - /** - * Returns a new color where the red channel of **color** has been replaced - * by **value**. - */ - static setRed(color: number, value: number): number; - /** - * Convert an HSL color to RGB, where h is specified in normalized degrees - * [**0**, **1**] (where 1 is 360-degrees); s and l are in the range [**0**, **1**]. - * Returns a list [**r**, **g**, **b**] with values in the range [**0**, **255**]. - */ - static hslToRgb(hue: number, saturation: number, lightness: number): number[]; + export class LibError extends Error { + toString(): string; + } +} +declare module "color/format" { + /** + * The format of a color or image. + */ + export enum Format { + uint1 = 0, + uint2 = 1, + uint4 = 2, + uint8 = 3, + uint16 = 4, + uint32 = 5, + int8 = 6, + int16 = 7, + int32 = 8, + float16 = 9, + float32 = 10, + float64 = 11 + } + /** + * The format type of a color or image. + */ + export enum FormatType { + uint = 0, + int = 1, + float = 2 + } + export const FormatToFormatType: Map; + export const FormatSize: Map; + export const FormatMaxValue: Map; + /** + * Convert a value from the **from** format to the **to** format. + */ + export function convertFormatValue(value: number, from: Format, to: Format): number; +} +declare module "common/bit-utils" { + /** @format */ + export abstract class BitUtils { + private static readonly _uint8; + private static readonly _uint8ToInt8; + private static readonly _int8; + private static readonly _int8ToUint8; + private static readonly _uint16; + private static readonly _uint16ToInt16; + private static readonly _int16; + private static readonly _int16ToUint16; + private static readonly _uint32; + private static readonly _uint32ToInt32; + private static readonly _uint32ToFloat32; + private static readonly _int32; + private static readonly _int32ToUint32; + private static readonly _float32; + private static readonly _float32ToUint32; + private static readonly _uint64; + private static readonly _uint64ToFloat64; + private static readonly _reverseByteTable; + /** + * Count the consecutive zero bits (trailing) on the right in parallel + * https://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightParallel + */ + static countTrailingZeroBits(v: number): number; + static reverseByte(x: number): number; + static signed(bits: number, value: number): number; + static shiftR(v: number, n: number): number; + static shiftL(v: number, n: number): number; /** - * Convert an HSV color to RGB, where h is specified in normalized degrees - * [**0**, **1**] (where 1 is 360-degrees); s and l are in the range [**0**, **1**]. - * Returns a list [**r**, **g**, **b**] with values in the range [**0**, **255**]. + * Binary conversion of a uint8 to an int8. This is equivalent in C to + * typecasting an unsigned char to a char. */ - static hsvToRgb(hue: number, saturation: number, brightness: number): number[]; + static uint8ToInt8(d: number): number; /** - * Convert an RGB color to HSL, where **r**, **g** and **b** are in the range [**0**, **255**]. - * Returns a list [**h**, **s**, **l**] with values in the range [**0**, **1**]. + * Binary conversion of an int8 to a uint8. */ - static rgbToHsl(r: number, g: number, b: number): number[]; + static int8ToUint8(d: number): number; /** - * Convert a CIE-L*a*b color to XYZ. + * Binary conversion of a uint16 to an int16. This is equivalent in C to + * typecasting an unsigned short to a short. */ - static labToXyz(l: number, a: number, b: number): number[]; + static uint16ToInt16(d: number): number; /** - * Convert an XYZ color to RGB. + * Binary conversion of an int16 to a uint16. This is equivalent in C to + * typecasting a short to an unsigned short. */ - static xyzToRgb(x: number, y: number, z: number): number[]; + static int16ToUint16(d: number): number; /** - * Convert a CMYK color to RGB, where **c**, **m**, **y**, **k** values are in the range - * [**0**, **255**]. Returns a list [**r**, **g**, **b**] with values in the range [**0**, **255**]. + * Binary conversion of a uint32 to an int32. This is equivalent in C to + * typecasting an unsigned int to signed int. */ - static cmykToRgb(c: number, m: number, y: number, k: number): number[]; + static uint32ToInt32(d: number): number; /** - * Convert a CIE-L*a*b color to RGB. + * Binary conversion of a uint32 to an float32. This is equivalent in C to + * typecasting an unsigned int to float. */ - static labToRgb(l: number, a: number, b: number): number[]; + static uint32ToFloat32(d: number): number; /** - * Convert a RGB color to XYZ. + * Binary conversion of a uint64 to an float64. This is equivalent in C to + * typecasting an unsigned long long to double. */ - static rgbToXyz(r: number, g: number, b: number): number[]; + static uint64ToFloat64(d: bigint): number; /** - * Convert a XYZ color to CIE-L*a*b. + * Binary conversion of an int32 to a uint32. This is equivalent in C to + * typecasting an int to an unsigned int. */ - static xyzToLab(x: number, y: number, z: number): number[]; + static int32ToUint32(d: number): number; /** - * Convert a RGB color to CIE-L*a*b. + * Binary conversion of a float32 to an uint32. This is equivalent in C to + * typecasting a float to unsigned int. */ - static rgbToLab(r: number, g: number, b: number): number[]; + static float32ToUint32(d: number): number; + static debugBits32(value?: number): string; } } -declare module "common/text-codec" { - export abstract class TextCodec { - static readonly utf8Decoder: TextDecoder; - static readonly latin1Decoder: TextDecoder; +declare module "common/string-utils" { + export abstract class StringUtils { + static readonly utf8Decoder: import("util").TextDecoder; + static readonly latin1Decoder: import("util").TextDecoder; static getCodePoints(str: string): Uint8Array; } } @@ -442,7 +197,7 @@ declare module "common/input-buffer" { /** * Create a InputStream for reading from an Array */ - constructor(options: InputBufferInitOptions); + constructor(opt: InputBufferInitOptions); /** * Create a copy of **other**. */ @@ -465,7 +220,7 @@ declare module "common/input-buffer" { */ memset(start: number, length: number, value: number): void; /** - * Return a InputStream to read a subset of this stream. It does not + * Return an InputBuffer to read a subset of this stream. It does not * move the read position of this stream. **position** is specified relative * to the start of the buffer. If **position** is not specified, the current * read position is used. If **length** is not specified, the remainder of this @@ -542,72 +297,289 @@ declare module "common/input-buffer" { toUint32Array(offset?: number): Uint32Array; } } -declare module "common/output-buffer" { +declare module "color/channel-order" { /** @format */ - import { InputBuffer } from "common/input-buffer"; - export interface OutputBufferInitOptions { - bigEndian?: boolean; - size?: number; + export enum ChannelOrder { + rgba = 0, + bgra = 1, + abgr = 2, + argb = 3, + rgb = 4, + bgr = 5, + grayAlpha = 6, + red = 7 } - export class OutputBuffer { - private static readonly BLOCK_SIZE; - private _buffer; - get buffer(): Uint8Array; - private _bigEndian; - get bigEndian(): boolean; - set bigEndian(v: boolean); - private _length; - get length(): number; - set length(v: number); + /** + * The number of channels for each ChannelOrder. + */ + export const ChannelOrderLength: Map; +} +declare module "image/palette" { + /** @format */ + import { Format } from "color/format"; + export interface Palette { /** - * Create a byte buffer for writing. + * The size of the palette data in bytes. */ - constructor(options?: OutputBufferInitOptions); + get byteLength(): number; /** - * Grow the buffer to accommodate additional data. + * The byte buffer storage of the palette data. */ - private expandBuffer; - rewind(): void; + get buffer(): ArrayBufferLike; /** - * Clear the buffer. + * The number of colors stored in the palette. */ - clear(): void; + get numColors(): number; /** - * Get the resulting bytes from the buffer. + * The number of channels per color. */ - getBytes(): Uint8Array; + get numChannels(): number; + get maxChannelValue(): number; /** - * Write a byte to the end of the buffer. + * The format of the color data. */ - writeByte(value: number): void; + get format(): Format; /** - * Write a set of bytes to the end of the buffer. + * Set the RGB color of a palette entry at **index**. If the palette has fewer + * channels than are set, the unsupported channels will be ignored. */ - writeBytes(bytes: Uint8Array, length?: number): void; - writeBuffer(bytes: InputBuffer): void; + setRgb(index: number, r: number, g: number, b: number): void; /** - * Write a 16-bit word to the end of the buffer. + * Set the RGBA color of a palette entry at **index**. If the palette has fewer + * channels than are set, the unsupported channels will be ignored. */ - writeUint16(value: number): void; + setRgba(index: number, r: number, g: number, b: number, a: number): void; /** - * Write a 32-bit word to the end of the buffer. + * Set a specific **channel** **value** of the palette entry at **index**. If the + * palette has fewer channels than **channel**, the value will be ignored. */ - writeUint32(value: number): void; + set(index: number, channel: number, value: number): void; /** - * Write a 32-bit float value to the end of the buffer. + * Get the the value of a specific **channel** of the palette entry at **index**. + * If the palette has fewer colors than **index** or fewer channels than + * **channel**, 0 will be returned. */ - writeFloat32(value: number): void; + get(index: number, channel: number): number; /** - * Write a 64-bit float value to the end of the buffer. + * Get the red channel of the palette entry at **index**. If the palette has + * fewer colors or channels, 0 will be returned. */ - writeFloat64(value: number): void; + getRed(index: number): number; /** - * Return the subarray of the buffer in the range **start**:**end**. - * If **start** or **end** are < 0 then it is relative to the end of the buffer. - * If **end** is not specified (or undefined), then it is the end of the buffer. - * This is equivalent to the python list range operator. + * Set the red channel of the palette entry at **index**. If the palette has + * fewer colors or channels, it will be ignored. */ - subarray(start: number, end?: number): Uint8Array; + setRed(index: number, value: number): void; + /** + * Get the green channel of the palette entry at **index**. If the palette has + * fewer colors or channels, 0 will be returned. + */ + getGreen(index: number): number; + /** + * Set the green channel of the palette entry at **index**. If the palette has + * fewer colors or channels, it will be ignored. + */ + setGreen(index: number, value: number): void; + /** + * Get the blue channel of the palette entry at **index**. If the palette has + * fewer colors or channels, 0 will be returned. + */ + getBlue(index: number): number; + /** + * Set the blue channel of the palette entry at **index**. If the palette has + * fewer colors or channels, it will be ignored. + */ + setBlue(index: number, value: number): void; + /** + * Get the alpha channel of the palette entry at **index**. If the palette has + * fewer colors or channels, 0 will be returned. + */ + getAlpha(index: number): number; + /** + * Set the alpha channel of the palette entry at **index**. If the palette has + * fewer colors or channels, it will be ignored. + */ + setAlpha(index: number, value: number): void; + /** + * Create a copy of the Palette. + */ + clone(): Palette; + /** + * A Uint8Array view of the palette buffer storage. + */ + toUint8Array(): Uint8Array; + } +} +declare module "color/channel" { + /** @format */ + /** + * A channel of a color + */ + export enum Channel { + /** + * Red channel + */ + red = 0, + /** + * Green channel + */ + green = 1, + /** + * Blue channel + */ + blue = 2, + /** + * Alpha channel + */ + alpha = 3, + /** + * Luminance is not an actual channel, it is the brightness value of the color. + */ + luminance = 4 + } +} +declare module "color/color" { + /** @format */ + import { Palette } from "image/palette"; + import { Channel } from "color/channel"; + import { Format } from "color/format"; + export interface ColorConvertOptions { + format?: Format; + numChannels?: number; + alpha?: number; + } + /** + * The abstract Color class is the base class for all specific color classes + * and Pixel classes. + */ + export interface Color { + /** + * The number of channels used by the color. + */ + get length(): number; + /** + * The maximum value for a color channel. + */ + get maxChannelValue(): number; + /** + * The maximum value for a palette index. + */ + get maxIndexValue(): number; + /** + * The Format of the color. + */ + get format(): Format; + /** + * True if the format is low dynamic range. + */ + get isLdrFormat(): boolean; + /** + * True if the format is high dynamic range. + */ + get isHdrFormat(): boolean; + /** + * True if the color uses a palette. + */ + get hasPalette(): boolean; + /** + * The palette used by the color, or undefined. + */ + get palette(): Palette | undefined; + /** + * Palette index value (or red channel if there is no palette). + */ + get index(): number; + set index(i: number); + /** + * Red channel. + */ + get r(): number; + set r(r: number); + /** + * Green channel. + */ + get g(): number; + set g(g: number); + /** + * Blue channel. + */ + get b(): number; + set b(b: number); + /** + * Alpha channel. + */ + get a(): number; + set a(a: number); + /** + * Normalized [0, 1] red. + */ + get rNormalized(): number; + set rNormalized(v: number); + /** + * Normalized [0, 1] green. + */ + get gNormalized(): number; + set gNormalized(v: number); + /** + * Normalized [0, 1] blue. + */ + get bNormalized(): number; + set bNormalized(v: number); + /** + * Normalized [0, 1] alpha. + */ + get aNormalized(): number; + set aNormalized(v: number); + /** + * The luminance (grayscale) of the color. + */ + get luminance(): number; + get luminanceNormalized(): number; + /** + * Gets a channel from the color by its index or Channel enum. + * If the channel isn't available, 0 will be returned. + */ + getChannel(channel: number | Channel): number; + /** + * Sets a channel to the color by its index. + */ + setChannel(channel: number | Channel, value: number): void; + /** + * Get the normalized [0, 1] value of A channel from the color. If the + * channel isn't available, 0 will be returned. + */ + getChannelNormalized(channel: number | Channel): number; + /** + * The the values of this color to the given Color. + */ + set(color: Color): void; + /** + * Set the individual **r**, **g**, **b** channels of the color. + */ + setRgb(r: number, g: number, b: number): void; + /** + * Set the individual **r**, **g**, **b**, **a** channels of the color. + */ + setRgba(r: number, g: number, b: number, a: number): void; + /** + * Converts the color to an array of channels. + */ + toArray(): number[]; + /** + * Returns a copy of the color. + */ + clone(): Color; + /** + * Convert the **format** and/or the **numChannels** of the color. If + * **numChannels** is 4 and the current color does not have an alpha value, + * then **alpha** can specify what value to use for the new alpha channel. + * If **alpha** is not given, then **maxChannelValue** will be used. + */ + convert(opt: ColorConvertOptions): Color; + /** + * Tests if this color is equivalent to another **Color**. + */ + equals(other: Color | number[]): boolean; } } declare module "common/rational" { @@ -616,379 +588,1318 @@ declare module "common/rational" { get numerator(): number; private _denominator; get denominator(): number; - get asInt(): number; - get asDouble(): number; + get toInt(): number; + get toDouble(): number; constructor(numerator: number, denominator: number); simplify(): void; - equalsTo(other: unknown): boolean; + equals(other: Rational): boolean; toString(): string; } } -declare module "exif/exif-value-type" { - /** @format */ - export enum ExifValueType { - none = 0, - byte = 1, - ascii = 2, - short = 3, - long = 4, - rational = 5, - sbyte = 6, - undefined = 7, - sshort = 8, - slong = 9, - srational = 10, - single = 11, - double = 12 - } - export const ExifValueTypeString: string[]; - export const ExifValueTypeSize: number[]; - export function getExifValueTypeString(type: ExifValueType): string; - export function getExifValueTypeSize(type: ExifValueType, length?: number): number; -} -declare module "exif/exif-value/exif-value" { - /** @format */ - import { OutputBuffer } from "common/output-buffer"; +declare module "common/array-utils" { import { Rational } from "common/rational"; - import { ExifValueType } from "exif/exif-value-type"; - export abstract class ExifValue { - get type(): ExifValueType; - get length(): number; - get dataSize(): number; - get typeString(): string; - toBool(_index?: number): boolean; - toInt(_index?: number): number; - toDouble(_index?: number): number; - toRational(_index?: number): Rational; - toString(): string; - write(_out: OutputBuffer): void; - setBool(_v: boolean, _index?: number): void; - setInt(_v: number, _index?: number): void; - setDouble(_v: number, _index?: number): void; - setRational(_numerator: number, _denomitator: number, _index?: number): void; - setString(_v: string): void; - equalsTo(_other: ExifValue): boolean; - clone(): ExifValue; - } -} -declare module "exif/exif-entry" { - /** @format */ - import { ExifValue } from "exif/exif-value/exif-value"; - export class ExifEntry { - private readonly _tag; - get tag(): number; - private _value; - get value(): ExifValue | undefined; - set value(v: ExifValue | undefined); - constructor(tag: number, value?: ExifValue); - } -} -declare module "exif/exif-ifd-container" { - /** @format */ - import { ExifIFD } from "exif/exif-ifd"; - export class ExifIFDContainer { - protected directories: Map; - get keys(): IterableIterator; - get values(): IterableIterator; - get size(): number; - get isEmpty(): boolean; - constructor(directories?: Map); - static from(other: ExifIFDContainer): ExifIFDContainer; - has(key: string): boolean; - get(ifdName: string): ExifIFD; - set(ifdName: string, value: ExifIFD): void; - clear(): void; + import { TypedArray } from "common/typings"; + export abstract class ArrayUtils { + static copyInt8(from: Int8Array, begin?: number, end?: number): Int8Array; + static copyUint8(from: Uint8Array, begin?: number, end?: number): Uint8Array; + static copyInt16(from: Int16Array, begin?: number, end?: number): Int16Array; + static copyUint16(from: Uint16Array, begin?: number, end?: number): Uint16Array; + static copyInt32(from: Int32Array, begin?: number, end?: number): Int32Array; + static copyUint32(from: Uint32Array, begin?: number, end?: number): Uint32Array; + static copyFloat32(from: Float32Array, begin?: number, end?: number): Float32Array; + static copyFloat64(from: Float64Array, begin?: number, end?: number): Float64Array; + static copy(from: TypedArray, begin?: number, end?: number): TypedArray; + static copyRange(from: T, fromStart: number, fromEnd: number, to: T, toStart: number): void; + static fill(length: number, value: T): T[]; + static generate(length: number, func: (index: number) => T): T[]; + static equals(a1: TypedArray | unknown[], a2: TypedArray | unknown[]): boolean; + static equalsRationalArray(a1: Rational[], a2: Rational[]): boolean; + static getNumEnumValues(t: T): number[]; + static isNumArrayOrTypedArray(obj: unknown): boolean; + static isArrayOfRational(obj: unknown): boolean; } } -declare module "exif/exif-tag" { - /** @format */ - import { ExifValueType } from "exif/exif-value-type"; - export interface ExifTagInitOptions { - name: string; - type?: ExifValueType; - count?: number; - } - export class ExifTag { - private readonly _name; - get name(): string; - private readonly _type; - get type(): ExifValueType; - private _count; - get count(): number; - constructor(options: ExifTagInitOptions); +declare module "common/float16" { + /** + * A 16-bit floating-point number, used by high-dynamic-range image formats + * as a more efficient storage for floating-point values that don't require + * full 32-bit precision. A list of Half floats can be stored in a + * Uint16Array, and converted to a double using the **float16ToDouble** static + * method. + * + * This class is derived from the OpenEXR library. + */ + export class Float16 { + private static _toFloatFloat32Data?; + private static _eLut; + private static get _toFloatFloat32(); + bits: number; + constructor(f?: number); + private static convert; + private static initialize; + private static halfToFloat; + static from(other: Float16): Float16; + static fromBits(bits: number): Float16; + static float16ToDouble(bits: number): number; + static doubleToFloat16(n: number): number; + /** + * Returns +Infinity. + */ + static posInf(): Float16; + /** + * Returns -Infinity. + */ + static negInf(): Float16; + /** + * Returns a NaN with the bit pattern 0111111111111111. + */ + static qNan(): Float16; + /** + * Returns a NaN with the bit pattern 0111110111111111. + */ + static sNan(): Float16; + toDouble(): number; + /** + * Unary minus + */ + minus(): Float16; + /** + * Addition operator for Half or num left operands. + */ + add(f: Float16 | number): Float16; + /** + * Subtraction operator for Half or num left operands. + */ + sub(f: Float16 | number): Float16; + /** + * Multiplication operator for Half or num left operands. + */ + mul(f: Float16 | number): Float16; + /** + * Division operator for Half or num left operands. + */ + div(f: Float16 | number): Float16; + /** + * Round to n-bit precision (n should be between 0 and 10). + * After rounding, the significand's 10-n least significant + * bits will be zero. + */ + round(n: number): Float16; + /** + * Returns true if h is a normalized number, a denormalized number or zero. + */ + isFinite(): boolean; + /** + * Returns true if h is a normalized number. + */ + isNormalized(): boolean; + /** + * Returns true if h is a denormalized number. + */ + isDenormalized(): boolean; + /** + * Returns true if h is zero. + */ + isZero(): boolean; + /** + * Returns true if h is a NaN. + */ + isNaN(): boolean; + /** + * Returns true if h is a positive or a negative infinity. + */ + isInfinity(): boolean; + /** + * Returns true if the sign bit of h is set (negative). + */ + isNegative(): boolean; } - export const ExifTagNameToID: Map; - export const ExifImageTags: Map; - export const ExifInteropTags: Map; - export const ExifGpsTags: Map; } -declare module "exif/exif-value/exif-ascii-value" { - /** @format */ - import { InputBuffer } from "common/input-buffer"; - import { OutputBuffer } from "common/output-buffer"; - import { ExifValue } from "exif/exif-value/exif-value"; - import { ExifValueType } from "exif/exif-value-type"; - export class ExifAsciiValue extends ExifValue { - private value; - get type(): ExifValueType; +declare module "color/color-float16" { + import { Palette } from "image/palette"; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + /** + * A 16-bit floating point color. + */ + export class ColorFloat16 implements Color { + protected data: Uint16Array; + get format(): Format; get length(): number; - constructor(value: number[] | string); - static fromData(data: InputBuffer, length: number): ExifAsciiValue; - toData(): Uint8Array; - toString(): string; - write(out: OutputBuffer): void; - setString(v: string): void; - equalsTo(other: unknown): boolean; - clone(): ExifValue; + get maxChannelValue(): number; + get maxIndexValue(): number; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get index(): number; + set index(i: number); + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(data: Uint16Array | number); + static from(other: ColorFloat16): ColorFloat16; + static fromArray(color: Uint16Array): ColorFloat16; + static rgb(r: number, g: number, b: number): ColorFloat16; + static rgba(r: number, g: number, b: number, a: number): ColorFloat16; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: number | Channel): number; + setChannel(index: number | Channel, value: number): void; + set(c: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + clone(): ColorFloat16; + equals(other: Color): boolean; + convert(opt?: ColorConvertOptions): Color; + } +} +declare module "color/color-float32" { + import { Palette } from "image/palette"; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + /** + * A 32-bit floating point color. + */ + export class ColorFloat32 implements Color { + protected data: Float32Array; + get format(): Format; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get index(): number; + set index(i: number); + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(data: Float32Array | number); + static from(other: ColorFloat32): ColorFloat32; + static fromArray(color: Float32Array): ColorFloat32; + static rgb(r: number, g: number, b: number): ColorFloat32; + static rgba(r: number, g: number, b: number, a: number): ColorFloat32; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: number | Channel): number; + setChannel(index: number | Channel, value: number): void; + set(c: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + clone(): ColorFloat32; + equals(other: Color): boolean; + convert(opt?: ColorConvertOptions): Color; + } +} +declare module "color/color-float64" { + import { Palette } from "image/palette"; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + /** + * A 64-bit floating point color. + */ + export class ColorFloat64 implements Color { + protected data: Float64Array; + get format(): Format; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get index(): number; + set index(i: number); + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(data: Float64Array | number); + static from(other: ColorFloat64): ColorFloat64; + static fromArray(color: Float64Array): ColorFloat64; + static rgb(r: number, g: number, b: number): ColorFloat64; + static rgba(r: number, g: number, b: number, a: number): ColorFloat64; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: number | Channel): number; + setChannel(index: number | Channel, value: number): void; + set(c: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + clone(): ColorFloat64; + equals(other: Color): boolean; + convert(opt?: ColorConvertOptions): Color; + } +} +declare module "color/color-int16" { + import { Palette } from "image/palette"; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + /** + * A 16-bit integer color. + */ + export class ColorInt16 implements Color { + private _data; + get format(): Format; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get index(): number; + set index(i: number); + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(data: Int16Array | number); + static from(other: ColorInt16): ColorInt16; + static fromArray(color: number[]): ColorInt16; + static rgb(r: number, g: number, b: number): ColorInt16; + static rgba(r: number, g: number, b: number, a: number): ColorInt16; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: number | Channel): number; + setChannel(index: number | Channel, value: number): void; + set(c: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + clone(): ColorInt16; + equals(other: Color): boolean; + convert(opt?: ColorConvertOptions): Color; + } +} +declare module "color/color-int32" { + import { Palette } from "image/palette"; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + /** + * A 32-bit integer color. + */ + export class ColorInt32 implements Color { + private _data; + get format(): Format; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get index(): number; + set index(i: number); + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(data: Int32Array | number); + static from(other: ColorInt32): ColorInt32; + static fromArray(color: number[]): ColorInt32; + static rgb(r: number, g: number, b: number): ColorInt32; + static rgba(r: number, g: number, b: number, a: number): ColorInt32; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: number | Channel): number; + setChannel(index: number | Channel, value: number): void; + set(c: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + clone(): ColorInt32; + equals(other: Color): boolean; + convert(opt?: ColorConvertOptions): Color; + } +} +declare module "color/color-int8" { + import { Palette } from "image/palette"; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + /** + * A 8-bit integer color. + */ + export class ColorInt8 implements Color { + private _data; + get format(): Format; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get index(): number; + set index(i: number); + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(data: Int8Array | number); + static from(other: ColorInt8): ColorInt8; + static fromArray(color: number[]): ColorInt8; + static rgb(r: number, g: number, b: number): ColorInt8; + static rgba(r: number, g: number, b: number, a: number): ColorInt8; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: number | Channel): number; + setChannel(index: number | Channel, value: number): void; + set(c: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + clone(): ColorInt8; + equals(other: Color): boolean; + convert(opt?: ColorConvertOptions): Color; + } +} +declare module "color/color-uint1" { + import { Palette } from "image/palette"; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + /** + * A 1-bit unsigned int color with channel values in the range [0, 1]. + */ + export class ColorUint1 implements Color { + private _data; + get format(): Format; + private readonly _length; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get index(): number; + set index(i: number); + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(data: number[] | number); + static from(other: ColorUint1): ColorUint1; + static fromArray(color: number[]): ColorUint1; + static rgb(r: number, g: number, b: number): ColorUint1; + static rgba(r: number, g: number, b: number, a: number): ColorUint1; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: number | Channel): number; + setChannel(index: number | Channel, value: number): void; + set(c: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + clone(): ColorUint1; + equals(other: Color): boolean; + convert(opt?: ColorConvertOptions): Color; + } +} +declare module "color/color-uint16" { + import { Palette } from "image/palette"; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + /** + * A 16-bit unsigned int color with channel values in the range [0, 65535]. + */ + export class ColorUint16 implements Color { + protected data: Uint16Array; + get format(): Format; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get index(): number; + set index(i: number); + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(data: Uint16Array | number); + static from(other: ColorUint16): ColorUint16; + static fromArray(color: Uint16Array): ColorUint16; + static rgb(r: number, g: number, b: number): ColorUint16; + static rgba(r: number, g: number, b: number, a: number): ColorUint16; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: number | Channel): number; + setChannel(index: number | Channel, value: number): void; + set(c: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + clone(): ColorUint16; + equals(other: Color): boolean; + convert(opt?: ColorConvertOptions): Color; + } +} +declare module "color/color-uint2" { + import { Palette } from "image/palette"; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + /** + * A 2-bit unsigned int color with channel values in the range [0, 3]. + */ + export class ColorUint2 implements Color { + private _data; + get format(): Format; + private readonly _length; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get index(): number; + set index(i: number); + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(data: number[] | number); + static from(other: ColorUint2): ColorUint2; + static fromArray(color: number[]): ColorUint2; + static rgb(r: number, g: number, b: number): ColorUint2; + static rgba(r: number, g: number, b: number, a: number): ColorUint2; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: number | Channel): number; + setChannel(index: number | Channel, value: number): void; + set(c: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + clone(): ColorUint2; + equals(other: Color): boolean; + convert(opt?: ColorConvertOptions): Color; + } +} +declare module "color/color-uint32" { + import { Palette } from "image/palette"; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + /** + * A 32-bit unsigned int color. + */ + export class ColorUint32 implements Color { + protected data: Uint32Array; + get format(): Format; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get index(): number; + set index(i: number); + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(data: Uint32Array | number); + static from(other: ColorUint32): ColorUint32; + static fromArray(color: Uint32Array): ColorUint32; + static rgb(r: number, g: number, b: number): ColorUint32; + static rgba(r: number, g: number, b: number, a: number): ColorUint32; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: number | Channel): number; + setChannel(index: number | Channel, value: number): void; + set(c: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + clone(): ColorUint32; + equals(other: Color): boolean; + convert(opt?: ColorConvertOptions): Color; + } +} +declare module "color/color-uint4" { + import { Palette } from "image/palette"; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + /** + * A 4-bit unsigned int color with channel values in the range [0, 15]. + */ + export class ColorUint4 implements Color { + private _data; + get format(): Format; + private readonly _length; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get index(): number; + set index(i: number); + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(data: Uint8Array | number); + static from(other: ColorUint4): ColorUint4; + static fromArray(color: Uint8Array): ColorUint4; + static rgb(r: number, g: number, b: number): ColorUint4; + static rgba(r: number, g: number, b: number, a: number): ColorUint4; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: number | Channel): number; + setChannel(index: number | Channel, value: number): void; + set(c: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + clone(): ColorUint4; + equals(other: Color): boolean; + convert(opt?: ColorConvertOptions): Color; + } +} +declare module "color/color-utils" { + import { Color } from "color/color"; + import { Format } from "color/format"; + export interface ConvertColorOptions { + from: Color; + to?: Color; + format?: Format; + numChannels?: number; + alpha?: number; + } + export abstract class ColorUtils { + private static convertColorInternal; + static uint32ToRed(c: number): number; + static uint32ToGreen(c: number): number; + static uint32ToBlue(c: number): number; + static uint32ToAlpha(c: number): number; + static rgbaToUint32(r: number, g: number, b: number, a: number): number; + static convertColor(opt: ConvertColorOptions): Color; + /** + * Returns the luminance (grayscale) value of the color. + */ + static getLuminance(c: Color): number; + /** + * Returns the normalized [0, 1] luminance (grayscale) value of the color. + */ + static getLuminanceNormalized(c: Color): number; + /** + * Returns the luminance (grayscale) value of the color. + */ + static getLuminanceRgb(r: number, g: number, b: number): number; + /** + * Convert an HSL color to RGB, where **hue** is specified in normalized degrees + * [0, 1] (where 1 is 360-degrees); **saturation** and **lightness** are in the range [0, 1]. + * Returns a list [r, g, b] with values in the range [0, 255]. + */ + static hslToRgb(hue: number, saturation: number, lightness: number): number[]; + /** + * Convert an HSV color to RGB, where **hue** is specified in normalized degrees + * [0, 1] (where 1 is 360-degrees); **saturation** and **brightness** are in the range [0, 1]. + * Returns a list [r, g, b] with values in the range [0, 255]. + */ + static hsvToRgb(hue: number, saturation: number, brightness: number): number[]; + /** + * Convert an RGB color to HSL, where **r**, **g** and **b** are in the range [0, 255]. + * Returns a list [h, s, l] with values in the range [0, 1]. + */ + static rgbToHsl(r: number, g: number, b: number): number[]; + /** + * Convert a CIE L\*a\*b color to XYZ. + */ + static labToXyz(l: number, a: number, b: number): number[]; + /** + * Convert an XYZ color to RGB. + */ + static xyzToRgb(x: number, y: number, z: number): number[]; + /** + * Convert a CMYK color to RGB, where **c**, **m**, **y**, **k** values are in the range + * [0, 255]. Returns a list [r, g, b] with values in the range [0, 255]. + */ + static cmykToRgb(c: number, m: number, y: number, k: number): number[]; + /** + * Convert a CIE L\*a\*b color to RGB. + */ + static labToRgb(l: number, a: number, b: number): number[]; + /** + * Convert a RGB color to XYZ. + */ + static rgbToXyz(r: number, g: number, b: number): number[]; + /** + * Convert a XYZ color to CIE L\*a\*b. + */ + static xyzToLab(x: number, y: number, z: number): number[]; + /** + * Convert a RGB color to CIE L\*a\*b. + */ + static rgbToLab(r: number, g: number, b: number): number[]; } } -declare module "exif/exif-value/exif-byte-value" { - /** @format */ - import { InputBuffer } from "common/input-buffer"; - import { OutputBuffer } from "common/output-buffer"; - import { ExifValue } from "exif/exif-value/exif-value"; - import { ExifValueType } from "exif/exif-value-type"; - export class ExifByteValue extends ExifValue { - private value; - get type(): ExifValueType; +declare module "color/color-uint8" { + import { Palette } from "image/palette"; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + /** + * An 8-bit unsigned int color with channel values in the range [0, 255]. + */ + export class ColorUint8 implements Color { + protected data: Uint8Array; + get format(): Format; get length(): number; - constructor(value: Uint8Array | number); - static fromData(data: InputBuffer, offset?: number, length?: number): ExifByteValue; - toInt(index?: number): number; - toData(): Uint8Array; - toString(): string; - write(out: OutputBuffer): void; - setInt(v: number, index?: number): void; - equalsTo(other: unknown): boolean; - clone(): ExifValue; + get maxChannelValue(): number; + get maxIndexValue(): number; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get index(): number; + set index(i: number); + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(data: Uint8Array | number); + static from(other: ColorUint8): ColorUint8; + static fromArray(color: Uint8Array): ColorUint8; + static rgb(r: number, g: number, b: number): ColorUint8; + static rgba(r: number, g: number, b: number, a: number): ColorUint8; + getChannel(channel: number | Channel, defValue?: number): number; + getChannelNormalized(channel: number | Channel): number; + setChannel(index: number | Channel, value: number): void; + set(c: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + clone(): ColorUint8; + equals(other: Color): boolean; + convert(opt?: ColorConvertOptions): Color; } } -declare module "exif/exif-value/exif-double-value" { +declare module "common/interpolation" { /** @format */ - import { InputBuffer } from "common/input-buffer"; - import { OutputBuffer } from "common/output-buffer"; - import { ExifValue } from "exif/exif-value/exif-value"; - import { ExifValueType } from "exif/exif-value-type"; - export class ExifDoubleValue extends ExifValue { - private value; - get type(): ExifValueType; - get length(): number; - constructor(value: Float64Array | number); - static fromData(data: InputBuffer, length: number): ExifDoubleValue; - toDouble(index?: number): number; - toData(): Uint8Array; - toString(): string; - write(out: OutputBuffer): void; - setDouble(v: number, index?: number): void; - equalsTo(other: unknown): boolean; - clone(): ExifValue; + /** + * Interpolation method to use when resizing images. + */ + export enum Interpolation { + /** + * Select the closest pixel.Fastest, lowest quality. + */ + nearest = 0, + /** + * Linearly blend between the neighboring pixels. + */ + linear = 1, + /** + * Cubic blend between the neighboring pixels. Slowest, highest Quality. + */ + cubic = 2, + /** + * Average the colors of the neighboring pixels. + */ + average = 3 } } -declare module "exif/exif-value/exif-long-value" { +declare module "common/output-buffer" { /** @format */ import { InputBuffer } from "common/input-buffer"; - import { OutputBuffer } from "common/output-buffer"; - import { ExifValue } from "exif/exif-value/exif-value"; - import { ExifValueType } from "exif/exif-value-type"; - export class ExifLongValue extends ExifValue { - private value; - get type(): ExifValueType; + export interface OutputBufferInitOptions { + bigEndian?: boolean; + size?: number; + } + export class OutputBuffer { + private static readonly _blockSize; + private _buffer; + get buffer(): Uint8Array; + private _bigEndian; + get bigEndian(): boolean; + set bigEndian(v: boolean); + private _length; get length(): number; - constructor(value: Uint32Array | number); - static fromData(data: InputBuffer, length: number): ExifLongValue; - toInt(index?: number): number; - toData(): Uint8Array; - toString(): string; - write(out: OutputBuffer): void; - setInt(v: number, index?: number): void; - equalsTo(other: unknown): boolean; - clone(): ExifValue; + set length(v: number); + /** + * Create a byte buffer for writing. + */ + constructor(opt?: OutputBufferInitOptions); + /** + * Grow the buffer to accommodate additional data. + */ + private expandBuffer; + rewind(): void; + /** + * Clear the buffer. + */ + clear(): void; + /** + * Get the resulting bytes from the buffer. + */ + getBytes(): Uint8Array; + /** + * Write a byte to the end of the buffer. + */ + writeByte(value: number): void; + /** + * Write a set of bytes to the end of the buffer. + */ + writeBytes(bytes: Uint8Array, length?: number): void; + writeBuffer(bytes: InputBuffer): void; + /** + * Write a 16-bit word to the end of the buffer. + */ + writeUint16(value: number): void; + /** + * Write a 32-bit word to the end of the buffer. + */ + writeUint32(value: number): void; + /** + * Write a 32-bit float value to the end of the buffer. + */ + writeFloat32(value: number): void; + /** + * Write a 64-bit float value to the end of the buffer. + */ + writeFloat64(value: number): void; + /** + * Return the subarray of the buffer in the range [**start**,**end**]. + * If **start** or **end** are < 0 then it is relative to the end of the buffer. + * If **end** is not specified (or undefined), then it is the end of the buffer. + * This is equivalent to the python list range operator. + */ + subarray(start: number, end?: number): Uint8Array; } } -declare module "exif/exif-value/exif-rational-value" { +declare module "exif/ifd-value-type" { /** @format */ - import { InputBuffer } from "common/input-buffer"; - import { OutputBuffer } from "common/output-buffer"; - import { ExifValue } from "exif/exif-value/exif-value"; - import { ExifValueType } from "exif/exif-value-type"; - import { Rational } from "common/rational"; - export class ExifRationalValue extends ExifValue { - private value; - get type(): ExifValueType; - get length(): number; - constructor(value: Rational[] | Rational); - static fromData(data: InputBuffer, length: number): ExifRationalValue; - static from(other: Rational): ExifRationalValue; - toInt(index?: number): number; - toDouble(index?: number): number; - toRational(index?: number): Rational; - toString(): string; - write(out: OutputBuffer): void; - setRational(numerator: number, denomitator: number, index?: number): void; - equalsTo(other: unknown): boolean; - clone(): ExifValue; + export enum IfdValueType { + none = 0, + byte = 1, + ascii = 2, + short = 3, + long = 4, + rational = 5, + sByte = 6, + undefined = 7, + sShort = 8, + sLong = 9, + sRational = 10, + single = 11, + double = 12 } + export const IfdValueTypeSize: number[]; + export function getIfdValueTypeString(type: IfdValueType): string; + export function getIfdValueTypeSize(type: IfdValueType, length?: number): number; } -declare module "exif/exif-value/exif-sbyte-value" { +declare module "exif/ifd-value/ifd-value" { /** @format */ - import { InputBuffer } from "common/input-buffer"; import { OutputBuffer } from "common/output-buffer"; - import { ExifValue } from "exif/exif-value/exif-value"; - import { ExifValueType } from "exif/exif-value-type"; - export class ExifSByteValue extends ExifValue { - private value; - get type(): ExifValueType; + import { Rational } from "common/rational"; + import { IfdValueType } from "exif/ifd-value-type"; + export abstract class IfdValue { + get type(): IfdValueType; get length(): number; - constructor(value: Int8Array | number); - static fromData(data: InputBuffer, offset?: number, length?: number): ExifSByteValue; - toInt(index?: number): number; + get dataSize(): number; + get typeString(): string; + toBool(_index?: number): boolean; + toInt(_index?: number): number; + toDouble(_index?: number): number; toData(): Uint8Array; + toRational(_index?: number): Rational; + write(_out: OutputBuffer): void; + setBool(_v: boolean, _index?: number): void; + setInt(_v: number, _index?: number): void; + setDouble(_v: number, _index?: number): void; + setRational(_numerator: number, _denomitator: number, _index?: number): void; + setString(_v: string): void; + equals(_other: IfdValue): boolean; + clone(): IfdValue; toString(): string; + } +} +declare module "exif/exif-entry" { + /** @format */ + import { IfdValue } from "exif/ifd-value/ifd-value"; + export class ExifEntry { + private readonly _tag; + get tag(): number; + private _value; + get value(): IfdValue | undefined; + set value(v: IfdValue | undefined); + constructor(tag: number, value?: IfdValue); + } +} +declare module "exif/exif-tag" { + /** @format */ + import { IfdValueType } from "exif/ifd-value-type"; + export interface ExifTagInitOptions { + name: string; + type?: IfdValueType; + count?: number; + } + export class ExifTag { + private readonly _name; + get name(): string; + private readonly _type; + get type(): IfdValueType; + private _count?; + get count(): number | undefined; + constructor(opt: ExifTagInitOptions); + } + export const ExifTagNameToID: Map; + export const ExifImageTags: Map; + export const ExifInteropTags: Map; + export const ExifGpsTags: Map; +} +declare module "exif/ifd-value/ifd-ascii-value" { + /** @format */ + import { InputBuffer } from "common/input-buffer"; + import { OutputBuffer } from "common/output-buffer"; + import { IfdValue } from "exif/ifd-value/ifd-value"; + import { IfdValueType } from "exif/ifd-value-type"; + export class IfdAsciiValue extends IfdValue { + private _value; + get type(): IfdValueType; + get length(): number; + constructor(value: number[] | string); + static data(data: InputBuffer, length: number): IfdAsciiValue; + toData(): Uint8Array; write(out: OutputBuffer): void; - setInt(v: number, index?: number): void; - equalsTo(other: unknown): boolean; - clone(): ExifValue; + setString(v: string): void; + equals(other: IfdValue): boolean; + clone(): IfdValue; + toString(): string; } } -declare module "exif/exif-value/exif-short-value" { +declare module "exif/ifd-value/ifd-short-value" { /** @format */ import { InputBuffer } from "common/input-buffer"; import { OutputBuffer } from "common/output-buffer"; - import { ExifValue } from "exif/exif-value/exif-value"; - import { ExifValueType } from "exif/exif-value-type"; - export class ExifShortValue extends ExifValue { - private value; - get type(): ExifValueType; + import { IfdValue } from "exif/ifd-value/ifd-value"; + import { IfdValueType } from "exif/ifd-value-type"; + export class IfdShortValue extends IfdValue { + private _value; + get type(): IfdValueType; get length(): number; constructor(value: Uint16Array | number); - static fromData(data: InputBuffer, length: number): ExifShortValue; + static data(data: InputBuffer, length: number): IfdShortValue; toInt(index?: number): number; - toString(): string; write(out: OutputBuffer): void; setInt(v: number, index?: number): void; - equalsTo(other: unknown): boolean; - clone(): ExifValue; + equals(other: IfdValue): boolean; + clone(): IfdValue; + toString(): string; } } -declare module "exif/exif-value/exif-single-value" { +declare module "exif/ifd-value/ifd-rational-value" { /** @format */ import { InputBuffer } from "common/input-buffer"; import { OutputBuffer } from "common/output-buffer"; - import { ExifValue } from "exif/exif-value/exif-value"; - import { ExifValueType } from "exif/exif-value-type"; - export class ExifSingleValue extends ExifValue { - private value; - get type(): ExifValueType; + import { IfdValue } from "exif/ifd-value/ifd-value"; + import { IfdValueType } from "exif/ifd-value-type"; + import { Rational } from "common/rational"; + export class IfdRationalValue extends IfdValue { + private _value; + get type(): IfdValueType; get length(): number; - constructor(value: Float32Array | number); - static fromData(data: InputBuffer, length: number): ExifSingleValue; + constructor(value: Rational[] | Rational); + static data(data: InputBuffer, length: number): IfdRationalValue; + static from(other: Rational): IfdRationalValue; + toInt(index?: number): number; toDouble(index?: number): number; + toRational(index?: number): Rational; + write(out: OutputBuffer): void; + setRational(numerator: number, denomitator: number, index?: number): void; + equals(other: IfdValue): boolean; + clone(): IfdValue; + toString(): string; + } +} +declare module "exif/ifd-value/ifd-byte-value" { + /** @format */ + import { InputBuffer } from "common/input-buffer"; + import { OutputBuffer } from "common/output-buffer"; + import { IfdValue } from "exif/ifd-value/ifd-value"; + import { IfdValueType } from "exif/ifd-value-type"; + export class IfdByteValue extends IfdValue { + private _value; + get type(): IfdValueType; + get length(): number; + constructor(value: Uint8Array | number); + static data(data: InputBuffer, offset?: number, length?: number): IfdByteValue; + toInt(index?: number): number; toData(): Uint8Array; + write(out: OutputBuffer): void; + setInt(v: number, index?: number): void; + equals(other: IfdValue): boolean; + clone(): IfdValue; toString(): string; + } +} +declare module "exif/ifd-value/ifd-long-value" { + /** @format */ + import { InputBuffer } from "common/input-buffer"; + import { OutputBuffer } from "common/output-buffer"; + import { IfdValue } from "exif/ifd-value/ifd-value"; + import { IfdValueType } from "exif/ifd-value-type"; + export class IfdLongValue extends IfdValue { + private _value; + get type(): IfdValueType; + get length(): number; + constructor(value: Uint32Array | number); + static data(data: InputBuffer, length: number): IfdLongValue; + toInt(index?: number): number; + toData(): Uint8Array; write(out: OutputBuffer): void; - setDouble(v: number, index?: number): void; - equalsTo(other: unknown): boolean; - clone(): ExifValue; + setInt(v: number, index?: number): void; + equals(other: IfdValue): boolean; + clone(): IfdValue; + toString(): string; } } -declare module "exif/exif-value/exif-slong-value" { +declare module "exif/ifd-value/ifd-sbyte-value" { /** @format */ import { InputBuffer } from "common/input-buffer"; import { OutputBuffer } from "common/output-buffer"; - import { ExifValue } from "exif/exif-value/exif-value"; - import { ExifValueType } from "exif/exif-value-type"; - export class ExifSLongValue extends ExifValue { - private value; - get type(): ExifValueType; + import { IfdValue } from "exif/ifd-value/ifd-value"; + import { IfdValueType } from "exif/ifd-value-type"; + export class IfdSByteValue extends IfdValue { + private _value; + get type(): IfdValueType; get length(): number; - constructor(value: Int32Array | number); - static fromData(data: InputBuffer, length: number): ExifSLongValue; + constructor(value: Int8Array | number); + static data(data: InputBuffer, offset?: number, length?: number): IfdSByteValue; + toInt(index?: number): number; + toData(): Uint8Array; + write(out: OutputBuffer): void; + setInt(v: number, index?: number): void; + equals(other: IfdValue): boolean; + clone(): IfdValue; + toString(): string; + } +} +declare module "exif/ifd-value/ifd-undefined-value" { + /** @format */ + import { InputBuffer } from "common/input-buffer"; + import { OutputBuffer } from "common/output-buffer"; + import { IfdValue } from "exif/ifd-value/ifd-value"; + import { IfdValueType } from "exif/ifd-value-type"; + export class IfdUndefinedValue extends IfdValue { + private _value; + get type(): IfdValueType; + get length(): number; + constructor(value: Uint8Array | number); + static data(data: InputBuffer, offset?: number, length?: number): IfdUndefinedValue; + toData(): Uint8Array; + write(out: OutputBuffer): void; + equals(other: IfdValue): boolean; + clone(): IfdValue; + toString(): string; + } +} +declare module "exif/ifd-value/ifd-sshort-value" { + /** @format */ + import { InputBuffer } from "common/input-buffer"; + import { OutputBuffer } from "common/output-buffer"; + import { IfdValue } from "exif/ifd-value/ifd-value"; + import { IfdValueType } from "exif/ifd-value-type"; + export class IfdSShortValue extends IfdValue { + private _value; + get type(): IfdValueType; + get length(): number; + constructor(value: Int16Array | number); + static data(data: InputBuffer, length: number): IfdSShortValue; toInt(index?: number): number; toData(): Uint8Array; + write(out: OutputBuffer): void; + setInt(v: number, index?: number): void; + equals(other: IfdValue): boolean; + clone(): IfdValue; toString(): string; + } +} +declare module "exif/ifd-value/ifd-slong-value" { + /** @format */ + import { InputBuffer } from "common/input-buffer"; + import { OutputBuffer } from "common/output-buffer"; + import { IfdValue } from "exif/ifd-value/ifd-value"; + import { IfdValueType } from "exif/ifd-value-type"; + export class IfdSLongValue extends IfdValue { + private _value; + get type(): IfdValueType; + get length(): number; + constructor(value: Int32Array | number); + static data(data: InputBuffer, length: number): IfdSLongValue; + toInt(index?: number): number; + toData(): Uint8Array; write(out: OutputBuffer): void; setInt(v: number, index?: number): void; - equalsTo(other: unknown): boolean; - clone(): ExifValue; + equals(other: IfdValue): boolean; + clone(): IfdValue; + toString(): string; } } -declare module "exif/exif-value/exif-srational-value" { +declare module "exif/ifd-value/ifd-srational-value" { /** @format */ import { InputBuffer } from "common/input-buffer"; import { OutputBuffer } from "common/output-buffer"; - import { ExifValue } from "exif/exif-value/exif-value"; - import { ExifValueType } from "exif/exif-value-type"; + import { IfdValue } from "exif/ifd-value/ifd-value"; + import { IfdValueType } from "exif/ifd-value-type"; import { Rational } from "common/rational"; - export class ExifSRationalValue extends ExifValue { - private value; - get type(): ExifValueType; + export class IfdSRationalValue extends IfdValue { + private _value; + get type(): IfdValueType; get length(): number; constructor(value: Rational[] | Rational); - static fromData(data: InputBuffer, length: number): ExifSRationalValue; - static from(other: Rational): ExifSRationalValue; + static data(data: InputBuffer, length: number): IfdSRationalValue; + static from(other: Rational): IfdSRationalValue; toInt(index?: number): number; toDouble(index?: number): number; toRational(index?: number): Rational; - toString(): string; write(out: OutputBuffer): void; setRational(numerator: number, denomitator: number, index?: number): void; - equalsTo(other: unknown): boolean; - clone(): ExifValue; + equals(other: IfdValue): boolean; + clone(): IfdValue; + toString(): string; } } -declare module "exif/exif-value/exif-sshort-value" { +declare module "exif/ifd-value/ifd-single-value" { /** @format */ import { InputBuffer } from "common/input-buffer"; import { OutputBuffer } from "common/output-buffer"; - import { ExifValue } from "exif/exif-value/exif-value"; - import { ExifValueType } from "exif/exif-value-type"; - export class ExifSShortValue extends ExifValue { - private value; - get type(): ExifValueType; + import { IfdValue } from "exif/ifd-value/ifd-value"; + import { IfdValueType } from "exif/ifd-value-type"; + export class IfdSingleValue extends IfdValue { + private _value; + get type(): IfdValueType; get length(): number; - constructor(value: Int16Array | number); - static fromData(data: InputBuffer, length: number): ExifSShortValue; - toInt(index?: number): number; + constructor(value: Float32Array | number); + static data(data: InputBuffer, length: number): IfdSingleValue; + toDouble(index?: number): number; toData(): Uint8Array; - toString(): string; write(out: OutputBuffer): void; - setInt(v: number, index?: number): void; - equalsTo(other: unknown): boolean; - clone(): ExifValue; + setDouble(v: number, index?: number): void; + equals(other: IfdValue): boolean; + clone(): IfdValue; + toString(): string; } } -declare module "exif/exif-value/exif-undefined-value" { +declare module "exif/ifd-value/ifd-double-value" { /** @format */ import { InputBuffer } from "common/input-buffer"; import { OutputBuffer } from "common/output-buffer"; - import { ExifValue } from "exif/exif-value/exif-value"; - import { ExifValueType } from "exif/exif-value-type"; - export class ExifUndefinedValue extends ExifValue { - private value; - get type(): ExifValueType; + import { IfdValue } from "exif/ifd-value/ifd-value"; + import { IfdValueType } from "exif/ifd-value-type"; + export class IfdDoubleValue extends IfdValue { + private _value; + get type(): IfdValueType; get length(): number; - constructor(value: Uint8Array | number); - static fromData(data: InputBuffer, offset?: number, length?: number): ExifUndefinedValue; + constructor(value: Float64Array | number); + static data(data: InputBuffer, length: number): IfdDoubleValue; + toDouble(index?: number): number; toData(): Uint8Array; - toString(): string; write(out: OutputBuffer): void; - equalsTo(other: unknown): boolean; - clone(): ExifValue; + setDouble(v: number, index?: number): void; + equals(other: IfdValue): boolean; + clone(): IfdValue; + toString(): string; } } -declare module "exif/exif-ifd" { +declare module "exif/ifd-directory" { /** @format */ import { Rational } from "common/rational"; - import { ExifIFDContainer } from "exif/exif-ifd-container"; - import { ExifValue } from "exif/exif-value/exif-value"; - export class ExifIFD { - private readonly data; + import { IfdContainer } from "exif/ifd-container"; + import { IfdValue } from "exif/ifd-value/ifd-value"; + import { TypedArray } from "common/typings"; + export class IfdDirectory { + private readonly _data; private readonly _sub; - get sub(): ExifIFDContainer; + get sub(): IfdContainer; get keys(): IterableIterator; - get values(): IterableIterator; + get values(): IterableIterator; get size(): number; get isEmpty(): boolean; + get hasUserComment(): boolean; + get userComment(): string | undefined; + set userComment(v: string | undefined); get hasImageDescription(): boolean; get imageDescription(): string | undefined; set imageDescription(v: string | undefined); @@ -1022,2341 +1933,4752 @@ declare module "exif/exif-ifd" { get hasCopyright(): boolean; get copyright(): string | undefined; set copyright(v: string | undefined); + /** + * The size in bytes of the data written by this directory. Can be used to + * calculate end-of-block offsets. + */ + get dataSize(): number; + constructor(data?: Map); private setRational; + static from(other: IfdDirectory): IfdDirectory; static isArrayOfRationalNumbers(value: unknown): boolean; has(tag: number): boolean; - getValue(tag: number | string): ExifValue | undefined; - setValue(tag: number | string, value: number[][] | Rational[] | number[] | Rational | ExifValue | undefined): void; + getValue(tag: number | string): IfdValue | undefined; + setValue(tag: number | string, value: Rational[] | number[] | TypedArray | Rational | IfdValue | number | undefined): void; + copyFrom(other: IfdDirectory): void; + clone(): IfdDirectory; + } +} +declare module "exif/ifd-container" { + /** @format */ + import { IfdDirectory } from "exif/ifd-directory"; + export class IfdContainer { + protected directories: Map; + get keys(): IterableIterator; + get values(): IterableIterator; + get size(): number; + get isEmpty(): boolean; + constructor(directories?: Map); + static from(other: IfdContainer): IfdContainer; + has(key: string): boolean; + get(ifdName: string): IfdDirectory; + set(ifdName: string, value: IfdDirectory): void; + clear(): void; } } declare module "exif/exif-data" { /** @format */ import { InputBuffer } from "common/input-buffer"; import { OutputBuffer } from "common/output-buffer"; - import { ExifIFD } from "exif/exif-ifd"; - import { ExifIFDContainer } from "exif/exif-ifd-container"; - import { ExifValue } from "exif/exif-value/exif-value"; - export class ExifData extends ExifIFDContainer { - get imageIfd(): ExifIFD; - get thumbnailIfd(): ExifIFD; - get exifIfd(): ExifIFD; - get gpsIfd(): ExifIFD; - get interopIfd(): ExifIFD; + import { IfdContainer } from "exif/ifd-container"; + import { IfdDirectory } from "exif/ifd-directory"; + import { IfdValue } from "exif/ifd-value/ifd-value"; + export class ExifData extends IfdContainer { + get imageIfd(): IfdDirectory; + get thumbnailIfd(): IfdDirectory; + get exifIfd(): IfdDirectory; + get gpsIfd(): IfdDirectory; + get interopIfd(): IfdDirectory; + get dataSize(): number; private writeDirectory; private writeDirectoryLargeValues; private readEntry; static from(other: ExifData): ExifData; static fromInputBuffer(input: InputBuffer): ExifData; hasTag(tag: number): boolean; - getTag(tag: number): ExifValue | undefined; + getTag(tag: number): IfdValue | undefined; getTagName(tag: number): string; write(out: OutputBuffer): void; read(block: InputBuffer): boolean; + clone(): ExifData; toString(): string; } } -declare module "common/memory-image" { +declare module "image/frame-type" { /** @format */ - import { ICCProfileData } from "common/icc-profile-data"; - import { RgbChannelSet } from "common/rgb-channel-set"; - import { DisposeMode } from "common/dispose-mode"; - import { BlendMode } from "common/blend-mode"; - import { ColorModel } from "common/color-model"; - import { Interpolation } from "common/interpolation"; - import { ExifData } from "exif/exif-data"; - export interface RgbMemoryImageInitOptions { - width: number; - height: number; - exifData?: ExifData; - iccProfile?: ICCProfileData; - textData?: Map; - } - export interface MemoryImageInitOptions extends RgbMemoryImageInitOptions { - rgbChannelSet?: RgbChannelSet; - data?: Uint32Array; - } - export interface MemoryImageInitOptionsColorModel { - width: number; - height: number; - data: Uint8Array; - rgbChannelSet?: RgbChannelSet; - exifData?: ExifData; - iccProfile?: ICCProfileData; - textData?: Map; - colorModel?: ColorModel; - } /** - * An image buffer where pixels are encoded into 32-bit unsigned ints (Uint32). - * - * Pixels are stored in 32-bit unsigned integers in #AARRGGBB format. - * You can use **getBytes** to access the pixel data at the byte (channel) level, - * optionally providing the format to get the image data as. You can use the - * letious color functions, such as **getRed**, **getGreen**, **getBlue**, and **getAlpha** - * to access the individual channels of a given pixel color. - * - * If this image is a frame of an animation as decoded by the **decodeFrame** - * method of **Decoder**, then the **xOffset**, **yOffset**, **width** and **height** - * determine the area of the canvas this image should be drawn into, - * as some frames of an animation only modify part of the canvas (recording - * the part of the frame that actually changes). The **decodeAnimation** method - * will always return the fully composed animation, so these coordinate - * properties are not used. + * The type of image this frame represents. Multi-page formats, such as + * TIFF, can represent the frames of an animation as pages in a document. */ - export class MemoryImage { - /** - * Pixels are encoded into 4-byte Uint32 integers in #AABBGGRR channel order. - */ - private readonly _data; - get data(): Uint32Array; - /** - * x position at which to render the frame. This is used for frames - * in an animation, such as from an animated GIF. - */ - private _xOffset; - get xOffset(): number; - /** - * y position at which to render the frame. This is used for frames - * in an animation, such as from an animated GIF. - */ - private _yOffset; - get yOffset(): number; - /** - * How long this frame should be displayed, in milliseconds. - * A duration of 0 indicates no delay and the next frame will be drawn - * as quickly as it can. - */ - private _duration; - set duration(v: number); - get duration(): number; - /** - * Defines what should be done to the canvas when drawing this frame - * in an animation. - */ - private _disposeMethod; - get disposeMethod(): DisposeMode; - /** - * Defines the blending method (alpha compositing) to use when drawing this - * frame in an animation. - */ - private _blendMethod; - get blendMethod(): BlendMode; + export enum FrameType { /** - * The channels used by this image, indicating whether the alpha channel - * is used or not. All images have an implicit alpha channel due to the - * image data being stored in a Uint32, but some images, such as those - * decoded from a Jpeg, don't use the alpha channel. This allows - * image encoders that support both rgb and rgba formats, to know which - * one it should use. + * The frames of this document are to be interpreted as animation. */ - private _rgbChannelSet; - get rgbChannelSet(): RgbChannelSet; + animation = 0, /** - * EXIF data decoded from an image file. + * The frames of this document are to be interpreted as pages of a document. */ - private _exifData; - get exifData(): ExifData; - set exifData(v: ExifData); + page = 1, /** - * ICC color profile read from an image file. + * The frames of this document are to be interpreted as a sequence of images. */ - private _iccProfile?; - set iccProfile(v: ICCProfileData | undefined); - get iccProfile(): ICCProfileData | undefined; + sequence = 2 + } +} +declare module "image/icc-profile-compression" { + /** @format */ + export enum IccProfileCompression { + none = 0, + deflate = 1 + } +} +declare module "image/icc-profile" { + import { IccProfileCompression } from "image/icc-profile-compression"; + /** + * ICC Profile data stored with an image. + */ + export class IccProfile { + private _name; + get name(): string; + private _compression; + get compression(): IccProfileCompression; + private _data; + get data(): Uint8Array; + constructor(name: string, compression: IccProfileCompression, data: Uint8Array); + static from(other: IccProfile): IccProfile; /** - * Some formats, like PNG, can encode and decode text data with the image. + * Returns the compressed data of the ICC Profile, compressing the stored data as necessary. */ - private _textData?; - get textData(): Map | undefined; + compressed(): Uint8Array; /** - * Width of the image. + * Returns the uncompressed data of the ICC Profile, decompressing the stored data as necessary. */ + decompressed(): Uint8Array; + clone(): IccProfile; + } +} +declare module "image/pixel-uint8" { + /** @format */ + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + import { MemoryImage } from "image/image"; + import { MemoryImageDataUint8 } from "image/image-data-uint8"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + export class PixelUint8 implements Pixel, Iterable, Iterator { + private _index; + private readonly _image; + get image(): MemoryImageDataUint8; + private _x; + get x(): number; + private _y; + get y(): number; + get xNormalized(): number; + get yNormalized(): number; + get index(): number; + set index(i: number); + get data(): Uint8Array; + get isValid(): boolean; + get width(): number; + get height(): number; + get length(): number; + get numChannels(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get format(): Format; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(x: number, y: number, index: number, image: MemoryImageDataUint8); + static imageData(image: MemoryImageDataUint8): PixelUint8; + static image(image: MemoryImage): PixelUint8; + static from(other: PixelUint8): PixelUint8; + next(): IteratorResult; + setPosition(x: number, y: number): void; + setPositionNormalized(x: number, y: number): void; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: Channel): number; + setChannel(channel: number, value: number): void; + set(color: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + equals(other: Pixel | number[]): boolean; + toArray(): number[]; + clone(): PixelUint8; + convert(opt: ColorConvertOptions): Color; + toString(): string; + [Symbol.iterator](): Iterator; + } +} +declare module "image/pixel-range-iterator" { + /** @format */ + import { Pixel } from "image/pixel"; + export class PixelRangeIterator implements Iterator { + private _pixel; + private _x1; + private _y1; + private _x2; + private _y2; + constructor(pixel: Pixel, x: number, y: number, width: number, height: number); + next(): IteratorResult; + [Symbol.iterator](): IterableIterator; + } +} +declare module "color/color-rgb8" { + /** @format */ + import { ColorUint8 } from "color/color-uint8"; + export class ColorRgb8 extends ColorUint8 { + constructor(r: number, g: number, b: number); + static from(other: ColorUint8): ColorUint8; + } +} +declare module "color/color-rgba8" { + /** @format */ + import { ColorUint8 } from "color/color-uint8"; + export class ColorRgba8 extends ColorUint8 { + constructor(r: number, g: number, b: number, a: number); + static from(other: ColorUint8): ColorUint8; + } +} +declare module "image/image-data-uint8" { + /** @format */ + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + import { PixelUint8 } from "image/pixel-uint8"; + export class MemoryImageDataUint8 implements MemoryImageData, Iterable { private readonly _width; get width(): number; - /** - * Height of the image. - */ private readonly _height; get height(): number; - /** - * The number of channels used by this Image. While all images - * are stored internally with 4 bytes, some images, such as those - * loaded from a Jpeg, don't use the 4th (alpha) channel. - */ - get numberOfChannels(): number; - /** - * The size of the image buffer. - */ + private readonly _data; + get data(): Uint8Array; + private readonly _numChannels; + get numChannels(): number; + get format(): Format; + get formatType(): FormatType; + get buffer(): ArrayBufferLike; + get rowStride(): number; + get iterator(): PixelUint8; + get byteLength(): number; get length(): number; - /** - * Create an image with the given dimensions and format. - */ - constructor(options: MemoryImageInitOptions); - private static convertData; - static rgb(options: RgbMemoryImageInitOptions): MemoryImage; - static from(other: MemoryImage): MemoryImage; - /** - * - * **format** defines the order of color channels in **data**. - * The length of **data** should be (width * height) * format-byte-count, - * where format-byte-count is 1, 3, or 4 depending on the number of - * channels in the format (luminance, rgb, rgba, etc). - * - * The native format of an image is Format.rgba. If another format - * is specified, the input data will be converted to rgba to store - * in the Image. - */ - static fromBytes(options: MemoryImageInitOptionsColorModel): MemoryImage; - /** - * Clone this image. - * */ - clone(): MemoryImage; - /** - * Get the bytes from the image. You can use this to access the - * color channels directly, or to pass it to something like an - * Html canvas context. - * - * Specifying the **format** will convert the image data to the specified - * format. Images are stored internally in Format.rgba format; any - * other format will require a conversion. - * - * For example, given an Html Canvas, you could draw this image into the - * canvas: - * Html.ImageData d = context2D.createImageData(image.width, image.height); - * d.data.setRange(0, image.length, image.getBytes(format: Format.rgba)); - * context2D.putImageData(data, 0, 0); - */ - getBytes(colorModel?: ColorModel): Uint8Array; - /** - * Set all of the pixels of the image to the given **color**. - */ - fill(color: number): MemoryImage; - /** - * Set all of the empty pixels (for png's) of the image to the given **color**. - */ - fillBackground(color: number): void; - /** - * Add the colors of **other** to the pixels of this image. - */ - addImage(other: MemoryImage): MemoryImage; - /** - * Subtract the colors of **other** from the pixels of this image. - */ - subtractImage(other: MemoryImage): MemoryImage; - /** - * Multiply the colors of **other** with the pixels of this image. - */ - multiplyImage(other: MemoryImage): MemoryImage; - /** - * OR the colors of **other** to the pixels of this image. - */ - orImage(other: MemoryImage): MemoryImage; - /** - * AND the colors of **other** with the pixels of this image. - */ - andImage(other: MemoryImage): MemoryImage; - /** - * Modula the colors of **other** with the pixels of this image. - */ - modImage(other: MemoryImage): MemoryImage; - /** - * Get a pixel from the buffer. No range checking is done. - */ - getPixelByIndex(index: number): number; - /** - * Set a pixel in the buffer. No range checking is done. - */ - setPixelByIndex(index: number, color: number): void; - /** - * Get the buffer index for the **x**, **y** pixel coordinates. - * No range checking is done. - */ - getBufferIndex(x: number, y: number): number; - /** - * Is the given **x**, **y** pixel coordinates within the resolution of the image. - */ - boundsSafe(x: number, y: number): boolean; - /** - * Get the pixel from the given **x**, **y** coordinate. Color is encoded in a - * Uint32 as #AABBGGRR. No range checking is done. - */ - getPixel(x: number, y: number): number; - /** - * Get the pixel from the given **x**, **y** coordinate. Color is encoded in a - * Uint32 as #AABBGGRR. If the pixel coordinates are out of bounds, 0 is - * returned. - */ - getPixelSafe(x: number, y: number): number; - /** - * Get the pixel using the given **interpolation** type for non-integer pixel - * coordinates. - */ - getPixelInterpolate(fx: number, fy: number, interpolation?: Interpolation): number; - /** - * Get the pixel using linear interpolation for non-integer pixel - * coordinates. - */ - getPixelLinear(fx: number, fy: number): number; - /** - * Get the pixel using cubic interpolation for non-integer pixel - * coordinates. - */ - getPixelCubic(fx: number, fy: number): number; - /** - * Set the pixel at the given **x**, **y** coordinate to the **color**. - * No range checking is done. - */ - setPixel(x: number, y: number, color: number): void; - /** - * Set the pixel at the given **x**, **y** coordinate to the **color**. - * If the pixel coordinates are out of bounds, nothing is done. - */ - setPixelSafe(x: number, y: number, color: number): void; - /** - * Set the pixel at the given **x**, **y** coordinate to the color - * **r**, **g**, **b**, **a**. - * - * This simply replaces the existing color, it does not do any alpha - * blending. Use **drawPixel** for that. No range checking is done. - */ - setPixelRgba(x: number, y: number, r: number, g: number, b: number, a?: number): void; - /** - * Return the average gray value of the image. - */ - getWhiteBalance(asDouble?: boolean): number; - /** - * Find the minimum and maximum color value in the image. - * Returns an object with **min** and **max** properties. - */ - getColorExtremes(): { - min: number; - max: number; - }; - addTextData(data: Map): void; + get maxChannelValue(): number; + get maxIndexValue(): number; + get hasPalette(): boolean; + private _palette?; + get palette(): Palette | undefined; + get isHdrFormat(): boolean; + get isLdrFormat(): boolean; + get bitsPerChannel(): number; + constructor(width: number, height: number, numChannels: number, data?: Uint8Array); + static palette(width: number, height: number, palette?: Palette): MemoryImageDataUint8; + static from(other: MemoryImageDataUint8, skipPixels?: boolean): MemoryImageDataUint8; + getRange(x: number, y: number, width: number, height: number): Iterator; + getColor(r: number, g: number, b: number, a?: number): Color; + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + setPixel(x: number, y: number, p: Color): void; + setPixelR(x: number, y: number, r: number): void; + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgbaSafe(x: number, y: number, r: number, g: number, b: number, a: number): void; + clear(c?: Color): void; + clone(skipPixels?: boolean): MemoryImageDataUint8; + toUint8Array(): Uint8Array; + getBytes(order?: ChannelOrder | undefined): Uint8Array; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "common/frame-animation" { +declare module "image/pixel-undefined" { /** @format */ - import { FrameType } from "common/frame-type"; - import { MemoryImage } from "common/memory-image"; - export interface FrameAnimationInitOptions { - width?: number; - height?: number; - loopCount?: number; - frameType?: FrameType; - } + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; /** - * Stores multiple images, most often as the frames of an animation. - * - * Some formats support multiple images that are not - * to be interpreted as animation, but rather multiple pages of a document. - * The **FrameAnimation** container is still used to store the images for these files. - * The **frameType** property is used to differentiate multi-page documents from - * multi-frame animations, where it is set to **FrameType.page** for documents - * and **FrameType.animation** for animated frames. - * - * All **Decoder** classes support decoding to an **FrameAnimation**, where the - * **FrameAnimation** will only contain a single frame for single image formats - * such as JPEG, or if the file doesn't contain any animation such as a single - * image GIF. If you want to generically support both animated and non-animated - * files, you can always decode to an animation and if the animation has only - * a single frame, then it's a non-animated image. - * - * In some cases, the frames of the animation may only provide a portion of the - * canvas, such as the case of animations encoding only the changing pixels - * from one frame to the next. The **width** and **height** and **backgroundColor** - * properties of the **FrameAnimation** provide information about the canvas that - * contains the animation, and the **MemoryImage** frames provide information about - * how to draw the particular frame, such as the area of the canvas to draw - * into, and if the canvas should be cleared prior to drawing the frame. + * Represents an invalid pixel. */ - export class FrameAnimation implements Iterable { - /** - * The canvas width for containing the animation. - */ - private _width; + export class PixelUndefined implements Pixel, Iterable, Iterator { + private static readonly _nullImageData; + get image(): MemoryImageData; + get isValid(): boolean; get width(): number; - /** - * The canvas height for containing the animation. - */ - private _height; get height(): number; - /** - * The suggested background color to clear the canvas with. - */ - private _backgroundColor; - get backgroundColor(): number; - /** - * How many times should the animation loop(0 means forever)? - */ - private _loopCount; - get loopCount(): number; - /** - * How should the frames be interpreted? If **FrameType.animation**, the - * frames are part of an animated sequence. If **FrameType.page**, the frames - * are the pages of a document. - */ - private _frameType; - get frameType(): FrameType; - /** - * The frames of the animation. - */ - private _frames; - get frames(): MemoryImage[]; - /** - * How many frames are in the animation? - */ - get numFrames(): number; - /** - * The first frame of the animation. - */ - get first(): MemoryImage; - /** - * The last frame of the animation. - */ - get last(): MemoryImage; - /** - * Is the animation empty(no frames)? - */ - get isEmpty(): boolean; - /** - * Returns true if there is at least one frame in the animation. - */ - get isNotEmpty(): boolean; - constructor(options?: FrameAnimationInitOptions); - /** - * Get the frame at the given **index**. - */ - getFrame(index: number): MemoryImage; - /** - * Add a frame to the animation. - */ - addFrame(image: MemoryImage): void; - /** - * Get the iterator for looping over the animation. - */ - [Symbol.iterator](): Iterator; - } -} -declare module "error/not-implemented-error" { - /** @format */ - /** - * An error thrown when some functionality has not yet been implemented. - */ - export class NotImplementedError extends Error { + get x(): number; + get y(): number; + get xNormalized(): number; + get yNormalized(): number; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get format(): Format; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get index(): number; + set index(_i: number); + get r(): number; + set r(_r: number); + get g(): number; + set g(_g: number); + get b(): number; + set b(_b: number); + get a(): number; + set a(_a: number); + get rNormalized(): number; + set rNormalized(_v: number); + get gNormalized(): number; + set gNormalized(_v: number); + get bNormalized(): number; + set bNormalized(_v: number); + get aNormalized(): number; + set aNormalized(_v: number); + get luminance(): number; + get luminanceNormalized(): number; + getChannel(_channel: number): number; + getChannelNormalized(_channel: Channel): number; + setChannel(_channel: number, _value: number): void; + set(_color: Color): void; + setRgb(_r: number, _g: number, _b: number): void; + setRgba(_r: number, _g: number, _b: number, _a: number): void; + clone(): Color; + convert(_options: ColorConvertOptions): Color; + setPosition(_x: number, _y: number): void; + setPositionNormalized(_x: number, _y: number): void; + equals(other: Pixel): boolean; + next(): IteratorResult; + toArray(): number[]; toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "hdr/half" { - /** - * A 16-bit floating-point number, used by high-dynamic-range image formats - * as a more efficient storage for floating-point values that don't require - * full 32-bit precision. A list of Half floats can be stored in a **Uint16Array**, - * and converted to a double using the **halfToDouble()** static method. - * - * This class is derived from the OpenEXR library. - */ - export class Half { - private static toFloatUint32; - private static toFloatFloat32; - private static eLut; - private bits; - constructor(bits: number); - private static convert; - private static halfToFloat; - private static fromBits; - static halfToDouble(bits: number): number; - static doubleToHalf(n: number): number; - /** - * Returns +infinity. - */ - static positiveInfinity(): Half; - /** - * Returns -infinity. - */ - static negativeInfinity(): Half; - /** - * Returns a NAN with the bit pattern 0111111111111111. - */ - static qNan(): Half; - /** - * Returns a NAN with the bit pattern 0111110111111111. - */ - static sNan(): Half; - toDouble(): number; - /** - * Unary minus - */ - unaryMinus(): Half; - /** - * Addition operator for Half or num left operands. - */ - add(other: Half | number): Half; +declare module "image/pixel" { + /** @format */ + import { Color } from "color/color"; + import { MemoryImageData } from "image/image-data"; + import { PixelUndefined } from "image/pixel-undefined"; + export interface Pixel extends Color, Iterator { /** - * Subtraction operator for Half or num left operands. + * The [MemoryImageData] this pixel refers to. */ - subtract(other: Half | number): Half; + get image(): MemoryImageData; /** - * Multiplication operator for Half or num left operands. + * True if this points to a valid pixel, otherwise false. */ - multiply(other: Half | number): Half; + get isValid(): boolean; /** - * Division operator for Half or num left operands. + * The width in pixels of the image data this pixel refers to. */ - divide(other: Half | number): Half; + get width(): number; /** - * Round to n-bit precision (n should be between 0 and 10). - * After rounding, the significand's 10-n least significant - * bits will be zero. + * The height in pixels of the image data this pixel refers to. */ - round(n: number): Half; + get height(): number; /** - * Returns true if h is a normalized number, a denormalized number or zero. + * The x coordinate of the pixel. */ - isFinite(): boolean; + get x(): number; /** - * Returns true if h is a normalized number. + * The y coordinate of the pixel. */ - isNormalized(): boolean; + get y(): number; /** - * Returns true if h is a denormalized number. + * The normalized x coordinate of the pixel, in the range [0, 1]. */ - isDenormalized(): boolean; + get xNormalized(): number; /** - * Returns true if h is zero. + * The normalized y coordinate of the pixel, in the range [0, 1]. */ - isZero(): boolean; + get yNormalized(): number; /** - * Returns true if h is a NAN. + * Set the coordinates of the pixel. */ - isNan(): boolean; + setPosition(x: number, y: number): void; /** - * Returns true if h is a positive or a negative infinity. + * Set the normalized coordinates of the pixel, in the range [0, 1]. */ - isInfinity(): boolean; + setPositionNormalized(x: number, y: number): void; /** - * Returns true if the sign bit of h is set (negative). + * Tests if this pixel has the same values as the given pixel or color. */ - isNegative(): boolean; - getBits(): number; - setBits(bits: number): void; - } -} -declare module "hdr/hdr-slice" { - import { TypedArray } from "common/typings"; - export interface HdrSliceInitOptions { - name: string; - width: number; - height: number; - format: number; - bitsPerSample: number; - data?: TypedArray; + equals(other: Pixel | number[]): boolean; } /** - * A slice is the data for an image framebuffer for a single channel. + * UndefinedPixel is used to represent an invalid pixel. */ - export class HdrSlice { - static UINT: number; - static INT: number; - static FLOAT: number; - private readonly _data; - /** - * **data** will be one of the type data lists, depending on the **type** and - * **bitsPerSample**. 16-bit FLOAT slices will be stored in a **Uint16Array**. - */ - get data(): TypedArray; - private readonly _name; - get name(): string; - private readonly _width; - get width(): number; - private readonly _height; - get height(): number; - /** - * Indicates the type of data stored by the slice, either **HdrSlice.INT**, - * **HdrSlice.FLOAT**, or **HdrSlice.UINT**. - */ - private readonly _format; - get format(): number; - /** - * How many bits per sample, either 8, 16, 32, or 64. - */ - private readonly _bitsPerSample; - get bitsPerSample(): number; - private get maxIntSize(); - /** - * Does this channel store floating-point data? - */ - get isFloat(): boolean; - constructor(options: HdrSliceInitOptions); - private static allocateDataForType; - /** - * Create a copy of the **other** HdrSlice. - */ - static from(other: HdrSlice): HdrSlice; - /** - * Get the raw bytes of the data buffer. - */ - getBytes(): Uint8Array; - /** - * Get the float value of the sample at the coordinates **x**,**y**. - * **Half** samples are converted to double. - */ - getFloat(x: number, y: number): number; - /** - * Set the float value of the sample at the coordinates **x**,**y** for - * **FLOAT** slices. - */ - setFloat(x: number, y: number, v: number): void; - /** - * Get the int value of the sample at the coordinates **x**,**y**. - * An exception will occur if the slice stores FLOAT data. - */ - getInt(x: number, y: number): number; - /** - * Set the int value of the sample at the coordinates **x**,**y** for **INT** and - * **UINT** slices. - */ - setInt(x: number, y: number, v: number): void; - } + export const UndefinedPixel: PixelUndefined; } -declare module "hdr/hdr-image" { +declare module "image/image-data" { /** @format */ - import { MemoryImage } from "common/memory-image"; - import { ExifData } from "exif/exif-data"; - import { HdrSlice } from "hdr/hdr-slice"; - /** - * A high dynamic range RGBA image stored in 16-bit or 32-bit floating-point - * channels. - */ - export class HdrImage { - /** - * Red value of a sample - */ - private static R; - /** - * Green value of a sample - */ - private static G; - /** - * Blue value of a sample - */ - private static B; + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + export interface MemoryImageData extends Iterable { + get width(): number; + get height(): number; + get numChannels(): number; /** - * Alpha/opacity + * The channel **Format** of the image. */ - private static A; + get format(): Format; /** - * Distance of the front of a sample from the viewer + * Whether the image has uint, int, or float data. */ - private static Z; - private readonly _slices; - get slices(): Map; - private _red; - get red(): HdrSlice | undefined; - private _green; - get green(): HdrSlice | undefined; - private _blue; - get blue(): HdrSlice | undefined; - private _alpha; - get alpha(): HdrSlice | undefined; - private _depth; - get depth(): HdrSlice | undefined; - private _exifData; - get exifData(): ExifData | undefined; - set exifData(v: ExifData | undefined); + get formatType(): FormatType; /** - * Does the image have any color channels? + * True if the image format is "high dynamic range." HDR formats include: + * float16, float32, float64, int8, int16, and int32. */ - get hasColor(): boolean; + get isHdrFormat(): boolean; /** - * Does the image have an alpha channel? + * True if the image format is "low dynamic range." LDR formats include: + * uint1, uint2, uint4, and uint8. */ - get hasAlpha(): boolean; + get isLdrFormat(): boolean; /** - * Does the image have a depth channel? + * The number of bits per color channel. Can be 1, 2, 4, 8, 16, 32, or 64. */ - get hasDepth(): boolean; + get bitsPerChannel(): number; /** - * The width of the framebuffer. + * The maximum value of a pixel channel, based on the **format** of the image. + * If the image has a **palette**, this will be the maximum value of a palette + * color channel. Float format images will have a **maxChannelValue** of 1, + * though they can have values above that. */ - get width(): number; + get maxChannelValue(): number; /** - * The height of the framebuffer. + * The maximum value of a palette index, based on the **format** of the image. + * This differs from **maxChannelValue** in that it will not be affected by + * the format of the **palette**. */ - get height(): number; + get maxIndexValue(): number; /** - * The number of bits per sample. + * True if the image has a palette. If the image has a palette, then the + * image data has 1 channel for the palette index of the pixel. */ - get bitsPerSample(): number; - get sampleFormat(): number; + get hasPalette(): boolean; /** - * The number of channels used by the image + * The **Palette** of the image, or undefined if the image does not have one. */ - get numberOfChannels(): number; + get palette(): Palette | undefined; /** - * Create an RGB[A] image. + * The size of the image data in bytes. */ - static create(width: number, height: number, channels: number, type: number, bitsPerSample: number): HdrImage; + get byteLength(): number; /** - * Create a copy of the **other** HdrImage. + * The size of the image data in bytes. */ - static from(other: HdrImage): HdrImage; + get length(): number; /** - * Create an HDR image from a LDR **MemoryImage** by transforming the channel values - * to the range [**0**, **1**]. + * The **ArrayBufferLike** storage of the image. */ - static fromImage(other: MemoryImage, type?: number, bitsPerSample?: number): HdrImage; + get buffer(): ArrayBufferLike; /** - * Get the value of the red channel at the given pixel coordinates **x**, **y**. + * The size, in bytes, of a row if pixels in the data. */ - getRed(x: number, y: number): number; + get rowStride(): number; /** - * Set the value of the red channel at the given pixel coordinates **x**, **y**. + * Returns a pixel iterator for iterating over a rectangular range of pixels + * in the image. */ - setRed(x: number, y: number, c: number): void; - setRedInt(x: number, y: number, c: number): void; + getRange(x: number, y: number, width: number, height: number): Iterator; /** - * Get the value of the green channel at the given pixel coordinates **x**, **y**. + * Create a **Color** object with the format and number of channels of the + * image. */ - getGreen(x: number, y: number): number; + getColor(r: number, g: number, b: number, a?: number): Color; /** - * Set the value of the green channel at the given pixel coordinates **x**, **y**. + * Return the **Pixel** at the given coordinates. If **pixel** is provided, + * it will be updated and returned rather than allocating a new **Pixel**. */ - setGreen(x: number, y: number, c: number): void; - setGreenInt(x: number, y: number, c: number): void; + getPixel(x: number, y: number, pixel?: Pixel): Pixel; /** - * Get the value of the blue channel at the given pixel coordinates **x**, **y**. + * Set the color of the pixel at the given coordinates to the color of the + * given Color **c**. */ - getBlue(x: number, y: number): number; + setPixel(x: number, y: number, c: Color): void; /** - * Set the value of the blue channel at the given pixel coordinates **x**, **y**. + * Set the red channel of the pixel, or the index value for palette images. */ - setBlue(x: number, y: number, c: number): void; - setBlueInt(x: number, y: number, c: number): void; + setPixelR(x: number, y: number, r: number): void; /** - * Get the value of the alpha channel at the given pixel coordinates **x**, **y**. + * Set the color of the **Pixel** at the given coordinates to the given + * color values **r**, **g**, **b**. */ - getAlpha(x: number, y: number): number; + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; /** - * Set the value of the alpha channel at the given pixel coordinates **x**, **y**. + * Set the color of the **Pixel** at the given coordinates to the given + * color values **r**, **g**, **b**, and **a**. */ - setAlpha(x: number, y: number, c: number): void; - setAlphaInt(x: number, y: number, c: number): void; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; /** - * Get the value of the depth channel at the given pixel coordinates **x**, **y**. + * Calls **setPixelRgb**, but ensures **x** and **y** are within the extents + * of the image, otherwise it returns without setting the pixel. */ - getDepth(x: number, y: number): number; + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; /** - * Set the value of the depth channel at the given pixel coordinates **x**, **y**. + * Calls **setPixelRgba**, but ensures **x** and **y** are within the extents + * of the image, otherwise it returns without setting the pixel. */ - setDepth(x: number, y: number, c: number): void; - setDepthInt(x: number, y: number, c: number): void; + setPixelRgbaSafe(x: number, y: number, r: number, g: number, b: number, a: number): void; /** - * Does this image contain the given channel? + * Set all of the pixels to the Color **c**, or all values to 0 if **c** is not + * given. */ - hasChannel(ch: string): boolean; + clear(c?: Color): void; /** - * Access a framebuffer slice by name. + * Get the copy of this image data. */ - getChannel(ch: string): HdrSlice | undefined; + clone(noPixels?: boolean): MemoryImageData; /** - * Add a channel **slice** to the + * The storage data of the image. */ - addChannel(slice: HdrSlice): void; + toUint8Array(): Uint8Array; /** - * Convert the framebuffer to an floating-point image, as a sequence of - * floats in RGBA order. + * Similar to toUint8Array, but will convert the channels of the image pixels + * to the given **order**. If that happens, the returned bytes will be a copy + * and not a direct view of the image data. */ - toFloatRgba(): Float32Array; - } -} -declare module "formats/bmp/bitmap-file-header" { - /** @format */ - import { InputBuffer } from "common/input-buffer"; - export class BitmapFileHeader { - static readonly BMP_HEADER_FILETYPE: number; - private readonly _fileLength; - get fileLength(): number; - private _offset; - set offset(v: number); - get offset(): number; - constructor(b: InputBuffer); - static isValidFile(b: InputBuffer): boolean; - toJson(): Map; + getBytes(order?: ChannelOrder): Uint8Array; } } -declare module "formats/decode-info" { +declare module "image/pixel-float16" { /** @format */ - /** - * Provides information about the image being decoded. - */ - export interface DecodeInfo { - /** - * The width of the image canvas. - */ - get width(): number; - /** - * The height of the image canvas. - */ + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + import { MemoryImage } from "image/image"; + import { MemoryImageDataFloat16 } from "image/image-data-float16"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + export class PixelFloat16 implements Pixel, Iterable, Iterator { + private _index; + private readonly _image; + get image(): MemoryImageDataFloat16; + private _x; + get x(): number; + private _y; + get y(): number; + get xNormalized(): number; + get yNormalized(): number; + get index(): number; + set index(i: number); + get data(): Uint16Array; + get isValid(): boolean; + get width(): number; get height(): number; - /** - * The suggested background color of the canvas. - */ - get backgroundColor(): number; - /** - * The number of frames that can be decoded. - */ - get numFrames(): number; + get length(): number; + get numChannels(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get format(): Format; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(x: number, y: number, index: number, image: MemoryImageDataFloat16); + static imageData(image: MemoryImageDataFloat16): PixelFloat16; + static image(image: MemoryImage): PixelFloat16; + static from(other: PixelFloat16): PixelFloat16; + next(): IteratorResult; + setPosition(x: number, y: number): void; + setPositionNormalized(x: number, y: number): void; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: Channel): number; + setChannel(channel: number, value: number): void; + set(color: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + equals(other: Pixel | number[]): boolean; + clone(): PixelFloat16; + convert(opt: ColorConvertOptions): Color; + [Symbol.iterator](): Iterator; + } +} +declare module "image/image-data-float16" { + /** @format */ + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + import { PixelFloat16 } from "image/pixel-float16"; + export class MemoryImageDataFloat16 implements MemoryImageData, Iterable { + private readonly _width; + get width(): number; + private readonly _height; + get height(): number; + private readonly _data; + get data(): Uint16Array; + private readonly _numChannels; + get numChannels(): number; + get format(): Format; + get formatType(): FormatType; + get buffer(): ArrayBufferLike; + get rowStride(): number; + get iterator(): PixelFloat16; + get byteLength(): number; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get isHdrFormat(): boolean; + get isLdrFormat(): boolean; + get bitsPerChannel(): number; + constructor(width: number, height: number, numChannels: number, data?: Uint16Array); + static from(other: MemoryImageDataFloat16, skipPixels?: boolean): MemoryImageDataFloat16; + getRange(x: number, y: number, width: number, height: number): Iterator; + getColor(r: number, g: number, b: number, a?: number): Color; + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + setPixel(x: number, y: number, p: Color): void; + setPixelR(x: number, y: number, r: number): void; + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgbaSafe(x: number, y: number, r: number, g: number, b: number, a: number): void; + clear(_c?: Color): void; + clone(skipPixels?: boolean): MemoryImageDataFloat16; + toUint8Array(): Uint8Array; + getBytes(order?: ChannelOrder | undefined): Uint8Array; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "formats/bmp/bitmap-compression-mode" { +declare module "image/pixel-float32" { /** @format */ - export enum BitmapCompressionMode { - BI_BITFIELDS = 0, - NONE = 1 + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + import { MemoryImage } from "image/image"; + import { MemoryImageDataFloat32 } from "image/image-data-float32"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + export class PixelFloat32 implements Pixel, Iterable, Iterator { + private _index; + private readonly _image; + get image(): MemoryImageDataFloat32; + private _x; + get x(): number; + private _y; + get y(): number; + get xNormalized(): number; + get yNormalized(): number; + get index(): number; + set index(i: number); + get data(): Float32Array; + get isValid(): boolean; + get width(): number; + get height(): number; + get length(): number; + get numChannels(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get format(): Format; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(x: number, y: number, index: number, image: MemoryImageDataFloat32); + static imageData(image: MemoryImageDataFloat32): PixelFloat32; + static image(image: MemoryImage): PixelFloat32; + static from(other: PixelFloat32): PixelFloat32; + next(): IteratorResult; + setPosition(x: number, y: number): void; + setPositionNormalized(x: number, y: number): void; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: Channel): number; + setChannel(channel: number, value: number): void; + set(color: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + equals(other: Pixel | number[]): boolean; + clone(): PixelFloat32; + convert(opt: ColorConvertOptions): Color; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "formats/bmp/bmp-info" { - import { InputBuffer } from "common/input-buffer"; - import { DecodeInfo } from "formats/decode-info"; - import { BitmapCompressionMode } from "formats/bmp/bitmap-compression-mode"; - import { BitmapFileHeader } from "formats/bmp/bitmap-file-header"; - export class BmpInfo implements DecodeInfo { +declare module "image/image-data-float32" { + /** @format */ + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + import { PixelFloat32 } from "image/pixel-float32"; + export class MemoryImageDataFloat32 implements MemoryImageData, Iterable { private readonly _width; get width(): number; - protected readonly _height: number; + private readonly _height; get height(): number; - private readonly _backgroundColor; - get backgroundColor(): number; - private readonly _numFrames; - get numFrames(): number; - private readonly _fileHeader; - get fileHeader(): BitmapFileHeader; - private readonly _headerSize; - get headerSize(): number; - private readonly _planes; - get planes(): number; - private readonly _bpp; - get bpp(): number; - private readonly _compression; - get compression(): BitmapCompressionMode; - private readonly _imageSize; - get imageSize(): number; - private readonly _xppm; - get xppm(): number; - private readonly _yppm; - get yppm(): number; - private readonly _totalColors; - get totalColors(): number; - private readonly _importantColors; - get importantColors(): number; - private readonly _readBottomUp; - get readBottomUp(): boolean; - private _v5redMask?; - get v5redMask(): number | undefined; - private _v5greenMask?; - get v5greenMask(): number | undefined; - private _v5blueMask?; - get v5blueMask(): number | undefined; - private _v5alphaMask?; - get v5alphaMask(): number | undefined; - private _colorPalette?; - get colorPalette(): number[] | undefined; - get ignoreAlphaChannel(): boolean; - constructor(p: InputBuffer, fileHeader?: BitmapFileHeader); - private static intToCompressionMode; - private compressionModeToString; - private readPalette; - private readRgba; - decodeRgba(input: InputBuffer, pixel: (color: number) => void): void; + private readonly _data; + get data(): Float32Array; + private readonly _numChannels; + get numChannels(): number; + get format(): Format; + get formatType(): FormatType; + get buffer(): ArrayBufferLike; + get rowStride(): number; + get iterator(): PixelFloat32; + get byteLength(): number; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get isHdrFormat(): boolean; + get isLdrFormat(): boolean; + get bitsPerChannel(): number; + constructor(width: number, height: number, numChannels: number, data?: Float32Array); + static from(other: MemoryImageDataFloat32, skipPixels?: boolean): MemoryImageDataFloat32; + getRange(x: number, y: number, width: number, height: number): Iterator; + getColor(r: number, g: number, b: number, a?: number): Color; + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + setPixel(x: number, y: number, p: Color): void; + setPixelR(x: number, y: number, r: number): void; + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgbaSafe(x: number, y: number, r: number, g: number, b: number, a: number): void; + clear(_c?: Color): void; + clone(skipPixels?: boolean): MemoryImageDataFloat32; + toUint8Array(): Uint8Array; + getBytes(order?: ChannelOrder | undefined): Uint8Array; toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "formats/decoder" { +declare module "image/pixel-float64" { /** @format */ - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; - import { HdrImage } from "hdr/hdr-image"; - import { DecodeInfo } from "formats/decode-info"; - /** - * Base class for image format decoders. - * - * Image pixels are stored as 32-bit unsigned ints, so all formats, regardless - * of their encoded color resolutions, decode to 32-bit RGBA images. Encoders - * can reduce the color resolution back down to their required formats. - * - * Some image formats support multiple frames, often for encoding animation. - * In such cases, the **decodeImage** method will decode the first (or otherwise - * specified with the **frame** parameter) frame of the file. **decodeAnimation** - * will decode all frames from the image. **startDecode** will initiate - * decoding of the file, and **decodeFrame** will then decode a specific frame - * from the file, allowing for animations to be decoded one frame at a time. - * Some formats, such as TIFF, may store multiple frames, but their use of - * frames is for multiple page documents and not animation. The terms - * 'animation' and 'frames' simply refer to 'pages' in this case. - * - * If an image file does not have multiple frames, **decodeAnimation** and - * **startDecode** / **decodeFrame** will return the single image of the - * file. As such, if you are not sure if a file is animated or not, you can - * use the animated functions and process it as a single frame image if it - * has only 1 frame, and as an animation if it has more than 1 frame. - * - * Most animated formats do not store full images for frames, but rather - * some frames will store full images and others will store partial 'change' - * images. For these files, **decodeAnimation** will always return all images - * fully composited, meaning full frame images. Decoding frames individually - * using **startDecode** and **decodeFrame** will return the potentially partial - * image. In this case, the **DecodeInfo** returned by **startDecode** will include - * the width and height resolution of the animation canvas, and each **MemoryImage** - * returned by **decodeFrame** will have x, y, width and height properties - * indicating where in the canvas the frame image should be drawn. It will - * also have a disposeMethod property that specifies what should be done to - * the canvas prior to drawing the frame: **DisposeMode.none** indicates the - * canvas should be left alone; **DisposeMode.clear** indicates the canvas - * should be cleared. For partial frame images,**DisposeMode.none** is used - * so that the partial-frame is drawn on top of the previous frame, applying - * it's changes to the image. - */ - export interface Decoder { - /** - * How many frames are available to be decoded. **startDecode** should have - * been called first. Non animated image files will have a single frame. - */ - get numFrames(): number; - /** - * A light-weight function to test if the given file is able to be decoded - * by this Decoder. - */ - isValidFile(bytes: Uint8Array): boolean; - /** - * Start decoding the data as an animation sequence, but don't actually - * process the frames until they are requested with decodeFrame. - */ - startDecode(bytes: Uint8Array): DecodeInfo | undefined; - /** - * Decode a single frame from the data that was set with **startDecode**. - * If **frame** is out of the range of available frames, undefined is returned. - * Non animated image files will only have **frame** 0. A **MemoryImage** - * is returned, which provides the image, and top-left coordinates of the - * image, as animated frames may only occupy a subset of the canvas. - */ - decodeFrame(frame: number): MemoryImage | undefined; - /** - * Decode a single high dynamic range (HDR) frame from the data that was set - * with **startDecode**. If the format of the file does not support HDR images, - * the regular image will be converted to an HDR image as (color / 255). - * If **frame** is out of the range of available frames, undefined is returned. - * Non animated image files will only have **frame** 0. A **MemoryImage** - * is returned, which provides the image, and top-left coordinates of the - * image, as animated frames may only occupy a subset of the canvas. - */ - decodeHdrFrame(frame: number): HdrImage | undefined; - /** - * Decode all of the frames from an animation. If the file is not an - * animation, a single frame animation is returned. If there was a problem - * decoding the file, undefined is returned. - */ - decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined; - /** - * Decode the file and extract a single image from it. If the file is - * animated, the specified **frame** will be decoded. If there was a problem - * decoding the file, undefined is returned. - */ - decodeImage(bytes: Uint8Array, frame?: number): MemoryImage | undefined; - /** - * Decode the file and extract a single High Dynamic Range (HDR) image from - * it. HDR images are stored in floating-poing values. If the format of the - * file does not support HDR images, the regular image will be converted to - * an HDR image as (color / 255). If the file is animated, the specified - * **frame** will be decoded. If there was a problem decoding the file, undefined is - * returned. - */ - decodeHdrImage(bytes: Uint8Array, frame?: number): HdrImage | undefined; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + import { MemoryImage } from "image/image"; + import { MemoryImageDataFloat64 } from "image/image-data-float64"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + export class PixelFloat64 implements Pixel, Iterable, Iterator { + private _index; + private readonly _image; + get image(): MemoryImageDataFloat64; + private _x; + get x(): number; + private _y; + get y(): number; + get xNormalized(): number; + get yNormalized(): number; + get index(): number; + set index(i: number); + get data(): Float64Array; + get isValid(): boolean; + get width(): number; + get height(): number; + get length(): number; + get numChannels(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get format(): Format; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(x: number, y: number, index: number, image: MemoryImageDataFloat64); + static imageData(image: MemoryImageDataFloat64): PixelFloat64; + static image(image: MemoryImage): PixelFloat64; + static from(other: PixelFloat64): PixelFloat64; + [Symbol.iterator](): Iterator; + next(): IteratorResult; + setPosition(x: number, y: number): void; + setPositionNormalized(x: number, y: number): void; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: Channel): number; + setChannel(channel: number, value: number): void; + set(color: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + equals(other: Pixel | number[]): boolean; + clone(): PixelFloat64; + convert(opt: ColorConvertOptions): Color; + toString(): string; } } -declare module "formats/bmp-decoder" { +declare module "image/image-data-float64" { /** @format */ - import { FrameAnimation } from "common/frame-animation"; - import { InputBuffer } from "common/input-buffer"; - import { MemoryImage } from "common/memory-image"; - import { HdrImage } from "hdr/hdr-image"; - import { BmpInfo } from "formats/bmp/bmp-info"; - import { Decoder } from "formats/decoder"; - export class BmpDecoder implements Decoder { - protected input?: InputBuffer; - protected info?: BmpInfo; - get numFrames(): number; - private pixelDataOffset; - /** - * Is the given file a valid BMP image? - */ - isValidFile(bytes: Uint8Array): boolean; - startDecode(bytes: Uint8Array): BmpInfo | undefined; - /** - * Decode a single frame from the data stat was set with **startDecode**. - * If **frame** is out of the range of available frames, undefined is returned. - * Non animated image files will only have **frame** 0. An **AnimationFrame** - * is returned, which provides the image, and top-left coordinates of the - * image, as animated frames may only occupy a subset of the canvas. - */ - decodeFrame(_: number): MemoryImage | undefined; - decodeHdrFrame(frame: number): HdrImage | undefined; - /** - * Decode all of the frames from an animation. If the file is not an - * animation, a single frame animation is returned. If there was a problem - * decoding the file, undefined is returned. - */ - decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined; - /** - * Decode the file and extract a single image from it. If the file is - * animated, the specified **frame** will be decoded. If there was a problem - * decoding the file, undefined is returned. - */ - decodeImage(bytes: Uint8Array, frame?: number): MemoryImage | undefined; - decodeHdrImage(bytes: Uint8Array, frame?: number): HdrImage | undefined; + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + import { PixelFloat64 } from "image/pixel-float64"; + export class MemoryImageDataFloat64 implements MemoryImageData, Iterable { + private readonly _width; + get width(): number; + private readonly _height; + get height(): number; + private readonly _data; + get data(): Float64Array; + private readonly _numChannels; + get numChannels(): number; + get format(): Format; + get formatType(): FormatType; + get buffer(): ArrayBufferLike; + get rowStride(): number; + get iterator(): PixelFloat64; + get byteLength(): number; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get isHdrFormat(): boolean; + get isLdrFormat(): boolean; + get bitsPerChannel(): number; + constructor(width: number, height: number, numChannels: number, data?: Float64Array); + static from(other: MemoryImageDataFloat64, skipPixels?: boolean): MemoryImageDataFloat64; + getRange(x: number, y: number, width: number, height: number): Iterator; + getColor(r: number, g: number, b: number, a?: number): Color; + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + setPixel(x: number, y: number, p: Color): void; + setPixelR(x: number, y: number, r: number): void; + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgbaSafe(x: number, y: number, r: number, g: number, b: number, a: number): void; + clear(_c?: Color): void; + clone(skipPixels?: boolean): MemoryImageDataFloat64; + toUint8Array(): Uint8Array; + getBytes(order?: ChannelOrder | undefined): Uint8Array; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "formats/encoder" { +declare module "image/pixel-int16" { /** @format */ - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; - /** - * Base class for image format encoders. - */ - export interface Encoder { - /** - * Does this encoder support animation? - */ - get supportsAnimation(): boolean; - /** - * Encode a single image. - */ - encodeImage(image: MemoryImage): Uint8Array; - /** - * Encode an animation. Not all formats support animation, and undefined - * will be returned if not. - */ - encodeAnimation(animation: FrameAnimation): Uint8Array | undefined; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + import { MemoryImage } from "image/image"; + import { MemoryImageDataInt16 } from "image/image-data-int16"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + export class PixelInt16 implements Pixel, Iterable, Iterator { + private _index; + private readonly _image; + get image(): MemoryImageDataInt16; + private _x; + get x(): number; + private _y; + get y(): number; + get xNormalized(): number; + get yNormalized(): number; + get index(): number; + set index(i: number); + get data(): Int16Array; + get isValid(): boolean; + get width(): number; + get height(): number; + get length(): number; + get numChannels(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get format(): Format; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(x: number, y: number, index: number, image: MemoryImageDataInt16); + static imageData(image: MemoryImageDataInt16): PixelInt16; + static image(image: MemoryImage): PixelInt16; + static from(other: PixelInt16): PixelInt16; + next(): IteratorResult; + setPosition(x: number, y: number): void; + setPositionNormalized(x: number, y: number): void; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: Channel): number; + setChannel(channel: number, value: number): void; + set(color: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + equals(other: Pixel | number[]): boolean; + clone(): PixelInt16; + convert(opt: ColorConvertOptions): Color; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "formats/bmp-encoder" { - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; - import { Encoder } from "formats/encoder"; - /** - * Encode a BMP image. - */ - export class BmpEncoder implements Encoder { - private _supportsAnimation; - get supportsAnimation(): boolean; - encodeImage(image: MemoryImage): Uint8Array; - encodeAnimation(_: FrameAnimation): Uint8Array | undefined; +declare module "image/image-data-int16" { + /** @format */ + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + import { PixelInt16 } from "image/pixel-int16"; + export class MemoryImageDataInt16 implements MemoryImageData, Iterable { + private readonly _width; + get width(): number; + private readonly _height; + get height(): number; + private readonly _data; + get data(): Int16Array; + private readonly _numChannels; + get numChannels(): number; + get format(): Format; + get formatType(): FormatType; + get buffer(): ArrayBufferLike; + get rowStride(): number; + get iterator(): PixelInt16; + get byteLength(): number; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get isHdrFormat(): boolean; + get isLdrFormat(): boolean; + get bitsPerChannel(): number; + constructor(width: number, height: number, numChannels: number, data?: Int16Array); + static from(other: MemoryImageDataInt16, skipPixels?: boolean): MemoryImageDataInt16; + getRange(x: number, y: number, width: number, height: number): Iterator; + getColor(r: number, g: number, b: number, a?: number): Color; + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + setPixel(x: number, y: number, p: Color): void; + setPixelR(x: number, y: number, r: number): void; + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgbaSafe(x: number, y: number, r: number, g: number, b: number, a: number): void; + clear(_c?: Color): void; + clone(skipPixels?: boolean): MemoryImageDataInt16; + toUint8Array(): Uint8Array; + getBytes(order?: ChannelOrder | undefined): Uint8Array; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "common/point" { - /** - * 2-dimensional point - * - * @format - */ - export class Point { +declare module "image/pixel-int32" { + /** @format */ + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + import { MemoryImage } from "image/image"; + import { MemoryImageDataInt32 } from "image/image-data-int32"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + export class PixelInt32 implements Pixel, Iterable, Iterator { + private _index; + private readonly _image; + get image(): MemoryImageDataInt32; private _x; - private _y; get x(): number; + private _y; get y(): number; - get xt(): number; - get yt(): number; - constructor(x: number, y: number); - static from(other: Point): Point; - move(x: number, y: number): Point; - offset(dx: number, dy: number): Point; - mul(n: number): Point; - add(p: Point): Point; - equals(other: unknown): boolean; - } -} -declare module "common/rectangle" { - export class Rectangle { - private _left; - private _top; - private _right; - private _bottom; - private _width; - private _height; - get left(): number; - get top(): number; - get right(): number; - get bottom(): number; + get xNormalized(): number; + get yNormalized(): number; + get index(): number; + set index(i: number); + get data(): Int32Array; + get isValid(): boolean; get width(): number; get height(): number; - constructor(x1: number, y1: number, x2: number, y2: number); - static fromXYWH(x: number, y: number, width: number, height: number): Rectangle; - static from(other: Rectangle): Rectangle; - private initialize; + get length(): number; + get numChannels(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get format(): Format; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(x: number, y: number, index: number, image: MemoryImageDataInt32); + static imageData(image: MemoryImageDataInt32): PixelInt32; + static image(image: MemoryImage): PixelInt32; + static from(other: PixelInt32): PixelInt32; + next(): IteratorResult; + setPosition(x: number, y: number): void; + setPositionNormalized(x: number, y: number): void; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: Channel): number; + setChannel(channel: number, value: number): void; + set(color: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + equals(other: Pixel | number[]): boolean; + clone(): PixelInt32; + convert(opt: ColorConvertOptions): Color; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "transform/flip-direction" { +declare module "image/image-data-int32" { /** @format */ - export enum FlipDirection { - /** - * Flip the image horizontally. - */ - horizontal = 0, - /** - * Flip the image vertically. - */ - vertical = 1, - /** - * Flip the image both horizontally and vertically. - */ - both = 2 + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + import { PixelInt32 } from "image/pixel-int32"; + export class MemoryImageDataInt32 implements MemoryImageData, Iterable { + private readonly _width; + get width(): number; + private readonly _height; + get height(): number; + private readonly _data; + get data(): Int32Array; + private readonly _numChannels; + get numChannels(): number; + get format(): Format; + get formatType(): FormatType; + get buffer(): ArrayBufferLike; + get rowStride(): number; + get iterator(): PixelInt32; + get byteLength(): number; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get isHdrFormat(): boolean; + get isLdrFormat(): boolean; + get bitsPerChannel(): number; + constructor(width: number, height: number, numChannels: number, data?: Int32Array); + static from(other: MemoryImageDataInt32, skipPixels?: boolean): MemoryImageDataInt32; + getRange(x: number, y: number, width: number, height: number): Iterator; + getColor(r: number, g: number, b: number, a?: number): Color; + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + setPixel(x: number, y: number, p: Color): void; + setPixelR(x: number, y: number, r: number): void; + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgbaSafe(x: number, y: number, r: number, g: number, b: number, a: number): void; + clear(_c?: Color): void; + clone(skipPixels?: boolean): MemoryImageDataInt32; + toUint8Array(): Uint8Array; + getBytes(order?: ChannelOrder | undefined): Uint8Array; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "transform/copy-resize-options" { +declare module "image/pixel-int8" { /** @format */ - import { Interpolation } from "common/interpolation"; - import { MemoryImage } from "common/memory-image"; - export interface CopyResizeOptionsUsingWidth { - image: MemoryImage; - width: number; - height?: number; - interpolation?: Interpolation; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + import { MemoryImage } from "image/image"; + import { MemoryImageDataInt8 } from "image/image-data-int8"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + export class PixelInt8 implements Pixel, Iterable, Iterator { + private _index; + private readonly _image; + get image(): MemoryImageDataInt8; + private _x; + get x(): number; + private _y; + get y(): number; + get xNormalized(): number; + get yNormalized(): number; + get index(): number; + set index(i: number); + get data(): Int8Array; + get isValid(): boolean; + get width(): number; + get height(): number; + get length(): number; + get numChannels(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get format(): Format; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(x: number, y: number, index: number, image: MemoryImageDataInt8); + static imageData(image: MemoryImageDataInt8): PixelInt8; + static image(image: MemoryImage): PixelInt8; + static from(other: PixelInt8): PixelInt8; + next(): IteratorResult; + setPosition(x: number, y: number): void; + setPositionNormalized(x: number, y: number): void; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: Channel): number; + setChannel(channel: number, value: number): void; + set(color: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + equals(other: Pixel | number[]): boolean; + clone(): PixelInt8; + convert(opt: ColorConvertOptions): Color; + toString(): string; + [Symbol.iterator](): Iterator; } - export interface CopyResizeOptionsUsingHeight { - image: MemoryImage; - height: number; - width?: number; - interpolation?: Interpolation; +} +declare module "image/image-data-int8" { + /** @format */ + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + import { PixelInt8 } from "image/pixel-int8"; + export class MemoryImageDataInt8 implements MemoryImageData, Iterable { + private readonly _width; + get width(): number; + private readonly _height; + get height(): number; + private readonly _data; + get data(): Int8Array; + private readonly _numChannels; + get numChannels(): number; + get format(): Format; + get formatType(): FormatType; + get buffer(): ArrayBufferLike; + get rowStride(): number; + get iterator(): PixelInt8; + get byteLength(): number; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get isHdrFormat(): boolean; + get isLdrFormat(): boolean; + get bitsPerChannel(): number; + constructor(width: number, height: number, numChannels: number, data?: Int8Array); + static from(other: MemoryImageDataInt8, skipPixels?: boolean): MemoryImageDataInt8; + getRange(x: number, y: number, width: number, height: number): Iterator; + getColor(r: number, g: number, b: number, a?: number): Color; + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + setPixel(x: number, y: number, p: Color): void; + setPixelR(x: number, y: number, r: number): void; + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgbaSafe(x: number, y: number, r: number, g: number, b: number, a: number): void; + clear(_c?: Color): void; + clone(skipPixels?: boolean): MemoryImageDataInt8; + toUint8Array(): Uint8Array; + getBytes(order?: ChannelOrder | undefined): Uint8Array; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "transform/copy-into-options" { +declare module "image/pixel-uint1" { /** @format */ - import { MemoryImage } from "common/memory-image"; - export interface CopyIntoOptions { - dst: MemoryImage; - src: MemoryImage; - dstX?: number; - dstY?: number; - srcX?: number; - srcY?: number; - srcW?: number; - srcH?: number; - blend?: boolean; - center?: boolean; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + import { MemoryImage } from "image/image"; + import { MemoryImageDataUint1 } from "image/image-data-uint1"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + export class PixelUint1 implements Pixel, Iterable, Iterator { + private _index; + private _bitIndex; + private _rowOffset; + private readonly _image; + get image(): MemoryImageDataUint1; + private _x; + get x(): number; + private _y; + get y(): number; + get xNormalized(): number; + get yNormalized(): number; + get index(): number; + set index(i: number); + get data(): Uint8Array; + get isValid(): boolean; + get width(): number; + get height(): number; + get length(): number; + get numChannels(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get format(): Format; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + get imageLength(): number; + constructor(x: number, y: number, index: number, bitIndex: number, rowOffset: number, image: MemoryImageDataUint1); + static imageData(image: MemoryImageDataUint1): PixelUint1; + static image(image: MemoryImage): PixelUint1; + static from(other: PixelUint1): PixelUint1; + private getChannelInternal; + next(): IteratorResult; + setPosition(x: number, y: number): void; + setPositionNormalized(x: number, y: number): void; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: Channel): number; + setChannel(channel: number, value: number): void; + set(color: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + toArray(): number[]; + equals(other: Pixel | number[]): boolean; + clone(): PixelUint1; + convert(opt: ColorConvertOptions): Color; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "common/line" { - export class Line { - private _startX; - private _startY; - private _endX; - private _endY; - private _dx; - private _dy; - get startX(): number; - get startY(): number; - get endX(): number; - get endY(): number; - get dx(): number; - get dy(): number; - constructor(x1: number, y1: number, x2: number, y2: number); - static from(other: Line): Line; - private initialize; - moveStart(x: number, y: number): void; - moveEnd(x: number, y: number): void; +declare module "image/image-data-uint1" { + /** @format */ + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + import { PixelUint1 } from "image/pixel-uint1"; + export class MemoryImageDataUint1 implements MemoryImageData, Iterable { + private pixel?; + private readonly _width; + get width(): number; + private readonly _height; + get height(): number; + private readonly _data; + get data(): Uint8Array; + private readonly _numChannels; + get numChannels(): number; + get format(): Format; + get formatType(): FormatType; + get buffer(): ArrayBufferLike; + private _rowStride; + get rowStride(): number; + get iterator(): PixelUint1; + get byteLength(): number; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get hasPalette(): boolean; + private _palette?; + get palette(): Palette | undefined; + get isHdrFormat(): boolean; + get isLdrFormat(): boolean; + get bitsPerChannel(): number; + constructor(width: number, height: number, numChannels: number, data?: Uint8Array); + static palette(width: number, height: number, palette?: Palette): MemoryImageDataUint1; + static from(other: MemoryImageDataUint1, skipPixels?: boolean): MemoryImageDataUint1; + getRange(x: number, y: number, width: number, height: number): Iterator; + getColor(r: number, g: number, b: number, a?: number): Color; + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + setPixel(x: number, y: number, p: Color): void; + setPixelR(x: number, y: number, r: number): void; + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgbaSafe(x: number, y: number, r: number, g: number, b: number, a: number): void; + clear(_c?: Color): void; + clone(skipPixels?: boolean): MemoryImageDataUint1; + toUint8Array(): Uint8Array; + getBytes(order?: ChannelOrder | undefined): Uint8Array; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "draw/draw-image-options" { +declare module "image/pixel-uint16" { /** @format */ - import { MemoryImage } from "common/memory-image"; - export interface DrawImageOptions { - dst: MemoryImage; - src: MemoryImage; - dstX?: number; - dstY?: number; - dstW?: number; - dstH?: number; - srcX?: number; - srcY?: number; - srcW?: number; - srcH?: number; - blend?: boolean; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + import { MemoryImage } from "image/image"; + import { MemoryImageDataUint16 } from "image/image-data-uint16"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + export class PixelUint16 implements Pixel, Iterable, Iterator { + private _index; + private readonly _image; + get image(): MemoryImageDataUint16; + private _x; + get x(): number; + private _y; + get y(): number; + get xNormalized(): number; + get yNormalized(): number; + get index(): number; + set index(i: number); + get data(): Uint16Array; + get isValid(): boolean; + get width(): number; + get height(): number; + get length(): number; + get numChannels(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get format(): Format; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(x: number, y: number, index: number, image: MemoryImageDataUint16); + static imageData(image: MemoryImageDataUint16): PixelUint16; + static image(image: MemoryImage): PixelUint16; + static from(other: PixelUint16): PixelUint16; + next(): IteratorResult; + setPosition(x: number, y: number): void; + setPositionNormalized(x: number, y: number): void; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: Channel): number; + setChannel(channel: number, value: number): void; + set(color: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + equals(other: Pixel | number[]): boolean; + toArray(): number[]; + clone(): PixelUint16; + convert(opt: ColorConvertOptions): Color; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "draw/draw-line-options" { +declare module "image/image-data-uint16" { /** @format */ - import { Line } from "common/line"; - import { MemoryImage } from "common/memory-image"; - export interface DrawLineOptions { - image: MemoryImage; - line: Line; - color: number; - antialias?: boolean; - thickness?: number; + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + import { PixelUint16 } from "image/pixel-uint16"; + export class MemoryImageDataUint16 implements MemoryImageData, Iterable { + private readonly _width; + get width(): number; + private readonly _height; + get height(): number; + private readonly _data; + get data(): Uint16Array; + private readonly _numChannels; + get numChannels(): number; + get format(): Format; + get formatType(): FormatType; + get buffer(): ArrayBufferLike; + get rowStride(): number; + get iterator(): PixelUint16; + get byteLength(): number; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get isHdrFormat(): boolean; + get isLdrFormat(): boolean; + get bitsPerChannel(): number; + constructor(width: number, height: number, numChannels: number, data?: Uint16Array); + static from(other: MemoryImageDataUint16, skipPixels?: boolean): MemoryImageDataUint16; + getRange(x: number, y: number, width: number, height: number): Iterator; + getColor(r: number, g: number, b: number, a?: number): Color; + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + setPixel(x: number, y: number, p: Color): void; + setPixelR(x: number, y: number, r: number): void; + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgbaSafe(x: number, y: number, r: number, g: number, b: number, a: number): void; + clear(_c?: Color): void; + clone(skipPixels?: boolean): MemoryImageDataUint16; + toUint8Array(): Uint8Array; + getBytes(order?: ChannelOrder | undefined): Uint8Array; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "draw/fill-flood-options" { +declare module "image/pixel-uint2" { /** @format */ - import { MemoryImage } from "common/memory-image"; - export interface FillFloodOptions { - src: MemoryImage; - x: number; - y: number; - color: number; - threshold?: number; - compareAlpha?: boolean; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + import { MemoryImage } from "image/image"; + import { MemoryImageDataUint2 } from "image/image-data-uint2"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + export class PixelUint2 implements Pixel, Iterable, Iterator { + private _index; + private _bitIndex; + private _rowOffset; + private readonly _image; + get image(): MemoryImageDataUint2; + private _x; + get x(): number; + private _y; + get y(): number; + get xNormalized(): number; + get yNormalized(): number; + get index(): number; + set index(i: number); + get data(): Uint8Array; + get isValid(): boolean; + get width(): number; + get height(): number; + get length(): number; + get numChannels(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get format(): Format; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + get bitsPerPixel(): number; + constructor(x: number, y: number, index: number, bitIndex: number, rowOffset: number, image: MemoryImageDataUint2); + static imageData(image: MemoryImageDataUint2): PixelUint2; + static image(image: MemoryImage): PixelUint2; + static from(other: PixelUint2): PixelUint2; + private getChannelInternal; + next(): IteratorResult; + setPosition(x: number, y: number): void; + setPositionNormalized(x: number, y: number): void; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: Channel): number; + setChannel(channel: number, value: number): void; + set(color: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + equals(other: Pixel | number[]): boolean; + toArray(): number[]; + clone(): PixelUint2; + convert(opt: ColorConvertOptions): Color; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "draw/mask-flood-options" { +declare module "image/image-data-uint2" { /** @format */ - import { MemoryImage } from "common/memory-image"; - export interface MaskFloodOptions { - src: MemoryImage; - x: number; - y: number; - threshold?: number; - compareAlpha?: boolean; - fillValue?: number; + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + import { PixelUint2 } from "image/pixel-uint2"; + export class MemoryImageDataUint2 implements MemoryImageData, Iterable { + private _pixel?; + private readonly _width; + get width(): number; + private readonly _height; + get height(): number; + private readonly _data; + get data(): Uint8Array; + private readonly _numChannels; + get numChannels(): number; + get format(): Format; + get formatType(): FormatType; + get buffer(): ArrayBufferLike; + private _rowStride; + get rowStride(): number; + get iterator(): PixelUint2; + get byteLength(): number; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get hasPalette(): boolean; + private _palette?; + get palette(): Palette | undefined; + get isHdrFormat(): boolean; + get isLdrFormat(): boolean; + get bitsPerChannel(): number; + constructor(width: number, height: number, numChannels: number, data?: Uint8Array); + static palette(width: number, height: number, palette?: Palette): MemoryImageDataUint2; + static from(other: MemoryImageDataUint2, skipPixels?: boolean): MemoryImageDataUint2; + getRange(x: number, y: number, width: number, height: number): Iterator; + getColor(r: number, g: number, b: number, a?: number): Color; + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + setPixel(x: number, y: number, p: Color): void; + setPixelR(x: number, y: number, r: number): void; + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgbaSafe(x: number, y: number, r: number, g: number, b: number, a: number): void; + clear(_c?: Color): void; + clone(skipPixels?: boolean): MemoryImageDataUint2; + toUint8Array(): Uint8Array; + getBytes(order?: ChannelOrder | undefined): Uint8Array; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "draw/draw" { - import { MemoryImage } from "common/memory-image"; - import { Point } from "common/point"; - import { Rectangle } from "common/rectangle"; - import { DrawImageOptions } from "draw/draw-image-options"; - import { DrawLineOptions } from "draw/draw-line-options"; - import { FillFloodOptions } from "draw/fill-flood-options"; - import { MaskFloodOptions } from "draw/mask-flood-options"; - export abstract class Draw { - private static readonly OUTCODE_INSIDE; - private static readonly OUTCODE_LEFT; - private static readonly OUTCODE_RIGHT; - private static readonly OUTCODE_BOTTOM; - private static readonly OUTCODE_TOP; - /** - * Calculate the pixels that make up the circumference of a circle on the - * given **image**, centered at **center** and the given **radius**. - * - * The returned list of points is sorted, first by the x coordinate, and - * second by the y coordinate. - */ - private static calculateCircumference; - /** - * Compute the bit code for a point **p** using the clip rectangle **rect** - */ - private static computeOutCode; - /** - * Clip a line to a rectangle using the Cohen–Sutherland clipping algorithm. - * **line** is a **Line** object. - * **rect** is a **Rectangle** object. - * Results are stored in **line**. - * If **line** falls completely outside of **rect**, false is returned, otherwise - * true is returned. - */ - private static clipLine; - private static testPixelLabColorDistance; - /** - * Adam Milazzo (2015). A More Efficient Flood Fill. - * http://www.adammil.net/blog/v126_A_More_Efficient_Flood_Fill.html - */ - private static fill4; - private static fill4Core; - /** - * Draw a circle into the **image** with a center of **center** and - * the given **radius** and **color**. - */ - static drawCircle(image: MemoryImage, center: Point, radius: number, color: number): MemoryImage; - /** - * Draw and fill a circle into the **image** with a **center** - * and the given **radius** and **color**. - * - * The algorithm uses the same logic as **drawCircle** to calculate each point - * around the circle's circumference. Then it iterates through every point, - * finding the smallest and largest y-coordinate values for a given x- - * coordinate. - * - * Once found, it draws a line connecting those two points. The circle is thus - * filled one vertical slice at a time (each slice being 1-pixel wide). - */ - static fillCircle(image: MemoryImage, center: Point, radius: number, color: number): MemoryImage; - /** - * Draw the image **src** onto the image **dst**. - * - * In other words, drawImage will take an rectangular area from **src** of - * width **srcW** and height **srcH** at position (**srcX**,**srY**) and place it - * in a rectangular area of **dst** of width **dstW** and height **dstH** at - * position (**dstX**,**dstY**). - * - * If the source and destination coordinates and width and heights differ, - * appropriate stretching or shrinking of the image fragment will be performed. - * The coordinates refer to the upper left corner. This function can be used to - * copy regions within the same image (if **dst** is the same as **src**) - * but if the regions overlap the results will be unpredictable. - */ - static drawImage(options: DrawImageOptions): MemoryImage; - /** - * Draw a line into **image**. - * - * If **antialias** is true then the line is drawn with smooth edges. - * **thickness** determines how thick the line should be drawn, in pixels. - */ - static drawLine(options: DrawLineOptions): MemoryImage; - /** - * Draw a single pixel into the image, applying alpha and opacity blending. - */ - static drawPixel(image: MemoryImage, pos: Point, color: number, opacity?: number): MemoryImage; - /** - * Draw a rectangle in the image **dst** with the **color**. - */ - static drawRect(dst: MemoryImage, rect: Rectangle, color: number): MemoryImage; - /** - * Fill the 4-connected shape containing **x**,**y** in the image **src** with the - * given **color**. - */ - static fillFlood(options: FillFloodOptions): MemoryImage; - /** - * Create a mask describing the 4-connected shape containing **x**,**y** in the - * image **src**. - */ - static maskFlood(options: MaskFloodOptions): Uint8Array; - /** - * Fill a rectangle in the image **src** with the given **color** with the - * coordinates defined by **rect**. - */ - static fillRect(src: MemoryImage, rect: Rectangle, color: number): MemoryImage; - /** - * Set all of the pixels of an **image** to the given **color**. - */ - static fill(image: MemoryImage, color: number): MemoryImage; +declare module "image/pixel-uint32" { + /** @format */ + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + import { MemoryImage } from "image/image"; + import { MemoryImageDataUint32 } from "image/image-data-uint32"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + export class PixelUint32 implements Pixel, Iterable, Iterator { + private _index; + private readonly _image; + get image(): MemoryImageDataUint32; + private _x; + get x(): number; + private _y; + get y(): number; + get xNormalized(): number; + get yNormalized(): number; + get index(): number; + set index(i: number); + get data(): Uint32Array; + get isValid(): boolean; + get width(): number; + get height(): number; + get length(): number; + get numChannels(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get format(): Format; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(x: number, y: number, index: number, image: MemoryImageDataUint32); + static imageData(image: MemoryImageDataUint32): PixelUint32; + static image(image: MemoryImage): PixelUint32; + static from(other: PixelUint32): PixelUint32; + next(): IteratorResult; + setPosition(x: number, y: number): void; + setPositionNormalized(x: number, y: number): void; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: Channel): number; + setChannel(channel: number, value: number): void; + set(color: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + equals(other: Pixel | number[]): boolean; + toArray(): number[]; + clone(): PixelUint32; + convert(opt: ColorConvertOptions): Color; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "transform/image-transform" { +declare module "image/image-data-uint32" { /** @format */ - import { MemoryImage } from "common/memory-image"; - import { Point } from "common/point"; - import { Rectangle } from "common/rectangle"; - import { FlipDirection } from "transform/flip-direction"; - import { CopyResizeOptionsUsingHeight, CopyResizeOptionsUsingWidth } from "transform/copy-resize-options"; - import { CopyIntoOptions } from "transform/copy-into-options"; - import { Interpolation } from "common/interpolation"; - export abstract class ImageTransform { - /** - * Returns a copy of the **src** image, rotated by **angle** degrees. - */ - static copyRotate(src: MemoryImage, angle: number, interpolation?: Interpolation): MemoryImage; - /** - * If **image** has an orientation value in its exif data, this will rotate the - * image so that it physically matches its orientation. This can be used to - * bake the orientation of the image for image formats that don't support exif - * data. - */ - static bakeOrientation(image: MemoryImage): MemoryImage; - /** - * Returns a resized copy of the **src** image. - * If **height** isn't specified, then it will be determined by the aspect - * ratio of **src** and **width**. - * If **width** isn't specified, then it will be determined by the aspect ratio - * of **src** and **height**. - */ - static copyResize(options: CopyResizeOptionsUsingWidth | CopyResizeOptionsUsingHeight): MemoryImage; - /** - * Returns a resized and square cropped copy of the **src** image of **size** size. - */ - static copyResizeCropSquare(src: MemoryImage, size: number): MemoryImage; - /** - * Copies a rectangular portion of one image to another image. **dst** is the - * destination image, **src** is the source image identifier. - * - * In other words, copyInto will take an rectangular area from **src** of - * width **srcW** and height **srcH** at position (**srcX**,**srcY**) and place it - * in a rectangular area of **dst** of width **dstW** and height **dstH** at - * position (**dstX**,**dstY**). - * - * If the source and destination coordinates and width and heights differ, - * appropriate stretching or shrinking of the image fragment will be performed. - * The coordinates refer to the upper left corner. This function can be used to - * copy regions within the same image (if **dst** is the same as **src**) - * but if the regions overlap the results will be unpredictable. - * - * **dstX** and **dstY** represent the X and Y position where the **src** will start - * printing. - * - * if **center** is true, the **src** will be centered in **dst**. - */ - static copyInto(options: CopyIntoOptions): MemoryImage; - /** - * Returns a cropped copy of **src**. - */ - static copyCrop(src: MemoryImage, x: number, y: number, w: number, h: number): MemoryImage; - /** - * Returns a round cropped copy of **src**. - */ - static copyCropCircle(src: MemoryImage, radius?: number, center?: Point): MemoryImage; - /** - * Returns a copy of the **src** image, where the given rectangle - * has been mapped to the full image. - */ - static copyRectify(src: MemoryImage, rect: Rectangle, toImage?: MemoryImage): MemoryImage; - /** - * Flips the **src** image using the given **mode**, which can be one of: - * **FlipDirection.horizontal**, **FlipDirection.vertical**, or **FlipDirection.both**. - */ - static flip(src: MemoryImage, direction: FlipDirection): MemoryImage; - /** - * Flip the **src** image vertically. - */ - static flipVertical(src: MemoryImage): MemoryImage; - /** - * Flip the src image horizontally. - */ - static flipHorizontal(src: MemoryImage): MemoryImage; - } -} -declare module "formats/gif/gif-color-map" { - export interface GifColorMapInitOptions { - numColors: number; - bitsPerPixel?: number; - colors?: Uint8Array; - transparent?: number; - } - export class GifColorMap { - private readonly _colors; - get colors(): Uint8Array; - private readonly _numColors; - get numColors(): number; - private readonly _bitsPerPixel; - get bitsPerPixel(): number; - private _transparent?; - set transparent(v: number | undefined); - get transparent(): number | undefined; - constructor(options: GifColorMapInitOptions); - private static bitSize; - static from(other: GifColorMap): GifColorMap; - getByte(index: number): number; - setByte(index: number, value: number): number; - getColor(index: number): number; - setColor(index: number, r: number, g: number, b: number): void; - getRed(color: number): number; - getGreen(color: number): number; - getBlue(color: number): number; - getAlpha(color: number): number; + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + import { PixelUint32 } from "image/pixel-uint32"; + export class MemoryImageDataUint32 implements MemoryImageData, Iterable { + private readonly _width; + get width(): number; + private readonly _height; + get height(): number; + private readonly _data; + get data(): Uint32Array; + private readonly _numChannels; + get numChannels(): number; + get format(): Format; + get formatType(): FormatType; + get buffer(): ArrayBufferLike; + get rowStride(): number; + get iterator(): PixelUint32; + get byteLength(): number; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get isHdrFormat(): boolean; + get isLdrFormat(): boolean; + get bitsPerChannel(): number; + constructor(width: number, height: number, numChannels: number, data?: Uint32Array); + static from(other: MemoryImageDataUint32, skipPixels?: boolean): MemoryImageDataUint32; + getRange(x: number, y: number, width: number, height: number): Iterator; + getColor(r: number, g: number, b: number, a?: number): Color; + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + setPixel(x: number, y: number, p: Color): void; + setPixelR(x: number, y: number, r: number): void; + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgbaSafe(x: number, y: number, r: number, g: number, b: number, a: number): void; + clear(_c?: Color): void; + clone(skipPixels?: boolean): MemoryImageDataUint32; + toUint8Array(): Uint8Array; + getBytes(order?: ChannelOrder | undefined): Uint8Array; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "formats/gif/gif-image-desc" { +declare module "image/pixel-uint4" { /** @format */ - import { InputBuffer } from "common/input-buffer"; - import { GifColorMap } from "formats/gif/gif-color-map"; - export class GifImageDesc { - private readonly _x; + import { Channel } from "color/channel"; + import { Color, ColorConvertOptions } from "color/color"; + import { Format } from "color/format"; + import { MemoryImage } from "image/image"; + import { MemoryImageDataUint4 } from "image/image-data-uint4"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + export class PixelUint4 implements Pixel, Iterable, Iterator { + private _index; + private _bitIndex; + private readonly _image; + get image(): MemoryImageDataUint4; + private _x; get x(): number; - private readonly _y; + private _y; get y(): number; - private readonly _width; + get xNormalized(): number; + get yNormalized(): number; + get index(): number; + set index(i: number); + get data(): Uint8Array; + get isValid(): boolean; get width(): number; - private readonly _height; get height(): number; - private readonly _interlaced; - get interlaced(): boolean; - private _colorMap?; - get colorMap(): GifColorMap | undefined; - set colorMap(v: GifColorMap | undefined); - private _duration; - set duration(v: number); - get duration(): number; - private _clearFrame; - set clearFrame(v: boolean); - get clearFrame(): boolean; - /** - * The position in the file after the ImageDesc for this frame. - */ - protected _inputPosition: number; - get inputPosition(): number; - constructor(input: InputBuffer); + get length(): number; + get numChannels(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get format(): Format; + get isLdrFormat(): boolean; + get isHdrFormat(): boolean; + get hasPalette(): boolean; + get palette(): Palette | undefined; + get r(): number; + set r(r: number); + get g(): number; + set g(g: number); + get b(): number; + set b(b: number); + get a(): number; + set a(a: number); + get rNormalized(): number; + set rNormalized(v: number); + get gNormalized(): number; + set gNormalized(v: number); + get bNormalized(): number; + set bNormalized(v: number); + get aNormalized(): number; + set aNormalized(v: number); + get luminance(): number; + get luminanceNormalized(): number; + constructor(x: number, y: number, index: number, bitIndex: number, image: MemoryImageDataUint4); + static imageData(image: MemoryImageDataUint4): PixelUint4; + static image(image: MemoryImage): PixelUint4; + static from(other: PixelUint4): PixelUint4; + private getChannelInternal; + next(): IteratorResult; + setPosition(x: number, y: number): void; + setPositionNormalized(x: number, y: number): void; + getChannel(channel: number | Channel): number; + getChannelNormalized(channel: Channel): number; + setChannel(channel: number, value: number): void; + set(color: Color): void; + setRgb(r: number, g: number, b: number): void; + setRgba(r: number, g: number, b: number, a: number): void; + equals(other: Pixel | number[]): boolean; + toArray(): number[]; + clone(): PixelUint4; + convert(opt: ColorConvertOptions): Color; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "formats/gif/gif-info" { +declare module "image/image-data-uint4" { /** @format */ - import { DecodeInfo } from "formats/decode-info"; - import { GifColorMap } from "formats/gif/gif-color-map"; - import { GifImageDesc } from "formats/gif/gif-image-desc"; - export interface GifInfoInitOptions { - width?: number; - height?: number; - backgroundColor?: number; - frames?: Array; - colorResolution?: number; - globalColorMap?: GifColorMap; - isGif89?: boolean; - } - export class GifInfo implements DecodeInfo { - private _width; + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + import { PixelUint4 } from "image/pixel-uint4"; + export class MemoryImageDataUint4 implements MemoryImageData, Iterable { + private _pixel?; + private readonly _width; get width(): number; - private _height; + private readonly _height; get height(): number; - private _backgroundColor; - get backgroundColor(): number; - private _frames; - get frames(): Array; - private _colorResolution; - get colorResolution(): number; - private _globalColorMap?; - get globalColorMap(): GifColorMap | undefined; - private _isGif89; - get isGif89(): boolean; - get numFrames(): number; - constructor(options?: GifInfoInitOptions); + private readonly _data; + get data(): Uint8Array; + private readonly _numChannels; + get numChannels(): number; + get format(): Format; + get formatType(): FormatType; + get buffer(): ArrayBufferLike; + private _rowStride; + get rowStride(): number; + get iterator(): PixelUint4; + get byteLength(): number; + get length(): number; + get maxChannelValue(): number; + get maxIndexValue(): number; + get hasPalette(): boolean; + private _palette?; + get palette(): Palette | undefined; + get isHdrFormat(): boolean; + get isLdrFormat(): boolean; + get bitsPerChannel(): number; + constructor(width: number, height: number, numChannels: number, data?: Uint8Array); + static palette(width: number, height: number, palette?: Palette): MemoryImageDataUint4; + static from(other: MemoryImageDataUint4, skipPixels?: boolean): MemoryImageDataUint4; + getRange(x: number, y: number, width: number, height: number): Iterator; + getColor(r: number, g: number, b: number, a?: number): Color; + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + setPixel(x: number, y: number, p: Color): void; + setPixelR(x: number, y: number, r: number): void; + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; + setPixelRgbaSafe(x: number, y: number, r: number, g: number, b: number, a: number): void; + clear(_c?: Color): void; + clone(skipPixels?: boolean): MemoryImageDataUint4; + toUint8Array(): Uint8Array; + getBytes(order?: ChannelOrder | undefined): Uint8Array; + toString(): string; + [Symbol.iterator](): Iterator; } } -declare module "formats/gif-decoder" { +declare module "image/palette-float16" { /** @format */ - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; - import { HdrImage } from "hdr/hdr-image"; - import { Decoder } from "formats/decoder"; - import { GifInfo } from "formats/gif/gif-info"; + import { Format } from "color/format"; + import { Palette } from "image/palette"; + export class PaletteFloat16 implements Palette { + private readonly _data; + get data(): Uint16Array; + private readonly _numColors; + get numColors(): number; + private readonly _numChannels; + get numChannels(): number; + get byteLength(): number; + get buffer(): ArrayBufferLike; + get format(): Format; + get maxChannelValue(): number; + constructor(numColors: number, numChannels: number, data?: Uint16Array); + static from(other: PaletteFloat16): PaletteFloat16; + setRgb(index: number, r: number, g: number, b: number): void; + setRgba(index: number, r: number, g: number, b: number, a: number): void; + set(index: number, channel: number, value: number): void; + get(index: number, channel: number): number; + getRed(index: number): number; + getGreen(index: number): number; + getBlue(index: number): number; + getAlpha(index: number): number; + setRed(index: number, value: number): void; + setGreen(index: number, value: number): void; + setBlue(index: number, value: number): void; + setAlpha(index: number, value: number): void; + clone(): PaletteFloat16; + toUint8Array(): Uint8Array; + } +} +declare module "image/palette-float32" { + /** @format */ + import { Format } from "color/format"; + import { Palette } from "image/palette"; + export class PaletteFloat32 implements Palette { + private readonly _data; + get data(): Float32Array; + private readonly _numColors; + get numColors(): number; + private readonly _numChannels; + get numChannels(): number; + get byteLength(): number; + get buffer(): ArrayBufferLike; + get format(): Format; + get maxChannelValue(): number; + constructor(numColors: number, numChannels: number, data?: Float32Array); + static from(other: PaletteFloat32): PaletteFloat32; + setRgb(index: number, r: number, g: number, b: number): void; + setRgba(index: number, r: number, g: number, b: number, a: number): void; + set(index: number, channel: number, value: number): void; + get(index: number, channel: number): number; + getRed(index: number): number; + getGreen(index: number): number; + getBlue(index: number): number; + getAlpha(index: number): number; + setRed(index: number, value: number): void; + setGreen(index: number, value: number): void; + setBlue(index: number, value: number): void; + setAlpha(index: number, value: number): void; + clone(): PaletteFloat32; + toUint8Array(): Uint8Array; + } +} +declare module "image/palette-float64" { + /** @format */ + import { Format } from "color/format"; + import { Palette } from "image/palette"; + export class PaletteFloat64 implements Palette { + private readonly _data; + get data(): Float64Array; + private readonly _numColors; + get numColors(): number; + private readonly _numChannels; + get numChannels(): number; + get byteLength(): number; + get buffer(): ArrayBufferLike; + get format(): Format; + get maxChannelValue(): number; + constructor(numColors: number, numChannels: number, data?: Float64Array); + static from(other: PaletteFloat64): PaletteFloat64; + setRgb(index: number, r: number, g: number, b: number): void; + setRgba(index: number, r: number, g: number, b: number, a: number): void; + set(index: number, channel: number, value: number): void; + get(index: number, channel: number): number; + getRed(index: number): number; + getGreen(index: number): number; + getBlue(index: number): number; + getAlpha(index: number): number; + setRed(index: number, value: number): void; + setGreen(index: number, value: number): void; + setBlue(index: number, value: number): void; + setAlpha(index: number, value: number): void; + clone(): PaletteFloat64; + toUint8Array(): Uint8Array; + } +} +declare module "image/palette-int16" { + /** @format */ + import { Format } from "color/format"; + import { Palette } from "image/palette"; + export class PaletteInt16 implements Palette { + private readonly _data; + get data(): Int16Array; + private readonly _numColors; + get numColors(): number; + private readonly _numChannels; + get numChannels(): number; + get byteLength(): number; + get buffer(): ArrayBufferLike; + get format(): Format; + get maxChannelValue(): number; + constructor(numColors: number, numChannels: number, data?: Int16Array); + static from(other: PaletteInt16): PaletteInt16; + setRgb(index: number, r: number, g: number, b: number): void; + setRgba(index: number, r: number, g: number, b: number, a: number): void; + set(index: number, channel: number, value: number): void; + get(index: number, channel: number): number; + getRed(index: number): number; + getGreen(index: number): number; + getBlue(index: number): number; + getAlpha(index: number): number; + setRed(index: number, value: number): void; + setGreen(index: number, value: number): void; + setBlue(index: number, value: number): void; + setAlpha(index: number, value: number): void; + clone(): PaletteInt16; + toUint8Array(): Uint8Array; + } +} +declare module "image/palette-int32" { + /** @format */ + import { Format } from "color/format"; + import { Palette } from "image/palette"; + export class PaletteInt32 implements Palette { + private readonly _data; + get data(): Int32Array; + private readonly _numColors; + get numColors(): number; + private readonly _numChannels; + get numChannels(): number; + get byteLength(): number; + get buffer(): ArrayBufferLike; + get format(): Format; + get maxChannelValue(): number; + constructor(numColors: number, numChannels: number, data?: Int32Array); + static from(other: PaletteInt32): PaletteInt32; + setRgb(index: number, r: number, g: number, b: number): void; + setRgba(index: number, r: number, g: number, b: number, a: number): void; + set(index: number, channel: number, value: number): void; + get(index: number, channel: number): number; + getRed(index: number): number; + getGreen(index: number): number; + getBlue(index: number): number; + getAlpha(index: number): number; + setRed(index: number, value: number): void; + setGreen(index: number, value: number): void; + setBlue(index: number, value: number): void; + setAlpha(index: number, value: number): void; + clone(): PaletteInt32; + toUint8Array(): Uint8Array; + } +} +declare module "image/palette-int8" { + /** @format */ + import { Format } from "color/format"; + import { Palette } from "image/palette"; + export class PaletteInt8 implements Palette { + private readonly _data; + get data(): Int8Array; + private readonly _numColors; + get numColors(): number; + private readonly _numChannels; + get numChannels(): number; + get byteLength(): number; + get buffer(): ArrayBufferLike; + get format(): Format; + get maxChannelValue(): number; + constructor(numColors: number, numChannels: number, data?: Int8Array); + static from(other: PaletteInt8): PaletteInt8; + setRgb(index: number, r: number, g: number, b: number): void; + setRgba(index: number, r: number, g: number, b: number, a: number): void; + set(index: number, channel: number, value: number): void; + get(index: number, channel: number): number; + getRed(index: number): number; + getGreen(index: number): number; + getBlue(index: number): number; + getAlpha(index: number): number; + setRed(index: number, value: number): void; + setGreen(index: number, value: number): void; + setBlue(index: number, value: number): void; + setAlpha(index: number, value: number): void; + clone(): PaletteInt8; + toUint8Array(): Uint8Array; + } +} +declare module "image/palette-uint16" { + /** @format */ + import { Format } from "color/format"; + import { Palette } from "image/palette"; + export class PaletteUint16 implements Palette { + private readonly _data; + get data(): Uint16Array; + private readonly _numColors; + get numColors(): number; + private readonly _numChannels; + get numChannels(): number; + get byteLength(): number; + get buffer(): ArrayBufferLike; + get format(): Format; + get maxChannelValue(): number; + constructor(numColors: number, numChannels: number, data?: Uint16Array); + static from(other: PaletteUint16): PaletteUint16; + setRgb(index: number, r: number, g: number, b: number): void; + setRgba(index: number, r: number, g: number, b: number, a: number): void; + set(index: number, channel: number, value: number): void; + get(index: number, channel: number): number; + getRed(index: number): number; + getGreen(index: number): number; + getBlue(index: number): number; + getAlpha(index: number): number; + setRed(index: number, value: number): void; + setGreen(index: number, value: number): void; + setBlue(index: number, value: number): void; + setAlpha(index: number, value: number): void; + clone(): PaletteUint16; + toUint8Array(): Uint8Array; + } +} +declare module "image/palette-uint32" { + /** @format */ + import { Format } from "color/format"; + import { Palette } from "image/palette"; + export class PaletteUint32 implements Palette { + private readonly _data; + get data(): Uint32Array; + private readonly _numColors; + get numColors(): number; + private readonly _numChannels; + get numChannels(): number; + get byteLength(): number; + get buffer(): ArrayBufferLike; + get format(): Format; + get maxChannelValue(): number; + constructor(numColors: number, numChannels: number, data?: Uint32Array); + static from(other: PaletteUint32): PaletteUint32; + setRgb(index: number, r: number, g: number, b: number): void; + setRgba(index: number, r: number, g: number, b: number, a: number): void; + set(index: number, channel: number, value: number): void; + get(index: number, channel: number): number; + getRed(index: number): number; + getGreen(index: number): number; + getBlue(index: number): number; + getAlpha(index: number): number; + setRed(index: number, value: number): void; + setGreen(index: number, value: number): void; + setBlue(index: number, value: number): void; + setAlpha(index: number, value: number): void; + clone(): PaletteUint32; + toUint8Array(): Uint8Array; + } +} +declare module "image/palette-uint8" { + /** @format */ + import { Format } from "color/format"; + import { Palette } from "image/palette"; + export class PaletteUint8 implements Palette { + private readonly _data; + get data(): Uint8Array; + private readonly _numColors; + get numColors(): number; + private readonly _numChannels; + get numChannels(): number; + get byteLength(): number; + get buffer(): ArrayBufferLike; + get format(): Format; + get maxChannelValue(): number; + constructor(numColors: number, numChannels: number, data?: Uint8Array); + static from(other: PaletteUint8): PaletteUint8; + setRgb(index: number, r: number, g: number, b: number): void; + setRgba(index: number, r: number, g: number, b: number, a: number): void; + set(index: number, channel: number, value: number): void; + get(index: number, channel: number): number; + getRed(index: number): number; + getGreen(index: number): number; + getBlue(index: number): number; + getAlpha(index: number): number; + setRed(index: number, value: number): void; + setGreen(index: number, value: number): void; + setBlue(index: number, value: number): void; + setAlpha(index: number, value: number): void; + clone(): PaletteUint8; + toUint8Array(): Uint8Array; + } +} +declare module "image/image" { + /** @format */ + import { ChannelOrder } from "color/channel-order"; + import { Color } from "color/color"; + import { Format, FormatType } from "color/format"; + import { Interpolation } from "common/interpolation"; + import { ExifData } from "exif/exif-data"; + import { FrameType } from "image/frame-type"; + import { IccProfile } from "image/icc-profile"; + import { MemoryImageData } from "image/image-data"; + import { Palette } from "image/palette"; + import { Pixel } from "image/pixel"; + interface MemoryImageInitializeOptions { + width: number; + height: number; + format?: Format; + numChannels?: number; + withPalette?: boolean; + paletteFormat?: Format; + palette?: Palette; + exifData?: ExifData; + iccProfile?: IccProfile; + } + export interface MemoryImageCreateOptions extends MemoryImageInitializeOptions { + loopCount?: number; + frameType?: FrameType; + frameDuration?: number; + frameIndex?: number; + backgroundColor?: Color; + textData?: Map; + } + export interface MemoryImageFromBytesOptions extends MemoryImageCreateOptions { + bytes: ArrayBufferLike; + rowStride?: number; + channelOrder?: ChannelOrder; + } + export interface MemoryImageCloneOptions { + skipAnimation?: boolean; + skipPixels?: boolean; + } + export interface MemoryImageConvertOptions { + format?: Format; + numChannels?: number; + alpha?: number; + withPalette?: boolean; + skipAnimation?: boolean; + } + export interface MemoryImageColorExtremes { + min: number; + max: number; + } /** - * A decoder for the GIF image format. This supports both single frame and - * animated GIF files, and transparency. + * A MemoryImage is a container for MemoryImageData and other various metadata + * representing an image in memory. */ - export class GifDecoder implements Decoder { - private static readonly STAMP_SIZE; - private static readonly GIF87_STAMP; - private static readonly GIF89_STAMP; - private static readonly IMAGE_DESC_RECORD_TYPE; - private static readonly EXTENSION_RECORD_TYPE; - private static readonly TERMINATE_RECORD_TYPE; - private static readonly GRAPHIC_CONTROL_EXT; - private static readonly APPLICATION_EXT; - private static readonly LZ_MAX_CODE; - private static readonly LZ_BITS; - private static readonly NO_SUCH_CODE; - private static readonly CODE_MASKS; - private static readonly INTERLACED_OFFSET; - private static readonly INTERLACED_JUMP; - private info?; - private input?; - private repeat; - private buffer?; - private stack; - private suffix; - private prefix?; - private bitsPerPixel; - private pixelCount?; - private currentShiftDWord; - private currentShiftState; - private stackPtr; - private currentCode?; - private lastCode; - private maxCode1; - private runningBits; - private runningCode; - private eofCode; - private clearCode; + export class MemoryImage implements Iterable { + private _data?; + get data(): MemoryImageData | undefined; + private get numPixelColors(); /** - * How many frames are available to decode? - * - * You should have prepared the decoder by either passing the file bytes - * to the constructor, or calling getInfo. + * The format of the image pixels. */ - get numFrames(): number; - constructor(bytes?: Uint8Array); + get format(): Format; /** - * Routine to trace the Prefixes linked list until we get a prefix which is - * not code, but a pixel value (less than ClearCode). Returns that pixel value. - * If image is defective, we might loop here forever, so we limit the loops to - * the maximum possible if image O.k. - LZ_MAX_CODE times. + * Indicates whether this image has a palette. */ - private static getPrefixChar; - private static updateImage; - private getInfo; - private skipImage; + get hasPalette(): boolean; /** - * Continue to get the image code in compressed form. This routine should be - * called until NULL block is returned. - * The block should NOT be freed by the user (not dynamically allocated). + * The palette if the image has one, undefined otherwise. */ - private skipRemainder; - private readApplicationExt; - private readGraphicsControlExt; - private decodeFrameImage; - private getLine; + get palette(): Palette | undefined; /** - * The LZ decompression routine: - * This version decompress the given gif file into Line of length LineLen. - * This routine can be called few times (one per scan line, for example), in - * order the complete the whole image. + * The number of color channels for the image. */ - private decompressLine; + get numChannels(): number; /** - * The LZ decompression input routine: - * This routine is responsible for the decompression of the bit stream from - * 8 bits (bytes) packets, into the real codes. + * Indicates whether this image is animated. + * An image is considered animated if it has more than one frame, as the + * first image in the frames list is the image itself. */ - private decompressInput; + get hasAnimation(): boolean; /** - * This routines read one gif data block at a time and buffers it internally - * so that the decompression routine could access it. - * The routine returns the next byte from its internal buffer (or read next - * block in if buffer empty) and returns undefined on failure. + * The number of frames in this MemoryImage. A MemoryImage will have at least one + * frame, itself, so it's considered animated if it has more than one + * frame. */ - private bufferedInput; - private initDecode; + get numFrames(): number; + private _exifData?; /** - * Is the given file a valid Gif image? + * The EXIF metadata for the image. If an ExifData hasn't been created + * for the image yet, one will be added. */ - isValidFile(bytes: Uint8Array): boolean; + get exifData(): ExifData; + set exifData(exif: ExifData); /** - * Validate the file is a Gif image and get information about it. - * If the file is not a valid Gif image, undefined is returned. + * The maximum value of a pixel channel, based on the format of the image. + * If the image has a **palette**, this will be the maximum value of a palette + * color channel. Float format images will have a **maxChannelValue** of 1, + * though they can have values above that. */ - startDecode(bytes: Uint8Array): GifInfo | undefined; - decodeFrame(frame: number): MemoryImage | undefined; - decodeHdrFrame(frame: number): HdrImage | undefined; + get maxChannelValue(): number; /** - * Decode all of the frames of an animated gif. For single image gifs, - * this will return an animation with a single frame. + * The maximum value of a palette index, based on the format of the image. + * This differs from **maxChannelValue** in that it will not be affected by + * the format of the **palette**. */ - decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined; - decodeImage(bytes: Uint8Array, frame?: number): MemoryImage | undefined; - decodeHdrImage(bytes: Uint8Array, frame?: number): HdrImage | undefined; - } -} -declare module "common/dither-kernel" { - /** @format */ - export enum DitherKernel { - None = 0, - FalseFloydSteinberg = 1, - FloydSteinberg = 2, - Stucki = 3, - Atkinson = 4 - } -} -declare module "common/quantizer" { - /** @format */ - export interface Quantizer { + get maxIndexValue(): number; /** - * Find the index of the closest color to **c** in the **colorMap**. + * Indicates whether this image supports using a palette. */ - getQuantizedColor(c: number): number; - } -} -declare module "common/neural-quantizer" { - import { MemoryImage } from "common/memory-image"; - import { Quantizer } from "common/quantizer"; - /** - * Compute a color map with a given number of colors that best represents - * the given image. - */ - export class NeuralQuantizer implements Quantizer { - private static readonly numCycles; - private static readonly alphaBiasShift; - private static readonly initAlpha; - private static readonly radiusBiasShift; - private static readonly radiusBias; - private static readonly alphaRadiusBiasShift; - private static readonly alphaRadiusBias; - private static readonly radiusDec; - private static readonly gamma; - private static readonly beta; - private static readonly betaGamma; - private static readonly prime1; - private static readonly prime2; - private static readonly prime3; - private static readonly prime4; - private static readonly smallImageBytes; - private readonly netIndex; - private samplingFactor; - private netSize; - private specials; - private bgColor; - private cutNetSize; - private maxNetPos; - private initRadius; - private initBiasRadius; - private radiusPower; + get supportsPalette(): boolean; /** - * The network itself + * The width of the image in pixels. */ - private network; - private _colorMap8; - get colorMap8(): Uint8Array; - private _colorMap32; - get colorMap32(): Int32Array; + get width(): number; /** - * Bias array for learning + * The height of the image in pixels. */ - private bias; - private freq; + get height(): number; /** - * How many colors are in the **colorMap**? + * The general type of the format, whether it's uint data, int data, or + * float data (regardless of precision). */ - get numColors(): number; + get formatType(): FormatType; /** - * 10 is a reasonable **samplingFactor** according to - * https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/. + * Indicates whether this image is valid and has data. */ - constructor(image: MemoryImage, numberOfColors?: number, samplingFactor?: number); - private initialize; - private updateRadiusPower; - private specialFind; + get isValid(): boolean; /** - * Search for biased BGR values + * The ArrayBufferLike of the image storage data or undefined if not initialized. */ - private contest; - private alterSingle; - private alterNeighbors; - private learn; - private fix; + get buffer(): ArrayBufferLike | undefined; /** - * Insertion sort of network and building of netindex[0..255] + * The length in bytes of the image data buffer. */ - private inxBuild; - private copyColorMap; + get byteLength(): number; /** - * Add an image to the quantized color table. + * The length in bytes of a row of pixels in the image buffer. */ - private addImage; + get rowStride(): number; /** - * Search for BGR values 0..255 and return color index + * Indicates whether this image is a Low Dynamic Range (regular) image. */ - private inxSearch; + get isLdrFormat(): boolean; /** - * Get a color from the **colorMap**. + * Indicates whether this image is a High Dynamic Range image. */ - color(index: number): number; + get isHdrFormat(): boolean; /** - * Find the index of the closest color to **c** in the **colorMap**. + * The number of bits per color channel. */ - lookup(c: number): number; + get bitsPerChannel(): number; /** - * Find the index of the closest color to **r**,**g**,**b** in the **colorMap**. + * Indicates whether this MemoryImage has an alpha channel. */ - lookupRGB(r: number, g: number, b: number): number; + get hasAlpha(): boolean; /** - * Find the color closest to **c** in the **colorMap**. + * Named non-color channels used by this image. */ - getQuantizedColor(c: number): number; + private _extraChannels?; + private _iccProfile; + get iccProfile(): IccProfile | undefined; + set iccProfile(v: IccProfile | undefined); + private _textData; + get textData(): Map | undefined; + private _backgroundColor?; /** - * Convert the **image** to an index map, mapping to this **colorMap**. + * The suggested background color to clear the canvas with. */ - getIndexMap(image: MemoryImage): Uint8Array; - } -} -declare module "common/dither-pixel" { - /** @format */ - import { DitherKernel } from "common/dither-kernel"; - import { MemoryImage } from "common/memory-image"; - import { NeuralQuantizer } from "common/neural-quantizer"; - export abstract class DitherPixel { - private static ditherKernels; - static getDitherPixels(image: MemoryImage, quantizer: NeuralQuantizer, kernel: DitherKernel, serpentine: boolean): Uint8Array; - } -} -declare module "formats/gif-encoder" { - /** @format */ - import { DitherKernel } from "common/dither-kernel"; - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; - import { Encoder } from "formats/encoder"; - export interface GifEncoderInitOptions { - delay?: number; - repeat?: number; - samplingFactor?: number; - dither?: DitherKernel; - ditherSerpentine?: boolean; - } - export class GifEncoder implements Encoder { - private static readonly gif89Id; - private static readonly imageDescRecordType; - private static readonly extensionRecordType; - private static readonly terminateRecordType; - private static readonly applicationExt; - private static readonly graphicControlExt; - private static readonly eof; - private static readonly bits; - private static readonly hsize; - private static readonly masks; - private lastImage?; - private lastImageDuration?; - private lastColorMap?; - private width; - private height; - private encodedFrames; - private curAccum; - private curBits; - private nBits; - private initBits; - private EOFCode; - private maxCode; - private clearCode; - private freeEnt; - private clearFlag; - private block; - private blockSize; - private outputBuffer?; - private delay; - private repeat; - private samplingFactor; - private dither; - private ditherSerpentine; + get backgroundColor(): Color | undefined; + set backgroundColor(v: Color | undefined); + private _loopCount; /** - * Does this encoder support animation? + * How many times should the animation loop (0 means forever) */ - private readonly _supportsAnimation; - get supportsAnimation(): boolean; - constructor(options?: GifEncoderInitOptions); - private addImage; - private encodeLZW; - private output; - private writeBlock; - private addToBlock; - private writeApplicationExt; - private writeGraphicsCtrlExt; - private writeHeader; + get loopCount(): number; + set loopCount(v: number); + private _frameType; /** - * Encode the images that were added with **addFrame**. - * After this has been called (returning the finishes GIF), - * calling **addFrame** for a new animation or image is safe again. + * Gets or sets how should the frames be interpreted. + * If the **frameType** is _FrameType.animation_, the frames are part + * of an animated sequence. If the **frameType** is _FrameType.page_, + * the frames are the pages of a document. + */ + get frameType(): FrameType; + set frameType(v: FrameType); + /** + * The list of sub-frames for the image, if it's an animation. An image + * is considered animated if it has more than one frame, as the first + * frame will be the image itself. + */ + private _frames; + get frames(): MemoryImage[]; + private _frameDuration; + /** + * How long this frame should be displayed, in milliseconds. + * A duration of 0 indicates no delay and the next frame will be drawn + * as quickly as it can. + */ + get frameDuration(): number; + set frameDuration(v: number); + /** + * Index of this image in the parent animations frame list. + */ + private _frameIndex; + get frameIndex(): number; + constructor(opt?: MemoryImageCreateOptions); + static fromResized(other: MemoryImage, width: number, height: number, skipAnimation?: boolean): MemoryImage; + /** + * Creates a copy of the given **other** MemoryImage. + */ + static from(other: MemoryImage, skipAnimation?: boolean, skipPixels?: boolean): MemoryImage; + /** + * Create an image from raw data in **bytes**. * - * **addFrame** will not encode the first image passed and after that - * always encode the previous image. Hence, the last image needs to be - * encoded here. + * **format** defines the order of color channels in **bytes**. + * An HTML canvas element stores colors in _Format.rgba_ format; + * a MemoryImage object stores colors in _Format.rgba_ format. + * + * **rowStride** is the row stride, in bytes, of the source data **bytes**. + * This may be different than the rowStride of the MemoryImage, as some data + * sources align rows to different byte alignments and include padding. + * + * **order** can be used if the source **bytes** has a different channel order + * than RGBA. _ChannelOrder.bgra_ will rearrange the color channels from + * BGRA to what MemoryImage wants, RGBA. + * + * If **numChannels** and **order** are not provided, a default of 3 for + * **numChannels** and _ChannelOrder.rgba_ for **order** will be assumed. */ - private finish; + static fromBytes(opt: MemoryImageFromBytesOptions): MemoryImage; + private initialize; + private createImageData; + private createPalette; /** - * This adds the frame passed to **image**. - * After the last frame has been added, **finish** is required to be called. - * Optional frame **duration** is in 1/100 sec. - * */ - addFrame(image: MemoryImage, duration?: number): void; + * Add a frame to the animation of this MemoryImage. + */ + addFrame(image?: MemoryImage): MemoryImage; /** - * Encode a single frame image. + * Get a frame from this image. If the MemoryImage is not animated, this + * MemoryImage will be returned; otherwise the particular frame MemoryImage will + * be returned. + */ + getFrame(index: number): MemoryImage; + /** + * Create a copy of this image. + */ + clone(opt?: MemoryImageCloneOptions): MemoryImage; + hasExtraChannel(name: string): boolean; + getExtraChannel(name: string): MemoryImageData | undefined; + setExtraChannel(name: string, data?: MemoryImageData): void; + /** + * Returns a pixel iterator for iterating over a rectangular range of pixels + * in the image. + */ + getRange(x: number, y: number, width: number, height: number): Iterator; + /** + * Get a Uint8Array view of the image storage data. + */ + toUint8Array(): Uint8Array; + /** + * Similar to **toUint8Array**, but will convert the channels of the image pixels + * to the given **order**. If that happens, the returned bytes will be a copy + * and not a direct view of the image data. + */ + getBytes(order?: ChannelOrder): Uint8Array; + /** + * Remap the color channels to the given **order**. Normally MemoryImage color + * channels are stored in rgba order for 4 channel images, and + * rgb order for 3 channel images. This method lets you re-arrange the + * color channels in-place without needing to clone the image for preparing + * image data for external usage that requires alternative channel ordering. + */ + remapChannels(order: ChannelOrder): void; + /** + * Returns true if the given pixel coordinates is within the dimensions + * of the image. + */ + isBoundsSafe(x: number, y: number): boolean; + /** + * Create a Color object with the format and number of channels of the + * image. + */ + getColor(r: number, g: number, b: number, a?: number): Color; + /** + * Return the Pixel at the given coordinates **x**,**y**. If **pixel** is provided, + * it will be updated and returned rather than allocating a new Pixel. + */ + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + /** + * Get the pixel from the given **x**, **y** coordinate. If the pixel coordinates + * are out of bounds, PixelUndefined is returned. + */ + getPixelSafe(x: number, y: number, pixel?: Pixel): Pixel; + /** + * Get the pixel from the given **x**, **y** coordinate. If the pixel coordinates + * are out of range of the image, they will be clamped to the resolution. + */ + getPixelClamped(x: number, y: number, pixel?: Pixel): Pixel; + /** + * Get the pixel using the given **interpolation** type for non-integer pixel + * coordinates. + */ + getPixelInterpolate(fx: number, fy: number, interpolation?: Interpolation): Color; + /** + * Get the pixel using linear interpolation for non-integer pixel + * coordinates. + */ + getPixelLinear(fx: number, fy: number): Color; + /** + * Get the pixel using cubic interpolation for non-integer pixel + * coordinates. + */ + getPixelCubic(fx: number, fy: number): Color; + /** + * Set the color of the pixel at the given coordinates to the color of the + * given Color **c**. + */ + setPixel(x: number, y: number, c: Color | Pixel): void; + /** + * Set the index value for palette images, or the red channel otherwise. + */ + setPixelIndex(x: number, y: number, i: number): void; + /** + * Set the red (or index) color channel of a pixel. + */ + setPixelR(x: number, y: number, i: number): void; + /** + * Set the color of the Pixel at the given coordinates to the given + * color values **r**, **g**, **b**. + */ + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + /** + * Set the color of the Pixel at the given coordinates to the given + * color values **r**, **g**, **b**, and **a**. */ - encodeImage(image: MemoryImage): Uint8Array; + setPixelRgba(x: number, y: number, r: number, g: number, b: number, a: number): void; /** - * Encode an animation. + * Set all pixels in the image to the given **color**. If no color is provided + * the image will be initialized to 0. */ - encodeAnimation(animation: FrameAnimation): Uint8Array | undefined; + clear(color?: Color): void; + /** + * Convert this image to a new **format** or number of channels, **numChannels**. + * If the new number of channels is 4 and the current image does + * not have an alpha channel, then the given **alpha** value will be used + * to set the new alpha channel. If **alpha** is not provided, then the + * **maxChannelValue** will be used to set the alpha. If **withPalette** is + * true, and to target format and **numChannels** has fewer than 256 colors, + * then the new image will be converted to use a palette. + */ + convert(opt: MemoryImageConvertOptions): MemoryImage; + /** + * Add text metadata to the image. + */ + addTextData(data: Map): void; + getColorExtremes(): MemoryImageColorExtremes; + toString(): string; + /** + * Returns a pixel iterator for iterating over all of the pixels in the + * image. + */ + [Symbol.iterator](): Iterator; } } -declare module "formats/dib-decoder" { +declare module "formats/bmp/bmp-file-header" { /** @format */ import { InputBuffer } from "common/input-buffer"; - import { BmpDecoder } from "formats/bmp-decoder"; - import { BmpInfo } from "formats/bmp/bmp-info"; - export class DibDecoder extends BmpDecoder { - constructor(input: InputBuffer, info: BmpInfo); + export class BmpFileHeader { + static readonly signature = 19778; + private readonly _fileLength; + get fileLength(): number; + private _imageOffset; + set imageOffset(v: number); + get imageOffset(): number; + constructor(b: InputBuffer); + static isValidFile(b: InputBuffer): boolean; } } -declare module "formats/ico/ico-bmp-info" { +declare module "formats/decode-info" { /** @format */ - import { BmpInfo } from "formats/bmp/bmp-info"; - export class IcoBmpInfo extends BmpInfo { + import { Color } from "color/color"; + /** + * Provides information about the image being decoded. + */ + export interface DecodeInfo { + /** + * The width of the image canvas. + */ + get width(): number; + /** + * The height of the image canvas. + */ get height(): number; - get ignoreAlphaChannel(): boolean; + /** + * The suggested background color of the canvas. + */ + get backgroundColor(): Color | undefined; + /** + * The number of frames that can be decoded. + */ + get numFrames(): number; } } -declare module "formats/ico/ico-info-image" { +declare module "formats/bmp/bmp-compression-mode" { /** @format */ - export class IcoInfoImage { + export enum BmpCompressionMode { + none = 0, + rle8 = 1, + rle4 = 2, + bitfields = 3, + jpeg = 4, + png = 5, + alphaBitfields = 6, + reserved7 = 7, + reserved8 = 8, + reserved9 = 9, + reserved10 = 10, + cmyk = 11, + cmykRle8 = 12, + cmykRle4 = 13 + } +} +declare module "formats/bmp/bmp-info" { + /** @format */ + import { Color } from "color/color"; + import { InputBuffer } from "common/input-buffer"; + import { PaletteUint8 } from "image/palette-uint8"; + import { DecodeInfo } from "formats/decode-info"; + import { BmpCompressionMode } from "formats/bmp/bmp-compression-mode"; + import { BmpFileHeader } from "formats/bmp/bmp-file-header"; + export class BmpInfo implements DecodeInfo { + private readonly _startPos; + private _redShift; + private _redScale; + private _greenShift; + private _greenScale; + private _blueShift; + private _blueScale; + private _alphaShift; + private _alphaScale; private readonly _width; get width(): number; - private readonly _height; + protected readonly _height: number; get height(): number; - private readonly _colorPalette; - get colorPalette(): number; - private readonly _bytesSize; - get bytesSize(): number; - private readonly _bytesOffset; - get bytesOffset(): number; - private readonly _colorPlanes; - get colorPlanes(): number; + private readonly _backgroundColor; + get backgroundColor(): Color | undefined; + private readonly _numFrames; + get numFrames(): number; + private readonly _header; + get header(): BmpFileHeader; + private readonly _headerSize; + get headerSize(): number; + private readonly _planes; + get planes(): number; private readonly _bitsPerPixel; get bitsPerPixel(): number; - constructor(width: number, height: number, colorPalette: number, bytesSize: number, bytesOffset: number, colorPlanes: number, bitsPerPixel: number); + private readonly _compression; + get compression(): BmpCompressionMode; + private readonly _imageSize; + get imageSize(): number; + private readonly _xppm; + get xppm(): number; + private readonly _yppm; + get yppm(): number; + private readonly _totalColors; + get totalColors(): number; + private readonly _importantColors; + get importantColors(): number; + private _redMask; + get redMask(): number; + private _greenMask; + get greenMask(): number; + private _blueMask; + get blueMask(): number; + private _alphaMask; + get alphaMask(): number; + private _palette; + get palette(): PaletteUint8 | undefined; + get readBottomUp(): boolean; + get ignoreAlphaChannel(): boolean; + constructor(p: InputBuffer, header?: BmpFileHeader); + private readPalette; + decodePixel(input: InputBuffer, pixel: (r: number, g: number, b: number, a: number) => void): void; } } -declare module "formats/ico/ico-info" { +declare module "formats/decoder" { /** @format */ - import { InputBuffer } from "common/input-buffer"; + import { MemoryImage } from "image/image"; import { DecodeInfo } from "formats/decode-info"; - import { IcoInfoImage } from "formats/ico/ico-info-image"; - export class IcoInfo implements DecodeInfo { - private readonly _type?; - get type(): number | undefined; - private readonly _images?; - get images(): IcoInfoImage[] | undefined; - private readonly _numFrames; + /** + * Base class for image format decoders. + * + * Image pixels are stored as 32-bit unsigned ints, so all formats, regardless + * of their encoded color resolutions, decode to 32-bit RGBA images. Encoders + * can reduce the color resolution back down to their required formats. + * + * Some image formats support multiple frames, often for encoding animation. + * In such cases, the **decode** method will decode all of the frames, + * unless the frame argument is specified for a particular frame to decode. + * **startDecode** will initiate decoding of the file, and **decodeFrame** will + * then decode a specific frame from the file, allowing for animations to be + * decoded one frame at a time. Some formats, such as TIFF, may store multiple + * frames, but their use of frames is for multiple page documents and not + * animation. The terms 'animation' and 'frames' simply refer to 'pages' in + * this case. + */ + export interface Decoder { + /** + * How many frames are available to be decoded. **startDecode** should have + * been called first. Non animated image files will have a single frame. + */ get numFrames(): number; - private _width; - get width(): number; - private _height; - get height(): number; - private _backgroundColor; - get backgroundColor(): number; - constructor(numFrames: number, type?: number, images?: IcoInfoImage[]); - static read(input: InputBuffer): IcoInfo | undefined; + /** + * A light-weight function to test if the given file is able to be decoded + * by this Decoder. + */ + isValidFile(bytes: Uint8Array): boolean; + /** + * Start decoding the data as an animation sequence, but don't actually + * process the frames until they are requested with **decodeFrame**. + */ + startDecode(bytes: Uint8Array): DecodeInfo | undefined; + /** + * Decode the file and extract a single image from it. If the file is + * animated, and **frame** is specified, that particular frame will be decoded. + * Otherwise if the image is animated and **frame** is undefined, the returned + * MemoryImage will include all frames. If there was a problem decoding the + * MemoryImage, undefined will be returned. + */ + decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined; + /** + * Decode a single frame from the data that was set with **startDecode**. + * If **frame** is out of the range of available frames, undefined is returned. + * Non animated image files will only have **frame** 0. A MemoryImage + * is returned, which provides the image, and top-left coordinates of the + * image, as animated frames may only occupy a subset of the canvas. + */ + decodeFrame(frame: number): MemoryImage | undefined; } } -declare module "common/crc32" { - /** @format */ - export interface Crc32Parameters { - buffer: Uint8Array; - baseCrc?: number; - position?: number; - length?: number; +declare module "formats/bmp-decoder" { + import { InputBuffer } from "common/input-buffer"; + import { MemoryImage } from "image/image"; + import { BmpInfo } from "formats/bmp/bmp-info"; + import { Decoder } from "formats/decoder"; + export class BmpDecoder implements Decoder { + protected _input?: InputBuffer; + protected _info?: BmpInfo; + protected _forceRgba: boolean; + get numFrames(): number; + constructor(forceRgba?: boolean); + /** + * Is the given file a valid BMP image? + */ + isValidFile(bytes: Uint8Array): boolean; + startDecode(bytes: Uint8Array): BmpInfo | undefined; + /** + * Decode a single frame from the data stat was set with **startDecode**. + * If **frame** is out of the range of available frames, undefined is returned. + * Non animated image files will only have **frame** 0. An animation frame + * is returned, which provides the image, and top-left coordinates of the + * image, as animated frames may only occupy a subset of the canvas. + */ + decodeFrame(_frame: number): MemoryImage | undefined; + /** + * Decode the file and extract a single image from it. If the file is + * animated, the specified **frame** will be decoded. If there was a problem + * decoding the file, undefined is returned. + */ + decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined; } - export abstract class Crc32 { - private static readonly crcTable; - private static makeTable; - static getChecksum(options: Crc32Parameters): number; +} +declare module "formats/encoder" { + /** @format */ + import { MemoryImage } from "image/image"; + /** + * Base class for image format encoders. + */ + export interface Encoder { + /** + * True if the encoder supports animated images; otherwise false. + */ + get supportsAnimation(): boolean; + /** + * Encode an **image** to an image format. + * If **singleFrame** is true, only the one MemoryImage will be encoded; + * otherwise if image has animation, all frames of the **image** will be + * encoded if the encoder supports animation. + */ + encode(image: MemoryImage, singleFrame?: boolean): Uint8Array; } } -declare module "formats/png/png-frame" { +declare module "formats/bmp-encoder" { + import { MemoryImage } from "image/image"; + import { Encoder } from "formats/encoder"; + /** + * Encode a BMP image. + */ + export class BmpEncoder implements Encoder { + private _supportsAnimation; + get supportsAnimation(): boolean; + encode(image: MemoryImage, _singleFrame?: boolean): Uint8Array; + } +} +declare module "formats/gif/gif-color-map" { /** @format */ - export interface PngFrameInitOptions { - sequenceNumber?: number; - width?: number; - height?: number; - xOffset?: number; - yOffset?: number; - delayNum?: number; - delayDen?: number; - dispose?: number; - blend?: number; + import { ColorUint8 } from "color/color-uint8"; + import { PaletteUint8 } from "image/palette-uint8"; + export class GifColorMap { + private readonly _numColors; + get numColors(): number; + private readonly _palette; + get palette(): PaletteUint8; + private _bitsPerPixel; + get bitsPerPixel(): number; + private _transparent?; + set transparent(v: number | undefined); + get transparent(): number | undefined; + constructor(numColors: number, palette?: PaletteUint8); + private static bitSize; + static from(other: GifColorMap): GifColorMap; + getColor(index: number): ColorUint8; + setColor(index: number, r: number, g: number, b: number): void; + getRed(color: number): number; + getGreen(color: number): number; + getBlue(color: number): number; + getAlpha(color: number): number; + getPalette(): PaletteUint8; } - export class PngFrame { - static readonly APNG_DISPOSE_OP_NONE = 0; - static readonly APNG_DISPOSE_OP_BACKGROUND = 1; - static readonly APNG_DISPOSE_OP_PREVIOUS = 2; - static readonly APNG_BLEND_OP_SOURCE = 0; - static readonly APNG_BLEND_OP_OVER = 1; - private readonly _fdat; - get fdat(): number[]; - private _sequenceNumber?; - get sequenceNumber(): number | undefined; - private _width?; - get width(): number | undefined; - private _height?; - get height(): number | undefined; - private _xOffset?; - get xOffset(): number | undefined; - private _yOffset?; - get yOffset(): number | undefined; - private _delayNum?; - get delayNum(): number | undefined; - private _delayDen?; - get delayDen(): number | undefined; - private _dispose?; - get dispose(): number | undefined; - private _blend?; - get blend(): number | undefined; - get delay(): number; - constructor(options: PngFrameInitOptions); +} +declare module "formats/gif/gif-image-desc" { + /** @format */ + import { InputBuffer } from "common/input-buffer"; + import { GifColorMap } from "formats/gif/gif-color-map"; + export class GifImageDesc { + private readonly _x; + get x(): number; + private readonly _y; + get y(): number; + private readonly _width; + get width(): number; + private readonly _height; + get height(): number; + private readonly _interlaced; + get interlaced(): boolean; + private _colorMap?; + get colorMap(): GifColorMap | undefined; + set colorMap(v: GifColorMap | undefined); + private _duration; + set duration(v: number); + get duration(): number; + private _clearFrame; + set clearFrame(v: boolean); + get clearFrame(): boolean; + /** + * The position in the file after the ImageDesc for this frame. + */ + protected _inputPosition: number; + get inputPosition(): number; + constructor(input: InputBuffer); } } -declare module "formats/png/png-info" { +declare module "formats/gif/gif-info" { /** @format */ + import { Color } from "color/color"; import { DecodeInfo } from "formats/decode-info"; - import { PngFrame } from "formats/png/png-frame"; - export interface PngInfoInitOptions { + import { GifColorMap } from "formats/gif/gif-color-map"; + import { GifImageDesc } from "formats/gif/gif-image-desc"; + export interface GifInfoInitOptions { width?: number; height?: number; - bits?: number; - colorType?: number; - compressionMethod?: number; - filterMethod?: number; - interlaceMethod?: number; + backgroundColor?: Color; + frames?: Array; + colorResolution?: number; + globalColorMap?: GifColorMap; + isGif89?: boolean; } - export class PngInfo implements DecodeInfo { + export class GifInfo implements DecodeInfo { private _width; - set width(v: number); get width(): number; private _height; - set height(v: number); get height(): number; private _backgroundColor; - set backgroundColor(v: number); - get backgroundColor(): number; - private _numFrames; - set numFrames(v: number); + get backgroundColor(): Color | undefined; + private _frames; + get frames(): Array; + private _colorResolution; + get colorResolution(): number; + private _globalColorMap?; + get globalColorMap(): GifColorMap | undefined; + private _isGif89; + get isGif89(): boolean; get numFrames(): number; - private _bits?; - get bits(): number | undefined; - private _colorType?; - get colorType(): number | undefined; - private _compressionMethod?; - get compressionMethod(): number | undefined; - private _filterMethod?; - get filterMethod(): number | undefined; - private _interlaceMethod?; - get interlaceMethod(): number | undefined; - private _palette?; - set palette(v: Uint8Array | undefined); - get palette(): Uint8Array | undefined; - private _transparency?; - set transparency(v: Uint8Array | undefined); - get transparency(): Uint8Array | undefined; - private _colorLut?; - set colorLut(v: number[] | undefined); - get colorLut(): number[] | undefined; - private _gamma?; - set gamma(v: number | undefined); - get gamma(): number | undefined; - private _iCCPName; - set iCCPName(v: string); - get iCCPName(): string; - private _iCCPCompression; - set iCCPCompression(v: number); - get iCCPCompression(): number; - private _iCCPData?; - set iCCPData(v: Uint8Array | undefined); - get iCCPData(): Uint8Array | undefined; - private _textData; - get textData(): Map; - private _repeat; - set repeat(v: number); - get repeat(): number; - private readonly _idat; - get idat(): number[]; - private readonly _frames; - get frames(): PngFrame[]; - get isAnimated(): boolean; - constructor(options?: PngInfoInitOptions); + constructor(opt?: GifInfoInitOptions); } } -declare module "formats/png-decoder" { - import { FrameAnimation } from "common/frame-animation"; - import { InputBuffer } from "common/input-buffer"; - import { MemoryImage } from "common/memory-image"; - import { HdrImage } from "hdr/hdr-image"; - import { DecodeInfo } from "formats/decode-info"; +declare module "formats/gif-decoder" { import { Decoder } from "formats/decoder"; - import { PngInfo } from "formats/png/png-info"; + import { GifInfo } from "formats/gif/gif-info"; + import { MemoryImage } from "image/image"; /** - * Decode a PNG encoded image. + * A decoder for the GIF image format. This supports both single frame and + * animated GIF files, and transparency. */ - export class PngDecoder implements Decoder { - private static readonly GRAYSCALE; - private static readonly RGB; - private static readonly INDEXED; - private static readonly GRAYSCALE_ALPHA; - private static readonly RGBA; - private static readonly FILTER_NONE; - private static readonly FILTER_SUB; - private static readonly FILTER_UP; - private static readonly FILTER_AVERAGE; - private static readonly FILTER_PAETH; - private _info?; - get info(): PngInfo | undefined; + export class GifDecoder implements Decoder { + private static readonly _stampSize; + private static readonly _gif87Stamp; + private static readonly _gif89Stamp; + private static readonly _imageDescRecordType; + private static readonly _extensionRecordType; + private static readonly _terminateRecordType; + private static readonly _graphicControlExt; + private static readonly _applicationExt; + private static readonly _lzMaxCode; + private static readonly _lzBits; + private static readonly _noSuchCode; + private static readonly _codeMasks; + private static readonly _interlacedOffset; + private static readonly _interlacedJump; private _input?; - get input(): InputBuffer | undefined; - private _progressY; - get progressY(): number; - private _bitBuffer; - get bitBuffer(): number; - private _bitBufferLen; - get bitBufferLen(): number; + private _info?; + private _repeat; + private _buffer?; + private _stack; + private _suffix; + private _prefix?; + private _bitsPerPixel; + private _pixelCount?; + private _currentShiftDWord; + private _currentShiftState; + private _stackPtr; + private _currentCode?; + private _lastCode; + private _maxCode1; + private _runningBits; + private _runningCode; + private _eofCode; + private _clearCode; /** - * The number of frames that can be decoded. + * How many frames are available to decode? + * + * You should have prepared the decoder by either passing the file bytes + * to the constructor, or calling getInfo. */ get numFrames(): number; - private static unfilter; - private static convert16to8; - private static convert1to8; - private static convert2to8; - private static convert4to8; + constructor(bytes?: Uint8Array); /** - * Return the CRC of the bytes + * Routine to trace the Prefixes linked list until we get a prefix which is + * not code, but a pixel value (less than ClearCode). Returns that pixel value. + * If image is defective, we might loop here forever, so we limit the loops to + * the maximum possible if image O.k. - lzMaxCode times. */ - private static crc; + private static getPrefixChar; + private static updateImage; + private getInfo; + private skipImage; /** - * Process a pass of an interlaced image. + * Continue to get the image code in compressed form. This routine should be + * called until NULL block is returned. + * The block should NOT be freed by the user (not dynamically allocated). */ - private processPass; - private process; - private resetBits; + private skipRemainder; + private readApplicationExt; + private readGraphicsControlExt; + private getLine; /** - * Read a number of bits from the input stream. + * The LZ decompression routine: + * This version decompress the given gif file into Line of length LineLen. + * This routine can be called few times (one per scan line, for example), in + * order the complete the whole image. */ - private readBits; + private decompressLine; /** - * Read the next pixel from the input stream. + * The LZ decompression input routine: + * This routine is responsible for the decompression of the bit stream from + * 8 bits (bytes) packets, into the real codes. */ - private readPixel; + private decompressInput; /** - * Get the color with the list of components. + * This routines read one gif data block at a time and buffers it internally + * so that the decompression routine could access it. + * The routine returns the next byte from its internal buffer (or read next + * block in if buffer empty) and returns undefined on failure. */ - private getColor; + private bufferedInput; + private initDecode; + private decodeImage; /** - * Is the given file a valid PNG image? + * Is the given file a valid Gif image? */ isValidFile(bytes: Uint8Array): boolean; /** - * Start decoding the data as an animation sequence, but don't actually - * process the frames until they are requested with decodeFrame. - */ - startDecode(bytes: Uint8Array): DecodeInfo | undefined; - /** - * Decode the frame (assuming **startDecode** has already been called). + * Validate the file is a Gif image and get information about it. + * If the file is not a valid Gif image, undefined is returned. */ + startDecode(bytes: Uint8Array): GifInfo | undefined; + decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined; decodeFrame(frame: number): MemoryImage | undefined; - decodeHdrFrame(frame: number): HdrImage | undefined; - decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined; - decodeImage(bytes: Uint8Array, frame?: number): MemoryImage | undefined; - decodeHdrImage(bytes: Uint8Array, frame?: number): HdrImage | undefined; } } -declare module "formats/ico-decoder" { +declare module "image/quantizer" { /** @format */ - import { FrameAnimation } from "common/frame-animation"; - import { InputBuffer } from "common/input-buffer"; - import { MemoryImage } from "common/memory-image"; - import { HdrImage } from "hdr/hdr-image"; - import { Decoder } from "formats/decoder"; - import { IcoInfo } from "formats/ico/ico-info"; - export class IcoDecoder implements Decoder { - _input?: InputBuffer; - _icoInfo?: IcoInfo; - get numFrames(): number; - isValidFile(bytes: Uint8Array): boolean; - startDecode(bytes: Uint8Array): IcoInfo | undefined; - decodeFrame(frame: number): MemoryImage | undefined; - decodeHdrFrame(frame: number): HdrImage | undefined; - decodeAnimation(_: Uint8Array): FrameAnimation | undefined; - decodeImage(bytes: Uint8Array, frame?: number): MemoryImage | undefined; - decodeHdrImage(bytes: Uint8Array, frame?: number): HdrImage | undefined; + import { Color } from "color/color"; + import { MemoryImage } from "image/image"; + import { Palette } from "image/palette"; + /** + * Interface for color quantizers, which reduce the total number of colors + * used by an image to a given maximum, used to convert images to palette + * images. + */ + export interface Quantizer { + get palette(): Palette; + getColorIndex(c: Color): number; + getColorIndexRgb(r: number, g: number, b: number): number; /** - * Decodes the largest frame. + * Find the index of the closest color to **c** in the **palette**. */ - decodeImageLargest(bytes: Uint8Array): MemoryImage | undefined; + getQuantizedColor(c: Color): Color; + /** + * Convert the **image** to a palette image. + */ + getIndexImage(image: MemoryImage): MemoryImage; } } -declare module "formats/png-encoder" { - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; - import { CompressionLevel } from "common/typings"; - import { Encoder } from "formats/encoder"; - export interface PngEncoderInitOptions { - filter?: number; - level?: CompressionLevel; - } +declare module "image/neural-quantizer" { + /** @format */ + import { Color } from "color/color"; + import { MemoryImage } from "image/image"; + import { PaletteUint8 } from "image/palette-uint8"; + import { Quantizer } from "image/quantizer"; /** - * Encode an image to the PNG format. + * Compute a color map with a given number of colors that best represents + * the given image. */ - export class PngEncoder implements Encoder { - private static readonly FILTER_NONE; - private static readonly FILTER_SUB; - private static readonly FILTER_UP; - private static readonly FILTER_AVERAGE; - private static readonly FILTER_PAETH; - private static readonly FILTER_AGRESSIVE; - private rgbChannelSet?; - private filter; - private level; - private repeat; - private xOffset; - private yOffset; - private delay?; - private disposeMethod; - private blendMethod; - private width; - private height; - private frames; - private sequenceNumber; - private isAnimated; - private output?; + export class NeuralQuantizer implements Quantizer { + private static readonly _numCycles; + private static readonly _alphaBiasShift; + private static readonly _initAlpha; + private static readonly _radiusBiasShift; + private static readonly _radiusBias; + private static readonly _alphaRadiusBiasShift; + private static readonly alphaRadiusBias; + private static readonly _radiusDec; + private static readonly _gamma; + private static readonly _beta; + private static readonly _betaGamma; + private static readonly _prime1; + private static readonly _prime2; + private static readonly _prime3; + private static readonly _prime4; + private static readonly _smallImageBytes; + private readonly _netIndex; + private _samplingFactor; + private _netSize; + private _specials; + private _bgColor; + private _cutNetSize; + private _maxNetPos; + private _initRadius; + private _initBiasRadius; + private _radiusPower; /** - * Does this encoder support animation? + * The network itself */ - private _supportsAnimation; - get supportsAnimation(): boolean; - constructor(options?: PngEncoderInitOptions); + private _network; + private _paletteInternal; + private _palette; + get palette(): PaletteUint8; /** - * Return the CRC of the bytes + * Bias array for learning */ - private static crc; - private static writeChunk; - private static filterSub; - private static filterUp; - private static filterAverage; - private static paethPredictor; - private static filterPaeth; - private static filterNone; - private writeHeader; - private writeICCPChunk; - private writeAnimationControlChunk; - private applyFilter; - private writeFrameControlChunk; - private writeTextChunk; - addFrame(image: MemoryImage): void; - finish(): Uint8Array | undefined; + private _bias; + private _freq; /** - * Encode a single frame image. + * How many colors are in the **palette**? + */ + get numColors(): number; + /** + * 10 is a reasonable **samplingFactor** according to + * https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/. + */ + constructor(image: MemoryImage, numberOfColors?: number, samplingFactor?: number); + private initialize; + private updateRadiusPower; + private specialFind; + /** + * Search for biased BGR values + */ + private contest; + private alterSingle; + private alterNeighbors; + private learn; + private fix; + /** + * Insertion sort of network and building of netindex[0..255] + */ + private inxBuild; + private copyPalette; + /** + * Search for BGR values 0..255 and return color index + */ + private inxSearch; + /** + * Find the index of the closest color to **c** in the **palette**. + */ + getColorIndex(c: Color): number; + /** + * Find the index of the closest color to **r**,**g**,**b** in the **palette**. + */ + getColorIndexRgb(r: number, g: number, b: number): number; + /** + * Find the color closest to **c** in the **palette**. + */ + getQuantizedColor(c: Color): Color; + /** + * Convert the **image** to a palette image. */ - encodeImage(image: MemoryImage): Uint8Array; + getIndexImage(image: MemoryImage): MemoryImage; /** - * Encode an animation. + * Add an image to the quantized color table. */ - encodeAnimation(animation: FrameAnimation): Uint8Array | undefined; + addImage(image: MemoryImage): void; } } -declare module "formats/win-encoder" { +declare module "image/quantizer-type" { /** @format */ - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; - import { Encoder } from "formats/encoder"; - export abstract class WinEncoder implements Encoder { - protected _type: number; - get type(): number; - private _supportsAnimation; - get supportsAnimation(): boolean; - protected colorPlanesOrXHotSpot(_index: number): number; - protected bitsPerPixelOrYHotSpot(_index: number): number; - encodeImages(images: MemoryImage[]): Uint8Array; - encodeImage(image: MemoryImage): Uint8Array; - encodeAnimation(_: FrameAnimation): Uint8Array | undefined; + export enum QuantizerType { + octree = 0, + neural = 1 } } -declare module "formats/ico-encoder" { +declare module "image/octree-node" { + export class OctreeNode { + private _r; + get r(): number; + set r(v: number); + private _g; + get g(): number; + set g(v: number); + private _b; + get b(): number; + set b(v: number); + private _count; + get count(): number; + set count(v: number); + private _heapIndex; + get heapIndex(): number; + set heapIndex(v: number); + private _paletteIndex; + get paletteIndex(): number; + set paletteIndex(v: number); + private _parent; + get parent(): OctreeNode | undefined; + private _children; + get children(): Array; + private _childCount; + get childCount(): number; + set childCount(v: number); + private _childIndex; + get childIndex(): number; + private _flags; + get flags(): number; + set flags(v: number); + private _depth; + get depth(): number; + constructor(childIndex: number, depth: number, parent?: OctreeNode); + } +} +declare module "image/heap-node" { /** @format */ - import { WinEncoder } from "formats/win-encoder"; - export class IcoEncoder extends WinEncoder { - protected _type: number; - protected colorPlanesOrXHotSpot(_index: number): number; - protected bitsPerPixelOrYHotSpot(_index: number): number; + import { OctreeNode } from "image/octree-node"; + export class HeapNode { + private _buf; + get buf(): Array; + get n(): number; } } -declare module "formats/jpeg/component-data" { +declare module "image/octree-quantizer" { /** @format */ - export class ComponentData { - private _hSamples; - get hSamples(): number; - private _maxHSamples; - get maxHSamples(): number; - private _vSamples; - get vSamples(): number; - private _maxVSamples; - get maxVSamples(): number; - private _lines; - get lines(): Array; - private _hScaleShift; - get hScaleShift(): number; - private _vScaleShift; - get vScaleShift(): number; - constructor(hSamples: number, maxHSamples: number, vSamples: number, maxVSamples: number, lines: Array); + import { Color } from "color/color"; + import { MemoryImage } from "image/image"; + import { PaletteUint8 } from "image/palette-uint8"; + import { Quantizer } from "image/quantizer"; + /** + * Color quantization using octree, + * from https://rosettacode.org/wiki/Color_quantization/C + */ + export class OctreeQuantizer implements Quantizer { + private static readonly _inHeap; + private readonly _root; + private _palette; + get palette(): PaletteUint8; + constructor(image: MemoryImage, numberOfColors?: number); + private nodeInsert; + private popHeap; + private heapAdd; + private downHeap; + private upHeap; + private nodeFold; + private compareNode; + private getNodes; + getColorIndex(c: Color): number; + getColorIndexRgb(r: number, g: number, b: number): number; + /** + * Find the index of the closest color to **c** in the **palette**. + */ + getQuantizedColor(c: Color): Color; + /** + * Convert the **image** to a palette image. + */ + getIndexImage(image: MemoryImage): MemoryImage; } } -declare module "formats/jpeg/jpeg" { +declare module "common/random-utils" { /** @format */ - export abstract class Jpeg { - static readonly dctZigZag: number[]; - static readonly DCTSIZE = 8; - static readonly DCTSIZE2 = 64; - static readonly NUM_QUANT_TBLS = 4; - static readonly NUM_HUFF_TBLS = 4; - static readonly NUM_ARITH_TBLS = 16; - static readonly MAX_COMPS_IN_SCAN = 4; - static readonly MAX_SAMP_FACTOR = 4; - static readonly M_SOF0 = 192; - static readonly M_SOF1 = 193; - static readonly M_SOF2 = 194; - static readonly M_SOF3 = 195; - static readonly M_SOF5 = 197; - static readonly M_SOF6 = 198; - static readonly M_SOF7 = 199; - static readonly M_JPG = 200; - static readonly M_SOF9 = 201; - static readonly M_SOF10 = 202; - static readonly M_SOF11 = 203; - static readonly M_SOF13 = 205; - static readonly M_SOF14 = 206; - static readonly M_SOF15 = 207; - static readonly M_DHT = 196; - static readonly M_DAC = 204; - static readonly M_RST0 = 208; - static readonly M_RST1 = 209; - static readonly M_RST2 = 210; - static readonly M_RST3 = 211; - static readonly M_RST4 = 212; - static readonly M_RST5 = 213; - static readonly M_RST6 = 214; - static readonly M_RST7 = 215; - static readonly M_SOI = 216; - static readonly M_EOI = 217; - static readonly M_SOS = 218; - static readonly M_DQT = 219; - static readonly M_DNL = 220; - static readonly M_DRI = 221; - static readonly M_DHP = 222; - static readonly M_EXP = 223; - static readonly M_APP0 = 224; - static readonly M_APP1 = 225; - static readonly M_APP2 = 226; - static readonly M_APP3 = 227; - static readonly M_APP4 = 228; - static readonly M_APP5 = 229; - static readonly M_APP6 = 230; - static readonly M_APP7 = 231; - static readonly M_APP8 = 232; - static readonly M_APP9 = 233; - static readonly M_APP10 = 234; - static readonly M_APP11 = 235; - static readonly M_APP12 = 236; - static readonly M_APP13 = 237; - static readonly M_APP14 = 238; - static readonly M_APP15 = 239; - static readonly M_JPG0 = 240; - static readonly M_JPG13 = 253; - static readonly M_COM = 254; - static readonly M_TEM = 1; - static readonly M_ERROR = 256; + export abstract class RandomUtils { + /** + * Return a random number between [-1, 1]. + */ + static crand(): number; + /** + * Return a random number following a gaussian distribution and a standard + * deviation of 1. + */ + static grand(): number; + /** + * Return a random variable following a Poisson distribution of parameter **z**. + */ + static prand(z: number): number; + /** + * Generates a non-negative random integer in the range from 0, inclusive, to **max**, exclusive. + */ + static intrand(max: number): number; } } -declare module "formats/jpeg/jpeg-adobe" { +declare module "common/point" { + /** + * 2-dimensional point + * + * @format + */ + export class Point { + private _x; + private _y; + get x(): number; + get y(): number; + get xt(): number; + get yt(): number; + constructor(x: number, y: number); + static from(other: Point): Point; + move(x: number, y: number): Point; + offset(dx: number, dy: number): Point; + mul(n: number): Point; + add(p: Point): Point; + equals(other: Point): boolean; + toString(): string; + } +} +declare module "common/line" { + export class Line { + private _x1; + private _y1; + private _x2; + private _y2; + get x1(): number; + get y1(): number; + get x2(): number; + get y2(): number; + get dx(): number; + get dy(): number; + constructor(x1: number, y1: number, x2: number, y2: number); + static from(other: Line): Line; + movePoint1(x: number, y: number): void; + movePoint2(x: number, y: number): void; + swapXY1(): void; + swapXY2(): void; + flipX(): void; + flipY(): void; + clone(): Line; + toString(): string; + } +} +declare module "common/rectangle" { /** @format */ - export class JpegAdobe { - private _version; - get version(): number; - private _flags0; - get flags0(): number; - private _flags1; - get flags1(): number; - private _transformCode; - get transformCode(): number; - constructor(version: number, flags0: number, flags1: number, transformCode: number); + import { Point } from "common/point"; + export class Rectangle { + private readonly _left; + private readonly _top; + private readonly _right; + private readonly _bottom; + get left(): number; + get top(): number; + get right(): number; + get bottom(): number; + get width(): number; + get height(): number; + get topLeft(): Point; + get topRight(): Point; + get bottomLeft(): Point; + get bottomRight(): Point; + constructor(x1: number, y1: number, x2: number, y2: number); + static fromXYWH(x: number, y: number, width: number, height: number): Rectangle; + static from(other: Rectangle): Rectangle; + toString(): string; } } -declare module "formats/jpeg/jpeg-component" { +declare module "image/image-utils" { /** @format */ - export class JpegComponent { - private readonly _quantizationTableList; - private readonly _quantizationIndex; - private readonly _hSamples; - get hSamples(): number; - private readonly _vSamples; - get vSamples(): number; - private _blocks; - get blocks(): Array>; - private _blocksPerLine; - get blocksPerLine(): number; - private _blocksPerColumn; - get blocksPerColumn(): number; - private _huffmanTableDC; - set huffmanTableDC(v: []); - get huffmanTableDC(): []; - private _huffmanTableAC; - set huffmanTableAC(v: []); - get huffmanTableAC(): []; - private _pred; - set pred(v: number); - get pred(): number; - get quantizationTable(): Int16Array | undefined; - constructor(hSamples: number, vSamples: number, quantizationTableList: Array, quantizationIndex: number); - setBlocks(blocks: Array>, blocksPerLine: number, blocksPerColumn: number): void; + import { Line } from "common/line"; + import { Point } from "common/point"; + import { Rectangle } from "common/rectangle"; + import { Pixel } from "image/pixel"; + export abstract class ImageUtils { + /** + * Test if the pixel **p** is within the circle centered at **center** with a + * squared radius of **rad2**. This will test the corners, edges, and center + * of the pixel and return the ratio of samples within the circle. + */ + static circleTest(p: Pixel, center: Point, rad2: number, antialias?: boolean): number; + /** + * Clip a line to a rectangle using the Cohen–Sutherland clipping algorithm. + * **line** is a Line object. + * **rect** is a Rectangle object. + * Results are stored in **line**. + * If **line** falls completely outside of **rect**, false is returned, otherwise + * true is returned. + */ + static clipLine(rect: Rectangle, line: Line): boolean; } } -declare module "formats/jpeg/jpeg-frame" { +declare module "draw/blend-mode" { /** @format */ + export enum BlendMode { + direct = 0, + alpha = 1, + lighten = 2, + screen = 3, + dodge = 4, + addition = 5, + darken = 6, + multiply = 7, + burn = 8, + overlay = 9, + softLight = 10, + hardLight = 11, + difference = 12, + subtract = 13, + divide = 14 + } +} +declare module "draw/circle-quadrant" { + /** @format */ + export enum CircleQuadrant { + topLeft = 1, + topRight = 2, + bottomLeft = 4, + bottomRight = 8, + all = 15 + } +} +declare module "draw/draw" { + /** @format */ + import { Channel } from "color/channel"; + import { Color } from "color/color"; + import { Line } from "common/line"; + import { Point } from "common/point"; + import { Rectangle } from "common/rectangle"; + import { MemoryImage } from "image/image"; + import { BlendMode } from "draw/blend-mode"; + interface DrawLineWuOptions { + image: MemoryImage; + line: Line; + color: Color; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface DrawLineOptions extends DrawLineWuOptions { + antialias?: boolean; + thickness?: number; + } + export interface DrawCircleOptions { + image: MemoryImage; + center: Point; + radius: number; + color: Color; + antialias?: boolean; + mask?: MemoryImage; + maskChannel?: Channel; + } + export interface DrawPixelOptions { + image: MemoryImage; + pos: Point; + color: Color; + filter?: Color; + alpha?: number; + blend?: BlendMode; + linearBlend?: boolean; + mask?: MemoryImage; + maskChannel?: Channel; + } + export interface DrawPolygonOptions { + image: MemoryImage; + vertices: Point[]; + color: Color; + antialias?: boolean; + thickness?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface DrawRectOptions { + image: MemoryImage; + rect: Rectangle; + color: Color; + thickness?: number; + radius?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface FillCircleOptions { + image: MemoryImage; + center: Point; + radius: number; + color: Color; + antialias?: boolean; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface FillFloodOptions { + image: MemoryImage; + start: Point; + color: Color; + threshold?: number; + compareAlpha?: boolean; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface MaskFloodOptions { + image: MemoryImage; + start: Point; + threshold?: number; + compareAlpha?: boolean; + fillValue?: number; + } + export interface FillPolygonOptions { + image: MemoryImage; + vertices: Point[]; + color: Color; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface FillRectOptions { + image: MemoryImage; + rect: Rectangle; + color: Color; + radius?: number; + mask?: MemoryImage; + maskChannel?: Channel; + } + export interface FillOptions { + image: MemoryImage; + color: Color; + maskChannel?: Channel.luminance; + mask?: MemoryImage; + } + export interface CompositeImageOptions { + dst: MemoryImage; + src: MemoryImage; + dstX?: number; + dstY?: number; + dstW?: number; + dstH?: number; + srcX?: number; + srcY?: number; + srcW?: number; + srcH?: number; + blend?: BlendMode; + linearBlend?: boolean; + center?: boolean; + mask?: MemoryImage; + maskChannel?: Channel; + } + export abstract class Draw { + /** + * Calculate the pixels that make up the circumference of a circle on the + * given **image**, centered at **center** and the given **radius**. + * + * The returned array of points is sorted, first by the **center.x** coordinate, and + * second by the **center.y** coordinate. + */ + private static calculateCircumference; + private static drawAntialiasCircle; + private static drawLineWu; + private static setAlpha; + /** + * Compare colors from a 3 or 4 dimensional color space + */ + private static colorDistance; + private static testPixelLabColorDistance; + private static fill4Core; + private static fill4; + private static imgDirectComposite; + private static imgComposite; + /** + * Draw a circle into the **image** with a center of **center** and + * the given **radius** and **color**. + */ + static drawCircle(opt: DrawCircleOptions): MemoryImage; + /** + * Draw and fill a circle into the **image** with a **center** + * and the given **radius** and **color**. + */ + static fillCircle(opt: FillCircleOptions): MemoryImage; + /** + * Draw a line into **image**. + * + * If **antialias** is true then the line is drawn with smooth edges. + * **thickness** determines how thick the line should be drawn, in pixels. + */ + static drawLine(opt: DrawLineOptions): MemoryImage; + /** + * Draw a single pixel into the image, applying alpha and opacity blending. + * If **filter** is provided, the color c will be scaled by the **filter** + * color. If **alpha** is provided, it will be used in place of the + * color alpha, as a normalized color value [0, 1]. + */ + static drawPixel(opt: DrawPixelOptions): MemoryImage; + /** + * Fill a polygon defined by the given **vertices**. + */ + static drawPolygon(opt: DrawPolygonOptions): MemoryImage; + /** + * Draw a rectangle in the **image** with the **color**. + */ + static drawRect(opt: DrawRectOptions): MemoryImage; + /** + * Fill the 4-connected shape containing **start** in the **image** with the + * given **color**. + */ + static fillFlood(opt: FillFloodOptions): MemoryImage; + /** + * Fill a polygon defined by the given **vertices**. + */ + static fillPolygon(opt: FillPolygonOptions): MemoryImage; + /** + * Fill a rectangle **rect** in the **image** with the given **color**. + */ + static fillRect(opt: FillRectOptions): MemoryImage; + /** + * Set all of the pixels of an **image** to the given **color**. + */ + static fill(opt: FillOptions): MemoryImage; + /** + * Create a mask describing the 4-connected shape containing **start** in the + * **image**. + */ + static maskFlood(opt: MaskFloodOptions): Uint8Array; + /** + * Composite the image **src** onto the image **dst**. + * + * In other words, compositeImage will take an rectangular area from src of + * width **srcW** and height **srcH** at position (**srcX**,**srcY**) and place it + * in a rectangular area of **dst** of width **dstW** and height **dstH** at + * position (**dstX**,**dstY**). + * + * If the source and destination coordinates and width and heights differ, + * appropriate stretching or shrinking of the image fragment will be performed. + * The coordinates refer to the upper left corner. This function can be used to + * copy regions within the same image (if **dst** is the same as **src**) + * but if the regions overlap the results will be unpredictable. + * + * if **center** is true, the **src** will be centered in **dst**. + */ + static compositeImage(opt: CompositeImageOptions): MemoryImage; + } +} +declare module "filter/dither-kernel" { + /** @format */ + /** + * The pattern to use for dithering + */ + export enum DitherKernel { + none = 0, + falseFloydSteinberg = 1, + floydSteinberg = 2, + stucki = 3, + atkinson = 4 + } + export const DitherKernels: number[][][]; +} +declare module "filter/noise-type" { + /** @format */ + export enum NoiseType { + gaussian = 0, + uniform = 1, + saltAndPepper = 2, + poisson = 3, + rice = 4 + } +} +declare module "filter/pixelate-mode" { + /** @format */ + export enum PixelateMode { + /** + * Use the top-left pixel of a block for the block color. + */ + upperLeft = 0, + /** + * Use the average of the pixels within a block for the block color. + */ + average = 1 + } +} +declare module "filter/quantize-method" { + /** @format */ + export enum QuantizeMethod { + neuralNet = 0, + octree = 1 + } +} +declare module "filter/separable-kernel" { + /** @format */ + import { Channel } from "color/channel"; + import { MemoryImage } from "image/image"; + export interface SeparableKernelApplyOptions { + src: MemoryImage; + dst: MemoryImage; + horizontal?: boolean; + maskChannel?: Channel; + mask?: MemoryImage; + } + /** + * A kernel object to use with **separableConvolution** filter. + */ + export class SeparableKernel { + private readonly _coefficients; + private readonly _size; + /** + * Get the number of coefficients in the kernel. + */ + get length(): number; + /** + * Create a separable convolution kernel for the given **size**. + */ + constructor(size: number); + private reflect; + private applyCoefficientsLine; + /** + * Get a coefficient from the kernel. + */ + getCoefficient(index: number): number; + /** + * Set a coefficient in the kernel. + */ + setCoefficient(index: number, c: number): void; + /** + * Apply the kernel to the **src** image, storing the results in **dst**, + * for a single dimension. If **horizontal** is true, the filter will be + * applied to the horizontal axis, otherwise it will be applied to the + * vertical axis. + */ + apply(opt: SeparableKernelApplyOptions): void; + /** + * Scale all of the coefficients by **s**. + */ + scaleCoefficients(s: number): void; + } +} +declare module "filter/filter" { + /** @format */ + import { Channel } from "color/channel"; + import { Color } from "color/color"; + import { Interpolation } from "common/interpolation"; + import { Quantizer } from "image/quantizer"; + import { MemoryImage } from "image/image"; + import { DitherKernel } from "filter/dither-kernel"; + import { NoiseType } from "filter/noise-type"; + import { PixelateMode } from "filter/pixelate-mode"; + import { QuantizeMethod } from "filter/quantize-method"; + import { SeparableKernel } from "filter/separable-kernel"; + export interface AdjustColorOptions { + image: MemoryImage; + blacks?: Color; + whites?: Color; + mids?: Color; + contrast?: number; + saturation?: number; + brightness?: number; + gamma?: number; + exposure?: number; + hue?: number; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface BillboardOptions { + image: MemoryImage; + grid?: number; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface BleachBypassOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface BulgeDistortionOptions { + image: MemoryImage; + centerX?: number; + centerY?: number; + radius?: number; + scale?: number; + interpolation?: Interpolation; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface BumpToNormalOptions { + image: MemoryImage; + strength?: number; + } + export interface ChromaticAberrationOptions { + image: MemoryImage; + shift?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface ColorHalftone { + image: MemoryImage; + amount?: number; + centerX?: number; + centerY?: number; + angle?: number; + size?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface ColorOffsetOptions { + image: MemoryImage; + red?: number; + green?: number; + blue?: number; + alpha?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface ContrastOptions { + image: MemoryImage; + contrast: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface ConvolutionOptions { + image: MemoryImage; + filter: number[]; + div?: number; + offset?: number; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface CopyImageChannelsOptions { + image: MemoryImage; + from: MemoryImage; + scaled?: boolean; + red?: Channel; + green?: Channel; + blue?: Channel; + alpha?: Channel; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface DitherImageOptions { + image: MemoryImage; + quantizer?: Quantizer; + kernel?: DitherKernel; + serpentine?: boolean; + } + export interface DotScreenOptions { + image: MemoryImage; + angle?: number; + size?: number; + centerX?: number; + centerY?: number; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface DropShadowOptions { + image: MemoryImage; + hShadow: number; + vShadow: number; + blur: number; + shadowColor?: Color; + } + export interface EdgeGlowOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface EmbossOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface GammaOptions { + image: MemoryImage; + gamma: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface GaussianBlurOptions { + image: MemoryImage; + radius: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface GrayscaleOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface HdrToLdrOptions { + image: MemoryImage; + exposure?: number; + } + export interface HexagonPixelateOptions { + image: MemoryImage; + centerX?: number; + centerY?: number; + size?: number; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface InvertOptions { + image: MemoryImage; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface LuminanceThresholdOptions { + image: MemoryImage; + threshold?: number; + outputColor?: boolean; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface MonochromeOptions { + image: MemoryImage; + color?: Color; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface NoiseOptions { + image: MemoryImage; + sigma: number; + type?: NoiseType; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface NormalizeOptions { + image: MemoryImage; + min: number; + max: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface PixelateOptions { + image: MemoryImage; + size: number; + mode?: PixelateMode; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface QuantizeOptions { + image: MemoryImage; + numberOfColors?: number; + method?: QuantizeMethod; + dither?: DitherKernel; + ditherSerpentine?: boolean; + } + export interface ReinhardToneMapOptions { + image: MemoryImage; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface RemapColorsOptions { + image: MemoryImage; + red?: Channel; + green?: Channel; + blue?: Channel; + alpha?: Channel; + } + export interface ScaleRgbaOptions { + image: MemoryImage; + scale: Color; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface SeparableConvolutionOptions { + image: MemoryImage; + kernel: SeparableKernel; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface SepiaOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface SketchOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface SmoothOptions { + image: MemoryImage; + weight: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface SobelOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface StretchDistortionOptions { + image: MemoryImage; + centerX?: number; + centerY?: number; + interpolation?: Interpolation; + maskChannel?: Channel; + mask?: MemoryImage; + } + export interface VignetteOptions { + image: MemoryImage; + start?: number; + end?: number; + amount?: number; + color?: Color; + maskChannel?: Channel; + mask?: MemoryImage; + } + export abstract class Filter { + private static _contrastCache?; + private static readonly _gaussianKernelCache; + /** + * Adjust the color of the **image** using various color transformations. + * + * **blacks** defines the black level of the image, as a color. + * + * **whites** defines the white level of the image, as a color. + * + * **mids** defines the mid level of hte image, as a color. + * + * **contrast** increases (> 1) / decreases (< 1) the contrast of the image by + * pushing colors away/toward neutral gray, where at 0 the image is entirely + * neutral gray (0 contrast), 1, the image is not adjusted and > 1 the + * image increases contrast. + * + * **saturation** increases (> 1) / decreases (< 1) the saturation of the image + * by pushing colors away/toward their grayscale value, where 0 is grayscale + * and 1 is the original image, and > 1 the image becomes more saturated. + * + * **brightness** is a constant scalar of the image colors. At 0 the image + * is black, 1 unmodified, and > 1 the image becomes brighter. + * + * **gamma** is an exponential scalar of the image colors. At < 1 the image + * becomes brighter, and > 1 the image becomes darker. A **gamma** of 1/2.2 + * will convert the image colors to linear color space. + * + * **exposure** is an exponential scalar of the image as rgb* pow(2, exposure). + * At 0, the image is unmodified; as the exposure increases, the image + * brightens. + * + * **hue** shifts the hue component of the image colors in degrees. A **hue** of + * 0 will have no affect, and a **hue** of 45 will shift the hue of all colors + * by 45 degrees. + * + * **amount** controls how much affect this filter has on the **image**, where + * 0 has no effect and 1 has full effect. + * + */ + static adjustColor(opt: AdjustColorOptions): MemoryImage; + /** + * Apply the billboard filter to the image. + */ + static billboard(opt: BillboardOptions): MemoryImage; + static bleachBypass(opt: BleachBypassOptions): MemoryImage; + static bulgeDistortion(opt: BulgeDistortionOptions): MemoryImage; + /** + * Generate a normal map from a heightfield bump image. + * + * The red channel of the **image** is used as an input, 0 represents a low + * height and 1 a high value. The optional **strength** parameter allows to set + * the strength of the normal image. + */ + static bumpToNormal(opt: BumpToNormalOptions): MemoryImage; + /** + * Apply chromatic aberration filter to the image. + */ + static chromaticAberration(opt: ChromaticAberrationOptions): MemoryImage; + /** + * Apply color halftone filter to the image. + */ + static colorHalftone(opt: ColorHalftone): MemoryImage; + /** + * Add the **red**, **green**, **blue** and **alpha** values to the **image** image + * colors, a per-channel brightness. + */ + static colorOffset(opt: ColorOffsetOptions): MemoryImage; + /** + * Set the contrast level for the **image**. + * + * **contrast** values below 100 will decrees the contrast of the image, + * and values above 100 will increase the contrast. A contrast of of 100 + * will have no affect. + */ + static contrast(opt: ContrastOptions): MemoryImage; + /** + * Apply a 3x3 convolution filter to the **image**. **filter** should be a + * list of 9 numbers. + * + * The rgb channels will be divided by **div** and add **offset**, allowing + * filters to normalize and offset the filtered pixel value. + */ + static convolution(opt: ConvolutionOptions): MemoryImage; + /** + * Copy channels from the **from** image to the **image**. If **scaled** is + * true, then the **from** image will be scaled to the **image** resolution. + */ + static copyImageChannels(opt: CopyImageChannelsOptions): MemoryImage; + /** + * Dither an image to reduce banding patterns when reducing the number of + * colors. + */ + static ditherImage(opt: DitherImageOptions): MemoryImage; + /** + * Apply the dot screen filter to the image. + */ + static dotScreen(opt: DotScreenOptions): MemoryImage; + /** + * Create a drop-shadow effect for the image. + */ + static dropShadow(opt: DropShadowOptions): MemoryImage; + /** + * Apply the edge glow filter to the image. + */ + static edgeGlow(opt: EdgeGlowOptions): MemoryImage; + /** + * Apply an emboss convolution filter. + */ + static emboss(opt: EmbossOptions): MemoryImage; + /** + * Apply gamma scaling + */ + static gamma(opt: GammaOptions): MemoryImage; + /** + * Apply gaussian blur to the **image**. **radius** determines how many pixels + * away from the current pixel should contribute to the blur, where 0 is no + * blur and the larger the **radius**, the stronger the blur. + */ + static gaussianBlur(opt: GaussianBlurOptions): MemoryImage; + /** + * Convert the image to grayscale. + */ + static grayscale(opt: GrayscaleOptions): MemoryImage; + /** + * Convert a high dynamic range image to a low dynamic range image, + * with optional exposure control. + */ + static hdrToLdr(opt: HdrToLdrOptions): MemoryImage; + /** + * Apply the hexagon pixelate filter to the image. + */ + static hexagonPixelate(opt: HexagonPixelateOptions): MemoryImage; + /** + * Invert the colors of the **image**. + */ + static invert(opt: InvertOptions): MemoryImage; + static luminanceThreshold(opt: LuminanceThresholdOptions): MemoryImage; + /** + * Apply the monochrome filter to the **image**. + * + * **amount** controls the strength of the effect, in the range [0, 1]. + */ + static monochrome(opt: MonochromeOptions): MemoryImage; + /** + * Add random noise to pixel values. **sigma** determines how strong the effect + * should be. **type** should be one of the following: _NoiseType.gaussian_, + * _NoiseType.uniform_, _NoiseType.saltAndPepper_, _NoiseType.poisson_, + * or _NoiseType.rice_. + */ + static noise(opt: NoiseOptions): MemoryImage; + /** + * Linearly normalize the colors of the image. All color values will be mapped + * to the range **min**, **max** inclusive. + */ + static normalize(opt: NormalizeOptions): MemoryImage; + /** + * Pixelate the **image**. + * + * **size** determines the size of the pixelated blocks. + * If **mode** is **upperLeft** then the upper-left corner of the + * block will be used for the block color. Otherwise if **mode** is + * **average**, the average of all the pixels in the block will be + * used for the block color. + */ + static pixelate(opt: PixelateOptions): MemoryImage; + /** + * Quantize the number of colors in image to 256. + */ + static quantize(opt: QuantizeOptions): MemoryImage; + /** + * Applies Reinhard tone mapping to the hdr image, in-place. + */ + static reinhardToneMap(opt: ReinhardToneMapOptions): MemoryImage; + /** + * Remap the color channels of the image. + * **red**, **green**, **blue** and **alpha** should be set to one of the following: + * _Channel.red_, _Channel.green_, _Channel.blue_, _Channel.alpha_, or + * _Channel.luminance_. + */ + static remapColors(opt: RemapColorsOptions): MemoryImage; + static scaleRgba(opt: ScaleRgbaOptions): MemoryImage; + /** + * Apply a generic separable convolution filter to the **image**, using the + * given **kernel**. + * + * **gaussianBlur** is an example of such a filter. + */ + static separableConvolution(opt: SeparableConvolutionOptions): MemoryImage; + /** + * Apply sepia tone to the **image**. + * + * **amount** controls the strength of the effect, in the range [0, 1]. + */ + static sepia(opt: SepiaOptions): MemoryImage; + /** + * Apply sketch filter to the **image**. + * + * **amount** controls the strength of the effect, in the range [0, 1]. + */ + static sketch(opt: SketchOptions): MemoryImage; + /** + * Apply a smoothing convolution filter to the **image**. + * + * **weight** is the weight of the current pixel being filtered. If it's greater + * than 1, it will make the image sharper. + */ + static smooth(opt: SmoothOptions): MemoryImage; + /** + * Apply Sobel edge detection filtering to the **image**. + */ + static sobel(opt: SobelOptions): MemoryImage; + static stretchDistortion(opt: StretchDistortionOptions): MemoryImage; + /** + * Apply a vignette filter to the **image**. + * + * **start** is the inner radius from the center of the image, where the fade to + * **color** starts to be applied; **end** is the outer radius of the + * vignette effect where the **color** is fully applied. The radius values are in + * normalized percentage of the image size [0, 1]. + * **amount** controls the blend of the effect with the original image. + */ + static vignette(opt: VignetteOptions): MemoryImage; + } +} +declare module "formats/gif-encoder" { + import { Encoder } from "formats/encoder"; + import { MemoryImage } from "image/image"; + import { DitherKernel } from "filter/dither-kernel"; + export interface GifEncoderInitOptions { + delay?: number; + repeat?: number; + samplingFactor?: number; + dither?: DitherKernel; + ditherSerpentine?: boolean; + } + export class GifEncoder implements Encoder { + private static readonly _gif89Id; + private static readonly _imageDescRecordType; + private static readonly _extensionRecordType; + private static readonly _terminateRecordType; + private static readonly _applicationExt; + private static readonly _graphicControlExt; + private static readonly _eof; + private static readonly _bits; + private static readonly _hSize; + private static readonly _masks; + private _delay; + private _repeat; + private _numColors; + private _quantizerType; + private _samplingFactor; + private _lastImage?; + private _lastImageDuration?; + private _lastColorMap?; + private _width; + private _height; + private _encodedFrames; + private _curAccum; + private _curBits; + private _nBits; + private _initBits; + private _eofCode; + private _maxCode; + private _clearCode; + private _freeEnt; + private _clearFlag; + private _block; + private _blockSize; + private _outputBuffer?; + private _dither; + private _ditherSerpentine; + /** + * Does this encoder support animation? + */ + private readonly _supportsAnimation; + get supportsAnimation(): boolean; + constructor(opt?: GifEncoderInitOptions); + private addImage; + private encodeLZW; + private output; + private writeBlock; + private addToBlock; + private writeApplicationExt; + private writeGraphicsCtrlExt; + private writeHeader; + /** + * Encode the images that were added with **addFrame**. + * After this has been called (returning the finishes GIF), + * calling **addFrame** for a new animation or image is safe again. + * + * **addFrame** will not encode the first image passed and after that + * always encode the previous image. Hence, the last image needs to be + * encoded here. + */ + private finish; + /** + * This adds the frame passed to **image**. + * After the last frame has been added, **finish** is required to be called. + * Optional frame **duration** is in 1/100 sec. + * */ + addFrame(image: MemoryImage, duration?: number): void; + /** + * Encode a single frame image. + */ + encode(image: MemoryImage, singleFrame?: boolean): Uint8Array; + } +} +declare module "formats/dib-decoder" { + /** @format */ + import { InputBuffer } from "common/input-buffer"; + import { BmpDecoder } from "formats/bmp-decoder"; + import { BmpInfo } from "formats/bmp/bmp-info"; + export class DibDecoder extends BmpDecoder { + constructor(input: InputBuffer, info: BmpInfo, forceRgba?: boolean); + } +} +declare module "formats/ico/ico-bmp-info" { + /** @format */ + import { BmpInfo } from "formats/bmp/bmp-info"; + export class IcoBmpInfo extends BmpInfo { + get height(): number; + get ignoreAlphaChannel(): boolean; + } +} +declare module "formats/ico/ico-info-image" { + /** @format */ + export interface IcoInfoImageInitOptions { + width: number; + height: number; + colorPalette: number; + bytesSize: number; + bytesOffset: number; + colorPlanes: number; + bitsPerPixel: number; + } + export class IcoInfoImage { + private readonly _width; + get width(): number; + private readonly _height; + get height(): number; + private readonly _colorPalette; + get colorPalette(): number; + private readonly _bytesSize; + get bytesSize(): number; + private readonly _bytesOffset; + get bytesOffset(): number; + private readonly _colorPlanes; + get colorPlanes(): number; + private readonly _bitsPerPixel; + get bitsPerPixel(): number; + constructor(opt: IcoInfoImageInitOptions); + } +} +declare module "formats/ico/ico-type" { + /** @format */ + export enum IcoType { + invalid = 0, + ico = 1, + cur = 2 + } + export const IcoTypeLength = 3; +} +declare module "formats/ico/ico-info" { + /** @format */ + import { Color } from "color/color"; + import { InputBuffer } from "common/input-buffer"; + import { DecodeInfo } from "formats/decode-info"; + import { IcoInfoImage } from "formats/ico/ico-info-image"; + import { IcoType } from "formats/ico/ico-type"; + export class IcoInfo implements DecodeInfo { + private _width; + get width(): number; + private _height; + get height(): number; + private readonly _type; + get type(): IcoType; + private readonly _numFrames; + get numFrames(): number; + private _backgroundColor; + get backgroundColor(): Color | undefined; + private readonly _images; + get images(): IcoInfoImage[]; + constructor(type: number, numFrames: number, images: IcoInfoImage[]); + static read(input: InputBuffer): IcoInfo | undefined; + } +} +declare module "common/crc32" { + /** @format */ + export interface Crc32Options { + buffer: Uint8Array; + baseCrc?: number; + position?: number; + length?: number; + } + export abstract class Crc32 { + private static readonly _crcTable; + private static makeTable; + static getChecksum(opt: Crc32Options): number; + } +} +declare module "formats/png/png-blend-mode" { + /** @format */ + export enum PngBlendMode { + /** + * No alpha blending should be done when drawing this frame (replace pixels in canvas). + */ + source = 0, + /** + * * Alpha blending should be used when drawing this frame (composited over + * the current canvas image). + */ + over = 1 + } +} +declare module "formats/png/png-dispose-mode" { + /** @format */ + export enum PngDisposeMode { + none = 0, + background = 1, + previous = 2 + } +} +declare module "formats/png/png-frame" { + /** @format */ + import { PngBlendMode } from "formats/png/png-blend-mode"; + import { PngDisposeMode } from "formats/png/png-dispose-mode"; + export interface PngFrameInitOptions { + sequenceNumber?: number; + width?: number; + height?: number; + xOffset?: number; + yOffset?: number; + delayNum?: number; + delayDen?: number; + dispose?: number; + blend?: number; + } + export class PngFrame { + private readonly _fdat; + get fdat(): number[]; + private _sequenceNumber; + get sequenceNumber(): number; + private _width; + get width(): number; + private _height; + get height(): number; + private _xOffset; + get xOffset(): number; + private _yOffset; + get yOffset(): number; + private _delayNum; + get delayNum(): number; + private _delayDen; + get delayDen(): number; + private _dispose; + get dispose(): PngDisposeMode; + private _blend; + get blend(): PngBlendMode; + get delay(): number; + constructor(opt: PngFrameInitOptions); + } +} +declare module "formats/png/png-color-type" { + /** @format */ + export enum PngColorType { + grayscale = 0, + rgb = 2, + indexed = 3, + grayscaleAlpha = 4, + rgba = 6 + } +} +declare module "formats/png/png-info" { + /** @format */ + import { Color } from "color/color"; + import { DecodeInfo } from "formats/decode-info"; + import { PngColorType } from "formats/png/png-color-type"; + import { PngFrame } from "formats/png/png-frame"; + export interface PngInfoInitOptions { + width?: number; + height?: number; + bits?: number; + colorType?: number; + compressionMethod?: number; + filterMethod?: number; + interlaceMethod?: number; + } + export class PngInfo implements DecodeInfo { + private _width; + get width(): number; + set width(v: number); + private _height; + set height(v: number); + get height(): number; + private _backgroundColor; + get backgroundColor(): Color | undefined; + set backgroundColor(v: Color | undefined); + private _numFrames; + get numFrames(): number; + set numFrames(v: number); + private _bits; + get bits(): number; + set bits(v: number); + private _colorType; + get colorType(): PngColorType | undefined; + set colorType(v: PngColorType | undefined); + private _compressionMethod; + get compressionMethod(): number; + set compressionMethod(v: number); + private _filterMethod; + get filterMethod(): number; + set filterMethod(v: number); + private _interlaceMethod; + get interlaceMethod(): number; + set interlaceMethod(v: number); + private _palette?; + get palette(): Uint8Array | undefined; + set palette(v: Uint8Array | undefined); + private _transparency?; + get transparency(): Uint8Array | undefined; + set transparency(v: Uint8Array | undefined); + private _gamma?; + get gamma(): number | undefined; + set gamma(v: number | undefined); + private _iccpName; + get iccpName(): string; + set iccpName(v: string); + private _iccpCompression; + get iccpCompression(): number; + set iccpCompression(v: number); + private _iccpData?; + get iccpData(): Uint8Array | undefined; + set iccpData(v: Uint8Array | undefined); + private _textData; + get textData(): Map; + private _repeat; + get repeat(): number; + set repeat(v: number); + private readonly _idat; + get idat(): number[]; + private readonly _frames; + get frames(): PngFrame[]; + get isAnimated(): boolean; + constructor(opt?: PngInfoInitOptions); + } +} +declare module "formats/png/png-filter-type" { + /** @format */ + export enum PngFilterType { + none = 0, + sub = 1, + up = 2, + average = 3, + paeth = 4 + } +} +declare module "formats/png-decoder" { + import { InputBuffer } from "common/input-buffer"; + import { DecodeInfo } from "formats/decode-info"; + import { Decoder } from "formats/decoder"; + import { PngInfo } from "formats/png/png-info"; + import { MemoryImage } from "image/image"; + /** + * Decode a PNG encoded image. + */ + export class PngDecoder implements Decoder { + private _input?; + get input(): InputBuffer | undefined; + private _info; + get info(): PngInfo; + private _progressY; + get progressY(): number; + private _bitBuffer; + get bitBuffer(): number; + private _bitBufferLen; + get bitBufferLen(): number; + /** + * The number of frames that can be decoded. + */ + get numFrames(): number; + private static unfilter; + /** + * Return the CRC of the bytes + */ + private static crc; + /** + * Process a pass of an interlaced image. + */ + private processPass; + private process; + private resetBits; + /** + * Read a number of bits from the input stream. + */ + private readBits; + /** + * Read the next pixel from the input stream. + */ + private readPixel; + private setPixel; + /** + * Is the given file a valid PNG image? + */ + isValidFile(bytes: Uint8Array): boolean; + /** + * Start decoding the data as an animation sequence, but don't actually + * process the frames until they are requested with decodeFrame. + */ + startDecode(bytes: Uint8Array): DecodeInfo | undefined; + /** + * Decode the frame (assuming **startDecode** has already been called). + */ + decodeFrame(frame: number): MemoryImage | undefined; + decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined; + } +} +declare module "formats/ico-decoder" { + import { Decoder } from "formats/decoder"; + import { IcoInfo } from "formats/ico/ico-info"; + import { MemoryImage } from "image/image"; + export class IcoDecoder implements Decoder { + private _input?; + private _info?; + get numFrames(): number; + isValidFile(bytes: Uint8Array): boolean; + startDecode(bytes: Uint8Array): IcoInfo | undefined; + decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined; + decodeFrame(frame: number): MemoryImage | undefined; + /** + * Decodes the largest frame. + */ + decodeImageLargest(bytes: Uint8Array): MemoryImage | undefined; + } +} +declare module "formats/png-encoder" { + import { CompressionLevel } from "common/typings"; + import { Encoder } from "formats/encoder"; + import { PngFilterType } from "formats/png/png-filter-type"; + import { MemoryImage } from "image/image"; + export interface PngEncoderInitOptions { + filter?: PngFilterType; + level?: CompressionLevel; + } + /** + * Encode an image to the PNG format. + */ + export class PngEncoder implements Encoder { + private _globalQuantizer; + private _filter; + private _level; + private _repeat; + private _frames; + private _sequenceNumber; + private _isAnimated; + private _output; + /** + * Does this encoder support animation? + */ + private _supportsAnimation; + get supportsAnimation(): boolean; + constructor(opt?: PngEncoderInitOptions); + /** + * Return the CRC of the bytes + */ + private static crc; + private static writeChunk; + private static write; + private static filterSub; + private static filterUp; + private static filterAverage; + private static paethPredictor; + private static filterPaeth; + private static filterNone; + private static numChannels; + private writeHeader; + private writeICCPChunk; + private writeAnimationControlChunk; + private writeFrameControlChunk; + private writePalette; + private writeTextChunk; + private filter; + addFrame(image: MemoryImage): void; + finish(): Uint8Array | undefined; + /** + * Encode **image** to the PNG format. + */ + encode(image: MemoryImage, singleFrame?: boolean): Uint8Array; + } +} +declare module "formats/win-encoder" { + import { MemoryImage } from "image/image"; + import { Encoder } from "formats/encoder"; + export abstract class WinEncoder implements Encoder { + protected _type: number; + get type(): number; + private _supportsAnimation; + get supportsAnimation(): boolean; + protected colorPlanesOrXHotSpot(_index: number): number; + protected bitsPerPixelOrYHotSpot(_index: number): number; + encode(image: MemoryImage, singleFrame?: boolean): Uint8Array; + encodeImages(images: MemoryImage[]): Uint8Array; + } +} +declare module "formats/ico-encoder" { + /** @format */ + import { WinEncoder } from "formats/win-encoder"; + export class IcoEncoder extends WinEncoder { + protected _type: number; + protected colorPlanesOrXHotSpot(_index: number): number; + protected bitsPerPixelOrYHotSpot(_index: number): number; + } +} +declare module "formats/jpeg/jpeg-component-data" { + /** @format */ + export class JpegComponentData { + private _hSamples; + get hSamples(): number; + private _maxHSamples; + get maxHSamples(): number; + private _vSamples; + get vSamples(): number; + private _maxVSamples; + get maxVSamples(): number; + private _lines; + get lines(): Array; + private _hScaleShift; + get hScaleShift(): number; + private _vScaleShift; + get vScaleShift(): number; + constructor(hSamples: number, maxHSamples: number, vSamples: number, maxVSamples: number, lines: Array); + } +} +declare module "formats/jpeg/jpeg-adobe" { + /** @format */ + export class JpegAdobe { + private _version; + get version(): number; + private _flags0; + get flags0(): number; + private _flags1; + get flags1(): number; + private _transformCode; + get transformCode(): number; + constructor(version: number, flags0: number, flags1: number, transformCode: number); + } +} +declare module "formats/jpeg/huffman-node" { + /** @format */ + export abstract class HuffmanNode { + } +} +declare module "formats/jpeg/jpeg-component" { + /** @format */ + import { HuffmanNode } from "formats/jpeg/huffman-node"; + export class JpegComponent { + private readonly _quantizationTableList; + private readonly _quantizationIndex; + private readonly _hSamples; + get hSamples(): number; + private readonly _vSamples; + get vSamples(): number; + private _blocks; + get blocks(): Array>; + private _blocksPerLine; + get blocksPerLine(): number; + private _blocksPerColumn; + get blocksPerColumn(): number; + private _huffmanTableDC; + set huffmanTableDC(v: Array); + get huffmanTableDC(): Array; + private _huffmanTableAC; + set huffmanTableAC(v: Array); + get huffmanTableAC(): Array; + private _pred; + set pred(v: number); + get pred(): number; + get quantizationTable(): Int16Array | undefined; + constructor(hSamples: number, vSamples: number, quantizationTableList: Array, quantizationIndex: number); + setBlocks(blocks: Array>, blocksPerLine: number, blocksPerColumn: number): void; + } +} +declare module "formats/jpeg/jpeg-frame" { import { JpegComponent } from "formats/jpeg/jpeg-component"; export class JpegFrame { private readonly _components; @@ -3382,15 +6704,15 @@ declare module "formats/jpeg/jpeg-frame" { private _mcusPerColumn; get mcusPerColumn(): number; constructor(components: Map, componentsOrder: Array, extended: boolean, progressive: boolean, precision: number, scanLines: number, samplesPerLine: number); - private static getEmptyBlocks; prepare(): void; } } declare module "formats/jpeg/jpeg-huffman" { /** @format */ + import { HuffmanNode } from "formats/jpeg/huffman-node"; export class JpegHuffman { private readonly _children; - get children(): Array; + get children(): Array; private _index; get index(): number; incrementIndex(): void; @@ -3398,16 +6720,17 @@ declare module "formats/jpeg/jpeg-huffman" { } declare module "formats/jpeg/jpeg-info" { /** @format */ + import { Color } from "color/color"; import { DecodeInfo } from "formats/decode-info"; export class JpegInfo implements DecodeInfo { private _width; get width(): number; private _height; get height(): number; - private _backgroundColor; - get backgroundColor(): number; private _numFrames; get numFrames(): number; + private _backgroundColor; + get backgroundColor(): Color | undefined; setSize(width: number, height: number): void; } } @@ -3433,1453 +6756,1331 @@ declare module "formats/jpeg/jpeg-jfif" { get thumbData(): InputBuffer; constructor(thumbWidth: number, thumbHeight: number, majorVersion: number, minorVersion: number, densityUnits: number, xDensity: number, yDensity: number, thumbData: InputBuffer); } -} -declare module "formats/jpeg/jpeg-quantize" { - import { MemoryImage } from "common/memory-image"; - import { JpegData } from "formats/jpeg/jpeg-data"; - export abstract class JpegQuantize { - private static dctClip; - private static clamp8; - static quantizeAndInverse(quantizationTable: Int16Array, coefBlock: Int32Array, dataOut: Uint8Array, dataIn: Int32Array): void; - static getImageFromJpeg(jpeg: JpegData): MemoryImage; - } -} -declare module "formats/jpeg/jpeg-scan" { - /** @format */ - import { InputBuffer } from "common/input-buffer"; - import { JpegComponent } from "formats/jpeg/jpeg-component"; - import { JpegFrame } from "formats/jpeg/jpeg-frame"; - export class JpegScan { - private _input; - get input(): InputBuffer; - private _frame; - get frame(): JpegFrame; - private _precision; - get precision(): number; - private _samplesPerLine; - get samplesPerLine(): number; - private _scanLines; - get scanLines(): number; - private _mcusPerLine; - get mcusPerLine(): number; - private _progressive; - get progressive(): boolean; - private _maxH; - get maxH(): number; - private _maxV; - get maxV(): number; - private _components; - get components(): Array; - private _resetInterval?; - get resetInterval(): number | undefined; - private _spectralStart; - get spectralStart(): number; - private _spectralEnd; - get spectralEnd(): number; - private _successivePrev; - get successivePrev(): number; - private _successive; - get successive(): number; - private _bitsData; - get bitsData(): number; - private _bitsCount; - get bitsCount(): number; - private _eobrun; - get eobrun(): number; - private _successiveACState; - get successiveACState(): number; - private _successiveACNextValue; - get successiveACNextValue(): number; - constructor(input: InputBuffer, frame: JpegFrame, components: Array, spectralStart: number, spectralEnd: number, successivePrev: number, successive: number, resetInterval?: number); - private readBit; - private decodeHuffman; - private receive; - private receiveAndExtend; - private decodeBaseline; - private decodeDCFirst; - private decodeDCSuccessive; - private decodeACFirst; - private decodeACSuccessive; - private decodeMcu; - private decodeBlock; - decode(): void; - } -} -declare module "formats/jpeg/jpeg-data" { - /** @format */ - import { InputBuffer } from "common/input-buffer"; - import { MemoryImage } from "common/memory-image"; - import { ComponentData } from "formats/jpeg/component-data"; - import { JpegAdobe } from "formats/jpeg/jpeg-adobe"; - import { JpegFrame } from "formats/jpeg/jpeg-frame"; - import { JpegInfo } from "formats/jpeg/jpeg-info"; - import { JpegJfif } from "formats/jpeg/jpeg-jfif"; - import { ExifData } from "exif/exif-data"; - export class JpegData { - static readonly CRR: number[]; - static readonly CRG: number[]; - static readonly CBG: number[]; - static readonly CBB: number[]; - private _input; - get input(): InputBuffer; - private _jfif; - get jfif(): JpegJfif; - private _adobe; - get adobe(): JpegAdobe; - private _frame?; - get frame(): JpegFrame | undefined; - private _resetInterval; - get resetInterval(): number; - private _comment?; - get comment(): string | undefined; - private readonly _exifData; - get exifData(): ExifData; - private readonly _quantizationTables; - get quantizationTables(): Array; - private readonly _frames; - get frames(): Array; - private readonly _huffmanTablesAC; - get huffmanTablesAC(): Array<[] | undefined>; - private readonly _huffmanTablesDC; - get huffmanTablesDC(): Array<[] | undefined>; - private readonly _components; - get components(): Array; - get width(): number; - get height(): number; - private readMarkers; - private skipBlock; - validate(bytes: Uint8Array): boolean; - readInfo(bytes: Uint8Array): JpegInfo | undefined; - read(bytes: Uint8Array): void; - getImage(): MemoryImage; - private static buildHuffmanTable; - private static buildComponentData; - static toFix(val: number): number; - private readBlock; - private nextMarker; - private readExifData; - private readAppData; - private readDQT; - private readFrame; - private readDHT; - private readDRI; - private readSOS; - } -} -declare module "formats/jpeg-decoder" { - /** @format */ - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; - import { HdrImage } from "hdr/hdr-image"; - import { Decoder } from "formats/decoder"; - import { JpegInfo } from "formats/jpeg/jpeg-info"; - /** - * Decode a jpeg encoded image. - */ - export class JpegDecoder implements Decoder { - private info?; - private input?; - get numFrames(): number; - /** - * Is the given file a valid JPEG image? - */ - isValidFile(bytes: Uint8Array): boolean; - startDecode(bytes: Uint8Array): JpegInfo | undefined; - decodeFrame(_: number): MemoryImage | undefined; - decodeHdrFrame(frame: number): HdrImage | undefined; - decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined; - decodeImage(bytes: Uint8Array, _?: number): MemoryImage | undefined; - decodeHdrImage(bytes: Uint8Array, frame?: number): HdrImage | undefined; - } -} -declare module "formats/jpeg-encoder" { - /** @format */ - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; - import { Encoder } from "formats/encoder"; - /** - * Encode an image to the JPEG format. - */ - export class JpegEncoder implements Encoder { - private static readonly ZIGZAG; - private static readonly STD_DC_LUMINANCE_NR_CODES; - private static readonly STD_DC_LUMINANCE_VALUES; - private static readonly STD_AC_LUMINANCE_NR_CODES; - private static readonly STD_AC_LUMINANCE_VALUES; - private static readonly STD_DC_CHROMINANCE_NR_CODES; - private static readonly STD_DC_CHROMINANCE_VALUES; - private static readonly STD_AC_CHROMINANCE_NR_CODES; - private static readonly STD_AC_CHROMINANCE_VALUES; - private readonly tableY; - private readonly tableUV; - private readonly ftableY; - private readonly ftableUV; - private readonly bitcode; - private readonly category; - private readonly outputfDCTQuant; - private readonly DU; - private readonly YDU; - private readonly UDU; - private readonly VDU; - private readonly tableRGBYUV; - private htYDC; - private htUVDC; - private htYAC; - private htUVAC; - private currentQuality?; - private byteNew; - private bytePos; - private _supportsAnimation; - get supportsAnimation(): boolean; - constructor(quality?: number); - private static computeHuffmanTable; - private static writeMarker; - private static writeAPP0; - private static writeAPP1; - private static writeSOF0; - private static writeSOS; - private static writeDHT; - private initHuffmanTable; - private initCategoryNumber; - private initRGBYUVTable; - private setQuality; - private initQuantTables; - private fDCTQuant; - private writeDQT; - private writeBits; - private resetBits; - private processDU; - encodeImage(image: MemoryImage): Uint8Array; - encodeAnimation(_: FrameAnimation): Uint8Array | undefined; - } -} -declare module "formats/tga/tga-info" { - /** @format */ - import { DecodeInfo } from "formats/decode-info"; - export interface TgaInfoInitOptions { - width?: number; - height?: number; - imageOffset?: number; - bitsPerPixel?: number; - } - export class TgaInfo implements DecodeInfo { - private readonly _width; - get width(): number; - protected readonly _height: number; - get height(): number; - private readonly _backgroundColor; - get backgroundColor(): number; - /** - * The number of frames that can be decoded. - */ - private readonly _numFrames; - get numFrames(): number; - /** - * Offset in the input file the image data starts at. - */ - private readonly _imageOffset; - get imageOffset(): number | undefined; - /** - * Bits per pixel. - */ - private readonly _bitsPerPixel; - get bitsPerPixel(): number | undefined; - constructor(options?: TgaInfoInitOptions); - } -} -declare module "formats/tga-decoder" { - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; - import { HdrImage } from "hdr/hdr-image"; - import { Decoder } from "formats/decoder"; - import { TgaInfo } from "formats/tga/tga-info"; - /** - * Decode a TGA image. This only supports the 24-bit uncompressed format. - */ - export class TgaDecoder implements Decoder { - private info; - private input; - get numFrames(): number; - /** - * Is the given file a valid TGA image? - */ - isValidFile(bytes: Uint8Array): boolean; - startDecode(bytes: Uint8Array): TgaInfo | undefined; - decodeFrame(_frame: number): MemoryImage | undefined; - decodeHdrFrame(frame: number): HdrImage | undefined; - decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined; - decodeImage(bytes: Uint8Array, frame?: number): MemoryImage | undefined; - decodeHdrImage(bytes: Uint8Array, frame?: number | undefined): HdrImage | undefined; - } -} -declare module "formats/tga-encoder" { - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; - import { Encoder } from "formats/encoder"; - /** - * Encode a TGA image. This only supports the 24-bit uncompressed format. - */ - export class TgaEncoder implements Encoder { - private _supportsAnimation; - get supportsAnimation(): boolean; - encodeImage(image: MemoryImage): Uint8Array; - encodeAnimation(_animation: FrameAnimation): Uint8Array | undefined; - } -} -declare module "formats/tiff/tiff-bit-reader" { - /** @format */ - import { InputBuffer } from "common/input-buffer"; - export class TiffBitReader { - private static readonly BITMASK; - private bitBuffer; - private bitPosition; - private input; - constructor(input: InputBuffer); - /** - * Read a number of bits from the input stream. - */ - readBits(numBits: number): number; - readByte(): number; - /** - * Flush the rest of the bits in the buffer so the next read starts at the next byte. - */ - flushByte(): number; +} +declare module "formats/jpeg/jpeg-quantize" { + import { MemoryImage } from "image/image"; + import { JpegData } from "formats/jpeg/jpeg-data"; + export abstract class JpegQuantize { + private static readonly _dctClipOffset; + private static readonly _dctClipLength; + private static readonly _dctClip; + private static createDctClip; + static quantizeAndInverse(quantizationTable: Int16Array, coefBlock: Int32Array, dataOut: Uint8Array, dataIn: Int32Array): void; + static getImageFromJpeg(jpeg: JpegData): MemoryImage; } } -declare module "formats/tiff/tiff-entry" { +declare module "formats/jpeg/huffman-parent" { /** @format */ - import { InputBuffer } from "common/input-buffer"; - export interface TiffEntryInitOptions { - tag: number; - type: number; - numValues: number; - p: InputBuffer; - } - export class TiffEntry { - private static readonly SIZE_OF_TYPE; - static readonly TYPE_BYTE = 1; - static readonly TYPE_ASCII = 2; - static readonly TYPE_SHORT = 3; - static readonly TYPE_LONG = 4; - static readonly TYPE_RATIONAL = 5; - static readonly TYPE_SBYTE = 6; - static readonly TYPE_UNDEFINED = 7; - static readonly TYPE_SSHORT = 8; - static readonly TYPE_SLONG = 9; - static readonly TYPE_SRATIONAL = 10; - static readonly TYPE_FLOAT = 11; - static readonly TYPE_DOUBLE = 12; - private _tag; - get tag(): number; - private _type; - get type(): number; - private _numValues; - get numValues(): number; - private _valueOffset; - get valueOffset(): number | undefined; - set valueOffset(v: number | undefined); - private _p; - get p(): InputBuffer; - get isValid(): boolean; - get typeSize(): number; - get isString(): boolean; - constructor(options: TiffEntryInitOptions); - private readValueInternal; - toString(): string; - readValue(): number; - readValues(): number[]; - readString(): string; - read(): number[]; + import { HuffmanNode } from "formats/jpeg/huffman-node"; + export class HuffmanParent extends HuffmanNode { + private readonly _children; + get children(): Array; + constructor(children: Array); } } -declare module "formats/tiff/tiff-fax-decoder" { +declare module "formats/jpeg/huffman-value" { /** @format */ - import { InputBuffer } from "common/input-buffer"; - export interface TiffFaxDecoderInitOptions { - fillOrder: number; - width: number; - height: number; - } - export class TiffFaxDecoder { - private static readonly TABLE1; - private static readonly TABLE2; - /** - * Table to be used when **fillOrder** = 2, for flipping bytes. - */ - private static readonly FLIP_TABLE; - /** - * The main 10 bit white runs lookup table - */ - private static readonly WHITE; - /** - * Additional make up codes for both White and Black runs - */ - private static readonly ADDITIONAL_MAKEUP; - /** - * Initial black run look up table, uses the first 4 bits of a code - */ - private static readonly INIT_BLACK; - private static readonly TWO_BIT_BLACK; - /** - * Main black run table, using the last 9 bits of possible 13 bit code - */ - private static readonly BLACK; - private static readonly TWO_D_CODES; - private _width; - get width(): number; - private _height; - get height(): number; - private _fillOrder; - get fillOrder(): number; - private changingElemSize; - private prevChangingElems?; - private currChangingElems?; - private data; - private bitPointer; - private bytePointer; - private lastChangingElement; - private compression; - private uncompressedMode; - private fillBits; - private oneD; - constructor(options: TiffFaxDecoderInitOptions); - private nextNBits; - private nextLesserThan8Bits; - /** - * Move pointer backwards by given amount of bits - */ - private updatePointer; - /** - * Move to the next byte boundary - */ - private advancePointer; - private setToBlack; - private decodeNextScanline; - private readEOL; - private getNextChangingElement; - /** - * Returns run length - */ - private decodeWhiteCodeWord; - /** - * Returns run length - */ - private decodeBlackCodeWord; - /** - * One-dimensional decoding methods - */ - decode1D(out: InputBuffer, compData: InputBuffer, startX: number, height: number): void; - /** - * Two-dimensional decoding methods - */ - decode2D(out: InputBuffer, compData: InputBuffer, startX: number, height: number, tiffT4Options: number): void; - decodeT6(out: InputBuffer, compData: InputBuffer, startX: number, height: number, tiffT6Options: number): void; + import { HuffmanNode } from "formats/jpeg/huffman-node"; + export class HuffmanValue extends HuffmanNode { + private readonly _value; + get value(): number; + constructor(value: number); } } -declare module "formats/tiff/tiff-lzw-decoder" { +declare module "formats/jpeg/jpeg-marker" { /** @format */ - import { InputBuffer } from "common/input-buffer"; - export class LzwDecoder { - private static readonly LZ_MAX_CODE; - private static readonly NO_SUCH_CODE; - private static readonly AND_TABLE; - private readonly buffer; - private bitsToGet; - private bytePointer; - private nextData; - private nextBits; - private data; - private dataLength; - private out; - private outPointer; - private table; - private prefix; - private tableIndex?; - private bufferLength; - private addString; - private getString; - /** - * Returns the next 9, 10, 11 or 12 bits - */ - private getNextCode; - /** - * Initialize the string table. - */ - private initializeStringTable; - decode(p: InputBuffer, out: Uint8Array): void; + export enum JpegMarker { + sof0 = 192, + sof1 = 193, + sof2 = 194, + sof3 = 195, + sof5 = 197, + sof6 = 198, + sof7 = 199, + jpg = 200, + sof9 = 201, + sof10 = 202, + sof11 = 203, + sof13 = 205, + sof14 = 206, + sof15 = 207, + dht = 196, + dac = 204, + rst0 = 208, + rst1 = 209, + rst2 = 210, + rst3 = 211, + rst4 = 212, + rst5 = 213, + rst6 = 214, + rst7 = 215, + soi = 216, + eoi = 217, + sos = 218, + dqt = 219, + dnl = 220, + dri = 221, + dhp = 222, + exp = 223, + app0 = 224, + app1 = 225, + app2 = 226, + app3 = 227, + app4 = 228, + app5 = 229, + app6 = 230, + app7 = 231, + app8 = 232, + app9 = 233, + app10 = 234, + app11 = 235, + app12 = 236, + app13 = 237, + app14 = 238, + app15 = 239, + jpg0 = 240, + jpg13 = 253, + com = 254, + tem = 1, + error = 256 } } -declare module "formats/tiff/tiff-image" { +declare module "formats/jpeg/jpeg-scan" { + /** @format */ import { InputBuffer } from "common/input-buffer"; - import { MemoryImage } from "common/memory-image"; - import { HdrImage } from "hdr/hdr-image"; - import { TiffEntry } from "formats/tiff/tiff-entry"; - export class TiffImage { - static readonly COMPRESSION_NONE = 1; - static readonly COMPRESSION_CCITT_RLE = 2; - static readonly COMPRESSION_CCITT_FAX3 = 3; - static readonly COMPRESSION_CCITT_FAX4 = 4; - static readonly COMPRESSION_LZW = 5; - static readonly COMPRESSION_OLD_JPEG = 6; - static readonly COMPRESSION_JPEG = 7; - static readonly COMPRESSION_NEXT = 32766; - static readonly COMPRESSION_CCITT_RLEW = 32771; - static readonly COMPRESSION_PACKBITS = 32773; - static readonly COMPRESSION_THUNDERSCAN = 32809; - static readonly COMPRESSION_IT8CTPAD = 32895; - static readonly COMPRESSION_IT8LW = 32896; - static readonly COMPRESSION_IT8MP = 32897; - static readonly COMPRESSION_IT8BL = 32898; - static readonly COMPRESSION_PIXARFILM = 32908; - static readonly COMPRESSION_PIXARLOG = 32909; - static readonly COMPRESSION_DEFLATE = 32946; - static readonly COMPRESSION_ZIP = 8; - static readonly COMPRESSION_DCS = 32947; - static readonly COMPRESSION_JBIG = 34661; - static readonly COMPRESSION_SGILOG = 34676; - static readonly COMPRESSION_SGILOG24 = 34677; - static readonly COMPRESSION_JP2000 = 34712; - static readonly PHOTOMETRIC_BLACKISZERO = 1; - static readonly PHOTOMETRIC_RGB = 2; - static readonly TYPE_UNSUPPORTED = -1; - static readonly TYPE_BILEVEL = 0; - static readonly TYPE_GRAY_4BIT = 1; - static readonly TYPE_GRAY = 2; - static readonly TYPE_GRAY_ALPHA = 3; - static readonly TYPE_PALETTE = 4; - static readonly TYPE_RGB = 5; - static readonly TYPE_RGB_ALPHA = 6; - static readonly TYPE_YCBCR_SUB = 7; - static readonly TYPE_GENERIC = 8; - static readonly FORMAT_UINT = 1; - static readonly FORMAT_INT = 2; - static readonly FORMAT_FLOAT = 3; - static readonly TAG_ARTIST = 315; - static readonly TAG_BITS_PER_SAMPLE = 258; - static readonly TAG_CELL_LENGTH = 265; - static readonly TAG_CELL_WIDTH = 264; - static readonly TAG_COLOR_MAP = 320; - static readonly TAG_COMPRESSION = 259; - static readonly TAG_DATE_TIME = 306; - static readonly TAG_EXIF_IFD = 34665; - static readonly TAG_EXTRA_SAMPLES = 338; - static readonly TAG_FILL_ORDER = 266; - static readonly TAG_FREE_BYTE_COUNTS = 289; - static readonly TAG_FREE_OFFSETS = 288; - static readonly TAG_GRAY_RESPONSE_CURVE = 291; - static readonly TAG_GRAY_RESPONSE_UNIT = 290; - static readonly TAG_HOST_COMPUTER = 316; - static readonly TAG_ICC_PROFILE = 34675; - static readonly TAG_IMAGE_DESCRIPTION = 270; - static readonly TAG_IMAGE_LENGTH = 257; - static readonly TAG_IMAGE_WIDTH = 256; - static readonly TAG_IPTC = 33723; - static readonly TAG_MAKE = 271; - static readonly TAG_MAX_SAMPLE_VALUE = 281; - static readonly TAG_MIN_SAMPLE_VALUE = 280; - static readonly TAG_MODEL = 272; - static readonly TAG_NEW_SUBFILE_TYPE = 254; - static readonly TAG_ORIENTATION = 274; - static readonly TAG_PHOTOMETRIC_INTERPRETATION = 262; - static readonly TAG_PHOTOSHOP = 34377; - static readonly TAG_PLANAR_CONFIGURATION = 284; - static readonly TAG_PREDICTOR = 317; - static readonly TAG_RESOLUTION_UNIT = 296; - static readonly TAG_ROWS_PER_STRIP = 278; - static readonly TAG_SAMPLES_PER_PIXEL = 277; - static readonly TAG_SOFTWARE = 305; - static readonly TAG_STRIP_BYTE_COUNTS = 279; - static readonly TAG_STRIP_OFFSETS = 273; - static readonly TAG_SUBFILE_TYPE = 255; - static readonly TAG_T4_OPTIONS = 292; - static readonly TAG_T6_OPTIONS = 293; - static readonly TAG_THRESHOLDING = 263; - static readonly TAG_TILE_WIDTH = 322; - static readonly TAG_TILE_LENGTH = 323; - static readonly TAG_TILE_OFFSETS = 324; - static readonly TAG_TILE_BYTE_COUNTS = 325; - static readonly TAG_SAMPLE_FORMAT = 339; - static readonly TAG_XMP = 700; - static readonly TAG_X_RESOLUTION = 282; - static readonly TAG_Y_RESOLUTION = 283; - static readonly TAG_YCBCR_COEFFICIENTS = 529; - static readonly TAG_YCBCR_SUBSAMPLING = 530; - static readonly TAG_YCBCR_POSITIONING = 531; - static readonly TAG_NAME: Map; - private readonly _tags; - get tags(): Map; - private readonly _width; - get width(): number; - private readonly _height; - get height(): number; - private _photometricType; - get photometricType(): number | undefined; - private _compression; - get compression(): number; - private _bitsPerSample; - get bitsPerSample(): number; - private _samplesPerPixel; - get samplesPerPixel(): number; - private _sampleFormat; - get sampleFormat(): number; - private _imageType; - get imageType(): number; - private _isWhiteZero; - get isWhiteZero(): boolean; - private _predictor; - get predictor(): number; - private _chromaSubH; - get chromaSubH(): number; - private _chromaSubV; - get chromaSubV(): number; - private _tiled; - get tiled(): boolean; - private _tileWidth; - get tileWidth(): number; - private _tileHeight; - get tileHeight(): number; - private _tileOffsets; - get tileOffsets(): number[] | undefined; - private _tileByteCounts; - get tileByteCounts(): number[] | undefined; - private _tilesX; - get tilesX(): number; - private _tilesY; - get tilesY(): number; - private _tileSize; - get tileSize(): number | undefined; - private _fillOrder; - get fillOrder(): number; - private _t4Options; - get t4Options(): number; - private _t6Options; - get t6Options(): number; - private _extraSamples; - get extraSamples(): number | undefined; - private _colorMap; - get colorMap(): number[] | undefined; - private colorMapRed; - private colorMapGreen; - private colorMapBlue; - private image?; - private hdrImage?; - get isValid(): boolean; - constructor(p: InputBuffer); - private readTag; - private readTagList; - private decodeBilevelTile; - private decodeTile; - private jpegToImage; - /** - * Uncompress packbits compressed image data. - */ - private decodePackbits; - decode(p: InputBuffer): MemoryImage; - decodeHdr(p: InputBuffer): HdrImage; - hasTag(tag: number): boolean; + import { JpegComponent } from "formats/jpeg/jpeg-component"; + import { JpegFrame } from "formats/jpeg/jpeg-frame"; + export type DecodeFunction = (component: JpegComponent, block: Int32Array) => void; + export class JpegScan { + private _input; + get input(): InputBuffer; + private _frame; + get frame(): JpegFrame; + private _precision; + get precision(): number; + private _samplesPerLine; + get samplesPerLine(): number; + private _scanLines; + get scanLines(): number; + private _mcusPerLine; + get mcusPerLine(): number; + private _progressive; + get progressive(): boolean; + private _maxH; + get maxH(): number; + private _maxV; + get maxV(): number; + private _components; + get components(): Array; + private _resetInterval?; + get resetInterval(): number | undefined; + private _spectralStart; + get spectralStart(): number; + private _spectralEnd; + get spectralEnd(): number; + private _successivePrev; + get successivePrev(): number; + private _successive; + get successive(): number; + private _bitsData; + get bitsData(): number; + private _bitsCount; + get bitsCount(): number; + private _eobrun; + get eobrun(): number; + private _successiveACState; + get successiveACState(): number; + private _successiveACNextValue; + get successiveACNextValue(): number; + constructor(input: InputBuffer, frame: JpegFrame, components: Array, spectralStart: number, spectralEnd: number, successivePrev: number, successive: number, resetInterval?: number); + private readBit; + private decodeHuffman; + private receive; + private receiveAndExtend; + private decodeBaseline; + private decodeDCFirst; + private decodeDCSuccessive; + private decodeACFirst; + private decodeACSuccessive; + private decodeMcu; + private decodeBlock; + decode(): void; } } -declare module "formats/tiff/tiff-info" { +declare module "formats/jpeg/jpeg-data" { /** @format */ - import { DecodeInfo } from "formats/decode-info"; - import { TiffImage } from "formats/tiff/tiff-image"; - export interface TiffInfoInitOptions { - bigEndian: boolean; - signature: number; - ifdOffset: number; - images: TiffImage[]; - } - export class TiffInfo implements DecodeInfo { - private _bigEndian; - get bigEndian(): boolean; - private _signature; - get signature(): number; - private _ifdOffset; - get ifdOffset(): number; - private _images; - get images(): TiffImage[]; - private _width; + import { InputBuffer } from "common/input-buffer"; + import { JpegComponentData } from "formats/jpeg/jpeg-component-data"; + import { JpegAdobe } from "formats/jpeg/jpeg-adobe"; + import { JpegFrame } from "formats/jpeg/jpeg-frame"; + import { JpegInfo } from "formats/jpeg/jpeg-info"; + import { JpegJfif } from "formats/jpeg/jpeg-jfif"; + import { ExifData } from "exif/exif-data"; + import { MemoryImage } from "image/image"; + import { HuffmanNode } from "formats/jpeg/huffman-node"; + export class JpegData { + static readonly dctZigZag: number[]; + static readonly dctSize = 8; + static readonly dctSize2 = 64; + static readonly numQuantizationTables = 4; + static readonly numHuffmanTables = 4; + static readonly numArithTables = 16; + static readonly maxCompsInScan = 4; + static readonly maxSamplingFactor = 4; + private _input; + get input(): InputBuffer; + private _jfif; + get jfif(): JpegJfif; + private _adobe; + get adobe(): JpegAdobe; + private _frame?; + get frame(): JpegFrame | undefined; + private _resetInterval; + get resetInterval(): number; + private _comment?; + get comment(): string | undefined; + private readonly _exifData; + get exifData(): ExifData; + private readonly _quantizationTables; + get quantizationTables(): Array; + private readonly _frames; + get frames(): Array; + private readonly _huffmanTablesAC; + get huffmanTablesAC(): Array | undefined>; + private readonly _huffmanTablesDC; + get huffmanTablesDC(): Array | undefined>; + private readonly _components; + get components(): Array; get width(): number; - private _height; get height(): number; - private _backgroundColor; - get backgroundColor(): number; - get numFrames(): number; - constructor(options: TiffInfoInitOptions); + private readMarkers; + private skipBlock; + validate(bytes: Uint8Array): boolean; + readInfo(bytes: Uint8Array): JpegInfo | undefined; + read(bytes: Uint8Array): void; + getImage(): MemoryImage; + private static buildHuffmanTable; + private static buildComponentData; + static toFix(val: number): number; + private readBlock; + private nextMarker; + private readExifData; + private readAppData; + private readDQT; + private readFrame; + private readDHT; + private readDRI; + private readSOS; } } -declare module "formats/tiff-decoder" { - /** @format */ - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; - import { ExifData } from "exif/exif-data"; - import { HdrImage } from "hdr/hdr-image"; +declare module "formats/jpeg-decoder" { + import { MemoryImage } from "image/image"; import { Decoder } from "formats/decoder"; - import { TiffInfo } from "formats/tiff/tiff-info"; - export class TiffDecoder implements Decoder { - private static readonly TIFF_SIGNATURE; - private static readonly TIFF_LITTLE_ENDIAN; - private static readonly TIFF_BIG_ENDIAN; - private input; - private _info; - get info(): TiffInfo | undefined; - private _exifData; - get exifData(): ExifData | undefined; - /** - * How many frames are available to be decoded. **startDecode** should have been called first. - * Non animated image files will have a single frame. - */ + import { JpegInfo } from "formats/jpeg/jpeg-info"; + /** + * Decode a jpeg encoded image. + */ + export class JpegDecoder implements Decoder { + private _input?; + private _info?; get numFrames(): number; /** - * Read the TIFF header and IFD blocks. - */ - private readHeader; - /** - * Is the given file a valid TIFF image? + * Is the given file a valid JPEG image? */ isValidFile(bytes: Uint8Array): boolean; - /** - * Validate the file is a TIFF image and get information about it. - * If the file is not a valid TIFF image, undefined is returned. - */ - startDecode(bytes: Uint8Array): TiffInfo | undefined; - /** - * Decode a single frame from the data stat was set with **startDecode**. - * If **frame** is out of the range of available frames, undefined is returned. - * Non animated image files will only have **frame** 0. An **AnimationFrame** - * is returned, which provides the image, and top-left coordinates of the - * image, as animated frames may only occupy a subset of the canvas. - */ - decodeFrame(frame: number): MemoryImage | undefined; - decodeHdrFrame(frame: number): HdrImage | undefined; - /** - * Decode all of the frames from an animation. If the file is not an - * animation, a single frame animation is returned. If there was a problem - * decoding the file, undefined is returned. - */ - decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined; - /** - * Decode the file and extract a single image from it. If the file is - * animated, the specified **frame** will be decoded. If there was a problem - * decoding the file, undefined is returned. - */ - decodeImage(bytes: Uint8Array, frame?: number): MemoryImage | undefined; - decodeHdrImage(bytes: Uint8Array, frame?: number): HdrImage | undefined; + startDecode(bytes: Uint8Array): JpegInfo | undefined; + decodeFrame(_: number): MemoryImage | undefined; + decode(bytes: Uint8Array, _frame?: number): MemoryImage | undefined; } } -declare module "formats/tiff-encoder" { - /** @format */ - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; - import { HdrImage } from "hdr/hdr-image"; +declare module "formats/jpeg-encoder" { + import { MemoryImage } from "image/image"; import { Encoder } from "formats/encoder"; /** - * Encode a TIFF image. + * Encode an image to the JPEG format. */ - export class TiffEncoder implements Encoder { - private static readonly LITTLE_ENDIAN; - private static readonly SIGNATURE; + export class JpegEncoder implements Encoder { + private static readonly _zigzag; + private static readonly _stdDcLuminanceNrCodes; + private static readonly _stdDcLuminanceValues; + private static readonly _stdAcLuminanceNrCodes; + private static readonly _stdAcLuminanceValues; + private static readonly _stdDcChrominanceNrCodes; + private static readonly _stdDcChrominanceValues; + private static readonly _stdAcChrominanceNrCodes; + private static readonly _stdAcChrominanceValues; + private readonly _tableY; + private readonly _tableUv; + private readonly _fdTableY; + private readonly _fdTableUv; + private readonly _bitCode; + private readonly _category; + private readonly _outputfDCTQuant; + private readonly _du; + private readonly _ydu; + private readonly _udu; + private readonly _vdu; + private readonly _tableRgbYuv; + private _ydcHuffman; + private _uvdcHuffman; + private _yacHuffman; + private _uvacHuffman; + private _currentQuality?; + private _byteNew; + private _bytePos; private _supportsAnimation; get supportsAnimation(): boolean; - private writeHeader; - private writeImage; - private writeHdrImage; - private getSampleFormat; - private writeEntryUint16; - private writeEntryUint32; - encodeImage(image: MemoryImage): Uint8Array; - encodeAnimation(_animation: FrameAnimation): Uint8Array | undefined; - encodeHdrImage(image: HdrImage): Uint8Array; + constructor(quality?: number); + private static computeHuffmanTable; + private static writeMarker; + private static writeAPP0; + private static writeAPP1; + private static writeSOF0; + private static writeSOS; + private static writeDHT; + private initHuffmanTable; + private initCategoryNumber; + private initRgbYuvTable; + private setQuality; + private initQuantTables; + private fDCTQuant; + private writeDQT; + private writeBits; + private resetBits; + private processDU; + encode(image: MemoryImage, _singleFrame?: boolean): Uint8Array; } } -declare module "common/octree-node" { +declare module "formats/tga/tga-image-type" { /** @format */ - export class OctreeNode { - private _r; - get r(): number; - set r(v: number); - private _g; - get g(): number; - set g(v: number); - private _b; - get b(): number; - set b(v: number); - private _count; - get count(): number; - set count(v: number); - private _heapIndex; - get heapIndex(): number; - set heapIndex(v: number); - private _parent; - get parent(): OctreeNode | undefined; - private _children; - get children(): Array; - private _childCount; - get childCount(): number; - set childCount(v: number); - private _childIndex; - get childIndex(): number; - private _flags; - get flags(): number; - set flags(v: number); - private _depth; - get depth(): number; - constructor(childIndex: number, depth: number, parent?: OctreeNode); - } + export enum TgaImageType { + none = 0, + palette = 1, + rgb = 2, + gray = 3, + reserved4 = 4, + reserved5 = 5, + reserved6 = 6, + reserved7 = 7, + reserved8 = 8, + paletteRle = 9, + rgbRle = 10, + grayRle = 11 + } + export const TgaImageTypeLength = 12; } -declare module "common/heap-node" { +declare module "formats/tga/tga-info" { /** @format */ - import { OctreeNode } from "common/octree-node"; - export class HeapNode { - private _buf; - get buf(): Array; - get n(): number; - } -} -declare module "common/octree-quantizer" { - import { MemoryImage } from "common/memory-image"; - import { Quantizer } from "common/quantizer"; - /** - * Color quantization using octree, - * from https://rosettacode.org/wiki/Color_quantization/C - */ - export class OctreeQuantizer implements Quantizer { - private static readonly ON_INHEAP; - private readonly root; - constructor(image: MemoryImage, numberOfColors?: number); - private nodeInsert; - private popHeap; - private heapAdd; - private downHeap; - private upHeap; - private nodeFold; - private compareNode; - /** - * Find the index of the closest color to **c** in the **colorMap**. - */ - getQuantizedColor(c: number): number; + import { Color } from "color/color"; + import { InputBuffer } from "common/input-buffer"; + import { DecodeInfo } from "formats/decode-info"; + import { TgaImageType } from "formats/tga/tga-image-type"; + export interface TgaInfoInitOptions { + width?: number; + height?: number; + imageOffset?: number; + bitsPerPixel?: number; } -} -declare module "common/random-utils" { - /** @format */ - export abstract class RandomUtils { - /** - * Return a random variable between [**-1**,**1**]. - */ - static crand(): number; + export class TgaInfo implements DecodeInfo { /** - * Return a random variable following a gaussian distribution and a standard - * deviation of 1. + * The number of frames that can be decoded. */ - static grand(): number; + private readonly _numFrames; + get numFrames(): number; + private readonly _backgroundColor; + get backgroundColor(): Color | undefined; + private _idLength; + get idLength(): number; + private _colorMapType; + get colorMapType(): number; + private _imageType; + get imageType(): TgaImageType; + private _colorMapOrigin; + get colorMapOrigin(): number; + private _colorMapLength; + get colorMapLength(): number; + private _colorMapDepth; + get colorMapDepth(): number; + private _offsetX; + get offsetX(): number; + private _offsetY; + get offsetY(): number; + private _width; + get width(): number; + protected _height: number; + get height(): number; + protected _pixelDepth: number; + get pixelDepth(): number; + protected _flags: number; + get flags(): number; + protected _colorMap: Uint8Array | undefined; + get colorMap(): Uint8Array | undefined; + set colorMap(v: Uint8Array | undefined); + protected _screenOrigin: number; + get screenOrigin(): number; /** - * Return a random variable following a Poisson distribution of parameter **z**. + * Offset in the input file the image data starts at. */ - static prand(z: number): number; - } -} -declare module "filter/adjust-color-options" { - /** @format */ - import { MemoryImage } from "common/memory-image"; - export interface AdjustColorOptions { - src: MemoryImage; - blacks?: number; - whites?: number; - mids?: number; - contrast?: number; - saturation?: number; - brightness?: number; - gamma?: number; - exposure?: number; - hue?: number; - amount?: number; - } -} -declare module "filter/color-offset-options" { - /** @format */ - import { MemoryImage } from "common/memory-image"; - export interface ColorOffsetOptions { - src: MemoryImage; - red?: number; - green?: number; - blue?: number; - alpha?: number; + private _imageOffset; + get imageOffset(): number; + set imageOffset(v: number); + get hasColorMap(): boolean; + read(header: InputBuffer): void; + isValid(): boolean; } } -declare module "filter/convolution-options" { - /** @format */ - import { MemoryImage } from "common/memory-image"; - export interface ConvolutionOptions { - src: MemoryImage; - filter: number[]; - div?: number; - offset?: number; +declare module "formats/tga-decoder" { + import { MemoryImage } from "image/image"; + import { Decoder } from "formats/decoder"; + import { TgaInfo } from "formats/tga/tga-info"; + /** + * Decode a TGA image. This only supports the 24-bit and 32-bit uncompressed format. + */ + export class TgaDecoder implements Decoder { + private _input; + private _info; + get numFrames(): number; + private decodeColorMap; + private decodeRle; + private decodeRgb; + /** + * Is the given file a valid TGA image? + */ + isValidFile(bytes: Uint8Array): boolean; + startDecode(bytes: Uint8Array): TgaInfo | undefined; + decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined; + decodeFrame(_frame: number): MemoryImage | undefined; } } -declare module "filter/noise-type" { - /** @format */ - export enum NoiseType { - gaussian = 0, - uniform = 1, - saltPepper = 2, - poisson = 3, - rice = 4 +declare module "formats/tga-encoder" { + import { MemoryImage } from "image/image"; + import { Encoder } from "formats/encoder"; + /** + * Encode a TGA image. This only supports the 24-bit uncompressed format. + */ + export class TgaEncoder implements Encoder { + private _supportsAnimation; + get supportsAnimation(): boolean; + encode(image: MemoryImage, _singleFrame?: boolean): Uint8Array; } } -declare module "filter/pixelate-mode" { +declare module "formats/tiff/tiff-bit-reader" { /** @format */ - export enum PixelateMode { + import { InputBuffer } from "common/input-buffer"; + export class TiffBitReader { + private static readonly _bitMask; + private _bitBuffer; + private _bitPosition; + private _input; + constructor(input: InputBuffer); /** - * Use the top-left pixel of a block for the block color. + * Read a number of bits from the input stream. */ - upperLeft = 0, + readBits(numBits: number): number; + readByte(): number; /** - * Use the average of the pixels within a block for the block color. + * Flush the rest of the bits in the buffer so the next read starts at the next byte. */ - average = 1 + flushByte(): number; } } -declare module "filter/quantize-method" { +declare module "formats/tiff/tiff-compression" { /** @format */ - export enum QuantizeMethod { - neuralNet = 0, - octree = 1 + export enum TiffCompression { + none = 1, + ccittRle = 2, + ccittFax3 = 3, + ccittFax4 = 4, + lzw = 5, + oldJpeg = 6, + jpeg = 7, + next = 32766, + ccittRlew = 32771, + packBits = 32773, + thunderScan = 32809, + it8ctpad = 32895, + tt8lw = 32896, + it8mp = 32897, + it8bl = 32898, + pixarFilm = 32908, + pixarLog = 32909, + deflate = 32946, + zip = 8, + dcs = 32947, + jbig = 34661, + sgiLog = 34676, + sgiLog24 = 34677, + jp2000 = 34712 } } -declare module "filter/quantize-options" { +declare module "formats/tiff/tiff-entry" { /** @format */ - import { MemoryImage } from "common/memory-image"; - import { QuantizeMethod } from "filter/quantize-method"; - export interface QuantizeOptions { - src: MemoryImage; - numberOfColors?: number; - method?: QuantizeMethod; + import { InputBuffer } from "common/input-buffer"; + import { IfdValueType } from "exif/ifd-value-type"; + import { IfdValue } from "exif/ifd-value/ifd-value"; + export interface TiffEntryInitOptions { + tag: number; + type: number; + count: number; + p: InputBuffer; + valueOffset: number; + } + export class TiffEntry { + private _tag; + get tag(): number; + private _type; + get type(): IfdValueType; + private _count; + get count(): number; + private _valueOffset; + get valueOffset(): number; + private _value; + get value(): IfdValue | undefined; + private _p; + get p(): InputBuffer; + get isValid(): boolean; + get typeSize(): number; + get isString(): boolean; + constructor(opt: TiffEntryInitOptions); + read(): IfdValue | undefined; + toString(): string; } } -declare module "filter/remap-colors-options" { +declare module "formats/tiff/tiff-fax-decoder" { /** @format */ - import { ColorChannel } from "common/color-channel"; - import { MemoryImage } from "common/memory-image"; - export interface RemapColorsOptions { - src: MemoryImage; - red?: ColorChannel; - green?: ColorChannel; - blue?: ColorChannel; - alpha?: ColorChannel; + import { InputBuffer } from "common/input-buffer"; + export interface TiffFaxDecoderInitOptions { + fillOrder: number; + width: number; + height: number; } -} -declare module "filter/separable-kernel" { - import { MemoryImage } from "common/memory-image"; - /** - * A kernel object to use with **separableConvolution** filtering. - */ - export class SeparableKernel { - private readonly coefficients; - private readonly size; + export class TiffFaxDecoder { + private static readonly _table1; + private static readonly _table2; /** - * Get the number of coefficients in the kernel. + * Table to be used when **fillOrder** = 2, for flipping bytes. */ - get length(): number; + private static readonly _flipTable; /** - * Create a separable convolution kernel for the given **radius**. + * The main 10 bit white runs lookup table */ - constructor(size: number); - private reflect; - private applyCoeffsLine; + private static readonly _white; /** - * Get a coefficient from the kernel. + * Additional make up codes for both White and Black runs */ - getCoefficient(index: number): number; + private static readonly _additionalMakeup; /** - * Set a coefficient in the kernel. + * Initial black run look up table, uses the first 4 bits of a code */ - setCoefficient(index: number, c: number): void; + private static readonly _initBlack; + private static readonly _twoBitBlack; /** - * Apply the kernel to the **src** image, storing the results in **dst**, - * for a single dimension. If **horizontal** is true, the filter will be - * applied to the horizontal axis, otherwise it will be appied to the - * vertical axis. + * Main black run table, using the last 9 bits of possible 13 bit code + */ + private static readonly _black; + private static readonly _twoDCodes; + private _width; + get width(): number; + private _height; + get height(): number; + private _fillOrder; + get fillOrder(): number; + private _changingElemSize; + private _prevChangingElements?; + private _currChangingElements?; + private _data; + private _bitPointer; + private _bytePointer; + private _lastChangingElement; + private _compression; + private _uncompressedMode; + private _fillBits; + private _oneD; + constructor(opt: TiffFaxDecoderInitOptions); + private nextNBits; + private nextLesserThan8Bits; + /** + * Move pointer backwards by given amount of bits */ - apply(src: MemoryImage, dst: MemoryImage, horizontal?: boolean): void; + private updatePointer; /** - * Scale all of the coefficients by **s**. + * Move to the next byte boundary */ - scaleCoefficients(s: number): void; + private advancePointer; + private setToBlack; + private decodeNextScanline; + private readEOL; + private getNextChangingElement; + /** + * Returns run length + */ + private decodeWhiteCodeWord; + /** + * Returns run length + */ + private decodeBlackCodeWord; + /** + * One-dimensional decoding methods + */ + decode1D(out: InputBuffer, compData: InputBuffer, startX: number, height: number): void; + /** + * Two-dimensional decoding methods + */ + decode2D(out: InputBuffer, compData: InputBuffer, startX: number, height: number, tiffT4Options: number): void; + decodeT6(out: InputBuffer, compData: InputBuffer, startX: number, height: number, tiffT6Options: number): void; } } -declare module "filter/vignette-options" { +declare module "formats/tiff/tiff-format" { /** @format */ - import { MemoryImage } from "common/memory-image"; - export interface VignetteOptions { - src: MemoryImage; - start?: number; - end?: number; - amount?: number; + export enum TiffFormat { + invalid = 0, + uint = 1, + int = 2, + float = 3 } } -declare module "filter/image-filter" { - import { MemoryImage } from "common/memory-image"; - import { AdjustColorOptions } from "filter/adjust-color-options"; - import { ColorOffsetOptions } from "filter/color-offset-options"; - import { ConvolutionOptions } from "filter/convolution-options"; - import { NoiseType } from "filter/noise-type"; - import { PixelateMode } from "filter/pixelate-mode"; - import { QuantizeOptions } from "filter/quantize-options"; - import { RemapColorsOptions } from "filter/remap-colors-options"; - import { SeparableKernel } from "filter/separable-kernel"; - import { VignetteOptions } from "filter/vignette-options"; - export abstract class ImageFilter { - private static readonly gaussianKernelCache; - private static smoothVignetteStep; - /** - * Adjust the color of the **src** image using various color transformations. - * - * **blacks** defines the black level of the image, as a color. - * - * **whites** defines the white level of the image, as a color. - * - * **mids** defines the mid level of hte image, as a color. - * - * **contrast** increases (> 1) / decreases (< 1) the contrast of the image by - * pushing colors away/toward neutral gray, where at 0 the image is entirely - * neutral gray (0 contrast), 1, the image is not adjusted and > 1 the - * image increases contrast. - * - * **saturation** increases (> 1) / decreases (< 1) the saturation of the image - * by pushing colors away/toward their grayscale value, where 0 is grayscale - * and 1 is the original image, and > 1 the image becomes more saturated. - * - * **brightness** is a constant scalar of the image colors. At 0 the image - * is black, 1 unmodified, and > 1 the image becomes brighter. - * - * **gamma** is an exponential scalar of the image colors. At < 1 the image - * becomes brighter, and > 1 the image becomes darker. A **gamma** of 1/2.2 - * will convert the image colors to linear color space. - * - * **exposure** is an exponential scalar of the image as rgb* pow(2, exposure). - * At 0, the image is unmodified; as the exposure increases, the image - * brightens. - * - * **hue** shifts the hue component of the image colors in degrees. A **hue** of - * 0 will have no affect, and a **hue** of 45 will shift the hue of all colors - * by 45 degrees. - * - * **amount** controls how much affect this filter has on the **src** image, where - * 0 has no effect and 1 has full effect. - */ - static adjustColor(options: AdjustColorOptions): MemoryImage; +declare module "formats/tiff/tiff-image-type" { + /** @format */ + export enum TiffImageType { + bilevel = 0, + gray4bit = 1, + gray = 2, + grayAlpha = 3, + palette = 4, + rgb = 5, + rgba = 6, + yCbCrSub = 7, + generic = 8, + invalid = 9 + } +} +declare module "formats/tiff/tiff-lzw-decoder" { + /** @format */ + import { InputBuffer } from "common/input-buffer"; + export class LzwDecoder { + private static readonly _lzMaxCode; + private static readonly _noSuchCode; + private static readonly _andTable; + private readonly _buffer; + private _bitsToGet; + private _bytePointer; + private _nextData; + private _nextBits; + private _data; + private _dataLength; + private _out; + private _outPointer; + private _table; + private _prefix; + private _tableIndex?; + private _bufferLength; + private addString; + private getString; /** - * Set the **brightness** level for the image **src**. - * **brightness** is an offset that is added to the red, green, and blue channels - * of every pixel. + * Returns the next 9, 10, 11 or 12 bits */ - static brightness(src: MemoryImage, brightness: number): MemoryImage; + private getNextCode; /** - * Generate a normal map from a height-field bump image. - * - * The red channel of the **src** image is used as an input, 0 represents a low - * height and 1 a high value. The optional **strength** parameter allows to set - * the strength of the normal image. + * Initialize the string table. */ - static bumpToNormal(src: MemoryImage, strength?: number): MemoryImage; + private initializeStringTable; + decode(p: InputBuffer, out: Uint8Array): void; + } +} +declare module "formats/tiff/tiff-photometric-type" { + /** @format */ + export enum TiffPhotometricType { + whiteIsZero = 0, + blackIsZero = 1, + rgb = 2, + palette = 3, + transparencyMask = 4, + cmyk = 5, + yCbCr = 6, + reserved7 = 7, + cieLab = 8, + iccLab = 9, + ituLab = 10, + logL = 11, + logLuv = 12, + colorFilterArray = 13, + linearRaw = 14, + depth = 15, + unknown = 16 + } + export const TiffPhotometricTypeLength = 17; +} +declare module "formats/tiff/tiff-image" { + import { InputBuffer } from "common/input-buffer"; + import { MemoryImage } from "image/image"; + import { TiffEntry } from "formats/tiff/tiff-entry"; + import { TiffFormat } from "formats/tiff/tiff-format"; + import { TiffImageType } from "formats/tiff/tiff-image-type"; + import { TiffPhotometricType } from "formats/tiff/tiff-photometric-type"; + export class TiffImage { + private readonly _tags; + get tags(): Map; + private readonly _width; + get width(): number; + private readonly _height; + get height(): number; + private _photometricType; + get photometricType(): TiffPhotometricType; + private _compression; + get compression(): number; + private _bitsPerSample; + get bitsPerSample(): number; + private _samplesPerPixel; + get samplesPerPixel(): number; + private _sampleFormat; + get sampleFormat(): TiffFormat; + private _imageType; + get imageType(): TiffImageType; + private _isWhiteZero; + get isWhiteZero(): boolean; + private _predictor; + get predictor(): number; + private _chromaSubH; + get chromaSubH(): number; + private _chromaSubV; + get chromaSubV(): number; + private _tiled; + get tiled(): boolean; + private _tileWidth; + get tileWidth(): number; + private _tileHeight; + get tileHeight(): number; + private _tileOffsets; + get tileOffsets(): number[] | undefined; + private _tileByteCounts; + get tileByteCounts(): number[] | undefined; + private _tilesX; + get tilesX(): number; + private _tilesY; + get tilesY(): number; + private _tileSize; + get tileSize(): number | undefined; + private _fillOrder; + get fillOrder(): number; + private _t4Options; + get t4Options(): number; + private _t6Options; + get t6Options(): number; + private _extraSamples; + get extraSamples(): number | undefined; + private _colorMapSamples; + get colorMapSamples(): number; + private _colorMap; + get colorMap(): Uint16Array | undefined; + private _colorMapRed; + private _colorMapGreen; + private _colorMapBlue; + get isValid(): boolean; + constructor(p: InputBuffer); + private readTag; + private readTagList; + private decodeBilevelTile; + private decodeTile; + private jpegToImage; /** - * Add the **red**, **green**, **blue** and **alpha** values to the **src** image - * colors, a per-channel brightness. + * Uncompress packbits compressed image data. */ - static colorOffset(options: ColorOffsetOptions): MemoryImage; + private decodePackBits; + decode(p: InputBuffer): MemoryImage; + hasTag(tag: number): boolean; + } +} +declare module "formats/tiff/tiff-info" { + /** @format */ + import { Color } from "color/color"; + import { DecodeInfo } from "formats/decode-info"; + import { TiffImage } from "formats/tiff/tiff-image"; + export interface TiffInfoInitOptions { + bigEndian: boolean; + signature: number; + ifdOffset: number; + images: TiffImage[]; + } + export class TiffInfo implements DecodeInfo { + private _bigEndian; + get bigEndian(): boolean; + private _signature; + get signature(): number; + private _ifdOffset; + get ifdOffset(): number; + private _images; + get images(): TiffImage[]; + private _width; + get width(): number; + private _height; + get height(): number; + private _backgroundColor; + get backgroundColor(): Color | undefined; + get numFrames(): number; + constructor(opt: TiffInfoInitOptions); + } +} +declare module "formats/tiff-decoder" { + import { ExifData } from "exif/exif-data"; + import { MemoryImage } from "image/image"; + import { Decoder } from "formats/decoder"; + import { TiffInfo } from "formats/tiff/tiff-info"; + export class TiffDecoder implements Decoder { + private static readonly _tiffSignature; + private static readonly _tiffLittleEndian; + private static readonly _tiffBigEndian; + private _input; + private _info; + get info(): TiffInfo | undefined; + private _exifData; + get exifData(): ExifData | undefined; /** - * Set the **contrast** level for the image **src**. - * - * **contrast** values below 100 will decrees the contrast of the image, - * and values above 100 will increase the contrast. A contrast of 100 - * will have no affect. + * How many frames are available to be decoded. **startDecode** should have been called first. + * Non animated image files will have a single frame. */ - static contrast(src: MemoryImage, contrast: number): MemoryImage; + get numFrames(): number; /** - * Apply a 3x3 convolution filter to the **src** image. **filter** should be a - * list of 9 numbers. - * - * The rgb channels will divided by **div** and add **offset**, allowing - * filters to normalize and offset the filtered pixel value. + * Read the TIFF header and IFD blocks. */ - static convolution(options: ConvolutionOptions): MemoryImage; + private readHeader; /** - * Apply an emboss convolution filter. + * Is the given file a valid TIFF image? */ - static emboss(src: MemoryImage): MemoryImage; + isValidFile(bytes: Uint8Array): boolean; /** - * Apply gaussian blur to the **src** image. **radius** determines how many pixels - * away from the current pixel should contribute to the blur, where 0 is no - * blur and the larger the radius, the stronger the blur. + * Validate the file is a TIFF image and get information about it. + * If the file is not a valid TIFF image, undefined is returned. */ - static gaussianBlur(src: MemoryImage, radius: number): MemoryImage; + startDecode(bytes: Uint8Array): TiffInfo | undefined; /** - * Convert the image to grayscale. + * Decode a single frame from the data stat was set with **startDecode**. + * If **frame** is out of the range of available frames, undefined is returned. + * Non animated image files will only have **frame** 0. */ - static grayscale(src: MemoryImage): MemoryImage; + decodeFrame(frame: number): MemoryImage | undefined; /** - * Invert the colors of the **src** image. + * Decode the file and extract a single image from it. If the file is + * animated, the specified **frame** will be decoded. If there was a problem + * decoding the file, undefined is returned. */ - static invert(src: MemoryImage): MemoryImage; + decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined; + } +} +declare module "formats/tiff-encoder" { + import { MemoryImage } from "image/image"; + import { Encoder } from "formats/encoder"; + /** + * Encode a MemoryImage to the TIFF format. + */ + export class TiffEncoder implements Encoder { + private _supportsAnimation; + get supportsAnimation(): boolean; + private getSampleFormat; + encode(image: MemoryImage, _singleFrame?: boolean): Uint8Array; + } +} +declare module "formats/jpeg/jpeg-utils" { + import { ExifData } from "exif/exif-data"; + export class JpegUtils { + private static readonly _exifSignature; + private readExifData; + private writeAPP1; + private readBlock; + private skipBlock; + private nextMarker; + decodeExif(data: Uint8Array): ExifData | undefined; + injectExif(exif: ExifData, data: Uint8Array): Uint8Array | undefined; + } +} +declare module "transform/flip-direction" { + /** @format */ + export enum FlipDirection { /** - * Add random noise to pixel values. **sigma** determines how strong the effect - * should be. **type** should be one of the following: **NoiseType.gaussian**, - * **NoiseType.uniform**, **NoiseType.saltPepper**, **NoiseType.poisson**, - * or **NoiseType.rice**. + * Flip the image horizontally. */ - static noise(image: MemoryImage, sigma: number, type?: NoiseType): MemoryImage; + horizontal = 0, /** - * Linearly normalize the colors of the image. All color values will be mapped - * to the range **minValue**, **maxValue** inclusive. + * Flip the image vertically. */ - static normalize(src: MemoryImage, minValue: number, maxValue: number): MemoryImage; + vertical = 1, /** - * Pixelate the **src** image. - * - * **blockSize** determines the size of the pixelated blocks. - * If **mode** is **PixelateMode.upperLeft** then the upper-left corner of the block - * will be used for the block color. Otherwise if **mode** is **PixelateMode.average**, - * the average of all the pixels in the block will be used for the block color. + * Flip the image both horizontally and vertically. */ - static pixelate(src: MemoryImage, blockSize: number, mode?: PixelateMode): MemoryImage; + both = 2 + } +} +declare module "transform/trim-side" { + /** @format */ + export enum TrimSide { + top = 1, + bottom = 2, + left = 4, + right = 8, + all = 15 + } +} +declare module "transform/trim-mode" { + /** @format */ + export enum TrimMode { /** - * Quantize the number of colors in image to 256. + * Trim an image to the top-left and bottom-right most non-transparent pixels */ - static quantize(options: QuantizeOptions): MemoryImage; + transparent = 0, /** - * Remap the color channels of the image. - * **red**, **green**, **blue** and **alpha** should be set to one of the following: - * **ColorChannel.red**, **ColorChannel.green**, **ColorChannel.blue**, **ColorChannel.alpha**, or - * **ColorChannel.luminance**. For example, - * **_remapColors({ src: src, red: ColorChannel.green, green: ColorChannel.red })_** - * will swap the red and green channels of the image. - * **_remapColors({ src: src, alpha: ColorChannel.luminance })_** - * will set the alpha channel to the luminance (grayscale) of the image. + * Trim an image to the top-left and bottom-right most pixels that are not + * the same as the top-left most pixel of the image. */ - static remapColors(options: RemapColorsOptions): MemoryImage; - static scaleRgba(src: MemoryImage, r: number, g: number, b: number, a: number): MemoryImage; + topLeftColor = 1, /** - * Apply a generic separable convolution filter the **src** image, using the - * given **kernel**. - * - * **gaussianBlur** is an example of such a filter. + * Trim an image to the top-left and bottom-right most pixels that are not + * the same as the bottom-right most pixel of the image. */ - static separableConvolution(src: MemoryImage, kernel: SeparableKernel): MemoryImage; + bottomRightColor = 2 + } +} +declare module "transform/transform" { + import { Point } from "common/point"; + import { Interpolation } from "common/interpolation"; + import { MemoryImage } from "image/image"; + import { FlipDirection } from "transform/flip-direction"; + import { TrimSide } from "transform/trim-side"; + import { Rectangle } from "common/rectangle"; + import { TrimMode } from "transform/trim-mode"; + export interface TransformOptions { + image: MemoryImage; + } + export interface CopyCropCircleOptions extends TransformOptions { + radius?: number; + center?: Point; + antialias?: boolean; + } + export interface CopyCropOptions extends TransformOptions { + rect: Rectangle; + radius?: number; + antialias?: boolean; + } + export interface CopyRectifyOptions extends TransformOptions { + topLeft: Point; + topRight: Point; + bottomLeft: Point; + bottomRight: Point; + interpolation?: Interpolation; + toImage?: MemoryImage; + } + export interface CopyResizeCropSquareOptions extends TransformOptions { + size: number; + interpolation?: Interpolation; + radius?: number; + antialias?: boolean; + } + export interface CopyResizeOptionsUsingWidth extends TransformOptions { + width: number; + height?: number; + interpolation?: Interpolation; + } + export interface CopyResizeOptionsUsingHeight extends TransformOptions { + height: number; + width?: number; + interpolation?: Interpolation; + } + export interface CopyRotateOptions extends TransformOptions { + angle: number; + interpolation?: Interpolation; + } + export interface FlipOptions extends TransformOptions { + direction: FlipDirection; + } + export interface TrimOptions extends TransformOptions { + mode?: TrimMode; + sides?: TrimSide; + } + export abstract class Transform { + private static rotate90; + private static rotate180; + private static rotate270; /** - * Apply sepia tone to the image. + * Find the crop area to be used by the trim function. * - * **amount** controls the strength of the effect, in the range **0**-**1**. + * Returns the Rectangle. You could pass these constraints + * to the **copyCrop** function to crop the image. */ - static sepia(src: MemoryImage, amount?: number): MemoryImage; + private static findTrim; /** - * Apply a smoothing convolution filter to the **src** image. - * - * **w** is the weight of the current pixel being filtered. If it's greater than - * 1, it will make the image sharper. + * If **image** has an orientation value in its exif data, this will rotate the + * image so that it physically matches its orientation. This can be used to + * bake the orientation of the image for image formats that don't support exif + * data. */ - static smooth(src: MemoryImage, w: number): MemoryImage; + static bakeOrientation(opt: TransformOptions): MemoryImage; /** - * Apply Sobel edge detection filtering to the **src** Image. + * Returns a cropped copy of **image**. */ - static sobel(src: MemoryImage, amount?: number): MemoryImage; - static vignette(options: VignetteOptions): MemoryImage; - } -} -declare module "hdr/hdr-to-image" { - import { MemoryImage } from "common/memory-image"; - import { HdrImage } from "hdr/hdr-image"; - export abstract class HdrToImage { + static copyCrop(opt: CopyCropOptions): MemoryImage; /** - * Convert a high dynamic range image to a low dynamic range image, - * with optional exposure control. + * Returns a circle cropped copy of **image**, centered at **centerX** and + * **centerY** and with the given **radius**. If **radius** is not provided, + * a radius filling the image will be used. If **centerX** is not provided, + * the horizontal mid-point of the image will be used. If **centerY** is not + * provided, the vertical mid-point of the image will be used. */ - static hdrToImage(hdr: HdrImage, exposure?: number): MemoryImage; - } -} -declare module "transform/trim-mode" { - /** @format */ - export enum TrimMode { + static copyCropCircle(opt: CopyCropCircleOptions): MemoryImage; /** - * Trim an image to the top-left and bottom-right most non-transparent pixels + * Returns a copy of the **image** image, flipped by the given **direction**. */ - transparent = 0, + static copyFlip(opt: FlipOptions): MemoryImage; /** - * Trim an image to the top-left and bottom-right most pixels that are not the - * same as the top-left most pixel of the image. + * Returns a copy of the **image**, where the given rectangle + * has been mapped to the full image. */ - topLeftColor = 1, + static copyRectify(opt: CopyRectifyOptions): MemoryImage; /** - * Trim an image to the top-left and bottom-right most pixels that are not the - * same as the bottom-right most pixel of the image. + * Returns a resized copy of the **image**. + * + * If **height** isn't specified, then it will be determined by the aspect + * ratio of **image** and **width**. + * + * If **width** isn't specified, then it will be determined by the aspect ratio + * of **image** and **height**. */ - bottomRightColor = 2 - } -} -declare module "transform/trim-side" { - /** @format */ - export class TrimSide { + static copyResize(opt: CopyResizeOptionsUsingWidth | CopyResizeOptionsUsingHeight): MemoryImage; /** - * Trim the image down from the top. + * Returns a resized and square cropped copy of the **image** of **size** size. */ - static readonly top: TrimSide; + static copyResizeCropSquare(opt: CopyResizeCropSquareOptions): MemoryImage; /** - * Trim the image up from the bottom. + * Returns a copy of the **image**, rotated by **angle** degrees. */ - static readonly bottom: TrimSide; + static copyRotate(opt: CopyRotateOptions): MemoryImage; /** - * Trim the left edge of the image. + * Flips the **image** using the given **direction**, which can be one of: + * _FlipDirection.horizontal_, _FlipDirection.vertical_ or _FlipDirection.both_. */ - static readonly left: TrimSide; + static flip(opt: FlipOptions): MemoryImage; /** - * Trim the right edge of the image. + * Flips the **image** vertically. */ - static readonly right: TrimSide; + static flipVertical(opt: TransformOptions): MemoryImage; /** - * Trim all edges of the image. + * Flips the **image** horizontally. */ - static readonly all: TrimSide; - private value; - constructor(...sides: [number | TrimSide, ...(number | TrimSide)[]]); - has(side: TrimSide): boolean; - } -} -declare module "transform/trim" { - /** @format */ - import { MemoryImage } from "common/memory-image"; - import { TrimMode } from "transform/trim-mode"; - import { TrimSide } from "transform/trim-side"; - export abstract class TrimTransform { + static flipHorizontal(opt: TransformOptions): MemoryImage; /** - * Find the crop area to be used by the trim function. - * Returns the Rectangle. You could pass these constraints - * to the **copyCrop** function to crop the image. + * Flip the **image** horizontally and vertically. */ - private static findTrim; + static flipHorizontalVertical(opt: TransformOptions): MemoryImage; /** * Automatically crops the image by finding the corners of the image that * meet the **mode** criteria (not transparent or a different color). * - * **mode** can be either **TrimMode.transparent**, **TrimMode.topLeftColor** or - * **TrimMode.bottomRightColor**. + * **mode** can be either _TrimMode.transparent_, _TrimMode.topLeftColor_ or + * _TrimMode.bottomRightColor_. * * **sides** can be used to control which sides of the image get trimmed, - * and can be any combination of **TrimSide.top**, **TrimSide.bottom**, **TrimSide.left**, - * and **TrimSide.right**. + * and can be any combination of _TrimSide.top_, _TrimSide.bottom_, _TrimSide.left_, + * and _TrimSide.right_. */ - static trim(src: MemoryImage, mode?: TrimMode, sides?: TrimSide): MemoryImage; + static trim(opt: TrimOptions): MemoryImage; } } declare module "index" { /** @format */ - import { FrameAnimation } from "common/frame-animation"; - import { MemoryImage } from "common/memory-image"; import { CompressionLevel, TypedArray } from "common/typings"; + import { Encoder } from "formats/encoder"; import { Decoder } from "formats/decoder"; + import { MemoryImage } from "image/image"; + import { PngFilterType } from "formats/png/png-filter-type"; + import { DitherKernel } from "filter/dither-kernel"; + import { ExifData } from "exif/exif-data"; + export { ChannelOrder, ChannelOrderLength } from "color/channel-order"; + export { Channel } from "color/channel"; + export { ColorFloat16 } from "color/color-float16"; + export { ColorFloat32 } from "color/color-float32"; + export { ColorFloat64 } from "color/color-float64"; + export { ColorInt8 } from "color/color-int8"; + export { ColorInt16 } from "color/color-int16"; + export { ColorInt32 } from "color/color-int32"; + export { ColorRgb8 } from "color/color-rgb8"; + export { ColorRgba8 } from "color/color-rgba8"; + export { ColorUint1 } from "color/color-uint1"; + export { ColorUint2 } from "color/color-uint2"; + export { ColorUint4 } from "color/color-uint4"; + export { ColorUint8 } from "color/color-uint8"; + export { ColorUint16 } from "color/color-uint16"; + export { ColorUint32 } from "color/color-uint32"; + export { Color, ColorConvertOptions } from "color/color"; + export { Format, FormatType, FormatMaxValue, FormatSize, FormatToFormatType, convertFormatValue, } from "color/format"; export { ArrayUtils } from "common/array-utils"; - export { BitOperators } from "common/bit-operators"; - export { BlendMode } from "common/blend-mode"; - export { ColorChannel } from "common/color-channel"; - export { ColorModel } from "common/color-model"; - export { Color } from "common/color"; - export { Crc32, Crc32Parameters } from "common/crc32"; - export { DisposeMode } from "common/dispose-mode"; - export { DitherKernel } from "common/dither-kernel"; - export { DitherPixel } from "common/dither-pixel"; - export { FrameAnimation, FrameAnimationInitOptions, } from "common/frame-animation"; - export { FrameType } from "common/frame-type"; - export { HeapNode } from "common/heap-node"; - export { ICCProfileData } from "common/icc-profile-data"; - export { ICCPCompressionMode } from "common/iccp-compression-mode"; + export { BitUtils } from "common/bit-utils"; + export { Crc32, Crc32Options } from "common/crc32"; + export { Float16 } from "common/float16"; export { InputBuffer, InputBufferInitOptions } from "common/input-buffer"; export { Interpolation } from "common/interpolation"; export { Line } from "common/line"; - export { MathOperators } from "common/math-operators"; - export { MemoryImage, MemoryImageInitOptions, MemoryImageInitOptionsColorModel, RgbMemoryImageInitOptions, } from "common/memory-image"; - export { NeuralQuantizer } from "common/neural-quantizer"; - export { OctreeNode } from "common/octree-node"; - export { OctreeQuantizer } from "common/octree-quantizer"; + export { MathUtils } from "common/math-utils"; export { OutputBuffer, OutputBufferInitOptions } from "common/output-buffer"; export { Point } from "common/point"; - export { Quantizer } from "common/quantizer"; export { RandomUtils } from "common/random-utils"; export { Rational } from "common/rational"; export { Rectangle } from "common/rectangle"; - export { RgbChannelSet } from "common/rgb-channel-set"; - export { TextCodec } from "common/text-codec"; - export { CompressionLevel, TypedArray, BufferEncoding } from "common/typings"; - export { DrawImageOptions } from "draw/draw-image-options"; - export { DrawLineOptions } from "draw/draw-line-options"; - export { Draw } from "draw/draw"; - export { FillFloodOptions } from "draw/fill-flood-options"; - export { MaskFloodOptions } from "draw/mask-flood-options"; - export { ExifAsciiValue } from "exif/exif-value/exif-ascii-value"; - export { ExifByteValue } from "exif/exif-value/exif-byte-value"; - export { ExifDoubleValue } from "exif/exif-value/exif-double-value"; - export { ExifLongValue } from "exif/exif-value/exif-long-value"; - export { ExifRationalValue } from "exif/exif-value/exif-rational-value"; - export { ExifSByteValue } from "exif/exif-value/exif-sbyte-value"; - export { ExifShortValue } from "exif/exif-value/exif-short-value"; - export { ExifSingleValue } from "exif/exif-value/exif-single-value"; - export { ExifSLongValue } from "exif/exif-value/exif-slong-value"; - export { ExifSRationalValue } from "exif/exif-value/exif-srational-value"; - export { ExifSShortValue } from "exif/exif-value/exif-sshort-value"; - export { ExifUndefinedValue } from "exif/exif-value/exif-undefined-value"; - export { ExifValue } from "exif/exif-value/exif-value"; + export { StringUtils } from "common/string-utils"; + export { BufferEncoding, CompressionLevel, TypedArray } from "common/typings"; + export { BlendMode } from "draw/blend-mode"; + export { CircleQuadrant } from "draw/circle-quadrant"; + export { Draw, CompositeImageOptions, DrawCircleOptions, DrawLineOptions, DrawPixelOptions, DrawPolygonOptions, DrawRectOptions, FillCircleOptions, FillFloodOptions, FillOptions, FillPolygonOptions, FillRectOptions, MaskFloodOptions, } from "draw/draw"; + export { LibError } from "error/lib-error"; + export { IfdAsciiValue } from "exif/ifd-value/ifd-ascii-value"; + export { IfdByteValue } from "exif/ifd-value/ifd-byte-value"; + export { IfdDoubleValue } from "exif/ifd-value/ifd-double-value"; + export { IfdLongValue } from "exif/ifd-value/ifd-long-value"; + export { IfdRationalValue } from "exif/ifd-value/ifd-rational-value"; + export { IfdSByteValue } from "exif/ifd-value/ifd-sbyte-value"; + export { IfdShortValue } from "exif/ifd-value/ifd-short-value"; + export { IfdSingleValue } from "exif/ifd-value/ifd-single-value"; + export { IfdSLongValue } from "exif/ifd-value/ifd-slong-value"; + export { IfdSRationalValue } from "exif/ifd-value/ifd-srational-value"; + export { IfdSShortValue } from "exif/ifd-value/ifd-sshort-value"; + export { IfdUndefinedValue } from "exif/ifd-value/ifd-undefined-value"; + export { IfdValue } from "exif/ifd-value/ifd-value"; export { ExifData } from "exif/exif-data"; export { ExifEntry } from "exif/exif-entry"; - export { ExifIFDContainer } from "exif/exif-ifd-container"; - export { ExifIFD } from "exif/exif-ifd"; export { ExifTag, ExifTagInitOptions, ExifGpsTags, ExifImageTags, ExifInteropTags, ExifTagNameToID, } from "exif/exif-tag"; - export { ExifValueType, ExifValueTypeSize, ExifValueTypeString, getExifValueTypeSize, getExifValueTypeString, } from "exif/exif-value-type"; - export { AdjustColorOptions } from "filter/adjust-color-options"; - export { ColorOffsetOptions } from "filter/color-offset-options"; - export { ConvolutionOptions } from "filter/convolution-options"; - export { ImageFilter } from "filter/image-filter"; + export { IfdContainer } from "exif/ifd-container"; + export { IfdDirectory } from "exif/ifd-directory"; + export { IfdValueType, IfdValueTypeSize, getIfdValueTypeSize, getIfdValueTypeString, } from "exif/ifd-value-type"; + export { DitherKernel, DitherKernels } from "filter/dither-kernel"; + export { Filter, AdjustColorOptions, BillboardOptions, BleachBypassOptions, BulgeDistortionOptions, BumpToNormalOptions, ChromaticAberrationOptions, ColorHalftone, ColorOffsetOptions, ContrastOptions, ConvolutionOptions, CopyImageChannelsOptions, DitherImageOptions, DotScreenOptions, DropShadowOptions, EdgeGlowOptions, EmbossOptions, GammaOptions, GaussianBlurOptions, GrayscaleOptions, HdrToLdrOptions, HexagonPixelateOptions, InvertOptions, LuminanceThresholdOptions, MonochromeOptions, NoiseOptions, NormalizeOptions, PixelateOptions, QuantizeOptions, ReinhardToneMapOptions, RemapColorsOptions, ScaleRgbaOptions, SeparableConvolutionOptions, SepiaOptions, SketchOptions, SmoothOptions, SobelOptions, StretchDistortionOptions, VignetteOptions, } from "filter/filter"; export { NoiseType } from "filter/noise-type"; export { PixelateMode } from "filter/pixelate-mode"; export { QuantizeMethod } from "filter/quantize-method"; - export { QuantizeOptions } from "filter/quantize-options"; - export { RemapColorsOptions } from "filter/remap-colors-options"; - export { SeparableKernel } from "filter/separable-kernel"; - export { VignetteOptions } from "filter/vignette-options"; - export { BmpDecoder } from "formats/bmp-decoder"; - export { BmpEncoder } from "formats/bmp-encoder"; - export { DecodeInfo } from "formats/decode-info"; - export { Decoder } from "formats/decoder"; - export { Encoder } from "formats/encoder"; - export { GifDecoder } from "formats/gif-decoder"; - export { GifEncoder, GifEncoderInitOptions } from "formats/gif-encoder"; - export { IcoDecoder } from "formats/ico-decoder"; - export { IcoEncoder } from "formats/ico-encoder"; - export { JpegDecoder } from "formats/jpeg-decoder"; - export { JpegEncoder } from "formats/jpeg-encoder"; - export { PngDecoder } from "formats/png-decoder"; - export { PngEncoder, PngEncoderInitOptions } from "formats/png-encoder"; - export { TgaDecoder } from "formats/tga-decoder"; - export { TgaEncoder } from "formats/tga-encoder"; - export { TiffDecoder } from "formats/tiff-decoder"; - export { TiffEncoder } from "formats/tiff-encoder"; - export { BitmapCompressionMode } from "formats/bmp/bitmap-compression-mode"; - export { BitmapFileHeader } from "formats/bmp/bitmap-file-header"; + export { SeparableKernel, SeparableKernelApplyOptions, } from "filter/separable-kernel"; + export { BmpCompressionMode } from "formats/bmp/bmp-compression-mode"; + export { BmpFileHeader } from "formats/bmp/bmp-file-header"; export { BmpInfo } from "formats/bmp/bmp-info"; - export { GifColorMap, GifColorMapInitOptions, } from "formats/gif/gif-color-map"; + export { GifColorMap } from "formats/gif/gif-color-map"; export { GifImageDesc } from "formats/gif/gif-image-desc"; export { GifInfo, GifInfoInitOptions } from "formats/gif/gif-info"; export { IcoBmpInfo } from "formats/ico/ico-bmp-info"; - export { IcoInfoImage } from "formats/ico/ico-info-image"; + export { IcoInfoImage, IcoInfoImageInitOptions, } from "formats/ico/ico-info-image"; export { IcoInfo } from "formats/ico/ico-info"; - export { ComponentData } from "formats/jpeg/component-data"; + export { IcoType, IcoTypeLength } from "formats/ico/ico-type"; + export { HuffmanNode } from "formats/jpeg/huffman-node"; + export { HuffmanParent } from "formats/jpeg/huffman-parent"; + export { HuffmanValue } from "formats/jpeg/huffman-value"; export { JpegAdobe } from "formats/jpeg/jpeg-adobe"; + export { JpegComponentData } from "formats/jpeg/jpeg-component-data"; export { JpegComponent } from "formats/jpeg/jpeg-component"; export { JpegData } from "formats/jpeg/jpeg-data"; export { JpegFrame } from "formats/jpeg/jpeg-frame"; export { JpegHuffman } from "formats/jpeg/jpeg-huffman"; export { JpegInfo } from "formats/jpeg/jpeg-info"; export { JpegJfif } from "formats/jpeg/jpeg-jfif"; + export { JpegMarker } from "formats/jpeg/jpeg-marker"; export { JpegQuantize } from "formats/jpeg/jpeg-quantize"; export { JpegScan } from "formats/jpeg/jpeg-scan"; - export { Jpeg } from "formats/jpeg/jpeg"; + export { JpegUtils } from "formats/jpeg/jpeg-utils"; + export { PngBlendMode } from "formats/png/png-blend-mode"; + export { PngColorType } from "formats/png/png-color-type"; + export { PngDisposeMode } from "formats/png/png-dispose-mode"; + export { PngFilterType } from "formats/png/png-filter-type"; export { PngFrame, PngFrameInitOptions } from "formats/png/png-frame"; export { PngInfo, PngInfoInitOptions } from "formats/png/png-info"; - export { TgaInfo } from "formats/tga/tga-info"; + export { TgaImageType, TgaImageTypeLength } from "formats/tga/tga-image-type"; + export { TgaInfo, TgaInfoInitOptions } from "formats/tga/tga-info"; export { TiffBitReader } from "formats/tiff/tiff-bit-reader"; + export { TiffCompression } from "formats/tiff/tiff-compression"; export { TiffEntry, TiffEntryInitOptions } from "formats/tiff/tiff-entry"; export { TiffFaxDecoder, TiffFaxDecoderInitOptions, } from "formats/tiff/tiff-fax-decoder"; + export { TiffFormat } from "formats/tiff/tiff-format"; + export { TiffImageType } from "formats/tiff/tiff-image-type"; export { TiffImage } from "formats/tiff/tiff-image"; export { TiffInfo, TiffInfoInitOptions } from "formats/tiff/tiff-info"; export { LzwDecoder } from "formats/tiff/tiff-lzw-decoder"; - export { Half } from "hdr/half"; - export { HdrImage } from "hdr/hdr-image"; - export { HdrSlice, HdrSliceInitOptions } from "hdr/hdr-slice"; - export { HdrToImage } from "hdr/hdr-to-image"; - export { CopyIntoOptions } from "transform/copy-into-options"; - export { CopyResizeOptionsUsingHeight, CopyResizeOptionsUsingWidth, } from "transform/copy-resize-options"; + export { TiffPhotometricType, TiffPhotometricTypeLength, } from "formats/tiff/tiff-photometric-type"; + export { BmpDecoder } from "formats/bmp-decoder"; + export { BmpEncoder } from "formats/bmp-encoder"; + export { DecodeInfo } from "formats/decode-info"; + export { Decoder } from "formats/decoder"; + export { DibDecoder } from "formats/dib-decoder"; + export { Encoder } from "formats/encoder"; + export { GifDecoder } from "formats/gif-decoder"; + export { GifEncoder, GifEncoderInitOptions } from "formats/gif-encoder"; + export { IcoDecoder } from "formats/ico-decoder"; + export { IcoEncoder } from "formats/ico-encoder"; + export { JpegDecoder } from "formats/jpeg-decoder"; + export { JpegEncoder } from "formats/jpeg-encoder"; + export { PngDecoder } from "formats/png-decoder"; + export { PngEncoder, PngEncoderInitOptions } from "formats/png-encoder"; + export { TgaDecoder } from "formats/tga-decoder"; + export { TgaEncoder } from "formats/tga-encoder"; + export { TiffDecoder } from "formats/tiff-decoder"; + export { TiffEncoder } from "formats/tiff-encoder"; + export { WinEncoder } from "formats/win-encoder"; + export { FrameType } from "image/frame-type"; + export { HeapNode } from "image/heap-node"; + export { IccProfile } from "image/icc-profile"; + export { IccProfileCompression } from "image/icc-profile-compression"; + export { MemoryImageDataFloat16 } from "image/image-data-float16"; + export { MemoryImageDataFloat32 } from "image/image-data-float32"; + export { MemoryImageDataFloat64 } from "image/image-data-float64"; + export { MemoryImageDataInt8 } from "image/image-data-int8"; + export { MemoryImageDataInt16 } from "image/image-data-int16"; + export { MemoryImageDataInt32 } from "image/image-data-int32"; + export { MemoryImageDataUint1 } from "image/image-data-uint1"; + export { MemoryImageDataUint2 } from "image/image-data-uint2"; + export { MemoryImageDataUint4 } from "image/image-data-uint4"; + export { MemoryImageDataUint8 } from "image/image-data-uint8"; + export { MemoryImageDataUint16 } from "image/image-data-uint16"; + export { MemoryImageDataUint32 } from "image/image-data-uint32"; + export { MemoryImageData } from "image/image-data"; + export { ImageUtils } from "image/image-utils"; + export { MemoryImage, MemoryImageCloneOptions, MemoryImageColorExtremes, MemoryImageConvertOptions, MemoryImageCreateOptions, MemoryImageFromBytesOptions, } from "image/image"; + export { NeuralQuantizer } from "image/neural-quantizer"; + export { OctreeNode } from "image/octree-node"; + export { OctreeQuantizer } from "image/octree-quantizer"; + export { PaletteFloat16 } from "image/palette-float16"; + export { PaletteFloat32 } from "image/palette-float32"; + export { PaletteFloat64 } from "image/palette-float64"; + export { PaletteInt8 } from "image/palette-int8"; + export { PaletteInt16 } from "image/palette-int16"; + export { PaletteInt32 } from "image/palette-int32"; + export { PaletteUint8 } from "image/palette-uint8"; + export { PaletteUint16 } from "image/palette-uint16"; + export { PaletteUint32 } from "image/palette-uint32"; + export { Palette } from "image/palette"; + export { PixelFloat16 } from "image/pixel-float16"; + export { PixelFloat32 } from "image/pixel-float32"; + export { PixelFloat64 } from "image/pixel-float64"; + export { PixelInt8 } from "image/pixel-int8"; + export { PixelInt16 } from "image/pixel-int16"; + export { PixelInt32 } from "image/pixel-int32"; + export { PixelUint1 } from "image/pixel-uint1"; + export { PixelUint2 } from "image/pixel-uint2"; + export { PixelUint4 } from "image/pixel-uint4"; + export { PixelUint8 } from "image/pixel-uint8"; + export { PixelUint16 } from "image/pixel-uint16"; + export { PixelUint32 } from "image/pixel-uint32"; + export { PixelUndefined } from "image/pixel-undefined"; + export { PixelRangeIterator } from "image/pixel-range-iterator"; + export { Pixel, UndefinedPixel } from "image/pixel"; + export { QuantizerType } from "image/quantizer-type"; + export { Quantizer } from "image/quantizer"; export { FlipDirection } from "transform/flip-direction"; - export { ImageTransform } from "transform/image-transform"; + export { Transform, CopyCropCircleOptions, CopyCropOptions, CopyRectifyOptions, CopyResizeCropSquareOptions, CopyResizeOptionsUsingHeight, CopyResizeOptionsUsingWidth, CopyRotateOptions, FlipOptions, TransformOptions, TrimOptions, } from "transform/transform"; export { TrimMode } from "transform/trim-mode"; export { TrimSide } from "transform/trim-side"; - export { TrimTransform } from "transform/trim"; - /** - * Find a **Decoder** that is able to decode the given image **data**. - * Use this is you don't know the type of image it is. Since this will - * validate the image against all known decoders, it is potentially very slow. - */ - export function findDecoderForData(data: TypedArray): Decoder | undefined; + export interface DecodeOptions { + data: TypedArray; + } + export interface DecodeImageOptions extends DecodeOptions { + frame?: number; + } + export interface DecodeNamedImageOptions extends DecodeImageOptions { + name: string; + } + export interface EncodeOptions { + image: MemoryImage; + } + export interface EncodeNamedImageOptions extends EncodeOptions { + name: string; + } + export interface EncodeJpgOptions extends EncodeOptions { + quality?: number; + } + export interface InjectJpgExifOptions extends DecodeOptions { + exifData: ExifData; + } + export interface EncodeAnimatedOptions extends EncodeOptions { + singleFrame?: boolean; + } + export interface EncodePngOptions extends EncodeAnimatedOptions { + level?: CompressionLevel; + filter?: PngFilterType; + } + export interface EncodeGifOptions extends EncodeAnimatedOptions { + repeat?: number; + samplingFactor?: number; + dither?: DitherKernel; + ditherSerpentine?: boolean; + } + export interface EncodeIcoImagesOptions { + images: MemoryImage[]; + } /** - * Decode the given image file bytes by first identifying the format of the - * file and using that decoder to decode the file into a single frame [Image]. + * Return the Decoder that can decode image with the given **name**, + * by looking at the file extension. */ - export function decodeImage(data: TypedArray): MemoryImage | undefined; + export function findDecoderForNamedImage(name: string): Decoder | undefined; /** - * Decode the given image file bytes by first identifying the format of the - * file and using that decoder to decode the file into an **FrameAnimation** - * containing one or more **MemoryImage** frames. + * Return the Encoder that can decode image with the given **name**, + * by looking at the file extension. */ - export function decodeAnimation(data: TypedArray): FrameAnimation | undefined; + export function findEncoderForNamedImage(name: string): Encoder | undefined; /** - * Return the **Decoder** that can decode image with the given **name**, - * by looking at the file extension. See also **findDecoderForData** to - * determine the decoder to use given the bytes of the file. + * Find a Decoder that is able to decode the given image **data**. + * Use this is you don't know the type of image it is. + * + * **WARNING:** Since this will check the image data against all known decoders, + * it is much slower than using an explicit decoder. */ - export function getDecoderForNamedImage(name: string): Decoder | undefined; + export function findDecoderForData(data: TypedArray): Decoder | undefined; /** - * Identify the format of the image using the file extension of the given - * **name**, and decode the given file **bytes** to an **FrameAnimation** with one or more - * **MemoryImage** frames. See also **decodeAnimation**. + * Decode the given image file bytes by first identifying the format of the + * file and using that decoder to decode the file into a single frame MemoryImage. + * + * **WARNING:** Since this will check the image data against all known decoders, + * it is much slower than using an explicit decoder. */ - export function decodeNamedAnimation(data: TypedArray, name: string): FrameAnimation | undefined; + export function decodeImage(opt: DecodeImageOptions): MemoryImage | undefined; /** - * Identify the format of the image using the file extension of the given - * **name**, and decode the given file **data** to a single frame **MemoryImage**. See - * also **decodeImage**. + * Decodes the given image file bytes, using the filename extension to + * determine the decoder. */ - export function decodeNamedImage(data: TypedArray, name: string): MemoryImage | undefined; + export function decodeNamedImage(opt: DecodeNamedImageOptions): MemoryImage | undefined; /** - * Identify the format of the image and encode it with the appropriate - * **Encoder**. + * Encode the MemoryImage to the format determined by the file extension of **name**. + * If a format wasn't able to be identified, undefined will be returned. + * Otherwise the encoded format bytes of the image will be returned. */ - export function encodeNamedImage(image: MemoryImage, name: string): Uint8Array | undefined; + export function encodeNamedImage(opt: EncodeNamedImageOptions): Uint8Array | undefined; /** * Decode a JPG formatted image. */ - export function decodeJpg(data: TypedArray): MemoryImage | undefined; + export function decodeJpg(opt: DecodeOptions): MemoryImage | undefined; /** * Encode an image to the JPEG format. */ - export function encodeJpg(image: MemoryImage, quality?: number): Uint8Array; + export function encodeJpg(opt: EncodeJpgOptions): Uint8Array; /** - * Decode a PNG formatted image. + * Decode only the ExifData from a JPEG file, returning undefined if it was + * unable to. */ - export function decodePng(data: TypedArray): MemoryImage | undefined; + export function decodeJpgExif(opt: DecodeOptions): ExifData | undefined; /** - * Decode a PNG formatted animation. + * Inject ExifData into a JPEG file, replacing any existing EXIF data. + * The new JPEG file bytes will be returned, otherwise undefined if there was an + * issue. */ - export function decodePngAnimation(data: TypedArray): FrameAnimation | undefined; + export function injectJpgExif(opt: InjectJpgExifOptions): Uint8Array | undefined; /** - * Encode an image to the PNG format. + * Decode a PNG formatted image. */ - export function encodePng(image: MemoryImage, level?: CompressionLevel): Uint8Array; + export function decodePng(opt: DecodeImageOptions): MemoryImage | undefined; /** - * Encode an animation to the PNG format. + * Encode an image to the PNG format. */ - export function encodePngAnimation(animation: FrameAnimation, level?: CompressionLevel): Uint8Array | undefined; + export function encodePng(opt: EncodePngOptions): Uint8Array; /** * Decode a Targa formatted image. */ - export function decodeTga(data: TypedArray): MemoryImage | undefined; + export function decodeTga(opt: DecodeImageOptions): MemoryImage | undefined; /** * Encode an image to the Targa format. */ - export function encodeTga(image: MemoryImage): Uint8Array; + export function encodeTga(opt: EncodeOptions): Uint8Array; /** * Decode a GIF formatted image (first frame for animations). */ - export function decodeGif(data: TypedArray): MemoryImage | undefined; - /** - * Decode an animated GIF file. If the GIF isn't animated, the animation - * will contain a single frame with the GIF's image. - */ - export function decodeGifAnimation(data: TypedArray): FrameAnimation | undefined; + export function decodeGif(opt: DecodeImageOptions): MemoryImage | undefined; /** * Encode an image to the GIF format. * @@ -4892,56 +8093,33 @@ declare module "index" { * If you know that you have less than 256 colors in your frames * anyway, you should supply a very large **samplingFactor** for maximum performance. */ - export function encodeGif(image: MemoryImage, samplingFactor?: number): Uint8Array; - /** - * Encode an animation to the GIF format. - * - * The **samplingFactor** specifies the sampling factor for - * NeuQuant image quantization. It is responsible for reducing - * the amount of unique colors in your images to 256. - * According to https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/, - * a sampling factor of 10 gives you a reasonable trade-off between - * image quality and quantization speed. - * If you know that you have less than 256 colors in your frames - * anyway, you should supply a very large **samplingFactor** for maximum performance. - * - * Here, `30` is used a default value for the **samplingFactor** as - * encoding animations is usually a process that takes longer than - * encoding a single image (see **encodeGif**). - */ - export function encodeGifAnimation(animation: FrameAnimation, samplingFactor?: number): Uint8Array | undefined; + export function encodeGif(opt: EncodeGifOptions): Uint8Array; /** * Decode a TIFF formatted image. */ - export function decodeTiff(data: TypedArray): MemoryImage | undefined; - /** - * Decode an multi-image (animated) TIFF file. If the tiff doesn't have - * multiple images, the animation will contain a single frame with the tiff's - * image. - */ - export function decodeTiffAnimation(data: TypedArray): FrameAnimation | undefined; + export function decodeTiff(opt: DecodeImageOptions): MemoryImage | undefined; /** * Encode an image to the TIFF format. */ - export function encodeTiff(image: MemoryImage): Uint8Array; + export function encodeTiff(opt: EncodeAnimatedOptions): Uint8Array; /** * Decode a BMP formatted image. */ - export function decodeBmp(data: TypedArray): MemoryImage | undefined; + export function decodeBmp(opt: DecodeOptions): MemoryImage | undefined; /** * Encode an image to the BMP format. */ - export function encodeBmp(image: MemoryImage): Uint8Array; + export function encodeBmp(opt: EncodeOptions): Uint8Array; /** - * Encode an image to the ICO format. + * Decode an ICO image. */ - export function encodeIco(image: MemoryImage): Uint8Array; + export function decodeIco(opt: DecodeImageOptions): MemoryImage | undefined; /** - * Encode a list of images to the ICO format. + * Encode an image to the ICO format. */ - export function encodeIcoImages(images: MemoryImage[]): Uint8Array; + export function encodeIco(opt: EncodeAnimatedOptions): Uint8Array; /** - * Decode an ICO image. + * Encode a list of images to the ICO format. */ - export function decodeIco(data: TypedArray): MemoryImage | undefined; + export function encodeIcoImages(opt: EncodeIcoImagesOptions): Uint8Array; } diff --git a/lib-compact/index.js b/lib-compact/index.js index d651629..f3bc5ff 100644 --- a/lib-compact/index.js +++ b/lib-compact/index.js @@ -1,8 +1,8 @@ -(()=>{var ws=Object.create;var Vn=Object.defineProperty,Is=Object.defineProperties,As=Object.getOwnPropertyDescriptor,vs=Object.getOwnPropertyDescriptors,Ps=Object.getOwnPropertyNames,hs=Object.getOwnPropertySymbols,Ss=Object.getPrototypeOf,cs=Object.prototype.hasOwnProperty,Cs=Object.prototype.propertyIsEnumerable;var fs=(m,e,t)=>e in m?Vn(m,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):m[e]=t,ds=(m,e)=>{for(var t in e||={})cs.call(e,t)&&fs(m,t,e[t]);if(hs)for(var t of hs(e))Cs.call(e,t)&&fs(m,t,e[t]);return m},ms=(m,e)=>Is(m,vs(e));var C=(m,e)=>()=>(m&&(e=m(m=0)),e);var Ms=(m,e)=>()=>(e||m((e={exports:{}}).exports,e),e.exports);var Bs=(m,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Ps(e))!cs.call(m,r)&&r!==t&&Vn(m,r,{get:()=>e[r],enumerable:!(i=As(e,r))||i.enumerable});return m};var An=(m,e,t)=>(t=m!=null?ws(Ss(m)):{},Bs(e||!m||!m.__esModule?Vn(t,"default",{value:m,enumerable:!0}):t,m));var T,ue=C(()=>{"use strict";T=class extends Error{toString(){return`ImageError: ${this.message}`}}});var te,ut=C(()=>{"use strict";ue();te=class{static copyInt8(e,t,i){return Int8Array.from(e.subarray(t,i))}static copyUint8(e,t,i){return Uint8Array.from(e.subarray(t,i))}static copyInt16(e,t,i){return Int16Array.from(e.subarray(t,i))}static copyUint16(e,t,i){return Uint16Array.from(e.subarray(t,i))}static copyInt32(e,t,i){return Int32Array.from(e.subarray(t,i))}static copyUint32(e,t,i){return Uint32Array.from(e.subarray(t,i))}static copyFloat32(e,t,i){return Float32Array.from(e.subarray(t,i))}static copyFloat64(e,t,i){return Float64Array.from(e.subarray(t,i))}static copy(e,t,i){if(e instanceof Int8Array)return te.copyInt8(e,t,i);if(e instanceof Uint8Array)return te.copyUint8(e,t,i);if(e instanceof Int16Array)return te.copyInt16(e,t,i);if(e instanceof Uint16Array)return te.copyUint16(e,t,i);if(e instanceof Int32Array)return te.copyInt32(e,t,i);if(e instanceof Uint32Array)return te.copyUint32(e,t,i);if(e instanceof Float32Array)return te.copyFloat32(e,t,i);if(e instanceof Float64Array)return te.copyFloat64(e,t,i);throw new T("Unknown array type")}static setRange(e,t,i,r,n=0){let s=r.subarray(n,i-t);e.set(s,t)}}});var ae,E,je=C(()=>{"use strict";ae=class{static signed(e,t){return t&1<>t)}static shiftL(e,t){return ae.signed(32,e<-1;r--)i+=(e&1<{"use strict"});var Vt=C(()=>{"use strict"});var Ci=C(()=>{"use strict"});var F,Qe=C(()=>{"use strict";F=class{static gcd(e,t){let i=Math.abs(e),r=Math.abs(t);for(;r;){let n=r;r=i%r,i=n}return i}static clamp(e,t,i){return Math.max(t,Math.min(e,i))}static clampInt(e,t,i){return Math.trunc(F.clamp(e,t,i))}static clampInt255(e){return Math.trunc(F.clamp(e,0,255))}}});var d,ge=C(()=>{"use strict";ue();je();Vt();Qe();d=class{static fromRgb(e,t,i){return d.getColor(e,t,i)}static fromRgba(e,t,i,r){return d.getColor(e,t,i,r)}static fromHsl(e,t,i){let r=d.hslToRgb(e,t,i);return d.getColor(r[0],r[1],r[2])}static fromHsv(e,t,i){let r=d.hsvToRgb(e,t,i);return d.getColor(r[0],r[1],r[2])}static fromXyz(e,t,i){let r=d.xyzToRgb(e,t,i);return d.getColor(r[0],r[1],r[2])}static fromLab(e,t,i){let r=d.labToRgb(e,t,i);return d.getColor(r[0],r[1],r[2])}static distance(e,t,i){let r=e[0]-t[0],n=e[1]-t[1],s=e[2]-t[2];if(i){let a=e[3]-t[3];return Math.sqrt(Math.max(r*r,(r-a)*(r-a))+Math.max(n*n,(n-a)*(n-a))+Math.max(s*s,(s-a)*(s-a)))}else return Math.sqrt(r*r+n*n+s*s)}static alphaBlendColors(e,t,i=255){let r=d.getAlpha(t);if(r===255&&i===255)return t;if(r===0&&i===255)return e;let n=r/255;i!==255&&(n*=i/255);let s=Math.round(d.getRed(t)*n),a=Math.round(d.getGreen(t)*n),o=Math.round(d.getBlue(t)*n),u=Math.round(r*n),l=Math.round(d.getRed(e)*(1-n)),h=Math.round(d.getGreen(e)*(1-n)),f=Math.round(d.getBlue(e)*(1-n)),c=Math.round(d.getAlpha(e)*(1-n));return d.getColor(s+l,a+h,o+f,u+c)}static getChannel(e,t){return t===0?d.getRed(e):t===1?d.getGreen(e):t===2?d.getBlue(e):t===3?d.getAlpha(e):d.getLuminance(e)}static getAlpha(e){return e>>24&255}static getBlue(e){return e>>16&255}static getColor(e,t,i,r=255){let n=F.clampInt255(r)<<24|F.clampInt255(i)<<16|F.clampInt255(t)<<8|F.clampInt255(e);return E.toUint32(n)}static getGreen(e){return e>>8&255}static getLuminance(e){let t=d.getRed(e),i=d.getGreen(e),r=d.getBlue(e);return d.getLuminanceRgb(t,i,r)}static getLuminanceRgb(e,t,i){return Math.round(.299*e+.587*t+.114*i)}static getRed(e){return e&255}static isBlack(e){return(e&16777215)===0}static isWhite(e){return(e&16777215)===16777215}static setAlpha(e,t){return e&16777215|F.clampInt255(t)<<24}static setBlue(e,t){return e&4278255615|F.clampInt255(t)<<16}static setChannel(e,t,i){return t===0?d.setRed(e,i):t===1?d.setGreen(e,i):t===2?d.setBlue(e,i):t===3?d.setAlpha(e,i):e}static setGreen(e,t){return e&4294902015|F.clampInt255(t)<<8}static setRed(e,t){return e&4294967040|F.clampInt255(t)}static hslToRgb(e,t,i){if(t===0){let l=Math.trunc(i*255);return[l,l,l]}let r=(l,h,f)=>{let c=f;return c<0&&(c+=1),c>1&&(c-=1),c<1/6?l+(h-l)*6*c:c<1/2?h:c<2/3?l+(h-l)*(2/3-c)*6:l},n=i<.5?i*(1+t):i+t-i*t,s=2*i-n,a=r(s,n,e+1/3),o=r(s,n,e),u=r(s,n,e-1/3);return[Math.round(a*255),Math.round(o*255),Math.round(u*255)]}static hsvToRgb(e,t,i){if(t===0){let u=Math.round(i*255);return[u,u,u]}let r=(e-Math.floor(e))*6,n=r-Math.floor(r),s=i*(1-t),a=i*(1-t*n),o=i*(1-t*(1-n));switch(Math.trunc(r)){case 0:return[Math.round(i*255),Math.round(o*255),Math.round(s*255)];case 1:return[Math.round(a*255),Math.round(i*255),Math.round(s*255)];case 2:return[Math.round(s*255),Math.round(i*255),Math.round(o*255)];case 3:return[Math.round(s*255),Math.round(a*255),Math.round(i*255)];case 4:return[Math.round(o*255),Math.round(s*255),Math.round(i*255)];case 5:return[Math.round(i*255),Math.round(s*255),Math.round(a*255)];default:throw new T("Invalid hue")}}static rgbToHsl(e,t,i){let r=e/255,n=t/255,s=i/255,a=Math.max(r,Math.max(n,s)),o=Math.min(r,Math.min(n,s)),u=(a+o)/2;if(a===o)return[0,0,u];let l=a-o,h=u>.5?l/(2-a-o):l/(a+o),f=0;return a===r?f=(n-s)/l+(n.008856?n=Math.pow(n,3):n=(n-16/116)/7.787,Math.pow(r,3)>.008856?r=Math.pow(r,3):r=(r-16/116)/7.787,Math.pow(s,3)>.008856?s=Math.pow(s,3):s=(s-16/116)/7.787,[Math.trunc(n*95.047),Math.trunc(r*100),Math.trunc(s*108.883)]}static xyzToRgb(e,t,i){let r=e/100,n=t/100,s=i/100,a=3.2406*r+-1.5372*n+-.4986*s,o=-.9689*r+1.8758*n+.0415*s,u=.0557*r+-.204*n+1.057*s;return a>.0031308?a=1.055*Math.pow(a,.4166666667)-.055:a*=12.92,o>.0031308?o=1.055*Math.pow(o,.4166666667)-.055:o*=12.92,u>.0031308?u=1.055*Math.pow(u,.4166666667)-.055:u*=12.92,[Math.trunc(F.clamp(a*255,0,255)),Math.trunc(F.clamp(o*255,0,255)),Math.trunc(F.clamp(u*255,0,255))]}static cmykToRgb(e,t,i,r){let n=e/255,s=t/255,a=i/255,o=r/255;return[Math.round(255*(1-n)*(1-o)),Math.round(255*(1-s)*(1-o)),Math.round(255*(1-a)*(1-o))]}static labToRgb(e,t,i){let a=(e+16)/116,o=t/500+a,u=a-i/200,l=Math.pow(a,3);l>.008856?a=l:a=(a-16/116)/7.787;let h=Math.pow(o,3);h>.008856?o=h:o=(o-16/116)/7.787;let f=Math.pow(u,3);f>.008856?u=f:u=(u-16/116)/7.787,o*=95.047,a*=100,u*=108.883,o/=100,a/=100,u/=100;let c=o*3.2406+a*-1.5372+u*-.4986,p=o*-.9689+a*1.8758+u*.0415,g=o*.0557+a*-.204+u*1.057;return c>.0031308?c=1.055*Math.pow(c,1/2.4)-.055:c*=12.92,p>.0031308?p=1.055*Math.pow(p,1/2.4)-.055:p*=12.92,g>.0031308?g=1.055*Math.pow(g,1/2.4)-.055:g*=12.92,[Math.trunc(F.clamp(c*255,0,255)),Math.trunc(F.clamp(p*255,0,255)),Math.trunc(F.clamp(g*255,0,255))]}static rgbToXyz(e,t,i){let r=e/255,n=t/255,s=i/255;return r>.04045?r=Math.pow((r+.055)/1.055,2.4):r/=12.92,n>.04045?n=Math.pow((n+.055)/1.055,2.4):n/=12.92,s>.04045?s=Math.pow((s+.055)/1.055,2.4):s/=12.92,r*=100,n*=100,s*=100,[r*.4124+n*.3576+s*.1805,r*.2126+n*.7152+s*.0722,r*.0193+n*.1192+s*.9505]}static xyzToLab(e,t,i){let r=e/95.047,n=t/100,s=i/108.883;return r>.008856?r=Math.pow(r,1/3):r=7.787*r+16/116,n>.008856?n=Math.pow(n,1/3):n=7.787*n+16/116,s>.008856?s=Math.pow(s,1/3):s=7.787*s+16/116,[116*n-16,500*(r-n),200*(n-s)]}static rgbToLab(e,t,i){let r=e/255,n=t/255,s=i/255;r>.04045?r=Math.pow((r+.055)/1.055,2.4):r/=12.92,n>.04045?n=Math.pow((n+.055)/1.055,2.4):n/=12.92,s>.04045?s=Math.pow((s+.055)/1.055,2.4):s/=12.92,r*=100,n*=100,s*=100;let a=r*.4124+n*.3576+s*.1805,o=r*.2126+n*.7152+s*.0722,u=r*.0193+n*.1192+s*.9505;return a/=95.047,o/=100,u/=108.883,a>.008856?a=Math.pow(a,1/3):a=7.787*a+16/116,o>.008856?o=Math.pow(o,1/3):o=7.787*o+16/116,u>.008856?u=Math.pow(u,1/3):u=7.787*u+16/116,[116*o-16,500*(a-o),200*(o-u)]}}});var Pn,pt,Yt=C(()=>{"use strict";Pn=class{static makeTable(){let e=[],t=0;for(let i=0;i<256;i++){t=i;for(let r=0;r<8;r++)t=t&1?3988292384^t>>>1:t>>>1;e[i]=t}return e}static getChecksum(e){var a,o,u;let t=Pn.crcTable,i=(a=e.length)!=null?a:e.buffer.length,r=(o=e.position)!=null?o:0,n=r+i,s=((u=e.baseCrc)!=null?u:0)^-1;for(let l=r;l>>8^t[(s^e.buffer[l])&255];return(s^-1)>>>0}},pt=Pn;pt.crcTable=new Uint32Array(Pn.makeTable())});var zt=C(()=>{"use strict"});var Wt=C(()=>{"use strict"});var Yn,Tt,Mi=C(()=>{"use strict";Wt();Yn=class{static getDitherPixels(e,t,i,r){if(i===0)return t.getIndexMap(e);let n=Yn.ditherKernels[i],s=e.height,a=e.width,o=new Uint8Array(e.getBytes()),u=new Uint8Array(a*s),l=t.colorMap8,h=r?-1:1,f=0;for(let c=0;c=0&&Z+b=0&&j+c{"use strict"});var Xe,bt=C(()=>{"use strict";Xt();Xe=class{constructor(e){this._width=0;this._height=0;this._backgroundColor=4294967295;this._loopCount=0;this._frameType=0;this._frames=[];var t,i,r,n;this._width=(t=e==null?void 0:e.width)!=null?t:0,this._height=(i=e==null?void 0:e.height)!=null?i:0,this._loopCount=(r=e==null?void 0:e.loopCount)!=null?r:0,this._frameType=(n=e==null?void 0:e.frameType)!=null?n:0}get width(){return this._width}get height(){return this._height}get backgroundColor(){return this._backgroundColor}get loopCount(){return this._loopCount}get frameType(){return this._frameType}get frames(){return this._frames}get numFrames(){return this.frames.length}get first(){return this.frames[0]}get last(){return this.frames[this.frames.length-1]}get isEmpty(){return this.frames.length===0}get isNotEmpty(){return this.frames.length>0}getFrame(e){return this.frames[e]}addFrame(e){this._width({value:this._frames[++e],done:!(e in this._frames)})}}}});var Bi,Ti=C(()=>{"use strict";Bi=class{constructor(){this._buf=[void 0]}get buf(){return this._buf}get n(){return this._buf.length}}});var qt=C(()=>{"use strict"});var ce,xt=C(()=>{"use strict";ue();ce=class{static getCodePoints(e){let t=new Uint8Array(e.length);for(let i=0;i{"use strict";ue();je();xt();G=class{get buffer(){return this._buffer}set bigEndian(e){this._bigEndian=e}get bigEndian(){return this._bigEndian}set offset(e){this._offset=e}get offset(){return this._offset}get start(){return this._start}get end(){return this._end}get position(){return this._offset-this._start}get length(){return this._end-this._offset}get isEOS(){return this._offset>=this._end}constructor(e){var t,i;this._buffer=e.buffer,this._bigEndian=(t=e.bigEndian)!=null?t:!1,this._offset=(i=e.offset)!=null?i:0,this._start=this._offset,this._end=e.length!==void 0?this._start+e.length:this._buffer.length}static from(e,t,i){let r=t!=null?t:0,n=new G({buffer:e._buffer,bigEndian:e._bigEndian,offset:e._offset+r,length:i});return n._start=e._start,n._end=i!==void 0?e.offset+r+i:e._end,n}rewind(){this._offset=this._start}getByte(e){return this._buffer[this._offset+e]}setByte(e,t){return this._buffer[this._offset+e]=t}memset(e,t,i){this._buffer.fill(this._offset+e,this._offset+e+t,i)}subarray(e,t,i=0){let r=t!==void 0?this._start+t:this._offset;return r+=i,new G({buffer:this._buffer,bigEndian:this._bigEndian,offset:r,length:e})}indexOf(e,t=0){for(let i=this._offset+t,r=this._offset+this.length;i{"use strict"});var qe,Ei=C(()=>{"use strict";qe=class{constructor(e,t,i,r){this._startX=0;this._startY=0;this._endX=0;this._endY=0;this._dx=0;this._dy=0;this.initialize(e,t,i,r)}get startX(){return this._startX}get startY(){return this._startY}get endX(){return this._endX}get endY(){return this._endY}get dx(){return this._dx}get dy(){return this._dy}static from(e){return new qe(e.startX,e.startY,e.endX,e.endY)}initialize(e,t,i,r){this._startX=Math.min(e,i),this._startY=Math.min(t,r),this._endX=Math.max(e,i),this._endY=Math.max(t,r),this._dx=this._endX-this._startX,this._dy=this._endY-this._startY}moveStart(e,t){this.initialize(e,t,this._endX,this._endY)}moveEnd(e,t){this.initialize(this._startX,this._startY,e,t)}}});var Ve=C(()=>{"use strict"});var Oi,Ui=C(()=>{"use strict";Oi=class{get tag(){return this._tag}get value(){return this._value}set value(e){this._value=e}constructor(e,t){this._tag=e,this._value=t}}});var se,vt=C(()=>{"use strict";Qe();se=class{get numerator(){return this._numerator}get denominator(){return this._denominator}get asInt(){return this.denominator!==0?Math.trunc(this.numerator/this.denominator):0}get asDouble(){return this.denominator!==0?this.numerator/this.denominator:0}constructor(e,t){this._numerator=e,this._denominator=t}simplify(){let e=F.gcd(this.numerator,this.denominator);e!==0&&(this._numerator=Math.trunc(this.numerator/e),this._denominator=Math.trunc(this.denominator/e))}equalsTo(e){return e instanceof se&&this._numerator===e._numerator&&this._denominator===e._denominator}toString(){return`${this._numerator}/${this._denominator}`}}});var yt,$t=C(()=>{"use strict";Kt();yt=class{get keys(){return this.directories.keys()}get values(){return this.directories.values()}get size(){return this.directories.size}get isEmpty(){if(this.directories.size===0)return!0;for(let e of this.directories.values())if(!e.isEmpty)return!1;return!0}constructor(e){this.directories=e!=null?e:new Map}static from(e){return new yt(e.directories)}has(e){return this.directories.has(e)}get(e){let t=this.directories.get(e);return t===void 0&&(t=new _t,this.directories.set(e,t)),t}set(e,t){this.directories.set(e,t)}clear(){this.directories.clear()}}});function $r(m){return Mn[m]}function Kr(m,e=1){return Lr[m]*e}var ve,Mn,Lr,Ie=C(()=>{"use strict";ve=(c=>(c[c.none=0]="none",c[c.byte=1]="byte",c[c.ascii=2]="ascii",c[c.short=3]="short",c[c.long=4]="long",c[c.rational=5]="rational",c[c.sbyte=6]="sbyte",c[c.undefined=7]="undefined",c[c.sshort=8]="sshort",c[c.slong=9]="slong",c[c.srational=10]="srational",c[c.single=11]="single",c[c.double=12]="double",c))(ve||{}),Mn=["None","Byte","Ascii","Short","Long","Rational","SByte","Undefined","SShort","SLong","SRational","Single","Double"],Lr=[0,1,1,2,4,8,1,1,2,4,8,4,8]});var _,Nr,Fi,zn,Wn,jt=C(()=>{"use strict";Ie();_=class{get name(){return this._name}get type(){return this._type}get count(){return this._count}constructor(e){var t,i;this._name=e.name,this._type=(t=e.type)!=null?t:0,this._count=(i=e.count)!=null?i:1}},Nr=new Map([["ProcessingSoftware",11],["SubfileType",254],["OldSubfileType",255],["ImageWidth",256],["ImageLength",257],["ImageHeight",257],["BitsPerSample",258],["Compression",259],["PhotometricInterpretation",262],["Thresholding",263],["CellWidth",264],["CellLength",265],["FillOrder",266],["DocumentName",269],["ImageDescription",270],["Make",271],["Model",272],["StripOffsets",273],["Orientation",274],["SamplesPerPixel",277],["RowsPerStrip",278],["StripByteCounts",279],["MinSampleValue",280],["MaxSampleValue",281],["XResolution",282],["YResolution",283],["PlanarConfiguration",284],["PageName",285],["XPosition",286],["YPosition",287],["GrayResponseUnit",290],["GrayResponseCurve",291],["T4Options",292],["T6Options",293],["ResolutionUnit",296],["PageNumber",297],["ColorResponseUnit",300],["TransferFunction",301],["Software",305],["DateTime",306],["Artist",315],["HostComputer",316],["Predictor",317],["WhitePoint",318],["PrimaryChromaticities",319],["ColorMap",320],["HalftoneHints",321],["TileWidth",322],["TileLength",323],["TileOffsets",324],["TileByteCounts",325],["BadFaxLines",326],["CleanFaxData",327],["ConsecutiveBadFaxLines",328],["InkSet",332],["InkNames",333],["NumberofInks",334],["DotRange",336],["TargetPrinter",337],["ExtraSamples",338],["SampleFormat",339],["SMinSampleValue",340],["SMaxSampleValue",341],["TransferRange",342],["ClipPath",343],["JPEGProc",512],["JPEGInterchangeFormat",513],["JPEGInterchangeFormatLength",514],["YCbCrCoefficients",529],["YCbCrSubSampling",530],["YCbCrPositioning",531],["ReferenceBlackWhite",532],["ApplicationNotes",700],["Rating",18246],["CFARepeatPatternDim",33421],["CFAPattern",33422],["BatteryLevel",33423],["Copyright",33432],["ExposureTime",33434],["FNumber",33437],["IPTC-NAA",33723],["ExifOffset",34665],["InterColorProfile",34675],["ExposureProgram",34850],["SpectralSensitivity",34852],["GPSOffset",34853],["ISOSpeed",34855],["OECF",34856],["SensitivityType",34864],["RecommendedExposureIndex",34866],["ExifVersion",36864],["DateTimeOriginal",36867],["DateTimeDigitized",36868],["OffsetTime",36880],["OffsetTimeOriginal",36881],["OffsetTimeDigitized",36882],["ComponentsConfiguration",37121],["CompressedBitsPerPixel",37122],["ShutterSpeedValue",37377],["ApertureValue",37378],["BrightnessValue",37379],["ExposureBiasValue",37380],["MaxApertureValue",37381],["SubjectDistance",37382],["MeteringMode",37383],["LightSource",37384],["Flash",37385],["FocalLength",37386],["SubjectArea",37396],["MakerNote",37500],["UserComment",37510],["SubSecTime",37520],["SubSecTimeOriginal",37521],["SubSecTimeDigitized",37522],["XPTitle",40091],["XPComment",40092],["XPAuthor",40093],["XPKeywords",40094],["XPSubject",40095],["FlashPixVersion",40960],["ColorSpace",40961],["ExifImageWidth",40962],["ExifImageLength",40963],["RelatedSoundFile",40964],["InteroperabilityOffset",40965],["FlashEnergy",41483],["SpatialFrequencyResponse",41484],["FocalPlaneXResolution",41486],["FocalPlaneYResolution",41487],["FocalPlaneResolutionUnit",41488],["SubjectLocation",41492],["ExposureIndex",41493],["SensingMethod",41495],["FileSource",41728],["SceneType",41729],["CVAPattern",41730],["CustomRendered",41985],["ExposureMode",41986],["WhiteBalance",41987],["DigitalZoomRatio",41988],["FocalLengthIn35mmFilm",41989],["SceneCaptureType",41990],["GainControl",41991],["Contrast",41992],["Saturation",41993],["Sharpness",41994],["DeviceSettingDescription",41995],["SubjectDistanceRange",41996],["ImageUniqueID",42016],["CameraOwnerName",42032],["BodySerialNumber",42033],["LensSpecification",42034],["LensMake",42035],["LensModel",42036],["LensSerialNumber",42037],["Gamma",42240],["PrintIM",50341],["Padding",59932],["OffsetSchema",59933],["OwnerName",65e3],["SerialNumber",65001],["InteropIndex",1],["InteropVersion",2],["RelatedImageFileFormat",4096],["RelatedImageWidth",4097],["RelatedImageLength",4098],["GPSVersionID",0],["GPSLatitudeRef",1],["GPSLatitude",2],["GPSLongitudeRef",3],["GPSLongitude",4],["GPSAltitudeRef",5],["GPSAltitude",6],["GPSTimeStamp",7],["GPSSatellites",8],["GPSStatus",9],["GPSMeasureMode",10],["GPSDOP",11],["GPSSpeedRef",12],["GPSSpeed",13],["GPSTrackRef",14],["GPSTrack",15],["GPSImgDirectionRef",16],["GPSImgDirection",17],["GPSMapDatum",18],["GPSDestLatitudeRef",19],["GPSDestLatitude",20],["GPSDestLongitudeRef",21],["GPSDestLongitude",22],["GPSDestBearingRef",23],["GPSDestBearing",24],["GPSDestDistanceRef",25],["GPSDestDistance",26],["GPSProcessingMethod",27],["GPSAreaInformation",28],["GPSDate",29],["GPSDifferential",30]]),Fi=new Map([[11,new _({name:"ProcessingSoftware",type:2})],[254,new _({name:"SubfileType",type:4})],[255,new _({name:"OldSubfileType",type:4})],[256,new _({name:"ImageWidth",type:4})],[257,new _({name:"ImageLength",type:4})],[258,new _({name:"BitsPerSample",type:3})],[259,new _({name:"Compression",type:3})],[262,new _({name:"PhotometricInterpretation",type:3})],[263,new _({name:"Thresholding",type:3})],[264,new _({name:"CellWidth",type:3})],[265,new _({name:"CellLength",type:3})],[266,new _({name:"FillOrder",type:3})],[269,new _({name:"DocumentName",type:2})],[270,new _({name:"ImageDescription",type:2})],[271,new _({name:"Make",type:2})],[272,new _({name:"Model",type:2})],[273,new _({name:"StripOffsets",type:4})],[274,new _({name:"Orientation",type:3})],[277,new _({name:"SamplesPerPixel",type:3})],[278,new _({name:"RowsPerStrip",type:4})],[279,new _({name:"StripByteCounts",type:4})],[280,new _({name:"MinSampleValue",type:3})],[281,new _({name:"MaxSampleValue",type:3})],[282,new _({name:"XResolution",type:5})],[283,new _({name:"YResolution",type:5})],[284,new _({name:"PlanarConfiguration",type:3})],[285,new _({name:"PageName",type:2})],[286,new _({name:"XPosition",type:5})],[287,new _({name:"YPosition",type:5})],[290,new _({name:"GrayResponseUnit",type:3})],[291,new _({name:"GrayResponseCurve"})],[292,new _({name:"T4Options"})],[293,new _({name:"T6Options"})],[296,new _({name:"ResolutionUnit",type:3})],[297,new _({name:"PageNumber",type:3,count:2})],[300,new _({name:"ColorResponseUnit"})],[301,new _({name:"TransferFunction",type:3,count:768})],[305,new _({name:"Software",type:2})],[306,new _({name:"DateTime",type:2})],[315,new _({name:"Artist",type:2})],[316,new _({name:"HostComputer",type:2})],[317,new _({name:"Predictor",type:3})],[318,new _({name:"WhitePoint",type:5,count:2})],[319,new _({name:"PrimaryChromaticities",type:5,count:6})],[320,new _({name:"ColorMap"})],[321,new _({name:"HalftoneHints",type:3,count:2})],[322,new _({name:"TileWidth",type:4})],[323,new _({name:"TileLength",type:4})],[324,new _({name:"TileOffsets"})],[325,new _({name:"TileByteCounts"})],[326,new _({name:"BadFaxLines"})],[327,new _({name:"CleanFaxData"})],[328,new _({name:"ConsecutiveBadFaxLines"})],[332,new _({name:"InkSet"})],[333,new _({name:"InkNames"})],[334,new _({name:"NumberofInks"})],[336,new _({name:"DotRange"})],[337,new _({name:"TargetPrinter",type:2})],[338,new _({name:"ExtraSamples"})],[339,new _({name:"SampleFormat"})],[340,new _({name:"SMinSampleValue"})],[341,new _({name:"SMaxSampleValue"})],[342,new _({name:"TransferRange"})],[343,new _({name:"ClipPath"})],[512,new _({name:"JPEGProc"})],[513,new _({name:"JPEGInterchangeFormat"})],[514,new _({name:"JPEGInterchangeFormatLength"})],[529,new _({name:"YCbCrCoefficients",type:5,count:3})],[530,new _({name:"YCbCrSubSampling",type:3})],[531,new _({name:"YCbCrPositioning",type:3})],[532,new _({name:"ReferenceBlackWhite",type:5,count:6})],[700,new _({name:"ApplicationNotes",type:3})],[18246,new _({name:"Rating",type:3})],[33421,new _({name:"CFARepeatPatternDim"})],[33422,new _({name:"CFAPattern"})],[33423,new _({name:"BatteryLevel"})],[33432,new _({name:"Copyright",type:2})],[33434,new _({name:"ExposureTime",type:5})],[33437,new _({name:"FNumber",type:5})],[33723,new _({name:"IPTC-NAA",type:4})],[34665,new _({name:"ExifOffset"})],[34675,new _({name:"InterColorProfile"})],[34850,new _({name:"ExposureProgram",type:3})],[34852,new _({name:"SpectralSensitivity",type:2})],[34853,new _({name:"GPSOffset"})],[34855,new _({name:"ISOSpeed",type:4})],[34856,new _({name:"OECF"})],[34864,new _({name:"SensitivityType",type:3})],[34866,new _({name:"RecommendedExposureIndex",type:4})],[34867,new _({name:"ISOSpeed",type:4})],[36864,new _({name:"ExifVersion",type:7})],[36867,new _({name:"DateTimeOriginal",type:2})],[36868,new _({name:"DateTimeDigitized",type:2})],[36880,new _({name:"OffsetTime",type:2})],[36881,new _({name:"OffsetTimeOriginal",type:2})],[36882,new _({name:"OffsetTimeDigitized",type:2})],[37121,new _({name:"ComponentsConfiguration"})],[37122,new _({name:"CompressedBitsPerPixel"})],[37377,new _({name:"ShutterSpeedValue"})],[37378,new _({name:"ApertureValue"})],[37379,new _({name:"BrightnessValue"})],[37380,new _({name:"ExposureBiasValue"})],[37381,new _({name:"MaxApertureValue"})],[37382,new _({name:"SubjectDistance"})],[37383,new _({name:"MeteringMode"})],[37384,new _({name:"LightSource"})],[37385,new _({name:"Flash"})],[37386,new _({name:"FocalLength"})],[37396,new _({name:"SubjectArea"})],[37500,new _({name:"MakerNote"})],[37510,new _({name:"UserComment"})],[37520,new _({name:"SubSecTime"})],[37521,new _({name:"SubSecTimeOriginal"})],[37522,new _({name:"SubSecTimeDigitized"})],[40091,new _({name:"XPTitle"})],[40092,new _({name:"XPComment"})],[40093,new _({name:"XPAuthor"})],[40094,new _({name:"XPKeywords"})],[40095,new _({name:"XPSubject"})],[40960,new _({name:"FlashPixVersion"})],[40961,new _({name:"ColorSpace",type:3})],[40962,new _({name:"ExifImageWidth",type:3})],[40963,new _({name:"ExifImageLength",type:3})],[40964,new _({name:"RelatedSoundFile"})],[40965,new _({name:"InteroperabilityOffset"})],[41483,new _({name:"FlashEnergy"})],[41484,new _({name:"SpatialFrequencyResponse"})],[41486,new _({name:"FocalPlaneXResolution"})],[41487,new _({name:"FocalPlaneYResolution"})],[41488,new _({name:"FocalPlaneResolutionUnit"})],[41492,new _({name:"SubjectLocation"})],[41493,new _({name:"ExposureIndex"})],[41495,new _({name:"SensingMethod"})],[41728,new _({name:"FileSource"})],[41729,new _({name:"SceneType"})],[41730,new _({name:"CVAPattern"})],[41985,new _({name:"CustomRendered"})],[41986,new _({name:"ExposureMode"})],[41987,new _({name:"WhiteBalance"})],[41988,new _({name:"DigitalZoomRatio"})],[41989,new _({name:"FocalLengthIn35mmFilm"})],[41990,new _({name:"SceneCaptureType"})],[41991,new _({name:"GainControl"})],[41992,new _({name:"Contrast"})],[41993,new _({name:"Saturation"})],[41994,new _({name:"Sharpness"})],[41995,new _({name:"DeviceSettingDescription"})],[41996,new _({name:"SubjectDistanceRange"})],[42016,new _({name:"ImageUniqueID"})],[42032,new _({name:"CameraOwnerName",type:2})],[42033,new _({name:"BodySerialNumber",type:2})],[42034,new _({name:"LensSpecification"})],[42035,new _({name:"LensMake",type:2})],[42036,new _({name:"LensModel",type:2})],[42037,new _({name:"LensSerialNumber",type:2})],[42240,new _({name:"Gamma",type:5})],[50341,new _({name:"PrintIM"})],[59932,new _({name:"Padding"})],[59933,new _({name:"OffsetSchema"})],[65e3,new _({name:"OwnerName",type:2})],[65001,new _({name:"SerialNumber",type:2})]]),zn=new Map([[1,new _({name:"InteropIndex",type:2})],[2,new _({name:"InteropVersion",type:7})],[4096,new _({name:"RelatedImageFileFormat",type:2})],[4097,new _({name:"RelatedImageWidth",type:3})],[4098,new _({name:"RelatedImageLength",type:3})]]),Wn=new Map([[0,new _({name:"GPSVersionID"})],[1,new _({name:"GPSLatitudeRef"})],[2,new _({name:"GPSLatitude"})],[3,new _({name:"GPSLongitudeRef"})],[4,new _({name:"GPSLongitude"})],[5,new _({name:"GPSAltitudeRef"})],[6,new _({name:"GPSAltitude"})],[7,new _({name:"GPSTimeStamp"})],[8,new _({name:"GPSSatellites"})],[9,new _({name:"GPSStatus"})],[10,new _({name:"GPSMeasureMode"})],[11,new _({name:"GPSDOP"})],[12,new _({name:"GPSSpeedRef"})],[13,new _({name:"GPSSpeed"})],[14,new _({name:"GPSTrackRef"})],[15,new _({name:"GPSTrack"})],[16,new _({name:"GPSImgDirectionRef"})],[17,new _({name:"GPSImgDirection"})],[18,new _({name:"GPSMapDatum"})],[19,new _({name:"GPSDestLatitudeRef"})],[20,new _({name:"GPSDestLatitude"})],[21,new _({name:"GPSDestLongitudeRef"})],[22,new _({name:"GPSDestLongitude"})],[23,new _({name:"GPSDestBearingRef"})],[24,new _({name:"GPSDestBearing"})],[25,new _({name:"GPSDestDistanceRef"})],[26,new _({name:"GPSDestDistance"})],[27,new _({name:"GPSProcessingMethod"})],[28,new _({name:"GPSAreaInformation"})],[29,new _({name:"GPSDate"})],[30,new _({name:"GPSDifferential"})]])});var ne,Ce=C(()=>{"use strict";vt();ue();Ie();ne=class{get type(){return 0}get length(){return 0}get dataSize(){return Kr(this.type,this.length)}get typeString(){return $r(this.type)}toBool(e){return!1}toInt(e){return 0}toDouble(e){return 0}toRational(e){return new se(0,1)}toString(){return""}write(e){}setBool(e,t){}setInt(e,t){}setDouble(e,t){}setRational(e,t,i){}setString(e){}equalsTo(e){return!1}clone(){throw new T("Cannot be copied.")}}});var Ee,Qt=C(()=>{"use strict";xt();Ce();Ie();Ee=class extends ne{constructor(t){super();typeof t=="string"?this.value=t:this.value=String.fromCharCode(...t)}get type(){return 2}get length(){return this.value.length}static fromData(t,i){let r=i>0?t.readString(i-1):t.readString();return new Ee(r)}toData(){return ce.getCodePoints(this.value)}toString(){return this.value}write(t){let i=ce.getCodePoints(this.value);t.writeBytes(i)}setString(t){this.value=t}equalsTo(t){return t instanceof Ee&&this.length===t.length}clone(){return new Ee(this.value)}}});var Je,Jt=C(()=>{"use strict";Ce();Ie();Je=class extends ne{constructor(t){super();typeof t=="number"?(this.value=new Uint8Array(1),this.value[0]=t):this.value=t}get type(){return 1}get length(){return this.value.length}static fromData(t,i,r){let n=t.toUint8Array(i,r);return new Je(n)}toInt(t=0){return this.value[t]}toData(){return this.value}toString(){return this.value.length===1?`${this.value[0]}`:`${this.value}`}write(t){t.writeBytes(this.value)}setInt(t,i=0){this.value[i]=t}equalsTo(t){return t instanceof Je&&this.length===t.length}clone(){return new Je(this.value)}}});var et,ei=C(()=>{"use strict";Ce();Ie();et=class extends ne{constructor(t){super();typeof t=="number"?(this.value=new Float64Array(1),this.value[0]=t):this.value=t}get type(){return 12}get length(){return this.value.length}static fromData(t,i){let r=new Float64Array(i);for(let n=0;n{"use strict";Ce();Ie();De=class extends ne{constructor(t){super();typeof t=="number"?(this.value=new Uint32Array(1),this.value[0]=t):this.value=t}get type(){return 4}get length(){return this.value.length}static fromData(t,i){let r=new Uint32Array(i);for(let n=0;n{"use strict";Ce();Ie();vt();Me=class extends ne{constructor(t){super();t instanceof se?this.value=[t]:this.value=t}get type(){return 5}get length(){return this.value.length}static fromData(t,i){let r=new Array;for(let n=0;n{"use strict";Ce();Ie();tt=class extends ne{constructor(t){super();typeof t=="number"?(this.value=new Int8Array(1),this.value[0]=t):this.value=t}get type(){return 6}get length(){return this.value.length}static fromData(t,i,r){let n=new Int8Array(new Int8Array(t.toUint8Array(i,r).buffer));return new tt(n)}toInt(t=0){return this.value[t]}toData(){return new Uint8Array(this.value.buffer)}toString(){return this.value.length===1?`${this.value[0]}`:`${this.value}`}write(t){t.writeBytes(new Uint8Array(this.value.buffer))}setInt(t,i=0){this.value[i]=t}equalsTo(t){return t instanceof tt&&this.length===t.length}clone(){return new tt(this.value)}}});var Oe,ni=C(()=>{"use strict";Ce();Ie();Oe=class extends ne{constructor(t){super();typeof t=="number"?(this.value=new Uint16Array(1),this.value[0]=t):this.value=t}get type(){return 3}get length(){return this.value.length}static fromData(t,i){let r=new Uint16Array(i);for(let n=0;n{"use strict";Ce();Ie();it=class extends ne{constructor(t){super();typeof t=="number"?(this.value=new Float32Array(1),this.value[0]=t):this.value=t}get type(){return 11}get length(){return this.value.length}static fromData(t,i){let r=new Float32Array(i);for(let n=0;n{"use strict";Ce();Ie();je();rt=class extends ne{constructor(t){super();typeof t=="number"?(this.value=new Int32Array(1),this.value[0]=t):this.value=t}get type(){return 9}get length(){return this.value.length}static fromData(t,i){let r=new Int32Array(i);for(let n=0;n{"use strict";Ce();Ie();je();vt();Le=class extends ne{constructor(t){super();t instanceof se?this.value=[t]:this.value=t}get type(){return 10}get length(){return this.value.length}static fromData(t,i){let r=new Array;for(let n=0;n{"use strict";Ce();Ie();nt=class extends ne{constructor(t){super();typeof t=="number"?(this.value=new Int16Array(1),this.value[0]=t):this.value=t}get type(){return 8}get length(){return this.value.length}static fromData(t,i){let r=new Int16Array(i);for(let n=0;n{"use strict";Ce();Ie();lt=class extends ne{constructor(t){super();typeof t=="number"?(this.value=new Uint8Array(1),this.value[0]=t):this.value=t}get type(){return 7}get length(){return this.value.length}static fromData(t,i,r){let n=new Uint8Array(t.toUint8Array(i,r));return new lt(n)}toData(){return this.value}toString(){return""}write(t){t.writeBytes(this.value)}equalsTo(t){return t instanceof lt&&this.length===t.length}clone(){return new lt(this.value)}}});var _t,Kt=C(()=>{"use strict";vt();$t();jt();Ie();Qt();Jt();ei();ti();ii();ri();ni();si();ai();oi();ui();li();Ce();_t=class{constructor(){this.data=new Map;this._sub=new yt}get sub(){return this._sub}get keys(){return this.data.keys()}get values(){return this.data.values()}get size(){return this.data.size}get isEmpty(){return this.data.size===0&&this._sub.isEmpty}get hasImageDescription(){return this.data.has(270)}get imageDescription(){var e;return(e=this.data.get(270))==null?void 0:e.toString()}set imageDescription(e){e===void 0?this.data.delete(270):this.data.set(270,new Ee(e))}get hasMake(){return this.data.has(271)}get make(){var e;return(e=this.data.get(271))==null?void 0:e.toString()}set make(e){e===void 0?this.data.delete(271):this.data.set(271,new Ee(e))}get hasModel(){return this.data.has(272)}get model(){var e;return(e=this.data.get(272))==null?void 0:e.toString()}set model(e){e===void 0?this.data.delete(272):this.data.set(272,new Ee(e))}get hasOrientation(){return this.data.has(274)}get orientation(){var e;return(e=this.data.get(274))==null?void 0:e.toInt()}set orientation(e){e===void 0?this.data.delete(274):this.data.set(274,new Oe(e))}get hasResolutionX(){return this.data.has(282)}get resolutionX(){var e;return(e=this.data.get(282))==null?void 0:e.toRational()}set resolutionX(e){this.setRational(282,e)||this.data.delete(282)}get hasResolutionY(){return this.data.has(283)}get resolutionY(){var e;return(e=this.data.get(283))==null?void 0:e.toRational()}set resolutionY(e){this.setRational(283,e)||this.data.delete(283)}get hasResolutionUnit(){return this.data.has(296)}get resolutionUnit(){var e;return(e=this.data.get(296))==null?void 0:e.toInt()}set resolutionUnit(e){e===void 0?this.data.delete(296):this.data.set(296,new Oe(Math.trunc(e)))}get hasImageWidth(){return this.data.has(256)}get imageWidth(){var e;return(e=this.data.get(256))==null?void 0:e.toInt()}set imageWidth(e){e===void 0?this.data.delete(256):this.data.set(256,new Oe(Math.trunc(e)))}get hasImageHeight(){return this.data.has(257)}get imageHeight(){var e;return(e=this.data.get(257))==null?void 0:e.toInt()}set imageHeight(e){e===void 0?this.data.delete(257):this.data.set(257,new Oe(Math.trunc(e)))}get hasSoftware(){return this.data.has(305)}get software(){var e;return(e=this.data.get(305))==null?void 0:e.toString()}set software(e){e===void 0?this.data.delete(305):this.data.set(305,new Ee(e))}get hasCopyright(){return this.data.has(33432)}get copyright(){var e;return(e=this.data.get(33432))==null?void 0:e.toString()}set copyright(e){e===void 0?this.data.delete(33432):this.data.set(33432,new Ee(e))}setRational(e,t){if(t instanceof se)return this.data.set(e,Me.from(t)),!0;if(Array.isArray(t)&&t.every(i=>typeof i=="number")&&t.length===2){let i=new se(t[0],t[1]);return this.data.set(e,Me.from(i)),!0}return!1}static isArrayOfRationalNumbers(e){return Array.isArray(e)&&e.every(t=>Array.isArray(t)&&t.length>=2&&t.every(i=>typeof i=="number"))}has(e){return this.data.has(e)}getValue(e){let t=e;if(typeof t=="string"&&(t=Nr.get(t)),typeof t=="number")return this.data.get(t)}setValue(e,t){let i=e;if(typeof i=="string"&&(i=Nr.get(i)),typeof i=="number")if(t===void 0)this.data.delete(i);else if(t instanceof ne)this.data.set(i,t);else{let r=Fi.get(i);if(r!==void 0){let n=r.type,s=r.count;switch(n){case 1:Array.isArray(t)&&t.length===s&&t.every(a=>typeof a=="number")?this.data.set(i,new Je(new Uint8Array(t))):typeof t=="number"&&s===1&&this.data.set(i,new Je(t));break;case 2:typeof t=="string"&&this.data.set(i,new Ee(t));break;case 3:Array.isArray(t)&&t.length===s&&t.every(a=>typeof a=="number")?this.data.set(i,new Oe(new Uint16Array(t))):typeof t=="number"&&s===1&&this.data.set(i,new Oe(t));break;case 4:Array.isArray(t)&&t.length===s&&t.every(a=>typeof a=="number")?this.data.set(i,new De(new Uint32Array(t))):typeof t=="number"&&s===1&&this.data.set(i,new De(t));break;case 5:if(Array.isArray(t)&&t.length===s&&t.every(a=>a instanceof se))this.data.set(i,new Me(t));else if(s===1&&Array.isArray(t)&&t.length===2&&t.every(a=>typeof a=="number")){let a=new se(t[0],t[1]);this.data.set(i,new Me(a))}else if(s===1&&t instanceof se)this.data.set(i,new Me(t));else if(Array.isArray(t)&&t.length===s&&t.every(a=>Array.isArray(a)&&a.length>=2&&a.every(o=>typeof o=="number"))){let a=new Array;for(let o=0;o=2&&u.every(l=>typeof l=="number")&&a.push(new se(u[0],u[1]))}this.data.set(i,new Me(a))}break;case 6:Array.isArray(t)&&t.length===s&&t.every(a=>typeof a=="number")?this.data.set(i,new tt(new Int8Array(t))):typeof t=="number"&&s===1&&this.data.set(i,new tt(t));break;case 7:Array.isArray(t)&&t.every(a=>typeof a=="number")&&this.data.set(i,new lt(new Uint8Array(t)));break;case 8:Array.isArray(t)&&t.length===s&&t.every(a=>typeof a=="number")?this.data.set(i,new nt(new Int16Array(t))):typeof t=="number"&&s===1&&this.data.set(i,new nt(t));break;case 9:Array.isArray(t)&&t.length===s&&t.every(a=>typeof a=="number")?this.data.set(i,new rt(new Int32Array(t))):typeof t=="number"&&s===1&&this.data.set(i,new rt(t));break;case 10:if(Array.isArray(t)&&t.length===s&&t.every(a=>a instanceof se))this.data.set(i,new Le(t));else if(s===1&&Array.isArray(t)&&t.length===2&&t.every(a=>typeof a=="number")){let a=new se(t[0],t[1]);this.data.set(i,new Le(a))}else if(s===1&&t instanceof se)this.data.set(i,new Le(t));else if(Array.isArray(t)&&t.length===s&&t.every(a=>Array.isArray(a)&&a.length>=2&&a.every(o=>typeof o=="number"))){let a=new Array;for(let o=0;o=2&&u.every(l=>typeof l=="number")&&a.push(new se(u[0],u[1]))}this.data.set(i,new Le(a))}break;case 11:Array.isArray(t)&&t.length===s&&t.every(a=>typeof a=="number")?this.data.set(i,new it(new Float32Array(t))):typeof t=="number"&&s===1&&this.data.set(i,new it(t));break;case 12:Array.isArray(t)&&t.length===s&&t.every(a=>typeof a=="number")?this.data.set(i,new et(new Float64Array(t))):typeof t=="number"&&s===1&&this.data.set(i,new et(t));break;case 0:break}}}}}});var Ae,wt=C(()=>{"use strict";Ui();Kt();$t();jt();Ie();Qt();Jt();ei();ti();ii();ri();ni();si();ai();oi();ui();li();Ae=class extends yt{get imageIfd(){return this.get("ifd0")}get thumbnailIfd(){return this.get("ifd1")}get exifIfd(){return this.get("ifd0").sub.get("exif")}get gpsIfd(){return this.get("ifd0").sub.get("gps")}get interopIfd(){return this.get("ifd0").sub.get("interop")}writeDirectory(e,t,i){let r=i;e.writeUint16(t.size);for(let n of t.keys){let s=t.getValue(n);e.writeUint16(n),e.writeUint16(s.type),e.writeUint32(s.length);let a=s.dataSize;if(a<=4)for(s.write(e);a<4;)e.writeByte(0),a++;else e.writeUint32(r),r+=a}return r}writeDirectoryLargeValues(e,t){for(let i of t.values)i.dataSize>4&&i.write(e)}readEntry(e,t){let i=e.readUint16(),r=e.readUint16(),n=e.readUint32(),s=new Oi(i,void 0);if(r>Object.keys(ve).length)return s;let a=r,o=Lr[r],u=n*o,l=e.offset+4;if(u>4){let f=e.readUint32();e.offset=f+t}if(e.offset+u>e.end)return s;let h=e.readBytes(u);switch(a){case 0:break;case 6:s.value=tt.fromData(h,n);break;case 1:s.value=Je.fromData(h,n);break;case 7:s.value=lt.fromData(h,n);break;case 2:s.value=Ee.fromData(h,n);break;case 3:s.value=Oe.fromData(h,n);break;case 4:s.value=De.fromData(h,n);break;case 5:s.value=Me.fromData(h,n);break;case 10:s.value=Le.fromData(h,n);break;case 8:s.value=nt.fromData(h,n);break;case 9:s.value=rt.fromData(h,n);break;case 11:s.value=it.fromData(h,n);break;case 12:s.value=et.fromData(h,n);break}return e.offset=l,s}static from(e){return new Ae(e.directories)}static fromInputBuffer(e){let t=new Ae;return t.read(e),t}hasTag(e){for(let t of this.directories.values())if(t.has(e))return!0;return!1}getTag(e){for(let t of this.directories.values())if(t.has(e))return t.getValue(e)}getTagName(e){var t,i;return(i=(t=Fi.get(e))==null?void 0:t.name)!=null?i:""}write(e){let t=e.bigEndian;e.bigEndian=!0,e.writeUint16(19789),e.writeUint16(42),e.writeUint32(8),this.directories.get("ifd0")===void 0&&this.directories.set("ifd0",new _t);let i=8,r=new Map;for(let[s,a]of this.directories){r.set(s,i),a.sub.has("exif")?a.setValue(34665,new De(0)):a.setValue(34665,void 0),a.sub.has("interop")?a.setValue(40965,new De(0)):a.setValue(40965,void 0),a.sub.has("gps")?a.setValue(34853,new De(0)):a.setValue(34853,void 0),i+=2+12*a.size+4;for(let o of a.values){let u=o.dataSize;u>4&&(i+=u)}for(let o of a.sub.keys){let u=a.sub.get(o);r.set(o,i);let l=2+12*u.size;for(let h of u.values){let f=h.dataSize;f>4&&(l+=f)}i+=l}}let n=Array.from(this.directories);for(let s=0;s0;){e.offset=i+n;let o=new _t,u=e.readUint16(),l=new Array;for(let h=0;h{"use strict";ut();Ve();zt();Ht();Ci();ue();Zt();ge();wt();W=class{constructor(e){this._xOffset=0;this._yOffset=0;this._duration=0;this._disposeMethod=1;this._blendMethod=1;var t,i;this._width=e.width,this._height=e.height,this._rgbChannelSet=(t=e.rgbChannelSet)!=null?t:1,this._exifData=e.exifData!==void 0?Ae.from(e.exifData):new Ae,this._iccProfile=e.iccProfile,this._textData=e.textData,this._data=(i=e.data)!=null?i:new Uint32Array(e.width*e.height)}get data(){return this._data}get xOffset(){return this._xOffset}get yOffset(){return this._yOffset}set duration(e){this._duration=e}get duration(){return this._duration}get disposeMethod(){return this._disposeMethod}get blendMethod(){return this._blendMethod}get rgbChannelSet(){return this._rgbChannelSet}get exifData(){return this._exifData}set exifData(e){this._exifData=e}set iccProfile(e){this._iccProfile=e}get iccProfile(){return this._iccProfile}get textData(){return this._textData}get width(){return this._width}get height(){return this._height}get numberOfChannels(){return this.rgbChannelSet===1?4:3}get length(){return this.data.length}static convertData(e,t,i,r){if(r===2)return i instanceof Uint32Array?te.copyUint32(i):te.copyUint32(new Uint32Array(i.buffer));let n=i instanceof Uint32Array?new Uint8Array(i.buffer):i,s=new Uint32Array(e*t),a=new Uint8Array(s.buffer);switch(r){case 3:for(let o=0,u=n.length;o=0&&e=0&&t=0?0:1),r=i+1,n=Math.trunc(t)-(t>=0?0:1),s=n+1,a=e-i,o=t-n,u=(p,g,b,x)=>Math.trunc(p+a*(g-p+o*(p+x-b-g))+o*(b-p)),l=this.getPixelSafe(i,n),h=s>=this._height?l:this.getPixelSafe(i,s),f=r>=this._width?l:this.getPixelSafe(r,n),c=r>=this._width||s>=this._height?l:this.getPixelSafe(r,s);return d.getColor(u(d.getRed(l),d.getRed(f),d.getRed(h),d.getRed(c)),u(d.getGreen(l),d.getGreen(f),d.getGreen(h),d.getGreen(c)),u(d.getBlue(l),d.getBlue(f),d.getBlue(h),d.getBlue(c)),u(d.getAlpha(l),d.getAlpha(f),d.getAlpha(h),d.getAlpha(c)))}getPixelCubic(e,t){let i=Math.trunc(e)-(e>=0?0:1),r=i-1,n=i+1,s=i+2,a=Math.trunc(t)-(t>=0?0:1),o=a-1,u=a+1,l=a+2,h=e-i,f=t-a,c=(Bt,mt,Gn,Hn,ls)=>Gn+.5*(Bt*(-mt+Hn)+(Bt*(Bt*(2*mt))-5*Gn+4*Hn-ls)+Bt*(Bt*(Bt*(-mt+3*Gn-3*Hn+ls)))),p=this.getPixelSafe(i,a),g=r<0||o<0?p:this.getPixelSafe(r,o),b=r<0?p:this.getPixelSafe(i,o),x=o<0||n>=this._width?p:this.getPixelSafe(n,o),y=s>=this._width||o<0?p:this.getPixelSafe(s,o),P=c(h,d.getRed(g),d.getRed(b),d.getRed(x),d.getRed(y)),w=c(h,d.getGreen(g),d.getGreen(b),d.getGreen(x),d.getGreen(y)),M=c(h,d.getBlue(g),d.getBlue(b),d.getBlue(x),d.getBlue(y)),B=c(h,d.getAlpha(g),d.getAlpha(b),d.getAlpha(x),d.getAlpha(y)),O=r<0?p:this.getPixelSafe(r,a),R=n>=this._width?p:this.getPixelSafe(n,a),N=s>=this._width?p:this.getPixelSafe(s,a),L=c(h,d.getRed(O),d.getRed(p),d.getRed(R),d.getRed(N)),D=c(h,d.getGreen(O),d.getGreen(p),d.getGreen(R),d.getGreen(N)),k=c(h,d.getBlue(O),d.getBlue(p),d.getBlue(R),d.getBlue(N)),Y=c(h,d.getAlpha(O),d.getAlpha(p),d.getAlpha(R),d.getAlpha(N)),Z=r<0||u>=this._height?p:this.getPixelSafe(r,u),j=u>=this._height?p:this.getPixelSafe(i,u),X=n>=this._width||u>=this._height?p:this.getPixelSafe(n,u),$=s>=this._width||u>=this._height?p:this.getPixelSafe(s,u),Ge=c(h,d.getRed(Z),d.getRed(j),d.getRed(X),d.getRed($)),Re=c(h,d.getGreen(Z),d.getGreen(j),d.getGreen(X),d.getGreen($)),be=c(h,d.getBlue(Z),d.getBlue(j),d.getBlue(X),d.getBlue($)),ee=c(h,d.getAlpha(Z),d.getAlpha(j),d.getAlpha(X),d.getAlpha($)),H=r<0||l>=this._height?p:this.getPixelSafe(r,l),Q=l>=this._height?p:this.getPixelSafe(i,l),Be=n>=this._width||l>=this._height?p:this.getPixelSafe(n,l),we=s>=this._width||l>=this._height?p:this.getPixelSafe(s,l),Te=c(h,d.getRed(H),d.getRed(Q),d.getRed(Be),d.getRed(we)),Xr=c(h,d.getGreen(H),d.getGreen(Q),d.getGreen(Be),d.getGreen(we)),qr=c(h,d.getBlue(H),d.getBlue(Q),d.getBlue(Be),d.getBlue(we)),Zr=c(h,d.getAlpha(H),d.getAlpha(Q),d.getAlpha(Be),d.getAlpha(we)),me=c(f,P,L,Ge,Te),_n=c(f,w,D,Re,Xr),wn=c(f,M,k,be,qr),In=c(f,B,Y,ee,Zr);return d.getColor(Math.trunc(me),Math.trunc(_n),Math.trunc(wn),Math.trunc(In))}setPixel(e,t,i){let r=this.getBufferIndex(e,t);this._data[r]=i}setPixelSafe(e,t,i){if(this.boundsSafe(e,t)){let r=this.getBufferIndex(e,t);this._data[r]=i}}setPixelRgba(e,t,i,r,n,s=255){let a=this.getBufferIndex(e,t);this._data[a]=d.getColor(i,r,n,s)}getWhiteBalance(e=!1){let t=this._data.length,i=0,r=0,n=0,s=1;for(let o=0;ot&&(t=n),st&&(t=s),at&&(t=a),this.rgbChannelSet===1){let o=d.getAlpha(r);ot&&(t=o)}}return{min:e,max:t}}addTextData(e){this._textData===void 0&&(this._textData=new Map);for(let[t,i]of e)this._textData.set(t,i)}}});var J,le,hi=C(()=>{"use strict";ge();J=class{constructor(e,t=256,i=10){this.netIndex=new Int32Array(256);this.netSize=16;this.specials=3;this.bgColor=0;this.cutNetSize=0;this.maxNetPos=0;this.initRadius=0;this.initBiasRadius=0;this.samplingFactor=i,this.initialize(t),this.addImage(e)}get colorMap8(){return this._colorMap8}get colorMap32(){return this._colorMap32}get numColors(){return this.netSize}initialize(e){this.netSize=Math.max(e,4),this.cutNetSize=this.netSize-this.specials,this.maxNetPos=this.netSize-1,this.initRadius=Math.floor(this.netSize/8),this.initBiasRadius=this.initRadius*J.radiusBias,this._colorMap32=new Int32Array(this.netSize*4),this._colorMap8=new Uint8Array(this.netSize*3),this.specials=3,this.bgColor=this.specials-1,this.radiusPower=new Int32Array(this.netSize>>3),this.network=new Array(this.netSize*3).fill(0),this.bias=new Array(this.netSize).fill(0),this.freq=new Array(this.netSize).fill(0),this.network[0]=0,this.network[1]=0,this.network[2]=0,this.network[3]=255,this.network[4]=255,this.network[5]=255;let t=1/this.netSize;for(let i=0;ithis.netSize&&(o=this.netSize);let u=i+1,l=i-1,h=1;for(;ua;){let f=this.radiusPower[h++];if(ua){let c=l*3;this.network[c]-=f*(this.network[c]-r)/J.alphaRadiusBias,this.network[c+1]-=f*(this.network[c+1]-n)/J.alphaRadiusBias,this.network[c+2]-=f*(this.network[c+2]-s)/J.alphaRadiusBias,l--}}}learn(e){let t=this.initBiasRadius,i=30+Math.floor((this.samplingFactor-1)/3),r=e.length,n=Math.floor(r/this.samplingFactor),s=Math.max(Math.floor(n/J.numCycles),1),a=J.initAlpha;s===0&&(s=1);let o=t>>J.radiusBiasShift;o<=1&&(o=0),this.updateRadiusPower(o,a);let u=0,l=0;r=this.specials){let x=Number(a)/J.initAlpha;this.alterSingle(x,b,g,p,c),o>0&&this.alterNeighbors(x,o,b,g,p,c)}for(l+=u;l>=r;)l-=r;h++,h%s===0&&(a-=Math.floor(a/i),t-=Math.floor(t/J.radiusDec),o=t>>J.radiusBiasShift,o<=1&&(o=0),this.updateRadiusPower(o,a))}}fix(){for(let e=0,t=0,i=0;e255&&(n=255),this._colorMap32[i+r]=n}this._colorMap32[i+3]=e}}inxBuild(){let e=0,t=0;for(let i=0,r=0;i>1;for(let o=e+1;o>1;for(let i=e+1;i<256;i++)this.netIndex[i]=this.maxNetPos}copyColorMap(){for(let e=0,t=0,i=0;e=0;){if(s=r)s=this.netSize;else{u<0&&(u=-u);let l=this._colorMap32[o]-e;l<0&&(l=-l),u+=l,u=0){let o=a*4,u=t-this._colorMap32[o+1];if(u>=r)a=-1;else{u<0&&(u=-u);let l=this._colorMap32[o]-e;l<0&&(l=-l),u+=l,u{"use strict";fi=class{constructor(e,t,i){this._r=0;this._g=0;this._b=0;this._count=0;this._heapIndex=0;this._children=new Array(8).fill(void 0);this._childCount=0;this._childIndex=0;this._flags=0;this._depth=0;this._childIndex=e,this._depth=t,this._parent=i,i!==void 0&&i._childCount++}get r(){return this._r}set r(e){this._r=e}get g(){return this._g}set g(e){this._g=e}get b(){return this._b}set b(e){this._b=e}get count(){return this._count}set count(e){this._count=e}get heapIndex(){return this._heapIndex}set heapIndex(e){this._heapIndex=e}get parent(){return this._parent}get children(){return this._children}get childCount(){return this._childCount}set childCount(e){this._childCount=e}get childIndex(){return this._childIndex}get flags(){return this._flags}set flags(e){this._flags=e}get depth(){return this._depth}}});var On,ci,Di=C(()=>{"use strict";ge();Ti();Ri();On=class{constructor(e,t=256){this.root=new fi(0,0);let i=new Bi;for(let n=0;nr;)this.heapAdd(i,this.nodeFold(this.popHeap(i)));for(let n=1;n>=1){let o=((i&a)!==0?1:0)*4+((t&a)!==0?1:0)*2+((r&a)!==0?1:0);n.children[o]===void 0&&(n.children[o]=new fi(o,s,n)),n=n.children[o]}return n.r+=t,n.g+=i,n.b+=r,n.count++,n}popHeap(e){if(e.n<=1)return;let t=e.buf[1];return e.buf[1]=e.buf.pop(),e.buf[1].heapIndex=1,this.downHeap(e,e.buf[1]),t}heapAdd(e,t){if((t.flags&On.ON_INHEAP)!==0){this.downHeap(e,t),this.upHeap(e,t);return}t.flags|=On.ON_INHEAP,t.heapIndex=e.n,e.buf.push(t),this.upHeap(e,t)}downHeap(e,t){let i=t.heapIndex;for(;;){let r=i*2;if(r>=e.n||(r+10&&r++,this.compareNode(t,e.buf[r])<=0))break;e.buf[i]=e.buf[r],e.buf[i].heapIndex=i,i=r}e.buf[i]=t,t.heapIndex=i}upHeap(e,t){let i=t.heapIndex,r;for(;i>1&&(r=e.buf[Math.trunc(i/2)],!(this.compareNode(t,r)>=0));)e.buf[i]=r,r.heapIndex=i,i=Math.trunc(i/2);e.buf[i]=t,t.heapIndex=i}nodeFold(e){if(e.childCount>0)return;let t=e.parent;return t.count+=e.count,t.r+=e.r,t.g+=e.g,t.b+=e.b,t.childCount--,t.children[e.childIndex]=void 0,t}compareNode(e,t){if(e.childCountt.childCount)return 1;let i=e.count>>e.depth,r=t.count>>t.depth;return ir?1:0}getQuantizedColor(e){let t=d.getRed(e),i=d.getGreen(e),r=d.getBlue(e),n=this.root;for(let s=1<<7;s!==0;s>>=1){let a=((i&s)!==0?1:0)*4+((t&s)!==0?1:0)*2+((r&s)!==0?1:0);if(n.children[a]===void 0)break;n=n.children[a]}return t=n.r,i=n.g,r=n.b,d.getColor(t,i,r)}},ci=On;ci.ON_INHEAP=1});var jr,he,st=C(()=>{"use strict";ut();jr=class{get buffer(){return this._buffer}get bigEndian(){return this._bigEndian}set bigEndian(e){this._bigEndian=e}get length(){return this._length}set length(e){this._length=e}constructor(e){var t,i;this._bigEndian=(t=e==null?void 0:e.bigEndian)!=null?t:!1,this._buffer=new Uint8Array((i=e==null?void 0:e.size)!=null?i:jr.BLOCK_SIZE),this._length=0}expandBuffer(e){let t=jr.BLOCK_SIZE;e!==void 0?t=e:this._buffer.length>0&&(t=this._buffer.length*2);let i=new Uint8Array(this._buffer.length+t);te.setRange(i,0,this._buffer.length,this._buffer),this._buffer=i}rewind(){this._length=0}clear(){this._buffer=new Uint8Array(jr.BLOCK_SIZE),this._length=0}getBytes(){return new Uint8Array(this._buffer.buffer,0,this._length)}writeByte(e){this._length===this._buffer.length&&this.expandBuffer(),this._buffer[this._length++]=e&255}writeBytes(e,t){let i=t!=null?t:e.length;for(;this._length+i>this._buffer.length;)this.expandBuffer(this._length+i-this._buffer.length);te.setRange(this._buffer,this._length,this._length+i,e),this._length+=i}writeBuffer(e){for(;length+e.length>this._buffer.length;)this.expandBuffer(length+e.length-this._buffer.length);te.setRange(this._buffer,length,length+e.length,e.buffer,e.offset),this._length+=e.length}writeUint16(e){if(this._bigEndian){this.writeByte(e>>8&255),this.writeByte(e&255);return}this.writeByte(e&255),this.writeByte(e>>8&255)}writeUint32(e){if(this._bigEndian){this.writeByte(e>>24&255),this.writeByte(e>>16&255),this.writeByte(e>>8&255),this.writeByte(e&255);return}this.writeByte(e&255),this.writeByte(e>>8&255),this.writeByte(e>>16&255),this.writeByte(e>>24&255)}writeFloat32(e){let t=new Float32Array(1);t[0]=e;let i=new Uint8Array(t.buffer);if(this._bigEndian){this.writeByte(i[3]),this.writeByte(i[2]),this.writeByte(i[1]),this.writeByte(i[0]);return}this.writeByte(i[0]),this.writeByte(i[1]),this.writeByte(i[2]),this.writeByte(i[3])}writeFloat64(e){let t=new Float64Array(1);t[0]=e;let i=new Uint8Array(t.buffer);if(this._bigEndian){this.writeByte(i[7]),this.writeByte(i[6]),this.writeByte(i[5]),this.writeByte(i[4]),this.writeByte(i[3]),this.writeByte(i[2]),this.writeByte(i[1]),this.writeByte(i[0]);return}this.writeByte(i[0]),this.writeByte(i[1]),this.writeByte(i[2]),this.writeByte(i[3]),this.writeByte(i[4]),this.writeByte(i[5]),this.writeByte(i[6]),this.writeByte(i[7])}subarray(e,t){let i=e>=0?e:this._length+e,r=t!=null?t:this._length;return r<0&&(r=this._length+r),new Uint8Array(this._buffer.buffer,i,r-i)}},he=jr;he.BLOCK_SIZE=8192});var z,di=C(()=>{"use strict";z=class{get x(){return this._x}get y(){return this._y}get xt(){return Math.trunc(this.x)}get yt(){return Math.trunc(this.y)}constructor(e,t){this._x=e,this._y=t}static from(e){return new z(e._x,e._y)}move(e,t){return this._x=e,this._y=t,this}offset(e,t){return this.move(this._x+e,this._y+t)}mul(e){return this.move(this._x*e,this._y*e)}add(e){return this.move(this._x+e.x,this._y+e.y)}equals(e){return e instanceof z&&this._x===e._x&&this._y===e._y}}});var Qr=C(()=>{"use strict"});var xe,Li=C(()=>{"use strict";xe=class{static crand(){return 1-2*Math.random()}static grand(){let e=0,t=0;do{let i=2*Math.random()-1;e=2*Math.random()-1,t=e*e+i*i}while(t<=0||t>=1);return e*Math.sqrt(-2*Math.log(t)/t)}static prand(e){if(e<=1e-10)return 0;if(e>100)return Math.trunc(Math.sqrt(e)*xe.grand()+e);let t=0,i=Math.exp(-e);for(let r=1;r>=i;++t)r*=Math.random();return t-1}}});var at,Et=C(()=>{"use strict";at=class{constructor(e,t,i,r){this._left=0;this._top=0;this._right=0;this._bottom=0;this._width=0;this._height=0;this.initialize(e,t,i,r)}get left(){return this._left}get top(){return this._top}get right(){return this._right}get bottom(){return this._bottom}get width(){return this._width}get height(){return this._height}static fromXYWH(e,t,i,r){return new at(e,t,e+i,t+r)}static from(e){return new at(e.left,e.top,e.right,e.bottom)}initialize(e,t,i,r){this._left=Math.min(e,i),this._top=Math.min(t,r),this._right=Math.max(e,i),this._bottom=Math.max(t,r),this._width=this._right-this._left,this._height=this._bottom-this._top}}});var Jr=C(()=>{"use strict"});var en=C(()=>{"use strict"});var tn=C(()=>{"use strict"});var V,Ze,mi=C(()=>{"use strict";ge();Ei();Qe();di();Et();V=class{static calculateCircumference(e,t,i){if(i<0||t.x+i<0||t.x-i>=e.width||t.y+i<0||t.y-i>=e.height)return[];if(i===0)return[t];let r=[new z(t.x-i,t.y),new z(t.x+i,t.y),new z(t.x,t.y-i),new z(t.x,t.y+i)];if(i===1)return r;for(let n=1-i,s=0,a=-(i<<1),o=0,u=i;o=0&&(a+=2,n+=a,--u),++o,s+=2,n+=s+1,o!==u+1){let l=t.x-u,h=t.x+u,f=t.y-o,c=t.y+o,p=t.x-o,g=t.x+o,b=t.y-u,x=t.y+u;r.push(new z(l,f)),r.push(new z(l,c)),r.push(new z(h,f)),r.push(new z(h,c)),o!==u&&(r.push(new z(p,b)),r.push(new z(g,x)),r.push(new z(g,b)),r.push(new z(p,x)))}return r}static computeOutCode(e,t){let i=V.OUTCODE_INSIDE;return t.xe.right&&(i|=V.OUTCODE_RIGHT),t.ye.bottom&&(i|=V.OUTCODE_BOTTOM),i}static clipLine(e,t){let i=e.left,r=e.top,n=e.right,s=e.bottom,a=V.computeOutCode(e,new z(t.startX,t.startY)),o=V.computeOutCode(e,new z(t.endX,t.endY)),u=!1;for(;;)if((a|o)===0){u=!0;break}else{if((a&o)!==0)break;{let l=a!==0?a:o,h=0,f=0;(l&V.OUTCODE_TOP)!==0?(h=t.startX+Math.trunc(t.dx*(r-t.startY)/t.dy),f=r):(l&V.OUTCODE_BOTTOM)!==0?(h=t.startX+Math.trunc(t.dx*(s-t.startY)/t.dy),f=s):(l&V.OUTCODE_RIGHT)!==0?(f=t.startY+Math.trunc(t.dy*(n-t.startX)/t.dx),h=n):(l&V.OUTCODE_LEFT)!==0&&(f=t.startY+Math.trunc(t.dy*(i-t.startX)/t.dx),h=i),l===a?(t.moveStart(h,f),a=V.computeOutCode(e,new z(t.startX,t.startY))):(t.moveEnd(h,f),o=V.computeOutCode(e,new z(t.endX,t.endY)))}}return u}static testPixelLabColorDistance(e,t,i,r,n){let s=e.getPixel(t,i),a=r.length>3,o=d.rgbToLab(d.getRed(s),d.getGreen(s),d.getBlue(s));return a&&o.push(d.getAlpha(s)),d.distance(o,r,a)>n}static fill4(e,t,i,r,n,s){let a=t,o=i;if(s[o*e.width+a]!==1){for(;;){let u=a,l=o;for(;o!==0&&!r(o-1,a);)o--;for(;a!==0&&!r(o,a-1);)a--;if(a===u&&o===l)break}V.fill4Core(e,a,o,r,n,s)}}static fill4Core(e,t,i,r,n,s){let a=t,o=i;if(s[o*e.width+a]===1)return;let u=0;do{let l=0,h=a;if(u!==0&&r(o,a)){do if(--u===0)return;while(r(o,++a));h=a}else for(;a!==0&&!r(o,a-1);l++,u++)n(o,--a),o!==0&&!r(o-1,a)&&V.fill4(e,a,o-1,r,n,s);for(;hu&&o!==0)for(let f=a+u;++fs.x===a.x?s.y-a.y:s.x-a.x),n.length>0){let s=n[0],a=n[0];for(let o=1;o~l+65536&65535;if(!e.antialias){if(t.dy<=t.dx){let l=Math.cos(Math.atan2(t.dy,t.dx)),h=0;l!==0?h=Math.trunc(r/l):h=1,h===0&&(h=1);let f=2*t.dy-t.dx,c=2*t.dy,p=2*(t.dy-t.dx),g=t.startX,b=t.startY,x=Math.trunc(b-h/2);for(let y=x;y0)for(;g0)for(;bt.dy){let l=t.startY,h=Math.trunc(t.dy*65536/t.dx),f=0;for(let c=t.startX;c<=t.endX;c++){let p=l-Math.trunc(o/2);for(let g=p;g>8&255),b.offset(0,1),V.drawPixel(e.image,b,e.color,s(f)>>8&255)}f+=h,f>=65536?(f-=65536,l++):f<0&&(f+=65536,l--)}}else{let l=t.startX,h=Math.trunc(t.dx*65536/t.dy),f=0;for(let c=t.startY;c<=t.endY;c++){let p=l-Math.trunc(o/2);for(let g=p;g>8&255),b.offset(1,0),V.drawPixel(e.image,b,e.color,s(f)>>8&255)}f+=h,f>=65536?(f-=65536,l++):f<0&&(f+=65536,l--)}}return e.image}static drawPixel(e,t,i,r=255){if(e.boundsSafe(t.xt,t.yt)){let n=e.getBufferIndex(t.xt,t.yt),s=e.getPixelByIndex(n);e.setPixelByIndex(n,d.alphaBlendColors(s,i,r))}return e}static drawRect(e,t,i){return V.drawLine({image:e,line:new qe(t.left,t.top,t.right,t.top),color:i}),V.drawLine({image:e,line:new qe(t.right,t.top,t.right,t.bottom),color:i}),V.drawLine({image:e,line:new qe(t.right,t.bottom,t.left,t.bottom),color:i}),V.drawLine({image:e,line:new qe(t.left,t.bottom,t.left,t.top),color:i}),e}static fillFlood(e){var o,u;let t=(o=e.threshold)!=null?o:0,i=(u=e.compareAlpha)!=null?u:!1,r=new Uint8Array(e.src.width*e.src.height),n=e.src.getPixel(e.x,e.y);i||(n=d.setAlpha(n,0));let s;if(t>0){let l=d.rgbToLab(d.getRed(n),d.getGreen(n),d.getBlue(n));i&&l.push(d.getAlpha(n)),s=(h,f)=>r[h*e.src.width+f]===0&&V.testPixelLabColorDistance(e.src,f,h,l,t)}else i?s=(l,h)=>r[l*e.src.width+h]===0&&e.src.getPixel(h,l)!==n:s=(l,h)=>r[l*e.src.width+h]===0&&d.setAlpha(e.src.getPixel(h,l),0)!==n;let a=(l,h)=>{e.src.setPixel(h,l,e.color),r[l*e.src.width+h]=1};return V.fill4(e.src,e.x,e.y,s,a,r),e.src}static maskFlood(e){var l,h,f;let t=(l=e.threshold)!=null?l:0,i=(h=e.compareAlpha)!=null?h:!1,r=(f=e.fillValue)!=null?f:255,n=new Uint8Array(e.src.width*e.src.height),s=e.src.getPixel(e.x,e.y);i||(s=d.setAlpha(s,0));let a=new Uint8Array(e.src.width*e.src.height),o;if(t>0){let c=d.rgbToLab(d.getRed(s),d.getGreen(s),d.getBlue(s));i&&c.push(d.getAlpha(s)),o=(p,g)=>n[p*e.src.width+g]===0&&(a[p*e.src.width+g]!==0||V.testPixelLabColorDistance(e.src,g,p,c,t))}else i?o=(c,p)=>n[c*e.src.width+p]===0&&(a[c*e.src.width+p]!==0||e.src.getPixel(p,c)!==s):o=(c,p)=>n[c*e.src.width+p]===0&&(a[c*e.src.width+p]!==0||d.setAlpha(e.src.getPixel(p,c),0)!==s);let u=(c,p)=>{a[c*e.src.width+p]=r,n[c*e.src.width+p]=1};return V.fill4(e.src,e.x,e.y,o,u,n),a}static fillRect(e,t,i){let r=F.clamp(t.left,0,e.width-1),n=F.clamp(t.top,0,e.height-1),s=F.clamp(t.right,0,e.width-1),a=F.clamp(t.bottom,0,e.height-1);if(d.getAlpha(i)===255){let o=e.width,u=n*o+r,l=u+(s-r)+1;for(let h=n;h<=a;++h)e.data.fill(i,u,l),u+=o,l+=o}else for(let o=n;o<=a;++o){let u=o*e.width+r;for(let l=r;l<=s;++l,++u)e.setPixelByIndex(u,d.alphaBlendColors(e.getPixelByIndex(u),i))}return e}static fill(e,t){return e.fill(t)}},Ze=V;Ze.OUTCODE_INSIDE=0,Ze.OUTCODE_LEFT=1,Ze.OUTCODE_RIGHT=2,Ze.OUTCODE_BOTTOM=4,Ze.OUTCODE_TOP=8});var rn=C(()=>{"use strict"});var nn=C(()=>{"use strict"});var Pt,Ot=C(()=>{"use strict";Pt=class extends Error{toString(){return this.message.length>0?`NotImplementedError: ${this.message}`:"NotImplementedError"}}});var sn=C(()=>{"use strict"});var an=C(()=>{"use strict"});var on=C(()=>{"use strict"});var Ni=C(()=>{"use strict"});var ki=C(()=>{"use strict"});var Gi=C(()=>{"use strict"});var Hi,Vi=C(()=>{"use strict";ge();Hi=class{get length(){return this.coefficients.length}constructor(e){this.size=e,this.coefficients=new Array(2*e+1).fill(0)}reflect(e,t){return t<0?-t:t>=e?e-(t-e)-1:t}applyCoeffsLine(e,t,i,r,n){for(let s=0;s255?255:a,o>255?255:o,u>255?255:u,l>255?255:l);n?t.setPixel(s,i,h):t.setPixel(i,s,h)}}getCoefficient(e){return this.coefficients[e]}setCoefficient(e,t){this.coefficients[e]=t}apply(e,t,i=!0){if(i)for(let r=0;r{"use strict";ge();Vt();Qe();Ye();hi();Di();Li();Et();mi();Ni();ki();Gi();Vi();St=class{static smoothVignetteStep(e,t,i){let r=i;return r=(r-e)/(t-e),r<0&&(r=0),r>1&&(r=1),r*r*(3-2*r)}static adjustColor(e){if(e.amount===0)return e.src;let t=e.contrast!==void 0?F.clamp(e.contrast,0,1):void 0,i=e.saturation!==void 0?F.clamp(e.saturation,0,1):void 0,r=e.brightness!==void 0?F.clamp(e.brightness,0,1):void 0,n=e.gamma!==void 0?F.clamp(e.gamma,0,1e3):void 0,s=e.exposure!==void 0?F.clamp(e.exposure,0,1e3):void 0,a=e.amount!==void 0?F.clamp(e.amount,0,1e3):void 0,o=.0174532925,u=.5,l=.5,h=.5,f=.2125,c=.7154,p=.0721,g=e.blacks!==void 0||e.whites!==void 0||e.mids!==void 0,b=0,x=0,y=0,P=0,w=0,M=0,B=0,O=0,R=0;g&&(b=e.blacks!==void 0?d.getRed(e.blacks)/255:0,x=e.blacks!==void 0?d.getGreen(e.blacks)/255:0,y=e.blacks!==void 0?d.getBlue(e.blacks)/255:0,P=e.whites!==void 0?d.getRed(e.whites)/255:1,w=e.whites!==void 0?d.getGreen(e.whites)/255:1,M=e.whites!==void 0?d.getBlue(e.whites)/255:1,B=e.mids!==void 0?d.getRed(e.mids)/255:.5,O=e.mids!==void 0?d.getGreen(e.mids)/255:.5,R=e.mids!==void 0?d.getBlue(e.mids)/255:.5,B=1/(1+2*(B-.5)),O=1/(1+2*(O-.5)),R=1/(1+2*(R-.5)));let N=i!==void 0?1-F.clamp(i,0,1):0,L=t!==void 0?1-F.clamp(t,0,1):0;s!==void 0&&(s=Math.pow(2,s));let D=0,k=0,Y=0;if(e.hue!==void 0){e.hue*=o;let X=Math.sin(e.hue),$=Math.cos(e.hue);D=2*$/3,k=(-Math.sqrt(3)*X-$)/3,Y=(Math.sqrt(3)*X-$+1)/3}let Z=a!==void 0?1-F.clamp(a,0,1):0,j=e.src.getBytes();for(let X=0,$=j.length;X<$;X+=4){let Ge=j[X]/255,Re=j[X+1]/255,be=j[X+2]/255,ee=Ge,H=Re,Q=be;if(g&&(ee=Math.pow((ee+b)*P,B),H=Math.pow((H+x)*w,O),Q=Math.pow((Q+y)*M,R)),r!==void 0&&r!==1){let Be=F.clamp(r,0,1e3);ee*=Be,H*=Be,Q*=Be}if(i!==void 0){let Be=ee*f+H*c+Q*p;ee=Be*N+ee*i,H=Be*N+H*i,Q=Be*N+Q*i}if(t!==void 0&&(ee=u*L+ee*t,H=l*L+H*t,Q=h*L+Q*t),n!==void 0&&(ee=Math.pow(ee,n),H=Math.pow(H,n),Q=Math.pow(Q,n)),s!==void 0&&(ee*=s,H*=s,Q*=s),e.hue!==void 0&&e.hue!==0){let Be=ee*D+H*k+Q*Y,we=ee*Y+H*D+Q*k,Te=ee*k+H*Y+Q*D;ee=Be,H=we,Q=Te}a!==void 0&&(ee=ee*a+Ge*Z,H=H*a+Re*Z,Q=Q*a+be*Z),j[X]=F.clampInt255(ee*255),j[X+1]=F.clampInt255(H*255),j[X+2]=F.clampInt255(Q*255)}return e.src}static brightness(e,t){if(t===0)return e;let i=e.getBytes();for(let r=0,n=i.length;r1&&(a/=u,o/=u);let l=Math.sqrt(1-a*a-o*o),h=a*.5+.5,f=o*.5+.5,c=l;i.setPixelRgba(n,r,Math.floor(255*h),Math.floor(255*f),Math.floor(255*c))}return i}static colorOffset(e){var i,r,n,s;let t=e.src.getBytes();for(let a=0,o=t.length;a255?255:o<0?0:o,u=u>255?255:u<0?0:u,l=l>255?255:l<0?0:l,e.src.setPixel(s,n,d.getColor(o,u,l,h))}return e.src}static emboss(e){let t=[1.5,0,0,0,0,0,0,0,-1.5];return St.convolution({src:e,filter:t,div:1,offset:127})}static gaussianBlur(e,t){if(t<=0)return e;let i;if(St.gaussianKernelCache.has(t))i=St.gaussianKernelCache.get(t);else{let r=t*2/3,n=2*r*r;i=new Hi(t);let s=0;for(let a=-t;a<=t;++a){let o=Math.exp(-(a*a)/n);s+=o,i.setCoefficient(a+t,o)}i.scaleCoefficients(1/s),St.gaussianKernelCache.set(t,i)}return St.separableConvolution(e,i)}static grayscale(e){let t=e.getBytes();for(let i=0,r=t.length;i0){let f=d.getColor(Math.trunc(o/h),Math.trunc(u/h),Math.trunc(l/h),Math.trunc(a/h)),c=new at(s,n,s+r,n+r);Ze.fillRect(e,c,f)}}break}return e}static quantize(e){var n,s;let t=(n=e.numberOfColors)!=null?n:256;if(((s=e.method)!=null?s:0)===1||t<4){let a=new ci(e.src,t);for(let o=0,u=e.src.length;o{"use strict"});var ln=C(()=>{"use strict"});var hn=C(()=>{"use strict"});var ie,Ne,pi=C(()=>{"use strict";je();ie=class{constructor(e){this.bits=e}static convert(e){let t=e>>16&32768,i=(e>>23&255)-(127-15),r=e&8388607;if(i<=0){if(i<-10)return t;r|=8388608;let n=14-i,s=(1<>n&1;return r=r+s+a>>n,t|r}else return i===255-(127-15)?r===0?t|31744:(r>>=13,t|31744|r|(r===0?1:0)):(r=r+4095+(r>>13&1),(r&8388608)!==0&&(r=0,i+=1),i>30?t|31744:t|i<<10|r>>13)}static halfToFloat(e){let t=e>>15&1,i=e>>10&31,r=e&1023;if(i===0){if(r===0)return t<<31;for(;(r&1024)===0;)r<<=1,i-=1;i+=1,r&=-1025}else if(i===31)return r===0?t<<31|2139095040:t<<31|2139095040|r<<13;return i+=127-15,r<<=13,t<<31|i<<23|r}static fromBits(e){return new ie(e)}static halfToDouble(e){return this.toFloatFloat32[e]}static doubleToHalf(e){let t=e,i=E.toUint32(t);if(t===0)return i>>16;let r=i>>23&511;if(r=this.eLut[r],r!==0){let n=i&8388607;return r+(n+4095+(n>>13&1)>>13)}return this.convert(i)}static positiveInfinity(){return ie.fromBits(31744)}static negativeInfinity(){return ie.fromBits(64512)}static qNan(){return ie.fromBits(32767)}static sNan(){return ie.fromBits(32255)}toDouble(){return ie.toFloatFloat32[this.bits]}unaryMinus(){return ie.fromBits(this.bits^32768)}add(e){let t=0;e instanceof ie?t=e.toDouble():typeof e=="number"&&(t=e);let i=ie.doubleToHalf(this.toDouble()+t);return new ie(i)}subtract(e){let t=0;e instanceof ie?t=e.toDouble():typeof e=="number"&&(t=e);let i=ie.doubleToHalf(this.toDouble()-t);return new ie(i)}multiply(e){let t=0;e instanceof ie?t=e.toDouble():typeof e=="number"&&(t=e);let i=ie.doubleToHalf(this.toDouble()*t);return new ie(i)}divide(e){let t=0;e instanceof ie?t=e.toDouble():typeof e=="number"&&(t=e);let i=ie.doubleToHalf(this.toDouble()/t);return new ie(i)}round(e){if(e>=10)return this;let t=this.bits&32768,i=this.bits&32767;return i>>=9-e,i+=i&1,i<<=9-e,i>=31744&&(i=this.bits,i>>=10-e,i<<=10-e),ie.fromBits(t|i)}isFinite(){return(this.bits>>10&31)<31}isNormalized(){let e=this.bits>>10&31;return e>0&&e<31}isDenormalized(){let e=this.bits>>10&31,t=this.bits&1023;return e===0&&t!==0}isZero(){return(this.bits&32767)===0}isNan(){let e=this.bits>>10&31,t=this.bits&1023;return e===31&&t!==0}isInfinity(){let e=this.bits>>10&31,t=this.bits&1023;return e===31&&t===0}isNegative(){return(this.bits&32768)!==0}getBits(){return this.bits}setBits(e){this.bits=e}},Ne=ie;(()=>{ie.toFloatUint32=new Uint32Array(1<<16),ie.toFloatFloat32=new Float32Array(ie.toFloatUint32.buffer),ie.eLut=new Uint16Array(1<<9);for(let t=0;t<256;t++){let i=(t&255)-112;i<=0||i>=30?(ie.eLut[t]=0,ie.eLut[t|256]=0):(ie.eLut[t]=i<<10,ie.eLut[t|256]=i<<10|32768)}let e=1<<16;for(let t=0;t{"use strict";ut();Ot();pi();ht=class{get data(){return this._data}get name(){return this._name}get width(){return this._width}get height(){return this._height}get format(){return this._format}get bitsPerSample(){return this._bitsPerSample}get maxIntSize(){let e=4294967295;return this._bitsPerSample===8?e=255:this._bitsPerSample===16&&(e=65535),this._format===ht.INT&&(e-=1),e}get isFloat(){return this._format===ht.FLOAT}constructor(e){var t;this._name=e.name,this._width=e.width,this._height=e.height,this._format=e.format,this._bitsPerSample=e.bitsPerSample,this._data=(t=e.data)!=null?t:ht.allocateDataForType(e.width*e.height,e.format,e.bitsPerSample)}static allocateDataForType(e,t,i){switch(t){case ht.INT:if(i===8)return new Int8Array(e);if(i===16)return new Int16Array(e);if(i===32)return new Int32Array(e);break;case ht.UINT:if(i===8)return new Uint8Array(e);if(i===16)return new Uint16Array(e);if(i===32)return new Uint32Array(e);break;case ht.FLOAT:if(i===16)return new Uint16Array(e);if(i===32)return new Float32Array(e);if(i===64)return new Float64Array(e);break}throw new Pt}static from(e){return new ht({name:e._name,width:e._width,height:e._height,format:e._format,bitsPerSample:e._bitsPerSample,data:te.copy(e.data)})}getBytes(){return new Uint8Array(this._data.buffer)}getFloat(e,t){let i=t*this._width+e;return this._format===ht.INT||this._format===ht.UINT?Math.trunc(this._data[i])/this.maxIntSize:this._format===ht.FLOAT&&this._bitsPerSample===16?Ne.halfToDouble(this._data[i]):this._data[i]}setFloat(e,t,i){if(this._format!==ht.FLOAT)return;let r=t*this._width+e;this._bitsPerSample===16?this._data[r]=Ne.doubleToHalf(i):this._data[r]=i}getInt(e,t){let i=t*this._width+e;return Math.trunc(this._data[i])}setInt(e,t,i){let r=t*this._width+e;this._data[r]=Math.trunc(i)}},ye=ht;ye.UINT=0,ye.INT=1,ye.FLOAT=3});var Ue,de,ft=C(()=>{"use strict";Ve();Ut();Ue=class{constructor(){this._slices=new Map;this._red=void 0;this._green=void 0;this._blue=void 0;this._alpha=void 0;this._depth=void 0;this._exifData=void 0}get slices(){return this._slices}get red(){return this._red}get green(){return this._green}get blue(){return this._blue}get alpha(){return this._alpha}get depth(){return this._depth}get exifData(){return this._exifData}set exifData(e){this._exifData=e}get hasColor(){return this.red!==void 0||this.green!==void 0||this.blue!==void 0}get hasAlpha(){return this.alpha!==void 0}get hasDepth(){return this.depth!==void 0}get width(){return this.slices.size>0?this.slices.values().next().value.width:0}get height(){return this.slices.size>0?this.slices.values().next().value.height:0}get bitsPerSample(){return this.red!==void 0?this.red.bitsPerSample:this.slices.size>0?this.slices.values().next().value.bitsPerSample:0}get sampleFormat(){return this.red!==void 0?this.red.format:this.slices.size>0?this.slices.values().next().value.format:0}get numberOfChannels(){return this.slices.size}static create(e,t,i,r,n){let s=new Ue;if(0<=i&&i<=4){let a=[Ue.R,Ue.G,Ue.B,Ue.A];for(let o=0;o{"use strict";He();ue();fn=class{get fileLength(){return this._fileLength}set offset(e){this._offset=e}get offset(){return this._offset}constructor(e){if(!fn.isValidFile(e))throw new T("Not a bitmap file.");e.skip(2),this._fileLength=e.readInt32(),e.skip(4),this._offset=e.readInt32()}static isValidFile(e){return e.length<2?!1:G.from(e).readUint16()===fn.BMP_HEADER_FILETYPE}toJson(){return new Map([["offset",this._offset],["fileLength",this.fileLength],["fileType",fn.BMP_HEADER_FILETYPE]])}},Ct=fn;Ct.BMP_HEADER_FILETYPE=66+(77<<8)});var Yi=C(()=>{"use strict"});var bi=C(()=>{"use strict";je();ge();ue();Ot();Yi();Mt()});var gi=C(()=>{"use strict";bt();He();Ye();ft();Mt();bi()});var zi=C(()=>{"use strict";ge();st();Ve();Mt()});var cn=C(()=>{"use strict"});var dn=C(()=>{"use strict"});var Hr=C(()=>{"use strict";gi()});var mn=C(()=>{"use strict"});var Wi=C(()=>{"use strict"});var fe,Ft=C(()=>{"use strict";Ye();Ve();ue();di();Wi();mi();Zt();ge();Qe();wt();fe=class{static copyRotate(e,t,i=0){let r=t%360;if(r%90===0){let x=e.width-1,y=e.height-1;switch(Math.floor(r/90)){case 1:{let w=new W({width:e.height,height:e.width,rgbChannelSet:e.rgbChannelSet,exifData:e.exifData,iccProfile:e.iccProfile});for(let M=0;Me.height&&(r=Math.trunc(t*(e.width/e.height)));let n=new W({width:t,height:t,rgbChannelSet:e.rgbChannelSet,exifData:e.exifData,iccProfile:e.iccProfile}),s=e.height/i,a=e.width/r,o=Math.trunc((r-t)/2),u=Math.trunc((i-t)/2),l=new Int32Array(t);for(let h=0;he.width&&(o=e.width-s);let u=n;a+u>e.height&&(u=e.height-a);let l=new W({width:o,height:u,rgbChannelSet:e.rgbChannelSet,exifData:e.exifData,iccProfile:e.iccProfile});for(let h=0,f=a;h{"use strict";ge();ct=class{get colors(){return this._colors}get numColors(){return this._numColors}get bitsPerPixel(){return this._bitsPerPixel}set transparent(e){this._transparent=e}get transparent(){return this._transparent}constructor(e){var t,i;this._numColors=e.numColors,this._bitsPerPixel=(t=e.bitsPerPixel)!=null?t:ct.bitSize(e.numColors),this._colors=(i=e.colors)!=null?i:new Uint8Array(e.numColors*3),this._transparent=e.transparent}static bitSize(e){for(let t=1;t<=8;t++)if(1<=e)return t;return 0}static from(e){return new ct({numColors:e.numColors,bitsPerPixel:e.bitsPerPixel,colors:e.colors,transparent:e.transparent})}getByte(e){return this._colors[e]}setByte(e,t){return this._colors[e]=t}getColor(e){let t=e*3,i=e===this._transparent?0:255;return d.getColor(this._colors[t],this._colors[t+1],this._colors[t+2],i)}setColor(e,t,i,r){let n=e*3;this._colors[n]=t,this._colors[n+1]=i,this._colors[n+2]=r}getRed(e){return this._colors[e*3]}getGreen(e){return this._colors[e*3+1]}getBlue(e){return this._colors[e*3+2]}getAlpha(e){return e===this._transparent?0:255}}});var Xi,qi=C(()=>{"use strict";xi();Xi=class{constructor(e){this._duration=80;this._clearFrame=!0;this._x=e.readUint16(),this._y=e.readUint16(),this._width=e.readUint16(),this._height=e.readUint16();let t=e.readByte(),i=(t&7)+1;if(this._interlaced=(t&64)!==0,(t&128)!==0){this._colorMap=new ct({numColors:1<{"use strict";Zi=class{constructor(e){this._isGif89=!1;var t,i,r,n,s,a;this._width=(t=e==null?void 0:e.width)!=null?t:0,this._height=(i=e==null?void 0:e.height)!=null?i:0,this._backgroundColor=(r=e==null?void 0:e.backgroundColor)!=null?r:4294967295,this._frames=(n=e==null?void 0:e.frames)!=null?n:new Array,this._colorResolution=(s=e==null?void 0:e.colorResolution)!=null?s:0,this._globalColorMap=e==null?void 0:e.globalColorMap,this._isGif89=(a=e==null?void 0:e.isGif89)!=null?a:!1}get width(){return this._width}get height(){return this._height}get backgroundColor(){return this._backgroundColor}get frames(){return this._frames}get colorResolution(){return this._colorResolution}get globalColorMap(){return this._globalColorMap}get isGif89(){return this._isGif89}get numFrames(){return this.frames.length}}});var q,Se,Ki=C(()=>{"use strict";bt();He();ut();Ye();ue();ft();Ft();xi();qi();$i();q=class{constructor(e){this.repeat=0;this.bitsPerPixel=0;this.currentShiftDWord=0;this.currentShiftState=0;this.stackPtr=0;this.lastCode=0;this.maxCode1=0;this.runningBits=0;this.runningCode=0;this.eofCode=0;this.clearCode=0;e!==void 0&&this.startDecode(e)}get numFrames(){return this.info!==void 0?this.info.numFrames:0}static getPrefixChar(e,t,i){let r=t,n=0;for(;r>i&&n++<=q.LZ_MAX_CODE;){if(r>q.LZ_MAX_CODE)return q.NO_SUCH_CODE;r=e[t]}return r}static updateImage(e,t,i,r){if(i!==void 0)for(let n=0,s=r.length;n>4)+1,s=(r&7)+1,a=this.input.readByte();this.input.skip(1);let o;if((r&128)!==0){o=new ct({numColors:1<>2&7,s=t&1;if(e.peekBytes(1).getByte(0)===q.IMAGE_DESC_RECORD_TYPE){e.skip(1);let o=this.skipImage();if(o===void 0)return;o.duration=i,o.clearFrame=n===2,s!==0&&(o.colorMap===void 0&&this.info.globalColorMap!==void 0&&(o.colorMap=ct.from(this.info.globalColorMap)),o.colorMap!==void 0&&(o.colorMap.transparent=r)),this.info.frames.push(o)}}decodeFrameImage(e){this.buffer===void 0&&this.initDecode(),this.bitsPerPixel=this.input.readByte(),this.clearCode=1<this.info.width||e.y+i>this.info.height)return;let r=e.colorMap!==void 0?e.colorMap:this.info.globalColorMap;this.pixelCount=t*i;let n=new W({width:t,height:i}),s=new Uint8Array(t);if(e.interlaced){let a=e.y;for(let o=0,u=0;o<4;++o)for(let l=a+q.INTERLACED_OFFSET[o];lq.LZ_MAX_CODE)return!1;let t=e.length,i=0;if(this.stackPtr!==0)for(;this.stackPtr!==0&&ithis.clearCode&&r<=q.LZ_MAX_CODE;)this.stack[this.stackPtr++]=this.suffix[r],r=this.prefix[r];if(n>=q.LZ_MAX_CODE||r>q.LZ_MAX_CODE)return!1;for(this.stack[this.stackPtr++]=r;this.stackPtr!==0&&iq.LZ_BITS)return;for(;this.currentShiftState>=this.runningBits,this.currentShiftState-=this.runningBits,this.runningCodethis.maxCode1&&this.runningBits=this.info.frames.length||e<0)return;let t=this.info.frames[e];return this.input.offset=t.inputPosition,this.decodeFrameImage(this.info.frames[e])}decodeHdrFrame(e){let t=this.decodeFrame(e);if(t!==void 0)return de.fromImage(t)}decodeAnimation(e){if(this.startDecode(e)===void 0||this.input===void 0||this.info===void 0)return;let t=new Xe({width:this.info.width,height:this.info.height,loopCount:this.repeat}),i;for(let r=0;r{"use strict";Wt();Mi();hi();st();xt();Pe=class{constructor(e){this.curAccum=0;this.curBits=0;this.nBits=0;this.initBits=0;this.EOFCode=0;this.maxCode=0;this.clearCode=0;this.freeEnt=0;this.clearFlag=!1;this.blockSize=0;this._supportsAnimation=!0;var t,i,r,n,s;this.delay=(t=e==null?void 0:e.delay)!=null?t:80,this.repeat=(i=e==null?void 0:e.repeat)!=null?i:0,this.samplingFactor=(r=e==null?void 0:e.samplingFactor)!=null?r:10,this.dither=(n=e==null?void 0:e.dither)!=null?n:2,this.ditherSerpentine=(s=e==null?void 0:e.ditherSerpentine)!=null?s:!1,this.encodedFrames=0}get supportsAnimation(){return this._supportsAnimation}addImage(e,t,i,r,n){this.outputBuffer.writeByte(Pe.imageDescRecordType),this.outputBuffer.writeUint16(0),this.outputBuffer.writeUint16(0),this.outputBuffer.writeUint16(t),this.outputBuffer.writeUint16(i),this.outputBuffer.writeByte(135),this.outputBuffer.writeBytes(r);for(let s=n;s<256;++s)this.outputBuffer.writeByte(0),this.outputBuffer.writeByte(0),this.outputBuffer.writeByte(0);this.encodeLZW(e,t,i)}encodeLZW(e,t,i){this.curAccum=0,this.curBits=0,this.blockSize=0,this.block=new Uint8Array(256);let r=8;this.outputBuffer.writeByte(r);let n=new Int32Array(Pe.hsize),s=new Int32Array(Pe.hsize),a=t*i,o=0;this.initBits=r+1,this.nBits=this.initBits,this.maxCode=(1<a===0?Pe.eof:(--a,e[o++]&255),l=u(),h=0;for(let p=Pe.hsize;p<65536;p*=2)h++;h=8-h;let f=Pe.hsize;for(let p=0;p=0){let x=f-b;b===0&&(x=1);do if((b-=x)<0&&(b+=f),n[b]===g){l=s[b],c=!0;break}while(n[b]>=0);if(c)break}if(this.output(l),l=p,this.freeEnt<1<0?this.curAccum|=e<=8;)this.addToBlock(this.curAccum&255),this.curAccum>>=8,this.curBits-=8;if((this.freeEnt>this.maxCode||this.clearFlag)&&(this.clearFlag?(this.nBits=this.initBits,this.maxCode=(1<0;)this.addToBlock(this.curAccum&255),this.curAccum>>=8,this.curBits-=8;this.writeBlock()}}writeBlock(){this.blockSize>0&&(this.outputBuffer.writeByte(this.blockSize),this.outputBuffer.writeBytes(this.block,this.blockSize),this.blockSize=0)}addToBlock(e){this.block[this.blockSize++]=e,this.blockSize>=254&&this.writeBlock()}writeApplicationExt(){this.outputBuffer.writeByte(Pe.extensionRecordType),this.outputBuffer.writeByte(Pe.applicationExt),this.outputBuffer.writeByte(11);let e=ce.getCodePoints("NETSCAPE2.0");this.outputBuffer.writeBytes(e),this.outputBuffer.writeBytes(new Uint8Array([3,1])),this.outputBuffer.writeUint16(this.repeat),this.outputBuffer.writeByte(0)}writeGraphicsCtrlExt(){var i;this.outputBuffer.writeByte(Pe.extensionRecordType),this.outputBuffer.writeByte(Pe.graphicControlExt),this.outputBuffer.writeByte(4);let e=0,t=0;this.outputBuffer.writeByte(0|t|0|e),this.outputBuffer.writeUint16((i=this.lastImageDuration)!=null?i:this.delay),this.outputBuffer.writeByte(0),this.outputBuffer.writeByte(0)}writeHeader(e,t){let i=ce.getCodePoints(Pe.gif89Id);this.outputBuffer.writeBytes(i),this.outputBuffer.writeUint16(e),this.outputBuffer.writeUint16(t),this.outputBuffer.writeByte(0),this.outputBuffer.writeByte(0),this.outputBuffer.writeByte(0)}finish(){let e;return this.outputBuffer===void 0||(this.encodedFrames===0?(this.writeHeader(this.width,this.height),this.writeApplicationExt()):this.writeGraphicsCtrlExt(),this.addImage(this.lastImage,this.width,this.height,this.lastColorMap.colorMap8,256),this.outputBuffer.writeByte(Pe.terminateRecordType),this.lastImage=void 0,this.lastColorMap=void 0,this.encodedFrames=0,e=this.outputBuffer.getBytes(),this.outputBuffer=void 0),e}addFrame(e,t){if(this.outputBuffer===void 0){this.outputBuffer=new he,this.lastColorMap=new le(e,256,this.samplingFactor),this.lastImage=Tt.getDitherPixels(e,this.lastColorMap,this.dither,this.ditherSerpentine),this.lastImageDuration=t,this.width=e.width,this.height=e.height;return}this.encodedFrames===0&&(this.writeHeader(this.width,this.height),this.writeApplicationExt()),this.writeGraphicsCtrlExt(),this.addImage(this.lastImage,this.width,this.height,this.lastColorMap.colorMap8,256),this.encodedFrames++,this.lastColorMap=new le(e,256,this.samplingFactor),this.lastImage=Tt.getDitherPixels(e,this.lastColorMap,this.dither,this.ditherSerpentine),this.lastImageDuration=t}encodeImage(e){return this.addFrame(e),this.finish()}encodeAnimation(e){this.repeat=e.loopCount;for(let t of e)this.addFrame(t,Math.floor(t.duration/10));return this.finish()}},ze=Pe;ze.gif89Id="GIF89a",ze.imageDescRecordType=44,ze.extensionRecordType=33,ze.terminateRecordType=59,ze.applicationExt=255,ze.graphicControlExt=249,ze.eof=-1,ze.bits=12,ze.hsize=5003,ze.masks=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535]});var Qi=C(()=>{"use strict";bi()});var Ji=C(()=>{"use strict"});var er=C(()=>{"use strict";Ji()});var We,tr=C(()=>{"use strict";We=class{constructor(e){this._fdat=[];this._sequenceNumber=e==null?void 0:e.sequenceNumber,this._width=e==null?void 0:e.width,this._height=e==null?void 0:e.height,this._xOffset=e==null?void 0:e.xOffset,this._yOffset=e==null?void 0:e.yOffset,this._delayNum=e==null?void 0:e.delayNum,this._delayDen=e==null?void 0:e.delayDen,this._dispose=e==null?void 0:e.dispose,this._blend=e==null?void 0:e.blend}get fdat(){return this._fdat}get sequenceNumber(){return this._sequenceNumber}get width(){return this._width}get height(){return this._height}get xOffset(){return this._xOffset}get yOffset(){return this._yOffset}get delayNum(){return this._delayNum}get delayDen(){return this._delayDen}get dispose(){return this._dispose}get blend(){return this._blend}get delay(){return this._delayNum===void 0||this._delayDen===void 0||this._delayDen===0?0:this._delayNum/this._delayDen}};We.APNG_DISPOSE_OP_NONE=0,We.APNG_DISPOSE_OP_BACKGROUND=1,We.APNG_DISPOSE_OP_PREVIOUS=2,We.APNG_BLEND_OP_SOURCE=0,We.APNG_BLEND_OP_OVER=1});var yi,ir=C(()=>{"use strict";yi=class{constructor(e){this._width=0;this._height=0;this._backgroundColor=16777215;this._numFrames=1;this._iCCPName="";this._iCCPCompression=0;this._textData=new Map;this._repeat=0;this._idat=[];this._frames=[];var t,i;this._width=(t=e==null?void 0:e.width)!=null?t:0,this._height=(i=e==null?void 0:e.height)!=null?i:0,this._bits=e==null?void 0:e.bits,this._colorType=e==null?void 0:e.colorType,this._compressionMethod=e==null?void 0:e.compressionMethod,this._filterMethod=e==null?void 0:e.filterMethod,this._interlaceMethod=e==null?void 0:e.interlaceMethod}set width(e){this._width=e}get width(){return this._width}set height(e){this._height=e}get height(){return this._height}set backgroundColor(e){this._backgroundColor=e}get backgroundColor(){return this._backgroundColor}set numFrames(e){this._numFrames=e}get numFrames(){return this._numFrames}get bits(){return this._bits}get colorType(){return this._colorType}get compressionMethod(){return this._compressionMethod}get filterMethod(){return this._filterMethod}get interlaceMethod(){return this._interlaceMethod}set palette(e){this._palette=e}get palette(){return this._palette}set transparency(e){this._transparency=e}get transparency(){return this._transparency}set colorLut(e){this._colorLut=e}get colorLut(){return this._colorLut}set gamma(e){this._gamma=e}get gamma(){return this._gamma}set iCCPName(e){this._iCCPName=e}get iCCPName(){return this._iCCPName}set iCCPCompression(e){this._iCCPCompression=e}get iCCPCompression(){return this._iCCPCompression}set iCCPData(e){this._iCCPData=e}get iCCPData(){return this._iCCPData}get textData(){return this._textData}set repeat(e){this._repeat=e}get repeat(){return this._repeat}get idat(){return this._idat}get frames(){return this._frames}get isAnimated(){return this._frames.length>0}}});var ps,U,ke,_i=C(()=>{"use strict";ps=An(pn());ge();Yt();bt();qt();rr();He();ut();Ye();Ve();xt();ue();Ot();ft();Ft();tr();ir();U=class{constructor(){this._progressY=0;this._bitBuffer=0;this._bitBufferLen=0}get info(){return this._info}get input(){return this._input}get progressY(){return this._progressY}get bitBuffer(){return this._bitBuffer}get bitBufferLen(){return this._bitBufferLen}get numFrames(){return this._info!==void 0?this._info.numFrames:0}static unfilter(e,t,i,r){let n=i.length;switch(e){case U.FILTER_NONE:break;case U.FILTER_SUB:for(let s=t;s>1)&255}break;case U.FILTER_PAETH:for(let s=0;s>8}static convert1to8(e){return e===0?0:255}static convert2to8(e){return e*85}static convert4to8(e){return e<<4}static crc(e,t){let i=ce.getCodePoints(e),r=pt.getChecksum({buffer:i});return pt.getChecksum({buffer:t,baseCrc:r})}processPass(e,t,i,r,n,s,a,o){let u=1;this._info.colorType===U.GRAYSCALE_ALPHA?u=2:this._info.colorType===U.RGB?u=3:this._info.colorType===U.RGBA&&(u=4);let l=u*this._info.bits,h=l+7>>3,f=l*a+7>>3,c=new Uint8Array(f),p=[c,c],g=[0,0,0,0];for(let b=0,x=r,y=0;b1||O>1)for(let k=0;k>3,o=r+7>>3,u=new Uint8Array(a),l=[u,u],h=[0,0,0,0];for(let f=0,c=0,p=0;f>this._bitBufferLen-t&i;return this._bitBufferLen-=t,r}readPixel(e,t){switch(this._info.colorType){case U.GRAYSCALE:t[0]=this.readBits(e,this._info.bits);return;case U.RGB:t[0]=this.readBits(e,this._info.bits),t[1]=this.readBits(e,this._info.bits),t[2]=this.readBits(e,this._info.bits);return;case U.INDEXED:t[0]=this.readBits(e,this._info.bits);return;case U.GRAYSCALE_ALPHA:t[0]=this.readBits(e,this._info.bits),t[1]=this.readBits(e,this._info.bits);return;case U.RGBA:t[0]=this.readBits(e,this._info.bits),t[1]=this.readBits(e,this._info.bits),t[2]=this.readBits(e,this._info.bits),t[3]=this.readBits(e,this._info.bits);return}throw new Pt(`Invalid color type: ${this._info.colorType}.`)}getColor(e){switch(this._info.colorType){case U.GRAYSCALE:{let t=0;switch(this._info.bits){case 1:t=U.convert1to8(e[0]);break;case 2:t=U.convert2to8(e[0]);break;case 4:t=U.convert4to8(e[0]);break;case 8:t=e[0];break;case 16:t=U.convert16to8(e[0]);break}if(t=this._info.colorLut[t],this._info.transparency!==void 0){let i=(this._info.transparency[0]&255)<<24|this._info.transparency[1]&255;if(e[0]===i)return d.getColor(t,t,t,0)}return d.getColor(t,t,t)}case U.RGB:{let t=0,i=0,r=0;switch(this._info.bits){case 1:t=U.convert1to8(e[0]),i=U.convert1to8(e[1]),r=U.convert1to8(e[2]);break;case 2:t=U.convert2to8(e[0]),i=U.convert2to8(e[1]),r=U.convert2to8(e[2]);break;case 4:t=U.convert4to8(e[0]),i=U.convert4to8(e[1]),r=U.convert4to8(e[2]);break;case 8:t=e[0],i=e[1],r=e[2];break;case 16:t=U.convert16to8(e[0]),i=U.convert16to8(e[1]),r=U.convert16to8(e[2]);break}if(t=this._info.colorLut[t],i=this._info.colorLut[i],r=this._info.colorLut[r],this._info.transparency!==void 0){let n=(this._info.transparency[0]&255)<<8|this._info.transparency[1]&255,s=(this._info.transparency[2]&255)<<8|this._info.transparency[3]&255,a=(this._info.transparency[4]&255)<<8|this._info.transparency[5]&255;if(e[0]===n&&e[1]===s&&e[2]===a)return d.getColor(t,i,r,0)}return d.getColor(t,i,r)}case U.INDEXED:{let t=e[0]*3,i=this._info.transparency!==void 0&&e[0]=this._info.palette.length)return d.getColor(255,255,255,i);let r=this._info.palette[t],n=this._info.palette[t+1],s=this._info.palette[t+2];return d.getColor(r,n,s,i)}case U.GRAYSCALE_ALPHA:{let t=0,i=0;switch(this._info.bits){case 1:t=U.convert1to8(e[0]),i=U.convert1to8(e[1]);break;case 2:t=U.convert2to8(e[0]),i=U.convert2to8(e[1]);break;case 4:t=U.convert4to8(e[0]),i=U.convert4to8(e[1]);break;case 8:t=e[0],i=e[1];break;case 16:t=U.convert16to8(e[0]),i=U.convert16to8(e[1]);break}return t=this._info.colorLut[t],d.getColor(t,t,t,i)}case U.RGBA:{let t=0,i=0,r=0,n=0;switch(this._info.bits){case 1:t=U.convert1to8(e[0]),i=U.convert1to8(e[1]),r=U.convert1to8(e[2]),n=U.convert1to8(e[3]);break;case 2:t=U.convert2to8(e[0]),i=U.convert2to8(e[1]),r=U.convert2to8(e[2]),n=U.convert2to8(e[3]);break;case 4:t=U.convert4to8(e[0]),i=U.convert4to8(e[1]),r=U.convert4to8(e[2]),n=U.convert4to8(e[3]);break;case 8:t=e[0],i=e[1],r=e[2],n=e[3];break;case 16:t=U.convert16to8(e[0]),i=U.convert16to8(e[1]),r=U.convert16to8(e[2]),n=U.convert16to8(e[3]);break}return t=this._info.colorLut[t],i=this._info.colorLut[i],r=this._info.colorLut[r],d.getColor(t,i,r,n)}}throw new T(`Invalid color type: ${this._info.colorType}.`)}isValidFile(e){let i=new G({buffer:e,bigEndian:!0}).readBytes(8),r=[137,80,78,71,13,10,26,10];for(let n=0;n<8;++n)if(i.getByte(n)!==r[n])return!1;return!0}startDecode(e){this._input=new G({buffer:e,bigEndian:!0});let t=this._input.readBytes(8),i=[137,80,78,71,13,10,26,10];for(let r=0;r<8;++r)if(t.getByte(r)!==i[r])return;for(;;){let r=this._input.position,n=this._input.readUint32(),s=this._input.readString(4);switch(s){case"tEXt":{this._info===void 0&&(this._info=new yi);let a=this._input.readBytes(n).toUint8Array();for(let o=0,u=a.length;o0&&this._input.skip(n),this._input.skip(4);break}case"iCCP":{this._info.iCCPName=this._input.readString(),this._info.iCCPCompression=this._input.readByte(),n-=this._info.iCCPName.length+2;let a=this._input.readBytes(n);this._info.iCCPData=a.toUint8Array(),this._input.skip(4);break}default:{this._input.skip(n),this._input.skip(4);break}}if(s==="IEND")break;if(this._input.isEOS)return}return this._info}decodeFrame(e){if(this._input===void 0||this._info===void 0)return;let t,i=this._info.width,r=this._info.height;if(!this._info.isAnimated||e===0){let c=0,p=new Array;for(let b=0,x=this._info.idat.length;b=this._info.frames.length)throw new T(`Invalid Frame Number: ${e}`);let c=this._info.frames[e];i=c.width,r=c.height;let p=0,g=new Array;for(let x=0;x>3,f+7>>3),this.processPass(o,s,4,0,8,8,h+3>>3,f+7>>3),this.processPass(o,s,0,4,4,8,h+3>>2,f+3>>3),this.processPass(o,s,2,0,4,4,h+1>>2,f+3>>2),this.processPass(o,s,0,2,2,4,h+1>>1,f+1>>2),this.processPass(o,s,1,0,2,2,h>>1,f+1>>1),this.processPass(o,s,0,1,1,2,h,f>>1)):this.process(o,s),this._info.width=u,this._info.height=l,this._info.iCCPData!==void 0&&(s.iccProfile=new Rt(this._info.iCCPName,1,this._info.iCCPData)),this._info.textData.size>0&&s.addTextData(this._info.textData),s}decodeHdrFrame(e){let t=this.decodeFrame(e);if(t!==void 0)return de.fromImage(t)}decodeAnimation(e){if(this.startDecode(e)===void 0)return;let t=new Xe({width:this._info.width,height:this._info.height});if(!this._info.isAnimated){let r=this.decodeFrame(0);return t.addFrame(r),t}let i;for(let r=0;r{"use strict";He();ut();st();Ot();ft();Mt();Hr();Qi();er();_i()});var gs,re,dt,wi=C(()=>{"use strict";gs=An(pn());Ht();ge();Yt();zt();st();Ve();xt();re=class{constructor(e){this.repeat=0;this.xOffset=0;this.yOffset=0;this.disposeMethod=0;this.blendMethod=0;this.width=0;this.height=0;this.frames=0;this.sequenceNumber=0;this.isAnimated=!1;this._supportsAnimation=!0;var t,i;this.filter=(t=e==null?void 0:e.filter)!=null?t:re.FILTER_PAETH,this.level=(i=e==null?void 0:e.level)!=null?i:6}get supportsAnimation(){return this._supportsAnimation}static crc(e,t){let i=ce.getCodePoints(e),r=pt.getChecksum({buffer:i});return pt.getChecksum({buffer:t,baseCrc:r})}static writeChunk(e,t,i){e.writeUint32(i.length);let r=ce.getCodePoints(t);e.writeBytes(r),e.writeBytes(i);let n=re.crc(t,i);e.writeUint32(n)}static filterSub(e,t,i,r){let n=t;r[n++]=re.FILTER_SUB,r[n++]=d.getRed(e.getPixel(0,i)),r[n++]=d.getGreen(e.getPixel(0,i)),r[n++]=d.getBlue(e.getPixel(0,i)),e.rgbChannelSet===1&&(r[n++]=d.getAlpha(e.getPixel(0,i)));for(let s=1;s>1)&255,r[n++]=p-(o+h>>1)&255,r[n++]=g-(u+f>>1)&255,e.rgbChannelSet===1){let b=s===0?0:d.getAlpha(e.getPixel(s-1,i)),x=i===0?0:d.getAlpha(e.getPixel(s,i-1)),y=d.getAlpha(e.getPixel(s,i));r[n++]=y-(b+x>>1)&255}}return n}static paethPredictor(e,t,i){let r=e+t-i,n=r>e?r-e:e-r,s=r>t?r-t:t-r,a=r>i?r-i:i-r;return n<=s&&n<=a?e:s<=a?t:i}static filterPaeth(e,t,i,r){let n=t;r[n++]=re.FILTER_PAETH;for(let s=0;s{"use strict";st();ue();wi()});var sr=C(()=>{"use strict";Vr()});var ar,or=C(()=>{"use strict";ar=class{get hSamples(){return this._hSamples}get maxHSamples(){return this._maxHSamples}get vSamples(){return this._vSamples}get maxVSamples(){return this._maxVSamples}get lines(){return this._lines}get hScaleShift(){return this._hScaleShift}get vScaleShift(){return this._vScaleShift}constructor(e,t,i,r,n){this._hSamples=e,this._maxHSamples=t,this._vSamples=i,this._maxVSamples=r,this._lines=n,this._hScaleShift=this._hSamples===1&&this._maxHSamples===2?1:0,this._vScaleShift=this._vSamples===1&&this._maxVSamples===2?1:0}}});var A,Dt=C(()=>{"use strict";A=class{};A.dctZigZag=[0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63],A.DCTSIZE=8,A.DCTSIZE2=64,A.NUM_QUANT_TBLS=4,A.NUM_HUFF_TBLS=4,A.NUM_ARITH_TBLS=16,A.MAX_COMPS_IN_SCAN=4,A.MAX_SAMP_FACTOR=4,A.M_SOF0=192,A.M_SOF1=193,A.M_SOF2=194,A.M_SOF3=195,A.M_SOF5=197,A.M_SOF6=198,A.M_SOF7=199,A.M_JPG=200,A.M_SOF9=201,A.M_SOF10=202,A.M_SOF11=203,A.M_SOF13=205,A.M_SOF14=206,A.M_SOF15=207,A.M_DHT=196,A.M_DAC=204,A.M_RST0=208,A.M_RST1=209,A.M_RST2=210,A.M_RST3=211,A.M_RST4=212,A.M_RST5=213,A.M_RST6=214,A.M_RST7=215,A.M_SOI=216,A.M_EOI=217,A.M_SOS=218,A.M_DQT=219,A.M_DNL=220,A.M_DRI=221,A.M_DHP=222,A.M_EXP=223,A.M_APP0=224,A.M_APP1=225,A.M_APP2=226,A.M_APP3=227,A.M_APP4=228,A.M_APP5=229,A.M_APP6=230,A.M_APP7=231,A.M_APP8=232,A.M_APP9=233,A.M_APP10=234,A.M_APP11=235,A.M_APP12=236,A.M_APP13=237,A.M_APP14=238,A.M_APP15=239,A.M_JPG0=240,A.M_JPG13=253,A.M_COM=254,A.M_TEM=1,A.M_ERROR=256});var ur,lr=C(()=>{"use strict";ur=class{get version(){return this._version}get flags0(){return this._flags0}get flags1(){return this._flags1}get transformCode(){return this._transformCode}constructor(e,t,i,r){this._version=e,this._flags0=t,this._flags1=i,this._transformCode=r}}});var hr,fr=C(()=>{"use strict";hr=class{constructor(e,t,i,r){this._blocks=new Array;this._blocksPerLine=0;this._blocksPerColumn=0;this._huffmanTableDC=[];this._huffmanTableAC=[];this._pred=0;this._hSamples=e,this._vSamples=t,this._quantizationTableList=i,this._quantizationIndex=r}get hSamples(){return this._hSamples}get vSamples(){return this._vSamples}get blocks(){return this._blocks}get blocksPerLine(){return this._blocksPerLine}get blocksPerColumn(){return this._blocksPerColumn}set huffmanTableDC(e){this._huffmanTableDC=e}get huffmanTableDC(){return this._huffmanTableDC}set huffmanTableAC(e){this._huffmanTableAC=e}get huffmanTableAC(){return this._huffmanTableAC}set pred(e){this._pred=e}get pred(){return this._pred}get quantizationTable(){return this._quantizationTableList[this._quantizationIndex]}setBlocks(e,t,i){this._blocks=e,this._blocksPerLine=t,this._blocksPerColumn=i}}});var Lt,cr=C(()=>{"use strict";Lt=class{constructor(e,t,i,r,n,s,a){this._maxHSamples=0;this._maxVSamples=0;this._mcusPerLine=0;this._mcusPerColumn=0;this._components=e,this._componentsOrder=t,this._extended=i,this._progressive=r,this._precision=n,this._scanLines=s,this._samplesPerLine=a}get components(){return this._components}get componentsOrder(){return this._componentsOrder}get extended(){return this._extended}get progressive(){return this._progressive}get precision(){return this._precision}get scanLines(){return this._scanLines}get samplesPerLine(){return this._samplesPerLine}get maxHSamples(){return this._maxHSamples}get maxVSamples(){return this._maxVSamples}get mcusPerLine(){return this._mcusPerLine}get mcusPerColumn(){return this._mcusPerColumn}static getEmptyBlocks(e,t){let i=new Array;for(let r=0;r{"use strict";Nt=class{constructor(){this._children=new Array;this._index=0}get children(){return this._children}get index(){return this._index}incrementIndex(){this._index++}}});var mr,pr=C(()=>{"use strict";mr=class{constructor(){this._width=0;this._height=0;this._backgroundColor=4294967295;this._numFrames=1}get width(){return this._width}get height(){return this._height}get backgroundColor(){return this._backgroundColor}get numFrames(){return this._numFrames}setSize(e,t){this._width=e,this._height=t}}});var br,gr=C(()=>{"use strict";br=class{get thumbWidth(){return this._thumbWidth}get thumbHeight(){return this._thumbHeight}get majorVersion(){return this._majorVersion}get minorVersion(){return this._minorVersion}get densityUnits(){return this._densityUnits}get xDensity(){return this._xDensity}get yDensity(){return this._yDensity}get thumbData(){return this._thumbData}constructor(e,t,i,r,n,s,a,o){this._thumbWidth=e,this._thumbHeight=t,this._majorVersion=i,this._minorVersion=r,this._densityUnits=n,this._xDensity=s,this._yDensity=a,this._thumbData=o}}});var $e,xr=C(()=>{"use strict";je();ge();Ye();Ve();ue();wt();$e=class{static clamp8(e){return e<0?0:e>255?255:e}static quantizeAndInverse(e,t,i,r){let n=r,s=256,a=768;if($e.dctClip===void 0){$e.dctClip=new Uint8Array(a);for(let x=-256;x<0;++x)$e.dctClip[s+x]=0;for(let x=0;x<256;++x)$e.dctClip[s+x]=x;for(let x=256;x<512;++x)$e.dctClip[s+x]=255}let o=4017,u=799,l=3406,h=2276,f=1567,c=3784,p=5793,g=2896;for(let x=0;x<64;x++)n[x]=t[x]*e[x];let b=0;for(let x=0;x<8;++x,b+=8){if(n[1+b]===0&&n[2+b]===0&&n[3+b]===0&&n[4+b]===0&&n[5+b]===0&&n[6+b]===0&&n[7+b]===0){let D=E.shiftR(p*n[0+b]+512,10);n[b+0]=D,n[b+1]=D,n[b+2]=D,n[b+3]=D,n[b+4]=D,n[b+5]=D,n[b+6]=D,n[b+7]=D;continue}let y=E.shiftR(p*n[0+b]+128,8),P=E.shiftR(p*n[4+b]+128,8),w=n[2+b],M=n[6+b],B=E.shiftR(g*(n[1+b]-n[7+b])+128,8),O=E.shiftR(g*(n[1+b]+n[7+b])+128,8),R=E.shiftL(n[3+b],4),N=E.shiftL(n[5+b],4),L=E.shiftR(y-P+1,1);y=E.shiftR(y+P+1,1),P=L,L=E.shiftR(w*c+M*f+128,8),w=E.shiftR(w*f-M*c+128,8),M=L,L=E.shiftR(B-N+1,1),B=E.shiftR(B+N+1,1),N=L,L=E.shiftR(O+R+1,1),R=E.shiftR(O-R+1,1),O=L,L=E.shiftR(y-M+1,1),y=E.shiftR(y+M+1,1),M=L,L=E.shiftR(P-w+1,1),P=E.shiftR(P+w+1,1),w=L,L=E.shiftR(B*h+O*l+2048,12),B=E.shiftR(B*l-O*h+2048,12),O=L,L=E.shiftR(R*u+N*o+2048,12),R=E.shiftR(R*o-N*u+2048,12),N=L,n[0+b]=y+O,n[7+b]=y-O,n[1+b]=P+N,n[6+b]=P-N,n[2+b]=w+R,n[5+b]=w-R,n[3+b]=M+B,n[4+b]=M-B}for(let x=0;x<8;++x){let y=x;if(n[1*8+y]===0&&n[2*8+y]===0&&n[3*8+y]===0&&n[4*8+y]===0&&n[5*8+y]===0&&n[6*8+y]===0&&n[7*8+y]===0){let k=E.shiftR(p*r[x]+8192,14);n[0*8+y]=k,n[1*8+y]=k,n[2*8+y]=k,n[3*8+y]=k,n[4*8+y]=k,n[5*8+y]=k,n[6*8+y]=k,n[7*8+y]=k;continue}let P=E.shiftR(p*n[0*8+y]+2048,12),w=E.shiftR(p*n[4*8+y]+2048,12),M=n[2*8+y],B=n[6*8+y],O=E.shiftR(g*(n[1*8+y]-n[7*8+y])+2048,12),R=E.shiftR(g*(n[1*8+y]+n[7*8+y])+2048,12),N=n[3*8+y],L=n[5*8+y],D=E.shiftR(P-w+1,1);P=E.shiftR(P+w+1,1),w=D,D=E.shiftR(M*c+B*f+2048,12),M=E.shiftR(M*f-B*c+2048,12),B=D,D=E.shiftR(O-L+1,1),O=E.shiftR(O+L+1,1),L=D,D=E.shiftR(R+N+1,1),N=E.shiftR(R-N+1,1),R=D,D=E.shiftR(P-B+1,1),P=E.shiftR(P+B+1,1),B=D,D=E.shiftR(w-M+1,1),w=E.shiftR(w+M+1,1),M=D,D=E.shiftR(O*h+R*l+2048,12),O=E.shiftR(O*l-R*h+2048,12),R=D,D=E.shiftR(N*u+L*o+2048,12),N=E.shiftR(N*o-L*u+2048,12),L=D,n[0*8+y]=P+R,n[7*8+y]=P-R,n[1*8+y]=w+L,n[6*8+y]=w-L,n[2*8+y]=M+N,n[5*8+y]=M-N,n[3*8+y]=B+O,n[4*8+y]=B-O}for(let x=0;x<64;++x)i[x]=$e.dctClip[s+128+E.shiftR(n[x]+8,4)]}static getImageFromJpeg(e){let t=e.exifData.imageIfd.hasOrientation?e.exifData.imageIfd.orientation:0,i=t>=5&&t<=8,r=i?e.height:e.width,n=i?e.width:e.height,s=new W({width:r,height:n,rgbChannelSet:0});s.exifData=Ae.from(e.exifData),s.exifData.imageIfd.orientation=void 0;let a,o,u,l,h,f,c,p,g=0,b=0,x=0,y=0,P=0,w=0,M=0,B=0,O=0,R=0,N=0,L=!1,D=e.height-1,k=e.width-1;switch(e.components.length){case 1:{let Y=e.components[0],Z=Y.lines,j=Y.hScaleShift,X=Y.vScaleShift;for(let $=0;$>X,Re=Z[Ge];for(let be=0;be>j,H=Re[ee],Q=d.getColor(H,H,H);t===2?s.setPixel(k-be,$,Q):t===3?s.setPixel(k-be,D-$,Q):t===4?s.setPixel(be,D-$,Q):t===5?s.setPixel($,be,Q):t===6?s.setPixel(D-$,be,Q):t===7?s.setPixel(D-$,k-be,Q):t===8?s.setPixel($,k-be,Q):s.setPixelByIndex(g++,Q)}}break}case 3:{L=!0,a=e.components[0],o=e.components[1],u=e.components[2];let Y=a.lines,Z=o.lines,j=u.lines,X=a.hScaleShift,$=a.vScaleShift,Ge=o.hScaleShift,Re=o.vScaleShift,be=u.hScaleShift,ee=u.vScaleShift;for(let H=0;H>$,Be=H>>Re,we=H>>ee;h=Y[Q],f=Z[Be],c=j[we];for(let Te=0;Te>X,qr=Te>>Ge,Zr=Te>>be;b=h[Xr]<<8,x=f[qr]-128,y=c[Zr]-128,O=b+359*y+128,R=b-88*x-183*y+128,N=b+454*x+128,O=this.clamp8(E.shiftR(O,8)),R=this.clamp8(E.shiftR(R,8)),N=this.clamp8(E.shiftR(N,8));let me=d.getColor(O,R,N);t===2?s.setPixel(k-Te,H,me):t===3?s.setPixel(k-Te,D-H,me):t===4?s.setPixel(Te,D-H,me):t===5?s.setPixel(H,Te,me):t===6?s.setPixel(D-H,Te,me):t===7?s.setPixel(D-H,k-Te,me):t===8?s.setPixel(H,k-Te,me):s.setPixelByIndex(g++,me)}}break}case 4:{if(e.adobe===void 0)throw new T("Unsupported color mode (4 components)");L=!1,e.adobe.transformCode!==0&&(L=!0),a=e.components[0],o=e.components[1],u=e.components[2],l=e.components[3];let Y=a.lines,Z=o.lines,j=u.lines,X=l.lines,$=a.hScaleShift,Ge=a.vScaleShift,Re=o.hScaleShift,be=o.vScaleShift,ee=u.hScaleShift,H=u.vScaleShift,Q=l.hScaleShift,Be=l.vScaleShift;for(let we=0;we>Ge,Xr=we>>be,qr=we>>H,Zr=we>>Be;h=Y[Te],f=Z[Xr],c=j[qr],p=X[Zr];for(let me=0;me>$,wn=me>>Re,In=me>>ee,Bt=me>>Q;L?(b=h[_n],x=f[wn],y=c[In],P=p[Bt],w=255-this.clamp8(Math.trunc(b+1.402*(y-128))),M=255-this.clamp8(Math.trunc(b-.3441363*(x-128)-.71413636*(y-128))),B=255-this.clamp8(Math.trunc(b+1.772*(x-128)))):(w=h[_n],M=f[wn],B=c[In],P=p[Bt]),O=E.shiftR(w*P,8),R=E.shiftR(M*P,8),N=E.shiftR(B*P,8);let mt=d.getColor(O,R,N);t===2?s.setPixel(k-me,we,mt):t===3?s.setPixel(k-me,D-we,mt):t===4?s.setPixel(me,D-we,mt):t===5?s.setPixel(we,me,mt):t===6?s.setPixel(D-we,me,mt):t===7?s.setPixel(D-we,k-me,mt):t===8?s.setPixel(we,k-me,mt):s.setPixelByIndex(g++,mt)}}break}default:throw new T("Unsupported color mode")}return s}}});var yr,_r=C(()=>{"use strict";ue();Dt();yr=class{constructor(e,t,i,r,n,s,a,o){this._bitsData=0;this._bitsCount=0;this._eobrun=0;this._successiveACState=0;this._successiveACNextValue=0;this._input=e,this._frame=t,this._precision=t.precision,this._samplesPerLine=t.samplesPerLine,this._scanLines=t.scanLines,this._mcusPerLine=t.mcusPerLine,this._progressive=t.progressive,this._maxH=t.maxHSamples,this._maxV=t.maxVSamples,this._components=i,this._resetInterval=o,this._spectralStart=r,this._spectralEnd=n,this._successivePrev=s,this._successive=a}get input(){return this._input}get frame(){return this._frame}get precision(){return this._precision}get samplesPerLine(){return this._samplesPerLine}get scanLines(){return this._scanLines}get mcusPerLine(){return this._mcusPerLine}get progressive(){return this._progressive}get maxH(){return this._maxH}get maxV(){return this._maxV}get components(){return this._components}get resetInterval(){return this._resetInterval}get spectralStart(){return this._spectralStart}get spectralEnd(){return this._spectralEnd}get successivePrev(){return this._successivePrev}get successive(){return this._successive}get bitsData(){return this._bitsData}get bitsCount(){return this._bitsCount}get eobrun(){return this._eobrun}get successiveACState(){return this._successiveACState}get successiveACNextValue(){return this._successiveACNextValue}readBit(){if(this.bitsCount>0)return this._bitsCount--,this._bitsData>>this._bitsCount&1;if(!this._input.isEOS){if(this._bitsData=this._input.readByte(),this._bitsData===255){let e=this.input.readByte();if(e!==0)throw new T(`unexpected marker: ${(this._bitsData<<8|e).toString(16)}`)}return this._bitsCount=7,this._bitsData>>7&1}}decodeHuffman(e){let t=e,i;for(;(i=this.readBit())!==void 0;)if(t=t[i],typeof t=="number")return Math.trunc(t)}receive(e){let t=0,i=e;for(;i>0;){let r=this.readBit();if(r===void 0)return;t=t<<1|r,i--}return t}receiveAndExtend(e){if(e===1)return this.readBit()===1?1:-1;let t=this.receive(e);return t>=1<<(e!=null?e:0)-1?t:t+(-1<<(e!=null?e:0))+1}decodeBaseline(e,t){let i=this.decodeHuffman(e.huffmanTableDC),r=i===0?0:this.receiveAndExtend(i);e.pred+=r,t[0]=e.pred;let n=1;for(;n<64;){let s=this.decodeHuffman(e.huffmanTableAC),a=s&15,o=s>>4;if(a===0){if(o<15)break;n+=16;continue}n+=o,a=this.receiveAndExtend(a);let u=A.dctZigZag[n];t[u]=a,n++}}decodeDCFirst(e,t){let i=this.decodeHuffman(e.huffmanTableDC),r=i===0?0:this.receiveAndExtend(i)<0){this._eobrun--;return}let i=this._spectralStart,r=this._spectralEnd;for(;i<=r;){let n=this.decodeHuffman(e.huffmanTableAC),s=n&15,a=n>>4;if(s===0){if(a<15){this._eobrun=this.receive(a)+(1<>4,n===0)s<15?(this._eobrun=this.receive(s)+(1<=e.blocks.length)return;let l=e.blocks[o].length;u>=l||t.call(this,e,e.blocks[o][u])}decodeBlock(e,t,i){let r=Math.floor(i/e.blocksPerLine),n=i%e.blocksPerLine;t.call(this,e,e.blocks[r][n])}decode(){let e=this._components.length,t,i;this._progressive?this._spectralStart===0?i=this._successivePrev===0?this.decodeDCFirst:this.decodeDCSuccessive:i=this._successivePrev===0?this.decodeACFirst:this.decodeACSuccessive:i=this.decodeBaseline;let r=0,n;e===1?n=this._components[0].blocksPerLine*this._components[0].blocksPerColumn:n=this._mcusPerLine*this._frame.mcusPerColumn,(this._resetInterval===void 0||this._resetInterval===0)&&(this._resetInterval=n);let s,a;for(;r=A.M_RST0&&u<=A.M_RST7)this._input.skip(2);else break}}}});var Dn,ot,wr=C(()=>{"use strict";He();ue();or();Dt();lr();fr();cr();dr();pr();gr();xr();_r();wt();Dn=class{constructor(){this._exifData=new Ae;this._quantizationTables=new Array(A.NUM_QUANT_TBLS);this._frames=new Array;this._huffmanTablesAC=new Array;this._huffmanTablesDC=new Array;this._components=new Array}get input(){return this._input}get jfif(){return this._jfif}get adobe(){return this._adobe}get frame(){return this._frame}get resetInterval(){return this._resetInterval}get comment(){return this._comment}get exifData(){return this._exifData}get quantizationTables(){return this._quantizationTables}get frames(){return this._frames}get huffmanTablesAC(){return this._huffmanTablesAC}get huffmanTablesDC(){return this._huffmanTablesDC}get components(){return this._components}get width(){return this._frame.samplesPerLine}get height(){return this._frame.scanLines}readMarkers(){let e=this.nextMarker();if(e!==A.M_SOI)throw new T("Start Of Image marker not found.");for(e=this.nextMarker();e!==A.M_EOI&&!this._input.isEOS;){let t=this.readBlock();switch(e){case A.M_APP0:case A.M_APP1:case A.M_APP2:case A.M_APP3:case A.M_APP4:case A.M_APP5:case A.M_APP6:case A.M_APP7:case A.M_APP8:case A.M_APP9:case A.M_APP10:case A.M_APP11:case A.M_APP12:case A.M_APP13:case A.M_APP14:case A.M_APP15:case A.M_COM:this.readAppData(e,t);break;case A.M_DQT:this.readDQT(t);break;case A.M_SOF0:case A.M_SOF1:case A.M_SOF2:this.readFrame(e,t);break;case A.M_SOF3:case A.M_SOF5:case A.M_SOF6:case A.M_SOF7:case A.M_JPG:case A.M_SOF9:case A.M_SOF10:case A.M_SOF11:case A.M_SOF13:case A.M_SOF14:case A.M_SOF15:throw new T(`Unhandled frame type ${e.toString(16)}`);case A.M_DHT:this.readDHT(t);break;case A.M_DRI:this.readDRI(t);break;case A.M_SOS:this.readSOS(t);break;case 255:this._input.getByte(0)!==255&&this._input.skip(-1);break;default:if(this._input.getByte(-3)===255&&this._input.getByte(-2)>=192&&this._input.getByte(-2)<=254){this._input.skip(-3);break}if(e!==0)throw new T(`Unknown JPEG marker ${e.toString(16)}`);break}e=this.nextMarker()}}skipBlock(){let e=this._input.readUint16();if(e<2)throw new T("Invalid Block");this._input.skip(e-2)}validate(e){this._input=new G({buffer:e,bigEndian:!0});let t=this._input.peekBytes(2);if(t.getByte(0)!==255||t.getByte(1)!==216)return!1;let i=this.nextMarker();if(i!==A.M_SOI)return!1;let r=!1,n=!1;for(i=this.nextMarker();i!==A.M_EOI&&!this._input.isEOS;){let s=this._input.readUint16();if(s<2)break;switch(this._input.skip(s-2),i){case A.M_SOF0:case A.M_SOF1:case A.M_SOF2:r=!0;break;case A.M_SOS:n=!0;break;default:}i=this.nextMarker()}return r&&n}readInfo(e){this._input=new G({buffer:e,bigEndian:!0});let t=this.nextMarker();if(t!==A.M_SOI)return;let i=new mr,r=!1,n=!1;for(t=this.nextMarker();t!==A.M_EOI&&!this._input.isEOS;){switch(t){case A.M_SOF0:case A.M_SOF1:case A.M_SOF2:r=!0,this.readFrame(t,this.readBlock());break;case A.M_SOS:n=!0,this.skipBlock();break;default:this.skipBlock();break}t=this.nextMarker()}return this._frame!==void 0&&(i.setSize(this._frame.samplesPerLine,this._frame.scanLines),this._frame=void 0),this.frames.length=0,r&&n?i:void 0}read(e){if(this._input=new G({buffer:e,bigEndian:!0}),this.readMarkers(),this._frames.length!==1)throw new T("Only single frame JPEGs supported");if(this._frame!==void 0)for(let t=0;t0&&e[n-1]===0;)n--;r.push(new Nt);let s=r[0];for(let a=0;a0;)s=r.pop();for(s.incrementIndex(),r.push(s);r.length<=a;){let u=new Nt;r.push(u),s.children.length<=s.index&&(s.children.length=s.index+1),s.children[s.index]=u.children,s=u}i++}if(a+1>4;if(t&=15,t>=A.NUM_QUANT_TBLS)throw new T("Invalid number of quantization tables");this._quantizationTables[t]===void 0&&(this._quantizationTables[t]=new Int16Array(64));let r=this._quantizationTables[t];if(r!==void 0)for(let n=0;n>4&15,g=c&15,b=t.readByte();l.push(f);let x=new hr(p,g,this._quantizationTables,b);u.set(f,x)}this._frame=new Lt(u,l,i,r,n,s,a),this._frame.prepare(),this.frames.push(this._frame)}readDHT(e){for(;!e.isEOS;){let t=e.readByte(),i=new Uint8Array(16),r=0;for(let a=0;a<16;a++)i[a]=e.readByte(),r+=i[a];let n=new Uint8Array(r);for(let a=0;aA.MAX_COMPS_IN_SCAN)throw new T("Invalid SOS block");let i=new Array;for(let l=0;l>4&15,g=f&15;p>4&15,o=s&15;new yr(this._input,this._frame,i,r,n,a,o,this._resetInterval).decode()}},ot=Dn;ot.CRR=[-179,-178,-177,-175,-174,-172,-171,-170,-168,-167,-165,-164,-163,-161,-160,-158,-157,-156,-154,-153,-151,-150,-149,-147,-146,-144,-143,-142,-140,-139,-137,-136,-135,-133,-132,-130,-129,-128,-126,-125,-123,-122,-121,-119,-118,-116,-115,-114,-112,-111,-109,-108,-107,-105,-104,-102,-101,-100,-98,-97,-95,-94,-93,-91,-90,-88,-87,-86,-84,-83,-81,-80,-79,-77,-76,-74,-73,-72,-70,-69,-67,-66,-64,-63,-62,-60,-59,-57,-56,-55,-53,-52,-50,-49,-48,-46,-45,-43,-42,-41,-39,-38,-36,-35,-34,-32,-31,-29,-28,-27,-25,-24,-22,-21,-20,-18,-17,-15,-14,-13,-11,-10,-8,-7,-6,-4,-3,-1,0,1,3,4,6,7,8,10,11,13,14,15,17,18,20,21,22,24,25,27,28,29,31,32,34,35,36,38,39,41,42,43,45,46,48,49,50,52,53,55,56,57,59,60,62,63,64,66,67,69,70,72,73,74,76,77,79,80,81,83,84,86,87,88,90,91,93,94,95,97,98,100,101,102,104,105,107,108,109,111,112,114,115,116,118,119,121,122,123,125,126,128,129,130,132,133,135,136,137,139,140,142,143,144,146,147,149,150,151,153,154,156,157,158,160,161,163,164,165,167,168,170,171,172,174,175,177,178],ot.CRG=[5990656,5943854,5897052,5850250,5803448,5756646,5709844,5663042,5616240,5569438,5522636,5475834,5429032,5382230,5335428,5288626,5241824,5195022,5148220,5101418,5054616,5007814,4961012,4914210,4867408,4820606,4773804,4727002,4680200,4633398,4586596,4539794,4492992,4446190,4399388,4352586,4305784,4258982,4212180,4165378,4118576,4071774,4024972,3978170,3931368,3884566,3837764,3790962,3744160,3697358,3650556,3603754,3556952,3510150,3463348,3416546,3369744,3322942,3276140,3229338,3182536,3135734,3088932,3042130,2995328,2948526,2901724,2854922,2808120,2761318,2714516,2667714,2620912,2574110,2527308,2480506,2433704,2386902,2340100,2293298,2246496,2199694,2152892,2106090,2059288,2012486,1965684,1918882,1872080,1825278,1778476,1731674,1684872,1638070,1591268,1544466,1497664,1450862,1404060,1357258,1310456,1263654,1216852,1170050,1123248,1076446,1029644,982842,936040,889238,842436,795634,748832,702030,655228,608426,561624,514822,468020,421218,374416,327614,280812,234010,187208,140406,93604,46802,0,-46802,-93604,-140406,-187208,-234010,-280812,-327614,-374416,-421218,-468020,-514822,-561624,-608426,-655228,-702030,-748832,-795634,-842436,-889238,-936040,-982842,-1029644,-1076446,-1123248,-1170050,-1216852,-1263654,-1310456,-1357258,-1404060,-1450862,-1497664,-1544466,-1591268,-1638070,-1684872,-1731674,-1778476,-1825278,-1872080,-1918882,-1965684,-2012486,-2059288,-2106090,-2152892,-2199694,-2246496,-2293298,-2340100,-2386902,-2433704,-2480506,-2527308,-2574110,-2620912,-2667714,-2714516,-2761318,-2808120,-2854922,-2901724,-2948526,-2995328,-3042130,-3088932,-3135734,-3182536,-3229338,-3276140,-3322942,-3369744,-3416546,-3463348,-3510150,-3556952,-3603754,-3650556,-3697358,-3744160,-3790962,-3837764,-3884566,-3931368,-3978170,-4024972,-4071774,-4118576,-4165378,-4212180,-4258982,-4305784,-4352586,-4399388,-4446190,-4492992,-4539794,-4586596,-4633398,-4680200,-4727002,-4773804,-4820606,-4867408,-4914210,-4961012,-5007814,-5054616,-5101418,-5148220,-5195022,-5241824,-5288626,-5335428,-5382230,-5429032,-5475834,-5522636,-5569438,-5616240,-5663042,-5709844,-5756646,-5803448,-5850250,-5897052,-5943854],ot.CBG=[2919680,2897126,2874572,2852018,2829464,2806910,2784356,2761802,2739248,2716694,2694140,2671586,2649032,2626478,2603924,2581370,2558816,2536262,2513708,2491154,2468600,2446046,2423492,2400938,2378384,2355830,2333276,2310722,2288168,2265614,2243060,2220506,2197952,2175398,2152844,2130290,2107736,2085182,2062628,2040074,2017520,1994966,1972412,1949858,1927304,1904750,1882196,1859642,1837088,1814534,1791980,1769426,1746872,1724318,1701764,1679210,1656656,1634102,1611548,1588994,1566440,1543886,1521332,1498778,1476224,1453670,1431116,1408562,1386008,1363454,1340900,1318346,1295792,1273238,1250684,1228130,1205576,1183022,1160468,1137914,1115360,1092806,1070252,1047698,1025144,1002590,980036,957482,934928,912374,889820,867266,844712,822158,799604,777050,754496,731942,709388,686834,664280,641726,619172,596618,574064,551510,528956,506402,483848,461294,438740,416186,393632,371078,348524,325970,303416,280862,258308,235754,213200,190646,168092,145538,122984,100430,77876,55322,32768,10214,-12340,-34894,-57448,-80002,-102556,-125110,-147664,-170218,-192772,-215326,-237880,-260434,-282988,-305542,-328096,-350650,-373204,-395758,-418312,-440866,-463420,-485974,-508528,-531082,-553636,-576190,-598744,-621298,-643852,-666406,-688960,-711514,-734068,-756622,-779176,-801730,-824284,-846838,-869392,-891946,-914500,-937054,-959608,-982162,-1004716,-1027270,-1049824,-1072378,-1094932,-1117486,-1140040,-1162594,-1185148,-1207702,-1230256,-1252810,-1275364,-1297918,-1320472,-1343026,-1365580,-1388134,-1410688,-1433242,-1455796,-1478350,-1500904,-1523458,-1546012,-1568566,-1591120,-1613674,-1636228,-1658782,-1681336,-1703890,-1726444,-1748998,-1771552,-1794106,-1816660,-1839214,-1861768,-1884322,-1906876,-1929430,-1951984,-1974538,-1997092,-2019646,-2042200,-2064754,-2087308,-2109862,-2132416,-2154970,-2177524,-2200078,-2222632,-2245186,-2267740,-2290294,-2312848,-2335402,-2357956,-2380510,-2403064,-2425618,-2448172,-2470726,-2493280,-2515834,-2538388,-2560942,-2583496,-2606050,-2628604,-2651158,-2673712,-2696266,-2718820,-2741374,-2763928,-2786482,-2809036,-2831590],ot.CBB=[-227,-225,-223,-222,-220,-218,-216,-214,-213,-211,-209,-207,-206,-204,-202,-200,-198,-197,-195,-193,-191,-190,-188,-186,-184,-183,-181,-179,-177,-175,-174,-172,-170,-168,-167,-165,-163,-161,-159,-158,-156,-154,-152,-151,-149,-147,-145,-144,-142,-140,-138,-136,-135,-133,-131,-129,-128,-126,-124,-122,-120,-119,-117,-115,-113,-112,-110,-108,-106,-105,-103,-101,-99,-97,-96,-94,-92,-90,-89,-87,-85,-83,-82,-80,-78,-76,-74,-73,-71,-69,-67,-66,-64,-62,-60,-58,-57,-55,-53,-51,-50,-48,-46,-44,-43,-41,-39,-37,-35,-34,-32,-30,-28,-27,-25,-23,-21,-19,-18,-16,-14,-12,-11,-9,-7,-5,-4,-2,0,2,4,5,7,9,11,12,14,16,18,19,21,23,25,27,28,30,32,34,35,37,39,41,43,44,46,48,50,51,53,55,57,58,60,62,64,66,67,69,71,73,74,76,78,80,82,83,85,87,89,90,92,94,96,97,99,101,103,105,106,108,110,112,113,115,117,119,120,122,124,126,128,129,131,133,135,136,138,140,142,144,145,147,149,151,152,154,156,158,159,161,163,165,167,168,170,172,174,175,177,179,181,183,184,186,188,190,191,193,195,197,198,200,202,204,206,207,209,211,213,214,216,218,220,222,223,225]});var Ii,Ai=C(()=>{"use strict";bt();He();ue();ft();wr();Ii=class{get numFrames(){return this.info!==void 0?this.info.numFrames:0}isValidFile(e){return new ot().validate(e)}startDecode(e){return this.input=new G({buffer:e,bigEndian:!0}),this.info=new ot().readInfo(e),this.info}decodeFrame(e){if(this.input===void 0)return;let t=new ot;if(t.read(this.input.buffer),t.frames.length!==1)throw new T("only single frame JPEGs supported");return t.getImage()}decodeHdrFrame(e){let t=this.decodeFrame(e);if(t!==void 0)return de.fromImage(t)}decodeAnimation(e){let t=this.decodeImage(e);if(t===void 0)return;let i=new Xe({width:t.width,height:t.height});return i.addFrame(t),i}decodeImage(e,t){let i=new ot;if(i.read(e),i.frames.length!==1)throw new T("only single frame JPEGs supported");return i.getImage()}decodeHdrImage(e,t=0){let i=this.decodeImage(e,t);if(i!==void 0)return de.fromImage(i)}}});var K,Ke,Ir=C(()=>{"use strict";Qe();st();Dt();K=class{constructor(e=100){this.tableY=new Uint8Array(64);this.tableUV=new Uint8Array(64);this.ftableY=new Float32Array(64);this.ftableUV=new Float32Array(64);this.bitcode=new Array(65535).fill(void 0);this.category=new Array(65535).fill(void 0);this.outputfDCTQuant=new Array(64).fill(void 0);this.DU=new Array(64).fill(void 0);this.YDU=new Float32Array(64);this.UDU=new Float32Array(64);this.VDU=new Float32Array(64);this.tableRGBYUV=new Int32Array(2048);this.byteNew=0;this.bytePos=7;this._supportsAnimation=!1;this.initHuffmanTable(),this.initCategoryNumber(),this.initRGBYUVTable(),this.setQuality(e)}get supportsAnimation(){return this._supportsAnimation}static computeHuffmanTable(e,t){let i=0,r=0,n=new Array;for(let s=1;s<=16;s++){for(let a=1;a<=e[s];a++){let o=t[r];n.length<=o&&(n.length=o+1),n[o]=[i,s],r++,i++}i*=2}return n}static writeMarker(e,t){e.writeByte(255),e.writeByte(t&255)}static writeAPP0(e){K.writeMarker(e,A.M_APP0),e.writeUint16(16),e.writeByte(74),e.writeByte(70),e.writeByte(73),e.writeByte(70),e.writeByte(0),e.writeByte(1),e.writeByte(1),e.writeByte(0),e.writeUint16(1),e.writeUint16(1),e.writeByte(0),e.writeByte(0)}static writeAPP1(e,t){if(t.isEmpty)return;let i=new he;t.write(i);let r=i.getBytes();this.writeMarker(e,A.M_APP1),e.writeUint16(r.length+8);let n=1165519206;e.writeUint32(n),e.writeUint16(0),e.writeBytes(r)}static writeSOF0(e,t,i){K.writeMarker(e,A.M_SOF0),e.writeUint16(17),e.writeByte(8),e.writeUint16(i),e.writeUint16(t),e.writeByte(3),e.writeByte(1),e.writeByte(17),e.writeByte(0),e.writeByte(2),e.writeByte(17),e.writeByte(1),e.writeByte(3),e.writeByte(17),e.writeByte(1)}static writeSOS(e){K.writeMarker(e,A.M_SOS),e.writeUint16(12),e.writeByte(3),e.writeByte(1),e.writeByte(0),e.writeByte(2),e.writeByte(17),e.writeByte(3),e.writeByte(17),e.writeByte(0),e.writeByte(63),e.writeByte(0)}static writeDHT(e){K.writeMarker(e,A.M_DHT),e.writeUint16(418),e.writeByte(0);for(let t=0;t<16;t++)e.writeByte(K.STD_DC_LUMINANCE_NR_CODES[t+1]);for(let t=0;t<=11;t++)e.writeByte(K.STD_DC_LUMINANCE_VALUES[t]);e.writeByte(16);for(let t=0;t<16;t++)e.writeByte(K.STD_AC_LUMINANCE_NR_CODES[t+1]);for(let t=0;t<=161;t++)e.writeByte(K.STD_AC_LUMINANCE_VALUES[t]);e.writeByte(1);for(let t=0;t<16;t++)e.writeByte(K.STD_DC_CHROMINANCE_NR_CODES[t+1]);for(let t=0;t<=11;t++)e.writeByte(K.STD_DC_CHROMINANCE_VALUES[t]);e.writeByte(17);for(let t=0;t<16;t++)e.writeByte(K.STD_AC_CHROMINANCE_NR_CODES[t+1]);for(let t=0;t<=161;t++)e.writeByte(K.STD_AC_CHROMINANCE_VALUES[t])}initHuffmanTable(){this.htYDC=K.computeHuffmanTable(K.STD_DC_LUMINANCE_NR_CODES,K.STD_DC_LUMINANCE_VALUES),this.htUVDC=K.computeHuffmanTable(K.STD_DC_CHROMINANCE_NR_CODES,K.STD_DC_CHROMINANCE_VALUES),this.htYAC=K.computeHuffmanTable(K.STD_AC_LUMINANCE_NR_CODES,K.STD_AC_LUMINANCE_VALUES),this.htUVAC=K.computeHuffmanTable(K.STD_AC_CHROMINANCE_NR_CODES,K.STD_AC_CHROMINANCE_VALUES)}initCategoryNumber(){let e=1,t=2;for(let i=1;i<=15;i++){for(let r=e;r255&&(a=255),this.tableY[K.ZIGZAG[s]]=a}let i=[17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99];for(let s=0;s<64;s++){let a=Math.floor((i[s]*e+50)/100);a<1?a=1:a>255&&(a=255),this.tableUV[K.ZIGZAG[s]]=a}let r=[1,1.387039845,1.306562965,1.175875602,1,.785694958,.5411961,.275899379],n=0;for(let s=0;s<8;s++)for(let a=0;a<8;a++)this.ftableY[n]=1/(this.tableY[K.ZIGZAG[n]]*r[s]*r[a]*8),this.ftableUV[n]=1/(this.tableUV[K.ZIGZAG[n]]*r[s]*r[a]*8),n++}fDCTQuant(e,t){let i=0,r=8,n=64;for(let s=0;s0?Math.trunc(a+.5):Math.trunc(a-.5)}return this.outputfDCTQuant}writeDQT(e){K.writeMarker(e,A.M_DQT),e.writeUint16(132),e.writeByte(0);for(let t=0;t<64;t++)e.writeByte(this.tableY[t]);e.writeByte(1);for(let t=0;t<64;t++)e.writeByte(this.tableUV[t])}writeBits(e,t){let i=t[0],r=t[1]-1;for(;r>=0;)(i&1<0&&this.DU[b]===0;b--);if(b===0)return this.writeBits(e,a),c;let x=1;for(;x<=b;){let y=x;for(;this.DU[x]===0&&x<=b;++x);let P=x-y;if(P>=u){let w=P>>4;for(let M=1;M<=w;++M)this.writeBits(e,o);P&=15}p=32767+this.DU[x],this.writeBits(e,n[(P<<4)+this.category[p]]),this.writeBits(e,this.bitcode[p]),x++}return b!==l&&this.writeBits(e,a),c}encodeImage(e){let t=new he({bigEndian:!0});K.writeMarker(t,A.M_SOI),K.writeAPP0(t),K.writeAPP1(t,e.exifData),this.writeDQT(t),K.writeSOF0(t,e.width,e.height),K.writeDHT(t),K.writeSOS(t);let i=0,r=0,n=0;this.resetBits();let s=e.width,a=e.height,o=e.getBytes(),u=s*4,l=0;for(;l>3,g=(c&7)*4,b=f+p*u+g;l+p>=a&&(b-=u*(l+1+p-a)),h+g>=u&&(b-=h+g-u+4);let x=o[b++],y=o[b++],P=o[b++];this.YDU[c]=(this.tableRGBYUV[x]+this.tableRGBYUV[y+256]+this.tableRGBYUV[P+512]>>16)-128,this.UDU[c]=(this.tableRGBYUV[x+768]+this.tableRGBYUV[y+1024]+this.tableRGBYUV[P+1280]>>16)-128,this.VDU[c]=(this.tableRGBYUV[x+1280]+this.tableRGBYUV[y+1536]+this.tableRGBYUV[P+1792]>>16)-128}i=this.processDU(t,this.YDU,this.ftableY,i,this.htYAC,this.htYDC),r=this.processDU(t,this.UDU,this.ftableUV,r,this.htUVAC,this.htUVDC),n=this.processDU(t,this.VDU,this.ftableUV,n,this.htUVAC,this.htUVDC),h+=32}l+=8}if(this.bytePos>=0){let h=[(1<{"use strict"});var vr=C(()=>{"use strict";ge();bt();He();Ye();Ve();ft();Ar()});var Pr=C(()=>{"use strict";ge();st();Ve()});var Ln,vi,Sr=C(()=>{"use strict";Ln=class{constructor(e){this.bitBuffer=0;this.bitPosition=0;this.input=e}readBits(e){let t=e;if(t===0)return 0;this.bitPosition===0&&(this.bitPosition=8,this.bitBuffer=this.input.readByte());let i=0;for(;t>this.bitPosition;)i=(i<0&&(this.bitPosition===0&&(this.bitPosition=8,this.bitBuffer=this.input.readByte()),i=(i<>this.bitPosition-t&Ln.BITMASK[t]),this.bitPosition-=t),i}readByte(){return this.readBits(8)}flushByte(){return this.bitPosition=0}},vi=Ln;vi.BITMASK=[0,1,3,7,15,31,63,127,255]});var pe,_e,Pi=C(()=>{"use strict";ue();kt();pe=class{get tag(){return this._tag}get type(){return this._type}get numValues(){return this._numValues}get valueOffset(){return this._valueOffset}set valueOffset(e){this._valueOffset=e}get p(){return this._p}get isValid(){return this._type<13&&this._type>0}get typeSize(){return this.isValid?pe.SIZE_OF_TYPE[this._type]:0}get isString(){return this._type===pe.TYPE_ASCII}constructor(e){this._tag=e.tag,this._type=e.type,this._numValues=e.numValues,this._p=e.p}readValueInternal(){switch(this._type){case pe.TYPE_BYTE:case pe.TYPE_ASCII:return this._p.readByte();case pe.TYPE_SHORT:return this._p.readUint16();case pe.TYPE_LONG:return this._p.readUint32();case pe.TYPE_RATIONAL:{let e=this._p.readUint32(),t=this._p.readUint32();return t===0?0:Math.trunc(e/t)}case pe.TYPE_SBYTE:throw new T("Unhandled value type: SBYTE");case pe.TYPE_UNDEFINED:return this._p.readByte();case pe.TYPE_SSHORT:throw new T("Unhandled value type: SSHORT");case pe.TYPE_SLONG:throw new T("Unhandled value type: SLONG");case pe.TYPE_SRATIONAL:throw new T("Unhandled value type: SRATIONAL");case pe.TYPE_FLOAT:throw new T("Unhandled value type: FLOAT");case pe.TYPE_DOUBLE:throw new T("Unhandled value type: DOUBLE")}return 0}toString(){return S.TAG_NAME.has(this._tag)?`${S.TAG_NAME.get(this._tag)}: $type $numValues`:`<${this._tag}>: ${this._type} ${this._numValues}`}readValue(){return this._p.offset=this._valueOffset,this.readValueInternal()}readValues(){this._p.offset=this._valueOffset;let e=[];for(let t=0;t{"use strict";ue();oe=class{constructor(e){this.changingElemSize=0;this.bitPointer=0;this.bytePointer=0;this.lastChangingElement=0;this.compression=2;this.uncompressedMode=0;this.fillBits=0;this.oneD=0;this._fillOrder=e.fillOrder,this._width=e.width,this._height=e.height,this.prevChangingElems=new Array(this._width),this.prevChangingElems.fill(0),this.currChangingElems=new Array(this._width),this.currChangingElems.fill(0)}get width(){return this._width}get height(){return this._height}get fillOrder(){return this._fillOrder}nextNBits(e){let t=0,i=0,r=0,n=this.data.length-1,s=this.bytePointer;if(this._fillOrder===1)t=this.data.getByte(s),s===n?(i=0,r=0):s+1===n?(i=this.data.getByte(s+1),r=0):(i=this.data.getByte(s+1),r=this.data.getByte(s+2));else if(this._fillOrder===2)t=oe.FLIP_TABLE[this.data.getByte(s)&255],s===n?(i=0,r=0):s+1===n?(i=oe.FLIP_TABLE[this.data.getByte(s+1)&255],r=0):(i=oe.FLIP_TABLE[this.data.getByte(s+1)&255],r=oe.FLIP_TABLE[this.data.getByte(s+2)&255]);else throw new T("TIFFFaxDecoder7");let a=8-this.bitPointer,o=e-a,u=0;o>8&&(u=o-8,o=8),this.bytePointer=this.bytePointer+1;let l=(t&oe.TABLE1[a])<>8-o,f=0;return u!==0?(h<<=u,f=(r&oe.TABLE2[u])>>8-u,h|=f,this.bytePointer+=1,this.bitPointer=u):o===8?(this.bitPointer=0,this.bytePointer+=1):this.bitPointer=o,l|h}nextLesserThan8Bits(e){let t=0,i=0,r=this.data.length-1,n=this.bytePointer;if(this._fillOrder===1)t=this.data.getByte(n),n===r?i=0:i=this.data.getByte(n+1);else if(this._fillOrder===2)t=oe.FLIP_TABLE[this.data.getByte(n)&255],n===r?i=0:i=oe.FLIP_TABLE[this.data.getByte(n+1)&255];else throw new T("TIFFFaxDecoder7");let s=8-this.bitPointer,a=e-s,o=s-e,u=0,l=0;return o>=0?(u=(t&oe.TABLE1[s])>>o,this.bitPointer+=e,this.bitPointer===8&&(this.bitPointer=0,this.bytePointer+=1)):(u=(t&oe.TABLE1[s])<<-o,l=(i&oe.TABLE2[a])>>8-a,u|=l,this.bytePointer+=1,this.bitPointer=a),u}updatePointer(e){let t=this.bitPointer-e;t<0?(this.bytePointer-=1,this.bitPointer=8+t):this.bitPointer=t}advancePointer(){return this.bitPointer!==0&&(this.bytePointer+=1,this.bitPointer=0),!0}setToBlack(e,t,i,r){let n=8*t+i,s=n+r,a=n>>3,o=n&7;if(o>0){let u=1<<7-o,l=e.getByte(a);for(;u>0&&n>=1,++n;e.setByte(a,l)}for(a=n>>3;n>3,e.setByte(a,e.getByte(a)|1<<7-(n&7)),++n}decodeNextScanline(e,t,i){let r=i,n=0,s=0,a=0,o=0,u=0,l=0,h=!0;for(this.changingElemSize=0;r>1&15,n===12)l=this.nextLesserThan8Bits(2),o=o<<2&12|l,u=oe.ADDITIONAL_MAKEUP[o],n=u>>1&7,s=u>>4&4095,r+=s,this.updatePointer(4-n);else{if(n===0)throw new T("TIFFFaxDecoder0");if(n===15)throw new T("TIFFFaxDecoder1");s=u>>5&2047,r+=s,this.updatePointer(10-n),a===0&&(h=!1,this.currChangingElems[this.changingElemSize++]=r)}if(r===this._width){this.compression===2&&this.advancePointer();break}for(;h===!1;)if(o=this.nextLesserThan8Bits(4),u=oe.INIT_BLACK[o],a=u&1,n=u>>1&15,s=u>>5&2047,s===100)if(o=this.nextNBits(9),u=oe.BLACK[o],a=u&1,n=u>>1&15,s=u>>5&2047,n===12)this.updatePointer(5),o=this.nextLesserThan8Bits(4),u=oe.ADDITIONAL_MAKEUP[o],n=u>>1&7,s=u>>4&4095,this.setToBlack(e,t,r,s),r+=s,this.updatePointer(4-n);else{if(n===15)throw new T("TIFFFaxDecoder2");this.setToBlack(e,t,r,s),r+=s,this.updatePointer(9-n),a===0&&(h=!0,this.currChangingElems[this.changingElemSize++]=r)}else s===200?(o=this.nextLesserThan8Bits(2),u=oe.TWO_BIT_BLACK[o],s=u>>5&2047,n=u>>1&15,this.setToBlack(e,t,r,s),r+=s,this.updatePointer(2-n),h=!0,this.currChangingElems[this.changingElemSize++]=r):(this.setToBlack(e,t,r,s),r+=s,this.updatePointer(4-n),h=!0,this.currChangingElems[this.changingElemSize++]=r);if(r===this._width){this.compression===2&&this.advancePointer();break}}this.currChangingElems[this.changingElemSize++]=r}readEOL(){if(this.fillBits===0){if(this.nextNBits(12)!==1)throw new T("TIFFFaxDecoder6")}else if(this.fillBits===1){let e=8-this.bitPointer;if(this.nextNBits(e)!==0)throw new T("TIFFFaxDecoder8");if(e<4&&this.nextNBits(8)!==0)throw new T("TIFFFaxDecoder8");let t=0;for(;(t=this.nextNBits(8))!==1;)if(t!==0)throw new T("TIFFFaxDecoder8")}return this.oneD===0?1:this.nextLesserThan8Bits(1)}getNextChangingElement(e,t,i){let r=this.prevChangingElems,n=this.changingElemSize,s=this.lastChangingElement>0?this.lastChangingElement-1:0;t?s&=-2:s|=1;let a=s;for(;ae){this.lastChangingElement=a,i[0]=o;break}}a+1>1&15,i===12)n=this.nextLesserThan8Bits(2),e=e<<2&12|n,t=oe.ADDITIONAL_MAKEUP[e],i=t>>1&7,s=t>>4&4095,a+=s,this.updatePointer(4-i);else{if(i===0)throw new T("TIFFFaxDecoder0");if(i===15)throw new T("TIFFFaxDecoder1");s=t>>5&2047,a+=s,this.updatePointer(10-i),r===0&&(o=!1)}return a}decodeBlackCodeWord(){let e=0,t=0,i=0,r=0,n=-1,s=0,a=!1;for(;!a;)if(e=this.nextLesserThan8Bits(4),t=oe.INIT_BLACK[e],r=t&1,i=t>>1&15,n=t>>5&2047,n===100)if(e=this.nextNBits(9),t=oe.BLACK[e],r=t&1,i=t>>1&15,n=t>>5&2047,i===12)this.updatePointer(5),e=this.nextLesserThan8Bits(4),t=oe.ADDITIONAL_MAKEUP[e],i=t>>1&7,n=t>>4&4095,s+=n,this.updatePointer(4-i);else{if(i===15)throw new T("TIFFFaxDecoder2");s+=n,this.updatePointer(9-i),r===0&&(a=!0)}else n===200?(e=this.nextLesserThan8Bits(2),t=oe.TWO_BIT_BLACK[e],n=t>>5&2047,s+=n,i=t>>1&15,this.updatePointer(2-i),a=!0):(s+=n,this.updatePointer(4-i),a=!0);return s}decode1D(e,t,i,r){this.data=t,this.bitPointer=0,this.bytePointer=0;let n=0,s=Math.trunc((this._width+7)/8);for(let a=0;a>1,this.fillBits=(n&4)>>2,this.readEOL()!==1)throw new T("TIFFFaxDecoder3");let b=0,x=0;this.decodeNextScanline(e,b,i),b+=s;for(let y=1;y>3,h=u&7,l===0)f||this.setToBlack(e,b,x,w-x),a=w,x=a,this.updatePointer(7-h);else if(l===1){this.updatePointer(7-h);let M=0;f?(M=this.decodeWhiteCodeWord(),x+=M,this.currChangingElems[c++]=x,M=this.decodeBlackCodeWord(),this.setToBlack(e,b,x,M),x+=M,this.currChangingElems[c++]=x):(M=this.decodeBlackCodeWord(),this.setToBlack(e,b,x,M),x+=M,this.currChangingElems[c++]=x,M=this.decodeWhiteCodeWord(),x+=M,this.currChangingElems[c++]=x),a=x}else if(l<=8)o=P+(l-5),this.currChangingElems[c++]=o,f||this.setToBlack(e,b,x,o-x),a=o,x=a,f=!f,this.updatePointer(7-h);else throw new T("TIFFFaxDecoder4")}this.currChangingElems[c++]=x,this.changingElemSize=c}else this.decodeNextScanline(e,b,i);b+=s}}decodeT6(e,t,i,r,n){this.data=t,this.compression=4,this.bitPointer=0,this.bytePointer=0;let s=Math.trunc((this._width+7)/8),a=0,o=0,u=0,l=0,h=0,f=0,c=0,p=!1,g=0,b,x=new Array(2);x.fill(0),this.uncompressedMode=(n&2)>>1;let y=this.currChangingElems;this.changingElemSize=0,y[this.changingElemSize++]=this._width,y[this.changingElemSize++]=this._width;let P=0,w=0;for(let M=0;M>3,c=h&7,f===0)p||this.setToBlack(e,P,w,l-w),a=l,w=a,this.updatePointer(7-c);else if(f===1){this.updatePointer(7-c);let B=0;p?(B=this.decodeWhiteCodeWord(),w+=B,y[g++]=w,B=this.decodeBlackCodeWord(),this.setToBlack(e,P,w,B),w+=B,y[g++]=w):(B=this.decodeBlackCodeWord(),this.setToBlack(e,P,w,B),w+=B,y[g++]=w,B=this.decodeWhiteCodeWord(),w+=B,y[g++]=w),a=w}else if(f<=8)o=u+(f-5),y[g++]=o,p||this.setToBlack(e,P,w,o-w),a=o,w=a,p=!p,this.updatePointer(7-c);else if(f===11){if(this.nextLesserThan8Bits(3)!==7)throw new T("TIFFFaxDecoder5");let B=0,O=!1;for(;!O;){for(;this.nextLesserThan8Bits(1)!==1;)B++;B>5&&(B-=6,!p&&B>0&&(y[g++]=w),w+=B,B>0&&(p=!0),this.nextLesserThan8Bits(1)===0?(p||(y[g++]=w),p=!0):(p&&(y[g++]=w),p=!1),O=!0),B===5?(p||(y[g++]=w),w+=B,p=!0):(w+=B,y[g++]=w,this.setToBlack(e,P,w,1),++w,p=!1)}}else throw new T(`TIFFFaxDecoder5 ${f}`);y[g++]=w,this.changingElemSize=g,P+=s}}},Fe=oe;Fe.TABLE1=[0,1,3,7,15,31,63,127,255],Fe.TABLE2=[0,128,192,224,240,248,252,254,255],Fe.FLIP_TABLE=[0,-128,64,-64,32,-96,96,-32,16,-112,80,-48,48,-80,112,-16,8,-120,72,-56,40,-88,104,-24,24,-104,88,-40,56,-72,120,-8,4,-124,68,-60,36,-92,100,-28,20,-108,84,-44,52,-76,116,-12,12,-116,76,-52,44,-84,108,-20,28,-100,92,-36,60,-68,124,-4,2,-126,66,-62,34,-94,98,-30,18,-110,82,-46,50,-78,114,-14,10,-118,74,-54,42,-86,106,-22,26,-102,90,-38,58,-70,122,-6,6,-122,70,-58,38,-90,102,-26,22,-106,86,-42,54,-74,118,-10,14,-114,78,-50,46,-82,110,-18,30,-98,94,-34,62,-66,126,-2,1,-127,65,-63,33,-95,97,-31,17,-111,81,-47,49,-79,113,-15,9,-119,73,-55,41,-87,105,-23,25,-103,89,-39,57,-71,121,-7,5,-123,69,-59,37,-91,101,-27,21,-107,85,-43,53,-75,117,-11,13,-115,77,-51,45,-83,109,-19,29,-99,93,-35,61,-67,125,-3,3,-125,67,-61,35,-93,99,-29,19,-109,83,-45,51,-77,115,-13,11,-117,75,-53,43,-85,107,-21,27,-101,91,-37,59,-69,123,-5,7,-121,71,-57,39,-89,103,-25,23,-105,87,-41,55,-73,119,-9,15,-113,79,-49,47,-81,111,-17,31,-97,95,-33,63,-65,127,-1],Fe.WHITE=[6430,6400,6400,6400,3225,3225,3225,3225,944,944,944,944,976,976,976,976,1456,1456,1456,1456,1488,1488,1488,1488,718,718,718,718,718,718,718,718,750,750,750,750,750,750,750,750,1520,1520,1520,1520,1552,1552,1552,1552,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,654,654,654,654,654,654,654,654,1072,1072,1072,1072,1104,1104,1104,1104,1136,1136,1136,1136,1168,1168,1168,1168,1200,1200,1200,1200,1232,1232,1232,1232,622,622,622,622,622,622,622,622,1008,1008,1008,1008,1040,1040,1040,1040,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,1712,1712,1712,1712,1744,1744,1744,1744,846,846,846,846,846,846,846,846,1264,1264,1264,1264,1296,1296,1296,1296,1328,1328,1328,1328,1360,1360,1360,1360,1392,1392,1392,1392,1424,1424,1424,1424,686,686,686,686,686,686,686,686,910,910,910,910,910,910,910,910,1968,1968,1968,1968,2e3,2e3,2e3,2e3,2032,2032,2032,2032,16,16,16,16,10257,10257,10257,10257,12305,12305,12305,12305,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,878,878,878,878,878,878,878,878,1904,1904,1904,1904,1936,1936,1936,1936,-18413,-18413,-16365,-16365,-14317,-14317,-10221,-10221,590,590,590,590,590,590,590,590,782,782,782,782,782,782,782,782,1584,1584,1584,1584,1616,1616,1616,1616,1648,1648,1648,1648,1680,1680,1680,1680,814,814,814,814,814,814,814,814,1776,1776,1776,1776,1808,1808,1808,1808,1840,1840,1840,1840,1872,1872,1872,1872,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,14353,14353,14353,14353,16401,16401,16401,16401,22547,22547,24595,24595,20497,20497,20497,20497,18449,18449,18449,18449,26643,26643,28691,28691,30739,30739,-32749,-32749,-30701,-30701,-28653,-28653,-26605,-26605,-24557,-24557,-22509,-22509,-20461,-20461,8207,8207,8207,8207,8207,8207,8207,8207,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232],Fe.ADDITIONAL_MAKEUP=[28679,28679,31752,-32759,-31735,-30711,-29687,-28663,29703,29703,30727,30727,-27639,-26615,-25591,-24567],Fe.INIT_BLACK=[3226,6412,200,168,38,38,134,134,100,100,100,100,68,68,68,68],Fe.TWO_BIT_BLACK=[292,260,226,226],Fe.BLACK=[62,62,30,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,588,588,588,588,588,588,588,588,1680,1680,20499,22547,24595,26643,1776,1776,1808,1808,-24557,-22509,-20461,-18413,1904,1904,1936,1936,-16365,-14317,782,782,782,782,814,814,814,814,-12269,-10221,10257,10257,12305,12305,14353,14353,16403,18451,1712,1712,1744,1744,28691,30739,-32749,-30701,-28653,-26605,2061,2061,2061,2061,2061,2061,2061,2061,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,750,750,750,750,1616,1616,1648,1648,1424,1424,1456,1456,1488,1488,1520,1520,1840,1840,1872,1872,1968,1968,8209,8209,524,524,524,524,524,524,524,524,556,556,556,556,556,556,556,556,1552,1552,1584,1584,2e3,2e3,2032,2032,976,976,1008,1008,1040,1040,1072,1072,1296,1296,1328,1328,718,718,718,718,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,4113,4113,6161,6161,848,848,880,880,912,912,944,944,622,622,622,622,654,654,654,654,1104,1104,1136,1136,1168,1168,1200,1200,1232,1232,1264,1264,686,686,686,686,1360,1360,1392,1392,12,12,12,12,12,12,12,12,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390],Fe.TWO_D_CODES=[80,88,23,71,30,30,62,62,4,4,4,4,4,4,4,4,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41]});var Mr,It,Br=C(()=>{"use strict";ue();Mr=class{constructor(){this.buffer=new Uint8Array(4096);this.bitsToGet=9;this.bytePointer=0;this.nextData=0;this.nextBits=0}addString(e,t){this.table[this.tableIndex]=t,this.prefix[this.tableIndex]=e,this.tableIndex=this.tableIndex+1,this.tableIndex===511?this.bitsToGet=10:this.tableIndex===1023?this.bitsToGet=11:this.tableIndex===2047&&(this.bitsToGet=12)}getString(e){this.bufferLength=0;let t=e;for(this.buffer[this.bufferLength++]=this.table[t],t=this.prefix[t];t!==Mr.NO_SUCH_CODE;)this.buffer[this.bufferLength++]=this.table[t],t=this.prefix[t]}getNextCode(){if(this.bytePointer>=this.dataLength)return 257;for(;this.nextBits=this.dataLength)return 257;this.nextData=(this.nextData<<8)+this.data[this.bytePointer++]&4294967295,this.nextBits+=8}return this.nextBits-=this.bitsToGet,this.nextData>>this.nextBits&Mr.AND_TABLE[this.bitsToGet-9]}initializeStringTable(){this.table=new Uint8Array(Mr.LZ_MAX_CODE+1),this.prefix=new Uint32Array(Mr.LZ_MAX_CODE+1),this.prefix.fill(Mr.NO_SUCH_CODE,0,this.prefix.length);for(let e=0;e<256;e++)this.table[e]=e;this.bitsToGet=9,this.tableIndex=258}decode(e,t){this.out=t;let i=t.length;if(this.outPointer=0,this.data=e.buffer,this.dataLength=this.data.length,this.bytePointer=e.offset,this.data[0]===0&&this.data[1]===1)throw new T("Invalid LZW Data");this.initializeStringTable(),this.nextData=0,this.nextBits=0;let r=0,n=this.getNextCode();for(;n!==257&&this.outPointer=0;--s)this.out[this.outPointer++]=this.buffer[s];this.addString(r,this.buffer[this.bufferLength-1]),r=n}else{this.getString(r);for(let s=this.bufferLength-1;s>=0;--s)this.out[this.outPointer++]=this.buffer[s];this.out[this.outPointer++]=this.buffer[this.bufferLength-1],this.addString(r,this.buffer[this.bufferLength-1]),r=n}n=this.getNextCode()}}},It=Mr;It.LZ_MAX_CODE=4095,It.NO_SUCH_CODE=4098,It.AND_TABLE=[511,1023,2047,4095]});var bn,I,S,kt=C(()=>{"use strict";bn=An(pn());je();ge();He();Qe();Ye();ue();pi();ft();Ut();Ai();Sr();Pi();Cr();Br();I=class{constructor(e){this._tags=new Map;this._width=0;this._height=0;this._compression=1;this._bitsPerSample=1;this._samplesPerPixel=1;this._sampleFormat=I.FORMAT_UINT;this._imageType=I.TYPE_UNSUPPORTED;this._isWhiteZero=!1;this._predictor=1;this._chromaSubH=0;this._chromaSubV=0;this._tiled=!1;this._tileWidth=0;this._tileHeight=0;this._tilesX=0;this._tilesY=0;this._fillOrder=1;this._t4Options=0;this._t6Options=0;this.colorMapRed=0;this.colorMapGreen=0;this.colorMapBlue=0;let t=G.from(e),i=e.readUint16();for(let r=0;r4?o.valueOffset=e.readUint32():(o.valueOffset=e.offset,e.offset+=4),this._tags.set(o.tag,o),o.tag===I.TAG_IMAGE_WIDTH?this._width=o.readValue():o.tag===I.TAG_IMAGE_LENGTH?this._height=o.readValue():o.tag===I.TAG_PHOTOMETRIC_INTERPRETATION?this._photometricType=o.readValue():o.tag===I.TAG_COMPRESSION?this._compression=o.readValue():o.tag===I.TAG_BITS_PER_SAMPLE?this._bitsPerSample=o.readValue():o.tag===I.TAG_SAMPLES_PER_PIXEL?this._samplesPerPixel=o.readValue():o.tag===I.TAG_PREDICTOR?this._predictor=o.readValue():o.tag===I.TAG_SAMPLE_FORMAT?this._sampleFormat=o.readValue():o.tag===I.TAG_COLOR_MAP&&(this._colorMap=o.readValues(),this.colorMapRed=0,this.colorMapGreen=Math.trunc(this._colorMap.length/3),this.colorMapBlue=this.colorMapGreen*2)}if(!(this._width===0||this._height===0)){if(this._colorMap!==void 0&&this._bitsPerSample===8)for(let r=0,n=this._colorMap.length;r>=8;if(this._photometricType===0&&(this._isWhiteZero=!0),this.hasTag(I.TAG_TILE_OFFSETS))this._tiled=!0,this._tileWidth=this.readTag(I.TAG_TILE_WIDTH),this._tileHeight=this.readTag(I.TAG_TILE_LENGTH),this._tileOffsets=this.readTagList(I.TAG_TILE_OFFSETS),this._tileByteCounts=this.readTagList(I.TAG_TILE_BYTE_COUNTS);else{if(this._tiled=!1,this._tileWidth=this.readTag(I.TAG_TILE_WIDTH,this._width),!this.hasTag(I.TAG_ROWS_PER_STRIP))this._tileHeight=this.readTag(I.TAG_TILE_LENGTH,this._height);else{let r=this.readTag(I.TAG_ROWS_PER_STRIP),n=1;n=(n<<32)-1,r===n?this._tileHeight=this._height:this._tileHeight=r}this._tileOffsets=this.readTagList(I.TAG_STRIP_OFFSETS),this._tileByteCounts=this.readTagList(I.TAG_STRIP_BYTE_COUNTS)}switch(this._tilesX=Math.trunc((this._width+this._tileWidth-1)/this._tileWidth),this._tilesY=Math.trunc((this._height+this._tileHeight-1)/this._tileHeight),this._tileSize=this._tileWidth*this._tileHeight*this._samplesPerPixel,this._fillOrder=this.readTag(I.TAG_FILL_ORDER,1),this._t4Options=this.readTag(I.TAG_T4_OPTIONS),this._t6Options=this.readTag(I.TAG_T6_OPTIONS),this._extraSamples=this.readTag(I.TAG_EXTRA_SAMPLES),this._photometricType){case 0:case 1:this._bitsPerSample===1&&this._samplesPerPixel===1?this._imageType=I.TYPE_BILEVEL:this._bitsPerSample===4&&this._samplesPerPixel===1?this._imageType=I.TYPE_GRAY_4BIT:this._bitsPerSample%8===0&&(this._samplesPerPixel===1?this._imageType=I.TYPE_GRAY:this._samplesPerPixel===2?this._imageType=I.TYPE_GRAY_ALPHA:this._imageType=I.TYPE_GENERIC);break;case 2:this._bitsPerSample%8===0&&(this._samplesPerPixel===3?this._imageType=I.TYPE_RGB:this._samplesPerPixel===4?this._imageType=I.TYPE_RGB_ALPHA:this._imageType=I.TYPE_GENERIC);break;case 3:this._samplesPerPixel===1&&(this._bitsPerSample===4||this._bitsPerSample===8||this._bitsPerSample===16)&&(this._imageType=I.TYPE_PALETTE);break;case 4:this._bitsPerSample===1&&this._samplesPerPixel===1&&(this._imageType=I.TYPE_BILEVEL);break;case 6:if(this._compression===I.COMPRESSION_JPEG&&this._bitsPerSample===8&&this._samplesPerPixel===3)this._imageType=I.TYPE_RGB;else{if(this.hasTag(I.TAG_YCBCR_SUBSAMPLING)){let r=this._tags.get(I.TAG_YCBCR_SUBSAMPLING).readValues();this._chromaSubH=r[0],this._chromaSubV=r[1]}else this._chromaSubH=2,this._chromaSubV=2;this._chromaSubH*this._chromaSubV===1?this._imageType=I.TYPE_GENERIC:this._bitsPerSample===8&&this._samplesPerPixel===3&&(this._imageType=I.TYPE_YCBCR_SUB)}break;default:this._bitsPerSample%8===0&&(this._imageType=I.TYPE_GENERIC);break}}}get tags(){return this._tags}get width(){return this._width}get height(){return this._height}get photometricType(){return this._photometricType}get compression(){return this._compression}get bitsPerSample(){return this._bitsPerSample}get samplesPerPixel(){return this._samplesPerPixel}get sampleFormat(){return this._sampleFormat}get imageType(){return this._imageType}get isWhiteZero(){return this._isWhiteZero}get predictor(){return this._predictor}get chromaSubH(){return this._chromaSubH}get chromaSubV(){return this._chromaSubV}get tiled(){return this._tiled}get tileWidth(){return this._tileWidth}get tileHeight(){return this._tileHeight}get tileOffsets(){return this._tileOffsets}get tileByteCounts(){return this._tileByteCounts}get tilesX(){return this._tilesX}get tilesY(){return this._tilesY}get tileSize(){return this._tileSize}get fillOrder(){return this._fillOrder}get t4Options(){return this._t4Options}get t6Options(){return this._t6Options}get extraSamples(){return this._extraSamples}get colorMap(){return this._colorMap}get isValid(){return this._width!==0&&this._height!==0}readTag(e,t=0){return this.hasTag(e)?this._tags.get(e).readValue():t}readTagList(e){if(!!this.hasTag(e))return this._tags.get(e).readValues()}decodeBilevelTile(e,t,i){let r=i*this._tilesX+t;e.offset=this._tileOffsets[r];let n=t*this._tileWidth,s=i*this._tileHeight,a=this._tileByteCounts[r],o;if(this._compression===I.COMPRESSION_PACKBITS){let c=0;this._tileWidth%8===0?c=Math.trunc(this._tileWidth/8)*this._tileHeight:c=(Math.trunc(this._tileWidth/8)+1)*this._tileHeight,o=new G({buffer:new Uint8Array(this._tileWidth*this._tileHeight)}),this.decodePackbits(e,c,o.buffer)}else if(this._compression===I.COMPRESSION_LZW){if(o=new G({buffer:new Uint8Array(this._tileWidth*this._tileHeight)}),new It().decode(G.from(e,0,a),o.buffer),this._predictor===2){let p=0;for(let g=0;g=f.height||b>=f.width);++g,++b)u.readBits(1)===0?f.setPixel(b,p,h):f.setPixel(b,p,l);u.flushByte()}}decodeTile(e,t,i){var l;if(this._imageType===I.TYPE_BILEVEL){this.decodeBilevelTile(e,t,i);return}let r=i*this._tilesX+t;e.offset=this._tileOffsets[r];let n=t*this._tileWidth,s=i*this._tileHeight,a=this._tileByteCounts[r],o=this._tileWidth*this._tileHeight*this._samplesPerPixel;this._bitsPerSample===16?o*=2:this._bitsPerSample===32&&(o*=4);let u;if(this._bitsPerSample===8||this._bitsPerSample===16||this._bitsPerSample===32||this._bitsPerSample===64){if(this._compression===I.COMPRESSION_NONE)u=e;else if(this._compression===I.COMPRESSION_LZW){u=new G({buffer:new Uint8Array(o)});let h=new It;try{h.decode(G.from(e,0,a),u.buffer)}catch(f){console.error(f)}if(this._predictor===2){let f=0;for(let c=0;c>8:this._bitsPerSample===32?g>>24:g,this._photometricType===0&&(g=255-g);let b=0;this._photometricType===3&&this._colorMap!==void 0?b=d.getColor(this._colorMap[this.colorMapRed+g],this._colorMap[this.colorMapGreen+g],this._colorMap[this.colorMapBlue+g]):b=d.getColor(g,g,g),this.image.setPixel(p,f,b)}}else if(this._samplesPerPixel===2){let g=0,b=0;if(this._bitsPerSample===8?(g=this._sampleFormat===I.FORMAT_INT?u.readInt8():u.readByte(),b=this._sampleFormat===I.FORMAT_INT?u.readInt8():u.readByte()):this._bitsPerSample===16?(g=this._sampleFormat===I.FORMAT_INT?u.readInt16():u.readUint16(),b=this._sampleFormat===I.FORMAT_INT?u.readInt16():u.readUint16()):this._bitsPerSample===32&&(g=this._sampleFormat===I.FORMAT_INT?u.readInt32():u.readUint32(),b=this._sampleFormat===I.FORMAT_INT?u.readInt32():u.readUint32()),this.hdrImage!==void 0&&(this.hdrImage.setRed(p,f,g),this.hdrImage.setGreen(p,f,b)),this.image!==void 0){g=this._bitsPerSample===16?g>>8:this._bitsPerSample===32?g>>24:g,b=this._bitsPerSample===16?b>>8:this._bitsPerSample===32?b>>24:b;let x=d.getColor(g,g,g,b);this.image.setPixel(p,f,x)}}else if(this._samplesPerPixel===3)if(this._sampleFormat===I.FORMAT_FLOAT){let g=0,b=0,x=0;if(this._bitsPerSample===32?(g=u.readFloat32(),b=u.readFloat32(),x=u.readFloat32()):this._bitsPerSample===64?(g=u.readFloat64(),b=u.readFloat64(),x=u.readFloat64()):this._bitsPerSample===16&&(g=Ne.halfToDouble(u.readUint16()),b=Ne.halfToDouble(u.readUint16()),x=Ne.halfToDouble(u.readUint16())),this.hdrImage!==void 0&&(this.hdrImage.setRed(p,f,g),this.hdrImage.setGreen(p,f,b),this.hdrImage.setBlue(p,f,x)),this.image!==void 0){let y=F.clampInt255(g*255),P=F.clampInt255(b*255),w=F.clampInt255(x*255),M=d.getColor(y,P,w);this.image.setPixel(p,f,M)}}else{let g=0,b=0,x=0;if(this._bitsPerSample===8?(g=this._sampleFormat===I.FORMAT_INT?u.readInt8():u.readByte(),b=this._sampleFormat===I.FORMAT_INT?u.readInt8():u.readByte(),x=this._sampleFormat===I.FORMAT_INT?u.readInt8():u.readByte()):this._bitsPerSample===16?(g=this._sampleFormat===I.FORMAT_INT?u.readInt16():u.readUint16(),b=this._sampleFormat===I.FORMAT_INT?u.readInt16():u.readUint16(),x=this._sampleFormat===I.FORMAT_INT?u.readInt16():u.readUint16()):this._bitsPerSample===32&&(g=this._sampleFormat===I.FORMAT_INT?u.readInt32():u.readUint32(),b=this._sampleFormat===I.FORMAT_INT?u.readInt32():u.readUint32(),x=this._sampleFormat===I.FORMAT_INT?u.readInt32():u.readUint32()),this.hdrImage!==void 0&&(this.hdrImage.setRed(p,f,g),this.hdrImage.setGreen(p,f,b),this.hdrImage.setBlue(p,f,x)),this.image!==void 0){g=this._bitsPerSample===16?g>>8:this._bitsPerSample===32?g>>24:g,b=this._bitsPerSample===16?b>>8:this._bitsPerSample===32?b>>24:b,x=this._bitsPerSample===16?x>>8:this._bitsPerSample===32?x>>24:x;let y=d.getColor(g,b,x);this.image.setPixel(p,f,y)}}else if(this._samplesPerPixel>=4)if(this._sampleFormat===I.FORMAT_FLOAT){let g=0,b=0,x=0,y=0;if(this._bitsPerSample===32?(g=u.readFloat32(),b=u.readFloat32(),x=u.readFloat32(),y=u.readFloat32()):this._bitsPerSample===64?(g=u.readFloat64(),b=u.readFloat64(),x=u.readFloat64(),y=u.readFloat64()):this._bitsPerSample===16&&(g=Ne.halfToDouble(u.readUint16()),b=Ne.halfToDouble(u.readUint16()),x=Ne.halfToDouble(u.readUint16()),y=Ne.halfToDouble(u.readUint16())),this.hdrImage!==void 0&&(this.hdrImage.setRed(p,f,g),this.hdrImage.setGreen(p,f,b),this.hdrImage.setBlue(p,f,x),this.hdrImage.setAlpha(p,f,y)),this.image!==void 0){let P=F.clampInt255(g*255),w=F.clampInt255(b*255),M=F.clampInt255(x*255),B=F.clampInt255(y*255),O=d.getColor(P,w,M,B);this.image.setPixel(p,f,O)}}else{let g=0,b=0,x=0,y=0;if(this._bitsPerSample===8?(g=this._sampleFormat===I.FORMAT_INT?u.readInt8():u.readByte(),b=this._sampleFormat===I.FORMAT_INT?u.readInt8():u.readByte(),x=this._sampleFormat===I.FORMAT_INT?u.readInt8():u.readByte(),y=this._sampleFormat===I.FORMAT_INT?u.readInt8():u.readByte()):this._bitsPerSample===16?(g=this._sampleFormat===I.FORMAT_INT?u.readInt16():u.readUint16(),b=this._sampleFormat===I.FORMAT_INT?u.readInt16():u.readUint16(),x=this._sampleFormat===I.FORMAT_INT?u.readInt16():u.readUint16(),y=this._sampleFormat===I.FORMAT_INT?u.readInt16():u.readUint16()):this._bitsPerSample===32&&(g=this._sampleFormat===I.FORMAT_INT?u.readInt32():u.readUint32(),b=this._sampleFormat===I.FORMAT_INT?u.readInt32():u.readUint32(),x=this._sampleFormat===I.FORMAT_INT?u.readInt32():u.readUint32(),y=this._sampleFormat===I.FORMAT_INT?u.readInt32():u.readUint32()),this.hdrImage!==void 0&&(this.hdrImage.setRed(p,f,g),this.hdrImage.setGreen(p,f,b),this.hdrImage.setBlue(p,f,x),this.hdrImage.setAlpha(p,f,y)),this.image!==void 0){g=this._bitsPerSample===16?g>>8:this._bitsPerSample===32?g>>24:g,b=this._bitsPerSample===16?b>>8:this._bitsPerSample===32?b>>24:b,x=this._bitsPerSample===16?x>>8:this._bitsPerSample===32?x>>24:x,y=this._bitsPerSample===16?y>>8:this._bitsPerSample===32?y>>24:y;let P=d.getColor(g,b,x,y);this.image.setPixel(p,f,P)}}}else throw new T(`Unsupported bitsPerSample: ${this._bitsPerSample}`)}jpegToImage(e,t,i,r,n,s){let a=n,o=s;for(let u=0;u=0&&s<=127)for(let a=0;a=-127){let a=e.getByte(r++);for(let o=0;o<-s+1;++o)i[n++]=a}else r++}}decode(e){this.image=new W({width:this._width,height:this._height});for(let t=0,i=0;t{"use strict";Tr=class{constructor(e){this._images=[];this._width=0;this._height=0;this._backgroundColor=4294967295;this._bigEndian=e.bigEndian,this._signature=e.signature,this._ifdOffset=e.ifdOffset,this._images=e.images,this._images.length>0&&(this._width=this._images[0].width,this._height=this._images[0].height)}get bigEndian(){return this._bigEndian}get signature(){return this._signature}get ifdOffset(){return this._ifdOffset}get images(){return this._images}get width(){return this._width}get height(){return this._height}get backgroundColor(){throw this._backgroundColor}get numFrames(){return this._images.length}}});var Yr,Gt,Or=C(()=>{"use strict";bt();Xt();He();wt();kt();Er();Yr=class{constructor(){this._info=void 0;this._exifData=void 0}get info(){return this._info}get exifData(){return this._exifData}get numFrames(){return this._info!==void 0?this._info.images.length:0}readHeader(e){let t=e.readUint16();if(t!==Yr.TIFF_LITTLE_ENDIAN&&t!==Yr.TIFF_BIG_ENDIAN)return;let i=!1;t===Yr.TIFF_BIG_ENDIAN?(e.bigEndian=!0,i=!0):(e.bigEndian=!1,i=!1);let r=0;if(r=e.readUint16(),r!==Yr.TIFF_SIGNATURE)return;let n=e.readUint32(),s=G.from(e);s.offset=n;let a=[];for(;n!==0;){let o;try{if(o=new S(s),!o.isValid)break}catch(u){break}a.push(o),n=s.readUint32(),n!==0&&(s.offset=n)}return a.length>0?new Tr({bigEndian:i,signature:r,ifdOffset:n,images:a}):void 0}isValidFile(e){let t=new G({buffer:e});return this.readHeader(t)!==void 0}startDecode(e){if(this.input=new G({buffer:e}),this._info=this.readHeader(this.input),this.info!==void 0){let t=new G({buffer:e});this._exifData=Ae.fromInputBuffer(t)}return this._info}decodeFrame(e){if(this._info===void 0)return;let t=this._info.images[e].decode(this.input);return this._exifData!==void 0&&(t.exifData=this._exifData),t}decodeHdrFrame(e){if(this._info!==void 0)return this._info.images[e].decodeHdr(this.input)}decodeAnimation(e){if(this.startDecode(e)===void 0)return;let t=new Xe({width:this._info.width,height:this._info.height,frameType:1});for(let i=0,r=this.numFrames;i{"use strict";st();Ut();Pi();kt();Nn=class{constructor(){this._supportsAnimation=!1}get supportsAnimation(){return this._supportsAnimation}writeHeader(e){e.writeUint16(Nn.LITTLE_ENDIAN),e.writeUint16(Nn.SIGNATURE),e.writeUint32(8)}writeImage(e,t){e.writeUint16(11),this.writeEntryUint32(e,S.TAG_IMAGE_WIDTH,t.width),this.writeEntryUint32(e,S.TAG_IMAGE_LENGTH,t.height),this.writeEntryUint16(e,S.TAG_BITS_PER_SAMPLE,8),this.writeEntryUint16(e,S.TAG_COMPRESSION,S.COMPRESSION_NONE),this.writeEntryUint16(e,S.TAG_PHOTOMETRIC_INTERPRETATION,S.PHOTOMETRIC_RGB),this.writeEntryUint16(e,S.TAG_SAMPLES_PER_PIXEL,4),this.writeEntryUint16(e,S.TAG_SAMPLE_FORMAT,S.FORMAT_UINT),this.writeEntryUint32(e,S.TAG_ROWS_PER_STRIP,t.height),this.writeEntryUint16(e,S.TAG_PLANAR_CONFIGURATION,1),this.writeEntryUint32(e,S.TAG_STRIP_BYTE_COUNTS,t.width*t.height*4),this.writeEntryUint32(e,S.TAG_STRIP_OFFSETS,e.length+4),e.writeBytes(t.getBytes())}writeHdrImage(e,t){e.writeUint16(11),this.writeEntryUint32(e,S.TAG_IMAGE_WIDTH,t.width),this.writeEntryUint32(e,S.TAG_IMAGE_LENGTH,t.height),this.writeEntryUint16(e,S.TAG_BITS_PER_SAMPLE,t.bitsPerSample),this.writeEntryUint16(e,S.TAG_COMPRESSION,S.COMPRESSION_NONE),this.writeEntryUint16(e,S.TAG_PHOTOMETRIC_INTERPRETATION,t.numberOfChannels===1?S.PHOTOMETRIC_BLACKISZERO:S.PHOTOMETRIC_RGB),this.writeEntryUint16(e,S.TAG_SAMPLES_PER_PIXEL,t.numberOfChannels),this.writeEntryUint16(e,S.TAG_SAMPLE_FORMAT,this.getSampleFormat(t));let i=Math.trunc(t.bitsPerSample/8),r=t.width*t.height*t.slices.size*i;this.writeEntryUint32(e,S.TAG_ROWS_PER_STRIP,t.height),this.writeEntryUint16(e,S.TAG_PLANAR_CONFIGURATION,1),this.writeEntryUint32(e,S.TAG_STRIP_BYTE_COUNTS,r),this.writeEntryUint32(e,S.TAG_STRIP_OFFSETS,e.length+4);let n=[];t.blue!==void 0&&n.push(t.blue.getBytes()),t.red!==void 0&&n.push(t.red.getBytes()),t.green!==void 0&&n.push(t.green.getBytes()),t.alpha!==void 0&&n.push(t.alpha.getBytes()),t.depth!==void 0&&n.push(t.depth.getBytes());for(let s=0,a=0;s{"use strict";Qe();Ye();ue()});var gn=C(()=>{"use strict"});var xn=C(()=>{"use strict"});var Fr=C(()=>{"use strict"});var Rr,At,Dr=C(()=>{"use strict";Rr=class{constructor(...e){this.value=0;for(let t of e)this.value|=typeof t=="number"?t:t.value}has(e){return(this.value&e.value)!==0}},At=Rr;At.top=new Rr(1),At.bottom=new Rr(2),At.left=new Rr(4),At.right=new Rr(8),At.all=new Rr(15)});var Wr=C(()=>{"use strict";Ye();Ve();Et();Fr();Dr();Ft();ge()});var yn=C(()=>{"use strict";gi();zi();Ki();ji();nr();sr();Ai();Ir();_i();wi();vr();Pr();Or();Ur();ut();je();Ht();Vt();Ci();ge();Yt();zt();Wt();Mi();bt();Xt();Ti();rr();qt();He();Zt();Ei();Qe();Ye();hi();Ri();Di();st();di();Li();vt();Et();Ve();xt();mi();Qt();Jt();ei();ti();ii();ri();ni();si();ai();oi();ui();li();Ce();wt();Ui();$t();Kt();jt();Ie();Gr();Ni();ki();Gi();Vi();gi();zi();Ki();ji();nr();sr();Ai();Ir();_i();wi();vr();Pr();Or();Ur();Yi();Mt();bi();xi();qi();$i();Qi();Ji();er();or();lr();fr();wr();cr();dr();pr();gr();xr();_r();Dt();tr();ir();Ar();Sr();Pi();Cr();kt();Er();Br();pi();ft();Ut();zr();Wi();Ft();Fr();Dr();Wr()});var pn=Ms((Qm,us)=>{ut();je();Ht();Vt();Ci();ge();Yt();zt();Wt();Mi();bt();Xt();Ti();rr();qt();He();Zt();Ei();Qe();Ye();hi();Ri();Di();st();di();Qr();Li();vt();Et();Ve();xt();Jr();en();tn();mi();rn();nn();ue();Ot();wt();Ui();$t();Kt();jt();Ie();Qt();Jt();ei();ti();ii();ri();ni();si();ai();oi();ui();li();Ce();sn();an();on();Gr();Ni();ki();Gi();un();ln();Vi();hn();gi();zi();Yi();Mt();bi();cn();dn();Hr();mn();Ki();ji();xi();qi();$i();nr();sr();Qi();Ji();er();Ai();Ir();or();lr();fr();wr();cr();dr();pr();gr();xr();_r();Dt();_i();wi();tr();ir();vr();Pr();Ar();Or();Ur();Sr();Pi();Cr();kt();Er();Br();Vr();pi();ft();Ut();zr();yn();gn();xn();Wi();Ft();Fr();Dr();Wr();var v={};typeof us=="object"&&(us.exports=v);v.parse=function(m,e){for(var t=v.bin.readUshort,i=v.bin.readUint,a=0,r={},n=new Uint8Array(m),s=n.length-4;i(n,s)!=101010256;)s--;var a=s;a+=4,a+=4;var o=t(n,a);a+=2;var u=t(n,a);a+=2;var l=i(n,a);a+=4;var h=i(n,a);a+=4,a=h;for(var f=0;f>>4;return v.inflateRaw(new Uint8Array(m.buffer,m.byteOffset+2,m.length-6),e)};v.deflate=function(m,e){e==null&&(e={level:6});var t=0,i=new Uint8Array(50+Math.floor(m.length*1.1));i[t]=120,i[t+1]=156,t+=2,t=v.F.deflateRaw(m,i,t,e.level);var r=v.adler(m,0,m.length);return i[t+0]=r>>>24&255,i[t+1]=r>>>16&255,i[t+2]=r>>>8&255,i[t+3]=r>>>0&255,new Uint8Array(i.buffer,0,t+4)};v.deflateRaw=function(m,e){e==null&&(e={level:6});var t=new Uint8Array(50+Math.floor(m.length*1.1)),i=v.F.deflateRaw(m,t,i,e.level);return new Uint8Array(t.buffer,0,i)};v.encode=function(m,e){e==null&&(e=!1);var t=0,i=v.bin.writeUint,r=v.bin.writeUshort,n={};for(var s in m){var a=!v._noNeed(s)&&!e,o=m[s],u=v.crc.crc(o,0,o.length);n[s]={cpr:a,usize:o.length,crc:u,file:a?v.deflateRaw(o):o}}for(var s in n)t+=n[s].file.length+30+46+2*v.bin.sizeUTF8(s);t+=22;var l=new Uint8Array(t),h=0,f=[];for(var s in n){var c=n[s];f.push(h),h=v._writeHeader(l,h,s,c,0)}var p=0,g=h;for(var s in n){var c=n[s];f.push(h),h=v._writeHeader(l,h,s,c,1,f[p++])}var b=h-g;return i(l,h,101010256),h+=4,h+=4,r(l,h,p),h+=2,r(l,h,p),h+=2,i(l,h,b),h+=4,i(l,h,g),h+=4,h+=2,l.buffer};v._noNeed=function(m){var e=m.split(".").pop().toLowerCase();return"png,jpg,jpeg,zip".indexOf(e)!=-1};v._writeHeader=function(m,e,t,i,r,n){var s=v.bin.writeUint,a=v.bin.writeUshort,o=i.file;s(m,e,r==0?67324752:33639248),e+=4,r==1&&(e+=2),a(m,e,20),e+=2,a(m,e,0),e+=2,a(m,e,i.cpr?8:0),e+=2,s(m,e,0),e+=4,s(m,e,i.crc),e+=4,s(m,e,o.length),e+=4,s(m,e,i.usize),e+=4,a(m,e,v.bin.sizeUTF8(t)),e+=2,a(m,e,0),e+=2,r==1&&(e+=2,e+=2,e+=6,s(m,e,n),e+=4);var u=v.bin.writeUTF8(m,e,t);return e+=u,r==0&&(m.set(o,e),e+=o.length),e};v.crc={table:function(){for(var m=new Uint32Array(256),e=0;e<256;e++){for(var t=e,i=0;i<8;i++)t&1?t=3988292384^t>>>1:t=t>>>1;m[e]=t}return m}(),update:function(m,e,t,i){for(var r=0;r>>8;return m},crc:function(m,e,t){return v.crc.update(4294967295,m,e,t)^4294967295}};v.adler=function(m,e,t){for(var i=1,r=0,n=e,s=e+t;n>8&255},readUint:function(m,e){return m[e+3]*(256*256*256)+(m[e+2]<<16|m[e+1]<<8|m[e])},writeUint:function(m,e,t){m[e]=t&255,m[e+1]=t>>8&255,m[e+2]=t>>16&255,m[e+3]=t>>24&255},readASCII:function(m,e,t){for(var i="",r=0;r>6,m[e+r+1]=128|s>>0&63,r+=2;else if((s&4294967295-(1<<16)+1)==0)m[e+r]=224|s>>12,m[e+r+1]=128|s>>6&63,m[e+r+2]=128|s>>0&63,r+=3;else if((s&4294967295-(1<<21)+1)==0)m[e+r]=240|s>>18,m[e+r+1]=128|s>>12&63,m[e+r+2]=128|s>>6&63,m[e+r+3]=128|s>>0&63,r+=4;else throw"e"}return r},sizeUTF8:function(m){for(var e=m.length,t=0,i=0;i>>3}var g=s.lits,b=s.strt,x=s.prev,y=0,P=0,w=0,M=0,B=0,O=0;c>2&&(O=v.F._hash(m,0),b[O]=0);var R=0,N=0;for(l=0;l14e3||P>26697)&&c-l>100&&(f>>16,k=D&65535;if(D!=0){var p=D>>>16,k=D&65535,Y=a(p,s.of0);s.lhst[257+Y]++;var Z=a(k,s.df0);s.dhst[Z]++,M+=s.exb[Y]+s.dxb[Z],g[y]=p<<23|l-f,g[y+1]=k<<16|Y<<8|Z,y+=2,f=l+p}else s.lhst[m[l]]++;P++}}for((w!=l||m.length==0)&&(f>>3};v.F._bestMatch=function(m,e,t,i,r,n){var s=e&32767,a=t[s],o=s-a+(1<<15)&32767;if(a==s||i!=v.F._hash(m,e-o))return 0;for(var u=0,l=0,h=Math.min(32767,e);o<=h&&--n!=0&&a!=s;){if(u==0||m[e+u]==m[e+u-o]){var f=v.F._howLong(m,e,o);if(f>u){if(u=f,l=o,u>=r)break;o+2c&&(c=x,a=g)}}}s=a,a=t[s],o+=s-a+(1<<15)&32767}return u<<16|l};v.F._howLong=function(m,e,t){if(m[e]!=m[e-t]||m[e+1]!=m[e+1-t]||m[e+2]!=m[e+2-t])return 0;var i=e,r=Math.min(m.length,e+258);for(e+=3;e>>23,Ge=Z+(X&(1<<23)-1);Z>16,ee=Re>>8&255,H=Re&255;o=v.F._writeLit(257+ee,D,a,o),h(a,o,$-u.of0[ee]),o+=u.exb[ee],o=v.F._writeLit(H,k,a,o),l(a,o,be-u.df0[H]),o+=u.dxb[H],Z+=$}}o=v.F._writeLit(256,D,a,o)}return o};v.F._copyExact=function(m,e,t,i,r){var n=r>>>3;return i[n]=t,i[n+1]=t>>>8,i[n+2]=255-i[n],i[n+3]=255-i[n+1],n+=4,i.set(new Uint8Array(m.buffer,e,t),n),r+(t+4<<3)};v.F.getTrees=function(){for(var m=v.F.U,e=v.F._hufTree(m.lhst,m.ltree,15),t=v.F._hufTree(m.dhst,m.dtree,15),i=[],r=v.F._lenCodes(m.ltree,i),n=[],s=v.F._lenCodes(m.dtree,n),a=0;a4&&m.itree[(m.ordr[u-1]<<1)+1]==0;)u--;return[e,t,o,r,s,u,i,n]};v.F.getSecond=function(m){for(var e=[],t=0;t>1)+",");return e};v.F.contSize=function(m,e){for(var t=0,i=0;i15&&(v.F._putsE(t,i,s,a),i+=a)}return i};v.F._lenCodes=function(m,e){for(var t=m.length;t!=2&&m[t-1]==0;)t-=2;for(var i=0;i>>1,138);u<11?e.push(17,u-3):e.push(18,u-11),i+=u*2-2}else if(r==a&&n==r&&s==r){for(var o=i+5;o+2>>1,6);e.push(16,u-3),i+=u*2-2}else e.push(r,0)}return t>>>1};v.F._hufTree=function(m,e,t){var i=[],r=m.length,n=e.length,s=0;for(s=0;st&&(v.F.restrictDepth(o,t,g),g=t),s=0;se;i++){var s=m[i].d;m[i].d=e,n+=r-(1<>>t-e;n>0;){var s=m[i].d;s=0;i--)m[i].d==e&&n<0&&(m[i].d--,n++);n!=0&&console.log("debt left")};v.F._goodIndex=function(m,e){var t=0;return e[t|16]<=m&&(t|=16),e[t|8]<=m&&(t|=8),e[t|4]<=m&&(t|=4),e[t|2]<=m&&(t|=2),e[t|1]<=m&&(t|=1),t};v.F._writeLit=function(m,e,t,i){return v.F._putsF(t,i,e[m<<1]),i+e[(m<<1)+1]};v.F.inflate=function(m,e){var t=Uint8Array;if(m[0]==3&&m[1]==0)return e||new t(0);var i=v.F,r=i._bitsF,n=i._bitsE,s=i._decodeTiny,a=i.makeCodes,o=i.codes2map,u=i._get17,l=i.U,h=e==null;h&&(e=new t(m.length>>>2<<3));for(var f=0,c=0,p=0,g=0,b=0,x=0,y=0,P=0,w=0,M,B;f==0;){if(f=r(m,w,1),c=r(m,w+1,2),w+=3,c==0){(w&7)!=0&&(w+=8-(w&7));var O=(w>>>3)+4,R=m[O-4]|m[O-3]<<8;h&&(e=v.F._check(e,P+R)),e.set(new t(m.buffer,m.byteOffset+O,R),P),w=O+R<<3,P+=R;continue}if(h&&(e=v.F._check(e,P+(1<<17))),c==1&&(M=l.flmap,B=l.fdmap,x=(1<<9)-1,y=(1<<5)-1),c==2){p=n(m,w,5)+257,g=n(m,w+5,5)+1,b=n(m,w+10,4)+4,w+=14;for(var N=w,L=0;L<38;L+=2)l.itree[L]=0,l.itree[L+1]=0;for(var D=1,L=0;LD&&(D=k)}w+=3*b,a(l.itree,D),o(l.itree,D,l.imap),M=l.lmap,B=l.dmap,w=s(l.imap,(1<>>4;if(X>>>8==0)e[P++]=X;else{if(X==256)break;var $=P+X-254;if(X>264){var Ge=l.ldef[X-257];$=P+(Ge>>>3)+n(m,w,Ge&7),w+=Ge&7}var Re=B[u(m,w)&y];w+=Re&15;var be=Re>>>4,ee=l.ddef[be],H=(ee>>>4)+r(m,w,ee&15);for(w+=ee&15,h&&(e=v.F._check(e,P+(1<<17)));P<$;)e[P]=e[P++-H],e[P]=e[P++-H],e[P]=e[P++-H],e[P]=e[P++-H];P=$}}}return e.length==P?e:e.slice(0,P)};v.F._check=function(m,e){var t=m.length;if(e<=t)return m;var i=new Uint8Array(Math.max(t<<1,e));return i.set(m,0),i};v.F._decodeTiny=function(m,e,t,i,r,n){for(var s=v.F._bitsE,a=v.F._get17,o=0;o>>4;if(l<=15)n[o]=l,o++;else{var h=0,f=0;l==16?(f=3+s(i,r,2),r+=2,h=n[o-1]):l==17?(f=3+s(i,r,3),r+=3):l==18&&(f=11+s(i,r,7),r+=7);for(var c=o+f;o>>1;nr&&(r=a),n++}for(;n>1,o=m[s+1],u=a<<4|o,l=e-o,h=m[s]<>>15-e;t[c]=u,h++}};v.F.revCodes=function(m,e){for(var t=v.F.U.rev15,i=15-e,r=0;r>>i}};v.F._putsE=function(m,e,t){t=t<<(e&7);var i=e>>>3;m[i]|=t,m[i+1]|=t>>>8};v.F._putsF=function(m,e,t){t=t<<(e&7);var i=e>>>3;m[i]|=t,m[i+1]|=t>>>8,m[i+2]|=t>>>16};v.F._bitsE=function(m,e,t){return(m[e>>>3]|m[(e>>>3)+1]<<8)>>>(e&7)&(1<>>3]|m[(e>>>3)+1]<<8|m[(e>>>3)+2]<<16)>>>(e&7)&(1<>>3]|m[(e>>>3)+1]<<8|m[(e>>>3)+2]<<16)>>>(e&7)};v.F._get25=function(m,e){return(m[e>>>3]|m[(e>>>3)+1]<<8|m[(e>>>3)+2]<<16|m[(e>>>3)+3]<<24)>>>(e&7)};v.F.U=function(){var m=Uint16Array,e=Uint32Array;return{next_code:new m(16),bl_count:new m(16),ordr:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],of0:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],exb:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],ldef:new m(32),df0:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],dxb:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],ddef:new e(32),flmap:new m(512),fltree:[],fdmap:new m(32),fdtree:[],lmap:new m(32768),ltree:[],ttree:[],dmap:new m(32768),dtree:[],imap:new m(512),itree:[],rev15:new m(1<<15),lhst:new e(286),dhst:new e(30),ihst:new e(19),lits:new e(15e3),strt:new m(1<<16),prev:new m(1<<15)}}();(function(){for(var m=v.F.U,e=1<<15,t=0;t>>1|(i&1431655765)<<1,i=(i&3435973836)>>>2|(i&858993459)<<2,i=(i&4042322160)>>>4|(i&252645135)<<4,i=(i&4278255360)>>>8|(i&16711935)<<8,m.rev15[t]=(i>>>16|i<<16)>>>17}function r(n,s,a){for(;s--!=0;)n.push(0,a)}for(var t=0;t<32;t++)m.ldef[t]=m.of0[t]<<3|m.exb[t],m.ddef[t]=m.df0[t]<<4|m.dxb[t];r(m.fltree,144,8),r(m.fltree,255-143,9),r(m.fltree,279-255,7),r(m.fltree,287-279,8),v.F.makeCodes(m.fltree,9),v.F.codes2map(m.fltree,9,m.flmap),v.F.revCodes(m.fltree,9),r(m.fdtree,32,5),v.F.makeCodes(m.fdtree,5),v.F.codes2map(m.fdtree,5,m.fdmap),v.F.revCodes(m.fdtree,5),r(m.itree,19,0),r(m.ltree,286,0),r(m.dtree,30,0),r(m.ttree,320,0)})()});var kn,Rt,rr=C(()=>{"use strict";kn=An(pn());qt();ut();Rt=class{get name(){return this._name}get compression(){return this._compression}get data(){return this._data}constructor(e,t,i){this._name=e,this._compression=t,this._data=i}static from(e){return new Rt(e._name,e._compression,te.copyUint8(e._data))}compressed(){return this._compression===1?this._data:(this._data=(0,kn.deflate)(this._data),this._compression=1,this._data)}decompressed(){return this._compression===1?this._data:(this._data=(0,kn.inflate)(this._data),this._compression=0,this._data)}}});ut();je();Ht();Vt();Ci();ge();Yt();zt();Wt();Mi();bt();Xt();Ti();rr();qt();He();Zt();Ei();Qe();Ye();hi();Ri();Di();st();di();Qr();Li();vt();Et();Ve();xt();Jr();en();tn();mi();rn();nn();ue();Ot();wt();Ui();$t();Kt();jt();Ie();Qt();Jt();ei();ti();ii();ri();ni();si();ai();oi();ui();li();Ce();sn();an();on();Gr();Ni();ki();Gi();un();ln();Vi();hn();gi();zi();Yi();Mt();bi();cn();dn();Hr();mn();Ki();ji();xi();qi();$i();nr();sr();Qi();Ji();er();Ai();Ir();or();lr();fr();wr();cr();dr();pr();gr();xr();_r();Dt();_i();wi();tr();ir();vr();Pr();Ar();Or();Ur();Sr();Pi();Cr();kt();Er();Br();Vr();pi();ft();Ut();zr();yn();gn();xn();Wi();Ft();Fr();Dr();Wr();})(); +(()=>{var Au=Object.create;var Cu=Object.defineProperty;var Fu=Object.getOwnPropertyDescriptor;var Bu=Object.getOwnPropertyNames;var Uu=Object.getPrototypeOf,Su=Object.prototype.hasOwnProperty;var A=(f,e)=>()=>(f&&(e=f(f=0)),e);var ku=(f,e)=>()=>(e||f((e={exports:{}}).exports,e),e.exports);var zu=(f,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Bu(e))!Su.call(f,i)&&i!==t&&Cu(f,i,{get:()=>e[i],enumerable:!(n=Fu(e,i))||n.enumerable});return f};var ws=(f,e,t)=>(t=f!=null?Au(Uu(f)):{},zu(e||!f||!f.__esModule?Cu(t,"default",{value:f,enumerable:!0}):t,f));var Ja,De=A(()=>{"use strict";Ja=new Map([[0,4],[1,4],[2,4],[3,4],[4,3],[5,3],[6,2],[7,1]])});var oe=A(()=>{"use strict"});var T,be=A(()=>{"use strict";T=class extends Error{toString(){return`${this.constructor.name} (${this.message})`}}});var _,_e=A(()=>{"use strict";_=class{static fract(e){return e-Math.floor(e)}static smoothStep(e,t,n){let i=(n-e)/(t-e),r=_.clamp(i,0,1);return r*r*(3-2*r)}static mix(e,t,n){return e*(1-n)+t*n}static sign(e){return e<0?-1:e>0?1:0}static step(e,t){return t{"use strict";_e();fe=class{get numerator(){return this._numerator}get denominator(){return this._denominator}get toInt(){return this.denominator!==0?Math.trunc(this.numerator/this.denominator):0}get toDouble(){return this.denominator!==0?this.numerator/this.denominator:0}constructor(e,t){this._numerator=e,this._denominator=t}simplify(){let e=_.gcd(this.numerator,this.denominator);e!==0&&(this._numerator=Math.trunc(this.numerator/e),this._denominator=Math.trunc(this.denominator/e))}equals(e){return this._numerator===e._numerator&&this._denominator===e._denominator}toString(){return`${this.constructor.name} (${this._numerator}/${this._denominator})`}}});var U,G=A(()=>{"use strict";be();sn();U=class{static copyInt8(e,t,n){return Int8Array.from(e.subarray(t,n))}static copyUint8(e,t,n){return Uint8Array.from(e.subarray(t,n))}static copyInt16(e,t,n){return Int16Array.from(e.subarray(t,n))}static copyUint16(e,t,n){return Uint16Array.from(e.subarray(t,n))}static copyInt32(e,t,n){return Int32Array.from(e.subarray(t,n))}static copyUint32(e,t,n){return Uint32Array.from(e.subarray(t,n))}static copyFloat32(e,t,n){return Float32Array.from(e.subarray(t,n))}static copyFloat64(e,t,n){return Float64Array.from(e.subarray(t,n))}static copy(e,t,n){if(e instanceof Int8Array)return U.copyInt8(e,t,n);if(e instanceof Uint8Array)return U.copyUint8(e,t,n);if(e instanceof Int16Array)return U.copyInt16(e,t,n);if(e instanceof Uint16Array)return U.copyUint16(e,t,n);if(e instanceof Int32Array)return U.copyInt32(e,t,n);if(e instanceof Uint32Array)return U.copyUint32(e,t,n);if(e instanceof Float32Array)return U.copyFloat32(e,t,n);if(e instanceof Float64Array)return U.copyFloat64(e,t,n);throw new T("Unknown array type")}static copyRange(e,t,n,i,r){let a=e.subarray(t,n);i.set(a,r)}static fill(e,t){return new Array(e).fill(t)}static generate(e,t){let n=new Array(e);for(let i=0;itypeof t=="number")}static isNumArrayOrTypedArray(e){return Boolean(e&&typeof e=="object"&&(Array.isArray(e)&&e.every(t=>typeof t=="number")||ArrayBuffer.isView(e)&&!(e instanceof DataView)))}static isArrayOfRational(e){return Boolean(e&&typeof e=="object"&&Array.isArray(e)&&e.every(t=>t instanceof fe))}}});var Rt,K,Jt=A(()=>{"use strict";Rt=class{static countTrailingZeroBits(e){let t=32,n=e&-e;return n!==0&&t--,n&65535&&(t-=16),n&16711935&&(t-=8),n&252645135&&(t-=4),n&858993459&&(t-=2),n&1431655765&&(t-=1),t}static reverseByte(e){return this._reverseByteTable[e]}static signed(e,t){return t&1<>t)}static shiftL(e,t){return Rt.signed(32,e<-1;i--)n+=e&1<{"use strict";Jt();R=class{static get _toFloatFloat32(){return this._toFloatFloat32Data!==void 0?this._toFloatFloat32Data:this.initialize()}constructor(e){this.bits=e!==void 0?R.doubleToFloat16(e):0}static convert(e){let t=e>>16&32768,n=(e>>23&255)-(127-15),i=e&8388607;if(n<=0){if(n<-10)return t;i|=8388608;let r=14-n,a=(1<>r&1;return i=i+a+s>>r,t|i}else return n===255-(127-15)?i===0?t|31744:(i>>=13,t|31744|i|(i===0?1:0)):(i=i+4095+(i>>13&1),i&8388608&&(i=0,n+=1),n>30?t|31744:t|n<<10|i>>13)}static initialize(){if(this._toFloatFloat32Data!==void 0)return this._toFloatFloat32Data;let e=new Uint32Array(1<<16);this._toFloatFloat32Data=new Float32Array(e.buffer),this._eLut=new Uint16Array(1<<9);for(let n=0;n<256;n++){let i=(n&255)-112;i<=0||i>=30?(this._eLut[n]=0,this._eLut[n|256]=0):(this._eLut[n]=i<<10,this._eLut[n|256]=i<<10|32768)}let t=1<<16;for(let n=0;n>15&1,n=e>>10&31,i=e&1023;if(n===0){if(i===0)return t<<31;for(;!(i&1024);)i<<=1,n-=1;n+=1,i&=-1025}else if(n===31)return i===0?t<<31|2139095040:t<<31|2139095040|i<<13;return n+=127-15,i<<=13,t<<31|n<<23|i}static from(e){let t=new R;return t.bits=e.bits,t}static fromBits(e){let t=new R;return t.bits=e,t}static float16ToDouble(e){return this._toFloatFloat32[e]}static doubleToFloat16(e){let t=e,n=K.float32ToUint32(t);if(t===0)return n>>16;this._toFloatFloat32Data===void 0&&this.initialize();let i=n>>23&511;if(i=this._eLut[i],i!==0){let r=n&8388607;return i+(r+4095+(r>>13&1)>>13)}return this.convert(n)}static posInf(){return R.fromBits(31744)}static negInf(){return R.fromBits(64512)}static qNan(){return R.fromBits(32767)}static sNan(){return R.fromBits(32255)}toDouble(){return R._toFloatFloat32[this.bits]}minus(){return R.fromBits(this.bits^32768)}add(e){let t=e instanceof R?e.toDouble():typeof e=="number"?e:0;return new R(this.toDouble()+t)}sub(e){let t=e instanceof R?e.toDouble():typeof e=="number"?e:0;return new R(this.toDouble()-t)}mul(e){let t=e instanceof R?e.toDouble():typeof e=="number"?e:0;return new R(this.toDouble()*t)}div(e){let t=e instanceof R?e.toDouble():typeof e=="number"?e:0;return new R(this.toDouble()/t)}round(e){if(e>=10)return R.from(this);let t=this.bits&32768,n=this.bits&32767;return n>>=9-e,n+=n&1,n<<=9-e,n>=31744&&(n=this.bits,n>>=10-e,n<<=10-e),R.fromBits(t|n)}isFinite(){return(this.bits>>10&31)<31}isNormalized(){let e=this.bits>>10&31;return e>0&&e<31}isDenormalized(){let e=this.bits>>10&31,t=this.bits&1023;return e===0&&t!==0}isZero(){return(this.bits&32767)===0}isNaN(){let e=this.bits>>10&31,t=this.bits&1023;return e===31&&t!==0}isInfinity(){let e=this.bits>>10&31,t=this.bits&1023;return e===31&&t===0}isNegative(){return(this.bits&32768)!==0}}});function ar(f,e,t){if(e===t)return f;switch(e){case 0:return f===0?0:Xa.get(t);case 1:switch(t){case 0:return f===0?0:1;case 1:return f;case 2:return f*5;case 3:return f*75;case 4:return f*21845;case 5:return f*1431655765;case 6:return f*42;case 7:return f*10922;case 8:return f*715827882;case 9:case 10:case 11:return f/3}break;case 2:switch(t){case 0:return f===0?0:1;case 1:return Math.trunc(f)>>1;case 2:return f;case 3:return f*17;case 4:return f*4369;case 5:return f*286331153;case 6:return f*8;case 7:return f*2184;case 8:return f*143165576;case 9:case 10:case 11:return f/3}break;case 3:switch(t){case 0:return f===0?0:1;case 1:return Math.trunc(f)>>6;case 2:return Math.trunc(f)>>4;case 3:return f;case 4:return f*257;case 5:return f*16843009;case 6:return Math.trunc(f)>>1;case 7:return f*128;case 8:return f*8421504;case 9:case 10:case 11:return f/255}break;case 4:switch(t){case 0:return f===0?0:1;case 1:return Math.trunc(f)>>14;case 2:return Math.trunc(f)>>12;case 3:return Math.trunc(f)>>8;case 4:return f;case 5:return Math.trunc(f)<<8;case 6:return Math.trunc(f)>>9;case 7:return Math.trunc(f)>>1;case 8:return f*524296;case 9:case 10:case 11:return f/65535}break;case 5:switch(t){case 0:return f===0?0:1;case 1:return Math.trunc(f)>>30;case 2:return Math.trunc(f)>>28;case 3:return Math.trunc(f)>>24;case 4:return Math.trunc(f)>>16;case 5:return f;case 6:return Math.trunc(f)>>25;case 7:return Math.trunc(f)>>17;case 8:return Math.trunc(f)>>1;case 9:case 10:case 11:return f/4294967295}break;case 6:switch(t){case 0:return f===0?0:1;case 1:return f<=0?0:Math.trunc(f)>>5;case 2:return f<=0?0:Math.trunc(f)>>3;case 3:return f<=0?0:Math.trunc(f)<<1;case 4:return f<=0?0:Math.trunc(f)*516;case 5:return f<=0?0:Math.trunc(f)*33818640;case 6:return f;case 7:return f*258;case 8:return f*16909320;case 9:case 10:case 11:return f/127}break;case 7:switch(t){case 0:return f===0?0:1;case 1:return f<=0?0:Math.trunc(f)>>15;case 2:return f<=0?0:Math.trunc(f)>>11;case 3:return f<=0?0:Math.trunc(f)>>7;case 4:return f<=0?0:Math.trunc(f)<<1;case 5:return f<=0?0:Math.trunc(f)*131076;case 6:return Math.trunc(f)>>8;case 7:return f;case 8:return Math.trunc(f)*65538;case 9:case 10:case 11:return f/32767}break;case 8:switch(t){case 0:return f===0?0:1;case 1:return f<=0?0:Math.trunc(f)>>29;case 2:return f<=0?0:Math.trunc(f)>>27;case 3:return f<=0?0:Math.trunc(f)>>23;case 4:return f<=0?0:Math.trunc(f)>>16;case 5:return f<=0?0:Math.trunc(f)<<1;case 6:return Math.trunc(f)>>24;case 7:return Math.trunc(f)>>16;case 8:return f;case 9:case 10:case 11:return f/2147483647}break;case 9:case 10:case 11:switch(t){case 0:return f===0?0:1;case 1:return Math.trunc(_.clamp(f,0,1)*3);case 2:return Math.trunc(_.clamp(f,0,1)*15);case 3:return Math.trunc(_.clamp(f,0,1)*255);case 4:return Math.trunc(_.clamp(f,0,1)*65535);case 5:return Math.trunc(_.clamp(f,0,1)*4294967295);case 6:return Math.trunc(f<0?_.clamp(f,-1,1)*128:_.clamp(f,-1,1)*127);case 7:return Math.trunc(f<0?_.clamp(f,-1,1)*32768:_.clamp(f,-1,1)*32767);case 8:return Math.trunc(f<0?_.clamp(f,-1,1)*2147483648:_.clamp(f,-1,1)*2147483647);case 9:case 10:case 11:return f}break}throw new T("Unknown format.")}var q,es,Xa,H=A(()=>{"use strict";_e();be();q=(b=>(b[b.uint1=0]="uint1",b[b.uint2=1]="uint2",b[b.uint4=2]="uint4",b[b.uint8=3]="uint8",b[b.uint16=4]="uint16",b[b.uint32=5]="uint32",b[b.int8=6]="int8",b[b.int16=7]="int16",b[b.int32=8]="int32",b[b.float16=9]="float16",b[b.float32=10]="float32",b[b.float64=11]="float64",b))(q||{}),es=new Map([[0,1],[1,1],[2,1],[3,1],[4,2],[5,4],[6,1],[7,2],[8,4],[9,2],[10,4],[11,8]]),Xa=new Map([[0,1],[1,3],[2,15],[3,255],[4,65535],[5,4294967295],[6,127],[7,32767],[8,2147483647],[9,1],[10,1],[11,1]])});var ot,ri=A(()=>{"use strict";G();oe();ae();H();ot=class{get format(){return 10}get length(){return this.data.length}get maxChannelValue(){return 1}get maxIndexValue(){return 1}get isLdrFormat(){return!1}get isHdrFormat(){return!0}get hasPalette(){return!1}get palette(){}get index(){return this.r}set index(e){this.r=e}get r(){return this.getChannel(0)}set r(e){this.setChannel(0,e)}get g(){return this.getChannel(1)}set g(e){this.setChannel(1,e)}get b(){return this.getChannel(2)}set b(e){this.setChannel(2,e)}get a(){return this.getChannel(3)}set a(e){this.setChannel(3,e)}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e){typeof e=="number"?this.data=new Float32Array(e):this.data=e.slice()}static from(e){let t=new ot(e.length);return t.data=e.data,t}static fromArray(e){return new ot(e)}static rgb(e,t,n){let i=new Float32Array([e,t,n]);return new ot(i)}static rgba(e,t,n,i){let r=new Float32Array([e,t,n,i]);return new ot(r)}getChannel(e){return e===4?this.luminance:e1&&(this.data[1]=t,i>2&&(this.data[2]=n))}setRgba(e,t,n,i){this.data[0]=e;let r=this.data.length;r>1&&(this.data[1]=t,r>2&&(this.data[2]=n,r>3&&(this.data[3]=i)))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return ot.from(this)}equals(e){if(e.length!==this.length)return!1;for(let t=0;t{"use strict";G();oe();ae();H();lt=class{get format(){return 11}get length(){return this.data.length}get maxChannelValue(){return 1}get maxIndexValue(){return 1}get isLdrFormat(){return!0}get isHdrFormat(){return!1}get hasPalette(){return!1}get palette(){}get index(){return this.r}set index(e){this.r=e}get r(){return this.getChannel(0)}set r(e){this.setChannel(0,e)}get g(){return this.getChannel(1)}set g(e){this.setChannel(1,e)}get b(){return this.getChannel(2)}set b(e){this.setChannel(2,e)}get a(){return this.getChannel(3)}set a(e){this.setChannel(3,e)}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e){typeof e=="number"?this.data=new Float64Array(e):this.data=e.slice()}static from(e){let t=new lt(e.length);return t.data=e.data,t}static fromArray(e){return new lt(e)}static rgb(e,t,n){let i=new Float64Array([e,t,n]);return new lt(i)}static rgba(e,t,n,i){let r=new Float64Array([e,t,n,i]);return new lt(r)}getChannel(e){return e===4?this.luminance:e1&&(this.data[1]=t,i>2&&(this.data[2]=n))}setRgba(e,t,n,i){this.data[0]=e;let r=this.data.length;r>1&&(this.data[1]=t,r>2&&(this.data[2]=n,r>3&&(this.data[3]=i)))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return lt.from(this)}equals(e){if(e.length!==this.length)return!1;for(let t=0;t{"use strict";G();oe();ae();H();mt=class{get format(){return 7}get length(){return this._data.length}get maxChannelValue(){return 32767}get maxIndexValue(){return 32767}get isLdrFormat(){return!1}get isHdrFormat(){return!0}get hasPalette(){return!1}get palette(){}get index(){return this.r}set index(e){this.r=e}get r(){return this._data.length>0?this._data[0]:0}set r(e){this._data.length>0&&(this._data[0]=Math.trunc(e))}get g(){return this._data.length>1?this._data[1]:0}set g(e){this._data.length>1&&(this._data[1]=Math.trunc(e))}get b(){return this._data.length>2?this._data[2]:0}set b(e){this._data.length>2&&(this._data[2]=Math.trunc(e))}get a(){return this._data.length>3?this._data[3]:0}set a(e){this._data.length>3&&(this._data[3]=Math.trunc(e))}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e){typeof e=="number"?this._data=new Int16Array(e):this._data=e.slice()}static from(e){let t=new mt(e.length);return t._data=e._data,t}static fromArray(e){let t=new Int16Array(e);return new mt(t)}static rgb(e,t,n){let i=new Int16Array([e,t,n]);return new mt(i)}static rgba(e,t,n,i){let r=new Int16Array([e,t,n,i]);return new mt(r)}getChannel(e){return e===4?this.luminance:e1&&(this._data[1]=Math.trunc(t),i>2&&(this._data[2]=Math.trunc(n)))}setRgba(e,t,n,i){this._data[0]=Math.trunc(e);let r=this._data.length;r>1&&(this._data[1]=Math.trunc(t),r>2&&(this._data[2]=Math.trunc(n),r>3&&(this._data[3]=Math.trunc(i))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return mt.from(this)}equals(e){if(e.length!==this.length)return!1;for(let t=0;t{"use strict";G();oe();ae();H();ht=class{get format(){return 8}get length(){return this._data.length}get maxChannelValue(){return 2147483647}get maxIndexValue(){return 2147483647}get isLdrFormat(){return!1}get isHdrFormat(){return!0}get hasPalette(){return!1}get palette(){}get index(){return this.r}set index(e){this.r=e}get r(){return this._data.length>0?this._data[0]:0}set r(e){this._data.length>0&&(this._data[0]=Math.trunc(e))}get g(){return this._data.length>1?this._data[1]:0}set g(e){this._data.length>1&&(this._data[1]=Math.trunc(e))}get b(){return this._data.length>2?this._data[2]:0}set b(e){this._data.length>2&&(this._data[2]=Math.trunc(e))}get a(){return this._data.length>3?this._data[3]:0}set a(e){this._data.length>3&&(this._data[3]=Math.trunc(e))}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e){typeof e=="number"?this._data=new Int32Array(e):this._data=e.slice()}static from(e){let t=new ht(e.length);return t._data=e._data,t}static fromArray(e){let t=new Int32Array(e);return new ht(t)}static rgb(e,t,n){let i=new Int32Array([e,t,n]);return new ht(i)}static rgba(e,t,n,i){let r=new Int32Array([e,t,n,i]);return new ht(r)}getChannel(e){return e===4?this.luminance:e1&&(this._data[1]=Math.trunc(t),i>2&&(this._data[2]=Math.trunc(n)))}setRgba(e,t,n,i){this._data[0]=Math.trunc(e);let r=this._data.length;r>1&&(this._data[1]=Math.trunc(t),r>2&&(this._data[2]=Math.trunc(n),r>3&&(this._data[3]=Math.trunc(i))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return ht.from(this)}equals(e){if(e.length!==this.length)return!1;for(let t=0;t{"use strict";G();oe();ae();H();ct=class{get format(){return 6}get length(){return this._data.length}get maxChannelValue(){return 127}get maxIndexValue(){return 127}get isLdrFormat(){return!1}get isHdrFormat(){return!0}get hasPalette(){return!1}get palette(){}get index(){return this.r}set index(e){this.r=e}get r(){return this._data.length>0?this._data[0]:0}set r(e){this._data.length>0&&(this._data[0]=Math.trunc(e))}get g(){return this._data.length>1?this._data[1]:0}set g(e){this._data.length>1&&(this._data[1]=Math.trunc(e))}get b(){return this._data.length>2?this._data[2]:0}set b(e){this._data.length>2&&(this._data[2]=Math.trunc(e))}get a(){return this._data.length>3?this._data[3]:0}set a(e){this._data.length>3&&(this._data[3]=Math.trunc(e))}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e){typeof e=="number"?this._data=new Int8Array(e):this._data=e.slice()}static from(e){let t=new ct(e.length);return t._data=e._data,t}static fromArray(e){let t=new Int8Array(e);return new ct(t)}static rgb(e,t,n){let i=new Int8Array([e,t,n]);return new ct(i)}static rgba(e,t,n,i){let r=new Int8Array([e,t,n,i]);return new ct(r)}getChannel(e){return e===4?this.luminance:e1&&(this._data[1]=Math.trunc(t),i>2&&(this._data[2]=Math.trunc(n)))}setRgba(e,t,n,i){this._data[0]=Math.trunc(e);let r=this._data.length;r>1&&(this._data[1]=Math.trunc(t),r>2&&(this._data[2]=Math.trunc(n),r>3&&(this._data[3]=Math.trunc(i))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return ct.from(this)}equals(e){if(e.length!==this.length)return!1;for(let t=0;t{"use strict";G();ae();H();bt=class{get format(){return 0}get length(){return this._length}get maxChannelValue(){return 1}get maxIndexValue(){return 1}get isLdrFormat(){return!0}get isHdrFormat(){return!1}get hasPalette(){return!1}get palette(){}get index(){return this.r}set index(e){this.r=e}get r(){return this.getChannel(0)}set r(e){this.setChannel(0,e)}get g(){return this.getChannel(1)}set g(e){this.setChannel(1,e)}get b(){return this.getChannel(2)}set b(e){this.setChannel(2,e)}get a(){return this.getChannel(3)}set a(e){this.setChannel(3,e)}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e){typeof e=="number"?(this._length=e,this._data=0):(this._length=e.length,this._data=0,this.setRgba(e.length>0?e[0]:0,e.length>1?e[1]:0,e.length>2?e[2]:0,e.length>3?e[3]:0))}static from(e){let t=new bt(e._length);return t._data=e._data,t}static fromArray(e){return new bt(e)}static rgb(e,t,n){return new bt([e,t,n])}static rgba(e,t,n,i){return new bt([e,t,n,i])}getChannel(e){return e>7-e&1:0}getChannelNormalized(e){return this.getChannel(e)/this.maxChannelValue}setChannel(e,t){let n=e;if(n>=this.length)return;n=7-n;let i=this._data;t!==0?i|=1<this.getChannel(e))}clone(){return bt.from(this)}equals(e){if(e.length!==this.length)return!1;for(let t=0;t{"use strict";G();oe();ae();H();ft=class{get format(){return 4}get length(){return this.data.length}get maxChannelValue(){return 65535}get maxIndexValue(){return 65535}get isLdrFormat(){return!1}get isHdrFormat(){return!0}get hasPalette(){return!1}get palette(){}get index(){return this.r}set index(e){this.r=e}get r(){return this.getChannel(0)}set r(e){this.setChannel(0,e)}get g(){return this.getChannel(1)}set g(e){this.setChannel(1,e)}get b(){return this.getChannel(2)}set b(e){this.setChannel(2,e)}get a(){return this.getChannel(3)}set a(e){this.setChannel(3,e)}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e){typeof e=="number"?this.data=new Uint16Array(e):this.data=e.slice()}static from(e){let t=new ft(e.length);return t.data=e.data,t}static fromArray(e){return new ft(e)}static rgb(e,t,n){let i=new Uint16Array([e,t,n]);return new ft(i)}static rgba(e,t,n,i){let r=new Uint16Array([e,t,n,i]);return new ft(r)}getChannel(e){return e===4?this.luminance:e1&&(this.data[1]=Math.trunc(t),i>2&&(this.data[2]=Math.trunc(n)))}setRgba(e,t,n,i){this.data[0]=Math.trunc(e);let r=this.data.length;r>1&&(this.data[1]=Math.trunc(t),r>2&&(this.data[2]=Math.trunc(n),r>3&&(this.data[3]=Math.trunc(i))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return ft.from(this)}equals(e){if(e.length!==this.length)return!1;for(let t=0;t{"use strict";G();ae();H();dt=class{get format(){return 1}get length(){return this._length}get maxChannelValue(){return 3}get maxIndexValue(){return 3}get isLdrFormat(){return!0}get isHdrFormat(){return!1}get hasPalette(){return!1}get palette(){}get index(){return this.r}set index(e){this.r=e}get r(){return this.getChannel(0)}set r(e){this.setChannel(0,e)}get g(){return this.getChannel(1)}set g(e){this.setChannel(1,e)}get b(){return this.getChannel(2)}set b(e){this.setChannel(2,e)}get a(){return this.getChannel(3)}set a(e){this.setChannel(3,e)}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e){typeof e=="number"?(this._length=e,this._data=0):(this._length=e.length,this._data=0,this.setRgba(e.length>0?e[0]:0,e.length>1?e[1]:0,e.length>2?e[2]:0,e.length>3?e[3]:0))}static from(e){let t=new dt(e._length);return t._data=e._data,t}static fromArray(e){return new dt(e)}static rgb(e,t,n){return new dt([e,t,n])}static rgba(e,t,n,i){return new dt([e,t,n,i])}getChannel(e){return e>6-(e<<1)&3:0}getChannelNormalized(e){return this.getChannel(e)/this.maxChannelValue}setChannel(e,t){if(e>=this.length)return;let r=[~(3<<6-(0<<1))&255,~(3<<6-(1<<1))&255,~(3<<6-(2<<1))&255,~(3<<6-(3<<1))&255][e],a=Math.trunc(t)&3;this._data=this._data&r|a<<6-(e<<1)}set(e){this.setRgba(e.r,e.g,e.b,e.a)}setRgb(e,t,n){this.r=e,this.g=t,this.b=n}setRgba(e,t,n,i){this.r=e,this.g=t,this.b=n,this.a=i}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return dt.from(this)}equals(e){if(e.length!==this.length)return!1;for(let t=0;t{"use strict";G();oe();ae();H();pt=class{get format(){return 5}get length(){return this.data.length}get maxChannelValue(){return 4294967295}get maxIndexValue(){return 4294967295}get isLdrFormat(){return!1}get isHdrFormat(){return!0}get hasPalette(){return!1}get palette(){}get index(){return this.r}set index(e){this.r=e}get r(){return this.getChannel(0)}set r(e){this.setChannel(0,e)}get g(){return this.getChannel(1)}set g(e){this.setChannel(1,e)}get b(){return this.getChannel(2)}set b(e){this.setChannel(2,e)}get a(){return this.getChannel(3)}set a(e){this.setChannel(3,e)}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e){typeof e=="number"?this.data=new Uint32Array(e):this.data=e.slice()}static from(e){let t=new pt(e.length);return t.data=e.data,t}static fromArray(e){return new pt(e)}static rgb(e,t,n){let i=new Uint32Array([e,t,n]);return new pt(i)}static rgba(e,t,n,i){let r=new Uint32Array([e,t,n,i]);return new pt(r)}getChannel(e){return e===4?this.luminance:e1&&(this.data[1]=Math.trunc(t),i>2&&(this.data[2]=Math.trunc(n)))}setRgba(e,t,n,i){this.data[0]=Math.trunc(e);let r=this.data.length;r>1&&(this.data[1]=Math.trunc(t),r>2&&(this.data[2]=Math.trunc(n),r>3&&(this.data[3]=Math.trunc(i))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return pt.from(this)}equals(e){if(e.length!==this.length)return!1;for(let t=0;t{"use strict";G();_e();ae();H();gt=class{get format(){return 2}get length(){return this._length}get maxChannelValue(){return 15}get maxIndexValue(){return 15}get isLdrFormat(){return!0}get isHdrFormat(){return!1}get hasPalette(){return!1}get palette(){}get index(){return this.r}set index(e){this.r=e}get r(){return this.getChannel(0)}set r(e){this.setChannel(0,e)}get g(){return this.getChannel(1)}set g(e){this.setChannel(1,e)}get b(){return this.getChannel(2)}set b(e){this.setChannel(2,e)}get a(){return this.getChannel(3)}set a(e){this.setChannel(3,e)}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e){typeof e=="number"?(this._length=e,this._data=new Uint8Array(this.length<3?1:2)):(this._length=e.length,this._data=new Uint8Array(this._length<3?1:2),this.setRgba(this._length>0?e[0]:0,this._length>1?e[1]:0,this._length>2?e[2]:0,this._length>3?e[3]:0))}static from(e){let t=new gt(e._length);return t._data=e._data,t}static fromArray(e){return new gt(e)}static rgb(e,t,n){let i=new gt(3);return i.setRgb(e,t,n),i}static rgba(e,t,n,i){let r=new gt(4);return r.setRgba(e,t,n,i),r}getChannel(e){return e<0||e>=this.length?0:e<2?this._data[0]>>4-(e<<2)&15:this._data[1]>>4-((e&1)<<2)&15}getChannelNormalized(e){return this.getChannel(e)/this.maxChannelValue}setChannel(e,t){let n=e;if(n>=this.length)return;let i=_.clamp(Math.trunc(t),0,15),r=0;n>1&&(n&=1,r=1),n===0?this._data[r]=this._data[r]&15|i<<4:n===1&&(this._data[r]=this._data[r]&240|i)}set(e){this.setRgba(e.r,e.g,e.b,e.a)}setRgb(e,t,n){this.r=e,this.g=t,this.b=n}setRgba(e,t,n,i){this.r=e,this.g=t,this.b=n,this.a=i}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return gt.from(this)}equals(e){if(e.length!==this.length)return!1;for(let t=0;t{"use strict";G();oe();ae();H();ge=class{get format(){return 3}get length(){return this.data.length}get maxChannelValue(){return 255}get maxIndexValue(){return 255}get isLdrFormat(){return!0}get isHdrFormat(){return!1}get hasPalette(){return!1}get palette(){}get index(){return this.r}set index(e){this.r=e}get r(){return this.getChannel(0)}set r(e){this.setChannel(0,e)}get g(){return this.getChannel(1)}set g(e){this.setChannel(1,e)}get b(){return this.getChannel(2)}set b(e){this.setChannel(2,e)}get a(){return this.getChannel(3,255)}set a(e){this.setChannel(3,e)}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e){typeof e=="number"?this.data=new Uint8Array(e):this.data=e.slice()}static from(e){let t=new ge(e.length);return t.data=e.data,t}static fromArray(e){return new ge(e)}static rgb(e,t,n){let i=new Uint8Array([e,t,n]);return new ge(i)}static rgba(e,t,n,i){let r=new Uint8Array([e,t,n,i]);return new ge(r)}getChannel(e,t=0){return e===4?this.luminance:e1&&(this.data[1]=Math.trunc(t),i>2&&(this.data[2]=Math.trunc(n)))}setRgba(e,t,n,i){this.data[0]=Math.trunc(e);let r=this.data.length;r>1&&(this.data[1]=Math.trunc(t),r>2&&(this.data[2]=Math.trunc(n),r>3&&(this.data[3]=Math.trunc(i))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return ge.from(this)}equals(e){if(e.length!==this.length)return!1;for(let t=0;t{"use strict";_e();be();fi();ri();ai();si();ui();oi();li();mi();hi();ci();bi();en();H();z=class{static convertColorInternal(e,t,n){var u,o;let i=t.length,r=t.format,a=(o=(u=e.palette)==null?void 0:u.format)!=null?o:e.format,s=e.length;if(i===1){let l=Math.trunc(e.length>2?e.luminance:e.getChannel(0));t.setChannel(0,ar(l,a,r))}else if(i<=s)for(let l=0;l>8&255}static uint32ToBlue(e){return e>>16&255}static uint32ToAlpha(e){return e>>24&255}static rgbaToUint32(e,t,n,i){return _.clampInt255(e)|_.clampInt255(t)<<8|_.clampInt255(n)<<16|_.clampInt255(i)<<24}static convertColor(e){var a,s,u,o,l,m,b,h,c,d,p,g,x,y,C,I,P,F,M,w,k;let t=(s=(a=e.from.palette)==null?void 0:a.format)!=null?s:e.from.format,n=(l=(o=(u=e.to)==null?void 0:u.format)!=null?o:e.format)!=null?l:e.from.format,i=(h=(b=(m=e.to)==null?void 0:m.length)!=null?b:e.numChannels)!=null?h:e.from.length,r=(c=e.alpha)!=null?c:0;if(n===t&&i===e.from.length)return e.to===void 0?e.from.clone():(e.to.set(e.from),e.to);switch(n){case 3:{let B=(d=e.to)!=null?d:new ge(i);return this.convertColorInternal(e.from,B,r)}case 0:{let B=(p=e.to)!=null?p:new bt(i);return this.convertColorInternal(e.from,B,r)}case 1:{let B=(g=e.to)!=null?g:new dt(i);return this.convertColorInternal(e.from,B,r)}case 2:{let B=(x=e.to)!=null?x:new gt(i);return this.convertColorInternal(e.from,B,r)}case 4:{let B=(y=e.to)!=null?y:new ft(i);return this.convertColorInternal(e.from,B,r)}case 5:{let B=(C=e.to)!=null?C:new pt(i);return this.convertColorInternal(e.from,B,r)}case 6:{let B=(I=e.to)!=null?I:new ct(i);return this.convertColorInternal(e.from,B,r)}case 7:{let B=(P=e.to)!=null?P:new mt(i);return this.convertColorInternal(e.from,B,r)}case 8:{let B=(F=e.to)!=null?F:new ht(i);return this.convertColorInternal(e.from,B,r)}case 9:{let B=(M=e.to)!=null?M:new xt(i);return this.convertColorInternal(e.from,B,r)}case 10:{let B=(w=e.to)!=null?w:new ot(i);return this.convertColorInternal(e.from,B,r)}case 11:{let B=(k=e.to)!=null?k:new lt(i);return this.convertColorInternal(e.from,B,r)}}throw new T("Unknown format.")}static getLuminance(e){return .299*e.r+.587*e.g+.114*e.b}static getLuminanceNormalized(e){return .299*e.rNormalized+.587*e.gNormalized+.114*e.bNormalized}static getLuminanceRgb(e,t,n){return .299*e+.587*t+.114*n}static hslToRgb(e,t,n){if(t===0){let l=Math.trunc(n*255);return[l,l,l]}let i=(l,m,b)=>{let h=b;return h<0&&(h+=1),h>1&&(h-=1),h<1/6?l+(m-l)*6*h:h<1/2?m:h<2/3?l+(m-l)*(2/3-h)*6:l},r=n<.5?n*(1+t):n+t-n*t,a=2*n-r,s=i(a,r,e+1/3),u=i(a,r,e),o=i(a,r,e-1/3);return[Math.round(s*255),Math.round(u*255),Math.round(o*255)]}static hsvToRgb(e,t,n){if(t===0){let o=Math.round(n*255);return[o,o,o]}let i=(e-Math.floor(e))*6,r=i-Math.floor(i),a=n*(1-t),s=n*(1-t*r),u=n*(1-t*(1-r));switch(Math.trunc(i)){case 0:return[Math.round(n*255),Math.round(u*255),Math.round(a*255)];case 1:return[Math.round(s*255),Math.round(n*255),Math.round(a*255)];case 2:return[Math.round(a*255),Math.round(n*255),Math.round(u*255)];case 3:return[Math.round(a*255),Math.round(s*255),Math.round(n*255)];case 4:return[Math.round(u*255),Math.round(a*255),Math.round(n*255)];case 5:return[Math.round(n*255),Math.round(a*255),Math.round(s*255)];default:throw new T("Invalid hue.")}}static rgbToHsl(e,t,n){let i=e/255,r=t/255,a=n/255,s=Math.max(i,Math.max(r,a)),u=Math.min(i,Math.min(r,a)),o=(s+u)/2;if(s===u)return[0,0,o];let l=s-u,m=o>.5?l/(2-s-u):l/(s+u),b=0;return s===i?b=(r-a)/l+(r.008856?r=Math.pow(r,3):r=(r-16/116)/7.787,Math.pow(i,3)>.008856?i=Math.pow(i,3):i=(i-16/116)/7.787,Math.pow(a,3)>.008856?a=Math.pow(a,3):a=(a-16/116)/7.787,[Math.trunc(r*95.047),Math.trunc(i*100),Math.trunc(a*108.883)]}static xyzToRgb(e,t,n){let i=e/100,r=t/100,a=n/100,s=3.2406*i+-1.5372*r+-.4986*a,u=-.9689*i+1.8758*r+.0415*a,o=.0557*i+-.204*r+1.057*a;return s>.0031308?s=1.055*Math.pow(s,.4166666667)-.055:s*=12.92,u>.0031308?u=1.055*Math.pow(u,.4166666667)-.055:u*=12.92,o>.0031308?o=1.055*Math.pow(o,.4166666667)-.055:o*=12.92,[_.clampInt255(s*255),_.clampInt255(u*255),_.clampInt255(o*255)]}static cmykToRgb(e,t,n,i){let r=e/255,a=t/255,s=n/255,u=i/255;return[Math.round(255*(1-r)*(1-u)),Math.round(255*(1-a)*(1-u)),Math.round(255*(1-s)*(1-u))]}static labToRgb(e,t,n){let s=(e+16)/116,u=t/500+s,o=s-n/200,l=Math.pow(s,3);l>.008856?s=l:s=(s-16/116)/7.787;let m=Math.pow(u,3);m>.008856?u=m:u=(u-16/116)/7.787;let b=Math.pow(o,3);b>.008856?o=b:o=(o-16/116)/7.787,u*=95.047,s*=100,o*=108.883,u/=100,s/=100,o/=100;let h=u*3.2406+s*-1.5372+o*-.4986,c=u*-.9689+s*1.8758+o*.0415,d=u*.0557+s*-.204+o*1.057;return h>.0031308?h=1.055*Math.pow(h,1/2.4)-.055:h*=12.92,c>.0031308?c=1.055*Math.pow(c,1/2.4)-.055:c*=12.92,d>.0031308?d=1.055*Math.pow(d,1/2.4)-.055:d*=12.92,[_.clampInt255(h*255),_.clampInt255(c*255),_.clampInt255(d*255)]}static rgbToXyz(e,t,n){let i=e/255,r=t/255,a=n/255;return i>.04045?i=Math.pow((i+.055)/1.055,2.4):i/=12.92,r>.04045?r=Math.pow((r+.055)/1.055,2.4):r/=12.92,a>.04045?a=Math.pow((a+.055)/1.055,2.4):a/=12.92,i*=100,r*=100,a*=100,[i*.4124+r*.3576+a*.1805,i*.2126+r*.7152+a*.0722,i*.0193+r*.1192+a*.9505]}static xyzToLab(e,t,n){let i=e/95.047,r=t/100,a=n/108.883;return i>.008856?i=Math.pow(i,1/3):i=7.787*i+16/116,r>.008856?r=Math.pow(r,1/3):r=7.787*r+16/116,a>.008856?a=Math.pow(a,1/3):a=7.787*a+16/116,[116*r-16,500*(i-r),200*(r-a)]}static rgbToLab(e,t,n){let i=e/255,r=t/255,a=n/255;i>.04045?i=Math.pow((i+.055)/1.055,2.4):i/=12.92,r>.04045?r=Math.pow((r+.055)/1.055,2.4):r/=12.92,a>.04045?a=Math.pow((a+.055)/1.055,2.4):a/=12.92,i*=100,r*=100,a*=100;let s=i*.4124+r*.3576+a*.1805,u=i*.2126+r*.7152+a*.0722,o=i*.0193+r*.1192+a*.9505;return s/=95.047,u/=100,o/=108.883,s>.008856?s=Math.pow(s,1/3):s=7.787*s+16/116,u>.008856?u=Math.pow(u,1/3):u=7.787*u+16/116,o>.008856?o=Math.pow(o,1/3):o=7.787*o+16/116,[116*u-16,500*(s-u),200*(u-o)]}}});var xt,fi=A(()=>{"use strict";G();un();oe();ae();H();xt=class{get format(){return 9}get length(){return this.data.length}get maxChannelValue(){return 1}get maxIndexValue(){return 1}get isLdrFormat(){return!1}get isHdrFormat(){return!0}get hasPalette(){return!1}get palette(){}get index(){return this.r}set index(e){this.r=e}get r(){return this.getChannel(0)}set r(e){this.setChannel(0,e)}get g(){return this.getChannel(1)}set g(e){this.setChannel(1,e)}get b(){return this.getChannel(2)}set b(e){this.setChannel(2,e)}get a(){return this.getChannel(3)}set a(e){this.setChannel(3,e)}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e){typeof e=="number"?this.data=new Uint16Array(e):this.data=e.slice()}static from(e){let t=new xt(e.length);return t.data=e.data,t}static fromArray(e){let t=new xt(e),n=e.length;for(let i=0;i1&&(this.data[1]=R.doubleToFloat16(t),i>2&&(this.data[2]=R.doubleToFloat16(n)))}setRgba(e,t,n,i){this.data[0]=R.doubleToFloat16(e);let r=this.data.length;r>1&&(this.data[1]=R.doubleToFloat16(t),r>2&&(this.data[2]=R.doubleToFloat16(n),r>3&&(this.data[3]=R.doubleToFloat16(i))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return xt.from(this)}equals(e){if(e.length!==this.length)return!1;for(let t=0;t{"use strict";en();tn=class extends ge{constructor(e,t,n){let i=new Uint8Array([e,t,n]);super(i)}static from(e){let t=new Uint8Array([e.getChannel(0),e.getChannel(1),e.getChannel(2)]);return new ge(t)}}});var Dt,pn=A(()=>{"use strict";en();Dt=class extends ge{constructor(e,t,n,i){let r=new Uint8Array([e,t,n,i]);super(r)}static from(e){let t=new Uint8Array([e.getChannel(0),e.getChannel(1),e.getChannel(2),e.getChannel(3)]);return new ge(t)}}});var ts=A(()=>{"use strict"});var vs,di,pi=A(()=>{"use strict";vs=class{static makeTable(){let e=[],t=0;for(let n=0;n<256;n++){t=n;for(let i=0;i<8;i++)t=t&1?3988292384^t>>>1:t>>>1;e[n]=t}return e}static getChecksum(e){var s,u,o;let t=vs._crcTable,n=(s=e.length)!=null?s:e.buffer.length,i=(u=e.position)!=null?u:0,r=i+n,a=((o=e.baseCrc)!=null?o:0)^-1;for(let l=i;l>>8^t[(a^e.buffer[l])&255];return(a^-1)>>>0}},di=vs;di._crcTable=new Uint32Array(vs.makeTable())});var we,nn=A(()=>{"use strict";be();we=class{static getCodePoints(e){let t=new Uint8Array(e.length);for(let n=0;n{"use strict";be();Jt();nn();Y=class{get buffer(){return this._buffer}set bigEndian(e){this._bigEndian=e}get bigEndian(){return this._bigEndian}set offset(e){this._offset=e}get offset(){return this._offset}get start(){return this._start}get end(){return this._end}get position(){return this._offset-this._start}get length(){return this._end-this._offset}get isEOS(){return this._offset>=this._end}constructor(e){var t,n;this._buffer=e.buffer,this._bigEndian=(t=e.bigEndian)!=null?t:!1,this._offset=(n=e.offset)!=null?n:0,this._start=this._offset,this._end=e.length!==void 0?this._start+e.length:this._buffer.length}static from(e,t,n){let i=t!=null?t:0,r=new Y({buffer:e._buffer,bigEndian:e._bigEndian,offset:e._offset+i,length:n});return r._start=e._start,r._end=n!==void 0?e.offset+i+n:e._end,r}rewind(){this._offset=this._start}getByte(e){return this._buffer[this._offset+e]}setByte(e,t){return this._buffer[this._offset+e]=t}memset(e,t,n){this._buffer.fill(this._offset+e,this._offset+e+t,n)}subarray(e,t,n=0){let i=t!==void 0?this._start+t:this._offset;return i+=n,new Y({buffer:this._buffer,bigEndian:this._bigEndian,offset:i,length:e})}indexOf(e,t=0){let n=this.offset+this.length;for(let i=this.offset+t;i{"use strict"});var ve,sr=A(()=>{"use strict";ve=class{get x1(){return this._x1}get y1(){return this._y1}get x2(){return this._x2}get y2(){return this._y2}get dx(){return this._x2-this._x1}get dy(){return this._y2-this._y1}constructor(e,t,n,i){this._x1=e,this._y1=t,this._x2=n,this._y2=i}static from(e){return new ve(e.x1,e.y1,e.x2,e.y2)}movePoint1(e,t){this._x1=e,this._y1=t}movePoint2(e,t){this._x2=e,this._y2=t}swapXY1(){let e=this._x1;this._x1=this._y1,this._y1=e}swapXY2(){let e=this._x2;this._x2=this._y2,this._y2=e}flipX(){let e=this._x1;this._x1=this._x2,this._x2=e}flipY(){let e=this._y1;this._y1=this._y2,this._y2=e}clone(){return new ve(this._x1,this._y1,this._x2,this._y2)}toString(){return`${this.constructor.name} (x1: ${this._x1}, y1: ${this._y1}, x2: ${this._x2}, y2: ${this._y2})`}}});var ns,Be,At=A(()=>{"use strict";G();ns=class{get buffer(){return this._buffer}get bigEndian(){return this._bigEndian}set bigEndian(e){this._bigEndian=e}get length(){return this._length}set length(e){this._length=e}constructor(e){var t,n;this._bigEndian=(t=e==null?void 0:e.bigEndian)!=null?t:!1,this._buffer=new Uint8Array((n=e==null?void 0:e.size)!=null?n:ns._blockSize),this._length=0}expandBuffer(e){let t=ns._blockSize;e!==void 0?t=e:this._buffer.length>0&&(t=this._buffer.length*2);let n=new Uint8Array(this._buffer.length+t);U.copyRange(this._buffer,0,this._buffer.length,n,0),this._buffer=n}rewind(){this._length=0}clear(){this._buffer=new Uint8Array(ns._blockSize),this._length=0}getBytes(){return new Uint8Array(this._buffer.buffer,0,this._length)}writeByte(e){this._length===this._buffer.length&&this.expandBuffer(),this._buffer[this._length++]=e&255}writeBytes(e,t){let n=t!=null?t:e.length;for(;this._length+n>this._buffer.length;)this.expandBuffer(this._length+n-this._buffer.length);U.copyRange(e,0,n,this._buffer,this._length),this._length+=n}writeBuffer(e){let t=e.length,n=this._length+t;for(;n>this._buffer.length;)this.expandBuffer(n-this._buffer.length);U.copyRange(e.buffer,e.offset,t,this._buffer,this._length),this._length+=t}writeUint16(e){if(this._bigEndian){this.writeByte(e>>8&255),this.writeByte(e&255);return}this.writeByte(e&255),this.writeByte(e>>8&255)}writeUint32(e){if(this._bigEndian){this.writeByte(e>>24&255),this.writeByte(e>>16&255),this.writeByte(e>>8&255),this.writeByte(e&255);return}this.writeByte(e&255),this.writeByte(e>>8&255),this.writeByte(e>>16&255),this.writeByte(e>>24&255)}writeFloat32(e){let t=new Float32Array(1);t[0]=e;let n=new Uint8Array(t.buffer);if(this._bigEndian){this.writeByte(n[3]),this.writeByte(n[2]),this.writeByte(n[1]),this.writeByte(n[0]);return}this.writeByte(n[0]),this.writeByte(n[1]),this.writeByte(n[2]),this.writeByte(n[3])}writeFloat64(e){let t=new Float64Array(1);t[0]=e;let n=new Uint8Array(t.buffer);if(this._bigEndian){this.writeByte(n[7]),this.writeByte(n[6]),this.writeByte(n[5]),this.writeByte(n[4]),this.writeByte(n[3]),this.writeByte(n[2]),this.writeByte(n[1]),this.writeByte(n[0]);return}this.writeByte(n[0]),this.writeByte(n[1]),this.writeByte(n[2]),this.writeByte(n[3]),this.writeByte(n[4]),this.writeByte(n[5]),this.writeByte(n[6]),this.writeByte(n[7])}subarray(e,t){let n=e>=0?e:this._length+e,i=t!=null?t:this._length;return i<0&&(i=this._length+i),new Uint8Array(this._buffer.buffer,n,i-n)}},Be=ns;Be._blockSize=8192});var L,gn=A(()=>{"use strict";L=class{get x(){return this._x}get y(){return this._y}get xt(){return Math.trunc(this.x)}get yt(){return Math.trunc(this.y)}constructor(e,t){this._x=e,this._y=t}static from(e){return new L(e._x,e._y)}move(e,t){return new L(e,t)}offset(e,t){return this.move(this._x+e,this._y+t)}mul(e){return this.move(this._x*e,this._y*e)}add(e){return this.move(this._x+e._x,this._y+e._y)}equals(e){return this._x===e._x&&this._y===e._y}toString(){return`${this.constructor.name} (x: ${this._x}, y: ${this._y})`}}});var ye,ur=A(()=>{"use strict";ye=class{static crand(){return 1-2*Math.random()}static grand(){let e=0,t=0;do{let n=2*Math.random()-1;e=2*Math.random()-1,t=e*e+n*n}while(t<=0||t>=1);return e*Math.sqrt(-2*Math.log(t)/t)}static prand(e){if(e<=1e-10)return 0;if(e>100)return Math.trunc(Math.sqrt(e)*ye.grand()+e);let t=0,n=Math.exp(-e);for(let i=1;i>=n;++t)i*=Math.random();return t-1}static intrand(e){return Math.floor(Math.random()*e)}}});var on,gi=A(()=>{"use strict";gn();on=class{get left(){return this._left}get top(){return this._top}get right(){return this._right}get bottom(){return this._bottom}get width(){return this._right-this._left}get height(){return this._bottom-this._top}get topLeft(){return new L(this._left,this._top)}get topRight(){return new L(this._right,this._top)}get bottomLeft(){return new L(this._left,this._bottom)}get bottomRight(){return new L(this._right,this._bottom)}constructor(e,t,n,i){this._left=Math.min(e,n),this._top=Math.min(t,i),this._right=Math.max(e,n),this._bottom=Math.max(t,i)}static fromXYWH(e,t,n,i){return new on(e,t,e+n,t+i)}static from(e){return new on(e._left,e._top,e._right,e._bottom)}toString(){return`${this.constructor.name} (l: ${this._left}, t: ${this._top}, r: ${this._right}, b: ${this._bottom}, w: ${this.width}, h: ${this.height})`}}});var is=A(()=>{"use strict"});var kn=A(()=>{"use strict"});var or=A(()=>{"use strict"});var Vt,xi=A(()=>{"use strict";gn();Vt=class{static circleTest(e,t,n,i=!0){let r=0,a=e.x-t.x,s=e.y-t.y,o=a*a+s*s<=n?1:0;r+=o;let l=e.x+1-t.x,m=e.y-t.y,h=l*l+m*m<=n?1:0;r+=h;let c=e.x+1-t.x,d=e.y+1-t.y,g=c*c+d*d<=n?1:0;r+=g;let x=e.x-t.x,y=e.y+1-t.y,I=x*x+y*y<=n?1:0;r+=I;let P=e.x+.5-t.x,F=e.y-t.y,w=P*P+F*F<=n?1:0;r+=w;let k=e.x+.5-t.x,B=e.y+1-t.y,O=k*k+B*B<=n?1:0;r+=O;let V=e.x-t.x,E=e.y+.5-t.y,X=V*V+E*E<=n?1:0;r+=X;let ie=e.x+1-t.x,te=e.y+.5-t.y,W=ie*ie+te*te<=n?1:0;r+=W;let j=e.x+.5-t.x,Re=e.y+.5-t.y,se=j*j+Re*Re<=n?1:0;return r+=se,i?r/9:r>0?1:0}static clipLine(e,t){let n=e.left,i=e.top,r=e.right,a=e.bottom,s=0,u=1,o=2,l=4,m=8,b=p=>{let g=s;return p.xr&&(g|=o),p.ya&&(g|=m),g},h=b(new L(t.x1,t.y1)),c=b(new L(t.x2,t.y2)),d=!1;for(;;)if(h|c){if(h&c)break;{let p=h!==0?h:c,g=0,x=0;p&m?(g=t.x1+Math.trunc(t.dx*(a-t.y1)/t.dy),x=a):p&l?(g=t.x1+Math.trunc(t.dx*(i-t.y1)/t.dy),x=i):p&o?(x=t.y1+Math.trunc(t.dy*(r-t.x1)/t.dx),g=r):p&u&&(x=t.y1+Math.trunc(t.dy*(n-t.x1)/t.dx),g=n),p===h?(t.movePoint1(g,x),h=b(new L(t.x1,t.y1))):(t.movePoint2(g,x),c=b(new L(t.x2,t.y2)))}}else{d=!0;break}return d}}});var D,zn=A(()=>{"use strict";oe();ae();G();sr();_e();gn();gi();xi();kn();or();D=class{static calculateCircumference(e,t,n){if(n<0||t.x+n<0||t.x-n>=e.width||t.y+n<0||t.y-n>=e.height)return[];if(n===0)return[t];let i=[new L(t.x-n,t.y),new L(t.x+n,t.y),new L(t.x,t.y-n),new L(t.x,t.y+n)];if(n===1)return i;for(let r=1-n,a=0,s=-(n<<1),u=0,o=n;u=0&&(s+=2,r+=s,--o),++u,a+=2,r+=a+1,u!==o+1){let l=t.x-o,m=t.x+o,b=t.y-u,h=t.y+u,c=t.x-u,d=t.x+u,p=t.y-o,g=t.y+o;i.push(new L(l,b)),i.push(new L(l,h)),i.push(new L(m,b)),i.push(new L(m,h)),u!==o&&(i.push(new L(c,p)),i.push(new L(d,g)),i.push(new L(d,p)),i.push(new L(c,g)))}return i}static drawAntialiasCircle(e){var s,u;let t=(o,l,m,b,h)=>{n&8&&D.drawPixel({image:e.image,pos:new L(o+m,l+b),color:e.color,alpha:h,maskChannel:i,mask:e.mask}),n&4&&D.drawPixel({image:e.image,pos:new L(o-m,l+b),color:e.color,alpha:h,maskChannel:i,mask:e.mask}),n&2&&D.drawPixel({image:e.image,pos:new L(o+m,l-b),color:e.color,alpha:h,maskChannel:i,mask:e.mask}),n&1&&D.drawPixel({image:e.image,pos:new L(o-m,l-b),color:e.color,alpha:h,maskChannel:i,mask:e.mask})},n=(s=e.quadrants)!=null?s:15,i=(u=e.maskChannel)!=null?u:4,r=e.radius*e.radius,a=Math.round(e.radius/Math.SQRT2);for(let o=0;o<=a;++o){let l=Math.sqrt(r-o*o),m=_.fract(l),b=m*(o===a?.25:1),h=Math.floor(l);t(e.x,e.y,o,h,1-m),t(e.x,e.y,o,h+1,b),t(e.x,e.y,h,o,1-m),t(e.x,e.y,h+1,o,b)}return e.image}static drawLineWu(e){let t=e.line.clone(),n=Math.abs(t.dy)>Math.abs(t.dx);n&&(t.swapXY1(),t.swapXY2()),t.x1>t.x2&&(t.flipX(),t.flipY());let i=t.dx===1?1:t.dy/t.dx,r=Math.floor(t.x1+.5),a=t.y1+i*(r-t.x1),s=1-(t.x1+.5-Math.floor(t.x1+.5)),u=r,o=Math.floor(a);n?(D.drawPixel({image:e.image,pos:new L(o,u),color:e.color,alpha:(1-(a-Math.floor(a)))*s,maskChannel:e.maskChannel,mask:e.mask}),D.drawPixel({image:e.image,pos:new L(o+1,u),color:e.color,alpha:(a-Math.floor(a))*s,maskChannel:e.maskChannel,mask:e.mask})):(D.drawPixel({image:e.image,pos:new L(u,o),color:e.color,alpha:(1-(a-Math.floor(a)))*s,maskChannel:e.maskChannel,mask:e.mask}),D.drawPixel({image:e.image,pos:new L(u,o+1),color:e.color,alpha:(a-Math.floor(a))*s,maskChannel:e.maskChannel,mask:e.mask}));let l=a+i;r=Math.floor(t.x2+.5),a=t.y2+i*(r-t.x2),s=t.x2+.5-Math.floor(t.x2+.5);let m=r,b=Math.floor(a);if(n){D.drawPixel({image:e.image,pos:new L(b,m),color:e.color,alpha:(1-(a-Math.floor(a)))*s,mask:e.mask,maskChannel:e.maskChannel}),D.drawPixel({image:e.image,pos:new L(b+1,m),color:e.color,alpha:(a-Math.floor(a))*s,maskChannel:e.maskChannel,mask:e.mask});for(let h=u+1;h<=m-1;h++)D.drawPixel({image:e.image,pos:new L(Math.floor(l),h),color:e.color,alpha:1-(l-Math.floor(l)),mask:e.mask,maskChannel:e.maskChannel}),D.drawPixel({image:e.image,pos:new L(Math.floor(l)+1,h),color:e.color,alpha:l-Math.floor(l),maskChannel:e.maskChannel,mask:e.mask}),l+=i}else{D.drawPixel({image:e.image,pos:new L(m,b),color:e.color,alpha:(1-(a-Math.floor(a)))*s,maskChannel:e.maskChannel,mask:e.mask}),D.drawPixel({image:e.image,pos:new L(m,b+1),color:e.color,alpha:(a-Math.floor(a))*s,maskChannel:e.maskChannel,mask:e.mask});for(let h=u+1;h<=m-1;h++)D.drawPixel({image:e.image,pos:new L(h,Math.floor(l)),color:e.color,alpha:1-(l-Math.floor(l)),maskChannel:e.maskChannel,mask:e.mask}),D.drawPixel({image:e.image,pos:new L(h,Math.floor(l)+1),color:e.color,alpha:l-Math.floor(l),maskChannel:e.maskChannel,mask:e.mask}),l+=i}return e.image}static setAlpha(e,t){return e.a=t,e}static colorDistance(e,t,n){let i=e[0]-t[0],r=e[1]-t[1],a=e[2]-t[2];if(n){let s=e[3]-t[3];return Math.sqrt(Math.max(i*i,(i-s)*(i-s))+Math.max(r*r,(r-s)*(r-s))+Math.max(a*a,(a-s)*(a-s)))}else return Math.sqrt(i*i+r*r+a*a)}static testPixelLabColorDistance(e,t,n,i,r){let a=e.getPixel(t,n),s=i.length>3,u=z.rgbToLab(a.r,a.g,a.b);return s&&u.push(a.a),D.colorDistance(u,i,s)>r}static fill4Core(e,t,n,i,r,a){let s=t,u=n;if(a[u*e.width+s]===1)return;let o=0;do{let l=0,m=s;if(o!==0&&i(u,s)){do if(--o===0)return;while(i(u,++s));m=s}else for(;s!==0&&!i(u,s-1);l++,o++)r(u,--s),u!==0&&!i(u-1,s)&&D.fill4(e,s,u-1,i,r,a);for(;mo&&u!==0)for(let b=s+o;++b0){let d=e.color.aNormalized*c;D.drawPixel({image:e.image,pos:new L(h.x,h.y),color:e.color,alpha:d,maskChannel:n,mask:e.mask})}}else{let c=h.x-e.center.x,d=h.y-e.center.y;c*c+d*d~h+65536&65535;if(!n){let h=Math.abs(t.dx),c=Math.abs(t.dy);if(c<=h){let d=Math.cos(Math.atan2(c,h)),p=0;d!==0?p=Math.trunc(i/d):p=1,p===0&&(p=1);let g=2*c-h,x=2*c,y=2*(c-h),C=0,I=0,P=0,F=0;t.x1>t.x2?(C=t.x2,I=t.y2,P=-1,F=t.x1):(C=t.x1,I=t.y1,P=1,F=t.x2);let M=Math.trunc(I-p/2);for(let w=M;w0)for(;Ct.y2?(I=t.y2,C=t.x2,P=t.y1,F=-1):(I=t.y1,C=t.x1,P=t.y2,F=1);let M=Math.trunc(C-p/2);for(let w=M;w0)for(;IMath.abs(t.dy)){t.dx<0&&(t.flipX(),t.flipY());let h=t.y1,c=Math.trunc(t.dy*65536/t.dx),d=0;for(let p=t.x1;p<=t.x2;p++){let g=h-Math.trunc(o/2);for(let x=g;x>8&255)/255,maskChannel:r,mask:e.mask}),D.drawPixel({image:e.image,pos:new L(p,x+1),color:e.color,alpha:(s(d)>>8&255)/255,maskChannel:r,mask:e.mask});d+=c,d>=65536?(d-=65536,h++):d<0&&(d+=65536,h--)}}else{t.dy<0&&(t.flipX(),t.flipY());let h=t.x1,c=Math.trunc(t.dx*65536/t.dy),d=0;for(let p=t.y1;p<=t.y2;p++){let g=h-Math.trunc(o/2);for(let x=g;x>8&255)/255,maskChannel:r,mask:e.mask}),D.drawPixel({image:e.image,pos:new L(x+1,p),color:e.color,alpha:(s(d)>>8&255)/255,maskChannel:r,mask:e.mask});d+=c,d>=65536?(d-=65536,h++):d<0&&(d+=65536,h--)}}return e.image}static drawPixel(e){var p,g,x,y,C,I;let t=(p=e.blend)!=null?p:1,n=(g=e.linearBlend)!=null?g:!1,i=(x=e.maskChannel)!=null?x:4;if(!e.image.isBoundsSafe(e.pos.x,e.pos.y))return e.image;if((t===0||e.image.hasPalette)&&e.image.isBoundsSafe(e.pos.x,e.pos.y))return e.image.getPixel(e.pos.x,e.pos.y).set(e.color),e.image;let r=(C=(y=e.mask)==null?void 0:y.getPixel(e.pos.x,e.pos.y).getChannelNormalized(i))!=null?C:1,a=e.filter!==void 0?e.color.rNormalized*e.filter.rNormalized:e.color.rNormalized,s=e.filter!==void 0?e.color.gNormalized*e.filter.gNormalized:e.color.gNormalized,u=e.filter!==void 0?e.color.bNormalized*e.filter.bNormalized:e.color.bNormalized,o=((I=e.alpha)!=null?I:e.color.length<4?1:e.color.aNormalized)*r;if(o===0)return e.image;let l=e.image.getPixel(e.pos.x,e.pos.y),m=l.rNormalized,b=l.gNormalized,h=l.bNormalized,c=l.aNormalized;switch(t){case 0:return e.image;case 1:break;case 2:a=Math.max(m,a),s=Math.max(b,s),u=Math.max(h,u);break;case 3:a=1-(1-a)*(1-m),s=1-(1-s)*(1-b),u=1-(1-u)*(1-h);break;case 4:{let P=o*c,F=a*(1-c)+m*(1-o),M=s*(1-c)+b*(1-o),w=u*(1-c)+h*(1-o),k=P+F,B=P+M,N=P+w,O=_.clamp(a/_.clamp(o,.01,1)*_.step(0,o),0,.99),V=_.clamp(s/_.clamp(o,.01,1)*_.step(0,o),0,.99),E=_.clamp(u/_.clamp(o,.01,1)*_.step(0,o),0,.99),$=m*o/(1-O)+F,X=b*o/(1-V)+M,ie=h*o/(1-E)+w,te=_.step(a*c+m*o,P),re=_.step(s*c+b*o,P),W=_.step(u*c+h*o,P);a=_.mix(k,$,te),s=_.mix(B,X,re),u=_.mix(N,ie,W)}break;case 5:a=m+a,s=b+s,u=h+u;break;case 6:a=Math.min(m,a),s=Math.min(b,s),u=Math.min(h,u);break;case 7:a*=m,s*=b,u*=h;break;case 8:a=a!==0?1-(1-m)/a:0,s=s!==0?1-(1-b)/s:0,u=u!==0?1-(1-h)/u:0;break;case 9:2*m0){let C=Math.round(i);D.drawLine({image:e.image,line:new ve(a+C,s,u-C,s),color:e.color}),D.drawLine({image:e.image,line:new ve(u,s+C,u,o-C),color:e.color}),D.drawLine({image:e.image,line:new ve(a+C,o,u-C,o),color:e.color}),D.drawLine({image:e.image,line:new ve(a,s+C,a,o-C),color:e.color});let I=a+C,P=s+C,F=u-C,M=s+C,w=u-C,k=o-C,B=a+C,N=o-C;return D.drawAntialiasCircle({image:e.image,x:I,y:P,radius:C,color:e.color,maskChannel:r,quadrants:1,mask:e.mask}),D.drawAntialiasCircle({image:e.image,x:F,y:M,radius:C,color:e.color,maskChannel:r,quadrants:2,mask:e.mask}),D.drawAntialiasCircle({image:e.image,x:w,y:k,radius:C,color:e.color,maskChannel:r,quadrants:8,mask:e.mask}),D.drawAntialiasCircle({image:e.image,x:B,y:N,radius:C,color:e.color,maskChannel:r,quadrants:4,mask:e.mask}),e.image}let l=n/2;D.drawLine({image:e.image,line:new ve(a,s,u,s),color:e.color,thickness:n,maskChannel:r,mask:e.mask}),D.drawLine({image:e.image,line:new ve(a,o,u,o),color:e.color,thickness:n,maskChannel:r,mask:e.mask});let b=l-Math.trunc(l)===0?1:0,h=Math.ceil(s+l),c=Math.floor(o-l-b),d=Math.floor(a+l),p=Math.ceil(u-l+b);return D.drawLine({image:e.image,line:new ve(d,h,d,c),color:e.color,thickness:n,maskChannel:r,mask:e.mask}),D.drawLine({image:e.image,line:new ve(p,h,p,c),color:e.color,thickness:n,maskChannel:r,mask:e.mask}),e.image}static fillFlood(e){var l,m,b;let t=(l=e.threshold)!=null?l:0,n=(m=e.compareAlpha)!=null?m:!1,i=(b=e.maskChannel)!=null?b:4;if(e.color.a===0)return e.image;let r=new Uint8Array(e.image.width*e.image.height),a=e.image.getPixel(e.start.x,e.start.y);n||(e.color.a=0);let s;if(t>0){let h=z.rgbToLab(a.r,a.g,a.b);n&&h.push(a.a),s=(c,d)=>r[c*e.image.width+d]===0&&D.testPixelLabColorDistance(e.image,d,c,h,t)}else n?s=(h,c)=>r[h*e.image.width+c]===0&&e.image.getPixel(c,h)!==a:s=(h,c)=>r[h*e.image.width+c]===0&&D.setAlpha(e.image.getPixel(c,h),0)!==a;let u,o=(h,c)=>{if(e.mask!==void 0){let d=e.mask.getPixel(c,h).getChannelNormalized(i);d>0&&(u=e.image.getPixel(c,h,u),u.r=_.mix(u.r,e.color.r,d),u.g=_.mix(u.g,e.color.g,d),u.b=_.mix(u.b,e.color.b,d),u.a=_.mix(u.a,e.color.a,d))}else e.image.setPixel(c,h,e.color);r[h*e.image.width+c]=1};return D.fill4(e.image,e.start.x,e.start.y,s,o,r),e.image}static fillPolygon(e){var m;let t=(m=e.maskChannel)!=null?m:4;if(e.color.a===0)return e.image;let n=e.vertices.length;if(n===0)return e.image;if(n===1)return D.drawPixel({image:e.image,pos:e.vertices[0],color:e.color,maskChannel:t,mask:e.mask});if(n===2)return D.drawLine({image:e.image,line:new ve(e.vertices[0].x,e.vertices[0].y,e.vertices[1].x,e.vertices[1].y),color:e.color,mask:e.mask,maskChannel:t});let i=0,r=0,a=0,s=0,u=!0;for(let b of e.vertices)u?(i=b.x,r=b.y,a=b.x,s=b.y,u=!1):(i=Math.min(i,b.x),r=Math.min(r,b.y),a=Math.max(a,b.x),s=Math.max(s,b.y));i=Math.max(i,0),r=Math.max(r,0),a=Math.min(a,e.image.width-1),s=Math.min(s,e.image.height-1);let o=U.fill(40,0),l=U.generate(n+1,b=>b=y){let P=0;y-I===0?P=x:(P=(C-x)*(h-y)/(I-y),P+=x),P<=a&&P>=i&&(o[c++]=P)}}for(let d=0;dg){let C=p;p=g,g=C}let x=Math.floor(p),y=Math.ceil(g);for(let C=x;C<=y;++C)D.drawPixel({image:e.image,pos:new L(C,b),color:e.color,maskChannel:t,mask:e.mask})}}return e.image}static fillRect(e){var l,m,b,h,c,d;let t=(l=e.radius)!=null?l:0,n=(m=e.maskChannel)!=null?m:4;if(e.color.a===0)return e.image;let i=_.clamp(e.rect.left,0,e.image.width-1),r=_.clamp(e.rect.top,0,e.image.height-1),a=_.clamp(e.rect.right,0,e.image.width-1),s=_.clamp(e.rect.bottom,0,e.image.height-1),u=a-i+1,o=s-r+1;if(t>0){let p=Math.round(t),g=p*p,x=i+p,y=r+p,C=a-p+1,I=r+p,P=a-p+1,F=s-p+1,M=i+p,w=s-p+1,k=e.image.getRange(i,r,u,o),B;for(;B=k.next(),!B.done;){let N=B.value,O=N.x,V=N.y,E=1;if(OC&&VP&&V>F){if(E=Vt.circleTest(N,new L(P,F),g),E===0)continue}else if(Ow&&(E=Vt.circleTest(N,new L(M,w),g),E===0))continue;E*=e.color.aNormalized;let $=(h=(b=e.mask)==null?void 0:b.getPixel(N.x,N.y).getChannelNormalized(n))!=null?h:1;N.r=_.mix(N.r,e.color.r,E*$),N.g=_.mix(N.g,e.color.g,E*$),N.b=_.mix(N.b,e.color.b,E*$),N.a*=1-e.color.a*$}return e.image}if(e.color.a===e.color.maxChannelValue&&e.mask===void 0){let p=e.image.getRange(i,r,u,o),g;for(;g=p.next(),!g.done;)g.value.set(e.color)}else{let p=e.color.a/e.color.maxChannelValue,g=e.image.getRange(i,r,u,o),x;for(;x=g.next(),!x.done;){let y=x.value,C=(d=(c=e.mask)==null?void 0:c.getPixel(y.x,y.y).getChannelNormalized(n))!=null?d:1;y.r=_.mix(y.r,e.color.r,p*C),y.g=_.mix(y.g,e.color.g,p*C),y.b=_.mix(y.b,e.color.b,p*C),y.a*=1-e.color.a*C}}return e.image}static fill(e){var n;let t=(n=e.maskChannel)!=null?n:4;if(e.mask===void 0)return e.image.clear(e.color),e.image;for(let i of e.image){let r=e.mask.getPixel(i.x,i.y).getChannelNormalized(t);i.r=_.mix(i.r,e.color.r,r),i.g=_.mix(i.g,e.color.g,r),i.b=_.mix(i.b,e.color.b,r),i.a=_.mix(i.a,e.color.a,r)}return e.image}static maskFlood(e){var l,m,b;let t=(l=e.threshold)!=null?l:0,n=(m=e.compareAlpha)!=null?m:!1,i=(b=e.fillValue)!=null?b:255,r=new Uint8Array(e.image.width*e.image.height),a=e.image.getPixel(e.start.x,e.start.y);n||(a=D.setAlpha(a,0));let s=new Uint8Array(e.image.width*e.image.height),u;if(t>0){let h=z.rgbToLab(a.r,a.g,a.b);n&&h.push(a.a),u=(c,d)=>r[c*e.image.width+d]===0&&(s[c*e.image.width+d]!==0||D.testPixelLabColorDistance(e.image,d,c,h,t))}else n?u=(h,c)=>r[h*e.image.width+c]===0&&(s[h*e.image.width+c]!==0||e.image.getPixel(c,h)!==a):u=(h,c)=>r[h*e.image.width+c]===0&&(s[h*e.image.width+c]!==0||D.setAlpha(e.image.getPixel(c,h),0)!==a);let o=(h,c)=>{s[h*e.image.width+c]=i,r[h*e.image.width+c]=1};return D.fill4(e.image,e.start.x,e.start.y,u,o,r),s}static compositeImage(e){var x,y,C,I,P,F,M,w,k,B,N,O;let t=(x=e.dstX)!=null?x:0,n=(y=e.dstY)!=null?y:0,i=(C=e.srcX)!=null?C:0,r=(I=e.srcY)!=null?I:0,a=(P=e.srcW)!=null?P:e.src.width,s=(F=e.srcH)!=null?F:e.src.height,u=(M=e.dstW)!=null?M:e.dst.widthr+Math.trunc(E*c)),g=Array.from({length:u},(V,E)=>i+Math.trunc(E*d));return l===0?D.imgDirectComposite(e.src,e.dst,t,n,u,o,g,p,h,e.mask):D.imgComposite(e.src,e.dst,t,n,u,o,g,p,l,m,h,e.mask),e.dst}}});var lr,mr=A(()=>{"use strict";lr=class{get tag(){return this._tag}get value(){return this._value}set value(e){this._value=e}constructor(e,t){this._tag=e,this._value=t}}});function as(f){return Ce[f]}function ss(f,e=1){return xn[f]*e}var Ce,xn,xe=A(()=>{"use strict";Ce=(h=>(h[h.none=0]="none",h[h.byte=1]="byte",h[h.ascii=2]="ascii",h[h.short=3]="short",h[h.long=4]="long",h[h.rational=5]="rational",h[h.sByte=6]="sByte",h[h.undefined=7]="undefined",h[h.sShort=8]="sShort",h[h.sLong=9]="sLong",h[h.sRational=10]="sRational",h[h.single=11]="single",h[h.double=12]="double",h))(Ce||{}),xn=[0,1,1,2,4,8,1,1,2,4,8,4,8]});var v,ne,On,qs,Gs,_n=A(()=>{"use strict";xe();v=class{get name(){return this._name}get type(){return this._type}get count(){return this._count}constructor(e){var t;this._name=e.name,this._type=(t=e.type)!=null?t:0,this._count=e.count}},ne=new Map([["ProcessingSoftware",11],["SubfileType",254],["OldSubfileType",255],["ImageWidth",256],["ImageLength",257],["ImageHeight",257],["BitsPerSample",258],["Compression",259],["PhotometricInterpretation",262],["Thresholding",263],["CellWidth",264],["CellLength",265],["FillOrder",266],["DocumentName",269],["ImageDescription",270],["Make",271],["Model",272],["StripOffsets",273],["Orientation",274],["SamplesPerPixel",277],["RowsPerStrip",278],["StripByteCounts",279],["MinSampleValue",280],["MaxSampleValue",281],["XResolution",282],["YResolution",283],["PlanarConfiguration",284],["PageName",285],["XPosition",286],["YPosition",287],["GrayResponseUnit",290],["GrayResponseCurve",291],["T4Options",292],["T6Options",293],["ResolutionUnit",296],["PageNumber",297],["ColorResponseUnit",300],["TransferFunction",301],["Software",305],["DateTime",306],["Artist",315],["HostComputer",316],["Predictor",317],["WhitePoint",318],["PrimaryChromaticities",319],["ColorMap",320],["HalftoneHints",321],["TileWidth",322],["TileLength",323],["TileOffsets",324],["TileByteCounts",325],["BadFaxLines",326],["CleanFaxData",327],["ConsecutiveBadFaxLines",328],["InkSet",332],["InkNames",333],["NumberofInks",334],["DotRange",336],["TargetPrinter",337],["ExtraSamples",338],["SampleFormat",339],["SMinSampleValue",340],["SMaxSampleValue",341],["TransferRange",342],["ClipPath",343],["JPEGProc",512],["JPEGInterchangeFormat",513],["JPEGInterchangeFormatLength",514],["YCbCrCoefficients",529],["YCbCrSubSampling",530],["YCbCrPositioning",531],["ReferenceBlackWhite",532],["ApplicationNotes",700],["Rating",18246],["CFARepeatPatternDim",33421],["CFAPattern",33422],["BatteryLevel",33423],["Copyright",33432],["ExposureTime",33434],["FNumber",33437],["IPTC-NAA",33723],["ExifOffset",34665],["InterColorProfile",34675],["ExposureProgram",34850],["SpectralSensitivity",34852],["GPSOffset",34853],["ISOSpeed",34855],["OECF",34856],["SensitivityType",34864],["RecommendedExposureIndex",34866],["ExifVersion",36864],["DateTimeOriginal",36867],["DateTimeDigitized",36868],["OffsetTime",36880],["OffsetTimeOriginal",36881],["OffsetTimeDigitized",36882],["ComponentsConfiguration",37121],["CompressedBitsPerPixel",37122],["ShutterSpeedValue",37377],["ApertureValue",37378],["BrightnessValue",37379],["ExposureBiasValue",37380],["MaxApertureValue",37381],["SubjectDistance",37382],["MeteringMode",37383],["LightSource",37384],["Flash",37385],["FocalLength",37386],["SubjectArea",37396],["MakerNote",37500],["UserComment",37510],["SubSecTime",37520],["SubSecTimeOriginal",37521],["SubSecTimeDigitized",37522],["XPTitle",40091],["XPComment",40092],["XPAuthor",40093],["XPKeywords",40094],["XPSubject",40095],["FlashPixVersion",40960],["ColorSpace",40961],["ExifImageWidth",40962],["ExifImageLength",40963],["RelatedSoundFile",40964],["InteroperabilityOffset",40965],["FlashEnergy",41483],["SpatialFrequencyResponse",41484],["FocalPlaneXResolution",41486],["FocalPlaneYResolution",41487],["FocalPlaneResolutionUnit",41488],["SubjectLocation",41492],["ExposureIndex",41493],["SensingMethod",41495],["FileSource",41728],["SceneType",41729],["CVAPattern",41730],["CustomRendered",41985],["ExposureMode",41986],["WhiteBalance",41987],["DigitalZoomRatio",41988],["FocalLengthIn35mmFilm",41989],["SceneCaptureType",41990],["GainControl",41991],["Contrast",41992],["Saturation",41993],["Sharpness",41994],["DeviceSettingDescription",41995],["SubjectDistanceRange",41996],["ImageUniqueID",42016],["CameraOwnerName",42032],["BodySerialNumber",42033],["LensSpecification",42034],["LensMake",42035],["LensModel",42036],["LensSerialNumber",42037],["Gamma",42240],["PrintIM",50341],["Padding",59932],["OffsetSchema",59933],["OwnerName",65e3],["SerialNumber",65001],["InteropIndex",1],["InteropVersion",2],["RelatedImageFileFormat",4096],["RelatedImageWidth",4097],["RelatedImageLength",4098],["GPSVersionID",0],["GPSLatitudeRef",1],["GPSLatitude",2],["GPSLongitudeRef",3],["GPSLongitude",4],["GPSAltitudeRef",5],["GPSAltitude",6],["GPSTimeStamp",7],["GPSSatellites",8],["GPSStatus",9],["GPSMeasureMode",10],["GPSDOP",11],["GPSSpeedRef",12],["GPSSpeed",13],["GPSTrackRef",14],["GPSTrack",15],["GPSImgDirectionRef",16],["GPSImgDirection",17],["GPSMapDatum",18],["GPSDestLatitudeRef",19],["GPSDestLatitude",20],["GPSDestLongitudeRef",21],["GPSDestLongitude",22],["GPSDestBearingRef",23],["GPSDestBearing",24],["GPSDestDistanceRef",25],["GPSDestDistance",26],["GPSProcessingMethod",27],["GPSAreaInformation",28],["GPSDate",29],["GPSDifferential",30]]),On=new Map([[11,new v({name:"ProcessingSoftware",type:2})],[254,new v({name:"SubfileType",type:4,count:1})],[255,new v({name:"OldSubfileType",type:4,count:1})],[256,new v({name:"ImageWidth",type:4,count:1})],[257,new v({name:"ImageLength",type:4,count:1})],[258,new v({name:"BitsPerSample",type:3,count:1})],[259,new v({name:"Compression",type:3,count:1})],[262,new v({name:"PhotometricInterpretation",type:3,count:1})],[263,new v({name:"Thresholding",type:3,count:1})],[264,new v({name:"CellWidth",type:3,count:1})],[265,new v({name:"CellLength",type:3,count:1})],[266,new v({name:"FillOrder",type:3,count:1})],[269,new v({name:"DocumentName",type:2})],[270,new v({name:"ImageDescription",type:2})],[271,new v({name:"Make",type:2})],[272,new v({name:"Model",type:2})],[273,new v({name:"StripOffsets",type:4})],[274,new v({name:"Orientation",type:3,count:1})],[277,new v({name:"SamplesPerPixel",type:3,count:1})],[278,new v({name:"RowsPerStrip",type:4,count:1})],[279,new v({name:"StripByteCounts",type:4,count:1})],[280,new v({name:"MinSampleValue",type:3,count:1})],[281,new v({name:"MaxSampleValue",type:3,count:1})],[282,new v({name:"XResolution",type:5,count:1})],[283,new v({name:"YResolution",type:5,count:1})],[284,new v({name:"PlanarConfiguration",type:3,count:1})],[285,new v({name:"PageName",type:2})],[286,new v({name:"XPosition",type:5,count:1})],[287,new v({name:"YPosition",type:5,count:1})],[290,new v({name:"GrayResponseUnit",type:3,count:1})],[291,new v({name:"GrayResponseCurve"})],[292,new v({name:"T4Options"})],[293,new v({name:"T6Options"})],[296,new v({name:"ResolutionUnit",type:3,count:1})],[297,new v({name:"PageNumber",type:3,count:2})],[300,new v({name:"ColorResponseUnit"})],[301,new v({name:"TransferFunction",type:3,count:768})],[305,new v({name:"Software",type:2})],[306,new v({name:"DateTime",type:2})],[315,new v({name:"Artist",type:2})],[316,new v({name:"HostComputer",type:2})],[317,new v({name:"Predictor",type:3,count:1})],[318,new v({name:"WhitePoint",type:5,count:2})],[319,new v({name:"PrimaryChromaticities",type:5,count:6})],[320,new v({name:"ColorMap",type:3})],[321,new v({name:"HalftoneHints",type:3,count:2})],[322,new v({name:"TileWidth",type:4,count:1})],[323,new v({name:"TileLength",type:4,count:1})],[324,new v({name:"TileOffsets",type:4})],[325,new v({name:"TileByteCounts"})],[326,new v({name:"BadFaxLines"})],[327,new v({name:"CleanFaxData"})],[328,new v({name:"ConsecutiveBadFaxLines"})],[332,new v({name:"InkSet"})],[333,new v({name:"InkNames"})],[334,new v({name:"NumberofInks"})],[336,new v({name:"DotRange"})],[337,new v({name:"TargetPrinter",type:2})],[338,new v({name:"ExtraSamples"})],[339,new v({name:"SampleFormat",type:3,count:1})],[340,new v({name:"SMinSampleValue"})],[341,new v({name:"SMaxSampleValue"})],[342,new v({name:"TransferRange"})],[343,new v({name:"ClipPath"})],[512,new v({name:"JPEGProc"})],[513,new v({name:"JPEGInterchangeFormat"})],[514,new v({name:"JPEGInterchangeFormatLength"})],[529,new v({name:"YCbCrCoefficients",type:5,count:3})],[530,new v({name:"YCbCrSubSampling",type:3,count:1})],[531,new v({name:"YCbCrPositioning",type:3,count:1})],[532,new v({name:"ReferenceBlackWhite",type:5,count:6})],[700,new v({name:"ApplicationNotes",type:3,count:1})],[18246,new v({name:"Rating",type:3,count:1})],[33421,new v({name:"CFARepeatPatternDim"})],[33422,new v({name:"CFAPattern"})],[33423,new v({name:"BatteryLevel"})],[33432,new v({name:"Copyright",type:2})],[33434,new v({name:"ExposureTime",type:5,count:1})],[33437,new v({name:"FNumber",type:5})],[33723,new v({name:"IPTC-NAA",type:4,count:1})],[34665,new v({name:"ExifOffset"})],[34675,new v({name:"InterColorProfile"})],[34850,new v({name:"ExposureProgram",type:3})],[34852,new v({name:"SpectralSensitivity",type:2})],[34853,new v({name:"GPSOffset"})],[34855,new v({name:"ISOSpeed",type:4,count:1})],[34856,new v({name:"OECF"})],[34864,new v({name:"SensitivityType",type:3,count:1})],[34866,new v({name:"RecommendedExposureIndex",type:4,count:1})],[34867,new v({name:"ISOSpeed",type:4,count:1})],[36864,new v({name:"ExifVersion",type:7})],[36867,new v({name:"DateTimeOriginal",type:2})],[36868,new v({name:"DateTimeDigitized",type:2})],[36880,new v({name:"OffsetTime",type:2})],[36881,new v({name:"OffsetTimeOriginal",type:2})],[36882,new v({name:"OffsetTimeDigitized",type:2})],[37121,new v({name:"ComponentsConfiguration",type:7})],[37122,new v({name:"CompressedBitsPerPixel"})],[37377,new v({name:"ShutterSpeedValue"})],[37378,new v({name:"ApertureValue"})],[37379,new v({name:"BrightnessValue"})],[37380,new v({name:"ExposureBiasValue"})],[37381,new v({name:"MaxApertureValue"})],[37382,new v({name:"SubjectDistance"})],[37383,new v({name:"MeteringMode"})],[37384,new v({name:"LightSource"})],[37385,new v({name:"Flash"})],[37386,new v({name:"FocalLength"})],[37396,new v({name:"SubjectArea"})],[37500,new v({name:"MakerNote",type:7})],[37510,new v({name:"UserComment",type:7})],[37520,new v({name:"SubSecTime"})],[37521,new v({name:"SubSecTimeOriginal"})],[37522,new v({name:"SubSecTimeDigitized"})],[40091,new v({name:"XPTitle"})],[40092,new v({name:"XPComment"})],[40093,new v({name:"XPAuthor"})],[40094,new v({name:"XPKeywords"})],[40095,new v({name:"XPSubject"})],[40960,new v({name:"FlashPixVersion"})],[40961,new v({name:"ColorSpace",type:3,count:1})],[40962,new v({name:"ExifImageWidth",type:3,count:1})],[40963,new v({name:"ExifImageLength",type:3,count:1})],[40964,new v({name:"RelatedSoundFile"})],[40965,new v({name:"InteroperabilityOffset"})],[41483,new v({name:"FlashEnergy"})],[41484,new v({name:"SpatialFrequencyResponse"})],[41486,new v({name:"FocalPlaneXResolution"})],[41487,new v({name:"FocalPlaneYResolution"})],[41488,new v({name:"FocalPlaneResolutionUnit"})],[41492,new v({name:"SubjectLocation"})],[41493,new v({name:"ExposureIndex"})],[41495,new v({name:"SensingMethod"})],[41728,new v({name:"FileSource"})],[41729,new v({name:"SceneType"})],[41730,new v({name:"CVAPattern"})],[41985,new v({name:"CustomRendered"})],[41986,new v({name:"ExposureMode"})],[41987,new v({name:"WhiteBalance"})],[41988,new v({name:"DigitalZoomRatio"})],[41989,new v({name:"FocalLengthIn35mmFilm"})],[41990,new v({name:"SceneCaptureType"})],[41991,new v({name:"GainControl"})],[41992,new v({name:"Contrast"})],[41993,new v({name:"Saturation"})],[41994,new v({name:"Sharpness"})],[41995,new v({name:"DeviceSettingDescription"})],[41996,new v({name:"SubjectDistanceRange"})],[42016,new v({name:"ImageUniqueID"})],[42032,new v({name:"CameraOwnerName",type:2})],[42033,new v({name:"BodySerialNumber",type:2})],[42034,new v({name:"LensSpecification"})],[42035,new v({name:"LensMake",type:2})],[42036,new v({name:"LensModel",type:2})],[42037,new v({name:"LensSerialNumber",type:2})],[42240,new v({name:"Gamma",type:5,count:1})],[50341,new v({name:"PrintIM"})],[59932,new v({name:"Padding"})],[59933,new v({name:"OffsetSchema"})],[65e3,new v({name:"OwnerName",type:2})],[65001,new v({name:"SerialNumber",type:2})]]),qs=new Map([[1,new v({name:"InteropIndex",type:2})],[2,new v({name:"InteropVersion",type:7})],[4096,new v({name:"RelatedImageFileFormat",type:2})],[4097,new v({name:"RelatedImageWidth",type:3,count:1})],[4098,new v({name:"RelatedImageLength",type:3,count:1})]]),Gs=new Map([[0,new v({name:"GPSVersionID"})],[1,new v({name:"GPSLatitudeRef"})],[2,new v({name:"GPSLatitude"})],[3,new v({name:"GPSLongitudeRef"})],[4,new v({name:"GPSLongitude"})],[5,new v({name:"GPSAltitudeRef"})],[6,new v({name:"GPSAltitude"})],[7,new v({name:"GPSTimeStamp"})],[8,new v({name:"GPSSatellites"})],[9,new v({name:"GPSStatus"})],[10,new v({name:"GPSMeasureMode"})],[11,new v({name:"GPSDOP"})],[12,new v({name:"GPSSpeedRef"})],[13,new v({name:"GPSSpeed"})],[14,new v({name:"GPSTrackRef"})],[15,new v({name:"GPSTrack"})],[16,new v({name:"GPSImgDirectionRef"})],[17,new v({name:"GPSImgDirection"})],[18,new v({name:"GPSMapDatum"})],[19,new v({name:"GPSDestLatitudeRef"})],[20,new v({name:"GPSDestLatitude"})],[21,new v({name:"GPSDestLongitudeRef"})],[22,new v({name:"GPSDestLongitude"})],[23,new v({name:"GPSDestBearingRef"})],[24,new v({name:"GPSDestBearing"})],[25,new v({name:"GPSDestDistanceRef"})],[26,new v({name:"GPSDestDistance"})],[27,new v({name:"GPSProcessingMethod"})],[28,new v({name:"GPSAreaInformation"})],[29,new v({name:"GPSDate"})],[30,new v({name:"GPSDifferential"})]])});var ue,Ve=A(()=>{"use strict";sn();be();xe();ue=class{get type(){return 0}get length(){return 0}get dataSize(){return ss(this.type,this.length)}get typeString(){return as(this.type)}toBool(e){return!1}toInt(e){return 0}toDouble(e){return 0}toData(){return new Uint8Array}toRational(e){return new fe(0,1)}write(e){}setBool(e,t){}setInt(e,t){}setDouble(e,t){}setRational(e,t,n){}setString(e){}equals(e){return!1}clone(){throw new T("Cannot be copied.")}toString(){return`${this.constructor.name}`}}});var Ue,Nn=A(()=>{"use strict";nn();Ve();xe();Ue=class extends ue{constructor(t){super();typeof t=="string"?this._value=t:this._value=String.fromCharCode(...t)}get type(){return 2}get length(){return we.getCodePoints(this._value).length+1}static data(t,n){let i=n>0?t.readString(n-1):"";return new Ue(i)}toData(){return we.getCodePoints(this._value)}write(t){let n=we.getCodePoints(this._value);t.writeBytes(n),t.writeByte(0)}setString(t){this._value=t}equals(t){return t instanceof Ue&&this.length===t.length&&this._value===this._value}clone(){return new Ue(this._value)}toString(){return`${this.constructor.name} (${this._value})`}}});var qe,_i=A(()=>{"use strict";Ve();xe();G();qe=class extends ue{constructor(t){super();typeof t=="number"?(this._value=new Uint16Array(1),this._value[0]=t):this._value=Uint16Array.from(t)}get type(){return 3}get length(){return this._value.length}static data(t,n){let i=new Uint16Array(n);for(let r=0;r{"use strict";Ve();xe();sn();G();Se=class extends ue{constructor(t){super();t instanceof fe?this._value=[t]:this._value=t}get type(){return 5}get length(){return this._value.length}static data(t,n){let i=new Array;for(let r=0;r{"use strict";Ve();xe();G();Ze=class extends ue{constructor(t){super();typeof t=="number"?(this._value=new Uint8Array(1),this._value[0]=t):this._value=Uint8Array.from(t)}get type(){return 1}get length(){return this._value.length}static data(t,n,i){let r=t.toUint8Array(n,i);return new Ze(r)}toInt(t=0){return this._value[t]}toData(){return this._value}write(t){t.writeBytes(this._value)}setInt(t,n=0){this._value[n]=t}equals(t){return t instanceof Ze&&this.length===t.length&&U.equals(this._value,t._value)}clone(){return new Ze(this._value)}toString(){return`${this.constructor.name} (${this._value.length===1?`${this._value[0]}`:`${this._value}`})`}}});var Te,Vn=A(()=>{"use strict";Ve();xe();G();Te=class extends ue{constructor(t){super();typeof t=="number"?(this._value=new Uint32Array(1),this._value[0]=t):this._value=Uint32Array.from(t)}get type(){return 4}get length(){return this._value.length}static data(t,n){let i=new Uint32Array(n);for(let r=0;r{"use strict";Ve();xe();G();_t=class extends ue{constructor(t){super();typeof t=="number"?(this._value=new Int8Array(1),this._value[0]=t):this._value=Int8Array.from(t)}get type(){return 6}get length(){return this._value.length}static data(t,n,i){let r=new Int8Array(new Int8Array(t.toUint8Array(n,i).buffer));return new _t(r)}toInt(t=0){return this._value[t]}toData(){return new Uint8Array(this._value.buffer)}write(t){t.writeBytes(new Uint8Array(this._value.buffer))}setInt(t,n=0){this._value[n]=t}equals(t){return t instanceof _t&&this.length===t.length&&U.equals(this._value,t._value)}clone(){return new _t(this._value)}toString(){return`${this.constructor.name} (${this._value.length===1?`${this._value[0]}`:`${this._value}`})`}}});var Ft,Ln=A(()=>{"use strict";Ve();xe();G();Ft=class extends ue{constructor(t){super();typeof t=="number"?(this._value=new Uint8Array(1),this._value[0]=t):this._value=t}get type(){return 7}get length(){return this._value.length}static data(t,n,i){let r=new Uint8Array(t.toUint8Array(n,i));return new Ft(r)}toData(){return this._value}write(t){t.writeBytes(this._value)}equals(t){return t instanceof Ft&&this.length===t.length&&U.equals(this._value,t._value)}clone(){return new Ft(this._value)}toString(){return`${this.constructor.name} (undefined)`}}});var Qe,En=A(()=>{"use strict";Ve();xe();G();Qe=class extends ue{constructor(t){super();typeof t=="number"?(this._value=new Int16Array(1),this._value[0]=t):this._value=Int16Array.from(t)}get type(){return 8}get length(){return this._value.length}static data(t,n){let i=new Int16Array(n);for(let r=0;r{"use strict";Ve();xe();Jt();G();yt=class extends ue{constructor(t){super();typeof t=="number"?(this._value=new Int32Array(1),this._value[0]=t):this._value=Int32Array.from(t)}get type(){return 9}get length(){return this._value.length}static data(t,n){let i=new Int32Array(n);for(let r=0;r{"use strict";Ve();xe();Jt();sn();G();Ge=class extends ue{constructor(t){super();t instanceof fe?this._value=[t]:this._value=t}get type(){return 10}get length(){return this._value.length}static data(t,n){let i=new Array;for(let r=0;r{"use strict";Ve();xe();G();Ct=class extends ue{constructor(t){super();typeof t=="number"?(this._value=new Float32Array(1),this._value[0]=t):this._value=Float32Array.from(t)}get type(){return 11}get length(){return this._value.length}static data(t,n){let i=new Float32Array(n);for(let r=0;r{"use strict";Ve();xe();G();wt=class extends ue{constructor(t){super();typeof t=="number"?(this._value=new Float64Array(1),this._value[0]=t):this._value=Float64Array.from(t)}get type(){return 12}get length(){return this._value.length}static data(t,n){let i=new Float64Array(n);for(let r=0;r{"use strict";sn();_n();xe();Ci();Ve();Nn();_i();Rn();Dn();Vn();Tn();Ln();En();Hn();qn();Gn();$n();nn();G();Nt=class{constructor(e){this._sub=new ln;this._data=e!=null?e:new Map}get sub(){return this._sub}get keys(){return this._data.keys()}get values(){return this._data.values()}get size(){return this._data.size}get isEmpty(){return this._data.size===0&&this._sub.isEmpty}get hasUserComment(){return this._data.has(37510)}get userComment(){var t;let e=(t=this._data.get(37510))==null?void 0:t.toData();return e!==void 0?we.utf8Decoder.decode(e):void 0}set userComment(e){if(e===void 0)this._data.delete(37510);else{let t=we.getCodePoints(e);this._data.set(37510,new Ft(t))}}get hasImageDescription(){return this._data.has(270)}get imageDescription(){var e;return(e=this._data.get(270))==null?void 0:e.toString()}set imageDescription(e){e===void 0?this._data.delete(270):this._data.set(270,new Ue(e))}get hasMake(){return this._data.has(271)}get make(){var e;return(e=this._data.get(271))==null?void 0:e.toString()}set make(e){e===void 0?this._data.delete(271):this._data.set(271,new Ue(e))}get hasModel(){return this._data.has(272)}get model(){var e;return(e=this._data.get(272))==null?void 0:e.toString()}set model(e){e===void 0?this._data.delete(272):this._data.set(272,new Ue(e))}get hasOrientation(){return this._data.has(274)}get orientation(){var e;return(e=this._data.get(274))==null?void 0:e.toInt()}set orientation(e){e===void 0?this._data.delete(274):this._data.set(274,new qe(e))}get hasResolutionX(){return this._data.has(282)}get resolutionX(){var e;return(e=this._data.get(282))==null?void 0:e.toRational()}set resolutionX(e){this.setRational(282,e)||this._data.delete(282)}get hasResolutionY(){return this._data.has(283)}get resolutionY(){var e;return(e=this._data.get(283))==null?void 0:e.toRational()}set resolutionY(e){this.setRational(283,e)||this._data.delete(283)}get hasResolutionUnit(){return this._data.has(296)}get resolutionUnit(){var e;return(e=this._data.get(296))==null?void 0:e.toInt()}set resolutionUnit(e){e===void 0?this._data.delete(296):this._data.set(296,new qe(Math.trunc(e)))}get hasImageWidth(){return this._data.has(256)}get imageWidth(){var e;return(e=this._data.get(256))==null?void 0:e.toInt()}set imageWidth(e){e===void 0?this._data.delete(256):this._data.set(256,new qe(Math.trunc(e)))}get hasImageHeight(){return this._data.has(257)}get imageHeight(){var e;return(e=this._data.get(257))==null?void 0:e.toInt()}set imageHeight(e){e===void 0?this._data.delete(257):this._data.set(257,new qe(Math.trunc(e)))}get hasSoftware(){return this._data.has(305)}get software(){var e;return(e=this._data.get(305))==null?void 0:e.toString()}set software(e){e===void 0?this._data.delete(305):this._data.set(305,new Ue(e))}get hasCopyright(){return this._data.has(33432)}get copyright(){var e;return(e=this._data.get(33432))==null?void 0:e.toString()}set copyright(e){e===void 0?this._data.delete(33432):this._data.set(33432,new Ue(e))}get dataSize(){let t=2+12*this.size+4;for(let n of this.values){let i=n.dataSize;i>4&&(t+=i)}for(let n of this.sub.keys){let i=this.sub.get(n),r=2+12*i.size;for(let a of i.values){let s=a.dataSize;s>4&&(r+=s)}t+=r}return t}setRational(e,t){if(t instanceof fe)return this._data.set(e,Se.from(t)),!0;if(U.isNumArrayOrTypedArray(t)&&t.length>=2){let n=new fe(t[0],t[1]);return this._data.set(e,Se.from(n)),!0}return!1}static from(e){return new Nt(new Map(e._data))}static isArrayOfRationalNumbers(e){return Array.isArray(e)&&e.every(t=>U.isNumArrayOrTypedArray(t)&&t.length>=2)}has(e){return this._data.has(e)}getValue(e){let t=e;if(typeof t=="string"&&(t=ne.get(t)),typeof t=="number")return this._data.get(t)}setValue(e,t){let n=e;if(typeof n=="string"&&(n=ne.get(n)),typeof n=="number")if(t===void 0)this._data.delete(n);else if(t instanceof ue)this._data.set(n,t);else{let i=On.get(n);if(i!==void 0)switch(i.type){case 1:U.isNumArrayOrTypedArray(t)?this._data.set(n,new Ze(new Uint8Array(t))):typeof t=="number"&&this._data.set(n,new Ze(t));break;case 2:typeof t=="string"&&this._data.set(n,new Ue(t));break;case 3:U.isNumArrayOrTypedArray(t)?this._data.set(n,new qe(new Uint16Array(t))):typeof t=="number"&&this._data.set(n,new qe(t));break;case 4:U.isNumArrayOrTypedArray(t)?this._data.set(n,new Te(new Uint32Array(t))):typeof t=="number"&&this._data.set(n,new Te(t));break;case 5:if(U.isArrayOfRational(t))this._data.set(n,new Se(t));else if(U.isNumArrayOrTypedArray(t)&&t.length>=2){let a=new fe(t[0],t[1]);this._data.set(n,new Se(a))}else t instanceof fe&&this._data.set(n,new Se(t));break;case 6:U.isNumArrayOrTypedArray(t)?this._data.set(n,new _t(new Int8Array(t))):typeof t=="number"&&this._data.set(n,new _t(t));break;case 7:U.isNumArrayOrTypedArray(t)&&this._data.set(n,new Ft(new Uint8Array(t)));break;case 8:U.isNumArrayOrTypedArray(t)?this._data.set(n,new Qe(new Int16Array(t))):typeof t=="number"&&this._data.set(n,new Qe(t));break;case 9:U.isNumArrayOrTypedArray(t)?this._data.set(n,new yt(new Int32Array(t))):typeof t=="number"&&this._data.set(n,new yt(t));break;case 10:if(U.isArrayOfRational(t))this._data.set(n,new Ge(t));else if(U.isNumArrayOrTypedArray(t)&&t.length>=2){let a=new fe(t[0],t[1]);this._data.set(n,new Ge(a))}else t instanceof fe&&this._data.set(n,new Ge(t));break;case 11:U.isNumArrayOrTypedArray(t)?this._data.set(n,new Ct(new Float32Array(t))):typeof t=="number"&&this._data.set(n,new Ct(t));break;case 12:U.isNumArrayOrTypedArray(t)?this._data.set(n,new wt(new Float64Array(t))):typeof t=="number"&&this._data.set(n,new wt(t));break;case 0:break}}}copyFrom(e){e._data.forEach((t,n)=>this._data.set(n,t.clone()))}clone(){return Nt.from(this)}}});var ln,Ci=A(()=>{"use strict";yi();ln=class{get keys(){return this.directories.keys()}get values(){return this.directories.values()}get size(){return this.directories.size}get isEmpty(){if(this.directories.size===0)return!0;for(let e of this.directories.values())if(!e.isEmpty)return!1;return!0}constructor(e){this.directories=e!=null?e:new Map}static from(e){let t=new Map(e.directories);return new ln(t)}has(e){return this.directories.has(e)}get(e){let t=this.directories.get(e);return t===void 0&&(t=new Nt,this.directories.set(e,t)),t}set(e,t){this.directories.set(e,t)}clear(){this.directories.clear()}}});var Ie,Tt=A(()=>{"use strict";mr();_n();Ci();yi();xe();Nn();Dn();$n();Vn();Rn();Tn();_i();Gn();Hn();qn();En();Ln();Ie=class extends ln{get imageIfd(){return this.get("ifd0")}get thumbnailIfd(){return this.get("ifd1")}get exifIfd(){return this.get("ifd0").sub.get("exif")}get gpsIfd(){return this.get("ifd0").sub.get("gps")}get interopIfd(){return this.get("ifd0").sub.get("interop")}get dataSize(){var e,t;return 8+((t=(e=this.directories.get("ifd0"))==null?void 0:e.dataSize)!=null?t:0)}writeDirectory(e,t,n){let i=n,r=ne.get("StripOffsets");e.writeUint16(t.size);for(let a of t.keys){let s=t.getValue(a),u=a===r&&s.type===7?4:s.type,o=a===r&&s.type===7?1:s.length;e.writeUint16(a),e.writeUint16(u),e.writeUint32(o);let l=s.dataSize;if(l<=4)for(s.write(e);l<4;)e.writeByte(0),l++;else e.writeUint32(i),i+=l}return i}writeDirectoryLargeValues(e,t){for(let n of t.values)n.dataSize>4&&n.write(e)}readEntry(e,t){let n=e.readUint16(),i=e.readUint16(),r=e.readUint32(),a=new lr(n,void 0);if(i>Object.keys(Ce).length)return a;let s=i,u=xn[i],o=r*u,l=e.offset+4;if(o>4){let b=e.readUint32();e.offset=b+t}if(e.offset+o>e.end)return a;let m=e.readBytes(o);switch(s){case 0:break;case 6:a.value=_t.data(m,r);break;case 1:a.value=Ze.data(m,r);break;case 7:a.value=Ft.data(m,r);break;case 2:a.value=Ue.data(m,r);break;case 3:a.value=qe.data(m,r);break;case 4:a.value=Te.data(m,r);break;case 5:a.value=Se.data(m,r);break;case 10:a.value=Ge.data(m,r);break;case 8:a.value=Qe.data(m,r);break;case 9:a.value=yt.data(m,r);break;case 11:a.value=Ct.data(m,r);break;case 12:a.value=wt.data(m,r);break}return e.offset=l,a}static from(e){let t=new Map(e.directories);return new Ie(t)}static fromInputBuffer(e){let t=new Ie;return t.read(e),t}hasTag(e){for(let t of this.directories.values())if(t.has(e))return!0;return!1}getTag(e){for(let t of this.directories.values())if(t.has(e))return t.getValue(e)}getTagName(e){var t,n;return(n=(t=On.get(e))==null?void 0:t.name)!=null?n:""}write(e){let t=e.bigEndian;e.bigEndian=!0,e.writeUint16(19789),e.writeUint16(42),e.writeUint32(8),this.directories.get("ifd0")===void 0&&this.directories.set("ifd0",new Nt);let n=8,i=new Map;for(let[a,s]of this.directories){i.set(a,n),s.sub.has("exif")?s.setValue(34665,new Te(0)):s.setValue(34665,void 0),s.sub.has("interop")?s.setValue(40965,new Te(0)):s.setValue(40965,void 0),s.sub.has("gps")?s.setValue(34853,new Te(0)):s.setValue(34853,void 0),n+=2+12*s.size+4;for(let u of s.values){let o=u.dataSize;o>4&&(n+=o)}for(let u of s.sub.keys){let o=s.sub.get(u);i.set(u,n);let l=2+12*o.size;for(let m of o.values){let b=m.dataSize;b>4&&(l+=b)}n+=l}}let r=Array.from(this.directories);for(let a=0;a0;){e.offset=n+r;let u=new Nt,o=e.readUint16(),l=new Array;for(let m=0;m{"use strict";us=[[[0,0,0],[0,0,0],[0,0,0]],[[.375,1,0],[.375,0,1],[.25,1,1]],[[.4375,1,0],[.1875,-1,1],[.3125,0,1],[.0625,1,1]],[[.19047619047619047,1,0],[.09523809523809523,2,0],[.047619047619047616,-2,1],[.09523809523809523,-1,1],[.19047619047619047,0,1],[.09523809523809523,1,1],[.047619047619047616,2,1],[.023809523809523808,-2,2],[.047619047619047616,-1,2],[.09523809523809523,0,2],[.047619047619047616,1,2],[.023809523809523808,2,2]],[[.125,1,0],[.125,2,0],[.125,-1,1],[.125,0,1],[.125,1,1],[.125,0,2]]]});var Yn=A(()=>{"use strict"});var Ke,hr=A(()=>{"use strict";oe();ae();H();G();un();wi();Ke=class{get image(){return this._image}get x(){return this._x}get y(){return this._y}get xNormalized(){return this.width>1?this._x/(this.width-1):0}get yNormalized(){return this.height>1?this._y/(this.height-1):0}get index(){return this.r}set index(e){this.r=e}get data(){return this._image.data}get isValid(){return this._x>=0&&this._x=0&&this._y0?R.float16ToDouble(this.data[this._index]):0}set r(e){this.numChannels>0&&(this.data[this._index]=R.doubleToFloat16(e))}get g(){return this.numChannels>1?R.float16ToDouble(this.data[this._index+1]):0}set g(e){this.numChannels>1&&(this.data[this._index+1]=R.doubleToFloat16(e))}get b(){return this.numChannels>2?R.float16ToDouble(this.data[this._index+2]):0}set b(e){this.numChannels>2&&(this.data[this._index+2]=R.doubleToFloat16(e))}get a(){return this.numChannels>3?R.float16ToDouble(this.data[this._index+3]):0}set a(e){this.numChannels>3&&(this.data[this._index+3]=R.doubleToFloat16(e))}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e,t,n,i){this._image=i,this._index=n,this._x=e,this._y=t}static imageData(e){return new Ke(-1,0,-e.numChannels,e)}static image(e){return new Ke(-1,0,-e.numChannels,e.data instanceof Lt?e.data:new Lt(0,0,0))}static from(e){return new Ke(e.x,e.y,e._index,e.image)}next(){return this._x++,this._x===this.width&&(this._x=0,this._y++,this._y===this.height)?{done:!0,value:this}:(this._index+=this.numChannels,{done:this._index>=this.image.data.length,value:this})}setPosition(e,t){this._x=e,this._y=t,this._index=this._y*this._image.width*this._image.numChannels+this._x*this._image.numChannels}setPositionNormalized(e,t){return this.setPosition(Math.floor(e*(this.width-1)),Math.floor(t*(this.height-1)))}getChannel(e){return e===4?this.luminance:e0&&(this.r=e.r,this.g=e.g,this.b=e.b,this.a=e.a)}setRgb(e,t,n){this.numChannels>0&&(this.data[this._index]=R.doubleToFloat16(e),this.numChannels>1&&(this.data[this._index+1]=R.doubleToFloat16(t),this.numChannels>2&&(this.data[this._index+2]=R.doubleToFloat16(n))))}setRgba(e,t,n,i){this.numChannels>0&&(this.data[this._index]=R.doubleToFloat16(e),this.numChannels>1&&(this.data[this._index+1]=R.doubleToFloat16(t),this.numChannels>2&&(this.data[this._index+2]=R.doubleToFloat16(n),this.numChannels>3&&(this.data[this._index+3]=R.doubleToFloat16(i)))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}equals(e){return e instanceof Ke?U.equals(this.toArray(),e.toArray()):Array.isArray(e)?U.equals(this.toArray(),e):!1}clone(){return Ke.from(this)}convert(e){return z.convertColor({from:this,format:e.format,numChannels:e.numChannels,alpha:e.alpha})}[Symbol.iterator](){return this}}});var le,$e=A(()=>{"use strict";le=class{constructor(e,t,n,i,r){this._pixel=e,this._x1=t,this._y1=n,this._x2=t+i-1,this._y2=n+r-1,this._pixel.setPosition(t-1,n)}next(){return this._pixel.x+1>this._x2?(this._pixel.setPosition(this._x1,this._pixel.y+1),{done:this._pixel.y>this._y2,value:this._pixel}):this._pixel.next()}[Symbol.iterator](){return this}}});var Lt,wi=A(()=>{"use strict";De();H();hr();$e();fi();un();Lt=class{get width(){return this._width}get height(){return this._height}get data(){return this._data}get numChannels(){return this._numChannels}get format(){return 9}get formatType(){return 2}get buffer(){return this._data.buffer}get rowStride(){return this._width*this._numChannels*2}get iterator(){return Ke.imageData(this)}get byteLength(){return this._data.byteLength}get length(){return this._data.byteLength}get maxChannelValue(){return 1}get maxIndexValue(){return 1}get hasPalette(){return this.palette!==void 0}get palette(){}get isHdrFormat(){return!0}get isLdrFormat(){return!this.isHdrFormat}get bitsPerChannel(){return 16}constructor(e,t,n,i){this._width=e,this._height=t,this._numChannels=n,this._data=i!=null?i:new Uint16Array(this._width*this._height*this._numChannels)}static from(e,t=!1){let n=t?new Uint16Array(e.data.length):e.data.slice();return new Lt(e.width,e.height,e._numChannels,n)}getRange(e,t,n,i){return new le(Ke.imageData(this),e,t,n,i)}getColor(e,t,n,i){return i===void 0?xt.rgb(e,t,n):xt.rgba(e,t,n,i)}getPixel(e,t,n){let i=n;return(i===void 0||!(i instanceof Ke)||i.image!==this)&&(i=Ke.imageData(this)),i.setPosition(e,t),i}setPixel(e,t,n){this.setPixelRgba(e,t,n.r,n.g,n.b,n.a)}setPixelR(e,t,n){let i=t*this._width*this._numChannels+e*this.numChannels;this.data[i]=R.doubleToFloat16(n)}setPixelRgb(e,t,n,i,r){let a=t*this._width*this._numChannels+e*this._numChannels;this._data[a]=R.doubleToFloat16(n),this._numChannels>1&&(this._data[a+1]=R.doubleToFloat16(i),this._numChannels>2&&(this._data[a+2]=R.doubleToFloat16(r)))}setPixelRgba(e,t,n,i,r,a){let s=t*this._width*this._numChannels+e*this._numChannels;this._data[s]=R.doubleToFloat16(n),this._numChannels>1&&(this._data[s+1]=R.doubleToFloat16(i),this._numChannels>2&&(this._data[s+2]=R.doubleToFloat16(r),this._numChannels>3&&(this._data[s+3]=R.doubleToFloat16(a))))}setPixelRgbSafe(e,t,n,i,r){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgb(e,t,n,i,r)}setPixelRgbaSafe(e,t,n,i,r,a){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgba(e,t,n,i,r,a)}clear(e){}clone(e=!1){return Lt.from(this,e)}toUint8Array(){return new Uint8Array(this.buffer)}getBytes(e){if(e===void 0)return this.toUint8Array();if(this.numChannels===4){if(e===2||e===3||e===1){let t=this.clone();if(e===2)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=a,n.b=r,n.a=i}else if(e===3)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=i,n.b=r,n.a=a}else if(e===1)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=a,n.g=r,n.b=i,n.a=s}return t.toUint8Array()}}else if(this.numChannels===3&&e===5){let t=this.clone();for(let n of t){let i=n.r;n.r=n.b,n.b=i}return t.toUint8Array()}return this.toUint8Array()}toString(){return`${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`}[Symbol.iterator](){return Ke.imageData(this)}}});var Je,cr=A(()=>{"use strict";oe();ae();H();G();vi();Je=class{get image(){return this._image}get x(){return this._x}get y(){return this._y}get xNormalized(){return this.width>1?this._x/(this.width-1):0}get yNormalized(){return this.height>1?this._y/(this.height-1):0}get index(){return this.r}set index(e){this.r=e}get data(){return this._image.data}get isValid(){return this._x>=0&&this._x=0&&this._y0?this.data[this._index]:0}set r(e){this.numChannels>0&&(this.data[this._index]=e)}get g(){return this.numChannels>1?this.data[this._index+1]:0}set g(e){this.numChannels>1&&(this.data[this._index+1]=e)}get b(){return this.numChannels>2?this.data[this._index+2]:0}set b(e){this.numChannels>2&&(this.data[this._index+2]=e)}get a(){return this.numChannels>3?this.data[this._index+3]:1}set a(e){this.numChannels>3&&(this.data[this._index+3]=e)}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e,t,n,i){this._image=i,this._index=n,this._x=e,this._y=t}static imageData(e){return new Je(-1,0,-e.numChannels,e)}static image(e){return new Je(-1,0,-e.numChannels,e.data instanceof Et?e.data:new Et(0,0,0))}static from(e){return new Je(e.x,e.y,e._index,e.image)}next(){return this._x++,this._x===this.width&&(this._x=0,this._y++,this._y===this.height)?{done:!0,value:this}:(this._index+=this.numChannels,{done:this._index>=this.image.data.length,value:this})}setPosition(e,t){this._x=e,this._y=t,this._index=this._y*this._image.width*this._image.numChannels+this._x*this._image.numChannels}setPositionNormalized(e,t){return this.setPosition(Math.floor(e*(this.width-1)),Math.floor(t*(this.height-1)))}getChannel(e){return e===4?this.luminance:e0&&(this.data[this._index]=e,this.numChannels>1&&(this.data[this._index+1]=t,this.numChannels>2&&(this.data[this._index+2]=n)))}setRgba(e,t,n,i){this.numChannels>0&&(this.data[this._index]=e,this.numChannels>1&&(this.data[this._index+1]=t,this.numChannels>2&&(this.data[this._index+2]=n,this.numChannels>3&&(this.data[this._index+3]=i))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}equals(e){return e instanceof Je?U.equals(this.toArray(),e.toArray()):Array.isArray(e)?U.equals(this.toArray(),e):!1}clone(){return Je.from(this)}convert(e){return z.convertColor({from:this,format:e.format,numChannels:e.numChannels,alpha:e.alpha})}toString(){return`${this.constructor.name} (${this.toArray()})`}[Symbol.iterator](){return this}}});var Et,vi=A(()=>{"use strict";De();H();cr();$e();ri();Et=class{get width(){return this._width}get height(){return this._height}get data(){return this._data}get numChannels(){return this._numChannels}get format(){return 10}get formatType(){return 2}get buffer(){return this._data.buffer}get rowStride(){return this._width*this._numChannels*4}get iterator(){return Je.imageData(this)}get byteLength(){return this._data.byteLength}get length(){return this._data.byteLength}get maxChannelValue(){return 1}get maxIndexValue(){return 1}get hasPalette(){return this.palette!==void 0}get palette(){}get isHdrFormat(){return!0}get isLdrFormat(){return!this.isHdrFormat}get bitsPerChannel(){return 32}constructor(e,t,n,i){this._width=e,this._height=t,this._numChannels=n,this._data=i!=null?i:new Float32Array(this._width*this._height*this._numChannels)}static from(e,t=!1){let n=t?new Float32Array(e.data.length):e.data.slice();return new Et(e.width,e.height,e._numChannels,n)}getRange(e,t,n,i){return new le(Je.imageData(this),e,t,n,i)}getColor(e,t,n,i){return i===void 0?ot.rgb(e,t,n):ot.rgba(e,t,n,i)}getPixel(e,t,n){let i=n;return(i===void 0||!(i instanceof Je)||i.image!==this)&&(i=Je.imageData(this)),i.setPosition(e,t),i}setPixel(e,t,n){this.setPixelRgba(e,t,n.r,n.g,n.b,n.a)}setPixelR(e,t,n){let i=t*this._width*this._numChannels+e*this.numChannels;this.data[i]=n}setPixelRgb(e,t,n,i,r){let a=t*this._width*this._numChannels+e*this._numChannels;this._data[a]=n,this._numChannels>1&&(this._data[a+1]=i,this._numChannels>2&&(this._data[a+2]=r))}setPixelRgba(e,t,n,i,r,a){let s=t*this._width*this._numChannels+e*this._numChannels;this._data[s]=n,this._numChannels>1&&(this._data[s+1]=i,this._numChannels>2&&(this._data[s+2]=r,this._numChannels>3&&(this._data[s+3]=a)))}setPixelRgbSafe(e,t,n,i,r){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgb(e,t,n,i,r)}setPixelRgbaSafe(e,t,n,i,r,a){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgba(e,t,n,i,r,a)}clear(e){}clone(e=!1){return Et.from(this,e)}toUint8Array(){return new Uint8Array(this.buffer)}getBytes(e){if(e===void 0)return this.toUint8Array();if(this.numChannels===4){if(e===2||e===3||e===1){let t=this.clone();if(e===2)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=a,n.b=r,n.a=i}else if(e===3)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=i,n.b=r,n.a=a}else if(e===1)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=a,n.g=r,n.b=i,n.a=s}return t.toUint8Array()}}else if(this.numChannels===3&&e===5){let t=this.clone();for(let n of t){let i=n.r;n.r=n.b,n.b=i}return t.toUint8Array()}return this.toUint8Array()}toString(){return`${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`}[Symbol.iterator](){return Je.imageData(this)}}});var et,br=A(()=>{"use strict";oe();ae();H();G();Ii();et=class{get image(){return this._image}get x(){return this._x}get y(){return this._y}get xNormalized(){return this.width>1?this._x/(this.width-1):0}get yNormalized(){return this.height>1?this._y/(this.height-1):0}get index(){return this.r}set index(e){this.r=e}get data(){return this._image.data}get isValid(){return this._x>=0&&this._x=0&&this._y0?this.data[this._index]:0}set r(e){this.numChannels>0&&(this.data[this._index]=e)}get g(){return this.numChannels>1?this.data[this._index+1]:0}set g(e){this.numChannels>1&&(this.data[this._index+1]=e)}get b(){return this.numChannels>2?this.data[this._index+2]:0}set b(e){this.numChannels>2&&(this.data[this._index+2]=e)}get a(){return this.numChannels>3?this.data[this._index+3]:0}set a(e){this.numChannels>3&&(this.data[this._index+3]=e)}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e,t,n,i){this._image=i,this._index=n,this._x=e,this._y=t}static imageData(e){return new et(-1,0,-e.numChannels,e)}static image(e){return new et(-1,0,-e.numChannels,e.data instanceof Ht?e.data:new Ht(0,0,0))}static from(e){return new et(e.x,e.y,e._index,e.image)}[Symbol.iterator](){return this}next(){return this._x++,this._x===this.width&&(this._x=0,this._y++,this._y===this.height)?{done:!0,value:this}:(this._index+=this.numChannels,{done:this._index>=this.image.data.length,value:this})}setPosition(e,t){this._x=e,this._y=t,this._index=this._y*this._image.width*this._image.numChannels+this._x*this._image.numChannels}setPositionNormalized(e,t){return this.setPosition(Math.floor(e*(this.width-1)),Math.floor(t*(this.height-1)))}getChannel(e){return e===4?this.luminance:e0&&(this.data[this._index]=e,this.numChannels>1&&(this.data[this._index+1]=t,this.numChannels>2&&(this.data[this._index+2]=n)))}setRgba(e,t,n,i){this.numChannels>0&&(this.data[this._index]=e,this.numChannels>1&&(this.data[this._index+1]=t,this.numChannels>2&&(this.data[this._index+2]=n,this.numChannels>3&&(this.data[this._index+3]=i))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}equals(e){return e instanceof et?U.equals(this.toArray(),e.toArray()):Array.isArray(e)?U.equals(this.toArray(),e):!1}clone(){return et.from(this)}convert(e){return z.convertColor({from:this,format:e.format,numChannels:e.numChannels,alpha:e.alpha})}toString(){return`${this.constructor.name} (${this.toArray()})`}}});var Ht,Ii=A(()=>{"use strict";De();H();br();$e();ai();Ht=class{get width(){return this._width}get height(){return this._height}get data(){return this._data}get numChannels(){return this._numChannels}get format(){return 11}get formatType(){return 2}get buffer(){return this._data.buffer}get rowStride(){return this._width*this._numChannels*8}get iterator(){return et.imageData(this)}get byteLength(){return this._data.byteLength}get length(){return this._data.byteLength}get maxChannelValue(){return 1}get maxIndexValue(){return 1}get hasPalette(){return this.palette!==void 0}get palette(){}get isHdrFormat(){return!0}get isLdrFormat(){return!this.isHdrFormat}get bitsPerChannel(){return 64}constructor(e,t,n,i){this._width=e,this._height=t,this._numChannels=n,this._data=i!=null?i:new Float64Array(this._width*this._height*4*this._numChannels)}static from(e,t=!1){let n=t?new Float64Array(e.data.length):e.data.slice();return new Ht(e.width,e.height,e._numChannels,n)}getRange(e,t,n,i){return new le(et.imageData(this),e,t,n,i)}getColor(e,t,n,i){return i===void 0?lt.rgb(e,t,n):lt.rgba(e,t,n,i)}getPixel(e,t,n){let i=n;return(i===void 0||!(i instanceof et)||i.image!==this)&&(i=et.imageData(this)),i.setPosition(e,t),i}setPixel(e,t,n){this.setPixelRgba(e,t,n.r,n.g,n.b,n.a)}setPixelR(e,t,n){let i=t*this._width*this._numChannels+e*this.numChannels;this.data[i]=n}setPixelRgb(e,t,n,i,r){let a=t*this._width*this._numChannels+e*this._numChannels;this._data[a]=n,this._numChannels>1&&(this._data[a+1]=i,this._numChannels>2&&(this._data[a+2]=r))}setPixelRgba(e,t,n,i,r,a){let s=t*this._width*this._numChannels+e*this._numChannels;this._data[s]=n,this._numChannels>1&&(this._data[s+1]=i,this._numChannels>2&&(this._data[s+2]=r,this._numChannels>3&&(this._data[s+3]=a)))}setPixelRgbSafe(e,t,n,i,r){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgb(e,t,n,i,r)}setPixelRgbaSafe(e,t,n,i,r,a){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgba(e,t,n,i,r,a)}clear(e){}clone(e=!1){return Ht.from(this,e)}toUint8Array(){return new Uint8Array(this.buffer)}getBytes(e){if(e===void 0)return this.toUint8Array();if(this.numChannels===4){if(e===2||e===3||e===1){let t=this.clone();if(e===2)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=a,n.b=r,n.a=i}else if(e===3)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=i,n.b=r,n.a=a}else if(e===1)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=a,n.g=r,n.b=i,n.a=s}return t.toUint8Array()}}else if(this.numChannels===3&&e===5){let t=this.clone();for(let n of t){let i=n.r;n.r=n.b,n.b=i}return t.toUint8Array()}return this.toUint8Array()}toString(){return`${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`}[Symbol.iterator](){return et.imageData(this)}}});var tt,fr=A(()=>{"use strict";oe();ae();H();G();Pi();tt=class{get image(){return this._image}get x(){return this._x}get y(){return this._y}get xNormalized(){return this.width>1?this._x/(this.width-1):0}get yNormalized(){return this.height>1?this._y/(this.height-1):0}get index(){return this.r}set index(e){this.r=e}get data(){return this._image.data}get isValid(){return this._x>=0&&this._x=0&&this._y0?this.data[this._index]:0}set r(e){this.numChannels>0&&(this.data[this._index]=Math.trunc(e))}get g(){return this.numChannels>1?this.data[this._index+1]:0}set g(e){this.numChannels>1&&(this.data[this._index+1]=Math.trunc(e))}get b(){return this.numChannels>2?this.data[this._index+2]:0}set b(e){this.numChannels>2&&(this.data[this._index+2]=Math.trunc(e))}get a(){return this.numChannels>3?this.data[this._index+3]:0}set a(e){this.numChannels>3&&(this.data[this._index+3]=Math.trunc(e))}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e,t,n,i){this._image=i,this._index=n,this._x=e,this._y=t}static imageData(e){return new tt(-1,0,-e.numChannels,e)}static image(e){return new tt(-1,0,-e.numChannels,e.data instanceof qt?e.data:new qt(0,0,0))}static from(e){return new tt(e.x,e.y,e._index,e.image)}next(){return this._x++,this._x===this.width&&(this._x=0,this._y++,this._y===this.height)?{done:!0,value:this}:(this._index+=this.numChannels,{done:this._index>=this.image.data.length,value:this})}setPosition(e,t){this._x=e,this._y=t,this._index=this._y*this._image.width*this._image.numChannels+this._x*this._image.numChannels}setPositionNormalized(e,t){return this.setPosition(Math.floor(e*(this.width-1)),Math.floor(t*(this.height-1)))}getChannel(e){return e===4?this.luminance:e0&&(this.data[this._index]=Math.trunc(e),this.numChannels>1&&(this.data[this._index+1]=Math.trunc(t),this.numChannels>2&&(this.data[this._index+2]=Math.trunc(n))))}setRgba(e,t,n,i){this.numChannels>0&&(this.data[this._index]=Math.trunc(e),this.numChannels>1&&(this.data[this._index+1]=Math.trunc(t),this.numChannels>2&&(this.data[this._index+2]=Math.trunc(n),this.numChannels>3&&(this.data[this._index+3]=Math.trunc(i)))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}equals(e){return e instanceof tt?U.equals(this.toArray(),e.toArray()):Array.isArray(e)?U.equals(this.toArray(),e):!1}clone(){return tt.from(this)}convert(e){return z.convertColor({from:this,format:e.format,numChannels:e.numChannels,alpha:e.alpha})}toString(){return`${this.constructor.name} (${this.toArray()})`}[Symbol.iterator](){return this}}});var qt,Pi=A(()=>{"use strict";De();si();H();fr();$e();qt=class{get width(){return this._width}get height(){return this._height}get data(){return this._data}get numChannels(){return this._numChannels}get format(){return 7}get formatType(){return 1}get buffer(){return this._data.buffer}get rowStride(){return this._width*this._numChannels*2}get iterator(){return tt.imageData(this)}get byteLength(){return this._data.byteLength}get length(){return this._data.byteLength}get maxChannelValue(){return 32767}get maxIndexValue(){return 32767}get hasPalette(){return this.palette!==void 0}get palette(){}get isHdrFormat(){return!0}get isLdrFormat(){return!this.isHdrFormat}get bitsPerChannel(){return 16}constructor(e,t,n,i){this._width=e,this._height=t,this._numChannels=n,this._data=i!=null?i:new Int16Array(this._width*this._height*this._numChannels)}static from(e,t=!1){let n=t?new Int16Array(e.data.length):e.data.slice();return new qt(e.width,e.height,e._numChannels,n)}getRange(e,t,n,i){return new le(tt.imageData(this),e,t,n,i)}getColor(e,t,n,i){return i===void 0?mt.rgb(Math.trunc(e),Math.trunc(t),Math.trunc(n)):mt.rgba(Math.trunc(e),Math.trunc(t),Math.trunc(n),Math.trunc(i))}getPixel(e,t,n){let i=n;return(i===void 0||!(i instanceof tt)||i.image!==this)&&(i=tt.imageData(this)),i.setPosition(e,t),i}setPixel(e,t,n){this.setPixelRgba(e,t,n.r,n.g,n.b,n.a)}setPixelR(e,t,n){let i=t*this.width*this.numChannels+e*this.numChannels;this.data[i]=Math.trunc(n)}setPixelRgb(e,t,n,i,r){let a=t*this.width*this.numChannels+e*this._numChannels;this._data[a]=Math.trunc(n),this._numChannels>1&&(this._data[a+1]=Math.trunc(i),this._numChannels>2&&(this._data[a+2]=Math.trunc(r)))}setPixelRgba(e,t,n,i,r,a){let s=t*this.width*this.numChannels+e*this._numChannels;this._data[s]=Math.trunc(n),this._numChannels>1&&(this._data[s+1]=Math.trunc(i),this._numChannels>2&&(this._data[s+2]=Math.trunc(r),this._numChannels>3&&(this._data[s+3]=Math.trunc(a))))}setPixelRgbSafe(e,t,n,i,r){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgb(e,t,n,i,r)}setPixelRgbaSafe(e,t,n,i,r,a){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgba(e,t,n,i,r,a)}clear(e){}clone(e=!1){return qt.from(this,e)}toUint8Array(){return new Uint8Array(this.buffer)}getBytes(e){if(e===void 0)return this.toUint8Array();if(this.numChannels===4){if(e===2||e===3||e===1){let t=this.clone();if(e===2)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=a,n.b=r,n.a=i}else if(e===3)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=i,n.b=r,n.a=a}else if(e===1)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=a,n.g=r,n.b=i,n.a=s}return t.toUint8Array()}}else if(this.numChannels===3&&e===5){let t=this.clone();for(let n of t){let i=n.r;n.r=n.b,n.b=i}return t.toUint8Array()}return this.toUint8Array()}toString(){return`${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`}[Symbol.iterator](){return tt.imageData(this)}}});var nt,dr=A(()=>{"use strict";oe();ae();H();G();Mi();nt=class{get image(){return this._image}get x(){return this._x}get y(){return this._y}get xNormalized(){return this.width>1?this._x/(this.width-1):0}get yNormalized(){return this.height>1?this._y/(this.height-1):0}get index(){return this.r}set index(e){this.r=e}get data(){return this._image.data}get isValid(){return this._x>=0&&this._x=0&&this._y0?this.data[this._index]:0}set r(e){this.numChannels>0&&(this.data[this._index]=Math.trunc(e))}get g(){return this.numChannels>1?this.data[this._index+1]:0}set g(e){this.numChannels>1&&(this.data[this._index+1]=Math.trunc(e))}get b(){return this.numChannels>2?this.data[this._index+2]:0}set b(e){this.numChannels>2&&(this.data[this._index+2]=Math.trunc(e))}get a(){return this.numChannels>3?this.data[this._index+3]:0}set a(e){this.numChannels>3&&(this.data[this._index+3]=Math.trunc(e))}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e,t,n,i){this._image=i,this._index=n,this._x=e,this._y=t}static imageData(e){return new nt(-1,0,-e.numChannels,e)}static image(e){return new nt(-1,0,-e.numChannels,e.data instanceof Gt?e.data:new Gt(0,0,0))}static from(e){return new nt(e.x,e.y,e._index,e.image)}next(){return this._x++,this._x===this.width&&(this._x=0,this._y++,this._y===this.height)?{done:!0,value:this}:(this._index+=this.numChannels,{done:this._index>=this.image.data.length,value:this})}setPosition(e,t){this._x=e,this._y=t,this._index=this._y*this._image.width*this._image.numChannels+this._x*this._image.numChannels}setPositionNormalized(e,t){return this.setPosition(Math.floor(e*(this.width-1)),Math.floor(t*(this.height-1)))}getChannel(e){return e===4?this.luminance:e0&&(this.data[this._index]=Math.trunc(e),this.numChannels>1&&(this.data[this._index+1]=Math.trunc(t),this.numChannels>2&&(this.data[this._index+2]=Math.trunc(n))))}setRgba(e,t,n,i){this.numChannels>0&&(this.data[this._index]=Math.trunc(e),this.numChannels>1&&(this.data[this._index+1]=Math.trunc(t),this.numChannels>2&&(this.data[this._index+2]=Math.trunc(n),this.numChannels>3&&(this.data[this._index+3]=Math.trunc(i)))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}equals(e){return e instanceof nt?U.equals(this.toArray(),e.toArray()):Array.isArray(e)?U.equals(this.toArray(),e):!1}clone(){return nt.from(this)}convert(e){return z.convertColor({from:this,format:e.format,numChannels:e.numChannels,alpha:e.alpha})}toString(){return`${this.constructor.name} (${this.toArray()})`}[Symbol.iterator](){return this}}});var Gt,Mi=A(()=>{"use strict";De();ui();H();dr();$e();Gt=class{get width(){return this._width}get height(){return this._height}get data(){return this._data}get numChannels(){return this._numChannels}get format(){return 8}get formatType(){return 1}get buffer(){return this._data.buffer}get rowStride(){return this._width*this._numChannels*4}get iterator(){return nt.imageData(this)}get byteLength(){return this._data.byteLength}get length(){return this._data.byteLength}get maxChannelValue(){return 2147483647}get maxIndexValue(){return 2147483647}get hasPalette(){return this.palette!==void 0}get palette(){}get isHdrFormat(){return!0}get isLdrFormat(){return!this.isHdrFormat}get bitsPerChannel(){return 32}constructor(e,t,n,i){this._width=e,this._height=t,this._numChannels=n,this._data=i!=null?i:new Int32Array(this._width*this._height*this._numChannels)}static from(e,t=!1){let n=t?new Int32Array(e.data.length):e.data.slice();return new Gt(e.width,e.height,e._numChannels,n)}getRange(e,t,n,i){return new le(nt.imageData(this),e,t,n,i)}getColor(e,t,n,i){return i===void 0?ht.rgb(Math.trunc(e),Math.trunc(t),Math.trunc(n)):ht.rgba(Math.trunc(e),Math.trunc(t),Math.trunc(n),Math.trunc(i))}getPixel(e,t,n){let i=n;return(i===void 0||!(i instanceof nt)||i.image!==this)&&(i=nt.imageData(this)),i.setPosition(e,t),i}setPixel(e,t,n){this.setPixelRgba(e,t,n.r,n.g,n.b,n.a)}setPixelR(e,t,n){let i=t*this.width*this.numChannels+e*this.numChannels;this.data[i]=Math.trunc(n)}setPixelRgb(e,t,n,i,r){let a=t*this.width*this.numChannels+e*this._numChannels;this._data[a]=Math.trunc(n),this._numChannels>1&&(this._data[a+1]=Math.trunc(i),this._numChannels>2&&(this._data[a+2]=Math.trunc(r)))}setPixelRgba(e,t,n,i,r,a){let s=t*this.width*this.numChannels+e*this._numChannels;this._data[s]=Math.trunc(n),this._numChannels>1&&(this._data[s+1]=Math.trunc(i),this._numChannels>2&&(this._data[s+2]=Math.trunc(r),this._numChannels>3&&(this._data[s+3]=Math.trunc(a))))}setPixelRgbSafe(e,t,n,i,r){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgb(e,t,n,i,r)}setPixelRgbaSafe(e,t,n,i,r,a){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgba(e,t,n,i,r,a)}clear(e){}clone(e=!1){return Gt.from(this,e)}toUint8Array(){return new Uint8Array(this.buffer)}getBytes(e){if(e===void 0)return this.toUint8Array();if(this.numChannels===4){if(e===2||e===3||e===1){let t=this.clone();if(e===2)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=a,n.b=r,n.a=i}else if(e===3)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=i,n.b=r,n.a=a}else if(e===1)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=a,n.g=r,n.b=i,n.a=s}return t.toUint8Array()}}else if(this.numChannels===3&&e===5){let t=this.clone();for(let n of t){let i=n.r;n.r=n.b,n.b=i}return t.toUint8Array()}return this.toUint8Array()}toString(){return`${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`}[Symbol.iterator](){return nt.imageData(this)}}});var it,pr=A(()=>{"use strict";oe();ae();H();G();Ai();it=class{get image(){return this._image}get x(){return this._x}get y(){return this._y}get xNormalized(){return this.width>1?this._x/(this.width-1):0}get yNormalized(){return this.height>1?this._y/(this.height-1):0}get index(){return this.r}set index(e){this.r=e}get data(){return this._image.data}get isValid(){return this._x>=0&&this._x=0&&this._y0?this.data[this._index]:0}set r(e){this.numChannels>0&&(this.data[this._index]=Math.trunc(e))}get g(){return this.numChannels>1?this.data[this._index+1]:0}set g(e){this.numChannels>1&&(this.data[this._index+1]=Math.trunc(e))}get b(){return this.numChannels>2?this.data[this._index+2]:0}set b(e){this.numChannels>2&&(this.data[this._index+2]=Math.trunc(e))}get a(){return this.numChannels>3?this.data[this._index+3]:0}set a(e){this.numChannels>3&&(this.data[this._index+3]=Math.trunc(e))}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e,t,n,i){this._image=i,this._index=n,this._x=e,this._y=t}static imageData(e){return new it(-1,0,-e.numChannels,e)}static image(e){return new it(-1,0,-e.numChannels,e.data instanceof $t?e.data:new $t(0,0,0))}static from(e){return new it(e.x,e.y,e._index,e.image)}next(){return this._x++,this._x===this.width&&(this._x=0,this._y++,this._y===this.height)?{done:!0,value:this}:(this._index+=this.numChannels,{done:this._index>=this.image.data.length,value:this})}setPosition(e,t){this._x=e,this._y=t,this._index=this._y*this._image.width*this._image.numChannels+this._x*this._image.numChannels}setPositionNormalized(e,t){return this.setPosition(Math.floor(e*(this.width-1)),Math.floor(t*(this.height-1)))}getChannel(e){return e===4?this.luminance:e0&&(this.data[this._index]=Math.trunc(e),this.numChannels>1&&(this.data[this._index+1]=Math.trunc(t),this.numChannels>2&&(this.data[this._index+2]=Math.trunc(n))))}setRgba(e,t,n,i){this.numChannels>0&&(this.data[this._index]=Math.trunc(e),this.numChannels>1&&(this.data[this._index+1]=Math.trunc(t),this.numChannels>2&&(this.data[this._index+2]=Math.trunc(n),this.numChannels>3&&(this.data[this._index+3]=Math.trunc(i)))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}equals(e){return e instanceof it?U.equals(this.toArray(),e.toArray()):Array.isArray(e)?U.equals(this.toArray(),e):!1}clone(){return it.from(this)}convert(e){return z.convertColor({from:this,format:e.format,numChannels:e.numChannels,alpha:e.alpha})}toString(){return`${this.constructor.name} (${this.toArray()})`}[Symbol.iterator](){return this}}});var $t,Ai=A(()=>{"use strict";De();oi();H();pr();$e();$t=class{get width(){return this._width}get height(){return this._height}get data(){return this._data}get numChannels(){return this._numChannels}get format(){return 6}get formatType(){return 1}get buffer(){return this._data.buffer}get rowStride(){return this._width*this._numChannels}get iterator(){return it.imageData(this)}get byteLength(){return this._data.byteLength}get length(){return this._data.byteLength}get maxChannelValue(){return 127}get maxIndexValue(){return 127}get hasPalette(){return this.palette!==void 0}get palette(){}get isHdrFormat(){return!0}get isLdrFormat(){return!this.isHdrFormat}get bitsPerChannel(){return 8}constructor(e,t,n,i){this._width=e,this._height=t,this._numChannels=n,this._data=i!=null?i:new Int8Array(this._width*this._height*this._numChannels)}static from(e,t=!1){let n=t?new Int8Array(e.data.length):e.data.slice();return new $t(e.width,e.height,e._numChannels,n)}getRange(e,t,n,i){return new le(it.imageData(this),e,t,n,i)}getColor(e,t,n,i){return i===void 0?ct.rgb(Math.trunc(e),Math.trunc(t),Math.trunc(n)):ct.rgba(Math.trunc(e),Math.trunc(t),Math.trunc(n),Math.trunc(i))}getPixel(e,t,n){let i=n;return(i===void 0||!(i instanceof it)||i.image!==this)&&(i=it.imageData(this)),i.setPosition(e,t),i}setPixel(e,t,n){this.setPixelRgba(e,t,n.r,n.g,n.b,n.a)}setPixelR(e,t,n){let i=t*this.rowStride+e*this.numChannels;this.data[i]=Math.trunc(n)}setPixelRgb(e,t,n,i,r){let a=t*this.rowStride+e*this._numChannels;this._data[a]=Math.trunc(n),this._numChannels>1&&(this._data[a+1]=Math.trunc(i),this._numChannels>2&&(this._data[a+2]=Math.trunc(r)))}setPixelRgba(e,t,n,i,r,a){let s=t*this.rowStride+e*this._numChannels;this._data[s]=Math.trunc(n),this._numChannels>1&&(this._data[s+1]=Math.trunc(i),this._numChannels>2&&(this._data[s+2]=Math.trunc(r),this._numChannels>3&&(this._data[s+3]=Math.trunc(a))))}setPixelRgbSafe(e,t,n,i,r){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgb(e,t,n,i,r)}setPixelRgbaSafe(e,t,n,i,r,a){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgba(e,t,n,i,r,a)}clear(e){}clone(e=!1){return $t.from(this,e)}toUint8Array(){return new Uint8Array(this.buffer)}getBytes(e){if(e===void 0)return this.toUint8Array();if(this.numChannels===4){if(e===2||e===3||e===1){let t=this.clone();if(e===2)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=a,n.b=r,n.a=i}else if(e===3)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=i,n.b=r,n.a=a}else if(e===1)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=a,n.g=r,n.b=i,n.a=s}return t.toUint8Array()}}else if(this.numChannels===3&&e===5){let t=this.clone();for(let n of t){let i=n.r;n.r=n.b,n.b=i}return t.toUint8Array()}return this.toUint8Array()}toString(){return`${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`}[Symbol.iterator](){return it.imageData(this)}}});var ke,gr=A(()=>{"use strict";oe();ae();H();G();_e();Fi();ke=class{get image(){return this._image}get x(){return this._x}get y(){return this._y}get xNormalized(){return this.width>1?this._x/(this.width-1):0}get yNormalized(){return this.height>1?this._y/(this.height-1):0}get index(){return this.getChannelInternal(0)}set index(e){this.setChannel(0,e)}get data(){return this._image.data}get isValid(){return this._x>=0&&this._x=0&&this._y=this._image.data.length?0:this._image.data[t]>>n&1}next(){if(this._x++,this._x===this.width)return this._x=0,this._y++,this._bitIndex=0,this._index++,this._rowOffset+=this.image.rowStride,{done:this._y>=this.height,value:this};let e=this.numChannels;if(this.palette!==void 0||e===1)this._bitIndex++,this._bitIndex>7&&(this._bitIndex=0,this._index++);else{let t=this.image.numChannels;this._bitIndex=this._x*t&7,this._index=this._rowOffset+(this._x*t>>3)}return{done:this._index>=this.imageLength,value:this}}setPosition(e,t){this._x=e,this._y=t;let n=this._image.numChannels;this._rowOffset=this._y*this._image.rowStride,this._index=this._rowOffset+(this._x*n>>3),this._bitIndex=this._x*n&7}setPositionNormalized(e,t){return this.setPosition(Math.floor(e*(this.width-1)),Math.floor(t*(this.height-1)))}getChannel(e){return this.palette!==void 0?this.palette.get(this.getChannelInternal(0),e):e===4?this.luminance:e=this.numChannels)return;let n=this._index,i=7-(this._bitIndex+e);i<0&&(i+=8,n++);let r=this.data[n],a=_.clampInt(t,0,1),u=[254,253,251,247,239,223,191,127][i];r=r&u|a<0&&(this.setChannel(0,e),i>1&&(this.setChannel(1,t),i>2&&this.setChannel(2,n)))}setRgba(e,t,n,i){let r=this.numChannels;r>0&&(this.setChannel(0,e),r>1&&(this.setChannel(1,t),r>2&&(this.setChannel(2,n),r>3&&this.setChannel(3,i))))}toArray(){return U.generate(this.length,e=>this.getChannel(e))}equals(e){return e instanceof ke?U.equals(this.toArray(),e.toArray()):Array.isArray(e)?U.equals(this.toArray(),e):!1}clone(){return ke.from(this)}convert(e){return z.convertColor({from:this,format:e.format,numChannels:e.numChannels,alpha:e.alpha})}toString(){return`${this.constructor.name} (${this.toArray()})`}[Symbol.iterator](){return this}}});var Ut,Fi=A(()=>{"use strict";De();H();gr();$e();li();Ut=class{get width(){return this._width}get height(){return this._height}get data(){return this._data}get numChannels(){return this._numChannels}get format(){return 0}get formatType(){return 0}get buffer(){return this._data.buffer}get rowStride(){return this._rowStride}get iterator(){return ke.imageData(this)}get byteLength(){return this._data.byteLength}get length(){return this._data.byteLength}get maxChannelValue(){var e,t;return(t=(e=this._palette)==null?void 0:e.maxChannelValue)!=null?t:1}get maxIndexValue(){return 1}get hasPalette(){return this.palette!==void 0}get palette(){return this._palette}get isHdrFormat(){return!1}get isLdrFormat(){return!this.isHdrFormat}get bitsPerChannel(){return 1}constructor(e,t,n,i){this._width=e,this._height=t,this._numChannels=n,this._rowStride=Math.ceil(this._width*this._numChannels/8),this._palette=void 0,this._data=i!=null?i:new Uint8Array(Math.max(this._rowStride*this._height,1))}static palette(e,t,n){let i=Math.ceil(e/8),r=new Uint8Array(Math.max(i*t,1)),a=new Ut(e,t,1,r);return a._rowStride=i,a._palette=n,a}static from(e,t=!1){var r;let n=t?new Uint8Array(e.data.length):e.data.slice(),i=new Ut(e.width,e.height,e._numChannels,n);return i._rowStride=e.rowStride,i._palette=(r=e.palette)==null?void 0:r.clone(),i}getRange(e,t,n,i){return new le(ke.imageData(this),e,t,n,i)}getColor(e,t,n,i){return i===void 0?bt.rgb(Math.trunc(e),Math.trunc(t),Math.trunc(n)):bt.rgba(Math.trunc(e),Math.trunc(t),Math.trunc(n),Math.trunc(i))}getPixel(e,t,n){let i=n;return(i===void 0||!(i instanceof ke)||i.image!==this)&&(i=ke.imageData(this)),i.setPosition(e,t),i}setPixel(e,t,n){this.setPixelRgba(e,t,n.r,n.g,n.b,n.a)}setPixelR(e,t,n){var i;this._numChannels<1||((i=this.pixel)!=null||(this.pixel=ke.imageData(this)),this.pixel.setPosition(e,t),this.pixel.index=n)}setPixelRgb(e,t,n,i,r){var a;this._numChannels<1||((a=this.pixel)!=null||(this.pixel=ke.imageData(this)),this.pixel.setPosition(e,t),this.pixel.setRgb(n,i,r))}setPixelRgba(e,t,n,i,r,a){var s;this._numChannels<1||((s=this.pixel)!=null||(this.pixel=ke.imageData(this)),this.pixel.setPosition(e,t),this.pixel.setRgba(n,i,r,a))}setPixelRgbSafe(e,t,n,i,r){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgb(e,t,n,i,r)}setPixelRgbaSafe(e,t,n,i,r,a){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgba(e,t,n,i,r,a)}clear(e){}clone(e=!1){return Ut.from(this,e)}toUint8Array(){return new Uint8Array(this.buffer)}getBytes(e){if(e===void 0)return this.toUint8Array();if(this.numChannels===4){if(e===2||e===3||e===1){let t=this.clone();if(e===2)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=a,n.b=r,n.a=i}else if(e===3)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=i,n.b=r,n.a=a}else if(e===1)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=a,n.g=r,n.b=i,n.a=s}return t.toUint8Array()}}else if(this.numChannels===3&&e===5){let t=this.clone();for(let n of t){let i=n.r;n.r=n.b,n.b=i}return t.toUint8Array()}return this.toUint8Array()}toString(){return`${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`}[Symbol.iterator](){return ke.imageData(this)}}});var rt,xr=A(()=>{"use strict";oe();ae();H();G();Bi();rt=class{get image(){return this._image}get x(){return this._x}get y(){return this._y}get xNormalized(){return this.width>1?this._x/(this.width-1):0}get yNormalized(){return this.height>1?this._y/(this.height-1):0}get index(){return this.r}set index(e){this.r=e}get data(){return this._image.data}get isValid(){return this._x>=0&&this._x=0&&this._y0?this.data[this._index]:0}set r(e){this.numChannels>0&&(this.data[this._index]=Math.trunc(e))}get g(){return this.numChannels>1?this.data[this._index+1]:0}set g(e){this.numChannels>1&&(this.data[this._index+1]=Math.trunc(e))}get b(){return this.numChannels>2?this.data[this._index+2]:0}set b(e){this.numChannels>2&&(this.data[this._index+2]=Math.trunc(e))}get a(){return this.numChannels>3?this.data[this._index+3]:0}set a(e){this.numChannels>3&&(this.data[this._index+3]=Math.trunc(e))}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e,t,n,i){this._image=i,this._index=n,this._x=e,this._y=t}static imageData(e){return new rt(-1,0,-e.numChannels,e)}static image(e){return new rt(-1,0,-e.numChannels,e.data instanceof Wt?e.data:new Wt(0,0,0))}static from(e){return new rt(e.x,e.y,e._index,e.image)}next(){return this._x++,this._x===this.width&&(this._x=0,this._y++,this._y===this.height)?{done:!0,value:this}:(this._index+=this.numChannels,{done:this._index>=this.image.data.length,value:this})}setPosition(e,t){this._x=e,this._y=t,this._index=this._y*this._image.width*this._image.numChannels+this._x*this._image.numChannels}setPositionNormalized(e,t){return this.setPosition(Math.floor(e*(this.width-1)),Math.floor(t*(this.height-1)))}getChannel(e){return e===4?this.luminance:e0&&(this.data[this._index]=Math.trunc(e),this.numChannels>1&&(this.data[this._index+1]=Math.trunc(t),this.numChannels>2&&(this.data[this._index+2]=Math.trunc(n))))}setRgba(e,t,n,i){this.numChannels>0&&(this.data[this._index]=Math.trunc(e),this.numChannels>1&&(this.data[this._index+1]=Math.trunc(t),this.numChannels>2&&(this.data[this._index+2]=Math.trunc(n),this.numChannels>3&&(this.data[this._index+3]=Math.trunc(i)))))}equals(e){return e instanceof rt?U.equals(this.toArray(),e.toArray()):Array.isArray(e)?U.equals(this.toArray(),e):!1}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return rt.from(this)}convert(e){return z.convertColor({from:this,format:e.format,numChannels:e.numChannels,alpha:e.alpha})}toString(){return`${this.constructor.name} (${this.toArray()})`}[Symbol.iterator](){return this}}});var Wt,Bi=A(()=>{"use strict";De();H();xr();$e();mi();Wt=class{get width(){return this._width}get height(){return this._height}get data(){return this._data}get numChannels(){return this._numChannels}get format(){return 4}get formatType(){return 0}get buffer(){return this._data.buffer}get rowStride(){return this._width*this._numChannels*2}get iterator(){return rt.imageData(this)}get byteLength(){return this._data.byteLength}get length(){return this._data.byteLength}get maxChannelValue(){return 65535}get maxIndexValue(){return 65535}get hasPalette(){return this.palette!==void 0}get palette(){}get isHdrFormat(){return!0}get isLdrFormat(){return!this.isHdrFormat}get bitsPerChannel(){return 16}constructor(e,t,n,i){this._width=e,this._height=t,this._numChannels=n,this._data=i!=null?i:new Uint16Array(this._width*this._height*this._numChannels)}static from(e,t=!1){let n=t?new Uint16Array(e.data.length):e.data.slice();return new Wt(e.width,e.height,e._numChannels,n)}getRange(e,t,n,i){return new le(rt.imageData(this),e,t,n,i)}getColor(e,t,n,i){return i===void 0?ft.rgb(Math.trunc(e),Math.trunc(t),Math.trunc(n)):ft.rgba(Math.trunc(e),Math.trunc(t),Math.trunc(n),Math.trunc(i))}getPixel(e,t,n){let i=n;return(i===void 0||!(i instanceof rt)||i.image!==this)&&(i=rt.imageData(this)),i.setPosition(e,t),i}setPixel(e,t,n){this.setPixelRgba(e,t,n.r,n.g,n.b,n.a)}setPixelR(e,t,n){let i=t*this._width*this._numChannels+e*this.numChannels;this.data[i]=Math.trunc(n)}setPixelRgb(e,t,n,i,r){let a=t*this._width*this._numChannels+e*this._numChannels;this._data[a]=Math.trunc(n),this._numChannels>1&&(this._data[a+1]=Math.trunc(i),this._numChannels>2&&(this._data[a+2]=Math.trunc(r)))}setPixelRgba(e,t,n,i,r,a){let s=t*this._width*this._numChannels+e*this._numChannels;this._data[s]=Math.trunc(n),this._numChannels>1&&(this._data[s+1]=Math.trunc(i),this._numChannels>2&&(this._data[s+2]=Math.trunc(r),this._numChannels>3&&(this._data[s+3]=Math.trunc(a))))}setPixelRgbSafe(e,t,n,i,r){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgb(e,t,n,i,r)}setPixelRgbaSafe(e,t,n,i,r,a){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgba(e,t,n,i,r,a)}clear(e){}clone(e=!1){return Wt.from(this,e)}toUint8Array(){return new Uint8Array(this.buffer)}getBytes(e){if(e===void 0)return this.toUint8Array();if(this.numChannels===4){if(e===2||e===3||e===1){let t=this.clone();if(e===2)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=a,n.b=r,n.a=i}else if(e===3)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=i,n.b=r,n.a=a}else if(e===1)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=a,n.g=r,n.b=i,n.a=s}return t.toUint8Array()}}else if(this.numChannels===3&&e===5){let t=this.clone();for(let n of t){let i=n.r;n.r=n.b,n.b=i}return t.toUint8Array()}return this.toUint8Array()}toString(){return`${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`}[Symbol.iterator](){return rt.imageData(this)}}});var ze,_r=A(()=>{"use strict";oe();ae();H();G();_e();Ui();ze=class{get image(){return this._image}get x(){return this._x}get y(){return this._y}get xNormalized(){return this.width>1?this._x/(this.width-1):0}get yNormalized(){return this.height>1?this._y/(this.height-1):0}get index(){return this.getChannelInternal(0)}set index(e){this.setChannel(0,e)}get data(){return this._image.data}get isValid(){return this._x>=0&&this._x=0&&this._y>n&3}next(){if(this._x++,this._x===this.width)return this._x=0,this._y++,this._bitIndex=0,this._index++,this._rowOffset+=this.image.rowStride,{done:this._y>=this.height,value:this};let e=this.numChannels;if(this.palette!==void 0||e===1)this._bitIndex+=2,this._bitIndex>7&&(this._bitIndex=0,this._index++);else{let t=this.bitsPerPixel;this._bitIndex=this._x*t&7,this._index=this._rowOffset+(this._x*t>>3)}return{done:this._index>=this.image.data.length,value:this}}setPosition(e,t){this._x=e,this._y=t;let n=this.bitsPerPixel;this._rowOffset=this._y*this._image.rowStride,this._index=this._rowOffset+(this._x*n>>3),this._bitIndex=this._x*n&7}setPositionNormalized(e,t){return this.setPosition(Math.floor(e*(this.width-1)),Math.floor(t*(this.height-1)))}getChannel(e){return this.palette!==void 0?this.palette.get(this.getChannelInternal(0),e):e===4?this.luminance:e=this.image.numChannels)return;let n=this._index,i=6-(this._bitIndex+(e<<1));i<0&&(i+=8,n++);let r=this.data[n],a=_.clampInt(t,0,3),u=[252,243,207,63][i>>1];r=r&u|a<0&&(this.setChannel(0,e),i>1&&(this.setChannel(1,t),i>2&&this.setChannel(2,n)))}setRgba(e,t,n,i){let r=this.image.numChannels;r>0&&(this.setChannel(0,e),r>1&&(this.setChannel(1,t),r>2&&(this.setChannel(2,n),r>3&&this.setChannel(3,i))))}equals(e){return e instanceof ze?U.equals(this.toArray(),e.toArray()):Array.isArray(e)?U.equals(this.toArray(),e):!1}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return ze.from(this)}convert(e){return z.convertColor({from:this,format:e.format,numChannels:e.numChannels,alpha:e.alpha})}toString(){return`${this.constructor.name} (${this.toArray()})`}[Symbol.iterator](){return this}}});var St,Ui=A(()=>{"use strict";De();H();_r();$e();hi();St=class{get width(){return this._width}get height(){return this._height}get data(){return this._data}get numChannels(){return this._numChannels}get format(){return 1}get formatType(){return 0}get buffer(){return this._data.buffer}get rowStride(){return this._rowStride}get iterator(){return ze.imageData(this)}get byteLength(){return this._data.byteLength}get length(){return this._data.byteLength}get maxChannelValue(){var e,t;return(t=(e=this._palette)==null?void 0:e.maxChannelValue)!=null?t:3}get maxIndexValue(){return 1}get hasPalette(){return this.palette!==void 0}get palette(){return this._palette}get isHdrFormat(){return!1}get isLdrFormat(){return!this.isHdrFormat}get bitsPerChannel(){return 2}constructor(e,t,n,i){this._width=e,this._height=t,this._numChannels=n,this._rowStride=Math.ceil(this._width*(this._numChannels<<1)/8),this._palette=void 0,this._data=i!=null?i:new Uint8Array(Math.max(this._rowStride*this._height,1))}static palette(e,t,n){let i=Math.ceil(e/4),r=new Uint8Array(Math.max(i*t,1)),a=new St(e,t,1,r);return a._rowStride=i,a._palette=n,a}static from(e,t=!1){var r;let n=t?new Uint8Array(e.data.length):e.data.slice(),i=new St(e.width,e.height,e._numChannels,n);return i._rowStride=e.rowStride,i._palette=(r=e.palette)==null?void 0:r.clone(),i}getRange(e,t,n,i){return new le(ze.imageData(this),e,t,n,i)}getColor(e,t,n,i){return i===void 0?dt.rgb(Math.trunc(e),Math.trunc(t),Math.trunc(n)):dt.rgba(Math.trunc(e),Math.trunc(t),Math.trunc(n),Math.trunc(i))}getPixel(e,t,n){let i=n;return(i===void 0||!(i instanceof ze)||i.image!==this)&&(i=ze.imageData(this)),i.setPosition(e,t),i}setPixel(e,t,n){this.setPixelRgba(e,t,n.r,n.g,n.b,n.a)}setPixelR(e,t,n){var i;this._numChannels<1||((i=this._pixel)!=null||(this._pixel=ze.imageData(this)),this._pixel.setPosition(e,t),this._pixel.index=n)}setPixelRgb(e,t,n,i,r){var a;this._numChannels<1||((a=this._pixel)!=null||(this._pixel=ze.imageData(this)),this._pixel.setPosition(e,t),this._pixel.setRgb(n,i,r))}setPixelRgba(e,t,n,i,r,a){var s;this._numChannels<1||((s=this._pixel)!=null||(this._pixel=ze.imageData(this)),this._pixel.setPosition(e,t),this._pixel.setRgba(n,i,r,a))}setPixelRgbSafe(e,t,n,i,r){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgb(e,t,n,i,r)}setPixelRgbaSafe(e,t,n,i,r,a){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgba(e,t,n,i,r,a)}clear(e){}clone(e=!1){return St.from(this,e)}toUint8Array(){return new Uint8Array(this.buffer)}getBytes(e){if(e===void 0)return this.toUint8Array();if(this.numChannels===4){if(e===2||e===3||e===1){let t=this.clone();if(e===2)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=a,n.b=r,n.a=i}else if(e===3)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=i,n.b=r,n.a=a}else if(e===1)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=a,n.g=r,n.b=i,n.a=s}return t.toUint8Array()}}else if(this.numChannels===3&&e===5){let t=this.clone();for(let n of t){let i=n.r;n.r=n.b,n.b=i}return t.toUint8Array()}return this.toUint8Array()}toString(){return`${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`}[Symbol.iterator](){return ze.imageData(this)}}});var at,yr=A(()=>{"use strict";oe();ae();H();G();Si();at=class{get image(){return this._image}get x(){return this._x}get y(){return this._y}get xNormalized(){return this.width>1?this._x/(this.width-1):0}get yNormalized(){return this.height>1?this._y/(this.height-1):0}get index(){return this.r}set index(e){this.r=e}get data(){return this._image.data}get isValid(){return this._x>=0&&this._x=0&&this._y0?this.data[this._index]:0}set r(e){this.numChannels>0&&(this.data[this._index]=Math.trunc(e))}get g(){return this.numChannels>1?this.data[this._index+1]:0}set g(e){this.numChannels>1&&(this.data[this._index+1]=Math.trunc(e))}get b(){return this.numChannels>2?this.data[this._index+2]:0}set b(e){this.numChannels>2&&(this.data[this._index+2]=Math.trunc(e))}get a(){return this.numChannels>3?this.data[this._index+3]:0}set a(e){this.numChannels>3&&(this.data[this._index+3]=Math.trunc(e))}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e,t,n,i){this._image=i,this._index=n,this._x=e,this._y=t}static imageData(e){return new at(-1,0,-e.numChannels,e)}static image(e){return new at(-1,0,-e.numChannels,e.data instanceof Yt?e.data:new Yt(0,0,0))}static from(e){return new at(e.x,e.y,e._index,e.image)}next(){return this._x++,this._x===this.width&&(this._x=0,this._y++,this._y===this.height)?{done:!0,value:this}:(this._index+=this.numChannels,{done:this._index>=this.image.data.length,value:this})}setPosition(e,t){this._x=e,this._y=t,this._index=this._y*this._image.width*this._image.numChannels+this._x*this._image.numChannels}setPositionNormalized(e,t){return this.setPosition(Math.floor(e*(this.width-1)),Math.floor(t*(this.height-1)))}getChannel(e){return e===4?this.luminance:e0&&(this.data[this._index]=Math.trunc(e),this.numChannels>1&&(this.data[this._index+1]=Math.trunc(t),this.numChannels>2&&(this.data[this._index+2]=Math.trunc(n))))}setRgba(e,t,n,i){this.numChannels>0&&(this.data[this._index]=Math.trunc(e),this.numChannels>1&&(this.data[this._index+1]=Math.trunc(t),this.numChannels>2&&(this.data[this._index+2]=Math.trunc(n),this.numChannels>3&&(this.data[this._index+3]=Math.trunc(i)))))}equals(e){return e instanceof at?U.equals(this.toArray(),e.toArray()):Array.isArray(e)?U.equals(this.toArray(),e):!1}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return at.from(this)}convert(e){return z.convertColor({from:this,format:e.format,numChannels:e.numChannels,alpha:e.alpha})}toString(){return`${this.constructor.name} (${this.toArray()})`}[Symbol.iterator](){return this}}});var Yt,Si=A(()=>{"use strict";De();H();yr();$e();ci();Yt=class{get width(){return this._width}get height(){return this._height}get data(){return this._data}get numChannels(){return this._numChannels}get format(){return 5}get formatType(){return 0}get buffer(){return this._data.buffer}get rowStride(){return this._width*this._numChannels*4}get iterator(){return at.imageData(this)}get byteLength(){return this._data.byteLength}get length(){return this._data.byteLength}get maxChannelValue(){return 4294967295}get maxIndexValue(){return 4294967295}get hasPalette(){return this.palette!==void 0}get palette(){}get isHdrFormat(){return!0}get isLdrFormat(){return!this.isHdrFormat}get bitsPerChannel(){return 32}constructor(e,t,n,i){this._width=e,this._height=t,this._numChannels=n,this._data=i!=null?i:new Uint32Array(this._width*this._height*this._numChannels)}static from(e,t=!1){let n=t?new Uint32Array(e.data.length):e.data.slice();return new Yt(e.width,e.height,e._numChannels,n)}getRange(e,t,n,i){return new le(at.imageData(this),e,t,n,i)}getColor(e,t,n,i){return i===void 0?pt.rgb(Math.trunc(e),Math.trunc(t),Math.trunc(n)):pt.rgba(Math.trunc(e),Math.trunc(t),Math.trunc(n),Math.trunc(i))}getPixel(e,t,n){let i=n;return(i===void 0||!(i instanceof at)||i.image!==this)&&(i=at.imageData(this)),i.setPosition(e,t),i}setPixel(e,t,n){this.setPixelRgba(e,t,n.r,n.g,n.b,n.a)}setPixelR(e,t,n){let i=t*this._width*this._numChannels+e*this.numChannels;this.data[i]=Math.trunc(n)}setPixelRgb(e,t,n,i,r){let a=t*this._width*this._numChannels+e*this._numChannels;this._data[a]=Math.trunc(n),this._numChannels>1&&(this._data[a+1]=Math.trunc(i),this._numChannels>2&&(this._data[a+2]=Math.trunc(r)))}setPixelRgba(e,t,n,i,r,a){let s=t*this._width*this._numChannels+e*this._numChannels;this._data[s]=Math.trunc(n),this._numChannels>1&&(this._data[s+1]=Math.trunc(i),this._numChannels>2&&(this._data[s+2]=Math.trunc(r),this._numChannels>3&&(this._data[s+3]=Math.trunc(a))))}setPixelRgbSafe(e,t,n,i,r){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgb(e,t,n,i,r)}setPixelRgbaSafe(e,t,n,i,r,a){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgba(e,t,n,i,r,a)}clear(e){}clone(e=!1){return Yt.from(this,e)}toUint8Array(){return new Uint8Array(this.buffer)}getBytes(e){if(e===void 0)return this.toUint8Array();if(this.numChannels===4){if(e===2||e===3||e===1){let t=this.clone();if(e===2)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=a,n.b=r,n.a=i}else if(e===3)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=i,n.b=r,n.a=a}else if(e===1)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=a,n.g=r,n.b=i,n.a=s}return t.toUint8Array()}}else if(this.numChannels===3&&e===5){let t=this.clone();for(let n of t){let i=n.r;n.r=n.b,n.b=i}return t.toUint8Array()}return this.toUint8Array()}toString(){return`${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`}[Symbol.iterator](){return at.imageData(this)}}});var Oe,Cr=A(()=>{"use strict";oe();ae();H();G();_e();ki();Oe=class{get image(){return this._image}get x(){return this._x}get y(){return this._y}get xNormalized(){return this.width>1?this._x/(this.width-1):0}get yNormalized(){return this.height>1?this._y/(this.height-1):0}get index(){return this.getChannelInternal(0)}set index(e){this.setChannel(0,e)}get data(){return this._image.data}get isValid(){return this._x>=0&&this._x=0&&this._y>n&15}next(){if(this._x++,this._x===this.width)return this._x=0,this._y++,this._bitIndex=0,this._index=this._y*this.image.rowStride,{done:this._y>=this.height,value:this};let e=this.image.numChannels;if(this.palette!==void 0||e===1)this._bitIndex+=4,this._bitIndex>7&&(this._bitIndex=0,this._index++);else{let t=e<<2;for(this._bitIndex+=t;this._bitIndex>7;)this._bitIndex-=8,this._index++}return{done:this._index>=this.image.data.length,value:this}}setPosition(e,t){this._x=e,this._y=t;let n=this.image.numChannels*4,i=this.image.width,r=this.image.rowStride;this._index=n===4?this._y*r+(this._x>>1):n===8?this._y*i+this._x:n===16?this._y*r+(this._x<<1):this._y*r+(this._x*n>>3),this._bitIndex=n>7?this._x*n&4:this._x*n&7}setPositionNormalized(e,t){return this.setPosition(Math.floor(e*(this.width-1)),Math.floor(t*(this.height-1)))}getChannel(e){return this.palette!==void 0?this.palette.get(this.getChannelInternal(0),e):e===4?this.luminance:e=this.image.numChannels)return;let n=this._index,i=4-(this._bitIndex+(e<<2));i<0&&(i+=8,n++);let r=this.data[n],a=_.clampInt(t,0,15);r=r&(i===4?15:240)|a<0&&(this.setChannel(0,e),i>1&&(this.setChannel(1,t),i>2&&this.setChannel(2,n)))}setRgba(e,t,n,i){let r=this.image.numChannels;r>0&&(this.setChannel(0,e),r>1&&(this.setChannel(1,t),r>2&&(this.setChannel(2,n),r>3&&this.setChannel(3,i))))}equals(e){return e instanceof Oe?U.equals(this.toArray(),e.toArray()):Array.isArray(e)?U.equals(this.toArray(),e):!1}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return Oe.from(this)}convert(e){return z.convertColor({from:this,format:e.format,numChannels:e.numChannels,alpha:e.alpha})}toString(){return`${this.constructor.name} (${this.toArray()})`}[Symbol.iterator](){return this}}});var kt,ki=A(()=>{"use strict";De();H();Cr();$e();bi();kt=class{get width(){return this._width}get height(){return this._height}get data(){return this._data}get numChannels(){return this._numChannels}get format(){return 2}get formatType(){return 0}get buffer(){return this._data.buffer}get rowStride(){return this._rowStride}get iterator(){return Oe.imageData(this)}get byteLength(){return this._data.byteLength}get length(){return this._data.byteLength}get maxChannelValue(){var e,t;return(t=(e=this._palette)==null?void 0:e.maxChannelValue)!=null?t:15}get maxIndexValue(){return 15}get hasPalette(){return this.palette!==void 0}get palette(){return this._palette}get isHdrFormat(){return!1}get isLdrFormat(){return!this.isHdrFormat}get bitsPerChannel(){return 4}constructor(e,t,n,i){this._width=e,this._height=t,this._numChannels=n,this._rowStride=this._numChannels===2?this._width:this._numChannels===4?this._width*2:this._numChannels===3?Math.ceil(this._width*1.5):Math.ceil(this._width/2),this._palette=void 0,this._data=i!=null?i:new Uint8Array(Math.max(this._rowStride*this._height,1))}static palette(e,t,n){let i=Math.ceil(e/2),r=new Uint8Array(Math.max(i*t,1)),a=new kt(e,t,1,r);return a._rowStride=i,a._palette=n,a}static from(e,t=!1){var r;let n=t?new Uint8Array(e.data.length):e.data.slice(),i=new kt(e.width,e.height,e._numChannels,n);return i._rowStride=e.rowStride,i._palette=(r=e.palette)==null?void 0:r.clone(),i}getRange(e,t,n,i){return new le(Oe.imageData(this),e,t,n,i)}getColor(e,t,n,i){return i===void 0?gt.rgb(Math.trunc(e),Math.trunc(t),Math.trunc(n)):gt.rgba(Math.trunc(e),Math.trunc(t),Math.trunc(n),Math.trunc(i))}getPixel(e,t,n){let i=n;return(i===void 0||!(i instanceof Oe)||i.image!==this)&&(i=Oe.imageData(this)),i.setPosition(e,t),i}setPixel(e,t,n){this.setPixelRgba(e,t,n.r,n.g,n.b,n.a)}setPixelR(e,t,n){var i;this._numChannels<1||((i=this._pixel)!=null||(this._pixel=Oe.imageData(this)),this._pixel.setPosition(e,t),this._pixel.index=n)}setPixelRgb(e,t,n,i,r){var a;this._numChannels<1||((a=this._pixel)!=null||(this._pixel=Oe.imageData(this)),this._pixel.setPosition(e,t),this._pixel.setRgb(n,i,r))}setPixelRgba(e,t,n,i,r,a){var s;this._numChannels<1||((s=this._pixel)!=null||(this._pixel=Oe.imageData(this)),this._pixel.setPosition(e,t),this._pixel.setRgba(n,i,r,a))}setPixelRgbSafe(e,t,n,i,r){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgb(e,t,n,i,r)}setPixelRgbaSafe(e,t,n,i,r,a){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgba(e,t,n,i,r,a)}clear(e){}clone(e=!1){return kt.from(this,e)}toUint8Array(){return new Uint8Array(this.buffer)}getBytes(e){if(e===void 0)return this.toUint8Array();if(this.numChannels===4){if(e===2||e===3||e===1){let t=this.clone();if(e===2)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=a,n.b=r,n.a=i}else if(e===3)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=i,n.b=r,n.a=a}else if(e===1)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=a,n.g=r,n.b=i,n.a=s}return t.toUint8Array()}}else if(this.numChannels===3&&e===5){let t=this.clone();for(let n of t){let i=n.r;n.r=n.b,n.b=i}return t.toUint8Array()}return this.toUint8Array()}toString(){return`${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`}[Symbol.iterator](){return Oe.imageData(this)}}});var st,wr=A(()=>{"use strict";oe();ae();H();G();_e();Xn();st=class{get image(){return this._image}get x(){return this._x}get y(){return this._y}get xNormalized(){return this.width>1?this._x/(this.width-1):0}get yNormalized(){return this.height>1?this._y/(this.height-1):0}get index(){return this.data[this._index]}set index(e){this.data[this._index]=_.clampInt255(e)}get data(){return this._image.data}get isValid(){return this._x>=0&&this._x=0&&this._y0?this.data[this._index]:0:this.palette.getRed(this.data[this._index])}set r(e){this.numChannels>0&&(this.data[this._index]=_.clampInt255(e))}get g(){return this.palette===void 0?this.numChannels>1?this.data[this._index+1]:0:this.palette.getGreen(this.data[this._index])}set g(e){this.numChannels>1&&(this.data[this._index+1]=_.clampInt255(e))}get b(){return this.palette===void 0?this.numChannels>2?this.data[this._index+2]:0:this.palette.getBlue(this.data[this._index])}set b(e){this.numChannels>2&&(this.data[this._index+2]=_.clampInt255(e))}get a(){return this.palette===void 0?this.numChannels>3?this.data[this._index+3]:255:this.palette.getAlpha(this.data[this._index])}set a(e){this.numChannels>3&&(this.data[this._index+3]=_.clampInt255(e))}get rNormalized(){return this.r/this.maxChannelValue}set rNormalized(e){this.r=e*this.maxChannelValue}get gNormalized(){return this.g/this.maxChannelValue}set gNormalized(e){this.g=e*this.maxChannelValue}get bNormalized(){return this.b/this.maxChannelValue}set bNormalized(e){this.b=e*this.maxChannelValue}get aNormalized(){return this.a/this.maxChannelValue}set aNormalized(e){this.a=e*this.maxChannelValue}get luminance(){return z.getLuminance(this)}get luminanceNormalized(){return z.getLuminanceNormalized(this)}constructor(e,t,n,i){this._image=i,this._index=n,this._x=e,this._y=t}static imageData(e){return new st(-1,0,-e.numChannels,e)}static image(e){return new st(-1,0,-e.numChannels,e.data instanceof ut?e.data:new ut(0,0,0))}static from(e){return new st(e.x,e.y,e._index,e.image)}next(){return this._x++,this._x===this.width&&(this._x=0,this._y++,this._y===this.height)?{done:!0,value:this}:(this._index+=this.palette===void 0?this.numChannels:1,{done:this._index>=this.image.data.length,value:this})}setPosition(e,t){this._x=e,this._y=t,this._index=this._y*this._image.width*this._image.numChannels+this._x*this._image.numChannels}setPositionNormalized(e,t){return this.setPosition(Math.floor(e*(this.width-1)),Math.floor(t*(this.height-1)))}getChannel(e){return this.palette!==void 0?this.palette.get(this.data[this._index],e):e===4?this.luminance:e0&&(this.data[this._index]=Math.trunc(e),this.numChannels>1&&(this.data[this._index+1]=Math.trunc(t),this.numChannels>2&&(this.data[this._index+2]=Math.trunc(n))))}setRgba(e,t,n,i){this.numChannels>0&&(this.data[this._index]=Math.trunc(e),this.numChannels>1&&(this.data[this._index+1]=Math.trunc(t),this.numChannels>2&&(this.data[this._index+2]=Math.trunc(n),this.numChannels>3&&(this.data[this._index+3]=Math.trunc(i)))))}equals(e){return e instanceof st?U.equals(this.toArray(),e.toArray()):Array.isArray(e)?U.equals(this.toArray(),e):!1}toArray(){return U.generate(this.length,e=>this.getChannel(e))}clone(){return st.from(this)}convert(e){return z.convertColor({from:this,format:e.format,numChannels:e.numChannels,alpha:e.alpha})}toString(){return`${this.constructor.name} (${this.toArray()})`}[Symbol.iterator](){return this}}});var ut,Xn=A(()=>{"use strict";De();H();wr();$e();dn();pn();_e();ut=class{get width(){return this._width}get height(){return this._height}get data(){return this._data}get numChannels(){return this._numChannels}get format(){return 3}get formatType(){return 0}get buffer(){return this._data.buffer}get rowStride(){return this._width*this._numChannels}get iterator(){return st.imageData(this)}get byteLength(){return this._data.byteLength}get length(){return this._data.byteLength}get maxChannelValue(){var e,t;return(t=(e=this._palette)==null?void 0:e.maxChannelValue)!=null?t:255}get maxIndexValue(){return 255}get hasPalette(){return this.palette!==void 0}get palette(){return this._palette}get isHdrFormat(){return!1}get isLdrFormat(){return!this.isHdrFormat}get bitsPerChannel(){return 8}constructor(e,t,n,i){this._width=e,this._height=t,this._numChannels=n,this._palette=void 0,this._data=i!=null?i:new Uint8Array(this._width*this._height*this._numChannels)}static palette(e,t,n){let i=new Uint8Array(e*t),r=new ut(e,t,1,i);return r._palette=n,r}static from(e,t=!1){var r;let n=t?new Uint8Array(e.data.length):e.data.slice(),i=new ut(e.width,e.height,e._numChannels,n);return i._palette=(r=e.palette)==null?void 0:r.clone(),i}getRange(e,t,n,i){return new le(st.imageData(this),e,t,n,i)}getColor(e,t,n,i){return i===void 0?new tn(_.clampInt255(e),_.clampInt255(t),_.clampInt255(n)):new Dt(_.clampInt255(e),_.clampInt255(t),_.clampInt255(n),_.clampInt255(i))}getPixel(e,t,n){let i=n;return(i===void 0||!(i instanceof st)||i.image!==this)&&(i=st.imageData(this)),i.setPosition(e,t),i}setPixel(e,t,n){this.setPixelRgba(e,t,n.r,n.g,n.b,n.a)}setPixelR(e,t,n){let i=t*this.rowStride+e*this.numChannels;this.data[i]=Math.trunc(n)}setPixelRgb(e,t,n,i,r){let a=t*this.rowStride+e*this._numChannels;this._data[a]=Math.trunc(n),this._numChannels>1&&(this._data[a+1]=Math.trunc(i),this._numChannels>2&&(this._data[a+2]=Math.trunc(r)))}setPixelRgba(e,t,n,i,r,a){let s=t*this.rowStride+e*this._numChannels;this._data[s]=Math.trunc(n),this._numChannels>1&&(this._data[s+1]=Math.trunc(i),this._numChannels>2&&(this._data[s+2]=Math.trunc(r),this._numChannels>3&&(this._data[s+3]=Math.trunc(a))))}setPixelRgbSafe(e,t,n,i,r){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgb(e,t,n,i,r)}setPixelRgbaSafe(e,t,n,i,r,a){e<0||e>=this.width||t<0||t>=this.height||this.setPixelRgba(e,t,n,i,r,a)}clear(e){let t=e==null?void 0:e.convert({format:3});if(this._numChannels===1){let n=t===void 0?0:_.clampInt255(t.r);this._data.fill(n)}else if(this._numChannels===2){let n=t===void 0?0:_.clampInt255(t.r),r=(t===void 0?0:_.clampInt255(t.g))<<8|n;new Uint16Array(this._data.buffer).fill(r)}else if(this._numChannels===4){let n=t===void 0?0:_.clampInt255(t.r),i=t===void 0?0:_.clampInt255(t.g),r=t===void 0?0:_.clampInt255(t.b),s=(t===void 0?0:_.clampInt255(t.a))<<24|r<<16|i<<8|n;new Uint32Array(this._data.buffer).fill(s)}else{let n=t===void 0?0:_.clampInt255(t.r),i=t===void 0?0:_.clampInt255(t.g),r=t===void 0?0:_.clampInt255(t.b);for(let a of this)a.r=n,a.g=i,a.b=r}}clone(e=!1){return ut.from(this,e)}toUint8Array(){return new Uint8Array(this.buffer)}getBytes(e){if(e===void 0)return this.toUint8Array();if(this.numChannels===4){if(e===2||e===3||e===1){let t=this.clone();if(e===2)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=a,n.b=r,n.a=i}else if(e===3)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=s,n.g=i,n.b=r,n.a=a}else if(e===1)for(let n of t){let i=n.r,r=n.g,a=n.b,s=n.a;n.r=a,n.g=r,n.b=i,n.a=s}return t.toUint8Array()}}else if(this.numChannels===3&&e===5){let t=this.clone();for(let n of t){let i=n.r;n.r=n.b,n.b=i}return t.toUint8Array()}return this.toUint8Array()}toString(){return`${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`}[Symbol.iterator](){return st.imageData(this)}}});var yn,vr=A(()=>{"use strict";H();un();yn=class{get data(){return this._data}get numColors(){return this._numColors}get numChannels(){return this._numChannels}get byteLength(){return this.data.byteLength}get buffer(){return this.data.buffer}get format(){return 9}get maxChannelValue(){return 1}constructor(e,t,n){this._numColors=e,this._numChannels=t,this._data=n!=null?n:new Uint16Array(e*t)}static from(e){return new yn(e.numColors,e.numChannels,e.data)}setRgb(e,t,n,i){let r=e;r*=this._numChannels,this._data[r]=R.doubleToFloat16(t),this._numChannels>1&&(this._data[r+1]=R.doubleToFloat16(n),this._numChannels>2&&(this._data[r+2]=R.doubleToFloat16(i)))}setRgba(e,t,n,i,r){let a=e;a*=this._numChannels,this._data[a]=R.doubleToFloat16(t),this._numChannels>1&&(this._data[a+1]=R.doubleToFloat16(n),this._numChannels>2&&(this._data[a+2]=R.doubleToFloat16(i),this._numChannels>3&&(this._data[a+3]=R.doubleToFloat16(r))))}set(e,t,n){let i=e;t{"use strict";H();Cn=class{get data(){return this._data}get numColors(){return this._numColors}get numChannels(){return this._numChannels}get byteLength(){return this.data.byteLength}get buffer(){return this.data.buffer}get format(){return 10}get maxChannelValue(){return 1}constructor(e,t,n){this._numColors=e,this._numChannels=t,this._data=n!=null?n:new Float32Array(e*t)}static from(e){return new Cn(e.numColors,e.numChannels,e.data)}setRgb(e,t,n,i){let r=e;r*=this._numChannels,this._data[r]=t,this._numChannels>1&&(this._data[r+1]=n,this._numChannels>2&&(this._data[r+2]=i))}setRgba(e,t,n,i,r){let a=e;a*=this._numChannels,this._data[a]=t,this._numChannels>1&&(this._data[a+1]=n,this._numChannels>2&&(this._data[a+2]=i,this._numChannels>3&&(this._data[a+3]=r)))}set(e,t,n){let i=e;t{"use strict";H();wn=class{get data(){return this._data}get numColors(){return this._numColors}get numChannels(){return this._numChannels}get byteLength(){return this.data.byteLength}get buffer(){return this.data.buffer}get format(){return 11}get maxChannelValue(){return 1}constructor(e,t,n){this._numColors=e,this._numChannels=t,this._data=n!=null?n:new Float64Array(e*t)}static from(e){return new wn(e.numColors,e.numChannels,e.data)}setRgb(e,t,n,i){let r=e;r*=this._numChannels,this._data[r]=t,this._numChannels>1&&(this._data[r+1]=n,this._numChannels>2&&(this._data[r+2]=i))}setRgba(e,t,n,i,r){let a=e;a*=this._numChannels,this._data[a]=t,this._numChannels>1&&(this._data[a+1]=n,this._numChannels>2&&(this._data[a+2]=i,this._numChannels>3&&(this._data[a+3]=r)))}set(e,t,n){let i=e;t{"use strict";H();vn=class{get data(){return this._data}get numColors(){return this._numColors}get numChannels(){return this._numChannels}get byteLength(){return this._data.byteLength}get buffer(){return this._data.buffer}get format(){return 7}get maxChannelValue(){return 32767}constructor(e,t,n){this._numColors=e,this._numChannels=t,this._data=n!=null?n:new Int16Array(e*t)}static from(e){return new vn(e.numColors,e.numChannels,e.data)}setRgb(e,t,n,i){let r=e;r*=this._numChannels,this._data[r]=Math.trunc(t),this._numChannels>1&&(this._data[r+1]=Math.trunc(n),this._numChannels>2&&(this._data[r+2]=Math.trunc(i)))}setRgba(e,t,n,i,r){let a=e;a*=this._numChannels,this._data[a]=Math.trunc(t),this._numChannels>1&&(this._data[a+1]=Math.trunc(n),this._numChannels>2&&(this._data[a+2]=Math.trunc(i),this._numChannels>3&&(this._data[a+3]=Math.trunc(r))))}set(e,t,n){let i=e;t{"use strict";H();In=class{get data(){return this._data}get numColors(){return this._numColors}get numChannels(){return this._numChannels}get byteLength(){return this._data.byteLength}get buffer(){return this._data.buffer}get format(){return 8}get maxChannelValue(){return 2147483647}constructor(e,t,n){this._numColors=e,this._numChannels=t,this._data=n!=null?n:new Int32Array(e*t)}static from(e){return new In(e.numColors,e.numChannels,e.data)}setRgb(e,t,n,i){let r=e;r*=this._numChannels,this._data[r]=Math.trunc(t),this._numChannels>1&&(this._data[r+1]=Math.trunc(n),this._numChannels>2&&(this._data[r+2]=Math.trunc(i)))}setRgba(e,t,n,i,r){let a=e;a*=this._numChannels,this._data[a]=Math.trunc(t),this._numChannels>1&&(this._data[a+1]=Math.trunc(n),this._numChannels>2&&(this._data[a+2]=Math.trunc(i),this._numChannels>3&&(this._data[a+3]=Math.trunc(r))))}set(e,t,n){let i=e;t{"use strict";H();Pn=class{get data(){return this._data}get numColors(){return this._numColors}get numChannels(){return this._numChannels}get byteLength(){return this.data.byteLength}get buffer(){return this.data.buffer}get format(){return 6}get maxChannelValue(){return 127}constructor(e,t,n){this._numColors=e,this._numChannels=t,this._data=n!=null?n:new Int8Array(e*t)}static from(e){return new Pn(e.numColors,e.numChannels,e.data)}setRgb(e,t,n,i){let r=e;r*=this._numChannels,this._data[r]=Math.trunc(t),this._numChannels>1&&(this._data[r+1]=Math.trunc(n),this._numChannels>2&&(this._data[r+2]=Math.trunc(i)))}setRgba(e,t,n,i,r){let a=e;a*=this._numChannels,this._data[a]=Math.trunc(t),this._numChannels>1&&(this._data[a+1]=Math.trunc(n),this._numChannels>2&&(this._data[a+2]=Math.trunc(i),this._numChannels>3&&(this._data[a+3]=Math.trunc(r))))}set(e,t,n){let i=e;t{"use strict";H();Mn=class{get data(){return this._data}get numColors(){return this._numColors}get numChannels(){return this._numChannels}get byteLength(){return this._data.byteLength}get buffer(){return this._data.buffer}get format(){return 4}get maxChannelValue(){return 65535}constructor(e,t,n){this._numColors=e,this._numChannels=t,this._data=n!=null?n:new Uint16Array(e*t)}static from(e){return new Mn(e.numColors,e.numChannels,e.data)}setRgb(e,t,n,i){let r=e;r*=this._numChannels,this._data[r]=Math.trunc(t),this._numChannels>1&&(this._data[r+1]=Math.trunc(n),this._numChannels>2&&(this._data[r+2]=Math.trunc(i)))}setRgba(e,t,n,i,r){let a=e;a*=this._numChannels,this._data[a]=Math.trunc(t),this._numChannels>1&&(this._data[a+1]=Math.trunc(n),this._numChannels>2&&(this._data[a+2]=Math.trunc(i),this._numChannels>3&&(this._data[a+3]=Math.trunc(r))))}set(e,t,n){let i=e;t{"use strict";H();rn=class{get data(){return this._data}get numColors(){return this._numColors}get numChannels(){return this._numChannels}get byteLength(){return this._data.byteLength}get buffer(){return this._data.buffer}get format(){return 5}get maxChannelValue(){return 4294967295}constructor(e,t,n){this._numColors=e,this._numChannels=t,this._data=n!=null?n:new Uint32Array(e*t)}static from(e){return new rn(e.numColors,e.numChannels,e.data)}setRgb(e,t,n,i){let r=e;r*=this._numChannels,this._data[r]=Math.trunc(t),this._numChannels>1&&(this._data[r+1]=Math.trunc(n),this._numChannels>2&&(this._data[r+2]=Math.trunc(i)))}setRgba(e,t,n,i,r){let a=e;a*=this._numChannels,this._data[a]=Math.trunc(t),this._numChannels>1&&(this._data[a+1]=Math.trunc(n),this._numChannels>2&&(this._data[a+2]=Math.trunc(i),this._numChannels>3&&(this._data[a+3]=Math.trunc(r))))}set(e,t,n){let i=e;t{"use strict";H();Ae=class{get data(){return this._data}get numColors(){return this._numColors}get numChannels(){return this._numChannels}get byteLength(){return this._data.byteLength}get buffer(){return this._data.buffer}get format(){return 3}get maxChannelValue(){return 255}constructor(e,t,n){this._numColors=e,this._numChannels=t,this._data=n!=null?n:new Uint8Array(e*t)}static from(e){return new Ae(e.numColors,e.numChannels,e.data)}setRgb(e,t,n,i){let r=e;r*=this._numChannels,this._data[r]=Math.trunc(t),this._numChannels>1&&(this._data[r+1]=Math.trunc(n),this._numChannels>2&&(this._data[r+2]=Math.trunc(i)))}setRgba(e,t,n,i,r){let a=e;a*=this._numChannels,this._data[a]=Math.trunc(t),this._numChannels>1&&(this._data[a+1]=Math.trunc(n),this._numChannels>2&&(this._data[a+2]=Math.trunc(i),this._numChannels>3&&(this._data[a+3]=Math.trunc(r))))}set(e,t,n){let i=e;t=this._data.length?0:this._data[t]}getGreen(e){let t=e;return this._numChannels<2||(t*=this._numChannels,t>=this._data.length)?0:this._data[t+1]}getBlue(e){let t=e;return this._numChannels<3||(t*=this._numChannels,t>=this._data.length)?0:this._data[t+2]}getAlpha(e){let t=e;return this._numChannels<4?255:(t*=this._numChannels,t>=this._data.length?0:this._data[t+3])}setRed(e,t){this.set(e,0,t)}setGreen(e,t){this.set(e,1,t)}setBlue(e,t){this.set(e,2,t)}setAlpha(e,t){this.set(e,3,t)}clone(){return Ae.from(this)}toUint8Array(){return new Uint8Array(this.buffer)}}});var os,Oi,Ur=A(()=>{"use strict";H();Xn();os=class{get image(){return os._nullImageData}get isValid(){return!1}get width(){return 0}get height(){return 0}get x(){return 0}get y(){return 0}get xNormalized(){return 0}get yNormalized(){return 0}get length(){return 0}get maxChannelValue(){return 0}get maxIndexValue(){return 0}get format(){return 3}get isLdrFormat(){return!1}get isHdrFormat(){return!1}get hasPalette(){return!1}get palette(){}get index(){return 0}set index(e){}get r(){return 0}set r(e){}get g(){return 0}set g(e){}get b(){return 0}set b(e){}get a(){return 0}set a(e){}get rNormalized(){return 0}set rNormalized(e){}get gNormalized(){return 0}set gNormalized(e){}get bNormalized(){return 0}set bNormalized(e){}get aNormalized(){return 0}set aNormalized(e){}get luminance(){return 0}get luminanceNormalized(){return 0}getChannel(e){return 0}getChannelNormalized(e){return 0}setChannel(e,t){}set(e){}setRgb(e,t,n){}setRgba(e,t,n,i){}clone(){return new os}convert(e){return this}setPosition(e,t){}setPositionNormalized(e,t){}equals(e){return e instanceof os}next(){return{done:!0,value:this}}toArray(){return[]}toString(){return`${this.constructor.name} (undefined)`}[Symbol.iterator](){return this}},Oi=os;Oi._nullImageData=new ut(0,0,0)});var Sr,kr=A(()=>{"use strict";Ur();Sr=new Oi});var Q,It=A(()=>{"use strict";De();en();ae();H();G();Sn();_e();be();Tt();Yn();wi();vi();Ii();Pi();Mi();Ai();Fi();Bi();Ui();Si();ki();Xn();vr();Ir();Pr();Mr();Ar();Fr();Br();zi();Xt();kr();Q=class{constructor(e){this._frames=[];var t,n,i,r,a,s,u,o;e!==void 0?(this._loopCount=(t=e.loopCount)!=null?t:0,this._frameType=(n=e.frameType)!=null?n:2,this._frameDuration=(i=e.frameDuration)!=null?i:0,this._frameIndex=(r=e.frameIndex)!=null?r:0,this._backgroundColor=e.backgroundColor,this._textData=e.textData,this._frames.push(this),this.initialize({width:e.width,height:e.height,format:(a=e.format)!=null?a:3,numChannels:(s=e.numChannels)!=null?s:3,withPalette:(u=e.withPalette)!=null?u:!1,paletteFormat:(o=e.paletteFormat)!=null?o:3,palette:e.palette,exifData:e.exifData,iccProfile:e.iccProfile})):(this._loopCount=0,this._frameType=2,this._frameDuration=0,this._frameIndex=0)}get data(){return this._data}get numPixelColors(){return this.format===0?2:this.format===1?4:this.format===2?16:this.format===3?256:0}get format(){var e,t;return(t=(e=this._data)==null?void 0:e.format)!=null?t:3}get hasPalette(){var e;return((e=this._data)==null?void 0:e.palette)!==void 0}get palette(){var e;return(e=this._data)==null?void 0:e.palette}get numChannels(){var e,t,n,i;return(i=(n=(e=this.palette)==null?void 0:e.numChannels)!=null?n:(t=this._data)==null?void 0:t.numChannels)!=null?i:0}get hasAnimation(){return this._frames.length>1}get numFrames(){return this._frames.length}get exifData(){var e;return(e=this._exifData)!=null||(this._exifData=new Ie),this._exifData}set exifData(e){this._exifData=e}get maxChannelValue(){var e,t;return(t=(e=this._data)==null?void 0:e.maxChannelValue)!=null?t:0}get maxIndexValue(){var e,t;return(t=(e=this.data)==null?void 0:e.maxIndexValue)!=null?t:0}get supportsPalette(){return this.format===0||this.format===1||this.format===2||this.format===3}get width(){var e,t;return(t=(e=this.data)==null?void 0:e.width)!=null?t:0}get height(){var e,t;return(t=(e=this.data)==null?void 0:e.height)!=null?t:0}get formatType(){var e,t;return(t=(e=this.data)==null?void 0:e.formatType)!=null?t:0}get isValid(){return this._data!==void 0&&this.width>0&&this.height>0}get buffer(){var e;return(e=this._data)==null?void 0:e.buffer}get byteLength(){var e,t;return(t=(e=this._data)==null?void 0:e.buffer.byteLength)!=null?t:0}get rowStride(){var e,t;return(t=(e=this._data)==null?void 0:e.rowStride)!=null?t:0}get isLdrFormat(){var e,t;return(t=(e=this._data)==null?void 0:e.isLdrFormat)!=null?t:!1}get isHdrFormat(){var e,t;return(t=(e=this._data)==null?void 0:e.isHdrFormat)!=null?t:!1}get bitsPerChannel(){var e,t;return(t=(e=this._data)==null?void 0:e.bitsPerChannel)!=null?t:0}get hasAlpha(){return this.numChannels===4}get iccProfile(){return this._iccProfile}set iccProfile(e){this._iccProfile=e}get textData(){return this._textData}get backgroundColor(){return this._backgroundColor}set backgroundColor(e){this._backgroundColor=e}get loopCount(){return this._loopCount}set loopCount(e){this._loopCount=e}get frameType(){return this._frameType}set frameType(e){this._frameType=e}get frames(){return this._frames}get frameDuration(){return this._frameDuration}set frameDuration(e){this._frameDuration=e}get frameIndex(){return this._frameIndex}static fromResized(e,t,n,i=!1){var a,s,u,o;let r=new Q({width:t,height:n,loopCount:e._loopCount,frameType:e._frameType,frameDuration:e._frameDuration,frameIndex:e._frameIndex,backgroundColor:(a=e._backgroundColor)==null?void 0:a.clone(),format:e.format,numChannels:e.numChannels,withPalette:e.hasPalette,paletteFormat:(s=e.palette)==null?void 0:s.format,palette:e.palette,exifData:(u=e._exifData)==null?void 0:u.clone(),iccProfile:(o=e._iccProfile)==null?void 0:o.clone(),textData:e._textData!==void 0?new Map(e._textData):void 0});if(e._extraChannels!==void 0&&(r._extraChannels=new Map(e._extraChannels)),!i){let l=e.numFrames;for(let m=1;m4)throw new T("A MemoryImage can only have 1-4 channels.");let s=(p=e.channelOrder)!=null?p:a===3?4:a===4?0:a===1?7:6;if(a===1?s=7:a===2?s=6:a===3?s!==4&&s!==5&&(s=4):a===4&&s!==1&&s!==0&&s!==2&&s!==3&&(s=0),t.initialize({width:e.width,height:e.height,format:n,numChannels:a,withPalette:i,paletteFormat:r,palette:e.palette,exifData:e.exifData,iccProfile:e.iccProfile}),t.data!==void 0){let x=t.data.toUint8Array(),y=new Uint8Array(e.bytes),C=(g=e.rowStride)!=null?g:e.width*a*es.get(n),I=t.data.rowStride,P=Math.min(C,I),F=0,M=0;for(let w=0;w4)throw new T(`Invalid number of channels for image (${n}). Must be between 1 and 4.`);this._iccProfile=e.iccProfile,e.exifData!==void 0&&(this._exifData=e.exifData.clone());let a=(m=e.palette)!=null?m:i&&this.supportsPalette?this.createPalette(r,n):void 0;this.createImageData(e.width,e.height,t,n,a)}createImageData(e,t,n,i,r){switch(n){case 0:r===void 0?this._data=new Ut(e,t,i):this._data=Ut.palette(e,t,r);break;case 1:r===void 0?this._data=new St(e,t,i):this._data=St.palette(e,t,r);break;case 2:r===void 0?this._data=new kt(e,t,i):this._data=kt.palette(e,t,r);break;case 3:r===void 0?this._data=new ut(e,t,i):this._data=ut.palette(e,t,r);break;case 4:this._data=new Wt(e,t,i);break;case 5:this._data=new Yt(e,t,i);break;case 6:this._data=new $t(e,t,i);break;case 7:this._data=new qt(e,t,i);break;case 8:this._data=new Gt(e,t,i);break;case 9:this._data=new Lt(e,t,i);break;case 10:this._data=new Et(e,t,i);break;case 11:this._data=new Ht(e,t,i);break}}createPalette(e,t){switch(e){case 0:return;case 1:return;case 2:return;case 3:return new Ae(this.numPixelColors,t);case 4:return new Mn(this.numPixelColors,t);case 5:return new rn(this.numPixelColors,t);case 6:return new Pn(this.numPixelColors,t);case 7:return new vn(this.numPixelColors,t);case 8:return new In(this.numPixelColors,t);case 9:return new yn(this.numPixelColors,t);case 10:return new Cn(this.numPixelColors,t);case 11:return new wn(this.numPixelColors,t)}throw new T("Unknown palette format.")}addFrame(e){let t=e!=null?e:Q.from(this,!0,!0);return t._frameIndex=this._frames.length,this._frames[this._frames.length-1]!==t&&this._frames.push(t),t}getFrame(e){return this._frames[e]}clone(e){var i,r;let t=(i=e==null?void 0:e.skipAnimation)!=null?i:!1,n=(r=e==null?void 0:e.skipPixels)!=null?r:!1;return Q.from(this,t,n)}hasExtraChannel(e){return this._extraChannels!==void 0&&this._extraChannels.has(e)}getExtraChannel(e){return this._extraChannels!==void 0?this._extraChannels.get(e):void 0}setExtraChannel(e,t){var n;this._extraChannels===void 0&&t===void 0||((n=this._extraChannels)!=null||(this._extraChannels=new Map),t===void 0?this._extraChannels.delete(e):this._extraChannels.set(e,t),this._extraChannels.size===0&&(this._extraChannels=void 0))}getRange(e,t,n,i){return this.data.getRange(e,t,n,i)}toUint8Array(){var e,t;return(t=(e=this._data)==null?void 0:e.toUint8Array())!=null?t:this.buffer!==void 0?new Uint8Array(this.buffer):new Uint8Array}getBytes(e){var t,n;return(n=(t=this._data)==null?void 0:t.getBytes(e))!=null?n:this.toUint8Array()}remapChannels(e){if(this.numChannels===4){if(e===2||e===3||e===1){if(e===2)for(let t of this){let n=t.r,i=t.g,r=t.b,a=t.a;t.r=a,t.g=r,t.b=i,t.a=n}else if(e===3)for(let t of this){let n=t.r,i=t.g,r=t.b,a=t.a;t.r=a,t.g=n,t.b=i,t.a=r}else if(e===1)for(let t of this){let n=t.r,i=t.g,r=t.b,a=t.a;t.r=r,t.g=i,t.b=n,t.a=a}}}else if(this.numChannels===3&&e===5)for(let t of this){let n=t.r;t.r=t.b,t.b=n}}isBoundsSafe(e,t){return e>=0&&t>=0&&e=this.width||t<0||t>=this.height?Sr:this.getPixel(e,t,n)}getPixelClamped(e,t,n){let i=_.clamp(e,0,this.width-1),r=_.clamp(t,0,this.height-1);return this.getPixel(i,r,n)}getPixelInterpolate(e,t,n=1){switch(n){case 0:return this.getPixelSafe(Math.trunc(e),Math.trunc(t));case 1:case 3:return this.getPixelLinear(e,t);case 2:return this.getPixelCubic(e,t)}throw new T("Unknown Interpolation mode.")}getPixelLinear(e,t){let n=Math.trunc(e)-(e>=0?0:1),i=n+1,r=Math.trunc(t)-(t>=0?0:1),a=r+1,s=e-n,u=t-r,o=(c,d,p,g)=>c+s*(d-c+u*(c+g-p-d))+u*(p-c),l=this.getPixelSafe(n,r),m=a>=this.height?l:this.getPixelSafe(n,a),b=i>=this.width?l:this.getPixelSafe(i,r),h=i>=this.width||a>=this.height?l:this.getPixelSafe(i,a);return this.getColor(o(l.r,b.r,m.r,h.r),o(l.g,b.g,m.g,h.g),o(l.b,b.b,m.b,h.b),o(l.a,b.a,m.a,h.a))}getPixelCubic(e,t){let n=Math.trunc(e)-(e>=0?0:1),i=n-1,r=n+1,a=n+2,s=Math.trunc(t)-(t>=0?0:1),u=s-1,o=s+1,l=s+2,m=e-n,b=t-s,h=(Qt,$a,Wa,Ya,rr)=>Wa+.5*(Qt*(-$a+Ya)+Qt*Qt*(2*$a-5*Wa+4*Ya-rr)+Qt*Qt*Qt*(-$a+3*Wa-3*Ya+rr)),c=this.getPixelSafe(n,s),d=i<0||u<0?c:this.getPixelSafe(i,u),p=i<0?c:this.getPixelSafe(n,u),g=u<0||r>=this.width?c:this.getPixelSafe(r,u),x=a>=this.width||u<0?c:this.getPixelSafe(a,u),y=h(m,d.r,p.r,g.r,x.r),C=h(m,d.g,p.g,g.g,x.g),I=h(m,d.b,p.b,g.b,x.b),P=h(m,d.a,p.a,g.a,x.a),F=i<0?c:this.getPixelSafe(i,s),M=r>=this.width?c:this.getPixelSafe(r,s),w=a>=this.width?c:this.getPixelSafe(a,s),k=h(m,F.r,c.r,M.r,w.r),B=h(m,F.g,c.g,M.g,w.g),N=h(m,F.b,c.b,M.b,w.b),O=h(m,F.a,c.a,M.a,w.a),V=i<0||o>=this.height?c:this.getPixelSafe(i,o),E=o>=this.height?c:this.getPixelSafe(n,o),$=r>=this.width||o>=this.height?c:this.getPixelSafe(r,o),X=a>=this.width||o>=this.height?c:this.getPixelSafe(a,o),ie=h(m,V.r,E.r,$.r,X.r),te=h(m,V.g,E.g,$.g,X.g),re=h(m,V.b,E.b,$.b,X.b),W=h(m,V.a,E.a,$.a,X.a),j=i<0||l>=this.height?c:this.getPixelSafe(i,l),Re=l>=this.height?c:this.getPixelSafe(n,l),pe=r>=this.width||l>=this.height?c:this.getPixelSafe(r,l),se=a>=this.width||l>=this.height?c:this.getPixelSafe(a,l),me=h(m,j.r,Re.r,pe.r,se.r),fn=h(m,j.g,Re.g,pe.g,se.g),Ot=h(m,j.b,Re.b,pe.b,se.b),Zt=h(m,j.a,Re.a,pe.a,se.a),Mt=h(b,y,k,ie,me),Ye=h(b,C,B,te,fn),Xe=h(b,I,N,re,Ot),an=h(b,P,O,W,Zt);return this.getColor(Math.trunc(Mt),Math.trunc(Ye),Math.trunc(Xe),Math.trunc(an))}setPixel(e,t,n){var i;if("image"in n&&"index"in n&&n.image.hasPalette&&this.hasPalette){this.setPixelIndex(e,t,n.index);return}(i=this._data)==null||i.setPixelRgba(e,t,n.r,n.g,n.b,n.a)}setPixelIndex(e,t,n){var i;(i=this._data)==null||i.setPixelR(e,t,n)}setPixelR(e,t,n){var i;(i=this._data)==null||i.setPixelR(e,t,n)}setPixelRgb(e,t,n,i,r){var a;(a=this._data)==null||a.setPixelRgb(e,t,n,i,r)}setPixelRgba(e,t,n,i,r,a){var s;(s=this._data)==null||s.setPixelRgba(e,t,n,i,r,a)}clear(e){var t;(t=this._data)==null||t.clear(e)}convert(e){var u,o,l,m,b,h,c,d,p,g;let t=(u=e.format)!=null?u:this.format,n=(o=e.numChannels)!=null?o:this.numChannels,i=(l=e.alpha)!=null?l:Xa.get(t),r=(m=e.withPalette)!=null?m:!1,a=(b=e.skipAnimation)!=null?b:!1;if((r&&(n>=4||!(t===0||t===1||t===2||t===3&&n===1))||t<3&&this.format>=3)&&(r=!1),t===this.format&&n===this.numChannels&&(!r&&this.palette===void 0||r&&this.palette!==void 0))return Q.from(this);let s;for(let x of this._frames){let y=new Q({width:x.width,height:x.height,format:t,numChannels:n,withPalette:r,exifData:(h=x._exifData)==null?void 0:h.clone(),iccProfile:(c=x._iccProfile)==null?void 0:c.clone(),backgroundColor:(d=x._backgroundColor)==null?void 0:d.clone(),frameType:x._frameType,loopCount:x._loopCount,frameDuration:x._frameDuration,textData:x._textData!==void 0?new Map(x.textData):void 0});s!==void 0?s.addFrame(y):s=y;let C=y.palette,I=(g=(p=y.palette)==null?void 0:p.format)!=null?g:t;if(C!==void 0){let P=new Map,F=0,M=x.getPixel(0,0),w;for(let k of y){let B=Math.floor(M.rNormalized*255),N=Math.floor(M.gNormalized*255),O=Math.floor(M.bNormalized*255),V=z.rgbaToUint32(B,N,O,0);P.has(V)?k.index=P.get(V):(P.set(V,F),k.index=F,w=z.convertColor({from:M,to:w,format:I,numChannels:n,alpha:i}),C.setRgb(F,w.r,w.g,w.b),F++),M.next()}}else{let P=x.getPixel(0,0);for(let F of y)z.convertColor({from:P,to:F,alpha:i}),P.next()}if(a)break}return s}addTextData(e){var t;(t=this._textData)!=null||(this._textData=new Map);for(let[n,i]of e)this._textData.set(n,i)}getColorExtremes(){let e=!0,t=0,n=0;for(let i of this){for(let r=0;rn)&&(n=a)}e=!1}return{min:t,max:n}}toString(){return`${this.constructor.name} (w: ${this.width}, h: ${this.height}, f: ${q[this.format]}, ch: ${this.numChannels})`}[Symbol.iterator](){return this._data!==void 0?this._data[Symbol.iterator]():{next:()=>({done:!0,value:Sr})}}}});var ee,he,jn=A(()=>{"use strict";dn();pn();_e();It();zi();Xt();ee=class{constructor(e,t=256,n=10){this._netIndex=new Int32Array(256);this._netSize=16;this._specials=3;this._bgColor=0;this._cutNetSize=0;this._maxNetPos=0;this._initRadius=0;this._initBiasRadius=0;this._samplingFactor=n,this.initialize(t),this.addImage(e)}get palette(){return this._palette}get numColors(){return this._netSize}initialize(e){this._netSize=Math.max(e,4),this._cutNetSize=this._netSize-this._specials,this._maxNetPos=this._netSize-1,this._initRadius=Math.floor(this._netSize/8),this._initBiasRadius=this._initRadius*ee._radiusBias,this._paletteInternal=new rn(256,4),this._palette=new Ae(256,3),this._specials=3,this._bgColor=this._specials-1,this._radiusPower=new Int32Array(this._netSize>>3),this._network=new Array(this._netSize*3).fill(0),this._bias=new Array(this._netSize).fill(0),this._freq=new Array(this._netSize).fill(0),this._network[0]=0,this._network[1]=0,this._network[2]=0,this._network[3]=255,this._network[4]=255,this._network[5]=255;let t=1/this._netSize;for(let n=0;nthis._netSize&&(u=this._netSize);let o=n+1,l=n-1,m=1;for(;os;){let b=this._radiusPower[m++];if(os){let h=l*3;this._network[h]-=b*(this._network[h]-i)/ee.alphaRadiusBias,this._network[h+1]-=b*(this._network[h+1]-r)/ee.alphaRadiusBias,this._network[h+2]-=b*(this._network[h+2]-a)/ee.alphaRadiusBias,l--}}}learn(e){let t=this._initBiasRadius,n=30+Math.floor((this._samplingFactor-1)/3),i=e.width*e.height,r=Math.floor(i/this._samplingFactor),a=Math.max(Math.floor(r/ee._numCycles),1),s=ee._initAlpha;a===0&&(a=1);let u=t>>ee._radiusBiasShift;u<=1&&(u=0),this.updateRadiusPower(u,s);let o=0,l=0;i=this._specials){let I=Number(s)/ee._initAlpha;this.alterSingle(I,C,y,x,g),u>0&&this.alterNeighbors(I,u,C,y,x,g)}for(l+=o,h+=o;h>m;)h-=m,c++;for(;l>=i;)l-=i,c-=b;d++,d%a===0&&(s-=Math.floor(s/n),t-=Math.floor(t/ee._radiusDec),u=t>>ee._radiusBiasShift,u<=1&&(u=0),this.updateRadiusPower(u,s))}}fix(){for(let e=0,t=0;e>1;for(let u=e+1;u>1;for(let n=e+1;n<256;n++)this._netIndex[n]=this._maxNetPos}copyPalette(){for(let e=0;e=0;){if(a=i)a=this._netSize;else{u<0&&(u=-u);let o=this._paletteInternal.get(a,0)-e;o<0&&(o=-o),u+=o,u=0){let u=s*4,o=t-this._paletteInternal.get(s,1);if(o>=i)s=-1;else{o<0&&(o=-o);let l=this._paletteInternal.get(s,0)-e;l<0&&(l=-l),o+=l,o{"use strict";zr=class{constructor(){this._buf=[void 0]}get buf(){return this._buf}get n(){return this._buf.length}}});var Ni,Nr=A(()=>{"use strict";G();Ni=class{constructor(e,t,n){this._r=0;this._g=0;this._b=0;this._count=0;this._heapIndex=0;this._paletteIndex=0;this._children=U.fill(8,void 0);this._childCount=0;this._childIndex=0;this._flags=0;this._depth=0;this._childIndex=e,this._depth=t,this._parent=n,n!==void 0&&n._childCount++}get r(){return this._r}set r(e){this._r=e}get g(){return this._g}set g(e){this._g=e}get b(){return this._b}set b(e){this._b=e}get count(){return this._count}set count(e){this._count=e}get heapIndex(){return this._heapIndex}set heapIndex(e){this._heapIndex=e}get paletteIndex(){return this._paletteIndex}set paletteIndex(e){this._paletteIndex=e}get parent(){return this._parent}get children(){return this._children}get childCount(){return this._childCount}set childCount(e){this._childCount=e}get childIndex(){return this._childIndex}get flags(){return this._flags}set flags(e){this._flags=e}get depth(){return this._depth}}});var Is,mn,Ri=A(()=>{"use strict";dn();Or();It();Nr();Xt();Is=class{get palette(){return this._palette}constructor(e,t=256){this._root=new Ni(0,0);let n=new zr;for(let s of e){let u=Math.trunc(s.r),o=Math.trunc(s.g),l=Math.trunc(s.b);this.heapAdd(n,this.nodeInsert(this._root,u,o,l))}let i=t+1;for(;n.n>i;)this.heapAdd(n,this.nodeFold(this.popHeap(n)));for(let s=1;s>=1){let u=(n&s?1:0)*4+(t&s?1:0)*2+(i&s?1:0);r.children[u]===void 0&&(r.children[u]=new Ni(u,a,r)),r=r.children[u]}return r.r+=t,r.g+=n,r.b+=i,r.count++,r}popHeap(e){if(e.n<=1)return;let t=e.buf[1];return e.buf[1]=e.buf.pop(),e.buf[1].heapIndex=1,this.downHeap(e,e.buf[1]),t}heapAdd(e,t){if(t.flags&Is._inHeap){this.downHeap(e,t),this.upHeap(e,t);return}t.flags|=Is._inHeap,t.heapIndex=e.n,e.buf.push(t),this.upHeap(e,t)}downHeap(e,t){let n=t.heapIndex;for(;;){let i=n*2;if(i>=e.n||(i+10&&i++,this.compareNode(t,e.buf[i])<=0))break;e.buf[n]=e.buf[i],e.buf[n].heapIndex=n,n=i}e.buf[n]=t,t.heapIndex=n}upHeap(e,t){let n=t.heapIndex,i;for(;n>1&&(i=e.buf[Math.trunc(n/2)],!(this.compareNode(t,i)>=0));)e.buf[n]=i,i.heapIndex=n,n=Math.trunc(n/2);e.buf[n]=t,t.heapIndex=n}nodeFold(e){if(e.childCount>0)return;let t=e.parent;return t.count+=e.count,t.r+=e.r,t.g+=e.g,t.b+=e.b,t.childCount--,t.children[e.childIndex]=void 0,t}compareNode(e,t){if(e.childCountt.childCount)return 1;let n=e.count>>e.depth,i=t.count>>t.depth;return ni?1:0}getNodes(e,t){if(t.childCount===0){e.push(t);return}for(let n of t.children)n!==void 0&&this.getNodes(e,n)}getColorIndex(e){return this.getColorIndexRgb(Math.trunc(e.r),Math.trunc(e.g),Math.trunc(e.b))}getColorIndexRgb(e,t,n){var r;let i=this._root;for(let a=1<<7;a!==0;a>>=1){let s=(t&a?1:0)*4+(e&a?1:0)*2+(n&a?1:0);if(i.children[s]===void 0)break;i=i.children[s]}return(r=i==null?void 0:i.paletteIndex)!=null?r:0}getQuantizedColor(e){let t=Math.trunc(e.r),n=Math.trunc(e.g),i=Math.trunc(e.b),r=this._root;for(let a=1<<7;a!==0;a>>=1){let s=(n&a?1:0)*4+(t&a?1:0)*2+(i&a?1:0);if(r.children[s]===void 0)break;r=r.children[s]}return t=r.r,n=r.g,i=r.b,new tn(t,n,i)}getIndexImage(e){let t=new Q({width:e.width,height:e.height,numChannels:1,palette:this.palette}),n=e[Symbol.iterator](),i=t[Symbol.iterator](),r,a;for(;r=n.next(),a=i.next(),!r.done&&!a.done;)a.value.setChannel(0,this.getColorIndex(r.value));return t}},mn=Is;mn._inHeap=1});var Rr=A(()=>{"use strict"});var Dr=A(()=>{"use strict"});var Vr=A(()=>{"use strict"});var Tr,Lr=A(()=>{"use strict";oe();G();_e();Tr=class{get length(){return this._coefficients.length}constructor(e){this._size=e,this._coefficients=U.fill(2*e+1,0)}reflect(e,t){return t<0?-t:t>=e?e-(t-e)-1:t}applyCoefficientsLine(e,t,n,i,r,a,s){for(let u=0;u{"use strict";oe();pn();Sn();_e();jn();Ri();ur();zn();It();Wn();Rr();Dr();Vr();Lr();ae();Pe=class{static adjustColor(e){var $,X,ie,te,re,W,j,Re,pe,se,me,fn,Ot,Zt,Mt,Ye,Xe,an,Qt,$a,Wa,Ya;let t=($=e.maskChannel)!=null?$:4,n=e.contrast!==void 0?_.clamp(e.contrast,0,1):void 0,i=e.saturation!==void 0?_.clamp(e.saturation,0,1):void 0,r=e.brightness!==void 0?_.clamp(e.brightness,0,1):void 0,a=e.gamma!==void 0?_.clamp(e.gamma,0,1e3):void 0,s=e.exposure!==void 0?_.clamp(e.exposure,0,1e3):void 0,u=_.clamp((X=e.amount)!=null?X:1,0,1e3),o=e.hue;if(u===0)return e.image;let l=.0174532925,m=.5,b=.5,h=.5,c=.2125,d=.7154,p=.0721,g=e.blacks!==void 0||e.whites!==void 0||e.mids!==void 0,x=0,y=0,C=0,I=0,P=0,F=0,M=0,w=0,k=0;g&&(x=(te=(ie=e.blacks)==null?void 0:ie.rNormalized)!=null?te:0,y=(W=(re=e.blacks)==null?void 0:re.gNormalized)!=null?W:0,C=(Re=(j=e.blacks)==null?void 0:j.bNormalized)!=null?Re:0,I=(se=(pe=e.whites)==null?void 0:pe.rNormalized)!=null?se:0,P=(fn=(me=e.whites)==null?void 0:me.gNormalized)!=null?fn:0,F=(Zt=(Ot=e.whites)==null?void 0:Ot.bNormalized)!=null?Zt:0,M=(Ye=(Mt=e.mids)==null?void 0:Mt.rNormalized)!=null?Ye:0,w=(an=(Xe=e.mids)==null?void 0:Xe.gNormalized)!=null?an:0,k=($a=(Qt=e.mids)==null?void 0:Qt.bNormalized)!=null?$a:0,M=1/(1+2*(M-.5)),w=1/(1+2*(w-.5)),k=1/(1+2*(k-.5)));let B=i!==void 0?1-_.clamp(i,0,1):0,N=n!==void 0?1-_.clamp(n,0,1):0;s!==void 0&&(s=Math.pow(2,s));let O=0,V=0,E=0;if(o!==void 0){o*=l;let rr=Math.sin(o),Kt=Math.cos(o);O=2*Kt/3,V=(-Math.sqrt(3)*rr-Kt)/3,E=(Math.sqrt(3)*rr-Kt+1)/3}for(let rr of e.image.frames)for(let Kt of rr){let xu=Kt.rNormalized,_u=Kt.gNormalized,yu=Kt.bNormalized,Le=xu,Ee=_u,He=yu;if(g&&(Le=Math.pow((Le+x)*I,M),Ee=Math.pow((Ee+y)*P,w),He=Math.pow((He+C)*F,k)),r!==void 0&&r!==1){let Un=_.clamp(r,0,1e3);Le*=Un,Ee*=Un,He*=Un}if(i!==void 0){let Un=Le*c+Ee*d+He*p;Le=Un*B+Le*i,Ee=Un*B+Ee*i,He=Un*B+He*i}if(n!==void 0&&(Le=m*N+Le*n,Ee=b*N+Ee*n,He=h*N+He*n),a!==void 0&&(Le=Math.pow(Le,a),Ee=Math.pow(Ee,a),He=Math.pow(He,a)),s!==void 0&&(Le*=s,Ee*=s,He*=s),o!==void 0&&o!==0){let Un=Le*O+Ee*V+He*E,Pu=Le*E+Ee*O+He*V,Mu=Le*V+Ee*E+He*O;Le=Un,Ee=Pu,He=Mu}let Es=((Ya=(Wa=e.mask)==null?void 0:Wa.getPixel(Kt.x,Kt.y).getChannelNormalized(t))!=null?Ya:1)*u;Le=_.mix(xu,Le,Es),Ee=_.mix(_u,Ee,Es),He=_.mix(yu,He,Es),Kt.rNormalized=Le,Kt.gNormalized=Ee,Kt.bNormalized=He}return e.image}static billboard(e){var a,s,u,o;let t=(a=e.grid)!=null?a:10,n=(s=e.amount)!=null?s:1,i=(u=e.maskChannel)!=null?u:4,r=.2025;for(let l of e.image.frames){let m=l.width,b=l.height,h=m/b,c=.0015625,d=.0015625*h,p=l.clone({skipAnimation:!0});for(let g of l){let x=g.x/(m-1),y=g.y/(b-1),C=Math.floor(x/(t*c)),I=Math.floor(y/(t*d)),P=Math.floor(C*t*c*(m-1)),F=Math.floor(I*t*d*(b-1));if(P>=m||F>=b)continue;let M=p.getPixel(P,F),w=_.fract(x/(t*c)),k=_.fract(y/(t*d)),B=Math.pow(Math.abs(w-.5),2),N=Math.pow(Math.abs(k-.5),2),O=M.r/g.maxChannelValue,V=M.g/g.maxChannelValue,E=M.b/g.maxChannelValue,$=_.smoothStep(r-.1,r+.1,B+N),X=(O+V+E)/3,ie=.3,te=Math.ceil(X/ie),re=ie*te+.3;O=_.mix(re*O,.1,$),V=_.mix(re*V,.1,$),E=_.mix(re*E,.1,$);let W=(o=e.mask)==null?void 0:o.getPixel(g.x,g.y).getChannelNormalized(i),j=(W!=null?W:1)*n;g.r=_.mix(g.r,O*g.maxChannelValue,j),g.g=_.mix(g.g,V*g.maxChannelValue,j),g.b=_.mix(g.b,E*g.maxChannelValue,j)}}return e.image}static bleachBypass(e){var s,u,o,l;let t=(s=e.amount)!=null?s:1,n=(u=e.maskChannel)!=null?u:4,i=.2125,r=.7154,a=.0721;for(let m of e.image.frames)for(let b of m){let h=b.rNormalized,c=b.gNormalized,d=b.bNormalized,p=h*i,g=c*r,x=d*a,y=p+g+x,C=_.clamp((y-.45)*10,0,1),I=2*h*y,P=2*c*y,F=2*d*y,M=1-2*(1-h)*(1-y),w=1-2*(1-c)*(1-y),k=1-2*(1-d)*(1-y);if(((l=(o=e.mask)==null?void 0:o.getPixel(b.x,b.y).getChannelNormalized(n))!=null?l:1)*t!==1){let O=_.mix(I,M,C)*b.maxChannelValue,V=_.mix(P,w,C)*b.maxChannelValue,E=_.mix(F,k,C)*b.maxChannelValue;b.r=_.mix(b.r,O,t),b.g=_.mix(b.g,V,t),b.b=_.mix(b.b,E,t)}else b.rNormalized=_.mix(I,M,C),b.gNormalized=_.mix(P,w,C),b.bNormalized=_.mix(F,k,C)}return e.image}static bulgeDistortion(e){var r,a,s,u,o,l,m;let t=(r=e.scale)!=null?r:.5,n=(a=e.interpolation)!=null?a:0,i=(s=e.maskChannel)!=null?s:4;for(let b of e.image.frames){let h=b.clone({skipAnimation:!0}),c=b.width,d=b.height,p=(u=e.centerX)!=null?u:Math.trunc(c/2),g=(o=e.centerY)!=null?o:Math.trunc(d/2),x=(l=e.radius)!=null?l:Math.trunc(Math.min(c,d)/2),y=x*x;for(let C of b){let I=C.x,P=C.y,F=p-I,M=g-P,w=F*F+M*M;if(I-=p,P-=g,w1&&(l/=b,m/=b);let h=Math.sqrt(1-l*l-m*m),c=l*.5+.5,d=m*.5+.5,p=h;n.frames[a.frameIndex].setPixelRgb(u,s,c*i,d*i,p*i)}return n}static chromaticAberration(e){var i,r,a;let t=(i=e.shift)!=null?i:5,n=(r=e.maskChannel)!=null?r:4;for(let s of e.image.frames){let u=s.clone({skipAnimation:!0}),o=s.width-1;for(let l of s){let m=_.clamp(l.x-t,0,o),b=_.clamp(l.x+t,0,o),h=u.getPixel(m,l.y),c=u.getPixel(b,l.y),d=(a=e.mask)==null?void 0:a.getPixel(l.x,l.y).getChannelNormalized(n);d===void 0?(l.r=c.r,l.b=h.b):(l.r=_.mix(l.r,c.r,d),l.b=_.mix(l.b,h.b,d))}}return e.image}static colorHalftone(e){var s,u,o,l,m,b,h;let t=(s=e.amount)!=null?s:1,n=(u=e.angle)!=null?u:1,i=(o=e.size)!=null?o:5,r=(l=e.maskChannel)!=null?l:4;n*=.0174533;let a=(c,d,p,g,x)=>{let y=3.14159/i,C=Math.sin(x),I=Math.cos(x),P=c-p,F=d-g,M=(I*P-C*F)*y,w=(C*P+I*F)*y;return Math.sin(M)*Math.sin(w)*4};for(let c of e.image.frames){let d=c.width,p=c.height,g=(m=e.centerX)!=null?m:Math.trunc(d/2),x=(b=e.centerY)!=null?b:Math.trunc(p/2);for(let y of c){let C=y.x,I=y.y,P=1-y.rNormalized,F=1-y.gNormalized,M=1-y.bNormalized,w=Math.min(P,Math.min(F,M));P=(P-w)/(1-w),F=(F-w)/(1-w),M=(M-w)/(1-w),P=_.clamp(P*10-3+a(C,I,g,x,n+.26179),0,1),F=_.clamp(F*10-3+a(C,I,g,x,n+1.30899),0,1),M=_.clamp(M*10-3+a(C,I,g,x,n),0,1),w=_.clamp(w*10-5+a(C,I,g,x,n+.78539),0,1);let k=(1-P-w)*y.maxChannelValue,B=(1-F-w)*y.maxChannelValue,N=(1-M-w)*y.maxChannelValue,O=(h=e.mask)==null?void 0:h.getPixel(y.x,y.y).getChannelNormalized(r),V=(O!=null?O:1)*t;V!==1?(y.r=_.mix(y.r,k,V),y.g=_.mix(y.g,B,V),y.b=_.mix(y.b,N,V)):(y.r=k,y.g=B,y.b=N)}}return e.image}static colorOffset(e){var s,u,o,l,m,b;let t=(s=e.red)!=null?s:0,n=(u=e.green)!=null?u:0,i=(o=e.blue)!=null?o:0,r=(l=e.alpha)!=null?l:0,a=(m=e.maskChannel)!=null?m:4;for(let h of e.image.frames)for(let c of h){let d=(b=e.mask)==null?void 0:b.getPixel(c.x,c.y).getChannelNormalized(a);d===void 0?(c.r+=t,c.g+=n,c.b+=i,c.a+=r):(c.r=_.mix(c.r,c.r+t,d),c.g=_.mix(c.g,c.g+n,d),c.b=_.mix(c.b,c.b+i,d),c.a=_.mix(c.a,c.a+r,d))}return e.image}static contrast(e){var n,i;let t=(n=e.maskChannel)!=null?n:4;if(e.contrast===100)return e.image;if(Pe._contrastCache===void 0||e.contrast!==Pe._contrastCache.lastContrast){Pe._contrastCache={lastContrast:e.contrast,contrast:new Uint8Array(256)};let r=e.contrast*e.contrast/1e4;for(let a=0;a<256;++a)Pe._contrastCache.contrast[a]=_.clampInt255(((a/255-.5)*r+.5)*255)}for(let r of e.image.frames)for(let a of r){let s=(i=e.mask)==null?void 0:i.getPixel(a.x,a.y).getChannelNormalized(t),u=Math.trunc(a.r),o=Math.trunc(a.g),l=Math.trunc(a.b);s===void 0?(a.r=Pe._contrastCache.contrast[u],a.g=Pe._contrastCache.contrast[o],a.b=Pe._contrastCache.contrast[l]):(a.r=_.mix(a.r,Pe._contrastCache.contrast[u],s),a.g=_.mix(a.g,Pe._contrastCache.contrast[o],s),a.b=_.mix(a.b,Pe._contrastCache.contrast[l],s))}return e.image}static convolution(e){var s,u,o,l,m;let t=(s=e.div)!=null?s:1,n=(u=e.offset)!=null?u:0,i=(o=e.amount)!=null?o:1,r=(l=e.maskChannel)!=null?l:4,a=Q.from(e.image);for(let b of e.image.frames){let h=a.frames[b.frameIndex];for(let c of h){let d=0,p=0,g=0;for(let I=0,P=0;I<3;++I){let F=Math.min(Math.max(c.y-1+I,0),e.image.height-1);for(let M=0;M<3;++M,++P){let w=Math.min(Math.max(c.x-1+M,0),e.image.width-1),k=h.getPixel(w,F);d+=k.r*e.filter[P],p+=k.g*e.filter[P],g+=k.b*e.filter[P]}}d=_.clampInt255(d/t+n),p=_.clampInt255(p/t+n),g=_.clampInt255(g/t+n);let x=b.getPixel(c.x,c.y),y=(m=e.mask)==null?void 0:m.getPixel(x.x,x.y).getChannelNormalized(r),C=(y!=null?y:1)*i;x.r=_.mix(x.r,d,C),x.g=_.mix(x.g,p,C),x.b=_.mix(x.b,g,C)}}return e.image}static copyImageChannels(e){var s,u,o;let t=(s=e.scaled)!=null?s:!1,n=(u=e.maskChannel)!=null?u:4,i=e.from.width/e.image.width,r=e.from.height/e.image.height,a=e.from.getPixel(0,0);for(let l of e.image.frames)for(let m of l){t?a.setPosition(Math.floor(m.x*i),Math.floor(m.y*r)):a.setPosition(m.x,m.y);let b=e.red!==void 0?a.getChannelNormalized(e.red):m.rNormalized,h=e.green!==void 0?a.getChannelNormalized(e.green):m.gNormalized,c=e.blue!==void 0?a.getChannelNormalized(e.blue):m.bNormalized,d=e.alpha!==void 0?a.getChannelNormalized(e.alpha):m.aNormalized,p=(o=e.mask)==null?void 0:o.getPixel(m.x,m.y).getChannelNormalized(n);p===void 0?(m.rNormalized=b,m.gNormalized=h,m.bNormalized=c,m.aNormalized=d):(m.rNormalized=_.mix(m.r,b,p),m.gNormalized=_.mix(m.g,h,p),m.bNormalized=_.mix(m.b,c,p),m.aNormalized=_.mix(m.a,d,p))}return e.image}static ditherImage(e){var c,d,p;let t=(c=e.quantizer)!=null?c:new he(e.image),n=(d=e.kernel)!=null?d:2,i=(p=e.serpentine)!=null?p:!1;if(n===0)return t.getIndexImage(e.image);let r=us[n],a=e.image.height,s=e.image.width,u=i?-1:1,o=t.palette,l=new Q({width:s,height:a,numChannels:1,palette:o}),m=e.image[Symbol.iterator](),b=m.next(),h=0;for(let g=0;g=0&&te+C=0&&re+g{let w=(F-I)*p,k=(M-P)*g,B=(s*w-a*k)*n,N=(a*w+s*k)*n;return Math.sin(B)*Math.sin(N)*4};for(let I of d){let P=I.luminanceNormalized,F=C(x,y,I.x/p,I.y/g),M=(P*10-5+F)*I.maxChannelValue,w=(c=e.mask)==null?void 0:c.getPixel(I.x,I.y).getChannelNormalized(r),k=(w!=null?w:1)*i;I.r=_.mix(I.r,M,k),I.g=_.mix(I.g,M,k),I.b=_.mix(I.b,M,k)}}return e.image}static dropShadow(e){var h;let t=e.blur>=0?e.blur:0,n=(h=e.shadowColor)!=null?h:new Dt(0,0,0,128),i=e.image.width+t*2,r=e.image.height+t*2,a=-t,s=-t,u=i,o=r,l=0,m=0;a+e.hShadow<0&&(l=-(a+e.hShadow),a=-a,u=l),s+e.vShadow<0&&(m=-(s+e.vShadow),s=-s,o+=m),i+a+e.hShadow>u&&(u=i+a+e.hShadow),r+s+e.vShadow>o&&(o=r+s+e.vShadow);let b=new Q({width:u,height:o,numChannels:4});return b.clear(new Dt(255,255,255,0)),D.compositeImage({dst:b,src:e.image,dstX:a,dstY:s}),Pe.remapColors({image:b,red:3,green:3,blue:3}),Pe.scaleRgba({image:b,scale:n}),Pe.gaussianBlur({image:b,radius:t}),D.compositeImage({dst:b,src:e.image,dstX:l,dstY:m}),b}static edgeGlow(e){var i,r,a;let t=(i=e.amount)!=null?i:1,n=(r=e.maskChannel)!=null?r:4;if(t===0)return e.image;for(let s of e.image.frames){let u=Q.from(s,!0),o=s.width,l=s.height;for(let m of s){let b=_.clamp(m.y-1,0,l-1),h=_.clamp(m.y+1,0,l-1),c=_.clamp(m.x-1,0,o-1),d=_.clamp(m.x+1,0,o-1),p=u.getPixel(c,b),g=u.getPixel(m.x,b),x=u.getPixel(d,b),y=u.getPixel(c,m.y),C=m,I=u.getPixel(d,m.y),P=u.getPixel(c,h),F=u.getPixel(m.x,h),M=u.getPixel(d,h),w=p.rNormalized+2*g.rNormalized+x.rNormalized-P.rNormalized-2*F.rNormalized-M.rNormalized,k=p.gNormalized+2*g.gNormalized+x.gNormalized-P.gNormalized-2*F.gNormalized-M.gNormalized,B=p.bNormalized+2*g.bNormalized+x.bNormalized-P.bNormalized-2*F.bNormalized-M.bNormalized,N=p.rNormalized-x.rNormalized+2*y.rNormalized-2*I.rNormalized+P.rNormalized-M.rNormalized,O=p.gNormalized-x.gNormalized+2*y.gNormalized-2*I.gNormalized+P.gNormalized-M.gNormalized,V=p.bNormalized-x.bNormalized+2*y.bNormalized-2*I.bNormalized+P.bNormalized-M.bNormalized,E=Math.sqrt(w*w+N*N),$=Math.sqrt(k*k+O*O),X=Math.sqrt(B*B+V*V),ie=E*2*C.rNormalized*m.maxChannelValue,te=$*2*C.gNormalized*m.maxChannelValue,re=X*2*C.bNormalized*m.maxChannelValue,W=(a=e.mask)==null?void 0:a.getPixel(m.x,m.y).getChannelNormalized(n),j=(W!=null?W:1)*t;m.r=_.mix(m.r,ie,j),m.g=_.mix(m.g,te,j),m.b=_.mix(m.b,re,j)}}return e.image}static emboss(e){var r,a;let t=(r=e.amount)!=null?r:1,n=(a=e.maskChannel)!=null?a:4,i=[1.5,0,0,0,0,0,0,0,-1.5];return Pe.convolution({image:e.image,filter:i,div:1,offset:127,amount:t,mask:e.mask,maskChannel:n})}static gamma(e){var n,i;let t=(n=e.maskChannel)!=null?n:4;for(let r of e.image.frames)for(let a of r){let s=(i=e.mask)==null?void 0:i.getPixel(a.x,a.y).getChannelNormalized(t);s===void 0?(a.rNormalized=Math.pow(a.rNormalized,e.gamma),a.gNormalized=Math.pow(a.gNormalized,e.gamma),a.bNormalized=Math.pow(a.bNormalized,e.gamma)):(a.rNormalized=_.mix(a.rNormalized,Math.pow(a.rNormalized,e.gamma),s),a.gNormalized=_.mix(a.gNormalized,Math.pow(a.gNormalized,e.gamma),s),a.bNormalized=_.mix(a.bNormalized,Math.pow(a.bNormalized,e.gamma),s))}return e.image}static gaussianBlur(e){var i;let t=(i=e.maskChannel)!=null?i:4;if(e.radius<=0)return e.image;let n;if(Pe._gaussianKernelCache.has(e.radius))n=Pe._gaussianKernelCache.get(e.radius);else{let r=e.radius*2/3,a=2*r*r;n=new Tr(e.radius);let s=0;for(let u=-e.radius;u<=e.radius;++u){let o=Math.exp(-(u*u)/a);s+=o,n.setCoefficient(u+e.radius,o)}n.scaleCoefficients(1/s),Pe._gaussianKernelCache.set(e.radius,n)}return Pe.separableConvolution({image:e.image,kernel:n,mask:e.mask,maskChannel:t})}static grayscale(e){var i,r,a;let t=(i=e.amount)!=null?i:1,n=(r=e.maskChannel)!=null?r:4;for(let s of e.image.frames)if(s.hasPalette){let u=s.palette,o=u.numColors;for(let l=0;lMath.log(s*u+1)/u,n=(s,u)=>{let o=Math.max(0,s*u);return o>1&&(o=1+t(o-1,.184874)),Math.pow(o,.4545)*84.66},i=new Q({width:e.image.width,height:e.image.height,numChannels:e.image.numChannels}),r=e.exposure!==void 0?Math.pow(2,_.clamp(e.exposure+2.47393,-20,20)):1,a=e.image.numChannels;for(let s=0;s255&&(h=255*(h/p),c=255*(c/p),d=255*(d/p)),e.image.numChannels>3){let g=o.a;(!isFinite(g)||isNaN(g))&&(g=1),i.setPixelRgba(u,s,_.clampInt255(h),_.clampInt255(c),_.clampInt255(d),_.clampInt255(g*255))}else i.setPixelRgb(u,s,_.clampInt255(h),_.clampInt255(c),_.clampInt255(d))}return i}static hexagonPixelate(e){var r,a,s,u,o,l;let t=(r=e.size)!=null?r:5,n=(a=e.amount)!=null?a:1,i=(s=e.maskChannel)!=null?s:4;for(let m of e.image.frames){let b=m.width-1,h=m.height-1,c=((u=e.centerX)!=null?u:Math.trunc(m.width/2))/b,d=((o=e.centerY)!=null?o:Math.trunc(m.height/2))/h,p=m.clone({skipAnimation:!0});for(let g of m){let x=(g.x-c)/t,y=(g.y-d)/t;y/=.866025404,x-=y*.5;let C=0,I=0;x+y-Math.floor(x)-Math.floor(y)<1?(C=Math.floor(x),I=Math.floor(y)):(C=Math.ceil(x),I=Math.ceil(y));let P=Math.ceil(x),F=Math.floor(y),M=Math.floor(x),w=Math.ceil(y),k=x,B=y,N=1-x-y,O=C,V=I,E=1-C-I,$=P,X=F,ie=1-P-F,te=M,re=w,W=1-M-w,j=_.length3(k-O,B-V,N-E),Re=_.length3(k-$,B-X,N-ie),pe=_.length3(k-te,B-re,N-W),se=0,me=0;j1e-4&&(i+=Math.log(b))}i=Math.exp(i/(e.image.width*e.image.height));let r=1/(i*i);for(let u of e.image){let o=u.r,l=u.g,m=u.b,b=n[0]*o+n[1]*l+n[2]*m,h=(1+b*r)/(1+b),c=(s=e.mask)==null?void 0:s.getPixel(u.x,u.y).getChannelNormalized(t);c===void 0?(u.r=o*h,u.g=l*h,u.b=m*h):(u.r=_.mix(u.r,o*h,c),u.g=_.mix(u.g,l*h,c),u.b=_.mix(u.b,m*h,c))}return e.image}static remapColors(e){var s,u,o,l;let t=(s=e.red)!=null?s:0,n=(u=e.green)!=null?u:1,i=(o=e.blue)!=null?o:2,r=(l=e.alpha)!=null?l:3,a=[0,0,0,0,0];for(let m of e.image.frames)for(let b of m)a[0]=b.r,a[1]=b.g,a[2]=b.b,a[3]=b.a,(t===4||n===4||i===4||r===4)&&(a[4]=z.getLuminanceRgb(a[0],a[1],a[2])),b.r=a[t],b.g=a[n],b.b=a[i],b.a=a[r];return e.image}static scaleRgba(e){var s,u;let t=(s=e.maskChannel)!=null?s:4,n=e.scale.rNormalized,i=e.scale.gNormalized,r=e.scale.bNormalized,a=e.scale.aNormalized;for(let o of e.image.frames)for(let l of o){let m=(u=e.mask)==null?void 0:u.getPixel(l.x,l.y).getChannelNormalized(t);m===void 0?l.setRgba(l.r*n,l.g*i,l.b*r,l.a*a):(l.r=_.mix(l.r,l.r*n,m),l.g=_.mix(l.g,l.g*i,m),l.b=_.mix(l.b,l.b*r,m),l.a=_.mix(l.a,l.a*a,m))}return e.image}static separableConvolution(e){var i;let t=(i=e.maskChannel)!=null?i:4,n=Q.from(e.image);return e.kernel.apply({src:e.image,dst:n,maskChannel:t,mask:e.mask}),e.kernel.apply({src:n,dst:e.image,horizontal:!1,maskChannel:t,mask:e.mask}),e.image}static sepia(e){var i,r,a;let t=(i=e.amount)!=null?i:1,n=(r=e.maskChannel)!=null?r:4;if(t===0)return e.image;for(let s of e.image.frames)for(let u of s){let o=u.rNormalized,l=u.gNormalized,m=u.bNormalized,b=z.getLuminanceRgb(o,l,m),h=(a=e.mask)==null?void 0:a.getPixel(u.x,u.y).getChannelNormalized(n),c=(h!=null?h:1)*t;u.rNormalized=c*(b+.15)+(1-c)*o,u.gNormalized=c*(b+.07)+(1-c)*l,u.bNormalized=c*(b-.12)+(1-c)*m}return e.image}static sketch(e){var i,r,a;let t=(i=e.amount)!=null?i:1,n=(r=e.maskChannel)!=null?r:4;if(t===0)return e.image;for(let s of e.image.frames){let u=s.width,o=s.height,l=Q.from(s,!0);for(let m of s){let b=_.clamp(m.y-1,0,o-1),h=_.clamp(m.y+1,0,o-1),c=_.clamp(m.x-1,0,u-1),d=_.clamp(m.x+1,0,u-1),p=l.getPixel(c,h).luminanceNormalized,g=l.getPixel(c,b).luminanceNormalized,x=l.getPixel(d,h).luminanceNormalized,y=l.getPixel(d,b).luminanceNormalized,C=l.getPixel(c,m.y).luminanceNormalized,I=l.getPixel(d,m.y).luminanceNormalized,P=l.getPixel(m.x,h).luminanceNormalized,F=l.getPixel(m.x,b).luminanceNormalized,M=-g-2*F-y+p+2*P+x,w=-p-2*C-g+x+2*I+y,k=1-Math.sqrt(M*M+w*w),B=_.clamp(k*m.r,0,m.maxChannelValue),N=_.clamp(k*m.g,0,m.maxChannelValue),O=_.clamp(k*m.b,0,m.maxChannelValue),V=(a=e.mask)==null?void 0:a.getPixel(m.x,m.y).getChannelNormalized(n),E=(V!=null?V:1)*t;m.r=_.mix(m.r,B,E),m.g=_.mix(m.g,N,E),m.b=_.mix(m.b,O,E)}}return e.image}static smooth(e){var i;let t=(i=e.maskChannel)!=null?i:4,n=[1,1,1,1,e.weight,1,1,1,1];return Pe.convolution({image:e.image,filter:n,div:e.weight+8,offset:0,mask:e.mask,maskChannel:t})}static sobel(e){var i,r,a;let t=(i=e.amount)!=null?i:1,n=(r=e.maskChannel)!=null?r:4;if(t===0)return e.image;for(let s of e.image.frames){let u=Q.from(s,!0),o=s.width,l=s.height;for(let m of s){let b=_.clamp(m.y-1,0,l-1),h=_.clamp(m.y+1,0,l-1),c=_.clamp(m.x-1,0,o-1),d=_.clamp(m.x+1,0,o-1),p=u.getPixel(c,h).luminanceNormalized,g=u.getPixel(c,b).luminanceNormalized,x=u.getPixel(d,h).luminanceNormalized,y=u.getPixel(d,b).luminanceNormalized,C=u.getPixel(c,m.y).luminanceNormalized,I=u.getPixel(d,m.y).luminanceNormalized,P=u.getPixel(m.x,h).luminanceNormalized,F=u.getPixel(m.x,b).luminanceNormalized,M=-g-2*F-y+p+2*P+x,w=-p-2*C-g+x+2*I+y,k=Math.sqrt(M*M+w*w)*m.maxChannelValue,B=(a=e.mask)==null?void 0:a.getPixel(m.x,m.y).getChannelNormalized(n),N=(B!=null?B:1)*t,O=1-N;m.r=k*N+m.r*O,m.g=k*N+m.g*O,m.b=k*N+m.b*O}}return e.image}static stretchDistortion(e){var i,r,a,s,u;let t=(i=e.interpolation)!=null?i:0,n=(r=e.maskChannel)!=null?r:4;for(let o of e.image.frames){let l=o.clone({skipAnimation:!0}),m=o.width-1,b=o.height-1,h=(a=e.centerX)!=null?a:Math.trunc(o.width/2),c=(s=e.centerY)!=null?s:Math.trunc(o.height/2),d=2*(h/m)-1,p=2*(c/b)-1;for(let g of o){let x=g.x/m*2-1,y=g.y/b*2-1;x-=d,y-=p;let C=Math.sign(x),I=Math.sign(y);x=Math.abs(x),y=Math.abs(y),x=(.5*x+.5*_.smoothStep(.25,.5,x)*x)*C,y=(.5*y+.5*_.smoothStep(.25,.5,y)*y)*I,x+=d,y+=p;let P=_.clamp((x/2+.5)*m,0,m-1),F=_.clamp((y/2+.5)*b,0,b-1),M=l.getPixelInterpolate(P,F,t),w=(u=e.mask)==null?void 0:u.getPixel(g.x,g.y).getChannelNormalized(n);w===void 0?(g.r=M.r,g.g=M.g,g.b=M.b):(g.r=_.mix(g.r,M.r,w),g.g=_.mix(g.g,M.g,w),g.b=_.mix(g.b,M.b,w))}}return e.image}static vignette(e){var h,c,d,p,g,x,y,C,I,P,F,M,w;let t=(h=e.start)!=null?h:.3,n=(c=e.end)!=null?c:.85,i=(d=e.amount)!=null?d:.9,r=(p=e.maskChannel)!=null?p:4,a=e.image.height-1,s=e.image.width-1,u=(x=(g=e.color)==null?void 0:g.rNormalized)!=null?x:0,o=(C=(y=e.color)==null?void 0:y.gNormalized)!=null?C:0,l=(P=(I=e.color)==null?void 0:I.bNormalized)!=null?P:0,m=(M=(F=e.color)==null?void 0:F.aNormalized)!=null?M:1,b=s/a;for(let k of e.image.frames)for(let B of k){let N=(.5-B.x/s)*b,O=.5-B.y/a,V=Math.sqrt(N*N+O*O);V=1-_.smoothStep(n,t,V);let E=_.mix(B.rNormalized,u,V)*B.maxChannelValue,$=_.mix(B.gNormalized,o,V)*B.maxChannelValue,X=_.mix(B.bNormalized,l,V)*B.maxChannelValue,ie=_.mix(B.aNormalized,m,V)*B.maxChannelValue,te=(w=e.mask)==null?void 0:w.getPixel(B.x,B.y).getChannelNormalized(r),re=(te!=null?te:1)*i;B.r=_.mix(B.r,E,re),B.g=_.mix(B.g,$,re),B.b=_.mix(B.b,X,re),B.a=_.mix(B.a,ie,re)}return e.image}},Zn=Pe;Zn._gaussianKernelCache=new Map});var Ps,An,Fn=A(()=>{"use strict";je();be();Ps=class{get fileLength(){return this._fileLength}set imageOffset(e){this._imageOffset=e}get imageOffset(){return this._imageOffset}constructor(e){if(!Ps.isValidFile(e))throw new T("Not a bitmap file.");e.skip(2),this._fileLength=e.readInt32(),e.skip(4),this._imageOffset=e.readInt32()}static isValidFile(e){return e.length<2?!1:Y.from(e).readUint16()===Ps.signature}},An=Ps;An.signature=19778});var Di=A(()=>{"use strict"});var Vi=A(()=>{"use strict";Jt();be();Xt();Di();Fn()});var Ti=A(()=>{"use strict";H();je();It();Fn();Vi()});var Hr=A(()=>{"use strict";H();At();Xt();Di();Fn()});var cs=A(()=>{"use strict"});var bs=A(()=>{"use strict"});var qr=A(()=>{"use strict";Ti()});var fs=A(()=>{"use strict"});var jt,Li=A(()=>{"use strict";en();Xt();jt=class{get numColors(){return this._numColors}get palette(){return this._palette}get bitsPerPixel(){return this._bitsPerPixel}set transparent(e){this._transparent=e}get transparent(){return this._transparent}constructor(e,t){this._numColors=e,this._palette=t!=null?t:new Ae(e,3),this._bitsPerPixel=jt.bitSize(e)}static bitSize(e){for(let t=1;t<=8;t++)if(1<=e)return t;return 0}static from(e){let t=Ae.from(e._palette),n=new jt(e.numColors,t);return n._bitsPerPixel=e._bitsPerPixel,n._transparent=e._transparent,n}getColor(e){let t=this.getRed(e),n=this.getGreen(e),i=this.getBlue(e),r=this.getAlpha(e);return ge.rgba(t,n,i,r)}setColor(e,t,n,i){this._palette.setRgb(e,t,n,i)}getRed(e){return Math.trunc(this._palette.getRed(e))}getGreen(e){return Math.trunc(this._palette.getGreen(e))}getBlue(e){return Math.trunc(this._palette.getBlue(e))}getAlpha(e){return e===this._transparent?0:255}getPalette(){if(this._transparent===void 0)return this._palette;let e=new Ae(this._palette.numColors,4),t=this._palette.numColors;for(let n=0;n{"use strict";Li();Gr=class{constructor(e){this._duration=80;this._clearFrame=!0;this._x=e.readUint16(),this._y=e.readUint16(),this._width=e.readUint16(),this._height=e.readUint16();let t=e.readByte(),n=(t&7)+1;if(this._interlaced=(t&64)!==0,t&128){this._colorMap=new jt(1<{"use strict";Wr=class{constructor(e){this._width=0;this._height=0;this._backgroundColor=void 0;this._isGif89=!1;var t,n,i,r,a;this._width=(t=e==null?void 0:e.width)!=null?t:0,this._height=(n=e==null?void 0:e.height)!=null?n:0,this._backgroundColor=e==null?void 0:e.backgroundColor,this._frames=(i=e==null?void 0:e.frames)!=null?i:new Array,this._colorResolution=(r=e==null?void 0:e.colorResolution)!=null?r:0,this._globalColorMap=e==null?void 0:e.globalColorMap,this._isGif89=(a=e==null?void 0:e.isGif89)!=null?a:!1}get width(){return this._width}get height(){return this._height}get backgroundColor(){return this._backgroundColor}get frames(){return this._frames}get colorResolution(){return this._colorResolution}get globalColorMap(){return this._globalColorMap}get isGif89(){return this._isGif89}get numFrames(){return this.frames.length}}});var Z,Ne,Xr=A(()=>{"use strict";je();G();Li();$r();Yr();It();en();Z=class{constructor(e){this._repeat=0;this._bitsPerPixel=0;this._currentShiftDWord=0;this._currentShiftState=0;this._stackPtr=0;this._lastCode=0;this._maxCode1=0;this._runningBits=0;this._runningCode=0;this._eofCode=0;this._clearCode=0;e!==void 0&&this.startDecode(e)}get numFrames(){return this._info!==void 0?this._info.numFrames:0}static getPrefixChar(e,t,n){let i=t,r=0;for(;i>n&&r++<=Z._lzMaxCode;){if(i>Z._lzMaxCode)return Z._noSuchCode;i=e[i]}return i}static updateImage(e,t,n,i){if(n!==void 0){let r=i.length;for(let a=0;a>4)+1,a=(i&7)+1,s=new ge(new Uint8Array([this._input.readByte()]));this._input.skip(1);let u;if(i&128){u=new jt(1<>2&7,a=t&1;if(e.peekBytes(1).getByte(0)===Z._imageDescRecordType){e.skip(1);let u=this.skipImage();if(u===void 0)return;u.duration=n,u.clearFrame=r===2,a!==0&&(u.colorMap===void 0&&this._info.globalColorMap!==void 0&&(u.colorMap=jt.from(this._info.globalColorMap)),u.colorMap!==void 0&&(u.colorMap.transparent=i)),this._info.frames.push(u)}}getLine(e){return this._pixelCount=this._pixelCount-e.length,this.decompressLine(e)?(this._pixelCount===0&&this.skipRemainder(),!0):!1}decompressLine(e){if(this._stackPtr>Z._lzMaxCode)return!1;let t=e.length,n=0;if(this._stackPtr!==0)for(;this._stackPtr!==0&&nthis._clearCode&&i<=Z._lzMaxCode;)this._stack[this._stackPtr++]=this._suffix[i],i=this._prefix[i];if(r>=Z._lzMaxCode||i>Z._lzMaxCode)return!1;for(this._stack[this._stackPtr++]=i;this._stackPtr!==0&&nZ._lzBits)return;for(;this._currentShiftState>=this._runningBits,this._currentShiftState-=this._runningBits,this._runningCodethis._maxCode1&&this._runningBitsthis._info.width||e.y+n>this._info.height)return;let i=e.colorMap!==void 0?e.colorMap:this._info.globalColorMap;this._pixelCount=t*n;let r=new Q({width:t,height:n,numChannels:1,palette:i.getPalette()}),a=new Uint8Array(t);if(e.interlaced){let s=e.y;for(let u=0,o=0;u<4;++u)for(let l=s+Z._interlacedOffset[u];l=this._info.frames.length||e<0)return;let t=this._info.frames[e];return this._input.offset=t.inputPosition,this.decodeImage(this._info.frames[e])}},Ne=Z;Ne._stampSize=6,Ne._gif87Stamp="GIF87a",Ne._gif89Stamp="GIF89a",Ne._imageDescRecordType=44,Ne._extensionRecordType=33,Ne._terminateRecordType=59,Ne._graphicControlExt=249,Ne._applicationExt=255,Ne._lzMaxCode=4095,Ne._lzBits=12,Ne._noSuchCode=4098,Ne._codeMasks=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095],Ne._interlacedOffset=[0,4,2,1],Ne._interlacedJump=[8,8,4,2]});var jr=A(()=>{"use strict"});var Fe,Pt,Zr=A(()=>{"use strict";jn();At();nn();jr();Ri();Er();be();Wn();Fe=class{constructor(e){this._curAccum=0;this._curBits=0;this._nBits=0;this._initBits=0;this._eofCode=0;this._maxCode=0;this._clearCode=0;this._freeEnt=0;this._clearFlag=!1;this._blockSize=0;this._supportsAnimation=!0;var t,n,i,r,a;this._delay=(t=e==null?void 0:e.delay)!=null?t:80,this._repeat=(n=e==null?void 0:e.repeat)!=null?n:0,this._numColors=256,this._quantizerType=1,this._samplingFactor=(i=e==null?void 0:e.samplingFactor)!=null?i:10,this._dither=(r=e==null?void 0:e.dither)!=null?r:2,this._ditherSerpentine=(a=e==null?void 0:e.ditherSerpentine)!=null?a:!1,this._encodedFrames=0}get supportsAnimation(){return this._supportsAnimation}addImage(e,t,n){if(!e.hasPalette)throw new T("GIF can only encode palette images.");let i=e.palette,r=i.numColors,a=this._outputBuffer;a.writeByte(Fe._imageDescRecordType),a.writeUint16(0),a.writeUint16(0),a.writeUint16(t),a.writeUint16(n);let s=i.toUint8Array();a.writeByte(135);let u=i.numChannels;if(u===3)a.writeBytes(s);else if(u===4)for(let o=0,l=0;o{if(s)return Fe._eof;let h=Math.trunc(a.value.index);return a=r.next(),a.done&&(s=!0),h},o=u(),l=0;for(let h=Fe._hSize;h<65536;h*=2)l++;l=8-l;let m=Fe._hSize;for(let h=0;h=0){let p=m-d;d===0&&(p=1);do if((d-=p)<0&&(d+=m),n[d]===c){o=i[d],b=!0;break}while(n[d]>=0);if(b)break}if(this.output(o),o=h,this._freeEnt<1<0?this._curAccum|=e<=8;)this.addToBlock(this._curAccum&255),this._curAccum>>=8,this._curBits-=8;if((this._freeEnt>this._maxCode||this._clearFlag)&&(this._clearFlag?(this._nBits=this._initBits,this._maxCode=(1<0;)this.addToBlock(this._curAccum&255),this._curAccum>>=8,this._curBits-=8;this.writeBlock()}}writeBlock(){this._blockSize>0&&(this._outputBuffer.writeByte(this._blockSize),this._outputBuffer.writeBytes(this._block,this._blockSize),this._blockSize=0)}addToBlock(e){this._block[this._blockSize++]=e,this._blockSize>=254&&this.writeBlock()}writeApplicationExt(){this._outputBuffer.writeByte(Fe._extensionRecordType),this._outputBuffer.writeByte(Fe._applicationExt),this._outputBuffer.writeByte(11);let e=we.getCodePoints("NETSCAPE2.0");this._outputBuffer.writeBytes(e),this._outputBuffer.writeBytes(new Uint8Array([3,1])),this._outputBuffer.writeUint16(this._repeat),this._outputBuffer.writeByte(0)}writeGraphicsCtrlExt(e){var o;this._outputBuffer.writeByte(Fe._extensionRecordType),this._outputBuffer.writeByte(Fe._graphicControlExt),this._outputBuffer.writeByte(4);let t=0,n=0,i=e.palette,r=i.numChannels,a=r-1;if(r===4||r===2){let l=i.toUint8Array(),m=i.numColors;for(let b=0,h=a;b{"use strict";Vi()});var Kr=A(()=>{"use strict"});var Jr=A(()=>{"use strict"});var ea=A(()=>{"use strict";G();Kr();Jr()});var Qn=A(()=>{"use strict"});var Ei=A(()=>{"use strict"});var Ou,Hi=A(()=>{"use strict";Ou=ws(ps());pi();At();nn();Qn();H();jn();Ei()});var ta=A(()=>{"use strict";At();be();Hi()});var na=A(()=>{"use strict";ta()});var ia,ra=A(()=>{"use strict";ia=class{get hSamples(){return this._hSamples}get maxHSamples(){return this._maxHSamples}get vSamples(){return this._vSamples}get maxVSamples(){return this._maxVSamples}get lines(){return this._lines}get hScaleShift(){return this._hScaleShift}get vScaleShift(){return this._vScaleShift}constructor(e,t,n,i,r){this._hSamples=e,this._maxHSamples=t,this._vSamples=n,this._maxVSamples=i,this._lines=r,this._hScaleShift=this._hSamples===1&&this._maxHSamples===2?1:0,this._vScaleShift=this._vSamples===1&&this._maxVSamples===2?1:0}}});var aa,sa=A(()=>{"use strict";aa=class{get version(){return this._version}get flags0(){return this._flags0}get flags1(){return this._flags1}get transformCode(){return this._transformCode}constructor(e,t,n,i){this._version=e,this._flags0=t,this._flags1=n,this._transformCode=i}}});var ua,oa=A(()=>{"use strict";ua=class{constructor(e,t,n,i){this._blocks=new Array;this._blocksPerLine=0;this._blocksPerColumn=0;this._huffmanTableDC=[];this._huffmanTableAC=[];this._pred=0;this._hSamples=e,this._vSamples=t,this._quantizationTableList=n,this._quantizationIndex=i}get hSamples(){return this._hSamples}get vSamples(){return this._vSamples}get blocks(){return this._blocks}get blocksPerLine(){return this._blocksPerLine}get blocksPerColumn(){return this._blocksPerColumn}set huffmanTableDC(e){this._huffmanTableDC=e}get huffmanTableDC(){return this._huffmanTableDC}set huffmanTableAC(e){this._huffmanTableAC=e}get huffmanTableAC(){return this._huffmanTableAC}set pred(e){this._pred=e}get pred(){return this._pred}get quantizationTable(){return this._quantizationTableList[this._quantizationIndex]}setBlocks(e,t,n){this._blocks=e,this._blocksPerLine=t,this._blocksPerColumn=n}}});var la,ma=A(()=>{"use strict";G();la=class{constructor(e,t,n,i,r,a,s){this._maxHSamples=0;this._maxVSamples=0;this._mcusPerLine=0;this._mcusPerColumn=0;this._components=e,this._componentsOrder=t,this._extended=n,this._progressive=i,this._precision=r,this._scanLines=a,this._samplesPerLine=s}get components(){return this._components}get componentsOrder(){return this._componentsOrder}get extended(){return this._extended}get progressive(){return this._progressive}get precision(){return this._precision}get scanLines(){return this._scanLines}get samplesPerLine(){return this._samplesPerLine}get maxHSamples(){return this._maxHSamples}get maxVSamples(){return this._maxVSamples}get mcusPerLine(){return this._mcusPerLine}get mcusPerColumn(){return this._mcusPerColumn}prepare(){for(let[e,t]of this._components)this._maxHSamples=Math.max(this._maxHSamples,t.hSamples),this._maxVSamples=Math.max(this._maxVSamples,t.vSamples);this._mcusPerLine=Math.ceil(this._samplesPerLine/8/this._maxHSamples),this._mcusPerColumn=Math.ceil(this._scanLines/8/this._maxVSamples);for(let[e,t]of this._components){let n=Math.ceil(Math.ceil(this._samplesPerLine/8)*t.hSamples/this._maxHSamples),i=Math.ceil(Math.ceil(this._scanLines/8)*t.vSamples/this.maxVSamples),r=this._mcusPerLine*t.hSamples,a=this._mcusPerColumn*t.vSamples,s=U.generate(a,u=>U.generate(r,o=>new Int32Array(64)));t.setBlocks(s,n,i)}}}});var Kn,ha=A(()=>{"use strict";Kn=class{constructor(){this._children=[];this._index=0}get children(){return this._children}get index(){return this._index}incrementIndex(){this._index++}}});var ca,ba=A(()=>{"use strict";ca=class{constructor(){this._width=0;this._height=0;this._numFrames=1;this._backgroundColor=void 0}get width(){return this._width}get height(){return this._height}get numFrames(){return this._numFrames}get backgroundColor(){return this._backgroundColor}setSize(e,t){this._width=e,this._height=t}}});var fa,da=A(()=>{"use strict";fa=class{get thumbWidth(){return this._thumbWidth}get thumbHeight(){return this._thumbHeight}get majorVersion(){return this._majorVersion}get minorVersion(){return this._minorVersion}get densityUnits(){return this._densityUnits}get xDensity(){return this._xDensity}get yDensity(){return this._yDensity}get thumbData(){return this._thumbData}constructor(e,t,n,i,r,a,s,u){this._thumbWidth=e,this._thumbHeight=t,this._majorVersion=n,this._minorVersion=i,this._densityUnits=r,this._xDensity=a,this._yDensity=s,this._thumbData=u}}});var Jn,hn,pa=A(()=>{"use strict";_e();be();Tt();It();Jn=class{static createDctClip(){let e=new Uint8Array(Jn._dctClipLength),t=0;for(t=-256;t<0;++t)e[Jn._dctClipOffset+t]=0;for(t=0;t<256;++t)e[Jn._dctClipOffset+t]=t;for(t=256;t<512;++t)e[Jn._dctClipOffset+t]=255;return e}static quantizeAndInverse(e,t,n,i){let r=i,a=4017,s=799,u=3406,o=2276,l=1567,m=3784,b=5793,h=2896;for(let d=0;d<64;d++)r[d]=t[d]*e[d];let c=0;for(let d=0;d<8;++d,c+=8){if(r[1+c]===0&&r[2+c]===0&&r[3+c]===0&&r[4+c]===0&&r[5+c]===0&&r[6+c]===0&&r[7+c]===0){let w=b*r[0+c]+512>>10;r[c+0]=w,r[c+1]=w,r[c+2]=w,r[c+3]=w,r[c+4]=w,r[c+5]=w,r[c+6]=w,r[c+7]=w;continue}let p=b*r[0+c]+128>>8,g=b*r[4+c]+128>>8,x=r[2+c],y=r[6+c],C=h*(r[1+c]-r[7+c])+128>>8,I=h*(r[1+c]+r[7+c])+128>>8,P=r[3+c]<<4,F=r[5+c]<<4,M=p-g+1>>1;p=p+g+1>>1,g=M,M=x*m+y*l+128>>8,x=x*l-y*m+128>>8,y=M,M=C-F+1>>1,C=C+F+1>>1,F=M,M=I+P+1>>1,P=I-P+1>>1,I=M,M=p-y+1>>1,p=p+y+1>>1,y=M,M=g-x+1>>1,g=g+x+1>>1,x=M,M=C*o+I*u+2048>>12,C=C*u-I*o+2048>>12,I=M,M=P*s+F*a+2048>>12,P=P*a-F*s+2048>>12,F=M,r[0+c]=p+I,r[7+c]=p-I,r[1+c]=g+F,r[6+c]=g-F,r[2+c]=x+P,r[5+c]=x-P,r[3+c]=y+C,r[4+c]=y-C}for(let d=0;d<8;++d){let p=d;if(r[1*8+p]===0&&r[2*8+p]===0&&r[3*8+p]===0&&r[4*8+p]===0&&r[5*8+p]===0&&r[6*8+p]===0&&r[7*8+p]===0){let k=b*i[d]+8192>>14;r[0*8+p]=k,r[1*8+p]=k,r[2*8+p]=k,r[3*8+p]=k,r[4*8+p]=k,r[5*8+p]=k,r[6*8+p]=k,r[7*8+p]=k;continue}let g=b*r[0*8+p]+2048>>12,x=b*r[4*8+p]+2048>>12,y=r[2*8+p],C=r[6*8+p],I=h*(r[1*8+p]-r[7*8+p])+2048>>12,P=h*(r[1*8+p]+r[7*8+p])+2048>>12,F=r[3*8+p],M=r[5*8+p],w=g-x+1>>1;g=g+x+1>>1,x=w,w=y*m+C*l+2048>>12,y=y*l-C*m+2048>>12,C=w,w=I-M+1>>1,I=I+M+1>>1,M=w,w=P+F+1>>1,F=P-F+1>>1,P=w,w=g-C+1>>1,g=g+C+1>>1,C=w,w=x-y+1>>1,x=x+y+1>>1,y=w,w=I*o+P*u+2048>>12,I=I*u-P*o+2048>>12,P=w,w=F*s+M*a+2048>>12,F=F*a-M*s+2048>>12,M=w,r[0*8+p]=g+P,r[7*8+p]=g-P,r[1*8+p]=x+M,r[6*8+p]=x-M,r[2*8+p]=y+F,r[5*8+p]=y-F,r[3*8+p]=C+I,r[4*8+p]=C-I}for(let d=0;d<64;++d)n[d]=Jn._dctClip[Jn._dctClipOffset+128+(r[d]+8>>4)]}static getImageFromJpeg(e){let t=e.exifData.imageIfd.hasOrientation?e.exifData.imageIfd.orientation:0,n=e.width,i=e.height,r=t>=5&&t<=8,a=r?i:n,s=r?n:i,u=new Q({width:a,height:s});u.exifData=Ie.from(e.exifData),u.exifData.imageIfd.orientation=void 0;let o,l,m,b,h,c,d,p,g=!1,x=i-1,y=n-1;switch(e.components.length){case 1:{o=e.components[0];let C=o.lines,I=o.hScaleShift,P=o.vScaleShift;for(let F=0;F>P;h=C[M];for(let w=0;w>I,B=h[k];t===2?u.setPixelRgb(y-w,F,B,B,B):t===3?u.setPixelRgb(y-w,x-F,B,B,B):t===4?u.setPixelRgb(w,x-F,B,B,B):t===5?u.setPixelRgb(F,w,B,B,B):t===6?u.setPixelRgb(x-F,w,B,B,B):t===7?u.setPixelRgb(x-F,y-w,B,B,B):t===8?u.setPixelRgb(F,y-w,B,B,B):u.setPixelRgb(w,F,B,B,B)}}}break;case 2:break;case 3:{g=!0,o=e.components[0],l=e.components[1],m=e.components[2];let C=o.lines,I=l.lines,P=m.lines,F=o.hScaleShift,M=o.vScaleShift,w=l.hScaleShift,k=l.vScaleShift,B=m.hScaleShift,N=m.vScaleShift;for(let O=0;O>M,E=O>>k,$=O>>N;h=C[V],c=I[E],d=P[$];for(let X=0;X>F,te=X>>w,re=X>>B,W=h[ie]<<8,j=c[te]-128,Re=d[re]-128,pe=W+359*Re+128,se=W-88*j-183*Re+128,me=W+454*j+128;pe=_.clampInt255(pe>>8),se=_.clampInt255(se>>8),me=_.clampInt255(me>>8),t===2?u.setPixelRgb(y-X,O,pe,se,me):t===3?u.setPixelRgb(y-X,x-O,pe,se,me):t===4?u.setPixelRgb(X,x-O,pe,se,me):t===5?u.setPixelRgb(O,X,pe,se,me):t===6?u.setPixelRgb(x-O,X,pe,se,me):t===7?u.setPixelRgb(x-O,y-X,pe,se,me):t===8?u.setPixelRgb(O,y-X,pe,se,me):u.setPixelRgb(X,O,pe,se,me)}}}break;case 4:{if(e.adobe===void 0)throw new T("Unsupported color mode (4 components)");g=!1,e.adobe.transformCode!==0&&(g=!0),o=e.components[0],l=e.components[1],m=e.components[2],b=e.components[3];let C=o.lines,I=l.lines,P=m.lines,F=b.lines,M=o.hScaleShift,w=o.vScaleShift,k=l.hScaleShift,B=l.vScaleShift,N=m.hScaleShift,O=m.vScaleShift,V=b.hScaleShift,E=b.vScaleShift;for(let $=0;$>w,ie=$>>B,te=$>>O,re=$>>E;h=C[X],c=I[ie],d=P[te],p=F[re];for(let W=0;W>M,Re=W>>k,pe=W>>N,se=W>>V,me=0,fn=0,Ot=0,Zt=0;if(!g)me=h[j],fn=c[Re],Ot=d[pe],Zt=p[se];else{Ot=h[j];let an=c[Re],Qt=d[pe];Zt=p[se],me=255-_.clampInt255(Ot+1.402*(Qt-128)),fn=255-_.clampInt255(Ot-.3441363*(an-128)-.71413636*(Qt-128)),Ot=255-_.clampInt255(Ot+1.772*(an-128))}let Mt=me*Zt>>8,Ye=fn*Zt>>8,Xe=Ot*Zt>>8;t===2?u.setPixelRgb(y-W,$,Mt,Ye,Xe):t===3?u.setPixelRgb(y-W,x-$,Mt,Ye,Xe):t===4?u.setPixelRgb(W,x-$,Mt,Ye,Xe):t===5?u.setPixelRgb($,W,Mt,Ye,Xe):t===6?u.setPixelRgb(x-$,W,Mt,Ye,Xe):t===7?u.setPixelRgb(x-$,y-W,Mt,Ye,Xe):t===8?u.setPixelRgb($,y-W,Mt,Ye,Xe):u.setPixelRgb(W,$,Mt,Ye,Xe)}}}break;default:throw new T("Unsupported color mode")}return u}},hn=Jn;hn._dctClipOffset=256,hn._dctClipLength=768,hn._dctClip=Jn.createDctClip()});var ei,qi=A(()=>{"use strict";ei=class{}});var cn,Gi=A(()=>{"use strict";qi();cn=class extends ei{constructor(t){super();this._children=t}get children(){return this._children}}});var ti,$i=A(()=>{"use strict";qi();ti=class extends ei{constructor(t){super();this._value=t}get value(){return this._value}}});var Bn=A(()=>{"use strict"});var ga,xa=A(()=>{"use strict";be();Gi();$i();Wi();Bn();ga=class{constructor(e,t,n,i,r,a,s,u){this._bitsData=0;this._bitsCount=0;this._eobrun=0;this._successiveACState=0;this._successiveACNextValue=0;this._input=e,this._frame=t,this._precision=t.precision,this._samplesPerLine=t.samplesPerLine,this._scanLines=t.scanLines,this._mcusPerLine=t.mcusPerLine,this._progressive=t.progressive,this._maxH=t.maxHSamples,this._maxV=t.maxVSamples,this._components=n,this._resetInterval=u,this._spectralStart=i,this._spectralEnd=r,this._successivePrev=a,this._successive=s}get input(){return this._input}get frame(){return this._frame}get precision(){return this._precision}get samplesPerLine(){return this._samplesPerLine}get scanLines(){return this._scanLines}get mcusPerLine(){return this._mcusPerLine}get progressive(){return this._progressive}get maxH(){return this._maxH}get maxV(){return this._maxV}get components(){return this._components}get resetInterval(){return this._resetInterval}get spectralStart(){return this._spectralStart}get spectralEnd(){return this._spectralEnd}get successivePrev(){return this._successivePrev}get successive(){return this._successive}get bitsData(){return this._bitsData}get bitsCount(){return this._bitsCount}get eobrun(){return this._eobrun}get successiveACState(){return this._successiveACState}get successiveACNextValue(){return this._successiveACNextValue}readBit(){if(this.bitsCount>0)return this._bitsCount--,this._bitsData>>this._bitsCount&1;if(!this._input.isEOS){if(this._bitsData=this._input.readByte(),this._bitsData===255){let e=this.input.readByte();if(e!==0){let t=(this._bitsData<<8|e).toString(16);throw new T(`unexpected marker: ${t}`)}}return this._bitsCount=7,this._bitsData>>7&1}}decodeHuffman(e){let t=new cn(e),n;for(;(n=this.readBit())!==void 0;)if(t instanceof cn&&(t=t.children[n]),t instanceof ti)return t.value}receive(e){let t=0,n=e;for(;n>0;){let i=this.readBit();if(i===void 0)return;t=t<<1|i,n--}return t}receiveAndExtend(e){if(e===1)return this.readBit()===1?1:-1;let t=this.receive(e);return t>=1<<(e!=null?e:0)-1?t:t+(-1<<(e!=null?e:0))+1}decodeBaseline(e,t){let n=this.decodeHuffman(e.huffmanTableDC),i=n===0?0:this.receiveAndExtend(n);e.pred+=i,t[0]=e.pred;let r=1;for(;r<64;){let a=this.decodeHuffman(e.huffmanTableAC),s=a&15,u=a>>4;if(s===0){if(u<15)break;r+=16;continue}r+=u,s=this.receiveAndExtend(s);let o=Me.dctZigZag[r];t[o]=s,r++}}decodeDCFirst(e,t){let n=this.decodeHuffman(e.huffmanTableDC),i=n===0?0:this.receiveAndExtend(n)<0){this._eobrun--;return}let n=this._spectralStart,i=this._spectralEnd;for(;n<=i;){let r=this.decodeHuffman(e.huffmanTableAC),a=r&15,s=r>>4;if(a===0){if(s<15){this._eobrun=this.receive(s)+(1<>4,r===0)a<15?(this._eobrun=this.receive(a)+(1<=e.blocks.length)return;let l=e.blocks[u].length;o>=l||t.call(this,e,e.blocks[u][o])}decodeBlock(e,t,n){let i=Math.floor(n/e.blocksPerLine),r=n%e.blocksPerLine;t.call(this,e,e.blocks[i][r])}decode(){let e=this._components.length,t,n;this._progressive?this._spectralStart===0?n=this._successivePrev===0?this.decodeDCFirst:this.decodeDCSuccessive:n=this._successivePrev===0?this.decodeACFirst:this.decodeACSuccessive:n=this.decodeBaseline;let i=0,r;e===1?r=this._components[0].blocksPerLine*this._components[0].blocksPerColumn:r=this._mcusPerLine*this._frame.mcusPerColumn,(this._resetInterval===void 0||this._resetInterval===0)&&(this._resetInterval=r);let a,s;for(;i=208&&o<=215)this._input.skip(2);else break}}}});var ni,Me,Wi=A(()=>{"use strict";je();be();ra();sa();oa();ma();ha();ba();da();pa();xa();Tt();G();Bn();$i();Gi();ni=class{constructor(){this._exifData=new Ie;this._quantizationTables=U.fill(ni.numQuantizationTables,void 0);this._frames=new Array;this._huffmanTablesAC=[];this._huffmanTablesDC=[];this._components=new Array}get input(){return this._input}get jfif(){return this._jfif}get adobe(){return this._adobe}get frame(){return this._frame}get resetInterval(){return this._resetInterval}get comment(){return this._comment}get exifData(){return this._exifData}get quantizationTables(){return this._quantizationTables}get frames(){return this._frames}get huffmanTablesAC(){return this._huffmanTablesAC}get huffmanTablesDC(){return this._huffmanTablesDC}get components(){return this._components}get width(){return this._frame.samplesPerLine}get height(){return this._frame.scanLines}readMarkers(){let e=this.nextMarker();if(e!==216)throw new T("Start Of Image marker not found.");for(e=this.nextMarker();e!==217&&!this._input.isEOS;){let t=this.readBlock();switch(e){case 224:case 225:case 226:case 227:case 228:case 229:case 230:case 231:case 232:case 233:case 234:case 235:case 236:case 237:case 238:case 239:case 254:this.readAppData(e,t);break;case 219:this.readDQT(t);break;case 192:case 193:case 194:this.readFrame(e,t);break;case 195:case 197:case 198:case 199:case 200:case 201:case 202:case 203:case 205:case 206:case 207:throw new T(`Unhandled frame type ${e.toString(16)}`);case 196:this.readDHT(t);break;case 221:this.readDRI(t);break;case 218:this.readSOS(t);break;case 255:this._input.getByte(0)!==255&&this._input.skip(-1);break;default:if(this._input.getByte(-3)===255&&this._input.getByte(-2)>=192&&this._input.getByte(-2)<=254){this._input.skip(-3);break}if(e!==0)throw new T(`Unknown JPEG marker ${e.toString(16)}`);break}e=this.nextMarker()}}skipBlock(){let e=this._input.readUint16();if(e<2)throw new T("Invalid Block");this._input.skip(e-2)}validate(e){this._input=new Y({buffer:e,bigEndian:!0});let t=this._input.peekBytes(2);if(t.getByte(0)!==255||t.getByte(1)!==216)return!1;let n=this.nextMarker();if(n!==216)return!1;let i=!1,r=!1;for(n=this.nextMarker();n!==217&&!this._input.isEOS;){let a=this._input.readUint16();if(a<2)break;switch(this._input.skip(a-2),n){case 192:case 193:case 194:i=!0;break;case 218:r=!0;break;default:}n=this.nextMarker()}return i&&r}readInfo(e){this._input=new Y({buffer:e,bigEndian:!0});let t=this.nextMarker();if(t!==216)return;let n=new ca,i=!1,r=!1;for(t=this.nextMarker();t!==217&&!this._input.isEOS;){switch(t){case 192:case 193:case 194:i=!0,this.readFrame(t,this.readBlock());break;case 218:r=!0,this.skipBlock();break;default:this.skipBlock();break}t=this.nextMarker()}return this._frame!==void 0&&(n.setSize(this._frame.samplesPerLine,this._frame.scanLines),this._frame=void 0),this.frames.length=0,i&&r?n:void 0}read(e){if(this._input=new Y({buffer:e,bigEndian:!0}),this.readMarkers(),this._frames.length!==1)throw new T("Only single frame JPEGs supported");if(this._frame!==void 0)for(let t=0;t0&&e[r-1]===0;)r--;i.push(new Kn);let a=i[0];for(let s=0;s0;)a=i.pop();for(a.incrementIndex(),i.push(a);i.length<=s;){let o=new Kn;i.push(o),a.children.length<=a.index&&(a.children.length=a.index+1),a.children[a.index]=new cn(o.children),a=o}n++}if(s+1>4;if(t&=15,t>=ni.numQuantizationTables)throw new T("Invalid number of quantization tables");this._quantizationTables[t]===void 0&&(this._quantizationTables[t]=new Int16Array(64));let i=this._quantizationTables[t];if(i!==void 0)for(let r=0;r>4&15,d=h&15,p=t.readByte();l.push(b);let g=new ua(c,d,this._quantizationTables,p);o.set(b,g)}this._frame=new la(o,l,n,i,r,a,s),this._frame.prepare(),this.frames.push(this._frame)}readDHT(e){for(;!e.isEOS;){let t=e.readByte(),n=new Uint8Array(16),i=0;for(let s=0;s<16;s++)n[s]=e.readByte(),i+=n[s];let r=e.readBytes(i).toUint8Array(),a=[];t&16?(t-=16,a=this._huffmanTablesAC):a=this._huffmanTablesDC,a.length<=t&&(a.length=t+1),a[t]=ni.buildHuffmanTable(n,r)}}readDRI(e){this._resetInterval=e.readUint16()}readSOS(e){let t=e.readByte();if(t<1||t>ni.maxCompsInScan)throw new T("Invalid SOS block");let n=new Array;for(let l=0;l>4&15,d=b&15;c>4&15,u=a&15;new ga(this._input,this._frame,n,i,r,s,u,this._resetInterval).decode()}},Me=ni;Me.dctZigZag=[0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63],Me.dctSize=8,Me.dctSize2=64,Me.numQuantizationTables=4,Me.numHuffmanTables=4,Me.numArithTables=16,Me.maxCompsInScan=4,Me.maxSamplingFactor=4});var Yi,Xi=A(()=>{"use strict";je();be();Wi();Yi=class{get numFrames(){return this._info!==void 0?this._info.numFrames:0}isValidFile(e){return new Me().validate(e)}startDecode(e){return this._input=new Y({buffer:e,bigEndian:!0}),this._info=new Me().readInfo(e),this._info}decodeFrame(e){if(this._input===void 0)return;let t=new Me;if(t.read(this._input.buffer),t.frames.length!==1)throw new T("Only single frame JPEGs supported.");return t.getImage()}decode(e,t){let n=new Me;if(n.read(e),n.frames.length!==1)throw new T("Only single frame JPEGs supported.");return n.getImage()}}});var J,zt,_a=A(()=>{"use strict";G();_e();At();Bn();J=class{constructor(e=100){this._tableY=new Uint8Array(64);this._tableUv=new Uint8Array(64);this._fdTableY=new Float32Array(64);this._fdTableUv=new Float32Array(64);this._bitCode=U.fill(65535,void 0);this._category=U.fill(65535,void 0);this._outputfDCTQuant=U.fill(64,void 0);this._du=U.fill(64,void 0);this._ydu=new Float32Array(64);this._udu=new Float32Array(64);this._vdu=new Float32Array(64);this._tableRgbYuv=new Int32Array(2048);this._byteNew=0;this._bytePos=7;this._supportsAnimation=!1;this.initHuffmanTable(),this.initCategoryNumber(),this.initRgbYuvTable(),this.setQuality(e)}get supportsAnimation(){return this._supportsAnimation}static computeHuffmanTable(e,t){let n=0,i=0,r=new Array;for(let a=1;a<=16;a++){for(let s=1;s<=e[a];s++){let u=t[i];r.length<=u&&(r.length=u+1),r[u]=[n,a],i++,n++}n*=2}return r}static writeMarker(e,t){e.writeByte(255),e.writeByte(t&255)}static writeAPP0(e){J.writeMarker(e,224),e.writeUint16(16),e.writeByte(74),e.writeByte(70),e.writeByte(73),e.writeByte(70),e.writeByte(0),e.writeByte(1),e.writeByte(1),e.writeByte(0),e.writeUint16(1),e.writeUint16(1),e.writeByte(0),e.writeByte(0)}static writeAPP1(e,t){if(t.isEmpty)return;let n=new Be;t.write(n);let i=n.getBytes();this.writeMarker(e,225);let r=1165519206;e.writeUint16(i.length+8),e.writeUint32(r),e.writeUint16(0),e.writeBytes(i)}static writeSOF0(e,t,n){J.writeMarker(e,192),e.writeUint16(17),e.writeByte(8),e.writeUint16(n),e.writeUint16(t),e.writeByte(3),e.writeByte(1),e.writeByte(17),e.writeByte(0),e.writeByte(2),e.writeByte(17),e.writeByte(1),e.writeByte(3),e.writeByte(17),e.writeByte(1)}static writeSOS(e){J.writeMarker(e,218),e.writeUint16(12),e.writeByte(3),e.writeByte(1),e.writeByte(0),e.writeByte(2),e.writeByte(17),e.writeByte(3),e.writeByte(17),e.writeByte(0),e.writeByte(63),e.writeByte(0)}static writeDHT(e){J.writeMarker(e,196),e.writeUint16(418),e.writeByte(0);for(let t=0;t<16;t++)e.writeByte(J._stdDcLuminanceNrCodes[t+1]);for(let t=0;t<=11;t++)e.writeByte(J._stdDcLuminanceValues[t]);e.writeByte(16);for(let t=0;t<16;t++)e.writeByte(J._stdAcLuminanceNrCodes[t+1]);for(let t=0;t<=161;t++)e.writeByte(J._stdAcLuminanceValues[t]);e.writeByte(1);for(let t=0;t<16;t++)e.writeByte(J._stdDcChrominanceNrCodes[t+1]);for(let t=0;t<=11;t++)e.writeByte(J._stdDcChrominanceValues[t]);e.writeByte(17);for(let t=0;t<16;t++)e.writeByte(J._stdAcChrominanceNrCodes[t+1]);for(let t=0;t<=161;t++)e.writeByte(J._stdAcChrominanceValues[t])}initHuffmanTable(){this._ydcHuffman=J.computeHuffmanTable(J._stdDcLuminanceNrCodes,J._stdDcLuminanceValues),this._uvdcHuffman=J.computeHuffmanTable(J._stdDcChrominanceNrCodes,J._stdDcChrominanceValues),this._yacHuffman=J.computeHuffmanTable(J._stdAcLuminanceNrCodes,J._stdAcLuminanceValues),this._uvacHuffman=J.computeHuffmanTable(J._stdAcChrominanceNrCodes,J._stdAcChrominanceValues)}initCategoryNumber(){let e=1,t=2;for(let n=1;n<=15;n++){for(let i=e;i255&&(s=255),this._tableY[J._zigzag[a]]=s}let n=[17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99];for(let a=0;a<64;a++){let s=Math.floor((n[a]*e+50)/100);s<1?s=1:s>255&&(s=255),this._tableUv[J._zigzag[a]]=s}let i=[1,1.387039845,1.306562965,1.175875602,1,.785694958,.5411961,.275899379],r=0;for(let a=0;a<8;a++)for(let s=0;s<8;s++)this._fdTableY[r]=1/(this._tableY[J._zigzag[r]]*i[a]*i[s]*8),this._fdTableUv[r]=1/(this._tableUv[J._zigzag[r]]*i[a]*i[s]*8),r++}fDCTQuant(e,t){let n=0;for(let i=0;i<8;++i){let r=e[n],a=e[n+1],s=e[n+2],u=e[n+3],o=e[n+4],l=e[n+5],m=e[n+6],b=e[n+7],h=r+b,c=r-b,d=a+m,p=a-m,g=s+l,x=s-l,y=u+o,C=u-o,I=h+y,P=h-y,F=d+g,M=d-g;e[n]=I+F,e[n+4]=I-F;let w=(M+P)*.707106781;e[n+2]=P+w,e[n+6]=P-w,I=C+x,F=x+p,M=p+c;let k=(I-M)*.382683433,B=.5411961*I+k,N=1.306562965*M+k,O=F*.707106781,V=c+O,E=c-O;e[n+5]=E+B,e[n+3]=E-B,e[n+1]=V+N,e[n+7]=V-N,n+=8}n=0;for(let i=0;i<8;++i){let r=e[n],a=e[n+8],s=e[n+16],u=e[n+24],o=e[n+32],l=e[n+40],m=e[n+48],b=e[n+56],h=r+b,c=r-b,d=a+m,p=a-m,g=s+l,x=s-l,y=u+o,C=u-o,I=h+y,P=h-y,F=d+g,M=d-g;e[n]=I+F,e[n+32]=I-F;let w=(M+P)*.707106781;e[n+16]=P+w,e[n+48]=P-w,I=C+x,F=x+p,M=p+c;let k=(I-M)*.382683433,B=.5411961*I+k,N=1.306562965*M+k,O=F*.707106781,V=c+O,E=c-O;e[n+40]=E+B,e[n+24]=E-B,e[n+8]=V+N,e[n+56]=V-N,n++}for(let i=0;i<64;++i){let r=e[i]*t[i];this._outputfDCTQuant[i]=r>0?Math.trunc(r+.5):Math.trunc(r-.5)}return this._outputfDCTQuant}writeDQT(e){J.writeMarker(e,219),e.writeUint16(132),e.writeByte(0);for(let t=0;t<64;t++)e.writeByte(this._tableY[t]);e.writeByte(1);for(let t=0;t<64;t++)e.writeByte(this._tableUv[t])}writeBits(e,t){let n=t[0],i=t[1]-1;for(;i>=0;)n&1<0&&this._du[p]===0;p--);if(p===0)return this.writeBits(e,s),h;let g=1;for(;g<=p;){let x=g;for(;this._du[g]===0&&g<=p;++g);let y=g-x;if(y>=o){let C=y>>4;for(let I=1;I<=C;++I)this.writeBits(e,u);y&=15}c=32767+this._du[g],this.writeBits(e,r[(y<<4)+this._category[c]]),this.writeBits(e,this._bitCode[c]),g++}return p!==l&&this.writeBits(e,s),h}encode(e,t=!1){let n=new Be({bigEndian:!0});J.writeMarker(n,216),J.writeAPP0(n),J.writeAPP1(n,e.exifData),this.writeDQT(n),J.writeSOF0(n,e.width,e.height),J.writeDHT(n),J.writeSOS(n);let i=0,r=0,a=0;this.resetBits();let s=e.width,u=e.height,o=0;for(;o>3,h=m&7,c=o+b,d=l+h;c>=u&&(c-=o+1+b-u),d>=s&&(d-=l+h-s+1);let p=e.getPixel(d,c),g=Math.trunc(p.r),x=Math.trunc(p.g),y=Math.trunc(p.b);this._ydu[m]=(this._tableRgbYuv[g]+this._tableRgbYuv[x+256]+this._tableRgbYuv[y+512]>>16)-128,this._udu[m]=(this._tableRgbYuv[g+768]+this._tableRgbYuv[x+1024]+this._tableRgbYuv[y+1280]>>16)-128,this._vdu[m]=(this._tableRgbYuv[g+1280]+this._tableRgbYuv[x+1536]+this._tableRgbYuv[y+1792]>>16)-128}i=this.processDU(n,this._ydu,this._fdTableY,i,this._yacHuffman,this._ydcHuffman),r=this.processDU(n,this._udu,this._fdTableUv,r,this._uvacHuffman,this._uvdcHuffman),a=this.processDU(n,this._vdu,this._fdTableUv,a,this._uvacHuffman,this._uvdcHuffman),l+=8}o+=8}if(this._bytePos>=0){let l=[(1<{"use strict";je();At();Tt();Bn();Za=class{readExifData(e){if(!(e===void 0||e.readUint32()!==Za._exifSignature)&&e.readUint16()===0)return Ie.fromInputBuffer(e)}writeAPP1(e,t){if(t.isEmpty)return;let n=new Be;t.write(n);let i=n.getBytes();e.writeUint16(i.length+8),e.writeUint32(Za._exifSignature),e.writeUint16(0),e.writeBytes(i)}readBlock(e){let t=e.readUint16();if(!(t<2))return e.readBytes(t-2)}skipBlock(e,t){let n=e.readUint16();return t==null||t.writeUint16(n),n<2?!1:(t!==void 0?t.writeBuffer(e.readBytes(n-2)):e.skip(n-2),!0)}nextMarker(e,t){let n=0;if(e.isEOS)return n;do{do n=e.readByte(),t==null||t.writeByte(n);while(n!==255&&!e.isEOS);if(e.isEOS)return n;do n=e.readByte(),t==null||t.writeByte(n);while(n===255&&!e.isEOS)}while(n===0&&!e.isEOS);return n}decodeExif(e){let t=new Y({buffer:e,bigEndian:!0}),n=t.peekBytes(2);if(n.getByte(0)!==255||n.getByte(1)!==216)return;let i=this.nextMarker(t);if(i!==216)return;let r;for(i=this.nextMarker(t);i!==217&&!t.isEOS;){switch(i){case 225:if(r=this.readExifData(this.readBlock(t)),r!==void 0)return r;break;default:this.skipBlock(t);break}i=this.nextMarker(t)}}injectExif(e,t){let n=new Y({buffer:t,bigEndian:!0}),i=n.peekBytes(2);if(i.getByte(0)!==255||i.getByte(1)!==216)return;let r=new Be({size:t.length,bigEndian:!0}),a=this.nextMarker(n,r);if(a!==216)return;let s=!1,u=n.offset;for(a=this.nextMarker(n);!s&&a!==217&&!n.isEOS;){if(a===225){let o=this.readBlock(n);if((o==null?void 0:o.readUint32())===Za._exifSignature){s=!0;break}}else this.skipBlock(n);a=this.nextMarker(n)}if(n.offset=u,!s)return this.writeAPP1(r,e),r.writeBuffer(n.readBytes(n.length)),r.getBytes();for(a=this.nextMarker(n,r);a!==217&&!n.isEOS;){if(a===225){let o=n.offset;n.skip(2);let l=n.readUint32();if(n.offset=o,l===Za._exifSignature)return this.skipBlock(n),this.writeAPP1(r,e),r.writeBuffer(n.readBytes(n.length)),r.getBytes()}this.skipBlock(n,r),a=this.nextMarker(n,r)}return r.getBytes()}},ya=Za;ya._exifSignature=1165519206});var ji=A(()=>{"use strict"});var Zi=A(()=>{"use strict"});var wa=A(()=>{"use strict";ji();Zi()});var va=A(()=>{"use strict"});var Qi=A(()=>{"use strict"});var Ia=A(()=>{"use strict";Qi()});var Pa=A(()=>{"use strict";je();It();Qi();Ia()});var Ma=A(()=>{"use strict";At()});var Os,Ki,Aa=A(()=>{"use strict";Os=class{constructor(e){this._bitBuffer=0;this._bitPosition=0;this._input=e}readBits(e){let t=e;if(t===0)return 0;this._bitPosition===0&&(this._bitPosition=8,this._bitBuffer=this._input.readByte());let n=0;for(;t>this._bitPosition;)n=(n<0&&(this._bitPosition===0&&(this._bitPosition=8,this._bitBuffer=this._input.readByte()),n=(n<>this._bitPosition-t&Os._bitMask[t]),this._bitPosition-=t),n}readByte(){return this.readBits(8)}flushByte(){return this._bitPosition=0}},Ki=Os;Ki._bitMask=[0,1,3,7,15,31,63,127,255]});var Ji=A(()=>{"use strict"});var Fa,Ba=A(()=>{"use strict";_n();xe();Nn();Dn();$n();Vn();Rn();Tn();Gn();Hn();qn();En();Fa=class{get tag(){return this._tag}get type(){return this._type}get count(){return this._count}get valueOffset(){return this._valueOffset}get value(){return this._value}get p(){return this._p}get isValid(){return this._type!==0}get typeSize(){return this.isValid?xn[this._type]:0}get isString(){return this._type===2}constructor(e){this._tag=e.tag,this._type=e.type,this._count=e.count,this._p=e.p,this._valueOffset=e.valueOffset}read(){if(this._value!==void 0)return this._value;this._p.offset=this._valueOffset;let e=this.p.readBytes(this._count*this.typeSize);switch(this._type){case 1:return this._value=Ze.data(e,this._count);case 2:return this._value=Ue.data(e,this._count);case 7:return this._value=Ze.data(e,this._count);case 3:return this._value=Qe.data(e,this._count);case 4:return this._value=Te.data(e,this._count);case 5:return this._value=Se.data(e,this._count);case 11:return this._value=Ct.data(e,this._count);case 12:return this._value=wt.data(e,this._count);case 6:return this._value=_t.data(e,this._count);case 8:return this._value=Qe.data(e,this._count);case 9:return this._value=yt.data(e,this._count);case 10:return this._value=Ge.data(e,this._count);default:case 0:return}}toString(){let e=On.get(this._tag);return e!==void 0?`${e.name}: ${this._type} ${this._count}`:`${this.constructor.name} (<${this._tag}>: ${this._type} ${this._count})`}}});var ce,We,Ua=A(()=>{"use strict";be();ce=class{constructor(e){this._changingElemSize=0;this._bitPointer=0;this._bytePointer=0;this._lastChangingElement=0;this._compression=2;this._uncompressedMode=0;this._fillBits=0;this._oneD=0;this._fillOrder=e.fillOrder,this._width=e.width,this._height=e.height,this._prevChangingElements=new Array(this._width),this._prevChangingElements.fill(0),this._currChangingElements=new Array(this._width),this._currChangingElements.fill(0)}get width(){return this._width}get height(){return this._height}get fillOrder(){return this._fillOrder}nextNBits(e){let t=0,n=0,i=0,r=this._data.length-1,a=this._bytePointer;if(this._fillOrder===1)t=this._data.getByte(a),a===r?(n=0,i=0):a+1===r?(n=this._data.getByte(a+1),i=0):(n=this._data.getByte(a+1),i=this._data.getByte(a+2));else if(this._fillOrder===2)t=ce._flipTable[this._data.getByte(a)&255],a===r?(n=0,i=0):a+1===r?(n=ce._flipTable[this._data.getByte(a+1)&255],i=0):(n=ce._flipTable[this._data.getByte(a+1)&255],i=ce._flipTable[this._data.getByte(a+2)&255]);else throw new T("TIFFFaxDecoder7");let s=8-this._bitPointer,u=e-s,o=0;u>8&&(o=u-8,u=8),this._bytePointer=this._bytePointer+1;let l=(t&ce._table1[s])<>8-u,b=0;return o!==0?(m<<=o,b=(i&ce._table2[o])>>8-o,m|=b,this._bytePointer+=1,this._bitPointer=o):u===8?(this._bitPointer=0,this._bytePointer+=1):this._bitPointer=u,l|m}nextLesserThan8Bits(e){let t=0,n=0,i=this._data.length-1,r=this._bytePointer;if(this._fillOrder===1)t=this._data.getByte(r),r===i?n=0:n=this._data.getByte(r+1);else if(this._fillOrder===2)t=ce._flipTable[this._data.getByte(r)&255],r===i?n=0:n=ce._flipTable[this._data.getByte(r+1)&255];else throw new T("TIFFFaxDecoder7");let a=8-this._bitPointer,s=e-a,u=a-e,o=0,l=0;return u>=0?(o=(t&ce._table1[a])>>u,this._bitPointer+=e,this._bitPointer===8&&(this._bitPointer=0,this._bytePointer+=1)):(o=(t&ce._table1[a])<<-u,l=(n&ce._table2[s])>>8-s,o|=l,this._bytePointer+=1,this._bitPointer=s),o}updatePointer(e){let t=this._bitPointer-e;t<0?(this._bytePointer-=1,this._bitPointer=8+t):this._bitPointer=t}advancePointer(){return this._bitPointer!==0&&(this._bytePointer+=1,this._bitPointer=0),!0}setToBlack(e,t,n,i){let r=8*t+n,a=r+i,s=r>>3,u=r&7;if(u>0){let o=1<<7-u,l=e.getByte(s);for(;o>0&&r>=1,++r;e.setByte(s,l)}for(s=r>>3;r>3,e.setByte(s,e.getByte(s)|1<<7-(r&7)),++r}decodeNextScanline(e,t,n){let i=n,r=0,a=0,s=0,u=0,o=0,l=0,m=!0;for(this._changingElemSize=0;i>1&15,r===12)l=this.nextLesserThan8Bits(2),u=u<<2&12|l,o=ce._additionalMakeup[u],r=o>>1&7,a=o>>4&4095,i+=a,this.updatePointer(4-r);else{if(r===0)throw new T("TIFFFaxDecoder0");if(r===15)throw new T("TIFFFaxDecoder1");a=o>>5&2047,i+=a,this.updatePointer(10-r),s===0&&(m=!1,this._currChangingElements[this._changingElemSize++]=i)}if(i===this._width){this._compression===2&&this.advancePointer();break}for(;m===!1;)if(u=this.nextLesserThan8Bits(4),o=ce._initBlack[u],s=o&1,r=o>>1&15,a=o>>5&2047,a===100)if(u=this.nextNBits(9),o=ce._black[u],s=o&1,r=o>>1&15,a=o>>5&2047,r===12)this.updatePointer(5),u=this.nextLesserThan8Bits(4),o=ce._additionalMakeup[u],r=o>>1&7,a=o>>4&4095,this.setToBlack(e,t,i,a),i+=a,this.updatePointer(4-r);else{if(r===15)throw new T("TIFFFaxDecoder2");this.setToBlack(e,t,i,a),i+=a,this.updatePointer(9-r),s===0&&(m=!0,this._currChangingElements[this._changingElemSize++]=i)}else a===200?(u=this.nextLesserThan8Bits(2),o=ce._twoBitBlack[u],a=o>>5&2047,r=o>>1&15,this.setToBlack(e,t,i,a),i+=a,this.updatePointer(2-r),m=!0,this._currChangingElements[this._changingElemSize++]=i):(this.setToBlack(e,t,i,a),i+=a,this.updatePointer(4-r),m=!0,this._currChangingElements[this._changingElemSize++]=i);if(i===this._width){this._compression===2&&this.advancePointer();break}}this._currChangingElements[this._changingElemSize++]=i}readEOL(){if(this._fillBits===0){if(this.nextNBits(12)!==1)throw new T("TIFFFaxDecoder6")}else if(this._fillBits===1){let e=8-this._bitPointer;if(this.nextNBits(e)!==0)throw new T("TIFFFaxDecoder8");if(e<4&&this.nextNBits(8)!==0)throw new T("TIFFFaxDecoder8");let t=0;for(;(t=this.nextNBits(8))!==1;)if(t!==0)throw new T("TIFFFaxDecoder8")}return this._oneD===0?1:this.nextLesserThan8Bits(1)}getNextChangingElement(e,t,n){let i=this._prevChangingElements,r=this._changingElemSize,a=this._lastChangingElement>0?this._lastChangingElement-1:0;t?a&=-2:a|=1;let s=a;for(;se){this._lastChangingElement=s,n[0]=u;break}}s+1>1&15,n===12)r=this.nextLesserThan8Bits(2),e=e<<2&12|r,t=ce._additionalMakeup[e],n=t>>1&7,a=t>>4&4095,s+=a,this.updatePointer(4-n);else{if(n===0)throw new T("TIFFFaxDecoder0");if(n===15)throw new T("TIFFFaxDecoder1");a=t>>5&2047,s+=a,this.updatePointer(10-n),i===0&&(u=!1)}return s}decodeBlackCodeWord(){let e=0,t=0,n=0,i=0,r=-1,a=0,s=!1;for(;!s;)if(e=this.nextLesserThan8Bits(4),t=ce._initBlack[e],i=t&1,n=t>>1&15,r=t>>5&2047,r===100)if(e=this.nextNBits(9),t=ce._black[e],i=t&1,n=t>>1&15,r=t>>5&2047,n===12)this.updatePointer(5),e=this.nextLesserThan8Bits(4),t=ce._additionalMakeup[e],n=t>>1&7,r=t>>4&4095,a+=r,this.updatePointer(4-n);else{if(n===15)throw new T("TIFFFaxDecoder2");a+=r,this.updatePointer(9-n),i===0&&(s=!0)}else r===200?(e=this.nextLesserThan8Bits(2),t=ce._twoBitBlack[e],r=t>>5&2047,a+=r,n=t>>1&15,this.updatePointer(2-n),s=!0):(a+=r,this.updatePointer(4-n),s=!0);return a}decode1D(e,t,n,i){this._data=t,this._bitPointer=0,this._bytePointer=0;let r=0,a=Math.trunc((this._width+7)/8);for(let s=0;s>1,this._fillBits=(r&4)>>2,this.readEOL()!==1)throw new T("TIFFFaxDecoder3");let p=0,g=0;this.decodeNextScanline(e,p,n),p+=a;for(let x=1;x>3,m=o&7,l===0)b||this.setToBlack(e,p,g,C-g),s=C,g=s,this.updatePointer(7-m);else if(l===1){this.updatePointer(7-m);let I=0;b?(I=this.decodeWhiteCodeWord(),g+=I,this._currChangingElements[h++]=g,I=this.decodeBlackCodeWord(),this.setToBlack(e,p,g,I),g+=I,this._currChangingElements[h++]=g):(I=this.decodeBlackCodeWord(),this.setToBlack(e,p,g,I),g+=I,this._currChangingElements[h++]=g,I=this.decodeWhiteCodeWord(),g+=I,this._currChangingElements[h++]=g),s=g}else if(l<=8)u=y+(l-5),this._currChangingElements[h++]=u,b||this.setToBlack(e,p,g,u-g),s=u,g=s,b=!b,this.updatePointer(7-m);else throw new T("TIFFFaxDecoder4")}this._currChangingElements[h++]=g,this._changingElemSize=h}else this.decodeNextScanline(e,p,n);p+=a}}decodeT6(e,t,n,i,r){this._data=t,this._compression=4,this._bitPointer=0,this._bytePointer=0;let a=Math.trunc((this._width+7)/8),s=0,u=0,o=0,l=0,m=0,b=0,h=0,c=!1,d=0,p,g=new Array(2);g.fill(0),this._uncompressedMode=(r&2)>>1;let x=this._currChangingElements;this._changingElemSize=0,x[this._changingElemSize++]=this._width,x[this._changingElemSize++]=this._width;let y=0,C=0;for(let I=0;I>3,h=m&7,b===0)c||this.setToBlack(e,y,C,l-C),s=l,C=s,this.updatePointer(7-h);else if(b===1){this.updatePointer(7-h);let P=0;c?(P=this.decodeWhiteCodeWord(),C+=P,x[d++]=C,P=this.decodeBlackCodeWord(),this.setToBlack(e,y,C,P),C+=P,x[d++]=C):(P=this.decodeBlackCodeWord(),this.setToBlack(e,y,C,P),C+=P,x[d++]=C,P=this.decodeWhiteCodeWord(),C+=P,x[d++]=C),s=C}else if(b<=8)u=o+(b-5),x[d++]=u,c||this.setToBlack(e,y,C,u-C),s=u,C=s,c=!c,this.updatePointer(7-h);else if(b===11){if(this.nextLesserThan8Bits(3)!==7)throw new T("TIFFFaxDecoder5");let P=0,F=!1;for(;!F;){for(;this.nextLesserThan8Bits(1)!==1;)P++;P>5&&(P-=6,!c&&P>0&&(x[d++]=C),C+=P,P>0&&(c=!0),this.nextLesserThan8Bits(1)===0?(c||(x[d++]=C),c=!0):(c&&(x[d++]=C),c=!1),F=!0),P===5?(c||(x[d++]=C),C+=P,c=!0):(C+=P,x[d++]=C,this.setToBlack(e,y,C,1),++C,c=!1)}}else throw new T(`TIFFFaxDecoder5 ${b}`);x[d++]=C,this._changingElemSize=d,y+=a}}},We=ce;We._table1=[0,1,3,7,15,31,63,127,255],We._table2=[0,128,192,224,240,248,252,254,255],We._flipTable=[0,-128,64,-64,32,-96,96,-32,16,-112,80,-48,48,-80,112,-16,8,-120,72,-56,40,-88,104,-24,24,-104,88,-40,56,-72,120,-8,4,-124,68,-60,36,-92,100,-28,20,-108,84,-44,52,-76,116,-12,12,-116,76,-52,44,-84,108,-20,28,-100,92,-36,60,-68,124,-4,2,-126,66,-62,34,-94,98,-30,18,-110,82,-46,50,-78,114,-14,10,-118,74,-54,42,-86,106,-22,26,-102,90,-38,58,-70,122,-6,6,-122,70,-58,38,-90,102,-26,22,-106,86,-42,54,-74,118,-10,14,-114,78,-50,46,-82,110,-18,30,-98,94,-34,62,-66,126,-2,1,-127,65,-63,33,-95,97,-31,17,-111,81,-47,49,-79,113,-15,9,-119,73,-55,41,-87,105,-23,25,-103,89,-39,57,-71,121,-7,5,-123,69,-59,37,-91,101,-27,21,-107,85,-43,53,-75,117,-11,13,-115,77,-51,45,-83,109,-19,29,-99,93,-35,61,-67,125,-3,3,-125,67,-61,35,-93,99,-29,19,-109,83,-45,51,-77,115,-13,11,-117,75,-53,43,-85,107,-21,27,-101,91,-37,59,-69,123,-5,7,-121,71,-57,39,-89,103,-25,23,-105,87,-41,55,-73,119,-9,15,-113,79,-49,47,-81,111,-17,31,-97,95,-33,63,-65,127,-1],We._white=[6430,6400,6400,6400,3225,3225,3225,3225,944,944,944,944,976,976,976,976,1456,1456,1456,1456,1488,1488,1488,1488,718,718,718,718,718,718,718,718,750,750,750,750,750,750,750,750,1520,1520,1520,1520,1552,1552,1552,1552,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,654,654,654,654,654,654,654,654,1072,1072,1072,1072,1104,1104,1104,1104,1136,1136,1136,1136,1168,1168,1168,1168,1200,1200,1200,1200,1232,1232,1232,1232,622,622,622,622,622,622,622,622,1008,1008,1008,1008,1040,1040,1040,1040,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,1712,1712,1712,1712,1744,1744,1744,1744,846,846,846,846,846,846,846,846,1264,1264,1264,1264,1296,1296,1296,1296,1328,1328,1328,1328,1360,1360,1360,1360,1392,1392,1392,1392,1424,1424,1424,1424,686,686,686,686,686,686,686,686,910,910,910,910,910,910,910,910,1968,1968,1968,1968,2e3,2e3,2e3,2e3,2032,2032,2032,2032,16,16,16,16,10257,10257,10257,10257,12305,12305,12305,12305,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,878,878,878,878,878,878,878,878,1904,1904,1904,1904,1936,1936,1936,1936,-18413,-18413,-16365,-16365,-14317,-14317,-10221,-10221,590,590,590,590,590,590,590,590,782,782,782,782,782,782,782,782,1584,1584,1584,1584,1616,1616,1616,1616,1648,1648,1648,1648,1680,1680,1680,1680,814,814,814,814,814,814,814,814,1776,1776,1776,1776,1808,1808,1808,1808,1840,1840,1840,1840,1872,1872,1872,1872,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,6157,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,-12275,14353,14353,14353,14353,16401,16401,16401,16401,22547,22547,24595,24595,20497,20497,20497,20497,18449,18449,18449,18449,26643,26643,28691,28691,30739,30739,-32749,-32749,-30701,-30701,-28653,-28653,-26605,-26605,-24557,-24557,-22509,-22509,-20461,-20461,8207,8207,8207,8207,8207,8207,8207,8207,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,4107,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,2059,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232],We._additionalMakeup=[28679,28679,31752,-32759,-31735,-30711,-29687,-28663,29703,29703,30727,30727,-27639,-26615,-25591,-24567],We._initBlack=[3226,6412,200,168,38,38,134,134,100,100,100,100,68,68,68,68],We._twoBitBlack=[292,260,226,226],We._black=[62,62,30,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,3225,588,588,588,588,588,588,588,588,1680,1680,20499,22547,24595,26643,1776,1776,1808,1808,-24557,-22509,-20461,-18413,1904,1904,1936,1936,-16365,-14317,782,782,782,782,814,814,814,814,-12269,-10221,10257,10257,12305,12305,14353,14353,16403,18451,1712,1712,1744,1744,28691,30739,-32749,-30701,-28653,-26605,2061,2061,2061,2061,2061,2061,2061,2061,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,750,750,750,750,1616,1616,1648,1648,1424,1424,1456,1456,1488,1488,1520,1520,1840,1840,1872,1872,1968,1968,8209,8209,524,524,524,524,524,524,524,524,556,556,556,556,556,556,556,556,1552,1552,1584,1584,2e3,2e3,2032,2032,976,976,1008,1008,1040,1040,1072,1072,1296,1296,1328,1328,718,718,718,718,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,4113,4113,6161,6161,848,848,880,880,912,912,944,944,622,622,622,622,654,654,654,654,1104,1104,1136,1136,1168,1168,1200,1200,1232,1232,1264,1264,686,686,686,686,1360,1360,1392,1392,12,12,12,12,12,12,12,12,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390],We._twoDCodes=[80,88,23,71,30,30,62,62,4,4,4,4,4,4,4,4,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41]});var er=A(()=>{"use strict"});var Sa=A(()=>{"use strict"});var ka,bn,za=A(()=>{"use strict";be();ka=class{constructor(){this._buffer=new Uint8Array(4096);this._bitsToGet=9;this._bytePointer=0;this._nextData=0;this._nextBits=0}addString(e,t){this._table[this._tableIndex]=t,this._prefix[this._tableIndex]=e,this._tableIndex=this._tableIndex+1,this._tableIndex===511?this._bitsToGet=10:this._tableIndex===1023?this._bitsToGet=11:this._tableIndex===2047&&(this._bitsToGet=12)}getString(e){this._bufferLength=0;let t=e;for(this._buffer[this._bufferLength++]=this._table[t],t=this._prefix[t];t!==ka._noSuchCode;)this._buffer[this._bufferLength++]=this._table[t],t=this._prefix[t]}getNextCode(){if(this._bytePointer>=this._dataLength)return 257;for(;this._nextBits=this._dataLength)return 257;this._nextData=(this._nextData<<8)+this._data[this._bytePointer++]&4294967295,this._nextBits+=8}return this._nextBits-=this._bitsToGet,this._nextData>>this._nextBits&ka._andTable[this._bitsToGet-9]}initializeStringTable(){this._table=new Uint8Array(ka._lzMaxCode+1),this._prefix=new Uint32Array(ka._lzMaxCode+1),this._prefix.fill(ka._noSuchCode,0,this._prefix.length);for(let e=0;e<256;e++)this._table[e]=e;this._bitsToGet=9,this._tableIndex=258}decode(e,t){this._out=t;let n=t.length;if(this._outPointer=0,this._data=e.buffer,this._dataLength=this._data.length,this._bytePointer=e.offset,this._data[0]===0&&this._data[1]===1)throw new T("Invalid LZW Data");this.initializeStringTable(),this._nextData=0,this._nextBits=0;let i=0,r=this.getNextCode();for(;r!==257&&this._outPointer=0;--a)this._out[this._outPointer++]=this._buffer[a];this.addString(i,this._buffer[this._bufferLength-1]),i=r}else{this.getString(i);for(let a=this._bufferLength-1;a>=0;--a)this._out[this._outPointer++]=this._buffer[a];this._out[this._outPointer++]=this._buffer[this._bufferLength-1],this.addString(i,this._buffer[this._bufferLength-1]),i=r}r=this.getNextCode()}}},bn=ka;bn._lzMaxCode=4095,bn._noSuchCode=4098,bn._andTable=[511,1023,2047,4095]});var tr=A(()=>{"use strict"});var gs,Oa,Na=A(()=>{"use strict";gs=ws(ps());ae();H();G();Jt();un();je();be();_n();xe();It();Xi();Aa();Ji();Ba();Ua();er();Sa();za();tr();Oa=class{constructor(e){this._tags=new Map;this._width=0;this._height=0;this._photometricType=16;this._compression=1;this._bitsPerSample=1;this._samplesPerPixel=1;this._sampleFormat=1;this._imageType=9;this._isWhiteZero=!1;this._predictor=1;this._chromaSubH=0;this._chromaSubV=0;this._tiled=!1;this._tileWidth=0;this._tileHeight=0;this._tilesX=0;this._tilesY=0;this._fillOrder=1;this._t4Options=0;this._t6Options=0;this._colorMapSamples=0;this._colorMapRed=0;this._colorMapGreen=0;this._colorMapBlue=0;var i,r,a,s,u,o,l,m,b,h,c,d,p,g;let t=Y.from(e),n=e.readUint16();for(let x=0;x4?M=e.readUint32():(M=e.offset,e.skip(4));let w=new Fa({tag:y,type:I,count:F,p:t,valueOffset:M});if(this._tags.set(w.tag,w),y===ne.get("ImageWidth"))this._width=(r=(i=w.read())==null?void 0:i.toInt())!=null?r:0;else if(y===ne.get("ImageLength"))this._height=(s=(a=w.read())==null?void 0:a.toInt())!=null?s:0;else if(y===ne.get("PhotometricInterpretation")){let k=w.read();if(k===void 0)this._photometricType=16;else{let B=k.toInt();B<17?this._photometricType=B:this._photometricType=16}}else if(y===ne.get("Compression"))this._compression=(o=(u=w.read())==null?void 0:u.toInt())!=null?o:0;else if(y===ne.get("BitsPerSample"))this._bitsPerSample=(m=(l=w.read())==null?void 0:l.toInt())!=null?m:0;else if(y===ne.get("SamplesPerPixel"))this._samplesPerPixel=(h=(b=w.read())==null?void 0:b.toInt())!=null?h:0;else if(y===ne.get("Predictor"))this._predictor=(d=(c=w.read())==null?void 0:c.toInt())!=null?d:0;else if(y===ne.get("SampleFormat")){let k=(g=(p=w.read())==null?void 0:p.toInt())!=null?g:0;this._sampleFormat=k}else if(y===ne.get("ColorMap")){let k=w.read();k!==void 0&&(this._colorMap=new Uint16Array(k.toData().buffer),this._colorMapRed=0,this._colorMapGreen=Math.trunc(this._colorMap.length/3),this._colorMapBlue=this._colorMapGreen*2)}}if(this._colorMap!==void 0&&this._photometricType===3&&(this._colorMapSamples=3,this._samplesPerPixel=1),!(this._width===0||this._height===0)){if(this._colorMap!==void 0&&this._bitsPerSample===8){let x=this._colorMap,y=x.length;for(let C=0;C>=8}if(this._photometricType===0&&(this._isWhiteZero=!0),this.hasTag(ne.get("TileOffsets")))this._tiled=!0,this._tileWidth=this.readTag(ne.get("TileWidth")),this._tileHeight=this.readTag(ne.get("TileLength")),this._tileOffsets=this.readTagList(ne.get("TileOffsets")),this._tileByteCounts=this.readTagList(ne.get("TileByteCounts"));else{if(this._tiled=!1,this._tileWidth=this.readTag(ne.get("TileWidth"),this._width),!this.hasTag(ne.get("RowsPerStrip")))this._tileHeight=this.readTag(ne.get("TileLength"),this._height);else{let x=this.readTag(ne.get("RowsPerStrip")),y=1;y=(y<<32)-1,x===y?this._tileHeight=this._height:this._tileHeight=x}this._tileOffsets=this.readTagList(ne.get("StripOffsets")),this._tileByteCounts=this.readTagList(ne.get("StripByteCounts"))}switch(this._tilesX=Math.trunc((this._width+this._tileWidth-1)/this._tileWidth),this._tilesY=Math.trunc((this._height+this._tileHeight-1)/this._tileHeight),this._tileSize=this._tileWidth*this._tileHeight*this._samplesPerPixel,this._fillOrder=this.readTag(ne.get("FillOrder"),1),this._t4Options=this.readTag(ne.get("T4Options")),this._t6Options=this.readTag(ne.get("T6Options")),this._extraSamples=this.readTag(ne.get("ExtraSamples")),this._photometricType){case 0:case 1:this._bitsPerSample===1&&this._samplesPerPixel===1?this._imageType=0:this._bitsPerSample===4&&this._samplesPerPixel===1?this._imageType=1:this._bitsPerSample%8===0&&(this._samplesPerPixel===1?this._imageType=2:this._samplesPerPixel===2?this._imageType=3:this._imageType=8);break;case 2:this._bitsPerSample%8===0&&(this._samplesPerPixel===3?this._imageType=5:this._samplesPerPixel===4?this._imageType=6:this._imageType=8);break;case 3:this._samplesPerPixel===1&&this._colorMap!==void 0&&(this._bitsPerSample===4||this._bitsPerSample===8||this._bitsPerSample===16)&&(this._imageType=4);break;case 4:this._bitsPerSample===1&&this._samplesPerPixel===1&&(this._imageType=0);break;case 6:if(this._compression===7&&this._bitsPerSample===8&&this._samplesPerPixel===3)this._imageType=5;else{if(this.hasTag(ne.get("YCbCrSubSampling"))){let x=ne.get("YCbCrSubSampling"),y=this._tags.get(x).read();this._chromaSubH=y.toInt(),this._chromaSubV=y.toInt(1)}else this._chromaSubH=2,this._chromaSubV=2;this._chromaSubH*this._chromaSubV===1?this._imageType=8:this._bitsPerSample===8&&this._samplesPerPixel===3&&(this._imageType=7)}break;default:this._bitsPerSample%8===0&&(this._imageType=8);break}}}get tags(){return this._tags}get width(){return this._width}get height(){return this._height}get photometricType(){return this._photometricType}get compression(){return this._compression}get bitsPerSample(){return this._bitsPerSample}get samplesPerPixel(){return this._samplesPerPixel}get sampleFormat(){return this._sampleFormat}get imageType(){return this._imageType}get isWhiteZero(){return this._isWhiteZero}get predictor(){return this._predictor}get chromaSubH(){return this._chromaSubH}get chromaSubV(){return this._chromaSubV}get tiled(){return this._tiled}get tileWidth(){return this._tileWidth}get tileHeight(){return this._tileHeight}get tileOffsets(){return this._tileOffsets}get tileByteCounts(){return this._tileByteCounts}get tilesX(){return this._tilesX}get tilesY(){return this._tilesY}get tileSize(){return this._tileSize}get fillOrder(){return this._fillOrder}get t4Options(){return this._t4Options}get t6Options(){return this._t6Options}get extraSamples(){return this._extraSamples}get colorMapSamples(){return this._colorMapSamples}get colorMap(){return this._colorMap}get isValid(){return this._width!==0&&this._height!==0}readTag(e,t=0){var n,i;return this.hasTag(e)?(i=(n=this._tags.get(e).read())==null?void 0:n.toInt())!=null?i:0:t}readTagList(e){if(!this.hasTag(e))return;let t=this._tags.get(e),n=t.read();return U.generate(t.count,i=>n.toInt(i))}decodeBilevelTile(e,t,n,i){let r=i*this._tilesX+n;e.offset=this._tileOffsets[r];let a=n*this._tileWidth,s=i*this._tileHeight,u=this._tileByteCounts[r],o;if(this._compression===32773){let c=0;this._tileWidth%8===0?c=Math.trunc(this._tileWidth/8)*this._tileHeight:c=(Math.trunc(this._tileWidth/8)+1)*this._tileHeight,o=new Y({buffer:new Uint8Array(this._tileWidth*this._tileHeight)}),this.decodePackBits(e,c,o.buffer)}else if(this._compression===5){if(o=new Y({buffer:new Uint8Array(this._tileWidth*this._tileHeight)}),new bn().decode(Y.from(e,0,u),o.buffer),this._predictor===2){let d=0;for(let p=0;p=t.height||g>=t.width);++p,++g)l.readBits(1)===0?t.setPixelRgb(g,d,b,0,0):t.setPixelRgb(g,d,h,0,0);l.flushByte()}}decodeTile(e,t,n,i){if(this._imageType===0){this.decodeBilevelTile(e,t,n,i);return}let r=i*this._tilesX+n;e.offset=this._tileOffsets[r];let a=n*this._tileWidth,s=i*this._tileHeight,u=this._tileByteCounts[r],o=this._tileWidth*this._tileHeight*this._samplesPerPixel;this._bitsPerSample===16?o*=2:this._bitsPerSample===32&&(o*=4);let l;if(this._bitsPerSample===8||this._bitsPerSample===16||this._bitsPerSample===32||this._bitsPerSample===64){if(this._compression===1)l=e;else if(this._compression===5){l=new Y({buffer:new Uint8Array(o)});let m=new bn;try{m.decode(Y.from(e,0,u),l.buffer)}catch(b){}if(this._predictor===2){let b=0;for(let h=0;h=4)if(this._sampleFormat===3){let d=0,p=0,g=0,x=0;this._bitsPerSample===32?(d=l.readFloat32(),p=l.readFloat32(),g=l.readFloat32(),x=l.readFloat32()):this._bitsPerSample===64?(d=l.readFloat64(),p=l.readFloat64(),g=l.readFloat64(),x=l.readFloat64()):this._bitsPerSample===16&&(d=R.float16ToDouble(l.readUint16()),p=R.float16ToDouble(l.readUint16()),g=R.float16ToDouble(l.readUint16()),x=R.float16ToDouble(l.readUint16())),t.setPixelRgba(c,b,d,p,g,x)}else{let d=0,p=0,g=0,x=0;if(this._bitsPerSample===8?(d=this._sampleFormat===2?l.readInt8():l.readByte(),p=this._sampleFormat===2?l.readInt8():l.readByte(),g=this._sampleFormat===2?l.readInt8():l.readByte(),x=this._sampleFormat===2?l.readInt8():l.readByte()):this._bitsPerSample===16?(d=this._sampleFormat===2?l.readInt16():l.readUint16(),p=this._sampleFormat===2?l.readInt16():l.readUint16(),g=this._sampleFormat===2?l.readInt16():l.readUint16(),x=this._sampleFormat===2?l.readInt16():l.readUint16()):this._bitsPerSample===32&&(d=this._sampleFormat===2?l.readInt32():l.readUint32(),p=this._sampleFormat===2?l.readInt32():l.readUint32(),g=this._sampleFormat===2?l.readInt32():l.readUint32(),x=this._sampleFormat===2?l.readInt32():l.readUint32()),this._photometricType===5){let y=z.cmykToRgb(d,p,g,x);d=y[0],p=y[1],g=y[2],x=Math.trunc(t.maxChannelValue)}t.setPixelRgba(c,b,d,p,g,x)}}else throw new T(`Unsupported bitsPerSample: ${this._bitsPerSample}`)}jpegToImage(e,t,n,i,r,a){let s=r,u=a;for(let o=0;o=0&&a<=127)for(let s=0;s=-127){let s=e.getByte(i++);for(let u=0;u<-a+1;++u)n[r++]=s}else i++}}decode(e){let t=this._sampleFormat===3,n=this._sampleFormat===2,i=this._bitsPerSample===1?0:this._bitsPerSample===2?1:this._bitsPerSample===4?2:t&&this._bitsPerSample===16?9:t&&this._bitsPerSample===32?10:t&&this._bitsPerSample===64?11:n&&this._bitsPerSample===8?6:n&&this._bitsPerSample===16?7:n&&this._bitsPerSample===32?8:this._bitsPerSample===16?4:this._bitsPerSample===32?5:3,r=this._colorMap!==void 0&&this._photometricType===3,a=r?3:this._samplesPerPixel,s=new Q({width:this._width,height:this._height,format:i,numChannels:a,withPalette:r});if(r){let u=s.palette,o=this._colorMap,l=3,m=Math.trunc(o.length/l);for(let b=0;b{"use strict";Ra=class{constructor(e){this._images=[];this._width=0;this._height=0;this._backgroundColor=void 0;this._bigEndian=e.bigEndian,this._signature=e.signature,this._ifdOffset=e.ifdOffset,this._images=e.images,this._images.length>0&&(this._width=this._images[0].width,this._height=this._images[0].height)}get bigEndian(){return this._bigEndian}get signature(){return this._signature}get ifdOffset(){return this._ifdOffset}get images(){return this._images}get width(){return this._width}get height(){return this._height}get backgroundColor(){throw this._backgroundColor}get numFrames(){return this._images.length}}});var Qa,ii,Va=A(()=>{"use strict";je();Tt();Yn();Na();Da();Qa=class{constructor(){this._info=void 0;this._exifData=void 0}get info(){return this._info}get exifData(){return this._exifData}get numFrames(){return this._info!==void 0?this._info.images.length:0}readHeader(e){let t=e.readUint16();if(t!==Qa._tiffLittleEndian&&t!==Qa._tiffBigEndian)return;let n=!1;t===Qa._tiffBigEndian?(e.bigEndian=!0,n=!0):(e.bigEndian=!1,n=!1);let i=0;if(i=e.readUint16(),i!==Qa._tiffSignature)return;let r=e.readUint32(),a=r,s=Y.from(e);s.offset=r;let u=[];for(;r!==0;){let o;try{if(o=new Oa(s),!o.isValid)break}catch(l){break}u.push(o),r=s.readUint32(),r!==0&&(s.offset=r)}return u.length>0?new Ra({bigEndian:n,signature:i,ifdOffset:a,images:u}):void 0}isValidFile(e){let t=new Y({buffer:e});return this.readHeader(t)!==void 0}startDecode(e){if(this._input=new Y({buffer:e}),this._info=this.readHeader(this._input),this.info!==void 0){let t=new Y({buffer:e});this._exifData=Ie.fromInputBuffer(t)}return this._info}decodeFrame(e){if(this._info===void 0)return;let t=this._info.images[e].decode(this._input);return this._exifData!==void 0&&(t.exifData=this._exifData),t}decode(e,t){if(this._input=new Y({buffer:e}),this._info=this.readHeader(this._input),this._info===void 0)return;let n=this.numFrames;if(n===1||t!==void 0)return this.decodeFrame(t!=null?t:0);let i=this.decodeFrame(0);if(i!==void 0){i.exifData=Ie.fromInputBuffer(new Y({buffer:e})),i.frameType=1;for(let r=1;r{"use strict";H();At();be();Tt();Ln();Ji();er();tr()});var nr=A(()=>{"use strict"});var wu,La=A(()=>{"use strict";wu=ws(ps());G();nr()});var xs=A(()=>{"use strict"});var _s=A(()=>{"use strict"});var ys=A(()=>{"use strict"});var Ea=A(()=>{"use strict"});var Ha=A(()=>{"use strict"});var qa=A(()=>{"use strict"});var Ka=A(()=>{"use strict";be();gn();Sn();_e();Tt();It();xi();Ea();Ha();gi();zn();kn();qa()});var Cs=A(()=>{"use strict";Ti();Hr();Xr();Zr();Ga();na();Xi();_a();ir();Hi();Pa();Ma();Va();Ta();Qn();Wn();Ca();De();oe();fi();ri();ai();oi();si();ui();dn();pn();li();hi();bi();en();mi();ci();H();G();Jt();pi();un();je();Sn();sr();_e();At();gn();ur();sn();gi();nn();kn();or();zn();be();Nn();Dn();$n();Vn();Rn();Tn();_i();Gn();Hn();qn();En();Ln();Ve();Tt();mr();_n();Ci();yi();xe();Wn();Er();Rr();Dr();Vr();Lr();Di();Fn();Vi();Li();$r();Yr();Qr();Kr();ea();Jr();qi();Gi();$i();sa();ra();oa();Wi();ma();ha();ba();da();Bn();pa();xa();Ca();ji();Ei();Zi();Qn();wa();va();Qi();Ia();Aa();Ji();Ba();Ua();er();Sa();Na();Da();za();tr();Ti();Hr();qr();Xr();Zr();Ga();na();Xi();_a();ir();Hi();Pa();Ma();Va();Ta();ta();Yn();Or();La();nr();wi();vi();Ii();Ai();Pi();Mi();Fi();Ui();ki();Xn();Bi();Si();xi();It();jn();Nr();Ri();vr();Ir();Pr();Fr();Mr();Ar();Xt();Br();zi();hr();cr();br();pr();fr();dr();gr();_r();Cr();wr();xr();yr();Ur();$e();kr();jr();Ea();Ka();qa();Ha()});var ps=ku((a3,gu)=>{De();oe();fi();ri();ai();si();ui();oi();dn();pn();li();mi();hi();ci();bi();en();ae();ts();H();G();Jt();pi();un();je();Sn();sr();_e();At();gn();ur();sn();gi();nn();is();kn();or();zn();be();Tt();mr();_n();Ci();yi();xe();Nn();Dn();$n();Vn();Rn();Tn();_i();Gn();Hn();qn();En();Ln();Ve();Wn();Er();Rr();Dr();Vr();Lr();Ti();Hr();Di();Fn();Vi();cs();bs();qr();fs();Xr();Zr();Li();$r();Yr();Ga();na();Qr();Kr();ea();Jr();Xi();_a();qi();Gi();$i();sa();ra();oa();Wi();ma();ha();ba();da();Bn();pa();xa();Ca();ir();Hi();ji();Ei();Zi();Qn();wa();va();Pa();Ma();Qi();Ia();Va();Ta();Aa();Ji();Ba();Ua();er();Sa();Na();Da();za();tr();ta();Yn();Or();nr();La();wi();vi();Ii();Pi();Mi();Ai();Fi();Bi();Ui();Si();ki();Xn();xs();xi();It();jn();Nr();Ri();vr();Ir();Pr();Mr();Ar();Fr();Br();zi();Xt();_s();hr();cr();br();fr();dr();pr();$e();gr();xr();_r();yr();Cr();wr();Ur();kr();jr();ys();Cs();Ea();Ka();qa();Ha();var S={};typeof gu=="object"&&(gu.exports=S);S.parse=function(f,e){for(var t=S.bin.readUshort,n=S.bin.readUint,s=0,i={},r=new Uint8Array(f),a=r.length-4;n(r,a)!=101010256;)a--;var s=a;s+=4,s+=4;var u=t(r,s);s+=2;var o=t(r,s);s+=2;var l=n(r,s);s+=4;var m=n(r,s);s+=4,s=m;for(var b=0;b>>4;return S.inflateRaw(new Uint8Array(f.buffer,f.byteOffset+2,f.length-6),e)};S.deflate=function(f,e){e==null&&(e={level:6});var t=0,n=new Uint8Array(50+Math.floor(f.length*1.1));n[t]=120,n[t+1]=156,t+=2,t=S.F.deflateRaw(f,n,t,e.level);var i=S.adler(f,0,f.length);return n[t+0]=i>>>24&255,n[t+1]=i>>>16&255,n[t+2]=i>>>8&255,n[t+3]=i>>>0&255,new Uint8Array(n.buffer,0,t+4)};S.deflateRaw=function(f,e){e==null&&(e={level:6});var t=new Uint8Array(50+Math.floor(f.length*1.1)),n=S.F.deflateRaw(f,t,n,e.level);return new Uint8Array(t.buffer,0,n)};S.encode=function(f,e){e==null&&(e=!1);var t=0,n=S.bin.writeUint,i=S.bin.writeUshort,r={};for(var a in f){var s=!S._noNeed(a)&&!e,u=f[a],o=S.crc.crc(u,0,u.length);r[a]={cpr:s,usize:u.length,crc:o,file:s?S.deflateRaw(u):u}}for(var a in r)t+=r[a].file.length+30+46+2*S.bin.sizeUTF8(a);t+=22;var l=new Uint8Array(t),m=0,b=[];for(var a in r){var h=r[a];b.push(m),m=S._writeHeader(l,m,a,h,0)}var c=0,d=m;for(var a in r){var h=r[a];b.push(m),m=S._writeHeader(l,m,a,h,1,b[c++])}var p=m-d;return n(l,m,101010256),m+=4,m+=4,i(l,m,c),m+=2,i(l,m,c),m+=2,n(l,m,p),m+=4,n(l,m,d),m+=4,m+=2,l.buffer};S._noNeed=function(f){var e=f.split(".").pop().toLowerCase();return"png,jpg,jpeg,zip".indexOf(e)!=-1};S._writeHeader=function(f,e,t,n,i,r){var a=S.bin.writeUint,s=S.bin.writeUshort,u=n.file;a(f,e,i==0?67324752:33639248),e+=4,i==1&&(e+=2),s(f,e,20),e+=2,s(f,e,0),e+=2,s(f,e,n.cpr?8:0),e+=2,a(f,e,0),e+=4,a(f,e,n.crc),e+=4,a(f,e,u.length),e+=4,a(f,e,n.usize),e+=4,s(f,e,S.bin.sizeUTF8(t)),e+=2,s(f,e,0),e+=2,i==1&&(e+=2,e+=2,e+=6,a(f,e,r),e+=4);var o=S.bin.writeUTF8(f,e,t);return e+=o,i==0&&(f.set(u,e),e+=u.length),e};S.crc={table:function(){for(var f=new Uint32Array(256),e=0;e<256;e++){for(var t=e,n=0;n<8;n++)t&1?t=3988292384^t>>>1:t=t>>>1;f[e]=t}return f}(),update:function(f,e,t,n){for(var i=0;i>>8;return f},crc:function(f,e,t){return S.crc.update(4294967295,f,e,t)^4294967295}};S.adler=function(f,e,t){for(var n=1,i=0,r=e,a=e+t;r>8&255},readUint:function(f,e){return f[e+3]*(256*256*256)+(f[e+2]<<16|f[e+1]<<8|f[e])},writeUint:function(f,e,t){f[e]=t&255,f[e+1]=t>>8&255,f[e+2]=t>>16&255,f[e+3]=t>>24&255},readASCII:function(f,e,t){for(var n="",i=0;i>6,f[e+i+1]=128|a>>0&63,i+=2;else if(!(a&4294967295-(1<<16)+1))f[e+i]=224|a>>12,f[e+i+1]=128|a>>6&63,f[e+i+2]=128|a>>0&63,i+=3;else if(!(a&4294967295-(1<<21)+1))f[e+i]=240|a>>18,f[e+i+1]=128|a>>12&63,f[e+i+2]=128|a>>6&63,f[e+i+3]=128|a>>0&63,i+=4;else throw"e"}return i},sizeUTF8:function(f){for(var e=f.length,t=0,n=0;n>>3}var d=a.lits,p=a.strt,g=a.prev,x=0,y=0,C=0,I=0,P=0,F=0;h>2&&(F=S.F._hash(f,0),p[F]=0);var M=0,w=0;for(l=0;l14e3||y>26697)&&h-l>100&&(b>>16,N=B&65535;if(B!=0){var c=B>>>16,N=B&65535,O=s(c,a.of0);a.lhst[257+O]++;var V=s(N,a.df0);a.dhst[V]++,I+=a.exb[O]+a.dxb[V],d[x]=c<<23|l-b,d[x+1]=N<<16|O<<8|V,x+=2,b=l+c}else a.lhst[f[l]]++;y++}}for((C!=l||f.length==0)&&(b>>3};S.F._bestMatch=function(f,e,t,n,i,r){var a=e&32767,s=t[a],u=a-s+(1<<15)&32767;if(s==a||n!=S.F._hash(f,e-u))return 0;for(var o=0,l=0,m=Math.min(32767,e);u<=m&&--r!=0&&s!=a;){if(o==0||f[e+o]==f[e+o-u]){var b=S.F._howLong(f,e,u);if(b>o){if(o=b,l=u,o>=i)break;u+2h&&(h=g,s=d)}}}a=s,s=t[a],u+=a-s+(1<<15)&32767}return o<<16|l};S.F._howLong=function(f,e,t){if(f[e]!=f[e-t]||f[e+1]!=f[e+1-t]||f[e+2]!=f[e+2-t])return 0;var n=e,i=Math.min(f.length,e+258);for(e+=3;e>>23,ie=V+($&(1<<23)-1);V>16,W=te>>8&255,j=te&255;u=S.F._writeLit(257+W,B,s,u),m(s,u,X-o.of0[W]),u+=o.exb[W],u=S.F._writeLit(j,N,s,u),l(s,u,re-o.df0[j]),u+=o.dxb[j],V+=X}}u=S.F._writeLit(256,B,s,u)}return u};S.F._copyExact=function(f,e,t,n,i){var r=i>>>3;return n[r]=t,n[r+1]=t>>>8,n[r+2]=255-n[r],n[r+3]=255-n[r+1],r+=4,n.set(new Uint8Array(f.buffer,e,t),r),i+(t+4<<3)};S.F.getTrees=function(){for(var f=S.F.U,e=S.F._hufTree(f.lhst,f.ltree,15),t=S.F._hufTree(f.dhst,f.dtree,15),n=[],i=S.F._lenCodes(f.ltree,n),r=[],a=S.F._lenCodes(f.dtree,r),s=0;s4&&f.itree[(f.ordr[o-1]<<1)+1]==0;)o--;return[e,t,u,i,a,o,n,r]};S.F.getSecond=function(f){for(var e=[],t=0;t>1)+",");return e};S.F.contSize=function(f,e){for(var t=0,n=0;n15&&(S.F._putsE(t,n,a,s),n+=s)}return n};S.F._lenCodes=function(f,e){for(var t=f.length;t!=2&&f[t-1]==0;)t-=2;for(var n=0;n>>1,138);o<11?e.push(17,o-3):e.push(18,o-11),n+=o*2-2}else if(i==s&&r==i&&a==i){for(var u=n+5;u+2>>1,6);e.push(16,o-3),n+=o*2-2}else e.push(i,0)}return t>>>1};S.F._hufTree=function(f,e,t){var n=[],i=f.length,r=e.length,a=0;for(a=0;at&&(S.F.restrictDepth(u,t,d),d=t),a=0;ae;n++){var a=f[n].d;f[n].d=e,r+=i-(1<>>t-e;r>0;){var a=f[n].d;a=0;n--)f[n].d==e&&r<0&&(f[n].d--,r++);r!=0&&console.log("debt left")};S.F._goodIndex=function(f,e){var t=0;return e[t|16]<=f&&(t|=16),e[t|8]<=f&&(t|=8),e[t|4]<=f&&(t|=4),e[t|2]<=f&&(t|=2),e[t|1]<=f&&(t|=1),t};S.F._writeLit=function(f,e,t,n){return S.F._putsF(t,n,e[f<<1]),n+e[(f<<1)+1]};S.F.inflate=function(f,e){var t=Uint8Array;if(f[0]==3&&f[1]==0)return e||new t(0);var n=S.F,i=n._bitsF,r=n._bitsE,a=n._decodeTiny,s=n.makeCodes,u=n.codes2map,o=n._get17,l=n.U,m=e==null;m&&(e=new t(f.length>>>2<<3));for(var b=0,h=0,c=0,d=0,p=0,g=0,x=0,y=0,C=0,I,P;b==0;){if(b=i(f,C,1),h=i(f,C+1,2),C+=3,h==0){C&7&&(C+=8-(C&7));var F=(C>>>3)+4,M=f[F-4]|f[F-3]<<8;m&&(e=S.F._check(e,y+M)),e.set(new t(f.buffer,f.byteOffset+F,M),y),C=F+M<<3,y+=M;continue}if(m&&(e=S.F._check(e,y+(1<<17))),h==1&&(I=l.flmap,P=l.fdmap,g=(1<<9)-1,x=(1<<5)-1),h==2){c=r(f,C,5)+257,d=r(f,C+5,5)+1,p=r(f,C+10,4)+4,C+=14;for(var w=C,k=0;k<38;k+=2)l.itree[k]=0,l.itree[k+1]=0;for(var B=1,k=0;kB&&(B=N)}C+=3*p,s(l.itree,B),u(l.itree,B,l.imap),I=l.lmap,P=l.dmap,C=a(l.imap,(1<>>4;if(!($>>>8))e[y++]=$;else{if($==256)break;var X=y+$-254;if($>264){var ie=l.ldef[$-257];X=y+(ie>>>3)+r(f,C,ie&7),C+=ie&7}var te=P[o(f,C)&x];C+=te&15;var re=te>>>4,W=l.ddef[re],j=(W>>>4)+i(f,C,W&15);for(C+=W&15,m&&(e=S.F._check(e,y+(1<<17)));y>>4;if(l<=15)r[u]=l,u++;else{var m=0,b=0;l==16?(b=3+a(n,i,2),i+=2,m=r[u-1]):l==17?(b=3+a(n,i,3),i+=3):l==18&&(b=11+a(n,i,7),i+=7);for(var h=u+b;u>>1;ri&&(i=s),r++}for(;r>1,u=f[a+1],o=s<<4|u,l=e-u,m=f[a]<>>15-e;t[h]=o,m++}};S.F.revCodes=function(f,e){for(var t=S.F.U.rev15,n=15-e,i=0;i>>n}};S.F._putsE=function(f,e,t){t=t<<(e&7);var n=e>>>3;f[n]|=t,f[n+1]|=t>>>8};S.F._putsF=function(f,e,t){t=t<<(e&7);var n=e>>>3;f[n]|=t,f[n+1]|=t>>>8,f[n+2]|=t>>>16};S.F._bitsE=function(f,e,t){return(f[e>>>3]|f[(e>>>3)+1]<<8)>>>(e&7)&(1<>>3]|f[(e>>>3)+1]<<8|f[(e>>>3)+2]<<16)>>>(e&7)&(1<>>3]|f[(e>>>3)+1]<<8|f[(e>>>3)+2]<<16)>>>(e&7)};S.F._get25=function(f,e){return(f[e>>>3]|f[(e>>>3)+1]<<8|f[(e>>>3)+2]<<16|f[(e>>>3)+3]<<24)>>>(e&7)};S.F.U=function(){var f=Uint16Array,e=Uint32Array;return{next_code:new f(16),bl_count:new f(16),ordr:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],of0:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],exb:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],ldef:new f(32),df0:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],dxb:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],ddef:new e(32),flmap:new f(512),fltree:[],fdmap:new f(32),fdtree:[],lmap:new f(32768),ltree:[],ttree:[],dmap:new f(32768),dtree:[],imap:new f(512),itree:[],rev15:new f(1<<15),lhst:new e(286),dhst:new e(30),ihst:new e(19),lits:new e(15e3),strt:new f(1<<16),prev:new f(1<<15)}}();(function(){for(var f=S.F.U,e=1<<15,t=0;t>>1|(n&1431655765)<<1,n=(n&3435973836)>>>2|(n&858993459)<<2,n=(n&4042322160)>>>4|(n&252645135)<<4,n=(n&4278255360)>>>8|(n&16711935)<<8,f.rev15[t]=(n>>>16|n<<16)>>>17}function i(r,a,s){for(;a--!=0;)r.push(0,s)}for(var t=0;t<32;t++)f.ldef[t]=f.of0[t]<<3|f.exb[t],f.ddef[t]=f.df0[t]<<4|f.dxb[t];i(f.fltree,144,8),i(f.fltree,255-143,9),i(f.fltree,279-255,7),i(f.fltree,287-279,8),S.F.makeCodes(f.fltree,9),S.F.codes2map(f.fltree,9,f.flmap),S.F.revCodes(f.fltree,9),i(f.fdtree,32,5),S.F.makeCodes(f.fdtree,5),S.F.codes2map(f.fdtree,5,f.fdmap),S.F.revCodes(f.fdtree,5),i(f.itree,19,0),i(f.ltree,286,0),i(f.dtree,30,0),i(f.ttree,320,0)})()});var ro,ir=A(()=>{"use strict";ro=ws(ps());pi();je();G();nn();be();wa();va();Ei();Zi();ji();pn();dn();It();Xt();H();La();nr();zn();kn();Qn()});var Ga=A(()=>{"use strict";je();At();Fn();qr();Qr();ea();ir();Yn()});De();oe();fi();ri();ai();si();ui();oi();dn();pn();li();mi();hi();ci();bi();en();ae();ts();H();G();Jt();pi();un();je();Sn();sr();_e();At();gn();ur();sn();gi();nn();is();kn();or();zn();be();Tt();mr();_n();Ci();yi();xe();Nn();Dn();$n();Vn();Rn();Tn();_i();Gn();Hn();qn();En();Ln();Ve();Wn();Er();Rr();Dr();Vr();Lr();Ti();Hr();Di();Fn();Vi();cs();bs();qr();fs();Xr();Zr();Li();$r();Yr();Ga();na();Qr();Kr();ea();Jr();Xi();_a();qi();Gi();$i();sa();ra();oa();Wi();ma();ha();ba();da();Bn();pa();xa();Ca();ir();Hi();ji();Ei();Zi();Qn();wa();va();Pa();Ma();Qi();Ia();Va();Ta();Aa();Ji();Ba();Ua();er();Sa();Na();Da();za();tr();ta();Yn();Or();nr();La();wi();vi();Ii();Pi();Mi();Ai();Fi();Bi();Ui();Si();ki();Xn();xs();xi();It();jn();Nr();Ri();vr();Ir();Pr();Mr();Ar();Fr();Br();zi();Xt();_s();hr();cr();br();fr();dr();pr();$e();gr();xr();_r();yr();Cr();wr();Ur();kr();jr();ys();Cs();Ea();Ka();qa();Ha();})(); //# sourceMappingURL=index.js.map diff --git a/lib-compact/index.js.map b/lib-compact/index.js.map index 7084745..37091e4 100644 --- a/lib-compact/index.js.map +++ b/lib-compact/index.js.map @@ -1,7 +1,7 @@ { "version": 3, - "sources": ["../src/error/image-error.ts", "../src/common/array-utils.ts", "../src/common/bit-operators.ts", "../src/common/blend-mode.ts", "../src/common/color-channel.ts", "../src/common/color-model.ts", "../src/common/math-operators.ts", "../src/common/color.ts", "../src/common/crc32.ts", "../src/common/dispose-mode.ts", "../src/common/dither-kernel.ts", "../src/common/dither-pixel.ts", "../src/common/frame-type.ts", "../src/common/frame-animation.ts", "../src/common/heap-node.ts", "../src/common/iccp-compression-mode.ts", "../src/common/text-codec.ts", "../src/common/input-buffer.ts", "../src/common/interpolation.ts", "../src/common/line.ts", "../src/common/rgb-channel-set.ts", "../src/exif/exif-entry.ts", "../src/common/rational.ts", "../src/exif/exif-ifd-container.ts", "../src/exif/exif-value-type.ts", "../src/exif/exif-tag.ts", "../src/exif/exif-value/exif-value.ts", "../src/exif/exif-value/exif-ascii-value.ts", "../src/exif/exif-value/exif-byte-value.ts", "../src/exif/exif-value/exif-double-value.ts", "../src/exif/exif-value/exif-long-value.ts", "../src/exif/exif-value/exif-rational-value.ts", "../src/exif/exif-value/exif-sbyte-value.ts", "../src/exif/exif-value/exif-short-value.ts", "../src/exif/exif-value/exif-single-value.ts", "../src/exif/exif-value/exif-slong-value.ts", "../src/exif/exif-value/exif-srational-value.ts", "../src/exif/exif-value/exif-sshort-value.ts", "../src/exif/exif-value/exif-undefined-value.ts", "../src/exif/exif-ifd.ts", "../src/exif/exif-data.ts", "../src/common/memory-image.ts", "../src/common/neural-quantizer.ts", "../src/common/octree-node.ts", "../src/common/octree-quantizer.ts", "../src/common/output-buffer.ts", "../src/common/point.ts", "../src/common/quantizer.ts", "../src/common/random-utils.ts", "../src/common/rectangle.ts", "../src/common/typings.ts", "../src/draw/draw-image-options.ts", "../src/draw/draw-line-options.ts", "../src/draw/draw.ts", "../src/draw/fill-flood-options.ts", "../src/draw/mask-flood-options.ts", "../src/error/not-implemented-error.ts", "../src/filter/adjust-color-options.ts", "../src/filter/color-offset-options.ts", "../src/filter/convolution-options.ts", "../src/filter/noise-type.ts", "../src/filter/pixelate-mode.ts", "../src/filter/quantize-method.ts", "../src/filter/separable-kernel.ts", "../src/filter/image-filter.ts", "../src/filter/quantize-options.ts", "../src/filter/remap-colors-options.ts", "../src/filter/vignette-options.ts", "../src/hdr/half.ts", "../src/hdr/hdr-slice.ts", "../src/hdr/hdr-image.ts", "../src/formats/bmp/bitmap-file-header.ts", "../src/formats/bmp/bitmap-compression-mode.ts", "../src/formats/bmp/bmp-info.ts", "../src/formats/bmp-decoder.ts", "../src/formats/bmp-encoder.ts", "../src/formats/decode-info.ts", "../src/formats/decoder.ts", "../src/formats/dib-decoder.ts", "../src/formats/encoder.ts", "../src/transform/flip-direction.ts", "../src/transform/image-transform.ts", "../src/formats/gif/gif-color-map.ts", "../src/formats/gif/gif-image-desc.ts", "../src/formats/gif/gif-info.ts", "../src/formats/gif-decoder.ts", "../src/formats/gif-encoder.ts", "../src/formats/ico/ico-bmp-info.ts", "../src/formats/ico/ico-info-image.ts", "../src/formats/ico/ico-info.ts", "../src/formats/png/png-frame.ts", "../src/formats/png/png-info.ts", "../src/formats/png-decoder.ts", "../src/formats/ico-decoder.ts", "../src/formats/png-encoder.ts", "../src/formats/win-encoder.ts", "../src/formats/ico-encoder.ts", "../src/formats/jpeg/component-data.ts", "../src/formats/jpeg/jpeg.ts", "../src/formats/jpeg/jpeg-adobe.ts", "../src/formats/jpeg/jpeg-component.ts", "../src/formats/jpeg/jpeg-frame.ts", "../src/formats/jpeg/jpeg-huffman.ts", "../src/formats/jpeg/jpeg-info.ts", "../src/formats/jpeg/jpeg-jfif.ts", "../src/formats/jpeg/jpeg-quantize.ts", "../src/formats/jpeg/jpeg-scan.ts", "../src/formats/jpeg/jpeg-data.ts", "../src/formats/jpeg-decoder.ts", "../src/formats/jpeg-encoder.ts", "../src/formats/tga/tga-info.ts", "../src/formats/tga-decoder.ts", "../src/formats/tga-encoder.ts", "../src/formats/tiff/tiff-bit-reader.ts", "../src/formats/tiff/tiff-entry.ts", "../src/formats/tiff/tiff-fax-decoder.ts", "../src/formats/tiff/tiff-lzw-decoder.ts", "../src/formats/tiff/tiff-image.ts", "../src/formats/tiff/tiff-info.ts", "../src/formats/tiff-decoder.ts", "../src/formats/tiff-encoder.ts", "../src/hdr/hdr-to-image.ts", "../src/transform/copy-into-options.ts", "../src/transform/copy-resize-options.ts", "../src/transform/trim-mode.ts", "../src/transform/trim-side.ts", "../src/transform/trim.ts", "../src/index.ts", "../node_modules/uzip/UZIP.js", "../src/common/icc-profile-data.ts", ""], - "sourcesContent": ["/** @format */\n\n/**\n * An Error thrown when there was a problem in the image library.\n */\nexport class ImageError extends Error {\n toString(): string {\n return `ImageError: ${this.message}`;\n }\n}\n", "/** @format */\n\nimport { ImageError } from '../error/image-error';\nimport { TypedArray } from './typings';\n\nexport abstract class ArrayUtils {\n public static copyInt8(\n from: Int8Array,\n begin?: number,\n end?: number\n ): Int8Array {\n return Int8Array.from(from.subarray(begin, end));\n }\n\n public static copyUint8(\n from: Uint8Array,\n begin?: number,\n end?: number\n ): Uint8Array {\n return Uint8Array.from(from.subarray(begin, end));\n }\n\n public static copyInt16(\n from: Int16Array,\n begin?: number,\n end?: number\n ): Int16Array {\n return Int16Array.from(from.subarray(begin, end));\n }\n\n public static copyUint16(\n from: Uint16Array,\n begin?: number,\n end?: number\n ): Uint16Array {\n return Uint16Array.from(from.subarray(begin, end));\n }\n\n public static copyInt32(\n from: Int32Array,\n begin?: number,\n end?: number\n ): Int32Array {\n return Int32Array.from(from.subarray(begin, end));\n }\n\n public static copyUint32(\n from: Uint32Array,\n begin?: number,\n end?: number\n ): Uint32Array {\n return Uint32Array.from(from.subarray(begin, end));\n }\n\n public static copyFloat32(\n from: Float32Array,\n begin?: number,\n end?: number\n ): Float32Array {\n return Float32Array.from(from.subarray(begin, end));\n }\n\n public static copyFloat64(\n from: Float64Array,\n begin?: number,\n end?: number\n ): Float64Array {\n return Float64Array.from(from.subarray(begin, end));\n }\n\n public static copy(\n from: TypedArray,\n begin?: number,\n end?: number\n ): TypedArray {\n if (from instanceof Int8Array) {\n return ArrayUtils.copyInt8(from, begin, end);\n } else if (from instanceof Uint8Array) {\n return ArrayUtils.copyUint8(from, begin, end);\n } else if (from instanceof Int16Array) {\n return ArrayUtils.copyInt16(from, begin, end);\n } else if (from instanceof Uint16Array) {\n return ArrayUtils.copyUint16(from, begin, end);\n } else if (from instanceof Int32Array) {\n return ArrayUtils.copyInt32(from, begin, end);\n } else if (from instanceof Uint32Array) {\n return ArrayUtils.copyUint32(from, begin, end);\n } else if (from instanceof Float32Array) {\n return ArrayUtils.copyFloat32(from, begin, end);\n } else if (from instanceof Float64Array) {\n return ArrayUtils.copyFloat64(from, begin, end);\n }\n throw new ImageError('Unknown array type');\n }\n\n public static setRange(\n to: T,\n start: number,\n end: number,\n from: T,\n skipCount = 0\n ): void {\n const viewFrom = from.subarray(skipCount, end - start);\n to.set(viewFrom, start);\n }\n}\n", "/** @format */\n\nexport abstract class BitOperators {\n private static readonly uint8arr: Uint8Array = new Uint8Array(1);\n private static readonly uint8ToInt8arr: Int8Array = new Int8Array(\n BitOperators.uint8arr.buffer\n );\n private static readonly int8arr: Int8Array = new Int8Array(1);\n private static readonly int8ToUint8arr: Uint8Array = new Uint8Array(\n BitOperators.int8arr.buffer\n );\n private static readonly uint16arr: Uint16Array = new Uint16Array(1);\n private static readonly uint16ToInt16arr: Int16Array = new Int16Array(\n BitOperators.uint16arr.buffer\n );\n private static readonly int16arr: Int16Array = new Int16Array(1);\n private static readonly int16ToUint16arr: Uint16Array = new Uint16Array(\n BitOperators.int16arr.buffer\n );\n private static readonly uint32arr: Uint32Array = new Uint32Array(1);\n private static readonly uint32ToInt32arr: Int32Array = new Int32Array(\n BitOperators.uint32arr.buffer\n );\n private static readonly int32arr: Int32Array = new Int32Array(1);\n private static readonly int32ToUint32arr: Uint32Array = new Uint32Array(\n BitOperators.int32arr.buffer\n );\n private static readonly uint32ToFloat32arr: Float32Array = new Float32Array(\n BitOperators.uint32arr.buffer\n );\n private static readonly uint64arr: BigUint64Array = new BigUint64Array(1);\n private static readonly uint64ToFloat64arr: Float64Array = new Float64Array(\n BitOperators.uint64arr.buffer\n );\n\n public static signed(bits: number, value: number) {\n return value & (1 << (bits - 1)) ? value - (1 << bits) : value;\n }\n\n public static shiftR(v: number, n: number): number {\n return BitOperators.signed(32, v >> n);\n }\n\n public static shiftL(v: number, n: number): number {\n return BitOperators.signed(32, v << n);\n }\n\n /**\n * Binary conversion to an int8. This is equivalent in C to\n * typecasting to a char.\n */\n public static toInt8(d: number): number {\n BitOperators.uint8arr[0] = d;\n return BitOperators.uint8ToInt8arr[0];\n }\n\n /**\n * Binary conversion to an uint8. This is equivalent in C to\n * typecasting to an unsigned char.\n */\n public static toUint8(d: number): number {\n BitOperators.int8arr[0] = d;\n return BitOperators.int8ToUint8arr[0];\n }\n\n /**\n * Binary conversion to an int16. This is equivalent in C to\n * typecasting to a short.\n */\n public static toInt16(d: number): number {\n BitOperators.uint16arr[0] = d;\n return BitOperators.uint16ToInt16arr[0];\n }\n\n /**\n * Binary conversion to an uint16. This is equivalent in C to\n * typecasting to an unsigned short.\n */\n public static toUint16(d: number): number {\n BitOperators.int16arr[0] = d;\n return BitOperators.int16ToUint16arr[0];\n }\n\n /**\n * Binary conversion to an int32. This is equivalent in C to\n * typecasting to signed int.\n */\n public static toInt32(d: number): number {\n BitOperators.uint32arr[0] = d;\n return BitOperators.uint32ToInt32arr[0];\n }\n\n /**\n * Binary conversion of an int32 to a uint32. This is equivalent in C to\n * typecasting to unsigned int.\n */\n public static toUint32(d: number): number {\n BitOperators.int32arr[0] = d;\n return BitOperators.int32ToUint32arr[0];\n }\n\n /**\n * Binary conversion to a float32. This is equivalent in C to\n * typecasting to float.\n */\n public static toFloat32(d: number): number {\n BitOperators.uint32arr[0] = d;\n return BitOperators.uint32ToFloat32arr[0];\n }\n\n /**\n * Binary conversion to a float64. This is equivalent in C to\n * typecasting to double.\n */\n public static toFloat64(d: bigint): number {\n BitOperators.uint64arr[0] = d;\n return BitOperators.uint64ToFloat64arr[0];\n }\n\n public static debugBits32(value?: number): string {\n if (value === undefined) {\n return 'undefined';\n }\n const bitCount = 32;\n let result = '';\n for (let i = bitCount; i > -1; i--) {\n result += (value & (1 << i)) === 0 ? '0' : '1';\n }\n return result;\n }\n}\n", "/** @format */\n\nexport enum BlendMode {\n /**\n * No alpha blending should be done when drawing this frame (replace pixels in canvas).\n */\n source,\n\n /**\n * * Alpha blending should be used when drawing this frame (composited over\n * the current canvas image).\n */\n over,\n}\n", "/** @format */\n\nexport enum ColorChannel {\n /**\n * Red channel of a color.\n */\n red,\n\n /**\n * Green channel of a color.\n */\n green,\n\n /**\n * Blue channel of a color.\n */\n blue,\n\n /**\n * Alpha channel of a color.\n */\n alpha,\n\n /**\n * Luminance (brightness) of a color.\n */\n luminance,\n}\n", "/** @format */\n\nexport enum ColorModel {\n argb,\n abgr,\n rgba,\n bgra,\n rgb,\n bgr,\n luminance,\n}\n", "/** @format */\n\nexport abstract class MathOperators {\n /**\n * Returns the greatest common divisor of **x** and **y**.\n */\n public static gcd(x: number, y: number) {\n let _x = Math.abs(x);\n let _y = Math.abs(y);\n while (_y) {\n const t = _y;\n _y = _x % _y;\n _x = t;\n }\n return _x;\n }\n\n /**\n * Clamp **num** to [**low**, **high**]\n */\n public static clamp(num: number, low: number, high: number) {\n return Math.max(low, Math.min(num, high));\n }\n\n /**\n * Clamp **num** to [**a**, **b**] and truncate\n */\n public static clampInt(num: number, low: number, high: number): number {\n return Math.trunc(MathOperators.clamp(num, low, high));\n }\n\n /**\n * Clamp **num** to [**0**, **255**]\n */\n public static clampInt255(num: number): number {\n return Math.trunc(MathOperators.clamp(num, 0, 255));\n }\n}\n", "/** @format */\n\nimport { ImageError } from '../error/image-error';\nimport { BitOperators } from './bit-operators';\nimport { ColorChannel } from './color-channel';\nimport { MathOperators } from './math-operators';\n\n/**\n * Image pixel colors are instantiated as an int object rather than an instance\n * of the Color class in order to reduce object allocations.\n */\nexport abstract class Color {\n /**\n * Create a color value from RGB values in the range [**0**, **255**].\n *\n * The channel order of a uint32 encoded color is BGRA.\n */\n public static fromRgb(red: number, green: number, blue: number): number {\n return Color.getColor(red, green, blue);\n }\n\n /**\n * Create a color value from RGBA values in the range [**0**, **255**].\n *\n * The channel order of a uint32 encoded color is BGRA.\n */\n public static fromRgba(\n red: number,\n green: number,\n blue: number,\n alpha: number\n ): number {\n return Color.getColor(red, green, blue, alpha);\n }\n\n /**\n * Create a color value from HSL values in the range [**0**, **1**].\n */\n public static fromHsl(\n hue: number,\n saturation: number,\n lightness: number\n ): number {\n const rgb = Color.hslToRgb(hue, saturation, lightness);\n return Color.getColor(rgb[0], rgb[1], rgb[2]);\n }\n\n /**\n * Create a color value from HSV values in the range [**0**, **1**].\n */\n public static fromHsv(\n hue: number,\n saturation: number,\n value: number\n ): number {\n const rgb = Color.hsvToRgb(hue, saturation, value);\n return Color.getColor(rgb[0], rgb[1], rgb[2]);\n }\n\n /**\n * Create a color value from XYZ values.\n */\n public static fromXyz(x: number, y: number, z: number): number {\n const rgb = Color.xyzToRgb(x, y, z);\n return Color.getColor(rgb[0], rgb[1], rgb[2]);\n }\n\n /**\n * Create a color value from CIE-L*a*b values.\n */\n public static fromLab(L: number, a: number, b: number): number {\n const rgb = Color.labToRgb(L, a, b);\n return Color.getColor(rgb[0], rgb[1], rgb[2]);\n }\n\n /**\n * Compare colors from a 3 or 4 dimensional color space\n */\n public static distance(\n c1: number[],\n c2: number[],\n compareAlpha: boolean\n ): number {\n const d1 = c1[0] - c2[0];\n const d2 = c1[1] - c2[1];\n const d3 = c1[2] - c2[2];\n if (compareAlpha) {\n const dA = c1[3] - c2[3];\n return Math.sqrt(\n Math.max(d1 * d1, (d1 - dA) * (d1 - dA)) +\n Math.max(d2 * d2, (d2 - dA) * (d2 - dA)) +\n Math.max(d3 * d3, (d3 - dA) * (d3 - dA))\n );\n } else {\n return Math.sqrt(d1 * d1 + d2 * d2 + d3 * d3);\n }\n }\n\n /**\n * Returns a new color of **src** alpha-blended onto **dst**. The opacity of **src**\n * is additionally scaled by **fraction** / **255**.\n */\n public static alphaBlendColors(\n dst: number,\n src: number,\n fraction = 0xff\n ): number {\n const srcAlpha = Color.getAlpha(src);\n if (srcAlpha === 255 && fraction === 0xff) {\n // src is fully opaque, nothing to blend\n return src;\n }\n if (srcAlpha === 0 && fraction === 0xff) {\n // src is fully transparent, nothing to blend\n return dst;\n }\n\n let a = srcAlpha / 255.0;\n if (fraction !== 0xff) {\n a *= fraction / 255.0;\n }\n\n const sr = Math.round(Color.getRed(src) * a);\n const sg = Math.round(Color.getGreen(src) * a);\n const sb = Math.round(Color.getBlue(src) * a);\n const sa = Math.round(srcAlpha * a);\n\n const dr = Math.round(Color.getRed(dst) * (1.0 - a));\n const dg = Math.round(Color.getGreen(dst) * (1.0 - a));\n const db = Math.round(Color.getBlue(dst) * (1.0 - a));\n const da = Math.round(Color.getAlpha(dst) * (1.0 - a));\n\n return Color.getColor(sr + dr, sg + dg, sb + db, sa + da);\n }\n\n /**\n * Get the **channel** from the **color**.\n */\n public static getChannel(color: number, channel: ColorChannel): number {\n if (channel === ColorChannel.red) {\n return Color.getRed(color);\n } else if (channel === ColorChannel.green) {\n return Color.getGreen(color);\n } else if (channel === ColorChannel.blue) {\n return Color.getBlue(color);\n } else if (channel === ColorChannel.alpha) {\n return Color.getAlpha(color);\n }\n return Color.getLuminance(color);\n }\n\n /**\n * Get the alpha channel from the **color**.\n */\n public static getAlpha(color: number): number {\n return (color >> 24) & 0xff;\n }\n\n /**\n * Get the blue channel from the **color**.\n */\n public static getBlue(color: number): number {\n return (color >> 16) & 0xff;\n }\n\n /**\n * Get the color with the given **r**, **g**, **b**, and **a** components.\n * The channel order of a uint32 encoded color is RGBA.\n */\n public static getColor(r: number, g: number, b: number, a = 255): number {\n // What we're doing here, is creating a 32 bit\n // integer by collecting the rgba in one integer.\n // we know for certain and we're also assuring that\n // all our letiables' values are 255 at maximum,\n // which means that they can never be bigger than\n // 8 bits so we can safely slide each one by 8 bits\n // for adding the other.\n const color =\n (MathOperators.clampInt255(a) << 24) |\n (MathOperators.clampInt255(b) << 16) |\n (MathOperators.clampInt255(g) << 8) |\n MathOperators.clampInt255(r);\n return BitOperators.toUint32(color);\n }\n\n /**\n * Get the green channel from the **color**.\n */\n public static getGreen(color: number): number {\n return (color >> 8) & 0xff;\n }\n\n /**\n * Returns the luminance (grayscale) value of the **color**.\n */\n public static getLuminance(color: number): number {\n const r = Color.getRed(color);\n const g = Color.getGreen(color);\n const b = Color.getBlue(color);\n return Color.getLuminanceRgb(r, g, b);\n }\n\n /**\n * Returns the luminance (grayscale) value of the color.\n */\n public static getLuminanceRgb(r: number, g: number, b: number): number {\n return Math.round(0.299 * r + 0.587 * g + 0.114 * b);\n }\n\n /**\n * Get the red channel from the **color**.\n */\n public static getRed(color: number): number {\n return color & 0xff;\n }\n\n /**\n * Check if **color** is white\n */\n public static isBlack(color: number): boolean {\n return (color & 0xffffff) === 0x0;\n }\n\n /**\n * Check if **color** is white\n */\n public static isWhite(color: number): boolean {\n return (color & 0xffffff) === 0xffffff;\n }\n\n /**\n * Returns a new color where the alpha channel of **color** has been replaced by **value**.\n */\n public static setAlpha(color: number, value: number): number {\n return (color & 0x00ffffff) | (MathOperators.clampInt255(value) << 24);\n }\n\n /**\n * Returns a new color where the blue channel of **color** has been replaced by **value**.\n */\n public static setBlue(color: number, value: number): number {\n return (color & 0xff00ffff) | (MathOperators.clampInt255(value) << 16);\n }\n\n /**\n * Returns a new color, where the given **color**'s **channel** has been\n * replaced with the given **value**.\n */\n public static setChannel(\n color: number,\n channel: ColorChannel,\n value: number\n ): number {\n if (channel === ColorChannel.red) {\n return Color.setRed(color, value);\n } else if (channel === ColorChannel.green) {\n return Color.setGreen(color, value);\n } else if (channel === ColorChannel.blue) {\n return Color.setBlue(color, value);\n } else if (channel === ColorChannel.alpha) {\n return Color.setAlpha(color, value);\n }\n return color;\n }\n\n /**\n * Returns a new color where the green channel of **color** has been replaced\n * by **value**.\n */\n public static setGreen(color: number, value: number): number {\n return (color & 0xffff00ff) | (MathOperators.clampInt255(value) << 8);\n }\n\n /**\n * Returns a new color where the red channel of **color** has been replaced\n * by **value**.\n */\n public static setRed(color: number, value: number): number {\n return (color & 0xffffff00) | MathOperators.clampInt255(value);\n }\n\n /**\n * Convert an HSL color to RGB, where h is specified in normalized degrees\n * [**0**, **1**] (where 1 is 360-degrees); s and l are in the range [**0**, **1**].\n * Returns a list [**r**, **g**, **b**] with values in the range [**0**, **255**].\n */\n public static hslToRgb(\n hue: number,\n saturation: number,\n lightness: number\n ): number[] {\n if (saturation === 0) {\n const gray = Math.trunc(lightness * 255.0);\n return [gray, gray, gray];\n }\n\n const hue2rgb = (p: number, q: number, t: number) => {\n let ti = t;\n if (ti < 0.0) {\n ti += 1.0;\n }\n if (ti > 1) {\n ti -= 1.0;\n }\n if (ti < 1.0 / 6.0) {\n return p + (q - p) * 6.0 * ti;\n }\n if (ti < 1.0 / 2.0) {\n return q;\n }\n if (ti < 2.0 / 3.0) {\n return p + (q - p) * (2.0 / 3.0 - ti) * 6.0;\n }\n return p;\n };\n\n const q =\n lightness < 0.5\n ? lightness * (1.0 + saturation)\n : lightness + saturation - lightness * saturation;\n const p = 2.0 * lightness - q;\n\n const r = hue2rgb(p, q, hue + 1.0 / 3.0);\n const g = hue2rgb(p, q, hue);\n const b = hue2rgb(p, q, hue - 1.0 / 3.0);\n\n return [\n Math.round(r * 255.0),\n Math.round(g * 255.0),\n Math.round(b * 255.0),\n ];\n }\n\n /**\n * Convert an HSV color to RGB, where h is specified in normalized degrees\n * [**0**, **1**] (where 1 is 360-degrees); s and l are in the range [**0**, **1**].\n * Returns a list [**r**, **g**, **b**] with values in the range [**0**, **255**].\n */\n public static hsvToRgb(\n hue: number,\n saturation: number,\n brightness: number\n ): number[] {\n if (saturation === 0) {\n const gray = Math.round(brightness * 255.0);\n return [gray, gray, gray];\n }\n\n const h = (hue - Math.floor(hue)) * 6.0;\n const f = h - Math.floor(h);\n const p = brightness * (1.0 - saturation);\n const q = brightness * (1.0 - saturation * f);\n const t = brightness * (1.0 - saturation * (1.0 - f));\n\n switch (Math.trunc(h)) {\n case 0:\n return [\n Math.round(brightness * 255.0),\n Math.round(t * 255.0),\n Math.round(p * 255.0),\n ];\n case 1:\n return [\n Math.round(q * 255.0),\n Math.round(brightness * 255.0),\n Math.round(p * 255.0),\n ];\n case 2:\n return [\n Math.round(p * 255.0),\n Math.round(brightness * 255.0),\n Math.round(t * 255.0),\n ];\n case 3:\n return [\n Math.round(p * 255.0),\n Math.round(q * 255.0),\n Math.round(brightness * 255.0),\n ];\n case 4:\n return [\n Math.round(t * 255.0),\n Math.round(p * 255.0),\n Math.round(brightness * 255.0),\n ];\n case 5:\n return [\n Math.round(brightness * 255.0),\n Math.round(p * 255.0),\n Math.round(q * 255.0),\n ];\n default:\n throw new ImageError('Invalid hue');\n }\n }\n\n /**\n * Convert an RGB color to HSL, where **r**, **g** and **b** are in the range [**0**, **255**].\n * Returns a list [**h**, **s**, **l**] with values in the range [**0**, **1**].\n */\n public static rgbToHsl(r: number, g: number, b: number): number[] {\n const ri = r / 255.0;\n const gi = g / 255.0;\n const bi = b / 255.0;\n const mx = Math.max(ri, Math.max(gi, bi));\n const mn = Math.min(ri, Math.min(gi, bi));\n\n const l = (mx + mn) / 2.0;\n\n if (mx === mn) {\n return [0.0, 0.0, l];\n }\n\n const d = mx - mn;\n const s = l > 0.5 ? d / (2.0 - mx - mn) : d / (mx + mn);\n\n let h = 0;\n if (mx === ri) {\n h = (gi - bi) / d + (gi < bi ? 6.0 : 0.0);\n } else if (mx === gi) {\n h = (bi - ri) / d + 2.0;\n } else {\n h = (ri - gi) / d + 4.0;\n }\n\n h /= 6.0;\n\n return [h, s, l];\n }\n\n /**\n * Convert a CIE-L*a*b color to XYZ.\n */\n public static labToXyz(l: number, a: number, b: number): number[] {\n let y = (l + 16) / 116;\n let x = y + a / 500;\n let z = y - b / 200;\n if (Math.pow(x, 3) > 0.008856) {\n x = Math.pow(x, 3);\n } else {\n x = (x - 16 / 116) / 7.787;\n }\n if (Math.pow(y, 3) > 0.008856) {\n y = Math.pow(y, 3);\n } else {\n y = (y - 16 / 116) / 7.787;\n }\n if (Math.pow(z, 3) > 0.008856) {\n z = Math.pow(z, 3);\n } else {\n z = (z - 16 / 116) / 7.787;\n }\n\n return [\n Math.trunc(x * 95.047),\n Math.trunc(y * 100.0),\n Math.trunc(z * 108.883),\n ];\n }\n\n /**\n * Convert an XYZ color to RGB.\n */\n public static xyzToRgb(x: number, y: number, z: number): number[] {\n const xi = x / 100;\n const yi = y / 100;\n const zi = z / 100;\n let r = 3.2406 * xi + -1.5372 * yi + -0.4986 * zi;\n let g = -0.9689 * xi + 1.8758 * yi + 0.0415 * zi;\n let b = 0.0557 * xi + -0.204 * yi + 1.057 * zi;\n if (r > 0.0031308) {\n r = 1.055 * Math.pow(r, 0.4166666667) - 0.055;\n } else {\n r *= 12.92;\n }\n if (g > 0.0031308) {\n g = 1.055 * Math.pow(g, 0.4166666667) - 0.055;\n } else {\n g *= 12.92;\n }\n if (b > 0.0031308) {\n b = 1.055 * Math.pow(b, 0.4166666667) - 0.055;\n } else {\n b *= 12.92;\n }\n\n return [\n Math.trunc(MathOperators.clamp(r * 255, 0, 255)),\n Math.trunc(MathOperators.clamp(g * 255, 0, 255)),\n Math.trunc(MathOperators.clamp(b * 255, 0, 255)),\n ];\n }\n\n /**\n * Convert a CMYK color to RGB, where **c**, **m**, **y**, **k** values are in the range\n * [**0**, **255**]. Returns a list [**r**, **g**, **b**] with values in the range [**0**, **255**].\n */\n public static cmykToRgb(\n c: number,\n m: number,\n y: number,\n k: number\n ): number[] {\n const ci = c / 255.0;\n const mi = m / 255.0;\n const yi = y / 255.0;\n const ki = k / 255.0;\n return [\n Math.round(255.0 * (1.0 - ci) * (1.0 - ki)),\n Math.round(255.0 * (1.0 - mi) * (1.0 - ki)),\n Math.round(255.0 * (1.0 - yi) * (1.0 - ki)),\n ];\n }\n\n /**\n * Convert a CIE-L*a*b color to RGB.\n */\n public static labToRgb(l: number, a: number, b: number): number[] {\n const refX = 95.047;\n const refY = 100.0;\n const refZ = 108.883;\n\n let y = (l + 16) / 116;\n let x = a / 500 + y;\n let z = y - b / 200;\n\n const y3 = Math.pow(y, 3);\n if (y3 > 0.008856) {\n y = y3;\n } else {\n y = (y - 16 / 116) / 7.787;\n }\n\n const x3 = Math.pow(x, 3);\n if (x3 > 0.008856) {\n x = x3;\n } else {\n x = (x - 16 / 116) / 7.787;\n }\n\n const z3 = Math.pow(z, 3);\n if (z3 > 0.008856) {\n z = z3;\n } else {\n z = (z - 16 / 116) / 7.787;\n }\n\n x *= refX;\n y *= refY;\n z *= refZ;\n\n x /= 100;\n y /= 100;\n z /= 100;\n\n // Xyz to rgb\n let R = x * 3.2406 + y * -1.5372 + z * -0.4986;\n let G = x * -0.9689 + y * 1.8758 + z * 0.0415;\n let B = x * 0.0557 + y * -0.204 + z * 1.057;\n\n if (R > 0.0031308) {\n R = 1.055 * Math.pow(R, 1.0 / 2.4) - 0.055;\n } else {\n R *= 12.92;\n }\n\n if (G > 0.0031308) {\n G = 1.055 * Math.pow(G, 1.0 / 2.4) - 0.055;\n } else {\n G *= 12.92;\n }\n\n if (B > 0.0031308) {\n B = 1.055 * Math.pow(B, 1.0 / 2.4) - 0.055;\n } else {\n B *= 12.92;\n }\n\n return [\n Math.trunc(MathOperators.clamp(R * 255.0, 0, 255)),\n Math.trunc(MathOperators.clamp(G * 255.0, 0, 255)),\n Math.trunc(MathOperators.clamp(B * 255.0, 0, 255)),\n ];\n }\n\n /**\n * Convert a RGB color to XYZ.\n */\n public static rgbToXyz(r: number, g: number, b: number): number[] {\n let ri = r / 255;\n let gi = g / 255;\n let bi = b / 255;\n\n if (ri > 0.04045) {\n ri = Math.pow((ri + 0.055) / 1.055, 2.4);\n } else {\n ri /= 12.92;\n }\n if (gi > 0.04045) {\n gi = Math.pow((gi + 0.055) / 1.055, 2.4);\n } else {\n gi /= 12.92;\n }\n if (bi > 0.04045) {\n bi = Math.pow((bi + 0.055) / 1.055, 2.4);\n } else {\n bi /= 12.92;\n }\n\n ri *= 100.0;\n gi *= 100.0;\n bi *= 100.0;\n\n return [\n ri * 0.4124 + gi * 0.3576 + bi * 0.1805,\n ri * 0.2126 + gi * 0.7152 + bi * 0.0722,\n ri * 0.0193 + gi * 0.1192 + bi * 0.9505,\n ];\n }\n\n /**\n * Convert a XYZ color to CIE-L*a*b.\n */\n public static xyzToLab(x: number, y: number, z: number): number[] {\n let xi = x / 95.047;\n let yi = y / 100;\n let zi = z / 108.883;\n\n if (xi > 0.008856) {\n xi = Math.pow(xi, 1 / 3);\n } else {\n xi = 7.787 * xi + 16 / 116;\n }\n if (yi > 0.008856) {\n yi = Math.pow(yi, 1 / 3);\n } else {\n yi = 7.787 * yi + 16 / 116;\n }\n if (zi > 0.008856) {\n zi = Math.pow(zi, 1 / 3);\n } else {\n zi = 7.787 * zi + 16 / 116;\n }\n\n return [116 * yi - 16, 500 * (xi - yi), 200 * (yi - zi)];\n }\n\n /**\n * Convert a RGB color to CIE-L*a*b.\n */\n public static rgbToLab(r: number, g: number, b: number): number[] {\n let ri = r / 255;\n let gi = g / 255;\n let bi = b / 255;\n\n if (ri > 0.04045) {\n ri = Math.pow((ri + 0.055) / 1.055, 2.4);\n } else {\n ri /= 12.92;\n }\n if (gi > 0.04045) {\n gi = Math.pow((gi + 0.055) / 1.055, 2.4);\n } else {\n gi /= 12.92;\n }\n if (bi > 0.04045) {\n bi = Math.pow((bi + 0.055) / 1.055, 2.4);\n } else {\n bi /= 12.92;\n }\n\n ri *= 100;\n gi *= 100;\n bi *= 100;\n\n let x = ri * 0.4124 + gi * 0.3576 + bi * 0.1805;\n let y = ri * 0.2126 + gi * 0.7152 + bi * 0.0722;\n let z = ri * 0.0193 + gi * 0.1192 + bi * 0.9505;\n\n x /= 95.047;\n y /= 100.0;\n z /= 108.883;\n\n if (x > 0.008856) {\n x = Math.pow(x, 1 / 3.0);\n } else {\n x = 7.787 * x + 16 / 116;\n }\n if (y > 0.008856) {\n y = Math.pow(y, 1 / 3);\n } else {\n y = 7.787 * y + 16 / 116;\n }\n if (z > 0.008856) {\n z = Math.pow(z, 1 / 3);\n } else {\n z = 7.787 * z + 16 / 116;\n }\n\n return [116 * y - 16, 500 * (x - y), 200 * (y - z)];\n }\n}\n", "/** @format */\n\nexport interface Crc32Parameters {\n buffer: Uint8Array;\n baseCrc?: number;\n position?: number;\n length?: number;\n}\n\nexport abstract class Crc32 {\n private static readonly crcTable = new Uint32Array(Crc32.makeTable());\n\n private static makeTable() {\n const table: number[] = [];\n let c = 0;\n for (let n = 0; n < 256; n++) {\n c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c;\n }\n return table;\n }\n\n public static getChecksum(options: Crc32Parameters) {\n const t = Crc32.crcTable;\n const len = options.length ?? options.buffer.length;\n const pos = options.position ?? 0;\n const end = pos + len;\n\n let result = (options.baseCrc ?? 0) ^ -1;\n for (let i = pos; i < end; i++) {\n result = (result >>> 8) ^ t[(result ^ options.buffer[i]) & 0xff];\n }\n\n return (result ^ -1) >>> 0;\n }\n}\n", "/** @format */\n\nexport enum DisposeMode {\n /**\n * When drawing a frame, the canvas should be left as it is.\n */\n none,\n\n /**\n * When drawing a frame, the canvas should be cleared first.\n */\n clear,\n\n /**\n * When drawing this frame, the canvas should be reverted to how it was before drawing it.\n */\n previous,\n}\n", "/** @format */\n\nexport enum DitherKernel {\n None,\n FalseFloydSteinberg,\n FloydSteinberg,\n Stucki,\n Atkinson,\n}\n", "/** @format */\n\nimport { DitherKernel } from './dither-kernel';\nimport { MemoryImage } from './memory-image';\nimport { NeuralQuantizer } from './neural-quantizer';\n\nexport abstract class DitherPixel {\n private static ditherKernels = [\n [\n [0, 0, 0],\n [0, 0, 0],\n [0, 0, 0],\n ],\n // FalseFloydSteinberg\n [\n [3 / 8, 1, 0],\n [3 / 8, 0, 1],\n [2 / 8, 1, 1],\n ],\n // FloydSteinberg\n [\n [7 / 16, 1, 0],\n [3 / 16, -1, 1],\n [5 / 16, 0, 1],\n [1 / 16, 1, 1],\n ],\n // Stucki\n [\n [8 / 42, 1, 0],\n [4 / 42, 2, 0],\n [2 / 42, -2, 1],\n [4 / 42, -1, 1],\n [8 / 42, 0, 1],\n [4 / 42, 1, 1],\n [2 / 42, 2, 1],\n [1 / 42, -2, 2],\n [2 / 42, -1, 2],\n [4 / 42, 0, 2],\n [2 / 42, 1, 2],\n [1 / 42, 2, 2],\n ],\n //Atkinson:\n [\n [1 / 8, 1, 0],\n [1 / 8, 2, 0],\n [1 / 8, -1, 1],\n [1 / 8, 0, 1],\n [1 / 8, 1, 1],\n [1 / 8, 0, 2],\n ],\n ];\n\n public static getDitherPixels(\n image: MemoryImage,\n quantizer: NeuralQuantizer,\n kernel: DitherKernel,\n serpentine: boolean\n ): Uint8Array {\n if (kernel === DitherKernel.None) {\n return quantizer.getIndexMap(image);\n }\n\n const ds = DitherPixel.ditherKernels[kernel];\n const height = image.height;\n const width = image.width;\n const data = new Uint8Array(image.getBytes());\n\n const indexedPixels = new Uint8Array(width * height);\n const colorMap = quantizer.colorMap8;\n\n let direction = serpentine ? -1 : 1;\n let index = 0;\n for (let y = 0; y < height; y++) {\n if (serpentine) {\n direction *= -1;\n }\n\n const x0 = direction === 1 ? 0 : width - 1;\n const x1 = direction === 1 ? width : 0;\n for (let x = x0; x !== x1; x += direction, ++index) {\n // Get original color\n let idx = index * 4;\n const r1 = data[idx];\n const g1 = data[idx + 1];\n const b1 = data[idx + 2];\n\n // Get converted color\n idx = quantizer.lookupRGB(r1, g1, b1);\n\n indexedPixels[index] = idx;\n idx *= 3;\n const r2 = colorMap[idx];\n const g2 = colorMap[idx + 1];\n const b2 = colorMap[idx + 2];\n\n const er = r1 - r2;\n const eg = g1 - g2;\n const eb = b1 - b2;\n\n if (er !== 0 || eg !== 0 || eb !== 0) {\n const i0 = direction === 1 ? 0 : ds.length - 1;\n const i1 = direction === 1 ? ds.length : 0;\n for (let i = i0; i !== i1; i += direction) {\n const x1 = Math.trunc(ds[i][1]);\n const y1 = Math.trunc(ds[i][2]);\n if (\n x1 + x >= 0 &&\n x1 + x < width &&\n y1 + y >= 0 &&\n y1 + y < height\n ) {\n const d = ds[i][0];\n idx = index + x1 + y1 * width;\n idx *= 4;\n data[idx] = Math.max(\n 0,\n Math.min(255, Math.trunc(data[idx] + er * d))\n );\n data[idx + 1] = Math.max(\n 0,\n Math.min(255, Math.trunc(data[idx + 1] + eg * d))\n );\n data[idx + 2] = Math.max(\n 0,\n Math.min(255, Math.trunc(data[idx + 2] + eb * d))\n );\n }\n }\n }\n }\n }\n\n return indexedPixels;\n }\n}\n", "/** @format */\n\nexport enum FrameType {\n /**\n * The frames of this document are to be interpreted as animation.\n */\n animation,\n\n /**\n * The frames of this document are to be interpreted as pages of a document.\n */\n page,\n}\n", "/** @format */\n\nimport { FrameType } from './frame-type';\nimport { MemoryImage } from './memory-image';\n\nexport interface FrameAnimationInitOptions {\n width?: number;\n height?: number;\n loopCount?: number;\n frameType?: FrameType;\n}\n\n/**\n * Stores multiple images, most often as the frames of an animation.\n *\n * Some formats support multiple images that are not\n * to be interpreted as animation, but rather multiple pages of a document.\n * The **FrameAnimation** container is still used to store the images for these files.\n * The **frameType** property is used to differentiate multi-page documents from\n * multi-frame animations, where it is set to **FrameType.page** for documents\n * and **FrameType.animation** for animated frames.\n *\n * All **Decoder** classes support decoding to an **FrameAnimation**, where the\n * **FrameAnimation** will only contain a single frame for single image formats\n * such as JPEG, or if the file doesn't contain any animation such as a single\n * image GIF. If you want to generically support both animated and non-animated\n * files, you can always decode to an animation and if the animation has only\n * a single frame, then it's a non-animated image.\n *\n * In some cases, the frames of the animation may only provide a portion of the\n * canvas, such as the case of animations encoding only the changing pixels\n * from one frame to the next. The **width** and **height** and **backgroundColor**\n * properties of the **FrameAnimation** provide information about the canvas that\n * contains the animation, and the **MemoryImage** frames provide information about\n * how to draw the particular frame, such as the area of the canvas to draw\n * into, and if the canvas should be cleared prior to drawing the frame.\n */\nexport class FrameAnimation implements Iterable {\n /**\n * The canvas width for containing the animation.\n */\n private _width = 0;\n public get width(): number {\n return this._width;\n }\n\n /**\n * The canvas height for containing the animation.\n */\n private _height = 0;\n public get height(): number {\n return this._height;\n }\n\n /**\n * The suggested background color to clear the canvas with.\n */\n private _backgroundColor = 0xffffffff;\n public get backgroundColor(): number {\n return this._backgroundColor;\n }\n\n /**\n * How many times should the animation loop(0 means forever)?\n */\n private _loopCount = 0;\n public get loopCount(): number {\n return this._loopCount;\n }\n\n /**\n * How should the frames be interpreted? If **FrameType.animation**, the\n * frames are part of an animated sequence. If **FrameType.page**, the frames\n * are the pages of a document.\n */\n private _frameType: FrameType = FrameType.animation;\n public get frameType(): FrameType {\n return this._frameType;\n }\n\n /**\n * The frames of the animation.\n */\n private _frames: MemoryImage[] = [];\n public get frames(): MemoryImage[] {\n return this._frames;\n }\n\n /**\n * How many frames are in the animation?\n */\n public get numFrames(): number {\n return this.frames.length;\n }\n\n /**\n * The first frame of the animation.\n */\n public get first(): MemoryImage {\n return this.frames[0];\n }\n\n /**\n * The last frame of the animation.\n */\n public get last(): MemoryImage {\n return this.frames[this.frames.length - 1];\n }\n\n /**\n * Is the animation empty(no frames)?\n */\n public get isEmpty(): boolean {\n return this.frames.length === 0;\n }\n\n /**\n * Returns true if there is at least one frame in the animation.\n */\n public get isNotEmpty(): boolean {\n return this.frames.length > 0;\n }\n\n constructor(options?: FrameAnimationInitOptions) {\n this._width = options?.width ?? 0;\n this._height = options?.height ?? 0;\n this._loopCount = options?.loopCount ?? 0;\n this._frameType = options?.frameType ?? FrameType.animation;\n }\n\n /**\n * Get the frame at the given **index**.\n */\n public getFrame(index: number): MemoryImage {\n return this.frames[index];\n }\n\n /**\n * Add a frame to the animation.\n */\n public addFrame(image: MemoryImage): void {\n if (this._width < image.width) {\n this._width = image.width;\n }\n if (this._height < image.height) {\n this._height = image.height;\n }\n this.frames.push(image);\n }\n\n /**\n * Get the iterator for looping over the animation.\n */\n public [Symbol.iterator](): Iterator {\n let index = -1;\n return {\n next: () => {\n return {\n value: this._frames[++index],\n done: !(index in this._frames),\n };\n },\n };\n }\n}\n", "/** @format */\n\nimport { OctreeNode } from './octree-node';\n\nexport class HeapNode {\n private _buf: Array = [undefined];\n public get buf(): Array {\n return this._buf;\n }\n\n public get n(): number {\n return this._buf.length;\n }\n}\n", "/** @format */\n\nexport enum ICCPCompressionMode {\n none,\n deflate,\n}\n", "/** @format */\n\nimport { ImageError } from '../error/image-error';\n\nexport abstract class TextCodec {\n public static readonly utf8Decoder = new TextDecoder('utf8');\n public static readonly latin1Decoder = new TextDecoder('latin1');\n\n public static getCodePoints(str: string): Uint8Array {\n const array = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n const codePoint = str.codePointAt(i);\n if (codePoint !== undefined) {\n if (0 <= codePoint && codePoint < 256) {\n array[i] = codePoint;\n } else {\n throw new ImageError(\n `Error encoding text \"${str}\": unknown character code point ${codePoint}`\n );\n }\n } else {\n throw new ImageError(`Error encoding text \"${str}\"`);\n }\n }\n return array;\n }\n}\n", "/** @format */\n\nimport { ImageError } from '../error/image-error';\nimport { BitOperators } from './bit-operators';\nimport { TextCodec } from './text-codec';\n\nexport interface InputBufferInitOptions {\n buffer: Uint8Array;\n offset?: number;\n length?: number;\n bigEndian?: boolean;\n}\n\n/**\n * A buffer that can be read as a stream of bytes.\n */\nexport class InputBuffer {\n private readonly _buffer: Uint8Array;\n public get buffer(): Uint8Array {\n return this._buffer;\n }\n\n private _bigEndian: boolean;\n public set bigEndian(v: boolean) {\n this._bigEndian = v;\n }\n public get bigEndian(): boolean {\n return this._bigEndian;\n }\n\n private _offset: number;\n public set offset(v: number) {\n this._offset = v;\n }\n public get offset(): number {\n return this._offset;\n }\n\n private _start: number;\n public get start(): number {\n return this._start;\n }\n\n private _end: number;\n public get end(): number {\n return this._end;\n }\n\n /**\n * The current read position relative to the start of the buffer.\n */\n get position(): number {\n return this._offset - this._start;\n }\n\n /**\n * How many bytes are left in the stream.\n */\n get length(): number {\n return this._end - this._offset;\n }\n\n /**\n * Is the current position at the end of the stream?\n */\n get isEOS(): boolean {\n return this._offset >= this._end;\n }\n\n /**\n * Create a InputStream for reading from an Array\n */\n constructor(options: InputBufferInitOptions) {\n this._buffer = options.buffer;\n this._bigEndian = options.bigEndian ?? false;\n this._offset = options.offset ?? 0;\n this._start = this._offset;\n this._end =\n options.length !== undefined\n ? this._start + options.length\n : this._buffer.length;\n }\n\n /**\n * Create a copy of **other**.\n */\n public static from(other: InputBuffer, offset?: number, length?: number) {\n const offsetFromOther = offset ?? 0;\n const result = new InputBuffer({\n buffer: other._buffer,\n bigEndian: other._bigEndian,\n offset: other._offset + offsetFromOther,\n length: length,\n });\n result._start = other._start;\n result._end =\n length !== undefined\n ? other.offset + offsetFromOther + length\n : other._end;\n return result;\n }\n\n /**\n * Reset to the beginning of the stream.\n */\n public rewind(): void {\n this._offset = this._start;\n }\n\n /**\n * Access the buffer relative from the current position.\n */\n public getByte(index: number): number {\n return this._buffer[this._offset + index];\n }\n\n /**\n * Set a buffer element relative to the current position.\n */\n public setByte(index: number, value: number) {\n return (this._buffer[this._offset + index] = value);\n }\n\n /**\n * Set a range of bytes in this buffer to **value**, at **start** offset from the\n * current read position, and **length** number of bytes.\n */\n public memset(start: number, length: number, value: number): void {\n this._buffer.fill(\n this._offset + start,\n this._offset + start + length,\n value\n );\n }\n\n /**\n * Return a InputStream to read a subset of this stream. It does not\n * move the read position of this stream. **position** is specified relative\n * to the start of the buffer. If **position** is not specified, the current\n * read position is used. If **length** is not specified, the remainder of this\n * stream is used.\n */\n public subarray(count: number, position?: number, offset = 0): InputBuffer {\n let pos = position !== undefined ? this._start + position : this._offset;\n pos += offset;\n return new InputBuffer({\n buffer: this._buffer,\n bigEndian: this._bigEndian,\n offset: pos,\n length: count,\n });\n }\n\n /**\n * Returns the position of the given **value** within the buffer, starting\n * from the current read position with the given **offset**. The position\n * returned is relative to the start of the buffer, or -1 if the **value**\n * was not found.\n */\n public indexOf(value: number, offset = 0): number {\n for (\n let i = this._offset + offset, end = this._offset + this.length;\n i < end;\n ++i\n ) {\n if (this._buffer[i] === value) {\n return i - this._start;\n }\n }\n return -1;\n }\n\n /**\n * Read **count** bytes from an **offset** of the current read position, without\n * moving the read position.\n */\n public peekBytes(count: number, offset = 0): InputBuffer {\n return this.subarray(count, undefined, offset);\n }\n\n /**\n * Move the read position by **count** bytes.\n */\n public skip(count: number): void {\n this._offset += count;\n }\n\n /**\n * Read a single byte.\n */\n public readByte(): number {\n return this._buffer[this._offset++];\n }\n\n public readInt8(): number {\n return BitOperators.toInt8(this.readByte());\n }\n\n /**\n * Read **count** bytes from the stream.\n */\n public readBytes(count: number): InputBuffer {\n const bytes = this.subarray(count);\n this._offset += bytes.length;\n return bytes;\n }\n\n /**\n * Read a null-terminated string, or if **length** is provided, that number of\n * bytes returned as a string.\n */\n public readString(length?: number): string {\n if (length === undefined) {\n const codes: number[] = [];\n while (!this.isEOS) {\n const c = this.readByte();\n if (c === 0) {\n return String.fromCharCode(...codes);\n }\n codes.push(c);\n }\n throw new ImageError('EOF reached without finding string terminator');\n }\n\n const s = this.readBytes(length);\n const bytes = s.toUint8Array();\n const result = String.fromCharCode(...bytes);\n return result;\n }\n\n /**\n * Read a null-terminated UTF-8 string.\n */\n public readStringUtf8(): string {\n const codes: number[] = [];\n while (!this.isEOS) {\n const c = this.readByte();\n if (c === 0) {\n const array = new Uint8Array(codes);\n return TextCodec.utf8Decoder.decode(array);\n }\n codes.push(c);\n }\n throw new ImageError('EOF reached without finding string terminator');\n }\n\n /**\n * Read a 16-bit word from the stream.\n */\n public readUint16(): number {\n const b1 = this._buffer[this._offset++] & 0xff;\n const b2 = this._buffer[this._offset++] & 0xff;\n if (this._bigEndian) {\n return (b1 << 8) | b2;\n }\n return (b2 << 8) | b1;\n }\n\n /**\n * Read a 16-bit word from the stream.\n */\n public readInt16(): number {\n return BitOperators.toInt16(this.readUint16());\n }\n\n /**\n * Read a 24-bit word from the stream.\n */\n public readUint24(): number {\n const b1 = this._buffer[this._offset++] & 0xff;\n const b2 = this._buffer[this._offset++] & 0xff;\n const b3 = this._buffer[this._offset++] & 0xff;\n if (this._bigEndian) {\n return b3 | (b2 << 8) | (b1 << 16);\n }\n return b1 | (b2 << 8) | (b3 << 16);\n }\n\n /**\n * Read a 32-bit word from the stream.\n */\n public readUint32(): number {\n const b1 = this._buffer[this._offset++] & 0xff;\n const b2 = this._buffer[this._offset++] & 0xff;\n const b3 = this._buffer[this._offset++] & 0xff;\n const b4 = this._buffer[this._offset++] & 0xff;\n const d = this._bigEndian\n ? (b1 << 24) | (b2 << 16) | (b3 << 8) | b4\n : (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;\n return BitOperators.toUint32(d);\n }\n\n /**\n * Read a signed 32-bit integer from the stream.\n */\n public readInt32(): number {\n return BitOperators.toInt32(this.readUint32());\n }\n\n /**\n * Read a 32-bit float.\n */\n public readFloat32(): number {\n return BitOperators.toFloat32(this.readUint32());\n }\n\n /**\n * Read a 64-bit float.\n */\n public readFloat64(): number {\n return BitOperators.toFloat64(this.readUint64());\n }\n\n /**\n * Read a 64-bit word form the stream.\n */\n public readUint64(): bigint {\n const b1 = this._buffer[this._offset++] & 0xff;\n const b2 = this._buffer[this._offset++] & 0xff;\n const b3 = this._buffer[this._offset++] & 0xff;\n const b4 = this._buffer[this._offset++] & 0xff;\n const b5 = this._buffer[this._offset++] & 0xff;\n const b6 = this._buffer[this._offset++] & 0xff;\n const b7 = this._buffer[this._offset++] & 0xff;\n const b8 = this._buffer[this._offset++] & 0xff;\n if (this._bigEndian) {\n return (\n BigInt(b1 << 56) |\n BigInt(b2 << 48) |\n BigInt(b3 << 40) |\n BigInt(b4 << 32) |\n BigInt(b5 << 24) |\n BigInt(b6 << 16) |\n BigInt(b7 << 8) |\n BigInt(b8)\n );\n }\n return (\n BigInt(b8 << 56) |\n BigInt(b7 << 48) |\n BigInt(b6 << 40) |\n BigInt(b5 << 32) |\n BigInt(b4 << 24) |\n BigInt(b3 << 16) |\n BigInt(b2 << 8) |\n BigInt(b1)\n );\n }\n\n public toUint8Array(offset?: number, length?: number): Uint8Array {\n const correctedOffset = offset ?? 0;\n const correctedLength = length ?? this.length - correctedOffset;\n return new Uint8Array(\n this._buffer.buffer,\n this._buffer.byteOffset + this._offset + correctedOffset,\n correctedLength\n );\n }\n\n public toUint32Array(offset?: number): Uint32Array {\n const correctedOffset = offset ?? 0;\n return new Uint32Array(\n this._buffer.buffer,\n this._buffer.byteOffset + this._offset + correctedOffset\n );\n }\n}\n", "/** @format */\n\nexport enum Interpolation {\n nearest,\n linear,\n cubic,\n average,\n}\n", "/** @format */\n\nimport { Point } from './point';\n\nexport class Line {\n private _startX = 0;\n private _startY = 0;\n private _endX = 0;\n private _endY = 0;\n private _dx = 0;\n private _dy = 0;\n\n public get startX(): number {\n return this._startX;\n }\n\n public get startY(): number {\n return this._startY;\n }\n\n public get endX(): number {\n return this._endX;\n }\n\n public get endY(): number {\n return this._endY;\n }\n\n public get dx(): number {\n return this._dx;\n }\n\n public get dy(): number {\n return this._dy;\n }\n\n constructor(x1: number, y1: number, x2: number, y2: number) {\n this.initialize(x1, y1, x2, y2);\n }\n\n public static from(other: Line) {\n return new Line(other.startX, other.startY, other.endX, other.endY);\n }\n\n private initialize(x1: number, y1: number, x2: number, y2: number) {\n this._startX = Math.min(x1, x2);\n this._startY = Math.min(y1, y2);\n this._endX = Math.max(x1, x2);\n this._endY = Math.max(y1, y2);\n this._dx = this._endX - this._startX;\n this._dy = this._endY - this._startY;\n }\n\n public moveStart(x: number, y: number) {\n this.initialize(x, y, this._endX, this._endY);\n }\n\n public moveEnd(x: number, y: number) {\n this.initialize(this._startX, this._startY, x, y);\n }\n}\n", "/** @format */\n\nexport enum RgbChannelSet {\n rgb,\n rgba,\n}\n", "/** @format */\n\nimport { ExifValue } from './exif-value/exif-value';\n\nexport class ExifEntry {\n private readonly _tag: number;\n public get tag(): number {\n return this._tag;\n }\n\n private _value: ExifValue | undefined;\n public get value(): ExifValue | undefined {\n return this._value;\n }\n public set value(v: ExifValue | undefined) {\n this._value = v;\n }\n\n constructor(tag: number, value?: ExifValue) {\n this._tag = tag;\n this._value = value;\n }\n}\n", "/** @format */\n\nimport { MathOperators } from '../common/math-operators';\n\nexport class Rational {\n private _numerator: number;\n public get numerator(): number {\n return this._numerator;\n }\n\n private _denominator: number;\n public get denominator(): number {\n return this._denominator;\n }\n\n public get asInt(): number {\n return this.denominator !== 0\n ? Math.trunc(this.numerator / this.denominator)\n : 0;\n }\n\n public get asDouble(): number {\n return this.denominator !== 0 ? this.numerator / this.denominator : 0;\n }\n\n constructor(numerator: number, denominator: number) {\n this._numerator = numerator;\n this._denominator = denominator;\n }\n\n public simplify(): void {\n const d = MathOperators.gcd(this.numerator, this.denominator);\n if (d !== 0) {\n this._numerator = Math.trunc(this.numerator / d);\n this._denominator = Math.trunc(this.denominator / d);\n }\n }\n\n public equalsTo(other: unknown) {\n return (\n other instanceof Rational &&\n this._numerator === other._numerator &&\n this._denominator === other._denominator\n );\n }\n\n public toString(): string {\n return `${this._numerator}/${this._denominator}`;\n }\n}\n", "/** @format */\n\nimport { ExifIFD } from './exif-ifd';\n\nexport class ExifIFDContainer {\n protected directories: Map;\n\n public get keys(): IterableIterator {\n return this.directories.keys();\n }\n\n public get values(): IterableIterator {\n return this.directories.values();\n }\n\n public get size(): number {\n return this.directories.size;\n }\n\n public get isEmpty(): boolean {\n if (this.directories.size === 0) {\n return true;\n }\n for (const ifd of this.directories.values()) {\n if (!ifd.isEmpty) {\n return false;\n }\n }\n return true;\n }\n\n constructor(directories?: Map) {\n this.directories = directories ?? new Map();\n }\n\n public static from(other: ExifIFDContainer) {\n return new ExifIFDContainer(other.directories);\n }\n\n public has(key: string): boolean {\n return this.directories.has(key);\n }\n\n public get(ifdName: string): ExifIFD {\n let ifd = this.directories.get(ifdName);\n if (ifd === undefined) {\n ifd = new ExifIFD();\n this.directories.set(ifdName, ifd);\n return ifd;\n } else {\n return ifd;\n }\n }\n\n public set(ifdName: string, value: ExifIFD): void {\n this.directories.set(ifdName, value);\n }\n\n public clear(): void {\n this.directories.clear();\n }\n}\n", "/** @format */\n\nexport enum ExifValueType {\n none,\n byte,\n ascii,\n short,\n long,\n rational,\n sbyte,\n undefined,\n sshort,\n slong,\n srational,\n single,\n double,\n}\n\nexport const ExifValueTypeString = [\n 'None',\n 'Byte',\n 'Ascii',\n 'Short',\n 'Long',\n 'Rational',\n 'SByte',\n 'Undefined',\n 'SShort',\n 'SLong',\n 'SRational',\n 'Single',\n 'Double',\n];\n\nexport const ExifValueTypeSize = [0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8];\n\nexport function getExifValueTypeString(type: ExifValueType) {\n return ExifValueTypeString[type];\n}\n\nexport function getExifValueTypeSize(type: ExifValueType, length = 1) {\n return ExifValueTypeSize[type] * length;\n}\n", "/** @format */\n\nimport { ExifValueType } from './exif-value-type';\n\nexport interface ExifTagInitOptions {\n name: string;\n type?: ExifValueType;\n count?: number;\n}\n\nexport class ExifTag {\n private readonly _name: string;\n public get name(): string {\n return this._name;\n }\n\n private readonly _type: ExifValueType;\n public get type(): ExifValueType {\n return this._type;\n }\n\n private _count: number;\n public get count(): number {\n return this._count;\n }\n\n constructor(options: ExifTagInitOptions) {\n this._name = options.name;\n this._type = options.type ?? ExifValueType.none;\n this._count = options.count ?? 1;\n }\n}\n\nexport const ExifTagNameToID = new Map([\n ['ProcessingSoftware', 0xb],\n ['SubfileType', 0xfe],\n ['OldSubfileType', 0xff],\n ['ImageWidth', 0x100],\n ['ImageLength', 0x101],\n // alias for a more common name.\n ['ImageHeight', 0x101],\n ['BitsPerSample', 0x102],\n ['Compression', 0x103],\n ['PhotometricInterpretation', 0x106],\n ['Thresholding', 0x107],\n ['CellWidth', 0x108],\n ['CellLength', 0x109],\n ['FillOrder', 0x10a],\n ['DocumentName', 0x10d],\n ['ImageDescription', 0x10e],\n ['Make', 0x10f],\n ['Model', 0x110],\n ['StripOffsets', 0x111],\n ['Orientation', 0x112],\n ['SamplesPerPixel', 0x115],\n ['RowsPerStrip', 0x116],\n ['StripByteCounts', 0x117],\n ['MinSampleValue', 0x118],\n ['MaxSampleValue', 0x119],\n ['XResolution', 0x11a],\n ['YResolution', 0x11b],\n ['PlanarConfiguration', 0x11c],\n ['PageName', 0x11d],\n ['XPosition', 0x11e],\n ['YPosition', 0x11f],\n ['GrayResponseUnit', 0x122],\n ['GrayResponseCurve', 0x123],\n ['T4Options', 0x124],\n ['T6Options', 0x125],\n ['ResolutionUnit', 0x128],\n ['PageNumber', 0x129],\n ['ColorResponseUnit', 0x12c],\n ['TransferFunction', 0x12d],\n ['Software', 0x131],\n ['DateTime', 0x132],\n ['Artist', 0x13b],\n ['HostComputer', 0x13c],\n ['Predictor', 0x13d],\n ['WhitePoint', 0x13e],\n ['PrimaryChromaticities', 0x13f],\n ['ColorMap', 0x140],\n ['HalftoneHints', 0x141],\n ['TileWidth', 0x142],\n ['TileLength', 0x143],\n ['TileOffsets', 0x144],\n ['TileByteCounts', 0x145],\n ['BadFaxLines', 0x146],\n ['CleanFaxData', 0x147],\n ['ConsecutiveBadFaxLines', 0x148],\n ['InkSet', 0x14c],\n ['InkNames', 0x14d],\n ['NumberofInks', 0x14e],\n ['DotRange', 0x150],\n ['TargetPrinter', 0x151],\n ['ExtraSamples', 0x152],\n ['SampleFormat', 0x153],\n ['SMinSampleValue', 0x154],\n ['SMaxSampleValue', 0x155],\n ['TransferRange', 0x156],\n ['ClipPath', 0x157],\n ['JPEGProc', 0x200],\n ['JPEGInterchangeFormat', 0x201],\n ['JPEGInterchangeFormatLength', 0x202],\n ['YCbCrCoefficients', 0x211],\n ['YCbCrSubSampling', 0x212],\n ['YCbCrPositioning', 0x213],\n ['ReferenceBlackWhite', 0x214],\n ['ApplicationNotes', 0x2bc],\n ['Rating', 0x4746],\n ['CFARepeatPatternDim', 0x828d],\n ['CFAPattern', 0x828e],\n ['BatteryLevel', 0x828f],\n ['Copyright', 0x8298],\n ['ExposureTime', 0x829a],\n ['FNumber', 0x829d],\n ['IPTC-NAA', 0x83bb],\n ['ExifOffset', 0x8769],\n ['InterColorProfile', 0x8773],\n ['ExposureProgram', 0x8822],\n ['SpectralSensitivity', 0x8824],\n ['GPSOffset', 0x8825],\n ['ISOSpeed', 0x8827],\n ['OECF', 0x8828],\n ['SensitivityType', 0x8830],\n ['RecommendedExposureIndex', 0x8832],\n ['ExifVersion', 0x9000],\n ['DateTimeOriginal', 0x9003],\n ['DateTimeDigitized', 0x9004],\n ['OffsetTime', 0x9010],\n ['OffsetTimeOriginal', 0x9011],\n ['OffsetTimeDigitized', 0x9012],\n ['ComponentsConfiguration', 0x9101],\n ['CompressedBitsPerPixel', 0x9102],\n ['ShutterSpeedValue', 0x9201],\n ['ApertureValue', 0x9202],\n ['BrightnessValue', 0x9203],\n ['ExposureBiasValue', 0x9204],\n ['MaxApertureValue', 0x9205],\n ['SubjectDistance', 0x9206],\n ['MeteringMode', 0x9207],\n ['LightSource', 0x9208],\n ['Flash', 0x9209],\n ['FocalLength', 0x920a],\n ['SubjectArea', 0x9214],\n ['MakerNote', 0x927c],\n ['UserComment', 0x9286],\n ['SubSecTime', 0x9290],\n ['SubSecTimeOriginal', 0x9291],\n ['SubSecTimeDigitized', 0x9292],\n ['XPTitle', 0x9c9b],\n ['XPComment', 0x9c9c],\n ['XPAuthor', 0x9c9d],\n ['XPKeywords', 0x9c9e],\n ['XPSubject', 0x9c9f],\n ['FlashPixVersion', 0xa000],\n ['ColorSpace', 0xa001],\n ['ExifImageWidth', 0xa002],\n ['ExifImageLength', 0xa003],\n ['RelatedSoundFile', 0xa004],\n ['InteroperabilityOffset', 0xa005],\n ['FlashEnergy', 0xa20b],\n ['SpatialFrequencyResponse', 0xa20c],\n ['FocalPlaneXResolution', 0xa20e],\n ['FocalPlaneYResolution', 0xa20f],\n ['FocalPlaneResolutionUnit', 0xa210],\n ['SubjectLocation', 0xa214],\n ['ExposureIndex', 0xa215],\n ['SensingMethod', 0xa217],\n ['FileSource', 0xa300],\n ['SceneType', 0xa301],\n ['CVAPattern', 0xa302],\n ['CustomRendered', 0xa401],\n ['ExposureMode', 0xa402],\n ['WhiteBalance', 0xa403],\n ['DigitalZoomRatio', 0xa404],\n ['FocalLengthIn35mmFilm', 0xa405],\n ['SceneCaptureType', 0xa406],\n ['GainControl', 0xa407],\n ['Contrast', 0xa408],\n ['Saturation', 0xa409],\n ['Sharpness', 0xa40a],\n ['DeviceSettingDescription', 0xa40b],\n ['SubjectDistanceRange', 0xa40c],\n ['ImageUniqueID', 0xa420],\n ['CameraOwnerName', 0xa430],\n ['BodySerialNumber', 0xa431],\n ['LensSpecification', 0xa432],\n ['LensMake', 0xa433],\n ['LensModel', 0xa434],\n ['LensSerialNumber', 0xa435],\n ['Gamma', 0xa500],\n ['PrintIM', 0xc4a5],\n ['Padding', 0xea1c],\n ['OffsetSchema', 0xea1d],\n ['OwnerName', 0xfde8],\n ['SerialNumber', 0xfde9],\n ['InteropIndex', 0x1],\n ['InteropVersion', 0x2],\n ['RelatedImageFileFormat', 0x1000],\n ['RelatedImageWidth', 0x1001],\n ['RelatedImageLength', 0x1002],\n ['GPSVersionID', 0x0],\n ['GPSLatitudeRef', 0x1],\n ['GPSLatitude', 0x2],\n ['GPSLongitudeRef', 0x3],\n ['GPSLongitude', 0x4],\n ['GPSAltitudeRef', 0x5],\n ['GPSAltitude', 0x6],\n ['GPSTimeStamp', 0x7],\n ['GPSSatellites', 0x8],\n ['GPSStatus', 0x9],\n ['GPSMeasureMode', 0xa],\n ['GPSDOP', 0xb],\n ['GPSSpeedRef', 0xc],\n ['GPSSpeed', 0xd],\n ['GPSTrackRef', 0xe],\n ['GPSTrack', 0xf],\n ['GPSImgDirectionRef', 0x10],\n ['GPSImgDirection', 0x11],\n ['GPSMapDatum', 0x12],\n ['GPSDestLatitudeRef', 0x13],\n ['GPSDestLatitude', 0x14],\n ['GPSDestLongitudeRef', 0x15],\n ['GPSDestLongitude', 0x16],\n ['GPSDestBearingRef', 0x17],\n ['GPSDestBearing', 0x18],\n ['GPSDestDistanceRef', 0x19],\n ['GPSDestDistance', 0x1a],\n ['GPSProcessingMethod', 0x1b],\n ['GPSAreaInformation', 0x1c],\n ['GPSDate', 0x1d],\n ['GPSDifferential', 0x1e],\n]);\n\nexport const ExifImageTags = new Map([\n [\n 0x000b,\n new ExifTag({\n name: 'ProcessingSoftware',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x00fe,\n new ExifTag({\n name: 'SubfileType',\n type: ExifValueType.long,\n }),\n ],\n [\n 0x00ff,\n new ExifTag({\n name: 'OldSubfileType',\n type: ExifValueType.long,\n }),\n ],\n [\n 0x0100,\n new ExifTag({\n name: 'ImageWidth',\n type: ExifValueType.long,\n }),\n ],\n [\n 0x0101,\n new ExifTag({\n name: 'ImageLength',\n type: ExifValueType.long,\n }),\n ],\n [\n 0x0102,\n new ExifTag({\n name: 'BitsPerSample',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x0103,\n new ExifTag({\n name: 'Compression',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x0106,\n new ExifTag({\n name: 'PhotometricInterpretation',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x0107,\n new ExifTag({\n name: 'Thresholding',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x0108,\n new ExifTag({\n name: 'CellWidth',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x0109,\n new ExifTag({\n name: 'CellLength',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x010a,\n new ExifTag({\n name: 'FillOrder',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x010d,\n new ExifTag({\n name: 'DocumentName',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x010e,\n new ExifTag({\n name: 'ImageDescription',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x010f,\n new ExifTag({\n name: 'Make',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x0110,\n new ExifTag({\n name: 'Model',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x0111,\n new ExifTag({\n name: 'StripOffsets',\n type: ExifValueType.long,\n }),\n ],\n [\n 0x0112,\n new ExifTag({\n name: 'Orientation',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x0115,\n new ExifTag({\n name: 'SamplesPerPixel',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x0116,\n new ExifTag({\n name: 'RowsPerStrip',\n type: ExifValueType.long,\n }),\n ],\n [\n 0x0117,\n new ExifTag({\n name: 'StripByteCounts',\n type: ExifValueType.long,\n }),\n ],\n [\n 0x0118,\n new ExifTag({\n name: 'MinSampleValue',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x0119,\n new ExifTag({\n name: 'MaxSampleValue',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x011a,\n new ExifTag({\n name: 'XResolution',\n type: ExifValueType.rational,\n }),\n ],\n [\n 0x011b,\n new ExifTag({\n name: 'YResolution',\n type: ExifValueType.rational,\n }),\n ],\n [\n 0x011c,\n new ExifTag({\n name: 'PlanarConfiguration',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x011d,\n new ExifTag({\n name: 'PageName',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x011e,\n new ExifTag({\n name: 'XPosition',\n type: ExifValueType.rational,\n }),\n ],\n [\n 0x011f,\n new ExifTag({\n name: 'YPosition',\n type: ExifValueType.rational,\n }),\n ],\n [\n 0x0122,\n new ExifTag({\n name: 'GrayResponseUnit',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x0123,\n new ExifTag({\n name: 'GrayResponseCurve',\n }),\n ],\n [\n 0x0124,\n new ExifTag({\n name: 'T4Options',\n }),\n ],\n [\n 0x0125,\n new ExifTag({\n name: 'T6Options',\n }),\n ],\n [\n 0x0128,\n new ExifTag({\n name: 'ResolutionUnit',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x0129,\n new ExifTag({\n name: 'PageNumber',\n type: ExifValueType.short,\n count: 2,\n }),\n ],\n [\n 0x012c,\n new ExifTag({\n name: 'ColorResponseUnit',\n }),\n ],\n [\n 0x012d,\n new ExifTag({\n name: 'TransferFunction',\n type: ExifValueType.short,\n count: 768,\n }),\n ],\n [\n 0x0131,\n new ExifTag({\n name: 'Software',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x0132,\n new ExifTag({\n name: 'DateTime',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x013b,\n new ExifTag({\n name: 'Artist',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x013c,\n new ExifTag({\n name: 'HostComputer',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x013d,\n new ExifTag({\n name: 'Predictor',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x013e,\n new ExifTag({\n name: 'WhitePoint',\n type: ExifValueType.rational,\n count: 2,\n }),\n ],\n [\n 0x013f,\n new ExifTag({\n name: 'PrimaryChromaticities',\n type: ExifValueType.rational,\n count: 6,\n }),\n ],\n [\n 0x0140,\n new ExifTag({\n name: 'ColorMap',\n }),\n ],\n [\n 0x0141,\n new ExifTag({\n name: 'HalftoneHints',\n type: ExifValueType.short,\n count: 2,\n }),\n ],\n [\n 0x0142,\n new ExifTag({\n name: 'TileWidth',\n type: ExifValueType.long,\n }),\n ],\n [\n 0x0143,\n new ExifTag({\n name: 'TileLength',\n type: ExifValueType.long,\n }),\n ],\n [\n 0x0144,\n new ExifTag({\n name: 'TileOffsets',\n }),\n ],\n [\n 0x0145,\n new ExifTag({\n name: 'TileByteCounts',\n }),\n ],\n [\n 0x0146,\n new ExifTag({\n name: 'BadFaxLines',\n }),\n ],\n [\n 0x0147,\n new ExifTag({\n name: 'CleanFaxData',\n }),\n ],\n [\n 0x0148,\n new ExifTag({\n name: 'ConsecutiveBadFaxLines',\n }),\n ],\n [\n 0x014c,\n new ExifTag({\n name: 'InkSet',\n }),\n ],\n [\n 0x014d,\n new ExifTag({\n name: 'InkNames',\n }),\n ],\n [\n 0x014e,\n new ExifTag({\n name: 'NumberofInks',\n }),\n ],\n [\n 0x0150,\n new ExifTag({\n name: 'DotRange',\n }),\n ],\n [\n 0x0151,\n new ExifTag({\n name: 'TargetPrinter',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x0152,\n new ExifTag({\n name: 'ExtraSamples',\n }),\n ],\n [\n 0x0153,\n new ExifTag({\n name: 'SampleFormat',\n }),\n ],\n [\n 0x0154,\n new ExifTag({\n name: 'SMinSampleValue',\n }),\n ],\n [\n 0x0155,\n new ExifTag({\n name: 'SMaxSampleValue',\n }),\n ],\n [\n 0x0156,\n new ExifTag({\n name: 'TransferRange',\n }),\n ],\n [\n 0x0157,\n new ExifTag({\n name: 'ClipPath',\n }),\n ],\n [\n 0x0200,\n new ExifTag({\n name: 'JPEGProc',\n }),\n ],\n [\n 0x0201,\n new ExifTag({\n name: 'JPEGInterchangeFormat',\n }),\n ],\n [\n 0x0202,\n new ExifTag({\n name: 'JPEGInterchangeFormatLength',\n }),\n ],\n [\n 0x0211,\n new ExifTag({\n name: 'YCbCrCoefficients',\n type: ExifValueType.rational,\n count: 3,\n }),\n ],\n [\n 0x0212,\n new ExifTag({\n name: 'YCbCrSubSampling',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x0213,\n new ExifTag({\n name: 'YCbCrPositioning',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x0214,\n new ExifTag({\n name: 'ReferenceBlackWhite',\n type: ExifValueType.rational,\n count: 6,\n }),\n ],\n // XPM Info\n [\n 0x02bc,\n new ExifTag({\n name: 'ApplicationNotes',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x4746,\n new ExifTag({\n name: 'Rating',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x828d,\n new ExifTag({\n name: 'CFARepeatPatternDim',\n }),\n ],\n [\n 0x828e,\n new ExifTag({\n name: 'CFAPattern',\n }),\n ],\n [\n 0x828f,\n new ExifTag({\n name: 'BatteryLevel',\n }),\n ],\n [\n 0x8298,\n new ExifTag({\n name: 'Copyright',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x829a,\n new ExifTag({\n name: 'ExposureTime',\n type: ExifValueType.rational,\n }),\n ],\n [\n 0x829d,\n new ExifTag({\n name: 'FNumber',\n type: ExifValueType.rational,\n }),\n ],\n [\n 0x83bb,\n new ExifTag({\n name: 'IPTC-NAA',\n type: ExifValueType.long,\n }),\n ],\n // Exif Tags\n [\n 0x8769,\n new ExifTag({\n name: 'ExifOffset',\n }),\n ],\n [\n 0x8773,\n new ExifTag({\n name: 'InterColorProfile',\n }),\n ],\n [\n 0x8822,\n new ExifTag({\n name: 'ExposureProgram',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x8824,\n new ExifTag({\n name: 'SpectralSensitivity',\n type: ExifValueType.ascii,\n }),\n ],\n // GPS tags\n [\n 0x8825,\n new ExifTag({\n name: 'GPSOffset',\n }),\n ],\n [\n 0x8827,\n new ExifTag({\n name: 'ISOSpeed',\n type: ExifValueType.long,\n }),\n ],\n [\n 0x8828,\n new ExifTag({\n name: 'OECF',\n }),\n ],\n [\n 0x8830,\n new ExifTag({\n name: 'SensitivityType',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x8832,\n new ExifTag({\n name: 'RecommendedExposureIndex',\n type: ExifValueType.long,\n }),\n ],\n [\n 0x8833,\n new ExifTag({\n name: 'ISOSpeed',\n type: ExifValueType.long,\n }),\n ],\n [\n 0x9000,\n new ExifTag({\n name: 'ExifVersion',\n type: ExifValueType.undefined,\n }),\n ],\n [\n 0x9003,\n new ExifTag({\n name: 'DateTimeOriginal',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x9004,\n new ExifTag({\n name: 'DateTimeDigitized',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x9010,\n new ExifTag({\n name: 'OffsetTime',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x9011,\n new ExifTag({\n name: 'OffsetTimeOriginal',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x9012,\n new ExifTag({\n name: 'OffsetTimeDigitized',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x9101,\n new ExifTag({\n name: 'ComponentsConfiguration',\n }),\n ],\n [\n 0x9102,\n new ExifTag({\n name: 'CompressedBitsPerPixel',\n }),\n ],\n [\n 0x9201,\n new ExifTag({\n name: 'ShutterSpeedValue',\n }),\n ],\n [\n 0x9202,\n new ExifTag({\n name: 'ApertureValue',\n }),\n ],\n [\n 0x9203,\n new ExifTag({\n name: 'BrightnessValue',\n }),\n ],\n [\n 0x9204,\n new ExifTag({\n name: 'ExposureBiasValue',\n }),\n ],\n [\n 0x9205,\n new ExifTag({\n name: 'MaxApertureValue',\n }),\n ],\n [\n 0x9206,\n new ExifTag({\n name: 'SubjectDistance',\n }),\n ],\n [\n 0x9207,\n new ExifTag({\n name: 'MeteringMode',\n }),\n ],\n [\n 0x9208,\n new ExifTag({\n name: 'LightSource',\n }),\n ],\n [\n 0x9209,\n new ExifTag({\n name: 'Flash',\n }),\n ],\n [\n 0x920a,\n new ExifTag({\n name: 'FocalLength',\n }),\n ],\n [\n 0x9214,\n new ExifTag({\n name: 'SubjectArea',\n }),\n ],\n [\n 0x927c,\n new ExifTag({\n name: 'MakerNote',\n }),\n ],\n [\n 0x9286,\n new ExifTag({\n name: 'UserComment',\n }),\n ],\n [\n 0x9290,\n new ExifTag({\n name: 'SubSecTime',\n }),\n ],\n [\n 0x9291,\n new ExifTag({\n name: 'SubSecTimeOriginal',\n }),\n ],\n [\n 0x9292,\n new ExifTag({\n name: 'SubSecTimeDigitized',\n }),\n ],\n [\n 0x9c9b,\n new ExifTag({\n name: 'XPTitle',\n }),\n ],\n [\n 0x9c9c,\n new ExifTag({\n name: 'XPComment',\n }),\n ],\n [\n 0x9c9d,\n new ExifTag({\n name: 'XPAuthor',\n }),\n ],\n [\n 0x9c9e,\n new ExifTag({\n name: 'XPKeywords',\n }),\n ],\n [\n 0x9c9f,\n new ExifTag({\n name: 'XPSubject',\n }),\n ],\n [\n 0xa000,\n new ExifTag({\n name: 'FlashPixVersion',\n }),\n ],\n [\n 0xa001,\n new ExifTag({\n name: 'ColorSpace',\n type: ExifValueType.short,\n }),\n ],\n [\n 0xa002,\n new ExifTag({\n name: 'ExifImageWidth',\n type: ExifValueType.short,\n }),\n ],\n [\n 0xa003,\n new ExifTag({\n name: 'ExifImageLength',\n type: ExifValueType.short,\n }),\n ],\n [\n 0xa004,\n new ExifTag({\n name: 'RelatedSoundFile',\n }),\n ],\n [\n 0xa005,\n new ExifTag({\n name: 'InteroperabilityOffset',\n }),\n ],\n // [0x920B in TIFF/EP\n [\n 0xa20b,\n new ExifTag({\n name: 'FlashEnergy',\n }),\n ],\n [\n 0xa20c,\n new ExifTag({\n name: 'SpatialFrequencyResponse',\n }),\n ],\n [\n 0xa20e,\n new ExifTag({\n name: 'FocalPlaneXResolution',\n }),\n ],\n [\n 0xa20f,\n new ExifTag({\n name: 'FocalPlaneYResolution',\n }),\n ],\n [\n 0xa210,\n new ExifTag({\n name: 'FocalPlaneResolutionUnit',\n }),\n ],\n [\n 0xa214,\n new ExifTag({\n name: 'SubjectLocation',\n }),\n ],\n [\n 0xa215,\n new ExifTag({\n name: 'ExposureIndex',\n }),\n ],\n [\n 0xa217,\n new ExifTag({\n name: 'SensingMethod',\n }),\n ],\n [\n 0xa300,\n new ExifTag({\n name: 'FileSource',\n }),\n ],\n [\n 0xa301,\n new ExifTag({\n name: 'SceneType',\n }),\n ],\n [\n 0xa302,\n new ExifTag({\n name: 'CVAPattern',\n }),\n ],\n [\n 0xa401,\n new ExifTag({\n name: 'CustomRendered',\n }),\n ],\n [\n 0xa402,\n new ExifTag({\n name: 'ExposureMode',\n }),\n ],\n [\n 0xa403,\n new ExifTag({\n name: 'WhiteBalance',\n }),\n ],\n [\n 0xa404,\n new ExifTag({\n name: 'DigitalZoomRatio',\n }),\n ],\n [\n 0xa405,\n new ExifTag({\n name: 'FocalLengthIn35mmFilm',\n }),\n ],\n [\n 0xa406,\n new ExifTag({\n name: 'SceneCaptureType',\n }),\n ],\n [\n 0xa407,\n new ExifTag({\n name: 'GainControl',\n }),\n ],\n [\n 0xa408,\n new ExifTag({\n name: 'Contrast',\n }),\n ],\n [\n 0xa409,\n new ExifTag({\n name: 'Saturation',\n }),\n ],\n [\n 0xa40a,\n new ExifTag({\n name: 'Sharpness',\n }),\n ],\n [\n 0xa40b,\n new ExifTag({\n name: 'DeviceSettingDescription',\n }),\n ],\n [\n 0xa40c,\n new ExifTag({\n name: 'SubjectDistanceRange',\n }),\n ],\n [\n 0xa420,\n new ExifTag({\n name: 'ImageUniqueID',\n }),\n ],\n [\n 0xa430,\n new ExifTag({\n name: 'CameraOwnerName',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0xa431,\n new ExifTag({\n name: 'BodySerialNumber',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0xa432,\n new ExifTag({\n name: 'LensSpecification',\n }),\n ],\n [\n 0xa433,\n new ExifTag({\n name: 'LensMake',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0xa434,\n new ExifTag({\n name: 'LensModel',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0xa435,\n new ExifTag({\n name: 'LensSerialNumber',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0xa500,\n new ExifTag({\n name: 'Gamma',\n type: ExifValueType.rational,\n }),\n ],\n [\n 0xc4a5,\n new ExifTag({\n name: 'PrintIM',\n }),\n ],\n [\n 0xea1c,\n new ExifTag({\n name: 'Padding',\n }),\n ],\n [\n 0xea1d,\n new ExifTag({\n name: 'OffsetSchema',\n }),\n ],\n [\n 0xfde8,\n new ExifTag({\n name: 'OwnerName',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0xfde9,\n new ExifTag({\n name: 'SerialNumber',\n type: ExifValueType.ascii,\n }),\n ],\n]);\n\nexport const ExifInteropTags = new Map([\n [\n 0x0001,\n new ExifTag({\n name: 'InteropIndex',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x0002,\n new ExifTag({\n name: 'InteropVersion',\n type: ExifValueType.undefined,\n }),\n ],\n [\n 0x1000,\n new ExifTag({\n name: 'RelatedImageFileFormat',\n type: ExifValueType.ascii,\n }),\n ],\n [\n 0x1001,\n new ExifTag({\n name: 'RelatedImageWidth',\n type: ExifValueType.short,\n }),\n ],\n [\n 0x1002,\n new ExifTag({\n name: 'RelatedImageLength',\n type: ExifValueType.short,\n }),\n ],\n]);\n\nexport const ExifGpsTags = new Map([\n [\n 0x0000,\n new ExifTag({\n name: 'GPSVersionID',\n }),\n ],\n [\n 0x0001,\n new ExifTag({\n name: 'GPSLatitudeRef',\n }),\n ],\n [\n 0x0002,\n new ExifTag({\n name: 'GPSLatitude',\n }),\n ],\n [\n 0x0003,\n new ExifTag({\n name: 'GPSLongitudeRef',\n }),\n ],\n [\n 0x0004,\n new ExifTag({\n name: 'GPSLongitude',\n }),\n ],\n [\n 0x0005,\n new ExifTag({\n name: 'GPSAltitudeRef',\n }),\n ],\n [\n 0x0006,\n new ExifTag({\n name: 'GPSAltitude',\n }),\n ],\n [\n 0x0007,\n new ExifTag({\n name: 'GPSTimeStamp',\n }),\n ],\n [\n 0x0008,\n new ExifTag({\n name: 'GPSSatellites',\n }),\n ],\n [\n 0x0009,\n new ExifTag({\n name: 'GPSStatus',\n }),\n ],\n [\n 0x000a,\n new ExifTag({\n name: 'GPSMeasureMode',\n }),\n ],\n [\n 0x000b,\n new ExifTag({\n name: 'GPSDOP',\n }),\n ],\n [\n 0x000c,\n new ExifTag({\n name: 'GPSSpeedRef',\n }),\n ],\n [\n 0x000d,\n new ExifTag({\n name: 'GPSSpeed',\n }),\n ],\n [\n 0x000e,\n new ExifTag({\n name: 'GPSTrackRef',\n }),\n ],\n [\n 0x000f,\n new ExifTag({\n name: 'GPSTrack',\n }),\n ],\n [\n 0x0010,\n new ExifTag({\n name: 'GPSImgDirectionRef',\n }),\n ],\n [\n 0x0011,\n new ExifTag({\n name: 'GPSImgDirection',\n }),\n ],\n [\n 0x0012,\n new ExifTag({\n name: 'GPSMapDatum',\n }),\n ],\n [\n 0x0013,\n new ExifTag({\n name: 'GPSDestLatitudeRef',\n }),\n ],\n [\n 0x0014,\n new ExifTag({\n name: 'GPSDestLatitude',\n }),\n ],\n [\n 0x0015,\n new ExifTag({\n name: 'GPSDestLongitudeRef',\n }),\n ],\n [\n 0x0016,\n new ExifTag({\n name: 'GPSDestLongitude',\n }),\n ],\n [\n 0x0017,\n new ExifTag({\n name: 'GPSDestBearingRef',\n }),\n ],\n [\n 0x0018,\n new ExifTag({\n name: 'GPSDestBearing',\n }),\n ],\n [\n 0x0019,\n new ExifTag({\n name: 'GPSDestDistanceRef',\n }),\n ],\n [\n 0x001a,\n new ExifTag({\n name: 'GPSDestDistance',\n }),\n ],\n [\n 0x001b,\n new ExifTag({\n name: 'GPSProcessingMethod',\n }),\n ],\n [\n 0x001c,\n new ExifTag({\n name: 'GPSAreaInformation',\n }),\n ],\n [\n 0x001d,\n new ExifTag({\n name: 'GPSDate',\n }),\n ],\n [\n 0x001e,\n new ExifTag({\n name: 'GPSDifferential',\n }),\n ],\n]);\n", "/** @format */\n\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { Rational } from '../../common/rational';\nimport { ImageError } from '../../error/image-error';\nimport {\n ExifValueType,\n getExifValueTypeSize,\n getExifValueTypeString,\n} from '../exif-value-type';\n\nexport abstract class ExifValue {\n public get type(): ExifValueType {\n return ExifValueType.none;\n }\n\n public get length(): number {\n return 0;\n }\n\n public get dataSize(): number {\n return getExifValueTypeSize(this.type, this.length);\n }\n\n public get typeString(): string {\n return getExifValueTypeString(this.type);\n }\n\n public toBool(_index?: number): boolean {\n return false;\n }\n\n public toInt(_index?: number): number {\n return 0;\n }\n\n public toDouble(_index?: number): number {\n return 0;\n }\n\n public toRational(_index?: number): Rational {\n return new Rational(0, 1);\n }\n\n public toString(): string {\n return '';\n }\n\n public write(_out: OutputBuffer): void {}\n\n public setBool(_v: boolean, _index?: number): void {}\n\n public setInt(_v: number, _index?: number): void {}\n\n public setDouble(_v: number, _index?: number): void {}\n\n public setRational(\n _numerator: number,\n _denomitator: number,\n _index?: number\n ): void {}\n\n public setString(_v: string): void {}\n\n public equalsTo(_other: ExifValue): boolean {\n return false;\n }\n\n public clone(): ExifValue {\n throw new ImageError('Cannot be copied.');\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { TextCodec } from '../../common/text-codec';\nimport { ExifValue } from './exif-value';\nimport { ExifValueType } from '../exif-value-type';\n\nexport class ExifAsciiValue extends ExifValue {\n private value: string;\n\n public get type(): ExifValueType {\n return ExifValueType.ascii;\n }\n\n public get length(): number {\n return this.value.length;\n }\n\n constructor(value: number[] | string) {\n super();\n if (typeof value === 'string') {\n this.value = value;\n } else {\n this.value = String.fromCharCode(...value);\n }\n }\n\n public static fromData(data: InputBuffer, length: number) {\n const value = length > 0 ? data.readString(length - 1) : data.readString();\n return new ExifAsciiValue(value);\n }\n\n public toData(): Uint8Array {\n return TextCodec.getCodePoints(this.value);\n }\n\n public toString(): string {\n return this.value;\n }\n\n public write(out: OutputBuffer): void {\n const bytes = TextCodec.getCodePoints(this.value);\n out.writeBytes(bytes);\n }\n\n public setString(v: string): void {\n this.value = v;\n }\n\n public equalsTo(other: unknown): boolean {\n return other instanceof ExifAsciiValue && this.length === other.length;\n }\n\n public clone(): ExifValue {\n return new ExifAsciiValue(this.value);\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { ExifValue } from './exif-value';\nimport { ExifValueType } from '../exif-value-type';\n\nexport class ExifByteValue extends ExifValue {\n private value: Uint8Array;\n\n public get type(): ExifValueType {\n return ExifValueType.byte;\n }\n\n public get length(): number {\n return this.value.length;\n }\n\n constructor(value: Uint8Array | number) {\n super();\n if (typeof value === 'number') {\n this.value = new Uint8Array(1);\n this.value[0] = value;\n } else {\n this.value = value;\n }\n }\n\n public static fromData(data: InputBuffer, offset?: number, length?: number) {\n const array = data.toUint8Array(offset, length);\n return new ExifByteValue(array);\n }\n\n public toInt(index = 0): number {\n return this.value[index];\n }\n\n public toData(): Uint8Array {\n return this.value;\n }\n\n public toString(): string {\n return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`;\n }\n\n public write(out: OutputBuffer): void {\n out.writeBytes(this.value);\n }\n\n public setInt(v: number, index = 0): void {\n this.value[index] = v;\n }\n\n public equalsTo(other: unknown): boolean {\n return other instanceof ExifByteValue && this.length === other.length;\n }\n\n public clone(): ExifValue {\n return new ExifByteValue(this.value);\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { ExifValue } from './exif-value';\nimport { ExifValueType } from '../exif-value-type';\n\nexport class ExifDoubleValue extends ExifValue {\n private value: Float64Array;\n\n public get type(): ExifValueType {\n return ExifValueType.double;\n }\n\n public get length(): number {\n return this.value.length;\n }\n\n constructor(value: Float64Array | number) {\n super();\n if (typeof value === 'number') {\n this.value = new Float64Array(1);\n this.value[0] = value;\n } else {\n this.value = value;\n }\n }\n\n public static fromData(data: InputBuffer, length: number) {\n const array = new Float64Array(length);\n for (let i = 0; i < length; ++i) {\n array[i] = data.readFloat64();\n }\n return new ExifDoubleValue(array);\n }\n\n public toDouble(index = 0): number {\n return this.value[index];\n }\n\n public toData(): Uint8Array {\n return new Uint8Array(this.value.buffer);\n }\n\n public toString(): string {\n return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`;\n }\n\n public write(out: OutputBuffer): void {\n for (let i = 0, l = this.value.length; i < l; ++i) {\n out.writeFloat64(this.value[i]);\n }\n }\n\n public setDouble(v: number, index = 0): void {\n this.value[index] = v;\n }\n\n public equalsTo(other: unknown): boolean {\n return other instanceof ExifDoubleValue && this.length === other.length;\n }\n\n public clone(): ExifValue {\n return new ExifDoubleValue(this.value);\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { ExifValue } from './exif-value';\nimport { ExifValueType } from '../exif-value-type';\n\nexport class ExifLongValue extends ExifValue {\n private value: Uint32Array;\n\n public get type(): ExifValueType {\n return ExifValueType.long;\n }\n\n public get length(): number {\n return this.value.length;\n }\n\n constructor(value: Uint32Array | number) {\n super();\n if (typeof value === 'number') {\n this.value = new Uint32Array(1);\n this.value[0] = value;\n } else {\n this.value = value;\n }\n }\n\n public static fromData(data: InputBuffer, length: number) {\n const array = new Uint32Array(length);\n for (let i = 0; i < length; ++i) {\n array[i] = data.readUint32();\n }\n return new ExifLongValue(array);\n }\n\n public toInt(index = 0): number {\n return this.value[index];\n }\n\n public toData(): Uint8Array {\n return new Uint8Array(this.value.buffer);\n }\n\n public toString(): string {\n return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`;\n }\n\n public write(out: OutputBuffer): void {\n for (let i = 0, l = this.value.length; i < l; ++i) {\n out.writeUint32(this.value[i]);\n }\n }\n\n public setInt(v: number, index = 0): void {\n this.value[index] = v;\n }\n\n public equalsTo(other: unknown): boolean {\n return other instanceof ExifLongValue && this.length === other.length;\n }\n\n public clone(): ExifValue {\n return new ExifLongValue(this.value);\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { ExifValue } from './exif-value';\nimport { ExifValueType } from '../exif-value-type';\nimport { Rational } from '../../common/rational';\n\nexport class ExifRationalValue extends ExifValue {\n private value: Rational[];\n\n public get type(): ExifValueType {\n return ExifValueType.rational;\n }\n\n public get length(): number {\n return this.value.length;\n }\n\n constructor(value: Rational[] | Rational) {\n super();\n if (value instanceof Rational) {\n this.value = [value];\n } else {\n this.value = value;\n }\n }\n\n public static fromData(data: InputBuffer, length: number) {\n const array = new Array();\n for (let i = 0; i < length; i++) {\n const r = new Rational(data.readUint32(), data.readUint32());\n array.push(r);\n }\n return new ExifRationalValue(array);\n }\n\n public static from(other: Rational) {\n const r = new Rational(other.numerator, other.denominator);\n return new ExifRationalValue(r);\n }\n\n public toInt(index = 0): number {\n return this.value[index].asInt;\n }\n\n public toDouble(index = 0): number {\n return this.value[index].asDouble;\n }\n\n public toRational(index = 0): Rational {\n return this.value[index];\n }\n\n public toString(): string {\n return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`;\n }\n\n public write(out: OutputBuffer): void {\n for (const v of this.value) {\n out.writeUint32(v.numerator);\n out.writeUint32(v.denominator);\n }\n }\n\n public setRational(numerator: number, denomitator: number, index = 0): void {\n this.value[index] = new Rational(numerator, denomitator);\n }\n\n public equalsTo(other: unknown): boolean {\n return other instanceof ExifRationalValue && this.length === other.length;\n }\n\n public clone(): ExifValue {\n return new ExifRationalValue(this.value);\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { ExifValue } from './exif-value';\nimport { ExifValueType } from '../exif-value-type';\n\nexport class ExifSByteValue extends ExifValue {\n private value: Int8Array;\n\n public get type(): ExifValueType {\n return ExifValueType.sbyte;\n }\n\n public get length(): number {\n return this.value.length;\n }\n\n constructor(value: Int8Array | number) {\n super();\n if (typeof value === 'number') {\n this.value = new Int8Array(1);\n this.value[0] = value;\n } else {\n this.value = value;\n }\n }\n\n public static fromData(data: InputBuffer, offset?: number, length?: number) {\n const array = new Int8Array(\n new Int8Array(data.toUint8Array(offset, length).buffer)\n );\n return new ExifSByteValue(array);\n }\n\n public toInt(index = 0): number {\n return this.value[index];\n }\n\n public toData(): Uint8Array {\n return new Uint8Array(this.value.buffer);\n }\n\n public toString(): string {\n return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`;\n }\n\n public write(out: OutputBuffer): void {\n out.writeBytes(new Uint8Array(this.value.buffer));\n }\n\n public setInt(v: number, index = 0): void {\n this.value[index] = v;\n }\n\n public equalsTo(other: unknown): boolean {\n return other instanceof ExifSByteValue && this.length === other.length;\n }\n\n public clone(): ExifValue {\n return new ExifSByteValue(this.value);\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { ExifValue } from './exif-value';\nimport { ExifValueType } from '../exif-value-type';\n\nexport class ExifShortValue extends ExifValue {\n private value: Uint16Array;\n\n public get type(): ExifValueType {\n return ExifValueType.short;\n }\n\n public get length(): number {\n return this.value.length;\n }\n\n constructor(value: Uint16Array | number) {\n super();\n if (typeof value === 'number') {\n this.value = new Uint16Array(1);\n this.value[0] = value;\n } else {\n this.value = value;\n }\n }\n\n public static fromData(data: InputBuffer, length: number) {\n const array = new Uint16Array(length);\n for (let i = 0; i < length; ++i) {\n array[i] = data.readUint16();\n }\n return new ExifShortValue(array);\n }\n\n public toInt(index = 0): number {\n return this.value[index];\n }\n\n public toString(): string {\n return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`;\n }\n\n public write(out: OutputBuffer): void {\n for (let i = 0, l = this.value.length; i < l; ++i) {\n out.writeUint16(this.value[i]);\n }\n }\n\n public setInt(v: number, index = 0): void {\n this.value[index] = v;\n }\n\n public equalsTo(other: unknown): boolean {\n return other instanceof ExifShortValue && this.length === other.length;\n }\n\n public clone(): ExifValue {\n return new ExifShortValue(this.value);\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { ExifValue } from './exif-value';\nimport { ExifValueType } from '../exif-value-type';\n\nexport class ExifSingleValue extends ExifValue {\n private value: Float32Array;\n\n public get type(): ExifValueType {\n return ExifValueType.single;\n }\n\n public get length(): number {\n return this.value.length;\n }\n\n constructor(value: Float32Array | number) {\n super();\n if (typeof value === 'number') {\n this.value = new Float32Array(1);\n this.value[0] = value;\n } else {\n this.value = value;\n }\n }\n\n public static fromData(data: InputBuffer, length: number) {\n const array = new Float32Array(length);\n for (let i = 0; i < length; ++i) {\n array[i] = data.readFloat32();\n }\n return new ExifSingleValue(array);\n }\n\n public toDouble(index = 0): number {\n return this.value[index];\n }\n\n public toData(): Uint8Array {\n return new Uint8Array(this.value.buffer);\n }\n\n public toString(): string {\n return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`;\n }\n\n public write(out: OutputBuffer): void {\n for (let i = 0, l = this.value.length; i < l; ++i) {\n out.writeFloat32(this.value[i]);\n }\n }\n\n public setDouble(v: number, index = 0): void {\n this.value[index] = v;\n }\n\n public equalsTo(other: unknown): boolean {\n return other instanceof ExifSingleValue && this.length === other.length;\n }\n\n public clone(): ExifValue {\n return new ExifSingleValue(this.value);\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { ExifValue } from './exif-value';\nimport { ExifValueType } from '../exif-value-type';\nimport { BitOperators } from '../../common/bit-operators';\n\nexport class ExifSLongValue extends ExifValue {\n private value: Int32Array;\n\n public get type(): ExifValueType {\n return ExifValueType.slong;\n }\n\n public get length(): number {\n return this.value.length;\n }\n\n constructor(value: Int32Array | number) {\n super();\n if (typeof value === 'number') {\n this.value = new Int32Array(1);\n this.value[0] = value;\n } else {\n this.value = value;\n }\n }\n\n public static fromData(data: InputBuffer, length: number) {\n const array = new Int32Array(length);\n for (let i = 0; i < length; ++i) {\n array[i] = data.readInt32();\n }\n return new ExifSLongValue(array);\n }\n\n public toInt(index = 0): number {\n return this.value[index];\n }\n\n public toData(): Uint8Array {\n return new Uint8Array(this.value.buffer);\n }\n\n public toString(): string {\n return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`;\n }\n\n public write(out: OutputBuffer): void {\n for (let i = 0, l = this.value.length; i < l; ++i) {\n out.writeUint32(BitOperators.toUint32(this.value[i]));\n }\n }\n\n public setInt(v: number, index = 0): void {\n this.value[index] = v;\n }\n\n public equalsTo(other: unknown): boolean {\n return other instanceof ExifSLongValue && this.length === other.length;\n }\n\n public clone(): ExifValue {\n return new ExifSLongValue(this.value);\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { ExifValue } from './exif-value';\nimport { ExifValueType } from '../exif-value-type';\nimport { BitOperators } from '../../common/bit-operators';\nimport { Rational } from '../../common/rational';\n\nexport class ExifSRationalValue extends ExifValue {\n private value: Rational[];\n\n public get type(): ExifValueType {\n return ExifValueType.srational;\n }\n\n public get length(): number {\n return this.value.length;\n }\n\n constructor(value: Rational[] | Rational) {\n super();\n if (value instanceof Rational) {\n this.value = [value];\n } else {\n this.value = value;\n }\n }\n\n public static fromData(data: InputBuffer, length: number) {\n const array = new Array();\n for (let i = 0; i < length; i++) {\n const r = new Rational(data.readInt32(), data.readInt32());\n array.push(r);\n }\n return new ExifSRationalValue(array);\n }\n\n public static from(other: Rational) {\n const r = new Rational(other.numerator, other.denominator);\n return new ExifSRationalValue(r);\n }\n\n public toInt(index = 0): number {\n return this.value[index].asInt;\n }\n\n public toDouble(index = 0): number {\n return this.value[index].asDouble;\n }\n\n public toRational(index = 0): Rational {\n return this.value[index];\n }\n\n public toString(): string {\n return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`;\n }\n\n public write(out: OutputBuffer): void {\n for (const v of this.value) {\n out.writeUint32(BitOperators.toUint32(v.numerator));\n out.writeUint32(BitOperators.toUint32(v.denominator));\n }\n }\n\n public setRational(numerator: number, denomitator: number, index = 0): void {\n this.value[index] = new Rational(numerator, denomitator);\n }\n\n public equalsTo(other: unknown): boolean {\n return other instanceof ExifSRationalValue && this.length === other.length;\n }\n\n public clone(): ExifValue {\n return new ExifSRationalValue(this.value);\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { ExifValue } from './exif-value';\nimport { ExifValueType } from '../exif-value-type';\n\nexport class ExifSShortValue extends ExifValue {\n private value: Int16Array;\n\n public get type(): ExifValueType {\n return ExifValueType.sshort;\n }\n\n public get length(): number {\n return this.value.length;\n }\n\n constructor(value: Int16Array | number) {\n super();\n if (typeof value === 'number') {\n this.value = new Int16Array(1);\n this.value[0] = value;\n } else {\n this.value = value;\n }\n }\n\n public static fromData(data: InputBuffer, length: number) {\n const array = new Int16Array(length);\n for (let i = 0; i < length; ++i) {\n array[i] = data.readInt16();\n }\n return new ExifSShortValue(array);\n }\n\n public toInt(index = 0): number {\n return this.value[index];\n }\n\n public toData(): Uint8Array {\n return new Uint8Array(this.value.buffer);\n }\n\n public toString(): string {\n return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`;\n }\n\n public write(out: OutputBuffer): void {\n const v = new Int16Array(1);\n const vb = new Uint16Array(v.buffer);\n for (let i = 0, l = this.value.length; i < l; ++i) {\n v[0] = this.value[i];\n out.writeUint16(vb[0]);\n }\n }\n\n public setInt(v: number, index = 0): void {\n this.value[index] = v;\n }\n\n public equalsTo(other: unknown): boolean {\n return other instanceof ExifSShortValue && this.length === other.length;\n }\n\n public clone(): ExifValue {\n return new ExifSShortValue(this.value);\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { ExifValue } from './exif-value';\nimport { ExifValueType } from '../exif-value-type';\n\nexport class ExifUndefinedValue extends ExifValue {\n private value: Uint8Array;\n\n public get type(): ExifValueType {\n return ExifValueType.undefined;\n }\n\n public get length(): number {\n return this.value.length;\n }\n\n constructor(value: Uint8Array | number) {\n super();\n if (typeof value === 'number') {\n this.value = new Uint8Array(1);\n this.value[0] = value;\n } else {\n this.value = value;\n }\n }\n\n public static fromData(data: InputBuffer, offset?: number, length?: number) {\n const array = new Uint8Array(data.toUint8Array(offset, length));\n return new ExifUndefinedValue(array);\n }\n\n public toData(): Uint8Array {\n return this.value;\n }\n\n public toString(): string {\n return '';\n }\n\n public write(out: OutputBuffer): void {\n out.writeBytes(this.value);\n }\n\n public equalsTo(other: unknown): boolean {\n return other instanceof ExifUndefinedValue && this.length === other.length;\n }\n\n public clone(): ExifValue {\n return new ExifUndefinedValue(this.value);\n }\n}\n", "/** @format */\n\nimport { Rational } from '../common/rational';\nimport { ExifIFDContainer } from './exif-ifd-container';\nimport { ExifImageTags, ExifTagNameToID } from './exif-tag';\nimport { ExifValueType } from './exif-value-type';\nimport { ExifAsciiValue } from './exif-value/exif-ascii-value';\nimport { ExifByteValue } from './exif-value/exif-byte-value';\nimport { ExifDoubleValue } from './exif-value/exif-double-value';\nimport { ExifLongValue } from './exif-value/exif-long-value';\nimport { ExifRationalValue } from './exif-value/exif-rational-value';\nimport { ExifSByteValue } from './exif-value/exif-sbyte-value';\nimport { ExifShortValue } from './exif-value/exif-short-value';\nimport { ExifSingleValue } from './exif-value/exif-single-value';\nimport { ExifSLongValue } from './exif-value/exif-slong-value';\nimport { ExifSRationalValue } from './exif-value/exif-srational-value';\nimport { ExifSShortValue } from './exif-value/exif-sshort-value';\nimport { ExifUndefinedValue } from './exif-value/exif-undefined-value';\nimport { ExifValue } from './exif-value/exif-value';\n\nexport class ExifIFD {\n private readonly data = new Map();\n\n private readonly _sub = new ExifIFDContainer();\n public get sub(): ExifIFDContainer {\n return this._sub;\n }\n\n public get keys(): IterableIterator {\n return this.data.keys();\n }\n\n public get values(): IterableIterator {\n return this.data.values();\n }\n\n public get size(): number {\n return this.data.size;\n }\n\n public get isEmpty(): boolean {\n return this.data.size === 0 && this._sub.isEmpty;\n }\n\n public get hasImageDescription(): boolean {\n return this.data.has(0x010e);\n }\n\n public get imageDescription(): string | undefined {\n return this.data.get(0x010e)?.toString();\n }\n\n public set imageDescription(v: string | undefined) {\n if (v === undefined) {\n this.data.delete(0x010e);\n } else {\n this.data.set(0x010e, new ExifAsciiValue(v));\n }\n }\n\n public get hasMake(): boolean {\n return this.data.has(0x010f);\n }\n\n public get make(): string | undefined {\n return this.data.get(0x010f)?.toString();\n }\n\n public set make(v: string | undefined) {\n if (v === undefined) {\n this.data.delete(0x010f);\n } else {\n this.data.set(0x010f, new ExifAsciiValue(v));\n }\n }\n\n public get hasModel(): boolean {\n return this.data.has(0x0110);\n }\n\n public get model(): string | undefined {\n return this.data.get(0x0110)?.toString();\n }\n\n public set model(v: string | undefined) {\n if (v === undefined) {\n this.data.delete(0x0110);\n } else {\n this.data.set(0x0110, new ExifAsciiValue(v));\n }\n }\n\n public get hasOrientation(): boolean {\n return this.data.has(0x0112);\n }\n\n public get orientation(): number | undefined {\n return this.data.get(0x0112)?.toInt();\n }\n\n public set orientation(v: number | undefined) {\n if (v === undefined) {\n this.data.delete(0x0112);\n } else {\n this.data.set(0x0112, new ExifShortValue(v));\n }\n }\n\n public get hasResolutionX(): boolean {\n return this.data.has(0x011a);\n }\n\n public get resolutionX(): Rational | undefined {\n return this.data.get(0x011a)?.toRational();\n }\n\n public set resolutionX(v: Rational | undefined) {\n if (!this.setRational(0x011a, v)) {\n this.data.delete(0x011a);\n }\n }\n\n public get hasResolutionY(): boolean {\n return this.data.has(0x011b);\n }\n\n public get resolutionY(): Rational | undefined {\n return this.data.get(0x011b)?.toRational();\n }\n\n public set resolutionY(v: Rational | undefined) {\n if (!this.setRational(0x011b, v)) {\n this.data.delete(0x011b);\n }\n }\n\n public get hasResolutionUnit(): boolean {\n return this.data.has(0x0128);\n }\n\n public get resolutionUnit(): number | undefined {\n return this.data.get(0x0128)?.toInt();\n }\n\n public set resolutionUnit(v: number | undefined) {\n if (v === undefined) {\n this.data.delete(0x0128);\n } else {\n this.data.set(0x0128, new ExifShortValue(Math.trunc(v)));\n }\n }\n\n public get hasImageWidth(): boolean {\n return this.data.has(0x0100);\n }\n\n public get imageWidth(): number | undefined {\n return this.data.get(0x0100)?.toInt();\n }\n\n public set imageWidth(v: number | undefined) {\n if (v === undefined) {\n this.data.delete(0x0100);\n } else {\n this.data.set(0x0100, new ExifShortValue(Math.trunc(v)));\n }\n }\n\n public get hasImageHeight(): boolean {\n return this.data.has(0x0101);\n }\n\n public get imageHeight(): number | undefined {\n return this.data.get(0x0101)?.toInt();\n }\n\n public set imageHeight(v: number | undefined) {\n if (v === undefined) {\n this.data.delete(0x0101);\n } else {\n this.data.set(0x0101, new ExifShortValue(Math.trunc(v)));\n }\n }\n\n public get hasSoftware(): boolean {\n return this.data.has(0x0131);\n }\n\n public get software(): string | undefined {\n return this.data.get(0x0131)?.toString();\n }\n\n public set software(v: string | undefined) {\n if (v === undefined) {\n this.data.delete(0x0131);\n } else {\n this.data.set(0x0131, new ExifAsciiValue(v));\n }\n }\n\n public get hasCopyright(): boolean {\n return this.data.has(0x8298);\n }\n\n public get copyright(): string | undefined {\n return this.data.get(0x8298)?.toString();\n }\n\n public set copyright(v: string | undefined) {\n if (v === undefined) {\n this.data.delete(0x8298);\n } else {\n this.data.set(0x8298, new ExifAsciiValue(v));\n }\n }\n\n private setRational(tag: number, value: unknown): boolean {\n if (value instanceof Rational) {\n this.data.set(tag, ExifRationalValue.from(value));\n return true;\n } else if (\n Array.isArray(value) &&\n (value as Array).every((v) => typeof v === 'number')\n ) {\n if (value.length === 2) {\n const r = new Rational((value as number[])[0], (value as number[])[1]);\n this.data.set(tag, ExifRationalValue.from(r));\n return true;\n }\n }\n return false;\n }\n\n public static isArrayOfRationalNumbers(value: unknown): boolean {\n return (\n Array.isArray(value) &&\n value.every(\n (v) =>\n Array.isArray(v) &&\n v.length >= 2 &&\n v.every((sv) => typeof sv === 'number')\n )\n );\n }\n\n public has(tag: number): boolean {\n return this.data.has(tag);\n }\n\n public getValue(tag: number | string): ExifValue | undefined {\n let _tag: string | number | undefined = tag;\n if (typeof _tag === 'string') {\n _tag = ExifTagNameToID.get(_tag);\n }\n if (typeof _tag === 'number') {\n return this.data.get(_tag);\n }\n return undefined;\n }\n\n public setValue(\n tag: number | string,\n value: number[][] | Rational[] | number[] | Rational | ExifValue | undefined\n ): void {\n let _tag: string | number | undefined = tag;\n if (typeof _tag === 'string') {\n _tag = ExifTagNameToID.get(_tag);\n }\n if (typeof _tag !== 'number') {\n return;\n }\n\n if (value === undefined) {\n this.data.delete(_tag);\n } else {\n if (value instanceof ExifValue) {\n this.data.set(_tag, value);\n } else {\n const tagInfo = ExifImageTags.get(_tag);\n if (tagInfo !== undefined) {\n const tagType = tagInfo.type;\n const tagCount = tagInfo.count;\n switch (tagType) {\n case ExifValueType.byte:\n if (\n Array.isArray(value) &&\n value.length === tagCount &&\n (value as Array).every((v) => typeof v === 'number')\n ) {\n this.data.set(\n _tag,\n new ExifByteValue(new Uint8Array(value as number[]))\n );\n } else if (typeof value === 'number' && tagCount === 1) {\n this.data.set(_tag, new ExifByteValue(value));\n }\n break;\n case ExifValueType.ascii:\n if (typeof value === 'string') {\n this.data.set(_tag, new ExifAsciiValue(value));\n }\n break;\n case ExifValueType.short:\n if (\n Array.isArray(value) &&\n value.length === tagCount &&\n (value as Array).every((v) => typeof v === 'number')\n ) {\n this.data.set(\n _tag,\n new ExifShortValue(new Uint16Array(value as number[]))\n );\n } else if (typeof value === 'number' && tagCount === 1) {\n this.data.set(_tag, new ExifShortValue(value));\n }\n break;\n case ExifValueType.long:\n if (\n Array.isArray(value) &&\n value.length === tagCount &&\n (value as Array).every((v) => typeof v === 'number')\n ) {\n this.data.set(\n _tag,\n new ExifLongValue(new Uint32Array(value as number[]))\n );\n } else if (typeof value === 'number' && tagCount === 1) {\n this.data.set(_tag, new ExifLongValue(value));\n }\n break;\n case ExifValueType.rational:\n if (\n Array.isArray(value) &&\n value.length === tagCount &&\n (value as Array).every((v) => v instanceof Rational)\n ) {\n this.data.set(_tag, new ExifRationalValue(value as Rational[]));\n } else if (\n tagCount === 1 &&\n Array.isArray(value) &&\n value.length === 2 &&\n (value as Array).every((v) => typeof v === 'number')\n ) {\n const r = new Rational(\n (value as number[])[0],\n (value as number[])[1]\n );\n this.data.set(_tag, new ExifRationalValue(r));\n } else if (tagCount === 1 && value instanceof Rational) {\n this.data.set(_tag, new ExifRationalValue(value));\n } else if (\n Array.isArray(value) &&\n value.length === tagCount &&\n (value as Array).every(\n (v) =>\n Array.isArray(v) &&\n v.length >= 2 &&\n v.every((sv) => typeof sv === 'number')\n )\n ) {\n const array = new Array();\n for (let i = 0; i < value.length; i++) {\n const subarray = value[i];\n if (\n Array.isArray(subarray) &&\n subarray.length >= 2 &&\n subarray.every((el) => typeof el === 'number')\n ) {\n array.push(new Rational(subarray[0], subarray[1]));\n }\n }\n this.data.set(_tag, new ExifRationalValue(array));\n }\n break;\n case ExifValueType.sbyte:\n if (\n Array.isArray(value) &&\n value.length === tagCount &&\n (value as Array).every((v) => typeof v === 'number')\n ) {\n this.data.set(\n _tag,\n new ExifSByteValue(new Int8Array(value as number[]))\n );\n } else if (typeof value === 'number' && tagCount === 1) {\n this.data.set(_tag, new ExifSByteValue(value));\n }\n break;\n case ExifValueType.undefined:\n if (\n Array.isArray(value) &&\n (value as Array).every((v) => typeof v === 'number')\n ) {\n this.data.set(\n _tag,\n new ExifUndefinedValue(new Uint8Array(value as number[]))\n );\n }\n break;\n case ExifValueType.sshort:\n if (\n Array.isArray(value) &&\n value.length === tagCount &&\n (value as Array).every((v) => typeof v === 'number')\n ) {\n this.data.set(\n _tag,\n new ExifSShortValue(new Int16Array(value as number[]))\n );\n } else if (typeof value === 'number' && tagCount === 1) {\n this.data.set(_tag, new ExifSShortValue(value));\n }\n break;\n case ExifValueType.slong:\n if (\n Array.isArray(value) &&\n value.length === tagCount &&\n (value as Array).every((v) => typeof v === 'number')\n ) {\n this.data.set(\n _tag,\n new ExifSLongValue(new Int32Array(value as number[]))\n );\n } else if (typeof value === 'number' && tagCount === 1) {\n this.data.set(_tag, new ExifSLongValue(value));\n }\n break;\n case ExifValueType.srational:\n if (\n Array.isArray(value) &&\n value.length === tagCount &&\n (value as Array).every((v) => v instanceof Rational)\n ) {\n this.data.set(\n _tag,\n new ExifSRationalValue(value as Rational[])\n );\n } else if (\n tagCount === 1 &&\n Array.isArray(value) &&\n value.length === 2 &&\n (value as Array).every((v) => typeof v === 'number')\n ) {\n const r = new Rational(\n (value as number[])[0],\n (value as number[])[1]\n );\n this.data.set(_tag, new ExifSRationalValue(r));\n } else if (tagCount === 1 && value instanceof Rational) {\n this.data.set(_tag, new ExifSRationalValue(value));\n } else if (\n Array.isArray(value) &&\n value.length === tagCount &&\n (value as Array).every(\n (v) =>\n Array.isArray(v) &&\n v.length >= 2 &&\n v.every((sv) => typeof sv === 'number')\n )\n ) {\n const array = new Array();\n for (let i = 0; i < value.length; i++) {\n const subarray = value[i];\n if (\n Array.isArray(subarray) &&\n subarray.length >= 2 &&\n subarray.every((el) => typeof el === 'number')\n ) {\n array.push(new Rational(subarray[0], subarray[1]));\n }\n }\n this.data.set(_tag, new ExifSRationalValue(array));\n }\n break;\n case ExifValueType.single:\n if (\n Array.isArray(value) &&\n value.length === tagCount &&\n (value as Array).every((v) => typeof v === 'number')\n ) {\n this.data.set(\n _tag,\n new ExifSingleValue(new Float32Array(value as number[]))\n );\n } else if (typeof value === 'number' && tagCount === 1) {\n this.data.set(_tag, new ExifSingleValue(value));\n }\n break;\n case ExifValueType.double:\n if (\n Array.isArray(value) &&\n value.length === tagCount &&\n (value as Array).every((v) => typeof v === 'number')\n ) {\n this.data.set(\n _tag,\n new ExifDoubleValue(new Float64Array(value as number[]))\n );\n } else if (typeof value === 'number' && tagCount === 1) {\n this.data.set(_tag, new ExifDoubleValue(value));\n }\n break;\n case ExifValueType.none:\n break;\n }\n }\n }\n }\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../common/input-buffer';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { ExifEntry } from './exif-entry';\nimport { ExifIFD } from './exif-ifd';\nimport { ExifIFDContainer } from './exif-ifd-container';\nimport { ExifImageTags } from './exif-tag';\nimport { ExifValueType, ExifValueTypeSize } from './exif-value-type';\nimport { ExifAsciiValue } from './exif-value/exif-ascii-value';\nimport { ExifByteValue } from './exif-value/exif-byte-value';\nimport { ExifDoubleValue } from './exif-value/exif-double-value';\nimport { ExifLongValue } from './exif-value/exif-long-value';\nimport { ExifRationalValue } from './exif-value/exif-rational-value';\nimport { ExifSByteValue } from './exif-value/exif-sbyte-value';\nimport { ExifShortValue } from './exif-value/exif-short-value';\nimport { ExifSingleValue } from './exif-value/exif-single-value';\nimport { ExifSLongValue } from './exif-value/exif-slong-value';\nimport { ExifSRationalValue } from './exif-value/exif-srational-value';\nimport { ExifSShortValue } from './exif-value/exif-sshort-value';\nimport { ExifUndefinedValue } from './exif-value/exif-undefined-value';\nimport { ExifValue } from './exif-value/exif-value';\n\nexport class ExifData extends ExifIFDContainer {\n public get imageIfd(): ExifIFD {\n return this.get('ifd0');\n }\n\n public get thumbnailIfd(): ExifIFD {\n return this.get('ifd1');\n }\n\n public get exifIfd(): ExifIFD {\n return this.get('ifd0').sub.get('exif');\n }\n\n public get gpsIfd(): ExifIFD {\n return this.get('ifd0').sub.get('gps');\n }\n\n public get interopIfd(): ExifIFD {\n return this.get('ifd0').sub.get('interop');\n }\n\n private writeDirectory(\n out: OutputBuffer,\n ifd: ExifIFD,\n dataOffset: number\n ): number {\n let offset = dataOffset;\n out.writeUint16(ifd.size);\n for (const tag of ifd.keys) {\n const value = ifd.getValue(tag)!;\n\n out.writeUint16(tag);\n out.writeUint16(value.type);\n out.writeUint32(value.length);\n\n let size = value.dataSize;\n if (size <= 4) {\n value.write(out);\n while (size < 4) {\n out.writeByte(0);\n size++;\n }\n } else {\n out.writeUint32(offset);\n offset += size;\n }\n }\n return offset;\n }\n\n private writeDirectoryLargeValues(out: OutputBuffer, ifd: ExifIFD): void {\n for (const value of ifd.values) {\n const size = value.dataSize;\n if (size > 4) {\n value.write(out);\n }\n }\n }\n\n private readEntry(block: InputBuffer, blockOffset: number): ExifEntry {\n const tag = block.readUint16();\n const format = block.readUint16();\n const count = block.readUint32();\n\n const entry = new ExifEntry(tag, undefined);\n\n if (format > Object.keys(ExifValueType).length) return entry;\n\n const f = format as ExifValueType;\n const fsize = ExifValueTypeSize[format];\n const size = count * fsize;\n\n const endOffset = block.offset + 4;\n\n if (size > 4) {\n const fieldOffset = block.readUint32();\n block.offset = fieldOffset + blockOffset;\n }\n\n if (block.offset + size > block.end) {\n return entry;\n }\n\n const data = block.readBytes(size);\n\n switch (f) {\n case ExifValueType.none:\n break;\n case ExifValueType.sbyte:\n entry.value = ExifSByteValue.fromData(data, count);\n break;\n case ExifValueType.byte:\n entry.value = ExifByteValue.fromData(data, count);\n break;\n case ExifValueType.undefined:\n entry.value = ExifUndefinedValue.fromData(data, count);\n break;\n case ExifValueType.ascii:\n entry.value = ExifAsciiValue.fromData(data, count);\n break;\n case ExifValueType.short:\n entry.value = ExifShortValue.fromData(data, count);\n break;\n case ExifValueType.long:\n entry.value = ExifLongValue.fromData(data, count);\n break;\n case ExifValueType.rational:\n entry.value = ExifRationalValue.fromData(data, count);\n break;\n case ExifValueType.srational:\n entry.value = ExifSRationalValue.fromData(data, count);\n break;\n case ExifValueType.sshort:\n entry.value = ExifSShortValue.fromData(data, count);\n break;\n case ExifValueType.slong:\n entry.value = ExifSLongValue.fromData(data, count);\n break;\n case ExifValueType.single:\n entry.value = ExifSingleValue.fromData(data, count);\n break;\n case ExifValueType.double:\n entry.value = ExifDoubleValue.fromData(data, count);\n break;\n }\n\n block.offset = endOffset;\n\n return entry;\n }\n\n public static from(other: ExifData) {\n return new ExifData(other.directories);\n }\n\n public static fromInputBuffer(input: InputBuffer) {\n const data = new ExifData();\n data.read(input);\n return data;\n }\n\n public hasTag(tag: number): boolean {\n for (const directory of this.directories.values()) {\n if (directory.has(tag)) {\n return true;\n }\n }\n return false;\n }\n\n public getTag(tag: number): ExifValue | undefined {\n for (const directory of this.directories.values()) {\n if (directory.has(tag)) {\n return directory.getValue(tag);\n }\n }\n return undefined;\n }\n\n public getTagName(tag: number): string {\n return ExifImageTags.get(tag)?.name ?? '';\n }\n\n public write(out: OutputBuffer): void {\n const saveEndian = out.bigEndian;\n out.bigEndian = true;\n\n // Tiff header\n // big endian\n out.writeUint16(0x4d4d);\n out.writeUint16(0x002a);\n // offset to first ifd block\n out.writeUint32(8);\n\n if (this.directories.get('ifd0') === undefined)\n this.directories.set('ifd0', new ExifIFD());\n\n // offset to first ifd block, from start of tiff header\n let dataOffset = 8;\n const offsets = new Map();\n\n for (const [name, ifd] of this.directories) {\n offsets.set(name, dataOffset);\n\n if (ifd.sub.has('exif')) {\n ifd.setValue(0x8769, new ExifLongValue(0));\n } else {\n ifd.setValue(0x8769, undefined);\n }\n\n if (ifd.sub.has('interop')) {\n ifd.setValue(0xa005, new ExifLongValue(0));\n } else {\n ifd.setValue(0xa005, undefined);\n }\n\n if (ifd.sub.has('gps')) {\n ifd.setValue(0x8825, new ExifLongValue(0));\n } else {\n ifd.setValue(0x8825, undefined);\n }\n\n // ifd block size\n dataOffset += 2 + 12 * ifd.size + 4;\n\n // storage for large tag values\n for (const value of ifd.values) {\n const dataSize = value.dataSize;\n if (dataSize > 4) {\n dataOffset += dataSize;\n }\n }\n\n // storage for sub-ifd blocks\n for (const subName of ifd.sub.keys) {\n const subIfd = ifd.sub.get(subName);\n offsets.set(subName, dataOffset);\n let subSize = 2 + 12 * subIfd.size;\n for (const value of subIfd.values) {\n const dataSize = value.dataSize;\n if (dataSize > 4) {\n subSize += dataSize;\n }\n }\n dataOffset += subSize;\n }\n }\n\n const dirArray = Array.from(this.directories);\n for (let i = 0; i < dirArray.length; i++) {\n const [name, ifd] = dirArray[i];\n\n if (ifd.sub.has('exif')) {\n ifd.getValue(0x8769)!.setInt(offsets.get('exif')!);\n }\n\n if (ifd.sub.has('interop')) {\n ifd.getValue(0xa005)!.setInt(offsets.get('interop')!);\n }\n\n if (ifd.sub.has('gps')) {\n ifd.getValue(0x8825)!.setInt(offsets.get('gps')!);\n }\n\n const ifdOffset = offsets.get(name)!;\n const dataOffset = ifdOffset + 2 + 12 * ifd.size + 4;\n\n this.writeDirectory(out, ifd, dataOffset);\n\n if (i === dirArray.length - 1) {\n out.writeUint32(0);\n } else {\n const nextName = dirArray[i + 1][0];\n out.writeUint32(offsets.get(nextName)!);\n }\n\n this.writeDirectoryLargeValues(out, ifd);\n\n for (const subName of ifd.sub.keys) {\n const subIfd = ifd.sub.get(subName);\n const subOffset = offsets.get(subName)!;\n const dataOffset = subOffset + 2 + 12 * subIfd.size;\n this.writeDirectory(out, subIfd, dataOffset);\n this.writeDirectoryLargeValues(out, subIfd);\n }\n }\n\n out.bigEndian = saveEndian;\n }\n\n public read(block: InputBuffer): boolean {\n const saveEndian = block.bigEndian;\n block.bigEndian = true;\n\n const blockOffset = block.offset;\n\n // Tiff header\n const endian = block.readUint16();\n\n if (endian === 0x4949) {\n // II\n block.bigEndian = false;\n if (block.readUint16() !== 0x2a00) {\n block.bigEndian = saveEndian;\n return false;\n }\n } else if (endian === 0x4d4d) {\n // MM\n block.bigEndian = true;\n if (block.readUint16() !== 0x002a) {\n block.bigEndian = saveEndian;\n return false;\n }\n } else {\n return false;\n }\n\n let ifdOffset = block.readUint32();\n\n // IFD blocks\n let index = 0;\n while (ifdOffset > 0) {\n block.offset = blockOffset + ifdOffset;\n\n const directory = new ExifIFD();\n const numEntries = block.readUint16();\n\n const dir = new Array();\n for (let i = 0; i < numEntries; i++) {\n const entry = this.readEntry(block, blockOffset);\n dir.push(entry);\n }\n\n for (const entry of dir) {\n if (entry.value !== undefined) {\n directory.setValue(entry.tag, entry.value);\n }\n }\n this.directories.set(`ifd${index}`, directory);\n index++;\n\n ifdOffset = block.readUint32();\n }\n\n const subTags = new Map([\n [0x8769, 'exif'],\n [0xa005, 'interop'],\n [0x8825, 'gps'],\n ]);\n\n for (const d of this.directories.values()) {\n for (const dt of subTags.keys()) {\n // ExifOffset\n if (d.has(dt)) {\n const ifdOffset = d.getValue(dt)!.toInt();\n block.offset = blockOffset + ifdOffset;\n const directory = new ExifIFD();\n const numEntries = block.readUint16();\n\n const dir = new Array();\n for (let i = 0; i < numEntries; i++) {\n const entry = this.readEntry(block, blockOffset);\n dir.push(entry);\n }\n\n for (const entry of dir) {\n if (entry.value !== undefined) {\n directory.setValue(entry.tag, entry.value!);\n }\n }\n d.sub.set(subTags.get(dt)!, directory);\n }\n }\n }\n\n block.bigEndian = saveEndian;\n return false;\n }\n\n public toString(): string {\n let s = '';\n for (const [name, directory] of this.directories) {\n s += `${name}\\n`;\n for (const tag of directory.keys) {\n const value = directory.getValue(tag);\n if (value === undefined) {\n s += `\\t${this.getTagName(tag)}\\n`;\n } else {\n s += `\\t${this.getTagName(tag)}: ${value.toString()}\\n`;\n }\n }\n for (const subName of directory.sub.keys) {\n s += `${subName}\\n`;\n const subDirectory = directory.sub.get(subName);\n for (const tag of subDirectory.keys) {\n const value = subDirectory.getValue(tag);\n if (value === undefined) {\n s += `\\t${this.getTagName(tag)}\\n`;\n } else {\n s += `\\t${this.getTagName(tag)}: ${value}\\n`;\n }\n }\n }\n }\n return s.toString();\n }\n}\n", "/** @format */\n\nimport { ICCProfileData } from './icc-profile-data';\nimport { ArrayUtils } from './array-utils';\nimport { RgbChannelSet } from './rgb-channel-set';\nimport { DisposeMode } from './dispose-mode';\nimport { BlendMode } from './blend-mode';\nimport { ColorModel } from './color-model';\nimport { ImageError } from '../error/image-error';\nimport { Interpolation } from './interpolation';\nimport { Color } from './color';\nimport { ExifData } from '../exif/exif-data';\n\nexport interface RgbMemoryImageInitOptions {\n width: number;\n height: number;\n exifData?: ExifData;\n iccProfile?: ICCProfileData;\n textData?: Map;\n}\n\nexport interface MemoryImageInitOptions extends RgbMemoryImageInitOptions {\n rgbChannelSet?: RgbChannelSet;\n data?: Uint32Array;\n}\n\nexport interface MemoryImageInitOptionsColorModel {\n width: number;\n height: number;\n data: Uint8Array;\n rgbChannelSet?: RgbChannelSet;\n exifData?: ExifData;\n iccProfile?: ICCProfileData;\n textData?: Map;\n colorModel?: ColorModel;\n}\n\n/**\n * An image buffer where pixels are encoded into 32-bit unsigned ints (Uint32).\n *\n * Pixels are stored in 32-bit unsigned integers in #AARRGGBB format.\n * You can use **getBytes** to access the pixel data at the byte (channel) level,\n * optionally providing the format to get the image data as. You can use the\n * letious color functions, such as **getRed**, **getGreen**, **getBlue**, and **getAlpha**\n * to access the individual channels of a given pixel color.\n *\n * If this image is a frame of an animation as decoded by the **decodeFrame**\n * method of **Decoder**, then the **xOffset**, **yOffset**, **width** and **height**\n * determine the area of the canvas this image should be drawn into,\n * as some frames of an animation only modify part of the canvas (recording\n * the part of the frame that actually changes). The **decodeAnimation** method\n * will always return the fully composed animation, so these coordinate\n * properties are not used.\n */\nexport class MemoryImage {\n /**\n * Pixels are encoded into 4-byte Uint32 integers in #AABBGGRR channel order.\n */\n private readonly _data: Uint32Array;\n public get data(): Uint32Array {\n return this._data;\n }\n\n /**\n * x position at which to render the frame. This is used for frames\n * in an animation, such as from an animated GIF.\n */\n private _xOffset = 0;\n public get xOffset(): number {\n return this._xOffset;\n }\n\n /**\n * y position at which to render the frame. This is used for frames\n * in an animation, such as from an animated GIF.\n */\n private _yOffset = 0;\n public get yOffset(): number {\n return this._yOffset;\n }\n\n /**\n * How long this frame should be displayed, in milliseconds.\n * A duration of 0 indicates no delay and the next frame will be drawn\n * as quickly as it can.\n */\n private _duration = 0;\n public set duration(v: number) {\n this._duration = v;\n }\n public get duration(): number {\n return this._duration;\n }\n\n /**\n * Defines what should be done to the canvas when drawing this frame\n * in an animation.\n */\n private _disposeMethod: DisposeMode = DisposeMode.clear;\n public get disposeMethod(): DisposeMode {\n return this._disposeMethod;\n }\n\n /**\n * Defines the blending method (alpha compositing) to use when drawing this\n * frame in an animation.\n */\n private _blendMethod: BlendMode = BlendMode.over;\n public get blendMethod(): BlendMode {\n return this._blendMethod;\n }\n\n /**\n * The channels used by this image, indicating whether the alpha channel\n * is used or not. All images have an implicit alpha channel due to the\n * image data being stored in a Uint32, but some images, such as those\n * decoded from a Jpeg, don't use the alpha channel. This allows\n * image encoders that support both rgb and rgba formats, to know which\n * one it should use.\n */\n private _rgbChannelSet: RgbChannelSet;\n public get rgbChannelSet(): RgbChannelSet {\n return this._rgbChannelSet;\n }\n\n /**\n * EXIF data decoded from an image file.\n */\n private _exifData: ExifData;\n public get exifData(): ExifData {\n return this._exifData;\n }\n public set exifData(v: ExifData) {\n this._exifData = v;\n }\n\n /**\n * ICC color profile read from an image file.\n */\n private _iccProfile?: ICCProfileData;\n public set iccProfile(v: ICCProfileData | undefined) {\n this._iccProfile = v;\n }\n public get iccProfile(): ICCProfileData | undefined {\n return this._iccProfile;\n }\n\n /**\n * Some formats, like PNG, can encode and decode text data with the image.\n */\n private _textData?: Map;\n public get textData(): Map | undefined {\n return this._textData;\n }\n\n /**\n * Width of the image.\n */\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n /**\n * Height of the image.\n */\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n /**\n * The number of channels used by this Image. While all images\n * are stored internally with 4 bytes, some images, such as those\n * loaded from a Jpeg, don't use the 4th (alpha) channel.\n */\n public get numberOfChannels(): number {\n return this.rgbChannelSet === RgbChannelSet.rgba ? 4 : 3;\n }\n\n /**\n * The size of the image buffer.\n */\n public get length(): number {\n return this.data.length;\n }\n\n /**\n * Create an image with the given dimensions and format.\n */\n constructor(options: MemoryImageInitOptions) {\n this._width = options.width;\n this._height = options.height;\n this._rgbChannelSet = options.rgbChannelSet ?? RgbChannelSet.rgba;\n this._exifData =\n options.exifData !== undefined\n ? ExifData.from(options.exifData)\n : new ExifData();\n this._iccProfile = options.iccProfile;\n this._textData = options.textData;\n this._data =\n options.data ?? new Uint32Array(options.width * options.height);\n }\n\n private static convertData(\n width: number,\n height: number,\n bytes: Uint8Array | Uint32Array,\n colorModel: ColorModel\n ): Uint32Array {\n if (colorModel === ColorModel.rgba) {\n return bytes instanceof Uint32Array\n ? ArrayUtils.copyUint32(bytes)\n : ArrayUtils.copyUint32(new Uint32Array(bytes.buffer));\n }\n const input =\n bytes instanceof Uint32Array ? new Uint8Array(bytes.buffer) : bytes;\n\n const data = new Uint32Array(width * height);\n const rgba = new Uint8Array(data.buffer);\n\n switch (colorModel) {\n case ColorModel.bgra:\n for (let i = 0, len = input.length; i < len; i += 4) {\n rgba[i + 0] = input[i + 2];\n rgba[i + 1] = input[i + 1];\n rgba[i + 2] = input[i + 0];\n rgba[i + 3] = input[i + 3];\n }\n break;\n case ColorModel.abgr:\n for (let i = 0, len = input.length; i < len; i += 4) {\n rgba[i + 0] = input[i + 3];\n rgba[i + 1] = input[i + 2];\n rgba[i + 2] = input[i + 1];\n rgba[i + 3] = input[i + 0];\n }\n break;\n case ColorModel.argb:\n for (let i = 0, len = input.length; i < len; i += 4) {\n rgba[i + 0] = input[i + 1];\n rgba[i + 1] = input[i + 2];\n rgba[i + 2] = input[i + 3];\n rgba[i + 3] = input[i + 0];\n }\n break;\n case ColorModel.bgr:\n for (let i = 0, j = 0, len = input.length; j < len; i += 4, j += 3) {\n rgba[i + 0] = input[j + 2];\n rgba[i + 1] = input[j + 1];\n rgba[i + 2] = input[j + 0];\n rgba[i + 3] = 255;\n }\n break;\n case ColorModel.rgb:\n for (let i = 0, j = 0, len = input.length; j < len; i += 4, j += 3) {\n rgba[i + 0] = input[j + 0];\n rgba[i + 1] = input[j + 1];\n rgba[i + 2] = input[j + 2];\n rgba[i + 3] = 255;\n }\n break;\n case ColorModel.luminance:\n for (let i = 0, j = 0, len = input.length; j < len; i += 4, ++j) {\n rgba[i + 0] = input[j];\n rgba[i + 1] = input[j];\n rgba[i + 2] = input[j];\n rgba[i + 3] = 255;\n }\n break;\n }\n return data;\n }\n\n public static rgb(options: RgbMemoryImageInitOptions): MemoryImage {\n const opt = {\n ...options,\n rgbChannelSet: RgbChannelSet.rgb,\n } as MemoryImageInitOptions;\n return new MemoryImage(opt);\n }\n\n public static from(other: MemoryImage): MemoryImage {\n const result = new MemoryImage({\n width: other._width,\n height: other._height,\n rgbChannelSet: other._rgbChannelSet,\n exifData: ExifData.from(other._exifData),\n iccProfile: other._iccProfile,\n textData:\n other._textData !== undefined ? new Map(other._textData) : undefined,\n data: ArrayUtils.copyUint32(other._data),\n });\n result._xOffset = other._xOffset;\n result._yOffset = other._yOffset;\n result._duration = other._duration;\n result._disposeMethod = other._disposeMethod;\n result._blendMethod = other._blendMethod;\n return result;\n }\n\n /**\n *\n * **format** defines the order of color channels in **data**.\n * The length of **data** should be (width * height) * format-byte-count,\n * where format-byte-count is 1, 3, or 4 depending on the number of\n * channels in the format (luminance, rgb, rgba, etc).\n *\n * The native format of an image is Format.rgba. If another format\n * is specified, the input data will be converted to rgba to store\n * in the Image.\n */\n public static fromBytes(\n options: MemoryImageInitOptionsColorModel\n ): MemoryImage {\n options.rgbChannelSet ??= RgbChannelSet.rgba;\n options.colorModel ??= ColorModel.rgba;\n const data = this.convertData(\n options.width,\n options.height,\n options.data,\n options.colorModel\n );\n const result = new MemoryImage({\n width: options.width,\n height: options.height,\n rgbChannelSet: options.rgbChannelSet,\n exifData: options.exifData,\n iccProfile: options.iccProfile,\n textData: options.textData,\n data: data,\n });\n return result;\n }\n\n /**\n * Clone this image.\n * */\n public clone(): MemoryImage {\n return MemoryImage.from(this);\n }\n\n /**\n * Get the bytes from the image. You can use this to access the\n * color channels directly, or to pass it to something like an\n * Html canvas context.\n *\n * Specifying the **format** will convert the image data to the specified\n * format. Images are stored internally in Format.rgba format; any\n * other format will require a conversion.\n *\n * For example, given an Html Canvas, you could draw this image into the\n * canvas:\n * Html.ImageData d = context2D.createImageData(image.width, image.height);\n * d.data.setRange(0, image.length, image.getBytes(format: Format.rgba));\n * context2D.putImageData(data, 0, 0);\n */\n public getBytes(colorModel: ColorModel = ColorModel.rgba): Uint8Array {\n const rgba = new Uint8Array(this._data.buffer);\n switch (colorModel) {\n case ColorModel.rgba:\n return rgba;\n case ColorModel.bgra: {\n const bytes = new Uint8Array(this._width * this._height * 4);\n for (let i = 0, len = bytes.length; i < len; i += 4) {\n bytes[i + 0] = rgba[i + 2];\n bytes[i + 1] = rgba[i + 1];\n bytes[i + 2] = rgba[i + 0];\n bytes[i + 3] = rgba[i + 3];\n }\n return bytes;\n }\n case ColorModel.abgr: {\n const bytes = new Uint8Array(this._width * this._height * 4);\n for (let i = 0, len = bytes.length; i < len; i += 4) {\n bytes[i + 0] = rgba[i + 3];\n bytes[i + 1] = rgba[i + 2];\n bytes[i + 2] = rgba[i + 1];\n bytes[i + 3] = rgba[i + 0];\n }\n return bytes;\n }\n case ColorModel.argb: {\n const bytes = new Uint8Array(this._width * this._height * 4);\n for (let i = 0, len = bytes.length; i < len; i += 4) {\n bytes[i + 0] = rgba[i + 3];\n bytes[i + 1] = rgba[i + 0];\n bytes[i + 2] = rgba[i + 1];\n bytes[i + 3] = rgba[i + 2];\n }\n return bytes;\n }\n case ColorModel.rgb: {\n const bytes = new Uint8Array(this._width * this._height * 3);\n for (let i = 0, j = 0, len = bytes.length; j < len; i += 4, j += 3) {\n bytes[j + 0] = rgba[i + 0];\n bytes[j + 1] = rgba[i + 1];\n bytes[j + 2] = rgba[i + 2];\n }\n return bytes;\n }\n case ColorModel.bgr: {\n const bytes = new Uint8Array(this._width * this._height * 3);\n for (let i = 0, j = 0, len = bytes.length; j < len; i += 4, j += 3) {\n bytes[j + 0] = rgba[i + 2];\n bytes[j + 1] = rgba[i + 1];\n bytes[j + 2] = rgba[i + 0];\n }\n return bytes;\n }\n case ColorModel.luminance: {\n const bytes = new Uint8Array(this._width * this._height);\n for (let i = 0, len = this.length; i < len; ++i) {\n bytes[i] = Color.getLuminance(this._data[i]);\n }\n return bytes;\n }\n }\n throw new ImageError('Unknown color model');\n }\n\n /**\n * Set all of the pixels of the image to the given **color**.\n */\n public fill(color: number): MemoryImage {\n this._data.fill(color);\n return this;\n }\n\n /**\n * Set all of the empty pixels (for png's) of the image to the given **color**.\n */\n public fillBackground(color: number): void {\n // Loop all pixels\n for (let i = 0; i < this.length; i++) {\n // Value 0 means null pixel\n if (this._data[i] === 0) {\n // Set the pixel to the given color\n this._data[i] = color;\n }\n }\n }\n\n /**\n * Add the colors of **other** to the pixels of this image.\n */\n public addImage(other: MemoryImage): MemoryImage {\n const h = Math.min(this._height, other._height);\n const w = Math.min(this._width, other._width);\n for (let y = 0; y < h; ++y) {\n for (let x = 0; x < w; ++x) {\n const c1 = this.getPixel(x, y);\n const r1 = Color.getRed(c1);\n const g1 = Color.getGreen(c1);\n const b1 = Color.getBlue(c1);\n const a1 = Color.getAlpha(c1);\n\n const c2 = other.getPixel(x, y);\n const r2 = Color.getRed(c2);\n const g2 = Color.getGreen(c2);\n const b2 = Color.getBlue(c2);\n const a2 = Color.getAlpha(c2);\n\n this.setPixel(x, y, Color.getColor(r1 + r2, g1 + g2, b1 + b2, a1 + a2));\n }\n }\n return this;\n }\n\n /**\n * Subtract the colors of **other** from the pixels of this image.\n */\n public subtractImage(other: MemoryImage): MemoryImage {\n const h = Math.min(this._height, other._height);\n const w = Math.min(this._width, other._width);\n for (let y = 0; y < h; ++y) {\n for (let x = 0; x < w; ++x) {\n const c1 = this.getPixel(x, y);\n const r1 = Color.getRed(c1);\n const g1 = Color.getGreen(c1);\n const b1 = Color.getBlue(c1);\n const a1 = Color.getAlpha(c1);\n\n const c2 = other.getPixel(x, y);\n const r2 = Color.getRed(c2);\n const g2 = Color.getGreen(c2);\n const b2 = Color.getBlue(c2);\n const a2 = Color.getAlpha(c2);\n\n this.setPixel(x, y, Color.getColor(r1 - r2, g1 - g2, b1 - b2, a1 - a2));\n }\n }\n return this;\n }\n\n /**\n * Multiply the colors of **other** with the pixels of this image.\n */\n public multiplyImage(other: MemoryImage): MemoryImage {\n const h = Math.min(this._height, other._height);\n const w = Math.min(this._width, other._width);\n for (let y = 0; y < h; ++y) {\n for (let x = 0; x < w; ++x) {\n const c1 = this.getPixel(x, y);\n const r1 = Color.getRed(c1);\n const g1 = Color.getGreen(c1);\n const b1 = Color.getBlue(c1);\n const a1 = Color.getAlpha(c1);\n\n const c2 = other.getPixel(x, y);\n const r2 = Color.getRed(c2);\n const g2 = Color.getGreen(c2);\n const b2 = Color.getBlue(c2);\n const a2 = Color.getAlpha(c2);\n\n this.setPixel(x, y, Color.getColor(r1 * r2, g1 * g2, b1 * b2, a1 * a2));\n }\n }\n return this;\n }\n\n /**\n * OR the colors of **other** to the pixels of this image.\n */\n public orImage(other: MemoryImage): MemoryImage {\n const h = Math.min(this._height, other._height);\n const w = Math.min(this._width, other._width);\n for (let y = 0; y < h; ++y) {\n for (let x = 0; x < w; ++x) {\n const c1 = this.getPixel(x, y);\n const r1 = Color.getRed(c1);\n const g1 = Color.getGreen(c1);\n const b1 = Color.getBlue(c1);\n const a1 = Color.getAlpha(c1);\n\n const c2 = other.getPixel(x, y);\n const r2 = Color.getRed(c2);\n const g2 = Color.getGreen(c2);\n const b2 = Color.getBlue(c2);\n const a2 = Color.getAlpha(c2);\n\n this.setPixel(x, y, Color.getColor(r1 | r2, g1 | g2, b1 | b2, a1 | a2));\n }\n }\n return this;\n }\n\n /**\n * AND the colors of **other** with the pixels of this image.\n */\n public andImage(other: MemoryImage): MemoryImage {\n const h = Math.min(this._height, other._height);\n const w = Math.min(this._width, other._width);\n for (let y = 0; y < h; ++y) {\n for (let x = 0; x < w; ++x) {\n const c1 = this.getPixel(x, y);\n const r1 = Color.getRed(c1);\n const g1 = Color.getGreen(c1);\n const b1 = Color.getBlue(c1);\n const a1 = Color.getAlpha(c1);\n\n const c2 = other.getPixel(x, y);\n const r2 = Color.getRed(c2);\n const g2 = Color.getGreen(c2);\n const b2 = Color.getBlue(c2);\n const a2 = Color.getAlpha(c2);\n\n this.setPixel(x, y, Color.getColor(r1 & r2, g1 & g2, b1 & b2, a1 & a2));\n }\n }\n return this;\n }\n\n /**\n * Modula the colors of **other** with the pixels of this image.\n */\n public modImage(other: MemoryImage): MemoryImage {\n const h = Math.min(this._height, other._height);\n const w = Math.min(this._width, other._width);\n for (let y = 0; y < h; ++y) {\n for (let x = 0; x < w; ++x) {\n const c1 = this.getPixel(x, y);\n const r1 = Color.getRed(c1);\n const g1 = Color.getGreen(c1);\n const b1 = Color.getBlue(c1);\n const a1 = Color.getAlpha(c1);\n\n const c2 = other.getPixel(x, y);\n const r2 = Color.getRed(c2);\n const g2 = Color.getGreen(c2);\n const b2 = Color.getBlue(c2);\n const a2 = Color.getAlpha(c2);\n\n this.setPixel(x, y, Color.getColor(r1 % r2, g1 % g2, b1 % b2, a1 % a2));\n }\n }\n return this;\n }\n\n /**\n * Get a pixel from the buffer. No range checking is done.\n */\n public getPixelByIndex(index: number): number {\n return this._data[index];\n }\n\n /**\n * Set a pixel in the buffer. No range checking is done.\n */\n public setPixelByIndex(index: number, color: number): void {\n this._data[index] = color;\n }\n\n /**\n * Get the buffer index for the **x**, **y** pixel coordinates.\n * No range checking is done.\n */\n public getBufferIndex(x: number, y: number): number {\n return y * this._width + x;\n }\n\n /**\n * Is the given **x**, **y** pixel coordinates within the resolution of the image.\n */\n public boundsSafe(x: number, y: number): boolean {\n return x >= 0 && x < this._width && y >= 0 && y < this._height;\n }\n\n /**\n * Get the pixel from the given **x**, **y** coordinate. Color is encoded in a\n * Uint32 as #AABBGGRR. No range checking is done.\n */\n public getPixel(x: number, y: number): number {\n const index = this.getBufferIndex(x, y);\n return this._data[index];\n }\n\n /**\n * Get the pixel from the given **x**, **y** coordinate. Color is encoded in a\n * Uint32 as #AABBGGRR. If the pixel coordinates are out of bounds, 0 is\n * returned.\n */\n public getPixelSafe(x: number, y: number): number {\n const index = this.getBufferIndex(x, y);\n return this.boundsSafe(x, y) ? this._data[index] : 0;\n }\n\n /**\n * Get the pixel using the given **interpolation** type for non-integer pixel\n * coordinates.\n */\n public getPixelInterpolate(\n fx: number,\n fy: number,\n interpolation: Interpolation = Interpolation.linear\n ): number {\n if (interpolation === Interpolation.cubic) {\n return this.getPixelCubic(fx, fy);\n } else if (interpolation === Interpolation.linear) {\n return this.getPixelLinear(fx, fy);\n }\n return this.getPixelSafe(Math.trunc(fx), Math.trunc(fy));\n }\n\n /**\n * Get the pixel using linear interpolation for non-integer pixel\n * coordinates.\n */\n public getPixelLinear(fx: number, fy: number): number {\n const x = Math.trunc(fx) - (fx >= 0 ? 0 : 1);\n const nx = x + 1;\n const y = Math.trunc(fy) - (fy >= 0 ? 0 : 1);\n const ny = y + 1;\n const dx = fx - x;\n const dy = fy - y;\n\n const linear = (\n icc: number,\n inc: number,\n icn: number,\n inn: number\n ): number => {\n return Math.trunc(\n icc + dx * (inc - icc + dy * (icc + inn - icn - inc)) + dy * (icn - icc)\n );\n };\n\n const icc = this.getPixelSafe(x, y);\n const icn = ny >= this._height ? icc : this.getPixelSafe(x, ny);\n const inc = nx >= this._width ? icc : this.getPixelSafe(nx, y);\n const inn =\n nx >= this._width || ny >= this._height ? icc : this.getPixelSafe(nx, ny);\n\n return Color.getColor(\n linear(\n Color.getRed(icc),\n Color.getRed(inc),\n Color.getRed(icn),\n Color.getRed(inn)\n ),\n linear(\n Color.getGreen(icc),\n Color.getGreen(inc),\n Color.getGreen(icn),\n Color.getGreen(inn)\n ),\n linear(\n Color.getBlue(icc),\n Color.getBlue(inc),\n Color.getBlue(icn),\n Color.getBlue(inn)\n ),\n linear(\n Color.getAlpha(icc),\n Color.getAlpha(inc),\n Color.getAlpha(icn),\n Color.getAlpha(inn)\n )\n );\n }\n\n /**\n * Get the pixel using cubic interpolation for non-integer pixel\n * coordinates.\n */\n public getPixelCubic(fx: number, fy: number): number {\n const x = Math.trunc(fx) - (fx >= 0.0 ? 0 : 1);\n const px = x - 1;\n const nx = x + 1;\n const ax = x + 2;\n const y = Math.trunc(fy) - (fy >= 0.0 ? 0 : 1);\n const py = y - 1;\n const ny = y + 1;\n const ay = y + 2;\n\n const dx = fx - x;\n const dy = fy - y;\n\n const cubic = (\n dx: number,\n ipp: number,\n icp: number,\n inp: number,\n iap: number\n ): number => {\n return (\n icp +\n 0.5 *\n (dx * (-ipp + inp) +\n (dx * (dx * (2 * ipp)) - 5 * icp + 4 * inp - iap) +\n dx * (dx * (dx * (-ipp + 3 * icp - 3 * inp + iap))))\n );\n };\n\n const icc = this.getPixelSafe(x, y);\n\n const ipp = px < 0 || py < 0 ? icc : this.getPixelSafe(px, py);\n const icp = px < 0 ? icc : this.getPixelSafe(x, py);\n const inp = py < 0 || nx >= this._width ? icc : this.getPixelSafe(nx, py);\n const iap = ax >= this._width || py < 0 ? icc : this.getPixelSafe(ax, py);\n\n const ip0 = cubic(\n dx,\n Color.getRed(ipp),\n Color.getRed(icp),\n Color.getRed(inp),\n Color.getRed(iap)\n );\n\n const ip1 = cubic(\n dx,\n Color.getGreen(ipp),\n Color.getGreen(icp),\n Color.getGreen(inp),\n Color.getGreen(iap)\n );\n const ip2 = cubic(\n dx,\n Color.getBlue(ipp),\n Color.getBlue(icp),\n Color.getBlue(inp),\n Color.getBlue(iap)\n );\n const ip3 = cubic(\n dx,\n Color.getAlpha(ipp),\n Color.getAlpha(icp),\n Color.getAlpha(inp),\n Color.getAlpha(iap)\n );\n\n const ipc = px < 0 ? icc : this.getPixelSafe(px, y);\n const inc = nx >= this._width ? icc : this.getPixelSafe(nx, y);\n const iac = ax >= this._width ? icc : this.getPixelSafe(ax, y);\n\n const Ic0 = cubic(\n dx,\n Color.getRed(ipc),\n Color.getRed(icc),\n Color.getRed(inc),\n Color.getRed(iac)\n );\n const Ic1 = cubic(\n dx,\n Color.getGreen(ipc),\n Color.getGreen(icc),\n Color.getGreen(inc),\n Color.getGreen(iac)\n );\n const Ic2 = cubic(\n dx,\n Color.getBlue(ipc),\n Color.getBlue(icc),\n Color.getBlue(inc),\n Color.getBlue(iac)\n );\n const Ic3 = cubic(\n dx,\n Color.getAlpha(ipc),\n Color.getAlpha(icc),\n Color.getAlpha(inc),\n Color.getAlpha(iac)\n );\n\n const ipn = px < 0 || ny >= this._height ? icc : this.getPixelSafe(px, ny);\n const icn = ny >= this._height ? icc : this.getPixelSafe(x, ny);\n const inn =\n nx >= this._width || ny >= this._height ? icc : this.getPixelSafe(nx, ny);\n const ian =\n ax >= this._width || ny >= this._height ? icc : this.getPixelSafe(ax, ny);\n\n const in0 = cubic(\n dx,\n Color.getRed(ipn),\n Color.getRed(icn),\n Color.getRed(inn),\n Color.getRed(ian)\n );\n const in1 = cubic(\n dx,\n Color.getGreen(ipn),\n Color.getGreen(icn),\n Color.getGreen(inn),\n Color.getGreen(ian)\n );\n const in2 = cubic(\n dx,\n Color.getBlue(ipn),\n Color.getBlue(icn),\n Color.getBlue(inn),\n Color.getBlue(ian)\n );\n const in3 = cubic(\n dx,\n Color.getAlpha(ipn),\n Color.getAlpha(icn),\n Color.getAlpha(inn),\n Color.getAlpha(ian)\n );\n\n const ipa = px < 0 || ay >= this._height ? icc : this.getPixelSafe(px, ay);\n const ica = ay >= this._height ? icc : this.getPixelSafe(x, ay);\n const ina =\n nx >= this._width || ay >= this._height ? icc : this.getPixelSafe(nx, ay);\n const iaa =\n ax >= this._width || ay >= this._height ? icc : this.getPixelSafe(ax, ay);\n\n const ia0 = cubic(\n dx,\n Color.getRed(ipa),\n Color.getRed(ica),\n Color.getRed(ina),\n Color.getRed(iaa)\n );\n const ia1 = cubic(\n dx,\n Color.getGreen(ipa),\n Color.getGreen(ica),\n Color.getGreen(ina),\n Color.getGreen(iaa)\n );\n const ia2 = cubic(\n dx,\n Color.getBlue(ipa),\n Color.getBlue(ica),\n Color.getBlue(ina),\n Color.getBlue(iaa)\n );\n const ia3 = cubic(\n dx,\n Color.getAlpha(ipa),\n Color.getAlpha(ica),\n Color.getAlpha(ina),\n Color.getAlpha(iaa)\n );\n\n const c0 = cubic(dy, ip0, Ic0, in0, ia0);\n const c1 = cubic(dy, ip1, Ic1, in1, ia1);\n const c2 = cubic(dy, ip2, Ic2, in2, ia2);\n const c3 = cubic(dy, ip3, Ic3, in3, ia3);\n\n return Color.getColor(\n Math.trunc(c0),\n Math.trunc(c1),\n Math.trunc(c2),\n Math.trunc(c3)\n );\n }\n\n /**\n * Set the pixel at the given **x**, **y** coordinate to the **color**.\n * No range checking is done.\n */\n public setPixel(x: number, y: number, color: number): void {\n const index = this.getBufferIndex(x, y);\n this._data[index] = color;\n }\n\n /**\n * Set the pixel at the given **x**, **y** coordinate to the **color**.\n * If the pixel coordinates are out of bounds, nothing is done.\n */\n public setPixelSafe(x: number, y: number, color: number): void {\n if (this.boundsSafe(x, y)) {\n const index = this.getBufferIndex(x, y);\n this._data[index] = color;\n }\n }\n\n /**\n * Set the pixel at the given **x**, **y** coordinate to the color\n * **r**, **g**, **b**, **a**.\n *\n * This simply replaces the existing color, it does not do any alpha\n * blending. Use **drawPixel** for that. No range checking is done.\n */\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a = 0xff\n ): void {\n const index = this.getBufferIndex(x, y);\n this._data[index] = Color.getColor(r, g, b, a);\n }\n\n /**\n * Return the average gray value of the image.\n */\n public getWhiteBalance(asDouble = false) {\n const len = this._data.length;\n let r = 0.0;\n let g = 0.0;\n let b = 0.0;\n let t = 1;\n for (let i = 0; i < len; ++i) {\n r += (Color.getRed(this._data[i]) - r) / t;\n g += (Color.getGreen(this._data[i]) - g) / t;\n b += (Color.getBlue(this._data[i]) - b) / t;\n ++t;\n }\n const averageGray = (r + g + b) / 3.0;\n return asDouble ? averageGray : Math.trunc(averageGray);\n }\n\n /**\n * Find the minimum and maximum color value in the image.\n * Returns an object with **min** and **max** properties.\n */\n public getColorExtremes(): {\n min: number;\n max: number;\n } {\n let min = 255;\n let max = 0;\n for (let i = 0; i < this.length; ++i) {\n const c = this.getPixelByIndex(i);\n const r = Color.getRed(c);\n const g = Color.getGreen(c);\n const b = Color.getBlue(c);\n\n if (r < min) {\n min = r;\n }\n if (r > max) {\n max = r;\n }\n if (g < min) {\n min = g;\n }\n if (g > max) {\n max = g;\n }\n if (b < min) {\n min = b;\n }\n if (b > max) {\n max = b;\n }\n if (this.rgbChannelSet === RgbChannelSet.rgba) {\n const a = Color.getAlpha(c);\n if (a < min) {\n min = a;\n }\n if (a > max) {\n max = a;\n }\n }\n }\n\n return {\n min: min,\n max: max,\n };\n }\n\n public addTextData(data: Map): void {\n if (this._textData === undefined) {\n this._textData = new Map();\n }\n for (const [key, value] of data) {\n this._textData.set(key, value);\n }\n }\n}\n", "/** @format */\n\nimport { Color } from './color';\nimport { MemoryImage } from './memory-image';\nimport { Quantizer } from './quantizer';\n\n/**\n * Compute a color map with a given number of colors that best represents\n * the given image.\n */\nexport class NeuralQuantizer implements Quantizer {\n // No. of learning cycles\n private static readonly numCycles: number = 100;\n\n // Alpha starts at 1\n private static readonly alphaBiasShift: number = 10;\n\n // Biased by 10 bits\n private static readonly initAlpha: number =\n 1 << NeuralQuantizer.alphaBiasShift;\n\n private static readonly radiusBiasShift: number = 8;\n\n private static readonly radiusBias: number =\n 1 << NeuralQuantizer.radiusBiasShift;\n\n private static readonly alphaRadiusBiasShift: number =\n NeuralQuantizer.alphaBiasShift + NeuralQuantizer.radiusBiasShift;\n\n private static readonly alphaRadiusBias: number =\n 1 << NeuralQuantizer.alphaRadiusBiasShift;\n\n // Factor of 1/30 each cycle\n private static readonly radiusDec: number = 30;\n\n private static readonly gamma: number = 1024;\n\n private static readonly beta: number = 1 / 1024;\n\n private static readonly betaGamma: number =\n NeuralQuantizer.beta * NeuralQuantizer.gamma;\n\n // Four primes near 500 - assume no image has a length so large\n // that it is divisible by all four primes\n\n private static readonly prime1 = 499;\n\n private static readonly prime2 = 491;\n\n private static readonly prime3 = 487;\n\n private static readonly prime4 = 503;\n\n private static readonly smallImageBytes = 3 * NeuralQuantizer.prime4;\n\n private readonly netIndex = new Int32Array(256);\n\n private samplingFactor: number;\n\n // Number of colors used\n private netSize = 16;\n\n // Number of reserved colors used\n private specials = 3;\n\n // Reserved background color\n private bgColor = 0;\n\n private cutNetSize = 0;\n\n private maxNetPos = 0;\n\n // For 256 cols, radius starts at 32\n private initRadius = 0;\n\n private initBiasRadius = 0;\n\n private radiusPower!: Int32Array;\n\n /**\n * The network itself\n */\n private network!: number[];\n\n private _colorMap8!: Uint8Array;\n public get colorMap8(): Uint8Array {\n return this._colorMap8;\n }\n\n private _colorMap32!: Int32Array;\n public get colorMap32(): Int32Array {\n return this._colorMap32;\n }\n\n /**\n * Bias array for learning\n */\n private bias!: number[];\n\n // Freq array for learning\n private freq!: number[];\n\n /**\n * How many colors are in the **colorMap**?\n */\n get numColors(): number {\n return this.netSize;\n }\n\n /**\n * 10 is a reasonable **samplingFactor** according to\n * https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/.\n */\n constructor(image: MemoryImage, numberOfColors = 256, samplingFactor = 10) {\n this.samplingFactor = samplingFactor;\n this.initialize(numberOfColors);\n this.addImage(image);\n }\n\n private initialize(numberOfColors: number): void {\n // Number of colours used\n this.netSize = Math.max(numberOfColors, 4);\n this.cutNetSize = this.netSize - this.specials;\n this.maxNetPos = this.netSize - 1;\n // For 256 cols, radius starts at 32\n this.initRadius = Math.floor(this.netSize / 8);\n this.initBiasRadius = this.initRadius * NeuralQuantizer.radiusBias;\n this._colorMap32 = new Int32Array(this.netSize * 4);\n this._colorMap8 = new Uint8Array(this.netSize * 3);\n // Number of reserved colors used\n this.specials = 3;\n this.bgColor = this.specials - 1;\n this.radiusPower = new Int32Array(this.netSize >> 3);\n\n this.network = new Array(this.netSize * 3).fill(0);\n this.bias = new Array(this.netSize).fill(0);\n this.freq = new Array(this.netSize).fill(0);\n\n // Black\n this.network[0] = 0.0;\n this.network[1] = 0.0;\n this.network[2] = 0.0;\n\n // White\n this.network[3] = 255.0;\n this.network[4] = 255.0;\n this.network[5] = 255.0;\n\n // RESERVED bgColor\n // background\n const f = 1.0 / this.netSize;\n for (let i = 0; i < this.specials; ++i) {\n this.freq[i] = f;\n this.bias[i] = 0.0;\n }\n\n for (let i = this.specials, p = this.specials * 3; i < this.netSize; ++i) {\n this.network[p++] = (255.0 * (i - this.specials)) / this.cutNetSize;\n this.network[p++] = (255.0 * (i - this.specials)) / this.cutNetSize;\n this.network[p++] = (255.0 * (i - this.specials)) / this.cutNetSize;\n\n this.freq[i] = f;\n this.bias[i] = 0.0;\n }\n }\n\n private updateRadiusPower(rad: number, alpha: number): void {\n for (let i = 0; i < rad; i++) {\n this.radiusPower[i] = Math.trunc(\n alpha *\n (((rad * rad - i * i) * NeuralQuantizer.radiusBias) / (rad * rad))\n );\n }\n }\n\n private specialFind(b: number, g: number, r: number): number {\n for (let i = 0, p = 0; i < this.specials; i++) {\n if (\n this.network[p++] === b &&\n this.network[p++] === g &&\n this.network[p++] === r\n ) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Search for biased BGR values\n */\n private contest(b: number, g: number, r: number): number {\n // Finds closest neuron (min dist) and updates freq\n // finds best neuron (min dist-bias) and returns position\n // for frequently chosen neurons, freq[i] is high and bias[i] is negative\n // bias[i] = gamma*((1/netsize)-freq[i])\n let bestd = 1.0e30;\n let bestBiasDist: number = bestd;\n let bestpos = -1;\n let bestbiaspos: number = bestpos;\n\n for (let i = this.specials, p = this.specials * 3; i < this.netSize; i++) {\n let dist = this.network[p++] - b;\n if (dist < 0) {\n dist = -dist;\n }\n let a = this.network[p++] - g;\n if (a < 0) {\n a = -a;\n }\n dist += a;\n a = this.network[p++] - r;\n if (a < 0) {\n a = -a;\n }\n dist += a;\n if (dist < bestd) {\n bestd = dist;\n bestpos = i;\n }\n\n const biasDist = dist - this.bias[i];\n if (biasDist < bestBiasDist) {\n bestBiasDist = biasDist;\n bestbiaspos = i;\n }\n this.freq[i] -= NeuralQuantizer.beta * this.freq[i];\n this.bias[i] += NeuralQuantizer.betaGamma * this.freq[i];\n }\n this.freq[bestpos] += NeuralQuantizer.beta;\n this.bias[bestpos] -= NeuralQuantizer.betaGamma;\n return bestbiaspos;\n }\n\n private alterSingle(\n alpha: number,\n i: number,\n b: number,\n g: number,\n r: number\n ): void {\n // Move neuron i towards biased (b,g,r) by factor alpha\n const p = i * 3;\n this.network[p] -= alpha * (this.network[p] - b);\n this.network[p + 1] -= alpha * (this.network[p + 1] - g);\n this.network[p + 2] -= alpha * (this.network[p + 2] - r);\n }\n\n private alterNeighbors(\n _: number,\n rad: number,\n i: number,\n b: number,\n g: number,\n r: number\n ): void {\n let lo = i - rad;\n if (lo < this.specials - 1) {\n lo = this.specials - 1;\n }\n\n let hi = i + rad;\n if (hi > this.netSize) {\n hi = this.netSize;\n }\n\n let j = i + 1;\n let k = i - 1;\n let m = 1;\n while (j < hi || k > lo) {\n const a = this.radiusPower[m++];\n if (j < hi) {\n const p = j * 3;\n this.network[p] -=\n (a * (this.network[p] - b)) / NeuralQuantizer.alphaRadiusBias;\n this.network[p + 1] -=\n (a * (this.network[p + 1] - g)) / NeuralQuantizer.alphaRadiusBias;\n this.network[p + 2] -=\n (a * (this.network[p + 2] - r)) / NeuralQuantizer.alphaRadiusBias;\n j++;\n }\n if (k > lo) {\n const p = k * 3;\n this.network[p] -=\n (a * (this.network[p] - b)) / NeuralQuantizer.alphaRadiusBias;\n this.network[p + 1] -=\n (a * (this.network[p + 1] - g)) / NeuralQuantizer.alphaRadiusBias;\n this.network[p + 2] -=\n (a * (this.network[p + 2] - r)) / NeuralQuantizer.alphaRadiusBias;\n k--;\n }\n }\n }\n\n private learn(image: MemoryImage): void {\n let biasRadius = this.initBiasRadius;\n const alphaDec = 30 + Math.floor((this.samplingFactor - 1) / 3);\n const lengthCount = image.length;\n const samplePixels = Math.floor(lengthCount / this.samplingFactor);\n let delta = Math.max(\n Math.floor(samplePixels / NeuralQuantizer.numCycles),\n 1\n );\n let alpha = NeuralQuantizer.initAlpha;\n\n if (delta === 0) {\n delta = 1;\n }\n\n let rad = biasRadius >> NeuralQuantizer.radiusBiasShift;\n if (rad <= 1) {\n rad = 0;\n }\n\n this.updateRadiusPower(rad, alpha);\n\n let step = 0;\n let pos = 0;\n if (lengthCount < NeuralQuantizer.smallImageBytes) {\n this.samplingFactor = 1;\n step = 1;\n } else if (lengthCount % NeuralQuantizer.prime1 !== 0) {\n step = NeuralQuantizer.prime1;\n } else {\n if (lengthCount % NeuralQuantizer.prime2 !== 0) {\n step = NeuralQuantizer.prime2;\n } else {\n if (lengthCount % NeuralQuantizer.prime3 !== 0) {\n step = NeuralQuantizer.prime3;\n } else {\n step = NeuralQuantizer.prime4;\n }\n }\n }\n\n let i = 0;\n while (i < samplePixels) {\n const p = image.getPixelByIndex(pos);\n const red = Color.getRed(p);\n const green = Color.getGreen(p);\n const blue = Color.getBlue(p);\n\n if (i === 0) {\n // Remember background colour\n this.network[this.bgColor * 3] = blue;\n this.network[this.bgColor * 3 + 1] = green;\n this.network[this.bgColor * 3 + 2] = red;\n }\n\n let j = this.specialFind(blue, green, red);\n j = j < 0 ? this.contest(blue, green, red) : j;\n\n if (j >= this.specials) {\n // Don't learn for specials\n const a = Number(alpha) / NeuralQuantizer.initAlpha;\n this.alterSingle(a, j, blue, green, red);\n if (rad > 0) {\n // Alter neighbours\n this.alterNeighbors(a, rad, j, blue, green, red);\n }\n }\n\n pos += step;\n while (pos >= lengthCount) {\n pos -= lengthCount;\n }\n\n i++;\n if (i % delta === 0) {\n alpha -= Math.floor(alpha / alphaDec);\n biasRadius -= Math.floor(biasRadius / NeuralQuantizer.radiusDec);\n rad = biasRadius >> NeuralQuantizer.radiusBiasShift;\n if (rad <= 1) {\n rad = 0;\n }\n this.updateRadiusPower(rad, alpha);\n }\n }\n }\n\n private fix(): void {\n for (let i = 0, p = 0, q = 0; i < this.netSize; i++, q += 4) {\n for (let j = 0; j < 3; ++j, ++p) {\n let x = Math.trunc(0.5 + this.network[p]);\n if (x < 0) {\n x = 0;\n }\n if (x > 255) {\n x = 255;\n }\n this._colorMap32[q + j] = x;\n }\n this._colorMap32[q + 3] = i;\n }\n }\n\n /**\n * Insertion sort of network and building of netindex[0..255]\n */\n private inxBuild(): void {\n let previousColor = 0;\n let startPos = 0;\n\n for (let i = 0, p = 0; i < this.netSize; i++, p += 4) {\n let smallpos = i;\n // Index on g\n let smallval = this._colorMap32[p + 1];\n\n // Find smallest in i..netsize-1\n for (let j = i + 1, q = p + 4; j < this.netSize; j++, q += 4) {\n if (this._colorMap32[q + 1] < smallval) {\n // Index on g\n smallpos = j;\n // Index on g\n smallval = this._colorMap32[q + 1];\n }\n }\n\n const q = smallpos * 4;\n\n // Swap p (i) and q (smallpos) entries\n if (i !== smallpos) {\n let j = this._colorMap32[q];\n this._colorMap32[q] = this._colorMap32[p];\n this._colorMap32[p] = j;\n\n j = this._colorMap32[q + 1];\n this._colorMap32[q + 1] = this._colorMap32[p + 1];\n this._colorMap32[p + 1] = j;\n\n j = this._colorMap32[q + 2];\n this._colorMap32[q + 2] = this._colorMap32[p + 2];\n this.colorMap32[p + 2] = j;\n\n j = this._colorMap32[q + 3];\n this._colorMap32[q + 3] = this._colorMap32[p + 3];\n this._colorMap32[p + 3] = j;\n }\n\n // SmallVal entry is now in position i\n if (smallval !== previousColor) {\n this.netIndex[previousColor] = (startPos + i) >> 1;\n for (let j = previousColor + 1; j < smallval; j++) {\n this.netIndex[j] = i;\n }\n previousColor = smallval;\n startPos = i;\n }\n }\n\n this.netIndex[previousColor] = (startPos + this.maxNetPos) >> 1;\n for (let j = previousColor + 1; j < 256; j++) {\n // Really 256\n this.netIndex[j] = this.maxNetPos;\n }\n }\n\n private copyColorMap(): void {\n for (let i = 0, p = 0, q = 0; i < this.netSize; ++i) {\n this._colorMap8[p++] = Math.abs(this._colorMap32[q + 2]) & 0xff;\n this._colorMap8[p++] = Math.abs(this._colorMap32[q + 1]) & 0xff;\n this._colorMap8[p++] = Math.abs(this._colorMap32[q]) & 0xff;\n q += 4;\n }\n }\n\n /**\n * Add an image to the quantized color table.\n */\n private addImage(image: MemoryImage): void {\n this.learn(image);\n this.fix();\n this.inxBuild();\n this.copyColorMap();\n }\n\n /**\n * Search for BGR values 0..255 and return color index\n */\n private inxSearch(b: number, g: number, r: number): number {\n // Biggest possible dist is 256*3\n let bestd = 1000;\n let best = -1;\n // Index on g\n let i = this.netIndex[g];\n // Start at netindex[g] and work outwards\n let j = i - 1;\n\n while (i < this.netSize || j >= 0) {\n if (i < this.netSize) {\n const p = i * 4;\n let dist = this._colorMap32[p + 1] - g;\n // Inx key\n if (dist >= bestd) {\n // Stop iter\n i = this.netSize;\n } else {\n if (dist < 0) {\n dist = -dist;\n }\n let a = this._colorMap32[p] - b;\n if (a < 0) {\n a = -a;\n }\n dist += a;\n if (dist < bestd) {\n a = this._colorMap32[p + 2] - r;\n if (a < 0) {\n a = -a;\n }\n dist += a;\n if (dist < bestd) {\n bestd = dist;\n best = i;\n }\n }\n i++;\n }\n }\n\n if (j >= 0) {\n const p = j * 4;\n // Inx key - reverse dif\n let dist = g - this._colorMap32[p + 1];\n if (dist >= bestd) {\n // Stop iter\n j = -1;\n } else {\n if (dist < 0) {\n dist = -dist;\n }\n let a = this._colorMap32[p] - b;\n if (a < 0) {\n a = -a;\n }\n dist += a;\n if (dist < bestd) {\n a = this._colorMap32[p + 2] - r;\n if (a < 0) {\n a = -a;\n }\n dist += a;\n if (dist < bestd) {\n bestd = dist;\n best = j;\n }\n }\n j--;\n }\n }\n }\n return best;\n }\n\n /**\n * Get a color from the **colorMap**.\n */\n public color(index: number): number {\n return Color.getColor(\n this._colorMap8[index * 3],\n this._colorMap8[index * 3 + 1],\n this._colorMap8[index * 3 + 2]\n );\n }\n\n /**\n * Find the index of the closest color to **c** in the **colorMap**.\n */\n public lookup(c: number): number {\n const r = Color.getRed(c);\n const g = Color.getGreen(c);\n const b = Color.getBlue(c);\n return this.inxSearch(b, g, r);\n }\n\n /**\n * Find the index of the closest color to **r**,**g**,**b** in the **colorMap**.\n */\n public lookupRGB(r: number, g: number, b: number): number {\n return this.inxSearch(b, g, r);\n }\n\n /**\n * Find the color closest to **c** in the **colorMap**.\n */\n public getQuantizedColor(c: number): number {\n const r = Color.getRed(c);\n const g = Color.getGreen(c);\n const b = Color.getBlue(c);\n const a = Color.getAlpha(c);\n const i = this.inxSearch(b, g, r) * 3;\n return Color.getColor(\n this._colorMap8[i],\n this._colorMap8[i + 1],\n this._colorMap8[i + 2],\n a\n );\n }\n\n /**\n * Convert the **image** to an index map, mapping to this **colorMap**.\n */\n public getIndexMap(image: MemoryImage): Uint8Array {\n const map = new Uint8Array(image.width * image.height);\n for (let i = 0, len = image.length; i < len; ++i) {\n map[i] = this.lookup(image.getPixelByIndex(i));\n }\n return map;\n }\n}\n", "/** @format */\n\nexport class OctreeNode {\n // sum of all colors represented by this node.\n private _r = 0;\n public get r(): number {\n return this._r;\n }\n public set r(v: number) {\n this._r = v;\n }\n\n private _g = 0;\n public get g(): number {\n return this._g;\n }\n public set g(v: number) {\n this._g = v;\n }\n\n private _b = 0;\n public get b(): number {\n return this._b;\n }\n public set b(v: number) {\n this._b = v;\n }\n\n private _count = 0;\n public get count(): number {\n return this._count;\n }\n public set count(v: number) {\n this._count = v;\n }\n\n private _heapIndex = 0;\n public get heapIndex(): number {\n return this._heapIndex;\n }\n public set heapIndex(v: number) {\n this._heapIndex = v;\n }\n\n private _parent: OctreeNode | undefined;\n public get parent(): OctreeNode | undefined {\n return this._parent;\n }\n\n private _children: Array = new Array<\n OctreeNode | undefined\n >(8).fill(undefined);\n public get children(): Array {\n return this._children;\n }\n\n private _childCount = 0;\n public get childCount(): number {\n return this._childCount;\n }\n public set childCount(v: number) {\n this._childCount = v;\n }\n\n private _childIndex = 0;\n public get childIndex(): number {\n return this._childIndex;\n }\n\n private _flags = 0;\n public get flags(): number {\n return this._flags;\n }\n public set flags(v: number) {\n this._flags = v;\n }\n\n private _depth = 0;\n public get depth(): number {\n return this._depth;\n }\n\n constructor(childIndex: number, depth: number, parent?: OctreeNode) {\n this._childIndex = childIndex;\n this._depth = depth;\n this._parent = parent;\n if (parent !== undefined) {\n parent._childCount++;\n }\n }\n}\n", "/** @format */\n\nimport { Color } from './color';\nimport { HeapNode } from './heap-node';\nimport { MemoryImage } from './memory-image';\nimport { OctreeNode } from './octree-node';\nimport { Quantizer } from './quantizer';\n\n/**\n * Color quantization using octree,\n * from https://rosettacode.org/wiki/Color_quantization/C\n */\nexport class OctreeQuantizer implements Quantizer {\n private static readonly ON_INHEAP = 1;\n\n private readonly root: OctreeNode;\n\n constructor(image: MemoryImage, numberOfColors = 256) {\n this.root = new OctreeNode(0, 0);\n const heap = new HeapNode();\n for (let si = 0; si < image.length; ++si) {\n const c = image.getPixelByIndex(si);\n const r = Color.getRed(c);\n const g = Color.getGreen(c);\n const b = Color.getBlue(c);\n this.heapAdd(heap, this.nodeInsert(this.root, r, g, b));\n }\n\n const nc = numberOfColors + 1;\n while (heap.n > nc) {\n this.heapAdd(heap, this.nodeFold(this.popHeap(heap)!)!);\n }\n\n for (let i = 1; i < heap.n; i++) {\n const got = heap.buf[i]!;\n const c = got.count;\n got.r = Math.round(got.r / c);\n got.g = Math.round(got.g / c);\n got.b = Math.round(got.b / c);\n }\n }\n\n private nodeInsert(\n root: OctreeNode,\n r: number,\n g: number,\n b: number\n ): OctreeNode {\n let _root = root;\n\n let depth = 0;\n for (let bit = 1 << 7; ++depth < 8; bit >>= 1) {\n const i =\n ((g & bit) !== 0 ? 1 : 0) * 4 +\n ((r & bit) !== 0 ? 1 : 0) * 2 +\n ((b & bit) !== 0 ? 1 : 0);\n if (_root.children[i] === undefined) {\n _root.children[i] = new OctreeNode(i, depth, _root);\n }\n _root = _root.children[i]!;\n }\n\n _root.r += r;\n _root.g += g;\n _root.b += b;\n _root.count++;\n return _root;\n }\n\n private popHeap(h: HeapNode): OctreeNode | undefined {\n if (h.n <= 1) {\n return undefined;\n }\n\n const ret = h.buf[1];\n h.buf[1] = h.buf.pop();\n h.buf[1]!.heapIndex = 1;\n this.downHeap(h, h.buf[1]!);\n\n return ret;\n }\n\n private heapAdd(h: HeapNode, p: OctreeNode): void {\n if ((p.flags & OctreeQuantizer.ON_INHEAP) !== 0) {\n this.downHeap(h, p);\n this.upHeap(h, p);\n return;\n }\n\n p.flags |= OctreeQuantizer.ON_INHEAP;\n p.heapIndex = h.n;\n h.buf.push(p);\n this.upHeap(h, p);\n }\n\n private downHeap(h: HeapNode, p: OctreeNode): void {\n let n = p.heapIndex;\n while (true) {\n let m = n * 2;\n if (m >= h.n) {\n break;\n }\n if (m + 1 < h.n && this.compareNode(h.buf[m]!, h.buf[m + 1]!) > 0) {\n m++;\n }\n\n if (this.compareNode(p, h.buf[m]!) <= 0) {\n break;\n }\n\n h.buf[n] = h.buf[m];\n h.buf[n]!.heapIndex = n;\n n = m;\n }\n\n h.buf[n] = p;\n p.heapIndex = n;\n }\n\n private upHeap(h: HeapNode, p: OctreeNode): void {\n let n = p.heapIndex;\n let prev: OctreeNode | undefined = undefined;\n\n while (n > 1) {\n prev = h.buf[Math.trunc(n / 2)];\n if (this.compareNode(p, prev!) >= 0) {\n break;\n }\n\n h.buf[n] = prev;\n prev!.heapIndex = n;\n n = Math.trunc(n / 2);\n }\n h.buf[n] = p;\n p.heapIndex = n;\n }\n\n private nodeFold(p: OctreeNode): OctreeNode | undefined {\n if (p.childCount > 0) {\n return undefined;\n }\n const q = p.parent!;\n q.count += p.count;\n\n q.r += p.r;\n q.g += p.g;\n q.b += p.b;\n q.childCount--;\n q.children[p.childIndex] = undefined;\n return q;\n }\n\n private compareNode(a: OctreeNode, b: OctreeNode): number {\n if (a.childCount < b.childCount) {\n return -1;\n }\n if (a.childCount > b.childCount) {\n return 1;\n }\n\n const ac = a.count >> a.depth;\n const bc = b.count >> b.depth;\n return ac < bc ? -1 : ac > bc ? 1 : 0;\n }\n\n /**\n * Find the index of the closest color to **c** in the **colorMap**.\n */\n public getQuantizedColor(c: number): number {\n let r = Color.getRed(c);\n let g = Color.getGreen(c);\n let b = Color.getBlue(c);\n let root: OctreeNode | undefined = this.root;\n\n for (let bit = 1 << 7; bit !== 0; bit >>= 1) {\n const i =\n ((g & bit) !== 0 ? 1 : 0) * 4 +\n ((r & bit) !== 0 ? 1 : 0) * 2 +\n ((b & bit) !== 0 ? 1 : 0);\n if (root!.children[i] === undefined) {\n break;\n }\n root = root!.children[i];\n }\n\n r = root!.r;\n g = root!.g;\n b = root!.b;\n return Color.getColor(r, g, b);\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from './input-buffer';\nimport { ArrayUtils } from './array-utils';\n\nexport interface OutputBufferInitOptions {\n bigEndian?: boolean;\n size?: number;\n}\n\nexport class OutputBuffer {\n // 8k block-size\n private static readonly BLOCK_SIZE = 0x2000;\n\n private _buffer: Uint8Array;\n public get buffer(): Uint8Array {\n return this._buffer;\n }\n\n private _bigEndian: boolean;\n public get bigEndian(): boolean {\n return this._bigEndian;\n }\n public set bigEndian(v: boolean) {\n this._bigEndian = v;\n }\n\n private _length: number;\n public get length(): number {\n return this._length;\n }\n public set length(v: number) {\n this._length = v;\n }\n\n /**\n * Create a byte buffer for writing.\n */\n constructor(options?: OutputBufferInitOptions) {\n this._bigEndian = options?.bigEndian ?? false;\n this._buffer = new Uint8Array(options?.size ?? OutputBuffer.BLOCK_SIZE);\n this._length = 0;\n }\n\n /**\n * Grow the buffer to accommodate additional data.\n */\n private expandBuffer(required?: number): void {\n let blockSize: number = OutputBuffer.BLOCK_SIZE;\n if (required !== undefined) {\n blockSize = required;\n } else if (this._buffer.length > 0) {\n blockSize = this._buffer.length * 2;\n }\n const newBuffer = new Uint8Array(this._buffer.length + blockSize);\n ArrayUtils.setRange(newBuffer, 0, this._buffer.length, this._buffer);\n this._buffer = newBuffer;\n }\n\n public rewind(): void {\n this._length = 0;\n }\n\n /**\n * Clear the buffer.\n */\n public clear(): void {\n this._buffer = new Uint8Array(OutputBuffer.BLOCK_SIZE);\n this._length = 0;\n }\n\n /**\n * Get the resulting bytes from the buffer.\n */\n public getBytes(): Uint8Array {\n return new Uint8Array(this._buffer.buffer, 0, this._length);\n }\n\n /**\n * Write a byte to the end of the buffer.\n */\n public writeByte(value: number): void {\n if (this._length === this._buffer.length) {\n this.expandBuffer();\n }\n this._buffer[this._length++] = value & 0xff;\n }\n\n /**\n * Write a set of bytes to the end of the buffer.\n */\n public writeBytes(bytes: Uint8Array, length?: number): void {\n const correctedLength = length ?? bytes.length;\n while (this._length + correctedLength > this._buffer.length) {\n this.expandBuffer(this._length + correctedLength - this._buffer.length);\n }\n ArrayUtils.setRange(\n this._buffer,\n this._length,\n this._length + correctedLength,\n bytes\n );\n this._length += correctedLength;\n }\n\n public writeBuffer(bytes: InputBuffer): void {\n while (length + bytes.length > this._buffer.length) {\n this.expandBuffer(length + bytes.length - this._buffer.length);\n }\n ArrayUtils.setRange(\n this._buffer,\n length,\n length + bytes.length,\n bytes.buffer,\n bytes.offset\n );\n this._length += bytes.length;\n }\n\n /**\n * Write a 16-bit word to the end of the buffer.\n */\n public writeUint16(value: number): void {\n if (this._bigEndian) {\n this.writeByte((value >> 8) & 0xff);\n this.writeByte(value & 0xff);\n return;\n }\n this.writeByte(value & 0xff);\n this.writeByte((value >> 8) & 0xff);\n }\n\n /**\n * Write a 32-bit word to the end of the buffer.\n */\n public writeUint32(value: number): void {\n if (this._bigEndian) {\n this.writeByte((value >> 24) & 0xff);\n this.writeByte((value >> 16) & 0xff);\n this.writeByte((value >> 8) & 0xff);\n this.writeByte(value & 0xff);\n return;\n }\n this.writeByte(value & 0xff);\n this.writeByte((value >> 8) & 0xff);\n this.writeByte((value >> 16) & 0xff);\n this.writeByte((value >> 24) & 0xff);\n }\n\n /**\n * Write a 32-bit float value to the end of the buffer.\n */\n public writeFloat32(value: number): void {\n const fb = new Float32Array(1);\n fb[0] = value;\n const b = new Uint8Array(fb.buffer);\n if (this._bigEndian) {\n this.writeByte(b[3]);\n this.writeByte(b[2]);\n this.writeByte(b[1]);\n this.writeByte(b[0]);\n return;\n }\n this.writeByte(b[0]);\n this.writeByte(b[1]);\n this.writeByte(b[2]);\n this.writeByte(b[3]);\n }\n\n /**\n * Write a 64-bit float value to the end of the buffer.\n */\n public writeFloat64(value: number): void {\n const fb = new Float64Array(1);\n fb[0] = value;\n const b = new Uint8Array(fb.buffer);\n if (this._bigEndian) {\n this.writeByte(b[7]);\n this.writeByte(b[6]);\n this.writeByte(b[5]);\n this.writeByte(b[4]);\n this.writeByte(b[3]);\n this.writeByte(b[2]);\n this.writeByte(b[1]);\n this.writeByte(b[0]);\n return;\n }\n this.writeByte(b[0]);\n this.writeByte(b[1]);\n this.writeByte(b[2]);\n this.writeByte(b[3]);\n this.writeByte(b[4]);\n this.writeByte(b[5]);\n this.writeByte(b[6]);\n this.writeByte(b[7]);\n }\n\n /**\n * Return the subarray of the buffer in the range **start**:**end**.\n * If **start** or **end** are < 0 then it is relative to the end of the buffer.\n * If **end** is not specified (or undefined), then it is the end of the buffer.\n * This is equivalent to the python list range operator.\n */\n public subarray(start: number, end?: number): Uint8Array {\n const correctedStart: number = start >= 0 ? start : this._length + start;\n let correctedEnd: number = end ?? this._length;\n if (correctedEnd < 0) {\n correctedEnd = this._length + correctedEnd;\n }\n return new Uint8Array(\n this._buffer.buffer,\n correctedStart,\n correctedEnd - correctedStart\n );\n }\n}\n", "/**\n * 2-dimensional point\n *\n * @format\n */\n\nexport class Point {\n private _x: number;\n private _y: number;\n\n public get x(): number {\n return this._x;\n }\n\n public get y(): number {\n return this._y;\n }\n\n public get xt() {\n return Math.trunc(this.x);\n }\n\n public get yt() {\n return Math.trunc(this.y);\n }\n\n constructor(x: number, y: number) {\n this._x = x;\n this._y = y;\n }\n\n public static from(other: Point): Point {\n return new Point(other._x, other._y);\n }\n\n public move(x: number, y: number): Point {\n this._x = x;\n this._y = y;\n return this;\n }\n\n public offset(dx: number, dy: number): Point {\n return this.move(this._x + dx, this._y + dy);\n }\n\n public mul(n: number): Point {\n return this.move(this._x * n, this._y * n);\n }\n\n public add(p: Point): Point {\n return this.move(this._x + p.x, this._y + p.y);\n }\n\n public equals(other: unknown) {\n return (\n other instanceof Point && this._x === other._x && this._y === other._y\n );\n }\n}\n", "/** @format */\n\nexport interface Quantizer {\n /**\n * Find the index of the closest color to **c** in the **colorMap**.\n */\n getQuantizedColor(c: number): number;\n}\n", "/** @format */\n\nexport abstract class RandomUtils {\n /**\n * Return a random variable between [**-1**,**1**].\n */\n public static crand(): number {\n return 1 - 2 * Math.random();\n }\n\n /**\n * Return a random variable following a gaussian distribution and a standard\n * deviation of 1.\n */\n public static grand(): number {\n let x1 = 0;\n let w = 0;\n do {\n const x2 = 2 * Math.random() - 1;\n x1 = 2 * Math.random() - 1;\n w = x1 * x1 + x2 * x2;\n } while (w <= 0 || w >= 1);\n\n return x1 * Math.sqrt((-2 * Math.log(w)) / w);\n }\n\n /**\n * Return a random variable following a Poisson distribution of parameter **z**.\n */\n public static prand(z: number): number {\n if (z <= 1e-10) {\n return 0;\n }\n if (z > 100) {\n return Math.trunc(Math.sqrt(z) * RandomUtils.grand() + z);\n }\n let k = 0;\n const y = Math.exp(-z);\n for (let s = 1.0; s >= y; ++k) {\n s *= Math.random();\n }\n return k - 1;\n }\n}\n", "/** @format */\n\nimport { Point } from './point';\n\nexport class Rectangle {\n private _left = 0;\n private _top = 0;\n private _right = 0;\n private _bottom = 0;\n private _width = 0;\n private _height = 0;\n\n public get left(): number {\n return this._left;\n }\n\n public get top(): number {\n return this._top;\n }\n\n public get right(): number {\n return this._right;\n }\n\n public get bottom(): number {\n return this._bottom;\n }\n\n public get width(): number {\n return this._width;\n }\n\n public get height(): number {\n return this._height;\n }\n\n constructor(x1: number, y1: number, x2: number, y2: number) {\n this.initialize(x1, y1, x2, y2);\n }\n\n public static fromXYWH(x: number, y: number, width: number, height: number) {\n return new Rectangle(x, y, x + width, y + height);\n }\n\n public static from(other: Rectangle) {\n return new Rectangle(other.left, other.top, other.right, other.bottom);\n }\n\n private initialize(x1: number, y1: number, x2: number, y2: number) {\n this._left = Math.min(x1, x2);\n this._top = Math.min(y1, y2);\n this._right = Math.max(x1, x2);\n this._bottom = Math.max(y1, y2);\n this._width = this._right - this._left;\n this._height = this._bottom - this._top;\n }\n}\n", "/** @format */\n\nexport type TypedArray =\n | Int8Array\n | Int16Array\n | Int32Array\n | Uint8Array\n | Uint16Array\n | Uint32Array\n | Float32Array\n | Float64Array;\n\nexport type BufferEncoding =\n | 'ascii'\n | 'utf8'\n | 'utf-8'\n | 'utf16le'\n | 'ucs2'\n | 'ucs-2'\n | 'base64'\n | 'latin1'\n | 'binary'\n | 'hex';\n\nexport type CompressionLevel =\n | -1\n | 0\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | undefined;\n", "/** @format */\n\nimport { MemoryImage } from '../common/memory-image';\n\nexport interface DrawImageOptions {\n dst: MemoryImage;\n src: MemoryImage;\n dstX?: number;\n dstY?: number;\n dstW?: number;\n dstH?: number;\n srcX?: number;\n srcY?: number;\n srcW?: number;\n srcH?: number;\n blend?: boolean;\n}\n", "/** @format */\n\nimport { Line } from '../common/line';\nimport { MemoryImage } from '../common/memory-image';\n\nexport interface DrawLineOptions {\n image: MemoryImage;\n line: Line;\n color: number;\n antialias?: boolean;\n thickness?: number;\n}\n", "/** @format */\n\nimport { Color } from '../common/color';\nimport { Line } from '../common/line';\nimport { MathOperators } from '../common/math-operators';\nimport { MemoryImage } from '../common/memory-image';\nimport { Point } from '../common/point';\nimport { Rectangle } from '../common/rectangle';\nimport { DrawImageOptions } from './draw-image-options';\nimport { DrawLineOptions } from './draw-line-options';\nimport { FillFloodOptions } from './fill-flood-options';\nimport { MaskFloodOptions } from './mask-flood-options';\n\ntype FillFloodTestPixel = (y: number, x: number) => boolean;\ntype FillFloodMarkPixel = (y: number, x: number) => void;\n\nexport abstract class Draw {\n // 0000\n private static readonly OUTCODE_INSIDE = 0;\n // 0001\n private static readonly OUTCODE_LEFT = 1;\n // 0010\n private static readonly OUTCODE_RIGHT = 2;\n // 0100\n private static readonly OUTCODE_BOTTOM = 4;\n // 1000\n private static readonly OUTCODE_TOP = 8;\n\n /**\n * Calculate the pixels that make up the circumference of a circle on the\n * given **image**, centered at **center** and the given **radius**.\n *\n * The returned list of points is sorted, first by the x coordinate, and\n * second by the y coordinate.\n */\n private static calculateCircumference(\n image: MemoryImage,\n center: Point,\n radius: number\n ): Point[] {\n if (\n radius < 0 ||\n center.x + radius < 0 ||\n center.x - radius >= image.width ||\n center.y + radius < 0 ||\n center.y - radius >= image.height\n ) {\n return [];\n }\n\n if (radius === 0) {\n return [center];\n }\n\n const points: Point[] = [\n new Point(center.x - radius, center.y),\n new Point(center.x + radius, center.y),\n new Point(center.x, center.y - radius),\n new Point(center.x, center.y + radius),\n ];\n\n if (radius === 1) {\n return points;\n }\n\n for (\n let f = 1 - radius, ddFx = 0, ddFy = -(radius << 1), x = 0, y = radius;\n x < y;\n\n ) {\n if (f >= 0) {\n ddFy += 2;\n f += ddFy;\n --y;\n }\n ++x;\n ddFx += 2;\n f += ddFx + 1;\n\n if (x !== y + 1) {\n const x1 = center.x - y;\n const x2 = center.x + y;\n const y1 = center.y - x;\n const y2 = center.y + x;\n const x3 = center.x - x;\n const x4 = center.x + x;\n const y3 = center.y - y;\n const y4 = center.y + y;\n\n points.push(new Point(x1, y1));\n points.push(new Point(x1, y2));\n points.push(new Point(x2, y1));\n points.push(new Point(x2, y2));\n\n if (x !== y) {\n points.push(new Point(x3, y3));\n points.push(new Point(x4, y4));\n points.push(new Point(x4, y3));\n points.push(new Point(x3, y4));\n }\n }\n }\n\n return points;\n }\n\n /**\n * Compute the bit code for a point **p** using the clip rectangle **rect**\n */\n private static computeOutCode(rect: Rectangle, p: Point): number {\n // initialized as being inside of clip window\n let code = Draw.OUTCODE_INSIDE;\n if (p.x < rect.left) {\n // to the left of clip window\n code |= Draw.OUTCODE_LEFT;\n } else if (p.x > rect.right) {\n // to the right of clip window\n code |= Draw.OUTCODE_RIGHT;\n }\n\n if (p.y < rect.top) {\n // below the clip window\n code |= Draw.OUTCODE_TOP;\n } else if (p.y > rect.bottom) {\n // above the clip window\n code |= Draw.OUTCODE_BOTTOM;\n }\n\n return code;\n }\n\n /**\n * Clip a line to a rectangle using the Cohen\u2013Sutherland clipping algorithm.\n * **line** is a **Line** object.\n * **rect** is a **Rectangle** object.\n * Results are stored in **line**.\n * If **line** falls completely outside of **rect**, false is returned, otherwise\n * true is returned.\n */\n private static clipLine(rect: Rectangle, line: Line): boolean {\n const xmin = rect.left;\n const ymin = rect.top;\n const xmax = rect.right;\n const ymax = rect.bottom;\n\n // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle\n let outcode1 = Draw.computeOutCode(\n rect,\n new Point(line.startX, line.startY)\n );\n let outcode2 = Draw.computeOutCode(rect, new Point(line.endX, line.endY));\n let accept = false;\n\n while (true) {\n if ((outcode1 | outcode2) === 0) {\n // Bitwise OR is 0. Trivially accept and get out of loop\n accept = true;\n break;\n } else if ((outcode1 & outcode2) !== 0) {\n // Bitwise AND is not 0. Trivially reject and get out of loop\n break;\n } else {\n // failed both tests, so calculate the line segment to clip\n // from an outside point to an intersection with clip edge\n\n // At least one endpoint is outside the clip rectangle; pick it.\n const outcodeOut = outcode1 !== 0 ? outcode1 : outcode2;\n\n let x = 0;\n let y = 0;\n\n // Now find the intersection point;\n // use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)\n if ((outcodeOut & Draw.OUTCODE_TOP) !== 0) {\n // point is above the clip rectangle\n x =\n line.startX +\n Math.trunc((line.dx * (ymin - line.startY)) / line.dy);\n y = ymin;\n } else if ((outcodeOut & Draw.OUTCODE_BOTTOM) !== 0) {\n // point is below the clip rectangle\n x =\n line.startX +\n Math.trunc((line.dx * (ymax - line.startY)) / line.dy);\n y = ymax;\n } else if ((outcodeOut & Draw.OUTCODE_RIGHT) !== 0) {\n // point is to the right of clip rectangle\n y =\n line.startY +\n Math.trunc((line.dy * (xmax - line.startX)) / line.dx);\n x = xmax;\n } else if ((outcodeOut & Draw.OUTCODE_LEFT) !== 0) {\n // point is to the left of clip rectangle\n y =\n line.startY +\n Math.trunc((line.dy * (xmin - line.startX)) / line.dx);\n x = xmin;\n }\n\n // Now we move outside point to intersection point to clip\n // and get ready for next pass.\n if (outcodeOut === outcode1) {\n line.moveStart(x, y);\n outcode1 = Draw.computeOutCode(\n rect,\n new Point(line.startX, line.startY)\n );\n } else {\n line.moveEnd(x, y);\n outcode2 = Draw.computeOutCode(rect, new Point(line.endX, line.endY));\n }\n }\n }\n\n return accept;\n }\n\n private static testPixelLabColorDistance(\n src: MemoryImage,\n x: number,\n y: number,\n refColor: number[],\n threshold: number\n ): boolean {\n const pixel = src.getPixel(x, y);\n const compareAlpha = refColor.length > 3;\n const pixelColor = Color.rgbToLab(\n Color.getRed(pixel),\n Color.getGreen(pixel),\n Color.getBlue(pixel)\n );\n if (compareAlpha) {\n pixelColor.push(Color.getAlpha(pixel));\n }\n return Color.distance(pixelColor, refColor, compareAlpha) > threshold;\n }\n\n /**\n * Adam Milazzo (2015). A More Efficient Flood Fill.\n * http://www.adammil.net/blog/v126_A_More_Efficient_Flood_Fill.html\n */\n private static fill4(\n src: MemoryImage,\n x: number,\n y: number,\n array: FillFloodTestPixel,\n mark: FillFloodMarkPixel,\n visited: Uint8Array\n ): void {\n let _x = x;\n let _y = y;\n\n if (visited[_y * src.width + _x] === 1) {\n return;\n }\n\n // at this point, we know array(y,x) is clear, and we want to move as far as\n // possible to the upper-left. moving up is much more important than moving\n // left, so we could try to make this smarter by sometimes moving to the\n // right if doing so would allow us to move further up, but it doesn't seem\n // worth the complexity\n while (true) {\n const ox = _x;\n const oy = _y;\n while (_y !== 0 && !array(_y - 1, _x)) {\n _y--;\n }\n while (_x !== 0 && !array(_y, _x - 1)) {\n _x--;\n }\n if (_x === ox && _y === oy) {\n break;\n }\n }\n Draw.fill4Core(src, _x, _y, array, mark, visited);\n }\n\n private static fill4Core(\n src: MemoryImage,\n x: number,\n y: number,\n array: FillFloodTestPixel,\n mark: FillFloodMarkPixel,\n visited: Uint8Array\n ): void {\n let _x = x;\n let _y = y;\n\n if (visited[_y * src.width + _x] === 1) {\n return;\n }\n // at this point, we know that array(y,x) is clear, and array(y-1,x) and\n // array(y,x-1) are set. We'll begin scanning down and to the right,\n // attempting to fill an entire rectangular block\n\n // the number of cells that were clear in the last row we scanned\n let lastRowLength = 0;\n\n do {\n let rowLength = 0;\n let sx = _x;\n // keep track of how long this row is. sx is the starting x for the main\n // scan below now we want to handle a case like |***|, where we fill 3\n // cells in the first row and then after we move to the second row we find\n // the first | **| cell is filled, ending our rectangular scan. rather\n // than handling this via the recursion below, we'll increase the starting\n // value of 'x' and reduce the last row length to match. then we'll continue\n // trying to set the narrower rectangular block\n if (lastRowLength !== 0 && array(_y, _x)) {\n // if this is not the first row and the leftmost cell is filled...\n do {\n if (--lastRowLength === 0) {\n // shorten the row. if it's full, we're done\n return;\n }\n // otherwise, update the starting point of the main scan to match\n } while (array(_y, ++_x));\n sx = _x;\n } else {\n // we also want to handle the opposite case, | **|, where we begin\n // scanning a 2-wide rectangular block and then find on the next row that\n // it has |***| gotten wider on the left. again, we could handle this\n // with recursion but we'd prefer to adjust x and lastRowLength instead\n for (; _x !== 0 && !array(_y, _x - 1); rowLength++, lastRowLength++) {\n mark(_y, --_x);\n // to avoid scanning the cells twice, we'll fill them and update\n // rowLength here if there's something above the new starting point,\n // handle that recursively. this deals with cases like |* **| when we\n // begin filling from (2,0), move down to (2,1), and then move left to\n // (0,1). The |****| main scan assumes the portion of the previous row\n // from x to x+lastRowLength has already been filled. adjusting x and\n // lastRowLength breaks that assumption in this case, so we must fix it\n if (_y !== 0 && !array(_y - 1, _x)) {\n // use _Fill since there may be more up and left\n Draw.fill4(src, _x, _y - 1, array, mark, visited);\n }\n }\n }\n\n // now at this point we can begin to scan the current row in the rectangular\n // block. the span of the previous row from x (inclusive) to x+lastRowLength\n // (exclusive) has already been filled, so we don't need to\n // check it. so scan across to the right in the current row\n for (; sx < src.width && !array(_y, sx); rowLength++, sx++) {\n mark(_y, sx);\n }\n // now we've scanned this row. if the block is rectangular, then the\n // previous row has already been scanned, so we don't need to look upwards\n // and we're going to scan the next row in the next iteration so we don't\n // need to look downwards. however, if the block is not rectangular, we may\n // need to look upwards or rightwards for some portion of the row. if this\n // row was shorter than the last row, we may need to look rightwards near\n // the end, as in the case of |*****|, where the first row is 5 cells long\n // and the second row is 3 cells long. We must look to the right |*** *|\n // of the single cell at the end of the second row, i.e. at (4,1)\n if (rowLength < lastRowLength) {\n // 'end' is the end of the previous row, so scan the current row to\n for (const end = _x + lastRowLength; ++sx < end; ) {\n // there. any clear cells would have been connected to the previous\n if (!array(_y, sx)) {\n // row. the cells up and left must be set so use FillCore\n Draw.fill4Core(src, sx, _y, array, mark, visited);\n }\n }\n }\n // alternately, if this row is longer than the previous row, as in the case\n // |*** *| then we must look above the end of the row, i.e at (4,0)\n // |*****|\n else if (rowLength > lastRowLength && _y !== 0) {\n // if this row is longer and we're not already at the top...\n for (let ux = _x + lastRowLength; ++ux < sx; ) {\n // sx is the end of the current row\n if (!array(_y - 1, ux)) {\n // since there may be clear cells up and left, use _Fill\n Draw.fill4(src, ux, _y - 1, array, mark, visited);\n }\n }\n }\n // record the new row length\n lastRowLength = rowLength;\n // if we get to a full row or to the bottom, we're done\n } while (lastRowLength !== 0 && ++_y < src.height);\n }\n\n /**\n * Draw a circle into the **image** with a center of **center** and\n * the given **radius** and **color**.\n */\n public static drawCircle(\n image: MemoryImage,\n center: Point,\n radius: number,\n color: number\n ): MemoryImage {\n const points = Draw.calculateCircumference(image, center, radius);\n for (const p of points) {\n Draw.drawPixel(image, p, color);\n }\n return image;\n }\n\n /**\n * Draw and fill a circle into the **image** with a **center**\n * and the given **radius** and **color**.\n *\n * The algorithm uses the same logic as **drawCircle** to calculate each point\n * around the circle's circumference. Then it iterates through every point,\n * finding the smallest and largest y-coordinate values for a given x-\n * coordinate.\n *\n * Once found, it draws a line connecting those two points. The circle is thus\n * filled one vertical slice at a time (each slice being 1-pixel wide).\n */\n public static fillCircle(\n image: MemoryImage,\n center: Point,\n radius: number,\n color: number\n ): MemoryImage {\n const points = Draw.calculateCircumference(image, center, radius);\n\n // sort points by x-coordinate and then by y-coordinate\n points.sort((a, b) => (a.x === b.x ? a.y - b.y : a.x - b.x));\n\n if (points.length > 0) {\n let start = points[0];\n let end = points[0];\n for (let i = 1; i < points.length; i++) {\n const p = points[i];\n if (p.x === start.x) {\n end = p;\n } else {\n Draw.drawLine({\n image: image,\n line: new Line(start.xt, start.yt, end.xt, end.yt),\n color: color,\n });\n start = p;\n end = p;\n }\n }\n Draw.drawLine({\n image: image,\n line: new Line(start.xt, start.yt, end.xt, end.yt),\n color: color,\n });\n }\n\n return image;\n }\n\n /**\n * Draw the image **src** onto the image **dst**.\n *\n * In other words, drawImage will take an rectangular area from **src** of\n * width **srcW** and height **srcH** at position (**srcX**,**srY**) and place it\n * in a rectangular area of **dst** of width **dstW** and height **dstH** at\n * position (**dstX**,**dstY**).\n *\n * If the source and destination coordinates and width and heights differ,\n * appropriate stretching or shrinking of the image fragment will be performed.\n * The coordinates refer to the upper left corner. This function can be used to\n * copy regions within the same image (if **dst** is the same as **src**)\n * but if the regions overlap the results will be unpredictable.\n */\n public static drawImage(options: DrawImageOptions): MemoryImage {\n const dstX = options.dstX ?? 0;\n const dstY = options.dstY ?? 0;\n const srcX = options.srcX ?? 0;\n const srcY = options.srcY ?? 0;\n const srcW = options.srcW ?? options.src.width;\n const srcH = options.srcH ?? options.src.height;\n const dstW = options.dstW ?? Math.min(options.dst.width, options.src.width);\n const dstH =\n options.dstH ?? Math.min(options.dst.height, options.src.height);\n const blend = options.blend ?? true;\n\n if (blend) {\n for (let y = 0; y < dstH; ++y) {\n for (let x = 0; x < dstW; ++x) {\n const stepX = Math.trunc(x * (srcW / dstW));\n const stepY = Math.trunc(y * (srcH / dstH));\n const srcPixel = options.src.getPixel(srcX + stepX, srcY + stepY);\n const point = new Point(dstX + x, dstY + y);\n Draw.drawPixel(options.dst, point, srcPixel);\n }\n }\n } else {\n for (let y = 0; y < dstH; ++y) {\n for (let x = 0; x < dstW; ++x) {\n const stepX = Math.trunc(x * (srcW / dstW));\n const stepY = Math.trunc(y * (srcH / dstH));\n const srcPixel = options.src.getPixel(srcX + stepX, srcY + stepY);\n options.dst.setPixel(dstX + x, dstY + y, srcPixel);\n }\n }\n }\n\n return options.dst;\n }\n\n /**\n * Draw a line into **image**.\n *\n * If **antialias** is true then the line is drawn with smooth edges.\n * **thickness** determines how thick the line should be drawn, in pixels.\n */\n public static drawLine(options: DrawLineOptions): MemoryImage {\n const line = Line.from(options.line);\n const isClipped = Draw.clipLine(\n new Rectangle(0, 0, options.image.width - 1, options.image.height - 1),\n line\n );\n if (!isClipped) {\n return options.image;\n }\n\n const thickness = options.thickness ?? 1;\n\n const radius = Math.floor(thickness / 2);\n\n // Drawing a single point.\n if (line.dx === 0 && line.dy === 0) {\n thickness === 1\n ? Draw.drawPixel(\n options.image,\n new Point(line.startX, line.startY),\n options.color\n )\n : Draw.fillCircle(\n options.image,\n new Point(line.startX, line.startY),\n radius,\n options.color\n );\n return options.image;\n }\n\n // Axis-aligned lines\n if (line.dx === 0) {\n for (let y = line.startY; y <= line.endY; ++y) {\n if (thickness <= 1) {\n const point = new Point(line.startX, y);\n Draw.drawPixel(options.image, point, options.color);\n } else {\n for (let i = 0; i < thickness; i++) {\n const point = new Point(line.startX - radius + i, y);\n Draw.drawPixel(options.image, point, options.color);\n }\n }\n }\n return options.image;\n } else if (line.dy === 0) {\n for (let x = line.startX; x <= line.endX; ++x) {\n if (thickness <= 1) {\n const point = new Point(x, line.startY);\n Draw.drawPixel(options.image, point, options.color);\n } else {\n for (let i = 0; i < thickness; i++) {\n const point = new Point(x, line.startY - radius + i);\n Draw.drawPixel(options.image, point, options.color);\n }\n }\n }\n return options.image;\n }\n\n // 16-bit xor\n const xor = (n: number) => (~n + 0x10000) & 0xffff;\n\n if (!options.antialias) {\n if (line.dy <= line.dx) {\n // More-or-less horizontal. use wid for vertical stroke\n const ac = Math.cos(Math.atan2(line.dy, line.dx));\n let wid = 0;\n if (ac !== 0) {\n wid = Math.trunc(thickness / ac);\n } else {\n wid = 1;\n }\n\n if (wid === 0) {\n wid = 1;\n }\n\n let d = 2 * line.dy - line.dx;\n const incr1 = 2 * line.dy;\n const incr2 = 2 * (line.dy - line.dx);\n\n let x = line.startX;\n let y = line.startY;\n\n // Set up line thickness\n let wstart = Math.trunc(y - wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n const point = new Point(x, w);\n Draw.drawPixel(options.image, point, options.color);\n }\n\n if (line.dy > 0) {\n while (x < line.endX) {\n x++;\n if (d < 0) {\n d += incr1;\n } else {\n y++;\n d += incr2;\n }\n wstart = Math.trunc(y - wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n const point = new Point(x, w);\n Draw.drawPixel(options.image, point, options.color);\n }\n }\n } else {\n while (x < line.endX) {\n x++;\n if (d < 0) {\n d += incr1;\n } else {\n y--;\n d += incr2;\n }\n wstart = Math.trunc(y - wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n const point = new Point(x, w);\n Draw.drawPixel(options.image, point, options.color);\n }\n }\n }\n } else {\n // More-or-less vertical. use wid for horizontal stroke\n const as = Math.sin(Math.atan2(line.dy, line.dx));\n let wid = 0;\n if (as !== 0) {\n wid = Math.trunc(thickness / as);\n } else {\n wid = 1;\n }\n if (wid === 0) {\n wid = 1;\n }\n\n let d = 2 * line.dx - line.dy;\n const incr1 = 2 * line.dx;\n const incr2 = 2 * (line.dx - line.dy);\n\n let x = line.startX;\n let y = line.startY;\n\n // Set up line thickness\n let wstart = Math.trunc(x - wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n const point = new Point(w, y);\n Draw.drawPixel(options.image, point, options.color);\n }\n\n if (line.endX - line.startX > 0) {\n while (y < line.endY) {\n y++;\n if (d < 0) {\n d += incr1;\n } else {\n x++;\n d += incr2;\n }\n wstart = Math.trunc(x - wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n const point = new Point(w, y);\n Draw.drawPixel(options.image, point, options.color);\n }\n }\n } else {\n while (y < line.endY) {\n y++;\n if (d < 0) {\n d += incr1;\n } else {\n x--;\n d += incr2;\n }\n wstart = Math.trunc(x - wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n const point = new Point(w, y);\n Draw.drawPixel(options.image, point, options.color);\n }\n }\n }\n }\n\n return options.image;\n }\n\n // Antialias Line\n\n const ag =\n line.dy < line.dx\n ? Math.cos(Math.atan2(line.dy, line.dx))\n : Math.sin(Math.atan2(line.dy, line.dx));\n\n let wid = 0;\n if (ag !== 0) {\n wid = Math.trunc(Math.abs(thickness / ag));\n } else {\n wid = 1;\n }\n if (wid === 0) {\n wid = 1;\n }\n\n if (line.dx > line.dy) {\n let y = line.startY;\n const inc = Math.trunc((line.dy * 65536) / line.dx);\n let frac = 0;\n\n for (let x = line.startX; x <= line.endX; x++) {\n const wstart = y - Math.trunc(wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n const point = new Point(x, w);\n Draw.drawPixel(\n options.image,\n point,\n options.color,\n (frac >> 8) & 0xff\n );\n point.offset(0, 1);\n Draw.drawPixel(\n options.image,\n point,\n options.color,\n (xor(frac) >> 8) & 0xff\n );\n }\n\n frac += inc;\n if (frac >= 65536) {\n frac -= 65536;\n y++;\n } else if (frac < 0) {\n frac += 65536;\n y--;\n }\n }\n } else {\n let x = line.startX;\n const inc = Math.trunc((line.dx * 65536) / line.dy);\n let frac = 0;\n\n for (let y = line.startY; y <= line.endY; y++) {\n const wstart = x - Math.trunc(wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n const point = new Point(w, y);\n Draw.drawPixel(\n options.image,\n point,\n options.color,\n (frac >> 8) & 0xff\n );\n point.offset(1, 0);\n Draw.drawPixel(\n options.image,\n point,\n options.color,\n (xor(frac) >> 8) & 0xff\n );\n }\n\n frac += inc;\n if (frac >= 65536) {\n frac -= 65536;\n x++;\n } else if (frac < 0) {\n frac += 65536;\n x--;\n }\n }\n }\n\n return options.image;\n }\n\n /**\n * Draw a single pixel into the image, applying alpha and opacity blending.\n */\n public static drawPixel(\n image: MemoryImage,\n pos: Point,\n color: number,\n opacity = 0xff\n ): MemoryImage {\n if (image.boundsSafe(pos.xt, pos.yt)) {\n const index = image.getBufferIndex(pos.xt, pos.yt);\n const dst = image.getPixelByIndex(index);\n image.setPixelByIndex(index, Color.alphaBlendColors(dst, color, opacity));\n }\n return image;\n }\n\n /**\n * Draw a rectangle in the image **dst** with the **color**.\n */\n public static drawRect(\n dst: MemoryImage,\n rect: Rectangle,\n color: number\n ): MemoryImage {\n Draw.drawLine({\n image: dst,\n line: new Line(rect.left, rect.top, rect.right, rect.top),\n color: color,\n });\n Draw.drawLine({\n image: dst,\n line: new Line(rect.right, rect.top, rect.right, rect.bottom),\n color: color,\n });\n Draw.drawLine({\n image: dst,\n line: new Line(rect.right, rect.bottom, rect.left, rect.bottom),\n color: color,\n });\n Draw.drawLine({\n image: dst,\n line: new Line(rect.left, rect.bottom, rect.left, rect.top),\n color: color,\n });\n return dst;\n }\n\n /**\n * Fill the 4-connected shape containing **x**,**y** in the image **src** with the\n * given **color**.\n */\n public static fillFlood(options: FillFloodOptions): MemoryImage {\n const threshold = options.threshold ?? 0;\n const compareAlpha = options.compareAlpha ?? false;\n\n const visited = new Uint8Array(options.src.width * options.src.height);\n\n let srcColor = options.src.getPixel(options.x, options.y);\n if (!compareAlpha) {\n srcColor = Color.setAlpha(srcColor, 0);\n }\n\n let array: FillFloodTestPixel | undefined = undefined;\n if (threshold > 0) {\n const lab = Color.rgbToLab(\n Color.getRed(srcColor),\n Color.getGreen(srcColor),\n Color.getBlue(srcColor)\n );\n if (compareAlpha) {\n lab.push(Color.getAlpha(srcColor));\n }\n array = (y: number, x: number) =>\n visited[y * options.src.width + x] === 0 &&\n Draw.testPixelLabColorDistance(options.src, x, y, lab, threshold);\n } else if (!compareAlpha) {\n array = (y: number, x: number) =>\n visited[y * options.src.width + x] === 0 &&\n Color.setAlpha(options.src.getPixel(x, y), 0) !== srcColor;\n } else {\n array = (y: number, x: number) =>\n visited[y * options.src.width + x] === 0 &&\n options.src.getPixel(x, y) !== srcColor;\n }\n\n const mark = (y: number, x: number) => {\n options.src.setPixel(x, y, options.color);\n visited[y * options.src.width + x] = 1;\n };\n\n Draw.fill4(options.src, options.x, options.y, array, mark, visited);\n return options.src;\n }\n\n /**\n * Create a mask describing the 4-connected shape containing **x**,**y** in the\n * image **src**.\n */\n public static maskFlood(options: MaskFloodOptions): Uint8Array {\n const threshold = options.threshold ?? 0;\n const compareAlpha = options.compareAlpha ?? false;\n const fillValue = options.fillValue ?? 255;\n\n const visited = new Uint8Array(options.src.width * options.src.height);\n\n let srcColor = options.src.getPixel(options.x, options.y);\n if (!compareAlpha) {\n srcColor = Color.setAlpha(srcColor, 0);\n }\n\n const ret = new Uint8Array(options.src.width * options.src.height);\n\n let array: FillFloodTestPixel | undefined = undefined;\n if (threshold > 0) {\n const lab = Color.rgbToLab(\n Color.getRed(srcColor),\n Color.getGreen(srcColor),\n Color.getBlue(srcColor)\n );\n if (compareAlpha) {\n lab.push(Color.getAlpha(srcColor));\n }\n array = (y: number, x: number) =>\n visited[y * options.src.width + x] === 0 &&\n (ret[y * options.src.width + x] !== 0 ||\n Draw.testPixelLabColorDistance(options.src, x, y, lab, threshold));\n } else if (!compareAlpha) {\n array = (y: number, x: number) =>\n visited[y * options.src.width + x] === 0 &&\n (ret[y * options.src.width + x] !== 0 ||\n Color.setAlpha(options.src.getPixel(x, y), 0) !== srcColor);\n } else {\n array = (y: number, x: number) =>\n visited[y * options.src.width + x] === 0 &&\n (ret[y * options.src.width + x] !== 0 ||\n options.src.getPixel(x, y) !== srcColor);\n }\n\n const mark = (y: number, x: number) => {\n ret[y * options.src.width + x] = fillValue;\n visited[y * options.src.width + x] = 1;\n };\n\n Draw.fill4(options.src, options.x, options.y, array, mark, visited);\n return ret;\n }\n\n /**\n * Fill a rectangle in the image **src** with the given **color** with the\n * coordinates defined by **rect**.\n */\n public static fillRect(\n src: MemoryImage,\n rect: Rectangle,\n color: number\n ): MemoryImage {\n const _x0 = MathOperators.clamp(rect.left, 0, src.width - 1);\n const _y0 = MathOperators.clamp(rect.top, 0, src.height - 1);\n const _x1 = MathOperators.clamp(rect.right, 0, src.width - 1);\n const _y1 = MathOperators.clamp(rect.bottom, 0, src.height - 1);\n\n // If no blending is necessary, use a faster fill method.\n if (Color.getAlpha(color) === 255) {\n const w = src.width;\n let start = _y0 * w + _x0;\n let end = start + (_x1 - _x0) + 1;\n for (let sy = _y0; sy <= _y1; ++sy) {\n src.data.fill(color, start, end);\n start += w;\n end += w;\n }\n } else {\n for (let sy = _y0; sy <= _y1; ++sy) {\n let pi = sy * src.width + _x0;\n for (let sx = _x0; sx <= _x1; ++sx, ++pi) {\n src.setPixelByIndex(\n pi,\n Color.alphaBlendColors(src.getPixelByIndex(pi), color)\n );\n }\n }\n }\n\n return src;\n }\n\n /**\n * Set all of the pixels of an **image** to the given **color**.\n */\n public static fill(image: MemoryImage, color: number): MemoryImage {\n return image.fill(color);\n }\n}\n", "/** @format */\n\nimport { MemoryImage } from '../common/memory-image';\n\nexport interface FillFloodOptions {\n src: MemoryImage;\n x: number;\n y: number;\n color: number;\n threshold?: number;\n compareAlpha?: boolean;\n}\n", "/** @format */\n\nimport { MemoryImage } from '../common/memory-image';\n\nexport interface MaskFloodOptions {\n src: MemoryImage;\n x: number;\n y: number;\n threshold?: number;\n compareAlpha?: boolean;\n fillValue?: number;\n}\n", "/** @format */\n\n/**\n * An error thrown when some functionality has not yet been implemented.\n */\nexport class NotImplementedError extends Error {\n toString(): string {\n return this.message.length > 0\n ? `NotImplementedError: ${this.message}`\n : 'NotImplementedError';\n }\n}\n", "/** @format */\n\nimport { MemoryImage } from '../common/memory-image';\n\nexport interface AdjustColorOptions {\n src: MemoryImage;\n blacks?: number;\n whites?: number;\n mids?: number;\n contrast?: number;\n saturation?: number;\n brightness?: number;\n gamma?: number;\n exposure?: number;\n hue?: number;\n amount?: number;\n}\n", "/** @format */\n\nimport { MemoryImage } from '../common/memory-image';\n\nexport interface ColorOffsetOptions {\n src: MemoryImage;\n red?: number;\n green?: number;\n blue?: number;\n alpha?: number;\n}\n", "/** @format */\n\nimport { MemoryImage } from '../common/memory-image';\n\nexport interface ConvolutionOptions {\n src: MemoryImage;\n filter: number[];\n div?: number;\n offset?: number;\n}\n", "/** @format */\n\nexport enum NoiseType {\n gaussian,\n uniform,\n saltPepper,\n poisson,\n rice,\n}\n", "/** @format */\n\nexport enum PixelateMode {\n /**\n * Use the top-left pixel of a block for the block color.\n */\n upperLeft,\n\n /**\n * Use the average of the pixels within a block for the block color.\n */\n average,\n}\n", "/** @format */\n\nexport enum QuantizeMethod {\n neuralNet,\n octree,\n}\n", "/** @format */\n\nimport { Color } from '../common/color';\nimport { MemoryImage } from '../common/memory-image';\n\n/**\n * A kernel object to use with **separableConvolution** filtering.\n */\nexport class SeparableKernel {\n private readonly coefficients: number[];\n private readonly size: number;\n\n /**\n * Get the number of coefficients in the kernel.\n */\n public get length() {\n return this.coefficients.length;\n }\n\n /**\n * Create a separable convolution kernel for the given **radius**.\n */\n constructor(size: number) {\n this.size = size;\n this.coefficients = new Array(2 * size + 1).fill(0);\n }\n\n private reflect(max: number, x: number): number {\n if (x < 0) {\n return -x;\n }\n if (x >= max) {\n return max - (x - max) - 1;\n }\n return x;\n }\n\n private applyCoeffsLine(\n src: MemoryImage,\n dst: MemoryImage,\n y: number,\n width: number,\n horizontal: boolean\n ): void {\n for (let x = 0; x < width; x++) {\n let r = 0;\n let g = 0;\n let b = 0;\n let a = 0;\n\n for (let j = -this.size, j2 = 0; j <= this.size; ++j, ++j2) {\n const coeff = this.coefficients[j2];\n const gr = this.reflect(width, x + j);\n\n const sc = horizontal ? src.getPixel(gr, y) : src.getPixel(y, gr);\n\n r += coeff * Color.getRed(sc);\n g += coeff * Color.getGreen(sc);\n b += coeff * Color.getBlue(sc);\n a += coeff * Color.getAlpha(sc);\n }\n\n const c = Color.getColor(\n r > 255 ? 255 : r,\n g > 255 ? 255 : g,\n b > 255 ? 255 : b,\n a > 255 ? 255 : a\n );\n\n if (horizontal) {\n dst.setPixel(x, y, c);\n } else {\n dst.setPixel(y, x, c);\n }\n }\n }\n\n /**\n * Get a coefficient from the kernel.\n */\n public getCoefficient(index: number) {\n return this.coefficients[index];\n }\n\n /**\n * Set a coefficient in the kernel.\n */\n public setCoefficient(index: number, c: number) {\n this.coefficients[index] = c;\n }\n\n /**\n * Apply the kernel to the **src** image, storing the results in **dst**,\n * for a single dimension. If **horizontal** is true, the filter will be\n * applied to the horizontal axis, otherwise it will be appied to the\n * vertical axis.\n */\n public apply(src: MemoryImage, dst: MemoryImage, horizontal = true): void {\n if (horizontal) {\n for (let y = 0; y < src.height; ++y) {\n this.applyCoeffsLine(src, dst, y, src.width, horizontal);\n }\n } else {\n for (let x = 0; x < src.width; ++x) {\n this.applyCoeffsLine(src, dst, x, src.height, horizontal);\n }\n }\n }\n\n /**\n * Scale all of the coefficients by **s**.\n */\n public scaleCoefficients(s: number): void {\n for (let i = 0; i < this.coefficients.length; ++i) {\n this.coefficients[i] *= s;\n }\n }\n}\n", "/** @format */\n\nimport { Color } from '../common/color';\nimport { ColorChannel } from '../common/color-channel';\nimport { MathOperators } from '../common/math-operators';\nimport { MemoryImage } from '../common/memory-image';\nimport { NeuralQuantizer } from '../common/neural-quantizer';\nimport { OctreeQuantizer } from '../common/octree-quantizer';\nimport { RandomUtils } from '../common/random-utils';\nimport { Rectangle } from '../common/rectangle';\nimport { Draw } from '../draw/draw';\nimport { AdjustColorOptions } from './adjust-color-options';\nimport { ColorOffsetOptions } from './color-offset-options';\nimport { ConvolutionOptions } from './convolution-options';\nimport { NoiseType } from './noise-type';\nimport { PixelateMode } from './pixelate-mode';\nimport { QuantizeMethod } from './quantize-method';\nimport { QuantizeOptions } from './quantize-options';\nimport { RemapColorsOptions } from './remap-colors-options';\nimport { SeparableKernel } from './separable-kernel';\nimport { VignetteOptions } from './vignette-options';\n\nexport abstract class ImageFilter {\n private static readonly gaussianKernelCache: Map =\n new Map();\n\n private static smoothVignetteStep(\n edge0: number,\n edge1: number,\n x: number\n ): number {\n let _x = x;\n _x = (_x - edge0) / (edge1 - edge0);\n if (_x < 0.0) {\n _x = 0.0;\n }\n if (_x > 1.0) {\n _x = 1.0;\n }\n return _x * _x * (3.0 - 2.0 * _x);\n }\n\n /**\n * Adjust the color of the **src** image using various color transformations.\n *\n * **blacks** defines the black level of the image, as a color.\n *\n * **whites** defines the white level of the image, as a color.\n *\n * **mids** defines the mid level of hte image, as a color.\n *\n * **contrast** increases (> 1) / decreases (< 1) the contrast of the image by\n * pushing colors away/toward neutral gray, where at 0 the image is entirely\n * neutral gray (0 contrast), 1, the image is not adjusted and > 1 the\n * image increases contrast.\n *\n * **saturation** increases (> 1) / decreases (< 1) the saturation of the image\n * by pushing colors away/toward their grayscale value, where 0 is grayscale\n * and 1 is the original image, and > 1 the image becomes more saturated.\n *\n * **brightness** is a constant scalar of the image colors. At 0 the image\n * is black, 1 unmodified, and > 1 the image becomes brighter.\n *\n * **gamma** is an exponential scalar of the image colors. At < 1 the image\n * becomes brighter, and > 1 the image becomes darker. A **gamma** of 1/2.2\n * will convert the image colors to linear color space.\n *\n * **exposure** is an exponential scalar of the image as rgb* pow(2, exposure).\n * At 0, the image is unmodified; as the exposure increases, the image\n * brightens.\n *\n * **hue** shifts the hue component of the image colors in degrees. A **hue** of\n * 0 will have no affect, and a **hue** of 45 will shift the hue of all colors\n * by 45 degrees.\n *\n * **amount** controls how much affect this filter has on the **src** image, where\n * 0 has no effect and 1 has full effect.\n */\n public static adjustColor(options: AdjustColorOptions): MemoryImage {\n if (options.amount === 0) {\n return options.src;\n }\n\n const contrast =\n options.contrast !== undefined\n ? MathOperators.clamp(options.contrast, 0, 1)\n : undefined;\n const saturation =\n options.saturation !== undefined\n ? MathOperators.clamp(options.saturation, 0, 1)\n : undefined;\n const brightness =\n options.brightness !== undefined\n ? MathOperators.clamp(options.brightness, 0, 1)\n : undefined;\n const gamma =\n options.gamma !== undefined\n ? MathOperators.clamp(options.gamma, 0, 1000)\n : undefined;\n let exposure =\n options.exposure !== undefined\n ? MathOperators.clamp(options.exposure, 0, 1000)\n : undefined;\n const amount =\n options.amount !== undefined\n ? MathOperators.clamp(options.amount, 0, 1000)\n : undefined;\n\n const DEG_TO_RAD = 0.0174532925;\n const avgLumR = 0.5;\n const avgLumG = 0.5;\n const avgLumB = 0.5;\n const lumCoeffR = 0.2125;\n const lumCoeffG = 0.7154;\n const lumCoeffB = 0.0721;\n\n const useBlacksWhitesMids =\n options.blacks !== undefined ||\n options.whites !== undefined ||\n options.mids !== undefined;\n let br = 0;\n let bg = 0;\n let bb = 0;\n let wr = 0;\n let wg = 0;\n let wb = 0;\n let mr = 0;\n let mg = 0;\n let mb = 0;\n if (useBlacksWhitesMids) {\n br =\n options.blacks !== undefined ? Color.getRed(options.blacks) / 255 : 0;\n bg =\n options.blacks !== undefined ? Color.getGreen(options.blacks) / 255 : 0;\n bb =\n options.blacks !== undefined ? Color.getBlue(options.blacks) / 255 : 0;\n\n wr =\n options.whites !== undefined ? Color.getRed(options.whites) / 255 : 1;\n wg =\n options.whites !== undefined ? Color.getGreen(options.whites) / 255 : 1;\n wb =\n options.whites !== undefined ? Color.getBlue(options.whites) / 255 : 1;\n\n mr = options.mids !== undefined ? Color.getRed(options.mids) / 255 : 0.5;\n mg =\n options.mids !== undefined ? Color.getGreen(options.mids) / 255 : 0.5;\n mb = options.mids !== undefined ? Color.getBlue(options.mids) / 255 : 0.5;\n\n mr = 1 / (1 + 2 * (mr - 0.5));\n mg = 1 / (1 + 2 * (mg - 0.5));\n mb = 1 / (1 + 2 * (mb - 0.5));\n }\n\n const invSaturation =\n saturation !== undefined ? 1 - MathOperators.clamp(saturation, 0, 1) : 0;\n const invContrast =\n contrast !== undefined ? 1 - MathOperators.clamp(contrast, 0, 1) : 0;\n\n if (exposure !== undefined) {\n exposure = Math.pow(2, exposure);\n }\n\n let hueR = 0;\n let hueG = 0;\n let hueB = 0;\n if (options.hue !== undefined) {\n options.hue *= DEG_TO_RAD;\n const s = Math.sin(options.hue);\n const c = Math.cos(options.hue);\n\n hueR = (2 * c) / 3;\n hueG = (-Math.sqrt(3) * s - c) / 3;\n hueB = (Math.sqrt(3) * s - c + 1) / 3;\n }\n\n const invAmount =\n amount !== undefined ? 1 - MathOperators.clamp(amount, 0, 1) : 0;\n\n const pixels = options.src.getBytes();\n for (let i = 0, len = pixels.length; i < len; i += 4) {\n const or = pixels[i] / 255;\n const og = pixels[i + 1] / 255;\n const ob = pixels[i + 2] / 255;\n\n let r = or;\n let g = og;\n let b = ob;\n\n if (useBlacksWhitesMids) {\n r = Math.pow((r + br) * wr, mr);\n g = Math.pow((g + bg) * wg, mg);\n b = Math.pow((b + bb) * wb, mb);\n }\n\n if (brightness !== undefined && brightness !== 1) {\n const br = MathOperators.clamp(brightness, 0, 1000);\n r *= br;\n g *= br;\n b *= br;\n }\n\n if (saturation !== undefined) {\n const lum = r * lumCoeffR + g * lumCoeffG + b * lumCoeffB;\n r = lum * invSaturation + r * saturation;\n g = lum * invSaturation + g * saturation;\n b = lum * invSaturation + b * saturation;\n }\n\n if (contrast !== undefined) {\n r = avgLumR * invContrast + r * contrast;\n g = avgLumG * invContrast + g * contrast;\n b = avgLumB * invContrast + b * contrast;\n }\n\n if (gamma !== undefined) {\n r = Math.pow(r, gamma);\n g = Math.pow(g, gamma);\n b = Math.pow(b, gamma);\n }\n\n if (exposure !== undefined) {\n r *= exposure;\n g *= exposure;\n b *= exposure;\n }\n\n if (options.hue !== undefined && options.hue !== 0) {\n const hr = r * hueR + g * hueG + b * hueB;\n const hg = r * hueB + g * hueR + b * hueG;\n const hb = r * hueG + g * hueB + b * hueR;\n r = hr;\n g = hg;\n b = hb;\n }\n\n if (amount !== undefined) {\n r = r * amount + or * invAmount;\n g = g * amount + og * invAmount;\n b = b * amount + ob * invAmount;\n }\n\n pixels[i] = MathOperators.clampInt255(r * 255);\n pixels[i + 1] = MathOperators.clampInt255(g * 255);\n pixels[i + 2] = MathOperators.clampInt255(b * 255);\n }\n\n return options.src;\n }\n\n /**\n * Set the **brightness** level for the image **src**.\n * **brightness** is an offset that is added to the red, green, and blue channels\n * of every pixel.\n */\n public static brightness(src: MemoryImage, brightness: number): MemoryImage {\n if (brightness === 0) {\n return src;\n }\n\n const pixels = src.getBytes();\n for (let i = 0, len = pixels.length; i < len; i += 4) {\n pixels[i] = MathOperators.clampInt255(pixels[i] + brightness);\n pixels[i + 1] = MathOperators.clampInt255(pixels[i + 1] + brightness);\n pixels[i + 2] = MathOperators.clampInt255(pixels[i + 2] + brightness);\n }\n\n return src;\n }\n\n /**\n * Generate a normal map from a height-field bump image.\n *\n * The red channel of the **src** image is used as an input, 0 represents a low\n * height and 1 a high value. The optional **strength** parameter allows to set\n * the strength of the normal image.\n */\n public static bumpToNormal(src: MemoryImage, strength = 2): MemoryImage {\n const dest = MemoryImage.from(src);\n\n for (let y = 0; y < src.height; ++y) {\n for (let x = 0; x < src.width; ++x) {\n const height = Color.getRed(src.getPixel(x, y)) / 255;\n let du =\n (height -\n Color.getRed(src.getPixel(x < src.width - 1 ? x + 1 : x, y)) /\n 255) *\n strength;\n let dv =\n (height -\n Color.getRed(src.getPixel(x, y < src.height - 1 ? y + 1 : y)) /\n 255) *\n strength;\n const z = Math.abs(du) + Math.abs(dv);\n\n if (z > 1) {\n du /= z;\n dv /= z;\n }\n\n const dw = Math.sqrt(1 - du * du - dv * dv);\n const nX = du * 0.5 + 0.5;\n const nY = dv * 0.5 + 0.5;\n const nZ = dw;\n\n dest.setPixelRgba(\n x,\n y,\n Math.floor(255 * nX),\n Math.floor(255 * nY),\n Math.floor(255 * nZ)\n );\n }\n }\n\n return dest;\n }\n\n /**\n * Add the **red**, **green**, **blue** and **alpha** values to the **src** image\n * colors, a per-channel brightness.\n */\n public static colorOffset(options: ColorOffsetOptions): MemoryImage {\n const pixels = options.src.getBytes();\n for (let i = 0, len = pixels.length; i < len; i += 4) {\n pixels[i] = MathOperators.clampInt255(pixels[i] + (options.red ?? 0));\n pixels[i + 1] = MathOperators.clampInt255(\n pixels[i + 1] + (options.green ?? 0)\n );\n pixels[i + 2] = MathOperators.clampInt255(\n pixels[i + 2] + (options.blue ?? 0)\n );\n pixels[i + 3] = MathOperators.clampInt255(\n pixels[i + 3] + (options.alpha ?? 0)\n );\n }\n\n return options.src;\n }\n\n /**\n * Set the **contrast** level for the image **src**.\n *\n * **contrast** values below 100 will decrees the contrast of the image,\n * and values above 100 will increase the contrast. A contrast of 100\n * will have no affect.\n */\n public static contrast(src: MemoryImage, contrast: number): MemoryImage {\n if (contrast === 100) {\n return src;\n }\n\n let c = contrast / 100;\n c *= c;\n const clevels = new Uint8Array(256);\n for (let i = 0; i < 256; ++i) {\n clevels[i] = MathOperators.clampInt255(\n ((i / 255.0 - 0.5) * c + 0.5) * 255.0\n );\n }\n\n const p = src.getBytes();\n for (let i = 0, len = p.length; i < len; i += 4) {\n p[i] = clevels[p[i]];\n p[i + 1] = clevels[p[i + 1]];\n p[i + 2] = clevels[p[i + 2]];\n }\n\n return src;\n }\n\n /**\n * Apply a 3x3 convolution filter to the **src** image. **filter** should be a\n * list of 9 numbers.\n *\n * The rgb channels will divided by **div** and add **offset**, allowing\n * filters to normalize and offset the filtered pixel value.\n */\n public static convolution(options: ConvolutionOptions): MemoryImage {\n const tmp = MemoryImage.from(options.src);\n\n for (let y = 0; y < options.src.height; ++y) {\n for (let x = 0; x < options.src.width; ++x) {\n const c = tmp.getPixel(x, y);\n let r = 0;\n let g = 0;\n let b = 0;\n const a = Color.getAlpha(c);\n for (let j = 0, fi = 0; j < 3; ++j) {\n const yv = Math.min(Math.max(y - 1 + j, 0), options.src.height - 1);\n for (let i = 0; i < 3; ++i, ++fi) {\n const xv = Math.min(Math.max(x - 1 + i, 0), options.src.width - 1);\n const c2 = tmp.getPixel(xv, yv);\n r += Color.getRed(c2) * options.filter[fi];\n g += Color.getGreen(c2) * options.filter[fi];\n b += Color.getBlue(c2) * options.filter[fi];\n }\n }\n\n const div = options.div ?? 1;\n const offset = options.offset ?? 0;\n\n r = r / div + offset;\n g = g / div + offset;\n b = b / div + offset;\n\n r = r > 255 ? 255 : r < 0 ? 0 : r;\n g = g > 255 ? 255 : g < 0 ? 0 : g;\n b = b > 255 ? 255 : b < 0 ? 0 : b;\n\n options.src.setPixel(x, y, Color.getColor(r, g, b, a));\n }\n }\n\n return options.src;\n }\n\n /**\n * Apply an emboss convolution filter.\n */\n public static emboss(src: MemoryImage): MemoryImage {\n const filter = [1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.5];\n\n return ImageFilter.convolution({\n src: src,\n filter: filter,\n div: 1,\n offset: 127,\n });\n }\n\n /**\n * Apply gaussian blur to the **src** image. **radius** determines how many pixels\n * away from the current pixel should contribute to the blur, where 0 is no\n * blur and the larger the radius, the stronger the blur.\n */\n public static gaussianBlur(src: MemoryImage, radius: number): MemoryImage {\n if (radius <= 0) {\n return src;\n }\n\n let kernel: SeparableKernel | undefined = undefined;\n\n if (ImageFilter.gaussianKernelCache.has(radius)) {\n kernel = ImageFilter.gaussianKernelCache.get(radius)!;\n } else {\n // Compute coefficients\n const sigma = (radius * 2) / 3;\n const s = 2 * sigma * sigma;\n\n kernel = new SeparableKernel(radius);\n\n let sum = 0;\n for (let x = -radius; x <= radius; ++x) {\n const c = Math.exp(-(x * x) / s);\n sum += c;\n kernel.setCoefficient(x + radius, c);\n }\n // Normalize the coefficients\n kernel.scaleCoefficients(1 / sum);\n\n // Cache the kernel for this radius so we don't have to recompute it\n // next time.\n ImageFilter.gaussianKernelCache.set(radius, kernel);\n }\n\n return ImageFilter.separableConvolution(src, kernel);\n }\n\n /**\n * Convert the image to grayscale.\n */\n public static grayscale(src: MemoryImage): MemoryImage {\n const p = src.getBytes();\n for (let i = 0, len = p.length; i < len; i += 4) {\n const l = Color.getLuminanceRgb(p[i], p[i + 1], p[i + 2]);\n p[i] = l;\n p[i + 1] = l;\n p[i + 2] = l;\n }\n return src;\n }\n\n /**\n * Invert the colors of the **src** image.\n */\n public static invert(src: MemoryImage): MemoryImage {\n const p = src.getBytes();\n for (let i = 0, len = p.length; i < len; i += 4) {\n p[i] = 255 - p[i];\n p[i + 1] = 255 - p[i + 1];\n p[i + 2] = 255 - p[i + 2];\n }\n return src;\n }\n\n /**\n * Add random noise to pixel values. **sigma** determines how strong the effect\n * should be. **type** should be one of the following: **NoiseType.gaussian**,\n * **NoiseType.uniform**, **NoiseType.saltPepper**, **NoiseType.poisson**,\n * or **NoiseType.rice**.\n */\n public static noise(\n image: MemoryImage,\n sigma: number,\n type: NoiseType = NoiseType.gaussian\n ): MemoryImage {\n let nsigma = sigma;\n let min = 0;\n let max = 0;\n\n if (nsigma === 0 && type !== NoiseType.poisson) {\n return image;\n }\n\n if (nsigma < 0 || type === NoiseType.saltPepper) {\n const extremes = image.getColorExtremes();\n min = extremes.min;\n max = extremes.max;\n }\n\n if (nsigma < 0) {\n nsigma = (-nsigma * (max - min)) / 100.0;\n }\n\n const len = image.length;\n switch (type) {\n case NoiseType.gaussian:\n for (let i = 0; i < len; ++i) {\n const c = image.getPixelByIndex(i);\n const r = Math.trunc(Color.getRed(c) + nsigma * RandomUtils.grand());\n const g = Math.trunc(\n Color.getGreen(c) + nsigma * RandomUtils.grand()\n );\n const b = Math.trunc(Color.getBlue(c) + nsigma * RandomUtils.grand());\n const a = Color.getAlpha(c);\n image.setPixelByIndex(i, Color.getColor(r, g, b, a));\n }\n break;\n case NoiseType.uniform:\n for (let i = 0; i < len; ++i) {\n const c = image.getPixelByIndex(i);\n const r = Math.trunc(Color.getRed(c) + nsigma * RandomUtils.crand());\n const g = Math.trunc(\n Color.getGreen(c) + nsigma * RandomUtils.crand()\n );\n const b = Math.trunc(Color.getBlue(c) + nsigma * RandomUtils.crand());\n const a = Color.getAlpha(c);\n image.setPixelByIndex(i, Color.getColor(r, g, b, a));\n }\n break;\n case NoiseType.saltPepper:\n if (nsigma < 0) {\n nsigma = -nsigma;\n }\n if (max === min) {\n min = 0;\n max = 255;\n }\n for (let i = 0; i < len; ++i) {\n const c = image.getPixelByIndex(i);\n if (Math.random() * 100 < nsigma) {\n const r = Math.random() < 0.5 ? max : min;\n const g = Math.random() < 0.5 ? max : min;\n const b = Math.random() < 0.5 ? max : min;\n const a = Color.getAlpha(c);\n image.setPixelByIndex(i, Color.getColor(r, g, b, a));\n }\n }\n break;\n case NoiseType.poisson:\n for (let i = 0; i < len; ++i) {\n const c = image.getPixelByIndex(i);\n const r = RandomUtils.prand(Color.getRed(c));\n const g = RandomUtils.prand(Color.getGreen(c));\n const b = RandomUtils.prand(Color.getBlue(c));\n const a = Color.getAlpha(c);\n image.setPixelByIndex(i, Color.getColor(r, g, b, a));\n }\n break;\n case NoiseType.rice: {\n const sqrt2 = Math.sqrt(2);\n for (let i = 0; i < len; ++i) {\n const c = image.getPixelByIndex(i);\n\n let val0 = Color.getRed(c) / sqrt2;\n let re = val0 + nsigma * RandomUtils.grand();\n let im = val0 + nsigma * RandomUtils.grand();\n let val = Math.sqrt(re * re + im * im);\n const r = Math.trunc(val);\n\n val0 = Color.getGreen(c) / sqrt2;\n re = val0 + nsigma * RandomUtils.grand();\n im = val0 + nsigma * RandomUtils.grand();\n val = Math.sqrt(re * re + im * im);\n const g = Math.trunc(val);\n\n val0 = Color.getBlue(c) / sqrt2;\n re = val0 + nsigma * RandomUtils.grand();\n im = val0 + nsigma * RandomUtils.grand();\n val = Math.sqrt(re * re + im * im);\n const b = Math.trunc(val);\n\n const a = Color.getAlpha(c);\n image.setPixelByIndex(i, Color.getColor(r, g, b, a));\n }\n break;\n }\n }\n\n return image;\n }\n\n /**\n * Linearly normalize the colors of the image. All color values will be mapped\n * to the range **minValue**, **maxValue** inclusive.\n */\n public static normalize(\n src: MemoryImage,\n minValue: number,\n maxValue: number\n ): MemoryImage {\n const A = minValue < maxValue ? minValue : maxValue;\n const B = minValue < maxValue ? maxValue : minValue;\n\n const extremes = src.getColorExtremes();\n const min = extremes.min;\n const max = extremes.max;\n\n if (min === max) {\n return src.fill(minValue);\n }\n\n if (min !== A || max !== B) {\n const p = src.getBytes();\n for (let i = 0, len = p.length; i < len; i += 4) {\n p[i] = Math.trunc(((p[i] - min) / (max - min)) * (B - A) + A);\n p[i + 1] = Math.trunc(((p[i + 1] - min) / (max - min)) * (B - A) + A);\n p[i + 2] = Math.trunc(((p[i + 2] - min) / (max - min)) * (B - A) + A);\n p[i + 3] = Math.trunc(((p[i + 3] - min) / (max - min)) * (B - A) + A);\n }\n }\n\n return src;\n }\n\n /**\n * Pixelate the **src** image.\n *\n * **blockSize** determines the size of the pixelated blocks.\n * If **mode** is **PixelateMode.upperLeft** then the upper-left corner of the block\n * will be used for the block color. Otherwise if **mode** is **PixelateMode.average**,\n * the average of all the pixels in the block will be used for the block color.\n */\n public static pixelate(\n src: MemoryImage,\n blockSize: number,\n mode: PixelateMode = PixelateMode.upperLeft\n ): MemoryImage {\n if (blockSize <= 1) {\n return src;\n }\n\n const bs = blockSize - 1;\n\n switch (mode) {\n case PixelateMode.upperLeft:\n for (let y = 0; y < src.height; y += blockSize) {\n for (let x = 0; x < src.width; x += blockSize) {\n if (src.boundsSafe(x, y)) {\n const c = src.getPixel(x, y);\n const rect = new Rectangle(x, y, x + bs, y + bs);\n Draw.fillRect(src, rect, c);\n }\n }\n }\n break;\n case PixelateMode.average:\n for (let y = 0; y < src.height; y += blockSize) {\n for (let x = 0; x < src.width; x += blockSize) {\n let a = 0;\n let r = 0;\n let g = 0;\n let b = 0;\n let total = 0;\n\n for (let cy = 0; cy < blockSize; ++cy) {\n for (let cx = 0; cx < blockSize; ++cx) {\n if (!src.boundsSafe(x + cx, y + cy)) {\n continue;\n }\n const c = src.getPixel(x + cx, y + cy);\n a += Color.getAlpha(c);\n r += Color.getRed(c);\n g += Color.getGreen(c);\n b += Color.getBlue(c);\n total++;\n }\n }\n\n if (total > 0) {\n const c = Color.getColor(\n Math.trunc(r / total),\n Math.trunc(g / total),\n Math.trunc(b / total),\n Math.trunc(a / total)\n );\n const rect = new Rectangle(x, y, x + bs, y + bs);\n Draw.fillRect(src, rect, c);\n }\n }\n }\n break;\n }\n\n return src;\n }\n\n /**\n * Quantize the number of colors in image to 256.\n */\n public static quantize(options: QuantizeOptions): MemoryImage {\n const numberOfColors = options.numberOfColors ?? 256;\n const method = options.method ?? QuantizeMethod.neuralNet;\n\n if (method === QuantizeMethod.octree || numberOfColors < 4) {\n const oct = new OctreeQuantizer(options.src, numberOfColors);\n for (let i = 0, len = options.src.length; i < len; ++i) {\n options.src.setPixelByIndex(\n i,\n oct.getQuantizedColor(options.src.getPixelByIndex(i))\n );\n }\n return options.src;\n }\n\n const quant = new NeuralQuantizer(options.src, numberOfColors);\n for (let i = 0, len = options.src.length; i < len; ++i) {\n options.src.setPixelByIndex(\n i,\n quant.getQuantizedColor(options.src.getPixelByIndex(i))\n );\n }\n return options.src;\n }\n\n /**\n * Remap the color channels of the image.\n * **red**, **green**, **blue** and **alpha** should be set to one of the following:\n * **ColorChannel.red**, **ColorChannel.green**, **ColorChannel.blue**, **ColorChannel.alpha**, or\n * **ColorChannel.luminance**. For example,\n * **_remapColors({ src: src, red: ColorChannel.green, green: ColorChannel.red })_**\n * will swap the red and green channels of the image.\n * **_remapColors({ src: src, alpha: ColorChannel.luminance })_**\n * will set the alpha channel to the luminance (grayscale) of the image.\n */\n public static remapColors(options: RemapColorsOptions): MemoryImage {\n const red = options.red ?? ColorChannel.red;\n const green = options.red ?? ColorChannel.red;\n const blue = options.red ?? ColorChannel.red;\n const alpha = options.red ?? ColorChannel.red;\n\n const l = [0, 0, 0, 0, 0];\n const p = options.src.getBytes();\n for (let i = 0, len = p.length; i < len; i += 4) {\n l[0] = p[i];\n l[1] = p[i + 1];\n l[2] = p[i + 2];\n l[3] = p[i + 3];\n if (\n red === ColorChannel.luminance ||\n green === ColorChannel.luminance ||\n blue === ColorChannel.luminance ||\n alpha === ColorChannel.luminance\n ) {\n l[4] = Color.getLuminanceRgb(l[0], l[1], l[2]);\n }\n p[i] = l[red];\n p[i + 1] = l[green];\n p[i + 2] = l[blue];\n p[i + 3] = l[alpha];\n }\n\n return options.src;\n }\n\n public static scaleRgba(\n src: MemoryImage,\n r: number,\n g: number,\n b: number,\n a: number\n ): MemoryImage {\n const dr = r / 255;\n const dg = g / 255;\n const db = b / 255;\n const da = a / 255;\n const bytes = src.getBytes();\n for (let i = 0, len = bytes.length; i < len; i += 4) {\n bytes[i] = Math.floor(bytes[i] * dr);\n bytes[i + 1] = Math.floor(bytes[i + 1] * dg);\n bytes[i + 2] = Math.floor(bytes[i + 2] * db);\n bytes[i + 3] = Math.floor(bytes[i + 3] * da);\n }\n return src;\n }\n\n /**\n * Apply a generic separable convolution filter the **src** image, using the\n * given **kernel**.\n *\n * **gaussianBlur** is an example of such a filter.\n */\n public static separableConvolution(\n src: MemoryImage,\n kernel: SeparableKernel\n ): MemoryImage {\n // Apply the filter horizontally\n const tmp = MemoryImage.from(src);\n kernel.apply(src, tmp);\n // Apply the filter vertically, applying back to the original image.\n kernel.apply(tmp, src, false);\n return src;\n }\n\n /**\n * Apply sepia tone to the image.\n *\n * **amount** controls the strength of the effect, in the range **0**-**1**.\n */\n public static sepia(src: MemoryImage, amount = 1): MemoryImage {\n if (amount === 0) {\n return src;\n }\n\n const p = src.getBytes();\n for (let i = 0, len = p.length; i < len; i += 4) {\n const r = p[i];\n const g = p[i + 1];\n const b = p[i + 2];\n const y = Color.getLuminanceRgb(r, g, b);\n p[i] = MathOperators.clampInt255(amount * (y + 38) + (1.0 - amount) * r);\n p[i + 1] = MathOperators.clampInt255(\n amount * (y + 18) + (1.0 - amount) * g\n );\n p[i + 2] = MathOperators.clampInt255(\n amount * (y - 31) + (1.0 - amount) * b\n );\n }\n\n return src;\n }\n\n /**\n * Apply a smoothing convolution filter to the **src** image.\n *\n * **w** is the weight of the current pixel being filtered. If it's greater than\n * 1, it will make the image sharper.\n */\n public static smooth(src: MemoryImage, w: number): MemoryImage {\n const filter = [1, 1, 1, 1, w, 1, 1, 1, 1];\n return ImageFilter.convolution({\n src: src,\n filter: filter,\n div: w + 8,\n offset: 0,\n });\n }\n\n /**\n * Apply Sobel edge detection filtering to the **src** Image.\n */\n public static sobel(src: MemoryImage, amount = 1): MemoryImage {\n const invAmount = 1 - amount;\n const orig = ImageFilter.grayscale(MemoryImage.from(src));\n const origRGBA = orig.getBytes();\n const rowSize = src.width * 4;\n const rgba = src.getBytes();\n const rgbaLen = rgba.length;\n for (let y = 0, pi = 0; y < src.height; ++y) {\n for (let x = 0; x < src.width; ++x, pi += 4) {\n const bl = pi + rowSize - 4;\n const b = pi + rowSize;\n const br = pi + rowSize + 4;\n const l = pi - 4;\n const r = pi + 4;\n const tl = pi - rowSize - 4;\n const t = pi - rowSize;\n const tr = pi - rowSize + 4;\n\n const tlInt = tl < 0 ? 0 : origRGBA[tl] / 255;\n const tInt = t < 0 ? 0 : origRGBA[t] / 255;\n const trInt = tr < 0 ? 0 : origRGBA[tr] / 255;\n const lInt = l < 0 ? 0 : origRGBA[l] / 255;\n const rInt = r < rgbaLen ? origRGBA[r] / 255 : 0;\n const blInt = bl < rgbaLen ? origRGBA[bl] / 255 : 0;\n const bInt = b < rgbaLen ? origRGBA[b] / 255 : 0;\n const brInt = br < rgbaLen ? origRGBA[br] / 255 : 0;\n\n const h = -tlInt - 2 * tInt - trInt + blInt + 2 * bInt + brInt;\n const v = -blInt - 2 * lInt - tlInt + brInt + 2 * rInt + trInt;\n\n const mag = MathOperators.clampInt255(Math.sqrt(h * h + v * v) * 255);\n\n rgba[pi] = MathOperators.clampInt255(\n mag * amount + rgba[pi] * invAmount\n );\n rgba[pi + 1] = MathOperators.clampInt255(\n mag * amount + rgba[pi + 1] * invAmount\n );\n rgba[pi + 2] = MathOperators.clampInt255(\n mag * amount + rgba[pi + 2] * invAmount\n );\n }\n }\n\n return src;\n }\n\n public static vignette(options: VignetteOptions): MemoryImage {\n const start = options.start ?? 0.3;\n const end = options.end ?? 0.75;\n const amount = options.amount ?? 0.8;\n\n const h = options.src.height - 1;\n const w = options.src.width - 1;\n const invAmt = 1 - amount;\n const p = options.src.getBytes();\n for (let y = 0, i = 0; y <= h; ++y) {\n const dy = 0.5 - y / h;\n for (let x = 0; x <= w; ++x, i += 4) {\n const dx = 0.5 - x / w;\n\n let d = Math.sqrt(dx * dx + dy * dy);\n d = ImageFilter.smoothVignetteStep(end, start, d);\n\n p[i] = MathOperators.clampInt255(amount * p[i] * d + invAmt * p[i]);\n p[i + 1] = MathOperators.clampInt255(\n amount * p[i + 1] * d + invAmt * p[i + 1]\n );\n p[i + 2] = MathOperators.clampInt255(\n amount * p[i + 2] * d + invAmt * p[i + 2]\n );\n }\n }\n\n return options.src;\n }\n}\n", "/** @format */\n\nimport { MemoryImage } from '../common/memory-image';\nimport { QuantizeMethod } from './quantize-method';\n\nexport interface QuantizeOptions {\n src: MemoryImage;\n numberOfColors?: number;\n method?: QuantizeMethod;\n}\n", "/** @format */\n\nimport { ColorChannel } from '../common/color-channel';\nimport { MemoryImage } from '../common/memory-image';\n\nexport interface RemapColorsOptions {\n src: MemoryImage;\n red?: ColorChannel;\n green?: ColorChannel;\n blue?: ColorChannel;\n alpha?: ColorChannel;\n}\n", "/** @format */\n\nimport { MemoryImage } from '../common/memory-image';\n\nexport interface VignetteOptions {\n src: MemoryImage;\n start?: number;\n end?: number;\n amount?: number;\n}\n", "/** @format */\n\nimport { BitOperators } from '../common/bit-operators';\n\n/**\n * A 16-bit floating-point number, used by high-dynamic-range image formats\n * as a more efficient storage for floating-point values that don't require\n * full 32-bit precision. A list of Half floats can be stored in a **Uint16Array**,\n * and converted to a double using the **halfToDouble()** static method.\n *\n * This class is derived from the OpenEXR library.\n */\nexport class Half {\n private static toFloatUint32: Uint32Array;\n private static toFloatFloat32: Float32Array;\n private static eLut: Uint16Array;\n\n static {\n Half.toFloatUint32 = new Uint32Array(1 << 16);\n Half.toFloatFloat32 = new Float32Array(Half.toFloatUint32.buffer);\n Half.eLut = new Uint16Array(1 << 9);\n\n // Init eLut\n for (let i = 0; i < 0x100; i++) {\n const e = (i & 0x0ff) - (127 - 15);\n if (e <= 0 || e >= 30) {\n // Special case\n Half.eLut[i] = 0;\n Half.eLut[i | 0x100] = 0;\n } else {\n // Common case - normalized half, no exponent overflow possible\n Half.eLut[i] = e << 10;\n Half.eLut[i | 0x100] = (e << 10) | 0x8000;\n }\n }\n\n // Init toFloat\n const iMax = 1 << 16;\n for (let i = 0; i < iMax; i++) {\n Half.toFloatUint32[i] = Half.halfToFloat(i);\n }\n }\n\n private bits: number;\n\n constructor(bits: number) {\n this.bits = bits;\n }\n\n private static convert(i: number): number {\n // Our floating point number, f, is represented by the bit\n // pattern in integer i. Disassemble that bit pattern into\n // the sign, s, the exponent, e, and the significand, m.\n // Shift s into the position where it will go in in the\n // resulting half number.\n // Adjust e, accounting for the different exponent bias\n // of float and half (127 versus 15).\n const s = (i >> 16) & 0x00008000;\n let e = ((i >> 23) & 0x000000ff) - (127 - 15);\n let m = i & 0x007fffff;\n\n // Now reassemble s, e and m into a half:\n if (e <= 0) {\n if (e < -10) {\n // E is less than -10. The absolute value of f is\n // less than HALF_MIN (f may be a small normalized\n // float, a denormalized float or a zero).\n //\n // We convert f to a half zero with the same sign as f.\n return s;\n }\n\n // E is between -10 and 0. F is a normalized float\n // whose magnitude is less than HALF_NRM_MIN.\n //\n // We convert f to a denormalized half.\n\n // Add an explicit leading 1 to the significand.\n\n m |= 0x00800000;\n\n // Round to m to the nearest (10+e)-bit value (with e between\n // -10 and 0); in case of a tie, round to the nearest even value.\n //\n // Rounding may cause the significand to overflow and make\n // our number normalized. Because of the way a half's bits\n // are laid out, we don't have to treat this case separately;\n // the code below will handle it correctly.\n\n const t = 14 - e;\n const a = (1 << (t - 1)) - 1;\n const b = (m >> t) & 1;\n\n m = (m + a + b) >> t;\n\n // Assemble the half from s, e (zero) and m.\n return s | m;\n } else if (e === 0xff - (127 - 15)) {\n if (m === 0) {\n // F is an infinity; convert f to a half\n // infinity with the same sign as f.\n return s | 0x7c00;\n } else {\n // F is a NAN; we produce a half NAN that preserves\n // the sign bit and the 10 leftmost bits of the\n // significand of f, with one exception: If the 10\n // leftmost bits are all zero, the NAN would turn\n // into an infinity, so we have to set at least one\n // bit in the significand.\n\n m >>= 13;\n return s | 0x7c00 | m | (m === 0 ? 1 : 0);\n }\n } else {\n // E is greater than zero. F is a normalized float.\n // We try to convert f to a normalized half.\n\n // Round to m to the nearest 10-bit value. In case of\n // a tie, round to the nearest even value.\n m = m + 0x00000fff + ((m >> 13) & 1);\n\n if ((m & 0x00800000) !== 0) {\n // Overflow in significand,\n m = 0;\n // Adjust exponent\n e += 1;\n }\n\n // Handle exponent overflow\n\n if (e > 30) {\n // If this returns, the half becomes an\n // infinity with the same sign as f.\n return s | 0x7c00;\n }\n\n // Assemble the half from s, e and m.\n return s | (e << 10) | (m >> 13);\n }\n }\n\n private static halfToFloat(y: number): number {\n const s = (y >> 15) & 0x00000001;\n let e = (y >> 10) & 0x0000001f;\n let m = y & 0x000003ff;\n\n if (e === 0) {\n if (m === 0) {\n // Plus or minus zero\n return s << 31;\n } else {\n // Denormalized number -- re-normalize it\n while ((m & 0x00000400) === 0) {\n m <<= 1;\n e -= 1;\n }\n\n e += 1;\n m &= ~0x00000400;\n }\n } else if (e === 31) {\n if (m === 0) {\n // Positive or negative infinity\n return (s << 31) | 0x7f800000;\n } else {\n // Nan -- preserve sign and significand bits\n return (s << 31) | 0x7f800000 | (m << 13);\n }\n }\n\n // Normalized number\n e += 127 - 15;\n m <<= 13;\n\n // Assemble s, e and m.\n return (s << 31) | (e << 23) | m;\n }\n\n private static fromBits(bits: number) {\n return new Half(bits);\n }\n\n public static halfToDouble(bits: number): number {\n return this.toFloatFloat32[bits];\n }\n\n public static doubleToHalf(n: number): number {\n const f = n;\n const xi = BitOperators.toUint32(f);\n if (f === 0.0) {\n // Common special case - zero.\n // Preserve the zero's sign bit.\n return xi >> 16;\n }\n\n // We extract the combined sign and exponent, e, from our\n // floating-point number, f. Then we convert e to the sign\n // and exponent of the half number via a table lookup.\n //\n // For the most common case, where a normalized half is produced,\n // the table lookup returns a non-zero value; in this case, all\n // we have to do is round f's significand to 10 bits and combine\n // the result with e.\n //\n // For all other cases (overflow, zeroes, denormalized numbers\n // resulting from underflow, infinities and NANs), the table\n // lookup returns zero, and we call a longer, non-inline function\n // to do the float-to-half conversion.\n let e = (xi >> 23) & 0x000001ff;\n\n e = this.eLut[e];\n\n if (e !== 0) {\n // Simple case - round the significand, m, to 10\n // bits and combine it with the sign and exponent.\n const m = xi & 0x007fffff;\n return e + ((m + 0x00000fff + ((m >> 13) & 1)) >> 13);\n }\n\n // Difficult case - call a function.\n return this.convert(xi);\n }\n\n /**\n * Returns +infinity.\n */\n public static positiveInfinity(): Half {\n return Half.fromBits(0x7c00);\n }\n\n /**\n * Returns -infinity.\n */\n public static negativeInfinity(): Half {\n return Half.fromBits(0xfc00);\n }\n\n /**\n * Returns a NAN with the bit pattern 0111111111111111.\n */\n public static qNan(): Half {\n return Half.fromBits(0x7fff);\n }\n\n /**\n * Returns a NAN with the bit pattern 0111110111111111.\n */\n public static sNan(): Half {\n return Half.fromBits(0x7dff);\n }\n\n public toDouble(): number {\n return Half.toFloatFloat32[this.bits];\n }\n\n /**\n * Unary minus\n */\n public unaryMinus(): Half {\n return Half.fromBits(this.bits ^ 0x8000);\n }\n\n /**\n * Addition operator for Half or num left operands.\n */\n public add(other: Half | number): Half {\n let d = 0;\n if (other instanceof Half) {\n d = other.toDouble();\n } else if (typeof other === 'number') {\n d = other;\n }\n const bits = Half.doubleToHalf(this.toDouble() + d);\n return new Half(bits);\n }\n\n /**\n * Subtraction operator for Half or num left operands.\n */\n public subtract(other: Half | number): Half {\n let d = 0;\n if (other instanceof Half) {\n d = other.toDouble();\n } else if (typeof other === 'number') {\n d = other;\n }\n const bits = Half.doubleToHalf(this.toDouble() - d);\n return new Half(bits);\n }\n\n /**\n * Multiplication operator for Half or num left operands.\n */\n public multiply(other: Half | number): Half {\n let d = 0;\n if (other instanceof Half) {\n d = other.toDouble();\n } else if (typeof other === 'number') {\n d = other;\n }\n const bits = Half.doubleToHalf(this.toDouble() * d);\n return new Half(bits);\n }\n\n /**\n * Division operator for Half or num left operands.\n */\n public divide(other: Half | number): Half {\n let d = 0;\n if (other instanceof Half) {\n d = other.toDouble();\n } else if (typeof other === 'number') {\n d = other;\n }\n const bits = Half.doubleToHalf(this.toDouble() / d);\n return new Half(bits);\n }\n\n /**\n * Round to n-bit precision (n should be between 0 and 10).\n * After rounding, the significand's 10-n least significant\n * bits will be zero.\n */\n public round(n: number): Half {\n if (n >= 10) {\n return this;\n }\n\n // Disassemble h into the sign, s,\n // and the combined exponent and significand, e.\n const s = this.bits & 0x8000;\n let e = this.bits & 0x7fff;\n\n // Round the exponent and significand to the nearest value\n // where ones occur only in the (10-n) most significant bits.\n // Note that the exponent adjusts automatically if rounding\n // up causes the significand to overflow.\n\n e >>= 9 - n;\n e += e & 1;\n e <<= 9 - n;\n\n // Check for exponent overflow.\n if (e >= 0x7c00) {\n // Overflow occurred -- truncate instead of rounding.\n e = this.bits;\n e >>= 10 - n;\n e <<= 10 - n;\n }\n\n // Put the original sign bit back.\n\n return Half.fromBits(s | e);\n }\n\n /**\n * Returns true if h is a normalized number, a denormalized number or zero.\n */\n public isFinite(): boolean {\n const e = (this.bits >> 10) & 0x001f;\n return e < 31;\n }\n\n /**\n * Returns true if h is a normalized number.\n */\n public isNormalized(): boolean {\n const e = (this.bits >> 10) & 0x001f;\n return e > 0 && e < 31;\n }\n\n /**\n * Returns true if h is a denormalized number.\n */\n public isDenormalized(): boolean {\n const e = (this.bits >> 10) & 0x001f;\n const m = this.bits & 0x3ff;\n return e === 0 && m !== 0;\n }\n\n /**\n * Returns true if h is zero.\n */\n public isZero(): boolean {\n return (this.bits & 0x7fff) === 0;\n }\n\n /**\n * Returns true if h is a NAN.\n */\n public isNan(): boolean {\n const e = (this.bits >> 10) & 0x001f;\n const m = this.bits & 0x3ff;\n return e === 31 && m !== 0;\n }\n\n /**\n * Returns true if h is a positive or a negative infinity.\n */\n public isInfinity(): boolean {\n const e = (this.bits >> 10) & 0x001f;\n const m = this.bits & 0x3ff;\n return e === 31 && m === 0;\n }\n\n /**\n * Returns true if the sign bit of h is set (negative).\n */\n public isNegative(): boolean {\n return (this.bits & 0x8000) !== 0;\n }\n\n public getBits(): number {\n return this.bits;\n }\n\n public setBits(bits: number): void {\n this.bits = bits;\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { TypedArray } from '../common/typings';\nimport { NotImplementedError } from '../error/not-implemented-error';\nimport { Half } from './half';\n\nexport interface HdrSliceInitOptions {\n name: string;\n width: number;\n height: number;\n format: number;\n bitsPerSample: number;\n data?: TypedArray;\n}\n\n/**\n * A slice is the data for an image framebuffer for a single channel.\n */\nexport class HdrSlice {\n public static UINT = 0;\n public static INT = 1;\n public static FLOAT = 3;\n\n private readonly _data: TypedArray;\n /**\n * **data** will be one of the type data lists, depending on the **type** and\n * **bitsPerSample**. 16-bit FLOAT slices will be stored in a **Uint16Array**.\n */\n public get data(): TypedArray {\n return this._data;\n }\n\n private readonly _name: string;\n public get name(): string {\n return this._name;\n }\n\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n /**\n * Indicates the type of data stored by the slice, either **HdrSlice.INT**,\n * **HdrSlice.FLOAT**, or **HdrSlice.UINT**.\n */\n private readonly _format: number;\n public get format(): number {\n return this._format;\n }\n\n /**\n * How many bits per sample, either 8, 16, 32, or 64.\n */\n private readonly _bitsPerSample: number;\n public get bitsPerSample(): number {\n return this._bitsPerSample;\n }\n\n private get maxIntSize(): number {\n let v = 0xffffffff;\n if (this._bitsPerSample === 8) {\n v = 0xff;\n } else if (this._bitsPerSample === 16) {\n v = 0xffff;\n }\n if (this._format === HdrSlice.INT) {\n v -= 1;\n }\n return v;\n }\n\n /**\n * Does this channel store floating-point data?\n */\n public get isFloat(): boolean {\n return this._format === HdrSlice.FLOAT;\n }\n\n constructor(options: HdrSliceInitOptions) {\n this._name = options.name;\n this._width = options.width;\n this._height = options.height;\n this._format = options.format;\n this._bitsPerSample = options.bitsPerSample;\n this._data =\n options.data ??\n HdrSlice.allocateDataForType(\n options.width * options.height,\n options.format,\n options.bitsPerSample\n );\n }\n\n private static allocateDataForType(\n size: number,\n type: number,\n bitsPerSample: number\n ): TypedArray {\n switch (type) {\n case HdrSlice.INT:\n if (bitsPerSample === 8) {\n return new Int8Array(size);\n } else if (bitsPerSample === 16) {\n return new Int16Array(size);\n } else if (bitsPerSample === 32) {\n return new Int32Array(size);\n }\n break;\n case HdrSlice.UINT:\n if (bitsPerSample === 8) {\n return new Uint8Array(size);\n } else if (bitsPerSample === 16) {\n return new Uint16Array(size);\n } else if (bitsPerSample === 32) {\n return new Uint32Array(size);\n }\n break;\n case HdrSlice.FLOAT:\n if (bitsPerSample === 16) {\n return new Uint16Array(size);\n } else if (bitsPerSample === 32) {\n return new Float32Array(size);\n } else if (bitsPerSample === 64) {\n return new Float64Array(size);\n }\n break;\n }\n throw new NotImplementedError();\n }\n\n /**\n * Create a copy of the **other** HdrSlice.\n */\n public static from(other: HdrSlice): HdrSlice {\n return new HdrSlice({\n name: other._name,\n width: other._width,\n height: other._height,\n format: other._format,\n bitsPerSample: other._bitsPerSample,\n data: ArrayUtils.copy(other.data),\n });\n }\n\n /**\n * Get the raw bytes of the data buffer.\n */\n public getBytes(): Uint8Array {\n return new Uint8Array(this._data.buffer);\n }\n\n /**\n * Get the float value of the sample at the coordinates **x**,**y**.\n * **Half** samples are converted to double.\n */\n public getFloat(x: number, y: number): number {\n const pi = y * this._width + x;\n if (this._format === HdrSlice.INT || this._format === HdrSlice.UINT) {\n return Math.trunc(this._data[pi]) / this.maxIntSize;\n }\n const s =\n this._format === HdrSlice.FLOAT && this._bitsPerSample === 16\n ? Half.halfToDouble(this._data[pi])\n : this._data[pi];\n return s;\n }\n\n /**\n * Set the float value of the sample at the coordinates **x**,**y** for\n * **FLOAT** slices.\n */\n public setFloat(x: number, y: number, v: number): void {\n if (this._format !== HdrSlice.FLOAT) {\n return;\n }\n const pi = y * this._width + x;\n if (this._bitsPerSample === 16) {\n this._data[pi] = Half.doubleToHalf(v);\n } else {\n this._data[pi] = v;\n }\n }\n\n /**\n * Get the int value of the sample at the coordinates **x**,**y**.\n * An exception will occur if the slice stores FLOAT data.\n */\n public getInt(x: number, y: number): number {\n const pi = y * this._width + x;\n return Math.trunc(this._data[pi]);\n }\n\n /**\n * Set the int value of the sample at the coordinates **x**,**y** for **INT** and\n * **UINT** slices.\n */\n public setInt(x: number, y: number, v: number): void {\n const pi = y * this._width + x;\n this._data[pi] = Math.trunc(v);\n }\n}\n", "/** @format */\n\nimport { MemoryImage } from '../common/memory-image';\nimport { RgbChannelSet } from '../common/rgb-channel-set';\nimport { ExifData } from '../exif/exif-data';\nimport { HdrSlice } from './hdr-slice';\n\n/**\n * A high dynamic range RGBA image stored in 16-bit or 32-bit floating-point\n * channels.\n */\nexport class HdrImage {\n /**\n * Red value of a sample\n */\n private static R = 'R';\n /**\n * Green value of a sample\n */\n private static G = 'G';\n /**\n * Blue value of a sample\n */\n private static B = 'B';\n /**\n * Alpha/opacity\n */\n private static A = 'A';\n /**\n * Distance of the front of a sample from the viewer\n */\n private static Z = 'Z';\n\n private readonly _slices: Map = new Map();\n public get slices(): Map {\n return this._slices;\n }\n\n private _red: HdrSlice | undefined = undefined;\n public get red(): HdrSlice | undefined {\n return this._red;\n }\n\n private _green: HdrSlice | undefined = undefined;\n public get green(): HdrSlice | undefined {\n return this._green;\n }\n\n private _blue: HdrSlice | undefined = undefined;\n public get blue(): HdrSlice | undefined {\n return this._blue;\n }\n\n private _alpha: HdrSlice | undefined = undefined;\n public get alpha(): HdrSlice | undefined {\n return this._alpha;\n }\n\n private _depth: HdrSlice | undefined = undefined;\n public get depth(): HdrSlice | undefined {\n return this._depth;\n }\n\n private _exifData: ExifData | undefined = undefined;\n public get exifData(): ExifData | undefined {\n return this._exifData;\n }\n public set exifData(v: ExifData | undefined) {\n this._exifData = v;\n }\n\n /**\n * Does the image have any color channels?\n */\n get hasColor(): boolean {\n return (\n this.red !== undefined ||\n this.green !== undefined ||\n this.blue !== undefined\n );\n }\n\n /**\n * Does the image have an alpha channel?\n */\n get hasAlpha(): boolean {\n return this.alpha !== undefined;\n }\n\n /**\n * Does the image have a depth channel?\n */\n get hasDepth(): boolean {\n return this.depth !== undefined;\n }\n\n /**\n * The width of the framebuffer.\n */\n get width(): number {\n if (this.slices.size > 0) {\n const firstSlice = this.slices.values().next().value as HdrSlice;\n return firstSlice.width;\n } else {\n return 0;\n }\n }\n\n /**\n * The height of the framebuffer.\n */\n get height(): number {\n if (this.slices.size > 0) {\n const firstSlice = this.slices.values().next().value as HdrSlice;\n return firstSlice.height;\n } else {\n return 0;\n }\n }\n\n /**\n * The number of bits per sample.\n */\n get bitsPerSample(): number {\n if (this.red !== undefined) {\n return this.red.bitsPerSample;\n } else {\n if (this.slices.size > 0) {\n const firstSlice = this.slices.values().next().value as HdrSlice;\n return firstSlice.bitsPerSample;\n } else {\n return 0;\n }\n }\n }\n\n get sampleFormat(): number {\n if (this.red !== undefined) {\n return this.red.format;\n } else {\n if (this.slices.size > 0) {\n const firstSlice = this.slices.values().next().value as HdrSlice;\n return firstSlice.format;\n } else {\n return 0;\n }\n }\n }\n\n /**\n * The number of channels used by the image\n */\n get numberOfChannels(): number {\n return this.slices.size;\n }\n\n /**\n * Create an RGB[A] image.\n */\n public static create(\n width: number,\n height: number,\n channels: number,\n type: number,\n bitsPerSample: number\n ): HdrImage {\n const image = new HdrImage();\n if (0 <= channels && channels <= 4) {\n const channelList = [HdrImage.R, HdrImage.G, HdrImage.B, HdrImage.A];\n for (let i = 0; i < channels; ++i) {\n image.addChannel(\n new HdrSlice({\n name: channelList[i],\n width: width,\n height: height,\n format: type,\n bitsPerSample: bitsPerSample,\n })\n );\n }\n return image;\n } else {\n return image;\n }\n }\n\n /**\n * Create a copy of the **other** HdrImage.\n */\n public static from(other: HdrImage): HdrImage {\n const image = new HdrImage();\n for (const [, value] of other.slices) {\n image.addChannel(HdrSlice.from(value));\n }\n return image;\n }\n\n /**\n * Create an HDR image from a LDR **MemoryImage** by transforming the channel values\n * to the range [**0**, **1**].\n */\n public static fromImage(\n other: MemoryImage,\n type: number = HdrSlice.FLOAT,\n bitsPerSample = 16\n ): HdrImage {\n const image = new HdrImage();\n image.addChannel(\n new HdrSlice({\n name: HdrImage.R,\n width: other.width,\n height: other.height,\n format: type,\n bitsPerSample: bitsPerSample,\n })\n );\n image.addChannel(\n new HdrSlice({\n name: HdrImage.G,\n width: other.width,\n height: other.height,\n format: type,\n bitsPerSample: bitsPerSample,\n })\n );\n image.addChannel(\n new HdrSlice({\n name: HdrImage.B,\n width: other.width,\n height: other.height,\n format: type,\n bitsPerSample: bitsPerSample,\n })\n );\n if (other.rgbChannelSet === RgbChannelSet.rgba) {\n image.addChannel(\n new HdrSlice({\n name: HdrImage.A,\n width: other.width,\n height: other.height,\n format: type,\n bitsPerSample: bitsPerSample,\n })\n );\n }\n const rgb = other.getBytes();\n for (let y = 0, si = 0; y < other.height; ++y) {\n for (let x = 0; x < other.width; ++x) {\n image.setRed(x, y, rgb[si++] / 255);\n image.setGreen(x, y, rgb[si++] / 255);\n image.setBlue(x, y, rgb[si++] / 255);\n if (image.alpha !== undefined) {\n image.setAlpha(x, y, rgb[si++] / 255);\n }\n }\n }\n return image;\n }\n\n /**\n * Get the value of the red channel at the given pixel coordinates **x**, **y**.\n */\n public getRed(x: number, y: number): number {\n if (this.red !== undefined) {\n return this.red.isFloat ? this.red.getFloat(x, y) : this.red.getInt(x, y);\n } else {\n return 0;\n }\n }\n\n /**\n * Set the value of the red channel at the given pixel coordinates **x**, **y**.\n */\n public setRed(x: number, y: number, c: number): void {\n if (this.red !== undefined) {\n if (this.red.isFloat) {\n this.red.setFloat(x, y, c);\n } else {\n this.red.setInt(x, y, c);\n }\n }\n }\n\n public setRedInt(x: number, y: number, c: number): void {\n if (this.red !== undefined) {\n this.red.setInt(x, y, c);\n }\n }\n\n /**\n * Get the value of the green channel at the given pixel coordinates **x**, **y**.\n */\n public getGreen(x: number, y: number): number {\n if (this.green !== undefined) {\n return this.green.isFloat\n ? this.green.getFloat(x, y)\n : this.green.getInt(x, y);\n } else {\n return 0;\n }\n }\n\n /**\n * Set the value of the green channel at the given pixel coordinates **x**, **y**.\n */\n public setGreen(x: number, y: number, c: number): void {\n if (this.green !== undefined) {\n if (this.green.isFloat) {\n this.green.setFloat(x, y, c);\n } else {\n this.green.setInt(x, y, c);\n }\n }\n }\n\n public setGreenInt(x: number, y: number, c: number): void {\n if (this.green !== undefined) {\n this.green.setInt(x, y, c);\n }\n }\n\n /**\n * Get the value of the blue channel at the given pixel coordinates **x**, **y**.\n */\n public getBlue(x: number, y: number): number {\n if (this.blue !== undefined) {\n return this.blue.isFloat\n ? this.blue.getFloat(x, y)\n : this.blue.getInt(x, y);\n } else {\n return 0;\n }\n }\n /**\n * Set the value of the blue channel at the given pixel coordinates **x**, **y**.\n */\n public setBlue(x: number, y: number, c: number): void {\n if (this.blue !== undefined) {\n if (this.blue.isFloat) {\n this.blue.setFloat(x, y, c);\n } else {\n this.blue.setInt(x, y, c);\n }\n }\n }\n\n public setBlueInt(x: number, y: number, c: number): void {\n if (this.blue !== undefined) {\n this.blue.setInt(x, y, c);\n }\n }\n\n /**\n * Get the value of the alpha channel at the given pixel coordinates **x**, **y**.\n */\n public getAlpha(x: number, y: number): number {\n if (this.alpha !== undefined) {\n return this.alpha.isFloat\n ? this.alpha.getFloat(x, y)\n : this.alpha.getInt(x, y);\n } else {\n return 0;\n }\n }\n\n /**\n * Set the value of the alpha channel at the given pixel coordinates **x**, **y**.\n */\n public setAlpha(x: number, y: number, c: number): void {\n if (this.alpha !== undefined) {\n if (this.alpha.isFloat) {\n this.alpha.setFloat(x, y, c);\n } else {\n this.alpha.setInt(x, y, c);\n }\n }\n }\n\n public setAlphaInt(x: number, y: number, c: number): void {\n if (this.alpha !== undefined) {\n this.alpha.setInt(x, y, c);\n }\n }\n\n /**\n * Get the value of the depth channel at the given pixel coordinates **x**, **y**.\n */\n public getDepth(x: number, y: number): number {\n if (this.depth !== undefined) {\n return this.depth.isFloat\n ? this.depth.getFloat(x, y)\n : this.depth.getInt(x, y);\n } else {\n return 0;\n }\n }\n\n /**\n * Set the value of the depth channel at the given pixel coordinates **x**, **y**.\n */\n public setDepth(x: number, y: number, c: number): void {\n if (this.depth !== undefined) {\n if (this.depth.isFloat) {\n this.depth.setFloat(x, y, c);\n } else {\n this.depth.setInt(x, y, c);\n }\n }\n }\n\n public setDepthInt(x: number, y: number, c: number): void {\n if (this.depth !== undefined) {\n this.depth.setInt(x, y, c);\n }\n }\n\n /**\n * Does this image contain the given channel?\n */\n public hasChannel(ch: string): boolean {\n return this.slices.has(ch);\n }\n\n /**\n * Access a framebuffer slice by name.\n */\n public getChannel(ch: string): HdrSlice | undefined {\n return this.slices.get(ch);\n }\n\n /**\n * Add a channel **slice** to the\n */\n public addChannel(slice: HdrSlice): void {\n const ch = slice.name;\n this.slices.set(ch, slice);\n switch (ch) {\n case HdrImage.R:\n this._red = slice;\n break;\n case HdrImage.G:\n this._green = slice;\n break;\n case HdrImage.B:\n this._blue = slice;\n break;\n case HdrImage.A:\n this._alpha = slice;\n break;\n case HdrImage.Z:\n this._depth = slice;\n break;\n }\n }\n\n /**\n * Convert the framebuffer to an floating-point image, as a sequence of\n * floats in RGBA order.\n */\n public toFloatRgba(): Float32Array {\n const rgba = new Float32Array(this.width * this.height * 4);\n const w = this.width;\n const h = this.height;\n for (let y = 0, di = 0; y < h; ++y) {\n for (let x = 0; x < w; ++x) {\n rgba[di++] = this.red === undefined ? 0.0 : this.red.getFloat(x, y);\n rgba[di++] = this.green === undefined ? 0.0 : this.green.getFloat(x, y);\n rgba[di++] = this.blue === undefined ? 0.0 : this.blue.getFloat(x, y);\n rgba[di++] = this.alpha === undefined ? 1.0 : this.alpha.getFloat(x, y);\n }\n }\n return rgba;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { ImageError } from '../../error/image-error';\n\nexport class BitmapFileHeader {\n // BM\n public static readonly BMP_HEADER_FILETYPE = 0x42 + (0x4d << 8);\n\n private readonly _fileLength: number;\n public get fileLength(): number {\n return this._fileLength;\n }\n\n private _offset: number;\n public set offset(v: number) {\n this._offset = v;\n }\n public get offset(): number {\n return this._offset;\n }\n\n constructor(b: InputBuffer) {\n if (!BitmapFileHeader.isValidFile(b)) {\n throw new ImageError('Not a bitmap file.');\n }\n b.skip(2);\n this._fileLength = b.readInt32();\n // Skip reserved space\n b.skip(4);\n this._offset = b.readInt32();\n }\n\n public static isValidFile(b: InputBuffer): boolean {\n if (b.length < 2) {\n return false;\n }\n const type = InputBuffer.from(b).readUint16();\n return type === BitmapFileHeader.BMP_HEADER_FILETYPE;\n }\n\n public toJson(): Map {\n return new Map([\n ['offset', this._offset],\n ['fileLength', this.fileLength],\n ['fileType', BitmapFileHeader.BMP_HEADER_FILETYPE],\n ]);\n }\n}\n", "/** @format */\n\nexport enum BitmapCompressionMode {\n BI_BITFIELDS,\n NONE,\n}\n", "/** @format */\n\nimport { BitOperators } from '../../common/bit-operators';\nimport { Color } from '../../common/color';\nimport { InputBuffer } from '../../common/input-buffer';\nimport { ImageError } from '../../error/image-error';\nimport { NotImplementedError } from '../../error/not-implemented-error';\nimport { DecodeInfo } from '../decode-info';\nimport { BitmapCompressionMode } from './bitmap-compression-mode';\nimport { BitmapFileHeader } from './bitmap-file-header';\n\nexport class BmpInfo implements DecodeInfo {\n private readonly _width: number = 0;\n public get width(): number {\n return this._width;\n }\n\n protected readonly _height: number = 0;\n public get height(): number {\n return this._height;\n }\n\n private readonly _backgroundColor: number = 0xffffffff;\n public get backgroundColor(): number {\n return this._backgroundColor;\n }\n\n private readonly _numFrames: number = 1;\n public get numFrames(): number {\n return this._numFrames;\n }\n\n private readonly _fileHeader: BitmapFileHeader;\n public get fileHeader(): BitmapFileHeader {\n return this._fileHeader;\n }\n\n private readonly _headerSize: number;\n public get headerSize(): number {\n return this._headerSize;\n }\n\n private readonly _planes: number;\n public get planes(): number {\n return this._planes;\n }\n\n private readonly _bpp: number;\n public get bpp(): number {\n return this._bpp;\n }\n\n private readonly _compression: BitmapCompressionMode;\n public get compression(): BitmapCompressionMode {\n return this._compression;\n }\n\n private readonly _imageSize: number;\n public get imageSize(): number {\n return this._imageSize;\n }\n\n private readonly _xppm: number;\n public get xppm(): number {\n return this._xppm;\n }\n\n private readonly _yppm: number;\n public get yppm(): number {\n return this._yppm;\n }\n\n private readonly _totalColors: number;\n public get totalColors(): number {\n return this._totalColors;\n }\n\n private readonly _importantColors: number;\n public get importantColors(): number {\n return this._importantColors;\n }\n\n private readonly _readBottomUp: boolean;\n public get readBottomUp(): boolean {\n return this._readBottomUp;\n }\n\n private _v5redMask?: number;\n public get v5redMask(): number | undefined {\n return this._v5redMask;\n }\n\n private _v5greenMask?: number;\n public get v5greenMask(): number | undefined {\n return this._v5greenMask;\n }\n\n private _v5blueMask?: number;\n public get v5blueMask(): number | undefined {\n return this._v5blueMask;\n }\n\n private _v5alphaMask?: number;\n public get v5alphaMask(): number | undefined {\n return this._v5alphaMask;\n }\n\n private _colorPalette?: number[];\n public get colorPalette(): number[] | undefined {\n return this._colorPalette;\n }\n\n // BITMAPINFOHEADER should (probably) ignore alpha channel altogether.\n // This is the behavior in gimp (?)\n // https://gitlab.gnome.org/GNOME/gimp/-/issues/461#note_208715\n public get ignoreAlphaChannel(): boolean {\n return (\n this._headerSize === 40 ||\n // BITMAPV5HEADER with undefined alpha mask.\n (this._headerSize === 124 && this._v5alphaMask === 0)\n );\n }\n\n constructor(p: InputBuffer, fileHeader?: BitmapFileHeader) {\n this._fileHeader = fileHeader ?? new BitmapFileHeader(p);\n this._headerSize = p.readUint32();\n this._width = p.readInt32();\n\n const height = p.readInt32();\n this._readBottomUp = height > 0;\n this._height = Math.abs(height);\n\n this._planes = p.readUint16();\n this._bpp = p.readUint16();\n this._compression = BmpInfo.intToCompressionMode(p.readUint32());\n this._imageSize = p.readUint32();\n this._xppm = p.readInt32();\n this._yppm = p.readInt32();\n this._totalColors = p.readUint32();\n this._importantColors = p.readUint32();\n\n if ([1, 4, 8].includes(this._bpp)) {\n this.readPalette(p);\n }\n if (this._headerSize === 124) {\n // BITMAPV5HEADER\n this._v5redMask = p.readUint32();\n this._v5greenMask = p.readUint32();\n this._v5blueMask = p.readUint32();\n this._v5alphaMask = p.readUint32();\n }\n }\n\n private static intToCompressionMode(\n compIndex: number\n ): BitmapCompressionMode {\n const map = new Map([\n [0, BitmapCompressionMode.NONE],\n // [ 1, BitmapCompression.RLE_8 ],\n // [ 2, BitmapCompression.RLE_4 ],\n [3, BitmapCompressionMode.BI_BITFIELDS],\n ]);\n const compression = map.get(compIndex);\n if (compression === undefined) {\n throw new ImageError(\n `Bitmap compression ${compIndex} is not supported yet.`\n );\n }\n return compression;\n }\n\n private compressionModeToString(): string {\n switch (this._compression) {\n case BitmapCompressionMode.BI_BITFIELDS:\n return 'BI_BITFIELDS';\n case BitmapCompressionMode.NONE:\n return 'none';\n }\n throw new NotImplementedError();\n }\n\n private readPalette(p: InputBuffer): void {\n const colors = this._totalColors === 0 ? 1 << this._bpp : this._totalColors;\n const colorBytes = this._headerSize === 12 ? 3 : 4;\n const colorPalette: number[] = [];\n for (let i = 0; i < colors; i++) {\n const color = this.readRgba(p, colorBytes === 3 ? 100 : undefined);\n colorPalette.push(color);\n }\n this._colorPalette = colorPalette;\n }\n\n private readRgba(input: InputBuffer, aDefault?: number): number {\n if (this._readBottomUp) {\n const b = input.readByte();\n const g = input.readByte();\n const r = input.readByte();\n const a = aDefault ?? input.readByte();\n return Color.getColor(r, g, b, this.ignoreAlphaChannel ? 255 : a);\n } else {\n const r = input.readByte();\n const b = input.readByte();\n const g = input.readByte();\n const a = aDefault ?? input.readByte();\n return Color.getColor(r, b, g, this.ignoreAlphaChannel ? 255 : a);\n }\n }\n\n public decodeRgba(input: InputBuffer, pixel: (color: number) => void): void {\n if (this._colorPalette !== undefined) {\n if (this._bpp === 1) {\n const b = input.readByte().toString(2).padStart(8, '0');\n for (let i = 0; i < 8; i++) {\n pixel(this._colorPalette![parseInt(b[i])]);\n }\n return;\n } else if (this._bpp === 4) {\n const b = input.readByte();\n const left = b >> 4;\n const right = b & 0x0f;\n pixel(this._colorPalette[left]);\n pixel(this._colorPalette[right]);\n return;\n } else if (this._bpp === 8) {\n const b = input.readByte();\n pixel(this._colorPalette[b]);\n return;\n }\n }\n if (\n this._bpp === 32 &&\n this._compression === BitmapCompressionMode.BI_BITFIELDS\n ) {\n pixel(this.readRgba(input));\n return;\n }\n if (this._bpp === 32 && this._compression === BitmapCompressionMode.NONE) {\n pixel(this.readRgba(input));\n return;\n }\n if (this._bpp === 24) {\n pixel(this.readRgba(input, 255));\n return;\n }\n // If (this.bpp === 16) {\n // return this._rgbaFrom16(input);\n // }\n throw new ImageError(\n `Unsupported bpp (${this._bpp}) or compression (${this._compression}).`\n );\n }\n\n // TODO: finish decoding for 16 bit\n // private rgbaFrom16(input: InputBuffer): number[] {\n // const maskRed = 0x7C00;\n // const maskGreen = 0x3E0;\n // const maskBlue = 0x1F;\n // const pixel = input.readUint16();\n // return [ (pixel & maskRed), (pixel & maskGreen), (pixel & maskBlue), 0 ];\n // }\n\n public toString(): string {\n return JSON.stringify(\n {\n headerSize: this._headerSize,\n width: this._width,\n height: this._height,\n planes: this._planes,\n bpp: this._bpp,\n file: this._fileHeader.toJson(),\n compression: this.compressionModeToString(),\n imageSize: this._imageSize,\n xppm: this._xppm,\n yppm: this._yppm,\n totalColors: this._totalColors,\n importantColors: this._importantColors,\n readBottomUp: this._readBottomUp,\n v5redMask: BitOperators.debugBits32(this._v5redMask),\n v5greenMask: BitOperators.debugBits32(this._v5greenMask),\n v5blueMask: BitOperators.debugBits32(this._v5blueMask),\n v5alphaMask: BitOperators.debugBits32(this._v5alphaMask),\n },\n undefined,\n 2\n );\n }\n}\n", "/** @format */\n\nimport { FrameAnimation } from '../common/frame-animation';\nimport { InputBuffer } from '../common/input-buffer';\nimport { MemoryImage } from '../common/memory-image';\nimport { HdrImage } from '../hdr/hdr-image';\nimport { BitmapFileHeader } from './bmp/bitmap-file-header';\nimport { BmpInfo } from './bmp/bmp-info';\nimport { Decoder } from './decoder';\n\nexport class BmpDecoder implements Decoder {\n protected input?: InputBuffer;\n\n protected info?: BmpInfo;\n\n public get numFrames(): number {\n return this.info !== undefined ? this.info.numFrames : 0;\n }\n\n private pixelDataOffset(): number | undefined {\n return this.info !== undefined ? this.info.fileHeader.offset : undefined;\n }\n\n /**\n * Is the given file a valid BMP image?\n */\n public isValidFile(bytes: Uint8Array): boolean {\n return BitmapFileHeader.isValidFile(\n new InputBuffer({\n buffer: bytes,\n })\n );\n }\n\n public startDecode(bytes: Uint8Array): BmpInfo | undefined {\n if (!this.isValidFile(bytes)) {\n return undefined;\n }\n this.input = new InputBuffer({\n buffer: bytes,\n });\n this.info = new BmpInfo(this.input);\n return this.info;\n }\n\n /**\n * Decode a single frame from the data stat was set with **startDecode**.\n * If **frame** is out of the range of available frames, undefined is returned.\n * Non animated image files will only have **frame** 0. An **AnimationFrame**\n * is returned, which provides the image, and top-left coordinates of the\n * image, as animated frames may only occupy a subset of the canvas.\n */\n public decodeFrame(_: number): MemoryImage | undefined {\n if (this.input === undefined || this.info === undefined) {\n return undefined;\n }\n\n const offset = this.pixelDataOffset();\n if (offset === undefined) {\n return undefined;\n }\n\n this.input.offset = offset;\n let rowStride = (this.info.width * this.info.bpp) >> 3;\n if (rowStride % 4 !== 0) {\n rowStride += 4 - (rowStride % 4);\n }\n\n const image = new MemoryImage({\n width: this.info.width,\n height: this.info.height,\n });\n for (let y = image.height - 1; y >= 0; --y) {\n const line = this.info.readBottomUp ? y : image.height - 1 - y;\n const row = this.input.readBytes(rowStride);\n for (let x = 0; x < image.width; ) {\n this.info.decodeRgba(row, (color) => {\n return image.setPixelSafe(x++, line, color);\n });\n }\n }\n\n return image;\n }\n\n public decodeHdrFrame(frame: number): HdrImage | undefined {\n const img = this.decodeFrame(frame);\n if (img === undefined) {\n return undefined;\n }\n return HdrImage.fromImage(img);\n }\n\n /**\n * Decode all of the frames from an animation. If the file is not an\n * animation, a single frame animation is returned. If there was a problem\n * decoding the file, undefined is returned.\n */\n public decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined {\n if (!this.isValidFile(bytes)) {\n return undefined;\n }\n\n const image = this.decodeImage(bytes);\n if (image === undefined) {\n return undefined;\n }\n\n const animation = new FrameAnimation();\n animation.addFrame(image);\n\n return animation;\n }\n\n /**\n * Decode the file and extract a single image from it. If the file is\n * animated, the specified **frame** will be decoded. If there was a problem\n * decoding the file, undefined is returned.\n */\n public decodeImage(bytes: Uint8Array, frame = 0): MemoryImage | undefined {\n if (!this.isValidFile(bytes)) {\n return undefined;\n }\n\n this.startDecode(bytes);\n return this.decodeFrame(frame);\n }\n\n public decodeHdrImage(bytes: Uint8Array, frame = 0): HdrImage | undefined {\n const img = this.decodeImage(bytes, frame);\n if (img === undefined) {\n return undefined;\n }\n return HdrImage.fromImage(img);\n }\n}\n", "/** @format */\n\nimport { Color } from '../common/color';\nimport { FrameAnimation } from '../common/frame-animation';\nimport { MemoryImage } from '../common/memory-image';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { RgbChannelSet } from '../common/rgb-channel-set';\nimport { BitmapFileHeader } from './bmp/bitmap-file-header';\nimport { Encoder } from './encoder';\n\n/**\n * Encode a BMP image.\n */\nexport class BmpEncoder implements Encoder {\n private _supportsAnimation = false;\n get supportsAnimation(): boolean {\n return this._supportsAnimation;\n }\n\n public encodeImage(image: MemoryImage): Uint8Array {\n const bytesPerPixel = image.rgbChannelSet === RgbChannelSet.rgb ? 3 : 4;\n const bpp = bytesPerPixel * 8;\n const rgbSize = image.width * image.height * bytesPerPixel;\n const headerSize = 54;\n const headerInfoSize = 40;\n const fileSize = rgbSize + headerSize;\n\n const out = new OutputBuffer();\n\n out.writeUint16(BitmapFileHeader.BMP_HEADER_FILETYPE);\n out.writeUint32(fileSize);\n // Reserved\n out.writeUint32(0);\n\n out.writeUint32(headerSize);\n out.writeUint32(headerInfoSize);\n out.writeUint32(image.width);\n out.writeUint32(-image.height);\n // Planes\n out.writeUint16(1);\n out.writeUint16(bpp);\n // Compress\n out.writeUint32(0);\n out.writeUint32(rgbSize);\n // Hr\n out.writeUint32(0);\n // Vr\n out.writeUint32(0);\n // Colors\n out.writeUint32(0);\n // ImportantColors\n out.writeUint32(0);\n\n for (let y = 0, pi = 0; y < image.height; ++y) {\n for (let x = 0; x < image.width; ++x, ++pi) {\n const rgba = image.getPixelByIndex(pi);\n out.writeByte(Color.getBlue(rgba));\n out.writeByte(Color.getGreen(rgba));\n out.writeByte(Color.getRed(rgba));\n if (bytesPerPixel === 4) {\n out.writeByte(Color.getAlpha(rgba));\n }\n }\n\n // Line padding\n if (bytesPerPixel !== 4) {\n const padding = 4 - ((image.width * bytesPerPixel) % 4);\n if (padding !== 4) {\n const bytes = new Uint8Array(padding - 1).fill(0x00);\n out.writeBytes(bytes);\n out.writeByte(0xff);\n }\n }\n }\n\n return out.getBytes();\n }\n\n public encodeAnimation(_: FrameAnimation): Uint8Array | undefined {\n return undefined;\n }\n}\n", "/** @format */\n\n/**\n * Provides information about the image being decoded.\n */\nexport interface DecodeInfo {\n /**\n * The width of the image canvas.\n */\n get width(): number;\n\n /**\n * The height of the image canvas.\n */\n get height(): number;\n\n /**\n * The suggested background color of the canvas.\n */\n get backgroundColor(): number;\n\n /**\n * The number of frames that can be decoded.\n */\n get numFrames(): number;\n}\n", "/** @format */\n\nimport { FrameAnimation } from '../common/frame-animation';\nimport { MemoryImage } from '../common/memory-image';\nimport { HdrImage } from '../hdr/hdr-image';\nimport { DecodeInfo } from './decode-info';\n\n/**\n * Base class for image format decoders.\n *\n * Image pixels are stored as 32-bit unsigned ints, so all formats, regardless\n * of their encoded color resolutions, decode to 32-bit RGBA images. Encoders\n * can reduce the color resolution back down to their required formats.\n *\n * Some image formats support multiple frames, often for encoding animation.\n * In such cases, the **decodeImage** method will decode the first (or otherwise\n * specified with the **frame** parameter) frame of the file. **decodeAnimation**\n * will decode all frames from the image. **startDecode** will initiate\n * decoding of the file, and **decodeFrame** will then decode a specific frame\n * from the file, allowing for animations to be decoded one frame at a time.\n * Some formats, such as TIFF, may store multiple frames, but their use of\n * frames is for multiple page documents and not animation. The terms\n * 'animation' and 'frames' simply refer to 'pages' in this case.\n *\n * If an image file does not have multiple frames, **decodeAnimation** and\n * **startDecode** / **decodeFrame** will return the single image of the\n * file. As such, if you are not sure if a file is animated or not, you can\n * use the animated functions and process it as a single frame image if it\n * has only 1 frame, and as an animation if it has more than 1 frame.\n *\n * Most animated formats do not store full images for frames, but rather\n * some frames will store full images and others will store partial 'change'\n * images. For these files, **decodeAnimation** will always return all images\n * fully composited, meaning full frame images. Decoding frames individually\n * using **startDecode** and **decodeFrame** will return the potentially partial\n * image. In this case, the **DecodeInfo** returned by **startDecode** will include\n * the width and height resolution of the animation canvas, and each **MemoryImage**\n * returned by **decodeFrame** will have x, y, width and height properties\n * indicating where in the canvas the frame image should be drawn. It will\n * also have a disposeMethod property that specifies what should be done to\n * the canvas prior to drawing the frame: **DisposeMode.none** indicates the\n * canvas should be left alone; **DisposeMode.clear** indicates the canvas\n * should be cleared. For partial frame images,**DisposeMode.none** is used\n * so that the partial-frame is drawn on top of the previous frame, applying\n * it's changes to the image.\n */\nexport interface Decoder {\n /**\n * How many frames are available to be decoded. **startDecode** should have\n * been called first. Non animated image files will have a single frame.\n */\n get numFrames(): number;\n\n /**\n * A light-weight function to test if the given file is able to be decoded\n * by this Decoder.\n */\n isValidFile(bytes: Uint8Array): boolean;\n\n /**\n * Start decoding the data as an animation sequence, but don't actually\n * process the frames until they are requested with decodeFrame.\n */\n startDecode(bytes: Uint8Array): DecodeInfo | undefined;\n\n /**\n * Decode a single frame from the data that was set with **startDecode**.\n * If **frame** is out of the range of available frames, undefined is returned.\n * Non animated image files will only have **frame** 0. A **MemoryImage**\n * is returned, which provides the image, and top-left coordinates of the\n * image, as animated frames may only occupy a subset of the canvas.\n */\n decodeFrame(frame: number): MemoryImage | undefined;\n\n /**\n * Decode a single high dynamic range (HDR) frame from the data that was set\n * with **startDecode**. If the format of the file does not support HDR images,\n * the regular image will be converted to an HDR image as (color / 255).\n * If **frame** is out of the range of available frames, undefined is returned.\n * Non animated image files will only have **frame** 0. A **MemoryImage**\n * is returned, which provides the image, and top-left coordinates of the\n * image, as animated frames may only occupy a subset of the canvas.\n */\n decodeHdrFrame(frame: number): HdrImage | undefined;\n\n /**\n * Decode all of the frames from an animation. If the file is not an\n * animation, a single frame animation is returned. If there was a problem\n * decoding the file, undefined is returned.\n */\n decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined;\n\n /**\n * Decode the file and extract a single image from it. If the file is\n * animated, the specified **frame** will be decoded. If there was a problem\n * decoding the file, undefined is returned.\n */\n decodeImage(bytes: Uint8Array, frame?: number): MemoryImage | undefined;\n\n /**\n * Decode the file and extract a single High Dynamic Range (HDR) image from\n * it. HDR images are stored in floating-poing values. If the format of the\n * file does not support HDR images, the regular image will be converted to\n * an HDR image as (color / 255). If the file is animated, the specified\n * **frame** will be decoded. If there was a problem decoding the file, undefined is\n * returned.\n */\n decodeHdrImage(bytes: Uint8Array, frame?: number): HdrImage | undefined;\n}\n", "/** @format */\n\nimport { InputBuffer } from '../common/input-buffer';\nimport { BmpDecoder } from './bmp-decoder';\nimport { BmpInfo } from './bmp/bmp-info';\n\nexport class DibDecoder extends BmpDecoder {\n constructor(input: InputBuffer, info: BmpInfo) {\n super();\n this.input = input;\n this.info = info;\n }\n}\n", "/** @format */\n\nimport { FrameAnimation } from '../common/frame-animation';\nimport { MemoryImage } from '../common/memory-image';\n\n/**\n * Base class for image format encoders.\n */\nexport interface Encoder {\n /**\n * Does this encoder support animation?\n */\n get supportsAnimation(): boolean;\n\n /**\n * Encode a single image.\n */\n encodeImage(image: MemoryImage): Uint8Array;\n\n /**\n * Encode an animation. Not all formats support animation, and undefined\n * will be returned if not.\n */\n encodeAnimation(animation: FrameAnimation): Uint8Array | undefined;\n}\n", "/** @format */\n\nexport enum FlipDirection {\n /**\n * Flip the image horizontally.\n */\n horizontal,\n\n /**\n * Flip the image vertically.\n */\n vertical,\n\n /**\n * Flip the image both horizontally and vertically.\n */\n both,\n}\n", "/** @format */\n\nimport { MemoryImage } from '../common/memory-image';\nimport { RgbChannelSet } from '../common/rgb-channel-set';\nimport { ImageError } from '../error/image-error';\nimport { Point } from '../common/point';\nimport { Rectangle } from '../common/rectangle';\nimport { FlipDirection } from './flip-direction';\nimport {\n CopyResizeOptionsUsingHeight,\n CopyResizeOptionsUsingWidth,\n} from './copy-resize-options';\nimport { CopyIntoOptions } from './copy-into-options';\nimport { Draw } from '../draw/draw';\nimport { Interpolation } from '../common/interpolation';\nimport { Color } from '../common/color';\nimport { MathOperators } from '../common/math-operators';\nimport { ExifData } from '../exif/exif-data';\n\nexport abstract class ImageTransform {\n /**\n * Returns a copy of the **src** image, rotated by **angle** degrees.\n */\n public static copyRotate(\n src: MemoryImage,\n angle: number,\n interpolation: Interpolation = Interpolation.nearest\n ): MemoryImage {\n const nangle: number = angle % 360.0;\n\n // Optimized version for orthogonal angles.\n if (nangle % 90 === 0) {\n const wm1 = src.width - 1;\n const hm1 = src.height - 1;\n\n const iangle = Math.floor(nangle / 90.0);\n switch (iangle) {\n case 1: {\n // 90 deg.\n const dst = new MemoryImage({\n width: src.height,\n height: src.width,\n rgbChannelSet: src.rgbChannelSet,\n exifData: src.exifData,\n iccProfile: src.iccProfile,\n });\n for (let y = 0; y < dst.height; ++y) {\n for (let x = 0; x < dst.width; ++x) {\n dst.setPixel(x, y, src.getPixel(y, hm1 - x));\n }\n }\n return dst;\n }\n case 2: {\n // 180 deg.\n const dst = new MemoryImage({\n width: src.width,\n height: src.height,\n rgbChannelSet: src.rgbChannelSet,\n exifData: src.exifData,\n iccProfile: src.iccProfile,\n });\n for (let y = 0; y < dst.height; ++y) {\n for (let x = 0; x < dst.width; ++x) {\n dst.setPixel(x, y, src.getPixel(wm1 - x, hm1 - y));\n }\n }\n return dst;\n }\n case 3: {\n // 270 deg.\n const dst = new MemoryImage({\n width: src.height,\n height: src.width,\n rgbChannelSet: src.rgbChannelSet,\n exifData: src.exifData,\n iccProfile: src.iccProfile,\n });\n for (let y = 0; y < dst.height; ++y) {\n for (let x = 0; x < dst.width; ++x) {\n dst.setPixel(x, y, src.getPixel(wm1 - y, x));\n }\n }\n return dst;\n }\n default: {\n // 0 deg.\n return MemoryImage.from(src);\n }\n }\n }\n\n // Generic angle.\n const rad = (nangle * Math.PI) / 180.0;\n const ca = Math.cos(rad);\n const sa = Math.sin(rad);\n const ux = Math.abs(src.width * ca);\n const uy = Math.abs(src.width * sa);\n const vx = Math.abs(src.height * sa);\n const vy = Math.abs(src.height * ca);\n const w2 = 0.5 * src.width;\n const h2 = 0.5 * src.height;\n const dw2 = 0.5 * (ux + vx);\n const dh2 = 0.5 * (uy + vy);\n\n const dst = new MemoryImage({\n width: Math.trunc(ux + vx),\n height: Math.trunc(uy + vy),\n rgbChannelSet: RgbChannelSet.rgba,\n exifData: src.exifData,\n iccProfile: src.iccProfile,\n });\n\n for (let y = 0; y < dst.height; ++y) {\n for (let x = 0; x < dst.width; ++x) {\n const c = src.getPixelInterpolate(\n w2 + (x - dw2) * ca + (y - dh2) * sa,\n h2 - (x - dw2) * sa + (y - dh2) * ca,\n interpolation\n );\n dst.setPixel(x, y, c);\n }\n }\n\n return dst;\n }\n\n /**\n * If **image** has an orientation value in its exif data, this will rotate the\n * image so that it physically matches its orientation. This can be used to\n * bake the orientation of the image for image formats that don't support exif\n * data.\n */\n public static bakeOrientation(image: MemoryImage): MemoryImage {\n const bakedImage = MemoryImage.from(image);\n if (\n !image.exifData.imageIfd.hasOrientation ||\n image.exifData.imageIfd.orientation === 1\n ) {\n return bakedImage;\n }\n\n // Copy all exif data except for orientation\n bakedImage.exifData = ExifData.from(image.exifData);\n bakedImage.exifData.imageIfd.orientation = undefined;\n\n switch (image.exifData.imageIfd.orientation) {\n case 2:\n return ImageTransform.flipHorizontal(bakedImage);\n case 3:\n return ImageTransform.flip(bakedImage, FlipDirection.both);\n case 4: {\n const rotated = ImageTransform.copyRotate(bakedImage, 180);\n return ImageTransform.flipHorizontal(rotated);\n }\n case 5: {\n const rotated = ImageTransform.copyRotate(bakedImage, 90);\n return ImageTransform.flipHorizontal(rotated);\n }\n case 6:\n return ImageTransform.copyRotate(bakedImage, 90);\n case 7: {\n const rotated = ImageTransform.copyRotate(bakedImage, -90);\n return ImageTransform.flipHorizontal(rotated);\n }\n case 8:\n return ImageTransform.copyRotate(bakedImage, -90);\n }\n return bakedImage;\n }\n\n /**\n * Returns a resized copy of the **src** image.\n * If **height** isn't specified, then it will be determined by the aspect\n * ratio of **src** and **width**.\n * If **width** isn't specified, then it will be determined by the aspect ratio\n * of **src** and **height**.\n */\n public static copyResize(\n options: CopyResizeOptionsUsingWidth | CopyResizeOptionsUsingHeight\n ): MemoryImage {\n options.interpolation ??= Interpolation.nearest;\n options.width ??= 0;\n options.height ??= 0;\n\n if (options.width === 0 && options.height === 0) {\n throw new ImageError('CopyResize: wrong size');\n }\n\n const src = ImageTransform.bakeOrientation(options.image);\n\n if (options.height === 0) {\n options.height = Math.trunc(options.width * (src.height / src.width));\n }\n\n if (options.width === 0) {\n options.width = Math.trunc(options.height * (src.width / src.height));\n }\n\n if (options.width === src.width && options.height === src.height) {\n return src.clone();\n }\n\n const dst = new MemoryImage({\n width: options.width,\n height: options.height,\n rgbChannelSet: src.rgbChannelSet,\n exifData: src.exifData,\n iccProfile: src.iccProfile,\n });\n\n const dy = src.height / options.height;\n const dx = src.width / options.width;\n\n if (options.interpolation === Interpolation.average) {\n const sData = src.getBytes();\n const sw4 = src.width * 4;\n\n for (let y = 0; y < options.height; ++y) {\n const y1 = Math.trunc(y * dy);\n let y2 = Math.trunc((y + 1) * dy);\n if (y2 === y1) {\n y2++;\n }\n\n for (let x = 0; x < options.width; ++x) {\n const x1 = Math.trunc(x * dx);\n let x2 = Math.trunc((x + 1) * dx);\n if (x2 === x1) {\n x2++;\n }\n\n let r = 0;\n let g = 0;\n let b = 0;\n let a = 0;\n let np = 0;\n for (let sy = y1; sy < y2; ++sy) {\n let si = sy * sw4 + x1 * 4;\n for (let sx = x1; sx < x2; ++sx, ++np) {\n r += sData[si++];\n g += sData[si++];\n b += sData[si++];\n a += sData[si++];\n }\n }\n dst.setPixel(\n x,\n y,\n Color.getColor(\n Math.floor(r / np),\n Math.floor(g / np),\n Math.floor(b / np),\n Math.floor(a / np)\n )\n );\n }\n }\n } else if (options.interpolation === Interpolation.nearest) {\n const scaleX = new Int32Array(options.width);\n for (let x = 0; x < options.width; ++x) {\n scaleX[x] = Math.trunc(x * dx);\n }\n for (let y = 0; y < options.height; ++y) {\n const y2 = Math.trunc(y * dy);\n for (let x = 0; x < options.width; ++x) {\n dst.setPixel(x, y, src.getPixel(scaleX[x], y2));\n }\n }\n } else {\n // Copy the pixels from this image to the new image.\n for (let y = 0; y < options.height; ++y) {\n const y2 = y * dy;\n for (let x = 0; x < options.width; ++x) {\n const x2 = x * dx;\n dst.setPixel(\n x,\n y,\n src.getPixelInterpolate(x2, y2, options.interpolation)\n );\n }\n }\n }\n\n return dst;\n }\n\n /**\n * Returns a resized and square cropped copy of the **src** image of **size** size.\n */\n public static copyResizeCropSquare(\n src: MemoryImage,\n size: number\n ): MemoryImage {\n if (size <= 0) {\n throw new ImageError('Invalid size');\n }\n\n let height = size;\n let width = size;\n if (src.width < src.height) {\n height = Math.trunc(size * (src.height / src.width));\n } else if (src.width > src.height) {\n width = Math.trunc(size * (src.width / src.height));\n }\n\n const dst = new MemoryImage({\n width: size,\n height: size,\n rgbChannelSet: src.rgbChannelSet,\n exifData: src.exifData,\n iccProfile: src.iccProfile,\n });\n\n const dy = src.height / height;\n const dx = src.width / width;\n\n const xOffset = Math.trunc((width - size) / 2);\n const yOffset = Math.trunc((height - size) / 2);\n\n const scaleX = new Int32Array(size);\n for (let x = 0; x < size; ++x) {\n scaleX[x] = Math.trunc((x + xOffset) * dx);\n }\n\n for (let y = 0; y < size; ++y) {\n const y2 = Math.trunc((y + yOffset) * dy);\n for (let x = 0; x < size; ++x) {\n dst.setPixel(x, y, src.getPixel(scaleX[x], y2));\n }\n }\n\n return dst;\n }\n\n /**\n * Copies a rectangular portion of one image to another image. **dst** is the\n * destination image, **src** is the source image identifier.\n *\n * In other words, copyInto will take an rectangular area from **src** of\n * width **srcW** and height **srcH** at position (**srcX**,**srcY**) and place it\n * in a rectangular area of **dst** of width **dstW** and height **dstH** at\n * position (**dstX**,**dstY**).\n *\n * If the source and destination coordinates and width and heights differ,\n * appropriate stretching or shrinking of the image fragment will be performed.\n * The coordinates refer to the upper left corner. This function can be used to\n * copy regions within the same image (if **dst** is the same as **src**)\n * but if the regions overlap the results will be unpredictable.\n *\n * **dstX** and **dstY** represent the X and Y position where the **src** will start\n * printing.\n *\n * if **center** is true, the **src** will be centered in **dst**.\n */\n public static copyInto(options: CopyIntoOptions): MemoryImage {\n options.dstX ??= 0;\n options.dstY ??= 0;\n options.srcX ??= 0;\n options.srcY ??= 0;\n options.srcW ??= options.src.width;\n options.srcH ??= options.src.height;\n options.blend ??= true;\n options.center ??= false;\n\n if (options.center) {\n {\n // If src is wider than dst\n let wdt = options.dst.width - options.src.width;\n if (wdt < 0) {\n wdt = 0;\n }\n options.dstX = Math.floor(wdt / 2);\n }\n {\n // If src is higher than dst\n let hight = options.dst.height - options.src.height;\n if (hight < 0) {\n hight = 0;\n }\n options.dstY = Math.floor(hight / 2);\n }\n }\n\n if (options.blend) {\n for (let y = 0; y < options.srcH; ++y) {\n for (let x = 0; x < options.srcW; ++x) {\n const pos = new Point(options.dstX + x, options.dstY + y);\n Draw.drawPixel(\n options.dst,\n pos,\n options.src.getPixel(options.srcX + x, options.srcY + y)\n );\n }\n }\n } else {\n for (let y = 0; y < options.srcH; ++y) {\n for (let x = 0; x < options.srcW; ++x) {\n options.dst.setPixel(\n options.dstX + x,\n options.dstY + y,\n options.src.getPixel(options.srcX + x, options.srcY + y)\n );\n }\n }\n }\n\n return options.dst;\n }\n\n /**\n * Returns a cropped copy of **src**.\n */\n public static copyCrop(\n src: MemoryImage,\n x: number,\n y: number,\n w: number,\n h: number\n ): MemoryImage {\n // Make sure crop rectangle is within the range of the src image.\n const _x = MathOperators.clampInt(x, 0, src.width - 1);\n const _y = MathOperators.clampInt(y, 0, src.height - 1);\n let _w = w;\n if (_x + _w > src.width) {\n _w = src.width - _x;\n }\n let _h = h;\n if (_y + _h > src.height) {\n _h = src.height - _y;\n }\n\n const dst = new MemoryImage({\n width: _w,\n height: _h,\n rgbChannelSet: src.rgbChannelSet,\n exifData: src.exifData,\n iccProfile: src.iccProfile,\n });\n\n for (let yi = 0, sy = _y; yi < _h; ++yi, ++sy) {\n for (let xi = 0, sx = _x; xi < _w; ++xi, ++sx) {\n dst.setPixel(xi, yi, src.getPixel(sx, sy));\n }\n }\n\n return dst;\n }\n\n /**\n * Returns a round cropped copy of **src**.\n */\n public static copyCropCircle(\n src: MemoryImage,\n radius?: number,\n center?: Point\n ): MemoryImage {\n const defaultRadius = Math.trunc(Math.min(src.width, src.height) / 2);\n const c =\n center ??\n new Point(Math.trunc(src.width / 2), Math.trunc(src.height / 2));\n let r = radius ?? defaultRadius;\n\n // Make sure center point is within the range of the src image\n c.move(\n MathOperators.clampInt(c.x, 0, src.width - 1),\n MathOperators.clampInt(c.y, 0, src.height - 1)\n );\n r = r < 1 ? defaultRadius : r;\n\n // topLeft.x\n const tlx = Math.trunc(c.x) - r;\n // topLeft.y\n const tly = Math.trunc(c.y) - r;\n\n const dst = new MemoryImage({\n width: r * 2,\n height: r * 2,\n iccProfile: src.iccProfile,\n });\n\n for (let yi = 0, sy = tly; yi < r * 2; ++yi, ++sy) {\n for (let xi = 0, sx = tlx; xi < r * 2; ++xi, ++sx) {\n if ((xi - r) * (xi - r) + (yi - r) * (yi - r) <= r * r) {\n dst.setPixel(xi, yi, src.getPixelSafe(sx, sy));\n }\n }\n }\n\n return dst;\n }\n\n /**\n * Returns a copy of the **src** image, where the given rectangle\n * has been mapped to the full image.\n */\n public static copyRectify(\n src: MemoryImage,\n rect: Rectangle,\n toImage?: MemoryImage\n ): MemoryImage {\n const dst = toImage ?? MemoryImage.from(src);\n for (let y = 0; y < dst.height; ++y) {\n const v = y / (dst.height - 1);\n for (let x = 0; x < dst.width; ++x) {\n const u = x / (dst.width - 1);\n // bilinear interpolation\n const srcPixelCoord = new Point(rect.left, rect.top)\n .mul(1 - u)\n .mul(1 - v)\n .add(new Point(rect.right, rect.top).mul(u).mul(1 - v))\n .add(new Point(rect.left, rect.bottom).mul(1 - u).mul(v))\n .add(new Point(rect.right, rect.bottom).mul(u).mul(v));\n const srcPixel = src.getPixel(srcPixelCoord.xt, srcPixelCoord.yt);\n dst.setPixel(x, y, srcPixel);\n }\n }\n return dst;\n }\n\n /**\n * Flips the **src** image using the given **mode**, which can be one of:\n * **FlipDirection.horizontal**, **FlipDirection.vertical**, or **FlipDirection.both**.\n */\n public static flip(src: MemoryImage, direction: FlipDirection): MemoryImage {\n switch (direction) {\n case FlipDirection.horizontal:\n ImageTransform.flipHorizontal(src);\n break;\n case FlipDirection.vertical:\n ImageTransform.flipVertical(src);\n break;\n case FlipDirection.both:\n ImageTransform.flipVertical(src);\n ImageTransform.flipHorizontal(src);\n break;\n }\n return src;\n }\n\n /**\n * Flip the **src** image vertically.\n */\n public static flipVertical(src: MemoryImage): MemoryImage {\n const w = src.width;\n const h = src.height;\n const h2 = Math.floor(h / 2);\n for (let y = 0; y < h2; ++y) {\n const y1 = y * w;\n const y2 = (h - 1 - y) * w;\n for (let x = 0; x < w; ++x) {\n const t = src.getPixelByIndex(y2 + x);\n src.setPixelByIndex(y2 + x, src.getPixelByIndex(y1 + x));\n src.setPixelByIndex(y1 + x, t);\n }\n }\n return src;\n }\n\n /**\n * Flip the src image horizontally.\n */\n public static flipHorizontal(src: MemoryImage): MemoryImage {\n const w = src.width;\n const h = src.height;\n const w2 = Math.floor(src.width / 2);\n for (let y = 0; y < h; ++y) {\n const y1 = y * w;\n for (let x = 0; x < w2; ++x) {\n const x2 = w - 1 - x;\n const t = src.getPixelByIndex(y1 + x2);\n src.setPixelByIndex(y1 + x2, src.getPixelByIndex(y1 + x));\n src.setPixelByIndex(y1 + x, t);\n }\n }\n return src;\n }\n}\n", "/** @format */\n\nimport { Color } from '../../common/color';\n\nexport interface GifColorMapInitOptions {\n numColors: number;\n bitsPerPixel?: number;\n colors?: Uint8Array;\n transparent?: number;\n}\n\nexport class GifColorMap {\n private readonly _colors: Uint8Array;\n public get colors(): Uint8Array {\n return this._colors;\n }\n\n private readonly _numColors: number;\n public get numColors(): number {\n return this._numColors;\n }\n\n private readonly _bitsPerPixel: number;\n public get bitsPerPixel(): number {\n return this._bitsPerPixel;\n }\n\n private _transparent?: number;\n public set transparent(v: number | undefined) {\n this._transparent = v;\n }\n public get transparent(): number | undefined {\n return this._transparent;\n }\n\n constructor(options: GifColorMapInitOptions) {\n this._numColors = options.numColors;\n this._bitsPerPixel =\n options.bitsPerPixel ?? GifColorMap.bitSize(options.numColors);\n this._colors = options.colors ?? new Uint8Array(options.numColors * 3);\n this._transparent = options.transparent;\n }\n\n private static bitSize(n: number): number {\n for (let i = 1; i <= 8; i++) {\n if (1 << i >= n) {\n return i;\n }\n }\n return 0;\n }\n\n public static from(other: GifColorMap) {\n return new GifColorMap({\n numColors: other.numColors,\n bitsPerPixel: other.bitsPerPixel,\n colors: other.colors,\n transparent: other.transparent,\n });\n }\n\n public getByte(index: number): number {\n return this._colors[index];\n }\n\n public setByte(index: number, value: number): number {\n return (this._colors[index] = value);\n }\n\n public getColor(index: number): number {\n const ci = index * 3;\n const a = index === this._transparent ? 0 : 255;\n return Color.getColor(\n this._colors[ci],\n this._colors[ci + 1],\n this._colors[ci + 2],\n a\n );\n }\n\n public setColor(index: number, r: number, g: number, b: number): void {\n const ci = index * 3;\n this._colors[ci] = r;\n this._colors[ci + 1] = g;\n this._colors[ci + 2] = b;\n }\n\n public getRed(color: number): number {\n return this._colors[color * 3];\n }\n\n public getGreen(color: number): number {\n return this._colors[color * 3 + 1];\n }\n\n public getBlue(color: number): number {\n return this._colors[color * 3 + 2];\n }\n\n public getAlpha(color: number): number {\n return color === this._transparent ? 0 : 255;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { GifColorMap } from './gif-color-map';\n\nexport class GifImageDesc {\n private readonly _x: number;\n public get x(): number {\n return this._x;\n }\n\n private readonly _y: number;\n public get y(): number {\n return this._y;\n }\n\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _interlaced: boolean;\n public get interlaced(): boolean {\n return this._interlaced;\n }\n\n private _colorMap?: GifColorMap;\n public get colorMap(): GifColorMap | undefined {\n return this._colorMap;\n }\n public set colorMap(v: GifColorMap | undefined) {\n this._colorMap = v;\n }\n\n private _duration = 80;\n public set duration(v: number) {\n this._duration = v;\n }\n public get duration(): number {\n return this._duration;\n }\n\n private _clearFrame = true;\n public set clearFrame(v: boolean) {\n this._clearFrame = v;\n }\n public get clearFrame(): boolean {\n return this._clearFrame;\n }\n\n /**\n * The position in the file after the ImageDesc for this frame.\n */\n protected _inputPosition: number;\n public get inputPosition(): number {\n return this._inputPosition;\n }\n\n constructor(input: InputBuffer) {\n this._x = input.readUint16();\n this._y = input.readUint16();\n this._width = input.readUint16();\n this._height = input.readUint16();\n\n const b = input.readByte();\n const bitsPerPixel = (b & 0x07) + 1;\n\n this._interlaced = (b & 0x40) !== 0;\n\n if ((b & 0x80) !== 0) {\n this._colorMap = new GifColorMap({\n numColors: 1 << bitsPerPixel,\n });\n for (let i = 0; i < this._colorMap.numColors; ++i) {\n this._colorMap.setColor(\n i,\n input.readByte(),\n input.readByte(),\n input.readByte()\n );\n }\n }\n\n this._inputPosition = input.position;\n }\n}\n", "/** @format */\n\nimport { DecodeInfo } from '../decode-info';\nimport { GifColorMap } from './gif-color-map';\nimport { GifImageDesc } from './gif-image-desc';\n\nexport interface GifInfoInitOptions {\n width?: number;\n height?: number;\n backgroundColor?: number;\n frames?: Array;\n colorResolution?: number;\n globalColorMap?: GifColorMap;\n isGif89?: boolean;\n}\n\nexport class GifInfo implements DecodeInfo {\n private _width;\n public get width(): number {\n return this._width;\n }\n\n private _height;\n public get height(): number {\n return this._height;\n }\n\n private _backgroundColor;\n public get backgroundColor(): number {\n return this._backgroundColor;\n }\n\n private _frames: Array;\n public get frames(): Array {\n return this._frames;\n }\n\n private _colorResolution;\n public get colorResolution(): number {\n return this._colorResolution;\n }\n\n private _globalColorMap?: GifColorMap;\n public get globalColorMap(): GifColorMap | undefined {\n return this._globalColorMap;\n }\n\n private _isGif89 = false;\n public get isGif89(): boolean {\n return this._isGif89;\n }\n\n public get numFrames(): number {\n return this.frames.length;\n }\n\n constructor(options?: GifInfoInitOptions) {\n this._width = options?.width ?? 0;\n this._height = options?.height ?? 0;\n this._backgroundColor = options?.backgroundColor ?? 0xffffffff;\n this._frames = options?.frames ?? new Array();\n this._colorResolution = options?.colorResolution ?? 0;\n this._globalColorMap = options?.globalColorMap;\n this._isGif89 = options?.isGif89 ?? false;\n }\n}\n", "/** @format */\n\nimport { FrameAnimation } from '../common/frame-animation';\nimport { InputBuffer } from '../common/input-buffer';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MemoryImage } from '../common/memory-image';\nimport { ImageError } from '../error/image-error';\nimport { HdrImage } from '../hdr/hdr-image';\nimport { ImageTransform } from '../transform/image-transform';\nimport { Decoder } from './decoder';\nimport { GifColorMap } from './gif/gif-color-map';\nimport { GifImageDesc } from './gif/gif-image-desc';\nimport { GifInfo } from './gif/gif-info';\n\n/**\n * A decoder for the GIF image format. This supports both single frame and\n * animated GIF files, and transparency.\n */\nexport class GifDecoder implements Decoder {\n private static readonly STAMP_SIZE: number = 6;\n\n private static readonly GIF87_STAMP: string = 'GIF87a';\n\n private static readonly GIF89_STAMP: string = 'GIF89a';\n\n private static readonly IMAGE_DESC_RECORD_TYPE: number = 0x2c;\n\n private static readonly EXTENSION_RECORD_TYPE: number = 0x21;\n\n private static readonly TERMINATE_RECORD_TYPE: number = 0x3b;\n\n private static readonly GRAPHIC_CONTROL_EXT: number = 0xf9;\n\n private static readonly APPLICATION_EXT: number = 0xff;\n\n private static readonly LZ_MAX_CODE: number = 4095;\n\n private static readonly LZ_BITS: number = 12;\n\n // Impossible code, to signal empty.\n private static readonly NO_SUCH_CODE: number = 4098;\n\n private static readonly CODE_MASKS: number[] = [\n 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,\n 0x01ff, 0x03ff, 0x07ff, 0x0fff,\n ];\n\n private static readonly INTERLACED_OFFSET: number[] = [0, 4, 2, 1];\n\n private static readonly INTERLACED_JUMP: number[] = [8, 8, 4, 2];\n\n private info?: GifInfo;\n\n private input?: InputBuffer;\n\n private repeat = 0;\n\n private buffer?: Uint8Array;\n\n private stack!: Uint8Array;\n\n private suffix!: Uint8Array;\n\n private prefix?: Uint32Array;\n\n private bitsPerPixel = 0;\n\n private pixelCount?: number;\n\n private currentShiftDWord = 0;\n\n private currentShiftState = 0;\n\n private stackPtr = 0;\n\n private currentCode?: number;\n\n private lastCode = 0;\n\n private maxCode1 = 0;\n\n private runningBits = 0;\n\n private runningCode = 0;\n\n private eofCode = 0;\n\n private clearCode = 0;\n\n /**\n * How many frames are available to decode?\n *\n * You should have prepared the decoder by either passing the file bytes\n * to the constructor, or calling getInfo.\n */\n public get numFrames(): number {\n return this.info !== undefined ? this.info.numFrames : 0;\n }\n\n constructor(bytes?: Uint8Array) {\n if (bytes !== undefined) {\n this.startDecode(bytes);\n }\n }\n\n /**\n * Routine to trace the Prefixes linked list until we get a prefix which is\n * not code, but a pixel value (less than ClearCode). Returns that pixel value.\n * If image is defective, we might loop here forever, so we limit the loops to\n * the maximum possible if image O.k. - LZ_MAX_CODE times.\n */\n private static getPrefixChar(\n prefix: Uint32Array,\n code: number,\n clearCode: number\n ): number {\n let c = code;\n let i = 0;\n while (c > clearCode && i++ <= GifDecoder.LZ_MAX_CODE) {\n if (c > GifDecoder.LZ_MAX_CODE) {\n return GifDecoder.NO_SUCH_CODE;\n }\n c = prefix[code];\n }\n return c;\n }\n\n private static updateImage(\n image: MemoryImage,\n y: number,\n colorMap: GifColorMap | undefined,\n line: Uint8Array\n ): void {\n if (colorMap !== undefined) {\n for (let x = 0, width = line.length; x < width; ++x) {\n image.setPixel(x, y, colorMap.getColor(line[x]));\n }\n }\n }\n\n private getInfo(): boolean {\n if (this.input === undefined) {\n return false;\n }\n\n const tag = this.input.readString(GifDecoder.STAMP_SIZE);\n if (tag !== GifDecoder.GIF87_STAMP && tag !== GifDecoder.GIF89_STAMP) {\n return false;\n }\n\n const width = this.input.readUint16();\n const height = this.input.readUint16();\n\n const b = this.input.readByte();\n const colorResolution = (((b & 0x70) + 1) >> 4) + 1;\n\n const bitsPerPixel = (b & 0x07) + 1;\n const backgroundColor = this.input.readByte();\n\n this.input.skip(1);\n\n let globalColorMap: GifColorMap | undefined = undefined;\n // Is there a global color map?\n if ((b & 0x80) !== 0) {\n globalColorMap = new GifColorMap({\n numColors: 1 << bitsPerPixel,\n });\n\n // Get the global color map:\n for (let i = 0; i < globalColorMap.numColors; ++i) {\n const r = this.input.readByte();\n const g = this.input.readByte();\n const b = this.input.readByte();\n globalColorMap.setColor(i, r, g, b);\n }\n }\n\n const isGif89 = tag === GifDecoder.GIF89_STAMP;\n\n this.info = new GifInfo({\n width: width,\n height: height,\n colorResolution: colorResolution,\n backgroundColor: backgroundColor,\n globalColorMap: globalColorMap,\n isGif89: isGif89,\n });\n\n return true;\n }\n\n private skipImage(): GifImageDesc | undefined {\n if (this.input === undefined || this.input.isEOS) {\n return undefined;\n }\n const gifImage = new GifImageDesc(this.input);\n this.input.skip(1);\n this.skipRemainder();\n return gifImage;\n }\n\n /**\n * Continue to get the image code in compressed form. This routine should be\n * called until NULL block is returned.\n * The block should NOT be freed by the user (not dynamically allocated).\n */\n private skipRemainder(): boolean {\n if (this.input === undefined || this.input.isEOS) {\n return true;\n }\n let b = this.input.readByte();\n while (b !== 0 && !this.input.isEOS) {\n this.input.skip(b);\n if (this.input.isEOS) {\n return true;\n }\n b = this.input.readByte();\n }\n return true;\n }\n\n private readApplicationExt(input: InputBuffer): void {\n const blockSize = input.readByte();\n const tag = input.readString(blockSize);\n if (tag === 'NETSCAPE2.0') {\n const b1 = input.readByte();\n const b2 = input.readByte();\n if (b1 === 0x03 && b2 === 0x01) {\n this.repeat = input.readUint16();\n }\n } else {\n this.skipRemainder();\n }\n }\n\n private readGraphicsControlExt(input: InputBuffer): void {\n /* const blockSize: number = */\n input.readByte();\n const b = input.readByte();\n const duration = input.readUint16();\n const transparent = input.readByte();\n /* const endBlock: number = */\n input.readByte();\n const disposalMethod = (b >> 2) & 0x7;\n // const userInput: number = (b >> 1) & 0x1;\n const transparentFlag = b & 0x1;\n\n const recordType = input.peekBytes(1).getByte(0);\n if (recordType === GifDecoder.IMAGE_DESC_RECORD_TYPE) {\n input.skip(1);\n const gifImage = this.skipImage();\n if (gifImage === undefined) {\n return;\n }\n\n gifImage.duration = duration;\n gifImage.clearFrame = disposalMethod === 2;\n\n if (transparentFlag !== 0) {\n if (\n gifImage.colorMap === undefined &&\n this.info!.globalColorMap !== undefined\n ) {\n gifImage.colorMap = GifColorMap.from(this.info!.globalColorMap);\n }\n if (gifImage.colorMap !== undefined) {\n gifImage.colorMap.transparent = transparent;\n }\n }\n\n this.info!.frames.push(gifImage);\n }\n }\n\n private decodeFrameImage(gifImage: GifImageDesc): MemoryImage | undefined {\n if (this.buffer === undefined) {\n this.initDecode();\n }\n\n this.bitsPerPixel = this.input!.readByte();\n this.clearCode = 1 << this.bitsPerPixel;\n this.eofCode = this.clearCode + 1;\n this.runningCode = this.eofCode + 1;\n this.runningBits = this.bitsPerPixel + 1;\n this.maxCode1 = 1 << this.runningBits;\n this.stackPtr = 0;\n this.lastCode = GifDecoder.NO_SUCH_CODE;\n this.currentShiftState = 0;\n this.currentShiftDWord = 0;\n this.buffer![0] = 0;\n this.prefix!.fill(GifDecoder.NO_SUCH_CODE, 0, this.prefix!.length);\n\n const width = gifImage.width;\n const height = gifImage.height;\n\n if (\n gifImage.x + width > this.info!.width ||\n gifImage.y + height > this.info!.height\n ) {\n return undefined;\n }\n\n const colorMap =\n gifImage.colorMap !== undefined\n ? gifImage.colorMap\n : this.info!.globalColorMap;\n\n this.pixelCount = width * height;\n\n const image = new MemoryImage({\n width: width,\n height: height,\n });\n const line = new Uint8Array(width);\n\n if (gifImage.interlaced) {\n const row = gifImage.y;\n for (let i = 0, j = 0; i < 4; ++i) {\n for (\n let y = row + GifDecoder.INTERLACED_OFFSET[i];\n y < row + height;\n y += GifDecoder.INTERLACED_JUMP[i], ++j\n ) {\n if (!this.getLine(line)) {\n return image;\n }\n GifDecoder.updateImage(image, y, colorMap, line);\n }\n }\n } else {\n for (let y = 0; y < height; ++y) {\n if (!this.getLine(line)) {\n return image;\n }\n GifDecoder.updateImage(image, y, colorMap, line);\n }\n }\n return image;\n }\n\n private getLine(line: Uint8Array): boolean {\n this.pixelCount = this.pixelCount! - line.length;\n\n if (!this.decompressLine(line)) {\n return false;\n }\n\n // Flush any remainder blocks.\n if (this.pixelCount === 0) {\n this.skipRemainder();\n }\n\n return true;\n }\n\n /**\n * The LZ decompression routine:\n * This version decompress the given gif file into Line of length LineLen.\n * This routine can be called few times (one per scan line, for example), in\n * order the complete the whole image.\n */\n private decompressLine(line: Uint8Array): boolean {\n if (this.stackPtr > GifDecoder.LZ_MAX_CODE) {\n return false;\n }\n\n const lineLen = line.length;\n let i = 0;\n\n if (this.stackPtr !== 0) {\n // Let pop the stack off before continuing to read the gif file:\n while (this.stackPtr !== 0 && i < lineLen) {\n line[i++] = this.stack[--this.stackPtr];\n }\n }\n\n let currentPrefix: number | undefined = undefined;\n\n // Decode LineLen items.\n while (i < lineLen) {\n this.currentCode = this.decompressInput();\n if (this.currentCode === undefined) {\n return false;\n }\n\n if (this.currentCode === this.eofCode) {\n // Note however that usually we will not be here as we will stop\n // decoding as soon as we got all the pixel, or EOF code will\n // not be read at all, and DGifGetLine/Pixel clean everything.\n return false;\n }\n\n if (this.currentCode === this.clearCode) {\n // We need to start over again:\n for (let j = 0; j <= GifDecoder.LZ_MAX_CODE; j++) {\n this.prefix![j] = GifDecoder.NO_SUCH_CODE;\n }\n\n this.runningCode = this.eofCode + 1;\n this.runningBits = this.bitsPerPixel + 1;\n this.maxCode1 = 1 << this.runningBits;\n this.lastCode = GifDecoder.NO_SUCH_CODE;\n } else {\n // Its regular code - if in pixel range simply add it to output\n // stream, otherwise trace to codes linked list until the prefix\n // is in pixel range:\n if (this.currentCode < this.clearCode) {\n // This is simple - its pixel scalar, so add it to output:\n line[i++] = this.currentCode;\n } else {\n // Its a code to needed to be traced: trace the linked list\n // until the prefix is a pixel, while pushing the suffix\n // pixels on our stack. If we done, pop the stack in reverse\n // (thats what stack is good for!) order to output. */\n if (this.prefix![this.currentCode] === GifDecoder.NO_SUCH_CODE) {\n // Only allowed if CrntCode is exactly the running code:\n // In that case CrntCode = XXXCode, CrntCode or the\n // prefix code is last code and the suffix char is\n // exactly the prefix of last code!\n if (this.currentCode === this.runningCode - 2) {\n currentPrefix = this.lastCode;\n const prefixChar = GifDecoder.getPrefixChar(\n this.prefix!,\n this.lastCode,\n this.clearCode\n );\n this.stack[this.stackPtr++] = prefixChar;\n this.suffix[this.runningCode - 2] = prefixChar;\n } else {\n return false;\n }\n } else {\n currentPrefix = this.currentCode;\n }\n\n // Now (if image is O.K.) we should not get an NO_SUCH_CODE\n // During the trace. As we might loop forever, in case of\n // defective image, we count the number of loops we trace\n // and stop if we got LZ_MAX_CODE. obviously we can not\n // loop more than that.\n let j = 0;\n while (\n j++ <= GifDecoder.LZ_MAX_CODE &&\n currentPrefix > this.clearCode &&\n currentPrefix <= GifDecoder.LZ_MAX_CODE\n ) {\n this.stack[this.stackPtr++] = this.suffix[currentPrefix];\n currentPrefix = this.prefix![currentPrefix];\n }\n\n if (\n j >= GifDecoder.LZ_MAX_CODE ||\n currentPrefix > GifDecoder.LZ_MAX_CODE\n ) {\n return false;\n }\n\n // Push the last character on stack:\n this.stack[this.stackPtr++] = currentPrefix;\n\n // Now lets pop all the stack into output:\n while (this.stackPtr !== 0 && i < lineLen) {\n line[i++] = this.stack[--this.stackPtr];\n }\n }\n\n if (\n this.lastCode !== GifDecoder.NO_SUCH_CODE &&\n this.prefix![this.runningCode - 2] === GifDecoder.NO_SUCH_CODE\n ) {\n this.prefix![this.runningCode - 2] = this.lastCode;\n\n if (this.currentCode === this.runningCode - 2) {\n // Only allowed if CrntCode is exactly the running code:\n // In that case CrntCode = XXXCode, CrntCode or the\n // prefix code is last code and the suffix char is\n // exactly the prefix of last code!\n this.suffix[this.runningCode - 2] = GifDecoder.getPrefixChar(\n this.prefix!,\n this.lastCode,\n this.clearCode\n );\n } else {\n this.suffix[this.runningCode - 2] = GifDecoder.getPrefixChar(\n this.prefix!,\n this.currentCode,\n this.clearCode\n );\n }\n }\n\n this.lastCode = this.currentCode;\n }\n }\n\n return true;\n }\n\n /**\n * The LZ decompression input routine:\n * This routine is responsible for the decompression of the bit stream from\n * 8 bits (bytes) packets, into the real codes.\n */\n private decompressInput(): number | undefined {\n // The image can't contain more than LZ_BITS per code.\n if (this.runningBits > GifDecoder.LZ_BITS) {\n return undefined;\n }\n\n while (this.currentShiftState < this.runningBits) {\n // Needs to get more bytes from input stream for next code:\n const nextByte = this.bufferedInput()!;\n\n this.currentShiftDWord |= nextByte << this.currentShiftState;\n this.currentShiftState += 8;\n }\n\n const code: number =\n this.currentShiftDWord & GifDecoder.CODE_MASKS[this.runningBits];\n\n this.currentShiftDWord >>= this.runningBits;\n this.currentShiftState -= this.runningBits;\n\n // If code cannot fit into RunningBits bits, must raise its size. Note\n // however that codes above 4095 are used for special signaling.\n // If we're using LZ_BITS bits already and we're at the max code, just\n // keep using the table as it is, don't increment Private->RunningCode.\n if (\n this.runningCode < GifDecoder.LZ_MAX_CODE + 2 &&\n ++this.runningCode > this.maxCode1 &&\n this.runningBits < GifDecoder.LZ_BITS\n ) {\n this.maxCode1 <<= 1;\n this.runningBits++;\n }\n\n return code;\n }\n\n /**\n * This routines read one gif data block at a time and buffers it internally\n * so that the decompression routine could access it.\n * The routine returns the next byte from its internal buffer (or read next\n * block in if buffer empty) and returns undefined on failure.\n */\n private bufferedInput(): number | undefined {\n let nextByte = 0;\n if (this.buffer![0] === 0) {\n // Needs to read the next buffer - this one is empty:\n this.buffer![0] = this.input!.readByte();\n\n // There shouldn't be any empty data blocks here as the LZW spec\n // says the LZW termination code should come first. Therefore we\n // shouldn't be inside this routine at that point.\n if (this.buffer![0] === 0) {\n return undefined;\n }\n\n const from = this.input!.readBytes(this.buffer![0]).toUint8Array();\n ArrayUtils.setRange(this.buffer!, 1, 1 + this.buffer![0], from);\n\n nextByte = this.buffer![1];\n // We use now the second place as last char read!\n this.buffer![1] = 2;\n this.buffer![0]--;\n } else {\n nextByte = this.buffer![this.buffer![1]++];\n this.buffer![0]--;\n }\n\n return nextByte;\n }\n\n private initDecode(): void {\n this.buffer = new Uint8Array(256);\n this.stack = new Uint8Array(GifDecoder.LZ_MAX_CODE);\n this.suffix = new Uint8Array(GifDecoder.LZ_MAX_CODE + 1);\n this.prefix = new Uint32Array(GifDecoder.LZ_MAX_CODE + 1);\n }\n\n /**\n * Is the given file a valid Gif image?\n */\n public isValidFile(bytes: Uint8Array): boolean {\n this.input = new InputBuffer({\n buffer: bytes,\n });\n return this.getInfo();\n }\n\n /**\n * Validate the file is a Gif image and get information about it.\n * If the file is not a valid Gif image, undefined is returned.\n */\n public startDecode(bytes: Uint8Array): GifInfo | undefined {\n this.input = new InputBuffer({\n buffer: bytes,\n });\n\n if (!this.getInfo()) {\n return undefined;\n }\n\n try {\n while (!this.input.isEOS) {\n const recordType = this.input.readByte();\n switch (recordType) {\n case GifDecoder.IMAGE_DESC_RECORD_TYPE: {\n const gifImage = this.skipImage();\n if (gifImage === undefined) {\n return this.info;\n }\n this.info!.frames.push(gifImage);\n break;\n }\n case GifDecoder.EXTENSION_RECORD_TYPE: {\n const extCode = this.input.readByte();\n if (extCode === GifDecoder.APPLICATION_EXT) {\n this.readApplicationExt(this.input);\n } else if (extCode === GifDecoder.GRAPHIC_CONTROL_EXT) {\n this.readGraphicsControlExt(this.input);\n } else {\n this.skipRemainder();\n }\n break;\n }\n case GifDecoder.TERMINATE_RECORD_TYPE: {\n // this._numFrames = info.numFrames;\n return this.info;\n }\n default:\n break;\n }\n }\n } catch (error) {\n const strError = JSON.stringify(error);\n throw new ImageError(strError);\n }\n\n // this._numFrames = info.numFrames;\n return this.info;\n }\n\n public decodeFrame(frame: number): MemoryImage | undefined {\n if (this.input === undefined || this.info === undefined) {\n return undefined;\n }\n\n if (frame >= this.info.frames.length || frame < 0) {\n return undefined;\n }\n\n // this._frame = frame;\n const gifImage = this.info.frames[frame];\n this.input.offset = gifImage.inputPosition;\n\n return this.decodeFrameImage(this.info.frames[frame]);\n }\n\n public decodeHdrFrame(frame: number): HdrImage | undefined {\n const img = this.decodeFrame(frame);\n if (img === undefined) {\n return undefined;\n }\n return HdrImage.fromImage(img);\n }\n\n /**\n * Decode all of the frames of an animated gif. For single image gifs,\n * this will return an animation with a single frame.\n */\n public decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined {\n if (this.startDecode(bytes) === undefined) {\n return undefined;\n }\n\n if (this.input === undefined || this.info === undefined) {\n return undefined;\n }\n\n const animation = new FrameAnimation({\n width: this.info.width,\n height: this.info.height,\n loopCount: this.repeat,\n });\n\n let lastImage: MemoryImage | undefined = undefined;\n\n for (let i = 0; i < this.info.numFrames; ++i) {\n const frame = this.info.frames[i];\n const image = this.decodeFrame(i);\n if (image === undefined) {\n return undefined;\n }\n\n if (lastImage === undefined) {\n lastImage = image;\n // Convert to MS\n lastImage.duration = frame.duration * 10;\n animation.addFrame(lastImage);\n continue;\n }\n\n if (\n image.width === lastImage.width &&\n image.height === lastImage.height &&\n frame.x === 0 &&\n frame.y === 0 &&\n frame.clearFrame\n ) {\n lastImage = image;\n // Convert to MS\n lastImage.duration = frame.duration * 10;\n animation.addFrame(lastImage);\n continue;\n }\n\n if (frame.clearFrame) {\n lastImage = new MemoryImage({\n width: lastImage.width,\n height: lastImage.height,\n });\n const colorMap =\n frame.colorMap !== undefined\n ? frame.colorMap\n : this.info!.globalColorMap;\n lastImage.fill(colorMap!.getColor(this.info!.backgroundColor));\n } else {\n lastImage = MemoryImage.from(lastImage);\n }\n\n ImageTransform.copyInto({\n dst: lastImage,\n src: image,\n dstX: frame.x,\n dstY: frame.y,\n });\n\n // Convert 1/100 sec to ms.\n lastImage.duration = frame.duration * 10;\n\n animation.addFrame(lastImage);\n }\n\n return animation;\n }\n\n public decodeImage(bytes: Uint8Array, frame = 0): MemoryImage | undefined {\n if (this.startDecode(bytes) === undefined) {\n return undefined;\n }\n // this._frame = 0;\n // this._numFrames = 1;\n return this.decodeFrame(frame);\n }\n\n public decodeHdrImage(bytes: Uint8Array, frame = 0): HdrImage | undefined {\n const img = this.decodeImage(bytes, frame);\n if (img === undefined) {\n return undefined;\n }\n return HdrImage.fromImage(img);\n }\n}\n", "/** @format */\n\nimport { DitherKernel } from '../common/dither-kernel';\nimport { DitherPixel } from '../common/dither-pixel';\nimport { FrameAnimation } from '../common/frame-animation';\nimport { MemoryImage } from '../common/memory-image';\nimport { NeuralQuantizer } from '../common/neural-quantizer';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { TextCodec } from '../common/text-codec';\nimport { Encoder } from './encoder';\n\nexport interface GifEncoderInitOptions {\n delay?: number;\n repeat?: number;\n samplingFactor?: number;\n dither?: DitherKernel;\n ditherSerpentine?: boolean;\n}\n\nexport class GifEncoder implements Encoder {\n private static readonly gif89Id = 'GIF89a';\n\n private static readonly imageDescRecordType = 0x2c;\n\n private static readonly extensionRecordType = 0x21;\n\n private static readonly terminateRecordType = 0x3b;\n\n private static readonly applicationExt = 0xff;\n\n private static readonly graphicControlExt = 0xf9;\n\n private static readonly eof = -1;\n\n private static readonly bits = 12;\n\n // 80% occupancy\n private static readonly hsize = 5003;\n\n private static readonly masks = [\n 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,\n 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff,\n ];\n\n private lastImage?: Uint8Array;\n\n private lastImageDuration?: number;\n\n private lastColorMap?: NeuralQuantizer;\n\n private width!: number;\n\n private height!: number;\n\n private encodedFrames: number;\n\n private curAccum = 0;\n\n private curBits = 0;\n\n private nBits = 0;\n\n private initBits = 0;\n\n private EOFCode = 0;\n\n private maxCode = 0;\n\n private clearCode = 0;\n\n private freeEnt = 0;\n\n private clearFlag = false;\n\n private block!: Uint8Array;\n\n private blockSize = 0;\n\n private outputBuffer?: OutputBuffer;\n\n private delay: number;\n\n private repeat: number;\n\n private samplingFactor: number;\n\n private dither: DitherKernel;\n\n private ditherSerpentine: boolean;\n\n /**\n * Does this encoder support animation?\n */\n private readonly _supportsAnimation = true;\n get supportsAnimation(): boolean {\n return this._supportsAnimation;\n }\n\n constructor(options?: GifEncoderInitOptions) {\n this.delay = options?.delay ?? 80;\n this.repeat = options?.repeat ?? 0;\n this.samplingFactor = options?.samplingFactor ?? 10;\n this.dither = options?.dither ?? DitherKernel.FloydSteinberg;\n this.ditherSerpentine = options?.ditherSerpentine ?? false;\n this.encodedFrames = 0;\n }\n\n private addImage(\n image: Uint8Array | undefined,\n width: number,\n height: number,\n colorMap: Uint8Array,\n numColors: number\n ): void {\n // Image desc\n this.outputBuffer!.writeByte(GifEncoder.imageDescRecordType);\n // Image position x,y = 0,0\n this.outputBuffer!.writeUint16(0);\n this.outputBuffer!.writeUint16(0);\n // Image size\n this.outputBuffer!.writeUint16(width);\n this.outputBuffer!.writeUint16(height);\n\n // Local Color Map\n // (0x80: Use LCM, 0x07: Palette Size (7 = 8-bit))\n this.outputBuffer!.writeByte(0x87);\n this.outputBuffer!.writeBytes(colorMap);\n for (let i = numColors; i < 256; ++i) {\n this.outputBuffer!.writeByte(0);\n this.outputBuffer!.writeByte(0);\n this.outputBuffer!.writeByte(0);\n }\n\n this.encodeLZW(image, width, height);\n }\n\n private encodeLZW(\n image: Uint8Array | undefined,\n width: number,\n height: number\n ): void {\n this.curAccum = 0;\n this.curBits = 0;\n this.blockSize = 0;\n this.block = new Uint8Array(256);\n\n const initCodeSize = 8;\n this.outputBuffer!.writeByte(initCodeSize);\n\n const hTab = new Int32Array(GifEncoder.hsize);\n const codeTab = new Int32Array(GifEncoder.hsize);\n let remaining = width * height;\n let curPixel = 0;\n\n this.initBits = initCodeSize + 1;\n this.nBits = this.initBits;\n this.maxCode = (1 << this.nBits) - 1;\n this.clearCode = 1 << (this.initBits - 1);\n this.EOFCode = this.clearCode + 1;\n this.clearFlag = false;\n this.freeEnt = this.clearCode + 2;\n\n const _nextPixel = () => {\n if (remaining === 0) {\n return GifEncoder.eof;\n }\n --remaining;\n return image![curPixel++] & 0xff;\n };\n\n let ent = _nextPixel();\n\n let hshift = 0;\n for (let fcode = GifEncoder.hsize; fcode < 65536; fcode *= 2) {\n hshift++;\n }\n hshift = 8 - hshift;\n\n const hSizeReg = GifEncoder.hsize;\n for (let i = 0; i < hSizeReg; ++i) {\n hTab[i] = -1;\n }\n\n this.output(this.clearCode);\n\n let outerLoop = true;\n while (outerLoop) {\n outerLoop = false;\n\n let c = _nextPixel();\n while (c !== GifEncoder.eof) {\n const fcode = (c << GifEncoder.bits) + ent;\n // XOR hashing\n let i = (c << hshift) ^ ent;\n\n if (hTab[i] === fcode) {\n ent = codeTab[i];\n c = _nextPixel();\n continue;\n } else if (hTab[i] >= 0) {\n // Non-empty slot\n // Secondary hash (after G. Knott)\n let disp = hSizeReg - i;\n if (i === 0) {\n disp = 1;\n }\n do {\n if ((i -= disp) < 0) {\n i += hSizeReg;\n }\n\n if (hTab[i] === fcode) {\n ent = codeTab[i];\n outerLoop = true;\n break;\n }\n } while (hTab[i] >= 0);\n if (outerLoop) {\n break;\n }\n }\n\n this.output(ent);\n ent = c;\n\n if (this.freeEnt < 1 << GifEncoder.bits) {\n // Code -> hashtable\n codeTab[i] = this.freeEnt++;\n hTab[i] = fcode;\n } else {\n for (let i = 0; i < GifEncoder.hsize; ++i) {\n hTab[i] = -1;\n }\n this.freeEnt = this.clearCode + 2;\n this.clearFlag = true;\n this.output(this.clearCode);\n }\n\n c = _nextPixel();\n }\n }\n\n this.output(ent);\n this.output(this.EOFCode);\n\n this.outputBuffer!.writeByte(0);\n }\n\n private output(code: number | undefined): void {\n this.curAccum &= GifEncoder.masks[this.curBits];\n\n if (this.curBits > 0) {\n this.curAccum |= code! << this.curBits;\n } else {\n this.curAccum = code!;\n }\n\n this.curBits += this.nBits;\n\n while (this.curBits >= 8) {\n this.addToBlock(this.curAccum & 0xff);\n this.curAccum >>= 8;\n this.curBits -= 8;\n }\n\n // If the next entry is going to be too big for the code size,\n // then increase it, if possible.\n if (this.freeEnt > this.maxCode || this.clearFlag) {\n if (this.clearFlag) {\n this.nBits = this.initBits;\n this.maxCode = (1 << this.nBits) - 1;\n this.clearFlag = false;\n } else {\n ++this.nBits;\n if (this.nBits === GifEncoder.bits) {\n this.maxCode = 1 << GifEncoder.bits;\n } else {\n this.maxCode = (1 << this.nBits) - 1;\n }\n }\n }\n\n if (code === this.EOFCode) {\n // At EOF, write the rest of the buffer.\n while (this.curBits > 0) {\n this.addToBlock(this.curAccum & 0xff);\n this.curAccum >>= 8;\n this.curBits -= 8;\n }\n this.writeBlock();\n }\n }\n\n private writeBlock(): void {\n if (this.blockSize > 0) {\n this.outputBuffer!.writeByte(this.blockSize);\n this.outputBuffer!.writeBytes(this.block, this.blockSize);\n this.blockSize = 0;\n }\n }\n\n private addToBlock(c: number): void {\n this.block[this.blockSize++] = c;\n if (this.blockSize >= 254) {\n this.writeBlock();\n }\n }\n\n private writeApplicationExt(): void {\n this.outputBuffer!.writeByte(GifEncoder.extensionRecordType);\n this.outputBuffer!.writeByte(GifEncoder.applicationExt);\n // Data block size\n this.outputBuffer!.writeByte(11);\n const appCodeUnits = TextCodec.getCodePoints('NETSCAPE2.0');\n // App identifier\n this.outputBuffer!.writeBytes(appCodeUnits);\n this.outputBuffer!.writeBytes(new Uint8Array([0x03, 0x01]));\n // Loop count\n this.outputBuffer!.writeUint16(this.repeat);\n // Block terminator\n this.outputBuffer!.writeByte(0);\n }\n\n private writeGraphicsCtrlExt(): void {\n this.outputBuffer!.writeByte(GifEncoder.extensionRecordType);\n this.outputBuffer!.writeByte(GifEncoder.graphicControlExt);\n // Data block size\n this.outputBuffer!.writeByte(4);\n\n const transparency = 0;\n // Dispose = no action\n const dispose = 0;\n\n // packed fields\n this.outputBuffer!.writeByte(0 | dispose | 0 | transparency);\n\n // Delay x 1/100 sec\n this.outputBuffer!.writeUint16(this.lastImageDuration ?? this.delay);\n // Transparent color index\n this.outputBuffer!.writeByte(0);\n // Block terminator\n this.outputBuffer!.writeByte(0);\n }\n\n // GIF header and Logical Screen Descriptor\n private writeHeader(width: number, height: number): void {\n const idCodeUnits = TextCodec.getCodePoints(GifEncoder.gif89Id);\n this.outputBuffer!.writeBytes(idCodeUnits);\n this.outputBuffer!.writeUint16(width);\n this.outputBuffer!.writeUint16(height);\n // global color map parameters (not being used).\n this.outputBuffer!.writeByte(0);\n // Background color index.\n this.outputBuffer!.writeByte(0);\n // Aspect\n this.outputBuffer!.writeByte(0);\n }\n\n /**\n * Encode the images that were added with **addFrame**.\n * After this has been called (returning the finishes GIF),\n * calling **addFrame** for a new animation or image is safe again.\n *\n * **addFrame** will not encode the first image passed and after that\n * always encode the previous image. Hence, the last image needs to be\n * encoded here.\n */\n private finish(): Uint8Array | undefined {\n let bytes: Uint8Array | undefined = undefined;\n if (this.outputBuffer === undefined) {\n return bytes;\n }\n\n if (this.encodedFrames === 0) {\n this.writeHeader(this.width, this.height);\n this.writeApplicationExt();\n } else {\n this.writeGraphicsCtrlExt();\n }\n\n this.addImage(\n this.lastImage,\n this.width,\n this.height,\n this.lastColorMap!.colorMap8,\n 256\n );\n\n this.outputBuffer.writeByte(GifEncoder.terminateRecordType);\n\n this.lastImage = undefined;\n this.lastColorMap = undefined;\n this.encodedFrames = 0;\n\n bytes = this.outputBuffer.getBytes();\n this.outputBuffer = undefined;\n return bytes;\n }\n\n /**\n * This adds the frame passed to **image**.\n * After the last frame has been added, **finish** is required to be called.\n * Optional frame **duration** is in 1/100 sec.\n * */\n public addFrame(image: MemoryImage, duration?: number): void {\n if (this.outputBuffer === undefined) {\n this.outputBuffer = new OutputBuffer();\n\n this.lastColorMap = new NeuralQuantizer(image, 256, this.samplingFactor);\n this.lastImage = DitherPixel.getDitherPixels(\n image,\n this.lastColorMap,\n this.dither,\n this.ditherSerpentine\n );\n this.lastImageDuration = duration;\n\n this.width = image.width;\n this.height = image.height;\n return;\n }\n\n if (this.encodedFrames === 0) {\n this.writeHeader(this.width, this.height);\n this.writeApplicationExt();\n }\n\n this.writeGraphicsCtrlExt();\n\n this.addImage(\n this.lastImage,\n this.width,\n this.height,\n this.lastColorMap!.colorMap8,\n 256\n );\n this.encodedFrames++;\n\n this.lastColorMap = new NeuralQuantizer(image, 256, this.samplingFactor);\n this.lastImage = DitherPixel.getDitherPixels(\n image,\n this.lastColorMap,\n this.dither,\n this.ditherSerpentine\n );\n this.lastImageDuration = duration;\n }\n\n /**\n * Encode a single frame image.\n */\n public encodeImage(image: MemoryImage): Uint8Array {\n this.addFrame(image);\n return this.finish()!;\n }\n\n /**\n * Encode an animation.\n */\n public encodeAnimation(animation: FrameAnimation): Uint8Array | undefined {\n this.repeat = animation.loopCount;\n for (const f of animation) {\n this.addFrame(\n f,\n // Convert ms to 1 / 100 sec.\n Math.floor(f.duration / 10)\n );\n }\n return this.finish();\n }\n}\n", "/** @format */\n\nimport { BmpInfo } from '../bmp/bmp-info';\n\nexport class IcoBmpInfo extends BmpInfo {\n public get height(): number {\n return Math.floor(this._height / 2);\n }\n\n public get ignoreAlphaChannel(): boolean {\n return this.headerSize === 40 && this.bpp === 32\n ? false\n : super.ignoreAlphaChannel;\n }\n}\n", "/** @format */\n\nexport class IcoInfoImage {\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _colorPalette: number;\n public get colorPalette(): number {\n return this._colorPalette;\n }\n\n private readonly _bytesSize: number;\n public get bytesSize(): number {\n return this._bytesSize;\n }\n\n private readonly _bytesOffset: number;\n public get bytesOffset(): number {\n return this._bytesOffset;\n }\n\n private readonly _colorPlanes: number;\n public get colorPlanes(): number {\n return this._colorPlanes;\n }\n\n private readonly _bitsPerPixel: number;\n public get bitsPerPixel(): number {\n return this._bitsPerPixel;\n }\n\n constructor(\n width: number,\n height: number,\n colorPalette: number,\n bytesSize: number,\n bytesOffset: number,\n colorPlanes: number,\n bitsPerPixel: number\n ) {\n this._width = width;\n this._height = height;\n this._colorPalette = colorPalette;\n this._bytesSize = bytesSize;\n this._bytesOffset = bytesOffset;\n this._colorPlanes = colorPlanes;\n this._bitsPerPixel = bitsPerPixel;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { DecodeInfo } from '../decode-info';\nimport { IcoInfoImage } from './ico-info-image';\n\nconst TYPE_ICO = 1;\nconst TYPE_CUR = 2;\n\nexport class IcoInfo implements DecodeInfo {\n private readonly _type?: number;\n public get type(): number | undefined {\n return this._type;\n }\n\n private readonly _images?: IcoInfoImage[];\n public get images(): IcoInfoImage[] | undefined {\n return this._images;\n }\n\n private readonly _numFrames: number;\n public get numFrames(): number {\n return this._numFrames;\n }\n\n private _width = 0;\n public get width(): number {\n return this._width;\n }\n\n private _height = 0;\n public get height(): number {\n return this._height;\n }\n\n private _backgroundColor = 0xffffffff;\n public get backgroundColor(): number {\n return this._backgroundColor;\n }\n\n constructor(numFrames: number, type?: number, images?: IcoInfoImage[]) {\n this._numFrames = numFrames;\n this._type = type;\n this._images = images;\n }\n\n public static read(input: InputBuffer): IcoInfo | undefined {\n if (input.readUint16() !== 0) {\n return undefined;\n }\n const type = input.readUint16();\n if (![TYPE_ICO, TYPE_CUR].includes(type)) {\n return undefined;\n }\n if (type === TYPE_CUR) {\n // We currently do not support CUR format.\n return undefined;\n }\n const imageCount = input.readUint16();\n const images: IcoInfoImage[] = [];\n for (let i = 0; i < imageCount; i++) {\n const width = input.readByte();\n const height = input.readByte();\n const colorPalette = input.readByte();\n input.skip(1);\n const colorPlanes = input.readUint16();\n const bitsPerPixel = input.readUint16();\n const bytesSize = input.readUint32();\n const bytesOffset = input.readUint32();\n\n const image = new IcoInfoImage(\n width,\n height,\n colorPalette,\n bytesSize,\n bytesOffset,\n colorPlanes,\n bitsPerPixel\n );\n images.push(image);\n }\n return new IcoInfo(imageCount, type, images);\n }\n}\n", "/** @format */\n\nexport interface PngFrameInitOptions {\n sequenceNumber?: number;\n width?: number;\n height?: number;\n xOffset?: number;\n yOffset?: number;\n delayNum?: number;\n delayDen?: number;\n dispose?: number;\n blend?: number;\n}\n\n// Decodes a frame from a PNG animation.\nexport class PngFrame {\n // DisposeMode\n public static readonly APNG_DISPOSE_OP_NONE = 0;\n\n public static readonly APNG_DISPOSE_OP_BACKGROUND = 1;\n\n public static readonly APNG_DISPOSE_OP_PREVIOUS = 2;\n\n // BlendMode\n public static readonly APNG_BLEND_OP_SOURCE = 0;\n\n public static readonly APNG_BLEND_OP_OVER = 1;\n\n private readonly _fdat: number[] = [];\n public get fdat(): number[] {\n return this._fdat;\n }\n\n private _sequenceNumber?: number;\n public get sequenceNumber(): number | undefined {\n return this._sequenceNumber;\n }\n\n private _width?: number;\n public get width(): number | undefined {\n return this._width;\n }\n\n private _height?: number;\n public get height(): number | undefined {\n return this._height;\n }\n\n private _xOffset?: number;\n public get xOffset(): number | undefined {\n return this._xOffset;\n }\n\n private _yOffset?: number;\n public get yOffset(): number | undefined {\n return this._yOffset;\n }\n\n private _delayNum?: number;\n public get delayNum(): number | undefined {\n return this._delayNum;\n }\n\n private _delayDen?: number;\n public get delayDen(): number | undefined {\n return this._delayDen;\n }\n\n private _dispose?: number;\n public get dispose(): number | undefined {\n return this._dispose;\n }\n\n private _blend?: number;\n public get blend(): number | undefined {\n return this._blend;\n }\n\n public get delay() {\n if (this._delayNum === undefined || this._delayDen === undefined) {\n return 0;\n }\n if (this._delayDen === 0) {\n return 0;\n }\n return this._delayNum / this._delayDen;\n }\n\n constructor(options: PngFrameInitOptions) {\n this._sequenceNumber = options?.sequenceNumber;\n this._width = options?.width;\n this._height = options?.height;\n this._xOffset = options?.xOffset;\n this._yOffset = options?.yOffset;\n this._delayNum = options?.delayNum;\n this._delayDen = options?.delayDen;\n this._dispose = options?.dispose;\n this._blend = options?.blend;\n }\n}\n", "/** @format */\n\nimport { DecodeInfo } from '../decode-info';\nimport { PngFrame } from './png-frame';\n\nexport interface PngInfoInitOptions {\n width?: number;\n height?: number;\n bits?: number;\n colorType?: number;\n compressionMethod?: number;\n filterMethod?: number;\n interlaceMethod?: number;\n}\n\nexport class PngInfo implements DecodeInfo {\n private _width = 0;\n public set width(v: number) {\n this._width = v;\n }\n public get width(): number {\n return this._width;\n }\n\n private _height = 0;\n public set height(v: number) {\n this._height = v;\n }\n public get height(): number {\n return this._height;\n }\n\n private _backgroundColor = 0x00ffffff;\n public set backgroundColor(v: number) {\n this._backgroundColor = v;\n }\n public get backgroundColor(): number {\n return this._backgroundColor;\n }\n\n private _numFrames = 1;\n public set numFrames(v: number) {\n this._numFrames = v;\n }\n public get numFrames(): number {\n return this._numFrames;\n }\n\n private _bits?: number;\n public get bits(): number | undefined {\n return this._bits;\n }\n\n private _colorType?: number;\n public get colorType(): number | undefined {\n return this._colorType;\n }\n\n private _compressionMethod?: number;\n public get compressionMethod(): number | undefined {\n return this._compressionMethod;\n }\n\n private _filterMethod?: number;\n public get filterMethod(): number | undefined {\n return this._filterMethod;\n }\n\n private _interlaceMethod?: number;\n public get interlaceMethod(): number | undefined {\n return this._interlaceMethod;\n }\n\n private _palette?: Uint8Array;\n public set palette(v: Uint8Array | undefined) {\n this._palette = v;\n }\n public get palette(): Uint8Array | undefined {\n return this._palette;\n }\n\n private _transparency?: Uint8Array;\n public set transparency(v: Uint8Array | undefined) {\n this._transparency = v;\n }\n public get transparency(): Uint8Array | undefined {\n return this._transparency;\n }\n\n private _colorLut?: number[];\n public set colorLut(v: number[] | undefined) {\n this._colorLut = v;\n }\n public get colorLut(): number[] | undefined {\n return this._colorLut;\n }\n\n private _gamma?: number;\n public set gamma(v: number | undefined) {\n this._gamma = v;\n }\n public get gamma(): number | undefined {\n return this._gamma;\n }\n\n private _iCCPName = '';\n public set iCCPName(v: string) {\n this._iCCPName = v;\n }\n public get iCCPName(): string {\n return this._iCCPName;\n }\n\n private _iCCPCompression = 0;\n public set iCCPCompression(v: number) {\n this._iCCPCompression = v;\n }\n public get iCCPCompression(): number {\n return this._iCCPCompression;\n }\n\n private _iCCPData?: Uint8Array;\n public set iCCPData(v: Uint8Array | undefined) {\n this._iCCPData = v;\n }\n public get iCCPData(): Uint8Array | undefined {\n return this._iCCPData;\n }\n\n private _textData: Map = new Map();\n public get textData(): Map {\n return this._textData;\n }\n\n private _repeat = 0;\n public set repeat(v: number) {\n this._repeat = v;\n }\n public get repeat(): number {\n return this._repeat;\n }\n\n private readonly _idat: number[] = [];\n public get idat(): number[] {\n return this._idat;\n }\n\n private readonly _frames: PngFrame[] = [];\n public get frames(): PngFrame[] {\n return this._frames;\n }\n\n public get isAnimated(): boolean {\n return this._frames.length > 0;\n }\n\n constructor(options?: PngInfoInitOptions) {\n this._width = options?.width ?? 0;\n this._height = options?.height ?? 0;\n this._bits = options?.bits;\n this._colorType = options?.colorType;\n this._compressionMethod = options?.compressionMethod;\n this._filterMethod = options?.filterMethod;\n this._interlaceMethod = options?.interlaceMethod;\n }\n}\n", "/** @format */\n\nimport { inflate } from 'uzip';\nimport { Color } from '../common/color';\nimport { Crc32 } from '../common/crc32';\nimport { FrameAnimation } from '../common/frame-animation';\nimport { ICCPCompressionMode } from '../common/iccp-compression-mode';\nimport { ICCProfileData } from '../common/icc-profile-data';\nimport { InputBuffer } from '../common/input-buffer';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MemoryImage } from '../common/memory-image';\nimport { RgbChannelSet } from '../common/rgb-channel-set';\nimport { TextCodec } from '../common/text-codec';\nimport { ImageError } from '../error/image-error';\nimport { NotImplementedError } from '../error/not-implemented-error';\nimport { HdrImage } from '../hdr/hdr-image';\nimport { ImageTransform } from '../transform/image-transform';\nimport { DecodeInfo } from './decode-info';\nimport { Decoder } from './decoder';\nimport { PngFrame } from './png/png-frame';\nimport { PngInfo } from './png/png-info';\n\n/**\n * Decode a PNG encoded image.\n */\nexport class PngDecoder implements Decoder {\n private static readonly GRAYSCALE = 0;\n\n private static readonly RGB = 2;\n\n private static readonly INDEXED = 3;\n\n private static readonly GRAYSCALE_ALPHA = 4;\n\n private static readonly RGBA = 6;\n\n private static readonly FILTER_NONE = 0;\n\n private static readonly FILTER_SUB = 1;\n\n private static readonly FILTER_UP = 2;\n\n private static readonly FILTER_AVERAGE = 3;\n\n private static readonly FILTER_PAETH = 4;\n\n private _info?: PngInfo;\n public get info(): PngInfo | undefined {\n return this._info;\n }\n\n private _input?: InputBuffer;\n public get input(): InputBuffer | undefined {\n return this._input;\n }\n\n private _progressY = 0;\n public get progressY(): number {\n return this._progressY;\n }\n\n private _bitBuffer = 0;\n public get bitBuffer(): number {\n return this._bitBuffer;\n }\n\n private _bitBufferLen = 0;\n public get bitBufferLen(): number {\n return this._bitBufferLen;\n }\n\n /**\n * The number of frames that can be decoded.\n */\n public get numFrames(): number {\n return this._info !== undefined ? this._info.numFrames : 0;\n }\n\n private static unfilter(\n filterType: number,\n bpp: number,\n row: Uint8Array,\n prevRow: Uint8Array\n ): void {\n const rowBytes = row.length;\n\n switch (filterType) {\n case PngDecoder.FILTER_NONE:\n break;\n case PngDecoder.FILTER_SUB:\n for (let x = bpp; x < rowBytes; ++x) {\n row[x] = (row[x] + row[x - bpp]) & 0xff;\n }\n break;\n case PngDecoder.FILTER_UP:\n for (let x = 0; x < rowBytes; ++x) {\n row[x] = (row[x] + prevRow[x]) & 0xff;\n }\n break;\n case PngDecoder.FILTER_AVERAGE:\n for (let x = 0; x < rowBytes; ++x) {\n const a = x < bpp ? 0 : row[x - bpp];\n const b = prevRow[x];\n row[x] = (row[x] + ((a + b) >> 1)) & 0xff;\n }\n break;\n case PngDecoder.FILTER_PAETH:\n for (let x = 0; x < rowBytes; ++x) {\n const a = x < bpp ? 0 : row[x - bpp];\n const b = prevRow[x];\n const c = x < bpp ? 0 : prevRow[x - bpp];\n\n const p = a + b - c;\n\n const pa = Math.abs(p - a);\n const pb = Math.abs(p - b);\n const pc = Math.abs(p - c);\n\n let paeth = 0;\n if (pa <= pb && pa <= pc) {\n paeth = a;\n } else if (pb <= pc) {\n paeth = b;\n } else {\n paeth = c;\n }\n\n row[x] = (row[x] + paeth) & 0xff;\n }\n break;\n default:\n throw new ImageError(`Invalid filter value: ${filterType}`);\n }\n }\n\n private static convert16to8(c: number): number {\n return c >> 8;\n }\n\n private static convert1to8(c: number): number {\n return c === 0 ? 0 : 255;\n }\n\n private static convert2to8(c: number): number {\n return c * 85;\n }\n\n private static convert4to8(c: number): number {\n return c << 4;\n }\n\n /**\n * Return the CRC of the bytes\n */\n private static crc(type: string, bytes: Uint8Array): number {\n const typeCodeUnits = TextCodec.getCodePoints(type);\n const crc = Crc32.getChecksum({\n buffer: typeCodeUnits,\n });\n return Crc32.getChecksum({\n buffer: bytes,\n baseCrc: crc,\n });\n }\n\n /**\n * Process a pass of an interlaced image.\n */\n private processPass(\n input: InputBuffer,\n image: MemoryImage,\n xOffset: number,\n yOffset: number,\n xStep: number,\n yStep: number,\n passWidth: number,\n passHeight: number\n ): void {\n let channels = 1;\n if (this._info!.colorType === PngDecoder.GRAYSCALE_ALPHA) {\n channels = 2;\n } else if (this._info!.colorType === PngDecoder.RGB) {\n channels = 3;\n } else if (this._info!.colorType === PngDecoder.RGBA) {\n channels = 4;\n }\n\n const pixelDepth = channels * this._info!.bits!;\n const bpp = (pixelDepth + 7) >> 3;\n const rowBytes = (pixelDepth * passWidth + 7) >> 3;\n\n const line = new Uint8Array(rowBytes);\n const inData = [line, line];\n\n const pixel = [0, 0, 0, 0];\n\n // Let pi: number = 0;\n for (\n let srcY = 0, dstY = yOffset, ri = 0;\n srcY < passHeight;\n ++srcY, dstY += yStep, ri = 1 - ri, this._progressY++\n ) {\n const filterType = input.readByte();\n inData[ri] = input.readBytes(rowBytes).toUint8Array();\n\n const row = inData[ri];\n const prevRow = inData[1 - ri];\n\n // Before the image is compressed, it was filtered to improve compression.\n // Reverse the filter now.\n PngDecoder.unfilter(filterType, bpp, row, prevRow);\n\n // Scanlines are always on byte boundaries, so for bit depths < 8,\n // reset the bit stream counter.\n this.resetBits();\n\n const rowInput = new InputBuffer({\n buffer: row,\n bigEndian: true,\n });\n\n const blockHeight = xStep;\n const blockWidth = xStep - xOffset;\n\n // Let yMax: number = Math.min(dstY + blockHeight, _info.height);\n\n for (\n let srcX = 0, dstX = xOffset;\n srcX < passWidth;\n ++srcX, dstX += xStep\n ) {\n this.readPixel(rowInput, pixel);\n const c = this.getColor(pixel);\n image.setPixel(dstX, dstY, c);\n\n if (blockWidth > 1 || blockHeight > 1) {\n // Let xMax: number = Math.min(dstX + blockWidth, _info.width);\n // let xPixels: number = xMax - dstX;\n for (let i = 0; i < blockHeight; ++i) {\n for (let j = 0; j < blockWidth; ++j) {\n image.setPixelSafe(dstX + j, dstY + j, c);\n }\n }\n }\n }\n }\n }\n\n private process(input: InputBuffer, image: MemoryImage): void {\n let channels = 1;\n if (this._info!.colorType === PngDecoder.GRAYSCALE_ALPHA) {\n channels = 2;\n } else if (this._info!.colorType === PngDecoder.RGB) {\n channels = 3;\n } else if (this._info!.colorType === PngDecoder.RGBA) {\n channels = 4;\n }\n\n const pixelDepth = channels * this._info!.bits!;\n\n const w = this._info!.width;\n const h = this._info!.height;\n\n const rowBytes = (w * pixelDepth + 7) >> 3;\n const bpp = (pixelDepth + 7) >> 3;\n\n const line = new Uint8Array(rowBytes);\n const inData = [line, line];\n\n const pixel = [0, 0, 0, 0];\n\n for (let y = 0, pi = 0, ri = 0; y < h; ++y, ri = 1 - ri) {\n const filterType = input.readByte();\n inData[ri] = input.readBytes(rowBytes).toUint8Array();\n\n const row = inData[ri];\n const prevRow = inData[1 - ri];\n\n // Before the image is compressed, it was filtered to improve compression.\n // Reverse the filter now.\n PngDecoder.unfilter(filterType, bpp, row, prevRow);\n\n // Scanlines are always on byte boundaries, so for bit depths < 8,\n // reset the bit stream counter.\n this.resetBits();\n\n const rowInput = new InputBuffer({\n buffer: inData[ri],\n bigEndian: true,\n });\n\n for (let x = 0; x < w; ++x) {\n this.readPixel(rowInput, pixel);\n image.setPixelByIndex(pi++, this.getColor(pixel));\n }\n }\n }\n\n private resetBits(): void {\n this._bitBuffer = 0;\n this._bitBufferLen = 0;\n }\n\n /**\n * Read a number of bits from the input stream.\n */\n private readBits(input: InputBuffer, numBits: number): number {\n if (numBits === 0) {\n return 0;\n }\n\n if (numBits === 8) {\n return input.readByte();\n }\n\n if (numBits === 16) {\n return input.readUint16();\n }\n\n // Not enough buffer\n while (this._bitBufferLen < numBits) {\n if (input.isEOS) {\n throw new ImageError('Invalid PNG data.');\n }\n\n // Input byte\n const octet = input.readByte();\n\n // Concat octet\n this._bitBuffer = octet << this._bitBufferLen;\n this._bitBufferLen += 8;\n }\n\n // Output byte\n let mask = 0;\n switch (numBits) {\n case 1:\n mask = 1;\n break;\n case 2:\n mask = 3;\n break;\n case 4:\n mask = 0xf;\n break;\n case 8:\n mask = 0xff;\n break;\n case 16:\n mask = 0xffff;\n break;\n default:\n mask = 0;\n break;\n }\n\n const octet = (this._bitBuffer >> (this._bitBufferLen - numBits)) & mask;\n\n this._bitBufferLen -= numBits;\n\n return octet;\n }\n\n /**\n * Read the next pixel from the input stream.\n */\n private readPixel(input: InputBuffer, pixel: number[]): void {\n switch (this._info!.colorType) {\n case PngDecoder.GRAYSCALE:\n pixel[0] = this.readBits(input, this._info!.bits!);\n return;\n case PngDecoder.RGB:\n pixel[0] = this.readBits(input, this._info!.bits!);\n pixel[1] = this.readBits(input, this._info!.bits!);\n pixel[2] = this.readBits(input, this._info!.bits!);\n return;\n case PngDecoder.INDEXED:\n pixel[0] = this.readBits(input, this._info!.bits!);\n return;\n case PngDecoder.GRAYSCALE_ALPHA:\n pixel[0] = this.readBits(input, this._info!.bits!);\n pixel[1] = this.readBits(input, this._info!.bits!);\n return;\n case PngDecoder.RGBA:\n pixel[0] = this.readBits(input, this._info!.bits!);\n pixel[1] = this.readBits(input, this._info!.bits!);\n pixel[2] = this.readBits(input, this._info!.bits!);\n pixel[3] = this.readBits(input, this._info!.bits!);\n return;\n }\n throw new NotImplementedError(\n `Invalid color type: ${this._info!.colorType}.`\n );\n }\n\n /**\n * Get the color with the list of components.\n */\n private getColor(raw: number[]): number {\n switch (this._info!.colorType) {\n case PngDecoder.GRAYSCALE: {\n let g = 0;\n switch (this._info!.bits) {\n case 1:\n g = PngDecoder.convert1to8(raw[0]);\n break;\n case 2:\n g = PngDecoder.convert2to8(raw[0]);\n break;\n case 4:\n g = PngDecoder.convert4to8(raw[0]);\n break;\n case 8:\n g = raw[0];\n break;\n case 16:\n g = PngDecoder.convert16to8(raw[0]);\n break;\n }\n\n g = this._info!.colorLut![g];\n\n if (this._info!.transparency !== undefined) {\n const a =\n ((this._info!.transparency[0] & 0xff) << 24) |\n (this._info!.transparency[1] & 0xff);\n if (raw[0] === a) {\n return Color.getColor(g, g, g, 0);\n }\n }\n\n return Color.getColor(g, g, g);\n }\n case PngDecoder.RGB: {\n let r = 0;\n let g = 0;\n let b = 0;\n switch (this._info!.bits) {\n case 1:\n r = PngDecoder.convert1to8(raw[0]);\n g = PngDecoder.convert1to8(raw[1]);\n b = PngDecoder.convert1to8(raw[2]);\n break;\n case 2:\n r = PngDecoder.convert2to8(raw[0]);\n g = PngDecoder.convert2to8(raw[1]);\n b = PngDecoder.convert2to8(raw[2]);\n break;\n case 4:\n r = PngDecoder.convert4to8(raw[0]);\n g = PngDecoder.convert4to8(raw[1]);\n b = PngDecoder.convert4to8(raw[2]);\n break;\n case 8:\n r = raw[0];\n g = raw[1];\n b = raw[2];\n break;\n case 16:\n r = PngDecoder.convert16to8(raw[0]);\n g = PngDecoder.convert16to8(raw[1]);\n b = PngDecoder.convert16to8(raw[2]);\n break;\n }\n\n r = this._info!.colorLut![r]!;\n g = this._info!.colorLut![g]!;\n b = this._info!.colorLut![b]!;\n\n if (this._info!.transparency !== undefined) {\n const tr =\n ((this._info!.transparency[0] & 0xff) << 8) |\n (this._info!.transparency[1] & 0xff);\n const tg =\n ((this._info!.transparency[2] & 0xff) << 8) |\n (this._info!.transparency[3] & 0xff);\n const tb =\n ((this._info!.transparency[4] & 0xff) << 8) |\n (this._info!.transparency[5] & 0xff);\n if (raw[0] === tr && raw[1] === tg && raw[2] === tb) {\n return Color.getColor(r, g, b, 0);\n }\n }\n\n return Color.getColor(r, g, b);\n }\n case PngDecoder.INDEXED: {\n const p = raw[0] * 3;\n\n const a =\n this._info!.transparency !== undefined &&\n raw[0] < this._info!.transparency.length\n ? this._info!.transparency[raw[0]]\n : 255;\n\n if (p >= this._info!.palette!.length) {\n return Color.getColor(255, 255, 255, a);\n }\n\n const r = this._info!.palette![p]!;\n const g = this._info!.palette![p + 1]!;\n const b = this._info!.palette![p + 2]!;\n\n return Color.getColor(r, g, b, a);\n }\n case PngDecoder.GRAYSCALE_ALPHA: {\n let g = 0;\n let a = 0;\n switch (this._info!.bits) {\n case 1:\n g = PngDecoder.convert1to8(raw[0]);\n a = PngDecoder.convert1to8(raw[1]);\n break;\n case 2:\n g = PngDecoder.convert2to8(raw[0]);\n a = PngDecoder.convert2to8(raw[1]);\n break;\n case 4:\n g = PngDecoder.convert4to8(raw[0]);\n a = PngDecoder.convert4to8(raw[1]);\n break;\n case 8:\n g = raw[0];\n a = raw[1];\n break;\n case 16:\n g = PngDecoder.convert16to8(raw[0]);\n a = PngDecoder.convert16to8(raw[1]);\n break;\n }\n\n g = this._info!.colorLut![g]!;\n\n return Color.getColor(g, g, g, a);\n }\n case PngDecoder.RGBA: {\n let r = 0;\n let g = 0;\n let b = 0;\n let a = 0;\n switch (this._info!.bits) {\n case 1:\n r = PngDecoder.convert1to8(raw[0]);\n g = PngDecoder.convert1to8(raw[1]);\n b = PngDecoder.convert1to8(raw[2]);\n a = PngDecoder.convert1to8(raw[3]);\n break;\n case 2:\n r = PngDecoder.convert2to8(raw[0]);\n g = PngDecoder.convert2to8(raw[1]);\n b = PngDecoder.convert2to8(raw[2]);\n a = PngDecoder.convert2to8(raw[3]);\n break;\n case 4:\n r = PngDecoder.convert4to8(raw[0]);\n g = PngDecoder.convert4to8(raw[1]);\n b = PngDecoder.convert4to8(raw[2]);\n a = PngDecoder.convert4to8(raw[3]);\n break;\n case 8:\n r = raw[0];\n g = raw[1];\n b = raw[2];\n a = raw[3];\n break;\n case 16:\n r = PngDecoder.convert16to8(raw[0]);\n g = PngDecoder.convert16to8(raw[1]);\n b = PngDecoder.convert16to8(raw[2]);\n a = PngDecoder.convert16to8(raw[3]);\n break;\n }\n\n r = this._info!.colorLut![r]!;\n g = this._info!.colorLut![g]!;\n b = this._info!.colorLut![b]!;\n\n return Color.getColor(r, g, b, a);\n }\n }\n\n throw new ImageError(`Invalid color type: ${this._info!.colorType}.`);\n }\n\n /**\n * Is the given file a valid PNG image?\n */\n public isValidFile(bytes: Uint8Array): boolean {\n const input = new InputBuffer({\n buffer: bytes,\n bigEndian: true,\n });\n const pngHeader = input.readBytes(8);\n const PNG_HEADER = [137, 80, 78, 71, 13, 10, 26, 10];\n for (let i = 0; i < 8; ++i) {\n if (pngHeader.getByte(i) !== PNG_HEADER[i]) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Start decoding the data as an animation sequence, but don't actually\n * process the frames until they are requested with decodeFrame.\n */\n public startDecode(bytes: Uint8Array): DecodeInfo | undefined {\n this._input = new InputBuffer({\n buffer: bytes,\n bigEndian: true,\n });\n const pngHeader = this._input.readBytes(8);\n const expectedHeader = [137, 80, 78, 71, 13, 10, 26, 10];\n for (let i = 0; i < 8; ++i) {\n if (pngHeader.getByte(i) !== expectedHeader[i]) {\n return undefined;\n }\n }\n\n while (true) {\n const inputPos = this._input.position;\n let chunkSize = this._input.readUint32();\n const chunkType = this._input.readString(4);\n switch (chunkType) {\n case 'tEXt': {\n if (this._info === undefined) {\n this._info = new PngInfo();\n }\n const txtData = this._input.readBytes(chunkSize).toUint8Array();\n for (let i = 0, l = txtData.length; i < l; ++i) {\n if (txtData[i] === 0) {\n const key = TextCodec.latin1Decoder.decode(\n ArrayUtils.copyUint8(txtData, 0, i)\n );\n const text = TextCodec.latin1Decoder.decode(\n ArrayUtils.copyUint8(txtData, i + 1)\n );\n this._info.textData.set(key, text);\n break;\n }\n }\n // CRC\n this._input.skip(4);\n break;\n }\n case 'IHDR': {\n const hdr = InputBuffer.from(this._input.readBytes(chunkSize));\n const hdrBytes: Uint8Array = hdr.toUint8Array();\n\n const width = hdr.readUint32();\n const height = hdr.readUint32();\n const bits = hdr.readByte();\n const colorType = hdr.readByte();\n const compressionMethod = hdr.readByte();\n const filterMethod = hdr.readByte();\n const interlaceMethod = hdr.readByte();\n\n this._info = new PngInfo({\n width: width,\n height: height,\n bits: bits,\n colorType: colorType,\n compressionMethod: compressionMethod,\n filterMethod: filterMethod,\n interlaceMethod: interlaceMethod,\n });\n\n // Validate some of the info in the header to make sure we support\n // the proposed image data.\n if (\n ![\n PngDecoder.GRAYSCALE,\n PngDecoder.RGB,\n PngDecoder.INDEXED,\n PngDecoder.GRAYSCALE_ALPHA,\n PngDecoder.RGBA,\n ].includes(this._info.colorType!)\n ) {\n return undefined;\n }\n\n if (this._info.filterMethod !== 0) {\n return undefined;\n }\n\n switch (this._info.colorType) {\n case PngDecoder.GRAYSCALE:\n if (![1, 2, 4, 8, 16].includes(this._info.bits!)) {\n return undefined;\n }\n break;\n case PngDecoder.RGB:\n if (![8, 16].includes(this._info.bits!)) {\n return undefined;\n }\n break;\n case PngDecoder.INDEXED:\n if (![1, 2, 4, 8].includes(this._info.bits!)) {\n return undefined;\n }\n break;\n case PngDecoder.GRAYSCALE_ALPHA:\n if (![8, 16].includes(this._info.bits!)) {\n return undefined;\n }\n break;\n case PngDecoder.RGBA:\n if (![8, 16].includes(this._info.bits!)) {\n return undefined;\n }\n break;\n }\n\n const crc = this._input.readUint32();\n const computedCrc = PngDecoder.crc(chunkType, hdrBytes);\n if (crc !== computedCrc) {\n throw new ImageError(`Invalid ${chunkType} checksum`);\n }\n break;\n }\n case 'PLTE': {\n this._info!.palette = this._input.readBytes(chunkSize).toUint8Array();\n const crc = this._input.readUint32();\n const computedCrc = PngDecoder.crc(chunkType, this._info!.palette);\n if (crc !== computedCrc) {\n throw new ImageError(`Invalid ${chunkType} checksum`);\n }\n break;\n }\n case 'tRNS': {\n this._info!.transparency = this._input\n .readBytes(chunkSize)\n .toUint8Array();\n const crc = this._input.readUint32();\n const computedCrc = PngDecoder.crc(\n chunkType,\n this._info!.transparency\n );\n if (crc !== computedCrc) {\n throw new ImageError(`Invalid ${chunkType} checksum`);\n }\n break;\n }\n case 'IEND': {\n // End of the image\n // CRC\n this._input.skip(4);\n break;\n }\n case 'gAMA': {\n if (chunkSize !== 4) {\n throw new ImageError('Invalid gAMA chunk');\n }\n const gammaInt = this._input.readUint32();\n // CRC\n this._input.skip(4);\n // A gamma of 1.0 doesn't have any affect, so pretend we didn't get\n // a gamma in that case.\n if (gammaInt !== 100000) {\n this._info!.gamma = gammaInt / 100000.0;\n }\n break;\n }\n case 'IDAT': {\n this._info!.idat.push(inputPos);\n this._input.skip(chunkSize);\n // CRC\n this._input.skip(4);\n break;\n }\n case 'acTL': {\n // Animation control chunk\n this._info!.numFrames = this._input.readUint32();\n this._info!.repeat = this._input.readUint32();\n // CRC\n this._input.skip(4);\n break;\n }\n case 'fcTL': {\n // Frame control chunk\n const sequenceNumber = this._input.readUint32();\n const width = this._input.readUint32();\n const height = this._input.readUint32();\n const xOffset = this._input.readUint32();\n const yOffset = this._input.readUint32();\n const delayNum = this._input.readUint16();\n const delayDen = this._input.readUint16();\n const dispose = this._input.readByte();\n const blend = this._input.readByte();\n // CRC\n this._input.skip(4);\n\n const frame: PngFrame = new PngFrame({\n sequenceNumber: sequenceNumber,\n width: width,\n height: height,\n xOffset: xOffset,\n yOffset: yOffset,\n delayNum: delayNum,\n delayDen: delayDen,\n dispose: dispose,\n blend: blend,\n });\n this._info!.frames.push(frame);\n break;\n }\n case 'fdAT': {\n const sequenceNumber = this._input.readUint32();\n const frame = this._info!.frames[this._info!.frames.length - 1];\n frame.fdat.push(inputPos);\n this._input.skip(chunkSize - 4);\n // CRC\n this._input.skip(4);\n break;\n }\n case 'bKGD': {\n if (this._info!.colorType === 3) {\n const paletteIndex = this._input.readByte();\n chunkSize--;\n const p3 = paletteIndex * 3;\n const r = this._info!.palette![p3]!;\n const g = this._info!.palette![p3 + 1]!;\n const b = this._info!.palette![p3 + 2]!;\n this._info!.backgroundColor = Color.fromRgb(r, g, b);\n } else if (\n this._info!.colorType === 0 ||\n this._info!.colorType === 4\n ) {\n /* Const gray: number = */\n this._input.readUint16();\n chunkSize -= 2;\n } else if (\n this._info!.colorType === 2 ||\n this._info!.colorType === 6\n ) {\n /* Const r: number = */\n this._input.readUint16();\n /* Const g: number = */\n this._input.readUint16();\n /* Const b: number = */\n this._input.readUint16();\n chunkSize -= 24;\n }\n if (chunkSize > 0) {\n this._input.skip(chunkSize);\n }\n // CRC\n this._input.skip(4);\n break;\n }\n case 'iCCP': {\n this._info!.iCCPName = this._input.readString();\n // 0: deflate\n this._info!.iCCPCompression = this._input.readByte();\n chunkSize -= this._info!.iCCPName.length + 2;\n const profile = this._input.readBytes(chunkSize);\n this._info!.iCCPData = profile.toUint8Array();\n // CRC\n this._input.skip(4);\n break;\n }\n default: {\n this._input.skip(chunkSize);\n // CRC\n this._input.skip(4);\n break;\n }\n }\n\n if (chunkType === 'IEND') {\n break;\n }\n\n if (this._input.isEOS) {\n return undefined;\n }\n }\n\n return this._info;\n }\n\n /**\n * Decode the frame (assuming **startDecode** has already been called).\n */\n public decodeFrame(frame: number): MemoryImage | undefined {\n if (this._input === undefined || this._info === undefined) {\n return undefined;\n }\n\n let imageData: Uint8Array | undefined = undefined;\n let width: number | undefined = this._info.width;\n let height: number | undefined = this._info.height;\n\n if (!this._info.isAnimated || frame === 0) {\n let totalSize = 0;\n const dataBlocks: Uint8Array[] = new Array();\n for (let i = 0, len = this._info.idat.length; i < len; ++i) {\n this._input.offset = this._info.idat[i];\n const chunkSize = this._input.readUint32();\n const chunkType = this._input.readString(4);\n const data = this._input.readBytes(chunkSize).toUint8Array();\n totalSize += data.length;\n dataBlocks.push(data);\n const crc = this._input.readUint32();\n const computedCrc = PngDecoder.crc(chunkType, data);\n if (crc !== computedCrc) {\n throw new ImageError(`Invalid ${chunkType} checksum`);\n }\n }\n imageData = new Uint8Array(totalSize);\n let offset = 0;\n for (const data of dataBlocks) {\n imageData.set(data, offset);\n offset += data.length;\n }\n } else {\n if (frame < 0 || frame >= this._info.frames.length) {\n throw new ImageError(`Invalid Frame Number: ${frame}`);\n }\n\n const f = this._info.frames[frame];\n width = f.width;\n height = f.height;\n let totalSize = 0;\n const dataBlocks: Uint8Array[] = new Array();\n for (let i = 0; i < f.fdat.length; ++i) {\n this._input.offset = f.fdat[i];\n const chunkSize = this._input.readUint32();\n // fDat chunk header\n this._input.readString(4);\n // Sequence number\n this._input.skip(4);\n const data = this._input.readBytes(chunkSize - 4).toUint8Array();\n totalSize += data.length;\n dataBlocks.push(data);\n }\n\n imageData = new Uint8Array(totalSize);\n let offset = 0;\n for (const data of dataBlocks) {\n imageData.set(data, offset);\n offset += data.length;\n }\n }\n\n const rgbChannelSet: RgbChannelSet =\n this._info.colorType === PngDecoder.GRAYSCALE_ALPHA ||\n this._info.colorType === PngDecoder.RGBA ||\n this._info.transparency !== undefined\n ? RgbChannelSet.rgba\n : RgbChannelSet.rgb;\n\n const image = new MemoryImage({\n width: width!,\n height: height!,\n rgbChannelSet: rgbChannelSet,\n });\n\n let uncompressed: Uint8Array | undefined = undefined;\n try {\n uncompressed = inflate(imageData);\n } catch (error) {\n console.error(error);\n return undefined;\n }\n\n // Input is the decompressed data.\n const input = new InputBuffer({\n buffer: uncompressed,\n bigEndian: true,\n });\n this.resetBits();\n\n // Set up a LUT to transform colors for gamma correction.\n if (this._info.colorLut === undefined) {\n this._info.colorLut = [];\n for (let i = 0; i < 256; i++) {\n const c = i;\n this._info.colorLut.push(c);\n }\n\n // Apply the LUT to the palette, if necessary.\n if (this._info.palette !== undefined && this._info.gamma !== undefined) {\n for (let i = 0; i < this._info.palette.length; ++i) {\n this._info.palette[i] = this._info.colorLut[this._info.palette[i]];\n }\n }\n }\n\n const origW = this._info.width;\n const origH = this._info.height;\n this._info.width = width!;\n this._info.height = height!;\n\n const w = width!;\n const h = height!;\n this._progressY = 0;\n if (this._info.interlaceMethod !== 0) {\n this.processPass(input, image, 0, 0, 8, 8, (w + 7) >> 3, (h + 7) >> 3);\n this.processPass(input, image, 4, 0, 8, 8, (w + 3) >> 3, (h + 7) >> 3);\n this.processPass(input, image, 0, 4, 4, 8, (w + 3) >> 2, (h + 3) >> 3);\n this.processPass(input, image, 2, 0, 4, 4, (w + 1) >> 2, (h + 3) >> 2);\n this.processPass(input, image, 0, 2, 2, 4, (w + 1) >> 1, (h + 1) >> 2);\n this.processPass(input, image, 1, 0, 2, 2, w >> 1, (h + 1) >> 1);\n this.processPass(input, image, 0, 1, 1, 2, w, h >> 1);\n } else {\n this.process(input, image);\n }\n\n this._info.width = origW;\n this._info.height = origH;\n\n if (this._info.iCCPData !== undefined) {\n image.iccProfile = new ICCProfileData(\n this._info.iCCPName,\n ICCPCompressionMode.deflate,\n this._info.iCCPData\n );\n }\n\n if (this._info.textData.size > 0) {\n image.addTextData(this._info.textData);\n }\n\n return image;\n }\n\n public decodeHdrFrame(frame: number): HdrImage | undefined {\n const img = this.decodeFrame(frame);\n if (img === undefined) {\n return undefined;\n }\n return HdrImage.fromImage(img);\n }\n\n public decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined {\n if (this.startDecode(bytes) === undefined) {\n return undefined;\n }\n\n const animation = new FrameAnimation({\n width: this._info!.width,\n height: this._info!.height,\n });\n\n if (!this._info!.isAnimated) {\n const image = this.decodeFrame(0)!;\n animation.addFrame(image);\n return animation;\n }\n\n let lastImage: MemoryImage | undefined = undefined;\n for (let i = 0; i < this._info!.numFrames; ++i) {\n const frame = this._info!.frames[i];\n const image = this.decodeFrame(i);\n if (image === undefined) {\n continue;\n }\n\n if (lastImage === undefined) {\n lastImage = image;\n // Convert to MS\n lastImage.duration = Math.trunc(frame.delay * 1000);\n animation.addFrame(lastImage);\n continue;\n }\n\n if (\n image.width === lastImage.width &&\n image.height === lastImage.height &&\n frame.xOffset === 0 &&\n frame.yOffset === 0 &&\n frame.blend === PngFrame.APNG_BLEND_OP_SOURCE\n ) {\n lastImage = image;\n // Convert to MS\n lastImage.duration = Math.trunc(frame.delay * 1000);\n animation.addFrame(lastImage);\n continue;\n }\n\n const dispose = frame.dispose;\n if (dispose === PngFrame.APNG_DISPOSE_OP_BACKGROUND) {\n lastImage = new MemoryImage({\n width: lastImage.width,\n height: lastImage.height,\n });\n lastImage.fill(this._info!.backgroundColor);\n } else if (dispose === PngFrame.APNG_DISPOSE_OP_PREVIOUS) {\n lastImage = MemoryImage.from(lastImage);\n } else {\n lastImage = MemoryImage.from(lastImage);\n }\n\n // Convert to MS\n lastImage.duration = Math.trunc(frame.delay * 1000);\n\n ImageTransform.copyInto({\n dst: lastImage,\n src: image,\n dstX: frame.xOffset,\n dstY: frame.yOffset,\n blend: frame.blend === PngFrame.APNG_BLEND_OP_OVER,\n });\n\n animation.addFrame(lastImage);\n }\n\n return animation;\n }\n\n public decodeImage(bytes: Uint8Array, frame = 0): MemoryImage | undefined {\n if (this.startDecode(bytes) === undefined) {\n return undefined;\n }\n return this.decodeFrame(frame);\n }\n\n public decodeHdrImage(bytes: Uint8Array, frame = 0): HdrImage | undefined {\n const img = this.decodeImage(bytes, frame);\n if (img === undefined) {\n return undefined;\n }\n return HdrImage.fromImage(img);\n }\n}\n", "/** @format */\n\nimport { FrameAnimation } from '../common/frame-animation';\nimport { InputBuffer } from '../common/input-buffer';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MemoryImage } from '../common/memory-image';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { NotImplementedError } from '../error/not-implemented-error';\nimport { HdrImage } from '../hdr/hdr-image';\nimport { BitmapFileHeader } from './bmp/bitmap-file-header';\nimport { Decoder } from './decoder';\nimport { DibDecoder } from './dib-decoder';\nimport { IcoBmpInfo } from './ico/ico-bmp-info';\nimport { IcoInfo } from './ico/ico-info';\nimport { PngDecoder } from './png-decoder';\n\nexport class IcoDecoder implements Decoder {\n _input?: InputBuffer;\n _icoInfo?: IcoInfo;\n\n get numFrames(): number {\n return this._icoInfo !== undefined ? this._icoInfo.numFrames : 0;\n }\n\n public isValidFile(bytes: Uint8Array): boolean {\n this._input = new InputBuffer({\n buffer: bytes,\n });\n this._icoInfo = IcoInfo.read(this._input);\n return this._icoInfo !== undefined;\n }\n\n public startDecode(bytes: Uint8Array): IcoInfo | undefined {\n this._input = new InputBuffer({\n buffer: bytes,\n });\n this._icoInfo = IcoInfo.read(this._input);\n return this._icoInfo;\n }\n\n public decodeFrame(frame: number): MemoryImage | undefined {\n if (\n this._input === undefined ||\n this._icoInfo === undefined ||\n frame >= this._icoInfo.numFrames\n ) {\n return undefined;\n }\n const imageInfo = this._icoInfo.images![frame];\n const imageBuffer = ArrayUtils.copyUint8(\n this._input.buffer,\n this._input.start + imageInfo.bytesOffset,\n this._input.start + imageInfo.bytesOffset + imageInfo.bytesSize\n );\n\n const png = new PngDecoder();\n if (png.isValidFile(imageBuffer)) {\n return png.decodeImage(imageBuffer);\n }\n // Should be bmp.\n const dummyBmpHeader = new OutputBuffer({\n size: 14,\n });\n dummyBmpHeader.writeUint16(BitmapFileHeader.BMP_HEADER_FILETYPE);\n dummyBmpHeader.writeUint32(imageInfo.bytesSize);\n dummyBmpHeader.writeUint32(0);\n dummyBmpHeader.writeUint32(0);\n const bmpInfo = new IcoBmpInfo(\n new InputBuffer({\n buffer: imageBuffer,\n }),\n new BitmapFileHeader(\n new InputBuffer({\n buffer: dummyBmpHeader.getBytes(),\n })\n )\n );\n if (bmpInfo.headerSize !== 40 && bmpInfo.planes !== 1) {\n // Invalid header.\n return undefined;\n }\n let offset = 0;\n if (bmpInfo.totalColors === 0 && bmpInfo.bpp <= 8) {\n // 14 + ...\n offset = 40 + 4 * (1 << bmpInfo.bpp);\n } else {\n // 14 + ...\n offset = 40 + 4 * bmpInfo.totalColors;\n }\n bmpInfo.fileHeader.offset = offset;\n dummyBmpHeader.length -= 4;\n dummyBmpHeader.writeUint32(offset);\n const inp = new InputBuffer({\n buffer: imageBuffer,\n });\n const bmp = new DibDecoder(inp, bmpInfo);\n const image = bmp.decodeFrame(0);\n if (image === undefined) {\n return undefined;\n }\n if (bmpInfo.bpp >= 32) {\n return image;\n }\n const padding = 32 - (bmpInfo.width % 32);\n const rowLength = Math.floor(\n (padding === 32 ? bmpInfo.width : bmpInfo.width + padding) / 8\n );\n // AND bitmask\n for (let y = 0; y < bmpInfo.height; y++) {\n const line = bmpInfo.readBottomUp ? y : image.height - 1 - y;\n const row = inp.readBytes(rowLength);\n for (let x = 0; x < bmpInfo.width; ) {\n const b = row.readByte();\n for (let j = 7; j > -1 && x < bmpInfo.width; j--) {\n if ((b & (1 << j)) !== 0) {\n // Just set the pixel to completely transparent.\n image.setPixelRgba(x, line, 0, 0, 0, 0);\n }\n x++;\n }\n }\n }\n return image;\n }\n\n public decodeHdrFrame(frame: number): HdrImage | undefined {\n const img = this.decodeFrame(frame);\n if (img === undefined) {\n return undefined;\n }\n return HdrImage.fromImage(img);\n }\n\n public decodeAnimation(_: Uint8Array): FrameAnimation | undefined {\n throw new NotImplementedError();\n }\n\n public decodeImage(bytes: Uint8Array, frame = 0): MemoryImage | undefined {\n const info = this.startDecode(bytes);\n if (info === undefined) {\n return undefined;\n }\n return this.decodeFrame(frame);\n }\n\n public decodeHdrImage(bytes: Uint8Array, frame = 0): HdrImage | undefined {\n const img = this.decodeImage(bytes, frame);\n if (img === undefined) {\n return undefined;\n }\n return HdrImage.fromImage(img);\n }\n\n /**\n * Decodes the largest frame.\n */\n public decodeImageLargest(bytes: Uint8Array): MemoryImage | undefined {\n const info = this.startDecode(bytes);\n if (info === undefined) {\n return undefined;\n }\n let largestFrame = 0;\n let largestSize = 0;\n for (let i = 0; i < this._icoInfo!.images!.length; i++) {\n const image = this._icoInfo!.images![i];\n const size = image.width * image.height;\n if (size > largestSize) {\n largestSize = size;\n largestFrame = i;\n }\n }\n return this.decodeFrame(largestFrame);\n }\n}\n", "/** @format */\n\nimport { deflate } from 'uzip';\nimport { BlendMode } from '../common/blend-mode';\nimport { Color } from '../common/color';\nimport { Crc32 } from '../common/crc32';\nimport { DisposeMode } from '../common/dispose-mode';\nimport { FrameAnimation } from '../common/frame-animation';\nimport { ICCProfileData } from '../common/icc-profile-data';\nimport { MemoryImage } from '../common/memory-image';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { RgbChannelSet } from '../common/rgb-channel-set';\nimport { TextCodec } from '../common/text-codec';\nimport { CompressionLevel } from '../common/typings';\nimport { Encoder } from './encoder';\n\nexport interface PngEncoderInitOptions {\n filter?: number;\n level?: CompressionLevel;\n}\n\n/**\n * Encode an image to the PNG format.\n */\nexport class PngEncoder implements Encoder {\n private static readonly FILTER_NONE = 0;\n\n private static readonly FILTER_SUB = 1;\n\n private static readonly FILTER_UP = 2;\n\n private static readonly FILTER_AVERAGE = 3;\n\n private static readonly FILTER_PAETH = 4;\n\n private static readonly FILTER_AGRESSIVE = 5;\n\n private rgbChannelSet?: RgbChannelSet;\n\n private filter: number;\n\n private level: number;\n\n private repeat = 0;\n\n private xOffset = 0;\n\n private yOffset = 0;\n\n private delay?: number;\n\n private disposeMethod: DisposeMode = DisposeMode.none;\n\n private blendMethod: BlendMode = BlendMode.source;\n\n private width = 0;\n\n private height = 0;\n\n private frames = 0;\n\n private sequenceNumber = 0;\n\n private isAnimated = false;\n\n private output?: OutputBuffer;\n\n /**\n * Does this encoder support animation?\n */\n private _supportsAnimation = true;\n get supportsAnimation() {\n return this._supportsAnimation;\n }\n\n constructor(options?: PngEncoderInitOptions) {\n this.filter = options?.filter ?? PngEncoder.FILTER_PAETH;\n this.level = options?.level ?? 6;\n }\n\n /**\n * Return the CRC of the bytes\n */\n private static crc(type: string, bytes: Uint8Array): number {\n const typeCodeUnits = TextCodec.getCodePoints(type);\n const crc = Crc32.getChecksum({\n buffer: typeCodeUnits,\n });\n return Crc32.getChecksum({\n buffer: bytes,\n baseCrc: crc,\n });\n }\n\n private static writeChunk(\n out: OutputBuffer,\n type: string,\n chunk: Uint8Array\n ): void {\n out.writeUint32(chunk.length);\n const typeCodeUnits = TextCodec.getCodePoints(type);\n out.writeBytes(typeCodeUnits);\n out.writeBytes(chunk);\n const crc = PngEncoder.crc(type, chunk);\n out.writeUint32(crc);\n }\n\n private static filterSub(\n image: MemoryImage,\n oi: number,\n row: number,\n out: Uint8Array\n ): number {\n let oindex = oi;\n\n out[oindex++] = PngEncoder.FILTER_SUB;\n\n out[oindex++] = Color.getRed(image.getPixel(0, row));\n out[oindex++] = Color.getGreen(image.getPixel(0, row));\n out[oindex++] = Color.getBlue(image.getPixel(0, row));\n if (image.rgbChannelSet === RgbChannelSet.rgba) {\n out[oindex++] = Color.getAlpha(image.getPixel(0, row));\n }\n\n for (let x = 1; x < image.width; ++x) {\n const ar = Color.getRed(image.getPixel(x - 1, row));\n const ag = Color.getGreen(image.getPixel(x - 1, row));\n const ab = Color.getBlue(image.getPixel(x - 1, row));\n\n const r = Color.getRed(image.getPixel(x, row));\n const g = Color.getGreen(image.getPixel(x, row));\n const b = Color.getBlue(image.getPixel(x, row));\n\n out[oindex++] = (r - ar) & 0xff;\n out[oindex++] = (g - ag) & 0xff;\n out[oindex++] = (b - ab) & 0xff;\n if (image.rgbChannelSet === RgbChannelSet.rgba) {\n const aa = Color.getAlpha(image.getPixel(x - 1, row));\n const a = Color.getAlpha(image.getPixel(x, row));\n out[oindex++] = (a - aa) & 0xff;\n }\n }\n\n return oindex;\n }\n\n private static filterUp(\n image: MemoryImage,\n oi: number,\n row: number,\n out: Uint8Array\n ): number {\n let oindex = oi;\n\n out[oindex++] = PngEncoder.FILTER_UP;\n\n for (let x = 0; x < image.width; ++x) {\n const br = row === 0 ? 0 : Color.getRed(image.getPixel(x, row - 1));\n const bg = row === 0 ? 0 : Color.getGreen(image.getPixel(x, row - 1));\n const bb = row === 0 ? 0 : Color.getBlue(image.getPixel(x, row - 1));\n\n const xr = Color.getRed(image.getPixel(x, row));\n const xg = Color.getGreen(image.getPixel(x, row));\n const xb = Color.getBlue(image.getPixel(x, row));\n\n out[oindex++] = (xr - br) & 0xff;\n out[oindex++] = (xg - bg) & 0xff;\n out[oindex++] = (xb - bb) & 0xff;\n if (image.rgbChannelSet === RgbChannelSet.rgba) {\n const ba = row === 0 ? 0 : Color.getAlpha(image.getPixel(x, row - 1));\n const xa = Color.getAlpha(image.getPixel(x, row));\n out[oindex++] = (xa - ba) & 0xff;\n }\n }\n\n return oindex;\n }\n\n private static filterAverage(\n image: MemoryImage,\n oi: number,\n row: number,\n out: Uint8Array\n ): number {\n let oindex = oi;\n\n out[oindex++] = PngEncoder.FILTER_AVERAGE;\n\n for (let x = 0; x < image.width; ++x) {\n const ar = x === 0 ? 0 : Color.getRed(image.getPixel(x - 1, row));\n const ag = x === 0 ? 0 : Color.getGreen(image.getPixel(x - 1, row));\n const ab = x === 0 ? 0 : Color.getBlue(image.getPixel(x - 1, row));\n\n const br = row === 0 ? 0 : Color.getRed(image.getPixel(x, row - 1));\n const bg = row === 0 ? 0 : Color.getGreen(image.getPixel(x, row - 1));\n const bb = row === 0 ? 0 : Color.getBlue(image.getPixel(x, row - 1));\n\n const xr = Color.getRed(image.getPixel(x, row));\n const xg = Color.getGreen(image.getPixel(x, row));\n const xb = Color.getBlue(image.getPixel(x, row));\n\n out[oindex++] = (xr - ((ar + br) >> 1)) & 0xff;\n out[oindex++] = (xg - ((ag + bg) >> 1)) & 0xff;\n out[oindex++] = (xb - ((ab + bb) >> 1)) & 0xff;\n if (image.rgbChannelSet === RgbChannelSet.rgba) {\n const aa = x === 0 ? 0 : Color.getAlpha(image.getPixel(x - 1, row));\n const ba = row === 0 ? 0 : Color.getAlpha(image.getPixel(x, row - 1));\n const xa = Color.getAlpha(image.getPixel(x, row));\n out[oindex++] = (xa - ((aa + ba) >> 1)) & 0xff;\n }\n }\n\n return oindex;\n }\n\n private static paethPredictor(a: number, b: number, c: number): number {\n const p = a + b - c;\n const pa = p > a ? p - a : a - p;\n const pb = p > b ? p - b : b - p;\n const pc = p > c ? p - c : c - p;\n if (pa <= pb && pa <= pc) {\n return a;\n } else if (pb <= pc) {\n return b;\n }\n return c;\n }\n\n private static filterPaeth(\n image: MemoryImage,\n oi: number,\n row: number,\n out: Uint8Array\n ): number {\n let oindex = oi;\n\n out[oindex++] = PngEncoder.FILTER_PAETH;\n for (let x = 0; x < image.width; ++x) {\n const ar = x === 0 ? 0 : Color.getRed(image.getPixel(x - 1, row));\n const ag = x === 0 ? 0 : Color.getGreen(image.getPixel(x - 1, row));\n const ab = x === 0 ? 0 : Color.getBlue(image.getPixel(x - 1, row));\n\n const br = row === 0 ? 0 : Color.getRed(image.getPixel(x, row - 1));\n const bg = row === 0 ? 0 : Color.getGreen(image.getPixel(x, row - 1));\n const bb = row === 0 ? 0 : Color.getBlue(image.getPixel(x, row - 1));\n\n const cr =\n row === 0 || x === 0 ? 0 : Color.getRed(image.getPixel(x - 1, row - 1));\n const cg =\n row === 0 || x === 0\n ? 0\n : Color.getGreen(image.getPixel(x - 1, row - 1));\n const cb =\n row === 0 || x === 0\n ? 0\n : Color.getBlue(image.getPixel(x - 1, row - 1));\n\n const xr = Color.getRed(image.getPixel(x, row));\n const xg = Color.getGreen(image.getPixel(x, row));\n const xb = Color.getBlue(image.getPixel(x, row));\n\n const pr = PngEncoder.paethPredictor(ar, br, cr);\n const pg = PngEncoder.paethPredictor(ag, bg, cg);\n const pb = PngEncoder.paethPredictor(ab, bb, cb);\n\n out[oindex++] = (xr - pr) & 0xff;\n out[oindex++] = (xg - pg) & 0xff;\n out[oindex++] = (xb - pb) & 0xff;\n if (image.rgbChannelSet === RgbChannelSet.rgba) {\n const aa = x === 0 ? 0 : Color.getAlpha(image.getPixel(x - 1, row));\n const ba = row === 0 ? 0 : Color.getAlpha(image.getPixel(x, row - 1));\n const ca =\n row === 0 || x === 0\n ? 0\n : Color.getAlpha(image.getPixel(x - 1, row - 1));\n const xa = Color.getAlpha(image.getPixel(x, row));\n const pa = PngEncoder.paethPredictor(aa, ba, ca);\n out[oindex++] = (xa - pa) & 0xff;\n }\n }\n\n return oindex;\n }\n\n private static filterNone(\n image: MemoryImage,\n oi: number,\n row: number,\n out: Uint8Array\n ): number {\n let oindex = oi;\n out[oindex++] = PngEncoder.FILTER_NONE;\n for (let x = 0; x < image.width; ++x) {\n const c = image.getPixel(x, row);\n out[oindex++] = Color.getRed(c);\n out[oindex++] = Color.getGreen(c);\n out[oindex++] = Color.getBlue(c);\n if (image.rgbChannelSet === RgbChannelSet.rgba) {\n out[oindex++] = Color.getAlpha(image.getPixel(x, row));\n }\n }\n return oindex;\n }\n\n private writeHeader(width: number, height: number): void {\n // PNG file signature\n this.output!.writeBytes(\n new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])\n );\n\n // IHDR chunk\n const chunk = new OutputBuffer({\n bigEndian: true,\n });\n chunk.writeUint32(width);\n chunk.writeUint32(height);\n chunk.writeByte(8);\n chunk.writeByte(this.rgbChannelSet === RgbChannelSet.rgb ? 2 : 6);\n // Compression method\n chunk.writeByte(0);\n // Filter method\n chunk.writeByte(0);\n // Interlace method\n chunk.writeByte(0);\n PngEncoder.writeChunk(this.output!, 'IHDR', chunk.getBytes());\n }\n\n private writeICCPChunk(_?: OutputBuffer, iccp?: ICCProfileData): void {\n if (iccp === undefined) {\n return;\n }\n\n const chunk = new OutputBuffer({\n bigEndian: true,\n });\n\n // Name\n const nameCodeUnits = TextCodec.getCodePoints(iccp.name);\n chunk.writeBytes(nameCodeUnits);\n chunk.writeByte(0);\n\n // Compression\n // 0 - deflate\n chunk.writeByte(0);\n\n // profile data\n chunk.writeBytes(iccp.compressed());\n\n PngEncoder.writeChunk(this.output!, 'iCCP', chunk.getBytes());\n }\n\n private writeAnimationControlChunk(): void {\n const chunk = new OutputBuffer({\n bigEndian: true,\n });\n // Number of frames\n chunk.writeUint32(this.frames);\n // Loop count\n chunk.writeUint32(this.repeat);\n PngEncoder.writeChunk(this.output!, 'acTL', chunk.getBytes());\n }\n\n private applyFilter(image: MemoryImage, out: Uint8Array): void {\n let oi = 0;\n for (let y = 0; y < image.height; ++y) {\n switch (this.filter) {\n case PngEncoder.FILTER_SUB:\n oi = PngEncoder.filterSub(image, oi, y, out);\n break;\n case PngEncoder.FILTER_UP:\n oi = PngEncoder.filterUp(image, oi, y, out);\n break;\n case PngEncoder.FILTER_AVERAGE:\n oi = PngEncoder.filterAverage(image, oi, y, out);\n break;\n case PngEncoder.FILTER_PAETH:\n oi = PngEncoder.filterPaeth(image, oi, y, out);\n break;\n case PngEncoder.FILTER_AGRESSIVE:\n // TODO Apply all five filters and select the filter that produces\n // the smallest sum of absolute values per row.\n oi = PngEncoder.filterPaeth(image, oi, y, out);\n break;\n default:\n oi = PngEncoder.filterNone(image, oi, y, out);\n break;\n }\n }\n }\n\n private writeFrameControlChunk(): void {\n const chunk = new OutputBuffer({\n bigEndian: true,\n });\n chunk.writeUint32(this.sequenceNumber);\n chunk.writeUint32(this.width);\n chunk.writeUint32(this.height);\n chunk.writeUint32(this.xOffset);\n chunk.writeUint32(this.yOffset);\n chunk.writeUint16(this.delay!);\n // Delay denominator\n chunk.writeUint16(1000);\n chunk.writeByte(this.disposeMethod);\n chunk.writeByte(this.blendMethod);\n PngEncoder.writeChunk(this.output!, 'fcTL', chunk.getBytes());\n }\n\n private writeTextChunk(keyword: string, text: string): void {\n const chunk = new OutputBuffer({\n bigEndian: true,\n });\n const keywordBytes = TextCodec.getCodePoints(keyword);\n const textBytes = TextCodec.getCodePoints(text);\n chunk.writeBytes(keywordBytes);\n chunk.writeByte(0);\n chunk.writeBytes(textBytes);\n PngEncoder.writeChunk(this.output!, 'tEXt', chunk.getBytes());\n }\n\n public addFrame(image: MemoryImage): void {\n this.xOffset = image.xOffset;\n this.yOffset = image.xOffset;\n this.delay = image.duration;\n this.disposeMethod = image.disposeMethod;\n this.blendMethod = image.blendMethod;\n\n if (this.output === undefined) {\n this.output = new OutputBuffer({\n bigEndian: true,\n });\n\n this.rgbChannelSet = image.rgbChannelSet;\n this.width = image.width;\n this.height = image.height;\n\n this.writeHeader(this.width, this.height);\n\n this.writeICCPChunk(this.output, image.iccProfile);\n\n if (this.isAnimated) {\n this.writeAnimationControlChunk();\n }\n }\n\n // Include room for the filter bytes (1 byte per row).\n const filteredImage = new Uint8Array(\n image.width * image.height * image.numberOfChannels + image.height\n );\n\n this.applyFilter(image, filteredImage);\n\n const compressed = deflate(filteredImage, {\n level: this.level,\n });\n\n if (image.textData !== undefined) {\n for (const [key, value] of image.textData) {\n this.writeTextChunk(key, value);\n }\n }\n\n if (this.isAnimated) {\n this.writeFrameControlChunk();\n this.sequenceNumber++;\n }\n\n if (this.sequenceNumber <= 1) {\n PngEncoder.writeChunk(this.output!, 'IDAT', compressed);\n } else {\n // FdAT chunk\n const fdat = new OutputBuffer({\n bigEndian: true,\n });\n fdat.writeUint32(this.sequenceNumber);\n fdat.writeBytes(compressed);\n PngEncoder.writeChunk(this.output!, 'fdAT', fdat.getBytes());\n\n this.sequenceNumber++;\n }\n }\n\n public finish(): Uint8Array | undefined {\n let bytes: Uint8Array | undefined = undefined;\n if (this.output === undefined) {\n return bytes;\n }\n\n PngEncoder.writeChunk(this.output, 'IEND', new Uint8Array());\n\n this.sequenceNumber = 0;\n\n bytes = this.output.getBytes();\n this.output = undefined;\n return bytes;\n }\n\n /**\n * Encode a single frame image.\n */\n encodeImage(image: MemoryImage): Uint8Array {\n this.isAnimated = false;\n this.addFrame(image);\n return this.finish()!;\n }\n\n /**\n * Encode an animation.\n */\n public encodeAnimation(animation: FrameAnimation): Uint8Array | undefined {\n this.isAnimated = true;\n this.frames = animation.frames.length;\n this.repeat = animation.loopCount;\n\n for (const f of animation) {\n this.addFrame(f);\n }\n return this.finish();\n }\n}\n", "/** @format */\n\nimport { FrameAnimation } from '../common/frame-animation';\nimport { MemoryImage } from '../common/memory-image';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { ImageError } from '../error/image-error';\nimport { Encoder } from './encoder';\nimport { PngEncoder } from './png-encoder';\n\nexport abstract class WinEncoder implements Encoder {\n protected _type = 0;\n public get type(): number {\n return this._type;\n }\n\n private _supportsAnimation = false;\n get supportsAnimation(): boolean {\n return this._supportsAnimation;\n }\n\n protected colorPlanesOrXHotSpot(_index: number): number {\n return 0;\n }\n\n protected bitsPerPixelOrYHotSpot(_index: number): number {\n return 0;\n }\n\n public encodeImages(images: MemoryImage[]): Uint8Array {\n const count = images.length;\n\n const out = new OutputBuffer();\n\n // Header\n // Reserved\n out.writeUint16(0);\n // Type: ICO => 1; CUR => 2\n out.writeUint16(this.type);\n out.writeUint16(count);\n\n // File header with image directory byte size\n let offset = 6 + count * 16;\n\n const imageDatas: Uint8Array[] = [];\n\n let i = 0;\n for (const img of images) {\n if (img.width > 256 || img.height > 256) {\n throw new ImageError('ICO and CUR support only sizes until 256');\n }\n\n // Image width in pixels\n out.writeByte(img.width);\n // Image height in pixels\n out.writeByte(img.height);\n // Color count, should be 0 if more than 256 colors\n out.writeByte(0);\n // Reserved\n out.writeByte(0);\n out.writeUint16(this.colorPlanesOrXHotSpot(i));\n out.writeUint16(this.bitsPerPixelOrYHotSpot(i));\n\n // Use png instead of bmp encoded data, it's supported since Windows Vista\n const data = new PngEncoder().encodeImage(img);\n\n // Size of the image's data in bytes\n out.writeUint32(data.length);\n\n // Offset of data from the beginning of the file\n out.writeUint32(offset);\n\n // add the size of bytes to get the new begin of the next image\n offset += data.length;\n i++;\n imageDatas.push(data);\n }\n\n for (const imageData of imageDatas) {\n out.writeBytes(imageData);\n }\n\n return out.getBytes();\n }\n\n public encodeImage(image: MemoryImage): Uint8Array {\n return this.encodeImages([image]);\n }\n\n public encodeAnimation(_: FrameAnimation): Uint8Array | undefined {\n return undefined;\n }\n}\n", "/** @format */\n\nimport { WinEncoder } from './win-encoder';\n\nexport class IcoEncoder extends WinEncoder {\n protected _type = 1;\n\n protected colorPlanesOrXHotSpot(_index: number): number {\n return 0;\n }\n\n protected bitsPerPixelOrYHotSpot(_index: number): number {\n return 32;\n }\n}\n", "/** @format */\n\nexport class ComponentData {\n private _hSamples: number;\n public get hSamples(): number {\n return this._hSamples;\n }\n\n private _maxHSamples: number;\n public get maxHSamples(): number {\n return this._maxHSamples;\n }\n\n private _vSamples: number;\n public get vSamples(): number {\n return this._vSamples;\n }\n\n private _maxVSamples: number;\n public get maxVSamples(): number {\n return this._maxVSamples;\n }\n\n private _lines: Array;\n public get lines(): Array {\n return this._lines;\n }\n\n private _hScaleShift: number;\n public get hScaleShift(): number {\n return this._hScaleShift;\n }\n\n private _vScaleShift: number;\n public get vScaleShift(): number {\n return this._vScaleShift;\n }\n\n constructor(\n hSamples: number,\n maxHSamples: number,\n vSamples: number,\n maxVSamples: number,\n lines: Array\n ) {\n this._hSamples = hSamples;\n this._maxHSamples = maxHSamples;\n this._vSamples = vSamples;\n this._maxVSamples = maxVSamples;\n this._lines = lines;\n this._hScaleShift = this._hSamples === 1 && this._maxHSamples === 2 ? 1 : 0;\n this._vScaleShift = this._vSamples === 1 && this._maxVSamples === 2 ? 1 : 0;\n }\n}\n", "/** @format */\n\nexport abstract class Jpeg {\n public static readonly dctZigZag = [\n 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40,\n 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36,\n 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61,\n 54, 47, 55, 62, 63,\n // Extra entries for safety in decoder\n 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,\n ];\n\n // The basic DCT block is 8x8 samples\n public static readonly DCTSIZE = 8;\n // DCTSIZE squared; # of elements in a block\n public static readonly DCTSIZE2 = 64;\n // Quantization tables are numbered 0..3\n public static readonly NUM_QUANT_TBLS = 4;\n // Huffman tables are numbered 0..3\n public static readonly NUM_HUFF_TBLS = 4;\n // Arith-coding tables are numbered 0..15\n public static readonly NUM_ARITH_TBLS = 16;\n // JPEG limit on # of components in one scan\n public static readonly MAX_COMPS_IN_SCAN = 4;\n // JPEG limit on sampling factors\n public static readonly MAX_SAMP_FACTOR = 4;\n\n public static readonly M_SOF0 = 0xc0;\n public static readonly M_SOF1 = 0xc1;\n public static readonly M_SOF2 = 0xc2;\n public static readonly M_SOF3 = 0xc3;\n\n public static readonly M_SOF5 = 0xc5;\n public static readonly M_SOF6 = 0xc6;\n public static readonly M_SOF7 = 0xc7;\n\n public static readonly M_JPG = 0xc8;\n public static readonly M_SOF9 = 0xc9;\n public static readonly M_SOF10 = 0xca;\n public static readonly M_SOF11 = 0xcb;\n\n public static readonly M_SOF13 = 0xcd;\n public static readonly M_SOF14 = 0xce;\n public static readonly M_SOF15 = 0xcf;\n\n public static readonly M_DHT = 0xc4;\n\n public static readonly M_DAC = 0xcc;\n\n public static readonly M_RST0 = 0xd0;\n public static readonly M_RST1 = 0xd1;\n public static readonly M_RST2 = 0xd2;\n public static readonly M_RST3 = 0xd3;\n public static readonly M_RST4 = 0xd4;\n public static readonly M_RST5 = 0xd5;\n public static readonly M_RST6 = 0xd6;\n public static readonly M_RST7 = 0xd7;\n\n public static readonly M_SOI = 0xd8;\n public static readonly M_EOI = 0xd9;\n public static readonly M_SOS = 0xda;\n public static readonly M_DQT = 0xdb;\n public static readonly M_DNL = 0xdc;\n public static readonly M_DRI = 0xdd;\n public static readonly M_DHP = 0xde;\n public static readonly M_EXP = 0xdf;\n\n // JFIF, JFXX, CIFF, AVI1, Ocad\n public static readonly M_APP0 = 0xe0;\n // EXIF, ExtendedXMP, XMP, QVCI, FLIR\n public static readonly M_APP1 = 0xe1;\n // ICC_Profile, FPXR, MPF, PreviewImage\n public static readonly M_APP2 = 0xe2;\n // Meta, Stim, PreviewImage\n public static readonly M_APP3 = 0xe3;\n // Scalado, FPXR, PreviewImage\n public static readonly M_APP4 = 0xe4;\n // RMETA, PreviewImage\n public static readonly M_APP5 = 0xe5;\n // EPPIM, NITF, HP_TDHD, GoPro\n public static readonly M_APP6 = 0xe6;\n // Pentax, Qualcomm\n public static readonly M_APP7 = 0xe7;\n // SPIFF\n public static readonly M_APP8 = 0xe8;\n // MediaJukebox\n public static readonly M_APP9 = 0xe9;\n // Comment\n public static readonly M_APP10 = 0xea;\n // Jpeg-HDR\n public static readonly M_APP11 = 0xeb;\n // PictureInfo, Ducky\n public static readonly M_APP12 = 0xec;\n // Photoshop, Adobe_CM\n public static readonly M_APP13 = 0xed;\n // ADOBE\n public static readonly M_APP14 = 0xee;\n // GraphicConverter\n public static readonly M_APP15 = 0xef;\n\n public static readonly M_JPG0 = 0xf0;\n public static readonly M_JPG13 = 0xfd;\n public static readonly M_COM = 0xfe;\n\n public static readonly M_TEM = 0x01;\n\n public static readonly M_ERROR = 0x100;\n}\n", "/** @format */\n\nexport class JpegAdobe {\n private _version: number;\n public get version(): number {\n return this._version;\n }\n\n private _flags0: number;\n public get flags0(): number {\n return this._flags0;\n }\n\n private _flags1: number;\n public get flags1(): number {\n return this._flags1;\n }\n\n private _transformCode: number;\n public get transformCode(): number {\n return this._transformCode;\n }\n\n constructor(\n version: number,\n flags0: number,\n flags1: number,\n transformCode: number\n ) {\n this._version = version;\n this._flags0 = flags0;\n this._flags1 = flags1;\n this._transformCode = transformCode;\n }\n}\n", "/** @format */\n\nexport class JpegComponent {\n private readonly _quantizationTableList: Array;\n\n private readonly _quantizationIndex: number;\n\n private readonly _hSamples: number;\n public get hSamples(): number {\n return this._hSamples;\n }\n\n private readonly _vSamples: number;\n public get vSamples(): number {\n return this._vSamples;\n }\n\n private _blocks: Array> = new Array>();\n public get blocks(): Array> {\n return this._blocks;\n }\n\n private _blocksPerLine = 0;\n public get blocksPerLine(): number {\n return this._blocksPerLine;\n }\n\n private _blocksPerColumn = 0;\n public get blocksPerColumn(): number {\n return this._blocksPerColumn;\n }\n\n private _huffmanTableDC: [] = [];\n public set huffmanTableDC(v: []) {\n this._huffmanTableDC = v;\n }\n public get huffmanTableDC(): [] {\n return this._huffmanTableDC;\n }\n\n private _huffmanTableAC: [] = [];\n public set huffmanTableAC(v: []) {\n this._huffmanTableAC = v;\n }\n public get huffmanTableAC(): [] {\n return this._huffmanTableAC;\n }\n\n private _pred = 0;\n public set pred(v: number) {\n this._pred = v;\n }\n public get pred(): number {\n return this._pred;\n }\n\n public get quantizationTable(): Int16Array | undefined {\n return this._quantizationTableList[this._quantizationIndex];\n }\n\n constructor(\n hSamples: number,\n vSamples: number,\n quantizationTableList: Array,\n quantizationIndex: number\n ) {\n this._hSamples = hSamples;\n this._vSamples = vSamples;\n this._quantizationTableList = quantizationTableList;\n this._quantizationIndex = quantizationIndex;\n }\n\n public setBlocks(\n blocks: Array>,\n blocksPerLine: number,\n blocksPerColumn: number\n ) {\n this._blocks = blocks;\n this._blocksPerLine = blocksPerLine;\n this._blocksPerColumn = blocksPerColumn;\n }\n}\n", "/** @format */\n\nimport { JpegComponent } from './jpeg-component';\n\nexport class JpegFrame {\n private readonly _components: Map;\n public get components(): Map {\n return this._components;\n }\n\n private readonly _componentsOrder: Array;\n public get componentsOrder(): Array {\n return this._componentsOrder;\n }\n\n private _extended: boolean;\n public get extended(): boolean {\n return this._extended;\n }\n\n private _progressive: boolean;\n public get progressive(): boolean {\n return this._progressive;\n }\n\n private _precision: number;\n public get precision(): number {\n return this._precision;\n }\n\n private _scanLines: number;\n public get scanLines(): number {\n return this._scanLines;\n }\n\n private _samplesPerLine: number;\n public get samplesPerLine(): number {\n return this._samplesPerLine;\n }\n\n private _maxHSamples = 0;\n public get maxHSamples(): number {\n return this._maxHSamples;\n }\n\n private _maxVSamples = 0;\n public get maxVSamples(): number {\n return this._maxVSamples;\n }\n\n private _mcusPerLine = 0;\n public get mcusPerLine(): number {\n return this._mcusPerLine;\n }\n\n private _mcusPerColumn = 0;\n public get mcusPerColumn(): number {\n return this._mcusPerColumn;\n }\n\n constructor(\n components: Map,\n componentsOrder: Array,\n extended: boolean,\n progressive: boolean,\n precision: number,\n scanLines: number,\n samplesPerLine: number\n ) {\n this._components = components;\n this._componentsOrder = componentsOrder;\n this._extended = extended;\n this._progressive = progressive;\n this._precision = precision;\n this._scanLines = scanLines;\n this._samplesPerLine = samplesPerLine;\n }\n\n private static getEmptyBlocks(\n blocksPerLineForMcu: number,\n blocksPerColumnForMcu: number\n ) {\n const blocks = new Array>();\n for (let ic = 0; ic < blocksPerColumnForMcu; ic++) {\n const line = new Array(blocksPerLineForMcu);\n for (let ir = 0; ir < blocksPerLineForMcu; ir++) {\n line[ir] = new Int32Array(64);\n }\n blocks[ic] = line;\n }\n return blocks;\n }\n\n public prepare(): void {\n for (const [_, component] of this._components) {\n this._maxHSamples = Math.max(this._maxHSamples, component.hSamples);\n this._maxVSamples = Math.max(this._maxVSamples, component.vSamples);\n }\n\n this._mcusPerLine = Math.ceil(this._samplesPerLine / 8 / this._maxHSamples);\n this._mcusPerColumn = Math.ceil(this._scanLines / 8 / this._maxVSamples);\n\n for (const [_, component] of this._components) {\n const blocksPerLine = Math.ceil(\n (Math.ceil(this._samplesPerLine / 8) * component.hSamples) /\n this._maxHSamples\n );\n const blocksPerColumn = Math.ceil(\n (Math.ceil(this._scanLines / 8) * component.vSamples) / this.maxVSamples\n );\n const blocksPerLineForMcu = this._mcusPerLine * component.hSamples;\n const blocksPerColumnForMcu = this._mcusPerColumn * component.vSamples;\n const blocks = JpegFrame.getEmptyBlocks(\n blocksPerLineForMcu,\n blocksPerColumnForMcu\n );\n component.setBlocks(blocks, blocksPerLine, blocksPerColumn);\n }\n }\n}\n", "/** @format */\n\nexport class JpegHuffman {\n private readonly _children: Array = new Array();\n public get children(): Array {\n return this._children;\n }\n\n private _index = 0;\n public get index(): number {\n return this._index;\n }\n\n public incrementIndex() {\n this._index++;\n }\n}\n", "/** @format */\n\nimport { DecodeInfo } from '../decode-info';\n\nexport class JpegInfo implements DecodeInfo {\n private _width = 0;\n public get width(): number {\n return this._width;\n }\n\n private _height = 0;\n public get height(): number {\n return this._height;\n }\n\n private _backgroundColor = 0xffffffff;\n public get backgroundColor(): number {\n return this._backgroundColor;\n }\n\n private _numFrames = 1;\n public get numFrames(): number {\n return this._numFrames;\n }\n\n public setSize(width: number, height: number) {\n this._width = width;\n this._height = height;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\n\nexport class JpegJfif {\n private _thumbWidth: number;\n public get thumbWidth(): number {\n return this._thumbWidth;\n }\n\n private _thumbHeight: number;\n public get thumbHeight(): number {\n return this._thumbHeight;\n }\n\n private _majorVersion: number;\n public get majorVersion(): number {\n return this._majorVersion;\n }\n\n private _minorVersion: number;\n public get minorVersion(): number {\n return this._minorVersion;\n }\n\n private _densityUnits: number;\n public get densityUnits(): number {\n return this._densityUnits;\n }\n\n private _xDensity: number;\n public get xDensity(): number {\n return this._xDensity;\n }\n\n private _yDensity: number;\n public get yDensity(): number {\n return this._yDensity;\n }\n\n private _thumbData: InputBuffer;\n public get thumbData(): InputBuffer {\n return this._thumbData;\n }\n\n constructor(\n thumbWidth: number,\n thumbHeight: number,\n majorVersion: number,\n minorVersion: number,\n densityUnits: number,\n xDensity: number,\n yDensity: number,\n thumbData: InputBuffer\n ) {\n this._thumbWidth = thumbWidth;\n this._thumbHeight = thumbHeight;\n this._majorVersion = majorVersion;\n this._minorVersion = minorVersion;\n this._densityUnits = densityUnits;\n this._xDensity = xDensity;\n this._yDensity = yDensity;\n this._thumbData = thumbData;\n }\n}\n", "/** @format */\n\nimport { BitOperators } from '../../common/bit-operators';\nimport { Color } from '../../common/color';\nimport { MemoryImage } from '../../common/memory-image';\nimport { RgbChannelSet } from '../../common/rgb-channel-set';\nimport { ImageError } from '../../error/image-error';\nimport { ExifData } from '../../exif/exif-data';\nimport { ComponentData } from './component-data';\nimport { JpegData } from './jpeg-data';\n\nexport abstract class JpegQuantize {\n private static dctClip: Uint8Array | undefined;\n\n private static clamp8(i: number) {\n if (i < 0) {\n return 0;\n }\n if (i > 255) {\n return 255;\n }\n return i;\n }\n\n // These functions contain bit-shift operations that fail with HTML builds.\n // A conditional import is used to use a modified version for HTML builds\n // to work around this javascript bug, while keeping the native version fast.\n\n // Quantize the coefficients and apply IDCT.\n //\n // A port of poppler's IDCT method which in turn is taken from:\n // Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,\n // \"Practical Fast 1-D DCT Algorithms with 11 Multiplications\",\n // IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989, 988-991.\n public static quantizeAndInverse(\n quantizationTable: Int16Array,\n coefBlock: Int32Array,\n dataOut: Uint8Array,\n dataIn: Int32Array\n ): void {\n const p = dataIn;\n\n const dctClipOffset = 256;\n const dctClipLength = 768;\n if (JpegQuantize.dctClip === undefined) {\n JpegQuantize.dctClip = new Uint8Array(dctClipLength);\n for (let i = -256; i < 0; ++i) {\n JpegQuantize.dctClip[dctClipOffset + i] = 0;\n }\n for (let i = 0; i < 256; ++i) {\n JpegQuantize.dctClip[dctClipOffset + i] = i;\n }\n for (let i = 256; i < 512; ++i) {\n JpegQuantize.dctClip[dctClipOffset + i] = 255;\n }\n }\n\n // IDCT constants (20.12 fixed point format)\n\n // cos(pi/16)*4096\n const COS_1 = 4017;\n // sin(pi/16)*4096\n const SIN_1 = 799;\n // cos(3*pi/16)*4096\n const COS_3 = 3406;\n // sin(3*pi/16)*4096\n const SIN_3 = 2276;\n // cos(6*pi/16)*4096\n const COS_6 = 1567;\n // sin(6*pi/16)*4096\n const SIN_6 = 3784;\n // sqrt(2)*4096\n const SQRT_2 = 5793;\n // sqrt(2)/2\n const SQRT_1D2 = 2896;\n\n // De-quantize\n for (let i = 0; i < 64; i++) {\n p[i] = coefBlock[i] * quantizationTable[i];\n }\n\n // Inverse DCT on rows\n let row = 0;\n for (let i = 0; i < 8; ++i, row += 8) {\n // Check for all-zero AC coefficients\n if (\n p[1 + row] === 0 &&\n p[2 + row] === 0 &&\n p[3 + row] === 0 &&\n p[4 + row] === 0 &&\n p[5 + row] === 0 &&\n p[6 + row] === 0 &&\n p[7 + row] === 0\n ) {\n const t = BitOperators.shiftR(SQRT_2 * p[0 + row] + 512, 10);\n p[row + 0] = t;\n p[row + 1] = t;\n p[row + 2] = t;\n p[row + 3] = t;\n p[row + 4] = t;\n p[row + 5] = t;\n p[row + 6] = t;\n p[row + 7] = t;\n continue;\n }\n\n // Stage 4\n let v0 = BitOperators.shiftR(SQRT_2 * p[0 + row] + 128, 8);\n let v1 = BitOperators.shiftR(SQRT_2 * p[4 + row] + 128, 8);\n let v2 = p[2 + row];\n let v3 = p[6 + row];\n let v4 = BitOperators.shiftR(\n SQRT_1D2 * (p[1 + row] - p[7 + row]) + 128,\n 8\n );\n let v7 = BitOperators.shiftR(\n SQRT_1D2 * (p[1 + row] + p[7 + row]) + 128,\n 8\n );\n let v5 = BitOperators.shiftL(p[3 + row], 4);\n let v6 = BitOperators.shiftL(p[5 + row], 4);\n\n // Stage 3\n let t = BitOperators.shiftR(v0 - v1 + 1, 1);\n v0 = BitOperators.shiftR(v0 + v1 + 1, 1);\n v1 = t;\n t = BitOperators.shiftR(v2 * SIN_6 + v3 * COS_6 + 128, 8);\n v2 = BitOperators.shiftR(v2 * COS_6 - v3 * SIN_6 + 128, 8);\n v3 = t;\n t = BitOperators.shiftR(v4 - v6 + 1, 1);\n v4 = BitOperators.shiftR(v4 + v6 + 1, 1);\n v6 = t;\n t = BitOperators.shiftR(v7 + v5 + 1, 1);\n v5 = BitOperators.shiftR(v7 - v5 + 1, 1);\n v7 = t;\n\n // Stage 2\n t = BitOperators.shiftR(v0 - v3 + 1, 1);\n v0 = BitOperators.shiftR(v0 + v3 + 1, 1);\n v3 = t;\n t = BitOperators.shiftR(v1 - v2 + 1, 1);\n v1 = BitOperators.shiftR(v1 + v2 + 1, 1);\n v2 = t;\n t = BitOperators.shiftR(v4 * SIN_3 + v7 * COS_3 + 2048, 12);\n v4 = BitOperators.shiftR(v4 * COS_3 - v7 * SIN_3 + 2048, 12);\n v7 = t;\n t = BitOperators.shiftR(v5 * SIN_1 + v6 * COS_1 + 2048, 12);\n v5 = BitOperators.shiftR(v5 * COS_1 - v6 * SIN_1 + 2048, 12);\n v6 = t;\n\n // Stage 1\n p[0 + row] = v0 + v7;\n p[7 + row] = v0 - v7;\n p[1 + row] = v1 + v6;\n p[6 + row] = v1 - v6;\n p[2 + row] = v2 + v5;\n p[5 + row] = v2 - v5;\n p[3 + row] = v3 + v4;\n p[4 + row] = v3 - v4;\n }\n\n // Inverse DCT on columns\n for (let i = 0; i < 8; ++i) {\n const col = i;\n\n // Check for all-zero AC coefficients\n if (\n p[1 * 8 + col] === 0 &&\n p[2 * 8 + col] === 0 &&\n p[3 * 8 + col] === 0 &&\n p[4 * 8 + col] === 0 &&\n p[5 * 8 + col] === 0 &&\n p[6 * 8 + col] === 0 &&\n p[7 * 8 + col] === 0\n ) {\n const t = BitOperators.shiftR(SQRT_2 * dataIn[i] + 8192, 14);\n p[0 * 8 + col] = t;\n p[1 * 8 + col] = t;\n p[2 * 8 + col] = t;\n p[3 * 8 + col] = t;\n p[4 * 8 + col] = t;\n p[5 * 8 + col] = t;\n p[6 * 8 + col] = t;\n p[7 * 8 + col] = t;\n continue;\n }\n\n // Stage 4\n let v0 = BitOperators.shiftR(SQRT_2 * p[0 * 8 + col] + 2048, 12);\n let v1 = BitOperators.shiftR(SQRT_2 * p[4 * 8 + col] + 2048, 12);\n let v2 = p[2 * 8 + col];\n let v3 = p[6 * 8 + col];\n let v4 = BitOperators.shiftR(\n SQRT_1D2 * (p[1 * 8 + col] - p[7 * 8 + col]) + 2048,\n 12\n );\n let v7 = BitOperators.shiftR(\n SQRT_1D2 * (p[1 * 8 + col] + p[7 * 8 + col]) + 2048,\n 12\n );\n let v5 = p[3 * 8 + col];\n let v6 = p[5 * 8 + col];\n\n // Stage 3\n let t = BitOperators.shiftR(v0 - v1 + 1, 1);\n v0 = BitOperators.shiftR(v0 + v1 + 1, 1);\n v1 = t;\n t = BitOperators.shiftR(v2 * SIN_6 + v3 * COS_6 + 2048, 12);\n v2 = BitOperators.shiftR(v2 * COS_6 - v3 * SIN_6 + 2048, 12);\n v3 = t;\n t = BitOperators.shiftR(v4 - v6 + 1, 1);\n v4 = BitOperators.shiftR(v4 + v6 + 1, 1);\n v6 = t;\n t = BitOperators.shiftR(v7 + v5 + 1, 1);\n v5 = BitOperators.shiftR(v7 - v5 + 1, 1);\n v7 = t;\n\n // Stage 2\n t = BitOperators.shiftR(v0 - v3 + 1, 1);\n v0 = BitOperators.shiftR(v0 + v3 + 1, 1);\n v3 = t;\n t = BitOperators.shiftR(v1 - v2 + 1, 1);\n v1 = BitOperators.shiftR(v1 + v2 + 1, 1);\n v2 = t;\n t = BitOperators.shiftR(v4 * SIN_3 + v7 * COS_3 + 2048, 12);\n v4 = BitOperators.shiftR(v4 * COS_3 - v7 * SIN_3 + 2048, 12);\n v7 = t;\n t = BitOperators.shiftR(v5 * SIN_1 + v6 * COS_1 + 2048, 12);\n v5 = BitOperators.shiftR(v5 * COS_1 - v6 * SIN_1 + 2048, 12);\n v6 = t;\n\n // Stage 1\n p[0 * 8 + col] = v0 + v7;\n p[7 * 8 + col] = v0 - v7;\n p[1 * 8 + col] = v1 + v6;\n p[6 * 8 + col] = v1 - v6;\n p[2 * 8 + col] = v2 + v5;\n p[5 * 8 + col] = v2 - v5;\n p[3 * 8 + col] = v3 + v4;\n p[4 * 8 + col] = v3 - v4;\n }\n\n // Convert to 8-bit integers\n for (let i = 0; i < 64; ++i) {\n dataOut[i] =\n JpegQuantize.dctClip[\n dctClipOffset + 128 + BitOperators.shiftR(p[i] + 8, 4)\n ];\n }\n }\n\n public static getImageFromJpeg(jpeg: JpegData): MemoryImage {\n const orientation = jpeg.exifData.imageIfd.hasOrientation\n ? jpeg.exifData.imageIfd.orientation!\n : 0;\n const flipWidthHeight = orientation >= 5 && orientation <= 8;\n const width = flipWidthHeight ? jpeg.height : jpeg.width;\n const height = flipWidthHeight ? jpeg.width : jpeg.height;\n\n const image = new MemoryImage({\n width: width,\n height: height,\n rgbChannelSet: RgbChannelSet.rgb,\n });\n\n // Copy exif data, except for ORIENTATION which we're baking.\n image.exifData = ExifData.from(jpeg.exifData);\n image.exifData.imageIfd.orientation = undefined;\n\n let component1: ComponentData | undefined = undefined;\n let component2: ComponentData | undefined = undefined;\n let component3: ComponentData | undefined = undefined;\n let component4: ComponentData | undefined = undefined;\n let component1Line: Uint8Array | undefined = undefined;\n let component2Line: Uint8Array | undefined = undefined;\n let component3Line: Uint8Array | undefined = undefined;\n let component4Line: Uint8Array | undefined = undefined;\n let offset = 0;\n let Y = 0;\n let Cb = 0;\n let Cr = 0;\n let K = 0;\n let C = 0;\n let M = 0;\n let Ye = 0;\n let R = 0;\n let G = 0;\n let B = 0;\n let colorTransform = false;\n\n const h1 = jpeg.height - 1;\n const w1 = jpeg.width - 1;\n\n switch (jpeg.components.length) {\n case 1: {\n const component1 = jpeg.components[0];\n const lines = component1.lines;\n const hShift1 = component1.hScaleShift;\n const vShift1 = component1.vScaleShift;\n for (let y = 0; y < jpeg.height; y++) {\n const y1 = y >> vShift1;\n const component1Line = lines[y1];\n for (let x = 0; x < jpeg.width; x++) {\n const x1 = x >> hShift1;\n const Y = component1Line[x1];\n const c = Color.getColor(Y, Y, Y);\n if (orientation === 2) {\n image.setPixel(w1 - x, y, c);\n } else if (orientation === 3) {\n image.setPixel(w1 - x, h1 - y, c);\n } else if (orientation === 4) {\n image.setPixel(x, h1 - y, c);\n } else if (orientation === 5) {\n image.setPixel(y, x, c);\n } else if (orientation === 6) {\n image.setPixel(h1 - y, x, c);\n } else if (orientation === 7) {\n image.setPixel(h1 - y, w1 - x, c);\n } else if (orientation === 8) {\n image.setPixel(y, w1 - x, c);\n } else {\n image.setPixelByIndex(offset++, c);\n }\n }\n }\n break;\n }\n // case 2:\n // {\n // // PDF might compress two component data in custom color-space\n // component1 = jpeg.components[0];\n // component2 = jpeg.components[1];\n // let hShift1: number = component1.hScaleShift;\n // let vShift1: number = component1.vScaleShift;\n // let hShift2: number = component2.hScaleShift;\n // let vShift2: number = component2.vScaleShift;\n\n // for (let y = 0; y < height; y++) {\n // let y1 = y >> vShift1;\n // let y2 = y >> vShift2;\n // component1Line = component1.lines[y1];\n // component2Line = component2.lines[y2];\n\n // for (let x = 0; x < width; x++) {\n // let x1 = x >> hShift1;\n // let x2 = x >> hShift2;\n\n // Y = component1Line![x1];\n // // data[offset++] = Y;\n\n // Y = component2Line![x2];\n // // data[offset++] = Y;\n // }\n // }\n // break;\n // }\n case 3: {\n // The default transform for three components is true\n colorTransform = true;\n\n component1 = jpeg.components[0];\n component2 = jpeg.components[1];\n component3 = jpeg.components[2];\n\n const lines1 = component1.lines;\n const lines2 = component2.lines;\n const lines3 = component3.lines;\n\n const hShift1 = component1.hScaleShift;\n const vShift1 = component1.vScaleShift;\n const hShift2 = component2.hScaleShift;\n const vShift2 = component2.vScaleShift;\n const hShift3 = component3.hScaleShift;\n const vShift3 = component3.vScaleShift;\n\n for (let y = 0; y < jpeg.height; y++) {\n const y1 = y >> vShift1;\n const y2 = y >> vShift2;\n const y3 = y >> vShift3;\n\n component1Line = lines1[y1];\n component2Line = lines2[y2];\n component3Line = lines3[y3];\n\n for (let x = 0; x < jpeg.width; x++) {\n const x1 = x >> hShift1;\n const x2 = x >> hShift2;\n const x3 = x >> hShift3;\n\n Y = component1Line[x1] << 8;\n Cb = component2Line[x2] - 128;\n Cr = component3Line[x3] - 128;\n\n R = Y + 359 * Cr + 128;\n G = Y - 88 * Cb - 183 * Cr + 128;\n B = Y + 454 * Cb + 128;\n\n R = this.clamp8(BitOperators.shiftR(R, 8));\n G = this.clamp8(BitOperators.shiftR(G, 8));\n B = this.clamp8(BitOperators.shiftR(B, 8));\n const c = Color.getColor(R, G, B);\n if (orientation === 2) {\n image.setPixel(w1 - x, y, c);\n } else if (orientation === 3) {\n image.setPixel(w1 - x, h1 - y, c);\n } else if (orientation === 4) {\n image.setPixel(x, h1 - y, c);\n } else if (orientation === 5) {\n image.setPixel(y, x, c);\n } else if (orientation === 6) {\n image.setPixel(h1 - y, x, c);\n } else if (orientation === 7) {\n image.setPixel(h1 - y, w1 - x, c);\n } else if (orientation === 8) {\n image.setPixel(y, w1 - x, c);\n } else {\n image.setPixelByIndex(offset++, c);\n }\n }\n }\n break;\n }\n case 4: {\n if (jpeg.adobe === undefined) {\n throw new ImageError('Unsupported color mode (4 components)');\n }\n // The default transform for four components is false\n colorTransform = false;\n // The adobe transform marker overrides any previous setting\n if (jpeg.adobe.transformCode !== 0) {\n colorTransform = true;\n }\n\n component1 = jpeg.components[0];\n component2 = jpeg.components[1];\n component3 = jpeg.components[2];\n component4 = jpeg.components[3];\n\n const lines1 = component1.lines;\n const lines2 = component2.lines;\n const lines3 = component3.lines;\n const lines4 = component4.lines;\n\n const hShift1 = component1.hScaleShift;\n const vShift1 = component1.vScaleShift;\n const hShift2 = component2.hScaleShift;\n const vShift2 = component2.vScaleShift;\n const hShift3 = component3.hScaleShift;\n const vShift3 = component3.vScaleShift;\n const hShift4 = component4.hScaleShift;\n const vShift4 = component4.vScaleShift;\n\n for (let y = 0; y < jpeg.height; y++) {\n const y1 = y >> vShift1;\n const y2 = y >> vShift2;\n const y3 = y >> vShift3;\n const y4 = y >> vShift4;\n component1Line = lines1[y1];\n component2Line = lines2[y2];\n component3Line = lines3[y3];\n component4Line = lines4[y4];\n for (let x = 0; x < jpeg.width; x++) {\n const x1 = x >> hShift1;\n const x2 = x >> hShift2;\n const x3 = x >> hShift3;\n const x4 = x >> hShift4;\n if (!colorTransform) {\n C = component1Line[x1];\n M = component2Line[x2];\n Ye = component3Line[x3];\n K = component4Line[x4];\n } else {\n Y = component1Line[x1];\n Cb = component2Line[x2];\n Cr = component3Line[x3];\n K = component4Line[x4];\n\n C = 255 - this.clamp8(Math.trunc(Y + 1.402 * (Cr - 128)));\n M =\n 255 -\n this.clamp8(\n Math.trunc(\n Y - 0.3441363 * (Cb - 128) - 0.71413636 * (Cr - 128)\n )\n );\n Ye = 255 - this.clamp8(Math.trunc(Y + 1.772 * (Cb - 128)));\n }\n R = BitOperators.shiftR(C * K, 8);\n G = BitOperators.shiftR(M * K, 8);\n B = BitOperators.shiftR(Ye * K, 8);\n const c = Color.getColor(R, G, B);\n if (orientation === 2) {\n image.setPixel(w1 - x, y, c);\n } else if (orientation === 3) {\n image.setPixel(w1 - x, h1 - y, c);\n } else if (orientation === 4) {\n image.setPixel(x, h1 - y, c);\n } else if (orientation === 5) {\n image.setPixel(y, x, c);\n } else if (orientation === 6) {\n image.setPixel(h1 - y, x, c);\n } else if (orientation === 7) {\n image.setPixel(h1 - y, w1 - x, c);\n } else if (orientation === 8) {\n image.setPixel(y, w1 - x, c);\n } else {\n image.setPixelByIndex(offset++, c);\n }\n }\n }\n break;\n }\n default:\n throw new ImageError('Unsupported color mode');\n }\n return image;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { ImageError } from '../../error/image-error';\nimport { Jpeg } from './jpeg';\nimport { JpegComponent } from './jpeg-component';\nimport { JpegFrame } from './jpeg-frame';\n\ntype DecodeFunction = (component: JpegComponent, block: Int32Array) => void;\n\nexport class JpegScan {\n private _input: InputBuffer;\n public get input(): InputBuffer {\n return this._input;\n }\n\n private _frame: JpegFrame;\n public get frame(): JpegFrame {\n return this._frame;\n }\n\n private _precision: number;\n public get precision(): number {\n return this._precision;\n }\n\n private _samplesPerLine: number;\n public get samplesPerLine(): number {\n return this._samplesPerLine;\n }\n\n private _scanLines: number;\n public get scanLines(): number {\n return this._scanLines;\n }\n\n private _mcusPerLine: number;\n public get mcusPerLine(): number {\n return this._mcusPerLine;\n }\n\n private _progressive: boolean;\n public get progressive(): boolean {\n return this._progressive;\n }\n\n private _maxH: number;\n public get maxH(): number {\n return this._maxH;\n }\n\n private _maxV: number;\n public get maxV(): number {\n return this._maxV;\n }\n\n private _components: Array;\n public get components(): Array {\n return this._components;\n }\n\n private _resetInterval?: number;\n public get resetInterval(): number | undefined {\n return this._resetInterval;\n }\n\n private _spectralStart: number;\n public get spectralStart(): number {\n return this._spectralStart;\n }\n\n private _spectralEnd: number;\n public get spectralEnd(): number {\n return this._spectralEnd;\n }\n\n private _successivePrev: number;\n public get successivePrev(): number {\n return this._successivePrev;\n }\n\n private _successive: number;\n public get successive(): number {\n return this._successive;\n }\n\n private _bitsData = 0;\n public get bitsData(): number {\n return this._bitsData;\n }\n\n private _bitsCount = 0;\n public get bitsCount(): number {\n return this._bitsCount;\n }\n\n private _eobrun = 0;\n public get eobrun(): number {\n return this._eobrun;\n }\n\n private _successiveACState = 0;\n public get successiveACState(): number {\n return this._successiveACState;\n }\n\n private _successiveACNextValue = 0;\n public get successiveACNextValue(): number {\n return this._successiveACNextValue;\n }\n\n constructor(\n input: InputBuffer,\n frame: JpegFrame,\n components: Array,\n spectralStart: number,\n spectralEnd: number,\n successivePrev: number,\n successive: number,\n resetInterval?: number\n ) {\n this._input = input;\n this._frame = frame;\n this._precision = frame.precision;\n this._samplesPerLine = frame.samplesPerLine;\n this._scanLines = frame.scanLines;\n this._mcusPerLine = frame.mcusPerLine;\n this._progressive = frame.progressive;\n this._maxH = frame.maxHSamples;\n this._maxV = frame.maxVSamples;\n this._components = components;\n this._resetInterval = resetInterval;\n this._spectralStart = spectralStart;\n this._spectralEnd = spectralEnd;\n this._successivePrev = successivePrev;\n this._successive = successive;\n }\n\n private readBit(): number | undefined {\n if (this.bitsCount > 0) {\n this._bitsCount--;\n return (this._bitsData >> this._bitsCount) & 1;\n }\n\n if (this._input.isEOS) {\n return undefined;\n }\n\n this._bitsData = this._input.readByte();\n if (this._bitsData === 0xff) {\n const nextByte = this.input.readByte();\n if (nextByte !== 0) {\n throw new ImageError(\n `unexpected marker: ${((this._bitsData << 8) | nextByte).toString(\n 16\n )}`\n );\n }\n }\n\n this._bitsCount = 7;\n return (this._bitsData >> 7) & 1;\n }\n\n private decodeHuffman(tree: []): number | undefined {\n let node = tree;\n let bit: number | undefined = undefined;\n while ((bit = this.readBit()) !== undefined) {\n node = node[bit];\n if (typeof node === 'number') {\n return Math.trunc(node);\n }\n }\n return undefined;\n }\n\n private receive(length: number): number | undefined {\n let n = 0;\n let len = length;\n while (len > 0) {\n const bit = this.readBit();\n if (bit === undefined) {\n return undefined;\n }\n n = (n << 1) | bit;\n len--;\n }\n return n;\n }\n\n private receiveAndExtend(length: number | undefined): number {\n if (length === 1) {\n return this.readBit() === 1 ? 1 : -1;\n }\n const n = this.receive(length!)!;\n if (n >= 1 << ((length ?? 0) - 1)) {\n return n;\n }\n return n + (-1 << (length ?? 0)) + 1;\n }\n\n private decodeBaseline(component: JpegComponent, zz: Int32Array): void {\n const t = this.decodeHuffman(component.huffmanTableDC);\n const diff = t === 0 ? 0 : this.receiveAndExtend(t);\n component.pred += diff;\n zz[0] = component.pred;\n\n let k = 1;\n while (k < 64) {\n const rs = this.decodeHuffman(component.huffmanTableAC)!;\n let s = rs & 15;\n const r = rs >> 4;\n if (s === 0) {\n if (r < 15) {\n break;\n }\n k += 16;\n continue;\n }\n\n k += r;\n\n s = this.receiveAndExtend(s);\n\n const z = Jpeg.dctZigZag[k];\n zz[z] = s;\n k++;\n }\n }\n\n private decodeDCFirst(component: JpegComponent, zz: Int32Array): void {\n const t = this.decodeHuffman(component.huffmanTableDC);\n const diff = t === 0 ? 0 : this.receiveAndExtend(t) << this._successive;\n component.pred += diff;\n zz[0] = component.pred;\n }\n\n private decodeDCSuccessive(_: JpegComponent, zz: Int32Array): void {\n zz[0] |= this.readBit()! << this._successive;\n }\n\n private decodeACFirst(component: JpegComponent, zz: Int32Array): void {\n if (this._eobrun > 0) {\n this._eobrun--;\n return;\n }\n let k = this._spectralStart;\n const e = this._spectralEnd;\n while (k <= e) {\n const rs = this.decodeHuffman(component.huffmanTableAC)!;\n const s = rs & 15;\n const r = rs >> 4;\n if (s === 0) {\n if (r < 15) {\n this._eobrun = this.receive(r)! + (1 << r) - 1;\n break;\n }\n k += 16;\n continue;\n }\n k += r;\n const z = Jpeg.dctZigZag[k];\n zz[z] = this.receiveAndExtend(s) * (1 << this._successive);\n k++;\n }\n }\n\n private decodeACSuccessive(component: JpegComponent, zz: Int32Array): void {\n let k = this._spectralStart;\n const e = this._spectralEnd;\n let s = 0;\n let r = 0;\n while (k <= e) {\n const z = Jpeg.dctZigZag[k];\n switch (this._successiveACState) {\n case 0: {\n // Initial state\n const rs = this.decodeHuffman(component.huffmanTableAC);\n if (rs === undefined) {\n throw new ImageError('Invalid progressive encoding');\n }\n s = rs & 15;\n r = rs >> 4;\n if (s === 0) {\n if (r < 15) {\n this._eobrun = this.receive(r)! + (1 << r);\n this._successiveACState = 4;\n } else {\n r = 16;\n this._successiveACState = 1;\n }\n } else {\n if (s !== 1) {\n throw new ImageError('invalid ACn encoding');\n }\n this._successiveACNextValue = this.receiveAndExtend(s);\n this._successiveACState = r !== 0 ? 2 : 3;\n }\n continue;\n }\n case 1:\n case 2: {\n // Skipping r zero items\n if (zz[z] !== 0) {\n zz[z] += this.readBit()! << this._successive;\n } else {\n r--;\n if (r === 0) {\n this._successiveACState = this._successiveACState === 2 ? 3 : 0;\n }\n }\n break;\n }\n case 3: {\n // Set value for a zero item\n if (zz[z] !== 0) {\n zz[z] += this.readBit()! << this._successive;\n } else {\n zz[z] = this._successiveACNextValue << this._successive;\n this._successiveACState = 0;\n }\n break;\n }\n case 4: {\n // Eob\n if (zz[z] !== 0) {\n zz[z] += this.readBit()! << this._successive;\n }\n break;\n }\n }\n k++;\n }\n if (this._successiveACState === 4) {\n this._eobrun--;\n if (this._eobrun === 0) {\n this._successiveACState = 0;\n }\n }\n }\n\n private decodeMcu(\n component: JpegComponent,\n decodeFn: DecodeFunction,\n mcu: number,\n row: number,\n col: number\n ): void {\n const mcuRow = Math.floor(mcu / this._mcusPerLine);\n const mcuCol = mcu % this._mcusPerLine;\n const blockRow = mcuRow * component.vSamples + row;\n const blockCol = mcuCol * component.hSamples + col;\n if (blockRow >= component.blocks.length) {\n return;\n }\n const numCols = component.blocks[blockRow].length;\n if (blockCol >= numCols) {\n return;\n }\n decodeFn.call(this, component, component.blocks[blockRow][blockCol]);\n }\n\n private decodeBlock(\n component: JpegComponent,\n decodeFn: DecodeFunction,\n mcu: number\n ): void {\n const blockRow = Math.floor(mcu / component.blocksPerLine);\n const blockCol = mcu % component.blocksPerLine;\n decodeFn.call(this, component, component.blocks[blockRow][blockCol]);\n }\n\n public decode(): void {\n const componentsLength = this._components.length;\n let component: JpegComponent | undefined = undefined;\n let decodeFn: DecodeFunction | undefined = undefined;\n if (this._progressive) {\n if (this._spectralStart === 0) {\n decodeFn =\n this._successivePrev === 0\n ? this.decodeDCFirst\n : this.decodeDCSuccessive;\n } else {\n decodeFn =\n this._successivePrev === 0\n ? this.decodeACFirst\n : this.decodeACSuccessive;\n }\n } else {\n decodeFn = this.decodeBaseline;\n }\n\n let mcu = 0;\n\n let mcuExpected: number | undefined = undefined;\n if (componentsLength === 1) {\n mcuExpected =\n this._components[0].blocksPerLine * this._components[0].blocksPerColumn;\n } else {\n mcuExpected = this._mcusPerLine * this._frame.mcusPerColumn;\n }\n\n if (this._resetInterval === undefined || this._resetInterval === 0) {\n this._resetInterval = mcuExpected;\n }\n\n let h: number | undefined = undefined;\n let v: number | undefined = undefined;\n while (mcu < mcuExpected) {\n // Reset interval stuff\n for (let i = 0; i < componentsLength; i++) {\n this._components[i].pred = 0;\n }\n this._eobrun = 0;\n\n if (componentsLength === 1) {\n component = this._components[0];\n for (let n = 0; n < this._resetInterval; n++) {\n this.decodeBlock(component, decodeFn, mcu);\n mcu++;\n }\n } else {\n for (let n = 0; n < this._resetInterval; n++) {\n for (let i = 0; i < componentsLength; i++) {\n component = this.components[i];\n h = component.hSamples;\n v = component.vSamples;\n for (let j = 0; j < v; j++) {\n for (let k = 0; k < h; k++) {\n this.decodeMcu(component, decodeFn, mcu, j, k);\n }\n }\n }\n mcu++;\n }\n }\n\n // Find marker\n this._bitsCount = 0;\n const m1 = this._input.getByte(0);\n const m2 = this._input.getByte(1);\n if (m1 === 0xff) {\n if (m2 >= Jpeg.M_RST0 && m2 <= Jpeg.M_RST7) {\n this._input.skip(2);\n } else {\n break;\n }\n }\n }\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { ArrayUtils } from '../../common/array-utils';\nimport { MemoryImage } from '../../common/memory-image';\nimport { ImageError } from '../../error/image-error';\nimport { ComponentData } from './component-data';\nimport { Jpeg } from './jpeg';\nimport { JpegAdobe } from './jpeg-adobe';\nimport { JpegComponent } from './jpeg-component';\nimport { JpegFrame } from './jpeg-frame';\nimport { JpegHuffman } from './jpeg-huffman';\nimport { JpegInfo } from './jpeg-info';\nimport { JpegJfif } from './jpeg-jfif';\nimport { JpegQuantize } from './jpeg-quantize';\nimport { JpegScan } from './jpeg-scan';\nimport { ExifData } from '../../exif/exif-data';\n\nexport class JpegData {\n static readonly CRR = [\n -179, -178, -177, -175, -174, -172, -171, -170, -168, -167, -165, -164,\n -163, -161, -160, -158, -157, -156, -154, -153, -151, -150, -149, -147,\n -146, -144, -143, -142, -140, -139, -137, -136, -135, -133, -132, -130,\n -129, -128, -126, -125, -123, -122, -121, -119, -118, -116, -115, -114,\n -112, -111, -109, -108, -107, -105, -104, -102, -101, -100, -98, -97, -95,\n -94, -93, -91, -90, -88, -87, -86, -84, -83, -81, -80, -79, -77, -76, -74,\n -73, -72, -70, -69, -67, -66, -64, -63, -62, -60, -59, -57, -56, -55, -53,\n -52, -50, -49, -48, -46, -45, -43, -42, -41, -39, -38, -36, -35, -34, -32,\n -31, -29, -28, -27, -25, -24, -22, -21, -20, -18, -17, -15, -14, -13, -11,\n -10, -8, -7, -6, -4, -3, -1, 0, 1, 3, 4, 6, 7, 8, 10, 11, 13, 14, 15, 17,\n 18, 20, 21, 22, 24, 25, 27, 28, 29, 31, 32, 34, 35, 36, 38, 39, 41, 42, 43,\n 45, 46, 48, 49, 50, 52, 53, 55, 56, 57, 59, 60, 62, 63, 64, 66, 67, 69, 70,\n 72, 73, 74, 76, 77, 79, 80, 81, 83, 84, 86, 87, 88, 90, 91, 93, 94, 95, 97,\n 98, 100, 101, 102, 104, 105, 107, 108, 109, 111, 112, 114, 115, 116, 118,\n 119, 121, 122, 123, 125, 126, 128, 129, 130, 132, 133, 135, 136, 137, 139,\n 140, 142, 143, 144, 146, 147, 149, 150, 151, 153, 154, 156, 157, 158, 160,\n 161, 163, 164, 165, 167, 168, 170, 171, 172, 174, 175, 177, 178,\n ];\n\n static readonly CRG = [\n 5990656, 5943854, 5897052, 5850250, 5803448, 5756646, 5709844, 5663042,\n 5616240, 5569438, 5522636, 5475834, 5429032, 5382230, 5335428, 5288626,\n 5241824, 5195022, 5148220, 5101418, 5054616, 5007814, 4961012, 4914210,\n 4867408, 4820606, 4773804, 4727002, 4680200, 4633398, 4586596, 4539794,\n 4492992, 4446190, 4399388, 4352586, 4305784, 4258982, 4212180, 4165378,\n 4118576, 4071774, 4024972, 3978170, 3931368, 3884566, 3837764, 3790962,\n 3744160, 3697358, 3650556, 3603754, 3556952, 3510150, 3463348, 3416546,\n 3369744, 3322942, 3276140, 3229338, 3182536, 3135734, 3088932, 3042130,\n 2995328, 2948526, 2901724, 2854922, 2808120, 2761318, 2714516, 2667714,\n 2620912, 2574110, 2527308, 2480506, 2433704, 2386902, 2340100, 2293298,\n 2246496, 2199694, 2152892, 2106090, 2059288, 2012486, 1965684, 1918882,\n 1872080, 1825278, 1778476, 1731674, 1684872, 1638070, 1591268, 1544466,\n 1497664, 1450862, 1404060, 1357258, 1310456, 1263654, 1216852, 1170050,\n 1123248, 1076446, 1029644, 982842, 936040, 889238, 842436, 795634, 748832,\n 702030, 655228, 608426, 561624, 514822, 468020, 421218, 374416, 327614,\n 280812, 234010, 187208, 140406, 93604, 46802, 0, -46802, -93604, -140406,\n -187208, -234010, -280812, -327614, -374416, -421218, -468020, -514822,\n -561624, -608426, -655228, -702030, -748832, -795634, -842436, -889238,\n -936040, -982842, -1029644, -1076446, -1123248, -1170050, -1216852,\n -1263654, -1310456, -1357258, -1404060, -1450862, -1497664, -1544466,\n -1591268, -1638070, -1684872, -1731674, -1778476, -1825278, -1872080,\n -1918882, -1965684, -2012486, -2059288, -2106090, -2152892, -2199694,\n -2246496, -2293298, -2340100, -2386902, -2433704, -2480506, -2527308,\n -2574110, -2620912, -2667714, -2714516, -2761318, -2808120, -2854922,\n -2901724, -2948526, -2995328, -3042130, -3088932, -3135734, -3182536,\n -3229338, -3276140, -3322942, -3369744, -3416546, -3463348, -3510150,\n -3556952, -3603754, -3650556, -3697358, -3744160, -3790962, -3837764,\n -3884566, -3931368, -3978170, -4024972, -4071774, -4118576, -4165378,\n -4212180, -4258982, -4305784, -4352586, -4399388, -4446190, -4492992,\n -4539794, -4586596, -4633398, -4680200, -4727002, -4773804, -4820606,\n -4867408, -4914210, -4961012, -5007814, -5054616, -5101418, -5148220,\n -5195022, -5241824, -5288626, -5335428, -5382230, -5429032, -5475834,\n -5522636, -5569438, -5616240, -5663042, -5709844, -5756646, -5803448,\n -5850250, -5897052, -5943854,\n ];\n\n static readonly CBG = [\n 2919680, 2897126, 2874572, 2852018, 2829464, 2806910, 2784356, 2761802,\n 2739248, 2716694, 2694140, 2671586, 2649032, 2626478, 2603924, 2581370,\n 2558816, 2536262, 2513708, 2491154, 2468600, 2446046, 2423492, 2400938,\n 2378384, 2355830, 2333276, 2310722, 2288168, 2265614, 2243060, 2220506,\n 2197952, 2175398, 2152844, 2130290, 2107736, 2085182, 2062628, 2040074,\n 2017520, 1994966, 1972412, 1949858, 1927304, 1904750, 1882196, 1859642,\n 1837088, 1814534, 1791980, 1769426, 1746872, 1724318, 1701764, 1679210,\n 1656656, 1634102, 1611548, 1588994, 1566440, 1543886, 1521332, 1498778,\n 1476224, 1453670, 1431116, 1408562, 1386008, 1363454, 1340900, 1318346,\n 1295792, 1273238, 1250684, 1228130, 1205576, 1183022, 1160468, 1137914,\n 1115360, 1092806, 1070252, 1047698, 1025144, 1002590, 980036, 957482,\n 934928, 912374, 889820, 867266, 844712, 822158, 799604, 777050, 754496,\n 731942, 709388, 686834, 664280, 641726, 619172, 596618, 574064, 551510,\n 528956, 506402, 483848, 461294, 438740, 416186, 393632, 371078, 348524,\n 325970, 303416, 280862, 258308, 235754, 213200, 190646, 168092, 145538,\n 122984, 100430, 77876, 55322, 32768, 10214, -12340, -34894, -57448, -80002,\n -102556, -125110, -147664, -170218, -192772, -215326, -237880, -260434,\n -282988, -305542, -328096, -350650, -373204, -395758, -418312, -440866,\n -463420, -485974, -508528, -531082, -553636, -576190, -598744, -621298,\n -643852, -666406, -688960, -711514, -734068, -756622, -779176, -801730,\n -824284, -846838, -869392, -891946, -914500, -937054, -959608, -982162,\n -1004716, -1027270, -1049824, -1072378, -1094932, -1117486, -1140040,\n -1162594, -1185148, -1207702, -1230256, -1252810, -1275364, -1297918,\n -1320472, -1343026, -1365580, -1388134, -1410688, -1433242, -1455796,\n -1478350, -1500904, -1523458, -1546012, -1568566, -1591120, -1613674,\n -1636228, -1658782, -1681336, -1703890, -1726444, -1748998, -1771552,\n -1794106, -1816660, -1839214, -1861768, -1884322, -1906876, -1929430,\n -1951984, -1974538, -1997092, -2019646, -2042200, -2064754, -2087308,\n -2109862, -2132416, -2154970, -2177524, -2200078, -2222632, -2245186,\n -2267740, -2290294, -2312848, -2335402, -2357956, -2380510, -2403064,\n -2425618, -2448172, -2470726, -2493280, -2515834, -2538388, -2560942,\n -2583496, -2606050, -2628604, -2651158, -2673712, -2696266, -2718820,\n -2741374, -2763928, -2786482, -2809036, -2831590,\n ];\n\n static readonly CBB = [\n -227, -225, -223, -222, -220, -218, -216, -214, -213, -211, -209, -207,\n -206, -204, -202, -200, -198, -197, -195, -193, -191, -190, -188, -186,\n -184, -183, -181, -179, -177, -175, -174, -172, -170, -168, -167, -165,\n -163, -161, -159, -158, -156, -154, -152, -151, -149, -147, -145, -144,\n -142, -140, -138, -136, -135, -133, -131, -129, -128, -126, -124, -122,\n -120, -119, -117, -115, -113, -112, -110, -108, -106, -105, -103, -101, -99,\n -97, -96, -94, -92, -90, -89, -87, -85, -83, -82, -80, -78, -76, -74, -73,\n -71, -69, -67, -66, -64, -62, -60, -58, -57, -55, -53, -51, -50, -48, -46,\n -44, -43, -41, -39, -37, -35, -34, -32, -30, -28, -27, -25, -23, -21, -19,\n -18, -16, -14, -12, -11, -9, -7, -5, -4, -2, 0, 2, 4, 5, 7, 9, 11, 12, 14,\n 16, 18, 19, 21, 23, 25, 27, 28, 30, 32, 34, 35, 37, 39, 41, 43, 44, 46, 48,\n 50, 51, 53, 55, 57, 58, 60, 62, 64, 66, 67, 69, 71, 73, 74, 76, 78, 80, 82,\n 83, 85, 87, 89, 90, 92, 94, 96, 97, 99, 101, 103, 105, 106, 108, 110, 112,\n 113, 115, 117, 119, 120, 122, 124, 126, 128, 129, 131, 133, 135, 136, 138,\n 140, 142, 144, 145, 147, 149, 151, 152, 154, 156, 158, 159, 161, 163, 165,\n 167, 168, 170, 172, 174, 175, 177, 179, 181, 183, 184, 186, 188, 190, 191,\n 193, 195, 197, 198, 200, 202, 204, 206, 207, 209, 211, 213, 214, 216, 218,\n 220, 222, 223, 225,\n ];\n\n private _input!: InputBuffer;\n public get input(): InputBuffer {\n return this._input;\n }\n\n private _jfif!: JpegJfif;\n public get jfif(): JpegJfif {\n return this._jfif;\n }\n\n private _adobe!: JpegAdobe;\n public get adobe(): JpegAdobe {\n return this._adobe;\n }\n\n private _frame?: JpegFrame;\n public get frame(): JpegFrame | undefined {\n return this._frame;\n }\n\n private _resetInterval!: number;\n public get resetInterval(): number {\n return this._resetInterval;\n }\n\n private _comment?: string;\n public get comment(): string | undefined {\n return this._comment;\n }\n\n private readonly _exifData: ExifData = new ExifData();\n public get exifData(): ExifData {\n return this._exifData;\n }\n\n private readonly _quantizationTables = new Array(\n Jpeg.NUM_QUANT_TBLS\n );\n public get quantizationTables(): Array {\n return this._quantizationTables;\n }\n\n private readonly _frames = new Array();\n public get frames(): Array {\n return this._frames;\n }\n\n private readonly _huffmanTablesAC = new Array<[] | undefined>();\n public get huffmanTablesAC(): Array<[] | undefined> {\n return this._huffmanTablesAC;\n }\n\n private readonly _huffmanTablesDC = new Array<[] | undefined>();\n public get huffmanTablesDC(): Array<[] | undefined> {\n return this._huffmanTablesDC;\n }\n\n private readonly _components = new Array();\n public get components(): Array {\n return this._components;\n }\n\n public get width(): number {\n return this._frame!.samplesPerLine;\n }\n\n public get height(): number {\n return this._frame!.scanLines;\n }\n\n private readMarkers(): void {\n let marker = this.nextMarker();\n if (marker !== Jpeg.M_SOI) {\n // SOI (Start of Image)\n throw new ImageError('Start Of Image marker not found.');\n }\n\n marker = this.nextMarker();\n while (marker !== Jpeg.M_EOI && !this._input.isEOS) {\n const block = this.readBlock();\n switch (marker) {\n case Jpeg.M_APP0:\n case Jpeg.M_APP1:\n case Jpeg.M_APP2:\n case Jpeg.M_APP3:\n case Jpeg.M_APP4:\n case Jpeg.M_APP5:\n case Jpeg.M_APP6:\n case Jpeg.M_APP7:\n case Jpeg.M_APP8:\n case Jpeg.M_APP9:\n case Jpeg.M_APP10:\n case Jpeg.M_APP11:\n case Jpeg.M_APP12:\n case Jpeg.M_APP13:\n case Jpeg.M_APP14:\n case Jpeg.M_APP15:\n case Jpeg.M_COM:\n this.readAppData(marker, block);\n break;\n\n // DQT (Define Quantization Tables)\n case Jpeg.M_DQT:\n this.readDQT(block);\n break;\n\n // SOF0 (Start of Frame, Baseline DCT)\n case Jpeg.M_SOF0:\n // SOF1 (Start of Frame, Extended DCT)\n // falls through\n case Jpeg.M_SOF1:\n // SOF2 (Start of Frame, Progressive DCT)\n // falls through\n case Jpeg.M_SOF2:\n this.readFrame(marker, block);\n break;\n\n case Jpeg.M_SOF3:\n case Jpeg.M_SOF5:\n case Jpeg.M_SOF6:\n case Jpeg.M_SOF7:\n case Jpeg.M_JPG:\n case Jpeg.M_SOF9:\n case Jpeg.M_SOF10:\n case Jpeg.M_SOF11:\n case Jpeg.M_SOF13:\n case Jpeg.M_SOF14:\n case Jpeg.M_SOF15:\n throw new ImageError(`Unhandled frame type ${marker.toString(16)}`);\n\n // DHT (Define Huffman Tables)\n case Jpeg.M_DHT:\n this.readDHT(block);\n break;\n\n // DRI (Define Restart Interval)\n case Jpeg.M_DRI:\n this.readDRI(block);\n break;\n\n // SOS (Start of Scan)\n case Jpeg.M_SOS:\n this.readSOS(block);\n break;\n\n // Fill bytes\n case 0xff:\n if (this._input.getByte(0) !== 0xff) {\n this._input.skip(-1);\n }\n break;\n\n default:\n if (\n this._input.getByte(-3) === 0xff &&\n this._input.getByte(-2) >= 0xc0 &&\n this._input.getByte(-2) <= 0xfe\n ) {\n // Could be incorrect encoding -- last 0xFF byte of the previous\n // block was eaten by the encoder\n this._input.skip(-3);\n break;\n }\n\n if (marker !== 0) {\n throw new ImageError(`Unknown JPEG marker ${marker.toString(16)}`);\n }\n break;\n }\n\n marker = this.nextMarker();\n }\n }\n\n private skipBlock(): void {\n const length = this._input.readUint16();\n if (length < 2) {\n throw new ImageError('Invalid Block');\n }\n this._input.skip(length - 2);\n }\n\n public validate(bytes: Uint8Array): boolean {\n this._input = new InputBuffer({\n buffer: bytes,\n bigEndian: true,\n });\n\n // Some other formats have embedded jpeg, or jpeg-like data.\n // Only validate if the image starts with the StartOfImage tag.\n const soiCheck = this._input.peekBytes(2);\n if (soiCheck.getByte(0) !== 0xff || soiCheck.getByte(1) !== 0xd8) {\n return false;\n }\n\n let marker = this.nextMarker();\n if (marker !== Jpeg.M_SOI) {\n return false;\n }\n\n let hasSOF = false;\n let hasSOS = false;\n\n marker = this.nextMarker();\n while (marker !== Jpeg.M_EOI && !this._input.isEOS) {\n // EOI (End of image)\n const sectionByteSize = this._input.readUint16();\n if (sectionByteSize < 2) {\n // Jpeg section consists of more than 2 bytes at least\n // return success only when SOF and SOS have already found (as a jpeg without EOF.)\n break;\n }\n\n this._input.skip(sectionByteSize - 2);\n\n switch (marker) {\n // SOF0 (Start of Frame, Baseline DCT)\n case Jpeg.M_SOF0:\n // SOF1 (Start of Frame, Extended DCT)\n // falls through\n case Jpeg.M_SOF1:\n // SOF2 (Start of Frame, Progressive DCT)\n // falls through\n case Jpeg.M_SOF2:\n hasSOF = true;\n break;\n // SOS (Start of Scan)\n case Jpeg.M_SOS:\n hasSOS = true;\n break;\n default:\n }\n\n marker = this.nextMarker();\n }\n\n return hasSOF && hasSOS;\n }\n\n public readInfo(bytes: Uint8Array): JpegInfo | undefined {\n this._input = new InputBuffer({\n buffer: bytes,\n bigEndian: true,\n });\n\n let marker = this.nextMarker();\n if (marker !== Jpeg.M_SOI) {\n return undefined;\n }\n\n const info = new JpegInfo();\n\n let hasSOF = false;\n let hasSOS = false;\n\n marker = this.nextMarker();\n while (marker !== Jpeg.M_EOI && !this._input.isEOS) {\n // EOI (End of image)\n switch (marker) {\n // SOF0 (Start of Frame, Baseline DCT)\n case Jpeg.M_SOF0:\n // SOF1 (Start of Frame, Extended DCT)\n // falls through\n case Jpeg.M_SOF1:\n // SOF2 (Start of Frame, Progressive DCT)\n // falls through\n case Jpeg.M_SOF2:\n hasSOF = true;\n this.readFrame(marker, this.readBlock());\n break;\n // SOS (Start of Scan)\n case Jpeg.M_SOS:\n hasSOS = true;\n this.skipBlock();\n break;\n default:\n this.skipBlock();\n break;\n }\n\n marker = this.nextMarker();\n }\n\n if (this._frame !== undefined) {\n info.setSize(this._frame.samplesPerLine, this._frame.scanLines);\n this._frame = undefined;\n }\n\n this.frames.length = 0;\n\n return hasSOF && hasSOS ? info : undefined;\n }\n\n public read(bytes: Uint8Array): void {\n this._input = new InputBuffer({\n buffer: bytes,\n bigEndian: true,\n });\n\n this.readMarkers();\n\n if (this._frames.length !== 1) {\n throw new ImageError('Only single frame JPEGs supported');\n }\n\n if (this._frame !== undefined) {\n for (let i = 0; i < this._frame.componentsOrder.length; ++i) {\n const component = this._frame.components.get(\n this._frame.componentsOrder[i]\n );\n if (component !== undefined) {\n this.components.push(\n new ComponentData(\n component.hSamples,\n this._frame.maxHSamples,\n component.vSamples,\n this._frame.maxVSamples,\n JpegData.buildComponentData(component)\n )\n );\n }\n }\n }\n }\n\n getImage(): MemoryImage {\n return JpegQuantize.getImageFromJpeg(this);\n }\n\n private static buildHuffmanTable(\n codeLengths: Uint8Array,\n values: Uint8Array\n ): Array {\n let k = 0;\n const code = new Array();\n let length = 16;\n\n while (length > 0 && codeLengths[length - 1] === 0) {\n length--;\n }\n\n code.push(new JpegHuffman());\n\n let p: JpegHuffman = code[0];\n for (let i = 0; i < length; i++) {\n for (let j = 0; j < codeLengths[i]; j++) {\n p = code.pop()!;\n if (p.children.length <= p.index) {\n p.children.length = p.index + 1;\n }\n p.children[p.index] = values[k];\n while (p.index > 0) {\n p = code.pop()!;\n }\n p.incrementIndex();\n code.push(p);\n while (code.length <= i) {\n const q = new JpegHuffman();\n code.push(q);\n if (p.children.length <= p.index) {\n p.children.length = p.index + 1;\n }\n p.children[p.index] = q.children;\n p = q;\n }\n k++;\n }\n\n if (i + 1 < length) {\n // P here points to last code\n const q = new JpegHuffman();\n code.push(q);\n if (p.children.length <= p.index) {\n p.children.length = p.index + 1;\n }\n p.children[p.index] = q.children;\n p = q;\n }\n }\n\n return code[0].children;\n }\n\n private static buildComponentData(\n component: JpegComponent\n ): Array {\n const blocksPerLine = component.blocksPerLine;\n const blocksPerColumn = component.blocksPerColumn;\n const samplesPerLine = blocksPerLine << 3;\n const R = new Int32Array(64);\n const r = new Uint8Array(64);\n const lines = new Array(blocksPerColumn * 8);\n\n let l = 0;\n for (let blockRow = 0; blockRow < blocksPerColumn; blockRow++) {\n const scanLine = blockRow << 3;\n for (let i = 0; i < 8; i++) {\n lines[l++] = new Uint8Array(samplesPerLine);\n }\n\n for (let blockCol = 0; blockCol < blocksPerLine; blockCol++) {\n JpegQuantize.quantizeAndInverse(\n component.quantizationTable!,\n component.blocks[blockRow][blockCol],\n r,\n R\n );\n\n let offset = 0;\n const sample = blockCol << 3;\n for (let j = 0; j < 8; j++) {\n const line = lines[scanLine + j];\n for (let i = 0; i < 8; i++) {\n line[sample + i] = r[offset++];\n }\n }\n }\n }\n\n return lines;\n }\n\n public static toFix(val: number): number {\n const FIXED_POINT = 20;\n const ONE = 1 << FIXED_POINT;\n return Math.trunc(val * ONE) & 0xffffffff;\n }\n\n private readBlock(): InputBuffer {\n const length = this._input.readUint16();\n if (length < 2) {\n throw new ImageError('Invalid Block');\n }\n return this._input.readBytes(length - 2);\n }\n\n private nextMarker(): number {\n let c = 0;\n if (this._input.isEOS) {\n return c;\n }\n\n do {\n do {\n c = this._input.readByte();\n } while (c !== 0xff && !this._input.isEOS);\n\n if (this._input.isEOS) {\n return c;\n }\n\n do {\n c = this._input.readByte();\n } while (c === 0xff && !this._input.isEOS);\n } while (c === 0 && !this._input.isEOS);\n\n return c;\n }\n\n private readExifData(block: InputBuffer): void {\n // Exif Header\n // Exif\\0\\0\n const exifSignature = 0x45786966;\n const signature = block.readUint32();\n if (signature !== exifSignature) {\n return;\n }\n if (block.readUint16() !== 0) {\n return;\n }\n\n this.exifData.read(block);\n }\n\n private readAppData(marker: number, block: InputBuffer): void {\n const appData = block;\n\n if (marker === Jpeg.M_APP0) {\n // 'JFIF\\0'\n if (\n appData.getByte(0) === 0x4a &&\n appData.getByte(1) === 0x46 &&\n appData.getByte(2) === 0x49 &&\n appData.getByte(3) === 0x46 &&\n appData.getByte(4) === 0\n ) {\n const majorVersion = appData.getByte(5);\n const minorVersion = appData.getByte(6);\n const densityUnits = appData.getByte(7);\n const xDensity = (appData.getByte(8) << 8) | appData.getByte(9);\n const yDensity = (appData.getByte(10) << 8) | appData.getByte(11);\n const thumbWidth = appData.getByte(12);\n const thumbHeight = appData.getByte(13);\n\n const thumbSize = 3 * thumbWidth * thumbHeight;\n const thumbData = appData.subarray(14 + thumbSize, undefined, 14);\n\n this._jfif = new JpegJfif(\n thumbWidth,\n thumbHeight,\n majorVersion,\n minorVersion,\n densityUnits,\n xDensity,\n yDensity,\n thumbData\n );\n }\n } else if (marker === Jpeg.M_APP1) {\n // 'EXIF\\0'\n this.readExifData(appData);\n } else if (marker === Jpeg.M_APP14) {\n // 'Adobe\\0'\n if (\n appData.getByte(0) === 0x41 &&\n appData.getByte(1) === 0x64 &&\n appData.getByte(2) === 0x6f &&\n appData.getByte(3) === 0x62 &&\n appData.getByte(4) === 0x65 &&\n appData.getByte(5) === 0\n ) {\n const version = appData.getByte(6);\n const flags0 = (appData.getByte(7) << 8) | appData.getByte(8);\n const flags1 = (appData.getByte(9) << 8) | appData.getByte(10);\n const transformCode = appData.getByte(11);\n this._adobe = new JpegAdobe(version, flags0, flags1, transformCode);\n }\n } else if (marker === Jpeg.M_COM) {\n // Comment\n try {\n this._comment = appData.readStringUtf8();\n } catch (_) {\n // ReadString without 0x00 terminator causes exception. Technically\n // bad data, but no reason to abort the rest of the image decoding.\n }\n }\n }\n\n private readDQT(block: InputBuffer): void {\n while (!block.isEOS) {\n let n = block.readByte();\n const prec = n >> 4;\n n &= 0x0f;\n\n if (n >= Jpeg.NUM_QUANT_TBLS) {\n throw new ImageError('Invalid number of quantization tables');\n }\n\n if (this._quantizationTables[n] === undefined) {\n this._quantizationTables[n] = new Int16Array(64);\n }\n\n const tableData = this._quantizationTables[n];\n if (tableData !== undefined) {\n for (let i = 0; i < Jpeg.DCTSIZE2; i++) {\n const tmp: number =\n prec !== 0 ? block.readUint16() : block.readByte();\n tableData[Jpeg.dctZigZag[i]] = tmp;\n }\n }\n }\n\n if (!block.isEOS) {\n throw new ImageError('Bad length for DQT block');\n }\n }\n\n private readFrame(marker: number, block: InputBuffer): void {\n if (this._frame !== undefined) {\n throw new ImageError('Duplicate JPG frame data found.');\n }\n\n const extended = marker === Jpeg.M_SOF1;\n const progressive = marker === Jpeg.M_SOF2;\n const precision = block.readByte();\n const scanLines = block.readUint16();\n const samplesPerLine = block.readUint16();\n\n const numComponents = block.readByte();\n const components = new Map();\n const componentsOrder = new Array();\n for (let i = 0; i < numComponents; i++) {\n const componentId = block.readByte();\n const x = block.readByte();\n const h = (x >> 4) & 15;\n const v = x & 15;\n const qId = block.readByte();\n componentsOrder.push(componentId);\n const component = new JpegComponent(h, v, this._quantizationTables, qId);\n components.set(componentId, component);\n }\n\n this._frame = new JpegFrame(\n components,\n componentsOrder,\n extended,\n progressive,\n precision,\n scanLines,\n samplesPerLine\n );\n\n this._frame.prepare();\n\n this.frames.push(this._frame);\n }\n\n private readDHT(block: InputBuffer): void {\n while (!block.isEOS) {\n let index = block.readByte();\n\n const bits = new Uint8Array(16);\n let count = 0;\n for (let j = 0; j < 16; j++) {\n bits[j] = block.readByte();\n count += bits[j];\n }\n\n const huffmanValues = new Uint8Array(count);\n for (let j = 0; j < count; j++) {\n huffmanValues[j] = block.readByte();\n }\n\n let ht: Array = [];\n if ((index & 0x10) !== 0) {\n // AC table definition\n index -= 0x10;\n ht = this._huffmanTablesAC;\n } else {\n // DC table definition\n ht = this._huffmanTablesDC;\n }\n\n if (ht.length <= index) {\n ht.length = index + 1;\n }\n\n ht[index] = JpegData.buildHuffmanTable(bits, huffmanValues);\n }\n }\n\n private readDRI(block: InputBuffer): void {\n this._resetInterval = block.readUint16();\n }\n\n private readSOS(block: InputBuffer): void {\n const n = block.readByte();\n if (n < 1 || n > Jpeg.MAX_COMPS_IN_SCAN) {\n throw new ImageError('Invalid SOS block');\n }\n\n const components = new Array();\n for (let i = 0; i < n; i++) {\n const id = block.readByte();\n const c = block.readByte();\n\n if (!this._frame!.components.has(id)) {\n throw new ImageError('Invalid Component in SOS block');\n }\n const component = this._frame!.components.get(id);\n if (component !== undefined) {\n const dcTableNumber = (c >> 4) & 15;\n const acTableNumber = c & 15;\n if (dcTableNumber < this._huffmanTablesDC.length) {\n component.huffmanTableDC = this._huffmanTablesDC[dcTableNumber]!;\n }\n if (acTableNumber < this._huffmanTablesAC.length) {\n component.huffmanTableAC = this._huffmanTablesAC[acTableNumber]!;\n }\n components.push(component);\n }\n }\n\n const spectralStart = block.readByte();\n const spectralEnd = block.readByte();\n const successiveApproximation = block.readByte();\n\n const Ah = (successiveApproximation >> 4) & 15;\n const Al = successiveApproximation & 15;\n\n const scan = new JpegScan(\n this._input,\n this._frame!,\n components,\n spectralStart,\n spectralEnd,\n Ah,\n Al,\n this._resetInterval\n );\n scan.decode();\n }\n}\n", "/** @format */\n\nimport { FrameAnimation } from '../common/frame-animation';\nimport { InputBuffer } from '../common/input-buffer';\nimport { MemoryImage } from '../common/memory-image';\nimport { ImageError } from '../error/image-error';\nimport { HdrImage } from '../hdr/hdr-image';\nimport { Decoder } from './decoder';\nimport { JpegData } from './jpeg/jpeg-data';\nimport { JpegInfo } from './jpeg/jpeg-info';\n\n/**\n * Decode a jpeg encoded image.\n */\nexport class JpegDecoder implements Decoder {\n private info?: JpegInfo;\n\n private input?: InputBuffer;\n\n public get numFrames(): number {\n return this.info !== undefined ? this.info.numFrames : 0;\n }\n\n /**\n * Is the given file a valid JPEG image?\n */\n public isValidFile(bytes: Uint8Array): boolean {\n return new JpegData().validate(bytes);\n }\n\n public startDecode(bytes: Uint8Array): JpegInfo | undefined {\n this.input = new InputBuffer({\n buffer: bytes,\n bigEndian: true,\n });\n this.info = new JpegData().readInfo(bytes);\n return this.info;\n }\n\n public decodeFrame(_: number): MemoryImage | undefined {\n if (this.input === undefined) {\n return undefined;\n }\n const jpeg = new JpegData();\n jpeg.read(this.input.buffer);\n if (jpeg.frames.length !== 1) {\n throw new ImageError('only single frame JPEGs supported');\n }\n\n return jpeg.getImage();\n }\n\n public decodeHdrFrame(frame: number): HdrImage | undefined {\n const img = this.decodeFrame(frame);\n if (img === undefined) {\n return undefined;\n }\n return HdrImage.fromImage(img);\n }\n\n public decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined {\n const image = this.decodeImage(bytes);\n if (image === undefined) {\n return undefined;\n }\n\n const animation = new FrameAnimation({\n width: image.width,\n height: image.height,\n });\n animation.addFrame(image);\n\n return animation;\n }\n\n public decodeImage(bytes: Uint8Array, _?: number): MemoryImage | undefined {\n const jpeg = new JpegData();\n jpeg.read(bytes);\n\n if (jpeg.frames.length !== 1) {\n throw new ImageError('only single frame JPEGs supported');\n }\n\n return jpeg.getImage();\n }\n\n public decodeHdrImage(bytes: Uint8Array, frame = 0): HdrImage | undefined {\n const img = this.decodeImage(bytes, frame);\n if (img === undefined) {\n return undefined;\n }\n return HdrImage.fromImage(img);\n }\n}\n", "/** @format */\n\nimport { FrameAnimation } from '../common/frame-animation';\nimport { MathOperators } from '../common/math-operators';\nimport { MemoryImage } from '../common/memory-image';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { ExifData } from '../exif/exif-data';\nimport { Encoder } from './encoder';\nimport { Jpeg } from './jpeg/jpeg';\n\n/**\n * Encode an image to the JPEG format.\n */\nexport class JpegEncoder implements Encoder {\n private static readonly ZIGZAG: number[] = [\n 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25,\n 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54,\n 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48,\n 49, 57, 58, 62, 63,\n ];\n\n private static readonly STD_DC_LUMINANCE_NR_CODES: number[] = [\n 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,\n ];\n\n private static readonly STD_DC_LUMINANCE_VALUES: number[] = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\n ];\n\n private static readonly STD_AC_LUMINANCE_NR_CODES: number[] = [\n 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d,\n ];\n\n private static readonly STD_AC_LUMINANCE_VALUES: number[] = [\n 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,\n 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,\n 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,\n 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,\n 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,\n 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,\n 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75,\n 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,\n 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,\n 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,\n 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,\n 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,\n 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4,\n 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,\n ];\n\n private static readonly STD_DC_CHROMINANCE_NR_CODES: number[] = [\n 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,\n ];\n\n private static readonly STD_DC_CHROMINANCE_VALUES: number[] = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\n ];\n\n private static readonly STD_AC_CHROMINANCE_NR_CODES: number[] = [\n 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77,\n ];\n\n private static readonly STD_AC_CHROMINANCE_VALUES: number[] = [\n 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,\n 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,\n 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,\n 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,\n 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44,\n 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,\n 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74,\n 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,\n 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,\n 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,\n 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,\n 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,\n 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,\n 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,\n ];\n\n private readonly tableY = new Uint8Array(64);\n private readonly tableUV = new Uint8Array(64);\n private readonly ftableY = new Float32Array(64);\n private readonly ftableUV = new Float32Array(64);\n\n private readonly bitcode = new Array | undefined>(65535).fill(\n undefined\n );\n private readonly category = new Array(65535).fill(\n undefined\n );\n private readonly outputfDCTQuant = new Array(64).fill(\n undefined\n );\n private readonly DU = new Array(64).fill(undefined);\n\n private readonly YDU: Float32Array = new Float32Array(64);\n private readonly UDU: Float32Array = new Float32Array(64);\n private readonly VDU: Float32Array = new Float32Array(64);\n private readonly tableRGBYUV: Int32Array = new Int32Array(2048);\n\n private htYDC: Array | undefined> | undefined;\n private htUVDC: Array | undefined> | undefined;\n private htYAC!: Array | undefined>;\n private htUVAC!: Array | undefined>;\n\n private currentQuality?: number;\n\n private byteNew = 0;\n private bytePos = 7;\n\n private _supportsAnimation = false;\n public get supportsAnimation(): boolean {\n return this._supportsAnimation;\n }\n\n constructor(quality = 100) {\n this.initHuffmanTable();\n this.initCategoryNumber();\n this.initRGBYUVTable();\n this.setQuality(quality);\n }\n\n private static computeHuffmanTable(\n nrcodes: number[],\n stdTable: number[]\n ): Array | undefined> {\n let codevalue = 0;\n let posInTable = 0;\n const HT = new Array | undefined>();\n for (let k = 1; k <= 16; k++) {\n for (let j = 1; j <= nrcodes[k]; j++) {\n const index = stdTable[posInTable];\n if (HT.length <= index) {\n HT.length = index + 1;\n }\n HT[index] = [codevalue, k];\n posInTable++;\n codevalue++;\n }\n codevalue *= 2;\n }\n return HT;\n }\n\n private static writeMarker(fp: OutputBuffer, marker: number): void {\n fp.writeByte(0xff);\n fp.writeByte(marker & 0xff);\n }\n\n private static writeAPP0(out: OutputBuffer): void {\n JpegEncoder.writeMarker(out, Jpeg.M_APP0);\n // Length\n out.writeUint16(16);\n // J\n out.writeByte(0x4a);\n // F\n out.writeByte(0x46);\n // I\n out.writeByte(0x49);\n // F\n out.writeByte(0x46);\n // '\\0'\n out.writeByte(0);\n // versionhi\n out.writeByte(1);\n // versionlo\n out.writeByte(1);\n // xyunits\n out.writeByte(0);\n // xdensity\n out.writeUint16(1);\n // ydensity\n out.writeUint16(1);\n // thumbnwidth\n out.writeByte(0);\n // thumbnheight\n out.writeByte(0);\n }\n\n private static writeAPP1(out: OutputBuffer, exif: ExifData): void {\n if (exif.isEmpty) {\n return;\n }\n\n const exifData = new OutputBuffer();\n exif.write(exifData);\n const exifBytes = exifData.getBytes();\n\n this.writeMarker(out, Jpeg.M_APP1);\n out.writeUint16(exifBytes.length + 8);\n // Exif\\0\\0\n const exifSignature = 0x45786966;\n out.writeUint32(exifSignature);\n out.writeUint16(0);\n out.writeBytes(exifBytes);\n }\n\n private static writeSOF0(\n out: OutputBuffer,\n width: number,\n height: number\n ): void {\n JpegEncoder.writeMarker(out, Jpeg.M_SOF0);\n // Length, truecolor YUV JPG\n out.writeUint16(17);\n // Precision\n out.writeByte(8);\n out.writeUint16(height);\n out.writeUint16(width);\n // nrofcomponents\n out.writeByte(3);\n // IdY\n out.writeByte(1);\n // HVY\n out.writeByte(0x11);\n // QTY\n out.writeByte(0);\n // IdU\n out.writeByte(2);\n // HVU\n out.writeByte(0x11);\n // QTU\n out.writeByte(1);\n // IdV\n out.writeByte(3);\n // HVV\n out.writeByte(0x11);\n // QTV\n out.writeByte(1);\n }\n\n private static writeSOS(out: OutputBuffer): void {\n JpegEncoder.writeMarker(out, Jpeg.M_SOS);\n // Length\n out.writeUint16(12);\n // Nrofcomponents\n out.writeByte(3);\n // IdY\n out.writeByte(1);\n // HTY\n out.writeByte(0);\n // IdU\n out.writeByte(2);\n // HTU\n out.writeByte(0x11);\n // IdV\n out.writeByte(3);\n // HTV\n out.writeByte(0x11);\n // Ss\n out.writeByte(0);\n // Se\n out.writeByte(0x3f);\n // Bf\n out.writeByte(0);\n }\n\n private static writeDHT(out: OutputBuffer): void {\n JpegEncoder.writeMarker(out, Jpeg.M_DHT);\n // Length\n out.writeUint16(0x01a2);\n\n // HTYDCinfo\n out.writeByte(0);\n for (let i = 0; i < 16; i++) {\n out.writeByte(JpegEncoder.STD_DC_LUMINANCE_NR_CODES[i + 1]);\n }\n for (let j = 0; j <= 11; j++) {\n out.writeByte(JpegEncoder.STD_DC_LUMINANCE_VALUES[j]);\n }\n\n // HTYACinfo\n out.writeByte(0x10);\n for (let k = 0; k < 16; k++) {\n out.writeByte(JpegEncoder.STD_AC_LUMINANCE_NR_CODES[k + 1]);\n }\n for (let l = 0; l <= 161; l++) {\n out.writeByte(JpegEncoder.STD_AC_LUMINANCE_VALUES[l]);\n }\n\n // HTUDCinfo\n out.writeByte(1);\n for (let m = 0; m < 16; m++) {\n out.writeByte(JpegEncoder.STD_DC_CHROMINANCE_NR_CODES[m + 1]);\n }\n for (let n = 0; n <= 11; n++) {\n out.writeByte(JpegEncoder.STD_DC_CHROMINANCE_VALUES[n]);\n }\n\n // HTUACinfo\n out.writeByte(0x11);\n for (let o = 0; o < 16; o++) {\n out.writeByte(JpegEncoder.STD_AC_CHROMINANCE_NR_CODES[o + 1]);\n }\n for (let p = 0; p <= 161; p++) {\n out.writeByte(JpegEncoder.STD_AC_CHROMINANCE_VALUES[p]);\n }\n }\n\n private initHuffmanTable(): void {\n this.htYDC = JpegEncoder.computeHuffmanTable(\n JpegEncoder.STD_DC_LUMINANCE_NR_CODES,\n JpegEncoder.STD_DC_LUMINANCE_VALUES\n );\n this.htUVDC = JpegEncoder.computeHuffmanTable(\n JpegEncoder.STD_DC_CHROMINANCE_NR_CODES,\n JpegEncoder.STD_DC_CHROMINANCE_VALUES\n );\n this.htYAC = JpegEncoder.computeHuffmanTable(\n JpegEncoder.STD_AC_LUMINANCE_NR_CODES,\n JpegEncoder.STD_AC_LUMINANCE_VALUES\n );\n this.htUVAC = JpegEncoder.computeHuffmanTable(\n JpegEncoder.STD_AC_CHROMINANCE_NR_CODES,\n JpegEncoder.STD_AC_CHROMINANCE_VALUES\n );\n }\n\n private initCategoryNumber(): void {\n let nrlower = 1;\n let nrupper = 2;\n for (let cat = 1; cat <= 15; cat++) {\n // Positive numbers\n for (let nr = nrlower; nr < nrupper; nr++) {\n this.category[32767 + nr] = cat;\n this.bitcode[32767 + nr] = [nr, cat];\n }\n // Negative numbers\n for (let nrneg = -(nrupper - 1); nrneg <= -nrlower; nrneg++) {\n this.category[32767 + nrneg] = cat;\n this.bitcode[32767 + nrneg] = [nrupper - 1 + nrneg, cat];\n }\n nrlower <<= 1;\n nrupper <<= 1;\n }\n }\n\n private initRGBYUVTable(): void {\n for (let i = 0; i < 256; i++) {\n this.tableRGBYUV[i] = 19595 * i;\n this.tableRGBYUV[i + 256] = 38470 * i;\n this.tableRGBYUV[i + 512] = 7471 * i + 0x8000;\n this.tableRGBYUV[i + 768] = -11059 * i;\n this.tableRGBYUV[i + 1024] = -21709 * i;\n this.tableRGBYUV[i + 1280] = 32768 * i + 0x807fff;\n this.tableRGBYUV[i + 1536] = -27439 * i;\n this.tableRGBYUV[i + 1792] = -5329 * i;\n }\n }\n\n private setQuality(quality: number): void {\n const q = MathOperators.clampInt(quality, 1, 100);\n\n if (this.currentQuality === q) {\n // Don't re-calc if unchanged\n return;\n }\n\n let sf = 0;\n if (q < 50) {\n sf = Math.floor(5000 / q);\n } else {\n sf = Math.floor(200 - q * 2);\n }\n\n this.initQuantTables(sf);\n this.currentQuality = q;\n }\n\n private initQuantTables(sf: number): void {\n const YQT: number[] = [\n 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13,\n 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56,\n 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103,\n 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99,\n ];\n\n for (let i = 0; i < 64; i++) {\n let t = Math.floor((YQT[i] * sf + 50) / 100);\n if (t < 1) {\n t = 1;\n } else if (t > 255) {\n t = 255;\n }\n this.tableY[JpegEncoder.ZIGZAG[i]] = t;\n }\n\n const UVQT: number[] = [\n 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26,\n 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,\n 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,\n 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,\n ];\n\n for (let j = 0; j < 64; j++) {\n let u = Math.floor((UVQT[j] * sf + 50) / 100);\n if (u < 1) {\n u = 1;\n } else if (u > 255) {\n u = 255;\n }\n this.tableUV[JpegEncoder.ZIGZAG[j]] = u;\n }\n\n const aasf: number[] = [\n 1.0, 1.387039845, 1.306562965, 1.175875602, 1.0, 0.785694958, 0.5411961,\n 0.275899379,\n ];\n\n let k = 0;\n for (let row = 0; row < 8; row++) {\n for (let col = 0; col < 8; col++) {\n this.ftableY[k] =\n 1.0 /\n (this.tableY[JpegEncoder.ZIGZAG[k]] * aasf[row] * aasf[col] * 8.0);\n this.ftableUV[k] =\n 1.0 /\n (this.tableUV[JpegEncoder.ZIGZAG[k]] * aasf[row] * aasf[col] * 8.0);\n k++;\n }\n }\n }\n\n // DCT & quantization core\n private fDCTQuant(\n data: Float32Array,\n fdtbl: Float32Array\n ): Array {\n // Pass 1: process rows.\n let dataOff = 0;\n const I8 = 8;\n const I64 = 64;\n for (let i = 0; i < I8; ++i) {\n const d0 = data[dataOff];\n const d1 = data[dataOff + 1];\n const d2 = data[dataOff + 2];\n const d3 = data[dataOff + 3];\n const d4 = data[dataOff + 4];\n const d5 = data[dataOff + 5];\n const d6 = data[dataOff + 6];\n const d7 = data[dataOff + 7];\n\n const tmp0 = d0 + d7;\n const tmp7 = d0 - d7;\n const tmp1 = d1 + d6;\n const tmp6 = d1 - d6;\n const tmp2 = d2 + d5;\n const tmp5 = d2 - d5;\n const tmp3 = d3 + d4;\n const tmp4 = d3 - d4;\n\n // Even part\n // Phase 2\n let tmp10 = tmp0 + tmp3;\n const tmp13 = tmp0 - tmp3;\n let tmp11 = tmp1 + tmp2;\n let tmp12 = tmp1 - tmp2;\n\n // Phase 3\n data[dataOff] = tmp10 + tmp11;\n data[dataOff + 4] = tmp10 - tmp11;\n\n // C4\n const z1 = (tmp12 + tmp13) * 0.707106781;\n // Phase 5\n data[dataOff + 2] = tmp13 + z1;\n data[dataOff + 6] = tmp13 - z1;\n\n // Odd part\n // Phase 2\n tmp10 = tmp4 + tmp5;\n tmp11 = tmp5 + tmp6;\n tmp12 = tmp6 + tmp7;\n\n // The rotator is modified from fig 4-8 to avoid extra negations.\n // c6\n const z5 = (tmp10 - tmp12) * 0.382683433;\n // c2 - c6\n const z2 = 0.5411961 * tmp10 + z5;\n // c2 + c6\n const z4 = 1.306562965 * tmp12 + z5;\n // c4\n const z3 = tmp11 * 0.707106781;\n\n // Phase 5\n const z11 = tmp7 + z3;\n const z13 = tmp7 - z3;\n\n // Phase 6\n data[dataOff + 5] = z13 + z2;\n data[dataOff + 3] = z13 - z2;\n data[dataOff + 1] = z11 + z4;\n data[dataOff + 7] = z11 - z4;\n\n // Advance pointer to next row\n dataOff += 8;\n }\n\n // Pass 2: process columns.\n dataOff = 0;\n for (let i = 0; i < I8; ++i) {\n const d0 = data[dataOff];\n const d1 = data[dataOff + 8];\n const d2 = data[dataOff + 16];\n const d3 = data[dataOff + 24];\n const d4 = data[dataOff + 32];\n const d5 = data[dataOff + 40];\n const d6 = data[dataOff + 48];\n const d7 = data[dataOff + 56];\n\n const tmp0p2 = d0 + d7;\n const tmp7p2 = d0 - d7;\n const tmp1p2 = d1 + d6;\n const tmp6p2 = d1 - d6;\n const tmp2p2 = d2 + d5;\n const tmp5p2 = d2 - d5;\n const tmp3p2 = d3 + d4;\n const tmp4p2 = d3 - d4;\n\n // Even part\n // Phase 2\n let tmp10p2 = tmp0p2 + tmp3p2;\n const tmp13p2 = tmp0p2 - tmp3p2;\n let tmp11p2 = tmp1p2 + tmp2p2;\n let tmp12p2 = tmp1p2 - tmp2p2;\n\n // Phase 3\n data[dataOff] = tmp10p2 + tmp11p2;\n data[dataOff + 32] = tmp10p2 - tmp11p2;\n\n // c4\n const z1p2 = (tmp12p2 + tmp13p2) * 0.707106781;\n // Phase 5\n data[dataOff + 16] = tmp13p2 + z1p2;\n data[dataOff + 48] = tmp13p2 - z1p2;\n\n // Odd part\n // Phase 2\n tmp10p2 = tmp4p2 + tmp5p2;\n tmp11p2 = tmp5p2 + tmp6p2;\n tmp12p2 = tmp6p2 + tmp7p2;\n\n // The rotator is modified from fig 4-8 to avoid extra negations.\n // c6\n const z5p2 = (tmp10p2 - tmp12p2) * 0.382683433;\n // c2 - c6\n const z2p2 = 0.5411961 * tmp10p2 + z5p2;\n // c2 + c6\n const z4p2 = 1.306562965 * tmp12p2 + z5p2;\n // c4\n const z3p2 = tmp11p2 * 0.707106781;\n // Phase 5\n const z11p2 = tmp7p2 + z3p2;\n const z13p2 = tmp7p2 - z3p2;\n\n // Phase 6\n data[dataOff + 40] = z13p2 + z2p2;\n data[dataOff + 24] = z13p2 - z2p2;\n data[dataOff + 8] = z11p2 + z4p2;\n data[dataOff + 56] = z11p2 - z4p2;\n\n // Advance pointer to next column\n dataOff++;\n }\n\n // Quantize/descale the coefficients\n for (let i = 0; i < I64; ++i) {\n // Apply the quantization and scaling factor & Round to nearest integer\n const fDCTQuant = data[i] * fdtbl[i];\n this.outputfDCTQuant[i] =\n fDCTQuant > 0.0\n ? Math.trunc(fDCTQuant + 0.5)\n : Math.trunc(fDCTQuant - 0.5);\n }\n\n return this.outputfDCTQuant;\n }\n\n private writeDQT(out: OutputBuffer): void {\n JpegEncoder.writeMarker(out, Jpeg.M_DQT);\n // Length\n out.writeUint16(132);\n out.writeByte(0);\n for (let i = 0; i < 64; i++) {\n out.writeByte(this.tableY[i]);\n }\n out.writeByte(1);\n for (let j = 0; j < 64; j++) {\n out.writeByte(this.tableUV[j]);\n }\n }\n\n private writeBits(out: OutputBuffer, bits: number[]): void {\n const value = bits[0];\n let posval = bits[1] - 1;\n while (posval >= 0) {\n if ((value & (1 << posval)) !== 0) {\n this.byteNew |= 1 << this.bytePos;\n }\n posval--;\n this.bytePos--;\n if (this.bytePos < 0) {\n if (this.byteNew === 0xff) {\n out.writeByte(0xff);\n out.writeByte(0);\n } else {\n out.writeByte(this.byteNew);\n }\n this.bytePos = 7;\n this.byteNew = 0;\n }\n }\n }\n\n private resetBits(): void {\n this.byteNew = 0;\n this.bytePos = 7;\n }\n\n private processDU(\n out: OutputBuffer,\n CDU: Float32Array,\n fdtbl: Float32Array,\n DC: number,\n HTAC: Array | undefined>,\n HTDC?: Array | undefined>\n ): number | undefined {\n const EOB = HTAC[0x00];\n const M16zeroes = HTAC[0xf0];\n const I16 = 16;\n const I63 = 63;\n const I64 = 64;\n const DU_DCT = this.fDCTQuant(CDU, fdtbl);\n let dc = DC;\n let pos = 0;\n\n // ZigZag reorder\n for (let j = 0; j < I64; ++j) {\n this.DU[JpegEncoder.ZIGZAG[j]] = DU_DCT[j];\n }\n\n const Diff = this.DU[0]! - dc;\n dc = this.DU[0]!;\n // Encode DC\n if (Diff === 0) {\n // Diff might be 0\n this.writeBits(out, HTDC![0]!);\n } else {\n pos = 32767 + Diff;\n this.writeBits(out, HTDC![this.category[pos]!]!);\n this.writeBits(out, this.bitcode[pos]!);\n }\n\n // Encode ACs\n let end0pos = 63;\n // eslint-disable-next-line no-empty\n for (; end0pos > 0 && this.DU[end0pos] === 0; end0pos--) {}\n //End0pos = first element in reverse order !=0\n if (end0pos === 0) {\n this.writeBits(out, EOB!);\n return dc;\n }\n\n let i = 1;\n while (i <= end0pos) {\n const startpos = i;\n // eslint-disable-next-line no-empty\n for (; this.DU[i] === 0 && i <= end0pos; ++i) {}\n\n let nrzeroes = i - startpos;\n if (nrzeroes >= I16) {\n const lng = nrzeroes >> 4;\n for (let nrmarker = 1; nrmarker <= lng; ++nrmarker) {\n this.writeBits(out, M16zeroes!);\n }\n nrzeroes &= 0xf;\n }\n pos = 32767 + this.DU[i]!;\n this.writeBits(out, HTAC[(nrzeroes << 4) + this.category[pos]!]!);\n this.writeBits(out, this.bitcode[pos]!);\n i++;\n }\n\n if (end0pos !== I63) {\n this.writeBits(out, EOB!);\n }\n\n return dc;\n }\n\n public encodeImage(image: MemoryImage): Uint8Array {\n const fp = new OutputBuffer({\n bigEndian: true,\n });\n\n // Add JPEG headers\n JpegEncoder.writeMarker(fp, Jpeg.M_SOI);\n JpegEncoder.writeAPP0(fp);\n JpegEncoder.writeAPP1(fp, image.exifData);\n this.writeDQT(fp);\n JpegEncoder.writeSOF0(fp, image.width, image.height);\n JpegEncoder.writeDHT(fp);\n JpegEncoder.writeSOS(fp);\n\n // Encode 8x8 macroblocks\n let DCY: number | undefined = 0;\n let DCU: number | undefined = 0;\n let DCV: number | undefined = 0;\n\n this.resetBits();\n\n const width = image.width;\n const height = image.height;\n\n const imageData = image.getBytes();\n const quadWidth = width * 4;\n // Let tripleWidth: number = width * 3;\n // let first: Boolean = true;\n\n let y = 0;\n while (y < height) {\n let x = 0;\n while (x < quadWidth) {\n const start = quadWidth * y + x;\n for (let pos = 0; pos < 64; pos++) {\n // / 8\n const row = pos >> 3;\n // % 8\n const col = (pos & 7) * 4;\n let p = start + row * quadWidth + col;\n\n if (y + row >= height) {\n // Padding bottom\n p -= quadWidth * (y + 1 + row - height);\n }\n\n if (x + col >= quadWidth) {\n // Padding right\n p -= x + col - quadWidth + 4;\n }\n\n const r = imageData[p++];\n const g = imageData[p++];\n const b = imageData[p++];\n\n // Calculate YUV values\n this.YDU[pos] =\n ((this.tableRGBYUV[r] +\n this.tableRGBYUV[g + 256] +\n this.tableRGBYUV[b + 512]) >>\n 16) -\n 128.0;\n\n this.UDU[pos] =\n ((this.tableRGBYUV[r + 768] +\n this.tableRGBYUV[g + 1024] +\n this.tableRGBYUV[b + 1280]) >>\n 16) -\n 128.0;\n\n this.VDU[pos] =\n ((this.tableRGBYUV[r + 1280] +\n this.tableRGBYUV[g + 1536] +\n this.tableRGBYUV[b + 1792]) >>\n 16) -\n 128.0;\n }\n\n DCY = this.processDU(\n fp,\n this.YDU,\n this.ftableY,\n DCY!,\n this.htYAC,\n this.htYDC\n );\n DCU = this.processDU(\n fp,\n this.UDU,\n this.ftableUV,\n DCU!,\n this.htUVAC,\n this.htUVDC\n );\n DCV = this.processDU(\n fp,\n this.VDU,\n this.ftableUV,\n DCV!,\n this.htUVAC,\n this.htUVDC\n );\n\n x += 32;\n }\n\n y += 8;\n }\n\n // Do the bit alignment of the EOI marker\n if (this.bytePos >= 0) {\n const fillBits = [(1 << (this.bytePos + 1)) - 1, this.bytePos + 1];\n this.writeBits(fp, fillBits);\n }\n\n JpegEncoder.writeMarker(fp, Jpeg.M_EOI);\n\n return fp.getBytes();\n }\n\n public encodeAnimation(_: FrameAnimation): Uint8Array | undefined {\n return undefined;\n }\n}\n", "/** @format */\n\nimport { DecodeInfo } from '../decode-info';\n\nexport interface TgaInfoInitOptions {\n width?: number;\n height?: number;\n imageOffset?: number;\n bitsPerPixel?: number;\n}\n\nexport class TgaInfo implements DecodeInfo {\n private readonly _width: number = 0;\n public get width(): number {\n return this._width;\n }\n\n protected readonly _height: number = 0;\n public get height(): number {\n return this._height;\n }\n\n private readonly _backgroundColor: number = 0xffffffff;\n public get backgroundColor(): number {\n return this._backgroundColor;\n }\n\n /**\n * The number of frames that can be decoded.\n */\n private readonly _numFrames: number = 1;\n public get numFrames(): number {\n return this._numFrames;\n }\n\n /**\n * Offset in the input file the image data starts at.\n */\n private readonly _imageOffset: number | undefined = undefined;\n public get imageOffset(): number | undefined {\n return this._imageOffset;\n }\n\n /**\n * Bits per pixel.\n */\n private readonly _bitsPerPixel: number | undefined = undefined;\n public get bitsPerPixel(): number | undefined {\n return this._bitsPerPixel;\n }\n\n constructor(options?: TgaInfoInitOptions) {\n this._width = options?.width ?? 0;\n this._height = options?.height ?? 0;\n this._imageOffset = options?.imageOffset ?? undefined;\n this._bitsPerPixel = options?.bitsPerPixel ?? undefined;\n }\n}\n", "/** @format */\n\nimport { Color } from '../common/color';\nimport { FrameAnimation } from '../common/frame-animation';\nimport { InputBuffer } from '../common/input-buffer';\nimport { MemoryImage } from '../common/memory-image';\nimport { RgbChannelSet } from '../common/rgb-channel-set';\nimport { HdrImage } from '../hdr/hdr-image';\nimport { Decoder } from './decoder';\nimport { TgaInfo } from './tga/tga-info';\n\n/**\n * Decode a TGA image. This only supports the 24-bit uncompressed format.\n */\nexport class TgaDecoder implements Decoder {\n private info: TgaInfo | undefined = undefined;\n\n private input: InputBuffer | undefined = undefined;\n\n public get numFrames(): number {\n return this.info !== undefined ? 1 : 0;\n }\n\n /**\n * Is the given file a valid TGA image?\n */\n public isValidFile(bytes: Uint8Array): boolean {\n const input = new InputBuffer({\n buffer: bytes,\n bigEndian: true,\n });\n\n const header = input.readBytes(18);\n if (header.getByte(2) !== 2) {\n return false;\n }\n if (header.getByte(16) !== 24 && header.getByte(16) !== 32) {\n return false;\n }\n\n return true;\n }\n\n public startDecode(bytes: Uint8Array): TgaInfo | undefined {\n this.input = new InputBuffer({\n buffer: bytes,\n bigEndian: true,\n });\n\n const header = this.input.readBytes(18);\n if (header.getByte(2) !== 2) {\n return undefined;\n }\n if (header.getByte(16) !== 24 && header.getByte(16) !== 32) {\n return undefined;\n }\n\n const width =\n (header.getByte(12) & 0xff) | ((header.getByte(13) & 0xff) << 8);\n const height =\n (header.getByte(14) & 0xff) | ((header.getByte(15) & 0xff) << 8);\n const imageOffset = this.input.offset;\n const bitsPerPixel = header.getByte(16);\n\n this.info = new TgaInfo({\n width: width,\n height: height,\n imageOffset: imageOffset,\n bitsPerPixel: bitsPerPixel,\n });\n\n return this.info;\n }\n\n public decodeFrame(_frame: number): MemoryImage | undefined {\n if (this.info === undefined || this.input === undefined) {\n return undefined;\n }\n\n this.input.offset = this.info.imageOffset!;\n const image = new MemoryImage({\n width: this.info.width,\n height: this.info.height,\n rgbChannelSet: RgbChannelSet.rgb,\n });\n for (let y = image.height - 1; y >= 0; --y) {\n for (let x = 0; x < image.width; ++x) {\n const b = this.input.readByte();\n const g = this.input.readByte();\n const r = this.input.readByte();\n const a = this.info.bitsPerPixel === 32 ? this.input.readByte() : 255;\n image.setPixel(x, y, Color.getColor(r, g, b, a));\n }\n }\n\n return image;\n }\n\n public decodeHdrFrame(frame: number): HdrImage | undefined {\n const img = this.decodeFrame(frame);\n if (img === undefined) {\n return undefined;\n }\n return HdrImage.fromImage(img);\n }\n\n public decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined {\n const image = this.decodeImage(bytes);\n if (image === undefined) {\n return undefined;\n }\n\n const animation = new FrameAnimation({\n width: image.width,\n height: image.height,\n });\n\n animation.addFrame(image);\n\n return animation;\n }\n\n public decodeImage(bytes: Uint8Array, frame = 0): MemoryImage | undefined {\n if (this.startDecode(bytes) === undefined) {\n return undefined;\n }\n\n return this.decodeFrame(frame);\n }\n\n public decodeHdrImage(\n bytes: Uint8Array,\n frame?: number | undefined\n ): HdrImage | undefined {\n const img = this.decodeImage(bytes, frame);\n if (img === undefined) {\n return undefined;\n }\n return HdrImage.fromImage(img);\n }\n}\n", "/** @format */\n\nimport { Color } from '../common/color';\nimport { FrameAnimation } from '../common/frame-animation';\nimport { MemoryImage } from '../common/memory-image';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { RgbChannelSet } from '../common/rgb-channel-set';\nimport { Encoder } from './encoder';\n\n/**\n * Encode a TGA image. This only supports the 24-bit uncompressed format.\n */\nexport class TgaEncoder implements Encoder {\n private _supportsAnimation = false;\n public get supportsAnimation(): boolean {\n return this._supportsAnimation;\n }\n\n public encodeImage(image: MemoryImage): Uint8Array {\n const out = new OutputBuffer({\n bigEndian: true,\n });\n\n const header = new Uint8Array(18);\n header.fill(0);\n\n header[2] = 2;\n header[12] = image.width & 0xff;\n header[13] = (image.width >> 8) & 0xff;\n header[14] = image.height & 0xff;\n header[15] = (image.height >> 8) & 0xff;\n header[16] = image.rgbChannelSet === RgbChannelSet.rgb ? 24 : 32;\n\n out.writeBytes(header);\n\n for (let y = image.height - 1; y >= 0; --y) {\n for (let x = 0; x < image.width; ++x) {\n const c = image.getPixel(x, y);\n out.writeByte(Color.getBlue(c));\n out.writeByte(Color.getGreen(c));\n out.writeByte(Color.getRed(c));\n if (image.rgbChannelSet === RgbChannelSet.rgba) {\n out.writeByte(Color.getAlpha(c));\n }\n }\n }\n\n return out.getBytes();\n }\n\n public encodeAnimation(_animation: FrameAnimation): Uint8Array | undefined {\n return undefined;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\n\nexport class TiffBitReader {\n private static readonly BITMASK = [0, 1, 3, 7, 15, 31, 63, 127, 255];\n\n private bitBuffer = 0;\n\n private bitPosition = 0;\n\n private input: InputBuffer;\n\n constructor(input: InputBuffer) {\n this.input = input;\n }\n\n /**\n * Read a number of bits from the input stream.\n */\n public readBits(numBits: number): number {\n let nBits = numBits;\n if (nBits === 0) {\n return 0;\n }\n\n if (this.bitPosition === 0) {\n this.bitPosition = 8;\n this.bitBuffer = this.input.readByte();\n }\n\n let value = 0;\n\n while (nBits > this.bitPosition) {\n value =\n (value << this.bitPosition) +\n (this.bitBuffer & TiffBitReader.BITMASK[this.bitPosition]);\n nBits -= this.bitPosition;\n this.bitPosition = 8;\n this.bitBuffer = this.input.readByte();\n }\n\n if (nBits > 0) {\n if (this.bitPosition === 0) {\n this.bitPosition = 8;\n this.bitBuffer = this.input.readByte();\n }\n\n value =\n (value << nBits) +\n ((this.bitBuffer >> (this.bitPosition - nBits)) &\n TiffBitReader.BITMASK[nBits]);\n\n this.bitPosition -= nBits;\n }\n\n return value;\n }\n\n public readByte() {\n return this.readBits(8);\n }\n\n /**\n * Flush the rest of the bits in the buffer so the next read starts at the next byte.\n */\n public flushByte() {\n return (this.bitPosition = 0);\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { ImageError } from '../../error/image-error';\nimport { TiffImage } from './tiff-image';\n\nexport interface TiffEntryInitOptions {\n tag: number;\n type: number;\n numValues: number;\n p: InputBuffer;\n}\n\nexport class TiffEntry {\n private static readonly SIZE_OF_TYPE: number[] = [\n // 0 = n/a\n 0,\n // 1 = byte\n 1,\n // 2 = ascii\n 1,\n // 3 = short\n 2,\n // 4 = long\n 4,\n // 5 = rational\n 8,\n // 6 = sbyte\n 1,\n // 7 = undefined\n 1,\n // 8 = sshort\n 2,\n // 9 = slong\n 4,\n // 10 = srational\n 8,\n // 11 = float\n 4,\n // 12 = double\n 8, 0,\n ];\n\n public static readonly TYPE_BYTE = 1;\n public static readonly TYPE_ASCII = 2;\n public static readonly TYPE_SHORT = 3;\n public static readonly TYPE_LONG = 4;\n public static readonly TYPE_RATIONAL = 5;\n public static readonly TYPE_SBYTE = 6;\n public static readonly TYPE_UNDEFINED = 7;\n public static readonly TYPE_SSHORT = 8;\n public static readonly TYPE_SLONG = 9;\n public static readonly TYPE_SRATIONAL = 10;\n public static readonly TYPE_FLOAT = 11;\n public static readonly TYPE_DOUBLE = 12;\n\n private _tag: number;\n public get tag(): number {\n return this._tag;\n }\n\n private _type: number;\n public get type(): number {\n return this._type;\n }\n\n private _numValues: number;\n public get numValues(): number {\n return this._numValues;\n }\n\n private _valueOffset: number | undefined;\n public get valueOffset(): number | undefined {\n return this._valueOffset;\n }\n public set valueOffset(v: number | undefined) {\n this._valueOffset = v;\n }\n\n private _p: InputBuffer;\n public get p(): InputBuffer {\n return this._p;\n }\n\n get isValid(): boolean {\n return this._type < 13 && this._type > 0;\n }\n\n get typeSize(): number {\n return this.isValid ? TiffEntry.SIZE_OF_TYPE[this._type] : 0;\n }\n\n get isString(): boolean {\n return this._type === TiffEntry.TYPE_ASCII;\n }\n\n constructor(options: TiffEntryInitOptions) {\n this._tag = options.tag;\n this._type = options.type;\n this._numValues = options.numValues;\n this._p = options.p;\n }\n\n private readValueInternal(): number {\n switch (this._type) {\n case TiffEntry.TYPE_BYTE:\n case TiffEntry.TYPE_ASCII:\n return this._p.readByte();\n case TiffEntry.TYPE_SHORT:\n return this._p.readUint16();\n case TiffEntry.TYPE_LONG:\n return this._p.readUint32();\n case TiffEntry.TYPE_RATIONAL: {\n const num = this._p.readUint32();\n const den = this._p.readUint32();\n if (den === 0) {\n return 0;\n }\n return Math.trunc(num / den);\n }\n case TiffEntry.TYPE_SBYTE:\n throw new ImageError('Unhandled value type: SBYTE');\n case TiffEntry.TYPE_UNDEFINED:\n return this._p.readByte();\n case TiffEntry.TYPE_SSHORT:\n throw new ImageError('Unhandled value type: SSHORT');\n case TiffEntry.TYPE_SLONG:\n throw new ImageError('Unhandled value type: SLONG');\n case TiffEntry.TYPE_SRATIONAL:\n throw new ImageError('Unhandled value type: SRATIONAL');\n case TiffEntry.TYPE_FLOAT:\n throw new ImageError('Unhandled value type: FLOAT');\n case TiffEntry.TYPE_DOUBLE:\n throw new ImageError('Unhandled value type: DOUBLE');\n }\n return 0;\n }\n\n public toString() {\n if (TiffImage.TAG_NAME.has(this._tag)) {\n return `${TiffImage.TAG_NAME.get(this._tag)}: $type $numValues`;\n }\n return `<${this._tag}>: ${this._type} ${this._numValues}`;\n }\n\n public readValue(): number {\n this._p.offset = this._valueOffset!;\n return this.readValueInternal();\n }\n\n public readValues(): number[] {\n this._p.offset = this._valueOffset!;\n const values: number[] = [];\n for (let i = 0; i < this._numValues; ++i) {\n values.push(this.readValueInternal());\n }\n return values;\n }\n\n public readString(): string {\n if (this._type !== TiffEntry.TYPE_ASCII) {\n throw new ImageError('readString requires ASCII entity');\n }\n // TODO: ASCII fields can contain multiple strings, separated with a NULL.\n return String.fromCharCode(...this.readValues());\n }\n\n public read(): number[] {\n this._p.offset = this._valueOffset!;\n const values: number[] = [];\n for (let i = 0; i < this._numValues; ++i) {\n switch (this._type) {\n case TiffEntry.TYPE_BYTE:\n case TiffEntry.TYPE_ASCII:\n values.push(this._p.readByte());\n break;\n case TiffEntry.TYPE_SHORT:\n values.push(this._p.readUint16());\n break;\n case TiffEntry.TYPE_LONG:\n values.push(this._p.readUint32());\n break;\n case TiffEntry.TYPE_RATIONAL: {\n const num = this._p.readUint32();\n const den = this._p.readUint32();\n if (den !== 0) {\n values.push(num / den);\n }\n break;\n }\n case TiffEntry.TYPE_FLOAT:\n values.push(this._p.readFloat32());\n break;\n case TiffEntry.TYPE_DOUBLE:\n values.push(this._p.readFloat64());\n break;\n }\n }\n return values;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { ImageError } from '../../error/image-error';\n\nexport interface TiffFaxDecoderInitOptions {\n fillOrder: number;\n width: number;\n height: number;\n}\n\nexport class TiffFaxDecoder {\n private static readonly TABLE1: number[] = [\n // 0 bits are left in first byte - SHOULD NOT HAPPEN\n 0x00,\n // 1 bits are left in first byte\n 0x01,\n // 2 bits are left in first byte\n 0x03,\n // 3 bits are left in first byte\n 0x07,\n // 4 bits are left in first byte\n 0x0f,\n // 5 bits are left in first byte\n 0x1f,\n // 6 bits are left in first byte\n 0x3f,\n // 7 bits are left in first byte\n 0x7f,\n // 8 bits are left in first byte\n 0xff,\n ];\n\n private static readonly TABLE2: number[] = [\n // 0\n 0x00,\n // 1\n 0x80,\n // 2\n 0xc0,\n // 3\n 0xe0,\n // 4\n 0xf0,\n // 5\n 0xf8,\n // 6\n 0xfc,\n // 7\n 0xfe,\n // 8\n 0xff,\n ];\n\n /**\n * Table to be used when **fillOrder** = 2, for flipping bytes.\n */\n private static readonly FLIP_TABLE: number[] = [\n 0, -128, 64, -64, 32, -96, 96, -32, 16, -112, 80, -48, 48, -80, 112, -16, 8,\n -120, 72, -56, 40, -88, 104, -24, 24, -104, 88, -40, 56, -72, 120, -8, 4,\n -124, 68, -60, 36, -92, 100, -28, 20, -108, 84, -44, 52, -76, 116, -12, 12,\n -116, 76, -52, 44, -84, 108, -20, 28, -100, 92, -36, 60, -68, 124, -4, 2,\n -126, 66, -62, 34, -94, 98, -30, 18, -110, 82, -46, 50, -78, 114, -14, 10,\n -118, 74, -54, 42, -86, 106, -22, 26, -102, 90, -38, 58, -70, 122, -6, 6,\n -122, 70, -58, 38, -90, 102, -26, 22, -106, 86, -42, 54, -74, 118, -10, 14,\n -114, 78, -50, 46, -82, 110, -18, 30, -98, 94, -34, 62, -66, 126, -2, 1,\n -127, 65, -63, 33, -95, 97, -31, 17, -111, 81, -47, 49, -79, 113, -15, 9,\n -119, 73, -55, 41, -87, 105, -23, 25, -103, 89, -39, 57, -71, 121, -7, 5,\n -123, 69, -59, 37, -91, 101, -27, 21, -107, 85, -43, 53, -75, 117, -11, 13,\n -115, 77, -51, 45, -83, 109, -19, 29, -99, 93, -35, 61, -67, 125, -3, 3,\n -125, 67, -61, 35, -93, 99, -29, 19, -109, 83, -45, 51, -77, 115, -13, 11,\n -117, 75, -53, 43, -85, 107, -21, 27, -101, 91, -37, 59, -69, 123, -5, 7,\n -121, 71, -57, 39, -89, 103, -25, 23, -105, 87, -41, 55, -73, 119, -9, 15,\n -113, 79, -49, 47, -81, 111, -17, 31, -97, 95, -33, 63, -65, 127, -1,\n ];\n\n /**\n * The main 10 bit white runs lookup table\n */\n private static readonly WHITE: number[] = [\n // 0 - 7\n 6430, 6400, 6400, 6400, 3225, 3225, 3225, 3225,\n // 8 - 15\n 944, 944, 944, 944, 976, 976, 976, 976,\n // 16 - 23\n 1456, 1456, 1456, 1456, 1488, 1488, 1488, 1488,\n // 24 - 31\n 718, 718, 718, 718, 718, 718, 718, 718,\n // 32 - 39\n 750, 750, 750, 750, 750, 750, 750, 750,\n // 40 - 47\n 1520, 1520, 1520, 1520, 1552, 1552, 1552, 1552,\n // 48 - 55\n 428, 428, 428, 428, 428, 428, 428, 428,\n // 56 - 63\n 428, 428, 428, 428, 428, 428, 428, 428,\n // 64 - 71\n 654, 654, 654, 654, 654, 654, 654, 654,\n // 72 - 79\n 1072, 1072, 1072, 1072, 1104, 1104, 1104, 1104,\n // 80 - 87\n 1136, 1136, 1136, 1136, 1168, 1168, 1168, 1168,\n // 88 - 95\n 1200, 1200, 1200, 1200, 1232, 1232, 1232, 1232,\n // 96 - 103\n 622, 622, 622, 622, 622, 622, 622, 622,\n // 104 - 111\n 1008, 1008, 1008, 1008, 1040, 1040, 1040, 1040,\n // 112 - 119\n 44, 44, 44, 44, 44, 44, 44, 44,\n // 120 - 127\n 44, 44, 44, 44, 44, 44, 44, 44,\n // 128 - 135\n 396, 396, 396, 396, 396, 396, 396, 396,\n // 136 - 143\n 396, 396, 396, 396, 396, 396, 396, 396,\n // 144 - 151\n 1712, 1712, 1712, 1712, 1744, 1744, 1744, 1744,\n // 152 - 159\n 846, 846, 846, 846, 846, 846, 846, 846,\n // 160 - 167\n 1264, 1264, 1264, 1264, 1296, 1296, 1296, 1296,\n // 168 - 175\n 1328, 1328, 1328, 1328, 1360, 1360, 1360, 1360,\n // 176 - 183\n 1392, 1392, 1392, 1392, 1424, 1424, 1424, 1424,\n // 184 - 191\n 686, 686, 686, 686, 686, 686, 686, 686,\n // 192 - 199\n 910, 910, 910, 910, 910, 910, 910, 910,\n // 200 - 207\n 1968, 1968, 1968, 1968, 2000, 2000, 2000, 2000,\n // 208 - 215\n 2032, 2032, 2032, 2032, 16, 16, 16, 16,\n // 216 - 223\n 10257, 10257, 10257, 10257, 12305, 12305, 12305, 12305,\n // 224 - 231\n 330, 330, 330, 330, 330, 330, 330, 330,\n // 232 - 239\n 330, 330, 330, 330, 330, 330, 330, 330,\n // 240 - 247\n 330, 330, 330, 330, 330, 330, 330, 330,\n // 248 - 255\n 330, 330, 330, 330, 330, 330, 330, 330,\n // 256 - 263\n 362, 362, 362, 362, 362, 362, 362, 362,\n // 264 - 271\n 362, 362, 362, 362, 362, 362, 362, 362,\n // 272 - 279\n 362, 362, 362, 362, 362, 362, 362, 362,\n // 280 - 287\n 362, 362, 362, 362, 362, 362, 362, 362,\n // 288 - 295\n 878, 878, 878, 878, 878, 878, 878, 878,\n // 296 - 303\n 1904, 1904, 1904, 1904, 1936, 1936, 1936, 1936,\n // 304 - 311\n -18413, -18413, -16365, -16365, -14317, -14317, -10221, -10221,\n // 312 - 319\n 590, 590, 590, 590, 590, 590, 590, 590,\n // 320 - 327\n 782, 782, 782, 782, 782, 782, 782, 782,\n // 328 - 335\n 1584, 1584, 1584, 1584, 1616, 1616, 1616, 1616,\n // 336 - 343\n 1648, 1648, 1648, 1648, 1680, 1680, 1680, 1680,\n // 344 - 351\n 814, 814, 814, 814, 814, 814, 814, 814,\n // 352 - 359\n 1776, 1776, 1776, 1776, 1808, 1808, 1808, 1808,\n // 360 - 367\n 1840, 1840, 1840, 1840, 1872, 1872, 1872, 1872,\n // 368 - 375\n 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157,\n // 376 - 383\n 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157,\n // 384 - 391\n -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275,\n // 392 - 399\n -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275,\n // 400 - 407\n 14353, 14353, 14353, 14353, 16401, 16401, 16401, 16401,\n // 408 - 415\n 22547, 22547, 24595, 24595, 20497, 20497, 20497, 20497,\n // 416 - 423\n 18449, 18449, 18449, 18449, 26643, 26643, 28691, 28691,\n // 424 - 431\n 30739, 30739, -32749, -32749, -30701, -30701, -28653, -28653,\n // 432 - 439\n -26605, -26605, -24557, -24557, -22509, -22509, -20461, -20461,\n // 440 - 447\n 8207, 8207, 8207, 8207, 8207, 8207, 8207, 8207,\n // 448 - 455\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 456 - 463\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 464 - 471\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 472 - 479\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 480 - 487\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 488 - 495\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 496 - 503\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 504 - 511\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 512 - 519\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 520 - 527\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 528 - 535\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 536 - 543\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 544 - 551\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 552 - 559\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 560 - 567\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 568 - 575\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 576 - 583\n 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,\n // 584 - 591\n 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,\n // 592 - 599\n 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,\n // 600 - 607\n 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,\n // 608 - 615\n 266, 266, 266, 266, 266, 266, 266, 266,\n // 616 - 623\n 266, 266, 266, 266, 266, 266, 266, 266,\n // 624 - 631\n 266, 266, 266, 266, 266, 266, 266, 266,\n // 632 - 639\n 266, 266, 266, 266, 266, 266, 266, 266,\n // 640 - 647\n 298, 298, 298, 298, 298, 298, 298, 298,\n // 648 - 655\n 298, 298, 298, 298, 298, 298, 298, 298,\n // 656 - 663\n 298, 298, 298, 298, 298, 298, 298, 298,\n // 664 - 671\n 298, 298, 298, 298, 298, 298, 298, 298,\n // 672 - 679\n 524, 524, 524, 524, 524, 524, 524, 524,\n // 680 - 687\n 524, 524, 524, 524, 524, 524, 524, 524,\n // 688 - 695\n 556, 556, 556, 556, 556, 556, 556, 556,\n // 696 - 703\n 556, 556, 556, 556, 556, 556, 556, 556,\n // 704 - 711\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 712 - 719\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 720 - 727\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 728 - 735\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 736 - 743\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 744 - 751\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 752 - 759\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 760 - 767\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 768 - 775\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 776 - 783\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 784 - 791\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 792 - 799\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 800 - 807\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 808 - 815\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 816 - 823\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 824 - 831\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 832 - 839\n 460, 460, 460, 460, 460, 460, 460, 460,\n // 840 - 847\n 460, 460, 460, 460, 460, 460, 460, 460,\n // 848 - 855\n 492, 492, 492, 492, 492, 492, 492, 492,\n // 856 - 863\n 492, 492, 492, 492, 492, 492, 492, 492,\n // 864 - 871\n 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,\n // 872 - 879\n 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,\n // 880 - 887\n 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,\n // 888 - 895\n 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,\n // 896 - 903\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 904 - 911\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 912 - 919\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 920 - 927\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 928 - 935\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 936 - 943\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 944 - 951\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 952 - 959\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 960 - 967\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 968 - 975\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 976 - 983\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 984 - 991\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 992 - 999\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 1000 - 1007\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 1008 - 1015\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 1016 - 1023\n 232, 232, 232, 232, 232, 232, 232, 232,\n ];\n\n /**\n * Additional make up codes for both White and Black runs\n */\n private static readonly ADDITIONAL_MAKEUP: number[] = [\n 28679, 28679, 31752, -32759, -31735, -30711, -29687, -28663, 29703, 29703,\n 30727, 30727, -27639, -26615, -25591, -24567,\n ];\n\n /**\n * Initial black run look up table, uses the first 4 bits of a code\n */\n private static readonly INIT_BLACK: number[] = [\n // 0 - 7\n 3226, 6412, 200, 168, 38, 38, 134, 134,\n // 8 - 15\n 100, 100, 100, 100, 68, 68, 68, 68,\n ];\n\n private static readonly TWO_BIT_BLACK: number[] = [292, 260, 226, 226];\n\n /**\n * Main black run table, using the last 9 bits of possible 13 bit code\n */\n private static readonly BLACK: number[] = [\n // 0 - 7\n 62, 62, 30, 30, 0, 0, 0, 0,\n // 8 - 15\n 0, 0, 0, 0, 0, 0, 0, 0,\n // 16 - 23\n 0, 0, 0, 0, 0, 0, 0, 0,\n // 24 - 31\n 0, 0, 0, 0, 0, 0, 0, 0,\n // 32 - 39\n 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,\n // 40 - 47\n 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,\n // 48 - 55\n 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,\n // 56 - 63\n 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,\n // 64 - 71\n 588, 588, 588, 588, 588, 588, 588, 588,\n // 72 - 79\n 1680, 1680, 20499, 22547, 24595, 26643, 1776, 1776,\n // 80 - 87\n 1808, 1808, -24557, -22509, -20461, -18413, 1904, 1904,\n // 88 - 95\n 1936, 1936, -16365, -14317, 782, 782, 782, 782,\n // 96 - 103\n 814, 814, 814, 814, -12269, -10221, 10257, 10257,\n // 104 - 111\n 12305, 12305, 14353, 14353, 16403, 18451, 1712, 1712,\n // 112 - 119\n 1744, 1744, 28691, 30739, -32749, -30701, -28653, -26605,\n // 120 - 127\n 2061, 2061, 2061, 2061, 2061, 2061, 2061, 2061,\n // 128 - 135\n 424, 424, 424, 424, 424, 424, 424, 424,\n // 136 - 143\n 424, 424, 424, 424, 424, 424, 424, 424,\n // 144 - 151\n 424, 424, 424, 424, 424, 424, 424, 424,\n // 152 - 159\n 424, 424, 424, 424, 424, 424, 424, 424,\n // 160 - 167\n 750, 750, 750, 750, 1616, 1616, 1648, 1648,\n // 168 - 175\n 1424, 1424, 1456, 1456, 1488, 1488, 1520, 1520,\n // 176 - 183\n 1840, 1840, 1872, 1872, 1968, 1968, 8209, 8209,\n // 184 - 191\n 524, 524, 524, 524, 524, 524, 524, 524,\n // 192 - 199\n 556, 556, 556, 556, 556, 556, 556, 556,\n // 200 - 207\n 1552, 1552, 1584, 1584, 2000, 2000, 2032, 2032,\n // 208 - 215\n 976, 976, 1008, 1008, 1040, 1040, 1072, 1072,\n // 216 - 223\n 1296, 1296, 1328, 1328, 718, 718, 718, 718,\n // 224 - 231\n 456, 456, 456, 456, 456, 456, 456, 456,\n // 232 - 239\n 456, 456, 456, 456, 456, 456, 456, 456,\n // 240 - 247\n 456, 456, 456, 456, 456, 456, 456, 456,\n // 248 - 255\n 456, 456, 456, 456, 456, 456, 456, 456,\n // 256 - 263\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 264 - 271\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 272 - 279\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 280 - 287\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 288 - 295\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 296 - 303\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 304 - 311\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 312 - 319\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 320 - 327\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 328 - 335\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 336 - 343\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 344 - 351\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 352 - 359\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 360 - 367\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 368 - 375\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 376 - 383\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 384 - 391\n 490, 490, 490, 490, 490, 490, 490, 490,\n // 392 - 399\n 490, 490, 490, 490, 490, 490, 490, 490,\n // 400 - 407\n 4113, 4113, 6161, 6161, 848, 848, 880, 880,\n // 408 - 415\n 912, 912, 944, 944, 622, 622, 622, 622,\n // 416 - 423\n 654, 654, 654, 654, 1104, 1104, 1136, 1136,\n // 424 - 431\n 1168, 1168, 1200, 1200, 1232, 1232, 1264, 1264,\n // 432 - 439\n 686, 686, 686, 686, 1360, 1360, 1392, 1392,\n // 440 - 447\n 12, 12, 12, 12, 12, 12, 12, 12,\n // 448 - 455\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 456 - 463\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 464 - 471\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 472 - 479\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 480 - 487\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 488 - 495\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 496 - 503\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 504 - 511\n 390, 390, 390, 390, 390, 390, 390, 390,\n ];\n\n private static readonly TWO_D_CODES: number[] = [\n // 0 - 7\n 80, 88, 23, 71, 30, 30, 62, 62,\n // 8 - 15\n 4, 4, 4, 4, 4, 4, 4, 4,\n // 16 - 23\n 11, 11, 11, 11, 11, 11, 11, 11,\n // 24 - 31\n 11, 11, 11, 11, 11, 11, 11, 11,\n // 32 - 39\n 35, 35, 35, 35, 35, 35, 35, 35,\n // 40 - 47\n 35, 35, 35, 35, 35, 35, 35, 35,\n // 48 - 55\n 51, 51, 51, 51, 51, 51, 51, 51,\n // 56 - 63\n 51, 51, 51, 51, 51, 51, 51, 51,\n // 64 - 71\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 72 - 79\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 80 - 87\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 88 - 95\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 96 - 103\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 104 - 111\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 112 - 119\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 120 - 127\n 41, 41, 41, 41, 41, 41, 41, 41,\n ];\n\n private _width: number;\n public get width(): number {\n return this._width;\n }\n\n private _height: number;\n public get height(): number {\n return this._height;\n }\n\n private _fillOrder: number;\n public get fillOrder(): number {\n return this._fillOrder;\n }\n\n // Data structures needed to store changing elements for the previous\n // and the current scanline\n private changingElemSize = 0;\n private prevChangingElems?: Array;\n private currChangingElems?: Array;\n private data!: InputBuffer;\n private bitPointer = 0;\n private bytePointer = 0;\n\n // Element at which to start search in getNextChangingElement\n private lastChangingElement = 0;\n private compression = 2;\n\n // Variables set by T4Options\n // @ts-ignore\n private uncompressedMode = 0;\n private fillBits = 0;\n private oneD = 0;\n\n constructor(options: TiffFaxDecoderInitOptions) {\n this._fillOrder = options.fillOrder;\n this._width = options.width;\n this._height = options.height;\n this.prevChangingElems = new Array(this._width);\n this.prevChangingElems.fill(0);\n this.currChangingElems = new Array(this._width);\n this.currChangingElems.fill(0);\n }\n\n private nextNBits(bitsToGet: number): number {\n let b = 0;\n let next = 0;\n let next2next = 0;\n const l = this.data.length - 1;\n const bp = this.bytePointer;\n\n if (this._fillOrder === 1) {\n b = this.data.getByte(bp);\n\n if (bp === l) {\n next = 0x00;\n next2next = 0x00;\n } else if (bp + 1 === l) {\n next = this.data.getByte(bp + 1);\n next2next = 0x00;\n } else {\n next = this.data.getByte(bp + 1);\n next2next = this.data.getByte(bp + 2);\n }\n } else if (this._fillOrder === 2) {\n b = TiffFaxDecoder.FLIP_TABLE[this.data.getByte(bp) & 0xff];\n\n if (bp === l) {\n next = 0x00;\n next2next = 0x00;\n } else if (bp + 1 === l) {\n next = TiffFaxDecoder.FLIP_TABLE[this.data.getByte(bp + 1) & 0xff];\n next2next = 0x00;\n } else {\n next = TiffFaxDecoder.FLIP_TABLE[this.data.getByte(bp + 1) & 0xff];\n next2next = TiffFaxDecoder.FLIP_TABLE[this.data.getByte(bp + 2) & 0xff];\n }\n } else {\n throw new ImageError('TIFFFaxDecoder7');\n }\n\n const bitsLeft = 8 - this.bitPointer;\n let bitsFromNextByte = bitsToGet - bitsLeft;\n let bitsFromNext2NextByte = 0;\n if (bitsFromNextByte > 8) {\n bitsFromNext2NextByte = bitsFromNextByte - 8;\n bitsFromNextByte = 8;\n }\n\n this.bytePointer = this.bytePointer! + 1;\n\n const i1 = (b & TiffFaxDecoder.TABLE1[bitsLeft]) << (bitsToGet - bitsLeft);\n let i2 =\n (next & TiffFaxDecoder.TABLE2[bitsFromNextByte]) >>\n (8 - bitsFromNextByte);\n\n let i3 = 0;\n if (bitsFromNext2NextByte !== 0) {\n i2 <<= bitsFromNext2NextByte;\n i3 =\n (next2next & TiffFaxDecoder.TABLE2[bitsFromNext2NextByte]) >>\n (8 - bitsFromNext2NextByte);\n i2 |= i3;\n this.bytePointer += 1;\n this.bitPointer = bitsFromNext2NextByte;\n } else {\n if (bitsFromNextByte === 8) {\n this.bitPointer = 0;\n this.bytePointer += 1;\n } else {\n this.bitPointer = bitsFromNextByte;\n }\n }\n\n return i1 | i2;\n }\n\n private nextLesserThan8Bits(bitsToGet: number): number {\n let b = 0;\n let next = 0;\n const l = this.data.length - 1;\n const bp = this.bytePointer;\n\n if (this._fillOrder === 1) {\n b = this.data.getByte(bp);\n if (bp === l) {\n next = 0x00;\n } else {\n next = this.data.getByte(bp + 1);\n }\n } else if (this._fillOrder === 2) {\n b = TiffFaxDecoder.FLIP_TABLE[this.data.getByte(bp) & 0xff];\n if (bp === l) {\n next = 0x00;\n } else {\n next = TiffFaxDecoder.FLIP_TABLE[this.data.getByte(bp + 1) & 0xff];\n }\n } else {\n throw new ImageError('TIFFFaxDecoder7');\n }\n\n const bitsLeft = 8 - this.bitPointer;\n const bitsFromNextByte = bitsToGet - bitsLeft;\n\n const shift = bitsLeft - bitsToGet;\n let i1 = 0;\n let i2 = 0;\n if (shift >= 0) {\n i1 = (b & TiffFaxDecoder.TABLE1[bitsLeft]) >> shift;\n this.bitPointer += bitsToGet;\n if (this.bitPointer === 8) {\n this.bitPointer = 0;\n this.bytePointer += 1;\n }\n } else {\n i1 = (b & TiffFaxDecoder.TABLE1[bitsLeft]) << -shift;\n i2 =\n (next & TiffFaxDecoder.TABLE2[bitsFromNextByte]) >>\n (8 - bitsFromNextByte);\n\n i1 |= i2;\n this.bytePointer += 1;\n this.bitPointer = bitsFromNextByte;\n }\n\n return i1;\n }\n\n /**\n * Move pointer backwards by given amount of bits\n */\n private updatePointer(bitsToMoveBack: number): void {\n const i = this.bitPointer - bitsToMoveBack;\n\n if (i < 0) {\n this.bytePointer -= 1;\n this.bitPointer = 8 + i;\n } else {\n this.bitPointer = i;\n }\n }\n\n /**\n * Move to the next byte boundary\n */\n private advancePointer(): boolean {\n if (this.bitPointer !== 0) {\n this.bytePointer += 1;\n this.bitPointer = 0;\n }\n\n return true;\n }\n\n private setToBlack(\n buffer: InputBuffer,\n lineOffset: number,\n bitOffset: number,\n numBits: number\n ): void {\n let bitNum = 8 * lineOffset + bitOffset;\n const lastBit = bitNum + numBits;\n\n let byteNum = bitNum >> 3;\n\n // Handle bits in first byte\n const shift = bitNum & 0x7;\n if (shift > 0) {\n let maskVal = 1 << (7 - shift);\n let val = buffer.getByte(byteNum);\n while (maskVal > 0 && bitNum < lastBit) {\n val |= maskVal;\n maskVal >>= 1;\n ++bitNum;\n }\n buffer.setByte(byteNum, val);\n }\n\n // Fill in 8 bits at a time\n byteNum = bitNum >> 3;\n while (bitNum < lastBit - 7) {\n buffer.setByte(byteNum++, 255);\n bitNum += 8;\n }\n\n // Fill in remaining bits\n while (bitNum < lastBit) {\n byteNum = bitNum >> 3;\n buffer.setByte(\n byteNum,\n buffer.getByte(byteNum) | (1 << (7 - (bitNum & 0x7)))\n );\n ++bitNum;\n }\n }\n\n private decodeNextScanline(\n buffer: InputBuffer,\n lineOffset: number,\n bitOffset: number\n ): void {\n let offset = bitOffset;\n let bits = 0;\n let code = 0;\n let isT = 0;\n let current = 0;\n let entry = 0;\n let twoBits = 0;\n let isWhite = true;\n\n // Initialize starting of the changing elements array\n this.changingElemSize = 0;\n\n // While scanline not complete\n while (offset < this._width) {\n while (isWhite) {\n // White run\n current = this.nextNBits(10);\n entry = TiffFaxDecoder.WHITE[current];\n\n // Get the 3 fields from the entry\n isT = entry & 0x0001;\n bits = (entry >> 1) & 0x0f;\n\n if (bits === 12) {\n // Additional Make up code\n // Get the next 2 bits\n twoBits = this.nextLesserThan8Bits(2);\n // Consolidate the 2 bits and last 2 bits into 4 bits\n current = ((current << 2) & 0x000c) | twoBits;\n entry = TiffFaxDecoder.ADDITIONAL_MAKEUP[current];\n // 3 bits 0000 0111\n bits = (entry >> 1) & 0x07;\n // 12 bits\n code = (entry >> 4) & 0x0fff;\n // Skip white run\n offset += code;\n\n this.updatePointer(4 - bits);\n } else if (bits === 0) {\n // ERROR\n throw new ImageError('TIFFFaxDecoder0');\n } else if (bits === 15) {\n // EOL\n throw new ImageError('TIFFFaxDecoder1');\n } else {\n // 11 bits - 0000 0111 1111 1111 = 0x07ff\n code = (entry >> 5) & 0x07ff;\n offset += code;\n\n this.updatePointer(10 - bits);\n if (isT === 0) {\n isWhite = false;\n this.currChangingElems![this.changingElemSize++] = offset;\n }\n }\n }\n\n // Check whether this run completed one width, if so\n // advance to next byte boundary for compression = 2.\n if (offset === this._width) {\n if (this.compression === 2) {\n this.advancePointer();\n }\n break;\n }\n\n while (isWhite === false) {\n // Black run\n current = this.nextLesserThan8Bits(4);\n entry = TiffFaxDecoder.INIT_BLACK[current];\n\n // Get the 3 fields from the entry\n isT = entry & 0x0001;\n bits = (entry >> 1) & 0x000f;\n code = (entry >> 5) & 0x07ff;\n\n if (code === 100) {\n current = this.nextNBits(9);\n entry = TiffFaxDecoder.BLACK[current];\n\n // Get the 3 fields from the entry\n isT = entry & 0x0001;\n bits = (entry >> 1) & 0x000f;\n code = (entry >> 5) & 0x07ff;\n\n if (bits === 12) {\n // Additional makeup codes\n this.updatePointer(5);\n current = this.nextLesserThan8Bits(4);\n entry = TiffFaxDecoder.ADDITIONAL_MAKEUP[current];\n // 3 bits 0000 0111\n bits = (entry >> 1) & 0x07;\n // 12 bits\n code = (entry >> 4) & 0x0fff;\n\n this.setToBlack(buffer, lineOffset, offset, code);\n offset += code;\n\n this.updatePointer(4 - bits);\n } else if (bits === 15) {\n // EOL code\n throw new ImageError('TIFFFaxDecoder2');\n } else {\n this.setToBlack(buffer, lineOffset, offset, code);\n offset += code;\n\n this.updatePointer(9 - bits);\n if (isT === 0) {\n isWhite = true;\n this.currChangingElems![this.changingElemSize++] = offset;\n }\n }\n } else if (code === 200) {\n // Is a Terminating code\n current = this.nextLesserThan8Bits(2);\n entry = TiffFaxDecoder.TWO_BIT_BLACK[current];\n code = (entry >> 5) & 0x07ff;\n bits = (entry >> 1) & 0x0f;\n\n this.setToBlack(buffer, lineOffset, offset, code);\n offset += code;\n\n this.updatePointer(2 - bits);\n isWhite = true;\n this.currChangingElems![this.changingElemSize++] = offset;\n } else {\n // Is a Terminating code\n this.setToBlack(buffer, lineOffset, offset, code);\n offset += code;\n\n this.updatePointer(4 - bits);\n isWhite = true;\n this.currChangingElems![this.changingElemSize++] = offset;\n }\n }\n\n // Check whether this run completed one width\n if (offset === this._width) {\n if (this.compression === 2) {\n this.advancePointer();\n }\n break;\n }\n }\n\n this.currChangingElems![this.changingElemSize++] = offset;\n }\n\n private readEOL(): number {\n if (this.fillBits === 0) {\n if (this.nextNBits(12) !== 1) {\n throw new ImageError('TIFFFaxDecoder6');\n }\n } else if (this.fillBits === 1) {\n // First EOL code word xxxx 0000 0000 0001 will occur\n // As many fill bits will be present as required to make\n // the EOL code of 12 bits end on a byte boundary.\n const bitsLeft = 8 - this.bitPointer;\n\n if (this.nextNBits(bitsLeft) !== 0) {\n throw new ImageError('TIFFFaxDecoder8');\n }\n\n // If the number of bitsLeft is less than 8, then to have a 12\n // bit EOL sequence, two more bytes are certainly going to be\n // required. The first of them has to be all zeros, so ensure\n // that.\n if (bitsLeft < 4) {\n if (this.nextNBits(8) !== 0) {\n throw new ImageError('TIFFFaxDecoder8');\n }\n }\n\n // There might be a random number of fill bytes with 0s, so\n // loop till the EOL of 0000 0001 is found, as long as all\n // the bytes preceding it are 0's.\n let n = 0;\n while ((n = this.nextNBits(8)) !== 1) {\n // If not all zeros\n if (n !== 0) {\n throw new ImageError('TIFFFaxDecoder8');\n }\n }\n }\n\n // If one dimensional encoding mode, then always return 1\n if (this.oneD === 0) {\n return 1;\n } else {\n // Otherwise for 2D encoding mode,\n // The next one bit signifies 1D/2D encoding of next line.\n return this.nextLesserThan8Bits(1);\n }\n }\n\n private getNextChangingElement(\n a0: number | undefined,\n isWhite: boolean,\n ret: Array\n ): void {\n // Local copies of instance variables\n const pce = this.prevChangingElems;\n const ces = this.changingElemSize;\n\n // If the previous match was at an odd element, we still\n // have to search the preceeding element.\n // int start = lastChangingElement & ~0x1;\n let start = this.lastChangingElement > 0 ? this.lastChangingElement - 1 : 0;\n if (isWhite) {\n // Search even numbered elements\n start &= ~0x1;\n } else {\n // Search odd numbered elements\n start |= 0x1;\n }\n\n let i = start;\n for (; i < ces; i += 2) {\n const temp = pce![i]!;\n if (temp > a0!) {\n this.lastChangingElement = i;\n ret[0] = temp;\n break;\n }\n }\n\n if (i + 1 < ces) {\n ret[1] = pce![i + 1];\n }\n }\n\n /**\n * Returns run length\n */\n private decodeWhiteCodeWord(): number {\n let current = 0;\n let entry = 0;\n let bits = 0;\n let isT = 0;\n let twoBits = 0;\n let code = -1;\n let runLength = 0;\n let isWhite = true;\n\n while (isWhite) {\n current = this.nextNBits(10);\n entry = TiffFaxDecoder.WHITE[current];\n\n // Get the 3 fields from the entry\n isT = entry & 0x0001;\n bits = (entry >> 1) & 0x0f;\n\n if (bits === 12) {\n // Additional Make up code\n // Get the next 2 bits\n twoBits = this.nextLesserThan8Bits(2);\n // Consolidate the 2 new bits and last 2 bits into 4 bits\n current = ((current << 2) & 0x000c) | twoBits;\n entry = TiffFaxDecoder.ADDITIONAL_MAKEUP[current];\n // 3 bits 0000 0111\n bits = (entry >> 1) & 0x07;\n // 12 bits\n code = (entry >> 4) & 0x0fff;\n runLength += code;\n this.updatePointer(4 - bits);\n } else if (bits === 0) {\n // ERROR\n throw new ImageError('TIFFFaxDecoder0');\n } else if (bits === 15) {\n // EOL\n throw new ImageError('TIFFFaxDecoder1');\n } else {\n // 11 bits - 0000 0111 1111 1111 = 0x07ff\n code = (entry >> 5) & 0x07ff;\n runLength += code;\n this.updatePointer(10 - bits);\n if (isT === 0) {\n isWhite = false;\n }\n }\n }\n\n return runLength;\n }\n\n /**\n * Returns run length\n */\n private decodeBlackCodeWord() {\n let current = 0;\n let entry = 0;\n let bits = 0;\n let isT = 0;\n let code = -1;\n let runLength = 0;\n let isWhite = false;\n\n while (!isWhite) {\n current = this.nextLesserThan8Bits(4);\n entry = TiffFaxDecoder.INIT_BLACK[current];\n\n // Get the 3 fields from the entry\n isT = entry & 0x0001;\n bits = (entry >> 1) & 0x000f;\n code = (entry >> 5) & 0x07ff;\n\n if (code === 100) {\n current = this.nextNBits(9);\n entry = TiffFaxDecoder.BLACK[current];\n\n // Get the 3 fields from the entry\n isT = entry & 0x0001;\n bits = (entry >> 1) & 0x000f;\n code = (entry >> 5) & 0x07ff;\n\n if (bits === 12) {\n // Additional makeup codes\n this.updatePointer(5);\n current = this.nextLesserThan8Bits(4);\n entry = TiffFaxDecoder.ADDITIONAL_MAKEUP[current];\n // 3 bits 0000 0111\n bits = (entry >> 1) & 0x07;\n // 12 bits\n code = (entry >> 4) & 0x0fff;\n runLength += code;\n\n this.updatePointer(4 - bits);\n } else if (bits === 15) {\n // EOL code\n throw new ImageError('TIFFFaxDecoder2');\n } else {\n runLength += code;\n this.updatePointer(9 - bits);\n if (isT === 0) {\n isWhite = true;\n }\n }\n } else if (code === 200) {\n // Is a Terminating code\n current = this.nextLesserThan8Bits(2);\n entry = TiffFaxDecoder.TWO_BIT_BLACK[current];\n code = (entry >> 5) & 0x07ff;\n runLength += code;\n bits = (entry >> 1) & 0x0f;\n this.updatePointer(2 - bits);\n isWhite = true;\n } else {\n // Is a Terminating code\n runLength += code;\n this.updatePointer(4 - bits);\n isWhite = true;\n }\n }\n\n return runLength;\n }\n\n /**\n * One-dimensional decoding methods\n */\n public decode1D(\n out: InputBuffer,\n compData: InputBuffer,\n startX: number,\n height: number\n ): void {\n this.data = compData;\n this.bitPointer = 0;\n this.bytePointer = 0;\n\n let lineOffset = 0;\n const scanlineStride = Math.trunc((this._width + 7) / 8);\n\n for (let i = 0; i < height; i++) {\n this.decodeNextScanline(out, lineOffset, startX);\n lineOffset += scanlineStride;\n }\n }\n\n /**\n * Two-dimensional decoding methods\n */\n public decode2D(\n out: InputBuffer,\n compData: InputBuffer,\n startX: number,\n height: number,\n tiffT4Options: number\n ): void {\n this.data = compData;\n this.compression = 3;\n\n this.bitPointer = 0;\n this.bytePointer = 0;\n\n const scanlineStride = Math.trunc((this._width + 7) / 8);\n\n let a0 = 0;\n let a1 = 0;\n let entry = 0;\n let code = 0;\n let bits = 0;\n let isWhite = false;\n let currIndex = 0;\n let temp: Array | undefined = undefined;\n\n const b = new Array(2);\n b.fill(0);\n\n // fillBits - dealt with this in readEOL\n // 1D/2D encoding - dealt with this in readEOL\n\n // uncompressedMode - haven't dealt with this yet.\n this.oneD = tiffT4Options & 0x01;\n this.uncompressedMode = (tiffT4Options & 0x02) >> 1;\n this.fillBits = (tiffT4Options & 0x04) >> 2;\n\n // The data must start with an EOL code\n if (this.readEOL() !== 1) {\n throw new ImageError('TIFFFaxDecoder3');\n }\n\n let lineOffset = 0;\n let bitOffset = 0;\n\n // Then the 1D encoded scanline data will occur, changing elements\n // array gets set.\n this.decodeNextScanline(out, lineOffset, startX);\n lineOffset += scanlineStride;\n\n for (let lines = 1; lines < height; lines++) {\n // Every line must begin with an EOL followed by a bit which\n // indicates whether the following scanline is 1D or 2D encoded.\n if (this.readEOL() === 0) {\n // 2D encoded scanline follows\n\n // Initialize previous scanlines changing elements, and\n // initialize current scanline's changing elements array\n temp = this.prevChangingElems;\n this.prevChangingElems = this.currChangingElems;\n this.currChangingElems = temp;\n currIndex = 0;\n\n // a0 has to be set just before the start of this scanline.\n a0 = -1;\n isWhite = true;\n bitOffset = startX;\n\n this.lastChangingElement = 0;\n\n while (bitOffset < this._width) {\n // Get the next changing element\n this.getNextChangingElement(a0, isWhite, b);\n\n const b1 = b[0];\n const b2 = b[1];\n\n // Get the next seven bits\n entry = this.nextLesserThan8Bits(7);\n\n // Run these through the 2DCodes table\n entry = TiffFaxDecoder.TWO_D_CODES[entry] & 0xff;\n\n // Get the code and the number of bits used up\n code = (entry & 0x78) >> 3;\n bits = entry & 0x07;\n\n if (code === 0) {\n if (!isWhite) {\n this.setToBlack(out, lineOffset, bitOffset, b2 - bitOffset);\n }\n a0 = b2;\n bitOffset = a0;\n\n // Set pointer to consume the correct number of bits.\n this.updatePointer(7 - bits);\n } else if (code === 1) {\n // Horizontal\n this.updatePointer(7 - bits);\n\n // identify the next 2 codes.\n let number = 0;\n if (isWhite) {\n number = this.decodeWhiteCodeWord();\n bitOffset += number;\n this.currChangingElems![currIndex++] = bitOffset;\n\n number = this.decodeBlackCodeWord();\n this.setToBlack(out, lineOffset, bitOffset, number);\n bitOffset += number;\n this.currChangingElems![currIndex++] = bitOffset;\n } else {\n number = this.decodeBlackCodeWord();\n this.setToBlack(out, lineOffset, bitOffset, number);\n bitOffset += number;\n this.currChangingElems![currIndex++] = bitOffset;\n\n number = this.decodeWhiteCodeWord();\n bitOffset += number;\n this.currChangingElems![currIndex++] = bitOffset;\n }\n\n a0 = bitOffset;\n } else if (code <= 8) {\n // Vertical\n a1 = b1 + (code - 5);\n\n this.currChangingElems![currIndex++] = a1;\n\n // We write the current color till a1 - 1 pos,\n // since a1 is where the next color starts\n if (!isWhite) {\n this.setToBlack(out, lineOffset, bitOffset, a1 - bitOffset);\n }\n a0 = a1;\n bitOffset = a0;\n isWhite = !isWhite;\n\n this.updatePointer(7 - bits);\n } else {\n throw new ImageError('TIFFFaxDecoder4');\n }\n }\n\n // Add the changing element beyond the current scanline for the\n // other color too\n this.currChangingElems![currIndex++] = bitOffset;\n this.changingElemSize = currIndex;\n } else {\n // 1D encoded scanline follows\n this.decodeNextScanline(out, lineOffset, startX);\n }\n\n lineOffset += scanlineStride;\n }\n }\n\n public decodeT6(\n out: InputBuffer,\n compData: InputBuffer,\n startX: number,\n height: number,\n tiffT6Options: number\n ): void {\n this.data = compData;\n this.compression = 4;\n\n this.bitPointer = 0;\n this.bytePointer = 0;\n\n const scanlineStride = Math.trunc((this._width + 7) / 8);\n\n let a0 = 0;\n let a1 = 0;\n let b1 = 0;\n let b2 = 0;\n let entry = 0;\n let code = 0;\n let bits = 0;\n let isWhite = false;\n let currIndex = 0;\n let temp: Array | undefined = undefined;\n\n // Return values from getNextChangingElement\n const b = new Array(2);\n b.fill(0);\n\n this.uncompressedMode = (tiffT6Options & 0x02) >> 1;\n\n // Local cached reference\n let cce = this.currChangingElems!;\n\n // Assume invisible preceding row of all white pixels and insert\n // both black and white changing elements beyond the end of this\n // imaginary scanline.\n this.changingElemSize = 0;\n cce[this.changingElemSize++] = this._width;\n cce[this.changingElemSize++] = this._width;\n\n let lineOffset = 0;\n let bitOffset = 0;\n\n for (let lines = 0; lines < height; lines++) {\n // a0 has to be set just before the start of the scanline.\n a0 = -1;\n isWhite = true;\n\n // Assign the changing elements of the previous scanline to\n // prevChangingElems and start putting this new scanline's\n // changing elements into the currChangingElems.\n temp = this.prevChangingElems;\n this.prevChangingElems = this.currChangingElems;\n cce = (this.currChangingElems = temp)!;\n currIndex = 0;\n\n // Start decoding the scanline at startX in the raster\n bitOffset = startX;\n\n // Reset search start position for getNextChangingElement\n this.lastChangingElement = 0;\n\n // Till one whole scanline is decoded\n while (bitOffset < this._width) {\n // Get the next changing element\n this.getNextChangingElement(a0, isWhite, b);\n b1 = b[0];\n b2 = b[1];\n\n // Get the next seven bits\n entry = this.nextLesserThan8Bits(7);\n // Run these through the 2DCodes table\n entry = TiffFaxDecoder.TWO_D_CODES[entry] & 0xff;\n\n // Get the code and the number of bits used up\n code = (entry & 0x78) >> 3;\n bits = entry & 0x07;\n\n if (code === 0) {\n // Pass\n // We always assume WhiteIsZero format for fax.\n if (!isWhite) {\n this.setToBlack(out, lineOffset, bitOffset, b2! - bitOffset);\n }\n a0 = b2;\n bitOffset = a0;\n\n // Set pointer to only consume the correct number of bits.\n this.updatePointer(7 - bits);\n } else if (code === 1) {\n // Horizontal\n // Set pointer to only consume the correct number of bits.\n this.updatePointer(7 - bits);\n\n // identify the next 2 alternating color codes.\n let number = 0;\n if (isWhite) {\n // Following are white and black runs\n number = this.decodeWhiteCodeWord();\n bitOffset += number;\n cce[currIndex++] = bitOffset;\n\n number = this.decodeBlackCodeWord();\n this.setToBlack(out, lineOffset, bitOffset, number);\n bitOffset += number;\n cce[currIndex++] = bitOffset;\n } else {\n // First a black run and then a white run follows\n number = this.decodeBlackCodeWord();\n this.setToBlack(out, lineOffset, bitOffset, number);\n bitOffset += number;\n cce[currIndex++] = bitOffset;\n\n number = this.decodeWhiteCodeWord();\n bitOffset += number;\n cce[currIndex++] = bitOffset;\n }\n\n a0 = bitOffset;\n } else if (code <= 8) {\n // Vertical\n a1 = b1 + (code - 5);\n cce[currIndex++] = a1;\n\n // We write the current color till a1 - 1 pos,\n // since a1 is where the next color starts\n if (!isWhite) {\n this.setToBlack(out, lineOffset, bitOffset, a1 - bitOffset);\n }\n a0 = a1;\n bitOffset = a0;\n isWhite = !isWhite;\n\n this.updatePointer(7 - bits);\n } else if (code === 11) {\n if (this.nextLesserThan8Bits(3) !== 7) {\n throw new ImageError('TIFFFaxDecoder5');\n }\n\n let zeros = 0;\n let exit = false;\n\n while (!exit) {\n while (this.nextLesserThan8Bits(1) !== 1) {\n zeros++;\n }\n\n if (zeros > 5) {\n // Exit code\n\n // Zeros before exit code\n zeros -= 6;\n\n if (!isWhite && zeros > 0) {\n cce[currIndex++] = bitOffset;\n }\n\n // Zeros before the exit code\n bitOffset += zeros;\n if (zeros > 0) {\n // Some zeros have been written\n isWhite = true;\n }\n\n // Read in the bit which specifies the color of\n // the following run\n if (this.nextLesserThan8Bits(1) === 0) {\n if (!isWhite) {\n cce[currIndex++] = bitOffset;\n }\n isWhite = true;\n } else {\n if (isWhite) {\n cce[currIndex++] = bitOffset;\n }\n isWhite = false;\n }\n\n exit = true;\n }\n\n if (zeros === 5) {\n if (!isWhite) {\n cce[currIndex++] = bitOffset;\n }\n bitOffset += zeros;\n\n // Last thing written was white\n isWhite = true;\n } else {\n bitOffset += zeros;\n\n cce[currIndex++] = bitOffset;\n this.setToBlack(out, lineOffset, bitOffset, 1);\n ++bitOffset;\n\n // Last thing written was black\n isWhite = false;\n }\n }\n } else {\n throw new ImageError(`TIFFFaxDecoder5 ${code}`);\n }\n }\n\n // Add the changing element beyond the current scanline for the\n // other color too\n cce[currIndex++] = bitOffset;\n\n // Number of changing elements in this scanline.\n this.changingElemSize = currIndex;\n\n lineOffset += scanlineStride;\n }\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { ImageError } from '../../error/image-error';\n\nexport class LzwDecoder {\n private static readonly LZ_MAX_CODE = 4095;\n private static readonly NO_SUCH_CODE = 4098;\n private static readonly AND_TABLE: number[] = [511, 1023, 2047, 4095];\n\n private readonly buffer = new Uint8Array(4096);\n\n private bitsToGet = 9;\n private bytePointer = 0;\n private nextData = 0;\n private nextBits = 0;\n private data!: Uint8Array;\n private dataLength!: number;\n private out!: Uint8Array;\n private outPointer!: number;\n private table!: Uint8Array;\n private prefix!: Uint32Array;\n private tableIndex?: number;\n private bufferLength!: number;\n\n private addString(string: number, newString: number): void {\n this.table[this.tableIndex!] = newString;\n this.prefix[this.tableIndex!] = string;\n this.tableIndex = this.tableIndex! + 1;\n\n if (this.tableIndex === 511) {\n this.bitsToGet = 10;\n } else if (this.tableIndex === 1023) {\n this.bitsToGet = 11;\n } else if (this.tableIndex === 2047) {\n this.bitsToGet = 12;\n }\n }\n\n private getString(code: number): void {\n this.bufferLength = 0;\n let c = code;\n this.buffer[this.bufferLength++] = this.table[c];\n c = this.prefix[c];\n while (c !== LzwDecoder.NO_SUCH_CODE) {\n this.buffer[this.bufferLength++] = this.table[c];\n c = this.prefix[c];\n }\n }\n\n /**\n * Returns the next 9, 10, 11 or 12 bits\n */\n private getNextCode(): number {\n if (this.bytePointer >= this.dataLength) {\n return 257;\n }\n\n while (this.nextBits < this.bitsToGet) {\n if (this.bytePointer >= this.dataLength) {\n return 257;\n }\n this.nextData =\n ((this.nextData << 8) + this.data[this.bytePointer++]) & 0xffffffff;\n this.nextBits += 8;\n }\n\n this.nextBits -= this.bitsToGet;\n const code =\n (this.nextData >> this.nextBits) &\n LzwDecoder.AND_TABLE[this.bitsToGet - 9];\n\n return code;\n }\n\n /**\n * Initialize the string table.\n */\n private initializeStringTable(): void {\n this.table = new Uint8Array(LzwDecoder.LZ_MAX_CODE + 1);\n this.prefix = new Uint32Array(LzwDecoder.LZ_MAX_CODE + 1);\n this.prefix.fill(LzwDecoder.NO_SUCH_CODE, 0, this.prefix.length);\n\n for (let i = 0; i < 256; i++) {\n this.table[i] = i;\n }\n\n this.bitsToGet = 9;\n\n this.tableIndex = 258;\n }\n\n public decode(p: InputBuffer, out: Uint8Array): void {\n this.out = out;\n const outLen = out.length;\n this.outPointer = 0;\n this.data = p.buffer;\n this.dataLength = this.data.length;\n this.bytePointer = p.offset;\n\n if (this.data[0] === 0x00 && this.data[1] === 0x01) {\n throw new ImageError('Invalid LZW Data');\n }\n\n this.initializeStringTable();\n\n this.nextData = 0;\n this.nextBits = 0;\n\n let oldCode = 0;\n\n let code = this.getNextCode();\n while (code !== 257 && this.outPointer < outLen) {\n if (code === 256) {\n this.initializeStringTable();\n code = this.getNextCode();\n this.bufferLength = 0;\n if (code === 257) {\n break;\n }\n\n this.out[this.outPointer++] = code;\n oldCode = code;\n } else {\n if (code < this.tableIndex!) {\n this.getString(code);\n for (let i = this.bufferLength - 1; i >= 0; --i) {\n this.out[this.outPointer++] = this.buffer[i];\n }\n this.addString(oldCode, this.buffer[this.bufferLength - 1]);\n oldCode = code;\n } else {\n this.getString(oldCode);\n for (let i = this.bufferLength - 1; i >= 0; --i) {\n this.out[this.outPointer++] = this.buffer[i];\n }\n this.out[this.outPointer++] = this.buffer[this.bufferLength - 1];\n this.addString(oldCode, this.buffer[this.bufferLength - 1]);\n\n oldCode = code;\n }\n }\n\n code = this.getNextCode();\n }\n }\n}\n", "/** @format */\n\nimport { inflate } from 'uzip';\nimport { BitOperators } from '../../common/bit-operators';\nimport { Color } from '../../common/color';\nimport { InputBuffer } from '../../common/input-buffer';\nimport { MathOperators } from '../../common/math-operators';\nimport { MemoryImage } from '../../common/memory-image';\nimport { ImageError } from '../../error/image-error';\nimport { Half } from '../../hdr/half';\nimport { HdrImage } from '../../hdr/hdr-image';\nimport { HdrSlice } from '../../hdr/hdr-slice';\nimport { JpegDecoder } from '../jpeg-decoder';\nimport { TiffBitReader } from './tiff-bit-reader';\nimport { TiffEntry } from './tiff-entry';\nimport { TiffFaxDecoder } from './tiff-fax-decoder';\nimport { LzwDecoder } from './tiff-lzw-decoder';\n\nexport class TiffImage {\n // Compression types\n public static readonly COMPRESSION_NONE = 1;\n public static readonly COMPRESSION_CCITT_RLE = 2;\n public static readonly COMPRESSION_CCITT_FAX3 = 3;\n public static readonly COMPRESSION_CCITT_FAX4 = 4;\n public static readonly COMPRESSION_LZW = 5;\n public static readonly COMPRESSION_OLD_JPEG = 6;\n public static readonly COMPRESSION_JPEG = 7;\n public static readonly COMPRESSION_NEXT = 32766;\n public static readonly COMPRESSION_CCITT_RLEW = 32771;\n public static readonly COMPRESSION_PACKBITS = 32773;\n public static readonly COMPRESSION_THUNDERSCAN = 32809;\n public static readonly COMPRESSION_IT8CTPAD = 32895;\n public static readonly COMPRESSION_IT8LW = 32896;\n public static readonly COMPRESSION_IT8MP = 32897;\n public static readonly COMPRESSION_IT8BL = 32898;\n public static readonly COMPRESSION_PIXARFILM = 32908;\n public static readonly COMPRESSION_PIXARLOG = 32909;\n public static readonly COMPRESSION_DEFLATE = 32946;\n public static readonly COMPRESSION_ZIP = 8;\n public static readonly COMPRESSION_DCS = 32947;\n public static readonly COMPRESSION_JBIG = 34661;\n public static readonly COMPRESSION_SGILOG = 34676;\n public static readonly COMPRESSION_SGILOG24 = 34677;\n public static readonly COMPRESSION_JP2000 = 34712;\n\n // Photometric types\n public static readonly PHOTOMETRIC_BLACKISZERO = 1;\n public static readonly PHOTOMETRIC_RGB = 2;\n\n // Image types\n public static readonly TYPE_UNSUPPORTED = -1;\n public static readonly TYPE_BILEVEL = 0;\n public static readonly TYPE_GRAY_4BIT = 1;\n public static readonly TYPE_GRAY = 2;\n public static readonly TYPE_GRAY_ALPHA = 3;\n public static readonly TYPE_PALETTE = 4;\n public static readonly TYPE_RGB = 5;\n public static readonly TYPE_RGB_ALPHA = 6;\n public static readonly TYPE_YCBCR_SUB = 7;\n public static readonly TYPE_GENERIC = 8;\n\n // Sample Formats\n public static readonly FORMAT_UINT = 1;\n public static readonly FORMAT_INT = 2;\n public static readonly FORMAT_FLOAT = 3;\n\n // Tag types\n public static readonly TAG_ARTIST = 315;\n public static readonly TAG_BITS_PER_SAMPLE = 258;\n public static readonly TAG_CELL_LENGTH = 265;\n public static readonly TAG_CELL_WIDTH = 264;\n public static readonly TAG_COLOR_MAP = 320;\n public static readonly TAG_COMPRESSION = 259;\n public static readonly TAG_DATE_TIME = 306;\n public static readonly TAG_EXIF_IFD = 34665;\n public static readonly TAG_EXTRA_SAMPLES = 338;\n public static readonly TAG_FILL_ORDER = 266;\n public static readonly TAG_FREE_BYTE_COUNTS = 289;\n public static readonly TAG_FREE_OFFSETS = 288;\n public static readonly TAG_GRAY_RESPONSE_CURVE = 291;\n public static readonly TAG_GRAY_RESPONSE_UNIT = 290;\n public static readonly TAG_HOST_COMPUTER = 316;\n public static readonly TAG_ICC_PROFILE = 34675;\n public static readonly TAG_IMAGE_DESCRIPTION = 270;\n public static readonly TAG_IMAGE_LENGTH = 257;\n public static readonly TAG_IMAGE_WIDTH = 256;\n public static readonly TAG_IPTC = 33723;\n public static readonly TAG_MAKE = 271;\n public static readonly TAG_MAX_SAMPLE_VALUE = 281;\n public static readonly TAG_MIN_SAMPLE_VALUE = 280;\n public static readonly TAG_MODEL = 272;\n public static readonly TAG_NEW_SUBFILE_TYPE = 254;\n public static readonly TAG_ORIENTATION = 274;\n public static readonly TAG_PHOTOMETRIC_INTERPRETATION = 262;\n public static readonly TAG_PHOTOSHOP = 34377;\n public static readonly TAG_PLANAR_CONFIGURATION = 284;\n public static readonly TAG_PREDICTOR = 317;\n public static readonly TAG_RESOLUTION_UNIT = 296;\n public static readonly TAG_ROWS_PER_STRIP = 278;\n public static readonly TAG_SAMPLES_PER_PIXEL = 277;\n public static readonly TAG_SOFTWARE = 305;\n public static readonly TAG_STRIP_BYTE_COUNTS = 279;\n public static readonly TAG_STRIP_OFFSETS = 273;\n public static readonly TAG_SUBFILE_TYPE = 255;\n public static readonly TAG_T4_OPTIONS = 292;\n public static readonly TAG_T6_OPTIONS = 293;\n public static readonly TAG_THRESHOLDING = 263;\n public static readonly TAG_TILE_WIDTH = 322;\n public static readonly TAG_TILE_LENGTH = 323;\n public static readonly TAG_TILE_OFFSETS = 324;\n public static readonly TAG_TILE_BYTE_COUNTS = 325;\n public static readonly TAG_SAMPLE_FORMAT = 339;\n public static readonly TAG_XMP = 700;\n public static readonly TAG_X_RESOLUTION = 282;\n public static readonly TAG_Y_RESOLUTION = 283;\n public static readonly TAG_YCBCR_COEFFICIENTS = 529;\n public static readonly TAG_YCBCR_SUBSAMPLING = 530;\n public static readonly TAG_YCBCR_POSITIONING = 531;\n\n public static readonly TAG_NAME: Map = new Map<\n number,\n string\n >([\n [TiffImage.TAG_ARTIST, 'artist'],\n [TiffImage.TAG_BITS_PER_SAMPLE, 'bitsPerSample'],\n [TiffImage.TAG_CELL_LENGTH, 'cellLength'],\n [TiffImage.TAG_CELL_WIDTH, 'cellWidth'],\n [TiffImage.TAG_COLOR_MAP, 'colorMap'],\n [TiffImage.TAG_COMPRESSION, 'compression'],\n [TiffImage.TAG_DATE_TIME, 'dateTime'],\n [TiffImage.TAG_EXIF_IFD, 'exifIFD'],\n [TiffImage.TAG_EXTRA_SAMPLES, 'extraSamples'],\n [TiffImage.TAG_FILL_ORDER, 'fillOrder'],\n [TiffImage.TAG_FREE_BYTE_COUNTS, 'freeByteCounts'],\n [TiffImage.TAG_FREE_OFFSETS, 'freeOffsets'],\n [TiffImage.TAG_GRAY_RESPONSE_CURVE, 'grayResponseCurve'],\n [TiffImage.TAG_GRAY_RESPONSE_UNIT, 'grayResponseUnit'],\n [TiffImage.TAG_HOST_COMPUTER, 'hostComputer'],\n [TiffImage.TAG_ICC_PROFILE, 'iccProfile'],\n [TiffImage.TAG_IMAGE_DESCRIPTION, 'imageDescription'],\n [TiffImage.TAG_IMAGE_LENGTH, 'imageLength'],\n [TiffImage.TAG_IMAGE_WIDTH, 'imageWidth'],\n [TiffImage.TAG_IPTC, 'iptc'],\n [TiffImage.TAG_MAKE, 'make'],\n [TiffImage.TAG_MAX_SAMPLE_VALUE, 'maxSampleValue'],\n [TiffImage.TAG_MIN_SAMPLE_VALUE, 'minSampleValue'],\n [TiffImage.TAG_MODEL, 'model'],\n [TiffImage.TAG_NEW_SUBFILE_TYPE, 'newSubfileType'],\n [TiffImage.TAG_ORIENTATION, 'orientation'],\n [TiffImage.TAG_PHOTOMETRIC_INTERPRETATION, 'photometricInterpretation'],\n [TiffImage.TAG_PHOTOSHOP, 'photoshop'],\n [TiffImage.TAG_PLANAR_CONFIGURATION, 'planarConfiguration'],\n [TiffImage.TAG_PREDICTOR, 'predictor'],\n [TiffImage.TAG_RESOLUTION_UNIT, 'resolutionUnit'],\n [TiffImage.TAG_ROWS_PER_STRIP, 'rowsPerStrip'],\n [TiffImage.TAG_SAMPLES_PER_PIXEL, 'samplesPerPixel'],\n [TiffImage.TAG_SOFTWARE, 'software'],\n [TiffImage.TAG_STRIP_BYTE_COUNTS, 'stripByteCounts'],\n [TiffImage.TAG_STRIP_OFFSETS, 'stropOffsets'],\n [TiffImage.TAG_SUBFILE_TYPE, 'subfileType'],\n [TiffImage.TAG_T4_OPTIONS, 't4Options'],\n [TiffImage.TAG_T6_OPTIONS, 't6Options'],\n [TiffImage.TAG_THRESHOLDING, 'thresholding'],\n [TiffImage.TAG_TILE_WIDTH, 'tileWidth'],\n [TiffImage.TAG_TILE_LENGTH, 'tileLength'],\n [TiffImage.TAG_TILE_OFFSETS, 'tileOffsets'],\n [TiffImage.TAG_TILE_BYTE_COUNTS, 'tileByteCounts'],\n [TiffImage.TAG_XMP, 'xmp'],\n [TiffImage.TAG_X_RESOLUTION, 'xResolution'],\n [TiffImage.TAG_Y_RESOLUTION, 'yResolution'],\n [TiffImage.TAG_YCBCR_COEFFICIENTS, 'yCbCrCoefficients'],\n [TiffImage.TAG_YCBCR_SUBSAMPLING, 'yCbCrSubsampling'],\n [TiffImage.TAG_YCBCR_POSITIONING, 'yCbCrPositioning'],\n [TiffImage.TAG_SAMPLE_FORMAT, 'sampleFormat'],\n ]);\n\n private readonly _tags: Map = new Map();\n public get tags(): Map {\n return this._tags;\n }\n\n private readonly _width: number = 0;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number = 0;\n public get height(): number {\n return this._height;\n }\n\n private _photometricType: number | undefined;\n public get photometricType(): number | undefined {\n return this._photometricType;\n }\n\n private _compression = 1;\n public get compression(): number {\n return this._compression;\n }\n\n private _bitsPerSample = 1;\n public get bitsPerSample(): number {\n return this._bitsPerSample;\n }\n\n private _samplesPerPixel = 1;\n public get samplesPerPixel(): number {\n return this._samplesPerPixel;\n }\n\n private _sampleFormat = TiffImage.FORMAT_UINT;\n public get sampleFormat(): number {\n return this._sampleFormat;\n }\n\n private _imageType = TiffImage.TYPE_UNSUPPORTED;\n public get imageType(): number {\n return this._imageType;\n }\n\n private _isWhiteZero = false;\n public get isWhiteZero(): boolean {\n return this._isWhiteZero;\n }\n\n private _predictor = 1;\n public get predictor(): number {\n return this._predictor;\n }\n\n private _chromaSubH = 0;\n public get chromaSubH(): number {\n return this._chromaSubH;\n }\n\n private _chromaSubV = 0;\n public get chromaSubV(): number {\n return this._chromaSubV;\n }\n\n private _tiled = false;\n public get tiled(): boolean {\n return this._tiled;\n }\n\n private _tileWidth = 0;\n public get tileWidth(): number {\n return this._tileWidth;\n }\n\n private _tileHeight = 0;\n public get tileHeight(): number {\n return this._tileHeight;\n }\n\n private _tileOffsets: number[] | undefined;\n public get tileOffsets(): number[] | undefined {\n return this._tileOffsets;\n }\n\n private _tileByteCounts: number[] | undefined;\n public get tileByteCounts(): number[] | undefined {\n return this._tileByteCounts;\n }\n\n private _tilesX = 0;\n public get tilesX(): number {\n return this._tilesX;\n }\n\n private _tilesY = 0;\n public get tilesY(): number {\n return this._tilesY;\n }\n\n private _tileSize: number | undefined;\n public get tileSize(): number | undefined {\n return this._tileSize;\n }\n\n private _fillOrder = 1;\n public get fillOrder(): number {\n return this._fillOrder;\n }\n\n private _t4Options = 0;\n public get t4Options(): number {\n return this._t4Options;\n }\n\n private _t6Options = 0;\n public get t6Options(): number {\n return this._t6Options;\n }\n\n private _extraSamples: number | undefined;\n public get extraSamples(): number | undefined {\n return this._extraSamples;\n }\n\n private _colorMap: number[] | undefined;\n public get colorMap(): number[] | undefined {\n return this._colorMap;\n }\n\n // Starting index in the [colorMap] for the red channel.\n private colorMapRed = 0;\n\n // Starting index in the [colorMap] for the green channel.\n private colorMapGreen = 0;\n\n // Starting index in the [colorMap] for the blue channel.\n private colorMapBlue = 0;\n\n private image?: MemoryImage;\n\n private hdrImage?: HdrImage;\n\n public get isValid(): boolean {\n return this._width !== 0 && this._height !== 0;\n }\n\n constructor(p: InputBuffer) {\n const p3 = InputBuffer.from(p);\n const numDirEntries = p.readUint16();\n for (let i = 0; i < numDirEntries; ++i) {\n const tag = p.readUint16();\n const type = p.readUint16();\n const numValues = p.readUint32();\n const entry = new TiffEntry({\n tag: tag,\n type: type,\n numValues: numValues,\n p: p3,\n });\n\n // The value for the tag is either stored in another location,\n // or within the tag itself (if the size fits in 4 bytes).\n // We're not reading the data here, just storing offsets.\n if (entry.numValues * entry.typeSize > 4) {\n entry.valueOffset = p.readUint32();\n } else {\n entry.valueOffset = p.offset;\n p.offset += 4;\n }\n\n this._tags.set(entry.tag, entry);\n\n if (entry.tag === TiffImage.TAG_IMAGE_WIDTH) {\n this._width = entry.readValue();\n } else if (entry.tag === TiffImage.TAG_IMAGE_LENGTH) {\n this._height = entry.readValue();\n } else if (entry.tag === TiffImage.TAG_PHOTOMETRIC_INTERPRETATION) {\n this._photometricType = entry.readValue();\n } else if (entry.tag === TiffImage.TAG_COMPRESSION) {\n this._compression = entry.readValue();\n } else if (entry.tag === TiffImage.TAG_BITS_PER_SAMPLE) {\n this._bitsPerSample = entry.readValue();\n } else if (entry.tag === TiffImage.TAG_SAMPLES_PER_PIXEL) {\n this._samplesPerPixel = entry.readValue();\n } else if (entry.tag === TiffImage.TAG_PREDICTOR) {\n this._predictor = entry.readValue();\n } else if (entry.tag === TiffImage.TAG_SAMPLE_FORMAT) {\n this._sampleFormat = entry.readValue();\n } else if (entry.tag === TiffImage.TAG_COLOR_MAP) {\n this._colorMap = entry.readValues();\n this.colorMapRed = 0;\n this.colorMapGreen = Math.trunc(this._colorMap.length / 3);\n this.colorMapBlue = this.colorMapGreen * 2;\n }\n }\n\n if (this._width === 0 || this._height === 0) {\n return;\n }\n\n if (this._colorMap !== undefined && this._bitsPerSample === 8) {\n for (let i = 0, len = this._colorMap.length; i < len; ++i) {\n this._colorMap[i] >>= 8;\n }\n }\n\n if (this._photometricType === 0) {\n this._isWhiteZero = true;\n }\n\n if (this.hasTag(TiffImage.TAG_TILE_OFFSETS)) {\n this._tiled = true;\n // Image is in tiled format\n this._tileWidth = this.readTag(TiffImage.TAG_TILE_WIDTH);\n this._tileHeight = this.readTag(TiffImage.TAG_TILE_LENGTH);\n this._tileOffsets = this.readTagList(TiffImage.TAG_TILE_OFFSETS);\n this._tileByteCounts = this.readTagList(TiffImage.TAG_TILE_BYTE_COUNTS);\n } else {\n this._tiled = false;\n\n this._tileWidth = this.readTag(TiffImage.TAG_TILE_WIDTH, this._width);\n if (!this.hasTag(TiffImage.TAG_ROWS_PER_STRIP)) {\n this._tileHeight = this.readTag(\n TiffImage.TAG_TILE_LENGTH,\n this._height\n );\n } else {\n const l = this.readTag(TiffImage.TAG_ROWS_PER_STRIP);\n let infinity = 1;\n infinity = (infinity << 32) - 1;\n if (l === infinity) {\n // 2^32 - 1 (effectively infinity, entire image is 1 strip)\n this._tileHeight = this._height;\n } else {\n this._tileHeight = l;\n }\n }\n\n this._tileOffsets = this.readTagList(TiffImage.TAG_STRIP_OFFSETS);\n this._tileByteCounts = this.readTagList(TiffImage.TAG_STRIP_BYTE_COUNTS);\n }\n\n // Calculate number of tiles and the tileSize in bytes\n this._tilesX = Math.trunc(\n (this._width + this._tileWidth - 1) / this._tileWidth\n );\n this._tilesY = Math.trunc(\n (this._height + this._tileHeight - 1) / this._tileHeight\n );\n this._tileSize = this._tileWidth * this._tileHeight * this._samplesPerPixel;\n\n this._fillOrder = this.readTag(TiffImage.TAG_FILL_ORDER, 1);\n this._t4Options = this.readTag(TiffImage.TAG_T4_OPTIONS);\n this._t6Options = this.readTag(TiffImage.TAG_T6_OPTIONS);\n this._extraSamples = this.readTag(TiffImage.TAG_EXTRA_SAMPLES);\n\n // Determine which kind of image we are dealing with.\n switch (this._photometricType) {\n // WhiteIsZero\n case 0:\n // BlackIsZero\n // falls through\n case 1:\n if (this._bitsPerSample === 1 && this._samplesPerPixel === 1) {\n this._imageType = TiffImage.TYPE_BILEVEL;\n } else if (this._bitsPerSample === 4 && this._samplesPerPixel === 1) {\n this._imageType = TiffImage.TYPE_GRAY_4BIT;\n } else if (this._bitsPerSample % 8 === 0) {\n if (this._samplesPerPixel === 1) {\n this._imageType = TiffImage.TYPE_GRAY;\n } else if (this._samplesPerPixel === 2) {\n this._imageType = TiffImage.TYPE_GRAY_ALPHA;\n } else {\n this._imageType = TiffImage.TYPE_GENERIC;\n }\n }\n break;\n // RGB\n case 2:\n if (this._bitsPerSample % 8 === 0) {\n if (this._samplesPerPixel === 3) {\n this._imageType = TiffImage.TYPE_RGB;\n } else if (this._samplesPerPixel === 4) {\n this._imageType = TiffImage.TYPE_RGB_ALPHA;\n } else {\n this._imageType = TiffImage.TYPE_GENERIC;\n }\n }\n break;\n // RGB Palette\n case 3:\n if (\n this._samplesPerPixel === 1 &&\n (this._bitsPerSample === 4 ||\n this._bitsPerSample === 8 ||\n this._bitsPerSample === 16)\n ) {\n this._imageType = TiffImage.TYPE_PALETTE;\n }\n break;\n // Transparency mask\n case 4:\n if (this._bitsPerSample === 1 && this._samplesPerPixel === 1) {\n this._imageType = TiffImage.TYPE_BILEVEL;\n }\n break;\n // YCbCr\n case 6:\n if (\n this._compression === TiffImage.COMPRESSION_JPEG &&\n this._bitsPerSample === 8 &&\n this._samplesPerPixel === 3\n ) {\n this._imageType = TiffImage.TYPE_RGB;\n } else {\n if (this.hasTag(TiffImage.TAG_YCBCR_SUBSAMPLING)) {\n const v = this._tags\n .get(TiffImage.TAG_YCBCR_SUBSAMPLING)!\n .readValues();\n this._chromaSubH = v[0];\n this._chromaSubV = v[1];\n } else {\n this._chromaSubH = 2;\n this._chromaSubV = 2;\n }\n\n if (this._chromaSubH * this._chromaSubV === 1) {\n this._imageType = TiffImage.TYPE_GENERIC;\n } else if (this._bitsPerSample === 8 && this._samplesPerPixel === 3) {\n this._imageType = TiffImage.TYPE_YCBCR_SUB;\n }\n }\n break;\n // Other including CMYK, CIE L*a*b*, unknown.\n default:\n if (this._bitsPerSample % 8 === 0) {\n this._imageType = TiffImage.TYPE_GENERIC;\n }\n break;\n }\n }\n\n private readTag(type: number, defaultValue = 0): number {\n if (!this.hasTag(type)) {\n return defaultValue;\n }\n return this._tags.get(type)!.readValue();\n }\n\n private readTagList(type: number): number[] | undefined {\n if (!this.hasTag(type)) {\n return undefined;\n }\n return this._tags.get(type)!.readValues();\n }\n\n private decodeBilevelTile(\n p: InputBuffer,\n tileX: number,\n tileY: number\n ): void {\n const tileIndex = tileY * this._tilesX + tileX;\n p.offset = this._tileOffsets![tileIndex];\n\n const outX = tileX * this._tileWidth;\n const outY = tileY * this._tileHeight;\n\n const byteCount = this._tileByteCounts![tileIndex];\n\n let bdata: InputBuffer | undefined = undefined;\n if (this._compression === TiffImage.COMPRESSION_PACKBITS) {\n // Since the decompressed data will still be packed\n // 8 pixels into 1 byte, calculate bytesInThisTile\n let bytesInThisTile = 0;\n if (this._tileWidth % 8 === 0) {\n bytesInThisTile = Math.trunc(this._tileWidth / 8) * this._tileHeight;\n } else {\n bytesInThisTile =\n (Math.trunc(this._tileWidth / 8) + 1) * this._tileHeight;\n }\n bdata = new InputBuffer({\n buffer: new Uint8Array(this._tileWidth * this._tileHeight),\n });\n this.decodePackbits(p, bytesInThisTile, bdata.buffer);\n } else if (this._compression === TiffImage.COMPRESSION_LZW) {\n bdata = new InputBuffer({\n buffer: new Uint8Array(this._tileWidth * this._tileHeight),\n });\n\n const decoder = new LzwDecoder();\n decoder.decode(InputBuffer.from(p, 0, byteCount), bdata.buffer);\n\n // Horizontal Differencing Predictor\n if (this._predictor === 2) {\n let count = 0;\n for (let j = 0; j < this._height; j++) {\n count = this._samplesPerPixel * (j * this._width + 1);\n for (\n let i = this._samplesPerPixel;\n i < this._width * this._samplesPerPixel;\n i++\n ) {\n const b =\n bdata.getByte(count) +\n bdata.getByte(count - this._samplesPerPixel);\n bdata.setByte(count, b);\n count++;\n }\n }\n }\n } else if (this._compression === TiffImage.COMPRESSION_CCITT_RLE) {\n bdata = new InputBuffer({\n buffer: new Uint8Array(this._tileWidth * this._tileHeight),\n });\n try {\n const decoder = new TiffFaxDecoder({\n fillOrder: this._fillOrder,\n width: this._tileWidth,\n height: this._tileHeight,\n });\n decoder.decode1D(bdata, p, 0, this._tileHeight);\n } catch (_) {\n // skip\n }\n } else if (this._compression === TiffImage.COMPRESSION_CCITT_FAX3) {\n bdata = new InputBuffer({\n buffer: new Uint8Array(this._tileWidth * this._tileHeight),\n });\n try {\n const decoder = new TiffFaxDecoder({\n fillOrder: this._fillOrder,\n width: this._tileWidth,\n height: this._tileHeight,\n });\n decoder.decode2D(bdata, p, 0, this._tileHeight, this._t4Options);\n } catch (_) {\n // skip\n }\n } else if (this._compression === TiffImage.COMPRESSION_CCITT_FAX4) {\n bdata = new InputBuffer({\n buffer: new Uint8Array(this._tileWidth * this._tileHeight),\n });\n try {\n const decoder = new TiffFaxDecoder({\n fillOrder: this._fillOrder,\n width: this._tileWidth,\n height: this._tileHeight,\n });\n decoder.decodeT6(bdata, p, 0, this._tileHeight, this._t6Options);\n } catch (_) {\n // skip\n }\n } else if (this._compression === TiffImage.COMPRESSION_ZIP) {\n const data = p.toUint8Array(0, byteCount);\n const outData = inflate(data);\n bdata = new InputBuffer({\n buffer: outData,\n });\n } else if (this._compression === TiffImage.COMPRESSION_DEFLATE) {\n const data = p.toUint8Array(0, byteCount);\n const outData = inflate(data);\n bdata = new InputBuffer({\n buffer: outData,\n });\n } else if (this._compression === TiffImage.COMPRESSION_NONE) {\n bdata = p;\n } else {\n throw new ImageError(\n `Unsupported Compression Type: ${this._compression}`\n );\n }\n\n const br = new TiffBitReader(bdata);\n const white = this._isWhiteZero ? 0xff000000 : 0xffffffff;\n const black = this._isWhiteZero ? 0xffffffff : 0xff000000;\n\n const img = this.image!;\n for (let y = 0, py = outY; y < this._tileHeight; ++y, ++py) {\n for (let x = 0, px = outX; x < this._tileWidth; ++x, ++px) {\n if (py >= img.height || px >= img.width) break;\n if (br.readBits(1) === 0) {\n img.setPixel(px, py, black);\n } else {\n img.setPixel(px, py, white);\n }\n }\n br.flushByte();\n }\n }\n\n private decodeTile(p: InputBuffer, tileX: number, tileY: number): void {\n // Read the data, uncompressing as needed. There are four cases:\n // bilevel, palette-RGB, 4-bit grayscale, and everything else.\n if (this._imageType === TiffImage.TYPE_BILEVEL) {\n this.decodeBilevelTile(p, tileX, tileY);\n return;\n }\n\n const tileIndex = tileY * this._tilesX + tileX;\n p.offset = this._tileOffsets![tileIndex];\n\n const outX = tileX * this._tileWidth;\n const outY = tileY * this._tileHeight;\n\n const byteCount = this._tileByteCounts![tileIndex];\n let bytesInThisTile =\n this._tileWidth * this._tileHeight * this._samplesPerPixel;\n if (this._bitsPerSample === 16) {\n bytesInThisTile *= 2;\n } else if (this._bitsPerSample === 32) {\n bytesInThisTile *= 4;\n }\n\n let bdata: InputBuffer | undefined = undefined;\n if (\n this._bitsPerSample === 8 ||\n this._bitsPerSample === 16 ||\n this._bitsPerSample === 32 ||\n this._bitsPerSample === 64\n ) {\n if (this._compression === TiffImage.COMPRESSION_NONE) {\n bdata = p;\n } else if (this._compression === TiffImage.COMPRESSION_LZW) {\n bdata = new InputBuffer({\n buffer: new Uint8Array(bytesInThisTile),\n });\n const decoder = new LzwDecoder();\n try {\n decoder.decode(InputBuffer.from(p, 0, byteCount), bdata.buffer);\n } catch (e) {\n console.error(e);\n }\n // Horizontal Differencing Predictor\n if (this._predictor === 2) {\n let count = 0;\n for (let j = 0; j < this._tileHeight; j++) {\n count = this._samplesPerPixel * (j * this._tileWidth + 1);\n for (\n let i = this._samplesPerPixel,\n len = this._tileWidth * this._samplesPerPixel;\n i < len;\n i++\n ) {\n const b =\n bdata.getByte(count) +\n bdata.getByte(count - this._samplesPerPixel);\n bdata.setByte(count, b);\n count++;\n }\n }\n }\n } else if (this._compression === TiffImage.COMPRESSION_PACKBITS) {\n bdata = new InputBuffer({\n buffer: new Uint8Array(bytesInThisTile),\n });\n this.decodePackbits(p, bytesInThisTile, bdata.buffer);\n } else if (this._compression === TiffImage.COMPRESSION_DEFLATE) {\n const data = p.toUint8Array(0, byteCount);\n const outData = inflate(data);\n bdata = new InputBuffer({\n buffer: outData,\n });\n } else if (this._compression === TiffImage.COMPRESSION_ZIP) {\n const data = p.toUint8Array(0, byteCount);\n const outData = inflate(data);\n bdata = new InputBuffer({\n buffer: outData,\n });\n } else if (this._compression === TiffImage.COMPRESSION_OLD_JPEG) {\n this.image ??= new MemoryImage({\n width: this._width,\n height: this._height,\n });\n const data = p.toUint8Array(0, byteCount);\n const tile = new JpegDecoder().decodeImage(data);\n if (tile !== undefined) {\n this.jpegToImage(\n tile,\n this.image,\n outX,\n outY,\n this._tileWidth,\n this._tileHeight\n );\n }\n if (this.hdrImage !== undefined) {\n this.hdrImage = HdrImage.fromImage(this.image);\n }\n return;\n } else {\n throw new ImageError(\n `Unsupported Compression Type: ${this._compression}`\n );\n }\n\n for (\n let y = 0, py = outY;\n y < this._tileHeight && py < this._height;\n ++y, ++py\n ) {\n for (\n let x = 0, px = outX;\n x < this._tileWidth && px < this._width;\n ++x, ++px\n ) {\n if (this._samplesPerPixel === 1) {\n if (this._sampleFormat === TiffImage.FORMAT_FLOAT) {\n let sample = 0.0;\n if (this._bitsPerSample === 32) {\n sample = bdata.readFloat32();\n } else if (this._bitsPerSample === 64) {\n sample = bdata.readFloat64();\n } else if (this._bitsPerSample === 16) {\n sample = Half.halfToDouble(bdata.readUint16());\n }\n if (this.hdrImage !== undefined) {\n this.hdrImage.setRed(px, py, sample);\n }\n if (this.image !== undefined) {\n const gray = MathOperators.clampInt255(sample * 255);\n let c = 0;\n if (\n this._photometricType === 3 &&\n this._colorMap !== undefined\n ) {\n c = Color.getColor(\n this._colorMap[this.colorMapRed + gray],\n this._colorMap[this.colorMapGreen + gray],\n this._colorMap[this.colorMapBlue + gray]\n );\n } else {\n c = Color.getColor(gray, gray, gray);\n }\n this.image.setPixel(px, py, c);\n }\n } else {\n let gray = 0;\n if (this._bitsPerSample === 8) {\n gray =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt8()\n : bdata.readByte();\n } else if (this._bitsPerSample === 16) {\n gray =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt16()\n : bdata.readUint16();\n } else if (this._bitsPerSample === 32) {\n gray =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt32()\n : bdata.readUint32();\n }\n\n if (this.hdrImage !== undefined) {\n this.hdrImage.setRed(px, py, gray);\n }\n\n if (this.image !== undefined) {\n gray =\n this._bitsPerSample === 16\n ? gray >> 8\n : this._bitsPerSample === 32\n ? gray >> 24\n : gray;\n if (this._photometricType === 0) {\n gray = 255 - gray;\n }\n\n let c = 0;\n if (\n this._photometricType === 3 &&\n this._colorMap !== undefined\n ) {\n c = Color.getColor(\n this._colorMap[this.colorMapRed + gray],\n this._colorMap[this.colorMapGreen + gray],\n this._colorMap[this.colorMapBlue + gray]\n );\n } else {\n c = Color.getColor(gray, gray, gray);\n }\n\n this.image.setPixel(px, py, c);\n }\n }\n } else if (this._samplesPerPixel === 2) {\n let gray = 0;\n let alpha = 0;\n if (this._bitsPerSample === 8) {\n gray =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt8()\n : bdata.readByte();\n alpha =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt8()\n : bdata.readByte();\n } else if (this._bitsPerSample === 16) {\n gray =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt16()\n : bdata.readUint16();\n alpha =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt16()\n : bdata.readUint16();\n } else if (this._bitsPerSample === 32) {\n gray =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt32()\n : bdata.readUint32();\n alpha =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt32()\n : bdata.readUint32();\n }\n\n if (this.hdrImage !== undefined) {\n this.hdrImage.setRed(px, py, gray);\n this.hdrImage.setGreen(px, py, alpha);\n }\n\n if (this.image !== undefined) {\n gray =\n this._bitsPerSample === 16\n ? gray >> 8\n : this._bitsPerSample === 32\n ? gray >> 24\n : gray;\n alpha =\n this._bitsPerSample === 16\n ? alpha >> 8\n : this._bitsPerSample === 32\n ? alpha >> 24\n : alpha;\n const c = Color.getColor(gray, gray, gray, alpha);\n this.image.setPixel(px, py, c);\n }\n } else if (this._samplesPerPixel === 3) {\n if (this._sampleFormat === TiffImage.FORMAT_FLOAT) {\n let r = 0.0;\n let g = 0.0;\n let b = 0.0;\n if (this._bitsPerSample === 32) {\n r = bdata.readFloat32();\n g = bdata.readFloat32();\n b = bdata.readFloat32();\n } else if (this._bitsPerSample === 64) {\n r = bdata.readFloat64();\n g = bdata.readFloat64();\n b = bdata.readFloat64();\n } else if (this._bitsPerSample === 16) {\n r = Half.halfToDouble(bdata.readUint16());\n g = Half.halfToDouble(bdata.readUint16());\n b = Half.halfToDouble(bdata.readUint16());\n }\n if (this.hdrImage !== undefined) {\n this.hdrImage.setRed(px, py, r);\n this.hdrImage.setGreen(px, py, g);\n this.hdrImage.setBlue(px, py, b);\n }\n if (this.image !== undefined) {\n const ri = MathOperators.clampInt255(r * 255);\n const gi = MathOperators.clampInt255(g * 255);\n const bi = MathOperators.clampInt255(b * 255);\n const c = Color.getColor(ri, gi, bi);\n this.image.setPixel(px, py, c);\n }\n } else {\n let r = 0;\n let g = 0;\n let b = 0;\n if (this._bitsPerSample === 8) {\n r =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt8()\n : bdata.readByte();\n g =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt8()\n : bdata.readByte();\n b =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt8()\n : bdata.readByte();\n } else if (this._bitsPerSample === 16) {\n r =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt16()\n : bdata.readUint16();\n g =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt16()\n : bdata.readUint16();\n b =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt16()\n : bdata.readUint16();\n } else if (this._bitsPerSample === 32) {\n r =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt32()\n : bdata.readUint32();\n g =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt32()\n : bdata.readUint32();\n b =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt32()\n : bdata.readUint32();\n }\n\n if (this.hdrImage !== undefined) {\n this.hdrImage.setRed(px, py, r);\n this.hdrImage.setGreen(px, py, g);\n this.hdrImage.setBlue(px, py, b);\n }\n\n if (this.image !== undefined) {\n r =\n this._bitsPerSample === 16\n ? r >> 8\n : this._bitsPerSample === 32\n ? r >> 24\n : r;\n g =\n this._bitsPerSample === 16\n ? g >> 8\n : this._bitsPerSample === 32\n ? g >> 24\n : g;\n b =\n this._bitsPerSample === 16\n ? b >> 8\n : this._bitsPerSample === 32\n ? b >> 24\n : b;\n const c = Color.getColor(r, g, b);\n this.image.setPixel(px, py, c);\n }\n }\n } else if (this._samplesPerPixel >= 4) {\n if (this._sampleFormat === TiffImage.FORMAT_FLOAT) {\n let r = 0.0;\n let g = 0.0;\n let b = 0.0;\n let a = 0.0;\n if (this._bitsPerSample === 32) {\n r = bdata.readFloat32();\n g = bdata.readFloat32();\n b = bdata.readFloat32();\n a = bdata.readFloat32();\n } else if (this._bitsPerSample === 64) {\n r = bdata.readFloat64();\n g = bdata.readFloat64();\n b = bdata.readFloat64();\n a = bdata.readFloat64();\n } else if (this._bitsPerSample === 16) {\n r = Half.halfToDouble(bdata.readUint16());\n g = Half.halfToDouble(bdata.readUint16());\n b = Half.halfToDouble(bdata.readUint16());\n a = Half.halfToDouble(bdata.readUint16());\n }\n if (this.hdrImage !== undefined) {\n this.hdrImage.setRed(px, py, r);\n this.hdrImage.setGreen(px, py, g);\n this.hdrImage.setBlue(px, py, b);\n this.hdrImage.setAlpha(px, py, a);\n }\n if (this.image !== undefined) {\n const ri = MathOperators.clampInt255(r * 255);\n const gi = MathOperators.clampInt255(g * 255);\n const bi = MathOperators.clampInt255(b * 255);\n const ai = MathOperators.clampInt255(a * 255);\n const c = Color.getColor(ri, gi, bi, ai);\n this.image.setPixel(px, py, c);\n }\n } else {\n let r = 0;\n let g = 0;\n let b = 0;\n let a = 0;\n if (this._bitsPerSample === 8) {\n r =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt8()\n : bdata.readByte();\n g =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt8()\n : bdata.readByte();\n b =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt8()\n : bdata.readByte();\n a =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt8()\n : bdata.readByte();\n } else if (this._bitsPerSample === 16) {\n r =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt16()\n : bdata.readUint16();\n g =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt16()\n : bdata.readUint16();\n b =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt16()\n : bdata.readUint16();\n a =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt16()\n : bdata.readUint16();\n } else if (this._bitsPerSample === 32) {\n r =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt32()\n : bdata.readUint32();\n g =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt32()\n : bdata.readUint32();\n b =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt32()\n : bdata.readUint32();\n a =\n this._sampleFormat === TiffImage.FORMAT_INT\n ? bdata.readInt32()\n : bdata.readUint32();\n }\n\n if (this.hdrImage !== undefined) {\n this.hdrImage.setRed(px, py, r);\n this.hdrImage.setGreen(px, py, g);\n this.hdrImage.setBlue(px, py, b);\n this.hdrImage.setAlpha(px, py, a);\n }\n\n if (this.image !== undefined) {\n r =\n this._bitsPerSample === 16\n ? r >> 8\n : this._bitsPerSample === 32\n ? r >> 24\n : r;\n g =\n this._bitsPerSample === 16\n ? g >> 8\n : this._bitsPerSample === 32\n ? g >> 24\n : g;\n b =\n this._bitsPerSample === 16\n ? b >> 8\n : this._bitsPerSample === 32\n ? b >> 24\n : b;\n a =\n this._bitsPerSample === 16\n ? a >> 8\n : this._bitsPerSample === 32\n ? a >> 24\n : a;\n const c = Color.getColor(r, g, b, a);\n this.image.setPixel(px, py, c);\n }\n }\n }\n }\n }\n } else {\n throw new ImageError(`Unsupported bitsPerSample: ${this._bitsPerSample}`);\n }\n }\n\n private jpegToImage(\n tile: MemoryImage,\n image: MemoryImage,\n outX: number,\n outY: number,\n tileWidth: number,\n tileHeight: number\n ): void {\n const width = tileWidth;\n const height = tileHeight;\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n image.setPixel(x + outX, y + outY, tile.getPixel(x, y));\n }\n }\n }\n\n /**\n * Uncompress packbits compressed image data.\n */\n private decodePackbits(\n data: InputBuffer,\n arraySize: number,\n dst: Uint8Array\n ): void {\n let srcCount = 0;\n let dstCount = 0;\n\n while (dstCount < arraySize) {\n const b = BitOperators.toInt8(data.getByte(srcCount++));\n if (b >= 0 && b <= 127) {\n // literal run packet\n for (let i = 0; i < b + 1; ++i) {\n dst[dstCount++] = data.getByte(srcCount++);\n }\n } else if (b <= -1 && b >= -127) {\n // 2 byte encoded run packet\n const repeat = data.getByte(srcCount++);\n for (let i = 0; i < -b + 1; ++i) {\n dst[dstCount++] = repeat;\n }\n } else {\n // no-op packet. Do nothing\n srcCount++;\n }\n }\n }\n\n public decode(p: InputBuffer): MemoryImage {\n this.image = new MemoryImage({\n width: this._width,\n height: this._height,\n });\n for (let tileY = 0, ti = 0; tileY < this._tilesY; ++tileY) {\n for (let tileX = 0; tileX < this._tilesX; ++tileX, ++ti) {\n this.decodeTile(p, tileX, tileY);\n }\n }\n return this.image;\n }\n\n public decodeHdr(p: InputBuffer): HdrImage {\n this.hdrImage = HdrImage.create(\n this._width,\n this._height,\n this._samplesPerPixel,\n this._sampleFormat === TiffImage.FORMAT_UINT\n ? HdrSlice.UINT\n : this._sampleFormat === TiffImage.FORMAT_INT\n ? HdrSlice.INT\n : HdrSlice.FLOAT,\n this._bitsPerSample\n );\n for (let tileY = 0, ti = 0; tileY < this._tilesY; ++tileY) {\n for (let tileX = 0; tileX < this._tilesX; ++tileX, ++ti) {\n this.decodeTile(p, tileX, tileY);\n }\n }\n return this.hdrImage;\n }\n\n public hasTag(tag: number): boolean {\n return this._tags.has(tag);\n }\n}\n", "/** @format */\n\nimport { DecodeInfo } from '../decode-info';\nimport { TiffImage } from './tiff-image';\n\nexport interface TiffInfoInitOptions {\n bigEndian: boolean;\n signature: number;\n ifdOffset: number;\n images: TiffImage[];\n}\n\nexport class TiffInfo implements DecodeInfo {\n private _bigEndian: boolean;\n public get bigEndian(): boolean {\n return this._bigEndian;\n }\n\n private _signature: number;\n public get signature(): number {\n return this._signature;\n }\n\n private _ifdOffset: number;\n public get ifdOffset(): number {\n return this._ifdOffset;\n }\n\n private _images: TiffImage[] = [];\n public get images(): TiffImage[] {\n return this._images;\n }\n\n private _width = 0;\n public get width(): number {\n return this._width;\n }\n\n private _height = 0;\n public get height(): number {\n return this._height;\n }\n\n private _backgroundColor = 0xffffffff;\n get backgroundColor(): number {\n throw this._backgroundColor;\n }\n\n public get numFrames(): number {\n return this._images.length;\n }\n\n constructor(options: TiffInfoInitOptions) {\n this._bigEndian = options.bigEndian;\n this._signature = options.signature;\n this._ifdOffset = options.ifdOffset;\n this._images = options.images;\n if (this._images.length > 0) {\n this._width = this._images[0].width;\n this._height = this._images[0].height;\n }\n }\n}\n", "/** @format */\n\nimport { FrameAnimation } from '../common/frame-animation';\nimport { FrameType } from '../common/frame-type';\nimport { InputBuffer } from '../common/input-buffer';\nimport { MemoryImage } from '../common/memory-image';\nimport { ExifData } from '../exif/exif-data';\nimport { HdrImage } from '../hdr/hdr-image';\nimport { Decoder } from './decoder';\nimport { TiffImage } from './tiff/tiff-image';\nimport { TiffInfo } from './tiff/tiff-info';\n\nexport class TiffDecoder implements Decoder {\n private static readonly TIFF_SIGNATURE = 42;\n private static readonly TIFF_LITTLE_ENDIAN = 0x4949;\n private static readonly TIFF_BIG_ENDIAN = 0x4d4d;\n\n private input!: InputBuffer;\n\n private _info: TiffInfo | undefined = undefined;\n public get info(): TiffInfo | undefined {\n return this._info;\n }\n\n private _exifData: ExifData | undefined = undefined;\n public get exifData(): ExifData | undefined {\n return this._exifData;\n }\n\n /**\n * How many frames are available to be decoded. **startDecode** should have been called first.\n * Non animated image files will have a single frame.\n */\n public get numFrames(): number {\n return this._info !== undefined ? this._info.images.length : 0;\n }\n\n /**\n * Read the TIFF header and IFD blocks.\n */\n private readHeader(p: InputBuffer): TiffInfo | undefined {\n const byteOrder = p.readUint16();\n if (\n byteOrder !== TiffDecoder.TIFF_LITTLE_ENDIAN &&\n byteOrder !== TiffDecoder.TIFF_BIG_ENDIAN\n ) {\n return undefined;\n }\n\n let bigEndian = false;\n if (byteOrder === TiffDecoder.TIFF_BIG_ENDIAN) {\n p.bigEndian = true;\n bigEndian = true;\n } else {\n p.bigEndian = false;\n bigEndian = false;\n }\n\n let signature = 0;\n signature = p.readUint16();\n if (signature !== TiffDecoder.TIFF_SIGNATURE) {\n return undefined;\n }\n\n let offset = p.readUint32();\n\n const p2 = InputBuffer.from(p);\n p2.offset = offset;\n\n const images: TiffImage[] = [];\n while (offset !== 0) {\n let img: TiffImage | undefined = undefined;\n try {\n img = new TiffImage(p2);\n if (!img.isValid) {\n break;\n }\n } catch (error) {\n break;\n }\n images.push(img);\n\n offset = p2.readUint32();\n if (offset !== 0) {\n p2.offset = offset;\n }\n }\n\n return images.length > 0\n ? new TiffInfo({\n bigEndian: bigEndian,\n signature: signature,\n ifdOffset: offset,\n images: images,\n })\n : undefined;\n }\n\n /**\n * Is the given file a valid TIFF image?\n */\n public isValidFile(bytes: Uint8Array): boolean {\n const buffer = new InputBuffer({\n buffer: bytes,\n });\n return this.readHeader(buffer) !== undefined;\n }\n\n /**\n * Validate the file is a TIFF image and get information about it.\n * If the file is not a valid TIFF image, undefined is returned.\n */\n public startDecode(bytes: Uint8Array): TiffInfo | undefined {\n this.input = new InputBuffer({\n buffer: bytes,\n });\n this._info = this.readHeader(this.input);\n if (this.info !== undefined) {\n const buffer = new InputBuffer({\n buffer: bytes,\n });\n this._exifData = ExifData.fromInputBuffer(buffer);\n }\n return this._info;\n }\n\n /**\n * Decode a single frame from the data stat was set with **startDecode**.\n * If **frame** is out of the range of available frames, undefined is returned.\n * Non animated image files will only have **frame** 0. An **AnimationFrame**\n * is returned, which provides the image, and top-left coordinates of the\n * image, as animated frames may only occupy a subset of the canvas.\n */\n public decodeFrame(frame: number): MemoryImage | undefined {\n if (this._info === undefined) {\n return undefined;\n }\n\n const image = this._info.images[frame].decode(this.input);\n if (this._exifData !== undefined) {\n image.exifData = this._exifData;\n }\n return image;\n }\n\n public decodeHdrFrame(frame: number): HdrImage | undefined {\n if (this._info === undefined) {\n return undefined;\n }\n return this._info.images[frame].decodeHdr(this.input);\n }\n\n /**\n * Decode all of the frames from an animation. If the file is not an\n * animation, a single frame animation is returned. If there was a problem\n * decoding the file, undefined is returned.\n */\n public decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined {\n if (this.startDecode(bytes) === undefined) {\n return undefined;\n }\n\n const animation = new FrameAnimation({\n width: this._info!.width,\n height: this._info!.height,\n frameType: FrameType.page,\n });\n\n for (let i = 0, len = this.numFrames; i < len; ++i) {\n const image = this.decodeFrame(i);\n animation.addFrame(image!);\n }\n\n return animation;\n }\n\n /**\n * Decode the file and extract a single image from it. If the file is\n * animated, the specified **frame** will be decoded. If there was a problem\n * decoding the file, undefined is returned.\n */\n public decodeImage(bytes: Uint8Array, frame = 0): MemoryImage | undefined {\n this.input = new InputBuffer({\n buffer: bytes,\n });\n\n this._info = this.readHeader(this.input);\n if (this._info === undefined) {\n return undefined;\n }\n\n const image = this._info.images[frame].decode(this.input);\n const buffer = new InputBuffer({\n buffer: bytes,\n });\n image.exifData = ExifData.fromInputBuffer(buffer);\n return image;\n }\n\n public decodeHdrImage(bytes: Uint8Array, frame = 0): HdrImage | undefined {\n this.input = new InputBuffer({\n buffer: bytes,\n });\n\n this._info = this.readHeader(this.input);\n if (this._info === undefined) {\n return undefined;\n }\n\n const image = this._info.images[frame].decodeHdr(this.input);\n const buffer = new InputBuffer({\n buffer: bytes,\n });\n image.exifData = ExifData.fromInputBuffer(buffer);\n return image;\n }\n}\n", "/** @format */\n\nimport { FrameAnimation } from '../common/frame-animation';\nimport { MemoryImage } from '../common/memory-image';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { HdrImage } from '../hdr/hdr-image';\nimport { HdrSlice } from '../hdr/hdr-slice';\nimport { Encoder } from './encoder';\nimport { TiffEntry } from './tiff/tiff-entry';\nimport { TiffImage } from './tiff/tiff-image';\n\n/**\n * Encode a TIFF image.\n */\nexport class TiffEncoder implements Encoder {\n private static readonly LITTLE_ENDIAN = 0x4949;\n private static readonly SIGNATURE = 42;\n\n private _supportsAnimation = false;\n public get supportsAnimation(): boolean {\n return this._supportsAnimation;\n }\n\n private writeHeader(out: OutputBuffer): void {\n // byteOrder\n out.writeUint16(TiffEncoder.LITTLE_ENDIAN);\n // TIFF signature\n out.writeUint16(TiffEncoder.SIGNATURE);\n // Offset to the start of the IFD tags\n out.writeUint32(8);\n }\n\n private writeImage(out: OutputBuffer, image: MemoryImage): void {\n // number of IFD entries\n out.writeUint16(11);\n\n this.writeEntryUint32(out, TiffImage.TAG_IMAGE_WIDTH, image.width);\n this.writeEntryUint32(out, TiffImage.TAG_IMAGE_LENGTH, image.height);\n this.writeEntryUint16(out, TiffImage.TAG_BITS_PER_SAMPLE, 8);\n this.writeEntryUint16(\n out,\n TiffImage.TAG_COMPRESSION,\n TiffImage.COMPRESSION_NONE\n );\n this.writeEntryUint16(\n out,\n TiffImage.TAG_PHOTOMETRIC_INTERPRETATION,\n TiffImage.PHOTOMETRIC_RGB\n );\n this.writeEntryUint16(out, TiffImage.TAG_SAMPLES_PER_PIXEL, 4);\n this.writeEntryUint16(\n out,\n TiffImage.TAG_SAMPLE_FORMAT,\n TiffImage.FORMAT_UINT\n );\n\n this.writeEntryUint32(out, TiffImage.TAG_ROWS_PER_STRIP, image.height);\n this.writeEntryUint16(out, TiffImage.TAG_PLANAR_CONFIGURATION, 1);\n this.writeEntryUint32(\n out,\n TiffImage.TAG_STRIP_BYTE_COUNTS,\n image.width * image.height * 4\n );\n this.writeEntryUint32(out, TiffImage.TAG_STRIP_OFFSETS, out.length + 4);\n out.writeBytes(image.getBytes());\n }\n\n private writeHdrImage(out: OutputBuffer, image: HdrImage): void {\n // number of IFD entries\n out.writeUint16(11);\n\n this.writeEntryUint32(out, TiffImage.TAG_IMAGE_WIDTH, image.width);\n this.writeEntryUint32(out, TiffImage.TAG_IMAGE_LENGTH, image.height);\n this.writeEntryUint16(\n out,\n TiffImage.TAG_BITS_PER_SAMPLE,\n image.bitsPerSample\n );\n this.writeEntryUint16(\n out,\n TiffImage.TAG_COMPRESSION,\n TiffImage.COMPRESSION_NONE\n );\n this.writeEntryUint16(\n out,\n TiffImage.TAG_PHOTOMETRIC_INTERPRETATION,\n image.numberOfChannels === 1\n ? TiffImage.PHOTOMETRIC_BLACKISZERO\n : TiffImage.PHOTOMETRIC_RGB\n );\n this.writeEntryUint16(\n out,\n TiffImage.TAG_SAMPLES_PER_PIXEL,\n image.numberOfChannels\n );\n this.writeEntryUint16(\n out,\n TiffImage.TAG_SAMPLE_FORMAT,\n this.getSampleFormat(image)\n );\n\n const bytesPerSample = Math.trunc(image.bitsPerSample / 8);\n const imageSize =\n image.width * image.height * image.slices.size * bytesPerSample;\n\n this.writeEntryUint32(out, TiffImage.TAG_ROWS_PER_STRIP, image.height);\n this.writeEntryUint16(out, TiffImage.TAG_PLANAR_CONFIGURATION, 1);\n this.writeEntryUint32(out, TiffImage.TAG_STRIP_BYTE_COUNTS, imageSize);\n this.writeEntryUint32(out, TiffImage.TAG_STRIP_OFFSETS, out.length + 4);\n\n const channels: Uint8Array[] = [];\n if (image.blue !== undefined) {\n // ? Why does this channel order working but not RGB?\n channels.push(image.blue.getBytes());\n }\n if (image.red !== undefined) {\n channels.push(image.red.getBytes());\n }\n if (image.green !== undefined) {\n channels.push(image.green.getBytes());\n }\n if (image.alpha !== undefined) {\n channels.push(image.alpha.getBytes());\n }\n if (image.depth !== undefined) {\n channels.push(image.depth.getBytes());\n }\n\n for (let y = 0, pi = 0; y < image.height; ++y) {\n for (let x = 0; x < image.width; ++x, pi += bytesPerSample) {\n for (let c = 0; c < channels.length; ++c) {\n const ch = channels[c];\n for (let b = 0; b < bytesPerSample; ++b) {\n out.writeByte(ch[pi + b]);\n }\n }\n }\n }\n }\n\n private getSampleFormat(image: HdrImage): number {\n switch (image.sampleFormat) {\n case HdrSlice.UINT:\n return TiffImage.FORMAT_UINT;\n case HdrSlice.INT:\n return TiffImage.FORMAT_INT;\n }\n return TiffImage.FORMAT_FLOAT;\n }\n\n private writeEntryUint16(out: OutputBuffer, tag: number, data: number): void {\n out.writeUint16(tag);\n out.writeUint16(TiffEntry.TYPE_SHORT);\n // number of values\n out.writeUint32(1);\n out.writeUint16(data);\n // pad to 4 bytes\n out.writeUint16(0);\n }\n\n private writeEntryUint32(out: OutputBuffer, tag: number, data: number): void {\n out.writeUint16(tag);\n out.writeUint16(TiffEntry.TYPE_LONG);\n // number of values\n out.writeUint32(1);\n out.writeUint32(data);\n }\n\n public encodeImage(image: MemoryImage): Uint8Array {\n const out = new OutputBuffer();\n this.writeHeader(out);\n this.writeImage(out, image);\n // no offset to the next image\n out.writeUint32(0);\n return out.getBytes();\n }\n\n public encodeAnimation(_animation: FrameAnimation): Uint8Array | undefined {\n return undefined;\n }\n\n public encodeHdrImage(image: HdrImage): Uint8Array {\n const out = new OutputBuffer();\n this.writeHeader(out);\n this.writeHdrImage(out, image);\n // no offset to the next image\n out.writeUint32(0);\n return out.getBytes();\n }\n}\n", "/** @format */\n\nimport { MathOperators } from '../common/math-operators';\nimport { MemoryImage } from '../common/memory-image';\nimport { ImageError } from '../error/image-error';\nimport { HdrImage } from './hdr-image';\n\nexport abstract class HdrToImage {\n /**\n * Convert a high dynamic range image to a low dynamic range image,\n * with optional exposure control.\n */\n public static hdrToImage(hdr: HdrImage, exposure?: number): MemoryImage {\n const knee = (x: number, f: number) => Math.log(x * f + 1.0) / f;\n const gamma = (h: number, m: number) => {\n let x = Math.max(0, h * m);\n if (x > 1.0) {\n x = 1.0 + knee(x - 1, 0.184874);\n }\n return Math.pow(x, 0.4545) * 84.66;\n };\n\n const image = new MemoryImage({\n width: hdr.width,\n height: hdr.height,\n });\n const pixels = image.getBytes();\n\n if (!hdr.hasColor) {\n throw new ImageError('Only RGB[A] images are currently supported.');\n }\n\n const m =\n exposure !== undefined\n ? Math.pow(2.0, MathOperators.clamp(exposure + 2.47393, -20.0, 20.0))\n : 1.0;\n\n for (let y = 0, di = 0; y < hdr.height; ++y) {\n for (let x = 0; x < hdr.width; ++x) {\n let r = hdr.getRed(x, y);\n let g = hdr.numberOfChannels == 1 ? r : hdr.getGreen(x, y);\n let b = hdr.numberOfChannels == 1 ? r : hdr.getBlue(x, y);\n\n if (!Number.isFinite(r) || Number.isNaN(r)) {\n r = 0.0;\n }\n if (!Number.isFinite(g) || Number.isNaN(g)) {\n g = 0.0;\n }\n if (!Number.isFinite(b) || Number.isNaN(b)) {\n b = 0.0;\n }\n\n let ri = 0;\n let gi = 0;\n let bi = 0;\n if (exposure !== undefined) {\n ri = gamma(r, m);\n gi = gamma(g, m);\n bi = gamma(b, m);\n } else {\n ri = r * 255.0;\n gi = g * 255.0;\n bi = b * 255.0;\n }\n\n // Normalize the color\n const mi = Math.max(ri, Math.max(gi, bi));\n if (mi > 255.0) {\n ri = 255.0 * (ri / mi);\n gi = 255.0 * (gi / mi);\n bi = 255.0 * (bi / mi);\n }\n\n pixels[di++] = MathOperators.clampInt255(ri);\n pixels[di++] = MathOperators.clampInt255(gi);\n pixels[di++] = MathOperators.clampInt255(bi);\n\n if (hdr.alpha !== undefined) {\n let a = hdr.alpha!.getFloat(x, y);\n if (!Number.isFinite(a) || Number.isNaN(a)) {\n a = 1.0;\n }\n pixels[di++] = MathOperators.clampInt255(a * 255.0);\n } else {\n pixels[di++] = 255;\n }\n }\n }\n\n return image;\n }\n}\n", "/** @format */\n\nimport { MemoryImage } from '../common/memory-image';\n\nexport interface CopyIntoOptions {\n dst: MemoryImage;\n src: MemoryImage;\n dstX?: number;\n dstY?: number;\n srcX?: number;\n srcY?: number;\n srcW?: number;\n srcH?: number;\n blend?: boolean;\n center?: boolean;\n}\n", "/** @format */\n\nimport { Interpolation } from '../common/interpolation';\nimport { MemoryImage } from '../common/memory-image';\n\nexport interface CopyResizeOptionsUsingWidth {\n image: MemoryImage;\n width: number;\n height?: number;\n interpolation?: Interpolation;\n}\n\nexport interface CopyResizeOptionsUsingHeight {\n image: MemoryImage;\n height: number;\n width?: number;\n interpolation?: Interpolation;\n}\n", "/** @format */\n\nexport enum TrimMode {\n /**\n * Trim an image to the top-left and bottom-right most non-transparent pixels\n */\n transparent,\n\n /**\n * Trim an image to the top-left and bottom-right most pixels that are not the\n * same as the top-left most pixel of the image.\n */\n topLeftColor,\n\n /**\n * Trim an image to the top-left and bottom-right most pixels that are not the\n * same as the bottom-right most pixel of the image.\n */\n bottomRightColor,\n}\n", "/** @format */\n\nexport class TrimSide {\n /**\n * Trim the image down from the top.\n */\n public static readonly top = new TrimSide(1);\n\n /**\n * Trim the image up from the bottom.\n */\n public static readonly bottom = new TrimSide(2);\n\n /**\n * Trim the left edge of the image.\n */\n public static readonly left = new TrimSide(4);\n\n /**\n * Trim the right edge of the image.\n */\n public static readonly right = new TrimSide(8);\n\n /**\n * Trim all edges of the image.\n */\n public static readonly all = new TrimSide(1 | 2 | 4 | 8);\n\n private value: number;\n\n constructor(...sides: [number | TrimSide, ...(number | TrimSide)[]]) {\n this.value = 0;\n for (const s of sides) {\n this.value |= typeof s === 'number' ? s : s.value;\n }\n }\n\n public has(side: TrimSide) {\n return (this.value & side.value) !== 0;\n }\n}\n", "/** @format */\n\nimport { MemoryImage } from '../common/memory-image';\nimport { RgbChannelSet } from '../common/rgb-channel-set';\nimport { Rectangle } from '../common/rectangle';\nimport { TrimMode } from './trim-mode';\nimport { TrimSide } from './trim-side';\nimport { ImageTransform } from './image-transform';\nimport { Color } from '../common/color';\n\nexport abstract class TrimTransform {\n /**\n * Find the crop area to be used by the trim function.\n * Returns the Rectangle. You could pass these constraints\n * to the **copyCrop** function to crop the image.\n */\n private static findTrim(\n src: MemoryImage,\n mode: TrimMode = TrimMode.transparent,\n sides: TrimSide = TrimSide.all\n ) {\n let h = src.height;\n let w = src.width;\n\n const bg =\n mode === TrimMode.topLeftColor\n ? src.getPixel(0, 0)\n : mode === TrimMode.bottomRightColor\n ? src.getPixel(w - 1, h - 1)\n : 0;\n\n let xmin = w;\n let xmax = 0;\n let ymin: number | undefined = undefined;\n let ymax = 0;\n\n for (let y = 0; y < h; ++y) {\n let first = true;\n for (let x = 0; x < w; ++x) {\n const c = src.getPixel(x, y);\n if (\n (mode === TrimMode.transparent && Color.getAlpha(c) !== 0) ||\n (mode !== TrimMode.transparent && c !== bg)\n ) {\n if (xmin > x) {\n xmin = x;\n }\n if (xmax < x) {\n xmax = x;\n }\n ymin ??= y;\n\n ymax = y;\n\n if (first) {\n x = xmax;\n first = false;\n }\n }\n }\n }\n\n // A trim wasn't found\n if (ymin === undefined) {\n return new Rectangle(0, 0, w, h);\n }\n\n if (!sides.has(TrimSide.top)) {\n ymin = 0;\n }\n if (!sides.has(TrimSide.bottom)) {\n ymax = h - 1;\n }\n if (!sides.has(TrimSide.left)) {\n xmin = 0;\n }\n if (!sides.has(TrimSide.right)) {\n xmax = w - 1;\n }\n\n // Image width in pixels\n w = 1 + xmax - xmin;\n // Image height in pixels\n h = 1 + ymax - ymin;\n\n return new Rectangle(xmin, ymin, w, h);\n }\n\n /**\n * Automatically crops the image by finding the corners of the image that\n * meet the **mode** criteria (not transparent or a different color).\n *\n * **mode** can be either **TrimMode.transparent**, **TrimMode.topLeftColor** or\n * **TrimMode.bottomRightColor**.\n *\n * **sides** can be used to control which sides of the image get trimmed,\n * and can be any combination of **TrimSide.top**, **TrimSide.bottom**, **TrimSide.left**,\n * and **TrimSide.right**.\n */\n public static trim(\n src: MemoryImage,\n mode: TrimMode = TrimMode.transparent,\n sides: TrimSide = TrimSide.all\n ): MemoryImage {\n if (\n mode === TrimMode.transparent &&\n src.rgbChannelSet === RgbChannelSet.rgb\n ) {\n return MemoryImage.from(src);\n }\n\n const crop = TrimTransform.findTrim(src, mode, sides);\n\n const dst = new MemoryImage({\n width: crop.width,\n height: crop.height,\n exifData: src.exifData,\n iccProfile: src.iccProfile,\n });\n\n ImageTransform.copyInto({\n dst: dst,\n src: src,\n srcX: crop.left,\n srcY: crop.top,\n srcW: crop.width,\n srcH: crop.height,\n blend: false,\n });\n\n return dst;\n }\n}\n", "/** @format */\n\nimport { FrameAnimation } from './common/frame-animation';\nimport { MemoryImage } from './common/memory-image';\nimport { CompressionLevel, TypedArray } from './common/typings';\nimport { BmpDecoder } from './formats/bmp-decoder';\nimport { BmpEncoder } from './formats/bmp-encoder';\nimport { Decoder } from './formats/decoder';\nimport { GifDecoder } from './formats/gif-decoder';\nimport { GifEncoder } from './formats/gif-encoder';\nimport { IcoDecoder } from './formats/ico-decoder';\nimport { IcoEncoder } from './formats/ico-encoder';\nimport { JpegDecoder } from './formats/jpeg-decoder';\nimport { JpegEncoder } from './formats/jpeg-encoder';\nimport { PngDecoder } from './formats/png-decoder';\nimport { PngEncoder } from './formats/png-encoder';\nimport { TgaDecoder } from './formats/tga-decoder';\nimport { TgaEncoder } from './formats/tga-encoder';\nimport { TiffDecoder } from './formats/tiff-decoder';\nimport { TiffEncoder } from './formats/tiff-encoder';\n\n// Export types from 'common' directory\nexport { ArrayUtils } from './common/array-utils';\nexport { BitOperators } from './common/bit-operators';\nexport { BlendMode } from './common/blend-mode';\nexport { ColorChannel } from './common/color-channel';\nexport { ColorModel } from './common/color-model';\nexport { Color } from './common/color';\nexport { Crc32, Crc32Parameters } from './common/crc32';\nexport { DisposeMode } from './common/dispose-mode';\nexport { DitherKernel } from './common/dither-kernel';\nexport { DitherPixel } from './common/dither-pixel';\nexport {\n FrameAnimation,\n FrameAnimationInitOptions,\n} from './common/frame-animation';\nexport { FrameType } from './common/frame-type';\nexport { HeapNode } from './common/heap-node';\nexport { ICCProfileData } from './common/icc-profile-data';\nexport { ICCPCompressionMode } from './common/iccp-compression-mode';\nexport { InputBuffer, InputBufferInitOptions } from './common/input-buffer';\nexport { Interpolation } from './common/interpolation';\nexport { Line } from './common/line';\nexport { MathOperators } from './common/math-operators';\nexport {\n MemoryImage,\n MemoryImageInitOptions,\n MemoryImageInitOptionsColorModel,\n RgbMemoryImageInitOptions,\n} from './common/memory-image';\nexport { NeuralQuantizer } from './common/neural-quantizer';\nexport { OctreeNode } from './common/octree-node';\nexport { OctreeQuantizer } from './common/octree-quantizer';\nexport { OutputBuffer, OutputBufferInitOptions } from './common/output-buffer';\nexport { Point } from './common/point';\nexport { Quantizer } from './common/quantizer';\nexport { RandomUtils } from './common/random-utils';\nexport { Rational } from './common/rational';\nexport { Rectangle } from './common/rectangle';\nexport { RgbChannelSet } from './common/rgb-channel-set';\nexport { TextCodec } from './common/text-codec';\nexport { CompressionLevel, TypedArray, BufferEncoding } from './common/typings';\n\n// Export types from 'draw' directory\nexport { DrawImageOptions } from './draw/draw-image-options';\nexport { DrawLineOptions } from './draw/draw-line-options';\nexport { Draw } from './draw/draw';\nexport { FillFloodOptions } from './draw/fill-flood-options';\nexport { MaskFloodOptions } from './draw/mask-flood-options';\n\n// Export types from 'exif' directory\nexport { ExifAsciiValue } from './exif/exif-value/exif-ascii-value';\nexport { ExifByteValue } from './exif/exif-value/exif-byte-value';\nexport { ExifDoubleValue } from './exif/exif-value/exif-double-value';\nexport { ExifLongValue } from './exif/exif-value/exif-long-value';\nexport { ExifRationalValue } from './exif/exif-value/exif-rational-value';\nexport { ExifSByteValue } from './exif/exif-value/exif-sbyte-value';\nexport { ExifShortValue } from './exif/exif-value/exif-short-value';\nexport { ExifSingleValue } from './exif/exif-value/exif-single-value';\nexport { ExifSLongValue } from './exif/exif-value/exif-slong-value';\nexport { ExifSRationalValue } from './exif/exif-value/exif-srational-value';\nexport { ExifSShortValue } from './exif/exif-value/exif-sshort-value';\nexport { ExifUndefinedValue } from './exif/exif-value/exif-undefined-value';\nexport { ExifValue } from './exif/exif-value/exif-value';\nexport { ExifData } from './exif/exif-data';\nexport { ExifEntry } from './exif/exif-entry';\nexport { ExifIFDContainer } from './exif/exif-ifd-container';\nexport { ExifIFD } from './exif/exif-ifd';\nexport {\n ExifTag,\n ExifTagInitOptions,\n ExifGpsTags,\n ExifImageTags,\n ExifInteropTags,\n ExifTagNameToID,\n} from './exif/exif-tag';\nexport {\n ExifValueType,\n ExifValueTypeSize,\n ExifValueTypeString,\n getExifValueTypeSize,\n getExifValueTypeString,\n} from './exif/exif-value-type';\n\n// Export types from 'filter' directory\nexport { AdjustColorOptions } from './filter/adjust-color-options';\nexport { ColorOffsetOptions } from './filter/color-offset-options';\nexport { ConvolutionOptions } from './filter/convolution-options';\nexport { ImageFilter } from './filter/image-filter';\nexport { NoiseType } from './filter/noise-type';\nexport { PixelateMode } from './filter/pixelate-mode';\nexport { QuantizeMethod } from './filter/quantize-method';\nexport { QuantizeOptions } from './filter/quantize-options';\nexport { RemapColorsOptions } from './filter/remap-colors-options';\nexport { SeparableKernel } from './filter/separable-kernel';\nexport { VignetteOptions } from './filter/vignette-options';\n\n// Export types from 'formats' directory\nexport { BmpDecoder } from './formats/bmp-decoder';\nexport { BmpEncoder } from './formats/bmp-encoder';\nexport { DecodeInfo } from './formats/decode-info';\nexport { Decoder } from './formats/decoder';\nexport { Encoder } from './formats/encoder';\nexport { GifDecoder } from './formats/gif-decoder';\nexport { GifEncoder, GifEncoderInitOptions } from './formats/gif-encoder';\nexport { IcoDecoder } from './formats/ico-decoder';\nexport { IcoEncoder } from './formats/ico-encoder';\nexport { JpegDecoder } from './formats/jpeg-decoder';\nexport { JpegEncoder } from './formats/jpeg-encoder';\nexport { PngDecoder } from './formats/png-decoder';\nexport { PngEncoder, PngEncoderInitOptions } from './formats/png-encoder';\nexport { TgaDecoder } from './formats/tga-decoder';\nexport { TgaEncoder } from './formats/tga-encoder';\nexport { TiffDecoder } from './formats/tiff-decoder';\nexport { TiffEncoder } from './formats/tiff-encoder';\n\nexport { BitmapCompressionMode } from './formats/bmp/bitmap-compression-mode';\nexport { BitmapFileHeader } from './formats/bmp/bitmap-file-header';\nexport { BmpInfo } from './formats/bmp/bmp-info';\n\nexport {\n GifColorMap,\n GifColorMapInitOptions,\n} from './formats/gif/gif-color-map';\nexport { GifImageDesc } from './formats/gif/gif-image-desc';\nexport { GifInfo, GifInfoInitOptions } from './formats/gif/gif-info';\n\nexport { IcoBmpInfo } from './formats/ico/ico-bmp-info';\nexport { IcoInfoImage } from './formats/ico/ico-info-image';\nexport { IcoInfo } from './formats/ico/ico-info';\n\nexport { ComponentData } from './formats/jpeg/component-data';\nexport { JpegAdobe } from './formats/jpeg/jpeg-adobe';\nexport { JpegComponent } from './formats/jpeg/jpeg-component';\nexport { JpegData } from './formats/jpeg/jpeg-data';\nexport { JpegFrame } from './formats/jpeg/jpeg-frame';\nexport { JpegHuffman } from './formats/jpeg/jpeg-huffman';\nexport { JpegInfo } from './formats/jpeg/jpeg-info';\nexport { JpegJfif } from './formats/jpeg/jpeg-jfif';\nexport { JpegQuantize } from './formats/jpeg/jpeg-quantize';\nexport { JpegScan } from './formats/jpeg/jpeg-scan';\nexport { Jpeg } from './formats/jpeg/jpeg';\n\nexport { PngFrame, PngFrameInitOptions } from './formats/png/png-frame';\nexport { PngInfo, PngInfoInitOptions } from './formats/png/png-info';\n\nexport { TgaInfo } from './formats/tga/tga-info';\n\nexport { TiffBitReader } from './formats/tiff/tiff-bit-reader';\nexport { TiffEntry, TiffEntryInitOptions } from './formats/tiff/tiff-entry';\nexport {\n TiffFaxDecoder,\n TiffFaxDecoderInitOptions,\n} from './formats/tiff/tiff-fax-decoder';\nexport { TiffImage } from './formats/tiff/tiff-image';\nexport { TiffInfo, TiffInfoInitOptions } from './formats/tiff/tiff-info';\nexport { LzwDecoder } from './formats/tiff/tiff-lzw-decoder';\n\n// Export types from 'hdr' directory\nexport { Half } from './hdr/half';\nexport { HdrImage } from './hdr/hdr-image';\nexport { HdrSlice, HdrSliceInitOptions } from './hdr/hdr-slice';\nexport { HdrToImage } from './hdr/hdr-to-image';\n\n// Export types from 'transform' directory\nexport { CopyIntoOptions } from './transform/copy-into-options';\nexport {\n CopyResizeOptionsUsingHeight,\n CopyResizeOptionsUsingWidth,\n} from './transform/copy-resize-options';\nexport { FlipDirection } from './transform/flip-direction';\nexport { ImageTransform } from './transform/image-transform';\nexport { TrimMode } from './transform/trim-mode';\nexport { TrimSide } from './transform/trim-side';\nexport { TrimTransform } from './transform/trim';\n\n/**\n * Find a **Decoder** that is able to decode the given image **data**.\n * Use this is you don't know the type of image it is. Since this will\n * validate the image against all known decoders, it is potentially very slow.\n */\nexport function findDecoderForData(data: TypedArray): Decoder | undefined {\n // The letious decoders will be creating a Uint8List for their InputStream\n // if the data isn't already that type, so do it once here to avoid having to\n // do it multiple times.\n const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);\n\n const jpg = new JpegDecoder();\n if (jpg.isValidFile(bytes)) {\n return jpg;\n }\n\n const png = new PngDecoder();\n if (png.isValidFile(bytes)) {\n return png;\n }\n\n const gif = new GifDecoder();\n if (gif.isValidFile(bytes)) {\n return gif;\n }\n\n const tiff = new TiffDecoder();\n if (tiff.isValidFile(bytes)) {\n return tiff;\n }\n\n const bmp = new BmpDecoder();\n if (bmp.isValidFile(bytes)) {\n return bmp;\n }\n\n const tga = new TgaDecoder();\n if (tga.isValidFile(bytes)) {\n return tga;\n }\n\n const ico = new IcoDecoder();\n if (ico.isValidFile(bytes)) {\n return ico;\n }\n\n return undefined;\n}\n\n/**\n * Decode the given image file bytes by first identifying the format of the\n * file and using that decoder to decode the file into a single frame [Image].\n */\nexport function decodeImage(data: TypedArray): MemoryImage | undefined {\n const decoder = findDecoderForData(data);\n if (decoder === undefined) {\n return undefined;\n }\n const dataUint8 = new Uint8Array(data);\n return decoder.decodeImage(dataUint8);\n}\n\n/**\n * Decode the given image file bytes by first identifying the format of the\n * file and using that decoder to decode the file into an **FrameAnimation**\n * containing one or more **MemoryImage** frames.\n */\nexport function decodeAnimation(data: TypedArray): FrameAnimation | undefined {\n const decoder = findDecoderForData(data);\n if (decoder === undefined) {\n return undefined;\n }\n const dataUint8 = new Uint8Array(data);\n return decoder.decodeAnimation(dataUint8);\n}\n\n/**\n * Return the **Decoder** that can decode image with the given **name**,\n * by looking at the file extension. See also **findDecoderForData** to\n * determine the decoder to use given the bytes of the file.\n */\nexport function getDecoderForNamedImage(name: string): Decoder | undefined {\n const n = name.toLowerCase();\n if (n.endsWith('.jpg') || n.endsWith('.jpeg')) {\n return new JpegDecoder();\n }\n if (n.endsWith('.png')) {\n return new PngDecoder();\n }\n if (n.endsWith('.tga')) {\n return new TgaDecoder();\n }\n if (n.endsWith('.gif')) {\n return new GifDecoder();\n }\n if (n.endsWith('.tif') || n.endsWith('.tiff')) {\n return new TiffDecoder();\n }\n if (n.endsWith('.bmp')) {\n return new BmpDecoder();\n }\n if (n.endsWith('.ico')) {\n return new IcoDecoder();\n }\n return undefined;\n}\n\n/**\n * Identify the format of the image using the file extension of the given\n * **name**, and decode the given file **bytes** to an **FrameAnimation** with one or more\n * **MemoryImage** frames. See also **decodeAnimation**.\n */\nexport function decodeNamedAnimation(\n data: TypedArray,\n name: string\n): FrameAnimation | undefined {\n const decoder = getDecoderForNamedImage(name);\n if (decoder === undefined) {\n return undefined;\n }\n const dataUint8 = new Uint8Array(data);\n return decoder.decodeAnimation(dataUint8);\n}\n\n/**\n * Identify the format of the image using the file extension of the given\n * **name**, and decode the given file **data** to a single frame **MemoryImage**. See\n * also **decodeImage**.\n */\nexport function decodeNamedImage(\n data: TypedArray,\n name: string\n): MemoryImage | undefined {\n const decoder = getDecoderForNamedImage(name);\n if (decoder === undefined) {\n return undefined;\n }\n const dataUint8 = new Uint8Array(data);\n return decoder.decodeImage(dataUint8);\n}\n\n/**\n * Identify the format of the image and encode it with the appropriate\n * **Encoder**.\n */\nexport function encodeNamedImage(\n image: MemoryImage,\n name: string\n): Uint8Array | undefined {\n const n = name.toLowerCase();\n if (n.endsWith('.jpg') || n.endsWith('.jpeg')) {\n return encodeJpg(image);\n }\n if (n.endsWith('.png')) {\n return encodePng(image);\n }\n if (n.endsWith('.tga')) {\n return encodeTga(image);\n }\n if (n.endsWith('.gif')) {\n return encodeGif(image);\n }\n if (n.endsWith('.ico')) {\n return encodeIco(image);\n }\n if (n.endsWith('.bmp')) {\n return encodeBmp(image);\n }\n return undefined;\n}\n\n/**\n * Decode a JPG formatted image.\n */\nexport function decodeJpg(data: TypedArray): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(data);\n return new JpegDecoder().decodeImage(dataUint8);\n}\n\n/**\n * Encode an image to the JPEG format.\n */\nexport function encodeJpg(image: MemoryImage, quality = 100): Uint8Array {\n return new JpegEncoder(quality).encodeImage(image);\n}\n\n/**\n * Decode a PNG formatted image.\n */\nexport function decodePng(data: TypedArray): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(data);\n return new PngDecoder().decodeImage(dataUint8);\n}\n\n/**\n * Decode a PNG formatted animation.\n */\nexport function decodePngAnimation(\n data: TypedArray\n): FrameAnimation | undefined {\n const dataUint8 = new Uint8Array(data);\n return new PngDecoder().decodeAnimation(dataUint8);\n}\n\n/**\n * Encode an image to the PNG format.\n */\nexport function encodePng(\n image: MemoryImage,\n level: CompressionLevel = 6\n): Uint8Array {\n return new PngEncoder({\n level: level,\n }).encodeImage(image);\n}\n\n/**\n * Encode an animation to the PNG format.\n */\nexport function encodePngAnimation(\n animation: FrameAnimation,\n level: CompressionLevel = 6\n): Uint8Array | undefined {\n return new PngEncoder({\n level: level,\n }).encodeAnimation(animation);\n}\n\n/**\n * Decode a Targa formatted image.\n */\nexport function decodeTga(data: TypedArray): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(data);\n return new TgaDecoder().decodeImage(dataUint8);\n}\n\n/**\n * Encode an image to the Targa format.\n */\nexport function encodeTga(image: MemoryImage): Uint8Array {\n return new TgaEncoder().encodeImage(image);\n}\n\n/**\n * Decode a GIF formatted image (first frame for animations).\n */\nexport function decodeGif(data: TypedArray): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(data);\n return new GifDecoder().decodeImage(dataUint8);\n}\n\n/**\n * Decode an animated GIF file. If the GIF isn't animated, the animation\n * will contain a single frame with the GIF's image.\n */\nexport function decodeGifAnimation(\n data: TypedArray\n): FrameAnimation | undefined {\n const dataUint8 = new Uint8Array(data);\n return new GifDecoder().decodeAnimation(dataUint8);\n}\n\n/**\n * Encode an image to the GIF format.\n *\n * The **samplingFactor** specifies the sampling factor for\n * image quantization. It is responsible for reducing\n * the amount of unique colors in your images to 256.\n * According to https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/,\n * a sampling factor of 10 gives you a reasonable trade-off between\n * image quality and quantization speed.\n * If you know that you have less than 256 colors in your frames\n * anyway, you should supply a very large **samplingFactor** for maximum performance.\n */\nexport function encodeGif(image: MemoryImage, samplingFactor = 10): Uint8Array {\n return new GifEncoder({\n samplingFactor: samplingFactor,\n }).encodeImage(image);\n}\n\n/**\n * Encode an animation to the GIF format.\n *\n * The **samplingFactor** specifies the sampling factor for\n * NeuQuant image quantization. It is responsible for reducing\n * the amount of unique colors in your images to 256.\n * According to https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/,\n * a sampling factor of 10 gives you a reasonable trade-off between\n * image quality and quantization speed.\n * If you know that you have less than 256 colors in your frames\n * anyway, you should supply a very large **samplingFactor** for maximum performance.\n *\n * Here, `30` is used a default value for the **samplingFactor** as\n * encoding animations is usually a process that takes longer than\n * encoding a single image (see **encodeGif**).\n */\nexport function encodeGifAnimation(\n animation: FrameAnimation,\n samplingFactor = 10\n): Uint8Array | undefined {\n return new GifEncoder({\n samplingFactor: samplingFactor,\n }).encodeAnimation(animation);\n}\n\n/**\n * Decode a TIFF formatted image.\n */\nexport function decodeTiff(data: TypedArray): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(data);\n return new TiffDecoder().decodeImage(dataUint8);\n}\n\n/**\n * Decode an multi-image (animated) TIFF file. If the tiff doesn't have\n * multiple images, the animation will contain a single frame with the tiff's\n * image.\n */\nexport function decodeTiffAnimation(\n data: TypedArray\n): FrameAnimation | undefined {\n const dataUint8 = new Uint8Array(data);\n return new TiffDecoder().decodeAnimation(dataUint8);\n}\n\n/**\n * Encode an image to the TIFF format.\n */\nexport function encodeTiff(image: MemoryImage): Uint8Array {\n return new TiffEncoder().encodeImage(image);\n}\n\n/**\n * Decode a BMP formatted image.\n */\nexport function decodeBmp(data: TypedArray): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(data);\n return new BmpDecoder().decodeImage(dataUint8);\n}\n\n/**\n * Encode an image to the BMP format.\n */\nexport function encodeBmp(image: MemoryImage): Uint8Array {\n return new BmpEncoder().encodeImage(image);\n}\n\n/**\n * Encode an image to the ICO format.\n */\nexport function encodeIco(image: MemoryImage): Uint8Array {\n return new IcoEncoder().encodeImage(image);\n}\n\n/**\n * Encode a list of images to the ICO format.\n */\nexport function encodeIcoImages(images: MemoryImage[]): Uint8Array {\n return new IcoEncoder().encodeImages(images);\n}\n\n/**\n * Decode an ICO image.\n */\nexport function decodeIco(data: TypedArray): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(data);\n return new IcoDecoder().decodeImage(dataUint8);\n}\n", "\r\n\r\nvar UZIP = {};\r\nif(typeof module == \"object\") module.exports = UZIP;\r\n\r\n\r\nUZIP[\"parse\"] = function(buf, onlyNames)\t// ArrayBuffer\r\n{\r\n\tvar rUs = UZIP.bin.readUshort, rUi = UZIP.bin.readUint, o = 0, out = {};\r\n\tvar data = new Uint8Array(buf);\r\n\tvar eocd = data.length-4;\r\n\t\r\n\twhile(rUi(data, eocd)!=0x06054b50) eocd--;\r\n\t\r\n\tvar o = eocd;\r\n\to+=4;\t// sign = 0x06054b50\r\n\to+=4; // disks = 0;\r\n\tvar cnu = rUs(data, o); o+=2;\r\n\tvar cnt = rUs(data, o); o+=2;\r\n\t\t\t\r\n\tvar csize = rUi(data, o); o+=4;\r\n\tvar coffs = rUi(data, o); o+=4;\r\n\t\r\n\to = coffs;\r\n\tfor(var i=0; i8514000) {\r\n\t\t\t//console.log(PUtils.readASCII(buf , 8514500, 500));\r\n\t\t\t//console.log(PUtils.readASCII(nbuf, 8514500, 500));\r\n\t\t}\r\n\t\tfor(var i=0; i>>4);\r\n\t//console.log(CM, CINFO,CMF,FLG);\r\n\treturn UZIP.inflateRaw(new Uint8Array(file.buffer, file.byteOffset+2, file.length-6), buf); \r\n}\r\nUZIP.deflate = function(data, opts/*, buf, off*/) {\r\n\tif(opts==null) opts={level:6};\r\n\tvar off=0, buf=new Uint8Array(50+Math.floor(data.length*1.1));\r\n\tbuf[off]=120; buf[off+1]=156; off+=2;\r\n\toff = UZIP.F.deflateRaw(data, buf, off, opts.level);\r\n\tvar crc = UZIP.adler(data, 0, data.length);\r\n\tbuf[off+0]=((crc>>>24)&255); \r\n\tbuf[off+1]=((crc>>>16)&255); \r\n\tbuf[off+2]=((crc>>> 8)&255); \r\n\tbuf[off+3]=((crc>>> 0)&255); \t\r\n\treturn new Uint8Array(buf.buffer, 0, off+4);\r\n}\r\nUZIP.deflateRaw = function(data, opts) {\r\n\tif(opts==null) opts={level:6};\r\n\tvar buf=new Uint8Array(50+Math.floor(data.length*1.1));\r\n\tvar off = UZIP.F.deflateRaw(data, buf, off, opts.level);\r\n\treturn new Uint8Array(buf.buffer, 0, off);\r\n}\r\n\r\n\r\nUZIP.encode = function(obj, noCmpr) {\r\n\tif(noCmpr==null) noCmpr=false;\r\n\tvar tot = 0, wUi = UZIP.bin.writeUint, wUs = UZIP.bin.writeUshort;\r\n\tvar zpd = {};\r\n\tfor(var p in obj) { var cpr = !UZIP._noNeed(p) && !noCmpr, buf = obj[p], crc = UZIP.crc.crc(buf,0,buf.length); \r\n\t\tzpd[p] = { cpr:cpr, usize:buf.length, crc:crc, file: (cpr ? UZIP.deflateRaw(buf) : buf) }; }\r\n\t\r\n\tfor(var p in zpd) tot += zpd[p].file.length + 30 + 46 + 2*UZIP.bin.sizeUTF8(p);\r\n\ttot += 22;\r\n\t\r\n\tvar data = new Uint8Array(tot), o = 0;\r\n\tvar fof = []\r\n\t\r\n\tfor(var p in zpd) {\r\n\t\tvar file = zpd[p]; fof.push(o);\r\n\t\to = UZIP._writeHeader(data, o, p, file, 0);\r\n\t}\r\n\tvar i=0, ioff = o;\r\n\tfor(var p in zpd) {\r\n\t\tvar file = zpd[p]; fof.push(o);\r\n\t\to = UZIP._writeHeader(data, o, p, file, 1, fof[i++]);\t\t\r\n\t}\r\n\tvar csize = o-ioff;\r\n\t\r\n\twUi(data, o, 0x06054b50); o+=4;\r\n\to += 4; // disks\r\n\twUs(data, o, i); o += 2;\r\n\twUs(data, o, i); o += 2;\t// number of c d records\r\n\twUi(data, o, csize); o += 4;\r\n\twUi(data, o, ioff ); o += 4;\r\n\to += 2;\r\n\treturn data.buffer;\r\n}\r\n// no need to compress .PNG, .ZIP, .JPEG ....\r\nUZIP._noNeed = function(fn) { var ext = fn.split(\".\").pop().toLowerCase(); return \"png,jpg,jpeg,zip\".indexOf(ext)!=-1; }\r\n\r\nUZIP._writeHeader = function(data, o, p, obj, t, roff)\r\n{\r\n\tvar wUi = UZIP.bin.writeUint, wUs = UZIP.bin.writeUshort;\r\n\tvar file = obj.file;\r\n\t\r\n\twUi(data, o, t==0 ? 0x04034b50 : 0x02014b50); o+=4; // sign\r\n\tif(t==1) o+=2; // ver made by\r\n\twUs(data, o, 20); o+=2;\t// ver\r\n\twUs(data, o, 0); o+=2; // gflip\r\n\twUs(data, o, obj.cpr?8:0); o+=2;\t// cmpr\r\n\t\t\r\n\twUi(data, o, 0); o+=4;\t// time\t\t\r\n\twUi(data, o, obj.crc); o+=4;\t// crc32\r\n\twUi(data, o, file.length); o+=4;\t// csize\r\n\twUi(data, o, obj.usize); o+=4;\t// usize\r\n\t\t\r\n\twUs(data, o, UZIP.bin.sizeUTF8(p)); o+=2;\t// nlen\r\n\twUs(data, o, 0); o+=2;\t// elen\r\n\t\r\n\tif(t==1) {\r\n\t\to += 2; // comment length\r\n\t\to += 2; // disk number\r\n\t\to += 6; // attributes\r\n\t\twUi(data, o, roff); o+=4;\t// usize\r\n\t}\r\n\tvar nlen = UZIP.bin.writeUTF8(data, o, p); o+= nlen;\t\r\n\tif(t==0) { data.set(file, o); o += file.length; }\r\n\treturn o;\r\n}\r\n\r\n\r\n\r\n\r\n\r\nUZIP.crc = {\r\n\ttable : ( function() {\r\n\t var tab = new Uint32Array(256);\r\n\t for (var n=0; n<256; n++) {\r\n\t\t\tvar c = n;\r\n\t\t\tfor (var k=0; k<8; k++) {\r\n\t\t\t\tif (c & 1) c = 0xedb88320 ^ (c >>> 1);\r\n\t\t\t\telse c = c >>> 1;\r\n\t\t\t}\r\n\t\t\ttab[n] = c; } \r\n\t\treturn tab; })(),\r\n\tupdate : function(c, buf, off, len) {\r\n\t\tfor (var i=0; i>> 8);\r\n\t\treturn c;\r\n\t},\r\n\tcrc : function(b,o,l) { return UZIP.crc.update(0xffffffff,b,o,l) ^ 0xffffffff; }\r\n}\r\nUZIP.adler = function(data,o,len) {\r\n\tvar a = 1, b = 0;\r\n\tvar off = o, end=o+len;\r\n\twhile(off>8)&255; },\r\n\treadUint : function(buff,p) { return (buff[p+3]*(256*256*256)) + ((buff[p+2]<<16) | (buff[p+1]<< 8) | buff[p]); },\r\n\twriteUint : function(buff,p,n){ buff[p]=n&255; buff[p+1]=(n>>8)&255; buff[p+2]=(n>>16)&255; buff[p+3]=(n>>24)&255; },\r\n\treadASCII : function(buff,p,l){ var s = \"\"; for(var i=0; i> 6)); buff[p+i+1] = (128|((code>> 0)&63)); i+=2; }\r\n\t\t\telse if((code&(0xffffffff-(1<<16)+1))==0) { buff[p+i] = (224|(code>>12)); buff[p+i+1] = (128|((code>> 6)&63)); buff[p+i+2] = (128|((code>>0)&63)); i+=3; }\r\n\t\t\telse if((code&(0xffffffff-(1<<21)+1))==0) { buff[p+i] = (240|(code>>18)); buff[p+i+1] = (128|((code>>12)&63)); buff[p+i+2] = (128|((code>>6)&63)); buff[p+i+3] = (128|((code>>0)&63)); i+=4; }\r\n\t\t\telse throw \"e\";\r\n\t\t}\r\n\t\treturn i;\r\n\t},\r\n\tsizeUTF8 : function(str) {\r\n\t\tvar strl = str.length, i=0;\r\n\t\tfor(var ci=0; ci>>3;\r\n\t}\r\n\r\n\tvar lits = U.lits, strt=U.strt, prev=U.prev, li=0, lc=0, bs=0, ebits=0, c=0, nc=0; // last_item, literal_count, block_start\r\n\tif(dlen>2) { nc=UZIP.F._hash(data,0); strt[nc]=0; }\r\n\tvar nmch=0,nmci=0;\r\n\t\r\n\tfor(i=0; i14000 || lc>26697) && (dlen-i)>100) {\r\n\t\t\t\tif(cvrd>>16)>>16)>(mch>>>16)) mch=0;\r\n\t\t\t}//*/\r\n\t\t\tvar len = mch>>>16, dst = mch&0xffff; //if(i-dst<0) throw \"e\";\r\n\t\t\tif(mch!=0) { \r\n\t\t\t\tvar len = mch>>>16, dst = mch&0xffff; //if(i-dst<0) throw \"e\";\r\n\t\t\t\tvar lgi = goodIndex(len, U.of0); U.lhst[257+lgi]++; \r\n\t\t\t\tvar dgi = goodIndex(dst, U.df0); U.dhst[ dgi]++; ebits += U.exb[lgi] + U.dxb[dgi]; \r\n\t\t\t\tlits[li] = (len<<23)|(i-cvrd); lits[li+1] = (dst<<16)|(lgi<<8)|dgi; li+=2;\r\n\t\t\t\tcvrd = i + len; \r\n\t\t\t}\r\n\t\t\telse {\tU.lhst[data[i]]++; }\r\n\t\t\tlc++;\r\n\t\t}\r\n\t}\r\n\tif(bs!=i || data.length==0) {\r\n\t\tif(cvrd>>3;\r\n}\r\nUZIP.F._bestMatch = function(data, i, prev, c, nice, chain) {\r\n\tvar ci = (i&0x7fff), pi=prev[ci]; \r\n\t//console.log(\"----\", i);\r\n\tvar dif = ((ci-pi + (1<<15)) & 0x7fff); if(pi==ci || c!=UZIP.F._hash(data,i-dif)) return 0;\r\n\tvar tl=0, td=0; // top length, top distance\r\n\tvar dlim = Math.min(0x7fff, i);\r\n\twhile(dif<=dlim && --chain!=0 && pi!=ci /*&& c==UZIP.F._hash(data,i-dif)*/) {\r\n\t\tif(tl==0 || (data[i+tl]==data[i+tl-dif])) {\r\n\t\t\tvar cl = UZIP.F._howLong(data, i, dif);\r\n\t\t\tif(cl>tl) { \r\n\t\t\t\ttl=cl; td=dif; if(tl>=nice) break; //* \r\n\t\t\t\tif(dif+2maxd) { maxd=curd; pi = ei; }\r\n\t\t\t\t} //*/\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tci=pi; pi = prev[ci];\r\n\t\tdif += ((ci-pi + (1<<15)) & 0x7fff);\r\n\t}\r\n\treturn (tl<<16)|td;\r\n}\r\nUZIP.F._howLong = function(data, i, dif) {\r\n\tif(data[i]!=data[i-dif] || data[i+1]!=data[i+1-dif] || data[i+2]!=data[i+2-dif]) return 0;\r\n\tvar oi=i, l = Math.min(data.length, i+258); i+=3;\r\n\t//while(i+4>>23), end = off+(qb&((1<<23)-1));\r\n\t\t\twhile(off>16), lgi=(qc>>8)&255, dgi=(qc&255);\r\n\t\t\t\tpos = UZIP.F._writeLit(257+lgi, ltree, out, pos);\r\n\t\t\t\tputsE(out, pos, len-U.of0[lgi]); pos+=U.exb[lgi];\r\n\t\t\t\t\r\n\t\t\t\tpos = UZIP.F._writeLit(dgi, dtree, out, pos);\r\n\t\t\t\tputsF(out, pos, dst-U.df0[dgi]); pos+=U.dxb[dgi]; off+=len;\r\n\t\t\t}\r\n\t\t}\r\n\t\tpos = UZIP.F._writeLit(256, ltree, out, pos);\r\n\t}\r\n\t//console.log(pos-opos, fxdSize, dynSize, cstSize);\r\n\treturn pos;\r\n}\r\nUZIP.F._copyExact = function(data,off,len,out,pos) {\r\n\tvar p8 = (pos>>>3);\r\n\tout[p8]=(len); out[p8+1]=(len>>>8); out[p8+2]=255-out[p8]; out[p8+3]=255-out[p8+1]; p8+=4;\r\n\tout.set(new Uint8Array(data.buffer, off, len), p8);\r\n\t//for(var i=0; i4 && U.itree[(U.ordr[numh-1]<<1)+1]==0) numh--;\r\n\treturn [ML, MD, MH, numl, numd, numh, lset, dset];\r\n}\r\nUZIP.F.getSecond= function(a) { var b=[]; for(var i=0; i>1)+\",\"; return b; }\r\nUZIP.F.contSize = function(tree, hst) { var s=0; for(var i=0; i15) { UZIP.F._putsE(out, pos, rst, rsl); pos+=rsl; }\r\n\t}\r\n\treturn pos;\r\n}\r\nUZIP.F._lenCodes = function(tree, set) {\r\n\tvar len=tree.length; while(len!=2 && tree[len-1]==0) len-=2; // when no distances, keep one code with length 0\r\n\tfor(var i=0; i>>1, 138);\r\n\t\t\tif(zc<11) set.push(17, zc-3);\r\n\t\t\telse set.push(18, zc-11);\r\n\t\t\ti += zc*2-2;\r\n\t\t}\r\n\t\telse if(l==prv && nxt==l && nnxt==l) {\r\n\t\t\tvar lz = i+5;\r\n\t\t\twhile(lz+2>>1, 6);\r\n\t\t\tset.push(16, zc-3);\r\n\t\t\ti += zc*2-2;\r\n\t\t}\r\n\t\telse set.push(l, 0);\r\n\t}\r\n\treturn len>>>1;\r\n}\r\nUZIP.F._hufTree = function(hst, tree, MAXL) {\r\n\tvar list=[], hl = hst.length, tl=tree.length, i=0;\r\n\tfor(i=0; iMAXL) { UZIP.F.restrictDepth(l2, MAXL, maxl); maxl = MAXL; }\r\n\tfor(i=0; iMD) { var od=dps[i].d; dps[i].d=MD; dbt+=bCost-(1<<(maxl-od)); } else break;\r\n\tdbt = dbt>>>(maxl-MD);\r\n\twhile(dbt>0) { var od=dps[i].d; if(od=0; i--) if(dps[i].d==MD && dbt<0) { dps[i].d--; dbt++; } if(dbt!=0) console.log(\"debt left\");\r\n}\r\n\r\nUZIP.F._goodIndex = function(v, arr) {\r\n\tvar i=0; if(arr[i|16]<=v) i|=16; if(arr[i|8]<=v) i|=8; if(arr[i|4]<=v) i|=4; if(arr[i|2]<=v) i|=2; if(arr[i|1]<=v) i|=1; return i;\r\n}\r\nUZIP.F._writeLit = function(ch, ltree, out, pos) {\r\n\tUZIP.F._putsF(out, pos, ltree[ch<<1]);\r\n\treturn pos+ltree[(ch<<1)+1];\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nUZIP.F.inflate = function(data, buf) {\r\n\tvar u8=Uint8Array;\r\n\tif(data[0]==3 && data[1]==0) return (buf ? buf : new u8(0));\r\n\tvar F=UZIP.F, bitsF = F._bitsF, bitsE = F._bitsE, decodeTiny = F._decodeTiny, makeCodes = F.makeCodes, codes2map=F.codes2map, get17 = F._get17;\r\n\tvar U = F.U;\r\n\t\r\n\tvar noBuf = (buf==null);\r\n\tif(noBuf) buf = new u8((data.length>>>2)<<3);\r\n\t\r\n\tvar BFINAL=0, BTYPE=0, HLIT=0, HDIST=0, HCLEN=0, ML=0, MD=0; \t\r\n\tvar off = 0, pos = 0;\r\n\tvar lmap, dmap;\r\n\t\r\n\twhile(BFINAL==0) {\t\t\r\n\t\tBFINAL = bitsF(data, pos , 1);\r\n\t\tBTYPE = bitsF(data, pos+1, 2); pos+=3;\r\n\t\t//console.log(BFINAL, BTYPE);\r\n\t\t\r\n\t\tif(BTYPE==0) {\r\n\t\t\tif((pos&7)!=0) pos+=8-(pos&7);\r\n\t\t\tvar p8 = (pos>>>3)+4, len = data[p8-4]|(data[p8-3]<<8); //console.log(len);//bitsF(data, pos, 16), \r\n\t\t\tif(noBuf) buf=UZIP.F._check(buf, off+len);\r\n\t\t\tbuf.set(new u8(data.buffer, data.byteOffset+p8, len), off);\r\n\t\t\t//for(var i=0; itl)tl=l; } pos+=3*HCLEN; //console.log(itree);\r\n\t\t\tmakeCodes(U.itree, tl);\r\n\t\t\tcodes2map(U.itree, tl, U.imap);\r\n\t\t\t\r\n\t\t\tlmap = U.lmap; dmap = U.dmap;\r\n\t\t\t\r\n\t\t\tpos = decodeTiny(U.imap, (1<>>24))-1; pos+=(ml&0xffffff);\r\n\t\t\tmakeCodes(U.ltree, mx0);\r\n\t\t\tcodes2map(U.ltree, mx0, lmap);\r\n\t\t\t\r\n\t\t\t//var md = decodeTiny(U.imap, (1<>>24))-1; pos+=(md&0xffffff);\r\n\t\t\tmakeCodes(U.dtree, mx1);\r\n\t\t\tcodes2map(U.dtree, mx1, dmap);\r\n\t\t}\r\n\t\t//var ooff=off, opos=pos;\r\n\t\twhile(true) {\r\n\t\t\tvar code = lmap[get17(data, pos) & ML]; pos += code&15;\r\n\t\t\tvar lit = code>>>4; //U.lhst[lit]++; \r\n\t\t\tif((lit>>>8)==0) { buf[off++] = lit; }\r\n\t\t\telse if(lit==256) { break; }\r\n\t\t\telse {\r\n\t\t\t\tvar end = off+lit-254;\r\n\t\t\t\tif(lit>264) { var ebs = U.ldef[lit-257]; end = off + (ebs>>>3) + bitsE(data, pos, ebs&7); pos += ebs&7; }\r\n\t\t\t\t//UZIP.F.dst[end-off]++;\r\n\t\t\t\t\r\n\t\t\t\tvar dcode = dmap[get17(data, pos) & MD]; pos += dcode&15;\r\n\t\t\t\tvar dlit = dcode>>>4;\r\n\t\t\t\tvar dbs = U.ddef[dlit], dst = (dbs>>>4) + bitsF(data, pos, dbs&15); pos += dbs&15;\r\n\t\t\t\t\r\n\t\t\t\t//var o0 = off-dst, stp = Math.min(end-off, dst);\r\n\t\t\t\t//if(stp>20) while(off>>3);\r\n\t}\r\n\t//console.log(UZIP.F.dst);\r\n\t//console.log(tlen, dlen, off-tlen+tcnt);\r\n\treturn buf.length==off ? buf : buf.slice(0,off);\r\n}\r\nUZIP.F._check=function(buf, len) {\r\n\tvar bl=buf.length; if(len<=bl) return buf;\r\n\tvar nbuf = new Uint8Array(Math.max(bl<<1,len)); nbuf.set(buf,0);\r\n\t//for(var i=0; i>>4; \r\n\t\tif(lit<=15) { tree[i]=lit; i++; }\r\n\t\telse {\r\n\t\t\tvar ll = 0, n = 0;\r\n\t\t\tif(lit==16) {\r\n\t\t\t\tn = (3 + bitsE(data, pos, 2)); pos += 2; ll = tree[i-1];\r\n\t\t\t}\r\n\t\t\telse if(lit==17) {\r\n\t\t\t\tn = (3 + bitsE(data, pos, 3)); pos += 3;\r\n\t\t\t}\r\n\t\t\telse if(lit==18) {\r\n\t\t\t\tn = (11 + bitsE(data, pos, 7)); pos += 7;\r\n\t\t\t}\r\n\t\t\tvar ni = i+n;\r\n\t\t\twhile(i>>1;\r\n\twhile(imx)mx=v; i++; }\r\n\twhile(i>1;\r\n\t\tvar cl = tree[i+1], val = (lit<<4)|cl; // : (0x8000 | (U.of0[lit-257]<<7) | (U.exb[lit-257]<<4) | cl);\r\n\t\tvar rest = (MAX_BITS-cl), i0 = tree[i]<>>(15-MAX_BITS);\r\n\t\twhile(i0!=i1) {\r\n\t\t\tvar p0 = r15[i0]>>>(15-MAX_BITS);\r\n\t\t\tmap[p0]=val; i0++;\r\n\t\t}\r\n\t}\r\n}\r\nUZIP.F.revCodes = function(tree, MAX_BITS) {\r\n\tvar r15 = UZIP.F.U.rev15, imb = 15-MAX_BITS;\r\n\tfor(var i=0; i>>imb; }\r\n}\r\n\r\n// used only in deflate\r\nUZIP.F._putsE= function(dt, pos, val ) { val = val<<(pos&7); var o=(pos>>>3); dt[o]|=val; dt[o+1]|=(val>>>8); }\r\nUZIP.F._putsF= function(dt, pos, val ) { val = val<<(pos&7); var o=(pos>>>3); dt[o]|=val; dt[o+1]|=(val>>>8); dt[o+2]|=(val>>>16); }\r\n\r\nUZIP.F._bitsE= function(dt, pos, length) { return ((dt[pos>>>3] | (dt[(pos>>>3)+1]<<8) )>>>(pos&7))&((1<>>3] | (dt[(pos>>>3)+1]<<8) | (dt[(pos>>>3)+2]<<16))>>>(pos&7))&((1<>>3] | (dt[(pos>>>3)+1]<<8))>>>(pos&7))&511;\r\n} */\r\nUZIP.F._get17= function(dt, pos) {\t// return at least 17 meaningful bytes\r\n\treturn (dt[pos>>>3] | (dt[(pos>>>3)+1]<<8) | (dt[(pos>>>3)+2]<<16) )>>>(pos&7);\r\n}\r\nUZIP.F._get25= function(dt, pos) {\t// return at least 17 meaningful bytes\r\n\treturn (dt[pos>>>3] | (dt[(pos>>>3)+1]<<8) | (dt[(pos>>>3)+2]<<16) | (dt[(pos>>>3)+3]<<24) )>>>(pos&7);\r\n}\r\nUZIP.F.U = function(){\r\n\tvar u16=Uint16Array, u32=Uint32Array;\r\n\treturn {\r\n\t\tnext_code : new u16(16),\r\n\t\tbl_count : new u16(16),\r\n\t\tordr : [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ],\r\n\t\tof0 : [3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],\r\n\t\texb : [0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0, 0],\r\n\t\tldef : new u16(32),\r\n\t\tdf0 : [1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 65535, 65535],\r\n\t\tdxb : [0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0],\r\n\t\tddef : new u32(32),\r\n\t\tflmap: new u16( 512), fltree: [],\r\n\t\tfdmap: new u16( 32), fdtree: [],\r\n\t\tlmap : new u16(32768), ltree : [], ttree:[],\r\n\t\tdmap : new u16(32768), dtree : [],\r\n\t\timap : new u16( 512), itree : [],\r\n\t\t//rev9 : new u16( 512)\r\n\t\trev15: new u16(1<<15),\r\n\t\tlhst : new u32(286), dhst : new u32( 30), ihst : new u32(19),\r\n\t\tlits : new u32(15000),\r\n\t\tstrt : new u16(1<<16),\r\n\t\tprev : new u16(1<<15)\r\n\t}; \r\n} ();\r\n\r\n(function(){\t\r\n\tvar U = UZIP.F.U;\r\n\tvar len = 1<<15;\r\n\tfor(var i=0; i>> 1) | ((x & 0x55555555) << 1));\r\n\t\tx = (((x & 0xcccccccc) >>> 2) | ((x & 0x33333333) << 2));\r\n\t\tx = (((x & 0xf0f0f0f0) >>> 4) | ((x & 0x0f0f0f0f) << 4));\r\n\t\tx = (((x & 0xff00ff00) >>> 8) | ((x & 0x00ff00ff) << 8));\r\n\t\tU.rev15[i] = (((x >>> 16) | (x << 16)))>>>17;\r\n\t}\r\n\t\r\n\tfunction pushV(tgt, n, sv) { while(n--!=0) tgt.push(0,sv); }\r\n\t\r\n\tfor(var i=0; i<32; i++) { U.ldef[i]=(U.of0[i]<<3)|U.exb[i]; U.ddef[i]=(U.df0[i]<<4)|U.dxb[i]; }\r\n\t\r\n\tpushV(U.fltree, 144, 8); pushV(U.fltree, 255-143, 9); pushV(U.fltree, 279-255, 7); pushV(U.fltree,287-279,8);\r\n\t/*\r\n\tvar i = 0;\r\n\tfor(; i<=143; i++) U.fltree.push(0,8);\r\n\tfor(; i<=255; i++) U.fltree.push(0,9);\r\n\tfor(; i<=279; i++) U.fltree.push(0,7);\r\n\tfor(; i<=287; i++) U.fltree.push(0,8);\r\n\t*/\r\n\tUZIP.F.makeCodes(U.fltree, 9);\r\n\tUZIP.F.codes2map(U.fltree, 9, U.flmap);\r\n\tUZIP.F.revCodes (U.fltree, 9)\r\n\t\r\n\tpushV(U.fdtree,32,5);\r\n\t//for(i=0;i<32; i++) U.fdtree.push(0,5);\r\n\tUZIP.F.makeCodes(U.fdtree, 5);\r\n\tUZIP.F.codes2map(U.fdtree, 5, U.fdmap);\r\n\tUZIP.F.revCodes (U.fdtree, 5)\r\n\t\r\n\tpushV(U.itree,19,0); pushV(U.ltree,286,0); pushV(U.dtree,30,0); pushV(U.ttree,320,0);\r\n\t/*\r\n\tfor(var i=0; i< 19; i++) U.itree.push(0,0);\r\n\tfor(var i=0; i<286; i++) U.ltree.push(0,0);\r\n\tfor(var i=0; i< 30; i++) U.dtree.push(0,0);\r\n\tfor(var i=0; i<320; i++) U.ttree.push(0,0);\r\n\t*/\r\n})()\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", "/** @format */\n\nimport { deflate, inflate } from 'uzip';\nimport { ICCPCompressionMode } from './iccp-compression-mode';\nimport { ArrayUtils } from './array-utils';\n\n/**\n * ICC Profile data stored with an image.\n */\nexport class ICCProfileData {\n private _name: string;\n public get name(): string {\n return this._name;\n }\n\n private _compression: ICCPCompressionMode;\n public get compression(): ICCPCompressionMode {\n return this._compression;\n }\n\n private _data: Uint8Array;\n public get data(): Uint8Array {\n return this._data;\n }\n\n constructor(\n name: string,\n compression: ICCPCompressionMode,\n data: Uint8Array\n ) {\n this._name = name;\n this._compression = compression;\n this._data = data;\n }\n\n public static from(other: ICCProfileData) {\n return new ICCProfileData(\n other._name,\n other._compression,\n ArrayUtils.copyUint8(other._data)\n );\n }\n\n /**\n * Returns the compressed data of the ICC Profile, compressing the stored data as necessary.\n */\n public compressed(): Uint8Array {\n if (this._compression === ICCPCompressionMode.deflate) {\n return this._data;\n }\n this._data = deflate(this._data);\n this._compression = ICCPCompressionMode.deflate;\n return this._data;\n }\n\n /**\n * Returns the uncompressed data of the ICC Profile, decompressing the stored data as necessary.\n */\n public decompressed(): Uint8Array {\n if (this._compression === ICCPCompressionMode.deflate) {\n return this._data;\n }\n this._data = inflate(this._data);\n this._compression = ICCPCompressionMode.none;\n return this._data;\n }\n}\n", ""], - "mappings": "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V,KAAM,aACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,YACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,eACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,OACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,QACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,eACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,kBACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,eACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,kBACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,iBACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,iBACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,sBACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,WACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,YACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,YACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,iBACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,aACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACN,OACA,MAAO,GACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,WACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,WACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,SACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,eACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,YACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,aACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,wBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,gBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,YACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,aACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,gBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,wBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,QACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,gBACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,eACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,uBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,6BACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,oBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,sBACN,OACA,MAAO,CACT,CAAC,CACH,EAEA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,SACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,qBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,eACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,UACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACN,MACF,CAAC,CACH,EAEA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,sBACN,MACF,CAAC,CACH,EAEA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,MACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,2BACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,cACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,oBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,qBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,sBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,yBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,wBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,eACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,OACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,oBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,qBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,SACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,iBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,wBACR,CAAC,CACH,EAEA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,0BACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,uBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,uBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,0BACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,eACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,eACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,gBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,uBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,0BACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,sBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,eACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,QACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,SACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,SACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,KACA,IAAIA,EAAQ,CACV,KAAM,YACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,eACN,MACF,CAAC,CACH,CACF,CAAC,EAEYG,GAAkB,IAAI,IAAqB,CACtD,CACE,EACA,IAAIH,EAAQ,CACV,KAAM,eACN,MACF,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,iBACN,MACF,CAAC,CACH,EACA,CACE,KACA,IAAIA,EAAQ,CACV,KAAM,yBACN,MACF,CAAC,CACH,EACA,CACE,KACA,IAAIA,EAAQ,CACV,KAAM,oBACN,MACF,CAAC,CACH,EACA,CACE,KACA,IAAIA,EAAQ,CACV,KAAM,qBACN,MACF,CAAC,CACH,CACF,CAAC,EAEYI,GAAc,IAAI,IAAqB,CAClD,CACE,EACA,IAAIJ,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,gBACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,gBACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,eACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,gBACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,QACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,oBACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,oBACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CAC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KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAClE,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAClE,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAClE,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAClE,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAClE,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IACxE,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACtE,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACtE,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACtE,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,GAAI,GAAI,GAAI,GAAI,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAAI,GAAI,GACvE,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GACxE,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GACxE,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACtE,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACtE,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACtE,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACtE,IAAK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OAAQ,OAAQ,OAAQ,OAAQ,OAExD,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAE5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAE5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAE5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAE5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAE5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAE5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAE5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAE5B,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IA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AAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC", - "names": ["ImageError", "init_image_error", "__esmMin", "ArrayUtils", "init_array_utils", "__esmMin", "init_image_error", "from", "begin", "end", "ImageError", "to", "start", "skipCount", "viewFrom", "_BitOperators", "BitOperators", "init_bit_operators", "__esmMin", "bits", "value", "v", "n", "d", "bitCount", "result", "i", "init_blend_mode", "__esmMin", "init_color_channel", "__esmMin", "init_color_model", "__esmMin", "MathOperators", "init_math_operators", "__esmMin", "x", "y", "_x", "_y", "t", "num", "low", "high", "Color", "init_color", "__esmMin", "init_image_error", "init_bit_operators", "init_color_channel", "init_math_operators", "red", "green", "blue", "alpha", "hue", "saturation", "lightness", "rgb", "value", "x", "y", "z", "L", "a", "b", "c1", "c2", "compareAlpha", "d1", "d2", "d3", "dA", "dst", "src", "fraction", "srcAlpha", "sr", "sg", "sb", "sa", "dr", "dg", "db", "da", "color", "channel", "r", "g", "MathOperators", "BitOperators", "gray", "hue2rgb", "p", "q", "t", "ti", "brightness", "h", "f", "ImageError", "ri", "gi", "bi", "mx", "mn", "l", "d", "s", "xi", "yi", "zi", "c", "m", "k", "ci", "mi", "ki", "y3", "x3", "z3", "R", "G", "B", "_Crc32", "Crc32", "init_crc32", "__esmMin", "table", "c", "n", "k", "options", "_a", "_b", "_c", "len", "pos", "end", "result", "i", "init_dispose_mode", "__esmMin", "init_dither_kernel", "__esmMin", "_DitherPixel", "DitherPixel", "init_dither_pixel", "__esmMin", "init_dither_kernel", "image", "quantizer", "kernel", "serpentine", "ds", "height", "width", "data", "indexedPixels", "colorMap", "direction", "index", "y", "x0", "x1", "x", "idx", "r1", "g1", "b1", "r2", "g2", "b2", "er", "eg", "eb", "i0", "i1", "i", "y1", "d", "init_frame_type", "__esmMin", "FrameAnimation", "init_frame_animation", "__esmMin", "init_frame_type", "options", "_a", "_b", "_c", "_d", "index", "image", "HeapNode", "init_heap_node", "__esmMin", "init_iccp_compression_mode", "__esmMin", "TextCodec", "init_text_codec", "__esmMin", "init_image_error", "str", "array", "codePoint", "ImageError", "InputBuffer", "init_input_buffer", "__esmMin", "init_image_error", "init_bit_operators", "init_text_codec", "v", "options", "_a", "_b", "other", "offset", "length", "offsetFromOther", "result", "index", "value", "start", "count", "position", "pos", "end", "BitOperators", "bytes", "codes", "c", "ImageError", "array", "TextCodec", "b1", "b2", "b3", "b4", "d", "b5", "b6", "b7", "b8", "correctedOffset", "correctedLength", "init_interpolation", "__esmMin", "Line", "init_line", "__esmMin", "x1", "y1", "x2", "y2", "other", "x", "y", "init_rgb_channel_set", "__esmMin", "ExifEntry", "init_exif_entry", "__esmMin", "v", "tag", "value", "Rational", "init_rational", "__esmMin", "init_math_operators", "numerator", "denominator", "d", "MathOperators", "other", "ExifIFDContainer", "init_exif_ifd_container", "__esmMin", "init_exif_ifd", "ifd", "directories", "other", "key", "ifdName", "ExifIFD", "value", "getExifValueTypeString", "type", "ExifValueTypeString", "getExifValueTypeSize", "length", "ExifValueTypeSize", "ExifValueType", "init_exif_value_type", "__esmMin", "ExifTag", "ExifTagNameToID", "ExifImageTags", "ExifInteropTags", "ExifGpsTags", "init_exif_tag", "__esmMin", "init_exif_value_type", "options", "_a", "_b", "ExifValue", "init_exif_value", "__esmMin", "init_rational", "init_image_error", "init_exif_value_type", "getExifValueTypeSize", "getExifValueTypeString", "_index", "Rational", "_out", "_v", "_numerator", "_denomitator", "_other", "ImageError", "ExifAsciiValue", "init_exif_ascii_value", "__esmMin", "init_text_codec", "init_exif_value", "init_exif_value_type", "ExifValue", "value", "data", "length", "TextCodec", "out", "bytes", "v", "other", "ExifByteValue", "init_exif_byte_value", "__esmMin", "init_exif_value", "init_exif_value_type", "ExifValue", "value", "data", "offset", "length", "array", "index", "out", "v", "other", "ExifDoubleValue", "init_exif_double_value", "__esmMin", "init_exif_value", "init_exif_value_type", "ExifValue", "value", "data", "length", "array", "i", "index", "out", "l", "v", "other", "ExifLongValue", "init_exif_long_value", "__esmMin", "init_exif_value", "init_exif_value_type", "ExifValue", "value", "data", "length", "array", "i", "index", "out", "l", "v", "other", "ExifRationalValue", "init_exif_rational_value", "__esmMin", "init_exif_value", "init_exif_value_type", "init_rational", "ExifValue", "value", "Rational", "data", "length", "array", "i", "r", "other", "index", "out", "v", "numerator", "denomitator", "ExifSByteValue", "init_exif_sbyte_value", "__esmMin", "init_exif_value", "init_exif_value_type", "ExifValue", "value", "data", "offset", "length", "array", "index", "out", "v", "other", "ExifShortValue", "init_exif_short_value", "__esmMin", "init_exif_value", "init_exif_value_type", "ExifValue", "value", "data", "length", "array", "i", "index", "out", "l", "v", "other", "ExifSingleValue", "init_exif_single_value", "__esmMin", "init_exif_value", "init_exif_value_type", "ExifValue", "value", "data", "length", "array", "i", "index", "out", "l", "v", "other", "ExifSLongValue", "init_exif_slong_value", "__esmMin", "init_exif_value", "init_exif_value_type", "init_bit_operators", "ExifValue", "value", "data", "length", "array", "i", "index", "out", "l", "BitOperators", "v", "other", "ExifSRationalValue", "init_exif_srational_value", "__esmMin", "init_exif_value", "init_exif_value_type", "init_bit_operators", "init_rational", "ExifValue", "value", "Rational", "data", "length", "array", "i", "r", "other", "index", "out", "v", "BitOperators", "numerator", "denomitator", "ExifSShortValue", "init_exif_sshort_value", "__esmMin", "init_exif_value", "init_exif_value_type", "ExifValue", "value", "data", "length", "array", "i", "index", "out", "v", "vb", "l", "other", "ExifUndefinedValue", "init_exif_undefined_value", "__esmMin", "init_exif_value", "init_exif_value_type", "ExifValue", "value", "data", "offset", "length", "array", "out", "other", "ExifIFD", "init_exif_ifd", "__esmMin", "init_rational", "init_exif_ifd_container", "init_exif_tag", "init_exif_value_type", "init_exif_ascii_value", "init_exif_byte_value", "init_exif_double_value", "init_exif_long_value", "init_exif_rational_value", "init_exif_sbyte_value", "init_exif_short_value", "init_exif_single_value", "init_exif_slong_value", "init_exif_srational_value", "init_exif_sshort_value", "init_exif_undefined_value", "init_exif_value", "ExifIFDContainer", "_a", "v", "ExifAsciiValue", "ExifShortValue", "tag", "value", "Rational", "ExifRationalValue", "r", "sv", "_tag", "ExifTagNameToID", "ExifValue", "tagInfo", "ExifImageTags", "tagType", "tagCount", "ExifByteValue", "ExifLongValue", "array", "i", "subarray", "el", "ExifSByteValue", "ExifUndefinedValue", "ExifSShortValue", "ExifSLongValue", "ExifSRationalValue", "ExifSingleValue", "ExifDoubleValue", "ExifData", "init_exif_data", "__esmMin", "init_exif_entry", "init_exif_ifd", "init_exif_ifd_container", "init_exif_tag", "init_exif_value_type", "init_exif_ascii_value", "init_exif_byte_value", "init_exif_double_value", "init_exif_long_value", "init_exif_rational_value", "init_exif_sbyte_value", "init_exif_short_value", "init_exif_single_value", "init_exif_slong_value", "init_exif_srational_value", "init_exif_sshort_value", "init_exif_undefined_value", "ExifIFDContainer", "out", "ifd", "dataOffset", "offset", "tag", "value", "size", "block", "blockOffset", "format", "count", "entry", "ExifEntry", "ExifValueType", "f", "fsize", "ExifValueTypeSize", "endOffset", "fieldOffset", "data", "ExifSByteValue", "ExifByteValue", "ExifUndefinedValue", "ExifAsciiValue", "ExifShortValue", "ExifLongValue", "ExifRationalValue", "ExifSRationalValue", "ExifSShortValue", "ExifSLongValue", "ExifSingleValue", "ExifDoubleValue", "other", "input", "directory", "_a", "_b", "ExifImageTags", "saveEndian", "ExifIFD", "offsets", "name", "dataSize", "subName", "subIfd", "subSize", "dirArray", "i", "nextName", "endian", "ifdOffset", "index", "numEntries", "dir", "subTags", "d", "dt", "s", "subDirectory", "MemoryImage", "init_memory_image", "__esmMin", "init_array_utils", "init_rgb_channel_set", "init_dispose_mode", "init_blend_mode", "init_color_model", "init_image_error", "init_interpolation", "init_color", "init_exif_data", "options", "_a", "_b", "ExifData", "v", "width", "height", "bytes", "colorModel", "ArrayUtils", "input", "data", "rgba", "i", "len", "j", "opt", "__spreadProps", "__spreadValues", "other", "result", "Color", "ImageError", "color", "h", "w", "y", "x", "c1", "r1", "g1", "b1", "a1", "c2", "r2", "g2", "b2", "a2", "index", "fx", "fy", "interpolation", "nx", "ny", "dx", "dy", "linear", "icc", "inc", "icn", "inn", "px", "ax", "py", "ay", "cubic", "ipp", "icp", "inp", "iap", "ip0", "ip1", "ip2", "ip3", "ipc", "iac", "Ic0", "Ic1", "Ic2", "Ic3", "ipn", "ian", "in0", "in1", "in2", "in3", "ipa", "ica", "ina", "iaa", "ia0", "ia1", "ia2", "ia3", "c0", "c3", "r", "g", "b", "a", "asDouble", "t", "averageGray", "min", "max", "c", "key", "value", "_NeuralQuantizer", "NeuralQuantizer", "init_neural_quantizer", "__esmMin", "init_color", "image", "numberOfColors", "samplingFactor", "f", "p", "rad", "alpha", "b", "g", "r", "i", "bestd", "bestBiasDist", "bestpos", "bestbiaspos", "dist", "a", "biasDist", "_", "lo", "hi", "j", "k", "m", "biasRadius", "alphaDec", "lengthCount", "samplePixels", "delta", "step", "pos", "red", "Color", "green", "blue", "q", "x", "previousColor", "startPos", "smallpos", "smallval", "best", "index", "c", "map", "len", "OctreeNode", "init_octree_node", "__esmMin", "childIndex", "depth", "parent", "v", "_OctreeQuantizer", "OctreeQuantizer", "init_octree_quantizer", "__esmMin", "init_color", "init_heap_node", "init_octree_node", "image", "numberOfColors", "OctreeNode", "heap", "HeapNode", "si", "c", "r", "Color", "g", "b", "nc", "i", "got", "root", "_root", "depth", "bit", "h", "ret", "p", "n", "m", "prev", "q", "a", "ac", "bc", "_OutputBuffer", "OutputBuffer", "init_output_buffer", "__esmMin", "init_array_utils", "v", "options", "_a", "_b", "required", "blockSize", "newBuffer", "ArrayUtils", "value", "bytes", "length", "correctedLength", "fb", "b", "start", "end", "correctedStart", "correctedEnd", "Point", "init_point", "__esmMin", "x", "y", "other", "dx", "dy", "n", "p", "init_quantizer", "__esmMin", "RandomUtils", "init_random_utils", "__esmMin", "x1", "w", "x2", "z", "k", "y", "s", "Rectangle", "init_rectangle", "__esmMin", "x1", "y1", "x2", "y2", "x", "y", "width", "height", "other", "init_typings", "__esmMin", "init_draw_image_options", "__esmMin", "init_draw_line_options", "__esmMin", "_Draw", "Draw", "init_draw", "__esmMin", "init_color", "init_line", "init_math_operators", "init_point", "init_rectangle", "image", "center", "radius", "points", "Point", "f", "ddFx", "ddFy", "x", "y", "x1", "x2", "y1", "y2", "x3", "x4", "y3", "y4", "rect", "p", "code", "line", "xmin", "ymin", "xmax", "ymax", "outcode1", "outcode2", "accept", "outcodeOut", "src", "refColor", "threshold", "pixel", "compareAlpha", "pixelColor", "Color", "array", "mark", "visited", "_x", "_y", "ox", "oy", "lastRowLength", "rowLength", "sx", "end", "ux", "color", "a", "b", "start", "i", "Line", "options", "_a", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "_i", "dstX", "dstY", "srcX", "srcY", "srcW", "srcH", "dstW", "dstH", "stepX", "stepY", "srcPixel", "point", "Rectangle", "thickness", "xor", "n", "ac", "wid", "d", "incr1", "incr2", "wstart", "w", "as", "ag", "inc", "frac", "pos", "opacity", "index", "dst", "srcColor", "lab", "fillValue", "ret", "_x0", "MathOperators", "_y0", "_x1", "_y1", "sy", "pi", "init_fill_flood_options", "__esmMin", "init_mask_flood_options", "__esmMin", "NotImplementedError", "init_not_implemented_error", "__esmMin", "init_adjust_color_options", "__esmMin", "init_color_offset_options", "__esmMin", "init_convolution_options", "__esmMin", "init_noise_type", "__esmMin", "init_pixelate_mode", "__esmMin", "init_quantize_method", "__esmMin", "SeparableKernel", "init_separable_kernel", "__esmMin", "init_color", "size", "max", "x", "src", "dst", "y", "width", "horizontal", "r", "g", "b", "a", "j", "j2", "coeff", "gr", "sc", "Color", "c", "index", "s", "i", "_ImageFilter", "ImageFilter", "init_image_filter", "__esmMin", "init_color", "init_color_channel", "init_math_operators", "init_memory_image", "init_neural_quantizer", "init_octree_quantizer", "init_random_utils", "init_rectangle", "init_draw", "init_noise_type", "init_pixelate_mode", "init_quantize_method", "init_separable_kernel", "edge0", "edge1", "x", "_x", "options", "contrast", "MathOperators", "saturation", "brightness", "gamma", "exposure", "amount", "DEG_TO_RAD", "avgLumR", "avgLumG", "avgLumB", "lumCoeffR", "lumCoeffG", "lumCoeffB", "useBlacksWhitesMids", "br", "bg", "bb", "wr", "wg", "wb", "mr", "mg", "mb", "Color", "invSaturation", "invContrast", "hueR", "hueG", "hueB", "s", "c", "invAmount", "pixels", "i", "len", "or", "og", "ob", "r", "g", "b", "lum", "hr", "hg", "hb", "src", "strength", "dest", "MemoryImage", "y", "height", "du", "dv", "z", "dw", "nX", "nY", "nZ", "_a", "_b", "_c", "_d", "clevels", "p", "tmp", "a", "j", "fi", "yv", "xv", "c2", "div", "offset", "filter", "radius", "kernel", "sigma", "SeparableKernel", "sum", "l", "image", "type", "nsigma", "min", "max", "extremes", "RandomUtils", "sqrt2", "val0", "re", "im", "val", "minValue", "maxValue", "A", "B", "blockSize", "mode", "bs", "rect", "Rectangle", "Draw", "total", "cy", "cx", "numberOfColors", "oct", "OctreeQuantizer", "quant", "NeuralQuantizer", "red", "green", "blue", "alpha", "dr", "dg", "db", "da", "bytes", "w", "origRGBA", "rowSize", "rgba", "rgbaLen", "pi", "bl", "tl", "t", "tr", "tlInt", "tInt", "trInt", "lInt", "rInt", "blInt", "bInt", "brInt", "h", "v", "mag", "start", "end", "invAmt", "dy", "dx", "d", "init_quantize_options", "__esmMin", "init_remap_colors_options", "__esmMin", "init_vignette_options", "__esmMin", "_Half", "Half", "init_half", "__esmMin", "init_bit_operators", "bits", "i", "s", "e", "m", "t", "a", "b", "y", "n", "f", "xi", "BitOperators", "other", "d", "iMax", "_HdrSlice", "HdrSlice", "init_hdr_slice", "__esmMin", "init_array_utils", "init_not_implemented_error", "init_half", "v", "options", "_a", "size", "type", "bitsPerSample", "NotImplementedError", "other", "ArrayUtils", "x", "y", "pi", "Half", "_HdrImage", "HdrImage", "init_hdr_image", "__esmMin", "init_rgb_channel_set", "init_hdr_slice", "v", "width", "height", "channels", "type", "bitsPerSample", "image", "channelList", "i", "HdrSlice", "other", "value", "rgb", "y", "si", "x", "c", "ch", "slice", "rgba", "w", "h", "di", "_BitmapFileHeader", "BitmapFileHeader", "init_bitmap_file_header", "__esmMin", "init_input_buffer", "init_image_error", "v", "b", "ImageError", "InputBuffer", "init_bitmap_compression_mode", "__esmMin", "init_bmp_info", "__esmMin", "init_bit_operators", "init_color", "init_image_error", "init_not_implemented_error", "init_bitmap_compression_mode", "init_bitmap_file_header", "init_bmp_decoder", "__esmMin", "init_frame_animation", "init_input_buffer", "init_memory_image", "init_hdr_image", "init_bitmap_file_header", "init_bmp_info", "init_bmp_encoder", "__esmMin", "init_color", "init_output_buffer", "init_rgb_channel_set", "init_bitmap_file_header", "init_decode_info", "__esmMin", "init_decoder", "__esmMin", "init_dib_decoder", "__esmMin", "init_bmp_decoder", "init_encoder", "__esmMin", "init_flip_direction", "__esmMin", "ImageTransform", "init_image_transform", "__esmMin", "init_memory_image", "init_rgb_channel_set", "init_image_error", "init_point", "init_flip_direction", "init_draw", "init_interpolation", "init_color", "init_math_operators", "init_exif_data", "src", "angle", "interpolation", "nangle", "wm1", "hm1", "dst", "MemoryImage", "y", "x", "rad", "ca", "sa", "ux", "uy", "vx", "vy", "w2", "h2", "dw2", "dh2", "c", "image", "bakedImage", "ExifData", "rotated", "options", "_a", "_b", "_c", "ImageError", "dy", "dx", "sData", "sw4", "y1", "y2", "x1", "x2", "r", "g", "b", "a", "np", "sy", "si", "sx", "Color", "scaleX", "size", "height", "width", "xOffset", "yOffset", "_d", "_e", "_f", "_g", "_h", "wdt", "hight", "pos", "Point", "Draw", "w", "h", "_x", "MathOperators", "_y", "_w", "yi", "xi", "radius", "center", "defaultRadius", "tlx", "tly", "rect", "toImage", "v", "u", "srcPixelCoord", "srcPixel", "direction", "t", "GifColorMap", "init_gif_color_map", "__esmMin", "init_color", "v", "options", "_a", "_b", "n", "i", "other", "index", "value", "ci", "a", "Color", "r", "g", "b", "color", "GifImageDesc", "init_gif_image_desc", "__esmMin", "init_gif_color_map", "input", "b", "bitsPerPixel", "GifColorMap", "i", "v", "GifInfo", "init_gif_info", "__esmMin", "options", "_a", "_b", "_c", "_d", "_e", "_f", "_GifDecoder", "GifDecoder", "init_gif_decoder", "__esmMin", "init_frame_animation", "init_input_buffer", "init_array_utils", "init_memory_image", "init_image_error", "init_hdr_image", "init_image_transform", "init_gif_color_map", "init_gif_image_desc", "init_gif_info", "bytes", "prefix", "code", "clearCode", "c", "i", "image", "y", "colorMap", "line", "x", "width", "tag", "height", "b", "colorResolution", "bitsPerPixel", "backgroundColor", "globalColorMap", "GifColorMap", "r", "g", "isGif89", "GifInfo", "gifImage", "GifImageDesc", "input", "blockSize", "b1", "b2", "duration", "transparent", "disposalMethod", "transparentFlag", "MemoryImage", "row", "j", "lineLen", "currentPrefix", "prefixChar", "nextByte", "from", "ArrayUtils", "InputBuffer", "extCode", "error", "strError", "ImageError", "frame", "img", "HdrImage", "animation", "FrameAnimation", "lastImage", "ImageTransform", "_GifEncoder", "GifEncoder", "init_gif_encoder", "__esmMin", "init_dither_kernel", "init_dither_pixel", "init_neural_quantizer", "init_output_buffer", "init_text_codec", "options", "_a", "_b", "_c", "_d", "_e", "image", "width", "height", "colorMap", "numColors", "i", "initCodeSize", "hTab", "codeTab", "remaining", "curPixel", "_nextPixel", "ent", "hshift", "fcode", "hSizeReg", "outerLoop", "c", "disp", "code", "appCodeUnits", "TextCodec", "transparency", "dispose", "idCodeUnits", "bytes", "duration", "OutputBuffer", "NeuralQuantizer", "DitherPixel", "animation", "f", "init_ico_bmp_info", "__esmMin", "init_bmp_info", "init_ico_info_image", "__esmMin", "init_ico_info", "__esmMin", "init_ico_info_image", "PngFrame", "init_png_frame", "__esmMin", "options", "PngInfo", "init_png_info", "__esmMin", "options", "_a", "_b", "v", "import_uzip", "_PngDecoder", "PngDecoder", "init_png_decoder", "__esmMin", "init_color", "init_crc32", "init_frame_animation", "init_iccp_compression_mode", "init_icc_profile_data", "init_input_buffer", "init_array_utils", "init_memory_image", "init_rgb_channel_set", "init_text_codec", "init_image_error", "init_not_implemented_error", "init_hdr_image", "init_image_transform", "init_png_frame", "init_png_info", "filterType", "bpp", "row", "prevRow", "rowBytes", "x", "b", "c", "p", "pa", "pb", "pc", "paeth", "ImageError", "type", "bytes", "typeCodeUnits", "TextCodec", "crc", "Crc32", "input", "image", "xOffset", "yOffset", "xStep", "yStep", "passWidth", "passHeight", "channels", "pixelDepth", "line", "inData", "pixel", "srcY", "dstY", "ri", "rowInput", "InputBuffer", "blockHeight", "blockWidth", "srcX", "dstX", "i", "j", "w", "h", "y", "pi", "numBits", "octet", "mask", "NotImplementedError", "raw", "g", "a", "Color", "r", "tr", "tg", "tb", "pngHeader", "PNG_HEADER", "expectedHeader", "inputPos", "chunkSize", "chunkType", "PngInfo", "txtData", "l", "key", "ArrayUtils", "text", "hdr", "hdrBytes", "width", "height", "bits", "colorType", "compressionMethod", "filterMethod", "interlaceMethod", "computedCrc", "gammaInt", "sequenceNumber", "delayNum", "delayDen", "dispose", "blend", "frame", "PngFrame", "paletteIndex", "p3", "profile", "imageData", "totalSize", "dataBlocks", "len", "data", "offset", "f", "rgbChannelSet", "MemoryImage", "uncompressed", "error", "origW", "origH", "ICCProfileData", "img", "HdrImage", "animation", "FrameAnimation", "lastImage", "ImageTransform", "init_ico_decoder", "__esmMin", "init_input_buffer", "init_array_utils", "init_output_buffer", "init_not_implemented_error", "init_hdr_image", "init_bitmap_file_header", "init_dib_decoder", "init_ico_bmp_info", "init_ico_info", "init_png_decoder", "import_uzip", "_PngEncoder", "PngEncoder", "init_png_encoder", "__esmMin", "init_blend_mode", "init_color", "init_crc32", "init_dispose_mode", "init_output_buffer", "init_rgb_channel_set", "init_text_codec", "options", "_a", "_b", "type", "bytes", "typeCodeUnits", "TextCodec", "crc", "Crc32", "out", "chunk", "image", "oi", "row", "oindex", "Color", "x", "ar", "ag", "ab", "r", "g", "b", "aa", "a", "br", "bg", "bb", "xr", "xg", "xb", "ba", "xa", "c", "p", "pa", "pb", "pc", "cr", "cg", "cb", "pr", "pg", "ca", "width", "height", "OutputBuffer", "_", "iccp", "nameCodeUnits", "y", "keyword", "text", "keywordBytes", "textBytes", "filteredImage", "compressed", "key", "value", "fdat", "animation", "f", "init_win_encoder", "__esmMin", "init_output_buffer", "init_image_error", "init_png_encoder", "init_ico_encoder", "__esmMin", "init_win_encoder", "ComponentData", "init_component_data", "__esmMin", "hSamples", "maxHSamples", "vSamples", "maxVSamples", "lines", "Jpeg", "init_jpeg", "__esmMin", "JpegAdobe", "init_jpeg_adobe", "__esmMin", "version", "flags0", "flags1", "transformCode", "JpegComponent", "init_jpeg_component", "__esmMin", "hSamples", "vSamples", "quantizationTableList", "quantizationIndex", "v", "blocks", "blocksPerLine", "blocksPerColumn", "JpegFrame", "init_jpeg_frame", "__esmMin", "components", "componentsOrder", "extended", "progressive", "precision", "scanLines", "samplesPerLine", "blocksPerLineForMcu", "blocksPerColumnForMcu", "blocks", "ic", "line", "ir", "_", "component", "blocksPerLine", "blocksPerColumn", "JpegHuffman", "init_jpeg_huffman", "__esmMin", "JpegInfo", "init_jpeg_info", "__esmMin", "width", "height", "JpegJfif", "init_jpeg_jfif", "__esmMin", "thumbWidth", "thumbHeight", "majorVersion", "minorVersion", "densityUnits", "xDensity", "yDensity", "thumbData", "JpegQuantize", "init_jpeg_quantize", "__esmMin", "init_bit_operators", "init_color", "init_memory_image", "init_rgb_channel_set", "init_image_error", "init_exif_data", "i", "quantizationTable", "coefBlock", "dataOut", "dataIn", "p", "dctClipOffset", "dctClipLength", "COS_1", "SIN_1", "COS_3", "SIN_3", "COS_6", "SIN_6", "SQRT_2", "SQRT_1D2", "row", "t", "BitOperators", "v0", "v1", "v2", "v3", "v4", "v7", "v5", "v6", "col", "jpeg", "orientation", "flipWidthHeight", "width", "height", "image", "MemoryImage", "ExifData", "component1", "component2", "component3", "component4", "component1Line", "component2Line", "component3Line", "component4Line", "offset", "Y", "Cb", "Cr", "K", "C", "Ye", "R", "G", "B", "colorTransform", "h1", "w1", "lines", "hShift1", "vShift1", "y", "y1", "x", "x1", "c", "Color", "lines1", "lines2", "lines3", "hShift2", "vShift2", "hShift3", "vShift3", "y2", "y3", "x2", "x3", "ImageError", "lines4", "hShift4", "vShift4", "y4", "x4", "JpegScan", "init_jpeg_scan", "__esmMin", "init_image_error", "init_jpeg", "input", "frame", "components", "spectralStart", "spectralEnd", "successivePrev", "successive", "resetInterval", "nextByte", "ImageError", "tree", "node", "bit", "length", "n", "len", "component", "zz", "t", "diff", "k", "rs", "s", "r", "z", "Jpeg", "_", "e", "decodeFn", "mcu", "row", "col", "mcuRow", "mcuCol", "blockRow", "blockCol", "numCols", "componentsLength", "mcuExpected", "h", "v", "i", "j", "m1", "m2", "_JpegData", "JpegData", "init_jpeg_data", "__esmMin", "init_input_buffer", "init_image_error", "init_component_data", "init_jpeg", "init_jpeg_adobe", "init_jpeg_component", "init_jpeg_frame", "init_jpeg_huffman", "init_jpeg_info", "init_jpeg_jfif", "init_jpeg_quantize", "init_jpeg_scan", "init_exif_data", "ExifData", "Jpeg", "marker", "ImageError", "block", "length", "bytes", "InputBuffer", "soiCheck", "hasSOF", "hasSOS", "sectionByteSize", "info", "JpegInfo", "i", "component", "ComponentData", "JpegQuantize", "codeLengths", "values", "k", "code", "JpegHuffman", "p", "j", "q", "blocksPerLine", "blocksPerColumn", "samplesPerLine", "R", "r", "lines", "l", "blockRow", "scanLine", "blockCol", "offset", "sample", "line", "val", "c", "appData", "majorVersion", "minorVersion", "densityUnits", "xDensity", "yDensity", "thumbWidth", "thumbHeight", "thumbSize", "thumbData", "JpegJfif", "version", "flags0", "flags1", "transformCode", "JpegAdobe", "_", "n", "prec", "tableData", "tmp", "extended", "progressive", "precision", "scanLines", "numComponents", "components", "componentsOrder", "componentId", "x", "h", "v", "qId", "JpegComponent", "JpegFrame", "index", "bits", "count", "huffmanValues", "ht", "id", "dcTableNumber", "acTableNumber", "spectralStart", "spectralEnd", "successiveApproximation", "Ah", "Al", "JpegScan", "JpegDecoder", "init_jpeg_decoder", "__esmMin", "init_frame_animation", "init_input_buffer", "init_image_error", "init_hdr_image", "init_jpeg_data", "bytes", "JpegData", "InputBuffer", "_", "jpeg", "ImageError", "frame", "img", "HdrImage", "image", "animation", "FrameAnimation", "_JpegEncoder", "JpegEncoder", "init_jpeg_encoder", "__esmMin", "init_math_operators", "init_output_buffer", "init_jpeg", "quality", "nrcodes", "stdTable", "codevalue", "posInTable", "HT", "k", "j", "index", "fp", "marker", "out", "Jpeg", "exif", "exifData", "OutputBuffer", "exifBytes", "exifSignature", "width", "height", "i", "l", "m", "n", "o", "p", "nrlower", "nrupper", "cat", "nr", "nrneg", "q", "MathOperators", "sf", "YQT", "t", "UVQT", "u", "aasf", "row", "col", "data", "fdtbl", "dataOff", "I8", "I64", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "tmp0", "tmp7", "tmp1", "tmp6", "tmp2", "tmp5", "tmp3", "tmp4", "tmp10", "tmp13", "tmp11", "tmp12", "z1", "z5", "z2", "z4", "z3", "z11", "z13", "tmp0p2", "tmp7p2", "tmp1p2", "tmp6p2", "tmp2p2", "tmp5p2", "tmp3p2", "tmp4p2", "tmp10p2", "tmp13p2", "tmp11p2", "tmp12p2", "z1p2", "z5p2", "z2p2", "z4p2", "z3p2", "z11p2", "z13p2", "fDCTQuant", "bits", "value", "posval", "CDU", "DC", "HTAC", "HTDC", "EOB", "M16zeroes", "I16", "I63", "DU_DCT", "dc", "pos", "Diff", "end0pos", "startpos", "nrzeroes", "lng", "nrmarker", "image", "DCY", "DCU", "DCV", "imageData", "quadWidth", "y", "x", "start", "r", "g", "b", "fillBits", "_", "init_tga_info", "__esmMin", "init_tga_decoder", "__esmMin", "init_color", "init_frame_animation", "init_input_buffer", "init_memory_image", "init_rgb_channel_set", "init_hdr_image", "init_tga_info", "init_tga_encoder", "__esmMin", "init_color", "init_output_buffer", "init_rgb_channel_set", "_TiffBitReader", "TiffBitReader", "init_tiff_bit_reader", "__esmMin", "input", "numBits", "nBits", "value", "_TiffEntry", "TiffEntry", "init_tiff_entry", "__esmMin", "init_image_error", "init_tiff_image", "v", "options", "num", "den", "ImageError", "TiffImage", "values", "i", "_TiffFaxDecoder", "TiffFaxDecoder", "init_tiff_fax_decoder", "__esmMin", "init_image_error", "options", "bitsToGet", "b", "next", "next2next", "l", "bp", "ImageError", "bitsLeft", "bitsFromNextByte", "bitsFromNext2NextByte", "i1", "i2", "i3", "shift", "bitsToMoveBack", "i", "buffer", "lineOffset", "bitOffset", "numBits", "bitNum", "lastBit", "byteNum", "maskVal", "val", "offset", "bits", "code", "isT", "current", "entry", "twoBits", "isWhite", "n", "a0", "ret", "pce", "ces", "start", "temp", "runLength", "out", "compData", "startX", "height", "scanlineStride", "tiffT4Options", "a1", "currIndex", "lines", "b1", "b2", "number", "tiffT6Options", "cce", "zeros", "exit", "_LzwDecoder", "LzwDecoder", "init_tiff_lzw_decoder", "__esmMin", "init_image_error", "string", "newString", "code", "c", "i", "p", "out", "outLen", "ImageError", "oldCode", "import_uzip", "_TiffImage", "TiffImage", "init_tiff_image", "__esmMin", "init_bit_operators", "init_color", "init_input_buffer", "init_math_operators", "init_memory_image", "init_image_error", "init_half", "init_hdr_image", "init_hdr_slice", "init_jpeg_decoder", "init_tiff_bit_reader", "init_tiff_entry", "init_tiff_fax_decoder", "init_tiff_lzw_decoder", "p", "p3", "InputBuffer", "numDirEntries", "i", "tag", "type", "numValues", "entry", "TiffEntry", "len", "l", "infinity", "v", "defaultValue", "tileX", "tileY", "tileIndex", "outX", "outY", "byteCount", "bdata", "bytesInThisTile", "LzwDecoder", "count", "j", "b", "TiffFaxDecoder", "_", "data", "outData", "ImageError", "br", "TiffBitReader", "white", "black", "img", "y", "py", "x", "px", "_a", "decoder", "e", "MemoryImage", "tile", "JpegDecoder", "HdrImage", "sample", "Half", "gray", "MathOperators", "c", "Color", "alpha", "r", "g", "ri", "gi", "bi", "a", "ai", "image", "tileWidth", "tileHeight", "width", "height", "arraySize", "dst", "srcCount", "dstCount", "BitOperators", "repeat", "ti", "HdrSlice", "TiffInfo", "init_tiff_info", "__esmMin", "options", "_TiffDecoder", "TiffDecoder", "init_tiff_decoder", "__esmMin", "init_frame_animation", "init_frame_type", "init_input_buffer", "init_exif_data", "init_tiff_image", "init_tiff_info", "p", "byteOrder", "bigEndian", "signature", "offset", "p2", "InputBuffer", "images", "img", "TiffImage", "error", "TiffInfo", "bytes", "buffer", "ExifData", "frame", "image", "animation", "FrameAnimation", "len", "_TiffEncoder", "TiffEncoder", "init_tiff_encoder", "__esmMin", "init_output_buffer", "init_hdr_slice", "init_tiff_entry", "init_tiff_image", "out", "image", "TiffImage", "bytesPerSample", "imageSize", "channels", "y", "pi", "x", "c", "ch", "b", "HdrSlice", "tag", "data", "TiffEntry", "OutputBuffer", "_animation", "init_hdr_to_image", "__esmMin", "init_math_operators", "init_memory_image", "init_image_error", "init_copy_into_options", "__esmMin", "init_copy_resize_options", "__esmMin", "init_trim_mode", "__esmMin", "_TrimSide", "TrimSide", "init_trim_side", "__esmMin", "sides", "s", "side", "init_trim", "__esmMin", "init_memory_image", "init_rgb_channel_set", "init_rectangle", "init_trim_mode", "init_trim_side", "init_image_transform", "init_color", "init_src", "__esmMin", "init_bmp_decoder", "init_bmp_encoder", "init_gif_decoder", "init_gif_encoder", "init_ico_decoder", "init_ico_encoder", "init_jpeg_decoder", "init_jpeg_encoder", "init_png_decoder", "init_png_encoder", "init_tga_decoder", "init_tga_encoder", "init_tiff_decoder", "init_tiff_encoder", "init_array_utils", "init_bit_operators", "init_blend_mode", "init_color_channel", "init_color_model", "init_color", "init_crc32", "init_dispose_mode", "init_dither_kernel", "init_dither_pixel", "init_frame_animation", "init_frame_type", "init_heap_node", "init_icc_profile_data", "init_iccp_compression_mode", "init_input_buffer", "init_interpolation", "init_line", "init_math_operators", "init_memory_image", "init_neural_quantizer", "init_octree_node", "init_octree_quantizer", "init_output_buffer", "init_point", "init_random_utils", "init_rational", "init_rectangle", "init_rgb_channel_set", "init_text_codec", "init_draw", "init_exif_ascii_value", "init_exif_byte_value", "init_exif_double_value", "init_exif_long_value", "init_exif_rational_value", "init_exif_sbyte_value", "init_exif_short_value", "init_exif_single_value", "init_exif_slong_value", "init_exif_srational_value", "init_exif_sshort_value", "init_exif_undefined_value", "init_exif_value", "init_exif_data", "init_exif_entry", "init_exif_ifd_container", "init_exif_ifd", "init_exif_tag", "init_exif_value_type", "init_image_filter", "init_noise_type", "init_pixelate_mode", "init_quantize_method", "init_separable_kernel", "init_bitmap_compression_mode", "init_bitmap_file_header", "init_bmp_info", "init_gif_color_map", "init_gif_image_desc", "init_gif_info", "init_ico_bmp_info", "init_ico_info_image", "init_ico_info", "init_component_data", "init_jpeg_adobe", "init_jpeg_component", "init_jpeg_data", "init_jpeg_frame", "init_jpeg_huffman", "init_jpeg_info", "init_jpeg_jfif", "init_jpeg_quantize", "init_jpeg_scan", "init_jpeg", "init_png_frame", "init_png_info", "init_tga_info", "init_tiff_bit_reader", "init_tiff_entry", "init_tiff_fax_decoder", "init_tiff_image", "init_tiff_info", "init_tiff_lzw_decoder", "init_half", "init_hdr_image", "init_hdr_slice", "init_hdr_to_image", "init_flip_direction", "init_image_transform", "init_trim_mode", "init_trim_side", "init_trim", "require_UZIP", "__commonJSMin", "exports", "module", "init_array_utils", "init_bit_operators", "init_blend_mode", "init_color_channel", "init_color_model", "init_color", "init_crc32", "init_dispose_mode", "init_dither_kernel", "init_dither_pixel", "init_frame_animation", "init_frame_type", "init_heap_node", "init_icc_profile_data", "init_iccp_compression_mode", "init_input_buffer", "init_interpolation", "init_line", "init_math_operators", "init_memory_image", "init_neural_quantizer", "init_octree_node", "init_octree_quantizer", "init_output_buffer", "init_point", "init_quantizer", "init_random_utils", "init_rational", "init_rectangle", "init_rgb_channel_set", "init_text_codec", "init_typings", "init_draw_image_options", "init_draw_line_options", "init_draw", "init_fill_flood_options", "init_mask_flood_options", "init_image_error", "init_not_implemented_error", "init_exif_data", "init_exif_entry", "init_exif_ifd_container", "init_exif_ifd", "init_exif_tag", "init_exif_value_type", "init_exif_ascii_value", "init_exif_byte_value", "init_exif_double_value", "init_exif_long_value", "init_exif_rational_value", "init_exif_sbyte_value", "init_exif_short_value", "init_exif_single_value", "init_exif_slong_value", "init_exif_srational_value", "init_exif_sshort_value", "init_exif_undefined_value", "init_exif_value", "init_adjust_color_options", "init_color_offset_options", "init_convolution_options", "init_image_filter", "init_noise_type", "init_pixelate_mode", "init_quantize_method", "init_quantize_options", "init_remap_colors_options", "init_separable_kernel", "init_vignette_options", "init_bmp_decoder", "init_bmp_encoder", "init_bitmap_compression_mode", "init_bitmap_file_header", "init_bmp_info", "init_decode_info", "init_decoder", "init_dib_decoder", "init_encoder", "init_gif_decoder", "init_gif_encoder", "init_gif_color_map", "init_gif_image_desc", "init_gif_info", "init_ico_decoder", "init_ico_encoder", "init_ico_bmp_info", "init_ico_info_image", "init_ico_info", "init_jpeg_decoder", "init_jpeg_encoder", "init_component_data", "init_jpeg_adobe", "init_jpeg_component", "init_jpeg_data", "init_jpeg_frame", "init_jpeg_huffman", "init_jpeg_info", "init_jpeg_jfif", "init_jpeg_quantize", "init_jpeg_scan", "init_jpeg", "init_png_decoder", "init_png_encoder", "init_png_frame", "init_png_info", "init_tga_decoder", "init_tga_encoder", "init_tga_info", "init_tiff_decoder", "init_tiff_encoder", "init_tiff_bit_reader", "init_tiff_entry", "init_tiff_fax_decoder", "init_tiff_image", "init_tiff_info", "init_tiff_lzw_decoder", "init_win_encoder", "init_half", "init_hdr_image", "init_hdr_slice", "init_hdr_to_image", "init_src", "init_copy_into_options", "init_copy_resize_options", "init_flip_direction", "init_image_transform", "init_trim_mode", "init_trim_side", "init_trim", "UZIP", "buf", "onlyNames", "rUs", "rUi", "o", "out", "data", "eocd", "cnu", "cnt", "csize", "coffs", "i", "sign", "crc32", "usize", "nl", "el", "cl", "roff", "ver", "gpflg", "cmpr", "time", "nlen", "elen", "name", "file", "CMF", "FLG", "CM", "CINFO", "opts", "off", "crc", "obj", "noCmpr", "tot", "wUi", "wUs", "zpd", "p", "cpr", "fof", "ioff", "fn", "ext", "t", "tab", "n", "c", "k", "len", "b", "l", "a", "end", "eend", "buff", "s", "ns", "str", "strl", "ci", "code", "opos", "lvl", "opt", "U", "goodIndex", "hash", "putsE", "pos", "cvrd", "dlen", "lits", "strt", "prev", "li", "lc", "bs", "ebits", "nc", "nmch", "nmci", "ii", "mch", "dst", "lgi", "dgi", "nice", "chain", "pi", "dif", "tl", "td", "dlim", "maxd", "j", "ei", "curd", "oi", "BFINAL", "o0", "l0", "putsF", "T", "ML", "MD", "MH", "numl", "numd", "numh", "lset", "dset", "cstSize", "fxdSize", "dynSize", "BTYPE", "ltree", "dtree", "si", "qb", "qc", "p8", "tree", "hst", "set", "rst", "rsl", "nxt", "nnxt", "prv", "lz", "zc", "MAXL", "list", "hl", "l2", "lit", "i0", "i1", "i2", "maxl", "d", "dps", "bCost", "dbt", "od", "v", "arr", "ch", "u8", "F", "bitsF", "bitsE", "decodeTiny", "makeCodes", "codes2map", "get17", "noBuf", "HLIT", "HDIST", "HCLEN", "lmap", "dmap", "ppos", "mx0", "mx1", "ebs", "dcode", "dlit", "dbs", "bl", "nbuf", "LL", "ll", "ni", "src", "mx", "MAX_BITS", "max_code", "bits", "bl_count", "next_code", "map", "r15", "val", "rest", "p0", "imb", "dt", "length", "u16", "u32", "x", "pushV", "tgt", "sv", "import_uzip", "ICCProfileData", "init_icc_profile_data", "__esmMin", "init_iccp_compression_mode", "init_array_utils", "name", "compression", "data", "other", "ArrayUtils", "init_array_utils", "init_bit_operators", "init_blend_mode", "init_color_channel", "init_color_model", "init_color", "init_crc32", "init_dispose_mode", "init_dither_kernel", "init_dither_pixel", "init_frame_animation", "init_frame_type", "init_heap_node", "init_icc_profile_data", "init_iccp_compression_mode", "init_input_buffer", "init_interpolation", "init_line", "init_math_operators", "init_memory_image", "init_neural_quantizer", "init_octree_node", "init_octree_quantizer", "init_output_buffer", "init_point", "init_quantizer", "init_random_utils", "init_rational", "init_rectangle", "init_rgb_channel_set", "init_text_codec", "init_typings", "init_draw_image_options", "init_draw_line_options", "init_draw", "init_fill_flood_options", "init_mask_flood_options", "init_image_error", "init_not_implemented_error", "init_exif_data", "init_exif_entry", "init_exif_ifd_container", "init_exif_ifd", "init_exif_tag", "init_exif_value_type", "init_exif_ascii_value", "init_exif_byte_value", "init_exif_double_value", "init_exif_long_value", "init_exif_rational_value", "init_exif_sbyte_value", "init_exif_short_value", "init_exif_single_value", "init_exif_slong_value", "init_exif_srational_value", "init_exif_sshort_value", "init_exif_undefined_value", "init_exif_value", "init_adjust_color_options", "init_color_offset_options", "init_convolution_options", "init_image_filter", "init_noise_type", "init_pixelate_mode", "init_quantize_method", "init_quantize_options", "init_remap_colors_options", "init_separable_kernel", "init_vignette_options", "init_bmp_decoder", "init_bmp_encoder", "init_bitmap_compression_mode", "init_bitmap_file_header", "init_bmp_info", "init_decode_info", "init_decoder", "init_dib_decoder", "init_encoder", "init_gif_decoder", "init_gif_encoder", "init_gif_color_map", "init_gif_image_desc", "init_gif_info", "init_ico_decoder", "init_ico_encoder", "init_ico_bmp_info", "init_ico_info_image", "init_ico_info", "init_jpeg_decoder", "init_jpeg_encoder", "init_component_data", "init_jpeg_adobe", "init_jpeg_component", "init_jpeg_data", "init_jpeg_frame", "init_jpeg_huffman", "init_jpeg_info", "init_jpeg_jfif", "init_jpeg_quantize", "init_jpeg_scan", "init_jpeg", "init_png_decoder", "init_png_encoder", "init_png_frame", "init_png_info", "init_tga_decoder", "init_tga_encoder", "init_tga_info", "init_tiff_decoder", "init_tiff_encoder", "init_tiff_bit_reader", "init_tiff_entry", "init_tiff_fax_decoder", "init_tiff_image", "init_tiff_info", "init_tiff_lzw_decoder", "init_win_encoder", "init_half", "init_hdr_image", "init_hdr_slice", "init_hdr_to_image", "init_src", "init_copy_into_options", "init_copy_resize_options", "init_flip_direction", "init_image_transform", "init_trim_mode", "init_trim_side", "init_trim"] + "sources": ["../src/color/channel-order.ts", "../src/color/channel.ts", "../src/error/lib-error.ts", "../src/common/math-utils.ts", "../src/common/rational.ts", "../src/common/array-utils.ts", "../src/common/bit-utils.ts", "../src/common/float16.ts", "../src/color/format.ts", "../src/color/color-float32.ts", "../src/color/color-float64.ts", "../src/color/color-int16.ts", "../src/color/color-int32.ts", "../src/color/color-int8.ts", "../src/color/color-uint1.ts", "../src/color/color-uint16.ts", "../src/color/color-uint2.ts", "../src/color/color-uint32.ts", "../src/color/color-uint4.ts", "../src/color/color-uint8.ts", "../src/color/color-utils.ts", "../src/color/color-float16.ts", "../src/color/color-rgb8.ts", "../src/color/color-rgba8.ts", "../src/color/color.ts", "../src/common/crc32.ts", "../src/common/string-utils.ts", "../src/common/input-buffer.ts", "../src/common/interpolation.ts", "../src/common/line.ts", "../src/common/output-buffer.ts", "../src/common/point.ts", "../src/common/random-utils.ts", "../src/common/rectangle.ts", "../src/common/typings.ts", "../src/draw/blend-mode.ts", "../src/draw/circle-quadrant.ts", "../src/image/image-utils.ts", "../src/draw/draw.ts", "../src/exif/exif-entry.ts", "../src/exif/ifd-value-type.ts", "../src/exif/exif-tag.ts", "../src/exif/ifd-value/ifd-value.ts", "../src/exif/ifd-value/ifd-ascii-value.ts", "../src/exif/ifd-value/ifd-short-value.ts", "../src/exif/ifd-value/ifd-rational-value.ts", "../src/exif/ifd-value/ifd-byte-value.ts", "../src/exif/ifd-value/ifd-long-value.ts", "../src/exif/ifd-value/ifd-sbyte-value.ts", "../src/exif/ifd-value/ifd-undefined-value.ts", "../src/exif/ifd-value/ifd-sshort-value.ts", "../src/exif/ifd-value/ifd-slong-value.ts", "../src/exif/ifd-value/ifd-srational-value.ts", "../src/exif/ifd-value/ifd-single-value.ts", "../src/exif/ifd-value/ifd-double-value.ts", "../src/exif/ifd-directory.ts", "../src/exif/ifd-container.ts", "../src/exif/exif-data.ts", "../src/filter/dither-kernel.ts", "../src/image/frame-type.ts", "../src/image/pixel-float16.ts", "../src/image/pixel-range-iterator.ts", "../src/image/image-data-float16.ts", "../src/image/pixel-float32.ts", "../src/image/image-data-float32.ts", "../src/image/pixel-float64.ts", "../src/image/image-data-float64.ts", "../src/image/pixel-int16.ts", "../src/image/image-data-int16.ts", "../src/image/pixel-int32.ts", "../src/image/image-data-int32.ts", "../src/image/pixel-int8.ts", "../src/image/image-data-int8.ts", "../src/image/pixel-uint1.ts", "../src/image/image-data-uint1.ts", "../src/image/pixel-uint16.ts", "../src/image/image-data-uint16.ts", "../src/image/pixel-uint2.ts", "../src/image/image-data-uint2.ts", "../src/image/pixel-uint32.ts", "../src/image/image-data-uint32.ts", "../src/image/pixel-uint4.ts", "../src/image/image-data-uint4.ts", "../src/image/pixel-uint8.ts", "../src/image/image-data-uint8.ts", "../src/image/palette-float16.ts", "../src/image/palette-float32.ts", "../src/image/palette-float64.ts", "../src/image/palette-int16.ts", "../src/image/palette-int32.ts", "../src/image/palette-int8.ts", "../src/image/palette-uint16.ts", "../src/image/palette-uint32.ts", "../src/image/palette-uint8.ts", "../src/image/pixel-undefined.ts", "../src/image/pixel.ts", "../src/image/image.ts", "../src/image/neural-quantizer.ts", "../src/image/heap-node.ts", "../src/image/octree-node.ts", "../src/image/octree-quantizer.ts", "../src/filter/noise-type.ts", "../src/filter/pixelate-mode.ts", "../src/filter/quantize-method.ts", "../src/filter/separable-kernel.ts", "../src/filter/filter.ts", "../src/formats/bmp/bmp-file-header.ts", "../src/formats/bmp/bmp-compression-mode.ts", "../src/formats/bmp/bmp-info.ts", "../src/formats/bmp-decoder.ts", "../src/formats/bmp-encoder.ts", "../src/formats/decode-info.ts", "../src/formats/decoder.ts", "../src/formats/dib-decoder.ts", "../src/formats/encoder.ts", "../src/formats/gif/gif-color-map.ts", "../src/formats/gif/gif-image-desc.ts", "../src/formats/gif/gif-info.ts", "../src/formats/gif-decoder.ts", "../src/image/quantizer-type.ts", "../src/formats/gif-encoder.ts", "../src/formats/ico/ico-bmp-info.ts", "../src/formats/ico/ico-info-image.ts", "../src/formats/ico/ico-type.ts", "../src/formats/ico/ico-info.ts", "../src/formats/png/png-filter-type.ts", "../src/formats/png/png-color-type.ts", "../src/formats/png-encoder.ts", "../src/formats/win-encoder.ts", "../src/formats/ico-encoder.ts", "../src/formats/jpeg/jpeg-component-data.ts", "../src/formats/jpeg/jpeg-adobe.ts", "../src/formats/jpeg/jpeg-component.ts", "../src/formats/jpeg/jpeg-frame.ts", "../src/formats/jpeg/jpeg-huffman.ts", "../src/formats/jpeg/jpeg-info.ts", "../src/formats/jpeg/jpeg-jfif.ts", "../src/formats/jpeg/jpeg-quantize.ts", "../src/formats/jpeg/huffman-node.ts", "../src/formats/jpeg/huffman-parent.ts", "../src/formats/jpeg/huffman-value.ts", "../src/formats/jpeg/jpeg-marker.ts", "../src/formats/jpeg/jpeg-scan.ts", "../src/formats/jpeg/jpeg-data.ts", "../src/formats/jpeg-decoder.ts", "../src/formats/jpeg-encoder.ts", "../src/formats/jpeg/jpeg-utils.ts", "../src/formats/png/png-blend-mode.ts", "../src/formats/png/png-dispose-mode.ts", "../src/formats/png/png-frame.ts", "../src/formats/png/png-info.ts", "../src/formats/tga/tga-image-type.ts", "../src/formats/tga/tga-info.ts", "../src/formats/tga-decoder.ts", "../src/formats/tga-encoder.ts", "../src/formats/tiff/tiff-bit-reader.ts", "../src/formats/tiff/tiff-compression.ts", "../src/formats/tiff/tiff-entry.ts", "../src/formats/tiff/tiff-fax-decoder.ts", "../src/formats/tiff/tiff-format.ts", "../src/formats/tiff/tiff-image-type.ts", "../src/formats/tiff/tiff-lzw-decoder.ts", "../src/formats/tiff/tiff-photometric-type.ts", "../src/formats/tiff/tiff-image.ts", "../src/formats/tiff/tiff-info.ts", "../src/formats/tiff-decoder.ts", "../src/formats/tiff-encoder.ts", "../src/image/icc-profile-compression.ts", "../src/image/icc-profile.ts", "../src/image/image-data.ts", "../src/image/palette.ts", "../src/image/quantizer.ts", "../src/transform/flip-direction.ts", "../src/transform/trim-side.ts", "../src/transform/trim-mode.ts", "../src/transform/transform.ts", "../src/index.ts", "../node_modules/uzip/UZIP.js", "../src/formats/png-decoder.ts", "../src/formats/ico-decoder.ts", ""], + "sourcesContent": ["/** @format */\n\nexport enum ChannelOrder {\n rgba,\n bgra,\n abgr,\n argb,\n rgb,\n bgr,\n grayAlpha,\n red,\n}\n\n/**\n * The number of channels for each ChannelOrder.\n */\nexport const ChannelOrderLength = new Map([\n [ChannelOrder.rgba, 4],\n [ChannelOrder.bgra, 4],\n [ChannelOrder.abgr, 4],\n [ChannelOrder.argb, 4],\n [ChannelOrder.rgb, 3],\n [ChannelOrder.bgr, 3],\n [ChannelOrder.grayAlpha, 2],\n [ChannelOrder.red, 1],\n]);\n", "/** @format */\n\n/**\n * A channel of a color\n */\nexport enum Channel {\n /**\n * Red channel\n */\n red,\n /**\n * Green channel\n */\n green,\n /**\n * Blue channel\n */\n blue,\n /**\n * Alpha channel\n */\n alpha,\n /**\n * Luminance is not an actual channel, it is the brightness value of the color.\n */\n luminance,\n}\n", "/** @format */\n\n/**\n * An Error thrown when there was a problem in the library.\n */\nexport class LibError extends Error {\n public toString(): string {\n return `${this.constructor.name} (${this.message})`;\n }\n}\n", "/** @format */\n\nexport abstract class MathUtils {\n public static fract(x: number): number {\n return x - Math.floor(x);\n }\n\n public static smoothStep(edge0: number, edge1: number, x: number): number {\n const t0 = (x - edge0) / (edge1 - edge0);\n const t = MathUtils.clamp(t0, 0, 1);\n return t * t * (3 - 2 * t);\n }\n\n public static mix(x: number, y: number, a: number): number {\n return x * (1 - a) + y * a;\n }\n\n public static sign(x: number): number {\n return x < 0 ? -1 : x > 0 ? 1 : 0;\n }\n\n public static step(edge: number, x: number): number {\n return x < edge ? 0 : 1;\n }\n\n public static length3(x: number, y: number, z: number): number {\n return Math.sqrt(x * x + y * y + z * z);\n }\n\n /**\n * Returns the greatest common divisor of **x** and **y**.\n */\n public static gcd(x: number, y: number) {\n let _x = Math.abs(x);\n let _y = Math.abs(y);\n while (_y) {\n const t = _y;\n _y = _x % _y;\n _x = t;\n }\n return _x;\n }\n\n /**\n * Clamp **num** to [**low**, **high**]\n */\n public static clamp(num: number, low: number, high: number) {\n return Math.max(low, Math.min(num, high));\n }\n\n /**\n * Clamp **num** to [**low**, **high**] and truncate\n */\n public static clampInt(num: number, low: number, high: number): number {\n return Math.trunc(MathUtils.clamp(num, low, high));\n }\n\n /**\n * Clamp **num** to [0, 255] and truncate\n */\n public static clampInt255(num: number): number {\n return Math.trunc(MathUtils.clamp(num, 0, 255));\n }\n}\n", "/** @format */\n\nimport { MathUtils } from './math-utils';\nimport { StringUtils } from './string-utils';\n\nexport class Rational {\n private _numerator: number;\n public get numerator(): number {\n return this._numerator;\n }\n\n private _denominator: number;\n public get denominator(): number {\n return this._denominator;\n }\n\n public get toInt(): number {\n return this.denominator !== 0\n ? Math.trunc(this.numerator / this.denominator)\n : 0;\n }\n\n public get toDouble(): number {\n return this.denominator !== 0 ? this.numerator / this.denominator : 0;\n }\n\n constructor(numerator: number, denominator: number) {\n this._numerator = numerator;\n this._denominator = denominator;\n }\n\n public simplify(): void {\n const d = MathUtils.gcd(this.numerator, this.denominator);\n if (d !== 0) {\n this._numerator = Math.trunc(this.numerator / d);\n this._denominator = Math.trunc(this.denominator / d);\n }\n }\n\n public equals(other: Rational) {\n return (\n this._numerator === other._numerator &&\n this._denominator === other._denominator\n );\n }\n\n public toString(): string {\n return `${this.constructor.name} (${this._numerator}/${this._denominator})`;\n }\n}\n", "/** @format */\n\nimport { LibError } from '../error/lib-error';\nimport { Rational } from './rational';\nimport { TypedArray } from './typings';\n\nexport abstract class ArrayUtils {\n public static copyInt8(\n from: Int8Array,\n begin?: number,\n end?: number\n ): Int8Array {\n return Int8Array.from(from.subarray(begin, end));\n }\n\n public static copyUint8(\n from: Uint8Array,\n begin?: number,\n end?: number\n ): Uint8Array {\n return Uint8Array.from(from.subarray(begin, end));\n }\n\n public static copyInt16(\n from: Int16Array,\n begin?: number,\n end?: number\n ): Int16Array {\n return Int16Array.from(from.subarray(begin, end));\n }\n\n public static copyUint16(\n from: Uint16Array,\n begin?: number,\n end?: number\n ): Uint16Array {\n return Uint16Array.from(from.subarray(begin, end));\n }\n\n public static copyInt32(\n from: Int32Array,\n begin?: number,\n end?: number\n ): Int32Array {\n return Int32Array.from(from.subarray(begin, end));\n }\n\n public static copyUint32(\n from: Uint32Array,\n begin?: number,\n end?: number\n ): Uint32Array {\n return Uint32Array.from(from.subarray(begin, end));\n }\n\n public static copyFloat32(\n from: Float32Array,\n begin?: number,\n end?: number\n ): Float32Array {\n return Float32Array.from(from.subarray(begin, end));\n }\n\n public static copyFloat64(\n from: Float64Array,\n begin?: number,\n end?: number\n ): Float64Array {\n return Float64Array.from(from.subarray(begin, end));\n }\n\n public static copy(\n from: TypedArray,\n begin?: number,\n end?: number\n ): TypedArray {\n if (from instanceof Int8Array) {\n return ArrayUtils.copyInt8(from, begin, end);\n } else if (from instanceof Uint8Array) {\n return ArrayUtils.copyUint8(from, begin, end);\n } else if (from instanceof Int16Array) {\n return ArrayUtils.copyInt16(from, begin, end);\n } else if (from instanceof Uint16Array) {\n return ArrayUtils.copyUint16(from, begin, end);\n } else if (from instanceof Int32Array) {\n return ArrayUtils.copyInt32(from, begin, end);\n } else if (from instanceof Uint32Array) {\n return ArrayUtils.copyUint32(from, begin, end);\n } else if (from instanceof Float32Array) {\n return ArrayUtils.copyFloat32(from, begin, end);\n } else if (from instanceof Float64Array) {\n return ArrayUtils.copyFloat64(from, begin, end);\n }\n throw new LibError('Unknown array type');\n }\n\n public static copyRange(\n from: T,\n fromStart: number,\n fromEnd: number,\n to: T,\n toStart: number\n ): void {\n const viewFrom = from.subarray(fromStart, fromEnd);\n to.set(viewFrom, toStart);\n }\n\n public static fill(length: number, value: T): T[] {\n const a = new Array(length);\n return a.fill(value);\n }\n\n public static generate(length: number, func: (index: number) => T): T[] {\n const a = new Array(length);\n for (let i = 0; i < length; ++i) {\n a[i] = func(i);\n }\n return a;\n }\n\n public static equals(\n a1: TypedArray | unknown[],\n a2: TypedArray | unknown[]\n ): boolean {\n if (a1 === a2) return true;\n if (a1.length !== a2.length) return false;\n for (let i = 0, l = a1.length; i < l; i++) {\n if (\n ArrayUtils.isNumArrayOrTypedArray(a1[i]) &&\n ArrayUtils.isNumArrayOrTypedArray(a2[i])\n ) {\n if (\n !ArrayUtils.equals(\n a1[i] as TypedArray | unknown[],\n a2[i] as TypedArray | unknown[]\n )\n )\n return false;\n } else if (a1[i] !== a2[i]) {\n return false;\n }\n }\n return true;\n }\n\n public static equalsRationalArray(a1: Rational[], a2: Rational[]): boolean {\n if (a1 === a2) return true;\n if (a1.length !== a2.length) return false;\n for (let i = 0, l = a1.length; i < l; i++) {\n if (!a1[i].equals(a2[i])) {\n return false;\n }\n }\n return true;\n }\n\n public static getNumEnumValues(t: T): number[] {\n return Object.values(t).filter((v) => typeof v === 'number');\n }\n\n public static isNumArrayOrTypedArray(obj: unknown) {\n return Boolean(\n obj &&\n typeof obj === 'object' &&\n ((Array.isArray(obj) &&\n (obj as Array).every((v) => typeof v === 'number')) ||\n (ArrayBuffer.isView(obj) && !(obj instanceof DataView)))\n );\n }\n\n public static isArrayOfRational(obj: unknown) {\n return Boolean(\n obj &&\n typeof obj === 'object' &&\n Array.isArray(obj) &&\n (obj as Array).every((v) => v instanceof Rational)\n );\n }\n}\n", "/** @format */\n\nexport abstract class BitUtils {\n private static readonly _uint8 = new Uint8Array(1);\n private static readonly _uint8ToInt8 = new Int8Array(BitUtils._uint8.buffer);\n\n private static readonly _int8 = new Int8Array(1);\n private static readonly _int8ToUint8 = new Uint8Array(BitUtils._int8.buffer);\n\n private static readonly _uint16 = new Uint16Array(1);\n private static readonly _uint16ToInt16 = new Int16Array(\n BitUtils._uint16.buffer\n );\n\n private static readonly _int16 = new Int16Array(1);\n private static readonly _int16ToUint16 = new Uint16Array(\n BitUtils._int16.buffer\n );\n\n private static readonly _uint32 = new Uint32Array(1);\n private static readonly _uint32ToInt32 = new Int32Array(\n BitUtils._uint32.buffer\n );\n private static readonly _uint32ToFloat32 = new Float32Array(\n BitUtils._uint32.buffer\n );\n\n private static readonly _int32 = new Int32Array(1);\n private static readonly _int32ToUint32 = new Uint32Array(\n BitUtils._int32.buffer\n );\n\n private static readonly _float32 = new Float32Array(1);\n private static readonly _float32ToUint32 = new Uint32Array(\n BitUtils._float32.buffer\n );\n\n private static readonly _uint64 = new BigUint64Array(1);\n private static readonly _uint64ToFloat64 = new Float64Array(\n BitUtils._uint64.buffer\n );\n\n private static readonly _reverseByteTable = [\n 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0,\n 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,\n 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4,\n 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,\n 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc,\n 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,\n 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca,\n 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,\n 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6,\n 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,\n 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,\n 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,\n 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9,\n 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,\n 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd,\n 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,\n 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3,\n 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,\n 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7,\n 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,\n 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf,\n 0x3f, 0xbf, 0x7f, 0xff,\n ];\n\n /**\n * Count the consecutive zero bits (trailing) on the right in parallel\n * https://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightParallel\n */\n public static countTrailingZeroBits(v: number): number {\n let c = 32;\n const _v = v & -v;\n if (_v !== 0) c--;\n if ((_v & 0x0000ffff) !== 0) c -= 16;\n if ((_v & 0x00ff00ff) !== 0) c -= 8;\n if ((_v & 0x0f0f0f0f) !== 0) c -= 4;\n if ((_v & 0x33333333) !== 0) c -= 2;\n if ((_v & 0x55555555) !== 0) c -= 1;\n return c;\n }\n\n public static reverseByte(x: number): number {\n return this._reverseByteTable[x];\n }\n\n public static signed(bits: number, value: number) {\n return value & (1 << (bits - 1)) ? value - (1 << bits) : value;\n }\n\n public static shiftR(v: number, n: number): number {\n return BitUtils.signed(32, v >> n);\n }\n\n public static shiftL(v: number, n: number): number {\n return BitUtils.signed(32, v << n);\n }\n\n /**\n * Binary conversion of a uint8 to an int8. This is equivalent in C to\n * typecasting an unsigned char to a char.\n */\n public static uint8ToInt8(d: number): number {\n this._uint8[0] = d;\n return this._uint8ToInt8[0];\n }\n\n /**\n * Binary conversion of an int8 to a uint8.\n */\n public static int8ToUint8(d: number): number {\n this._int8[0] = d;\n return this._int8ToUint8[0];\n }\n\n /**\n * Binary conversion of a uint16 to an int16. This is equivalent in C to\n * typecasting an unsigned short to a short.\n */\n public static uint16ToInt16(d: number): number {\n this._uint16[0] = d;\n return this._uint16ToInt16[0];\n }\n\n /**\n * Binary conversion of an int16 to a uint16. This is equivalent in C to\n * typecasting a short to an unsigned short.\n */\n public static int16ToUint16(d: number): number {\n this._int16[0] = d;\n return this._int16ToUint16[0];\n }\n\n /**\n * Binary conversion of a uint32 to an int32. This is equivalent in C to\n * typecasting an unsigned int to signed int.\n */\n public static uint32ToInt32(d: number): number {\n this._uint32[0] = d;\n return this._uint32ToInt32[0];\n }\n\n /**\n * Binary conversion of a uint32 to an float32. This is equivalent in C to\n * typecasting an unsigned int to float.\n */\n public static uint32ToFloat32(d: number): number {\n this._uint32[0] = d;\n return this._uint32ToFloat32[0];\n }\n\n /**\n * Binary conversion of a uint64 to an float64. This is equivalent in C to\n * typecasting an unsigned long long to double.\n */\n public static uint64ToFloat64(d: bigint): number {\n this._uint64[0] = d;\n return this._uint64ToFloat64[0];\n }\n\n /**\n * Binary conversion of an int32 to a uint32. This is equivalent in C to\n * typecasting an int to an unsigned int.\n */\n public static int32ToUint32(d: number): number {\n this._int32[0] = d;\n return this._int32ToUint32[0];\n }\n\n /**\n * Binary conversion of a float32 to an uint32. This is equivalent in C to\n * typecasting a float to unsigned int.\n */\n public static float32ToUint32(d: number): number {\n this._float32[0] = d;\n return this._float32ToUint32[0];\n }\n\n public static debugBits32(value?: number): string {\n if (value === undefined) {\n return 'undefined';\n }\n const bitCount = 32;\n let result = '';\n for (let i = bitCount; i > -1; i--) {\n result += (value & (1 << i)) === 0 ? '0' : '1';\n }\n return result;\n }\n}\n", "/** @format */\n\nimport { BitUtils } from './bit-utils';\n\n/**\n * A 16-bit floating-point number, used by high-dynamic-range image formats\n * as a more efficient storage for floating-point values that don't require\n * full 32-bit precision. A list of Half floats can be stored in a\n * Uint16Array, and converted to a double using the **float16ToDouble** static\n * method.\n *\n * This class is derived from the OpenEXR library.\n */\nexport class Float16 {\n private static _toFloatFloat32Data?: Float32Array;\n private static _eLut: Uint16Array;\n\n private static get _toFloatFloat32(): Float32Array {\n return this._toFloatFloat32Data !== undefined\n ? this._toFloatFloat32Data\n : this.initialize();\n }\n\n public bits: number;\n\n constructor(f?: number) {\n this.bits = f !== undefined ? Float16.doubleToFloat16(f) : 0;\n }\n\n private static convert(i: number): number {\n // Our floating point number, f, is represented by the bit\n // pattern in integer i. Disassemble that bit pattern into\n // the sign, s, the exponent, e, and the significand, m.\n // Shift s into the position where it will go in in the\n // resulting half number.\n // Adjust e, accounting for the different exponent bias\n // of float and half (127 versus 15).\n const s = (i >> 16) & 0x00008000;\n let e = ((i >> 23) & 0x000000ff) - (127 - 15);\n let m = i & 0x007fffff;\n\n // Now reassemble s, e and m into a half:\n if (e <= 0) {\n if (e < -10) {\n // E is less than -10. The absolute value of f is\n // less than HALF_MIN (f may be a small normalized\n // float, a denormalized float or a zero).\n //\n // We convert f to a half zero with the same sign as f.\n return s;\n }\n\n // E is between -10 and 0. F is a normalized float\n // whose magnitude is less than HALF_NRM_MIN.\n //\n // We convert f to a denormalized half.\n\n // Add an explicit leading 1 to the significand.\n\n m |= 0x00800000;\n\n // Round to m to the nearest (10+e)-bit value (with e between\n // -10 and 0); in case of a tie, round to the nearest even value.\n //\n // Rounding may cause the significand to overflow and make\n // our number normalized. Because of the way a half's bits\n // are laid out, we don't have to treat this case separately;\n // the code below will handle it correctly.\n\n const t = 14 - e;\n const a = (1 << (t - 1)) - 1;\n const b = (m >> t) & 1;\n\n m = (m + a + b) >> t;\n\n // Assemble the half from s, e (zero) and m.\n return s | m;\n } else if (e === 0xff - (127 - 15)) {\n if (m === 0) {\n // F is an infinity; convert f to a half\n // infinity with the same sign as f.\n return s | 0x7c00;\n } else {\n // F is a NAN; we produce a half NAN that preserves\n // the sign bit and the 10 leftmost bits of the\n // significand of f, with one exception: If the 10\n // leftmost bits are all zero, the NAN would turn\n // into an infinity, so we have to set at least one\n // bit in the significand.\n\n m >>= 13;\n return s | 0x7c00 | m | (m === 0 ? 1 : 0);\n }\n } else {\n // E is greater than zero. F is a normalized float.\n // We try to convert f to a normalized half.\n\n // Round to m to the nearest 10-bit value. In case of\n // a tie, round to the nearest even value.\n m = m + 0x00000fff + ((m >> 13) & 1);\n\n if ((m & 0x00800000) !== 0) {\n // overflow in significand\n m = 0;\n // adjust exponent\n e += 1;\n }\n\n // Handle exponent overflow\n\n if (e > 30) {\n // if this returns, the half becomes an\n // infinity with the same sign as f\n return s | 0x7c00;\n }\n\n // Assemble the half from s, e and m.\n return s | (e << 10) | (m >> 13);\n }\n }\n\n private static initialize(): Float32Array {\n if (this._toFloatFloat32Data !== undefined) {\n return this._toFloatFloat32Data;\n }\n\n const floatUint32Data = new Uint32Array(1 << 16);\n this._toFloatFloat32Data = new Float32Array(floatUint32Data.buffer);\n this._eLut = new Uint16Array(1 << 9);\n\n // Init eLut\n for (let i = 0; i < 0x100; i++) {\n const e = (i & 0x0ff) - (127 - 15);\n\n if (e <= 0 || e >= 30) {\n // Special case\n this._eLut[i] = 0;\n this._eLut[i | 0x100] = 0;\n } else {\n // Common case - normalized half, no exponent overflow possible\n this._eLut[i] = e << 10;\n this._eLut[i | 0x100] = (e << 10) | 0x8000;\n }\n }\n\n // Init toFloat\n const iMax = 1 << 16;\n for (let i = 0; i < iMax; i++) {\n floatUint32Data[i] = this.halfToFloat(i);\n }\n\n return this._toFloatFloat32Data;\n }\n\n private static halfToFloat(y: number): number {\n const s = (y >> 15) & 0x00000001;\n let e = (y >> 10) & 0x0000001f;\n let m = y & 0x000003ff;\n\n if (e === 0) {\n if (m === 0) {\n // Plus or minus zero\n return s << 31;\n } else {\n // Denormalized number -- re-normalize it\n while ((m & 0x00000400) === 0) {\n m <<= 1;\n e -= 1;\n }\n\n e += 1;\n m &= ~0x00000400;\n }\n } else if (e === 31) {\n if (m === 0) {\n // Positive or negative infinity\n return (s << 31) | 0x7f800000;\n } else {\n // Nan -- preserve sign and significand bits\n return (s << 31) | 0x7f800000 | (m << 13);\n }\n }\n\n // Normalized number\n e += 127 - 15;\n m <<= 13;\n\n // Assemble s, e and m.\n return (s << 31) | (e << 23) | m;\n }\n\n public static from(other: Float16): Float16 {\n const float16 = new Float16();\n float16.bits = other.bits;\n return float16;\n }\n\n public static fromBits(bits: number): Float16 {\n const float16 = new Float16();\n float16.bits = bits;\n return float16;\n }\n\n public static float16ToDouble(bits: number): number {\n return this._toFloatFloat32[bits];\n }\n\n public static doubleToFloat16(n: number): number {\n const f = n;\n const xI = BitUtils.float32ToUint32(f);\n if (f === 0) {\n // Common special case - zero.\n // Preserve the zero's sign bit.\n return xI >> 16;\n }\n\n if (this._toFloatFloat32Data === undefined) {\n this.initialize();\n }\n\n // We extract the combined sign and exponent, e, from our\n // floating-point number, f. Then we convert e to the sign\n // and exponent of the half number via a table lookup.\n //\n // For the most common case, where a normalized half is produced,\n // the table lookup returns a non-zero value; in this case, all\n // we have to do is round f's significand to 10 bits and combine\n // the result with e.\n //\n // For all other cases (overflow, zeroes, denormalized numbers\n // resulting from underflow, infinities and NANs), the table\n // lookup returns zero, and we call a longer, non-inline function\n // to do the float-to-half conversion.\n let e = (xI >> 23) & 0x000001ff;\n\n e = this._eLut[e];\n\n if (e !== 0) {\n // Simple case - round the significand, m, to 10\n // bits and combine it with the sign and exponent.\n const m = xI & 0x007fffff;\n return e + ((m + 0x00000fff + ((m >> 13) & 1)) >> 13);\n }\n\n // Difficult case - call a function.\n return this.convert(xI);\n }\n\n /**\n * Returns +Infinity.\n */\n public static posInf(): Float16 {\n return Float16.fromBits(0x7c00);\n }\n\n /**\n * Returns -Infinity.\n */\n public static negInf(): Float16 {\n return Float16.fromBits(0xfc00);\n }\n\n /**\n * Returns a NaN with the bit pattern 0111111111111111.\n */\n public static qNan(): Float16 {\n return Float16.fromBits(0x7fff);\n }\n\n /**\n * Returns a NaN with the bit pattern 0111110111111111.\n */\n public static sNan(): Float16 {\n return Float16.fromBits(0x7dff);\n }\n\n public toDouble(): number {\n return Float16._toFloatFloat32[this.bits];\n }\n\n /**\n * Unary minus\n */\n public minus(): Float16 {\n return Float16.fromBits(this.bits ^ 0x8000);\n }\n\n /**\n * Addition operator for Half or num left operands.\n */\n public add(f: Float16 | number): Float16 {\n const d =\n f instanceof Float16 ? f.toDouble() : typeof f === 'number' ? f : 0;\n return new Float16(this.toDouble() + d);\n }\n\n /**\n * Subtraction operator for Half or num left operands.\n */\n public sub(f: Float16 | number): Float16 {\n const d =\n f instanceof Float16 ? f.toDouble() : typeof f === 'number' ? f : 0;\n return new Float16(this.toDouble() - d);\n }\n\n /**\n * Multiplication operator for Half or num left operands.\n */\n public mul(f: Float16 | number): Float16 {\n const d =\n f instanceof Float16 ? f.toDouble() : typeof f === 'number' ? f : 0;\n return new Float16(this.toDouble() * d);\n }\n\n /**\n * Division operator for Half or num left operands.\n */\n public div(f: Float16 | number): Float16 {\n const d =\n f instanceof Float16 ? f.toDouble() : typeof f === 'number' ? f : 0;\n return new Float16(this.toDouble() / d);\n }\n\n /**\n * Round to n-bit precision (n should be between 0 and 10).\n * After rounding, the significand's 10-n least significant\n * bits will be zero.\n */\n public round(n: number): Float16 {\n if (n >= 10) {\n return Float16.from(this);\n }\n\n // Disassemble h into the sign, s,\n // and the combined exponent and significand, e.\n const s = this.bits & 0x8000;\n let e = this.bits & 0x7fff;\n\n // Round the exponent and significand to the nearest value\n // where ones occur only in the (10-n) most significant bits.\n // Note that the exponent adjusts automatically if rounding\n // up causes the significand to overflow.\n\n e >>= 9 - n;\n e += e & 1;\n e <<= 9 - n;\n\n // Check for exponent overflow.\n if (e >= 0x7c00) {\n // Overflow occurred - truncate instead of rounding.\n e = this.bits;\n e >>= 10 - n;\n e <<= 10 - n;\n }\n\n // Put the original sign bit back.\n\n return Float16.fromBits(s | e);\n }\n\n /**\n * Returns true if h is a normalized number, a denormalized number or zero.\n */\n public isFinite(): boolean {\n const e = (this.bits >> 10) & 0x001f;\n return e < 31;\n }\n\n /**\n * Returns true if h is a normalized number.\n */\n public isNormalized(): boolean {\n const e = (this.bits >> 10) & 0x001f;\n return e > 0 && e < 31;\n }\n\n /**\n * Returns true if h is a denormalized number.\n */\n public isDenormalized(): boolean {\n const e = (this.bits >> 10) & 0x001f;\n const m = this.bits & 0x3ff;\n return e === 0 && m !== 0;\n }\n\n /**\n * Returns true if h is zero.\n */\n public isZero(): boolean {\n return (this.bits & 0x7fff) === 0;\n }\n\n /**\n * Returns true if h is a NaN.\n */\n public isNaN(): boolean {\n const e = (this.bits >> 10) & 0x001f;\n const m = this.bits & 0x3ff;\n return e === 31 && m !== 0;\n }\n\n /**\n * Returns true if h is a positive or a negative infinity.\n */\n public isInfinity(): boolean {\n const e = (this.bits >> 10) & 0x001f;\n const m = this.bits & 0x3ff;\n return e === 31 && m === 0;\n }\n\n /**\n * Returns true if the sign bit of h is set (negative).\n */\n public isNegative(): boolean {\n return (this.bits & 0x8000) !== 0;\n }\n}\n", "/** @format */\n\nimport { MathUtils } from '../common/math-utils';\nimport { LibError } from '../error/lib-error';\n\n/**\n * The format of a color or image.\n */\nexport enum Format {\n uint1,\n uint2,\n uint4,\n uint8,\n uint16,\n uint32,\n int8,\n int16,\n int32,\n float16,\n float32,\n float64,\n}\n\n/**\n * The format type of a color or image.\n */\nexport enum FormatType {\n uint,\n int,\n float,\n}\n\nexport const FormatToFormatType = new Map([\n [Format.uint1, FormatType.uint],\n [Format.uint2, FormatType.uint],\n [Format.uint4, FormatType.uint],\n [Format.uint8, FormatType.uint],\n [Format.uint16, FormatType.uint],\n [Format.uint32, FormatType.uint],\n [Format.int8, FormatType.int],\n [Format.int16, FormatType.int],\n [Format.int32, FormatType.int],\n [Format.float16, FormatType.float],\n [Format.float32, FormatType.float],\n [Format.float64, FormatType.float],\n]);\n\nexport const FormatSize = new Map([\n [Format.uint1, 1],\n [Format.uint2, 1],\n [Format.uint4, 1],\n [Format.uint8, 1],\n [Format.uint16, 2],\n [Format.uint32, 4],\n [Format.int8, 1],\n [Format.int16, 2],\n [Format.int32, 4],\n [Format.float16, 2],\n [Format.float32, 4],\n [Format.float64, 8],\n]);\n\nexport const FormatMaxValue = new Map([\n [Format.uint1, 0x1],\n [Format.uint2, 0x3],\n [Format.uint4, 0xf],\n [Format.uint8, 0xff],\n [Format.uint16, 0xffff],\n [Format.uint32, 0xffffffff],\n [Format.int8, 0x7f],\n [Format.int16, 0x7fff],\n [Format.int32, 0x7fffffff],\n [Format.float16, 1],\n [Format.float32, 1],\n [Format.float64, 1],\n]);\n\n/**\n * Convert a value from the **from** format to the **to** format.\n */\nexport function convertFormatValue(\n value: number,\n from: Format,\n to: Format\n): number {\n if (from === to) {\n return value;\n }\n\n switch (from) {\n case Format.uint1:\n return value === 0 ? 0 : FormatMaxValue.get(to)!;\n case Format.uint2:\n switch (to) {\n case Format.uint1:\n return value === 0 ? 0 : 1;\n case Format.uint2:\n return value;\n case Format.uint4:\n return value * 5;\n case Format.uint8:\n return value * 75;\n case Format.uint16:\n return value * 21845;\n case Format.uint32:\n return value * 1431655765;\n case Format.int8:\n return value * 42;\n case Format.int16:\n return value * 10922;\n case Format.int32:\n return value * 715827882;\n case Format.float16:\n case Format.float32:\n case Format.float64:\n return value / 3;\n }\n break;\n case Format.uint4:\n switch (to) {\n case Format.uint1:\n return value === 0 ? 0 : 1;\n case Format.uint2:\n return Math.trunc(value) >> 1;\n case Format.uint4:\n return value;\n case Format.uint8:\n return value * 17;\n case Format.uint16:\n return value * 4369;\n case Format.uint32:\n return value * 286331153;\n case Format.int8:\n return value * 8;\n case Format.int16:\n return value * 2184;\n case Format.int32:\n return value * 143165576;\n case Format.float16:\n case Format.float32:\n case Format.float64:\n return value / 3;\n }\n break;\n case Format.uint8:\n switch (to) {\n case Format.uint1:\n return value === 0 ? 0 : 1;\n case Format.uint2:\n return Math.trunc(value) >> 6;\n case Format.uint4:\n return Math.trunc(value) >> 4;\n case Format.uint8:\n return value;\n case Format.uint16:\n return value * 257;\n case Format.uint32:\n return value * 16843009;\n case Format.int8:\n return Math.trunc(value) >> 1;\n case Format.int16:\n return value * 128;\n case Format.int32:\n return value * 8421504;\n case Format.float16:\n case Format.float32:\n case Format.float64:\n return value / 255;\n }\n break;\n case Format.uint16:\n switch (to) {\n case Format.uint1:\n return value === 0 ? 0 : 1;\n case Format.uint2:\n return Math.trunc(value) >> 14;\n case Format.uint4:\n return Math.trunc(value) >> 12;\n case Format.uint8:\n return Math.trunc(value) >> 8;\n case Format.uint16:\n return value;\n case Format.uint32:\n return Math.trunc(value) << 8;\n case Format.int8:\n return Math.trunc(value) >> 9;\n case Format.int16:\n return Math.trunc(value) >> 1;\n case Format.int32:\n return value * 524296;\n case Format.float16:\n case Format.float32:\n case Format.float64:\n return value / 0xffff;\n }\n break;\n case Format.uint32:\n switch (to) {\n case Format.uint1:\n return value === 0 ? 0 : 1;\n case Format.uint2:\n return Math.trunc(value) >> 30;\n case Format.uint4:\n return Math.trunc(value) >> 28;\n case Format.uint8:\n return Math.trunc(value) >> 24;\n case Format.uint16:\n return Math.trunc(value) >> 16;\n case Format.uint32:\n return value;\n case Format.int8:\n return Math.trunc(value) >> 25;\n case Format.int16:\n return Math.trunc(value) >> 17;\n case Format.int32:\n return Math.trunc(value) >> 1;\n case Format.float16:\n case Format.float32:\n case Format.float64:\n return value / 0xffffffff;\n }\n break;\n case Format.int8:\n switch (to) {\n case Format.uint1:\n return value === 0 ? 0 : 1;\n case Format.uint2:\n return value <= 0 ? 0 : Math.trunc(value) >> 5;\n case Format.uint4:\n return value <= 0 ? 0 : Math.trunc(value) >> 3;\n case Format.uint8:\n return value <= 0 ? 0 : Math.trunc(value) << 1;\n case Format.uint16:\n return value <= 0 ? 0 : Math.trunc(value) * 516;\n case Format.uint32:\n return value <= 0 ? 0 : Math.trunc(value) * 33818640;\n case Format.int8:\n return value;\n case Format.int16:\n return value * 258;\n case Format.int32:\n return value * 16909320;\n case Format.float16:\n case Format.float32:\n case Format.float64:\n return value / 127;\n }\n break;\n case Format.int16:\n switch (to) {\n case Format.uint1:\n return value === 0 ? 0 : 1;\n case Format.uint2:\n return value <= 0 ? 0 : Math.trunc(value) >> 15;\n case Format.uint4:\n return value <= 0 ? 0 : Math.trunc(value) >> 11;\n case Format.uint8:\n return value <= 0 ? 0 : Math.trunc(value) >> 7;\n case Format.uint16:\n return value <= 0 ? 0 : Math.trunc(value) << 1;\n case Format.uint32:\n return value <= 0 ? 0 : Math.trunc(value) * 131076;\n case Format.int8:\n return Math.trunc(value) >> 8;\n case Format.int16:\n return value;\n case Format.int32:\n return Math.trunc(value) * 65538;\n case Format.float16:\n case Format.float32:\n case Format.float64:\n return value / 0x7fff;\n }\n break;\n case Format.int32:\n switch (to) {\n case Format.uint1:\n return value === 0 ? 0 : 1;\n case Format.uint2:\n return value <= 0 ? 0 : Math.trunc(value) >> 29;\n case Format.uint4:\n return value <= 0 ? 0 : Math.trunc(value) >> 27;\n case Format.uint8:\n return value <= 0 ? 0 : Math.trunc(value) >> 23;\n case Format.uint16:\n return value <= 0 ? 0 : Math.trunc(value) >> 16;\n case Format.uint32:\n return value <= 0 ? 0 : Math.trunc(value) << 1;\n case Format.int8:\n return Math.trunc(value) >> 24;\n case Format.int16:\n return Math.trunc(value) >> 16;\n case Format.int32:\n return value;\n case Format.float16:\n case Format.float32:\n case Format.float64:\n return value / 0x7fffffff;\n }\n break;\n case Format.float16:\n case Format.float32:\n case Format.float64:\n switch (to) {\n case Format.uint1:\n return value === 0 ? 0 : 1;\n case Format.uint2:\n return Math.trunc(MathUtils.clamp(value, 0, 1) * 3);\n case Format.uint4:\n return Math.trunc(MathUtils.clamp(value, 0, 1) * 15);\n case Format.uint8:\n return Math.trunc(MathUtils.clamp(value, 0, 1) * 255);\n case Format.uint16:\n return Math.trunc(MathUtils.clamp(value, 0, 1) * 0xffff);\n case Format.uint32:\n return Math.trunc(MathUtils.clamp(value, 0, 1) * 0xffffffff);\n case Format.int8:\n return Math.trunc(\n value < 0\n ? MathUtils.clamp(value, -1, 1) * 128\n : MathUtils.clamp(value, -1, 1) * 127\n );\n case Format.int16:\n return Math.trunc(\n value < 0\n ? MathUtils.clamp(value, -1, 1) * 32768\n : MathUtils.clamp(value, -1, 1) * 32767\n );\n case Format.int32:\n return Math.trunc(\n value < 0\n ? MathUtils.clamp(value, -1, 1) * 2147483648\n : MathUtils.clamp(value, -1, 1) * 2147483647\n );\n case Format.float16:\n case Format.float32:\n case Format.float64:\n return value;\n }\n break;\n }\n throw new LibError('Unknown format.');\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { Palette } from '../image/palette';\nimport { Channel } from './channel';\nimport { Color, ColorConvertOptions } from './color';\nimport { ColorUtils } from './color-utils';\nimport { Format } from './format';\n\n/**\n * A 32-bit floating point color.\n */\nexport class ColorFloat32 implements Color {\n protected data: Float32Array;\n\n public get format(): Format {\n return Format.float32;\n }\n\n public get length(): number {\n return this.data.length;\n }\n\n public get maxChannelValue(): number {\n return 1;\n }\n\n public get maxIndexValue(): number {\n return 1;\n }\n\n public get isLdrFormat(): boolean {\n return false;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get hasPalette(): boolean {\n return false;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get r(): number {\n return this.getChannel(0);\n }\n public set r(r: number) {\n this.setChannel(0, r);\n }\n\n public get g(): number {\n return this.getChannel(1);\n }\n public set g(g: number) {\n this.setChannel(1, g);\n }\n\n public get b(): number {\n return this.getChannel(2);\n }\n public set b(b: number) {\n this.setChannel(2, b);\n }\n\n public get a(): number {\n return this.getChannel(3);\n }\n public set a(a: number) {\n this.setChannel(3, a);\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(data: Float32Array | number) {\n if (typeof data === 'number') {\n this.data = new Float32Array(data);\n } else {\n this.data = data.slice();\n }\n }\n\n public static from(other: ColorFloat32) {\n const c = new ColorFloat32(other.length);\n c.data = other.data;\n return c;\n }\n\n public static fromArray(color: Float32Array) {\n return new ColorFloat32(color);\n }\n\n public static rgb(r: number, g: number, b: number) {\n const data = new Float32Array([r, g, b]);\n return new ColorFloat32(data);\n }\n\n public static rgba(r: number, g: number, b: number, a: number) {\n const data = new Float32Array([r, g, b, a]);\n return new ColorFloat32(data);\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.data.length ? this.data[channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: number | Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(index: number | Channel, value: number): void {\n if (index < this.data.length) {\n this.data[index] = value;\n }\n }\n\n public set(c: Color): void {\n this.setRgba(c.r, c.g, c.b, c.a);\n }\n\n public setRgb(r: number, g: number, b: number): void {\n this.data[0] = r;\n const nc = this.data.length;\n if (nc > 1) {\n this.data[1] = g;\n if (nc > 2) {\n this.data[2] = b;\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n this.data[0] = r;\n const nc = this.data.length;\n if (nc > 1) {\n this.data[1] = g;\n if (nc > 2) {\n this.data[2] = b;\n if (nc > 3) {\n this.data[3] = a;\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone() {\n return ColorFloat32.from(this);\n }\n\n public equals(other: Color) {\n if (other.length !== this.length) {\n return false;\n }\n for (let i = 0; i < this.length; i++) {\n if (other.getChannel(i) !== this.getChannel(i)) {\n return false;\n }\n }\n return true;\n }\n\n public convert(opt?: ColorConvertOptions) {\n return ColorUtils.convertColor({\n from: this,\n format: opt?.format,\n numChannels: opt?.numChannels,\n alpha: opt?.alpha,\n });\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { Palette } from '../image/palette';\nimport { Channel } from './channel';\nimport { Color, ColorConvertOptions } from './color';\nimport { ColorUtils } from './color-utils';\nimport { Format } from './format';\n\n/**\n * A 64-bit floating point color.\n */\nexport class ColorFloat64 implements Color {\n protected data: Float64Array;\n\n public get format(): Format {\n return Format.float64;\n }\n\n public get length(): number {\n return this.data.length;\n }\n\n public get maxChannelValue(): number {\n return 1;\n }\n\n public get maxIndexValue(): number {\n return 1;\n }\n\n public get isLdrFormat(): boolean {\n return true;\n }\n\n public get isHdrFormat(): boolean {\n return false;\n }\n\n public get hasPalette(): boolean {\n return false;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get r(): number {\n return this.getChannel(0);\n }\n public set r(r: number) {\n this.setChannel(0, r);\n }\n\n public get g(): number {\n return this.getChannel(1);\n }\n public set g(g: number) {\n this.setChannel(1, g);\n }\n\n public get b(): number {\n return this.getChannel(2);\n }\n public set b(b: number) {\n this.setChannel(2, b);\n }\n\n public get a(): number {\n return this.getChannel(3);\n }\n public set a(a: number) {\n this.setChannel(3, a);\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(data: Float64Array | number) {\n if (typeof data === 'number') {\n this.data = new Float64Array(data);\n } else {\n this.data = data.slice();\n }\n }\n\n public static from(other: ColorFloat64) {\n const c = new ColorFloat64(other.length);\n c.data = other.data;\n return c;\n }\n\n public static fromArray(color: Float64Array) {\n return new ColorFloat64(color);\n }\n\n public static rgb(r: number, g: number, b: number) {\n const data = new Float64Array([r, g, b]);\n return new ColorFloat64(data);\n }\n\n public static rgba(r: number, g: number, b: number, a: number) {\n const data = new Float64Array([r, g, b, a]);\n return new ColorFloat64(data);\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.data.length ? this.data[channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: number | Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(index: number | Channel, value: number): void {\n if (index < this.data.length) {\n this.data[index] = value;\n }\n }\n\n public set(c: Color): void {\n this.setRgba(c.r, c.g, c.b, c.a);\n }\n\n public setRgb(r: number, g: number, b: number): void {\n this.data[0] = r;\n const nc = this.data.length;\n if (nc > 1) {\n this.data[1] = g;\n if (nc > 2) {\n this.data[2] = b;\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n this.data[0] = r;\n const nc = this.data.length;\n if (nc > 1) {\n this.data[1] = g;\n if (nc > 2) {\n this.data[2] = b;\n if (nc > 3) {\n this.data[3] = a;\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone() {\n return ColorFloat64.from(this);\n }\n\n public equals(other: Color) {\n if (other.length !== this.length) {\n return false;\n }\n for (let i = 0; i < this.length; i++) {\n if (other.getChannel(i) !== this.getChannel(i)) {\n return false;\n }\n }\n return true;\n }\n\n public convert(opt?: ColorConvertOptions) {\n return ColorUtils.convertColor({\n from: this,\n format: opt?.format,\n numChannels: opt?.numChannels,\n alpha: opt?.alpha,\n });\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { Palette } from '../image/palette';\nimport { Channel } from './channel';\nimport { Color, ColorConvertOptions } from './color';\nimport { ColorUtils } from './color-utils';\nimport { Format } from './format';\n\n/**\n * A 16-bit integer color.\n */\nexport class ColorInt16 implements Color {\n private _data: Int16Array;\n\n public get format(): Format {\n return Format.int16;\n }\n\n public get length(): number {\n return this._data.length;\n }\n\n public get maxChannelValue(): number {\n return 0x7fff;\n }\n\n public get maxIndexValue(): number {\n return 0x7fff;\n }\n\n public get isLdrFormat(): boolean {\n return false;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get hasPalette(): boolean {\n return false;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get r(): number {\n return this._data.length > 0 ? this._data[0] : 0;\n }\n public set r(r: number) {\n if (this._data.length > 0) {\n this._data[0] = Math.trunc(r);\n }\n }\n\n public get g(): number {\n return this._data.length > 1 ? this._data[1] : 0;\n }\n public set g(g: number) {\n if (this._data.length > 1) {\n this._data[1] = Math.trunc(g);\n }\n }\n\n public get b(): number {\n return this._data.length > 2 ? this._data[2] : 0;\n }\n public set b(b: number) {\n if (this._data.length > 2) {\n this._data[2] = Math.trunc(b);\n }\n }\n\n public get a(): number {\n return this._data.length > 3 ? this._data[3] : 0;\n }\n public set a(a: number) {\n if (this._data.length > 3) {\n this._data[3] = Math.trunc(a);\n }\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(data: Int16Array | number) {\n if (typeof data === 'number') {\n this._data = new Int16Array(data);\n } else {\n this._data = data.slice();\n }\n }\n\n public static from(other: ColorInt16) {\n const c = new ColorInt16(other.length);\n c._data = other._data;\n return c;\n }\n\n public static fromArray(color: number[]) {\n const data = new Int16Array(color);\n return new ColorInt16(data);\n }\n\n public static rgb(r: number, g: number, b: number) {\n const data = new Int16Array([r, g, b]);\n return new ColorInt16(data);\n }\n\n public static rgba(r: number, g: number, b: number, a: number) {\n const data = new Int16Array([r, g, b, a]);\n return new ColorInt16(data);\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this._data.length ? this._data[channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: number | Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(index: number | Channel, value: number): void {\n if (index < this._data.length) {\n this._data[index] = Math.trunc(value);\n }\n }\n\n public set(c: Color): void {\n this.setRgba(c.r, c.g, c.b, c.a);\n }\n\n public setRgb(r: number, g: number, b: number): void {\n this._data[0] = Math.trunc(r);\n const nc = this._data.length;\n if (nc > 1) {\n this._data[1] = Math.trunc(g);\n if (nc > 2) {\n this._data[2] = Math.trunc(b);\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n this._data[0] = Math.trunc(r);\n const nc = this._data.length;\n if (nc > 1) {\n this._data[1] = Math.trunc(g);\n if (nc > 2) {\n this._data[2] = Math.trunc(b);\n if (nc > 3) {\n this._data[3] = Math.trunc(a);\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone() {\n return ColorInt16.from(this);\n }\n\n public equals(other: Color) {\n if (other.length !== this.length) {\n return false;\n }\n for (let i = 0; i < this.length; i++) {\n if (other.getChannel(i) !== this.getChannel(i)) {\n return false;\n }\n }\n return true;\n }\n\n public convert(opt?: ColorConvertOptions) {\n return ColorUtils.convertColor({\n from: this,\n format: opt?.format,\n numChannels: opt?.numChannels,\n alpha: opt?.alpha,\n });\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { Palette } from '../image/palette';\nimport { Channel } from './channel';\nimport { Color, ColorConvertOptions } from './color';\nimport { ColorUtils } from './color-utils';\nimport { Format } from './format';\n\n/**\n * A 32-bit integer color.\n */\nexport class ColorInt32 implements Color {\n private _data: Int32Array;\n\n public get format(): Format {\n return Format.int32;\n }\n\n public get length(): number {\n return this._data.length;\n }\n\n public get maxChannelValue(): number {\n return 0x7fffffff;\n }\n\n public get maxIndexValue(): number {\n return 0x7fffffff;\n }\n\n public get isLdrFormat(): boolean {\n return false;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get hasPalette(): boolean {\n return false;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get r(): number {\n return this._data.length > 0 ? this._data[0] : 0;\n }\n public set r(r: number) {\n if (this._data.length > 0) {\n this._data[0] = Math.trunc(r);\n }\n }\n\n public get g(): number {\n return this._data.length > 1 ? this._data[1] : 0;\n }\n public set g(g: number) {\n if (this._data.length > 1) {\n this._data[1] = Math.trunc(g);\n }\n }\n\n public get b(): number {\n return this._data.length > 2 ? this._data[2] : 0;\n }\n public set b(b: number) {\n if (this._data.length > 2) {\n this._data[2] = Math.trunc(b);\n }\n }\n\n public get a(): number {\n return this._data.length > 3 ? this._data[3] : 0;\n }\n public set a(a: number) {\n if (this._data.length > 3) {\n this._data[3] = Math.trunc(a);\n }\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(data: Int32Array | number) {\n if (typeof data === 'number') {\n this._data = new Int32Array(data);\n } else {\n this._data = data.slice();\n }\n }\n\n public static from(other: ColorInt32) {\n const c = new ColorInt32(other.length);\n c._data = other._data;\n return c;\n }\n\n public static fromArray(color: number[]) {\n const data = new Int32Array(color);\n return new ColorInt32(data);\n }\n\n public static rgb(r: number, g: number, b: number) {\n const data = new Int32Array([r, g, b]);\n return new ColorInt32(data);\n }\n\n public static rgba(r: number, g: number, b: number, a: number) {\n const data = new Int32Array([r, g, b, a]);\n return new ColorInt32(data);\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this._data.length ? this._data[channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: number | Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(index: number | Channel, value: number): void {\n if (index < this._data.length) {\n this._data[index] = Math.trunc(value);\n }\n }\n\n public set(c: Color): void {\n this.setRgba(c.r, c.g, c.b, c.a);\n }\n\n public setRgb(r: number, g: number, b: number): void {\n this._data[0] = Math.trunc(r);\n const nc = this._data.length;\n if (nc > 1) {\n this._data[1] = Math.trunc(g);\n if (nc > 2) {\n this._data[2] = Math.trunc(b);\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n this._data[0] = Math.trunc(r);\n const nc = this._data.length;\n if (nc > 1) {\n this._data[1] = Math.trunc(g);\n if (nc > 2) {\n this._data[2] = Math.trunc(b);\n if (nc > 3) {\n this._data[3] = Math.trunc(a);\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone() {\n return ColorInt32.from(this);\n }\n\n public equals(other: Color) {\n if (other.length !== this.length) {\n return false;\n }\n for (let i = 0; i < this.length; i++) {\n if (other.getChannel(i) !== this.getChannel(i)) {\n return false;\n }\n }\n return true;\n }\n\n public convert(opt?: ColorConvertOptions) {\n return ColorUtils.convertColor({\n from: this,\n format: opt?.format,\n numChannels: opt?.numChannels,\n alpha: opt?.alpha,\n });\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { Palette } from '../image/palette';\nimport { Channel } from './channel';\nimport { Color, ColorConvertOptions } from './color';\nimport { ColorUtils } from './color-utils';\nimport { Format } from './format';\n\n/**\n * A 8-bit integer color.\n */\nexport class ColorInt8 implements Color {\n private _data: Int8Array;\n\n public get format(): Format {\n return Format.int8;\n }\n\n public get length(): number {\n return this._data.length;\n }\n\n public get maxChannelValue(): number {\n return 127;\n }\n\n public get maxIndexValue(): number {\n return 127;\n }\n\n public get isLdrFormat(): boolean {\n return false;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get hasPalette(): boolean {\n return false;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get r(): number {\n return this._data.length > 0 ? this._data[0] : 0;\n }\n public set r(r: number) {\n if (this._data.length > 0) {\n this._data[0] = Math.trunc(r);\n }\n }\n\n public get g(): number {\n return this._data.length > 1 ? this._data[1] : 0;\n }\n public set g(g: number) {\n if (this._data.length > 1) {\n this._data[1] = Math.trunc(g);\n }\n }\n\n public get b(): number {\n return this._data.length > 2 ? this._data[2] : 0;\n }\n public set b(b: number) {\n if (this._data.length > 2) {\n this._data[2] = Math.trunc(b);\n }\n }\n\n public get a(): number {\n return this._data.length > 3 ? this._data[3] : 0;\n }\n public set a(a: number) {\n if (this._data.length > 3) {\n this._data[3] = Math.trunc(a);\n }\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(data: Int8Array | number) {\n if (typeof data === 'number') {\n this._data = new Int8Array(data);\n } else {\n this._data = data.slice();\n }\n }\n\n public static from(other: ColorInt8) {\n const c = new ColorInt8(other.length);\n c._data = other._data;\n return c;\n }\n\n public static fromArray(color: number[]) {\n const data = new Int8Array(color);\n return new ColorInt8(data);\n }\n\n public static rgb(r: number, g: number, b: number) {\n const data = new Int8Array([r, g, b]);\n return new ColorInt8(data);\n }\n\n public static rgba(r: number, g: number, b: number, a: number) {\n const data = new Int8Array([r, g, b, a]);\n return new ColorInt8(data);\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this._data.length ? this._data[channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: number | Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(index: number | Channel, value: number): void {\n if (index < this._data.length) {\n this._data[index] = Math.trunc(value);\n }\n }\n\n public set(c: Color): void {\n this.setRgba(c.r, c.g, c.b, c.a);\n }\n\n public setRgb(r: number, g: number, b: number): void {\n this._data[0] = Math.trunc(r);\n const nc = this._data.length;\n if (nc > 1) {\n this._data[1] = Math.trunc(g);\n if (nc > 2) {\n this._data[2] = Math.trunc(b);\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n this._data[0] = Math.trunc(r);\n const nc = this._data.length;\n if (nc > 1) {\n this._data[1] = Math.trunc(g);\n if (nc > 2) {\n this._data[2] = Math.trunc(b);\n if (nc > 3) {\n this._data[3] = Math.trunc(a);\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone() {\n return ColorInt8.from(this);\n }\n\n public equals(other: Color) {\n if (other.length !== this.length) {\n return false;\n }\n for (let i = 0; i < this.length; i++) {\n if (other.getChannel(i) !== this.getChannel(i)) {\n return false;\n }\n }\n return true;\n }\n\n public convert(opt?: ColorConvertOptions) {\n return ColorUtils.convertColor({\n from: this,\n format: opt?.format,\n numChannels: opt?.numChannels,\n alpha: opt?.alpha,\n });\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { Palette } from '../image/palette';\nimport { Channel } from './channel';\nimport { Color, ColorConvertOptions } from './color';\nimport { ColorUtils } from './color-utils';\nimport { Format } from './format';\n\n/**\n * A 1-bit unsigned int color with channel values in the range [0, 1].\n */\nexport class ColorUint1 implements Color {\n private _data: number;\n\n public get format(): Format {\n return Format.uint1;\n }\n\n private readonly _length: number;\n public get length(): number {\n return this._length;\n }\n\n public get maxChannelValue(): number {\n return 1;\n }\n\n public get maxIndexValue(): number {\n return 1;\n }\n\n public get isLdrFormat(): boolean {\n return true;\n }\n\n public get isHdrFormat(): boolean {\n return false;\n }\n\n public get hasPalette(): boolean {\n return false;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get r(): number {\n return this.getChannel(0);\n }\n public set r(r: number) {\n this.setChannel(0, r);\n }\n\n public get g(): number {\n return this.getChannel(1);\n }\n public set g(g: number) {\n this.setChannel(1, g);\n }\n\n public get b(): number {\n return this.getChannel(2);\n }\n public set b(b: number) {\n this.setChannel(2, b);\n }\n\n public get a(): number {\n return this.getChannel(3);\n }\n public set a(a: number) {\n this.setChannel(3, a);\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(data: number[] | number) {\n if (typeof data === 'number') {\n this._length = data;\n this._data = 0;\n } else {\n this._length = data.length;\n this._data = 0;\n this.setRgba(\n data.length > 0 ? data[0] : 0,\n data.length > 1 ? data[1] : 0,\n data.length > 2 ? data[2] : 0,\n data.length > 3 ? data[3] : 0\n );\n }\n }\n\n public static from(other: ColorUint1) {\n const c = new ColorUint1(other._length);\n c._data = other._data;\n return c;\n }\n\n public static fromArray(color: number[]) {\n return new ColorUint1(color);\n }\n\n public static rgb(r: number, g: number, b: number) {\n return new ColorUint1([r, g, b]);\n }\n\n public static rgba(r: number, g: number, b: number, a: number) {\n return new ColorUint1([r, g, b, a]);\n }\n\n public getChannel(channel: number | Channel): number {\n return channel < this.length ? (this._data >> (7 - channel)) & 0x1 : 0;\n }\n\n public getChannelNormalized(channel: number | Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(index: number | Channel, value: number): void {\n let _index = index;\n if (_index >= this.length) {\n return;\n }\n _index = 7 - _index;\n let v = this._data;\n if (value !== 0) {\n v |= 1 << _index;\n } else {\n v &= ~((1 << _index) & 0xff);\n }\n this._data = v;\n }\n\n public set(c: Color): void {\n this.setRgba(c.r, c.g, c.b, c.a);\n }\n\n public setRgb(r: number, g: number, b: number): void {\n this.r = r;\n this.g = g;\n this.b = b;\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n this.r = r;\n this.g = g;\n this.b = b;\n this.a = a;\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone() {\n return ColorUint1.from(this);\n }\n\n public equals(other: Color) {\n if (other.length !== this.length) {\n return false;\n }\n for (let i = 0; i < this.length; i++) {\n if (other.getChannel(i) !== this.getChannel(i)) {\n return false;\n }\n }\n return true;\n }\n\n public convert(opt?: ColorConvertOptions) {\n return ColorUtils.convertColor({\n from: this,\n format: opt?.format,\n numChannels: opt?.numChannels,\n alpha: opt?.alpha,\n });\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { Palette } from '../image/palette';\nimport { Channel } from './channel';\nimport { Color, ColorConvertOptions } from './color';\nimport { ColorUtils } from './color-utils';\nimport { Format } from './format';\n\n/**\n * A 16-bit unsigned int color with channel values in the range [0, 65535].\n */\nexport class ColorUint16 implements Color {\n protected data: Uint16Array;\n\n public get format(): Format {\n return Format.uint16;\n }\n\n public get length(): number {\n return this.data.length;\n }\n\n public get maxChannelValue(): number {\n return 0xffff;\n }\n\n public get maxIndexValue(): number {\n return 0xffff;\n }\n\n public get isLdrFormat(): boolean {\n return false;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get hasPalette(): boolean {\n return false;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get r(): number {\n return this.getChannel(0);\n }\n public set r(r: number) {\n this.setChannel(0, r);\n }\n\n public get g(): number {\n return this.getChannel(1);\n }\n public set g(g: number) {\n this.setChannel(1, g);\n }\n\n public get b(): number {\n return this.getChannel(2);\n }\n public set b(b: number) {\n this.setChannel(2, b);\n }\n\n public get a(): number {\n return this.getChannel(3);\n }\n public set a(a: number) {\n this.setChannel(3, a);\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(data: Uint16Array | number) {\n if (typeof data === 'number') {\n this.data = new Uint16Array(data);\n } else {\n this.data = data.slice();\n }\n }\n\n public static from(other: ColorUint16) {\n const c = new ColorUint16(other.length);\n c.data = other.data;\n return c;\n }\n\n public static fromArray(color: Uint16Array) {\n return new ColorUint16(color);\n }\n\n public static rgb(r: number, g: number, b: number) {\n const data = new Uint16Array([r, g, b]);\n return new ColorUint16(data);\n }\n\n public static rgba(r: number, g: number, b: number, a: number) {\n const data = new Uint16Array([r, g, b, a]);\n return new ColorUint16(data);\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.data.length ? this.data[channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: number | Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(index: number | Channel, value: number): void {\n if (index < this.data.length) {\n this.data[index] = Math.trunc(value);\n }\n }\n\n public set(c: Color): void {\n this.setRgba(c.r, c.g, c.b, c.a);\n }\n\n public setRgb(r: number, g: number, b: number): void {\n this.data[0] = Math.trunc(r);\n const nc = this.data.length;\n if (nc > 1) {\n this.data[1] = Math.trunc(g);\n if (nc > 2) {\n this.data[2] = Math.trunc(b);\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n this.data[0] = Math.trunc(r);\n const nc = this.data.length;\n if (nc > 1) {\n this.data[1] = Math.trunc(g);\n if (nc > 2) {\n this.data[2] = Math.trunc(b);\n if (nc > 3) {\n this.data[3] = Math.trunc(a);\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone() {\n return ColorUint16.from(this);\n }\n\n public equals(other: Color) {\n if (other.length !== this.length) {\n return false;\n }\n for (let i = 0; i < this.length; i++) {\n if (other.getChannel(i) !== this.getChannel(i)) {\n return false;\n }\n }\n return true;\n }\n\n public convert(opt?: ColorConvertOptions) {\n return ColorUtils.convertColor({\n from: this,\n format: opt?.format,\n numChannels: opt?.numChannels,\n alpha: opt?.alpha,\n });\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { Palette } from '../image/palette';\nimport { Channel } from './channel';\nimport { Color, ColorConvertOptions } from './color';\nimport { ColorUtils } from './color-utils';\nimport { Format } from './format';\n\n/**\n * A 2-bit unsigned int color with channel values in the range [0, 3].\n */\nexport class ColorUint2 implements Color {\n private _data: number;\n\n public get format(): Format {\n return Format.uint2;\n }\n\n private readonly _length: number;\n public get length(): number {\n return this._length;\n }\n\n public get maxChannelValue(): number {\n return 3;\n }\n\n public get maxIndexValue(): number {\n return 3;\n }\n\n public get isLdrFormat(): boolean {\n return true;\n }\n\n public get isHdrFormat(): boolean {\n return false;\n }\n\n public get hasPalette(): boolean {\n return false;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get r(): number {\n return this.getChannel(0);\n }\n public set r(r: number) {\n this.setChannel(0, r);\n }\n\n public get g(): number {\n return this.getChannel(1);\n }\n public set g(g: number) {\n this.setChannel(1, g);\n }\n\n public get b(): number {\n return this.getChannel(2);\n }\n public set b(b: number) {\n this.setChannel(2, b);\n }\n\n public get a(): number {\n return this.getChannel(3);\n }\n public set a(a: number) {\n this.setChannel(3, a);\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(data: number[] | number) {\n if (typeof data === 'number') {\n this._length = data;\n this._data = 0;\n } else {\n this._length = data.length;\n this._data = 0;\n this.setRgba(\n data.length > 0 ? data[0] : 0,\n data.length > 1 ? data[1] : 0,\n data.length > 2 ? data[2] : 0,\n data.length > 3 ? data[3] : 0\n );\n }\n }\n\n public static from(other: ColorUint2) {\n const c = new ColorUint2(other._length);\n c._data = other._data;\n return c;\n }\n\n public static fromArray(color: number[]) {\n return new ColorUint2(color);\n }\n\n public static rgb(r: number, g: number, b: number) {\n return new ColorUint2([r, g, b]);\n }\n\n public static rgba(r: number, g: number, b: number, a: number) {\n return new ColorUint2([r, g, b, a]);\n }\n\n public getChannel(channel: number | Channel): number {\n return channel < this.length\n ? (this._data >> (6 - (channel << 1))) & 0x3\n : 0;\n }\n\n public getChannelNormalized(channel: number | Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(index: number | Channel, value: number): void {\n const _index = index;\n if (_index >= this.length) {\n return;\n }\n\n const _mask = [\n ~(0x3 << (6 - (0 << 1))) & 0xff,\n ~(0x3 << (6 - (1 << 1))) & 0xff,\n ~(0x3 << (6 - (2 << 1))) & 0xff,\n ~(0x3 << (6 - (3 << 1))) & 0xff,\n ];\n\n const mask = _mask[index];\n const x = Math.trunc(value) & 0x3;\n this._data = (this._data & mask) | (x << (6 - (index << 1)));\n }\n\n public set(c: Color): void {\n this.setRgba(c.r, c.g, c.b, c.a);\n }\n\n public setRgb(r: number, g: number, b: number): void {\n this.r = r;\n this.g = g;\n this.b = b;\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n this.r = r;\n this.g = g;\n this.b = b;\n this.a = a;\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone() {\n return ColorUint2.from(this);\n }\n\n public equals(other: Color) {\n if (other.length !== this.length) {\n return false;\n }\n for (let i = 0; i < this.length; i++) {\n if (other.getChannel(i) !== this.getChannel(i)) {\n return false;\n }\n }\n return true;\n }\n\n public convert(opt?: ColorConvertOptions) {\n return ColorUtils.convertColor({\n from: this,\n format: opt?.format,\n numChannels: opt?.numChannels,\n alpha: opt?.alpha,\n });\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { Palette } from '../image/palette';\nimport { Channel } from './channel';\nimport { Color, ColorConvertOptions } from './color';\nimport { ColorUtils } from './color-utils';\nimport { Format } from './format';\n\n/**\n * A 32-bit unsigned int color.\n */\nexport class ColorUint32 implements Color {\n protected data: Uint32Array;\n\n public get format(): Format {\n return Format.uint32;\n }\n\n public get length(): number {\n return this.data.length;\n }\n\n public get maxChannelValue(): number {\n return 0xffffffff;\n }\n\n public get maxIndexValue(): number {\n return 0xffffffff;\n }\n\n public get isLdrFormat(): boolean {\n return false;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get hasPalette(): boolean {\n return false;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get r(): number {\n return this.getChannel(0);\n }\n public set r(r: number) {\n this.setChannel(0, r);\n }\n\n public get g(): number {\n return this.getChannel(1);\n }\n public set g(g: number) {\n this.setChannel(1, g);\n }\n\n public get b(): number {\n return this.getChannel(2);\n }\n public set b(b: number) {\n this.setChannel(2, b);\n }\n\n public get a(): number {\n return this.getChannel(3);\n }\n public set a(a: number) {\n this.setChannel(3, a);\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(data: Uint32Array | number) {\n if (typeof data === 'number') {\n this.data = new Uint32Array(data);\n } else {\n this.data = data.slice();\n }\n }\n\n public static from(other: ColorUint32) {\n const c = new ColorUint32(other.length);\n c.data = other.data;\n return c;\n }\n\n public static fromArray(color: Uint32Array) {\n return new ColorUint32(color);\n }\n\n public static rgb(r: number, g: number, b: number) {\n const data = new Uint32Array([r, g, b]);\n return new ColorUint32(data);\n }\n\n public static rgba(r: number, g: number, b: number, a: number) {\n const data = new Uint32Array([r, g, b, a]);\n return new ColorUint32(data);\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.data.length ? this.data[channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: number | Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(index: number | Channel, value: number): void {\n if (index < this.data.length) {\n this.data[index] = Math.trunc(value);\n }\n }\n\n public set(c: Color): void {\n this.setRgba(c.r, c.g, c.b, c.a);\n }\n\n public setRgb(r: number, g: number, b: number): void {\n this.data[0] = Math.trunc(r);\n const nc = this.data.length;\n if (nc > 1) {\n this.data[1] = Math.trunc(g);\n if (nc > 2) {\n this.data[2] = Math.trunc(b);\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n this.data[0] = Math.trunc(r);\n const nc = this.data.length;\n if (nc > 1) {\n this.data[1] = Math.trunc(g);\n if (nc > 2) {\n this.data[2] = Math.trunc(b);\n if (nc > 3) {\n this.data[3] = Math.trunc(a);\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone() {\n return ColorUint32.from(this);\n }\n\n public equals(other: Color) {\n if (other.length !== this.length) {\n return false;\n }\n for (let i = 0; i < this.length; i++) {\n if (other.getChannel(i) !== this.getChannel(i)) {\n return false;\n }\n }\n return true;\n }\n\n public convert(opt?: ColorConvertOptions) {\n return ColorUtils.convertColor({\n from: this,\n format: opt?.format,\n numChannels: opt?.numChannels,\n alpha: opt?.alpha,\n });\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { MathUtils } from '../common/math-utils';\nimport { Palette } from '../image/palette';\nimport { Channel } from './channel';\nimport { Color, ColorConvertOptions } from './color';\nimport { ColorUtils } from './color-utils';\nimport { Format } from './format';\n\n/**\n * A 4-bit unsigned int color with channel values in the range [0, 15].\n */\nexport class ColorUint4 implements Color {\n private _data: Uint8Array;\n\n public get format(): Format {\n return Format.uint4;\n }\n\n private readonly _length: number;\n public get length(): number {\n return this._length;\n }\n\n public get maxChannelValue(): number {\n return 15;\n }\n\n public get maxIndexValue(): number {\n return 15;\n }\n\n public get isLdrFormat(): boolean {\n return true;\n }\n\n public get isHdrFormat(): boolean {\n return false;\n }\n\n public get hasPalette(): boolean {\n return false;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get r(): number {\n return this.getChannel(0);\n }\n public set r(r: number) {\n this.setChannel(0, r);\n }\n\n public get g(): number {\n return this.getChannel(1);\n }\n public set g(g: number) {\n this.setChannel(1, g);\n }\n\n public get b(): number {\n return this.getChannel(2);\n }\n public set b(b: number) {\n this.setChannel(2, b);\n }\n\n public get a(): number {\n return this.getChannel(3);\n }\n public set a(a: number) {\n this.setChannel(3, a);\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(data: Uint8Array | number) {\n if (typeof data === 'number') {\n this._length = data;\n this._data = new Uint8Array(this.length < 3 ? 1 : 2);\n } else {\n this._length = data.length;\n this._data = new Uint8Array(this._length < 3 ? 1 : 2);\n this.setRgba(\n this._length > 0 ? data[0] : 0,\n this._length > 1 ? data[1] : 0,\n this._length > 2 ? data[2] : 0,\n this._length > 3 ? data[3] : 0\n );\n }\n }\n\n public static from(other: ColorUint4) {\n const c = new ColorUint4(other._length);\n c._data = other._data;\n return c;\n }\n\n public static fromArray(color: Uint8Array) {\n return new ColorUint4(color);\n }\n\n public static rgb(r: number, g: number, b: number) {\n const c = new ColorUint4(3);\n c.setRgb(r, g, b);\n return c;\n }\n\n public static rgba(r: number, g: number, b: number, a: number) {\n const c = new ColorUint4(4);\n c.setRgba(r, g, b, a);\n return c;\n }\n\n public getChannel(channel: number | Channel): number {\n return channel < 0 || channel >= this.length\n ? 0\n : channel < 2\n ? (this._data[0] >> (4 - (channel << 2))) & 0xf\n : (this._data[1] >> (4 - ((channel & 0x1) << 2))) & 0xf;\n }\n\n public getChannelNormalized(channel: number | Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(index: number | Channel, value: number): void {\n let _index = index;\n if (_index >= this.length) {\n return;\n }\n const vi = MathUtils.clamp(Math.trunc(value), 0, 15);\n let i = 0;\n if (_index > 1) {\n _index &= 0x1;\n i = 1;\n }\n if (_index === 0) {\n this._data[i] = (this._data[i] & 0xf) | (vi << 4);\n } else if (_index === 1) {\n this._data[i] = (this._data[i] & 0xf0) | vi;\n }\n }\n\n public set(c: Color): void {\n this.setRgba(c.r, c.g, c.b, c.a);\n }\n\n public setRgb(r: number, g: number, b: number): void {\n this.r = r;\n this.g = g;\n this.b = b;\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n this.r = r;\n this.g = g;\n this.b = b;\n this.a = a;\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone() {\n return ColorUint4.from(this);\n }\n\n public equals(other: Color) {\n if (other.length !== this.length) {\n return false;\n }\n for (let i = 0; i < this.length; i++) {\n if (other.getChannel(i) !== this.getChannel(i)) {\n return false;\n }\n }\n return true;\n }\n\n public convert(opt?: ColorConvertOptions) {\n return ColorUtils.convertColor({\n from: this,\n format: opt?.format,\n numChannels: opt?.numChannels,\n alpha: opt?.alpha,\n });\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { Palette } from '../image/palette';\nimport { Channel } from './channel';\nimport { Color, ColorConvertOptions } from './color';\nimport { ColorUtils } from './color-utils';\nimport { Format } from './format';\n\n/**\n * An 8-bit unsigned int color with channel values in the range [0, 255].\n */\nexport class ColorUint8 implements Color {\n protected data: Uint8Array;\n\n public get format(): Format {\n return Format.uint8;\n }\n\n public get length(): number {\n return this.data.length;\n }\n\n public get maxChannelValue(): number {\n return 255;\n }\n\n public get maxIndexValue(): number {\n return 255;\n }\n\n public get isLdrFormat(): boolean {\n return true;\n }\n\n public get isHdrFormat(): boolean {\n return false;\n }\n\n public get hasPalette(): boolean {\n return false;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get r(): number {\n return this.getChannel(0);\n }\n public set r(r: number) {\n this.setChannel(0, r);\n }\n\n public get g(): number {\n return this.getChannel(1);\n }\n public set g(g: number) {\n this.setChannel(1, g);\n }\n\n public get b(): number {\n return this.getChannel(2);\n }\n public set b(b: number) {\n this.setChannel(2, b);\n }\n\n public get a(): number {\n return this.getChannel(3, 255);\n }\n public set a(a: number) {\n this.setChannel(3, a);\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(data: Uint8Array | number) {\n if (typeof data === 'number') {\n this.data = new Uint8Array(data);\n } else {\n this.data = data.slice();\n }\n }\n\n public static from(other: ColorUint8) {\n const c = new ColorUint8(other.length);\n c.data = other.data;\n return c;\n }\n\n public static fromArray(color: Uint8Array) {\n return new ColorUint8(color);\n }\n\n public static rgb(r: number, g: number, b: number) {\n const data = new Uint8Array([r, g, b]);\n return new ColorUint8(data);\n }\n\n public static rgba(r: number, g: number, b: number, a: number) {\n const data = new Uint8Array([r, g, b, a]);\n return new ColorUint8(data);\n }\n\n public getChannel(channel: number | Channel, defValue = 0): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.data.length ? this.data[channel] : defValue;\n }\n }\n\n public getChannelNormalized(channel: number | Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(index: number | Channel, value: number): void {\n if (index < this.data.length) {\n this.data[index] = Math.trunc(value);\n }\n }\n\n public set(c: Color): void {\n this.setRgba(c.r, c.g, c.b, c.a);\n }\n\n public setRgb(r: number, g: number, b: number): void {\n this.data[0] = Math.trunc(r);\n const nc = this.data.length;\n if (nc > 1) {\n this.data[1] = Math.trunc(g);\n if (nc > 2) {\n this.data[2] = Math.trunc(b);\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n this.data[0] = Math.trunc(r);\n const nc = this.data.length;\n if (nc > 1) {\n this.data[1] = Math.trunc(g);\n if (nc > 2) {\n this.data[2] = Math.trunc(b);\n if (nc > 3) {\n this.data[3] = Math.trunc(a);\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone() {\n return ColorUint8.from(this);\n }\n\n public equals(other: Color) {\n if (other.length !== this.length) {\n return false;\n }\n for (let i = 0; i < this.length; i++) {\n if (other.getChannel(i) !== this.getChannel(i)) {\n return false;\n }\n }\n return true;\n }\n\n public convert(opt?: ColorConvertOptions) {\n return ColorUtils.convertColor({\n from: this,\n format: opt?.format,\n numChannels: opt?.numChannels,\n alpha: opt?.alpha,\n });\n }\n}\n", "/** @format */\n\nimport { MathUtils } from '../common/math-utils';\nimport { LibError } from '../error/lib-error';\nimport { Color } from './color';\nimport { ColorFloat16 } from './color-float16';\nimport { ColorFloat32 } from './color-float32';\nimport { ColorFloat64 } from './color-float64';\nimport { ColorInt16 } from './color-int16';\nimport { ColorInt32 } from './color-int32';\nimport { ColorInt8 } from './color-int8';\nimport { ColorUint1 } from './color-uint1';\nimport { ColorUint16 } from './color-uint16';\nimport { ColorUint2 } from './color-uint2';\nimport { ColorUint32 } from './color-uint32';\nimport { ColorUint4 } from './color-uint4';\nimport { ColorUint8 } from './color-uint8';\nimport { convertFormatValue, Format } from './format';\n\nexport interface ConvertColorOptions {\n from: Color;\n to?: Color;\n format?: Format;\n numChannels?: number;\n alpha?: number;\n}\n\nexport abstract class ColorUtils {\n private static convertColorInternal(c: Color, c2: Color, a: number): Color {\n const numChannels = c2.length;\n const format = c2.format;\n const fromFormat = c.palette?.format ?? c.format;\n const cl = c.length;\n if (numChannels === 1) {\n const g = Math.trunc(c.length > 2 ? c.luminance : c.getChannel(0));\n c2.setChannel(0, convertFormatValue(g, fromFormat, format));\n } else if (numChannels <= cl) {\n for (let ci = 0; ci < numChannels; ++ci) {\n c2.setChannel(\n ci,\n convertFormatValue(c.getChannel(ci), fromFormat, format)\n );\n }\n } else {\n for (let ci = 0; ci < cl; ++ci) {\n c2.setChannel(\n ci,\n convertFormatValue(c.getChannel(ci), fromFormat, format)\n );\n }\n const v = cl === 1 ? c2.getChannel(0) : 0;\n for (let ci = cl; ci < numChannels; ++ci) {\n c2.setChannel(ci, ci === 3 ? a : v);\n }\n }\n return c2;\n }\n\n public static uint32ToRed(c: number): number {\n return c & 0xff;\n }\n\n public static uint32ToGreen(c: number): number {\n return (c >> 8) & 0xff;\n }\n\n public static uint32ToBlue(c: number): number {\n return (c >> 16) & 0xff;\n }\n\n public static uint32ToAlpha(c: number): number {\n return (c >> 24) & 0xff;\n }\n\n public static rgbaToUint32(\n r: number,\n g: number,\n b: number,\n a: number\n ): number {\n return (\n MathUtils.clampInt255(r) |\n (MathUtils.clampInt255(g) << 8) |\n (MathUtils.clampInt255(b) << 16) |\n (MathUtils.clampInt255(a) << 24)\n );\n }\n\n public static convertColor(opt: ConvertColorOptions): Color {\n const fromFormat = opt.from.palette?.format ?? opt.from.format;\n const format = opt.to?.format ?? opt.format ?? opt.from.format;\n const numChannels = opt.to?.length ?? opt.numChannels ?? opt.from.length;\n const alpha = opt.alpha ?? 0;\n\n if (format === fromFormat && numChannels === opt.from.length) {\n if (opt.to === undefined) {\n return opt.from.clone();\n }\n opt.to.set(opt.from);\n return opt.to;\n }\n\n switch (format) {\n case Format.uint8: {\n const c2 = opt.to ?? new ColorUint8(numChannels);\n return this.convertColorInternal(opt.from, c2, alpha);\n }\n case Format.uint1: {\n const c2 = opt.to ?? new ColorUint1(numChannels);\n return this.convertColorInternal(opt.from, c2, alpha);\n }\n case Format.uint2: {\n const c2 = opt.to ?? new ColorUint2(numChannels);\n return this.convertColorInternal(opt.from, c2, alpha);\n }\n case Format.uint4: {\n const c2 = opt.to ?? new ColorUint4(numChannels);\n return this.convertColorInternal(opt.from, c2, alpha);\n }\n case Format.uint16: {\n const c2 = opt.to ?? new ColorUint16(numChannels);\n return this.convertColorInternal(opt.from, c2, alpha);\n }\n case Format.uint32: {\n const c2 = opt.to ?? new ColorUint32(numChannels);\n return this.convertColorInternal(opt.from, c2, alpha);\n }\n case Format.int8: {\n const c2 = opt.to ?? new ColorInt8(numChannels);\n return this.convertColorInternal(opt.from, c2, alpha);\n }\n case Format.int16: {\n const c2 = opt.to ?? new ColorInt16(numChannels);\n return this.convertColorInternal(opt.from, c2, alpha);\n }\n case Format.int32: {\n const c2 = opt.to ?? new ColorInt32(numChannels);\n return this.convertColorInternal(opt.from, c2, alpha);\n }\n case Format.float16: {\n const c2 = opt.to ?? new ColorFloat16(numChannels);\n return this.convertColorInternal(opt.from, c2, alpha);\n }\n case Format.float32: {\n const c2 = opt.to ?? new ColorFloat32(numChannels);\n return this.convertColorInternal(opt.from, c2, alpha);\n }\n case Format.float64: {\n const c2 = opt.to ?? new ColorFloat64(numChannels);\n return this.convertColorInternal(opt.from, c2, alpha);\n }\n }\n throw new LibError('Unknown format.');\n }\n\n /**\n * Returns the luminance (grayscale) value of the color.\n */\n public static getLuminance(c: Color): number {\n return 0.299 * c.r + 0.587 * c.g + 0.114 * c.b;\n }\n\n /**\n * Returns the normalized [0, 1] luminance (grayscale) value of the color.\n */\n public static getLuminanceNormalized(c: Color): number {\n return (\n 0.299 * c.rNormalized + 0.587 * c.gNormalized + 0.114 * c.bNormalized\n );\n }\n\n /**\n * Returns the luminance (grayscale) value of the color.\n */\n public static getLuminanceRgb(r: number, g: number, b: number): number {\n return 0.299 * r + 0.587 * g + 0.114 * b;\n }\n\n /**\n * Convert an HSL color to RGB, where **hue** is specified in normalized degrees\n * [0, 1] (where 1 is 360-degrees); **saturation** and **lightness** are in the range [0, 1].\n * Returns a list [r, g, b] with values in the range [0, 255].\n */\n public static hslToRgb(\n hue: number,\n saturation: number,\n lightness: number\n ): number[] {\n if (saturation === 0) {\n const gray = Math.trunc(lightness * 255);\n return [gray, gray, gray];\n }\n\n const hue2rgb = (p: number, q: number, t: number): number => {\n let _t = t;\n if (_t < 0) {\n _t += 1;\n }\n if (_t > 1) {\n _t -= 1;\n }\n if (_t < 1 / 6) {\n return p + (q - p) * 6 * _t;\n }\n if (_t < 1 / 2) {\n return q;\n }\n if (_t < 2 / 3) {\n return p + (q - p) * (2 / 3 - _t) * 6;\n }\n return p;\n };\n\n const q =\n lightness < 0.5\n ? lightness * (1 + saturation)\n : lightness + saturation - lightness * saturation;\n const p = 2 * lightness - q;\n\n const r = hue2rgb(p, q, hue + 1 / 3);\n const g = hue2rgb(p, q, hue);\n const b = hue2rgb(p, q, hue - 1 / 3);\n\n return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];\n }\n\n /**\n * Convert an HSV color to RGB, where **hue** is specified in normalized degrees\n * [0, 1] (where 1 is 360-degrees); **saturation** and **brightness** are in the range [0, 1].\n * Returns a list [r, g, b] with values in the range [0, 255].\n */\n public static hsvToRgb(\n hue: number,\n saturation: number,\n brightness: number\n ): number[] {\n if (saturation === 0) {\n const gray = Math.round(brightness * 255);\n return [gray, gray, gray];\n }\n\n const h = (hue - Math.floor(hue)) * 6;\n const f = h - Math.floor(h);\n const p = brightness * (1 - saturation);\n const q = brightness * (1 - saturation * f);\n const t = brightness * (1 - saturation * (1 - f));\n\n switch (Math.trunc(h)) {\n case 0:\n return [\n Math.round(brightness * 255),\n Math.round(t * 255),\n Math.round(p * 255),\n ];\n case 1:\n return [\n Math.round(q * 255),\n Math.round(brightness * 255),\n Math.round(p * 255),\n ];\n case 2:\n return [\n Math.round(p * 255),\n Math.round(brightness * 255),\n Math.round(t * 255),\n ];\n case 3:\n return [\n Math.round(p * 255),\n Math.round(q * 255),\n Math.round(brightness * 255),\n ];\n case 4:\n return [\n Math.round(t * 255),\n Math.round(p * 255),\n Math.round(brightness * 255),\n ];\n case 5:\n return [\n Math.round(brightness * 255),\n Math.round(p * 255),\n Math.round(q * 255),\n ];\n default:\n throw new LibError('Invalid hue.');\n }\n }\n\n /**\n * Convert an RGB color to HSL, where **r**, **g** and **b** are in the range [0, 255].\n * Returns a list [h, s, l] with values in the range [0, 1].\n */\n public static rgbToHsl(r: number, g: number, b: number): number[] {\n const _r = r / 255;\n const _g = g / 255;\n const _b = b / 255;\n const mx = Math.max(_r, Math.max(_g, _b));\n const mn = Math.min(_r, Math.min(_g, _b));\n const l = (mx + mn) / 2;\n\n if (mx === mn) {\n return [0, 0, l];\n }\n\n const d = mx - mn;\n\n const s = l > 0.5 ? d / (2 - mx - mn) : d / (mx + mn);\n\n let h = 0;\n if (mx === _r) {\n h = (_g - _b) / d + (_g < _b ? 6 : 0);\n } else if (mx === _g) {\n h = (_b - _r) / d + 2;\n } else {\n h = (_r - _g) / d + 4;\n }\n\n h /= 6;\n\n return [h, s, l];\n }\n\n /**\n * Convert a CIE L\\*a\\*b color to XYZ.\n */\n public static labToXyz(l: number, a: number, b: number): number[] {\n let y = (l + 16) / 116;\n let x = y + a / 500;\n let z = y - b / 200;\n if (Math.pow(x, 3) > 0.008856) {\n x = Math.pow(x, 3);\n } else {\n x = (x - 16 / 116) / 7.787;\n }\n if (Math.pow(y, 3) > 0.008856) {\n y = Math.pow(y, 3);\n } else {\n y = (y - 16 / 116) / 7.787;\n }\n if (Math.pow(z, 3) > 0.008856) {\n z = Math.pow(z, 3);\n } else {\n z = (z - 16 / 116) / 7.787;\n }\n\n return [\n Math.trunc(x * 95.047),\n Math.trunc(y * 100),\n Math.trunc(z * 108.883),\n ];\n }\n\n /**\n * Convert an XYZ color to RGB.\n */\n public static xyzToRgb(x: number, y: number, z: number): number[] {\n const _x = x / 100;\n const _y = y / 100;\n const _z = z / 100;\n let r = 3.2406 * _x + -1.5372 * _y + -0.4986 * _z;\n let g = -0.9689 * _x + 1.8758 * _y + 0.0415 * _z;\n let b = 0.0557 * _x + -0.204 * _y + 1.057 * _z;\n if (r > 0.0031308) {\n r = 1.055 * Math.pow(r, 0.4166666667) - 0.055;\n } else {\n r *= 12.92;\n }\n if (g > 0.0031308) {\n g = 1.055 * Math.pow(g, 0.4166666667) - 0.055;\n } else {\n g *= 12.92;\n }\n if (b > 0.0031308) {\n b = 1.055 * Math.pow(b, 0.4166666667) - 0.055;\n } else {\n b *= 12.92;\n }\n\n return [\n MathUtils.clampInt255(r * 255),\n MathUtils.clampInt255(g * 255),\n MathUtils.clampInt255(b * 255),\n ];\n }\n\n /**\n * Convert a CMYK color to RGB, where **c**, **m**, **y**, **k** values are in the range\n * [0, 255]. Returns a list [r, g, b] with values in the range [0, 255].\n */\n public static cmykToRgb(\n c: number,\n m: number,\n y: number,\n k: number\n ): number[] {\n const _c = c / 255;\n const _m = m / 255;\n const _y = y / 255;\n const _k = k / 255;\n return [\n Math.round(255 * (1 - _c) * (1 - _k)),\n Math.round(255 * (1 - _m) * (1 - _k)),\n Math.round(255 * (1 - _y) * (1 - _k)),\n ];\n }\n\n /**\n * Convert a CIE L\\*a\\*b color to RGB.\n */\n public static labToRgb(l: number, a: number, b: number): number[] {\n const refX = 95.047;\n const refY = 100.0;\n const refZ = 108.883;\n\n let y = (l + 16) / 116;\n let x = a / 500 + y;\n let z = y - b / 200;\n\n const y3 = Math.pow(y, 3);\n if (y3 > 0.008856) {\n y = y3;\n } else {\n y = (y - 16 / 116) / 7.787;\n }\n\n const x3 = Math.pow(x, 3);\n if (x3 > 0.008856) {\n x = x3;\n } else {\n x = (x - 16 / 116) / 7.787;\n }\n\n const z3 = Math.pow(z, 3);\n if (z3 > 0.008856) {\n z = z3;\n } else {\n z = (z - 16 / 116) / 7.787;\n }\n\n x *= refX;\n y *= refY;\n z *= refZ;\n\n x /= 100;\n y /= 100;\n z /= 100;\n\n // xyz to rgb\n let R = x * 3.2406 + y * -1.5372 + z * -0.4986;\n let G = x * -0.9689 + y * 1.8758 + z * 0.0415;\n let B = x * 0.0557 + y * -0.204 + z * 1.057;\n\n if (R > 0.0031308) {\n R = 1.055 * Math.pow(R, 1 / 2.4) - 0.055;\n } else {\n R *= 12.92;\n }\n\n if (G > 0.0031308) {\n G = 1.055 * Math.pow(G, 1 / 2.4) - 0.055;\n } else {\n G *= 12.92;\n }\n\n if (B > 0.0031308) {\n B = 1.055 * Math.pow(B, 1 / 2.4) - 0.055;\n } else {\n B *= 12.92;\n }\n\n return [\n MathUtils.clampInt255(R * 255),\n MathUtils.clampInt255(G * 255),\n MathUtils.clampInt255(B * 255),\n ];\n }\n\n /**\n * Convert a RGB color to XYZ.\n */\n public static rgbToXyz(r: number, g: number, b: number): number[] {\n let _r = r / 255;\n let _g = g / 255;\n let _b = b / 255;\n\n if (_r > 0.04045) {\n _r = Math.pow((_r + 0.055) / 1.055, 2.4);\n } else {\n _r /= 12.92;\n }\n if (_g > 0.04045) {\n _g = Math.pow((_g + 0.055) / 1.055, 2.4);\n } else {\n _g /= 12.92;\n }\n if (_b > 0.04045) {\n _b = Math.pow((_b + 0.055) / 1.055, 2.4);\n } else {\n _b /= 12.92;\n }\n\n _r *= 100;\n _g *= 100;\n _b *= 100;\n\n return [\n _r * 0.4124 + _g * 0.3576 + _b * 0.1805,\n _r * 0.2126 + _g * 0.7152 + _b * 0.0722,\n _r * 0.0193 + _g * 0.1192 + _b * 0.9505,\n ];\n }\n\n /**\n * Convert a XYZ color to CIE L\\*a\\*b.\n */\n public static xyzToLab(x: number, y: number, z: number): number[] {\n let _x = x / 95.047;\n let _y = y / 100;\n let _z = z / 108.883;\n\n if (_x > 0.008856) {\n _x = Math.pow(_x, 1 / 3);\n } else {\n _x = 7.787 * _x + 16 / 116;\n }\n if (_y > 0.008856) {\n _y = Math.pow(_y, 1 / 3);\n } else {\n _y = 7.787 * _y + 16 / 116;\n }\n if (_z > 0.008856) {\n _z = Math.pow(_z, 1 / 3);\n } else {\n _z = 7.787 * _z + 16 / 116;\n }\n\n return [116 * _y - 16, 500 * (_x - _y), 200 * (_y - _z)];\n }\n\n /**\n * Convert a RGB color to CIE L\\*a\\*b.\n */\n public static rgbToLab(r: number, g: number, b: number): number[] {\n let _r = r / 255;\n let _g = g / 255;\n let _b = b / 255;\n\n if (_r > 0.04045) {\n _r = Math.pow((_r + 0.055) / 1.055, 2.4);\n } else {\n _r /= 12.92;\n }\n if (_g > 0.04045) {\n _g = Math.pow((_g + 0.055) / 1.055, 2.4);\n } else {\n _g /= 12.92;\n }\n if (_b > 0.04045) {\n _b = Math.pow((_b + 0.055) / 1.055, 2.4);\n } else {\n _b /= 12.92;\n }\n\n _r *= 100;\n _g *= 100;\n _b *= 100;\n\n let x = _r * 0.4124 + _g * 0.3576 + _b * 0.1805;\n let y = _r * 0.2126 + _g * 0.7152 + _b * 0.0722;\n let z = _r * 0.0193 + _g * 0.1192 + _b * 0.9505;\n\n x /= 95.047;\n y /= 100;\n z /= 108.883;\n\n if (x > 0.008856) {\n x = Math.pow(x, 1 / 3);\n } else {\n x = 7.787 * x + 16 / 116;\n }\n if (y > 0.008856) {\n y = Math.pow(y, 1 / 3);\n } else {\n y = 7.787 * y + 16 / 116;\n }\n if (z > 0.008856) {\n z = Math.pow(z, 1 / 3);\n } else {\n z = 7.787 * z + 16 / 116;\n }\n\n return [116 * y - 16, 500 * (x - y), 200 * (y - z)];\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { Float16 } from '../common/float16';\nimport { Palette } from '../image/palette';\nimport { Channel } from './channel';\nimport { Color, ColorConvertOptions } from './color';\nimport { ColorUtils } from './color-utils';\nimport { Format } from './format';\n\n/**\n * A 16-bit floating point color.\n */\nexport class ColorFloat16 implements Color {\n protected data: Uint16Array;\n\n public get format(): Format {\n return Format.float16;\n }\n\n public get length(): number {\n return this.data.length;\n }\n\n public get maxChannelValue(): number {\n return 1;\n }\n\n public get maxIndexValue(): number {\n return 1;\n }\n\n public get isLdrFormat(): boolean {\n return false;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get hasPalette(): boolean {\n return false;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get r(): number {\n return this.getChannel(0);\n }\n public set r(r: number) {\n this.setChannel(0, r);\n }\n\n public get g(): number {\n return this.getChannel(1);\n }\n public set g(g: number) {\n this.setChannel(1, g);\n }\n\n public get b(): number {\n return this.getChannel(2);\n }\n public set b(b: number) {\n this.setChannel(2, b);\n }\n\n public get a(): number {\n return this.getChannel(3);\n }\n public set a(a: number) {\n this.setChannel(3, a);\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(data: Uint16Array | number) {\n if (typeof data === 'number') {\n this.data = new Uint16Array(data);\n } else {\n this.data = data.slice();\n }\n }\n\n public static from(other: ColorFloat16) {\n const c = new ColorFloat16(other.length);\n c.data = other.data;\n return c;\n }\n\n public static fromArray(color: Uint16Array) {\n const c = new ColorFloat16(color);\n const l = color.length;\n for (let i = 0; i < l; ++i) {\n c.data[i] = Float16.doubleToFloat16(color[i]);\n }\n return c;\n }\n\n public static rgb(r: number, g: number, b: number) {\n const data = new Uint16Array([\n Float16.doubleToFloat16(r),\n Float16.doubleToFloat16(g),\n Float16.doubleToFloat16(b),\n ]);\n return new ColorFloat16(data);\n }\n\n public static rgba(r: number, g: number, b: number, a: number) {\n const data = new Uint16Array([\n Float16.doubleToFloat16(r),\n Float16.doubleToFloat16(g),\n Float16.doubleToFloat16(b),\n Float16.doubleToFloat16(a),\n ]);\n return new ColorFloat16(data);\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.data.length\n ? Float16.float16ToDouble(this.data[channel])\n : 0;\n }\n }\n\n public getChannelNormalized(channel: number | Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(index: number | Channel, value: number): void {\n if (index < this.data.length) {\n this.data[index] = Float16.doubleToFloat16(value);\n }\n }\n\n public set(c: Color): void {\n this.setRgba(c.r, c.g, c.b, c.a);\n }\n\n public setRgb(r: number, g: number, b: number): void {\n this.data[0] = Float16.doubleToFloat16(r);\n const nc = this.data.length;\n if (nc > 1) {\n this.data[1] = Float16.doubleToFloat16(g);\n if (nc > 2) {\n this.data[2] = Float16.doubleToFloat16(b);\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n this.data[0] = Float16.doubleToFloat16(r);\n const nc = this.data.length;\n if (nc > 1) {\n this.data[1] = Float16.doubleToFloat16(g);\n if (nc > 2) {\n this.data[2] = Float16.doubleToFloat16(b);\n if (nc > 3) {\n this.data[3] = Float16.doubleToFloat16(a);\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone() {\n return ColorFloat16.from(this);\n }\n\n public equals(other: Color) {\n if (other.length !== this.length) {\n return false;\n }\n for (let i = 0; i < this.length; i++) {\n if (other.getChannel(i) !== this.getChannel(i)) {\n return false;\n }\n }\n return true;\n }\n\n public convert(opt?: ColorConvertOptions) {\n return ColorUtils.convertColor({\n from: this,\n format: opt?.format,\n numChannels: opt?.numChannels,\n alpha: opt?.alpha,\n });\n }\n}\n", "/** @format */\n\nimport { ColorUint8 } from './color-uint8';\n\nexport class ColorRgb8 extends ColorUint8 {\n constructor(r: number, g: number, b: number) {\n const data = new Uint8Array([r, g, b]);\n super(data);\n }\n\n public static from(other: ColorUint8) {\n const data = new Uint8Array([\n other.getChannel(0),\n other.getChannel(1),\n other.getChannel(2),\n ]);\n return new ColorUint8(data);\n }\n}\n", "/** @format */\n\nimport { ColorUint8 } from './color-uint8';\n\nexport class ColorRgba8 extends ColorUint8 {\n constructor(r: number, g: number, b: number, a: number) {\n const data = new Uint8Array([r, g, b, a]);\n super(data);\n }\n\n public static from(other: ColorUint8) {\n const data = new Uint8Array([\n other.getChannel(0),\n other.getChannel(1),\n other.getChannel(2),\n other.getChannel(3),\n ]);\n return new ColorUint8(data);\n }\n}\n", "/** @format */\n\nimport { Palette } from '../image/palette';\nimport { Channel } from './channel';\nimport { Format } from './format';\n\nexport interface ColorConvertOptions {\n format?: Format;\n numChannels?: number;\n alpha?: number;\n}\n\n/**\n * The abstract Color class is the base class for all specific color classes\n * and Pixel classes.\n */\nexport interface Color {\n /**\n * The number of channels used by the color.\n */\n get length(): number;\n /**\n * The maximum value for a color channel.\n */\n get maxChannelValue(): number;\n /**\n * The maximum value for a palette index.\n */\n get maxIndexValue(): number;\n /**\n * The Format of the color.\n */\n get format(): Format;\n /**\n * True if the format is low dynamic range.\n */\n get isLdrFormat(): boolean;\n /**\n * True if the format is high dynamic range.\n */\n get isHdrFormat(): boolean;\n /**\n * True if the color uses a palette.\n */\n get hasPalette(): boolean;\n /**\n * The palette used by the color, or undefined.\n */\n get palette(): Palette | undefined;\n /**\n * Palette index value (or red channel if there is no palette).\n */\n get index(): number;\n set index(i: number);\n /**\n * Red channel.\n */\n get r(): number;\n set r(r: number);\n /**\n * Green channel.\n */\n get g(): number;\n set g(g: number);\n /**\n * Blue channel.\n */\n get b(): number;\n set b(b: number);\n /**\n * Alpha channel.\n */\n get a(): number;\n set a(a: number);\n /**\n * Normalized [0, 1] red.\n */\n get rNormalized(): number;\n set rNormalized(v: number);\n /**\n * Normalized [0, 1] green.\n */\n get gNormalized(): number;\n set gNormalized(v: number);\n /**\n * Normalized [0, 1] blue.\n */\n get bNormalized(): number;\n set bNormalized(v: number);\n /**\n * Normalized [0, 1] alpha.\n */\n get aNormalized(): number;\n set aNormalized(v: number);\n /**\n * The luminance (grayscale) of the color.\n */\n get luminance(): number;\n get luminanceNormalized(): number;\n /**\n * Gets a channel from the color by its index or Channel enum.\n * If the channel isn't available, 0 will be returned.\n */\n getChannel(channel: number | Channel): number;\n /**\n * Sets a channel to the color by its index.\n */\n setChannel(channel: number | Channel, value: number): void;\n /**\n * Get the normalized [0, 1] value of A channel from the color. If the\n * channel isn't available, 0 will be returned.\n */\n getChannelNormalized(channel: number | Channel): number;\n /**\n * The the values of this color to the given Color.\n */\n set(color: Color): void;\n /**\n * Set the individual **r**, **g**, **b** channels of the color.\n */\n setRgb(r: number, g: number, b: number): void;\n /**\n * Set the individual **r**, **g**, **b**, **a** channels of the color.\n */\n setRgba(r: number, g: number, b: number, a: number): void;\n /**\n * Converts the color to an array of channels.\n */\n toArray(): number[];\n /**\n * Returns a copy of the color.\n */\n clone(): Color;\n /**\n * Convert the **format** and/or the **numChannels** of the color. If\n * **numChannels** is 4 and the current color does not have an alpha value,\n * then **alpha** can specify what value to use for the new alpha channel.\n * If **alpha** is not given, then **maxChannelValue** will be used.\n */\n convert(opt: ColorConvertOptions): Color;\n /**\n * Tests if this color is equivalent to another **Color**.\n */\n equals(other: Color | number[]): boolean;\n}\n", "/** @format */\n\nexport interface Crc32Options {\n buffer: Uint8Array;\n baseCrc?: number;\n position?: number;\n length?: number;\n}\n\nexport abstract class Crc32 {\n private static readonly _crcTable = new Uint32Array(Crc32.makeTable());\n\n private static makeTable() {\n const table: number[] = [];\n let c = 0;\n for (let n = 0; n < 256; n++) {\n c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c;\n }\n return table;\n }\n\n public static getChecksum(opt: Crc32Options) {\n const t = Crc32._crcTable;\n const len = opt.length ?? opt.buffer.length;\n const pos = opt.position ?? 0;\n const end = pos + len;\n\n let result = (opt.baseCrc ?? 0) ^ -1;\n for (let i = pos; i < end; i++) {\n result = (result >>> 8) ^ t[(result ^ opt.buffer[i]) & 0xff];\n }\n\n return (result ^ -1) >>> 0;\n }\n}\n", "/** @format */\n\nimport { LibError } from '../error/lib-error';\n\nexport abstract class StringUtils {\n public static readonly utf8Decoder = new TextDecoder('utf8');\n public static readonly latin1Decoder = new TextDecoder('latin1');\n\n public static getCodePoints(str: string): Uint8Array {\n const array = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n const codePoint = str.codePointAt(i);\n if (codePoint !== undefined) {\n if (0 <= codePoint && codePoint < 256) {\n array[i] = codePoint;\n } else {\n throw new LibError(\n `Error encoding text \"${str}\": unknown character code point ${codePoint}`\n );\n }\n } else {\n throw new LibError(`Error encoding text \"${str}\"`);\n }\n }\n return array;\n }\n}\n", "/** @format */\n\nimport { LibError } from '../error/lib-error';\nimport { BitUtils } from './bit-utils';\nimport { StringUtils } from './string-utils';\n\nexport interface InputBufferInitOptions {\n buffer: Uint8Array;\n offset?: number;\n length?: number;\n bigEndian?: boolean;\n}\n\n/**\n * A buffer that can be read as a stream of bytes.\n */\nexport class InputBuffer {\n private readonly _buffer: Uint8Array;\n public get buffer(): Uint8Array {\n return this._buffer;\n }\n\n private _bigEndian: boolean;\n public set bigEndian(v: boolean) {\n this._bigEndian = v;\n }\n public get bigEndian(): boolean {\n return this._bigEndian;\n }\n\n private _offset: number;\n public set offset(v: number) {\n this._offset = v;\n }\n public get offset(): number {\n return this._offset;\n }\n\n private _start: number;\n public get start(): number {\n return this._start;\n }\n\n private _end: number;\n public get end(): number {\n return this._end;\n }\n\n /**\n * The current read position relative to the start of the buffer.\n */\n public get position(): number {\n return this._offset - this._start;\n }\n\n /**\n * How many bytes are left in the stream.\n */\n public get length(): number {\n return this._end - this._offset;\n }\n\n /**\n * Is the current position at the end of the stream?\n */\n public get isEOS(): boolean {\n return this._offset >= this._end;\n }\n\n /**\n * Create a InputStream for reading from an Array\n */\n constructor(opt: InputBufferInitOptions) {\n this._buffer = opt.buffer;\n this._bigEndian = opt.bigEndian ?? false;\n this._offset = opt.offset ?? 0;\n this._start = this._offset;\n this._end =\n opt.length !== undefined ? this._start + opt.length : this._buffer.length;\n }\n\n /**\n * Create a copy of **other**.\n */\n public static from(other: InputBuffer, offset?: number, length?: number) {\n const offsetFromOther = offset ?? 0;\n const result = new InputBuffer({\n buffer: other._buffer,\n bigEndian: other._bigEndian,\n offset: other._offset + offsetFromOther,\n length: length,\n });\n result._start = other._start;\n result._end =\n length !== undefined\n ? other.offset + offsetFromOther + length\n : other._end;\n return result;\n }\n\n /**\n * Reset to the beginning of the stream.\n */\n public rewind(): void {\n this._offset = this._start;\n }\n\n /**\n * Access the buffer relative from the current position.\n */\n public getByte(index: number): number {\n return this._buffer[this._offset + index];\n }\n\n /**\n * Set a buffer element relative to the current position.\n */\n public setByte(index: number, value: number) {\n return (this._buffer[this._offset + index] = value);\n }\n\n /**\n * Set a range of bytes in this buffer to **value**, at **start** offset from the\n * current read position, and **length** number of bytes.\n */\n public memset(start: number, length: number, value: number): void {\n this._buffer.fill(\n this._offset + start,\n this._offset + start + length,\n value\n );\n }\n\n /**\n * Return an InputBuffer to read a subset of this stream. It does not\n * move the read position of this stream. **position** is specified relative\n * to the start of the buffer. If **position** is not specified, the current\n * read position is used. If **length** is not specified, the remainder of this\n * stream is used.\n */\n public subarray(count: number, position?: number, offset = 0): InputBuffer {\n let pos = position !== undefined ? this._start + position : this._offset;\n pos += offset;\n return new InputBuffer({\n buffer: this._buffer,\n bigEndian: this._bigEndian,\n offset: pos,\n length: count,\n });\n }\n\n /**\n * Returns the position of the given **value** within the buffer, starting\n * from the current read position with the given **offset**. The position\n * returned is relative to the start of the buffer, or -1 if the **value**\n * was not found.\n */\n public indexOf(value: number, offset = 0): number {\n const end = this.offset + this.length;\n for (let i = this.offset + offset; i < end; ++i) {\n if (this._buffer[i] === value) {\n return i - this._start;\n }\n }\n return -1;\n }\n\n /**\n * Read **count** bytes from an **offset** of the current read position, without\n * moving the read position.\n */\n public peekBytes(count: number, offset = 0): InputBuffer {\n return this.subarray(count, undefined, offset);\n }\n\n /**\n * Move the read position by **count** bytes.\n */\n public skip(count: number): void {\n this._offset += count;\n }\n\n /**\n * Read a single byte.\n */\n public readByte(): number {\n return this._buffer[this._offset++];\n }\n\n public readInt8(): number {\n return BitUtils.uint8ToInt8(this.readByte());\n }\n\n /**\n * Read **count** bytes from the stream.\n */\n public readBytes(count: number): InputBuffer {\n const bytes = this.subarray(count);\n this._offset += bytes.length;\n return bytes;\n }\n\n /**\n * Read a null-terminated string, or if **length** is provided, that number of\n * bytes returned as a string.\n */\n public readString(length?: number): string {\n if (length === undefined) {\n const codes: number[] = [];\n while (!this.isEOS) {\n const c = this.readByte();\n if (c === 0) {\n return String.fromCharCode(...codes);\n }\n codes.push(c);\n }\n throw new LibError('EOF reached without finding string terminator.');\n }\n\n const s = this.readBytes(length);\n const bytes = s.toUint8Array();\n const result = String.fromCharCode(...bytes);\n return result;\n }\n\n /**\n * Read a null-terminated UTF-8 string.\n */\n public readStringUtf8(): string {\n const codes: number[] = [];\n while (!this.isEOS) {\n const c = this.readByte();\n if (c === 0) {\n const array = new Uint8Array(codes);\n return StringUtils.utf8Decoder.decode(array);\n }\n codes.push(c);\n }\n const array = new Uint8Array(codes);\n return StringUtils.utf8Decoder.decode(array);\n }\n\n /**\n * Read a 16-bit word from the stream.\n */\n public readUint16(): number {\n const b1 = this._buffer[this._offset++] & 0xff;\n const b2 = this._buffer[this._offset++] & 0xff;\n if (this._bigEndian) {\n return (b1 << 8) | b2;\n }\n return (b2 << 8) | b1;\n }\n\n /**\n * Read a 16-bit word from the stream.\n */\n public readInt16(): number {\n return BitUtils.uint16ToInt16(this.readUint16());\n }\n\n /**\n * Read a 24-bit word from the stream.\n */\n public readUint24(): number {\n const b1 = this._buffer[this._offset++] & 0xff;\n const b2 = this._buffer[this._offset++] & 0xff;\n const b3 = this._buffer[this._offset++] & 0xff;\n if (this._bigEndian) {\n return b3 | (b2 << 8) | (b1 << 16);\n }\n return b1 | (b2 << 8) | (b3 << 16);\n }\n\n /**\n * Read a 32-bit word from the stream.\n */\n public readUint32(): number {\n return BitUtils.int32ToUint32(this.readInt32());\n }\n\n /**\n * Read a signed 32-bit integer from the stream.\n */\n public readInt32(): number {\n const b1 = this._buffer[this._offset++] & 0xff;\n const b2 = this._buffer[this._offset++] & 0xff;\n const b3 = this._buffer[this._offset++] & 0xff;\n const b4 = this._buffer[this._offset++] & 0xff;\n return this._bigEndian\n ? (b1 << 24) | (b2 << 16) | (b3 << 8) | b4\n : (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;\n }\n\n /**\n * Read a 32-bit float.\n */\n public readFloat32(): number {\n return BitUtils.uint32ToFloat32(this.readUint32());\n }\n\n /**\n * Read a 64-bit float.\n */\n public readFloat64(): number {\n return BitUtils.uint64ToFloat64(this.readUint64());\n }\n\n /**\n * Read a 64-bit word form the stream.\n */\n public readUint64(): bigint {\n const b1 = this._buffer[this._offset++] & 0xff;\n const b2 = this._buffer[this._offset++] & 0xff;\n const b3 = this._buffer[this._offset++] & 0xff;\n const b4 = this._buffer[this._offset++] & 0xff;\n const b5 = this._buffer[this._offset++] & 0xff;\n const b6 = this._buffer[this._offset++] & 0xff;\n const b7 = this._buffer[this._offset++] & 0xff;\n const b8 = this._buffer[this._offset++] & 0xff;\n if (this._bigEndian) {\n return (\n BigInt(b1 << 56) |\n BigInt(b2 << 48) |\n BigInt(b3 << 40) |\n BigInt(b4 << 32) |\n BigInt(b5 << 24) |\n BigInt(b6 << 16) |\n BigInt(b7 << 8) |\n BigInt(b8)\n );\n }\n return (\n BigInt(b8 << 56) |\n BigInt(b7 << 48) |\n BigInt(b6 << 40) |\n BigInt(b5 << 32) |\n BigInt(b4 << 24) |\n BigInt(b3 << 16) |\n BigInt(b2 << 8) |\n BigInt(b1)\n );\n }\n\n public toUint8Array(offset?: number, length?: number): Uint8Array {\n const correctedOffset = offset ?? 0;\n const correctedLength = length ?? this.length - correctedOffset;\n return new Uint8Array(\n this._buffer.buffer,\n this._buffer.byteOffset + this._offset + correctedOffset,\n correctedLength\n );\n }\n\n public toUint32Array(offset?: number): Uint32Array {\n const correctedOffset = offset ?? 0;\n return new Uint32Array(\n this._buffer.buffer,\n this._buffer.byteOffset + this._offset + correctedOffset\n );\n }\n}\n", "/** @format */\n\n/**\n * Interpolation method to use when resizing images.\n */\nexport enum Interpolation {\n /**\n * Select the closest pixel.Fastest, lowest quality.\n */\n nearest,\n\n /**\n * Linearly blend between the neighboring pixels.\n */\n linear,\n\n /**\n * Cubic blend between the neighboring pixels. Slowest, highest Quality.\n */\n cubic,\n\n /**\n * Average the colors of the neighboring pixels.\n */\n average,\n}\n", "/** @format */\n\nimport { Point } from './point';\n\nexport class Line {\n private _x1: number;\n private _y1: number;\n private _x2: number;\n private _y2: number;\n\n public get x1(): number {\n return this._x1;\n }\n\n public get y1(): number {\n return this._y1;\n }\n\n public get x2(): number {\n return this._x2;\n }\n\n public get y2(): number {\n return this._y2;\n }\n\n public get dx(): number {\n return this._x2 - this._x1;\n }\n\n public get dy(): number {\n return this._y2 - this._y1;\n }\n\n constructor(x1: number, y1: number, x2: number, y2: number) {\n this._x1 = x1;\n this._y1 = y1;\n this._x2 = x2;\n this._y2 = y2;\n }\n\n public static from(other: Line) {\n return new Line(other.x1, other.y1, other.x2, other.y2);\n }\n\n public movePoint1(x: number, y: number) {\n this._x1 = x;\n this._y1 = y;\n }\n\n public movePoint2(x: number, y: number) {\n this._x2 = x;\n this._y2 = y;\n }\n\n public swapXY1() {\n const tmp = this._x1;\n this._x1 = this._y1;\n this._y1 = tmp;\n }\n\n public swapXY2() {\n const tmp = this._x2;\n this._x2 = this._y2;\n this._y2 = tmp;\n }\n\n public flipX() {\n const tmp = this._x1;\n this._x1 = this._x2;\n this._x2 = tmp;\n }\n\n public flipY() {\n const tmp = this._y1;\n this._y1 = this._y2;\n this._y2 = tmp;\n }\n\n public clone(): Line {\n return new Line(this._x1, this._y1, this._x2, this._y2);\n }\n\n public toString(): string {\n return `${this.constructor.name} (x1: ${this._x1}, y1: ${this._y1}, x2: ${this._x2}, y2: ${this._y2})`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from './input-buffer';\nimport { ArrayUtils } from './array-utils';\n\nexport interface OutputBufferInitOptions {\n bigEndian?: boolean;\n size?: number;\n}\n\nexport class OutputBuffer {\n // 8k block-size\n private static readonly _blockSize = 0x2000;\n\n private _buffer: Uint8Array;\n public get buffer(): Uint8Array {\n return this._buffer;\n }\n\n private _bigEndian: boolean;\n public get bigEndian(): boolean {\n return this._bigEndian;\n }\n public set bigEndian(v: boolean) {\n this._bigEndian = v;\n }\n\n private _length: number;\n public get length(): number {\n return this._length;\n }\n public set length(v: number) {\n this._length = v;\n }\n\n /**\n * Create a byte buffer for writing.\n */\n constructor(opt?: OutputBufferInitOptions) {\n this._bigEndian = opt?.bigEndian ?? false;\n this._buffer = new Uint8Array(opt?.size ?? OutputBuffer._blockSize);\n this._length = 0;\n }\n\n /**\n * Grow the buffer to accommodate additional data.\n */\n private expandBuffer(required?: number): void {\n let blockSize: number = OutputBuffer._blockSize;\n if (required !== undefined) {\n blockSize = required;\n } else if (this._buffer.length > 0) {\n blockSize = this._buffer.length * 2;\n }\n const newBuffer = new Uint8Array(this._buffer.length + blockSize);\n ArrayUtils.copyRange(this._buffer, 0, this._buffer.length, newBuffer, 0);\n this._buffer = newBuffer;\n }\n\n public rewind(): void {\n this._length = 0;\n }\n\n /**\n * Clear the buffer.\n */\n public clear(): void {\n this._buffer = new Uint8Array(OutputBuffer._blockSize);\n this._length = 0;\n }\n\n /**\n * Get the resulting bytes from the buffer.\n */\n public getBytes(): Uint8Array {\n return new Uint8Array(this._buffer.buffer, 0, this._length);\n }\n\n /**\n * Write a byte to the end of the buffer.\n */\n public writeByte(value: number): void {\n if (this._length === this._buffer.length) {\n this.expandBuffer();\n }\n this._buffer[this._length++] = value & 0xff;\n }\n\n /**\n * Write a set of bytes to the end of the buffer.\n */\n public writeBytes(bytes: Uint8Array, length?: number): void {\n const bytesLength = length ?? bytes.length;\n while (this._length + bytesLength > this._buffer.length) {\n this.expandBuffer(this._length + bytesLength - this._buffer.length);\n }\n ArrayUtils.copyRange(bytes, 0, bytesLength, this._buffer, this._length);\n this._length += bytesLength;\n }\n\n public writeBuffer(bytes: InputBuffer): void {\n const bytesLength = bytes.length;\n const requiredLength = this._length + bytesLength;\n while (requiredLength > this._buffer.length) {\n this.expandBuffer(requiredLength - this._buffer.length);\n }\n ArrayUtils.copyRange(\n bytes.buffer,\n bytes.offset,\n bytesLength,\n this._buffer,\n this._length\n );\n this._length += bytesLength;\n }\n\n /**\n * Write a 16-bit word to the end of the buffer.\n */\n public writeUint16(value: number): void {\n if (this._bigEndian) {\n this.writeByte((value >> 8) & 0xff);\n this.writeByte(value & 0xff);\n return;\n }\n this.writeByte(value & 0xff);\n this.writeByte((value >> 8) & 0xff);\n }\n\n /**\n * Write a 32-bit word to the end of the buffer.\n */\n public writeUint32(value: number): void {\n if (this._bigEndian) {\n this.writeByte((value >> 24) & 0xff);\n this.writeByte((value >> 16) & 0xff);\n this.writeByte((value >> 8) & 0xff);\n this.writeByte(value & 0xff);\n return;\n }\n this.writeByte(value & 0xff);\n this.writeByte((value >> 8) & 0xff);\n this.writeByte((value >> 16) & 0xff);\n this.writeByte((value >> 24) & 0xff);\n }\n\n /**\n * Write a 32-bit float value to the end of the buffer.\n */\n public writeFloat32(value: number): void {\n const fb = new Float32Array(1);\n fb[0] = value;\n const b = new Uint8Array(fb.buffer);\n if (this._bigEndian) {\n this.writeByte(b[3]);\n this.writeByte(b[2]);\n this.writeByte(b[1]);\n this.writeByte(b[0]);\n return;\n }\n this.writeByte(b[0]);\n this.writeByte(b[1]);\n this.writeByte(b[2]);\n this.writeByte(b[3]);\n }\n\n /**\n * Write a 64-bit float value to the end of the buffer.\n */\n public writeFloat64(value: number): void {\n const fb = new Float64Array(1);\n fb[0] = value;\n const b = new Uint8Array(fb.buffer);\n if (this._bigEndian) {\n this.writeByte(b[7]);\n this.writeByte(b[6]);\n this.writeByte(b[5]);\n this.writeByte(b[4]);\n this.writeByte(b[3]);\n this.writeByte(b[2]);\n this.writeByte(b[1]);\n this.writeByte(b[0]);\n return;\n }\n this.writeByte(b[0]);\n this.writeByte(b[1]);\n this.writeByte(b[2]);\n this.writeByte(b[3]);\n this.writeByte(b[4]);\n this.writeByte(b[5]);\n this.writeByte(b[6]);\n this.writeByte(b[7]);\n }\n\n /**\n * Return the subarray of the buffer in the range [**start**,**end**].\n * If **start** or **end** are < 0 then it is relative to the end of the buffer.\n * If **end** is not specified (or undefined), then it is the end of the buffer.\n * This is equivalent to the python list range operator.\n */\n public subarray(start: number, end?: number): Uint8Array {\n const correctedStart: number = start >= 0 ? start : this._length + start;\n let correctedEnd: number = end ?? this._length;\n if (correctedEnd < 0) {\n correctedEnd = this._length + correctedEnd;\n }\n return new Uint8Array(\n this._buffer.buffer,\n correctedStart,\n correctedEnd - correctedStart\n );\n }\n}\n", "/**\n * 2-dimensional point\n *\n * @format\n */\n\nexport class Point {\n private _x: number;\n private _y: number;\n\n public get x(): number {\n return this._x;\n }\n\n public get y(): number {\n return this._y;\n }\n\n public get xt() {\n return Math.trunc(this.x);\n }\n\n public get yt() {\n return Math.trunc(this.y);\n }\n\n constructor(x: number, y: number) {\n this._x = x;\n this._y = y;\n }\n\n public static from(other: Point): Point {\n return new Point(other._x, other._y);\n }\n\n public move(x: number, y: number): Point {\n return new Point(x, y);\n }\n\n public offset(dx: number, dy: number): Point {\n return this.move(this._x + dx, this._y + dy);\n }\n\n public mul(n: number): Point {\n return this.move(this._x * n, this._y * n);\n }\n\n public add(p: Point): Point {\n return this.move(this._x + p._x, this._y + p._y);\n }\n\n public equals(other: Point) {\n return this._x === other._x && this._y === other._y;\n }\n\n public toString(): string {\n return `${this.constructor.name} (x: ${this._x}, y: ${this._y})`;\n }\n}\n", "/** @format */\n\nexport abstract class RandomUtils {\n /**\n * Return a random number between [-1, 1].\n */\n public static crand(): number {\n return 1 - 2 * Math.random();\n }\n\n /**\n * Return a random number following a gaussian distribution and a standard\n * deviation of 1.\n */\n public static grand(): number {\n let x1 = 0;\n let w = 0;\n do {\n const x2 = 2 * Math.random() - 1;\n x1 = 2 * Math.random() - 1;\n w = x1 * x1 + x2 * x2;\n } while (w <= 0 || w >= 1);\n\n return x1 * Math.sqrt((-2 * Math.log(w)) / w);\n }\n\n /**\n * Return a random variable following a Poisson distribution of parameter **z**.\n */\n public static prand(z: number): number {\n if (z <= 1e-10) {\n return 0;\n }\n if (z > 100) {\n return Math.trunc(Math.sqrt(z) * RandomUtils.grand() + z);\n }\n let k = 0;\n const y = Math.exp(-z);\n for (let s = 1.0; s >= y; ++k) {\n s *= Math.random();\n }\n return k - 1;\n }\n\n /**\n * Generates a non-negative random integer in the range from 0, inclusive, to **max**, exclusive.\n */\n public static intrand(max: number) {\n return Math.floor(Math.random() * max);\n }\n}\n", "/** @format */\n\nimport { Point } from './point';\n\nexport class Rectangle {\n private readonly _left;\n private readonly _top;\n private readonly _right;\n private readonly _bottom;\n\n public get left(): number {\n return this._left;\n }\n\n public get top(): number {\n return this._top;\n }\n\n public get right(): number {\n return this._right;\n }\n\n public get bottom(): number {\n return this._bottom;\n }\n\n public get width(): number {\n return this._right - this._left;\n }\n\n public get height(): number {\n return this._bottom - this._top;\n }\n\n public get topLeft(): Point {\n return new Point(this._left, this._top);\n }\n\n public get topRight(): Point {\n return new Point(this._right, this._top);\n }\n\n public get bottomLeft(): Point {\n return new Point(this._left, this._bottom);\n }\n\n public get bottomRight(): Point {\n return new Point(this._right, this._bottom);\n }\n\n constructor(x1: number, y1: number, x2: number, y2: number) {\n this._left = Math.min(x1, x2);\n this._top = Math.min(y1, y2);\n this._right = Math.max(x1, x2);\n this._bottom = Math.max(y1, y2);\n }\n\n public static fromXYWH(x: number, y: number, width: number, height: number) {\n return new Rectangle(x, y, x + width, y + height);\n }\n\n public static from(other: Rectangle) {\n return new Rectangle(other._left, other._top, other._right, other._bottom);\n }\n\n public toString(): string {\n return `${this.constructor.name} (l: ${this._left}, t: ${this._top}, r: ${this._right}, b: ${this._bottom}, w: ${this.width}, h: ${this.height})`;\n }\n}\n", "/** @format */\n\nexport type TypedArray =\n | Int8Array\n | Int16Array\n | Int32Array\n | Uint8Array\n | Uint16Array\n | Uint32Array\n | Float32Array\n | Float64Array;\n\nexport type BufferEncoding =\n | 'ascii'\n | 'utf8'\n | 'utf-8'\n | 'utf16le'\n | 'ucs2'\n | 'ucs-2'\n | 'base64'\n | 'latin1'\n | 'binary'\n | 'hex';\n\nexport type CompressionLevel =\n | -1\n | 0\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | undefined;\n", "/** @format */\n\nexport enum BlendMode {\n direct,\n alpha,\n lighten,\n screen,\n dodge,\n addition,\n darken,\n multiply,\n burn,\n overlay,\n softLight,\n hardLight,\n difference,\n subtract,\n divide,\n}\n", "/** @format */\n\nexport enum CircleQuadrant {\n topLeft = 1,\n topRight = 2,\n bottomLeft = 4,\n bottomRight = 8,\n all = topLeft | topRight | bottomLeft | bottomRight,\n}\n", "/** @format */\n\nimport { Line } from '../common/line';\nimport { Point } from '../common/point';\nimport { Rectangle } from '../common/rectangle';\nimport { Pixel } from './pixel';\n\nexport abstract class ImageUtils {\n /**\n * Test if the pixel **p** is within the circle centered at **center** with a\n * squared radius of **rad2**. This will test the corners, edges, and center\n * of the pixel and return the ratio of samples within the circle.\n */\n public static circleTest(\n p: Pixel,\n center: Point,\n rad2: number,\n antialias = true\n ): number {\n let total = 0;\n const dx1 = p.x - center.x;\n const dy1 = p.y - center.y;\n const d1 = dx1 * dx1 + dy1 * dy1;\n const r1 = d1 <= rad2 ? 1 : 0;\n total += r1;\n\n const dx2 = p.x + 1 - center.x;\n const dy2 = p.y - center.y;\n const d2 = dx2 * dx2 + dy2 * dy2;\n const r2 = d2 <= rad2 ? 1 : 0;\n total += r2;\n\n const dx3 = p.x + 1 - center.x;\n const dy3 = p.y + 1 - center.y;\n const d3 = dx3 * dx3 + dy3 * dy3;\n const r3 = d3 <= rad2 ? 1 : 0;\n total += r3;\n\n const dx4 = p.x - center.x;\n const dy4 = p.y + 1 - center.y;\n const d4 = dx4 * dx4 + dy4 * dy4;\n const r4 = d4 <= rad2 ? 1 : 0;\n total += r4;\n\n const dx5 = p.x + 0.5 - center.x;\n const dy5 = p.y - center.y;\n const d5 = dx5 * dx5 + dy5 * dy5;\n const r5 = d5 <= rad2 ? 1 : 0;\n total += r5;\n\n const dx6 = p.x + 0.5 - center.x;\n const dy6 = p.y + 1 - center.y;\n const d6 = dx6 * dx6 + dy6 * dy6;\n const r6 = d6 <= rad2 ? 1 : 0;\n total += r6;\n\n const dx7 = p.x - center.x;\n const dy7 = p.y + 0.5 - center.y;\n const d7 = dx7 * dx7 + dy7 * dy7;\n const r7 = d7 <= rad2 ? 1 : 0;\n total += r7;\n\n const dx8 = p.x + 1 - center.x;\n const dy8 = p.y + 0.5 - center.y;\n const d8 = dx8 * dx8 + dy8 * dy8;\n const r8 = d8 <= rad2 ? 1 : 0;\n total += r8;\n\n const dx9 = p.x + 0.5 - center.x;\n const dy9 = p.y + 0.5 - center.y;\n const d9 = dx9 * dx9 + dy9 * dy9;\n const r9 = d9 <= rad2 ? 1 : 0;\n total += r9;\n\n return antialias ? total / 9 : total > 0 ? 1 : 0;\n }\n\n /**\n * Clip a line to a rectangle using the Cohen\u2013Sutherland clipping algorithm.\n * **line** is a Line object.\n * **rect** is a Rectangle object.\n * Results are stored in **line**.\n * If **line** falls completely outside of **rect**, false is returned, otherwise\n * true is returned.\n */\n public static clipLine(rect: Rectangle, line: Line): boolean {\n const xmin = rect.left;\n const ymin = rect.top;\n const xmax = rect.right;\n const ymax = rect.bottom;\n\n // 0000\n const inside = 0;\n // 0001\n const left = 1;\n // 0010\n const right = 2;\n // 0100\n const bottom = 4;\n // 1000\n const top = 8;\n\n const computeOutCode = (p: Point): number => {\n // initialized as being inside of clip window\n let code = inside;\n if (p.x < xmin) {\n // to the left of clip window\n code |= left;\n } else if (p.x > xmax) {\n // to the right of clip window\n code |= right;\n }\n\n if (p.y < ymin) {\n // below the clip window\n code |= bottom;\n } else if (p.y > ymax) {\n // above the clip window\n code |= top;\n }\n\n return code;\n };\n\n // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle\n let outcode1 = computeOutCode(new Point(line.x1, line.y1));\n let outcode2 = computeOutCode(new Point(line.x2, line.y2));\n let accept = false;\n\n while (true) {\n if ((outcode1 | outcode2) === 0) {\n // Bitwise OR is 0. Trivially accept and get out of loop\n accept = true;\n break;\n } else if ((outcode1 & outcode2) !== 0) {\n // Bitwise AND is not 0. Trivially reject and get out of loop\n break;\n } else {\n // failed both tests, so calculate the line segment to clip\n // from an outside point to an intersection with clip edge\n\n // At least one endpoint is outside the clip rectangle; pick it.\n const outcodeOut = outcode1 !== 0 ? outcode1 : outcode2;\n\n let x = 0;\n let y = 0;\n\n // Now find the intersection point;\n // use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)\n if ((outcodeOut & top) !== 0) {\n // point is above the clip rectangle\n x = line.x1 + Math.trunc((line.dx * (ymax - line.y1)) / line.dy);\n y = ymax;\n } else if ((outcodeOut & bottom) !== 0) {\n // point is below the clip rectangle\n x = line.x1 + Math.trunc((line.dx * (ymin - line.y1)) / line.dy);\n y = ymin;\n } else if ((outcodeOut & right) !== 0) {\n // point is to the right of clip rectangle\n y = line.y1 + Math.trunc((line.dy * (xmax - line.x1)) / line.dx);\n x = xmax;\n } else if ((outcodeOut & left) !== 0) {\n // point is to the left of clip rectangle\n y = line.y1 + Math.trunc((line.dy * (xmin - line.x1)) / line.dx);\n x = xmin;\n }\n\n // Now we move outside point to intersection point to clip\n // and get ready for next pass.\n if (outcodeOut === outcode1) {\n line.movePoint1(x, y);\n outcode1 = computeOutCode(new Point(line.x1, line.y1));\n } else {\n line.movePoint2(x, y);\n outcode2 = computeOutCode(new Point(line.x2, line.y2));\n }\n }\n }\n\n return accept;\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color } from '../color/color';\nimport { ColorUtils } from '../color/color-utils';\nimport { ArrayUtils } from '../common/array-utils';\nimport { Line } from '../common/line';\nimport { MathUtils } from '../common/math-utils';\nimport { Point } from '../common/point';\nimport { Rectangle } from '../common/rectangle';\nimport { MemoryImage } from '../image/image';\nimport { ImageUtils } from '../image/image-utils';\nimport { Pixel } from '../image/pixel';\nimport { BlendMode } from './blend-mode';\nimport { CircleQuadrant } from './circle-quadrant';\n\ntype FillFloodTestPixel = (y: number, x: number) => boolean;\ntype FillFloodMarkPixel = (y: number, x: number) => void;\n\ninterface DrawLineWuOptions {\n image: MemoryImage;\n line: Line;\n color: Color;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface DrawLineOptions extends DrawLineWuOptions {\n antialias?: boolean;\n thickness?: number;\n}\n\ninterface DrawAntialiasCircleOptions {\n image: MemoryImage;\n x: number;\n y: number;\n radius: number;\n color: Color;\n quadrants?: CircleQuadrant;\n mask?: MemoryImage;\n maskChannel?: Channel;\n}\n\nexport interface DrawCircleOptions {\n image: MemoryImage;\n center: Point;\n radius: number;\n color: Color;\n antialias?: boolean;\n mask?: MemoryImage;\n maskChannel?: Channel;\n}\n\nexport interface DrawPixelOptions {\n image: MemoryImage;\n pos: Point;\n color: Color;\n filter?: Color;\n alpha?: number;\n blend?: BlendMode;\n linearBlend?: boolean;\n mask?: MemoryImage;\n maskChannel?: Channel;\n}\n\nexport interface DrawPolygonOptions {\n image: MemoryImage;\n vertices: Point[];\n color: Color;\n antialias?: boolean;\n thickness?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface DrawRectOptions {\n image: MemoryImage;\n rect: Rectangle;\n color: Color;\n thickness?: number;\n radius?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface FillCircleOptions {\n image: MemoryImage;\n center: Point;\n radius: number;\n color: Color;\n antialias?: boolean;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface FillFloodOptions {\n image: MemoryImage;\n start: Point;\n color: Color;\n threshold?: number;\n compareAlpha?: boolean;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface MaskFloodOptions {\n image: MemoryImage;\n start: Point;\n threshold?: number;\n compareAlpha?: boolean;\n fillValue?: number;\n}\n\nexport interface FillPolygonOptions {\n image: MemoryImage;\n vertices: Point[];\n color: Color;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface FillRectOptions {\n image: MemoryImage;\n rect: Rectangle;\n color: Color;\n radius?: number;\n mask?: MemoryImage;\n maskChannel?: Channel;\n}\n\nexport interface FillOptions {\n image: MemoryImage;\n color: Color;\n maskChannel?: Channel.luminance;\n mask?: MemoryImage;\n}\n\nexport interface CompositeImageOptions {\n dst: MemoryImage;\n src: MemoryImage;\n dstX?: number;\n dstY?: number;\n dstW?: number;\n dstH?: number;\n srcX?: number;\n srcY?: number;\n srcW?: number;\n srcH?: number;\n blend?: BlendMode;\n linearBlend?: boolean;\n center?: boolean;\n mask?: MemoryImage;\n maskChannel?: Channel;\n}\n\nexport abstract class Draw {\n /**\n * Calculate the pixels that make up the circumference of a circle on the\n * given **image**, centered at **center** and the given **radius**.\n *\n * The returned array of points is sorted, first by the **center.x** coordinate, and\n * second by the **center.y** coordinate.\n */\n private static calculateCircumference(\n image: MemoryImage,\n center: Point,\n radius: number\n ): Point[] {\n if (\n radius < 0 ||\n center.x + radius < 0 ||\n center.x - radius >= image.width ||\n center.y + radius < 0 ||\n center.y - radius >= image.height\n ) {\n return [];\n }\n\n if (radius === 0) {\n return [center];\n }\n\n const points: Point[] = [\n new Point(center.x - radius, center.y),\n new Point(center.x + radius, center.y),\n new Point(center.x, center.y - radius),\n new Point(center.x, center.y + radius),\n ];\n\n if (radius === 1) {\n return points;\n }\n\n for (\n let f = 1 - radius, ddFx = 0, ddFy = -(radius << 1), x = 0, y = radius;\n x < y;\n\n ) {\n if (f >= 0) {\n ddFy += 2;\n f += ddFy;\n --y;\n }\n ++x;\n ddFx += 2;\n f += ddFx + 1;\n\n if (x !== y + 1) {\n const x1 = center.x - y;\n const x2 = center.x + y;\n const y1 = center.y - x;\n const y2 = center.y + x;\n const x3 = center.x - x;\n const x4 = center.x + x;\n const y3 = center.y - y;\n const y4 = center.y + y;\n\n points.push(new Point(x1, y1));\n points.push(new Point(x1, y2));\n points.push(new Point(x2, y1));\n points.push(new Point(x2, y2));\n\n if (x !== y) {\n points.push(new Point(x3, y3));\n points.push(new Point(x4, y4));\n points.push(new Point(x4, y3));\n points.push(new Point(x3, y4));\n }\n }\n }\n\n return points;\n }\n\n private static drawAntialiasCircle(\n opt: DrawAntialiasCircleOptions\n ): MemoryImage {\n const drawPixel4 = (\n x: number,\n y: number,\n dx: number,\n dy: number,\n alpha: number\n ): void => {\n // bottom right\n if ((quadrants & CircleQuadrant.bottomRight) !== 0) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x + dx, y + dy),\n color: opt.color,\n alpha: alpha,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n\n // bottom left\n if ((quadrants & CircleQuadrant.bottomLeft) !== 0) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x - dx, y + dy),\n color: opt.color,\n alpha: alpha,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n\n // upper right\n if ((quadrants & CircleQuadrant.topRight) !== 0) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x + dx, y - dy),\n color: opt.color,\n alpha: alpha,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n\n // upper left\n if ((quadrants & CircleQuadrant.topLeft) !== 0) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x - dx, y - dy),\n color: opt.color,\n alpha: alpha,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n };\n\n const quadrants = opt.quadrants ?? CircleQuadrant.all;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n const radiusSqr = opt.radius * opt.radius;\n const quarter = Math.round(opt.radius / Math.SQRT2);\n for (let i = 0; i <= quarter; ++i) {\n const j = Math.sqrt(radiusSqr - i * i);\n const frc = MathUtils.fract(j);\n const frc2 = frc * (i === quarter ? 0.25 : 1);\n const flr = Math.floor(j);\n drawPixel4(opt.x, opt.y, i, flr, 1 - frc);\n drawPixel4(opt.x, opt.y, i, flr + 1, frc2);\n drawPixel4(opt.x, opt.y, flr, i, 1 - frc);\n drawPixel4(opt.x, opt.y, flr + 1, i, frc2);\n }\n\n return opt.image;\n }\n\n // Xiaolin Wu's line algorithm,\n // https://en.wikipedia.org/wiki/Xiaolin_Wu's_line_algorithm\n private static drawLineWu(opt: DrawLineWuOptions): MemoryImage {\n const line = opt.line.clone();\n const steep = Math.abs(line.dy) > Math.abs(line.dx);\n\n if (steep) {\n line.swapXY1();\n line.swapXY2();\n }\n if (line.x1 > line.x2) {\n line.flipX();\n line.flipY();\n }\n\n const gradient = line.dx === 1 ? 1 : line.dy / line.dx;\n\n // handle first endpoint\n let xend = Math.floor(line.x1 + 0.5);\n let yend = line.y1 + gradient * (xend - line.x1);\n let xgap = 1 - (line.x1 + 0.5 - Math.floor(line.x1 + 0.5));\n // this will be used in the main loop\n const xpxl1 = xend;\n const ypxl1 = Math.floor(yend);\n\n if (steep) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(ypxl1, xpxl1),\n color: opt.color,\n alpha: (1 - (yend - Math.floor(yend))) * xgap,\n maskChannel: opt.maskChannel,\n mask: opt.mask,\n });\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(ypxl1 + 1, xpxl1),\n color: opt.color,\n alpha: (yend - Math.floor(yend)) * xgap,\n maskChannel: opt.maskChannel,\n mask: opt.mask,\n });\n } else {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(xpxl1, ypxl1),\n color: opt.color,\n alpha: (1 - (yend - Math.floor(yend))) * xgap,\n maskChannel: opt.maskChannel,\n mask: opt.mask,\n });\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(xpxl1, ypxl1 + 1),\n color: opt.color,\n alpha: (yend - Math.floor(yend)) * xgap,\n maskChannel: opt.maskChannel,\n mask: opt.mask,\n });\n }\n\n // first y-intersection for the main loop\n let intery = yend + gradient;\n\n // handle second endpoint\n xend = Math.floor(line.x2 + 0.5);\n yend = line.y2 + gradient * (xend - line.x2);\n xgap = line.x2 + 0.5 - Math.floor(line.x2 + 0.5);\n\n // this will be used in the main loop\n const xpxl2 = xend;\n const ypxl2 = Math.floor(yend);\n\n if (steep) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(ypxl2, xpxl2),\n color: opt.color,\n alpha: (1 - (yend - Math.floor(yend))) * xgap,\n mask: opt.mask,\n maskChannel: opt.maskChannel,\n });\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(ypxl2 + 1, xpxl2),\n color: opt.color,\n alpha: (yend - Math.floor(yend)) * xgap,\n maskChannel: opt.maskChannel,\n mask: opt.mask,\n });\n\n // main loop\n for (let x = xpxl1 + 1; x <= xpxl2 - 1; x++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(Math.floor(intery), x),\n color: opt.color,\n alpha: 1 - (intery - Math.floor(intery)),\n mask: opt.mask,\n maskChannel: opt.maskChannel,\n });\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(Math.floor(intery) + 1, x),\n color: opt.color,\n alpha: intery - Math.floor(intery),\n maskChannel: opt.maskChannel,\n mask: opt.mask,\n });\n\n intery += gradient;\n }\n } else {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(xpxl2, ypxl2),\n color: opt.color,\n alpha: (1 - (yend - Math.floor(yend))) * xgap,\n maskChannel: opt.maskChannel,\n mask: opt.mask,\n });\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(xpxl2, ypxl2 + 1),\n color: opt.color,\n alpha: (yend - Math.floor(yend)) * xgap,\n maskChannel: opt.maskChannel,\n mask: opt.mask,\n });\n\n // main loop\n for (let x = xpxl1 + 1; x <= xpxl2 - 1; x++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x, Math.floor(intery)),\n color: opt.color,\n alpha: 1 - (intery - Math.floor(intery)),\n maskChannel: opt.maskChannel,\n mask: opt.mask,\n });\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x, Math.floor(intery) + 1),\n color: opt.color,\n alpha: intery - Math.floor(intery),\n maskChannel: opt.maskChannel,\n mask: opt.mask,\n });\n\n intery += gradient;\n }\n }\n\n return opt.image;\n }\n\n private static setAlpha(c: Color, a: number): Color {\n c.a = a;\n return c;\n }\n\n /**\n * Compare colors from a 3 or 4 dimensional color space\n */\n private static colorDistance(\n c1: number[],\n c2: number[],\n compareAlpha: boolean\n ): number {\n const d1 = c1[0] - c2[0];\n const d2 = c1[1] - c2[1];\n const d3 = c1[2] - c2[2];\n if (compareAlpha) {\n const dA = c1[3] - c2[3];\n return Math.sqrt(\n Math.max(d1 * d1, (d1 - dA) * (d1 - dA)) +\n Math.max(d2 * d2, (d2 - dA) * (d2 - dA)) +\n Math.max(d3 * d3, (d3 - dA) * (d3 - dA))\n );\n } else {\n return Math.sqrt(d1 * d1 + d2 * d2 + d3 * d3);\n }\n }\n\n private static testPixelLabColorDistance(\n src: MemoryImage,\n x: number,\n y: number,\n refColor: number[],\n threshold: number\n ): boolean {\n const pixel = src.getPixel(x, y);\n const compareAlpha = refColor.length > 3;\n const pixelColor = ColorUtils.rgbToLab(pixel.r, pixel.g, pixel.b);\n if (compareAlpha) {\n pixelColor.push(pixel.a);\n }\n return Draw.colorDistance(pixelColor, refColor, compareAlpha) > threshold;\n }\n\n private static fill4Core(\n src: MemoryImage,\n x: number,\n y: number,\n array: FillFloodTestPixel,\n mark: FillFloodMarkPixel,\n visited: Uint8Array\n ): void {\n let _x = x;\n let _y = y;\n\n if (visited[_y * src.width + _x] === 1) {\n return;\n }\n // at this point, we know that array(y,x) is clear, and array(y-1,x) and\n // array(y,x-1) are set. We'll begin scanning down and to the right,\n // attempting to fill an entire rectangular block\n\n // the number of cells that were clear in the last row we scanned\n let lastRowLength = 0;\n\n do {\n let rowLength = 0;\n let sx = _x;\n // keep track of how long this row is. sx is the starting x for the main\n // scan below now we want to handle a case like |***|, where we fill 3\n // cells in the first row and then after we move to the second row we find\n // the first | **| cell is filled, ending our rectangular scan. rather\n // than handling this via the recursion below, we'll increase the starting\n // value of 'x' and reduce the last row length to match. then we'll continue\n // trying to set the narrower rectangular block\n if (lastRowLength !== 0 && array(_y, _x)) {\n // if this is not the first row and the leftmost cell is filled...\n do {\n if (--lastRowLength === 0) {\n // shorten the row. if it's full, we're done\n return;\n }\n // otherwise, update the starting point of the main scan to match\n } while (array(_y, ++_x));\n sx = _x;\n } else {\n // we also want to handle the opposite case, | **|, where we begin\n // scanning a 2-wide rectangular block and then find on the next row that\n // it has |***| gotten wider on the left. again, we could handle this\n // with recursion but we'd prefer to adjust x and lastRowLength instead\n for (; _x !== 0 && !array(_y, _x - 1); rowLength++, lastRowLength++) {\n mark(_y, --_x);\n // to avoid scanning the cells twice, we'll fill them and update\n // rowLength here if there's something above the new starting point,\n // handle that recursively. this deals with cases like |* **| when we\n // begin filling from (2,0), move down to (2,1), and then move left to\n // (0,1). The |****| main scan assumes the portion of the previous row\n // from x to x+lastRowLength has already been filled. adjusting x and\n // lastRowLength breaks that assumption in this case, so we must fix it\n if (_y !== 0 && !array(_y - 1, _x)) {\n // use _Fill since there may be more up and left\n Draw.fill4(src, _x, _y - 1, array, mark, visited);\n }\n }\n }\n\n // now at this point we can begin to scan the current row in the rectangular\n // block. the span of the previous row from x (inclusive) to x+lastRowLength\n // (exclusive) has already been filled, so we don't need to\n // check it. so scan across to the right in the current row\n for (; sx < src.width && !array(_y, sx); rowLength++, sx++) {\n mark(_y, sx);\n }\n // now we've scanned this row. if the block is rectangular, then the\n // previous row has already been scanned, so we don't need to look upwards\n // and we're going to scan the next row in the next iteration so we don't\n // need to look downwards. however, if the block is not rectangular, we may\n // need to look upwards or rightwards for some portion of the row. if this\n // row was shorter than the last row, we may need to look rightwards near\n // the end, as in the case of |*****|, where the first row is 5 cells long\n // and the second row is 3 cells long. We must look to the right |*** *|\n // of the single cell at the end of the second row, i.e. at (4,1)\n if (rowLength < lastRowLength) {\n // 'end' is the end of the previous row, so scan the current row to\n for (const end = _x + lastRowLength; ++sx < end; ) {\n // there. any clear cells would have been connected to the previous\n if (!array(_y, sx)) {\n // row. the cells up and left must be set so use FillCore\n Draw.fill4Core(src, sx, _y, array, mark, visited);\n }\n }\n }\n // alternately, if this row is longer than the previous row, as in the case\n // |*** *| then we must look above the end of the row, i.e at (4,0)\n // |*****|\n else if (rowLength > lastRowLength && _y !== 0) {\n // if this row is longer and we're not already at the top...\n for (let ux = _x + lastRowLength; ++ux < sx; ) {\n // sx is the end of the current row\n if (!array(_y - 1, ux)) {\n // since there may be clear cells up and left, use _Fill\n Draw.fill4(src, ux, _y - 1, array, mark, visited);\n }\n }\n }\n // record the new row length\n lastRowLength = rowLength;\n // if we get to a full row or to the bottom, we're done\n } while (lastRowLength !== 0 && ++_y < src.height);\n }\n\n // Adam Milazzo (2015). A More Efficient Flood Fill.\n // http://www.adammil.net/blog/v126_A_More_Efficient_Flood_Fill.html\n private static fill4(\n src: MemoryImage,\n x: number,\n y: number,\n array: FillFloodTestPixel,\n mark: FillFloodMarkPixel,\n visited: Uint8Array\n ): void {\n let _x = x;\n let _y = y;\n\n if (visited[_y * src.width + _x] === 1) {\n return;\n }\n\n // at this point, we know array(y,x) is clear, and we want to move as far as\n // possible to the upper-left. moving up is much more important than moving\n // left, so we could try to make this smarter by sometimes moving to the\n // right if doing so would allow us to move further up, but it doesn't seem\n // worth the complexity\n while (true) {\n const ox = _x;\n const oy = _y;\n while (_y !== 0 && !array(_y - 1, _x)) {\n _y--;\n }\n while (_x !== 0 && !array(_y, _x - 1)) {\n _x--;\n }\n if (_x === ox && _y === oy) {\n break;\n }\n }\n Draw.fill4Core(src, _x, _y, array, mark, visited);\n }\n\n private static imgDirectComposite(\n src: MemoryImage,\n dst: MemoryImage,\n dstX: number,\n dstY: number,\n dstW: number,\n dstH: number,\n xCache: number[],\n yCache: number[],\n maskChannel: Channel,\n mask?: MemoryImage\n ): void {\n let p: Pixel | undefined = undefined;\n if (mask !== undefined) {\n for (let y = 0; y < dstH; ++y) {\n for (let x = 0; x < dstW; ++x) {\n const sx = xCache[x];\n const sy = yCache[y];\n p = src.getPixel(sx, sy, p);\n const m = mask.getPixel(sx, sy).getChannelNormalized(maskChannel);\n if (m === 1) {\n dst.setPixel(dstX + x, dstY + y, p);\n } else {\n const dp = dst.getPixel(dstX + x, dstY + y);\n dp.r = MathUtils.mix(dp.r, p.r, m);\n dp.g = MathUtils.mix(dp.g, p.g, m);\n dp.b = MathUtils.mix(dp.b, p.b, m);\n dp.a = MathUtils.mix(dp.a, p.a, m);\n }\n }\n }\n } else {\n for (let y = 0; y < dstH; ++y) {\n for (let x = 0; x < dstW; ++x) {\n p = src.getPixel(xCache[x], yCache[y], p);\n dst.setPixel(dstX + x, dstY + y, p);\n }\n }\n }\n }\n\n private static imgComposite(\n src: MemoryImage,\n dst: MemoryImage,\n dstX: number,\n dstY: number,\n dstW: number,\n dstH: number,\n xCache: number[],\n yCache: number[],\n blend: BlendMode,\n linearBlend: boolean,\n maskChannel: Channel,\n mask?: MemoryImage\n ): void {\n let p: Pixel | undefined = undefined;\n for (let y = 0; y < dstH; ++y) {\n for (let x = 0; x < dstW; ++x) {\n p = src.getPixel(xCache[x], yCache[y], p);\n Draw.drawPixel({\n image: dst,\n pos: new Point(dstX + x, dstY + y),\n color: p,\n blend: blend,\n linearBlend: linearBlend,\n maskChannel: maskChannel,\n mask: mask,\n });\n }\n }\n }\n\n /**\n * Draw a circle into the **image** with a center of **center** and\n * the given **radius** and **color**.\n */\n public static drawCircle(opt: DrawCircleOptions): MemoryImage {\n const antialias = opt.antialias ?? false;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n if (antialias) {\n return Draw.drawAntialiasCircle({\n image: opt.image,\n x: opt.center.x,\n y: opt.center.y,\n radius: opt.radius,\n color: opt.color,\n mask: opt.mask,\n maskChannel: maskChannel,\n });\n }\n\n const points = Draw.calculateCircumference(\n opt.image,\n opt.center,\n opt.radius\n );\n for (const pt of points) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(pt.x, pt.y),\n color: opt.color,\n mask: opt.mask,\n maskChannel: maskChannel,\n });\n }\n return opt.image;\n }\n\n /**\n * Draw and fill a circle into the **image** with a **center**\n * and the given **radius** and **color**.\n */\n public static fillCircle(opt: FillCircleOptions): MemoryImage {\n const antialias = opt.antialias ?? false;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n const radiusSqr = opt.radius * opt.radius;\n const x1 = Math.max(0, opt.center.x - opt.radius);\n const y1 = Math.max(0, opt.center.y - opt.radius);\n const x2 = Math.min(opt.image.width - 1, opt.center.x + opt.radius);\n const y2 = Math.min(opt.image.height - 1, opt.center.y + opt.radius);\n const range = opt.image.getRange(x1, y1, x2 - x1 + 1, y2 - y1 + 1);\n\n let it: IteratorResult | undefined = undefined;\n while (((it = range.next()), !it.done)) {\n const p = it.value;\n if (antialias) {\n const a = ImageUtils.circleTest(p, opt.center, radiusSqr, antialias);\n if (a > 0) {\n const alpha = opt.color.aNormalized * a;\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(p.x, p.y),\n color: opt.color,\n alpha: alpha,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n } else {\n const dx = p.x - opt.center.x;\n const dy = p.y - opt.center.y;\n const d2 = dx * dx + dy * dy;\n if (d2 < radiusSqr) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(p.x, p.y),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n }\n }\n\n return opt.image;\n }\n\n /**\n * Draw a line into **image**.\n *\n * If **antialias** is true then the line is drawn with smooth edges.\n * **thickness** determines how thick the line should be drawn, in pixels.\n */\n public static drawLine(opt: DrawLineOptions): MemoryImage {\n const line = opt.line.clone();\n const antialias = opt.antialias ?? false;\n const thickness = opt.thickness ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (\n !ImageUtils.clipLine(\n new Rectangle(0, 0, opt.image.width - 1, opt.image.height - 1),\n line\n )\n ) {\n return opt.image;\n }\n\n const radius = Math.floor(thickness / 2);\n\n // Drawing a single point.\n if (line.dx === 0 && line.dy === 0) {\n opt.thickness === 1\n ? Draw.drawPixel({\n image: opt.image,\n pos: new Point(line.x1, line.y1),\n color: opt.color,\n maskChannel: opt.maskChannel,\n mask: opt.mask,\n })\n : Draw.fillCircle({\n image: opt.image,\n center: new Point(line.x1, line.y1),\n radius: radius,\n color: opt.color,\n maskChannel: opt.maskChannel,\n mask: opt.mask,\n });\n return opt.image;\n }\n\n // Axis-aligned lines\n if (line.dx === 0) {\n if (line.dy < 0) {\n for (let y = line.y2; y <= line.y1; ++y) {\n if (thickness <= 1) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(line.x1, y),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n } else {\n for (let i = 0; i < thickness; i++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(line.x1 - radius + i, y),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n }\n }\n } else {\n for (let y = line.y1; y <= line.y2; ++y) {\n if (thickness <= 1) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(line.x1, y),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n } else {\n for (let i = 0; i < thickness; i++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(line.x1 - radius + i, y),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n }\n }\n }\n return opt.image;\n } else if (line.dy === 0) {\n if (line.dx < 0) {\n for (let x = line.x2; x <= line.x1; ++x) {\n if (thickness <= 1) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x, line.y1),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n } else {\n for (let i = 0; i < thickness; i++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x, line.y1 - radius + i),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n }\n }\n } else {\n for (let x = line.x1; x <= line.x2; ++x) {\n if (thickness <= 1) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x, line.y1),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n } else {\n for (let i = 0; i < thickness; i++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x, line.y1 - radius + i),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n }\n }\n }\n return opt.image;\n }\n\n // 16-bit unsigned int xor.\n const xor = (n: number): number => {\n return (~n + 0x10000) & 0xffff;\n };\n\n if (!antialias) {\n const dx = Math.abs(line.dx);\n const dy = Math.abs(line.dy);\n if (dy <= dx) {\n // More-or-less horizontal. use wid for vertical stroke\n const ac = Math.cos(Math.atan2(dy, dx));\n let wid = 0;\n if (ac !== 0) {\n wid = Math.trunc(thickness / ac);\n } else {\n wid = 1;\n }\n\n if (wid === 0) {\n wid = 1;\n }\n\n let d = 2 * dy - dx;\n const incr1 = 2 * dy;\n const incr2 = 2 * (dy - dx);\n\n let x = 0;\n let y = 0;\n let ydirflag = 0;\n let xend = 0;\n if (line.x1 > line.x2) {\n x = line.x2;\n y = line.y2;\n ydirflag = -1;\n xend = line.x1;\n } else {\n x = line.x1;\n y = line.y1;\n ydirflag = 1;\n xend = line.x2;\n }\n\n // Set up line thickness\n let wstart = Math.trunc(y - wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x, w),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n\n if ((line.y2 - line.y1) * ydirflag > 0) {\n while (x < xend) {\n x++;\n if (d < 0) {\n d += incr1;\n } else {\n y++;\n d += incr2;\n }\n wstart = Math.trunc(y - wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x, w),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n }\n } else {\n while (x < xend) {\n x++;\n if (d < 0) {\n d += incr1;\n } else {\n y--;\n d += incr2;\n }\n wstart = Math.trunc(y - wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x, w),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n }\n }\n } else {\n // More-or-less vertical. use wid for horizontal stroke\n const as = Math.sin(Math.atan2(dy, dx));\n let wid = 0;\n if (as !== 0) {\n wid = Math.trunc(thickness / as);\n } else {\n wid = 1;\n }\n if (wid === 0) {\n wid = 1;\n }\n\n let d = 2 * dx - dy;\n const incr1 = 2 * dx;\n const incr2 = 2 * (dx - dy);\n let x = 0;\n let y = 0;\n let yend = 0;\n let xdirflag = 0;\n if (line.y1 > line.y2) {\n y = line.y2;\n x = line.x2;\n yend = line.y1;\n xdirflag = -1;\n } else {\n y = line.y1;\n x = line.x1;\n yend = line.y2;\n xdirflag = 1;\n }\n\n // Set up line thickness\n let wstart = Math.trunc(x - wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(w, y),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n\n if ((line.x2 - line.x1) * xdirflag > 0) {\n while (y < yend) {\n y++;\n if (d < 0) {\n d += incr1;\n } else {\n x++;\n d += incr2;\n }\n wstart = Math.trunc(x - wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(w, y),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n }\n } else {\n while (y < yend) {\n y++;\n if (d < 0) {\n d += incr1;\n } else {\n x--;\n d += incr2;\n }\n wstart = Math.trunc(x - wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(w, y),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n }\n }\n }\n\n return opt.image;\n }\n\n // Antialias Line\n if (thickness === 1) {\n return Draw.drawLineWu({\n image: opt.image,\n line: new Line(line.x1, line.y1, line.x2, line.y2),\n color: opt.color,\n });\n }\n\n const ag =\n Math.abs(line.dy) < Math.abs(line.dx)\n ? Math.cos(Math.atan2(line.dy, line.dx))\n : Math.sin(Math.atan2(line.dy, line.dx));\n\n let wid = 0;\n if (ag !== 0.0) {\n wid = Math.trunc(Math.abs(thickness / ag));\n } else {\n wid = 1;\n }\n if (wid === 0) {\n wid = 1;\n }\n\n if (Math.abs(line.dx) > Math.abs(line.dy)) {\n if (line.dx < 0) {\n line.flipX();\n line.flipY();\n }\n\n let y = line.y1;\n const inc = Math.trunc((line.dy * 65536) / line.dx);\n let frac = 0;\n\n for (let x = line.x1; x <= line.x2; x++) {\n const wstart = y - Math.trunc(wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x, w),\n color: opt.color,\n alpha: ((frac >> 8) & 0xff) / 255,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x, w + 1),\n color: opt.color,\n alpha: ((xor(frac) >> 8) & 0xff) / 255,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n\n frac += inc;\n if (frac >= 65536) {\n frac -= 65536;\n y++;\n } else if (frac < 0) {\n frac += 65536;\n y--;\n }\n }\n } else {\n if (line.dy < 0) {\n line.flipX();\n line.flipY();\n }\n\n let x = line.x1;\n const inc = Math.trunc((line.dx * 65536) / line.dy);\n let frac = 0;\n\n for (let y = line.y1; y <= line.y2; y++) {\n const wstart = x - Math.trunc(wid / 2);\n for (let w = wstart; w < wstart + wid; w++) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(w, y),\n color: opt.color,\n alpha: ((frac >> 8) & 0xff) / 255,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(w + 1, y),\n color: opt.color,\n alpha: ((xor(frac) >> 8) & 0xff) / 255,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n\n frac += inc;\n if (frac >= 65536) {\n frac -= 65536;\n x++;\n } else if (frac < 0) {\n frac += 65536;\n x--;\n }\n }\n }\n\n return opt.image;\n }\n\n /**\n * Draw a single pixel into the image, applying alpha and opacity blending.\n * If **filter** is provided, the color c will be scaled by the **filter**\n * color. If **alpha** is provided, it will be used in place of the\n * color alpha, as a normalized color value [0, 1].\n */\n public static drawPixel(opt: DrawPixelOptions): MemoryImage {\n const blend = opt.blend ?? BlendMode.alpha;\n const linearBlend = opt.linearBlend ?? false;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (!opt.image.isBoundsSafe(opt.pos.x, opt.pos.y)) {\n return opt.image;\n }\n\n if (blend === BlendMode.direct || opt.image.hasPalette) {\n if (opt.image.isBoundsSafe(opt.pos.x, opt.pos.y)) {\n opt.image.getPixel(opt.pos.x, opt.pos.y).set(opt.color);\n return opt.image;\n }\n }\n\n const msk =\n opt.mask\n ?.getPixel(opt.pos.x, opt.pos.y)\n .getChannelNormalized(maskChannel) ?? 1;\n\n let overlayR =\n opt.filter !== undefined\n ? opt.color.rNormalized * opt.filter.rNormalized\n : opt.color.rNormalized;\n let overlayG =\n opt.filter !== undefined\n ? opt.color.gNormalized * opt.filter.gNormalized\n : opt.color.gNormalized;\n let overlayB =\n opt.filter !== undefined\n ? opt.color.bNormalized * opt.filter.bNormalized\n : opt.color.bNormalized;\n\n const overlayA =\n (opt.alpha ?? (opt.color.length < 4 ? 1 : opt.color.aNormalized)) * msk;\n\n if (overlayA === 0) {\n return opt.image;\n }\n\n const dst = opt.image.getPixel(opt.pos.x, opt.pos.y);\n\n const baseR = dst.rNormalized;\n const baseG = dst.gNormalized;\n const baseB = dst.bNormalized;\n const baseA = dst.aNormalized;\n\n switch (blend) {\n case BlendMode.direct:\n return opt.image;\n case BlendMode.alpha:\n break;\n case BlendMode.lighten:\n overlayR = Math.max(baseR, overlayR);\n overlayG = Math.max(baseG, overlayG);\n overlayB = Math.max(baseB, overlayB);\n break;\n case BlendMode.screen:\n overlayR = 1 - (1 - overlayR) * (1 - baseR);\n overlayG = 1 - (1 - overlayG) * (1 - baseG);\n overlayB = 1 - (1 - overlayB) * (1 - baseB);\n break;\n case BlendMode.dodge:\n {\n const baseOverlayAlphaProduct = overlayA * baseA;\n\n const rightHandProductR =\n overlayR * (1 - baseA) + baseR * (1 - overlayA);\n const rightHandProductG =\n overlayG * (1 - baseA) + baseG * (1 - overlayA);\n const rightHandProductB =\n overlayB * (1 - baseA) + baseB * (1 - overlayA);\n\n const firstBlendColorR = baseOverlayAlphaProduct + rightHandProductR;\n const firstBlendColorG = baseOverlayAlphaProduct + rightHandProductG;\n const firstBlendColorB = baseOverlayAlphaProduct + rightHandProductB;\n\n const oR = MathUtils.clamp(\n (overlayR / MathUtils.clamp(overlayA, 0.01, 1)) *\n MathUtils.step(0, overlayA),\n 0,\n 0.99\n );\n const oG = MathUtils.clamp(\n (overlayG / MathUtils.clamp(overlayA, 0.01, 1)) *\n MathUtils.step(0, overlayA),\n 0,\n 0.99\n );\n const oB = MathUtils.clamp(\n (overlayB / MathUtils.clamp(overlayA, 0.01, 1)) *\n MathUtils.step(0, overlayA),\n 0,\n 0.99\n );\n\n const secondBlendColorR =\n (baseR * overlayA) / (1 - oR) + rightHandProductR;\n const secondBlendColorG =\n (baseG * overlayA) / (1 - oG) + rightHandProductG;\n const secondBlendColorB =\n (baseB * overlayA) / (1 - oB) + rightHandProductB;\n\n const colorChoiceR = MathUtils.step(\n overlayR * baseA + baseR * overlayA,\n baseOverlayAlphaProduct\n );\n const colorChoiceG = MathUtils.step(\n overlayG * baseA + baseG * overlayA,\n baseOverlayAlphaProduct\n );\n const colorChoiceB = MathUtils.step(\n overlayB * baseA + baseB * overlayA,\n baseOverlayAlphaProduct\n );\n\n overlayR = MathUtils.mix(\n firstBlendColorR,\n secondBlendColorR,\n colorChoiceR\n );\n overlayG = MathUtils.mix(\n firstBlendColorG,\n secondBlendColorG,\n colorChoiceG\n );\n overlayB = MathUtils.mix(\n firstBlendColorB,\n secondBlendColorB,\n colorChoiceB\n );\n }\n break;\n case BlendMode.addition:\n overlayR = baseR + overlayR;\n overlayG = baseG + overlayG;\n overlayB = baseB + overlayB;\n break;\n case BlendMode.darken:\n overlayR = Math.min(baseR, overlayR);\n overlayG = Math.min(baseG, overlayG);\n overlayB = Math.min(baseB, overlayB);\n break;\n case BlendMode.multiply:\n overlayR *= baseR;\n overlayG *= baseG;\n overlayB *= baseB;\n break;\n case BlendMode.burn:\n overlayR = overlayR !== 0 ? 1 - (1 - baseR) / overlayR : 0;\n overlayG = overlayG !== 0 ? 1 - (1 - baseG) / overlayG : 0;\n overlayB = overlayB !== 0 ? 1 - (1 - baseB) / overlayB : 0;\n break;\n case BlendMode.overlay:\n if (2 * baseR < baseA) {\n overlayR =\n 2 * overlayR * baseR +\n overlayR * (1 - baseA) +\n baseR * (1 - overlayA);\n } else {\n overlayR =\n overlayA * baseA -\n 2 * (baseA - baseR) * (overlayA - overlayR) +\n overlayR * (1 - baseA) +\n baseR * (1 - overlayA);\n }\n\n if (2 * baseG < baseA) {\n overlayG =\n 2 * overlayG * baseG +\n overlayG * (1 - baseA) +\n baseG * (1 - overlayA);\n } else {\n overlayG =\n overlayA * baseA -\n 2 * (baseA - baseG) * (overlayA - overlayG) +\n overlayG * (1 - baseA) +\n baseG * (1 - overlayA);\n }\n\n if (2 * baseB < baseA) {\n overlayB =\n 2 * overlayB * baseB +\n overlayB * (1 - baseA) +\n baseB * (1 - overlayA);\n } else {\n overlayB =\n overlayA * baseA -\n 2 * (baseA - baseB) * (overlayA - overlayB) +\n overlayB * (1 - baseA) +\n baseB * (1 - overlayA);\n }\n break;\n case BlendMode.softLight:\n overlayR =\n baseA === 0\n ? 0\n : baseR *\n (overlayA * (baseR / baseA) +\n 2 * overlayR * (1 - baseR / baseA)) +\n overlayR * (1 - baseA) +\n baseR * (1 - overlayA);\n\n overlayG =\n baseA === 0\n ? 0\n : baseG *\n (overlayA * (baseG / baseA) +\n 2 * overlayG * (1 - baseG / baseA)) +\n overlayG * (1 - baseA) +\n baseG * (1 - overlayA);\n\n overlayB =\n baseA === 0\n ? 0\n : baseB *\n (overlayA * (baseB / baseA) +\n 2 * overlayB * (1 - baseB / baseA)) +\n overlayB * (1 - baseA) +\n baseB * (1 - overlayA);\n break;\n case BlendMode.hardLight:\n if (2 * overlayR < overlayA) {\n overlayR =\n 2 * overlayR * baseR +\n overlayR * (1 - baseA) +\n baseR * (1 - overlayA);\n } else {\n overlayR =\n overlayA * baseA -\n 2 * (baseA - baseR) * (overlayA - overlayR) +\n overlayR * (1 - baseA) +\n baseR * (1 - overlayA);\n }\n\n if (2 * overlayG < overlayA) {\n overlayG =\n 2 * overlayG * baseG +\n overlayG * (1 - baseA) +\n baseG * (1 - overlayA);\n } else {\n overlayG =\n overlayA * baseA -\n 2 * (baseA - baseG) * (overlayA - overlayG) +\n overlayG * (1 - baseA) +\n baseG * (1 - overlayA);\n }\n\n if (2 * overlayB < overlayA) {\n overlayB =\n 2 * overlayB * baseB +\n overlayB * (1 - baseA) +\n baseB * (1 - overlayA);\n } else {\n overlayB =\n overlayA * baseA -\n 2 * (baseA - baseB) * (overlayA - overlayB) +\n overlayB * (1 - baseA) +\n baseB * (1 - overlayA);\n }\n break;\n case BlendMode.difference:\n overlayR = Math.abs(overlayR - baseR);\n overlayG = Math.abs(overlayG - baseG);\n overlayB = Math.abs(overlayB - baseB);\n break;\n case BlendMode.subtract:\n overlayR = baseR - overlayR;\n overlayG = baseG - overlayG;\n overlayB = baseB - overlayB;\n break;\n case BlendMode.divide:\n overlayR = overlayR !== 0 ? baseR / overlayR : 0;\n overlayG = overlayG !== 0 ? baseG / overlayG : 0;\n overlayB = overlayB !== 0 ? baseB / overlayB : 0;\n break;\n }\n\n const invA = 1 - overlayA;\n\n if (linearBlend) {\n const lbr = Math.pow(baseR, 2.2);\n const lbg = Math.pow(baseG, 2.2);\n const lbb = Math.pow(baseB, 2.2);\n const lor = Math.pow(overlayR, 2.2);\n const log = Math.pow(overlayG, 2.2);\n const lob = Math.pow(overlayB, 2.2);\n const r = Math.pow(lor * overlayA + lbr * baseA * invA, 1 / 2.2);\n const g = Math.pow(log * overlayA + lbg * baseA * invA, 1 / 2.2);\n const b = Math.pow(lob * overlayA + lbb * baseA * invA, 1 / 2.2);\n const a = overlayA + baseA * invA;\n dst.rNormalized = r;\n dst.gNormalized = g;\n dst.bNormalized = b;\n dst.aNormalized = a;\n } else {\n const r = overlayR * overlayA + baseR * baseA * invA;\n const g = overlayG * overlayA + baseG * baseA * invA;\n const b = overlayB * overlayA + baseB * baseA * invA;\n const a = overlayA + baseA * invA;\n dst.rNormalized = r;\n dst.gNormalized = g;\n dst.bNormalized = b;\n dst.aNormalized = a;\n }\n\n return opt.image;\n }\n\n /**\n * Fill a polygon defined by the given **vertices**.\n */\n public static drawPolygon(opt: DrawPolygonOptions): MemoryImage {\n const antialias = opt.antialias ?? false;\n const thickness = opt.thickness ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (opt.color.a === 0) {\n return opt.image;\n }\n\n const vertices = opt.vertices;\n const numVertices = vertices.length;\n\n if (numVertices === 0) {\n return opt.image;\n }\n\n if (numVertices === 1) {\n return Draw.drawPixel({\n image: opt.image,\n pos: vertices[0],\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n\n if (numVertices === 2) {\n return Draw.drawLine({\n image: opt.image,\n line: new Line(\n vertices[0].x,\n vertices[0].y,\n vertices[1].x,\n vertices[1].y\n ),\n color: opt.color,\n antialias: antialias,\n thickness: thickness,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n\n for (let i = 0; i < numVertices - 1; ++i) {\n Draw.drawLine({\n image: opt.image,\n line: new Line(\n vertices[i].x,\n vertices[i].y,\n vertices[i + 1].x,\n vertices[i + 1].y\n ),\n color: opt.color,\n antialias: antialias,\n thickness: thickness,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n\n Draw.drawLine({\n image: opt.image,\n line: new Line(\n vertices[numVertices - 1].x,\n vertices[numVertices - 1].y,\n vertices[0].x,\n vertices[0].y\n ),\n color: opt.color,\n antialias: antialias,\n thickness: thickness,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n\n return opt.image;\n }\n\n /**\n * Draw a rectangle in the **image** with the **color**.\n */\n public static drawRect(opt: DrawRectOptions): MemoryImage {\n const rect = opt.rect;\n const thickness = opt.thickness ?? 1;\n const radius = opt.radius ?? 0;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n const x0 = rect.left;\n const y0 = rect.top;\n const x1 = rect.right;\n const y1 = rect.bottom;\n\n // Draw a rounded rectangle\n if (radius > 0) {\n const rad = Math.round(radius);\n Draw.drawLine({\n image: opt.image,\n line: new Line(x0 + rad, y0, x1 - rad, y0),\n color: opt.color,\n });\n Draw.drawLine({\n image: opt.image,\n line: new Line(x1, y0 + rad, x1, y1 - rad),\n color: opt.color,\n });\n Draw.drawLine({\n image: opt.image,\n line: new Line(x0 + rad, y1, x1 - rad, y1),\n color: opt.color,\n });\n Draw.drawLine({\n image: opt.image,\n line: new Line(x0, y0 + rad, x0, y1 - rad),\n color: opt.color,\n });\n\n const c1x = x0 + rad;\n const c1y = y0 + rad;\n const c2x = x1 - rad;\n const c2y = y0 + rad;\n const c3x = x1 - rad;\n const c3y = y1 - rad;\n const c4x = x0 + rad;\n const c4y = y1 - rad;\n\n Draw.drawAntialiasCircle({\n image: opt.image,\n x: c1x,\n y: c1y,\n radius: rad,\n color: opt.color,\n maskChannel: maskChannel,\n quadrants: CircleQuadrant.topLeft,\n mask: opt.mask,\n });\n\n Draw.drawAntialiasCircle({\n image: opt.image,\n x: c2x,\n y: c2y,\n radius: rad,\n color: opt.color,\n maskChannel: maskChannel,\n quadrants: CircleQuadrant.topRight,\n mask: opt.mask,\n });\n\n Draw.drawAntialiasCircle({\n image: opt.image,\n x: c3x,\n y: c3y,\n radius: rad,\n color: opt.color,\n maskChannel: maskChannel,\n quadrants: CircleQuadrant.bottomRight,\n mask: opt.mask,\n });\n\n Draw.drawAntialiasCircle({\n image: opt.image,\n x: c4x,\n y: c4y,\n radius: rad,\n color: opt.color,\n maskChannel: maskChannel,\n quadrants: CircleQuadrant.bottomLeft,\n mask: opt.mask,\n });\n\n return opt.image;\n }\n\n const ht = thickness / 2;\n\n Draw.drawLine({\n image: opt.image,\n line: new Line(x0, y0, x1, y0),\n color: opt.color,\n thickness: thickness,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n\n Draw.drawLine({\n image: opt.image,\n line: new Line(x0, y1, x1, y1),\n color: opt.color,\n thickness: thickness,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n\n const isEvenThickness = ht - Math.trunc(ht) === 0;\n const dh = isEvenThickness ? 1 : 0;\n\n const by0 = Math.ceil(y0 + ht);\n const by1 = Math.floor(y1 - ht - dh);\n const bx0 = Math.floor(x0 + ht);\n const bx1 = Math.ceil(x1 - ht + dh);\n\n Draw.drawLine({\n image: opt.image,\n line: new Line(bx0, by0, bx0, by1),\n color: opt.color,\n thickness: thickness,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n\n Draw.drawLine({\n image: opt.image,\n line: new Line(bx1, by0, bx1, by1),\n color: opt.color,\n thickness: thickness,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n\n return opt.image;\n }\n\n /**\n * Fill the 4-connected shape containing **start** in the **image** with the\n * given **color**.\n */\n public static fillFlood(opt: FillFloodOptions): MemoryImage {\n const threshold = opt.threshold ?? 0;\n const compareAlpha = opt.compareAlpha ?? false;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (opt.color.a === 0) {\n return opt.image;\n }\n\n const visited = new Uint8Array(opt.image.width * opt.image.height);\n\n const srcColor = opt.image.getPixel(opt.start.x, opt.start.y);\n if (!compareAlpha) {\n opt.color.a = 0;\n }\n\n let array: FillFloodTestPixel | undefined = undefined;\n if (threshold > 0) {\n const lab = ColorUtils.rgbToLab(srcColor.r, srcColor.g, srcColor.b);\n if (compareAlpha) {\n lab.push(srcColor.a);\n }\n\n array = (y: number, x: number) => {\n return (\n visited[y * opt.image.width + x] === 0 &&\n Draw.testPixelLabColorDistance(opt.image, x, y, lab, threshold)\n );\n };\n } else if (!compareAlpha) {\n array = (y: number, x: number) => {\n return (\n visited[y * opt.image.width + x] === 0 &&\n Draw.setAlpha(opt.image.getPixel(x, y), 0) !== srcColor\n );\n };\n } else {\n array = (y: number, x: number) => {\n return (\n visited[y * opt.image.width + x] === 0 &&\n opt.image.getPixel(x, y) !== srcColor\n );\n };\n }\n\n let p: Pixel | undefined = undefined;\n\n const mark = (y: number, x: number): void => {\n if (opt.mask !== undefined) {\n const m = opt.mask.getPixel(x, y).getChannelNormalized(maskChannel);\n if (m > 0) {\n p = opt.image.getPixel(x, y, p);\n p.r = MathUtils.mix(p!.r, opt.color.r, m);\n p.g = MathUtils.mix(p!.g, opt.color.g, m);\n p.b = MathUtils.mix(p!.b, opt.color.b, m);\n p.a = MathUtils.mix(p!.a, opt.color.a, m);\n }\n } else {\n opt.image.setPixel(x, y, opt.color);\n }\n visited[y * opt.image.width + x] = 1;\n };\n\n Draw.fill4(opt.image, opt.start.x, opt.start.y, array, mark, visited);\n\n return opt.image;\n }\n\n /**\n * Fill a polygon defined by the given **vertices**.\n */\n public static fillPolygon(opt: FillPolygonOptions): MemoryImage {\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (opt.color.a === 0) {\n return opt.image;\n }\n\n const numVertices = opt.vertices.length;\n\n if (numVertices === 0) {\n return opt.image;\n }\n\n if (numVertices === 1) {\n return Draw.drawPixel({\n image: opt.image,\n pos: opt.vertices[0],\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n\n if (numVertices === 2) {\n return Draw.drawLine({\n image: opt.image,\n line: new Line(\n opt.vertices[0].x,\n opt.vertices[0].y,\n opt.vertices[1].x,\n opt.vertices[1].y\n ),\n color: opt.color,\n mask: opt.mask,\n maskChannel: maskChannel,\n });\n }\n\n let xMin = 0;\n let yMin = 0;\n let xMax = 0;\n let yMax = 0;\n let first = true;\n for (const vertex of opt.vertices) {\n if (first) {\n xMin = vertex.x;\n yMin = vertex.y;\n xMax = vertex.x;\n yMax = vertex.y;\n first = false;\n } else {\n xMin = Math.min(xMin, vertex.x);\n yMin = Math.min(yMin, vertex.y);\n xMax = Math.max(xMax, vertex.x);\n yMax = Math.max(yMax, vertex.y);\n }\n }\n\n xMin = Math.max(xMin, 0);\n yMin = Math.max(yMin, 0);\n xMax = Math.min(xMax, opt.image.width - 1);\n yMax = Math.min(yMax, opt.image.height - 1);\n\n const inter = ArrayUtils.fill(40, 0);\n const vi = ArrayUtils.generate(numVertices + 1, (i) =>\n i < numVertices ? i : 0\n );\n\n for (let yi = yMin, y = yMin + 0.5; yi <= yMax; ++yi, ++y) {\n let c = 0;\n for (let i = 0; i < numVertices; ++i) {\n const v1 = opt.vertices[vi[i]];\n const v2 = opt.vertices[vi[i + 1]];\n\n let x1 = v1.x;\n let y1 = v1.y;\n let x2 = v2.x;\n let y2 = v2.y;\n if (y2 < y1) {\n let temp = x1;\n x1 = x2;\n x2 = temp;\n temp = y1;\n y1 = y2;\n y2 = temp;\n }\n\n if (y <= y2 && y >= y1) {\n let x = 0;\n if (y1 - y2 === 0) {\n x = x1;\n } else {\n x = ((x2 - x1) * (y - y1)) / (y2 - y1);\n x += x1;\n }\n if (x <= xMax && x >= xMin) {\n inter[c++] = x;\n }\n }\n }\n\n for (let i = 0; i < c; i += 2) {\n let x1f = inter[i];\n let x2f = inter[i + 1];\n if (x1f > x2f) {\n const t = x1f;\n x1f = x2f;\n x2f = t;\n }\n const x1 = Math.floor(x1f);\n const x2 = Math.ceil(x2f);\n for (let x = x1; x <= x2; ++x) {\n Draw.drawPixel({\n image: opt.image,\n pos: new Point(x, yi),\n color: opt.color,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n }\n }\n }\n\n return opt.image;\n }\n\n /**\n * Fill a rectangle **rect** in the **image** with the given **color**.\n */\n public static fillRect(opt: FillRectOptions): MemoryImage {\n const radius = opt.radius ?? 0;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (opt.color.a === 0) {\n return opt.image;\n }\n\n const xx0 = MathUtils.clamp(opt.rect.left, 0, opt.image.width - 1);\n const yy0 = MathUtils.clamp(opt.rect.top, 0, opt.image.height - 1);\n const xx1 = MathUtils.clamp(opt.rect.right, 0, opt.image.width - 1);\n const yy1 = MathUtils.clamp(opt.rect.bottom, 0, opt.image.height - 1);\n const ww = xx1 - xx0 + 1;\n const hh = yy1 - yy0 + 1;\n\n // Fill a rounded rect\n if (radius > 0) {\n const rad = Math.round(radius);\n const rad2 = rad * rad;\n const c1x = xx0 + rad;\n const c1y = yy0 + rad;\n const c2x = xx1 - rad + 1;\n const c2y = yy0 + rad;\n const c3x = xx1 - rad + 1;\n const c3y = yy1 - rad + 1;\n const c4x = xx0 + rad;\n const c4y = yy1 - rad + 1;\n\n const range = opt.image.getRange(xx0, yy0, ww, hh);\n let it: IteratorResult | undefined = undefined;\n while (((it = range.next()), !it.done)) {\n const p = it.value;\n const px = p.x;\n const py = p.y;\n\n let a = 1;\n if (px < c1x && py < c1y) {\n a = ImageUtils.circleTest(p, new Point(c1x, c1y), rad2);\n if (a === 0) {\n continue;\n }\n } else if (px > c2x && py < c2y) {\n a = ImageUtils.circleTest(p, new Point(c2x, c2y), rad2);\n if (a === 0) {\n continue;\n }\n } else if (px > c3x && py > c3y) {\n a = ImageUtils.circleTest(p, new Point(c3x, c3y), rad2);\n if (a === 0) {\n continue;\n }\n } else if (px < c4x && py > c4y) {\n a = ImageUtils.circleTest(p, new Point(c4x, c4y), rad2);\n if (a === 0) {\n continue;\n }\n }\n\n a *= opt.color.aNormalized;\n\n const m =\n opt.mask?.getPixel(p.x, p.y).getChannelNormalized(maskChannel) ?? 1;\n p.r = MathUtils.mix(p.r, opt.color.r, a * m);\n p.g = MathUtils.mix(p.g, opt.color.g, a * m);\n p.b = MathUtils.mix(p.b, opt.color.b, a * m);\n p.a *= 1 - opt.color.a * m;\n }\n\n return opt.image;\n }\n\n // If no blending is necessary, use a faster fill method.\n if (opt.color.a === opt.color.maxChannelValue && opt.mask === undefined) {\n const range = opt.image.getRange(xx0, yy0, ww, hh);\n let it: IteratorResult | undefined = undefined;\n while (((it = range.next()), !it.done)) {\n it.value.set(opt.color);\n }\n } else {\n const a = opt.color.a / opt.color.maxChannelValue;\n const range = opt.image.getRange(xx0, yy0, ww, hh);\n let it: IteratorResult | undefined = undefined;\n while (((it = range.next()), !it.done)) {\n const p = it.value;\n const m =\n opt.mask?.getPixel(p.x, p.y).getChannelNormalized(maskChannel) ?? 1;\n p.r = MathUtils.mix(p.r, opt.color.r, a * m);\n p.g = MathUtils.mix(p.g, opt.color.g, a * m);\n p.b = MathUtils.mix(p.b, opt.color.b, a * m);\n p.a *= 1 - opt.color.a * m;\n }\n }\n\n return opt.image;\n }\n\n /**\n * Set all of the pixels of an **image** to the given **color**.\n */\n public static fill(opt: FillOptions): MemoryImage {\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (opt.mask === undefined) {\n opt.image.clear(opt.color);\n return opt.image;\n }\n\n for (const p of opt.image) {\n const maskValue = opt.mask\n .getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n p.r = MathUtils.mix(p.r, opt.color.r, maskValue);\n p.g = MathUtils.mix(p.g, opt.color.g, maskValue);\n p.b = MathUtils.mix(p.b, opt.color.b, maskValue);\n p.a = MathUtils.mix(p.a, opt.color.a, maskValue);\n }\n\n return opt.image;\n }\n\n /**\n * Create a mask describing the 4-connected shape containing **start** in the\n * **image**.\n */\n public static maskFlood(opt: MaskFloodOptions): Uint8Array {\n const threshold = opt.threshold ?? 0;\n const compareAlpha = opt.compareAlpha ?? false;\n const fillValue = opt.fillValue ?? 255;\n\n const visited = new Uint8Array(opt.image.width * opt.image.height);\n\n let srcColor: Color = opt.image.getPixel(opt.start.x, opt.start.y);\n if (!compareAlpha) {\n srcColor = Draw.setAlpha(srcColor, 0);\n }\n\n const ret = new Uint8Array(opt.image.width * opt.image.height);\n\n let array: FillFloodTestPixel | undefined = undefined;\n if (threshold > 0) {\n const lab = ColorUtils.rgbToLab(srcColor.r, srcColor.g, srcColor.b);\n if (compareAlpha) {\n lab.push(srcColor.a);\n }\n array = (y: number, x: number) => {\n return (\n visited[y * opt.image.width + x] === 0 &&\n (ret[y * opt.image.width + x] !== 0 ||\n Draw.testPixelLabColorDistance(opt.image, x, y, lab, threshold))\n );\n };\n } else if (!compareAlpha) {\n array = (y: number, x: number) => {\n return (\n visited[y * opt.image.width + x] === 0 &&\n (ret[y * opt.image.width + x] !== 0 ||\n Draw.setAlpha(opt.image.getPixel(x, y), 0) !== srcColor)\n );\n };\n } else {\n array = (y: number, x: number) => {\n return (\n visited[y * opt.image.width + x] === 0 &&\n (ret[y * opt.image.width + x] !== 0 ||\n opt.image.getPixel(x, y) !== srcColor)\n );\n };\n }\n\n const mark = (y: number, x: number): void => {\n ret[y * opt.image.width + x] = fillValue;\n visited[y * opt.image.width + x] = 1;\n };\n\n Draw.fill4(opt.image, opt.start.x, opt.start.y, array, mark, visited);\n return ret;\n }\n\n /**\n * Composite the image **src** onto the image **dst**.\n *\n * In other words, compositeImage will take an rectangular area from src of\n * width **srcW** and height **srcH** at position (**srcX**,**srcY**) and place it\n * in a rectangular area of **dst** of width **dstW** and height **dstH** at\n * position (**dstX**,**dstY**).\n *\n * If the source and destination coordinates and width and heights differ,\n * appropriate stretching or shrinking of the image fragment will be performed.\n * The coordinates refer to the upper left corner. This function can be used to\n * copy regions within the same image (if **dst** is the same as **src**)\n * but if the regions overlap the results will be unpredictable.\n *\n * if **center** is true, the **src** will be centered in **dst**.\n */\n public static compositeImage(opt: CompositeImageOptions): MemoryImage {\n let dstX = opt.dstX ?? 0;\n let dstY = opt.dstY ?? 0;\n const srcX = opt.srcX ?? 0;\n const srcY = opt.srcY ?? 0;\n const srcW = opt.srcW ?? opt.src.width;\n const srcH = opt.srcH ?? opt.src.height;\n const dstW =\n opt.dstW ??\n (opt.dst.width < opt.src.width ? opt.dst.width : opt.src.width);\n const dstH =\n opt.dstH ??\n (opt.dst.height < opt.src.height ? opt.dst.height : opt.src.height);\n const blend = opt.blend ?? BlendMode.alpha;\n const linearBlend = opt.linearBlend ?? false;\n const center = opt.center ?? false;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (center) {\n // if [src] is wider than [dst]\n let wdt = opt.dst.width - opt.src.width;\n if (wdt < 0) wdt = 0;\n dstX = Math.trunc(wdt / 2);\n // if [src] is higher than [dst]\n let height = opt.dst.height - opt.src.height;\n if (height < 0) height = 0;\n dstY = Math.trunc(height / 2);\n }\n\n if (opt.dst.hasPalette) {\n opt.dst.convert({\n numChannels: opt.dst.numChannels,\n });\n }\n\n const dy = srcH / dstH;\n const dx = srcW / dstW;\n const yCache = Array.from(\n { length: dstH },\n (_, y) => srcY + Math.trunc(y * dy)\n );\n const xCache = Array.from(\n { length: dstW },\n (_, x) => srcX + Math.trunc(x * dx)\n );\n\n if (blend === BlendMode.direct) {\n Draw.imgDirectComposite(\n opt.src,\n opt.dst,\n dstX,\n dstY,\n dstW,\n dstH,\n xCache,\n yCache,\n maskChannel,\n opt.mask\n );\n } else {\n Draw.imgComposite(\n opt.src,\n opt.dst,\n dstX,\n dstY,\n dstW,\n dstH,\n xCache,\n yCache,\n blend,\n linearBlend,\n maskChannel,\n opt.mask\n );\n }\n\n return opt.dst;\n }\n}\n", "/** @format */\n\nimport { IfdValue } from './ifd-value/ifd-value';\n\nexport class ExifEntry {\n private readonly _tag: number;\n public get tag(): number {\n return this._tag;\n }\n\n private _value: IfdValue | undefined;\n public get value(): IfdValue | undefined {\n return this._value;\n }\n public set value(v: IfdValue | undefined) {\n this._value = v;\n }\n\n constructor(tag: number, value?: IfdValue) {\n this._tag = tag;\n this._value = value;\n }\n}\n", "/** @format */\n\nexport enum IfdValueType {\n none,\n byte,\n ascii,\n short,\n long,\n rational,\n sByte,\n undefined,\n sShort,\n sLong,\n sRational,\n single,\n double,\n}\n\nexport const IfdValueTypeSize = [0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8];\n\nexport function getIfdValueTypeString(type: IfdValueType) {\n return IfdValueType[type];\n}\n\nexport function getIfdValueTypeSize(type: IfdValueType, length = 1) {\n return IfdValueTypeSize[type] * length;\n}\n", "/** @format */\n\nimport { IfdValueType } from './ifd-value-type';\n\nexport interface ExifTagInitOptions {\n name: string;\n type?: IfdValueType;\n count?: number;\n}\n\nexport class ExifTag {\n private readonly _name: string;\n public get name(): string {\n return this._name;\n }\n\n private readonly _type: IfdValueType;\n public get type(): IfdValueType {\n return this._type;\n }\n\n private _count?: number;\n public get count(): number | undefined {\n return this._count;\n }\n\n constructor(opt: ExifTagInitOptions) {\n this._name = opt.name;\n this._type = opt.type ?? IfdValueType.none;\n this._count = opt.count;\n }\n}\n\nexport const ExifTagNameToID = new Map([\n ['ProcessingSoftware', 0xb],\n ['SubfileType', 0xfe],\n ['OldSubfileType', 0xff],\n ['ImageWidth', 0x100],\n ['ImageLength', 0x101],\n // alias for a more common name.\n ['ImageHeight', 0x101],\n ['BitsPerSample', 0x102],\n ['Compression', 0x103],\n ['PhotometricInterpretation', 0x106],\n ['Thresholding', 0x107],\n ['CellWidth', 0x108],\n ['CellLength', 0x109],\n ['FillOrder', 0x10a],\n ['DocumentName', 0x10d],\n ['ImageDescription', 0x10e],\n ['Make', 0x10f],\n ['Model', 0x110],\n ['StripOffsets', 0x111],\n ['Orientation', 0x112],\n ['SamplesPerPixel', 0x115],\n ['RowsPerStrip', 0x116],\n ['StripByteCounts', 0x117],\n ['MinSampleValue', 0x118],\n ['MaxSampleValue', 0x119],\n ['XResolution', 0x11a],\n ['YResolution', 0x11b],\n ['PlanarConfiguration', 0x11c],\n ['PageName', 0x11d],\n ['XPosition', 0x11e],\n ['YPosition', 0x11f],\n ['GrayResponseUnit', 0x122],\n ['GrayResponseCurve', 0x123],\n ['T4Options', 0x124],\n ['T6Options', 0x125],\n ['ResolutionUnit', 0x128],\n ['PageNumber', 0x129],\n ['ColorResponseUnit', 0x12c],\n ['TransferFunction', 0x12d],\n ['Software', 0x131],\n ['DateTime', 0x132],\n ['Artist', 0x13b],\n ['HostComputer', 0x13c],\n ['Predictor', 0x13d],\n ['WhitePoint', 0x13e],\n ['PrimaryChromaticities', 0x13f],\n ['ColorMap', 0x140],\n ['HalftoneHints', 0x141],\n ['TileWidth', 0x142],\n ['TileLength', 0x143],\n ['TileOffsets', 0x144],\n ['TileByteCounts', 0x145],\n ['BadFaxLines', 0x146],\n ['CleanFaxData', 0x147],\n ['ConsecutiveBadFaxLines', 0x148],\n ['InkSet', 0x14c],\n ['InkNames', 0x14d],\n ['NumberofInks', 0x14e],\n ['DotRange', 0x150],\n ['TargetPrinter', 0x151],\n ['ExtraSamples', 0x152],\n ['SampleFormat', 0x153],\n ['SMinSampleValue', 0x154],\n ['SMaxSampleValue', 0x155],\n ['TransferRange', 0x156],\n ['ClipPath', 0x157],\n ['JPEGProc', 0x200],\n ['JPEGInterchangeFormat', 0x201],\n ['JPEGInterchangeFormatLength', 0x202],\n ['YCbCrCoefficients', 0x211],\n ['YCbCrSubSampling', 0x212],\n ['YCbCrPositioning', 0x213],\n ['ReferenceBlackWhite', 0x214],\n ['ApplicationNotes', 0x2bc],\n ['Rating', 0x4746],\n ['CFARepeatPatternDim', 0x828d],\n ['CFAPattern', 0x828e],\n ['BatteryLevel', 0x828f],\n ['Copyright', 0x8298],\n ['ExposureTime', 0x829a],\n ['FNumber', 0x829d],\n ['IPTC-NAA', 0x83bb],\n ['ExifOffset', 0x8769],\n ['InterColorProfile', 0x8773],\n ['ExposureProgram', 0x8822],\n ['SpectralSensitivity', 0x8824],\n ['GPSOffset', 0x8825],\n ['ISOSpeed', 0x8827],\n ['OECF', 0x8828],\n ['SensitivityType', 0x8830],\n ['RecommendedExposureIndex', 0x8832],\n ['ExifVersion', 0x9000],\n ['DateTimeOriginal', 0x9003],\n ['DateTimeDigitized', 0x9004],\n ['OffsetTime', 0x9010],\n ['OffsetTimeOriginal', 0x9011],\n ['OffsetTimeDigitized', 0x9012],\n ['ComponentsConfiguration', 0x9101],\n ['CompressedBitsPerPixel', 0x9102],\n ['ShutterSpeedValue', 0x9201],\n ['ApertureValue', 0x9202],\n ['BrightnessValue', 0x9203],\n ['ExposureBiasValue', 0x9204],\n ['MaxApertureValue', 0x9205],\n ['SubjectDistance', 0x9206],\n ['MeteringMode', 0x9207],\n ['LightSource', 0x9208],\n ['Flash', 0x9209],\n ['FocalLength', 0x920a],\n ['SubjectArea', 0x9214],\n ['MakerNote', 0x927c],\n ['UserComment', 0x9286],\n ['SubSecTime', 0x9290],\n ['SubSecTimeOriginal', 0x9291],\n ['SubSecTimeDigitized', 0x9292],\n ['XPTitle', 0x9c9b],\n ['XPComment', 0x9c9c],\n ['XPAuthor', 0x9c9d],\n ['XPKeywords', 0x9c9e],\n ['XPSubject', 0x9c9f],\n ['FlashPixVersion', 0xa000],\n ['ColorSpace', 0xa001],\n ['ExifImageWidth', 0xa002],\n ['ExifImageLength', 0xa003],\n ['RelatedSoundFile', 0xa004],\n ['InteroperabilityOffset', 0xa005],\n ['FlashEnergy', 0xa20b],\n ['SpatialFrequencyResponse', 0xa20c],\n ['FocalPlaneXResolution', 0xa20e],\n ['FocalPlaneYResolution', 0xa20f],\n ['FocalPlaneResolutionUnit', 0xa210],\n ['SubjectLocation', 0xa214],\n ['ExposureIndex', 0xa215],\n ['SensingMethod', 0xa217],\n ['FileSource', 0xa300],\n ['SceneType', 0xa301],\n ['CVAPattern', 0xa302],\n ['CustomRendered', 0xa401],\n ['ExposureMode', 0xa402],\n ['WhiteBalance', 0xa403],\n ['DigitalZoomRatio', 0xa404],\n ['FocalLengthIn35mmFilm', 0xa405],\n ['SceneCaptureType', 0xa406],\n ['GainControl', 0xa407],\n ['Contrast', 0xa408],\n ['Saturation', 0xa409],\n ['Sharpness', 0xa40a],\n ['DeviceSettingDescription', 0xa40b],\n ['SubjectDistanceRange', 0xa40c],\n ['ImageUniqueID', 0xa420],\n ['CameraOwnerName', 0xa430],\n ['BodySerialNumber', 0xa431],\n ['LensSpecification', 0xa432],\n ['LensMake', 0xa433],\n ['LensModel', 0xa434],\n ['LensSerialNumber', 0xa435],\n ['Gamma', 0xa500],\n ['PrintIM', 0xc4a5],\n ['Padding', 0xea1c],\n ['OffsetSchema', 0xea1d],\n ['OwnerName', 0xfde8],\n ['SerialNumber', 0xfde9],\n ['InteropIndex', 0x1],\n ['InteropVersion', 0x2],\n ['RelatedImageFileFormat', 0x1000],\n ['RelatedImageWidth', 0x1001],\n ['RelatedImageLength', 0x1002],\n ['GPSVersionID', 0x0],\n ['GPSLatitudeRef', 0x1],\n ['GPSLatitude', 0x2],\n ['GPSLongitudeRef', 0x3],\n ['GPSLongitude', 0x4],\n ['GPSAltitudeRef', 0x5],\n ['GPSAltitude', 0x6],\n ['GPSTimeStamp', 0x7],\n ['GPSSatellites', 0x8],\n ['GPSStatus', 0x9],\n ['GPSMeasureMode', 0xa],\n ['GPSDOP', 0xb],\n ['GPSSpeedRef', 0xc],\n ['GPSSpeed', 0xd],\n ['GPSTrackRef', 0xe],\n ['GPSTrack', 0xf],\n ['GPSImgDirectionRef', 0x10],\n ['GPSImgDirection', 0x11],\n ['GPSMapDatum', 0x12],\n ['GPSDestLatitudeRef', 0x13],\n ['GPSDestLatitude', 0x14],\n ['GPSDestLongitudeRef', 0x15],\n ['GPSDestLongitude', 0x16],\n ['GPSDestBearingRef', 0x17],\n ['GPSDestBearing', 0x18],\n ['GPSDestDistanceRef', 0x19],\n ['GPSDestDistance', 0x1a],\n ['GPSProcessingMethod', 0x1b],\n ['GPSAreaInformation', 0x1c],\n ['GPSDate', 0x1d],\n ['GPSDifferential', 0x1e],\n]);\n\nexport const ExifImageTags = new Map([\n [\n 0x000b,\n new ExifTag({\n name: 'ProcessingSoftware',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x00fe,\n new ExifTag({\n name: 'SubfileType',\n type: IfdValueType.long,\n count: 1,\n }),\n ],\n [\n 0x00ff,\n new ExifTag({\n name: 'OldSubfileType',\n type: IfdValueType.long,\n count: 1,\n }),\n ],\n [\n 0x0100,\n new ExifTag({\n name: 'ImageWidth',\n type: IfdValueType.long,\n count: 1,\n }),\n ],\n [\n 0x0101,\n new ExifTag({\n name: 'ImageLength',\n type: IfdValueType.long,\n count: 1,\n }),\n ],\n [\n 0x0102,\n new ExifTag({\n name: 'BitsPerSample',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x0103,\n new ExifTag({\n name: 'Compression',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x0106,\n new ExifTag({\n name: 'PhotometricInterpretation',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x0107,\n new ExifTag({\n name: 'Thresholding',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x0108,\n new ExifTag({\n name: 'CellWidth',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x0109,\n new ExifTag({\n name: 'CellLength',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x010a,\n new ExifTag({\n name: 'FillOrder',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x010d,\n new ExifTag({\n name: 'DocumentName',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x010e,\n new ExifTag({\n name: 'ImageDescription',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x010f,\n new ExifTag({\n name: 'Make',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x0110,\n new ExifTag({\n name: 'Model',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x0111,\n new ExifTag({\n name: 'StripOffsets',\n type: IfdValueType.long,\n }),\n ],\n [\n 0x0112,\n new ExifTag({\n name: 'Orientation',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x0115,\n new ExifTag({\n name: 'SamplesPerPixel',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x0116,\n new ExifTag({\n name: 'RowsPerStrip',\n type: IfdValueType.long,\n count: 1,\n }),\n ],\n [\n 0x0117,\n new ExifTag({\n name: 'StripByteCounts',\n type: IfdValueType.long,\n count: 1,\n }),\n ],\n [\n 0x0118,\n new ExifTag({\n name: 'MinSampleValue',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x0119,\n new ExifTag({\n name: 'MaxSampleValue',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x011a,\n new ExifTag({\n name: 'XResolution',\n type: IfdValueType.rational,\n count: 1,\n }),\n ],\n [\n 0x011b,\n new ExifTag({\n name: 'YResolution',\n type: IfdValueType.rational,\n count: 1,\n }),\n ],\n [\n 0x011c,\n new ExifTag({\n name: 'PlanarConfiguration',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x011d,\n new ExifTag({\n name: 'PageName',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x011e,\n new ExifTag({\n name: 'XPosition',\n type: IfdValueType.rational,\n count: 1,\n }),\n ],\n [\n 0x011f,\n new ExifTag({\n name: 'YPosition',\n type: IfdValueType.rational,\n count: 1,\n }),\n ],\n [\n 0x0122,\n new ExifTag({\n name: 'GrayResponseUnit',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x0123,\n new ExifTag({\n name: 'GrayResponseCurve',\n }),\n ],\n [\n 0x0124,\n new ExifTag({\n name: 'T4Options',\n }),\n ],\n [\n 0x0125,\n new ExifTag({\n name: 'T6Options',\n }),\n ],\n [\n 0x0128,\n new ExifTag({\n name: 'ResolutionUnit',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x0129,\n new ExifTag({\n name: 'PageNumber',\n type: IfdValueType.short,\n count: 2,\n }),\n ],\n [\n 0x012c,\n new ExifTag({\n name: 'ColorResponseUnit',\n }),\n ],\n [\n 0x012d,\n new ExifTag({\n name: 'TransferFunction',\n type: IfdValueType.short,\n count: 768,\n }),\n ],\n [\n 0x0131,\n new ExifTag({\n name: 'Software',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x0132,\n new ExifTag({\n name: 'DateTime',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x013b,\n new ExifTag({\n name: 'Artist',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x013c,\n new ExifTag({\n name: 'HostComputer',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x013d,\n new ExifTag({\n name: 'Predictor',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x013e,\n new ExifTag({\n name: 'WhitePoint',\n type: IfdValueType.rational,\n count: 2,\n }),\n ],\n [\n 0x013f,\n new ExifTag({\n name: 'PrimaryChromaticities',\n type: IfdValueType.rational,\n count: 6,\n }),\n ],\n [\n 0x0140,\n new ExifTag({\n name: 'ColorMap',\n type: IfdValueType.short,\n }),\n ],\n [\n 0x0141,\n new ExifTag({\n name: 'HalftoneHints',\n type: IfdValueType.short,\n count: 2,\n }),\n ],\n [\n 0x0142,\n new ExifTag({\n name: 'TileWidth',\n type: IfdValueType.long,\n count: 1,\n }),\n ],\n [\n 0x0143,\n new ExifTag({\n name: 'TileLength',\n type: IfdValueType.long,\n count: 1,\n }),\n ],\n [\n 0x0144,\n new ExifTag({\n name: 'TileOffsets',\n type: IfdValueType.long,\n }),\n ],\n [\n 0x0145,\n new ExifTag({\n name: 'TileByteCounts',\n }),\n ],\n [\n 0x0146,\n new ExifTag({\n name: 'BadFaxLines',\n }),\n ],\n [\n 0x0147,\n new ExifTag({\n name: 'CleanFaxData',\n }),\n ],\n [\n 0x0148,\n new ExifTag({\n name: 'ConsecutiveBadFaxLines',\n }),\n ],\n [\n 0x014c,\n new ExifTag({\n name: 'InkSet',\n }),\n ],\n [\n 0x014d,\n new ExifTag({\n name: 'InkNames',\n }),\n ],\n [\n 0x014e,\n new ExifTag({\n name: 'NumberofInks',\n }),\n ],\n [\n 0x0150,\n new ExifTag({\n name: 'DotRange',\n }),\n ],\n [\n 0x0151,\n new ExifTag({\n name: 'TargetPrinter',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x0152,\n new ExifTag({\n name: 'ExtraSamples',\n }),\n ],\n [\n 0x0153,\n new ExifTag({\n name: 'SampleFormat',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x0154,\n new ExifTag({\n name: 'SMinSampleValue',\n }),\n ],\n [\n 0x0155,\n new ExifTag({\n name: 'SMaxSampleValue',\n }),\n ],\n [\n 0x0156,\n new ExifTag({\n name: 'TransferRange',\n }),\n ],\n [\n 0x0157,\n new ExifTag({\n name: 'ClipPath',\n }),\n ],\n [\n 0x0200,\n new ExifTag({\n name: 'JPEGProc',\n }),\n ],\n [\n 0x0201,\n new ExifTag({\n name: 'JPEGInterchangeFormat',\n }),\n ],\n [\n 0x0202,\n new ExifTag({\n name: 'JPEGInterchangeFormatLength',\n }),\n ],\n [\n 0x0211,\n new ExifTag({\n name: 'YCbCrCoefficients',\n type: IfdValueType.rational,\n count: 3,\n }),\n ],\n [\n 0x0212,\n new ExifTag({\n name: 'YCbCrSubSampling',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x0213,\n new ExifTag({\n name: 'YCbCrPositioning',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x0214,\n new ExifTag({\n name: 'ReferenceBlackWhite',\n type: IfdValueType.rational,\n count: 6,\n }),\n ],\n // XPM Info\n [\n 0x02bc,\n new ExifTag({\n name: 'ApplicationNotes',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x4746,\n new ExifTag({\n name: 'Rating',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x828d,\n new ExifTag({\n name: 'CFARepeatPatternDim',\n }),\n ],\n [\n 0x828e,\n new ExifTag({\n name: 'CFAPattern',\n }),\n ],\n [\n 0x828f,\n new ExifTag({\n name: 'BatteryLevel',\n }),\n ],\n [\n 0x8298,\n new ExifTag({\n name: 'Copyright',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x829a,\n new ExifTag({\n name: 'ExposureTime',\n type: IfdValueType.rational,\n count: 1,\n }),\n ],\n [\n 0x829d,\n new ExifTag({\n name: 'FNumber',\n type: IfdValueType.rational,\n }),\n ],\n [\n 0x83bb,\n new ExifTag({\n name: 'IPTC-NAA',\n type: IfdValueType.long,\n count: 1,\n }),\n ],\n // Exif Tags\n [\n 0x8769,\n new ExifTag({\n name: 'ExifOffset',\n }),\n ],\n [\n 0x8773,\n new ExifTag({\n name: 'InterColorProfile',\n }),\n ],\n [\n 0x8822,\n new ExifTag({\n name: 'ExposureProgram',\n type: IfdValueType.short,\n }),\n ],\n [\n 0x8824,\n new ExifTag({\n name: 'SpectralSensitivity',\n type: IfdValueType.ascii,\n }),\n ],\n // GPS tags\n [\n 0x8825,\n new ExifTag({\n name: 'GPSOffset',\n }),\n ],\n [\n 0x8827,\n new ExifTag({\n name: 'ISOSpeed',\n type: IfdValueType.long,\n count: 1,\n }),\n ],\n [\n 0x8828,\n new ExifTag({\n name: 'OECF',\n }),\n ],\n [\n 0x8830,\n new ExifTag({\n name: 'SensitivityType',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x8832,\n new ExifTag({\n name: 'RecommendedExposureIndex',\n type: IfdValueType.long,\n count: 1,\n }),\n ],\n [\n 0x8833,\n new ExifTag({\n name: 'ISOSpeed',\n type: IfdValueType.long,\n count: 1,\n }),\n ],\n [\n 0x9000,\n new ExifTag({\n name: 'ExifVersion',\n type: IfdValueType.undefined,\n }),\n ],\n [\n 0x9003,\n new ExifTag({\n name: 'DateTimeOriginal',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x9004,\n new ExifTag({\n name: 'DateTimeDigitized',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x9010,\n new ExifTag({\n name: 'OffsetTime',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x9011,\n new ExifTag({\n name: 'OffsetTimeOriginal',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x9012,\n new ExifTag({\n name: 'OffsetTimeDigitized',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x9101,\n new ExifTag({\n name: 'ComponentsConfiguration',\n type: IfdValueType.undefined,\n }),\n ],\n [\n 0x9102,\n new ExifTag({\n name: 'CompressedBitsPerPixel',\n }),\n ],\n [\n 0x9201,\n new ExifTag({\n name: 'ShutterSpeedValue',\n }),\n ],\n [\n 0x9202,\n new ExifTag({\n name: 'ApertureValue',\n }),\n ],\n [\n 0x9203,\n new ExifTag({\n name: 'BrightnessValue',\n }),\n ],\n [\n 0x9204,\n new ExifTag({\n name: 'ExposureBiasValue',\n }),\n ],\n [\n 0x9205,\n new ExifTag({\n name: 'MaxApertureValue',\n }),\n ],\n [\n 0x9206,\n new ExifTag({\n name: 'SubjectDistance',\n }),\n ],\n [\n 0x9207,\n new ExifTag({\n name: 'MeteringMode',\n }),\n ],\n [\n 0x9208,\n new ExifTag({\n name: 'LightSource',\n }),\n ],\n [\n 0x9209,\n new ExifTag({\n name: 'Flash',\n }),\n ],\n [\n 0x920a,\n new ExifTag({\n name: 'FocalLength',\n }),\n ],\n [\n 0x9214,\n new ExifTag({\n name: 'SubjectArea',\n }),\n ],\n [\n 0x927c,\n new ExifTag({\n name: 'MakerNote',\n type: IfdValueType.undefined,\n }),\n ],\n [\n 0x9286,\n new ExifTag({\n name: 'UserComment',\n type: IfdValueType.undefined,\n }),\n ],\n [\n 0x9290,\n new ExifTag({\n name: 'SubSecTime',\n }),\n ],\n [\n 0x9291,\n new ExifTag({\n name: 'SubSecTimeOriginal',\n }),\n ],\n [\n 0x9292,\n new ExifTag({\n name: 'SubSecTimeDigitized',\n }),\n ],\n [\n 0x9c9b,\n new ExifTag({\n name: 'XPTitle',\n }),\n ],\n [\n 0x9c9c,\n new ExifTag({\n name: 'XPComment',\n }),\n ],\n [\n 0x9c9d,\n new ExifTag({\n name: 'XPAuthor',\n }),\n ],\n [\n 0x9c9e,\n new ExifTag({\n name: 'XPKeywords',\n }),\n ],\n [\n 0x9c9f,\n new ExifTag({\n name: 'XPSubject',\n }),\n ],\n [\n 0xa000,\n new ExifTag({\n name: 'FlashPixVersion',\n }),\n ],\n [\n 0xa001,\n new ExifTag({\n name: 'ColorSpace',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0xa002,\n new ExifTag({\n name: 'ExifImageWidth',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0xa003,\n new ExifTag({\n name: 'ExifImageLength',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0xa004,\n new ExifTag({\n name: 'RelatedSoundFile',\n }),\n ],\n [\n 0xa005,\n new ExifTag({\n name: 'InteroperabilityOffset',\n }),\n ],\n // [0x920B in TIFF/EP\n [\n 0xa20b,\n new ExifTag({\n name: 'FlashEnergy',\n }),\n ],\n [\n 0xa20c,\n new ExifTag({\n name: 'SpatialFrequencyResponse',\n }),\n ],\n [\n 0xa20e,\n new ExifTag({\n name: 'FocalPlaneXResolution',\n }),\n ],\n [\n 0xa20f,\n new ExifTag({\n name: 'FocalPlaneYResolution',\n }),\n ],\n [\n 0xa210,\n new ExifTag({\n name: 'FocalPlaneResolutionUnit',\n }),\n ],\n [\n 0xa214,\n new ExifTag({\n name: 'SubjectLocation',\n }),\n ],\n [\n 0xa215,\n new ExifTag({\n name: 'ExposureIndex',\n }),\n ],\n [\n 0xa217,\n new ExifTag({\n name: 'SensingMethod',\n }),\n ],\n [\n 0xa300,\n new ExifTag({\n name: 'FileSource',\n }),\n ],\n [\n 0xa301,\n new ExifTag({\n name: 'SceneType',\n }),\n ],\n [\n 0xa302,\n new ExifTag({\n name: 'CVAPattern',\n }),\n ],\n [\n 0xa401,\n new ExifTag({\n name: 'CustomRendered',\n }),\n ],\n [\n 0xa402,\n new ExifTag({\n name: 'ExposureMode',\n }),\n ],\n [\n 0xa403,\n new ExifTag({\n name: 'WhiteBalance',\n }),\n ],\n [\n 0xa404,\n new ExifTag({\n name: 'DigitalZoomRatio',\n }),\n ],\n [\n 0xa405,\n new ExifTag({\n name: 'FocalLengthIn35mmFilm',\n }),\n ],\n [\n 0xa406,\n new ExifTag({\n name: 'SceneCaptureType',\n }),\n ],\n [\n 0xa407,\n new ExifTag({\n name: 'GainControl',\n }),\n ],\n [\n 0xa408,\n new ExifTag({\n name: 'Contrast',\n }),\n ],\n [\n 0xa409,\n new ExifTag({\n name: 'Saturation',\n }),\n ],\n [\n 0xa40a,\n new ExifTag({\n name: 'Sharpness',\n }),\n ],\n [\n 0xa40b,\n new ExifTag({\n name: 'DeviceSettingDescription',\n }),\n ],\n [\n 0xa40c,\n new ExifTag({\n name: 'SubjectDistanceRange',\n }),\n ],\n [\n 0xa420,\n new ExifTag({\n name: 'ImageUniqueID',\n }),\n ],\n [\n 0xa430,\n new ExifTag({\n name: 'CameraOwnerName',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0xa431,\n new ExifTag({\n name: 'BodySerialNumber',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0xa432,\n new ExifTag({\n name: 'LensSpecification',\n }),\n ],\n [\n 0xa433,\n new ExifTag({\n name: 'LensMake',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0xa434,\n new ExifTag({\n name: 'LensModel',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0xa435,\n new ExifTag({\n name: 'LensSerialNumber',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0xa500,\n new ExifTag({\n name: 'Gamma',\n type: IfdValueType.rational,\n count: 1,\n }),\n ],\n [\n 0xc4a5,\n new ExifTag({\n name: 'PrintIM',\n }),\n ],\n [\n 0xea1c,\n new ExifTag({\n name: 'Padding',\n }),\n ],\n [\n 0xea1d,\n new ExifTag({\n name: 'OffsetSchema',\n }),\n ],\n [\n 0xfde8,\n new ExifTag({\n name: 'OwnerName',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0xfde9,\n new ExifTag({\n name: 'SerialNumber',\n type: IfdValueType.ascii,\n }),\n ],\n]);\n\nexport const ExifInteropTags = new Map([\n [\n 0x0001,\n new ExifTag({\n name: 'InteropIndex',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x0002,\n new ExifTag({\n name: 'InteropVersion',\n type: IfdValueType.undefined,\n }),\n ],\n [\n 0x1000,\n new ExifTag({\n name: 'RelatedImageFileFormat',\n type: IfdValueType.ascii,\n }),\n ],\n [\n 0x1001,\n new ExifTag({\n name: 'RelatedImageWidth',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n [\n 0x1002,\n new ExifTag({\n name: 'RelatedImageLength',\n type: IfdValueType.short,\n count: 1,\n }),\n ],\n]);\n\nexport const ExifGpsTags = new Map([\n [\n 0x0000,\n new ExifTag({\n name: 'GPSVersionID',\n }),\n ],\n [\n 0x0001,\n new ExifTag({\n name: 'GPSLatitudeRef',\n }),\n ],\n [\n 0x0002,\n new ExifTag({\n name: 'GPSLatitude',\n }),\n ],\n [\n 0x0003,\n new ExifTag({\n name: 'GPSLongitudeRef',\n }),\n ],\n [\n 0x0004,\n new ExifTag({\n name: 'GPSLongitude',\n }),\n ],\n [\n 0x0005,\n new ExifTag({\n name: 'GPSAltitudeRef',\n }),\n ],\n [\n 0x0006,\n new ExifTag({\n name: 'GPSAltitude',\n }),\n ],\n [\n 0x0007,\n new ExifTag({\n name: 'GPSTimeStamp',\n }),\n ],\n [\n 0x0008,\n new ExifTag({\n name: 'GPSSatellites',\n }),\n ],\n [\n 0x0009,\n new ExifTag({\n name: 'GPSStatus',\n }),\n ],\n [\n 0x000a,\n new ExifTag({\n name: 'GPSMeasureMode',\n }),\n ],\n [\n 0x000b,\n new ExifTag({\n name: 'GPSDOP',\n }),\n ],\n [\n 0x000c,\n new ExifTag({\n name: 'GPSSpeedRef',\n }),\n ],\n [\n 0x000d,\n new ExifTag({\n name: 'GPSSpeed',\n }),\n ],\n [\n 0x000e,\n new ExifTag({\n name: 'GPSTrackRef',\n }),\n ],\n [\n 0x000f,\n new ExifTag({\n name: 'GPSTrack',\n }),\n ],\n [\n 0x0010,\n new ExifTag({\n name: 'GPSImgDirectionRef',\n }),\n ],\n [\n 0x0011,\n new ExifTag({\n name: 'GPSImgDirection',\n }),\n ],\n [\n 0x0012,\n new ExifTag({\n name: 'GPSMapDatum',\n }),\n ],\n [\n 0x0013,\n new ExifTag({\n name: 'GPSDestLatitudeRef',\n }),\n ],\n [\n 0x0014,\n new ExifTag({\n name: 'GPSDestLatitude',\n }),\n ],\n [\n 0x0015,\n new ExifTag({\n name: 'GPSDestLongitudeRef',\n }),\n ],\n [\n 0x0016,\n new ExifTag({\n name: 'GPSDestLongitude',\n }),\n ],\n [\n 0x0017,\n new ExifTag({\n name: 'GPSDestBearingRef',\n }),\n ],\n [\n 0x0018,\n new ExifTag({\n name: 'GPSDestBearing',\n }),\n ],\n [\n 0x0019,\n new ExifTag({\n name: 'GPSDestDistanceRef',\n }),\n ],\n [\n 0x001a,\n new ExifTag({\n name: 'GPSDestDistance',\n }),\n ],\n [\n 0x001b,\n new ExifTag({\n name: 'GPSProcessingMethod',\n }),\n ],\n [\n 0x001c,\n new ExifTag({\n name: 'GPSAreaInformation',\n }),\n ],\n [\n 0x001d,\n new ExifTag({\n name: 'GPSDate',\n }),\n ],\n [\n 0x001e,\n new ExifTag({\n name: 'GPSDifferential',\n }),\n ],\n]);\n", "/** @format */\n\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { Rational } from '../../common/rational';\nimport { LibError } from '../../error/lib-error';\nimport {\n getIfdValueTypeSize,\n getIfdValueTypeString,\n IfdValueType,\n} from '../ifd-value-type';\n\nexport abstract class IfdValue {\n public get type(): IfdValueType {\n return IfdValueType.none;\n }\n\n public get length(): number {\n return 0;\n }\n\n public get dataSize(): number {\n return getIfdValueTypeSize(this.type, this.length);\n }\n\n public get typeString(): string {\n return getIfdValueTypeString(this.type);\n }\n\n public toBool(_index?: number): boolean {\n return false;\n }\n\n public toInt(_index?: number): number {\n return 0;\n }\n\n public toDouble(_index?: number): number {\n return 0;\n }\n\n public toData(): Uint8Array {\n return new Uint8Array();\n }\n\n public toRational(_index?: number): Rational {\n return new Rational(0, 1);\n }\n\n public write(_out: OutputBuffer): void {}\n\n public setBool(_v: boolean, _index?: number): void {}\n\n public setInt(_v: number, _index?: number): void {}\n\n public setDouble(_v: number, _index?: number): void {}\n\n public setRational(\n _numerator: number,\n _denomitator: number,\n _index?: number\n ): void {}\n\n public setString(_v: string): void {}\n\n public equals(_other: IfdValue): boolean {\n return false;\n }\n\n public clone(): IfdValue {\n throw new LibError('Cannot be copied.');\n }\n\n public toString(): string {\n return `${this.constructor.name}`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { StringUtils } from '../../common/string-utils';\nimport { IfdValue } from './ifd-value';\nimport { IfdValueType } from '../ifd-value-type';\n\nexport class IfdAsciiValue extends IfdValue {\n private _value: string;\n\n public get type(): IfdValueType {\n return IfdValueType.ascii;\n }\n\n public get length(): number {\n const codeUnits = StringUtils.getCodePoints(this._value);\n return codeUnits.length + 1;\n }\n\n constructor(value: number[] | string) {\n super();\n if (typeof value === 'string') {\n this._value = value;\n } else {\n this._value = String.fromCharCode(...value);\n }\n }\n\n public static data(data: InputBuffer, length: number) {\n // The final byte is a null terminator\n const value = length > 0 ? data.readString(length - 1) : '';\n return new IfdAsciiValue(value);\n }\n\n public toData(): Uint8Array {\n return StringUtils.getCodePoints(this._value);\n }\n\n public write(out: OutputBuffer): void {\n const bytes = StringUtils.getCodePoints(this._value);\n out.writeBytes(bytes);\n out.writeByte(0);\n }\n\n public setString(v: string): void {\n this._value = v;\n }\n\n public equals(other: IfdValue): boolean {\n return (\n other instanceof IfdAsciiValue &&\n this.length === other.length &&\n this._value === this._value\n );\n }\n\n public clone(): IfdValue {\n return new IfdAsciiValue(this._value);\n }\n\n public toString(): string {\n return `${this.constructor.name} (${this._value})`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { IfdValue } from './ifd-value';\nimport { IfdValueType } from '../ifd-value-type';\nimport { ArrayUtils } from '../../common/array-utils';\n\nexport class IfdShortValue extends IfdValue {\n private _value: Uint16Array;\n\n public get type(): IfdValueType {\n return IfdValueType.short;\n }\n\n public get length(): number {\n return this._value.length;\n }\n\n constructor(value: Uint16Array | number) {\n super();\n if (typeof value === 'number') {\n this._value = new Uint16Array(1);\n this._value[0] = value;\n } else {\n this._value = Uint16Array.from(value);\n }\n }\n\n public static data(data: InputBuffer, length: number) {\n const array = new Uint16Array(length);\n for (let i = 0; i < length; ++i) {\n array[i] = data.readUint16();\n }\n return new IfdShortValue(array);\n }\n\n public toInt(index = 0): number {\n return this._value[index];\n }\n\n public write(out: OutputBuffer): void {\n for (let i = 0, l = this._value.length; i < l; ++i) {\n out.writeUint16(this._value[i]);\n }\n }\n\n public setInt(v: number, index = 0): void {\n this._value[index] = v;\n }\n\n public equals(other: IfdValue): boolean {\n return (\n other instanceof IfdShortValue &&\n this.length === other.length &&\n ArrayUtils.equals(this._value, other._value)\n );\n }\n\n public clone(): IfdValue {\n return new IfdShortValue(this._value);\n }\n\n public toString(): string {\n return `${this.constructor.name} (${\n this._value.length === 1 ? `${this._value[0]}` : `${this._value}`\n })`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { IfdValue } from './ifd-value';\nimport { IfdValueType } from '../ifd-value-type';\nimport { Rational } from '../../common/rational';\nimport { ArrayUtils } from '../../common/array-utils';\n\nexport class IfdRationalValue extends IfdValue {\n private _value: Rational[];\n\n public get type(): IfdValueType {\n return IfdValueType.rational;\n }\n\n public get length(): number {\n return this._value.length;\n }\n\n constructor(value: Rational[] | Rational) {\n super();\n if (value instanceof Rational) {\n this._value = [value];\n } else {\n this._value = value;\n }\n }\n\n public static data(data: InputBuffer, length: number) {\n const array = new Array();\n for (let i = 0; i < length; i++) {\n const r = new Rational(data.readUint32(), data.readUint32());\n array.push(r);\n }\n return new IfdRationalValue(array);\n }\n\n public static from(other: Rational) {\n const r = new Rational(other.numerator, other.denominator);\n return new IfdRationalValue(r);\n }\n\n public toInt(index = 0): number {\n return this._value[index].toInt;\n }\n\n public toDouble(index = 0): number {\n return this._value[index].toDouble;\n }\n\n public toRational(index = 0): Rational {\n return this._value[index];\n }\n\n public write(out: OutputBuffer): void {\n for (const v of this._value) {\n out.writeUint32(v.numerator);\n out.writeUint32(v.denominator);\n }\n }\n\n public setRational(numerator: number, denomitator: number, index = 0): void {\n this._value[index] = new Rational(numerator, denomitator);\n }\n\n public equals(other: IfdValue): boolean {\n return (\n other instanceof IfdRationalValue &&\n this.length === other.length &&\n ArrayUtils.equalsRationalArray(this._value, other._value)\n );\n }\n\n public clone(): IfdValue {\n return new IfdRationalValue(this._value);\n }\n\n public toString(): string {\n return `${this.constructor.name} (${\n this._value.length === 1 ? `${this._value[0]}` : `${this._value}`\n })`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { IfdValue } from './ifd-value';\nimport { IfdValueType } from '../ifd-value-type';\nimport { ArrayUtils } from '../../common/array-utils';\n\nexport class IfdByteValue extends IfdValue {\n private _value: Uint8Array;\n\n public get type(): IfdValueType {\n return IfdValueType.byte;\n }\n\n public get length(): number {\n return this._value.length;\n }\n\n constructor(value: Uint8Array | number) {\n super();\n if (typeof value === 'number') {\n this._value = new Uint8Array(1);\n this._value[0] = value;\n } else {\n this._value = Uint8Array.from(value);\n }\n }\n\n public static data(data: InputBuffer, offset?: number, length?: number) {\n const array = data.toUint8Array(offset, length);\n return new IfdByteValue(array);\n }\n\n public toInt(index = 0): number {\n return this._value[index];\n }\n\n public toData(): Uint8Array {\n return this._value;\n }\n\n public write(out: OutputBuffer): void {\n out.writeBytes(this._value);\n }\n\n public setInt(v: number, index = 0): void {\n this._value[index] = v;\n }\n\n public equals(other: IfdValue): boolean {\n return (\n other instanceof IfdByteValue &&\n this.length === other.length &&\n ArrayUtils.equals(this._value, other._value)\n );\n }\n\n public clone(): IfdValue {\n return new IfdByteValue(this._value);\n }\n\n public toString(): string {\n return `${this.constructor.name} (${\n this._value.length === 1 ? `${this._value[0]}` : `${this._value}`\n })`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { IfdValue } from './ifd-value';\nimport { IfdValueType } from '../ifd-value-type';\nimport { ArrayUtils } from '../../common/array-utils';\n\nexport class IfdLongValue extends IfdValue {\n private _value: Uint32Array;\n\n public get type(): IfdValueType {\n return IfdValueType.long;\n }\n\n public get length(): number {\n return this._value.length;\n }\n\n constructor(value: Uint32Array | number) {\n super();\n if (typeof value === 'number') {\n this._value = new Uint32Array(1);\n this._value[0] = value;\n } else {\n this._value = Uint32Array.from(value);\n }\n }\n\n public static data(data: InputBuffer, length: number) {\n const array = new Uint32Array(length);\n for (let i = 0; i < length; ++i) {\n array[i] = data.readUint32();\n }\n return new IfdLongValue(array);\n }\n\n public toInt(index = 0): number {\n return this._value[index];\n }\n\n public toData(): Uint8Array {\n return new Uint8Array(this._value.buffer);\n }\n\n public write(out: OutputBuffer): void {\n for (let i = 0, l = this._value.length; i < l; ++i) {\n out.writeUint32(this._value[i]);\n }\n }\n\n public setInt(v: number, index = 0): void {\n this._value[index] = v;\n }\n\n public equals(other: IfdValue): boolean {\n return (\n other instanceof IfdLongValue &&\n this.length === other.length &&\n ArrayUtils.equals(this._value, other._value)\n );\n }\n\n public clone(): IfdValue {\n return new IfdLongValue(this._value);\n }\n\n public toString(): string {\n return `${this.constructor.name} (${\n this._value.length === 1 ? `${this._value[0]}` : `${this._value}`\n })`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { IfdValue } from './ifd-value';\nimport { IfdValueType } from '../ifd-value-type';\nimport { ArrayUtils } from '../../common/array-utils';\n\nexport class IfdSByteValue extends IfdValue {\n private _value: Int8Array;\n\n public get type(): IfdValueType {\n return IfdValueType.sByte;\n }\n\n public get length(): number {\n return this._value.length;\n }\n\n constructor(value: Int8Array | number) {\n super();\n if (typeof value === 'number') {\n this._value = new Int8Array(1);\n this._value[0] = value;\n } else {\n this._value = Int8Array.from(value);\n }\n }\n\n public static data(data: InputBuffer, offset?: number, length?: number) {\n const array = new Int8Array(\n new Int8Array(data.toUint8Array(offset, length).buffer)\n );\n return new IfdSByteValue(array);\n }\n\n public toInt(index = 0): number {\n return this._value[index];\n }\n\n public toData(): Uint8Array {\n return new Uint8Array(this._value.buffer);\n }\n\n public write(out: OutputBuffer): void {\n out.writeBytes(new Uint8Array(this._value.buffer));\n }\n\n public setInt(v: number, index = 0): void {\n this._value[index] = v;\n }\n\n public equals(other: IfdValue): boolean {\n return (\n other instanceof IfdSByteValue &&\n this.length === other.length &&\n ArrayUtils.equals(this._value, other._value)\n );\n }\n\n public clone(): IfdValue {\n return new IfdSByteValue(this._value);\n }\n\n public toString(): string {\n return `${this.constructor.name} (${\n this._value.length === 1 ? `${this._value[0]}` : `${this._value}`\n })`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { IfdValue } from './ifd-value';\nimport { IfdValueType } from '../ifd-value-type';\nimport { ArrayUtils } from '../../common/array-utils';\n\nexport class IfdUndefinedValue extends IfdValue {\n private _value: Uint8Array;\n\n public get type(): IfdValueType {\n return IfdValueType.undefined;\n }\n\n public get length(): number {\n return this._value.length;\n }\n\n constructor(value: Uint8Array | number) {\n super();\n if (typeof value === 'number') {\n this._value = new Uint8Array(1);\n this._value[0] = value;\n } else {\n this._value = value;\n }\n }\n\n public static data(data: InputBuffer, offset?: number, length?: number) {\n const array = new Uint8Array(data.toUint8Array(offset, length));\n return new IfdUndefinedValue(array);\n }\n\n public toData(): Uint8Array {\n return this._value;\n }\n\n public write(out: OutputBuffer): void {\n out.writeBytes(this._value);\n }\n\n public equals(other: IfdValue): boolean {\n return (\n other instanceof IfdUndefinedValue &&\n this.length === other.length &&\n ArrayUtils.equals(this._value, other._value)\n );\n }\n\n public clone(): IfdValue {\n return new IfdUndefinedValue(this._value);\n }\n\n public toString(): string {\n return `${this.constructor.name} (undefined)`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { IfdValue } from './ifd-value';\nimport { IfdValueType } from '../ifd-value-type';\nimport { ArrayUtils } from '../../common/array-utils';\n\nexport class IfdSShortValue extends IfdValue {\n private _value: Int16Array;\n\n public get type(): IfdValueType {\n return IfdValueType.sShort;\n }\n\n public get length(): number {\n return this._value.length;\n }\n\n constructor(value: Int16Array | number) {\n super();\n if (typeof value === 'number') {\n this._value = new Int16Array(1);\n this._value[0] = value;\n } else {\n this._value = Int16Array.from(value);\n }\n }\n\n public static data(data: InputBuffer, length: number) {\n const array = new Int16Array(length);\n for (let i = 0; i < length; ++i) {\n array[i] = data.readInt16();\n }\n return new IfdSShortValue(array);\n }\n\n public toInt(index = 0): number {\n return this._value[index];\n }\n\n public toData(): Uint8Array {\n return new Uint8Array(this._value.buffer);\n }\n\n public write(out: OutputBuffer): void {\n const v = new Int16Array(1);\n const vb = new Uint16Array(v.buffer);\n for (let i = 0, l = this._value.length; i < l; ++i) {\n v[0] = this._value[i];\n out.writeUint16(vb[0]);\n }\n }\n\n public setInt(v: number, index = 0): void {\n this._value[index] = v;\n }\n\n public equals(other: IfdValue): boolean {\n return (\n other instanceof IfdSShortValue &&\n this.length === other.length &&\n ArrayUtils.equals(this._value, other._value)\n );\n }\n\n public clone(): IfdValue {\n return new IfdSShortValue(this._value);\n }\n\n public toString(): string {\n return `${this.constructor.name} (${\n this._value.length === 1 ? `${this._value[0]}` : `${this._value}`\n })`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { IfdValue } from './ifd-value';\nimport { IfdValueType } from '../ifd-value-type';\nimport { BitUtils } from '../../common/bit-utils';\nimport { ArrayUtils } from '../../common/array-utils';\n\nexport class IfdSLongValue extends IfdValue {\n private _value: Int32Array;\n\n public get type(): IfdValueType {\n return IfdValueType.sLong;\n }\n\n public get length(): number {\n return this._value.length;\n }\n\n constructor(value: Int32Array | number) {\n super();\n if (typeof value === 'number') {\n this._value = new Int32Array(1);\n this._value[0] = value;\n } else {\n this._value = Int32Array.from(value);\n }\n }\n\n public static data(data: InputBuffer, length: number) {\n const array = new Int32Array(length);\n for (let i = 0; i < length; ++i) {\n array[i] = data.readInt32();\n }\n return new IfdSLongValue(array);\n }\n\n public toInt(index = 0): number {\n return this._value[index];\n }\n\n public toData(): Uint8Array {\n return new Uint8Array(this._value.buffer);\n }\n\n public write(out: OutputBuffer): void {\n for (let i = 0, l = this._value.length; i < l; ++i) {\n out.writeUint32(BitUtils.int32ToUint32(this._value[i]));\n }\n }\n\n public setInt(v: number, index = 0): void {\n this._value[index] = v;\n }\n\n public equals(other: IfdValue): boolean {\n return (\n other instanceof IfdSLongValue &&\n this.length === other.length &&\n ArrayUtils.equals(this._value, other._value)\n );\n }\n\n public clone(): IfdValue {\n return new IfdSLongValue(this._value);\n }\n\n public toString(): string {\n return `${this.constructor.name} (${\n this._value.length === 1 ? `${this._value[0]}` : `${this._value}`\n })`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { IfdValue } from './ifd-value';\nimport { IfdValueType } from '../ifd-value-type';\nimport { BitUtils } from '../../common/bit-utils';\nimport { Rational } from '../../common/rational';\nimport { ArrayUtils } from '../../common/array-utils';\n\nexport class IfdSRationalValue extends IfdValue {\n private _value: Rational[];\n\n public get type(): IfdValueType {\n return IfdValueType.sRational;\n }\n\n public get length(): number {\n return this._value.length;\n }\n\n constructor(value: Rational[] | Rational) {\n super();\n if (value instanceof Rational) {\n this._value = [value];\n } else {\n this._value = value;\n }\n }\n\n public static data(data: InputBuffer, length: number) {\n const array = new Array();\n for (let i = 0; i < length; i++) {\n const r = new Rational(data.readInt32(), data.readInt32());\n array.push(r);\n }\n return new IfdSRationalValue(array);\n }\n\n public static from(other: Rational) {\n const r = new Rational(other.numerator, other.denominator);\n return new IfdSRationalValue(r);\n }\n\n public toInt(index = 0): number {\n return this._value[index].toInt;\n }\n\n public toDouble(index = 0): number {\n return this._value[index].toDouble;\n }\n\n public toRational(index = 0): Rational {\n return this._value[index];\n }\n\n public write(out: OutputBuffer): void {\n for (const v of this._value) {\n out.writeUint32(BitUtils.int32ToUint32(v.numerator));\n out.writeUint32(BitUtils.int32ToUint32(v.denominator));\n }\n }\n\n public setRational(numerator: number, denomitator: number, index = 0): void {\n this._value[index] = new Rational(numerator, denomitator);\n }\n\n public equals(other: IfdValue): boolean {\n return (\n other instanceof IfdSRationalValue &&\n this.length === other.length &&\n ArrayUtils.equalsRationalArray(this._value, other._value)\n );\n }\n\n public clone(): IfdValue {\n return new IfdSRationalValue(this._value);\n }\n\n public toString(): string {\n return `${this.constructor.name} (${\n this._value.length === 1 ? `${this._value[0]}` : `${this._value}`\n })`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { IfdValue } from './ifd-value';\nimport { IfdValueType } from '../ifd-value-type';\nimport { ArrayUtils } from '../../common/array-utils';\n\nexport class IfdSingleValue extends IfdValue {\n private _value: Float32Array;\n\n public get type(): IfdValueType {\n return IfdValueType.single;\n }\n\n public get length(): number {\n return this._value.length;\n }\n\n constructor(value: Float32Array | number) {\n super();\n if (typeof value === 'number') {\n this._value = new Float32Array(1);\n this._value[0] = value;\n } else {\n this._value = Float32Array.from(value);\n }\n }\n\n public static data(data: InputBuffer, length: number) {\n const array = new Float32Array(length);\n for (let i = 0; i < length; ++i) {\n array[i] = data.readFloat32();\n }\n return new IfdSingleValue(array);\n }\n\n public toDouble(index = 0): number {\n return this._value[index];\n }\n\n public toData(): Uint8Array {\n return new Uint8Array(this._value.buffer);\n }\n\n public write(out: OutputBuffer): void {\n for (let i = 0, l = this._value.length; i < l; ++i) {\n out.writeFloat32(this._value[i]);\n }\n }\n\n public setDouble(v: number, index = 0): void {\n this._value[index] = v;\n }\n\n public equals(other: IfdValue): boolean {\n return (\n other instanceof IfdSingleValue &&\n this.length === other.length &&\n ArrayUtils.equals(this._value, other._value)\n );\n }\n\n public clone(): IfdValue {\n return new IfdSingleValue(this._value);\n }\n\n public toString(): string {\n return `${this.constructor.name} (${\n this._value.length === 1 ? `${this._value[0]}` : `${this._value}`\n })`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { IfdValue } from './ifd-value';\nimport { IfdValueType } from '../ifd-value-type';\nimport { ArrayUtils } from '../../common/array-utils';\n\nexport class IfdDoubleValue extends IfdValue {\n private _value: Float64Array;\n\n public get type(): IfdValueType {\n return IfdValueType.double;\n }\n\n public get length(): number {\n return this._value.length;\n }\n\n constructor(value: Float64Array | number) {\n super();\n if (typeof value === 'number') {\n this._value = new Float64Array(1);\n this._value[0] = value;\n } else {\n this._value = Float64Array.from(value);\n }\n }\n\n public static data(data: InputBuffer, length: number) {\n const array = new Float64Array(length);\n for (let i = 0; i < length; ++i) {\n array[i] = data.readFloat64();\n }\n return new IfdDoubleValue(array);\n }\n\n public toDouble(index = 0): number {\n return this._value[index];\n }\n\n public toData(): Uint8Array {\n return new Uint8Array(this._value.buffer);\n }\n\n public write(out: OutputBuffer): void {\n for (let i = 0, l = this._value.length; i < l; ++i) {\n out.writeFloat64(this._value[i]);\n }\n }\n\n public setDouble(v: number, index = 0): void {\n this._value[index] = v;\n }\n\n public equals(other: IfdValue): boolean {\n return (\n other instanceof IfdDoubleValue &&\n this.length === other.length &&\n ArrayUtils.equals(this._value, other._value)\n );\n }\n\n public clone(): IfdValue {\n return new IfdDoubleValue(this._value);\n }\n\n public toString(): string {\n return `${this.constructor.name} (${\n this._value.length === 1 ? `${this._value[0]}` : `${this._value}`\n })`;\n }\n}\n", "/** @format */\n\nimport { Rational } from '../common/rational';\nimport { ExifImageTags, ExifTagNameToID } from './exif-tag';\nimport { IfdValueType } from './ifd-value-type';\nimport { IfdContainer } from './ifd-container';\nimport { IfdValue } from './ifd-value/ifd-value';\nimport { IfdAsciiValue } from './ifd-value/ifd-ascii-value';\nimport { IfdShortValue } from './ifd-value/ifd-short-value';\nimport { IfdRationalValue } from './ifd-value/ifd-rational-value';\nimport { IfdByteValue } from './ifd-value/ifd-byte-value';\nimport { IfdLongValue } from './ifd-value/ifd-long-value';\nimport { IfdSByteValue } from './ifd-value/ifd-sbyte-value';\nimport { IfdUndefinedValue } from './ifd-value/ifd-undefined-value';\nimport { IfdSShortValue } from './ifd-value/ifd-sshort-value';\nimport { IfdSLongValue } from './ifd-value/ifd-slong-value';\nimport { IfdSRationalValue } from './ifd-value/ifd-srational-value';\nimport { IfdSingleValue } from './ifd-value/ifd-single-value';\nimport { IfdDoubleValue } from './ifd-value/ifd-double-value';\nimport { TypedArray } from '../common/typings';\nimport { StringUtils } from '../common/string-utils';\nimport { ArrayUtils } from '../common/array-utils';\n\nexport class IfdDirectory {\n private readonly _data: Map;\n\n private readonly _sub = new IfdContainer();\n public get sub(): IfdContainer {\n return this._sub;\n }\n\n public get keys(): IterableIterator {\n return this._data.keys();\n }\n\n public get values(): IterableIterator {\n return this._data.values();\n }\n\n public get size(): number {\n return this._data.size;\n }\n\n public get isEmpty(): boolean {\n return this._data.size === 0 && this._sub.isEmpty;\n }\n\n public get hasUserComment(): boolean {\n return this._data.has(0x9286);\n }\n\n public get userComment(): string | undefined {\n const data = this._data.get(0x9286)?.toData();\n return data !== undefined\n ? StringUtils.utf8Decoder.decode(data)\n : undefined;\n }\n\n public set userComment(v: string | undefined) {\n if (v === undefined) {\n this._data.delete(0x9286);\n } else {\n const codeUnits = StringUtils.getCodePoints(v);\n this._data.set(0x9286, new IfdUndefinedValue(codeUnits));\n }\n }\n\n public get hasImageDescription(): boolean {\n return this._data.has(0x010e);\n }\n\n public get imageDescription(): string | undefined {\n return this._data.get(0x010e)?.toString();\n }\n\n public set imageDescription(v: string | undefined) {\n if (v === undefined) {\n this._data.delete(0x010e);\n } else {\n this._data.set(0x010e, new IfdAsciiValue(v));\n }\n }\n\n public get hasMake(): boolean {\n return this._data.has(0x010f);\n }\n\n public get make(): string | undefined {\n return this._data.get(0x010f)?.toString();\n }\n\n public set make(v: string | undefined) {\n if (v === undefined) {\n this._data.delete(0x010f);\n } else {\n this._data.set(0x010f, new IfdAsciiValue(v));\n }\n }\n\n public get hasModel(): boolean {\n return this._data.has(0x0110);\n }\n\n public get model(): string | undefined {\n return this._data.get(0x0110)?.toString();\n }\n\n public set model(v: string | undefined) {\n if (v === undefined) {\n this._data.delete(0x0110);\n } else {\n this._data.set(0x0110, new IfdAsciiValue(v));\n }\n }\n\n public get hasOrientation(): boolean {\n return this._data.has(0x0112);\n }\n\n public get orientation(): number | undefined {\n return this._data.get(0x0112)?.toInt();\n }\n\n public set orientation(v: number | undefined) {\n if (v === undefined) {\n this._data.delete(0x0112);\n } else {\n this._data.set(0x0112, new IfdShortValue(v));\n }\n }\n\n public get hasResolutionX(): boolean {\n return this._data.has(0x011a);\n }\n\n public get resolutionX(): Rational | undefined {\n return this._data.get(0x011a)?.toRational();\n }\n\n public set resolutionX(v: Rational | undefined) {\n if (!this.setRational(0x011a, v)) {\n this._data.delete(0x011a);\n }\n }\n\n public get hasResolutionY(): boolean {\n return this._data.has(0x011b);\n }\n\n public get resolutionY(): Rational | undefined {\n return this._data.get(0x011b)?.toRational();\n }\n\n public set resolutionY(v: Rational | undefined) {\n if (!this.setRational(0x011b, v)) {\n this._data.delete(0x011b);\n }\n }\n\n public get hasResolutionUnit(): boolean {\n return this._data.has(0x0128);\n }\n\n public get resolutionUnit(): number | undefined {\n return this._data.get(0x0128)?.toInt();\n }\n\n public set resolutionUnit(v: number | undefined) {\n if (v === undefined) {\n this._data.delete(0x0128);\n } else {\n this._data.set(0x0128, new IfdShortValue(Math.trunc(v)));\n }\n }\n\n public get hasImageWidth(): boolean {\n return this._data.has(0x0100);\n }\n\n public get imageWidth(): number | undefined {\n return this._data.get(0x0100)?.toInt();\n }\n\n public set imageWidth(v: number | undefined) {\n if (v === undefined) {\n this._data.delete(0x0100);\n } else {\n this._data.set(0x0100, new IfdShortValue(Math.trunc(v)));\n }\n }\n\n public get hasImageHeight(): boolean {\n return this._data.has(0x0101);\n }\n\n public get imageHeight(): number | undefined {\n return this._data.get(0x0101)?.toInt();\n }\n\n public set imageHeight(v: number | undefined) {\n if (v === undefined) {\n this._data.delete(0x0101);\n } else {\n this._data.set(0x0101, new IfdShortValue(Math.trunc(v)));\n }\n }\n\n public get hasSoftware(): boolean {\n return this._data.has(0x0131);\n }\n\n public get software(): string | undefined {\n return this._data.get(0x0131)?.toString();\n }\n\n public set software(v: string | undefined) {\n if (v === undefined) {\n this._data.delete(0x0131);\n } else {\n this._data.set(0x0131, new IfdAsciiValue(v));\n }\n }\n\n public get hasCopyright(): boolean {\n return this._data.has(0x8298);\n }\n\n public get copyright(): string | undefined {\n return this._data.get(0x8298)?.toString();\n }\n\n public set copyright(v: string | undefined) {\n if (v === undefined) {\n this._data.delete(0x8298);\n } else {\n this._data.set(0x8298, new IfdAsciiValue(v));\n }\n }\n\n /**\n * The size in bytes of the data written by this directory. Can be used to\n * calculate end-of-block offsets.\n */\n public get dataSize(): number {\n const numEntries = this.size;\n let dataOffset = 2 + 12 * numEntries + 4;\n for (const value of this.values) {\n const dataSize = value.dataSize;\n if (dataSize > 4) {\n dataOffset += dataSize;\n }\n }\n // storage for sub-ifd blocks\n for (const subName of this.sub.keys) {\n const subIfd = this.sub.get(subName);\n let subSize = 2 + 12 * subIfd.size;\n for (const value of subIfd.values) {\n const dataSize = value.dataSize;\n if (dataSize > 4) {\n subSize += dataSize;\n }\n }\n dataOffset += subSize;\n }\n return dataOffset;\n }\n\n constructor(data?: Map) {\n this._data = data ?? new Map();\n }\n\n private setRational(\n tag: number,\n value: Rational | number[] | TypedArray | unknown\n ): boolean {\n if (value instanceof Rational) {\n this._data.set(tag, IfdRationalValue.from(value));\n return true;\n } else if (\n ArrayUtils.isNumArrayOrTypedArray(value) &&\n (value as []).length >= 2\n ) {\n const r = new Rational((value as number[])[0], (value as number[])[1]);\n this._data.set(tag, IfdRationalValue.from(r));\n return true;\n }\n return false;\n }\n\n public static from(other: IfdDirectory): IfdDirectory {\n return new IfdDirectory(new Map(other._data));\n }\n\n public static isArrayOfRationalNumbers(value: unknown): boolean {\n return (\n Array.isArray(value) &&\n value.every(\n (v) => ArrayUtils.isNumArrayOrTypedArray(v) && (v as []).length >= 2\n )\n );\n }\n\n public has(tag: number): boolean {\n return this._data.has(tag);\n }\n\n public getValue(tag: number | string): IfdValue | undefined {\n let _tag: string | number | undefined = tag;\n if (typeof _tag === 'string') {\n _tag = ExifTagNameToID.get(_tag);\n }\n if (typeof _tag === 'number') {\n return this._data.get(_tag);\n }\n return undefined;\n }\n\n public setValue(\n tag: number | string,\n value:\n | Rational[]\n | number[]\n | TypedArray\n | Rational\n | IfdValue\n | number\n | undefined\n ): void {\n let _tag: string | number | undefined = tag;\n if (typeof _tag === 'string') {\n _tag = ExifTagNameToID.get(_tag);\n }\n if (typeof _tag !== 'number') {\n return;\n }\n\n if (value === undefined) {\n this._data.delete(_tag);\n } else {\n if (value instanceof IfdValue) {\n this._data.set(_tag, value);\n } else {\n const tagInfo = ExifImageTags.get(_tag);\n if (tagInfo !== undefined) {\n const tagType = tagInfo.type;\n switch (tagType) {\n case IfdValueType.byte:\n if (ArrayUtils.isNumArrayOrTypedArray(value)) {\n this._data.set(\n _tag,\n new IfdByteValue(new Uint8Array(value as number[]))\n );\n } else if (typeof value === 'number') {\n this._data.set(_tag, new IfdByteValue(value));\n }\n break;\n case IfdValueType.ascii:\n if (typeof value === 'string') {\n this._data.set(_tag, new IfdAsciiValue(value));\n }\n break;\n case IfdValueType.short:\n if (ArrayUtils.isNumArrayOrTypedArray(value)) {\n this._data.set(\n _tag,\n new IfdShortValue(new Uint16Array(value as number[]))\n );\n } else if (typeof value === 'number') {\n this._data.set(_tag, new IfdShortValue(value));\n }\n break;\n case IfdValueType.long:\n if (ArrayUtils.isNumArrayOrTypedArray(value)) {\n this._data.set(\n _tag,\n new IfdLongValue(new Uint32Array(value as number[]))\n );\n } else if (typeof value === 'number') {\n this._data.set(_tag, new IfdLongValue(value));\n }\n break;\n case IfdValueType.rational:\n if (ArrayUtils.isArrayOfRational(value)) {\n this._data.set(_tag, new IfdRationalValue(value as Rational[]));\n } else if (\n ArrayUtils.isNumArrayOrTypedArray(value) &&\n (value as []).length >= 2\n ) {\n const r = new Rational(\n (value as number[])[0],\n (value as number[])[1]\n );\n this._data.set(_tag, new IfdRationalValue(r));\n } else if (value instanceof Rational) {\n this._data.set(_tag, new IfdRationalValue(value));\n }\n break;\n case IfdValueType.sByte:\n if (ArrayUtils.isNumArrayOrTypedArray(value)) {\n this._data.set(\n _tag,\n new IfdSByteValue(new Int8Array(value as number[]))\n );\n } else if (typeof value === 'number') {\n this._data.set(_tag, new IfdSByteValue(value));\n }\n break;\n case IfdValueType.undefined:\n if (ArrayUtils.isNumArrayOrTypedArray(value)) {\n this._data.set(\n _tag,\n new IfdUndefinedValue(new Uint8Array(value as number[]))\n );\n }\n break;\n case IfdValueType.sShort:\n if (ArrayUtils.isNumArrayOrTypedArray(value)) {\n this._data.set(\n _tag,\n new IfdSShortValue(new Int16Array(value as number[]))\n );\n } else if (typeof value === 'number') {\n this._data.set(_tag, new IfdSShortValue(value));\n }\n break;\n case IfdValueType.sLong:\n if (ArrayUtils.isNumArrayOrTypedArray(value)) {\n this._data.set(\n _tag,\n new IfdSLongValue(new Int32Array(value as number[]))\n );\n } else if (typeof value === 'number') {\n this._data.set(_tag, new IfdSLongValue(value));\n }\n break;\n case IfdValueType.sRational:\n if (ArrayUtils.isArrayOfRational(value)) {\n this._data.set(\n _tag,\n new IfdSRationalValue(value as Rational[])\n );\n } else if (\n ArrayUtils.isNumArrayOrTypedArray(value) &&\n (value as []).length >= 2\n ) {\n const r = new Rational(\n (value as number[])[0],\n (value as number[])[1]\n );\n this._data.set(_tag, new IfdSRationalValue(r));\n } else if (value instanceof Rational) {\n this._data.set(_tag, new IfdSRationalValue(value));\n }\n break;\n case IfdValueType.single:\n if (ArrayUtils.isNumArrayOrTypedArray(value)) {\n this._data.set(\n _tag,\n new IfdSingleValue(new Float32Array(value as number[]))\n );\n } else if (typeof value === 'number') {\n this._data.set(_tag, new IfdSingleValue(value));\n }\n break;\n case IfdValueType.double:\n if (ArrayUtils.isNumArrayOrTypedArray(value)) {\n this._data.set(\n _tag,\n new IfdDoubleValue(new Float64Array(value as number[]))\n );\n } else if (typeof value === 'number') {\n this._data.set(_tag, new IfdDoubleValue(value));\n }\n break;\n case IfdValueType.none:\n break;\n }\n }\n }\n }\n }\n\n public copyFrom(other: IfdDirectory): void {\n other._data.forEach((value, tag) => this._data.set(tag, value.clone()));\n }\n\n public clone(): IfdDirectory {\n return IfdDirectory.from(this);\n }\n}\n", "/** @format */\n\nimport { IfdDirectory } from './ifd-directory';\n\nexport class IfdContainer {\n protected directories: Map;\n\n public get keys(): IterableIterator {\n return this.directories.keys();\n }\n\n public get values(): IterableIterator {\n return this.directories.values();\n }\n\n public get size(): number {\n return this.directories.size;\n }\n\n public get isEmpty(): boolean {\n if (this.directories.size === 0) {\n return true;\n }\n for (const ifd of this.directories.values()) {\n if (!ifd.isEmpty) {\n return false;\n }\n }\n return true;\n }\n\n constructor(directories?: Map) {\n this.directories = directories ?? new Map();\n }\n\n public static from(other: IfdContainer) {\n const dirs = new Map(other.directories);\n return new IfdContainer(dirs);\n }\n\n public has(key: string): boolean {\n return this.directories.has(key);\n }\n\n public get(ifdName: string): IfdDirectory {\n let ifd = this.directories.get(ifdName);\n if (ifd === undefined) {\n ifd = new IfdDirectory();\n this.directories.set(ifdName, ifd);\n return ifd;\n } else {\n return ifd;\n }\n }\n\n public set(ifdName: string, value: IfdDirectory): void {\n this.directories.set(ifdName, value);\n }\n\n public clear(): void {\n this.directories.clear();\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../common/input-buffer';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { ExifEntry } from './exif-entry';\nimport { ExifImageTags, ExifTagNameToID } from './exif-tag';\nimport { IfdContainer } from './ifd-container';\nimport { IfdDirectory } from './ifd-directory';\nimport { IfdValueType, IfdValueTypeSize } from './ifd-value-type';\nimport { IfdAsciiValue } from './ifd-value/ifd-ascii-value';\nimport { IfdByteValue } from './ifd-value/ifd-byte-value';\nimport { IfdDoubleValue } from './ifd-value/ifd-double-value';\nimport { IfdLongValue } from './ifd-value/ifd-long-value';\nimport { IfdRationalValue } from './ifd-value/ifd-rational-value';\nimport { IfdSByteValue } from './ifd-value/ifd-sbyte-value';\nimport { IfdShortValue } from './ifd-value/ifd-short-value';\nimport { IfdSingleValue } from './ifd-value/ifd-single-value';\nimport { IfdSLongValue } from './ifd-value/ifd-slong-value';\nimport { IfdSRationalValue } from './ifd-value/ifd-srational-value';\nimport { IfdSShortValue } from './ifd-value/ifd-sshort-value';\nimport { IfdUndefinedValue } from './ifd-value/ifd-undefined-value';\nimport { IfdValue } from './ifd-value/ifd-value';\n\nexport class ExifData extends IfdContainer {\n public get imageIfd(): IfdDirectory {\n return this.get('ifd0');\n }\n\n public get thumbnailIfd(): IfdDirectory {\n return this.get('ifd1');\n }\n\n public get exifIfd(): IfdDirectory {\n return this.get('ifd0').sub.get('exif');\n }\n\n public get gpsIfd(): IfdDirectory {\n return this.get('ifd0').sub.get('gps');\n }\n\n public get interopIfd(): IfdDirectory {\n return this.get('ifd0').sub.get('interop');\n }\n\n public get dataSize(): number {\n return 8 + (this.directories.get('ifd0')?.dataSize ?? 0);\n }\n\n private writeDirectory(\n out: OutputBuffer,\n ifd: IfdDirectory,\n dataOffset: number\n ): number {\n let offset = dataOffset;\n const stripOffsetTag = ExifTagNameToID.get('StripOffsets');\n out.writeUint16(ifd.size);\n for (const tag of ifd.keys) {\n const value = ifd.getValue(tag)!;\n\n // Special-case StripOffsets, used by TIFF, that if it points to\n // Undefined value type, then its storing the image data and should\n // be translated to the StripOffsets long type.\n const tagType =\n tag === stripOffsetTag && value.type === IfdValueType.undefined\n ? IfdValueType.long\n : value.type;\n\n const tagLength =\n tag === stripOffsetTag && value.type === IfdValueType.undefined\n ? 1\n : value.length;\n\n out.writeUint16(tag);\n out.writeUint16(tagType);\n out.writeUint32(tagLength);\n\n let size = value.dataSize;\n if (size <= 4) {\n value.write(out);\n while (size < 4) {\n out.writeByte(0);\n size++;\n }\n } else {\n out.writeUint32(offset);\n offset += size;\n }\n }\n return offset;\n }\n\n private writeDirectoryLargeValues(\n out: OutputBuffer,\n ifd: IfdDirectory\n ): void {\n for (const value of ifd.values) {\n const size = value.dataSize;\n if (size > 4) {\n value.write(out);\n }\n }\n }\n\n private readEntry(block: InputBuffer, blockOffset: number): ExifEntry {\n const tag = block.readUint16();\n const format = block.readUint16();\n const count = block.readUint32();\n\n const entry = new ExifEntry(tag, undefined);\n\n if (format > Object.keys(IfdValueType).length) return entry;\n\n const f = format as IfdValueType;\n const fsize = IfdValueTypeSize[format];\n const size = count * fsize;\n\n const endOffset = block.offset + 4;\n\n if (size > 4) {\n const fieldOffset = block.readUint32();\n block.offset = fieldOffset + blockOffset;\n }\n\n if (block.offset + size > block.end) {\n return entry;\n }\n\n const data = block.readBytes(size);\n\n switch (f) {\n case IfdValueType.none:\n break;\n case IfdValueType.sByte:\n entry.value = IfdSByteValue.data(data, count);\n break;\n case IfdValueType.byte:\n entry.value = IfdByteValue.data(data, count);\n break;\n case IfdValueType.undefined:\n entry.value = IfdUndefinedValue.data(data, count);\n break;\n case IfdValueType.ascii:\n entry.value = IfdAsciiValue.data(data, count);\n break;\n case IfdValueType.short:\n entry.value = IfdShortValue.data(data, count);\n break;\n case IfdValueType.long:\n entry.value = IfdLongValue.data(data, count);\n break;\n case IfdValueType.rational:\n entry.value = IfdRationalValue.data(data, count);\n break;\n case IfdValueType.sRational:\n entry.value = IfdSRationalValue.data(data, count);\n break;\n case IfdValueType.sShort:\n entry.value = IfdSShortValue.data(data, count);\n break;\n case IfdValueType.sLong:\n entry.value = IfdSLongValue.data(data, count);\n break;\n case IfdValueType.single:\n entry.value = IfdSingleValue.data(data, count);\n break;\n case IfdValueType.double:\n entry.value = IfdDoubleValue.data(data, count);\n break;\n }\n\n block.offset = endOffset;\n\n return entry;\n }\n\n public static from(other: ExifData) {\n const dirs = new Map(other.directories);\n return new ExifData(dirs);\n }\n\n public static fromInputBuffer(input: InputBuffer) {\n const data = new ExifData();\n data.read(input);\n return data;\n }\n\n public hasTag(tag: number): boolean {\n for (const directory of this.directories.values()) {\n if (directory.has(tag)) {\n return true;\n }\n }\n return false;\n }\n\n public getTag(tag: number): IfdValue | undefined {\n for (const directory of this.directories.values()) {\n if (directory.has(tag)) {\n return directory.getValue(tag);\n }\n }\n return undefined;\n }\n\n public getTagName(tag: number): string {\n return ExifImageTags.get(tag)?.name ?? '';\n }\n\n public write(out: OutputBuffer): void {\n const saveEndian = out.bigEndian;\n out.bigEndian = true;\n\n // Tiff header\n // big endian\n out.writeUint16(0x4d4d);\n out.writeUint16(0x002a);\n // offset to first ifd block\n out.writeUint32(8);\n\n if (this.directories.get('ifd0') === undefined)\n this.directories.set('ifd0', new IfdDirectory());\n\n // offset to first ifd block, from start of tiff header\n let dataOffset = 8;\n const offsets = new Map();\n\n for (const [name, ifd] of this.directories) {\n offsets.set(name, dataOffset);\n\n if (ifd.sub.has('exif')) {\n ifd.setValue(0x8769, new IfdLongValue(0));\n } else {\n ifd.setValue(0x8769, undefined);\n }\n\n if (ifd.sub.has('interop')) {\n ifd.setValue(0xa005, new IfdLongValue(0));\n } else {\n ifd.setValue(0xa005, undefined);\n }\n\n if (ifd.sub.has('gps')) {\n ifd.setValue(0x8825, new IfdLongValue(0));\n } else {\n ifd.setValue(0x8825, undefined);\n }\n\n // ifd block size\n dataOffset += 2 + 12 * ifd.size + 4;\n\n // storage for large tag values\n for (const value of ifd.values) {\n const dataSize = value.dataSize;\n if (dataSize > 4) {\n dataOffset += dataSize;\n }\n }\n\n // storage for sub-ifd blocks\n for (const subName of ifd.sub.keys) {\n const subIfd = ifd.sub.get(subName);\n offsets.set(subName, dataOffset);\n let subSize = 2 + 12 * subIfd.size;\n for (const value of subIfd.values) {\n const dataSize = value.dataSize;\n if (dataSize > 4) {\n subSize += dataSize;\n }\n }\n dataOffset += subSize;\n }\n }\n\n const dirArray = Array.from(this.directories);\n for (let i = 0; i < dirArray.length; i++) {\n const [name, ifd] = dirArray[i];\n\n if (ifd.sub.has('exif')) {\n ifd.getValue(0x8769)!.setInt(offsets.get('exif')!);\n }\n\n if (ifd.sub.has('interop')) {\n ifd.getValue(0xa005)!.setInt(offsets.get('interop')!);\n }\n\n if (ifd.sub.has('gps')) {\n ifd.getValue(0x8825)!.setInt(offsets.get('gps')!);\n }\n\n const ifdOffset = offsets.get(name)!;\n const dataOffset = ifdOffset + 2 + 12 * ifd.size + 4;\n\n this.writeDirectory(out, ifd, dataOffset);\n\n if (i === dirArray.length - 1) {\n out.writeUint32(0);\n } else {\n const nextName = dirArray[i + 1][0];\n out.writeUint32(offsets.get(nextName)!);\n }\n\n this.writeDirectoryLargeValues(out, ifd);\n\n for (const subName of ifd.sub.keys) {\n const subIfd = ifd.sub.get(subName);\n const subOffset = offsets.get(subName)!;\n const dataOffset = subOffset + 2 + 12 * subIfd.size;\n this.writeDirectory(out, subIfd, dataOffset);\n this.writeDirectoryLargeValues(out, subIfd);\n }\n }\n\n out.bigEndian = saveEndian;\n }\n\n public read(block: InputBuffer): boolean {\n const saveEndian = block.bigEndian;\n block.bigEndian = true;\n\n const blockOffset = block.offset;\n\n // Tiff header\n const endian = block.readUint16();\n if (endian === 0x4949) {\n // II\n block.bigEndian = false;\n if (block.readUint16() !== 0x002a) {\n block.bigEndian = saveEndian;\n return false;\n }\n } else if (endian === 0x4d4d) {\n // MM\n block.bigEndian = true;\n if (block.readUint16() !== 0x002a) {\n block.bigEndian = saveEndian;\n return false;\n }\n } else {\n return false;\n }\n\n let ifdOffset = block.readUint32();\n\n // IFD blocks\n let index = 0;\n while (ifdOffset > 0) {\n block.offset = blockOffset + ifdOffset;\n\n const directory = new IfdDirectory();\n const numEntries = block.readUint16();\n\n const dir = new Array();\n for (let i = 0; i < numEntries; i++) {\n const entry = this.readEntry(block, blockOffset);\n dir.push(entry);\n }\n\n for (const entry of dir) {\n if (entry.value !== undefined) {\n directory.setValue(entry.tag, entry.value);\n }\n }\n this.directories.set(`ifd${index}`, directory);\n index++;\n\n ifdOffset = block.readUint32();\n }\n\n const subTags = new Map([\n [0x8769, 'exif'],\n [0xa005, 'interop'],\n [0x8825, 'gps'],\n ]);\n\n for (const d of this.directories.values()) {\n for (const dt of subTags.keys()) {\n // ExifOffset\n if (d.has(dt)) {\n const ifdOffset = d.getValue(dt)!.toInt();\n block.offset = blockOffset + ifdOffset;\n const directory = new IfdDirectory();\n const numEntries = block.readUint16();\n\n const dir = new Array();\n for (let i = 0; i < numEntries; i++) {\n const entry = this.readEntry(block, blockOffset);\n dir.push(entry);\n }\n\n for (const entry of dir) {\n if (entry.value !== undefined) {\n directory.setValue(entry.tag, entry.value!);\n }\n }\n d.sub.set(subTags.get(dt)!, directory);\n }\n }\n }\n\n block.bigEndian = saveEndian;\n return false;\n }\n\n public clone(): ExifData {\n return ExifData.from(this);\n }\n\n public toString(): string {\n let s = '';\n for (const [name, directory] of this.directories) {\n s += `${name}\\n`;\n for (const tag of directory.keys) {\n const value = directory.getValue(tag);\n if (value === undefined) {\n s += `\\t${this.getTagName(tag)}\\n`;\n } else {\n s += `\\t${this.getTagName(tag)}: ${value.toString()}\\n`;\n }\n }\n for (const subName of directory.sub.keys) {\n s += `${subName}\\n`;\n const subDirectory = directory.sub.get(subName);\n for (const tag of subDirectory.keys) {\n const value = subDirectory.getValue(tag);\n if (value === undefined) {\n s += `\\t${this.getTagName(tag)}\\n`;\n } else {\n s += `\\t${this.getTagName(tag)}: ${value}\\n`;\n }\n }\n }\n }\n return `${this.constructor.name} (${s})`;\n }\n}\n", "/** @format */\n\n/**\n * The pattern to use for dithering\n */\nexport enum DitherKernel {\n none,\n falseFloydSteinberg,\n floydSteinberg,\n stucki,\n atkinson,\n}\n\nexport const DitherKernels = [\n [\n [0, 0, 0],\n [0, 0, 0],\n [0, 0, 0],\n ],\n // FalseFloydSteinberg\n [\n [3 / 8, 1, 0],\n [3 / 8, 0, 1],\n [2 / 8, 1, 1],\n ],\n // FloydSteinberg\n [\n [7 / 16, 1, 0],\n [3 / 16, -1, 1],\n [5 / 16, 0, 1],\n [1 / 16, 1, 1],\n ],\n // Stucki\n [\n [8 / 42, 1, 0],\n [4 / 42, 2, 0],\n [2 / 42, -2, 1],\n [4 / 42, -1, 1],\n [8 / 42, 0, 1],\n [4 / 42, 1, 1],\n [2 / 42, 2, 1],\n [1 / 42, -2, 2],\n [2 / 42, -1, 2],\n [4 / 42, 0, 2],\n [2 / 42, 1, 2],\n [1 / 42, 2, 2],\n ],\n //Atkinson:\n [\n [1 / 8, 1, 0],\n [1 / 8, 2, 0],\n [1 / 8, -1, 1],\n [1 / 8, 0, 1],\n [1 / 8, 1, 1],\n [1 / 8, 0, 2],\n ],\n];\n", "/** @format */\n\n/**\n * The type of image this frame represents. Multi-page formats, such as\n * TIFF, can represent the frames of an animation as pages in a document.\n */\nexport enum FrameType {\n /**\n * The frames of this document are to be interpreted as animation.\n */\n animation,\n\n /**\n * The frames of this document are to be interpreted as pages of a document.\n */\n page,\n\n /**\n * The frames of this document are to be interpreted as a sequence of images.\n */\n sequence,\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color, ColorConvertOptions } from '../color/color';\nimport { ColorUtils } from '../color/color-utils';\nimport { Format } from '../color/format';\nimport { ArrayUtils } from '../common/array-utils';\nimport { Float16 } from '../common/float16';\nimport { MemoryImage } from './image';\nimport { MemoryImageDataFloat16 } from './image-data-float16';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\nexport class PixelFloat16 implements Pixel, Iterable, Iterator {\n private _index: number;\n\n private readonly _image: MemoryImageDataFloat16;\n public get image(): MemoryImageDataFloat16 {\n return this._image;\n }\n\n private _x: number;\n public get x(): number {\n return this._x;\n }\n\n private _y: number;\n public get y(): number {\n return this._y;\n }\n\n public get xNormalized(): number {\n return this.width > 1 ? this._x / (this.width - 1) : 0;\n }\n\n public get yNormalized(): number {\n return this.height > 1 ? this._y / (this.height - 1) : 0;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get data(): Uint16Array {\n return this._image.data;\n }\n\n public get isValid(): boolean {\n return (\n this._x >= 0 &&\n this._x < this._image.width - 1 &&\n this._y >= 0 &&\n this._y < this._image.height - 1\n );\n }\n\n public get width(): number {\n return this._image.width;\n }\n\n public get height(): number {\n return this._image.width;\n }\n\n public get length(): number {\n return this._image.numChannels;\n }\n\n public get numChannels(): number {\n return this._image.numChannels;\n }\n\n public get maxChannelValue(): number {\n return this._image.maxChannelValue;\n }\n\n public get maxIndexValue(): number {\n return this._image.maxIndexValue;\n }\n\n public get format(): Format {\n return Format.float16;\n }\n\n public get isLdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get isHdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get hasPalette(): boolean {\n return this._image.hasPalette;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get r(): number {\n return this.numChannels > 0\n ? Float16.float16ToDouble(this.data[this._index])\n : 0;\n }\n public set r(r: number) {\n if (this.numChannels > 0) {\n this.data[this._index] = Float16.doubleToFloat16(r);\n }\n }\n\n public get g(): number {\n return this.numChannels > 1\n ? Float16.float16ToDouble(this.data[this._index + 1])\n : 0;\n }\n public set g(g: number) {\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Float16.doubleToFloat16(g);\n }\n }\n\n public get b(): number {\n return this.numChannels > 2\n ? Float16.float16ToDouble(this.data[this._index + 2])\n : 0;\n }\n public set b(b: number) {\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Float16.doubleToFloat16(b);\n }\n }\n\n public get a(): number {\n return this.numChannels > 3\n ? Float16.float16ToDouble(this.data[this._index + 3])\n : 0;\n }\n public set a(a: number) {\n if (this.numChannels > 3) {\n this.data[this._index + 3] = Float16.doubleToFloat16(a);\n }\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(\n x: number,\n y: number,\n index: number,\n image: MemoryImageDataFloat16\n ) {\n this._image = image;\n this._index = index;\n this._x = x;\n this._y = y;\n }\n\n public static imageData(image: MemoryImageDataFloat16) {\n return new PixelFloat16(-1, 0, -image.numChannels, image);\n }\n\n public static image(image: MemoryImage) {\n return new PixelFloat16(\n -1,\n 0,\n -image.numChannels,\n image.data instanceof MemoryImageDataFloat16\n ? (image.data as MemoryImageDataFloat16)\n : new MemoryImageDataFloat16(0, 0, 0)\n );\n }\n\n public static from(other: PixelFloat16) {\n return new PixelFloat16(other.x, other.y, other._index, other.image);\n }\n\n public next(): IteratorResult {\n this._x++;\n if (this._x === this.width) {\n this._x = 0;\n this._y++;\n if (this._y === this.height) {\n return >{\n done: true,\n value: this,\n };\n }\n }\n this._index += this.numChannels;\n return >{\n done: this._index >= this.image.data.length,\n value: this,\n };\n }\n\n public setPosition(x: number, y: number): void {\n this._x = x;\n this._y = y;\n this._index =\n this._y * this._image.width * this._image.numChannels +\n this._x * this._image.numChannels;\n }\n\n public setPositionNormalized(x: number, y: number): void {\n return this.setPosition(\n Math.floor(x * (this.width - 1)),\n Math.floor(y * (this.height - 1))\n );\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.numChannels\n ? Float16.float16ToDouble(this.data[this._index + channel])\n : 0;\n }\n }\n\n public getChannelNormalized(channel: Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(channel: number, value: number): void {\n if (channel < this.numChannels) {\n this.data[this._index + channel] = Float16.doubleToFloat16(value);\n }\n }\n\n public set(color: Color): void {\n if (this.numChannels > 0) {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n this.a = color.a;\n }\n }\n\n public setRgb(r: number, g: number, b: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Float16.doubleToFloat16(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Float16.doubleToFloat16(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Float16.doubleToFloat16(b);\n }\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Float16.doubleToFloat16(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Float16.doubleToFloat16(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Float16.doubleToFloat16(b);\n if (this.numChannels > 3) {\n this.data[this._index + 3] = Float16.doubleToFloat16(a);\n }\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public equals(other: Pixel | number[]): boolean {\n if (other instanceof PixelFloat16) {\n return ArrayUtils.equals(this.toArray(), other.toArray());\n }\n if (Array.isArray(other)) {\n return ArrayUtils.equals(this.toArray(), other);\n }\n return false;\n }\n\n public clone(): PixelFloat16 {\n return PixelFloat16.from(this);\n }\n\n public convert(opt: ColorConvertOptions): Color {\n return ColorUtils.convertColor({\n from: this,\n format: opt.format,\n numChannels: opt.numChannels,\n alpha: opt.alpha,\n });\n }\n\n public [Symbol.iterator](): Iterator {\n return this;\n }\n}\n", "/** @format */\n\nimport { Pixel } from './pixel';\n\nexport class PixelRangeIterator implements Iterator {\n private _pixel: Pixel;\n private _x1: number;\n private _y1: number;\n private _x2: number;\n private _y2: number;\n\n constructor(\n pixel: Pixel,\n x: number,\n y: number,\n width: number,\n height: number\n ) {\n this._pixel = pixel;\n this._x1 = x;\n this._y1 = y;\n this._x2 = x + width - 1;\n this._y2 = y + height - 1;\n this._pixel.setPosition(x - 1, y);\n }\n\n public next(): IteratorResult {\n if (this._pixel.x + 1 > this._x2) {\n this._pixel.setPosition(this._x1, this._pixel.y + 1);\n return {\n done: this._pixel.y > this._y2,\n value: this._pixel,\n };\n }\n return this._pixel.next();\n }\n\n public [Symbol.iterator](): IterableIterator {\n return this;\n }\n}\n", "/** @format */\n\nimport { ChannelOrder } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { Format, FormatType } from '../color/format';\nimport { MemoryImageData } from './image-data';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\nimport { PixelFloat16 } from './pixel-float16';\nimport { PixelRangeIterator } from './pixel-range-iterator';\nimport { ColorFloat16 } from '../color/color-float16';\nimport { Float16 } from '../common/float16';\n\nexport class MemoryImageDataFloat16\n implements MemoryImageData, Iterable\n{\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _data: Uint16Array;\n public get data(): Uint16Array {\n return this._data;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get format(): Format {\n return Format.float16;\n }\n\n public get formatType(): FormatType {\n return FormatType.float;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get rowStride(): number {\n return this._width * this._numChannels * 2;\n }\n\n public get iterator(): PixelFloat16 {\n return PixelFloat16.imageData(this);\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get length(): number {\n return this._data.byteLength;\n }\n\n public get maxChannelValue(): number {\n return 1;\n }\n\n public get maxIndexValue(): number {\n return 1;\n }\n\n public get hasPalette(): boolean {\n return this.palette !== undefined;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get isLdrFormat(): boolean {\n return !this.isHdrFormat;\n }\n\n public get bitsPerChannel(): number {\n return 16;\n }\n\n constructor(\n width: number,\n height: number,\n numChannels: number,\n data?: Uint16Array\n ) {\n this._width = width;\n this._height = height;\n this._numChannels = numChannels;\n this._data =\n data ?? new Uint16Array(this._width * this._height * this._numChannels);\n }\n\n public static from(\n other: MemoryImageDataFloat16,\n skipPixels = false\n ): MemoryImageDataFloat16 {\n const data = skipPixels\n ? new Uint16Array(other.data.length)\n : other.data.slice();\n return new MemoryImageDataFloat16(\n other.width,\n other.height,\n other._numChannels,\n data\n );\n }\n\n public getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator {\n return new PixelRangeIterator(\n PixelFloat16.imageData(this),\n x,\n y,\n width,\n height\n );\n }\n\n public getColor(r: number, g: number, b: number, a?: number): Color {\n return a === undefined\n ? ColorFloat16.rgb(r, g, b)\n : ColorFloat16.rgba(r, g, b, a);\n }\n\n public getPixel(x: number, y: number, pixel?: Pixel): Pixel {\n let p = pixel;\n if (p === undefined || !(p instanceof PixelFloat16) || p.image !== this) {\n p = PixelFloat16.imageData(this);\n }\n p.setPosition(x, y);\n return p;\n }\n\n public setPixel(x: number, y: number, p: Color): void {\n this.setPixelRgba(x, y, p.r, p.g, p.b, p.a);\n }\n\n public setPixelR(x: number, y: number, r: number): void {\n const index = y * this._width * this._numChannels + x * this.numChannels;\n this.data[index] = Float16.doubleToFloat16(r);\n }\n\n public setPixelRgb(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n const index = y * this._width * this._numChannels + x * this._numChannels;\n this._data[index] = Float16.doubleToFloat16(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Float16.doubleToFloat16(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Float16.doubleToFloat16(b);\n }\n }\n }\n\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n const index = y * this._width * this._numChannels + x * this._numChannels;\n this._data[index] = Float16.doubleToFloat16(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Float16.doubleToFloat16(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Float16.doubleToFloat16(b);\n if (this._numChannels > 3) {\n this._data[index + 3] = Float16.doubleToFloat16(a);\n }\n }\n }\n }\n\n public setPixelRgbSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgb(x, y, r, g, b);\n }\n\n public setPixelRgbaSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgba(x, y, r, g, b, a);\n }\n\n public clear(_c?: Color): void {}\n\n public clone(skipPixels = false): MemoryImageDataFloat16 {\n return MemoryImageDataFloat16.from(this, skipPixels);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n\n public getBytes(order?: ChannelOrder | undefined): Uint8Array {\n if (order === undefined) {\n return this.toUint8Array();\n }\n\n if (this.numChannels === 4) {\n if (\n order === ChannelOrder.abgr ||\n order === ChannelOrder.argb ||\n order === ChannelOrder.bgra\n ) {\n const tempImage = this.clone();\n if (order === ChannelOrder.abgr) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (order === ChannelOrder.argb) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (order === ChannelOrder.bgra) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n return tempImage.toUint8Array();\n }\n } else if (this.numChannels === 3) {\n if (order === ChannelOrder.bgr) {\n const tempImage = this.clone();\n for (const p of tempImage) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n return tempImage.toUint8Array();\n }\n }\n\n return this.toUint8Array();\n }\n\n public toString(): string {\n return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return PixelFloat16.imageData(this);\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color, ColorConvertOptions } from '../color/color';\nimport { ColorUtils } from '../color/color-utils';\nimport { Format } from '../color/format';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MemoryImage } from './image';\nimport { MemoryImageDataFloat32 } from './image-data-float32';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\nexport class PixelFloat32 implements Pixel, Iterable, Iterator {\n private _index: number;\n\n private readonly _image: MemoryImageDataFloat32;\n public get image(): MemoryImageDataFloat32 {\n return this._image;\n }\n\n private _x: number;\n public get x(): number {\n return this._x;\n }\n\n private _y: number;\n public get y(): number {\n return this._y;\n }\n\n public get xNormalized(): number {\n return this.width > 1 ? this._x / (this.width - 1) : 0;\n }\n\n public get yNormalized(): number {\n return this.height > 1 ? this._y / (this.height - 1) : 0;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get data(): Float32Array {\n return this._image.data;\n }\n\n public get isValid(): boolean {\n return (\n this._x >= 0 &&\n this._x < this._image.width - 1 &&\n this._y >= 0 &&\n this._y < this._image.height - 1\n );\n }\n\n public get width(): number {\n return this._image.width;\n }\n\n public get height(): number {\n return this._image.width;\n }\n\n public get length(): number {\n return this._image.numChannels;\n }\n\n public get numChannels(): number {\n return this._image.numChannels;\n }\n\n public get maxChannelValue(): number {\n return this._image.maxChannelValue;\n }\n\n public get maxIndexValue(): number {\n return this._image.maxIndexValue;\n }\n\n public get format(): Format {\n return Format.float32;\n }\n\n public get isLdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get isHdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get hasPalette(): boolean {\n return this._image.hasPalette;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get r(): number {\n return this.numChannels > 0 ? this.data[this._index] : 0;\n }\n public set r(r: number) {\n if (this.numChannels > 0) {\n this.data[this._index] = r;\n }\n }\n\n public get g(): number {\n return this.numChannels > 1 ? this.data[this._index + 1] : 0;\n }\n public set g(g: number) {\n if (this.numChannels > 1) {\n this.data[this._index + 1] = g;\n }\n }\n\n public get b(): number {\n return this.numChannels > 2 ? this.data[this._index + 2] : 0;\n }\n public set b(b: number) {\n if (this.numChannels > 2) {\n this.data[this._index + 2] = b;\n }\n }\n\n public get a(): number {\n return this.numChannels > 3 ? this.data[this._index + 3] : 1;\n }\n public set a(a: number) {\n if (this.numChannels > 3) {\n this.data[this._index + 3] = a;\n }\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(\n x: number,\n y: number,\n index: number,\n image: MemoryImageDataFloat32\n ) {\n this._image = image;\n this._index = index;\n this._x = x;\n this._y = y;\n }\n\n public static imageData(image: MemoryImageDataFloat32) {\n return new PixelFloat32(-1, 0, -image.numChannels, image);\n }\n\n public static image(image: MemoryImage) {\n return new PixelFloat32(\n -1,\n 0,\n -image.numChannels,\n image.data instanceof MemoryImageDataFloat32\n ? (image.data as MemoryImageDataFloat32)\n : new MemoryImageDataFloat32(0, 0, 0)\n );\n }\n\n public static from(other: PixelFloat32) {\n return new PixelFloat32(other.x, other.y, other._index, other.image);\n }\n\n public next(): IteratorResult {\n this._x++;\n if (this._x === this.width) {\n this._x = 0;\n this._y++;\n if (this._y === this.height) {\n return >{\n done: true,\n value: this,\n };\n }\n }\n this._index += this.numChannels;\n return >{\n done: this._index >= this.image.data.length,\n value: this,\n };\n }\n\n public setPosition(x: number, y: number): void {\n this._x = x;\n this._y = y;\n this._index =\n this._y * this._image.width * this._image.numChannels +\n this._x * this._image.numChannels;\n }\n\n public setPositionNormalized(x: number, y: number): void {\n return this.setPosition(\n Math.floor(x * (this.width - 1)),\n Math.floor(y * (this.height - 1))\n );\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.numChannels ? this.data[this._index + channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(channel: number, value: number): void {\n if (channel < this.numChannels) {\n this.data[this._index + channel] = value;\n }\n }\n\n public set(color: Color): void {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n this.a = color.a;\n }\n\n public setRgb(r: number, g: number, b: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = r;\n if (this.numChannels > 1) {\n this.data[this._index + 1] = g;\n if (this.numChannels > 2) {\n this.data[this._index + 2] = b;\n }\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = r;\n if (this.numChannels > 1) {\n this.data[this._index + 1] = g;\n if (this.numChannels > 2) {\n this.data[this._index + 2] = b;\n if (this.numChannels > 3) {\n this.data[this._index + 3] = a;\n }\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public equals(other: Pixel | number[]): boolean {\n if (other instanceof PixelFloat32) {\n return ArrayUtils.equals(this.toArray(), other.toArray());\n }\n if (Array.isArray(other)) {\n return ArrayUtils.equals(this.toArray(), other);\n }\n return false;\n }\n\n public clone(): PixelFloat32 {\n return PixelFloat32.from(this);\n }\n\n public convert(opt: ColorConvertOptions): Color {\n return ColorUtils.convertColor({\n from: this,\n format: opt.format,\n numChannels: opt.numChannels,\n alpha: opt.alpha,\n });\n }\n\n public toString(): string {\n return `${this.constructor.name} (${this.toArray()})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return this;\n }\n}\n", "/** @format */\n\nimport { ChannelOrder } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { Format, FormatType } from '../color/format';\nimport { MemoryImageData } from './image-data';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\nimport { PixelFloat32 } from './pixel-float32';\nimport { PixelRangeIterator } from './pixel-range-iterator';\nimport { ColorFloat32 } from '../color/color-float32';\n\nexport class MemoryImageDataFloat32\n implements MemoryImageData, Iterable\n{\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _data: Float32Array;\n public get data(): Float32Array {\n return this._data;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get format(): Format {\n return Format.float32;\n }\n\n public get formatType(): FormatType {\n return FormatType.float;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get rowStride(): number {\n return this._width * this._numChannels * 4;\n }\n\n public get iterator(): PixelFloat32 {\n return PixelFloat32.imageData(this);\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get length(): number {\n return this._data.byteLength;\n }\n\n public get maxChannelValue(): number {\n return 1;\n }\n\n public get maxIndexValue(): number {\n return 1;\n }\n\n public get hasPalette(): boolean {\n return this.palette !== undefined;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get isLdrFormat(): boolean {\n return !this.isHdrFormat;\n }\n\n public get bitsPerChannel(): number {\n return 32;\n }\n\n constructor(\n width: number,\n height: number,\n numChannels: number,\n data?: Float32Array\n ) {\n this._width = width;\n this._height = height;\n this._numChannels = numChannels;\n this._data =\n data ?? new Float32Array(this._width * this._height * this._numChannels);\n }\n\n public static from(\n other: MemoryImageDataFloat32,\n skipPixels = false\n ): MemoryImageDataFloat32 {\n const data = skipPixels\n ? new Float32Array(other.data.length)\n : other.data.slice();\n return new MemoryImageDataFloat32(\n other.width,\n other.height,\n other._numChannels,\n data\n );\n }\n\n public getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator {\n return new PixelRangeIterator(\n PixelFloat32.imageData(this),\n x,\n y,\n width,\n height\n );\n }\n\n public getColor(r: number, g: number, b: number, a?: number): Color {\n return a === undefined\n ? ColorFloat32.rgb(r, g, b)\n : ColorFloat32.rgba(r, g, b, a);\n }\n\n public getPixel(x: number, y: number, pixel?: Pixel): Pixel {\n let p = pixel;\n if (p === undefined || !(p instanceof PixelFloat32) || p.image !== this) {\n p = PixelFloat32.imageData(this);\n }\n p.setPosition(x, y);\n return p;\n }\n\n public setPixel(x: number, y: number, p: Color): void {\n this.setPixelRgba(x, y, p.r, p.g, p.b, p.a);\n }\n\n public setPixelR(x: number, y: number, r: number): void {\n const index = y * this._width * this._numChannels + x * this.numChannels;\n this.data[index] = r;\n }\n\n public setPixelRgb(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n const index = y * this._width * this._numChannels + x * this._numChannels;\n this._data[index] = r;\n if (this._numChannels > 1) {\n this._data[index + 1] = g;\n if (this._numChannels > 2) {\n this._data[index + 2] = b;\n }\n }\n }\n\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n const index = y * this._width * this._numChannels + x * this._numChannels;\n this._data[index] = r;\n if (this._numChannels > 1) {\n this._data[index + 1] = g;\n if (this._numChannels > 2) {\n this._data[index + 2] = b;\n if (this._numChannels > 3) {\n this._data[index + 3] = a;\n }\n }\n }\n }\n\n public setPixelRgbSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgb(x, y, r, g, b);\n }\n\n public setPixelRgbaSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgba(x, y, r, g, b, a);\n }\n\n public clear(_c?: Color): void {}\n\n public clone(skipPixels = false): MemoryImageDataFloat32 {\n return MemoryImageDataFloat32.from(this, skipPixels);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n\n public getBytes(order?: ChannelOrder | undefined): Uint8Array {\n if (order === undefined) {\n return this.toUint8Array();\n }\n\n if (this.numChannels === 4) {\n if (\n order === ChannelOrder.abgr ||\n order === ChannelOrder.argb ||\n order === ChannelOrder.bgra\n ) {\n const tempImage = this.clone();\n if (order === ChannelOrder.abgr) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (order === ChannelOrder.argb) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (order === ChannelOrder.bgra) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n return tempImage.toUint8Array();\n }\n } else if (this.numChannels === 3) {\n if (order === ChannelOrder.bgr) {\n const tempImage = this.clone();\n for (const p of tempImage) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n return tempImage.toUint8Array();\n }\n }\n\n return this.toUint8Array();\n }\n\n public toString(): string {\n return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return PixelFloat32.imageData(this);\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color, ColorConvertOptions } from '../color/color';\nimport { ColorUtils } from '../color/color-utils';\nimport { Format } from '../color/format';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MemoryImage } from './image';\nimport { MemoryImageDataFloat64 } from './image-data-float64';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\nexport class PixelFloat64 implements Pixel, Iterable, Iterator {\n private _index: number;\n\n private readonly _image: MemoryImageDataFloat64;\n public get image(): MemoryImageDataFloat64 {\n return this._image;\n }\n\n private _x: number;\n public get x(): number {\n return this._x;\n }\n\n private _y: number;\n public get y(): number {\n return this._y;\n }\n\n public get xNormalized(): number {\n return this.width > 1 ? this._x / (this.width - 1) : 0;\n }\n\n public get yNormalized(): number {\n return this.height > 1 ? this._y / (this.height - 1) : 0;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get data(): Float64Array {\n return this._image.data;\n }\n\n public get isValid(): boolean {\n return (\n this._x >= 0 &&\n this._x < this._image.width - 1 &&\n this._y >= 0 &&\n this._y < this._image.height - 1\n );\n }\n\n public get width(): number {\n return this._image.width;\n }\n\n public get height(): number {\n return this._image.width;\n }\n\n public get length(): number {\n return this._image.numChannels;\n }\n\n public get numChannels(): number {\n return this._image.numChannels;\n }\n\n public get maxChannelValue(): number {\n return this._image.maxChannelValue;\n }\n\n public get maxIndexValue(): number {\n return this._image.maxIndexValue;\n }\n\n public get format(): Format {\n return Format.float64;\n }\n\n public get isLdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get isHdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get hasPalette(): boolean {\n return this._image.hasPalette;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get r(): number {\n return this.numChannels > 0 ? this.data[this._index] : 0;\n }\n public set r(r: number) {\n if (this.numChannels > 0) {\n this.data[this._index] = r;\n }\n }\n\n public get g(): number {\n return this.numChannels > 1 ? this.data[this._index + 1] : 0;\n }\n public set g(g: number) {\n if (this.numChannels > 1) {\n this.data[this._index + 1] = g;\n }\n }\n\n public get b(): number {\n return this.numChannels > 2 ? this.data[this._index + 2] : 0;\n }\n public set b(b: number) {\n if (this.numChannels > 2) {\n this.data[this._index + 2] = b;\n }\n }\n\n public get a(): number {\n return this.numChannels > 3 ? this.data[this._index + 3] : 0;\n }\n public set a(a: number) {\n if (this.numChannels > 3) {\n this.data[this._index + 3] = a;\n }\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(\n x: number,\n y: number,\n index: number,\n image: MemoryImageDataFloat64\n ) {\n this._image = image;\n this._index = index;\n this._x = x;\n this._y = y;\n }\n\n public static imageData(image: MemoryImageDataFloat64) {\n return new PixelFloat64(-1, 0, -image.numChannels, image);\n }\n\n public static image(image: MemoryImage) {\n return new PixelFloat64(\n -1,\n 0,\n -image.numChannels,\n image.data instanceof MemoryImageDataFloat64\n ? (image.data as MemoryImageDataFloat64)\n : new MemoryImageDataFloat64(0, 0, 0)\n );\n }\n\n public static from(other: PixelFloat64) {\n return new PixelFloat64(other.x, other.y, other._index, other.image);\n }\n\n [Symbol.iterator](): Iterator {\n return this;\n }\n\n public next(): IteratorResult {\n this._x++;\n if (this._x === this.width) {\n this._x = 0;\n this._y++;\n if (this._y === this.height) {\n return >{\n done: true,\n value: this,\n };\n }\n }\n this._index += this.numChannels;\n return >{\n done: this._index >= this.image.data.length,\n value: this,\n };\n }\n\n public setPosition(x: number, y: number): void {\n this._x = x;\n this._y = y;\n this._index =\n this._y * this._image.width * this._image.numChannels +\n this._x * this._image.numChannels;\n }\n\n public setPositionNormalized(x: number, y: number): void {\n return this.setPosition(\n Math.floor(x * (this.width - 1)),\n Math.floor(y * (this.height - 1))\n );\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.numChannels ? this.data[this._index + channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(channel: number, value: number): void {\n if (channel < this.numChannels) {\n this.data[this._index + channel] = value;\n }\n }\n\n public set(color: Color): void {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n this.a = color.a;\n }\n\n public setRgb(r: number, g: number, b: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = r;\n if (this.numChannels > 1) {\n this.data[this._index + 1] = g;\n if (this.numChannels > 2) {\n this.data[this._index + 2] = b;\n }\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = r;\n if (this.numChannels > 1) {\n this.data[this._index + 1] = g;\n if (this.numChannels > 2) {\n this.data[this._index + 2] = b;\n if (this.numChannels > 3) {\n this.data[this._index + 3] = a;\n }\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public equals(other: Pixel | number[]): boolean {\n if (other instanceof PixelFloat64) {\n return ArrayUtils.equals(this.toArray(), other.toArray());\n }\n if (Array.isArray(other)) {\n return ArrayUtils.equals(this.toArray(), other);\n }\n return false;\n }\n\n public clone(): PixelFloat64 {\n return PixelFloat64.from(this);\n }\n\n public convert(opt: ColorConvertOptions): Color {\n return ColorUtils.convertColor({\n from: this,\n format: opt.format,\n numChannels: opt.numChannels,\n alpha: opt.alpha,\n });\n }\n\n public toString(): string {\n return `${this.constructor.name} (${this.toArray()})`;\n }\n}\n", "/** @format */\n\nimport { ChannelOrder } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { Format, FormatType } from '../color/format';\nimport { MemoryImageData } from './image-data';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\nimport { PixelFloat64 } from './pixel-float64';\nimport { PixelRangeIterator } from './pixel-range-iterator';\nimport { ColorFloat64 } from '../color/color-float64';\n\nexport class MemoryImageDataFloat64\n implements MemoryImageData, Iterable\n{\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _data: Float64Array;\n public get data(): Float64Array {\n return this._data;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get format(): Format {\n return Format.float64;\n }\n\n public get formatType(): FormatType {\n return FormatType.float;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get rowStride(): number {\n return this._width * this._numChannels * 8;\n }\n\n public get iterator(): PixelFloat64 {\n return PixelFloat64.imageData(this);\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get length(): number {\n return this._data.byteLength;\n }\n\n public get maxChannelValue(): number {\n return 1;\n }\n\n public get maxIndexValue(): number {\n return 1;\n }\n\n public get hasPalette(): boolean {\n return this.palette !== undefined;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get isLdrFormat(): boolean {\n return !this.isHdrFormat;\n }\n\n public get bitsPerChannel(): number {\n return 64;\n }\n\n constructor(\n width: number,\n height: number,\n numChannels: number,\n data?: Float64Array\n ) {\n this._width = width;\n this._height = height;\n this._numChannels = numChannels;\n this._data =\n data ??\n new Float64Array(this._width * this._height * 4 * this._numChannels);\n }\n\n public static from(\n other: MemoryImageDataFloat64,\n skipPixels = false\n ): MemoryImageDataFloat64 {\n const data = skipPixels\n ? new Float64Array(other.data.length)\n : other.data.slice();\n return new MemoryImageDataFloat64(\n other.width,\n other.height,\n other._numChannels,\n data\n );\n }\n\n public getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator {\n return new PixelRangeIterator(\n PixelFloat64.imageData(this),\n x,\n y,\n width,\n height\n );\n }\n\n public getColor(r: number, g: number, b: number, a?: number): Color {\n return a === undefined\n ? ColorFloat64.rgb(r, g, b)\n : ColorFloat64.rgba(r, g, b, a);\n }\n\n public getPixel(x: number, y: number, pixel?: Pixel): Pixel {\n let p = pixel;\n if (p === undefined || !(p instanceof PixelFloat64) || p.image !== this) {\n p = PixelFloat64.imageData(this);\n }\n p.setPosition(x, y);\n return p;\n }\n\n public setPixel(x: number, y: number, p: Color): void {\n this.setPixelRgba(x, y, p.r, p.g, p.b, p.a);\n }\n\n public setPixelR(x: number, y: number, r: number): void {\n const index = y * this._width * this._numChannels + x * this.numChannels;\n this.data[index] = r;\n }\n\n public setPixelRgb(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n const index = y * this._width * this._numChannels + x * this._numChannels;\n this._data[index] = r;\n if (this._numChannels > 1) {\n this._data[index + 1] = g;\n if (this._numChannels > 2) {\n this._data[index + 2] = b;\n }\n }\n }\n\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n const index = y * this._width * this._numChannels + x * this._numChannels;\n this._data[index] = r;\n if (this._numChannels > 1) {\n this._data[index + 1] = g;\n if (this._numChannels > 2) {\n this._data[index + 2] = b;\n if (this._numChannels > 3) {\n this._data[index + 3] = a;\n }\n }\n }\n }\n\n public setPixelRgbSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgb(x, y, r, g, b);\n }\n\n public setPixelRgbaSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgba(x, y, r, g, b, a);\n }\n\n public clear(_c?: Color): void {}\n\n public clone(skipPixels = false): MemoryImageDataFloat64 {\n return MemoryImageDataFloat64.from(this, skipPixels);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n\n public getBytes(order?: ChannelOrder | undefined): Uint8Array {\n if (order === undefined) {\n return this.toUint8Array();\n }\n\n if (this.numChannels === 4) {\n if (\n order === ChannelOrder.abgr ||\n order === ChannelOrder.argb ||\n order === ChannelOrder.bgra\n ) {\n const tempImage = this.clone();\n if (order === ChannelOrder.abgr) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (order === ChannelOrder.argb) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (order === ChannelOrder.bgra) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n return tempImage.toUint8Array();\n }\n } else if (this.numChannels === 3) {\n if (order === ChannelOrder.bgr) {\n const tempImage = this.clone();\n for (const p of tempImage) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n return tempImage.toUint8Array();\n }\n }\n\n return this.toUint8Array();\n }\n\n public toString(): string {\n return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return PixelFloat64.imageData(this);\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color, ColorConvertOptions } from '../color/color';\nimport { ColorUtils } from '../color/color-utils';\nimport { Format } from '../color/format';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MemoryImage } from './image';\nimport { MemoryImageDataInt16 } from './image-data-int16';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\nexport class PixelInt16 implements Pixel, Iterable, Iterator {\n private _index: number;\n\n private readonly _image: MemoryImageDataInt16;\n public get image(): MemoryImageDataInt16 {\n return this._image;\n }\n\n private _x: number;\n public get x(): number {\n return this._x;\n }\n\n private _y: number;\n public get y(): number {\n return this._y;\n }\n\n public get xNormalized(): number {\n return this.width > 1 ? this._x / (this.width - 1) : 0;\n }\n\n public get yNormalized(): number {\n return this.height > 1 ? this._y / (this.height - 1) : 0;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get data(): Int16Array {\n return this._image.data;\n }\n\n public get isValid(): boolean {\n return (\n this._x >= 0 &&\n this._x < this._image.width - 1 &&\n this._y >= 0 &&\n this._y < this._image.height - 1\n );\n }\n\n public get width(): number {\n return this._image.width;\n }\n\n public get height(): number {\n return this._image.width;\n }\n\n public get length(): number {\n return this._image.numChannels;\n }\n\n public get numChannels(): number {\n return this._image.numChannels;\n }\n\n public get maxChannelValue(): number {\n return this._image.maxChannelValue;\n }\n\n public get maxIndexValue(): number {\n return this._image.maxIndexValue;\n }\n\n public get format(): Format {\n return Format.int16;\n }\n\n public get isLdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get isHdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get hasPalette(): boolean {\n return this._image.hasPalette;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get r(): number {\n return this.numChannels > 0 ? this.data[this._index] : 0;\n }\n public set r(r: number) {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n }\n }\n\n public get g(): number {\n return this.numChannels > 1 ? this.data[this._index + 1] : 0;\n }\n public set g(g: number) {\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n }\n }\n\n public get b(): number {\n return this.numChannels > 2 ? this.data[this._index + 2] : 0;\n }\n public set b(b: number) {\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n }\n }\n\n public get a(): number {\n return this.numChannels > 3 ? this.data[this._index + 3] : 0;\n }\n public set a(a: number) {\n if (this.numChannels > 3) {\n this.data[this._index + 3] = Math.trunc(a);\n }\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(\n x: number,\n y: number,\n index: number,\n image: MemoryImageDataInt16\n ) {\n this._image = image;\n this._index = index;\n this._x = x;\n this._y = y;\n }\n\n public static imageData(image: MemoryImageDataInt16) {\n return new PixelInt16(-1, 0, -image.numChannels, image);\n }\n\n public static image(image: MemoryImage) {\n return new PixelInt16(\n -1,\n 0,\n -image.numChannels,\n image.data instanceof MemoryImageDataInt16\n ? (image.data as MemoryImageDataInt16)\n : new MemoryImageDataInt16(0, 0, 0)\n );\n }\n\n public static from(other: PixelInt16) {\n return new PixelInt16(other.x, other.y, other._index, other.image);\n }\n\n public next(): IteratorResult {\n this._x++;\n if (this._x === this.width) {\n this._x = 0;\n this._y++;\n if (this._y === this.height) {\n return >{\n done: true,\n value: this,\n };\n }\n }\n this._index += this.numChannels;\n return >{\n done: this._index >= this.image.data.length,\n value: this,\n };\n }\n\n public setPosition(x: number, y: number): void {\n this._x = x;\n this._y = y;\n this._index =\n this._y * this._image.width * this._image.numChannels +\n this._x * this._image.numChannels;\n }\n\n public setPositionNormalized(x: number, y: number): void {\n return this.setPosition(\n Math.floor(x * (this.width - 1)),\n Math.floor(y * (this.height - 1))\n );\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.numChannels ? this.data[this._index + channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(channel: number, value: number): void {\n if (channel < this.numChannels) {\n this.data[this._index + channel] = Math.trunc(value);\n }\n }\n\n public set(color: Color): void {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n this.a = color.a;\n }\n\n public setRgb(r: number, g: number, b: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n }\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n if (this.numChannels > 3) {\n this.data[this._index + 3] = Math.trunc(a);\n }\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public equals(other: Pixel | number[]): boolean {\n if (other instanceof PixelInt16) {\n return ArrayUtils.equals(this.toArray(), other.toArray());\n }\n if (Array.isArray(other)) {\n return ArrayUtils.equals(this.toArray(), other);\n }\n return false;\n }\n\n public clone(): PixelInt16 {\n return PixelInt16.from(this);\n }\n\n public convert(opt: ColorConvertOptions): Color {\n return ColorUtils.convertColor({\n from: this,\n format: opt.format,\n numChannels: opt.numChannels,\n alpha: opt.alpha,\n });\n }\n\n public toString(): string {\n return `${this.constructor.name} (${this.toArray()})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return this;\n }\n}\n", "/** @format */\n\nimport { ChannelOrder } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { ColorInt16 } from '../color/color-int16';\nimport { Format, FormatType } from '../color/format';\nimport { MemoryImageData } from './image-data';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\nimport { PixelInt16 } from './pixel-int16';\nimport { PixelRangeIterator } from './pixel-range-iterator';\n\nexport class MemoryImageDataInt16 implements MemoryImageData, Iterable {\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _data: Int16Array;\n public get data(): Int16Array {\n return this._data;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get format(): Format {\n return Format.int16;\n }\n\n public get formatType(): FormatType {\n return FormatType.int;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get rowStride(): number {\n return this._width * this._numChannels * 2;\n }\n\n public get iterator(): PixelInt16 {\n return PixelInt16.imageData(this);\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get length(): number {\n return this._data.byteLength;\n }\n\n public get maxChannelValue(): number {\n return 0x7fff;\n }\n\n public get maxIndexValue(): number {\n return 0x7fff;\n }\n\n public get hasPalette(): boolean {\n return this.palette !== undefined;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get isLdrFormat(): boolean {\n return !this.isHdrFormat;\n }\n\n public get bitsPerChannel(): number {\n return 16;\n }\n\n constructor(\n width: number,\n height: number,\n numChannels: number,\n data?: Int16Array\n ) {\n this._width = width;\n this._height = height;\n this._numChannels = numChannels;\n this._data =\n data ?? new Int16Array(this._width * this._height * this._numChannels);\n }\n\n public static from(\n other: MemoryImageDataInt16,\n skipPixels = false\n ): MemoryImageDataInt16 {\n const data = skipPixels\n ? new Int16Array(other.data.length)\n : other.data.slice();\n return new MemoryImageDataInt16(\n other.width,\n other.height,\n other._numChannels,\n data\n );\n }\n\n public getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator {\n return new PixelRangeIterator(\n PixelInt16.imageData(this),\n x,\n y,\n width,\n height\n );\n }\n\n public getColor(r: number, g: number, b: number, a?: number): Color {\n return a === undefined\n ? ColorInt16.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b))\n : ColorInt16.rgba(\n Math.trunc(r),\n Math.trunc(g),\n Math.trunc(b),\n Math.trunc(a)\n );\n }\n\n public getPixel(x: number, y: number, pixel?: Pixel): Pixel {\n let p = pixel;\n if (p === undefined || !(p instanceof PixelInt16) || p.image !== this) {\n p = PixelInt16.imageData(this);\n }\n p.setPosition(x, y);\n return p;\n }\n\n public setPixel(x: number, y: number, p: Color): void {\n this.setPixelRgba(x, y, p.r, p.g, p.b, p.a);\n }\n\n public setPixelR(x: number, y: number, r: number): void {\n const index = y * this.width * this.numChannels + x * this.numChannels;\n this.data[index] = Math.trunc(r);\n }\n\n public setPixelRgb(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n const index = y * this.width * this.numChannels + x * this._numChannels;\n this._data[index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Math.trunc(b);\n }\n }\n }\n\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n const index = y * this.width * this.numChannels + x * this._numChannels;\n this._data[index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Math.trunc(b);\n if (this._numChannels > 3) {\n this._data[index + 3] = Math.trunc(a);\n }\n }\n }\n }\n\n public setPixelRgbSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgb(x, y, r, g, b);\n }\n\n public setPixelRgbaSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgba(x, y, r, g, b, a);\n }\n\n public clear(_c?: Color): void {}\n\n public clone(skipPixels = false): MemoryImageDataInt16 {\n return MemoryImageDataInt16.from(this, skipPixels);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n\n public getBytes(order?: ChannelOrder | undefined): Uint8Array {\n if (order === undefined) {\n return this.toUint8Array();\n }\n\n if (this.numChannels === 4) {\n if (\n order === ChannelOrder.abgr ||\n order === ChannelOrder.argb ||\n order === ChannelOrder.bgra\n ) {\n const tempImage = this.clone();\n if (order === ChannelOrder.abgr) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (order === ChannelOrder.argb) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (order === ChannelOrder.bgra) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n return tempImage.toUint8Array();\n }\n } else if (this.numChannels === 3) {\n if (order === ChannelOrder.bgr) {\n const tempImage = this.clone();\n for (const p of tempImage) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n return tempImage.toUint8Array();\n }\n }\n\n return this.toUint8Array();\n }\n\n public toString(): string {\n return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return PixelInt16.imageData(this);\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color, ColorConvertOptions } from '../color/color';\nimport { ColorUtils } from '../color/color-utils';\nimport { Format } from '../color/format';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MemoryImage } from './image';\nimport { MemoryImageDataInt32 } from './image-data-int32';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\nexport class PixelInt32 implements Pixel, Iterable, Iterator {\n private _index: number;\n\n private readonly _image: MemoryImageDataInt32;\n public get image(): MemoryImageDataInt32 {\n return this._image;\n }\n\n private _x: number;\n public get x(): number {\n return this._x;\n }\n\n private _y: number;\n public get y(): number {\n return this._y;\n }\n\n public get xNormalized(): number {\n return this.width > 1 ? this._x / (this.width - 1) : 0;\n }\n\n public get yNormalized(): number {\n return this.height > 1 ? this._y / (this.height - 1) : 0;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get data(): Int32Array {\n return this._image.data;\n }\n\n public get isValid(): boolean {\n return (\n this._x >= 0 &&\n this._x < this._image.width - 1 &&\n this._y >= 0 &&\n this._y < this._image.height - 1\n );\n }\n\n public get width(): number {\n return this._image.width;\n }\n\n public get height(): number {\n return this._image.width;\n }\n\n public get length(): number {\n return this._image.numChannels;\n }\n\n public get numChannels(): number {\n return this._image.numChannels;\n }\n\n public get maxChannelValue(): number {\n return this._image.maxChannelValue;\n }\n\n public get maxIndexValue(): number {\n return this._image.maxIndexValue;\n }\n\n public get format(): Format {\n return Format.int32;\n }\n\n public get isLdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get isHdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get hasPalette(): boolean {\n return this._image.hasPalette;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get r(): number {\n return this.numChannels > 0 ? this.data[this._index] : 0;\n }\n public set r(r: number) {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n }\n }\n\n public get g(): number {\n return this.numChannels > 1 ? this.data[this._index + 1] : 0;\n }\n public set g(g: number) {\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n }\n }\n\n public get b(): number {\n return this.numChannels > 2 ? this.data[this._index + 2] : 0;\n }\n public set b(b: number) {\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n }\n }\n\n public get a(): number {\n return this.numChannels > 3 ? this.data[this._index + 3] : 0;\n }\n public set a(a: number) {\n if (this.numChannels > 3) {\n this.data[this._index + 3] = Math.trunc(a);\n }\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(\n x: number,\n y: number,\n index: number,\n image: MemoryImageDataInt32\n ) {\n this._image = image;\n this._index = index;\n this._x = x;\n this._y = y;\n }\n\n public static imageData(image: MemoryImageDataInt32) {\n return new PixelInt32(-1, 0, -image.numChannels, image);\n }\n\n public static image(image: MemoryImage) {\n return new PixelInt32(\n -1,\n 0,\n -image.numChannels,\n image.data instanceof MemoryImageDataInt32\n ? (image.data as MemoryImageDataInt32)\n : new MemoryImageDataInt32(0, 0, 0)\n );\n }\n\n public static from(other: PixelInt32) {\n return new PixelInt32(other.x, other.y, other._index, other.image);\n }\n\n public next(): IteratorResult {\n this._x++;\n if (this._x === this.width) {\n this._x = 0;\n this._y++;\n if (this._y === this.height) {\n return >{\n done: true,\n value: this,\n };\n }\n }\n this._index += this.numChannels;\n return >{\n done: this._index >= this.image.data.length,\n value: this,\n };\n }\n\n public setPosition(x: number, y: number): void {\n this._x = x;\n this._y = y;\n this._index =\n this._y * this._image.width * this._image.numChannels +\n this._x * this._image.numChannels;\n }\n\n public setPositionNormalized(x: number, y: number): void {\n return this.setPosition(\n Math.floor(x * (this.width - 1)),\n Math.floor(y * (this.height - 1))\n );\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.numChannels ? this.data[this._index + channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(channel: number, value: number): void {\n if (channel < this.numChannels) {\n this.data[this._index + channel] = Math.trunc(value);\n }\n }\n\n public set(color: Color): void {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n this.a = color.a;\n }\n\n public setRgb(r: number, g: number, b: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n }\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n if (this.numChannels > 3) {\n this.data[this._index + 3] = Math.trunc(a);\n }\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public equals(other: Pixel | number[]): boolean {\n if (other instanceof PixelInt32) {\n return ArrayUtils.equals(this.toArray(), other.toArray());\n }\n if (Array.isArray(other)) {\n return ArrayUtils.equals(this.toArray(), other);\n }\n return false;\n }\n\n public clone(): PixelInt32 {\n return PixelInt32.from(this);\n }\n\n public convert(opt: ColorConvertOptions): Color {\n return ColorUtils.convertColor({\n from: this,\n format: opt.format,\n numChannels: opt.numChannels,\n alpha: opt.alpha,\n });\n }\n\n public toString(): string {\n return `${this.constructor.name} (${this.toArray()})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return this;\n }\n}\n", "/** @format */\n\nimport { ChannelOrder } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { ColorInt32 } from '../color/color-int32';\nimport { Format, FormatType } from '../color/format';\nimport { StringUtils } from '../common/string-utils';\nimport { MemoryImageData } from './image-data';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\nimport { PixelInt32 } from './pixel-int32';\nimport { PixelRangeIterator } from './pixel-range-iterator';\n\nexport class MemoryImageDataInt32 implements MemoryImageData, Iterable {\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _data: Int32Array;\n public get data(): Int32Array {\n return this._data;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get format(): Format {\n return Format.int32;\n }\n\n public get formatType(): FormatType {\n return FormatType.int;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get rowStride(): number {\n return this._width * this._numChannels * 4;\n }\n\n public get iterator(): PixelInt32 {\n return PixelInt32.imageData(this);\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get length(): number {\n return this._data.byteLength;\n }\n\n public get maxChannelValue(): number {\n return 0x7fffffff;\n }\n\n public get maxIndexValue(): number {\n return 0x7fffffff;\n }\n\n public get hasPalette(): boolean {\n return this.palette !== undefined;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get isLdrFormat(): boolean {\n return !this.isHdrFormat;\n }\n\n public get bitsPerChannel(): number {\n return 32;\n }\n\n constructor(\n width: number,\n height: number,\n numChannels: number,\n data?: Int32Array\n ) {\n this._width = width;\n this._height = height;\n this._numChannels = numChannels;\n this._data =\n data ?? new Int32Array(this._width * this._height * this._numChannels);\n }\n\n public static from(\n other: MemoryImageDataInt32,\n skipPixels = false\n ): MemoryImageDataInt32 {\n const data = skipPixels\n ? new Int32Array(other.data.length)\n : other.data.slice();\n return new MemoryImageDataInt32(\n other.width,\n other.height,\n other._numChannels,\n data\n );\n }\n\n public getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator {\n return new PixelRangeIterator(\n PixelInt32.imageData(this),\n x,\n y,\n width,\n height\n );\n }\n\n public getColor(r: number, g: number, b: number, a?: number): Color {\n return a === undefined\n ? ColorInt32.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b))\n : ColorInt32.rgba(\n Math.trunc(r),\n Math.trunc(g),\n Math.trunc(b),\n Math.trunc(a)\n );\n }\n\n public getPixel(x: number, y: number, pixel?: Pixel): Pixel {\n let p = pixel;\n if (p === undefined || !(p instanceof PixelInt32) || p.image !== this) {\n p = PixelInt32.imageData(this);\n }\n p.setPosition(x, y);\n return p;\n }\n\n public setPixel(x: number, y: number, p: Color): void {\n this.setPixelRgba(x, y, p.r, p.g, p.b, p.a);\n }\n\n public setPixelR(x: number, y: number, r: number): void {\n const index = y * this.width * this.numChannels + x * this.numChannels;\n this.data[index] = Math.trunc(r);\n }\n\n public setPixelRgb(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n const index = y * this.width * this.numChannels + x * this._numChannels;\n this._data[index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Math.trunc(b);\n }\n }\n }\n\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n const index = y * this.width * this.numChannels + x * this._numChannels;\n this._data[index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Math.trunc(b);\n if (this._numChannels > 3) {\n this._data[index + 3] = Math.trunc(a);\n }\n }\n }\n }\n\n public setPixelRgbSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgb(x, y, r, g, b);\n }\n\n public setPixelRgbaSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgba(x, y, r, g, b, a);\n }\n\n public clear(_c?: Color): void {}\n\n public clone(skipPixels = false): MemoryImageDataInt32 {\n return MemoryImageDataInt32.from(this, skipPixels);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n\n public getBytes(order?: ChannelOrder | undefined): Uint8Array {\n if (order === undefined) {\n return this.toUint8Array();\n }\n\n if (this.numChannels === 4) {\n if (\n order === ChannelOrder.abgr ||\n order === ChannelOrder.argb ||\n order === ChannelOrder.bgra\n ) {\n const tempImage = this.clone();\n if (order === ChannelOrder.abgr) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (order === ChannelOrder.argb) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (order === ChannelOrder.bgra) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n return tempImage.toUint8Array();\n }\n } else if (this.numChannels === 3) {\n if (order === ChannelOrder.bgr) {\n const tempImage = this.clone();\n for (const p of tempImage) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n return tempImage.toUint8Array();\n }\n }\n\n return this.toUint8Array();\n }\n\n public toString(): string {\n return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return PixelInt32.imageData(this);\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color, ColorConvertOptions } from '../color/color';\nimport { ColorUtils } from '../color/color-utils';\nimport { Format } from '../color/format';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MemoryImage } from './image';\nimport { MemoryImageDataInt8 } from './image-data-int8';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\nexport class PixelInt8 implements Pixel, Iterable, Iterator {\n private _index: number;\n\n private readonly _image: MemoryImageDataInt8;\n public get image(): MemoryImageDataInt8 {\n return this._image;\n }\n\n private _x: number;\n public get x(): number {\n return this._x;\n }\n\n private _y: number;\n public get y(): number {\n return this._y;\n }\n\n public get xNormalized(): number {\n return this.width > 1 ? this._x / (this.width - 1) : 0;\n }\n\n public get yNormalized(): number {\n return this.height > 1 ? this._y / (this.height - 1) : 0;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get data(): Int8Array {\n return this._image.data;\n }\n\n public get isValid(): boolean {\n return (\n this._x >= 0 &&\n this._x < this._image.width - 1 &&\n this._y >= 0 &&\n this._y < this._image.height - 1\n );\n }\n\n public get width(): number {\n return this._image.width;\n }\n\n public get height(): number {\n return this._image.width;\n }\n\n public get length(): number {\n return this._image.numChannels;\n }\n\n public get numChannels(): number {\n return this._image.numChannels;\n }\n\n public get maxChannelValue(): number {\n return this._image.maxChannelValue;\n }\n\n public get maxIndexValue(): number {\n return this._image.maxIndexValue;\n }\n\n public get format(): Format {\n return Format.int8;\n }\n\n public get isLdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get isHdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get hasPalette(): boolean {\n return this._image.hasPalette;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get r(): number {\n return this.numChannels > 0 ? this.data[this._index] : 0;\n }\n public set r(r: number) {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n }\n }\n\n public get g(): number {\n return this.numChannels > 1 ? this.data[this._index + 1] : 0;\n }\n public set g(g: number) {\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n }\n }\n\n public get b(): number {\n return this.numChannels > 2 ? this.data[this._index + 2] : 0;\n }\n public set b(b: number) {\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n }\n }\n\n public get a(): number {\n return this.numChannels > 3 ? this.data[this._index + 3] : 0;\n }\n public set a(a: number) {\n if (this.numChannels > 3) {\n this.data[this._index + 3] = Math.trunc(a);\n }\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(x: number, y: number, index: number, image: MemoryImageDataInt8) {\n this._image = image;\n this._index = index;\n this._x = x;\n this._y = y;\n }\n\n public static imageData(image: MemoryImageDataInt8) {\n return new PixelInt8(-1, 0, -image.numChannels, image);\n }\n\n public static image(image: MemoryImage) {\n return new PixelInt8(\n -1,\n 0,\n -image.numChannels,\n image.data instanceof MemoryImageDataInt8\n ? (image.data as MemoryImageDataInt8)\n : new MemoryImageDataInt8(0, 0, 0)\n );\n }\n\n public static from(other: PixelInt8) {\n return new PixelInt8(other.x, other.y, other._index, other.image);\n }\n\n public next(): IteratorResult {\n this._x++;\n if (this._x === this.width) {\n this._x = 0;\n this._y++;\n if (this._y === this.height) {\n return >{\n done: true,\n value: this,\n };\n }\n }\n this._index += this.numChannels;\n return >{\n done: this._index >= this.image.data.length,\n value: this,\n };\n }\n\n public setPosition(x: number, y: number): void {\n this._x = x;\n this._y = y;\n this._index =\n this._y * this._image.width * this._image.numChannels +\n this._x * this._image.numChannels;\n }\n\n public setPositionNormalized(x: number, y: number): void {\n return this.setPosition(\n Math.floor(x * (this.width - 1)),\n Math.floor(y * (this.height - 1))\n );\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.numChannels ? this.data[this._index + channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(channel: number, value: number): void {\n if (channel < this.numChannels) {\n this.data[this._index + channel] = Math.trunc(value);\n }\n }\n\n public set(color: Color): void {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n this.a = color.a;\n }\n\n public setRgb(r: number, g: number, b: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n }\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n if (this.numChannels > 3) {\n this.data[this._index + 3] = Math.trunc(a);\n }\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public equals(other: Pixel | number[]): boolean {\n if (other instanceof PixelInt8) {\n return ArrayUtils.equals(this.toArray(), other.toArray());\n }\n if (Array.isArray(other)) {\n return ArrayUtils.equals(this.toArray(), other);\n }\n return false;\n }\n\n public clone(): PixelInt8 {\n return PixelInt8.from(this);\n }\n\n public convert(opt: ColorConvertOptions): Color {\n return ColorUtils.convertColor({\n from: this,\n format: opt.format,\n numChannels: opt.numChannels,\n alpha: opt.alpha,\n });\n }\n\n public toString(): string {\n return `${this.constructor.name} (${this.toArray()})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return this;\n }\n}\n", "/** @format */\n\nimport { ChannelOrder } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { ColorInt8 } from '../color/color-int8';\nimport { Format, FormatType } from '../color/format';\nimport { MemoryImageData } from './image-data';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\nimport { PixelInt8 } from './pixel-int8';\nimport { PixelRangeIterator } from './pixel-range-iterator';\n\nexport class MemoryImageDataInt8 implements MemoryImageData, Iterable {\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _data: Int8Array;\n public get data(): Int8Array {\n return this._data;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get format(): Format {\n return Format.int8;\n }\n\n public get formatType(): FormatType {\n return FormatType.int;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get rowStride(): number {\n return this._width * this._numChannels;\n }\n\n public get iterator(): PixelInt8 {\n return PixelInt8.imageData(this);\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get length(): number {\n return this._data.byteLength;\n }\n\n public get maxChannelValue(): number {\n return 0x7f;\n }\n\n public get maxIndexValue(): number {\n return 0x7f;\n }\n\n public get hasPalette(): boolean {\n return this.palette !== undefined;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get isLdrFormat(): boolean {\n return !this.isHdrFormat;\n }\n\n public get bitsPerChannel(): number {\n return 8;\n }\n\n constructor(\n width: number,\n height: number,\n numChannels: number,\n data?: Int8Array\n ) {\n this._width = width;\n this._height = height;\n this._numChannels = numChannels;\n this._data =\n data ?? new Int8Array(this._width * this._height * this._numChannels);\n }\n\n public static from(\n other: MemoryImageDataInt8,\n skipPixels = false\n ): MemoryImageDataInt8 {\n const data = skipPixels\n ? new Int8Array(other.data.length)\n : other.data.slice();\n return new MemoryImageDataInt8(\n other.width,\n other.height,\n other._numChannels,\n data\n );\n }\n\n public getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator {\n return new PixelRangeIterator(\n PixelInt8.imageData(this),\n x,\n y,\n width,\n height\n );\n }\n\n public getColor(r: number, g: number, b: number, a?: number): Color {\n return a === undefined\n ? ColorInt8.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b))\n : ColorInt8.rgba(\n Math.trunc(r),\n Math.trunc(g),\n Math.trunc(b),\n Math.trunc(a)\n );\n }\n\n public getPixel(x: number, y: number, pixel?: Pixel): Pixel {\n let p = pixel;\n if (p === undefined || !(p instanceof PixelInt8) || p.image !== this) {\n p = PixelInt8.imageData(this);\n }\n p.setPosition(x, y);\n return p;\n }\n\n public setPixel(x: number, y: number, p: Color): void {\n this.setPixelRgba(x, y, p.r, p.g, p.b, p.a);\n }\n\n public setPixelR(x: number, y: number, r: number): void {\n const index = y * this.rowStride + x * this.numChannels;\n this.data[index] = Math.trunc(r);\n }\n\n public setPixelRgb(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n const index = y * this.rowStride + x * this._numChannels;\n this._data[index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Math.trunc(b);\n }\n }\n }\n\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n const index = y * this.rowStride + x * this._numChannels;\n this._data[index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Math.trunc(b);\n if (this._numChannels > 3) {\n this._data[index + 3] = Math.trunc(a);\n }\n }\n }\n }\n\n public setPixelRgbSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgb(x, y, r, g, b);\n }\n\n public setPixelRgbaSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgba(x, y, r, g, b, a);\n }\n\n public clear(_c?: Color): void {}\n\n public clone(skipPixels = false): MemoryImageDataInt8 {\n return MemoryImageDataInt8.from(this, skipPixels);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n\n public getBytes(order?: ChannelOrder | undefined): Uint8Array {\n if (order === undefined) {\n return this.toUint8Array();\n }\n\n if (this.numChannels === 4) {\n if (\n order === ChannelOrder.abgr ||\n order === ChannelOrder.argb ||\n order === ChannelOrder.bgra\n ) {\n const tempImage = this.clone();\n if (order === ChannelOrder.abgr) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (order === ChannelOrder.argb) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (order === ChannelOrder.bgra) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n return tempImage.toUint8Array();\n }\n } else if (this.numChannels === 3) {\n if (order === ChannelOrder.bgr) {\n const tempImage = this.clone();\n for (const p of tempImage) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n return tempImage.toUint8Array();\n }\n }\n\n return this.toUint8Array();\n }\n\n public toString(): string {\n return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return PixelInt8.imageData(this);\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color, ColorConvertOptions } from '../color/color';\nimport { ColorUtils } from '../color/color-utils';\nimport { Format } from '../color/format';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MathUtils } from '../common/math-utils';\nimport { MemoryImage } from './image';\nimport { MemoryImageDataUint1 } from './image-data-uint1';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\nexport class PixelUint1 implements Pixel, Iterable, Iterator {\n private _index: number;\n private _bitIndex: number;\n private _rowOffset: number;\n\n private readonly _image: MemoryImageDataUint1;\n public get image(): MemoryImageDataUint1 {\n return this._image;\n }\n\n private _x: number;\n public get x(): number {\n return this._x;\n }\n\n private _y: number;\n public get y(): number {\n return this._y;\n }\n\n public get xNormalized(): number {\n return this.width > 1 ? this._x / (this.width - 1) : 0;\n }\n\n public get yNormalized(): number {\n return this.height > 1 ? this._y / (this.height - 1) : 0;\n }\n\n public get index(): number {\n return this.getChannelInternal(0);\n }\n public set index(i: number) {\n this.setChannel(0, i);\n }\n\n public get data(): Uint8Array {\n return this._image.data;\n }\n\n public get isValid(): boolean {\n return (\n this._x >= 0 &&\n this._x < this._image.width - 1 &&\n this._y >= 0 &&\n this._y < this._image.height - 1\n );\n }\n\n public get width(): number {\n return this._image.width;\n }\n\n public get height(): number {\n return this._image.width;\n }\n\n public get length(): number {\n return this.palette?.numChannels ?? this._image.numChannels;\n }\n\n public get numChannels(): number {\n return this._image.numChannels;\n }\n\n public get maxChannelValue(): number {\n return this._image.maxChannelValue;\n }\n\n public get maxIndexValue(): number {\n return this._image.maxIndexValue;\n }\n\n public get format(): Format {\n return Format.uint1;\n }\n\n public get isLdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get isHdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get hasPalette(): boolean {\n return this._image.hasPalette;\n }\n\n public get palette(): Palette | undefined {\n return this._image.palette;\n }\n\n public get r(): number {\n return this.getChannel(0);\n }\n public set r(r: number) {\n this.setChannel(0, r);\n }\n\n public get g(): number {\n return this.getChannel(1);\n }\n public set g(g: number) {\n this.setChannel(1, g);\n }\n\n public get b(): number {\n return this.getChannel(2);\n }\n public set b(b: number) {\n this.setChannel(2, b);\n }\n\n public get a(): number {\n return this.getChannel(3);\n }\n public set a(a: number) {\n this.setChannel(3, a);\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n public get imageLength(): number {\n return this._image.length;\n }\n\n constructor(\n x: number,\n y: number,\n index: number,\n bitIndex: number,\n rowOffset: number,\n image: MemoryImageDataUint1\n ) {\n this._image = image;\n this._index = index;\n this._bitIndex = bitIndex;\n this._rowOffset = rowOffset;\n this._x = x;\n this._y = y;\n }\n\n public static imageData(image: MemoryImageDataUint1) {\n return new PixelUint1(-1, 0, 0, -1, 0, image);\n }\n\n public static image(image: MemoryImage) {\n return new PixelUint1(\n -1,\n 0,\n 0,\n -1,\n 0,\n image.data instanceof MemoryImageDataUint1\n ? (image.data as MemoryImageDataUint1)\n : new MemoryImageDataUint1(0, 0, 0)\n );\n }\n\n public static from(other: PixelUint1) {\n return new PixelUint1(\n other.x,\n other.y,\n other._index,\n other._bitIndex,\n other._rowOffset,\n other.image\n );\n }\n\n private getChannelInternal(channel: number): number {\n let i = this._index;\n let bi = 7 - (this._bitIndex + channel);\n if (bi < 0) {\n bi += 8;\n i++;\n }\n if (i >= this._image.data.length) {\n return 0;\n }\n return (this._image.data[i] >> bi) & 0x1;\n }\n\n public next(): IteratorResult {\n this._x++;\n if (this._x === this.width) {\n this._x = 0;\n this._y++;\n this._bitIndex = 0;\n this._index++;\n this._rowOffset += this.image.rowStride;\n return >{\n done: this._y >= this.height,\n value: this,\n };\n }\n\n const nc = this.numChannels;\n if (this.palette !== undefined || nc === 1) {\n this._bitIndex++;\n if (this._bitIndex > 7) {\n this._bitIndex = 0;\n this._index++;\n }\n } else {\n const bpp = this.image.numChannels;\n this._bitIndex = (this._x * bpp) & 0x7;\n this._index = this._rowOffset + ((this._x * bpp) >> 3);\n }\n return >{\n done: this._index >= this.imageLength,\n value: this,\n };\n }\n\n public setPosition(x: number, y: number): void {\n this._x = x;\n this._y = y;\n const bpp = this._image.numChannels;\n this._rowOffset = this._y * this._image.rowStride;\n this._index = this._rowOffset + ((this._x * bpp) >> 3);\n this._bitIndex = (this._x * bpp) & 0x7;\n }\n\n public setPositionNormalized(x: number, y: number): void {\n return this.setPosition(\n Math.floor(x * (this.width - 1)),\n Math.floor(y * (this.height - 1))\n );\n }\n\n public getChannel(channel: number | Channel): number {\n if (this.palette !== undefined) {\n return this.palette.get(this.getChannelInternal(0), channel);\n } else {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.numChannels\n ? this.getChannelInternal(channel)\n : 0;\n }\n }\n }\n\n public getChannelNormalized(channel: Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(channel: number, value: number): void {\n if (channel >= this.numChannels) {\n return;\n }\n\n let i = this._index;\n let bi = 7 - (this._bitIndex + channel);\n if (bi < 0) {\n bi += 8;\n i++;\n }\n\n let v = this.data[i];\n\n const vi = MathUtils.clampInt(value, 0, 1);\n const msk = [0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f];\n const mask = msk[bi];\n v = (v & mask) | (vi << bi);\n this.data[i] = v;\n }\n\n public set(color: Color): void {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n this.a = color.a;\n }\n\n public setRgb(r: number, g: number, b: number): void {\n const nc = this.image.numChannels;\n if (nc > 0) {\n this.setChannel(0, r);\n if (nc > 1) {\n this.setChannel(1, g);\n if (nc > 2) {\n this.setChannel(2, b);\n }\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n const nc = this.numChannels;\n if (nc > 0) {\n this.setChannel(0, r);\n if (nc > 1) {\n this.setChannel(1, g);\n if (nc > 2) {\n this.setChannel(2, b);\n if (nc > 3) {\n this.setChannel(3, a);\n }\n }\n }\n }\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public equals(other: Pixel | number[]): boolean {\n if (other instanceof PixelUint1) {\n return ArrayUtils.equals(this.toArray(), other.toArray());\n }\n if (Array.isArray(other)) {\n return ArrayUtils.equals(this.toArray(), other);\n }\n return false;\n }\n\n public clone(): PixelUint1 {\n return PixelUint1.from(this);\n }\n\n public convert(opt: ColorConvertOptions): Color {\n return ColorUtils.convertColor({\n from: this,\n format: opt.format,\n numChannels: opt.numChannels,\n alpha: opt.alpha,\n });\n }\n\n public toString(): string {\n return `${this.constructor.name} (${this.toArray()})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return this;\n }\n}\n", "/** @format */\n\nimport { ChannelOrder } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { Format, FormatType } from '../color/format';\nimport { MemoryImageData } from './image-data';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\nimport { PixelUint1 } from './pixel-uint1';\nimport { PixelRangeIterator } from './pixel-range-iterator';\nimport { ColorUint1 } from '../color/color-uint1';\n\nexport class MemoryImageDataUint1 implements MemoryImageData, Iterable {\n private pixel?: PixelUint1;\n\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _data: Uint8Array;\n public get data(): Uint8Array {\n return this._data;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get format(): Format {\n return Format.uint1;\n }\n\n public get formatType(): FormatType {\n return FormatType.uint;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n private _rowStride: number;\n public get rowStride(): number {\n return this._rowStride;\n }\n\n public get iterator(): PixelUint1 {\n return PixelUint1.imageData(this);\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get length(): number {\n return this._data.byteLength;\n }\n\n public get maxChannelValue(): number {\n return this._palette?.maxChannelValue ?? 1;\n }\n\n public get maxIndexValue(): number {\n return 1;\n }\n\n public get hasPalette(): boolean {\n return this.palette !== undefined;\n }\n\n private _palette?: Palette;\n public get palette(): Palette | undefined {\n return this._palette;\n }\n\n public get isHdrFormat(): boolean {\n return false;\n }\n\n public get isLdrFormat(): boolean {\n return !this.isHdrFormat;\n }\n\n public get bitsPerChannel(): number {\n return 1;\n }\n\n constructor(\n width: number,\n height: number,\n numChannels: number,\n data?: Uint8Array\n ) {\n this._width = width;\n this._height = height;\n this._numChannels = numChannels;\n this._rowStride = Math.ceil((this._width * this._numChannels) / 8);\n this._palette = undefined;\n this._data =\n data ?? new Uint8Array(Math.max(this._rowStride * this._height, 1));\n }\n\n public static palette(\n width: number,\n height: number,\n palette?: Palette\n ): MemoryImageDataUint1 {\n const rowStride = Math.ceil(width / 8);\n const data = new Uint8Array(Math.max(rowStride * height, 1));\n const d = new MemoryImageDataUint1(width, height, 1, data);\n d._rowStride = rowStride;\n d._palette = palette;\n return d;\n }\n\n public static from(\n other: MemoryImageDataUint1,\n skipPixels = false\n ): MemoryImageDataUint1 {\n const data = skipPixels\n ? new Uint8Array(other.data.length)\n : other.data.slice();\n const d = new MemoryImageDataUint1(\n other.width,\n other.height,\n other._numChannels,\n data\n );\n d._rowStride = other.rowStride;\n d._palette = other.palette?.clone();\n return d;\n }\n\n public getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator {\n return new PixelRangeIterator(\n PixelUint1.imageData(this),\n x,\n y,\n width,\n height\n );\n }\n\n public getColor(r: number, g: number, b: number, a?: number): Color {\n return a === undefined\n ? ColorUint1.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b))\n : ColorUint1.rgba(\n Math.trunc(r),\n Math.trunc(g),\n Math.trunc(b),\n Math.trunc(a)\n );\n }\n\n public getPixel(x: number, y: number, pixel?: Pixel): Pixel {\n let p = pixel;\n if (p === undefined || !(p instanceof PixelUint1) || p.image !== this) {\n p = PixelUint1.imageData(this);\n }\n p.setPosition(x, y);\n return p;\n }\n\n public setPixel(x: number, y: number, p: Color): void {\n this.setPixelRgba(x, y, p.r, p.g, p.b, p.a);\n }\n\n public setPixelR(x: number, y: number, r: number): void {\n if (this._numChannels < 1) {\n return;\n }\n this.pixel ??= PixelUint1.imageData(this);\n this.pixel.setPosition(x, y);\n this.pixel.index = r;\n }\n\n public setPixelRgb(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (this._numChannels < 1) {\n return;\n }\n this.pixel ??= PixelUint1.imageData(this);\n this.pixel.setPosition(x, y);\n this.pixel.setRgb(r, g, b);\n }\n\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (this._numChannels < 1) {\n return;\n }\n this.pixel ??= PixelUint1.imageData(this);\n this.pixel.setPosition(x, y);\n this.pixel.setRgba(r, g, b, a);\n }\n\n public setPixelRgbSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgb(x, y, r, g, b);\n }\n\n public setPixelRgbaSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgba(x, y, r, g, b, a);\n }\n\n public clear(_c?: Color): void {}\n\n public clone(skipPixels = false): MemoryImageDataUint1 {\n return MemoryImageDataUint1.from(this, skipPixels);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n\n public getBytes(order?: ChannelOrder | undefined): Uint8Array {\n if (order === undefined) {\n return this.toUint8Array();\n }\n\n if (this.numChannels === 4) {\n if (\n order === ChannelOrder.abgr ||\n order === ChannelOrder.argb ||\n order === ChannelOrder.bgra\n ) {\n const tempImage = this.clone();\n if (order === ChannelOrder.abgr) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (order === ChannelOrder.argb) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (order === ChannelOrder.bgra) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n return tempImage.toUint8Array();\n }\n } else if (this.numChannels === 3) {\n if (order === ChannelOrder.bgr) {\n const tempImage = this.clone();\n for (const p of tempImage) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n return tempImage.toUint8Array();\n }\n }\n\n return this.toUint8Array();\n }\n\n public toString(): string {\n return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return PixelUint1.imageData(this);\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color, ColorConvertOptions } from '../color/color';\nimport { ColorUtils } from '../color/color-utils';\nimport { Format } from '../color/format';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MemoryImage } from './image';\nimport { MemoryImageDataUint16 } from './image-data-uint16';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\nexport class PixelUint16 implements Pixel, Iterable, Iterator {\n private _index: number;\n\n private readonly _image: MemoryImageDataUint16;\n public get image(): MemoryImageDataUint16 {\n return this._image;\n }\n\n private _x: number;\n public get x(): number {\n return this._x;\n }\n\n private _y: number;\n public get y(): number {\n return this._y;\n }\n\n public get xNormalized(): number {\n return this.width > 1 ? this._x / (this.width - 1) : 0;\n }\n\n public get yNormalized(): number {\n return this.height > 1 ? this._y / (this.height - 1) : 0;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get data(): Uint16Array {\n return this._image.data;\n }\n\n public get isValid(): boolean {\n return (\n this._x >= 0 &&\n this._x < this._image.width - 1 &&\n this._y >= 0 &&\n this._y < this._image.height - 1\n );\n }\n\n public get width(): number {\n return this._image.width;\n }\n\n public get height(): number {\n return this._image.width;\n }\n\n public get length(): number {\n return this._image.numChannels;\n }\n\n public get numChannels(): number {\n return this._image.numChannels;\n }\n\n public get maxChannelValue(): number {\n return this._image.maxChannelValue;\n }\n\n public get maxIndexValue(): number {\n return this._image.maxIndexValue;\n }\n\n public get format(): Format {\n return Format.uint16;\n }\n\n public get isLdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get isHdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get hasPalette(): boolean {\n return this._image.hasPalette;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get r(): number {\n return this.numChannels > 0 ? this.data[this._index] : 0;\n }\n public set r(r: number) {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n }\n }\n\n public get g(): number {\n return this.numChannels > 1 ? this.data[this._index + 1] : 0;\n }\n public set g(g: number) {\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n }\n }\n\n public get b(): number {\n return this.numChannels > 2 ? this.data[this._index + 2] : 0;\n }\n public set b(b: number) {\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n }\n }\n\n public get a(): number {\n return this.numChannels > 3 ? this.data[this._index + 3] : 0;\n }\n public set a(a: number) {\n if (this.numChannels > 3) {\n this.data[this._index + 3] = Math.trunc(a);\n }\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(\n x: number,\n y: number,\n index: number,\n image: MemoryImageDataUint16\n ) {\n this._image = image;\n this._index = index;\n this._x = x;\n this._y = y;\n }\n\n public static imageData(image: MemoryImageDataUint16) {\n return new PixelUint16(-1, 0, -image.numChannels, image);\n }\n\n public static image(image: MemoryImage) {\n return new PixelUint16(\n -1,\n 0,\n -image.numChannels,\n image.data instanceof MemoryImageDataUint16\n ? (image.data as MemoryImageDataUint16)\n : new MemoryImageDataUint16(0, 0, 0)\n );\n }\n\n public static from(other: PixelUint16) {\n return new PixelUint16(other.x, other.y, other._index, other.image);\n }\n\n public next(): IteratorResult {\n this._x++;\n if (this._x === this.width) {\n this._x = 0;\n this._y++;\n if (this._y === this.height) {\n return >{\n done: true,\n value: this,\n };\n }\n }\n this._index += this.numChannels;\n return >{\n done: this._index >= this.image.data.length,\n value: this,\n };\n }\n\n public setPosition(x: number, y: number): void {\n this._x = x;\n this._y = y;\n this._index =\n this._y * this._image.width * this._image.numChannels +\n this._x * this._image.numChannels;\n }\n\n public setPositionNormalized(x: number, y: number): void {\n return this.setPosition(\n Math.floor(x * (this.width - 1)),\n Math.floor(y * (this.height - 1))\n );\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.numChannels ? this.data[this._index + channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(channel: number, value: number): void {\n if (channel < this.numChannels) {\n this.data[this._index + channel] = Math.trunc(value);\n }\n }\n\n public set(color: Color): void {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n this.a = color.a;\n }\n\n public setRgb(r: number, g: number, b: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n }\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n if (this.numChannels > 3) {\n this.data[this._index + 3] = Math.trunc(a);\n }\n }\n }\n }\n }\n\n public equals(other: Pixel | number[]): boolean {\n if (other instanceof PixelUint16) {\n return ArrayUtils.equals(this.toArray(), other.toArray());\n }\n if (Array.isArray(other)) {\n return ArrayUtils.equals(this.toArray(), other);\n }\n return false;\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone(): PixelUint16 {\n return PixelUint16.from(this);\n }\n\n public convert(opt: ColorConvertOptions): Color {\n return ColorUtils.convertColor({\n from: this,\n format: opt.format,\n numChannels: opt.numChannels,\n alpha: opt.alpha,\n });\n }\n\n public toString(): string {\n return `${this.constructor.name} (${this.toArray()})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return this;\n }\n}\n", "/** @format */\n\nimport { ChannelOrder } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { Format, FormatType } from '../color/format';\nimport { MemoryImageData } from './image-data';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\nimport { PixelUint16 } from './pixel-uint16';\nimport { PixelRangeIterator } from './pixel-range-iterator';\nimport { ColorUint16 } from '../color/color-uint16';\n\nexport class MemoryImageDataUint16 implements MemoryImageData, Iterable {\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _data: Uint16Array;\n public get data(): Uint16Array {\n return this._data;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get format(): Format {\n return Format.uint16;\n }\n\n public get formatType(): FormatType {\n return FormatType.uint;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get rowStride(): number {\n return this._width * this._numChannels * 2;\n }\n\n public get iterator(): PixelUint16 {\n return PixelUint16.imageData(this);\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get length(): number {\n return this._data.byteLength;\n }\n\n public get maxChannelValue(): number {\n return 0xffff;\n }\n\n public get maxIndexValue(): number {\n return 0xffff;\n }\n\n public get hasPalette(): boolean {\n return this.palette !== undefined;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get isLdrFormat(): boolean {\n return !this.isHdrFormat;\n }\n\n public get bitsPerChannel(): number {\n return 16;\n }\n\n constructor(\n width: number,\n height: number,\n numChannels: number,\n data?: Uint16Array\n ) {\n this._width = width;\n this._height = height;\n this._numChannels = numChannels;\n this._data =\n data ?? new Uint16Array(this._width * this._height * this._numChannels);\n }\n\n public static from(\n other: MemoryImageDataUint16,\n skipPixels = false\n ): MemoryImageDataUint16 {\n const data = skipPixels\n ? new Uint16Array(other.data.length)\n : other.data.slice();\n return new MemoryImageDataUint16(\n other.width,\n other.height,\n other._numChannels,\n data\n );\n }\n\n public getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator {\n return new PixelRangeIterator(\n PixelUint16.imageData(this),\n x,\n y,\n width,\n height\n );\n }\n\n public getColor(r: number, g: number, b: number, a?: number): Color {\n return a === undefined\n ? ColorUint16.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b))\n : ColorUint16.rgba(\n Math.trunc(r),\n Math.trunc(g),\n Math.trunc(b),\n Math.trunc(a)\n );\n }\n\n public getPixel(x: number, y: number, pixel?: Pixel): Pixel {\n let p = pixel;\n if (p === undefined || !(p instanceof PixelUint16) || p.image !== this) {\n p = PixelUint16.imageData(this);\n }\n p.setPosition(x, y);\n return p;\n }\n\n public setPixel(x: number, y: number, p: Color): void {\n this.setPixelRgba(x, y, p.r, p.g, p.b, p.a);\n }\n\n public setPixelR(x: number, y: number, r: number): void {\n const index = y * this._width * this._numChannels + x * this.numChannels;\n this.data[index] = Math.trunc(r);\n }\n\n public setPixelRgb(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n const index = y * this._width * this._numChannels + x * this._numChannels;\n this._data[index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Math.trunc(b);\n }\n }\n }\n\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n const index = y * this._width * this._numChannels + x * this._numChannels;\n this._data[index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Math.trunc(b);\n if (this._numChannels > 3) {\n this._data[index + 3] = Math.trunc(a);\n }\n }\n }\n }\n\n public setPixelRgbSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgb(x, y, r, g, b);\n }\n\n public setPixelRgbaSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgba(x, y, r, g, b, a);\n }\n\n public clear(_c?: Color): void {}\n\n public clone(skipPixels = false): MemoryImageDataUint16 {\n return MemoryImageDataUint16.from(this, skipPixels);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n\n public getBytes(order?: ChannelOrder | undefined): Uint8Array {\n if (order === undefined) {\n return this.toUint8Array();\n }\n\n if (this.numChannels === 4) {\n if (\n order === ChannelOrder.abgr ||\n order === ChannelOrder.argb ||\n order === ChannelOrder.bgra\n ) {\n const tempImage = this.clone();\n if (order === ChannelOrder.abgr) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (order === ChannelOrder.argb) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (order === ChannelOrder.bgra) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n return tempImage.toUint8Array();\n }\n } else if (this.numChannels === 3) {\n if (order === ChannelOrder.bgr) {\n const tempImage = this.clone();\n for (const p of tempImage) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n return tempImage.toUint8Array();\n }\n }\n\n return this.toUint8Array();\n }\n\n public toString(): string {\n return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return PixelUint16.imageData(this);\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color, ColorConvertOptions } from '../color/color';\nimport { ColorUtils } from '../color/color-utils';\nimport { Format } from '../color/format';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MathUtils } from '../common/math-utils';\nimport { MemoryImage } from './image';\nimport { MemoryImageDataUint2 } from './image-data-uint2';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\nexport class PixelUint2 implements Pixel, Iterable, Iterator {\n private _index: number;\n private _bitIndex: number;\n private _rowOffset: number;\n\n private readonly _image: MemoryImageDataUint2;\n public get image(): MemoryImageDataUint2 {\n return this._image;\n }\n\n private _x: number;\n public get x(): number {\n return this._x;\n }\n\n private _y: number;\n public get y(): number {\n return this._y;\n }\n\n public get xNormalized(): number {\n return this.width > 1 ? this._x / (this.width - 1) : 0;\n }\n\n public get yNormalized(): number {\n return this.height > 1 ? this._y / (this.height - 1) : 0;\n }\n\n public get index(): number {\n return this.getChannelInternal(0);\n }\n public set index(i: number) {\n this.setChannel(0, i);\n }\n\n public get data(): Uint8Array {\n return this._image.data;\n }\n\n public get isValid(): boolean {\n return (\n this._x >= 0 &&\n this._x < this._image.width - 1 &&\n this._y >= 0 &&\n this._y < this._image.height - 1\n );\n }\n\n public get width(): number {\n return this._image.width;\n }\n\n public get height(): number {\n return this._image.width;\n }\n\n public get length(): number {\n return this.palette?.numChannels ?? this._image.numChannels;\n }\n\n public get numChannels(): number {\n return this._image.numChannels;\n }\n\n public get maxChannelValue(): number {\n return this._image.maxChannelValue;\n }\n\n public get maxIndexValue(): number {\n return this._image.maxIndexValue;\n }\n\n public get format(): Format {\n return Format.uint2;\n }\n\n public get isLdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get isHdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get hasPalette(): boolean {\n return this._image.hasPalette;\n }\n\n public get palette(): Palette | undefined {\n return this._image.palette;\n }\n\n public get r(): number {\n return this.getChannel(0);\n }\n public set r(r: number) {\n this.setChannel(0, r);\n }\n\n public get g(): number {\n return this.getChannel(1);\n }\n public set g(g: number) {\n this.setChannel(1, g);\n }\n\n public get b(): number {\n return this.getChannel(2);\n }\n public set b(b: number) {\n this.setChannel(2, b);\n }\n\n public get a(): number {\n return this.getChannel(3);\n }\n public set a(a: number) {\n this.setChannel(3, a);\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n public get bitsPerPixel(): number {\n return this._image.palette !== undefined ? 2 : this._image.numChannels << 1;\n }\n\n constructor(\n x: number,\n y: number,\n index: number,\n bitIndex: number,\n rowOffset: number,\n image: MemoryImageDataUint2\n ) {\n this._image = image;\n this._index = index;\n this._bitIndex = bitIndex;\n this._rowOffset = rowOffset;\n this._x = x;\n this._y = y;\n }\n\n public static imageData(image: MemoryImageDataUint2) {\n return new PixelUint2(-1, 0, 0, -2, 0, image);\n }\n\n public static image(image: MemoryImage) {\n return new PixelUint2(\n -1,\n 0,\n 0,\n -2,\n 0,\n image.data instanceof MemoryImageDataUint2\n ? (image.data as MemoryImageDataUint2)\n : new MemoryImageDataUint2(0, 0, 0)\n );\n }\n\n public static from(other: PixelUint2) {\n return new PixelUint2(\n other.x,\n other.y,\n other._index,\n other._bitIndex,\n other._rowOffset,\n other.image\n );\n }\n\n private getChannelInternal(channel: number): number {\n let i = this._index;\n let bi = 6 - (this._bitIndex + (channel << 1));\n if (bi < 0) {\n bi += 8;\n i++;\n }\n return (this._image.data[i] >> bi) & 0x3;\n }\n\n public next(): IteratorResult {\n this._x++;\n if (this._x === this.width) {\n this._x = 0;\n this._y++;\n this._bitIndex = 0;\n this._index++;\n this._rowOffset += this.image.rowStride;\n return >{\n done: this._y >= this.height,\n value: this,\n };\n }\n\n const nc = this.numChannels;\n if (this.palette !== undefined || nc === 1) {\n this._bitIndex += 2;\n if (this._bitIndex > 7) {\n this._bitIndex = 0;\n this._index++;\n }\n } else {\n const bpp = this.bitsPerPixel;\n this._bitIndex = (this._x * bpp) & 0x7;\n this._index = this._rowOffset + ((this._x * bpp) >> 3);\n }\n return >{\n done: this._index >= this.image.data.length,\n value: this,\n };\n }\n\n public setPosition(x: number, y: number): void {\n this._x = x;\n this._y = y;\n const bpp = this.bitsPerPixel;\n this._rowOffset = this._y * this._image.rowStride;\n this._index = this._rowOffset + ((this._x * bpp) >> 3);\n this._bitIndex = (this._x * bpp) & 0x7;\n }\n\n public setPositionNormalized(x: number, y: number): void {\n return this.setPosition(\n Math.floor(x * (this.width - 1)),\n Math.floor(y * (this.height - 1))\n );\n }\n\n public getChannel(channel: number | Channel): number {\n if (this.palette !== undefined) {\n return this.palette.get(this.getChannelInternal(0), channel);\n } else {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.numChannels\n ? this.getChannelInternal(channel)\n : 0;\n }\n }\n }\n\n public getChannelNormalized(channel: Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(channel: number, value: number): void {\n if (channel >= this.image.numChannels) {\n return;\n }\n\n let i = this._index;\n let bi = 6 - (this._bitIndex + (channel << 1));\n if (bi < 0) {\n bi += 8;\n i++;\n }\n\n let v = this.data[i];\n\n const vi = MathUtils.clampInt(value, 0, 3);\n const msk = [0xfc, 0xf3, 0xcf, 0x3f];\n const mask = msk[bi >> 1];\n v = (v & mask) | (vi << bi);\n this.data[i] = v;\n }\n\n public set(color: Color): void {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n this.a = color.a;\n }\n\n public setRgb(r: number, g: number, b: number): void {\n const nc = this.image.numChannels;\n if (nc > 0) {\n this.setChannel(0, r);\n if (nc > 1) {\n this.setChannel(1, g);\n if (nc > 2) {\n this.setChannel(2, b);\n }\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n const nc = this.image.numChannels;\n if (nc > 0) {\n this.setChannel(0, r);\n if (nc > 1) {\n this.setChannel(1, g);\n if (nc > 2) {\n this.setChannel(2, b);\n if (nc > 3) {\n this.setChannel(3, a);\n }\n }\n }\n }\n }\n\n public equals(other: Pixel | number[]): boolean {\n if (other instanceof PixelUint2) {\n return ArrayUtils.equals(this.toArray(), other.toArray());\n }\n if (Array.isArray(other)) {\n return ArrayUtils.equals(this.toArray(), other);\n }\n return false;\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone(): PixelUint2 {\n return PixelUint2.from(this);\n }\n\n public convert(opt: ColorConvertOptions): Color {\n return ColorUtils.convertColor({\n from: this,\n format: opt.format,\n numChannels: opt.numChannels,\n alpha: opt.alpha,\n });\n }\n\n public toString(): string {\n return `${this.constructor.name} (${this.toArray()})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return this;\n }\n}\n", "/** @format */\n\nimport { ChannelOrder } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { Format, FormatType } from '../color/format';\nimport { MemoryImageData } from './image-data';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\nimport { PixelUint2 } from './pixel-uint2';\nimport { PixelRangeIterator } from './pixel-range-iterator';\nimport { ColorUint2 } from '../color/color-uint2';\n\nexport class MemoryImageDataUint2 implements MemoryImageData, Iterable {\n private _pixel?: PixelUint2;\n\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _data: Uint8Array;\n public get data(): Uint8Array {\n return this._data;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get format(): Format {\n return Format.uint2;\n }\n\n public get formatType(): FormatType {\n return FormatType.uint;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n private _rowStride: number;\n public get rowStride(): number {\n return this._rowStride;\n }\n\n public get iterator(): PixelUint2 {\n return PixelUint2.imageData(this);\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get length(): number {\n return this._data.byteLength;\n }\n\n public get maxChannelValue(): number {\n return this._palette?.maxChannelValue ?? 3;\n }\n\n public get maxIndexValue(): number {\n return 1;\n }\n\n public get hasPalette(): boolean {\n return this.palette !== undefined;\n }\n\n private _palette?: Palette;\n public get palette(): Palette | undefined {\n return this._palette;\n }\n\n public get isHdrFormat(): boolean {\n return false;\n }\n\n public get isLdrFormat(): boolean {\n return !this.isHdrFormat;\n }\n\n public get bitsPerChannel(): number {\n return 2;\n }\n\n constructor(\n width: number,\n height: number,\n numChannels: number,\n data?: Uint8Array\n ) {\n this._width = width;\n this._height = height;\n this._numChannels = numChannels;\n this._rowStride = Math.ceil((this._width * (this._numChannels << 1)) / 8);\n this._palette = undefined;\n this._data =\n data ?? new Uint8Array(Math.max(this._rowStride * this._height, 1));\n }\n\n public static palette(\n width: number,\n height: number,\n palette?: Palette\n ): MemoryImageDataUint2 {\n const rowStride = Math.ceil(width / 4);\n const data = new Uint8Array(Math.max(rowStride * height, 1));\n const d = new MemoryImageDataUint2(width, height, 1, data);\n d._rowStride = rowStride;\n d._palette = palette;\n return d;\n }\n\n public static from(\n other: MemoryImageDataUint2,\n skipPixels = false\n ): MemoryImageDataUint2 {\n const data = skipPixels\n ? new Uint8Array(other.data.length)\n : other.data.slice();\n const d = new MemoryImageDataUint2(\n other.width,\n other.height,\n other._numChannels,\n data\n );\n d._rowStride = other.rowStride;\n d._palette = other.palette?.clone();\n return d;\n }\n\n public getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator {\n return new PixelRangeIterator(\n PixelUint2.imageData(this),\n x,\n y,\n width,\n height\n );\n }\n\n public getColor(r: number, g: number, b: number, a?: number): Color {\n return a === undefined\n ? ColorUint2.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b))\n : ColorUint2.rgba(\n Math.trunc(r),\n Math.trunc(g),\n Math.trunc(b),\n Math.trunc(a)\n );\n }\n\n public getPixel(x: number, y: number, pixel?: Pixel): Pixel {\n let p = pixel;\n if (p === undefined || !(p instanceof PixelUint2) || p.image !== this) {\n p = PixelUint2.imageData(this);\n }\n p.setPosition(x, y);\n return p;\n }\n\n public setPixel(x: number, y: number, p: Color): void {\n this.setPixelRgba(x, y, p.r, p.g, p.b, p.a);\n }\n\n public setPixelR(x: number, y: number, r: number): void {\n if (this._numChannels < 1) {\n return;\n }\n this._pixel ??= PixelUint2.imageData(this);\n this._pixel.setPosition(x, y);\n this._pixel.index = r;\n }\n\n public setPixelRgb(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (this._numChannels < 1) {\n return;\n }\n this._pixel ??= PixelUint2.imageData(this);\n this._pixel.setPosition(x, y);\n this._pixel.setRgb(r, g, b);\n }\n\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (this._numChannels < 1) {\n return;\n }\n this._pixel ??= PixelUint2.imageData(this);\n this._pixel.setPosition(x, y);\n this._pixel.setRgba(r, g, b, a);\n }\n\n public setPixelRgbSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgb(x, y, r, g, b);\n }\n\n public setPixelRgbaSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgba(x, y, r, g, b, a);\n }\n\n public clear(_c?: Color): void {}\n\n public clone(skipPixels = false): MemoryImageDataUint2 {\n return MemoryImageDataUint2.from(this, skipPixels);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n\n public getBytes(order?: ChannelOrder | undefined): Uint8Array {\n if (order === undefined) {\n return this.toUint8Array();\n }\n\n if (this.numChannels === 4) {\n if (\n order === ChannelOrder.abgr ||\n order === ChannelOrder.argb ||\n order === ChannelOrder.bgra\n ) {\n const tempImage = this.clone();\n if (order === ChannelOrder.abgr) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (order === ChannelOrder.argb) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (order === ChannelOrder.bgra) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n return tempImage.toUint8Array();\n }\n } else if (this.numChannels === 3) {\n if (order === ChannelOrder.bgr) {\n const tempImage = this.clone();\n for (const p of tempImage) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n return tempImage.toUint8Array();\n }\n }\n\n return this.toUint8Array();\n }\n\n public toString(): string {\n return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return PixelUint2.imageData(this);\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color, ColorConvertOptions } from '../color/color';\nimport { ColorUtils } from '../color/color-utils';\nimport { Format } from '../color/format';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MemoryImage } from './image';\nimport { MemoryImageDataUint32 } from './image-data-uint32';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\nexport class PixelUint32 implements Pixel, Iterable, Iterator {\n private _index: number;\n\n private readonly _image: MemoryImageDataUint32;\n public get image(): MemoryImageDataUint32 {\n return this._image;\n }\n\n private _x: number;\n public get x(): number {\n return this._x;\n }\n\n private _y: number;\n public get y(): number {\n return this._y;\n }\n\n public get xNormalized(): number {\n return this.width > 1 ? this._x / (this.width - 1) : 0;\n }\n\n public get yNormalized(): number {\n return this.height > 1 ? this._y / (this.height - 1) : 0;\n }\n\n public get index(): number {\n return this.r;\n }\n public set index(i: number) {\n this.r = i;\n }\n\n public get data(): Uint32Array {\n return this._image.data;\n }\n\n public get isValid(): boolean {\n return (\n this._x >= 0 &&\n this._x < this._image.width - 1 &&\n this._y >= 0 &&\n this._y < this._image.height - 1\n );\n }\n\n public get width(): number {\n return this._image.width;\n }\n\n public get height(): number {\n return this._image.width;\n }\n\n public get length(): number {\n return this._image.numChannels;\n }\n\n public get numChannels(): number {\n return this._image.numChannels;\n }\n\n public get maxChannelValue(): number {\n return this._image.maxChannelValue;\n }\n\n public get maxIndexValue(): number {\n return this._image.maxIndexValue;\n }\n\n public get format(): Format {\n return Format.uint32;\n }\n\n public get isLdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get isHdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get hasPalette(): boolean {\n return this._image.hasPalette;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get r(): number {\n return this.numChannels > 0 ? this.data[this._index] : 0;\n }\n public set r(r: number) {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n }\n }\n\n public get g(): number {\n return this.numChannels > 1 ? this.data[this._index + 1] : 0;\n }\n public set g(g: number) {\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n }\n }\n\n public get b(): number {\n return this.numChannels > 2 ? this.data[this._index + 2] : 0;\n }\n public set b(b: number) {\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n }\n }\n\n public get a(): number {\n return this.numChannels > 3 ? this.data[this._index + 3] : 0;\n }\n public set a(a: number) {\n if (this.numChannels > 3) {\n this.data[this._index + 3] = Math.trunc(a);\n }\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(\n x: number,\n y: number,\n index: number,\n image: MemoryImageDataUint32\n ) {\n this._image = image;\n this._index = index;\n this._x = x;\n this._y = y;\n }\n\n public static imageData(image: MemoryImageDataUint32) {\n return new PixelUint32(-1, 0, -image.numChannels, image);\n }\n\n public static image(image: MemoryImage) {\n return new PixelUint32(\n -1,\n 0,\n -image.numChannels,\n image.data instanceof MemoryImageDataUint32\n ? (image.data as MemoryImageDataUint32)\n : new MemoryImageDataUint32(0, 0, 0)\n );\n }\n\n public static from(other: PixelUint32) {\n return new PixelUint32(other.x, other.y, other._index, other.image);\n }\n\n public next(): IteratorResult {\n this._x++;\n if (this._x === this.width) {\n this._x = 0;\n this._y++;\n if (this._y === this.height) {\n return >{\n done: true,\n value: this,\n };\n }\n }\n this._index += this.numChannels;\n return >{\n done: this._index >= this.image.data.length,\n value: this,\n };\n }\n\n public setPosition(x: number, y: number): void {\n this._x = x;\n this._y = y;\n this._index =\n this._y * this._image.width * this._image.numChannels +\n this._x * this._image.numChannels;\n }\n\n public setPositionNormalized(x: number, y: number): void {\n return this.setPosition(\n Math.floor(x * (this.width - 1)),\n Math.floor(y * (this.height - 1))\n );\n }\n\n public getChannel(channel: number | Channel): number {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.numChannels ? this.data[this._index + channel] : 0;\n }\n }\n\n public getChannelNormalized(channel: Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(channel: number, value: number): void {\n if (channel < this.numChannels) {\n this.data[this._index + channel] = Math.trunc(value);\n }\n }\n\n public set(color: Color): void {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n this.a = color.a;\n }\n\n public setRgb(r: number, g: number, b: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n }\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n if (this.numChannels > 3) {\n this.data[this._index + 3] = Math.trunc(a);\n }\n }\n }\n }\n }\n\n public equals(other: Pixel | number[]): boolean {\n if (other instanceof PixelUint32) {\n return ArrayUtils.equals(this.toArray(), other.toArray());\n }\n if (Array.isArray(other)) {\n return ArrayUtils.equals(this.toArray(), other);\n }\n return false;\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone(): PixelUint32 {\n return PixelUint32.from(this);\n }\n\n public convert(opt: ColorConvertOptions): Color {\n return ColorUtils.convertColor({\n from: this,\n format: opt.format,\n numChannels: opt.numChannels,\n alpha: opt.alpha,\n });\n }\n\n public toString(): string {\n return `${this.constructor.name} (${this.toArray()})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return this;\n }\n}\n", "/** @format */\n\nimport { ChannelOrder } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { Format, FormatType } from '../color/format';\nimport { MemoryImageData } from './image-data';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\nimport { PixelUint32 } from './pixel-uint32';\nimport { PixelRangeIterator } from './pixel-range-iterator';\nimport { ColorUint32 } from '../color/color-uint32';\n\nexport class MemoryImageDataUint32 implements MemoryImageData, Iterable {\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _data: Uint32Array;\n public get data(): Uint32Array {\n return this._data;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get format(): Format {\n return Format.uint32;\n }\n\n public get formatType(): FormatType {\n return FormatType.uint;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get rowStride(): number {\n return this._width * this._numChannels * 4;\n }\n\n public get iterator(): PixelUint32 {\n return PixelUint32.imageData(this);\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get length(): number {\n return this._data.byteLength;\n }\n\n public get maxChannelValue(): number {\n return 0xffffffff;\n }\n\n public get maxIndexValue(): number {\n return 0xffffffff;\n }\n\n public get hasPalette(): boolean {\n return this.palette !== undefined;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get isHdrFormat(): boolean {\n return true;\n }\n\n public get isLdrFormat(): boolean {\n return !this.isHdrFormat;\n }\n\n public get bitsPerChannel(): number {\n return 32;\n }\n\n constructor(\n width: number,\n height: number,\n numChannels: number,\n data?: Uint32Array\n ) {\n this._width = width;\n this._height = height;\n this._numChannels = numChannels;\n this._data =\n data ?? new Uint32Array(this._width * this._height * this._numChannels);\n }\n\n public static from(\n other: MemoryImageDataUint32,\n skipPixels = false\n ): MemoryImageDataUint32 {\n const data = skipPixels\n ? new Uint32Array(other.data.length)\n : other.data.slice();\n return new MemoryImageDataUint32(\n other.width,\n other.height,\n other._numChannels,\n data\n );\n }\n\n public getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator {\n return new PixelRangeIterator(\n PixelUint32.imageData(this),\n x,\n y,\n width,\n height\n );\n }\n\n public getColor(r: number, g: number, b: number, a?: number): Color {\n return a === undefined\n ? ColorUint32.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b))\n : ColorUint32.rgba(\n Math.trunc(r),\n Math.trunc(g),\n Math.trunc(b),\n Math.trunc(a)\n );\n }\n\n public getPixel(x: number, y: number, pixel?: Pixel): Pixel {\n let p = pixel;\n if (p === undefined || !(p instanceof PixelUint32) || p.image !== this) {\n p = PixelUint32.imageData(this);\n }\n p.setPosition(x, y);\n return p;\n }\n\n public setPixel(x: number, y: number, p: Color): void {\n this.setPixelRgba(x, y, p.r, p.g, p.b, p.a);\n }\n\n public setPixelR(x: number, y: number, r: number): void {\n const index = y * this._width * this._numChannels + x * this.numChannels;\n this.data[index] = Math.trunc(r);\n }\n\n public setPixelRgb(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n const index = y * this._width * this._numChannels + x * this._numChannels;\n this._data[index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Math.trunc(b);\n }\n }\n }\n\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n const index = y * this._width * this._numChannels + x * this._numChannels;\n this._data[index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Math.trunc(b);\n if (this._numChannels > 3) {\n this._data[index + 3] = Math.trunc(a);\n }\n }\n }\n }\n\n public setPixelRgbSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgb(x, y, r, g, b);\n }\n\n public setPixelRgbaSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgba(x, y, r, g, b, a);\n }\n\n public clear(_c?: Color): void {}\n\n public clone(skipPixels = false): MemoryImageDataUint32 {\n return MemoryImageDataUint32.from(this, skipPixels);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n\n public getBytes(order?: ChannelOrder | undefined): Uint8Array {\n if (order === undefined) {\n return this.toUint8Array();\n }\n\n if (this.numChannels === 4) {\n if (\n order === ChannelOrder.abgr ||\n order === ChannelOrder.argb ||\n order === ChannelOrder.bgra\n ) {\n const tempImage = this.clone();\n if (order === ChannelOrder.abgr) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (order === ChannelOrder.argb) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (order === ChannelOrder.bgra) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n return tempImage.toUint8Array();\n }\n } else if (this.numChannels === 3) {\n if (order === ChannelOrder.bgr) {\n const tempImage = this.clone();\n for (const p of tempImage) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n return tempImage.toUint8Array();\n }\n }\n\n return this.toUint8Array();\n }\n\n public toString(): string {\n return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return PixelUint32.imageData(this);\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color, ColorConvertOptions } from '../color/color';\nimport { ColorUtils } from '../color/color-utils';\nimport { Format } from '../color/format';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MathUtils } from '../common/math-utils';\nimport { MemoryImage } from './image';\nimport { MemoryImageDataUint4 } from './image-data-uint4';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\nexport class PixelUint4 implements Pixel, Iterable, Iterator {\n private _index: number;\n private _bitIndex: number;\n\n private readonly _image: MemoryImageDataUint4;\n public get image(): MemoryImageDataUint4 {\n return this._image;\n }\n\n private _x: number;\n public get x(): number {\n return this._x;\n }\n\n private _y: number;\n public get y(): number {\n return this._y;\n }\n\n public get xNormalized(): number {\n return this.width > 1 ? this._x / (this.width - 1) : 0;\n }\n\n public get yNormalized(): number {\n return this.height > 1 ? this._y / (this.height - 1) : 0;\n }\n\n public get index(): number {\n return this.getChannelInternal(0);\n }\n public set index(i: number) {\n this.setChannel(0, i);\n }\n\n public get data(): Uint8Array {\n return this._image.data;\n }\n\n public get isValid(): boolean {\n return (\n this._x >= 0 &&\n this._x < this._image.width - 1 &&\n this._y >= 0 &&\n this._y < this._image.height - 1\n );\n }\n\n public get width(): number {\n return this._image.width;\n }\n\n public get height(): number {\n return this._image.width;\n }\n\n public get length(): number {\n return this.palette?.numChannels ?? this._image.numChannels;\n }\n\n public get numChannels(): number {\n return this._image.numChannels;\n }\n\n public get maxChannelValue(): number {\n return this._image.maxChannelValue;\n }\n\n public get maxIndexValue(): number {\n return this._image.maxIndexValue;\n }\n\n public get format(): Format {\n return Format.uint4;\n }\n\n public get isLdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get isHdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get hasPalette(): boolean {\n return this._image.hasPalette;\n }\n\n public get palette(): Palette | undefined {\n return this._image.palette;\n }\n\n public get r(): number {\n return this.getChannel(0);\n }\n public set r(r: number) {\n this.setChannel(0, r);\n }\n\n public get g(): number {\n return this.getChannel(1);\n }\n public set g(g: number) {\n this.setChannel(1, g);\n }\n\n public get b(): number {\n return this.getChannel(2);\n }\n public set b(b: number) {\n this.setChannel(2, b);\n }\n\n public get a(): number {\n return this.getChannel(3);\n }\n public set a(a: number) {\n this.setChannel(3, a);\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(\n x: number,\n y: number,\n index: number,\n bitIndex: number,\n image: MemoryImageDataUint4\n ) {\n this._image = image;\n this._index = index;\n this._bitIndex = bitIndex;\n this._x = x;\n this._y = y;\n }\n\n public static imageData(image: MemoryImageDataUint4) {\n return new PixelUint4(-1, 0, 0, -(image.numChannels << 2), image);\n }\n\n public static image(image: MemoryImage) {\n return new PixelUint4(\n -1,\n 0,\n 0,\n -(image.numChannels << 2),\n image.data instanceof MemoryImageDataUint4\n ? (image.data as MemoryImageDataUint4)\n : new MemoryImageDataUint4(0, 0, 0)\n );\n }\n\n public static from(other: PixelUint4) {\n return new PixelUint4(\n other.x,\n other.y,\n other._index,\n other._bitIndex,\n other.image\n );\n }\n\n private getChannelInternal(channel: number): number {\n let i = this._index;\n let bi = 4 - (this._bitIndex + (channel << 2));\n if (bi < 0) {\n bi += 8;\n i++;\n }\n return (this._image.data[i] >> bi) & 0xf;\n }\n\n public next(): IteratorResult {\n this._x++;\n if (this._x === this.width) {\n // skip row stride padding bits\n this._x = 0;\n this._y++;\n this._bitIndex = 0;\n this._index = this._y * this.image.rowStride;\n return >{\n done: this._y >= this.height,\n value: this,\n };\n }\n const nc = this.image.numChannels;\n if (this.palette !== undefined || nc === 1) {\n this._bitIndex += 4;\n if (this._bitIndex > 7) {\n this._bitIndex = 0;\n this._index++;\n }\n } else {\n const bpp = nc << 2;\n this._bitIndex += bpp;\n while (this._bitIndex > 7) {\n this._bitIndex -= 8;\n this._index++;\n }\n }\n return >{\n done: this._index >= this.image.data.length,\n value: this,\n };\n }\n\n public setPosition(x: number, y: number): void {\n this._x = x;\n this._y = y;\n const bpp = this.image.numChannels * 4;\n const w = this.image.width;\n const rowStride = this.image.rowStride;\n this._index =\n bpp === 4\n ? this._y * rowStride + (this._x >> 1)\n : bpp === 8\n ? this._y * w + this._x\n : bpp === 16\n ? this._y * rowStride + (this._x << 1)\n : this._y * rowStride + ((this._x * bpp) >> 3);\n this._bitIndex = bpp > 7 ? (this._x * bpp) & 0x4 : (this._x * bpp) & 0x7;\n }\n\n public setPositionNormalized(x: number, y: number): void {\n return this.setPosition(\n Math.floor(x * (this.width - 1)),\n Math.floor(y * (this.height - 1))\n );\n }\n\n public getChannel(channel: number | Channel): number {\n if (this.palette !== undefined) {\n return this.palette.get(this.getChannelInternal(0), channel);\n } else {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.numChannels\n ? this.getChannelInternal(channel)\n : 0;\n }\n }\n }\n\n public getChannelNormalized(channel: Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(channel: number, value: number): void {\n if (channel >= this.image.numChannels) {\n return;\n }\n\n let i = this._index;\n let bi = 4 - (this._bitIndex + (channel << 2));\n if (bi < 0) {\n bi += 8;\n i++;\n }\n\n let v = this.data[i];\n\n const vi = MathUtils.clampInt(value, 0, 15);\n const mask = bi === 4 ? 0x0f : 0xf0;\n v = (v & mask) | (vi << bi);\n this.data[i] = v;\n }\n\n public set(color: Color): void {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n this.a = color.a;\n }\n\n public setRgb(r: number, g: number, b: number): void {\n const nc = this.image.numChannels;\n if (nc > 0) {\n this.setChannel(0, r);\n if (nc > 1) {\n this.setChannel(1, g);\n if (nc > 2) {\n this.setChannel(2, b);\n }\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n const nc = this.image.numChannels;\n if (nc > 0) {\n this.setChannel(0, r);\n if (nc > 1) {\n this.setChannel(1, g);\n if (nc > 2) {\n this.setChannel(2, b);\n if (nc > 3) {\n this.setChannel(3, a);\n }\n }\n }\n }\n }\n\n public equals(other: Pixel | number[]): boolean {\n if (other instanceof PixelUint4) {\n return ArrayUtils.equals(this.toArray(), other.toArray());\n }\n if (Array.isArray(other)) {\n return ArrayUtils.equals(this.toArray(), other);\n }\n return false;\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone(): PixelUint4 {\n return PixelUint4.from(this);\n }\n\n public convert(opt: ColorConvertOptions): Color {\n return ColorUtils.convertColor({\n from: this,\n format: opt.format,\n numChannels: opt.numChannels,\n alpha: opt.alpha,\n });\n }\n\n public toString(): string {\n return `${this.constructor.name} (${this.toArray()})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return this;\n }\n}\n", "/** @format */\n\nimport { ChannelOrder } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { Format, FormatType } from '../color/format';\nimport { MemoryImageData } from './image-data';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\nimport { PixelUint4 } from './pixel-uint4';\nimport { PixelRangeIterator } from './pixel-range-iterator';\nimport { ColorUint4 } from '../color/color-uint4';\n\nexport class MemoryImageDataUint4 implements MemoryImageData, Iterable {\n private _pixel?: PixelUint4;\n\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _data: Uint8Array;\n public get data(): Uint8Array {\n return this._data;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get format(): Format {\n return Format.uint4;\n }\n\n public get formatType(): FormatType {\n return FormatType.uint;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n private _rowStride: number;\n public get rowStride(): number {\n return this._rowStride;\n }\n\n public get iterator(): PixelUint4 {\n return PixelUint4.imageData(this);\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get length(): number {\n return this._data.byteLength;\n }\n\n public get maxChannelValue(): number {\n return this._palette?.maxChannelValue ?? 15;\n }\n\n public get maxIndexValue(): number {\n return 15;\n }\n\n public get hasPalette(): boolean {\n return this.palette !== undefined;\n }\n\n private _palette?: Palette;\n public get palette(): Palette | undefined {\n return this._palette;\n }\n\n public get isHdrFormat(): boolean {\n return false;\n }\n\n public get isLdrFormat(): boolean {\n return !this.isHdrFormat;\n }\n\n public get bitsPerChannel(): number {\n return 4;\n }\n\n constructor(\n width: number,\n height: number,\n numChannels: number,\n data?: Uint8Array\n ) {\n this._width = width;\n this._height = height;\n this._numChannels = numChannels;\n this._rowStride =\n this._numChannels === 2\n ? this._width\n : this._numChannels === 4\n ? this._width * 2\n : this._numChannels === 3\n ? Math.ceil(this._width * 1.5)\n : Math.ceil(this._width / 2);\n this._palette = undefined;\n this._data =\n data ?? new Uint8Array(Math.max(this._rowStride * this._height, 1));\n }\n\n public static palette(\n width: number,\n height: number,\n palette?: Palette\n ): MemoryImageDataUint4 {\n const rowStride = Math.ceil(width / 2);\n const data = new Uint8Array(Math.max(rowStride * height, 1));\n const d = new MemoryImageDataUint4(width, height, 1, data);\n d._rowStride = rowStride;\n d._palette = palette;\n return d;\n }\n\n public static from(\n other: MemoryImageDataUint4,\n skipPixels = false\n ): MemoryImageDataUint4 {\n const data = skipPixels\n ? new Uint8Array(other.data.length)\n : other.data.slice();\n const d = new MemoryImageDataUint4(\n other.width,\n other.height,\n other._numChannels,\n data\n );\n d._rowStride = other.rowStride;\n d._palette = other.palette?.clone();\n return d;\n }\n\n public getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator {\n return new PixelRangeIterator(\n PixelUint4.imageData(this),\n x,\n y,\n width,\n height\n );\n }\n\n public getColor(r: number, g: number, b: number, a?: number): Color {\n return a === undefined\n ? ColorUint4.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b))\n : ColorUint4.rgba(\n Math.trunc(r),\n Math.trunc(g),\n Math.trunc(b),\n Math.trunc(a)\n );\n }\n\n public getPixel(x: number, y: number, pixel?: Pixel): Pixel {\n let p = pixel;\n if (p === undefined || !(p instanceof PixelUint4) || p.image !== this) {\n p = PixelUint4.imageData(this);\n }\n p.setPosition(x, y);\n return p;\n }\n\n public setPixel(x: number, y: number, p: Color): void {\n this.setPixelRgba(x, y, p.r, p.g, p.b, p.a);\n }\n\n public setPixelR(x: number, y: number, r: number): void {\n if (this._numChannels < 1) {\n return;\n }\n this._pixel ??= PixelUint4.imageData(this);\n this._pixel.setPosition(x, y);\n this._pixel.index = r;\n }\n\n public setPixelRgb(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (this._numChannels < 1) {\n return;\n }\n this._pixel ??= PixelUint4.imageData(this);\n this._pixel.setPosition(x, y);\n this._pixel.setRgb(r, g, b);\n }\n\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (this._numChannels < 1) {\n return;\n }\n this._pixel ??= PixelUint4.imageData(this);\n this._pixel.setPosition(x, y);\n this._pixel.setRgba(r, g, b, a);\n }\n\n public setPixelRgbSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgb(x, y, r, g, b);\n }\n\n public setPixelRgbaSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgba(x, y, r, g, b, a);\n }\n\n public clear(_c?: Color): void {}\n\n public clone(skipPixels = false): MemoryImageDataUint4 {\n return MemoryImageDataUint4.from(this, skipPixels);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n\n public getBytes(order?: ChannelOrder | undefined): Uint8Array {\n if (order === undefined) {\n return this.toUint8Array();\n }\n\n if (this.numChannels === 4) {\n if (\n order === ChannelOrder.abgr ||\n order === ChannelOrder.argb ||\n order === ChannelOrder.bgra\n ) {\n const tempImage = this.clone();\n if (order === ChannelOrder.abgr) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (order === ChannelOrder.argb) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (order === ChannelOrder.bgra) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n return tempImage.toUint8Array();\n }\n } else if (this.numChannels === 3) {\n if (order === ChannelOrder.bgr) {\n const tempImage = this.clone();\n for (const p of tempImage) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n return tempImage.toUint8Array();\n }\n }\n\n return this.toUint8Array();\n }\n\n public toString(): string {\n return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return PixelUint4.imageData(this);\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color, ColorConvertOptions } from '../color/color';\nimport { ColorUtils } from '../color/color-utils';\nimport { Format } from '../color/format';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MathUtils } from '../common/math-utils';\nimport { MemoryImage } from './image';\nimport { MemoryImageDataUint8 } from './image-data-uint8';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\nexport class PixelUint8 implements Pixel, Iterable, Iterator {\n private _index: number;\n\n private readonly _image: MemoryImageDataUint8;\n public get image(): MemoryImageDataUint8 {\n return this._image;\n }\n\n private _x: number;\n public get x(): number {\n return this._x;\n }\n\n private _y: number;\n public get y(): number {\n return this._y;\n }\n\n public get xNormalized(): number {\n return this.width > 1 ? this._x / (this.width - 1) : 0;\n }\n\n public get yNormalized(): number {\n return this.height > 1 ? this._y / (this.height - 1) : 0;\n }\n\n public get index(): number {\n return this.data[this._index];\n }\n public set index(i: number) {\n this.data[this._index] = MathUtils.clampInt255(i);\n }\n\n public get data(): Uint8Array {\n return this._image.data;\n }\n\n public get isValid(): boolean {\n return (\n this._x >= 0 &&\n this._x < this._image.width - 1 &&\n this._y >= 0 &&\n this._y < this._image.height - 1\n );\n }\n\n public get width(): number {\n return this._image.width;\n }\n\n public get height(): number {\n return this._image.width;\n }\n\n public get length(): number {\n return this.palette?.numChannels ?? this._image.numChannels;\n }\n\n public get numChannels(): number {\n return this._image.numChannels;\n }\n\n public get maxChannelValue(): number {\n return this._image.maxChannelValue;\n }\n\n public get maxIndexValue(): number {\n return this._image.maxIndexValue;\n }\n\n public get format(): Format {\n return Format.uint8;\n }\n\n public get isLdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get isHdrFormat(): boolean {\n return this._image.isLdrFormat;\n }\n\n public get hasPalette(): boolean {\n return this._image.hasPalette;\n }\n\n public get palette(): Palette | undefined {\n return this._image.palette;\n }\n\n public get r(): number {\n return this.palette === undefined\n ? this.numChannels > 0\n ? this.data[this._index]\n : 0\n : this.palette.getRed(this.data[this._index]);\n }\n public set r(r: number) {\n if (this.numChannels > 0) {\n this.data[this._index] = MathUtils.clampInt255(r);\n }\n }\n\n public get g(): number {\n return this.palette === undefined\n ? this.numChannels > 1\n ? this.data[this._index + 1]\n : 0\n : this.palette.getGreen(this.data[this._index]);\n }\n public set g(g: number) {\n if (this.numChannels > 1) {\n this.data[this._index + 1] = MathUtils.clampInt255(g);\n }\n }\n\n public get b(): number {\n return this.palette === undefined\n ? this.numChannels > 2\n ? this.data[this._index + 2]\n : 0\n : this.palette.getBlue(this.data[this._index]);\n }\n public set b(b: number) {\n if (this.numChannels > 2) {\n this.data[this._index + 2] = MathUtils.clampInt255(b);\n }\n }\n\n public get a(): number {\n return this.palette === undefined\n ? this.numChannels > 3\n ? this.data[this._index + 3]\n : 255\n : this.palette.getAlpha(this.data[this._index]);\n }\n public set a(a: number) {\n if (this.numChannels > 3) {\n this.data[this._index + 3] = MathUtils.clampInt255(a);\n }\n }\n\n public get rNormalized(): number {\n return this.r / this.maxChannelValue;\n }\n public set rNormalized(v: number) {\n this.r = v * this.maxChannelValue;\n }\n\n public get gNormalized(): number {\n return this.g / this.maxChannelValue;\n }\n public set gNormalized(v: number) {\n this.g = v * this.maxChannelValue;\n }\n\n public get bNormalized(): number {\n return this.b / this.maxChannelValue;\n }\n public set bNormalized(v: number) {\n this.b = v * this.maxChannelValue;\n }\n\n public get aNormalized(): number {\n return this.a / this.maxChannelValue;\n }\n public set aNormalized(v: number) {\n this.a = v * this.maxChannelValue;\n }\n\n public get luminance(): number {\n return ColorUtils.getLuminance(this);\n }\n\n public get luminanceNormalized(): number {\n return ColorUtils.getLuminanceNormalized(this);\n }\n\n constructor(\n x: number,\n y: number,\n index: number,\n image: MemoryImageDataUint8\n ) {\n this._image = image;\n this._index = index;\n this._x = x;\n this._y = y;\n }\n\n public static imageData(image: MemoryImageDataUint8) {\n return new PixelUint8(-1, 0, -image.numChannels, image);\n }\n\n public static image(image: MemoryImage) {\n return new PixelUint8(\n -1,\n 0,\n -image.numChannels,\n image.data instanceof MemoryImageDataUint8\n ? (image.data as MemoryImageDataUint8)\n : new MemoryImageDataUint8(0, 0, 0)\n );\n }\n\n public static from(other: PixelUint8) {\n return new PixelUint8(other.x, other.y, other._index, other.image);\n }\n\n public next(): IteratorResult {\n this._x++;\n if (this._x === this.width) {\n this._x = 0;\n this._y++;\n if (this._y === this.height) {\n return >{\n done: true,\n value: this,\n };\n }\n }\n this._index += this.palette === undefined ? this.numChannels : 1;\n return >{\n done: this._index >= this.image.data.length,\n value: this,\n };\n }\n\n public setPosition(x: number, y: number): void {\n this._x = x;\n this._y = y;\n this._index =\n this._y * this._image.width * this._image.numChannels +\n this._x * this._image.numChannels;\n }\n\n public setPositionNormalized(x: number, y: number): void {\n return this.setPosition(\n Math.floor(x * (this.width - 1)),\n Math.floor(y * (this.height - 1))\n );\n }\n\n public getChannel(channel: number | Channel): number {\n if (this.palette !== undefined) {\n return this.palette.get(this.data[this._index], channel);\n } else {\n if (channel === Channel.luminance) {\n return this.luminance;\n } else {\n return channel < this.data.length\n ? this.data[this._index + channel]\n : 0;\n }\n }\n }\n\n public getChannelNormalized(channel: Channel): number {\n return this.getChannel(channel) / this.maxChannelValue;\n }\n\n public setChannel(channel: number, value: number): void {\n if (channel < this.numChannels) {\n this.data[this._index + channel] = MathUtils.clampInt255(value);\n }\n }\n\n public set(color: Color): void {\n if (this._image.hasPalette) {\n this._index = color.index;\n } else {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n this.a = color.a;\n }\n }\n\n public setRgb(r: number, g: number, b: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n }\n }\n }\n }\n\n public setRgba(r: number, g: number, b: number, a: number): void {\n if (this.numChannels > 0) {\n this.data[this._index] = Math.trunc(r);\n if (this.numChannels > 1) {\n this.data[this._index + 1] = Math.trunc(g);\n if (this.numChannels > 2) {\n this.data[this._index + 2] = Math.trunc(b);\n if (this.numChannels > 3) {\n this.data[this._index + 3] = Math.trunc(a);\n }\n }\n }\n }\n }\n\n public equals(other: Pixel | number[]): boolean {\n if (other instanceof PixelUint8) {\n return ArrayUtils.equals(this.toArray(), other.toArray());\n }\n if (Array.isArray(other)) {\n return ArrayUtils.equals(this.toArray(), other);\n }\n return false;\n }\n\n public toArray(): number[] {\n return ArrayUtils.generate(this.length, (i) => this.getChannel(i));\n }\n\n public clone(): PixelUint8 {\n return PixelUint8.from(this);\n }\n\n public convert(opt: ColorConvertOptions): Color {\n return ColorUtils.convertColor({\n from: this,\n format: opt.format,\n numChannels: opt.numChannels,\n alpha: opt.alpha,\n });\n }\n\n public toString(): string {\n return `${this.constructor.name} (${this.toArray()})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return this;\n }\n}\n", "/** @format */\n\nimport { ChannelOrder } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { Format, FormatType } from '../color/format';\nimport { MemoryImageData } from './image-data';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\nimport { PixelUint8 } from './pixel-uint8';\nimport { PixelRangeIterator } from './pixel-range-iterator';\nimport { ColorRgb8 } from '../color/color-rgb8';\nimport { ColorRgba8 } from '../color/color-rgba8';\nimport { MathUtils } from '../common/math-utils';\n\nexport class MemoryImageDataUint8 implements MemoryImageData, Iterable {\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _data: Uint8Array;\n public get data(): Uint8Array {\n return this._data;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get format(): Format {\n return Format.uint8;\n }\n\n public get formatType(): FormatType {\n return FormatType.uint;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get rowStride(): number {\n return this._width * this._numChannels;\n }\n\n public get iterator(): PixelUint8 {\n return PixelUint8.imageData(this);\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get length(): number {\n return this._data.byteLength;\n }\n\n public get maxChannelValue(): number {\n return this._palette?.maxChannelValue ?? 255;\n }\n\n public get maxIndexValue(): number {\n return 255;\n }\n\n public get hasPalette(): boolean {\n return this.palette !== undefined;\n }\n\n private _palette?: Palette;\n public get palette(): Palette | undefined {\n return this._palette;\n }\n\n public get isHdrFormat(): boolean {\n return false;\n }\n\n public get isLdrFormat(): boolean {\n return !this.isHdrFormat;\n }\n\n public get bitsPerChannel(): number {\n return 8;\n }\n\n constructor(\n width: number,\n height: number,\n numChannels: number,\n data?: Uint8Array\n ) {\n this._width = width;\n this._height = height;\n this._numChannels = numChannels;\n this._palette = undefined;\n this._data =\n data ?? new Uint8Array(this._width * this._height * this._numChannels);\n }\n\n public static palette(\n width: number,\n height: number,\n palette?: Palette\n ): MemoryImageDataUint8 {\n const data = new Uint8Array(width * height);\n const d = new MemoryImageDataUint8(width, height, 1, data);\n d._palette = palette;\n return d;\n }\n\n public static from(\n other: MemoryImageDataUint8,\n skipPixels = false\n ): MemoryImageDataUint8 {\n const data = skipPixels\n ? new Uint8Array(other.data.length)\n : other.data.slice();\n const d = new MemoryImageDataUint8(\n other.width,\n other.height,\n other._numChannels,\n data\n );\n d._palette = other.palette?.clone();\n return d;\n }\n\n public getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator {\n return new PixelRangeIterator(\n PixelUint8.imageData(this),\n x,\n y,\n width,\n height\n );\n }\n\n public getColor(r: number, g: number, b: number, a?: number): Color {\n return a === undefined\n ? new ColorRgb8(\n MathUtils.clampInt255(r),\n MathUtils.clampInt255(g),\n MathUtils.clampInt255(b)\n )\n : new ColorRgba8(\n MathUtils.clampInt255(r),\n MathUtils.clampInt255(g),\n MathUtils.clampInt255(b),\n MathUtils.clampInt255(a)\n );\n }\n\n public getPixel(x: number, y: number, pixel?: Pixel): Pixel {\n let p = pixel;\n if (p === undefined || !(p instanceof PixelUint8) || p.image !== this) {\n p = PixelUint8.imageData(this);\n }\n p.setPosition(x, y);\n return p;\n }\n\n public setPixel(x: number, y: number, p: Color): void {\n this.setPixelRgba(x, y, p.r, p.g, p.b, p.a);\n }\n\n public setPixelR(x: number, y: number, r: number): void {\n const index = y * this.rowStride + x * this.numChannels;\n this.data[index] = Math.trunc(r);\n }\n\n public setPixelRgb(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n const index = y * this.rowStride + x * this._numChannels;\n this._data[index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Math.trunc(b);\n }\n }\n }\n\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n const index = y * this.rowStride + x * this._numChannels;\n this._data[index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[index + 2] = Math.trunc(b);\n if (this._numChannels > 3) {\n this._data[index + 3] = Math.trunc(a);\n }\n }\n }\n }\n\n public setPixelRgbSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgb(x, y, r, g, b);\n }\n\n public setPixelRgbaSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return;\n }\n this.setPixelRgba(x, y, r, g, b, a);\n }\n\n public clear(c?: Color): void {\n const c8 = c?.convert({\n format: Format.uint8,\n });\n if (this._numChannels === 1) {\n const ri = c8 === undefined ? 0 : MathUtils.clampInt255(c8.r);\n this._data.fill(ri);\n } else if (this._numChannels === 2) {\n const ri = c8 === undefined ? 0 : MathUtils.clampInt255(c8.r);\n const gi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.g);\n const rg = (gi << 8) | ri;\n const u16 = new Uint16Array(this._data.buffer);\n u16.fill(rg);\n } else if (this._numChannels === 4) {\n const ri = c8 === undefined ? 0 : MathUtils.clampInt255(c8.r);\n const gi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.g);\n const bi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.b);\n const ai = c8 === undefined ? 0 : MathUtils.clampInt255(c8.a);\n const rgba = (ai << 24) | (bi << 16) | (gi << 8) | ri;\n const u32 = new Uint32Array(this._data.buffer);\n u32.fill(rgba);\n } else {\n const ri = c8 === undefined ? 0 : MathUtils.clampInt255(c8.r);\n const gi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.g);\n const bi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.b);\n // rgb is the slow case since we can't pack the channels\n for (const p of this) {\n p.r = ri;\n p.g = gi;\n p.b = bi;\n }\n }\n }\n\n public clone(skipPixels = false): MemoryImageDataUint8 {\n return MemoryImageDataUint8.from(this, skipPixels);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n\n public getBytes(order?: ChannelOrder | undefined): Uint8Array {\n if (order === undefined) {\n return this.toUint8Array();\n }\n\n if (this.numChannels === 4) {\n if (\n order === ChannelOrder.abgr ||\n order === ChannelOrder.argb ||\n order === ChannelOrder.bgra\n ) {\n const tempImage = this.clone();\n if (order === ChannelOrder.abgr) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (order === ChannelOrder.argb) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (order === ChannelOrder.bgra) {\n for (const p of tempImage) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n return tempImage.toUint8Array();\n }\n } else if (this.numChannels === 3) {\n if (order === ChannelOrder.bgr) {\n const tempImage = this.clone();\n for (const p of tempImage) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n return tempImage.toUint8Array();\n }\n }\n\n return this.toUint8Array();\n }\n\n public toString(): string {\n return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`;\n }\n\n public [Symbol.iterator](): Iterator {\n return PixelUint8.imageData(this);\n }\n}\n", "/** @format */\n\nimport { Format } from '../color/format';\nimport { Float16 } from '../common/float16';\nimport { Palette } from './palette';\n\nexport class PaletteFloat16 implements Palette {\n private readonly _data: Uint16Array;\n public get data(): Uint16Array {\n return this._data;\n }\n\n private readonly _numColors: number;\n public get numColors(): number {\n return this._numColors;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get byteLength(): number {\n return this.data.byteLength;\n }\n\n public get buffer(): ArrayBufferLike {\n return this.data.buffer;\n }\n\n public get format(): Format {\n return Format.float16;\n }\n\n public get maxChannelValue(): number {\n return 1;\n }\n\n constructor(numColors: number, numChannels: number, data?: Uint16Array) {\n this._numColors = numColors;\n this._numChannels = numChannels;\n this._data = data ?? new Uint16Array(numColors * numChannels);\n }\n\n public static from(other: PaletteFloat16) {\n return new PaletteFloat16(other.numColors, other.numChannels, other.data);\n }\n\n public setRgb(index: number, r: number, g: number, b: number): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Float16.doubleToFloat16(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Float16.doubleToFloat16(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Float16.doubleToFloat16(b);\n }\n }\n }\n\n public setRgba(\n index: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Float16.doubleToFloat16(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Float16.doubleToFloat16(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Float16.doubleToFloat16(b);\n if (this._numChannels > 3) {\n this._data[_index + 3] = Float16.doubleToFloat16(a);\n }\n }\n }\n }\n\n public set(index: number, channel: number, value: number): void {\n let _index = index;\n if (channel < this._numChannels) {\n _index *= this._numChannels;\n this._data[_index + channel] = Float16.doubleToFloat16(value);\n }\n }\n\n public get(index: number, channel: number): number {\n return channel < this._numChannels\n ? Float16.float16ToDouble(this._data[index * this._numChannels + channel])\n : 0;\n }\n\n public getRed(index: number): number {\n let _index = index;\n _index *= this._numChannels;\n return Float16.float16ToDouble(this._data[_index]);\n }\n\n public getGreen(index: number): number {\n let _index = index;\n if (this._numChannels < 2) {\n return 0;\n }\n _index *= this._numChannels;\n return Float16.float16ToDouble(this._data[_index + 1]);\n }\n\n public getBlue(index: number): number {\n let _index = index;\n if (this._numChannels < 3) {\n return 0;\n }\n _index *= this._numChannels;\n return Float16.float16ToDouble(this._data[_index + 2]);\n }\n\n public getAlpha(index: number) {\n let _index = index;\n if (this._numChannels < 4) {\n return 255;\n }\n _index *= this._numChannels;\n return Float16.float16ToDouble(this._data[_index + 3]);\n }\n\n public setRed(index: number, value: number): void {\n this.set(index, 0, value);\n }\n\n public setGreen(index: number, value: number): void {\n this.set(index, 1, value);\n }\n\n public setBlue(index: number, value: number): void {\n this.set(index, 2, value);\n }\n\n public setAlpha(index: number, value: number): void {\n this.set(index, 3, value);\n }\n\n public clone(): PaletteFloat16 {\n return PaletteFloat16.from(this);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n}\n", "/** @format */\n\nimport { Format } from '../color/format';\nimport { Palette } from './palette';\n\nexport class PaletteFloat32 implements Palette {\n private readonly _data: Float32Array;\n public get data(): Float32Array {\n return this._data;\n }\n\n private readonly _numColors: number;\n public get numColors(): number {\n return this._numColors;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get byteLength(): number {\n return this.data.byteLength;\n }\n\n public get buffer(): ArrayBufferLike {\n return this.data.buffer;\n }\n\n public get format(): Format {\n return Format.float32;\n }\n\n public get maxChannelValue(): number {\n return 1;\n }\n\n constructor(numColors: number, numChannels: number, data?: Float32Array) {\n this._numColors = numColors;\n this._numChannels = numChannels;\n this._data = data ?? new Float32Array(numColors * numChannels);\n }\n\n public static from(other: PaletteFloat32) {\n return new PaletteFloat32(other.numColors, other.numChannels, other.data);\n }\n\n public setRgb(index: number, r: number, g: number, b: number): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = r;\n if (this._numChannels > 1) {\n this._data[_index + 1] = g;\n if (this._numChannels > 2) {\n this._data[_index + 2] = b;\n }\n }\n }\n\n public setRgba(\n index: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = r;\n if (this._numChannels > 1) {\n this._data[_index + 1] = g;\n if (this._numChannels > 2) {\n this._data[_index + 2] = b;\n if (this._numChannels > 3) {\n this._data[_index + 3] = a;\n }\n }\n }\n }\n\n public set(index: number, channel: number, value: number): void {\n let _index = index;\n if (channel < this._numChannels) {\n _index *= this._numChannels;\n this._data[_index + channel] = value;\n }\n }\n\n public get(index: number, channel: number): number {\n return channel < this._numChannels\n ? this._data[index * this._numChannels + channel]\n : 0;\n }\n\n public getRed(index: number): number {\n let _index = index;\n _index *= this._numChannels;\n return this._data[_index];\n }\n\n public getGreen(index: number): number {\n let _index = index;\n if (this._numChannels < 2) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 1];\n }\n\n public getBlue(index: number): number {\n let _index = index;\n if (this._numChannels < 3) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 2];\n }\n\n public getAlpha(index: number) {\n let _index = index;\n if (this._numChannels < 4) {\n return 255;\n }\n _index *= this._numChannels;\n return this._data[_index + 3];\n }\n\n public setRed(index: number, value: number): void {\n this.set(index, 0, value);\n }\n\n public setGreen(index: number, value: number): void {\n this.set(index, 1, value);\n }\n\n public setBlue(index: number, value: number): void {\n this.set(index, 2, value);\n }\n\n public setAlpha(index: number, value: number): void {\n this.set(index, 3, value);\n }\n\n public clone(): PaletteFloat32 {\n return PaletteFloat32.from(this);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n}\n", "/** @format */\n\nimport { Format } from '../color/format';\nimport { Palette } from './palette';\n\nexport class PaletteFloat64 implements Palette {\n private readonly _data: Float64Array;\n public get data(): Float64Array {\n return this._data;\n }\n\n private readonly _numColors: number;\n public get numColors(): number {\n return this._numColors;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get byteLength(): number {\n return this.data.byteLength;\n }\n\n public get buffer(): ArrayBufferLike {\n return this.data.buffer;\n }\n\n public get format(): Format {\n return Format.float64;\n }\n\n public get maxChannelValue(): number {\n return 1;\n }\n\n constructor(numColors: number, numChannels: number, data?: Float64Array) {\n this._numColors = numColors;\n this._numChannels = numChannels;\n this._data = data ?? new Float64Array(numColors * numChannels);\n }\n\n public static from(other: PaletteFloat64) {\n return new PaletteFloat64(other.numColors, other.numChannels, other.data);\n }\n\n public setRgb(index: number, r: number, g: number, b: number): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = r;\n if (this._numChannels > 1) {\n this._data[_index + 1] = g;\n if (this._numChannels > 2) {\n this._data[_index + 2] = b;\n }\n }\n }\n\n public setRgba(\n index: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = r;\n if (this._numChannels > 1) {\n this._data[_index + 1] = g;\n if (this._numChannels > 2) {\n this._data[_index + 2] = b;\n if (this._numChannels > 3) {\n this._data[_index + 3] = a;\n }\n }\n }\n }\n\n public set(index: number, channel: number, value: number): void {\n let _index = index;\n if (channel < this._numChannels) {\n _index *= this._numChannels;\n this._data[_index + channel] = value;\n }\n }\n\n public get(index: number, channel: number): number {\n return channel < this._numChannels\n ? this._data[index * this._numChannels + channel]\n : 0;\n }\n\n public getRed(index: number): number {\n let _index = index;\n _index *= this._numChannels;\n return this._data[_index];\n }\n\n public getGreen(index: number): number {\n let _index = index;\n if (this._numChannels < 2) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 1];\n }\n\n public getBlue(index: number): number {\n let _index = index;\n if (this._numChannels < 3) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 2];\n }\n\n public getAlpha(index: number) {\n let _index = index;\n if (this._numChannels < 4) {\n return 255;\n }\n _index *= this._numChannels;\n return this._data[_index + 3];\n }\n\n public setRed(index: number, value: number): void {\n this.set(index, 0, value);\n }\n\n public setGreen(index: number, value: number): void {\n this.set(index, 1, value);\n }\n\n public setBlue(index: number, value: number): void {\n this.set(index, 2, value);\n }\n\n public setAlpha(index: number, value: number): void {\n this.set(index, 3, value);\n }\n\n public clone(): PaletteFloat64 {\n return PaletteFloat64.from(this);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n}\n", "/** @format */\n\nimport { Format } from '../color/format';\nimport { Palette } from './palette';\n\nexport class PaletteInt16 implements Palette {\n private readonly _data: Int16Array;\n public get data(): Int16Array {\n return this._data;\n }\n\n private readonly _numColors: number;\n public get numColors(): number {\n return this._numColors;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get format(): Format {\n return Format.int16;\n }\n\n public get maxChannelValue(): number {\n return 0x7fff;\n }\n\n constructor(numColors: number, numChannels: number, data?: Int16Array) {\n this._numColors = numColors;\n this._numChannels = numChannels;\n this._data = data ?? new Int16Array(numColors * numChannels);\n }\n\n public static from(other: PaletteInt16) {\n return new PaletteInt16(other.numColors, other.numChannels, other.data);\n }\n\n public setRgb(index: number, r: number, g: number, b: number): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Math.trunc(b);\n }\n }\n }\n\n public setRgba(\n index: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Math.trunc(b);\n if (this._numChannels > 3) {\n this._data[_index + 3] = Math.trunc(a);\n }\n }\n }\n }\n\n public set(index: number, channel: number, value: number): void {\n let _index = index;\n if (channel < this._numChannels) {\n _index *= this._numChannels;\n this._data[_index + channel] = Math.trunc(value);\n }\n }\n\n public get(index: number, channel: number): number {\n return channel < this._numChannels\n ? this._data[index * this._numChannels + channel]\n : 0;\n }\n\n public getRed(index: number): number {\n let _index = index;\n _index *= this._numChannels;\n return this._data[_index];\n }\n\n public getGreen(index: number): number {\n let _index = index;\n if (this._numChannels < 2) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 1];\n }\n\n public getBlue(index: number): number {\n let _index = index;\n if (this._numChannels < 3) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 2];\n }\n\n public getAlpha(index: number) {\n let _index = index;\n if (this._numChannels < 4) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 3];\n }\n\n public setRed(index: number, value: number): void {\n this.set(index, 0, value);\n }\n\n public setGreen(index: number, value: number): void {\n this.set(index, 1, value);\n }\n\n public setBlue(index: number, value: number): void {\n this.set(index, 2, value);\n }\n\n public setAlpha(index: number, value: number): void {\n this.set(index, 3, value);\n }\n\n public clone(): PaletteInt16 {\n return PaletteInt16.from(this);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n}\n", "/** @format */\n\nimport { Format } from '../color/format';\nimport { Palette } from './palette';\n\nexport class PaletteInt32 implements Palette {\n private readonly _data: Int32Array;\n public get data(): Int32Array {\n return this._data;\n }\n\n private readonly _numColors: number;\n public get numColors(): number {\n return this._numColors;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get format(): Format {\n return Format.int32;\n }\n\n public get maxChannelValue(): number {\n return 0x7fffffff;\n }\n\n constructor(numColors: number, numChannels: number, data?: Int32Array) {\n this._numColors = numColors;\n this._numChannels = numChannels;\n this._data = data ?? new Int32Array(numColors * numChannels);\n }\n\n public static from(other: PaletteInt32) {\n return new PaletteInt32(other.numColors, other.numChannels, other.data);\n }\n\n public setRgb(index: number, r: number, g: number, b: number): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Math.trunc(b);\n }\n }\n }\n\n public setRgba(\n index: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Math.trunc(b);\n if (this._numChannels > 3) {\n this._data[_index + 3] = Math.trunc(a);\n }\n }\n }\n }\n\n public set(index: number, channel: number, value: number): void {\n let _index = index;\n if (channel < this._numChannels) {\n _index *= this._numChannels;\n this._data[_index + channel] = Math.trunc(value);\n }\n }\n\n public get(index: number, channel: number): number {\n return channel < this._numChannels\n ? this._data[index * this._numChannels + channel]\n : 0;\n }\n\n public getRed(index: number): number {\n let _index = index;\n _index *= this._numChannels;\n return this._data[_index];\n }\n\n public getGreen(index: number): number {\n let _index = index;\n if (this._numChannels < 2) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 1];\n }\n\n public getBlue(index: number): number {\n let _index = index;\n if (this._numChannels < 3) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 2];\n }\n\n public getAlpha(index: number) {\n let _index = index;\n if (this._numChannels < 4) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 3];\n }\n\n public setRed(index: number, value: number): void {\n this.set(index, 0, value);\n }\n\n public setGreen(index: number, value: number): void {\n this.set(index, 1, value);\n }\n\n public setBlue(index: number, value: number): void {\n this.set(index, 2, value);\n }\n\n public setAlpha(index: number, value: number): void {\n this.set(index, 3, value);\n }\n\n public clone(): PaletteInt32 {\n return PaletteInt32.from(this);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n}\n", "/** @format */\n\nimport { Format } from '../color/format';\nimport { Palette } from './palette';\n\nexport class PaletteInt8 implements Palette {\n private readonly _data: Int8Array;\n public get data(): Int8Array {\n return this._data;\n }\n\n private readonly _numColors: number;\n public get numColors(): number {\n return this._numColors;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get byteLength(): number {\n return this.data.byteLength;\n }\n\n public get buffer(): ArrayBufferLike {\n return this.data.buffer;\n }\n\n public get format(): Format {\n return Format.int8;\n }\n\n public get maxChannelValue(): number {\n return 0x7f;\n }\n\n constructor(numColors: number, numChannels: number, data?: Int8Array) {\n this._numColors = numColors;\n this._numChannels = numChannels;\n this._data = data ?? new Int8Array(numColors * numChannels);\n }\n\n public static from(other: PaletteInt8) {\n return new PaletteInt8(other.numColors, other.numChannels, other.data);\n }\n\n public setRgb(index: number, r: number, g: number, b: number): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Math.trunc(b);\n }\n }\n }\n\n public setRgba(\n index: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Math.trunc(b);\n if (this._numChannels > 3) {\n this._data[_index + 3] = Math.trunc(a);\n }\n }\n }\n }\n\n public set(index: number, channel: number, value: number): void {\n let _index = index;\n if (channel < this._numChannels) {\n _index *= this._numChannels;\n this._data[_index + channel] = Math.trunc(value);\n }\n }\n\n public get(index: number, channel: number): number {\n return channel < this._numChannels\n ? this._data[index * this._numChannels + channel]\n : 0;\n }\n\n public getRed(index: number): number {\n let _index = index;\n _index *= this._numChannels;\n return this._data[_index];\n }\n\n public getGreen(index: number): number {\n let _index = index;\n if (this._numChannels < 2) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 1];\n }\n\n public getBlue(index: number): number {\n let _index = index;\n if (this._numChannels < 3) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 2];\n }\n\n public getAlpha(index: number) {\n let _index = index;\n if (this._numChannels < 4) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 3];\n }\n\n public setRed(index: number, value: number): void {\n this.set(index, 0, value);\n }\n\n public setGreen(index: number, value: number): void {\n this.set(index, 1, value);\n }\n\n public setBlue(index: number, value: number): void {\n this.set(index, 2, value);\n }\n\n public setAlpha(index: number, value: number): void {\n this.set(index, 3, value);\n }\n\n public clone(): PaletteInt8 {\n return PaletteInt8.from(this);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n}\n", "/** @format */\n\nimport { Format } from '../color/format';\nimport { Palette } from './palette';\n\nexport class PaletteUint16 implements Palette {\n private readonly _data: Uint16Array;\n public get data(): Uint16Array {\n return this._data;\n }\n\n private readonly _numColors: number;\n public get numColors(): number {\n return this._numColors;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get format(): Format {\n return Format.uint16;\n }\n\n public get maxChannelValue(): number {\n return 0xffff;\n }\n\n constructor(numColors: number, numChannels: number, data?: Uint16Array) {\n this._numColors = numColors;\n this._numChannels = numChannels;\n this._data = data ?? new Uint16Array(numColors * numChannels);\n }\n\n public static from(other: PaletteUint16) {\n return new PaletteUint16(other.numColors, other.numChannels, other.data);\n }\n\n public setRgb(index: number, r: number, g: number, b: number): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Math.trunc(b);\n }\n }\n }\n\n public setRgba(\n index: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Math.trunc(b);\n if (this._numChannels > 3) {\n this._data[_index + 3] = Math.trunc(a);\n }\n }\n }\n }\n\n public set(index: number, channel: number, value: number): void {\n let _index = index;\n if (channel < this._numChannels) {\n _index *= this._numChannels;\n this._data[_index + channel] = Math.trunc(value);\n }\n }\n\n public get(index: number, channel: number): number {\n return channel < this._numChannels\n ? this._data[index * this._numChannels + channel]\n : 0;\n }\n\n public getRed(index: number): number {\n let _index = index;\n _index *= this._numChannels;\n return this._data[_index];\n }\n\n public getGreen(index: number): number {\n let _index = index;\n if (this._numChannels < 2) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 1];\n }\n\n public getBlue(index: number): number {\n let _index = index;\n if (this._numChannels < 3) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 2];\n }\n\n public getAlpha(index: number) {\n let _index = index;\n if (this._numChannels < 4) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 3];\n }\n\n public setRed(index: number, value: number): void {\n this.set(index, 0, value);\n }\n\n public setGreen(index: number, value: number): void {\n this.set(index, 1, value);\n }\n\n public setBlue(index: number, value: number): void {\n this.set(index, 2, value);\n }\n\n public setAlpha(index: number, value: number): void {\n this.set(index, 3, value);\n }\n\n public clone(): PaletteUint16 {\n return PaletteUint16.from(this);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n}\n", "/** @format */\n\nimport { Format } from '../color/format';\nimport { Palette } from './palette';\n\nexport class PaletteUint32 implements Palette {\n private readonly _data: Uint32Array;\n public get data(): Uint32Array {\n return this._data;\n }\n\n private readonly _numColors: number;\n public get numColors(): number {\n return this._numColors;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get format(): Format {\n return Format.uint32;\n }\n\n public get maxChannelValue(): number {\n return 0xffffffff;\n }\n\n constructor(numColors: number, numChannels: number, data?: Uint32Array) {\n this._numColors = numColors;\n this._numChannels = numChannels;\n this._data = data ?? new Uint32Array(numColors * numChannels);\n }\n\n public static from(other: PaletteUint32) {\n return new PaletteUint32(other.numColors, other.numChannels, other.data);\n }\n\n public setRgb(index: number, r: number, g: number, b: number): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Math.trunc(b);\n }\n }\n }\n\n public setRgba(\n index: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Math.trunc(b);\n if (this._numChannels > 3) {\n this._data[_index + 3] = Math.trunc(a);\n }\n }\n }\n }\n\n public set(index: number, channel: number, value: number): void {\n let _index = index;\n if (channel < this._numChannels) {\n _index *= this._numChannels;\n this._data[_index + channel] = Math.trunc(value);\n }\n }\n\n public get(index: number, channel: number): number {\n return channel < this._numChannels\n ? this._data[index * this._numChannels + channel]\n : 0;\n }\n\n public getRed(index: number): number {\n let _index = index;\n _index *= this._numChannels;\n return this._data[_index];\n }\n\n public getGreen(index: number): number {\n let _index = index;\n if (this._numChannels < 2) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 1];\n }\n\n public getBlue(index: number): number {\n let _index = index;\n if (this._numChannels < 3) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 2];\n }\n\n public getAlpha(index: number) {\n let _index = index;\n if (this._numChannels < 4) {\n return 0;\n }\n _index *= this._numChannels;\n return this._data[_index + 3];\n }\n\n public setRed(index: number, value: number): void {\n this.set(index, 0, value);\n }\n\n public setGreen(index: number, value: number): void {\n this.set(index, 1, value);\n }\n\n public setBlue(index: number, value: number): void {\n this.set(index, 2, value);\n }\n\n public setAlpha(index: number, value: number): void {\n this.set(index, 3, value);\n }\n\n public clone(): PaletteUint32 {\n return PaletteUint32.from(this);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n}\n", "/** @format */\n\nimport { Format } from '../color/format';\nimport { Palette } from './palette';\n\nexport class PaletteUint8 implements Palette {\n private readonly _data: Uint8Array;\n public get data(): Uint8Array {\n return this._data;\n }\n\n private readonly _numColors: number;\n public get numColors(): number {\n return this._numColors;\n }\n\n private readonly _numChannels: number;\n public get numChannels(): number {\n return this._numChannels;\n }\n\n public get byteLength(): number {\n return this._data.byteLength;\n }\n\n public get buffer(): ArrayBufferLike {\n return this._data.buffer;\n }\n\n public get format(): Format {\n return Format.uint8;\n }\n\n public get maxChannelValue(): number {\n return 255;\n }\n\n constructor(numColors: number, numChannels: number, data?: Uint8Array) {\n this._numColors = numColors;\n this._numChannels = numChannels;\n this._data = data ?? new Uint8Array(numColors * numChannels);\n }\n\n public static from(other: PaletteUint8) {\n return new PaletteUint8(other.numColors, other.numChannels, other.data);\n }\n\n public setRgb(index: number, r: number, g: number, b: number): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Math.trunc(b);\n }\n }\n }\n\n public setRgba(\n index: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n let _index = index;\n _index *= this._numChannels;\n this._data[_index] = Math.trunc(r);\n if (this._numChannels > 1) {\n this._data[_index + 1] = Math.trunc(g);\n if (this._numChannels > 2) {\n this._data[_index + 2] = Math.trunc(b);\n if (this._numChannels > 3) {\n this._data[_index + 3] = Math.trunc(a);\n }\n }\n }\n }\n\n public set(index: number, channel: number, value: number): void {\n let _index = index;\n if (channel < this._numChannels) {\n _index *= this._numChannels;\n this._data[_index + channel] = Math.trunc(value);\n }\n }\n\n public get(index: number, channel: number): number {\n return channel < this._numChannels\n ? this._data[index * this._numChannels + channel]\n : 0;\n }\n\n public getRed(index: number): number {\n let _index = index;\n _index *= this._numChannels;\n if (_index >= this._data.length) {\n return 0;\n }\n return this._data[_index];\n }\n\n public getGreen(index: number): number {\n let _index = index;\n if (this._numChannels < 2) {\n return 0;\n }\n _index *= this._numChannels;\n if (_index >= this._data.length) {\n return 0;\n }\n return this._data[_index + 1];\n }\n\n public getBlue(index: number): number {\n let _index = index;\n if (this._numChannels < 3) {\n return 0;\n }\n _index *= this._numChannels;\n if (_index >= this._data.length) {\n return 0;\n }\n return this._data[_index + 2];\n }\n\n public getAlpha(index: number) {\n let _index = index;\n if (this._numChannels < 4) {\n return 255;\n }\n _index *= this._numChannels;\n if (_index >= this._data.length) {\n return 0;\n }\n return this._data[_index + 3];\n }\n\n public setRed(index: number, value: number): void {\n this.set(index, 0, value);\n }\n\n public setGreen(index: number, value: number): void {\n this.set(index, 1, value);\n }\n\n public setBlue(index: number, value: number): void {\n this.set(index, 2, value);\n }\n\n public setAlpha(index: number, value: number): void {\n this.set(index, 3, value);\n }\n\n public clone(): PaletteUint8 {\n return PaletteUint8.from(this);\n }\n\n public toUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color, ColorConvertOptions } from '../color/color';\nimport { Format } from '../color/format';\nimport { MemoryImageData } from './image-data';\nimport { MemoryImageDataUint8 } from './image-data-uint8';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\n/**\n * Represents an invalid pixel.\n */\nexport class PixelUndefined implements Pixel, Iterable, Iterator {\n private static readonly _nullImageData = new MemoryImageDataUint8(0, 0, 0);\n\n public get image(): MemoryImageData {\n return PixelUndefined._nullImageData;\n }\n\n public get isValid(): boolean {\n return false;\n }\n\n public get width(): number {\n return 0;\n }\n\n public get height(): number {\n return 0;\n }\n\n public get x(): number {\n return 0;\n }\n\n public get y(): number {\n return 0;\n }\n\n public get xNormalized(): number {\n return 0;\n }\n\n public get yNormalized(): number {\n return 0;\n }\n\n public get length(): number {\n return 0;\n }\n\n public get maxChannelValue(): number {\n return 0;\n }\n\n public get maxIndexValue(): number {\n return 0;\n }\n\n public get format(): Format {\n return Format.uint8;\n }\n\n public get isLdrFormat(): boolean {\n return false;\n }\n\n public get isHdrFormat(): boolean {\n return false;\n }\n\n public get hasPalette(): boolean {\n return false;\n }\n\n public get palette(): Palette | undefined {\n return undefined;\n }\n\n public get index(): number {\n return 0;\n }\n\n public set index(_i: number) {}\n\n public get r(): number {\n return 0;\n }\n\n public set r(_r: number) {}\n\n public get g(): number {\n return 0;\n }\n\n public set g(_g: number) {}\n\n public get b(): number {\n return 0;\n }\n\n public set b(_b: number) {}\n\n public get a(): number {\n return 0;\n }\n\n public set a(_a: number) {}\n\n public get rNormalized(): number {\n return 0;\n }\n\n public set rNormalized(_v: number) {}\n\n public get gNormalized(): number {\n return 0;\n }\n\n public set gNormalized(_v: number) {}\n\n public get bNormalized(): number {\n return 0;\n }\n\n public set bNormalized(_v: number) {}\n\n public get aNormalized(): number {\n return 0;\n }\n\n public set aNormalized(_v: number) {}\n\n public get luminance(): number {\n return 0;\n }\n\n public get luminanceNormalized(): number {\n return 0;\n }\n\n public getChannel(_channel: number): number {\n return 0;\n }\n\n public getChannelNormalized(_channel: Channel): number {\n return 0;\n }\n\n public setChannel(_channel: number, _value: number): void {}\n\n public set(_color: Color): void {}\n\n public setRgb(_r: number, _g: number, _b: number): void {}\n\n public setRgba(_r: number, _g: number, _b: number, _a: number): void {}\n\n public clone(): Color {\n return new PixelUndefined();\n }\n\n public convert(_options: ColorConvertOptions): Color {\n return this;\n }\n\n public setPosition(_x: number, _y: number): void {}\n\n public setPositionNormalized(_x: number, _y: number): void {}\n\n public equals(other: Pixel): boolean {\n return other instanceof PixelUndefined;\n }\n\n public next(): IteratorResult {\n return {\n done: true,\n value: this,\n };\n }\n\n public toArray(): number[] {\n return [];\n }\n\n public toString(): string {\n return `${this.constructor.name} (undefined)`;\n }\n\n public [Symbol.iterator](): Iterator {\n return this;\n }\n}\n", "/** @format */\n\nimport { Color } from '../color/color';\nimport { MemoryImageData } from './image-data';\nimport { PixelUndefined } from './pixel-undefined';\n\nexport interface Pixel extends Color, Iterator {\n /**\n * The [MemoryImageData] this pixel refers to.\n */\n get image(): MemoryImageData;\n /**\n * True if this points to a valid pixel, otherwise false.\n */\n get isValid(): boolean;\n /**\n * The width in pixels of the image data this pixel refers to.\n */\n get width(): number;\n /**\n * The height in pixels of the image data this pixel refers to.\n */\n get height(): number;\n /**\n * The x coordinate of the pixel.\n */\n get x(): number;\n /**\n * The y coordinate of the pixel.\n */\n get y(): number;\n /**\n * The normalized x coordinate of the pixel, in the range [0, 1].\n */\n get xNormalized(): number;\n /**\n * The normalized y coordinate of the pixel, in the range [0, 1].\n */\n get yNormalized(): number;\n /**\n * Set the coordinates of the pixel.\n */\n setPosition(x: number, y: number): void;\n /**\n * Set the normalized coordinates of the pixel, in the range [0, 1].\n */\n setPositionNormalized(x: number, y: number): void;\n /**\n * Tests if this pixel has the same values as the given pixel or color.\n */\n equals(other: Pixel | number[]): boolean;\n}\n\n/**\n * UndefinedPixel is used to represent an invalid pixel.\n */\nexport const UndefinedPixel = new PixelUndefined();\n", "/** @format */\n\nimport { ChannelOrder, ChannelOrderLength } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { ColorUint8 } from '../color/color-uint8';\nimport { ColorUtils } from '../color/color-utils';\nimport {\n Format,\n FormatMaxValue,\n FormatSize,\n FormatType,\n} from '../color/format';\nimport { ArrayUtils } from '../common/array-utils';\nimport { Interpolation } from '../common/interpolation';\nimport { MathUtils } from '../common/math-utils';\nimport { LibError } from '../error/lib-error';\nimport { ExifData } from '../exif/exif-data';\nimport { FrameType } from './frame-type';\nimport { IccProfile } from './icc-profile';\nimport { MemoryImageData } from './image-data';\nimport { MemoryImageDataFloat16 } from './image-data-float16';\nimport { MemoryImageDataFloat32 } from './image-data-float32';\nimport { MemoryImageDataFloat64 } from './image-data-float64';\nimport { MemoryImageDataInt16 } from './image-data-int16';\nimport { MemoryImageDataInt32 } from './image-data-int32';\nimport { MemoryImageDataInt8 } from './image-data-int8';\nimport { MemoryImageDataUint1 } from './image-data-uint1';\nimport { MemoryImageDataUint16 } from './image-data-uint16';\nimport { MemoryImageDataUint2 } from './image-data-uint2';\nimport { MemoryImageDataUint32 } from './image-data-uint32';\nimport { MemoryImageDataUint4 } from './image-data-uint4';\nimport { MemoryImageDataUint8 } from './image-data-uint8';\nimport { Palette } from './palette';\nimport { PaletteFloat16 } from './palette-float16';\nimport { PaletteFloat32 } from './palette-float32';\nimport { PaletteFloat64 } from './palette-float64';\nimport { PaletteInt16 } from './palette-int16';\nimport { PaletteInt32 } from './palette-int32';\nimport { PaletteInt8 } from './palette-int8';\nimport { PaletteUint16 } from './palette-uint16';\nimport { PaletteUint32 } from './palette-uint32';\nimport { PaletteUint8 } from './palette-uint8';\nimport { Pixel, UndefinedPixel } from './pixel';\n\ninterface MemoryImageInitializeOptions {\n width: number;\n height: number;\n format?: Format;\n numChannels?: number;\n withPalette?: boolean;\n paletteFormat?: Format;\n palette?: Palette;\n exifData?: ExifData;\n iccProfile?: IccProfile;\n}\n\nexport interface MemoryImageCreateOptions extends MemoryImageInitializeOptions {\n loopCount?: number;\n frameType?: FrameType;\n frameDuration?: number;\n frameIndex?: number;\n backgroundColor?: Color;\n textData?: Map;\n}\n\nexport interface MemoryImageFromBytesOptions extends MemoryImageCreateOptions {\n bytes: ArrayBufferLike;\n rowStride?: number;\n channelOrder?: ChannelOrder;\n}\n\nexport interface MemoryImageCloneOptions {\n skipAnimation?: boolean;\n skipPixels?: boolean;\n}\n\nexport interface MemoryImageConvertOptions {\n format?: Format;\n numChannels?: number;\n alpha?: number;\n withPalette?: boolean;\n skipAnimation?: boolean;\n}\n\nexport interface MemoryImageColorExtremes {\n min: number;\n max: number;\n}\n\n/**\n * A MemoryImage is a container for MemoryImageData and other various metadata\n * representing an image in memory.\n */\nexport class MemoryImage implements Iterable {\n private _data?: MemoryImageData;\n public get data(): MemoryImageData | undefined {\n return this._data;\n }\n\n private get numPixelColors(): number {\n return this.format === Format.uint1\n ? 2\n : this.format === Format.uint2\n ? 4\n : this.format === Format.uint4\n ? 16\n : this.format === Format.uint8\n ? 256\n : 0;\n }\n\n /**\n * The format of the image pixels.\n */\n public get format(): Format {\n return this._data?.format ?? Format.uint8;\n }\n\n /**\n * Indicates whether this image has a palette.\n */\n public get hasPalette(): boolean {\n return this._data?.palette !== undefined;\n }\n\n /**\n * The palette if the image has one, undefined otherwise.\n */\n public get palette(): Palette | undefined {\n return this._data?.palette;\n }\n\n /**\n * The number of color channels for the image.\n */\n public get numChannels(): number {\n return this.palette?.numChannels ?? this._data?.numChannels ?? 0;\n }\n\n /**\n * Indicates whether this image is animated.\n * An image is considered animated if it has more than one frame, as the\n * first image in the frames list is the image itself.\n */\n public get hasAnimation(): boolean {\n return this._frames.length > 1;\n }\n\n /**\n * The number of frames in this MemoryImage. A MemoryImage will have at least one\n * frame, itself, so it's considered animated if it has more than one\n * frame.\n */\n public get numFrames(): number {\n return this._frames.length;\n }\n\n private _exifData?: ExifData;\n /**\n * The EXIF metadata for the image. If an ExifData hasn't been created\n * for the image yet, one will be added.\n */\n public get exifData(): ExifData {\n this._exifData ??= new ExifData();\n return this._exifData;\n }\n public set exifData(exif: ExifData) {\n this._exifData = exif;\n }\n\n /**\n * The maximum value of a pixel channel, based on the format of the image.\n * If the image has a **palette**, this will be the maximum value of a palette\n * color channel. Float format images will have a **maxChannelValue** of 1,\n * though they can have values above that.\n */\n public get maxChannelValue(): number {\n return this._data?.maxChannelValue ?? 0;\n }\n\n /**\n * The maximum value of a palette index, based on the format of the image.\n * This differs from **maxChannelValue** in that it will not be affected by\n * the format of the **palette**.\n */\n public get maxIndexValue(): number {\n return this.data?.maxIndexValue ?? 0;\n }\n\n /**\n * Indicates whether this image supports using a palette.\n */\n public get supportsPalette(): boolean {\n return (\n this.format === Format.uint1 ||\n this.format === Format.uint2 ||\n this.format === Format.uint4 ||\n this.format === Format.uint8\n );\n }\n\n /**\n * The width of the image in pixels.\n */\n public get width(): number {\n return this.data?.width ?? 0;\n }\n\n /**\n * The height of the image in pixels.\n */\n public get height(): number {\n return this.data?.height ?? 0;\n }\n\n /**\n * The general type of the format, whether it's uint data, int data, or\n * float data (regardless of precision).\n */\n public get formatType(): FormatType {\n return this.data?.formatType ?? FormatType.uint;\n }\n\n /**\n * Indicates whether this image is valid and has data.\n */\n public get isValid(): boolean {\n return this._data !== undefined && this.width > 0 && this.height > 0;\n }\n\n /**\n * The ArrayBufferLike of the image storage data or undefined if not initialized.\n */\n public get buffer(): ArrayBufferLike | undefined {\n return this._data?.buffer;\n }\n\n /**\n * The length in bytes of the image data buffer.\n */\n public get byteLength(): number {\n return this._data?.buffer.byteLength ?? 0;\n }\n\n /**\n * The length in bytes of a row of pixels in the image buffer.\n */\n public get rowStride(): number {\n return this._data?.rowStride ?? 0;\n }\n\n /**\n * Indicates whether this image is a Low Dynamic Range (regular) image.\n */\n public get isLdrFormat(): boolean {\n return this._data?.isLdrFormat ?? false;\n }\n\n /**\n * Indicates whether this image is a High Dynamic Range image.\n */\n public get isHdrFormat(): boolean {\n return this._data?.isHdrFormat ?? false;\n }\n\n /**\n * The number of bits per color channel.\n */\n public get bitsPerChannel(): number {\n return this._data?.bitsPerChannel ?? 0;\n }\n\n /**\n * Indicates whether this MemoryImage has an alpha channel.\n */\n public get hasAlpha(): boolean {\n return this.numChannels === 4;\n }\n\n /**\n * Named non-color channels used by this image.\n */\n private _extraChannels?: Map;\n\n private _iccProfile: IccProfile | undefined;\n public get iccProfile(): IccProfile | undefined {\n return this._iccProfile;\n }\n public set iccProfile(v: IccProfile | undefined) {\n this._iccProfile = v;\n }\n\n private _textData: Map | undefined;\n public get textData(): Map | undefined {\n return this._textData;\n }\n\n private _backgroundColor?: Color;\n /**\n * The suggested background color to clear the canvas with.\n */\n public get backgroundColor(): Color | undefined {\n return this._backgroundColor;\n }\n public set backgroundColor(v: Color | undefined) {\n this._backgroundColor = v;\n }\n\n private _loopCount: number;\n /**\n * How many times should the animation loop (0 means forever)\n */\n public get loopCount(): number {\n return this._loopCount;\n }\n public set loopCount(v: number) {\n this._loopCount = v;\n }\n\n private _frameType: FrameType;\n /**\n * Gets or sets how should the frames be interpreted.\n * If the **frameType** is _FrameType.animation_, the frames are part\n * of an animated sequence. If the **frameType** is _FrameType.page_,\n * the frames are the pages of a document.\n */\n public get frameType(): FrameType {\n return this._frameType;\n }\n public set frameType(v: FrameType) {\n this._frameType = v;\n }\n\n /**\n * The list of sub-frames for the image, if it's an animation. An image\n * is considered animated if it has more than one frame, as the first\n * frame will be the image itself.\n */\n private _frames: MemoryImage[] = [];\n public get frames(): MemoryImage[] {\n return this._frames;\n }\n\n private _frameDuration: number;\n /**\n * How long this frame should be displayed, in milliseconds.\n * A duration of 0 indicates no delay and the next frame will be drawn\n * as quickly as it can.\n */\n public get frameDuration(): number {\n return this._frameDuration;\n }\n public set frameDuration(v: number) {\n this._frameDuration = v;\n }\n\n /**\n * Index of this image in the parent animations frame list.\n */\n private _frameIndex: number;\n public get frameIndex(): number {\n return this._frameIndex;\n }\n\n constructor(opt?: MemoryImageCreateOptions) {\n if (opt !== undefined) {\n this._loopCount = opt.loopCount ?? 0;\n this._frameType = opt.frameType ?? FrameType.sequence;\n this._frameDuration = opt.frameDuration ?? 0;\n this._frameIndex = opt.frameIndex ?? 0;\n this._backgroundColor = opt.backgroundColor;\n this._textData = opt.textData;\n this._frames.push(this);\n this.initialize({\n width: opt.width,\n height: opt.height,\n format: opt.format ?? Format.uint8,\n numChannels: opt.numChannels ?? 3,\n withPalette: opt.withPalette ?? false,\n paletteFormat: opt.paletteFormat ?? Format.uint8,\n palette: opt.palette,\n exifData: opt.exifData,\n iccProfile: opt.iccProfile,\n });\n } else {\n // create an empty image\n this._loopCount = 0;\n this._frameType = FrameType.sequence;\n this._frameDuration = 0;\n this._frameIndex = 0;\n }\n }\n\n public static fromResized(\n other: MemoryImage,\n width: number,\n height: number,\n skipAnimation = false\n ): MemoryImage {\n const image = new MemoryImage({\n width: width,\n height: height,\n loopCount: other._loopCount,\n frameType: other._frameType,\n frameDuration: other._frameDuration,\n frameIndex: other._frameIndex,\n backgroundColor: other._backgroundColor?.clone(),\n format: other.format,\n numChannels: other.numChannels,\n withPalette: other.hasPalette,\n paletteFormat: other.palette?.format,\n palette: other.palette,\n exifData: other._exifData?.clone(),\n iccProfile: other._iccProfile?.clone(),\n textData:\n other._textData !== undefined\n ? new Map(other._textData)\n : undefined,\n });\n\n if (other._extraChannels !== undefined) {\n image._extraChannels = new Map(\n other._extraChannels\n );\n }\n\n if (!skipAnimation) {\n const numFrames = other.numFrames;\n for (let fi = 1; fi < numFrames; ++fi) {\n const frame = other._frames[fi];\n image.addFrame(MemoryImage.fromResized(frame, width, height));\n }\n }\n\n return image;\n }\n\n /**\n * Creates a copy of the given **other** MemoryImage.\n */\n public static from(\n other: MemoryImage,\n skipAnimation = false,\n skipPixels = false\n ): MemoryImage {\n const image = new MemoryImage();\n image._data = other.data?.clone(skipPixels);\n image._exifData = other._exifData?.clone();\n image._iccProfile = other.iccProfile?.clone();\n image._frameType = other.frameType;\n image._loopCount = other._loopCount;\n image._backgroundColor = other._backgroundColor?.clone();\n image._frameDuration = other._frameDuration;\n image._frameIndex = other._frameIndex;\n if (other._extraChannels !== undefined) {\n image._extraChannels = new Map(\n other._extraChannels\n );\n }\n if (other._textData !== undefined) {\n image._textData = new Map(other.textData);\n }\n image._frames.push(image);\n if (!skipAnimation && other.hasAnimation) {\n const numFrames = other.numFrames;\n for (let fi = 1; fi < numFrames; ++fi) {\n const frame = other._frames[fi];\n image.addFrame(MemoryImage.from(frame));\n }\n }\n return image;\n }\n\n /**\n * Create an image from raw data in **bytes**.\n *\n * **format** defines the order of color channels in **bytes**.\n * An HTML canvas element stores colors in _Format.rgba_ format;\n * a MemoryImage object stores colors in _Format.rgba_ format.\n *\n * **rowStride** is the row stride, in bytes, of the source data **bytes**.\n * This may be different than the rowStride of the MemoryImage, as some data\n * sources align rows to different byte alignments and include padding.\n *\n * **order** can be used if the source **bytes** has a different channel order\n * than RGBA. _ChannelOrder.bgra_ will rearrange the color channels from\n * BGRA to what MemoryImage wants, RGBA.\n *\n * If **numChannels** and **order** are not provided, a default of 3 for\n * **numChannels** and _ChannelOrder.rgba_ for **order** will be assumed.\n */\n public static fromBytes(opt: MemoryImageFromBytesOptions): MemoryImage {\n const image = new MemoryImage();\n image._loopCount = opt.loopCount ?? 0;\n image._frameType = opt.frameType ?? FrameType.sequence;\n image._frameDuration = opt.frameDuration ?? 0;\n image._frameIndex = opt.frameIndex ?? 0;\n image._backgroundColor = opt.backgroundColor;\n image._textData = opt.textData;\n image._frames.push(image);\n\n const format = opt.format ?? Format.uint8;\n const withPalette = opt.withPalette ?? false;\n const paletteFormat = opt.paletteFormat ?? Format.uint8;\n const numChannels =\n opt.numChannels ??\n (opt.channelOrder !== undefined\n ? ChannelOrderLength.get(opt.channelOrder)!\n : 3);\n\n if (numChannels < 0 || numChannels > 4) {\n throw new LibError('A MemoryImage can only have 1-4 channels.');\n }\n\n let channelOrder =\n opt.channelOrder ??\n (numChannels === 3\n ? ChannelOrder.rgb\n : numChannels === 4\n ? ChannelOrder.rgba\n : numChannels === 1\n ? ChannelOrder.red\n : ChannelOrder.grayAlpha);\n\n if (numChannels === 1) {\n // There is only one channel order\n channelOrder = ChannelOrder.red;\n } else if (numChannels === 2) {\n // There is only one channel order\n channelOrder = ChannelOrder.grayAlpha;\n } else if (numChannels === 3) {\n if (\n channelOrder !== ChannelOrder.rgb &&\n channelOrder !== ChannelOrder.bgr\n ) {\n // The user asked for a channel order that conflicts with the number\n // of channels.\n channelOrder = ChannelOrder.rgb;\n }\n } else if (numChannels === 4) {\n if (\n channelOrder !== ChannelOrder.bgra &&\n channelOrder !== ChannelOrder.rgba &&\n channelOrder !== ChannelOrder.abgr &&\n channelOrder !== ChannelOrder.argb\n ) {\n // The user asked for a channel order that conflicts with the number\n // of channels.\n channelOrder = ChannelOrder.rgba;\n }\n }\n\n image.initialize({\n width: opt.width,\n height: opt.height,\n format: format,\n numChannels: numChannels,\n withPalette: withPalette,\n paletteFormat: paletteFormat,\n palette: opt.palette,\n exifData: opt.exifData,\n iccProfile: opt.iccProfile,\n });\n\n if (image.data !== undefined) {\n const toBytes = image.data.toUint8Array();\n const fromBytes = new Uint8Array(opt.bytes);\n\n const rowStride =\n opt.rowStride ?? opt.width * numChannels * FormatSize.get(format)!;\n const dataStride = image.data.rowStride;\n const stride = Math.min(rowStride, dataStride);\n\n let dOff = 0;\n let bOff = 0;\n for (\n let y = 0;\n y < opt.height;\n ++y, bOff += rowStride, dOff += dataStride\n ) {\n ArrayUtils.copyRange(fromBytes, bOff, bOff + stride, toBytes, dOff);\n }\n\n if (numChannels === 3 && channelOrder === ChannelOrder.bgr) {\n for (const p of image) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n } else if (numChannels === 4 && channelOrder === ChannelOrder.abgr) {\n for (const p of image) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (numChannels === 4 && channelOrder === ChannelOrder.argb) {\n for (const p of image) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (numChannels === 4 && channelOrder === ChannelOrder.bgra) {\n for (const p of image) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n }\n return image;\n }\n\n private initialize(opt: MemoryImageInitializeOptions): void {\n const format = opt.format ?? Format.uint8;\n const numChannels = opt.numChannels ?? 3;\n const withPalette = opt.withPalette ?? false;\n const paletteFormat = opt.paletteFormat ?? Format.uint8;\n\n if (numChannels < 1 || numChannels > 4) {\n throw new LibError(\n `Invalid number of channels for image (${numChannels}). Must be between 1 and 4.`\n );\n }\n\n this._iccProfile = opt.iccProfile;\n\n if (opt.exifData !== undefined) {\n this._exifData = opt.exifData.clone();\n }\n\n const palette =\n opt.palette ??\n (withPalette && this.supportsPalette\n ? this.createPalette(paletteFormat, numChannels)\n : undefined);\n\n this.createImageData(opt.width, opt.height, format, numChannels, palette);\n }\n\n private createImageData(\n width: number,\n height: number,\n format: Format,\n numChannels: number,\n palette?: Palette\n ): void {\n switch (format) {\n case Format.uint1:\n if (palette === undefined) {\n this._data = new MemoryImageDataUint1(width, height, numChannels);\n } else {\n this._data = MemoryImageDataUint1.palette(width, height, palette);\n }\n break;\n case Format.uint2:\n if (palette === undefined) {\n this._data = new MemoryImageDataUint2(width, height, numChannels);\n } else {\n this._data = MemoryImageDataUint2.palette(width, height, palette);\n }\n break;\n case Format.uint4:\n if (palette === undefined) {\n this._data = new MemoryImageDataUint4(width, height, numChannels);\n } else {\n this._data = MemoryImageDataUint4.palette(width, height, palette);\n }\n break;\n case Format.uint8:\n if (palette === undefined) {\n this._data = new MemoryImageDataUint8(width, height, numChannels);\n } else {\n this._data = MemoryImageDataUint8.palette(width, height, palette);\n }\n break;\n case Format.uint16:\n this._data = new MemoryImageDataUint16(width, height, numChannels);\n break;\n case Format.uint32:\n this._data = new MemoryImageDataUint32(width, height, numChannels);\n break;\n case Format.int8:\n this._data = new MemoryImageDataInt8(width, height, numChannels);\n break;\n case Format.int16:\n this._data = new MemoryImageDataInt16(width, height, numChannels);\n break;\n case Format.int32:\n this._data = new MemoryImageDataInt32(width, height, numChannels);\n break;\n case Format.float16:\n this._data = new MemoryImageDataFloat16(width, height, numChannels);\n break;\n case Format.float32:\n this._data = new MemoryImageDataFloat32(width, height, numChannels);\n break;\n case Format.float64:\n this._data = new MemoryImageDataFloat64(width, height, numChannels);\n break;\n }\n }\n\n private createPalette(\n paletteFormat: Format,\n numChannels: number\n ): Palette | undefined {\n switch (paletteFormat) {\n case Format.uint1:\n return undefined;\n case Format.uint2:\n return undefined;\n case Format.uint4:\n return undefined;\n case Format.uint8:\n return new PaletteUint8(this.numPixelColors, numChannels);\n case Format.uint16:\n return new PaletteUint16(this.numPixelColors, numChannels);\n case Format.uint32:\n return new PaletteUint32(this.numPixelColors, numChannels);\n case Format.int8:\n return new PaletteInt8(this.numPixelColors, numChannels);\n case Format.int16:\n return new PaletteInt16(this.numPixelColors, numChannels);\n case Format.int32:\n return new PaletteInt32(this.numPixelColors, numChannels);\n case Format.float16:\n return new PaletteFloat16(this.numPixelColors, numChannels);\n case Format.float32:\n return new PaletteFloat32(this.numPixelColors, numChannels);\n case Format.float64:\n return new PaletteFloat64(this.numPixelColors, numChannels);\n }\n throw new LibError('Unknown palette format.');\n }\n\n /**\n * Add a frame to the animation of this MemoryImage.\n */\n public addFrame(image?: MemoryImage): MemoryImage {\n const img = image ?? MemoryImage.from(this, true, true);\n img._frameIndex = this._frames.length;\n if (this._frames[this._frames.length - 1] !== img) {\n this._frames.push(img);\n }\n return img;\n }\n\n /**\n * Get a frame from this image. If the MemoryImage is not animated, this\n * MemoryImage will be returned; otherwise the particular frame MemoryImage will\n * be returned.\n */\n public getFrame(index: number): MemoryImage {\n return this._frames[index];\n }\n\n /**\n * Create a copy of this image.\n */\n public clone(opt?: MemoryImageCloneOptions): MemoryImage {\n const skipAnimation = opt?.skipAnimation ?? false;\n const skipPixels = opt?.skipPixels ?? false;\n return MemoryImage.from(this, skipAnimation, skipPixels);\n }\n\n public hasExtraChannel(name: string): boolean {\n return this._extraChannels !== undefined && this._extraChannels.has(name);\n }\n\n public getExtraChannel(name: string): MemoryImageData | undefined {\n return this._extraChannels !== undefined\n ? this._extraChannels.get(name)\n : undefined;\n }\n\n public setExtraChannel(name: string, data?: MemoryImageData): void {\n if (this._extraChannels === undefined && data === undefined) {\n return;\n }\n\n this._extraChannels ??= new Map();\n\n if (data === undefined) {\n this._extraChannels.delete(name);\n } else {\n this._extraChannels.set(name, data);\n }\n\n if (this._extraChannels.size === 0) {\n this._extraChannels = undefined;\n }\n }\n\n /**\n * Returns a pixel iterator for iterating over a rectangular range of pixels\n * in the image.\n */\n public getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator {\n return this.data!.getRange(x, y, width, height);\n }\n\n /**\n * Get a Uint8Array view of the image storage data.\n */\n public toUint8Array(): Uint8Array {\n return (\n this._data?.toUint8Array() ??\n (this.buffer !== undefined\n ? new Uint8Array(this.buffer)\n : new Uint8Array())\n );\n }\n\n /**\n * Similar to **toUint8Array**, but will convert the channels of the image pixels\n * to the given **order**. If that happens, the returned bytes will be a copy\n * and not a direct view of the image data.\n */\n public getBytes(order?: ChannelOrder): Uint8Array {\n return this._data?.getBytes(order) ?? this.toUint8Array();\n }\n\n /**\n * Remap the color channels to the given **order**. Normally MemoryImage color\n * channels are stored in rgba order for 4 channel images, and\n * rgb order for 3 channel images. This method lets you re-arrange the\n * color channels in-place without needing to clone the image for preparing\n * image data for external usage that requires alternative channel ordering.\n */\n public remapChannels(order: ChannelOrder): void {\n if (this.numChannels === 4) {\n if (\n order === ChannelOrder.abgr ||\n order === ChannelOrder.argb ||\n order === ChannelOrder.bgra\n ) {\n if (order === ChannelOrder.abgr) {\n for (const p of this) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = b;\n p.b = g;\n p.a = r;\n }\n } else if (order === ChannelOrder.argb) {\n for (const p of this) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = a;\n p.g = r;\n p.b = g;\n p.a = b;\n }\n } else if (order === ChannelOrder.bgra) {\n for (const p of this) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const a = p.a;\n p.r = b;\n p.g = g;\n p.b = r;\n p.a = a;\n }\n }\n }\n } else if (this.numChannels === 3) {\n if (order === ChannelOrder.bgr) {\n for (const p of this) {\n const r = p.r;\n p.r = p.b;\n p.b = r;\n }\n }\n }\n }\n\n /**\n * Returns true if the given pixel coordinates is within the dimensions\n * of the image.\n */\n public isBoundsSafe(x: number, y: number): boolean {\n return x >= 0 && y >= 0 && x < this.width && y < this.height;\n }\n\n /**\n * Create a Color object with the format and number of channels of the\n * image.\n */\n public getColor(r: number, g: number, b: number, a?: number): Color {\n return this._data?.getColor(r, g, b, a) ?? new ColorUint8(0);\n }\n\n /**\n * Return the Pixel at the given coordinates **x**,**y**. If **pixel** is provided,\n * it will be updated and returned rather than allocating a new Pixel.\n */\n public getPixel(x: number, y: number, pixel?: Pixel): Pixel {\n return this._data?.getPixel(x, y, pixel) ?? UndefinedPixel;\n }\n\n /**\n * Get the pixel from the given **x**, **y** coordinate. If the pixel coordinates\n * are out of bounds, PixelUndefined is returned.\n */\n public getPixelSafe(x: number, y: number, pixel?: Pixel): Pixel {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return UndefinedPixel;\n }\n return this.getPixel(x, y, pixel);\n }\n\n /**\n * Get the pixel from the given **x**, **y** coordinate. If the pixel coordinates\n * are out of range of the image, they will be clamped to the resolution.\n */\n public getPixelClamped(x: number, y: number, pixel?: Pixel): Pixel {\n const _x = MathUtils.clamp(x, 0, this.width - 1);\n const _y = MathUtils.clamp(y, 0, this.height - 1);\n return this.getPixel(_x, _y, pixel);\n }\n\n /**\n * Get the pixel using the given **interpolation** type for non-integer pixel\n * coordinates.\n */\n public getPixelInterpolate(\n fx: number,\n fy: number,\n interpolation = Interpolation.linear\n ): Color {\n switch (interpolation) {\n case Interpolation.nearest:\n return this.getPixelSafe(Math.trunc(fx), Math.trunc(fy));\n case Interpolation.linear:\n case Interpolation.average:\n return this.getPixelLinear(fx, fy);\n case Interpolation.cubic:\n return this.getPixelCubic(fx, fy);\n }\n throw new LibError('Unknown Interpolation mode.');\n }\n\n /**\n * Get the pixel using linear interpolation for non-integer pixel\n * coordinates.\n */\n public getPixelLinear(fx: number, fy: number): Color {\n const x = Math.trunc(fx) - (fx >= 0 ? 0 : 1);\n const nx = x + 1;\n const y = Math.trunc(fy) - (fy >= 0 ? 0 : 1);\n const ny = y + 1;\n const dx = fx - x;\n const dy = fy - y;\n\n const linear = (\n icc: number,\n inc: number,\n icn: number,\n inn: number\n ): number => {\n return (\n icc + dx * (inc - icc + dy * (icc + inn - icn - inc)) + dy * (icn - icc)\n );\n };\n\n const icc = this.getPixelSafe(x, y);\n const icn = ny >= this.height ? icc : this.getPixelSafe(x, ny);\n const inc = nx >= this.width ? icc : this.getPixelSafe(nx, y);\n const inn =\n nx >= this.width || ny >= this.height ? icc : this.getPixelSafe(nx, ny);\n\n return this.getColor(\n linear(icc.r, inc.r, icn.r, inn.r),\n linear(icc.g, inc.g, icn.g, inn.g),\n linear(icc.b, inc.b, icn.b, inn.b),\n linear(icc.a, inc.a, icn.a, inn.a)\n );\n }\n\n /**\n * Get the pixel using cubic interpolation for non-integer pixel\n * coordinates.\n */\n public getPixelCubic(fx: number, fy: number): Color {\n const x = Math.trunc(fx) - (fx >= 0 ? 0 : 1);\n const px = x - 1;\n const nx = x + 1;\n const ax = x + 2;\n const y = Math.trunc(fy) - (fy >= 0 ? 0 : 1);\n const py = y - 1;\n const ny = y + 1;\n const ay = y + 2;\n\n const dx = fx - x;\n const dy = fy - y;\n\n const cubic = (\n dx: number,\n ipp: number,\n icp: number,\n inp: number,\n iap: number\n ): number => {\n return (\n icp +\n 0.5 *\n (dx * (-ipp + inp) +\n dx * dx * (2 * ipp - 5 * icp + 4 * inp - iap) +\n dx * dx * dx * (-ipp + 3 * icp - 3 * inp + iap))\n );\n };\n\n const icc = this.getPixelSafe(x, y);\n\n const ipp = px < 0 || py < 0 ? icc : this.getPixelSafe(px, py);\n const icp = px < 0 ? icc : this.getPixelSafe(x, py);\n const inp = py < 0 || nx >= this.width ? icc : this.getPixelSafe(nx, py);\n const iap = ax >= this.width || py < 0 ? icc : this.getPixelSafe(ax, py);\n\n const ip0 = cubic(dx, ipp.r, icp.r, inp.r, iap.r);\n const ip1 = cubic(dx, ipp.g, icp.g, inp.g, iap.g);\n const ip2 = cubic(dx, ipp.b, icp.b, inp.b, iap.b);\n const ip3 = cubic(dx, ipp.a, icp.a, inp.a, iap.a);\n\n const ipc = px < 0 ? icc : this.getPixelSafe(px, y);\n const inc = nx >= this.width ? icc : this.getPixelSafe(nx, y);\n const iac = ax >= this.width ? icc : this.getPixelSafe(ax, y);\n\n const ic0 = cubic(dx, ipc.r, icc.r, inc.r, iac.r);\n const ic1 = cubic(dx, ipc.g, icc.g, inc.g, iac.g);\n const ic2 = cubic(dx, ipc.b, icc.b, inc.b, iac.b);\n const ic3 = cubic(dx, ipc.a, icc.a, inc.a, iac.a);\n\n const ipn = px < 0 || ny >= this.height ? icc : this.getPixelSafe(px, ny);\n const icn = ny >= this.height ? icc : this.getPixelSafe(x, ny);\n const inn =\n nx >= this.width || ny >= this.height ? icc : this.getPixelSafe(nx, ny);\n const ian =\n ax >= this.width || ny >= this.height ? icc : this.getPixelSafe(ax, ny);\n\n const in0 = cubic(dx, ipn.r, icn.r, inn.r, ian.r);\n const in1 = cubic(dx, ipn.g, icn.g, inn.g, ian.g);\n const in2 = cubic(dx, ipn.b, icn.b, inn.b, ian.b);\n const in3 = cubic(dx, ipn.a, icn.a, inn.a, ian.a);\n\n const ipa = px < 0 || ay >= this.height ? icc : this.getPixelSafe(px, ay);\n const ica = ay >= this.height ? icc : this.getPixelSafe(x, ay);\n const ina =\n nx >= this.width || ay >= this.height ? icc : this.getPixelSafe(nx, ay);\n const iaa =\n ax >= this.width || ay >= this.height ? icc : this.getPixelSafe(ax, ay);\n\n const ia0 = cubic(dx, ipa.r, ica.r, ina.r, iaa.r);\n const ia1 = cubic(dx, ipa.g, ica.g, ina.g, iaa.g);\n const ia2 = cubic(dx, ipa.b, ica.b, ina.b, iaa.b);\n const ia3 = cubic(dx, ipa.a, ica.a, ina.a, iaa.a);\n\n const c0 = cubic(dy, ip0, ic0, in0, ia0);\n const c1 = cubic(dy, ip1, ic1, in1, ia1);\n const c2 = cubic(dy, ip2, ic2, in2, ia2);\n const c3 = cubic(dy, ip3, ic3, in3, ia3);\n\n return this.getColor(\n Math.trunc(c0),\n Math.trunc(c1),\n Math.trunc(c2),\n Math.trunc(c3)\n );\n }\n\n /**\n * Set the color of the pixel at the given coordinates to the color of the\n * given Color **c**.\n */\n public setPixel(x: number, y: number, c: Color | Pixel): void {\n // TODO: improve the class check for being a Pixel\n if ('image' in c && 'index' in c) {\n if (c.image.hasPalette) {\n if (this.hasPalette) {\n this.setPixelIndex(x, y, c.index);\n return;\n }\n }\n }\n this._data?.setPixelRgba(x, y, c.r, c.g, c.b, c.a);\n }\n\n /**\n * Set the index value for palette images, or the red channel otherwise.\n */\n public setPixelIndex(x: number, y: number, i: number): void {\n this._data?.setPixelR(x, y, i);\n }\n\n /**\n * Set the red (or index) color channel of a pixel.\n */\n public setPixelR(x: number, y: number, i: number): void {\n this._data?.setPixelR(x, y, i);\n }\n\n /**\n * Set the color of the Pixel at the given coordinates to the given\n * color values **r**, **g**, **b**.\n */\n public setPixelRgb(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number\n ): void {\n this._data?.setPixelRgb(x, y, r, g, b);\n }\n\n /**\n * Set the color of the Pixel at the given coordinates to the given\n * color values **r**, **g**, **b**, and **a**.\n */\n public setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void {\n this._data?.setPixelRgba(x, y, r, g, b, a);\n }\n\n /**\n * Set all pixels in the image to the given **color**. If no color is provided\n * the image will be initialized to 0.\n */\n public clear(color?: Color): void {\n this._data?.clear(color);\n }\n\n /**\n * Convert this image to a new **format** or number of channels, **numChannels**.\n * If the new number of channels is 4 and the current image does\n * not have an alpha channel, then the given **alpha** value will be used\n * to set the new alpha channel. If **alpha** is not provided, then the\n * **maxChannelValue** will be used to set the alpha. If **withPalette** is\n * true, and to target format and **numChannels** has fewer than 256 colors,\n * then the new image will be converted to use a palette.\n */\n public convert(opt: MemoryImageConvertOptions): MemoryImage {\n const format = opt.format ?? this.format;\n const numChannels = opt.numChannels ?? this.numChannels;\n const alpha = opt.alpha ?? FormatMaxValue.get(format);\n let withPalette = opt.withPalette ?? false;\n const skipAnimation = opt.skipAnimation ?? false;\n\n if (\n (withPalette &&\n (numChannels >= 4 ||\n !(\n format === Format.uint1 ||\n format === Format.uint2 ||\n format === Format.uint4 ||\n (format === Format.uint8 && numChannels === 1)\n ))) ||\n (format < Format.uint8 && this.format >= Format.uint8)\n ) {\n withPalette = false;\n }\n\n if (\n format === this.format &&\n numChannels === this.numChannels &&\n ((!withPalette && this.palette === undefined) ||\n (withPalette && this.palette !== undefined))\n ) {\n // Same format and number of channels\n return MemoryImage.from(this);\n }\n\n let firstFrame: MemoryImage | undefined = undefined;\n for (const frame of this._frames) {\n const newImage = new MemoryImage({\n width: frame.width,\n height: frame.height,\n format: format,\n numChannels: numChannels,\n withPalette: withPalette,\n exifData: frame._exifData?.clone(),\n iccProfile: frame._iccProfile?.clone(),\n backgroundColor: frame._backgroundColor?.clone(),\n frameType: frame._frameType,\n loopCount: frame._loopCount,\n frameDuration: frame._frameDuration,\n textData:\n frame._textData !== undefined\n ? new Map(frame.textData)\n : undefined,\n });\n\n if (firstFrame !== undefined) {\n firstFrame.addFrame(newImage);\n } else {\n firstFrame = newImage;\n }\n\n const pal = newImage.palette;\n const f = newImage.palette?.format ?? format;\n if (pal !== undefined) {\n const usedColors = new Map();\n let numColors = 0;\n const op = frame.getPixel(0, 0);\n let c: Color | undefined = undefined;\n for (const np of newImage) {\n const nr = Math.floor(op.rNormalized * 255);\n const ng = Math.floor(op.gNormalized * 255);\n const nb = Math.floor(op.bNormalized * 255);\n const h = ColorUtils.rgbaToUint32(nr, ng, nb, 0);\n if (usedColors.has(h)) {\n np.index = usedColors.get(h)!;\n } else {\n usedColors.set(h, numColors);\n np.index = numColors;\n c = ColorUtils.convertColor({\n from: op,\n to: c,\n format: f,\n numChannels: numChannels,\n alpha: alpha,\n });\n pal.setRgb(numColors, c.r, c.g, c.b);\n numColors++;\n }\n op.next();\n }\n } else {\n const op = frame.getPixel(0, 0);\n for (const np of newImage) {\n ColorUtils.convertColor({\n from: op,\n to: np,\n alpha: alpha,\n });\n op.next();\n }\n }\n\n if (skipAnimation) {\n break;\n }\n }\n\n return firstFrame!;\n }\n\n /**\n * Add text metadata to the image.\n */\n public addTextData(data: Map): void {\n this._textData ??= new Map();\n for (const [key, value] of data) {\n this._textData.set(key, value);\n }\n }\n\n public getColorExtremes(): MemoryImageColorExtremes {\n let first = true;\n let min = 0;\n let max = 0;\n for (const p of this) {\n for (let i = 0; i < p.length; i++) {\n const c = p.getChannel(i);\n if (first || c < min) {\n min = c;\n }\n if (first || c > max) {\n max = c;\n }\n }\n first = false;\n }\n return {\n min: min,\n max: max,\n };\n }\n\n public toString(): string {\n return `${this.constructor.name} (w: ${this.width}, h: ${this.height}, f: ${\n Format[this.format]\n }, ch: ${this.numChannels})`;\n }\n\n /**\n * Returns a pixel iterator for iterating over all of the pixels in the\n * image.\n */\n public [Symbol.iterator](): Iterator {\n return this._data !== undefined\n ? this._data[Symbol.iterator]()\n : {\n next: () =>\n >{\n done: true,\n value: UndefinedPixel,\n },\n };\n }\n}\n", "/** @format */\n\nimport { Color } from '../color/color';\nimport { ColorRgb8 } from '../color/color-rgb8';\nimport { ColorRgba8 } from '../color/color-rgba8';\nimport { MathUtils } from '../common/math-utils';\nimport { MemoryImage } from './image';\nimport { PaletteUint32 } from './palette-uint32';\nimport { PaletteUint8 } from './palette-uint8';\nimport { Pixel } from './pixel';\nimport { Quantizer } from './quantizer';\n\n/**\n * Compute a color map with a given number of colors that best represents\n * the given image.\n */\nexport class NeuralQuantizer implements Quantizer {\n // No. of learning cycles\n private static readonly _numCycles: number = 100;\n\n // Alpha starts at 1\n private static readonly _alphaBiasShift: number = 10;\n\n // Biased by 10 bits\n private static readonly _initAlpha: number =\n 1 << NeuralQuantizer._alphaBiasShift;\n\n private static readonly _radiusBiasShift: number = 8;\n\n private static readonly _radiusBias: number =\n 1 << NeuralQuantizer._radiusBiasShift;\n\n private static readonly _alphaRadiusBiasShift: number =\n NeuralQuantizer._alphaBiasShift + NeuralQuantizer._radiusBiasShift;\n\n private static readonly alphaRadiusBias: number =\n 1 << NeuralQuantizer._alphaRadiusBiasShift;\n\n // Factor of 1/30 each cycle\n private static readonly _radiusDec: number = 30;\n\n private static readonly _gamma: number = 1024;\n\n private static readonly _beta: number = 1 / 1024;\n\n private static readonly _betaGamma: number =\n NeuralQuantizer._beta * NeuralQuantizer._gamma;\n\n // Four primes near 500 - assume no image has a length so large\n // that it is divisible by all four primes\n\n private static readonly _prime1 = 499;\n\n private static readonly _prime2 = 491;\n\n private static readonly _prime3 = 487;\n\n private static readonly _prime4 = 503;\n\n private static readonly _smallImageBytes = 3 * NeuralQuantizer._prime4;\n\n private readonly _netIndex = new Int32Array(256);\n\n private _samplingFactor: number;\n\n // Number of colors used\n private _netSize = 16;\n\n // Number of reserved colors used\n private _specials = 3;\n\n // Reserved background color\n private _bgColor = 0;\n\n private _cutNetSize = 0;\n\n private _maxNetPos = 0;\n\n // For 256 cols, radius starts at 32\n private _initRadius = 0;\n\n private _initBiasRadius = 0;\n\n private _radiusPower!: Int32Array;\n\n /**\n * The network itself\n */\n private _network!: number[];\n\n private _paletteInternal!: PaletteUint32;\n\n private _palette!: PaletteUint8;\n public get palette(): PaletteUint8 {\n return this._palette;\n }\n\n /**\n * Bias array for learning\n */\n private _bias!: number[];\n\n // Freq array for learning\n private _freq!: number[];\n\n /**\n * How many colors are in the **palette**?\n */\n public get numColors(): number {\n return this._netSize;\n }\n\n /**\n * 10 is a reasonable **samplingFactor** according to\n * https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/.\n */\n constructor(image: MemoryImage, numberOfColors = 256, samplingFactor = 10) {\n this._samplingFactor = samplingFactor;\n this.initialize(numberOfColors);\n this.addImage(image);\n }\n\n private initialize(numberOfColors: number): void {\n // Number of colours used\n this._netSize = Math.max(numberOfColors, 4);\n this._cutNetSize = this._netSize - this._specials;\n this._maxNetPos = this._netSize - 1;\n // For 256 cols, radius starts at 32\n this._initRadius = Math.floor(this._netSize / 8);\n this._initBiasRadius = this._initRadius * NeuralQuantizer._radiusBias;\n this._paletteInternal = new PaletteUint32(256, 4);\n this._palette = new PaletteUint8(256, 3);\n // Number of reserved colors used\n this._specials = 3;\n this._bgColor = this._specials - 1;\n this._radiusPower = new Int32Array(this._netSize >> 3);\n\n this._network = new Array(this._netSize * 3).fill(0);\n this._bias = new Array(this._netSize).fill(0);\n this._freq = new Array(this._netSize).fill(0);\n\n // Black\n this._network[0] = 0.0;\n this._network[1] = 0.0;\n this._network[2] = 0.0;\n\n // White\n this._network[3] = 255.0;\n this._network[4] = 255.0;\n this._network[5] = 255.0;\n\n // RESERVED bgColor\n // background\n const f = 1 / this._netSize;\n for (let i = 0; i < this._specials; ++i) {\n this._freq[i] = f;\n this._bias[i] = 0.0;\n }\n\n for (\n let i = this._specials, p = this._specials * 3;\n i < this._netSize;\n ++i\n ) {\n this._network[p++] = (255 * (i - this._specials)) / this._cutNetSize;\n this._network[p++] = (255 * (i - this._specials)) / this._cutNetSize;\n this._network[p++] = (255 * (i - this._specials)) / this._cutNetSize;\n\n this._freq[i] = f;\n this._bias[i] = 0.0;\n }\n }\n\n private updateRadiusPower(rad: number, alpha: number): void {\n for (let i = 0; i < rad; i++) {\n this._radiusPower[i] = Math.trunc(\n alpha *\n (((rad * rad - i * i) * NeuralQuantizer._radiusBias) / (rad * rad))\n );\n }\n }\n\n private specialFind(b: number, g: number, r: number): number {\n for (let i = 0, p = 0; i < this._specials; i++) {\n if (\n this._network[p++] === b &&\n this._network[p++] === g &&\n this._network[p++] === r\n ) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Search for biased BGR values\n */\n private contest(b: number, g: number, r: number): number {\n // Finds closest neuron (min dist) and updates freq\n // finds best neuron (min dist-bias) and returns position\n // for frequently chosen neurons, freq[i] is high and bias[i] is negative\n // bias[i] = gamma*((1/netSize)-freq[i])\n\n let bestD = 1.0e30;\n let bestBiasDist = bestD;\n let bestPos = -1;\n let bestBiasPos = bestPos;\n\n for (\n let i = this._specials, p = this._specials * 3;\n i < this._netSize;\n i++\n ) {\n let dist = this._network[p++] - b;\n if (dist < 0) {\n dist = -dist;\n }\n let a = this._network[p++] - g;\n if (a < 0) {\n a = -a;\n }\n dist += a;\n a = this._network[p++] - r;\n if (a < 0) {\n a = -a;\n }\n dist += a;\n if (dist < bestD) {\n bestD = dist;\n bestPos = i;\n }\n\n const biasDist = dist - this._bias[i];\n if (biasDist < bestBiasDist) {\n bestBiasDist = biasDist;\n bestBiasPos = i;\n }\n this._freq[i] -= NeuralQuantizer._beta * this._freq[i];\n this._bias[i] += NeuralQuantizer._betaGamma * this._freq[i];\n }\n\n this._freq[bestPos] += NeuralQuantizer._beta;\n this._bias[bestPos] -= NeuralQuantizer._betaGamma;\n return bestBiasPos;\n }\n\n private alterSingle(\n alpha: number,\n i: number,\n b: number,\n g: number,\n r: number\n ): void {\n // Move neuron i towards biased (b,g,r) by factor alpha\n const p = i * 3;\n this._network[p] -= alpha * (this._network[p] - b);\n this._network[p + 1] -= alpha * (this._network[p + 1] - g);\n this._network[p + 2] -= alpha * (this._network[p + 2] - r);\n }\n\n private alterNeighbors(\n _: number,\n rad: number,\n i: number,\n b: number,\n g: number,\n r: number\n ): void {\n let lo = i - rad;\n if (lo < this._specials - 1) {\n lo = this._specials - 1;\n }\n\n let hi = i + rad;\n if (hi > this._netSize) {\n hi = this._netSize;\n }\n\n let j = i + 1;\n let k = i - 1;\n let m = 1;\n while (j < hi || k > lo) {\n const a = this._radiusPower[m++];\n if (j < hi) {\n const p = j * 3;\n this._network[p] -=\n (a * (this._network[p] - b)) / NeuralQuantizer.alphaRadiusBias;\n this._network[p + 1] -=\n (a * (this._network[p + 1] - g)) / NeuralQuantizer.alphaRadiusBias;\n this._network[p + 2] -=\n (a * (this._network[p + 2] - r)) / NeuralQuantizer.alphaRadiusBias;\n j++;\n }\n if (k > lo) {\n const p = k * 3;\n this._network[p] -=\n (a * (this._network[p] - b)) / NeuralQuantizer.alphaRadiusBias;\n this._network[p + 1] -=\n (a * (this._network[p + 1] - g)) / NeuralQuantizer.alphaRadiusBias;\n this._network[p + 2] -=\n (a * (this._network[p + 2] - r)) / NeuralQuantizer.alphaRadiusBias;\n k--;\n }\n }\n }\n\n private learn(image: MemoryImage): void {\n let biasRadius = this._initBiasRadius;\n const alphaDec = 30 + Math.floor((this._samplingFactor - 1) / 3);\n const lengthCount = image.width * image.height;\n const samplePixels = Math.floor(lengthCount / this._samplingFactor);\n let delta = Math.max(\n Math.floor(samplePixels / NeuralQuantizer._numCycles),\n 1\n );\n let alpha = NeuralQuantizer._initAlpha;\n\n if (delta === 0) {\n delta = 1;\n }\n\n let rad = biasRadius >> NeuralQuantizer._radiusBiasShift;\n if (rad <= 1) {\n rad = 0;\n }\n\n this.updateRadiusPower(rad, alpha);\n\n let step = 0;\n let pos = 0;\n if (lengthCount < NeuralQuantizer._smallImageBytes) {\n this._samplingFactor = 1;\n step = 1;\n } else if (lengthCount % NeuralQuantizer._prime1 !== 0) {\n step = NeuralQuantizer._prime1;\n } else {\n if (lengthCount % NeuralQuantizer._prime2 !== 0) {\n step = NeuralQuantizer._prime2;\n } else {\n if (lengthCount % NeuralQuantizer._prime3 !== 0) {\n step = NeuralQuantizer._prime3;\n } else {\n step = NeuralQuantizer._prime4;\n }\n }\n }\n\n const w = image.width;\n const h = image.height;\n\n let x = 0;\n let y = 0;\n let i = 0;\n while (i < samplePixels) {\n const p = image.getPixel(x, y);\n\n const red = p.r;\n const green = p.g;\n const blue = p.b;\n\n if (i === 0) {\n // Remember background colour\n this._network[this._bgColor * 3] = blue;\n this._network[this._bgColor * 3 + 1] = green;\n this._network[this._bgColor * 3 + 2] = red;\n }\n\n let j = this.specialFind(blue, green, red);\n j = j < 0 ? this.contest(blue, green, red) : j;\n\n if (j >= this._specials) {\n // Don't learn for specials\n const a = Number(alpha) / NeuralQuantizer._initAlpha;\n this.alterSingle(a, j, blue, green, red);\n if (rad > 0) {\n // Alter neighbours\n this.alterNeighbors(a, rad, j, blue, green, red);\n }\n }\n\n pos += step;\n x += step;\n while (x > w) {\n x -= w;\n y++;\n }\n while (pos >= lengthCount) {\n pos -= lengthCount;\n y -= h;\n }\n\n i++;\n if (i % delta === 0) {\n alpha -= Math.floor(alpha / alphaDec);\n biasRadius -= Math.floor(biasRadius / NeuralQuantizer._radiusDec);\n rad = biasRadius >> NeuralQuantizer._radiusBiasShift;\n if (rad <= 1) {\n rad = 0;\n }\n this.updateRadiusPower(rad, alpha);\n }\n }\n }\n\n private fix(): void {\n for (let i = 0, p = 0; i < this._netSize; i++) {\n for (let j = 0; j < 3; ++j, ++p) {\n const x = MathUtils.clampInt255(Math.trunc(0.5 + this._network[p]));\n this._paletteInternal.set(i, j, x);\n }\n this._paletteInternal.set(i, 3, i);\n }\n }\n\n /**\n * Insertion sort of network and building of netindex[0..255]\n */\n private inxBuild(): void {\n let previousColor = 0;\n let startPos = 0;\n\n for (let i = 0; i < this._netSize; i++) {\n let smallPos = i;\n // index on g\n let smallVal = this._paletteInternal.get(i, 1);\n\n // find smallest in i..netSize-1\n for (let j = i + 1; j < this._netSize; j++) {\n if (this._paletteInternal.get(j, 1) < smallVal) {\n smallPos = j;\n // index on g\n smallVal = this._paletteInternal.get(j, 1);\n }\n }\n\n const p = i;\n const q = smallPos;\n\n // swap p (i) and q (smallPos) entries\n if (i !== smallPos) {\n let j = this._paletteInternal.get(q, 0);\n this._paletteInternal.set(q, 0, this._paletteInternal.get(p, 0));\n this._paletteInternal.set(p, 0, j);\n\n j = this._paletteInternal.get(q, 1);\n this._paletteInternal.set(q, 1, this._paletteInternal.get(p, 1));\n this._paletteInternal.set(p, 1, j);\n\n j = this._paletteInternal.get(q, 2);\n this._paletteInternal.set(q, 2, this._paletteInternal.get(p, 2));\n this._paletteInternal.set(p, 2, j);\n\n j = this._paletteInternal.get(q, 3);\n this._paletteInternal.set(q, 3, this._paletteInternal.get(p, 3));\n this._paletteInternal.set(p, 3, j);\n }\n\n // smallVal entry is now in position i\n if (smallVal !== previousColor) {\n this._netIndex[previousColor] = (startPos + i) >> 1;\n for (let j = previousColor + 1; j < smallVal; j++) {\n this._netIndex[j] = i;\n }\n previousColor = Math.trunc(smallVal);\n startPos = i;\n }\n }\n\n this._netIndex[previousColor] = (startPos + this._maxNetPos) >> 1;\n for (let j = previousColor + 1; j < 256; j++) {\n // really 256\n this._netIndex[j] = this._maxNetPos;\n }\n }\n\n private copyPalette(): void {\n for (let i = 0; i < this._netSize; ++i) {\n this._palette.setRgb(\n i,\n Math.abs(this._paletteInternal.get(i, 2)),\n Math.abs(this._paletteInternal.get(i, 1)),\n Math.abs(this._paletteInternal.get(i, 0))\n );\n }\n }\n\n /**\n * Search for BGR values 0..255 and return color index\n */\n private inxSearch(b: number, g: number, r: number): number {\n // Biggest possible dist is 256*3\n let bestD = 1000;\n let best = -1;\n // Index on g\n let i = this._netIndex[g];\n // Start at netIndex[g] and work outwards\n let j = i - 1;\n\n while (i < this._netSize || j >= 0) {\n if (i < this._netSize) {\n // Inx key\n let dist = this._paletteInternal.get(i, 1) - g;\n if (dist >= bestD) {\n // Stop iter\n i = this._netSize;\n } else {\n if (dist < 0) {\n dist = -dist;\n }\n let a = this._paletteInternal.get(i, 0) - b;\n if (a < 0) {\n a = -a;\n }\n dist += a;\n if (dist < bestD) {\n a = this._paletteInternal.get(i, 2) - r;\n if (a < 0) {\n a = -a;\n }\n dist += a;\n if (dist < bestD) {\n bestD = Math.trunc(dist);\n best = i;\n }\n }\n i++;\n }\n }\n\n if (j >= 0) {\n const p = j * 4;\n // Inx key - reverse dif\n let dist = g - this._paletteInternal.get(j, 1);\n if (dist >= bestD) {\n // Stop iter\n j = -1;\n } else {\n if (dist < 0) {\n dist = -dist;\n }\n let a = this._paletteInternal.get(j, 0) - b;\n if (a < 0) {\n a = -a;\n }\n dist += a;\n if (dist < bestD) {\n a = this._paletteInternal.get(j, 2) - r;\n if (a < 0) {\n a = -a;\n }\n dist += a;\n if (dist < bestD) {\n bestD = Math.trunc(dist);\n best = j;\n }\n }\n j--;\n }\n }\n }\n return best;\n }\n\n /**\n * Find the index of the closest color to **c** in the **palette**.\n */\n public getColorIndex(c: Color): number {\n const r = Math.trunc(c.r);\n const g = Math.trunc(c.g);\n const b = Math.trunc(c.b);\n return this.inxSearch(b, g, r);\n }\n\n /**\n * Find the index of the closest color to **r**,**g**,**b** in the **palette**.\n */\n public getColorIndexRgb(r: number, g: number, b: number): number {\n return this.inxSearch(b, g, r);\n }\n\n /**\n * Find the color closest to **c** in the **palette**.\n */\n public getQuantizedColor(c: Color): Color {\n const i = this.getColorIndex(c);\n const out =\n c.length === 4 ? new ColorRgba8(0, 0, 0, 255) : new ColorRgb8(0, 0, 0);\n out.r = this.palette.get(i, 0);\n out.g = this.palette.get(i, 1);\n out.b = this.palette.get(i, 2);\n if (c.length === 4) {\n out.a = c.a;\n }\n return out;\n }\n\n /**\n * Convert the **image** to a palette image.\n */\n public getIndexImage(image: MemoryImage): MemoryImage {\n const target = new MemoryImage({\n width: image.width,\n height: image.height,\n numChannels: 1,\n palette: this.palette,\n });\n\n const imageIt = image[Symbol.iterator]();\n const targetIt = target[Symbol.iterator]();\n let imageItRes: IteratorResult | undefined = undefined;\n let targetItRes: IteratorResult | undefined = undefined;\n while (\n (((imageItRes = imageIt.next()), (targetItRes = targetIt.next())),\n !imageItRes.done && !targetItRes.done)\n ) {\n const t = targetItRes.value;\n t.setChannel(0, this.getColorIndex(imageItRes.value));\n }\n\n return target;\n }\n\n /**\n * Add an image to the quantized color table.\n */\n public addImage(image: MemoryImage): void {\n this.learn(image);\n this.fix();\n this.inxBuild();\n this.copyPalette();\n }\n}\n", "/** @format */\n\nimport { OctreeNode } from './octree-node';\n\nexport class HeapNode {\n private _buf: Array = [undefined];\n public get buf(): Array {\n return this._buf;\n }\n\n public get n(): number {\n return this._buf.length;\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\n\nexport class OctreeNode {\n // sum of all colors represented by this node.\n private _r = 0;\n public get r(): number {\n return this._r;\n }\n public set r(v: number) {\n this._r = v;\n }\n\n private _g = 0;\n public get g(): number {\n return this._g;\n }\n public set g(v: number) {\n this._g = v;\n }\n\n private _b = 0;\n public get b(): number {\n return this._b;\n }\n public set b(v: number) {\n this._b = v;\n }\n\n private _count = 0;\n public get count(): number {\n return this._count;\n }\n public set count(v: number) {\n this._count = v;\n }\n\n private _heapIndex = 0;\n public get heapIndex(): number {\n return this._heapIndex;\n }\n public set heapIndex(v: number) {\n this._heapIndex = v;\n }\n\n private _paletteIndex = 0;\n public get paletteIndex(): number {\n return this._paletteIndex;\n }\n public set paletteIndex(v: number) {\n this._paletteIndex = v;\n }\n\n private _parent: OctreeNode | undefined;\n public get parent(): OctreeNode | undefined {\n return this._parent;\n }\n\n private _children: Array = ArrayUtils.fill<\n OctreeNode | undefined\n >(8, undefined);\n public get children(): Array {\n return this._children;\n }\n\n private _childCount = 0;\n public get childCount(): number {\n return this._childCount;\n }\n public set childCount(v: number) {\n this._childCount = v;\n }\n\n private _childIndex = 0;\n public get childIndex(): number {\n return this._childIndex;\n }\n\n private _flags = 0;\n public get flags(): number {\n return this._flags;\n }\n public set flags(v: number) {\n this._flags = v;\n }\n\n private _depth = 0;\n public get depth(): number {\n return this._depth;\n }\n\n constructor(childIndex: number, depth: number, parent?: OctreeNode) {\n this._childIndex = childIndex;\n this._depth = depth;\n this._parent = parent;\n if (parent !== undefined) {\n parent._childCount++;\n }\n }\n}\n", "/** @format */\n\nimport { Color } from '../color/color';\nimport { ColorRgb8 } from '../color/color-rgb8';\nimport { HeapNode } from './heap-node';\nimport { MemoryImage } from './image';\nimport { OctreeNode } from './octree-node';\nimport { PaletteUint8 } from './palette-uint8';\nimport { Pixel } from './pixel';\nimport { Quantizer } from './quantizer';\n\n/**\n * Color quantization using octree,\n * from https://rosettacode.org/wiki/Color_quantization/C\n */\nexport class OctreeQuantizer implements Quantizer {\n private static readonly _inHeap = 1;\n\n private readonly _root: OctreeNode;\n\n private _palette!: PaletteUint8;\n public get palette(): PaletteUint8 {\n return this._palette;\n }\n\n constructor(image: MemoryImage, numberOfColors = 256) {\n this._root = new OctreeNode(0, 0);\n const heap = new HeapNode();\n for (const p of image) {\n const r = Math.trunc(p.r);\n const g = Math.trunc(p.g);\n const b = Math.trunc(p.b);\n this.heapAdd(heap, this.nodeInsert(this._root, r, g, b));\n }\n\n const nc = numberOfColors + 1;\n while (heap.n > nc) {\n this.heapAdd(heap, this.nodeFold(this.popHeap(heap)!)!);\n }\n\n for (let i = 1; i < heap.n; i++) {\n const got = heap.buf[i]!;\n const c = got.count;\n got.r = Math.round(got.r / c);\n got.g = Math.round(got.g / c);\n got.b = Math.round(got.b / c);\n }\n\n const nodes: OctreeNode[] = [];\n this.getNodes(nodes, this._root);\n\n this._palette = new PaletteUint8(nodes.length, 3);\n const l = nodes.length;\n for (let i = 0; i < l; ++i) {\n nodes[i].paletteIndex = i;\n const n = nodes[i];\n this._palette.setRgb(i, n.r, n.g, n.b);\n }\n }\n\n private nodeInsert(\n root: OctreeNode,\n r: number,\n g: number,\n b: number\n ): OctreeNode {\n let _root = root;\n\n let depth = 0;\n for (let bit = 1 << 7; ++depth < 8; bit >>= 1) {\n const i =\n ((g & bit) !== 0 ? 1 : 0) * 4 +\n ((r & bit) !== 0 ? 1 : 0) * 2 +\n ((b & bit) !== 0 ? 1 : 0);\n if (_root.children[i] === undefined) {\n _root.children[i] = new OctreeNode(i, depth, _root);\n }\n _root = _root.children[i]!;\n }\n\n _root.r += r;\n _root.g += g;\n _root.b += b;\n _root.count++;\n return _root;\n }\n\n private popHeap(h: HeapNode): OctreeNode | undefined {\n if (h.n <= 1) {\n return undefined;\n }\n\n const ret = h.buf[1];\n h.buf[1] = h.buf.pop();\n h.buf[1]!.heapIndex = 1;\n this.downHeap(h, h.buf[1]!);\n\n return ret;\n }\n\n private heapAdd(h: HeapNode, p: OctreeNode): void {\n if ((p.flags & OctreeQuantizer._inHeap) !== 0) {\n this.downHeap(h, p);\n this.upHeap(h, p);\n return;\n }\n\n p.flags |= OctreeQuantizer._inHeap;\n p.heapIndex = h.n;\n h.buf.push(p);\n this.upHeap(h, p);\n }\n\n private downHeap(h: HeapNode, p: OctreeNode): void {\n let n = p.heapIndex;\n while (true) {\n let m = n * 2;\n if (m >= h.n) {\n break;\n }\n if (m + 1 < h.n && this.compareNode(h.buf[m]!, h.buf[m + 1]!) > 0) {\n m++;\n }\n\n if (this.compareNode(p, h.buf[m]!) <= 0) {\n break;\n }\n\n h.buf[n] = h.buf[m];\n h.buf[n]!.heapIndex = n;\n n = m;\n }\n\n h.buf[n] = p;\n p.heapIndex = n;\n }\n\n private upHeap(h: HeapNode, p: OctreeNode): void {\n let n = p.heapIndex;\n let prev: OctreeNode | undefined = undefined;\n\n while (n > 1) {\n prev = h.buf[Math.trunc(n / 2)];\n if (this.compareNode(p, prev!) >= 0) {\n break;\n }\n\n h.buf[n] = prev;\n prev!.heapIndex = n;\n n = Math.trunc(n / 2);\n }\n h.buf[n] = p;\n p.heapIndex = n;\n }\n\n private nodeFold(p: OctreeNode): OctreeNode | undefined {\n if (p.childCount > 0) {\n return undefined;\n }\n const q = p.parent!;\n q.count += p.count;\n\n q.r += p.r;\n q.g += p.g;\n q.b += p.b;\n q.childCount--;\n q.children[p.childIndex] = undefined;\n return q;\n }\n\n private compareNode(a: OctreeNode, b: OctreeNode): number {\n if (a.childCount < b.childCount) {\n return -1;\n }\n if (a.childCount > b.childCount) {\n return 1;\n }\n\n const ac = a.count >> a.depth;\n const bc = b.count >> b.depth;\n return ac < bc ? -1 : ac > bc ? 1 : 0;\n }\n\n private getNodes(nodes: OctreeNode[], node: OctreeNode): void {\n if (node.childCount === 0) {\n nodes.push(node);\n return;\n }\n for (const n of node.children) {\n if (n !== undefined) {\n this.getNodes(nodes, n);\n }\n }\n }\n\n public getColorIndex(c: Color): number {\n return this.getColorIndexRgb(\n Math.trunc(c.r),\n Math.trunc(c.g),\n Math.trunc(c.b)\n );\n }\n\n public getColorIndexRgb(r: number, g: number, b: number): number {\n let root: OctreeNode | undefined = this._root;\n for (let bit = 1 << 7; bit !== 0; bit >>= 1) {\n const i =\n ((g & bit) !== 0 ? 1 : 0) * 4 +\n ((r & bit) !== 0 ? 1 : 0) * 2 +\n ((b & bit) !== 0 ? 1 : 0);\n if (root!.children[i] === undefined) {\n break;\n }\n root = root!.children[i];\n }\n return root?.paletteIndex ?? 0;\n }\n\n /**\n * Find the index of the closest color to **c** in the **palette**.\n */\n public getQuantizedColor(c: Color): Color {\n let r = Math.trunc(c.r);\n let g = Math.trunc(c.g);\n let b = Math.trunc(c.b);\n let root: OctreeNode | undefined = this._root;\n\n for (let bit = 1 << 7; bit !== 0; bit >>= 1) {\n const i =\n ((g & bit) !== 0 ? 1 : 0) * 4 +\n ((r & bit) !== 0 ? 1 : 0) * 2 +\n ((b & bit) !== 0 ? 1 : 0);\n if (root!.children[i] === undefined) {\n break;\n }\n root = root!.children[i];\n }\n\n r = root!.r;\n g = root!.g;\n b = root!.b;\n\n return new ColorRgb8(r, g, b);\n }\n\n /**\n * Convert the **image** to a palette image.\n */\n public getIndexImage(image: MemoryImage): MemoryImage {\n const target = new MemoryImage({\n width: image.width,\n height: image.height,\n numChannels: 1,\n palette: this.palette,\n });\n\n const imageIt = image[Symbol.iterator]();\n const targetIt = target[Symbol.iterator]();\n let imageItRes: IteratorResult | undefined = undefined;\n let targetItRes: IteratorResult | undefined = undefined;\n while (\n (((imageItRes = imageIt.next()), (targetItRes = targetIt.next())),\n !imageItRes.done && !targetItRes.done)\n ) {\n const t = targetItRes.value;\n t.setChannel(0, this.getColorIndex(imageItRes.value));\n }\n\n return target;\n }\n}\n", "/** @format */\n\nexport enum NoiseType {\n gaussian,\n uniform,\n saltAndPepper,\n poisson,\n rice,\n}\n", "/** @format */\n\nexport enum PixelateMode {\n /**\n * Use the top-left pixel of a block for the block color.\n */\n upperLeft,\n\n /**\n * Use the average of the pixels within a block for the block color.\n */\n average,\n}\n", "/** @format */\n\nexport enum QuantizeMethod {\n neuralNet,\n octree,\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { ArrayUtils } from '../common/array-utils';\nimport { MathUtils } from '../common/math-utils';\nimport { MemoryImage } from '../image/image';\n\nexport interface SeparableKernelApplyOptions {\n src: MemoryImage;\n dst: MemoryImage;\n horizontal?: boolean;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\n/**\n * A kernel object to use with **separableConvolution** filter.\n */\nexport class SeparableKernel {\n private readonly _coefficients: number[];\n private readonly _size: number;\n\n /**\n * Get the number of coefficients in the kernel.\n */\n public get length() {\n return this._coefficients.length;\n }\n\n /**\n * Create a separable convolution kernel for the given **size**.\n */\n constructor(size: number) {\n this._size = size;\n this._coefficients = ArrayUtils.fill(2 * size + 1, 0);\n }\n\n private reflect(max: number, x: number): number {\n if (x < 0) {\n return -x;\n }\n if (x >= max) {\n return max - (x - max) - 1;\n }\n return x;\n }\n\n private applyCoefficientsLine(\n src: MemoryImage,\n dst: MemoryImage,\n y: number,\n width: number,\n horizontal: boolean,\n maskChannel: Channel,\n mask?: MemoryImage\n ): void {\n for (let x = 0; x < width; x++) {\n let r = 0;\n let g = 0;\n let b = 0;\n let a = 0;\n\n for (let j = -this._size, j2 = 0; j <= this._size; ++j, ++j2) {\n const c = this._coefficients[j2];\n const gr = this.reflect(width, x + j);\n\n const sc = horizontal ? src.getPixel(gr, y) : src.getPixel(y, gr);\n\n r += c * sc.r;\n g += c * sc.g;\n b += c * sc.b;\n a += c * sc.a;\n }\n\n const p = horizontal ? dst.getPixel(x, y) : dst.getPixel(y, x);\n\n const msk = mask?.getPixel(p.x, p.y).getChannelNormalized(maskChannel);\n if (msk === undefined) {\n p.setRgba(r, g, b, a);\n } else {\n p.r = MathUtils.mix(p.r, r, msk);\n p.g = MathUtils.mix(p.g, g, msk);\n p.b = MathUtils.mix(p.b, b, msk);\n p.a = MathUtils.mix(p.a, a, msk);\n }\n }\n }\n\n /**\n * Get a coefficient from the kernel.\n */\n public getCoefficient(index: number) {\n return this._coefficients[index];\n }\n\n /**\n * Set a coefficient in the kernel.\n */\n public setCoefficient(index: number, c: number) {\n this._coefficients[index] = c;\n }\n\n /**\n * Apply the kernel to the **src** image, storing the results in **dst**,\n * for a single dimension. If **horizontal** is true, the filter will be\n * applied to the horizontal axis, otherwise it will be applied to the\n * vertical axis.\n */\n public apply(opt: SeparableKernelApplyOptions): void {\n const horizontal = opt.horizontal ?? true;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (horizontal) {\n for (let y = 0; y < opt.src.height; ++y) {\n this.applyCoefficientsLine(\n opt.src,\n opt.dst,\n y,\n opt.src.width,\n horizontal,\n maskChannel,\n opt.mask\n );\n }\n } else {\n for (let x = 0; x < opt.src.width; ++x) {\n this.applyCoefficientsLine(\n opt.src,\n opt.dst,\n x,\n opt.src.height,\n horizontal,\n maskChannel,\n opt.mask\n );\n }\n }\n }\n\n /**\n * Scale all of the coefficients by **s**.\n */\n public scaleCoefficients(s: number): void {\n for (let i = 0; i < this._coefficients.length; ++i) {\n this._coefficients[i] *= s;\n }\n }\n}\n", "/** @format */\n\nimport { Channel } from '../color/channel';\nimport { Color } from '../color/color';\nimport { ColorRgba8 } from '../color/color-rgba8';\nimport { Interpolation } from '../common/interpolation';\nimport { MathUtils } from '../common/math-utils';\nimport { NeuralQuantizer } from '../image/neural-quantizer';\nimport { OctreeQuantizer } from '../image/octree-quantizer';\nimport { Quantizer } from '../image/quantizer';\nimport { RandomUtils } from '../common/random-utils';\nimport { Draw } from '../draw/draw';\nimport { MemoryImage } from '../image/image';\nimport { DitherKernel, DitherKernels } from './dither-kernel';\nimport { NoiseType } from './noise-type';\nimport { PixelateMode } from './pixelate-mode';\nimport { QuantizeMethod } from './quantize-method';\nimport { SeparableKernel } from './separable-kernel';\nimport { ColorUtils } from '../color/color-utils';\n\ninterface ContrastCache {\n lastContrast: number;\n contrast: Uint8Array;\n}\n\nexport interface AdjustColorOptions {\n image: MemoryImage;\n blacks?: Color;\n whites?: Color;\n mids?: Color;\n contrast?: number;\n saturation?: number;\n brightness?: number;\n gamma?: number;\n exposure?: number;\n hue?: number;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface BillboardOptions {\n image: MemoryImage;\n grid?: number;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface BleachBypassOptions {\n image: MemoryImage;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface BulgeDistortionOptions {\n image: MemoryImage;\n centerX?: number;\n centerY?: number;\n radius?: number;\n scale?: number;\n interpolation?: Interpolation;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface BumpToNormalOptions {\n image: MemoryImage;\n strength?: number;\n}\n\nexport interface ChromaticAberrationOptions {\n image: MemoryImage;\n shift?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface ColorHalftone {\n image: MemoryImage;\n amount?: number;\n centerX?: number;\n centerY?: number;\n angle?: number;\n size?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface ColorOffsetOptions {\n image: MemoryImage;\n red?: number;\n green?: number;\n blue?: number;\n alpha?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface ContrastOptions {\n image: MemoryImage;\n contrast: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface ConvolutionOptions {\n image: MemoryImage;\n filter: number[];\n div?: number;\n offset?: number;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface CopyImageChannelsOptions {\n image: MemoryImage;\n from: MemoryImage;\n scaled?: boolean;\n red?: Channel;\n green?: Channel;\n blue?: Channel;\n alpha?: Channel;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface DitherImageOptions {\n image: MemoryImage;\n quantizer?: Quantizer;\n kernel?: DitherKernel;\n serpentine?: boolean;\n}\n\nexport interface DotScreenOptions {\n image: MemoryImage;\n angle?: number;\n size?: number;\n centerX?: number;\n centerY?: number;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface DropShadowOptions {\n image: MemoryImage;\n hShadow: number;\n vShadow: number;\n blur: number;\n shadowColor?: Color;\n}\n\nexport interface EdgeGlowOptions {\n image: MemoryImage;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface EmbossOptions {\n image: MemoryImage;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface GammaOptions {\n image: MemoryImage;\n gamma: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface GaussianBlurOptions {\n image: MemoryImage;\n radius: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface GrayscaleOptions {\n image: MemoryImage;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface HdrToLdrOptions {\n image: MemoryImage;\n exposure?: number;\n}\n\nexport interface HexagonPixelateOptions {\n image: MemoryImage;\n centerX?: number;\n centerY?: number;\n size?: number;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface InvertOptions {\n image: MemoryImage;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface LuminanceThresholdOptions {\n image: MemoryImage;\n threshold?: number;\n outputColor?: boolean;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface MonochromeOptions {\n image: MemoryImage;\n color?: Color;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface NoiseOptions {\n image: MemoryImage;\n sigma: number;\n type?: NoiseType;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface NormalizeOptions {\n image: MemoryImage;\n min: number;\n max: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface PixelateOptions {\n image: MemoryImage;\n size: number;\n mode?: PixelateMode;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface QuantizeOptions {\n image: MemoryImage;\n numberOfColors?: number;\n method?: QuantizeMethod;\n dither?: DitherKernel;\n ditherSerpentine?: boolean;\n}\n\nexport interface ReinhardToneMapOptions {\n image: MemoryImage;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface RemapColorsOptions {\n image: MemoryImage;\n red?: Channel;\n green?: Channel;\n blue?: Channel;\n alpha?: Channel;\n}\n\nexport interface ScaleRgbaOptions {\n image: MemoryImage;\n scale: Color;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface SeparableConvolutionOptions {\n image: MemoryImage;\n kernel: SeparableKernel;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface SepiaOptions {\n image: MemoryImage;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface SketchOptions {\n image: MemoryImage;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface SmoothOptions {\n image: MemoryImage;\n weight: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface SobelOptions {\n image: MemoryImage;\n amount?: number;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface StretchDistortionOptions {\n image: MemoryImage;\n centerX?: number;\n centerY?: number;\n interpolation?: Interpolation;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport interface VignetteOptions {\n image: MemoryImage;\n start?: number;\n end?: number;\n amount?: number;\n color?: Color;\n maskChannel?: Channel;\n mask?: MemoryImage;\n}\n\nexport abstract class Filter {\n private static _contrastCache?: ContrastCache;\n private static readonly _gaussianKernelCache: Map =\n new Map();\n\n /**\n * Adjust the color of the **image** using various color transformations.\n *\n * **blacks** defines the black level of the image, as a color.\n *\n * **whites** defines the white level of the image, as a color.\n *\n * **mids** defines the mid level of hte image, as a color.\n *\n * **contrast** increases (> 1) / decreases (< 1) the contrast of the image by\n * pushing colors away/toward neutral gray, where at 0 the image is entirely\n * neutral gray (0 contrast), 1, the image is not adjusted and > 1 the\n * image increases contrast.\n *\n * **saturation** increases (> 1) / decreases (< 1) the saturation of the image\n * by pushing colors away/toward their grayscale value, where 0 is grayscale\n * and 1 is the original image, and > 1 the image becomes more saturated.\n *\n * **brightness** is a constant scalar of the image colors. At 0 the image\n * is black, 1 unmodified, and > 1 the image becomes brighter.\n *\n * **gamma** is an exponential scalar of the image colors. At < 1 the image\n * becomes brighter, and > 1 the image becomes darker. A **gamma** of 1/2.2\n * will convert the image colors to linear color space.\n *\n * **exposure** is an exponential scalar of the image as rgb* pow(2, exposure).\n * At 0, the image is unmodified; as the exposure increases, the image\n * brightens.\n *\n * **hue** shifts the hue component of the image colors in degrees. A **hue** of\n * 0 will have no affect, and a **hue** of 45 will shift the hue of all colors\n * by 45 degrees.\n *\n * **amount** controls how much affect this filter has on the **image**, where\n * 0 has no effect and 1 has full effect.\n *\n */\n public static adjustColor(opt: AdjustColorOptions): MemoryImage {\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n const contrast =\n opt.contrast !== undefined\n ? MathUtils.clamp(opt.contrast, 0, 1)\n : undefined;\n const saturation =\n opt.saturation !== undefined\n ? MathUtils.clamp(opt.saturation, 0, 1)\n : undefined;\n const brightness =\n opt.brightness !== undefined\n ? MathUtils.clamp(opt.brightness, 0, 1)\n : undefined;\n const gamma =\n opt.gamma !== undefined ? MathUtils.clamp(opt.gamma, 0, 1000) : undefined;\n let exposure =\n opt.exposure !== undefined\n ? MathUtils.clamp(opt.exposure, 0, 1000)\n : undefined;\n const amount = MathUtils.clamp(opt.amount ?? 1, 0, 1000);\n let hue = opt.hue;\n\n if (amount === 0) {\n return opt.image;\n }\n\n const degToRad = 0.0174532925;\n const avgLumR = 0.5;\n const avgLumG = 0.5;\n const avgLumB = 0.5;\n const lumCoeffR = 0.2125;\n const lumCoeffG = 0.7154;\n const lumCoeffB = 0.0721;\n\n const useBlacksWhitesMids =\n opt.blacks !== undefined ||\n opt.whites !== undefined ||\n opt.mids !== undefined;\n let br = 0;\n let bg = 0;\n let bb = 0;\n let wr = 0;\n let wg = 0;\n let wb = 0;\n let mr = 0;\n let mg = 0;\n let mb = 0;\n if (useBlacksWhitesMids) {\n br = opt.blacks?.rNormalized ?? 0;\n bg = opt.blacks?.gNormalized ?? 0;\n bb = opt.blacks?.bNormalized ?? 0;\n\n wr = opt.whites?.rNormalized ?? 0;\n wg = opt.whites?.gNormalized ?? 0;\n wb = opt.whites?.bNormalized ?? 0;\n\n mr = opt.mids?.rNormalized ?? 0;\n mg = opt.mids?.gNormalized ?? 0;\n mb = opt.mids?.bNormalized ?? 0;\n\n mr = 1 / (1 + 2 * (mr - 0.5));\n mg = 1 / (1 + 2 * (mg - 0.5));\n mb = 1 / (1 + 2 * (mb - 0.5));\n }\n\n const invSaturation =\n saturation !== undefined ? 1 - MathUtils.clamp(saturation, 0, 1) : 0;\n const invContrast =\n contrast !== undefined ? 1 - MathUtils.clamp(contrast, 0, 1) : 0;\n\n if (exposure !== undefined) {\n exposure = Math.pow(2, exposure);\n }\n\n let hueR = 0;\n let hueG = 0;\n let hueB = 0;\n if (hue !== undefined) {\n hue *= degToRad;\n const s = Math.sin(hue);\n const c = Math.cos(hue);\n\n hueR = (2 * c) / 3.0;\n hueG = (-Math.sqrt(3.0) * s - c) / 3.0;\n hueB = (Math.sqrt(3.0) * s - c + 1.0) / 3.0;\n }\n\n for (const frame of opt.image.frames) {\n for (const p of frame) {\n const or = p.rNormalized;\n const og = p.gNormalized;\n const ob = p.bNormalized;\n\n let r = or;\n let g = og;\n let b = ob;\n\n if (useBlacksWhitesMids) {\n r = Math.pow((r + br) * wr, mr);\n g = Math.pow((g + bg) * wg, mg);\n b = Math.pow((b + bb) * wb, mb);\n }\n\n if (brightness !== undefined && brightness !== 1.0) {\n const tb = MathUtils.clamp(brightness, 0, 1000);\n r *= tb;\n g *= tb;\n b *= tb;\n }\n\n if (saturation !== undefined) {\n const lum = r * lumCoeffR + g * lumCoeffG + b * lumCoeffB;\n\n r = lum * invSaturation + r * saturation;\n g = lum * invSaturation + g * saturation;\n b = lum * invSaturation + b * saturation;\n }\n\n if (contrast !== undefined) {\n r = avgLumR * invContrast + r * contrast;\n g = avgLumG * invContrast + g * contrast;\n b = avgLumB * invContrast + b * contrast;\n }\n\n if (gamma !== undefined) {\n r = Math.pow(r, gamma);\n g = Math.pow(g, gamma);\n b = Math.pow(b, gamma);\n }\n\n if (exposure !== undefined) {\n r *= exposure;\n g *= exposure;\n b *= exposure;\n }\n\n if (hue !== undefined && hue !== 0.0) {\n const hr = r * hueR + g * hueG + b * hueB;\n const hg = r * hueB + g * hueR + b * hueG;\n const hb = r * hueG + g * hueB + b * hueR;\n\n r = hr;\n g = hg;\n b = hb;\n }\n\n const msk =\n opt.mask?.getPixel(p.x, p.y).getChannelNormalized(maskChannel) ?? 1;\n const blend = msk * amount;\n\n r = MathUtils.mix(or, r, blend);\n g = MathUtils.mix(og, g, blend);\n b = MathUtils.mix(ob, b, blend);\n\n p.rNormalized = r;\n p.gNormalized = g;\n p.bNormalized = b;\n }\n }\n\n return opt.image;\n }\n\n /**\n * Apply the billboard filter to the image.\n */\n public static billboard(opt: BillboardOptions): MemoryImage {\n const grid = opt.grid ?? 10;\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n // Math.pow(0.45, 2);\n const rs = 0.2025;\n\n for (const frame of opt.image.frames) {\n const w = frame.width;\n const h = frame.height;\n const aspect = w / h;\n const stepX = 0.0015625;\n const stepY = 0.0015625 * aspect;\n const orig = frame.clone({\n skipAnimation: true,\n });\n for (const p of frame) {\n const uvX = p.x / (w - 1);\n const uvY = p.y / (h - 1);\n\n const offX = Math.floor(uvX / (grid * stepX));\n const offY = Math.floor(uvY / (grid * stepY));\n\n const x2 = Math.floor(offX * grid * stepX * (w - 1));\n const y2 = Math.floor(offY * grid * stepY * (h - 1));\n\n if (x2 >= w || y2 >= h) {\n continue;\n }\n\n const op = orig.getPixel(x2, y2);\n\n const prcX = MathUtils.fract(uvX / (grid * stepX));\n const prcY = MathUtils.fract(uvY / (grid * stepY));\n const pwX = Math.pow(Math.abs(prcX - 0.5), 2);\n const pwY = Math.pow(Math.abs(prcY - 0.5), 2);\n\n let r = op.r / p.maxChannelValue;\n let g = op.g / p.maxChannelValue;\n let b = op.b / p.maxChannelValue;\n\n const gr = MathUtils.smoothStep(rs - 0.1, rs + 0.1, pwX + pwY);\n const y = (r + g + b) / 3.0;\n\n const ls = 0.3;\n const lb = Math.ceil(y / ls);\n const lf = ls * lb + 0.3;\n\n r = MathUtils.mix(lf * r, 0.1, gr);\n g = MathUtils.mix(lf * g, 0.1, gr);\n b = MathUtils.mix(lf * b, 0.1, gr);\n\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n\n p.r = MathUtils.mix(p.r, r * p.maxChannelValue, mx);\n p.g = MathUtils.mix(p.g, g * p.maxChannelValue, mx);\n p.b = MathUtils.mix(p.b, b * p.maxChannelValue, mx);\n }\n }\n return opt.image;\n }\n\n public static bleachBypass(opt: BleachBypassOptions): MemoryImage {\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n const luminanceR = 0.2125;\n const luminanceG = 0.7154;\n const luminanceB = 0.0721;\n for (const frame of opt.image.frames) {\n for (const p of frame) {\n const r = p.rNormalized;\n const g = p.gNormalized;\n const b = p.bNormalized;\n const lr = r * luminanceR;\n const lg = g * luminanceG;\n const lb = b * luminanceB;\n const l = lr + lg + lb;\n\n const mixAmount = MathUtils.clamp((l - 0.45) * 10, 0, 1);\n const branch1R = 2 * r * l;\n const branch1G = 2 * g * l;\n const branch1B = 2 * b * l;\n const branch2R = 1 - 2 * (1 - r) * (1 - l);\n const branch2G = 1 - 2 * (1 - g) * (1 - l);\n const branch2B = 1 - 2 * (1 - b) * (1 - l);\n\n const msk =\n opt.mask?.getPixel(p.x, p.y).getChannelNormalized(maskChannel) ?? 1;\n const mx = msk * amount;\n\n if (mx !== 1) {\n const nr =\n MathUtils.mix(branch1R, branch2R, mixAmount) * p.maxChannelValue;\n const ng =\n MathUtils.mix(branch1G, branch2G, mixAmount) * p.maxChannelValue;\n const nb =\n MathUtils.mix(branch1B, branch2B, mixAmount) * p.maxChannelValue;\n p.r = MathUtils.mix(p.r, nr, amount);\n p.g = MathUtils.mix(p.g, ng, amount);\n p.b = MathUtils.mix(p.b, nb, amount);\n } else {\n p.rNormalized = MathUtils.mix(branch1R, branch2R, mixAmount);\n p.gNormalized = MathUtils.mix(branch1G, branch2G, mixAmount);\n p.bNormalized = MathUtils.mix(branch1B, branch2B, mixAmount);\n }\n }\n }\n return opt.image;\n }\n\n public static bulgeDistortion(opt: BulgeDistortionOptions): MemoryImage {\n const scale = opt.scale ?? 0.5;\n const interpolation = opt.interpolation ?? Interpolation.nearest;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n for (const frame of opt.image.frames) {\n const orig = frame.clone({\n skipAnimation: true,\n });\n const w = frame.width;\n const h = frame.height;\n const cx = opt.centerX ?? Math.trunc(w / 2);\n const cy = opt.centerY ?? Math.trunc(h / 2);\n const rad = opt.radius ?? Math.trunc(Math.min(w, h) / 2);\n const radSqr = rad * rad;\n for (const p of frame) {\n let x = p.x;\n let y = p.y;\n const deltaX = cx - x;\n const deltaY = cy - y;\n const dist = deltaX * deltaX + deltaY * deltaY;\n x -= cx;\n y -= cy;\n if (dist < radSqr) {\n const percent = 1 - ((radSqr - dist) / radSqr) * scale;\n const percentSqr = percent * percent;\n x *= percentSqr;\n y *= percentSqr;\n }\n x += cx;\n y += cy;\n\n const p2 = orig.getPixelInterpolate(x, y, interpolation);\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n\n if (msk === undefined) {\n p.set(p2);\n } else {\n p.r = MathUtils.mix(p.r, p2.r, msk);\n p.g = MathUtils.mix(p.g, p2.g, msk);\n p.b = MathUtils.mix(p.b, p2.b, msk);\n p.a = MathUtils.mix(p.a, p2.a, msk);\n }\n }\n }\n return opt.image;\n }\n\n /**\n * Generate a normal map from a heightfield bump image.\n *\n * The red channel of the **image** is used as an input, 0 represents a low\n * height and 1 a high value. The optional **strength** parameter allows to set\n * the strength of the normal image.\n */\n public static bumpToNormal(opt: BumpToNormalOptions): MemoryImage {\n const strength = opt.strength ?? 2;\n\n const dest = MemoryImage.from(opt.image);\n\n const mx = opt.image.maxChannelValue;\n for (const frame of opt.image.frames) {\n for (let y = 0; y < frame.height; ++y) {\n for (let x = 0; x < frame.width; ++x) {\n const height = frame.getPixel(x, y).r / mx;\n let du =\n (height -\n frame.getPixel(x < frame.width - 1 ? x + 1 : x, y).r / mx) *\n strength;\n let dv =\n (height -\n frame.getPixel(x, y < frame.height - 1 ? y + 1 : y).r / mx) *\n strength;\n const z = Math.abs(du) + Math.abs(dv);\n\n if (z > 1) {\n du /= z;\n dv /= z;\n }\n\n const dw = Math.sqrt(1 - du * du - dv * dv);\n const nX = du * 0.5 + 0.5;\n const nY = dv * 0.5 + 0.5;\n const nZ = dw;\n\n dest.frames[frame.frameIndex].setPixelRgb(\n x,\n y,\n nX * mx,\n nY * mx,\n nZ * mx\n );\n }\n }\n }\n\n return dest;\n }\n\n /**\n * Apply chromatic aberration filter to the image.\n */\n public static chromaticAberration(\n opt: ChromaticAberrationOptions\n ): MemoryImage {\n const shift = opt.shift ?? 5;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n for (const frame of opt.image.frames) {\n const orig = frame.clone({\n skipAnimation: true,\n });\n const w = frame.width - 1;\n for (const p of frame) {\n const shiftLeft = MathUtils.clamp(p.x - shift, 0, w);\n const shiftRight = MathUtils.clamp(p.x + shift, 0, w);\n const lc = orig.getPixel(shiftLeft, p.y);\n const rc = orig.getPixel(shiftRight, p.y);\n\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n\n if (msk === undefined) {\n p.r = rc.r;\n p.b = lc.b;\n } else {\n p.r = MathUtils.mix(p.r, rc.r, msk);\n p.b = MathUtils.mix(p.b, lc.b, msk);\n }\n }\n }\n return opt.image;\n }\n\n /**\n * Apply color halftone filter to the image.\n */\n public static colorHalftone(opt: ColorHalftone): MemoryImage {\n const amount = opt.amount ?? 1;\n let angle = opt.angle ?? 1;\n const size = opt.size ?? 5;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n angle *= 0.0174533;\n\n const pattern = (\n x: number,\n y: number,\n cx: number,\n cy: number,\n angle: number\n ): number => {\n const scale = 3.14159 / size;\n const s = Math.sin(angle);\n const c = Math.cos(angle);\n const tx = x - cx;\n const ty = y - cy;\n const px = (c * tx - s * ty) * scale;\n const py = (s * tx + c * ty) * scale;\n return Math.sin(px) * Math.sin(py) * 4.0;\n };\n\n for (const frame of opt.image.frames) {\n const w = frame.width;\n const h = frame.height;\n const cx = opt.centerX ?? Math.trunc(w / 2);\n const cy = opt.centerY ?? Math.trunc(h / 2);\n for (const p of frame) {\n const x = p.x;\n const y = p.y;\n let cmyC = 1 - p.rNormalized;\n let cmyM = 1 - p.gNormalized;\n let cmyY = 1 - p.bNormalized;\n let cmyK = Math.min(cmyC, Math.min(cmyM, cmyY));\n cmyC = (cmyC - cmyK) / (1 - cmyK);\n cmyM = (cmyM - cmyK) / (1 - cmyK);\n cmyY = (cmyY - cmyK) / (1 - cmyK);\n cmyC = MathUtils.clamp(\n cmyC * 10 - 3 + pattern(x, y, cx, cy, angle + 0.26179),\n 0,\n 1\n );\n cmyM = MathUtils.clamp(\n cmyM * 10 - 3 + pattern(x, y, cx, cy, angle + 1.30899),\n 0,\n 1\n );\n cmyY = MathUtils.clamp(\n cmyY * 10 - 3 + pattern(x, y, cx, cy, angle),\n 0,\n 1\n );\n cmyK = MathUtils.clamp(\n cmyK * 10 - 5 + pattern(x, y, cx, cy, angle + 0.78539),\n 0,\n 1\n );\n\n const r = (1 - cmyC - cmyK) * p.maxChannelValue;\n const g = (1 - cmyM - cmyK) * p.maxChannelValue;\n const b = (1 - cmyY - cmyK) * p.maxChannelValue;\n\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n\n if (mx !== 1) {\n p.r = MathUtils.mix(p.r, r, mx);\n p.g = MathUtils.mix(p.g, g, mx);\n p.b = MathUtils.mix(p.b, b, mx);\n } else {\n p.r = r;\n p.g = g;\n p.b = b;\n }\n }\n }\n return opt.image;\n }\n\n /**\n * Add the **red**, **green**, **blue** and **alpha** values to the **image** image\n * colors, a per-channel brightness.\n */\n public static colorOffset(opt: ColorOffsetOptions): MemoryImage {\n const red = opt.red ?? 0;\n const green = opt.green ?? 0;\n const blue = opt.blue ?? 0;\n const alpha = opt.alpha ?? 0;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n for (const frame of opt.image.frames) {\n for (const p of frame) {\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n if (msk === undefined) {\n p.r += red;\n p.g += green;\n p.b += blue;\n p.a += alpha;\n } else {\n p.r = MathUtils.mix(p.r, p.r + red, msk);\n p.g = MathUtils.mix(p.g, p.g + green, msk);\n p.b = MathUtils.mix(p.b, p.b + blue, msk);\n p.a = MathUtils.mix(p.a, p.a + alpha, msk);\n }\n }\n }\n return opt.image;\n }\n\n /**\n * Set the contrast level for the **image**.\n *\n * **contrast** values below 100 will decrees the contrast of the image,\n * and values above 100 will increase the contrast. A contrast of of 100\n * will have no affect.\n */\n public static contrast(opt: ContrastOptions): MemoryImage {\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (opt.contrast === 100) {\n return opt.image;\n }\n\n if (\n Filter._contrastCache === undefined ||\n opt.contrast !== Filter._contrastCache.lastContrast\n ) {\n Filter._contrastCache = {\n lastContrast: opt.contrast,\n contrast: new Uint8Array(256),\n };\n\n const c = (opt.contrast * opt.contrast) / 10000;\n for (let i = 0; i < 256; ++i) {\n Filter._contrastCache.contrast[i] = MathUtils.clampInt255(\n ((i / 255 - 0.5) * c + 0.5) * 255\n );\n }\n }\n\n for (const frame of opt.image.frames) {\n for (const p of frame) {\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const r = Math.trunc(p.r);\n const g = Math.trunc(p.g);\n const b = Math.trunc(p.b);\n if (msk === undefined) {\n p.r = Filter._contrastCache.contrast[r];\n p.g = Filter._contrastCache.contrast[g];\n p.b = Filter._contrastCache.contrast[b];\n } else {\n p.r = MathUtils.mix(p.r, Filter._contrastCache.contrast[r], msk);\n p.g = MathUtils.mix(p.g, Filter._contrastCache.contrast[g], msk);\n p.b = MathUtils.mix(p.b, Filter._contrastCache.contrast[b], msk);\n }\n }\n }\n\n return opt.image;\n }\n\n /**\n * Apply a 3x3 convolution filter to the **image**. **filter** should be a\n * list of 9 numbers.\n *\n * The rgb channels will be divided by **div** and add **offset**, allowing\n * filters to normalize and offset the filtered pixel value.\n */\n public static convolution(opt: ConvolutionOptions): MemoryImage {\n const div = opt.div ?? 1;\n const offset = opt.offset ?? 0;\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n const tmp = MemoryImage.from(opt.image);\n for (const frame of opt.image.frames) {\n const tmpFrame = tmp.frames[frame.frameIndex];\n for (const c of tmpFrame) {\n let r = 0;\n let g = 0;\n let b = 0;\n for (let j = 0, fi = 0; j < 3; ++j) {\n const yv = Math.min(Math.max(c.y - 1 + j, 0), opt.image.height - 1);\n for (let i = 0; i < 3; ++i, ++fi) {\n const xv = Math.min(Math.max(c.x - 1 + i, 0), opt.image.width - 1);\n const c2 = tmpFrame.getPixel(xv, yv);\n r += c2.r * opt.filter[fi];\n g += c2.g * opt.filter[fi];\n b += c2.b * opt.filter[fi];\n }\n }\n\n r = MathUtils.clampInt255(r / div + offset);\n g = MathUtils.clampInt255(g / div + offset);\n b = MathUtils.clampInt255(b / div + offset);\n\n const p = frame.getPixel(c.x, c.y);\n\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n\n p.r = MathUtils.mix(p.r, r, mx);\n p.g = MathUtils.mix(p.g, g, mx);\n p.b = MathUtils.mix(p.b, b, mx);\n }\n }\n\n return opt.image;\n }\n\n /**\n * Copy channels from the **from** image to the **image**. If **scaled** is\n * true, then the **from** image will be scaled to the **image** resolution.\n */\n public static copyImageChannels(opt: CopyImageChannelsOptions): MemoryImage {\n const scaled = opt.scaled ?? false;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n const dx = opt.from.width / opt.image.width;\n const dy = opt.from.height / opt.image.height;\n const fromPixel = opt.from.getPixel(0, 0);\n for (const frame of opt.image.frames) {\n for (const p of frame) {\n if (scaled) {\n fromPixel.setPosition(Math.floor(p.x * dx), Math.floor(p.y * dy));\n } else {\n fromPixel.setPosition(p.x, p.y);\n }\n\n const r =\n opt.red !== undefined\n ? fromPixel.getChannelNormalized(opt.red)\n : p.rNormalized;\n const g =\n opt.green !== undefined\n ? fromPixel.getChannelNormalized(opt.green)\n : p.gNormalized;\n const b =\n opt.blue !== undefined\n ? fromPixel.getChannelNormalized(opt.blue)\n : p.bNormalized;\n const a =\n opt.alpha !== undefined\n ? fromPixel.getChannelNormalized(opt.alpha)\n : p.aNormalized;\n\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n if (msk === undefined) {\n p.rNormalized = r;\n p.gNormalized = g;\n p.bNormalized = b;\n p.aNormalized = a;\n } else {\n p.rNormalized = MathUtils.mix(p.r, r, msk);\n p.gNormalized = MathUtils.mix(p.g, g, msk);\n p.bNormalized = MathUtils.mix(p.b, b, msk);\n p.aNormalized = MathUtils.mix(p.a, a, msk);\n }\n }\n }\n return opt.image;\n }\n\n /**\n * Dither an image to reduce banding patterns when reducing the number of\n * colors.\n */\n public static ditherImage(opt: DitherImageOptions): MemoryImage {\n const quantizer = opt.quantizer ?? new NeuralQuantizer(opt.image);\n const kernel = opt.kernel ?? DitherKernel.floydSteinberg;\n const serpentine = opt.serpentine ?? false;\n\n if (kernel === DitherKernel.none) {\n return quantizer.getIndexImage(opt.image);\n }\n\n const ds = DitherKernels[kernel];\n const height = opt.image.height;\n const width = opt.image.width;\n\n let direction = serpentine ? -1 : 1;\n\n const palette = quantizer.palette;\n const indexedImage = new MemoryImage({\n width: width,\n height: height,\n numChannels: 1,\n palette: palette,\n });\n\n const pIter = opt.image[Symbol.iterator]();\n let itRes = pIter.next();\n\n let index = 0;\n for (let y = 0; y < height; y++) {\n if (serpentine) direction *= -1;\n\n const x0 = direction === 1 ? 0 : width - 1;\n const x1 = direction === 1 ? width : 0;\n for (\n let x = x0;\n x !== x1;\n x += direction, ++index, itRes = pIter.next()\n ) {\n // Get original color\n const pc = itRes.value;\n const r1 = Math.trunc(pc.getChannel(0));\n const g1 = Math.trunc(pc.getChannel(1));\n const b1 = Math.trunc(pc.getChannel(2));\n\n // Get converted color\n let idx = quantizer.getColorIndexRgb(r1, g1, b1);\n indexedImage.setPixelRgb(x, y, idx, 0, 0);\n\n const r2 = palette.get(idx, 0);\n const g2 = palette.get(idx, 1);\n const b2 = palette.get(idx, 2);\n\n const er = r1 - r2;\n const eg = g1 - g2;\n const eb = b1 - b2;\n\n if (er === 0 && eg === 0 && eb === 0) {\n continue;\n }\n\n const i0 = direction === 1 ? 0 : ds.length - 1;\n const i1 = direction === 1 ? ds.length : 0;\n for (let i = i0; i !== i1; i += direction) {\n const x1 = Math.trunc(ds[i][1]);\n const y1 = Math.trunc(ds[i][2]);\n if (x1 + x >= 0 && x1 + x < width && y1 + y >= 0 && y1 + y < height) {\n const d = ds[i][0];\n idx = index + x1 + y1 * width;\n idx *= 4;\n const p2 = opt.image.getPixel(x1, y1);\n p2.r = Math.max(0, Math.min(255, Math.trunc(p2.r + er * d)));\n p2.g = Math.max(0, Math.min(255, Math.trunc(p2.g + er * d)));\n p2.b = Math.max(0, Math.min(255, Math.trunc(p2.b + er * d)));\n }\n }\n }\n }\n\n return indexedImage;\n }\n\n /**\n * Apply the dot screen filter to the image.\n */\n public static dotScreen(opt: DotScreenOptions): MemoryImage {\n let angle = opt.angle ?? 180;\n const size = opt.size ?? 5.75;\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n angle *= 0.0174533;\n const s = Math.sin(angle);\n const c = Math.cos(angle);\n for (const frame of opt.image.frames) {\n const w = frame.width - 1;\n const h = frame.height - 1;\n const cntX = (opt.centerX ?? Math.trunc(w / 2)) / w;\n const cntY = (opt.centerY ?? Math.trunc(h / 2)) / h;\n\n const pattern = (\n cntX: number,\n cntY: number,\n tx: number,\n ty: number\n ): number => {\n const texX = (tx - cntX) * w;\n const texY = (ty - cntY) * h;\n const pointX = (c * texX - s * texY) * size;\n const pointY = (s * texX + c * texY) * size;\n return Math.sin(pointX) * Math.sin(pointY) * 4;\n };\n\n for (const p of frame) {\n const average = p.luminanceNormalized;\n const pat = pattern(cntX, cntY, p.x / w, p.y / h);\n const c = (average * 10 - 5 + pat) * p.maxChannelValue;\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n p.r = MathUtils.mix(p.r, c, mx);\n p.g = MathUtils.mix(p.g, c, mx);\n p.b = MathUtils.mix(p.b, c, mx);\n }\n }\n\n return opt.image;\n }\n\n /**\n * Create a drop-shadow effect for the image.\n */\n public static dropShadow(opt: DropShadowOptions): MemoryImage {\n const blur = opt.blur >= 0 ? opt.blur : 0;\n const shadowColor = opt.shadowColor ?? new ColorRgba8(0, 0, 0, 128);\n\n const shadowWidth = opt.image.width + blur * 2;\n const shadowHeight = opt.image.height + blur * 2;\n let shadowOffsetX = -blur;\n let shadowOffsetY = -blur;\n\n let newImageWidth = shadowWidth;\n let newImageHeight = shadowHeight;\n let imageOffsetX = 0;\n let imageOffsetY = 0;\n\n if (shadowOffsetX + opt.hShadow < 0) {\n imageOffsetX = -(shadowOffsetX + opt.hShadow);\n shadowOffsetX = -shadowOffsetX;\n newImageWidth = imageOffsetX;\n }\n\n if (shadowOffsetY + opt.vShadow < 0) {\n imageOffsetY = -(shadowOffsetY + opt.vShadow);\n shadowOffsetY = -shadowOffsetY;\n newImageHeight += imageOffsetY;\n }\n\n if (shadowWidth + shadowOffsetX + opt.hShadow > newImageWidth) {\n newImageWidth = shadowWidth + shadowOffsetX + opt.hShadow;\n }\n\n if (shadowHeight + shadowOffsetY + opt.vShadow > newImageHeight) {\n newImageHeight = shadowHeight + shadowOffsetY + opt.vShadow;\n }\n\n const dst = new MemoryImage({\n width: newImageWidth,\n height: newImageHeight,\n numChannels: 4,\n });\n\n dst.clear(new ColorRgba8(255, 255, 255, 0));\n\n Draw.compositeImage({\n dst: dst,\n src: opt.image,\n dstX: shadowOffsetX,\n dstY: shadowOffsetY,\n });\n\n Filter.remapColors({\n image: dst,\n red: Channel.alpha,\n green: Channel.alpha,\n blue: Channel.alpha,\n });\n\n Filter.scaleRgba({\n image: dst,\n scale: shadowColor,\n });\n\n Filter.gaussianBlur({\n image: dst,\n radius: blur,\n });\n\n Draw.compositeImage({\n dst: dst,\n src: opt.image,\n dstX: imageOffsetX,\n dstY: imageOffsetY,\n });\n\n return dst;\n }\n\n /**\n * Apply the edge glow filter to the image.\n */\n public static edgeGlow(opt: EdgeGlowOptions): MemoryImage {\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (amount === 0) {\n return opt.image;\n }\n\n for (const frame of opt.image.frames) {\n const orig = MemoryImage.from(frame, true);\n const width = frame.width;\n const height = frame.height;\n for (const p of frame) {\n const ny = MathUtils.clamp(p.y - 1, 0, height - 1);\n const py = MathUtils.clamp(p.y + 1, 0, height - 1);\n const nx = MathUtils.clamp(p.x - 1, 0, width - 1);\n const px = MathUtils.clamp(p.x + 1, 0, width - 1);\n\n const t1 = orig.getPixel(nx, ny);\n const t2 = orig.getPixel(p.x, ny);\n const t3 = orig.getPixel(px, ny);\n const t4 = orig.getPixel(nx, p.y);\n const t5 = p;\n const t6 = orig.getPixel(px, p.y);\n const t7 = orig.getPixel(nx, py);\n const t8 = orig.getPixel(p.x, py);\n const t9 = orig.getPixel(px, py);\n\n const xxR =\n t1.rNormalized +\n 2 * t2.rNormalized +\n t3.rNormalized -\n t7.rNormalized -\n 2 * t8.rNormalized -\n t9.rNormalized;\n const xxG =\n t1.gNormalized +\n 2 * t2.gNormalized +\n t3.gNormalized -\n t7.gNormalized -\n 2 * t8.gNormalized -\n t9.gNormalized;\n const xxB =\n t1.bNormalized +\n 2 * t2.bNormalized +\n t3.bNormalized -\n t7.bNormalized -\n 2 * t8.bNormalized -\n t9.bNormalized;\n\n const yyR =\n t1.rNormalized -\n t3.rNormalized +\n 2 * t4.rNormalized -\n 2 * t6.rNormalized +\n t7.rNormalized -\n t9.rNormalized;\n const yyG =\n t1.gNormalized -\n t3.gNormalized +\n 2 * t4.gNormalized -\n 2 * t6.gNormalized +\n t7.gNormalized -\n t9.gNormalized;\n const yyB =\n t1.bNormalized -\n t3.bNormalized +\n 2 * t4.bNormalized -\n 2 * t6.bNormalized +\n t7.bNormalized -\n t9.bNormalized;\n\n const rrR = Math.sqrt(xxR * xxR + yyR * yyR);\n const rrG = Math.sqrt(xxG * xxG + yyG * yyG);\n const rrB = Math.sqrt(xxB * xxB + yyB * yyB);\n\n const r = rrR * 2 * t5.rNormalized * p.maxChannelValue;\n const g = rrG * 2 * t5.gNormalized * p.maxChannelValue;\n const b = rrB * 2 * t5.bNormalized * p.maxChannelValue;\n\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n\n p.r = MathUtils.mix(p.r, r, mx);\n p.g = MathUtils.mix(p.g, g, mx);\n p.b = MathUtils.mix(p.b, b, mx);\n }\n }\n\n return opt.image;\n }\n\n /**\n * Apply an emboss convolution filter.\n */\n public static emboss(opt: EmbossOptions): MemoryImage {\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n const filter = [1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.5];\n return Filter.convolution({\n image: opt.image,\n filter: filter,\n div: 1,\n offset: 127,\n amount: amount,\n mask: opt.mask,\n maskChannel: maskChannel,\n });\n }\n\n /**\n * Apply gamma scaling\n */\n public static gamma(opt: GammaOptions): MemoryImage {\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n for (const frame of opt.image.frames) {\n for (const p of frame) {\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n if (msk === undefined) {\n p.rNormalized = Math.pow(p.rNormalized, opt.gamma);\n p.gNormalized = Math.pow(p.gNormalized, opt.gamma);\n p.bNormalized = Math.pow(p.bNormalized, opt.gamma);\n } else {\n p.rNormalized = MathUtils.mix(\n p.rNormalized,\n Math.pow(p.rNormalized, opt.gamma),\n msk\n );\n p.gNormalized = MathUtils.mix(\n p.gNormalized,\n Math.pow(p.gNormalized, opt.gamma),\n msk\n );\n p.bNormalized = MathUtils.mix(\n p.bNormalized,\n Math.pow(p.bNormalized, opt.gamma),\n msk\n );\n }\n }\n }\n return opt.image;\n }\n\n /**\n * Apply gaussian blur to the **image**. **radius** determines how many pixels\n * away from the current pixel should contribute to the blur, where 0 is no\n * blur and the larger the **radius**, the stronger the blur.\n */\n public static gaussianBlur(opt: GaussianBlurOptions): MemoryImage {\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (opt.radius <= 0) {\n return opt.image;\n }\n\n let kernel: SeparableKernel | undefined = undefined;\n\n if (Filter._gaussianKernelCache.has(opt.radius)) {\n kernel = Filter._gaussianKernelCache.get(opt.radius)!;\n } else {\n // Compute coefficients\n const sigma = (opt.radius * 2) / 3;\n const s = 2 * sigma * sigma;\n\n kernel = new SeparableKernel(opt.radius);\n\n let sum = 0;\n for (let x = -opt.radius; x <= opt.radius; ++x) {\n const c = Math.exp(-(x * x) / s);\n sum += c;\n kernel.setCoefficient(x + opt.radius, c);\n }\n // Normalize the coefficients\n kernel.scaleCoefficients(1 / sum);\n\n // Cache the kernel for this radius so we don't have to recompute it\n // next time.\n Filter._gaussianKernelCache.set(opt.radius, kernel);\n }\n\n return Filter.separableConvolution({\n image: opt.image,\n kernel: kernel,\n mask: opt.mask,\n maskChannel: maskChannel,\n });\n }\n\n /**\n * Convert the image to grayscale.\n */\n public static grayscale(opt: GrayscaleOptions): MemoryImage {\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n for (const frame of opt.image.frames) {\n if (frame.hasPalette) {\n const p = frame.palette!;\n const numColors = p.numColors;\n for (let i = 0; i < numColors; ++i) {\n const l = ColorUtils.getLuminanceRgb(\n p.getRed(i),\n p.getGreen(i),\n p.getBlue(i)\n );\n if (amount !== 1) {\n const r = MathUtils.mix(p.getRed(i), l, amount);\n const g = MathUtils.mix(p.getGreen(i), l, amount);\n const b = MathUtils.mix(p.getBlue(i), l, amount);\n p.setRed(i, r);\n p.setGreen(i, g);\n p.setBlue(i, b);\n } else {\n p.setRed(i, l);\n p.setGreen(i, l);\n p.setBlue(i, l);\n }\n }\n } else {\n for (const p of frame) {\n const l = ColorUtils.getLuminanceRgb(p.r, p.g, p.b);\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n if (mx !== 1) {\n p.r = MathUtils.mix(p.r, l, mx);\n p.g = MathUtils.mix(p.g, l, mx);\n p.b = MathUtils.mix(p.b, l, mx);\n } else {\n p.r = l;\n p.g = l;\n p.b = l;\n }\n }\n }\n }\n\n return opt.image;\n }\n\n /**\n * Convert a high dynamic range image to a low dynamic range image,\n * with optional exposure control.\n */\n public static hdrToLdr(opt: HdrToLdrOptions): MemoryImage {\n const knee = (x: number, f: number): number => {\n return Math.log(x * f + 1.0) / f;\n };\n\n const gamma = (h: number, m: number): number => {\n let x = Math.max(0, h * m);\n if (x > 1.0) {\n x = 1 + knee(x - 1, 0.184874);\n }\n return Math.pow(x, 0.4545) * 84.66;\n };\n\n const image = new MemoryImage({\n width: opt.image.width,\n height: opt.image.height,\n numChannels: opt.image.numChannels,\n });\n\n const m =\n opt.exposure !== undefined\n ? Math.pow(2, MathUtils.clamp(opt.exposure + 2.47393, -20, 20))\n : 1;\n\n const nc = opt.image.numChannels;\n\n for (let y = 0; y < opt.image.height; ++y) {\n for (let x = 0; x < opt.image.width; ++x) {\n const hp = opt.image.getPixel(x, y);\n\n let r = hp.rNormalized;\n let g = nc === 1 ? r : hp.gNormalized;\n let b = nc === 1 ? r : hp.bNormalized;\n\n if (!isFinite(r) || isNaN(r)) {\n r = 0;\n }\n if (!isFinite(g) || isNaN(g)) {\n g = 0;\n }\n if (!isFinite(b) || isNaN(b)) {\n b = 0;\n }\n\n let ri = 0;\n let gi = 0;\n let bi = 0;\n if (opt.exposure !== undefined) {\n ri = gamma(r, m);\n gi = gamma(g, m);\n bi = gamma(b, m);\n } else {\n ri = MathUtils.clamp(r, 0, 1) * 255;\n gi = MathUtils.clamp(g, 0, 1) * 255;\n bi = MathUtils.clamp(b, 0, 1) * 255;\n }\n\n // Normalize the color\n const mi = Math.max(ri, Math.max(gi, bi));\n if (mi > 255) {\n ri = 255 * (ri / mi);\n gi = 255 * (gi / mi);\n bi = 255 * (bi / mi);\n }\n\n if (opt.image.numChannels > 3) {\n let a = hp.a;\n if (!isFinite(a) || isNaN(a)) {\n a = 1;\n }\n image.setPixelRgba(\n x,\n y,\n MathUtils.clampInt255(ri),\n MathUtils.clampInt255(gi),\n MathUtils.clampInt255(bi),\n MathUtils.clampInt255(a * 255)\n );\n } else {\n image.setPixelRgb(\n x,\n y,\n MathUtils.clampInt255(ri),\n MathUtils.clampInt255(gi),\n MathUtils.clampInt255(bi)\n );\n }\n }\n }\n\n return image;\n }\n\n /**\n * Apply the hexagon pixelate filter to the image.\n */\n public static hexagonPixelate(opt: HexagonPixelateOptions): MemoryImage {\n const size = opt.size ?? 5;\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n for (const frame of opt.image.frames) {\n const w = frame.width - 1;\n const h = frame.height - 1;\n const cntX = (opt.centerX ?? Math.trunc(frame.width / 2)) / w;\n const cntY = (opt.centerY ?? Math.trunc(frame.height / 2)) / h;\n const orig = frame.clone({\n skipAnimation: true,\n });\n\n for (const p of frame) {\n let texX = (p.x - cntX) / size;\n let texY = (p.y - cntY) / size;\n texY /= 0.866025404;\n texX -= texY * 0.5;\n\n let ax = 0;\n let ay = 0;\n if (texX + texY - Math.floor(texX) - Math.floor(texY) < 1) {\n ax = Math.floor(texX);\n ay = Math.floor(texY);\n } else {\n ax = Math.ceil(texX);\n ay = Math.ceil(texY);\n }\n\n const bx = Math.ceil(texX);\n const by = Math.floor(texY);\n const cx = Math.floor(texX);\n const cy = Math.ceil(texY);\n\n const tex2X = texX;\n const tex2Y = texY;\n const tex2Z = 1 - texX - texY;\n const a2x = ax;\n const a2y = ay;\n const a2z = 1 - ax - ay;\n const b2x = bx;\n const b2y = by;\n const b2z = 1 - bx - by;\n const c2x = cx;\n const c2y = cy;\n const c2z = 1 - cx - cy;\n\n const aLen = MathUtils.length3(tex2X - a2x, tex2Y - a2y, tex2Z - a2z);\n const bLen = MathUtils.length3(tex2X - b2x, tex2Y - b2y, tex2Z - b2z);\n const cLen = MathUtils.length3(tex2X - c2x, tex2Y - c2y, tex2Z - c2z);\n\n let choiceX = 0;\n let choiceY = 0;\n if (aLen < bLen) {\n if (aLen < cLen) {\n choiceX = ax;\n choiceY = ay;\n } else {\n choiceX = cx;\n choiceY = cy;\n }\n } else {\n if (bLen < cLen) {\n choiceX = bx;\n choiceY = by;\n } else {\n choiceX = cx;\n choiceY = cy;\n }\n }\n\n choiceX += choiceY * 0.5;\n choiceY *= 0.866025404;\n choiceX *= size / w;\n choiceY *= size / h;\n\n const nx = choiceX + cntX / w;\n const ny = choiceY + cntY / h;\n const x = MathUtils.clamp(nx * w, 0, w);\n const y = MathUtils.clamp(ny * h, 0, h);\n const newColor = orig.getPixel(Math.floor(x), Math.floor(y));\n\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n\n p.r = MathUtils.mix(p.r, newColor.r, mx);\n p.g = MathUtils.mix(p.g, newColor.g, mx);\n p.b = MathUtils.mix(p.b, newColor.b, mx);\n }\n }\n return opt.image;\n }\n\n /**\n * Invert the colors of the **image**.\n */\n public static invert(opt: InvertOptions): MemoryImage {\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n const max = opt.image.maxChannelValue;\n for (const frame of opt.image.frames) {\n if (opt.image.hasPalette) {\n const p = frame.palette!;\n const numColors = p.numColors;\n for (let i = 0; i < numColors; ++i) {\n const r = max - p.getRed(i);\n const g = max - p.getGreen(i);\n const b = max - p.getBlue(i);\n p.setRgb(i, r, g, b);\n }\n } else {\n if (max !== 0) {\n for (const p of frame) {\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n\n if (msk === undefined) {\n p.r = max - p.r;\n p.g = max - p.g;\n p.b = max - p.b;\n } else {\n p.r = MathUtils.mix(p.r, max - p.r, msk);\n p.g = MathUtils.mix(p.g, max - p.g, msk);\n p.b = MathUtils.mix(p.b, max - p.b, msk);\n }\n }\n }\n }\n }\n return opt.image;\n }\n\n public static luminanceThreshold(\n opt: LuminanceThresholdOptions\n ): MemoryImage {\n const threshold = opt.threshold ?? 0.5;\n const outputColor = opt.outputColor ?? false;\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n for (const frame of opt.image.frames) {\n for (const p of frame) {\n const y =\n 0.3 * p.rNormalized + 0.59 * p.gNormalized + 0.11 * p.bNormalized;\n if (outputColor) {\n const l = Math.max(0, y - threshold);\n const sl = Math.sign(l);\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n p.r = MathUtils.mix(p.r, p.r * sl, mx);\n p.g = MathUtils.mix(p.g, p.g * sl, mx);\n p.b *= MathUtils.mix(p.b, p.b * sl, mx);\n } else {\n const y2 = y < threshold ? 0 : p.maxChannelValue;\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n p.r = MathUtils.mix(p.r, y2, mx);\n p.g = MathUtils.mix(p.g, y2, mx);\n p.b = MathUtils.mix(p.b, y2, mx);\n }\n }\n }\n return opt.image;\n }\n\n /**\n * Apply the monochrome filter to the **image**.\n *\n * **amount** controls the strength of the effect, in the range [0, 1].\n */\n public static monochrome(opt: MonochromeOptions): MemoryImage {\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (amount === 0) {\n return opt.image;\n }\n\n const nr = opt.color?.rNormalized ?? 0.45;\n const ng = opt.color?.gNormalized ?? 0.6;\n const nb = opt.color?.bNormalized ?? 0.3;\n\n for (const frame of opt.image.frames) {\n for (const p of frame) {\n const y = p.luminanceNormalized;\n\n const r = y < 0.5 ? 2 * y * nr : 1 - 2 * (1 - y) * (1 - nr);\n const g = y < 0.5 ? 2 * y * ng : 1 - 2 * (1 - y) * (1 - ng);\n const b = y < 0.5 ? 2 * y * nb : 1 - 2 * (1 - y) * (1 - nb);\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n p.r = MathUtils.mix(p.r, r * p.maxChannelValue, mx);\n p.g = MathUtils.mix(p.g, g * p.maxChannelValue, mx);\n p.b = MathUtils.mix(p.b, b * p.maxChannelValue, mx);\n }\n }\n\n return opt.image;\n }\n\n /**\n * Add random noise to pixel values. **sigma** determines how strong the effect\n * should be. **type** should be one of the following: _NoiseType.gaussian_,\n * _NoiseType.uniform_, _NoiseType.saltAndPepper_, _NoiseType.poisson_,\n * or _NoiseType.rice_.\n */\n public static noise(opt: NoiseOptions): MemoryImage {\n const type = opt.type ?? NoiseType.gaussian;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n let nSigma = opt.sigma;\n let min = 0;\n let max = 0;\n\n if (nSigma === 0 && type !== NoiseType.poisson) {\n return opt.image;\n }\n\n if (nSigma < 0 || type === NoiseType.saltAndPepper) {\n const extremes = opt.image.getColorExtremes();\n min = extremes.min;\n max = extremes.max;\n }\n\n if (nSigma < 0) {\n nSigma = (-nSigma * (max - min)) / 100.0;\n }\n\n for (const frame of opt.image.frames) {\n switch (type) {\n case NoiseType.gaussian:\n for (const p of frame) {\n const r = p.r + nSigma * RandomUtils.grand();\n const g = p.g + nSigma * RandomUtils.grand();\n const b = p.b + nSigma * RandomUtils.grand();\n const a = p.a;\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n if (msk === undefined) {\n p.setRgba(r, g, b, a);\n } else {\n p.r = MathUtils.mix(p.r, r, msk);\n p.g = MathUtils.mix(p.g, g, msk);\n p.b = MathUtils.mix(p.b, b, msk);\n p.a = MathUtils.mix(p.a, a, msk);\n }\n }\n break;\n case NoiseType.uniform:\n for (const p of frame) {\n const r = p.r + nSigma * RandomUtils.crand();\n const g = p.g + nSigma * RandomUtils.crand();\n const b = p.b + nSigma * RandomUtils.crand();\n const a = p.a;\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n if (msk === undefined) {\n p.setRgba(r, g, b, a);\n } else {\n p.r = MathUtils.mix(p.r, r, msk);\n p.g = MathUtils.mix(p.g, g, msk);\n p.b = MathUtils.mix(p.b, b, msk);\n p.a = MathUtils.mix(p.a, a, msk);\n }\n }\n break;\n case NoiseType.saltAndPepper:\n if (nSigma < 0) {\n nSigma = -nSigma;\n }\n if (max === min) {\n min = 0;\n max = 255;\n }\n for (const p of frame) {\n if (Math.random() * 100 < nSigma) {\n const r = Math.random() < 0.5 ? max : min;\n const g = Math.random() < 0.5 ? max : min;\n const b = Math.random() < 0.5 ? max : min;\n const a = p.a;\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n if (msk === undefined) {\n p.setRgba(r, g, b, a);\n } else {\n p.r = MathUtils.mix(p.r, r, msk);\n p.g = MathUtils.mix(p.g, g, msk);\n p.b = MathUtils.mix(p.b, b, msk);\n p.a = MathUtils.mix(p.a, a, msk);\n }\n }\n }\n break;\n case NoiseType.poisson:\n for (const p of frame) {\n const r = RandomUtils.prand(p.r);\n const g = RandomUtils.prand(p.g);\n const b = RandomUtils.prand(p.b);\n const a = p.a;\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n if (msk === undefined) {\n p.setRgba(r, g, b, a);\n } else {\n p.r = MathUtils.mix(p.r, r, msk);\n p.g = MathUtils.mix(p.g, g, msk);\n p.b = MathUtils.mix(p.b, b, msk);\n p.a = MathUtils.mix(p.a, a, msk);\n }\n }\n break;\n case NoiseType.rice: {\n const sqrt2 = Math.sqrt(2);\n for (const p of frame) {\n let val0 = p.r / sqrt2;\n let re = val0 + nSigma * RandomUtils.grand();\n let im = val0 + nSigma * RandomUtils.grand();\n let val = Math.sqrt(re * re + im * im);\n const r = Math.trunc(val);\n\n val0 = p.g / sqrt2;\n re = val0 + nSigma * RandomUtils.grand();\n im = val0 + nSigma * RandomUtils.grand();\n val = Math.sqrt(re * re + im * im);\n const g = Math.trunc(val);\n\n val0 = p.b / sqrt2;\n re = val0 + nSigma * RandomUtils.grand();\n im = val0 + nSigma * RandomUtils.grand();\n val = Math.sqrt(re * re + im * im);\n const b = Math.trunc(val);\n\n const a = p.a;\n\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n if (msk === undefined) {\n p.setRgba(r, g, b, a);\n } else {\n p.r = MathUtils.mix(p.r, r, msk);\n p.g = MathUtils.mix(p.g, g, msk);\n p.b = MathUtils.mix(p.b, b, msk);\n p.a = MathUtils.mix(p.a, a, msk);\n }\n }\n break;\n }\n }\n }\n\n return opt.image;\n }\n\n /**\n * Linearly normalize the colors of the image. All color values will be mapped\n * to the range **min**, **max** inclusive.\n */\n public static normalize(opt: NormalizeOptions): MemoryImage {\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n const a = opt.min < opt.max ? opt.min : opt.max;\n const b = opt.min < opt.max ? opt.max : opt.min;\n\n const extremes = opt.image.getColorExtremes();\n const mn = extremes.min;\n const mx = extremes.max;\n\n if (mn === mx) {\n return opt.image;\n }\n\n const fm = mn;\n const fM = mx;\n\n if (mn !== a || mx !== b) {\n for (const frame of opt.image.frames) {\n for (const p of frame) {\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n if (msk === undefined) {\n p.r = ((p.r - fm) / (fM - fm)) * (b - a) + a;\n p.g = ((p.g - fm) / (fM - fm)) * (b - a) + a;\n p.b = ((p.b - fm) / (fM - fm)) * (b - a) + a;\n p.a = ((p.a - fm) / (fM - fm)) * (b - a) + a;\n } else {\n const xr = ((p.r - fm) / (fM - fm)) * (b - a) + a;\n const xg = ((p.g - fm) / (fM - fm)) * (b - a) + a;\n const xb = ((p.b - fm) / (fM - fm)) * (b - a) + a;\n const xa = ((p.a - fm) / (fM - fm)) * (b - a) + a;\n p.r = MathUtils.mix(p.r, xr, msk);\n p.g = MathUtils.mix(p.g, xg, msk);\n p.b = MathUtils.mix(p.b, xb, msk);\n p.a = MathUtils.mix(p.a, xa, msk);\n }\n }\n }\n }\n\n return opt.image;\n }\n\n /**\n * Pixelate the **image**.\n *\n * **size** determines the size of the pixelated blocks.\n * If **mode** is **upperLeft** then the upper-left corner of the\n * block will be used for the block color. Otherwise if **mode** is\n * **average**, the average of all the pixels in the block will be\n * used for the block color.\n */\n public static pixelate(opt: PixelateOptions): MemoryImage {\n const mode = opt.mode ?? PixelateMode.upperLeft;\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (opt.size <= 1) {\n return opt.image;\n }\n\n for (const frame of opt.image.frames) {\n const w = frame.width;\n const h = frame.height;\n switch (mode) {\n case PixelateMode.upperLeft:\n for (const p of frame) {\n const x2 = Math.trunc(p.x / opt.size) * opt.size;\n const y2 = Math.trunc(p.y / opt.size) * opt.size;\n const p2 = frame.getPixel(x2, y2);\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n if (mx === 1) {\n p.set(p2);\n } else {\n p.r = MathUtils.mix(p.r, p2.r, mx);\n p.g = MathUtils.mix(p.g, p2.g, mx);\n p.b = MathUtils.mix(p.b, p2.b, mx);\n p.a = MathUtils.mix(p.a, p2.a, mx);\n }\n }\n break;\n case PixelateMode.average:\n {\n let r = 0;\n let g = 0;\n let b = 0;\n let a = 0;\n let lx = -1;\n let ly = -1;\n for (const p of frame) {\n const x2 = Math.trunc(p.x / opt.size) * opt.size;\n const y2 = Math.trunc(p.y / opt.size) * opt.size;\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n if (x2 !== lx || y2 <= ly) {\n lx = x2;\n ly = y2;\n r = 0;\n g = 0;\n b = 0;\n a = 0;\n for (\n let by = 0, by2 = y2;\n by < opt.size && by2 < h;\n ++by, ++by2\n ) {\n for (\n let bx = 0, bx2 = x2;\n bx < opt.size && bx2 < w;\n ++bx, ++bx2\n ) {\n const p2 = frame.getPixel(bx2, by2);\n r += p2.r;\n g += p2.g;\n b += p2.b;\n a += p2.a;\n }\n }\n const total = opt.size * opt.size;\n r /= total;\n g /= total;\n b /= total;\n a /= total;\n }\n\n p.r = MathUtils.mix(p.r, r, mx);\n p.g = MathUtils.mix(p.g, g, mx);\n p.b = MathUtils.mix(p.b, b, mx);\n p.a = MathUtils.mix(p.a, a, mx);\n }\n }\n\n break;\n }\n }\n return opt.image;\n }\n\n /**\n * Quantize the number of colors in image to 256.\n */\n public static quantize(opt: QuantizeOptions): MemoryImage {\n const numberOfColors = opt.numberOfColors ?? 256;\n const method = opt.method ?? QuantizeMethod.neuralNet;\n const dither = opt.dither ?? DitherKernel.none;\n const ditherSerpentine = opt.ditherSerpentine ?? false;\n\n let quantizer: Quantizer | undefined = undefined;\n if (method === QuantizeMethod.octree || numberOfColors < 4) {\n quantizer = new OctreeQuantizer(opt.image, numberOfColors);\n } else {\n quantizer = new NeuralQuantizer(opt.image, numberOfColors);\n }\n\n return Filter.ditherImage({\n image: opt.image,\n quantizer: quantizer,\n kernel: dither,\n serpentine: ditherSerpentine,\n });\n }\n\n /**\n * Applies Reinhard tone mapping to the hdr image, in-place.\n */\n public static reinhardToneMap(opt: ReinhardToneMapOptions): MemoryImage {\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n const yw = [0.212671, 0.71516, 0.072169];\n\n // Compute world adaptation luminance, _Ywa_\n let ywa = 0.0;\n for (const p of opt.image) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n const lum = yw[0] * r + yw[1] * g + yw[2] * b;\n if (lum > 1.0e-4) {\n ywa += Math.log(lum);\n }\n }\n\n ywa = Math.exp(ywa / (opt.image.width * opt.image.height));\n\n const invY2 = 1 / (ywa * ywa);\n\n for (const p of opt.image) {\n const r = p.r;\n const g = p.g;\n const b = p.b;\n\n const lum = yw[0] * r + yw[1] * g + yw[2] * b;\n\n const s = (1 + lum * invY2) / (1 + lum);\n\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n if (msk === undefined) {\n p.r = r * s;\n p.g = g * s;\n p.b = b * s;\n } else {\n p.r = MathUtils.mix(p.r, r * s, msk);\n p.g = MathUtils.mix(p.g, g * s, msk);\n p.b = MathUtils.mix(p.b, b * s, msk);\n }\n }\n\n return opt.image;\n }\n\n /**\n * Remap the color channels of the image.\n * **red**, **green**, **blue** and **alpha** should be set to one of the following:\n * _Channel.red_, _Channel.green_, _Channel.blue_, _Channel.alpha_, or\n * _Channel.luminance_.\n */\n public static remapColors(opt: RemapColorsOptions): MemoryImage {\n const red = opt.red ?? Channel.red;\n const green = opt.green ?? Channel.green;\n const blue = opt.blue ?? Channel.blue;\n const alpha = opt.alpha ?? Channel.alpha;\n\n const l: number[] = [0, 0, 0, 0, 0];\n for (const frame of opt.image.frames) {\n for (const p of frame) {\n l[0] = p.r;\n l[1] = p.g;\n l[2] = p.b;\n l[3] = p.a;\n if (\n red === Channel.luminance ||\n green === Channel.luminance ||\n blue === Channel.luminance ||\n alpha === Channel.luminance\n ) {\n l[4] = ColorUtils.getLuminanceRgb(l[0], l[1], l[2]);\n }\n p.r = l[red];\n p.g = l[green];\n p.b = l[blue];\n p.a = l[alpha];\n }\n }\n return opt.image;\n }\n\n public static scaleRgba(opt: ScaleRgbaOptions): MemoryImage {\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n const dr = opt.scale.rNormalized;\n const dg = opt.scale.gNormalized;\n const db = opt.scale.bNormalized;\n const da = opt.scale.aNormalized;\n for (const frame of opt.image.frames) {\n for (const p of frame) {\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n if (msk === undefined) {\n p.setRgba(p.r * dr, p.g * dg, p.b * db, p.a * da);\n } else {\n p.r = MathUtils.mix(p.r, p.r * dr, msk);\n p.g = MathUtils.mix(p.g, p.g * dg, msk);\n p.b = MathUtils.mix(p.b, p.b * db, msk);\n p.a = MathUtils.mix(p.a, p.a * da, msk);\n }\n }\n }\n\n return opt.image;\n }\n\n /**\n * Apply a generic separable convolution filter to the **image**, using the\n * given **kernel**.\n *\n * **gaussianBlur** is an example of such a filter.\n */\n public static separableConvolution(\n opt: SeparableConvolutionOptions\n ): MemoryImage {\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n const tmp = MemoryImage.from(opt.image);\n\n // Apply the filter horizontally\n opt.kernel.apply({\n src: opt.image,\n dst: tmp,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n\n // Apply the filter vertically, applying back to the original image.\n opt.kernel.apply({\n src: tmp,\n dst: opt.image,\n horizontal: false,\n maskChannel: maskChannel,\n mask: opt.mask,\n });\n\n return opt.image;\n }\n\n /**\n * Apply sepia tone to the **image**.\n *\n * **amount** controls the strength of the effect, in the range [0, 1].\n */\n public static sepia(opt: SepiaOptions): MemoryImage {\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (amount === 0) {\n return opt.image;\n }\n\n for (const frame of opt.image.frames) {\n for (const p of frame) {\n const r = p.rNormalized;\n const g = p.gNormalized;\n const b = p.bNormalized;\n const y = ColorUtils.getLuminanceRgb(r, g, b);\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n p.rNormalized = mx * (y + 0.15) + (1 - mx) * r;\n p.gNormalized = mx * (y + 0.07) + (1 - mx) * g;\n p.bNormalized = mx * (y - 0.12) + (1 - mx) * b;\n }\n }\n\n return opt.image;\n }\n\n /**\n * Apply sketch filter to the **image**.\n *\n * **amount** controls the strength of the effect, in the range [0, 1].\n */\n public static sketch(opt: SketchOptions): MemoryImage {\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (amount === 0) {\n return opt.image;\n }\n\n for (const frame of opt.image.frames) {\n const width = frame.width;\n const height = frame.height;\n const orig = MemoryImage.from(frame, true);\n for (const p of frame) {\n const ny = MathUtils.clamp(p.y - 1, 0, height - 1);\n const py = MathUtils.clamp(p.y + 1, 0, height - 1);\n const nx = MathUtils.clamp(p.x - 1, 0, width - 1);\n const px = MathUtils.clamp(p.x + 1, 0, width - 1);\n\n const bottomLeft = orig.getPixel(nx, py).luminanceNormalized;\n const topLeft = orig.getPixel(nx, ny).luminanceNormalized;\n const bottomRight = orig.getPixel(px, py).luminanceNormalized;\n const topRight = orig.getPixel(px, ny).luminanceNormalized;\n const left = orig.getPixel(nx, p.y).luminanceNormalized;\n const right = orig.getPixel(px, p.y).luminanceNormalized;\n const bottom = orig.getPixel(p.x, py).luminanceNormalized;\n const top = orig.getPixel(p.x, ny).luminanceNormalized;\n\n const h =\n -topLeft - 2 * top - topRight + bottomLeft + 2 * bottom + bottomRight;\n\n const v =\n -bottomLeft - 2 * left - topLeft + bottomRight + 2 * right + topRight;\n\n const mag = 1 - Math.sqrt(h * h + v * v);\n\n const r = MathUtils.clamp(mag * p.r, 0, p.maxChannelValue);\n const g = MathUtils.clamp(mag * p.g, 0, p.maxChannelValue);\n const b = MathUtils.clamp(mag * p.b, 0, p.maxChannelValue);\n\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n\n p.r = MathUtils.mix(p.r, r, mx);\n p.g = MathUtils.mix(p.g, g, mx);\n p.b = MathUtils.mix(p.b, b, mx);\n }\n }\n\n return opt.image;\n }\n\n /**\n * Apply a smoothing convolution filter to the **image**.\n *\n * **weight** is the weight of the current pixel being filtered. If it's greater\n * than 1, it will make the image sharper.\n */\n public static smooth(opt: SmoothOptions): MemoryImage {\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n const filter = [1, 1, 1, 1, opt.weight, 1, 1, 1, 1];\n return Filter.convolution({\n image: opt.image,\n filter: filter,\n div: opt.weight + 8,\n offset: 0,\n mask: opt.mask,\n maskChannel: maskChannel,\n });\n }\n\n /**\n * Apply Sobel edge detection filtering to the **image**.\n */\n public static sobel(opt: SobelOptions): MemoryImage {\n const amount = opt.amount ?? 1;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n if (amount === 0) {\n return opt.image;\n }\n\n for (const frame of opt.image.frames) {\n const orig = MemoryImage.from(frame, true);\n const width = frame.width;\n const height = frame.height;\n for (const p of frame) {\n const ny = MathUtils.clamp(p.y - 1, 0, height - 1);\n const py = MathUtils.clamp(p.y + 1, 0, height - 1);\n const nx = MathUtils.clamp(p.x - 1, 0, width - 1);\n const px = MathUtils.clamp(p.x + 1, 0, width - 1);\n\n const bottomLeft = orig.getPixel(nx, py).luminanceNormalized;\n const topLeft = orig.getPixel(nx, ny).luminanceNormalized;\n const bottomRight = orig.getPixel(px, py).luminanceNormalized;\n const topRight = orig.getPixel(px, ny).luminanceNormalized;\n const left = orig.getPixel(nx, p.y).luminanceNormalized;\n const right = orig.getPixel(px, p.y).luminanceNormalized;\n const bottom = orig.getPixel(p.x, py).luminanceNormalized;\n const top = orig.getPixel(p.x, ny).luminanceNormalized;\n\n const h =\n -topLeft - 2 * top - topRight + bottomLeft + 2 * bottom + bottomRight;\n\n const v =\n -bottomLeft - 2 * left - topLeft + bottomRight + 2 * right + topRight;\n\n const mag = Math.sqrt(h * h + v * v) * p.maxChannelValue;\n\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n const invMx = 1 - mx;\n\n p.r = mag * mx + p.r * invMx;\n p.g = mag * mx + p.g * invMx;\n p.b = mag * mx + p.b * invMx;\n }\n }\n\n return opt.image;\n }\n\n public static stretchDistortion(opt: StretchDistortionOptions): MemoryImage {\n const interpolation = opt.interpolation ?? Interpolation.nearest;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n for (const frame of opt.image.frames) {\n const orig = frame.clone({\n skipAnimation: true,\n });\n const w = frame.width - 1;\n const h = frame.height - 1;\n const cx = opt.centerX ?? Math.trunc(frame.width / 2);\n const cy = opt.centerY ?? Math.trunc(frame.height / 2);\n const nCntX = 2 * (cx / w) - 1;\n const nCntY = 2 * (cy / h) - 1;\n for (const p of frame) {\n let ncX = (p.x / w) * 2 - 1;\n let ncY = (p.y / h) * 2 - 1;\n ncX -= nCntX;\n ncY -= nCntY;\n const sX = Math.sign(ncX);\n const sY = Math.sign(ncY);\n ncX = Math.abs(ncX);\n ncY = Math.abs(ncY);\n ncX =\n (0.5 * ncX + 0.5 * MathUtils.smoothStep(0.25, 0.5, ncX) * ncX) * sX;\n ncY =\n (0.5 * ncY + 0.5 * MathUtils.smoothStep(0.25, 0.5, ncY) * ncY) * sY;\n ncX += nCntX;\n ncY += nCntY;\n\n const x = MathUtils.clamp((ncX / 2 + 0.5) * w, 0, w - 1);\n const y = MathUtils.clamp((ncY / 2 + 0.5) * h, 0, h - 1);\n\n const p2 = orig.getPixelInterpolate(x, y, interpolation);\n\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n\n if (msk === undefined) {\n p.r = p2.r;\n p.g = p2.g;\n p.b = p2.b;\n } else {\n p.r = MathUtils.mix(p.r, p2.r, msk);\n p.g = MathUtils.mix(p.g, p2.g, msk);\n p.b = MathUtils.mix(p.b, p2.b, msk);\n }\n }\n }\n\n return opt.image;\n }\n\n /**\n * Apply a vignette filter to the **image**.\n *\n * **start** is the inner radius from the center of the image, where the fade to\n * **color** starts to be applied; **end** is the outer radius of the\n * vignette effect where the **color** is fully applied. The radius values are in\n * normalized percentage of the image size [0, 1].\n * **amount** controls the blend of the effect with the original image.\n */\n public static vignette(opt: VignetteOptions): MemoryImage {\n const start = opt.start ?? 0.3;\n const end = opt.end ?? 0.85;\n const amount = opt.amount ?? 0.9;\n const maskChannel = opt.maskChannel ?? Channel.luminance;\n\n const h = opt.image.height - 1;\n const w = opt.image.width - 1;\n const cr = opt.color?.rNormalized ?? 0;\n const cg = opt.color?.gNormalized ?? 0;\n const cb = opt.color?.bNormalized ?? 0;\n const ca = opt.color?.aNormalized ?? 1;\n const aspect = w / h;\n for (const frame of opt.image.frames) {\n for (const p of frame) {\n const dx = (0.5 - p.x / w) * aspect;\n const dy = 0.5 - p.y / h;\n\n let d = Math.sqrt(dx * dx + dy * dy);\n d = 1 - MathUtils.smoothStep(end, start, d);\n\n const r = MathUtils.mix(p.rNormalized, cr, d) * p.maxChannelValue;\n const g = MathUtils.mix(p.gNormalized, cg, d) * p.maxChannelValue;\n const b = MathUtils.mix(p.bNormalized, cb, d) * p.maxChannelValue;\n const a = MathUtils.mix(p.aNormalized, ca, d) * p.maxChannelValue;\n\n const msk = opt.mask\n ?.getPixel(p.x, p.y)\n .getChannelNormalized(maskChannel);\n const mx = (msk ?? 1) * amount;\n\n p.r = MathUtils.mix(p.r, r, mx);\n p.g = MathUtils.mix(p.g, g, mx);\n p.b = MathUtils.mix(p.b, b, mx);\n p.a = MathUtils.mix(p.a, a, mx);\n }\n }\n\n return opt.image;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { LibError } from '../../error/lib-error';\n\nexport class BmpFileHeader {\n // Signature: BM\n public static readonly signature = 0x4d42;\n\n private readonly _fileLength: number;\n public get fileLength(): number {\n return this._fileLength;\n }\n\n private _imageOffset: number;\n public set imageOffset(v: number) {\n this._imageOffset = v;\n }\n public get imageOffset(): number {\n return this._imageOffset;\n }\n\n constructor(b: InputBuffer) {\n if (!BmpFileHeader.isValidFile(b)) {\n throw new LibError('Not a bitmap file.');\n }\n b.skip(2);\n this._fileLength = b.readInt32();\n // Skip reserved space\n b.skip(4);\n this._imageOffset = b.readInt32();\n }\n\n public static isValidFile(b: InputBuffer): boolean {\n if (b.length < 2) {\n return false;\n }\n const type = InputBuffer.from(b).readUint16();\n return type === BmpFileHeader.signature;\n }\n}\n", "/** @format */\n\nexport enum BmpCompressionMode {\n none,\n rle8,\n rle4,\n bitfields,\n jpeg,\n png,\n alphaBitfields,\n reserved7,\n reserved8,\n reserved9,\n reserved10,\n cmyk,\n cmykRle8,\n cmykRle4,\n}\n", "/** @format */\n\nimport { Color } from '../../color/color';\nimport { BitUtils } from '../../common/bit-utils';\nimport { InputBuffer } from '../../common/input-buffer';\nimport { LibError } from '../../error/lib-error';\nimport { PaletteUint8 } from '../../image/palette-uint8';\nimport { DecodeInfo } from '../decode-info';\nimport { BmpCompressionMode } from './bmp-compression-mode';\nimport { BmpFileHeader } from './bmp-file-header';\n\nexport class BmpInfo implements DecodeInfo {\n private readonly _startPos: number;\n private _redShift = 0;\n private _redScale = 0;\n private _greenShift = 0;\n private _greenScale = 0;\n private _blueShift = 0;\n private _blueScale = 0;\n private _alphaShift = 0;\n private _alphaScale = 0;\n\n private readonly _width: number = 0;\n public get width(): number {\n return this._width;\n }\n\n protected readonly _height: number = 0;\n public get height(): number {\n return Math.abs(this._height);\n }\n\n private readonly _backgroundColor: Color | undefined = undefined;\n public get backgroundColor(): Color | undefined {\n return this._backgroundColor;\n }\n\n private readonly _numFrames: number = 1;\n public get numFrames(): number {\n return this._numFrames;\n }\n\n private readonly _header: BmpFileHeader;\n public get header(): BmpFileHeader {\n return this._header;\n }\n\n private readonly _headerSize: number;\n public get headerSize(): number {\n return this._headerSize;\n }\n\n private readonly _planes: number;\n public get planes(): number {\n return this._planes;\n }\n\n private readonly _bitsPerPixel: number;\n public get bitsPerPixel(): number {\n return this._bitsPerPixel;\n }\n\n private readonly _compression: BmpCompressionMode;\n public get compression(): BmpCompressionMode {\n return this._compression;\n }\n\n private readonly _imageSize: number;\n public get imageSize(): number {\n return this._imageSize;\n }\n\n private readonly _xppm: number;\n public get xppm(): number {\n return this._xppm;\n }\n\n private readonly _yppm: number;\n public get yppm(): number {\n return this._yppm;\n }\n\n private readonly _totalColors: number;\n public get totalColors(): number {\n return this._totalColors;\n }\n\n private readonly _importantColors: number;\n public get importantColors(): number {\n return this._importantColors;\n }\n\n private _redMask = 0;\n public get redMask(): number {\n return this._redMask;\n }\n\n private _greenMask = 0;\n public get greenMask(): number {\n return this._greenMask;\n }\n\n private _blueMask = 0;\n public get blueMask(): number {\n return this._blueMask;\n }\n\n private _alphaMask = 0;\n public get alphaMask(): number {\n return this._alphaMask;\n }\n\n private _palette: PaletteUint8 | undefined;\n public get palette(): PaletteUint8 | undefined {\n return this._palette;\n }\n\n public get readBottomUp(): boolean {\n return this._height >= 0;\n }\n\n public get ignoreAlphaChannel(): boolean {\n // Gimp and Photoshop ignore the alpha channel for BITMAPINFOHEADER.\n return (\n this._headerSize === 40 ||\n // BITMAPV5HEADER with null alpha mask.\n (this._headerSize === 124 && this._alphaMask === 0)\n );\n }\n\n constructor(p: InputBuffer, header?: BmpFileHeader) {\n this._header = header ?? new BmpFileHeader(p);\n this._startPos = p.offset;\n this._headerSize = p.readUint32();\n this._width = p.readInt32();\n this._height = p.readInt32();\n this._planes = p.readUint16();\n this._bitsPerPixel = p.readUint16();\n this._compression = p.readUint32();\n this._imageSize = p.readUint32();\n this._xppm = p.readInt32();\n this._yppm = p.readInt32();\n this._totalColors = p.readUint32();\n this._importantColors = p.readUint32();\n\n // BMP allows > 4 bit per channel for 16bpp, so we have to scale it\n // up to 8-bit\n const maxChannelValue = 255.0;\n\n if (\n this._headerSize > 40 ||\n this._compression === BmpCompressionMode.bitfields ||\n this._compression === BmpCompressionMode.alphaBitfields\n ) {\n this._redMask = p.readUint32();\n this._redShift = BitUtils.countTrailingZeroBits(this._redMask);\n const redDepth = this._redMask >> this._redShift;\n this._redScale = redDepth > 0 ? maxChannelValue / redDepth : 0;\n\n this._greenMask = p.readUint32();\n this._greenShift = BitUtils.countTrailingZeroBits(this._greenMask);\n const greenDepth = this._greenMask >> this._greenShift;\n this._greenScale = redDepth > 0 ? maxChannelValue / greenDepth : 0;\n\n this._blueMask = p.readUint32();\n this._blueShift = BitUtils.countTrailingZeroBits(this._blueMask);\n const blueDepth = this._blueMask >> this._blueShift;\n this._blueScale = redDepth > 0 ? maxChannelValue / blueDepth : 0;\n\n if (\n this._headerSize > 40 ||\n this._compression === BmpCompressionMode.alphaBitfields\n ) {\n this._alphaMask = p.readUint32();\n this._alphaShift = BitUtils.countTrailingZeroBits(this._alphaMask);\n const alphaDepth = this._alphaMask >>> this._alphaShift;\n this._alphaScale = alphaDepth > 0 ? maxChannelValue / alphaDepth : 0;\n } else {\n if (this._bitsPerPixel === 16) {\n this._alphaMask = 0xff000000;\n this._alphaShift = 24;\n this._alphaScale = 1.0;\n } else {\n this._alphaMask = 0xff000000;\n this._alphaShift = 24;\n this._alphaScale = 1.0;\n }\n }\n } else {\n if (this._bitsPerPixel === 16) {\n this._redMask = 0x7c00;\n this._redShift = 10;\n const redDepth = this._redMask >> this._redShift;\n this._redScale = redDepth > 0 ? maxChannelValue / redDepth : 0;\n\n this._greenMask = 0x03e0;\n this._greenShift = 5;\n const greenDepth = this._greenMask >> this._greenShift;\n this._greenScale = redDepth > 0 ? maxChannelValue / greenDepth : 0;\n\n this._blueMask = 0x001f;\n this._blueShift = 0;\n const blueDepth = this._blueMask >> this._blueShift;\n this._blueScale = redDepth > 0 ? maxChannelValue / blueDepth : 0;\n\n this._alphaMask = 0x00000000;\n this._alphaShift = 0;\n this._alphaScale = 0.0;\n } else {\n this._redMask = 0x00ff0000;\n this._redShift = 16;\n this._redScale = 1.0;\n\n this._greenMask = 0x0000ff00;\n this._greenShift = 8;\n this._greenScale = 1.0;\n\n this._blueMask = 0x000000ff;\n this._blueShift = 0;\n this._blueScale = 1.0;\n\n this._alphaMask = 0xff000000;\n this._alphaShift = 24;\n this._alphaScale = 1.0;\n }\n }\n\n const headerRead = p.offset - this._startPos;\n\n const remainingHeaderBytes = this._headerSize - headerRead;\n p.skip(remainingHeaderBytes);\n\n if (this._bitsPerPixel <= 8) {\n this.readPalette(p);\n }\n }\n\n private readPalette(input: InputBuffer): void {\n const numColors =\n this._totalColors === 0 ? 1 << this._bitsPerPixel : this._totalColors;\n const numChannels = 3;\n this._palette = new PaletteUint8(numColors, numChannels);\n for (let i = 0; i < numColors; ++i) {\n const b = input.readByte();\n const g = input.readByte();\n const r = input.readByte();\n // ignored\n const a = input.readByte();\n this._palette.setRgba(i, r, g, b, a);\n }\n }\n\n public decodePixel(\n input: InputBuffer,\n pixel: (r: number, g: number, b: number, a: number) => void\n ): void {\n if (this._palette !== undefined) {\n if (this._bitsPerPixel === 1) {\n const bi = input.readByte();\n for (let i = 7; i >= 0; --i) {\n const b = (bi >> i) & 0x1;\n pixel(b, 0, 0, 0);\n }\n return;\n } else if (this._bitsPerPixel === 2) {\n const bi = input.readByte();\n for (let i = 6; i >= 0; i -= 2) {\n const b = (bi >> i) & 0x2;\n pixel(b, 0, 0, 0);\n }\n } else if (this._bitsPerPixel === 4) {\n const bi = input.readByte();\n const b1 = (bi >> 4) & 0xf;\n pixel(b1, 0, 0, 0);\n const b2 = bi & 0xf;\n pixel(b2, 0, 0, 0);\n return;\n } else if (this._bitsPerPixel === 8) {\n const b = input.readByte();\n pixel(b, 0, 0, 0);\n return;\n }\n }\n\n if (\n this._compression === BmpCompressionMode.bitfields &&\n this._bitsPerPixel === 32\n ) {\n const p = input.readUint32();\n const r = Math.trunc(\n ((p & this._redMask) >> this._redShift) * this._redScale\n );\n const g = Math.trunc(\n ((p & this._greenMask) >> this._greenShift) * this._greenScale\n );\n const b = Math.trunc(\n ((p & this._blueMask) >> this._blueShift) * this._blueScale\n );\n const a = this.ignoreAlphaChannel\n ? 255\n : Math.trunc(\n ((p & this._alphaMask) >> this._alphaShift) * this._alphaScale\n );\n pixel(r, g, b, a);\n return;\n } else if (\n this._bitsPerPixel === 32 &&\n this._compression === BmpCompressionMode.none\n ) {\n const b = input.readByte();\n const g = input.readByte();\n const r = input.readByte();\n const a = input.readByte();\n pixel(r, g, b, this.ignoreAlphaChannel ? 255 : a);\n return;\n } else if (this._bitsPerPixel === 24) {\n const b = input.readByte();\n const g = input.readByte();\n const r = input.readByte();\n pixel(r, g, b, 255);\n return;\n } else if (this._bitsPerPixel === 16) {\n const p = input.readUint16();\n const r = Math.trunc(\n ((p & this._redMask) >> this._redShift) * this._redScale\n );\n const g = Math.trunc(\n ((p & this._greenMask) >> this._greenShift) * this._greenScale\n );\n const b = Math.trunc(\n ((p & this._blueMask) >> this._blueShift) * this._blueScale\n );\n const a = this.ignoreAlphaChannel\n ? 255\n : Math.trunc(\n ((p & this._alphaMask) >> this._alphaShift) * this._alphaScale\n );\n pixel(r, g, b, a);\n return;\n } else {\n throw new LibError(\n `Unsupported bitsPerPixel (${this._bitsPerPixel}) or compression (${this._compression}).`\n );\n }\n }\n}\n", "/** @format */\n\nimport { Format } from '../color/format';\nimport { InputBuffer } from '../common/input-buffer';\nimport { MemoryImage } from '../image/image';\nimport { BmpFileHeader } from './bmp/bmp-file-header';\nimport { BmpInfo } from './bmp/bmp-info';\nimport { Decoder } from './decoder';\n\nexport class BmpDecoder implements Decoder {\n protected _input?: InputBuffer;\n protected _info?: BmpInfo;\n protected _forceRgba: boolean;\n\n public get numFrames(): number {\n return this._info !== undefined ? this._info.numFrames : 0;\n }\n\n constructor(forceRgba = false) {\n this._forceRgba = forceRgba;\n }\n\n /**\n * Is the given file a valid BMP image?\n */\n public isValidFile(bytes: Uint8Array): boolean {\n return BmpFileHeader.isValidFile(\n new InputBuffer({\n buffer: bytes,\n })\n );\n }\n\n public startDecode(bytes: Uint8Array): BmpInfo | undefined {\n if (!this.isValidFile(bytes)) {\n return undefined;\n }\n this._input = new InputBuffer({\n buffer: bytes,\n });\n this._info = new BmpInfo(this._input);\n return this._info;\n }\n\n /**\n * Decode a single frame from the data stat was set with **startDecode**.\n * If **frame** is out of the range of available frames, undefined is returned.\n * Non animated image files will only have **frame** 0. An animation frame\n * is returned, which provides the image, and top-left coordinates of the\n * image, as animated frames may only occupy a subset of the canvas.\n */\n public decodeFrame(_frame: number): MemoryImage | undefined {\n if (this._input === undefined || this._info === undefined) {\n return undefined;\n }\n\n const inf = this._info;\n this._input.offset = inf.header.imageOffset;\n\n const bpp = inf.bitsPerPixel;\n const rowStride = Math.trunc((inf.width * bpp + 31) / 32) * 4;\n const nc = this._forceRgba\n ? 4\n : bpp === 1 || bpp === 4 || bpp === 8\n ? 1\n : bpp === 32\n ? 4\n : 3;\n const format = this._forceRgba\n ? Format.uint8\n : bpp === 1\n ? Format.uint1\n : bpp === 2\n ? Format.uint2\n : bpp === 4\n ? Format.uint4\n : bpp === 8\n ? Format.uint8\n : bpp === 16\n ? Format.uint8\n : bpp === 24\n ? Format.uint8\n : bpp === 32\n ? Format.uint8\n : Format.uint8;\n const palette = this._forceRgba ? undefined : inf.palette;\n\n const image = new MemoryImage({\n width: inf.width,\n height: inf.height,\n format: format,\n numChannels: nc,\n palette: palette,\n });\n\n for (let y = image.height - 1; y >= 0; --y) {\n const line = inf.readBottomUp ? y : image.height - 1 - y;\n const row = this._input.readBytes(rowStride);\n const w = image.width;\n let x = 0;\n const p = image.getPixel(0, line);\n while (x < w) {\n inf.decodePixel(row, (r, g, b, a) => {\n if (x < w) {\n if (this._forceRgba && inf.palette !== undefined) {\n const pi = Math.trunc(r);\n const pr = inf.palette!.getRed(pi);\n const pg = inf.palette!.getGreen(pi);\n const pb = inf.palette!.getBlue(pi);\n const pa = inf.palette!.getAlpha(pi);\n p.setRgba(pr, pg, pb, pa);\n } else {\n p.setRgba(r, g, b, a);\n }\n p.next();\n x++;\n }\n });\n }\n }\n\n return image;\n }\n\n /**\n * Decode the file and extract a single image from it. If the file is\n * animated, the specified **frame** will be decoded. If there was a problem\n * decoding the file, undefined is returned.\n */\n public decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined {\n if (this.startDecode(bytes) === undefined) {\n return undefined;\n }\n return this.decodeFrame(frame ?? 0);\n }\n}\n", "/** @format */\n\nimport { Format } from '../color/format';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { MemoryImage } from '../image/image';\nimport { PaletteUint8 } from '../image/palette-uint8';\nimport { BmpCompressionMode } from './bmp/bmp-compression-mode';\nimport { BmpFileHeader } from './bmp/bmp-file-header';\nimport { Encoder } from './encoder';\n\n/**\n * Encode a BMP image.\n */\nexport class BmpEncoder implements Encoder {\n private _supportsAnimation = false;\n public get supportsAnimation(): boolean {\n return this._supportsAnimation;\n }\n\n public encode(image: MemoryImage, _singleFrame = false): Uint8Array {\n const out = new OutputBuffer();\n let img = image;\n\n const nc = img.numChannels;\n let palette = img.palette;\n const format = img.format;\n\n if (format === Format.uint1 && nc === 1 && palette === undefined) {\n // add palette\n palette = new PaletteUint8(2, 3);\n palette.setRgb(0, 0, 0, 0);\n palette.setRgb(1, 255, 255, 255);\n } else if (format === Format.uint1 && nc === 2) {\n // => uint2 palette\n img = img.convert({\n format: Format.uint2,\n numChannels: 1,\n withPalette: true,\n });\n palette = img.palette;\n } else if (format === Format.uint1 && nc === 3 && palette === undefined) {\n // => uint4 palette\n img = img.convert({\n format: Format.uint4,\n withPalette: true,\n });\n palette = img.palette;\n } else if (format === Format.uint1 && nc === 4) {\n // => uint8,4 - only 32bpp supports alpha\n img = img.convert({\n format: Format.uint8,\n numChannels: 4,\n });\n } else if (format === Format.uint2 && nc === 1 && palette === undefined) {\n // => uint2 palette\n img = img.convert({\n format: Format.uint2,\n withPalette: true,\n });\n palette = img.palette;\n } else if (format === Format.uint2 && nc === 2) {\n // => uint8 palette\n img = img.convert({\n format: Format.uint8,\n withPalette: true,\n });\n palette = img.palette;\n } else if (format === Format.uint2 && nc === 3 && palette === undefined) {\n // => uint8 palette\n img = img.convert({\n format: Format.uint8,\n withPalette: true,\n });\n palette = img.palette;\n } else if (format === Format.uint2 && nc === 4) {\n // => uint8 palette\n img = img.convert({\n format: Format.uint8,\n withPalette: true,\n });\n palette = img.palette;\n } else if (format === Format.uint4 && nc === 1 && palette === undefined) {\n // => uint8 palette\n img = img.convert({\n format: Format.uint8,\n withPalette: true,\n });\n palette = img.palette;\n } else if (format === Format.uint4 && nc === 2) {\n // => uint8,3\n img = img.convert({\n format: Format.uint8,\n numChannels: 3,\n });\n } else if (format === Format.uint4 && nc === 3 && palette === undefined) {\n // => uint8,3\n img = img.convert({\n format: Format.uint8,\n numChannels: 3,\n });\n } else if (format === Format.uint4 && nc === 4) {\n // => uint8,4\n img = img.convert({\n format: Format.uint8,\n numChannels: 4,\n });\n } else if (format === Format.uint8 && nc === 1 && palette === undefined) {\n // => uint8 palette\n img = img.convert({\n format: Format.uint8,\n withPalette: true,\n });\n } else if (format === Format.uint8 && nc === 2) {\n // => uint8,3\n img = img.convert({\n format: Format.uint8,\n numChannels: 3,\n });\n } else if (img.isHdrFormat) {\n // => uint8,[3,4]\n img = img.convert({\n format: Format.uint8,\n });\n } else if (img.hasPalette && img.numChannels === 4) {\n img = img.convert({\n numChannels: 4,\n });\n }\n\n let bpp = img.bitsPerChannel * img.data!.numChannels;\n if (bpp === 12) {\n bpp = 16;\n }\n\n const compression =\n bpp > 8 ? BmpCompressionMode.bitfields : BmpCompressionMode.none;\n\n const imageStride = img.rowStride;\n const fileStride = Math.trunc((img.width * bpp + 31) / 32) * 4;\n const rowPaddingSize = fileStride - imageStride;\n const rowPadding =\n rowPaddingSize > 0\n ? new Uint8Array(rowPaddingSize).fill(0xff)\n : undefined;\n const imageFileSize = fileStride * img.height;\n const headerInfoSize = bpp > 8 ? 124 : 40;\n const headerSize = headerInfoSize + 14;\n const paletteSize = (img.palette?.numColors ?? 0) * 4;\n const origImageOffset = headerSize + paletteSize;\n const imageOffset = origImageOffset;\n const gapSize = imageOffset - origImageOffset;\n const fileSize = imageFileSize + headerSize + paletteSize + gapSize;\n\n const sRgb = 0x73524742;\n\n out.writeUint16(BmpFileHeader.signature);\n out.writeUint32(fileSize);\n // reserved\n out.writeUint32(0);\n // offset to image data\n out.writeUint32(imageOffset);\n out.writeUint32(headerInfoSize);\n out.writeUint32(img.width);\n out.writeUint32(img.height);\n // planes\n out.writeUint16(1);\n // bits per pixel\n out.writeUint16(bpp);\n // compression\n out.writeUint32(compression);\n\n out.writeUint32(imageFileSize);\n // hr\n out.writeUint32(11811);\n // vr\n out.writeUint32(11811);\n // totalColors\n out.writeUint32(bpp === 8 ? 255 : 0);\n // importantColors\n out.writeUint32(bpp === 8 ? 255 : 0);\n\n if (bpp > 8) {\n const blueMask = bpp === 16 ? 0xf : 0xff;\n const greenMask = bpp === 16 ? 0xf0 : 0xff00;\n const redMask = bpp === 16 ? 0xf00 : 0xff0000;\n const alphaMask = bpp === 16 ? 0xf000 : 0xff000000;\n\n // redMask\n out.writeUint32(redMask);\n // greenMask\n out.writeUint32(greenMask);\n // blueMask\n out.writeUint32(blueMask);\n // alphaMask\n out.writeUint32(alphaMask);\n // CSType\n out.writeUint32(sRgb);\n // endpoints.red.x\n out.writeUint32(0);\n // endpoints.red.y\n out.writeUint32(0);\n // endpoints.red.z\n out.writeUint32(0);\n // endpoints.green.x\n out.writeUint32(0);\n // endpoints.green.y\n out.writeUint32(0);\n // endpoints.green.z\n out.writeUint32(0);\n // endpoints.blue.x\n out.writeUint32(0);\n // endpoints.blue.y\n out.writeUint32(0);\n // endpoints.blue.z\n out.writeUint32(0);\n // gammaRed\n out.writeUint32(0);\n // gammaGreen\n out.writeUint32(0);\n // gammaBlue\n out.writeUint32(0);\n // intent LCS_GM_GRAPHICS\n out.writeUint32(2);\n // profileData\n out.writeUint32(0);\n // profileSize\n out.writeUint32(0);\n // reserved\n out.writeUint32(0);\n }\n\n if (bpp === 1 || bpp === 2 || bpp === 4 || bpp === 8) {\n if (palette !== undefined) {\n const l = palette.numColors;\n for (let pi = 0; pi < l; ++pi) {\n out.writeByte(Math.trunc(palette.getBlue(pi)));\n out.writeByte(Math.trunc(palette.getGreen(pi)));\n out.writeByte(Math.trunc(palette.getRed(pi)));\n out.writeByte(0);\n }\n } else {\n if (bpp === 1) {\n out.writeByte(0);\n out.writeByte(0);\n out.writeByte(0);\n out.writeByte(0);\n out.writeByte(255);\n out.writeByte(255);\n out.writeByte(255);\n out.writeByte(0);\n } else if (bpp === 2) {\n for (let pi = 0; pi < 4; ++pi) {\n const v = pi * 85;\n out.writeByte(v);\n out.writeByte(v);\n out.writeByte(v);\n out.writeByte(0);\n }\n } else if (bpp === 4) {\n for (let pi = 0; pi < 16; ++pi) {\n const v = pi * 17;\n out.writeByte(v);\n out.writeByte(v);\n out.writeByte(v);\n out.writeByte(0);\n }\n } else if (bpp === 8) {\n for (let pi = 0; pi < 256; ++pi) {\n out.writeByte(pi);\n out.writeByte(pi);\n out.writeByte(pi);\n out.writeByte(0);\n }\n }\n }\n }\n\n // image data must be aligned to a 4 byte alignment. Pad the remaining\n // bytes until the image starts.\n let gap1 = gapSize;\n while (gap1-- > 0) {\n out.writeByte(0);\n }\n\n // Write image data\n if (bpp === 1 || bpp === 2 || bpp === 4 || bpp === 8) {\n let offset = img.byteLength - imageStride;\n const h = img.height;\n for (let y = 0; y < h; ++y) {\n const bytes =\n img.buffer !== undefined\n ? new Uint8Array(img.buffer, offset, imageStride)\n : new Uint8Array();\n\n if (bpp === 1) {\n out.writeBytes(bytes);\n } else if (bpp === 2) {\n const l = bytes.length;\n for (let xi = 0; xi < l; ++xi) {\n const b = bytes[xi];\n const left = b >> 4;\n const right = b & 0x0f;\n const rb = (right << 4) | left;\n out.writeByte(rb);\n }\n } else if (bpp === 4) {\n const l = bytes.length;\n for (let xi = 0; xi < l; ++xi) {\n const b = bytes[xi];\n const b1 = b >> 4;\n const b2 = b & 0x0f;\n const rb = (b1 << 4) | b2;\n out.writeByte(rb);\n }\n } else {\n out.writeBytes(bytes);\n }\n\n if (rowPadding !== undefined) {\n out.writeBytes(rowPadding);\n }\n\n offset -= imageStride;\n }\n\n return out.getBytes();\n }\n\n const hasAlpha = img.numChannels === 4;\n const h = img.height;\n const w = img.width;\n if (bpp === 16) {\n for (let y = h - 1; y >= 0; --y) {\n for (let x = 0; x < w; ++x) {\n const p = img.getPixel(x, y);\n out.writeByte((Math.trunc(p.g) << 4) | Math.trunc(p.b));\n out.writeByte((Math.trunc(p.a) << 4) | Math.trunc(p.r));\n }\n if (rowPadding !== undefined) {\n out.writeBytes(rowPadding);\n }\n }\n } else {\n for (let y = h - 1; y >= 0; --y) {\n for (let x = 0; x < w; ++x) {\n const p = img.getPixel(x, y);\n out.writeByte(Math.trunc(p.b));\n out.writeByte(Math.trunc(p.g));\n out.writeByte(Math.trunc(p.r));\n if (hasAlpha) {\n out.writeByte(Math.trunc(p.a));\n }\n }\n if (rowPadding !== undefined) {\n out.writeBytes(rowPadding);\n }\n }\n }\n\n return out.getBytes();\n }\n}\n", "/** @format */\n\nimport { Color } from '../color/color';\n\n/**\n * Provides information about the image being decoded.\n */\nexport interface DecodeInfo {\n /**\n * The width of the image canvas.\n */\n get width(): number;\n\n /**\n * The height of the image canvas.\n */\n get height(): number;\n\n /**\n * The suggested background color of the canvas.\n */\n get backgroundColor(): Color | undefined;\n\n /**\n * The number of frames that can be decoded.\n */\n get numFrames(): number;\n}\n", "/** @format */\n\nimport { MemoryImage } from '../image/image';\nimport { DecodeInfo } from './decode-info';\n\n/**\n * Base class for image format decoders.\n *\n * Image pixels are stored as 32-bit unsigned ints, so all formats, regardless\n * of their encoded color resolutions, decode to 32-bit RGBA images. Encoders\n * can reduce the color resolution back down to their required formats.\n *\n * Some image formats support multiple frames, often for encoding animation.\n * In such cases, the **decode** method will decode all of the frames,\n * unless the frame argument is specified for a particular frame to decode.\n * **startDecode** will initiate decoding of the file, and **decodeFrame** will\n * then decode a specific frame from the file, allowing for animations to be\n * decoded one frame at a time. Some formats, such as TIFF, may store multiple\n * frames, but their use of frames is for multiple page documents and not\n * animation. The terms 'animation' and 'frames' simply refer to 'pages' in\n * this case.\n */\nexport interface Decoder {\n /**\n * How many frames are available to be decoded. **startDecode** should have\n * been called first. Non animated image files will have a single frame.\n */\n get numFrames(): number;\n\n /**\n * A light-weight function to test if the given file is able to be decoded\n * by this Decoder.\n */\n isValidFile(bytes: Uint8Array): boolean;\n\n /**\n * Start decoding the data as an animation sequence, but don't actually\n * process the frames until they are requested with **decodeFrame**.\n */\n startDecode(bytes: Uint8Array): DecodeInfo | undefined;\n\n /**\n * Decode the file and extract a single image from it. If the file is\n * animated, and **frame** is specified, that particular frame will be decoded.\n * Otherwise if the image is animated and **frame** is undefined, the returned\n * MemoryImage will include all frames. If there was a problem decoding the\n * MemoryImage, undefined will be returned.\n */\n decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined;\n\n /**\n * Decode a single frame from the data that was set with **startDecode**.\n * If **frame** is out of the range of available frames, undefined is returned.\n * Non animated image files will only have **frame** 0. A MemoryImage\n * is returned, which provides the image, and top-left coordinates of the\n * image, as animated frames may only occupy a subset of the canvas.\n */\n decodeFrame(frame: number): MemoryImage | undefined;\n}\n", "/** @format */\n\nimport { InputBuffer } from '../common/input-buffer';\nimport { BmpDecoder } from './bmp-decoder';\nimport { BmpInfo } from './bmp/bmp-info';\n\nexport class DibDecoder extends BmpDecoder {\n constructor(input: InputBuffer, info: BmpInfo, forceRgba = false) {\n super(forceRgba);\n this._input = input;\n this._info = info;\n }\n}\n", "/** @format */\n\nimport { MemoryImage } from '../image/image';\n\n/**\n * Base class for image format encoders.\n */\nexport interface Encoder {\n /**\n * True if the encoder supports animated images; otherwise false.\n */\n get supportsAnimation(): boolean;\n\n /**\n * Encode an **image** to an image format.\n * If **singleFrame** is true, only the one MemoryImage will be encoded;\n * otherwise if image has animation, all frames of the **image** will be\n * encoded if the encoder supports animation.\n */\n encode(image: MemoryImage, singleFrame?: boolean): Uint8Array;\n}\n", "/** @format */\n\nimport { ColorUint8 } from '../../color/color-uint8';\nimport { PaletteUint8 } from '../../image/palette-uint8';\n\nexport class GifColorMap {\n private readonly _numColors: number;\n public get numColors(): number {\n return this._numColors;\n }\n\n private readonly _palette: PaletteUint8;\n public get palette(): PaletteUint8 {\n return this._palette;\n }\n\n private _bitsPerPixel: number;\n public get bitsPerPixel(): number {\n return this._bitsPerPixel;\n }\n\n private _transparent?: number;\n public set transparent(v: number | undefined) {\n this._transparent = v;\n }\n public get transparent(): number | undefined {\n return this._transparent;\n }\n\n constructor(numColors: number, palette?: PaletteUint8) {\n this._numColors = numColors;\n this._palette = palette ?? new PaletteUint8(numColors, 3);\n this._bitsPerPixel = GifColorMap.bitSize(numColors);\n }\n\n private static bitSize(n: number): number {\n for (let i = 1; i <= 8; i++) {\n if (1 << i >= n) {\n return i;\n }\n }\n return 0;\n }\n\n public static from(other: GifColorMap) {\n const palette = PaletteUint8.from(other._palette);\n const r = new GifColorMap(other.numColors, palette);\n r._bitsPerPixel = other._bitsPerPixel;\n r._transparent = other._transparent;\n return r;\n }\n\n public getColor(index: number): ColorUint8 {\n const r = this.getRed(index);\n const g = this.getGreen(index);\n const b = this.getBlue(index);\n const a = this.getAlpha(index);\n return ColorUint8.rgba(r, g, b, a);\n }\n\n public setColor(index: number, r: number, g: number, b: number): void {\n this._palette.setRgb(index, r, g, b);\n }\n\n public getRed(color: number): number {\n return Math.trunc(this._palette.getRed(color));\n }\n\n public getGreen(color: number): number {\n return Math.trunc(this._palette.getGreen(color));\n }\n\n public getBlue(color: number): number {\n return Math.trunc(this._palette.getBlue(color));\n }\n\n public getAlpha(color: number): number {\n return color === this._transparent ? 0 : 255;\n }\n\n public getPalette(): PaletteUint8 {\n if (this._transparent === undefined) {\n return this._palette;\n }\n const p = new PaletteUint8(this._palette.numColors, 4);\n const l = this._palette.numColors;\n for (let i = 0; i < l; ++i) {\n p.setRgba(\n i,\n this.getRed(i),\n this.getGreen(i),\n this.getBlue(i),\n this.getAlpha(i)\n );\n }\n return p;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { GifColorMap } from './gif-color-map';\n\nexport class GifImageDesc {\n private readonly _x: number;\n public get x(): number {\n return this._x;\n }\n\n private readonly _y: number;\n public get y(): number {\n return this._y;\n }\n\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _interlaced: boolean;\n public get interlaced(): boolean {\n return this._interlaced;\n }\n\n private _colorMap?: GifColorMap;\n public get colorMap(): GifColorMap | undefined {\n return this._colorMap;\n }\n public set colorMap(v: GifColorMap | undefined) {\n this._colorMap = v;\n }\n\n private _duration = 80;\n public set duration(v: number) {\n this._duration = v;\n }\n public get duration(): number {\n return this._duration;\n }\n\n private _clearFrame = true;\n public set clearFrame(v: boolean) {\n this._clearFrame = v;\n }\n public get clearFrame(): boolean {\n return this._clearFrame;\n }\n\n /**\n * The position in the file after the ImageDesc for this frame.\n */\n protected _inputPosition: number;\n public get inputPosition(): number {\n return this._inputPosition;\n }\n\n constructor(input: InputBuffer) {\n this._x = input.readUint16();\n this._y = input.readUint16();\n this._width = input.readUint16();\n this._height = input.readUint16();\n\n const b = input.readByte();\n const bitsPerPixel = (b & 0x07) + 1;\n\n this._interlaced = (b & 0x40) !== 0;\n\n if ((b & 0x80) !== 0) {\n this._colorMap = new GifColorMap(1 << bitsPerPixel);\n for (let i = 0; i < this._colorMap.numColors; ++i) {\n this._colorMap.setColor(\n i,\n input.readByte(),\n input.readByte(),\n input.readByte()\n );\n }\n }\n\n this._inputPosition = input.position;\n }\n}\n", "/** @format */\n\nimport { Color } from '../../color/color';\nimport { DecodeInfo } from '../decode-info';\nimport { GifColorMap } from './gif-color-map';\nimport { GifImageDesc } from './gif-image-desc';\n\nexport interface GifInfoInitOptions {\n width?: number;\n height?: number;\n backgroundColor?: Color;\n frames?: Array;\n colorResolution?: number;\n globalColorMap?: GifColorMap;\n isGif89?: boolean;\n}\n\nexport class GifInfo implements DecodeInfo {\n private _width = 0;\n public get width(): number {\n return this._width;\n }\n\n private _height = 0;\n public get height(): number {\n return this._height;\n }\n\n private _backgroundColor: Color | undefined = undefined;\n public get backgroundColor(): Color | undefined {\n return this._backgroundColor;\n }\n\n private _frames: Array;\n public get frames(): Array {\n return this._frames;\n }\n\n private _colorResolution;\n public get colorResolution(): number {\n return this._colorResolution;\n }\n\n private _globalColorMap?: GifColorMap;\n public get globalColorMap(): GifColorMap | undefined {\n return this._globalColorMap;\n }\n\n private _isGif89 = false;\n public get isGif89(): boolean {\n return this._isGif89;\n }\n\n public get numFrames(): number {\n return this.frames.length;\n }\n\n constructor(opt?: GifInfoInitOptions) {\n this._width = opt?.width ?? 0;\n this._height = opt?.height ?? 0;\n this._backgroundColor = opt?.backgroundColor;\n this._frames = opt?.frames ?? new Array();\n this._colorResolution = opt?.colorResolution ?? 0;\n this._globalColorMap = opt?.globalColorMap;\n this._isGif89 = opt?.isGif89 ?? false;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../common/input-buffer';\nimport { ArrayUtils } from '../common/array-utils';\nimport { Decoder } from './decoder';\nimport { GifColorMap } from './gif/gif-color-map';\nimport { GifImageDesc } from './gif/gif-image-desc';\nimport { GifInfo } from './gif/gif-info';\nimport { MemoryImage } from '../image/image';\nimport { ColorUint8 } from '../color/color-uint8';\n\n/**\n * A decoder for the GIF image format. This supports both single frame and\n * animated GIF files, and transparency.\n */\nexport class GifDecoder implements Decoder {\n private static readonly _stampSize: number = 6;\n private static readonly _gif87Stamp: string = 'GIF87a';\n private static readonly _gif89Stamp: string = 'GIF89a';\n\n private static readonly _imageDescRecordType: number = 0x2c;\n private static readonly _extensionRecordType: number = 0x21;\n private static readonly _terminateRecordType: number = 0x3b;\n\n private static readonly _graphicControlExt: number = 0xf9;\n private static readonly _applicationExt: number = 0xff;\n\n private static readonly _lzMaxCode: number = 4095;\n private static readonly _lzBits: number = 12;\n\n // Impossible code, to signal empty.\n private static readonly _noSuchCode: number = 4098;\n\n private static readonly _codeMasks: number[] = [\n 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,\n 0x01ff, 0x03ff, 0x07ff, 0x0fff,\n ];\n\n private static readonly _interlacedOffset: number[] = [0, 4, 2, 1];\n private static readonly _interlacedJump: number[] = [8, 8, 4, 2];\n\n private _input?: InputBuffer;\n\n private _info?: GifInfo;\n\n private _repeat = 0;\n\n private _buffer?: Uint8Array;\n\n private _stack!: Uint8Array;\n\n private _suffix!: Uint8Array;\n\n private _prefix?: Uint32Array;\n\n private _bitsPerPixel = 0;\n\n private _pixelCount?: number;\n\n private _currentShiftDWord = 0;\n\n private _currentShiftState = 0;\n\n private _stackPtr = 0;\n\n private _currentCode?: number;\n\n private _lastCode = 0;\n\n private _maxCode1 = 0;\n\n private _runningBits = 0;\n\n private _runningCode = 0;\n\n private _eofCode = 0;\n\n private _clearCode = 0;\n\n /**\n * How many frames are available to decode?\n *\n * You should have prepared the decoder by either passing the file bytes\n * to the constructor, or calling getInfo.\n */\n public get numFrames(): number {\n return this._info !== undefined ? this._info.numFrames : 0;\n }\n\n constructor(bytes?: Uint8Array) {\n if (bytes !== undefined) {\n this.startDecode(bytes);\n }\n }\n\n /**\n * Routine to trace the Prefixes linked list until we get a prefix which is\n * not code, but a pixel value (less than ClearCode). Returns that pixel value.\n * If image is defective, we might loop here forever, so we limit the loops to\n * the maximum possible if image O.k. - lzMaxCode times.\n */\n private static getPrefixChar(\n prefix: Uint32Array,\n code: number,\n clearCode: number\n ): number {\n let c = code;\n let i = 0;\n while (c > clearCode && i++ <= GifDecoder._lzMaxCode) {\n if (c > GifDecoder._lzMaxCode) {\n return GifDecoder._noSuchCode;\n }\n c = prefix[c];\n }\n return c;\n }\n\n private static updateImage(\n image: MemoryImage,\n y: number,\n colorMap: GifColorMap | undefined,\n line: Uint8Array\n ): void {\n if (colorMap !== undefined) {\n const width = line.length;\n for (let x = 0; x < width; ++x) {\n image.setPixelRgb(x, y, line[x], 0, 0);\n }\n }\n }\n\n private getInfo(): boolean {\n if (this._input === undefined) {\n return false;\n }\n\n const tag = this._input.readString(GifDecoder._stampSize);\n if (tag !== GifDecoder._gif87Stamp && tag !== GifDecoder._gif89Stamp) {\n return false;\n }\n\n const width = this._input.readUint16();\n const height = this._input.readUint16();\n\n const b = this._input.readByte();\n const colorResolution = (((b & 0x70) + 1) >> 4) + 1;\n\n const bitsPerPixel = (b & 0x07) + 1;\n const backgroundColor = new ColorUint8(\n new Uint8Array([this._input.readByte()])\n );\n\n this._input.skip(1);\n\n let globalColorMap: GifColorMap | undefined = undefined;\n // Is there a global color map?\n if ((b & 0x80) !== 0) {\n globalColorMap = new GifColorMap(1 << bitsPerPixel);\n\n // Get the global color map:\n for (let i = 0; i < globalColorMap.numColors; ++i) {\n const r = this._input.readByte();\n const g = this._input.readByte();\n const b = this._input.readByte();\n globalColorMap.setColor(i, r, g, b);\n }\n }\n\n const isGif89 = tag === GifDecoder._gif89Stamp;\n\n this._info = new GifInfo({\n width: width,\n height: height,\n colorResolution: colorResolution,\n backgroundColor: backgroundColor,\n globalColorMap: globalColorMap,\n isGif89: isGif89,\n });\n\n return true;\n }\n\n private skipImage(): GifImageDesc | undefined {\n if (this._input === undefined || this._input.isEOS) {\n return undefined;\n }\n const gifImage = new GifImageDesc(this._input);\n this._input.skip(1);\n this.skipRemainder();\n return gifImage;\n }\n\n /**\n * Continue to get the image code in compressed form. This routine should be\n * called until NULL block is returned.\n * The block should NOT be freed by the user (not dynamically allocated).\n */\n private skipRemainder(): boolean {\n if (this._input === undefined || this._input.isEOS) {\n return true;\n }\n let b = this._input.readByte();\n while (b !== 0 && !this._input.isEOS) {\n this._input.skip(b);\n if (this._input.isEOS) {\n return true;\n }\n b = this._input.readByte();\n }\n return true;\n }\n\n private readApplicationExt(input: InputBuffer): void {\n const blockSize = input.readByte();\n const tag = input.readString(blockSize);\n if (tag === 'NETSCAPE2.0') {\n const b1 = input.readByte();\n const b2 = input.readByte();\n if (b1 === 0x03 && b2 === 0x01) {\n this._repeat = input.readUint16();\n }\n } else {\n this.skipRemainder();\n }\n }\n\n private readGraphicsControlExt(input: InputBuffer): void {\n /* const blockSize: number = */\n input.readByte();\n const b = input.readByte();\n const duration = input.readUint16();\n const transparent = input.readByte();\n /* const endBlock: number = */\n input.readByte();\n const disposalMethod = (b >> 2) & 0x7;\n // const userInput: number = (b >> 1) & 0x1;\n const transparentFlag = b & 0x1;\n\n const recordType = input.peekBytes(1).getByte(0);\n if (recordType === GifDecoder._imageDescRecordType) {\n input.skip(1);\n const gifImage = this.skipImage();\n if (gifImage === undefined) {\n return;\n }\n\n gifImage.duration = duration;\n gifImage.clearFrame = disposalMethod === 2;\n\n if (transparentFlag !== 0) {\n if (\n gifImage.colorMap === undefined &&\n this._info!.globalColorMap !== undefined\n ) {\n gifImage.colorMap = GifColorMap.from(this._info!.globalColorMap);\n }\n if (gifImage.colorMap !== undefined) {\n gifImage.colorMap.transparent = transparent;\n }\n }\n\n this._info!.frames.push(gifImage);\n }\n }\n\n private getLine(line: Uint8Array): boolean {\n this._pixelCount = this._pixelCount! - line.length;\n\n if (!this.decompressLine(line)) {\n return false;\n }\n\n // Flush any remainder blocks.\n if (this._pixelCount === 0) {\n this.skipRemainder();\n }\n\n return true;\n }\n\n /**\n * The LZ decompression routine:\n * This version decompress the given gif file into Line of length LineLen.\n * This routine can be called few times (one per scan line, for example), in\n * order the complete the whole image.\n */\n private decompressLine(line: Uint8Array): boolean {\n if (this._stackPtr > GifDecoder._lzMaxCode) {\n return false;\n }\n\n const lineLen = line.length;\n let i = 0;\n\n if (this._stackPtr !== 0) {\n // Let pop the stack off before continuing to read the gif file:\n while (this._stackPtr !== 0 && i < lineLen) {\n line[i++] = this._stack[--this._stackPtr];\n }\n }\n\n let currentPrefix: number | undefined = undefined;\n\n // Decode LineLen items.\n while (i < lineLen) {\n this._currentCode = this.decompressInput();\n if (this._currentCode === undefined) {\n return false;\n }\n\n if (this._currentCode === this._eofCode) {\n // Note however that usually we will not be here as we will stop\n // decoding as soon as we got all the pixel, or EOF code will\n // not be read at all, and DGifGetLine/Pixel clean everything.\n return false;\n }\n\n if (this._currentCode === this._clearCode) {\n // We need to start over again:\n for (let j = 0; j <= GifDecoder._lzMaxCode; j++) {\n this._prefix![j] = GifDecoder._noSuchCode;\n }\n\n this._runningCode = this._eofCode + 1;\n this._runningBits = this._bitsPerPixel + 1;\n this._maxCode1 = 1 << this._runningBits;\n this._lastCode = GifDecoder._noSuchCode;\n } else {\n // Its regular code - if in pixel range simply add it to output\n // stream, otherwise trace to codes linked list until the prefix\n // is in pixel range:\n if (this._currentCode < this._clearCode) {\n // This is simple - its pixel scalar, so add it to output:\n line[i++] = this._currentCode;\n } else {\n // Its a code to needed to be traced: trace the linked list\n // until the prefix is a pixel, while pushing the suffix\n // pixels on our stack. If we done, pop the stack in reverse\n // (thats what stack is good for!) order to output. */\n if (this._prefix![this._currentCode] === GifDecoder._noSuchCode) {\n // Only allowed if CrntCode is exactly the running code:\n // In that case CrntCode = XXXCode, CrntCode or the\n // prefix code is last code and the suffix char is\n // exactly the prefix of last code!\n if (this._currentCode === this._runningCode - 2) {\n currentPrefix = this._lastCode;\n const prefixChar = GifDecoder.getPrefixChar(\n this._prefix!,\n this._lastCode,\n this._clearCode\n );\n this._stack[this._stackPtr++] = prefixChar;\n this._suffix[this._runningCode - 2] = prefixChar;\n } else {\n return false;\n }\n } else {\n currentPrefix = this._currentCode;\n }\n\n // Now (if image is O.K.) we should not get an noSuchCode\n // During the trace. As we might loop forever, in case of\n // defective image, we count the number of loops we trace\n // and stop if we got lzMaxCode. obviously we can not\n // loop more than that.\n let j = 0;\n while (\n j++ <= GifDecoder._lzMaxCode &&\n currentPrefix > this._clearCode &&\n currentPrefix <= GifDecoder._lzMaxCode\n ) {\n this._stack[this._stackPtr++] = this._suffix[currentPrefix];\n currentPrefix = this._prefix![currentPrefix];\n }\n\n if (\n j >= GifDecoder._lzMaxCode ||\n currentPrefix > GifDecoder._lzMaxCode\n ) {\n return false;\n }\n\n // Push the last character on stack:\n this._stack[this._stackPtr++] = currentPrefix;\n\n // Now lets pop all the stack into output:\n while (this._stackPtr !== 0 && i < lineLen) {\n line[i++] = this._stack[--this._stackPtr];\n }\n }\n\n if (\n this._lastCode !== GifDecoder._noSuchCode &&\n this._prefix![this._runningCode - 2] === GifDecoder._noSuchCode\n ) {\n this._prefix![this._runningCode - 2] = this._lastCode;\n\n if (this._currentCode === this._runningCode - 2) {\n // Only allowed if CrntCode is exactly the running code:\n // In that case CrntCode = XXXCode, CrntCode or the\n // prefix code is last code and the suffix char is\n // exactly the prefix of last code!\n this._suffix[this._runningCode - 2] = GifDecoder.getPrefixChar(\n this._prefix!,\n this._lastCode,\n this._clearCode\n );\n } else {\n this._suffix[this._runningCode - 2] = GifDecoder.getPrefixChar(\n this._prefix!,\n this._currentCode,\n this._clearCode\n );\n }\n }\n\n this._lastCode = this._currentCode;\n }\n }\n\n return true;\n }\n\n /**\n * The LZ decompression input routine:\n * This routine is responsible for the decompression of the bit stream from\n * 8 bits (bytes) packets, into the real codes.\n */\n private decompressInput(): number | undefined {\n // The image can't contain more than LZ_BITS per code.\n if (this._runningBits > GifDecoder._lzBits) {\n return undefined;\n }\n\n while (this._currentShiftState < this._runningBits) {\n // Needs to get more bytes from input stream for next code:\n const nextByte = this.bufferedInput()!;\n\n this._currentShiftDWord |= nextByte << this._currentShiftState;\n this._currentShiftState += 8;\n }\n\n const code: number =\n this._currentShiftDWord & GifDecoder._codeMasks[this._runningBits];\n\n this._currentShiftDWord >>= this._runningBits;\n this._currentShiftState -= this._runningBits;\n\n // If code cannot fit into RunningBits bits, must raise its size. Note\n // however that codes above 4095 are used for special signaling.\n // If we're using lzBits bits already and we're at the max code, just\n // keep using the table as it is, don't increment Private->RunningCode.\n if (\n this._runningCode < GifDecoder._lzMaxCode + 2 &&\n ++this._runningCode > this._maxCode1 &&\n this._runningBits < GifDecoder._lzBits\n ) {\n this._maxCode1 <<= 1;\n this._runningBits++;\n }\n\n return code;\n }\n\n /**\n * This routines read one gif data block at a time and buffers it internally\n * so that the decompression routine could access it.\n * The routine returns the next byte from its internal buffer (or read next\n * block in if buffer empty) and returns undefined on failure.\n */\n private bufferedInput(): number | undefined {\n let nextByte = 0;\n if (this._buffer![0] === 0) {\n // Needs to read the next buffer - this one is empty:\n this._buffer![0] = this._input!.readByte();\n\n // There shouldn't be any empty data blocks here as the LZW spec\n // says the LZW termination code should come first. Therefore we\n // shouldn't be inside this routine at that point.\n if (this._buffer![0] === 0) {\n return undefined;\n }\n\n const from = this._input!.readBytes(this._buffer![0]).toUint8Array();\n\n ArrayUtils.copyRange(from, 0, this._buffer![0], this._buffer!, 1);\n\n nextByte = this._buffer![1];\n // We use now the second place as last char read!\n this._buffer![1] = 2;\n this._buffer![0]--;\n } else {\n nextByte = this._buffer![this._buffer![1]++];\n this._buffer![0]--;\n }\n\n return nextByte;\n }\n\n private initDecode(): void {\n this._buffer = new Uint8Array(256);\n this._stack = new Uint8Array(GifDecoder._lzMaxCode);\n this._suffix = new Uint8Array(GifDecoder._lzMaxCode + 1);\n this._prefix = new Uint32Array(GifDecoder._lzMaxCode + 1);\n }\n\n private decodeImage(gifImage: GifImageDesc): MemoryImage | undefined {\n if (this._input === undefined || this._info === undefined) {\n return undefined;\n }\n\n if (this._buffer === undefined) {\n this.initDecode();\n }\n\n this._bitsPerPixel = this._input.readByte();\n this._clearCode = 1 << this._bitsPerPixel;\n this._eofCode = this._clearCode + 1;\n this._runningCode = this._eofCode + 1;\n this._runningBits = this._bitsPerPixel + 1;\n this._maxCode1 = 1 << this._runningBits;\n this._stackPtr = 0;\n this._lastCode = GifDecoder._noSuchCode;\n this._currentShiftState = 0;\n this._currentShiftDWord = 0;\n this._buffer![0] = 0;\n this._prefix!.fill(GifDecoder._noSuchCode, 0, this._prefix!.length);\n\n const width = gifImage.width;\n const height = gifImage.height;\n\n if (\n gifImage.x + width > this._info.width ||\n gifImage.y + height > this._info.height\n ) {\n return undefined;\n }\n\n const colorMap =\n gifImage.colorMap !== undefined\n ? gifImage.colorMap!\n : this._info.globalColorMap!;\n\n this._pixelCount = width * height;\n\n const image = new MemoryImage({\n width: width,\n height: height,\n numChannels: 1,\n palette: colorMap.getPalette(),\n });\n\n const line = new Uint8Array(width);\n\n if (gifImage.interlaced) {\n const row = gifImage.y;\n for (let i = 0, j = 0; i < 4; ++i) {\n for (\n let y = row + GifDecoder._interlacedOffset[i];\n y < row + height;\n y += GifDecoder._interlacedJump[i], ++j\n ) {\n if (!this.getLine(line)) {\n return image;\n }\n GifDecoder.updateImage(image, y, colorMap, line);\n }\n }\n } else {\n for (let y = 0; y < height; ++y) {\n if (!this.getLine(line)) {\n return image;\n }\n GifDecoder.updateImage(image, y, colorMap, line);\n }\n }\n\n return image;\n }\n\n /**\n * Is the given file a valid Gif image?\n */\n public isValidFile(bytes: Uint8Array): boolean {\n this._input = new InputBuffer({\n buffer: bytes,\n });\n return this.getInfo();\n }\n\n /**\n * Validate the file is a Gif image and get information about it.\n * If the file is not a valid Gif image, undefined is returned.\n */\n public startDecode(bytes: Uint8Array): GifInfo | undefined {\n this._input = new InputBuffer({\n buffer: bytes,\n });\n\n if (!this.getInfo()) {\n return undefined;\n }\n\n try {\n while (!this._input.isEOS) {\n const recordType = this._input.readByte();\n switch (recordType) {\n case GifDecoder._imageDescRecordType: {\n const gifImage = this.skipImage();\n if (gifImage === undefined) {\n return this._info;\n }\n this._info!.frames.push(gifImage);\n break;\n }\n case GifDecoder._extensionRecordType: {\n const extCode = this._input.readByte();\n if (extCode === GifDecoder._applicationExt) {\n this.readApplicationExt(this._input);\n } else if (extCode === GifDecoder._graphicControlExt) {\n this.readGraphicsControlExt(this._input);\n } else {\n this.skipRemainder();\n }\n break;\n }\n case GifDecoder._terminateRecordType: {\n return this._info;\n }\n default:\n break;\n }\n }\n } catch (error) {\n // ignore\n }\n\n return this._info;\n }\n\n public decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined {\n if (this.startDecode(bytes) === undefined || this._info === undefined) {\n return undefined;\n }\n\n if (this._info.numFrames === 1) {\n return this.decodeFrame(frame ?? 0);\n }\n\n let firstImage: MemoryImage | undefined = undefined;\n let lastImage: MemoryImage | undefined = undefined;\n for (let i = 0; i < this._info.numFrames; ++i) {\n const frame = this._info.frames[i];\n const image = this.decodeFrame(i);\n if (image === undefined) {\n return undefined;\n }\n\n // Convert to MS\n image.frameDuration = frame.duration * 10;\n\n if (firstImage === undefined || lastImage === undefined) {\n firstImage = image;\n lastImage = image;\n image.loopCount = this._repeat;\n continue;\n }\n\n if (\n image.width === lastImage.width &&\n image.height === lastImage.height &&\n frame.x === 0 &&\n frame.y === 0 &&\n frame.clearFrame\n ) {\n lastImage = image;\n firstImage.addFrame(lastImage);\n continue;\n }\n\n if (frame.clearFrame) {\n const colorMap =\n frame.colorMap !== undefined\n ? frame.colorMap\n : this._info.globalColorMap!;\n\n lastImage = new MemoryImage({\n width: lastImage.width,\n height: lastImage.height,\n numChannels: 1,\n palette: colorMap.getPalette(),\n });\n lastImage.clear(colorMap.getColor(this._info.backgroundColor!.r));\n } else {\n lastImage = MemoryImage.from(lastImage);\n }\n\n lastImage.frameDuration = image.frameDuration;\n\n for (const p of image) {\n if (p.a !== 0) {\n lastImage.setPixel(p.x + frame.x, p.y + frame.y, p);\n }\n }\n\n firstImage.addFrame(lastImage);\n }\n\n return firstImage;\n }\n\n public decodeFrame(frame: number): MemoryImage | undefined {\n if (this._input === undefined || this._info === undefined) {\n return undefined;\n }\n\n if (frame >= this._info.frames.length || frame < 0) {\n return undefined;\n }\n\n // this._frame = frame;\n const gifImage = this._info.frames[frame];\n this._input.offset = gifImage.inputPosition;\n\n return this.decodeImage(this._info.frames[frame]);\n }\n}\n", "/** @format */\n\nexport enum QuantizerType {\n octree,\n neural,\n}\n", "/** @format */\n\nimport { NeuralQuantizer } from '../image/neural-quantizer';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { StringUtils } from '../common/string-utils';\nimport { Encoder } from './encoder';\nimport { QuantizerType } from '../image/quantizer-type';\nimport { MemoryImage } from '../image/image';\nimport { OctreeQuantizer } from '../image/octree-quantizer';\nimport { Quantizer } from '../image/quantizer';\nimport { Filter } from '../filter/filter';\nimport { LibError } from '../error/lib-error';\nimport { DitherKernel } from '../filter/dither-kernel';\n\nexport interface GifEncoderInitOptions {\n delay?: number;\n repeat?: number;\n samplingFactor?: number;\n dither?: DitherKernel;\n ditherSerpentine?: boolean;\n}\n\nexport class GifEncoder implements Encoder {\n private static readonly _gif89Id = 'GIF89a';\n\n private static readonly _imageDescRecordType = 0x2c;\n private static readonly _extensionRecordType = 0x21;\n private static readonly _terminateRecordType = 0x3b;\n\n private static readonly _applicationExt = 0xff;\n private static readonly _graphicControlExt = 0xf9;\n\n private static readonly _eof = -1;\n private static readonly _bits = 12;\n // 80% occupancy\n private static readonly _hSize = 5003;\n private static readonly _masks = [\n 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,\n 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff,\n ];\n\n private _delay: number;\n\n private _repeat: number;\n\n private _numColors: number;\n\n private _quantizerType: QuantizerType;\n\n private _samplingFactor: number;\n\n private _lastImage?: MemoryImage;\n\n private _lastImageDuration?: number;\n\n private _lastColorMap?: Quantizer;\n\n private _width!: number;\n\n private _height!: number;\n\n private _encodedFrames: number;\n\n private _curAccum = 0;\n\n private _curBits = 0;\n\n private _nBits = 0;\n\n private _initBits = 0;\n\n private _eofCode = 0;\n\n private _maxCode = 0;\n\n private _clearCode = 0;\n\n private _freeEnt = 0;\n\n private _clearFlag = false;\n\n private _block!: Uint8Array;\n\n private _blockSize = 0;\n\n private _outputBuffer?: OutputBuffer;\n\n private _dither: DitherKernel;\n\n private _ditherSerpentine: boolean;\n\n /**\n * Does this encoder support animation?\n */\n private readonly _supportsAnimation = true;\n public get supportsAnimation(): boolean {\n return this._supportsAnimation;\n }\n\n constructor(opt?: GifEncoderInitOptions) {\n this._delay = opt?.delay ?? 80;\n this._repeat = opt?.repeat ?? 0;\n this._numColors = 256;\n this._quantizerType = QuantizerType.neural;\n this._samplingFactor = opt?.samplingFactor ?? 10;\n this._dither = opt?.dither ?? DitherKernel.floydSteinberg;\n this._ditherSerpentine = opt?.ditherSerpentine ?? false;\n this._encodedFrames = 0;\n }\n\n private addImage(image: MemoryImage, width: number, height: number): void {\n if (!image.hasPalette) {\n throw new LibError('GIF can only encode palette images.');\n }\n\n const palette = image.palette!;\n const numColors = palette.numColors;\n\n const out = this._outputBuffer!;\n\n // Image desc\n out.writeByte(GifEncoder._imageDescRecordType);\n // image position x,y = 0,0\n out.writeUint16(0);\n out.writeUint16(0);\n // image size\n out.writeUint16(width);\n out.writeUint16(height);\n\n const paletteBytes = palette.toUint8Array();\n\n // Local Color Map\n // (0x80: Use LCM, 0x07: Palette Size (7 = 8-bit))\n out.writeByte(0x87);\n\n const numChannels = palette.numChannels;\n if (numChannels === 3) {\n out.writeBytes(paletteBytes);\n } else if (numChannels === 4) {\n for (let i = 0, pi = 0; i < numColors; ++i, pi += 4) {\n out.writeByte(paletteBytes[pi]);\n out.writeByte(paletteBytes[pi + 1]);\n out.writeByte(paletteBytes[pi + 2]);\n }\n } else if (numChannels === 1 || numChannels === 2) {\n for (let i = 0, pi = 0; i < numColors; ++i, pi += numChannels) {\n const g = paletteBytes[pi];\n out.writeByte(g);\n out.writeByte(g);\n out.writeByte(g);\n }\n }\n\n for (let i = numColors; i < 256; ++i) {\n out.writeByte(0);\n out.writeByte(0);\n out.writeByte(0);\n }\n\n this.encodeLZW(image);\n }\n\n private encodeLZW(image: MemoryImage): void {\n this._curAccum = 0;\n this._curBits = 0;\n this._blockSize = 0;\n this._block = new Uint8Array(256);\n\n const initCodeSize = 8;\n this._outputBuffer!.writeByte(initCodeSize);\n\n const hTab = new Int32Array(GifEncoder._hSize);\n const codeTab = new Int32Array(GifEncoder._hSize);\n const pIter = image[Symbol.iterator]();\n let pIterRes = pIter.next();\n\n this._initBits = initCodeSize + 1;\n this._nBits = this._initBits;\n this._maxCode = (1 << this._nBits) - 1;\n this._clearCode = 1 << (this._initBits - 1);\n this._eofCode = this._clearCode + 1;\n this._clearFlag = false;\n this._freeEnt = this._clearCode + 2;\n let pFinished = false;\n\n const nextPixel = (): number => {\n if (pFinished) {\n return GifEncoder._eof;\n }\n const r = Math.trunc(pIterRes.value.index);\n if (((pIterRes = pIter.next()), pIterRes.done)) {\n pFinished = true;\n }\n return r;\n };\n\n let ent = nextPixel();\n\n let hShift = 0;\n for (let fCode = GifEncoder._hSize; fCode < 65536; fCode *= 2) {\n hShift++;\n }\n hShift = 8 - hShift;\n\n const hSizeReg = GifEncoder._hSize;\n for (let i = 0; i < hSizeReg; ++i) {\n hTab[i] = -1;\n }\n\n this.output(this._clearCode);\n\n let outerLoop = true;\n while (outerLoop) {\n outerLoop = false;\n\n let c = nextPixel();\n while (c !== GifEncoder._eof) {\n const fcode = (c << GifEncoder._bits) + ent;\n // xor hashing\n let i = (c << hShift) ^ ent;\n\n if (hTab[i] === fcode) {\n ent = codeTab[i];\n c = nextPixel();\n continue;\n } else if (hTab[i] >= 0) {\n // non-empty slot\n // secondary hash (after G. Knott)\n let disp = hSizeReg - i;\n if (i === 0) {\n disp = 1;\n }\n do {\n if ((i -= disp) < 0) {\n i += hSizeReg;\n }\n\n if (hTab[i] === fcode) {\n ent = codeTab[i];\n outerLoop = true;\n break;\n }\n } while (hTab[i] >= 0);\n if (outerLoop) {\n break;\n }\n }\n\n this.output(ent);\n ent = c;\n\n if (this._freeEnt < 1 << GifEncoder._bits) {\n // code -> hashtable\n codeTab[i] = this._freeEnt++;\n hTab[i] = fcode;\n } else {\n for (let i = 0; i < GifEncoder._hSize; ++i) {\n hTab[i] = -1;\n }\n this._freeEnt = this._clearCode + 2;\n this._clearFlag = true;\n this.output(this._clearCode);\n }\n\n c = nextPixel();\n }\n }\n\n this.output(ent);\n this.output(this._eofCode);\n\n this._outputBuffer!.writeByte(0);\n }\n\n private output(code: number | undefined): void {\n this._curAccum &= GifEncoder._masks[this._curBits];\n\n if (this._curBits > 0) {\n this._curAccum |= code! << this._curBits;\n } else {\n this._curAccum = code!;\n }\n\n this._curBits += this._nBits;\n\n while (this._curBits >= 8) {\n this.addToBlock(this._curAccum & 0xff);\n this._curAccum >>= 8;\n this._curBits -= 8;\n }\n\n // If the next entry is going to be too big for the code size,\n // then increase it, if possible.\n if (this._freeEnt > this._maxCode || this._clearFlag) {\n if (this._clearFlag) {\n this._nBits = this._initBits;\n this._maxCode = (1 << this._nBits) - 1;\n this._clearFlag = false;\n } else {\n ++this._nBits;\n if (this._nBits === GifEncoder._bits) {\n this._maxCode = 1 << GifEncoder._bits;\n } else {\n this._maxCode = (1 << this._nBits) - 1;\n }\n }\n }\n\n if (code === this._eofCode) {\n // At EOF, write the rest of the buffer.\n while (this._curBits > 0) {\n this.addToBlock(this._curAccum & 0xff);\n this._curAccum >>= 8;\n this._curBits -= 8;\n }\n this.writeBlock();\n }\n }\n\n private writeBlock(): void {\n if (this._blockSize > 0) {\n this._outputBuffer!.writeByte(this._blockSize);\n this._outputBuffer!.writeBytes(this._block, this._blockSize);\n this._blockSize = 0;\n }\n }\n\n private addToBlock(c: number): void {\n this._block[this._blockSize++] = c;\n if (this._blockSize >= 254) {\n this.writeBlock();\n }\n }\n\n private writeApplicationExt(): void {\n this._outputBuffer!.writeByte(GifEncoder._extensionRecordType);\n this._outputBuffer!.writeByte(GifEncoder._applicationExt);\n // Data block size\n this._outputBuffer!.writeByte(11);\n const appCodeUnits = StringUtils.getCodePoints('NETSCAPE2.0');\n // App identifier\n this._outputBuffer!.writeBytes(appCodeUnits);\n this._outputBuffer!.writeBytes(new Uint8Array([0x03, 0x01]));\n // Loop count\n this._outputBuffer!.writeUint16(this._repeat);\n // Block terminator\n this._outputBuffer!.writeByte(0);\n }\n\n private writeGraphicsCtrlExt(image: MemoryImage): void {\n this._outputBuffer!.writeByte(GifEncoder._extensionRecordType);\n this._outputBuffer!.writeByte(GifEncoder._graphicControlExt);\n // data block size\n this._outputBuffer!.writeByte(4);\n\n let transparentIndex = 0;\n let hasTransparency = 0;\n const palette = image.palette!;\n const nc = palette.numChannels;\n const pa = nc - 1;\n if (nc === 4 || nc === 2) {\n const p = palette.toUint8Array();\n const l = palette.numColors;\n for (let i = 0, pi = pa; i < l; ++i, pi += nc) {\n const a = p[pi];\n if (a === 0) {\n hasTransparency = 1;\n transparentIndex = i;\n break;\n }\n }\n }\n\n // dispose: 0 = no action, 2 = clear\n const dispose = 2;\n\n // 1:3 reserved\n const fields =\n 0 |\n // 4:6 disposal\n (dispose << 2) |\n // 7 user input - 0 = none\n 0 |\n // 8 transparency flag\n hasTransparency;\n\n // packed fields\n this._outputBuffer!.writeByte(fields);\n\n // delay x 1/100 sec\n this._outputBuffer!.writeUint16(this._lastImageDuration ?? this._delay);\n // transparent color index\n this._outputBuffer!.writeByte(transparentIndex);\n // block terminator\n this._outputBuffer!.writeByte(0);\n }\n\n // GIF header and Logical Screen Descriptor\n private writeHeader(width: number, height: number): void {\n const idCodeUnits = StringUtils.getCodePoints(GifEncoder._gif89Id);\n this._outputBuffer!.writeBytes(idCodeUnits);\n this._outputBuffer!.writeUint16(width);\n this._outputBuffer!.writeUint16(height);\n // global color map parameters (not being used).\n this._outputBuffer!.writeByte(0);\n // Background color index.\n this._outputBuffer!.writeByte(0);\n // Aspect\n this._outputBuffer!.writeByte(0);\n }\n\n /**\n * Encode the images that were added with **addFrame**.\n * After this has been called (returning the finishes GIF),\n * calling **addFrame** for a new animation or image is safe again.\n *\n * **addFrame** will not encode the first image passed and after that\n * always encode the previous image. Hence, the last image needs to be\n * encoded here.\n */\n private finish(): Uint8Array | undefined {\n let bytes: Uint8Array | undefined = undefined;\n if (this._outputBuffer === undefined) {\n return bytes;\n }\n\n if (this._encodedFrames === 0) {\n this.writeHeader(this._width, this._height);\n this.writeApplicationExt();\n } else {\n this.writeGraphicsCtrlExt(this._lastImage!);\n }\n\n this.addImage(this._lastImage!, this._width, this._height);\n\n this._outputBuffer.writeByte(GifEncoder._terminateRecordType);\n\n this._lastImage = undefined;\n this._lastColorMap = undefined;\n this._encodedFrames = 0;\n\n bytes = this._outputBuffer.getBytes();\n this._outputBuffer = undefined;\n return bytes;\n }\n\n /**\n * This adds the frame passed to **image**.\n * After the last frame has been added, **finish** is required to be called.\n * Optional frame **duration** is in 1/100 sec.\n * */\n public addFrame(image: MemoryImage, duration?: number): void {\n if (this._outputBuffer === undefined) {\n this._outputBuffer = new OutputBuffer();\n\n if (!image.hasPalette) {\n if (this._quantizerType === QuantizerType.neural) {\n this._lastColorMap = new NeuralQuantizer(\n image,\n this._numColors,\n this._samplingFactor\n );\n } else {\n this._lastColorMap = new OctreeQuantizer(image, this._numColors);\n }\n\n this._lastImage = Filter.ditherImage({\n image: image,\n quantizer: this._lastColorMap,\n kernel: this._dither,\n serpentine: this._ditherSerpentine,\n });\n } else {\n this._lastImage = image;\n }\n\n this._lastImageDuration = duration;\n\n this._width = image.width;\n this._height = image.height;\n return;\n }\n\n if (this._encodedFrames === 0) {\n this.writeHeader(this._width, this._height);\n this.writeApplicationExt();\n }\n\n this.writeGraphicsCtrlExt(this._lastImage!);\n\n this.addImage(this._lastImage!, this._width, this._height);\n this._encodedFrames++;\n\n if (!image.hasPalette) {\n if (this._quantizerType === QuantizerType.neural) {\n this._lastColorMap = new NeuralQuantizer(\n image,\n this._numColors,\n this._samplingFactor\n );\n } else {\n this._lastColorMap = new OctreeQuantizer(image, this._numColors);\n }\n\n this._lastImage = Filter.ditherImage({\n image: image,\n quantizer: this._lastColorMap!,\n kernel: this._dither,\n serpentine: this._ditherSerpentine,\n });\n } else {\n this._lastImage = image;\n }\n\n this._lastImageDuration = duration;\n }\n\n /**\n * Encode a single frame image.\n */\n public encode(image: MemoryImage, singleFrame = false): Uint8Array {\n if (!image.hasAnimation || singleFrame) {\n this.addFrame(image);\n return this.finish()!;\n }\n\n this._repeat = image.loopCount;\n for (const f of image.frames) {\n // Convert ms to 1/100 sec.\n this.addFrame(f, Math.trunc(f.frameDuration / 10));\n }\n return this.finish()!;\n }\n}\n", "/** @format */\n\nimport { BmpInfo } from '../bmp/bmp-info';\n\nexport class IcoBmpInfo extends BmpInfo {\n public get height(): number {\n return Math.floor(this._height / 2);\n }\n\n public get ignoreAlphaChannel(): boolean {\n return this.headerSize === 40 && this.bitsPerPixel === 32\n ? false\n : super.ignoreAlphaChannel;\n }\n}\n", "/** @format */\n\nexport interface IcoInfoImageInitOptions {\n width: number;\n height: number;\n colorPalette: number;\n bytesSize: number;\n bytesOffset: number;\n colorPlanes: number;\n bitsPerPixel: number;\n}\n\nexport class IcoInfoImage {\n private readonly _width: number;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number;\n public get height(): number {\n return this._height;\n }\n\n private readonly _colorPalette: number;\n public get colorPalette(): number {\n return this._colorPalette;\n }\n\n private readonly _bytesSize: number;\n public get bytesSize(): number {\n return this._bytesSize;\n }\n\n private readonly _bytesOffset: number;\n public get bytesOffset(): number {\n return this._bytesOffset;\n }\n\n private readonly _colorPlanes: number;\n public get colorPlanes(): number {\n return this._colorPlanes;\n }\n\n private readonly _bitsPerPixel: number;\n public get bitsPerPixel(): number {\n return this._bitsPerPixel;\n }\n\n constructor(opt: IcoInfoImageInitOptions) {\n this._width = opt.width;\n this._height = opt.height;\n this._colorPalette = opt.colorPalette;\n this._bytesSize = opt.bytesSize;\n this._bytesOffset = opt.bytesOffset;\n this._colorPlanes = opt.colorPlanes;\n this._bitsPerPixel = opt.bitsPerPixel;\n }\n}\n", "/** @format */\n\nexport enum IcoType {\n invalid,\n ico,\n cur,\n}\n\nexport const IcoTypeLength = 3;\n", "/** @format */\n\nimport { Color } from '../../color/color';\nimport { ArrayUtils } from '../../common/array-utils';\nimport { InputBuffer } from '../../common/input-buffer';\nimport { DecodeInfo } from '../decode-info';\nimport { IcoInfoImage } from './ico-info-image';\nimport { IcoType, IcoTypeLength } from './ico-type';\n\nexport class IcoInfo implements DecodeInfo {\n private _width = 0;\n public get width(): number {\n return this._width;\n }\n\n private _height = 0;\n public get height(): number {\n return this._height;\n }\n\n private readonly _type: IcoType;\n public get type(): IcoType {\n return this._type;\n }\n\n private readonly _numFrames: number;\n public get numFrames(): number {\n return this._numFrames;\n }\n\n private _backgroundColor: Color | undefined = undefined;\n public get backgroundColor(): Color | undefined {\n return this._backgroundColor;\n }\n\n private readonly _images: IcoInfoImage[];\n public get images(): IcoInfoImage[] {\n return this._images;\n }\n\n constructor(type: number, numFrames: number, images: IcoInfoImage[]) {\n this._type = type;\n this._numFrames = numFrames;\n this._images = images;\n }\n\n public static read(input: InputBuffer): IcoInfo | undefined {\n if (input.readUint16() !== 0) {\n return undefined;\n }\n const t = input.readUint16();\n if (t >= IcoTypeLength) {\n return undefined;\n }\n const type = t as IcoType;\n if (type === IcoType.cur) {\n // CUR format not yet supported.\n return undefined;\n }\n\n const imageCount = input.readUint16();\n\n const images = ArrayUtils.generate(\n imageCount,\n (_) =>\n new IcoInfoImage({\n width: input.readByte(),\n height: input.readByte(),\n colorPalette: input.readByte(),\n // ignore 1 byte\n colorPlanes: (input.skip(1), input).readUint16(),\n bitsPerPixel: input.readUint16(),\n bytesSize: input.readUint32(),\n bytesOffset: input.readUint32(),\n })\n );\n\n return new IcoInfo(type, imageCount, images);\n }\n}\n", "/** @format */\n\nexport enum PngFilterType {\n none,\n sub,\n up,\n average,\n paeth,\n}\n", "/** @format */\n\nexport enum PngColorType {\n grayscale = 0,\n rgb = 2,\n indexed = 3,\n grayscaleAlpha = 4,\n rgba = 6,\n}\n", "/** @format */\n\nimport { deflate } from 'uzip';\nimport { Crc32 } from '../common/crc32';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { StringUtils } from '../common/string-utils';\nimport { CompressionLevel } from '../common/typings';\nimport { Encoder } from './encoder';\nimport { Quantizer } from '../image/quantizer';\nimport { PngFilterType } from './png/png-filter-type';\nimport { MemoryImage } from '../image/image';\nimport { Format } from '../color/format';\nimport { NeuralQuantizer } from '../image/neural-quantizer';\nimport { PngColorType } from './png/png-color-type';\nimport { Palette } from '../image/palette';\nimport { IccProfile } from '../image/icc-profile';\n\nexport interface PngEncoderInitOptions {\n filter?: PngFilterType;\n level?: CompressionLevel;\n}\n\n/**\n * Encode an image to the PNG format.\n */\nexport class PngEncoder implements Encoder {\n private _globalQuantizer: Quantizer | undefined;\n\n private _filter: PngFilterType;\n\n private _level: number;\n\n private _repeat = 0;\n\n private _frames = 0;\n\n private _sequenceNumber = 0;\n\n private _isAnimated = false;\n\n private _output: OutputBuffer | undefined;\n\n /**\n * Does this encoder support animation?\n */\n private _supportsAnimation = true;\n public get supportsAnimation() {\n return this._supportsAnimation;\n }\n\n constructor(opt?: PngEncoderInitOptions) {\n this._filter = opt?.filter ?? PngFilterType.paeth;\n this._level = opt?.level ?? 6;\n }\n\n /**\n * Return the CRC of the bytes\n */\n private static crc(type: string, bytes: Uint8Array): number {\n const typeCodeUnits = StringUtils.getCodePoints(type);\n const crc = Crc32.getChecksum({\n buffer: typeCodeUnits,\n });\n return Crc32.getChecksum({\n buffer: bytes,\n baseCrc: crc,\n });\n }\n\n private static writeChunk(\n out: OutputBuffer,\n type: string,\n chunk: Uint8Array\n ): void {\n out.writeUint32(chunk.length);\n const typeCodeUnits = StringUtils.getCodePoints(type);\n out.writeBytes(typeCodeUnits);\n out.writeBytes(chunk);\n const crc = PngEncoder.crc(type, chunk);\n out.writeUint32(crc);\n }\n\n private static write(\n bpc: number,\n row: Uint8Array,\n ri: number,\n out: Uint8Array,\n oi: number\n ): number {\n let _bpc = bpc;\n let _oi = oi;\n _bpc--;\n while (_bpc >= 0) {\n out[_oi++] = row[ri + _bpc];\n _bpc--;\n }\n return _oi;\n }\n\n private static filterSub(\n row: Uint8Array,\n bpc: number,\n bpp: number,\n out: Uint8Array,\n oi: number\n ): number {\n let _oi = oi;\n out[_oi++] = PngFilterType.sub;\n for (let x = 0; x < bpp; x += bpc) {\n _oi = PngEncoder.write(bpc, row, x, out, _oi);\n }\n const l = row.length;\n for (let x = bpp; x < l; x += bpc) {\n for (let c = 0, c2 = bpc - 1; c < bpc; ++c, --c2) {\n out[_oi++] = (row[x + c2] - row[x + c2 - bpp]) & 0xff;\n }\n }\n return _oi;\n }\n\n private static filterUp(\n row: Uint8Array,\n bpc: number,\n out: Uint8Array,\n oi: number,\n prevRow?: Uint8Array\n ): number {\n let _oi = oi;\n out[_oi++] = PngFilterType.up;\n const l = row.length;\n for (let x = 0; x < l; x += bpc) {\n for (let c = 0, c2 = bpc - 1; c < bpc; ++c, --c2) {\n const b = prevRow !== undefined ? prevRow[x + c2] : 0;\n out[_oi++] = (row[x + c2] - b) & 0xff;\n }\n }\n return _oi;\n }\n\n private static filterAverage(\n row: Uint8Array,\n bpc: number,\n bpp: number,\n out: Uint8Array,\n oi: number,\n prevRow?: Uint8Array\n ): number {\n let _oi = oi;\n out[_oi++] = PngFilterType.average;\n const l = row.length;\n for (let x = 0; x < l; x += bpc) {\n for (let c = 0, c2 = bpc - 1; c < bpc; ++c, --c2) {\n const x2 = x + c2;\n const p1 = x2 < bpp ? 0 : row[x2 - bpp];\n const p2 = prevRow === undefined ? 0 : prevRow[x2];\n const p3 = row[x2];\n out[_oi++] = p3 - ((p1 + p2) >> 1);\n }\n }\n return _oi;\n }\n\n private static paethPredictor(a: number, b: number, c: number): number {\n const p = a + b - c;\n const pa = p > a ? p - a : a - p;\n const pb = p > b ? p - b : b - p;\n const pc = p > c ? p - c : c - p;\n if (pa <= pb && pa <= pc) {\n return a;\n } else if (pb <= pc) {\n return b;\n }\n return c;\n }\n\n private static filterPaeth(\n row: Uint8Array,\n bpc: number,\n bpp: number,\n out: Uint8Array,\n oi: number,\n prevRow?: Uint8Array\n ): number {\n let _oi = oi;\n out[_oi++] = PngFilterType.paeth;\n const l = row.length;\n for (let x = 0; x < l; x += bpc) {\n for (let c = 0, c2 = bpc - 1; c < bpc; ++c, --c2) {\n const x2 = x + c2;\n const p0 = x2 < bpp ? 0 : row[x2 - bpp];\n const p1 = prevRow === undefined ? 0 : prevRow[x2];\n const p2 = x2 < bpp || prevRow === undefined ? 0 : prevRow[x2 - bpp];\n const p = row[x2];\n const pi = PngEncoder.paethPredictor(p0, p1, p2);\n out[_oi++] = (p - pi) & 0xff;\n }\n }\n return _oi;\n }\n\n private static filterNone(\n rowBytes: Uint8Array,\n bpc: number,\n out: Uint8Array,\n oi: number\n ): number {\n let _oi = oi;\n out[_oi++] = PngFilterType.none;\n if (bpc === 1) {\n const l = rowBytes.length;\n for (let i = 0; i < l; ++i) {\n out[_oi++] = rowBytes[i];\n }\n } else {\n const l = rowBytes.length;\n for (let i = 0; i < l; i += bpc) {\n _oi = PngEncoder.write(bpc, rowBytes, i, out, _oi);\n }\n }\n return _oi;\n }\n\n private static numChannels(image: MemoryImage): number {\n return image.hasPalette ? 1 : image.numChannels;\n }\n\n private writeHeader(image: MemoryImage): void {\n // PNG file signature\n this._output!.writeBytes(\n new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])\n );\n\n // IHDR chunk\n const chunk = new OutputBuffer({\n bigEndian: true,\n });\n\n // width\n chunk.writeUint32(image.width);\n // height\n chunk.writeUint32(image.height);\n // bit depth\n chunk.writeByte(image.bitsPerChannel);\n chunk.writeByte(\n image.hasPalette\n ? PngColorType.indexed\n : image.numChannels === 1\n ? PngColorType.grayscale\n : image.numChannels === 2\n ? PngColorType.grayscaleAlpha\n : image.numChannels === 3\n ? PngColorType.rgb\n : PngColorType.rgba\n );\n // compression method: 0:deflate\n chunk.writeByte(0);\n // filter method: 0:adaptive\n chunk.writeByte(0);\n // interlace method: 0:no interlace\n chunk.writeByte(0);\n PngEncoder.writeChunk(this._output!, 'IHDR', chunk.getBytes());\n }\n\n private writeICCPChunk(iccp: IccProfile): void {\n const chunk = new OutputBuffer({\n bigEndian: true,\n });\n\n // name\n const nameCodeUnits = StringUtils.getCodePoints(iccp.name);\n chunk.writeBytes(nameCodeUnits);\n chunk.writeByte(0);\n\n // compression (0 - deflate)\n chunk.writeByte(0);\n\n // profile data\n chunk.writeBytes(iccp.compressed());\n\n PngEncoder.writeChunk(this._output!, 'iCCP', chunk.getBytes());\n }\n\n private writeAnimationControlChunk(): void {\n const chunk = new OutputBuffer({\n bigEndian: true,\n });\n // Number of frames\n chunk.writeUint32(this._frames);\n // Loop count\n chunk.writeUint32(this._repeat);\n PngEncoder.writeChunk(this._output!, 'acTL', chunk.getBytes());\n }\n\n private writeFrameControlChunk(image: MemoryImage): void {\n const chunk = new OutputBuffer({\n bigEndian: true,\n });\n\n chunk.writeUint32(this._sequenceNumber);\n chunk.writeUint32(image.width);\n chunk.writeUint32(image.height);\n // xOffset\n chunk.writeUint32(0);\n // yOffset\n chunk.writeUint32(0);\n chunk.writeUint16(image.frameDuration);\n // delay denominator\n chunk.writeUint16(1000);\n // dispose method 0: APNG_DISPOSE_OP_NONE\n chunk.writeByte(1);\n // blend method 0: APNG_BLEND_OP_SOURCE\n chunk.writeByte(0);\n PngEncoder.writeChunk(this._output!, 'fcTL', chunk.getBytes());\n }\n\n private writePalette(palette: Palette): void {\n if (\n palette.format === Format.uint8 &&\n palette.numChannels === 3 &&\n palette.numColors === 256\n ) {\n PngEncoder.writeChunk(this._output!, 'PLTE', palette.toUint8Array());\n } else {\n const chunk = new OutputBuffer({\n size: palette.numColors * 3,\n bigEndian: true,\n });\n const nc = palette.numColors;\n for (let i = 0; i < nc; ++i) {\n chunk.writeByte(Math.trunc(palette.getRed(i)));\n chunk.writeByte(Math.trunc(palette.getGreen(i)));\n chunk.writeByte(Math.trunc(palette.getBlue(i)));\n }\n PngEncoder.writeChunk(this._output!, 'PLTE', chunk.getBytes());\n }\n\n if (palette.numChannels === 4) {\n const chunk = new OutputBuffer({\n size: palette.numColors,\n bigEndian: true,\n });\n const nc = palette.numColors;\n for (let i = 0; i < nc; ++i) {\n const a = Math.trunc(palette.getAlpha(i));\n chunk.writeByte(a);\n }\n PngEncoder.writeChunk(this._output!, 'tRNS', chunk.getBytes());\n }\n }\n\n private writeTextChunk(keyword: string, text: string): void {\n const chunk = new OutputBuffer({\n bigEndian: true,\n });\n const keywordBytes = StringUtils.getCodePoints(keyword);\n const textBytes = StringUtils.getCodePoints(text);\n chunk.writeBytes(keywordBytes);\n chunk.writeByte(0);\n chunk.writeBytes(textBytes);\n PngEncoder.writeChunk(this._output!, 'tEXt', chunk.getBytes());\n }\n\n private filter(image: MemoryImage, out: Uint8Array): void {\n let oi = 0;\n const filter = image.hasPalette ? PngFilterType.none : this._filter;\n const buffer = image.buffer;\n const rowStride = image.data!.rowStride;\n const nc = PngEncoder.numChannels(image);\n const bpp = (nc * image.bitsPerChannel + 7) >> 3;\n const bpc = (image.bitsPerChannel + 7) >> 3;\n\n let rowOffset = 0;\n let prevRow: Uint8Array | undefined = undefined;\n for (let y = 0; y < image.height; ++y) {\n const rowBytes =\n buffer !== undefined\n ? new Uint8Array(buffer, rowOffset, rowStride)\n : new Uint8Array();\n rowOffset += rowStride;\n\n switch (filter) {\n case PngFilterType.sub:\n oi = PngEncoder.filterSub(rowBytes, bpc, bpp, out, oi);\n break;\n case PngFilterType.up:\n oi = PngEncoder.filterUp(rowBytes, bpc, out, oi, prevRow);\n break;\n case PngFilterType.average:\n oi = PngEncoder.filterAverage(rowBytes, bpc, bpp, out, oi, prevRow);\n break;\n case PngFilterType.paeth:\n oi = PngEncoder.filterPaeth(rowBytes, bpc, bpp, out, oi, prevRow);\n break;\n default:\n oi = PngEncoder.filterNone(rowBytes, bpc, out, oi);\n break;\n }\n prevRow = rowBytes;\n }\n }\n\n public addFrame(image: MemoryImage): void {\n let _image = image;\n // PNG can't encode HDR formats, and can only encode formats with fewer\n // than 8 bits if they have a palette. In the case of incompatible\n // formats, convert them to uint8.\n if (\n (_image.isHdrFormat && _image.format !== Format.uint16) ||\n (_image.bitsPerChannel < 8 &&\n !_image.hasPalette &&\n _image.numChannels > 1)\n ) {\n _image = _image.convert({\n format: Format.uint8,\n });\n }\n\n if (this._output === undefined) {\n this._output = new OutputBuffer({\n bigEndian: true,\n });\n\n this.writeHeader(_image);\n\n if (_image.iccProfile !== undefined) {\n this.writeICCPChunk(_image.iccProfile);\n }\n\n if (_image.hasPalette) {\n if (this._globalQuantizer !== undefined) {\n this.writePalette(this._globalQuantizer!.palette);\n } else {\n this.writePalette(_image.palette!);\n }\n }\n\n if (this._isAnimated) {\n this.writeAnimationControlChunk();\n }\n }\n\n const nc = PngEncoder.numChannels(_image);\n\n const channelBytes = _image.format === Format.uint16 ? 2 : 1;\n\n // Include room for the filter bytes (1 byte per row).\n const filteredImage = new Uint8Array(\n _image.width * _image.height * nc * channelBytes + image.height\n );\n\n this.filter(_image, filteredImage);\n\n const compressed = deflate(filteredImage, {\n level: this._level,\n });\n\n if (_image.textData !== undefined) {\n for (const [key, value] of _image.textData) {\n this.writeTextChunk(key, value);\n }\n }\n\n if (this._isAnimated) {\n this.writeFrameControlChunk(_image);\n this._sequenceNumber++;\n }\n\n if (this._sequenceNumber <= 1) {\n PngEncoder.writeChunk(this._output, 'IDAT', compressed);\n } else {\n // fdAT chunk\n const fdat = new OutputBuffer({\n bigEndian: true,\n });\n fdat.writeUint32(this._sequenceNumber);\n fdat.writeBytes(compressed);\n PngEncoder.writeChunk(this._output, 'fdAT', fdat.getBytes());\n\n this._sequenceNumber++;\n }\n }\n\n public finish(): Uint8Array | undefined {\n let bytes: Uint8Array | undefined = undefined;\n if (this._output === undefined) {\n return bytes;\n }\n\n PngEncoder.writeChunk(this._output, 'IEND', new Uint8Array());\n\n this._sequenceNumber = 0;\n\n bytes = this._output.getBytes();\n this._output = undefined;\n return bytes;\n }\n\n /**\n * Encode **image** to the PNG format.\n */\n public encode(image: MemoryImage, singleFrame = false): Uint8Array {\n if (!image.hasAnimation || singleFrame) {\n this._isAnimated = false;\n this.addFrame(image);\n } else {\n this._isAnimated = true;\n this._frames = image.frames.length;\n this._repeat = image.loopCount;\n\n if (image.hasPalette) {\n const q = new NeuralQuantizer(image);\n this._globalQuantizer = q;\n for (const frame of image.frames) {\n if (frame !== image) {\n q.addImage(frame);\n }\n }\n }\n\n for (const frame of image.frames) {\n if (this._globalQuantizer !== undefined) {\n const newImage = this._globalQuantizer.getIndexImage(frame);\n this.addFrame(newImage);\n } else {\n this.addFrame(frame);\n }\n }\n }\n return this.finish()!;\n }\n}\n", "/** @format */\n\nimport { OutputBuffer } from '../common/output-buffer';\nimport { LibError } from '../error/lib-error';\nimport { MemoryImage } from '../image/image';\nimport { Encoder } from './encoder';\nimport { PngEncoder } from './png-encoder';\n\nexport abstract class WinEncoder implements Encoder {\n protected _type = 0;\n public get type(): number {\n return this._type;\n }\n\n private _supportsAnimation = true;\n get supportsAnimation(): boolean {\n return this._supportsAnimation;\n }\n\n protected colorPlanesOrXHotSpot(_index: number): number {\n return 0;\n }\n\n protected bitsPerPixelOrYHotSpot(_index: number): number {\n return 0;\n }\n\n public encode(image: MemoryImage, singleFrame = false): Uint8Array {\n if (image.hasAnimation && !singleFrame) {\n return this.encodeImages(image.frames);\n } else {\n return this.encodeImages([image]);\n }\n }\n\n public encodeImages(images: MemoryImage[]): Uint8Array {\n const count = images.length;\n\n const out = new OutputBuffer();\n\n // header\n out.writeUint16(0);\n // type: ICO => 1; CUR => 2\n out.writeUint16(this._type);\n out.writeUint16(count);\n\n // file header with image directory byte size\n let offset = 6 + count * 16;\n\n const imageDataList: Uint8Array[] = [];\n\n let i = 0;\n for (const img of images) {\n if (img.width > 256 || img.height > 256) {\n throw new LibError('ICO and CUR support only sizes until 256');\n }\n\n // image width in pixels\n out.writeByte(img.width);\n // image height in pixels\n out.writeByte(img.height);\n // Color count, should be 0 if more than 256 colors\n out.writeByte(0);\n // Reserved\n out.writeByte(0);\n out.writeUint16(this.colorPlanesOrXHotSpot(i));\n out.writeUint16(this.bitsPerPixelOrYHotSpot(i));\n\n // Use png instead of bmp encoded data, it's supported since Windows Vista\n const data: Uint8Array = new PngEncoder().encode(img);\n\n // size of the image's data in bytes\n out.writeUint32(data.length);\n // offset of data from the beginning of the file\n out.writeUint32(offset);\n\n // add the size of bytes to get the new begin of the next image\n offset += data.length;\n i++;\n imageDataList.push(data);\n }\n\n for (const imageData of imageDataList) {\n out.writeBytes(imageData);\n }\n\n return out.getBytes();\n }\n}\n", "/** @format */\n\nimport { WinEncoder } from './win-encoder';\n\nexport class IcoEncoder extends WinEncoder {\n protected _type = 1;\n\n protected colorPlanesOrXHotSpot(_index: number): number {\n return 0;\n }\n\n protected bitsPerPixelOrYHotSpot(_index: number): number {\n return 32;\n }\n}\n", "/** @format */\n\nexport class JpegComponentData {\n private _hSamples: number;\n public get hSamples(): number {\n return this._hSamples;\n }\n\n private _maxHSamples: number;\n public get maxHSamples(): number {\n return this._maxHSamples;\n }\n\n private _vSamples: number;\n public get vSamples(): number {\n return this._vSamples;\n }\n\n private _maxVSamples: number;\n public get maxVSamples(): number {\n return this._maxVSamples;\n }\n\n private _lines: Array;\n public get lines(): Array {\n return this._lines;\n }\n\n private _hScaleShift: number;\n public get hScaleShift(): number {\n return this._hScaleShift;\n }\n\n private _vScaleShift: number;\n public get vScaleShift(): number {\n return this._vScaleShift;\n }\n\n constructor(\n hSamples: number,\n maxHSamples: number,\n vSamples: number,\n maxVSamples: number,\n lines: Array\n ) {\n this._hSamples = hSamples;\n this._maxHSamples = maxHSamples;\n this._vSamples = vSamples;\n this._maxVSamples = maxVSamples;\n this._lines = lines;\n this._hScaleShift = this._hSamples === 1 && this._maxHSamples === 2 ? 1 : 0;\n this._vScaleShift = this._vSamples === 1 && this._maxVSamples === 2 ? 1 : 0;\n }\n}\n", "/** @format */\n\nexport class JpegAdobe {\n private _version: number;\n public get version(): number {\n return this._version;\n }\n\n private _flags0: number;\n public get flags0(): number {\n return this._flags0;\n }\n\n private _flags1: number;\n public get flags1(): number {\n return this._flags1;\n }\n\n private _transformCode: number;\n public get transformCode(): number {\n return this._transformCode;\n }\n\n constructor(\n version: number,\n flags0: number,\n flags1: number,\n transformCode: number\n ) {\n this._version = version;\n this._flags0 = flags0;\n this._flags1 = flags1;\n this._transformCode = transformCode;\n }\n}\n", "/** @format */\n\nimport { HuffmanNode } from './huffman-node';\n\nexport class JpegComponent {\n private readonly _quantizationTableList: Array;\n\n private readonly _quantizationIndex: number;\n\n private readonly _hSamples: number;\n public get hSamples(): number {\n return this._hSamples;\n }\n\n private readonly _vSamples: number;\n public get vSamples(): number {\n return this._vSamples;\n }\n\n private _blocks: Array> = new Array>();\n public get blocks(): Array> {\n return this._blocks;\n }\n\n private _blocksPerLine = 0;\n public get blocksPerLine(): number {\n return this._blocksPerLine;\n }\n\n private _blocksPerColumn = 0;\n public get blocksPerColumn(): number {\n return this._blocksPerColumn;\n }\n\n private _huffmanTableDC: Array = [];\n public set huffmanTableDC(v: Array) {\n this._huffmanTableDC = v;\n }\n public get huffmanTableDC(): Array {\n return this._huffmanTableDC;\n }\n\n private _huffmanTableAC: Array = [];\n public set huffmanTableAC(v: Array) {\n this._huffmanTableAC = v;\n }\n public get huffmanTableAC(): Array {\n return this._huffmanTableAC;\n }\n\n private _pred = 0;\n public set pred(v: number) {\n this._pred = v;\n }\n public get pred(): number {\n return this._pred;\n }\n\n public get quantizationTable(): Int16Array | undefined {\n return this._quantizationTableList[this._quantizationIndex];\n }\n\n constructor(\n hSamples: number,\n vSamples: number,\n quantizationTableList: Array,\n quantizationIndex: number\n ) {\n this._hSamples = hSamples;\n this._vSamples = vSamples;\n this._quantizationTableList = quantizationTableList;\n this._quantizationIndex = quantizationIndex;\n }\n\n public setBlocks(\n blocks: Array>,\n blocksPerLine: number,\n blocksPerColumn: number\n ) {\n this._blocks = blocks;\n this._blocksPerLine = blocksPerLine;\n this._blocksPerColumn = blocksPerColumn;\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../../common/array-utils';\nimport { JpegComponent } from './jpeg-component';\n\nexport class JpegFrame {\n private readonly _components: Map;\n public get components(): Map {\n return this._components;\n }\n\n private readonly _componentsOrder: Array;\n public get componentsOrder(): Array {\n return this._componentsOrder;\n }\n\n private _extended: boolean;\n public get extended(): boolean {\n return this._extended;\n }\n\n private _progressive: boolean;\n public get progressive(): boolean {\n return this._progressive;\n }\n\n private _precision: number;\n public get precision(): number {\n return this._precision;\n }\n\n private _scanLines: number;\n public get scanLines(): number {\n return this._scanLines;\n }\n\n private _samplesPerLine: number;\n public get samplesPerLine(): number {\n return this._samplesPerLine;\n }\n\n private _maxHSamples = 0;\n public get maxHSamples(): number {\n return this._maxHSamples;\n }\n\n private _maxVSamples = 0;\n public get maxVSamples(): number {\n return this._maxVSamples;\n }\n\n private _mcusPerLine = 0;\n public get mcusPerLine(): number {\n return this._mcusPerLine;\n }\n\n private _mcusPerColumn = 0;\n public get mcusPerColumn(): number {\n return this._mcusPerColumn;\n }\n\n constructor(\n components: Map,\n componentsOrder: Array,\n extended: boolean,\n progressive: boolean,\n precision: number,\n scanLines: number,\n samplesPerLine: number\n ) {\n this._components = components;\n this._componentsOrder = componentsOrder;\n this._extended = extended;\n this._progressive = progressive;\n this._precision = precision;\n this._scanLines = scanLines;\n this._samplesPerLine = samplesPerLine;\n }\n\n public prepare(): void {\n for (const [_, component] of this._components) {\n this._maxHSamples = Math.max(this._maxHSamples, component.hSamples);\n this._maxVSamples = Math.max(this._maxVSamples, component.vSamples);\n }\n\n this._mcusPerLine = Math.ceil(this._samplesPerLine / 8 / this._maxHSamples);\n this._mcusPerColumn = Math.ceil(this._scanLines / 8 / this._maxVSamples);\n\n for (const [_, component] of this._components) {\n const blocksPerLine = Math.ceil(\n (Math.ceil(this._samplesPerLine / 8) * component.hSamples) /\n this._maxHSamples\n );\n const blocksPerColumn = Math.ceil(\n (Math.ceil(this._scanLines / 8) * component.vSamples) / this.maxVSamples\n );\n const blocksPerLineForMcu = this._mcusPerLine * component.hSamples;\n const blocksPerColumnForMcu = this._mcusPerColumn * component.vSamples;\n\n const blocks = ArrayUtils.generate(\n blocksPerColumnForMcu,\n (_) =>\n ArrayUtils.generate(\n blocksPerLineForMcu,\n (_) => new Int32Array(64)\n )\n );\n\n component.setBlocks(blocks, blocksPerLine, blocksPerColumn);\n }\n }\n}\n", "/** @format */\n\nimport { HuffmanNode } from './huffman-node';\n\nexport class JpegHuffman {\n private readonly _children: Array = [];\n public get children(): Array {\n return this._children;\n }\n\n private _index = 0;\n public get index(): number {\n return this._index;\n }\n\n public incrementIndex() {\n this._index++;\n }\n}\n", "/** @format */\n\nimport { Color } from '../../color/color';\nimport { DecodeInfo } from '../decode-info';\n\nexport class JpegInfo implements DecodeInfo {\n private _width = 0;\n public get width(): number {\n return this._width;\n }\n\n private _height = 0;\n public get height(): number {\n return this._height;\n }\n\n private _numFrames = 1;\n public get numFrames(): number {\n return this._numFrames;\n }\n\n private _backgroundColor: Color | undefined = undefined;\n public get backgroundColor(): Color | undefined {\n return this._backgroundColor;\n }\n\n public setSize(width: number, height: number) {\n this._width = width;\n this._height = height;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\n\nexport class JpegJfif {\n private _thumbWidth: number;\n public get thumbWidth(): number {\n return this._thumbWidth;\n }\n\n private _thumbHeight: number;\n public get thumbHeight(): number {\n return this._thumbHeight;\n }\n\n private _majorVersion: number;\n public get majorVersion(): number {\n return this._majorVersion;\n }\n\n private _minorVersion: number;\n public get minorVersion(): number {\n return this._minorVersion;\n }\n\n private _densityUnits: number;\n public get densityUnits(): number {\n return this._densityUnits;\n }\n\n private _xDensity: number;\n public get xDensity(): number {\n return this._xDensity;\n }\n\n private _yDensity: number;\n public get yDensity(): number {\n return this._yDensity;\n }\n\n private _thumbData: InputBuffer;\n public get thumbData(): InputBuffer {\n return this._thumbData;\n }\n\n constructor(\n thumbWidth: number,\n thumbHeight: number,\n majorVersion: number,\n minorVersion: number,\n densityUnits: number,\n xDensity: number,\n yDensity: number,\n thumbData: InputBuffer\n ) {\n this._thumbWidth = thumbWidth;\n this._thumbHeight = thumbHeight;\n this._majorVersion = majorVersion;\n this._minorVersion = minorVersion;\n this._densityUnits = densityUnits;\n this._xDensity = xDensity;\n this._yDensity = yDensity;\n this._thumbData = thumbData;\n }\n}\n", "/** @format */\n\nimport { MathUtils } from '../../common/math-utils';\nimport { LibError } from '../../error/lib-error';\nimport { ExifData } from '../../exif/exif-data';\nimport { MemoryImage } from '../../image/image';\nimport { JpegComponentData } from './jpeg-component-data';\nimport { JpegData } from './jpeg-data';\n\nexport abstract class JpegQuantize {\n private static readonly _dctClipOffset = 256;\n private static readonly _dctClipLength = 768;\n private static readonly _dctClip = JpegQuantize.createDctClip();\n\n private static createDctClip(): Uint8Array {\n const result = new Uint8Array(JpegQuantize._dctClipLength);\n let i = 0;\n for (i = -256; i < 0; ++i) {\n result[JpegQuantize._dctClipOffset + i] = 0;\n }\n for (i = 0; i < 256; ++i) {\n result[JpegQuantize._dctClipOffset + i] = i;\n }\n for (i = 256; i < 512; ++i) {\n result[JpegQuantize._dctClipOffset + i] = 255;\n }\n return result;\n }\n\n // Quantize the coefficients and apply IDCT.\n //\n // A port of poppler's IDCT method which in turn is taken from:\n // Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,\n // \"Practical Fast 1-D DCT Algorithms with 11 Multiplications\",\n // IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989, 988-991.\n public static quantizeAndInverse(\n quantizationTable: Int16Array,\n coefBlock: Int32Array,\n dataOut: Uint8Array,\n dataIn: Int32Array\n ): void {\n const p = dataIn;\n\n // IDCT constants (20.12 fixed point format)\n // cos(pi/16)*4096\n const cos1 = 4017;\n // sin(pi/16)*4096\n const sin1 = 799;\n // cos(3*pi/16)*4096\n const cos3 = 3406;\n // sin(3*pi/16)*4096\n const sin3 = 2276;\n // cos(6*pi/16)*4096\n const cos6 = 1567;\n // sin(6*pi/16)*4096\n const sin6 = 3784;\n // sqrt(2)*4096\n const sqrt2 = 5793;\n // sqrt(2) / 2\n const sqrt102 = 2896;\n\n // de-quantize\n for (let i = 0; i < 64; i++) {\n p[i] = coefBlock[i] * quantizationTable[i];\n }\n\n // inverse DCT on rows\n let row = 0;\n for (let i = 0; i < 8; ++i, row += 8) {\n // check for all-zero AC coefficients\n if (\n p[1 + row] === 0 &&\n p[2 + row] === 0 &&\n p[3 + row] === 0 &&\n p[4 + row] === 0 &&\n p[5 + row] === 0 &&\n p[6 + row] === 0 &&\n p[7 + row] === 0\n ) {\n const t = (sqrt2 * p[0 + row] + 512) >> 10;\n p[row + 0] = t;\n p[row + 1] = t;\n p[row + 2] = t;\n p[row + 3] = t;\n p[row + 4] = t;\n p[row + 5] = t;\n p[row + 6] = t;\n p[row + 7] = t;\n continue;\n }\n\n // stage 4\n let v0 = (sqrt2 * p[0 + row] + 128) >> 8;\n let v1 = (sqrt2 * p[4 + row] + 128) >> 8;\n let v2 = p[2 + row];\n let v3 = p[6 + row];\n let v4 = (sqrt102 * (p[1 + row] - p[7 + row]) + 128) >> 8;\n let v7 = (sqrt102 * (p[1 + row] + p[7 + row]) + 128) >> 8;\n let v5 = p[3 + row] << 4;\n let v6 = p[5 + row] << 4;\n\n // stage 3\n let t = (v0 - v1 + 1) >> 1;\n v0 = (v0 + v1 + 1) >> 1;\n v1 = t;\n t = (v2 * sin6 + v3 * cos6 + 128) >> 8;\n v2 = (v2 * cos6 - v3 * sin6 + 128) >> 8;\n v3 = t;\n t = (v4 - v6 + 1) >> 1;\n v4 = (v4 + v6 + 1) >> 1;\n v6 = t;\n t = (v7 + v5 + 1) >> 1;\n v5 = (v7 - v5 + 1) >> 1;\n v7 = t;\n\n // stage 2\n t = (v0 - v3 + 1) >> 1;\n v0 = (v0 + v3 + 1) >> 1;\n v3 = t;\n t = (v1 - v2 + 1) >> 1;\n v1 = (v1 + v2 + 1) >> 1;\n v2 = t;\n t = (v4 * sin3 + v7 * cos3 + 2048) >> 12;\n v4 = (v4 * cos3 - v7 * sin3 + 2048) >> 12;\n v7 = t;\n t = (v5 * sin1 + v6 * cos1 + 2048) >> 12;\n v5 = (v5 * cos1 - v6 * sin1 + 2048) >> 12;\n v6 = t;\n\n // stage 1\n p[0 + row] = v0 + v7;\n p[7 + row] = v0 - v7;\n p[1 + row] = v1 + v6;\n p[6 + row] = v1 - v6;\n p[2 + row] = v2 + v5;\n p[5 + row] = v2 - v5;\n p[3 + row] = v3 + v4;\n p[4 + row] = v3 - v4;\n }\n\n // inverse DCT on columns\n for (let i = 0; i < 8; ++i) {\n const col = i;\n\n // check for all-zero AC coefficients\n if (\n p[1 * 8 + col] === 0 &&\n p[2 * 8 + col] === 0 &&\n p[3 * 8 + col] === 0 &&\n p[4 * 8 + col] === 0 &&\n p[5 * 8 + col] === 0 &&\n p[6 * 8 + col] === 0 &&\n p[7 * 8 + col] === 0\n ) {\n const t = (sqrt2 * dataIn[i] + 8192) >> 14;\n p[0 * 8 + col] = t;\n p[1 * 8 + col] = t;\n p[2 * 8 + col] = t;\n p[3 * 8 + col] = t;\n p[4 * 8 + col] = t;\n p[5 * 8 + col] = t;\n p[6 * 8 + col] = t;\n p[7 * 8 + col] = t;\n continue;\n }\n\n // stage 4\n let v0 = (sqrt2 * p[0 * 8 + col] + 2048) >> 12;\n let v1 = (sqrt2 * p[4 * 8 + col] + 2048) >> 12;\n let v2 = p[2 * 8 + col];\n let v3 = p[6 * 8 + col];\n let v4 = (sqrt102 * (p[1 * 8 + col] - p[7 * 8 + col]) + 2048) >> 12;\n let v7 = (sqrt102 * (p[1 * 8 + col] + p[7 * 8 + col]) + 2048) >> 12;\n let v5 = p[3 * 8 + col];\n let v6 = p[5 * 8 + col];\n\n // stage 3\n let t = (v0 - v1 + 1) >> 1;\n v0 = (v0 + v1 + 1) >> 1;\n v1 = t;\n t = (v2 * sin6 + v3 * cos6 + 2048) >> 12;\n v2 = (v2 * cos6 - v3 * sin6 + 2048) >> 12;\n v3 = t;\n t = (v4 - v6 + 1) >> 1;\n v4 = (v4 + v6 + 1) >> 1;\n v6 = t;\n t = (v7 + v5 + 1) >> 1;\n v5 = (v7 - v5 + 1) >> 1;\n v7 = t;\n\n // stage 2\n t = (v0 - v3 + 1) >> 1;\n v0 = (v0 + v3 + 1) >> 1;\n v3 = t;\n t = (v1 - v2 + 1) >> 1;\n v1 = (v1 + v2 + 1) >> 1;\n v2 = t;\n t = (v4 * sin3 + v7 * cos3 + 2048) >> 12;\n v4 = (v4 * cos3 - v7 * sin3 + 2048) >> 12;\n v7 = t;\n t = (v5 * sin1 + v6 * cos1 + 2048) >> 12;\n v5 = (v5 * cos1 - v6 * sin1 + 2048) >> 12;\n v6 = t;\n\n // stage 1\n p[0 * 8 + col] = v0 + v7;\n p[7 * 8 + col] = v0 - v7;\n p[1 * 8 + col] = v1 + v6;\n p[6 * 8 + col] = v1 - v6;\n p[2 * 8 + col] = v2 + v5;\n p[5 * 8 + col] = v2 - v5;\n p[3 * 8 + col] = v3 + v4;\n p[4 * 8 + col] = v3 - v4;\n }\n\n // convert to 8-bit integers\n for (let i = 0; i < 64; ++i) {\n dataOut[i] =\n JpegQuantize._dctClip[\n JpegQuantize._dctClipOffset + 128 + ((p[i] + 8) >> 4)\n ];\n }\n }\n\n public static getImageFromJpeg(jpeg: JpegData): MemoryImage {\n const orientation = jpeg.exifData.imageIfd.hasOrientation\n ? jpeg.exifData.imageIfd.orientation!\n : 0;\n\n const w = jpeg.width!;\n const h = jpeg.height!;\n const flipWidthHeight = orientation >= 5 && orientation <= 8;\n const width = flipWidthHeight ? h : w;\n const height = flipWidthHeight ? w : h;\n\n const image = new MemoryImage({\n width: width,\n height: height,\n });\n\n // Copy exif data, except for ORIENTATION which we're baking.\n image.exifData = ExifData.from(jpeg.exifData);\n image.exifData.imageIfd.orientation = undefined;\n\n let component1: JpegComponentData | undefined = undefined;\n let component2: JpegComponentData | undefined = undefined;\n let component3: JpegComponentData | undefined = undefined;\n let component4: JpegComponentData | undefined = undefined;\n let component1Line: Uint8Array | undefined = undefined;\n let component2Line: Uint8Array | undefined = undefined;\n let component3Line: Uint8Array | undefined = undefined;\n let component4Line: Uint8Array | undefined = undefined;\n let colorTransform = false;\n\n const h1 = h - 1;\n const w1 = w - 1;\n\n switch (jpeg.components.length) {\n case 1:\n {\n component1 = jpeg.components[0];\n const lines = component1.lines;\n const hShift1 = component1.hScaleShift;\n const vShift1 = component1.vScaleShift;\n for (let y = 0; y < h; y++) {\n const y1 = y >> vShift1;\n component1Line = lines[y1];\n for (let x = 0; x < w; x++) {\n const x1 = x >> hShift1;\n const cy = component1Line![x1];\n\n if (orientation === 2) {\n image.setPixelRgb(w1 - x, y, cy, cy, cy);\n } else if (orientation === 3) {\n image.setPixelRgb(w1 - x, h1 - y, cy, cy, cy);\n } else if (orientation === 4) {\n image.setPixelRgb(x, h1 - y, cy, cy, cy);\n } else if (orientation === 5) {\n image.setPixelRgb(y, x, cy, cy, cy);\n } else if (orientation === 6) {\n image.setPixelRgb(h1 - y, x, cy, cy, cy);\n } else if (orientation === 7) {\n image.setPixelRgb(h1 - y, w1 - x, cy, cy, cy);\n } else if (orientation === 8) {\n image.setPixelRgb(y, w1 - x, cy, cy, cy);\n } else {\n image.setPixelRgb(x, y, cy, cy, cy);\n }\n }\n }\n }\n break;\n case 2:\n // {\n // // PDF might compress two component data in custom color-space\n // component1 = jpeg.components[0];\n // component2 = jpeg.components[1];\n // const hShift1 = component1.hScaleShift;\n // const vShift1 = component1.vScaleShift;\n // const hShift2 = component2.hScaleShift;\n // const vShift2 = component2.vScaleShift;\n\n // for (let y = 0; y < h; ++y) {\n // const y1 = y >> vShift1;\n // const y2 = y >> vShift2;\n // component1Line = component1.lines[y1];\n // component2Line = component2.lines[y2];\n\n // for (let x = 0; x < w; ++x) {\n // const x1 = x >> hShift1;\n // const x2 = x >> hShift2;\n\n // let cy = component1Line![x1];\n // // data[offset++] = cy;\n\n // cy = component2Line![x2];\n // // data[offset++] = cy;\n // }\n // }\n // }\n break;\n case 3:\n {\n // The default transform for three components is true\n colorTransform = true;\n\n component1 = jpeg.components[0];\n component2 = jpeg.components[1];\n component3 = jpeg.components[2];\n\n const lines1 = component1.lines;\n const lines2 = component2.lines;\n const lines3 = component3.lines;\n\n const hShift1 = component1.hScaleShift;\n const vShift1 = component1.vScaleShift;\n const hShift2 = component2.hScaleShift;\n const vShift2 = component2.vScaleShift;\n const hShift3 = component3.hScaleShift;\n const vShift3 = component3.vScaleShift;\n\n for (let y = 0; y < h; y++) {\n const y1 = y >> vShift1;\n const y2 = y >> vShift2;\n const y3 = y >> vShift3;\n\n component1Line = lines1[y1];\n component2Line = lines2[y2];\n component3Line = lines3[y3];\n\n for (let x = 0; x < w; x++) {\n const x1 = x >> hShift1;\n const x2 = x >> hShift2;\n const x3 = x >> hShift3;\n\n const cy = component1Line![x1] << 8;\n const cb = component2Line![x2] - 128;\n const cr = component3Line![x3] - 128;\n\n let r = cy + 359 * cr + 128;\n let g = cy - 88 * cb - 183 * cr + 128;\n let b = cy + 454 * cb + 128;\n r = MathUtils.clampInt255(r >> 8);\n g = MathUtils.clampInt255(g >> 8);\n b = MathUtils.clampInt255(b >> 8);\n\n if (orientation === 2) {\n image.setPixelRgb(w1 - x, y, r, g, b);\n } else if (orientation === 3) {\n image.setPixelRgb(w1 - x, h1 - y, r, g, b);\n } else if (orientation === 4) {\n image.setPixelRgb(x, h1 - y, r, g, b);\n } else if (orientation === 5) {\n image.setPixelRgb(y, x, r, g, b);\n } else if (orientation === 6) {\n image.setPixelRgb(h1 - y, x, r, g, b);\n } else if (orientation === 7) {\n image.setPixelRgb(h1 - y, w1 - x, r, g, b);\n } else if (orientation === 8) {\n image.setPixelRgb(y, w1 - x, r, g, b);\n } else {\n image.setPixelRgb(x, y, r, g, b);\n }\n }\n }\n }\n break;\n case 4:\n {\n if (jpeg.adobe === undefined) {\n throw new LibError('Unsupported color mode (4 components)');\n }\n // The default transform for four components is false\n colorTransform = false;\n // The adobe transform marker overrides any previous setting\n if (jpeg.adobe!.transformCode !== 0) {\n colorTransform = true;\n }\n\n component1 = jpeg.components[0];\n component2 = jpeg.components[1];\n component3 = jpeg.components[2];\n component4 = jpeg.components[3];\n\n const lines1 = component1.lines;\n const lines2 = component2.lines;\n const lines3 = component3.lines;\n const lines4 = component4.lines;\n\n const hShift1 = component1.hScaleShift;\n const vShift1 = component1.vScaleShift;\n const hShift2 = component2.hScaleShift;\n const vShift2 = component2.vScaleShift;\n const hShift3 = component3.hScaleShift;\n const vShift3 = component3.vScaleShift;\n const hShift4 = component4.hScaleShift;\n const vShift4 = component4.vScaleShift;\n\n for (let y = 0; y < jpeg.height!; y++) {\n const y1 = y >> vShift1;\n const y2 = y >> vShift2;\n const y3 = y >> vShift3;\n const y4 = y >> vShift4;\n component1Line = lines1[y1];\n component2Line = lines2[y2];\n component3Line = lines3[y3];\n component4Line = lines4[y4];\n for (let x = 0; x < jpeg.width!; x++) {\n const x1 = x >> hShift1;\n const x2 = x >> hShift2;\n const x3 = x >> hShift3;\n const x4 = x >> hShift4;\n let cc = 0;\n let cm = 0;\n let cy = 0;\n let ck = 0;\n if (!colorTransform) {\n cc = component1Line![x1];\n cm = component2Line![x2];\n cy = component3Line![x3];\n ck = component4Line![x4];\n } else {\n cy = component1Line![x1];\n const cb = component2Line![x2];\n const cr = component3Line![x3];\n ck = component4Line![x4];\n\n cc = 255 - MathUtils.clampInt255(cy + 1.402 * (cr - 128));\n cm =\n 255 -\n MathUtils.clampInt255(\n cy - 0.3441363 * (cb - 128) - 0.71413636 * (cr - 128)\n );\n cy = 255 - MathUtils.clampInt255(cy + 1.772 * (cb - 128));\n }\n const r = (cc * ck) >> 8;\n const g = (cm * ck) >> 8;\n const b = (cy * ck) >> 8;\n\n if (orientation === 2) {\n image.setPixelRgb(w1 - x, y, r, g, b);\n } else if (orientation === 3) {\n image.setPixelRgb(w1 - x, h1 - y, r, g, b);\n } else if (orientation === 4) {\n image.setPixelRgb(x, h1 - y, r, g, b);\n } else if (orientation === 5) {\n image.setPixelRgb(y, x, r, g, b);\n } else if (orientation === 6) {\n image.setPixelRgb(h1 - y, x, r, g, b);\n } else if (orientation === 7) {\n image.setPixelRgb(h1 - y, w1 - x, r, g, b);\n } else if (orientation === 8) {\n image.setPixelRgb(y, w1 - x, r, g, b);\n } else {\n image.setPixelRgb(x, y, r, g, b);\n }\n }\n }\n }\n break;\n default:\n throw new LibError('Unsupported color mode');\n }\n\n return image;\n }\n}\n", "/** @format */\n\nexport abstract class HuffmanNode {}\n", "/** @format */\n\nimport { HuffmanNode } from './huffman-node';\n\nexport class HuffmanParent extends HuffmanNode {\n private readonly _children: Array;\n public get children(): Array {\n return this._children;\n }\n\n constructor(children: Array) {\n super();\n this._children = children;\n }\n}\n", "/** @format */\n\nimport { HuffmanNode } from './huffman-node';\n\nexport class HuffmanValue extends HuffmanNode {\n private readonly _value: number;\n public get value(): number {\n return this._value;\n }\n\n constructor(value: number) {\n super();\n this._value = value;\n }\n}\n", "/** @format */\n\nexport enum JpegMarker {\n sof0 = 0xc0,\n sof1 = 0xc1,\n sof2 = 0xc2,\n sof3 = 0xc3,\n sof5 = 0xc5,\n sof6 = 0xc6,\n sof7 = 0xc7,\n\n jpg = 0xc8,\n sof9 = 0xc9,\n sof10 = 0xca,\n sof11 = 0xcb,\n\n sof13 = 0xcd,\n sof14 = 0xce,\n sof15 = 0xcf,\n\n dht = 0xc4,\n\n dac = 0xcc,\n\n rst0 = 0xd0,\n rst1 = 0xd1,\n rst2 = 0xd2,\n rst3 = 0xd3,\n rst4 = 0xd4,\n rst5 = 0xd5,\n rst6 = 0xd6,\n rst7 = 0xd7,\n\n soi = 0xd8,\n eoi = 0xd9,\n sos = 0xda,\n dqt = 0xdb,\n dnl = 0xdc,\n dri = 0xdd,\n dhp = 0xde,\n exp = 0xdf,\n\n // JFIF, JFXX, CIFF, AVI1, Ocad\n app0 = 0xe0,\n // EXIF, ExtendedXMP, XMP, QVCI, FLIR\n app1 = 0xe1,\n // ICC_Profile, FPXR, MPF, PreviewImage\n app2 = 0xe2,\n // Meta, Stim, PreviewImage\n app3 = 0xe3,\n // Scalado, FPXR, PreviewImage\n app4 = 0xe4,\n // RMETA, PreviewImage\n app5 = 0xe5,\n // EPPIM, NITF, HP_TDHD, GoPro\n app6 = 0xe6,\n // Pentax, Qualcomm\n app7 = 0xe7,\n // SPIFF\n app8 = 0xe8,\n // MediaJukebox\n app9 = 0xe9,\n // Comment\n app10 = 0xea,\n // Jpeg-HDR\n app11 = 0xeb,\n // PictureInfo, Ducky\n app12 = 0xec,\n // Photoshop, Adobe_CM\n app13 = 0xed,\n // ADOBE\n app14 = 0xee,\n // GraphicConverter\n app15 = 0xef,\n\n jpg0 = 0xf0,\n jpg13 = 0xfd,\n com = 0xfe,\n\n tem = 0x01,\n\n error = 0x100,\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { LibError } from '../../error/lib-error';\nimport { HuffmanNode } from './huffman-node';\nimport { HuffmanParent } from './huffman-parent';\nimport { HuffmanValue } from './huffman-value';\nimport { JpegComponent } from './jpeg-component';\nimport { JpegData } from './jpeg-data';\nimport { JpegFrame } from './jpeg-frame';\nimport { JpegMarker } from './jpeg-marker';\n\nexport type DecodeFunction = (\n component: JpegComponent,\n block: Int32Array\n) => void;\n\nexport class JpegScan {\n private _input: InputBuffer;\n public get input(): InputBuffer {\n return this._input;\n }\n\n private _frame: JpegFrame;\n public get frame(): JpegFrame {\n return this._frame;\n }\n\n private _precision: number;\n public get precision(): number {\n return this._precision;\n }\n\n private _samplesPerLine: number;\n public get samplesPerLine(): number {\n return this._samplesPerLine;\n }\n\n private _scanLines: number;\n public get scanLines(): number {\n return this._scanLines;\n }\n\n private _mcusPerLine: number;\n public get mcusPerLine(): number {\n return this._mcusPerLine;\n }\n\n private _progressive: boolean;\n public get progressive(): boolean {\n return this._progressive;\n }\n\n private _maxH: number;\n public get maxH(): number {\n return this._maxH;\n }\n\n private _maxV: number;\n public get maxV(): number {\n return this._maxV;\n }\n\n private _components: Array;\n public get components(): Array {\n return this._components;\n }\n\n private _resetInterval?: number;\n public get resetInterval(): number | undefined {\n return this._resetInterval;\n }\n\n private _spectralStart: number;\n public get spectralStart(): number {\n return this._spectralStart;\n }\n\n private _spectralEnd: number;\n public get spectralEnd(): number {\n return this._spectralEnd;\n }\n\n private _successivePrev: number;\n public get successivePrev(): number {\n return this._successivePrev;\n }\n\n private _successive: number;\n public get successive(): number {\n return this._successive;\n }\n\n private _bitsData = 0;\n public get bitsData(): number {\n return this._bitsData;\n }\n\n private _bitsCount = 0;\n public get bitsCount(): number {\n return this._bitsCount;\n }\n\n private _eobrun = 0;\n public get eobrun(): number {\n return this._eobrun;\n }\n\n private _successiveACState = 0;\n public get successiveACState(): number {\n return this._successiveACState;\n }\n\n private _successiveACNextValue = 0;\n public get successiveACNextValue(): number {\n return this._successiveACNextValue;\n }\n\n constructor(\n input: InputBuffer,\n frame: JpegFrame,\n components: Array,\n spectralStart: number,\n spectralEnd: number,\n successivePrev: number,\n successive: number,\n resetInterval?: number\n ) {\n this._input = input;\n this._frame = frame;\n this._precision = frame.precision;\n this._samplesPerLine = frame.samplesPerLine;\n this._scanLines = frame.scanLines;\n this._mcusPerLine = frame.mcusPerLine;\n this._progressive = frame.progressive;\n this._maxH = frame.maxHSamples;\n this._maxV = frame.maxVSamples;\n this._components = components;\n this._resetInterval = resetInterval;\n this._spectralStart = spectralStart;\n this._spectralEnd = spectralEnd;\n this._successivePrev = successivePrev;\n this._successive = successive;\n }\n\n private readBit(): number | undefined {\n if (this.bitsCount > 0) {\n this._bitsCount--;\n return (this._bitsData >> this._bitsCount) & 1;\n }\n\n if (this._input.isEOS) {\n return undefined;\n }\n\n this._bitsData = this._input.readByte();\n if (this._bitsData === 0xff) {\n const nextByte = this.input.readByte();\n if (nextByte !== 0) {\n const marker = ((this._bitsData << 8) | nextByte).toString(16);\n throw new LibError(`unexpected marker: ${marker}`);\n }\n }\n\n this._bitsCount = 7;\n return (this._bitsData >> 7) & 1;\n }\n\n private decodeHuffman(\n tree: Array\n ): number | undefined {\n let node: HuffmanNode | undefined = new HuffmanParent(tree);\n let bit: number | undefined = undefined;\n while ((bit = this.readBit()) !== undefined) {\n if (node instanceof HuffmanParent) {\n node = node.children[bit];\n }\n if (node instanceof HuffmanValue) {\n return node.value;\n }\n }\n return undefined;\n }\n\n private receive(length: number): number | undefined {\n let n = 0;\n let len = length;\n while (len > 0) {\n const bit = this.readBit();\n if (bit === undefined) {\n return undefined;\n }\n n = (n << 1) | bit;\n len--;\n }\n return n;\n }\n\n private receiveAndExtend(length: number | undefined): number {\n if (length === 1) {\n return this.readBit() === 1 ? 1 : -1;\n }\n const n = this.receive(length!)!;\n if (n >= 1 << ((length ?? 0) - 1)) {\n return n;\n }\n return n + (-1 << (length ?? 0)) + 1;\n }\n\n private decodeBaseline(component: JpegComponent, zz: Int32Array): void {\n const t = this.decodeHuffman(component.huffmanTableDC);\n const diff = t === 0 ? 0 : this.receiveAndExtend(t);\n component.pred += diff;\n zz[0] = component.pred;\n\n let k = 1;\n while (k < 64) {\n const rs = this.decodeHuffman(component.huffmanTableAC)!;\n let s = rs & 15;\n const r = rs >> 4;\n if (s === 0) {\n if (r < 15) {\n break;\n }\n k += 16;\n continue;\n }\n\n k += r;\n\n s = this.receiveAndExtend(s);\n\n const z = JpegData.dctZigZag[k];\n zz[z] = s;\n k++;\n }\n }\n\n private decodeDCFirst(component: JpegComponent, zz: Int32Array): void {\n const t = this.decodeHuffman(component.huffmanTableDC);\n const diff = t === 0 ? 0 : this.receiveAndExtend(t) << this._successive;\n component.pred += diff;\n zz[0] = component.pred;\n }\n\n private decodeDCSuccessive(_: JpegComponent, zz: Int32Array): void {\n zz[0] |= this.readBit()! << this._successive;\n }\n\n private decodeACFirst(component: JpegComponent, zz: Int32Array): void {\n if (this._eobrun > 0) {\n this._eobrun--;\n return;\n }\n let k = this._spectralStart;\n const e = this._spectralEnd;\n while (k <= e) {\n const rs = this.decodeHuffman(component.huffmanTableAC)!;\n const s = rs & 15;\n const r = rs >> 4;\n if (s === 0) {\n if (r < 15) {\n this._eobrun = this.receive(r)! + (1 << r) - 1;\n break;\n }\n k += 16;\n continue;\n }\n k += r;\n const z = JpegData.dctZigZag[k];\n zz[z] = this.receiveAndExtend(s) * (1 << this._successive);\n k++;\n }\n }\n\n private decodeACSuccessive(component: JpegComponent, zz: Int32Array): void {\n let k = this._spectralStart;\n const e = this._spectralEnd;\n let s = 0;\n let r = 0;\n while (k <= e) {\n const z = JpegData.dctZigZag[k];\n switch (this._successiveACState) {\n case 0: {\n // Initial state\n const rs = this.decodeHuffman(component.huffmanTableAC);\n if (rs === undefined) {\n throw new LibError('Invalid progressive encoding');\n }\n s = rs & 15;\n r = rs >> 4;\n if (s === 0) {\n if (r < 15) {\n this._eobrun = this.receive(r)! + (1 << r);\n this._successiveACState = 4;\n } else {\n r = 16;\n this._successiveACState = 1;\n }\n } else {\n if (s !== 1) {\n throw new LibError('invalid ACn encoding');\n }\n this._successiveACNextValue = this.receiveAndExtend(s);\n this._successiveACState = r !== 0 ? 2 : 3;\n }\n continue;\n }\n case 1:\n case 2: {\n // Skipping r zero items\n if (zz[z] !== 0) {\n zz[z] += this.readBit()! << this._successive;\n } else {\n r--;\n if (r === 0) {\n this._successiveACState = this._successiveACState === 2 ? 3 : 0;\n }\n }\n break;\n }\n case 3: {\n // Set value for a zero item\n if (zz[z] !== 0) {\n zz[z] += this.readBit()! << this._successive;\n } else {\n zz[z] = this._successiveACNextValue << this._successive;\n this._successiveACState = 0;\n }\n break;\n }\n case 4: {\n // Eob\n if (zz[z] !== 0) {\n zz[z] += this.readBit()! << this._successive;\n }\n break;\n }\n }\n k++;\n }\n if (this._successiveACState === 4) {\n this._eobrun--;\n if (this._eobrun === 0) {\n this._successiveACState = 0;\n }\n }\n }\n\n private decodeMcu(\n component: JpegComponent,\n decodeFn: DecodeFunction,\n mcu: number,\n row: number,\n col: number\n ): void {\n const mcuRow = Math.floor(mcu / this._mcusPerLine);\n const mcuCol = mcu % this._mcusPerLine;\n const blockRow = mcuRow * component.vSamples + row;\n const blockCol = mcuCol * component.hSamples + col;\n if (blockRow >= component.blocks.length) {\n return;\n }\n const numCols = component.blocks[blockRow].length;\n if (blockCol >= numCols) {\n return;\n }\n decodeFn.call(this, component, component.blocks[blockRow][blockCol]);\n }\n\n private decodeBlock(\n component: JpegComponent,\n decodeFn: DecodeFunction,\n mcu: number\n ): void {\n const blockRow = Math.floor(mcu / component.blocksPerLine);\n const blockCol = mcu % component.blocksPerLine;\n decodeFn.call(this, component, component.blocks[blockRow][blockCol]);\n }\n\n public decode(): void {\n const componentsLength = this._components.length;\n let component: JpegComponent | undefined = undefined;\n let decodeFn: DecodeFunction | undefined = undefined;\n if (this._progressive) {\n if (this._spectralStart === 0) {\n decodeFn =\n this._successivePrev === 0\n ? this.decodeDCFirst\n : this.decodeDCSuccessive;\n } else {\n decodeFn =\n this._successivePrev === 0\n ? this.decodeACFirst\n : this.decodeACSuccessive;\n }\n } else {\n decodeFn = this.decodeBaseline;\n }\n\n let mcu = 0;\n\n let mcuExpected: number | undefined = undefined;\n if (componentsLength === 1) {\n mcuExpected =\n this._components[0].blocksPerLine * this._components[0].blocksPerColumn;\n } else {\n mcuExpected = this._mcusPerLine * this._frame.mcusPerColumn;\n }\n\n if (this._resetInterval === undefined || this._resetInterval === 0) {\n this._resetInterval = mcuExpected;\n }\n\n let h: number | undefined = undefined;\n let v: number | undefined = undefined;\n while (mcu < mcuExpected) {\n // Reset interval stuff\n for (let i = 0; i < componentsLength; i++) {\n this._components[i].pred = 0;\n }\n this._eobrun = 0;\n\n if (componentsLength === 1) {\n component = this._components[0];\n for (let n = 0; n < this._resetInterval; n++) {\n this.decodeBlock(component, decodeFn, mcu);\n mcu++;\n }\n } else {\n for (let n = 0; n < this._resetInterval; n++) {\n for (let i = 0; i < componentsLength; i++) {\n component = this.components[i];\n h = component.hSamples;\n v = component.vSamples;\n for (let j = 0; j < v; j++) {\n for (let k = 0; k < h; k++) {\n this.decodeMcu(component, decodeFn, mcu, j, k);\n }\n }\n }\n mcu++;\n }\n }\n\n // Find marker\n this._bitsCount = 0;\n const m1 = this._input.getByte(0);\n const m2 = this._input.getByte(1);\n if (m1 === 0xff) {\n if (m2 >= JpegMarker.rst0 && m2 <= JpegMarker.rst7) {\n this._input.skip(2);\n } else {\n break;\n }\n }\n }\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { LibError } from '../../error/lib-error';\nimport { JpegComponentData } from './jpeg-component-data';\nimport { JpegAdobe } from './jpeg-adobe';\nimport { JpegComponent } from './jpeg-component';\nimport { JpegFrame } from './jpeg-frame';\nimport { JpegHuffman } from './jpeg-huffman';\nimport { JpegInfo } from './jpeg-info';\nimport { JpegJfif } from './jpeg-jfif';\nimport { JpegQuantize } from './jpeg-quantize';\nimport { JpegScan } from './jpeg-scan';\nimport { ExifData } from '../../exif/exif-data';\nimport { ArrayUtils } from '../../common/array-utils';\nimport { JpegMarker } from './jpeg-marker';\nimport { MemoryImage } from '../../image/image';\nimport { HuffmanNode } from './huffman-node';\nimport { HuffmanValue } from './huffman-value';\nimport { HuffmanParent } from './huffman-parent';\n\nexport class JpegData {\n public static readonly dctZigZag = [\n 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40,\n 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36,\n 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61,\n 54, 47, 55, 62, 63,\n // extra entries for safety in decoder\n 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,\n ];\n\n // The basic DCT block is 8x8 samples\n public static readonly dctSize = 8;\n // DCTSIZE squared; # of elements in a block\n public static readonly dctSize2 = 64;\n // Quantization tables are 0..3\n public static readonly numQuantizationTables = 4;\n // Huffman tables are numbered 0..3\n public static readonly numHuffmanTables = 4;\n // Arith-coding tables are numbered 0..15\n public static readonly numArithTables = 16;\n // JPEG limit on # of components in one scan\n public static readonly maxCompsInScan = 4;\n // JPEG limit on sampling factors\n public static readonly maxSamplingFactor = 4;\n\n private _input!: InputBuffer;\n public get input(): InputBuffer {\n return this._input;\n }\n\n private _jfif!: JpegJfif;\n public get jfif(): JpegJfif {\n return this._jfif;\n }\n\n private _adobe!: JpegAdobe;\n public get adobe(): JpegAdobe {\n return this._adobe;\n }\n\n private _frame?: JpegFrame;\n public get frame(): JpegFrame | undefined {\n return this._frame;\n }\n\n private _resetInterval!: number;\n public get resetInterval(): number {\n return this._resetInterval;\n }\n\n private _comment?: string;\n public get comment(): string | undefined {\n return this._comment;\n }\n\n private readonly _exifData: ExifData = new ExifData();\n public get exifData(): ExifData {\n return this._exifData;\n }\n\n private readonly _quantizationTables = ArrayUtils.fill<\n Int16Array | undefined\n >(JpegData.numQuantizationTables, undefined);\n public get quantizationTables(): Array {\n return this._quantizationTables;\n }\n\n private readonly _frames = new Array();\n public get frames(): Array {\n return this._frames;\n }\n\n private readonly _huffmanTablesAC: Array<\n Array | undefined\n > = [];\n public get huffmanTablesAC(): Array<\n Array | undefined\n > {\n return this._huffmanTablesAC;\n }\n\n private readonly _huffmanTablesDC: Array<\n Array | undefined\n > = [];\n public get huffmanTablesDC(): Array<\n Array | undefined\n > {\n return this._huffmanTablesDC;\n }\n\n private readonly _components = new Array();\n public get components(): Array {\n return this._components;\n }\n\n public get width(): number {\n return this._frame!.samplesPerLine;\n }\n\n public get height(): number {\n return this._frame!.scanLines;\n }\n\n private readMarkers(): void {\n let marker = this.nextMarker();\n if (marker !== JpegMarker.soi) {\n // SOI (Start of Image)\n throw new LibError('Start Of Image marker not found.');\n }\n\n marker = this.nextMarker();\n while (marker !== JpegMarker.eoi && !this._input.isEOS) {\n const block = this.readBlock();\n switch (marker) {\n case JpegMarker.app0:\n case JpegMarker.app1:\n case JpegMarker.app2:\n case JpegMarker.app3:\n case JpegMarker.app4:\n case JpegMarker.app5:\n case JpegMarker.app6:\n case JpegMarker.app7:\n case JpegMarker.app8:\n case JpegMarker.app9:\n case JpegMarker.app10:\n case JpegMarker.app11:\n case JpegMarker.app12:\n case JpegMarker.app13:\n case JpegMarker.app14:\n case JpegMarker.app15:\n case JpegMarker.com:\n this.readAppData(marker, block);\n break;\n\n // DQT (Define Quantization Tables)\n case JpegMarker.dqt:\n this.readDQT(block);\n break;\n\n // SOF0 (Start of Frame, Baseline DCT)\n case JpegMarker.sof0:\n // SOF1 (Start of Frame, Extended DCT)\n // falls through\n case JpegMarker.sof1:\n // SOF2 (Start of Frame, Progressive DCT)\n // falls through\n case JpegMarker.sof2:\n this.readFrame(marker, block);\n break;\n\n case JpegMarker.sof3:\n case JpegMarker.sof5:\n case JpegMarker.sof6:\n case JpegMarker.sof7:\n case JpegMarker.jpg:\n case JpegMarker.sof9:\n case JpegMarker.sof10:\n case JpegMarker.sof11:\n case JpegMarker.sof13:\n case JpegMarker.sof14:\n case JpegMarker.sof15:\n throw new LibError(`Unhandled frame type ${marker.toString(16)}`);\n\n // DHT (Define Huffman Tables)\n case JpegMarker.dht:\n this.readDHT(block);\n break;\n\n // DRI (Define Restart Interval)\n case JpegMarker.dri:\n this.readDRI(block);\n break;\n\n // SOS (Start of Scan)\n case JpegMarker.sos:\n this.readSOS(block);\n break;\n\n // Fill bytes\n case 0xff:\n if (this._input.getByte(0) !== 0xff) {\n this._input.skip(-1);\n }\n break;\n\n default:\n if (\n this._input.getByte(-3) === 0xff &&\n this._input.getByte(-2) >= 0xc0 &&\n this._input.getByte(-2) <= 0xfe\n ) {\n // Could be incorrect encoding -- last 0xFF byte of the previous\n // block was eaten by the encoder\n this._input.skip(-3);\n break;\n }\n\n if (marker !== 0) {\n throw new LibError(`Unknown JPEG marker ${marker.toString(16)}`);\n }\n break;\n }\n\n marker = this.nextMarker();\n }\n }\n\n private skipBlock(): void {\n const length = this._input.readUint16();\n if (length < 2) {\n throw new LibError('Invalid Block');\n }\n this._input.skip(length - 2);\n }\n\n public validate(bytes: Uint8Array): boolean {\n this._input = new InputBuffer({\n buffer: bytes,\n bigEndian: true,\n });\n\n // Some other formats have embedded jpeg, or jpeg-like data.\n // Only validate if the image starts with the StartOfImage tag.\n const soiCheck = this._input.peekBytes(2);\n if (soiCheck.getByte(0) !== 0xff || soiCheck.getByte(1) !== 0xd8) {\n return false;\n }\n\n let marker = this.nextMarker();\n if (marker !== JpegMarker.soi) {\n return false;\n }\n\n let hasSOF = false;\n let hasSOS = false;\n\n marker = this.nextMarker();\n while (marker !== JpegMarker.eoi && !this._input.isEOS) {\n // EOI (End of image)\n const sectionByteSize = this._input.readUint16();\n if (sectionByteSize < 2) {\n // Jpeg section consists of more than 2 bytes at least\n // return success only when SOF and SOS have already found (as a jpeg without EOF)\n break;\n }\n\n this._input.skip(sectionByteSize - 2);\n\n switch (marker) {\n // SOF0 (Start of Frame, Baseline DCT)\n case JpegMarker.sof0:\n // SOF1 (Start of Frame, Extended DCT)\n // falls through\n case JpegMarker.sof1:\n // SOF2 (Start of Frame, Progressive DCT)\n // falls through\n case JpegMarker.sof2:\n hasSOF = true;\n break;\n // SOS (Start of Scan)\n case JpegMarker.sos:\n hasSOS = true;\n break;\n default:\n }\n\n marker = this.nextMarker();\n }\n\n return hasSOF && hasSOS;\n }\n\n public readInfo(bytes: Uint8Array): JpegInfo | undefined {\n this._input = new InputBuffer({\n buffer: bytes,\n bigEndian: true,\n });\n\n let marker = this.nextMarker();\n if (marker !== JpegMarker.soi) {\n return undefined;\n }\n\n const info = new JpegInfo();\n\n let hasSOF = false;\n let hasSOS = false;\n\n marker = this.nextMarker();\n while (marker !== JpegMarker.eoi && !this._input.isEOS) {\n // EOI (End of image)\n switch (marker) {\n // SOF0 (Start of Frame, Baseline DCT)\n case JpegMarker.sof0:\n // SOF1 (Start of Frame, Extended DCT)\n // falls through\n case JpegMarker.sof1:\n // SOF2 (Start of Frame, Progressive DCT)\n // falls through\n case JpegMarker.sof2:\n hasSOF = true;\n this.readFrame(marker, this.readBlock());\n break;\n // SOS (Start of Scan)\n case JpegMarker.sos:\n hasSOS = true;\n this.skipBlock();\n break;\n default:\n this.skipBlock();\n break;\n }\n\n marker = this.nextMarker();\n }\n\n if (this._frame !== undefined) {\n info.setSize(this._frame.samplesPerLine, this._frame.scanLines);\n this._frame = undefined;\n }\n\n this.frames.length = 0;\n\n return hasSOF && hasSOS ? info : undefined;\n }\n\n public read(bytes: Uint8Array): void {\n this._input = new InputBuffer({\n buffer: bytes,\n bigEndian: true,\n });\n\n this.readMarkers();\n\n if (this._frames.length !== 1) {\n throw new LibError('Only single frame JPEGs supported');\n }\n\n if (this._frame !== undefined) {\n for (let i = 0; i < this._frame.componentsOrder.length; ++i) {\n const component = this._frame.components.get(\n this._frame.componentsOrder[i]\n );\n if (component !== undefined) {\n this.components.push(\n new JpegComponentData(\n component.hSamples,\n this._frame.maxHSamples,\n component.vSamples,\n this._frame.maxVSamples,\n JpegData.buildComponentData(component)\n )\n );\n }\n }\n }\n }\n\n getImage(): MemoryImage {\n return JpegQuantize.getImageFromJpeg(this);\n }\n\n private static buildHuffmanTable(\n codeLengths: Uint8Array,\n values: Uint8Array\n ): Array {\n let k = 0;\n const code = new Array();\n let length = 16;\n\n while (length > 0 && codeLengths[length - 1] === 0) {\n length--;\n }\n\n code.push(new JpegHuffman());\n\n let p: JpegHuffman = code[0];\n for (let i = 0; i < length; i++) {\n for (let j = 0; j < codeLengths[i]; j++) {\n p = code.pop()!;\n if (p.children.length <= p.index) {\n p.children.length = p.index + 1;\n }\n p.children[p.index] = new HuffmanValue(values[k]);\n while (p.index > 0) {\n p = code.pop()!;\n }\n p.incrementIndex();\n code.push(p);\n while (code.length <= i) {\n const q = new JpegHuffman();\n code.push(q);\n if (p.children.length <= p.index) {\n p.children.length = p.index + 1;\n }\n p.children[p.index] = new HuffmanParent(q.children);\n p = q;\n }\n k++;\n }\n\n if (i + 1 < length) {\n // P here points to last code\n const q = new JpegHuffman();\n code.push(q);\n if (p.children.length <= p.index) {\n p.children.length = p.index + 1;\n }\n p.children[p.index] = new HuffmanParent(q.children);\n p = q;\n }\n }\n\n return code[0].children;\n }\n\n private static buildComponentData(\n component: JpegComponent\n ): Array {\n const blocksPerLine = component.blocksPerLine;\n const blocksPerColumn = component.blocksPerColumn;\n const samplesPerLine = blocksPerLine << 3;\n const R = new Int32Array(64);\n const r = new Uint8Array(64);\n const lines = ArrayUtils.fill(\n blocksPerColumn * 8,\n undefined\n );\n\n let l = 0;\n for (let blockRow = 0; blockRow < blocksPerColumn; blockRow++) {\n const scanLine = blockRow << 3;\n for (let i = 0; i < 8; i++) {\n lines[l++] = new Uint8Array(samplesPerLine);\n }\n\n for (let blockCol = 0; blockCol < blocksPerLine; blockCol++) {\n JpegQuantize.quantizeAndInverse(\n component.quantizationTable!,\n component.blocks[blockRow][blockCol],\n r,\n R\n );\n\n let offset = 0;\n const sample = blockCol << 3;\n for (let j = 0; j < 8; j++) {\n const line = lines[scanLine + j];\n for (let i = 0; i < 8; i++) {\n line![sample + i] = r[offset++];\n }\n }\n }\n }\n\n return lines;\n }\n\n public static toFix(val: number): number {\n const fixedPoint = 20;\n const one = 1 << fixedPoint;\n return Math.trunc(val * one) & 0xffffffff;\n }\n\n private readBlock(): InputBuffer {\n const length = this._input.readUint16();\n if (length < 2) {\n throw new LibError('Invalid Block');\n }\n return this._input.readBytes(length - 2);\n }\n\n private nextMarker(): number {\n let c = 0;\n if (this._input.isEOS) {\n return c;\n }\n\n do {\n do {\n c = this._input.readByte();\n } while (c !== 0xff && !this._input.isEOS);\n\n if (this._input.isEOS) {\n return c;\n }\n\n do {\n c = this._input.readByte();\n } while (c === 0xff && !this._input.isEOS);\n } while (c === 0 && !this._input.isEOS);\n\n return c;\n }\n\n private readExifData(block: InputBuffer): void {\n // Exif Header\n // Exif\\0\\0\n const exifSignature = 0x45786966;\n const signature = block.readUint32();\n if (signature !== exifSignature) {\n return;\n }\n if (block.readUint16() !== 0) {\n return;\n }\n\n this.exifData.read(block);\n }\n\n private readAppData(marker: number, block: InputBuffer): void {\n const appData = block;\n\n if (marker === JpegMarker.app0) {\n // 'JFIF\\0'\n if (\n appData.getByte(0) === 0x4a &&\n appData.getByte(1) === 0x46 &&\n appData.getByte(2) === 0x49 &&\n appData.getByte(3) === 0x46 &&\n appData.getByte(4) === 0\n ) {\n const majorVersion = appData.getByte(5);\n const minorVersion = appData.getByte(6);\n const densityUnits = appData.getByte(7);\n const xDensity = (appData.getByte(8) << 8) | appData.getByte(9);\n const yDensity = (appData.getByte(10) << 8) | appData.getByte(11);\n const thumbWidth = appData.getByte(12);\n const thumbHeight = appData.getByte(13);\n\n const thumbSize = 3 * thumbWidth * thumbHeight;\n const thumbData = appData.subarray(14 + thumbSize, undefined, 14);\n\n this._jfif = new JpegJfif(\n thumbWidth,\n thumbHeight,\n majorVersion,\n minorVersion,\n densityUnits,\n xDensity,\n yDensity,\n thumbData\n );\n }\n } else if (marker === JpegMarker.app1) {\n // 'EXIF\\0'\n this.readExifData(appData);\n } else if (marker === JpegMarker.app14) {\n // 'Adobe\\0'\n if (\n appData.getByte(0) === 0x41 &&\n appData.getByte(1) === 0x64 &&\n appData.getByte(2) === 0x6f &&\n appData.getByte(3) === 0x62 &&\n appData.getByte(4) === 0x65 &&\n appData.getByte(5) === 0\n ) {\n const version = appData.getByte(6);\n const flags0 = (appData.getByte(7) << 8) | appData.getByte(8);\n const flags1 = (appData.getByte(9) << 8) | appData.getByte(10);\n const transformCode = appData.getByte(11);\n this._adobe = new JpegAdobe(version, flags0, flags1, transformCode);\n }\n } else if (marker === JpegMarker.com) {\n // Comment\n try {\n this._comment = appData.readStringUtf8();\n } catch (_) {\n // ReadString without 0x00 terminator causes exception. Technically\n // bad data, but no reason to abort the rest of the image decoding.\n }\n }\n }\n\n private readDQT(block: InputBuffer): void {\n while (!block.isEOS) {\n let n = block.readByte();\n const prec = n >> 4;\n n &= 0x0f;\n\n if (n >= JpegData.numQuantizationTables) {\n throw new LibError('Invalid number of quantization tables');\n }\n\n if (this._quantizationTables[n] === undefined) {\n this._quantizationTables[n] = new Int16Array(64);\n }\n\n const tableData = this._quantizationTables[n];\n if (tableData !== undefined) {\n for (let i = 0; i < JpegData.dctSize2; i++) {\n const tmp: number =\n prec !== 0 ? block.readUint16() : block.readByte();\n tableData[JpegData.dctZigZag[i]] = tmp;\n }\n }\n }\n\n if (!block.isEOS) {\n throw new LibError('Bad length for DQT block');\n }\n }\n\n private readFrame(marker: number, block: InputBuffer): void {\n if (this._frame !== undefined) {\n throw new LibError('Duplicate JPG frame data found.');\n }\n\n const extended = marker === JpegMarker.sof1;\n const progressive = marker === JpegMarker.sof2;\n const precision = block.readByte();\n const scanLines = block.readUint16();\n const samplesPerLine = block.readUint16();\n\n const numComponents = block.readByte();\n const components = new Map();\n const componentsOrder = new Array();\n for (let i = 0; i < numComponents; i++) {\n const componentId = block.readByte();\n const x = block.readByte();\n const h = (x >> 4) & 15;\n const v = x & 15;\n const qId = block.readByte();\n componentsOrder.push(componentId);\n const component = new JpegComponent(h, v, this._quantizationTables, qId);\n components.set(componentId, component);\n }\n\n this._frame = new JpegFrame(\n components,\n componentsOrder,\n extended,\n progressive,\n precision,\n scanLines,\n samplesPerLine\n );\n\n this._frame.prepare();\n\n this.frames.push(this._frame);\n }\n\n private readDHT(block: InputBuffer): void {\n while (!block.isEOS) {\n let index = block.readByte();\n\n const bits = new Uint8Array(16);\n let count = 0;\n for (let j = 0; j < 16; j++) {\n bits[j] = block.readByte();\n count += bits[j];\n }\n\n const huffmanValues = block.readBytes(count).toUint8Array();\n\n let ht: Array | undefined> = [];\n if ((index & 0x10) !== 0) {\n // AC table definition\n index -= 0x10;\n ht = this._huffmanTablesAC;\n } else {\n // DC table definition\n ht = this._huffmanTablesDC;\n }\n\n if (ht.length <= index) {\n ht.length = index + 1;\n }\n\n ht[index] = JpegData.buildHuffmanTable(bits, huffmanValues);\n }\n }\n\n private readDRI(block: InputBuffer): void {\n this._resetInterval = block.readUint16();\n }\n\n private readSOS(block: InputBuffer): void {\n const n = block.readByte();\n if (n < 1 || n > JpegData.maxCompsInScan) {\n throw new LibError('Invalid SOS block');\n }\n\n const components = new Array();\n for (let i = 0; i < n; i++) {\n const id = block.readByte();\n const c = block.readByte();\n\n if (!this._frame!.components.has(id)) {\n throw new LibError('Invalid Component in SOS block');\n }\n const component = this._frame!.components.get(id);\n if (component !== undefined) {\n const dcTableNumber = (c >> 4) & 15;\n const acTableNumber = c & 15;\n if (dcTableNumber < this._huffmanTablesDC.length) {\n component.huffmanTableDC = this._huffmanTablesDC[dcTableNumber]!;\n }\n if (acTableNumber < this._huffmanTablesAC.length) {\n component.huffmanTableAC = this._huffmanTablesAC[acTableNumber]!;\n }\n components.push(component);\n }\n }\n\n const spectralStart = block.readByte();\n const spectralEnd = block.readByte();\n const successiveApproximation = block.readByte();\n\n const ah = (successiveApproximation >> 4) & 15;\n const al = successiveApproximation & 15;\n\n const scan = new JpegScan(\n this._input,\n this._frame!,\n components,\n spectralStart,\n spectralEnd,\n ah,\n al,\n this._resetInterval\n );\n scan.decode();\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../common/input-buffer';\nimport { LibError } from '../error/lib-error';\nimport { MemoryImage } from '../image/image';\nimport { Decoder } from './decoder';\nimport { JpegData } from './jpeg/jpeg-data';\nimport { JpegInfo } from './jpeg/jpeg-info';\n\n/**\n * Decode a jpeg encoded image.\n */\nexport class JpegDecoder implements Decoder {\n private _input?: InputBuffer;\n private _info?: JpegInfo;\n\n public get numFrames(): number {\n return this._info !== undefined ? this._info.numFrames : 0;\n }\n\n /**\n * Is the given file a valid JPEG image?\n */\n public isValidFile(bytes: Uint8Array): boolean {\n return new JpegData().validate(bytes);\n }\n\n public startDecode(bytes: Uint8Array): JpegInfo | undefined {\n this._input = new InputBuffer({\n buffer: bytes,\n bigEndian: true,\n });\n this._info = new JpegData().readInfo(bytes);\n return this._info;\n }\n\n public decodeFrame(_: number): MemoryImage | undefined {\n if (this._input === undefined) {\n return undefined;\n }\n\n const jpeg = new JpegData();\n jpeg.read(this._input.buffer);\n if (jpeg.frames.length !== 1) {\n throw new LibError('Only single frame JPEGs supported.');\n }\n\n return jpeg.getImage();\n }\n\n public decode(bytes: Uint8Array, _frame?: number): MemoryImage | undefined {\n const jpeg = new JpegData();\n jpeg.read(bytes);\n\n if (jpeg.frames.length !== 1) {\n throw new LibError('Only single frame JPEGs supported.');\n }\n\n return jpeg.getImage();\n }\n}\n", "/** @format */\n\nimport { ArrayUtils } from '../common/array-utils';\nimport { MathUtils } from '../common/math-utils';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { ExifData } from '../exif/exif-data';\nimport { MemoryImage } from '../image/image';\nimport { Encoder } from './encoder';\nimport { JpegMarker } from './jpeg/jpeg-marker';\n\n/**\n * Encode an image to the JPEG format.\n */\nexport class JpegEncoder implements Encoder {\n private static readonly _zigzag: number[] = [\n 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25,\n 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54,\n 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48,\n 49, 57, 58, 62, 63,\n ];\n\n private static readonly _stdDcLuminanceNrCodes: number[] = [\n 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,\n ];\n\n private static readonly _stdDcLuminanceValues: number[] = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\n ];\n\n private static readonly _stdAcLuminanceNrCodes: number[] = [\n 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d,\n ];\n\n private static readonly _stdAcLuminanceValues: number[] = [\n 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,\n 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,\n 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,\n 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,\n 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,\n 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,\n 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75,\n 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,\n 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,\n 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,\n 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,\n 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,\n 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4,\n 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,\n ];\n\n private static readonly _stdDcChrominanceNrCodes: number[] = [\n 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,\n ];\n\n private static readonly _stdDcChrominanceValues: number[] = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\n ];\n\n private static readonly _stdAcChrominanceNrCodes: number[] = [\n 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77,\n ];\n\n private static readonly _stdAcChrominanceValues: number[] = [\n 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,\n 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,\n 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,\n 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,\n 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44,\n 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,\n 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74,\n 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,\n 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,\n 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,\n 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,\n 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,\n 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,\n 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,\n ];\n\n private readonly _tableY = new Uint8Array(64);\n private readonly _tableUv = new Uint8Array(64);\n private readonly _fdTableY = new Float32Array(64);\n private readonly _fdTableUv = new Float32Array(64);\n\n private readonly _bitCode = ArrayUtils.fill(\n 65535,\n undefined\n );\n private readonly _category = ArrayUtils.fill(\n 65535,\n undefined\n );\n private readonly _outputfDCTQuant = ArrayUtils.fill(\n 64,\n undefined\n );\n private readonly _du = ArrayUtils.fill(64, undefined);\n\n private readonly _ydu: Float32Array = new Float32Array(64);\n private readonly _udu: Float32Array = new Float32Array(64);\n private readonly _vdu: Float32Array = new Float32Array(64);\n private readonly _tableRgbYuv: Int32Array = new Int32Array(2048);\n\n private _ydcHuffman: Array | undefined> | undefined;\n private _uvdcHuffman: Array | undefined> | undefined;\n private _yacHuffman!: Array | undefined>;\n private _uvacHuffman!: Array | undefined>;\n\n private _currentQuality?: number;\n\n private _byteNew = 0;\n private _bytePos = 7;\n\n private _supportsAnimation = false;\n public get supportsAnimation(): boolean {\n return this._supportsAnimation;\n }\n\n constructor(quality = 100) {\n this.initHuffmanTable();\n this.initCategoryNumber();\n this.initRgbYuvTable();\n this.setQuality(quality);\n }\n\n private static computeHuffmanTable(\n nrcodes: number[],\n stdTable: number[]\n ): Array | undefined> {\n let codeValue = 0;\n let posInTable = 0;\n const ht = new Array | undefined>();\n for (let k = 1; k <= 16; k++) {\n for (let j = 1; j <= nrcodes[k]; j++) {\n const index = stdTable[posInTable];\n if (ht.length <= index) {\n ht.length = index + 1;\n }\n ht[index] = [codeValue, k];\n posInTable++;\n codeValue++;\n }\n codeValue *= 2;\n }\n return ht;\n }\n\n private static writeMarker(fp: OutputBuffer, marker: number): void {\n fp.writeByte(0xff);\n fp.writeByte(marker & 0xff);\n }\n\n private static writeAPP0(out: OutputBuffer): void {\n JpegEncoder.writeMarker(out, JpegMarker.app0);\n // Length\n out.writeUint16(16);\n // J\n out.writeByte(0x4a);\n // F\n out.writeByte(0x46);\n // I\n out.writeByte(0x49);\n // F\n out.writeByte(0x46);\n // '\\0'\n out.writeByte(0);\n // versionhi\n out.writeByte(1);\n // versionlo\n out.writeByte(1);\n // xyunits\n out.writeByte(0);\n // xdensity\n out.writeUint16(1);\n // ydensity\n out.writeUint16(1);\n // thumbnwidth\n out.writeByte(0);\n // thumbnheight\n out.writeByte(0);\n }\n\n private static writeAPP1(out: OutputBuffer, exif: ExifData): void {\n if (exif.isEmpty) {\n return;\n }\n\n const exifData = new OutputBuffer();\n exif.write(exifData);\n const exifBytes = exifData.getBytes();\n\n this.writeMarker(out, JpegMarker.app1);\n // Signature: Exif\\0\\0\n const exifSignature = 0x45786966;\n out.writeUint16(exifBytes.length + 8);\n out.writeUint32(exifSignature);\n out.writeUint16(0);\n out.writeBytes(exifBytes);\n }\n\n private static writeSOF0(\n out: OutputBuffer,\n width: number,\n height: number\n ): void {\n JpegEncoder.writeMarker(out, JpegMarker.sof0);\n // Length, truecolor YUV JPG\n out.writeUint16(17);\n // Precision\n out.writeByte(8);\n out.writeUint16(height);\n out.writeUint16(width);\n // nrofcomponents\n out.writeByte(3);\n // IdY\n out.writeByte(1);\n // HVY\n out.writeByte(0x11);\n // QTY\n out.writeByte(0);\n // IdU\n out.writeByte(2);\n // HVU\n out.writeByte(0x11);\n // QTU\n out.writeByte(1);\n // IdV\n out.writeByte(3);\n // HVV\n out.writeByte(0x11);\n // QTV\n out.writeByte(1);\n }\n\n private static writeSOS(out: OutputBuffer): void {\n JpegEncoder.writeMarker(out, JpegMarker.sos);\n // Length\n out.writeUint16(12);\n // Nrofcomponents\n out.writeByte(3);\n // IdY\n out.writeByte(1);\n // HTY\n out.writeByte(0);\n // IdU\n out.writeByte(2);\n // HTU\n out.writeByte(0x11);\n // IdV\n out.writeByte(3);\n // HTV\n out.writeByte(0x11);\n // Ss\n out.writeByte(0);\n // Se\n out.writeByte(0x3f);\n // Bf\n out.writeByte(0);\n }\n\n private static writeDHT(out: OutputBuffer): void {\n JpegEncoder.writeMarker(out, JpegMarker.dht);\n // Length\n out.writeUint16(0x01a2);\n\n // HTYDCinfo\n out.writeByte(0);\n for (let i = 0; i < 16; i++) {\n out.writeByte(JpegEncoder._stdDcLuminanceNrCodes[i + 1]);\n }\n for (let j = 0; j <= 11; j++) {\n out.writeByte(JpegEncoder._stdDcLuminanceValues[j]);\n }\n\n // HTYACinfo\n out.writeByte(0x10);\n for (let k = 0; k < 16; k++) {\n out.writeByte(JpegEncoder._stdAcLuminanceNrCodes[k + 1]);\n }\n for (let l = 0; l <= 161; l++) {\n out.writeByte(JpegEncoder._stdAcLuminanceValues[l]);\n }\n\n // HTUDCinfo\n out.writeByte(1);\n for (let m = 0; m < 16; m++) {\n out.writeByte(JpegEncoder._stdDcChrominanceNrCodes[m + 1]);\n }\n for (let n = 0; n <= 11; n++) {\n out.writeByte(JpegEncoder._stdDcChrominanceValues[n]);\n }\n\n // HTUACinfo\n out.writeByte(0x11);\n for (let o = 0; o < 16; o++) {\n out.writeByte(JpegEncoder._stdAcChrominanceNrCodes[o + 1]);\n }\n for (let p = 0; p <= 161; p++) {\n out.writeByte(JpegEncoder._stdAcChrominanceValues[p]);\n }\n }\n\n private initHuffmanTable(): void {\n this._ydcHuffman = JpegEncoder.computeHuffmanTable(\n JpegEncoder._stdDcLuminanceNrCodes,\n JpegEncoder._stdDcLuminanceValues\n );\n this._uvdcHuffman = JpegEncoder.computeHuffmanTable(\n JpegEncoder._stdDcChrominanceNrCodes,\n JpegEncoder._stdDcChrominanceValues\n );\n this._yacHuffman = JpegEncoder.computeHuffmanTable(\n JpegEncoder._stdAcLuminanceNrCodes,\n JpegEncoder._stdAcLuminanceValues\n );\n this._uvacHuffman = JpegEncoder.computeHuffmanTable(\n JpegEncoder._stdAcChrominanceNrCodes,\n JpegEncoder._stdAcChrominanceValues\n );\n }\n\n private initCategoryNumber(): void {\n let nrLower = 1;\n let nrUpper = 2;\n for (let cat = 1; cat <= 15; cat++) {\n // Positive numbers\n for (let nr = nrLower; nr < nrUpper; nr++) {\n this._category[32767 + nr] = cat;\n this._bitCode[32767 + nr] = [nr, cat];\n }\n // Negative numbers\n for (let nrneg = -(nrUpper - 1); nrneg <= -nrLower; nrneg++) {\n this._category[32767 + nrneg] = cat;\n this._bitCode[32767 + nrneg] = [nrUpper - 1 + nrneg, cat];\n }\n nrLower <<= 1;\n nrUpper <<= 1;\n }\n }\n\n private initRgbYuvTable(): void {\n for (let i = 0; i < 256; i++) {\n this._tableRgbYuv[i] = 19595 * i;\n this._tableRgbYuv[i + 256] = 38470 * i;\n this._tableRgbYuv[i + 512] = 7471 * i + 0x8000;\n this._tableRgbYuv[i + 768] = -11059 * i;\n this._tableRgbYuv[i + 1024] = -21709 * i;\n this._tableRgbYuv[i + 1280] = 32768 * i + 0x807fff;\n this._tableRgbYuv[i + 1536] = -27439 * i;\n this._tableRgbYuv[i + 1792] = -5329 * i;\n }\n }\n\n private setQuality(quality: number): void {\n const q = MathUtils.clampInt(quality, 1, 100);\n\n if (this._currentQuality === q) {\n // Don't re-calc if unchanged\n return;\n }\n\n let sf = 0;\n if (q < 50) {\n sf = Math.floor(5000 / q);\n } else {\n sf = Math.floor(200 - q * 2);\n }\n\n this.initQuantTables(sf);\n this._currentQuality = q;\n }\n\n private initQuantTables(sf: number): void {\n const yqt: number[] = [\n 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13,\n 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56,\n 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103,\n 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99,\n ];\n\n for (let i = 0; i < 64; i++) {\n let t = Math.floor((yqt[i] * sf + 50) / 100);\n if (t < 1) {\n t = 1;\n } else if (t > 255) {\n t = 255;\n }\n this._tableY[JpegEncoder._zigzag[i]] = t;\n }\n\n const uvqt: number[] = [\n 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26,\n 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,\n 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,\n 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,\n ];\n\n for (let j = 0; j < 64; j++) {\n let u = Math.floor((uvqt[j] * sf + 50) / 100);\n if (u < 1) {\n u = 1;\n } else if (u > 255) {\n u = 255;\n }\n this._tableUv[JpegEncoder._zigzag[j]] = u;\n }\n\n const aasf: number[] = [\n 1.0, 1.387039845, 1.306562965, 1.175875602, 1.0, 0.785694958, 0.5411961,\n 0.275899379,\n ];\n\n let k = 0;\n for (let row = 0; row < 8; row++) {\n for (let col = 0; col < 8; col++) {\n this._fdTableY[k] =\n 1 /\n (this._tableY[JpegEncoder._zigzag[k]] * aasf[row] * aasf[col] * 8.0);\n this._fdTableUv[k] =\n 1 /\n (this._tableUv[JpegEncoder._zigzag[k]] * aasf[row] * aasf[col] * 8.0);\n k++;\n }\n }\n }\n\n // DCT & quantization core\n private fDCTQuant(\n data: Float32Array,\n fdtbl: Float32Array\n ): Array {\n // Pass 1: process rows.\n let dataOff = 0;\n for (let i = 0; i < 8; ++i) {\n const d0 = data[dataOff];\n const d1 = data[dataOff + 1];\n const d2 = data[dataOff + 2];\n const d3 = data[dataOff + 3];\n const d4 = data[dataOff + 4];\n const d5 = data[dataOff + 5];\n const d6 = data[dataOff + 6];\n const d7 = data[dataOff + 7];\n\n const tmp0 = d0 + d7;\n const tmp7 = d0 - d7;\n const tmp1 = d1 + d6;\n const tmp6 = d1 - d6;\n const tmp2 = d2 + d5;\n const tmp5 = d2 - d5;\n const tmp3 = d3 + d4;\n const tmp4 = d3 - d4;\n\n // Even part\n // Phase 2\n let tmp10 = tmp0 + tmp3;\n const tmp13 = tmp0 - tmp3;\n let tmp11 = tmp1 + tmp2;\n let tmp12 = tmp1 - tmp2;\n\n // Phase 3\n data[dataOff] = tmp10 + tmp11;\n data[dataOff + 4] = tmp10 - tmp11;\n\n // C4\n const z1 = (tmp12 + tmp13) * 0.707106781;\n // Phase 5\n data[dataOff + 2] = tmp13 + z1;\n data[dataOff + 6] = tmp13 - z1;\n\n // Odd part\n // Phase 2\n tmp10 = tmp4 + tmp5;\n tmp11 = tmp5 + tmp6;\n tmp12 = tmp6 + tmp7;\n\n // The rotator is modified from fig 4-8 to avoid extra negations.\n // c6\n const z5 = (tmp10 - tmp12) * 0.382683433;\n // c2 - c6\n const z2 = 0.5411961 * tmp10 + z5;\n // c2 + c6\n const z4 = 1.306562965 * tmp12 + z5;\n // c4\n const z3 = tmp11 * 0.707106781;\n\n // Phase 5\n const z11 = tmp7 + z3;\n const z13 = tmp7 - z3;\n\n // Phase 6\n data[dataOff + 5] = z13 + z2;\n data[dataOff + 3] = z13 - z2;\n data[dataOff + 1] = z11 + z4;\n data[dataOff + 7] = z11 - z4;\n\n // Advance pointer to next row\n dataOff += 8;\n }\n\n // Pass 2: process columns.\n dataOff = 0;\n for (let i = 0; i < 8; ++i) {\n const d0 = data[dataOff];\n const d1 = data[dataOff + 8];\n const d2 = data[dataOff + 16];\n const d3 = data[dataOff + 24];\n const d4 = data[dataOff + 32];\n const d5 = data[dataOff + 40];\n const d6 = data[dataOff + 48];\n const d7 = data[dataOff + 56];\n\n const tmp0p2 = d0 + d7;\n const tmp7p2 = d0 - d7;\n const tmp1p2 = d1 + d6;\n const tmp6p2 = d1 - d6;\n const tmp2p2 = d2 + d5;\n const tmp5p2 = d2 - d5;\n const tmp3p2 = d3 + d4;\n const tmp4p2 = d3 - d4;\n\n // Even part\n // Phase 2\n let tmp10p2 = tmp0p2 + tmp3p2;\n const tmp13p2 = tmp0p2 - tmp3p2;\n let tmp11p2 = tmp1p2 + tmp2p2;\n let tmp12p2 = tmp1p2 - tmp2p2;\n\n // Phase 3\n data[dataOff] = tmp10p2 + tmp11p2;\n data[dataOff + 32] = tmp10p2 - tmp11p2;\n\n // c4\n const z1p2 = (tmp12p2 + tmp13p2) * 0.707106781;\n // Phase 5\n data[dataOff + 16] = tmp13p2 + z1p2;\n data[dataOff + 48] = tmp13p2 - z1p2;\n\n // Odd part\n // Phase 2\n tmp10p2 = tmp4p2 + tmp5p2;\n tmp11p2 = tmp5p2 + tmp6p2;\n tmp12p2 = tmp6p2 + tmp7p2;\n\n // The rotator is modified from fig 4-8 to avoid extra negations.\n // c6\n const z5p2 = (tmp10p2 - tmp12p2) * 0.382683433;\n // c2 - c6\n const z2p2 = 0.5411961 * tmp10p2 + z5p2;\n // c2 + c6\n const z4p2 = 1.306562965 * tmp12p2 + z5p2;\n // c4\n const z3p2 = tmp11p2 * 0.707106781;\n // Phase 5\n const z11p2 = tmp7p2 + z3p2;\n const z13p2 = tmp7p2 - z3p2;\n\n // Phase 6\n data[dataOff + 40] = z13p2 + z2p2;\n data[dataOff + 24] = z13p2 - z2p2;\n data[dataOff + 8] = z11p2 + z4p2;\n data[dataOff + 56] = z11p2 - z4p2;\n\n // Advance pointer to next column\n dataOff++;\n }\n\n // Quantize/descale the coefficients\n for (let i = 0; i < 64; ++i) {\n // Apply the quantization and scaling factor & Round to nearest integer\n const fDCTQuant = data[i] * fdtbl[i];\n this._outputfDCTQuant[i] =\n fDCTQuant > 0.0\n ? Math.trunc(fDCTQuant + 0.5)\n : Math.trunc(fDCTQuant - 0.5);\n }\n\n return this._outputfDCTQuant;\n }\n\n private writeDQT(out: OutputBuffer): void {\n JpegEncoder.writeMarker(out, JpegMarker.dqt);\n // Length\n out.writeUint16(132);\n out.writeByte(0);\n for (let i = 0; i < 64; i++) {\n out.writeByte(this._tableY[i]);\n }\n out.writeByte(1);\n for (let j = 0; j < 64; j++) {\n out.writeByte(this._tableUv[j]);\n }\n }\n\n private writeBits(out: OutputBuffer, bits: number[]): void {\n const value = bits[0];\n let posval = bits[1] - 1;\n while (posval >= 0) {\n if ((value & (1 << posval)) !== 0) {\n this._byteNew |= 1 << this._bytePos;\n }\n posval--;\n this._bytePos--;\n if (this._bytePos < 0) {\n if (this._byteNew === 0xff) {\n out.writeByte(0xff);\n out.writeByte(0);\n } else {\n out.writeByte(this._byteNew);\n }\n this._bytePos = 7;\n this._byteNew = 0;\n }\n }\n }\n\n private resetBits(): void {\n this._byteNew = 0;\n this._bytePos = 7;\n }\n\n private processDU(\n out: OutputBuffer,\n cdu: Float32Array,\n fdtbl: Float32Array,\n dc: number,\n htac: Array,\n htdc?: Array\n ): number | undefined {\n const eob = htac[0x00];\n const m16Zeroes = htac[0xf0];\n const I16 = 16;\n const I63 = 63;\n const I64 = 64;\n const duDct = this.fDCTQuant(cdu, fdtbl);\n let _dc = dc;\n let pos = 0;\n\n // ZigZag reorder\n for (let j = 0; j < I64; ++j) {\n this._du[JpegEncoder._zigzag[j]] = duDct[j];\n }\n\n const diff = this._du[0]! - _dc;\n _dc = this._du[0]!;\n // Encode DC\n if (diff === 0) {\n // Diff might be 0\n this.writeBits(out, htdc![0]!);\n } else {\n pos = 32767 + diff;\n this.writeBits(out, htdc![this._category[pos]!]!);\n this.writeBits(out, this._bitCode[pos]!);\n }\n\n // Encode ACs\n let end0pos = 63;\n // eslint-disable-next-line no-empty\n for (; end0pos > 0 && this._du[end0pos] === 0; end0pos--) {}\n //End0pos = first element in reverse order !=0\n if (end0pos === 0) {\n this.writeBits(out, eob!);\n return _dc;\n }\n\n let i = 1;\n while (i <= end0pos) {\n const startpos = i;\n // eslint-disable-next-line no-empty\n for (; this._du[i] === 0 && i <= end0pos; ++i) {}\n\n let nrzeroes = i - startpos;\n if (nrzeroes >= I16) {\n const lng = nrzeroes >> 4;\n for (let nrmarker = 1; nrmarker <= lng; ++nrmarker) {\n this.writeBits(out, m16Zeroes!);\n }\n nrzeroes &= 0xf;\n }\n pos = 32767 + this._du[i]!;\n this.writeBits(out, htac[(nrzeroes << 4) + this._category[pos]!]!);\n this.writeBits(out, this._bitCode[pos]!);\n i++;\n }\n\n if (end0pos !== I63) {\n this.writeBits(out, eob!);\n }\n\n return _dc;\n }\n\n public encode(image: MemoryImage, _singleFrame = false): Uint8Array {\n const fp = new OutputBuffer({\n bigEndian: true,\n });\n\n // Add JPEG headers\n JpegEncoder.writeMarker(fp, JpegMarker.soi);\n JpegEncoder.writeAPP0(fp);\n JpegEncoder.writeAPP1(fp, image.exifData);\n this.writeDQT(fp);\n JpegEncoder.writeSOF0(fp, image.width, image.height);\n JpegEncoder.writeDHT(fp);\n JpegEncoder.writeSOS(fp);\n\n // Encode 8x8 macroblocks\n let dcy: number | undefined = 0;\n let dcu: number | undefined = 0;\n let dcv: number | undefined = 0;\n\n this.resetBits();\n\n const width = image.width;\n const height = image.height;\n\n let y = 0;\n while (y < height) {\n let x = 0;\n while (x < width) {\n for (let pos = 0; pos < 64; pos++) {\n // / 8\n const row = pos >> 3;\n // % 8\n const col = pos & 7;\n\n let yy = y + row;\n let xx = x + col;\n\n if (yy >= height) {\n // padding bottom\n yy -= y + 1 + row - height;\n }\n\n if (xx >= width) {\n // padding right\n xx -= x + col - width + 1;\n }\n\n const p = image.getPixel(xx, yy);\n const r = Math.trunc(p.r);\n const g = Math.trunc(p.g);\n const b = Math.trunc(p.b);\n\n // calculate YUV values\n this._ydu[pos] =\n ((this._tableRgbYuv[r] +\n this._tableRgbYuv[g + 256] +\n this._tableRgbYuv[b + 512]) >>\n 16) -\n 128.0;\n\n this._udu[pos] =\n ((this._tableRgbYuv[r + 768] +\n this._tableRgbYuv[g + 1024] +\n this._tableRgbYuv[b + 1280]) >>\n 16) -\n 128.0;\n\n this._vdu[pos] =\n ((this._tableRgbYuv[r + 1280] +\n this._tableRgbYuv[g + 1536] +\n this._tableRgbYuv[b + 1792]) >>\n 16) -\n 128.0;\n }\n\n dcy = this.processDU(\n fp,\n this._ydu,\n this._fdTableY,\n dcy!,\n this._yacHuffman,\n this._ydcHuffman\n );\n dcu = this.processDU(\n fp,\n this._udu,\n this._fdTableUv,\n dcu!,\n this._uvacHuffman,\n this._uvdcHuffman\n );\n dcv = this.processDU(\n fp,\n this._vdu,\n this._fdTableUv,\n dcv!,\n this._uvacHuffman,\n this._uvdcHuffman\n );\n\n x += 8;\n }\n\n y += 8;\n }\n\n // Do the bit alignment of the EOI marker\n if (this._bytePos >= 0) {\n const fillBits = [(1 << (this._bytePos + 1)) - 1, this._bytePos + 1];\n this.writeBits(fp, fillBits);\n }\n\n JpegEncoder.writeMarker(fp, JpegMarker.eoi);\n\n return fp.getBytes();\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { OutputBuffer } from '../../common/output-buffer';\nimport { ExifData } from '../../exif/exif-data';\nimport { JpegMarker } from './jpeg-marker';\n\nexport class JpegUtils {\n // Exif\\0\\0\n private static readonly _exifSignature = 0x45786966;\n\n private readExifData(block: InputBuffer | undefined): ExifData | undefined {\n if (block === undefined) {\n return undefined;\n }\n\n // Exif Header\n const signature = block.readUint32();\n if (signature !== JpegUtils._exifSignature) {\n return undefined;\n }\n if (block.readUint16() !== 0) {\n return undefined;\n }\n\n return ExifData.fromInputBuffer(block);\n }\n\n private writeAPP1(out: OutputBuffer, exif: ExifData): void {\n if (exif.isEmpty) {\n return;\n }\n\n const exifData = new OutputBuffer();\n exif.write(exifData);\n const exifBytes = exifData.getBytes();\n\n out.writeUint16(exifBytes.length + 8);\n out.writeUint32(JpegUtils._exifSignature);\n out.writeUint16(0);\n out.writeBytes(exifBytes);\n }\n\n private readBlock(input: InputBuffer): InputBuffer | undefined {\n const length = input.readUint16();\n if (length < 2) {\n return undefined;\n }\n return input.readBytes(length - 2);\n }\n\n private skipBlock(input: InputBuffer, output?: OutputBuffer): boolean {\n const length = input.readUint16();\n output?.writeUint16(length);\n if (length < 2) {\n return false;\n }\n if (output !== undefined) {\n output.writeBuffer(input.readBytes(length - 2));\n } else {\n input.skip(length - 2);\n }\n return true;\n }\n\n private nextMarker(input: InputBuffer, output?: OutputBuffer): number {\n let c = 0;\n if (input.isEOS) {\n return c;\n }\n\n do {\n do {\n c = input.readByte();\n output?.writeByte(c);\n } while (c !== 0xff && !input.isEOS);\n\n if (input.isEOS) {\n return c;\n }\n\n do {\n c = input.readByte();\n output?.writeByte(c);\n } while (c === 0xff && !input.isEOS);\n } while (c === 0 && !input.isEOS);\n\n return c;\n }\n\n public decodeExif(data: Uint8Array): ExifData | undefined {\n const input = new InputBuffer({\n buffer: data,\n bigEndian: true,\n });\n\n // Some other formats have embedded jpeg, or jpeg-like data.\n // Only validate if the image starts with the StartOfImage tag.\n const soiCheck = input.peekBytes(2);\n if (soiCheck.getByte(0) !== 0xff || soiCheck.getByte(1) !== 0xd8) {\n return undefined;\n }\n\n let marker = this.nextMarker(input);\n if (marker !== JpegMarker.soi) {\n return undefined;\n }\n\n let exif: ExifData | undefined = undefined;\n marker = this.nextMarker(input);\n while (marker !== JpegMarker.eoi && !input.isEOS) {\n switch (marker) {\n case JpegMarker.app1:\n exif = this.readExifData(this.readBlock(input));\n if (exif !== undefined) {\n return exif;\n }\n break;\n default:\n this.skipBlock(input);\n break;\n }\n marker = this.nextMarker(input);\n }\n\n return undefined;\n }\n\n public injectExif(exif: ExifData, data: Uint8Array): Uint8Array | undefined {\n const input = new InputBuffer({\n buffer: data,\n bigEndian: true,\n });\n\n // Some other formats have embedded jpeg, or jpeg-like data.\n // Only validate if the image starts with the StartOfImage tag.\n const soiCheck = input.peekBytes(2);\n if (soiCheck.getByte(0) !== 0xff || soiCheck.getByte(1) !== 0xd8) {\n return undefined;\n }\n\n const output = new OutputBuffer({\n size: data.length,\n bigEndian: true,\n });\n\n let marker = this.nextMarker(input, output);\n if (marker !== JpegMarker.soi) {\n return undefined;\n }\n\n // Check to see if the JPEG file has an EXIF block\n let hasExifBlock = false;\n const startOffset = input.offset;\n marker = this.nextMarker(input);\n while (!hasExifBlock && marker !== JpegMarker.eoi && !input.isEOS) {\n if (marker === JpegMarker.app1) {\n const block = this.readBlock(input);\n const signature = block?.readUint32();\n if (signature === JpegUtils._exifSignature) {\n hasExifBlock = true;\n break;\n }\n } else {\n this.skipBlock(input);\n }\n marker = this.nextMarker(input);\n }\n\n input.offset = startOffset;\n\n // If the JPEG file does not have an EXIF block, add a new one.\n if (!hasExifBlock) {\n this.writeAPP1(output, exif);\n // No need to parse the remaining individual blocks, just write out\n // the remainder of the file.\n output.writeBuffer(input.readBytes(input.length));\n return output.getBytes();\n }\n\n marker = this.nextMarker(input, output);\n while (marker !== JpegMarker.eoi && !input.isEOS) {\n if (marker === JpegMarker.app1) {\n const saveOffset = input.offset;\n // block length\n input.skip(2);\n const signature = input.readUint32();\n input.offset = saveOffset;\n if (signature === JpegUtils._exifSignature) {\n this.skipBlock(input);\n this.writeAPP1(output, exif);\n // No need to parse the remaining individual blocks, just write out\n // the remainder of the file.\n output.writeBuffer(input.readBytes(input.length));\n return output.getBytes();\n }\n }\n this.skipBlock(input, output);\n marker = this.nextMarker(input, output);\n }\n\n return output.getBytes();\n }\n}\n", "/** @format */\n\nexport enum PngBlendMode {\n /**\n * No alpha blending should be done when drawing this frame (replace pixels in canvas).\n */\n source,\n\n /**\n * * Alpha blending should be used when drawing this frame (composited over\n * the current canvas image).\n */\n over,\n}\n", "/** @format */\n\nexport enum PngDisposeMode {\n none,\n background,\n previous,\n}\n", "/** @format */\n\nimport { PngBlendMode } from './png-blend-mode';\nimport { PngDisposeMode } from './png-dispose-mode';\n\nexport interface PngFrameInitOptions {\n sequenceNumber?: number;\n width?: number;\n height?: number;\n xOffset?: number;\n yOffset?: number;\n delayNum?: number;\n delayDen?: number;\n dispose?: number;\n blend?: number;\n}\n\n// Decodes a frame from a PNG animation.\nexport class PngFrame {\n private readonly _fdat: number[] = [];\n public get fdat(): number[] {\n return this._fdat;\n }\n\n private _sequenceNumber: number;\n public get sequenceNumber(): number {\n return this._sequenceNumber;\n }\n\n private _width: number;\n public get width(): number {\n return this._width;\n }\n\n private _height: number;\n public get height(): number {\n return this._height;\n }\n\n private _xOffset: number;\n public get xOffset(): number {\n return this._xOffset;\n }\n\n private _yOffset: number;\n public get yOffset(): number {\n return this._yOffset;\n }\n\n private _delayNum: number;\n public get delayNum(): number {\n return this._delayNum;\n }\n\n private _delayDen: number;\n public get delayDen(): number {\n return this._delayDen;\n }\n\n private _dispose: PngDisposeMode;\n public get dispose(): PngDisposeMode {\n return this._dispose;\n }\n\n private _blend: PngBlendMode;\n public get blend(): PngBlendMode {\n return this._blend;\n }\n\n public get delay() {\n if (this._delayNum === undefined || this._delayDen === undefined) {\n return 0;\n }\n if (this._delayDen === 0) {\n return 0;\n }\n return this._delayNum / this._delayDen;\n }\n\n constructor(opt: PngFrameInitOptions) {\n this._sequenceNumber = opt?.sequenceNumber ?? 0;\n this._width = opt?.width ?? 0;\n this._height = opt?.height ?? 0;\n this._xOffset = opt?.xOffset ?? 0;\n this._yOffset = opt?.yOffset ?? 0;\n this._delayNum = opt?.delayNum ?? 0;\n this._delayDen = opt?.delayDen ?? 0;\n this._dispose = opt?.dispose ?? PngDisposeMode.none;\n this._blend = opt?.blend ?? PngBlendMode.source;\n }\n}\n", "/** @format */\n\nimport { Color } from '../../color/color';\nimport { DecodeInfo } from '../decode-info';\nimport { PngColorType } from './png-color-type';\nimport { PngFrame } from './png-frame';\n\nexport interface PngInfoInitOptions {\n width?: number;\n height?: number;\n bits?: number;\n colorType?: number;\n compressionMethod?: number;\n filterMethod?: number;\n interlaceMethod?: number;\n}\n\nexport class PngInfo implements DecodeInfo {\n private _width = 0;\n public get width(): number {\n return this._width;\n }\n public set width(v: number) {\n this._width = v;\n }\n\n private _height = 0;\n public set height(v: number) {\n this._height = v;\n }\n public get height(): number {\n return this._height;\n }\n\n private _backgroundColor: Color | undefined = undefined;\n public get backgroundColor(): Color | undefined {\n return this._backgroundColor;\n }\n public set backgroundColor(v: Color | undefined) {\n this._backgroundColor = v;\n }\n\n private _numFrames = 1;\n public get numFrames(): number {\n return this._numFrames;\n }\n public set numFrames(v: number) {\n this._numFrames = v;\n }\n\n private _bits: number;\n public get bits(): number {\n return this._bits;\n }\n public set bits(v: number) {\n this._bits = v;\n }\n\n private _colorType: PngColorType | undefined;\n public get colorType(): PngColorType | undefined {\n return this._colorType;\n }\n public set colorType(v: PngColorType | undefined) {\n this._colorType = v;\n }\n\n private _compressionMethod: number;\n public get compressionMethod(): number {\n return this._compressionMethod;\n }\n public set compressionMethod(v: number) {\n this._compressionMethod = v;\n }\n\n private _filterMethod: number;\n public get filterMethod(): number {\n return this._filterMethod;\n }\n public set filterMethod(v: number) {\n this._filterMethod = v;\n }\n\n private _interlaceMethod: number;\n public get interlaceMethod(): number {\n return this._interlaceMethod;\n }\n public set interlaceMethod(v: number) {\n this._interlaceMethod = v;\n }\n\n private _palette?: Uint8Array;\n public get palette(): Uint8Array | undefined {\n return this._palette;\n }\n public set palette(v: Uint8Array | undefined) {\n this._palette = v;\n }\n\n private _transparency?: Uint8Array;\n public get transparency(): Uint8Array | undefined {\n return this._transparency;\n }\n public set transparency(v: Uint8Array | undefined) {\n this._transparency = v;\n }\n\n private _gamma?: number;\n public get gamma(): number | undefined {\n return this._gamma;\n }\n public set gamma(v: number | undefined) {\n this._gamma = v;\n }\n\n private _iccpName = '';\n public get iccpName(): string {\n return this._iccpName;\n }\n public set iccpName(v: string) {\n this._iccpName = v;\n }\n\n private _iccpCompression = 0;\n public get iccpCompression(): number {\n return this._iccpCompression;\n }\n public set iccpCompression(v: number) {\n this._iccpCompression = v;\n }\n\n private _iccpData?: Uint8Array;\n public get iccpData(): Uint8Array | undefined {\n return this._iccpData;\n }\n public set iccpData(v: Uint8Array | undefined) {\n this._iccpData = v;\n }\n\n private _textData: Map = new Map();\n public get textData(): Map {\n return this._textData;\n }\n\n private _repeat = 0;\n public get repeat(): number {\n return this._repeat;\n }\n public set repeat(v: number) {\n this._repeat = v;\n }\n\n private readonly _idat: number[] = [];\n public get idat(): number[] {\n return this._idat;\n }\n\n private readonly _frames: PngFrame[] = [];\n public get frames(): PngFrame[] {\n return this._frames;\n }\n\n public get isAnimated(): boolean {\n return this._frames.length > 0;\n }\n\n constructor(opt?: PngInfoInitOptions) {\n this._width = opt?.width ?? 0;\n this._height = opt?.height ?? 0;\n this._bits = opt?.bits ?? 0;\n this._colorType = opt?.colorType;\n this._compressionMethod = opt?.compressionMethod ?? 0;\n this._filterMethod = opt?.filterMethod ?? 0;\n this._interlaceMethod = opt?.interlaceMethod ?? 0;\n }\n}\n", "/** @format */\n\nexport enum TgaImageType {\n none,\n palette,\n rgb,\n gray,\n reserved4,\n reserved5,\n reserved6,\n reserved7,\n reserved8,\n paletteRle,\n rgbRle,\n grayRle,\n}\n\nexport const TgaImageTypeLength = 12;\n", "/** @format */\n\nimport { Color } from '../../color/color';\nimport { InputBuffer } from '../../common/input-buffer';\nimport { DecodeInfo } from '../decode-info';\nimport { TgaImageType, TgaImageTypeLength } from './tga-image-type';\n\nexport interface TgaInfoInitOptions {\n width?: number;\n height?: number;\n imageOffset?: number;\n bitsPerPixel?: number;\n}\n\nexport class TgaInfo implements DecodeInfo {\n /**\n * The number of frames that can be decoded.\n */\n private readonly _numFrames: number = 1;\n public get numFrames(): number {\n return this._numFrames;\n }\n\n private readonly _backgroundColor: Color | undefined = undefined;\n public get backgroundColor(): Color | undefined {\n return this._backgroundColor;\n }\n\n private _idLength = 0;\n public get idLength(): number {\n return this._idLength;\n }\n\n private _colorMapType = 0;\n public get colorMapType(): number {\n return this._colorMapType;\n }\n\n private _imageType: TgaImageType = TgaImageType.none;\n public get imageType(): TgaImageType {\n return this._imageType;\n }\n\n private _colorMapOrigin = 0;\n public get colorMapOrigin(): number {\n return this._colorMapOrigin;\n }\n\n private _colorMapLength = 0;\n public get colorMapLength(): number {\n return this._colorMapLength;\n }\n\n private _colorMapDepth = 0;\n public get colorMapDepth(): number {\n return this._colorMapDepth;\n }\n\n private _offsetX = 0;\n public get offsetX(): number {\n return this._offsetX;\n }\n\n private _offsetY = 0;\n public get offsetY(): number {\n return this._offsetY;\n }\n\n private _width = 0;\n public get width(): number {\n return this._width;\n }\n\n protected _height = 0;\n public get height(): number {\n return this._height;\n }\n\n protected _pixelDepth = 0;\n public get pixelDepth(): number {\n return this._pixelDepth;\n }\n\n protected _flags = 0;\n public get flags(): number {\n return this._flags;\n }\n\n protected _colorMap: Uint8Array | undefined;\n public get colorMap(): Uint8Array | undefined {\n return this._colorMap;\n }\n public set colorMap(v: Uint8Array | undefined) {\n this._colorMap = v;\n }\n\n protected _screenOrigin = 0;\n public get screenOrigin(): number {\n return this._screenOrigin;\n }\n\n /**\n * Offset in the input file the image data starts at.\n */\n private _imageOffset = 0;\n public get imageOffset(): number {\n return this._imageOffset;\n }\n public set imageOffset(v: number) {\n this._imageOffset = v;\n }\n\n public get hasColorMap(): boolean {\n return (\n this._imageType === TgaImageType.palette ||\n this._imageType === TgaImageType.paletteRle\n );\n }\n\n public read(header: InputBuffer): void {\n if (header.length < 18) {\n return;\n }\n // 0\n this._idLength = header.readByte();\n // 1\n this._colorMapType = header.readByte();\n const it = header.readByte();\n // 2\n this._imageType =\n it < TgaImageTypeLength ? (it as TgaImageType) : TgaImageType.none;\n // 3\n this._colorMapOrigin = header.readUint16();\n // 5\n this._colorMapLength = header.readUint16();\n // 7\n this._colorMapDepth = header.readByte();\n // 8\n this._offsetX = header.readUint16();\n // 10\n this._offsetY = header.readUint16();\n // 12\n this._width = header.readUint16();\n // 14\n this._height = header.readUint16();\n // 16\n this._pixelDepth = header.readByte();\n // 17\n this._flags = header.readByte();\n this._screenOrigin = (this._flags & 0x30) >> 4;\n }\n\n public isValid(): boolean {\n if (\n this._pixelDepth !== 8 &&\n this._pixelDepth !== 16 &&\n this._pixelDepth !== 24 &&\n this._pixelDepth !== 32\n ) {\n return false;\n }\n\n if (this.hasColorMap) {\n if (this._colorMapLength > 256 || this._colorMapType !== 1) {\n return false;\n }\n if (\n this._colorMapDepth !== 16 &&\n this._colorMapDepth !== 24 &&\n this._colorMapDepth !== 32\n ) {\n return false;\n }\n } else if (this._colorMapType === 1) {\n return false;\n }\n\n return true;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../common/input-buffer';\nimport { MemoryImage } from '../image/image';\nimport { Palette } from '../image/palette';\nimport { Decoder } from './decoder';\nimport { TgaImageType } from './tga/tga-image-type';\nimport { TgaInfo } from './tga/tga-info';\n\n/**\n * Decode a TGA image. This only supports the 24-bit and 32-bit uncompressed format.\n */\nexport class TgaDecoder implements Decoder {\n private _input: InputBuffer | undefined = undefined;\n private _info: TgaInfo | undefined = undefined;\n\n public get numFrames(): number {\n return this._info !== undefined ? 1 : 0;\n }\n\n private decodeColorMap(colorMap: Uint8Array, palette: Palette): void {\n if (this._info === undefined || this._input === undefined) {\n return;\n }\n\n const cm = new InputBuffer({\n buffer: colorMap,\n });\n\n if (this._info.colorMapDepth === 16) {\n const color = this._input.readUint16();\n const r = (color & 0x7c00) >> 7;\n const g = (color & 0x3e0) >> 2;\n const b = (color & 0x1f) << 3;\n const a = (color & 0x8000) !== 0 ? 0 : 255;\n for (let i = 0; i < this._info.colorMapLength; ++i) {\n palette.setRed(i, r);\n palette.setGreen(i, g);\n palette.setBlue(i, b);\n palette.setAlpha(i, a);\n }\n } else {\n const hasAlpha = this._info.colorMapDepth === 32;\n for (let i = 0; i < this._info.colorMapLength; ++i) {\n const b = cm.readByte();\n const g = cm.readByte();\n const r = cm.readByte();\n const a = hasAlpha ? cm.readByte() : 255;\n palette.setRed(i, r);\n palette.setGreen(i, g);\n palette.setBlue(i, b);\n palette.setAlpha(i, a);\n }\n }\n }\n\n private decodeRle(): MemoryImage | undefined {\n if (this._info === undefined || this._input === undefined) {\n return undefined;\n }\n\n const bpp = this._info.pixelDepth;\n const hasAlpha = bpp === 16 || bpp === 32;\n const image = new MemoryImage({\n width: this._info.width,\n height: this._info.height,\n numChannels: hasAlpha ? 4 : 3,\n withPalette: this._info.hasColorMap,\n });\n\n const rleBit = 0x80;\n const rleMask = 0x7f;\n\n if (image.palette !== undefined && this._info.colorMap !== undefined) {\n this.decodeColorMap(this._info.colorMap, image.palette);\n }\n\n const w = image.width;\n const h = image.height;\n let y = h - 1;\n let x = 0;\n while (!this._input.isEOS && y >= 0) {\n const c = this._input.readByte();\n const count = (c & rleMask) + 1;\n\n if ((c & rleBit) !== 0) {\n if (bpp === 8) {\n const r = this._input.readByte();\n for (let i = 0; i < count; ++i) {\n image.setPixelR(x++, y, r);\n if (x >= w) {\n x = 0;\n y--;\n if (y < 0) {\n break;\n }\n }\n }\n } else if (bpp === 16) {\n const color = this._input.readUint16();\n const r = (color & 0x7c00) >> 7;\n const g = (color & 0x3e0) >> 2;\n const b = (color & 0x1f) << 3;\n const a = (color & 0x8000) !== 0 ? 0 : 255;\n for (let i = 0; i < count; ++i) {\n image.setPixelRgba(x++, y, r, g, b, a);\n if (x >= w) {\n x = 0;\n y--;\n if (y < 0) {\n break;\n }\n }\n }\n } else {\n const b = this._input.readByte();\n const g = this._input.readByte();\n const r = this._input.readByte();\n const a = hasAlpha ? this._input.readByte() : 255;\n for (let i = 0; i < count; ++i) {\n image.setPixelRgba(x++, y, r, g, b, a);\n if (x >= w) {\n x = 0;\n y--;\n if (y < 0) {\n break;\n }\n }\n }\n }\n } else {\n if (bpp === 8) {\n for (let i = 0; i < count; ++i) {\n const r = this._input.readByte();\n image.setPixelR(x++, y, r);\n if (x >= w) {\n x = 0;\n y--;\n if (y < 0) {\n break;\n }\n }\n }\n } else if (bpp === 16) {\n for (let i = 0; i < count; ++i) {\n const color = this._input.readUint16();\n const r = (color & 0x7c00) >> 7;\n const g = (color & 0x3e0) >> 2;\n const b = (color & 0x1f) << 3;\n const a = (color & 0x8000) !== 0 ? 0 : 255;\n image.setPixelRgba(x++, y, r, g, b, a);\n if (this._input.isEOS) {\n break;\n }\n if (x >= w) {\n x = 0;\n y--;\n if (y < 0) {\n break;\n }\n }\n }\n } else {\n for (let i = 0; i < count; ++i) {\n const b = this._input.readByte();\n const g = this._input.readByte();\n const r = this._input.readByte();\n const a = hasAlpha ? this._input.readByte() : 255;\n image.setPixelRgba(x++, y, r, g, b, a);\n if (x >= w) {\n x = 0;\n y--;\n if (y < 0) {\n break;\n }\n }\n }\n }\n }\n\n if (x >= w) {\n x = 0;\n y--;\n if (y < 0) {\n break;\n }\n }\n }\n\n return image;\n }\n\n private decodeRgb(): MemoryImage | undefined {\n if (this._info === undefined || this._input === undefined) {\n return undefined;\n }\n\n this._input.offset = this._info.imageOffset;\n\n const bpp = this._info.pixelDepth;\n const hasAlpha =\n bpp === 16 ||\n bpp === 32 ||\n (this._info.hasColorMap &&\n (this._info.colorMapDepth === 16 || this._info.colorMapDepth === 32));\n\n const image = new MemoryImage({\n width: this._info.width,\n height: this._info.height,\n numChannels: hasAlpha ? 4 : 3,\n withPalette: this._info.hasColorMap,\n });\n\n if (this._info.hasColorMap) {\n this.decodeColorMap(this._info.colorMap!, image.palette!);\n }\n\n if (bpp === 8) {\n for (let y = image.height - 1; y >= 0; --y) {\n for (let x = 0; x < image.width; ++x) {\n const index = this._input.readByte();\n image.setPixelR(x, y, index);\n }\n }\n } else if (bpp === 16) {\n for (let y = image.height - 1; y >= 0; --y) {\n for (let x = 0; x < image.width; ++x) {\n const color = this._input.readUint16();\n const r = (color & 0x7c00) >> 7;\n const g = (color & 0x3e0) >> 2;\n const b = (color & 0x1f) << 3;\n const a = (color & 0x8000) !== 0 ? 0 : 255;\n image.setPixelRgba(x, y, r, g, b, a);\n }\n }\n } else {\n for (let y = image.height - 1; y >= 0; --y) {\n for (let x = 0; x < image.width; ++x) {\n const b = this._input.readByte();\n const g = this._input.readByte();\n const r = this._input.readByte();\n const a = hasAlpha ? this._input.readByte() : 255;\n image.setPixelRgba(x, y, r, g, b, a);\n }\n }\n }\n\n return image;\n }\n\n /**\n * Is the given file a valid TGA image?\n */\n public isValidFile(bytes: Uint8Array): boolean {\n const input = new InputBuffer({\n buffer: bytes,\n });\n\n this._info = new TgaInfo();\n this._info.read(input);\n return this._info.isValid();\n }\n\n public startDecode(bytes: Uint8Array): TgaInfo | undefined {\n this._info = new TgaInfo();\n this._input = new InputBuffer({ buffer: bytes });\n\n const header = this._input.readBytes(18);\n this._info.read(header);\n if (!this._info.isValid()) {\n return undefined;\n }\n\n this._input.skip(this._info.idLength);\n\n // Decode colormap\n if (this._info.hasColorMap) {\n const size = this._info.colorMapLength * (this._info.colorMapDepth >> 3);\n this._info.colorMap = this._input.readBytes(size).toUint8Array();\n }\n\n this._info.imageOffset = this._input.offset;\n\n return this._info;\n }\n\n public decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined {\n if (this.startDecode(bytes) === undefined) {\n return undefined;\n }\n\n return this.decodeFrame(frame ?? 0);\n }\n\n public decodeFrame(_frame: number): MemoryImage | undefined {\n if (this._info === undefined || this._input === undefined) {\n return undefined;\n }\n\n if (this._info.imageType === TgaImageType.rgb) {\n return this.decodeRgb();\n } else if (\n this._info.imageType === TgaImageType.rgbRle ||\n this._info.imageType === TgaImageType.paletteRle\n ) {\n return this.decodeRle();\n } else if (this._info.imageType === TgaImageType.palette) {\n return this.decodeRgb();\n }\n\n return undefined;\n }\n}\n", "/** @format */\n\nimport { OutputBuffer } from '../common/output-buffer';\nimport { MemoryImage } from '../image/image';\nimport { Encoder } from './encoder';\n\n/**\n * Encode a TGA image. This only supports the 24-bit uncompressed format.\n */\nexport class TgaEncoder implements Encoder {\n private _supportsAnimation = false;\n public get supportsAnimation(): boolean {\n return this._supportsAnimation;\n }\n\n public encode(image: MemoryImage, _singleFrame = false): Uint8Array {\n const out = new OutputBuffer({\n bigEndian: true,\n });\n\n const header = new Uint8Array(18);\n header.fill(0);\n\n header[2] = 2;\n header[12] = image.width & 0xff;\n header[13] = (image.width >> 8) & 0xff;\n header[14] = image.height & 0xff;\n header[15] = (image.height >> 8) & 0xff;\n const nc = image.palette?.numChannels ?? image.numChannels;\n header[16] = nc === 3 ? 24 : 32;\n\n out.writeBytes(header);\n\n if (nc === 4) {\n for (let y = image.height - 1; y >= 0; --y) {\n for (let x = 0; x < image.width; ++x) {\n const c = image.getPixel(x, y);\n out.writeByte(Math.trunc(c.b));\n out.writeByte(Math.trunc(c.g));\n out.writeByte(Math.trunc(c.r));\n out.writeByte(Math.trunc(c.a));\n }\n }\n } else {\n for (let y = image.height - 1; y >= 0; --y) {\n for (let x = 0; x < image.width; ++x) {\n const c = image.getPixel(x, y);\n out.writeByte(Math.trunc(c.b));\n out.writeByte(Math.trunc(c.g));\n out.writeByte(Math.trunc(c.r));\n }\n }\n }\n\n return out.getBytes();\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\n\nexport class TiffBitReader {\n private static readonly _bitMask = [0, 1, 3, 7, 15, 31, 63, 127, 255];\n\n private _bitBuffer = 0;\n\n private _bitPosition = 0;\n\n private _input: InputBuffer;\n\n constructor(input: InputBuffer) {\n this._input = input;\n }\n\n /**\n * Read a number of bits from the input stream.\n */\n public readBits(numBits: number): number {\n let nBits = numBits;\n if (nBits === 0) {\n return 0;\n }\n\n if (this._bitPosition === 0) {\n this._bitPosition = 8;\n this._bitBuffer = this._input.readByte();\n }\n\n let value = 0;\n\n while (nBits > this._bitPosition) {\n value =\n (value << this._bitPosition) +\n (this._bitBuffer & TiffBitReader._bitMask[this._bitPosition]);\n nBits -= this._bitPosition;\n this._bitPosition = 8;\n this._bitBuffer = this._input.readByte();\n }\n\n if (nBits > 0) {\n if (this._bitPosition === 0) {\n this._bitPosition = 8;\n this._bitBuffer = this._input.readByte();\n }\n\n value =\n (value << nBits) +\n ((this._bitBuffer >> (this._bitPosition - nBits)) &\n TiffBitReader._bitMask[nBits]);\n\n this._bitPosition -= nBits;\n }\n\n return value;\n }\n\n public readByte() {\n return this.readBits(8);\n }\n\n /**\n * Flush the rest of the bits in the buffer so the next read starts at the next byte.\n */\n public flushByte() {\n return (this._bitPosition = 0);\n }\n}\n", "/** @format */\n\nexport enum TiffCompression {\n none = 1,\n ccittRle = 2,\n ccittFax3 = 3,\n ccittFax4 = 4,\n lzw = 5,\n oldJpeg = 6,\n jpeg = 7,\n next = 32766,\n ccittRlew = 32771,\n packBits = 32773,\n thunderScan = 32809,\n it8ctpad = 32895,\n tt8lw = 32896,\n it8mp = 32897,\n it8bl = 32898,\n pixarFilm = 32908,\n pixarLog = 32909,\n deflate = 32946,\n zip = 8,\n dcs = 32947,\n jbig = 34661,\n sgiLog = 34676,\n sgiLog24 = 34677,\n jp2000 = 34712,\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { LibError } from '../../error/lib-error';\nimport { ExifImageTags } from '../../exif/exif-tag';\nimport { IfdValueType, IfdValueTypeSize } from '../../exif/ifd-value-type';\nimport { IfdAsciiValue } from '../../exif/ifd-value/ifd-ascii-value';\nimport { IfdByteValue } from '../../exif/ifd-value/ifd-byte-value';\nimport { IfdDoubleValue } from '../../exif/ifd-value/ifd-double-value';\nimport { IfdLongValue } from '../../exif/ifd-value/ifd-long-value';\nimport { IfdRationalValue } from '../../exif/ifd-value/ifd-rational-value';\nimport { IfdSByteValue } from '../../exif/ifd-value/ifd-sbyte-value';\nimport { IfdSingleValue } from '../../exif/ifd-value/ifd-single-value';\nimport { IfdSLongValue } from '../../exif/ifd-value/ifd-slong-value';\nimport { IfdSRationalValue } from '../../exif/ifd-value/ifd-srational-value';\nimport { IfdSShortValue } from '../../exif/ifd-value/ifd-sshort-value';\nimport { IfdValue } from '../../exif/ifd-value/ifd-value';\nimport { TiffImage } from './tiff-image';\n\nexport interface TiffEntryInitOptions {\n tag: number;\n type: number;\n count: number;\n p: InputBuffer;\n valueOffset: number;\n}\n\nexport class TiffEntry {\n private _tag: number;\n public get tag(): number {\n return this._tag;\n }\n\n private _type: IfdValueType;\n public get type(): IfdValueType {\n return this._type;\n }\n\n private _count: number;\n public get count(): number {\n return this._count;\n }\n\n private _valueOffset: number;\n public get valueOffset(): number {\n return this._valueOffset;\n }\n\n private _value: IfdValue | undefined;\n public get value(): IfdValue | undefined {\n return this._value;\n }\n\n private _p: InputBuffer;\n public get p(): InputBuffer {\n return this._p;\n }\n\n public get isValid(): boolean {\n return this._type !== IfdValueType.none;\n }\n\n public get typeSize(): number {\n return this.isValid ? IfdValueTypeSize[this._type] : 0;\n }\n\n public get isString(): boolean {\n return this._type === IfdValueType.ascii;\n }\n\n constructor(opt: TiffEntryInitOptions) {\n this._tag = opt.tag;\n this._type = opt.type;\n this._count = opt.count;\n this._p = opt.p;\n this._valueOffset = opt.valueOffset;\n }\n\n public read(): IfdValue | undefined {\n if (this._value !== undefined) {\n return this._value;\n }\n\n this._p.offset = this._valueOffset;\n const data = this.p.readBytes(this._count * this.typeSize);\n switch (this._type) {\n case IfdValueType.byte:\n return (this._value = IfdByteValue.data(data, this._count));\n case IfdValueType.ascii:\n return (this._value = IfdAsciiValue.data(data, this._count));\n case IfdValueType.undefined:\n return (this._value = IfdByteValue.data(data, this._count));\n case IfdValueType.short:\n return (this._value = IfdSShortValue.data(data, this._count));\n case IfdValueType.long:\n return (this._value = IfdLongValue.data(data, this._count));\n case IfdValueType.rational:\n return (this._value = IfdRationalValue.data(data, this._count));\n case IfdValueType.single:\n return (this._value = IfdSingleValue.data(data, this._count));\n case IfdValueType.double:\n return (this._value = IfdDoubleValue.data(data, this._count));\n case IfdValueType.sByte:\n return (this._value = IfdSByteValue.data(data, this._count));\n case IfdValueType.sShort:\n return (this._value = IfdSShortValue.data(data, this._count));\n case IfdValueType.sLong:\n return (this._value = IfdSLongValue.data(data, this._count));\n case IfdValueType.sRational:\n return (this._value = IfdSRationalValue.data(data, this._count));\n default:\n case IfdValueType.none:\n return undefined;\n }\n }\n\n public toString(): string {\n const exifTag = ExifImageTags.get(this._tag);\n if (exifTag !== undefined) {\n return `${exifTag.name}: ${this._type} ${this._count}`;\n }\n return `${this.constructor.name} (<${this._tag}>: ${this._type} ${this._count})`;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { LibError } from '../../error/lib-error';\n\nexport interface TiffFaxDecoderInitOptions {\n fillOrder: number;\n width: number;\n height: number;\n}\n\nexport class TiffFaxDecoder {\n private static readonly _table1: number[] = [\n // 0 bits are left in first byte - SHOULD NOT HAPPEN\n 0x00,\n // 1 bits are left in first byte\n 0x01,\n // 2 bits are left in first byte\n 0x03,\n // 3 bits are left in first byte\n 0x07,\n // 4 bits are left in first byte\n 0x0f,\n // 5 bits are left in first byte\n 0x1f,\n // 6 bits are left in first byte\n 0x3f,\n // 7 bits are left in first byte\n 0x7f,\n // 8 bits are left in first byte\n 0xff,\n ];\n\n private static readonly _table2: number[] = [\n // 0\n 0x00,\n // 1\n 0x80,\n // 2\n 0xc0,\n // 3\n 0xe0,\n // 4\n 0xf0,\n // 5\n 0xf8,\n // 6\n 0xfc,\n // 7\n 0xfe,\n // 8\n 0xff,\n ];\n\n /**\n * Table to be used when **fillOrder** = 2, for flipping bytes.\n */\n private static readonly _flipTable: number[] = [\n 0, -128, 64, -64, 32, -96, 96, -32, 16, -112, 80, -48, 48, -80, 112, -16, 8,\n -120, 72, -56, 40, -88, 104, -24, 24, -104, 88, -40, 56, -72, 120, -8, 4,\n -124, 68, -60, 36, -92, 100, -28, 20, -108, 84, -44, 52, -76, 116, -12, 12,\n -116, 76, -52, 44, -84, 108, -20, 28, -100, 92, -36, 60, -68, 124, -4, 2,\n -126, 66, -62, 34, -94, 98, -30, 18, -110, 82, -46, 50, -78, 114, -14, 10,\n -118, 74, -54, 42, -86, 106, -22, 26, -102, 90, -38, 58, -70, 122, -6, 6,\n -122, 70, -58, 38, -90, 102, -26, 22, -106, 86, -42, 54, -74, 118, -10, 14,\n -114, 78, -50, 46, -82, 110, -18, 30, -98, 94, -34, 62, -66, 126, -2, 1,\n -127, 65, -63, 33, -95, 97, -31, 17, -111, 81, -47, 49, -79, 113, -15, 9,\n -119, 73, -55, 41, -87, 105, -23, 25, -103, 89, -39, 57, -71, 121, -7, 5,\n -123, 69, -59, 37, -91, 101, -27, 21, -107, 85, -43, 53, -75, 117, -11, 13,\n -115, 77, -51, 45, -83, 109, -19, 29, -99, 93, -35, 61, -67, 125, -3, 3,\n -125, 67, -61, 35, -93, 99, -29, 19, -109, 83, -45, 51, -77, 115, -13, 11,\n -117, 75, -53, 43, -85, 107, -21, 27, -101, 91, -37, 59, -69, 123, -5, 7,\n -121, 71, -57, 39, -89, 103, -25, 23, -105, 87, -41, 55, -73, 119, -9, 15,\n -113, 79, -49, 47, -81, 111, -17, 31, -97, 95, -33, 63, -65, 127, -1,\n ];\n\n /**\n * The main 10 bit white runs lookup table\n */\n private static readonly _white: number[] = [\n // 0 - 7\n 6430, 6400, 6400, 6400, 3225, 3225, 3225, 3225,\n // 8 - 15\n 944, 944, 944, 944, 976, 976, 976, 976,\n // 16 - 23\n 1456, 1456, 1456, 1456, 1488, 1488, 1488, 1488,\n // 24 - 31\n 718, 718, 718, 718, 718, 718, 718, 718,\n // 32 - 39\n 750, 750, 750, 750, 750, 750, 750, 750,\n // 40 - 47\n 1520, 1520, 1520, 1520, 1552, 1552, 1552, 1552,\n // 48 - 55\n 428, 428, 428, 428, 428, 428, 428, 428,\n // 56 - 63\n 428, 428, 428, 428, 428, 428, 428, 428,\n // 64 - 71\n 654, 654, 654, 654, 654, 654, 654, 654,\n // 72 - 79\n 1072, 1072, 1072, 1072, 1104, 1104, 1104, 1104,\n // 80 - 87\n 1136, 1136, 1136, 1136, 1168, 1168, 1168, 1168,\n // 88 - 95\n 1200, 1200, 1200, 1200, 1232, 1232, 1232, 1232,\n // 96 - 103\n 622, 622, 622, 622, 622, 622, 622, 622,\n // 104 - 111\n 1008, 1008, 1008, 1008, 1040, 1040, 1040, 1040,\n // 112 - 119\n 44, 44, 44, 44, 44, 44, 44, 44,\n // 120 - 127\n 44, 44, 44, 44, 44, 44, 44, 44,\n // 128 - 135\n 396, 396, 396, 396, 396, 396, 396, 396,\n // 136 - 143\n 396, 396, 396, 396, 396, 396, 396, 396,\n // 144 - 151\n 1712, 1712, 1712, 1712, 1744, 1744, 1744, 1744,\n // 152 - 159\n 846, 846, 846, 846, 846, 846, 846, 846,\n // 160 - 167\n 1264, 1264, 1264, 1264, 1296, 1296, 1296, 1296,\n // 168 - 175\n 1328, 1328, 1328, 1328, 1360, 1360, 1360, 1360,\n // 176 - 183\n 1392, 1392, 1392, 1392, 1424, 1424, 1424, 1424,\n // 184 - 191\n 686, 686, 686, 686, 686, 686, 686, 686,\n // 192 - 199\n 910, 910, 910, 910, 910, 910, 910, 910,\n // 200 - 207\n 1968, 1968, 1968, 1968, 2000, 2000, 2000, 2000,\n // 208 - 215\n 2032, 2032, 2032, 2032, 16, 16, 16, 16,\n // 216 - 223\n 10257, 10257, 10257, 10257, 12305, 12305, 12305, 12305,\n // 224 - 231\n 330, 330, 330, 330, 330, 330, 330, 330,\n // 232 - 239\n 330, 330, 330, 330, 330, 330, 330, 330,\n // 240 - 247\n 330, 330, 330, 330, 330, 330, 330, 330,\n // 248 - 255\n 330, 330, 330, 330, 330, 330, 330, 330,\n // 256 - 263\n 362, 362, 362, 362, 362, 362, 362, 362,\n // 264 - 271\n 362, 362, 362, 362, 362, 362, 362, 362,\n // 272 - 279\n 362, 362, 362, 362, 362, 362, 362, 362,\n // 280 - 287\n 362, 362, 362, 362, 362, 362, 362, 362,\n // 288 - 295\n 878, 878, 878, 878, 878, 878, 878, 878,\n // 296 - 303\n 1904, 1904, 1904, 1904, 1936, 1936, 1936, 1936,\n // 304 - 311\n -18413, -18413, -16365, -16365, -14317, -14317, -10221, -10221,\n // 312 - 319\n 590, 590, 590, 590, 590, 590, 590, 590,\n // 320 - 327\n 782, 782, 782, 782, 782, 782, 782, 782,\n // 328 - 335\n 1584, 1584, 1584, 1584, 1616, 1616, 1616, 1616,\n // 336 - 343\n 1648, 1648, 1648, 1648, 1680, 1680, 1680, 1680,\n // 344 - 351\n 814, 814, 814, 814, 814, 814, 814, 814,\n // 352 - 359\n 1776, 1776, 1776, 1776, 1808, 1808, 1808, 1808,\n // 360 - 367\n 1840, 1840, 1840, 1840, 1872, 1872, 1872, 1872,\n // 368 - 375\n 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157,\n // 376 - 383\n 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157,\n // 384 - 391\n -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275,\n // 392 - 399\n -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275,\n // 400 - 407\n 14353, 14353, 14353, 14353, 16401, 16401, 16401, 16401,\n // 408 - 415\n 22547, 22547, 24595, 24595, 20497, 20497, 20497, 20497,\n // 416 - 423\n 18449, 18449, 18449, 18449, 26643, 26643, 28691, 28691,\n // 424 - 431\n 30739, 30739, -32749, -32749, -30701, -30701, -28653, -28653,\n // 432 - 439\n -26605, -26605, -24557, -24557, -22509, -22509, -20461, -20461,\n // 440 - 447\n 8207, 8207, 8207, 8207, 8207, 8207, 8207, 8207,\n // 448 - 455\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 456 - 463\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 464 - 471\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 472 - 479\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 480 - 487\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 488 - 495\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 496 - 503\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 504 - 511\n 72, 72, 72, 72, 72, 72, 72, 72,\n // 512 - 519\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 520 - 527\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 528 - 535\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 536 - 543\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 544 - 551\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 552 - 559\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 560 - 567\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 568 - 575\n 104, 104, 104, 104, 104, 104, 104, 104,\n // 576 - 583\n 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,\n // 584 - 591\n 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,\n // 592 - 599\n 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,\n // 600 - 607\n 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,\n // 608 - 615\n 266, 266, 266, 266, 266, 266, 266, 266,\n // 616 - 623\n 266, 266, 266, 266, 266, 266, 266, 266,\n // 624 - 631\n 266, 266, 266, 266, 266, 266, 266, 266,\n // 632 - 639\n 266, 266, 266, 266, 266, 266, 266, 266,\n // 640 - 647\n 298, 298, 298, 298, 298, 298, 298, 298,\n // 648 - 655\n 298, 298, 298, 298, 298, 298, 298, 298,\n // 656 - 663\n 298, 298, 298, 298, 298, 298, 298, 298,\n // 664 - 671\n 298, 298, 298, 298, 298, 298, 298, 298,\n // 672 - 679\n 524, 524, 524, 524, 524, 524, 524, 524,\n // 680 - 687\n 524, 524, 524, 524, 524, 524, 524, 524,\n // 688 - 695\n 556, 556, 556, 556, 556, 556, 556, 556,\n // 696 - 703\n 556, 556, 556, 556, 556, 556, 556, 556,\n // 704 - 711\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 712 - 719\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 720 - 727\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 728 - 735\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 736 - 743\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 744 - 751\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 752 - 759\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 760 - 767\n 136, 136, 136, 136, 136, 136, 136, 136,\n // 768 - 775\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 776 - 783\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 784 - 791\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 792 - 799\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 800 - 807\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 808 - 815\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 816 - 823\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 824 - 831\n 168, 168, 168, 168, 168, 168, 168, 168,\n // 832 - 839\n 460, 460, 460, 460, 460, 460, 460, 460,\n // 840 - 847\n 460, 460, 460, 460, 460, 460, 460, 460,\n // 848 - 855\n 492, 492, 492, 492, 492, 492, 492, 492,\n // 856 - 863\n 492, 492, 492, 492, 492, 492, 492, 492,\n // 864 - 871\n 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,\n // 872 - 879\n 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,\n // 880 - 887\n 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,\n // 888 - 895\n 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,\n // 896 - 903\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 904 - 911\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 912 - 919\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 920 - 927\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 928 - 935\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 936 - 943\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 944 - 951\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 952 - 959\n 200, 200, 200, 200, 200, 200, 200, 200,\n // 960 - 967\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 968 - 975\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 976 - 983\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 984 - 991\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 992 - 999\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 1000 - 1007\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 1008 - 1015\n 232, 232, 232, 232, 232, 232, 232, 232,\n // 1016 - 1023\n 232, 232, 232, 232, 232, 232, 232, 232,\n ];\n\n /**\n * Additional make up codes for both White and Black runs\n */\n private static readonly _additionalMakeup: number[] = [\n 28679, 28679, 31752, -32759, -31735, -30711, -29687, -28663, 29703, 29703,\n 30727, 30727, -27639, -26615, -25591, -24567,\n ];\n\n /**\n * Initial black run look up table, uses the first 4 bits of a code\n */\n private static readonly _initBlack: number[] = [\n // 0 - 7\n 3226, 6412, 200, 168, 38, 38, 134, 134,\n // 8 - 15\n 100, 100, 100, 100, 68, 68, 68, 68,\n ];\n\n private static readonly _twoBitBlack: number[] = [292, 260, 226, 226];\n\n /**\n * Main black run table, using the last 9 bits of possible 13 bit code\n */\n private static readonly _black: number[] = [\n // 0 - 7\n 62, 62, 30, 30, 0, 0, 0, 0,\n // 8 - 15\n 0, 0, 0, 0, 0, 0, 0, 0,\n // 16 - 23\n 0, 0, 0, 0, 0, 0, 0, 0,\n // 24 - 31\n 0, 0, 0, 0, 0, 0, 0, 0,\n // 32 - 39\n 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,\n // 40 - 47\n 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,\n // 48 - 55\n 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,\n // 56 - 63\n 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,\n // 64 - 71\n 588, 588, 588, 588, 588, 588, 588, 588,\n // 72 - 79\n 1680, 1680, 20499, 22547, 24595, 26643, 1776, 1776,\n // 80 - 87\n 1808, 1808, -24557, -22509, -20461, -18413, 1904, 1904,\n // 88 - 95\n 1936, 1936, -16365, -14317, 782, 782, 782, 782,\n // 96 - 103\n 814, 814, 814, 814, -12269, -10221, 10257, 10257,\n // 104 - 111\n 12305, 12305, 14353, 14353, 16403, 18451, 1712, 1712,\n // 112 - 119\n 1744, 1744, 28691, 30739, -32749, -30701, -28653, -26605,\n // 120 - 127\n 2061, 2061, 2061, 2061, 2061, 2061, 2061, 2061,\n // 128 - 135\n 424, 424, 424, 424, 424, 424, 424, 424,\n // 136 - 143\n 424, 424, 424, 424, 424, 424, 424, 424,\n // 144 - 151\n 424, 424, 424, 424, 424, 424, 424, 424,\n // 152 - 159\n 424, 424, 424, 424, 424, 424, 424, 424,\n // 160 - 167\n 750, 750, 750, 750, 1616, 1616, 1648, 1648,\n // 168 - 175\n 1424, 1424, 1456, 1456, 1488, 1488, 1520, 1520,\n // 176 - 183\n 1840, 1840, 1872, 1872, 1968, 1968, 8209, 8209,\n // 184 - 191\n 524, 524, 524, 524, 524, 524, 524, 524,\n // 192 - 199\n 556, 556, 556, 556, 556, 556, 556, 556,\n // 200 - 207\n 1552, 1552, 1584, 1584, 2000, 2000, 2032, 2032,\n // 208 - 215\n 976, 976, 1008, 1008, 1040, 1040, 1072, 1072,\n // 216 - 223\n 1296, 1296, 1328, 1328, 718, 718, 718, 718,\n // 224 - 231\n 456, 456, 456, 456, 456, 456, 456, 456,\n // 232 - 239\n 456, 456, 456, 456, 456, 456, 456, 456,\n // 240 - 247\n 456, 456, 456, 456, 456, 456, 456, 456,\n // 248 - 255\n 456, 456, 456, 456, 456, 456, 456, 456,\n // 256 - 263\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 264 - 271\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 272 - 279\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 280 - 287\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 288 - 295\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 296 - 303\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 304 - 311\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 312 - 319\n 326, 326, 326, 326, 326, 326, 326, 326,\n // 320 - 327\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 328 - 335\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 336 - 343\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 344 - 351\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 352 - 359\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 360 - 367\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 368 - 375\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 376 - 383\n 358, 358, 358, 358, 358, 358, 358, 358,\n // 384 - 391\n 490, 490, 490, 490, 490, 490, 490, 490,\n // 392 - 399\n 490, 490, 490, 490, 490, 490, 490, 490,\n // 400 - 407\n 4113, 4113, 6161, 6161, 848, 848, 880, 880,\n // 408 - 415\n 912, 912, 944, 944, 622, 622, 622, 622,\n // 416 - 423\n 654, 654, 654, 654, 1104, 1104, 1136, 1136,\n // 424 - 431\n 1168, 1168, 1200, 1200, 1232, 1232, 1264, 1264,\n // 432 - 439\n 686, 686, 686, 686, 1360, 1360, 1392, 1392,\n // 440 - 447\n 12, 12, 12, 12, 12, 12, 12, 12,\n // 448 - 455\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 456 - 463\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 464 - 471\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 472 - 479\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 480 - 487\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 488 - 495\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 496 - 503\n 390, 390, 390, 390, 390, 390, 390, 390,\n // 504 - 511\n 390, 390, 390, 390, 390, 390, 390, 390,\n ];\n\n private static readonly _twoDCodes: number[] = [\n // 0 - 7\n 80, 88, 23, 71, 30, 30, 62, 62,\n // 8 - 15\n 4, 4, 4, 4, 4, 4, 4, 4,\n // 16 - 23\n 11, 11, 11, 11, 11, 11, 11, 11,\n // 24 - 31\n 11, 11, 11, 11, 11, 11, 11, 11,\n // 32 - 39\n 35, 35, 35, 35, 35, 35, 35, 35,\n // 40 - 47\n 35, 35, 35, 35, 35, 35, 35, 35,\n // 48 - 55\n 51, 51, 51, 51, 51, 51, 51, 51,\n // 56 - 63\n 51, 51, 51, 51, 51, 51, 51, 51,\n // 64 - 71\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 72 - 79\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 80 - 87\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 88 - 95\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 96 - 103\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 104 - 111\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 112 - 119\n 41, 41, 41, 41, 41, 41, 41, 41,\n // 120 - 127\n 41, 41, 41, 41, 41, 41, 41, 41,\n ];\n\n private _width: number;\n public get width(): number {\n return this._width;\n }\n\n private _height: number;\n public get height(): number {\n return this._height;\n }\n\n private _fillOrder: number;\n public get fillOrder(): number {\n return this._fillOrder;\n }\n\n // Data structures needed to store changing elements for the previous\n // and the current scanline\n private _changingElemSize = 0;\n private _prevChangingElements?: Array;\n private _currChangingElements?: Array;\n private _data!: InputBuffer;\n private _bitPointer = 0;\n private _bytePointer = 0;\n\n // Element at which to start search in getNextChangingElement\n private _lastChangingElement = 0;\n private _compression = 2;\n\n // Variables set by T4Options\n private _uncompressedMode = 0;\n private _fillBits = 0;\n private _oneD = 0;\n\n constructor(opt: TiffFaxDecoderInitOptions) {\n this._fillOrder = opt.fillOrder;\n this._width = opt.width;\n this._height = opt.height;\n this._prevChangingElements = new Array(this._width);\n this._prevChangingElements.fill(0);\n this._currChangingElements = new Array(this._width);\n this._currChangingElements.fill(0);\n }\n\n private nextNBits(bitsToGet: number): number {\n let b = 0;\n let next = 0;\n let next2next = 0;\n const l = this._data.length - 1;\n const bp = this._bytePointer;\n\n if (this._fillOrder === 1) {\n b = this._data.getByte(bp);\n\n if (bp === l) {\n next = 0x00;\n next2next = 0x00;\n } else if (bp + 1 === l) {\n next = this._data.getByte(bp + 1);\n next2next = 0x00;\n } else {\n next = this._data.getByte(bp + 1);\n next2next = this._data.getByte(bp + 2);\n }\n } else if (this._fillOrder === 2) {\n b = TiffFaxDecoder._flipTable[this._data.getByte(bp) & 0xff];\n\n if (bp === l) {\n next = 0x00;\n next2next = 0x00;\n } else if (bp + 1 === l) {\n next = TiffFaxDecoder._flipTable[this._data.getByte(bp + 1) & 0xff];\n next2next = 0x00;\n } else {\n next = TiffFaxDecoder._flipTable[this._data.getByte(bp + 1) & 0xff];\n next2next =\n TiffFaxDecoder._flipTable[this._data.getByte(bp + 2) & 0xff];\n }\n } else {\n throw new LibError('TIFFFaxDecoder7');\n }\n\n const bitsLeft = 8 - this._bitPointer;\n let bitsFromNextByte = bitsToGet - bitsLeft;\n let bitsFromNext2NextByte = 0;\n if (bitsFromNextByte > 8) {\n bitsFromNext2NextByte = bitsFromNextByte - 8;\n bitsFromNextByte = 8;\n }\n\n this._bytePointer = this._bytePointer! + 1;\n\n const i1 = (b & TiffFaxDecoder._table1[bitsLeft]) << (bitsToGet - bitsLeft);\n let i2 =\n (next & TiffFaxDecoder._table2[bitsFromNextByte]) >>\n (8 - bitsFromNextByte);\n\n let i3 = 0;\n if (bitsFromNext2NextByte !== 0) {\n i2 <<= bitsFromNext2NextByte;\n i3 =\n (next2next & TiffFaxDecoder._table2[bitsFromNext2NextByte]) >>\n (8 - bitsFromNext2NextByte);\n i2 |= i3;\n this._bytePointer += 1;\n this._bitPointer = bitsFromNext2NextByte;\n } else {\n if (bitsFromNextByte === 8) {\n this._bitPointer = 0;\n this._bytePointer += 1;\n } else {\n this._bitPointer = bitsFromNextByte;\n }\n }\n\n return i1 | i2;\n }\n\n private nextLesserThan8Bits(bitsToGet: number): number {\n let b = 0;\n let next = 0;\n const l = this._data.length - 1;\n const bp = this._bytePointer;\n\n if (this._fillOrder === 1) {\n b = this._data.getByte(bp);\n if (bp === l) {\n next = 0x00;\n } else {\n next = this._data.getByte(bp + 1);\n }\n } else if (this._fillOrder === 2) {\n b = TiffFaxDecoder._flipTable[this._data.getByte(bp) & 0xff];\n if (bp === l) {\n next = 0x00;\n } else {\n next = TiffFaxDecoder._flipTable[this._data.getByte(bp + 1) & 0xff];\n }\n } else {\n throw new LibError('TIFFFaxDecoder7');\n }\n\n const bitsLeft = 8 - this._bitPointer;\n const bitsFromNextByte = bitsToGet - bitsLeft;\n\n const shift = bitsLeft - bitsToGet;\n let i1 = 0;\n let i2 = 0;\n if (shift >= 0) {\n i1 = (b & TiffFaxDecoder._table1[bitsLeft]) >> shift;\n this._bitPointer += bitsToGet;\n if (this._bitPointer === 8) {\n this._bitPointer = 0;\n this._bytePointer += 1;\n }\n } else {\n i1 = (b & TiffFaxDecoder._table1[bitsLeft]) << -shift;\n i2 =\n (next & TiffFaxDecoder._table2[bitsFromNextByte]) >>\n (8 - bitsFromNextByte);\n\n i1 |= i2;\n this._bytePointer += 1;\n this._bitPointer = bitsFromNextByte;\n }\n\n return i1;\n }\n\n /**\n * Move pointer backwards by given amount of bits\n */\n private updatePointer(bitsToMoveBack: number): void {\n const i = this._bitPointer - bitsToMoveBack;\n\n if (i < 0) {\n this._bytePointer -= 1;\n this._bitPointer = 8 + i;\n } else {\n this._bitPointer = i;\n }\n }\n\n /**\n * Move to the next byte boundary\n */\n private advancePointer(): boolean {\n if (this._bitPointer !== 0) {\n this._bytePointer += 1;\n this._bitPointer = 0;\n }\n\n return true;\n }\n\n private setToBlack(\n buffer: InputBuffer,\n lineOffset: number,\n bitOffset: number,\n numBits: number\n ): void {\n let bitNum = 8 * lineOffset + bitOffset;\n const lastBit = bitNum + numBits;\n\n let byteNum = bitNum >> 3;\n\n // Handle bits in first byte\n const shift = bitNum & 0x7;\n if (shift > 0) {\n let maskVal = 1 << (7 - shift);\n let val = buffer.getByte(byteNum);\n while (maskVal > 0 && bitNum < lastBit) {\n val |= maskVal;\n maskVal >>= 1;\n ++bitNum;\n }\n buffer.setByte(byteNum, val);\n }\n\n // Fill in 8 bits at a time\n byteNum = bitNum >> 3;\n while (bitNum < lastBit - 7) {\n buffer.setByte(byteNum++, 255);\n bitNum += 8;\n }\n\n // Fill in remaining bits\n while (bitNum < lastBit) {\n byteNum = bitNum >> 3;\n buffer.setByte(\n byteNum,\n buffer.getByte(byteNum) | (1 << (7 - (bitNum & 0x7)))\n );\n ++bitNum;\n }\n }\n\n private decodeNextScanline(\n buffer: InputBuffer,\n lineOffset: number,\n bitOffset: number\n ): void {\n let offset = bitOffset;\n let bits = 0;\n let code = 0;\n let isT = 0;\n let current = 0;\n let entry = 0;\n let twoBits = 0;\n let isWhite = true;\n\n // Initialize starting of the changing elements array\n this._changingElemSize = 0;\n\n // While scanline not complete\n while (offset < this._width) {\n while (isWhite) {\n // White run\n current = this.nextNBits(10);\n entry = TiffFaxDecoder._white[current];\n\n // Get the 3 fields from the entry\n isT = entry & 0x0001;\n bits = (entry >> 1) & 0x0f;\n\n if (bits === 12) {\n // Additional Make up code\n // Get the next 2 bits\n twoBits = this.nextLesserThan8Bits(2);\n // Consolidate the 2 bits and last 2 bits into 4 bits\n current = ((current << 2) & 0x000c) | twoBits;\n entry = TiffFaxDecoder._additionalMakeup[current];\n // 3 bits 0000 0111\n bits = (entry >> 1) & 0x07;\n // 12 bits\n code = (entry >> 4) & 0x0fff;\n // Skip white run\n offset += code;\n\n this.updatePointer(4 - bits);\n } else if (bits === 0) {\n // ERROR\n throw new LibError('TIFFFaxDecoder0');\n } else if (bits === 15) {\n // EOL\n throw new LibError('TIFFFaxDecoder1');\n } else {\n // 11 bits - 0000 0111 1111 1111 = 0x07ff\n code = (entry >> 5) & 0x07ff;\n offset += code;\n\n this.updatePointer(10 - bits);\n if (isT === 0) {\n isWhite = false;\n this._currChangingElements![this._changingElemSize++] = offset;\n }\n }\n }\n\n // Check whether this run completed one width, if so\n // advance to next byte boundary for compression = 2.\n if (offset === this._width) {\n if (this._compression === 2) {\n this.advancePointer();\n }\n break;\n }\n\n while (isWhite === false) {\n // Black run\n current = this.nextLesserThan8Bits(4);\n entry = TiffFaxDecoder._initBlack[current];\n\n // Get the 3 fields from the entry\n isT = entry & 0x0001;\n bits = (entry >> 1) & 0x000f;\n code = (entry >> 5) & 0x07ff;\n\n if (code === 100) {\n current = this.nextNBits(9);\n entry = TiffFaxDecoder._black[current];\n\n // Get the 3 fields from the entry\n isT = entry & 0x0001;\n bits = (entry >> 1) & 0x000f;\n code = (entry >> 5) & 0x07ff;\n\n if (bits === 12) {\n // Additional makeup codes\n this.updatePointer(5);\n current = this.nextLesserThan8Bits(4);\n entry = TiffFaxDecoder._additionalMakeup[current];\n // 3 bits 0000 0111\n bits = (entry >> 1) & 0x07;\n // 12 bits\n code = (entry >> 4) & 0x0fff;\n\n this.setToBlack(buffer, lineOffset, offset, code);\n offset += code;\n\n this.updatePointer(4 - bits);\n } else if (bits === 15) {\n // EOL code\n throw new LibError('TIFFFaxDecoder2');\n } else {\n this.setToBlack(buffer, lineOffset, offset, code);\n offset += code;\n\n this.updatePointer(9 - bits);\n if (isT === 0) {\n isWhite = true;\n this._currChangingElements![this._changingElemSize++] = offset;\n }\n }\n } else if (code === 200) {\n // Is a Terminating code\n current = this.nextLesserThan8Bits(2);\n entry = TiffFaxDecoder._twoBitBlack[current];\n code = (entry >> 5) & 0x07ff;\n bits = (entry >> 1) & 0x0f;\n\n this.setToBlack(buffer, lineOffset, offset, code);\n offset += code;\n\n this.updatePointer(2 - bits);\n isWhite = true;\n this._currChangingElements![this._changingElemSize++] = offset;\n } else {\n // Is a Terminating code\n this.setToBlack(buffer, lineOffset, offset, code);\n offset += code;\n\n this.updatePointer(4 - bits);\n isWhite = true;\n this._currChangingElements![this._changingElemSize++] = offset;\n }\n }\n\n // Check whether this run completed one width\n if (offset === this._width) {\n if (this._compression === 2) {\n this.advancePointer();\n }\n break;\n }\n }\n\n this._currChangingElements![this._changingElemSize++] = offset;\n }\n\n private readEOL(): number {\n if (this._fillBits === 0) {\n if (this.nextNBits(12) !== 1) {\n throw new LibError('TIFFFaxDecoder6');\n }\n } else if (this._fillBits === 1) {\n // First EOL code word xxxx 0000 0000 0001 will occur\n // As many fill bits will be present as required to make\n // the EOL code of 12 bits end on a byte boundary.\n const bitsLeft = 8 - this._bitPointer;\n\n if (this.nextNBits(bitsLeft) !== 0) {\n throw new LibError('TIFFFaxDecoder8');\n }\n\n // If the number of bitsLeft is less than 8, then to have a 12\n // bit EOL sequence, two more bytes are certainly going to be\n // required. The first of them has to be all zeros, so ensure\n // that.\n if (bitsLeft < 4) {\n if (this.nextNBits(8) !== 0) {\n throw new LibError('TIFFFaxDecoder8');\n }\n }\n\n // There might be a random number of fill bytes with 0s, so\n // loop till the EOL of 0000 0001 is found, as long as all\n // the bytes preceding it are 0's.\n let n = 0;\n while ((n = this.nextNBits(8)) !== 1) {\n // If not all zeros\n if (n !== 0) {\n throw new LibError('TIFFFaxDecoder8');\n }\n }\n }\n\n // If one dimensional encoding mode, then always return 1\n if (this._oneD === 0) {\n return 1;\n } else {\n // Otherwise for 2D encoding mode,\n // The next one bit signifies 1D/2D encoding of next line.\n return this.nextLesserThan8Bits(1);\n }\n }\n\n private getNextChangingElement(\n a0: number | undefined,\n isWhite: boolean,\n ret: Array\n ): void {\n // Local copies of instance variables\n const pce = this._prevChangingElements;\n const ces = this._changingElemSize;\n\n // If the previous match was at an odd element, we still\n // have to search the preceeding element.\n // int start = lastChangingElement & ~0x1;\n let start =\n this._lastChangingElement > 0 ? this._lastChangingElement - 1 : 0;\n if (isWhite) {\n // Search even numbered elements\n start &= ~0x1;\n } else {\n // Search odd numbered elements\n start |= 0x1;\n }\n\n let i = start;\n for (; i < ces; i += 2) {\n const temp = pce![i]!;\n if (temp > a0!) {\n this._lastChangingElement = i;\n ret[0] = temp;\n break;\n }\n }\n\n if (i + 1 < ces) {\n ret[1] = pce![i + 1];\n }\n }\n\n /**\n * Returns run length\n */\n private decodeWhiteCodeWord(): number {\n let current = 0;\n let entry = 0;\n let bits = 0;\n let isT = 0;\n let twoBits = 0;\n let code = -1;\n let runLength = 0;\n let isWhite = true;\n\n while (isWhite) {\n current = this.nextNBits(10);\n entry = TiffFaxDecoder._white[current];\n\n // Get the 3 fields from the entry\n isT = entry & 0x0001;\n bits = (entry >> 1) & 0x0f;\n\n if (bits === 12) {\n // Additional Make up code\n // Get the next 2 bits\n twoBits = this.nextLesserThan8Bits(2);\n // Consolidate the 2 new bits and last 2 bits into 4 bits\n current = ((current << 2) & 0x000c) | twoBits;\n entry = TiffFaxDecoder._additionalMakeup[current];\n // 3 bits 0000 0111\n bits = (entry >> 1) & 0x07;\n // 12 bits\n code = (entry >> 4) & 0x0fff;\n runLength += code;\n this.updatePointer(4 - bits);\n } else if (bits === 0) {\n // ERROR\n throw new LibError('TIFFFaxDecoder0');\n } else if (bits === 15) {\n // EOL\n throw new LibError('TIFFFaxDecoder1');\n } else {\n // 11 bits - 0000 0111 1111 1111 = 0x07ff\n code = (entry >> 5) & 0x07ff;\n runLength += code;\n this.updatePointer(10 - bits);\n if (isT === 0) {\n isWhite = false;\n }\n }\n }\n\n return runLength;\n }\n\n /**\n * Returns run length\n */\n private decodeBlackCodeWord() {\n let current = 0;\n let entry = 0;\n let bits = 0;\n let isT = 0;\n let code = -1;\n let runLength = 0;\n let isWhite = false;\n\n while (!isWhite) {\n current = this.nextLesserThan8Bits(4);\n entry = TiffFaxDecoder._initBlack[current];\n\n // Get the 3 fields from the entry\n isT = entry & 0x0001;\n bits = (entry >> 1) & 0x000f;\n code = (entry >> 5) & 0x07ff;\n\n if (code === 100) {\n current = this.nextNBits(9);\n entry = TiffFaxDecoder._black[current];\n\n // Get the 3 fields from the entry\n isT = entry & 0x0001;\n bits = (entry >> 1) & 0x000f;\n code = (entry >> 5) & 0x07ff;\n\n if (bits === 12) {\n // Additional makeup codes\n this.updatePointer(5);\n current = this.nextLesserThan8Bits(4);\n entry = TiffFaxDecoder._additionalMakeup[current];\n // 3 bits 0000 0111\n bits = (entry >> 1) & 0x07;\n // 12 bits\n code = (entry >> 4) & 0x0fff;\n runLength += code;\n\n this.updatePointer(4 - bits);\n } else if (bits === 15) {\n // EOL code\n throw new LibError('TIFFFaxDecoder2');\n } else {\n runLength += code;\n this.updatePointer(9 - bits);\n if (isT === 0) {\n isWhite = true;\n }\n }\n } else if (code === 200) {\n // Is a Terminating code\n current = this.nextLesserThan8Bits(2);\n entry = TiffFaxDecoder._twoBitBlack[current];\n code = (entry >> 5) & 0x07ff;\n runLength += code;\n bits = (entry >> 1) & 0x0f;\n this.updatePointer(2 - bits);\n isWhite = true;\n } else {\n // Is a Terminating code\n runLength += code;\n this.updatePointer(4 - bits);\n isWhite = true;\n }\n }\n\n return runLength;\n }\n\n /**\n * One-dimensional decoding methods\n */\n public decode1D(\n out: InputBuffer,\n compData: InputBuffer,\n startX: number,\n height: number\n ): void {\n this._data = compData;\n this._bitPointer = 0;\n this._bytePointer = 0;\n\n let lineOffset = 0;\n const scanlineStride = Math.trunc((this._width + 7) / 8);\n\n for (let i = 0; i < height; i++) {\n this.decodeNextScanline(out, lineOffset, startX);\n lineOffset += scanlineStride;\n }\n }\n\n /**\n * Two-dimensional decoding methods\n */\n public decode2D(\n out: InputBuffer,\n compData: InputBuffer,\n startX: number,\n height: number,\n tiffT4Options: number\n ): void {\n this._data = compData;\n this._compression = 3;\n\n this._bitPointer = 0;\n this._bytePointer = 0;\n\n const scanlineStride = Math.trunc((this._width + 7) / 8);\n\n let a0 = 0;\n let a1 = 0;\n let entry = 0;\n let code = 0;\n let bits = 0;\n let isWhite = false;\n let currIndex = 0;\n let temp: Array | undefined = undefined;\n\n const b = new Array(2);\n b.fill(0);\n\n // fillBits - dealt with this in readEOL\n // 1D/2D encoding - dealt with this in readEOL\n\n // uncompressedMode - haven't dealt with this yet.\n this._oneD = tiffT4Options & 0x01;\n this._uncompressedMode = (tiffT4Options & 0x02) >> 1;\n this._fillBits = (tiffT4Options & 0x04) >> 2;\n\n // The data must start with an EOL code\n if (this.readEOL() !== 1) {\n throw new LibError('TIFFFaxDecoder3');\n }\n\n let lineOffset = 0;\n let bitOffset = 0;\n\n // Then the 1D encoded scanline data will occur, changing elements\n // array gets set.\n this.decodeNextScanline(out, lineOffset, startX);\n lineOffset += scanlineStride;\n\n for (let lines = 1; lines < height; lines++) {\n // Every line must begin with an EOL followed by a bit which\n // indicates whether the following scanline is 1D or 2D encoded.\n if (this.readEOL() === 0) {\n // 2D encoded scanline follows\n\n // Initialize previous scanlines changing elements, and\n // initialize current scanline's changing elements array\n temp = this._prevChangingElements;\n this._prevChangingElements = this._currChangingElements;\n this._currChangingElements = temp;\n currIndex = 0;\n\n // a0 has to be set just before the start of this scanline.\n a0 = -1;\n isWhite = true;\n bitOffset = startX;\n\n this._lastChangingElement = 0;\n\n while (bitOffset < this._width) {\n // Get the next changing element\n this.getNextChangingElement(a0, isWhite, b);\n\n const b1 = b[0];\n const b2 = b[1];\n\n // Get the next seven bits\n entry = this.nextLesserThan8Bits(7);\n\n // Run these through the 2DCodes table\n entry = TiffFaxDecoder._twoDCodes[entry] & 0xff;\n\n // Get the code and the number of bits used up\n code = (entry & 0x78) >> 3;\n bits = entry & 0x07;\n\n if (code === 0) {\n if (!isWhite) {\n this.setToBlack(out, lineOffset, bitOffset, b2 - bitOffset);\n }\n a0 = b2;\n bitOffset = a0;\n\n // Set pointer to consume the correct number of bits.\n this.updatePointer(7 - bits);\n } else if (code === 1) {\n // Horizontal\n this.updatePointer(7 - bits);\n\n // identify the next 2 codes.\n let number = 0;\n if (isWhite) {\n number = this.decodeWhiteCodeWord();\n bitOffset += number;\n this._currChangingElements![currIndex++] = bitOffset;\n\n number = this.decodeBlackCodeWord();\n this.setToBlack(out, lineOffset, bitOffset, number);\n bitOffset += number;\n this._currChangingElements![currIndex++] = bitOffset;\n } else {\n number = this.decodeBlackCodeWord();\n this.setToBlack(out, lineOffset, bitOffset, number);\n bitOffset += number;\n this._currChangingElements![currIndex++] = bitOffset;\n\n number = this.decodeWhiteCodeWord();\n bitOffset += number;\n this._currChangingElements![currIndex++] = bitOffset;\n }\n\n a0 = bitOffset;\n } else if (code <= 8) {\n // Vertical\n a1 = b1 + (code - 5);\n\n this._currChangingElements![currIndex++] = a1;\n\n // We write the current color till a1 - 1 pos,\n // since a1 is where the next color starts\n if (!isWhite) {\n this.setToBlack(out, lineOffset, bitOffset, a1 - bitOffset);\n }\n a0 = a1;\n bitOffset = a0;\n isWhite = !isWhite;\n\n this.updatePointer(7 - bits);\n } else {\n throw new LibError('TIFFFaxDecoder4');\n }\n }\n\n // Add the changing element beyond the current scanline for the\n // other color too\n this._currChangingElements![currIndex++] = bitOffset;\n this._changingElemSize = currIndex;\n } else {\n // 1D encoded scanline follows\n this.decodeNextScanline(out, lineOffset, startX);\n }\n\n lineOffset += scanlineStride;\n }\n }\n\n public decodeT6(\n out: InputBuffer,\n compData: InputBuffer,\n startX: number,\n height: number,\n tiffT6Options: number\n ): void {\n this._data = compData;\n this._compression = 4;\n\n this._bitPointer = 0;\n this._bytePointer = 0;\n\n const scanlineStride = Math.trunc((this._width + 7) / 8);\n\n let a0 = 0;\n let a1 = 0;\n let b1 = 0;\n let b2 = 0;\n let entry = 0;\n let code = 0;\n let bits = 0;\n let isWhite = false;\n let currIndex = 0;\n let temp: Array | undefined = undefined;\n\n // Return values from getNextChangingElement\n const b = new Array(2);\n b.fill(0);\n\n this._uncompressedMode = (tiffT6Options & 0x02) >> 1;\n\n // Local cached reference\n let cce = this._currChangingElements!;\n\n // Assume invisible preceding row of all white pixels and insert\n // both black and white changing elements beyond the end of this\n // imaginary scanline.\n this._changingElemSize = 0;\n cce[this._changingElemSize++] = this._width;\n cce[this._changingElemSize++] = this._width;\n\n let lineOffset = 0;\n let bitOffset = 0;\n\n for (let lines = 0; lines < height; lines++) {\n // a0 has to be set just before the start of the scanline.\n a0 = -1;\n isWhite = true;\n\n // Assign the changing elements of the previous scanline to\n // prevChangingElems and start putting this new scanline's\n // changing elements into the currChangingElems.\n temp = this._prevChangingElements;\n this._prevChangingElements = this._currChangingElements;\n cce = (this._currChangingElements = temp)!;\n currIndex = 0;\n\n // Start decoding the scanline at startX in the raster\n bitOffset = startX;\n\n // Reset search start position for getNextChangingElement\n this._lastChangingElement = 0;\n\n // Till one whole scanline is decoded\n while (bitOffset < this._width) {\n // Get the next changing element\n this.getNextChangingElement(a0, isWhite, b);\n b1 = b[0];\n b2 = b[1];\n\n // Get the next seven bits\n entry = this.nextLesserThan8Bits(7);\n // Run these through the 2DCodes table\n entry = TiffFaxDecoder._twoDCodes[entry] & 0xff;\n\n // Get the code and the number of bits used up\n code = (entry & 0x78) >> 3;\n bits = entry & 0x07;\n\n if (code === 0) {\n // Pass\n // We always assume WhiteIsZero format for fax.\n if (!isWhite) {\n this.setToBlack(out, lineOffset, bitOffset, b2! - bitOffset);\n }\n a0 = b2;\n bitOffset = a0;\n\n // Set pointer to only consume the correct number of bits.\n this.updatePointer(7 - bits);\n } else if (code === 1) {\n // Horizontal\n // Set pointer to only consume the correct number of bits.\n this.updatePointer(7 - bits);\n\n // identify the next 2 alternating color codes.\n let number = 0;\n if (isWhite) {\n // Following are white and black runs\n number = this.decodeWhiteCodeWord();\n bitOffset += number;\n cce[currIndex++] = bitOffset;\n\n number = this.decodeBlackCodeWord();\n this.setToBlack(out, lineOffset, bitOffset, number);\n bitOffset += number;\n cce[currIndex++] = bitOffset;\n } else {\n // First a black run and then a white run follows\n number = this.decodeBlackCodeWord();\n this.setToBlack(out, lineOffset, bitOffset, number);\n bitOffset += number;\n cce[currIndex++] = bitOffset;\n\n number = this.decodeWhiteCodeWord();\n bitOffset += number;\n cce[currIndex++] = bitOffset;\n }\n\n a0 = bitOffset;\n } else if (code <= 8) {\n // Vertical\n a1 = b1 + (code - 5);\n cce[currIndex++] = a1;\n\n // We write the current color till a1 - 1 pos,\n // since a1 is where the next color starts\n if (!isWhite) {\n this.setToBlack(out, lineOffset, bitOffset, a1 - bitOffset);\n }\n a0 = a1;\n bitOffset = a0;\n isWhite = !isWhite;\n\n this.updatePointer(7 - bits);\n } else if (code === 11) {\n if (this.nextLesserThan8Bits(3) !== 7) {\n throw new LibError('TIFFFaxDecoder5');\n }\n\n let zeros = 0;\n let exit = false;\n\n while (!exit) {\n while (this.nextLesserThan8Bits(1) !== 1) {\n zeros++;\n }\n\n if (zeros > 5) {\n // Exit code\n\n // Zeros before exit code\n zeros -= 6;\n\n if (!isWhite && zeros > 0) {\n cce[currIndex++] = bitOffset;\n }\n\n // Zeros before the exit code\n bitOffset += zeros;\n if (zeros > 0) {\n // Some zeros have been written\n isWhite = true;\n }\n\n // Read in the bit which specifies the color of\n // the following run\n if (this.nextLesserThan8Bits(1) === 0) {\n if (!isWhite) {\n cce[currIndex++] = bitOffset;\n }\n isWhite = true;\n } else {\n if (isWhite) {\n cce[currIndex++] = bitOffset;\n }\n isWhite = false;\n }\n\n exit = true;\n }\n\n if (zeros === 5) {\n if (!isWhite) {\n cce[currIndex++] = bitOffset;\n }\n bitOffset += zeros;\n\n // Last thing written was white\n isWhite = true;\n } else {\n bitOffset += zeros;\n\n cce[currIndex++] = bitOffset;\n this.setToBlack(out, lineOffset, bitOffset, 1);\n ++bitOffset;\n\n // Last thing written was black\n isWhite = false;\n }\n }\n } else {\n throw new LibError(`TIFFFaxDecoder5 ${code}`);\n }\n }\n\n // Add the changing element beyond the current scanline for the\n // other color too\n cce[currIndex++] = bitOffset;\n\n // Number of changing elements in this scanline.\n this._changingElemSize = currIndex;\n\n lineOffset += scanlineStride;\n }\n }\n}\n", "/** @format */\n\nexport enum TiffFormat {\n invalid,\n uint,\n int,\n float,\n}\n", "/** @format */\n\nexport enum TiffImageType {\n bilevel,\n gray4bit,\n gray,\n grayAlpha,\n palette,\n rgb,\n rgba,\n yCbCrSub,\n generic,\n invalid,\n}\n", "/** @format */\n\nimport { InputBuffer } from '../../common/input-buffer';\nimport { LibError } from '../../error/lib-error';\n\nexport class LzwDecoder {\n private static readonly _lzMaxCode = 4095;\n private static readonly _noSuchCode = 4098;\n private static readonly _andTable: number[] = [511, 1023, 2047, 4095];\n\n private readonly _buffer = new Uint8Array(4096);\n\n private _bitsToGet = 9;\n private _bytePointer = 0;\n private _nextData = 0;\n private _nextBits = 0;\n private _data!: Uint8Array;\n private _dataLength!: number;\n private _out!: Uint8Array;\n private _outPointer!: number;\n private _table!: Uint8Array;\n private _prefix!: Uint32Array;\n private _tableIndex?: number;\n private _bufferLength!: number;\n\n private addString(string: number, newString: number): void {\n this._table[this._tableIndex!] = newString;\n this._prefix[this._tableIndex!] = string;\n this._tableIndex = this._tableIndex! + 1;\n\n if (this._tableIndex === 511) {\n this._bitsToGet = 10;\n } else if (this._tableIndex === 1023) {\n this._bitsToGet = 11;\n } else if (this._tableIndex === 2047) {\n this._bitsToGet = 12;\n }\n }\n\n private getString(code: number): void {\n this._bufferLength = 0;\n let c = code;\n this._buffer[this._bufferLength++] = this._table[c];\n c = this._prefix[c];\n while (c !== LzwDecoder._noSuchCode) {\n this._buffer[this._bufferLength++] = this._table[c];\n c = this._prefix[c];\n }\n }\n\n /**\n * Returns the next 9, 10, 11 or 12 bits\n */\n private getNextCode(): number {\n if (this._bytePointer >= this._dataLength) {\n return 257;\n }\n\n while (this._nextBits < this._bitsToGet) {\n if (this._bytePointer >= this._dataLength) {\n return 257;\n }\n this._nextData =\n ((this._nextData << 8) + this._data[this._bytePointer++]) & 0xffffffff;\n this._nextBits += 8;\n }\n\n this._nextBits -= this._bitsToGet;\n const code =\n (this._nextData >> this._nextBits) &\n LzwDecoder._andTable[this._bitsToGet - 9];\n\n return code;\n }\n\n /**\n * Initialize the string table.\n */\n private initializeStringTable(): void {\n this._table = new Uint8Array(LzwDecoder._lzMaxCode + 1);\n this._prefix = new Uint32Array(LzwDecoder._lzMaxCode + 1);\n this._prefix.fill(LzwDecoder._noSuchCode, 0, this._prefix.length);\n\n for (let i = 0; i < 256; i++) {\n this._table[i] = i;\n }\n\n this._bitsToGet = 9;\n\n this._tableIndex = 258;\n }\n\n public decode(p: InputBuffer, out: Uint8Array): void {\n this._out = out;\n const outLen = out.length;\n this._outPointer = 0;\n this._data = p.buffer;\n this._dataLength = this._data.length;\n this._bytePointer = p.offset;\n\n if (this._data[0] === 0x00 && this._data[1] === 0x01) {\n throw new LibError('Invalid LZW Data');\n }\n\n this.initializeStringTable();\n\n this._nextData = 0;\n this._nextBits = 0;\n\n let oldCode = 0;\n\n let code = this.getNextCode();\n while (code !== 257 && this._outPointer < outLen) {\n if (code === 256) {\n this.initializeStringTable();\n code = this.getNextCode();\n this._bufferLength = 0;\n if (code === 257) {\n break;\n }\n\n this._out[this._outPointer++] = code;\n oldCode = code;\n } else {\n if (code < this._tableIndex!) {\n this.getString(code);\n for (let i = this._bufferLength - 1; i >= 0; --i) {\n this._out[this._outPointer++] = this._buffer[i];\n }\n this.addString(oldCode, this._buffer[this._bufferLength - 1]);\n oldCode = code;\n } else {\n this.getString(oldCode);\n for (let i = this._bufferLength - 1; i >= 0; --i) {\n this._out[this._outPointer++] = this._buffer[i];\n }\n this._out[this._outPointer++] = this._buffer[this._bufferLength - 1];\n this.addString(oldCode, this._buffer[this._bufferLength - 1]);\n\n oldCode = code;\n }\n }\n\n code = this.getNextCode();\n }\n }\n}\n", "/** @format */\n\nexport enum TiffPhotometricType {\n // 0\n whiteIsZero,\n // 1\n blackIsZero,\n // 2\n rgb,\n // 3\n palette,\n // 4\n transparencyMask,\n // 5\n cmyk,\n // 6\n yCbCr,\n // 7\n reserved7,\n // 8\n cieLab,\n // 9\n iccLab,\n // 10\n ituLab,\n // 32844\n logL,\n // 32845\n logLuv,\n // 32803\n colorFilterArray,\n // 34892\n linearRaw,\n // 51177\n depth,\n unknown,\n}\n\nexport const TiffPhotometricTypeLength = 17;\n", "/** @format */\n\nimport { inflate } from 'uzip';\nimport { ColorUtils } from '../../color/color-utils';\nimport { Format } from '../../color/format';\nimport { ArrayUtils } from '../../common/array-utils';\nimport { BitUtils } from '../../common/bit-utils';\nimport { Float16 } from '../../common/float16';\nimport { InputBuffer } from '../../common/input-buffer';\nimport { LibError } from '../../error/lib-error';\nimport { ExifTagNameToID } from '../../exif/exif-tag';\nimport { IfdValueType, IfdValueTypeSize } from '../../exif/ifd-value-type';\nimport { MemoryImage } from '../../image/image';\nimport { JpegDecoder } from '../jpeg-decoder';\nimport { TiffBitReader } from './tiff-bit-reader';\nimport { TiffCompression } from './tiff-compression';\nimport { TiffEntry } from './tiff-entry';\nimport { TiffFaxDecoder } from './tiff-fax-decoder';\nimport { TiffFormat } from './tiff-format';\nimport { TiffImageType } from './tiff-image-type';\nimport { LzwDecoder } from './tiff-lzw-decoder';\nimport {\n TiffPhotometricType,\n TiffPhotometricTypeLength,\n} from './tiff-photometric-type';\n\nexport class TiffImage {\n private readonly _tags: Map = new Map();\n public get tags(): Map {\n return this._tags;\n }\n\n private readonly _width: number = 0;\n public get width(): number {\n return this._width;\n }\n\n private readonly _height: number = 0;\n public get height(): number {\n return this._height;\n }\n\n private _photometricType: TiffPhotometricType = TiffPhotometricType.unknown;\n public get photometricType(): TiffPhotometricType {\n return this._photometricType;\n }\n\n private _compression = 1;\n public get compression(): number {\n return this._compression;\n }\n\n private _bitsPerSample = 1;\n public get bitsPerSample(): number {\n return this._bitsPerSample;\n }\n\n private _samplesPerPixel = 1;\n public get samplesPerPixel(): number {\n return this._samplesPerPixel;\n }\n\n private _sampleFormat: TiffFormat = TiffFormat.uint;\n public get sampleFormat(): TiffFormat {\n return this._sampleFormat;\n }\n\n private _imageType: TiffImageType = TiffImageType.invalid;\n public get imageType(): TiffImageType {\n return this._imageType;\n }\n\n private _isWhiteZero = false;\n public get isWhiteZero(): boolean {\n return this._isWhiteZero;\n }\n\n private _predictor = 1;\n public get predictor(): number {\n return this._predictor;\n }\n\n private _chromaSubH = 0;\n public get chromaSubH(): number {\n return this._chromaSubH;\n }\n\n private _chromaSubV = 0;\n public get chromaSubV(): number {\n return this._chromaSubV;\n }\n\n private _tiled = false;\n public get tiled(): boolean {\n return this._tiled;\n }\n\n private _tileWidth = 0;\n public get tileWidth(): number {\n return this._tileWidth;\n }\n\n private _tileHeight = 0;\n public get tileHeight(): number {\n return this._tileHeight;\n }\n\n private _tileOffsets: number[] | undefined;\n public get tileOffsets(): number[] | undefined {\n return this._tileOffsets;\n }\n\n private _tileByteCounts: number[] | undefined;\n public get tileByteCounts(): number[] | undefined {\n return this._tileByteCounts;\n }\n\n private _tilesX = 0;\n public get tilesX(): number {\n return this._tilesX;\n }\n\n private _tilesY = 0;\n public get tilesY(): number {\n return this._tilesY;\n }\n\n private _tileSize: number | undefined;\n public get tileSize(): number | undefined {\n return this._tileSize;\n }\n\n private _fillOrder = 1;\n public get fillOrder(): number {\n return this._fillOrder;\n }\n\n private _t4Options = 0;\n public get t4Options(): number {\n return this._t4Options;\n }\n\n private _t6Options = 0;\n public get t6Options(): number {\n return this._t6Options;\n }\n\n private _extraSamples: number | undefined;\n public get extraSamples(): number | undefined {\n return this._extraSamples;\n }\n\n private _colorMapSamples = 0;\n public get colorMapSamples(): number {\n return this._colorMapSamples;\n }\n\n private _colorMap: Uint16Array | undefined;\n public get colorMap(): Uint16Array | undefined {\n return this._colorMap;\n }\n\n // Starting index in the [colorMap] for the red channel.\n private _colorMapRed = 0;\n\n // Starting index in the [colorMap] for the green channel.\n private _colorMapGreen = 0;\n\n // Starting index in the [colorMap] for the blue channel.\n private _colorMapBlue = 0;\n\n public get isValid(): boolean {\n return this._width !== 0 && this._height !== 0;\n }\n\n constructor(p: InputBuffer) {\n const p3 = InputBuffer.from(p);\n\n const numDirEntries = p.readUint16();\n for (let i = 0; i < numDirEntries; ++i) {\n const tag = p.readUint16();\n const ti = p.readUint16();\n const type = ti as IfdValueType;\n const typeSize = IfdValueTypeSize[ti];\n const count = p.readUint32();\n let valueOffset = 0;\n // The value for the tag is either stored in another location,\n // or within the tag itself (if the size fits in 4 bytes).\n // We're not reading the data here, just storing offsets.\n if (count * typeSize > 4) {\n valueOffset = p.readUint32();\n } else {\n valueOffset = p.offset;\n p.skip(4);\n }\n\n const entry = new TiffEntry({\n tag: tag,\n type: type,\n count: count,\n p: p3,\n valueOffset: valueOffset,\n });\n\n this._tags.set(entry.tag, entry);\n\n if (tag === ExifTagNameToID.get('ImageWidth')) {\n this._width = entry.read()?.toInt() ?? 0;\n } else if (tag === ExifTagNameToID.get('ImageLength')) {\n this._height = entry.read()?.toInt() ?? 0;\n } else if (tag === ExifTagNameToID.get('PhotometricInterpretation')) {\n const v = entry.read();\n if (v === undefined) {\n this._photometricType = TiffPhotometricType.unknown;\n } else {\n const pt = v.toInt();\n if (pt < TiffPhotometricTypeLength) {\n this._photometricType = pt as TiffPhotometricType;\n } else {\n this._photometricType = TiffPhotometricType.unknown;\n }\n }\n } else if (tag === ExifTagNameToID.get('Compression')) {\n this._compression = entry.read()?.toInt() ?? 0;\n } else if (tag === ExifTagNameToID.get('BitsPerSample')) {\n this._bitsPerSample = entry.read()?.toInt() ?? 0;\n } else if (tag === ExifTagNameToID.get('SamplesPerPixel')) {\n this._samplesPerPixel = entry.read()?.toInt() ?? 0;\n } else if (tag === ExifTagNameToID.get('Predictor')) {\n this._predictor = entry.read()?.toInt() ?? 0;\n } else if (tag === ExifTagNameToID.get('SampleFormat')) {\n const v = entry.read()?.toInt() ?? 0;\n this._sampleFormat = v as TiffFormat;\n } else if (tag === ExifTagNameToID.get('ColorMap')) {\n const v = entry.read();\n if (v !== undefined) {\n this._colorMap = new Uint16Array(v.toData().buffer);\n this._colorMapRed = 0;\n this._colorMapGreen = Math.trunc(this._colorMap.length / 3);\n this._colorMapBlue = this._colorMapGreen * 2;\n }\n }\n }\n\n if (\n this._colorMap !== undefined &&\n this._photometricType === TiffPhotometricType.palette\n ) {\n // Only support RGB palettes.\n this._colorMapSamples = 3;\n this._samplesPerPixel = 1;\n }\n\n if (this._width === 0 || this._height === 0) {\n return;\n }\n\n if (this._colorMap !== undefined && this._bitsPerSample === 8) {\n const cm = this._colorMap;\n const len = cm.length;\n for (let i = 0; i < len; ++i) {\n cm[i] >>= 8;\n }\n }\n\n if (this._photometricType === TiffPhotometricType.whiteIsZero) {\n this._isWhiteZero = true;\n }\n\n if (this.hasTag(ExifTagNameToID.get('TileOffsets')!)) {\n this._tiled = true;\n // Image is in tiled format\n this._tileWidth = this.readTag(ExifTagNameToID.get('TileWidth')!);\n this._tileHeight = this.readTag(ExifTagNameToID.get('TileLength')!);\n this._tileOffsets = this.readTagList(ExifTagNameToID.get('TileOffsets')!);\n this._tileByteCounts = this.readTagList(\n ExifTagNameToID.get('TileByteCounts')!\n );\n } else {\n this._tiled = false;\n\n this._tileWidth = this.readTag(\n ExifTagNameToID.get('TileWidth')!,\n this._width\n );\n if (!this.hasTag(ExifTagNameToID.get('RowsPerStrip')!)) {\n this._tileHeight = this.readTag(\n ExifTagNameToID.get('TileLength')!,\n this._height\n );\n } else {\n const l = this.readTag(ExifTagNameToID.get('RowsPerStrip')!);\n let infinity = 1;\n infinity = (infinity << 32) - 1;\n if (l === infinity) {\n // 2^32 - 1 (effectively infinity, entire image is 1 strip)\n this._tileHeight = this._height;\n } else {\n this._tileHeight = l;\n }\n }\n\n this._tileOffsets = this.readTagList(\n ExifTagNameToID.get('StripOffsets')!\n );\n this._tileByteCounts = this.readTagList(\n ExifTagNameToID.get('StripByteCounts')!\n );\n }\n\n // Calculate number of tiles and the tileSize in bytes\n this._tilesX = Math.trunc(\n (this._width + this._tileWidth - 1) / this._tileWidth\n );\n this._tilesY = Math.trunc(\n (this._height + this._tileHeight - 1) / this._tileHeight\n );\n this._tileSize = this._tileWidth * this._tileHeight * this._samplesPerPixel;\n\n this._fillOrder = this.readTag(ExifTagNameToID.get('FillOrder')!, 1);\n this._t4Options = this.readTag(ExifTagNameToID.get('T4Options')!);\n this._t6Options = this.readTag(ExifTagNameToID.get('T6Options')!);\n this._extraSamples = this.readTag(ExifTagNameToID.get('ExtraSamples')!);\n\n // Determine which kind of image we are dealing with.\n switch (this._photometricType) {\n case TiffPhotometricType.whiteIsZero:\n case TiffPhotometricType.blackIsZero:\n if (this._bitsPerSample === 1 && this._samplesPerPixel === 1) {\n this._imageType = TiffImageType.bilevel;\n } else if (this._bitsPerSample === 4 && this._samplesPerPixel === 1) {\n this._imageType = TiffImageType.gray4bit;\n } else if (this._bitsPerSample % 8 === 0) {\n if (this._samplesPerPixel === 1) {\n this._imageType = TiffImageType.gray;\n } else if (this._samplesPerPixel === 2) {\n this._imageType = TiffImageType.grayAlpha;\n } else {\n this._imageType = TiffImageType.generic;\n }\n }\n break;\n case TiffPhotometricType.rgb:\n if (this._bitsPerSample % 8 === 0) {\n if (this._samplesPerPixel === 3) {\n this._imageType = TiffImageType.rgb;\n } else if (this._samplesPerPixel === 4) {\n this._imageType = TiffImageType.rgba;\n } else {\n this._imageType = TiffImageType.generic;\n }\n }\n break;\n case TiffPhotometricType.palette:\n if (\n this._samplesPerPixel === 1 &&\n this._colorMap !== undefined &&\n (this._bitsPerSample === 4 ||\n this._bitsPerSample === 8 ||\n this._bitsPerSample === 16)\n ) {\n this._imageType = TiffImageType.palette;\n }\n break;\n case TiffPhotometricType.transparencyMask:\n // Transparency mask\n if (this._bitsPerSample === 1 && this._samplesPerPixel === 1) {\n this._imageType = TiffImageType.bilevel;\n }\n break;\n case TiffPhotometricType.yCbCr:\n if (\n this._compression === TiffCompression.jpeg &&\n this._bitsPerSample === 8 &&\n this._samplesPerPixel === 3\n ) {\n this._imageType = TiffImageType.rgb;\n } else {\n if (this.hasTag(ExifTagNameToID.get('YCbCrSubSampling')!)) {\n const s = ExifTagNameToID.get('YCbCrSubSampling')!;\n const v = this._tags.get(s)!.read()!;\n this._chromaSubH = v.toInt();\n this._chromaSubV = v.toInt(1);\n } else {\n this._chromaSubH = 2;\n this._chromaSubV = 2;\n }\n\n if (this._chromaSubH * this._chromaSubV === 1) {\n this._imageType = TiffImageType.generic;\n } else if (this._bitsPerSample === 8 && this._samplesPerPixel === 3) {\n this._imageType = TiffImageType.yCbCrSub;\n }\n }\n break;\n default:\n // Other including CMYK, CIE L*a*b*, unknown.\n if (this._bitsPerSample % 8 === 0) {\n this._imageType = TiffImageType.generic;\n }\n break;\n }\n }\n\n private readTag(type: number, defaultValue = 0): number {\n if (!this.hasTag(type)) {\n return defaultValue;\n }\n return this._tags.get(type)!.read()?.toInt() ?? 0;\n }\n\n private readTagList(type: number): number[] | undefined {\n if (!this.hasTag(type)) {\n return undefined;\n }\n const tag = this._tags.get(type)!;\n const value = tag.read()!;\n return ArrayUtils.generate(tag.count, (i) => value.toInt(i));\n }\n\n private decodeBilevelTile(\n p: InputBuffer,\n image: MemoryImage,\n tileX: number,\n tileY: number\n ): void {\n const tileIndex = tileY * this._tilesX + tileX;\n p.offset = this._tileOffsets![tileIndex];\n\n const outX = tileX * this._tileWidth;\n const outY = tileY * this._tileHeight;\n\n const byteCount = this._tileByteCounts![tileIndex];\n\n let byteData: InputBuffer | undefined = undefined;\n if (this._compression === TiffCompression.packBits) {\n // Since the decompressed data will still be packed\n // 8 pixels into 1 byte, calculate bytesInThisTile\n let bytesInThisTile = 0;\n if (this._tileWidth % 8 === 0) {\n bytesInThisTile = Math.trunc(this._tileWidth / 8) * this._tileHeight;\n } else {\n bytesInThisTile =\n (Math.trunc(this._tileWidth / 8) + 1) * this._tileHeight;\n }\n byteData = new InputBuffer({\n buffer: new Uint8Array(this._tileWidth * this._tileHeight),\n });\n this.decodePackBits(p, bytesInThisTile, byteData.buffer);\n } else if (this._compression === TiffCompression.lzw) {\n byteData = new InputBuffer({\n buffer: new Uint8Array(this._tileWidth * this._tileHeight),\n });\n\n const decoder = new LzwDecoder();\n decoder.decode(InputBuffer.from(p, 0, byteCount), byteData.buffer);\n\n // Horizontal Differencing Predictor\n if (this._predictor === 2) {\n let count = 0;\n for (let j = 0; j < this._height; j++) {\n count = this._samplesPerPixel * (j * this._width + 1);\n for (\n let i = this._samplesPerPixel;\n i < this._width * this._samplesPerPixel;\n i++\n ) {\n const b =\n byteData.getByte(count) +\n byteData.getByte(count - this._samplesPerPixel);\n byteData.setByte(count, b);\n count++;\n }\n }\n }\n } else if (this._compression === TiffCompression.ccittRle) {\n byteData = new InputBuffer({\n buffer: new Uint8Array(this._tileWidth * this._tileHeight),\n });\n try {\n const decoder = new TiffFaxDecoder({\n fillOrder: this._fillOrder,\n width: this._tileWidth,\n height: this._tileHeight,\n });\n decoder.decode1D(byteData, p, 0, this._tileHeight);\n } catch (_) {\n // skip\n }\n } else if (this._compression === TiffCompression.ccittFax3) {\n byteData = new InputBuffer({\n buffer: new Uint8Array(this._tileWidth * this._tileHeight),\n });\n try {\n const decoder = new TiffFaxDecoder({\n fillOrder: this._fillOrder,\n width: this._tileWidth,\n height: this._tileHeight,\n });\n decoder.decode2D(byteData, p, 0, this._tileHeight, this._t4Options);\n } catch (_) {\n // skip\n }\n } else if (this._compression === TiffCompression.ccittFax4) {\n byteData = new InputBuffer({\n buffer: new Uint8Array(this._tileWidth * this._tileHeight),\n });\n try {\n const decoder = new TiffFaxDecoder({\n fillOrder: this._fillOrder,\n width: this._tileWidth,\n height: this._tileHeight,\n });\n decoder.decodeT6(byteData, p, 0, this._tileHeight, this._t6Options);\n } catch (_) {\n // skip\n }\n } else if (this._compression === TiffCompression.zip) {\n const data = p.toUint8Array(0, byteCount);\n const outData = inflate(data);\n byteData = new InputBuffer({\n buffer: outData,\n });\n } else if (this._compression === TiffCompression.deflate) {\n const data = p.toUint8Array(0, byteCount);\n const outData = inflate(data);\n byteData = new InputBuffer({\n buffer: outData,\n });\n } else if (this._compression === TiffCompression.none) {\n byteData = p;\n } else {\n throw new LibError(`Unsupported Compression Type: ${this._compression}`);\n }\n\n const br = new TiffBitReader(byteData);\n const mx = image.maxChannelValue;\n const black = this._isWhiteZero ? mx : 0;\n const white = this._isWhiteZero ? 0 : mx;\n\n for (let y = 0, py = outY; y < this._tileHeight; ++y, ++py) {\n for (let x = 0, px = outX; x < this._tileWidth; ++x, ++px) {\n if (py >= image.height || px >= image.width) break;\n if (br.readBits(1) === 0) {\n image.setPixelRgb(px, py, black, 0, 0);\n } else {\n image.setPixelRgb(px, py, white, 0, 0);\n }\n }\n br.flushByte();\n }\n }\n\n private decodeTile(\n p: InputBuffer,\n image: MemoryImage,\n tileX: number,\n tileY: number\n ): void {\n // Read the data, uncompressing as needed. There are four cases:\n // bilevel, palette-RGB, 4-bit grayscale, and everything else.\n if (this._imageType === TiffImageType.bilevel) {\n this.decodeBilevelTile(p, image, tileX, tileY);\n return;\n }\n\n const tileIndex = tileY * this._tilesX + tileX;\n p.offset = this._tileOffsets![tileIndex];\n\n const outX = tileX * this._tileWidth;\n const outY = tileY * this._tileHeight;\n\n const byteCount = this._tileByteCounts![tileIndex];\n let bytesInThisTile =\n this._tileWidth * this._tileHeight * this._samplesPerPixel;\n if (this._bitsPerSample === 16) {\n bytesInThisTile *= 2;\n } else if (this._bitsPerSample === 32) {\n bytesInThisTile *= 4;\n }\n\n let byteData: InputBuffer | undefined = undefined;\n if (\n this._bitsPerSample === 8 ||\n this._bitsPerSample === 16 ||\n this._bitsPerSample === 32 ||\n this._bitsPerSample === 64\n ) {\n if (this._compression === TiffCompression.none) {\n byteData = p;\n } else if (this._compression === TiffCompression.lzw) {\n byteData = new InputBuffer({\n buffer: new Uint8Array(bytesInThisTile),\n });\n const decoder = new LzwDecoder();\n try {\n decoder.decode(InputBuffer.from(p, 0, byteCount), byteData.buffer);\n } catch (e) {\n // ignore\n }\n // Horizontal Differencing Predictor\n if (this._predictor === 2) {\n let count = 0;\n for (let j = 0; j < this._tileHeight; j++) {\n count = this._samplesPerPixel * (j * this._tileWidth + 1);\n const len = this._tileWidth * this._samplesPerPixel;\n for (let i = this._samplesPerPixel; i < len; i++) {\n byteData.setByte(\n count,\n byteData.getByte(count) +\n byteData.getByte(count - this._samplesPerPixel)\n );\n count++;\n }\n }\n }\n } else if (this._compression === TiffCompression.packBits) {\n byteData = new InputBuffer({\n buffer: new Uint8Array(bytesInThisTile),\n });\n this.decodePackBits(p, bytesInThisTile, byteData.buffer);\n } else if (this._compression === TiffCompression.deflate) {\n const data = p.toUint8Array(0, byteCount);\n const outData = inflate(data);\n byteData = new InputBuffer({\n buffer: outData,\n });\n } else if (this._compression === TiffCompression.zip) {\n const data = p.toUint8Array(0, byteCount);\n const outData = inflate(data);\n byteData = new InputBuffer({\n buffer: outData,\n });\n } else if (this._compression === TiffCompression.oldJpeg) {\n const data = p.toUint8Array(0, byteCount);\n const tile = new JpegDecoder().decode(data);\n if (tile !== undefined) {\n this.jpegToImage(\n tile,\n image,\n outX,\n outY,\n this._tileWidth,\n this._tileHeight\n );\n }\n return;\n } else {\n throw new LibError(\n `Unsupported Compression Type: ${this._compression}`\n );\n }\n\n for (\n let y = 0, py = outY;\n y < this._tileHeight && py < this._height;\n ++y, ++py\n ) {\n for (\n let x = 0, px = outX;\n x < this._tileWidth && px < this._width;\n ++x, ++px\n ) {\n if (this._samplesPerPixel === 1) {\n if (this._sampleFormat === TiffFormat.float) {\n let sample = 0;\n if (this._bitsPerSample === 32) {\n sample = byteData.readFloat32();\n } else if (this._bitsPerSample === 64) {\n sample = byteData.readFloat64();\n } else if (this._bitsPerSample === 16) {\n sample = Float16.float16ToDouble(byteData.readUint16());\n }\n image.setPixelR(px, py, sample);\n } else {\n let sample = 0;\n if (this._bitsPerSample === 8) {\n sample =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt8()\n : byteData.readByte();\n } else if (this._bitsPerSample === 16) {\n sample =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt16()\n : byteData.readUint16();\n } else if (this._bitsPerSample === 32) {\n sample =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt32()\n : byteData.readUint32();\n }\n\n if (this._photometricType === TiffPhotometricType.whiteIsZero) {\n const mx = Math.trunc(image.maxChannelValue);\n sample = mx - sample;\n }\n\n image.setPixelR(px, py, sample);\n }\n } else if (this._samplesPerPixel === 2) {\n let gray = 0;\n let alpha = 0;\n if (this._bitsPerSample === 8) {\n gray =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt8()\n : byteData.readByte();\n alpha =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt8()\n : byteData.readByte();\n } else if (this._bitsPerSample === 16) {\n gray =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt16()\n : byteData.readUint16();\n alpha =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt16()\n : byteData.readUint16();\n } else if (this._bitsPerSample === 32) {\n gray =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt32()\n : byteData.readUint32();\n alpha =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt32()\n : byteData.readUint32();\n }\n\n image.setPixelRgb(px, py, gray, alpha, 0);\n } else if (this._samplesPerPixel === 3) {\n if (this._sampleFormat === TiffFormat.float) {\n let r = 0.0;\n let g = 0.0;\n let b = 0.0;\n if (this._bitsPerSample === 32) {\n r = byteData.readFloat32();\n g = byteData.readFloat32();\n b = byteData.readFloat32();\n } else if (this._bitsPerSample === 64) {\n r = byteData.readFloat64();\n g = byteData.readFloat64();\n b = byteData.readFloat64();\n } else if (this._bitsPerSample === 16) {\n r = Float16.float16ToDouble(byteData.readUint16());\n g = Float16.float16ToDouble(byteData.readUint16());\n b = Float16.float16ToDouble(byteData.readUint16());\n }\n image.setPixelRgb(px, py, r, g, b);\n } else {\n let r = 0;\n let g = 0;\n let b = 0;\n if (this._bitsPerSample === 8) {\n r =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt8()\n : byteData.readByte();\n g =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt8()\n : byteData.readByte();\n b =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt8()\n : byteData.readByte();\n } else if (this._bitsPerSample === 16) {\n r =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt16()\n : byteData.readUint16();\n g =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt16()\n : byteData.readUint16();\n b =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt16()\n : byteData.readUint16();\n } else if (this._bitsPerSample === 32) {\n r =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt32()\n : byteData.readUint32();\n g =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt32()\n : byteData.readUint32();\n b =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt32()\n : byteData.readUint32();\n }\n\n image.setPixelRgb(px, py, r, g, b);\n }\n } else if (this._samplesPerPixel >= 4) {\n if (this._sampleFormat === TiffFormat.float) {\n let r = 0.0;\n let g = 0.0;\n let b = 0.0;\n let a = 0.0;\n if (this._bitsPerSample === 32) {\n r = byteData.readFloat32();\n g = byteData.readFloat32();\n b = byteData.readFloat32();\n a = byteData.readFloat32();\n } else if (this._bitsPerSample === 64) {\n r = byteData.readFloat64();\n g = byteData.readFloat64();\n b = byteData.readFloat64();\n a = byteData.readFloat64();\n } else if (this._bitsPerSample === 16) {\n r = Float16.float16ToDouble(byteData.readUint16());\n g = Float16.float16ToDouble(byteData.readUint16());\n b = Float16.float16ToDouble(byteData.readUint16());\n a = Float16.float16ToDouble(byteData.readUint16());\n }\n image.setPixelRgba(px, py, r, g, b, a);\n } else {\n let r = 0;\n let g = 0;\n let b = 0;\n let a = 0;\n if (this._bitsPerSample === 8) {\n r =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt8()\n : byteData.readByte();\n g =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt8()\n : byteData.readByte();\n b =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt8()\n : byteData.readByte();\n a =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt8()\n : byteData.readByte();\n } else if (this._bitsPerSample === 16) {\n r =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt16()\n : byteData.readUint16();\n g =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt16()\n : byteData.readUint16();\n b =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt16()\n : byteData.readUint16();\n a =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt16()\n : byteData.readUint16();\n } else if (this._bitsPerSample === 32) {\n r =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt32()\n : byteData.readUint32();\n g =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt32()\n : byteData.readUint32();\n b =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt32()\n : byteData.readUint32();\n a =\n this._sampleFormat === TiffFormat.int\n ? byteData.readInt32()\n : byteData.readUint32();\n }\n\n if (this._photometricType === TiffPhotometricType.cmyk) {\n const rgba = ColorUtils.cmykToRgb(r, g, b, a);\n r = rgba[0];\n g = rgba[1];\n b = rgba[2];\n a = Math.trunc(image.maxChannelValue);\n }\n\n image.setPixelRgba(px, py, r, g, b, a);\n }\n }\n }\n }\n } else {\n throw new LibError(`Unsupported bitsPerSample: ${this._bitsPerSample}`);\n }\n }\n\n private jpegToImage(\n tile: MemoryImage,\n image: MemoryImage,\n outX: number,\n outY: number,\n tileWidth: number,\n tileHeight: number\n ): void {\n const width = tileWidth;\n const height = tileHeight;\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n image.setPixel(x + outX, y + outY, tile.getPixel(x, y));\n }\n }\n }\n\n /**\n * Uncompress packbits compressed image data.\n */\n private decodePackBits(\n data: InputBuffer,\n arraySize: number,\n dst: Uint8Array\n ): void {\n let srcCount = 0;\n let dstCount = 0;\n\n while (dstCount < arraySize) {\n const b = BitUtils.uint8ToInt8(data.getByte(srcCount++));\n if (b >= 0 && b <= 127) {\n // literal run packet\n for (let i = 0; i < b + 1; ++i) {\n dst[dstCount++] = data.getByte(srcCount++);\n }\n } else if (b <= -1 && b >= -127) {\n // 2 byte encoded run packet\n const repeat = data.getByte(srcCount++);\n for (let i = 0; i < -b + 1; ++i) {\n dst[dstCount++] = repeat;\n }\n } else {\n // no-op packet. Do nothing\n srcCount++;\n }\n }\n }\n\n public decode(p: InputBuffer): MemoryImage {\n const isFloat = this._sampleFormat === TiffFormat.float;\n const isInt = this._sampleFormat === TiffFormat.int;\n const format =\n this._bitsPerSample === 1\n ? Format.uint1\n : this._bitsPerSample === 2\n ? Format.uint2\n : this._bitsPerSample === 4\n ? Format.uint4\n : isFloat && this._bitsPerSample === 16\n ? Format.float16\n : isFloat && this._bitsPerSample === 32\n ? Format.float32\n : isFloat && this._bitsPerSample === 64\n ? Format.float64\n : isInt && this._bitsPerSample === 8\n ? Format.int8\n : isInt && this._bitsPerSample === 16\n ? Format.int16\n : isInt && this._bitsPerSample === 32\n ? Format.int32\n : this._bitsPerSample === 16\n ? Format.uint16\n : this._bitsPerSample === 32\n ? Format.uint32\n : Format.uint8;\n const hasPalette =\n this._colorMap !== undefined &&\n this._photometricType === TiffPhotometricType.palette;\n const numChannels = hasPalette ? 3 : this._samplesPerPixel;\n\n const image = new MemoryImage({\n width: this._width,\n height: this._height,\n format: format,\n numChannels: numChannels,\n withPalette: hasPalette,\n });\n\n if (hasPalette) {\n const p = image.palette!;\n const cm = this._colorMap!;\n const numChannels = 3;\n // Only support RGB palettes\n const numColors = Math.trunc(cm.length / numChannels);\n for (let i = 0; i < numColors; ++i) {\n p.setRgb(\n i,\n cm[this._colorMapRed + i],\n cm[this._colorMapGreen + i],\n cm[this._colorMapBlue + i]\n );\n }\n }\n\n for (let tileY = 0, ti = 0; tileY < this._tilesY; ++tileY) {\n for (let tileX = 0; tileX < this._tilesX; ++tileX, ++ti) {\n this.decodeTile(p, image, tileX, tileY);\n }\n }\n\n return image;\n }\n\n public hasTag(tag: number): boolean {\n return this._tags.has(tag);\n }\n}\n", "/** @format */\n\nimport { Color } from '../../color/color';\nimport { DecodeInfo } from '../decode-info';\nimport { TiffImage } from './tiff-image';\n\nexport interface TiffInfoInitOptions {\n bigEndian: boolean;\n signature: number;\n ifdOffset: number;\n images: TiffImage[];\n}\n\nexport class TiffInfo implements DecodeInfo {\n private _bigEndian: boolean;\n public get bigEndian(): boolean {\n return this._bigEndian;\n }\n\n private _signature: number;\n public get signature(): number {\n return this._signature;\n }\n\n private _ifdOffset: number;\n public get ifdOffset(): number {\n return this._ifdOffset;\n }\n\n private _images: TiffImage[] = [];\n public get images(): TiffImage[] {\n return this._images;\n }\n\n private _width = 0;\n public get width(): number {\n return this._width;\n }\n\n private _height = 0;\n public get height(): number {\n return this._height;\n }\n\n private _backgroundColor: Color | undefined = undefined;\n public get backgroundColor(): Color | undefined {\n throw this._backgroundColor;\n }\n\n public get numFrames(): number {\n return this._images.length;\n }\n\n constructor(opt: TiffInfoInitOptions) {\n this._bigEndian = opt.bigEndian;\n this._signature = opt.signature;\n this._ifdOffset = opt.ifdOffset;\n this._images = opt.images;\n if (this._images.length > 0) {\n this._width = this._images[0].width;\n this._height = this._images[0].height;\n }\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../common/input-buffer';\nimport { ExifData } from '../exif/exif-data';\nimport { FrameType } from '../image/frame-type';\nimport { MemoryImage } from '../image/image';\nimport { Decoder } from './decoder';\nimport { TiffImage } from './tiff/tiff-image';\nimport { TiffInfo } from './tiff/tiff-info';\n\nexport class TiffDecoder implements Decoder {\n private static readonly _tiffSignature = 42;\n private static readonly _tiffLittleEndian = 0x4949;\n private static readonly _tiffBigEndian = 0x4d4d;\n\n private _input!: InputBuffer;\n\n private _info: TiffInfo | undefined = undefined;\n public get info(): TiffInfo | undefined {\n return this._info;\n }\n\n private _exifData: ExifData | undefined = undefined;\n public get exifData(): ExifData | undefined {\n return this._exifData;\n }\n\n /**\n * How many frames are available to be decoded. **startDecode** should have been called first.\n * Non animated image files will have a single frame.\n */\n public get numFrames(): number {\n return this._info !== undefined ? this._info.images.length : 0;\n }\n\n /**\n * Read the TIFF header and IFD blocks.\n */\n private readHeader(p: InputBuffer): TiffInfo | undefined {\n const byteOrder = p.readUint16();\n if (\n byteOrder !== TiffDecoder._tiffLittleEndian &&\n byteOrder !== TiffDecoder._tiffBigEndian\n ) {\n return undefined;\n }\n\n let bigEndian = false;\n if (byteOrder === TiffDecoder._tiffBigEndian) {\n p.bigEndian = true;\n bigEndian = true;\n } else {\n p.bigEndian = false;\n bigEndian = false;\n }\n\n let signature = 0;\n signature = p.readUint16();\n if (signature !== TiffDecoder._tiffSignature) {\n return undefined;\n }\n\n let offset = p.readUint32();\n const ifdOffset = offset;\n\n const p2 = InputBuffer.from(p);\n p2.offset = offset;\n\n const images: TiffImage[] = [];\n while (offset !== 0) {\n let img: TiffImage | undefined = undefined;\n try {\n img = new TiffImage(p2);\n if (!img.isValid) {\n break;\n }\n } catch (error) {\n break;\n }\n images.push(img);\n\n offset = p2.readUint32();\n if (offset !== 0) {\n p2.offset = offset;\n }\n }\n\n return images.length > 0\n ? new TiffInfo({\n bigEndian: bigEndian,\n signature: signature,\n ifdOffset: ifdOffset,\n images: images,\n })\n : undefined;\n }\n\n /**\n * Is the given file a valid TIFF image?\n */\n public isValidFile(bytes: Uint8Array): boolean {\n const buffer = new InputBuffer({\n buffer: bytes,\n });\n return this.readHeader(buffer) !== undefined;\n }\n\n /**\n * Validate the file is a TIFF image and get information about it.\n * If the file is not a valid TIFF image, undefined is returned.\n */\n public startDecode(bytes: Uint8Array): TiffInfo | undefined {\n this._input = new InputBuffer({\n buffer: bytes,\n });\n this._info = this.readHeader(this._input);\n if (this.info !== undefined) {\n const buffer = new InputBuffer({\n buffer: bytes,\n });\n this._exifData = ExifData.fromInputBuffer(buffer);\n }\n return this._info;\n }\n\n /**\n * Decode a single frame from the data stat was set with **startDecode**.\n * If **frame** is out of the range of available frames, undefined is returned.\n * Non animated image files will only have **frame** 0.\n */\n public decodeFrame(frame: number): MemoryImage | undefined {\n if (this._info === undefined) {\n return undefined;\n }\n\n const image = this._info.images[frame].decode(this._input);\n if (this._exifData !== undefined) {\n image.exifData = this._exifData;\n }\n return image;\n }\n\n /**\n * Decode the file and extract a single image from it. If the file is\n * animated, the specified **frame** will be decoded. If there was a problem\n * decoding the file, undefined is returned.\n */\n public decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined {\n this._input = new InputBuffer({\n buffer: bytes,\n });\n\n this._info = this.readHeader(this._input);\n if (this._info === undefined) {\n return undefined;\n }\n\n const len = this.numFrames;\n if (len === 1 || frame !== undefined) {\n return this.decodeFrame(frame ?? 0);\n }\n\n const image = this.decodeFrame(0);\n if (image === undefined) {\n return undefined;\n }\n image.exifData = ExifData.fromInputBuffer(\n new InputBuffer({\n buffer: bytes,\n })\n );\n image.frameType = FrameType.page;\n\n for (let i = 1; i < len; ++i) {\n const frame = this.decodeFrame(i);\n image.addFrame(frame);\n }\n\n return image;\n }\n}\n", "/** @format */\n\nimport { Format, FormatType } from '../color/format';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { LibError } from '../error/lib-error';\nimport { ExifData } from '../exif/exif-data';\nimport { IfdUndefinedValue } from '../exif/ifd-value/ifd-undefined-value';\nimport { MemoryImage } from '../image/image';\nimport { Encoder } from './encoder';\nimport { TiffCompression } from './tiff/tiff-compression';\nimport { TiffFormat } from './tiff/tiff-format';\nimport { TiffPhotometricType } from './tiff/tiff-photometric-type';\n\n/**\n * Encode a MemoryImage to the TIFF format.\n */\nexport class TiffEncoder implements Encoder {\n private _supportsAnimation = false;\n public get supportsAnimation(): boolean {\n return this._supportsAnimation;\n }\n\n private getSampleFormat(image: MemoryImage): number {\n switch (image.formatType) {\n case FormatType.uint:\n return TiffFormat.uint;\n case FormatType.int:\n return TiffFormat.int;\n case FormatType.float:\n return TiffFormat.float;\n }\n throw new LibError('Unknown TIFF format type.');\n }\n\n public encode(image: MemoryImage, _singleFrame = false): Uint8Array {\n let img = image;\n\n const out = new OutputBuffer();\n\n // TIFF is really just an EXIF structure (or, really, EXIF is just a TIFF\n // structure).\n\n const exif = new ExifData();\n if (img.exifData.size > 0) {\n exif.imageIfd.copyFrom(img.exifData.imageIfd);\n }\n\n // TODO: support encoding HDR images to TIFF.\n if (img.isHdrFormat) {\n img = img.convert({\n format: Format.uint8,\n });\n }\n\n const type =\n img.numChannels === 1\n ? TiffPhotometricType.blackIsZero\n : img.hasPalette\n ? TiffPhotometricType.palette\n : TiffPhotometricType.rgb;\n\n const nc = img.numChannels;\n\n const ifd0 = exif.imageIfd;\n ifd0.setValue('ImageWidth', img.width);\n ifd0.setValue('ImageHeight', img.height);\n ifd0.setValue('BitsPerSample', img.bitsPerChannel);\n ifd0.setValue('SampleFormat', this.getSampleFormat(img));\n ifd0.setValue('SamplesPerPixel', img.hasPalette ? 1 : nc);\n ifd0.setValue('Compression', TiffCompression.none);\n ifd0.setValue('PhotometricInterpretation', type);\n ifd0.setValue('RowsPerStrip', img.height);\n ifd0.setValue('PlanarConfiguration', 1);\n ifd0.setValue('TileWidth', img.width);\n ifd0.setValue('TileLength', img.height);\n ifd0.setValue('StripByteCounts', img.byteLength);\n ifd0.setValue('StripOffsets', new IfdUndefinedValue(img.toUint8Array()));\n\n if (img.hasPalette) {\n const p = img.palette!;\n // Only support RGB palettes\n const numCh = 3;\n const numC = p.numColors;\n const colorMap = new Uint16Array(numC * numCh);\n for (let c = 0, ci = 0; c < numCh; ++c) {\n for (let i = 0; i < numC; ++i) {\n colorMap[ci++] = Math.trunc(p.get(i, c)) << 8;\n }\n }\n\n ifd0.setValue('ColorMap', colorMap);\n }\n\n exif.write(out);\n\n return out.getBytes();\n }\n}\n", "/** @format */\n\nexport enum IccProfileCompression {\n none,\n deflate,\n}\n", "/** @format */\n\nimport { inflate, deflate } from 'uzip';\nimport { ArrayUtils } from '../common/array-utils';\nimport { IccProfileCompression } from './icc-profile-compression';\n\n/**\n * ICC Profile data stored with an image.\n */\nexport class IccProfile {\n private _name: string;\n public get name(): string {\n return this._name;\n }\n\n private _compression: IccProfileCompression;\n public get compression(): IccProfileCompression {\n return this._compression;\n }\n\n private _data: Uint8Array;\n public get data(): Uint8Array {\n return this._data;\n }\n\n constructor(\n name: string,\n compression: IccProfileCompression,\n data: Uint8Array\n ) {\n this._name = name;\n this._compression = compression;\n this._data = data;\n }\n\n public static from(other: IccProfile) {\n return new IccProfile(\n other._name,\n other._compression,\n ArrayUtils.copyUint8(other._data)\n );\n }\n\n /**\n * Returns the compressed data of the ICC Profile, compressing the stored data as necessary.\n */\n public compressed(): Uint8Array {\n if (this._compression === IccProfileCompression.deflate) {\n return this._data;\n }\n this._data = deflate(this._data);\n this._compression = IccProfileCompression.deflate;\n return this._data;\n }\n\n /**\n * Returns the uncompressed data of the ICC Profile, decompressing the stored data as necessary.\n */\n public decompressed(): Uint8Array {\n if (this._compression === IccProfileCompression.deflate) {\n return this._data;\n }\n this._data = inflate(this._data);\n this._compression = IccProfileCompression.none;\n return this._data;\n }\n\n public clone(): IccProfile {\n return IccProfile.from(this);\n }\n}\n", "/** @format */\n\nimport { ChannelOrder } from '../color/channel-order';\nimport { Color } from '../color/color';\nimport { Format, FormatType } from '../color/format';\nimport { Palette } from './palette';\nimport { Pixel } from './pixel';\n\nexport interface MemoryImageData extends Iterable {\n get width(): number;\n\n get height(): number;\n\n get numChannels(): number;\n\n /**\n * The channel **Format** of the image.\n */\n get format(): Format;\n\n /**\n * Whether the image has uint, int, or float data.\n */\n get formatType(): FormatType;\n\n /**\n * True if the image format is \"high dynamic range.\" HDR formats include:\n * float16, float32, float64, int8, int16, and int32.\n */\n get isHdrFormat(): boolean;\n\n /**\n * True if the image format is \"low dynamic range.\" LDR formats include:\n * uint1, uint2, uint4, and uint8.\n */\n get isLdrFormat(): boolean;\n\n /**\n * The number of bits per color channel. Can be 1, 2, 4, 8, 16, 32, or 64.\n */\n get bitsPerChannel(): number;\n\n /**\n * The maximum value of a pixel channel, based on the **format** of the image.\n * If the image has a **palette**, this will be the maximum value of a palette\n * color channel. Float format images will have a **maxChannelValue** of 1,\n * though they can have values above that.\n */\n get maxChannelValue(): number;\n\n /**\n * The maximum value of a palette index, based on the **format** of the image.\n * This differs from **maxChannelValue** in that it will not be affected by\n * the format of the **palette**.\n */\n get maxIndexValue(): number;\n\n /**\n * True if the image has a palette. If the image has a palette, then the\n * image data has 1 channel for the palette index of the pixel.\n */\n get hasPalette(): boolean;\n\n /**\n * The **Palette** of the image, or undefined if the image does not have one.\n */\n get palette(): Palette | undefined;\n\n /**\n * The size of the image data in bytes.\n */\n get byteLength(): number;\n\n /**\n * The size of the image data in bytes.\n */\n get length(): number;\n\n /**\n * The **ArrayBufferLike** storage of the image.\n */\n get buffer(): ArrayBufferLike;\n\n /**\n * The size, in bytes, of a row if pixels in the data.\n */\n get rowStride(): number;\n\n /**\n * Returns a pixel iterator for iterating over a rectangular range of pixels\n * in the image.\n */\n getRange(\n x: number,\n y: number,\n width: number,\n height: number\n ): Iterator;\n\n /**\n * Create a **Color** object with the format and number of channels of the\n * image.\n */\n getColor(r: number, g: number, b: number, a?: number): Color;\n\n /**\n * Return the **Pixel** at the given coordinates. If **pixel** is provided,\n * it will be updated and returned rather than allocating a new **Pixel**.\n */\n getPixel(x: number, y: number, pixel?: Pixel): Pixel;\n\n /**\n * Set the color of the pixel at the given coordinates to the color of the\n * given Color **c**.\n */\n setPixel(x: number, y: number, c: Color): void;\n\n /**\n * Set the red channel of the pixel, or the index value for palette images.\n */\n setPixelR(x: number, y: number, r: number): void;\n\n /**\n * Set the color of the **Pixel** at the given coordinates to the given\n * color values **r**, **g**, **b**.\n */\n setPixelRgb(x: number, y: number, r: number, g: number, b: number): void;\n\n /**\n * Set the color of the **Pixel** at the given coordinates to the given\n * color values **r**, **g**, **b**, and **a**.\n */\n setPixelRgba(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void;\n\n /**\n * Calls **setPixelRgb**, but ensures **x** and **y** are within the extents\n * of the image, otherwise it returns without setting the pixel.\n */\n setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void;\n\n /**\n * Calls **setPixelRgba**, but ensures **x** and **y** are within the extents\n * of the image, otherwise it returns without setting the pixel.\n */\n setPixelRgbaSafe(\n x: number,\n y: number,\n r: number,\n g: number,\n b: number,\n a: number\n ): void;\n\n /**\n * Set all of the pixels to the Color **c**, or all values to 0 if **c** is not\n * given.\n */\n clear(c?: Color): void;\n\n /**\n * Get the copy of this image data.\n */\n clone(noPixels?: boolean): MemoryImageData;\n\n /**\n * The storage data of the image.\n */\n toUint8Array(): Uint8Array;\n\n /**\n * Similar to toUint8Array, but will convert the channels of the image pixels\n * to the given **order**. If that happens, the returned bytes will be a copy\n * and not a direct view of the image data.\n */\n getBytes(order?: ChannelOrder): Uint8Array;\n}\n", "/** @format */\n\nimport { Format } from '../color/format';\n\nexport interface Palette {\n /**\n * The size of the palette data in bytes.\n */\n get byteLength(): number;\n /**\n * The byte buffer storage of the palette data.\n */\n get buffer(): ArrayBufferLike;\n /**\n * The number of colors stored in the palette.\n */\n get numColors(): number;\n /**\n * The number of channels per color.\n */\n get numChannels(): number;\n get maxChannelValue(): number;\n /**\n * The format of the color data.\n */\n get format(): Format;\n /**\n * Set the RGB color of a palette entry at **index**. If the palette has fewer\n * channels than are set, the unsupported channels will be ignored.\n */\n setRgb(index: number, r: number, g: number, b: number): void;\n /**\n * Set the RGBA color of a palette entry at **index**. If the palette has fewer\n * channels than are set, the unsupported channels will be ignored.\n */\n setRgba(index: number, r: number, g: number, b: number, a: number): void;\n /**\n * Set a specific **channel** **value** of the palette entry at **index**. If the\n * palette has fewer channels than **channel**, the value will be ignored.\n */\n set(index: number, channel: number, value: number): void;\n /**\n * Get the the value of a specific **channel** of the palette entry at **index**.\n * If the palette has fewer colors than **index** or fewer channels than\n * **channel**, 0 will be returned.\n */\n get(index: number, channel: number): number;\n /**\n * Get the red channel of the palette entry at **index**. If the palette has\n * fewer colors or channels, 0 will be returned.\n */\n getRed(index: number): number;\n /**\n * Set the red channel of the palette entry at **index**. If the palette has\n * fewer colors or channels, it will be ignored.\n */\n setRed(index: number, value: number): void;\n /**\n * Get the green channel of the palette entry at **index**. If the palette has\n * fewer colors or channels, 0 will be returned.\n */\n getGreen(index: number): number;\n /**\n * Set the green channel of the palette entry at **index**. If the palette has\n * fewer colors or channels, it will be ignored.\n */\n setGreen(index: number, value: number): void;\n /**\n * Get the blue channel of the palette entry at **index**. If the palette has\n * fewer colors or channels, 0 will be returned.\n */\n getBlue(index: number): number;\n /**\n * Set the blue channel of the palette entry at **index**. If the palette has\n * fewer colors or channels, it will be ignored.\n */\n setBlue(index: number, value: number): void;\n /**\n * Get the alpha channel of the palette entry at **index**. If the palette has\n * fewer colors or channels, 0 will be returned.\n */\n getAlpha(index: number): number;\n /**\n * Set the alpha channel of the palette entry at **index**. If the palette has\n * fewer colors or channels, it will be ignored.\n */\n setAlpha(index: number, value: number): void;\n /**\n * Create a copy of the Palette.\n */\n clone(): Palette;\n /**\n * A Uint8Array view of the palette buffer storage.\n */\n toUint8Array(): Uint8Array;\n}\n", "/** @format */\n\nimport { Color } from '../color/color';\nimport { MemoryImage } from './image';\nimport { Palette } from './palette';\n\n/**\n * Interface for color quantizers, which reduce the total number of colors\n * used by an image to a given maximum, used to convert images to palette\n * images.\n */\nexport interface Quantizer {\n get palette(): Palette;\n\n getColorIndex(c: Color): number;\n\n getColorIndexRgb(r: number, g: number, b: number): number;\n\n /**\n * Find the index of the closest color to **c** in the **palette**.\n */\n getQuantizedColor(c: Color): Color;\n\n /**\n * Convert the **image** to a palette image.\n */\n getIndexImage(image: MemoryImage): MemoryImage;\n}\n", "/** @format */\n\nexport enum FlipDirection {\n /**\n * Flip the image horizontally.\n */\n horizontal,\n\n /**\n * Flip the image vertically.\n */\n vertical,\n\n /**\n * Flip the image both horizontally and vertically.\n */\n both,\n}\n", "/** @format */\n\nexport enum TrimSide {\n top = 1,\n bottom = 2,\n left = 4,\n right = 8,\n all = top | bottom | left | right,\n}\n", "/** @format */\n\nexport enum TrimMode {\n /**\n * Trim an image to the top-left and bottom-right most non-transparent pixels\n */\n transparent,\n /**\n * Trim an image to the top-left and bottom-right most pixels that are not\n * the same as the top-left most pixel of the image.\n */\n topLeftColor,\n /**\n * Trim an image to the top-left and bottom-right most pixels that are not\n * the same as the bottom-right most pixel of the image.\n */\n bottomRightColor,\n}\n", "/** @format */\n\nimport { LibError } from '../error/lib-error';\nimport { Point } from '../common/point';\nimport { Interpolation } from '../common/interpolation';\nimport { MathUtils } from '../common/math-utils';\nimport { ExifData } from '../exif/exif-data';\nimport { MemoryImage } from '../image/image';\nimport { ImageUtils } from '../image/image-utils';\nimport { Pixel } from '../image/pixel';\nimport { FlipDirection } from './flip-direction';\nimport { TrimSide } from './trim-side';\nimport { Rectangle } from '../common/rectangle';\nimport { Draw } from '../draw/draw';\nimport { BlendMode } from '../draw/blend-mode';\nimport { TrimMode } from './trim-mode';\n\nexport interface TransformOptions {\n image: MemoryImage;\n}\n\nexport interface CopyCropCircleOptions extends TransformOptions {\n radius?: number;\n center?: Point;\n antialias?: boolean;\n}\n\nexport interface CopyCropOptions extends TransformOptions {\n rect: Rectangle;\n radius?: number;\n antialias?: boolean;\n}\n\nexport interface CopyRectifyOptions extends TransformOptions {\n topLeft: Point;\n topRight: Point;\n bottomLeft: Point;\n bottomRight: Point;\n interpolation?: Interpolation;\n toImage?: MemoryImage;\n}\n\nexport interface CopyResizeCropSquareOptions extends TransformOptions {\n size: number;\n interpolation?: Interpolation;\n radius?: number;\n antialias?: boolean;\n}\n\nexport interface CopyResizeOptionsUsingWidth extends TransformOptions {\n width: number;\n height?: number;\n interpolation?: Interpolation;\n}\n\nexport interface CopyResizeOptionsUsingHeight extends TransformOptions {\n height: number;\n width?: number;\n interpolation?: Interpolation;\n}\n\nexport interface CopyRotateOptions extends TransformOptions {\n angle: number;\n interpolation?: Interpolation;\n}\n\nexport interface FlipOptions extends TransformOptions {\n direction: FlipDirection;\n}\n\nexport interface TrimOptions extends TransformOptions {\n mode?: TrimMode;\n sides?: TrimSide;\n}\n\nexport abstract class Transform {\n private static rotate90(src: MemoryImage) {\n let firstFrame: MemoryImage | undefined = undefined;\n for (const frame of src.frames) {\n const dst: MemoryImage =\n firstFrame?.addFrame() ??\n MemoryImage.fromResized(frame, frame.height, frame.width, true);\n firstFrame ??= dst;\n const hm1 = frame.height - 1;\n for (let y = 0; y < dst.height; ++y) {\n for (let x = 0; x < dst.width; ++x) {\n dst.setPixel(x, y, frame.getPixel(y, hm1 - x));\n }\n }\n }\n return firstFrame!;\n }\n\n private static rotate180(src: MemoryImage) {\n let firstFrame: MemoryImage | undefined = undefined;\n for (const frame of src.frames) {\n const wm1 = frame.width - 1;\n const hm1 = frame.height - 1;\n const dst: MemoryImage =\n firstFrame?.addFrame() ?? MemoryImage.from(frame, true, true);\n firstFrame ??= dst;\n for (let y = 0; y < dst.height; ++y) {\n for (let x = 0; x < dst.width; ++x) {\n dst.setPixel(x, y, frame.getPixel(wm1 - x, hm1 - y));\n }\n }\n }\n return firstFrame!;\n }\n\n private static rotate270(src: MemoryImage) {\n let firstFrame: MemoryImage | undefined = undefined;\n for (const frame of src.frames) {\n const wm1 = src.width - 1;\n const dst: MemoryImage =\n firstFrame?.addFrame() ??\n MemoryImage.fromResized(frame, frame.height, frame.width, true);\n firstFrame ??= dst;\n for (let y = 0; y < dst.height; ++y) {\n for (let x = 0; x < dst.width; ++x) {\n dst.setPixel(x, y, frame.getPixel(wm1 - y, x));\n }\n }\n }\n return firstFrame!;\n }\n\n /**\n * Find the crop area to be used by the trim function.\n *\n * Returns the Rectangle. You could pass these constraints\n * to the **copyCrop** function to crop the image.\n */\n private static findTrim(opt: TrimOptions): Rectangle {\n const mode = opt.mode ?? TrimMode.transparent;\n const sides = opt.sides ?? TrimSide.all;\n\n let h = opt.image.height;\n let w = opt.image.width;\n\n const bg =\n mode === TrimMode.topLeftColor\n ? opt.image.getPixel(0, 0)\n : mode === TrimMode.bottomRightColor\n ? opt.image.getPixel(w - 1, h - 1)\n : undefined;\n\n let xMin = w;\n let xMax = 0;\n let yMin: number | undefined = undefined;\n let yMax = 0;\n\n for (let y = 0; y < h; ++y) {\n let first = true;\n for (let x = 0; x < w; ++x) {\n const c = opt.image.getPixel(x, y);\n if (\n (mode === TrimMode.transparent && c.a !== 0) ||\n (mode !== TrimMode.transparent && (bg === undefined || !c.equals(bg)))\n ) {\n if (xMin > x) {\n xMin = x;\n }\n if (xMax < x) {\n xMax = x;\n }\n yMin ??= y;\n\n yMax = y;\n\n if (first) {\n x = xMax;\n first = false;\n }\n }\n }\n }\n\n // A trim wasn't found\n if (yMin === undefined) {\n return new Rectangle(0, 0, w, h);\n }\n\n if (!(sides & TrimSide.top)) {\n yMin = 0;\n }\n if (!(sides & TrimSide.bottom)) {\n yMax = h - 1;\n }\n if (!(sides & TrimSide.left)) {\n xMin = 0;\n }\n if (!(sides & TrimSide.right)) {\n xMax = w - 1;\n }\n\n // Image width in pixels\n w = 1 + xMax - xMin;\n // Image height in pixels\n h = 1 + yMax - yMin;\n\n return Rectangle.fromXYWH(xMin, yMin, w, h);\n }\n\n /**\n * If **image** has an orientation value in its exif data, this will rotate the\n * image so that it physically matches its orientation. This can be used to\n * bake the orientation of the image for image formats that don't support exif\n * data.\n */\n public static bakeOrientation(opt: TransformOptions): MemoryImage {\n const bakedImage = MemoryImage.from(opt.image);\n if (\n !opt.image.exifData.imageIfd.hasOrientation ||\n opt.image.exifData.imageIfd.orientation === 1\n ) {\n return bakedImage;\n }\n\n // Copy all exif data except for orientation\n bakedImage.exifData = ExifData.from(opt.image.exifData);\n bakedImage.exifData.imageIfd.orientation = undefined;\n\n switch (opt.image.exifData.imageIfd.orientation) {\n case 2:\n return Transform.flipHorizontal({\n image: bakedImage,\n });\n case 3:\n return Transform.flip({\n image: bakedImage,\n direction: FlipDirection.both,\n });\n case 4: {\n const rotated = Transform.copyRotate({\n image: bakedImage,\n angle: 180,\n });\n return Transform.flipHorizontal({\n image: rotated,\n });\n }\n case 5: {\n const rotated = Transform.copyRotate({\n image: bakedImage,\n angle: 90,\n });\n return Transform.flipHorizontal({\n image: rotated,\n });\n }\n case 6:\n return Transform.copyRotate({\n image: bakedImage,\n angle: 90,\n });\n case 7: {\n const rotated = Transform.copyRotate({\n image: bakedImage,\n angle: -90,\n });\n return Transform.flipHorizontal({\n image: rotated,\n });\n }\n case 8:\n return Transform.copyRotate({\n image: bakedImage,\n angle: -90,\n });\n }\n return bakedImage;\n }\n\n /**\n * Returns a cropped copy of **image**.\n */\n public static copyCrop(opt: CopyCropOptions): MemoryImage {\n let image = opt.image;\n const radius = opt.radius ?? 0;\n const antialias = opt.antialias ?? true;\n\n // Make sure crop rectangle is within the range of the src image.\n const x = MathUtils.clampInt(opt.rect.left, 0, image.width - 1);\n const y = MathUtils.clampInt(opt.rect.top, 0, image.height - 1);\n\n const width =\n x + opt.rect.width > image.width ? image.width - x : opt.rect.width;\n const height =\n y + opt.rect.height > image.height ? image.height - y : opt.rect.height;\n\n if (radius > 0 && image.hasPalette) {\n image = image.convert({\n numChannels: image.numChannels,\n });\n }\n\n let firstFrame: MemoryImage | undefined = undefined;\n const numFrames = image.numFrames;\n for (let i = 0; i < numFrames; ++i) {\n const frame = image.frames[i];\n const dst: MemoryImage =\n firstFrame?.addFrame() ??\n MemoryImage.fromResized(frame, width, height, true);\n firstFrame ??= dst;\n\n if (radius > 0) {\n const rad = Math.round(radius);\n const rad2 = rad * rad;\n const x1 = x;\n const y1 = y;\n const x2 = x + width;\n const y2 = y + height;\n const c1x = x1 + rad - 1;\n const c1y = y1 + rad - 1;\n const c2x = x2 - rad + 1;\n const c2y = y1 + rad - 1;\n const c3x = x2 - rad + 1;\n const c3y = y2 - rad + 1;\n const c4x = x1 + rad - 1;\n const c4y = y2 - rad + 1;\n\n const iter = image.getRange(x1, y1, width, height);\n let iterRes: IteratorResult | undefined = undefined;\n while (((iterRes = iter.next()), !iterRes.done)) {\n const p = iterRes.value;\n const px = p.x;\n const py = p.y;\n\n let a = 1;\n if (px < c1x && py < c1y) {\n a = ImageUtils.circleTest(p, new Point(c1x, c1y), rad2, antialias);\n if (a === 0) {\n dst.setPixelRgba(p.x - x1, p.y - y1, 0, 0, 0, 0);\n continue;\n }\n } else if (px > c2x && py < c2y) {\n a = ImageUtils.circleTest(p, new Point(c2x, c2y), rad2, antialias);\n if (a === 0) {\n dst.setPixelRgba(p.x - x1, p.y - y1, 0, 0, 0, 0);\n continue;\n }\n } else if (px > c3x && py > c3y) {\n a = ImageUtils.circleTest(p, new Point(c3x, c3y), rad2, antialias);\n if (a === 0) {\n dst.setPixelRgba(p.x - x1, p.y - y1, 0, 0, 0, 0);\n continue;\n }\n } else if (px < c4x && py > c4y) {\n a = ImageUtils.circleTest(p, new Point(c4x, c4y), rad2, antialias);\n if (a === 0) {\n dst.setPixelRgba(p.x - x1, p.y - y1, 0, 0, 0, 0);\n continue;\n }\n }\n\n if (a !== 1) {\n dst.getPixel(p.x - x1, p.y - y1).setRgba(p.r, p.g, p.b, p.a * a);\n } else {\n dst.setPixel(p.x - x1, p.y - y1, p);\n }\n }\n } else {\n for (const p of dst) {\n p.set(frame.getPixel(x + p.x, y + p.y));\n }\n }\n }\n\n return firstFrame!;\n }\n\n /**\n * Returns a circle cropped copy of **image**, centered at **centerX** and\n * **centerY** and with the given **radius**. If **radius** is not provided,\n * a radius filling the image will be used. If **centerX** is not provided,\n * the horizontal mid-point of the image will be used. If **centerY** is not\n * provided, the vertical mid-point of the image will be used.\n */\n public static copyCropCircle(opt: CopyCropCircleOptions): MemoryImage {\n let image = opt.image;\n let centerX = opt.center?.x ?? Math.trunc(image.width / 2);\n let centerY = opt.center?.y ?? Math.trunc(image.height / 2);\n let radius =\n opt.radius ?? Math.trunc(Math.min(image.width, image.height) / 2);\n const antialias = opt.antialias ?? true;\n\n // Make sure center point is within the range of the src image\n centerX = MathUtils.clamp(centerX, 0, image.width - 1);\n centerY = MathUtils.clamp(centerY, 0, image.height - 1);\n if (radius < 1) {\n radius = Math.trunc(Math.min(image.width, image.height) / 2);\n }\n\n // topLeft.x\n const tlx = centerX - radius;\n // topLeft.y\n const tly = centerY - radius;\n\n const wh = radius * 2;\n const radiusSqr = radius * radius;\n\n if (image.hasPalette) {\n image = image.convert({\n numChannels: 4,\n });\n }\n\n let firstFrame: MemoryImage | undefined = undefined;\n const numFrames = image.numFrames;\n for (let i = 0; i < numFrames; ++i) {\n const frame = image.frames[i];\n const dst: MemoryImage =\n firstFrame?.addFrame() ?? MemoryImage.fromResized(frame, wh, wh, true);\n firstFrame ??= dst;\n\n const bg = frame.backgroundColor ?? image.backgroundColor;\n if (bg !== undefined) {\n dst.clear(bg);\n }\n\n const dh = dst.height;\n const dw = radius * 2;\n for (let yi = 0, sy = tly; yi < dh; ++yi, ++sy) {\n for (let xi = 0, sx = tlx; xi < dw; ++xi, ++sx) {\n const p = frame.getPixel(sx, sy);\n const a = ImageUtils.circleTest(\n p,\n new Point(centerX, centerY),\n radiusSqr,\n antialias\n );\n\n if (a !== 1) {\n dst.getPixel(xi, yi).setRgba(p.r, p.g, p.b, p.a * a);\n } else {\n dst.setPixel(xi, yi, p);\n }\n }\n }\n }\n\n return firstFrame!;\n }\n\n /**\n * Returns a copy of the **image** image, flipped by the given **direction**.\n */\n public static copyFlip(opt: FlipOptions): MemoryImage {\n return Transform.flip({\n image: opt.image.clone(),\n direction: opt.direction,\n });\n }\n\n /**\n * Returns a copy of the **image**, where the given rectangle\n * has been mapped to the full image.\n */\n public static copyRectify(opt: CopyRectifyOptions): MemoryImage {\n const interpolation = opt.interpolation ?? Interpolation.nearest;\n\n // You can't interpolate index pixels, so we need to convert the image\n // to a non-palette image if non-nearest interpolation is used.\n const src =\n interpolation !== Interpolation.nearest && opt.image.hasPalette\n ? opt.image.convert({\n numChannels: opt.image.numChannels,\n })\n : opt.image;\n\n let firstFrame: MemoryImage | undefined = undefined;\n for (const frame of src.frames) {\n const dst: MemoryImage =\n firstFrame?.addFrame() ?? opt.toImage ?? MemoryImage.from(frame, true);\n firstFrame ??= dst;\n for (let y = 0; y < dst.height; ++y) {\n const v = y / (dst.height - 1);\n for (let x = 0; x < dst.width; ++x) {\n const u = x / (dst.width - 1);\n // bilinear interpolation\n const srcPixelCoord = opt.topLeft\n .mul((1 - u) * (1 - v))\n .add(\n opt.topRight\n .mul(u * (1 - v))\n .add(\n opt.bottomLeft\n .mul((1 - u) * v)\n .add(opt.bottomRight.mul(u * v))\n )\n );\n\n const srcPixel =\n interpolation === Interpolation.nearest\n ? frame.getPixel(\n Math.trunc(srcPixelCoord.x),\n Math.trunc(srcPixelCoord.y)\n )\n : frame.getPixelInterpolate(\n srcPixelCoord.x,\n srcPixelCoord.y,\n interpolation\n );\n\n dst.setPixel(x, y, srcPixel);\n }\n }\n }\n\n return firstFrame!;\n }\n\n /**\n * Returns a resized copy of the **image**.\n *\n * If **height** isn't specified, then it will be determined by the aspect\n * ratio of **image** and **width**.\n *\n * If **width** isn't specified, then it will be determined by the aspect ratio\n * of **image** and **height**.\n */\n public static copyResize(\n opt: CopyResizeOptionsUsingWidth | CopyResizeOptionsUsingHeight\n ): MemoryImage {\n let src = opt.image;\n let interpolation = opt.interpolation ?? Interpolation.nearest;\n\n if (opt.width === undefined && opt.height === undefined) {\n throw new LibError('Invalid size. Please specify the width or height.');\n }\n\n // You can't interpolate index pixels\n if (src.hasPalette) {\n interpolation = Interpolation.nearest;\n }\n\n if (\n src.exifData.imageIfd.hasOrientation &&\n src.exifData.imageIfd.orientation !== 1\n ) {\n src = Transform.bakeOrientation({\n image: src,\n });\n }\n\n // this block sets [width] and [height] if null or negative.\n const height =\n opt.height === undefined || opt.height <= 0\n ? Math.trunc(opt.width! * (src.height / src.width))\n : opt.height;\n\n const width =\n opt.width === undefined || opt.width <= 0\n ? Math.trunc(opt.height! * (src.width / src.height))\n : opt.width;\n\n if (width === src.width && height === src.height) {\n return src.clone();\n }\n\n const scaleX = new Int32Array(width);\n const dx = src.width / width;\n for (let x = 0; x < width; ++x) {\n scaleX[x] = Math.trunc(x * dx);\n }\n\n let firstFrame: MemoryImage | undefined = undefined;\n const numFrames = src.numFrames;\n for (let i = 0; i < numFrames; ++i) {\n const frame = src.frames[i];\n const dst: MemoryImage =\n firstFrame?.addFrame() ??\n MemoryImage.fromResized(frame, width, height, true);\n firstFrame ??= dst;\n\n const dy = frame.height / height;\n const dx = frame.width / width;\n\n if (interpolation === Interpolation.average) {\n for (let y = 0; y < height; ++y) {\n const y1 = Math.trunc(y * dy);\n let y2 = Math.trunc((y + 1) * dy);\n if (y2 === y1) {\n y2++;\n }\n\n for (let x = 0; x < width; ++x) {\n const x1 = Math.trunc(x * dx);\n let x2 = Math.trunc((x + 1) * dx);\n if (x2 === x1) {\n x2++;\n }\n\n let r = 0;\n let g = 0;\n let b = 0;\n let a = 0;\n let np = 0;\n for (let sy = y1; sy < y2; ++sy) {\n for (let sx = x1; sx < x2; ++sx, ++np) {\n const s = frame.getPixel(sx, sy);\n r += s.r;\n g += s.g;\n b += s.b;\n a += s.a;\n }\n }\n dst.setPixel(x, y, dst.getColor(r / np, g / np, b / np, a / np));\n }\n }\n } else if (interpolation === Interpolation.nearest) {\n for (let y = 0; y < height; ++y) {\n const y2 = Math.trunc(y * dy);\n for (let x = 0; x < width; ++x) {\n dst.setPixel(x, y, frame.getPixel(scaleX[x], y2));\n }\n }\n } else {\n // Copy the pixels from this image to the new image.\n for (let y = 0; y < height; ++y) {\n const y2 = y * dy;\n for (let x = 0; x < width; ++x) {\n const x2 = x * dx;\n dst.setPixel(\n x,\n y,\n frame.getPixelInterpolate(x2, y2, interpolation)\n );\n }\n }\n }\n }\n\n return firstFrame!;\n }\n\n /**\n * Returns a resized and square cropped copy of the **image** of **size** size.\n */\n public static copyResizeCropSquare(\n opt: CopyResizeCropSquareOptions\n ): MemoryImage {\n const src = opt.image;\n let interpolation = opt.interpolation ?? Interpolation.nearest;\n const radius = opt.radius ?? 0;\n const antialias = opt.antialias ?? true;\n\n if (opt.size <= 0) {\n throw new LibError('Invalid size.');\n }\n\n // You can't interpolate index pixels\n if (src.hasPalette) {\n interpolation = Interpolation.nearest;\n }\n\n let height = opt.size;\n let width = opt.size;\n if (src.width < src.height) {\n height = Math.trunc(opt.size * (src.height / src.width));\n } else if (src.width > src.height) {\n width = Math.trunc(opt.size * (src.width / src.height));\n }\n\n const dy = src.height / height;\n const dx = src.width / width;\n\n const xOffset = Math.trunc((width - opt.size) / 2);\n const yOffset = Math.trunc((height - opt.size) / 2);\n\n const scaleX =\n interpolation === Interpolation.nearest\n ? new Int32Array(opt.size)\n : undefined;\n\n if (scaleX !== undefined) {\n for (let x = 0; x < opt.size; ++x) {\n scaleX[x] = Math.trunc((x + xOffset) * dx);\n }\n }\n\n let firstFrame: MemoryImage | undefined = undefined;\n for (const frame of src.frames) {\n const dst: MemoryImage =\n firstFrame?.addFrame() ??\n MemoryImage.fromResized(frame, opt.size, opt.size, true);\n firstFrame ??= dst;\n\n // Rounded corners\n if (radius > 0) {\n const rad = Math.round(radius);\n const rad2 = rad * rad;\n const x1 = 0;\n const y1 = 0;\n const x2 = opt.size - 1;\n const y2 = opt.size - 1;\n const c1x = x1 + rad - 1;\n const c1y = y1 + rad - 1;\n const c2x = x2 - rad + 1;\n const c2y = y1 + rad - 1;\n const c3x = x2 - rad + 1;\n const c3y = y2 - rad + 1;\n const c4x = x1 + rad - 1;\n const c4y = y2 - rad + 1;\n\n const iter = dst.getRange(x1, y1, width, height);\n let iterRes: IteratorResult | undefined = undefined;\n while (((iterRes = iter.next()), !iterRes.done)) {\n const p = iterRes.value;\n const px = p.x;\n const py = p.y;\n\n let a = 1;\n if (px < c1x && py < c1y) {\n a = ImageUtils.circleTest(p, new Point(c1x, c1y), rad2, antialias);\n if (a === 0) {\n p.setRgba(0, 0, 0, 0);\n continue;\n }\n } else if (px > c2x && py < c2y) {\n a = ImageUtils.circleTest(p, new Point(c2x, c2y), rad2, antialias);\n if (a === 0) {\n p.setRgba(0, 0, 0, 0);\n continue;\n }\n } else if (px > c3x && py > c3y) {\n a = ImageUtils.circleTest(p, new Point(c3x, c3y), rad2, antialias);\n if (a === 0) {\n p.setRgba(0, 0, 0, 0);\n continue;\n }\n } else if (px < c4x && py > c4y) {\n a = ImageUtils.circleTest(p, new Point(c4x, c4y), rad2, antialias);\n if (a === 0) {\n p.setRgba(0, 0, 0, 0);\n continue;\n }\n }\n\n if (interpolation === Interpolation.nearest) {\n const sy = Math.trunc((p.y + yOffset) * dy);\n const sp = frame.getPixel(scaleX![p.x], sy);\n p.setRgba(sp.r, sp.g, sp.b, sp.a * a);\n } else {\n const x = p.x * dx;\n const y = p.y * dy;\n const sp = frame.getPixelInterpolate(x, y, interpolation);\n const spa = sp.a * a;\n p.setRgba(sp.r, sp.g, sp.b, spa);\n }\n }\n\n return dst;\n }\n\n if (interpolation === Interpolation.nearest) {\n for (let y = 0; y < opt.size; ++y) {\n const y2 = Math.trunc((y + yOffset) * dy);\n for (let x = 0; x < opt.size; ++x) {\n dst.setPixel(x, y, frame.getPixel(scaleX![x], y2));\n }\n }\n } else {\n for (const p of dst) {\n const x = p.x * dx;\n const y = p.y * dy;\n p.set(frame.getPixelInterpolate(x, y, interpolation));\n }\n }\n }\n\n return firstFrame!;\n }\n\n /**\n * Returns a copy of the **image**, rotated by **angle** degrees.\n */\n public static copyRotate(opt: CopyRotateOptions): MemoryImage {\n const src = opt.image;\n let interpolation = opt.interpolation ?? Interpolation.nearest;\n\n const nAngle = opt.angle % 360;\n\n // You can't interpolate index pixels\n if (src.hasPalette) {\n interpolation = Interpolation.nearest;\n }\n\n // Optimized version for orthogonal angles.\n if (nAngle % 90 === 0) {\n const iAngle = Math.trunc(nAngle / 90);\n switch (iAngle) {\n case 1:\n // 90 deg.\n return Transform.rotate90(src);\n case 2:\n // 180 deg.\n return Transform.rotate180(src);\n case 3:\n // 270 deg.\n return Transform.rotate270(src);\n default:\n // 0 deg.\n return MemoryImage.from(src);\n }\n }\n\n // Generic angle.\n const rad = (nAngle * Math.PI) / 180;\n const ca = Math.cos(rad);\n const sa = Math.sin(rad);\n const ux = Math.abs(src.width * ca);\n const uy = Math.abs(src.width * sa);\n const vx = Math.abs(src.height * sa);\n const vy = Math.abs(src.height * ca);\n const w2 = 0.5 * src.width;\n const h2 = 0.5 * src.height;\n const dw2 = 0.5 * (ux + vx);\n const dh2 = 0.5 * (uy + vy);\n\n let firstFrame: MemoryImage | undefined = undefined;\n const numFrames = src.numFrames;\n for (let i = 0; i < numFrames; ++i) {\n const frame = src.frames[i];\n const dst: MemoryImage =\n firstFrame?.addFrame() ??\n MemoryImage.fromResized(\n src,\n Math.trunc(ux + vx),\n Math.trunc(uy + vy),\n true\n );\n firstFrame ??= dst;\n const bg = frame.backgroundColor ?? src.backgroundColor;\n if (bg !== undefined) {\n dst.clear(bg);\n }\n\n for (const p of dst) {\n const x = p.x;\n const y = p.y;\n const x2 = w2 + (x - dw2) * ca + (y - dh2) * sa;\n const y2 = h2 - (x - dw2) * sa + (y - dh2) * ca;\n if (frame.isBoundsSafe(x2, y2)) {\n const c = frame.getPixelInterpolate(x2, y2, interpolation);\n dst.setPixel(x, y, c);\n }\n }\n }\n\n return firstFrame!;\n }\n\n /**\n * Flips the **image** using the given **direction**, which can be one of:\n * _FlipDirection.horizontal_, _FlipDirection.vertical_ or _FlipDirection.both_.\n */\n public static flip(opt: FlipOptions): MemoryImage {\n switch (opt.direction) {\n case FlipDirection.horizontal:\n Transform.flipHorizontal(opt);\n break;\n case FlipDirection.vertical:\n Transform.flipVertical(opt);\n break;\n case FlipDirection.both:\n Transform.flipHorizontalVertical(opt);\n break;\n }\n\n return opt.image;\n }\n\n /**\n * Flips the **image** vertically.\n */\n public static flipVertical(opt: TransformOptions): MemoryImage {\n const numFrames = opt.image.numFrames;\n for (let i = 0; i < numFrames; ++i) {\n const frame = opt.image.frames[i];\n const w = frame.width;\n const h = frame.height;\n const h2 = Math.trunc(h / 2);\n if (opt.image.hasPalette) {\n for (let y = 0, y2 = h - 1; y < h2; ++y, --y2) {\n for (let x = 0; x < w; ++x) {\n const p1 = frame.getPixel(x, y);\n const p2 = frame.getPixel(x, y2);\n const t = p1.index;\n p1.index = p2.index;\n p2.index = t;\n }\n }\n } else {\n for (let y = 0, y2 = h - 1; y < h2; ++y, --y2) {\n for (let x = 0; x < w; ++x) {\n const p1 = frame.getPixel(x, y);\n const p2 = frame.getPixel(x, y2);\n let t = p1.r;\n p1.r = p2.r;\n p2.r = t;\n\n t = p1.g;\n p1.g = p2.g;\n p2.g = t;\n\n t = p1.b;\n p1.b = p2.b;\n p2.b = t;\n\n t = p1.a;\n p1.a = p2.a;\n p2.a = t;\n }\n }\n }\n }\n return opt.image;\n }\n\n /**\n * Flips the **image** horizontally.\n */\n public static flipHorizontal(opt: TransformOptions): MemoryImage {\n const numFrames = opt.image.numFrames;\n for (let i = 0; i < numFrames; ++i) {\n const frame = opt.image.frames[i];\n const w = frame.width;\n const h = frame.height;\n const w2 = Math.trunc(w / 2);\n if (opt.image.hasPalette) {\n for (let y = 0; y < h; ++y) {\n for (let x = 0, x2 = w - 1; x < w2; ++x, --x2) {\n const p1 = frame.getPixel(x, y);\n const p2 = frame.getPixel(x2, y);\n const t = p1.index;\n p1.index = p2.index;\n p2.index = t;\n }\n }\n } else {\n for (let y = 0; y < h; ++y) {\n for (let x = 0, x2 = w - 1; x < w2; ++x, --x2) {\n const p1 = frame.getPixel(x, y);\n const p2 = frame.getPixel(x2, y);\n let t = p1.r;\n p1.r = p2.r;\n p2.r = t;\n\n t = p1.g;\n p1.g = p2.g;\n p2.g = t;\n\n t = p1.b;\n p1.b = p2.b;\n p2.b = t;\n\n t = p1.a;\n p1.a = p2.a;\n p2.a = t;\n }\n }\n }\n }\n return opt.image;\n }\n\n /**\n * Flip the **image** horizontally and vertically.\n */\n public static flipHorizontalVertical(opt: TransformOptions): MemoryImage {\n const numFrames = opt.image.numFrames;\n for (let i = 0; i < numFrames; ++i) {\n const frame = opt.image.frames[i];\n const w = frame.width;\n const h = frame.height;\n const h2 = Math.trunc(h / 2);\n if (frame.hasPalette) {\n for (let y = 0, y2 = h - 1; y < h2; ++y, --y2) {\n for (let x = 0, x2 = w - 1; x < w; ++x, --x2) {\n const p1 = frame.getPixel(x, y);\n const p2 = frame.getPixel(x2, y2);\n const t = p1.index;\n p1.index = p2.index;\n p2.index = t;\n }\n }\n } else {\n for (let y = 0, y2 = h - 1; y < h2; ++y, --y2) {\n for (let x = 0, x2 = w - 1; x < w; ++x, --x2) {\n const p1 = frame.getPixel(x, y);\n const p2 = frame.getPixel(x2, y2);\n let t = p1.r;\n p1.r = p2.r;\n p2.r = t;\n\n t = p1.g;\n p1.g = p2.g;\n p2.g = t;\n\n t = p1.b;\n p1.b = p2.b;\n p2.b = t;\n\n t = p1.a;\n p1.a = p2.a;\n p2.a = t;\n }\n }\n }\n }\n return opt.image;\n }\n\n /**\n * Automatically crops the image by finding the corners of the image that\n * meet the **mode** criteria (not transparent or a different color).\n *\n * **mode** can be either _TrimMode.transparent_, _TrimMode.topLeftColor_ or\n * _TrimMode.bottomRightColor_.\n *\n * **sides** can be used to control which sides of the image get trimmed,\n * and can be any combination of _TrimSide.top_, _TrimSide.bottom_, _TrimSide.left_,\n * and _TrimSide.right_.\n */\n public static trim(opt: TrimOptions): MemoryImage {\n const mode = opt.mode ?? TrimMode.topLeftColor;\n const sides = opt.sides ?? TrimSide.all;\n\n if (mode === TrimMode.transparent && opt.image.numChannels === 3) {\n return MemoryImage.from(opt.image);\n }\n\n const crop = Transform.findTrim({\n image: opt.image,\n mode: mode,\n sides: sides,\n });\n\n let firstFrame: MemoryImage | undefined = undefined;\n for (const frame of opt.image.frames) {\n const dst: MemoryImage =\n firstFrame?.addFrame() ??\n MemoryImage.fromResized(frame, crop.width, crop.height, true);\n firstFrame ??= dst;\n\n Draw.compositeImage({\n dst: dst,\n src: opt.image,\n srcX: crop.left,\n srcY: crop.top,\n srcW: crop.width,\n srcH: crop.height,\n blend: BlendMode.direct,\n });\n }\n\n return firstFrame!;\n }\n}\n", "/** @format */\n\nimport { CompressionLevel, TypedArray } from './common/typings';\nimport { BmpDecoder } from './formats/bmp-decoder';\nimport { BmpEncoder } from './formats/bmp-encoder';\nimport { Encoder } from './formats/encoder';\nimport { Decoder } from './formats/decoder';\nimport { GifDecoder } from './formats/gif-decoder';\nimport { GifEncoder } from './formats/gif-encoder';\nimport { IcoDecoder } from './formats/ico-decoder';\nimport { IcoEncoder } from './formats/ico-encoder';\nimport { JpegDecoder } from './formats/jpeg-decoder';\nimport { JpegEncoder } from './formats/jpeg-encoder';\nimport { PngDecoder } from './formats/png-decoder';\nimport { PngEncoder } from './formats/png-encoder';\nimport { TgaDecoder } from './formats/tga-decoder';\nimport { TgaEncoder } from './formats/tga-encoder';\nimport { TiffDecoder } from './formats/tiff-decoder';\nimport { TiffEncoder } from './formats/tiff-encoder';\nimport { MemoryImage } from './image/image';\nimport { PngFilterType } from './formats/png/png-filter-type';\nimport { DitherKernel } from './filter/dither-kernel';\nimport { ExifData } from './exif/exif-data';\nimport { JpegUtils } from './formats/jpeg/jpeg-utils';\n\n// Export types from 'color' directory\nexport { ChannelOrder, ChannelOrderLength } from './color/channel-order';\nexport { Channel } from './color/channel';\nexport { ColorFloat16 } from './color/color-float16';\nexport { ColorFloat32 } from './color/color-float32';\nexport { ColorFloat64 } from './color/color-float64';\nexport { ColorInt8 } from './color/color-int8';\nexport { ColorInt16 } from './color/color-int16';\nexport { ColorInt32 } from './color/color-int32';\nexport { ColorRgb8 } from './color/color-rgb8';\nexport { ColorRgba8 } from './color/color-rgba8';\nexport { ColorUint1 } from './color/color-uint1';\nexport { ColorUint2 } from './color/color-uint2';\nexport { ColorUint4 } from './color/color-uint4';\nexport { ColorUint8 } from './color/color-uint8';\nexport { ColorUint16 } from './color/color-uint16';\nexport { ColorUint32 } from './color/color-uint32';\nexport { Color, ColorConvertOptions } from './color/color';\nexport {\n Format,\n FormatType,\n FormatMaxValue,\n FormatSize,\n FormatToFormatType,\n convertFormatValue,\n} from './color/format';\n\n// Export types from 'common' directory\nexport { ArrayUtils } from './common/array-utils';\nexport { BitUtils } from './common/bit-utils';\nexport { Crc32, Crc32Options } from './common/crc32';\nexport { Float16 } from './common/float16';\nexport { InputBuffer, InputBufferInitOptions } from './common/input-buffer';\nexport { Interpolation } from './common/interpolation';\nexport { Line } from './common/line';\nexport { MathUtils } from './common/math-utils';\nexport { OutputBuffer, OutputBufferInitOptions } from './common/output-buffer';\nexport { Point } from './common/point';\nexport { RandomUtils } from './common/random-utils';\nexport { Rational } from './common/rational';\nexport { Rectangle } from './common/rectangle';\nexport { StringUtils } from './common/string-utils';\nexport { BufferEncoding, CompressionLevel, TypedArray } from './common/typings';\n\n// Export types from 'draw' directory\nexport { BlendMode } from './draw/blend-mode';\nexport { CircleQuadrant } from './draw/circle-quadrant';\nexport {\n Draw,\n CompositeImageOptions,\n DrawCircleOptions,\n DrawLineOptions,\n DrawPixelOptions,\n DrawPolygonOptions,\n DrawRectOptions,\n FillCircleOptions,\n FillFloodOptions,\n FillOptions,\n FillPolygonOptions,\n FillRectOptions,\n MaskFloodOptions,\n} from './draw/draw';\n\n// Export types from 'error' directory\nexport { LibError } from './error/lib-error';\n\n// Export types from 'exif' directory\nexport { IfdAsciiValue } from './exif/ifd-value/ifd-ascii-value';\nexport { IfdByteValue } from './exif/ifd-value/ifd-byte-value';\nexport { IfdDoubleValue } from './exif/ifd-value/ifd-double-value';\nexport { IfdLongValue } from './exif/ifd-value/ifd-long-value';\nexport { IfdRationalValue } from './exif/ifd-value/ifd-rational-value';\nexport { IfdSByteValue } from './exif/ifd-value/ifd-sbyte-value';\nexport { IfdShortValue } from './exif/ifd-value/ifd-short-value';\nexport { IfdSingleValue } from './exif/ifd-value/ifd-single-value';\nexport { IfdSLongValue } from './exif/ifd-value/ifd-slong-value';\nexport { IfdSRationalValue } from './exif/ifd-value/ifd-srational-value';\nexport { IfdSShortValue } from './exif/ifd-value/ifd-sshort-value';\nexport { IfdUndefinedValue } from './exif/ifd-value/ifd-undefined-value';\nexport { IfdValue } from './exif/ifd-value/ifd-value';\nexport { ExifData } from './exif/exif-data';\nexport { ExifEntry } from './exif/exif-entry';\nexport {\n ExifTag,\n ExifTagInitOptions,\n ExifGpsTags,\n ExifImageTags,\n ExifInteropTags,\n ExifTagNameToID,\n} from './exif/exif-tag';\nexport { IfdContainer } from './exif/ifd-container';\nexport { IfdDirectory } from './exif/ifd-directory';\nexport {\n IfdValueType,\n IfdValueTypeSize,\n getIfdValueTypeSize,\n getIfdValueTypeString,\n} from './exif/ifd-value-type';\n\n// Export types from 'filter' directory\nexport { DitherKernel, DitherKernels } from './filter/dither-kernel';\nexport {\n Filter,\n AdjustColorOptions,\n BillboardOptions,\n BleachBypassOptions,\n BulgeDistortionOptions,\n BumpToNormalOptions,\n ChromaticAberrationOptions,\n ColorHalftone,\n ColorOffsetOptions,\n ContrastOptions,\n ConvolutionOptions,\n CopyImageChannelsOptions,\n DitherImageOptions,\n DotScreenOptions,\n DropShadowOptions,\n EdgeGlowOptions,\n EmbossOptions,\n GammaOptions,\n GaussianBlurOptions,\n GrayscaleOptions,\n HdrToLdrOptions,\n HexagonPixelateOptions,\n InvertOptions,\n LuminanceThresholdOptions,\n MonochromeOptions,\n NoiseOptions,\n NormalizeOptions,\n PixelateOptions,\n QuantizeOptions,\n ReinhardToneMapOptions,\n RemapColorsOptions,\n ScaleRgbaOptions,\n SeparableConvolutionOptions,\n SepiaOptions,\n SketchOptions,\n SmoothOptions,\n SobelOptions,\n StretchDistortionOptions,\n VignetteOptions,\n} from './filter/filter';\nexport { NoiseType } from './filter/noise-type';\nexport { PixelateMode } from './filter/pixelate-mode';\nexport { QuantizeMethod } from './filter/quantize-method';\nexport {\n SeparableKernel,\n SeparableKernelApplyOptions,\n} from './filter/separable-kernel';\n\n// Export types from 'formats' directory\nexport { BmpCompressionMode } from './formats/bmp/bmp-compression-mode';\nexport { BmpFileHeader } from './formats/bmp/bmp-file-header';\nexport { BmpInfo } from './formats/bmp/bmp-info';\n\nexport { GifColorMap } from './formats/gif/gif-color-map';\nexport { GifImageDesc } from './formats/gif/gif-image-desc';\nexport { GifInfo, GifInfoInitOptions } from './formats/gif/gif-info';\n\nexport { IcoBmpInfo } from './formats/ico/ico-bmp-info';\nexport {\n IcoInfoImage,\n IcoInfoImageInitOptions,\n} from './formats/ico/ico-info-image';\nexport { IcoInfo } from './formats/ico/ico-info';\nexport { IcoType, IcoTypeLength } from './formats/ico/ico-type';\n\nexport { HuffmanNode } from './formats/jpeg/huffman-node';\nexport { HuffmanParent } from './formats/jpeg/huffman-parent';\nexport { HuffmanValue } from './formats/jpeg/huffman-value';\nexport { JpegAdobe } from './formats/jpeg/jpeg-adobe';\nexport { JpegComponentData } from './formats/jpeg/jpeg-component-data';\nexport { JpegComponent } from './formats/jpeg/jpeg-component';\nexport { JpegData } from './formats/jpeg/jpeg-data';\nexport { JpegFrame } from './formats/jpeg/jpeg-frame';\nexport { JpegHuffman } from './formats/jpeg/jpeg-huffman';\nexport { JpegInfo } from './formats/jpeg/jpeg-info';\nexport { JpegJfif } from './formats/jpeg/jpeg-jfif';\nexport { JpegMarker } from './formats/jpeg/jpeg-marker';\nexport { JpegQuantize } from './formats/jpeg/jpeg-quantize';\nexport { JpegScan } from './formats/jpeg/jpeg-scan';\nexport { JpegUtils } from './formats/jpeg/jpeg-utils';\n\nexport { PngBlendMode } from './formats/png/png-blend-mode';\nexport { PngColorType } from './formats/png/png-color-type';\nexport { PngDisposeMode } from './formats/png/png-dispose-mode';\nexport { PngFilterType } from './formats/png/png-filter-type';\nexport { PngFrame, PngFrameInitOptions } from './formats/png/png-frame';\nexport { PngInfo, PngInfoInitOptions } from './formats/png/png-info';\n\nexport { TgaImageType, TgaImageTypeLength } from './formats/tga/tga-image-type';\nexport { TgaInfo, TgaInfoInitOptions } from './formats/tga/tga-info';\n\nexport { TiffBitReader } from './formats/tiff/tiff-bit-reader';\nexport { TiffCompression } from './formats/tiff/tiff-compression';\nexport { TiffEntry, TiffEntryInitOptions } from './formats/tiff/tiff-entry';\nexport {\n TiffFaxDecoder,\n TiffFaxDecoderInitOptions,\n} from './formats/tiff/tiff-fax-decoder';\nexport { TiffFormat } from './formats/tiff/tiff-format';\nexport { TiffImageType } from './formats/tiff/tiff-image-type';\nexport { TiffImage } from './formats/tiff/tiff-image';\nexport { TiffInfo, TiffInfoInitOptions } from './formats/tiff/tiff-info';\nexport { LzwDecoder } from './formats/tiff/tiff-lzw-decoder';\nexport {\n TiffPhotometricType,\n TiffPhotometricTypeLength,\n} from './formats/tiff/tiff-photometric-type';\n\nexport { BmpDecoder } from './formats/bmp-decoder';\nexport { BmpEncoder } from './formats/bmp-encoder';\nexport { DecodeInfo } from './formats/decode-info';\nexport { Decoder } from './formats/decoder';\nexport { DibDecoder } from './formats/dib-decoder';\nexport { Encoder } from './formats/encoder';\nexport { GifDecoder } from './formats/gif-decoder';\nexport { GifEncoder, GifEncoderInitOptions } from './formats/gif-encoder';\nexport { IcoDecoder } from './formats/ico-decoder';\nexport { IcoEncoder } from './formats/ico-encoder';\nexport { JpegDecoder } from './formats/jpeg-decoder';\nexport { JpegEncoder } from './formats/jpeg-encoder';\nexport { PngDecoder } from './formats/png-decoder';\nexport { PngEncoder, PngEncoderInitOptions } from './formats/png-encoder';\nexport { TgaDecoder } from './formats/tga-decoder';\nexport { TgaEncoder } from './formats/tga-encoder';\nexport { TiffDecoder } from './formats/tiff-decoder';\nexport { TiffEncoder } from './formats/tiff-encoder';\nexport { WinEncoder } from './formats/win-encoder';\n\n// Export types from 'image' directory\nexport { FrameType } from './image/frame-type';\nexport { HeapNode } from './image/heap-node';\nexport { IccProfile } from './image/icc-profile';\nexport { IccProfileCompression } from './image/icc-profile-compression';\nexport { MemoryImageDataFloat16 } from './image/image-data-float16';\nexport { MemoryImageDataFloat32 } from './image/image-data-float32';\nexport { MemoryImageDataFloat64 } from './image/image-data-float64';\nexport { MemoryImageDataInt8 } from './image/image-data-int8';\nexport { MemoryImageDataInt16 } from './image/image-data-int16';\nexport { MemoryImageDataInt32 } from './image/image-data-int32';\nexport { MemoryImageDataUint1 } from './image/image-data-uint1';\nexport { MemoryImageDataUint2 } from './image/image-data-uint2';\nexport { MemoryImageDataUint4 } from './image/image-data-uint4';\nexport { MemoryImageDataUint8 } from './image/image-data-uint8';\nexport { MemoryImageDataUint16 } from './image/image-data-uint16';\nexport { MemoryImageDataUint32 } from './image/image-data-uint32';\nexport { MemoryImageData } from './image/image-data';\nexport { ImageUtils } from './image/image-utils';\nexport {\n MemoryImage,\n MemoryImageCloneOptions,\n MemoryImageColorExtremes,\n MemoryImageConvertOptions,\n MemoryImageCreateOptions,\n MemoryImageFromBytesOptions,\n} from './image/image';\nexport { NeuralQuantizer } from './image/neural-quantizer';\nexport { OctreeNode } from './image/octree-node';\nexport { OctreeQuantizer } from './image/octree-quantizer';\nexport { PaletteFloat16 } from './image/palette-float16';\nexport { PaletteFloat32 } from './image/palette-float32';\nexport { PaletteFloat64 } from './image/palette-float64';\nexport { PaletteInt8 } from './image/palette-int8';\nexport { PaletteInt16 } from './image/palette-int16';\nexport { PaletteInt32 } from './image/palette-int32';\nexport { PaletteUint8 } from './image/palette-uint8';\nexport { PaletteUint16 } from './image/palette-uint16';\nexport { PaletteUint32 } from './image/palette-uint32';\nexport { Palette } from './image/palette';\nexport { PixelFloat16 } from './image/pixel-float16';\nexport { PixelFloat32 } from './image/pixel-float32';\nexport { PixelFloat64 } from './image/pixel-float64';\nexport { PixelInt8 } from './image/pixel-int8';\nexport { PixelInt16 } from './image/pixel-int16';\nexport { PixelInt32 } from './image/pixel-int32';\nexport { PixelUint1 } from './image/pixel-uint1';\nexport { PixelUint2 } from './image/pixel-uint2';\nexport { PixelUint4 } from './image/pixel-uint4';\nexport { PixelUint8 } from './image/pixel-uint8';\nexport { PixelUint16 } from './image/pixel-uint16';\nexport { PixelUint32 } from './image/pixel-uint32';\nexport { PixelUndefined } from './image/pixel-undefined';\nexport { PixelRangeIterator } from './image/pixel-range-iterator';\nexport { Pixel, UndefinedPixel } from './image/pixel';\nexport { QuantizerType } from './image/quantizer-type';\nexport { Quantizer } from './image/quantizer';\n\n// Export types from 'transform' directory\nexport { FlipDirection } from './transform/flip-direction';\nexport {\n Transform,\n CopyCropCircleOptions,\n CopyCropOptions,\n CopyRectifyOptions,\n CopyResizeCropSquareOptions,\n CopyResizeOptionsUsingHeight,\n CopyResizeOptionsUsingWidth,\n CopyRotateOptions,\n FlipOptions,\n TransformOptions,\n TrimOptions,\n} from './transform/transform';\nexport { TrimMode } from './transform/trim-mode';\nexport { TrimSide } from './transform/trim-side';\n\n// In-place exports\nexport interface DecodeOptions {\n data: TypedArray;\n}\n\nexport interface DecodeImageOptions extends DecodeOptions {\n frame?: number;\n}\n\nexport interface DecodeNamedImageOptions extends DecodeImageOptions {\n name: string;\n}\n\nexport interface EncodeOptions {\n image: MemoryImage;\n}\n\nexport interface EncodeNamedImageOptions extends EncodeOptions {\n name: string;\n}\n\nexport interface EncodeJpgOptions extends EncodeOptions {\n quality?: number;\n}\n\nexport interface InjectJpgExifOptions extends DecodeOptions {\n exifData: ExifData;\n}\n\nexport interface EncodeAnimatedOptions extends EncodeOptions {\n singleFrame?: boolean;\n}\n\nexport interface EncodePngOptions extends EncodeAnimatedOptions {\n level?: CompressionLevel;\n filter?: PngFilterType;\n}\n\nexport interface EncodeGifOptions extends EncodeAnimatedOptions {\n repeat?: number;\n samplingFactor?: number;\n dither?: DitherKernel;\n ditherSerpentine?: boolean;\n}\n\nexport interface EncodeIcoImagesOptions {\n images: MemoryImage[];\n}\n\n/**\n * Return the Decoder that can decode image with the given **name**,\n * by looking at the file extension.\n */\nexport function findDecoderForNamedImage(name: string): Decoder | undefined {\n const n = name.toLowerCase();\n if (n.endsWith('.jpg') || n.endsWith('.jpeg')) {\n return new JpegDecoder();\n }\n if (n.endsWith('.png')) {\n return new PngDecoder();\n }\n if (n.endsWith('.tga')) {\n return new TgaDecoder();\n }\n if (n.endsWith('.gif')) {\n return new GifDecoder();\n }\n if (n.endsWith('.tif') || n.endsWith('.tiff')) {\n return new TiffDecoder();\n }\n if (n.endsWith('.bmp')) {\n return new BmpDecoder();\n }\n if (n.endsWith('.ico')) {\n return new IcoDecoder();\n }\n return undefined;\n}\n\n/**\n * Return the Encoder that can decode image with the given **name**,\n * by looking at the file extension.\n */\nexport function findEncoderForNamedImage(name: string): Encoder | undefined {\n const n = name.toLowerCase();\n if (n.endsWith('.jpg') || n.endsWith('.jpeg')) {\n return new JpegEncoder();\n }\n if (n.endsWith('.png')) {\n return new PngEncoder();\n }\n if (n.endsWith('.tga')) {\n return new TgaEncoder();\n }\n if (n.endsWith('.gif')) {\n return new GifEncoder();\n }\n if (n.endsWith('.tif') || n.endsWith('.tiff')) {\n return new TiffEncoder();\n }\n if (n.endsWith('.bmp')) {\n return new BmpEncoder();\n }\n if (n.endsWith('.ico')) {\n return new IcoEncoder();\n }\n if (n.endsWith('.cur')) {\n return new IcoEncoder();\n }\n return undefined;\n}\n\n/**\n * Find a Decoder that is able to decode the given image **data**.\n * Use this is you don't know the type of image it is.\n *\n * **WARNING:** Since this will check the image data against all known decoders,\n * it is much slower than using an explicit decoder.\n */\nexport function findDecoderForData(data: TypedArray): Decoder | undefined {\n // The letious decoders will be creating a Uint8List for their InputStream\n // if the data isn't already that type, so do it once here to avoid having to\n // do it multiple times.\n const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);\n\n const jpg = new JpegDecoder();\n if (jpg.isValidFile(bytes)) {\n return jpg;\n }\n\n const png = new PngDecoder();\n if (png.isValidFile(bytes)) {\n return png;\n }\n\n const gif = new GifDecoder();\n if (gif.isValidFile(bytes)) {\n return gif;\n }\n\n const tiff = new TiffDecoder();\n if (tiff.isValidFile(bytes)) {\n return tiff;\n }\n\n const bmp = new BmpDecoder();\n if (bmp.isValidFile(bytes)) {\n return bmp;\n }\n\n const tga = new TgaDecoder();\n if (tga.isValidFile(bytes)) {\n return tga;\n }\n\n const ico = new IcoDecoder();\n if (ico.isValidFile(bytes)) {\n return ico;\n }\n\n return undefined;\n}\n\n/**\n * Decode the given image file bytes by first identifying the format of the\n * file and using that decoder to decode the file into a single frame MemoryImage.\n *\n * **WARNING:** Since this will check the image data against all known decoders,\n * it is much slower than using an explicit decoder.\n */\nexport function decodeImage(opt: DecodeImageOptions): MemoryImage | undefined {\n const decoder = findDecoderForData(opt.data);\n if (decoder === undefined) {\n return undefined;\n }\n const dataUint8 = new Uint8Array(opt.data);\n return decoder.decode(dataUint8, opt.frame);\n}\n\n/**\n * Decodes the given image file bytes, using the filename extension to\n * determine the decoder.\n */\nexport function decodeNamedImage(\n opt: DecodeNamedImageOptions\n): MemoryImage | undefined {\n const decoder = findDecoderForNamedImage(opt.name);\n if (decoder !== undefined) {\n const dataUint8 = new Uint8Array(opt.data);\n return decoder.decode(dataUint8, opt.frame);\n }\n return decodeImage(opt);\n}\n\n/**\n * Encode the MemoryImage to the format determined by the file extension of **name**.\n * If a format wasn't able to be identified, undefined will be returned.\n * Otherwise the encoded format bytes of the image will be returned.\n */\nexport function encodeNamedImage(\n opt: EncodeNamedImageOptions\n): Uint8Array | undefined {\n const encoder = findEncoderForNamedImage(opt.name);\n if (encoder === undefined) {\n return undefined;\n }\n return encoder.encode(opt.image);\n}\n\n/**\n * Decode a JPG formatted image.\n */\nexport function decodeJpg(opt: DecodeOptions): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(opt.data);\n return new JpegDecoder().decode(dataUint8);\n}\n\n/**\n * Encode an image to the JPEG format.\n */\nexport function encodeJpg(opt: EncodeJpgOptions): Uint8Array {\n const quality = opt.quality ?? 100;\n return new JpegEncoder(quality).encode(opt.image);\n}\n\n/**\n * Decode only the ExifData from a JPEG file, returning undefined if it was\n * unable to.\n */\nexport function decodeJpgExif(opt: DecodeOptions): ExifData | undefined {\n const dataUint8 = new Uint8Array(opt.data);\n return new JpegUtils().decodeExif(dataUint8);\n}\n\n/**\n * Inject ExifData into a JPEG file, replacing any existing EXIF data.\n * The new JPEG file bytes will be returned, otherwise undefined if there was an\n * issue.\n */\nexport function injectJpgExif(\n opt: InjectJpgExifOptions\n): Uint8Array | undefined {\n const dataUint8 = new Uint8Array(opt.data);\n return new JpegUtils().injectExif(opt.exifData, dataUint8);\n}\n\n/**\n * Decode a PNG formatted image.\n */\nexport function decodePng(opt: DecodeImageOptions): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(opt.data);\n return new PngDecoder().decode(dataUint8, opt.frame);\n}\n\n/**\n * Encode an image to the PNG format.\n */\nexport function encodePng(opt: EncodePngOptions): Uint8Array {\n const singleFrame = opt.singleFrame ?? false;\n const level = opt.level ?? 6;\n const filter = opt.filter ?? PngFilterType.paeth;\n return new PngEncoder({\n filter: filter,\n level: level,\n }).encode(opt.image, singleFrame);\n}\n\n/**\n * Decode a Targa formatted image.\n */\nexport function decodeTga(opt: DecodeImageOptions): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(opt.data);\n return new TgaDecoder().decode(dataUint8, opt.frame);\n}\n\n/**\n * Encode an image to the Targa format.\n */\nexport function encodeTga(opt: EncodeOptions): Uint8Array {\n return new TgaEncoder().encode(opt.image);\n}\n\n/**\n * Decode a GIF formatted image (first frame for animations).\n */\nexport function decodeGif(opt: DecodeImageOptions): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(opt.data);\n return new GifDecoder().decode(dataUint8, opt.frame);\n}\n\n/**\n * Encode an image to the GIF format.\n *\n * The **samplingFactor** specifies the sampling factor for\n * image quantization. It is responsible for reducing\n * the amount of unique colors in your images to 256.\n * According to https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/,\n * a sampling factor of 10 gives you a reasonable trade-off between\n * image quality and quantization speed.\n * If you know that you have less than 256 colors in your frames\n * anyway, you should supply a very large **samplingFactor** for maximum performance.\n */\nexport function encodeGif(opt: EncodeGifOptions): Uint8Array {\n const singleFrame = opt.singleFrame ?? false;\n const repeat = opt.repeat ?? 0;\n const samplingFactor = opt.samplingFactor ?? 10;\n const dither = opt.dither ?? DitherKernel.floydSteinberg;\n const ditherSerpentine = opt.ditherSerpentine ?? false;\n return new GifEncoder({\n repeat: repeat,\n samplingFactor: samplingFactor,\n dither: dither,\n ditherSerpentine: ditherSerpentine,\n }).encode(opt.image, singleFrame);\n}\n\n/**\n * Decode a TIFF formatted image.\n */\nexport function decodeTiff(opt: DecodeImageOptions): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(opt.data);\n return new TiffDecoder().decode(dataUint8, opt.frame);\n}\n\n/**\n * Encode an image to the TIFF format.\n */\nexport function encodeTiff(opt: EncodeAnimatedOptions): Uint8Array {\n const singleFrame = opt.singleFrame ?? false;\n return new TiffEncoder().encode(opt.image, singleFrame);\n}\n\n/**\n * Decode a BMP formatted image.\n */\nexport function decodeBmp(opt: DecodeOptions): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(opt.data);\n return new BmpDecoder().decode(dataUint8);\n}\n\n/**\n * Encode an image to the BMP format.\n */\nexport function encodeBmp(opt: EncodeOptions): Uint8Array {\n return new BmpEncoder().encode(opt.image);\n}\n\n/**\n * Decode an ICO image.\n */\nexport function decodeIco(opt: DecodeImageOptions): MemoryImage | undefined {\n const dataUint8 = new Uint8Array(opt.data);\n return new IcoDecoder().decode(dataUint8, opt.frame);\n}\n\n/**\n * Encode an image to the ICO format.\n */\nexport function encodeIco(opt: EncodeAnimatedOptions): Uint8Array {\n const singleFrame = opt.singleFrame ?? false;\n return new IcoEncoder().encode(opt.image, singleFrame);\n}\n\n/**\n * Encode a list of images to the ICO format.\n */\nexport function encodeIcoImages(opt: EncodeIcoImagesOptions): Uint8Array {\n return new IcoEncoder().encodeImages(opt.images);\n}\n", "\r\n\r\nvar UZIP = {};\r\nif(typeof module == \"object\") module.exports = UZIP;\r\n\r\n\r\nUZIP[\"parse\"] = function(buf, onlyNames)\t// ArrayBuffer\r\n{\r\n\tvar rUs = UZIP.bin.readUshort, rUi = UZIP.bin.readUint, o = 0, out = {};\r\n\tvar data = new Uint8Array(buf);\r\n\tvar eocd = data.length-4;\r\n\t\r\n\twhile(rUi(data, eocd)!=0x06054b50) eocd--;\r\n\t\r\n\tvar o = eocd;\r\n\to+=4;\t// sign = 0x06054b50\r\n\to+=4; // disks = 0;\r\n\tvar cnu = rUs(data, o); o+=2;\r\n\tvar cnt = rUs(data, o); o+=2;\r\n\t\t\t\r\n\tvar csize = rUi(data, o); o+=4;\r\n\tvar coffs = rUi(data, o); o+=4;\r\n\t\r\n\to = coffs;\r\n\tfor(var i=0; i8514000) {\r\n\t\t\t//console.log(PUtils.readASCII(buf , 8514500, 500));\r\n\t\t\t//console.log(PUtils.readASCII(nbuf, 8514500, 500));\r\n\t\t}\r\n\t\tfor(var i=0; i>>4);\r\n\t//console.log(CM, CINFO,CMF,FLG);\r\n\treturn UZIP.inflateRaw(new Uint8Array(file.buffer, file.byteOffset+2, file.length-6), buf); \r\n}\r\nUZIP.deflate = function(data, opts/*, buf, off*/) {\r\n\tif(opts==null) opts={level:6};\r\n\tvar off=0, buf=new Uint8Array(50+Math.floor(data.length*1.1));\r\n\tbuf[off]=120; buf[off+1]=156; off+=2;\r\n\toff = UZIP.F.deflateRaw(data, buf, off, opts.level);\r\n\tvar crc = UZIP.adler(data, 0, data.length);\r\n\tbuf[off+0]=((crc>>>24)&255); \r\n\tbuf[off+1]=((crc>>>16)&255); \r\n\tbuf[off+2]=((crc>>> 8)&255); \r\n\tbuf[off+3]=((crc>>> 0)&255); \t\r\n\treturn new Uint8Array(buf.buffer, 0, off+4);\r\n}\r\nUZIP.deflateRaw = function(data, opts) {\r\n\tif(opts==null) opts={level:6};\r\n\tvar buf=new Uint8Array(50+Math.floor(data.length*1.1));\r\n\tvar off = UZIP.F.deflateRaw(data, buf, off, opts.level);\r\n\treturn new Uint8Array(buf.buffer, 0, off);\r\n}\r\n\r\n\r\nUZIP.encode = function(obj, noCmpr) {\r\n\tif(noCmpr==null) noCmpr=false;\r\n\tvar tot = 0, wUi = UZIP.bin.writeUint, wUs = UZIP.bin.writeUshort;\r\n\tvar zpd = {};\r\n\tfor(var p in obj) { var cpr = !UZIP._noNeed(p) && !noCmpr, buf = obj[p], crc = UZIP.crc.crc(buf,0,buf.length); \r\n\t\tzpd[p] = { cpr:cpr, usize:buf.length, crc:crc, file: (cpr ? UZIP.deflateRaw(buf) : buf) }; }\r\n\t\r\n\tfor(var p in zpd) tot += zpd[p].file.length + 30 + 46 + 2*UZIP.bin.sizeUTF8(p);\r\n\ttot += 22;\r\n\t\r\n\tvar data = new Uint8Array(tot), o = 0;\r\n\tvar fof = []\r\n\t\r\n\tfor(var p in zpd) {\r\n\t\tvar file = zpd[p]; fof.push(o);\r\n\t\to = UZIP._writeHeader(data, o, p, file, 0);\r\n\t}\r\n\tvar i=0, ioff = o;\r\n\tfor(var p in zpd) {\r\n\t\tvar file = zpd[p]; fof.push(o);\r\n\t\to = UZIP._writeHeader(data, o, p, file, 1, fof[i++]);\t\t\r\n\t}\r\n\tvar csize = o-ioff;\r\n\t\r\n\twUi(data, o, 0x06054b50); o+=4;\r\n\to += 4; // disks\r\n\twUs(data, o, i); o += 2;\r\n\twUs(data, o, i); o += 2;\t// number of c d records\r\n\twUi(data, o, csize); o += 4;\r\n\twUi(data, o, ioff ); o += 4;\r\n\to += 2;\r\n\treturn data.buffer;\r\n}\r\n// no need to compress .PNG, .ZIP, .JPEG ....\r\nUZIP._noNeed = function(fn) { var ext = fn.split(\".\").pop().toLowerCase(); return \"png,jpg,jpeg,zip\".indexOf(ext)!=-1; }\r\n\r\nUZIP._writeHeader = function(data, o, p, obj, t, roff)\r\n{\r\n\tvar wUi = UZIP.bin.writeUint, wUs = UZIP.bin.writeUshort;\r\n\tvar file = obj.file;\r\n\t\r\n\twUi(data, o, t==0 ? 0x04034b50 : 0x02014b50); o+=4; // sign\r\n\tif(t==1) o+=2; // ver made by\r\n\twUs(data, o, 20); o+=2;\t// ver\r\n\twUs(data, o, 0); o+=2; // gflip\r\n\twUs(data, o, obj.cpr?8:0); o+=2;\t// cmpr\r\n\t\t\r\n\twUi(data, o, 0); o+=4;\t// time\t\t\r\n\twUi(data, o, obj.crc); o+=4;\t// crc32\r\n\twUi(data, o, file.length); o+=4;\t// csize\r\n\twUi(data, o, obj.usize); o+=4;\t// usize\r\n\t\t\r\n\twUs(data, o, UZIP.bin.sizeUTF8(p)); o+=2;\t// nlen\r\n\twUs(data, o, 0); o+=2;\t// elen\r\n\t\r\n\tif(t==1) {\r\n\t\to += 2; // comment length\r\n\t\to += 2; // disk number\r\n\t\to += 6; // attributes\r\n\t\twUi(data, o, roff); o+=4;\t// usize\r\n\t}\r\n\tvar nlen = UZIP.bin.writeUTF8(data, o, p); o+= nlen;\t\r\n\tif(t==0) { data.set(file, o); o += file.length; }\r\n\treturn o;\r\n}\r\n\r\n\r\n\r\n\r\n\r\nUZIP.crc = {\r\n\ttable : ( function() {\r\n\t var tab = new Uint32Array(256);\r\n\t for (var n=0; n<256; n++) {\r\n\t\t\tvar c = n;\r\n\t\t\tfor (var k=0; k<8; k++) {\r\n\t\t\t\tif (c & 1) c = 0xedb88320 ^ (c >>> 1);\r\n\t\t\t\telse c = c >>> 1;\r\n\t\t\t}\r\n\t\t\ttab[n] = c; } \r\n\t\treturn tab; })(),\r\n\tupdate : function(c, buf, off, len) {\r\n\t\tfor (var i=0; i>> 8);\r\n\t\treturn c;\r\n\t},\r\n\tcrc : function(b,o,l) { return UZIP.crc.update(0xffffffff,b,o,l) ^ 0xffffffff; }\r\n}\r\nUZIP.adler = function(data,o,len) {\r\n\tvar a = 1, b = 0;\r\n\tvar off = o, end=o+len;\r\n\twhile(off>8)&255; },\r\n\treadUint : function(buff,p) { return (buff[p+3]*(256*256*256)) + ((buff[p+2]<<16) | (buff[p+1]<< 8) | buff[p]); },\r\n\twriteUint : function(buff,p,n){ buff[p]=n&255; buff[p+1]=(n>>8)&255; buff[p+2]=(n>>16)&255; buff[p+3]=(n>>24)&255; },\r\n\treadASCII : function(buff,p,l){ var s = \"\"; for(var i=0; i> 6)); buff[p+i+1] = (128|((code>> 0)&63)); i+=2; }\r\n\t\t\telse if((code&(0xffffffff-(1<<16)+1))==0) { buff[p+i] = (224|(code>>12)); buff[p+i+1] = (128|((code>> 6)&63)); buff[p+i+2] = (128|((code>>0)&63)); i+=3; }\r\n\t\t\telse if((code&(0xffffffff-(1<<21)+1))==0) { buff[p+i] = (240|(code>>18)); buff[p+i+1] = (128|((code>>12)&63)); buff[p+i+2] = (128|((code>>6)&63)); buff[p+i+3] = (128|((code>>0)&63)); i+=4; }\r\n\t\t\telse throw \"e\";\r\n\t\t}\r\n\t\treturn i;\r\n\t},\r\n\tsizeUTF8 : function(str) {\r\n\t\tvar strl = str.length, i=0;\r\n\t\tfor(var ci=0; ci>>3;\r\n\t}\r\n\r\n\tvar lits = U.lits, strt=U.strt, prev=U.prev, li=0, lc=0, bs=0, ebits=0, c=0, nc=0; // last_item, literal_count, block_start\r\n\tif(dlen>2) { nc=UZIP.F._hash(data,0); strt[nc]=0; }\r\n\tvar nmch=0,nmci=0;\r\n\t\r\n\tfor(i=0; i14000 || lc>26697) && (dlen-i)>100) {\r\n\t\t\t\tif(cvrd>>16)>>16)>(mch>>>16)) mch=0;\r\n\t\t\t}//*/\r\n\t\t\tvar len = mch>>>16, dst = mch&0xffff; //if(i-dst<0) throw \"e\";\r\n\t\t\tif(mch!=0) { \r\n\t\t\t\tvar len = mch>>>16, dst = mch&0xffff; //if(i-dst<0) throw \"e\";\r\n\t\t\t\tvar lgi = goodIndex(len, U.of0); U.lhst[257+lgi]++; \r\n\t\t\t\tvar dgi = goodIndex(dst, U.df0); U.dhst[ dgi]++; ebits += U.exb[lgi] + U.dxb[dgi]; \r\n\t\t\t\tlits[li] = (len<<23)|(i-cvrd); lits[li+1] = (dst<<16)|(lgi<<8)|dgi; li+=2;\r\n\t\t\t\tcvrd = i + len; \r\n\t\t\t}\r\n\t\t\telse {\tU.lhst[data[i]]++; }\r\n\t\t\tlc++;\r\n\t\t}\r\n\t}\r\n\tif(bs!=i || data.length==0) {\r\n\t\tif(cvrd>>3;\r\n}\r\nUZIP.F._bestMatch = function(data, i, prev, c, nice, chain) {\r\n\tvar ci = (i&0x7fff), pi=prev[ci]; \r\n\t//console.log(\"----\", i);\r\n\tvar dif = ((ci-pi + (1<<15)) & 0x7fff); if(pi==ci || c!=UZIP.F._hash(data,i-dif)) return 0;\r\n\tvar tl=0, td=0; // top length, top distance\r\n\tvar dlim = Math.min(0x7fff, i);\r\n\twhile(dif<=dlim && --chain!=0 && pi!=ci /*&& c==UZIP.F._hash(data,i-dif)*/) {\r\n\t\tif(tl==0 || (data[i+tl]==data[i+tl-dif])) {\r\n\t\t\tvar cl = UZIP.F._howLong(data, i, dif);\r\n\t\t\tif(cl>tl) { \r\n\t\t\t\ttl=cl; td=dif; if(tl>=nice) break; //* \r\n\t\t\t\tif(dif+2maxd) { maxd=curd; pi = ei; }\r\n\t\t\t\t} //*/\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tci=pi; pi = prev[ci];\r\n\t\tdif += ((ci-pi + (1<<15)) & 0x7fff);\r\n\t}\r\n\treturn (tl<<16)|td;\r\n}\r\nUZIP.F._howLong = function(data, i, dif) {\r\n\tif(data[i]!=data[i-dif] || data[i+1]!=data[i+1-dif] || data[i+2]!=data[i+2-dif]) return 0;\r\n\tvar oi=i, l = Math.min(data.length, i+258); i+=3;\r\n\t//while(i+4>>23), end = off+(qb&((1<<23)-1));\r\n\t\t\twhile(off>16), lgi=(qc>>8)&255, dgi=(qc&255);\r\n\t\t\t\tpos = UZIP.F._writeLit(257+lgi, ltree, out, pos);\r\n\t\t\t\tputsE(out, pos, len-U.of0[lgi]); pos+=U.exb[lgi];\r\n\t\t\t\t\r\n\t\t\t\tpos = UZIP.F._writeLit(dgi, dtree, out, pos);\r\n\t\t\t\tputsF(out, pos, dst-U.df0[dgi]); pos+=U.dxb[dgi]; off+=len;\r\n\t\t\t}\r\n\t\t}\r\n\t\tpos = UZIP.F._writeLit(256, ltree, out, pos);\r\n\t}\r\n\t//console.log(pos-opos, fxdSize, dynSize, cstSize);\r\n\treturn pos;\r\n}\r\nUZIP.F._copyExact = function(data,off,len,out,pos) {\r\n\tvar p8 = (pos>>>3);\r\n\tout[p8]=(len); out[p8+1]=(len>>>8); out[p8+2]=255-out[p8]; out[p8+3]=255-out[p8+1]; p8+=4;\r\n\tout.set(new Uint8Array(data.buffer, off, len), p8);\r\n\t//for(var i=0; i4 && U.itree[(U.ordr[numh-1]<<1)+1]==0) numh--;\r\n\treturn [ML, MD, MH, numl, numd, numh, lset, dset];\r\n}\r\nUZIP.F.getSecond= function(a) { var b=[]; for(var i=0; i>1)+\",\"; return b; }\r\nUZIP.F.contSize = function(tree, hst) { var s=0; for(var i=0; i15) { UZIP.F._putsE(out, pos, rst, rsl); pos+=rsl; }\r\n\t}\r\n\treturn pos;\r\n}\r\nUZIP.F._lenCodes = function(tree, set) {\r\n\tvar len=tree.length; while(len!=2 && tree[len-1]==0) len-=2; // when no distances, keep one code with length 0\r\n\tfor(var i=0; i>>1, 138);\r\n\t\t\tif(zc<11) set.push(17, zc-3);\r\n\t\t\telse set.push(18, zc-11);\r\n\t\t\ti += zc*2-2;\r\n\t\t}\r\n\t\telse if(l==prv && nxt==l && nnxt==l) {\r\n\t\t\tvar lz = i+5;\r\n\t\t\twhile(lz+2>>1, 6);\r\n\t\t\tset.push(16, zc-3);\r\n\t\t\ti += zc*2-2;\r\n\t\t}\r\n\t\telse set.push(l, 0);\r\n\t}\r\n\treturn len>>>1;\r\n}\r\nUZIP.F._hufTree = function(hst, tree, MAXL) {\r\n\tvar list=[], hl = hst.length, tl=tree.length, i=0;\r\n\tfor(i=0; iMAXL) { UZIP.F.restrictDepth(l2, MAXL, maxl); maxl = MAXL; }\r\n\tfor(i=0; iMD) { var od=dps[i].d; dps[i].d=MD; dbt+=bCost-(1<<(maxl-od)); } else break;\r\n\tdbt = dbt>>>(maxl-MD);\r\n\twhile(dbt>0) { var od=dps[i].d; if(od=0; i--) if(dps[i].d==MD && dbt<0) { dps[i].d--; dbt++; } if(dbt!=0) console.log(\"debt left\");\r\n}\r\n\r\nUZIP.F._goodIndex = function(v, arr) {\r\n\tvar i=0; if(arr[i|16]<=v) i|=16; if(arr[i|8]<=v) i|=8; if(arr[i|4]<=v) i|=4; if(arr[i|2]<=v) i|=2; if(arr[i|1]<=v) i|=1; return i;\r\n}\r\nUZIP.F._writeLit = function(ch, ltree, out, pos) {\r\n\tUZIP.F._putsF(out, pos, ltree[ch<<1]);\r\n\treturn pos+ltree[(ch<<1)+1];\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nUZIP.F.inflate = function(data, buf) {\r\n\tvar u8=Uint8Array;\r\n\tif(data[0]==3 && data[1]==0) return (buf ? buf : new u8(0));\r\n\tvar F=UZIP.F, bitsF = F._bitsF, bitsE = F._bitsE, decodeTiny = F._decodeTiny, makeCodes = F.makeCodes, codes2map=F.codes2map, get17 = F._get17;\r\n\tvar U = F.U;\r\n\t\r\n\tvar noBuf = (buf==null);\r\n\tif(noBuf) buf = new u8((data.length>>>2)<<3);\r\n\t\r\n\tvar BFINAL=0, BTYPE=0, HLIT=0, HDIST=0, HCLEN=0, ML=0, MD=0; \t\r\n\tvar off = 0, pos = 0;\r\n\tvar lmap, dmap;\r\n\t\r\n\twhile(BFINAL==0) {\t\t\r\n\t\tBFINAL = bitsF(data, pos , 1);\r\n\t\tBTYPE = bitsF(data, pos+1, 2); pos+=3;\r\n\t\t//console.log(BFINAL, BTYPE);\r\n\t\t\r\n\t\tif(BTYPE==0) {\r\n\t\t\tif((pos&7)!=0) pos+=8-(pos&7);\r\n\t\t\tvar p8 = (pos>>>3)+4, len = data[p8-4]|(data[p8-3]<<8); //console.log(len);//bitsF(data, pos, 16), \r\n\t\t\tif(noBuf) buf=UZIP.F._check(buf, off+len);\r\n\t\t\tbuf.set(new u8(data.buffer, data.byteOffset+p8, len), off);\r\n\t\t\t//for(var i=0; itl)tl=l; } pos+=3*HCLEN; //console.log(itree);\r\n\t\t\tmakeCodes(U.itree, tl);\r\n\t\t\tcodes2map(U.itree, tl, U.imap);\r\n\t\t\t\r\n\t\t\tlmap = U.lmap; dmap = U.dmap;\r\n\t\t\t\r\n\t\t\tpos = decodeTiny(U.imap, (1<>>24))-1; pos+=(ml&0xffffff);\r\n\t\t\tmakeCodes(U.ltree, mx0);\r\n\t\t\tcodes2map(U.ltree, mx0, lmap);\r\n\t\t\t\r\n\t\t\t//var md = decodeTiny(U.imap, (1<>>24))-1; pos+=(md&0xffffff);\r\n\t\t\tmakeCodes(U.dtree, mx1);\r\n\t\t\tcodes2map(U.dtree, mx1, dmap);\r\n\t\t}\r\n\t\t//var ooff=off, opos=pos;\r\n\t\twhile(true) {\r\n\t\t\tvar code = lmap[get17(data, pos) & ML]; pos += code&15;\r\n\t\t\tvar lit = code>>>4; //U.lhst[lit]++; \r\n\t\t\tif((lit>>>8)==0) { buf[off++] = lit; }\r\n\t\t\telse if(lit==256) { break; }\r\n\t\t\telse {\r\n\t\t\t\tvar end = off+lit-254;\r\n\t\t\t\tif(lit>264) { var ebs = U.ldef[lit-257]; end = off + (ebs>>>3) + bitsE(data, pos, ebs&7); pos += ebs&7; }\r\n\t\t\t\t//UZIP.F.dst[end-off]++;\r\n\t\t\t\t\r\n\t\t\t\tvar dcode = dmap[get17(data, pos) & MD]; pos += dcode&15;\r\n\t\t\t\tvar dlit = dcode>>>4;\r\n\t\t\t\tvar dbs = U.ddef[dlit], dst = (dbs>>>4) + bitsF(data, pos, dbs&15); pos += dbs&15;\r\n\t\t\t\t\r\n\t\t\t\t//var o0 = off-dst, stp = Math.min(end-off, dst);\r\n\t\t\t\t//if(stp>20) while(off>>3);\r\n\t}\r\n\t//console.log(UZIP.F.dst);\r\n\t//console.log(tlen, dlen, off-tlen+tcnt);\r\n\treturn buf.length==off ? buf : buf.slice(0,off);\r\n}\r\nUZIP.F._check=function(buf, len) {\r\n\tvar bl=buf.length; if(len<=bl) return buf;\r\n\tvar nbuf = new Uint8Array(Math.max(bl<<1,len)); nbuf.set(buf,0);\r\n\t//for(var i=0; i>>4; \r\n\t\tif(lit<=15) { tree[i]=lit; i++; }\r\n\t\telse {\r\n\t\t\tvar ll = 0, n = 0;\r\n\t\t\tif(lit==16) {\r\n\t\t\t\tn = (3 + bitsE(data, pos, 2)); pos += 2; ll = tree[i-1];\r\n\t\t\t}\r\n\t\t\telse if(lit==17) {\r\n\t\t\t\tn = (3 + bitsE(data, pos, 3)); pos += 3;\r\n\t\t\t}\r\n\t\t\telse if(lit==18) {\r\n\t\t\t\tn = (11 + bitsE(data, pos, 7)); pos += 7;\r\n\t\t\t}\r\n\t\t\tvar ni = i+n;\r\n\t\t\twhile(i>>1;\r\n\twhile(imx)mx=v; i++; }\r\n\twhile(i>1;\r\n\t\tvar cl = tree[i+1], val = (lit<<4)|cl; // : (0x8000 | (U.of0[lit-257]<<7) | (U.exb[lit-257]<<4) | cl);\r\n\t\tvar rest = (MAX_BITS-cl), i0 = tree[i]<>>(15-MAX_BITS);\r\n\t\twhile(i0!=i1) {\r\n\t\t\tvar p0 = r15[i0]>>>(15-MAX_BITS);\r\n\t\t\tmap[p0]=val; i0++;\r\n\t\t}\r\n\t}\r\n}\r\nUZIP.F.revCodes = function(tree, MAX_BITS) {\r\n\tvar r15 = UZIP.F.U.rev15, imb = 15-MAX_BITS;\r\n\tfor(var i=0; i>>imb; }\r\n}\r\n\r\n// used only in deflate\r\nUZIP.F._putsE= function(dt, pos, val ) { val = val<<(pos&7); var o=(pos>>>3); dt[o]|=val; dt[o+1]|=(val>>>8); }\r\nUZIP.F._putsF= function(dt, pos, val ) { val = val<<(pos&7); var o=(pos>>>3); dt[o]|=val; dt[o+1]|=(val>>>8); dt[o+2]|=(val>>>16); }\r\n\r\nUZIP.F._bitsE= function(dt, pos, length) { return ((dt[pos>>>3] | (dt[(pos>>>3)+1]<<8) )>>>(pos&7))&((1<>>3] | (dt[(pos>>>3)+1]<<8) | (dt[(pos>>>3)+2]<<16))>>>(pos&7))&((1<>>3] | (dt[(pos>>>3)+1]<<8))>>>(pos&7))&511;\r\n} */\r\nUZIP.F._get17= function(dt, pos) {\t// return at least 17 meaningful bytes\r\n\treturn (dt[pos>>>3] | (dt[(pos>>>3)+1]<<8) | (dt[(pos>>>3)+2]<<16) )>>>(pos&7);\r\n}\r\nUZIP.F._get25= function(dt, pos) {\t// return at least 17 meaningful bytes\r\n\treturn (dt[pos>>>3] | (dt[(pos>>>3)+1]<<8) | (dt[(pos>>>3)+2]<<16) | (dt[(pos>>>3)+3]<<24) )>>>(pos&7);\r\n}\r\nUZIP.F.U = function(){\r\n\tvar u16=Uint16Array, u32=Uint32Array;\r\n\treturn {\r\n\t\tnext_code : new u16(16),\r\n\t\tbl_count : new u16(16),\r\n\t\tordr : [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ],\r\n\t\tof0 : [3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],\r\n\t\texb : [0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0, 0],\r\n\t\tldef : new u16(32),\r\n\t\tdf0 : [1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 65535, 65535],\r\n\t\tdxb : [0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0],\r\n\t\tddef : new u32(32),\r\n\t\tflmap: new u16( 512), fltree: [],\r\n\t\tfdmap: new u16( 32), fdtree: [],\r\n\t\tlmap : new u16(32768), ltree : [], ttree:[],\r\n\t\tdmap : new u16(32768), dtree : [],\r\n\t\timap : new u16( 512), itree : [],\r\n\t\t//rev9 : new u16( 512)\r\n\t\trev15: new u16(1<<15),\r\n\t\tlhst : new u32(286), dhst : new u32( 30), ihst : new u32(19),\r\n\t\tlits : new u32(15000),\r\n\t\tstrt : new u16(1<<16),\r\n\t\tprev : new u16(1<<15)\r\n\t}; \r\n} ();\r\n\r\n(function(){\t\r\n\tvar U = UZIP.F.U;\r\n\tvar len = 1<<15;\r\n\tfor(var i=0; i>> 1) | ((x & 0x55555555) << 1));\r\n\t\tx = (((x & 0xcccccccc) >>> 2) | ((x & 0x33333333) << 2));\r\n\t\tx = (((x & 0xf0f0f0f0) >>> 4) | ((x & 0x0f0f0f0f) << 4));\r\n\t\tx = (((x & 0xff00ff00) >>> 8) | ((x & 0x00ff00ff) << 8));\r\n\t\tU.rev15[i] = (((x >>> 16) | (x << 16)))>>>17;\r\n\t}\r\n\t\r\n\tfunction pushV(tgt, n, sv) { while(n--!=0) tgt.push(0,sv); }\r\n\t\r\n\tfor(var i=0; i<32; i++) { U.ldef[i]=(U.of0[i]<<3)|U.exb[i]; U.ddef[i]=(U.df0[i]<<4)|U.dxb[i]; }\r\n\t\r\n\tpushV(U.fltree, 144, 8); pushV(U.fltree, 255-143, 9); pushV(U.fltree, 279-255, 7); pushV(U.fltree,287-279,8);\r\n\t/*\r\n\tvar i = 0;\r\n\tfor(; i<=143; i++) U.fltree.push(0,8);\r\n\tfor(; i<=255; i++) U.fltree.push(0,9);\r\n\tfor(; i<=279; i++) U.fltree.push(0,7);\r\n\tfor(; i<=287; i++) U.fltree.push(0,8);\r\n\t*/\r\n\tUZIP.F.makeCodes(U.fltree, 9);\r\n\tUZIP.F.codes2map(U.fltree, 9, U.flmap);\r\n\tUZIP.F.revCodes (U.fltree, 9)\r\n\t\r\n\tpushV(U.fdtree,32,5);\r\n\t//for(i=0;i<32; i++) U.fdtree.push(0,5);\r\n\tUZIP.F.makeCodes(U.fdtree, 5);\r\n\tUZIP.F.codes2map(U.fdtree, 5, U.fdmap);\r\n\tUZIP.F.revCodes (U.fdtree, 5)\r\n\t\r\n\tpushV(U.itree,19,0); pushV(U.ltree,286,0); pushV(U.dtree,30,0); pushV(U.ttree,320,0);\r\n\t/*\r\n\tfor(var i=0; i< 19; i++) U.itree.push(0,0);\r\n\tfor(var i=0; i<286; i++) U.ltree.push(0,0);\r\n\tfor(var i=0; i< 30; i++) U.dtree.push(0,0);\r\n\tfor(var i=0; i<320; i++) U.ttree.push(0,0);\r\n\t*/\r\n})()\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", "/** @format */\n\nimport { inflate } from 'uzip';\nimport { Crc32 } from '../common/crc32';\nimport { InputBuffer } from '../common/input-buffer';\nimport { ArrayUtils } from '../common/array-utils';\nimport { StringUtils } from '../common/string-utils';\nimport { LibError } from '../error/lib-error';\nimport { DecodeInfo } from './decode-info';\nimport { Decoder } from './decoder';\nimport { PngFrame } from './png/png-frame';\nimport { PngInfo } from './png/png-info';\nimport { PngColorType } from './png/png-color-type';\nimport { PngDisposeMode } from './png/png-dispose-mode';\nimport { PngBlendMode } from './png/png-blend-mode';\nimport { ColorRgba8 } from '../color/color-rgba8';\nimport { ColorRgb8 } from '../color/color-rgb8';\nimport { MemoryImage, MemoryImageCreateOptions } from '../image/image';\nimport { PaletteUint8 } from '../image/palette-uint8';\nimport { Format } from '../color/format';\nimport { IccProfile } from '../image/icc-profile';\nimport { IccProfileCompression } from '../image/icc-profile-compression';\nimport { Draw } from '../draw/draw';\nimport { BlendMode } from '../draw/blend-mode';\nimport { PngFilterType } from './png/png-filter-type';\nimport { Pixel } from '../image/pixel';\n\n/**\n * Decode a PNG encoded image.\n */\nexport class PngDecoder implements Decoder {\n private _input?: InputBuffer;\n public get input(): InputBuffer | undefined {\n return this._input;\n }\n\n private _info: PngInfo = new PngInfo();\n public get info(): PngInfo {\n return this._info;\n }\n\n private _progressY = 0;\n public get progressY(): number {\n return this._progressY;\n }\n\n private _bitBuffer = 0;\n public get bitBuffer(): number {\n return this._bitBuffer;\n }\n\n private _bitBufferLen = 0;\n public get bitBufferLen(): number {\n return this._bitBufferLen;\n }\n\n /**\n * The number of frames that can be decoded.\n */\n public get numFrames(): number {\n return this._info.numFrames;\n }\n\n private static unfilter(\n filterType: PngFilterType,\n bpp: number,\n row: Uint8Array,\n prevRow?: Uint8Array\n ): void {\n const rowBytes = row.length;\n\n switch (filterType) {\n case PngFilterType.none:\n break;\n case PngFilterType.sub:\n for (let x = bpp; x < rowBytes; ++x) {\n row[x] = (row[x] + row[x - bpp]) & 0xff;\n }\n break;\n case PngFilterType.up:\n for (let x = 0; x < rowBytes; ++x) {\n const b = prevRow !== undefined ? prevRow[x] : 0;\n row[x] = (row[x] + b) & 0xff;\n }\n break;\n case PngFilterType.average:\n for (let x = 0; x < rowBytes; ++x) {\n const a = x < bpp ? 0 : row[x - bpp];\n const b = prevRow !== undefined ? prevRow[x] : 0;\n row[x] = (row[x] + ((a + b) >> 1)) & 0xff;\n }\n break;\n case PngFilterType.paeth:\n for (let x = 0; x < rowBytes; ++x) {\n const a = x < bpp ? 0 : row[x - bpp];\n const b = prevRow !== undefined ? prevRow[x] : 0;\n const c = x < bpp || prevRow === undefined ? 0 : prevRow[x - bpp];\n\n const p = a + b - c;\n\n const pa = Math.abs(p - a);\n const pb = Math.abs(p - b);\n const pc = Math.abs(p - c);\n\n let paeth = 0;\n if (pa <= pb && pa <= pc) {\n paeth = a;\n } else if (pb <= pc) {\n paeth = b;\n } else {\n paeth = c;\n }\n\n row[x] = (row[x] + paeth) & 0xff;\n }\n break;\n default:\n throw new LibError(`Invalid filter value: ${filterType}`);\n }\n }\n\n /**\n * Return the CRC of the bytes\n */\n private static crc(type: string, bytes: Uint8Array): number {\n const typeCodeUnits = StringUtils.getCodePoints(type);\n const crc = Crc32.getChecksum({\n buffer: typeCodeUnits,\n });\n return Crc32.getChecksum({\n buffer: bytes,\n baseCrc: crc,\n });\n }\n\n /**\n * Process a pass of an interlaced image.\n */\n private processPass(\n input: InputBuffer,\n image: MemoryImage,\n xOffset: number,\n yOffset: number,\n xStep: number,\n yStep: number,\n passWidth: number,\n passHeight: number\n ): void {\n let channels = 1;\n if (this._info.colorType === PngColorType.grayscaleAlpha) {\n channels = 2;\n } else if (this._info.colorType === PngColorType.rgb) {\n channels = 3;\n } else if (this._info.colorType === PngColorType.rgba) {\n channels = 4;\n }\n\n const pixelDepth = channels * this._info.bits;\n const bpp = (pixelDepth + 7) >> 3;\n const rowBytes = (pixelDepth * passWidth + 7) >> 3;\n\n const inData: Array = [undefined, undefined];\n\n const pixel = [0, 0, 0, 0];\n\n // Let pi: number = 0;\n for (\n let srcY = 0, dstY = yOffset, ri = 0;\n srcY < passHeight;\n ++srcY, dstY += yStep, ri = 1 - ri, this._progressY++\n ) {\n const filterType = input.readByte() as PngFilterType;\n inData[ri] = input.readBytes(rowBytes).toUint8Array();\n\n const row = inData[ri]!;\n const prevRow = inData[1 - ri];\n\n // Before the image is compressed, it was filtered to improve compression.\n // Reverse the filter now.\n PngDecoder.unfilter(filterType, bpp, row, prevRow);\n\n // Scanlines are always on byte boundaries, so for bit depths < 8,\n // reset the bit stream counter.\n this.resetBits();\n\n const rowInput = new InputBuffer({\n buffer: row,\n bigEndian: true,\n });\n\n const blockHeight = xStep;\n const blockWidth = xStep - xOffset;\n\n // Let yMax: number = Math.min(dstY + blockHeight, _info.height);\n\n for (\n let srcX = 0, dstX = xOffset;\n srcX < passWidth;\n ++srcX, dstX += xStep\n ) {\n this.readPixel(rowInput, pixel);\n this.setPixel(image.getPixel(dstX, dstY), pixel);\n\n if (blockWidth > 1 || blockHeight > 1) {\n for (let i = 0; i < blockHeight; ++i) {\n for (let j = 0; j < blockWidth; ++j) {\n this.setPixel(image.getPixelSafe(dstX + j, dstY + i), pixel);\n }\n }\n }\n }\n }\n }\n\n private process(input: InputBuffer, image: MemoryImage): void {\n let channels = 1;\n if (this._info.colorType === PngColorType.grayscaleAlpha) {\n channels = 2;\n } else if (this._info.colorType === PngColorType.rgb) {\n channels = 3;\n } else if (this._info.colorType === PngColorType.rgba) {\n channels = 4;\n }\n\n const pixelDepth = channels * this._info!.bits!;\n\n const w = this._info.width;\n const h = this._info.height;\n\n const rowBytes = (w * pixelDepth + 7) >> 3;\n const bpp = (pixelDepth + 7) >> 3;\n\n const line = new Uint8Array(rowBytes);\n const inData = [line, line];\n\n const pixel = [0, 0, 0, 0];\n\n const pIter = image[Symbol.iterator]();\n let pIterRes = pIter.next();\n for (let y = 0, ri = 0; y < h; ++y, ri = 1 - ri) {\n const filterType = input.readByte() as PngFilterType;\n inData[ri] = input.readBytes(rowBytes).toUint8Array();\n\n const row = inData[ri];\n const prevRow = inData[1 - ri];\n\n // Before the image is compressed, it was filtered to improve compression.\n // Reverse the filter now.\n PngDecoder.unfilter(filterType, bpp, row, prevRow);\n\n // Scanlines are always on byte boundaries, so for bit depths < 8,\n // reset the bit stream counter.\n this.resetBits();\n\n const rowInput = new InputBuffer({\n buffer: inData[ri],\n bigEndian: true,\n });\n\n for (let x = 0; x < w; ++x) {\n this.readPixel(rowInput, pixel);\n this.setPixel(pIterRes.value, pixel);\n pIterRes = pIter.next();\n }\n }\n }\n\n private resetBits(): void {\n this._bitBuffer = 0;\n this._bitBufferLen = 0;\n }\n\n /**\n * Read a number of bits from the input stream.\n */\n private readBits(input: InputBuffer, numBits: number): number {\n if (numBits === 0) {\n return 0;\n }\n\n if (numBits === 8) {\n return input.readByte();\n }\n\n if (numBits === 16) {\n return input.readUint16();\n }\n\n // Not enough buffer\n while (this._bitBufferLen < numBits) {\n if (input.isEOS) {\n throw new LibError('Invalid PNG data.');\n }\n\n // Input byte\n const octet = input.readByte();\n\n // Concat octet\n this._bitBuffer = octet << this._bitBufferLen;\n this._bitBufferLen += 8;\n }\n\n // Output byte\n let mask = 0;\n switch (numBits) {\n case 1:\n mask = 1;\n break;\n case 2:\n mask = 3;\n break;\n case 4:\n mask = 0xf;\n break;\n case 8:\n mask = 0xff;\n break;\n case 16:\n mask = 0xffff;\n break;\n default:\n mask = 0;\n break;\n }\n\n const octet = (this._bitBuffer >> (this._bitBufferLen - numBits)) & mask;\n\n this._bitBufferLen -= numBits;\n\n return octet;\n }\n\n /**\n * Read the next pixel from the input stream.\n */\n private readPixel(input: InputBuffer, pixel: number[]): void {\n switch (this._info.colorType) {\n case PngColorType.grayscale:\n pixel[0] = this.readBits(input, this._info.bits!);\n return;\n case PngColorType.rgb:\n pixel[0] = this.readBits(input, this._info.bits!);\n pixel[1] = this.readBits(input, this._info.bits!);\n pixel[2] = this.readBits(input, this._info.bits!);\n return;\n case PngColorType.indexed:\n pixel[0] = this.readBits(input, this._info.bits!);\n return;\n case PngColorType.grayscaleAlpha:\n pixel[0] = this.readBits(input, this._info.bits!);\n pixel[1] = this.readBits(input, this._info.bits!);\n return;\n case PngColorType.rgba:\n pixel[0] = this.readBits(input, this._info.bits!);\n pixel[1] = this.readBits(input, this._info.bits!);\n pixel[2] = this.readBits(input, this._info.bits!);\n pixel[3] = this.readBits(input, this._info.bits!);\n return;\n }\n throw new LibError(`Invalid color type: ${this._info.colorType}.`);\n }\n\n // Get the color with the list of components.\n private setPixel(p: Pixel, raw: number[]): void {\n switch (this._info.colorType) {\n case PngColorType.grayscale:\n if (this._info.transparency !== undefined && this._info.bits > 8) {\n const t = this._info.transparency!;\n const a = ((t[0] & 0xff) << 24) | (t[1] & 0xff);\n const g = raw[0];\n p.setRgba(g, g, g, g !== a ? p.maxChannelValue : 0);\n return;\n }\n p.setRgb(raw[0], 0, 0);\n return;\n case PngColorType.rgb:\n {\n const r = raw[0];\n const g = raw[1];\n const b = raw[2];\n\n if (this._info.transparency !== undefined) {\n const t = this._info.transparency!;\n const tr = ((t[0] & 0xff) << 8) | (t[1] & 0xff);\n const tg = ((t[2] & 0xff) << 8) | (t[3] & 0xff);\n const tb = ((t[4] & 0xff) << 8) | (t[5] & 0xff);\n if (raw[0] !== tr || raw[1] !== tg || raw[2] !== tb) {\n p.setRgba(r, g, b, p.maxChannelValue);\n return;\n }\n }\n\n p.setRgb(r, g, b);\n }\n return;\n case PngColorType.indexed:\n p.index = raw[0];\n return;\n case PngColorType.grayscaleAlpha:\n p.setRgb(raw[0], raw[1], 0);\n return;\n case PngColorType.rgba:\n p.setRgba(raw[0], raw[1], raw[2], raw[3]);\n return;\n }\n\n throw new LibError(`Invalid color type: ${this._info.colorType}.`);\n }\n\n /**\n * Is the given file a valid PNG image?\n */\n public isValidFile(bytes: Uint8Array): boolean {\n this._input = new InputBuffer({\n buffer: bytes,\n bigEndian: true,\n });\n const headerBytes = this._input.readBytes(8);\n const expectedHeaderBytes = [137, 80, 78, 71, 13, 10, 26, 10];\n for (let i = 0; i < 8; ++i) {\n if (headerBytes.getByte(i) !== expectedHeaderBytes[i]) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Start decoding the data as an animation sequence, but don't actually\n * process the frames until they are requested with decodeFrame.\n */\n public startDecode(bytes: Uint8Array): DecodeInfo | undefined {\n if (!this.isValidFile(bytes) || this._input === undefined) {\n return undefined;\n }\n\n while (true) {\n const inputPos = this._input.position;\n let chunkSize = this._input.readUint32();\n const chunkType = this._input.readString(4);\n switch (chunkType) {\n case 'tEXt':\n {\n const txtData = this._input.readBytes(chunkSize).toUint8Array();\n const l = txtData.length;\n for (let i = 0; i < l; ++i) {\n if (txtData[i] === 0) {\n const key = StringUtils.latin1Decoder.decode(\n ArrayUtils.copyUint8(txtData, 0, i)\n );\n const text = StringUtils.latin1Decoder.decode(\n ArrayUtils.copyUint8(txtData, i + 1)\n );\n this._info.textData.set(key, text);\n break;\n }\n }\n // CRC\n this._input.skip(4);\n }\n break;\n case 'IHDR': {\n const hdr = InputBuffer.from(this._input.readBytes(chunkSize));\n const hdrBytes: Uint8Array = hdr.toUint8Array();\n this._info.width = hdr.readUint32();\n this._info.height = hdr.readUint32();\n this._info.bits = hdr.readByte();\n this._info.colorType = hdr.readByte();\n this._info.compressionMethod = hdr.readByte();\n this._info.filterMethod = hdr.readByte();\n this._info.interlaceMethod = hdr.readByte();\n\n if (this._info.filterMethod !== 0) {\n return undefined;\n }\n\n switch (this._info.colorType) {\n case PngColorType.grayscale:\n if (![1, 2, 4, 8, 16].includes(this._info.bits!)) {\n return undefined;\n }\n break;\n case PngColorType.rgb:\n if (![8, 16].includes(this._info.bits!)) {\n return undefined;\n }\n break;\n case PngColorType.indexed:\n if (![1, 2, 4, 8].includes(this._info.bits!)) {\n return undefined;\n }\n break;\n case PngColorType.grayscaleAlpha:\n if (![8, 16].includes(this._info.bits!)) {\n return undefined;\n }\n break;\n case PngColorType.rgba:\n if (![8, 16].includes(this._info.bits!)) {\n return undefined;\n }\n break;\n default:\n // The proposed image data is not supported.\n return undefined;\n }\n\n const crc = this._input.readUint32();\n const computedCrc = PngDecoder.crc(chunkType, hdrBytes);\n if (crc !== computedCrc) {\n throw new LibError(`Invalid ${chunkType} checksum`);\n }\n break;\n }\n case 'PLTE': {\n this._info.palette = this._input.readBytes(chunkSize).toUint8Array();\n const crc = this._input.readUint32();\n const computedCrc = PngDecoder.crc(chunkType, this._info.palette);\n if (crc !== computedCrc) {\n throw new LibError(`Invalid ${chunkType} checksum`);\n }\n break;\n }\n case 'tRNS': {\n this._info.transparency = this._input\n .readBytes(chunkSize)\n .toUint8Array();\n const crc = this._input.readUint32();\n const computedCrc = PngDecoder.crc(\n chunkType,\n this._info.transparency\n );\n if (crc !== computedCrc) {\n throw new LibError(`Invalid ${chunkType} checksum`);\n }\n break;\n }\n case 'IEND': {\n // End of the image\n // CRC\n this._input.skip(4);\n break;\n }\n case 'gAMA': {\n if (chunkSize !== 4) {\n throw new LibError('Invalid gAMA chunk');\n }\n const gammaInt = this._input.readUint32();\n // CRC\n this._input.skip(4);\n // A gamma of 1 doesn't have any affect, so pretend we didn't get\n // a gamma in that case.\n if (gammaInt !== 100000) {\n this._info.gamma = gammaInt / 100000.0;\n }\n break;\n }\n case 'IDAT': {\n this._info.idat.push(inputPos);\n this._input.skip(chunkSize);\n // CRC\n this._input.skip(4);\n break;\n }\n case 'acTL': {\n // Animation control chunk\n this._info.numFrames = this._input.readUint32();\n this._info.repeat = this._input.readUint32();\n // CRC\n this._input.skip(4);\n break;\n }\n case 'fcTL': {\n // Frame control chunk\n const sequenceNumber = this._input.readUint32();\n const width = this._input.readUint32();\n const height = this._input.readUint32();\n const xOffset = this._input.readUint32();\n const yOffset = this._input.readUint32();\n const delayNum = this._input.readUint16();\n const delayDen = this._input.readUint16();\n const dispose = this._input.readByte() as PngDisposeMode;\n const blend = this._input.readByte() as PngBlendMode;\n // CRC\n this._input.skip(4);\n\n const frame: PngFrame = new PngFrame({\n sequenceNumber: sequenceNumber,\n width: width,\n height: height,\n xOffset: xOffset,\n yOffset: yOffset,\n delayNum: delayNum,\n delayDen: delayDen,\n dispose: dispose,\n blend: blend,\n });\n this._info.frames.push(frame);\n break;\n }\n case 'fdAT': {\n const sequenceNumber = this._input.readUint32();\n const frame = this._info.frames[this._info.frames.length - 1];\n frame.fdat.push(inputPos);\n this._input.skip(chunkSize - 4);\n // CRC\n this._input.skip(4);\n break;\n }\n case 'bKGD': {\n if (this._info.colorType === PngColorType.indexed) {\n const paletteIndex = this._input.readByte();\n chunkSize--;\n const p3 = paletteIndex * 3;\n const r = this._info.palette![p3]!;\n const g = this._info.palette![p3 + 1]!;\n const b = this._info.palette![p3 + 2]!;\n if (this._info.transparency !== undefined) {\n const isTransparent =\n this._info.transparency.includes(paletteIndex);\n this._info.backgroundColor = new ColorRgba8(\n r,\n g,\n b,\n isTransparent ? 0 : 255\n );\n } else {\n this._info.backgroundColor = new ColorRgb8(r, g, b);\n }\n } else if (\n this._info.colorType === PngColorType.grayscale ||\n this._info.colorType === PngColorType.grayscaleAlpha\n ) {\n /* Const gray: number = */\n this._input.readUint16();\n chunkSize -= 2;\n } else if (\n this._info.colorType === PngColorType.rgb ||\n this._info.colorType === PngColorType.rgba\n ) {\n /* Const r: number = */\n this._input.readUint16();\n /* Const g: number = */\n this._input.readUint16();\n /* Const b: number = */\n this._input.readUint16();\n chunkSize -= 24;\n }\n if (chunkSize > 0) {\n this._input.skip(chunkSize);\n }\n // CRC\n this._input.skip(4);\n break;\n }\n case 'iCCP': {\n this._info.iccpName = this._input.readString();\n // 0: deflate\n this._info.iccpCompression = this._input.readByte();\n chunkSize -= this._info.iccpName.length + 2;\n const profile = this._input.readBytes(chunkSize);\n this._info.iccpData = profile.toUint8Array();\n // CRC\n this._input.skip(4);\n break;\n }\n default: {\n this._input.skip(chunkSize);\n // CRC\n this._input.skip(4);\n break;\n }\n }\n\n if (chunkType === 'IEND') {\n break;\n }\n\n if (this._input.isEOS) {\n return undefined;\n }\n }\n\n return this._info;\n }\n\n /**\n * Decode the frame (assuming **startDecode** has already been called).\n */\n public decodeFrame(frame: number): MemoryImage | undefined {\n if (this._input === undefined) {\n return undefined;\n }\n\n let imageData: Uint8Array | undefined = undefined;\n let width: number | undefined = this._info.width;\n let height: number | undefined = this._info.height;\n\n if (!this._info.isAnimated || frame === 0) {\n let totalSize = 0;\n const len = this._info.idat.length;\n const dataBlocks: Uint8Array[] = new Array();\n for (let i = 0; i < len; ++i) {\n this._input.offset = this._info.idat[i];\n const chunkSize = this._input.readUint32();\n const chunkType = this._input.readString(4);\n const data = this._input.readBytes(chunkSize).toUint8Array();\n totalSize += data.length;\n dataBlocks.push(data);\n const crc = this._input.readUint32();\n const computedCrc = PngDecoder.crc(chunkType, data);\n if (crc !== computedCrc) {\n throw new LibError(`Invalid ${chunkType} checksum`);\n }\n }\n imageData = new Uint8Array(totalSize);\n let offset = 0;\n for (const data of dataBlocks) {\n imageData.set(data, offset);\n offset += data.length;\n }\n } else {\n if (frame < 0 || frame >= this._info.frames.length) {\n throw new LibError(`Invalid Frame Number: ${frame}`);\n }\n\n const f = this._info.frames[frame];\n width = f.width;\n height = f.height;\n let totalSize = 0;\n const dataBlocks: Uint8Array[] = new Array();\n for (let i = 0; i < f.fdat.length; ++i) {\n this._input.offset = f.fdat[i];\n const chunkSize = this._input.readUint32();\n // fDat chunk header\n this._input.readString(4);\n // Sequence number\n this._input.skip(4);\n const data = this._input.readBytes(chunkSize - 4).toUint8Array();\n totalSize += data.length;\n dataBlocks.push(data);\n }\n\n imageData = new Uint8Array(totalSize);\n let offset = 0;\n for (const data of dataBlocks) {\n imageData.set(data, offset);\n offset += data.length;\n }\n }\n\n let numChannels =\n this._info.colorType === PngColorType.indexed\n ? 1\n : this._info.colorType === PngColorType.grayscale\n ? 1\n : this._info.colorType === PngColorType.grayscaleAlpha\n ? 2\n : this._info.colorType === PngColorType.rgba\n ? 4\n : 3;\n\n let uncompressed: Uint8Array | undefined = undefined;\n try {\n uncompressed = inflate(imageData);\n } catch (error) {\n console.error(error);\n return undefined;\n }\n\n // Input is the decompressed data.\n const input = new InputBuffer({\n buffer: uncompressed,\n bigEndian: true,\n });\n this.resetBits();\n\n let palette: PaletteUint8 | undefined = undefined;\n\n // Non-indexed PNGs may have a palette, but it only provides a suggested\n // set of colors to which an RGB color can be quantized if not displayed\n // directly. In this case, just ignore the palette.\n if (this._info.colorType === PngColorType.indexed) {\n if (this._info.palette !== undefined) {\n const p = this._info.palette!;\n const numColors = Math.trunc(p.length / 3);\n const t = this._info.transparency;\n const tl = t !== undefined ? t.length : 0;\n const nc = t !== undefined ? 4 : 3;\n palette = new PaletteUint8(numColors, nc);\n for (let i = 0, pi = 0; i < numColors; ++i, pi += 3) {\n let a = 255;\n if (nc === 4 && i < tl) {\n a = t![i];\n }\n palette.setRgba(i, p[pi]!, p[pi + 1]!, p[pi + 2]!, a);\n }\n }\n }\n\n // grayscale images with no palette but with transparency, get\n // converted to a indexed palette image.\n if (\n this._info.colorType === PngColorType.grayscale &&\n this._info.transparency !== undefined &&\n palette === undefined &&\n this._info.bits <= 8\n ) {\n const t = this._info.transparency!;\n const nt = t.length;\n const numColors = 1 << this._info.bits;\n palette = new PaletteUint8(numColors, 4);\n // palette color are 8-bit, so convert the grayscale bit value to the\n // 8-bit palette value.\n const to8bit =\n this._info.bits === 1\n ? 255\n : this._info.bits === 2\n ? 85\n : this._info.bits === 4\n ? 17\n : 1;\n for (let i = 0; i < numColors; ++i) {\n const g = i * to8bit;\n palette.setRgba(i, g, g, g, 255);\n }\n for (let i = 0; i < nt; i += 2) {\n const ti = ((t[i] & 0xff) << 8) | (t[i + 1] & 0xff);\n if (ti < numColors) {\n palette.set(ti, 3, 0);\n }\n }\n }\n\n const format =\n this._info.bits === 1\n ? Format.uint1\n : this._info.bits === 2\n ? Format.uint2\n : this._info.bits === 4\n ? Format.uint4\n : this._info.bits === 16\n ? Format.uint16\n : Format.uint8;\n\n if (\n this._info.colorType === PngColorType.grayscale &&\n this._info.transparency !== undefined &&\n this._info.bits > 8\n ) {\n numChannels = 4;\n }\n\n if (\n this._info.colorType === PngColorType.rgb &&\n this._info.transparency !== undefined\n ) {\n numChannels = 4;\n }\n\n const opt: MemoryImageCreateOptions = {\n width: width,\n height: height,\n numChannels: numChannels,\n palette: palette,\n format: format,\n };\n\n if (this._info.iccpData !== undefined) {\n opt.iccProfile = new IccProfile(\n this._info.iccpName,\n IccProfileCompression.deflate,\n this._info.iccpData\n );\n }\n\n if (this._info.textData.size > 0) {\n opt.textData = new Map(this._info.textData);\n }\n\n const image = new MemoryImage(opt);\n\n const origW = this._info.width;\n const origH = this._info.height;\n this._info.width = width;\n this._info.height = height;\n\n const w = width;\n const h = height;\n this._progressY = 0;\n if (this._info.interlaceMethod !== 0) {\n this.processPass(input, image, 0, 0, 8, 8, (w + 7) >> 3, (h + 7) >> 3);\n this.processPass(input, image, 4, 0, 8, 8, (w + 3) >> 3, (h + 7) >> 3);\n this.processPass(input, image, 0, 4, 4, 8, (w + 3) >> 2, (h + 3) >> 3);\n this.processPass(input, image, 2, 0, 4, 4, (w + 1) >> 2, (h + 3) >> 2);\n this.processPass(input, image, 0, 2, 2, 4, (w + 1) >> 1, (h + 1) >> 2);\n this.processPass(input, image, 1, 0, 2, 2, w >> 1, (h + 1) >> 1);\n this.processPass(input, image, 0, 1, 1, 2, w, h >> 1);\n } else {\n this.process(input, image);\n }\n\n this._info.width = origW;\n this._info.height = origH;\n\n return image;\n }\n\n public decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined {\n if (this.startDecode(bytes) === undefined) {\n return undefined;\n }\n\n if (!this._info.isAnimated || frame !== undefined) {\n return this.decodeFrame(frame ?? 0);\n }\n\n let firstImage: MemoryImage | undefined = undefined;\n let lastImage: MemoryImage | undefined = undefined;\n for (let i = 0; i < this._info.numFrames; ++i) {\n const frame = this._info.frames[i];\n const image = this.decodeFrame(i);\n if (image === undefined) {\n continue;\n }\n\n if (firstImage === undefined || lastImage === undefined) {\n firstImage = image;\n lastImage = image;\n // Convert to MS\n lastImage.frameDuration = Math.trunc(frame.delay * 1000);\n continue;\n }\n\n if (\n image.width === lastImage.width &&\n image.height === lastImage.height &&\n frame.xOffset === 0 &&\n frame.yOffset === 0 &&\n frame.blend === PngBlendMode.source\n ) {\n lastImage = image;\n // Convert to MS\n lastImage.frameDuration = Math.trunc(frame.delay * 1000);\n firstImage.addFrame(lastImage);\n continue;\n }\n\n const dispose = frame.dispose;\n if (dispose === PngDisposeMode.background) {\n lastImage = MemoryImage.from(lastImage);\n lastImage.clear(this._info.backgroundColor);\n } else if (dispose === PngDisposeMode.previous) {\n lastImage = MemoryImage.from(lastImage);\n } else {\n lastImage = MemoryImage.from(lastImage);\n }\n\n // Convert to MS\n lastImage.frameDuration = Math.trunc(frame.delay * 1000);\n\n Draw.compositeImage({\n dst: lastImage,\n src: image,\n dstX: frame.xOffset,\n dstY: frame.yOffset,\n blend:\n frame.blend === PngBlendMode.over\n ? BlendMode.alpha\n : BlendMode.direct,\n });\n\n firstImage.addFrame(lastImage);\n }\n\n return firstImage;\n }\n}\n", "/** @format */\n\nimport { InputBuffer } from '../common/input-buffer';\nimport { OutputBuffer } from '../common/output-buffer';\nimport { BmpFileHeader } from './bmp/bmp-file-header';\nimport { Decoder } from './decoder';\nimport { DibDecoder } from './dib-decoder';\nimport { IcoBmpInfo } from './ico/ico-bmp-info';\nimport { IcoInfo } from './ico/ico-info';\nimport { PngDecoder } from './png-decoder';\nimport { MemoryImage } from '../image/image';\nimport { FrameType } from '../image/frame-type';\n\nexport class IcoDecoder implements Decoder {\n private _input?: InputBuffer;\n private _info?: IcoInfo;\n\n public get numFrames(): number {\n return this._info !== undefined ? this._info.numFrames : 0;\n }\n\n public isValidFile(bytes: Uint8Array): boolean {\n this._input = new InputBuffer({\n buffer: bytes,\n });\n this._info = IcoInfo.read(this._input);\n return this._info !== undefined;\n }\n\n public startDecode(bytes: Uint8Array): IcoInfo | undefined {\n this._input = new InputBuffer({\n buffer: bytes,\n });\n this._info = IcoInfo.read(this._input);\n return this._info;\n }\n\n public decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined {\n const info = this.startDecode(bytes);\n if (info === undefined) {\n return undefined;\n }\n\n if (info.images.length === 1 || frame !== undefined) {\n return this.decodeFrame(frame ?? 0);\n }\n\n let firstImage: MemoryImage | undefined = undefined;\n for (let i = 0; i < info.images.length; i++) {\n const frame = this.decodeFrame(i);\n if (frame === undefined) {\n continue;\n }\n if (firstImage === undefined) {\n frame.frameType = FrameType.sequence;\n firstImage = frame;\n } else {\n firstImage.addFrame(frame);\n }\n }\n\n return firstImage;\n }\n\n public decodeFrame(frame: number): MemoryImage | undefined {\n if (\n this._input === undefined ||\n this._info === undefined ||\n frame >= this._info.numFrames\n ) {\n return undefined;\n }\n\n const imageInfo = this._info.images[frame];\n const imageBuffer = this._input.buffer.subarray(\n this._input.start + imageInfo.bytesOffset,\n this._input.start + imageInfo.bytesOffset + imageInfo.bytesSize\n );\n\n const png = new PngDecoder();\n if (png.isValidFile(imageBuffer)) {\n return png.decode(imageBuffer);\n }\n\n // should be bmp.\n const dummyBmpHeader = new OutputBuffer({\n size: 14,\n });\n dummyBmpHeader.writeUint16(BmpFileHeader.signature);\n dummyBmpHeader.writeUint32(imageInfo.bytesSize);\n dummyBmpHeader.writeUint32(0);\n dummyBmpHeader.writeUint32(0);\n\n const bmpInfo = new IcoBmpInfo(\n new InputBuffer({\n buffer: imageBuffer,\n }),\n new BmpFileHeader(\n new InputBuffer({\n buffer: dummyBmpHeader.getBytes(),\n })\n )\n );\n\n if (bmpInfo.headerSize !== 40 && bmpInfo.planes !== 1) {\n // invalid header.\n return undefined;\n }\n\n let offset = 0;\n if (bmpInfo.totalColors === 0 && bmpInfo.bitsPerPixel <= 8) {\n offset = 40 + 4 * (1 << bmpInfo.bitsPerPixel);\n } else {\n offset = 40 + 4 * bmpInfo.totalColors;\n }\n\n bmpInfo.header.imageOffset = offset;\n dummyBmpHeader.length -= 4;\n dummyBmpHeader.writeUint32(offset);\n const inp = new InputBuffer({\n buffer: imageBuffer,\n });\n const bmp = new DibDecoder(inp, bmpInfo, true);\n\n const image = bmp.decodeFrame(0);\n if (image === undefined || bmpInfo.bitsPerPixel >= 32) {\n return image;\n }\n\n const padding = 32 - (bmpInfo.width % 32);\n const rowLength = Math.trunc(\n (padding === 32 ? bmpInfo.width : bmpInfo.width + padding) / 8\n );\n\n // AND bitmask\n for (let y = 0; y < bmpInfo.height; y++) {\n const line = bmpInfo.readBottomUp ? y : image.height - 1 - y;\n const row = inp.readBytes(rowLength);\n const p = image.getPixel(0, line);\n for (let x = 0; x < bmpInfo.width; ) {\n const b = row.readByte();\n for (let j = 7; j > -1 && x < bmpInfo.width; j--) {\n if ((b & (1 << j)) !== 0) {\n // set the pixel to completely transparent.\n p.a = 0;\n }\n p.next();\n x++;\n }\n }\n }\n\n return image;\n }\n\n /**\n * Decodes the largest frame.\n */\n public decodeImageLargest(bytes: Uint8Array): MemoryImage | undefined {\n const info = this.startDecode(bytes);\n if (info === undefined) {\n return undefined;\n }\n let largestFrame = 0;\n let largestSize = 0;\n for (let i = 0; i < info.images.length; i++) {\n const image = info.images[i];\n const size = image.width * image.height;\n if (size > largestSize) {\n largestSize = size;\n largestFrame = i;\n }\n }\n return this.decodeFrame(largestFrame);\n }\n}\n", ""], + "mappings": "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AIA,EAAQ,CACV,KAAM,YACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,eACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,OACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,QACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,eACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,kBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,eACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,kBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,iBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,iBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,sBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,WACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,YACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,YACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,iBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,aACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACN,OACA,MAAO,GACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,WACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,WACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,SACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,eACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,YACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,aACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,wBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,WACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,gBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,YACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,aACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,gBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,wBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,QACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,gBACN,MACF,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,eACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,eACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,uBACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,6BACR,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,oBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,sBACN,OACA,MAAO,CACT,CAAC,CACH,EAEA,CACE,IACA,IAAIA,EAAQ,CACV,KAAM,mBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,SACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,qBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,eACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,UACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACN,OACA,MAAO,CACT,CAAC,CACH,EAEA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,sBACN,MACF,CAAC,CACH,EAEA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,MACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,2BACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,cACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,oBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,qBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,sBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,0BACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,wBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,eACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,OACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,cACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,oBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,qBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,SACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,iBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,wBACR,CAAC,CACH,EAEA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,0BACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,uBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,uBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,0BACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,eACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,eACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,gBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,uBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,0BACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,sBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,eACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,kBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,WACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,YACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,mBACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,QACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,SACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,SACR,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,KACA,IAAIA,EAAQ,CACV,KAAM,YACN,MACF,CAAC,CACH,EACA,CACE,MACA,IAAIA,EAAQ,CACV,KAAM,eACN,MACF,CAAC,CACH,CACF,CAAC,EAEYG,GAAkB,IAAI,IAAqB,CACtD,CACE,EACA,IAAIH,EAAQ,CACV,KAAM,eACN,MACF,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,iBACN,MACF,CAAC,CACH,EACA,CACE,KACA,IAAIA,EAAQ,CACV,KAAM,yBACN,MACF,CAAC,CACH,EACA,CACE,KACA,IAAIA,EAAQ,CACV,KAAM,oBACN,OACA,MAAO,CACT,CAAC,CACH,EACA,CACE,KACA,IAAIA,EAAQ,CACV,KAAM,qBACN,OACA,MAAO,CACT,CAAC,CACH,CACF,CAAC,EAEYI,GAAc,IAAI,IAAqB,CAClD,CACE,EACA,IAAIJ,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,gBACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,iBACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,gBACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,cACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,eACR,CAAC,CACH,EACA,CACE,EACA,IAAIA,EAAQ,CACV,KAAM,WACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,gBACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,QACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,UACR,CAAC,CACH,EACA,CACE,GACA,IAAIA,EAAQ,CACV,KAAM,aACR,CAAC,CACH,EACA,CACE,GAC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K,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,GACrC,EArUWA,GA0Ua,kBAA8B,CACpD,MAAO,MAAO,MAAO,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,MAAO,MACpE,MAAO,MAAO,OAAQ,OAAQ,OAAQ,MACxC,EA7UWA,GAkVa,WAAuB,CAE7C,KAAM,KAAM,IAAK,IAAK,GAAI,GAAI,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,GAAI,GAAI,GAAI,EAClC,EAvVWA,GAyVa,aAAyB,CAAC,IAAK,IAAK,IAAK,GAAG,EAzVzDA,GA8Va,OAAmB,CAEzC,GAAI,GAAI,GAAI,GAAI,EAAG,EAAG,EAAG,EAEzB,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAErB,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAErB,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAErB,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,KAAM,KAAM,MAAO,MAAO,MAAO,MAAO,KAAM,KAE9C,KAAM,KAAM,OAAQ,OAAQ,OAAQ,OAAQ,KAAM,KAElD,KAAM,KAAM,OAAQ,OAAQ,IAAK,IAAK,IAAK,IAE3C,IAAK,IAAK,IAAK,IAAK,OAAQ,OAAQ,MAAO,MAE3C,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,KAAM,KAEhD,KAAM,KAAM,MAAO,MAAO,OAAQ,OAAQ,OAAQ,OAElD,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,KAEtC,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAE1C,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,KAAM,KAAM,KAAM,KAAM,IAAM,IAAM,KAAM,KAE1C,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAExC,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAEvC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAEnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAA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AAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC,KAAAC", + "names": ["ChannelOrderLength", "init_channel_order", "__esmMin", "init_channel", "__esmMin", "LibError", "init_lib_error", "__esmMin", "MathUtils", "init_math_utils", "__esmMin", "x", "edge0", "edge1", "t0", "t", "y", "a", "edge", "z", "_x", "_y", "num", "low", "high", "Rational", "init_rational", "__esmMin", "init_math_utils", "numerator", "denominator", "d", "MathUtils", "other", "ArrayUtils", "init_array_utils", "__esmMin", "init_lib_error", "init_rational", "from", "begin", "end", "LibError", "fromStart", "fromEnd", "to", "toStart", "viewFrom", "length", "value", "func", "a", "a1", "a2", "i", "l", "t", "v", "obj", "Rational", "_BitUtils", "BitUtils", "init_bit_utils", "__esmMin", "v", "c", "_v", "x", "bits", "value", "n", "d", "bitCount", "result", "Float16", "init_float16", "__esmMin", "init_bit_utils", "f", "i", "s", "e", "m", "t", "b", "floatUint32Data", "iMax", "y", "other", "float16", "bits", "n", "xI", "BitUtils", "d", "convertFormatValue", "value", "from", "to", "FormatMaxValue", "MathUtils", "LibError", "Format", "FormatSize", "init_format", "__esmMin", "init_math_utils", "init_lib_error", "ColorFloat32", "init_color_float32", "__esmMin", "init_array_utils", "init_channel", "init_color_utils", "init_format", "i", "r", "g", "b", "a", "v", "ColorUtils", "data", "other", "c", "color", "channel", "index", "value", "nc", "ArrayUtils", "opt", "ColorFloat64", "init_color_float64", "__esmMin", "init_array_utils", "init_channel", "init_color_utils", "init_format", "i", "r", "g", "b", "a", "v", "ColorUtils", "data", "other", "c", "color", "channel", "index", "value", "nc", "ArrayUtils", "opt", "ColorInt16", "init_color_int16", "__esmMin", "init_array_utils", "init_channel", "init_color_utils", "init_format", "i", "r", "g", "b", "a", "v", "ColorUtils", "data", "other", "c", "color", "channel", "index", "value", "nc", "ArrayUtils", "opt", "ColorInt32", "init_color_int32", "__esmMin", "init_array_utils", "init_channel", "init_color_utils", "init_format", "i", "r", "g", "b", "a", "v", "ColorUtils", "data", "other", "c", "color", "channel", "index", "value", "nc", "ArrayUtils", "opt", "ColorInt8", "init_color_int8", "__esmMin", "init_array_utils", "init_channel", "init_color_utils", "init_format", "i", "r", "g", "b", "a", "v", "ColorUtils", "data", "other", "c", "color", "channel", "index", "value", "nc", "ArrayUtils", "opt", "ColorUint1", "init_color_uint1", "__esmMin", "init_array_utils", "init_color_utils", "init_format", "i", "r", "g", "b", "a", "v", "ColorUtils", "data", "other", "c", "color", "channel", "index", "value", "_index", "ArrayUtils", "opt", "ColorUint16", "init_color_uint16", "__esmMin", "init_array_utils", "init_channel", "init_color_utils", "init_format", "i", "r", "g", "b", "a", "v", "ColorUtils", "data", "other", "c", "color", "channel", "index", "value", "nc", "ArrayUtils", "opt", "ColorUint2", "init_color_uint2", "__esmMin", "init_array_utils", "init_color_utils", "init_format", "i", "r", "g", "b", "a", "v", "ColorUtils", "data", "other", "c", "color", "channel", "index", "value", "mask", "x", "ArrayUtils", "opt", "ColorUint32", "init_color_uint32", "__esmMin", "init_array_utils", "init_channel", "init_color_utils", "init_format", "i", "r", "g", "b", "a", "v", "ColorUtils", "data", "other", "c", "color", "channel", "index", "value", "nc", "ArrayUtils", "opt", "ColorUint4", "init_color_uint4", "__esmMin", "init_array_utils", "init_math_utils", "init_color_utils", "init_format", "i", "r", "g", "b", "a", "v", "ColorUtils", "data", "other", "c", "color", "channel", "index", "value", "_index", "vi", "MathUtils", "ArrayUtils", "opt", "ColorUint8", "init_color_uint8", "__esmMin", "init_array_utils", "init_channel", "init_color_utils", "init_format", "i", "r", "g", "b", "a", "v", "ColorUtils", "data", "other", "c", "color", "channel", "defValue", "index", "value", "nc", "ArrayUtils", "opt", "ColorUtils", "init_color_utils", "__esmMin", "init_math_utils", "init_lib_error", "init_color_float16", "init_color_float32", "init_color_float64", "init_color_int16", "init_color_int32", "init_color_int8", "init_color_uint1", "init_color_uint16", "init_color_uint2", "init_color_uint32", "init_color_uint4", "init_color_uint8", "init_format", "c", "c2", "a", "_a", "_b", "numChannels", "format", "fromFormat", "cl", "g", "convertFormatValue", "ci", "v", "r", "b", "MathUtils", "opt", "_c", "_d", "_e", "_f", "_g", "_h", "_i", "_j", "_k", "_l", "_m", "_n", "_o", "_p", "_q", "_r", "_s", "_t", "_u", "alpha", "ColorUint8", "ColorUint1", "ColorUint2", "ColorUint4", "ColorUint16", "ColorUint32", "ColorInt8", "ColorInt16", "ColorInt32", "ColorFloat16", "ColorFloat32", "ColorFloat64", "LibError", "hue", "saturation", "lightness", "gray", "hue2rgb", "p", "q", "t", "brightness", "h", "f", "mx", "mn", "l", "d", "s", "y", "x", "z", "_x", "_y", "_z", "m", "k", "y3", "x3", "z3", "R", "G", "B", "ColorFloat16", "init_color_float16", "__esmMin", "init_array_utils", "init_float16", "init_channel", "init_color_utils", "init_format", "i", "r", "g", "b", "a", "v", "ColorUtils", "data", "other", "c", "color", "l", "Float16", "channel", "index", "value", "nc", "ArrayUtils", "opt", "ColorRgb8", "init_color_rgb8", "__esmMin", "init_color_uint8", "ColorUint8", "r", "g", "b", "data", "other", "ColorRgba8", "init_color_rgba8", "__esmMin", "init_color_uint8", "ColorUint8", "r", "g", "b", "a", "data", "other", "init_color", "__esmMin", "_Crc32", "Crc32", "init_crc32", "__esmMin", "table", "c", "k", "opt", "_a", "_b", "_c", "len", "pos", "end", "result", "i", "StringUtils", "init_string_utils", "__esmMin", "init_lib_error", "str", "array", "i", "codePoint", "LibError", "InputBuffer", "init_input_buffer", "__esmMin", "init_lib_error", "init_bit_utils", "init_string_utils", "v", "opt", "_a", "_b", "other", "offset", "length", "offsetFromOther", "result", "index", "value", "start", "count", "position", "pos", "end", "BitUtils", "bytes", "codes", "c", "LibError", "array", "StringUtils", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "correctedOffset", "correctedLength", "init_interpolation", "__esmMin", "Line", "init_line", "__esmMin", "x1", "y1", "x2", "y2", "other", "x", "y", "tmp", "_OutputBuffer", "OutputBuffer", "init_output_buffer", "__esmMin", "init_array_utils", "v", "opt", "_a", "_b", "required", "blockSize", "newBuffer", "ArrayUtils", "value", "bytes", "length", "bytesLength", "requiredLength", "fb", "b", "start", "end", "correctedStart", "correctedEnd", "Point", "init_point", "__esmMin", "x", "y", "other", "dx", "dy", "n", "p", "RandomUtils", "init_random_utils", "__esmMin", "x1", "w", "x2", "z", "k", "y", "s", "max", "Rectangle", "init_rectangle", "__esmMin", "init_point", "Point", "x1", "y1", "x2", "y2", "x", "y", "width", "height", "other", "init_typings", "__esmMin", "init_blend_mode", "__esmMin", "init_circle_quadrant", "__esmMin", "ImageUtils", "init_image_utils", "__esmMin", "init_point", "p", "center", "rad2", "antialias", "total", "dx1", "dy1", "r1", "dx2", "dy2", "r2", "dx3", "dy3", "r3", "dx4", "dy4", "r4", "dx5", "dy5", "r5", "dx6", "dy6", "r6", "dx7", "dy7", "r7", "dx8", "dy8", "r8", "dx9", "dy9", "r9", "rect", "line", "xmin", "ymin", "xmax", "ymax", "inside", "left", "right", "bottom", "top", "computeOutCode", "code", "outcode1", "Point", "outcode2", "accept", "outcodeOut", "x", "y", "Draw", "init_draw", "__esmMin", "init_channel", "init_color_utils", "init_array_utils", "init_line", "init_math_utils", "init_point", "init_rectangle", "init_image_utils", "init_blend_mode", "init_circle_quadrant", "image", "center", "radius", "points", "Point", "f", "ddFx", "ddFy", "x", "y", "x1", "x2", "y1", "y2", "x3", "x4", "y3", "y4", "opt", "_a", "_b", "drawPixel4", "dx", "dy", "alpha", "quadrants", "maskChannel", "radiusSqr", "quarter", "i", "j", "frc", "MathUtils", "frc2", "flr", "line", "steep", "gradient", "xend", "yend", "xgap", "xpxl1", "ypxl1", "intery", "xpxl2", "ypxl2", "c", "a", "c1", "c2", "compareAlpha", "d1", "d2", "d3", "dA", "src", "refColor", "threshold", "pixel", "pixelColor", "ColorUtils", "array", "mark", "visited", "_x", "_y", "lastRowLength", "rowLength", "sx", "end", "ux", "ox", "oy", "dst", "dstX", "dstY", "dstW", "dstH", "xCache", "yCache", "mask", "p", "sy", "m", "dp", "blend", "linearBlend", "antialias", "pt", "range", "it", "ImageUtils", "_c", "thickness", "Rectangle", "xor", "n", "ac", "wid", "d", "incr1", "incr2", "ydirflag", "wstart", "as", "xdirflag", "Line", "ag", "inc", "frac", "w", "_d", "_e", "_f", "msk", "overlayR", "overlayG", "overlayB", "overlayA", "baseR", "baseG", "baseB", "baseA", "baseOverlayAlphaProduct", "rightHandProductR", "rightHandProductG", "rightHandProductB", "firstBlendColorR", "firstBlendColorG", "firstBlendColorB", "oR", "oG", "oB", "secondBlendColorR", "secondBlendColorG", "secondBlendColorB", "colorChoiceR", "colorChoiceG", "colorChoiceB", "invA", "lbr", "lbg", "lbb", "lor", "log", "lob", "r", "g", "b", "vertices", "numVertices", "rect", "x0", "y0", "rad", "c1x", "c1y", "c2x", "c2y", "c3x", "c3y", "c4x", "c4y", "ht", "dh", "by0", "by1", "bx0", "bx1", "srcColor", "lab", "xMin", "yMin", "xMax", "yMax", "first", "vertex", "inter", "ArrayUtils", "vi", "yi", "v1", "v2", "temp", "x1f", "x2f", "t", "xx0", "yy0", "xx1", "yy1", "ww", "hh", "rad2", "px", "py", "maskValue", "fillValue", "ret", "_g", "_h", "_i", "_j", "_k", "_l", "srcX", "srcY", "srcW", "srcH", "wdt", "height", "_", "ExifEntry", "init_exif_entry", "__esmMin", "v", "tag", "value", "getIfdValueTypeString", "type", "IfdValueType", "getIfdValueTypeSize", "length", "IfdValueTypeSize", "init_ifd_value_type", "__esmMin", "ExifTag", "ExifTagNameToID", "ExifImageTags", "ExifInteropTags", "ExifGpsTags", "init_exif_tag", "__esmMin", "init_ifd_value_type", "opt", "_a", "IfdValue", "init_ifd_value", "__esmMin", "init_rational", "init_lib_error", "init_ifd_value_type", "getIfdValueTypeSize", "getIfdValueTypeString", "_index", "Rational", "_out", "_v", "_numerator", "_denomitator", "_other", "LibError", "IfdAsciiValue", "init_ifd_ascii_value", "__esmMin", "init_string_utils", "init_ifd_value", "init_ifd_value_type", "IfdValue", "value", "StringUtils", "data", "length", "out", "bytes", "v", "other", "IfdShortValue", "init_ifd_short_value", "__esmMin", "init_ifd_value", "init_ifd_value_type", "init_array_utils", "IfdValue", "value", "data", "length", "array", "i", "index", "out", "l", "v", "other", "ArrayUtils", "IfdRationalValue", "init_ifd_rational_value", "__esmMin", "init_ifd_value", "init_ifd_value_type", "init_rational", "init_array_utils", "IfdValue", "value", "Rational", "data", "length", "array", "i", "r", "other", "index", "out", "v", "numerator", "denomitator", "ArrayUtils", "IfdByteValue", "init_ifd_byte_value", "__esmMin", "init_ifd_value", "init_ifd_value_type", "init_array_utils", "IfdValue", "value", "data", "offset", "length", "array", "index", "out", "v", "other", "ArrayUtils", "IfdLongValue", "init_ifd_long_value", "__esmMin", "init_ifd_value", "init_ifd_value_type", "init_array_utils", "IfdValue", "value", "data", "length", "array", "i", "index", "out", "l", "v", "other", "ArrayUtils", "IfdSByteValue", "init_ifd_sbyte_value", "__esmMin", "init_ifd_value", "init_ifd_value_type", "init_array_utils", "IfdValue", "value", "data", "offset", "length", "array", "index", "out", "v", "other", "ArrayUtils", "IfdUndefinedValue", "init_ifd_undefined_value", "__esmMin", "init_ifd_value", "init_ifd_value_type", "init_array_utils", "IfdValue", "value", "data", "offset", "length", "array", "out", "other", "ArrayUtils", "IfdSShortValue", "init_ifd_sshort_value", "__esmMin", "init_ifd_value", "init_ifd_value_type", "init_array_utils", "IfdValue", "value", "data", "length", "array", "i", "index", "out", "v", "vb", "l", "other", "ArrayUtils", "IfdSLongValue", "init_ifd_slong_value", "__esmMin", "init_ifd_value", "init_ifd_value_type", "init_bit_utils", "init_array_utils", "IfdValue", "value", "data", "length", "array", "i", "index", "out", "l", "BitUtils", "v", "other", "ArrayUtils", "IfdSRationalValue", "init_ifd_srational_value", "__esmMin", "init_ifd_value", "init_ifd_value_type", "init_bit_utils", "init_rational", "init_array_utils", "IfdValue", "value", "Rational", "data", "length", "array", "i", "r", "other", "index", "out", "v", "BitUtils", "numerator", "denomitator", "ArrayUtils", "IfdSingleValue", "init_ifd_single_value", "__esmMin", "init_ifd_value", "init_ifd_value_type", "init_array_utils", "IfdValue", "value", "data", "length", "array", "i", "index", "out", "l", "v", "other", "ArrayUtils", "IfdDoubleValue", "init_ifd_double_value", "__esmMin", "init_ifd_value", "init_ifd_value_type", "init_array_utils", "IfdValue", "value", "data", "length", "array", "i", "index", "out", "l", "v", "other", "ArrayUtils", "IfdDirectory", "init_ifd_directory", "__esmMin", "init_rational", "init_exif_tag", "init_ifd_value_type", "init_ifd_container", "init_ifd_value", "init_ifd_ascii_value", "init_ifd_short_value", "init_ifd_rational_value", "init_ifd_byte_value", "init_ifd_long_value", "init_ifd_sbyte_value", "init_ifd_undefined_value", "init_ifd_sshort_value", "init_ifd_slong_value", "init_ifd_srational_value", "init_ifd_single_value", "init_ifd_double_value", "init_string_utils", "init_array_utils", "data", "IfdContainer", "_a", "StringUtils", "v", "codeUnits", "IfdUndefinedValue", "IfdAsciiValue", "IfdShortValue", "dataOffset", "value", "dataSize", "subName", "subIfd", "subSize", "tag", "Rational", "IfdRationalValue", "ArrayUtils", "r", "other", "_tag", "ExifTagNameToID", "IfdValue", "tagInfo", "ExifImageTags", "IfdByteValue", "IfdLongValue", "IfdSByteValue", "IfdSShortValue", "IfdSLongValue", "IfdSRationalValue", "IfdSingleValue", "IfdDoubleValue", "IfdContainer", "init_ifd_container", "__esmMin", "init_ifd_directory", "ifd", "directories", "other", "dirs", "key", "ifdName", "IfdDirectory", "value", "ExifData", "init_exif_data", "__esmMin", "init_exif_entry", "init_exif_tag", "init_ifd_container", "init_ifd_directory", "init_ifd_value_type", "init_ifd_ascii_value", "init_ifd_byte_value", "init_ifd_double_value", "init_ifd_long_value", "init_ifd_rational_value", "init_ifd_sbyte_value", "init_ifd_short_value", "init_ifd_single_value", "init_ifd_slong_value", "init_ifd_srational_value", "init_ifd_sshort_value", "init_ifd_undefined_value", "IfdContainer", "_a", "_b", "out", "ifd", "dataOffset", "offset", "stripOffsetTag", "ExifTagNameToID", "tag", "value", "tagType", "tagLength", "size", "block", "blockOffset", "format", "count", "entry", "ExifEntry", "IfdValueType", "f", "fsize", "IfdValueTypeSize", "endOffset", "fieldOffset", "data", "IfdSByteValue", "IfdByteValue", "IfdUndefinedValue", "IfdAsciiValue", "IfdShortValue", "IfdLongValue", "IfdRationalValue", "IfdSRationalValue", "IfdSShortValue", "IfdSLongValue", "IfdSingleValue", "IfdDoubleValue", "other", "dirs", "input", "directory", "ExifImageTags", "saveEndian", "IfdDirectory", "offsets", "name", "dataSize", "subName", "subIfd", "subSize", "dirArray", "i", "nextName", "endian", "ifdOffset", "index", "numEntries", "dir", "subTags", "d", "dt", "s", "subDirectory", "DitherKernels", "init_dither_kernel", "__esmMin", "init_frame_type", "__esmMin", "PixelFloat16", "init_pixel_float16", "__esmMin", "init_channel", "init_color_utils", "init_format", "init_array_utils", "init_float16", "init_image_data_float16", "i", "Float16", "r", "g", "b", "a", "v", "ColorUtils", "x", "y", "index", "image", "MemoryImageDataFloat16", "other", "channel", "value", "color", "ArrayUtils", "opt", "PixelRangeIterator", "init_pixel_range_iterator", "__esmMin", "pixel", "x", "y", "width", "height", "MemoryImageDataFloat16", "init_image_data_float16", "__esmMin", "init_channel_order", "init_format", "init_pixel_float16", "init_pixel_range_iterator", "init_color_float16", "init_float16", "PixelFloat16", "width", "height", "numChannels", "data", "other", "skipPixels", "x", "y", "PixelRangeIterator", "r", "g", "b", "a", "ColorFloat16", "pixel", "p", "index", "Float16", "_c", "order", "tempImage", "PixelFloat32", "init_pixel_float32", "__esmMin", "init_channel", "init_color_utils", "init_format", "init_array_utils", "init_image_data_float32", "i", "r", "g", "b", "a", "v", "ColorUtils", "x", "y", "index", "image", "MemoryImageDataFloat32", "other", "channel", "value", "color", "ArrayUtils", "opt", "MemoryImageDataFloat32", "init_image_data_float32", "__esmMin", "init_channel_order", "init_format", "init_pixel_float32", "init_pixel_range_iterator", "init_color_float32", "PixelFloat32", "width", "height", "numChannels", "data", "other", "skipPixels", "x", "y", "PixelRangeIterator", "r", "g", "b", "a", "ColorFloat32", "pixel", "p", "index", "_c", "order", "tempImage", "PixelFloat64", "init_pixel_float64", "__esmMin", "init_channel", "init_color_utils", "init_format", "init_array_utils", "init_image_data_float64", "i", "r", "g", "b", "a", "v", "ColorUtils", "x", "y", "index", "image", "MemoryImageDataFloat64", "other", "channel", "value", "color", "ArrayUtils", "opt", "MemoryImageDataFloat64", "init_image_data_float64", "__esmMin", "init_channel_order", "init_format", "init_pixel_float64", "init_pixel_range_iterator", "init_color_float64", "PixelFloat64", "width", "height", "numChannels", "data", "other", "skipPixels", "x", "y", "PixelRangeIterator", "r", "g", "b", "a", "ColorFloat64", "pixel", "p", "index", "_c", "order", "tempImage", "PixelInt16", "init_pixel_int16", "__esmMin", "init_channel", "init_color_utils", "init_format", "init_array_utils", "init_image_data_int16", "i", "r", "g", "b", "a", "v", "ColorUtils", "x", "y", "index", "image", "MemoryImageDataInt16", "other", "channel", "value", "color", "ArrayUtils", "opt", "MemoryImageDataInt16", "init_image_data_int16", "__esmMin", "init_channel_order", "init_color_int16", "init_format", "init_pixel_int16", "init_pixel_range_iterator", "PixelInt16", "width", "height", "numChannels", "data", "other", "skipPixels", "x", "y", "PixelRangeIterator", "r", "g", "b", "a", "ColorInt16", "pixel", "p", "index", "_c", "order", "tempImage", "PixelInt32", "init_pixel_int32", "__esmMin", "init_channel", "init_color_utils", "init_format", "init_array_utils", "init_image_data_int32", "i", "r", "g", "b", "a", "v", "ColorUtils", "x", "y", "index", "image", "MemoryImageDataInt32", "other", "channel", "value", "color", "ArrayUtils", "opt", "MemoryImageDataInt32", "init_image_data_int32", "__esmMin", "init_channel_order", "init_color_int32", "init_format", "init_pixel_int32", "init_pixel_range_iterator", "PixelInt32", "width", "height", "numChannels", "data", "other", "skipPixels", "x", "y", "PixelRangeIterator", "r", "g", "b", "a", "ColorInt32", "pixel", "p", "index", "_c", "order", "tempImage", "PixelInt8", "init_pixel_int8", "__esmMin", "init_channel", "init_color_utils", "init_format", "init_array_utils", "init_image_data_int8", "i", "r", "g", "b", "a", "v", "ColorUtils", "x", "y", "index", "image", "MemoryImageDataInt8", "other", "channel", "value", "color", "ArrayUtils", "opt", "MemoryImageDataInt8", "init_image_data_int8", "__esmMin", "init_channel_order", "init_color_int8", "init_format", "init_pixel_int8", "init_pixel_range_iterator", "PixelInt8", "width", "height", "numChannels", "data", "other", "skipPixels", "x", "y", "PixelRangeIterator", "r", "g", "b", "a", "ColorInt8", "pixel", "p", "index", "_c", "order", "tempImage", "PixelUint1", "init_pixel_uint1", "__esmMin", "init_channel", "init_color_utils", "init_format", "init_array_utils", "init_math_utils", "init_image_data_uint1", "i", "_a", "_b", "r", "g", "b", "a", "v", "ColorUtils", "x", "y", "index", "bitIndex", "rowOffset", "image", "MemoryImageDataUint1", "other", "channel", "bi", "nc", "bpp", "value", "vi", "MathUtils", "mask", "color", "ArrayUtils", "opt", "MemoryImageDataUint1", "init_image_data_uint1", "__esmMin", "init_channel_order", "init_format", "init_pixel_uint1", "init_pixel_range_iterator", "init_color_uint1", "PixelUint1", "_a", "_b", "width", "height", "numChannels", "data", "palette", "rowStride", "d", "other", "skipPixels", "x", "y", "PixelRangeIterator", "r", "g", "b", "a", "ColorUint1", "pixel", "p", "_c", "order", "tempImage", "PixelUint16", "init_pixel_uint16", "__esmMin", "init_channel", "init_color_utils", "init_format", "init_array_utils", "init_image_data_uint16", "i", "r", "g", "b", "a", "v", "ColorUtils", "x", "y", "index", "image", "MemoryImageDataUint16", "other", "channel", "value", "color", "ArrayUtils", "opt", "MemoryImageDataUint16", "init_image_data_uint16", "__esmMin", "init_channel_order", "init_format", "init_pixel_uint16", "init_pixel_range_iterator", "init_color_uint16", "PixelUint16", "width", "height", "numChannels", "data", "other", "skipPixels", "x", "y", "PixelRangeIterator", "r", "g", "b", "a", "ColorUint16", "pixel", "p", "index", "_c", "order", "tempImage", "PixelUint2", "init_pixel_uint2", "__esmMin", "init_channel", "init_color_utils", "init_format", "init_array_utils", "init_math_utils", "init_image_data_uint2", "i", "_a", "_b", "r", "g", "b", "a", "v", "ColorUtils", "x", "y", "index", "bitIndex", "rowOffset", "image", "MemoryImageDataUint2", "other", "channel", "bi", "nc", "bpp", "value", "vi", "MathUtils", "mask", "color", "ArrayUtils", "opt", "MemoryImageDataUint2", "init_image_data_uint2", "__esmMin", "init_channel_order", "init_format", "init_pixel_uint2", "init_pixel_range_iterator", "init_color_uint2", "PixelUint2", "_a", "_b", "width", "height", "numChannels", "data", "palette", "rowStride", "d", "other", "skipPixels", "x", "y", "PixelRangeIterator", "r", "g", "b", "a", "ColorUint2", "pixel", "p", "_c", "order", "tempImage", "PixelUint32", "init_pixel_uint32", "__esmMin", "init_channel", "init_color_utils", "init_format", "init_array_utils", "init_image_data_uint32", "i", "r", "g", "b", "a", "v", "ColorUtils", "x", "y", "index", "image", "MemoryImageDataUint32", "other", "channel", "value", "color", "ArrayUtils", "opt", "MemoryImageDataUint32", "init_image_data_uint32", "__esmMin", "init_channel_order", "init_format", "init_pixel_uint32", "init_pixel_range_iterator", "init_color_uint32", "PixelUint32", "width", "height", "numChannels", "data", "other", "skipPixels", "x", "y", "PixelRangeIterator", "r", "g", "b", "a", "ColorUint32", "pixel", "p", "index", "_c", "order", "tempImage", "PixelUint4", "init_pixel_uint4", "__esmMin", "init_channel", "init_color_utils", "init_format", "init_array_utils", "init_math_utils", "init_image_data_uint4", "i", "_a", "_b", "r", "g", "b", "a", "v", "ColorUtils", "x", "y", "index", "bitIndex", "image", "MemoryImageDataUint4", "other", "channel", "bi", "nc", "bpp", "w", "rowStride", "value", "vi", "MathUtils", "color", "ArrayUtils", "opt", "MemoryImageDataUint4", "init_image_data_uint4", "__esmMin", "init_channel_order", "init_format", "init_pixel_uint4", "init_pixel_range_iterator", "init_color_uint4", "PixelUint4", "_a", "_b", "width", "height", "numChannels", "data", "palette", "rowStride", "d", "other", "skipPixels", "x", "y", "PixelRangeIterator", "r", "g", "b", "a", "ColorUint4", "pixel", "p", "_c", "order", "tempImage", "PixelUint8", "init_pixel_uint8", "__esmMin", "init_channel", "init_color_utils", "init_format", "init_array_utils", "init_math_utils", "init_image_data_uint8", "i", "MathUtils", "_a", "_b", "r", "g", "b", "a", "v", "ColorUtils", "x", "y", "index", "image", "MemoryImageDataUint8", "other", "channel", "value", "color", "ArrayUtils", "opt", "MemoryImageDataUint8", "init_image_data_uint8", "__esmMin", "init_channel_order", "init_format", "init_pixel_uint8", "init_pixel_range_iterator", "init_color_rgb8", "init_color_rgba8", "init_math_utils", "PixelUint8", "_a", "_b", "width", "height", "numChannels", "data", "palette", "d", "other", "skipPixels", "x", "y", "PixelRangeIterator", "r", "g", "b", "a", "ColorRgb8", "MathUtils", "ColorRgba8", "pixel", "p", "index", "c", "c8", "ri", "rg", "gi", "bi", "rgba", "order", "tempImage", "PaletteFloat16", "init_palette_float16", "__esmMin", "init_format", "init_float16", "numColors", "numChannels", "data", "other", "index", "r", "g", "b", "_index", "Float16", "a", "channel", "value", "PaletteFloat32", "init_palette_float32", "__esmMin", "init_format", "numColors", "numChannels", "data", "other", "index", "r", "g", "b", "_index", "a", "channel", "value", "PaletteFloat64", "init_palette_float64", "__esmMin", "init_format", "numColors", "numChannels", "data", "other", "index", "r", "g", "b", "_index", "a", "channel", "value", "PaletteInt16", "init_palette_int16", "__esmMin", "init_format", "numColors", "numChannels", "data", "other", "index", "r", "g", "b", "_index", "a", "channel", "value", "PaletteInt32", "init_palette_int32", "__esmMin", "init_format", "numColors", "numChannels", "data", "other", "index", "r", "g", "b", "_index", "a", "channel", "value", "PaletteInt8", "init_palette_int8", "__esmMin", "init_format", "numColors", "numChannels", "data", "other", "index", "r", "g", "b", "_index", "a", "channel", "value", "PaletteUint16", "init_palette_uint16", "__esmMin", "init_format", "numColors", "numChannels", "data", "other", "index", "r", "g", "b", "_index", "a", "channel", "value", "PaletteUint32", "init_palette_uint32", "__esmMin", "init_format", "numColors", "numChannels", "data", "other", "index", "r", "g", "b", "_index", "a", "channel", "value", "PaletteUint8", "init_palette_uint8", "__esmMin", "init_format", "numColors", "numChannels", "data", "other", "index", "r", "g", "b", "_index", "a", "channel", "value", "_PixelUndefined", "PixelUndefined", "init_pixel_undefined", "__esmMin", "init_format", "init_image_data_uint8", "_i", "_r", "_g", "_b", "_a", "_v", "_channel", "_value", "_color", "_options", "_x", "_y", "other", "MemoryImageDataUint8", "UndefinedPixel", "init_pixel", "__esmMin", "init_pixel_undefined", "PixelUndefined", "MemoryImage", "init_image", "__esmMin", "init_channel_order", "init_color_uint8", "init_color_utils", "init_format", "init_array_utils", "init_interpolation", "init_math_utils", "init_lib_error", "init_exif_data", "init_frame_type", "init_image_data_float16", "init_image_data_float32", "init_image_data_float64", "init_image_data_int16", "init_image_data_int32", "init_image_data_int8", "init_image_data_uint1", "init_image_data_uint16", "init_image_data_uint2", "init_image_data_uint32", "init_image_data_uint4", "init_image_data_uint8", "init_palette_float16", "init_palette_float32", "init_palette_float64", "init_palette_int16", "init_palette_int32", "init_palette_int8", "init_palette_uint16", "init_palette_uint32", "init_palette_uint8", "init_pixel", "opt", "_a", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "ExifData", "exif", "v", "other", "width", "height", "skipAnimation", "image", "numFrames", "fi", "frame", "skipPixels", "_i", "_j", "format", "withPalette", "paletteFormat", "numChannels", "ChannelOrderLength", "LibError", "channelOrder", "toBytes", "fromBytes", "rowStride", "FormatSize", "dataStride", "stride", "dOff", "bOff", "y", "ArrayUtils", "p", "r", "g", "b", "a", "palette", "MemoryImageDataUint1", "MemoryImageDataUint2", "MemoryImageDataUint4", "MemoryImageDataUint8", "MemoryImageDataUint16", "MemoryImageDataUint32", "MemoryImageDataInt8", "MemoryImageDataInt16", "MemoryImageDataInt32", "MemoryImageDataFloat16", "MemoryImageDataFloat32", "MemoryImageDataFloat64", "PaletteUint8", "PaletteUint16", "PaletteUint32", "PaletteInt8", "PaletteInt16", "PaletteInt32", "PaletteFloat16", "PaletteFloat32", "PaletteFloat64", "img", "index", "name", "data", "x", "order", "ColorUint8", "pixel", "UndefinedPixel", "_x", "MathUtils", "_y", "fx", "fy", "interpolation", "nx", "ny", "dx", "dy", "linear", "icc", "inc", "icn", "inn", "px", "ax", "py", "ay", "cubic", "ipp", "icp", "inp", "iap", "ip0", "ip1", "ip2", "ip3", "ipc", "iac", "ic0", "ic1", "ic2", "ic3", "ipn", "ian", "in0", "in1", "in2", "in3", "ipa", "ica", "ina", "iaa", "ia0", "ia1", "ia2", "ia3", "c0", "c1", "c2", "c3", "c", "i", "color", "alpha", "FormatMaxValue", "firstFrame", "newImage", "pal", "f", "usedColors", "numColors", "op", "np", "nr", "ng", "nb", "h", "ColorUtils", "key", "value", "first", "min", "max", "Format", "_NeuralQuantizer", "NeuralQuantizer", "init_neural_quantizer", "__esmMin", "init_color_rgb8", "init_color_rgba8", "init_math_utils", "init_image", "init_palette_uint32", "init_palette_uint8", "image", "numberOfColors", "samplingFactor", "PaletteUint32", "PaletteUint8", "f", "i", "p", "rad", "alpha", "b", "g", "r", "bestD", "bestBiasDist", "bestPos", "bestBiasPos", "dist", "a", "biasDist", "_", "lo", "hi", "j", "k", "biasRadius", "alphaDec", "lengthCount", "samplePixels", "delta", "step", "pos", "w", "h", "x", "y", "red", "green", "blue", "MathUtils", "previousColor", "startPos", "smallPos", "smallVal", "q", "best", "c", "out", "ColorRgba8", "ColorRgb8", "target", "MemoryImage", "imageIt", "targetIt", "imageItRes", "targetItRes", "HeapNode", "init_heap_node", "__esmMin", "OctreeNode", "init_octree_node", "__esmMin", "init_array_utils", "childIndex", "depth", "parent", "ArrayUtils", "v", "_OctreeQuantizer", "OctreeQuantizer", "init_octree_quantizer", "__esmMin", "init_color_rgb8", "init_heap_node", "init_image", "init_octree_node", "init_palette_uint8", "image", "numberOfColors", "OctreeNode", "heap", "HeapNode", "p", "r", "g", "b", "nc", "i", "got", "c", "nodes", "PaletteUint8", "l", "n", "root", "_root", "depth", "bit", "h", "ret", "m", "prev", "q", "a", "ac", "bc", "node", "_a", "ColorRgb8", "target", "MemoryImage", "imageIt", "targetIt", "imageItRes", "targetItRes", "init_noise_type", "__esmMin", "init_pixelate_mode", "__esmMin", "init_quantize_method", "__esmMin", "SeparableKernel", "init_separable_kernel", "__esmMin", "init_channel", "init_array_utils", "init_math_utils", "size", "ArrayUtils", "max", "x", "src", "dst", "y", "width", "horizontal", "maskChannel", "mask", "r", "g", "b", "a", "j", "j2", "c", "gr", "sc", "p", "msk", "MathUtils", "index", "opt", "_a", "_b", "s", "i", "_Filter", "Filter", "init_filter", "__esmMin", "init_channel", "init_color_rgba8", "init_interpolation", "init_math_utils", "init_neural_quantizer", "init_octree_quantizer", "init_random_utils", "init_draw", "init_image", "init_dither_kernel", "init_noise_type", "init_pixelate_mode", "init_quantize_method", "init_separable_kernel", "init_color_utils", "opt", "_a", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "_i", "_j", "_k", "_l", "_m", "_n", "_o", "_p", "_q", "_r", "_s", "_t", "_u", "_v", "maskChannel", "contrast", "MathUtils", "saturation", "brightness", "gamma", "exposure", "amount", "hue", "degToRad", "avgLumR", "avgLumG", "avgLumB", "lumCoeffR", "lumCoeffG", "lumCoeffB", "useBlacksWhitesMids", "br", "bg", "bb", "wr", "wg", "wb", "mr", "mg", "mb", "invSaturation", "invContrast", "hueR", "hueG", "hueB", "s", "c", "frame", "p", "or", "og", "ob", "r", "g", "b", "tb", "lum", "hr", "hg", "hb", "blend", "grid", "rs", "w", "h", "aspect", "stepX", "stepY", "orig", "uvX", "uvY", "offX", "offY", "x2", "y2", "op", "prcX", "prcY", "pwX", "pwY", "gr", "y", "ls", "lb", "lf", "msk", "mx", "luminanceR", "luminanceG", "luminanceB", "lr", "lg", "l", "mixAmount", "branch1R", "branch1G", "branch1B", "branch2R", "branch2G", "branch2B", "nr", "ng", "nb", "scale", "interpolation", "cx", "cy", "rad", "radSqr", "x", "deltaX", "deltaY", "dist", "percent", "percentSqr", "p2", "strength", "dest", "MemoryImage", "height", "du", "dv", "z", "dw", "nX", "nY", "nZ", "shift", "shiftLeft", "shiftRight", "lc", "rc", "angle", "size", "pattern", "tx", "ty", "px", "py", "cmyC", "cmyM", "cmyY", "cmyK", "red", "green", "blue", "alpha", "i", "div", "offset", "tmp", "tmpFrame", "j", "fi", "yv", "xv", "c2", "scaled", "dx", "dy", "fromPixel", "a", "quantizer", "NeuralQuantizer", "kernel", "serpentine", "ds", "DitherKernels", "width", "direction", "palette", "indexedImage", "pIter", "itRes", "index", "x0", "x1", "pc", "r1", "g1", "b1", "idx", "r2", "g2", "b2", "er", "eg", "eb", "i0", "i1", "y1", "d", "cntX", "cntY", "texX", "texY", "pointX", "pointY", "average", "pat", "blur", "shadowColor", "ColorRgba8", "shadowWidth", "shadowHeight", "shadowOffsetX", "shadowOffsetY", "newImageWidth", "newImageHeight", "imageOffsetX", "imageOffsetY", "dst", "Draw", "ny", "nx", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "xxR", "xxG", "xxB", "yyR", "yyG", "yyB", "rrR", "rrG", "rrB", "filter", "sigma", "SeparableKernel", "sum", "numColors", "ColorUtils", "knee", "f", "m", "image", "nc", "hp", "ri", "gi", "bi", "mi", "ax", "ay", "bx", "by", "tex2X", "tex2Y", "tex2Z", "a2x", "a2y", "a2z", "b2x", "b2y", "b2z", "c2x", "c2y", "c2z", "aLen", "bLen", "cLen", "choiceX", "choiceY", "newColor", "max", "threshold", "outputColor", "sl", "type", "nSigma", "min", "extremes", "RandomUtils", "sqrt2", "val0", "re", "im", "val", "mn", "fm", "fM", "xr", "xg", "xb", "xa", "mode", "lx", "ly", "by2", "bx2", "total", "numberOfColors", "method", "dither", "ditherSerpentine", "OctreeQuantizer", "yw", "ywa", "invY2", "dr", "dg", "db", "da", "bottomLeft", "topLeft", "bottomRight", "topRight", "left", "right", "bottom", "top", "v", "mag", "invMx", "nCntX", "nCntY", "ncX", "ncY", "sX", "sY", "start", "end", "cr", "cg", "cb", "ca", "_BmpFileHeader", "BmpFileHeader", "init_bmp_file_header", "__esmMin", "init_input_buffer", "init_lib_error", "v", "b", "LibError", "InputBuffer", "init_bmp_compression_mode", "__esmMin", "init_bmp_info", "__esmMin", "init_bit_utils", "init_lib_error", "init_palette_uint8", "init_bmp_compression_mode", "init_bmp_file_header", "init_bmp_decoder", "__esmMin", "init_format", "init_input_buffer", "init_image", "init_bmp_file_header", "init_bmp_info", "init_bmp_encoder", "__esmMin", "init_format", "init_output_buffer", "init_palette_uint8", "init_bmp_compression_mode", "init_bmp_file_header", "init_decode_info", "__esmMin", "init_decoder", "__esmMin", "init_dib_decoder", "__esmMin", "init_bmp_decoder", "init_encoder", "__esmMin", "GifColorMap", "init_gif_color_map", "__esmMin", "init_color_uint8", "init_palette_uint8", "v", "numColors", "palette", "PaletteUint8", "n", "i", "other", "r", "index", "g", "b", "a", "ColorUint8", "color", "p", "l", "GifImageDesc", "init_gif_image_desc", "__esmMin", "init_gif_color_map", "input", "b", "bitsPerPixel", "GifColorMap", "v", "GifInfo", "init_gif_info", "__esmMin", "opt", "_a", "_b", "_c", "_d", "_e", "_GifDecoder", "GifDecoder", "init_gif_decoder", "__esmMin", "init_input_buffer", "init_array_utils", "init_gif_color_map", "init_gif_image_desc", "init_gif_info", "init_image", "init_color_uint8", "bytes", "prefix", "code", "clearCode", "c", "i", "image", "y", "colorMap", "line", "width", "x", "tag", "height", "b", "colorResolution", "bitsPerPixel", "backgroundColor", "ColorUint8", "globalColorMap", "GifColorMap", "r", "g", "isGif89", "GifInfo", "gifImage", "GifImageDesc", "input", "blockSize", "b1", "b2", "duration", "transparent", "disposalMethod", "transparentFlag", "lineLen", "currentPrefix", "j", "prefixChar", "nextByte", "from", "ArrayUtils", "MemoryImage", "row", "InputBuffer", "extCode", "error", "frame", "firstImage", "lastImage", "p", "init_quantizer_type", "__esmMin", "_GifEncoder", "GifEncoder", "init_gif_encoder", "__esmMin", "init_neural_quantizer", "init_output_buffer", "init_string_utils", "init_quantizer_type", "init_octree_quantizer", "init_filter", "init_lib_error", "init_dither_kernel", "opt", "_a", "_b", "_c", "_d", "_e", "image", "width", "height", "LibError", "palette", "numColors", "out", "paletteBytes", "numChannels", "i", "pi", "g", "initCodeSize", "hTab", "codeTab", "pIter", "pIterRes", "pFinished", "nextPixel", "r", "ent", "hShift", "fCode", "hSizeReg", "outerLoop", "c", "fcode", "disp", "code", "appCodeUnits", "StringUtils", "transparentIndex", "hasTransparency", "nc", "pa", "p", "l", "fields", "idCodeUnits", "bytes", "duration", "OutputBuffer", "NeuralQuantizer", "OctreeQuantizer", "Filter", "singleFrame", "f", "init_ico_bmp_info", "__esmMin", "init_bmp_info", "init_ico_info_image", "__esmMin", "init_ico_type", "__esmMin", "init_ico_info", "__esmMin", "init_array_utils", "init_ico_info_image", "init_ico_type", "init_png_filter_type", "__esmMin", "init_png_color_type", "__esmMin", "import_uzip", "init_png_encoder", "__esmMin", "init_crc32", "init_output_buffer", "init_string_utils", "init_png_filter_type", "init_format", "init_neural_quantizer", "init_png_color_type", "init_win_encoder", "__esmMin", "init_output_buffer", "init_lib_error", "init_png_encoder", "init_ico_encoder", "__esmMin", "init_win_encoder", "JpegComponentData", "init_jpeg_component_data", "__esmMin", "hSamples", "maxHSamples", "vSamples", "maxVSamples", "lines", "JpegAdobe", "init_jpeg_adobe", "__esmMin", "version", "flags0", "flags1", "transformCode", "JpegComponent", "init_jpeg_component", "__esmMin", "hSamples", "vSamples", "quantizationTableList", "quantizationIndex", "v", "blocks", "blocksPerLine", "blocksPerColumn", "JpegFrame", "init_jpeg_frame", "__esmMin", "init_array_utils", "components", "componentsOrder", "extended", "progressive", "precision", "scanLines", "samplesPerLine", "_", "component", "blocksPerLine", "blocksPerColumn", "blocksPerLineForMcu", "blocksPerColumnForMcu", "blocks", "ArrayUtils", "JpegHuffman", "init_jpeg_huffman", "__esmMin", "JpegInfo", "init_jpeg_info", "__esmMin", "width", "height", "JpegJfif", "init_jpeg_jfif", "__esmMin", "thumbWidth", "thumbHeight", "majorVersion", "minorVersion", "densityUnits", "xDensity", "yDensity", "thumbData", "_JpegQuantize", "JpegQuantize", "init_jpeg_quantize", "__esmMin", "init_math_utils", "init_lib_error", "init_exif_data", "init_image", "result", "i", "quantizationTable", "coefBlock", "dataOut", "dataIn", "p", "cos1", "sin1", "cos3", "sin3", "cos6", "sin6", "sqrt2", "sqrt102", "row", "t", "v0", "v1", "v2", "v3", "v4", "v7", "v5", "v6", "col", "jpeg", "orientation", "w", "h", "flipWidthHeight", "width", "height", "image", "MemoryImage", "ExifData", "component1", "component2", "component3", "component4", "component1Line", "component2Line", "component3Line", "component4Line", "colorTransform", "h1", "w1", "lines", "hShift1", "vShift1", "y", "y1", "x", "x1", "cy", "lines1", "lines2", "lines3", "hShift2", "vShift2", "hShift3", "vShift3", "y2", "y3", "x2", "x3", "cb", "cr", "r", "g", "b", "MathUtils", "LibError", "lines4", "hShift4", "vShift4", "y4", "x4", "cc", "cm", "ck", "HuffmanNode", "init_huffman_node", "__esmMin", "HuffmanParent", "init_huffman_parent", "__esmMin", "init_huffman_node", "HuffmanNode", "children", "HuffmanValue", "init_huffman_value", "__esmMin", "init_huffman_node", "HuffmanNode", "value", "init_jpeg_marker", "__esmMin", "JpegScan", "init_jpeg_scan", "__esmMin", "init_lib_error", "init_huffman_parent", "init_huffman_value", "init_jpeg_data", "init_jpeg_marker", "input", "frame", "components", "spectralStart", "spectralEnd", "successivePrev", "successive", "resetInterval", "nextByte", "marker", "LibError", "tree", "node", "HuffmanParent", "bit", "HuffmanValue", "length", "n", "len", "component", "zz", "t", "diff", "k", "rs", "r", "z", "JpegData", "_", "e", "s", "decodeFn", "mcu", "row", "col", "mcuRow", "mcuCol", "blockRow", "blockCol", "numCols", "componentsLength", "mcuExpected", "h", "v", "i", "j", "m1", "m2", "_JpegData", "JpegData", "init_jpeg_data", "__esmMin", "init_input_buffer", "init_lib_error", "init_jpeg_component_data", "init_jpeg_adobe", "init_jpeg_component", "init_jpeg_frame", "init_jpeg_huffman", "init_jpeg_info", "init_jpeg_jfif", "init_jpeg_quantize", "init_jpeg_scan", "init_exif_data", "init_array_utils", "init_jpeg_marker", "init_huffman_value", "init_huffman_parent", "ExifData", "ArrayUtils", "marker", "LibError", "block", "length", "bytes", "InputBuffer", "soiCheck", "hasSOF", "hasSOS", "sectionByteSize", "info", "JpegInfo", "i", "component", "JpegComponentData", "JpegQuantize", "codeLengths", "values", "k", "code", "JpegHuffman", "p", "j", "HuffmanValue", "q", "HuffmanParent", "blocksPerLine", "blocksPerColumn", "samplesPerLine", "R", "r", "lines", "l", "blockRow", "scanLine", "blockCol", "offset", "sample", "line", "val", "c", "appData", "majorVersion", "minorVersion", "densityUnits", "xDensity", "yDensity", "thumbWidth", "thumbHeight", "thumbSize", "thumbData", "JpegJfif", "version", "flags0", "flags1", "transformCode", "JpegAdobe", "_", "n", "prec", "tableData", "tmp", "extended", "progressive", "precision", "scanLines", "numComponents", "components", "componentsOrder", "componentId", "x", "h", "v", "qId", "JpegComponent", "JpegFrame", "index", "bits", "count", "huffmanValues", "ht", "id", "dcTableNumber", "acTableNumber", "spectralStart", "spectralEnd", "successiveApproximation", "ah", "al", "JpegScan", "JpegDecoder", "init_jpeg_decoder", "__esmMin", "init_input_buffer", "init_lib_error", "init_jpeg_data", "bytes", "JpegData", "InputBuffer", "_", "jpeg", "LibError", "_frame", "_JpegEncoder", "JpegEncoder", "init_jpeg_encoder", "__esmMin", "init_array_utils", "init_math_utils", "init_output_buffer", "init_jpeg_marker", "quality", "ArrayUtils", "nrcodes", "stdTable", "codeValue", "posInTable", "ht", "k", "j", "index", "fp", "marker", "out", "exif", "exifData", "OutputBuffer", "exifBytes", "exifSignature", "width", "height", "i", "l", "m", "n", "o", "p", "nrLower", "nrUpper", "cat", "nr", "nrneg", "q", "MathUtils", "sf", "yqt", "t", "uvqt", "u", "aasf", "row", "col", "data", "fdtbl", "dataOff", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "tmp0", "tmp7", "tmp1", "tmp6", "tmp2", "tmp5", "tmp3", "tmp4", "tmp10", "tmp13", "tmp11", "tmp12", "z1", "z5", "z2", "z4", "z3", "z11", "z13", "tmp0p2", "tmp7p2", "tmp1p2", "tmp6p2", "tmp2p2", "tmp5p2", "tmp3p2", "tmp4p2", "tmp10p2", "tmp13p2", "tmp11p2", "tmp12p2", "z1p2", "z5p2", "z2p2", "z4p2", "z3p2", "z11p2", "z13p2", "fDCTQuant", "bits", "value", "posval", "cdu", "dc", "htac", "htdc", "eob", "m16Zeroes", "I16", "I63", "I64", "duDct", "_dc", "pos", "diff", "end0pos", "startpos", "nrzeroes", "lng", "nrmarker", "image", "_singleFrame", "dcy", "dcu", "dcv", "y", "x", "yy", "xx", "r", "g", "b", "fillBits", "_JpegUtils", "JpegUtils", "init_jpeg_utils", "__esmMin", "init_input_buffer", "init_output_buffer", "init_exif_data", "init_jpeg_marker", "block", "ExifData", "out", "exif", "exifData", "OutputBuffer", "exifBytes", "input", "length", "output", "c", "data", "InputBuffer", "soiCheck", "marker", "hasExifBlock", "startOffset", "saveOffset", "signature", "init_png_blend_mode", "__esmMin", "init_png_dispose_mode", "__esmMin", "init_png_frame", "__esmMin", "init_png_blend_mode", "init_png_dispose_mode", "init_png_info", "__esmMin", "init_tga_image_type", "__esmMin", "init_tga_info", "__esmMin", "init_tga_image_type", "init_tga_decoder", "__esmMin", "init_input_buffer", "init_image", "init_tga_image_type", "init_tga_info", "init_tga_encoder", "__esmMin", "init_output_buffer", "_TiffBitReader", "TiffBitReader", "init_tiff_bit_reader", "__esmMin", "input", "numBits", "nBits", "value", "init_tiff_compression", "__esmMin", "TiffEntry", "init_tiff_entry", "__esmMin", "init_exif_tag", "init_ifd_value_type", "init_ifd_ascii_value", "init_ifd_byte_value", "init_ifd_double_value", "init_ifd_long_value", "init_ifd_rational_value", "init_ifd_sbyte_value", "init_ifd_single_value", "init_ifd_slong_value", "init_ifd_srational_value", "init_ifd_sshort_value", "IfdValueTypeSize", "opt", "data", "IfdByteValue", "IfdAsciiValue", "IfdSShortValue", "IfdLongValue", "IfdRationalValue", "IfdSingleValue", "IfdDoubleValue", "IfdSByteValue", "IfdSLongValue", "IfdSRationalValue", "exifTag", "ExifImageTags", "_TiffFaxDecoder", "TiffFaxDecoder", "init_tiff_fax_decoder", "__esmMin", "init_lib_error", "opt", "bitsToGet", "b", "next", "next2next", "l", "bp", "LibError", "bitsLeft", "bitsFromNextByte", "bitsFromNext2NextByte", "i1", "i2", "i3", "shift", "bitsToMoveBack", "i", "buffer", "lineOffset", "bitOffset", "numBits", "bitNum", "lastBit", "byteNum", "maskVal", "val", "offset", "bits", "code", "isT", "current", "entry", "twoBits", "isWhite", "n", "a0", "ret", "pce", "ces", "start", "temp", "runLength", "out", "compData", "startX", "height", "scanlineStride", "tiffT4Options", "a1", "currIndex", "lines", "b1", "b2", "number", "tiffT6Options", "cce", "zeros", "exit", "init_tiff_format", "__esmMin", "init_tiff_image_type", "__esmMin", "_LzwDecoder", "LzwDecoder", "init_tiff_lzw_decoder", "__esmMin", "init_lib_error", "string", "newString", "code", "c", "i", "p", "out", "outLen", "LibError", "oldCode", "init_tiff_photometric_type", "__esmMin", "import_uzip", "TiffImage", "init_tiff_image", "__esmMin", "init_color_utils", "init_format", "init_array_utils", "init_bit_utils", "init_float16", "init_input_buffer", "init_lib_error", "init_exif_tag", "init_ifd_value_type", "init_image", "init_jpeg_decoder", "init_tiff_bit_reader", "init_tiff_compression", "init_tiff_entry", "init_tiff_fax_decoder", "init_tiff_format", "init_tiff_image_type", "init_tiff_lzw_decoder", "init_tiff_photometric_type", "p", "_a", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "_i", "_j", "_k", "_l", "_m", "_n", "p3", "InputBuffer", "numDirEntries", "i", "tag", "ti", "type", "typeSize", "IfdValueTypeSize", "count", "valueOffset", "entry", "TiffEntry", "ExifTagNameToID", "v", "pt", "cm", "len", "l", "infinity", "s", "defaultValue", "value", "ArrayUtils", "image", "tileX", "tileY", "tileIndex", "outX", "outY", "byteCount", "byteData", "bytesInThisTile", "LzwDecoder", "j", "b", "TiffFaxDecoder", "_", "data", "outData", "LibError", "br", "TiffBitReader", "mx", "black", "white", "y", "py", "x", "px", "decoder", "e", "tile", "JpegDecoder", "sample", "Float16", "gray", "alpha", "r", "g", "a", "rgba", "ColorUtils", "tileWidth", "tileHeight", "width", "height", "arraySize", "dst", "srcCount", "dstCount", "BitUtils", "repeat", "isFloat", "isInt", "format", "hasPalette", "numChannels", "MemoryImage", "numColors", "TiffInfo", "init_tiff_info", "__esmMin", "opt", "_TiffDecoder", "TiffDecoder", "init_tiff_decoder", "__esmMin", "init_input_buffer", "init_exif_data", "init_frame_type", "init_tiff_image", "init_tiff_info", "p", "byteOrder", "bigEndian", "signature", "offset", "ifdOffset", "p2", "InputBuffer", "images", "img", "TiffImage", "error", "TiffInfo", "bytes", "buffer", "ExifData", "frame", "image", "len", "i", "init_tiff_encoder", "__esmMin", "init_format", "init_output_buffer", "init_lib_error", "init_exif_data", "init_ifd_undefined_value", "init_tiff_compression", "init_tiff_format", "init_tiff_photometric_type", "init_icc_profile_compression", "__esmMin", "import_uzip", "init_icc_profile", "__esmMin", "init_array_utils", "init_icc_profile_compression", "init_image_data", "__esmMin", "init_palette", "__esmMin", "init_quantizer", "__esmMin", "init_flip_direction", "__esmMin", "init_trim_side", "__esmMin", "init_trim_mode", "__esmMin", "init_transform", "__esmMin", "init_lib_error", "init_point", "init_interpolation", "init_math_utils", "init_exif_data", "init_image", "init_image_utils", "init_flip_direction", "init_trim_side", "init_rectangle", "init_draw", "init_blend_mode", "init_trim_mode", "init_src", "__esmMin", "init_bmp_decoder", "init_bmp_encoder", "init_gif_decoder", "init_gif_encoder", "init_ico_decoder", "init_ico_encoder", "init_jpeg_decoder", "init_jpeg_encoder", "init_png_decoder", "init_png_encoder", "init_tga_decoder", "init_tga_encoder", "init_tiff_decoder", "init_tiff_encoder", "init_png_filter_type", "init_dither_kernel", "init_jpeg_utils", "init_channel_order", "init_channel", "init_color_float16", "init_color_float32", "init_color_float64", "init_color_int8", "init_color_int16", "init_color_int32", "init_color_rgb8", "init_color_rgba8", "init_color_uint1", "init_color_uint2", "init_color_uint4", "init_color_uint8", "init_color_uint16", "init_color_uint32", "init_format", "init_array_utils", "init_bit_utils", "init_crc32", "init_float16", "init_input_buffer", "init_interpolation", "init_line", "init_math_utils", "init_output_buffer", "init_point", "init_random_utils", "init_rational", "init_rectangle", "init_string_utils", "init_blend_mode", "init_circle_quadrant", "init_draw", "init_lib_error", "init_ifd_ascii_value", "init_ifd_byte_value", "init_ifd_double_value", "init_ifd_long_value", "init_ifd_rational_value", "init_ifd_sbyte_value", "init_ifd_short_value", "init_ifd_single_value", "init_ifd_slong_value", "init_ifd_srational_value", "init_ifd_sshort_value", "init_ifd_undefined_value", "init_ifd_value", "init_exif_data", "init_exif_entry", "init_exif_tag", "init_ifd_container", "init_ifd_directory", "init_ifd_value_type", "init_filter", "init_noise_type", "init_pixelate_mode", "init_quantize_method", "init_separable_kernel", "init_bmp_compression_mode", "init_bmp_file_header", "init_bmp_info", "init_gif_color_map", "init_gif_image_desc", "init_gif_info", "init_ico_bmp_info", "init_ico_info_image", "init_ico_info", "init_ico_type", "init_huffman_node", "init_huffman_parent", "init_huffman_value", "init_jpeg_adobe", "init_jpeg_component_data", "init_jpeg_component", "init_jpeg_data", "init_jpeg_frame", "init_jpeg_huffman", "init_jpeg_info", "init_jpeg_jfif", "init_jpeg_marker", "init_jpeg_quantize", "init_jpeg_scan", "init_png_blend_mode", "init_png_color_type", "init_png_dispose_mode", "init_png_frame", "init_png_info", "init_tga_image_type", "init_tga_info", "init_tiff_bit_reader", "init_tiff_compression", "init_tiff_entry", "init_tiff_fax_decoder", "init_tiff_format", "init_tiff_image_type", "init_tiff_image", "init_tiff_info", "init_tiff_lzw_decoder", "init_tiff_photometric_type", "init_dib_decoder", "init_win_encoder", "init_frame_type", "init_heap_node", "init_icc_profile", "init_icc_profile_compression", "init_image_data_float16", "init_image_data_float32", "init_image_data_float64", "init_image_data_int8", "init_image_data_int16", "init_image_data_int32", "init_image_data_uint1", "init_image_data_uint2", "init_image_data_uint4", "init_image_data_uint8", "init_image_data_uint16", "init_image_data_uint32", "init_image_utils", "init_image", "init_neural_quantizer", "init_octree_node", "init_octree_quantizer", "init_palette_float16", "init_palette_float32", "init_palette_float64", "init_palette_int8", "init_palette_int16", "init_palette_int32", "init_palette_uint8", "init_palette_uint16", "init_palette_uint32", "init_pixel_float16", "init_pixel_float32", "init_pixel_float64", "init_pixel_int8", "init_pixel_int16", "init_pixel_int32", "init_pixel_uint1", "init_pixel_uint2", "init_pixel_uint4", "init_pixel_uint8", "init_pixel_uint16", "init_pixel_uint32", "init_pixel_undefined", "init_pixel_range_iterator", "init_pixel", "init_quantizer_type", "init_flip_direction", "init_transform", "init_trim_mode", "init_trim_side", "require_UZIP", "__commonJSMin", "exports", "module", "init_channel_order", "init_channel", "init_color_float16", "init_color_float32", "init_color_float64", "init_color_int16", "init_color_int32", "init_color_int8", "init_color_rgb8", "init_color_rgba8", "init_color_uint1", "init_color_uint16", "init_color_uint2", "init_color_uint32", "init_color_uint4", "init_color_uint8", "init_color_utils", "init_color", "init_format", "init_array_utils", "init_bit_utils", "init_crc32", "init_float16", "init_input_buffer", "init_interpolation", "init_line", "init_math_utils", "init_output_buffer", "init_point", "init_random_utils", "init_rational", "init_rectangle", "init_string_utils", "init_typings", "init_blend_mode", "init_circle_quadrant", "init_draw", "init_lib_error", "init_exif_data", "init_exif_entry", "init_exif_tag", "init_ifd_container", "init_ifd_directory", "init_ifd_value_type", "init_ifd_ascii_value", "init_ifd_byte_value", "init_ifd_double_value", "init_ifd_long_value", "init_ifd_rational_value", "init_ifd_sbyte_value", "init_ifd_short_value", "init_ifd_single_value", "init_ifd_slong_value", "init_ifd_srational_value", "init_ifd_sshort_value", "init_ifd_undefined_value", "init_ifd_value", "init_dither_kernel", "init_filter", "init_noise_type", "init_pixelate_mode", "init_quantize_method", "init_separable_kernel", "init_bmp_decoder", "init_bmp_encoder", "init_bmp_compression_mode", "init_bmp_file_header", "init_bmp_info", "init_decode_info", "init_decoder", "init_dib_decoder", "init_encoder", "init_gif_decoder", "init_gif_encoder", "init_gif_color_map", "init_gif_image_desc", "init_gif_info", "init_ico_decoder", "init_ico_encoder", "init_ico_bmp_info", "init_ico_info_image", "init_ico_info", "init_ico_type", "init_jpeg_decoder", "init_jpeg_encoder", "init_huffman_node", "init_huffman_parent", "init_huffman_value", "init_jpeg_adobe", "init_jpeg_component_data", "init_jpeg_component", "init_jpeg_data", "init_jpeg_frame", "init_jpeg_huffman", "init_jpeg_info", "init_jpeg_jfif", "init_jpeg_marker", "init_jpeg_quantize", "init_jpeg_scan", "init_jpeg_utils", "init_png_decoder", "init_png_encoder", "init_png_blend_mode", "init_png_color_type", "init_png_dispose_mode", "init_png_filter_type", "init_png_frame", "init_png_info", "init_tga_decoder", "init_tga_encoder", "init_tga_image_type", "init_tga_info", "init_tiff_decoder", "init_tiff_encoder", "init_tiff_bit_reader", "init_tiff_compression", "init_tiff_entry", "init_tiff_fax_decoder", "init_tiff_format", "init_tiff_image_type", "init_tiff_image", "init_tiff_info", "init_tiff_lzw_decoder", "init_tiff_photometric_type", "init_win_encoder", "init_frame_type", "init_heap_node", "init_icc_profile_compression", "init_icc_profile", "init_image_data_float16", "init_image_data_float32", "init_image_data_float64", "init_image_data_int16", "init_image_data_int32", "init_image_data_int8", "init_image_data_uint1", "init_image_data_uint16", "init_image_data_uint2", "init_image_data_uint32", "init_image_data_uint4", "init_image_data_uint8", "init_image_data", "init_image_utils", "init_image", "init_neural_quantizer", "init_octree_node", "init_octree_quantizer", "init_palette_float16", "init_palette_float32", "init_palette_float64", "init_palette_int16", "init_palette_int32", "init_palette_int8", "init_palette_uint16", "init_palette_uint32", "init_palette_uint8", "init_palette", "init_pixel_float16", "init_pixel_float32", "init_pixel_float64", "init_pixel_int16", "init_pixel_int32", "init_pixel_int8", "init_pixel_range_iterator", "init_pixel_uint1", "init_pixel_uint16", "init_pixel_uint2", "init_pixel_uint32", "init_pixel_uint4", "init_pixel_uint8", "init_pixel_undefined", "init_pixel", "init_quantizer_type", "init_quantizer", "init_src", "init_flip_direction", "init_transform", "init_trim_mode", "init_trim_side", "UZIP", "buf", "onlyNames", "rUs", "rUi", "o", "out", "data", "eocd", "cnu", "cnt", "csize", "coffs", "i", "sign", "crc32", "usize", "nl", "el", "cl", "roff", "ver", "gpflg", "cmpr", "time", "nlen", "elen", "name", "file", "CMF", "FLG", "CM", "CINFO", "opts", "off", "crc", "obj", "noCmpr", "tot", "wUi", "wUs", "zpd", "p", "cpr", "fof", "ioff", "fn", "ext", "t", "tab", "n", "c", "k", "len", "b", "l", "a", "end", "eend", "buff", "s", "ns", "str", "strl", "ci", "code", "opos", "lvl", "opt", "U", "goodIndex", "hash", "putsE", "pos", "cvrd", "dlen", "lits", "strt", "prev", "li", "lc", "bs", "ebits", "nc", "nmch", "nmci", "ii", "mch", "dst", "lgi", "dgi", "nice", "chain", "pi", "dif", "tl", "td", "dlim", "maxd", "j", "ei", "curd", "oi", "BFINAL", "o0", "l0", "putsF", "T", "ML", "MD", "MH", "numl", "numd", "numh", "lset", "dset", "cstSize", "fxdSize", "dynSize", "BTYPE", "ltree", "dtree", "si", "qb", "qc", "p8", "tree", "hst", "set", "rst", "rsl", "nxt", "nnxt", "prv", "lz", "zc", "MAXL", "list", "hl", "l2", "lit", "i0", "i1", "i2", "maxl", "d", "dps", "bCost", "dbt", "od", "v", "arr", "ch", "u8", "F", "bitsF", "bitsE", "decodeTiny", "makeCodes", "codes2map", "get17", "noBuf", "HLIT", "HDIST", "HCLEN", "lmap", "dmap", "ppos", "mx0", "mx1", "ebs", "dcode", "dlit", "dbs", "bl", "nbuf", "LL", "ll", "ni", "src", "mx", "MAX_BITS", "max_code", "bits", "bl_count", "next_code", "map", "r15", "val", "rest", "p0", "imb", "dt", "length", "u16", "u32", "x", "pushV", "tgt", "sv", "import_uzip", "init_png_decoder", "__esmMin", "init_crc32", "init_input_buffer", "init_array_utils", "init_string_utils", "init_lib_error", "init_png_frame", "init_png_info", "init_png_color_type", "init_png_dispose_mode", "init_png_blend_mode", "init_color_rgba8", "init_color_rgb8", "init_image", "init_palette_uint8", "init_format", "init_icc_profile", "init_icc_profile_compression", "init_draw", "init_blend_mode", "init_png_filter_type", "init_ico_decoder", "__esmMin", "init_input_buffer", "init_output_buffer", "init_bmp_file_header", "init_dib_decoder", "init_ico_bmp_info", "init_ico_info", "init_png_decoder", "init_frame_type", "init_channel_order", "init_channel", "init_color_float16", "init_color_float32", "init_color_float64", "init_color_int16", "init_color_int32", "init_color_int8", "init_color_rgb8", "init_color_rgba8", "init_color_uint1", "init_color_uint16", "init_color_uint2", "init_color_uint32", "init_color_uint4", "init_color_uint8", "init_color_utils", "init_color", "init_format", "init_array_utils", "init_bit_utils", "init_crc32", "init_float16", "init_input_buffer", "init_interpolation", "init_line", "init_math_utils", "init_output_buffer", "init_point", "init_random_utils", "init_rational", "init_rectangle", "init_string_utils", "init_typings", "init_blend_mode", "init_circle_quadrant", "init_draw", "init_lib_error", "init_exif_data", "init_exif_entry", "init_exif_tag", "init_ifd_container", "init_ifd_directory", "init_ifd_value_type", "init_ifd_ascii_value", "init_ifd_byte_value", "init_ifd_double_value", "init_ifd_long_value", "init_ifd_rational_value", "init_ifd_sbyte_value", "init_ifd_short_value", "init_ifd_single_value", "init_ifd_slong_value", "init_ifd_srational_value", "init_ifd_sshort_value", "init_ifd_undefined_value", "init_ifd_value", "init_dither_kernel", "init_filter", "init_noise_type", "init_pixelate_mode", "init_quantize_method", "init_separable_kernel", "init_bmp_decoder", "init_bmp_encoder", "init_bmp_compression_mode", "init_bmp_file_header", "init_bmp_info", "init_decode_info", "init_decoder", "init_dib_decoder", "init_encoder", "init_gif_decoder", "init_gif_encoder", "init_gif_color_map", "init_gif_image_desc", "init_gif_info", "init_ico_decoder", "init_ico_encoder", "init_ico_bmp_info", "init_ico_info_image", "init_ico_info", "init_ico_type", "init_jpeg_decoder", "init_jpeg_encoder", "init_huffman_node", "init_huffman_parent", "init_huffman_value", "init_jpeg_adobe", "init_jpeg_component_data", "init_jpeg_component", "init_jpeg_data", "init_jpeg_frame", "init_jpeg_huffman", "init_jpeg_info", "init_jpeg_jfif", "init_jpeg_marker", "init_jpeg_quantize", "init_jpeg_scan", "init_jpeg_utils", "init_png_decoder", "init_png_encoder", "init_png_blend_mode", "init_png_color_type", "init_png_dispose_mode", "init_png_filter_type", "init_png_frame", "init_png_info", "init_tga_decoder", "init_tga_encoder", "init_tga_image_type", "init_tga_info", "init_tiff_decoder", "init_tiff_encoder", "init_tiff_bit_reader", "init_tiff_compression", "init_tiff_entry", "init_tiff_fax_decoder", "init_tiff_format", "init_tiff_image_type", "init_tiff_image", "init_tiff_info", "init_tiff_lzw_decoder", "init_tiff_photometric_type", "init_win_encoder", "init_frame_type", "init_heap_node", "init_icc_profile_compression", "init_icc_profile", "init_image_data_float16", "init_image_data_float32", "init_image_data_float64", "init_image_data_int16", "init_image_data_int32", "init_image_data_int8", "init_image_data_uint1", "init_image_data_uint16", "init_image_data_uint2", "init_image_data_uint32", "init_image_data_uint4", "init_image_data_uint8", "init_image_data", "init_image_utils", "init_image", "init_neural_quantizer", "init_octree_node", "init_octree_quantizer", "init_palette_float16", "init_palette_float32", "init_palette_float64", "init_palette_int16", "init_palette_int32", "init_palette_int8", "init_palette_uint16", "init_palette_uint32", "init_palette_uint8", "init_palette", "init_pixel_float16", "init_pixel_float32", "init_pixel_float64", "init_pixel_int16", "init_pixel_int32", "init_pixel_int8", "init_pixel_range_iterator", "init_pixel_uint1", "init_pixel_uint16", "init_pixel_uint2", "init_pixel_uint32", "init_pixel_uint4", "init_pixel_uint8", "init_pixel_undefined", "init_pixel", "init_quantizer_type", "init_quantizer", "init_src", "init_flip_direction", "init_transform", "init_trim_mode", "init_trim_side"] } diff --git a/package-lock.json b/package-lock.json index 30c43af..1b7346b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "image-in-browser", "version": "1.4.6", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -12,19 +12,19 @@ "uzip": "^0.20201231.0" }, "devDependencies": { - "@types/jest": "^29.2.0", - "@types/node": "^18.11.3", + "@types/jest": "^29.4.0", + "@types/node": "^18.11.19", "@types/uzip": "^0.20201231.0", - "@typescript-eslint/eslint-plugin": "^5.40.1", - "@typescript-eslint/parser": "^5.40.1", - "esbuild": "^0.15.12", - "eslint": "^8.26.0", - "eslint-config-prettier": "^8.5.0", - "jest": "^29.2.1", - "prettier": "2.7.1", + "@typescript-eslint/eslint-plugin": "^5.51.0", + "@typescript-eslint/parser": "^5.51.0", + "esbuild": "^0.17.6", + "eslint": "^8.33.0", + "eslint-config-prettier": "^8.6.0", + "jest": "^29.4.1", + "prettier": "2.8.3", "standard-version": "^9.5.0", - "ts-jest": "^29.0.3", - "typescript": "^4.8.4" + "ts-jest": "^29.0.5", + "typescript": "^4.9.5" } }, "node_modules/@ampproject/remapping": { @@ -53,34 +53,34 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", - "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==", + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz", + "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.6.tgz", - "integrity": "sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==", + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.6", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helpers": "^7.19.4", - "@babel/parser": "^7.19.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", + "json5": "^2.2.2", "semver": "^6.3.0" }, "engines": { @@ -91,6 +91,12 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -101,12 +107,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.6.tgz", - "integrity": "sha512-oHGRUQeoX1QrKeJIKVe0hwjGqNnVYsM5Nep5zo0uE0m42sLH+Fsd2pStJ5sRM1bNyTUUoz0pe2lTeMJrb/taTA==", + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", + "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", "dev": true, "dependencies": { - "@babel/types": "^7.19.4", + "@babel/types": "^7.20.7", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -129,14 +135,15 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", - "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.19.3", + "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", "semver": "^6.3.0" }, "engines": { @@ -202,40 +209,40 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz", - "integrity": "sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==", + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.19.4", + "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", - "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dev": true, "dependencies": { - "@babel/types": "^7.19.4" + "@babel/types": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -281,14 +288,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", - "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", + "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", "dev": true, "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.4", - "@babel/types": "^7.19.4" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.13", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" @@ -380,9 +387,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.6.tgz", - "integrity": "sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA==", + "version": "7.20.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", + "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -554,12 +561,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -569,33 +576,33 @@ } }, "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.6.tgz", - "integrity": "sha512-6l5HrUCzFM04mfbG09AagtYyR2P0B71B1wN7PfSPiksDPz2k5H9CBC1tcZpz2M8OxbKTPccByoOJ22rUKbpmQQ==", + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", + "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.6", + "@babel/generator": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.6", - "@babel/types": "^7.19.4", + "@babel/parser": "^7.20.13", + "@babel/types": "^7.20.7", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -613,9 +620,9 @@ } }, "node_modules/@babel/types": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", - "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.19.4", @@ -633,9 +640,9 @@ "dev": true }, "node_modules/@esbuild/android-arm": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.12.tgz", - "integrity": "sha512-IC7TqIqiyE0MmvAhWkl/8AEzpOtbhRNDo7aph47We1NbE5w2bt/Q+giAhe0YYeVpYnIhGMcuZY92qDK6dQauvA==", + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.6.tgz", + "integrity": "sha512-bSC9YVUjADDy1gae8RrioINU6e1lCkg3VGVwm0QQ2E1CWcC4gnMce9+B6RpxuSsrsXsk1yojn7sp1fnG8erE2g==", "cpu": [ "arm" ], @@ -648,6825 +655,662 @@ "node": ">=12" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.12.tgz", - "integrity": "sha512-tZEowDjvU7O7I04GYvWQOS4yyP9E/7YlsB0jjw1Ycukgr2ycEzKyIk5tms5WnLBymaewc6VmRKnn5IJWgK4eFw==", + "node_modules/@esbuild/android-arm64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.6.tgz", + "integrity": "sha512-YnYSCceN/dUzUr5kdtUzB+wZprCafuD89Hs0Aqv9QSdwhYQybhXTaSTcrl6X/aWThn1a/j0eEpUBGOE7269REg==", "cpu": [ - "loong64" + "arm64" ], "dev": true, "optional": true, "os": [ - "linux" + "android" ], "engines": { "node": ">=12" } }, - "node_modules/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "node_modules/@esbuild/android-x64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.6.tgz", + "integrity": "sha512-MVcYcgSO7pfu/x34uX9u2QIZHmXAB7dEiLQC5bBl5Ryqtpj9lT2sg3gNDEsrPEmimSJW2FXIaxqSQ501YLDsZQ==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=12" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.6.tgz", - "integrity": "sha512-jJr+hPTJYKyDILJfhNSHsjiwXYf26Flsz8DvNndOsHs5pwSnpGUEy8yzF0JYhCEvTDdV2vuOK5tt8BVhwO5/hg==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.6.tgz", + "integrity": "sha512-bsDRvlbKMQMt6Wl08nHtFz++yoZHsyTOxnjfB2Q95gato+Yi4WnRl13oC2/PJJA9yLCoRv9gqT/EYX0/zDsyMA==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=10.10.0" + "node": ">=12" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.6.tgz", + "integrity": "sha512-xh2A5oPrYRfMFz74QXIQTQo8uA+hYzGWJFoeTE8EvoZGHb+idyV4ATaukaUvnnxJiauhs/fPx3vYhU4wiGfosg==", + "cpu": [ + "x64" + ], "dev": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=12" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@hutson/parse-repository-url": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", - "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.6.tgz", + "integrity": "sha512-EnUwjRc1inT4ccZh4pB3v1cIhohE2S4YXlt1OvI7sw/+pD+dIE4smwekZlEPIwY6PhU6oDWwITrQQm5S2/iZgg==", + "cpu": [ + "arm64" + ], "dev": true, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.6.tgz", + "integrity": "sha512-Uh3HLWGzH6FwpviUcLMKPCbZUAFzv67Wj5MTwK6jn89b576SR2IbEp+tqUHTr8DIl0iDmBAf51MVaP7pw6PY5Q==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/@esbuild/linux-arm": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.6.tgz", + "integrity": "sha512-7YdGiurNt7lqO0Bf/U9/arrPWPqdPqcV6JCZda4LZgEn+PTQ5SMEI4MGR52Bfn3+d6bNEGcWFzlIxiQdS48YUw==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.6.tgz", + "integrity": "sha512-bUR58IFOMJX523aDVozswnlp5yry7+0cRLCXDsxnUeQYJik1DukMY+apBsLOZJblpH+K7ox7YrKrHmJoWqVR9w==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.6.tgz", + "integrity": "sha512-ujp8uoQCM9FRcbDfkqECoARsLnLfCUhKARTP56TFPog8ie9JG83D5GVKjQ6yVrEVdMie1djH86fm98eY3quQkQ==", + "cpu": [ + "ia32" + ], "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.6.tgz", + "integrity": "sha512-y2NX1+X/Nt+izj9bLoiaYB9YXT/LoaQFYvCkVD77G/4F+/yuVXYCWz4SE9yr5CBMbOxOfBcy/xFL4LlOeNlzYQ==", + "cpu": [ + "loong64" + ], "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.6.tgz", + "integrity": "sha512-09AXKB1HDOzXD+j3FdXCiL/MWmZP0Ex9eR8DLMBVcHorrWJxWmY8Nms2Nm41iRM64WVx7bA/JVHMv081iP2kUA==", + "cpu": [ + "mips64el" + ], "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.6.tgz", + "integrity": "sha512-AmLhMzkM8JuqTIOhxnX4ubh0XWJIznEynRnZAVdA2mMKE6FAfwT2TWKTwdqMG+qEaeyDPtfNoZRpJbD4ZBv0Tg==", + "cpu": [ + "ppc64" + ], "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.6.tgz", + "integrity": "sha512-Y4Ri62PfavhLQhFbqucysHOmRamlTVK10zPWlqjNbj2XMea+BOs4w6ASKwQwAiqf9ZqcY9Ab7NOU4wIgpxwoSQ==", + "cpu": [ + "riscv64" + ], "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/@jest/console": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.2.1.tgz", - "integrity": "sha512-MF8Adcw+WPLZGBiNxn76DOuczG3BhODTcMlDCA4+cFi41OkaY/lyI0XUUhi73F88Y+7IHoGmD80pN5CtxQUdSw==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.6.tgz", + "integrity": "sha512-SPUiz4fDbnNEm3JSdUW8pBJ/vkop3M1YwZAVwvdwlFLoJwKEZ9L98l3tzeyMzq27CyepDQ3Qgoba44StgbiN5Q==", + "cpu": [ + "s390x" + ], "dev": true, - "dependencies": { - "@jest/types": "^29.2.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1", - "slash": "^3.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/core": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.2.1.tgz", - "integrity": "sha512-kuLKYqnqgerXkBUwlHVxeSuhSnd+JMnMCLfU98bpacBSfWEJPegytDh3P2m15/JHzet32hGGld4KR4OzMb6/Tg==", + "node_modules/@esbuild/linux-x64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.6.tgz", + "integrity": "sha512-a3yHLmOodHrzuNgdpB7peFGPx1iJ2x6m+uDvhP2CKdr2CwOaqEFMeSqYAHU7hG+RjCq8r2NFujcd/YsEsFgTGw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@jest/console": "^29.2.1", - "@jest/reporters": "^29.2.1", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.1", - "@jest/types": "^29.2.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.2.0", - "jest-config": "^29.2.1", - "jest-haste-map": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.2.1", - "jest-resolve-dependencies": "^29.2.1", - "jest-runner": "^29.2.1", - "jest-runtime": "^29.2.1", - "jest-snapshot": "^29.2.1", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.1", - "jest-watcher": "^29.2.1", - "micromatch": "^4.0.4", - "pretty-format": "^29.2.1", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "node": ">=12" } }, - "node_modules/@jest/environment": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.2.1.tgz", - "integrity": "sha512-EutqA7T/X6zFjw6mAWRHND+ZkTPklmIEWCNbmwX6uCmOrFrWaLbDZjA+gePHJx6fFMMRvNfjXcvzXEtz54KPlg==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.6.tgz", + "integrity": "sha512-EanJqcU/4uZIBreTrnbnre2DXgXSa+Gjap7ifRfllpmyAU7YMvaXmljdArptTHmjrkkKm9BK6GH5D5Yo+p6y5A==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@jest/fake-timers": "^29.2.1", - "@jest/types": "^29.2.1", - "@types/node": "*", - "jest-mock": "^29.2.1" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/expect": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.2.1.tgz", - "integrity": "sha512-o14R2t2tHHHudwji43UKkzmmH49xfF5T++FQBK2tl88qwuBWQOcx7fNUYl+mA/9TPNAN0FkQ3usnpyS8FUwsvQ==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.6.tgz", + "integrity": "sha512-xaxeSunhQRsTNGFanoOkkLtnmMn5QbA0qBhNet/XLVsc+OVkpIWPHcr3zTW2gxVU5YOHFbIHR9ODuaUdNza2Vw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "expect": "^29.2.1", - "jest-snapshot": "^29.2.1" - }, + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/expect-utils": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.2.1.tgz", - "integrity": "sha512-yr4aHNg5Z1CjKby5ozm7sKjgBlCOorlAoFcvrOQ/4rbZRfgZQdnmh7cth192PYIgiPZo2bBXvqdOApnAMWFJZg==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.6.tgz", + "integrity": "sha512-gnMnMPg5pfMkZvhHee21KbKdc6W3GR8/JuE0Da1kjwpK6oiFU3nqfHuVPgUX2rsOx9N2SadSQTIYV1CIjYG+xw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "jest-get-type": "^29.2.0" - }, + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/fake-timers": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.2.1.tgz", - "integrity": "sha512-KWil+8fef7Uj/P/PTZlPKk1Pw117wAmr71VWFV8ZDtRtkwmTG8oY4IRf0Ss44J2y5CYRy8d/zLOhxyoGRENjvA==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.6.tgz", + "integrity": "sha512-G95n7vP1UnGJPsVdKXllAJPtqjMvFYbN20e8RK8LVLhlTiSOH1sd7+Gt7rm70xiG+I5tM58nYgwWrLs6I1jHqg==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@jest/types": "^29.2.1", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^29.2.1", - "jest-mock": "^29.2.1", - "jest-util": "^29.2.1" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/globals": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.2.1.tgz", - "integrity": "sha512-Z4EejYPP1OPVq2abk1+9urAwJqkgw5jB2UJGlPjb5ZwzPQF8WLMcigKEfFzZb2OHhEVPP0RZD0/DbVTY1R6iQA==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.6.tgz", + "integrity": "sha512-96yEFzLhq5bv9jJo5JhTs1gI+1cKQ83cUpyxHuGqXVwQtY5Eq54ZEsKs8veKtiKwlrNimtckHEkj4mRh4pPjsg==", + "cpu": [ + "ia32" + ], "dev": true, - "dependencies": { - "@jest/environment": "^29.2.1", - "@jest/expect": "^29.2.1", - "@jest/types": "^29.2.1", - "jest-mock": "^29.2.1" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/reporters": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.2.1.tgz", - "integrity": "sha512-sCsfUKM/yIF4nNed3e/rIgVIS58EiASGMDEPWqItfLZ9UO1ALW2ASDNJzdWkxEt0T8o2Ztj619G0KKrvK+McAw==", + "node_modules/@esbuild/win32-x64": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.6.tgz", + "integrity": "sha512-n6d8MOyUrNp6G4VSpRcgjs5xj4A91svJSaiwLIDWVWEsZtpN5FA9NlBbZHDmAJc2e8e6SF4tkBD3HAvPF+7igA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", "dev": true, "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.2.1", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.1", - "@jest/types": "^29.2.1", - "@jridgewell/trace-mapping": "^0.3.15", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1", - "jest-worker": "^29.2.1", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.24.1" + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10.10.0" } }, - "node_modules/@jest/source-map": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", - "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.15", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" + "engines": { + "node": ">=12.22" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "dev": true, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=6.9.0" } }, - "node_modules/@jest/test-result": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.2.1.tgz", - "integrity": "sha512-lS4+H+VkhbX6z64tZP7PAUwPqhwj3kbuEHcaLuaBuB+riyaX7oa1txe0tXgrFj5hRWvZKvqO7LZDlNWeJ7VTPA==", + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "dependencies": { - "@jest/console": "^29.2.1", - "@jest/types": "^29.2.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/@jest/test-sequencer": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.2.1.tgz", - "integrity": "sha512-O/pnk0/xGj3lxPVNwB6HREJ7AYvUdyP2xo/s14/9Dtf091HoOeyIhWLKQE/4HzB8lNQBMo6J5mg0bHz/uCWK7w==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "dependencies": { - "@jest/test-result": "^29.2.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.2.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "sprintf-js": "~1.0.2" } }, - "node_modules/@jest/transform": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.2.1.tgz", - "integrity": "sha512-xup+iEuaIRSQabQaeqxaQyN0vg1Dctrp9oTObQsNf3sZEowTIa5cANYuoyi8Tqhg4GCqEVLTf18KW7ii0UeFVA==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.2.1", - "@jridgewell/trace-mapping": "^0.3.15", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.2.1", - "jest-regex-util": "^29.2.0", - "jest-util": "^29.2.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/@jest/types": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.2.1.tgz", - "integrity": "sha512-O/QNDQODLnINEPAI0cl9U6zUIDXEWXt6IC1o2N2QENuos7hlGUIthlKyV4p6ki3TvXFX071blj8HUhgLGquPjw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=8" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "p-try": "^2.0.0" }, "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "p-limit": "^2.2.0" }, "engines": { - "node": ">= 8" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.24.50", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.50.tgz", - "integrity": "sha512-k8ETQOOQDg5FtK7y9KJWpsGLik+QlPmIi8zzl/dGUgshV2QitprkFlCR/AemjWOTyKn9UwSSGRTzLVotvgCjYQ==", - "dev": true - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", - "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.3.0" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.0.tgz", - "integrity": "sha512-KO7bPV21d65PKwv3LLsD8Jn3E05pjNjRZvkm+YTacWhVmykAb07wW6IkZUmQAltwQafNcDUEUrMO2h3jeBSisg==", - "dev": true, - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "node_modules/@types/minimist": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.11.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.3.tgz", - "integrity": "sha512-fNjDQzzOsZeKZu5NATgXUPsaFaTxeRgFXoosrHivTl8RGeV733OLawXsGfEk9a8/tySyZUyiZ6E8LcjPFZ2y1A==", - "dev": true - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "dev": true - }, - "node_modules/@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", - "dev": true - }, - "node_modules/@types/semver": { - "version": "7.3.12", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz", - "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==", - "dev": true - }, - "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "node_modules/@types/uzip": { - "version": "0.20201231.0", - "resolved": "https://registry.npmjs.org/@types/uzip/-/uzip-0.20201231.0.tgz", - "integrity": "sha512-h5QS4GArSRa0VqWC30rQ8q/WjDwmTrFFMOulFQUAEjhL9zUApefLnpF2Y7ZRNrfMqCjKnWGxs2AtYrN6/t699w==", - "dev": true - }, - "node_modules/@types/yargs": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", - "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" + "node": ">=8" } }, - "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.1.tgz", - "integrity": "sha512-FsWboKkWdytGiXT5O1/R9j37YgcjO8MKHSUmWnIEjVaz0krHkplPnYi7mwdb+5+cs0toFNQb0HIrN7zONdIEWg==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/type-utils": "5.40.1", - "@typescript-eslint/utils": "5.40.1", - "debug": "^4.3.4", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=8" } }, - "node_modules/@typescript-eslint/parser": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.1.tgz", - "integrity": "sha512-IK6x55va5w4YvXd4b3VrXQPldV9vQTxi5ov+g4pMANsXPTXOcfjx08CRR1Dfrcc51syPtXHF5bgLlMHYFrvQtg==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/typescript-estree": "5.40.1", - "debug": "^4.3.4" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=8" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.1.tgz", - "integrity": "sha512-jkn4xsJiUQucI16OLCXrLRXDZ3afKhOIqXs4R3O+M00hdQLKR58WuyXPZZjhKLFCEP2g+TXdBRtLQ33UfAdRUg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/visitor-keys": "5.40.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.40.1.tgz", - "integrity": "sha512-DLAs+AHQOe6n5LRraXiv27IYPhleF0ldEmx6yBqBgBLaNRKTkffhV1RPsjoJBhVup2zHxfaRtan8/YRBgYhU9Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "5.40.1", - "@typescript-eslint/utils": "5.40.1", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.1.tgz", - "integrity": "sha512-Icg9kiuVJSwdzSQvtdGspOlWNjVDnF3qVIKXdJ103o36yRprdl3Ge5cABQx+csx960nuMF21v8qvO31v9t3OHw==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.1.tgz", - "integrity": "sha512-5QTP/nW5+60jBcEPfXy/EZL01qrl9GZtbgDZtDPlfW5zj/zjNrdI2B5zMUHmOsfvOr2cWqwVdWjobCiHcedmQA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/visitor-keys": "5.40.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.40.1.tgz", - "integrity": "sha512-a2TAVScoX9fjryNrW6BZRnreDUszxqm9eQ9Esv8n5nXApMW0zeANUYlwh/DED04SC/ifuBvXgZpIK5xeJHQ3aw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/typescript-estree": "5.40.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.1.tgz", - "integrity": "sha512-A2DGmeZ+FMja0geX5rww+DpvILpwo1OsiQs0M+joPWJYsiEFBLsH0y1oFymPNul6Z5okSmHpP4ivkc2N0Cgfkw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.40.1", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/add-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", - "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", - "dev": true - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-jest": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.2.1.tgz", - "integrity": "sha512-gQJwArok0mqoREiCYhXKWOgUhElJj9DpnssW6GL8dG7ARYqHEhrM9fmPHTjdqEGRVXZAd6+imo3/Vwa8TjLcsw==", - "dev": true, - "dependencies": { - "@jest/transform": "^29.2.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.2.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz", - "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz", - "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^29.2.0", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001423", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001423.tgz", - "integrity": "sha512-09iwWGOlifvE1XuHokFMP7eR38a0JnajoyL3/i87c8ZjRWRrdKo1fqjNfugfBD0UDBIOz0U+jtNhJ0EPm1VleQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", - "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", - "dev": true - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, - "dependencies": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "dev": true, - "engines": [ - "node >= 6.0" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/conventional-changelog": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", - "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==", - "dev": true, - "dependencies": { - "conventional-changelog-angular": "^5.0.12", - "conventional-changelog-atom": "^2.0.8", - "conventional-changelog-codemirror": "^2.0.8", - "conventional-changelog-conventionalcommits": "^4.5.0", - "conventional-changelog-core": "^4.2.1", - "conventional-changelog-ember": "^2.0.9", - "conventional-changelog-eslint": "^3.0.9", - "conventional-changelog-express": "^2.0.6", - "conventional-changelog-jquery": "^3.0.11", - "conventional-changelog-jshint": "^2.0.9", - "conventional-changelog-preset-loader": "^2.3.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-angular": { - "version": "5.0.13", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", - "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0", - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-atom": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", - "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", - "dev": true, - "dependencies": { - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-codemirror": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", - "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", - "dev": true, - "dependencies": { - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-config-spec": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", - "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", - "dev": true - }, - "node_modules/conventional-changelog-conventionalcommits": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz", - "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0", - "lodash": "^4.17.15", - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-core": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", - "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", - "dev": true, - "dependencies": { - "add-stream": "^1.0.0", - "conventional-changelog-writer": "^5.0.0", - "conventional-commits-parser": "^3.2.0", - "dateformat": "^3.0.0", - "get-pkg-repo": "^4.0.0", - "git-raw-commits": "^2.0.8", - "git-remote-origin-url": "^2.0.0", - "git-semver-tags": "^4.1.1", - "lodash": "^4.17.15", - "normalize-package-data": "^3.0.0", - "q": "^1.5.1", - "read-pkg": "^3.0.0", - "read-pkg-up": "^3.0.0", - "through2": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-ember": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", - "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", - "dev": true, - "dependencies": { - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-eslint": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", - "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", - "dev": true, - "dependencies": { - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-express": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", - "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", - "dev": true, - "dependencies": { - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-jquery": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", - "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", - "dev": true, - "dependencies": { - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-jshint": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", - "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0", - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-preset-loader": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", - "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-writer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", - "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", - "dev": true, - "dependencies": { - "conventional-commits-filter": "^2.0.7", - "dateformat": "^3.0.0", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "semver": "^6.0.0", - "split": "^1.0.0", - "through2": "^4.0.0" - }, - "bin": { - "conventional-changelog-writer": "cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-writer/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/conventional-commits-filter": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", - "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", - "dev": true, - "dependencies": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-commits-parser": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", - "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", - "dev": true, - "dependencies": { - "is-text-path": "^1.0.1", - "JSONStream": "^1.0.4", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" - }, - "bin": { - "conventional-commits-parser": "cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-recommended-bump": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", - "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", - "dev": true, - "dependencies": { - "concat-stream": "^2.0.0", - "conventional-changelog-preset-loader": "^2.3.4", - "conventional-commits-filter": "^2.0.7", - "conventional-commits-parser": "^3.2.0", - "git-raw-commits": "^2.0.8", - "git-semver-tags": "^4.1.1", - "meow": "^8.0.0", - "q": "^1.5.1" - }, - "bin": { - "conventional-recommended-bump": "cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/dargs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==", - "dev": true, - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/diff-sequences": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.2.0.tgz", - "integrity": "sha512-413SY5JpYeSBZxmenGEmCVQ8mCgtFJF0w9PROdaS6z987XC2Pd2GOKqOITLtMftmyFZqgtCOb/QA7/Z3ZXfzIw==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dotgitignore": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", - "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", - "dev": true, - "dependencies": { - "find-up": "^3.0.0", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dotgitignore/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", - "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/esbuild": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.12.tgz", - "integrity": "sha512-PcT+/wyDqJQsRVhaE9uX/Oq4XLrFh0ce/bs2TJh4CSaw9xuvI+xFrH2nAYOADbhQjUgAhNWC5LKoUsakm4dxng==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.15.12", - "@esbuild/linux-loong64": "0.15.12", - "esbuild-android-64": "0.15.12", - "esbuild-android-arm64": "0.15.12", - "esbuild-darwin-64": "0.15.12", - "esbuild-darwin-arm64": "0.15.12", - "esbuild-freebsd-64": "0.15.12", - "esbuild-freebsd-arm64": "0.15.12", - "esbuild-linux-32": "0.15.12", - "esbuild-linux-64": "0.15.12", - "esbuild-linux-arm": "0.15.12", - "esbuild-linux-arm64": "0.15.12", - "esbuild-linux-mips64le": "0.15.12", - "esbuild-linux-ppc64le": "0.15.12", - "esbuild-linux-riscv64": "0.15.12", - "esbuild-linux-s390x": "0.15.12", - "esbuild-netbsd-64": "0.15.12", - "esbuild-openbsd-64": "0.15.12", - "esbuild-sunos-64": "0.15.12", - "esbuild-windows-32": "0.15.12", - "esbuild-windows-64": "0.15.12", - "esbuild-windows-arm64": "0.15.12" - } - }, - "node_modules/esbuild-android-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.12.tgz", - "integrity": "sha512-MJKXwvPY9g0rGps0+U65HlTsM1wUs9lbjt5CU19RESqycGFDRijMDQsh68MtbzkqWSRdEtiKS1mtPzKneaAI0Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-android-arm64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.12.tgz", - "integrity": "sha512-Hc9SEcZbIMhhLcvhr1DH+lrrec9SFTiRzfJ7EGSBZiiw994gfkVV6vG0sLWqQQ6DD7V4+OggB+Hn0IRUdDUqvA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-darwin-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.12.tgz", - "integrity": "sha512-qkmqrTVYPFiePt5qFjP8w/S+GIUMbt6k8qmiPraECUWfPptaPJUGkCKrWEfYFRWB7bY23FV95rhvPyh/KARP8Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-darwin-arm64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.12.tgz", - "integrity": "sha512-z4zPX02tQ41kcXMyN3c/GfZpIjKoI/BzHrdKUwhC/Ki5BAhWv59A9M8H+iqaRbwpzYrYidTybBwiZAIWCLJAkw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-freebsd-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.12.tgz", - "integrity": "sha512-XFL7gKMCKXLDiAiBjhLG0XECliXaRLTZh6hsyzqUqPUf/PY4C6EJDTKIeqqPKXaVJ8+fzNek88285krSz1QECw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-freebsd-arm64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.12.tgz", - "integrity": "sha512-jwEIu5UCUk6TjiG1X+KQnCGISI+ILnXzIzt9yDVrhjug2fkYzlLbl0K43q96Q3KB66v6N1UFF0r5Ks4Xo7i72g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-32": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.12.tgz", - "integrity": "sha512-uSQuSEyF1kVzGzuIr4XM+v7TPKxHjBnLcwv2yPyCz8riV8VUCnO/C4BF3w5dHiVpCd5Z1cebBtZJNlC4anWpwA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.12.tgz", - "integrity": "sha512-QcgCKb7zfJxqT9o5z9ZUeGH1k8N6iX1Y7VNsEi5F9+HzN1OIx7ESxtQXDN9jbeUSPiRH1n9cw6gFT3H4qbdvcA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-arm": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.12.tgz", - "integrity": "sha512-Wf7T0aNylGcLu7hBnzMvsTfEXdEdJY/hY3u36Vla21aY66xR0MS5I1Hw8nVquXjTN0A6fk/vnr32tkC/C2lb0A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-arm64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.12.tgz", - "integrity": "sha512-HtNq5xm8fUpZKwWKS2/YGwSfTF+339L4aIA8yphNKYJckd5hVdhfdl6GM2P3HwLSCORS++++7++//ApEwXEuAQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-mips64le": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.12.tgz", - "integrity": "sha512-Qol3+AvivngUZkTVFgLpb0H6DT+N5/zM3V1YgTkryPYFeUvuT5JFNDR3ZiS6LxhyF8EE+fiNtzwlPqMDqVcc6A==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-ppc64le": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.12.tgz", - "integrity": "sha512-4D8qUCo+CFKaR0cGXtGyVsOI7w7k93Qxb3KFXWr75An0DHamYzq8lt7TNZKoOq/Gh8c40/aKaxvcZnTgQ0TJNg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-riscv64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.12.tgz", - "integrity": "sha512-G9w6NcuuCI6TUUxe6ka0enjZHDnSVK8bO+1qDhMOCtl7Tr78CcZilJj8SGLN00zO5iIlwNRZKHjdMpfFgNn1VA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-s390x": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.12.tgz", - "integrity": "sha512-Lt6BDnuXbXeqSlVuuUM5z18GkJAZf3ERskGZbAWjrQoi9xbEIsj/hEzVnSAFLtkfLuy2DE4RwTcX02tZFunXww==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-netbsd-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.12.tgz", - "integrity": "sha512-jlUxCiHO1dsqoURZDQts+HK100o0hXfi4t54MNRMCAqKGAV33JCVvMplLAa2FwviSojT/5ZG5HUfG3gstwAG8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-openbsd-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.12.tgz", - "integrity": "sha512-1o1uAfRTMIWNOmpf8v7iudND0L6zRBYSH45sofCZywrcf7NcZA+c7aFsS1YryU+yN7aRppTqdUK1PgbZVaB1Dw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-sunos-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.12.tgz", - "integrity": "sha512-nkl251DpoWoBO9Eq9aFdoIt2yYmp4I3kvQjba3jFKlMXuqQ9A4q+JaqdkCouG3DHgAGnzshzaGu6xofGcXyPXg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-32": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.12.tgz", - "integrity": "sha512-WlGeBZHgPC00O08luIp5B2SP4cNCp/PcS+3Pcg31kdcJPopHxLkdCXtadLU9J82LCfw4TVls21A6lilQ9mzHrw==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.12.tgz", - "integrity": "sha512-VActO3WnWZSN//xjSfbiGOSyC+wkZtI8I4KlgrTo5oHJM6z3MZZBCuFaZHd8hzf/W9KPhF0lY8OqlmWC9HO5AA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-arm64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.12.tgz", - "integrity": "sha512-Of3MIacva1OK/m4zCNIvBfz8VVROBmQT+gRX6pFTLPngFYcj6TFH/12VveAqq1k9VB2l28EoVMNMUCcmsfwyuA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", - "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.15.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", - "dev": true, - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.2.1.tgz", - "integrity": "sha512-BJtA754Fba0YWRWHgjKUMTA3ltWarKgITXHQnbZ2mTxTXC4yMQlR0FI7HkB3fJYkhWBf4qjNiqvg3LDtXCcVRQ==", - "dev": true, - "dependencies": { - "@jest/expect-utils": "^29.2.1", - "jest-get-type": "^29.2.0", - "jest-matcher-utils": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-pkg-repo": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", - "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", - "dev": true, - "dependencies": { - "@hutson/parse-repository-url": "^3.0.0", - "hosted-git-info": "^4.0.0", - "through2": "^2.0.0", - "yargs": "^16.2.0" - }, - "bin": { - "get-pkg-repo": "src/cli.js" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-pkg-repo/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/get-pkg-repo/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/get-pkg-repo/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/get-pkg-repo/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/get-pkg-repo/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/get-pkg-repo/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/git-raw-commits": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", - "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", - "dev": true, - "dependencies": { - "dargs": "^7.0.0", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" - }, - "bin": { - "git-raw-commits": "cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/git-remote-origin-url": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", - "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", - "dev": true, - "dependencies": { - "gitconfiglocal": "^1.0.0", - "pify": "^2.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/git-semver-tags": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", - "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", - "dev": true, - "dependencies": { - "meow": "^8.0.0", - "semver": "^6.0.0" - }, - "bin": { - "git-semver-tags": "cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/git-semver-tags/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/gitconfiglocal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", - "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", - "dev": true, - "dependencies": { - "ini": "^1.3.2" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-text-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", - "dev": true, - "dependencies": { - "text-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.2.1.tgz", - "integrity": "sha512-K0N+7rx+fv3Us3KhuwRSJt55MMpZPs9Q3WSO/spRZSnsalX8yEYOTQ1PiSN7OvqzoRX4JEUXCbOJRlP4n8m5LA==", - "dev": true, - "dependencies": { - "@jest/core": "^29.2.1", - "@jest/types": "^29.2.1", - "import-local": "^3.0.2", - "jest-cli": "^29.2.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz", - "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==", - "dev": true, - "dependencies": { - "execa": "^5.0.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.2.1.tgz", - "integrity": "sha512-W+ZQQ5ln4Db2UZNM4NJIeasnhCdDhSuYW4eLgNAUi0XiSSpF634Kc5wiPvGiHvTgXMFVn1ZgWIijqhi9+kLNLg==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.2.1", - "@jest/expect": "^29.2.1", - "@jest/test-result": "^29.2.1", - "@jest/types": "^29.2.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.2.1", - "jest-matcher-utils": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-runtime": "^29.2.1", - "jest-snapshot": "^29.2.1", - "jest-util": "^29.2.1", - "p-limit": "^3.1.0", - "pretty-format": "^29.2.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-cli": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.2.1.tgz", - "integrity": "sha512-UIMD5aNqvPKpdlJSaeUAoLfxsh9TZvOkaMETx5qXnkboc317bcbb0eLHbIj8sFBHdcJAIAM+IRKnIU7Wi61MBw==", - "dev": true, - "dependencies": { - "@jest/core": "^29.2.1", - "@jest/test-result": "^29.2.1", - "@jest/types": "^29.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^29.2.1", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.1", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.2.1.tgz", - "integrity": "sha512-EV5F1tQYW/quZV2br2o88hnYEeRzG53Dfi6rSG3TZBuzGQ6luhQBux/RLlU5QrJjCdq3LXxRRM8F1LP6DN1ycA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.2.1", - "@jest/types": "^29.2.1", - "babel-jest": "^29.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.2.1", - "jest-environment-node": "^29.2.1", - "jest-get-type": "^29.2.0", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.2.1", - "jest-runner": "^29.2.1", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.2.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.2.1.tgz", - "integrity": "sha512-gfh/SMNlQmP3MOUgdzxPOd4XETDJifADpT937fN1iUGz+9DgOu2eUPHH25JDkLVcLwwqxv3GzVyK4VBUr9fjfA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.2.0", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.2.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", - "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-each": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.2.1.tgz", - "integrity": "sha512-sGP86H/CpWHMyK3qGIGFCgP6mt+o5tu9qG4+tobl0LNdgny0aitLXs9/EBacLy3Bwqy+v4uXClqJgASJWcruYw==", - "dev": true, - "dependencies": { - "@jest/types": "^29.2.1", - "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", - "jest-util": "^29.2.1", - "pretty-format": "^29.2.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.2.1.tgz", - "integrity": "sha512-PulFKwEMz6nTAdLUwglFKei3b/LixwlRiqTN6nvPE1JtrLtlnpd6LXnFI1NFHYJGlTmIWilMP2n9jEtPPKX50g==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.2.1", - "@jest/fake-timers": "^29.2.1", - "@jest/types": "^29.2.1", - "@types/node": "*", - "jest-mock": "^29.2.1", - "jest-util": "^29.2.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", - "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.2.1.tgz", - "integrity": "sha512-wF460rAFmYc6ARcCFNw4MbGYQjYkvjovb9GBT+W10Um8q5nHq98jD6fHZMDMO3tA56S8XnmNkM8GcA8diSZfnA==", - "dev": true, - "dependencies": { - "@jest/types": "^29.2.1", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.2.0", - "jest-util": "^29.2.1", - "jest-worker": "^29.2.1", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-leak-detector": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.2.1.tgz", - "integrity": "sha512-1YvSqYoiurxKOJtySc+CGVmw/e1v4yNY27BjWTVzp0aTduQeA7pdieLiW05wTYG/twlKOp2xS/pWuikQEmklug==", - "dev": true, - "dependencies": { - "jest-get-type": "^29.2.0", - "pretty-format": "^29.2.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.2.1.tgz", - "integrity": "sha512-hUTBh7H/Mnb6GTpihbLh8uF5rjAMdekfW/oZNXUMAXi7bbmym2HiRpzgqf/zzkjgejMrVAkPdVSQj+32enlUww==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.2.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.2.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.2.1.tgz", - "integrity": "sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.2.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.2.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-mock": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.2.1.tgz", - "integrity": "sha512-NDphaY/GqyQpTfnTZiTqqpMaw4Z0I7XnB7yBgrT6IwYrLGxpOhrejYr4ANY4YvO2sEGdd8Tx/6D0+WLQy7/qDA==", - "dev": true, - "dependencies": { - "@jest/types": "^29.2.1", - "@types/node": "*", - "jest-util": "^29.2.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", - "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.2.1.tgz", - "integrity": "sha512-1dJTW76Z9622Viq4yRcwBuEXuzGtE9B2kdl05RC8Om/lAzac9uEgC+M8Q5osVidbuBPmxm8wSrcItYhca2ZAtQ==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.2.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.2.1.tgz", - "integrity": "sha512-o3mUGX2j08usj1jIAIE8KmUVpqVAn54k80kI27ldbZf2oJn6eghhB6DvJxjrcH40va9CQgWTfU5f2Ag/MoUqgQ==", - "dev": true, - "dependencies": { - "jest-regex-util": "^29.2.0", - "jest-snapshot": "^29.2.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runner": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.2.1.tgz", - "integrity": "sha512-PojFI+uVhQ4u4YZKCN/a3yU0/l/pJJXhq1sW3JpCp8CyvGBYGddRFPKZ1WihApusxqWRTHjBJmGyPWv6Av2lWA==", - "dev": true, - "dependencies": { - "@jest/console": "^29.2.1", - "@jest/environment": "^29.2.1", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.1", - "@jest/types": "^29.2.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.2.0", - "jest-environment-node": "^29.2.1", - "jest-haste-map": "^29.2.1", - "jest-leak-detector": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-resolve": "^29.2.1", - "jest-runtime": "^29.2.1", - "jest-util": "^29.2.1", - "jest-watcher": "^29.2.1", - "jest-worker": "^29.2.1", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.2.1.tgz", - "integrity": "sha512-PSQ880OoIW9y8E6/jjhGn3eQNgNc6ndMzCZaKqy357bv7FqCfSyYepu3yDC6Sp1Vkt+GhP2M/PVgldS2uZSFZg==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.2.1", - "@jest/fake-timers": "^29.2.1", - "@jest/globals": "^29.2.1", - "@jest/source-map": "^29.2.0", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.1", - "@jest/types": "^29.2.1", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-mock": "^29.2.1", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.2.1", - "jest-snapshot": "^29.2.1", - "jest-util": "^29.2.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.2.1.tgz", - "integrity": "sha512-KZdLD7iEz5M4ZYd+ezZ/kk73z+DtNbk/yJ4Qx7408Vb0CCuclJIZPa/HmIwSsCfIlOBNcYTKufr7x/Yv47oYlg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.2.1", - "@jest/transform": "^29.2.1", - "@jest/types": "^29.2.1", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.2.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.2.1", - "jest-get-type": "^29.2.0", - "jest-haste-map": "^29.2.1", - "jest-matcher-utils": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1", - "natural-compare": "^1.4.0", - "pretty-format": "^29.2.1", - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.2.1.tgz", - "integrity": "sha512-P5VWDj25r7kj7kl4pN2rG/RN2c1TLfYYYZYULnS/35nFDjBai+hBeo3MDrYZS7p6IoY3YHZnt2vq4L6mKnLk0g==", - "dev": true, - "dependencies": { - "@jest/types": "^29.2.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.2.1.tgz", - "integrity": "sha512-DZVX5msG6J6DL5vUUw+++6LEkXUsPwB5R7fsfM7BXdz2Ipr0Ib046ak+8egrwAR++pvSM/5laxLK977ieIGxkQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.2.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", - "leven": "^3.1.0", - "pretty-format": "^29.2.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.2.1.tgz", - "integrity": "sha512-7jFaHUaRq50l4w/f6RuY713bvI5XskMmjWCE54NGYcY74fLkShS8LucXJke1QfGnwDSCoIqGnGGGKPwdaBYz2Q==", - "dev": true, - "dependencies": { - "@jest/test-result": "^29.2.1", - "@jest/types": "^29.2.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^29.2.1", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.2.1.tgz", - "integrity": "sha512-ROHTZ+oj7sBrgtv46zZ84uWky71AoYi0vEV9CdEtc1FQunsoAGe5HbQmW76nI5QWdvECVPrSi1MCVUmizSavMg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "jest-util": "^29.2.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true, - "engines": [ - "node >= 0.2.0" - ] - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.ismatch": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "dev": true - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", - "dev": true, - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/meow/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/modify-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", - "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-format": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.2.1.tgz", - "integrity": "sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "dev": true, - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", - "dev": true, - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", - "dev": true - }, - "node_modules/split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dev": true, - "dependencies": { - "readable-stream": "^3.0.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/standard-version": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.5.0.tgz", - "integrity": "sha512-3zWJ/mmZQsOaO+fOlsa0+QK90pwhNd042qEcw6hKFNoLFs7peGyvPffpEBbK/DSGPbyOvli0mUIFv5A4qTjh2Q==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2", - "conventional-changelog": "3.1.25", - "conventional-changelog-config-spec": "2.1.0", - "conventional-changelog-conventionalcommits": "4.6.3", - "conventional-recommended-bump": "6.1.0", - "detect-indent": "^6.0.0", - "detect-newline": "^3.1.0", - "dotgitignore": "^2.1.0", - "figures": "^3.1.0", - "find-up": "^5.0.0", - "git-semver-tags": "^4.0.0", - "semver": "^7.1.1", - "stringify-package": "^1.0.1", - "yargs": "^16.0.0" - }, - "bin": { - "standard-version": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/standard-version/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/standard-version/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/standard-version/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/standard-version/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/standard-version/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/standard-version/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/standard-version/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/standard-version/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/standard-version/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/stringify-package": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", - "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", - "dev": true - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-extensions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", - "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "dependencies": { - "readable-stream": "3" - } - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-jest": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz", - "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==", - "dev": true, - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.1", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^21.0.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-jest/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/uglify-js": { - "version": "3.17.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.3.tgz", - "integrity": "sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/uzip": { - "version": "0.20201231.0", - "resolved": "https://registry.npmjs.org/uzip/-/uzip-0.20201231.0.tgz", - "integrity": "sha512-OZeJfZP+R0z9D6TmBgLq2LHzSSptGMGDGigGiEe0pr8UBe/7fdflgHlHBNDASTXB5jnFuxHpNaJywSg8YFeGng==" - }, - "node_modules/v8-to-istanbul": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", - "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", - "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", - "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==", - "dev": true - }, - "@babel/core": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.6.tgz", - "integrity": "sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.6", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helpers": "^7.19.4", - "@babel/parser": "^7.19.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.6.tgz", - "integrity": "sha512-oHGRUQeoX1QrKeJIKVe0hwjGqNnVYsM5Nep5zo0uE0m42sLH+Fsd2pStJ5sRM1bNyTUUoz0pe2lTeMJrb/taTA==", - "dev": true, - "requires": { - "@babel/types": "^7.19.4", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } - } - }, - "@babel/helper-compilation-targets": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", - "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.19.3", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-transforms": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz", - "integrity": "sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.19.4", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", - "dev": true - }, - "@babel/helper-simple-access": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", - "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", - "dev": true, - "requires": { - "@babel/types": "^7.19.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true - }, - "@babel/helpers": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", - "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.4", - "@babel/types": "^7.19.4" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.6.tgz", - "integrity": "sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - } - }, - "@babel/traverse": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.6.tgz", - "integrity": "sha512-6l5HrUCzFM04mfbG09AagtYyR2P0B71B1wN7PfSPiksDPz2k5H9CBC1tcZpz2M8OxbKTPccByoOJ22rUKbpmQQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.6", - "@babel/types": "^7.19.4", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", - "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@esbuild/android-arm": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.12.tgz", - "integrity": "sha512-IC7TqIqiyE0MmvAhWkl/8AEzpOtbhRNDo7aph47We1NbE5w2bt/Q+giAhe0YYeVpYnIhGMcuZY92qDK6dQauvA==", - "dev": true, - "optional": true - }, - "@esbuild/linux-loong64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.12.tgz", - "integrity": "sha512-tZEowDjvU7O7I04GYvWQOS4yyP9E/7YlsB0jjw1Ycukgr2ycEzKyIk5tms5WnLBymaewc6VmRKnn5IJWgK4eFw==", - "dev": true, - "optional": true - }, - "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - } - }, - "@humanwhocodes/config-array": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.6.tgz", - "integrity": "sha512-jJr+hPTJYKyDILJfhNSHsjiwXYf26Flsz8DvNndOsHs5pwSnpGUEy8yzF0JYhCEvTDdV2vuOK5tt8BVhwO5/hg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@hutson/parse-repository-url": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", - "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.2.1.tgz", - "integrity": "sha512-MF8Adcw+WPLZGBiNxn76DOuczG3BhODTcMlDCA4+cFi41OkaY/lyI0XUUhi73F88Y+7IHoGmD80pN5CtxQUdSw==", + "node_modules/@jest/console": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.1.tgz", + "integrity": "sha512-m+XpwKSi3PPM9znm5NGS8bBReeAJJpSkL1OuFCqaMaJL2YX9YXLkkI+MBchMPwu+ZuM2rynL51sgfkQteQ1CKQ==", "dev": true, - "requires": { - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/types": "^29.4.1", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1", + "jest-message-util": "^29.4.1", + "jest-util": "^29.4.1", "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "@jest/core": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.2.1.tgz", - "integrity": "sha512-kuLKYqnqgerXkBUwlHVxeSuhSnd+JMnMCLfU98bpacBSfWEJPegytDh3P2m15/JHzet32hGGld4KR4OzMb6/Tg==", + "node_modules/@jest/core": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.4.1.tgz", + "integrity": "sha512-RXFTohpBqpaTebNdg5l3I5yadnKo9zLBajMT0I38D0tDhreVBYv3fA8kywthI00sWxPztWLD3yjiUkewwu/wKA==", "dev": true, - "requires": { - "@jest/console": "^29.2.1", - "@jest/reporters": "^29.2.1", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.1", - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/console": "^29.4.1", + "@jest/reporters": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.2.0", - "jest-config": "^29.2.1", - "jest-haste-map": "^29.2.1", - "jest-message-util": "^29.2.1", + "jest-changed-files": "^29.4.0", + "jest-config": "^29.4.1", + "jest-haste-map": "^29.4.1", + "jest-message-util": "^29.4.1", "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.2.1", - "jest-resolve-dependencies": "^29.2.1", - "jest-runner": "^29.2.1", - "jest-runtime": "^29.2.1", - "jest-snapshot": "^29.2.1", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.1", - "jest-watcher": "^29.2.1", + "jest-resolve": "^29.4.1", + "jest-resolve-dependencies": "^29.4.1", + "jest-runner": "^29.4.1", + "jest-runtime": "^29.4.1", + "jest-snapshot": "^29.4.1", + "jest-util": "^29.4.1", + "jest-validate": "^29.4.1", + "jest-watcher": "^29.4.1", "micromatch": "^4.0.4", - "pretty-format": "^29.2.1", + "pretty-format": "^29.4.1", "slash": "^3.0.0", "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "@jest/environment": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.2.1.tgz", - "integrity": "sha512-EutqA7T/X6zFjw6mAWRHND+ZkTPklmIEWCNbmwX6uCmOrFrWaLbDZjA+gePHJx6fFMMRvNfjXcvzXEtz54KPlg==", + "node_modules/@jest/environment": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.1.tgz", + "integrity": "sha512-pJ14dHGSQke7Q3mkL/UZR9ZtTOxqskZaC91NzamEH4dlKRt42W+maRBXiw/LWkdJe+P0f/zDR37+SPMplMRlPg==", "dev": true, - "requires": { - "@jest/fake-timers": "^29.2.1", - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/fake-timers": "^29.4.1", + "@jest/types": "^29.4.1", "@types/node": "*", - "jest-mock": "^29.2.1" + "jest-mock": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "@jest/expect": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.2.1.tgz", - "integrity": "sha512-o14R2t2tHHHudwji43UKkzmmH49xfF5T++FQBK2tl88qwuBWQOcx7fNUYl+mA/9TPNAN0FkQ3usnpyS8FUwsvQ==", + "node_modules/@jest/expect": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.1.tgz", + "integrity": "sha512-ZxKJP5DTUNF2XkpJeZIzvnzF1KkfrhEF6Rz0HGG69fHl6Bgx5/GoU3XyaeFYEjuuKSOOsbqD/k72wFvFxc3iTw==", "dev": true, - "requires": { - "expect": "^29.2.1", - "jest-snapshot": "^29.2.1" + "dependencies": { + "expect": "^29.4.1", + "jest-snapshot": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "@jest/expect-utils": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.2.1.tgz", - "integrity": "sha512-yr4aHNg5Z1CjKby5ozm7sKjgBlCOorlAoFcvrOQ/4rbZRfgZQdnmh7cth192PYIgiPZo2bBXvqdOApnAMWFJZg==", + "node_modules/@jest/expect-utils": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.1.tgz", + "integrity": "sha512-w6YJMn5DlzmxjO00i9wu2YSozUYRBhIoJ6nQwpMYcBMtiqMGJm1QBzOf6DDgRao8dbtpDoaqLg6iiQTvv0UHhQ==", "dev": true, - "requires": { + "dependencies": { "jest-get-type": "^29.2.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "@jest/fake-timers": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.2.1.tgz", - "integrity": "sha512-KWil+8fef7Uj/P/PTZlPKk1Pw117wAmr71VWFV8ZDtRtkwmTG8oY4IRf0Ss44J2y5CYRy8d/zLOhxyoGRENjvA==", + "node_modules/@jest/fake-timers": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.1.tgz", + "integrity": "sha512-/1joI6rfHFmmm39JxNfmNAO3Nwm6Y0VoL5fJDy7H1AtWrD1CgRtqJbN9Ld6rhAkGO76qqp4cwhhxJ9o9kYjQMw==", "dev": true, - "requires": { - "@jest/types": "^29.2.1", - "@sinonjs/fake-timers": "^9.1.2", + "dependencies": { + "@jest/types": "^29.4.1", + "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.2.1", - "jest-mock": "^29.2.1", - "jest-util": "^29.2.1" + "jest-message-util": "^29.4.1", + "jest-mock": "^29.4.1", + "jest-util": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "@jest/globals": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.2.1.tgz", - "integrity": "sha512-Z4EejYPP1OPVq2abk1+9urAwJqkgw5jB2UJGlPjb5ZwzPQF8WLMcigKEfFzZb2OHhEVPP0RZD0/DbVTY1R6iQA==", + "node_modules/@jest/globals": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.1.tgz", + "integrity": "sha512-znoK2EuFytbHH0ZSf2mQK2K1xtIgmaw4Da21R2C/NE/+NnItm5mPEFQmn8gmF3f0rfOlmZ3Y3bIf7bFj7DHxAA==", "dev": true, - "requires": { - "@jest/environment": "^29.2.1", - "@jest/expect": "^29.2.1", - "@jest/types": "^29.2.1", - "jest-mock": "^29.2.1" + "dependencies": { + "@jest/environment": "^29.4.1", + "@jest/expect": "^29.4.1", + "@jest/types": "^29.4.1", + "jest-mock": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "@jest/reporters": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.2.1.tgz", - "integrity": "sha512-sCsfUKM/yIF4nNed3e/rIgVIS58EiASGMDEPWqItfLZ9UO1ALW2ASDNJzdWkxEt0T8o2Ztj619G0KKrvK+McAw==", + "node_modules/@jest/reporters": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.4.1.tgz", + "integrity": "sha512-AISY5xpt2Xpxj9R6y0RF1+O6GRy9JsGa8+vK23Lmzdy1AYcpQn5ItX79wJSsTmfzPKSAcsY1LNt/8Y5Xe5LOSg==", "dev": true, - "requires": { + "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.2.1", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.1", - "@jest/types": "^29.2.1", + "@jest/console": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", "@jridgewell/trace-mapping": "^0.3.15", "@types/node": "*", "chalk": "^4.0.0", @@ -7479,571 +1323,761 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1", - "jest-worker": "^29.2.1", + "jest-message-util": "^29.4.1", + "jest-util": "^29.4.1", + "jest-worker": "^29.4.1", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "node_modules/@jest/schemas": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.0.tgz", + "integrity": "sha512-0E01f/gOZeNTG76i5eWWSupvSHaIINrTie7vCyjiYFKgzNdyEGd12BUv4oNBFHOqlHDbtoJi3HrQ38KCC90NsQ==", "dev": true, - "requires": { - "@sinclair/typebox": "^0.24.1" + "dependencies": { + "@sinclair/typebox": "^0.25.16" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "@jest/source-map": { + "node_modules/@jest/source-map": { "version": "29.2.0", "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", "dev": true, - "requires": { + "dependencies": { "@jridgewell/trace-mapping": "^0.3.15", "callsites": "^3.0.0", "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "@jest/test-result": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.2.1.tgz", - "integrity": "sha512-lS4+H+VkhbX6z64tZP7PAUwPqhwj3kbuEHcaLuaBuB+riyaX7oa1txe0tXgrFj5hRWvZKvqO7LZDlNWeJ7VTPA==", + "node_modules/@jest/test-result": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.1.tgz", + "integrity": "sha512-WRt29Lwt+hEgfN8QDrXqXGgCTidq1rLyFqmZ4lmJOpVArC8daXrZWkWjiaijQvgd3aOUj2fM8INclKHsQW9YyQ==", "dev": true, - "requires": { - "@jest/console": "^29.2.1", - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/console": "^29.4.1", + "@jest/types": "^29.4.1", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "@jest/test-sequencer": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.2.1.tgz", - "integrity": "sha512-O/pnk0/xGj3lxPVNwB6HREJ7AYvUdyP2xo/s14/9Dtf091HoOeyIhWLKQE/4HzB8lNQBMo6J5mg0bHz/uCWK7w==", + "node_modules/@jest/test-sequencer": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.4.1.tgz", + "integrity": "sha512-v5qLBNSsM0eHzWLXsQ5fiB65xi49A3ILPSFQKPXzGL4Vyux0DPZAIN7NAFJa9b4BiTDP9MBF/Zqc/QA1vuiJ0w==", "dev": true, - "requires": { - "@jest/test-result": "^29.2.1", + "dependencies": { + "@jest/test-result": "^29.4.1", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.2.1", + "jest-haste-map": "^29.4.1", "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "@jest/transform": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.2.1.tgz", - "integrity": "sha512-xup+iEuaIRSQabQaeqxaQyN0vg1Dctrp9oTObQsNf3sZEowTIa5cANYuoyi8Tqhg4GCqEVLTf18KW7ii0UeFVA==", + "node_modules/@jest/transform": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.1.tgz", + "integrity": "sha512-5w6YJrVAtiAgr0phzKjYd83UPbCXsBRTeYI4BXokv9Er9CcrH9hfXL/crCvP2d2nGOcovPUnlYiLPFLZrkG5Hg==", "dev": true, - "requires": { + "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.2.1", + "@jest/types": "^29.4.1", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", + "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.2.1", + "jest-haste-map": "^29.4.1", "jest-regex-util": "^29.2.0", - "jest-util": "^29.2.1", + "jest-util": "^29.4.1", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" + "write-file-atomic": "^5.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "@jest/types": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.2.1.tgz", - "integrity": "sha512-O/QNDQODLnINEPAI0cl9U6zUIDXEWXt6IC1o2N2QENuos7hlGUIthlKyV4p6ki3TvXFX071blj8HUhgLGquPjw==", + "node_modules/@jest/types": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.1.tgz", + "integrity": "sha512-zbrAXDUOnpJ+FMST2rV7QZOgec8rskg2zv8g2ajeqitp4tvZiyqTCYXANrKsM+ryj5o+LI+ZN2EgU9drrkiwSA==", "dev": true, - "requires": { - "@jest/schemas": "^29.0.0", + "dependencies": { + "@jest/schemas": "^29.4.0", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "@jridgewell/gen-mapping": { + "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", "dev": true, - "requires": { + "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" } }, - "@jridgewell/resolve-uri": { + "node_modules/@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.0.0" + } }, - "@jridgewell/set-array": { + "node_modules/@jridgewell/set-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.0.0" + } }, - "@jridgewell/sourcemap-codec": { + "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, - "@jridgewell/trace-mapping": { + "node_modules/@jridgewell/trace-mapping": { "version": "0.3.17", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, - "requires": { + "dependencies": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" } }, - "@nodelib/fs.scandir": { + "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "requires": { + "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "@nodelib/fs.stat": { + "node_modules/@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true + "dev": true, + "engines": { + "node": ">= 8" + } }, - "@nodelib/fs.walk": { + "node_modules/@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "requires": { + "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" } }, - "@sinclair/typebox": { - "version": "0.24.50", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.50.tgz", - "integrity": "sha512-k8ETQOOQDg5FtK7y9KJWpsGLik+QlPmIi8zzl/dGUgshV2QitprkFlCR/AemjWOTyKn9UwSSGRTzLVotvgCjYQ==", + "node_modules/@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", "dev": true }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", "dev": true, - "requires": { + "dependencies": { "type-detect": "4.0.8" } }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "node_modules/@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" + "dependencies": { + "@sinonjs/commons": "^2.0.0" } }, - "@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "node_modules/@types/babel__core": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, - "@types/babel__generator": { + "node_modules/@types/babel__generator": { "version": "7.6.4", "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.0.0" } }, - "@types/babel__template": { + "node_modules/@types/babel__template": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, - "requires": { + "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, - "@types/babel__traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", - "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", + "node_modules/@types/babel__traverse": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.3.0" } }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", "dev": true, - "requires": { + "dependencies": { "@types/node": "*" } }, - "@types/istanbul-lib-coverage": { + "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, - "@types/istanbul-lib-report": { + "node_modules/@types/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "dev": true, - "requires": { + "dependencies": { "@types/istanbul-lib-coverage": "*" } }, - "@types/istanbul-reports": { + "node_modules/@types/istanbul-reports": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, - "requires": { + "dependencies": { "@types/istanbul-lib-report": "*" } }, - "@types/jest": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.0.tgz", - "integrity": "sha512-KO7bPV21d65PKwv3LLsD8Jn3E05pjNjRZvkm+YTacWhVmykAb07wW6IkZUmQAltwQafNcDUEUrMO2h3jeBSisg==", + "node_modules/@types/jest": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.4.0.tgz", + "integrity": "sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==", "dev": true, - "requires": { + "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" } }, - "@types/json-schema": { + "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, - "@types/minimist": { + "node_modules/@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, - "@types/node": { - "version": "18.11.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.3.tgz", - "integrity": "sha512-fNjDQzzOsZeKZu5NATgXUPsaFaTxeRgFXoosrHivTl8RGeV733OLawXsGfEk9a8/tySyZUyiZ6E8LcjPFZ2y1A==", + "node_modules/@types/node": { + "version": "18.11.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.19.tgz", + "integrity": "sha512-YUgMWAQBWLObABqrvx8qKO1enAvBUdjZOAWQ5grBAkp5LQv45jBvYKZ3oFS9iKRCQyFjqw6iuEa1vmFqtxYLZw==", "dev": true }, - "@types/normalize-package-data": { + "node_modules/@types/normalize-package-data": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, - "@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", + "node_modules/@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", "dev": true }, - "@types/semver": { - "version": "7.3.12", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz", - "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==", + "node_modules/@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, - "@types/stack-utils": { + "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, - "@types/uzip": { + "node_modules/@types/uzip": { "version": "0.20201231.0", "resolved": "https://registry.npmjs.org/@types/uzip/-/uzip-0.20201231.0.tgz", "integrity": "sha512-h5QS4GArSRa0VqWC30rQ8q/WjDwmTrFFMOulFQUAEjhL9zUApefLnpF2Y7ZRNrfMqCjKnWGxs2AtYrN6/t699w==", "dev": true }, - "@types/yargs": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", - "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", + "node_modules/@types/yargs": { + "version": "17.0.22", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", + "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", "dev": true, - "requires": { + "dependencies": { "@types/yargs-parser": "*" } }, - "@types/yargs-parser": { + "node_modules/@types/yargs-parser": { "version": "21.0.0", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, - "@typescript-eslint/eslint-plugin": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.1.tgz", - "integrity": "sha512-FsWboKkWdytGiXT5O1/R9j37YgcjO8MKHSUmWnIEjVaz0krHkplPnYi7mwdb+5+cs0toFNQb0HIrN7zONdIEWg==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.51.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.51.0.tgz", + "integrity": "sha512-wcAwhEWm1RgNd7dxD/o+nnLW8oH+6RK1OGnmbmkj/GGoDPV1WWMVP0FXYQBivKHdwM1pwii3bt//RC62EriIUQ==", "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/type-utils": "5.40.1", - "@typescript-eslint/utils": "5.40.1", + "dependencies": { + "@typescript-eslint/scope-manager": "5.51.0", + "@typescript-eslint/type-utils": "5.51.0", + "@typescript-eslint/utils": "5.51.0", "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "@typescript-eslint/parser": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.1.tgz", - "integrity": "sha512-IK6x55va5w4YvXd4b3VrXQPldV9vQTxi5ov+g4pMANsXPTXOcfjx08CRR1Dfrcc51syPtXHF5bgLlMHYFrvQtg==", + "node_modules/@typescript-eslint/parser": { + "version": "5.51.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.51.0.tgz", + "integrity": "sha512-fEV0R9gGmfpDeRzJXn+fGQKcl0inIeYobmmUWijZh9zA7bxJ8clPhV9up2ZQzATxAiFAECqPQyMDB4o4B81AaA==", "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/typescript-estree": "5.40.1", + "dependencies": { + "@typescript-eslint/scope-manager": "5.51.0", + "@typescript-eslint/types": "5.51.0", + "@typescript-eslint/typescript-estree": "5.51.0", "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "@typescript-eslint/scope-manager": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.1.tgz", - "integrity": "sha512-jkn4xsJiUQucI16OLCXrLRXDZ3afKhOIqXs4R3O+M00hdQLKR58WuyXPZZjhKLFCEP2g+TXdBRtLQ33UfAdRUg==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.51.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.51.0.tgz", + "integrity": "sha512-gNpxRdlx5qw3yaHA0SFuTjW4rxeYhpHxt491PEcKF8Z6zpq0kMhe0Tolxt0qjlojS+/wArSDlj/LtE69xUJphQ==", "dev": true, - "requires": { - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/visitor-keys": "5.40.1" + "dependencies": { + "@typescript-eslint/types": "5.51.0", + "@typescript-eslint/visitor-keys": "5.51.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "@typescript-eslint/type-utils": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.40.1.tgz", - "integrity": "sha512-DLAs+AHQOe6n5LRraXiv27IYPhleF0ldEmx6yBqBgBLaNRKTkffhV1RPsjoJBhVup2zHxfaRtan8/YRBgYhU9Q==", + "node_modules/@typescript-eslint/type-utils": { + "version": "5.51.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.51.0.tgz", + "integrity": "sha512-QHC5KKyfV8sNSyHqfNa0UbTbJ6caB8uhcx2hYcWVvJAZYJRBo5HyyZfzMdRx8nvS+GyMg56fugMzzWnojREuQQ==", "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "5.40.1", - "@typescript-eslint/utils": "5.40.1", + "dependencies": { + "@typescript-eslint/typescript-estree": "5.51.0", + "@typescript-eslint/utils": "5.51.0", "debug": "^4.3.4", "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "@typescript-eslint/types": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.1.tgz", - "integrity": "sha512-Icg9kiuVJSwdzSQvtdGspOlWNjVDnF3qVIKXdJ103o36yRprdl3Ge5cABQx+csx960nuMF21v8qvO31v9t3OHw==", - "dev": true + "node_modules/@typescript-eslint/types": { + "version": "5.51.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.51.0.tgz", + "integrity": "sha512-SqOn0ANn/v6hFn0kjvLwiDi4AzR++CBZz0NV5AnusT2/3y32jdc0G4woXPWHCumWtUXZKPAS27/9vziSsC9jnw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } }, - "@typescript-eslint/typescript-estree": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.1.tgz", - "integrity": "sha512-5QTP/nW5+60jBcEPfXy/EZL01qrl9GZtbgDZtDPlfW5zj/zjNrdI2B5zMUHmOsfvOr2cWqwVdWjobCiHcedmQA==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.51.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.51.0.tgz", + "integrity": "sha512-TSkNupHvNRkoH9FMA3w7TazVFcBPveAAmb7Sz+kArY6sLT86PA5Vx80cKlYmd8m3Ha2SwofM1KwraF24lM9FvA==", "dev": true, - "requires": { - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/visitor-keys": "5.40.1", + "dependencies": { + "@typescript-eslint/types": "5.51.0", + "@typescript-eslint/visitor-keys": "5.51.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", "semver": "^7.3.7", "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "@typescript-eslint/utils": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.40.1.tgz", - "integrity": "sha512-a2TAVScoX9fjryNrW6BZRnreDUszxqm9eQ9Esv8n5nXApMW0zeANUYlwh/DED04SC/ifuBvXgZpIK5xeJHQ3aw==", + "node_modules/@typescript-eslint/utils": { + "version": "5.51.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.51.0.tgz", + "integrity": "sha512-76qs+5KWcaatmwtwsDJvBk4H76RJQBFe+Gext0EfJdC3Vd2kpY2Pf//OHHzHp84Ciw0/rYoGTDnIAr3uWhhJYw==", "dev": true, - "requires": { + "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/typescript-estree": "5.40.1", + "@typescript-eslint/scope-manager": "5.51.0", + "@typescript-eslint/types": "5.51.0", + "@typescript-eslint/typescript-estree": "5.51.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "@typescript-eslint/visitor-keys": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.1.tgz", - "integrity": "sha512-A2DGmeZ+FMja0geX5rww+DpvILpwo1OsiQs0M+joPWJYsiEFBLsH0y1oFymPNul6Z5okSmHpP4ivkc2N0Cgfkw==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.51.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.51.0.tgz", + "integrity": "sha512-Oh2+eTdjHjOFjKA27sxESlA87YPSOJafGCR0md5oeMdh1ZcCfAGCIOL216uTBAkAIptvLIfKQhl7lHxMJet4GQ==", "dev": true, - "requires": { - "@typescript-eslint/types": "5.40.1", + "dependencies": { + "@typescript-eslint/types": "5.51.0", "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, - "acorn-jsx": { + "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "requires": {} + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, - "add-stream": { + "node_modules/add-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", "dev": true }, - "ajv": { + "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "requires": { + "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "ansi-escapes": { + "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, - "requires": { + "dependencies": { "type-fest": "^0.21.3" }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "ansi-regex": { + "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "ansi-styles": { + "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { + "dependencies": { "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "requires": { + "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "argparse": { + "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "array-ify": { + "node_modules/array-ify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", "dev": true }, - "array-union": { + "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "arrify": { + "node_modules/arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "babel-jest": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.2.1.tgz", - "integrity": "sha512-gQJwArok0mqoREiCYhXKWOgUhElJj9DpnssW6GL8dG7ARYqHEhrM9fmPHTjdqEGRVXZAd6+imo3/Vwa8TjLcsw==", + "node_modules/babel-jest": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.1.tgz", + "integrity": "sha512-xBZa/pLSsF/1sNpkgsiT3CmY7zV1kAsZ9OxxtrFqYucnOuRftXAfcJqcDVyOPeN4lttWTwhLdu0T9f8uvoPEUg==", "dev": true, - "requires": { - "@jest/transform": "^29.2.1", + "dependencies": { + "@jest/transform": "^29.4.1", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.2.0", + "babel-preset-jest": "^29.4.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "babel-plugin-istanbul": { + "node_modules/babel-plugin-istanbul": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-instrument": "^5.0.4", "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" } }, - "babel-plugin-jest-hoist": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz", - "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==", + "node_modules/babel-plugin-jest-hoist": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.0.tgz", + "integrity": "sha512-a/sZRLQJEmsmejQ2rPEUe35nO1+C9dc9O1gplH1SXmJxveQSRUYdBk8yGZG/VOUuZs1u2aHZJusEGoRMbhhwCg==", "dev": true, - "requires": { + "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", "@types/babel__core": "^7.1.14", "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-preset-current-node-syntax": { + "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, - "requires": { + "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", "@babel/plugin-syntax-class-properties": "^7.8.3", @@ -8056,208 +2090,292 @@ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "babel-preset-jest": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz", - "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==", + "node_modules/babel-preset-jest": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.4.0.tgz", + "integrity": "sha512-fUB9vZflUSM3dO/6M2TCAepTzvA4VkOvl67PjErcrQMGt9Eve7uazaeyCZ2th3UtI7ljpiBJES0F7A1vBRsLZA==", "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^29.2.0", + "dependencies": { + "babel-plugin-jest-hoist": "^29.4.0", "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "balanced-match": { + "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "brace-expansion": { + "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "requires": { + "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "braces": { + "node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "requires": { + "dependencies": { "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" } }, - "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "node_modules/browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "bs-logger": { + "node_modules/bs-logger": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, - "requires": { + "dependencies": { "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" } }, - "bser": { + "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, - "requires": { + "dependencies": { "node-int64": "^0.4.0" } }, - "buffer-from": { + "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "callsites": { + "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "camelcase": { + "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "camelcase-keys": { + "node_modules/camelcase-keys": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, - "requires": { + "dependencies": { "camelcase": "^5.3.1", "map-obj": "^4.0.0", "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "caniuse-lite": { - "version": "1.0.30001423", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001423.tgz", - "integrity": "sha512-09iwWGOlifvE1XuHokFMP7eR38a0JnajoyL3/i87c8ZjRWRrdKo1fqjNfugfBD0UDBIOz0U+jtNhJ0EPm1VleQ==", - "dev": true + "node_modules/caniuse-lite": { + "version": "1.0.30001450", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001450.tgz", + "integrity": "sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] }, - "chalk": { + "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "char-regex": { + "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + } }, - "ci-info": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", - "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", - "dev": true + "node_modules/ci-info": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz", + "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } }, - "cjs-module-lexer": { + "node_modules/cjs-module-lexer": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, - "cliui": { + "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "requires": { + "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "co": { + "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } }, - "collect-v8-coverage": { + "node_modules/collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, - "color-convert": { + "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { + "dependencies": { "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "color-name": { + "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "compare-func": { + "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", "dev": true, - "requires": { + "dependencies": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" } }, - "concat-map": { + "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "concat-stream": { + "node_modules/concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "dev": true, - "requires": { + "engines": [ + "node >= 6.0" + ], + "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, - "conventional-changelog": { + "node_modules/conventional-changelog": { "version": "3.1.25", "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==", "dev": true, - "requires": { + "dependencies": { "conventional-changelog-angular": "^5.0.12", "conventional-changelog-atom": "^2.0.8", "conventional-changelog-codemirror": "^2.0.8", @@ -8269,59 +2387,74 @@ "conventional-changelog-jquery": "^3.0.11", "conventional-changelog-jshint": "^2.0.9", "conventional-changelog-preset-loader": "^2.3.4" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-angular": { + "node_modules/conventional-changelog-angular": { "version": "5.0.13", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", "dev": true, - "requires": { + "dependencies": { "compare-func": "^2.0.0", "q": "^1.5.1" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-atom": { + "node_modules/conventional-changelog-atom": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", "dev": true, - "requires": { + "dependencies": { "q": "^1.5.1" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-codemirror": { + "node_modules/conventional-changelog-codemirror": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", "dev": true, - "requires": { + "dependencies": { "q": "^1.5.1" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-config-spec": { + "node_modules/conventional-changelog-config-spec": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", "dev": true }, - "conventional-changelog-conventionalcommits": { + "node_modules/conventional-changelog-conventionalcommits": { "version": "4.6.3", "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz", "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==", "dev": true, - "requires": { + "dependencies": { "compare-func": "^2.0.0", "lodash": "^4.17.15", "q": "^1.5.1" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-core": { + "node_modules/conventional-changelog-core": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", "dev": true, - "requires": { + "dependencies": { "add-stream": "^1.0.0", "conventional-changelog-writer": "^5.0.0", "conventional-commits-parser": "^3.2.0", @@ -8336,66 +2469,87 @@ "read-pkg": "^3.0.0", "read-pkg-up": "^3.0.0", "through2": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-ember": { + "node_modules/conventional-changelog-ember": { "version": "2.0.9", "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", "dev": true, - "requires": { + "dependencies": { "q": "^1.5.1" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-eslint": { + "node_modules/conventional-changelog-eslint": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", "dev": true, - "requires": { + "dependencies": { "q": "^1.5.1" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-express": { + "node_modules/conventional-changelog-express": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", "dev": true, - "requires": { + "dependencies": { "q": "^1.5.1" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-jquery": { + "node_modules/conventional-changelog-jquery": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", "dev": true, - "requires": { + "dependencies": { "q": "^1.5.1" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-jshint": { + "node_modules/conventional-changelog-jshint": { "version": "2.0.9", "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", "dev": true, - "requires": { + "dependencies": { "compare-func": "^2.0.0", "q": "^1.5.1" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-preset-loader": { + "node_modules/conventional-changelog-preset-loader": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + } }, - "conventional-changelog-writer": { + "node_modules/conventional-changelog-writer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", "dev": true, - "requires": { + "dependencies": { "conventional-commits-filter": "^2.0.7", "dateformat": "^3.0.0", "handlebars": "^4.7.7", @@ -8406,45 +2560,61 @@ "split": "^1.0.0", "through2": "^4.0.0" }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" } }, - "conventional-commits-filter": { + "node_modules/conventional-commits-filter": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", "dev": true, - "requires": { + "dependencies": { "lodash.ismatch": "^4.4.0", "modify-values": "^1.0.0" + }, + "engines": { + "node": ">=10" } }, - "conventional-commits-parser": { + "node_modules/conventional-commits-parser": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", "dev": true, - "requires": { + "dependencies": { "is-text-path": "^1.0.1", "JSONStream": "^1.0.4", "lodash": "^4.17.15", "meow": "^8.0.0", "split2": "^3.0.0", "through2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=10" } }, - "conventional-recommended-bump": { + "node_modules/conventional-recommended-bump": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", "dev": true, - "requires": { + "dependencies": { "concat-stream": "^2.0.0", "conventional-changelog-preset-loader": "^2.3.4", "conventional-commits-filter": "^2.0.7", @@ -8453,411 +2623,366 @@ "git-semver-tags": "^4.1.1", "meow": "^8.0.0", "q": "^1.5.1" + }, + "bin": { + "conventional-recommended-bump": "cli.js" + }, + "engines": { + "node": ">=10" } }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "core-util-is": { + "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, - "cross-spawn": { + "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "requires": { + "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "dargs": { + "node_modules/dargs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "dateformat": { + "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "debug": { + "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, - "requires": { + "dependencies": { "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "decamelize": { + "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "decamelize-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==", + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, - "requires": { + "dependencies": { "decamelize": "^1.1.0", "map-obj": "^1.0.0" }, - "dependencies": { - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true - } + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "dedent": { + "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, - "deep-is": { + "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true + "node_modules/deepmerge": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz", + "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "detect-indent": { + "node_modules/detect-indent": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "detect-newline": { + "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "diff-sequences": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.2.0.tgz", - "integrity": "sha512-413SY5JpYeSBZxmenGEmCVQ8mCgtFJF0w9PROdaS6z987XC2Pd2GOKqOITLtMftmyFZqgtCOb/QA7/Z3ZXfzIw==", - "dev": true + "node_modules/diff-sequences": { + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", + "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "dir-glob": { + "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "requires": { + "dependencies": { "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "doctrine": { + "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "requires": { + "dependencies": { "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotgitignore": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", + "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotgitignore/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotgitignore/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotgitignore/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dotgitignore/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" } }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "node_modules/dotgitignore/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true, - "requires": { - "is-obj": "^2.0.0" + "engines": { + "node": ">=4" } }, - "dotgitignore": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", - "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", + "node_modules/electron-to-chromium": { + "version": "1.4.286", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.286.tgz", + "integrity": "sha512-Vp3CVhmYpgf4iXNKAucoQUDcCrBQX3XLBtwgFqP9BUXuucgvAV9zWp1kYU7LL9j4++s9O+12cb3wMtN4SJy6UQ==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, - "requires": { - "find-up": "^3.0.0", - "minimatch": "^3.0.4" + "engines": { + "node": ">=12" }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - } + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "emittery": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", - "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", - "dev": true - }, - "emoji-regex": { + "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "error-ex": { + "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, - "requires": { + "dependencies": { "is-arrayish": "^0.2.1" } }, - "esbuild": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.12.tgz", - "integrity": "sha512-PcT+/wyDqJQsRVhaE9uX/Oq4XLrFh0ce/bs2TJh4CSaw9xuvI+xFrH2nAYOADbhQjUgAhNWC5LKoUsakm4dxng==", + "node_modules/esbuild": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.6.tgz", + "integrity": "sha512-TKFRp9TxrJDdRWfSsSERKEovm6v30iHnrjlcGhLBOtReE28Yp1VSBRfO3GTaOFMoxsNerx4TjrhzSuma9ha83Q==", "dev": true, - "requires": { - "@esbuild/android-arm": "0.15.12", - "@esbuild/linux-loong64": "0.15.12", - "esbuild-android-64": "0.15.12", - "esbuild-android-arm64": "0.15.12", - "esbuild-darwin-64": "0.15.12", - "esbuild-darwin-arm64": "0.15.12", - "esbuild-freebsd-64": "0.15.12", - "esbuild-freebsd-arm64": "0.15.12", - "esbuild-linux-32": "0.15.12", - "esbuild-linux-64": "0.15.12", - "esbuild-linux-arm": "0.15.12", - "esbuild-linux-arm64": "0.15.12", - "esbuild-linux-mips64le": "0.15.12", - "esbuild-linux-ppc64le": "0.15.12", - "esbuild-linux-riscv64": "0.15.12", - "esbuild-linux-s390x": "0.15.12", - "esbuild-netbsd-64": "0.15.12", - "esbuild-openbsd-64": "0.15.12", - "esbuild-sunos-64": "0.15.12", - "esbuild-windows-32": "0.15.12", - "esbuild-windows-64": "0.15.12", - "esbuild-windows-arm64": "0.15.12" + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.6", + "@esbuild/android-arm64": "0.17.6", + "@esbuild/android-x64": "0.17.6", + "@esbuild/darwin-arm64": "0.17.6", + "@esbuild/darwin-x64": "0.17.6", + "@esbuild/freebsd-arm64": "0.17.6", + "@esbuild/freebsd-x64": "0.17.6", + "@esbuild/linux-arm": "0.17.6", + "@esbuild/linux-arm64": "0.17.6", + "@esbuild/linux-ia32": "0.17.6", + "@esbuild/linux-loong64": "0.17.6", + "@esbuild/linux-mips64el": "0.17.6", + "@esbuild/linux-ppc64": "0.17.6", + "@esbuild/linux-riscv64": "0.17.6", + "@esbuild/linux-s390x": "0.17.6", + "@esbuild/linux-x64": "0.17.6", + "@esbuild/netbsd-x64": "0.17.6", + "@esbuild/openbsd-x64": "0.17.6", + "@esbuild/sunos-x64": "0.17.6", + "@esbuild/win32-arm64": "0.17.6", + "@esbuild/win32-ia32": "0.17.6", + "@esbuild/win32-x64": "0.17.6" } }, - "esbuild-android-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.12.tgz", - "integrity": "sha512-MJKXwvPY9g0rGps0+U65HlTsM1wUs9lbjt5CU19RESqycGFDRijMDQsh68MtbzkqWSRdEtiKS1mtPzKneaAI0Q==", - "dev": true, - "optional": true - }, - "esbuild-android-arm64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.12.tgz", - "integrity": "sha512-Hc9SEcZbIMhhLcvhr1DH+lrrec9SFTiRzfJ7EGSBZiiw994gfkVV6vG0sLWqQQ6DD7V4+OggB+Hn0IRUdDUqvA==", - "dev": true, - "optional": true - }, - "esbuild-darwin-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.12.tgz", - "integrity": "sha512-qkmqrTVYPFiePt5qFjP8w/S+GIUMbt6k8qmiPraECUWfPptaPJUGkCKrWEfYFRWB7bY23FV95rhvPyh/KARP8Q==", - "dev": true, - "optional": true - }, - "esbuild-darwin-arm64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.12.tgz", - "integrity": "sha512-z4zPX02tQ41kcXMyN3c/GfZpIjKoI/BzHrdKUwhC/Ki5BAhWv59A9M8H+iqaRbwpzYrYidTybBwiZAIWCLJAkw==", - "dev": true, - "optional": true - }, - "esbuild-freebsd-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.12.tgz", - "integrity": "sha512-XFL7gKMCKXLDiAiBjhLG0XECliXaRLTZh6hsyzqUqPUf/PY4C6EJDTKIeqqPKXaVJ8+fzNek88285krSz1QECw==", - "dev": true, - "optional": true - }, - "esbuild-freebsd-arm64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.12.tgz", - "integrity": "sha512-jwEIu5UCUk6TjiG1X+KQnCGISI+ILnXzIzt9yDVrhjug2fkYzlLbl0K43q96Q3KB66v6N1UFF0r5Ks4Xo7i72g==", - "dev": true, - "optional": true - }, - "esbuild-linux-32": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.12.tgz", - "integrity": "sha512-uSQuSEyF1kVzGzuIr4XM+v7TPKxHjBnLcwv2yPyCz8riV8VUCnO/C4BF3w5dHiVpCd5Z1cebBtZJNlC4anWpwA==", - "dev": true, - "optional": true - }, - "esbuild-linux-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.12.tgz", - "integrity": "sha512-QcgCKb7zfJxqT9o5z9ZUeGH1k8N6iX1Y7VNsEi5F9+HzN1OIx7ESxtQXDN9jbeUSPiRH1n9cw6gFT3H4qbdvcA==", - "dev": true, - "optional": true - }, - "esbuild-linux-arm": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.12.tgz", - "integrity": "sha512-Wf7T0aNylGcLu7hBnzMvsTfEXdEdJY/hY3u36Vla21aY66xR0MS5I1Hw8nVquXjTN0A6fk/vnr32tkC/C2lb0A==", - "dev": true, - "optional": true - }, - "esbuild-linux-arm64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.12.tgz", - "integrity": "sha512-HtNq5xm8fUpZKwWKS2/YGwSfTF+339L4aIA8yphNKYJckd5hVdhfdl6GM2P3HwLSCORS++++7++//ApEwXEuAQ==", - "dev": true, - "optional": true - }, - "esbuild-linux-mips64le": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.12.tgz", - "integrity": "sha512-Qol3+AvivngUZkTVFgLpb0H6DT+N5/zM3V1YgTkryPYFeUvuT5JFNDR3ZiS6LxhyF8EE+fiNtzwlPqMDqVcc6A==", - "dev": true, - "optional": true - }, - "esbuild-linux-ppc64le": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.12.tgz", - "integrity": "sha512-4D8qUCo+CFKaR0cGXtGyVsOI7w7k93Qxb3KFXWr75An0DHamYzq8lt7TNZKoOq/Gh8c40/aKaxvcZnTgQ0TJNg==", - "dev": true, - "optional": true - }, - "esbuild-linux-riscv64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.12.tgz", - "integrity": "sha512-G9w6NcuuCI6TUUxe6ka0enjZHDnSVK8bO+1qDhMOCtl7Tr78CcZilJj8SGLN00zO5iIlwNRZKHjdMpfFgNn1VA==", - "dev": true, - "optional": true - }, - "esbuild-linux-s390x": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.12.tgz", - "integrity": "sha512-Lt6BDnuXbXeqSlVuuUM5z18GkJAZf3ERskGZbAWjrQoi9xbEIsj/hEzVnSAFLtkfLuy2DE4RwTcX02tZFunXww==", - "dev": true, - "optional": true - }, - "esbuild-netbsd-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.12.tgz", - "integrity": "sha512-jlUxCiHO1dsqoURZDQts+HK100o0hXfi4t54MNRMCAqKGAV33JCVvMplLAa2FwviSojT/5ZG5HUfG3gstwAG8w==", - "dev": true, - "optional": true - }, - "esbuild-openbsd-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.12.tgz", - "integrity": "sha512-1o1uAfRTMIWNOmpf8v7iudND0L6zRBYSH45sofCZywrcf7NcZA+c7aFsS1YryU+yN7aRppTqdUK1PgbZVaB1Dw==", - "dev": true, - "optional": true - }, - "esbuild-sunos-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.12.tgz", - "integrity": "sha512-nkl251DpoWoBO9Eq9aFdoIt2yYmp4I3kvQjba3jFKlMXuqQ9A4q+JaqdkCouG3DHgAGnzshzaGu6xofGcXyPXg==", - "dev": true, - "optional": true - }, - "esbuild-windows-32": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.12.tgz", - "integrity": "sha512-WlGeBZHgPC00O08luIp5B2SP4cNCp/PcS+3Pcg31kdcJPopHxLkdCXtadLU9J82LCfw4TVls21A6lilQ9mzHrw==", - "dev": true, - "optional": true - }, - "esbuild-windows-64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.12.tgz", - "integrity": "sha512-VActO3WnWZSN//xjSfbiGOSyC+wkZtI8I4KlgrTo5oHJM6z3MZZBCuFaZHd8hzf/W9KPhF0lY8OqlmWC9HO5AA==", - "dev": true, - "optional": true - }, - "esbuild-windows-arm64": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.12.tgz", - "integrity": "sha512-Of3MIacva1OK/m4zCNIvBfz8VVROBmQT+gRX6pFTLPngFYcj6TFH/12VveAqq1k9VB2l28EoVMNMUCcmsfwyuA==", - "dev": true, - "optional": true - }, - "escalade": { + "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "escape-string-regexp": { + "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "eslint": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", - "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", + "node_modules/eslint": { + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.33.0.tgz", + "integrity": "sha512-WjOpFQgKK8VrCnAtl8We0SUOy/oVZ5NHykyMiagV1M9r8IFpIJX7DduK6n1mpfhlG7T1NLWm2SuD8QB7KFySaA==", "dev": true, - "requires": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "dependencies": { + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", @@ -8876,7 +3001,7 @@ "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.15.0", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", @@ -8896,134 +3021,195 @@ "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, - "dependencies": { - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "node_modules/eslint-config-prettier": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz", + "integrity": "sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==", "dev": true, - "requires": {} + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } }, - "eslint-scope": { + "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "requires": { + "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" } }, - "eslint-utils": { + "node_modules/eslint-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, - "requires": { + "dependencies": { "eslint-visitor-keys": "^2.0.0" }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" } }, - "eslint-visitor-keys": { + "node_modules/eslint-visitor-keys": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } }, - "espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "node_modules/espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "dev": true, - "requires": { + "dependencies": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "esprima": { + "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } }, - "esquery": { + "node_modules/esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, - "requires": { + "dependencies": { "estraverse": "^5.1.0" }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" } }, - "esrecurse": { + "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "requires": { + "dependencies": { "estraverse": "^5.2.0" }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" } }, - "estraverse": { + "node_modules/estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "dev": true, + "engines": { + "node": ">=4.0" + } }, - "esutils": { + "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "execa": { + "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, - "requires": { + "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", @@ -9033,1310 +3219,1730 @@ "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "exit": { + "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.8.0" + } }, - "expect": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.2.1.tgz", - "integrity": "sha512-BJtA754Fba0YWRWHgjKUMTA3ltWarKgITXHQnbZ2mTxTXC4yMQlR0FI7HkB3fJYkhWBf4qjNiqvg3LDtXCcVRQ==", + "node_modules/expect": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.1.tgz", + "integrity": "sha512-OKrGESHOaMxK3b6zxIq9SOW8kEXztKff/Dvg88j4xIJxur1hspEbedVkR3GpHe5LO+WB2Qw7OWN0RMTdp6as5A==", "dev": true, - "requires": { - "@jest/expect-utils": "^29.2.1", + "dependencies": { + "@jest/expect-utils": "^29.4.1", "jest-get-type": "^29.2.0", - "jest-matcher-utils": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1" + "jest-matcher-utils": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-util": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "fast-deep-equal": { + "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "fast-glob": { + "node_modules/fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, - "requires": { + "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, - "fast-json-stable-stringify": { + "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, - "fast-levenshtein": { + "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, - "requires": { + "dependencies": { "reusify": "^1.0.4" } }, - "fb-watchman": { + "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, - "requires": { + "dependencies": { "bser": "2.1.1" } }, - "figures": { + "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, - "requires": { + "dependencies": { "escape-string-regexp": "^1.0.5" }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - } + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" } }, - "file-entry-cache": { + "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, - "requires": { + "dependencies": { "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "fill-range": { + "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "requires": { + "dependencies": { "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "find-up": { + "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "requires": { + "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "flat-cache": { + "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, - "requires": { + "dependencies": { "flatted": "^3.1.0", "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "flatted": { + "node_modules/flatted": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "fsevents": { + "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "optional": true + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } }, - "function-bind": { + "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "gensync": { + "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "get-caller-file": { + "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, - "get-package-type": { + "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=8.0.0" + } }, - "get-pkg-repo": { + "node_modules/get-pkg-repo": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", "dev": true, - "requires": { + "dependencies": { "@hutson/parse-repository-url": "^3.0.0", "hosted-git-info": "^4.0.0", "through2": "^2.0.0", "yargs": "^16.2.0" }, + "bin": { + "get-pkg-repo": "src/cli.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-pkg-repo/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/get-pkg-repo/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/get-pkg-repo/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/get-pkg-repo/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/get-pkg-repo/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/get-pkg-repo/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" } }, - "get-stream": { + "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "git-raw-commits": { + "node_modules/git-raw-commits": { "version": "2.0.11", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", "dev": true, - "requires": { + "dependencies": { "dargs": "^7.0.0", "lodash": "^4.17.15", "meow": "^8.0.0", "split2": "^3.0.0", "through2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=10" } }, - "git-remote-origin-url": { + "node_modules/git-remote-origin-url": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", "dev": true, - "requires": { + "dependencies": { "gitconfiglocal": "^1.0.0", "pify": "^2.3.0" + }, + "engines": { + "node": ">=4" } }, - "git-semver-tags": { + "node_modules/git-semver-tags": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", "dev": true, - "requires": { + "dependencies": { "meow": "^8.0.0", "semver": "^6.0.0" }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "bin": { + "git-semver-tags": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-semver-tags/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" } }, - "gitconfiglocal": { + "node_modules/gitconfiglocal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", "dev": true, - "requires": { + "dependencies": { "ini": "^1.3.2" } }, - "glob": { + "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, - "requires": { + "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "glob-parent": { + "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "requires": { + "dependencies": { "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" } }, - "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, - "requires": { + "dependencies": { "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "globby": { + "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "requires": { + "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "graceful-fs": { + "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, - "grapheme-splitter": { + "node_modules/grapheme-splitter": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, - "handlebars": { + "node_modules/handlebars": { "version": "4.7.7", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", "dev": true, - "requires": { + "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.0", "source-map": "^0.6.1", - "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" } }, - "hard-rejection": { + "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "has": { + "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, - "requires": { + "dependencies": { "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" } }, - "has-flag": { + "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "hosted-git-info": { + "node_modules/hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, - "requires": { + "dependencies": { "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "html-escaper": { + "node_modules/hosted-git-info/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "human-signals": { + "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true + "dev": true, + "engines": { + "node": ">=10.17.0" + } }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } }, - "import-fresh": { + "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "requires": { + "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "import-local": { + "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, - "requires": { + "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "imurmurhash": { + "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.19" + } }, - "indent-string": { + "node_modules/indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, - "requires": { + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "ini": { + "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, - "is-arrayish": { + "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "is-core-module": { + "node_modules/is-core-module": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "dev": true, - "requires": { + "dependencies": { "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-extglob": { + "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-fullwidth-code-point": { + "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "is-generator-fn": { + "node_modules/is-generator-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "is-glob": { + "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "requires": { + "dependencies": { "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-number": { + "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.12.0" + } }, - "is-obj": { + "node_modules/is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "is-path-inside": { + "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "is-plain-obj": { + "node_modules/is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-stream": { + "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "is-text-path": { + "node_modules/is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", "dev": true, - "requires": { + "dependencies": { "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "isarray": { + "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, - "isexe": { + "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "istanbul-lib-coverage": { + "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "istanbul-lib-instrument": { + "node_modules/istanbul-lib-instrument": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, - "requires": { + "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" } }, - "istanbul-lib-report": { + "node_modules/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "dev": true, - "requires": { + "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" } }, - "istanbul-lib-source-maps": { + "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, - "requires": { + "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" } }, - "istanbul-reports": { + "node_modules/istanbul-reports": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, - "requires": { + "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "jest": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.2.1.tgz", - "integrity": "sha512-K0N+7rx+fv3Us3KhuwRSJt55MMpZPs9Q3WSO/spRZSnsalX8yEYOTQ1PiSN7OvqzoRX4JEUXCbOJRlP4n8m5LA==", + "node_modules/jest": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.4.1.tgz", + "integrity": "sha512-cknimw7gAXPDOmj0QqztlxVtBVCw2lYY9CeIE5N6kD+kET1H4H79HSNISJmijb1HF+qk+G+ploJgiDi5k/fRlg==", "dev": true, - "requires": { - "@jest/core": "^29.2.1", - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/core": "^29.4.1", + "@jest/types": "^29.4.1", "import-local": "^3.0.2", - "jest-cli": "^29.2.1" + "jest-cli": "^29.4.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "jest-changed-files": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz", - "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==", + "node_modules/jest-changed-files": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.4.0.tgz", + "integrity": "sha512-rnI1oPxgFghoz32Y8eZsGJMjW54UlqT17ycQeCEktcxxwqqKdlj9afl8LNeO0Pbu+h2JQHThQP0BzS67eTRx4w==", "dev": true, - "requires": { + "dependencies": { "execa": "^5.0.0", "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-circus": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.2.1.tgz", - "integrity": "sha512-W+ZQQ5ln4Db2UZNM4NJIeasnhCdDhSuYW4eLgNAUi0XiSSpF634Kc5wiPvGiHvTgXMFVn1ZgWIijqhi9+kLNLg==", + "node_modules/jest-circus": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.1.tgz", + "integrity": "sha512-v02NuL5crMNY4CGPHBEflLzl4v91NFb85a+dH9a1pUNx6Xjggrd8l9pPy4LZ1VYNRXlb+f65+7O/MSIbLir6pA==", "dev": true, - "requires": { - "@jest/environment": "^29.2.1", - "@jest/expect": "^29.2.1", - "@jest/test-result": "^29.2.1", - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/environment": "^29.4.1", + "@jest/expect": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/types": "^29.4.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.2.1", - "jest-matcher-utils": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-runtime": "^29.2.1", - "jest-snapshot": "^29.2.1", - "jest-util": "^29.2.1", + "jest-each": "^29.4.1", + "jest-matcher-utils": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-runtime": "^29.4.1", + "jest-snapshot": "^29.4.1", + "jest-util": "^29.4.1", "p-limit": "^3.1.0", - "pretty-format": "^29.2.1", + "pretty-format": "^29.4.1", "slash": "^3.0.0", "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-cli": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.2.1.tgz", - "integrity": "sha512-UIMD5aNqvPKpdlJSaeUAoLfxsh9TZvOkaMETx5qXnkboc317bcbb0eLHbIj8sFBHdcJAIAM+IRKnIU7Wi61MBw==", + "node_modules/jest-cli": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.4.1.tgz", + "integrity": "sha512-jz7GDIhtxQ37M+9dlbv5K+/FVcIo1O/b1sX3cJgzlQUf/3VG25nvuWzlDC4F1FLLzUThJeWLu8I7JF9eWpuURQ==", "dev": true, - "requires": { - "@jest/core": "^29.2.1", - "@jest/test-result": "^29.2.1", - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/core": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/types": "^29.4.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.2.1", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.1", + "jest-config": "^29.4.1", + "jest-util": "^29.4.1", + "jest-validate": "^29.4.1", "prompts": "^2.0.1", "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "jest-config": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.2.1.tgz", - "integrity": "sha512-EV5F1tQYW/quZV2br2o88hnYEeRzG53Dfi6rSG3TZBuzGQ6luhQBux/RLlU5QrJjCdq3LXxRRM8F1LP6DN1ycA==", + "node_modules/jest-config": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.4.1.tgz", + "integrity": "sha512-g7p3q4NuXiM4hrS4XFATTkd+2z0Ml2RhFmFPM8c3WyKwVDNszbl4E7cV7WIx1YZeqqCtqbtTtZhGZWJlJqngzg==", "dev": true, - "requires": { + "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.2.1", - "@jest/types": "^29.2.1", - "babel-jest": "^29.2.1", + "@jest/test-sequencer": "^29.4.1", + "@jest/types": "^29.4.1", + "babel-jest": "^29.4.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.2.1", - "jest-environment-node": "^29.2.1", + "jest-circus": "^29.4.1", + "jest-environment-node": "^29.4.1", "jest-get-type": "^29.2.0", "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.2.1", - "jest-runner": "^29.2.1", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.1", + "jest-resolve": "^29.4.1", + "jest-runner": "^29.4.1", + "jest-util": "^29.4.1", + "jest-validate": "^29.4.1", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.2.1", + "pretty-format": "^29.4.1", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, - "jest-diff": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.2.1.tgz", - "integrity": "sha512-gfh/SMNlQmP3MOUgdzxPOd4XETDJifADpT937fN1iUGz+9DgOu2eUPHH25JDkLVcLwwqxv3GzVyK4VBUr9fjfA==", + "node_modules/jest-diff": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.1.tgz", + "integrity": "sha512-uazdl2g331iY56CEyfbNA0Ut7Mn2ulAG5vUaEHXycf1L6IPyuImIxSz4F0VYBKi7LYIuxOwTZzK3wh5jHzASMw==", "dev": true, - "requires": { + "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.2.0", + "diff-sequences": "^29.3.1", "jest-get-type": "^29.2.0", - "pretty-format": "^29.2.1" + "pretty-format": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-docblock": { + "node_modules/jest-docblock": { "version": "29.2.0", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", "dev": true, - "requires": { + "dependencies": { "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-each": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.2.1.tgz", - "integrity": "sha512-sGP86H/CpWHMyK3qGIGFCgP6mt+o5tu9qG4+tobl0LNdgny0aitLXs9/EBacLy3Bwqy+v4uXClqJgASJWcruYw==", + "node_modules/jest-each": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.1.tgz", + "integrity": "sha512-QlYFiX3llJMWUV0BtWht/esGEz9w+0i7BHwODKCze7YzZzizgExB9MOfiivF/vVT0GSQ8wXLhvHXh3x2fVD4QQ==", "dev": true, - "requires": { - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/types": "^29.4.1", "chalk": "^4.0.0", "jest-get-type": "^29.2.0", - "jest-util": "^29.2.1", - "pretty-format": "^29.2.1" + "jest-util": "^29.4.1", + "pretty-format": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-environment-node": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.2.1.tgz", - "integrity": "sha512-PulFKwEMz6nTAdLUwglFKei3b/LixwlRiqTN6nvPE1JtrLtlnpd6LXnFI1NFHYJGlTmIWilMP2n9jEtPPKX50g==", + "node_modules/jest-environment-node": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.4.1.tgz", + "integrity": "sha512-x/H2kdVgxSkxWAIlIh9MfMuBa0hZySmfsC5lCsWmWr6tZySP44ediRKDUiNggX/eHLH7Cd5ZN10Rw+XF5tXsqg==", "dev": true, - "requires": { - "@jest/environment": "^29.2.1", - "@jest/fake-timers": "^29.2.1", - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/environment": "^29.4.1", + "@jest/fake-timers": "^29.4.1", + "@jest/types": "^29.4.1", "@types/node": "*", - "jest-mock": "^29.2.1", - "jest-util": "^29.2.1" + "jest-mock": "^29.4.1", + "jest-util": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-get-type": { + "node_modules/jest-get-type": { "version": "29.2.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", - "dev": true + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "jest-haste-map": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.2.1.tgz", - "integrity": "sha512-wF460rAFmYc6ARcCFNw4MbGYQjYkvjovb9GBT+W10Um8q5nHq98jD6fHZMDMO3tA56S8XnmNkM8GcA8diSZfnA==", + "node_modules/jest-haste-map": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.1.tgz", + "integrity": "sha512-imTjcgfVVTvg02khXL11NNLTx9ZaofbAWhilrMg/G8dIkp+HYCswhxf0xxJwBkfhWb3e8dwbjuWburvxmcr58w==", "dev": true, - "requires": { - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/types": "^29.4.1", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", "jest-regex-util": "^29.2.0", - "jest-util": "^29.2.1", - "jest-worker": "^29.2.1", + "jest-util": "^29.4.1", + "jest-worker": "^29.4.1", "micromatch": "^4.0.4", "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "jest-leak-detector": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.2.1.tgz", - "integrity": "sha512-1YvSqYoiurxKOJtySc+CGVmw/e1v4yNY27BjWTVzp0aTduQeA7pdieLiW05wTYG/twlKOp2xS/pWuikQEmklug==", + "node_modules/jest-leak-detector": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.4.1.tgz", + "integrity": "sha512-akpZv7TPyGMnH2RimOCgy+hPmWZf55EyFUvymQ4LMsQP8xSPlZumCPtXGoDhFNhUE2039RApZkTQDKU79p/FiQ==", "dev": true, - "requires": { + "dependencies": { "jest-get-type": "^29.2.0", - "pretty-format": "^29.2.1" + "pretty-format": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-matcher-utils": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.2.1.tgz", - "integrity": "sha512-hUTBh7H/Mnb6GTpihbLh8uF5rjAMdekfW/oZNXUMAXi7bbmym2HiRpzgqf/zzkjgejMrVAkPdVSQj+32enlUww==", + "node_modules/jest-matcher-utils": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.1.tgz", + "integrity": "sha512-k5h0u8V4nAEy6lSACepxL/rw78FLDkBnXhZVgFneVpnJONhb2DhZj/Gv4eNe+1XqQ5IhgUcqj745UwH0HJmMnA==", "dev": true, - "requires": { + "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.2.1", + "jest-diff": "^29.4.1", "jest-get-type": "^29.2.0", - "pretty-format": "^29.2.1" + "pretty-format": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-message-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.2.1.tgz", - "integrity": "sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw==", + "node_modules/jest-message-util": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.1.tgz", + "integrity": "sha512-H4/I0cXUaLeCw6FM+i4AwCnOwHRgitdaUFOdm49022YD5nfyr8C/DrbXOBEyJaj+w/y0gGJ57klssOaUiLLQGQ==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.2.1", + "@jest/types": "^29.4.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.2.1", + "pretty-format": "^29.4.1", "slash": "^3.0.0", "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-mock": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.2.1.tgz", - "integrity": "sha512-NDphaY/GqyQpTfnTZiTqqpMaw4Z0I7XnB7yBgrT6IwYrLGxpOhrejYr4ANY4YvO2sEGdd8Tx/6D0+WLQy7/qDA==", + "node_modules/jest-mock": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.1.tgz", + "integrity": "sha512-MwA4hQ7zBOcgVCVnsM8TzaFLVUD/pFWTfbkY953Y81L5ret3GFRZtmPmRFAjKQSdCKoJvvqOu6Bvfpqlwwb0dQ==", "dev": true, - "requires": { - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/types": "^29.4.1", "@types/node": "*", - "jest-util": "^29.2.1" + "jest-util": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, - "requires": {} + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } }, - "jest-regex-util": { + "node_modules/jest-regex-util": { "version": "29.2.0", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", - "dev": true + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "jest-resolve": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.2.1.tgz", - "integrity": "sha512-1dJTW76Z9622Viq4yRcwBuEXuzGtE9B2kdl05RC8Om/lAzac9uEgC+M8Q5osVidbuBPmxm8wSrcItYhca2ZAtQ==", + "node_modules/jest-resolve": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.1.tgz", + "integrity": "sha512-j/ZFNV2lm9IJ2wmlq1uYK0Y/1PiyDq9g4HEGsNTNr3viRbJdV+8Lf1SXIiLZXFvyiisu0qUyIXGBnw+OKWkJwQ==", "dev": true, - "requires": { + "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.2.1", + "jest-haste-map": "^29.4.1", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.1", + "jest-util": "^29.4.1", + "jest-validate": "^29.4.1", "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", + "resolve.exports": "^2.0.0", "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-resolve-dependencies": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.2.1.tgz", - "integrity": "sha512-o3mUGX2j08usj1jIAIE8KmUVpqVAn54k80kI27ldbZf2oJn6eghhB6DvJxjrcH40va9CQgWTfU5f2Ag/MoUqgQ==", + "node_modules/jest-resolve-dependencies": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.1.tgz", + "integrity": "sha512-Y3QG3M1ncAMxfjbYgtqNXC5B595zmB6e//p/qpA/58JkQXu/IpLDoLeOa8YoYfsSglBKQQzNUqtfGJJT/qLmJg==", "dev": true, - "requires": { + "dependencies": { "jest-regex-util": "^29.2.0", - "jest-snapshot": "^29.2.1" + "jest-snapshot": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-runner": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.2.1.tgz", - "integrity": "sha512-PojFI+uVhQ4u4YZKCN/a3yU0/l/pJJXhq1sW3JpCp8CyvGBYGddRFPKZ1WihApusxqWRTHjBJmGyPWv6Av2lWA==", + "node_modules/jest-runner": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.4.1.tgz", + "integrity": "sha512-8d6XXXi7GtHmsHrnaqBKWxjKb166Eyj/ksSaUYdcBK09VbjPwIgWov1VwSmtupCIz8q1Xv4Qkzt/BTo3ZqiCeg==", "dev": true, - "requires": { - "@jest/console": "^29.2.1", - "@jest/environment": "^29.2.1", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.1", - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/console": "^29.4.1", + "@jest/environment": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.10.2", + "emittery": "^0.13.1", "graceful-fs": "^4.2.9", "jest-docblock": "^29.2.0", - "jest-environment-node": "^29.2.1", - "jest-haste-map": "^29.2.1", - "jest-leak-detector": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-resolve": "^29.2.1", - "jest-runtime": "^29.2.1", - "jest-util": "^29.2.1", - "jest-watcher": "^29.2.1", - "jest-worker": "^29.2.1", + "jest-environment-node": "^29.4.1", + "jest-haste-map": "^29.4.1", + "jest-leak-detector": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-resolve": "^29.4.1", + "jest-runtime": "^29.4.1", + "jest-util": "^29.4.1", + "jest-watcher": "^29.4.1", + "jest-worker": "^29.4.1", "p-limit": "^3.1.0", "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-runtime": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.2.1.tgz", - "integrity": "sha512-PSQ880OoIW9y8E6/jjhGn3eQNgNc6ndMzCZaKqy357bv7FqCfSyYepu3yDC6Sp1Vkt+GhP2M/PVgldS2uZSFZg==", + "node_modules/jest-runtime": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.1.tgz", + "integrity": "sha512-UXTMU9uKu2GjYwTtoAw5rn4STxWw/nadOfW7v1sx6LaJYa3V/iymdCLQM6xy3+7C6mY8GfX22vKpgxY171UIoA==", "dev": true, - "requires": { - "@jest/environment": "^29.2.1", - "@jest/fake-timers": "^29.2.1", - "@jest/globals": "^29.2.1", + "dependencies": { + "@jest/environment": "^29.4.1", + "@jest/fake-timers": "^29.4.1", + "@jest/globals": "^29.4.1", "@jest/source-map": "^29.2.0", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.1", - "@jest/types": "^29.2.1", + "@jest/test-result": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-mock": "^29.2.1", + "jest-haste-map": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-mock": "^29.4.1", "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.2.1", - "jest-snapshot": "^29.2.1", - "jest-util": "^29.2.1", + "jest-resolve": "^29.4.1", + "jest-snapshot": "^29.4.1", + "jest-util": "^29.4.1", + "semver": "^7.3.5", "slash": "^3.0.0", "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-snapshot": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.2.1.tgz", - "integrity": "sha512-KZdLD7iEz5M4ZYd+ezZ/kk73z+DtNbk/yJ4Qx7408Vb0CCuclJIZPa/HmIwSsCfIlOBNcYTKufr7x/Yv47oYlg==", + "node_modules/jest-snapshot": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.1.tgz", + "integrity": "sha512-l4iV8EjGgQWVz3ee/LR9sULDk2pCkqb71bjvlqn+qp90lFwpnulHj4ZBT8nm1hA1C5wowXLc7MGnw321u0tsYA==", "dev": true, - "requires": { + "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.2.1", - "@jest/transform": "^29.2.1", - "@jest/types": "^29.2.1", + "@jest/expect-utils": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.2.1", + "expect": "^29.4.1", "graceful-fs": "^4.2.9", - "jest-diff": "^29.2.1", + "jest-diff": "^29.4.1", "jest-get-type": "^29.2.0", - "jest-haste-map": "^29.2.1", - "jest-matcher-utils": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1", + "jest-haste-map": "^29.4.1", + "jest-matcher-utils": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-util": "^29.4.1", "natural-compare": "^1.4.0", - "pretty-format": "^29.2.1", + "pretty-format": "^29.4.1", "semver": "^7.3.5" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.2.1.tgz", - "integrity": "sha512-P5VWDj25r7kj7kl4pN2rG/RN2c1TLfYYYZYULnS/35nFDjBai+hBeo3MDrYZS7p6IoY3YHZnt2vq4L6mKnLk0g==", + "node_modules/jest-util": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.1.tgz", + "integrity": "sha512-bQy9FPGxVutgpN4VRc0hk6w7Hx/m6L53QxpDreTZgJd9gfx/AV2MjyPde9tGyZRINAUrSv57p2inGBu2dRLmkQ==", "dev": true, - "requires": { - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/types": "^29.4.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-validate": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.2.1.tgz", - "integrity": "sha512-DZVX5msG6J6DL5vUUw+++6LEkXUsPwB5R7fsfM7BXdz2Ipr0Ib046ak+8egrwAR++pvSM/5laxLK977ieIGxkQ==", + "node_modules/jest-validate": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.1.tgz", + "integrity": "sha512-qNZXcZQdIQx4SfUB/atWnI4/I2HUvhz8ajOSYUu40CSmf9U5emil8EDHgE7M+3j9/pavtk3knlZBDsgFvv/SWw==", "dev": true, - "requires": { - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/types": "^29.4.1", "camelcase": "^6.2.0", "chalk": "^4.0.0", "jest-get-type": "^29.2.0", "leven": "^3.1.0", - "pretty-format": "^29.2.1" + "pretty-format": "^29.4.1" }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "jest-watcher": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.2.1.tgz", - "integrity": "sha512-7jFaHUaRq50l4w/f6RuY713bvI5XskMmjWCE54NGYcY74fLkShS8LucXJke1QfGnwDSCoIqGnGGGKPwdaBYz2Q==", + "node_modules/jest-watcher": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.4.1.tgz", + "integrity": "sha512-vFOzflGFs27nU6h8dpnVRER3O2rFtL+VMEwnG0H3KLHcllLsU8y9DchSh0AL/Rg5nN1/wSiQ+P4ByMGpuybaVw==", "dev": true, - "requires": { - "@jest/test-result": "^29.2.1", - "@jest/types": "^29.2.1", + "dependencies": { + "@jest/test-result": "^29.4.1", + "@jest/types": "^29.4.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^29.2.1", + "emittery": "^0.13.1", + "jest-util": "^29.4.1", "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "jest-worker": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.2.1.tgz", - "integrity": "sha512-ROHTZ+oj7sBrgtv46zZ84uWky71AoYi0vEV9CdEtc1FQunsoAGe5HbQmW76nI5QWdvECVPrSi1MCVUmizSavMg==", + "node_modules/jest-worker": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.1.tgz", + "integrity": "sha512-O9doU/S1EBe+yp/mstQ0VpPwpv0Clgn68TkNwGxL6/usX/KUW9Arnn4ag8C3jc6qHcXznhsT5Na1liYzAsuAbQ==", "dev": true, - "requires": { + "dependencies": { "@types/node": "*", - "jest-util": "^29.2.1", + "jest-util": "^29.4.1", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true + "node_modules/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } }, - "js-tokens": { + "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "js-yaml": { + "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "requires": { + "dependencies": { "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "jsesc": { + "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } }, - "json-parse-better-errors": { + "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "json-parse-even-better-errors": { + "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "json-schema-traverse": { + "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "json-stable-stringify-without-jsonify": { + "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "json-stringify-safe": { + "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true }, - "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } }, - "jsonparse": { + "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true + "dev": true, + "engines": [ + "node >= 0.2.0" + ] }, - "JSONStream": { + "node_modules/JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dev": true, - "requires": { + "dependencies": { "jsonparse": "^1.2.0", "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" } }, - "kind-of": { + "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "kleur": { + "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "leven": { + "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "engines": { + "node": ">=4" } }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - } + "engines": { + "node": ">=4" } }, - "locate-path": { + "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "requires": { + "dependencies": { "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "lodash": { + "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lodash.ismatch": { + "node_modules/lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", "dev": true }, - "lodash.memoize": { + "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, - "lodash.merge": { + "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "requires": { - "yallist": "^4.0.0" + "dependencies": { + "yallist": "^3.0.2" } }, - "make-dir": { + "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, - "requires": { + "dependencies": { "semver": "^6.0.0" }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" } }, - "make-error": { + "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "makeerror": { + "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, - "requires": { + "dependencies": { "tmpl": "1.0.5" } }, - "map-obj": { + "node_modules/map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "meow": { + "node_modules/meow": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", "dev": true, - "requires": { + "dependencies": { "@types/minimist": "^1.2.0", "camelcase-keys": "^6.2.2", "decamelize-keys": "^1.1.0", @@ -10349,847 +4955,1185 @@ "type-fest": "^0.18.0", "yargs-parser": "^20.2.3" }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/meow/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "dev": true - } + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "merge-stream": { + "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "merge2": { + "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true + "dev": true, + "engines": { + "node": ">= 8" + } }, - "micromatch": { + "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, - "requires": { + "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" } }, - "mimic-fn": { + "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "min-indent": { + "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "minimatch": { + "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "requires": { + "dependencies": { "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "minimist": { + "node_modules/minimist": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", - "dev": true + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "minimist-options": { + "node_modules/minimist-options": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, - "requires": { + "dependencies": { "arrify": "^1.0.1", "is-plain-obj": "^1.1.0", "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" } }, - "modify-values": { + "node_modules/modify-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "ms": { + "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "natural-compare": { + "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "neo-async": { + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, + "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "node-int64": { + "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, - "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "node_modules/node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", "dev": true }, - "normalize-package-data": { + "node_modules/normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "dev": true, - "requires": { + "dependencies": { "hosted-git-info": "^4.0.1", "is-core-module": "^2.5.0", "semver": "^7.3.4", "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" } }, - "normalize-path": { + "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "npm-run-path": { + "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, - "requires": { + "dependencies": { "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "requires": { + "dependencies": { "wrappy": "1" } }, - "onetime": { + "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "requires": { + "dependencies": { "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "optionator": { + "node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, - "requires": { + "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" } }, - "p-limit": { + "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "requires": { + "dependencies": { "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-locate": { + "node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "requires": { + "dependencies": { "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-try": { + "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "parent-module": { + "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "requires": { + "dependencies": { "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "parse-json": { + "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "path-exists": { + "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "path-key": { + "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "path-parse": { + "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "path-type": { + "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "picocolors": { + "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "picomatch": { + "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, - "pify": { + "node_modules/pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "pirates": { + "node_modules/pirates": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true + "dev": true, + "engines": { + "node": ">= 6" + } }, - "pkg-dir": { + "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, - "requires": { + "dependencies": { "find-up": "^4.0.0" }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "prelude-ls": { + "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.8.0" + } }, - "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true + "node_modules/prettier": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } }, - "pretty-format": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.2.1.tgz", - "integrity": "sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA==", + "node_modules/pretty-format": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.1.tgz", + "integrity": "sha512-dt/Z761JUVsrIKaY215o1xQJBGlSmTx/h4cSqXqjHLnU1+Kt+mavVE7UgqJJO5ukx5HjSswHfmXz4LjS2oIJfg==", "dev": true, - "requires": { - "@jest/schemas": "^29.0.0", + "dependencies": { + "@jest/schemas": "^29.4.0", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "process-nextick-args": { + "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "prompts": { + "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, - "requires": { + "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" } }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "q": { + "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } }, - "queue-microtask": { + "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "quick-lru": { + "node_modules/quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "react-is": { + "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "read-pkg": { + "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", "dev": true, - "requires": { + "dependencies": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", "path-type": "^3.0.0" }, - "dependencies": { - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } + "engines": { + "node": ">=4" } }, - "read-pkg-up": { + "node_modules/read-pkg-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", "dev": true, - "requires": { + "dependencies": { "find-up": "^2.0.0", "read-pkg": "^3.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - } + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" } }, - "readable-stream": { + "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, - "requires": { + "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "redent": { + "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, - "requires": { + "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "regexpp": { + "node_modules/regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } }, - "require-directory": { + "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "resolve": { + "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dev": true, - "requires": { + "dependencies": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "resolve-cwd": { + "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, - "requires": { + "dependencies": { "resolve-from": "^5.0.0" }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" } }, - "resolve-from": { + "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true + "node_modules/resolve.exports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.0.tgz", + "integrity": "sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==", + "dev": true, + "engines": { + "node": ">=10" + } }, - "reusify": { + "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } }, - "rimraf": { + "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, - "requires": { + "dependencies": { "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "run-parallel": { + "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, - "requires": { + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { "queue-microtask": "^1.2.2" } }, - "safe-buffer": { + "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "semver": { + "node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, - "requires": { + "dependencies": { "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "shebang-command": { + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "requires": { + "dependencies": { "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "shebang-regex": { + "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "signal-exit": { + "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "sisteransi": { + "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, - "slash": { + "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "source-map": { + "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "source-map-support": { + "node_modules/source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, - "requires": { + "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, - "spdx-correct": { + "node_modules/spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, - "requires": { + "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-exceptions": { + "node_modules/spdx-exceptions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, - "spdx-expression-parse": { + "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "requires": { + "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-license-ids": { + "node_modules/spdx-license-ids": { "version": "3.0.12", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", "dev": true }, - "split": { + "node_modules/split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "dev": true, - "requires": { + "dependencies": { "through": "2" + }, + "engines": { + "node": "*" } }, - "split2": { + "node_modules/split2": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "dev": true, - "requires": { + "dependencies": { "readable-stream": "^3.0.0" } }, - "sprintf-js": { + "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, - "requires": { + "dependencies": { "escape-string-regexp": "^2.0.0" }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" } }, - "standard-version": { + "node_modules/standard-version": { "version": "9.5.0", "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.5.0.tgz", "integrity": "sha512-3zWJ/mmZQsOaO+fOlsa0+QK90pwhNd042qEcw6hKFNoLFs7peGyvPffpEBbK/DSGPbyOvli0mUIFv5A4qTjh2Q==", "dev": true, - "requires": { + "dependencies": { "chalk": "^2.4.2", "conventional-changelog": "3.1.25", "conventional-changelog-config-spec": "2.1.0", @@ -11205,482 +6149,674 @@ "stringify-package": "^1.0.1", "yargs": "^16.0.0" }, + "bin": { + "standard-version": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/standard-version/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/standard-version/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/standard-version/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/standard-version/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/standard-version/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/standard-version/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/standard-version/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/standard-version/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/standard-version/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" } }, - "string_decoder": { + "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, - "requires": { + "dependencies": { "safe-buffer": "~5.2.0" } }, - "string-length": { + "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, - "requires": { + "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" } }, - "string-width": { + "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "requires": { + "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "stringify-package": { + "node_modules/stringify-package": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", + "deprecated": "This module is not used anymore, and has been replaced by @npmcli/package-json", "dev": true }, - "strip-ansi": { + "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { + "dependencies": { "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "strip-bom": { + "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "strip-final-newline": { + "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "strip-indent": { + "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, - "requires": { + "dependencies": { "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" } }, - "strip-json-comments": { + "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "supports-color": { + "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "requires": { + "dependencies": { "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "supports-preserve-symlinks-flag": { + "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "test-exclude": { + "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "requires": { + "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" } }, - "text-extensions": { + "node_modules/text-extensions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10" + } }, - "text-table": { + "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "through": { + "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, - "through2": { + "node_modules/through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "dev": true, - "requires": { + "dependencies": { "readable-stream": "3" } }, - "tmpl": { + "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, - "to-fast-properties": { + "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "to-regex-range": { + "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "requires": { + "dependencies": { "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "trim-newlines": { + "node_modules/trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "ts-jest": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz", - "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==", + "node_modules/ts-jest": { + "version": "29.0.5", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.5.tgz", + "integrity": "sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==", "dev": true, - "requires": { + "dependencies": { "bs-logger": "0.x", "fast-json-stable-stringify": "2.x", "jest-util": "^29.0.0", - "json5": "^2.2.1", + "json5": "^2.2.3", "lodash.memoize": "4.x", "make-error": "1.x", "semver": "7.x", "yargs-parser": "^21.0.1" }, - "dependencies": { - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true } } }, - "tslib": { + "node_modules/ts-jest/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "tsutils": { + "node_modules/tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, - "requires": { + "dependencies": { "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "type-check": { + "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "requires": { + "dependencies": { "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "type-detect": { + "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "type-fest": { + "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "typedarray": { + "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, - "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } }, - "uglify-js": { - "version": "3.17.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.3.tgz", - "integrity": "sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==", + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", "dev": true, - "optional": true + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } }, - "update-browserslist-db": { + "node_modules/update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, - "requires": { + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "uri-js": { + "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "requires": { + "dependencies": { "punycode": "^2.1.0" } }, - "util-deprecate": { + "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "uzip": { + "node_modules/uzip": { "version": "0.20201231.0", "resolved": "https://registry.npmjs.org/uzip/-/uzip-0.20201231.0.tgz", "integrity": "sha512-OZeJfZP+R0z9D6TmBgLq2LHzSSptGMGDGigGiEe0pr8UBe/7fdflgHlHBNDASTXB5jnFuxHpNaJywSg8YFeGng==" }, - "v8-to-istanbul": { + "node_modules/v8-to-istanbul": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", "dev": true, - "requires": { + "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" } }, - "validate-npm-package-license": { + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "requires": { + "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, - "walker": { + "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, - "requires": { + "dependencies": { "makeerror": "1.0.12" } }, - "which": { + "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "word-wrap": { + "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "wordwrap": { + "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true }, - "wrap-ansi": { + "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "node_modules/write-file-atomic": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.0.tgz", + "integrity": "sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==", "dev": true, - "requires": { + "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "xtend": { + "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.4" + } }, - "y18n": { + "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + } }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, - "yargs": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", - "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", + "node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "dev": true, - "requires": { + "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" }, - "dependencies": { - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - } + "engines": { + "node": ">=12" } }, - "yargs-parser": { + "node_modules/yargs-parser": { "version": "20.2.9", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } }, - "yocto-queue": { + "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index acd78d8..a4e9456 100644 --- a/package.json +++ b/package.json @@ -67,34 +67,41 @@ "flood-fill" ], "scripts": { - "format-src": "prettier --write \"src/**/*.ts\" \"src/**/*.js\" --no-error-on-unmatched-pattern", - "format-test": "prettier --write \"test/**/*.ts\" \"test/**/*.js\" --no-error-on-unmatched-pattern", - "eslint": "eslint --fix", - "format": "npm run format-src && npm run format-test && npm run eslint", - "test": "jest", - "build:normal-js": "tsc --removeComments", - "build:normal-typings": "tsc --emitDeclarationOnly", - "build:normal": "npm run build:normal-js && npm run build:normal-typings", + "test:color": "jest ./test/color", + "test:draw": "jest ./test/draw", + "test:exif": "jest ./test/exif", + "test:filter": "jest ./test/filter", + "test:format": "jest ./test/format", + "test:image": "jest ./test/image", + "test:transform": "jest ./test/transform", + "test:all": "jest ./test/", + "format:src": "prettier --write \"src/**/*.ts\" \"src/**/*.js\" --no-error-on-unmatched-pattern", + "format:test": "prettier --write \"test/**/*.ts\" \"test/**/*.js\" --no-error-on-unmatched-pattern", + "format:eslint": "eslint --fix", + "format": "npm run format:src && npm run format:test && npm run format:eslint", + "build:src-js": "tsc -p tsconfig.build.json --removeComments", + "build:src-typings": "tsc -p tsconfig.build.json --emitDeclarationOnly", + "build:src": "npm run build:src-js && npm run build:src-typings", "build:compact-js": "node build.js", - "build:compact-typings": "tsc --emitDeclarationOnly --declaration --outFile lib-compact/index.d.ts", + "build:compact-typings": "tsc -p tsconfig.build.json --emitDeclarationOnly --declaration --outFile lib-compact/index.d.ts", "build:compact": "npm run build:compact-js && npm run build:compact-typings", - "build": "npm run format && npm run build:normal && npm run build:compact", + "build": "npm run format && npm run build:src && npm run build:compact", "release": "standard-version" }, "devDependencies": { - "@types/jest": "^29.2.0", - "@types/node": "^18.11.3", + "@types/jest": "^29.4.0", + "@types/node": "^18.11.19", "@types/uzip": "^0.20201231.0", - "@typescript-eslint/eslint-plugin": "^5.40.1", - "@typescript-eslint/parser": "^5.40.1", - "esbuild": "^0.15.12", - "eslint": "^8.26.0", - "eslint-config-prettier": "^8.5.0", - "jest": "^29.2.1", - "prettier": "2.7.1", + "@typescript-eslint/eslint-plugin": "^5.51.0", + "@typescript-eslint/parser": "^5.51.0", + "esbuild": "^0.17.6", + "eslint": "^8.33.0", + "eslint-config-prettier": "^8.6.0", + "jest": "^29.4.1", + "prettier": "2.8.3", "standard-version": "^9.5.0", - "ts-jest": "^29.0.3", - "typescript": "^4.8.4" + "ts-jest": "^29.0.5", + "typescript": "^4.9.5" }, "dependencies": { "uzip": "^0.20201231.0" diff --git a/src/color/channel-order.ts b/src/color/channel-order.ts new file mode 100644 index 0000000..afdd872 --- /dev/null +++ b/src/color/channel-order.ts @@ -0,0 +1,26 @@ +/** @format */ + +export enum ChannelOrder { + rgba, + bgra, + abgr, + argb, + rgb, + bgr, + grayAlpha, + red, +} + +/** + * The number of channels for each ChannelOrder. + */ +export const ChannelOrderLength = new Map([ + [ChannelOrder.rgba, 4], + [ChannelOrder.bgra, 4], + [ChannelOrder.abgr, 4], + [ChannelOrder.argb, 4], + [ChannelOrder.rgb, 3], + [ChannelOrder.bgr, 3], + [ChannelOrder.grayAlpha, 2], + [ChannelOrder.red, 1], +]); diff --git a/src/color/channel.ts b/src/color/channel.ts new file mode 100644 index 0000000..8e4a87a --- /dev/null +++ b/src/color/channel.ts @@ -0,0 +1,27 @@ +/** @format */ + +/** + * A channel of a color + */ +export enum Channel { + /** + * Red channel + */ + red, + /** + * Green channel + */ + green, + /** + * Blue channel + */ + blue, + /** + * Alpha channel + */ + alpha, + /** + * Luminance is not an actual channel, it is the brightness value of the color. + */ + luminance, +} diff --git a/src/color/color-float16.ts b/src/color/color-float16.ts new file mode 100644 index 0000000..74d2d64 --- /dev/null +++ b/src/color/color-float16.ts @@ -0,0 +1,238 @@ +/** @format */ + +import { ArrayUtils } from '../common/array-utils'; +import { Float16 } from '../common/float16'; +import { Palette } from '../image/palette'; +import { Channel } from './channel'; +import { Color, ColorConvertOptions } from './color'; +import { ColorUtils } from './color-utils'; +import { Format } from './format'; + +/** + * A 16-bit floating point color. + */ +export class ColorFloat16 implements Color { + protected data: Uint16Array; + + public get format(): Format { + return Format.float16; + } + + public get length(): number { + return this.data.length; + } + + public get maxChannelValue(): number { + return 1; + } + + public get maxIndexValue(): number { + return 1; + } + + public get isLdrFormat(): boolean { + return false; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get hasPalette(): boolean { + return false; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get r(): number { + return this.getChannel(0); + } + public set r(r: number) { + this.setChannel(0, r); + } + + public get g(): number { + return this.getChannel(1); + } + public set g(g: number) { + this.setChannel(1, g); + } + + public get b(): number { + return this.getChannel(2); + } + public set b(b: number) { + this.setChannel(2, b); + } + + public get a(): number { + return this.getChannel(3); + } + public set a(a: number) { + this.setChannel(3, a); + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor(data: Uint16Array | number) { + if (typeof data === 'number') { + this.data = new Uint16Array(data); + } else { + this.data = data.slice(); + } + } + + public static from(other: ColorFloat16) { + const c = new ColorFloat16(other.length); + c.data = other.data; + return c; + } + + public static fromArray(color: Uint16Array) { + const c = new ColorFloat16(color); + const l = color.length; + for (let i = 0; i < l; ++i) { + c.data[i] = Float16.doubleToFloat16(color[i]); + } + return c; + } + + public static rgb(r: number, g: number, b: number) { + const data = new Uint16Array([ + Float16.doubleToFloat16(r), + Float16.doubleToFloat16(g), + Float16.doubleToFloat16(b), + ]); + return new ColorFloat16(data); + } + + public static rgba(r: number, g: number, b: number, a: number) { + const data = new Uint16Array([ + Float16.doubleToFloat16(r), + Float16.doubleToFloat16(g), + Float16.doubleToFloat16(b), + Float16.doubleToFloat16(a), + ]); + return new ColorFloat16(data); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.data.length + ? Float16.float16ToDouble(this.data[channel]) + : 0; + } + } + + public getChannelNormalized(channel: number | Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(index: number | Channel, value: number): void { + if (index < this.data.length) { + this.data[index] = Float16.doubleToFloat16(value); + } + } + + public set(c: Color): void { + this.setRgba(c.r, c.g, c.b, c.a); + } + + public setRgb(r: number, g: number, b: number): void { + this.data[0] = Float16.doubleToFloat16(r); + const nc = this.data.length; + if (nc > 1) { + this.data[1] = Float16.doubleToFloat16(g); + if (nc > 2) { + this.data[2] = Float16.doubleToFloat16(b); + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + this.data[0] = Float16.doubleToFloat16(r); + const nc = this.data.length; + if (nc > 1) { + this.data[1] = Float16.doubleToFloat16(g); + if (nc > 2) { + this.data[2] = Float16.doubleToFloat16(b); + if (nc > 3) { + this.data[3] = Float16.doubleToFloat16(a); + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone() { + return ColorFloat16.from(this); + } + + public equals(other: Color) { + if (other.length !== this.length) { + return false; + } + for (let i = 0; i < this.length; i++) { + if (other.getChannel(i) !== this.getChannel(i)) { + return false; + } + } + return true; + } + + public convert(opt?: ColorConvertOptions) { + return ColorUtils.convertColor({ + from: this, + format: opt?.format, + numChannels: opt?.numChannels, + alpha: opt?.alpha, + }); + } +} diff --git a/src/color/color-float32.ts b/src/color/color-float32.ts new file mode 100644 index 0000000..8ffef84 --- /dev/null +++ b/src/color/color-float32.ts @@ -0,0 +1,221 @@ +/** @format */ + +import { ArrayUtils } from '../common/array-utils'; +import { Palette } from '../image/palette'; +import { Channel } from './channel'; +import { Color, ColorConvertOptions } from './color'; +import { ColorUtils } from './color-utils'; +import { Format } from './format'; + +/** + * A 32-bit floating point color. + */ +export class ColorFloat32 implements Color { + protected data: Float32Array; + + public get format(): Format { + return Format.float32; + } + + public get length(): number { + return this.data.length; + } + + public get maxChannelValue(): number { + return 1; + } + + public get maxIndexValue(): number { + return 1; + } + + public get isLdrFormat(): boolean { + return false; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get hasPalette(): boolean { + return false; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get r(): number { + return this.getChannel(0); + } + public set r(r: number) { + this.setChannel(0, r); + } + + public get g(): number { + return this.getChannel(1); + } + public set g(g: number) { + this.setChannel(1, g); + } + + public get b(): number { + return this.getChannel(2); + } + public set b(b: number) { + this.setChannel(2, b); + } + + public get a(): number { + return this.getChannel(3); + } + public set a(a: number) { + this.setChannel(3, a); + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor(data: Float32Array | number) { + if (typeof data === 'number') { + this.data = new Float32Array(data); + } else { + this.data = data.slice(); + } + } + + public static from(other: ColorFloat32) { + const c = new ColorFloat32(other.length); + c.data = other.data; + return c; + } + + public static fromArray(color: Float32Array) { + return new ColorFloat32(color); + } + + public static rgb(r: number, g: number, b: number) { + const data = new Float32Array([r, g, b]); + return new ColorFloat32(data); + } + + public static rgba(r: number, g: number, b: number, a: number) { + const data = new Float32Array([r, g, b, a]); + return new ColorFloat32(data); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.data.length ? this.data[channel] : 0; + } + } + + public getChannelNormalized(channel: number | Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(index: number | Channel, value: number): void { + if (index < this.data.length) { + this.data[index] = value; + } + } + + public set(c: Color): void { + this.setRgba(c.r, c.g, c.b, c.a); + } + + public setRgb(r: number, g: number, b: number): void { + this.data[0] = r; + const nc = this.data.length; + if (nc > 1) { + this.data[1] = g; + if (nc > 2) { + this.data[2] = b; + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + this.data[0] = r; + const nc = this.data.length; + if (nc > 1) { + this.data[1] = g; + if (nc > 2) { + this.data[2] = b; + if (nc > 3) { + this.data[3] = a; + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone() { + return ColorFloat32.from(this); + } + + public equals(other: Color) { + if (other.length !== this.length) { + return false; + } + for (let i = 0; i < this.length; i++) { + if (other.getChannel(i) !== this.getChannel(i)) { + return false; + } + } + return true; + } + + public convert(opt?: ColorConvertOptions) { + return ColorUtils.convertColor({ + from: this, + format: opt?.format, + numChannels: opt?.numChannels, + alpha: opt?.alpha, + }); + } +} diff --git a/src/color/color-float64.ts b/src/color/color-float64.ts new file mode 100644 index 0000000..0e47825 --- /dev/null +++ b/src/color/color-float64.ts @@ -0,0 +1,221 @@ +/** @format */ + +import { ArrayUtils } from '../common/array-utils'; +import { Palette } from '../image/palette'; +import { Channel } from './channel'; +import { Color, ColorConvertOptions } from './color'; +import { ColorUtils } from './color-utils'; +import { Format } from './format'; + +/** + * A 64-bit floating point color. + */ +export class ColorFloat64 implements Color { + protected data: Float64Array; + + public get format(): Format { + return Format.float64; + } + + public get length(): number { + return this.data.length; + } + + public get maxChannelValue(): number { + return 1; + } + + public get maxIndexValue(): number { + return 1; + } + + public get isLdrFormat(): boolean { + return true; + } + + public get isHdrFormat(): boolean { + return false; + } + + public get hasPalette(): boolean { + return false; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get r(): number { + return this.getChannel(0); + } + public set r(r: number) { + this.setChannel(0, r); + } + + public get g(): number { + return this.getChannel(1); + } + public set g(g: number) { + this.setChannel(1, g); + } + + public get b(): number { + return this.getChannel(2); + } + public set b(b: number) { + this.setChannel(2, b); + } + + public get a(): number { + return this.getChannel(3); + } + public set a(a: number) { + this.setChannel(3, a); + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor(data: Float64Array | number) { + if (typeof data === 'number') { + this.data = new Float64Array(data); + } else { + this.data = data.slice(); + } + } + + public static from(other: ColorFloat64) { + const c = new ColorFloat64(other.length); + c.data = other.data; + return c; + } + + public static fromArray(color: Float64Array) { + return new ColorFloat64(color); + } + + public static rgb(r: number, g: number, b: number) { + const data = new Float64Array([r, g, b]); + return new ColorFloat64(data); + } + + public static rgba(r: number, g: number, b: number, a: number) { + const data = new Float64Array([r, g, b, a]); + return new ColorFloat64(data); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.data.length ? this.data[channel] : 0; + } + } + + public getChannelNormalized(channel: number | Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(index: number | Channel, value: number): void { + if (index < this.data.length) { + this.data[index] = value; + } + } + + public set(c: Color): void { + this.setRgba(c.r, c.g, c.b, c.a); + } + + public setRgb(r: number, g: number, b: number): void { + this.data[0] = r; + const nc = this.data.length; + if (nc > 1) { + this.data[1] = g; + if (nc > 2) { + this.data[2] = b; + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + this.data[0] = r; + const nc = this.data.length; + if (nc > 1) { + this.data[1] = g; + if (nc > 2) { + this.data[2] = b; + if (nc > 3) { + this.data[3] = a; + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone() { + return ColorFloat64.from(this); + } + + public equals(other: Color) { + if (other.length !== this.length) { + return false; + } + for (let i = 0; i < this.length; i++) { + if (other.getChannel(i) !== this.getChannel(i)) { + return false; + } + } + return true; + } + + public convert(opt?: ColorConvertOptions) { + return ColorUtils.convertColor({ + from: this, + format: opt?.format, + numChannels: opt?.numChannels, + alpha: opt?.alpha, + }); + } +} diff --git a/src/color/color-int16.ts b/src/color/color-int16.ts new file mode 100644 index 0000000..3dc812c --- /dev/null +++ b/src/color/color-int16.ts @@ -0,0 +1,230 @@ +/** @format */ + +import { ArrayUtils } from '../common/array-utils'; +import { Palette } from '../image/palette'; +import { Channel } from './channel'; +import { Color, ColorConvertOptions } from './color'; +import { ColorUtils } from './color-utils'; +import { Format } from './format'; + +/** + * A 16-bit integer color. + */ +export class ColorInt16 implements Color { + private _data: Int16Array; + + public get format(): Format { + return Format.int16; + } + + public get length(): number { + return this._data.length; + } + + public get maxChannelValue(): number { + return 0x7fff; + } + + public get maxIndexValue(): number { + return 0x7fff; + } + + public get isLdrFormat(): boolean { + return false; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get hasPalette(): boolean { + return false; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get r(): number { + return this._data.length > 0 ? this._data[0] : 0; + } + public set r(r: number) { + if (this._data.length > 0) { + this._data[0] = Math.trunc(r); + } + } + + public get g(): number { + return this._data.length > 1 ? this._data[1] : 0; + } + public set g(g: number) { + if (this._data.length > 1) { + this._data[1] = Math.trunc(g); + } + } + + public get b(): number { + return this._data.length > 2 ? this._data[2] : 0; + } + public set b(b: number) { + if (this._data.length > 2) { + this._data[2] = Math.trunc(b); + } + } + + public get a(): number { + return this._data.length > 3 ? this._data[3] : 0; + } + public set a(a: number) { + if (this._data.length > 3) { + this._data[3] = Math.trunc(a); + } + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor(data: Int16Array | number) { + if (typeof data === 'number') { + this._data = new Int16Array(data); + } else { + this._data = data.slice(); + } + } + + public static from(other: ColorInt16) { + const c = new ColorInt16(other.length); + c._data = other._data; + return c; + } + + public static fromArray(color: number[]) { + const data = new Int16Array(color); + return new ColorInt16(data); + } + + public static rgb(r: number, g: number, b: number) { + const data = new Int16Array([r, g, b]); + return new ColorInt16(data); + } + + public static rgba(r: number, g: number, b: number, a: number) { + const data = new Int16Array([r, g, b, a]); + return new ColorInt16(data); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this._data.length ? this._data[channel] : 0; + } + } + + public getChannelNormalized(channel: number | Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(index: number | Channel, value: number): void { + if (index < this._data.length) { + this._data[index] = Math.trunc(value); + } + } + + public set(c: Color): void { + this.setRgba(c.r, c.g, c.b, c.a); + } + + public setRgb(r: number, g: number, b: number): void { + this._data[0] = Math.trunc(r); + const nc = this._data.length; + if (nc > 1) { + this._data[1] = Math.trunc(g); + if (nc > 2) { + this._data[2] = Math.trunc(b); + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + this._data[0] = Math.trunc(r); + const nc = this._data.length; + if (nc > 1) { + this._data[1] = Math.trunc(g); + if (nc > 2) { + this._data[2] = Math.trunc(b); + if (nc > 3) { + this._data[3] = Math.trunc(a); + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone() { + return ColorInt16.from(this); + } + + public equals(other: Color) { + if (other.length !== this.length) { + return false; + } + for (let i = 0; i < this.length; i++) { + if (other.getChannel(i) !== this.getChannel(i)) { + return false; + } + } + return true; + } + + public convert(opt?: ColorConvertOptions) { + return ColorUtils.convertColor({ + from: this, + format: opt?.format, + numChannels: opt?.numChannels, + alpha: opt?.alpha, + }); + } +} diff --git a/src/color/color-int32.ts b/src/color/color-int32.ts new file mode 100644 index 0000000..c34abae --- /dev/null +++ b/src/color/color-int32.ts @@ -0,0 +1,230 @@ +/** @format */ + +import { ArrayUtils } from '../common/array-utils'; +import { Palette } from '../image/palette'; +import { Channel } from './channel'; +import { Color, ColorConvertOptions } from './color'; +import { ColorUtils } from './color-utils'; +import { Format } from './format'; + +/** + * A 32-bit integer color. + */ +export class ColorInt32 implements Color { + private _data: Int32Array; + + public get format(): Format { + return Format.int32; + } + + public get length(): number { + return this._data.length; + } + + public get maxChannelValue(): number { + return 0x7fffffff; + } + + public get maxIndexValue(): number { + return 0x7fffffff; + } + + public get isLdrFormat(): boolean { + return false; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get hasPalette(): boolean { + return false; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get r(): number { + return this._data.length > 0 ? this._data[0] : 0; + } + public set r(r: number) { + if (this._data.length > 0) { + this._data[0] = Math.trunc(r); + } + } + + public get g(): number { + return this._data.length > 1 ? this._data[1] : 0; + } + public set g(g: number) { + if (this._data.length > 1) { + this._data[1] = Math.trunc(g); + } + } + + public get b(): number { + return this._data.length > 2 ? this._data[2] : 0; + } + public set b(b: number) { + if (this._data.length > 2) { + this._data[2] = Math.trunc(b); + } + } + + public get a(): number { + return this._data.length > 3 ? this._data[3] : 0; + } + public set a(a: number) { + if (this._data.length > 3) { + this._data[3] = Math.trunc(a); + } + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor(data: Int32Array | number) { + if (typeof data === 'number') { + this._data = new Int32Array(data); + } else { + this._data = data.slice(); + } + } + + public static from(other: ColorInt32) { + const c = new ColorInt32(other.length); + c._data = other._data; + return c; + } + + public static fromArray(color: number[]) { + const data = new Int32Array(color); + return new ColorInt32(data); + } + + public static rgb(r: number, g: number, b: number) { + const data = new Int32Array([r, g, b]); + return new ColorInt32(data); + } + + public static rgba(r: number, g: number, b: number, a: number) { + const data = new Int32Array([r, g, b, a]); + return new ColorInt32(data); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this._data.length ? this._data[channel] : 0; + } + } + + public getChannelNormalized(channel: number | Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(index: number | Channel, value: number): void { + if (index < this._data.length) { + this._data[index] = Math.trunc(value); + } + } + + public set(c: Color): void { + this.setRgba(c.r, c.g, c.b, c.a); + } + + public setRgb(r: number, g: number, b: number): void { + this._data[0] = Math.trunc(r); + const nc = this._data.length; + if (nc > 1) { + this._data[1] = Math.trunc(g); + if (nc > 2) { + this._data[2] = Math.trunc(b); + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + this._data[0] = Math.trunc(r); + const nc = this._data.length; + if (nc > 1) { + this._data[1] = Math.trunc(g); + if (nc > 2) { + this._data[2] = Math.trunc(b); + if (nc > 3) { + this._data[3] = Math.trunc(a); + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone() { + return ColorInt32.from(this); + } + + public equals(other: Color) { + if (other.length !== this.length) { + return false; + } + for (let i = 0; i < this.length; i++) { + if (other.getChannel(i) !== this.getChannel(i)) { + return false; + } + } + return true; + } + + public convert(opt?: ColorConvertOptions) { + return ColorUtils.convertColor({ + from: this, + format: opt?.format, + numChannels: opt?.numChannels, + alpha: opt?.alpha, + }); + } +} diff --git a/src/color/color-int8.ts b/src/color/color-int8.ts new file mode 100644 index 0000000..08dbcd2 --- /dev/null +++ b/src/color/color-int8.ts @@ -0,0 +1,230 @@ +/** @format */ + +import { ArrayUtils } from '../common/array-utils'; +import { Palette } from '../image/palette'; +import { Channel } from './channel'; +import { Color, ColorConvertOptions } from './color'; +import { ColorUtils } from './color-utils'; +import { Format } from './format'; + +/** + * A 8-bit integer color. + */ +export class ColorInt8 implements Color { + private _data: Int8Array; + + public get format(): Format { + return Format.int8; + } + + public get length(): number { + return this._data.length; + } + + public get maxChannelValue(): number { + return 127; + } + + public get maxIndexValue(): number { + return 127; + } + + public get isLdrFormat(): boolean { + return false; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get hasPalette(): boolean { + return false; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get r(): number { + return this._data.length > 0 ? this._data[0] : 0; + } + public set r(r: number) { + if (this._data.length > 0) { + this._data[0] = Math.trunc(r); + } + } + + public get g(): number { + return this._data.length > 1 ? this._data[1] : 0; + } + public set g(g: number) { + if (this._data.length > 1) { + this._data[1] = Math.trunc(g); + } + } + + public get b(): number { + return this._data.length > 2 ? this._data[2] : 0; + } + public set b(b: number) { + if (this._data.length > 2) { + this._data[2] = Math.trunc(b); + } + } + + public get a(): number { + return this._data.length > 3 ? this._data[3] : 0; + } + public set a(a: number) { + if (this._data.length > 3) { + this._data[3] = Math.trunc(a); + } + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor(data: Int8Array | number) { + if (typeof data === 'number') { + this._data = new Int8Array(data); + } else { + this._data = data.slice(); + } + } + + public static from(other: ColorInt8) { + const c = new ColorInt8(other.length); + c._data = other._data; + return c; + } + + public static fromArray(color: number[]) { + const data = new Int8Array(color); + return new ColorInt8(data); + } + + public static rgb(r: number, g: number, b: number) { + const data = new Int8Array([r, g, b]); + return new ColorInt8(data); + } + + public static rgba(r: number, g: number, b: number, a: number) { + const data = new Int8Array([r, g, b, a]); + return new ColorInt8(data); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this._data.length ? this._data[channel] : 0; + } + } + + public getChannelNormalized(channel: number | Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(index: number | Channel, value: number): void { + if (index < this._data.length) { + this._data[index] = Math.trunc(value); + } + } + + public set(c: Color): void { + this.setRgba(c.r, c.g, c.b, c.a); + } + + public setRgb(r: number, g: number, b: number): void { + this._data[0] = Math.trunc(r); + const nc = this._data.length; + if (nc > 1) { + this._data[1] = Math.trunc(g); + if (nc > 2) { + this._data[2] = Math.trunc(b); + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + this._data[0] = Math.trunc(r); + const nc = this._data.length; + if (nc > 1) { + this._data[1] = Math.trunc(g); + if (nc > 2) { + this._data[2] = Math.trunc(b); + if (nc > 3) { + this._data[3] = Math.trunc(a); + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone() { + return ColorInt8.from(this); + } + + public equals(other: Color) { + if (other.length !== this.length) { + return false; + } + for (let i = 0; i < this.length; i++) { + if (other.getChannel(i) !== this.getChannel(i)) { + return false; + } + } + return true; + } + + public convert(opt?: ColorConvertOptions) { + return ColorUtils.convertColor({ + from: this, + format: opt?.format, + numChannels: opt?.numChannels, + alpha: opt?.alpha, + }); + } +} diff --git a/src/color/color-rgb8.ts b/src/color/color-rgb8.ts new file mode 100644 index 0000000..e48920d --- /dev/null +++ b/src/color/color-rgb8.ts @@ -0,0 +1,19 @@ +/** @format */ + +import { ColorUint8 } from './color-uint8'; + +export class ColorRgb8 extends ColorUint8 { + constructor(r: number, g: number, b: number) { + const data = new Uint8Array([r, g, b]); + super(data); + } + + public static from(other: ColorUint8) { + const data = new Uint8Array([ + other.getChannel(0), + other.getChannel(1), + other.getChannel(2), + ]); + return new ColorUint8(data); + } +} diff --git a/src/color/color-rgba8.ts b/src/color/color-rgba8.ts new file mode 100644 index 0000000..1e0b416 --- /dev/null +++ b/src/color/color-rgba8.ts @@ -0,0 +1,20 @@ +/** @format */ + +import { ColorUint8 } from './color-uint8'; + +export class ColorRgba8 extends ColorUint8 { + constructor(r: number, g: number, b: number, a: number) { + const data = new Uint8Array([r, g, b, a]); + super(data); + } + + public static from(other: ColorUint8) { + const data = new Uint8Array([ + other.getChannel(0), + other.getChannel(1), + other.getChannel(2), + other.getChannel(3), + ]); + return new ColorUint8(data); + } +} diff --git a/src/color/color-uint1.ts b/src/color/color-uint1.ts new file mode 100644 index 0000000..c8f6302 --- /dev/null +++ b/src/color/color-uint1.ts @@ -0,0 +1,221 @@ +/** @format */ + +import { ArrayUtils } from '../common/array-utils'; +import { Palette } from '../image/palette'; +import { Channel } from './channel'; +import { Color, ColorConvertOptions } from './color'; +import { ColorUtils } from './color-utils'; +import { Format } from './format'; + +/** + * A 1-bit unsigned int color with channel values in the range [0, 1]. + */ +export class ColorUint1 implements Color { + private _data: number; + + public get format(): Format { + return Format.uint1; + } + + private readonly _length: number; + public get length(): number { + return this._length; + } + + public get maxChannelValue(): number { + return 1; + } + + public get maxIndexValue(): number { + return 1; + } + + public get isLdrFormat(): boolean { + return true; + } + + public get isHdrFormat(): boolean { + return false; + } + + public get hasPalette(): boolean { + return false; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get r(): number { + return this.getChannel(0); + } + public set r(r: number) { + this.setChannel(0, r); + } + + public get g(): number { + return this.getChannel(1); + } + public set g(g: number) { + this.setChannel(1, g); + } + + public get b(): number { + return this.getChannel(2); + } + public set b(b: number) { + this.setChannel(2, b); + } + + public get a(): number { + return this.getChannel(3); + } + public set a(a: number) { + this.setChannel(3, a); + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor(data: number[] | number) { + if (typeof data === 'number') { + this._length = data; + this._data = 0; + } else { + this._length = data.length; + this._data = 0; + this.setRgba( + data.length > 0 ? data[0] : 0, + data.length > 1 ? data[1] : 0, + data.length > 2 ? data[2] : 0, + data.length > 3 ? data[3] : 0 + ); + } + } + + public static from(other: ColorUint1) { + const c = new ColorUint1(other._length); + c._data = other._data; + return c; + } + + public static fromArray(color: number[]) { + return new ColorUint1(color); + } + + public static rgb(r: number, g: number, b: number) { + return new ColorUint1([r, g, b]); + } + + public static rgba(r: number, g: number, b: number, a: number) { + return new ColorUint1([r, g, b, a]); + } + + public getChannel(channel: number | Channel): number { + return channel < this.length ? (this._data >> (7 - channel)) & 0x1 : 0; + } + + public getChannelNormalized(channel: number | Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(index: number | Channel, value: number): void { + let _index = index; + if (_index >= this.length) { + return; + } + _index = 7 - _index; + let v = this._data; + if (value !== 0) { + v |= 1 << _index; + } else { + v &= ~((1 << _index) & 0xff); + } + this._data = v; + } + + public set(c: Color): void { + this.setRgba(c.r, c.g, c.b, c.a); + } + + public setRgb(r: number, g: number, b: number): void { + this.r = r; + this.g = g; + this.b = b; + } + + public setRgba(r: number, g: number, b: number, a: number): void { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone() { + return ColorUint1.from(this); + } + + public equals(other: Color) { + if (other.length !== this.length) { + return false; + } + for (let i = 0; i < this.length; i++) { + if (other.getChannel(i) !== this.getChannel(i)) { + return false; + } + } + return true; + } + + public convert(opt?: ColorConvertOptions) { + return ColorUtils.convertColor({ + from: this, + format: opt?.format, + numChannels: opt?.numChannels, + alpha: opt?.alpha, + }); + } +} diff --git a/src/color/color-uint16.ts b/src/color/color-uint16.ts new file mode 100644 index 0000000..4c948d6 --- /dev/null +++ b/src/color/color-uint16.ts @@ -0,0 +1,221 @@ +/** @format */ + +import { ArrayUtils } from '../common/array-utils'; +import { Palette } from '../image/palette'; +import { Channel } from './channel'; +import { Color, ColorConvertOptions } from './color'; +import { ColorUtils } from './color-utils'; +import { Format } from './format'; + +/** + * A 16-bit unsigned int color with channel values in the range [0, 65535]. + */ +export class ColorUint16 implements Color { + protected data: Uint16Array; + + public get format(): Format { + return Format.uint16; + } + + public get length(): number { + return this.data.length; + } + + public get maxChannelValue(): number { + return 0xffff; + } + + public get maxIndexValue(): number { + return 0xffff; + } + + public get isLdrFormat(): boolean { + return false; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get hasPalette(): boolean { + return false; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get r(): number { + return this.getChannel(0); + } + public set r(r: number) { + this.setChannel(0, r); + } + + public get g(): number { + return this.getChannel(1); + } + public set g(g: number) { + this.setChannel(1, g); + } + + public get b(): number { + return this.getChannel(2); + } + public set b(b: number) { + this.setChannel(2, b); + } + + public get a(): number { + return this.getChannel(3); + } + public set a(a: number) { + this.setChannel(3, a); + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor(data: Uint16Array | number) { + if (typeof data === 'number') { + this.data = new Uint16Array(data); + } else { + this.data = data.slice(); + } + } + + public static from(other: ColorUint16) { + const c = new ColorUint16(other.length); + c.data = other.data; + return c; + } + + public static fromArray(color: Uint16Array) { + return new ColorUint16(color); + } + + public static rgb(r: number, g: number, b: number) { + const data = new Uint16Array([r, g, b]); + return new ColorUint16(data); + } + + public static rgba(r: number, g: number, b: number, a: number) { + const data = new Uint16Array([r, g, b, a]); + return new ColorUint16(data); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.data.length ? this.data[channel] : 0; + } + } + + public getChannelNormalized(channel: number | Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(index: number | Channel, value: number): void { + if (index < this.data.length) { + this.data[index] = Math.trunc(value); + } + } + + public set(c: Color): void { + this.setRgba(c.r, c.g, c.b, c.a); + } + + public setRgb(r: number, g: number, b: number): void { + this.data[0] = Math.trunc(r); + const nc = this.data.length; + if (nc > 1) { + this.data[1] = Math.trunc(g); + if (nc > 2) { + this.data[2] = Math.trunc(b); + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + this.data[0] = Math.trunc(r); + const nc = this.data.length; + if (nc > 1) { + this.data[1] = Math.trunc(g); + if (nc > 2) { + this.data[2] = Math.trunc(b); + if (nc > 3) { + this.data[3] = Math.trunc(a); + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone() { + return ColorUint16.from(this); + } + + public equals(other: Color) { + if (other.length !== this.length) { + return false; + } + for (let i = 0; i < this.length; i++) { + if (other.getChannel(i) !== this.getChannel(i)) { + return false; + } + } + return true; + } + + public convert(opt?: ColorConvertOptions) { + return ColorUtils.convertColor({ + from: this, + format: opt?.format, + numChannels: opt?.numChannels, + alpha: opt?.alpha, + }); + } +} diff --git a/src/color/color-uint2.ts b/src/color/color-uint2.ts new file mode 100644 index 0000000..b70aeed --- /dev/null +++ b/src/color/color-uint2.ts @@ -0,0 +1,226 @@ +/** @format */ + +import { ArrayUtils } from '../common/array-utils'; +import { Palette } from '../image/palette'; +import { Channel } from './channel'; +import { Color, ColorConvertOptions } from './color'; +import { ColorUtils } from './color-utils'; +import { Format } from './format'; + +/** + * A 2-bit unsigned int color with channel values in the range [0, 3]. + */ +export class ColorUint2 implements Color { + private _data: number; + + public get format(): Format { + return Format.uint2; + } + + private readonly _length: number; + public get length(): number { + return this._length; + } + + public get maxChannelValue(): number { + return 3; + } + + public get maxIndexValue(): number { + return 3; + } + + public get isLdrFormat(): boolean { + return true; + } + + public get isHdrFormat(): boolean { + return false; + } + + public get hasPalette(): boolean { + return false; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get r(): number { + return this.getChannel(0); + } + public set r(r: number) { + this.setChannel(0, r); + } + + public get g(): number { + return this.getChannel(1); + } + public set g(g: number) { + this.setChannel(1, g); + } + + public get b(): number { + return this.getChannel(2); + } + public set b(b: number) { + this.setChannel(2, b); + } + + public get a(): number { + return this.getChannel(3); + } + public set a(a: number) { + this.setChannel(3, a); + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor(data: number[] | number) { + if (typeof data === 'number') { + this._length = data; + this._data = 0; + } else { + this._length = data.length; + this._data = 0; + this.setRgba( + data.length > 0 ? data[0] : 0, + data.length > 1 ? data[1] : 0, + data.length > 2 ? data[2] : 0, + data.length > 3 ? data[3] : 0 + ); + } + } + + public static from(other: ColorUint2) { + const c = new ColorUint2(other._length); + c._data = other._data; + return c; + } + + public static fromArray(color: number[]) { + return new ColorUint2(color); + } + + public static rgb(r: number, g: number, b: number) { + return new ColorUint2([r, g, b]); + } + + public static rgba(r: number, g: number, b: number, a: number) { + return new ColorUint2([r, g, b, a]); + } + + public getChannel(channel: number | Channel): number { + return channel < this.length + ? (this._data >> (6 - (channel << 1))) & 0x3 + : 0; + } + + public getChannelNormalized(channel: number | Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(index: number | Channel, value: number): void { + const _index = index; + if (_index >= this.length) { + return; + } + + const _mask = [ + ~(0x3 << (6 - (0 << 1))) & 0xff, + ~(0x3 << (6 - (1 << 1))) & 0xff, + ~(0x3 << (6 - (2 << 1))) & 0xff, + ~(0x3 << (6 - (3 << 1))) & 0xff, + ]; + + const mask = _mask[index]; + const x = Math.trunc(value) & 0x3; + this._data = (this._data & mask) | (x << (6 - (index << 1))); + } + + public set(c: Color): void { + this.setRgba(c.r, c.g, c.b, c.a); + } + + public setRgb(r: number, g: number, b: number): void { + this.r = r; + this.g = g; + this.b = b; + } + + public setRgba(r: number, g: number, b: number, a: number): void { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone() { + return ColorUint2.from(this); + } + + public equals(other: Color) { + if (other.length !== this.length) { + return false; + } + for (let i = 0; i < this.length; i++) { + if (other.getChannel(i) !== this.getChannel(i)) { + return false; + } + } + return true; + } + + public convert(opt?: ColorConvertOptions) { + return ColorUtils.convertColor({ + from: this, + format: opt?.format, + numChannels: opt?.numChannels, + alpha: opt?.alpha, + }); + } +} diff --git a/src/color/color-uint32.ts b/src/color/color-uint32.ts new file mode 100644 index 0000000..c84f177 --- /dev/null +++ b/src/color/color-uint32.ts @@ -0,0 +1,221 @@ +/** @format */ + +import { ArrayUtils } from '../common/array-utils'; +import { Palette } from '../image/palette'; +import { Channel } from './channel'; +import { Color, ColorConvertOptions } from './color'; +import { ColorUtils } from './color-utils'; +import { Format } from './format'; + +/** + * A 32-bit unsigned int color. + */ +export class ColorUint32 implements Color { + protected data: Uint32Array; + + public get format(): Format { + return Format.uint32; + } + + public get length(): number { + return this.data.length; + } + + public get maxChannelValue(): number { + return 0xffffffff; + } + + public get maxIndexValue(): number { + return 0xffffffff; + } + + public get isLdrFormat(): boolean { + return false; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get hasPalette(): boolean { + return false; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get r(): number { + return this.getChannel(0); + } + public set r(r: number) { + this.setChannel(0, r); + } + + public get g(): number { + return this.getChannel(1); + } + public set g(g: number) { + this.setChannel(1, g); + } + + public get b(): number { + return this.getChannel(2); + } + public set b(b: number) { + this.setChannel(2, b); + } + + public get a(): number { + return this.getChannel(3); + } + public set a(a: number) { + this.setChannel(3, a); + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor(data: Uint32Array | number) { + if (typeof data === 'number') { + this.data = new Uint32Array(data); + } else { + this.data = data.slice(); + } + } + + public static from(other: ColorUint32) { + const c = new ColorUint32(other.length); + c.data = other.data; + return c; + } + + public static fromArray(color: Uint32Array) { + return new ColorUint32(color); + } + + public static rgb(r: number, g: number, b: number) { + const data = new Uint32Array([r, g, b]); + return new ColorUint32(data); + } + + public static rgba(r: number, g: number, b: number, a: number) { + const data = new Uint32Array([r, g, b, a]); + return new ColorUint32(data); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.data.length ? this.data[channel] : 0; + } + } + + public getChannelNormalized(channel: number | Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(index: number | Channel, value: number): void { + if (index < this.data.length) { + this.data[index] = Math.trunc(value); + } + } + + public set(c: Color): void { + this.setRgba(c.r, c.g, c.b, c.a); + } + + public setRgb(r: number, g: number, b: number): void { + this.data[0] = Math.trunc(r); + const nc = this.data.length; + if (nc > 1) { + this.data[1] = Math.trunc(g); + if (nc > 2) { + this.data[2] = Math.trunc(b); + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + this.data[0] = Math.trunc(r); + const nc = this.data.length; + if (nc > 1) { + this.data[1] = Math.trunc(g); + if (nc > 2) { + this.data[2] = Math.trunc(b); + if (nc > 3) { + this.data[3] = Math.trunc(a); + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone() { + return ColorUint32.from(this); + } + + public equals(other: Color) { + if (other.length !== this.length) { + return false; + } + for (let i = 0; i < this.length; i++) { + if (other.getChannel(i) !== this.getChannel(i)) { + return false; + } + } + return true; + } + + public convert(opt?: ColorConvertOptions) { + return ColorUtils.convertColor({ + from: this, + format: opt?.format, + numChannels: opt?.numChannels, + alpha: opt?.alpha, + }); + } +} diff --git a/src/color/color-uint4.ts b/src/color/color-uint4.ts new file mode 100644 index 0000000..a8c45ba --- /dev/null +++ b/src/color/color-uint4.ts @@ -0,0 +1,233 @@ +/** @format */ + +import { ArrayUtils } from '../common/array-utils'; +import { MathUtils } from '../common/math-utils'; +import { Palette } from '../image/palette'; +import { Channel } from './channel'; +import { Color, ColorConvertOptions } from './color'; +import { ColorUtils } from './color-utils'; +import { Format } from './format'; + +/** + * A 4-bit unsigned int color with channel values in the range [0, 15]. + */ +export class ColorUint4 implements Color { + private _data: Uint8Array; + + public get format(): Format { + return Format.uint4; + } + + private readonly _length: number; + public get length(): number { + return this._length; + } + + public get maxChannelValue(): number { + return 15; + } + + public get maxIndexValue(): number { + return 15; + } + + public get isLdrFormat(): boolean { + return true; + } + + public get isHdrFormat(): boolean { + return false; + } + + public get hasPalette(): boolean { + return false; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get r(): number { + return this.getChannel(0); + } + public set r(r: number) { + this.setChannel(0, r); + } + + public get g(): number { + return this.getChannel(1); + } + public set g(g: number) { + this.setChannel(1, g); + } + + public get b(): number { + return this.getChannel(2); + } + public set b(b: number) { + this.setChannel(2, b); + } + + public get a(): number { + return this.getChannel(3); + } + public set a(a: number) { + this.setChannel(3, a); + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor(data: Uint8Array | number) { + if (typeof data === 'number') { + this._length = data; + this._data = new Uint8Array(this.length < 3 ? 1 : 2); + } else { + this._length = data.length; + this._data = new Uint8Array(this._length < 3 ? 1 : 2); + this.setRgba( + this._length > 0 ? data[0] : 0, + this._length > 1 ? data[1] : 0, + this._length > 2 ? data[2] : 0, + this._length > 3 ? data[3] : 0 + ); + } + } + + public static from(other: ColorUint4) { + const c = new ColorUint4(other._length); + c._data = other._data; + return c; + } + + public static fromArray(color: Uint8Array) { + return new ColorUint4(color); + } + + public static rgb(r: number, g: number, b: number) { + const c = new ColorUint4(3); + c.setRgb(r, g, b); + return c; + } + + public static rgba(r: number, g: number, b: number, a: number) { + const c = new ColorUint4(4); + c.setRgba(r, g, b, a); + return c; + } + + public getChannel(channel: number | Channel): number { + return channel < 0 || channel >= this.length + ? 0 + : channel < 2 + ? (this._data[0] >> (4 - (channel << 2))) & 0xf + : (this._data[1] >> (4 - ((channel & 0x1) << 2))) & 0xf; + } + + public getChannelNormalized(channel: number | Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(index: number | Channel, value: number): void { + let _index = index; + if (_index >= this.length) { + return; + } + const vi = MathUtils.clamp(Math.trunc(value), 0, 15); + let i = 0; + if (_index > 1) { + _index &= 0x1; + i = 1; + } + if (_index === 0) { + this._data[i] = (this._data[i] & 0xf) | (vi << 4); + } else if (_index === 1) { + this._data[i] = (this._data[i] & 0xf0) | vi; + } + } + + public set(c: Color): void { + this.setRgba(c.r, c.g, c.b, c.a); + } + + public setRgb(r: number, g: number, b: number): void { + this.r = r; + this.g = g; + this.b = b; + } + + public setRgba(r: number, g: number, b: number, a: number): void { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone() { + return ColorUint4.from(this); + } + + public equals(other: Color) { + if (other.length !== this.length) { + return false; + } + for (let i = 0; i < this.length; i++) { + if (other.getChannel(i) !== this.getChannel(i)) { + return false; + } + } + return true; + } + + public convert(opt?: ColorConvertOptions) { + return ColorUtils.convertColor({ + from: this, + format: opt?.format, + numChannels: opt?.numChannels, + alpha: opt?.alpha, + }); + } +} diff --git a/src/color/color-uint8.ts b/src/color/color-uint8.ts new file mode 100644 index 0000000..02bab75 --- /dev/null +++ b/src/color/color-uint8.ts @@ -0,0 +1,221 @@ +/** @format */ + +import { ArrayUtils } from '../common/array-utils'; +import { Palette } from '../image/palette'; +import { Channel } from './channel'; +import { Color, ColorConvertOptions } from './color'; +import { ColorUtils } from './color-utils'; +import { Format } from './format'; + +/** + * An 8-bit unsigned int color with channel values in the range [0, 255]. + */ +export class ColorUint8 implements Color { + protected data: Uint8Array; + + public get format(): Format { + return Format.uint8; + } + + public get length(): number { + return this.data.length; + } + + public get maxChannelValue(): number { + return 255; + } + + public get maxIndexValue(): number { + return 255; + } + + public get isLdrFormat(): boolean { + return true; + } + + public get isHdrFormat(): boolean { + return false; + } + + public get hasPalette(): boolean { + return false; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get r(): number { + return this.getChannel(0); + } + public set r(r: number) { + this.setChannel(0, r); + } + + public get g(): number { + return this.getChannel(1); + } + public set g(g: number) { + this.setChannel(1, g); + } + + public get b(): number { + return this.getChannel(2); + } + public set b(b: number) { + this.setChannel(2, b); + } + + public get a(): number { + return this.getChannel(3, 255); + } + public set a(a: number) { + this.setChannel(3, a); + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor(data: Uint8Array | number) { + if (typeof data === 'number') { + this.data = new Uint8Array(data); + } else { + this.data = data.slice(); + } + } + + public static from(other: ColorUint8) { + const c = new ColorUint8(other.length); + c.data = other.data; + return c; + } + + public static fromArray(color: Uint8Array) { + return new ColorUint8(color); + } + + public static rgb(r: number, g: number, b: number) { + const data = new Uint8Array([r, g, b]); + return new ColorUint8(data); + } + + public static rgba(r: number, g: number, b: number, a: number) { + const data = new Uint8Array([r, g, b, a]); + return new ColorUint8(data); + } + + public getChannel(channel: number | Channel, defValue = 0): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.data.length ? this.data[channel] : defValue; + } + } + + public getChannelNormalized(channel: number | Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(index: number | Channel, value: number): void { + if (index < this.data.length) { + this.data[index] = Math.trunc(value); + } + } + + public set(c: Color): void { + this.setRgba(c.r, c.g, c.b, c.a); + } + + public setRgb(r: number, g: number, b: number): void { + this.data[0] = Math.trunc(r); + const nc = this.data.length; + if (nc > 1) { + this.data[1] = Math.trunc(g); + if (nc > 2) { + this.data[2] = Math.trunc(b); + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + this.data[0] = Math.trunc(r); + const nc = this.data.length; + if (nc > 1) { + this.data[1] = Math.trunc(g); + if (nc > 2) { + this.data[2] = Math.trunc(b); + if (nc > 3) { + this.data[3] = Math.trunc(a); + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone() { + return ColorUint8.from(this); + } + + public equals(other: Color) { + if (other.length !== this.length) { + return false; + } + for (let i = 0; i < this.length; i++) { + if (other.getChannel(i) !== this.getChannel(i)) { + return false; + } + } + return true; + } + + public convert(opt?: ColorConvertOptions) { + return ColorUtils.convertColor({ + from: this, + format: opt?.format, + numChannels: opt?.numChannels, + alpha: opt?.alpha, + }); + } +} diff --git a/src/color/color-utils.ts b/src/color/color-utils.ts new file mode 100644 index 0000000..5f06c01 --- /dev/null +++ b/src/color/color-utils.ts @@ -0,0 +1,595 @@ +/** @format */ + +import { MathUtils } from '../common/math-utils'; +import { LibError } from '../error/lib-error'; +import { Color } from './color'; +import { ColorFloat16 } from './color-float16'; +import { ColorFloat32 } from './color-float32'; +import { ColorFloat64 } from './color-float64'; +import { ColorInt16 } from './color-int16'; +import { ColorInt32 } from './color-int32'; +import { ColorInt8 } from './color-int8'; +import { ColorUint1 } from './color-uint1'; +import { ColorUint16 } from './color-uint16'; +import { ColorUint2 } from './color-uint2'; +import { ColorUint32 } from './color-uint32'; +import { ColorUint4 } from './color-uint4'; +import { ColorUint8 } from './color-uint8'; +import { convertFormatValue, Format } from './format'; + +export interface ConvertColorOptions { + from: Color; + to?: Color; + format?: Format; + numChannels?: number; + alpha?: number; +} + +export abstract class ColorUtils { + private static convertColorInternal(c: Color, c2: Color, a: number): Color { + const numChannels = c2.length; + const format = c2.format; + const fromFormat = c.palette?.format ?? c.format; + const cl = c.length; + if (numChannels === 1) { + const g = Math.trunc(c.length > 2 ? c.luminance : c.getChannel(0)); + c2.setChannel(0, convertFormatValue(g, fromFormat, format)); + } else if (numChannels <= cl) { + for (let ci = 0; ci < numChannels; ++ci) { + c2.setChannel( + ci, + convertFormatValue(c.getChannel(ci), fromFormat, format) + ); + } + } else { + for (let ci = 0; ci < cl; ++ci) { + c2.setChannel( + ci, + convertFormatValue(c.getChannel(ci), fromFormat, format) + ); + } + const v = cl === 1 ? c2.getChannel(0) : 0; + for (let ci = cl; ci < numChannels; ++ci) { + c2.setChannel(ci, ci === 3 ? a : v); + } + } + return c2; + } + + public static uint32ToRed(c: number): number { + return c & 0xff; + } + + public static uint32ToGreen(c: number): number { + return (c >> 8) & 0xff; + } + + public static uint32ToBlue(c: number): number { + return (c >> 16) & 0xff; + } + + public static uint32ToAlpha(c: number): number { + return (c >> 24) & 0xff; + } + + public static rgbaToUint32( + r: number, + g: number, + b: number, + a: number + ): number { + return ( + MathUtils.clampInt255(r) | + (MathUtils.clampInt255(g) << 8) | + (MathUtils.clampInt255(b) << 16) | + (MathUtils.clampInt255(a) << 24) + ); + } + + public static convertColor(opt: ConvertColorOptions): Color { + const fromFormat = opt.from.palette?.format ?? opt.from.format; + const format = opt.to?.format ?? opt.format ?? opt.from.format; + const numChannels = opt.to?.length ?? opt.numChannels ?? opt.from.length; + const alpha = opt.alpha ?? 0; + + if (format === fromFormat && numChannels === opt.from.length) { + if (opt.to === undefined) { + return opt.from.clone(); + } + opt.to.set(opt.from); + return opt.to; + } + + switch (format) { + case Format.uint8: { + const c2 = opt.to ?? new ColorUint8(numChannels); + return this.convertColorInternal(opt.from, c2, alpha); + } + case Format.uint1: { + const c2 = opt.to ?? new ColorUint1(numChannels); + return this.convertColorInternal(opt.from, c2, alpha); + } + case Format.uint2: { + const c2 = opt.to ?? new ColorUint2(numChannels); + return this.convertColorInternal(opt.from, c2, alpha); + } + case Format.uint4: { + const c2 = opt.to ?? new ColorUint4(numChannels); + return this.convertColorInternal(opt.from, c2, alpha); + } + case Format.uint16: { + const c2 = opt.to ?? new ColorUint16(numChannels); + return this.convertColorInternal(opt.from, c2, alpha); + } + case Format.uint32: { + const c2 = opt.to ?? new ColorUint32(numChannels); + return this.convertColorInternal(opt.from, c2, alpha); + } + case Format.int8: { + const c2 = opt.to ?? new ColorInt8(numChannels); + return this.convertColorInternal(opt.from, c2, alpha); + } + case Format.int16: { + const c2 = opt.to ?? new ColorInt16(numChannels); + return this.convertColorInternal(opt.from, c2, alpha); + } + case Format.int32: { + const c2 = opt.to ?? new ColorInt32(numChannels); + return this.convertColorInternal(opt.from, c2, alpha); + } + case Format.float16: { + const c2 = opt.to ?? new ColorFloat16(numChannels); + return this.convertColorInternal(opt.from, c2, alpha); + } + case Format.float32: { + const c2 = opt.to ?? new ColorFloat32(numChannels); + return this.convertColorInternal(opt.from, c2, alpha); + } + case Format.float64: { + const c2 = opt.to ?? new ColorFloat64(numChannels); + return this.convertColorInternal(opt.from, c2, alpha); + } + } + throw new LibError('Unknown format.'); + } + + /** + * Returns the luminance (grayscale) value of the color. + */ + public static getLuminance(c: Color): number { + return 0.299 * c.r + 0.587 * c.g + 0.114 * c.b; + } + + /** + * Returns the normalized [0, 1] luminance (grayscale) value of the color. + */ + public static getLuminanceNormalized(c: Color): number { + return ( + 0.299 * c.rNormalized + 0.587 * c.gNormalized + 0.114 * c.bNormalized + ); + } + + /** + * Returns the luminance (grayscale) value of the color. + */ + public static getLuminanceRgb(r: number, g: number, b: number): number { + return 0.299 * r + 0.587 * g + 0.114 * b; + } + + /** + * Convert an HSL color to RGB, where **hue** is specified in normalized degrees + * [0, 1] (where 1 is 360-degrees); **saturation** and **lightness** are in the range [0, 1]. + * Returns a list [r, g, b] with values in the range [0, 255]. + */ + public static hslToRgb( + hue: number, + saturation: number, + lightness: number + ): number[] { + if (saturation === 0) { + const gray = Math.trunc(lightness * 255); + return [gray, gray, gray]; + } + + const hue2rgb = (p: number, q: number, t: number): number => { + let _t = t; + if (_t < 0) { + _t += 1; + } + if (_t > 1) { + _t -= 1; + } + if (_t < 1 / 6) { + return p + (q - p) * 6 * _t; + } + if (_t < 1 / 2) { + return q; + } + if (_t < 2 / 3) { + return p + (q - p) * (2 / 3 - _t) * 6; + } + return p; + }; + + const q = + lightness < 0.5 + ? lightness * (1 + saturation) + : lightness + saturation - lightness * saturation; + const p = 2 * lightness - q; + + const r = hue2rgb(p, q, hue + 1 / 3); + const g = hue2rgb(p, q, hue); + const b = hue2rgb(p, q, hue - 1 / 3); + + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; + } + + /** + * Convert an HSV color to RGB, where **hue** is specified in normalized degrees + * [0, 1] (where 1 is 360-degrees); **saturation** and **brightness** are in the range [0, 1]. + * Returns a list [r, g, b] with values in the range [0, 255]. + */ + public static hsvToRgb( + hue: number, + saturation: number, + brightness: number + ): number[] { + if (saturation === 0) { + const gray = Math.round(brightness * 255); + return [gray, gray, gray]; + } + + const h = (hue - Math.floor(hue)) * 6; + const f = h - Math.floor(h); + const p = brightness * (1 - saturation); + const q = brightness * (1 - saturation * f); + const t = brightness * (1 - saturation * (1 - f)); + + switch (Math.trunc(h)) { + case 0: + return [ + Math.round(brightness * 255), + Math.round(t * 255), + Math.round(p * 255), + ]; + case 1: + return [ + Math.round(q * 255), + Math.round(brightness * 255), + Math.round(p * 255), + ]; + case 2: + return [ + Math.round(p * 255), + Math.round(brightness * 255), + Math.round(t * 255), + ]; + case 3: + return [ + Math.round(p * 255), + Math.round(q * 255), + Math.round(brightness * 255), + ]; + case 4: + return [ + Math.round(t * 255), + Math.round(p * 255), + Math.round(brightness * 255), + ]; + case 5: + return [ + Math.round(brightness * 255), + Math.round(p * 255), + Math.round(q * 255), + ]; + default: + throw new LibError('Invalid hue.'); + } + } + + /** + * Convert an RGB color to HSL, where **r**, **g** and **b** are in the range [0, 255]. + * Returns a list [h, s, l] with values in the range [0, 1]. + */ + public static rgbToHsl(r: number, g: number, b: number): number[] { + const _r = r / 255; + const _g = g / 255; + const _b = b / 255; + const mx = Math.max(_r, Math.max(_g, _b)); + const mn = Math.min(_r, Math.min(_g, _b)); + const l = (mx + mn) / 2; + + if (mx === mn) { + return [0, 0, l]; + } + + const d = mx - mn; + + const s = l > 0.5 ? d / (2 - mx - mn) : d / (mx + mn); + + let h = 0; + if (mx === _r) { + h = (_g - _b) / d + (_g < _b ? 6 : 0); + } else if (mx === _g) { + h = (_b - _r) / d + 2; + } else { + h = (_r - _g) / d + 4; + } + + h /= 6; + + return [h, s, l]; + } + + /** + * Convert a CIE L\*a\*b color to XYZ. + */ + public static labToXyz(l: number, a: number, b: number): number[] { + let y = (l + 16) / 116; + let x = y + a / 500; + let z = y - b / 200; + if (Math.pow(x, 3) > 0.008856) { + x = Math.pow(x, 3); + } else { + x = (x - 16 / 116) / 7.787; + } + if (Math.pow(y, 3) > 0.008856) { + y = Math.pow(y, 3); + } else { + y = (y - 16 / 116) / 7.787; + } + if (Math.pow(z, 3) > 0.008856) { + z = Math.pow(z, 3); + } else { + z = (z - 16 / 116) / 7.787; + } + + return [ + Math.trunc(x * 95.047), + Math.trunc(y * 100), + Math.trunc(z * 108.883), + ]; + } + + /** + * Convert an XYZ color to RGB. + */ + public static xyzToRgb(x: number, y: number, z: number): number[] { + const _x = x / 100; + const _y = y / 100; + const _z = z / 100; + let r = 3.2406 * _x + -1.5372 * _y + -0.4986 * _z; + let g = -0.9689 * _x + 1.8758 * _y + 0.0415 * _z; + let b = 0.0557 * _x + -0.204 * _y + 1.057 * _z; + if (r > 0.0031308) { + r = 1.055 * Math.pow(r, 0.4166666667) - 0.055; + } else { + r *= 12.92; + } + if (g > 0.0031308) { + g = 1.055 * Math.pow(g, 0.4166666667) - 0.055; + } else { + g *= 12.92; + } + if (b > 0.0031308) { + b = 1.055 * Math.pow(b, 0.4166666667) - 0.055; + } else { + b *= 12.92; + } + + return [ + MathUtils.clampInt255(r * 255), + MathUtils.clampInt255(g * 255), + MathUtils.clampInt255(b * 255), + ]; + } + + /** + * Convert a CMYK color to RGB, where **c**, **m**, **y**, **k** values are in the range + * [0, 255]. Returns a list [r, g, b] with values in the range [0, 255]. + */ + public static cmykToRgb( + c: number, + m: number, + y: number, + k: number + ): number[] { + const _c = c / 255; + const _m = m / 255; + const _y = y / 255; + const _k = k / 255; + return [ + Math.round(255 * (1 - _c) * (1 - _k)), + Math.round(255 * (1 - _m) * (1 - _k)), + Math.round(255 * (1 - _y) * (1 - _k)), + ]; + } + + /** + * Convert a CIE L\*a\*b color to RGB. + */ + public static labToRgb(l: number, a: number, b: number): number[] { + const refX = 95.047; + const refY = 100.0; + const refZ = 108.883; + + let y = (l + 16) / 116; + let x = a / 500 + y; + let z = y - b / 200; + + const y3 = Math.pow(y, 3); + if (y3 > 0.008856) { + y = y3; + } else { + y = (y - 16 / 116) / 7.787; + } + + const x3 = Math.pow(x, 3); + if (x3 > 0.008856) { + x = x3; + } else { + x = (x - 16 / 116) / 7.787; + } + + const z3 = Math.pow(z, 3); + if (z3 > 0.008856) { + z = z3; + } else { + z = (z - 16 / 116) / 7.787; + } + + x *= refX; + y *= refY; + z *= refZ; + + x /= 100; + y /= 100; + z /= 100; + + // xyz to rgb + let R = x * 3.2406 + y * -1.5372 + z * -0.4986; + let G = x * -0.9689 + y * 1.8758 + z * 0.0415; + let B = x * 0.0557 + y * -0.204 + z * 1.057; + + if (R > 0.0031308) { + R = 1.055 * Math.pow(R, 1 / 2.4) - 0.055; + } else { + R *= 12.92; + } + + if (G > 0.0031308) { + G = 1.055 * Math.pow(G, 1 / 2.4) - 0.055; + } else { + G *= 12.92; + } + + if (B > 0.0031308) { + B = 1.055 * Math.pow(B, 1 / 2.4) - 0.055; + } else { + B *= 12.92; + } + + return [ + MathUtils.clampInt255(R * 255), + MathUtils.clampInt255(G * 255), + MathUtils.clampInt255(B * 255), + ]; + } + + /** + * Convert a RGB color to XYZ. + */ + public static rgbToXyz(r: number, g: number, b: number): number[] { + let _r = r / 255; + let _g = g / 255; + let _b = b / 255; + + if (_r > 0.04045) { + _r = Math.pow((_r + 0.055) / 1.055, 2.4); + } else { + _r /= 12.92; + } + if (_g > 0.04045) { + _g = Math.pow((_g + 0.055) / 1.055, 2.4); + } else { + _g /= 12.92; + } + if (_b > 0.04045) { + _b = Math.pow((_b + 0.055) / 1.055, 2.4); + } else { + _b /= 12.92; + } + + _r *= 100; + _g *= 100; + _b *= 100; + + return [ + _r * 0.4124 + _g * 0.3576 + _b * 0.1805, + _r * 0.2126 + _g * 0.7152 + _b * 0.0722, + _r * 0.0193 + _g * 0.1192 + _b * 0.9505, + ]; + } + + /** + * Convert a XYZ color to CIE L\*a\*b. + */ + public static xyzToLab(x: number, y: number, z: number): number[] { + let _x = x / 95.047; + let _y = y / 100; + let _z = z / 108.883; + + if (_x > 0.008856) { + _x = Math.pow(_x, 1 / 3); + } else { + _x = 7.787 * _x + 16 / 116; + } + if (_y > 0.008856) { + _y = Math.pow(_y, 1 / 3); + } else { + _y = 7.787 * _y + 16 / 116; + } + if (_z > 0.008856) { + _z = Math.pow(_z, 1 / 3); + } else { + _z = 7.787 * _z + 16 / 116; + } + + return [116 * _y - 16, 500 * (_x - _y), 200 * (_y - _z)]; + } + + /** + * Convert a RGB color to CIE L\*a\*b. + */ + public static rgbToLab(r: number, g: number, b: number): number[] { + let _r = r / 255; + let _g = g / 255; + let _b = b / 255; + + if (_r > 0.04045) { + _r = Math.pow((_r + 0.055) / 1.055, 2.4); + } else { + _r /= 12.92; + } + if (_g > 0.04045) { + _g = Math.pow((_g + 0.055) / 1.055, 2.4); + } else { + _g /= 12.92; + } + if (_b > 0.04045) { + _b = Math.pow((_b + 0.055) / 1.055, 2.4); + } else { + _b /= 12.92; + } + + _r *= 100; + _g *= 100; + _b *= 100; + + let x = _r * 0.4124 + _g * 0.3576 + _b * 0.1805; + let y = _r * 0.2126 + _g * 0.7152 + _b * 0.0722; + let z = _r * 0.0193 + _g * 0.1192 + _b * 0.9505; + + x /= 95.047; + y /= 100; + z /= 108.883; + + if (x > 0.008856) { + x = Math.pow(x, 1 / 3); + } else { + x = 7.787 * x + 16 / 116; + } + if (y > 0.008856) { + y = Math.pow(y, 1 / 3); + } else { + y = 7.787 * y + 16 / 116; + } + if (z > 0.008856) { + z = Math.pow(z, 1 / 3); + } else { + z = 7.787 * z + 16 / 116; + } + + return [116 * y - 16, 500 * (x - y), 200 * (y - z)]; + } +} diff --git a/src/color/color.ts b/src/color/color.ts new file mode 100644 index 0000000..5c5ad37 --- /dev/null +++ b/src/color/color.ts @@ -0,0 +1,145 @@ +/** @format */ + +import { Palette } from '../image/palette'; +import { Channel } from './channel'; +import { Format } from './format'; + +export interface ColorConvertOptions { + format?: Format; + numChannels?: number; + alpha?: number; +} + +/** + * The abstract Color class is the base class for all specific color classes + * and Pixel classes. + */ +export interface Color { + /** + * The number of channels used by the color. + */ + get length(): number; + /** + * The maximum value for a color channel. + */ + get maxChannelValue(): number; + /** + * The maximum value for a palette index. + */ + get maxIndexValue(): number; + /** + * The Format of the color. + */ + get format(): Format; + /** + * True if the format is low dynamic range. + */ + get isLdrFormat(): boolean; + /** + * True if the format is high dynamic range. + */ + get isHdrFormat(): boolean; + /** + * True if the color uses a palette. + */ + get hasPalette(): boolean; + /** + * The palette used by the color, or undefined. + */ + get palette(): Palette | undefined; + /** + * Palette index value (or red channel if there is no palette). + */ + get index(): number; + set index(i: number); + /** + * Red channel. + */ + get r(): number; + set r(r: number); + /** + * Green channel. + */ + get g(): number; + set g(g: number); + /** + * Blue channel. + */ + get b(): number; + set b(b: number); + /** + * Alpha channel. + */ + get a(): number; + set a(a: number); + /** + * Normalized [0, 1] red. + */ + get rNormalized(): number; + set rNormalized(v: number); + /** + * Normalized [0, 1] green. + */ + get gNormalized(): number; + set gNormalized(v: number); + /** + * Normalized [0, 1] blue. + */ + get bNormalized(): number; + set bNormalized(v: number); + /** + * Normalized [0, 1] alpha. + */ + get aNormalized(): number; + set aNormalized(v: number); + /** + * The luminance (grayscale) of the color. + */ + get luminance(): number; + get luminanceNormalized(): number; + /** + * Gets a channel from the color by its index or Channel enum. + * If the channel isn't available, 0 will be returned. + */ + getChannel(channel: number | Channel): number; + /** + * Sets a channel to the color by its index. + */ + setChannel(channel: number | Channel, value: number): void; + /** + * Get the normalized [0, 1] value of A channel from the color. If the + * channel isn't available, 0 will be returned. + */ + getChannelNormalized(channel: number | Channel): number; + /** + * The the values of this color to the given Color. + */ + set(color: Color): void; + /** + * Set the individual **r**, **g**, **b** channels of the color. + */ + setRgb(r: number, g: number, b: number): void; + /** + * Set the individual **r**, **g**, **b**, **a** channels of the color. + */ + setRgba(r: number, g: number, b: number, a: number): void; + /** + * Converts the color to an array of channels. + */ + toArray(): number[]; + /** + * Returns a copy of the color. + */ + clone(): Color; + /** + * Convert the **format** and/or the **numChannels** of the color. If + * **numChannels** is 4 and the current color does not have an alpha value, + * then **alpha** can specify what value to use for the new alpha channel. + * If **alpha** is not given, then **maxChannelValue** will be used. + */ + convert(opt: ColorConvertOptions): Color; + /** + * Tests if this color is equivalent to another **Color**. + */ + equals(other: Color | number[]): boolean; +} diff --git a/src/color/format.ts b/src/color/format.ts new file mode 100644 index 0000000..c9fe565 --- /dev/null +++ b/src/color/format.ts @@ -0,0 +1,343 @@ +/** @format */ + +import { MathUtils } from '../common/math-utils'; +import { LibError } from '../error/lib-error'; + +/** + * The format of a color or image. + */ +export enum Format { + uint1, + uint2, + uint4, + uint8, + uint16, + uint32, + int8, + int16, + int32, + float16, + float32, + float64, +} + +/** + * The format type of a color or image. + */ +export enum FormatType { + uint, + int, + float, +} + +export const FormatToFormatType = new Map([ + [Format.uint1, FormatType.uint], + [Format.uint2, FormatType.uint], + [Format.uint4, FormatType.uint], + [Format.uint8, FormatType.uint], + [Format.uint16, FormatType.uint], + [Format.uint32, FormatType.uint], + [Format.int8, FormatType.int], + [Format.int16, FormatType.int], + [Format.int32, FormatType.int], + [Format.float16, FormatType.float], + [Format.float32, FormatType.float], + [Format.float64, FormatType.float], +]); + +export const FormatSize = new Map([ + [Format.uint1, 1], + [Format.uint2, 1], + [Format.uint4, 1], + [Format.uint8, 1], + [Format.uint16, 2], + [Format.uint32, 4], + [Format.int8, 1], + [Format.int16, 2], + [Format.int32, 4], + [Format.float16, 2], + [Format.float32, 4], + [Format.float64, 8], +]); + +export const FormatMaxValue = new Map([ + [Format.uint1, 0x1], + [Format.uint2, 0x3], + [Format.uint4, 0xf], + [Format.uint8, 0xff], + [Format.uint16, 0xffff], + [Format.uint32, 0xffffffff], + [Format.int8, 0x7f], + [Format.int16, 0x7fff], + [Format.int32, 0x7fffffff], + [Format.float16, 1], + [Format.float32, 1], + [Format.float64, 1], +]); + +/** + * Convert a value from the **from** format to the **to** format. + */ +export function convertFormatValue( + value: number, + from: Format, + to: Format +): number { + if (from === to) { + return value; + } + + switch (from) { + case Format.uint1: + return value === 0 ? 0 : FormatMaxValue.get(to)!; + case Format.uint2: + switch (to) { + case Format.uint1: + return value === 0 ? 0 : 1; + case Format.uint2: + return value; + case Format.uint4: + return value * 5; + case Format.uint8: + return value * 75; + case Format.uint16: + return value * 21845; + case Format.uint32: + return value * 1431655765; + case Format.int8: + return value * 42; + case Format.int16: + return value * 10922; + case Format.int32: + return value * 715827882; + case Format.float16: + case Format.float32: + case Format.float64: + return value / 3; + } + break; + case Format.uint4: + switch (to) { + case Format.uint1: + return value === 0 ? 0 : 1; + case Format.uint2: + return Math.trunc(value) >> 1; + case Format.uint4: + return value; + case Format.uint8: + return value * 17; + case Format.uint16: + return value * 4369; + case Format.uint32: + return value * 286331153; + case Format.int8: + return value * 8; + case Format.int16: + return value * 2184; + case Format.int32: + return value * 143165576; + case Format.float16: + case Format.float32: + case Format.float64: + return value / 3; + } + break; + case Format.uint8: + switch (to) { + case Format.uint1: + return value === 0 ? 0 : 1; + case Format.uint2: + return Math.trunc(value) >> 6; + case Format.uint4: + return Math.trunc(value) >> 4; + case Format.uint8: + return value; + case Format.uint16: + return value * 257; + case Format.uint32: + return value * 16843009; + case Format.int8: + return Math.trunc(value) >> 1; + case Format.int16: + return value * 128; + case Format.int32: + return value * 8421504; + case Format.float16: + case Format.float32: + case Format.float64: + return value / 255; + } + break; + case Format.uint16: + switch (to) { + case Format.uint1: + return value === 0 ? 0 : 1; + case Format.uint2: + return Math.trunc(value) >> 14; + case Format.uint4: + return Math.trunc(value) >> 12; + case Format.uint8: + return Math.trunc(value) >> 8; + case Format.uint16: + return value; + case Format.uint32: + return Math.trunc(value) << 8; + case Format.int8: + return Math.trunc(value) >> 9; + case Format.int16: + return Math.trunc(value) >> 1; + case Format.int32: + return value * 524296; + case Format.float16: + case Format.float32: + case Format.float64: + return value / 0xffff; + } + break; + case Format.uint32: + switch (to) { + case Format.uint1: + return value === 0 ? 0 : 1; + case Format.uint2: + return Math.trunc(value) >> 30; + case Format.uint4: + return Math.trunc(value) >> 28; + case Format.uint8: + return Math.trunc(value) >> 24; + case Format.uint16: + return Math.trunc(value) >> 16; + case Format.uint32: + return value; + case Format.int8: + return Math.trunc(value) >> 25; + case Format.int16: + return Math.trunc(value) >> 17; + case Format.int32: + return Math.trunc(value) >> 1; + case Format.float16: + case Format.float32: + case Format.float64: + return value / 0xffffffff; + } + break; + case Format.int8: + switch (to) { + case Format.uint1: + return value === 0 ? 0 : 1; + case Format.uint2: + return value <= 0 ? 0 : Math.trunc(value) >> 5; + case Format.uint4: + return value <= 0 ? 0 : Math.trunc(value) >> 3; + case Format.uint8: + return value <= 0 ? 0 : Math.trunc(value) << 1; + case Format.uint16: + return value <= 0 ? 0 : Math.trunc(value) * 516; + case Format.uint32: + return value <= 0 ? 0 : Math.trunc(value) * 33818640; + case Format.int8: + return value; + case Format.int16: + return value * 258; + case Format.int32: + return value * 16909320; + case Format.float16: + case Format.float32: + case Format.float64: + return value / 127; + } + break; + case Format.int16: + switch (to) { + case Format.uint1: + return value === 0 ? 0 : 1; + case Format.uint2: + return value <= 0 ? 0 : Math.trunc(value) >> 15; + case Format.uint4: + return value <= 0 ? 0 : Math.trunc(value) >> 11; + case Format.uint8: + return value <= 0 ? 0 : Math.trunc(value) >> 7; + case Format.uint16: + return value <= 0 ? 0 : Math.trunc(value) << 1; + case Format.uint32: + return value <= 0 ? 0 : Math.trunc(value) * 131076; + case Format.int8: + return Math.trunc(value) >> 8; + case Format.int16: + return value; + case Format.int32: + return Math.trunc(value) * 65538; + case Format.float16: + case Format.float32: + case Format.float64: + return value / 0x7fff; + } + break; + case Format.int32: + switch (to) { + case Format.uint1: + return value === 0 ? 0 : 1; + case Format.uint2: + return value <= 0 ? 0 : Math.trunc(value) >> 29; + case Format.uint4: + return value <= 0 ? 0 : Math.trunc(value) >> 27; + case Format.uint8: + return value <= 0 ? 0 : Math.trunc(value) >> 23; + case Format.uint16: + return value <= 0 ? 0 : Math.trunc(value) >> 16; + case Format.uint32: + return value <= 0 ? 0 : Math.trunc(value) << 1; + case Format.int8: + return Math.trunc(value) >> 24; + case Format.int16: + return Math.trunc(value) >> 16; + case Format.int32: + return value; + case Format.float16: + case Format.float32: + case Format.float64: + return value / 0x7fffffff; + } + break; + case Format.float16: + case Format.float32: + case Format.float64: + switch (to) { + case Format.uint1: + return value === 0 ? 0 : 1; + case Format.uint2: + return Math.trunc(MathUtils.clamp(value, 0, 1) * 3); + case Format.uint4: + return Math.trunc(MathUtils.clamp(value, 0, 1) * 15); + case Format.uint8: + return Math.trunc(MathUtils.clamp(value, 0, 1) * 255); + case Format.uint16: + return Math.trunc(MathUtils.clamp(value, 0, 1) * 0xffff); + case Format.uint32: + return Math.trunc(MathUtils.clamp(value, 0, 1) * 0xffffffff); + case Format.int8: + return Math.trunc( + value < 0 + ? MathUtils.clamp(value, -1, 1) * 128 + : MathUtils.clamp(value, -1, 1) * 127 + ); + case Format.int16: + return Math.trunc( + value < 0 + ? MathUtils.clamp(value, -1, 1) * 32768 + : MathUtils.clamp(value, -1, 1) * 32767 + ); + case Format.int32: + return Math.trunc( + value < 0 + ? MathUtils.clamp(value, -1, 1) * 2147483648 + : MathUtils.clamp(value, -1, 1) * 2147483647 + ); + case Format.float16: + case Format.float32: + case Format.float64: + return value; + } + break; + } + throw new LibError('Unknown format.'); +} diff --git a/src/common/array-utils.ts b/src/common/array-utils.ts index c57d469..a61267c 100644 --- a/src/common/array-utils.ts +++ b/src/common/array-utils.ts @@ -1,6 +1,7 @@ /** @format */ -import { ImageError } from '../error/image-error'; +import { LibError } from '../error/lib-error'; +import { Rational } from './rational'; import { TypedArray } from './typings'; export abstract class ArrayUtils { @@ -90,17 +91,89 @@ export abstract class ArrayUtils { } else if (from instanceof Float64Array) { return ArrayUtils.copyFloat64(from, begin, end); } - throw new ImageError('Unknown array type'); + throw new LibError('Unknown array type'); } - public static setRange( - to: T, - start: number, - end: number, + public static copyRange( from: T, - skipCount = 0 + fromStart: number, + fromEnd: number, + to: T, + toStart: number ): void { - const viewFrom = from.subarray(skipCount, end - start); - to.set(viewFrom, start); + const viewFrom = from.subarray(fromStart, fromEnd); + to.set(viewFrom, toStart); + } + + public static fill(length: number, value: T): T[] { + const a = new Array(length); + return a.fill(value); + } + + public static generate(length: number, func: (index: number) => T): T[] { + const a = new Array(length); + for (let i = 0; i < length; ++i) { + a[i] = func(i); + } + return a; + } + + public static equals( + a1: TypedArray | unknown[], + a2: TypedArray | unknown[] + ): boolean { + if (a1 === a2) return true; + if (a1.length !== a2.length) return false; + for (let i = 0, l = a1.length; i < l; i++) { + if ( + ArrayUtils.isNumArrayOrTypedArray(a1[i]) && + ArrayUtils.isNumArrayOrTypedArray(a2[i]) + ) { + if ( + !ArrayUtils.equals( + a1[i] as TypedArray | unknown[], + a2[i] as TypedArray | unknown[] + ) + ) + return false; + } else if (a1[i] !== a2[i]) { + return false; + } + } + return true; + } + + public static equalsRationalArray(a1: Rational[], a2: Rational[]): boolean { + if (a1 === a2) return true; + if (a1.length !== a2.length) return false; + for (let i = 0, l = a1.length; i < l; i++) { + if (!a1[i].equals(a2[i])) { + return false; + } + } + return true; + } + + public static getNumEnumValues(t: T): number[] { + return Object.values(t).filter((v) => typeof v === 'number'); + } + + public static isNumArrayOrTypedArray(obj: unknown) { + return Boolean( + obj && + typeof obj === 'object' && + ((Array.isArray(obj) && + (obj as Array).every((v) => typeof v === 'number')) || + (ArrayBuffer.isView(obj) && !(obj instanceof DataView))) + ); + } + + public static isArrayOfRational(obj: unknown) { + return Boolean( + obj && + typeof obj === 'object' && + Array.isArray(obj) && + (obj as Array).every((v) => v instanceof Rational) + ); } } diff --git a/src/common/bit-operators.ts b/src/common/bit-operators.ts deleted file mode 100644 index 0611a07..0000000 --- a/src/common/bit-operators.ts +++ /dev/null @@ -1,131 +0,0 @@ -/** @format */ - -export abstract class BitOperators { - private static readonly uint8arr: Uint8Array = new Uint8Array(1); - private static readonly uint8ToInt8arr: Int8Array = new Int8Array( - BitOperators.uint8arr.buffer - ); - private static readonly int8arr: Int8Array = new Int8Array(1); - private static readonly int8ToUint8arr: Uint8Array = new Uint8Array( - BitOperators.int8arr.buffer - ); - private static readonly uint16arr: Uint16Array = new Uint16Array(1); - private static readonly uint16ToInt16arr: Int16Array = new Int16Array( - BitOperators.uint16arr.buffer - ); - private static readonly int16arr: Int16Array = new Int16Array(1); - private static readonly int16ToUint16arr: Uint16Array = new Uint16Array( - BitOperators.int16arr.buffer - ); - private static readonly uint32arr: Uint32Array = new Uint32Array(1); - private static readonly uint32ToInt32arr: Int32Array = new Int32Array( - BitOperators.uint32arr.buffer - ); - private static readonly int32arr: Int32Array = new Int32Array(1); - private static readonly int32ToUint32arr: Uint32Array = new Uint32Array( - BitOperators.int32arr.buffer - ); - private static readonly uint32ToFloat32arr: Float32Array = new Float32Array( - BitOperators.uint32arr.buffer - ); - private static readonly uint64arr: BigUint64Array = new BigUint64Array(1); - private static readonly uint64ToFloat64arr: Float64Array = new Float64Array( - BitOperators.uint64arr.buffer - ); - - public static signed(bits: number, value: number) { - return value & (1 << (bits - 1)) ? value - (1 << bits) : value; - } - - public static shiftR(v: number, n: number): number { - return BitOperators.signed(32, v >> n); - } - - public static shiftL(v: number, n: number): number { - return BitOperators.signed(32, v << n); - } - - /** - * Binary conversion to an int8. This is equivalent in C to - * typecasting to a char. - */ - public static toInt8(d: number): number { - BitOperators.uint8arr[0] = d; - return BitOperators.uint8ToInt8arr[0]; - } - - /** - * Binary conversion to an uint8. This is equivalent in C to - * typecasting to an unsigned char. - */ - public static toUint8(d: number): number { - BitOperators.int8arr[0] = d; - return BitOperators.int8ToUint8arr[0]; - } - - /** - * Binary conversion to an int16. This is equivalent in C to - * typecasting to a short. - */ - public static toInt16(d: number): number { - BitOperators.uint16arr[0] = d; - return BitOperators.uint16ToInt16arr[0]; - } - - /** - * Binary conversion to an uint16. This is equivalent in C to - * typecasting to an unsigned short. - */ - public static toUint16(d: number): number { - BitOperators.int16arr[0] = d; - return BitOperators.int16ToUint16arr[0]; - } - - /** - * Binary conversion to an int32. This is equivalent in C to - * typecasting to signed int. - */ - public static toInt32(d: number): number { - BitOperators.uint32arr[0] = d; - return BitOperators.uint32ToInt32arr[0]; - } - - /** - * Binary conversion of an int32 to a uint32. This is equivalent in C to - * typecasting to unsigned int. - */ - public static toUint32(d: number): number { - BitOperators.int32arr[0] = d; - return BitOperators.int32ToUint32arr[0]; - } - - /** - * Binary conversion to a float32. This is equivalent in C to - * typecasting to float. - */ - public static toFloat32(d: number): number { - BitOperators.uint32arr[0] = d; - return BitOperators.uint32ToFloat32arr[0]; - } - - /** - * Binary conversion to a float64. This is equivalent in C to - * typecasting to double. - */ - public static toFloat64(d: bigint): number { - BitOperators.uint64arr[0] = d; - return BitOperators.uint64ToFloat64arr[0]; - } - - public static debugBits32(value?: number): string { - if (value === undefined) { - return 'undefined'; - } - const bitCount = 32; - let result = ''; - for (let i = bitCount; i > -1; i--) { - result += (value & (1 << i)) === 0 ? '0' : '1'; - } - return result; - } -} diff --git a/src/common/bit-utils.ts b/src/common/bit-utils.ts new file mode 100644 index 0000000..ad35689 --- /dev/null +++ b/src/common/bit-utils.ts @@ -0,0 +1,191 @@ +/** @format */ + +export abstract class BitUtils { + private static readonly _uint8 = new Uint8Array(1); + private static readonly _uint8ToInt8 = new Int8Array(BitUtils._uint8.buffer); + + private static readonly _int8 = new Int8Array(1); + private static readonly _int8ToUint8 = new Uint8Array(BitUtils._int8.buffer); + + private static readonly _uint16 = new Uint16Array(1); + private static readonly _uint16ToInt16 = new Int16Array( + BitUtils._uint16.buffer + ); + + private static readonly _int16 = new Int16Array(1); + private static readonly _int16ToUint16 = new Uint16Array( + BitUtils._int16.buffer + ); + + private static readonly _uint32 = new Uint32Array(1); + private static readonly _uint32ToInt32 = new Int32Array( + BitUtils._uint32.buffer + ); + private static readonly _uint32ToFloat32 = new Float32Array( + BitUtils._uint32.buffer + ); + + private static readonly _int32 = new Int32Array(1); + private static readonly _int32ToUint32 = new Uint32Array( + BitUtils._int32.buffer + ); + + private static readonly _float32 = new Float32Array(1); + private static readonly _float32ToUint32 = new Uint32Array( + BitUtils._float32.buffer + ); + + private static readonly _uint64 = new BigUint64Array(1); + private static readonly _uint64ToFloat64 = new Float64Array( + BitUtils._uint64.buffer + ); + + private static readonly _reverseByteTable = [ + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, + 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, + 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, + 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, + 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, + 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, + 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, + 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, + 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, + 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, + 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, + 0x3f, 0xbf, 0x7f, 0xff, + ]; + + /** + * Count the consecutive zero bits (trailing) on the right in parallel + * https://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightParallel + */ + public static countTrailingZeroBits(v: number): number { + let c = 32; + const _v = v & -v; + if (_v !== 0) c--; + if ((_v & 0x0000ffff) !== 0) c -= 16; + if ((_v & 0x00ff00ff) !== 0) c -= 8; + if ((_v & 0x0f0f0f0f) !== 0) c -= 4; + if ((_v & 0x33333333) !== 0) c -= 2; + if ((_v & 0x55555555) !== 0) c -= 1; + return c; + } + + public static reverseByte(x: number): number { + return this._reverseByteTable[x]; + } + + public static signed(bits: number, value: number) { + return value & (1 << (bits - 1)) ? value - (1 << bits) : value; + } + + public static shiftR(v: number, n: number): number { + return BitUtils.signed(32, v >> n); + } + + public static shiftL(v: number, n: number): number { + return BitUtils.signed(32, v << n); + } + + /** + * Binary conversion of a uint8 to an int8. This is equivalent in C to + * typecasting an unsigned char to a char. + */ + public static uint8ToInt8(d: number): number { + this._uint8[0] = d; + return this._uint8ToInt8[0]; + } + + /** + * Binary conversion of an int8 to a uint8. + */ + public static int8ToUint8(d: number): number { + this._int8[0] = d; + return this._int8ToUint8[0]; + } + + /** + * Binary conversion of a uint16 to an int16. This is equivalent in C to + * typecasting an unsigned short to a short. + */ + public static uint16ToInt16(d: number): number { + this._uint16[0] = d; + return this._uint16ToInt16[0]; + } + + /** + * Binary conversion of an int16 to a uint16. This is equivalent in C to + * typecasting a short to an unsigned short. + */ + public static int16ToUint16(d: number): number { + this._int16[0] = d; + return this._int16ToUint16[0]; + } + + /** + * Binary conversion of a uint32 to an int32. This is equivalent in C to + * typecasting an unsigned int to signed int. + */ + public static uint32ToInt32(d: number): number { + this._uint32[0] = d; + return this._uint32ToInt32[0]; + } + + /** + * Binary conversion of a uint32 to an float32. This is equivalent in C to + * typecasting an unsigned int to float. + */ + public static uint32ToFloat32(d: number): number { + this._uint32[0] = d; + return this._uint32ToFloat32[0]; + } + + /** + * Binary conversion of a uint64 to an float64. This is equivalent in C to + * typecasting an unsigned long long to double. + */ + public static uint64ToFloat64(d: bigint): number { + this._uint64[0] = d; + return this._uint64ToFloat64[0]; + } + + /** + * Binary conversion of an int32 to a uint32. This is equivalent in C to + * typecasting an int to an unsigned int. + */ + public static int32ToUint32(d: number): number { + this._int32[0] = d; + return this._int32ToUint32[0]; + } + + /** + * Binary conversion of a float32 to an uint32. This is equivalent in C to + * typecasting a float to unsigned int. + */ + public static float32ToUint32(d: number): number { + this._float32[0] = d; + return this._float32ToUint32[0]; + } + + public static debugBits32(value?: number): string { + if (value === undefined) { + return 'undefined'; + } + const bitCount = 32; + let result = ''; + for (let i = bitCount; i > -1; i--) { + result += (value & (1 << i)) === 0 ? '0' : '1'; + } + return result; + } +} diff --git a/src/common/color-channel.ts b/src/common/color-channel.ts deleted file mode 100644 index be37bc2..0000000 --- a/src/common/color-channel.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** @format */ - -export enum ColorChannel { - /** - * Red channel of a color. - */ - red, - - /** - * Green channel of a color. - */ - green, - - /** - * Blue channel of a color. - */ - blue, - - /** - * Alpha channel of a color. - */ - alpha, - - /** - * Luminance (brightness) of a color. - */ - luminance, -} diff --git a/src/common/color-model.ts b/src/common/color-model.ts deleted file mode 100644 index b4548cc..0000000 --- a/src/common/color-model.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** @format */ - -export enum ColorModel { - argb, - abgr, - rgba, - bgra, - rgb, - bgr, - luminance, -} diff --git a/src/common/color.ts b/src/common/color.ts deleted file mode 100644 index 19fd575..0000000 --- a/src/common/color.ts +++ /dev/null @@ -1,702 +0,0 @@ -/** @format */ - -import { ImageError } from '../error/image-error'; -import { BitOperators } from './bit-operators'; -import { ColorChannel } from './color-channel'; -import { MathOperators } from './math-operators'; - -/** - * Image pixel colors are instantiated as an int object rather than an instance - * of the Color class in order to reduce object allocations. - */ -export abstract class Color { - /** - * Create a color value from RGB values in the range [**0**, **255**]. - * - * The channel order of a uint32 encoded color is BGRA. - */ - public static fromRgb(red: number, green: number, blue: number): number { - return Color.getColor(red, green, blue); - } - - /** - * Create a color value from RGBA values in the range [**0**, **255**]. - * - * The channel order of a uint32 encoded color is BGRA. - */ - public static fromRgba( - red: number, - green: number, - blue: number, - alpha: number - ): number { - return Color.getColor(red, green, blue, alpha); - } - - /** - * Create a color value from HSL values in the range [**0**, **1**]. - */ - public static fromHsl( - hue: number, - saturation: number, - lightness: number - ): number { - const rgb = Color.hslToRgb(hue, saturation, lightness); - return Color.getColor(rgb[0], rgb[1], rgb[2]); - } - - /** - * Create a color value from HSV values in the range [**0**, **1**]. - */ - public static fromHsv( - hue: number, - saturation: number, - value: number - ): number { - const rgb = Color.hsvToRgb(hue, saturation, value); - return Color.getColor(rgb[0], rgb[1], rgb[2]); - } - - /** - * Create a color value from XYZ values. - */ - public static fromXyz(x: number, y: number, z: number): number { - const rgb = Color.xyzToRgb(x, y, z); - return Color.getColor(rgb[0], rgb[1], rgb[2]); - } - - /** - * Create a color value from CIE-L*a*b values. - */ - public static fromLab(L: number, a: number, b: number): number { - const rgb = Color.labToRgb(L, a, b); - return Color.getColor(rgb[0], rgb[1], rgb[2]); - } - - /** - * Compare colors from a 3 or 4 dimensional color space - */ - public static distance( - c1: number[], - c2: number[], - compareAlpha: boolean - ): number { - const d1 = c1[0] - c2[0]; - const d2 = c1[1] - c2[1]; - const d3 = c1[2] - c2[2]; - if (compareAlpha) { - const dA = c1[3] - c2[3]; - return Math.sqrt( - Math.max(d1 * d1, (d1 - dA) * (d1 - dA)) + - Math.max(d2 * d2, (d2 - dA) * (d2 - dA)) + - Math.max(d3 * d3, (d3 - dA) * (d3 - dA)) - ); - } else { - return Math.sqrt(d1 * d1 + d2 * d2 + d3 * d3); - } - } - - /** - * Returns a new color of **src** alpha-blended onto **dst**. The opacity of **src** - * is additionally scaled by **fraction** / **255**. - */ - public static alphaBlendColors( - dst: number, - src: number, - fraction = 0xff - ): number { - const srcAlpha = Color.getAlpha(src); - if (srcAlpha === 255 && fraction === 0xff) { - // src is fully opaque, nothing to blend - return src; - } - if (srcAlpha === 0 && fraction === 0xff) { - // src is fully transparent, nothing to blend - return dst; - } - - let a = srcAlpha / 255.0; - if (fraction !== 0xff) { - a *= fraction / 255.0; - } - - const sr = Math.round(Color.getRed(src) * a); - const sg = Math.round(Color.getGreen(src) * a); - const sb = Math.round(Color.getBlue(src) * a); - const sa = Math.round(srcAlpha * a); - - const dr = Math.round(Color.getRed(dst) * (1.0 - a)); - const dg = Math.round(Color.getGreen(dst) * (1.0 - a)); - const db = Math.round(Color.getBlue(dst) * (1.0 - a)); - const da = Math.round(Color.getAlpha(dst) * (1.0 - a)); - - return Color.getColor(sr + dr, sg + dg, sb + db, sa + da); - } - - /** - * Get the **channel** from the **color**. - */ - public static getChannel(color: number, channel: ColorChannel): number { - if (channel === ColorChannel.red) { - return Color.getRed(color); - } else if (channel === ColorChannel.green) { - return Color.getGreen(color); - } else if (channel === ColorChannel.blue) { - return Color.getBlue(color); - } else if (channel === ColorChannel.alpha) { - return Color.getAlpha(color); - } - return Color.getLuminance(color); - } - - /** - * Get the alpha channel from the **color**. - */ - public static getAlpha(color: number): number { - return (color >> 24) & 0xff; - } - - /** - * Get the blue channel from the **color**. - */ - public static getBlue(color: number): number { - return (color >> 16) & 0xff; - } - - /** - * Get the color with the given **r**, **g**, **b**, and **a** components. - * The channel order of a uint32 encoded color is RGBA. - */ - public static getColor(r: number, g: number, b: number, a = 255): number { - // What we're doing here, is creating a 32 bit - // integer by collecting the rgba in one integer. - // we know for certain and we're also assuring that - // all our letiables' values are 255 at maximum, - // which means that they can never be bigger than - // 8 bits so we can safely slide each one by 8 bits - // for adding the other. - const color = - (MathOperators.clampInt255(a) << 24) | - (MathOperators.clampInt255(b) << 16) | - (MathOperators.clampInt255(g) << 8) | - MathOperators.clampInt255(r); - return BitOperators.toUint32(color); - } - - /** - * Get the green channel from the **color**. - */ - public static getGreen(color: number): number { - return (color >> 8) & 0xff; - } - - /** - * Returns the luminance (grayscale) value of the **color**. - */ - public static getLuminance(color: number): number { - const r = Color.getRed(color); - const g = Color.getGreen(color); - const b = Color.getBlue(color); - return Color.getLuminanceRgb(r, g, b); - } - - /** - * Returns the luminance (grayscale) value of the color. - */ - public static getLuminanceRgb(r: number, g: number, b: number): number { - return Math.round(0.299 * r + 0.587 * g + 0.114 * b); - } - - /** - * Get the red channel from the **color**. - */ - public static getRed(color: number): number { - return color & 0xff; - } - - /** - * Check if **color** is white - */ - public static isBlack(color: number): boolean { - return (color & 0xffffff) === 0x0; - } - - /** - * Check if **color** is white - */ - public static isWhite(color: number): boolean { - return (color & 0xffffff) === 0xffffff; - } - - /** - * Returns a new color where the alpha channel of **color** has been replaced by **value**. - */ - public static setAlpha(color: number, value: number): number { - return (color & 0x00ffffff) | (MathOperators.clampInt255(value) << 24); - } - - /** - * Returns a new color where the blue channel of **color** has been replaced by **value**. - */ - public static setBlue(color: number, value: number): number { - return (color & 0xff00ffff) | (MathOperators.clampInt255(value) << 16); - } - - /** - * Returns a new color, where the given **color**'s **channel** has been - * replaced with the given **value**. - */ - public static setChannel( - color: number, - channel: ColorChannel, - value: number - ): number { - if (channel === ColorChannel.red) { - return Color.setRed(color, value); - } else if (channel === ColorChannel.green) { - return Color.setGreen(color, value); - } else if (channel === ColorChannel.blue) { - return Color.setBlue(color, value); - } else if (channel === ColorChannel.alpha) { - return Color.setAlpha(color, value); - } - return color; - } - - /** - * Returns a new color where the green channel of **color** has been replaced - * by **value**. - */ - public static setGreen(color: number, value: number): number { - return (color & 0xffff00ff) | (MathOperators.clampInt255(value) << 8); - } - - /** - * Returns a new color where the red channel of **color** has been replaced - * by **value**. - */ - public static setRed(color: number, value: number): number { - return (color & 0xffffff00) | MathOperators.clampInt255(value); - } - - /** - * Convert an HSL color to RGB, where h is specified in normalized degrees - * [**0**, **1**] (where 1 is 360-degrees); s and l are in the range [**0**, **1**]. - * Returns a list [**r**, **g**, **b**] with values in the range [**0**, **255**]. - */ - public static hslToRgb( - hue: number, - saturation: number, - lightness: number - ): number[] { - if (saturation === 0) { - const gray = Math.trunc(lightness * 255.0); - return [gray, gray, gray]; - } - - const hue2rgb = (p: number, q: number, t: number) => { - let ti = t; - if (ti < 0.0) { - ti += 1.0; - } - if (ti > 1) { - ti -= 1.0; - } - if (ti < 1.0 / 6.0) { - return p + (q - p) * 6.0 * ti; - } - if (ti < 1.0 / 2.0) { - return q; - } - if (ti < 2.0 / 3.0) { - return p + (q - p) * (2.0 / 3.0 - ti) * 6.0; - } - return p; - }; - - const q = - lightness < 0.5 - ? lightness * (1.0 + saturation) - : lightness + saturation - lightness * saturation; - const p = 2.0 * lightness - q; - - const r = hue2rgb(p, q, hue + 1.0 / 3.0); - const g = hue2rgb(p, q, hue); - const b = hue2rgb(p, q, hue - 1.0 / 3.0); - - return [ - Math.round(r * 255.0), - Math.round(g * 255.0), - Math.round(b * 255.0), - ]; - } - - /** - * Convert an HSV color to RGB, where h is specified in normalized degrees - * [**0**, **1**] (where 1 is 360-degrees); s and l are in the range [**0**, **1**]. - * Returns a list [**r**, **g**, **b**] with values in the range [**0**, **255**]. - */ - public static hsvToRgb( - hue: number, - saturation: number, - brightness: number - ): number[] { - if (saturation === 0) { - const gray = Math.round(brightness * 255.0); - return [gray, gray, gray]; - } - - const h = (hue - Math.floor(hue)) * 6.0; - const f = h - Math.floor(h); - const p = brightness * (1.0 - saturation); - const q = brightness * (1.0 - saturation * f); - const t = brightness * (1.0 - saturation * (1.0 - f)); - - switch (Math.trunc(h)) { - case 0: - return [ - Math.round(brightness * 255.0), - Math.round(t * 255.0), - Math.round(p * 255.0), - ]; - case 1: - return [ - Math.round(q * 255.0), - Math.round(brightness * 255.0), - Math.round(p * 255.0), - ]; - case 2: - return [ - Math.round(p * 255.0), - Math.round(brightness * 255.0), - Math.round(t * 255.0), - ]; - case 3: - return [ - Math.round(p * 255.0), - Math.round(q * 255.0), - Math.round(brightness * 255.0), - ]; - case 4: - return [ - Math.round(t * 255.0), - Math.round(p * 255.0), - Math.round(brightness * 255.0), - ]; - case 5: - return [ - Math.round(brightness * 255.0), - Math.round(p * 255.0), - Math.round(q * 255.0), - ]; - default: - throw new ImageError('Invalid hue'); - } - } - - /** - * Convert an RGB color to HSL, where **r**, **g** and **b** are in the range [**0**, **255**]. - * Returns a list [**h**, **s**, **l**] with values in the range [**0**, **1**]. - */ - public static rgbToHsl(r: number, g: number, b: number): number[] { - const ri = r / 255.0; - const gi = g / 255.0; - const bi = b / 255.0; - const mx = Math.max(ri, Math.max(gi, bi)); - const mn = Math.min(ri, Math.min(gi, bi)); - - const l = (mx + mn) / 2.0; - - if (mx === mn) { - return [0.0, 0.0, l]; - } - - const d = mx - mn; - const s = l > 0.5 ? d / (2.0 - mx - mn) : d / (mx + mn); - - let h = 0; - if (mx === ri) { - h = (gi - bi) / d + (gi < bi ? 6.0 : 0.0); - } else if (mx === gi) { - h = (bi - ri) / d + 2.0; - } else { - h = (ri - gi) / d + 4.0; - } - - h /= 6.0; - - return [h, s, l]; - } - - /** - * Convert a CIE-L*a*b color to XYZ. - */ - public static labToXyz(l: number, a: number, b: number): number[] { - let y = (l + 16) / 116; - let x = y + a / 500; - let z = y - b / 200; - if (Math.pow(x, 3) > 0.008856) { - x = Math.pow(x, 3); - } else { - x = (x - 16 / 116) / 7.787; - } - if (Math.pow(y, 3) > 0.008856) { - y = Math.pow(y, 3); - } else { - y = (y - 16 / 116) / 7.787; - } - if (Math.pow(z, 3) > 0.008856) { - z = Math.pow(z, 3); - } else { - z = (z - 16 / 116) / 7.787; - } - - return [ - Math.trunc(x * 95.047), - Math.trunc(y * 100.0), - Math.trunc(z * 108.883), - ]; - } - - /** - * Convert an XYZ color to RGB. - */ - public static xyzToRgb(x: number, y: number, z: number): number[] { - const xi = x / 100; - const yi = y / 100; - const zi = z / 100; - let r = 3.2406 * xi + -1.5372 * yi + -0.4986 * zi; - let g = -0.9689 * xi + 1.8758 * yi + 0.0415 * zi; - let b = 0.0557 * xi + -0.204 * yi + 1.057 * zi; - if (r > 0.0031308) { - r = 1.055 * Math.pow(r, 0.4166666667) - 0.055; - } else { - r *= 12.92; - } - if (g > 0.0031308) { - g = 1.055 * Math.pow(g, 0.4166666667) - 0.055; - } else { - g *= 12.92; - } - if (b > 0.0031308) { - b = 1.055 * Math.pow(b, 0.4166666667) - 0.055; - } else { - b *= 12.92; - } - - return [ - Math.trunc(MathOperators.clamp(r * 255, 0, 255)), - Math.trunc(MathOperators.clamp(g * 255, 0, 255)), - Math.trunc(MathOperators.clamp(b * 255, 0, 255)), - ]; - } - - /** - * Convert a CMYK color to RGB, where **c**, **m**, **y**, **k** values are in the range - * [**0**, **255**]. Returns a list [**r**, **g**, **b**] with values in the range [**0**, **255**]. - */ - public static cmykToRgb( - c: number, - m: number, - y: number, - k: number - ): number[] { - const ci = c / 255.0; - const mi = m / 255.0; - const yi = y / 255.0; - const ki = k / 255.0; - return [ - Math.round(255.0 * (1.0 - ci) * (1.0 - ki)), - Math.round(255.0 * (1.0 - mi) * (1.0 - ki)), - Math.round(255.0 * (1.0 - yi) * (1.0 - ki)), - ]; - } - - /** - * Convert a CIE-L*a*b color to RGB. - */ - public static labToRgb(l: number, a: number, b: number): number[] { - const refX = 95.047; - const refY = 100.0; - const refZ = 108.883; - - let y = (l + 16) / 116; - let x = a / 500 + y; - let z = y - b / 200; - - const y3 = Math.pow(y, 3); - if (y3 > 0.008856) { - y = y3; - } else { - y = (y - 16 / 116) / 7.787; - } - - const x3 = Math.pow(x, 3); - if (x3 > 0.008856) { - x = x3; - } else { - x = (x - 16 / 116) / 7.787; - } - - const z3 = Math.pow(z, 3); - if (z3 > 0.008856) { - z = z3; - } else { - z = (z - 16 / 116) / 7.787; - } - - x *= refX; - y *= refY; - z *= refZ; - - x /= 100; - y /= 100; - z /= 100; - - // Xyz to rgb - let R = x * 3.2406 + y * -1.5372 + z * -0.4986; - let G = x * -0.9689 + y * 1.8758 + z * 0.0415; - let B = x * 0.0557 + y * -0.204 + z * 1.057; - - if (R > 0.0031308) { - R = 1.055 * Math.pow(R, 1.0 / 2.4) - 0.055; - } else { - R *= 12.92; - } - - if (G > 0.0031308) { - G = 1.055 * Math.pow(G, 1.0 / 2.4) - 0.055; - } else { - G *= 12.92; - } - - if (B > 0.0031308) { - B = 1.055 * Math.pow(B, 1.0 / 2.4) - 0.055; - } else { - B *= 12.92; - } - - return [ - Math.trunc(MathOperators.clamp(R * 255.0, 0, 255)), - Math.trunc(MathOperators.clamp(G * 255.0, 0, 255)), - Math.trunc(MathOperators.clamp(B * 255.0, 0, 255)), - ]; - } - - /** - * Convert a RGB color to XYZ. - */ - public static rgbToXyz(r: number, g: number, b: number): number[] { - let ri = r / 255; - let gi = g / 255; - let bi = b / 255; - - if (ri > 0.04045) { - ri = Math.pow((ri + 0.055) / 1.055, 2.4); - } else { - ri /= 12.92; - } - if (gi > 0.04045) { - gi = Math.pow((gi + 0.055) / 1.055, 2.4); - } else { - gi /= 12.92; - } - if (bi > 0.04045) { - bi = Math.pow((bi + 0.055) / 1.055, 2.4); - } else { - bi /= 12.92; - } - - ri *= 100.0; - gi *= 100.0; - bi *= 100.0; - - return [ - ri * 0.4124 + gi * 0.3576 + bi * 0.1805, - ri * 0.2126 + gi * 0.7152 + bi * 0.0722, - ri * 0.0193 + gi * 0.1192 + bi * 0.9505, - ]; - } - - /** - * Convert a XYZ color to CIE-L*a*b. - */ - public static xyzToLab(x: number, y: number, z: number): number[] { - let xi = x / 95.047; - let yi = y / 100; - let zi = z / 108.883; - - if (xi > 0.008856) { - xi = Math.pow(xi, 1 / 3); - } else { - xi = 7.787 * xi + 16 / 116; - } - if (yi > 0.008856) { - yi = Math.pow(yi, 1 / 3); - } else { - yi = 7.787 * yi + 16 / 116; - } - if (zi > 0.008856) { - zi = Math.pow(zi, 1 / 3); - } else { - zi = 7.787 * zi + 16 / 116; - } - - return [116 * yi - 16, 500 * (xi - yi), 200 * (yi - zi)]; - } - - /** - * Convert a RGB color to CIE-L*a*b. - */ - public static rgbToLab(r: number, g: number, b: number): number[] { - let ri = r / 255; - let gi = g / 255; - let bi = b / 255; - - if (ri > 0.04045) { - ri = Math.pow((ri + 0.055) / 1.055, 2.4); - } else { - ri /= 12.92; - } - if (gi > 0.04045) { - gi = Math.pow((gi + 0.055) / 1.055, 2.4); - } else { - gi /= 12.92; - } - if (bi > 0.04045) { - bi = Math.pow((bi + 0.055) / 1.055, 2.4); - } else { - bi /= 12.92; - } - - ri *= 100; - gi *= 100; - bi *= 100; - - let x = ri * 0.4124 + gi * 0.3576 + bi * 0.1805; - let y = ri * 0.2126 + gi * 0.7152 + bi * 0.0722; - let z = ri * 0.0193 + gi * 0.1192 + bi * 0.9505; - - x /= 95.047; - y /= 100.0; - z /= 108.883; - - if (x > 0.008856) { - x = Math.pow(x, 1 / 3.0); - } else { - x = 7.787 * x + 16 / 116; - } - if (y > 0.008856) { - y = Math.pow(y, 1 / 3); - } else { - y = 7.787 * y + 16 / 116; - } - if (z > 0.008856) { - z = Math.pow(z, 1 / 3); - } else { - z = 7.787 * z + 16 / 116; - } - - return [116 * y - 16, 500 * (x - y), 200 * (y - z)]; - } -} diff --git a/src/common/crc32.ts b/src/common/crc32.ts index 7ed3555..2512490 100644 --- a/src/common/crc32.ts +++ b/src/common/crc32.ts @@ -1,6 +1,6 @@ /** @format */ -export interface Crc32Parameters { +export interface Crc32Options { buffer: Uint8Array; baseCrc?: number; position?: number; @@ -8,7 +8,7 @@ export interface Crc32Parameters { } export abstract class Crc32 { - private static readonly crcTable = new Uint32Array(Crc32.makeTable()); + private static readonly _crcTable = new Uint32Array(Crc32.makeTable()); private static makeTable() { const table: number[] = []; @@ -23,15 +23,15 @@ export abstract class Crc32 { return table; } - public static getChecksum(options: Crc32Parameters) { - const t = Crc32.crcTable; - const len = options.length ?? options.buffer.length; - const pos = options.position ?? 0; + public static getChecksum(opt: Crc32Options) { + const t = Crc32._crcTable; + const len = opt.length ?? opt.buffer.length; + const pos = opt.position ?? 0; const end = pos + len; - let result = (options.baseCrc ?? 0) ^ -1; + let result = (opt.baseCrc ?? 0) ^ -1; for (let i = pos; i < end; i++) { - result = (result >>> 8) ^ t[(result ^ options.buffer[i]) & 0xff]; + result = (result >>> 8) ^ t[(result ^ opt.buffer[i]) & 0xff]; } return (result ^ -1) >>> 0; diff --git a/src/common/dispose-mode.ts b/src/common/dispose-mode.ts deleted file mode 100644 index 4e4809d..0000000 --- a/src/common/dispose-mode.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** @format */ - -export enum DisposeMode { - /** - * When drawing a frame, the canvas should be left as it is. - */ - none, - - /** - * When drawing a frame, the canvas should be cleared first. - */ - clear, - - /** - * When drawing this frame, the canvas should be reverted to how it was before drawing it. - */ - previous, -} diff --git a/src/common/dither-kernel.ts b/src/common/dither-kernel.ts deleted file mode 100644 index 73c8605..0000000 --- a/src/common/dither-kernel.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** @format */ - -export enum DitherKernel { - None, - FalseFloydSteinberg, - FloydSteinberg, - Stucki, - Atkinson, -} diff --git a/src/common/dither-pixel.ts b/src/common/dither-pixel.ts deleted file mode 100644 index b4d02a5..0000000 --- a/src/common/dither-pixel.ts +++ /dev/null @@ -1,135 +0,0 @@ -/** @format */ - -import { DitherKernel } from './dither-kernel'; -import { MemoryImage } from './memory-image'; -import { NeuralQuantizer } from './neural-quantizer'; - -export abstract class DitherPixel { - private static ditherKernels = [ - [ - [0, 0, 0], - [0, 0, 0], - [0, 0, 0], - ], - // FalseFloydSteinberg - [ - [3 / 8, 1, 0], - [3 / 8, 0, 1], - [2 / 8, 1, 1], - ], - // FloydSteinberg - [ - [7 / 16, 1, 0], - [3 / 16, -1, 1], - [5 / 16, 0, 1], - [1 / 16, 1, 1], - ], - // Stucki - [ - [8 / 42, 1, 0], - [4 / 42, 2, 0], - [2 / 42, -2, 1], - [4 / 42, -1, 1], - [8 / 42, 0, 1], - [4 / 42, 1, 1], - [2 / 42, 2, 1], - [1 / 42, -2, 2], - [2 / 42, -1, 2], - [4 / 42, 0, 2], - [2 / 42, 1, 2], - [1 / 42, 2, 2], - ], - //Atkinson: - [ - [1 / 8, 1, 0], - [1 / 8, 2, 0], - [1 / 8, -1, 1], - [1 / 8, 0, 1], - [1 / 8, 1, 1], - [1 / 8, 0, 2], - ], - ]; - - public static getDitherPixels( - image: MemoryImage, - quantizer: NeuralQuantizer, - kernel: DitherKernel, - serpentine: boolean - ): Uint8Array { - if (kernel === DitherKernel.None) { - return quantizer.getIndexMap(image); - } - - const ds = DitherPixel.ditherKernels[kernel]; - const height = image.height; - const width = image.width; - const data = new Uint8Array(image.getBytes()); - - const indexedPixels = new Uint8Array(width * height); - const colorMap = quantizer.colorMap8; - - let direction = serpentine ? -1 : 1; - let index = 0; - for (let y = 0; y < height; y++) { - if (serpentine) { - direction *= -1; - } - - const x0 = direction === 1 ? 0 : width - 1; - const x1 = direction === 1 ? width : 0; - for (let x = x0; x !== x1; x += direction, ++index) { - // Get original color - let idx = index * 4; - const r1 = data[idx]; - const g1 = data[idx + 1]; - const b1 = data[idx + 2]; - - // Get converted color - idx = quantizer.lookupRGB(r1, g1, b1); - - indexedPixels[index] = idx; - idx *= 3; - const r2 = colorMap[idx]; - const g2 = colorMap[idx + 1]; - const b2 = colorMap[idx + 2]; - - const er = r1 - r2; - const eg = g1 - g2; - const eb = b1 - b2; - - if (er !== 0 || eg !== 0 || eb !== 0) { - const i0 = direction === 1 ? 0 : ds.length - 1; - const i1 = direction === 1 ? ds.length : 0; - for (let i = i0; i !== i1; i += direction) { - const x1 = Math.trunc(ds[i][1]); - const y1 = Math.trunc(ds[i][2]); - if ( - x1 + x >= 0 && - x1 + x < width && - y1 + y >= 0 && - y1 + y < height - ) { - const d = ds[i][0]; - idx = index + x1 + y1 * width; - idx *= 4; - data[idx] = Math.max( - 0, - Math.min(255, Math.trunc(data[idx] + er * d)) - ); - data[idx + 1] = Math.max( - 0, - Math.min(255, Math.trunc(data[idx + 1] + eg * d)) - ); - data[idx + 2] = Math.max( - 0, - Math.min(255, Math.trunc(data[idx + 2] + eb * d)) - ); - } - } - } - } - } - - return indexedPixels; - } -} diff --git a/src/hdr/half.ts b/src/common/float16.ts similarity index 69% rename from src/hdr/half.ts rename to src/common/float16.ts index 1ddc6f4..22a2449 100644 --- a/src/hdr/half.ts +++ b/src/common/float16.ts @@ -1,50 +1,30 @@ /** @format */ -import { BitOperators } from '../common/bit-operators'; +import { BitUtils } from './bit-utils'; /** * A 16-bit floating-point number, used by high-dynamic-range image formats * as a more efficient storage for floating-point values that don't require - * full 32-bit precision. A list of Half floats can be stored in a **Uint16Array**, - * and converted to a double using the **halfToDouble()** static method. + * full 32-bit precision. A list of Half floats can be stored in a + * Uint16Array, and converted to a double using the **float16ToDouble** static + * method. * * This class is derived from the OpenEXR library. */ -export class Half { - private static toFloatUint32: Uint32Array; - private static toFloatFloat32: Float32Array; - private static eLut: Uint16Array; - - static { - Half.toFloatUint32 = new Uint32Array(1 << 16); - Half.toFloatFloat32 = new Float32Array(Half.toFloatUint32.buffer); - Half.eLut = new Uint16Array(1 << 9); - - // Init eLut - for (let i = 0; i < 0x100; i++) { - const e = (i & 0x0ff) - (127 - 15); - if (e <= 0 || e >= 30) { - // Special case - Half.eLut[i] = 0; - Half.eLut[i | 0x100] = 0; - } else { - // Common case - normalized half, no exponent overflow possible - Half.eLut[i] = e << 10; - Half.eLut[i | 0x100] = (e << 10) | 0x8000; - } - } - - // Init toFloat - const iMax = 1 << 16; - for (let i = 0; i < iMax; i++) { - Half.toFloatUint32[i] = Half.halfToFloat(i); - } +export class Float16 { + private static _toFloatFloat32Data?: Float32Array; + private static _eLut: Uint16Array; + + private static get _toFloatFloat32(): Float32Array { + return this._toFloatFloat32Data !== undefined + ? this._toFloatFloat32Data + : this.initialize(); } - private bits: number; + public bits: number; - constructor(bits: number) { - this.bits = bits; + constructor(f?: number) { + this.bits = f !== undefined ? Float16.doubleToFloat16(f) : 0; } private static convert(i: number): number { @@ -120,17 +100,17 @@ export class Half { m = m + 0x00000fff + ((m >> 13) & 1); if ((m & 0x00800000) !== 0) { - // Overflow in significand, + // overflow in significand m = 0; - // Adjust exponent + // adjust exponent e += 1; } // Handle exponent overflow if (e > 30) { - // If this returns, the half becomes an - // infinity with the same sign as f. + // if this returns, the half becomes an + // infinity with the same sign as f return s | 0x7c00; } @@ -139,6 +119,39 @@ export class Half { } } + private static initialize(): Float32Array { + if (this._toFloatFloat32Data !== undefined) { + return this._toFloatFloat32Data; + } + + const floatUint32Data = new Uint32Array(1 << 16); + this._toFloatFloat32Data = new Float32Array(floatUint32Data.buffer); + this._eLut = new Uint16Array(1 << 9); + + // Init eLut + for (let i = 0; i < 0x100; i++) { + const e = (i & 0x0ff) - (127 - 15); + + if (e <= 0 || e >= 30) { + // Special case + this._eLut[i] = 0; + this._eLut[i | 0x100] = 0; + } else { + // Common case - normalized half, no exponent overflow possible + this._eLut[i] = e << 10; + this._eLut[i | 0x100] = (e << 10) | 0x8000; + } + } + + // Init toFloat + const iMax = 1 << 16; + for (let i = 0; i < iMax; i++) { + floatUint32Data[i] = this.halfToFloat(i); + } + + return this._toFloatFloat32Data; + } + private static halfToFloat(y: number): number { const s = (y >> 15) & 0x00000001; let e = (y >> 10) & 0x0000001f; @@ -176,21 +189,33 @@ export class Half { return (s << 31) | (e << 23) | m; } - private static fromBits(bits: number) { - return new Half(bits); + public static from(other: Float16): Float16 { + const float16 = new Float16(); + float16.bits = other.bits; + return float16; } - public static halfToDouble(bits: number): number { - return this.toFloatFloat32[bits]; + public static fromBits(bits: number): Float16 { + const float16 = new Float16(); + float16.bits = bits; + return float16; } - public static doubleToHalf(n: number): number { + public static float16ToDouble(bits: number): number { + return this._toFloatFloat32[bits]; + } + + public static doubleToFloat16(n: number): number { const f = n; - const xi = BitOperators.toUint32(f); - if (f === 0.0) { + const xI = BitUtils.float32ToUint32(f); + if (f === 0) { // Common special case - zero. // Preserve the zero's sign bit. - return xi >> 16; + return xI >> 16; + } + + if (this._toFloatFloat32Data === undefined) { + this.initialize(); } // We extract the combined sign and exponent, e, from our @@ -206,114 +231,94 @@ export class Half { // resulting from underflow, infinities and NANs), the table // lookup returns zero, and we call a longer, non-inline function // to do the float-to-half conversion. - let e = (xi >> 23) & 0x000001ff; + let e = (xI >> 23) & 0x000001ff; - e = this.eLut[e]; + e = this._eLut[e]; if (e !== 0) { // Simple case - round the significand, m, to 10 // bits and combine it with the sign and exponent. - const m = xi & 0x007fffff; + const m = xI & 0x007fffff; return e + ((m + 0x00000fff + ((m >> 13) & 1)) >> 13); } // Difficult case - call a function. - return this.convert(xi); + return this.convert(xI); } /** - * Returns +infinity. + * Returns +Infinity. */ - public static positiveInfinity(): Half { - return Half.fromBits(0x7c00); + public static posInf(): Float16 { + return Float16.fromBits(0x7c00); } /** - * Returns -infinity. + * Returns -Infinity. */ - public static negativeInfinity(): Half { - return Half.fromBits(0xfc00); + public static negInf(): Float16 { + return Float16.fromBits(0xfc00); } /** - * Returns a NAN with the bit pattern 0111111111111111. + * Returns a NaN with the bit pattern 0111111111111111. */ - public static qNan(): Half { - return Half.fromBits(0x7fff); + public static qNan(): Float16 { + return Float16.fromBits(0x7fff); } /** - * Returns a NAN with the bit pattern 0111110111111111. + * Returns a NaN with the bit pattern 0111110111111111. */ - public static sNan(): Half { - return Half.fromBits(0x7dff); + public static sNan(): Float16 { + return Float16.fromBits(0x7dff); } public toDouble(): number { - return Half.toFloatFloat32[this.bits]; + return Float16._toFloatFloat32[this.bits]; } /** * Unary minus */ - public unaryMinus(): Half { - return Half.fromBits(this.bits ^ 0x8000); + public minus(): Float16 { + return Float16.fromBits(this.bits ^ 0x8000); } /** * Addition operator for Half or num left operands. */ - public add(other: Half | number): Half { - let d = 0; - if (other instanceof Half) { - d = other.toDouble(); - } else if (typeof other === 'number') { - d = other; - } - const bits = Half.doubleToHalf(this.toDouble() + d); - return new Half(bits); + public add(f: Float16 | number): Float16 { + const d = + f instanceof Float16 ? f.toDouble() : typeof f === 'number' ? f : 0; + return new Float16(this.toDouble() + d); } /** * Subtraction operator for Half or num left operands. */ - public subtract(other: Half | number): Half { - let d = 0; - if (other instanceof Half) { - d = other.toDouble(); - } else if (typeof other === 'number') { - d = other; - } - const bits = Half.doubleToHalf(this.toDouble() - d); - return new Half(bits); + public sub(f: Float16 | number): Float16 { + const d = + f instanceof Float16 ? f.toDouble() : typeof f === 'number' ? f : 0; + return new Float16(this.toDouble() - d); } /** * Multiplication operator for Half or num left operands. */ - public multiply(other: Half | number): Half { - let d = 0; - if (other instanceof Half) { - d = other.toDouble(); - } else if (typeof other === 'number') { - d = other; - } - const bits = Half.doubleToHalf(this.toDouble() * d); - return new Half(bits); + public mul(f: Float16 | number): Float16 { + const d = + f instanceof Float16 ? f.toDouble() : typeof f === 'number' ? f : 0; + return new Float16(this.toDouble() * d); } /** * Division operator for Half or num left operands. */ - public divide(other: Half | number): Half { - let d = 0; - if (other instanceof Half) { - d = other.toDouble(); - } else if (typeof other === 'number') { - d = other; - } - const bits = Half.doubleToHalf(this.toDouble() / d); - return new Half(bits); + public div(f: Float16 | number): Float16 { + const d = + f instanceof Float16 ? f.toDouble() : typeof f === 'number' ? f : 0; + return new Float16(this.toDouble() / d); } /** @@ -321,9 +326,9 @@ export class Half { * After rounding, the significand's 10-n least significant * bits will be zero. */ - public round(n: number): Half { + public round(n: number): Float16 { if (n >= 10) { - return this; + return Float16.from(this); } // Disassemble h into the sign, s, @@ -342,7 +347,7 @@ export class Half { // Check for exponent overflow. if (e >= 0x7c00) { - // Overflow occurred -- truncate instead of rounding. + // Overflow occurred - truncate instead of rounding. e = this.bits; e >>= 10 - n; e <<= 10 - n; @@ -350,7 +355,7 @@ export class Half { // Put the original sign bit back. - return Half.fromBits(s | e); + return Float16.fromBits(s | e); } /** @@ -386,9 +391,9 @@ export class Half { } /** - * Returns true if h is a NAN. + * Returns true if h is a NaN. */ - public isNan(): boolean { + public isNaN(): boolean { const e = (this.bits >> 10) & 0x001f; const m = this.bits & 0x3ff; return e === 31 && m !== 0; @@ -409,12 +414,4 @@ export class Half { public isNegative(): boolean { return (this.bits & 0x8000) !== 0; } - - public getBits(): number { - return this.bits; - } - - public setBits(bits: number): void { - this.bits = bits; - } } diff --git a/src/common/frame-animation.ts b/src/common/frame-animation.ts deleted file mode 100644 index 608d847..0000000 --- a/src/common/frame-animation.ts +++ /dev/null @@ -1,165 +0,0 @@ -/** @format */ - -import { FrameType } from './frame-type'; -import { MemoryImage } from './memory-image'; - -export interface FrameAnimationInitOptions { - width?: number; - height?: number; - loopCount?: number; - frameType?: FrameType; -} - -/** - * Stores multiple images, most often as the frames of an animation. - * - * Some formats support multiple images that are not - * to be interpreted as animation, but rather multiple pages of a document. - * The **FrameAnimation** container is still used to store the images for these files. - * The **frameType** property is used to differentiate multi-page documents from - * multi-frame animations, where it is set to **FrameType.page** for documents - * and **FrameType.animation** for animated frames. - * - * All **Decoder** classes support decoding to an **FrameAnimation**, where the - * **FrameAnimation** will only contain a single frame for single image formats - * such as JPEG, or if the file doesn't contain any animation such as a single - * image GIF. If you want to generically support both animated and non-animated - * files, you can always decode to an animation and if the animation has only - * a single frame, then it's a non-animated image. - * - * In some cases, the frames of the animation may only provide a portion of the - * canvas, such as the case of animations encoding only the changing pixels - * from one frame to the next. The **width** and **height** and **backgroundColor** - * properties of the **FrameAnimation** provide information about the canvas that - * contains the animation, and the **MemoryImage** frames provide information about - * how to draw the particular frame, such as the area of the canvas to draw - * into, and if the canvas should be cleared prior to drawing the frame. - */ -export class FrameAnimation implements Iterable { - /** - * The canvas width for containing the animation. - */ - private _width = 0; - public get width(): number { - return this._width; - } - - /** - * The canvas height for containing the animation. - */ - private _height = 0; - public get height(): number { - return this._height; - } - - /** - * The suggested background color to clear the canvas with. - */ - private _backgroundColor = 0xffffffff; - public get backgroundColor(): number { - return this._backgroundColor; - } - - /** - * How many times should the animation loop(0 means forever)? - */ - private _loopCount = 0; - public get loopCount(): number { - return this._loopCount; - } - - /** - * How should the frames be interpreted? If **FrameType.animation**, the - * frames are part of an animated sequence. If **FrameType.page**, the frames - * are the pages of a document. - */ - private _frameType: FrameType = FrameType.animation; - public get frameType(): FrameType { - return this._frameType; - } - - /** - * The frames of the animation. - */ - private _frames: MemoryImage[] = []; - public get frames(): MemoryImage[] { - return this._frames; - } - - /** - * How many frames are in the animation? - */ - public get numFrames(): number { - return this.frames.length; - } - - /** - * The first frame of the animation. - */ - public get first(): MemoryImage { - return this.frames[0]; - } - - /** - * The last frame of the animation. - */ - public get last(): MemoryImage { - return this.frames[this.frames.length - 1]; - } - - /** - * Is the animation empty(no frames)? - */ - public get isEmpty(): boolean { - return this.frames.length === 0; - } - - /** - * Returns true if there is at least one frame in the animation. - */ - public get isNotEmpty(): boolean { - return this.frames.length > 0; - } - - constructor(options?: FrameAnimationInitOptions) { - this._width = options?.width ?? 0; - this._height = options?.height ?? 0; - this._loopCount = options?.loopCount ?? 0; - this._frameType = options?.frameType ?? FrameType.animation; - } - - /** - * Get the frame at the given **index**. - */ - public getFrame(index: number): MemoryImage { - return this.frames[index]; - } - - /** - * Add a frame to the animation. - */ - public addFrame(image: MemoryImage): void { - if (this._width < image.width) { - this._width = image.width; - } - if (this._height < image.height) { - this._height = image.height; - } - this.frames.push(image); - } - - /** - * Get the iterator for looping over the animation. - */ - public [Symbol.iterator](): Iterator { - let index = -1; - return { - next: () => { - return { - value: this._frames[++index], - done: !(index in this._frames), - }; - }, - }; - } -} diff --git a/src/common/frame-type.ts b/src/common/frame-type.ts deleted file mode 100644 index 1651af4..0000000 --- a/src/common/frame-type.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** @format */ - -export enum FrameType { - /** - * The frames of this document are to be interpreted as animation. - */ - animation, - - /** - * The frames of this document are to be interpreted as pages of a document. - */ - page, -} diff --git a/src/common/input-buffer.ts b/src/common/input-buffer.ts index f18a717..f5dffdc 100644 --- a/src/common/input-buffer.ts +++ b/src/common/input-buffer.ts @@ -1,8 +1,8 @@ /** @format */ -import { ImageError } from '../error/image-error'; -import { BitOperators } from './bit-operators'; -import { TextCodec } from './text-codec'; +import { LibError } from '../error/lib-error'; +import { BitUtils } from './bit-utils'; +import { StringUtils } from './string-utils'; export interface InputBufferInitOptions { buffer: Uint8Array; @@ -49,36 +49,34 @@ export class InputBuffer { /** * The current read position relative to the start of the buffer. */ - get position(): number { + public get position(): number { return this._offset - this._start; } /** * How many bytes are left in the stream. */ - get length(): number { + public get length(): number { return this._end - this._offset; } /** * Is the current position at the end of the stream? */ - get isEOS(): boolean { + public get isEOS(): boolean { return this._offset >= this._end; } /** * Create a InputStream for reading from an Array */ - constructor(options: InputBufferInitOptions) { - this._buffer = options.buffer; - this._bigEndian = options.bigEndian ?? false; - this._offset = options.offset ?? 0; + constructor(opt: InputBufferInitOptions) { + this._buffer = opt.buffer; + this._bigEndian = opt.bigEndian ?? false; + this._offset = opt.offset ?? 0; this._start = this._offset; this._end = - options.length !== undefined - ? this._start + options.length - : this._buffer.length; + opt.length !== undefined ? this._start + opt.length : this._buffer.length; } /** @@ -134,7 +132,7 @@ export class InputBuffer { } /** - * Return a InputStream to read a subset of this stream. It does not + * Return an InputBuffer to read a subset of this stream. It does not * move the read position of this stream. **position** is specified relative * to the start of the buffer. If **position** is not specified, the current * read position is used. If **length** is not specified, the remainder of this @@ -158,11 +156,8 @@ export class InputBuffer { * was not found. */ public indexOf(value: number, offset = 0): number { - for ( - let i = this._offset + offset, end = this._offset + this.length; - i < end; - ++i - ) { + const end = this.offset + this.length; + for (let i = this.offset + offset; i < end; ++i) { if (this._buffer[i] === value) { return i - this._start; } @@ -193,7 +188,7 @@ export class InputBuffer { } public readInt8(): number { - return BitOperators.toInt8(this.readByte()); + return BitUtils.uint8ToInt8(this.readByte()); } /** @@ -219,7 +214,7 @@ export class InputBuffer { } codes.push(c); } - throw new ImageError('EOF reached without finding string terminator'); + throw new LibError('EOF reached without finding string terminator.'); } const s = this.readBytes(length); @@ -237,11 +232,12 @@ export class InputBuffer { const c = this.readByte(); if (c === 0) { const array = new Uint8Array(codes); - return TextCodec.utf8Decoder.decode(array); + return StringUtils.utf8Decoder.decode(array); } codes.push(c); } - throw new ImageError('EOF reached without finding string terminator'); + const array = new Uint8Array(codes); + return StringUtils.utf8Decoder.decode(array); } /** @@ -260,7 +256,7 @@ export class InputBuffer { * Read a 16-bit word from the stream. */ public readInt16(): number { - return BitOperators.toInt16(this.readUint16()); + return BitUtils.uint16ToInt16(this.readUint16()); } /** @@ -280,35 +276,34 @@ export class InputBuffer { * Read a 32-bit word from the stream. */ public readUint32(): number { - const b1 = this._buffer[this._offset++] & 0xff; - const b2 = this._buffer[this._offset++] & 0xff; - const b3 = this._buffer[this._offset++] & 0xff; - const b4 = this._buffer[this._offset++] & 0xff; - const d = this._bigEndian - ? (b1 << 24) | (b2 << 16) | (b3 << 8) | b4 - : (b4 << 24) | (b3 << 16) | (b2 << 8) | b1; - return BitOperators.toUint32(d); + return BitUtils.int32ToUint32(this.readInt32()); } /** * Read a signed 32-bit integer from the stream. */ public readInt32(): number { - return BitOperators.toInt32(this.readUint32()); + const b1 = this._buffer[this._offset++] & 0xff; + const b2 = this._buffer[this._offset++] & 0xff; + const b3 = this._buffer[this._offset++] & 0xff; + const b4 = this._buffer[this._offset++] & 0xff; + return this._bigEndian + ? (b1 << 24) | (b2 << 16) | (b3 << 8) | b4 + : (b4 << 24) | (b3 << 16) | (b2 << 8) | b1; } /** * Read a 32-bit float. */ public readFloat32(): number { - return BitOperators.toFloat32(this.readUint32()); + return BitUtils.uint32ToFloat32(this.readUint32()); } /** * Read a 64-bit float. */ public readFloat64(): number { - return BitOperators.toFloat64(this.readUint64()); + return BitUtils.uint64ToFloat64(this.readUint64()); } /** diff --git a/src/common/interpolation.ts b/src/common/interpolation.ts index 0fcc1af..6baf7a5 100644 --- a/src/common/interpolation.ts +++ b/src/common/interpolation.ts @@ -1,8 +1,26 @@ /** @format */ +/** + * Interpolation method to use when resizing images. + */ export enum Interpolation { + /** + * Select the closest pixel.Fastest, lowest quality. + */ nearest, + + /** + * Linearly blend between the neighboring pixels. + */ linear, + + /** + * Cubic blend between the neighboring pixels. Slowest, highest Quality. + */ cubic, + + /** + * Average the colors of the neighboring pixels. + */ average, } diff --git a/src/common/line.ts b/src/common/line.ts index 82a2bcf..595a42e 100644 --- a/src/common/line.ts +++ b/src/common/line.ts @@ -3,59 +3,85 @@ import { Point } from './point'; export class Line { - private _startX = 0; - private _startY = 0; - private _endX = 0; - private _endY = 0; - private _dx = 0; - private _dy = 0; + private _x1: number; + private _y1: number; + private _x2: number; + private _y2: number; - public get startX(): number { - return this._startX; + public get x1(): number { + return this._x1; } - public get startY(): number { - return this._startY; + public get y1(): number { + return this._y1; } - public get endX(): number { - return this._endX; + public get x2(): number { + return this._x2; } - public get endY(): number { - return this._endY; + public get y2(): number { + return this._y2; } public get dx(): number { - return this._dx; + return this._x2 - this._x1; } public get dy(): number { - return this._dy; + return this._y2 - this._y1; } constructor(x1: number, y1: number, x2: number, y2: number) { - this.initialize(x1, y1, x2, y2); + this._x1 = x1; + this._y1 = y1; + this._x2 = x2; + this._y2 = y2; } public static from(other: Line) { - return new Line(other.startX, other.startY, other.endX, other.endY); + return new Line(other.x1, other.y1, other.x2, other.y2); } - private initialize(x1: number, y1: number, x2: number, y2: number) { - this._startX = Math.min(x1, x2); - this._startY = Math.min(y1, y2); - this._endX = Math.max(x1, x2); - this._endY = Math.max(y1, y2); - this._dx = this._endX - this._startX; - this._dy = this._endY - this._startY; + public movePoint1(x: number, y: number) { + this._x1 = x; + this._y1 = y; } - public moveStart(x: number, y: number) { - this.initialize(x, y, this._endX, this._endY); + public movePoint2(x: number, y: number) { + this._x2 = x; + this._y2 = y; } - public moveEnd(x: number, y: number) { - this.initialize(this._startX, this._startY, x, y); + public swapXY1() { + const tmp = this._x1; + this._x1 = this._y1; + this._y1 = tmp; + } + + public swapXY2() { + const tmp = this._x2; + this._x2 = this._y2; + this._y2 = tmp; + } + + public flipX() { + const tmp = this._x1; + this._x1 = this._x2; + this._x2 = tmp; + } + + public flipY() { + const tmp = this._y1; + this._y1 = this._y2; + this._y2 = tmp; + } + + public clone(): Line { + return new Line(this._x1, this._y1, this._x2, this._y2); + } + + public toString(): string { + return `${this.constructor.name} (x1: ${this._x1}, y1: ${this._y1}, x2: ${this._x2}, y2: ${this._y2})`; } } diff --git a/src/common/math-operators.ts b/src/common/math-operators.ts deleted file mode 100644 index 4a66eff..0000000 --- a/src/common/math-operators.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** @format */ - -export abstract class MathOperators { - /** - * Returns the greatest common divisor of **x** and **y**. - */ - public static gcd(x: number, y: number) { - let _x = Math.abs(x); - let _y = Math.abs(y); - while (_y) { - const t = _y; - _y = _x % _y; - _x = t; - } - return _x; - } - - /** - * Clamp **num** to [**low**, **high**] - */ - public static clamp(num: number, low: number, high: number) { - return Math.max(low, Math.min(num, high)); - } - - /** - * Clamp **num** to [**a**, **b**] and truncate - */ - public static clampInt(num: number, low: number, high: number): number { - return Math.trunc(MathOperators.clamp(num, low, high)); - } - - /** - * Clamp **num** to [**0**, **255**] - */ - public static clampInt255(num: number): number { - return Math.trunc(MathOperators.clamp(num, 0, 255)); - } -} diff --git a/src/common/math-utils.ts b/src/common/math-utils.ts new file mode 100644 index 0000000..6e7f144 --- /dev/null +++ b/src/common/math-utils.ts @@ -0,0 +1,64 @@ +/** @format */ + +export abstract class MathUtils { + public static fract(x: number): number { + return x - Math.floor(x); + } + + public static smoothStep(edge0: number, edge1: number, x: number): number { + const t0 = (x - edge0) / (edge1 - edge0); + const t = MathUtils.clamp(t0, 0, 1); + return t * t * (3 - 2 * t); + } + + public static mix(x: number, y: number, a: number): number { + return x * (1 - a) + y * a; + } + + public static sign(x: number): number { + return x < 0 ? -1 : x > 0 ? 1 : 0; + } + + public static step(edge: number, x: number): number { + return x < edge ? 0 : 1; + } + + public static length3(x: number, y: number, z: number): number { + return Math.sqrt(x * x + y * y + z * z); + } + + /** + * Returns the greatest common divisor of **x** and **y**. + */ + public static gcd(x: number, y: number) { + let _x = Math.abs(x); + let _y = Math.abs(y); + while (_y) { + const t = _y; + _y = _x % _y; + _x = t; + } + return _x; + } + + /** + * Clamp **num** to [**low**, **high**] + */ + public static clamp(num: number, low: number, high: number) { + return Math.max(low, Math.min(num, high)); + } + + /** + * Clamp **num** to [**low**, **high**] and truncate + */ + public static clampInt(num: number, low: number, high: number): number { + return Math.trunc(MathUtils.clamp(num, low, high)); + } + + /** + * Clamp **num** to [0, 255] and truncate + */ + public static clampInt255(num: number): number { + return Math.trunc(MathUtils.clamp(num, 0, 255)); + } +} diff --git a/src/common/memory-image.ts b/src/common/memory-image.ts deleted file mode 100644 index 4e2c850..0000000 --- a/src/common/memory-image.ts +++ /dev/null @@ -1,1027 +0,0 @@ -/** @format */ - -import { ICCProfileData } from './icc-profile-data'; -import { ArrayUtils } from './array-utils'; -import { RgbChannelSet } from './rgb-channel-set'; -import { DisposeMode } from './dispose-mode'; -import { BlendMode } from './blend-mode'; -import { ColorModel } from './color-model'; -import { ImageError } from '../error/image-error'; -import { Interpolation } from './interpolation'; -import { Color } from './color'; -import { ExifData } from '../exif/exif-data'; - -export interface RgbMemoryImageInitOptions { - width: number; - height: number; - exifData?: ExifData; - iccProfile?: ICCProfileData; - textData?: Map; -} - -export interface MemoryImageInitOptions extends RgbMemoryImageInitOptions { - rgbChannelSet?: RgbChannelSet; - data?: Uint32Array; -} - -export interface MemoryImageInitOptionsColorModel { - width: number; - height: number; - data: Uint8Array; - rgbChannelSet?: RgbChannelSet; - exifData?: ExifData; - iccProfile?: ICCProfileData; - textData?: Map; - colorModel?: ColorModel; -} - -/** - * An image buffer where pixels are encoded into 32-bit unsigned ints (Uint32). - * - * Pixels are stored in 32-bit unsigned integers in #AARRGGBB format. - * You can use **getBytes** to access the pixel data at the byte (channel) level, - * optionally providing the format to get the image data as. You can use the - * letious color functions, such as **getRed**, **getGreen**, **getBlue**, and **getAlpha** - * to access the individual channels of a given pixel color. - * - * If this image is a frame of an animation as decoded by the **decodeFrame** - * method of **Decoder**, then the **xOffset**, **yOffset**, **width** and **height** - * determine the area of the canvas this image should be drawn into, - * as some frames of an animation only modify part of the canvas (recording - * the part of the frame that actually changes). The **decodeAnimation** method - * will always return the fully composed animation, so these coordinate - * properties are not used. - */ -export class MemoryImage { - /** - * Pixels are encoded into 4-byte Uint32 integers in #AABBGGRR channel order. - */ - private readonly _data: Uint32Array; - public get data(): Uint32Array { - return this._data; - } - - /** - * x position at which to render the frame. This is used for frames - * in an animation, such as from an animated GIF. - */ - private _xOffset = 0; - public get xOffset(): number { - return this._xOffset; - } - - /** - * y position at which to render the frame. This is used for frames - * in an animation, such as from an animated GIF. - */ - private _yOffset = 0; - public get yOffset(): number { - return this._yOffset; - } - - /** - * How long this frame should be displayed, in milliseconds. - * A duration of 0 indicates no delay and the next frame will be drawn - * as quickly as it can. - */ - private _duration = 0; - public set duration(v: number) { - this._duration = v; - } - public get duration(): number { - return this._duration; - } - - /** - * Defines what should be done to the canvas when drawing this frame - * in an animation. - */ - private _disposeMethod: DisposeMode = DisposeMode.clear; - public get disposeMethod(): DisposeMode { - return this._disposeMethod; - } - - /** - * Defines the blending method (alpha compositing) to use when drawing this - * frame in an animation. - */ - private _blendMethod: BlendMode = BlendMode.over; - public get blendMethod(): BlendMode { - return this._blendMethod; - } - - /** - * The channels used by this image, indicating whether the alpha channel - * is used or not. All images have an implicit alpha channel due to the - * image data being stored in a Uint32, but some images, such as those - * decoded from a Jpeg, don't use the alpha channel. This allows - * image encoders that support both rgb and rgba formats, to know which - * one it should use. - */ - private _rgbChannelSet: RgbChannelSet; - public get rgbChannelSet(): RgbChannelSet { - return this._rgbChannelSet; - } - - /** - * EXIF data decoded from an image file. - */ - private _exifData: ExifData; - public get exifData(): ExifData { - return this._exifData; - } - public set exifData(v: ExifData) { - this._exifData = v; - } - - /** - * ICC color profile read from an image file. - */ - private _iccProfile?: ICCProfileData; - public set iccProfile(v: ICCProfileData | undefined) { - this._iccProfile = v; - } - public get iccProfile(): ICCProfileData | undefined { - return this._iccProfile; - } - - /** - * Some formats, like PNG, can encode and decode text data with the image. - */ - private _textData?: Map; - public get textData(): Map | undefined { - return this._textData; - } - - /** - * Width of the image. - */ - private readonly _width: number; - public get width(): number { - return this._width; - } - - /** - * Height of the image. - */ - private readonly _height: number; - public get height(): number { - return this._height; - } - - /** - * The number of channels used by this Image. While all images - * are stored internally with 4 bytes, some images, such as those - * loaded from a Jpeg, don't use the 4th (alpha) channel. - */ - public get numberOfChannels(): number { - return this.rgbChannelSet === RgbChannelSet.rgba ? 4 : 3; - } - - /** - * The size of the image buffer. - */ - public get length(): number { - return this.data.length; - } - - /** - * Create an image with the given dimensions and format. - */ - constructor(options: MemoryImageInitOptions) { - this._width = options.width; - this._height = options.height; - this._rgbChannelSet = options.rgbChannelSet ?? RgbChannelSet.rgba; - this._exifData = - options.exifData !== undefined - ? ExifData.from(options.exifData) - : new ExifData(); - this._iccProfile = options.iccProfile; - this._textData = options.textData; - this._data = - options.data ?? new Uint32Array(options.width * options.height); - } - - private static convertData( - width: number, - height: number, - bytes: Uint8Array | Uint32Array, - colorModel: ColorModel - ): Uint32Array { - if (colorModel === ColorModel.rgba) { - return bytes instanceof Uint32Array - ? ArrayUtils.copyUint32(bytes) - : ArrayUtils.copyUint32(new Uint32Array(bytes.buffer)); - } - const input = - bytes instanceof Uint32Array ? new Uint8Array(bytes.buffer) : bytes; - - const data = new Uint32Array(width * height); - const rgba = new Uint8Array(data.buffer); - - switch (colorModel) { - case ColorModel.bgra: - for (let i = 0, len = input.length; i < len; i += 4) { - rgba[i + 0] = input[i + 2]; - rgba[i + 1] = input[i + 1]; - rgba[i + 2] = input[i + 0]; - rgba[i + 3] = input[i + 3]; - } - break; - case ColorModel.abgr: - for (let i = 0, len = input.length; i < len; i += 4) { - rgba[i + 0] = input[i + 3]; - rgba[i + 1] = input[i + 2]; - rgba[i + 2] = input[i + 1]; - rgba[i + 3] = input[i + 0]; - } - break; - case ColorModel.argb: - for (let i = 0, len = input.length; i < len; i += 4) { - rgba[i + 0] = input[i + 1]; - rgba[i + 1] = input[i + 2]; - rgba[i + 2] = input[i + 3]; - rgba[i + 3] = input[i + 0]; - } - break; - case ColorModel.bgr: - for (let i = 0, j = 0, len = input.length; j < len; i += 4, j += 3) { - rgba[i + 0] = input[j + 2]; - rgba[i + 1] = input[j + 1]; - rgba[i + 2] = input[j + 0]; - rgba[i + 3] = 255; - } - break; - case ColorModel.rgb: - for (let i = 0, j = 0, len = input.length; j < len; i += 4, j += 3) { - rgba[i + 0] = input[j + 0]; - rgba[i + 1] = input[j + 1]; - rgba[i + 2] = input[j + 2]; - rgba[i + 3] = 255; - } - break; - case ColorModel.luminance: - for (let i = 0, j = 0, len = input.length; j < len; i += 4, ++j) { - rgba[i + 0] = input[j]; - rgba[i + 1] = input[j]; - rgba[i + 2] = input[j]; - rgba[i + 3] = 255; - } - break; - } - return data; - } - - public static rgb(options: RgbMemoryImageInitOptions): MemoryImage { - const opt = { - ...options, - rgbChannelSet: RgbChannelSet.rgb, - } as MemoryImageInitOptions; - return new MemoryImage(opt); - } - - public static from(other: MemoryImage): MemoryImage { - const result = new MemoryImage({ - width: other._width, - height: other._height, - rgbChannelSet: other._rgbChannelSet, - exifData: ExifData.from(other._exifData), - iccProfile: other._iccProfile, - textData: - other._textData !== undefined ? new Map(other._textData) : undefined, - data: ArrayUtils.copyUint32(other._data), - }); - result._xOffset = other._xOffset; - result._yOffset = other._yOffset; - result._duration = other._duration; - result._disposeMethod = other._disposeMethod; - result._blendMethod = other._blendMethod; - return result; - } - - /** - * - * **format** defines the order of color channels in **data**. - * The length of **data** should be (width * height) * format-byte-count, - * where format-byte-count is 1, 3, or 4 depending on the number of - * channels in the format (luminance, rgb, rgba, etc). - * - * The native format of an image is Format.rgba. If another format - * is specified, the input data will be converted to rgba to store - * in the Image. - */ - public static fromBytes( - options: MemoryImageInitOptionsColorModel - ): MemoryImage { - options.rgbChannelSet ??= RgbChannelSet.rgba; - options.colorModel ??= ColorModel.rgba; - const data = this.convertData( - options.width, - options.height, - options.data, - options.colorModel - ); - const result = new MemoryImage({ - width: options.width, - height: options.height, - rgbChannelSet: options.rgbChannelSet, - exifData: options.exifData, - iccProfile: options.iccProfile, - textData: options.textData, - data: data, - }); - return result; - } - - /** - * Clone this image. - * */ - public clone(): MemoryImage { - return MemoryImage.from(this); - } - - /** - * Get the bytes from the image. You can use this to access the - * color channels directly, or to pass it to something like an - * Html canvas context. - * - * Specifying the **format** will convert the image data to the specified - * format. Images are stored internally in Format.rgba format; any - * other format will require a conversion. - * - * For example, given an Html Canvas, you could draw this image into the - * canvas: - * Html.ImageData d = context2D.createImageData(image.width, image.height); - * d.data.setRange(0, image.length, image.getBytes(format: Format.rgba)); - * context2D.putImageData(data, 0, 0); - */ - public getBytes(colorModel: ColorModel = ColorModel.rgba): Uint8Array { - const rgba = new Uint8Array(this._data.buffer); - switch (colorModel) { - case ColorModel.rgba: - return rgba; - case ColorModel.bgra: { - const bytes = new Uint8Array(this._width * this._height * 4); - for (let i = 0, len = bytes.length; i < len; i += 4) { - bytes[i + 0] = rgba[i + 2]; - bytes[i + 1] = rgba[i + 1]; - bytes[i + 2] = rgba[i + 0]; - bytes[i + 3] = rgba[i + 3]; - } - return bytes; - } - case ColorModel.abgr: { - const bytes = new Uint8Array(this._width * this._height * 4); - for (let i = 0, len = bytes.length; i < len; i += 4) { - bytes[i + 0] = rgba[i + 3]; - bytes[i + 1] = rgba[i + 2]; - bytes[i + 2] = rgba[i + 1]; - bytes[i + 3] = rgba[i + 0]; - } - return bytes; - } - case ColorModel.argb: { - const bytes = new Uint8Array(this._width * this._height * 4); - for (let i = 0, len = bytes.length; i < len; i += 4) { - bytes[i + 0] = rgba[i + 3]; - bytes[i + 1] = rgba[i + 0]; - bytes[i + 2] = rgba[i + 1]; - bytes[i + 3] = rgba[i + 2]; - } - return bytes; - } - case ColorModel.rgb: { - const bytes = new Uint8Array(this._width * this._height * 3); - for (let i = 0, j = 0, len = bytes.length; j < len; i += 4, j += 3) { - bytes[j + 0] = rgba[i + 0]; - bytes[j + 1] = rgba[i + 1]; - bytes[j + 2] = rgba[i + 2]; - } - return bytes; - } - case ColorModel.bgr: { - const bytes = new Uint8Array(this._width * this._height * 3); - for (let i = 0, j = 0, len = bytes.length; j < len; i += 4, j += 3) { - bytes[j + 0] = rgba[i + 2]; - bytes[j + 1] = rgba[i + 1]; - bytes[j + 2] = rgba[i + 0]; - } - return bytes; - } - case ColorModel.luminance: { - const bytes = new Uint8Array(this._width * this._height); - for (let i = 0, len = this.length; i < len; ++i) { - bytes[i] = Color.getLuminance(this._data[i]); - } - return bytes; - } - } - throw new ImageError('Unknown color model'); - } - - /** - * Set all of the pixels of the image to the given **color**. - */ - public fill(color: number): MemoryImage { - this._data.fill(color); - return this; - } - - /** - * Set all of the empty pixels (for png's) of the image to the given **color**. - */ - public fillBackground(color: number): void { - // Loop all pixels - for (let i = 0; i < this.length; i++) { - // Value 0 means null pixel - if (this._data[i] === 0) { - // Set the pixel to the given color - this._data[i] = color; - } - } - } - - /** - * Add the colors of **other** to the pixels of this image. - */ - public addImage(other: MemoryImage): MemoryImage { - const h = Math.min(this._height, other._height); - const w = Math.min(this._width, other._width); - for (let y = 0; y < h; ++y) { - for (let x = 0; x < w; ++x) { - const c1 = this.getPixel(x, y); - const r1 = Color.getRed(c1); - const g1 = Color.getGreen(c1); - const b1 = Color.getBlue(c1); - const a1 = Color.getAlpha(c1); - - const c2 = other.getPixel(x, y); - const r2 = Color.getRed(c2); - const g2 = Color.getGreen(c2); - const b2 = Color.getBlue(c2); - const a2 = Color.getAlpha(c2); - - this.setPixel(x, y, Color.getColor(r1 + r2, g1 + g2, b1 + b2, a1 + a2)); - } - } - return this; - } - - /** - * Subtract the colors of **other** from the pixels of this image. - */ - public subtractImage(other: MemoryImage): MemoryImage { - const h = Math.min(this._height, other._height); - const w = Math.min(this._width, other._width); - for (let y = 0; y < h; ++y) { - for (let x = 0; x < w; ++x) { - const c1 = this.getPixel(x, y); - const r1 = Color.getRed(c1); - const g1 = Color.getGreen(c1); - const b1 = Color.getBlue(c1); - const a1 = Color.getAlpha(c1); - - const c2 = other.getPixel(x, y); - const r2 = Color.getRed(c2); - const g2 = Color.getGreen(c2); - const b2 = Color.getBlue(c2); - const a2 = Color.getAlpha(c2); - - this.setPixel(x, y, Color.getColor(r1 - r2, g1 - g2, b1 - b2, a1 - a2)); - } - } - return this; - } - - /** - * Multiply the colors of **other** with the pixels of this image. - */ - public multiplyImage(other: MemoryImage): MemoryImage { - const h = Math.min(this._height, other._height); - const w = Math.min(this._width, other._width); - for (let y = 0; y < h; ++y) { - for (let x = 0; x < w; ++x) { - const c1 = this.getPixel(x, y); - const r1 = Color.getRed(c1); - const g1 = Color.getGreen(c1); - const b1 = Color.getBlue(c1); - const a1 = Color.getAlpha(c1); - - const c2 = other.getPixel(x, y); - const r2 = Color.getRed(c2); - const g2 = Color.getGreen(c2); - const b2 = Color.getBlue(c2); - const a2 = Color.getAlpha(c2); - - this.setPixel(x, y, Color.getColor(r1 * r2, g1 * g2, b1 * b2, a1 * a2)); - } - } - return this; - } - - /** - * OR the colors of **other** to the pixels of this image. - */ - public orImage(other: MemoryImage): MemoryImage { - const h = Math.min(this._height, other._height); - const w = Math.min(this._width, other._width); - for (let y = 0; y < h; ++y) { - for (let x = 0; x < w; ++x) { - const c1 = this.getPixel(x, y); - const r1 = Color.getRed(c1); - const g1 = Color.getGreen(c1); - const b1 = Color.getBlue(c1); - const a1 = Color.getAlpha(c1); - - const c2 = other.getPixel(x, y); - const r2 = Color.getRed(c2); - const g2 = Color.getGreen(c2); - const b2 = Color.getBlue(c2); - const a2 = Color.getAlpha(c2); - - this.setPixel(x, y, Color.getColor(r1 | r2, g1 | g2, b1 | b2, a1 | a2)); - } - } - return this; - } - - /** - * AND the colors of **other** with the pixels of this image. - */ - public andImage(other: MemoryImage): MemoryImage { - const h = Math.min(this._height, other._height); - const w = Math.min(this._width, other._width); - for (let y = 0; y < h; ++y) { - for (let x = 0; x < w; ++x) { - const c1 = this.getPixel(x, y); - const r1 = Color.getRed(c1); - const g1 = Color.getGreen(c1); - const b1 = Color.getBlue(c1); - const a1 = Color.getAlpha(c1); - - const c2 = other.getPixel(x, y); - const r2 = Color.getRed(c2); - const g2 = Color.getGreen(c2); - const b2 = Color.getBlue(c2); - const a2 = Color.getAlpha(c2); - - this.setPixel(x, y, Color.getColor(r1 & r2, g1 & g2, b1 & b2, a1 & a2)); - } - } - return this; - } - - /** - * Modula the colors of **other** with the pixels of this image. - */ - public modImage(other: MemoryImage): MemoryImage { - const h = Math.min(this._height, other._height); - const w = Math.min(this._width, other._width); - for (let y = 0; y < h; ++y) { - for (let x = 0; x < w; ++x) { - const c1 = this.getPixel(x, y); - const r1 = Color.getRed(c1); - const g1 = Color.getGreen(c1); - const b1 = Color.getBlue(c1); - const a1 = Color.getAlpha(c1); - - const c2 = other.getPixel(x, y); - const r2 = Color.getRed(c2); - const g2 = Color.getGreen(c2); - const b2 = Color.getBlue(c2); - const a2 = Color.getAlpha(c2); - - this.setPixel(x, y, Color.getColor(r1 % r2, g1 % g2, b1 % b2, a1 % a2)); - } - } - return this; - } - - /** - * Get a pixel from the buffer. No range checking is done. - */ - public getPixelByIndex(index: number): number { - return this._data[index]; - } - - /** - * Set a pixel in the buffer. No range checking is done. - */ - public setPixelByIndex(index: number, color: number): void { - this._data[index] = color; - } - - /** - * Get the buffer index for the **x**, **y** pixel coordinates. - * No range checking is done. - */ - public getBufferIndex(x: number, y: number): number { - return y * this._width + x; - } - - /** - * Is the given **x**, **y** pixel coordinates within the resolution of the image. - */ - public boundsSafe(x: number, y: number): boolean { - return x >= 0 && x < this._width && y >= 0 && y < this._height; - } - - /** - * Get the pixel from the given **x**, **y** coordinate. Color is encoded in a - * Uint32 as #AABBGGRR. No range checking is done. - */ - public getPixel(x: number, y: number): number { - const index = this.getBufferIndex(x, y); - return this._data[index]; - } - - /** - * Get the pixel from the given **x**, **y** coordinate. Color is encoded in a - * Uint32 as #AABBGGRR. If the pixel coordinates are out of bounds, 0 is - * returned. - */ - public getPixelSafe(x: number, y: number): number { - const index = this.getBufferIndex(x, y); - return this.boundsSafe(x, y) ? this._data[index] : 0; - } - - /** - * Get the pixel using the given **interpolation** type for non-integer pixel - * coordinates. - */ - public getPixelInterpolate( - fx: number, - fy: number, - interpolation: Interpolation = Interpolation.linear - ): number { - if (interpolation === Interpolation.cubic) { - return this.getPixelCubic(fx, fy); - } else if (interpolation === Interpolation.linear) { - return this.getPixelLinear(fx, fy); - } - return this.getPixelSafe(Math.trunc(fx), Math.trunc(fy)); - } - - /** - * Get the pixel using linear interpolation for non-integer pixel - * coordinates. - */ - public getPixelLinear(fx: number, fy: number): number { - const x = Math.trunc(fx) - (fx >= 0 ? 0 : 1); - const nx = x + 1; - const y = Math.trunc(fy) - (fy >= 0 ? 0 : 1); - const ny = y + 1; - const dx = fx - x; - const dy = fy - y; - - const linear = ( - icc: number, - inc: number, - icn: number, - inn: number - ): number => { - return Math.trunc( - icc + dx * (inc - icc + dy * (icc + inn - icn - inc)) + dy * (icn - icc) - ); - }; - - const icc = this.getPixelSafe(x, y); - const icn = ny >= this._height ? icc : this.getPixelSafe(x, ny); - const inc = nx >= this._width ? icc : this.getPixelSafe(nx, y); - const inn = - nx >= this._width || ny >= this._height ? icc : this.getPixelSafe(nx, ny); - - return Color.getColor( - linear( - Color.getRed(icc), - Color.getRed(inc), - Color.getRed(icn), - Color.getRed(inn) - ), - linear( - Color.getGreen(icc), - Color.getGreen(inc), - Color.getGreen(icn), - Color.getGreen(inn) - ), - linear( - Color.getBlue(icc), - Color.getBlue(inc), - Color.getBlue(icn), - Color.getBlue(inn) - ), - linear( - Color.getAlpha(icc), - Color.getAlpha(inc), - Color.getAlpha(icn), - Color.getAlpha(inn) - ) - ); - } - - /** - * Get the pixel using cubic interpolation for non-integer pixel - * coordinates. - */ - public getPixelCubic(fx: number, fy: number): number { - const x = Math.trunc(fx) - (fx >= 0.0 ? 0 : 1); - const px = x - 1; - const nx = x + 1; - const ax = x + 2; - const y = Math.trunc(fy) - (fy >= 0.0 ? 0 : 1); - const py = y - 1; - const ny = y + 1; - const ay = y + 2; - - const dx = fx - x; - const dy = fy - y; - - const cubic = ( - dx: number, - ipp: number, - icp: number, - inp: number, - iap: number - ): number => { - return ( - icp + - 0.5 * - (dx * (-ipp + inp) + - (dx * (dx * (2 * ipp)) - 5 * icp + 4 * inp - iap) + - dx * (dx * (dx * (-ipp + 3 * icp - 3 * inp + iap)))) - ); - }; - - const icc = this.getPixelSafe(x, y); - - const ipp = px < 0 || py < 0 ? icc : this.getPixelSafe(px, py); - const icp = px < 0 ? icc : this.getPixelSafe(x, py); - const inp = py < 0 || nx >= this._width ? icc : this.getPixelSafe(nx, py); - const iap = ax >= this._width || py < 0 ? icc : this.getPixelSafe(ax, py); - - const ip0 = cubic( - dx, - Color.getRed(ipp), - Color.getRed(icp), - Color.getRed(inp), - Color.getRed(iap) - ); - - const ip1 = cubic( - dx, - Color.getGreen(ipp), - Color.getGreen(icp), - Color.getGreen(inp), - Color.getGreen(iap) - ); - const ip2 = cubic( - dx, - Color.getBlue(ipp), - Color.getBlue(icp), - Color.getBlue(inp), - Color.getBlue(iap) - ); - const ip3 = cubic( - dx, - Color.getAlpha(ipp), - Color.getAlpha(icp), - Color.getAlpha(inp), - Color.getAlpha(iap) - ); - - const ipc = px < 0 ? icc : this.getPixelSafe(px, y); - const inc = nx >= this._width ? icc : this.getPixelSafe(nx, y); - const iac = ax >= this._width ? icc : this.getPixelSafe(ax, y); - - const Ic0 = cubic( - dx, - Color.getRed(ipc), - Color.getRed(icc), - Color.getRed(inc), - Color.getRed(iac) - ); - const Ic1 = cubic( - dx, - Color.getGreen(ipc), - Color.getGreen(icc), - Color.getGreen(inc), - Color.getGreen(iac) - ); - const Ic2 = cubic( - dx, - Color.getBlue(ipc), - Color.getBlue(icc), - Color.getBlue(inc), - Color.getBlue(iac) - ); - const Ic3 = cubic( - dx, - Color.getAlpha(ipc), - Color.getAlpha(icc), - Color.getAlpha(inc), - Color.getAlpha(iac) - ); - - const ipn = px < 0 || ny >= this._height ? icc : this.getPixelSafe(px, ny); - const icn = ny >= this._height ? icc : this.getPixelSafe(x, ny); - const inn = - nx >= this._width || ny >= this._height ? icc : this.getPixelSafe(nx, ny); - const ian = - ax >= this._width || ny >= this._height ? icc : this.getPixelSafe(ax, ny); - - const in0 = cubic( - dx, - Color.getRed(ipn), - Color.getRed(icn), - Color.getRed(inn), - Color.getRed(ian) - ); - const in1 = cubic( - dx, - Color.getGreen(ipn), - Color.getGreen(icn), - Color.getGreen(inn), - Color.getGreen(ian) - ); - const in2 = cubic( - dx, - Color.getBlue(ipn), - Color.getBlue(icn), - Color.getBlue(inn), - Color.getBlue(ian) - ); - const in3 = cubic( - dx, - Color.getAlpha(ipn), - Color.getAlpha(icn), - Color.getAlpha(inn), - Color.getAlpha(ian) - ); - - const ipa = px < 0 || ay >= this._height ? icc : this.getPixelSafe(px, ay); - const ica = ay >= this._height ? icc : this.getPixelSafe(x, ay); - const ina = - nx >= this._width || ay >= this._height ? icc : this.getPixelSafe(nx, ay); - const iaa = - ax >= this._width || ay >= this._height ? icc : this.getPixelSafe(ax, ay); - - const ia0 = cubic( - dx, - Color.getRed(ipa), - Color.getRed(ica), - Color.getRed(ina), - Color.getRed(iaa) - ); - const ia1 = cubic( - dx, - Color.getGreen(ipa), - Color.getGreen(ica), - Color.getGreen(ina), - Color.getGreen(iaa) - ); - const ia2 = cubic( - dx, - Color.getBlue(ipa), - Color.getBlue(ica), - Color.getBlue(ina), - Color.getBlue(iaa) - ); - const ia3 = cubic( - dx, - Color.getAlpha(ipa), - Color.getAlpha(ica), - Color.getAlpha(ina), - Color.getAlpha(iaa) - ); - - const c0 = cubic(dy, ip0, Ic0, in0, ia0); - const c1 = cubic(dy, ip1, Ic1, in1, ia1); - const c2 = cubic(dy, ip2, Ic2, in2, ia2); - const c3 = cubic(dy, ip3, Ic3, in3, ia3); - - return Color.getColor( - Math.trunc(c0), - Math.trunc(c1), - Math.trunc(c2), - Math.trunc(c3) - ); - } - - /** - * Set the pixel at the given **x**, **y** coordinate to the **color**. - * No range checking is done. - */ - public setPixel(x: number, y: number, color: number): void { - const index = this.getBufferIndex(x, y); - this._data[index] = color; - } - - /** - * Set the pixel at the given **x**, **y** coordinate to the **color**. - * If the pixel coordinates are out of bounds, nothing is done. - */ - public setPixelSafe(x: number, y: number, color: number): void { - if (this.boundsSafe(x, y)) { - const index = this.getBufferIndex(x, y); - this._data[index] = color; - } - } - - /** - * Set the pixel at the given **x**, **y** coordinate to the color - * **r**, **g**, **b**, **a**. - * - * This simply replaces the existing color, it does not do any alpha - * blending. Use **drawPixel** for that. No range checking is done. - */ - public setPixelRgba( - x: number, - y: number, - r: number, - g: number, - b: number, - a = 0xff - ): void { - const index = this.getBufferIndex(x, y); - this._data[index] = Color.getColor(r, g, b, a); - } - - /** - * Return the average gray value of the image. - */ - public getWhiteBalance(asDouble = false) { - const len = this._data.length; - let r = 0.0; - let g = 0.0; - let b = 0.0; - let t = 1; - for (let i = 0; i < len; ++i) { - r += (Color.getRed(this._data[i]) - r) / t; - g += (Color.getGreen(this._data[i]) - g) / t; - b += (Color.getBlue(this._data[i]) - b) / t; - ++t; - } - const averageGray = (r + g + b) / 3.0; - return asDouble ? averageGray : Math.trunc(averageGray); - } - - /** - * Find the minimum and maximum color value in the image. - * Returns an object with **min** and **max** properties. - */ - public getColorExtremes(): { - min: number; - max: number; - } { - let min = 255; - let max = 0; - for (let i = 0; i < this.length; ++i) { - const c = this.getPixelByIndex(i); - const r = Color.getRed(c); - const g = Color.getGreen(c); - const b = Color.getBlue(c); - - if (r < min) { - min = r; - } - if (r > max) { - max = r; - } - if (g < min) { - min = g; - } - if (g > max) { - max = g; - } - if (b < min) { - min = b; - } - if (b > max) { - max = b; - } - if (this.rgbChannelSet === RgbChannelSet.rgba) { - const a = Color.getAlpha(c); - if (a < min) { - min = a; - } - if (a > max) { - max = a; - } - } - } - - return { - min: min, - max: max, - }; - } - - public addTextData(data: Map): void { - if (this._textData === undefined) { - this._textData = new Map(); - } - for (const [key, value] of data) { - this._textData.set(key, value); - } - } -} diff --git a/src/common/neural-quantizer.ts b/src/common/neural-quantizer.ts deleted file mode 100644 index 2091f05..0000000 --- a/src/common/neural-quantizer.ts +++ /dev/null @@ -1,610 +0,0 @@ -/** @format */ - -import { Color } from './color'; -import { MemoryImage } from './memory-image'; -import { Quantizer } from './quantizer'; - -/** - * Compute a color map with a given number of colors that best represents - * the given image. - */ -export class NeuralQuantizer implements Quantizer { - // No. of learning cycles - private static readonly numCycles: number = 100; - - // Alpha starts at 1 - private static readonly alphaBiasShift: number = 10; - - // Biased by 10 bits - private static readonly initAlpha: number = - 1 << NeuralQuantizer.alphaBiasShift; - - private static readonly radiusBiasShift: number = 8; - - private static readonly radiusBias: number = - 1 << NeuralQuantizer.radiusBiasShift; - - private static readonly alphaRadiusBiasShift: number = - NeuralQuantizer.alphaBiasShift + NeuralQuantizer.radiusBiasShift; - - private static readonly alphaRadiusBias: number = - 1 << NeuralQuantizer.alphaRadiusBiasShift; - - // Factor of 1/30 each cycle - private static readonly radiusDec: number = 30; - - private static readonly gamma: number = 1024; - - private static readonly beta: number = 1 / 1024; - - private static readonly betaGamma: number = - NeuralQuantizer.beta * NeuralQuantizer.gamma; - - // Four primes near 500 - assume no image has a length so large - // that it is divisible by all four primes - - private static readonly prime1 = 499; - - private static readonly prime2 = 491; - - private static readonly prime3 = 487; - - private static readonly prime4 = 503; - - private static readonly smallImageBytes = 3 * NeuralQuantizer.prime4; - - private readonly netIndex = new Int32Array(256); - - private samplingFactor: number; - - // Number of colors used - private netSize = 16; - - // Number of reserved colors used - private specials = 3; - - // Reserved background color - private bgColor = 0; - - private cutNetSize = 0; - - private maxNetPos = 0; - - // For 256 cols, radius starts at 32 - private initRadius = 0; - - private initBiasRadius = 0; - - private radiusPower!: Int32Array; - - /** - * The network itself - */ - private network!: number[]; - - private _colorMap8!: Uint8Array; - public get colorMap8(): Uint8Array { - return this._colorMap8; - } - - private _colorMap32!: Int32Array; - public get colorMap32(): Int32Array { - return this._colorMap32; - } - - /** - * Bias array for learning - */ - private bias!: number[]; - - // Freq array for learning - private freq!: number[]; - - /** - * How many colors are in the **colorMap**? - */ - get numColors(): number { - return this.netSize; - } - - /** - * 10 is a reasonable **samplingFactor** according to - * https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/. - */ - constructor(image: MemoryImage, numberOfColors = 256, samplingFactor = 10) { - this.samplingFactor = samplingFactor; - this.initialize(numberOfColors); - this.addImage(image); - } - - private initialize(numberOfColors: number): void { - // Number of colours used - this.netSize = Math.max(numberOfColors, 4); - this.cutNetSize = this.netSize - this.specials; - this.maxNetPos = this.netSize - 1; - // For 256 cols, radius starts at 32 - this.initRadius = Math.floor(this.netSize / 8); - this.initBiasRadius = this.initRadius * NeuralQuantizer.radiusBias; - this._colorMap32 = new Int32Array(this.netSize * 4); - this._colorMap8 = new Uint8Array(this.netSize * 3); - // Number of reserved colors used - this.specials = 3; - this.bgColor = this.specials - 1; - this.radiusPower = new Int32Array(this.netSize >> 3); - - this.network = new Array(this.netSize * 3).fill(0); - this.bias = new Array(this.netSize).fill(0); - this.freq = new Array(this.netSize).fill(0); - - // Black - this.network[0] = 0.0; - this.network[1] = 0.0; - this.network[2] = 0.0; - - // White - this.network[3] = 255.0; - this.network[4] = 255.0; - this.network[5] = 255.0; - - // RESERVED bgColor - // background - const f = 1.0 / this.netSize; - for (let i = 0; i < this.specials; ++i) { - this.freq[i] = f; - this.bias[i] = 0.0; - } - - for (let i = this.specials, p = this.specials * 3; i < this.netSize; ++i) { - this.network[p++] = (255.0 * (i - this.specials)) / this.cutNetSize; - this.network[p++] = (255.0 * (i - this.specials)) / this.cutNetSize; - this.network[p++] = (255.0 * (i - this.specials)) / this.cutNetSize; - - this.freq[i] = f; - this.bias[i] = 0.0; - } - } - - private updateRadiusPower(rad: number, alpha: number): void { - for (let i = 0; i < rad; i++) { - this.radiusPower[i] = Math.trunc( - alpha * - (((rad * rad - i * i) * NeuralQuantizer.radiusBias) / (rad * rad)) - ); - } - } - - private specialFind(b: number, g: number, r: number): number { - for (let i = 0, p = 0; i < this.specials; i++) { - if ( - this.network[p++] === b && - this.network[p++] === g && - this.network[p++] === r - ) { - return i; - } - } - return -1; - } - - /** - * Search for biased BGR values - */ - private contest(b: number, g: number, r: number): number { - // Finds closest neuron (min dist) and updates freq - // finds best neuron (min dist-bias) and returns position - // for frequently chosen neurons, freq[i] is high and bias[i] is negative - // bias[i] = gamma*((1/netsize)-freq[i]) - let bestd = 1.0e30; - let bestBiasDist: number = bestd; - let bestpos = -1; - let bestbiaspos: number = bestpos; - - for (let i = this.specials, p = this.specials * 3; i < this.netSize; i++) { - let dist = this.network[p++] - b; - if (dist < 0) { - dist = -dist; - } - let a = this.network[p++] - g; - if (a < 0) { - a = -a; - } - dist += a; - a = this.network[p++] - r; - if (a < 0) { - a = -a; - } - dist += a; - if (dist < bestd) { - bestd = dist; - bestpos = i; - } - - const biasDist = dist - this.bias[i]; - if (biasDist < bestBiasDist) { - bestBiasDist = biasDist; - bestbiaspos = i; - } - this.freq[i] -= NeuralQuantizer.beta * this.freq[i]; - this.bias[i] += NeuralQuantizer.betaGamma * this.freq[i]; - } - this.freq[bestpos] += NeuralQuantizer.beta; - this.bias[bestpos] -= NeuralQuantizer.betaGamma; - return bestbiaspos; - } - - private alterSingle( - alpha: number, - i: number, - b: number, - g: number, - r: number - ): void { - // Move neuron i towards biased (b,g,r) by factor alpha - const p = i * 3; - this.network[p] -= alpha * (this.network[p] - b); - this.network[p + 1] -= alpha * (this.network[p + 1] - g); - this.network[p + 2] -= alpha * (this.network[p + 2] - r); - } - - private alterNeighbors( - _: number, - rad: number, - i: number, - b: number, - g: number, - r: number - ): void { - let lo = i - rad; - if (lo < this.specials - 1) { - lo = this.specials - 1; - } - - let hi = i + rad; - if (hi > this.netSize) { - hi = this.netSize; - } - - let j = i + 1; - let k = i - 1; - let m = 1; - while (j < hi || k > lo) { - const a = this.radiusPower[m++]; - if (j < hi) { - const p = j * 3; - this.network[p] -= - (a * (this.network[p] - b)) / NeuralQuantizer.alphaRadiusBias; - this.network[p + 1] -= - (a * (this.network[p + 1] - g)) / NeuralQuantizer.alphaRadiusBias; - this.network[p + 2] -= - (a * (this.network[p + 2] - r)) / NeuralQuantizer.alphaRadiusBias; - j++; - } - if (k > lo) { - const p = k * 3; - this.network[p] -= - (a * (this.network[p] - b)) / NeuralQuantizer.alphaRadiusBias; - this.network[p + 1] -= - (a * (this.network[p + 1] - g)) / NeuralQuantizer.alphaRadiusBias; - this.network[p + 2] -= - (a * (this.network[p + 2] - r)) / NeuralQuantizer.alphaRadiusBias; - k--; - } - } - } - - private learn(image: MemoryImage): void { - let biasRadius = this.initBiasRadius; - const alphaDec = 30 + Math.floor((this.samplingFactor - 1) / 3); - const lengthCount = image.length; - const samplePixels = Math.floor(lengthCount / this.samplingFactor); - let delta = Math.max( - Math.floor(samplePixels / NeuralQuantizer.numCycles), - 1 - ); - let alpha = NeuralQuantizer.initAlpha; - - if (delta === 0) { - delta = 1; - } - - let rad = biasRadius >> NeuralQuantizer.radiusBiasShift; - if (rad <= 1) { - rad = 0; - } - - this.updateRadiusPower(rad, alpha); - - let step = 0; - let pos = 0; - if (lengthCount < NeuralQuantizer.smallImageBytes) { - this.samplingFactor = 1; - step = 1; - } else if (lengthCount % NeuralQuantizer.prime1 !== 0) { - step = NeuralQuantizer.prime1; - } else { - if (lengthCount % NeuralQuantizer.prime2 !== 0) { - step = NeuralQuantizer.prime2; - } else { - if (lengthCount % NeuralQuantizer.prime3 !== 0) { - step = NeuralQuantizer.prime3; - } else { - step = NeuralQuantizer.prime4; - } - } - } - - let i = 0; - while (i < samplePixels) { - const p = image.getPixelByIndex(pos); - const red = Color.getRed(p); - const green = Color.getGreen(p); - const blue = Color.getBlue(p); - - if (i === 0) { - // Remember background colour - this.network[this.bgColor * 3] = blue; - this.network[this.bgColor * 3 + 1] = green; - this.network[this.bgColor * 3 + 2] = red; - } - - let j = this.specialFind(blue, green, red); - j = j < 0 ? this.contest(blue, green, red) : j; - - if (j >= this.specials) { - // Don't learn for specials - const a = Number(alpha) / NeuralQuantizer.initAlpha; - this.alterSingle(a, j, blue, green, red); - if (rad > 0) { - // Alter neighbours - this.alterNeighbors(a, rad, j, blue, green, red); - } - } - - pos += step; - while (pos >= lengthCount) { - pos -= lengthCount; - } - - i++; - if (i % delta === 0) { - alpha -= Math.floor(alpha / alphaDec); - biasRadius -= Math.floor(biasRadius / NeuralQuantizer.radiusDec); - rad = biasRadius >> NeuralQuantizer.radiusBiasShift; - if (rad <= 1) { - rad = 0; - } - this.updateRadiusPower(rad, alpha); - } - } - } - - private fix(): void { - for (let i = 0, p = 0, q = 0; i < this.netSize; i++, q += 4) { - for (let j = 0; j < 3; ++j, ++p) { - let x = Math.trunc(0.5 + this.network[p]); - if (x < 0) { - x = 0; - } - if (x > 255) { - x = 255; - } - this._colorMap32[q + j] = x; - } - this._colorMap32[q + 3] = i; - } - } - - /** - * Insertion sort of network and building of netindex[0..255] - */ - private inxBuild(): void { - let previousColor = 0; - let startPos = 0; - - for (let i = 0, p = 0; i < this.netSize; i++, p += 4) { - let smallpos = i; - // Index on g - let smallval = this._colorMap32[p + 1]; - - // Find smallest in i..netsize-1 - for (let j = i + 1, q = p + 4; j < this.netSize; j++, q += 4) { - if (this._colorMap32[q + 1] < smallval) { - // Index on g - smallpos = j; - // Index on g - smallval = this._colorMap32[q + 1]; - } - } - - const q = smallpos * 4; - - // Swap p (i) and q (smallpos) entries - if (i !== smallpos) { - let j = this._colorMap32[q]; - this._colorMap32[q] = this._colorMap32[p]; - this._colorMap32[p] = j; - - j = this._colorMap32[q + 1]; - this._colorMap32[q + 1] = this._colorMap32[p + 1]; - this._colorMap32[p + 1] = j; - - j = this._colorMap32[q + 2]; - this._colorMap32[q + 2] = this._colorMap32[p + 2]; - this.colorMap32[p + 2] = j; - - j = this._colorMap32[q + 3]; - this._colorMap32[q + 3] = this._colorMap32[p + 3]; - this._colorMap32[p + 3] = j; - } - - // SmallVal entry is now in position i - if (smallval !== previousColor) { - this.netIndex[previousColor] = (startPos + i) >> 1; - for (let j = previousColor + 1; j < smallval; j++) { - this.netIndex[j] = i; - } - previousColor = smallval; - startPos = i; - } - } - - this.netIndex[previousColor] = (startPos + this.maxNetPos) >> 1; - for (let j = previousColor + 1; j < 256; j++) { - // Really 256 - this.netIndex[j] = this.maxNetPos; - } - } - - private copyColorMap(): void { - for (let i = 0, p = 0, q = 0; i < this.netSize; ++i) { - this._colorMap8[p++] = Math.abs(this._colorMap32[q + 2]) & 0xff; - this._colorMap8[p++] = Math.abs(this._colorMap32[q + 1]) & 0xff; - this._colorMap8[p++] = Math.abs(this._colorMap32[q]) & 0xff; - q += 4; - } - } - - /** - * Add an image to the quantized color table. - */ - private addImage(image: MemoryImage): void { - this.learn(image); - this.fix(); - this.inxBuild(); - this.copyColorMap(); - } - - /** - * Search for BGR values 0..255 and return color index - */ - private inxSearch(b: number, g: number, r: number): number { - // Biggest possible dist is 256*3 - let bestd = 1000; - let best = -1; - // Index on g - let i = this.netIndex[g]; - // Start at netindex[g] and work outwards - let j = i - 1; - - while (i < this.netSize || j >= 0) { - if (i < this.netSize) { - const p = i * 4; - let dist = this._colorMap32[p + 1] - g; - // Inx key - if (dist >= bestd) { - // Stop iter - i = this.netSize; - } else { - if (dist < 0) { - dist = -dist; - } - let a = this._colorMap32[p] - b; - if (a < 0) { - a = -a; - } - dist += a; - if (dist < bestd) { - a = this._colorMap32[p + 2] - r; - if (a < 0) { - a = -a; - } - dist += a; - if (dist < bestd) { - bestd = dist; - best = i; - } - } - i++; - } - } - - if (j >= 0) { - const p = j * 4; - // Inx key - reverse dif - let dist = g - this._colorMap32[p + 1]; - if (dist >= bestd) { - // Stop iter - j = -1; - } else { - if (dist < 0) { - dist = -dist; - } - let a = this._colorMap32[p] - b; - if (a < 0) { - a = -a; - } - dist += a; - if (dist < bestd) { - a = this._colorMap32[p + 2] - r; - if (a < 0) { - a = -a; - } - dist += a; - if (dist < bestd) { - bestd = dist; - best = j; - } - } - j--; - } - } - } - return best; - } - - /** - * Get a color from the **colorMap**. - */ - public color(index: number): number { - return Color.getColor( - this._colorMap8[index * 3], - this._colorMap8[index * 3 + 1], - this._colorMap8[index * 3 + 2] - ); - } - - /** - * Find the index of the closest color to **c** in the **colorMap**. - */ - public lookup(c: number): number { - const r = Color.getRed(c); - const g = Color.getGreen(c); - const b = Color.getBlue(c); - return this.inxSearch(b, g, r); - } - - /** - * Find the index of the closest color to **r**,**g**,**b** in the **colorMap**. - */ - public lookupRGB(r: number, g: number, b: number): number { - return this.inxSearch(b, g, r); - } - - /** - * Find the color closest to **c** in the **colorMap**. - */ - public getQuantizedColor(c: number): number { - const r = Color.getRed(c); - const g = Color.getGreen(c); - const b = Color.getBlue(c); - const a = Color.getAlpha(c); - const i = this.inxSearch(b, g, r) * 3; - return Color.getColor( - this._colorMap8[i], - this._colorMap8[i + 1], - this._colorMap8[i + 2], - a - ); - } - - /** - * Convert the **image** to an index map, mapping to this **colorMap**. - */ - public getIndexMap(image: MemoryImage): Uint8Array { - const map = new Uint8Array(image.width * image.height); - for (let i = 0, len = image.length; i < len; ++i) { - map[i] = this.lookup(image.getPixelByIndex(i)); - } - return map; - } -} diff --git a/src/common/output-buffer.ts b/src/common/output-buffer.ts index 0ec63e4..d89ea8c 100644 --- a/src/common/output-buffer.ts +++ b/src/common/output-buffer.ts @@ -10,7 +10,7 @@ export interface OutputBufferInitOptions { export class OutputBuffer { // 8k block-size - private static readonly BLOCK_SIZE = 0x2000; + private static readonly _blockSize = 0x2000; private _buffer: Uint8Array; public get buffer(): Uint8Array { @@ -36,9 +36,9 @@ export class OutputBuffer { /** * Create a byte buffer for writing. */ - constructor(options?: OutputBufferInitOptions) { - this._bigEndian = options?.bigEndian ?? false; - this._buffer = new Uint8Array(options?.size ?? OutputBuffer.BLOCK_SIZE); + constructor(opt?: OutputBufferInitOptions) { + this._bigEndian = opt?.bigEndian ?? false; + this._buffer = new Uint8Array(opt?.size ?? OutputBuffer._blockSize); this._length = 0; } @@ -46,14 +46,14 @@ export class OutputBuffer { * Grow the buffer to accommodate additional data. */ private expandBuffer(required?: number): void { - let blockSize: number = OutputBuffer.BLOCK_SIZE; + let blockSize: number = OutputBuffer._blockSize; if (required !== undefined) { blockSize = required; } else if (this._buffer.length > 0) { blockSize = this._buffer.length * 2; } const newBuffer = new Uint8Array(this._buffer.length + blockSize); - ArrayUtils.setRange(newBuffer, 0, this._buffer.length, this._buffer); + ArrayUtils.copyRange(this._buffer, 0, this._buffer.length, newBuffer, 0); this._buffer = newBuffer; } @@ -65,7 +65,7 @@ export class OutputBuffer { * Clear the buffer. */ public clear(): void { - this._buffer = new Uint8Array(OutputBuffer.BLOCK_SIZE); + this._buffer = new Uint8Array(OutputBuffer._blockSize); this._length = 0; } @@ -90,31 +90,28 @@ export class OutputBuffer { * Write a set of bytes to the end of the buffer. */ public writeBytes(bytes: Uint8Array, length?: number): void { - const correctedLength = length ?? bytes.length; - while (this._length + correctedLength > this._buffer.length) { - this.expandBuffer(this._length + correctedLength - this._buffer.length); + const bytesLength = length ?? bytes.length; + while (this._length + bytesLength > this._buffer.length) { + this.expandBuffer(this._length + bytesLength - this._buffer.length); } - ArrayUtils.setRange( - this._buffer, - this._length, - this._length + correctedLength, - bytes - ); - this._length += correctedLength; + ArrayUtils.copyRange(bytes, 0, bytesLength, this._buffer, this._length); + this._length += bytesLength; } public writeBuffer(bytes: InputBuffer): void { - while (length + bytes.length > this._buffer.length) { - this.expandBuffer(length + bytes.length - this._buffer.length); + const bytesLength = bytes.length; + const requiredLength = this._length + bytesLength; + while (requiredLength > this._buffer.length) { + this.expandBuffer(requiredLength - this._buffer.length); } - ArrayUtils.setRange( - this._buffer, - length, - length + bytes.length, + ArrayUtils.copyRange( bytes.buffer, - bytes.offset + bytes.offset, + bytesLength, + this._buffer, + this._length ); - this._length += bytes.length; + this._length += bytesLength; } /** @@ -196,7 +193,7 @@ export class OutputBuffer { } /** - * Return the subarray of the buffer in the range **start**:**end**. + * Return the subarray of the buffer in the range [**start**,**end**]. * If **start** or **end** are < 0 then it is relative to the end of the buffer. * If **end** is not specified (or undefined), then it is the end of the buffer. * This is equivalent to the python list range operator. diff --git a/src/common/point.ts b/src/common/point.ts index b959d88..770e628 100644 --- a/src/common/point.ts +++ b/src/common/point.ts @@ -34,9 +34,7 @@ export class Point { } public move(x: number, y: number): Point { - this._x = x; - this._y = y; - return this; + return new Point(x, y); } public offset(dx: number, dy: number): Point { @@ -48,12 +46,14 @@ export class Point { } public add(p: Point): Point { - return this.move(this._x + p.x, this._y + p.y); + return this.move(this._x + p._x, this._y + p._y); + } + + public equals(other: Point) { + return this._x === other._x && this._y === other._y; } - public equals(other: unknown) { - return ( - other instanceof Point && this._x === other._x && this._y === other._y - ); + public toString(): string { + return `${this.constructor.name} (x: ${this._x}, y: ${this._y})`; } } diff --git a/src/common/quantizer.ts b/src/common/quantizer.ts deleted file mode 100644 index 3f5244d..0000000 --- a/src/common/quantizer.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** @format */ - -export interface Quantizer { - /** - * Find the index of the closest color to **c** in the **colorMap**. - */ - getQuantizedColor(c: number): number; -} diff --git a/src/common/random-utils.ts b/src/common/random-utils.ts index 46faca5..ecd36e6 100644 --- a/src/common/random-utils.ts +++ b/src/common/random-utils.ts @@ -2,14 +2,14 @@ export abstract class RandomUtils { /** - * Return a random variable between [**-1**,**1**]. + * Return a random number between [-1, 1]. */ public static crand(): number { return 1 - 2 * Math.random(); } /** - * Return a random variable following a gaussian distribution and a standard + * Return a random number following a gaussian distribution and a standard * deviation of 1. */ public static grand(): number { @@ -41,4 +41,11 @@ export abstract class RandomUtils { } return k - 1; } + + /** + * Generates a non-negative random integer in the range from 0, inclusive, to **max**, exclusive. + */ + public static intrand(max: number) { + return Math.floor(Math.random() * max); + } } diff --git a/src/common/rational.ts b/src/common/rational.ts index d81b829..3c54547 100644 --- a/src/common/rational.ts +++ b/src/common/rational.ts @@ -1,6 +1,7 @@ /** @format */ -import { MathOperators } from '../common/math-operators'; +import { MathUtils } from './math-utils'; +import { StringUtils } from './string-utils'; export class Rational { private _numerator: number; @@ -13,13 +14,13 @@ export class Rational { return this._denominator; } - public get asInt(): number { + public get toInt(): number { return this.denominator !== 0 ? Math.trunc(this.numerator / this.denominator) : 0; } - public get asDouble(): number { + public get toDouble(): number { return this.denominator !== 0 ? this.numerator / this.denominator : 0; } @@ -29,22 +30,21 @@ export class Rational { } public simplify(): void { - const d = MathOperators.gcd(this.numerator, this.denominator); + const d = MathUtils.gcd(this.numerator, this.denominator); if (d !== 0) { this._numerator = Math.trunc(this.numerator / d); this._denominator = Math.trunc(this.denominator / d); } } - public equalsTo(other: unknown) { + public equals(other: Rational) { return ( - other instanceof Rational && this._numerator === other._numerator && this._denominator === other._denominator ); } public toString(): string { - return `${this._numerator}/${this._denominator}`; + return `${this.constructor.name} (${this._numerator}/${this._denominator})`; } } diff --git a/src/common/rectangle.ts b/src/common/rectangle.ts index d784377..875868e 100644 --- a/src/common/rectangle.ts +++ b/src/common/rectangle.ts @@ -3,12 +3,10 @@ import { Point } from './point'; export class Rectangle { - private _left = 0; - private _top = 0; - private _right = 0; - private _bottom = 0; - private _width = 0; - private _height = 0; + private readonly _left; + private readonly _top; + private readonly _right; + private readonly _bottom; public get left(): number { return this._left; @@ -27,31 +25,45 @@ export class Rectangle { } public get width(): number { - return this._width; + return this._right - this._left; } public get height(): number { - return this._height; + return this._bottom - this._top; } - constructor(x1: number, y1: number, x2: number, y2: number) { - this.initialize(x1, y1, x2, y2); + public get topLeft(): Point { + return new Point(this._left, this._top); } - public static fromXYWH(x: number, y: number, width: number, height: number) { - return new Rectangle(x, y, x + width, y + height); + public get topRight(): Point { + return new Point(this._right, this._top); } - public static from(other: Rectangle) { - return new Rectangle(other.left, other.top, other.right, other.bottom); + public get bottomLeft(): Point { + return new Point(this._left, this._bottom); } - private initialize(x1: number, y1: number, x2: number, y2: number) { + public get bottomRight(): Point { + return new Point(this._right, this._bottom); + } + + constructor(x1: number, y1: number, x2: number, y2: number) { this._left = Math.min(x1, x2); this._top = Math.min(y1, y2); this._right = Math.max(x1, x2); this._bottom = Math.max(y1, y2); - this._width = this._right - this._left; - this._height = this._bottom - this._top; + } + + public static fromXYWH(x: number, y: number, width: number, height: number) { + return new Rectangle(x, y, x + width, y + height); + } + + public static from(other: Rectangle) { + return new Rectangle(other._left, other._top, other._right, other._bottom); + } + + public toString(): string { + return `${this.constructor.name} (l: ${this._left}, t: ${this._top}, r: ${this._right}, b: ${this._bottom}, w: ${this.width}, h: ${this.height})`; } } diff --git a/src/common/rgb-channel-set.ts b/src/common/rgb-channel-set.ts deleted file mode 100644 index 6b525fe..0000000 --- a/src/common/rgb-channel-set.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** @format */ - -export enum RgbChannelSet { - rgb, - rgba, -} diff --git a/src/common/text-codec.ts b/src/common/string-utils.ts similarity index 78% rename from src/common/text-codec.ts rename to src/common/string-utils.ts index 58efef3..eea26a4 100644 --- a/src/common/text-codec.ts +++ b/src/common/string-utils.ts @@ -1,8 +1,8 @@ /** @format */ -import { ImageError } from '../error/image-error'; +import { LibError } from '../error/lib-error'; -export abstract class TextCodec { +export abstract class StringUtils { public static readonly utf8Decoder = new TextDecoder('utf8'); public static readonly latin1Decoder = new TextDecoder('latin1'); @@ -14,12 +14,12 @@ export abstract class TextCodec { if (0 <= codePoint && codePoint < 256) { array[i] = codePoint; } else { - throw new ImageError( + throw new LibError( `Error encoding text "${str}": unknown character code point ${codePoint}` ); } } else { - throw new ImageError(`Error encoding text "${str}"`); + throw new LibError(`Error encoding text "${str}"`); } } return array; diff --git a/src/draw/blend-mode.ts b/src/draw/blend-mode.ts new file mode 100644 index 0000000..bc7acfe --- /dev/null +++ b/src/draw/blend-mode.ts @@ -0,0 +1,19 @@ +/** @format */ + +export enum BlendMode { + direct, + alpha, + lighten, + screen, + dodge, + addition, + darken, + multiply, + burn, + overlay, + softLight, + hardLight, + difference, + subtract, + divide, +} diff --git a/src/draw/circle-quadrant.ts b/src/draw/circle-quadrant.ts new file mode 100644 index 0000000..7059e90 --- /dev/null +++ b/src/draw/circle-quadrant.ts @@ -0,0 +1,9 @@ +/** @format */ + +export enum CircleQuadrant { + topLeft = 1, + topRight = 2, + bottomLeft = 4, + bottomRight = 8, + all = topLeft | topRight | bottomLeft | bottomRight, +} diff --git a/src/draw/draw-image-options.ts b/src/draw/draw-image-options.ts deleted file mode 100644 index 5f5e262..0000000 --- a/src/draw/draw-image-options.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** @format */ - -import { MemoryImage } from '../common/memory-image'; - -export interface DrawImageOptions { - dst: MemoryImage; - src: MemoryImage; - dstX?: number; - dstY?: number; - dstW?: number; - dstH?: number; - srcX?: number; - srcY?: number; - srcW?: number; - srcH?: number; - blend?: boolean; -} diff --git a/src/draw/draw-line-options.ts b/src/draw/draw-line-options.ts deleted file mode 100644 index c63f914..0000000 --- a/src/draw/draw-line-options.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** @format */ - -import { Line } from '../common/line'; -import { MemoryImage } from '../common/memory-image'; - -export interface DrawLineOptions { - image: MemoryImage; - line: Line; - color: number; - antialias?: boolean; - thickness?: number; -} diff --git a/src/draw/draw.ts b/src/draw/draw.ts index 3a881ba..8a312bd 100644 --- a/src/draw/draw.ts +++ b/src/draw/draw.ts @@ -1,37 +1,165 @@ /** @format */ -import { Color } from '../common/color'; +import { Channel } from '../color/channel'; +import { Color } from '../color/color'; +import { ColorUtils } from '../color/color-utils'; +import { ArrayUtils } from '../common/array-utils'; import { Line } from '../common/line'; -import { MathOperators } from '../common/math-operators'; -import { MemoryImage } from '../common/memory-image'; +import { MathUtils } from '../common/math-utils'; import { Point } from '../common/point'; import { Rectangle } from '../common/rectangle'; -import { DrawImageOptions } from './draw-image-options'; -import { DrawLineOptions } from './draw-line-options'; -import { FillFloodOptions } from './fill-flood-options'; -import { MaskFloodOptions } from './mask-flood-options'; +import { MemoryImage } from '../image/image'; +import { ImageUtils } from '../image/image-utils'; +import { Pixel } from '../image/pixel'; +import { BlendMode } from './blend-mode'; +import { CircleQuadrant } from './circle-quadrant'; type FillFloodTestPixel = (y: number, x: number) => boolean; type FillFloodMarkPixel = (y: number, x: number) => void; -export abstract class Draw { - // 0000 - private static readonly OUTCODE_INSIDE = 0; - // 0001 - private static readonly OUTCODE_LEFT = 1; - // 0010 - private static readonly OUTCODE_RIGHT = 2; - // 0100 - private static readonly OUTCODE_BOTTOM = 4; - // 1000 - private static readonly OUTCODE_TOP = 8; +interface DrawLineWuOptions { + image: MemoryImage; + line: Line; + color: Color; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface DrawLineOptions extends DrawLineWuOptions { + antialias?: boolean; + thickness?: number; +} + +interface DrawAntialiasCircleOptions { + image: MemoryImage; + x: number; + y: number; + radius: number; + color: Color; + quadrants?: CircleQuadrant; + mask?: MemoryImage; + maskChannel?: Channel; +} + +export interface DrawCircleOptions { + image: MemoryImage; + center: Point; + radius: number; + color: Color; + antialias?: boolean; + mask?: MemoryImage; + maskChannel?: Channel; +} + +export interface DrawPixelOptions { + image: MemoryImage; + pos: Point; + color: Color; + filter?: Color; + alpha?: number; + blend?: BlendMode; + linearBlend?: boolean; + mask?: MemoryImage; + maskChannel?: Channel; +} + +export interface DrawPolygonOptions { + image: MemoryImage; + vertices: Point[]; + color: Color; + antialias?: boolean; + thickness?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface DrawRectOptions { + image: MemoryImage; + rect: Rectangle; + color: Color; + thickness?: number; + radius?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface FillCircleOptions { + image: MemoryImage; + center: Point; + radius: number; + color: Color; + antialias?: boolean; + maskChannel?: Channel; + mask?: MemoryImage; +} +export interface FillFloodOptions { + image: MemoryImage; + start: Point; + color: Color; + threshold?: number; + compareAlpha?: boolean; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface MaskFloodOptions { + image: MemoryImage; + start: Point; + threshold?: number; + compareAlpha?: boolean; + fillValue?: number; +} + +export interface FillPolygonOptions { + image: MemoryImage; + vertices: Point[]; + color: Color; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface FillRectOptions { + image: MemoryImage; + rect: Rectangle; + color: Color; + radius?: number; + mask?: MemoryImage; + maskChannel?: Channel; +} + +export interface FillOptions { + image: MemoryImage; + color: Color; + maskChannel?: Channel.luminance; + mask?: MemoryImage; +} + +export interface CompositeImageOptions { + dst: MemoryImage; + src: MemoryImage; + dstX?: number; + dstY?: number; + dstW?: number; + dstH?: number; + srcX?: number; + srcY?: number; + srcW?: number; + srcH?: number; + blend?: BlendMode; + linearBlend?: boolean; + center?: boolean; + mask?: MemoryImage; + maskChannel?: Channel; +} + +export abstract class Draw { /** * Calculate the pixels that make up the circumference of a circle on the * given **image**, centered at **center** and the given **radius**. * - * The returned list of points is sorted, first by the x coordinate, and - * second by the y coordinate. + * The returned array of points is sorted, first by the **center.x** coordinate, and + * second by the **center.y** coordinate. */ private static calculateCircumference( image: MemoryImage, @@ -104,115 +232,266 @@ export abstract class Draw { return points; } - /** - * Compute the bit code for a point **p** using the clip rectangle **rect** - */ - private static computeOutCode(rect: Rectangle, p: Point): number { - // initialized as being inside of clip window - let code = Draw.OUTCODE_INSIDE; - if (p.x < rect.left) { - // to the left of clip window - code |= Draw.OUTCODE_LEFT; - } else if (p.x > rect.right) { - // to the right of clip window - code |= Draw.OUTCODE_RIGHT; - } - - if (p.y < rect.top) { - // below the clip window - code |= Draw.OUTCODE_TOP; - } else if (p.y > rect.bottom) { - // above the clip window - code |= Draw.OUTCODE_BOTTOM; - } - - return code; + private static drawAntialiasCircle( + opt: DrawAntialiasCircleOptions + ): MemoryImage { + const drawPixel4 = ( + x: number, + y: number, + dx: number, + dy: number, + alpha: number + ): void => { + // bottom right + if ((quadrants & CircleQuadrant.bottomRight) !== 0) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(x + dx, y + dy), + color: opt.color, + alpha: alpha, + maskChannel: maskChannel, + mask: opt.mask, + }); + } + + // bottom left + if ((quadrants & CircleQuadrant.bottomLeft) !== 0) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(x - dx, y + dy), + color: opt.color, + alpha: alpha, + maskChannel: maskChannel, + mask: opt.mask, + }); + } + + // upper right + if ((quadrants & CircleQuadrant.topRight) !== 0) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(x + dx, y - dy), + color: opt.color, + alpha: alpha, + maskChannel: maskChannel, + mask: opt.mask, + }); + } + + // upper left + if ((quadrants & CircleQuadrant.topLeft) !== 0) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(x - dx, y - dy), + color: opt.color, + alpha: alpha, + maskChannel: maskChannel, + mask: opt.mask, + }); + } + }; + + const quadrants = opt.quadrants ?? CircleQuadrant.all; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + const radiusSqr = opt.radius * opt.radius; + const quarter = Math.round(opt.radius / Math.SQRT2); + for (let i = 0; i <= quarter; ++i) { + const j = Math.sqrt(radiusSqr - i * i); + const frc = MathUtils.fract(j); + const frc2 = frc * (i === quarter ? 0.25 : 1); + const flr = Math.floor(j); + drawPixel4(opt.x, opt.y, i, flr, 1 - frc); + drawPixel4(opt.x, opt.y, i, flr + 1, frc2); + drawPixel4(opt.x, opt.y, flr, i, 1 - frc); + drawPixel4(opt.x, opt.y, flr + 1, i, frc2); + } + + return opt.image; } - /** - * Clip a line to a rectangle using the Cohen–Sutherland clipping algorithm. - * **line** is a **Line** object. - * **rect** is a **Rectangle** object. - * Results are stored in **line**. - * If **line** falls completely outside of **rect**, false is returned, otherwise - * true is returned. - */ - private static clipLine(rect: Rectangle, line: Line): boolean { - const xmin = rect.left; - const ymin = rect.top; - const xmax = rect.right; - const ymax = rect.bottom; - - // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle - let outcode1 = Draw.computeOutCode( - rect, - new Point(line.startX, line.startY) - ); - let outcode2 = Draw.computeOutCode(rect, new Point(line.endX, line.endY)); - let accept = false; + // Xiaolin Wu's line algorithm, + // https://en.wikipedia.org/wiki/Xiaolin_Wu's_line_algorithm + private static drawLineWu(opt: DrawLineWuOptions): MemoryImage { + const line = opt.line.clone(); + const steep = Math.abs(line.dy) > Math.abs(line.dx); - while (true) { - if ((outcode1 | outcode2) === 0) { - // Bitwise OR is 0. Trivially accept and get out of loop - accept = true; - break; - } else if ((outcode1 & outcode2) !== 0) { - // Bitwise AND is not 0. Trivially reject and get out of loop - break; - } else { - // failed both tests, so calculate the line segment to clip - // from an outside point to an intersection with clip edge + if (steep) { + line.swapXY1(); + line.swapXY2(); + } + if (line.x1 > line.x2) { + line.flipX(); + line.flipY(); + } - // At least one endpoint is outside the clip rectangle; pick it. - const outcodeOut = outcode1 !== 0 ? outcode1 : outcode2; + const gradient = line.dx === 1 ? 1 : line.dy / line.dx; + + // handle first endpoint + let xend = Math.floor(line.x1 + 0.5); + let yend = line.y1 + gradient * (xend - line.x1); + let xgap = 1 - (line.x1 + 0.5 - Math.floor(line.x1 + 0.5)); + // this will be used in the main loop + const xpxl1 = xend; + const ypxl1 = Math.floor(yend); + + if (steep) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(ypxl1, xpxl1), + color: opt.color, + alpha: (1 - (yend - Math.floor(yend))) * xgap, + maskChannel: opt.maskChannel, + mask: opt.mask, + }); + Draw.drawPixel({ + image: opt.image, + pos: new Point(ypxl1 + 1, xpxl1), + color: opt.color, + alpha: (yend - Math.floor(yend)) * xgap, + maskChannel: opt.maskChannel, + mask: opt.mask, + }); + } else { + Draw.drawPixel({ + image: opt.image, + pos: new Point(xpxl1, ypxl1), + color: opt.color, + alpha: (1 - (yend - Math.floor(yend))) * xgap, + maskChannel: opt.maskChannel, + mask: opt.mask, + }); + Draw.drawPixel({ + image: opt.image, + pos: new Point(xpxl1, ypxl1 + 1), + color: opt.color, + alpha: (yend - Math.floor(yend)) * xgap, + maskChannel: opt.maskChannel, + mask: opt.mask, + }); + } - let x = 0; - let y = 0; + // first y-intersection for the main loop + let intery = yend + gradient; + + // handle second endpoint + xend = Math.floor(line.x2 + 0.5); + yend = line.y2 + gradient * (xend - line.x2); + xgap = line.x2 + 0.5 - Math.floor(line.x2 + 0.5); + + // this will be used in the main loop + const xpxl2 = xend; + const ypxl2 = Math.floor(yend); + + if (steep) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(ypxl2, xpxl2), + color: opt.color, + alpha: (1 - (yend - Math.floor(yend))) * xgap, + mask: opt.mask, + maskChannel: opt.maskChannel, + }); + Draw.drawPixel({ + image: opt.image, + pos: new Point(ypxl2 + 1, xpxl2), + color: opt.color, + alpha: (yend - Math.floor(yend)) * xgap, + maskChannel: opt.maskChannel, + mask: opt.mask, + }); - // Now find the intersection point; - // use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0) - if ((outcodeOut & Draw.OUTCODE_TOP) !== 0) { - // point is above the clip rectangle - x = - line.startX + - Math.trunc((line.dx * (ymin - line.startY)) / line.dy); - y = ymin; - } else if ((outcodeOut & Draw.OUTCODE_BOTTOM) !== 0) { - // point is below the clip rectangle - x = - line.startX + - Math.trunc((line.dx * (ymax - line.startY)) / line.dy); - y = ymax; - } else if ((outcodeOut & Draw.OUTCODE_RIGHT) !== 0) { - // point is to the right of clip rectangle - y = - line.startY + - Math.trunc((line.dy * (xmax - line.startX)) / line.dx); - x = xmax; - } else if ((outcodeOut & Draw.OUTCODE_LEFT) !== 0) { - // point is to the left of clip rectangle - y = - line.startY + - Math.trunc((line.dy * (xmin - line.startX)) / line.dx); - x = xmin; - } - - // Now we move outside point to intersection point to clip - // and get ready for next pass. - if (outcodeOut === outcode1) { - line.moveStart(x, y); - outcode1 = Draw.computeOutCode( - rect, - new Point(line.startX, line.startY) - ); - } else { - line.moveEnd(x, y); - outcode2 = Draw.computeOutCode(rect, new Point(line.endX, line.endY)); - } + // main loop + for (let x = xpxl1 + 1; x <= xpxl2 - 1; x++) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(Math.floor(intery), x), + color: opt.color, + alpha: 1 - (intery - Math.floor(intery)), + mask: opt.mask, + maskChannel: opt.maskChannel, + }); + Draw.drawPixel({ + image: opt.image, + pos: new Point(Math.floor(intery) + 1, x), + color: opt.color, + alpha: intery - Math.floor(intery), + maskChannel: opt.maskChannel, + mask: opt.mask, + }); + + intery += gradient; + } + } else { + Draw.drawPixel({ + image: opt.image, + pos: new Point(xpxl2, ypxl2), + color: opt.color, + alpha: (1 - (yend - Math.floor(yend))) * xgap, + maskChannel: opt.maskChannel, + mask: opt.mask, + }); + Draw.drawPixel({ + image: opt.image, + pos: new Point(xpxl2, ypxl2 + 1), + color: opt.color, + alpha: (yend - Math.floor(yend)) * xgap, + maskChannel: opt.maskChannel, + mask: opt.mask, + }); + + // main loop + for (let x = xpxl1 + 1; x <= xpxl2 - 1; x++) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(x, Math.floor(intery)), + color: opt.color, + alpha: 1 - (intery - Math.floor(intery)), + maskChannel: opt.maskChannel, + mask: opt.mask, + }); + Draw.drawPixel({ + image: opt.image, + pos: new Point(x, Math.floor(intery) + 1), + color: opt.color, + alpha: intery - Math.floor(intery), + maskChannel: opt.maskChannel, + mask: opt.mask, + }); + + intery += gradient; } } - return accept; + return opt.image; + } + + private static setAlpha(c: Color, a: number): Color { + c.a = a; + return c; + } + + /** + * Compare colors from a 3 or 4 dimensional color space + */ + private static colorDistance( + c1: number[], + c2: number[], + compareAlpha: boolean + ): number { + const d1 = c1[0] - c2[0]; + const d2 = c1[1] - c2[1]; + const d3 = c1[2] - c2[2]; + if (compareAlpha) { + const dA = c1[3] - c2[3]; + return Math.sqrt( + Math.max(d1 * d1, (d1 - dA) * (d1 - dA)) + + Math.max(d2 * d2, (d2 - dA) * (d2 - dA)) + + Math.max(d3 * d3, (d3 - dA) * (d3 - dA)) + ); + } else { + return Math.sqrt(d1 * d1 + d2 * d2 + d3 * d3); + } } private static testPixelLabColorDistance( @@ -224,55 +503,11 @@ export abstract class Draw { ): boolean { const pixel = src.getPixel(x, y); const compareAlpha = refColor.length > 3; - const pixelColor = Color.rgbToLab( - Color.getRed(pixel), - Color.getGreen(pixel), - Color.getBlue(pixel) - ); + const pixelColor = ColorUtils.rgbToLab(pixel.r, pixel.g, pixel.b); if (compareAlpha) { - pixelColor.push(Color.getAlpha(pixel)); + pixelColor.push(pixel.a); } - return Color.distance(pixelColor, refColor, compareAlpha) > threshold; - } - - /** - * Adam Milazzo (2015). A More Efficient Flood Fill. - * http://www.adammil.net/blog/v126_A_More_Efficient_Flood_Fill.html - */ - private static fill4( - src: MemoryImage, - x: number, - y: number, - array: FillFloodTestPixel, - mark: FillFloodMarkPixel, - visited: Uint8Array - ): void { - let _x = x; - let _y = y; - - if (visited[_y * src.width + _x] === 1) { - return; - } - - // at this point, we know array(y,x) is clear, and we want to move as far as - // possible to the upper-left. moving up is much more important than moving - // left, so we could try to make this smarter by sometimes moving to the - // right if doing so would allow us to move further up, but it doesn't seem - // worth the complexity - while (true) { - const ox = _x; - const oy = _y; - while (_y !== 0 && !array(_y - 1, _x)) { - _y--; - } - while (_x !== 0 && !array(_y, _x - 1)) { - _x--; - } - if (_x === ox && _y === oy) { - break; - } - } - Draw.fill4Core(src, _x, _y, array, mark, visited); + return Draw.colorDistance(pixelColor, refColor, compareAlpha) > threshold; } private static fill4Core( @@ -382,121 +617,199 @@ export abstract class Draw { } while (lastRowLength !== 0 && ++_y < src.height); } - /** - * Draw a circle into the **image** with a center of **center** and - * the given **radius** and **color**. - */ - public static drawCircle( - image: MemoryImage, - center: Point, - radius: number, - color: number - ): MemoryImage { - const points = Draw.calculateCircumference(image, center, radius); - for (const p of points) { - Draw.drawPixel(image, p, color); + // Adam Milazzo (2015). A More Efficient Flood Fill. + // http://www.adammil.net/blog/v126_A_More_Efficient_Flood_Fill.html + private static fill4( + src: MemoryImage, + x: number, + y: number, + array: FillFloodTestPixel, + mark: FillFloodMarkPixel, + visited: Uint8Array + ): void { + let _x = x; + let _y = y; + + if (visited[_y * src.width + _x] === 1) { + return; } - return image; - } - /** - * Draw and fill a circle into the **image** with a **center** - * and the given **radius** and **color**. - * - * The algorithm uses the same logic as **drawCircle** to calculate each point - * around the circle's circumference. Then it iterates through every point, - * finding the smallest and largest y-coordinate values for a given x- - * coordinate. - * - * Once found, it draws a line connecting those two points. The circle is thus - * filled one vertical slice at a time (each slice being 1-pixel wide). - */ - public static fillCircle( - image: MemoryImage, - center: Point, - radius: number, - color: number - ): MemoryImage { - const points = Draw.calculateCircumference(image, center, radius); - - // sort points by x-coordinate and then by y-coordinate - points.sort((a, b) => (a.x === b.x ? a.y - b.y : a.x - b.x)); - - if (points.length > 0) { - let start = points[0]; - let end = points[0]; - for (let i = 1; i < points.length; i++) { - const p = points[i]; - if (p.x === start.x) { - end = p; - } else { - Draw.drawLine({ - image: image, - line: new Line(start.xt, start.yt, end.xt, end.yt), - color: color, - }); - start = p; - end = p; - } + // at this point, we know array(y,x) is clear, and we want to move as far as + // possible to the upper-left. moving up is much more important than moving + // left, so we could try to make this smarter by sometimes moving to the + // right if doing so would allow us to move further up, but it doesn't seem + // worth the complexity + while (true) { + const ox = _x; + const oy = _y; + while (_y !== 0 && !array(_y - 1, _x)) { + _y--; + } + while (_x !== 0 && !array(_y, _x - 1)) { + _x--; + } + if (_x === ox && _y === oy) { + break; } - Draw.drawLine({ - image: image, - line: new Line(start.xt, start.yt, end.xt, end.yt), - color: color, - }); } - - return image; + Draw.fill4Core(src, _x, _y, array, mark, visited); } - /** - * Draw the image **src** onto the image **dst**. - * - * In other words, drawImage will take an rectangular area from **src** of - * width **srcW** and height **srcH** at position (**srcX**,**srY**) and place it - * in a rectangular area of **dst** of width **dstW** and height **dstH** at - * position (**dstX**,**dstY**). - * - * If the source and destination coordinates and width and heights differ, - * appropriate stretching or shrinking of the image fragment will be performed. - * The coordinates refer to the upper left corner. This function can be used to - * copy regions within the same image (if **dst** is the same as **src**) - * but if the regions overlap the results will be unpredictable. - */ - public static drawImage(options: DrawImageOptions): MemoryImage { - const dstX = options.dstX ?? 0; - const dstY = options.dstY ?? 0; - const srcX = options.srcX ?? 0; - const srcY = options.srcY ?? 0; - const srcW = options.srcW ?? options.src.width; - const srcH = options.srcH ?? options.src.height; - const dstW = options.dstW ?? Math.min(options.dst.width, options.src.width); - const dstH = - options.dstH ?? Math.min(options.dst.height, options.src.height); - const blend = options.blend ?? true; - - if (blend) { + private static imgDirectComposite( + src: MemoryImage, + dst: MemoryImage, + dstX: number, + dstY: number, + dstW: number, + dstH: number, + xCache: number[], + yCache: number[], + maskChannel: Channel, + mask?: MemoryImage + ): void { + let p: Pixel | undefined = undefined; + if (mask !== undefined) { for (let y = 0; y < dstH; ++y) { for (let x = 0; x < dstW; ++x) { - const stepX = Math.trunc(x * (srcW / dstW)); - const stepY = Math.trunc(y * (srcH / dstH)); - const srcPixel = options.src.getPixel(srcX + stepX, srcY + stepY); - const point = new Point(dstX + x, dstY + y); - Draw.drawPixel(options.dst, point, srcPixel); + const sx = xCache[x]; + const sy = yCache[y]; + p = src.getPixel(sx, sy, p); + const m = mask.getPixel(sx, sy).getChannelNormalized(maskChannel); + if (m === 1) { + dst.setPixel(dstX + x, dstY + y, p); + } else { + const dp = dst.getPixel(dstX + x, dstY + y); + dp.r = MathUtils.mix(dp.r, p.r, m); + dp.g = MathUtils.mix(dp.g, p.g, m); + dp.b = MathUtils.mix(dp.b, p.b, m); + dp.a = MathUtils.mix(dp.a, p.a, m); + } } } } else { for (let y = 0; y < dstH; ++y) { for (let x = 0; x < dstW; ++x) { - const stepX = Math.trunc(x * (srcW / dstW)); - const stepY = Math.trunc(y * (srcH / dstH)); - const srcPixel = options.src.getPixel(srcX + stepX, srcY + stepY); - options.dst.setPixel(dstX + x, dstY + y, srcPixel); + p = src.getPixel(xCache[x], yCache[y], p); + dst.setPixel(dstX + x, dstY + y, p); } } } + } - return options.dst; + private static imgComposite( + src: MemoryImage, + dst: MemoryImage, + dstX: number, + dstY: number, + dstW: number, + dstH: number, + xCache: number[], + yCache: number[], + blend: BlendMode, + linearBlend: boolean, + maskChannel: Channel, + mask?: MemoryImage + ): void { + let p: Pixel | undefined = undefined; + for (let y = 0; y < dstH; ++y) { + for (let x = 0; x < dstW; ++x) { + p = src.getPixel(xCache[x], yCache[y], p); + Draw.drawPixel({ + image: dst, + pos: new Point(dstX + x, dstY + y), + color: p, + blend: blend, + linearBlend: linearBlend, + maskChannel: maskChannel, + mask: mask, + }); + } + } + } + + /** + * Draw a circle into the **image** with a center of **center** and + * the given **radius** and **color**. + */ + public static drawCircle(opt: DrawCircleOptions): MemoryImage { + const antialias = opt.antialias ?? false; + const maskChannel = opt.maskChannel ?? Channel.luminance; + if (antialias) { + return Draw.drawAntialiasCircle({ + image: opt.image, + x: opt.center.x, + y: opt.center.y, + radius: opt.radius, + color: opt.color, + mask: opt.mask, + maskChannel: maskChannel, + }); + } + + const points = Draw.calculateCircumference( + opt.image, + opt.center, + opt.radius + ); + for (const pt of points) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(pt.x, pt.y), + color: opt.color, + mask: opt.mask, + maskChannel: maskChannel, + }); + } + return opt.image; + } + + /** + * Draw and fill a circle into the **image** with a **center** + * and the given **radius** and **color**. + */ + public static fillCircle(opt: FillCircleOptions): MemoryImage { + const antialias = opt.antialias ?? false; + const maskChannel = opt.maskChannel ?? Channel.luminance; + const radiusSqr = opt.radius * opt.radius; + const x1 = Math.max(0, opt.center.x - opt.radius); + const y1 = Math.max(0, opt.center.y - opt.radius); + const x2 = Math.min(opt.image.width - 1, opt.center.x + opt.radius); + const y2 = Math.min(opt.image.height - 1, opt.center.y + opt.radius); + const range = opt.image.getRange(x1, y1, x2 - x1 + 1, y2 - y1 + 1); + + let it: IteratorResult | undefined = undefined; + while (((it = range.next()), !it.done)) { + const p = it.value; + if (antialias) { + const a = ImageUtils.circleTest(p, opt.center, radiusSqr, antialias); + if (a > 0) { + const alpha = opt.color.aNormalized * a; + Draw.drawPixel({ + image: opt.image, + pos: new Point(p.x, p.y), + color: opt.color, + alpha: alpha, + maskChannel: maskChannel, + mask: opt.mask, + }); + } + } else { + const dx = p.x - opt.center.x; + const dy = p.y - opt.center.y; + const d2 = dx * dx + dy * dy; + if (d2 < radiusSqr) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(p.x, p.y), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); + } + } + } + + return opt.image; } /** @@ -505,73 +818,152 @@ export abstract class Draw { * If **antialias** is true then the line is drawn with smooth edges. * **thickness** determines how thick the line should be drawn, in pixels. */ - public static drawLine(options: DrawLineOptions): MemoryImage { - const line = Line.from(options.line); - const isClipped = Draw.clipLine( - new Rectangle(0, 0, options.image.width - 1, options.image.height - 1), - line - ); - if (!isClipped) { - return options.image; - } + public static drawLine(opt: DrawLineOptions): MemoryImage { + const line = opt.line.clone(); + const antialias = opt.antialias ?? false; + const thickness = opt.thickness ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; - const thickness = options.thickness ?? 1; + if ( + !ImageUtils.clipLine( + new Rectangle(0, 0, opt.image.width - 1, opt.image.height - 1), + line + ) + ) { + return opt.image; + } const radius = Math.floor(thickness / 2); // Drawing a single point. if (line.dx === 0 && line.dy === 0) { - thickness === 1 - ? Draw.drawPixel( - options.image, - new Point(line.startX, line.startY), - options.color - ) - : Draw.fillCircle( - options.image, - new Point(line.startX, line.startY), - radius, - options.color - ); - return options.image; + opt.thickness === 1 + ? Draw.drawPixel({ + image: opt.image, + pos: new Point(line.x1, line.y1), + color: opt.color, + maskChannel: opt.maskChannel, + mask: opt.mask, + }) + : Draw.fillCircle({ + image: opt.image, + center: new Point(line.x1, line.y1), + radius: radius, + color: opt.color, + maskChannel: opt.maskChannel, + mask: opt.mask, + }); + return opt.image; } // Axis-aligned lines if (line.dx === 0) { - for (let y = line.startY; y <= line.endY; ++y) { - if (thickness <= 1) { - const point = new Point(line.startX, y); - Draw.drawPixel(options.image, point, options.color); - } else { - for (let i = 0; i < thickness; i++) { - const point = new Point(line.startX - radius + i, y); - Draw.drawPixel(options.image, point, options.color); + if (line.dy < 0) { + for (let y = line.y2; y <= line.y1; ++y) { + if (thickness <= 1) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(line.x1, y), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); + } else { + for (let i = 0; i < thickness; i++) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(line.x1 - radius + i, y), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); + } + } + } + } else { + for (let y = line.y1; y <= line.y2; ++y) { + if (thickness <= 1) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(line.x1, y), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); + } else { + for (let i = 0; i < thickness; i++) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(line.x1 - radius + i, y), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); + } } } } - return options.image; + return opt.image; } else if (line.dy === 0) { - for (let x = line.startX; x <= line.endX; ++x) { - if (thickness <= 1) { - const point = new Point(x, line.startY); - Draw.drawPixel(options.image, point, options.color); - } else { - for (let i = 0; i < thickness; i++) { - const point = new Point(x, line.startY - radius + i); - Draw.drawPixel(options.image, point, options.color); + if (line.dx < 0) { + for (let x = line.x2; x <= line.x1; ++x) { + if (thickness <= 1) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(x, line.y1), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); + } else { + for (let i = 0; i < thickness; i++) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(x, line.y1 - radius + i), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); + } + } + } + } else { + for (let x = line.x1; x <= line.x2; ++x) { + if (thickness <= 1) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(x, line.y1), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); + } else { + for (let i = 0; i < thickness; i++) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(x, line.y1 - radius + i), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); + } } } } - return options.image; + return opt.image; } - // 16-bit xor - const xor = (n: number) => (~n + 0x10000) & 0xffff; + // 16-bit unsigned int xor. + const xor = (n: number): number => { + return (~n + 0x10000) & 0xffff; + }; - if (!options.antialias) { - if (line.dy <= line.dx) { + if (!antialias) { + const dx = Math.abs(line.dx); + const dy = Math.abs(line.dy); + if (dy <= dx) { // More-or-less horizontal. use wid for vertical stroke - const ac = Math.cos(Math.atan2(line.dy, line.dx)); + const ac = Math.cos(Math.atan2(dy, dx)); let wid = 0; if (ac !== 0) { wid = Math.trunc(thickness / ac); @@ -583,22 +975,40 @@ export abstract class Draw { wid = 1; } - let d = 2 * line.dy - line.dx; - const incr1 = 2 * line.dy; - const incr2 = 2 * (line.dy - line.dx); + let d = 2 * dy - dx; + const incr1 = 2 * dy; + const incr2 = 2 * (dy - dx); - let x = line.startX; - let y = line.startY; + let x = 0; + let y = 0; + let ydirflag = 0; + let xend = 0; + if (line.x1 > line.x2) { + x = line.x2; + y = line.y2; + ydirflag = -1; + xend = line.x1; + } else { + x = line.x1; + y = line.y1; + ydirflag = 1; + xend = line.x2; + } // Set up line thickness let wstart = Math.trunc(y - wid / 2); for (let w = wstart; w < wstart + wid; w++) { - const point = new Point(x, w); - Draw.drawPixel(options.image, point, options.color); + Draw.drawPixel({ + image: opt.image, + pos: new Point(x, w), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); } - if (line.dy > 0) { - while (x < line.endX) { + if ((line.y2 - line.y1) * ydirflag > 0) { + while (x < xend) { x++; if (d < 0) { d += incr1; @@ -608,12 +1018,17 @@ export abstract class Draw { } wstart = Math.trunc(y - wid / 2); for (let w = wstart; w < wstart + wid; w++) { - const point = new Point(x, w); - Draw.drawPixel(options.image, point, options.color); + Draw.drawPixel({ + image: opt.image, + pos: new Point(x, w), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); } } } else { - while (x < line.endX) { + while (x < xend) { x++; if (d < 0) { d += incr1; @@ -623,14 +1038,19 @@ export abstract class Draw { } wstart = Math.trunc(y - wid / 2); for (let w = wstart; w < wstart + wid; w++) { - const point = new Point(x, w); - Draw.drawPixel(options.image, point, options.color); + Draw.drawPixel({ + image: opt.image, + pos: new Point(x, w), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); } } } } else { // More-or-less vertical. use wid for horizontal stroke - const as = Math.sin(Math.atan2(line.dy, line.dx)); + const as = Math.sin(Math.atan2(dy, dx)); let wid = 0; if (as !== 0) { wid = Math.trunc(thickness / as); @@ -641,22 +1061,39 @@ export abstract class Draw { wid = 1; } - let d = 2 * line.dx - line.dy; - const incr1 = 2 * line.dx; - const incr2 = 2 * (line.dx - line.dy); - - let x = line.startX; - let y = line.startY; + let d = 2 * dx - dy; + const incr1 = 2 * dx; + const incr2 = 2 * (dx - dy); + let x = 0; + let y = 0; + let yend = 0; + let xdirflag = 0; + if (line.y1 > line.y2) { + y = line.y2; + x = line.x2; + yend = line.y1; + xdirflag = -1; + } else { + y = line.y1; + x = line.x1; + yend = line.y2; + xdirflag = 1; + } // Set up line thickness let wstart = Math.trunc(x - wid / 2); for (let w = wstart; w < wstart + wid; w++) { - const point = new Point(w, y); - Draw.drawPixel(options.image, point, options.color); + Draw.drawPixel({ + image: opt.image, + pos: new Point(w, y), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); } - if (line.endX - line.startX > 0) { - while (y < line.endY) { + if ((line.x2 - line.x1) * xdirflag > 0) { + while (y < yend) { y++; if (d < 0) { d += incr1; @@ -666,12 +1103,17 @@ export abstract class Draw { } wstart = Math.trunc(x - wid / 2); for (let w = wstart; w < wstart + wid; w++) { - const point = new Point(w, y); - Draw.drawPixel(options.image, point, options.color); + Draw.drawPixel({ + image: opt.image, + pos: new Point(w, y), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); } } } else { - while (y < line.endY) { + while (y < yend) { y++; if (d < 0) { d += incr1; @@ -681,25 +1123,37 @@ export abstract class Draw { } wstart = Math.trunc(x - wid / 2); for (let w = wstart; w < wstart + wid; w++) { - const point = new Point(w, y); - Draw.drawPixel(options.image, point, options.color); + Draw.drawPixel({ + image: opt.image, + pos: new Point(w, y), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); } } } } - return options.image; + return opt.image; } // Antialias Line + if (thickness === 1) { + return Draw.drawLineWu({ + image: opt.image, + line: new Line(line.x1, line.y1, line.x2, line.y2), + color: opt.color, + }); + } const ag = - line.dy < line.dx + Math.abs(line.dy) < Math.abs(line.dx) ? Math.cos(Math.atan2(line.dy, line.dx)) : Math.sin(Math.atan2(line.dy, line.dx)); let wid = 0; - if (ag !== 0) { + if (ag !== 0.0) { wid = Math.trunc(Math.abs(thickness / ag)); } else { wid = 1; @@ -708,28 +1162,36 @@ export abstract class Draw { wid = 1; } - if (line.dx > line.dy) { - let y = line.startY; + if (Math.abs(line.dx) > Math.abs(line.dy)) { + if (line.dx < 0) { + line.flipX(); + line.flipY(); + } + + let y = line.y1; const inc = Math.trunc((line.dy * 65536) / line.dx); let frac = 0; - for (let x = line.startX; x <= line.endX; x++) { + for (let x = line.x1; x <= line.x2; x++) { const wstart = y - Math.trunc(wid / 2); for (let w = wstart; w < wstart + wid; w++) { - const point = new Point(x, w); - Draw.drawPixel( - options.image, - point, - options.color, - (frac >> 8) & 0xff - ); - point.offset(0, 1); - Draw.drawPixel( - options.image, - point, - options.color, - (xor(frac) >> 8) & 0xff - ); + Draw.drawPixel({ + image: opt.image, + pos: new Point(x, w), + color: opt.color, + alpha: ((frac >> 8) & 0xff) / 255, + maskChannel: maskChannel, + mask: opt.mask, + }); + + Draw.drawPixel({ + image: opt.image, + pos: new Point(x, w + 1), + color: opt.color, + alpha: ((xor(frac) >> 8) & 0xff) / 255, + maskChannel: maskChannel, + mask: opt.mask, + }); } frac += inc; @@ -742,27 +1204,35 @@ export abstract class Draw { } } } else { - let x = line.startX; + if (line.dy < 0) { + line.flipX(); + line.flipY(); + } + + let x = line.x1; const inc = Math.trunc((line.dx * 65536) / line.dy); let frac = 0; - for (let y = line.startY; y <= line.endY; y++) { + for (let y = line.y1; y <= line.y2; y++) { const wstart = x - Math.trunc(wid / 2); for (let w = wstart; w < wstart + wid; w++) { - const point = new Point(w, y); - Draw.drawPixel( - options.image, - point, - options.color, - (frac >> 8) & 0xff - ); - point.offset(1, 0); - Draw.drawPixel( - options.image, - point, - options.color, - (xor(frac) >> 8) & 0xff - ); + Draw.drawPixel({ + image: opt.image, + pos: new Point(w, y), + color: opt.color, + alpha: ((frac >> 8) & 0xff) / 255, + maskChannel: maskChannel, + mask: opt.mask, + }); + + Draw.drawPixel({ + image: opt.image, + pos: new Point(w + 1, y), + color: opt.color, + alpha: ((xor(frac) >> 8) & 0xff) / 255, + maskChannel: maskChannel, + mask: opt.mask, + }); } frac += inc; @@ -776,200 +1246,1023 @@ export abstract class Draw { } } - return options.image; + return opt.image; } /** * Draw a single pixel into the image, applying alpha and opacity blending. + * If **filter** is provided, the color c will be scaled by the **filter** + * color. If **alpha** is provided, it will be used in place of the + * color alpha, as a normalized color value [0, 1]. */ - public static drawPixel( - image: MemoryImage, - pos: Point, - color: number, - opacity = 0xff - ): MemoryImage { - if (image.boundsSafe(pos.xt, pos.yt)) { - const index = image.getBufferIndex(pos.xt, pos.yt); - const dst = image.getPixelByIndex(index); - image.setPixelByIndex(index, Color.alphaBlendColors(dst, color, opacity)); + public static drawPixel(opt: DrawPixelOptions): MemoryImage { + const blend = opt.blend ?? BlendMode.alpha; + const linearBlend = opt.linearBlend ?? false; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (!opt.image.isBoundsSafe(opt.pos.x, opt.pos.y)) { + return opt.image; + } + + if (blend === BlendMode.direct || opt.image.hasPalette) { + if (opt.image.isBoundsSafe(opt.pos.x, opt.pos.y)) { + opt.image.getPixel(opt.pos.x, opt.pos.y).set(opt.color); + return opt.image; + } + } + + const msk = + opt.mask + ?.getPixel(opt.pos.x, opt.pos.y) + .getChannelNormalized(maskChannel) ?? 1; + + let overlayR = + opt.filter !== undefined + ? opt.color.rNormalized * opt.filter.rNormalized + : opt.color.rNormalized; + let overlayG = + opt.filter !== undefined + ? opt.color.gNormalized * opt.filter.gNormalized + : opt.color.gNormalized; + let overlayB = + opt.filter !== undefined + ? opt.color.bNormalized * opt.filter.bNormalized + : opt.color.bNormalized; + + const overlayA = + (opt.alpha ?? (opt.color.length < 4 ? 1 : opt.color.aNormalized)) * msk; + + if (overlayA === 0) { + return opt.image; + } + + const dst = opt.image.getPixel(opt.pos.x, opt.pos.y); + + const baseR = dst.rNormalized; + const baseG = dst.gNormalized; + const baseB = dst.bNormalized; + const baseA = dst.aNormalized; + + switch (blend) { + case BlendMode.direct: + return opt.image; + case BlendMode.alpha: + break; + case BlendMode.lighten: + overlayR = Math.max(baseR, overlayR); + overlayG = Math.max(baseG, overlayG); + overlayB = Math.max(baseB, overlayB); + break; + case BlendMode.screen: + overlayR = 1 - (1 - overlayR) * (1 - baseR); + overlayG = 1 - (1 - overlayG) * (1 - baseG); + overlayB = 1 - (1 - overlayB) * (1 - baseB); + break; + case BlendMode.dodge: + { + const baseOverlayAlphaProduct = overlayA * baseA; + + const rightHandProductR = + overlayR * (1 - baseA) + baseR * (1 - overlayA); + const rightHandProductG = + overlayG * (1 - baseA) + baseG * (1 - overlayA); + const rightHandProductB = + overlayB * (1 - baseA) + baseB * (1 - overlayA); + + const firstBlendColorR = baseOverlayAlphaProduct + rightHandProductR; + const firstBlendColorG = baseOverlayAlphaProduct + rightHandProductG; + const firstBlendColorB = baseOverlayAlphaProduct + rightHandProductB; + + const oR = MathUtils.clamp( + (overlayR / MathUtils.clamp(overlayA, 0.01, 1)) * + MathUtils.step(0, overlayA), + 0, + 0.99 + ); + const oG = MathUtils.clamp( + (overlayG / MathUtils.clamp(overlayA, 0.01, 1)) * + MathUtils.step(0, overlayA), + 0, + 0.99 + ); + const oB = MathUtils.clamp( + (overlayB / MathUtils.clamp(overlayA, 0.01, 1)) * + MathUtils.step(0, overlayA), + 0, + 0.99 + ); + + const secondBlendColorR = + (baseR * overlayA) / (1 - oR) + rightHandProductR; + const secondBlendColorG = + (baseG * overlayA) / (1 - oG) + rightHandProductG; + const secondBlendColorB = + (baseB * overlayA) / (1 - oB) + rightHandProductB; + + const colorChoiceR = MathUtils.step( + overlayR * baseA + baseR * overlayA, + baseOverlayAlphaProduct + ); + const colorChoiceG = MathUtils.step( + overlayG * baseA + baseG * overlayA, + baseOverlayAlphaProduct + ); + const colorChoiceB = MathUtils.step( + overlayB * baseA + baseB * overlayA, + baseOverlayAlphaProduct + ); + + overlayR = MathUtils.mix( + firstBlendColorR, + secondBlendColorR, + colorChoiceR + ); + overlayG = MathUtils.mix( + firstBlendColorG, + secondBlendColorG, + colorChoiceG + ); + overlayB = MathUtils.mix( + firstBlendColorB, + secondBlendColorB, + colorChoiceB + ); + } + break; + case BlendMode.addition: + overlayR = baseR + overlayR; + overlayG = baseG + overlayG; + overlayB = baseB + overlayB; + break; + case BlendMode.darken: + overlayR = Math.min(baseR, overlayR); + overlayG = Math.min(baseG, overlayG); + overlayB = Math.min(baseB, overlayB); + break; + case BlendMode.multiply: + overlayR *= baseR; + overlayG *= baseG; + overlayB *= baseB; + break; + case BlendMode.burn: + overlayR = overlayR !== 0 ? 1 - (1 - baseR) / overlayR : 0; + overlayG = overlayG !== 0 ? 1 - (1 - baseG) / overlayG : 0; + overlayB = overlayB !== 0 ? 1 - (1 - baseB) / overlayB : 0; + break; + case BlendMode.overlay: + if (2 * baseR < baseA) { + overlayR = + 2 * overlayR * baseR + + overlayR * (1 - baseA) + + baseR * (1 - overlayA); + } else { + overlayR = + overlayA * baseA - + 2 * (baseA - baseR) * (overlayA - overlayR) + + overlayR * (1 - baseA) + + baseR * (1 - overlayA); + } + + if (2 * baseG < baseA) { + overlayG = + 2 * overlayG * baseG + + overlayG * (1 - baseA) + + baseG * (1 - overlayA); + } else { + overlayG = + overlayA * baseA - + 2 * (baseA - baseG) * (overlayA - overlayG) + + overlayG * (1 - baseA) + + baseG * (1 - overlayA); + } + + if (2 * baseB < baseA) { + overlayB = + 2 * overlayB * baseB + + overlayB * (1 - baseA) + + baseB * (1 - overlayA); + } else { + overlayB = + overlayA * baseA - + 2 * (baseA - baseB) * (overlayA - overlayB) + + overlayB * (1 - baseA) + + baseB * (1 - overlayA); + } + break; + case BlendMode.softLight: + overlayR = + baseA === 0 + ? 0 + : baseR * + (overlayA * (baseR / baseA) + + 2 * overlayR * (1 - baseR / baseA)) + + overlayR * (1 - baseA) + + baseR * (1 - overlayA); + + overlayG = + baseA === 0 + ? 0 + : baseG * + (overlayA * (baseG / baseA) + + 2 * overlayG * (1 - baseG / baseA)) + + overlayG * (1 - baseA) + + baseG * (1 - overlayA); + + overlayB = + baseA === 0 + ? 0 + : baseB * + (overlayA * (baseB / baseA) + + 2 * overlayB * (1 - baseB / baseA)) + + overlayB * (1 - baseA) + + baseB * (1 - overlayA); + break; + case BlendMode.hardLight: + if (2 * overlayR < overlayA) { + overlayR = + 2 * overlayR * baseR + + overlayR * (1 - baseA) + + baseR * (1 - overlayA); + } else { + overlayR = + overlayA * baseA - + 2 * (baseA - baseR) * (overlayA - overlayR) + + overlayR * (1 - baseA) + + baseR * (1 - overlayA); + } + + if (2 * overlayG < overlayA) { + overlayG = + 2 * overlayG * baseG + + overlayG * (1 - baseA) + + baseG * (1 - overlayA); + } else { + overlayG = + overlayA * baseA - + 2 * (baseA - baseG) * (overlayA - overlayG) + + overlayG * (1 - baseA) + + baseG * (1 - overlayA); + } + + if (2 * overlayB < overlayA) { + overlayB = + 2 * overlayB * baseB + + overlayB * (1 - baseA) + + baseB * (1 - overlayA); + } else { + overlayB = + overlayA * baseA - + 2 * (baseA - baseB) * (overlayA - overlayB) + + overlayB * (1 - baseA) + + baseB * (1 - overlayA); + } + break; + case BlendMode.difference: + overlayR = Math.abs(overlayR - baseR); + overlayG = Math.abs(overlayG - baseG); + overlayB = Math.abs(overlayB - baseB); + break; + case BlendMode.subtract: + overlayR = baseR - overlayR; + overlayG = baseG - overlayG; + overlayB = baseB - overlayB; + break; + case BlendMode.divide: + overlayR = overlayR !== 0 ? baseR / overlayR : 0; + overlayG = overlayG !== 0 ? baseG / overlayG : 0; + overlayB = overlayB !== 0 ? baseB / overlayB : 0; + break; + } + + const invA = 1 - overlayA; + + if (linearBlend) { + const lbr = Math.pow(baseR, 2.2); + const lbg = Math.pow(baseG, 2.2); + const lbb = Math.pow(baseB, 2.2); + const lor = Math.pow(overlayR, 2.2); + const log = Math.pow(overlayG, 2.2); + const lob = Math.pow(overlayB, 2.2); + const r = Math.pow(lor * overlayA + lbr * baseA * invA, 1 / 2.2); + const g = Math.pow(log * overlayA + lbg * baseA * invA, 1 / 2.2); + const b = Math.pow(lob * overlayA + lbb * baseA * invA, 1 / 2.2); + const a = overlayA + baseA * invA; + dst.rNormalized = r; + dst.gNormalized = g; + dst.bNormalized = b; + dst.aNormalized = a; + } else { + const r = overlayR * overlayA + baseR * baseA * invA; + const g = overlayG * overlayA + baseG * baseA * invA; + const b = overlayB * overlayA + baseB * baseA * invA; + const a = overlayA + baseA * invA; + dst.rNormalized = r; + dst.gNormalized = g; + dst.bNormalized = b; + dst.aNormalized = a; } - return image; + + return opt.image; } /** - * Draw a rectangle in the image **dst** with the **color**. + * Fill a polygon defined by the given **vertices**. */ - public static drawRect( - dst: MemoryImage, - rect: Rectangle, - color: number - ): MemoryImage { + public static drawPolygon(opt: DrawPolygonOptions): MemoryImage { + const antialias = opt.antialias ?? false; + const thickness = opt.thickness ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (opt.color.a === 0) { + return opt.image; + } + + const vertices = opt.vertices; + const numVertices = vertices.length; + + if (numVertices === 0) { + return opt.image; + } + + if (numVertices === 1) { + return Draw.drawPixel({ + image: opt.image, + pos: vertices[0], + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); + } + + if (numVertices === 2) { + return Draw.drawLine({ + image: opt.image, + line: new Line( + vertices[0].x, + vertices[0].y, + vertices[1].x, + vertices[1].y + ), + color: opt.color, + antialias: antialias, + thickness: thickness, + maskChannel: maskChannel, + mask: opt.mask, + }); + } + + for (let i = 0; i < numVertices - 1; ++i) { + Draw.drawLine({ + image: opt.image, + line: new Line( + vertices[i].x, + vertices[i].y, + vertices[i + 1].x, + vertices[i + 1].y + ), + color: opt.color, + antialias: antialias, + thickness: thickness, + maskChannel: maskChannel, + mask: opt.mask, + }); + } + + Draw.drawLine({ + image: opt.image, + line: new Line( + vertices[numVertices - 1].x, + vertices[numVertices - 1].y, + vertices[0].x, + vertices[0].y + ), + color: opt.color, + antialias: antialias, + thickness: thickness, + maskChannel: maskChannel, + mask: opt.mask, + }); + + return opt.image; + } + + /** + * Draw a rectangle in the **image** with the **color**. + */ + public static drawRect(opt: DrawRectOptions): MemoryImage { + const rect = opt.rect; + const thickness = opt.thickness ?? 1; + const radius = opt.radius ?? 0; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + const x0 = rect.left; + const y0 = rect.top; + const x1 = rect.right; + const y1 = rect.bottom; + + // Draw a rounded rectangle + if (radius > 0) { + const rad = Math.round(radius); + Draw.drawLine({ + image: opt.image, + line: new Line(x0 + rad, y0, x1 - rad, y0), + color: opt.color, + }); + Draw.drawLine({ + image: opt.image, + line: new Line(x1, y0 + rad, x1, y1 - rad), + color: opt.color, + }); + Draw.drawLine({ + image: opt.image, + line: new Line(x0 + rad, y1, x1 - rad, y1), + color: opt.color, + }); + Draw.drawLine({ + image: opt.image, + line: new Line(x0, y0 + rad, x0, y1 - rad), + color: opt.color, + }); + + const c1x = x0 + rad; + const c1y = y0 + rad; + const c2x = x1 - rad; + const c2y = y0 + rad; + const c3x = x1 - rad; + const c3y = y1 - rad; + const c4x = x0 + rad; + const c4y = y1 - rad; + + Draw.drawAntialiasCircle({ + image: opt.image, + x: c1x, + y: c1y, + radius: rad, + color: opt.color, + maskChannel: maskChannel, + quadrants: CircleQuadrant.topLeft, + mask: opt.mask, + }); + + Draw.drawAntialiasCircle({ + image: opt.image, + x: c2x, + y: c2y, + radius: rad, + color: opt.color, + maskChannel: maskChannel, + quadrants: CircleQuadrant.topRight, + mask: opt.mask, + }); + + Draw.drawAntialiasCircle({ + image: opt.image, + x: c3x, + y: c3y, + radius: rad, + color: opt.color, + maskChannel: maskChannel, + quadrants: CircleQuadrant.bottomRight, + mask: opt.mask, + }); + + Draw.drawAntialiasCircle({ + image: opt.image, + x: c4x, + y: c4y, + radius: rad, + color: opt.color, + maskChannel: maskChannel, + quadrants: CircleQuadrant.bottomLeft, + mask: opt.mask, + }); + + return opt.image; + } + + const ht = thickness / 2; + Draw.drawLine({ - image: dst, - line: new Line(rect.left, rect.top, rect.right, rect.top), - color: color, + image: opt.image, + line: new Line(x0, y0, x1, y0), + color: opt.color, + thickness: thickness, + maskChannel: maskChannel, + mask: opt.mask, }); + Draw.drawLine({ - image: dst, - line: new Line(rect.right, rect.top, rect.right, rect.bottom), - color: color, + image: opt.image, + line: new Line(x0, y1, x1, y1), + color: opt.color, + thickness: thickness, + maskChannel: maskChannel, + mask: opt.mask, }); + + const isEvenThickness = ht - Math.trunc(ht) === 0; + const dh = isEvenThickness ? 1 : 0; + + const by0 = Math.ceil(y0 + ht); + const by1 = Math.floor(y1 - ht - dh); + const bx0 = Math.floor(x0 + ht); + const bx1 = Math.ceil(x1 - ht + dh); + Draw.drawLine({ - image: dst, - line: new Line(rect.right, rect.bottom, rect.left, rect.bottom), - color: color, + image: opt.image, + line: new Line(bx0, by0, bx0, by1), + color: opt.color, + thickness: thickness, + maskChannel: maskChannel, + mask: opt.mask, }); + Draw.drawLine({ - image: dst, - line: new Line(rect.left, rect.bottom, rect.left, rect.top), - color: color, + image: opt.image, + line: new Line(bx1, by0, bx1, by1), + color: opt.color, + thickness: thickness, + maskChannel: maskChannel, + mask: opt.mask, }); - return dst; + + return opt.image; } /** - * Fill the 4-connected shape containing **x**,**y** in the image **src** with the + * Fill the 4-connected shape containing **start** in the **image** with the * given **color**. */ - public static fillFlood(options: FillFloodOptions): MemoryImage { - const threshold = options.threshold ?? 0; - const compareAlpha = options.compareAlpha ?? false; + public static fillFlood(opt: FillFloodOptions): MemoryImage { + const threshold = opt.threshold ?? 0; + const compareAlpha = opt.compareAlpha ?? false; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (opt.color.a === 0) { + return opt.image; + } - const visited = new Uint8Array(options.src.width * options.src.height); + const visited = new Uint8Array(opt.image.width * opt.image.height); - let srcColor = options.src.getPixel(options.x, options.y); + const srcColor = opt.image.getPixel(opt.start.x, opt.start.y); if (!compareAlpha) { - srcColor = Color.setAlpha(srcColor, 0); + opt.color.a = 0; } let array: FillFloodTestPixel | undefined = undefined; if (threshold > 0) { - const lab = Color.rgbToLab( - Color.getRed(srcColor), - Color.getGreen(srcColor), - Color.getBlue(srcColor) - ); + const lab = ColorUtils.rgbToLab(srcColor.r, srcColor.g, srcColor.b); if (compareAlpha) { - lab.push(Color.getAlpha(srcColor)); + lab.push(srcColor.a); } - array = (y: number, x: number) => - visited[y * options.src.width + x] === 0 && - Draw.testPixelLabColorDistance(options.src, x, y, lab, threshold); + + array = (y: number, x: number) => { + return ( + visited[y * opt.image.width + x] === 0 && + Draw.testPixelLabColorDistance(opt.image, x, y, lab, threshold) + ); + }; } else if (!compareAlpha) { - array = (y: number, x: number) => - visited[y * options.src.width + x] === 0 && - Color.setAlpha(options.src.getPixel(x, y), 0) !== srcColor; + array = (y: number, x: number) => { + return ( + visited[y * opt.image.width + x] === 0 && + Draw.setAlpha(opt.image.getPixel(x, y), 0) !== srcColor + ); + }; } else { - array = (y: number, x: number) => - visited[y * options.src.width + x] === 0 && - options.src.getPixel(x, y) !== srcColor; + array = (y: number, x: number) => { + return ( + visited[y * opt.image.width + x] === 0 && + opt.image.getPixel(x, y) !== srcColor + ); + }; } - const mark = (y: number, x: number) => { - options.src.setPixel(x, y, options.color); - visited[y * options.src.width + x] = 1; + let p: Pixel | undefined = undefined; + + const mark = (y: number, x: number): void => { + if (opt.mask !== undefined) { + const m = opt.mask.getPixel(x, y).getChannelNormalized(maskChannel); + if (m > 0) { + p = opt.image.getPixel(x, y, p); + p.r = MathUtils.mix(p!.r, opt.color.r, m); + p.g = MathUtils.mix(p!.g, opt.color.g, m); + p.b = MathUtils.mix(p!.b, opt.color.b, m); + p.a = MathUtils.mix(p!.a, opt.color.a, m); + } + } else { + opt.image.setPixel(x, y, opt.color); + } + visited[y * opt.image.width + x] = 1; }; - Draw.fill4(options.src, options.x, options.y, array, mark, visited); - return options.src; + Draw.fill4(opt.image, opt.start.x, opt.start.y, array, mark, visited); + + return opt.image; } /** - * Create a mask describing the 4-connected shape containing **x**,**y** in the - * image **src**. + * Fill a polygon defined by the given **vertices**. */ - public static maskFlood(options: MaskFloodOptions): Uint8Array { - const threshold = options.threshold ?? 0; - const compareAlpha = options.compareAlpha ?? false; - const fillValue = options.fillValue ?? 255; + public static fillPolygon(opt: FillPolygonOptions): MemoryImage { + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (opt.color.a === 0) { + return opt.image; + } - const visited = new Uint8Array(options.src.width * options.src.height); + const numVertices = opt.vertices.length; - let srcColor = options.src.getPixel(options.x, options.y); - if (!compareAlpha) { - srcColor = Color.setAlpha(srcColor, 0); + if (numVertices === 0) { + return opt.image; } - const ret = new Uint8Array(options.src.width * options.src.height); + if (numVertices === 1) { + return Draw.drawPixel({ + image: opt.image, + pos: opt.vertices[0], + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); + } - let array: FillFloodTestPixel | undefined = undefined; - if (threshold > 0) { - const lab = Color.rgbToLab( - Color.getRed(srcColor), - Color.getGreen(srcColor), - Color.getBlue(srcColor) - ); - if (compareAlpha) { - lab.push(Color.getAlpha(srcColor)); + if (numVertices === 2) { + return Draw.drawLine({ + image: opt.image, + line: new Line( + opt.vertices[0].x, + opt.vertices[0].y, + opt.vertices[1].x, + opt.vertices[1].y + ), + color: opt.color, + mask: opt.mask, + maskChannel: maskChannel, + }); + } + + let xMin = 0; + let yMin = 0; + let xMax = 0; + let yMax = 0; + let first = true; + for (const vertex of opt.vertices) { + if (first) { + xMin = vertex.x; + yMin = vertex.y; + xMax = vertex.x; + yMax = vertex.y; + first = false; + } else { + xMin = Math.min(xMin, vertex.x); + yMin = Math.min(yMin, vertex.y); + xMax = Math.max(xMax, vertex.x); + yMax = Math.max(yMax, vertex.y); } - array = (y: number, x: number) => - visited[y * options.src.width + x] === 0 && - (ret[y * options.src.width + x] !== 0 || - Draw.testPixelLabColorDistance(options.src, x, y, lab, threshold)); - } else if (!compareAlpha) { - array = (y: number, x: number) => - visited[y * options.src.width + x] === 0 && - (ret[y * options.src.width + x] !== 0 || - Color.setAlpha(options.src.getPixel(x, y), 0) !== srcColor); - } else { - array = (y: number, x: number) => - visited[y * options.src.width + x] === 0 && - (ret[y * options.src.width + x] !== 0 || - options.src.getPixel(x, y) !== srcColor); } - const mark = (y: number, x: number) => { - ret[y * options.src.width + x] = fillValue; - visited[y * options.src.width + x] = 1; - }; + xMin = Math.max(xMin, 0); + yMin = Math.max(yMin, 0); + xMax = Math.min(xMax, opt.image.width - 1); + yMax = Math.min(yMax, opt.image.height - 1); - Draw.fill4(options.src, options.x, options.y, array, mark, visited); - return ret; + const inter = ArrayUtils.fill(40, 0); + const vi = ArrayUtils.generate(numVertices + 1, (i) => + i < numVertices ? i : 0 + ); + + for (let yi = yMin, y = yMin + 0.5; yi <= yMax; ++yi, ++y) { + let c = 0; + for (let i = 0; i < numVertices; ++i) { + const v1 = opt.vertices[vi[i]]; + const v2 = opt.vertices[vi[i + 1]]; + + let x1 = v1.x; + let y1 = v1.y; + let x2 = v2.x; + let y2 = v2.y; + if (y2 < y1) { + let temp = x1; + x1 = x2; + x2 = temp; + temp = y1; + y1 = y2; + y2 = temp; + } + + if (y <= y2 && y >= y1) { + let x = 0; + if (y1 - y2 === 0) { + x = x1; + } else { + x = ((x2 - x1) * (y - y1)) / (y2 - y1); + x += x1; + } + if (x <= xMax && x >= xMin) { + inter[c++] = x; + } + } + } + + for (let i = 0; i < c; i += 2) { + let x1f = inter[i]; + let x2f = inter[i + 1]; + if (x1f > x2f) { + const t = x1f; + x1f = x2f; + x2f = t; + } + const x1 = Math.floor(x1f); + const x2 = Math.ceil(x2f); + for (let x = x1; x <= x2; ++x) { + Draw.drawPixel({ + image: opt.image, + pos: new Point(x, yi), + color: opt.color, + maskChannel: maskChannel, + mask: opt.mask, + }); + } + } + } + + return opt.image; } /** - * Fill a rectangle in the image **src** with the given **color** with the - * coordinates defined by **rect**. + * Fill a rectangle **rect** in the **image** with the given **color**. */ - public static fillRect( - src: MemoryImage, - rect: Rectangle, - color: number - ): MemoryImage { - const _x0 = MathOperators.clamp(rect.left, 0, src.width - 1); - const _y0 = MathOperators.clamp(rect.top, 0, src.height - 1); - const _x1 = MathOperators.clamp(rect.right, 0, src.width - 1); - const _y1 = MathOperators.clamp(rect.bottom, 0, src.height - 1); + public static fillRect(opt: FillRectOptions): MemoryImage { + const radius = opt.radius ?? 0; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (opt.color.a === 0) { + return opt.image; + } + + const xx0 = MathUtils.clamp(opt.rect.left, 0, opt.image.width - 1); + const yy0 = MathUtils.clamp(opt.rect.top, 0, opt.image.height - 1); + const xx1 = MathUtils.clamp(opt.rect.right, 0, opt.image.width - 1); + const yy1 = MathUtils.clamp(opt.rect.bottom, 0, opt.image.height - 1); + const ww = xx1 - xx0 + 1; + const hh = yy1 - yy0 + 1; + + // Fill a rounded rect + if (radius > 0) { + const rad = Math.round(radius); + const rad2 = rad * rad; + const c1x = xx0 + rad; + const c1y = yy0 + rad; + const c2x = xx1 - rad + 1; + const c2y = yy0 + rad; + const c3x = xx1 - rad + 1; + const c3y = yy1 - rad + 1; + const c4x = xx0 + rad; + const c4y = yy1 - rad + 1; + + const range = opt.image.getRange(xx0, yy0, ww, hh); + let it: IteratorResult | undefined = undefined; + while (((it = range.next()), !it.done)) { + const p = it.value; + const px = p.x; + const py = p.y; + + let a = 1; + if (px < c1x && py < c1y) { + a = ImageUtils.circleTest(p, new Point(c1x, c1y), rad2); + if (a === 0) { + continue; + } + } else if (px > c2x && py < c2y) { + a = ImageUtils.circleTest(p, new Point(c2x, c2y), rad2); + if (a === 0) { + continue; + } + } else if (px > c3x && py > c3y) { + a = ImageUtils.circleTest(p, new Point(c3x, c3y), rad2); + if (a === 0) { + continue; + } + } else if (px < c4x && py > c4y) { + a = ImageUtils.circleTest(p, new Point(c4x, c4y), rad2); + if (a === 0) { + continue; + } + } + + a *= opt.color.aNormalized; + + const m = + opt.mask?.getPixel(p.x, p.y).getChannelNormalized(maskChannel) ?? 1; + p.r = MathUtils.mix(p.r, opt.color.r, a * m); + p.g = MathUtils.mix(p.g, opt.color.g, a * m); + p.b = MathUtils.mix(p.b, opt.color.b, a * m); + p.a *= 1 - opt.color.a * m; + } + + return opt.image; + } // If no blending is necessary, use a faster fill method. - if (Color.getAlpha(color) === 255) { - const w = src.width; - let start = _y0 * w + _x0; - let end = start + (_x1 - _x0) + 1; - for (let sy = _y0; sy <= _y1; ++sy) { - src.data.fill(color, start, end); - start += w; - end += w; + if (opt.color.a === opt.color.maxChannelValue && opt.mask === undefined) { + const range = opt.image.getRange(xx0, yy0, ww, hh); + let it: IteratorResult | undefined = undefined; + while (((it = range.next()), !it.done)) { + it.value.set(opt.color); } } else { - for (let sy = _y0; sy <= _y1; ++sy) { - let pi = sy * src.width + _x0; - for (let sx = _x0; sx <= _x1; ++sx, ++pi) { - src.setPixelByIndex( - pi, - Color.alphaBlendColors(src.getPixelByIndex(pi), color) - ); - } + const a = opt.color.a / opt.color.maxChannelValue; + const range = opt.image.getRange(xx0, yy0, ww, hh); + let it: IteratorResult | undefined = undefined; + while (((it = range.next()), !it.done)) { + const p = it.value; + const m = + opt.mask?.getPixel(p.x, p.y).getChannelNormalized(maskChannel) ?? 1; + p.r = MathUtils.mix(p.r, opt.color.r, a * m); + p.g = MathUtils.mix(p.g, opt.color.g, a * m); + p.b = MathUtils.mix(p.b, opt.color.b, a * m); + p.a *= 1 - opt.color.a * m; } } - return src; + return opt.image; } /** * Set all of the pixels of an **image** to the given **color**. */ - public static fill(image: MemoryImage, color: number): MemoryImage { - return image.fill(color); + public static fill(opt: FillOptions): MemoryImage { + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (opt.mask === undefined) { + opt.image.clear(opt.color); + return opt.image; + } + + for (const p of opt.image) { + const maskValue = opt.mask + .getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + p.r = MathUtils.mix(p.r, opt.color.r, maskValue); + p.g = MathUtils.mix(p.g, opt.color.g, maskValue); + p.b = MathUtils.mix(p.b, opt.color.b, maskValue); + p.a = MathUtils.mix(p.a, opt.color.a, maskValue); + } + + return opt.image; + } + + /** + * Create a mask describing the 4-connected shape containing **start** in the + * **image**. + */ + public static maskFlood(opt: MaskFloodOptions): Uint8Array { + const threshold = opt.threshold ?? 0; + const compareAlpha = opt.compareAlpha ?? false; + const fillValue = opt.fillValue ?? 255; + + const visited = new Uint8Array(opt.image.width * opt.image.height); + + let srcColor: Color = opt.image.getPixel(opt.start.x, opt.start.y); + if (!compareAlpha) { + srcColor = Draw.setAlpha(srcColor, 0); + } + + const ret = new Uint8Array(opt.image.width * opt.image.height); + + let array: FillFloodTestPixel | undefined = undefined; + if (threshold > 0) { + const lab = ColorUtils.rgbToLab(srcColor.r, srcColor.g, srcColor.b); + if (compareAlpha) { + lab.push(srcColor.a); + } + array = (y: number, x: number) => { + return ( + visited[y * opt.image.width + x] === 0 && + (ret[y * opt.image.width + x] !== 0 || + Draw.testPixelLabColorDistance(opt.image, x, y, lab, threshold)) + ); + }; + } else if (!compareAlpha) { + array = (y: number, x: number) => { + return ( + visited[y * opt.image.width + x] === 0 && + (ret[y * opt.image.width + x] !== 0 || + Draw.setAlpha(opt.image.getPixel(x, y), 0) !== srcColor) + ); + }; + } else { + array = (y: number, x: number) => { + return ( + visited[y * opt.image.width + x] === 0 && + (ret[y * opt.image.width + x] !== 0 || + opt.image.getPixel(x, y) !== srcColor) + ); + }; + } + + const mark = (y: number, x: number): void => { + ret[y * opt.image.width + x] = fillValue; + visited[y * opt.image.width + x] = 1; + }; + + Draw.fill4(opt.image, opt.start.x, opt.start.y, array, mark, visited); + return ret; + } + + /** + * Composite the image **src** onto the image **dst**. + * + * In other words, compositeImage will take an rectangular area from src of + * width **srcW** and height **srcH** at position (**srcX**,**srcY**) and place it + * in a rectangular area of **dst** of width **dstW** and height **dstH** at + * position (**dstX**,**dstY**). + * + * If the source and destination coordinates and width and heights differ, + * appropriate stretching or shrinking of the image fragment will be performed. + * The coordinates refer to the upper left corner. This function can be used to + * copy regions within the same image (if **dst** is the same as **src**) + * but if the regions overlap the results will be unpredictable. + * + * if **center** is true, the **src** will be centered in **dst**. + */ + public static compositeImage(opt: CompositeImageOptions): MemoryImage { + let dstX = opt.dstX ?? 0; + let dstY = opt.dstY ?? 0; + const srcX = opt.srcX ?? 0; + const srcY = opt.srcY ?? 0; + const srcW = opt.srcW ?? opt.src.width; + const srcH = opt.srcH ?? opt.src.height; + const dstW = + opt.dstW ?? + (opt.dst.width < opt.src.width ? opt.dst.width : opt.src.width); + const dstH = + opt.dstH ?? + (opt.dst.height < opt.src.height ? opt.dst.height : opt.src.height); + const blend = opt.blend ?? BlendMode.alpha; + const linearBlend = opt.linearBlend ?? false; + const center = opt.center ?? false; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (center) { + // if [src] is wider than [dst] + let wdt = opt.dst.width - opt.src.width; + if (wdt < 0) wdt = 0; + dstX = Math.trunc(wdt / 2); + // if [src] is higher than [dst] + let height = opt.dst.height - opt.src.height; + if (height < 0) height = 0; + dstY = Math.trunc(height / 2); + } + + if (opt.dst.hasPalette) { + opt.dst.convert({ + numChannels: opt.dst.numChannels, + }); + } + + const dy = srcH / dstH; + const dx = srcW / dstW; + const yCache = Array.from( + { length: dstH }, + (_, y) => srcY + Math.trunc(y * dy) + ); + const xCache = Array.from( + { length: dstW }, + (_, x) => srcX + Math.trunc(x * dx) + ); + + if (blend === BlendMode.direct) { + Draw.imgDirectComposite( + opt.src, + opt.dst, + dstX, + dstY, + dstW, + dstH, + xCache, + yCache, + maskChannel, + opt.mask + ); + } else { + Draw.imgComposite( + opt.src, + opt.dst, + dstX, + dstY, + dstW, + dstH, + xCache, + yCache, + blend, + linearBlend, + maskChannel, + opt.mask + ); + } + + return opt.dst; } } diff --git a/src/draw/fill-flood-options.ts b/src/draw/fill-flood-options.ts deleted file mode 100644 index 60b803f..0000000 --- a/src/draw/fill-flood-options.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** @format */ - -import { MemoryImage } from '../common/memory-image'; - -export interface FillFloodOptions { - src: MemoryImage; - x: number; - y: number; - color: number; - threshold?: number; - compareAlpha?: boolean; -} diff --git a/src/draw/mask-flood-options.ts b/src/draw/mask-flood-options.ts deleted file mode 100644 index 7b61851..0000000 --- a/src/draw/mask-flood-options.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** @format */ - -import { MemoryImage } from '../common/memory-image'; - -export interface MaskFloodOptions { - src: MemoryImage; - x: number; - y: number; - threshold?: number; - compareAlpha?: boolean; - fillValue?: number; -} diff --git a/src/error/image-error.ts b/src/error/image-error.ts deleted file mode 100644 index b1ad73e..0000000 --- a/src/error/image-error.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** @format */ - -/** - * An Error thrown when there was a problem in the image library. - */ -export class ImageError extends Error { - toString(): string { - return `ImageError: ${this.message}`; - } -} diff --git a/src/error/lib-error.ts b/src/error/lib-error.ts new file mode 100644 index 0000000..8d17a8d --- /dev/null +++ b/src/error/lib-error.ts @@ -0,0 +1,10 @@ +/** @format */ + +/** + * An Error thrown when there was a problem in the library. + */ +export class LibError extends Error { + public toString(): string { + return `${this.constructor.name} (${this.message})`; + } +} diff --git a/src/error/not-implemented-error.ts b/src/error/not-implemented-error.ts deleted file mode 100644 index e988f96..0000000 --- a/src/error/not-implemented-error.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** @format */ - -/** - * An error thrown when some functionality has not yet been implemented. - */ -export class NotImplementedError extends Error { - toString(): string { - return this.message.length > 0 - ? `NotImplementedError: ${this.message}` - : 'NotImplementedError'; - } -} diff --git a/src/exif/exif-data.ts b/src/exif/exif-data.ts index 930f3d4..a751a7c 100644 --- a/src/exif/exif-data.ts +++ b/src/exif/exif-data.ts @@ -3,58 +3,76 @@ import { InputBuffer } from '../common/input-buffer'; import { OutputBuffer } from '../common/output-buffer'; import { ExifEntry } from './exif-entry'; -import { ExifIFD } from './exif-ifd'; -import { ExifIFDContainer } from './exif-ifd-container'; -import { ExifImageTags } from './exif-tag'; -import { ExifValueType, ExifValueTypeSize } from './exif-value-type'; -import { ExifAsciiValue } from './exif-value/exif-ascii-value'; -import { ExifByteValue } from './exif-value/exif-byte-value'; -import { ExifDoubleValue } from './exif-value/exif-double-value'; -import { ExifLongValue } from './exif-value/exif-long-value'; -import { ExifRationalValue } from './exif-value/exif-rational-value'; -import { ExifSByteValue } from './exif-value/exif-sbyte-value'; -import { ExifShortValue } from './exif-value/exif-short-value'; -import { ExifSingleValue } from './exif-value/exif-single-value'; -import { ExifSLongValue } from './exif-value/exif-slong-value'; -import { ExifSRationalValue } from './exif-value/exif-srational-value'; -import { ExifSShortValue } from './exif-value/exif-sshort-value'; -import { ExifUndefinedValue } from './exif-value/exif-undefined-value'; -import { ExifValue } from './exif-value/exif-value'; - -export class ExifData extends ExifIFDContainer { - public get imageIfd(): ExifIFD { +import { ExifImageTags, ExifTagNameToID } from './exif-tag'; +import { IfdContainer } from './ifd-container'; +import { IfdDirectory } from './ifd-directory'; +import { IfdValueType, IfdValueTypeSize } from './ifd-value-type'; +import { IfdAsciiValue } from './ifd-value/ifd-ascii-value'; +import { IfdByteValue } from './ifd-value/ifd-byte-value'; +import { IfdDoubleValue } from './ifd-value/ifd-double-value'; +import { IfdLongValue } from './ifd-value/ifd-long-value'; +import { IfdRationalValue } from './ifd-value/ifd-rational-value'; +import { IfdSByteValue } from './ifd-value/ifd-sbyte-value'; +import { IfdShortValue } from './ifd-value/ifd-short-value'; +import { IfdSingleValue } from './ifd-value/ifd-single-value'; +import { IfdSLongValue } from './ifd-value/ifd-slong-value'; +import { IfdSRationalValue } from './ifd-value/ifd-srational-value'; +import { IfdSShortValue } from './ifd-value/ifd-sshort-value'; +import { IfdUndefinedValue } from './ifd-value/ifd-undefined-value'; +import { IfdValue } from './ifd-value/ifd-value'; + +export class ExifData extends IfdContainer { + public get imageIfd(): IfdDirectory { return this.get('ifd0'); } - public get thumbnailIfd(): ExifIFD { + public get thumbnailIfd(): IfdDirectory { return this.get('ifd1'); } - public get exifIfd(): ExifIFD { + public get exifIfd(): IfdDirectory { return this.get('ifd0').sub.get('exif'); } - public get gpsIfd(): ExifIFD { + public get gpsIfd(): IfdDirectory { return this.get('ifd0').sub.get('gps'); } - public get interopIfd(): ExifIFD { + public get interopIfd(): IfdDirectory { return this.get('ifd0').sub.get('interop'); } + public get dataSize(): number { + return 8 + (this.directories.get('ifd0')?.dataSize ?? 0); + } + private writeDirectory( out: OutputBuffer, - ifd: ExifIFD, + ifd: IfdDirectory, dataOffset: number ): number { let offset = dataOffset; + const stripOffsetTag = ExifTagNameToID.get('StripOffsets'); out.writeUint16(ifd.size); for (const tag of ifd.keys) { const value = ifd.getValue(tag)!; + // Special-case StripOffsets, used by TIFF, that if it points to + // Undefined value type, then its storing the image data and should + // be translated to the StripOffsets long type. + const tagType = + tag === stripOffsetTag && value.type === IfdValueType.undefined + ? IfdValueType.long + : value.type; + + const tagLength = + tag === stripOffsetTag && value.type === IfdValueType.undefined + ? 1 + : value.length; + out.writeUint16(tag); - out.writeUint16(value.type); - out.writeUint32(value.length); + out.writeUint16(tagType); + out.writeUint32(tagLength); let size = value.dataSize; if (size <= 4) { @@ -71,7 +89,10 @@ export class ExifData extends ExifIFDContainer { return offset; } - private writeDirectoryLargeValues(out: OutputBuffer, ifd: ExifIFD): void { + private writeDirectoryLargeValues( + out: OutputBuffer, + ifd: IfdDirectory + ): void { for (const value of ifd.values) { const size = value.dataSize; if (size > 4) { @@ -87,10 +108,10 @@ export class ExifData extends ExifIFDContainer { const entry = new ExifEntry(tag, undefined); - if (format > Object.keys(ExifValueType).length) return entry; + if (format > Object.keys(IfdValueType).length) return entry; - const f = format as ExifValueType; - const fsize = ExifValueTypeSize[format]; + const f = format as IfdValueType; + const fsize = IfdValueTypeSize[format]; const size = count * fsize; const endOffset = block.offset + 4; @@ -107,43 +128,43 @@ export class ExifData extends ExifIFDContainer { const data = block.readBytes(size); switch (f) { - case ExifValueType.none: + case IfdValueType.none: break; - case ExifValueType.sbyte: - entry.value = ExifSByteValue.fromData(data, count); + case IfdValueType.sByte: + entry.value = IfdSByteValue.data(data, count); break; - case ExifValueType.byte: - entry.value = ExifByteValue.fromData(data, count); + case IfdValueType.byte: + entry.value = IfdByteValue.data(data, count); break; - case ExifValueType.undefined: - entry.value = ExifUndefinedValue.fromData(data, count); + case IfdValueType.undefined: + entry.value = IfdUndefinedValue.data(data, count); break; - case ExifValueType.ascii: - entry.value = ExifAsciiValue.fromData(data, count); + case IfdValueType.ascii: + entry.value = IfdAsciiValue.data(data, count); break; - case ExifValueType.short: - entry.value = ExifShortValue.fromData(data, count); + case IfdValueType.short: + entry.value = IfdShortValue.data(data, count); break; - case ExifValueType.long: - entry.value = ExifLongValue.fromData(data, count); + case IfdValueType.long: + entry.value = IfdLongValue.data(data, count); break; - case ExifValueType.rational: - entry.value = ExifRationalValue.fromData(data, count); + case IfdValueType.rational: + entry.value = IfdRationalValue.data(data, count); break; - case ExifValueType.srational: - entry.value = ExifSRationalValue.fromData(data, count); + case IfdValueType.sRational: + entry.value = IfdSRationalValue.data(data, count); break; - case ExifValueType.sshort: - entry.value = ExifSShortValue.fromData(data, count); + case IfdValueType.sShort: + entry.value = IfdSShortValue.data(data, count); break; - case ExifValueType.slong: - entry.value = ExifSLongValue.fromData(data, count); + case IfdValueType.sLong: + entry.value = IfdSLongValue.data(data, count); break; - case ExifValueType.single: - entry.value = ExifSingleValue.fromData(data, count); + case IfdValueType.single: + entry.value = IfdSingleValue.data(data, count); break; - case ExifValueType.double: - entry.value = ExifDoubleValue.fromData(data, count); + case IfdValueType.double: + entry.value = IfdDoubleValue.data(data, count); break; } @@ -153,7 +174,8 @@ export class ExifData extends ExifIFDContainer { } public static from(other: ExifData) { - return new ExifData(other.directories); + const dirs = new Map(other.directories); + return new ExifData(dirs); } public static fromInputBuffer(input: InputBuffer) { @@ -171,7 +193,7 @@ export class ExifData extends ExifIFDContainer { return false; } - public getTag(tag: number): ExifValue | undefined { + public getTag(tag: number): IfdValue | undefined { for (const directory of this.directories.values()) { if (directory.has(tag)) { return directory.getValue(tag); @@ -196,7 +218,7 @@ export class ExifData extends ExifIFDContainer { out.writeUint32(8); if (this.directories.get('ifd0') === undefined) - this.directories.set('ifd0', new ExifIFD()); + this.directories.set('ifd0', new IfdDirectory()); // offset to first ifd block, from start of tiff header let dataOffset = 8; @@ -206,19 +228,19 @@ export class ExifData extends ExifIFDContainer { offsets.set(name, dataOffset); if (ifd.sub.has('exif')) { - ifd.setValue(0x8769, new ExifLongValue(0)); + ifd.setValue(0x8769, new IfdLongValue(0)); } else { ifd.setValue(0x8769, undefined); } if (ifd.sub.has('interop')) { - ifd.setValue(0xa005, new ExifLongValue(0)); + ifd.setValue(0xa005, new IfdLongValue(0)); } else { ifd.setValue(0xa005, undefined); } if (ifd.sub.has('gps')) { - ifd.setValue(0x8825, new ExifLongValue(0)); + ifd.setValue(0x8825, new IfdLongValue(0)); } else { ifd.setValue(0x8825, undefined); } @@ -299,11 +321,10 @@ export class ExifData extends ExifIFDContainer { // Tiff header const endian = block.readUint16(); - if (endian === 0x4949) { // II block.bigEndian = false; - if (block.readUint16() !== 0x2a00) { + if (block.readUint16() !== 0x002a) { block.bigEndian = saveEndian; return false; } @@ -325,7 +346,7 @@ export class ExifData extends ExifIFDContainer { while (ifdOffset > 0) { block.offset = blockOffset + ifdOffset; - const directory = new ExifIFD(); + const directory = new IfdDirectory(); const numEntries = block.readUint16(); const dir = new Array(); @@ -357,7 +378,7 @@ export class ExifData extends ExifIFDContainer { if (d.has(dt)) { const ifdOffset = d.getValue(dt)!.toInt(); block.offset = blockOffset + ifdOffset; - const directory = new ExifIFD(); + const directory = new IfdDirectory(); const numEntries = block.readUint16(); const dir = new Array(); @@ -380,6 +401,10 @@ export class ExifData extends ExifIFDContainer { return false; } + public clone(): ExifData { + return ExifData.from(this); + } + public toString(): string { let s = ''; for (const [name, directory] of this.directories) { @@ -405,6 +430,6 @@ export class ExifData extends ExifIFDContainer { } } } - return s.toString(); + return `${this.constructor.name} (${s})`; } } diff --git a/src/exif/exif-entry.ts b/src/exif/exif-entry.ts index d10dfc4..01a6b05 100644 --- a/src/exif/exif-entry.ts +++ b/src/exif/exif-entry.ts @@ -1,6 +1,6 @@ /** @format */ -import { ExifValue } from './exif-value/exif-value'; +import { IfdValue } from './ifd-value/ifd-value'; export class ExifEntry { private readonly _tag: number; @@ -8,15 +8,15 @@ export class ExifEntry { return this._tag; } - private _value: ExifValue | undefined; - public get value(): ExifValue | undefined { + private _value: IfdValue | undefined; + public get value(): IfdValue | undefined { return this._value; } - public set value(v: ExifValue | undefined) { + public set value(v: IfdValue | undefined) { this._value = v; } - constructor(tag: number, value?: ExifValue) { + constructor(tag: number, value?: IfdValue) { this._tag = tag; this._value = value; } diff --git a/src/exif/exif-ifd.ts b/src/exif/exif-ifd.ts deleted file mode 100644 index 4464096..0000000 --- a/src/exif/exif-ifd.ts +++ /dev/null @@ -1,510 +0,0 @@ -/** @format */ - -import { Rational } from '../common/rational'; -import { ExifIFDContainer } from './exif-ifd-container'; -import { ExifImageTags, ExifTagNameToID } from './exif-tag'; -import { ExifValueType } from './exif-value-type'; -import { ExifAsciiValue } from './exif-value/exif-ascii-value'; -import { ExifByteValue } from './exif-value/exif-byte-value'; -import { ExifDoubleValue } from './exif-value/exif-double-value'; -import { ExifLongValue } from './exif-value/exif-long-value'; -import { ExifRationalValue } from './exif-value/exif-rational-value'; -import { ExifSByteValue } from './exif-value/exif-sbyte-value'; -import { ExifShortValue } from './exif-value/exif-short-value'; -import { ExifSingleValue } from './exif-value/exif-single-value'; -import { ExifSLongValue } from './exif-value/exif-slong-value'; -import { ExifSRationalValue } from './exif-value/exif-srational-value'; -import { ExifSShortValue } from './exif-value/exif-sshort-value'; -import { ExifUndefinedValue } from './exif-value/exif-undefined-value'; -import { ExifValue } from './exif-value/exif-value'; - -export class ExifIFD { - private readonly data = new Map(); - - private readonly _sub = new ExifIFDContainer(); - public get sub(): ExifIFDContainer { - return this._sub; - } - - public get keys(): IterableIterator { - return this.data.keys(); - } - - public get values(): IterableIterator { - return this.data.values(); - } - - public get size(): number { - return this.data.size; - } - - public get isEmpty(): boolean { - return this.data.size === 0 && this._sub.isEmpty; - } - - public get hasImageDescription(): boolean { - return this.data.has(0x010e); - } - - public get imageDescription(): string | undefined { - return this.data.get(0x010e)?.toString(); - } - - public set imageDescription(v: string | undefined) { - if (v === undefined) { - this.data.delete(0x010e); - } else { - this.data.set(0x010e, new ExifAsciiValue(v)); - } - } - - public get hasMake(): boolean { - return this.data.has(0x010f); - } - - public get make(): string | undefined { - return this.data.get(0x010f)?.toString(); - } - - public set make(v: string | undefined) { - if (v === undefined) { - this.data.delete(0x010f); - } else { - this.data.set(0x010f, new ExifAsciiValue(v)); - } - } - - public get hasModel(): boolean { - return this.data.has(0x0110); - } - - public get model(): string | undefined { - return this.data.get(0x0110)?.toString(); - } - - public set model(v: string | undefined) { - if (v === undefined) { - this.data.delete(0x0110); - } else { - this.data.set(0x0110, new ExifAsciiValue(v)); - } - } - - public get hasOrientation(): boolean { - return this.data.has(0x0112); - } - - public get orientation(): number | undefined { - return this.data.get(0x0112)?.toInt(); - } - - public set orientation(v: number | undefined) { - if (v === undefined) { - this.data.delete(0x0112); - } else { - this.data.set(0x0112, new ExifShortValue(v)); - } - } - - public get hasResolutionX(): boolean { - return this.data.has(0x011a); - } - - public get resolutionX(): Rational | undefined { - return this.data.get(0x011a)?.toRational(); - } - - public set resolutionX(v: Rational | undefined) { - if (!this.setRational(0x011a, v)) { - this.data.delete(0x011a); - } - } - - public get hasResolutionY(): boolean { - return this.data.has(0x011b); - } - - public get resolutionY(): Rational | undefined { - return this.data.get(0x011b)?.toRational(); - } - - public set resolutionY(v: Rational | undefined) { - if (!this.setRational(0x011b, v)) { - this.data.delete(0x011b); - } - } - - public get hasResolutionUnit(): boolean { - return this.data.has(0x0128); - } - - public get resolutionUnit(): number | undefined { - return this.data.get(0x0128)?.toInt(); - } - - public set resolutionUnit(v: number | undefined) { - if (v === undefined) { - this.data.delete(0x0128); - } else { - this.data.set(0x0128, new ExifShortValue(Math.trunc(v))); - } - } - - public get hasImageWidth(): boolean { - return this.data.has(0x0100); - } - - public get imageWidth(): number | undefined { - return this.data.get(0x0100)?.toInt(); - } - - public set imageWidth(v: number | undefined) { - if (v === undefined) { - this.data.delete(0x0100); - } else { - this.data.set(0x0100, new ExifShortValue(Math.trunc(v))); - } - } - - public get hasImageHeight(): boolean { - return this.data.has(0x0101); - } - - public get imageHeight(): number | undefined { - return this.data.get(0x0101)?.toInt(); - } - - public set imageHeight(v: number | undefined) { - if (v === undefined) { - this.data.delete(0x0101); - } else { - this.data.set(0x0101, new ExifShortValue(Math.trunc(v))); - } - } - - public get hasSoftware(): boolean { - return this.data.has(0x0131); - } - - public get software(): string | undefined { - return this.data.get(0x0131)?.toString(); - } - - public set software(v: string | undefined) { - if (v === undefined) { - this.data.delete(0x0131); - } else { - this.data.set(0x0131, new ExifAsciiValue(v)); - } - } - - public get hasCopyright(): boolean { - return this.data.has(0x8298); - } - - public get copyright(): string | undefined { - return this.data.get(0x8298)?.toString(); - } - - public set copyright(v: string | undefined) { - if (v === undefined) { - this.data.delete(0x8298); - } else { - this.data.set(0x8298, new ExifAsciiValue(v)); - } - } - - private setRational(tag: number, value: unknown): boolean { - if (value instanceof Rational) { - this.data.set(tag, ExifRationalValue.from(value)); - return true; - } else if ( - Array.isArray(value) && - (value as Array).every((v) => typeof v === 'number') - ) { - if (value.length === 2) { - const r = new Rational((value as number[])[0], (value as number[])[1]); - this.data.set(tag, ExifRationalValue.from(r)); - return true; - } - } - return false; - } - - public static isArrayOfRationalNumbers(value: unknown): boolean { - return ( - Array.isArray(value) && - value.every( - (v) => - Array.isArray(v) && - v.length >= 2 && - v.every((sv) => typeof sv === 'number') - ) - ); - } - - public has(tag: number): boolean { - return this.data.has(tag); - } - - public getValue(tag: number | string): ExifValue | undefined { - let _tag: string | number | undefined = tag; - if (typeof _tag === 'string') { - _tag = ExifTagNameToID.get(_tag); - } - if (typeof _tag === 'number') { - return this.data.get(_tag); - } - return undefined; - } - - public setValue( - tag: number | string, - value: number[][] | Rational[] | number[] | Rational | ExifValue | undefined - ): void { - let _tag: string | number | undefined = tag; - if (typeof _tag === 'string') { - _tag = ExifTagNameToID.get(_tag); - } - if (typeof _tag !== 'number') { - return; - } - - if (value === undefined) { - this.data.delete(_tag); - } else { - if (value instanceof ExifValue) { - this.data.set(_tag, value); - } else { - const tagInfo = ExifImageTags.get(_tag); - if (tagInfo !== undefined) { - const tagType = tagInfo.type; - const tagCount = tagInfo.count; - switch (tagType) { - case ExifValueType.byte: - if ( - Array.isArray(value) && - value.length === tagCount && - (value as Array).every((v) => typeof v === 'number') - ) { - this.data.set( - _tag, - new ExifByteValue(new Uint8Array(value as number[])) - ); - } else if (typeof value === 'number' && tagCount === 1) { - this.data.set(_tag, new ExifByteValue(value)); - } - break; - case ExifValueType.ascii: - if (typeof value === 'string') { - this.data.set(_tag, new ExifAsciiValue(value)); - } - break; - case ExifValueType.short: - if ( - Array.isArray(value) && - value.length === tagCount && - (value as Array).every((v) => typeof v === 'number') - ) { - this.data.set( - _tag, - new ExifShortValue(new Uint16Array(value as number[])) - ); - } else if (typeof value === 'number' && tagCount === 1) { - this.data.set(_tag, new ExifShortValue(value)); - } - break; - case ExifValueType.long: - if ( - Array.isArray(value) && - value.length === tagCount && - (value as Array).every((v) => typeof v === 'number') - ) { - this.data.set( - _tag, - new ExifLongValue(new Uint32Array(value as number[])) - ); - } else if (typeof value === 'number' && tagCount === 1) { - this.data.set(_tag, new ExifLongValue(value)); - } - break; - case ExifValueType.rational: - if ( - Array.isArray(value) && - value.length === tagCount && - (value as Array).every((v) => v instanceof Rational) - ) { - this.data.set(_tag, new ExifRationalValue(value as Rational[])); - } else if ( - tagCount === 1 && - Array.isArray(value) && - value.length === 2 && - (value as Array).every((v) => typeof v === 'number') - ) { - const r = new Rational( - (value as number[])[0], - (value as number[])[1] - ); - this.data.set(_tag, new ExifRationalValue(r)); - } else if (tagCount === 1 && value instanceof Rational) { - this.data.set(_tag, new ExifRationalValue(value)); - } else if ( - Array.isArray(value) && - value.length === tagCount && - (value as Array).every( - (v) => - Array.isArray(v) && - v.length >= 2 && - v.every((sv) => typeof sv === 'number') - ) - ) { - const array = new Array(); - for (let i = 0; i < value.length; i++) { - const subarray = value[i]; - if ( - Array.isArray(subarray) && - subarray.length >= 2 && - subarray.every((el) => typeof el === 'number') - ) { - array.push(new Rational(subarray[0], subarray[1])); - } - } - this.data.set(_tag, new ExifRationalValue(array)); - } - break; - case ExifValueType.sbyte: - if ( - Array.isArray(value) && - value.length === tagCount && - (value as Array).every((v) => typeof v === 'number') - ) { - this.data.set( - _tag, - new ExifSByteValue(new Int8Array(value as number[])) - ); - } else if (typeof value === 'number' && tagCount === 1) { - this.data.set(_tag, new ExifSByteValue(value)); - } - break; - case ExifValueType.undefined: - if ( - Array.isArray(value) && - (value as Array).every((v) => typeof v === 'number') - ) { - this.data.set( - _tag, - new ExifUndefinedValue(new Uint8Array(value as number[])) - ); - } - break; - case ExifValueType.sshort: - if ( - Array.isArray(value) && - value.length === tagCount && - (value as Array).every((v) => typeof v === 'number') - ) { - this.data.set( - _tag, - new ExifSShortValue(new Int16Array(value as number[])) - ); - } else if (typeof value === 'number' && tagCount === 1) { - this.data.set(_tag, new ExifSShortValue(value)); - } - break; - case ExifValueType.slong: - if ( - Array.isArray(value) && - value.length === tagCount && - (value as Array).every((v) => typeof v === 'number') - ) { - this.data.set( - _tag, - new ExifSLongValue(new Int32Array(value as number[])) - ); - } else if (typeof value === 'number' && tagCount === 1) { - this.data.set(_tag, new ExifSLongValue(value)); - } - break; - case ExifValueType.srational: - if ( - Array.isArray(value) && - value.length === tagCount && - (value as Array).every((v) => v instanceof Rational) - ) { - this.data.set( - _tag, - new ExifSRationalValue(value as Rational[]) - ); - } else if ( - tagCount === 1 && - Array.isArray(value) && - value.length === 2 && - (value as Array).every((v) => typeof v === 'number') - ) { - const r = new Rational( - (value as number[])[0], - (value as number[])[1] - ); - this.data.set(_tag, new ExifSRationalValue(r)); - } else if (tagCount === 1 && value instanceof Rational) { - this.data.set(_tag, new ExifSRationalValue(value)); - } else if ( - Array.isArray(value) && - value.length === tagCount && - (value as Array).every( - (v) => - Array.isArray(v) && - v.length >= 2 && - v.every((sv) => typeof sv === 'number') - ) - ) { - const array = new Array(); - for (let i = 0; i < value.length; i++) { - const subarray = value[i]; - if ( - Array.isArray(subarray) && - subarray.length >= 2 && - subarray.every((el) => typeof el === 'number') - ) { - array.push(new Rational(subarray[0], subarray[1])); - } - } - this.data.set(_tag, new ExifSRationalValue(array)); - } - break; - case ExifValueType.single: - if ( - Array.isArray(value) && - value.length === tagCount && - (value as Array).every((v) => typeof v === 'number') - ) { - this.data.set( - _tag, - new ExifSingleValue(new Float32Array(value as number[])) - ); - } else if (typeof value === 'number' && tagCount === 1) { - this.data.set(_tag, new ExifSingleValue(value)); - } - break; - case ExifValueType.double: - if ( - Array.isArray(value) && - value.length === tagCount && - (value as Array).every((v) => typeof v === 'number') - ) { - this.data.set( - _tag, - new ExifDoubleValue(new Float64Array(value as number[])) - ); - } else if (typeof value === 'number' && tagCount === 1) { - this.data.set(_tag, new ExifDoubleValue(value)); - } - break; - case ExifValueType.none: - break; - } - } - } - } - } -} diff --git a/src/exif/exif-tag.ts b/src/exif/exif-tag.ts index ad7a65e..570b9b3 100644 --- a/src/exif/exif-tag.ts +++ b/src/exif/exif-tag.ts @@ -1,10 +1,10 @@ /** @format */ -import { ExifValueType } from './exif-value-type'; +import { IfdValueType } from './ifd-value-type'; export interface ExifTagInitOptions { name: string; - type?: ExifValueType; + type?: IfdValueType; count?: number; } @@ -14,20 +14,20 @@ export class ExifTag { return this._name; } - private readonly _type: ExifValueType; - public get type(): ExifValueType { + private readonly _type: IfdValueType; + public get type(): IfdValueType { return this._type; } - private _count: number; - public get count(): number { + private _count?: number; + public get count(): number | undefined { return this._count; } - constructor(options: ExifTagInitOptions) { - this._name = options.name; - this._type = options.type ?? ExifValueType.none; - this._count = options.count ?? 1; + constructor(opt: ExifTagInitOptions) { + this._name = opt.name; + this._type = opt.type ?? IfdValueType.none; + this._count = opt.count; } } @@ -237,210 +237,233 @@ export const ExifImageTags = new Map([ 0x000b, new ExifTag({ name: 'ProcessingSoftware', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x00fe, new ExifTag({ name: 'SubfileType', - type: ExifValueType.long, + type: IfdValueType.long, + count: 1, }), ], [ 0x00ff, new ExifTag({ name: 'OldSubfileType', - type: ExifValueType.long, + type: IfdValueType.long, + count: 1, }), ], [ 0x0100, new ExifTag({ name: 'ImageWidth', - type: ExifValueType.long, + type: IfdValueType.long, + count: 1, }), ], [ 0x0101, new ExifTag({ name: 'ImageLength', - type: ExifValueType.long, + type: IfdValueType.long, + count: 1, }), ], [ 0x0102, new ExifTag({ name: 'BitsPerSample', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x0103, new ExifTag({ name: 'Compression', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x0106, new ExifTag({ name: 'PhotometricInterpretation', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x0107, new ExifTag({ name: 'Thresholding', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x0108, new ExifTag({ name: 'CellWidth', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x0109, new ExifTag({ name: 'CellLength', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x010a, new ExifTag({ name: 'FillOrder', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x010d, new ExifTag({ name: 'DocumentName', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x010e, new ExifTag({ name: 'ImageDescription', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x010f, new ExifTag({ name: 'Make', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x0110, new ExifTag({ name: 'Model', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x0111, new ExifTag({ name: 'StripOffsets', - type: ExifValueType.long, + type: IfdValueType.long, }), ], [ 0x0112, new ExifTag({ name: 'Orientation', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x0115, new ExifTag({ name: 'SamplesPerPixel', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x0116, new ExifTag({ name: 'RowsPerStrip', - type: ExifValueType.long, + type: IfdValueType.long, + count: 1, }), ], [ 0x0117, new ExifTag({ name: 'StripByteCounts', - type: ExifValueType.long, + type: IfdValueType.long, + count: 1, }), ], [ 0x0118, new ExifTag({ name: 'MinSampleValue', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x0119, new ExifTag({ name: 'MaxSampleValue', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x011a, new ExifTag({ name: 'XResolution', - type: ExifValueType.rational, + type: IfdValueType.rational, + count: 1, }), ], [ 0x011b, new ExifTag({ name: 'YResolution', - type: ExifValueType.rational, + type: IfdValueType.rational, + count: 1, }), ], [ 0x011c, new ExifTag({ name: 'PlanarConfiguration', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x011d, new ExifTag({ name: 'PageName', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x011e, new ExifTag({ name: 'XPosition', - type: ExifValueType.rational, + type: IfdValueType.rational, + count: 1, }), ], [ 0x011f, new ExifTag({ name: 'YPosition', - type: ExifValueType.rational, + type: IfdValueType.rational, + count: 1, }), ], [ 0x0122, new ExifTag({ name: 'GrayResponseUnit', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ @@ -465,14 +488,15 @@ export const ExifImageTags = new Map([ 0x0128, new ExifTag({ name: 'ResolutionUnit', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x0129, new ExifTag({ name: 'PageNumber', - type: ExifValueType.short, + type: IfdValueType.short, count: 2, }), ], @@ -486,7 +510,7 @@ export const ExifImageTags = new Map([ 0x012d, new ExifTag({ name: 'TransferFunction', - type: ExifValueType.short, + type: IfdValueType.short, count: 768, }), ], @@ -494,42 +518,43 @@ export const ExifImageTags = new Map([ 0x0131, new ExifTag({ name: 'Software', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x0132, new ExifTag({ name: 'DateTime', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x013b, new ExifTag({ name: 'Artist', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x013c, new ExifTag({ name: 'HostComputer', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x013d, new ExifTag({ name: 'Predictor', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x013e, new ExifTag({ name: 'WhitePoint', - type: ExifValueType.rational, + type: IfdValueType.rational, count: 2, }), ], @@ -537,7 +562,7 @@ export const ExifImageTags = new Map([ 0x013f, new ExifTag({ name: 'PrimaryChromaticities', - type: ExifValueType.rational, + type: IfdValueType.rational, count: 6, }), ], @@ -545,13 +570,14 @@ export const ExifImageTags = new Map([ 0x0140, new ExifTag({ name: 'ColorMap', + type: IfdValueType.short, }), ], [ 0x0141, new ExifTag({ name: 'HalftoneHints', - type: ExifValueType.short, + type: IfdValueType.short, count: 2, }), ], @@ -559,20 +585,23 @@ export const ExifImageTags = new Map([ 0x0142, new ExifTag({ name: 'TileWidth', - type: ExifValueType.long, + type: IfdValueType.long, + count: 1, }), ], [ 0x0143, new ExifTag({ name: 'TileLength', - type: ExifValueType.long, + type: IfdValueType.long, + count: 1, }), ], [ 0x0144, new ExifTag({ name: 'TileOffsets', + type: IfdValueType.long, }), ], [ @@ -627,7 +656,7 @@ export const ExifImageTags = new Map([ 0x0151, new ExifTag({ name: 'TargetPrinter', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ @@ -640,6 +669,8 @@ export const ExifImageTags = new Map([ 0x0153, new ExifTag({ name: 'SampleFormat', + type: IfdValueType.short, + count: 1, }), ], [ @@ -688,7 +719,7 @@ export const ExifImageTags = new Map([ 0x0211, new ExifTag({ name: 'YCbCrCoefficients', - type: ExifValueType.rational, + type: IfdValueType.rational, count: 3, }), ], @@ -696,21 +727,23 @@ export const ExifImageTags = new Map([ 0x0212, new ExifTag({ name: 'YCbCrSubSampling', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x0213, new ExifTag({ name: 'YCbCrPositioning', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x0214, new ExifTag({ name: 'ReferenceBlackWhite', - type: ExifValueType.rational, + type: IfdValueType.rational, count: 6, }), ], @@ -719,14 +752,16 @@ export const ExifImageTags = new Map([ 0x02bc, new ExifTag({ name: 'ApplicationNotes', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x4746, new ExifTag({ name: 'Rating', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ @@ -751,28 +786,30 @@ export const ExifImageTags = new Map([ 0x8298, new ExifTag({ name: 'Copyright', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x829a, new ExifTag({ name: 'ExposureTime', - type: ExifValueType.rational, + type: IfdValueType.rational, + count: 1, }), ], [ 0x829d, new ExifTag({ name: 'FNumber', - type: ExifValueType.rational, + type: IfdValueType.rational, }), ], [ 0x83bb, new ExifTag({ name: 'IPTC-NAA', - type: ExifValueType.long, + type: IfdValueType.long, + count: 1, }), ], // Exif Tags @@ -792,14 +829,14 @@ export const ExifImageTags = new Map([ 0x8822, new ExifTag({ name: 'ExposureProgram', - type: ExifValueType.short, + type: IfdValueType.short, }), ], [ 0x8824, new ExifTag({ name: 'SpectralSensitivity', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], // GPS tags @@ -813,7 +850,8 @@ export const ExifImageTags = new Map([ 0x8827, new ExifTag({ name: 'ISOSpeed', - type: ExifValueType.long, + type: IfdValueType.long, + count: 1, }), ], [ @@ -826,69 +864,73 @@ export const ExifImageTags = new Map([ 0x8830, new ExifTag({ name: 'SensitivityType', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x8832, new ExifTag({ name: 'RecommendedExposureIndex', - type: ExifValueType.long, + type: IfdValueType.long, + count: 1, }), ], [ 0x8833, new ExifTag({ name: 'ISOSpeed', - type: ExifValueType.long, + type: IfdValueType.long, + count: 1, }), ], [ 0x9000, new ExifTag({ name: 'ExifVersion', - type: ExifValueType.undefined, + type: IfdValueType.undefined, }), ], [ 0x9003, new ExifTag({ name: 'DateTimeOriginal', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x9004, new ExifTag({ name: 'DateTimeDigitized', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x9010, new ExifTag({ name: 'OffsetTime', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x9011, new ExifTag({ name: 'OffsetTimeOriginal', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x9012, new ExifTag({ name: 'OffsetTimeDigitized', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x9101, new ExifTag({ name: 'ComponentsConfiguration', + type: IfdValueType.undefined, }), ], [ @@ -967,12 +1009,14 @@ export const ExifImageTags = new Map([ 0x927c, new ExifTag({ name: 'MakerNote', + type: IfdValueType.undefined, }), ], [ 0x9286, new ExifTag({ name: 'UserComment', + type: IfdValueType.undefined, }), ], [ @@ -1033,21 +1077,24 @@ export const ExifImageTags = new Map([ 0xa001, new ExifTag({ name: 'ColorSpace', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0xa002, new ExifTag({ name: 'ExifImageWidth', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0xa003, new ExifTag({ name: 'ExifImageLength', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ @@ -1211,14 +1258,14 @@ export const ExifImageTags = new Map([ 0xa430, new ExifTag({ name: 'CameraOwnerName', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0xa431, new ExifTag({ name: 'BodySerialNumber', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ @@ -1231,28 +1278,29 @@ export const ExifImageTags = new Map([ 0xa433, new ExifTag({ name: 'LensMake', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0xa434, new ExifTag({ name: 'LensModel', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0xa435, new ExifTag({ name: 'LensSerialNumber', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0xa500, new ExifTag({ name: 'Gamma', - type: ExifValueType.rational, + type: IfdValueType.rational, + count: 1, }), ], [ @@ -1277,14 +1325,14 @@ export const ExifImageTags = new Map([ 0xfde8, new ExifTag({ name: 'OwnerName', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0xfde9, new ExifTag({ name: 'SerialNumber', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], ]); @@ -1294,35 +1342,37 @@ export const ExifInteropTags = new Map([ 0x0001, new ExifTag({ name: 'InteropIndex', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x0002, new ExifTag({ name: 'InteropVersion', - type: ExifValueType.undefined, + type: IfdValueType.undefined, }), ], [ 0x1000, new ExifTag({ name: 'RelatedImageFileFormat', - type: ExifValueType.ascii, + type: IfdValueType.ascii, }), ], [ 0x1001, new ExifTag({ name: 'RelatedImageWidth', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], [ 0x1002, new ExifTag({ name: 'RelatedImageLength', - type: ExifValueType.short, + type: IfdValueType.short, + count: 1, }), ], ]); diff --git a/src/exif/exif-value-type.ts b/src/exif/exif-value-type.ts deleted file mode 100644 index c82e074..0000000 --- a/src/exif/exif-value-type.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** @format */ - -export enum ExifValueType { - none, - byte, - ascii, - short, - long, - rational, - sbyte, - undefined, - sshort, - slong, - srational, - single, - double, -} - -export const ExifValueTypeString = [ - 'None', - 'Byte', - 'Ascii', - 'Short', - 'Long', - 'Rational', - 'SByte', - 'Undefined', - 'SShort', - 'SLong', - 'SRational', - 'Single', - 'Double', -]; - -export const ExifValueTypeSize = [0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8]; - -export function getExifValueTypeString(type: ExifValueType) { - return ExifValueTypeString[type]; -} - -export function getExifValueTypeSize(type: ExifValueType, length = 1) { - return ExifValueTypeSize[type] * length; -} diff --git a/src/exif/exif-value/exif-ascii-value.ts b/src/exif/exif-value/exif-ascii-value.ts deleted file mode 100644 index a0f7ce5..0000000 --- a/src/exif/exif-value/exif-ascii-value.ts +++ /dev/null @@ -1,58 +0,0 @@ -/** @format */ - -import { InputBuffer } from '../../common/input-buffer'; -import { OutputBuffer } from '../../common/output-buffer'; -import { TextCodec } from '../../common/text-codec'; -import { ExifValue } from './exif-value'; -import { ExifValueType } from '../exif-value-type'; - -export class ExifAsciiValue extends ExifValue { - private value: string; - - public get type(): ExifValueType { - return ExifValueType.ascii; - } - - public get length(): number { - return this.value.length; - } - - constructor(value: number[] | string) { - super(); - if (typeof value === 'string') { - this.value = value; - } else { - this.value = String.fromCharCode(...value); - } - } - - public static fromData(data: InputBuffer, length: number) { - const value = length > 0 ? data.readString(length - 1) : data.readString(); - return new ExifAsciiValue(value); - } - - public toData(): Uint8Array { - return TextCodec.getCodePoints(this.value); - } - - public toString(): string { - return this.value; - } - - public write(out: OutputBuffer): void { - const bytes = TextCodec.getCodePoints(this.value); - out.writeBytes(bytes); - } - - public setString(v: string): void { - this.value = v; - } - - public equalsTo(other: unknown): boolean { - return other instanceof ExifAsciiValue && this.length === other.length; - } - - public clone(): ExifValue { - return new ExifAsciiValue(this.value); - } -} diff --git a/src/exif/exif-value/exif-byte-value.ts b/src/exif/exif-value/exif-byte-value.ts deleted file mode 100644 index ada243c..0000000 --- a/src/exif/exif-value/exif-byte-value.ts +++ /dev/null @@ -1,61 +0,0 @@ -/** @format */ - -import { InputBuffer } from '../../common/input-buffer'; -import { OutputBuffer } from '../../common/output-buffer'; -import { ExifValue } from './exif-value'; -import { ExifValueType } from '../exif-value-type'; - -export class ExifByteValue extends ExifValue { - private value: Uint8Array; - - public get type(): ExifValueType { - return ExifValueType.byte; - } - - public get length(): number { - return this.value.length; - } - - constructor(value: Uint8Array | number) { - super(); - if (typeof value === 'number') { - this.value = new Uint8Array(1); - this.value[0] = value; - } else { - this.value = value; - } - } - - public static fromData(data: InputBuffer, offset?: number, length?: number) { - const array = data.toUint8Array(offset, length); - return new ExifByteValue(array); - } - - public toInt(index = 0): number { - return this.value[index]; - } - - public toData(): Uint8Array { - return this.value; - } - - public toString(): string { - return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`; - } - - public write(out: OutputBuffer): void { - out.writeBytes(this.value); - } - - public setInt(v: number, index = 0): void { - this.value[index] = v; - } - - public equalsTo(other: unknown): boolean { - return other instanceof ExifByteValue && this.length === other.length; - } - - public clone(): ExifValue { - return new ExifByteValue(this.value); - } -} diff --git a/src/exif/exif-value/exif-double-value.ts b/src/exif/exif-value/exif-double-value.ts deleted file mode 100644 index 3382a3a..0000000 --- a/src/exif/exif-value/exif-double-value.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** @format */ - -import { InputBuffer } from '../../common/input-buffer'; -import { OutputBuffer } from '../../common/output-buffer'; -import { ExifValue } from './exif-value'; -import { ExifValueType } from '../exif-value-type'; - -export class ExifDoubleValue extends ExifValue { - private value: Float64Array; - - public get type(): ExifValueType { - return ExifValueType.double; - } - - public get length(): number { - return this.value.length; - } - - constructor(value: Float64Array | number) { - super(); - if (typeof value === 'number') { - this.value = new Float64Array(1); - this.value[0] = value; - } else { - this.value = value; - } - } - - public static fromData(data: InputBuffer, length: number) { - const array = new Float64Array(length); - for (let i = 0; i < length; ++i) { - array[i] = data.readFloat64(); - } - return new ExifDoubleValue(array); - } - - public toDouble(index = 0): number { - return this.value[index]; - } - - public toData(): Uint8Array { - return new Uint8Array(this.value.buffer); - } - - public toString(): string { - return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`; - } - - public write(out: OutputBuffer): void { - for (let i = 0, l = this.value.length; i < l; ++i) { - out.writeFloat64(this.value[i]); - } - } - - public setDouble(v: number, index = 0): void { - this.value[index] = v; - } - - public equalsTo(other: unknown): boolean { - return other instanceof ExifDoubleValue && this.length === other.length; - } - - public clone(): ExifValue { - return new ExifDoubleValue(this.value); - } -} diff --git a/src/exif/exif-value/exif-long-value.ts b/src/exif/exif-value/exif-long-value.ts deleted file mode 100644 index 6b6da64..0000000 --- a/src/exif/exif-value/exif-long-value.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** @format */ - -import { InputBuffer } from '../../common/input-buffer'; -import { OutputBuffer } from '../../common/output-buffer'; -import { ExifValue } from './exif-value'; -import { ExifValueType } from '../exif-value-type'; - -export class ExifLongValue extends ExifValue { - private value: Uint32Array; - - public get type(): ExifValueType { - return ExifValueType.long; - } - - public get length(): number { - return this.value.length; - } - - constructor(value: Uint32Array | number) { - super(); - if (typeof value === 'number') { - this.value = new Uint32Array(1); - this.value[0] = value; - } else { - this.value = value; - } - } - - public static fromData(data: InputBuffer, length: number) { - const array = new Uint32Array(length); - for (let i = 0; i < length; ++i) { - array[i] = data.readUint32(); - } - return new ExifLongValue(array); - } - - public toInt(index = 0): number { - return this.value[index]; - } - - public toData(): Uint8Array { - return new Uint8Array(this.value.buffer); - } - - public toString(): string { - return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`; - } - - public write(out: OutputBuffer): void { - for (let i = 0, l = this.value.length; i < l; ++i) { - out.writeUint32(this.value[i]); - } - } - - public setInt(v: number, index = 0): void { - this.value[index] = v; - } - - public equalsTo(other: unknown): boolean { - return other instanceof ExifLongValue && this.length === other.length; - } - - public clone(): ExifValue { - return new ExifLongValue(this.value); - } -} diff --git a/src/exif/exif-value/exif-rational-value.ts b/src/exif/exif-value/exif-rational-value.ts deleted file mode 100644 index 90ffe5a..0000000 --- a/src/exif/exif-value/exif-rational-value.ts +++ /dev/null @@ -1,77 +0,0 @@ -/** @format */ - -import { InputBuffer } from '../../common/input-buffer'; -import { OutputBuffer } from '../../common/output-buffer'; -import { ExifValue } from './exif-value'; -import { ExifValueType } from '../exif-value-type'; -import { Rational } from '../../common/rational'; - -export class ExifRationalValue extends ExifValue { - private value: Rational[]; - - public get type(): ExifValueType { - return ExifValueType.rational; - } - - public get length(): number { - return this.value.length; - } - - constructor(value: Rational[] | Rational) { - super(); - if (value instanceof Rational) { - this.value = [value]; - } else { - this.value = value; - } - } - - public static fromData(data: InputBuffer, length: number) { - const array = new Array(); - for (let i = 0; i < length; i++) { - const r = new Rational(data.readUint32(), data.readUint32()); - array.push(r); - } - return new ExifRationalValue(array); - } - - public static from(other: Rational) { - const r = new Rational(other.numerator, other.denominator); - return new ExifRationalValue(r); - } - - public toInt(index = 0): number { - return this.value[index].asInt; - } - - public toDouble(index = 0): number { - return this.value[index].asDouble; - } - - public toRational(index = 0): Rational { - return this.value[index]; - } - - public toString(): string { - return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`; - } - - public write(out: OutputBuffer): void { - for (const v of this.value) { - out.writeUint32(v.numerator); - out.writeUint32(v.denominator); - } - } - - public setRational(numerator: number, denomitator: number, index = 0): void { - this.value[index] = new Rational(numerator, denomitator); - } - - public equalsTo(other: unknown): boolean { - return other instanceof ExifRationalValue && this.length === other.length; - } - - public clone(): ExifValue { - return new ExifRationalValue(this.value); - } -} diff --git a/src/exif/exif-value/exif-sbyte-value.ts b/src/exif/exif-value/exif-sbyte-value.ts deleted file mode 100644 index c822986..0000000 --- a/src/exif/exif-value/exif-sbyte-value.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** @format */ - -import { InputBuffer } from '../../common/input-buffer'; -import { OutputBuffer } from '../../common/output-buffer'; -import { ExifValue } from './exif-value'; -import { ExifValueType } from '../exif-value-type'; - -export class ExifSByteValue extends ExifValue { - private value: Int8Array; - - public get type(): ExifValueType { - return ExifValueType.sbyte; - } - - public get length(): number { - return this.value.length; - } - - constructor(value: Int8Array | number) { - super(); - if (typeof value === 'number') { - this.value = new Int8Array(1); - this.value[0] = value; - } else { - this.value = value; - } - } - - public static fromData(data: InputBuffer, offset?: number, length?: number) { - const array = new Int8Array( - new Int8Array(data.toUint8Array(offset, length).buffer) - ); - return new ExifSByteValue(array); - } - - public toInt(index = 0): number { - return this.value[index]; - } - - public toData(): Uint8Array { - return new Uint8Array(this.value.buffer); - } - - public toString(): string { - return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`; - } - - public write(out: OutputBuffer): void { - out.writeBytes(new Uint8Array(this.value.buffer)); - } - - public setInt(v: number, index = 0): void { - this.value[index] = v; - } - - public equalsTo(other: unknown): boolean { - return other instanceof ExifSByteValue && this.length === other.length; - } - - public clone(): ExifValue { - return new ExifSByteValue(this.value); - } -} diff --git a/src/exif/exif-value/exif-short-value.ts b/src/exif/exif-value/exif-short-value.ts deleted file mode 100644 index bc969c3..0000000 --- a/src/exif/exif-value/exif-short-value.ts +++ /dev/null @@ -1,62 +0,0 @@ -/** @format */ - -import { InputBuffer } from '../../common/input-buffer'; -import { OutputBuffer } from '../../common/output-buffer'; -import { ExifValue } from './exif-value'; -import { ExifValueType } from '../exif-value-type'; - -export class ExifShortValue extends ExifValue { - private value: Uint16Array; - - public get type(): ExifValueType { - return ExifValueType.short; - } - - public get length(): number { - return this.value.length; - } - - constructor(value: Uint16Array | number) { - super(); - if (typeof value === 'number') { - this.value = new Uint16Array(1); - this.value[0] = value; - } else { - this.value = value; - } - } - - public static fromData(data: InputBuffer, length: number) { - const array = new Uint16Array(length); - for (let i = 0; i < length; ++i) { - array[i] = data.readUint16(); - } - return new ExifShortValue(array); - } - - public toInt(index = 0): number { - return this.value[index]; - } - - public toString(): string { - return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`; - } - - public write(out: OutputBuffer): void { - for (let i = 0, l = this.value.length; i < l; ++i) { - out.writeUint16(this.value[i]); - } - } - - public setInt(v: number, index = 0): void { - this.value[index] = v; - } - - public equalsTo(other: unknown): boolean { - return other instanceof ExifShortValue && this.length === other.length; - } - - public clone(): ExifValue { - return new ExifShortValue(this.value); - } -} diff --git a/src/exif/exif-value/exif-single-value.ts b/src/exif/exif-value/exif-single-value.ts deleted file mode 100644 index a07b182..0000000 --- a/src/exif/exif-value/exif-single-value.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** @format */ - -import { InputBuffer } from '../../common/input-buffer'; -import { OutputBuffer } from '../../common/output-buffer'; -import { ExifValue } from './exif-value'; -import { ExifValueType } from '../exif-value-type'; - -export class ExifSingleValue extends ExifValue { - private value: Float32Array; - - public get type(): ExifValueType { - return ExifValueType.single; - } - - public get length(): number { - return this.value.length; - } - - constructor(value: Float32Array | number) { - super(); - if (typeof value === 'number') { - this.value = new Float32Array(1); - this.value[0] = value; - } else { - this.value = value; - } - } - - public static fromData(data: InputBuffer, length: number) { - const array = new Float32Array(length); - for (let i = 0; i < length; ++i) { - array[i] = data.readFloat32(); - } - return new ExifSingleValue(array); - } - - public toDouble(index = 0): number { - return this.value[index]; - } - - public toData(): Uint8Array { - return new Uint8Array(this.value.buffer); - } - - public toString(): string { - return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`; - } - - public write(out: OutputBuffer): void { - for (let i = 0, l = this.value.length; i < l; ++i) { - out.writeFloat32(this.value[i]); - } - } - - public setDouble(v: number, index = 0): void { - this.value[index] = v; - } - - public equalsTo(other: unknown): boolean { - return other instanceof ExifSingleValue && this.length === other.length; - } - - public clone(): ExifValue { - return new ExifSingleValue(this.value); - } -} diff --git a/src/exif/exif-value/exif-slong-value.ts b/src/exif/exif-value/exif-slong-value.ts deleted file mode 100644 index 235917f..0000000 --- a/src/exif/exif-value/exif-slong-value.ts +++ /dev/null @@ -1,67 +0,0 @@ -/** @format */ - -import { InputBuffer } from '../../common/input-buffer'; -import { OutputBuffer } from '../../common/output-buffer'; -import { ExifValue } from './exif-value'; -import { ExifValueType } from '../exif-value-type'; -import { BitOperators } from '../../common/bit-operators'; - -export class ExifSLongValue extends ExifValue { - private value: Int32Array; - - public get type(): ExifValueType { - return ExifValueType.slong; - } - - public get length(): number { - return this.value.length; - } - - constructor(value: Int32Array | number) { - super(); - if (typeof value === 'number') { - this.value = new Int32Array(1); - this.value[0] = value; - } else { - this.value = value; - } - } - - public static fromData(data: InputBuffer, length: number) { - const array = new Int32Array(length); - for (let i = 0; i < length; ++i) { - array[i] = data.readInt32(); - } - return new ExifSLongValue(array); - } - - public toInt(index = 0): number { - return this.value[index]; - } - - public toData(): Uint8Array { - return new Uint8Array(this.value.buffer); - } - - public toString(): string { - return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`; - } - - public write(out: OutputBuffer): void { - for (let i = 0, l = this.value.length; i < l; ++i) { - out.writeUint32(BitOperators.toUint32(this.value[i])); - } - } - - public setInt(v: number, index = 0): void { - this.value[index] = v; - } - - public equalsTo(other: unknown): boolean { - return other instanceof ExifSLongValue && this.length === other.length; - } - - public clone(): ExifValue { - return new ExifSLongValue(this.value); - } -} diff --git a/src/exif/exif-value/exif-srational-value.ts b/src/exif/exif-value/exif-srational-value.ts deleted file mode 100644 index 8ab5f79..0000000 --- a/src/exif/exif-value/exif-srational-value.ts +++ /dev/null @@ -1,78 +0,0 @@ -/** @format */ - -import { InputBuffer } from '../../common/input-buffer'; -import { OutputBuffer } from '../../common/output-buffer'; -import { ExifValue } from './exif-value'; -import { ExifValueType } from '../exif-value-type'; -import { BitOperators } from '../../common/bit-operators'; -import { Rational } from '../../common/rational'; - -export class ExifSRationalValue extends ExifValue { - private value: Rational[]; - - public get type(): ExifValueType { - return ExifValueType.srational; - } - - public get length(): number { - return this.value.length; - } - - constructor(value: Rational[] | Rational) { - super(); - if (value instanceof Rational) { - this.value = [value]; - } else { - this.value = value; - } - } - - public static fromData(data: InputBuffer, length: number) { - const array = new Array(); - for (let i = 0; i < length; i++) { - const r = new Rational(data.readInt32(), data.readInt32()); - array.push(r); - } - return new ExifSRationalValue(array); - } - - public static from(other: Rational) { - const r = new Rational(other.numerator, other.denominator); - return new ExifSRationalValue(r); - } - - public toInt(index = 0): number { - return this.value[index].asInt; - } - - public toDouble(index = 0): number { - return this.value[index].asDouble; - } - - public toRational(index = 0): Rational { - return this.value[index]; - } - - public toString(): string { - return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`; - } - - public write(out: OutputBuffer): void { - for (const v of this.value) { - out.writeUint32(BitOperators.toUint32(v.numerator)); - out.writeUint32(BitOperators.toUint32(v.denominator)); - } - } - - public setRational(numerator: number, denomitator: number, index = 0): void { - this.value[index] = new Rational(numerator, denomitator); - } - - public equalsTo(other: unknown): boolean { - return other instanceof ExifSRationalValue && this.length === other.length; - } - - public clone(): ExifValue { - return new ExifSRationalValue(this.value); - } -} diff --git a/src/exif/exif-value/exif-sshort-value.ts b/src/exif/exif-value/exif-sshort-value.ts deleted file mode 100644 index ea56a15..0000000 --- a/src/exif/exif-value/exif-sshort-value.ts +++ /dev/null @@ -1,69 +0,0 @@ -/** @format */ - -import { InputBuffer } from '../../common/input-buffer'; -import { OutputBuffer } from '../../common/output-buffer'; -import { ExifValue } from './exif-value'; -import { ExifValueType } from '../exif-value-type'; - -export class ExifSShortValue extends ExifValue { - private value: Int16Array; - - public get type(): ExifValueType { - return ExifValueType.sshort; - } - - public get length(): number { - return this.value.length; - } - - constructor(value: Int16Array | number) { - super(); - if (typeof value === 'number') { - this.value = new Int16Array(1); - this.value[0] = value; - } else { - this.value = value; - } - } - - public static fromData(data: InputBuffer, length: number) { - const array = new Int16Array(length); - for (let i = 0; i < length; ++i) { - array[i] = data.readInt16(); - } - return new ExifSShortValue(array); - } - - public toInt(index = 0): number { - return this.value[index]; - } - - public toData(): Uint8Array { - return new Uint8Array(this.value.buffer); - } - - public toString(): string { - return this.value.length === 1 ? `${this.value[0]}` : `${this.value}`; - } - - public write(out: OutputBuffer): void { - const v = new Int16Array(1); - const vb = new Uint16Array(v.buffer); - for (let i = 0, l = this.value.length; i < l; ++i) { - v[0] = this.value[i]; - out.writeUint16(vb[0]); - } - } - - public setInt(v: number, index = 0): void { - this.value[index] = v; - } - - public equalsTo(other: unknown): boolean { - return other instanceof ExifSShortValue && this.length === other.length; - } - - public clone(): ExifValue { - return new ExifSShortValue(this.value); - } -} diff --git a/src/exif/exif-value/exif-undefined-value.ts b/src/exif/exif-value/exif-undefined-value.ts deleted file mode 100644 index 18eab9f..0000000 --- a/src/exif/exif-value/exif-undefined-value.ts +++ /dev/null @@ -1,53 +0,0 @@ -/** @format */ - -import { InputBuffer } from '../../common/input-buffer'; -import { OutputBuffer } from '../../common/output-buffer'; -import { ExifValue } from './exif-value'; -import { ExifValueType } from '../exif-value-type'; - -export class ExifUndefinedValue extends ExifValue { - private value: Uint8Array; - - public get type(): ExifValueType { - return ExifValueType.undefined; - } - - public get length(): number { - return this.value.length; - } - - constructor(value: Uint8Array | number) { - super(); - if (typeof value === 'number') { - this.value = new Uint8Array(1); - this.value[0] = value; - } else { - this.value = value; - } - } - - public static fromData(data: InputBuffer, offset?: number, length?: number) { - const array = new Uint8Array(data.toUint8Array(offset, length)); - return new ExifUndefinedValue(array); - } - - public toData(): Uint8Array { - return this.value; - } - - public toString(): string { - return ''; - } - - public write(out: OutputBuffer): void { - out.writeBytes(this.value); - } - - public equalsTo(other: unknown): boolean { - return other instanceof ExifUndefinedValue && this.length === other.length; - } - - public clone(): ExifValue { - return new ExifUndefinedValue(this.value); - } -} diff --git a/src/exif/exif-ifd-container.ts b/src/exif/ifd-container.ts similarity index 58% rename from src/exif/exif-ifd-container.ts rename to src/exif/ifd-container.ts index 79da49f..af450a0 100644 --- a/src/exif/exif-ifd-container.ts +++ b/src/exif/ifd-container.ts @@ -1,15 +1,15 @@ /** @format */ -import { ExifIFD } from './exif-ifd'; +import { IfdDirectory } from './ifd-directory'; -export class ExifIFDContainer { - protected directories: Map; +export class IfdContainer { + protected directories: Map; public get keys(): IterableIterator { return this.directories.keys(); } - public get values(): IterableIterator { + public get values(): IterableIterator { return this.directories.values(); } @@ -29,22 +29,23 @@ export class ExifIFDContainer { return true; } - constructor(directories?: Map) { - this.directories = directories ?? new Map(); + constructor(directories?: Map) { + this.directories = directories ?? new Map(); } - public static from(other: ExifIFDContainer) { - return new ExifIFDContainer(other.directories); + public static from(other: IfdContainer) { + const dirs = new Map(other.directories); + return new IfdContainer(dirs); } public has(key: string): boolean { return this.directories.has(key); } - public get(ifdName: string): ExifIFD { + public get(ifdName: string): IfdDirectory { let ifd = this.directories.get(ifdName); if (ifd === undefined) { - ifd = new ExifIFD(); + ifd = new IfdDirectory(); this.directories.set(ifdName, ifd); return ifd; } else { @@ -52,7 +53,7 @@ export class ExifIFDContainer { } } - public set(ifdName: string, value: ExifIFD): void { + public set(ifdName: string, value: IfdDirectory): void { this.directories.set(ifdName, value); } diff --git a/src/exif/ifd-directory.ts b/src/exif/ifd-directory.ts new file mode 100644 index 0000000..591c18a --- /dev/null +++ b/src/exif/ifd-directory.ts @@ -0,0 +1,490 @@ +/** @format */ + +import { Rational } from '../common/rational'; +import { ExifImageTags, ExifTagNameToID } from './exif-tag'; +import { IfdValueType } from './ifd-value-type'; +import { IfdContainer } from './ifd-container'; +import { IfdValue } from './ifd-value/ifd-value'; +import { IfdAsciiValue } from './ifd-value/ifd-ascii-value'; +import { IfdShortValue } from './ifd-value/ifd-short-value'; +import { IfdRationalValue } from './ifd-value/ifd-rational-value'; +import { IfdByteValue } from './ifd-value/ifd-byte-value'; +import { IfdLongValue } from './ifd-value/ifd-long-value'; +import { IfdSByteValue } from './ifd-value/ifd-sbyte-value'; +import { IfdUndefinedValue } from './ifd-value/ifd-undefined-value'; +import { IfdSShortValue } from './ifd-value/ifd-sshort-value'; +import { IfdSLongValue } from './ifd-value/ifd-slong-value'; +import { IfdSRationalValue } from './ifd-value/ifd-srational-value'; +import { IfdSingleValue } from './ifd-value/ifd-single-value'; +import { IfdDoubleValue } from './ifd-value/ifd-double-value'; +import { TypedArray } from '../common/typings'; +import { StringUtils } from '../common/string-utils'; +import { ArrayUtils } from '../common/array-utils'; + +export class IfdDirectory { + private readonly _data: Map; + + private readonly _sub = new IfdContainer(); + public get sub(): IfdContainer { + return this._sub; + } + + public get keys(): IterableIterator { + return this._data.keys(); + } + + public get values(): IterableIterator { + return this._data.values(); + } + + public get size(): number { + return this._data.size; + } + + public get isEmpty(): boolean { + return this._data.size === 0 && this._sub.isEmpty; + } + + public get hasUserComment(): boolean { + return this._data.has(0x9286); + } + + public get userComment(): string | undefined { + const data = this._data.get(0x9286)?.toData(); + return data !== undefined + ? StringUtils.utf8Decoder.decode(data) + : undefined; + } + + public set userComment(v: string | undefined) { + if (v === undefined) { + this._data.delete(0x9286); + } else { + const codeUnits = StringUtils.getCodePoints(v); + this._data.set(0x9286, new IfdUndefinedValue(codeUnits)); + } + } + + public get hasImageDescription(): boolean { + return this._data.has(0x010e); + } + + public get imageDescription(): string | undefined { + return this._data.get(0x010e)?.toString(); + } + + public set imageDescription(v: string | undefined) { + if (v === undefined) { + this._data.delete(0x010e); + } else { + this._data.set(0x010e, new IfdAsciiValue(v)); + } + } + + public get hasMake(): boolean { + return this._data.has(0x010f); + } + + public get make(): string | undefined { + return this._data.get(0x010f)?.toString(); + } + + public set make(v: string | undefined) { + if (v === undefined) { + this._data.delete(0x010f); + } else { + this._data.set(0x010f, new IfdAsciiValue(v)); + } + } + + public get hasModel(): boolean { + return this._data.has(0x0110); + } + + public get model(): string | undefined { + return this._data.get(0x0110)?.toString(); + } + + public set model(v: string | undefined) { + if (v === undefined) { + this._data.delete(0x0110); + } else { + this._data.set(0x0110, new IfdAsciiValue(v)); + } + } + + public get hasOrientation(): boolean { + return this._data.has(0x0112); + } + + public get orientation(): number | undefined { + return this._data.get(0x0112)?.toInt(); + } + + public set orientation(v: number | undefined) { + if (v === undefined) { + this._data.delete(0x0112); + } else { + this._data.set(0x0112, new IfdShortValue(v)); + } + } + + public get hasResolutionX(): boolean { + return this._data.has(0x011a); + } + + public get resolutionX(): Rational | undefined { + return this._data.get(0x011a)?.toRational(); + } + + public set resolutionX(v: Rational | undefined) { + if (!this.setRational(0x011a, v)) { + this._data.delete(0x011a); + } + } + + public get hasResolutionY(): boolean { + return this._data.has(0x011b); + } + + public get resolutionY(): Rational | undefined { + return this._data.get(0x011b)?.toRational(); + } + + public set resolutionY(v: Rational | undefined) { + if (!this.setRational(0x011b, v)) { + this._data.delete(0x011b); + } + } + + public get hasResolutionUnit(): boolean { + return this._data.has(0x0128); + } + + public get resolutionUnit(): number | undefined { + return this._data.get(0x0128)?.toInt(); + } + + public set resolutionUnit(v: number | undefined) { + if (v === undefined) { + this._data.delete(0x0128); + } else { + this._data.set(0x0128, new IfdShortValue(Math.trunc(v))); + } + } + + public get hasImageWidth(): boolean { + return this._data.has(0x0100); + } + + public get imageWidth(): number | undefined { + return this._data.get(0x0100)?.toInt(); + } + + public set imageWidth(v: number | undefined) { + if (v === undefined) { + this._data.delete(0x0100); + } else { + this._data.set(0x0100, new IfdShortValue(Math.trunc(v))); + } + } + + public get hasImageHeight(): boolean { + return this._data.has(0x0101); + } + + public get imageHeight(): number | undefined { + return this._data.get(0x0101)?.toInt(); + } + + public set imageHeight(v: number | undefined) { + if (v === undefined) { + this._data.delete(0x0101); + } else { + this._data.set(0x0101, new IfdShortValue(Math.trunc(v))); + } + } + + public get hasSoftware(): boolean { + return this._data.has(0x0131); + } + + public get software(): string | undefined { + return this._data.get(0x0131)?.toString(); + } + + public set software(v: string | undefined) { + if (v === undefined) { + this._data.delete(0x0131); + } else { + this._data.set(0x0131, new IfdAsciiValue(v)); + } + } + + public get hasCopyright(): boolean { + return this._data.has(0x8298); + } + + public get copyright(): string | undefined { + return this._data.get(0x8298)?.toString(); + } + + public set copyright(v: string | undefined) { + if (v === undefined) { + this._data.delete(0x8298); + } else { + this._data.set(0x8298, new IfdAsciiValue(v)); + } + } + + /** + * The size in bytes of the data written by this directory. Can be used to + * calculate end-of-block offsets. + */ + public get dataSize(): number { + const numEntries = this.size; + let dataOffset = 2 + 12 * numEntries + 4; + for (const value of this.values) { + const dataSize = value.dataSize; + if (dataSize > 4) { + dataOffset += dataSize; + } + } + // storage for sub-ifd blocks + for (const subName of this.sub.keys) { + const subIfd = this.sub.get(subName); + let subSize = 2 + 12 * subIfd.size; + for (const value of subIfd.values) { + const dataSize = value.dataSize; + if (dataSize > 4) { + subSize += dataSize; + } + } + dataOffset += subSize; + } + return dataOffset; + } + + constructor(data?: Map) { + this._data = data ?? new Map(); + } + + private setRational( + tag: number, + value: Rational | number[] | TypedArray | unknown + ): boolean { + if (value instanceof Rational) { + this._data.set(tag, IfdRationalValue.from(value)); + return true; + } else if ( + ArrayUtils.isNumArrayOrTypedArray(value) && + (value as []).length >= 2 + ) { + const r = new Rational((value as number[])[0], (value as number[])[1]); + this._data.set(tag, IfdRationalValue.from(r)); + return true; + } + return false; + } + + public static from(other: IfdDirectory): IfdDirectory { + return new IfdDirectory(new Map(other._data)); + } + + public static isArrayOfRationalNumbers(value: unknown): boolean { + return ( + Array.isArray(value) && + value.every( + (v) => ArrayUtils.isNumArrayOrTypedArray(v) && (v as []).length >= 2 + ) + ); + } + + public has(tag: number): boolean { + return this._data.has(tag); + } + + public getValue(tag: number | string): IfdValue | undefined { + let _tag: string | number | undefined = tag; + if (typeof _tag === 'string') { + _tag = ExifTagNameToID.get(_tag); + } + if (typeof _tag === 'number') { + return this._data.get(_tag); + } + return undefined; + } + + public setValue( + tag: number | string, + value: + | Rational[] + | number[] + | TypedArray + | Rational + | IfdValue + | number + | undefined + ): void { + let _tag: string | number | undefined = tag; + if (typeof _tag === 'string') { + _tag = ExifTagNameToID.get(_tag); + } + if (typeof _tag !== 'number') { + return; + } + + if (value === undefined) { + this._data.delete(_tag); + } else { + if (value instanceof IfdValue) { + this._data.set(_tag, value); + } else { + const tagInfo = ExifImageTags.get(_tag); + if (tagInfo !== undefined) { + const tagType = tagInfo.type; + switch (tagType) { + case IfdValueType.byte: + if (ArrayUtils.isNumArrayOrTypedArray(value)) { + this._data.set( + _tag, + new IfdByteValue(new Uint8Array(value as number[])) + ); + } else if (typeof value === 'number') { + this._data.set(_tag, new IfdByteValue(value)); + } + break; + case IfdValueType.ascii: + if (typeof value === 'string') { + this._data.set(_tag, new IfdAsciiValue(value)); + } + break; + case IfdValueType.short: + if (ArrayUtils.isNumArrayOrTypedArray(value)) { + this._data.set( + _tag, + new IfdShortValue(new Uint16Array(value as number[])) + ); + } else if (typeof value === 'number') { + this._data.set(_tag, new IfdShortValue(value)); + } + break; + case IfdValueType.long: + if (ArrayUtils.isNumArrayOrTypedArray(value)) { + this._data.set( + _tag, + new IfdLongValue(new Uint32Array(value as number[])) + ); + } else if (typeof value === 'number') { + this._data.set(_tag, new IfdLongValue(value)); + } + break; + case IfdValueType.rational: + if (ArrayUtils.isArrayOfRational(value)) { + this._data.set(_tag, new IfdRationalValue(value as Rational[])); + } else if ( + ArrayUtils.isNumArrayOrTypedArray(value) && + (value as []).length >= 2 + ) { + const r = new Rational( + (value as number[])[0], + (value as number[])[1] + ); + this._data.set(_tag, new IfdRationalValue(r)); + } else if (value instanceof Rational) { + this._data.set(_tag, new IfdRationalValue(value)); + } + break; + case IfdValueType.sByte: + if (ArrayUtils.isNumArrayOrTypedArray(value)) { + this._data.set( + _tag, + new IfdSByteValue(new Int8Array(value as number[])) + ); + } else if (typeof value === 'number') { + this._data.set(_tag, new IfdSByteValue(value)); + } + break; + case IfdValueType.undefined: + if (ArrayUtils.isNumArrayOrTypedArray(value)) { + this._data.set( + _tag, + new IfdUndefinedValue(new Uint8Array(value as number[])) + ); + } + break; + case IfdValueType.sShort: + if (ArrayUtils.isNumArrayOrTypedArray(value)) { + this._data.set( + _tag, + new IfdSShortValue(new Int16Array(value as number[])) + ); + } else if (typeof value === 'number') { + this._data.set(_tag, new IfdSShortValue(value)); + } + break; + case IfdValueType.sLong: + if (ArrayUtils.isNumArrayOrTypedArray(value)) { + this._data.set( + _tag, + new IfdSLongValue(new Int32Array(value as number[])) + ); + } else if (typeof value === 'number') { + this._data.set(_tag, new IfdSLongValue(value)); + } + break; + case IfdValueType.sRational: + if (ArrayUtils.isArrayOfRational(value)) { + this._data.set( + _tag, + new IfdSRationalValue(value as Rational[]) + ); + } else if ( + ArrayUtils.isNumArrayOrTypedArray(value) && + (value as []).length >= 2 + ) { + const r = new Rational( + (value as number[])[0], + (value as number[])[1] + ); + this._data.set(_tag, new IfdSRationalValue(r)); + } else if (value instanceof Rational) { + this._data.set(_tag, new IfdSRationalValue(value)); + } + break; + case IfdValueType.single: + if (ArrayUtils.isNumArrayOrTypedArray(value)) { + this._data.set( + _tag, + new IfdSingleValue(new Float32Array(value as number[])) + ); + } else if (typeof value === 'number') { + this._data.set(_tag, new IfdSingleValue(value)); + } + break; + case IfdValueType.double: + if (ArrayUtils.isNumArrayOrTypedArray(value)) { + this._data.set( + _tag, + new IfdDoubleValue(new Float64Array(value as number[])) + ); + } else if (typeof value === 'number') { + this._data.set(_tag, new IfdDoubleValue(value)); + } + break; + case IfdValueType.none: + break; + } + } + } + } + } + + public copyFrom(other: IfdDirectory): void { + other._data.forEach((value, tag) => this._data.set(tag, value.clone())); + } + + public clone(): IfdDirectory { + return IfdDirectory.from(this); + } +} diff --git a/src/exif/ifd-value-type.ts b/src/exif/ifd-value-type.ts new file mode 100644 index 0000000..60c29d3 --- /dev/null +++ b/src/exif/ifd-value-type.ts @@ -0,0 +1,27 @@ +/** @format */ + +export enum IfdValueType { + none, + byte, + ascii, + short, + long, + rational, + sByte, + undefined, + sShort, + sLong, + sRational, + single, + double, +} + +export const IfdValueTypeSize = [0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8]; + +export function getIfdValueTypeString(type: IfdValueType) { + return IfdValueType[type]; +} + +export function getIfdValueTypeSize(type: IfdValueType, length = 1) { + return IfdValueTypeSize[type] * length; +} diff --git a/src/exif/ifd-value/ifd-ascii-value.ts b/src/exif/ifd-value/ifd-ascii-value.ts new file mode 100644 index 0000000..009696d --- /dev/null +++ b/src/exif/ifd-value/ifd-ascii-value.ts @@ -0,0 +1,65 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { OutputBuffer } from '../../common/output-buffer'; +import { StringUtils } from '../../common/string-utils'; +import { IfdValue } from './ifd-value'; +import { IfdValueType } from '../ifd-value-type'; + +export class IfdAsciiValue extends IfdValue { + private _value: string; + + public get type(): IfdValueType { + return IfdValueType.ascii; + } + + public get length(): number { + const codeUnits = StringUtils.getCodePoints(this._value); + return codeUnits.length + 1; + } + + constructor(value: number[] | string) { + super(); + if (typeof value === 'string') { + this._value = value; + } else { + this._value = String.fromCharCode(...value); + } + } + + public static data(data: InputBuffer, length: number) { + // The final byte is a null terminator + const value = length > 0 ? data.readString(length - 1) : ''; + return new IfdAsciiValue(value); + } + + public toData(): Uint8Array { + return StringUtils.getCodePoints(this._value); + } + + public write(out: OutputBuffer): void { + const bytes = StringUtils.getCodePoints(this._value); + out.writeBytes(bytes); + out.writeByte(0); + } + + public setString(v: string): void { + this._value = v; + } + + public equals(other: IfdValue): boolean { + return ( + other instanceof IfdAsciiValue && + this.length === other.length && + this._value === this._value + ); + } + + public clone(): IfdValue { + return new IfdAsciiValue(this._value); + } + + public toString(): string { + return `${this.constructor.name} (${this._value})`; + } +} diff --git a/src/exif/ifd-value/ifd-byte-value.ts b/src/exif/ifd-value/ifd-byte-value.ts new file mode 100644 index 0000000..b324039 --- /dev/null +++ b/src/exif/ifd-value/ifd-byte-value.ts @@ -0,0 +1,68 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { OutputBuffer } from '../../common/output-buffer'; +import { IfdValue } from './ifd-value'; +import { IfdValueType } from '../ifd-value-type'; +import { ArrayUtils } from '../../common/array-utils'; + +export class IfdByteValue extends IfdValue { + private _value: Uint8Array; + + public get type(): IfdValueType { + return IfdValueType.byte; + } + + public get length(): number { + return this._value.length; + } + + constructor(value: Uint8Array | number) { + super(); + if (typeof value === 'number') { + this._value = new Uint8Array(1); + this._value[0] = value; + } else { + this._value = Uint8Array.from(value); + } + } + + public static data(data: InputBuffer, offset?: number, length?: number) { + const array = data.toUint8Array(offset, length); + return new IfdByteValue(array); + } + + public toInt(index = 0): number { + return this._value[index]; + } + + public toData(): Uint8Array { + return this._value; + } + + public write(out: OutputBuffer): void { + out.writeBytes(this._value); + } + + public setInt(v: number, index = 0): void { + this._value[index] = v; + } + + public equals(other: IfdValue): boolean { + return ( + other instanceof IfdByteValue && + this.length === other.length && + ArrayUtils.equals(this._value, other._value) + ); + } + + public clone(): IfdValue { + return new IfdByteValue(this._value); + } + + public toString(): string { + return `${this.constructor.name} (${ + this._value.length === 1 ? `${this._value[0]}` : `${this._value}` + })`; + } +} diff --git a/src/exif/ifd-value/ifd-double-value.ts b/src/exif/ifd-value/ifd-double-value.ts new file mode 100644 index 0000000..0b9e372 --- /dev/null +++ b/src/exif/ifd-value/ifd-double-value.ts @@ -0,0 +1,73 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { OutputBuffer } from '../../common/output-buffer'; +import { IfdValue } from './ifd-value'; +import { IfdValueType } from '../ifd-value-type'; +import { ArrayUtils } from '../../common/array-utils'; + +export class IfdDoubleValue extends IfdValue { + private _value: Float64Array; + + public get type(): IfdValueType { + return IfdValueType.double; + } + + public get length(): number { + return this._value.length; + } + + constructor(value: Float64Array | number) { + super(); + if (typeof value === 'number') { + this._value = new Float64Array(1); + this._value[0] = value; + } else { + this._value = Float64Array.from(value); + } + } + + public static data(data: InputBuffer, length: number) { + const array = new Float64Array(length); + for (let i = 0; i < length; ++i) { + array[i] = data.readFloat64(); + } + return new IfdDoubleValue(array); + } + + public toDouble(index = 0): number { + return this._value[index]; + } + + public toData(): Uint8Array { + return new Uint8Array(this._value.buffer); + } + + public write(out: OutputBuffer): void { + for (let i = 0, l = this._value.length; i < l; ++i) { + out.writeFloat64(this._value[i]); + } + } + + public setDouble(v: number, index = 0): void { + this._value[index] = v; + } + + public equals(other: IfdValue): boolean { + return ( + other instanceof IfdDoubleValue && + this.length === other.length && + ArrayUtils.equals(this._value, other._value) + ); + } + + public clone(): IfdValue { + return new IfdDoubleValue(this._value); + } + + public toString(): string { + return `${this.constructor.name} (${ + this._value.length === 1 ? `${this._value[0]}` : `${this._value}` + })`; + } +} diff --git a/src/exif/ifd-value/ifd-long-value.ts b/src/exif/ifd-value/ifd-long-value.ts new file mode 100644 index 0000000..79c4cc8 --- /dev/null +++ b/src/exif/ifd-value/ifd-long-value.ts @@ -0,0 +1,73 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { OutputBuffer } from '../../common/output-buffer'; +import { IfdValue } from './ifd-value'; +import { IfdValueType } from '../ifd-value-type'; +import { ArrayUtils } from '../../common/array-utils'; + +export class IfdLongValue extends IfdValue { + private _value: Uint32Array; + + public get type(): IfdValueType { + return IfdValueType.long; + } + + public get length(): number { + return this._value.length; + } + + constructor(value: Uint32Array | number) { + super(); + if (typeof value === 'number') { + this._value = new Uint32Array(1); + this._value[0] = value; + } else { + this._value = Uint32Array.from(value); + } + } + + public static data(data: InputBuffer, length: number) { + const array = new Uint32Array(length); + for (let i = 0; i < length; ++i) { + array[i] = data.readUint32(); + } + return new IfdLongValue(array); + } + + public toInt(index = 0): number { + return this._value[index]; + } + + public toData(): Uint8Array { + return new Uint8Array(this._value.buffer); + } + + public write(out: OutputBuffer): void { + for (let i = 0, l = this._value.length; i < l; ++i) { + out.writeUint32(this._value[i]); + } + } + + public setInt(v: number, index = 0): void { + this._value[index] = v; + } + + public equals(other: IfdValue): boolean { + return ( + other instanceof IfdLongValue && + this.length === other.length && + ArrayUtils.equals(this._value, other._value) + ); + } + + public clone(): IfdValue { + return new IfdLongValue(this._value); + } + + public toString(): string { + return `${this.constructor.name} (${ + this._value.length === 1 ? `${this._value[0]}` : `${this._value}` + })`; + } +} diff --git a/src/exif/ifd-value/ifd-rational-value.ts b/src/exif/ifd-value/ifd-rational-value.ts new file mode 100644 index 0000000..26e2e61 --- /dev/null +++ b/src/exif/ifd-value/ifd-rational-value.ts @@ -0,0 +1,84 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { OutputBuffer } from '../../common/output-buffer'; +import { IfdValue } from './ifd-value'; +import { IfdValueType } from '../ifd-value-type'; +import { Rational } from '../../common/rational'; +import { ArrayUtils } from '../../common/array-utils'; + +export class IfdRationalValue extends IfdValue { + private _value: Rational[]; + + public get type(): IfdValueType { + return IfdValueType.rational; + } + + public get length(): number { + return this._value.length; + } + + constructor(value: Rational[] | Rational) { + super(); + if (value instanceof Rational) { + this._value = [value]; + } else { + this._value = value; + } + } + + public static data(data: InputBuffer, length: number) { + const array = new Array(); + for (let i = 0; i < length; i++) { + const r = new Rational(data.readUint32(), data.readUint32()); + array.push(r); + } + return new IfdRationalValue(array); + } + + public static from(other: Rational) { + const r = new Rational(other.numerator, other.denominator); + return new IfdRationalValue(r); + } + + public toInt(index = 0): number { + return this._value[index].toInt; + } + + public toDouble(index = 0): number { + return this._value[index].toDouble; + } + + public toRational(index = 0): Rational { + return this._value[index]; + } + + public write(out: OutputBuffer): void { + for (const v of this._value) { + out.writeUint32(v.numerator); + out.writeUint32(v.denominator); + } + } + + public setRational(numerator: number, denomitator: number, index = 0): void { + this._value[index] = new Rational(numerator, denomitator); + } + + public equals(other: IfdValue): boolean { + return ( + other instanceof IfdRationalValue && + this.length === other.length && + ArrayUtils.equalsRationalArray(this._value, other._value) + ); + } + + public clone(): IfdValue { + return new IfdRationalValue(this._value); + } + + public toString(): string { + return `${this.constructor.name} (${ + this._value.length === 1 ? `${this._value[0]}` : `${this._value}` + })`; + } +} diff --git a/src/exif/ifd-value/ifd-sbyte-value.ts b/src/exif/ifd-value/ifd-sbyte-value.ts new file mode 100644 index 0000000..da36e0c --- /dev/null +++ b/src/exif/ifd-value/ifd-sbyte-value.ts @@ -0,0 +1,70 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { OutputBuffer } from '../../common/output-buffer'; +import { IfdValue } from './ifd-value'; +import { IfdValueType } from '../ifd-value-type'; +import { ArrayUtils } from '../../common/array-utils'; + +export class IfdSByteValue extends IfdValue { + private _value: Int8Array; + + public get type(): IfdValueType { + return IfdValueType.sByte; + } + + public get length(): number { + return this._value.length; + } + + constructor(value: Int8Array | number) { + super(); + if (typeof value === 'number') { + this._value = new Int8Array(1); + this._value[0] = value; + } else { + this._value = Int8Array.from(value); + } + } + + public static data(data: InputBuffer, offset?: number, length?: number) { + const array = new Int8Array( + new Int8Array(data.toUint8Array(offset, length).buffer) + ); + return new IfdSByteValue(array); + } + + public toInt(index = 0): number { + return this._value[index]; + } + + public toData(): Uint8Array { + return new Uint8Array(this._value.buffer); + } + + public write(out: OutputBuffer): void { + out.writeBytes(new Uint8Array(this._value.buffer)); + } + + public setInt(v: number, index = 0): void { + this._value[index] = v; + } + + public equals(other: IfdValue): boolean { + return ( + other instanceof IfdSByteValue && + this.length === other.length && + ArrayUtils.equals(this._value, other._value) + ); + } + + public clone(): IfdValue { + return new IfdSByteValue(this._value); + } + + public toString(): string { + return `${this.constructor.name} (${ + this._value.length === 1 ? `${this._value[0]}` : `${this._value}` + })`; + } +} diff --git a/src/exif/ifd-value/ifd-short-value.ts b/src/exif/ifd-value/ifd-short-value.ts new file mode 100644 index 0000000..fa92272 --- /dev/null +++ b/src/exif/ifd-value/ifd-short-value.ts @@ -0,0 +1,69 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { OutputBuffer } from '../../common/output-buffer'; +import { IfdValue } from './ifd-value'; +import { IfdValueType } from '../ifd-value-type'; +import { ArrayUtils } from '../../common/array-utils'; + +export class IfdShortValue extends IfdValue { + private _value: Uint16Array; + + public get type(): IfdValueType { + return IfdValueType.short; + } + + public get length(): number { + return this._value.length; + } + + constructor(value: Uint16Array | number) { + super(); + if (typeof value === 'number') { + this._value = new Uint16Array(1); + this._value[0] = value; + } else { + this._value = Uint16Array.from(value); + } + } + + public static data(data: InputBuffer, length: number) { + const array = new Uint16Array(length); + for (let i = 0; i < length; ++i) { + array[i] = data.readUint16(); + } + return new IfdShortValue(array); + } + + public toInt(index = 0): number { + return this._value[index]; + } + + public write(out: OutputBuffer): void { + for (let i = 0, l = this._value.length; i < l; ++i) { + out.writeUint16(this._value[i]); + } + } + + public setInt(v: number, index = 0): void { + this._value[index] = v; + } + + public equals(other: IfdValue): boolean { + return ( + other instanceof IfdShortValue && + this.length === other.length && + ArrayUtils.equals(this._value, other._value) + ); + } + + public clone(): IfdValue { + return new IfdShortValue(this._value); + } + + public toString(): string { + return `${this.constructor.name} (${ + this._value.length === 1 ? `${this._value[0]}` : `${this._value}` + })`; + } +} diff --git a/src/exif/ifd-value/ifd-single-value.ts b/src/exif/ifd-value/ifd-single-value.ts new file mode 100644 index 0000000..2f05c78 --- /dev/null +++ b/src/exif/ifd-value/ifd-single-value.ts @@ -0,0 +1,73 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { OutputBuffer } from '../../common/output-buffer'; +import { IfdValue } from './ifd-value'; +import { IfdValueType } from '../ifd-value-type'; +import { ArrayUtils } from '../../common/array-utils'; + +export class IfdSingleValue extends IfdValue { + private _value: Float32Array; + + public get type(): IfdValueType { + return IfdValueType.single; + } + + public get length(): number { + return this._value.length; + } + + constructor(value: Float32Array | number) { + super(); + if (typeof value === 'number') { + this._value = new Float32Array(1); + this._value[0] = value; + } else { + this._value = Float32Array.from(value); + } + } + + public static data(data: InputBuffer, length: number) { + const array = new Float32Array(length); + for (let i = 0; i < length; ++i) { + array[i] = data.readFloat32(); + } + return new IfdSingleValue(array); + } + + public toDouble(index = 0): number { + return this._value[index]; + } + + public toData(): Uint8Array { + return new Uint8Array(this._value.buffer); + } + + public write(out: OutputBuffer): void { + for (let i = 0, l = this._value.length; i < l; ++i) { + out.writeFloat32(this._value[i]); + } + } + + public setDouble(v: number, index = 0): void { + this._value[index] = v; + } + + public equals(other: IfdValue): boolean { + return ( + other instanceof IfdSingleValue && + this.length === other.length && + ArrayUtils.equals(this._value, other._value) + ); + } + + public clone(): IfdValue { + return new IfdSingleValue(this._value); + } + + public toString(): string { + return `${this.constructor.name} (${ + this._value.length === 1 ? `${this._value[0]}` : `${this._value}` + })`; + } +} diff --git a/src/exif/ifd-value/ifd-slong-value.ts b/src/exif/ifd-value/ifd-slong-value.ts new file mode 100644 index 0000000..c43cc01 --- /dev/null +++ b/src/exif/ifd-value/ifd-slong-value.ts @@ -0,0 +1,74 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { OutputBuffer } from '../../common/output-buffer'; +import { IfdValue } from './ifd-value'; +import { IfdValueType } from '../ifd-value-type'; +import { BitUtils } from '../../common/bit-utils'; +import { ArrayUtils } from '../../common/array-utils'; + +export class IfdSLongValue extends IfdValue { + private _value: Int32Array; + + public get type(): IfdValueType { + return IfdValueType.sLong; + } + + public get length(): number { + return this._value.length; + } + + constructor(value: Int32Array | number) { + super(); + if (typeof value === 'number') { + this._value = new Int32Array(1); + this._value[0] = value; + } else { + this._value = Int32Array.from(value); + } + } + + public static data(data: InputBuffer, length: number) { + const array = new Int32Array(length); + for (let i = 0; i < length; ++i) { + array[i] = data.readInt32(); + } + return new IfdSLongValue(array); + } + + public toInt(index = 0): number { + return this._value[index]; + } + + public toData(): Uint8Array { + return new Uint8Array(this._value.buffer); + } + + public write(out: OutputBuffer): void { + for (let i = 0, l = this._value.length; i < l; ++i) { + out.writeUint32(BitUtils.int32ToUint32(this._value[i])); + } + } + + public setInt(v: number, index = 0): void { + this._value[index] = v; + } + + public equals(other: IfdValue): boolean { + return ( + other instanceof IfdSLongValue && + this.length === other.length && + ArrayUtils.equals(this._value, other._value) + ); + } + + public clone(): IfdValue { + return new IfdSLongValue(this._value); + } + + public toString(): string { + return `${this.constructor.name} (${ + this._value.length === 1 ? `${this._value[0]}` : `${this._value}` + })`; + } +} diff --git a/src/exif/ifd-value/ifd-srational-value.ts b/src/exif/ifd-value/ifd-srational-value.ts new file mode 100644 index 0000000..b8cf4a5 --- /dev/null +++ b/src/exif/ifd-value/ifd-srational-value.ts @@ -0,0 +1,85 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { OutputBuffer } from '../../common/output-buffer'; +import { IfdValue } from './ifd-value'; +import { IfdValueType } from '../ifd-value-type'; +import { BitUtils } from '../../common/bit-utils'; +import { Rational } from '../../common/rational'; +import { ArrayUtils } from '../../common/array-utils'; + +export class IfdSRationalValue extends IfdValue { + private _value: Rational[]; + + public get type(): IfdValueType { + return IfdValueType.sRational; + } + + public get length(): number { + return this._value.length; + } + + constructor(value: Rational[] | Rational) { + super(); + if (value instanceof Rational) { + this._value = [value]; + } else { + this._value = value; + } + } + + public static data(data: InputBuffer, length: number) { + const array = new Array(); + for (let i = 0; i < length; i++) { + const r = new Rational(data.readInt32(), data.readInt32()); + array.push(r); + } + return new IfdSRationalValue(array); + } + + public static from(other: Rational) { + const r = new Rational(other.numerator, other.denominator); + return new IfdSRationalValue(r); + } + + public toInt(index = 0): number { + return this._value[index].toInt; + } + + public toDouble(index = 0): number { + return this._value[index].toDouble; + } + + public toRational(index = 0): Rational { + return this._value[index]; + } + + public write(out: OutputBuffer): void { + for (const v of this._value) { + out.writeUint32(BitUtils.int32ToUint32(v.numerator)); + out.writeUint32(BitUtils.int32ToUint32(v.denominator)); + } + } + + public setRational(numerator: number, denomitator: number, index = 0): void { + this._value[index] = new Rational(numerator, denomitator); + } + + public equals(other: IfdValue): boolean { + return ( + other instanceof IfdSRationalValue && + this.length === other.length && + ArrayUtils.equalsRationalArray(this._value, other._value) + ); + } + + public clone(): IfdValue { + return new IfdSRationalValue(this._value); + } + + public toString(): string { + return `${this.constructor.name} (${ + this._value.length === 1 ? `${this._value[0]}` : `${this._value}` + })`; + } +} diff --git a/src/exif/ifd-value/ifd-sshort-value.ts b/src/exif/ifd-value/ifd-sshort-value.ts new file mode 100644 index 0000000..ce35875 --- /dev/null +++ b/src/exif/ifd-value/ifd-sshort-value.ts @@ -0,0 +1,76 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { OutputBuffer } from '../../common/output-buffer'; +import { IfdValue } from './ifd-value'; +import { IfdValueType } from '../ifd-value-type'; +import { ArrayUtils } from '../../common/array-utils'; + +export class IfdSShortValue extends IfdValue { + private _value: Int16Array; + + public get type(): IfdValueType { + return IfdValueType.sShort; + } + + public get length(): number { + return this._value.length; + } + + constructor(value: Int16Array | number) { + super(); + if (typeof value === 'number') { + this._value = new Int16Array(1); + this._value[0] = value; + } else { + this._value = Int16Array.from(value); + } + } + + public static data(data: InputBuffer, length: number) { + const array = new Int16Array(length); + for (let i = 0; i < length; ++i) { + array[i] = data.readInt16(); + } + return new IfdSShortValue(array); + } + + public toInt(index = 0): number { + return this._value[index]; + } + + public toData(): Uint8Array { + return new Uint8Array(this._value.buffer); + } + + public write(out: OutputBuffer): void { + const v = new Int16Array(1); + const vb = new Uint16Array(v.buffer); + for (let i = 0, l = this._value.length; i < l; ++i) { + v[0] = this._value[i]; + out.writeUint16(vb[0]); + } + } + + public setInt(v: number, index = 0): void { + this._value[index] = v; + } + + public equals(other: IfdValue): boolean { + return ( + other instanceof IfdSShortValue && + this.length === other.length && + ArrayUtils.equals(this._value, other._value) + ); + } + + public clone(): IfdValue { + return new IfdSShortValue(this._value); + } + + public toString(): string { + return `${this.constructor.name} (${ + this._value.length === 1 ? `${this._value[0]}` : `${this._value}` + })`; + } +} diff --git a/src/exif/ifd-value/ifd-undefined-value.ts b/src/exif/ifd-value/ifd-undefined-value.ts new file mode 100644 index 0000000..9702453 --- /dev/null +++ b/src/exif/ifd-value/ifd-undefined-value.ts @@ -0,0 +1,58 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { OutputBuffer } from '../../common/output-buffer'; +import { IfdValue } from './ifd-value'; +import { IfdValueType } from '../ifd-value-type'; +import { ArrayUtils } from '../../common/array-utils'; + +export class IfdUndefinedValue extends IfdValue { + private _value: Uint8Array; + + public get type(): IfdValueType { + return IfdValueType.undefined; + } + + public get length(): number { + return this._value.length; + } + + constructor(value: Uint8Array | number) { + super(); + if (typeof value === 'number') { + this._value = new Uint8Array(1); + this._value[0] = value; + } else { + this._value = value; + } + } + + public static data(data: InputBuffer, offset?: number, length?: number) { + const array = new Uint8Array(data.toUint8Array(offset, length)); + return new IfdUndefinedValue(array); + } + + public toData(): Uint8Array { + return this._value; + } + + public write(out: OutputBuffer): void { + out.writeBytes(this._value); + } + + public equals(other: IfdValue): boolean { + return ( + other instanceof IfdUndefinedValue && + this.length === other.length && + ArrayUtils.equals(this._value, other._value) + ); + } + + public clone(): IfdValue { + return new IfdUndefinedValue(this._value); + } + + public toString(): string { + return `${this.constructor.name} (undefined)`; + } +} diff --git a/src/exif/exif-value/exif-value.ts b/src/exif/ifd-value/ifd-value.ts similarity index 63% rename from src/exif/exif-value/exif-value.ts rename to src/exif/ifd-value/ifd-value.ts index 7be21c9..42b5386 100644 --- a/src/exif/exif-value/exif-value.ts +++ b/src/exif/ifd-value/ifd-value.ts @@ -2,16 +2,16 @@ import { OutputBuffer } from '../../common/output-buffer'; import { Rational } from '../../common/rational'; -import { ImageError } from '../../error/image-error'; +import { LibError } from '../../error/lib-error'; import { - ExifValueType, - getExifValueTypeSize, - getExifValueTypeString, -} from '../exif-value-type'; - -export abstract class ExifValue { - public get type(): ExifValueType { - return ExifValueType.none; + getIfdValueTypeSize, + getIfdValueTypeString, + IfdValueType, +} from '../ifd-value-type'; + +export abstract class IfdValue { + public get type(): IfdValueType { + return IfdValueType.none; } public get length(): number { @@ -19,11 +19,11 @@ export abstract class ExifValue { } public get dataSize(): number { - return getExifValueTypeSize(this.type, this.length); + return getIfdValueTypeSize(this.type, this.length); } public get typeString(): string { - return getExifValueTypeString(this.type); + return getIfdValueTypeString(this.type); } public toBool(_index?: number): boolean { @@ -38,12 +38,12 @@ export abstract class ExifValue { return 0; } - public toRational(_index?: number): Rational { - return new Rational(0, 1); + public toData(): Uint8Array { + return new Uint8Array(); } - public toString(): string { - return ''; + public toRational(_index?: number): Rational { + return new Rational(0, 1); } public write(_out: OutputBuffer): void {} @@ -62,11 +62,15 @@ export abstract class ExifValue { public setString(_v: string): void {} - public equalsTo(_other: ExifValue): boolean { + public equals(_other: IfdValue): boolean { return false; } - public clone(): ExifValue { - throw new ImageError('Cannot be copied.'); + public clone(): IfdValue { + throw new LibError('Cannot be copied.'); + } + + public toString(): string { + return `${this.constructor.name}`; } } diff --git a/src/filter/adjust-color-options.ts b/src/filter/adjust-color-options.ts deleted file mode 100644 index 09db583..0000000 --- a/src/filter/adjust-color-options.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** @format */ - -import { MemoryImage } from '../common/memory-image'; - -export interface AdjustColorOptions { - src: MemoryImage; - blacks?: number; - whites?: number; - mids?: number; - contrast?: number; - saturation?: number; - brightness?: number; - gamma?: number; - exposure?: number; - hue?: number; - amount?: number; -} diff --git a/src/filter/color-offset-options.ts b/src/filter/color-offset-options.ts deleted file mode 100644 index bdc9604..0000000 --- a/src/filter/color-offset-options.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** @format */ - -import { MemoryImage } from '../common/memory-image'; - -export interface ColorOffsetOptions { - src: MemoryImage; - red?: number; - green?: number; - blue?: number; - alpha?: number; -} diff --git a/src/filter/convolution-options.ts b/src/filter/convolution-options.ts deleted file mode 100644 index 54ac491..0000000 --- a/src/filter/convolution-options.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** @format */ - -import { MemoryImage } from '../common/memory-image'; - -export interface ConvolutionOptions { - src: MemoryImage; - filter: number[]; - div?: number; - offset?: number; -} diff --git a/src/filter/dither-kernel.ts b/src/filter/dither-kernel.ts new file mode 100644 index 0000000..246e31c --- /dev/null +++ b/src/filter/dither-kernel.ts @@ -0,0 +1,57 @@ +/** @format */ + +/** + * The pattern to use for dithering + */ +export enum DitherKernel { + none, + falseFloydSteinberg, + floydSteinberg, + stucki, + atkinson, +} + +export const DitherKernels = [ + [ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + ], + // FalseFloydSteinberg + [ + [3 / 8, 1, 0], + [3 / 8, 0, 1], + [2 / 8, 1, 1], + ], + // FloydSteinberg + [ + [7 / 16, 1, 0], + [3 / 16, -1, 1], + [5 / 16, 0, 1], + [1 / 16, 1, 1], + ], + // Stucki + [ + [8 / 42, 1, 0], + [4 / 42, 2, 0], + [2 / 42, -2, 1], + [4 / 42, -1, 1], + [8 / 42, 0, 1], + [4 / 42, 1, 1], + [2 / 42, 2, 1], + [1 / 42, -2, 2], + [2 / 42, -1, 2], + [4 / 42, 0, 2], + [2 / 42, 1, 2], + [1 / 42, 2, 2], + ], + //Atkinson: + [ + [1 / 8, 1, 0], + [1 / 8, 2, 0], + [1 / 8, -1, 1], + [1 / 8, 0, 1], + [1 / 8, 1, 1], + [1 / 8, 0, 2], + ], +]; diff --git a/src/filter/filter.ts b/src/filter/filter.ts new file mode 100644 index 0000000..af4f868 --- /dev/null +++ b/src/filter/filter.ts @@ -0,0 +1,2588 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color } from '../color/color'; +import { ColorRgba8 } from '../color/color-rgba8'; +import { Interpolation } from '../common/interpolation'; +import { MathUtils } from '../common/math-utils'; +import { NeuralQuantizer } from '../image/neural-quantizer'; +import { OctreeQuantizer } from '../image/octree-quantizer'; +import { Quantizer } from '../image/quantizer'; +import { RandomUtils } from '../common/random-utils'; +import { Draw } from '../draw/draw'; +import { MemoryImage } from '../image/image'; +import { DitherKernel, DitherKernels } from './dither-kernel'; +import { NoiseType } from './noise-type'; +import { PixelateMode } from './pixelate-mode'; +import { QuantizeMethod } from './quantize-method'; +import { SeparableKernel } from './separable-kernel'; +import { ColorUtils } from '../color/color-utils'; + +interface ContrastCache { + lastContrast: number; + contrast: Uint8Array; +} + +export interface AdjustColorOptions { + image: MemoryImage; + blacks?: Color; + whites?: Color; + mids?: Color; + contrast?: number; + saturation?: number; + brightness?: number; + gamma?: number; + exposure?: number; + hue?: number; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface BillboardOptions { + image: MemoryImage; + grid?: number; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface BleachBypassOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface BulgeDistortionOptions { + image: MemoryImage; + centerX?: number; + centerY?: number; + radius?: number; + scale?: number; + interpolation?: Interpolation; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface BumpToNormalOptions { + image: MemoryImage; + strength?: number; +} + +export interface ChromaticAberrationOptions { + image: MemoryImage; + shift?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface ColorHalftone { + image: MemoryImage; + amount?: number; + centerX?: number; + centerY?: number; + angle?: number; + size?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface ColorOffsetOptions { + image: MemoryImage; + red?: number; + green?: number; + blue?: number; + alpha?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface ContrastOptions { + image: MemoryImage; + contrast: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface ConvolutionOptions { + image: MemoryImage; + filter: number[]; + div?: number; + offset?: number; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface CopyImageChannelsOptions { + image: MemoryImage; + from: MemoryImage; + scaled?: boolean; + red?: Channel; + green?: Channel; + blue?: Channel; + alpha?: Channel; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface DitherImageOptions { + image: MemoryImage; + quantizer?: Quantizer; + kernel?: DitherKernel; + serpentine?: boolean; +} + +export interface DotScreenOptions { + image: MemoryImage; + angle?: number; + size?: number; + centerX?: number; + centerY?: number; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface DropShadowOptions { + image: MemoryImage; + hShadow: number; + vShadow: number; + blur: number; + shadowColor?: Color; +} + +export interface EdgeGlowOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface EmbossOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface GammaOptions { + image: MemoryImage; + gamma: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface GaussianBlurOptions { + image: MemoryImage; + radius: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface GrayscaleOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface HdrToLdrOptions { + image: MemoryImage; + exposure?: number; +} + +export interface HexagonPixelateOptions { + image: MemoryImage; + centerX?: number; + centerY?: number; + size?: number; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface InvertOptions { + image: MemoryImage; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface LuminanceThresholdOptions { + image: MemoryImage; + threshold?: number; + outputColor?: boolean; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface MonochromeOptions { + image: MemoryImage; + color?: Color; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface NoiseOptions { + image: MemoryImage; + sigma: number; + type?: NoiseType; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface NormalizeOptions { + image: MemoryImage; + min: number; + max: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface PixelateOptions { + image: MemoryImage; + size: number; + mode?: PixelateMode; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface QuantizeOptions { + image: MemoryImage; + numberOfColors?: number; + method?: QuantizeMethod; + dither?: DitherKernel; + ditherSerpentine?: boolean; +} + +export interface ReinhardToneMapOptions { + image: MemoryImage; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface RemapColorsOptions { + image: MemoryImage; + red?: Channel; + green?: Channel; + blue?: Channel; + alpha?: Channel; +} + +export interface ScaleRgbaOptions { + image: MemoryImage; + scale: Color; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface SeparableConvolutionOptions { + image: MemoryImage; + kernel: SeparableKernel; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface SepiaOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface SketchOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface SmoothOptions { + image: MemoryImage; + weight: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface SobelOptions { + image: MemoryImage; + amount?: number; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface StretchDistortionOptions { + image: MemoryImage; + centerX?: number; + centerY?: number; + interpolation?: Interpolation; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export interface VignetteOptions { + image: MemoryImage; + start?: number; + end?: number; + amount?: number; + color?: Color; + maskChannel?: Channel; + mask?: MemoryImage; +} + +export abstract class Filter { + private static _contrastCache?: ContrastCache; + private static readonly _gaussianKernelCache: Map = + new Map(); + + /** + * Adjust the color of the **image** using various color transformations. + * + * **blacks** defines the black level of the image, as a color. + * + * **whites** defines the white level of the image, as a color. + * + * **mids** defines the mid level of hte image, as a color. + * + * **contrast** increases (> 1) / decreases (< 1) the contrast of the image by + * pushing colors away/toward neutral gray, where at 0 the image is entirely + * neutral gray (0 contrast), 1, the image is not adjusted and > 1 the + * image increases contrast. + * + * **saturation** increases (> 1) / decreases (< 1) the saturation of the image + * by pushing colors away/toward their grayscale value, where 0 is grayscale + * and 1 is the original image, and > 1 the image becomes more saturated. + * + * **brightness** is a constant scalar of the image colors. At 0 the image + * is black, 1 unmodified, and > 1 the image becomes brighter. + * + * **gamma** is an exponential scalar of the image colors. At < 1 the image + * becomes brighter, and > 1 the image becomes darker. A **gamma** of 1/2.2 + * will convert the image colors to linear color space. + * + * **exposure** is an exponential scalar of the image as rgb* pow(2, exposure). + * At 0, the image is unmodified; as the exposure increases, the image + * brightens. + * + * **hue** shifts the hue component of the image colors in degrees. A **hue** of + * 0 will have no affect, and a **hue** of 45 will shift the hue of all colors + * by 45 degrees. + * + * **amount** controls how much affect this filter has on the **image**, where + * 0 has no effect and 1 has full effect. + * + */ + public static adjustColor(opt: AdjustColorOptions): MemoryImage { + const maskChannel = opt.maskChannel ?? Channel.luminance; + const contrast = + opt.contrast !== undefined + ? MathUtils.clamp(opt.contrast, 0, 1) + : undefined; + const saturation = + opt.saturation !== undefined + ? MathUtils.clamp(opt.saturation, 0, 1) + : undefined; + const brightness = + opt.brightness !== undefined + ? MathUtils.clamp(opt.brightness, 0, 1) + : undefined; + const gamma = + opt.gamma !== undefined ? MathUtils.clamp(opt.gamma, 0, 1000) : undefined; + let exposure = + opt.exposure !== undefined + ? MathUtils.clamp(opt.exposure, 0, 1000) + : undefined; + const amount = MathUtils.clamp(opt.amount ?? 1, 0, 1000); + let hue = opt.hue; + + if (amount === 0) { + return opt.image; + } + + const degToRad = 0.0174532925; + const avgLumR = 0.5; + const avgLumG = 0.5; + const avgLumB = 0.5; + const lumCoeffR = 0.2125; + const lumCoeffG = 0.7154; + const lumCoeffB = 0.0721; + + const useBlacksWhitesMids = + opt.blacks !== undefined || + opt.whites !== undefined || + opt.mids !== undefined; + let br = 0; + let bg = 0; + let bb = 0; + let wr = 0; + let wg = 0; + let wb = 0; + let mr = 0; + let mg = 0; + let mb = 0; + if (useBlacksWhitesMids) { + br = opt.blacks?.rNormalized ?? 0; + bg = opt.blacks?.gNormalized ?? 0; + bb = opt.blacks?.bNormalized ?? 0; + + wr = opt.whites?.rNormalized ?? 0; + wg = opt.whites?.gNormalized ?? 0; + wb = opt.whites?.bNormalized ?? 0; + + mr = opt.mids?.rNormalized ?? 0; + mg = opt.mids?.gNormalized ?? 0; + mb = opt.mids?.bNormalized ?? 0; + + mr = 1 / (1 + 2 * (mr - 0.5)); + mg = 1 / (1 + 2 * (mg - 0.5)); + mb = 1 / (1 + 2 * (mb - 0.5)); + } + + const invSaturation = + saturation !== undefined ? 1 - MathUtils.clamp(saturation, 0, 1) : 0; + const invContrast = + contrast !== undefined ? 1 - MathUtils.clamp(contrast, 0, 1) : 0; + + if (exposure !== undefined) { + exposure = Math.pow(2, exposure); + } + + let hueR = 0; + let hueG = 0; + let hueB = 0; + if (hue !== undefined) { + hue *= degToRad; + const s = Math.sin(hue); + const c = Math.cos(hue); + + hueR = (2 * c) / 3.0; + hueG = (-Math.sqrt(3.0) * s - c) / 3.0; + hueB = (Math.sqrt(3.0) * s - c + 1.0) / 3.0; + } + + for (const frame of opt.image.frames) { + for (const p of frame) { + const or = p.rNormalized; + const og = p.gNormalized; + const ob = p.bNormalized; + + let r = or; + let g = og; + let b = ob; + + if (useBlacksWhitesMids) { + r = Math.pow((r + br) * wr, mr); + g = Math.pow((g + bg) * wg, mg); + b = Math.pow((b + bb) * wb, mb); + } + + if (brightness !== undefined && brightness !== 1.0) { + const tb = MathUtils.clamp(brightness, 0, 1000); + r *= tb; + g *= tb; + b *= tb; + } + + if (saturation !== undefined) { + const lum = r * lumCoeffR + g * lumCoeffG + b * lumCoeffB; + + r = lum * invSaturation + r * saturation; + g = lum * invSaturation + g * saturation; + b = lum * invSaturation + b * saturation; + } + + if (contrast !== undefined) { + r = avgLumR * invContrast + r * contrast; + g = avgLumG * invContrast + g * contrast; + b = avgLumB * invContrast + b * contrast; + } + + if (gamma !== undefined) { + r = Math.pow(r, gamma); + g = Math.pow(g, gamma); + b = Math.pow(b, gamma); + } + + if (exposure !== undefined) { + r *= exposure; + g *= exposure; + b *= exposure; + } + + if (hue !== undefined && hue !== 0.0) { + const hr = r * hueR + g * hueG + b * hueB; + const hg = r * hueB + g * hueR + b * hueG; + const hb = r * hueG + g * hueB + b * hueR; + + r = hr; + g = hg; + b = hb; + } + + const msk = + opt.mask?.getPixel(p.x, p.y).getChannelNormalized(maskChannel) ?? 1; + const blend = msk * amount; + + r = MathUtils.mix(or, r, blend); + g = MathUtils.mix(og, g, blend); + b = MathUtils.mix(ob, b, blend); + + p.rNormalized = r; + p.gNormalized = g; + p.bNormalized = b; + } + } + + return opt.image; + } + + /** + * Apply the billboard filter to the image. + */ + public static billboard(opt: BillboardOptions): MemoryImage { + const grid = opt.grid ?? 10; + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + // Math.pow(0.45, 2); + const rs = 0.2025; + + for (const frame of opt.image.frames) { + const w = frame.width; + const h = frame.height; + const aspect = w / h; + const stepX = 0.0015625; + const stepY = 0.0015625 * aspect; + const orig = frame.clone({ + skipAnimation: true, + }); + for (const p of frame) { + const uvX = p.x / (w - 1); + const uvY = p.y / (h - 1); + + const offX = Math.floor(uvX / (grid * stepX)); + const offY = Math.floor(uvY / (grid * stepY)); + + const x2 = Math.floor(offX * grid * stepX * (w - 1)); + const y2 = Math.floor(offY * grid * stepY * (h - 1)); + + if (x2 >= w || y2 >= h) { + continue; + } + + const op = orig.getPixel(x2, y2); + + const prcX = MathUtils.fract(uvX / (grid * stepX)); + const prcY = MathUtils.fract(uvY / (grid * stepY)); + const pwX = Math.pow(Math.abs(prcX - 0.5), 2); + const pwY = Math.pow(Math.abs(prcY - 0.5), 2); + + let r = op.r / p.maxChannelValue; + let g = op.g / p.maxChannelValue; + let b = op.b / p.maxChannelValue; + + const gr = MathUtils.smoothStep(rs - 0.1, rs + 0.1, pwX + pwY); + const y = (r + g + b) / 3.0; + + const ls = 0.3; + const lb = Math.ceil(y / ls); + const lf = ls * lb + 0.3; + + r = MathUtils.mix(lf * r, 0.1, gr); + g = MathUtils.mix(lf * g, 0.1, gr); + b = MathUtils.mix(lf * b, 0.1, gr); + + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + + p.r = MathUtils.mix(p.r, r * p.maxChannelValue, mx); + p.g = MathUtils.mix(p.g, g * p.maxChannelValue, mx); + p.b = MathUtils.mix(p.b, b * p.maxChannelValue, mx); + } + } + return opt.image; + } + + public static bleachBypass(opt: BleachBypassOptions): MemoryImage { + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + const luminanceR = 0.2125; + const luminanceG = 0.7154; + const luminanceB = 0.0721; + for (const frame of opt.image.frames) { + for (const p of frame) { + const r = p.rNormalized; + const g = p.gNormalized; + const b = p.bNormalized; + const lr = r * luminanceR; + const lg = g * luminanceG; + const lb = b * luminanceB; + const l = lr + lg + lb; + + const mixAmount = MathUtils.clamp((l - 0.45) * 10, 0, 1); + const branch1R = 2 * r * l; + const branch1G = 2 * g * l; + const branch1B = 2 * b * l; + const branch2R = 1 - 2 * (1 - r) * (1 - l); + const branch2G = 1 - 2 * (1 - g) * (1 - l); + const branch2B = 1 - 2 * (1 - b) * (1 - l); + + const msk = + opt.mask?.getPixel(p.x, p.y).getChannelNormalized(maskChannel) ?? 1; + const mx = msk * amount; + + if (mx !== 1) { + const nr = + MathUtils.mix(branch1R, branch2R, mixAmount) * p.maxChannelValue; + const ng = + MathUtils.mix(branch1G, branch2G, mixAmount) * p.maxChannelValue; + const nb = + MathUtils.mix(branch1B, branch2B, mixAmount) * p.maxChannelValue; + p.r = MathUtils.mix(p.r, nr, amount); + p.g = MathUtils.mix(p.g, ng, amount); + p.b = MathUtils.mix(p.b, nb, amount); + } else { + p.rNormalized = MathUtils.mix(branch1R, branch2R, mixAmount); + p.gNormalized = MathUtils.mix(branch1G, branch2G, mixAmount); + p.bNormalized = MathUtils.mix(branch1B, branch2B, mixAmount); + } + } + } + return opt.image; + } + + public static bulgeDistortion(opt: BulgeDistortionOptions): MemoryImage { + const scale = opt.scale ?? 0.5; + const interpolation = opt.interpolation ?? Interpolation.nearest; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + for (const frame of opt.image.frames) { + const orig = frame.clone({ + skipAnimation: true, + }); + const w = frame.width; + const h = frame.height; + const cx = opt.centerX ?? Math.trunc(w / 2); + const cy = opt.centerY ?? Math.trunc(h / 2); + const rad = opt.radius ?? Math.trunc(Math.min(w, h) / 2); + const radSqr = rad * rad; + for (const p of frame) { + let x = p.x; + let y = p.y; + const deltaX = cx - x; + const deltaY = cy - y; + const dist = deltaX * deltaX + deltaY * deltaY; + x -= cx; + y -= cy; + if (dist < radSqr) { + const percent = 1 - ((radSqr - dist) / radSqr) * scale; + const percentSqr = percent * percent; + x *= percentSqr; + y *= percentSqr; + } + x += cx; + y += cy; + + const p2 = orig.getPixelInterpolate(x, y, interpolation); + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + + if (msk === undefined) { + p.set(p2); + } else { + p.r = MathUtils.mix(p.r, p2.r, msk); + p.g = MathUtils.mix(p.g, p2.g, msk); + p.b = MathUtils.mix(p.b, p2.b, msk); + p.a = MathUtils.mix(p.a, p2.a, msk); + } + } + } + return opt.image; + } + + /** + * Generate a normal map from a heightfield bump image. + * + * The red channel of the **image** is used as an input, 0 represents a low + * height and 1 a high value. The optional **strength** parameter allows to set + * the strength of the normal image. + */ + public static bumpToNormal(opt: BumpToNormalOptions): MemoryImage { + const strength = opt.strength ?? 2; + + const dest = MemoryImage.from(opt.image); + + const mx = opt.image.maxChannelValue; + for (const frame of opt.image.frames) { + for (let y = 0; y < frame.height; ++y) { + for (let x = 0; x < frame.width; ++x) { + const height = frame.getPixel(x, y).r / mx; + let du = + (height - + frame.getPixel(x < frame.width - 1 ? x + 1 : x, y).r / mx) * + strength; + let dv = + (height - + frame.getPixel(x, y < frame.height - 1 ? y + 1 : y).r / mx) * + strength; + const z = Math.abs(du) + Math.abs(dv); + + if (z > 1) { + du /= z; + dv /= z; + } + + const dw = Math.sqrt(1 - du * du - dv * dv); + const nX = du * 0.5 + 0.5; + const nY = dv * 0.5 + 0.5; + const nZ = dw; + + dest.frames[frame.frameIndex].setPixelRgb( + x, + y, + nX * mx, + nY * mx, + nZ * mx + ); + } + } + } + + return dest; + } + + /** + * Apply chromatic aberration filter to the image. + */ + public static chromaticAberration( + opt: ChromaticAberrationOptions + ): MemoryImage { + const shift = opt.shift ?? 5; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + for (const frame of opt.image.frames) { + const orig = frame.clone({ + skipAnimation: true, + }); + const w = frame.width - 1; + for (const p of frame) { + const shiftLeft = MathUtils.clamp(p.x - shift, 0, w); + const shiftRight = MathUtils.clamp(p.x + shift, 0, w); + const lc = orig.getPixel(shiftLeft, p.y); + const rc = orig.getPixel(shiftRight, p.y); + + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + + if (msk === undefined) { + p.r = rc.r; + p.b = lc.b; + } else { + p.r = MathUtils.mix(p.r, rc.r, msk); + p.b = MathUtils.mix(p.b, lc.b, msk); + } + } + } + return opt.image; + } + + /** + * Apply color halftone filter to the image. + */ + public static colorHalftone(opt: ColorHalftone): MemoryImage { + const amount = opt.amount ?? 1; + let angle = opt.angle ?? 1; + const size = opt.size ?? 5; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + angle *= 0.0174533; + + const pattern = ( + x: number, + y: number, + cx: number, + cy: number, + angle: number + ): number => { + const scale = 3.14159 / size; + const s = Math.sin(angle); + const c = Math.cos(angle); + const tx = x - cx; + const ty = y - cy; + const px = (c * tx - s * ty) * scale; + const py = (s * tx + c * ty) * scale; + return Math.sin(px) * Math.sin(py) * 4.0; + }; + + for (const frame of opt.image.frames) { + const w = frame.width; + const h = frame.height; + const cx = opt.centerX ?? Math.trunc(w / 2); + const cy = opt.centerY ?? Math.trunc(h / 2); + for (const p of frame) { + const x = p.x; + const y = p.y; + let cmyC = 1 - p.rNormalized; + let cmyM = 1 - p.gNormalized; + let cmyY = 1 - p.bNormalized; + let cmyK = Math.min(cmyC, Math.min(cmyM, cmyY)); + cmyC = (cmyC - cmyK) / (1 - cmyK); + cmyM = (cmyM - cmyK) / (1 - cmyK); + cmyY = (cmyY - cmyK) / (1 - cmyK); + cmyC = MathUtils.clamp( + cmyC * 10 - 3 + pattern(x, y, cx, cy, angle + 0.26179), + 0, + 1 + ); + cmyM = MathUtils.clamp( + cmyM * 10 - 3 + pattern(x, y, cx, cy, angle + 1.30899), + 0, + 1 + ); + cmyY = MathUtils.clamp( + cmyY * 10 - 3 + pattern(x, y, cx, cy, angle), + 0, + 1 + ); + cmyK = MathUtils.clamp( + cmyK * 10 - 5 + pattern(x, y, cx, cy, angle + 0.78539), + 0, + 1 + ); + + const r = (1 - cmyC - cmyK) * p.maxChannelValue; + const g = (1 - cmyM - cmyK) * p.maxChannelValue; + const b = (1 - cmyY - cmyK) * p.maxChannelValue; + + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + + if (mx !== 1) { + p.r = MathUtils.mix(p.r, r, mx); + p.g = MathUtils.mix(p.g, g, mx); + p.b = MathUtils.mix(p.b, b, mx); + } else { + p.r = r; + p.g = g; + p.b = b; + } + } + } + return opt.image; + } + + /** + * Add the **red**, **green**, **blue** and **alpha** values to the **image** image + * colors, a per-channel brightness. + */ + public static colorOffset(opt: ColorOffsetOptions): MemoryImage { + const red = opt.red ?? 0; + const green = opt.green ?? 0; + const blue = opt.blue ?? 0; + const alpha = opt.alpha ?? 0; + const maskChannel = opt.maskChannel ?? Channel.luminance; + for (const frame of opt.image.frames) { + for (const p of frame) { + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + if (msk === undefined) { + p.r += red; + p.g += green; + p.b += blue; + p.a += alpha; + } else { + p.r = MathUtils.mix(p.r, p.r + red, msk); + p.g = MathUtils.mix(p.g, p.g + green, msk); + p.b = MathUtils.mix(p.b, p.b + blue, msk); + p.a = MathUtils.mix(p.a, p.a + alpha, msk); + } + } + } + return opt.image; + } + + /** + * Set the contrast level for the **image**. + * + * **contrast** values below 100 will decrees the contrast of the image, + * and values above 100 will increase the contrast. A contrast of of 100 + * will have no affect. + */ + public static contrast(opt: ContrastOptions): MemoryImage { + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (opt.contrast === 100) { + return opt.image; + } + + if ( + Filter._contrastCache === undefined || + opt.contrast !== Filter._contrastCache.lastContrast + ) { + Filter._contrastCache = { + lastContrast: opt.contrast, + contrast: new Uint8Array(256), + }; + + const c = (opt.contrast * opt.contrast) / 10000; + for (let i = 0; i < 256; ++i) { + Filter._contrastCache.contrast[i] = MathUtils.clampInt255( + ((i / 255 - 0.5) * c + 0.5) * 255 + ); + } + } + + for (const frame of opt.image.frames) { + for (const p of frame) { + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const r = Math.trunc(p.r); + const g = Math.trunc(p.g); + const b = Math.trunc(p.b); + if (msk === undefined) { + p.r = Filter._contrastCache.contrast[r]; + p.g = Filter._contrastCache.contrast[g]; + p.b = Filter._contrastCache.contrast[b]; + } else { + p.r = MathUtils.mix(p.r, Filter._contrastCache.contrast[r], msk); + p.g = MathUtils.mix(p.g, Filter._contrastCache.contrast[g], msk); + p.b = MathUtils.mix(p.b, Filter._contrastCache.contrast[b], msk); + } + } + } + + return opt.image; + } + + /** + * Apply a 3x3 convolution filter to the **image**. **filter** should be a + * list of 9 numbers. + * + * The rgb channels will be divided by **div** and add **offset**, allowing + * filters to normalize and offset the filtered pixel value. + */ + public static convolution(opt: ConvolutionOptions): MemoryImage { + const div = opt.div ?? 1; + const offset = opt.offset ?? 0; + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + const tmp = MemoryImage.from(opt.image); + for (const frame of opt.image.frames) { + const tmpFrame = tmp.frames[frame.frameIndex]; + for (const c of tmpFrame) { + let r = 0; + let g = 0; + let b = 0; + for (let j = 0, fi = 0; j < 3; ++j) { + const yv = Math.min(Math.max(c.y - 1 + j, 0), opt.image.height - 1); + for (let i = 0; i < 3; ++i, ++fi) { + const xv = Math.min(Math.max(c.x - 1 + i, 0), opt.image.width - 1); + const c2 = tmpFrame.getPixel(xv, yv); + r += c2.r * opt.filter[fi]; + g += c2.g * opt.filter[fi]; + b += c2.b * opt.filter[fi]; + } + } + + r = MathUtils.clampInt255(r / div + offset); + g = MathUtils.clampInt255(g / div + offset); + b = MathUtils.clampInt255(b / div + offset); + + const p = frame.getPixel(c.x, c.y); + + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + + p.r = MathUtils.mix(p.r, r, mx); + p.g = MathUtils.mix(p.g, g, mx); + p.b = MathUtils.mix(p.b, b, mx); + } + } + + return opt.image; + } + + /** + * Copy channels from the **from** image to the **image**. If **scaled** is + * true, then the **from** image will be scaled to the **image** resolution. + */ + public static copyImageChannels(opt: CopyImageChannelsOptions): MemoryImage { + const scaled = opt.scaled ?? false; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + const dx = opt.from.width / opt.image.width; + const dy = opt.from.height / opt.image.height; + const fromPixel = opt.from.getPixel(0, 0); + for (const frame of opt.image.frames) { + for (const p of frame) { + if (scaled) { + fromPixel.setPosition(Math.floor(p.x * dx), Math.floor(p.y * dy)); + } else { + fromPixel.setPosition(p.x, p.y); + } + + const r = + opt.red !== undefined + ? fromPixel.getChannelNormalized(opt.red) + : p.rNormalized; + const g = + opt.green !== undefined + ? fromPixel.getChannelNormalized(opt.green) + : p.gNormalized; + const b = + opt.blue !== undefined + ? fromPixel.getChannelNormalized(opt.blue) + : p.bNormalized; + const a = + opt.alpha !== undefined + ? fromPixel.getChannelNormalized(opt.alpha) + : p.aNormalized; + + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + if (msk === undefined) { + p.rNormalized = r; + p.gNormalized = g; + p.bNormalized = b; + p.aNormalized = a; + } else { + p.rNormalized = MathUtils.mix(p.r, r, msk); + p.gNormalized = MathUtils.mix(p.g, g, msk); + p.bNormalized = MathUtils.mix(p.b, b, msk); + p.aNormalized = MathUtils.mix(p.a, a, msk); + } + } + } + return opt.image; + } + + /** + * Dither an image to reduce banding patterns when reducing the number of + * colors. + */ + public static ditherImage(opt: DitherImageOptions): MemoryImage { + const quantizer = opt.quantizer ?? new NeuralQuantizer(opt.image); + const kernel = opt.kernel ?? DitherKernel.floydSteinberg; + const serpentine = opt.serpentine ?? false; + + if (kernel === DitherKernel.none) { + return quantizer.getIndexImage(opt.image); + } + + const ds = DitherKernels[kernel]; + const height = opt.image.height; + const width = opt.image.width; + + let direction = serpentine ? -1 : 1; + + const palette = quantizer.palette; + const indexedImage = new MemoryImage({ + width: width, + height: height, + numChannels: 1, + palette: palette, + }); + + const pIter = opt.image[Symbol.iterator](); + let itRes = pIter.next(); + + let index = 0; + for (let y = 0; y < height; y++) { + if (serpentine) direction *= -1; + + const x0 = direction === 1 ? 0 : width - 1; + const x1 = direction === 1 ? width : 0; + for ( + let x = x0; + x !== x1; + x += direction, ++index, itRes = pIter.next() + ) { + // Get original color + const pc = itRes.value; + const r1 = Math.trunc(pc.getChannel(0)); + const g1 = Math.trunc(pc.getChannel(1)); + const b1 = Math.trunc(pc.getChannel(2)); + + // Get converted color + let idx = quantizer.getColorIndexRgb(r1, g1, b1); + indexedImage.setPixelRgb(x, y, idx, 0, 0); + + const r2 = palette.get(idx, 0); + const g2 = palette.get(idx, 1); + const b2 = palette.get(idx, 2); + + const er = r1 - r2; + const eg = g1 - g2; + const eb = b1 - b2; + + if (er === 0 && eg === 0 && eb === 0) { + continue; + } + + const i0 = direction === 1 ? 0 : ds.length - 1; + const i1 = direction === 1 ? ds.length : 0; + for (let i = i0; i !== i1; i += direction) { + const x1 = Math.trunc(ds[i][1]); + const y1 = Math.trunc(ds[i][2]); + if (x1 + x >= 0 && x1 + x < width && y1 + y >= 0 && y1 + y < height) { + const d = ds[i][0]; + idx = index + x1 + y1 * width; + idx *= 4; + const p2 = opt.image.getPixel(x1, y1); + p2.r = Math.max(0, Math.min(255, Math.trunc(p2.r + er * d))); + p2.g = Math.max(0, Math.min(255, Math.trunc(p2.g + er * d))); + p2.b = Math.max(0, Math.min(255, Math.trunc(p2.b + er * d))); + } + } + } + } + + return indexedImage; + } + + /** + * Apply the dot screen filter to the image. + */ + public static dotScreen(opt: DotScreenOptions): MemoryImage { + let angle = opt.angle ?? 180; + const size = opt.size ?? 5.75; + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + angle *= 0.0174533; + const s = Math.sin(angle); + const c = Math.cos(angle); + for (const frame of opt.image.frames) { + const w = frame.width - 1; + const h = frame.height - 1; + const cntX = (opt.centerX ?? Math.trunc(w / 2)) / w; + const cntY = (opt.centerY ?? Math.trunc(h / 2)) / h; + + const pattern = ( + cntX: number, + cntY: number, + tx: number, + ty: number + ): number => { + const texX = (tx - cntX) * w; + const texY = (ty - cntY) * h; + const pointX = (c * texX - s * texY) * size; + const pointY = (s * texX + c * texY) * size; + return Math.sin(pointX) * Math.sin(pointY) * 4; + }; + + for (const p of frame) { + const average = p.luminanceNormalized; + const pat = pattern(cntX, cntY, p.x / w, p.y / h); + const c = (average * 10 - 5 + pat) * p.maxChannelValue; + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + p.r = MathUtils.mix(p.r, c, mx); + p.g = MathUtils.mix(p.g, c, mx); + p.b = MathUtils.mix(p.b, c, mx); + } + } + + return opt.image; + } + + /** + * Create a drop-shadow effect for the image. + */ + public static dropShadow(opt: DropShadowOptions): MemoryImage { + const blur = opt.blur >= 0 ? opt.blur : 0; + const shadowColor = opt.shadowColor ?? new ColorRgba8(0, 0, 0, 128); + + const shadowWidth = opt.image.width + blur * 2; + const shadowHeight = opt.image.height + blur * 2; + let shadowOffsetX = -blur; + let shadowOffsetY = -blur; + + let newImageWidth = shadowWidth; + let newImageHeight = shadowHeight; + let imageOffsetX = 0; + let imageOffsetY = 0; + + if (shadowOffsetX + opt.hShadow < 0) { + imageOffsetX = -(shadowOffsetX + opt.hShadow); + shadowOffsetX = -shadowOffsetX; + newImageWidth = imageOffsetX; + } + + if (shadowOffsetY + opt.vShadow < 0) { + imageOffsetY = -(shadowOffsetY + opt.vShadow); + shadowOffsetY = -shadowOffsetY; + newImageHeight += imageOffsetY; + } + + if (shadowWidth + shadowOffsetX + opt.hShadow > newImageWidth) { + newImageWidth = shadowWidth + shadowOffsetX + opt.hShadow; + } + + if (shadowHeight + shadowOffsetY + opt.vShadow > newImageHeight) { + newImageHeight = shadowHeight + shadowOffsetY + opt.vShadow; + } + + const dst = new MemoryImage({ + width: newImageWidth, + height: newImageHeight, + numChannels: 4, + }); + + dst.clear(new ColorRgba8(255, 255, 255, 0)); + + Draw.compositeImage({ + dst: dst, + src: opt.image, + dstX: shadowOffsetX, + dstY: shadowOffsetY, + }); + + Filter.remapColors({ + image: dst, + red: Channel.alpha, + green: Channel.alpha, + blue: Channel.alpha, + }); + + Filter.scaleRgba({ + image: dst, + scale: shadowColor, + }); + + Filter.gaussianBlur({ + image: dst, + radius: blur, + }); + + Draw.compositeImage({ + dst: dst, + src: opt.image, + dstX: imageOffsetX, + dstY: imageOffsetY, + }); + + return dst; + } + + /** + * Apply the edge glow filter to the image. + */ + public static edgeGlow(opt: EdgeGlowOptions): MemoryImage { + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (amount === 0) { + return opt.image; + } + + for (const frame of opt.image.frames) { + const orig = MemoryImage.from(frame, true); + const width = frame.width; + const height = frame.height; + for (const p of frame) { + const ny = MathUtils.clamp(p.y - 1, 0, height - 1); + const py = MathUtils.clamp(p.y + 1, 0, height - 1); + const nx = MathUtils.clamp(p.x - 1, 0, width - 1); + const px = MathUtils.clamp(p.x + 1, 0, width - 1); + + const t1 = orig.getPixel(nx, ny); + const t2 = orig.getPixel(p.x, ny); + const t3 = orig.getPixel(px, ny); + const t4 = orig.getPixel(nx, p.y); + const t5 = p; + const t6 = orig.getPixel(px, p.y); + const t7 = orig.getPixel(nx, py); + const t8 = orig.getPixel(p.x, py); + const t9 = orig.getPixel(px, py); + + const xxR = + t1.rNormalized + + 2 * t2.rNormalized + + t3.rNormalized - + t7.rNormalized - + 2 * t8.rNormalized - + t9.rNormalized; + const xxG = + t1.gNormalized + + 2 * t2.gNormalized + + t3.gNormalized - + t7.gNormalized - + 2 * t8.gNormalized - + t9.gNormalized; + const xxB = + t1.bNormalized + + 2 * t2.bNormalized + + t3.bNormalized - + t7.bNormalized - + 2 * t8.bNormalized - + t9.bNormalized; + + const yyR = + t1.rNormalized - + t3.rNormalized + + 2 * t4.rNormalized - + 2 * t6.rNormalized + + t7.rNormalized - + t9.rNormalized; + const yyG = + t1.gNormalized - + t3.gNormalized + + 2 * t4.gNormalized - + 2 * t6.gNormalized + + t7.gNormalized - + t9.gNormalized; + const yyB = + t1.bNormalized - + t3.bNormalized + + 2 * t4.bNormalized - + 2 * t6.bNormalized + + t7.bNormalized - + t9.bNormalized; + + const rrR = Math.sqrt(xxR * xxR + yyR * yyR); + const rrG = Math.sqrt(xxG * xxG + yyG * yyG); + const rrB = Math.sqrt(xxB * xxB + yyB * yyB); + + const r = rrR * 2 * t5.rNormalized * p.maxChannelValue; + const g = rrG * 2 * t5.gNormalized * p.maxChannelValue; + const b = rrB * 2 * t5.bNormalized * p.maxChannelValue; + + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + + p.r = MathUtils.mix(p.r, r, mx); + p.g = MathUtils.mix(p.g, g, mx); + p.b = MathUtils.mix(p.b, b, mx); + } + } + + return opt.image; + } + + /** + * Apply an emboss convolution filter. + */ + public static emboss(opt: EmbossOptions): MemoryImage { + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + const filter = [1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.5]; + return Filter.convolution({ + image: opt.image, + filter: filter, + div: 1, + offset: 127, + amount: amount, + mask: opt.mask, + maskChannel: maskChannel, + }); + } + + /** + * Apply gamma scaling + */ + public static gamma(opt: GammaOptions): MemoryImage { + const maskChannel = opt.maskChannel ?? Channel.luminance; + for (const frame of opt.image.frames) { + for (const p of frame) { + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + if (msk === undefined) { + p.rNormalized = Math.pow(p.rNormalized, opt.gamma); + p.gNormalized = Math.pow(p.gNormalized, opt.gamma); + p.bNormalized = Math.pow(p.bNormalized, opt.gamma); + } else { + p.rNormalized = MathUtils.mix( + p.rNormalized, + Math.pow(p.rNormalized, opt.gamma), + msk + ); + p.gNormalized = MathUtils.mix( + p.gNormalized, + Math.pow(p.gNormalized, opt.gamma), + msk + ); + p.bNormalized = MathUtils.mix( + p.bNormalized, + Math.pow(p.bNormalized, opt.gamma), + msk + ); + } + } + } + return opt.image; + } + + /** + * Apply gaussian blur to the **image**. **radius** determines how many pixels + * away from the current pixel should contribute to the blur, where 0 is no + * blur and the larger the **radius**, the stronger the blur. + */ + public static gaussianBlur(opt: GaussianBlurOptions): MemoryImage { + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (opt.radius <= 0) { + return opt.image; + } + + let kernel: SeparableKernel | undefined = undefined; + + if (Filter._gaussianKernelCache.has(opt.radius)) { + kernel = Filter._gaussianKernelCache.get(opt.radius)!; + } else { + // Compute coefficients + const sigma = (opt.radius * 2) / 3; + const s = 2 * sigma * sigma; + + kernel = new SeparableKernel(opt.radius); + + let sum = 0; + for (let x = -opt.radius; x <= opt.radius; ++x) { + const c = Math.exp(-(x * x) / s); + sum += c; + kernel.setCoefficient(x + opt.radius, c); + } + // Normalize the coefficients + kernel.scaleCoefficients(1 / sum); + + // Cache the kernel for this radius so we don't have to recompute it + // next time. + Filter._gaussianKernelCache.set(opt.radius, kernel); + } + + return Filter.separableConvolution({ + image: opt.image, + kernel: kernel, + mask: opt.mask, + maskChannel: maskChannel, + }); + } + + /** + * Convert the image to grayscale. + */ + public static grayscale(opt: GrayscaleOptions): MemoryImage { + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + for (const frame of opt.image.frames) { + if (frame.hasPalette) { + const p = frame.palette!; + const numColors = p.numColors; + for (let i = 0; i < numColors; ++i) { + const l = ColorUtils.getLuminanceRgb( + p.getRed(i), + p.getGreen(i), + p.getBlue(i) + ); + if (amount !== 1) { + const r = MathUtils.mix(p.getRed(i), l, amount); + const g = MathUtils.mix(p.getGreen(i), l, amount); + const b = MathUtils.mix(p.getBlue(i), l, amount); + p.setRed(i, r); + p.setGreen(i, g); + p.setBlue(i, b); + } else { + p.setRed(i, l); + p.setGreen(i, l); + p.setBlue(i, l); + } + } + } else { + for (const p of frame) { + const l = ColorUtils.getLuminanceRgb(p.r, p.g, p.b); + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + if (mx !== 1) { + p.r = MathUtils.mix(p.r, l, mx); + p.g = MathUtils.mix(p.g, l, mx); + p.b = MathUtils.mix(p.b, l, mx); + } else { + p.r = l; + p.g = l; + p.b = l; + } + } + } + } + + return opt.image; + } + + /** + * Convert a high dynamic range image to a low dynamic range image, + * with optional exposure control. + */ + public static hdrToLdr(opt: HdrToLdrOptions): MemoryImage { + const knee = (x: number, f: number): number => { + return Math.log(x * f + 1.0) / f; + }; + + const gamma = (h: number, m: number): number => { + let x = Math.max(0, h * m); + if (x > 1.0) { + x = 1 + knee(x - 1, 0.184874); + } + return Math.pow(x, 0.4545) * 84.66; + }; + + const image = new MemoryImage({ + width: opt.image.width, + height: opt.image.height, + numChannels: opt.image.numChannels, + }); + + const m = + opt.exposure !== undefined + ? Math.pow(2, MathUtils.clamp(opt.exposure + 2.47393, -20, 20)) + : 1; + + const nc = opt.image.numChannels; + + for (let y = 0; y < opt.image.height; ++y) { + for (let x = 0; x < opt.image.width; ++x) { + const hp = opt.image.getPixel(x, y); + + let r = hp.rNormalized; + let g = nc === 1 ? r : hp.gNormalized; + let b = nc === 1 ? r : hp.bNormalized; + + if (!isFinite(r) || isNaN(r)) { + r = 0; + } + if (!isFinite(g) || isNaN(g)) { + g = 0; + } + if (!isFinite(b) || isNaN(b)) { + b = 0; + } + + let ri = 0; + let gi = 0; + let bi = 0; + if (opt.exposure !== undefined) { + ri = gamma(r, m); + gi = gamma(g, m); + bi = gamma(b, m); + } else { + ri = MathUtils.clamp(r, 0, 1) * 255; + gi = MathUtils.clamp(g, 0, 1) * 255; + bi = MathUtils.clamp(b, 0, 1) * 255; + } + + // Normalize the color + const mi = Math.max(ri, Math.max(gi, bi)); + if (mi > 255) { + ri = 255 * (ri / mi); + gi = 255 * (gi / mi); + bi = 255 * (bi / mi); + } + + if (opt.image.numChannels > 3) { + let a = hp.a; + if (!isFinite(a) || isNaN(a)) { + a = 1; + } + image.setPixelRgba( + x, + y, + MathUtils.clampInt255(ri), + MathUtils.clampInt255(gi), + MathUtils.clampInt255(bi), + MathUtils.clampInt255(a * 255) + ); + } else { + image.setPixelRgb( + x, + y, + MathUtils.clampInt255(ri), + MathUtils.clampInt255(gi), + MathUtils.clampInt255(bi) + ); + } + } + } + + return image; + } + + /** + * Apply the hexagon pixelate filter to the image. + */ + public static hexagonPixelate(opt: HexagonPixelateOptions): MemoryImage { + const size = opt.size ?? 5; + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + for (const frame of opt.image.frames) { + const w = frame.width - 1; + const h = frame.height - 1; + const cntX = (opt.centerX ?? Math.trunc(frame.width / 2)) / w; + const cntY = (opt.centerY ?? Math.trunc(frame.height / 2)) / h; + const orig = frame.clone({ + skipAnimation: true, + }); + + for (const p of frame) { + let texX = (p.x - cntX) / size; + let texY = (p.y - cntY) / size; + texY /= 0.866025404; + texX -= texY * 0.5; + + let ax = 0; + let ay = 0; + if (texX + texY - Math.floor(texX) - Math.floor(texY) < 1) { + ax = Math.floor(texX); + ay = Math.floor(texY); + } else { + ax = Math.ceil(texX); + ay = Math.ceil(texY); + } + + const bx = Math.ceil(texX); + const by = Math.floor(texY); + const cx = Math.floor(texX); + const cy = Math.ceil(texY); + + const tex2X = texX; + const tex2Y = texY; + const tex2Z = 1 - texX - texY; + const a2x = ax; + const a2y = ay; + const a2z = 1 - ax - ay; + const b2x = bx; + const b2y = by; + const b2z = 1 - bx - by; + const c2x = cx; + const c2y = cy; + const c2z = 1 - cx - cy; + + const aLen = MathUtils.length3(tex2X - a2x, tex2Y - a2y, tex2Z - a2z); + const bLen = MathUtils.length3(tex2X - b2x, tex2Y - b2y, tex2Z - b2z); + const cLen = MathUtils.length3(tex2X - c2x, tex2Y - c2y, tex2Z - c2z); + + let choiceX = 0; + let choiceY = 0; + if (aLen < bLen) { + if (aLen < cLen) { + choiceX = ax; + choiceY = ay; + } else { + choiceX = cx; + choiceY = cy; + } + } else { + if (bLen < cLen) { + choiceX = bx; + choiceY = by; + } else { + choiceX = cx; + choiceY = cy; + } + } + + choiceX += choiceY * 0.5; + choiceY *= 0.866025404; + choiceX *= size / w; + choiceY *= size / h; + + const nx = choiceX + cntX / w; + const ny = choiceY + cntY / h; + const x = MathUtils.clamp(nx * w, 0, w); + const y = MathUtils.clamp(ny * h, 0, h); + const newColor = orig.getPixel(Math.floor(x), Math.floor(y)); + + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + + p.r = MathUtils.mix(p.r, newColor.r, mx); + p.g = MathUtils.mix(p.g, newColor.g, mx); + p.b = MathUtils.mix(p.b, newColor.b, mx); + } + } + return opt.image; + } + + /** + * Invert the colors of the **image**. + */ + public static invert(opt: InvertOptions): MemoryImage { + const maskChannel = opt.maskChannel ?? Channel.luminance; + + const max = opt.image.maxChannelValue; + for (const frame of opt.image.frames) { + if (opt.image.hasPalette) { + const p = frame.palette!; + const numColors = p.numColors; + for (let i = 0; i < numColors; ++i) { + const r = max - p.getRed(i); + const g = max - p.getGreen(i); + const b = max - p.getBlue(i); + p.setRgb(i, r, g, b); + } + } else { + if (max !== 0) { + for (const p of frame) { + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + + if (msk === undefined) { + p.r = max - p.r; + p.g = max - p.g; + p.b = max - p.b; + } else { + p.r = MathUtils.mix(p.r, max - p.r, msk); + p.g = MathUtils.mix(p.g, max - p.g, msk); + p.b = MathUtils.mix(p.b, max - p.b, msk); + } + } + } + } + } + return opt.image; + } + + public static luminanceThreshold( + opt: LuminanceThresholdOptions + ): MemoryImage { + const threshold = opt.threshold ?? 0.5; + const outputColor = opt.outputColor ?? false; + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + for (const frame of opt.image.frames) { + for (const p of frame) { + const y = + 0.3 * p.rNormalized + 0.59 * p.gNormalized + 0.11 * p.bNormalized; + if (outputColor) { + const l = Math.max(0, y - threshold); + const sl = Math.sign(l); + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + p.r = MathUtils.mix(p.r, p.r * sl, mx); + p.g = MathUtils.mix(p.g, p.g * sl, mx); + p.b *= MathUtils.mix(p.b, p.b * sl, mx); + } else { + const y2 = y < threshold ? 0 : p.maxChannelValue; + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + p.r = MathUtils.mix(p.r, y2, mx); + p.g = MathUtils.mix(p.g, y2, mx); + p.b = MathUtils.mix(p.b, y2, mx); + } + } + } + return opt.image; + } + + /** + * Apply the monochrome filter to the **image**. + * + * **amount** controls the strength of the effect, in the range [0, 1]. + */ + public static monochrome(opt: MonochromeOptions): MemoryImage { + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (amount === 0) { + return opt.image; + } + + const nr = opt.color?.rNormalized ?? 0.45; + const ng = opt.color?.gNormalized ?? 0.6; + const nb = opt.color?.bNormalized ?? 0.3; + + for (const frame of opt.image.frames) { + for (const p of frame) { + const y = p.luminanceNormalized; + + const r = y < 0.5 ? 2 * y * nr : 1 - 2 * (1 - y) * (1 - nr); + const g = y < 0.5 ? 2 * y * ng : 1 - 2 * (1 - y) * (1 - ng); + const b = y < 0.5 ? 2 * y * nb : 1 - 2 * (1 - y) * (1 - nb); + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + p.r = MathUtils.mix(p.r, r * p.maxChannelValue, mx); + p.g = MathUtils.mix(p.g, g * p.maxChannelValue, mx); + p.b = MathUtils.mix(p.b, b * p.maxChannelValue, mx); + } + } + + return opt.image; + } + + /** + * Add random noise to pixel values. **sigma** determines how strong the effect + * should be. **type** should be one of the following: _NoiseType.gaussian_, + * _NoiseType.uniform_, _NoiseType.saltAndPepper_, _NoiseType.poisson_, + * or _NoiseType.rice_. + */ + public static noise(opt: NoiseOptions): MemoryImage { + const type = opt.type ?? NoiseType.gaussian; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + let nSigma = opt.sigma; + let min = 0; + let max = 0; + + if (nSigma === 0 && type !== NoiseType.poisson) { + return opt.image; + } + + if (nSigma < 0 || type === NoiseType.saltAndPepper) { + const extremes = opt.image.getColorExtremes(); + min = extremes.min; + max = extremes.max; + } + + if (nSigma < 0) { + nSigma = (-nSigma * (max - min)) / 100.0; + } + + for (const frame of opt.image.frames) { + switch (type) { + case NoiseType.gaussian: + for (const p of frame) { + const r = p.r + nSigma * RandomUtils.grand(); + const g = p.g + nSigma * RandomUtils.grand(); + const b = p.b + nSigma * RandomUtils.grand(); + const a = p.a; + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + if (msk === undefined) { + p.setRgba(r, g, b, a); + } else { + p.r = MathUtils.mix(p.r, r, msk); + p.g = MathUtils.mix(p.g, g, msk); + p.b = MathUtils.mix(p.b, b, msk); + p.a = MathUtils.mix(p.a, a, msk); + } + } + break; + case NoiseType.uniform: + for (const p of frame) { + const r = p.r + nSigma * RandomUtils.crand(); + const g = p.g + nSigma * RandomUtils.crand(); + const b = p.b + nSigma * RandomUtils.crand(); + const a = p.a; + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + if (msk === undefined) { + p.setRgba(r, g, b, a); + } else { + p.r = MathUtils.mix(p.r, r, msk); + p.g = MathUtils.mix(p.g, g, msk); + p.b = MathUtils.mix(p.b, b, msk); + p.a = MathUtils.mix(p.a, a, msk); + } + } + break; + case NoiseType.saltAndPepper: + if (nSigma < 0) { + nSigma = -nSigma; + } + if (max === min) { + min = 0; + max = 255; + } + for (const p of frame) { + if (Math.random() * 100 < nSigma) { + const r = Math.random() < 0.5 ? max : min; + const g = Math.random() < 0.5 ? max : min; + const b = Math.random() < 0.5 ? max : min; + const a = p.a; + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + if (msk === undefined) { + p.setRgba(r, g, b, a); + } else { + p.r = MathUtils.mix(p.r, r, msk); + p.g = MathUtils.mix(p.g, g, msk); + p.b = MathUtils.mix(p.b, b, msk); + p.a = MathUtils.mix(p.a, a, msk); + } + } + } + break; + case NoiseType.poisson: + for (const p of frame) { + const r = RandomUtils.prand(p.r); + const g = RandomUtils.prand(p.g); + const b = RandomUtils.prand(p.b); + const a = p.a; + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + if (msk === undefined) { + p.setRgba(r, g, b, a); + } else { + p.r = MathUtils.mix(p.r, r, msk); + p.g = MathUtils.mix(p.g, g, msk); + p.b = MathUtils.mix(p.b, b, msk); + p.a = MathUtils.mix(p.a, a, msk); + } + } + break; + case NoiseType.rice: { + const sqrt2 = Math.sqrt(2); + for (const p of frame) { + let val0 = p.r / sqrt2; + let re = val0 + nSigma * RandomUtils.grand(); + let im = val0 + nSigma * RandomUtils.grand(); + let val = Math.sqrt(re * re + im * im); + const r = Math.trunc(val); + + val0 = p.g / sqrt2; + re = val0 + nSigma * RandomUtils.grand(); + im = val0 + nSigma * RandomUtils.grand(); + val = Math.sqrt(re * re + im * im); + const g = Math.trunc(val); + + val0 = p.b / sqrt2; + re = val0 + nSigma * RandomUtils.grand(); + im = val0 + nSigma * RandomUtils.grand(); + val = Math.sqrt(re * re + im * im); + const b = Math.trunc(val); + + const a = p.a; + + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + if (msk === undefined) { + p.setRgba(r, g, b, a); + } else { + p.r = MathUtils.mix(p.r, r, msk); + p.g = MathUtils.mix(p.g, g, msk); + p.b = MathUtils.mix(p.b, b, msk); + p.a = MathUtils.mix(p.a, a, msk); + } + } + break; + } + } + } + + return opt.image; + } + + /** + * Linearly normalize the colors of the image. All color values will be mapped + * to the range **min**, **max** inclusive. + */ + public static normalize(opt: NormalizeOptions): MemoryImage { + const maskChannel = opt.maskChannel ?? Channel.luminance; + + const a = opt.min < opt.max ? opt.min : opt.max; + const b = opt.min < opt.max ? opt.max : opt.min; + + const extremes = opt.image.getColorExtremes(); + const mn = extremes.min; + const mx = extremes.max; + + if (mn === mx) { + return opt.image; + } + + const fm = mn; + const fM = mx; + + if (mn !== a || mx !== b) { + for (const frame of opt.image.frames) { + for (const p of frame) { + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + if (msk === undefined) { + p.r = ((p.r - fm) / (fM - fm)) * (b - a) + a; + p.g = ((p.g - fm) / (fM - fm)) * (b - a) + a; + p.b = ((p.b - fm) / (fM - fm)) * (b - a) + a; + p.a = ((p.a - fm) / (fM - fm)) * (b - a) + a; + } else { + const xr = ((p.r - fm) / (fM - fm)) * (b - a) + a; + const xg = ((p.g - fm) / (fM - fm)) * (b - a) + a; + const xb = ((p.b - fm) / (fM - fm)) * (b - a) + a; + const xa = ((p.a - fm) / (fM - fm)) * (b - a) + a; + p.r = MathUtils.mix(p.r, xr, msk); + p.g = MathUtils.mix(p.g, xg, msk); + p.b = MathUtils.mix(p.b, xb, msk); + p.a = MathUtils.mix(p.a, xa, msk); + } + } + } + } + + return opt.image; + } + + /** + * Pixelate the **image**. + * + * **size** determines the size of the pixelated blocks. + * If **mode** is **upperLeft** then the upper-left corner of the + * block will be used for the block color. Otherwise if **mode** is + * **average**, the average of all the pixels in the block will be + * used for the block color. + */ + public static pixelate(opt: PixelateOptions): MemoryImage { + const mode = opt.mode ?? PixelateMode.upperLeft; + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (opt.size <= 1) { + return opt.image; + } + + for (const frame of opt.image.frames) { + const w = frame.width; + const h = frame.height; + switch (mode) { + case PixelateMode.upperLeft: + for (const p of frame) { + const x2 = Math.trunc(p.x / opt.size) * opt.size; + const y2 = Math.trunc(p.y / opt.size) * opt.size; + const p2 = frame.getPixel(x2, y2); + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + if (mx === 1) { + p.set(p2); + } else { + p.r = MathUtils.mix(p.r, p2.r, mx); + p.g = MathUtils.mix(p.g, p2.g, mx); + p.b = MathUtils.mix(p.b, p2.b, mx); + p.a = MathUtils.mix(p.a, p2.a, mx); + } + } + break; + case PixelateMode.average: + { + let r = 0; + let g = 0; + let b = 0; + let a = 0; + let lx = -1; + let ly = -1; + for (const p of frame) { + const x2 = Math.trunc(p.x / opt.size) * opt.size; + const y2 = Math.trunc(p.y / opt.size) * opt.size; + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + if (x2 !== lx || y2 <= ly) { + lx = x2; + ly = y2; + r = 0; + g = 0; + b = 0; + a = 0; + for ( + let by = 0, by2 = y2; + by < opt.size && by2 < h; + ++by, ++by2 + ) { + for ( + let bx = 0, bx2 = x2; + bx < opt.size && bx2 < w; + ++bx, ++bx2 + ) { + const p2 = frame.getPixel(bx2, by2); + r += p2.r; + g += p2.g; + b += p2.b; + a += p2.a; + } + } + const total = opt.size * opt.size; + r /= total; + g /= total; + b /= total; + a /= total; + } + + p.r = MathUtils.mix(p.r, r, mx); + p.g = MathUtils.mix(p.g, g, mx); + p.b = MathUtils.mix(p.b, b, mx); + p.a = MathUtils.mix(p.a, a, mx); + } + } + + break; + } + } + return opt.image; + } + + /** + * Quantize the number of colors in image to 256. + */ + public static quantize(opt: QuantizeOptions): MemoryImage { + const numberOfColors = opt.numberOfColors ?? 256; + const method = opt.method ?? QuantizeMethod.neuralNet; + const dither = opt.dither ?? DitherKernel.none; + const ditherSerpentine = opt.ditherSerpentine ?? false; + + let quantizer: Quantizer | undefined = undefined; + if (method === QuantizeMethod.octree || numberOfColors < 4) { + quantizer = new OctreeQuantizer(opt.image, numberOfColors); + } else { + quantizer = new NeuralQuantizer(opt.image, numberOfColors); + } + + return Filter.ditherImage({ + image: opt.image, + quantizer: quantizer, + kernel: dither, + serpentine: ditherSerpentine, + }); + } + + /** + * Applies Reinhard tone mapping to the hdr image, in-place. + */ + public static reinhardToneMap(opt: ReinhardToneMapOptions): MemoryImage { + const maskChannel = opt.maskChannel ?? Channel.luminance; + + const yw = [0.212671, 0.71516, 0.072169]; + + // Compute world adaptation luminance, _Ywa_ + let ywa = 0.0; + for (const p of opt.image) { + const r = p.r; + const g = p.g; + const b = p.b; + const lum = yw[0] * r + yw[1] * g + yw[2] * b; + if (lum > 1.0e-4) { + ywa += Math.log(lum); + } + } + + ywa = Math.exp(ywa / (opt.image.width * opt.image.height)); + + const invY2 = 1 / (ywa * ywa); + + for (const p of opt.image) { + const r = p.r; + const g = p.g; + const b = p.b; + + const lum = yw[0] * r + yw[1] * g + yw[2] * b; + + const s = (1 + lum * invY2) / (1 + lum); + + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + if (msk === undefined) { + p.r = r * s; + p.g = g * s; + p.b = b * s; + } else { + p.r = MathUtils.mix(p.r, r * s, msk); + p.g = MathUtils.mix(p.g, g * s, msk); + p.b = MathUtils.mix(p.b, b * s, msk); + } + } + + return opt.image; + } + + /** + * Remap the color channels of the image. + * **red**, **green**, **blue** and **alpha** should be set to one of the following: + * _Channel.red_, _Channel.green_, _Channel.blue_, _Channel.alpha_, or + * _Channel.luminance_. + */ + public static remapColors(opt: RemapColorsOptions): MemoryImage { + const red = opt.red ?? Channel.red; + const green = opt.green ?? Channel.green; + const blue = opt.blue ?? Channel.blue; + const alpha = opt.alpha ?? Channel.alpha; + + const l: number[] = [0, 0, 0, 0, 0]; + for (const frame of opt.image.frames) { + for (const p of frame) { + l[0] = p.r; + l[1] = p.g; + l[2] = p.b; + l[3] = p.a; + if ( + red === Channel.luminance || + green === Channel.luminance || + blue === Channel.luminance || + alpha === Channel.luminance + ) { + l[4] = ColorUtils.getLuminanceRgb(l[0], l[1], l[2]); + } + p.r = l[red]; + p.g = l[green]; + p.b = l[blue]; + p.a = l[alpha]; + } + } + return opt.image; + } + + public static scaleRgba(opt: ScaleRgbaOptions): MemoryImage { + const maskChannel = opt.maskChannel ?? Channel.luminance; + + const dr = opt.scale.rNormalized; + const dg = opt.scale.gNormalized; + const db = opt.scale.bNormalized; + const da = opt.scale.aNormalized; + for (const frame of opt.image.frames) { + for (const p of frame) { + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + if (msk === undefined) { + p.setRgba(p.r * dr, p.g * dg, p.b * db, p.a * da); + } else { + p.r = MathUtils.mix(p.r, p.r * dr, msk); + p.g = MathUtils.mix(p.g, p.g * dg, msk); + p.b = MathUtils.mix(p.b, p.b * db, msk); + p.a = MathUtils.mix(p.a, p.a * da, msk); + } + } + } + + return opt.image; + } + + /** + * Apply a generic separable convolution filter to the **image**, using the + * given **kernel**. + * + * **gaussianBlur** is an example of such a filter. + */ + public static separableConvolution( + opt: SeparableConvolutionOptions + ): MemoryImage { + const maskChannel = opt.maskChannel ?? Channel.luminance; + + const tmp = MemoryImage.from(opt.image); + + // Apply the filter horizontally + opt.kernel.apply({ + src: opt.image, + dst: tmp, + maskChannel: maskChannel, + mask: opt.mask, + }); + + // Apply the filter vertically, applying back to the original image. + opt.kernel.apply({ + src: tmp, + dst: opt.image, + horizontal: false, + maskChannel: maskChannel, + mask: opt.mask, + }); + + return opt.image; + } + + /** + * Apply sepia tone to the **image**. + * + * **amount** controls the strength of the effect, in the range [0, 1]. + */ + public static sepia(opt: SepiaOptions): MemoryImage { + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (amount === 0) { + return opt.image; + } + + for (const frame of opt.image.frames) { + for (const p of frame) { + const r = p.rNormalized; + const g = p.gNormalized; + const b = p.bNormalized; + const y = ColorUtils.getLuminanceRgb(r, g, b); + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + p.rNormalized = mx * (y + 0.15) + (1 - mx) * r; + p.gNormalized = mx * (y + 0.07) + (1 - mx) * g; + p.bNormalized = mx * (y - 0.12) + (1 - mx) * b; + } + } + + return opt.image; + } + + /** + * Apply sketch filter to the **image**. + * + * **amount** controls the strength of the effect, in the range [0, 1]. + */ + public static sketch(opt: SketchOptions): MemoryImage { + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (amount === 0) { + return opt.image; + } + + for (const frame of opt.image.frames) { + const width = frame.width; + const height = frame.height; + const orig = MemoryImage.from(frame, true); + for (const p of frame) { + const ny = MathUtils.clamp(p.y - 1, 0, height - 1); + const py = MathUtils.clamp(p.y + 1, 0, height - 1); + const nx = MathUtils.clamp(p.x - 1, 0, width - 1); + const px = MathUtils.clamp(p.x + 1, 0, width - 1); + + const bottomLeft = orig.getPixel(nx, py).luminanceNormalized; + const topLeft = orig.getPixel(nx, ny).luminanceNormalized; + const bottomRight = orig.getPixel(px, py).luminanceNormalized; + const topRight = orig.getPixel(px, ny).luminanceNormalized; + const left = orig.getPixel(nx, p.y).luminanceNormalized; + const right = orig.getPixel(px, p.y).luminanceNormalized; + const bottom = orig.getPixel(p.x, py).luminanceNormalized; + const top = orig.getPixel(p.x, ny).luminanceNormalized; + + const h = + -topLeft - 2 * top - topRight + bottomLeft + 2 * bottom + bottomRight; + + const v = + -bottomLeft - 2 * left - topLeft + bottomRight + 2 * right + topRight; + + const mag = 1 - Math.sqrt(h * h + v * v); + + const r = MathUtils.clamp(mag * p.r, 0, p.maxChannelValue); + const g = MathUtils.clamp(mag * p.g, 0, p.maxChannelValue); + const b = MathUtils.clamp(mag * p.b, 0, p.maxChannelValue); + + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + + p.r = MathUtils.mix(p.r, r, mx); + p.g = MathUtils.mix(p.g, g, mx); + p.b = MathUtils.mix(p.b, b, mx); + } + } + + return opt.image; + } + + /** + * Apply a smoothing convolution filter to the **image**. + * + * **weight** is the weight of the current pixel being filtered. If it's greater + * than 1, it will make the image sharper. + */ + public static smooth(opt: SmoothOptions): MemoryImage { + const maskChannel = opt.maskChannel ?? Channel.luminance; + + const filter = [1, 1, 1, 1, opt.weight, 1, 1, 1, 1]; + return Filter.convolution({ + image: opt.image, + filter: filter, + div: opt.weight + 8, + offset: 0, + mask: opt.mask, + maskChannel: maskChannel, + }); + } + + /** + * Apply Sobel edge detection filtering to the **image**. + */ + public static sobel(opt: SobelOptions): MemoryImage { + const amount = opt.amount ?? 1; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + if (amount === 0) { + return opt.image; + } + + for (const frame of opt.image.frames) { + const orig = MemoryImage.from(frame, true); + const width = frame.width; + const height = frame.height; + for (const p of frame) { + const ny = MathUtils.clamp(p.y - 1, 0, height - 1); + const py = MathUtils.clamp(p.y + 1, 0, height - 1); + const nx = MathUtils.clamp(p.x - 1, 0, width - 1); + const px = MathUtils.clamp(p.x + 1, 0, width - 1); + + const bottomLeft = orig.getPixel(nx, py).luminanceNormalized; + const topLeft = orig.getPixel(nx, ny).luminanceNormalized; + const bottomRight = orig.getPixel(px, py).luminanceNormalized; + const topRight = orig.getPixel(px, ny).luminanceNormalized; + const left = orig.getPixel(nx, p.y).luminanceNormalized; + const right = orig.getPixel(px, p.y).luminanceNormalized; + const bottom = orig.getPixel(p.x, py).luminanceNormalized; + const top = orig.getPixel(p.x, ny).luminanceNormalized; + + const h = + -topLeft - 2 * top - topRight + bottomLeft + 2 * bottom + bottomRight; + + const v = + -bottomLeft - 2 * left - topLeft + bottomRight + 2 * right + topRight; + + const mag = Math.sqrt(h * h + v * v) * p.maxChannelValue; + + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + const invMx = 1 - mx; + + p.r = mag * mx + p.r * invMx; + p.g = mag * mx + p.g * invMx; + p.b = mag * mx + p.b * invMx; + } + } + + return opt.image; + } + + public static stretchDistortion(opt: StretchDistortionOptions): MemoryImage { + const interpolation = opt.interpolation ?? Interpolation.nearest; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + for (const frame of opt.image.frames) { + const orig = frame.clone({ + skipAnimation: true, + }); + const w = frame.width - 1; + const h = frame.height - 1; + const cx = opt.centerX ?? Math.trunc(frame.width / 2); + const cy = opt.centerY ?? Math.trunc(frame.height / 2); + const nCntX = 2 * (cx / w) - 1; + const nCntY = 2 * (cy / h) - 1; + for (const p of frame) { + let ncX = (p.x / w) * 2 - 1; + let ncY = (p.y / h) * 2 - 1; + ncX -= nCntX; + ncY -= nCntY; + const sX = Math.sign(ncX); + const sY = Math.sign(ncY); + ncX = Math.abs(ncX); + ncY = Math.abs(ncY); + ncX = + (0.5 * ncX + 0.5 * MathUtils.smoothStep(0.25, 0.5, ncX) * ncX) * sX; + ncY = + (0.5 * ncY + 0.5 * MathUtils.smoothStep(0.25, 0.5, ncY) * ncY) * sY; + ncX += nCntX; + ncY += nCntY; + + const x = MathUtils.clamp((ncX / 2 + 0.5) * w, 0, w - 1); + const y = MathUtils.clamp((ncY / 2 + 0.5) * h, 0, h - 1); + + const p2 = orig.getPixelInterpolate(x, y, interpolation); + + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + + if (msk === undefined) { + p.r = p2.r; + p.g = p2.g; + p.b = p2.b; + } else { + p.r = MathUtils.mix(p.r, p2.r, msk); + p.g = MathUtils.mix(p.g, p2.g, msk); + p.b = MathUtils.mix(p.b, p2.b, msk); + } + } + } + + return opt.image; + } + + /** + * Apply a vignette filter to the **image**. + * + * **start** is the inner radius from the center of the image, where the fade to + * **color** starts to be applied; **end** is the outer radius of the + * vignette effect where the **color** is fully applied. The radius values are in + * normalized percentage of the image size [0, 1]. + * **amount** controls the blend of the effect with the original image. + */ + public static vignette(opt: VignetteOptions): MemoryImage { + const start = opt.start ?? 0.3; + const end = opt.end ?? 0.85; + const amount = opt.amount ?? 0.9; + const maskChannel = opt.maskChannel ?? Channel.luminance; + + const h = opt.image.height - 1; + const w = opt.image.width - 1; + const cr = opt.color?.rNormalized ?? 0; + const cg = opt.color?.gNormalized ?? 0; + const cb = opt.color?.bNormalized ?? 0; + const ca = opt.color?.aNormalized ?? 1; + const aspect = w / h; + for (const frame of opt.image.frames) { + for (const p of frame) { + const dx = (0.5 - p.x / w) * aspect; + const dy = 0.5 - p.y / h; + + let d = Math.sqrt(dx * dx + dy * dy); + d = 1 - MathUtils.smoothStep(end, start, d); + + const r = MathUtils.mix(p.rNormalized, cr, d) * p.maxChannelValue; + const g = MathUtils.mix(p.gNormalized, cg, d) * p.maxChannelValue; + const b = MathUtils.mix(p.bNormalized, cb, d) * p.maxChannelValue; + const a = MathUtils.mix(p.aNormalized, ca, d) * p.maxChannelValue; + + const msk = opt.mask + ?.getPixel(p.x, p.y) + .getChannelNormalized(maskChannel); + const mx = (msk ?? 1) * amount; + + p.r = MathUtils.mix(p.r, r, mx); + p.g = MathUtils.mix(p.g, g, mx); + p.b = MathUtils.mix(p.b, b, mx); + p.a = MathUtils.mix(p.a, a, mx); + } + } + + return opt.image; + } +} diff --git a/src/filter/image-filter.ts b/src/filter/image-filter.ts deleted file mode 100644 index 0e7889e..0000000 --- a/src/filter/image-filter.ts +++ /dev/null @@ -1,949 +0,0 @@ -/** @format */ - -import { Color } from '../common/color'; -import { ColorChannel } from '../common/color-channel'; -import { MathOperators } from '../common/math-operators'; -import { MemoryImage } from '../common/memory-image'; -import { NeuralQuantizer } from '../common/neural-quantizer'; -import { OctreeQuantizer } from '../common/octree-quantizer'; -import { RandomUtils } from '../common/random-utils'; -import { Rectangle } from '../common/rectangle'; -import { Draw } from '../draw/draw'; -import { AdjustColorOptions } from './adjust-color-options'; -import { ColorOffsetOptions } from './color-offset-options'; -import { ConvolutionOptions } from './convolution-options'; -import { NoiseType } from './noise-type'; -import { PixelateMode } from './pixelate-mode'; -import { QuantizeMethod } from './quantize-method'; -import { QuantizeOptions } from './quantize-options'; -import { RemapColorsOptions } from './remap-colors-options'; -import { SeparableKernel } from './separable-kernel'; -import { VignetteOptions } from './vignette-options'; - -export abstract class ImageFilter { - private static readonly gaussianKernelCache: Map = - new Map(); - - private static smoothVignetteStep( - edge0: number, - edge1: number, - x: number - ): number { - let _x = x; - _x = (_x - edge0) / (edge1 - edge0); - if (_x < 0.0) { - _x = 0.0; - } - if (_x > 1.0) { - _x = 1.0; - } - return _x * _x * (3.0 - 2.0 * _x); - } - - /** - * Adjust the color of the **src** image using various color transformations. - * - * **blacks** defines the black level of the image, as a color. - * - * **whites** defines the white level of the image, as a color. - * - * **mids** defines the mid level of hte image, as a color. - * - * **contrast** increases (> 1) / decreases (< 1) the contrast of the image by - * pushing colors away/toward neutral gray, where at 0 the image is entirely - * neutral gray (0 contrast), 1, the image is not adjusted and > 1 the - * image increases contrast. - * - * **saturation** increases (> 1) / decreases (< 1) the saturation of the image - * by pushing colors away/toward their grayscale value, where 0 is grayscale - * and 1 is the original image, and > 1 the image becomes more saturated. - * - * **brightness** is a constant scalar of the image colors. At 0 the image - * is black, 1 unmodified, and > 1 the image becomes brighter. - * - * **gamma** is an exponential scalar of the image colors. At < 1 the image - * becomes brighter, and > 1 the image becomes darker. A **gamma** of 1/2.2 - * will convert the image colors to linear color space. - * - * **exposure** is an exponential scalar of the image as rgb* pow(2, exposure). - * At 0, the image is unmodified; as the exposure increases, the image - * brightens. - * - * **hue** shifts the hue component of the image colors in degrees. A **hue** of - * 0 will have no affect, and a **hue** of 45 will shift the hue of all colors - * by 45 degrees. - * - * **amount** controls how much affect this filter has on the **src** image, where - * 0 has no effect and 1 has full effect. - */ - public static adjustColor(options: AdjustColorOptions): MemoryImage { - if (options.amount === 0) { - return options.src; - } - - const contrast = - options.contrast !== undefined - ? MathOperators.clamp(options.contrast, 0, 1) - : undefined; - const saturation = - options.saturation !== undefined - ? MathOperators.clamp(options.saturation, 0, 1) - : undefined; - const brightness = - options.brightness !== undefined - ? MathOperators.clamp(options.brightness, 0, 1) - : undefined; - const gamma = - options.gamma !== undefined - ? MathOperators.clamp(options.gamma, 0, 1000) - : undefined; - let exposure = - options.exposure !== undefined - ? MathOperators.clamp(options.exposure, 0, 1000) - : undefined; - const amount = - options.amount !== undefined - ? MathOperators.clamp(options.amount, 0, 1000) - : undefined; - - const DEG_TO_RAD = 0.0174532925; - const avgLumR = 0.5; - const avgLumG = 0.5; - const avgLumB = 0.5; - const lumCoeffR = 0.2125; - const lumCoeffG = 0.7154; - const lumCoeffB = 0.0721; - - const useBlacksWhitesMids = - options.blacks !== undefined || - options.whites !== undefined || - options.mids !== undefined; - let br = 0; - let bg = 0; - let bb = 0; - let wr = 0; - let wg = 0; - let wb = 0; - let mr = 0; - let mg = 0; - let mb = 0; - if (useBlacksWhitesMids) { - br = - options.blacks !== undefined ? Color.getRed(options.blacks) / 255 : 0; - bg = - options.blacks !== undefined ? Color.getGreen(options.blacks) / 255 : 0; - bb = - options.blacks !== undefined ? Color.getBlue(options.blacks) / 255 : 0; - - wr = - options.whites !== undefined ? Color.getRed(options.whites) / 255 : 1; - wg = - options.whites !== undefined ? Color.getGreen(options.whites) / 255 : 1; - wb = - options.whites !== undefined ? Color.getBlue(options.whites) / 255 : 1; - - mr = options.mids !== undefined ? Color.getRed(options.mids) / 255 : 0.5; - mg = - options.mids !== undefined ? Color.getGreen(options.mids) / 255 : 0.5; - mb = options.mids !== undefined ? Color.getBlue(options.mids) / 255 : 0.5; - - mr = 1 / (1 + 2 * (mr - 0.5)); - mg = 1 / (1 + 2 * (mg - 0.5)); - mb = 1 / (1 + 2 * (mb - 0.5)); - } - - const invSaturation = - saturation !== undefined ? 1 - MathOperators.clamp(saturation, 0, 1) : 0; - const invContrast = - contrast !== undefined ? 1 - MathOperators.clamp(contrast, 0, 1) : 0; - - if (exposure !== undefined) { - exposure = Math.pow(2, exposure); - } - - let hueR = 0; - let hueG = 0; - let hueB = 0; - if (options.hue !== undefined) { - options.hue *= DEG_TO_RAD; - const s = Math.sin(options.hue); - const c = Math.cos(options.hue); - - hueR = (2 * c) / 3; - hueG = (-Math.sqrt(3) * s - c) / 3; - hueB = (Math.sqrt(3) * s - c + 1) / 3; - } - - const invAmount = - amount !== undefined ? 1 - MathOperators.clamp(amount, 0, 1) : 0; - - const pixels = options.src.getBytes(); - for (let i = 0, len = pixels.length; i < len; i += 4) { - const or = pixels[i] / 255; - const og = pixels[i + 1] / 255; - const ob = pixels[i + 2] / 255; - - let r = or; - let g = og; - let b = ob; - - if (useBlacksWhitesMids) { - r = Math.pow((r + br) * wr, mr); - g = Math.pow((g + bg) * wg, mg); - b = Math.pow((b + bb) * wb, mb); - } - - if (brightness !== undefined && brightness !== 1) { - const br = MathOperators.clamp(brightness, 0, 1000); - r *= br; - g *= br; - b *= br; - } - - if (saturation !== undefined) { - const lum = r * lumCoeffR + g * lumCoeffG + b * lumCoeffB; - r = lum * invSaturation + r * saturation; - g = lum * invSaturation + g * saturation; - b = lum * invSaturation + b * saturation; - } - - if (contrast !== undefined) { - r = avgLumR * invContrast + r * contrast; - g = avgLumG * invContrast + g * contrast; - b = avgLumB * invContrast + b * contrast; - } - - if (gamma !== undefined) { - r = Math.pow(r, gamma); - g = Math.pow(g, gamma); - b = Math.pow(b, gamma); - } - - if (exposure !== undefined) { - r *= exposure; - g *= exposure; - b *= exposure; - } - - if (options.hue !== undefined && options.hue !== 0) { - const hr = r * hueR + g * hueG + b * hueB; - const hg = r * hueB + g * hueR + b * hueG; - const hb = r * hueG + g * hueB + b * hueR; - r = hr; - g = hg; - b = hb; - } - - if (amount !== undefined) { - r = r * amount + or * invAmount; - g = g * amount + og * invAmount; - b = b * amount + ob * invAmount; - } - - pixels[i] = MathOperators.clampInt255(r * 255); - pixels[i + 1] = MathOperators.clampInt255(g * 255); - pixels[i + 2] = MathOperators.clampInt255(b * 255); - } - - return options.src; - } - - /** - * Set the **brightness** level for the image **src**. - * **brightness** is an offset that is added to the red, green, and blue channels - * of every pixel. - */ - public static brightness(src: MemoryImage, brightness: number): MemoryImage { - if (brightness === 0) { - return src; - } - - const pixels = src.getBytes(); - for (let i = 0, len = pixels.length; i < len; i += 4) { - pixels[i] = MathOperators.clampInt255(pixels[i] + brightness); - pixels[i + 1] = MathOperators.clampInt255(pixels[i + 1] + brightness); - pixels[i + 2] = MathOperators.clampInt255(pixels[i + 2] + brightness); - } - - return src; - } - - /** - * Generate a normal map from a height-field bump image. - * - * The red channel of the **src** image is used as an input, 0 represents a low - * height and 1 a high value. The optional **strength** parameter allows to set - * the strength of the normal image. - */ - public static bumpToNormal(src: MemoryImage, strength = 2): MemoryImage { - const dest = MemoryImage.from(src); - - for (let y = 0; y < src.height; ++y) { - for (let x = 0; x < src.width; ++x) { - const height = Color.getRed(src.getPixel(x, y)) / 255; - let du = - (height - - Color.getRed(src.getPixel(x < src.width - 1 ? x + 1 : x, y)) / - 255) * - strength; - let dv = - (height - - Color.getRed(src.getPixel(x, y < src.height - 1 ? y + 1 : y)) / - 255) * - strength; - const z = Math.abs(du) + Math.abs(dv); - - if (z > 1) { - du /= z; - dv /= z; - } - - const dw = Math.sqrt(1 - du * du - dv * dv); - const nX = du * 0.5 + 0.5; - const nY = dv * 0.5 + 0.5; - const nZ = dw; - - dest.setPixelRgba( - x, - y, - Math.floor(255 * nX), - Math.floor(255 * nY), - Math.floor(255 * nZ) - ); - } - } - - return dest; - } - - /** - * Add the **red**, **green**, **blue** and **alpha** values to the **src** image - * colors, a per-channel brightness. - */ - public static colorOffset(options: ColorOffsetOptions): MemoryImage { - const pixels = options.src.getBytes(); - for (let i = 0, len = pixels.length; i < len; i += 4) { - pixels[i] = MathOperators.clampInt255(pixels[i] + (options.red ?? 0)); - pixels[i + 1] = MathOperators.clampInt255( - pixels[i + 1] + (options.green ?? 0) - ); - pixels[i + 2] = MathOperators.clampInt255( - pixels[i + 2] + (options.blue ?? 0) - ); - pixels[i + 3] = MathOperators.clampInt255( - pixels[i + 3] + (options.alpha ?? 0) - ); - } - - return options.src; - } - - /** - * Set the **contrast** level for the image **src**. - * - * **contrast** values below 100 will decrees the contrast of the image, - * and values above 100 will increase the contrast. A contrast of 100 - * will have no affect. - */ - public static contrast(src: MemoryImage, contrast: number): MemoryImage { - if (contrast === 100) { - return src; - } - - let c = contrast / 100; - c *= c; - const clevels = new Uint8Array(256); - for (let i = 0; i < 256; ++i) { - clevels[i] = MathOperators.clampInt255( - ((i / 255.0 - 0.5) * c + 0.5) * 255.0 - ); - } - - const p = src.getBytes(); - for (let i = 0, len = p.length; i < len; i += 4) { - p[i] = clevels[p[i]]; - p[i + 1] = clevels[p[i + 1]]; - p[i + 2] = clevels[p[i + 2]]; - } - - return src; - } - - /** - * Apply a 3x3 convolution filter to the **src** image. **filter** should be a - * list of 9 numbers. - * - * The rgb channels will divided by **div** and add **offset**, allowing - * filters to normalize and offset the filtered pixel value. - */ - public static convolution(options: ConvolutionOptions): MemoryImage { - const tmp = MemoryImage.from(options.src); - - for (let y = 0; y < options.src.height; ++y) { - for (let x = 0; x < options.src.width; ++x) { - const c = tmp.getPixel(x, y); - let r = 0; - let g = 0; - let b = 0; - const a = Color.getAlpha(c); - for (let j = 0, fi = 0; j < 3; ++j) { - const yv = Math.min(Math.max(y - 1 + j, 0), options.src.height - 1); - for (let i = 0; i < 3; ++i, ++fi) { - const xv = Math.min(Math.max(x - 1 + i, 0), options.src.width - 1); - const c2 = tmp.getPixel(xv, yv); - r += Color.getRed(c2) * options.filter[fi]; - g += Color.getGreen(c2) * options.filter[fi]; - b += Color.getBlue(c2) * options.filter[fi]; - } - } - - const div = options.div ?? 1; - const offset = options.offset ?? 0; - - r = r / div + offset; - g = g / div + offset; - b = b / div + offset; - - r = r > 255 ? 255 : r < 0 ? 0 : r; - g = g > 255 ? 255 : g < 0 ? 0 : g; - b = b > 255 ? 255 : b < 0 ? 0 : b; - - options.src.setPixel(x, y, Color.getColor(r, g, b, a)); - } - } - - return options.src; - } - - /** - * Apply an emboss convolution filter. - */ - public static emboss(src: MemoryImage): MemoryImage { - const filter = [1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.5]; - - return ImageFilter.convolution({ - src: src, - filter: filter, - div: 1, - offset: 127, - }); - } - - /** - * Apply gaussian blur to the **src** image. **radius** determines how many pixels - * away from the current pixel should contribute to the blur, where 0 is no - * blur and the larger the radius, the stronger the blur. - */ - public static gaussianBlur(src: MemoryImage, radius: number): MemoryImage { - if (radius <= 0) { - return src; - } - - let kernel: SeparableKernel | undefined = undefined; - - if (ImageFilter.gaussianKernelCache.has(radius)) { - kernel = ImageFilter.gaussianKernelCache.get(radius)!; - } else { - // Compute coefficients - const sigma = (radius * 2) / 3; - const s = 2 * sigma * sigma; - - kernel = new SeparableKernel(radius); - - let sum = 0; - for (let x = -radius; x <= radius; ++x) { - const c = Math.exp(-(x * x) / s); - sum += c; - kernel.setCoefficient(x + radius, c); - } - // Normalize the coefficients - kernel.scaleCoefficients(1 / sum); - - // Cache the kernel for this radius so we don't have to recompute it - // next time. - ImageFilter.gaussianKernelCache.set(radius, kernel); - } - - return ImageFilter.separableConvolution(src, kernel); - } - - /** - * Convert the image to grayscale. - */ - public static grayscale(src: MemoryImage): MemoryImage { - const p = src.getBytes(); - for (let i = 0, len = p.length; i < len; i += 4) { - const l = Color.getLuminanceRgb(p[i], p[i + 1], p[i + 2]); - p[i] = l; - p[i + 1] = l; - p[i + 2] = l; - } - return src; - } - - /** - * Invert the colors of the **src** image. - */ - public static invert(src: MemoryImage): MemoryImage { - const p = src.getBytes(); - for (let i = 0, len = p.length; i < len; i += 4) { - p[i] = 255 - p[i]; - p[i + 1] = 255 - p[i + 1]; - p[i + 2] = 255 - p[i + 2]; - } - return src; - } - - /** - * Add random noise to pixel values. **sigma** determines how strong the effect - * should be. **type** should be one of the following: **NoiseType.gaussian**, - * **NoiseType.uniform**, **NoiseType.saltPepper**, **NoiseType.poisson**, - * or **NoiseType.rice**. - */ - public static noise( - image: MemoryImage, - sigma: number, - type: NoiseType = NoiseType.gaussian - ): MemoryImage { - let nsigma = sigma; - let min = 0; - let max = 0; - - if (nsigma === 0 && type !== NoiseType.poisson) { - return image; - } - - if (nsigma < 0 || type === NoiseType.saltPepper) { - const extremes = image.getColorExtremes(); - min = extremes.min; - max = extremes.max; - } - - if (nsigma < 0) { - nsigma = (-nsigma * (max - min)) / 100.0; - } - - const len = image.length; - switch (type) { - case NoiseType.gaussian: - for (let i = 0; i < len; ++i) { - const c = image.getPixelByIndex(i); - const r = Math.trunc(Color.getRed(c) + nsigma * RandomUtils.grand()); - const g = Math.trunc( - Color.getGreen(c) + nsigma * RandomUtils.grand() - ); - const b = Math.trunc(Color.getBlue(c) + nsigma * RandomUtils.grand()); - const a = Color.getAlpha(c); - image.setPixelByIndex(i, Color.getColor(r, g, b, a)); - } - break; - case NoiseType.uniform: - for (let i = 0; i < len; ++i) { - const c = image.getPixelByIndex(i); - const r = Math.trunc(Color.getRed(c) + nsigma * RandomUtils.crand()); - const g = Math.trunc( - Color.getGreen(c) + nsigma * RandomUtils.crand() - ); - const b = Math.trunc(Color.getBlue(c) + nsigma * RandomUtils.crand()); - const a = Color.getAlpha(c); - image.setPixelByIndex(i, Color.getColor(r, g, b, a)); - } - break; - case NoiseType.saltPepper: - if (nsigma < 0) { - nsigma = -nsigma; - } - if (max === min) { - min = 0; - max = 255; - } - for (let i = 0; i < len; ++i) { - const c = image.getPixelByIndex(i); - if (Math.random() * 100 < nsigma) { - const r = Math.random() < 0.5 ? max : min; - const g = Math.random() < 0.5 ? max : min; - const b = Math.random() < 0.5 ? max : min; - const a = Color.getAlpha(c); - image.setPixelByIndex(i, Color.getColor(r, g, b, a)); - } - } - break; - case NoiseType.poisson: - for (let i = 0; i < len; ++i) { - const c = image.getPixelByIndex(i); - const r = RandomUtils.prand(Color.getRed(c)); - const g = RandomUtils.prand(Color.getGreen(c)); - const b = RandomUtils.prand(Color.getBlue(c)); - const a = Color.getAlpha(c); - image.setPixelByIndex(i, Color.getColor(r, g, b, a)); - } - break; - case NoiseType.rice: { - const sqrt2 = Math.sqrt(2); - for (let i = 0; i < len; ++i) { - const c = image.getPixelByIndex(i); - - let val0 = Color.getRed(c) / sqrt2; - let re = val0 + nsigma * RandomUtils.grand(); - let im = val0 + nsigma * RandomUtils.grand(); - let val = Math.sqrt(re * re + im * im); - const r = Math.trunc(val); - - val0 = Color.getGreen(c) / sqrt2; - re = val0 + nsigma * RandomUtils.grand(); - im = val0 + nsigma * RandomUtils.grand(); - val = Math.sqrt(re * re + im * im); - const g = Math.trunc(val); - - val0 = Color.getBlue(c) / sqrt2; - re = val0 + nsigma * RandomUtils.grand(); - im = val0 + nsigma * RandomUtils.grand(); - val = Math.sqrt(re * re + im * im); - const b = Math.trunc(val); - - const a = Color.getAlpha(c); - image.setPixelByIndex(i, Color.getColor(r, g, b, a)); - } - break; - } - } - - return image; - } - - /** - * Linearly normalize the colors of the image. All color values will be mapped - * to the range **minValue**, **maxValue** inclusive. - */ - public static normalize( - src: MemoryImage, - minValue: number, - maxValue: number - ): MemoryImage { - const A = minValue < maxValue ? minValue : maxValue; - const B = minValue < maxValue ? maxValue : minValue; - - const extremes = src.getColorExtremes(); - const min = extremes.min; - const max = extremes.max; - - if (min === max) { - return src.fill(minValue); - } - - if (min !== A || max !== B) { - const p = src.getBytes(); - for (let i = 0, len = p.length; i < len; i += 4) { - p[i] = Math.trunc(((p[i] - min) / (max - min)) * (B - A) + A); - p[i + 1] = Math.trunc(((p[i + 1] - min) / (max - min)) * (B - A) + A); - p[i + 2] = Math.trunc(((p[i + 2] - min) / (max - min)) * (B - A) + A); - p[i + 3] = Math.trunc(((p[i + 3] - min) / (max - min)) * (B - A) + A); - } - } - - return src; - } - - /** - * Pixelate the **src** image. - * - * **blockSize** determines the size of the pixelated blocks. - * If **mode** is **PixelateMode.upperLeft** then the upper-left corner of the block - * will be used for the block color. Otherwise if **mode** is **PixelateMode.average**, - * the average of all the pixels in the block will be used for the block color. - */ - public static pixelate( - src: MemoryImage, - blockSize: number, - mode: PixelateMode = PixelateMode.upperLeft - ): MemoryImage { - if (blockSize <= 1) { - return src; - } - - const bs = blockSize - 1; - - switch (mode) { - case PixelateMode.upperLeft: - for (let y = 0; y < src.height; y += blockSize) { - for (let x = 0; x < src.width; x += blockSize) { - if (src.boundsSafe(x, y)) { - const c = src.getPixel(x, y); - const rect = new Rectangle(x, y, x + bs, y + bs); - Draw.fillRect(src, rect, c); - } - } - } - break; - case PixelateMode.average: - for (let y = 0; y < src.height; y += blockSize) { - for (let x = 0; x < src.width; x += blockSize) { - let a = 0; - let r = 0; - let g = 0; - let b = 0; - let total = 0; - - for (let cy = 0; cy < blockSize; ++cy) { - for (let cx = 0; cx < blockSize; ++cx) { - if (!src.boundsSafe(x + cx, y + cy)) { - continue; - } - const c = src.getPixel(x + cx, y + cy); - a += Color.getAlpha(c); - r += Color.getRed(c); - g += Color.getGreen(c); - b += Color.getBlue(c); - total++; - } - } - - if (total > 0) { - const c = Color.getColor( - Math.trunc(r / total), - Math.trunc(g / total), - Math.trunc(b / total), - Math.trunc(a / total) - ); - const rect = new Rectangle(x, y, x + bs, y + bs); - Draw.fillRect(src, rect, c); - } - } - } - break; - } - - return src; - } - - /** - * Quantize the number of colors in image to 256. - */ - public static quantize(options: QuantizeOptions): MemoryImage { - const numberOfColors = options.numberOfColors ?? 256; - const method = options.method ?? QuantizeMethod.neuralNet; - - if (method === QuantizeMethod.octree || numberOfColors < 4) { - const oct = new OctreeQuantizer(options.src, numberOfColors); - for (let i = 0, len = options.src.length; i < len; ++i) { - options.src.setPixelByIndex( - i, - oct.getQuantizedColor(options.src.getPixelByIndex(i)) - ); - } - return options.src; - } - - const quant = new NeuralQuantizer(options.src, numberOfColors); - for (let i = 0, len = options.src.length; i < len; ++i) { - options.src.setPixelByIndex( - i, - quant.getQuantizedColor(options.src.getPixelByIndex(i)) - ); - } - return options.src; - } - - /** - * Remap the color channels of the image. - * **red**, **green**, **blue** and **alpha** should be set to one of the following: - * **ColorChannel.red**, **ColorChannel.green**, **ColorChannel.blue**, **ColorChannel.alpha**, or - * **ColorChannel.luminance**. For example, - * **_remapColors({ src: src, red: ColorChannel.green, green: ColorChannel.red })_** - * will swap the red and green channels of the image. - * **_remapColors({ src: src, alpha: ColorChannel.luminance })_** - * will set the alpha channel to the luminance (grayscale) of the image. - */ - public static remapColors(options: RemapColorsOptions): MemoryImage { - const red = options.red ?? ColorChannel.red; - const green = options.red ?? ColorChannel.red; - const blue = options.red ?? ColorChannel.red; - const alpha = options.red ?? ColorChannel.red; - - const l = [0, 0, 0, 0, 0]; - const p = options.src.getBytes(); - for (let i = 0, len = p.length; i < len; i += 4) { - l[0] = p[i]; - l[1] = p[i + 1]; - l[2] = p[i + 2]; - l[3] = p[i + 3]; - if ( - red === ColorChannel.luminance || - green === ColorChannel.luminance || - blue === ColorChannel.luminance || - alpha === ColorChannel.luminance - ) { - l[4] = Color.getLuminanceRgb(l[0], l[1], l[2]); - } - p[i] = l[red]; - p[i + 1] = l[green]; - p[i + 2] = l[blue]; - p[i + 3] = l[alpha]; - } - - return options.src; - } - - public static scaleRgba( - src: MemoryImage, - r: number, - g: number, - b: number, - a: number - ): MemoryImage { - const dr = r / 255; - const dg = g / 255; - const db = b / 255; - const da = a / 255; - const bytes = src.getBytes(); - for (let i = 0, len = bytes.length; i < len; i += 4) { - bytes[i] = Math.floor(bytes[i] * dr); - bytes[i + 1] = Math.floor(bytes[i + 1] * dg); - bytes[i + 2] = Math.floor(bytes[i + 2] * db); - bytes[i + 3] = Math.floor(bytes[i + 3] * da); - } - return src; - } - - /** - * Apply a generic separable convolution filter the **src** image, using the - * given **kernel**. - * - * **gaussianBlur** is an example of such a filter. - */ - public static separableConvolution( - src: MemoryImage, - kernel: SeparableKernel - ): MemoryImage { - // Apply the filter horizontally - const tmp = MemoryImage.from(src); - kernel.apply(src, tmp); - // Apply the filter vertically, applying back to the original image. - kernel.apply(tmp, src, false); - return src; - } - - /** - * Apply sepia tone to the image. - * - * **amount** controls the strength of the effect, in the range **0**-**1**. - */ - public static sepia(src: MemoryImage, amount = 1): MemoryImage { - if (amount === 0) { - return src; - } - - const p = src.getBytes(); - for (let i = 0, len = p.length; i < len; i += 4) { - const r = p[i]; - const g = p[i + 1]; - const b = p[i + 2]; - const y = Color.getLuminanceRgb(r, g, b); - p[i] = MathOperators.clampInt255(amount * (y + 38) + (1.0 - amount) * r); - p[i + 1] = MathOperators.clampInt255( - amount * (y + 18) + (1.0 - amount) * g - ); - p[i + 2] = MathOperators.clampInt255( - amount * (y - 31) + (1.0 - amount) * b - ); - } - - return src; - } - - /** - * Apply a smoothing convolution filter to the **src** image. - * - * **w** is the weight of the current pixel being filtered. If it's greater than - * 1, it will make the image sharper. - */ - public static smooth(src: MemoryImage, w: number): MemoryImage { - const filter = [1, 1, 1, 1, w, 1, 1, 1, 1]; - return ImageFilter.convolution({ - src: src, - filter: filter, - div: w + 8, - offset: 0, - }); - } - - /** - * Apply Sobel edge detection filtering to the **src** Image. - */ - public static sobel(src: MemoryImage, amount = 1): MemoryImage { - const invAmount = 1 - amount; - const orig = ImageFilter.grayscale(MemoryImage.from(src)); - const origRGBA = orig.getBytes(); - const rowSize = src.width * 4; - const rgba = src.getBytes(); - const rgbaLen = rgba.length; - for (let y = 0, pi = 0; y < src.height; ++y) { - for (let x = 0; x < src.width; ++x, pi += 4) { - const bl = pi + rowSize - 4; - const b = pi + rowSize; - const br = pi + rowSize + 4; - const l = pi - 4; - const r = pi + 4; - const tl = pi - rowSize - 4; - const t = pi - rowSize; - const tr = pi - rowSize + 4; - - const tlInt = tl < 0 ? 0 : origRGBA[tl] / 255; - const tInt = t < 0 ? 0 : origRGBA[t] / 255; - const trInt = tr < 0 ? 0 : origRGBA[tr] / 255; - const lInt = l < 0 ? 0 : origRGBA[l] / 255; - const rInt = r < rgbaLen ? origRGBA[r] / 255 : 0; - const blInt = bl < rgbaLen ? origRGBA[bl] / 255 : 0; - const bInt = b < rgbaLen ? origRGBA[b] / 255 : 0; - const brInt = br < rgbaLen ? origRGBA[br] / 255 : 0; - - const h = -tlInt - 2 * tInt - trInt + blInt + 2 * bInt + brInt; - const v = -blInt - 2 * lInt - tlInt + brInt + 2 * rInt + trInt; - - const mag = MathOperators.clampInt255(Math.sqrt(h * h + v * v) * 255); - - rgba[pi] = MathOperators.clampInt255( - mag * amount + rgba[pi] * invAmount - ); - rgba[pi + 1] = MathOperators.clampInt255( - mag * amount + rgba[pi + 1] * invAmount - ); - rgba[pi + 2] = MathOperators.clampInt255( - mag * amount + rgba[pi + 2] * invAmount - ); - } - } - - return src; - } - - public static vignette(options: VignetteOptions): MemoryImage { - const start = options.start ?? 0.3; - const end = options.end ?? 0.75; - const amount = options.amount ?? 0.8; - - const h = options.src.height - 1; - const w = options.src.width - 1; - const invAmt = 1 - amount; - const p = options.src.getBytes(); - for (let y = 0, i = 0; y <= h; ++y) { - const dy = 0.5 - y / h; - for (let x = 0; x <= w; ++x, i += 4) { - const dx = 0.5 - x / w; - - let d = Math.sqrt(dx * dx + dy * dy); - d = ImageFilter.smoothVignetteStep(end, start, d); - - p[i] = MathOperators.clampInt255(amount * p[i] * d + invAmt * p[i]); - p[i + 1] = MathOperators.clampInt255( - amount * p[i + 1] * d + invAmt * p[i + 1] - ); - p[i + 2] = MathOperators.clampInt255( - amount * p[i + 2] * d + invAmt * p[i + 2] - ); - } - } - - return options.src; - } -} diff --git a/src/filter/noise-type.ts b/src/filter/noise-type.ts index bb4fc32..37272d7 100644 --- a/src/filter/noise-type.ts +++ b/src/filter/noise-type.ts @@ -3,7 +3,7 @@ export enum NoiseType { gaussian, uniform, - saltPepper, + saltAndPepper, poisson, rice, } diff --git a/src/filter/quantize-options.ts b/src/filter/quantize-options.ts deleted file mode 100644 index ab1e61f..0000000 --- a/src/filter/quantize-options.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** @format */ - -import { MemoryImage } from '../common/memory-image'; -import { QuantizeMethod } from './quantize-method'; - -export interface QuantizeOptions { - src: MemoryImage; - numberOfColors?: number; - method?: QuantizeMethod; -} diff --git a/src/filter/remap-colors-options.ts b/src/filter/remap-colors-options.ts deleted file mode 100644 index ce32179..0000000 --- a/src/filter/remap-colors-options.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** @format */ - -import { ColorChannel } from '../common/color-channel'; -import { MemoryImage } from '../common/memory-image'; - -export interface RemapColorsOptions { - src: MemoryImage; - red?: ColorChannel; - green?: ColorChannel; - blue?: ColorChannel; - alpha?: ColorChannel; -} diff --git a/src/filter/separable-kernel.ts b/src/filter/separable-kernel.ts index 7e0a22b..620652f 100644 --- a/src/filter/separable-kernel.ts +++ b/src/filter/separable-kernel.ts @@ -1,28 +1,38 @@ /** @format */ -import { Color } from '../common/color'; -import { MemoryImage } from '../common/memory-image'; +import { Channel } from '../color/channel'; +import { ArrayUtils } from '../common/array-utils'; +import { MathUtils } from '../common/math-utils'; +import { MemoryImage } from '../image/image'; + +export interface SeparableKernelApplyOptions { + src: MemoryImage; + dst: MemoryImage; + horizontal?: boolean; + maskChannel?: Channel; + mask?: MemoryImage; +} /** - * A kernel object to use with **separableConvolution** filtering. + * A kernel object to use with **separableConvolution** filter. */ export class SeparableKernel { - private readonly coefficients: number[]; - private readonly size: number; + private readonly _coefficients: number[]; + private readonly _size: number; /** * Get the number of coefficients in the kernel. */ public get length() { - return this.coefficients.length; + return this._coefficients.length; } /** - * Create a separable convolution kernel for the given **radius**. + * Create a separable convolution kernel for the given **size**. */ constructor(size: number) { - this.size = size; - this.coefficients = new Array(2 * size + 1).fill(0); + this._size = size; + this._coefficients = ArrayUtils.fill(2 * size + 1, 0); } private reflect(max: number, x: number): number { @@ -35,12 +45,14 @@ export class SeparableKernel { return x; } - private applyCoeffsLine( + private applyCoefficientsLine( src: MemoryImage, dst: MemoryImage, y: number, width: number, - horizontal: boolean + horizontal: boolean, + maskChannel: Channel, + mask?: MemoryImage ): void { for (let x = 0; x < width; x++) { let r = 0; @@ -48,29 +60,28 @@ export class SeparableKernel { let b = 0; let a = 0; - for (let j = -this.size, j2 = 0; j <= this.size; ++j, ++j2) { - const coeff = this.coefficients[j2]; + for (let j = -this._size, j2 = 0; j <= this._size; ++j, ++j2) { + const c = this._coefficients[j2]; const gr = this.reflect(width, x + j); const sc = horizontal ? src.getPixel(gr, y) : src.getPixel(y, gr); - r += coeff * Color.getRed(sc); - g += coeff * Color.getGreen(sc); - b += coeff * Color.getBlue(sc); - a += coeff * Color.getAlpha(sc); + r += c * sc.r; + g += c * sc.g; + b += c * sc.b; + a += c * sc.a; } - const c = Color.getColor( - r > 255 ? 255 : r, - g > 255 ? 255 : g, - b > 255 ? 255 : b, - a > 255 ? 255 : a - ); + const p = horizontal ? dst.getPixel(x, y) : dst.getPixel(y, x); - if (horizontal) { - dst.setPixel(x, y, c); + const msk = mask?.getPixel(p.x, p.y).getChannelNormalized(maskChannel); + if (msk === undefined) { + p.setRgba(r, g, b, a); } else { - dst.setPixel(y, x, c); + p.r = MathUtils.mix(p.r, r, msk); + p.g = MathUtils.mix(p.g, g, msk); + p.b = MathUtils.mix(p.b, b, msk); + p.a = MathUtils.mix(p.a, a, msk); } } } @@ -79,30 +90,49 @@ export class SeparableKernel { * Get a coefficient from the kernel. */ public getCoefficient(index: number) { - return this.coefficients[index]; + return this._coefficients[index]; } /** * Set a coefficient in the kernel. */ public setCoefficient(index: number, c: number) { - this.coefficients[index] = c; + this._coefficients[index] = c; } /** * Apply the kernel to the **src** image, storing the results in **dst**, * for a single dimension. If **horizontal** is true, the filter will be - * applied to the horizontal axis, otherwise it will be appied to the + * applied to the horizontal axis, otherwise it will be applied to the * vertical axis. */ - public apply(src: MemoryImage, dst: MemoryImage, horizontal = true): void { + public apply(opt: SeparableKernelApplyOptions): void { + const horizontal = opt.horizontal ?? true; + const maskChannel = opt.maskChannel ?? Channel.luminance; + if (horizontal) { - for (let y = 0; y < src.height; ++y) { - this.applyCoeffsLine(src, dst, y, src.width, horizontal); + for (let y = 0; y < opt.src.height; ++y) { + this.applyCoefficientsLine( + opt.src, + opt.dst, + y, + opt.src.width, + horizontal, + maskChannel, + opt.mask + ); } } else { - for (let x = 0; x < src.width; ++x) { - this.applyCoeffsLine(src, dst, x, src.height, horizontal); + for (let x = 0; x < opt.src.width; ++x) { + this.applyCoefficientsLine( + opt.src, + opt.dst, + x, + opt.src.height, + horizontal, + maskChannel, + opt.mask + ); } } } @@ -111,8 +141,8 @@ export class SeparableKernel { * Scale all of the coefficients by **s**. */ public scaleCoefficients(s: number): void { - for (let i = 0; i < this.coefficients.length; ++i) { - this.coefficients[i] *= s; + for (let i = 0; i < this._coefficients.length; ++i) { + this._coefficients[i] *= s; } } } diff --git a/src/filter/vignette-options.ts b/src/filter/vignette-options.ts deleted file mode 100644 index 8069917..0000000 --- a/src/filter/vignette-options.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** @format */ - -import { MemoryImage } from '../common/memory-image'; - -export interface VignetteOptions { - src: MemoryImage; - start?: number; - end?: number; - amount?: number; -} diff --git a/src/formats/bmp-decoder.ts b/src/formats/bmp-decoder.ts index 170804d..57b95b0 100644 --- a/src/formats/bmp-decoder.ts +++ b/src/formats/bmp-decoder.ts @@ -1,31 +1,30 @@ /** @format */ -import { FrameAnimation } from '../common/frame-animation'; +import { Format } from '../color/format'; import { InputBuffer } from '../common/input-buffer'; -import { MemoryImage } from '../common/memory-image'; -import { HdrImage } from '../hdr/hdr-image'; -import { BitmapFileHeader } from './bmp/bitmap-file-header'; +import { MemoryImage } from '../image/image'; +import { BmpFileHeader } from './bmp/bmp-file-header'; import { BmpInfo } from './bmp/bmp-info'; import { Decoder } from './decoder'; export class BmpDecoder implements Decoder { - protected input?: InputBuffer; - - protected info?: BmpInfo; + protected _input?: InputBuffer; + protected _info?: BmpInfo; + protected _forceRgba: boolean; public get numFrames(): number { - return this.info !== undefined ? this.info.numFrames : 0; + return this._info !== undefined ? this._info.numFrames : 0; } - private pixelDataOffset(): number | undefined { - return this.info !== undefined ? this.info.fileHeader.offset : undefined; + constructor(forceRgba = false) { + this._forceRgba = forceRgba; } /** * Is the given file a valid BMP image? */ public isValidFile(bytes: Uint8Array): boolean { - return BitmapFileHeader.isValidFile( + return BmpFileHeader.isValidFile( new InputBuffer({ buffer: bytes, }) @@ -36,46 +35,86 @@ export class BmpDecoder implements Decoder { if (!this.isValidFile(bytes)) { return undefined; } - this.input = new InputBuffer({ + this._input = new InputBuffer({ buffer: bytes, }); - this.info = new BmpInfo(this.input); - return this.info; + this._info = new BmpInfo(this._input); + return this._info; } /** * Decode a single frame from the data stat was set with **startDecode**. * If **frame** is out of the range of available frames, undefined is returned. - * Non animated image files will only have **frame** 0. An **AnimationFrame** + * Non animated image files will only have **frame** 0. An animation frame * is returned, which provides the image, and top-left coordinates of the * image, as animated frames may only occupy a subset of the canvas. */ - public decodeFrame(_: number): MemoryImage | undefined { - if (this.input === undefined || this.info === undefined) { - return undefined; - } - - const offset = this.pixelDataOffset(); - if (offset === undefined) { + public decodeFrame(_frame: number): MemoryImage | undefined { + if (this._input === undefined || this._info === undefined) { return undefined; } - this.input.offset = offset; - let rowStride = (this.info.width * this.info.bpp) >> 3; - if (rowStride % 4 !== 0) { - rowStride += 4 - (rowStride % 4); - } + const inf = this._info; + this._input.offset = inf.header.imageOffset; + + const bpp = inf.bitsPerPixel; + const rowStride = Math.trunc((inf.width * bpp + 31) / 32) * 4; + const nc = this._forceRgba + ? 4 + : bpp === 1 || bpp === 4 || bpp === 8 + ? 1 + : bpp === 32 + ? 4 + : 3; + const format = this._forceRgba + ? Format.uint8 + : bpp === 1 + ? Format.uint1 + : bpp === 2 + ? Format.uint2 + : bpp === 4 + ? Format.uint4 + : bpp === 8 + ? Format.uint8 + : bpp === 16 + ? Format.uint8 + : bpp === 24 + ? Format.uint8 + : bpp === 32 + ? Format.uint8 + : Format.uint8; + const palette = this._forceRgba ? undefined : inf.palette; const image = new MemoryImage({ - width: this.info.width, - height: this.info.height, + width: inf.width, + height: inf.height, + format: format, + numChannels: nc, + palette: palette, }); + for (let y = image.height - 1; y >= 0; --y) { - const line = this.info.readBottomUp ? y : image.height - 1 - y; - const row = this.input.readBytes(rowStride); - for (let x = 0; x < image.width; ) { - this.info.decodeRgba(row, (color) => { - return image.setPixelSafe(x++, line, color); + const line = inf.readBottomUp ? y : image.height - 1 - y; + const row = this._input.readBytes(rowStride); + const w = image.width; + let x = 0; + const p = image.getPixel(0, line); + while (x < w) { + inf.decodePixel(row, (r, g, b, a) => { + if (x < w) { + if (this._forceRgba && inf.palette !== undefined) { + const pi = Math.trunc(r); + const pr = inf.palette!.getRed(pi); + const pg = inf.palette!.getGreen(pi); + const pb = inf.palette!.getBlue(pi); + const pa = inf.palette!.getAlpha(pi); + p.setRgba(pr, pg, pb, pa); + } else { + p.setRgba(r, g, b, a); + } + p.next(); + x++; + } }); } } @@ -83,54 +122,15 @@ export class BmpDecoder implements Decoder { return image; } - public decodeHdrFrame(frame: number): HdrImage | undefined { - const img = this.decodeFrame(frame); - if (img === undefined) { - return undefined; - } - return HdrImage.fromImage(img); - } - - /** - * Decode all of the frames from an animation. If the file is not an - * animation, a single frame animation is returned. If there was a problem - * decoding the file, undefined is returned. - */ - public decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined { - if (!this.isValidFile(bytes)) { - return undefined; - } - - const image = this.decodeImage(bytes); - if (image === undefined) { - return undefined; - } - - const animation = new FrameAnimation(); - animation.addFrame(image); - - return animation; - } - /** * Decode the file and extract a single image from it. If the file is * animated, the specified **frame** will be decoded. If there was a problem * decoding the file, undefined is returned. */ - public decodeImage(bytes: Uint8Array, frame = 0): MemoryImage | undefined { - if (!this.isValidFile(bytes)) { - return undefined; - } - - this.startDecode(bytes); - return this.decodeFrame(frame); - } - - public decodeHdrImage(bytes: Uint8Array, frame = 0): HdrImage | undefined { - const img = this.decodeImage(bytes, frame); - if (img === undefined) { + public decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined { + if (this.startDecode(bytes) === undefined) { return undefined; } - return HdrImage.fromImage(img); + return this.decodeFrame(frame ?? 0); } } diff --git a/src/formats/bmp-encoder.ts b/src/formats/bmp-encoder.ts index b516dc6..d454875 100644 --- a/src/formats/bmp-encoder.ts +++ b/src/formats/bmp-encoder.ts @@ -1,11 +1,11 @@ /** @format */ -import { Color } from '../common/color'; -import { FrameAnimation } from '../common/frame-animation'; -import { MemoryImage } from '../common/memory-image'; +import { Format } from '../color/format'; import { OutputBuffer } from '../common/output-buffer'; -import { RgbChannelSet } from '../common/rgb-channel-set'; -import { BitmapFileHeader } from './bmp/bitmap-file-header'; +import { MemoryImage } from '../image/image'; +import { PaletteUint8 } from '../image/palette-uint8'; +import { BmpCompressionMode } from './bmp/bmp-compression-mode'; +import { BmpFileHeader } from './bmp/bmp-file-header'; import { Encoder } from './encoder'; /** @@ -13,70 +13,350 @@ import { Encoder } from './encoder'; */ export class BmpEncoder implements Encoder { private _supportsAnimation = false; - get supportsAnimation(): boolean { + public get supportsAnimation(): boolean { return this._supportsAnimation; } - public encodeImage(image: MemoryImage): Uint8Array { - const bytesPerPixel = image.rgbChannelSet === RgbChannelSet.rgb ? 3 : 4; - const bpp = bytesPerPixel * 8; - const rgbSize = image.width * image.height * bytesPerPixel; - const headerSize = 54; - const headerInfoSize = 40; - const fileSize = rgbSize + headerSize; - + public encode(image: MemoryImage, _singleFrame = false): Uint8Array { const out = new OutputBuffer(); + let img = image; + + const nc = img.numChannels; + let palette = img.palette; + const format = img.format; + + if (format === Format.uint1 && nc === 1 && palette === undefined) { + // add palette + palette = new PaletteUint8(2, 3); + palette.setRgb(0, 0, 0, 0); + palette.setRgb(1, 255, 255, 255); + } else if (format === Format.uint1 && nc === 2) { + // => uint2 palette + img = img.convert({ + format: Format.uint2, + numChannels: 1, + withPalette: true, + }); + palette = img.palette; + } else if (format === Format.uint1 && nc === 3 && palette === undefined) { + // => uint4 palette + img = img.convert({ + format: Format.uint4, + withPalette: true, + }); + palette = img.palette; + } else if (format === Format.uint1 && nc === 4) { + // => uint8,4 - only 32bpp supports alpha + img = img.convert({ + format: Format.uint8, + numChannels: 4, + }); + } else if (format === Format.uint2 && nc === 1 && palette === undefined) { + // => uint2 palette + img = img.convert({ + format: Format.uint2, + withPalette: true, + }); + palette = img.palette; + } else if (format === Format.uint2 && nc === 2) { + // => uint8 palette + img = img.convert({ + format: Format.uint8, + withPalette: true, + }); + palette = img.palette; + } else if (format === Format.uint2 && nc === 3 && palette === undefined) { + // => uint8 palette + img = img.convert({ + format: Format.uint8, + withPalette: true, + }); + palette = img.palette; + } else if (format === Format.uint2 && nc === 4) { + // => uint8 palette + img = img.convert({ + format: Format.uint8, + withPalette: true, + }); + palette = img.palette; + } else if (format === Format.uint4 && nc === 1 && palette === undefined) { + // => uint8 palette + img = img.convert({ + format: Format.uint8, + withPalette: true, + }); + palette = img.palette; + } else if (format === Format.uint4 && nc === 2) { + // => uint8,3 + img = img.convert({ + format: Format.uint8, + numChannels: 3, + }); + } else if (format === Format.uint4 && nc === 3 && palette === undefined) { + // => uint8,3 + img = img.convert({ + format: Format.uint8, + numChannels: 3, + }); + } else if (format === Format.uint4 && nc === 4) { + // => uint8,4 + img = img.convert({ + format: Format.uint8, + numChannels: 4, + }); + } else if (format === Format.uint8 && nc === 1 && palette === undefined) { + // => uint8 palette + img = img.convert({ + format: Format.uint8, + withPalette: true, + }); + } else if (format === Format.uint8 && nc === 2) { + // => uint8,3 + img = img.convert({ + format: Format.uint8, + numChannels: 3, + }); + } else if (img.isHdrFormat) { + // => uint8,[3,4] + img = img.convert({ + format: Format.uint8, + }); + } else if (img.hasPalette && img.numChannels === 4) { + img = img.convert({ + numChannels: 4, + }); + } + + let bpp = img.bitsPerChannel * img.data!.numChannels; + if (bpp === 12) { + bpp = 16; + } + + const compression = + bpp > 8 ? BmpCompressionMode.bitfields : BmpCompressionMode.none; + + const imageStride = img.rowStride; + const fileStride = Math.trunc((img.width * bpp + 31) / 32) * 4; + const rowPaddingSize = fileStride - imageStride; + const rowPadding = + rowPaddingSize > 0 + ? new Uint8Array(rowPaddingSize).fill(0xff) + : undefined; + const imageFileSize = fileStride * img.height; + const headerInfoSize = bpp > 8 ? 124 : 40; + const headerSize = headerInfoSize + 14; + const paletteSize = (img.palette?.numColors ?? 0) * 4; + const origImageOffset = headerSize + paletteSize; + const imageOffset = origImageOffset; + const gapSize = imageOffset - origImageOffset; + const fileSize = imageFileSize + headerSize + paletteSize + gapSize; - out.writeUint16(BitmapFileHeader.BMP_HEADER_FILETYPE); + const sRgb = 0x73524742; + + out.writeUint16(BmpFileHeader.signature); out.writeUint32(fileSize); - // Reserved + // reserved out.writeUint32(0); - - out.writeUint32(headerSize); + // offset to image data + out.writeUint32(imageOffset); out.writeUint32(headerInfoSize); - out.writeUint32(image.width); - out.writeUint32(-image.height); - // Planes + out.writeUint32(img.width); + out.writeUint32(img.height); + // planes out.writeUint16(1); + // bits per pixel out.writeUint16(bpp); - // Compress - out.writeUint32(0); - out.writeUint32(rgbSize); - // Hr - out.writeUint32(0); - // Vr - out.writeUint32(0); - // Colors - out.writeUint32(0); - // ImportantColors - out.writeUint32(0); + // compression + out.writeUint32(compression); - for (let y = 0, pi = 0; y < image.height; ++y) { - for (let x = 0; x < image.width; ++x, ++pi) { - const rgba = image.getPixelByIndex(pi); - out.writeByte(Color.getBlue(rgba)); - out.writeByte(Color.getGreen(rgba)); - out.writeByte(Color.getRed(rgba)); - if (bytesPerPixel === 4) { - out.writeByte(Color.getAlpha(rgba)); + out.writeUint32(imageFileSize); + // hr + out.writeUint32(11811); + // vr + out.writeUint32(11811); + // totalColors + out.writeUint32(bpp === 8 ? 255 : 0); + // importantColors + out.writeUint32(bpp === 8 ? 255 : 0); + + if (bpp > 8) { + const blueMask = bpp === 16 ? 0xf : 0xff; + const greenMask = bpp === 16 ? 0xf0 : 0xff00; + const redMask = bpp === 16 ? 0xf00 : 0xff0000; + const alphaMask = bpp === 16 ? 0xf000 : 0xff000000; + + // redMask + out.writeUint32(redMask); + // greenMask + out.writeUint32(greenMask); + // blueMask + out.writeUint32(blueMask); + // alphaMask + out.writeUint32(alphaMask); + // CSType + out.writeUint32(sRgb); + // endpoints.red.x + out.writeUint32(0); + // endpoints.red.y + out.writeUint32(0); + // endpoints.red.z + out.writeUint32(0); + // endpoints.green.x + out.writeUint32(0); + // endpoints.green.y + out.writeUint32(0); + // endpoints.green.z + out.writeUint32(0); + // endpoints.blue.x + out.writeUint32(0); + // endpoints.blue.y + out.writeUint32(0); + // endpoints.blue.z + out.writeUint32(0); + // gammaRed + out.writeUint32(0); + // gammaGreen + out.writeUint32(0); + // gammaBlue + out.writeUint32(0); + // intent LCS_GM_GRAPHICS + out.writeUint32(2); + // profileData + out.writeUint32(0); + // profileSize + out.writeUint32(0); + // reserved + out.writeUint32(0); + } + + if (bpp === 1 || bpp === 2 || bpp === 4 || bpp === 8) { + if (palette !== undefined) { + const l = palette.numColors; + for (let pi = 0; pi < l; ++pi) { + out.writeByte(Math.trunc(palette.getBlue(pi))); + out.writeByte(Math.trunc(palette.getGreen(pi))); + out.writeByte(Math.trunc(palette.getRed(pi))); + out.writeByte(0); + } + } else { + if (bpp === 1) { + out.writeByte(0); + out.writeByte(0); + out.writeByte(0); + out.writeByte(0); + out.writeByte(255); + out.writeByte(255); + out.writeByte(255); + out.writeByte(0); + } else if (bpp === 2) { + for (let pi = 0; pi < 4; ++pi) { + const v = pi * 85; + out.writeByte(v); + out.writeByte(v); + out.writeByte(v); + out.writeByte(0); + } + } else if (bpp === 4) { + for (let pi = 0; pi < 16; ++pi) { + const v = pi * 17; + out.writeByte(v); + out.writeByte(v); + out.writeByte(v); + out.writeByte(0); + } + } else if (bpp === 8) { + for (let pi = 0; pi < 256; ++pi) { + out.writeByte(pi); + out.writeByte(pi); + out.writeByte(pi); + out.writeByte(0); + } } } + } + + // image data must be aligned to a 4 byte alignment. Pad the remaining + // bytes until the image starts. + let gap1 = gapSize; + while (gap1-- > 0) { + out.writeByte(0); + } - // Line padding - if (bytesPerPixel !== 4) { - const padding = 4 - ((image.width * bytesPerPixel) % 4); - if (padding !== 4) { - const bytes = new Uint8Array(padding - 1).fill(0x00); + // Write image data + if (bpp === 1 || bpp === 2 || bpp === 4 || bpp === 8) { + let offset = img.byteLength - imageStride; + const h = img.height; + for (let y = 0; y < h; ++y) { + const bytes = + img.buffer !== undefined + ? new Uint8Array(img.buffer, offset, imageStride) + : new Uint8Array(); + + if (bpp === 1) { + out.writeBytes(bytes); + } else if (bpp === 2) { + const l = bytes.length; + for (let xi = 0; xi < l; ++xi) { + const b = bytes[xi]; + const left = b >> 4; + const right = b & 0x0f; + const rb = (right << 4) | left; + out.writeByte(rb); + } + } else if (bpp === 4) { + const l = bytes.length; + for (let xi = 0; xi < l; ++xi) { + const b = bytes[xi]; + const b1 = b >> 4; + const b2 = b & 0x0f; + const rb = (b1 << 4) | b2; + out.writeByte(rb); + } + } else { out.writeBytes(bytes); - out.writeByte(0xff); } + + if (rowPadding !== undefined) { + out.writeBytes(rowPadding); + } + + offset -= imageStride; } + + return out.getBytes(); } - return out.getBytes(); - } + const hasAlpha = img.numChannels === 4; + const h = img.height; + const w = img.width; + if (bpp === 16) { + for (let y = h - 1; y >= 0; --y) { + for (let x = 0; x < w; ++x) { + const p = img.getPixel(x, y); + out.writeByte((Math.trunc(p.g) << 4) | Math.trunc(p.b)); + out.writeByte((Math.trunc(p.a) << 4) | Math.trunc(p.r)); + } + if (rowPadding !== undefined) { + out.writeBytes(rowPadding); + } + } + } else { + for (let y = h - 1; y >= 0; --y) { + for (let x = 0; x < w; ++x) { + const p = img.getPixel(x, y); + out.writeByte(Math.trunc(p.b)); + out.writeByte(Math.trunc(p.g)); + out.writeByte(Math.trunc(p.r)); + if (hasAlpha) { + out.writeByte(Math.trunc(p.a)); + } + } + if (rowPadding !== undefined) { + out.writeBytes(rowPadding); + } + } + } - public encodeAnimation(_: FrameAnimation): Uint8Array | undefined { - return undefined; + return out.getBytes(); } } diff --git a/src/formats/bmp/bitmap-compression-mode.ts b/src/formats/bmp/bitmap-compression-mode.ts deleted file mode 100644 index dda719e..0000000 --- a/src/formats/bmp/bitmap-compression-mode.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** @format */ - -export enum BitmapCompressionMode { - BI_BITFIELDS, - NONE, -} diff --git a/src/formats/bmp/bitmap-file-header.ts b/src/formats/bmp/bitmap-file-header.ts deleted file mode 100644 index 50de58f..0000000 --- a/src/formats/bmp/bitmap-file-header.ts +++ /dev/null @@ -1,49 +0,0 @@ -/** @format */ - -import { InputBuffer } from '../../common/input-buffer'; -import { ImageError } from '../../error/image-error'; - -export class BitmapFileHeader { - // BM - public static readonly BMP_HEADER_FILETYPE = 0x42 + (0x4d << 8); - - private readonly _fileLength: number; - public get fileLength(): number { - return this._fileLength; - } - - private _offset: number; - public set offset(v: number) { - this._offset = v; - } - public get offset(): number { - return this._offset; - } - - constructor(b: InputBuffer) { - if (!BitmapFileHeader.isValidFile(b)) { - throw new ImageError('Not a bitmap file.'); - } - b.skip(2); - this._fileLength = b.readInt32(); - // Skip reserved space - b.skip(4); - this._offset = b.readInt32(); - } - - public static isValidFile(b: InputBuffer): boolean { - if (b.length < 2) { - return false; - } - const type = InputBuffer.from(b).readUint16(); - return type === BitmapFileHeader.BMP_HEADER_FILETYPE; - } - - public toJson(): Map { - return new Map([ - ['offset', this._offset], - ['fileLength', this.fileLength], - ['fileType', BitmapFileHeader.BMP_HEADER_FILETYPE], - ]); - } -} diff --git a/src/formats/bmp/bmp-compression-mode.ts b/src/formats/bmp/bmp-compression-mode.ts new file mode 100644 index 0000000..86557db --- /dev/null +++ b/src/formats/bmp/bmp-compression-mode.ts @@ -0,0 +1,18 @@ +/** @format */ + +export enum BmpCompressionMode { + none, + rle8, + rle4, + bitfields, + jpeg, + png, + alphaBitfields, + reserved7, + reserved8, + reserved9, + reserved10, + cmyk, + cmykRle8, + cmykRle4, +} diff --git a/src/formats/bmp/bmp-file-header.ts b/src/formats/bmp/bmp-file-header.ts new file mode 100644 index 0000000..961a506 --- /dev/null +++ b/src/formats/bmp/bmp-file-header.ts @@ -0,0 +1,41 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { LibError } from '../../error/lib-error'; + +export class BmpFileHeader { + // Signature: BM + public static readonly signature = 0x4d42; + + private readonly _fileLength: number; + public get fileLength(): number { + return this._fileLength; + } + + private _imageOffset: number; + public set imageOffset(v: number) { + this._imageOffset = v; + } + public get imageOffset(): number { + return this._imageOffset; + } + + constructor(b: InputBuffer) { + if (!BmpFileHeader.isValidFile(b)) { + throw new LibError('Not a bitmap file.'); + } + b.skip(2); + this._fileLength = b.readInt32(); + // Skip reserved space + b.skip(4); + this._imageOffset = b.readInt32(); + } + + public static isValidFile(b: InputBuffer): boolean { + if (b.length < 2) { + return false; + } + const type = InputBuffer.from(b).readUint16(); + return type === BmpFileHeader.signature; + } +} diff --git a/src/formats/bmp/bmp-info.ts b/src/formats/bmp/bmp-info.ts index 5d3584d..5e139ff 100644 --- a/src/formats/bmp/bmp-info.ts +++ b/src/formats/bmp/bmp-info.ts @@ -1,15 +1,25 @@ /** @format */ -import { BitOperators } from '../../common/bit-operators'; -import { Color } from '../../common/color'; +import { Color } from '../../color/color'; +import { BitUtils } from '../../common/bit-utils'; import { InputBuffer } from '../../common/input-buffer'; -import { ImageError } from '../../error/image-error'; -import { NotImplementedError } from '../../error/not-implemented-error'; +import { LibError } from '../../error/lib-error'; +import { PaletteUint8 } from '../../image/palette-uint8'; import { DecodeInfo } from '../decode-info'; -import { BitmapCompressionMode } from './bitmap-compression-mode'; -import { BitmapFileHeader } from './bitmap-file-header'; +import { BmpCompressionMode } from './bmp-compression-mode'; +import { BmpFileHeader } from './bmp-file-header'; export class BmpInfo implements DecodeInfo { + private readonly _startPos: number; + private _redShift = 0; + private _redScale = 0; + private _greenShift = 0; + private _greenScale = 0; + private _blueShift = 0; + private _blueScale = 0; + private _alphaShift = 0; + private _alphaScale = 0; + private readonly _width: number = 0; public get width(): number { return this._width; @@ -17,11 +27,11 @@ export class BmpInfo implements DecodeInfo { protected readonly _height: number = 0; public get height(): number { - return this._height; + return Math.abs(this._height); } - private readonly _backgroundColor: number = 0xffffffff; - public get backgroundColor(): number { + private readonly _backgroundColor: Color | undefined = undefined; + public get backgroundColor(): Color | undefined { return this._backgroundColor; } @@ -30,9 +40,9 @@ export class BmpInfo implements DecodeInfo { return this._numFrames; } - private readonly _fileHeader: BitmapFileHeader; - public get fileHeader(): BitmapFileHeader { - return this._fileHeader; + private readonly _header: BmpFileHeader; + public get header(): BmpFileHeader { + return this._header; } private readonly _headerSize: number; @@ -45,13 +55,13 @@ export class BmpInfo implements DecodeInfo { return this._planes; } - private readonly _bpp: number; - public get bpp(): number { - return this._bpp; + private readonly _bitsPerPixel: number; + public get bitsPerPixel(): number { + return this._bitsPerPixel; } - private readonly _compression: BitmapCompressionMode; - public get compression(): BitmapCompressionMode { + private readonly _compression: BmpCompressionMode; + public get compression(): BmpCompressionMode { return this._compression; } @@ -80,208 +90,257 @@ export class BmpInfo implements DecodeInfo { return this._importantColors; } - private readonly _readBottomUp: boolean; - public get readBottomUp(): boolean { - return this._readBottomUp; + private _redMask = 0; + public get redMask(): number { + return this._redMask; } - private _v5redMask?: number; - public get v5redMask(): number | undefined { - return this._v5redMask; + private _greenMask = 0; + public get greenMask(): number { + return this._greenMask; } - private _v5greenMask?: number; - public get v5greenMask(): number | undefined { - return this._v5greenMask; + private _blueMask = 0; + public get blueMask(): number { + return this._blueMask; } - private _v5blueMask?: number; - public get v5blueMask(): number | undefined { - return this._v5blueMask; + private _alphaMask = 0; + public get alphaMask(): number { + return this._alphaMask; } - private _v5alphaMask?: number; - public get v5alphaMask(): number | undefined { - return this._v5alphaMask; + private _palette: PaletteUint8 | undefined; + public get palette(): PaletteUint8 | undefined { + return this._palette; } - private _colorPalette?: number[]; - public get colorPalette(): number[] | undefined { - return this._colorPalette; + public get readBottomUp(): boolean { + return this._height >= 0; } - // BITMAPINFOHEADER should (probably) ignore alpha channel altogether. - // This is the behavior in gimp (?) - // https://gitlab.gnome.org/GNOME/gimp/-/issues/461#note_208715 public get ignoreAlphaChannel(): boolean { + // Gimp and Photoshop ignore the alpha channel for BITMAPINFOHEADER. return ( this._headerSize === 40 || - // BITMAPV5HEADER with undefined alpha mask. - (this._headerSize === 124 && this._v5alphaMask === 0) + // BITMAPV5HEADER with null alpha mask. + (this._headerSize === 124 && this._alphaMask === 0) ); } - constructor(p: InputBuffer, fileHeader?: BitmapFileHeader) { - this._fileHeader = fileHeader ?? new BitmapFileHeader(p); + constructor(p: InputBuffer, header?: BmpFileHeader) { + this._header = header ?? new BmpFileHeader(p); + this._startPos = p.offset; this._headerSize = p.readUint32(); this._width = p.readInt32(); - - const height = p.readInt32(); - this._readBottomUp = height > 0; - this._height = Math.abs(height); - + this._height = p.readInt32(); this._planes = p.readUint16(); - this._bpp = p.readUint16(); - this._compression = BmpInfo.intToCompressionMode(p.readUint32()); + this._bitsPerPixel = p.readUint16(); + this._compression = p.readUint32(); this._imageSize = p.readUint32(); this._xppm = p.readInt32(); this._yppm = p.readInt32(); this._totalColors = p.readUint32(); this._importantColors = p.readUint32(); - if ([1, 4, 8].includes(this._bpp)) { - this.readPalette(p); - } - if (this._headerSize === 124) { - // BITMAPV5HEADER - this._v5redMask = p.readUint32(); - this._v5greenMask = p.readUint32(); - this._v5blueMask = p.readUint32(); - this._v5alphaMask = p.readUint32(); - } - } + // BMP allows > 4 bit per channel for 16bpp, so we have to scale it + // up to 8-bit + const maxChannelValue = 255.0; - private static intToCompressionMode( - compIndex: number - ): BitmapCompressionMode { - const map = new Map([ - [0, BitmapCompressionMode.NONE], - // [ 1, BitmapCompression.RLE_8 ], - // [ 2, BitmapCompression.RLE_4 ], - [3, BitmapCompressionMode.BI_BITFIELDS], - ]); - const compression = map.get(compIndex); - if (compression === undefined) { - throw new ImageError( - `Bitmap compression ${compIndex} is not supported yet.` - ); + if ( + this._headerSize > 40 || + this._compression === BmpCompressionMode.bitfields || + this._compression === BmpCompressionMode.alphaBitfields + ) { + this._redMask = p.readUint32(); + this._redShift = BitUtils.countTrailingZeroBits(this._redMask); + const redDepth = this._redMask >> this._redShift; + this._redScale = redDepth > 0 ? maxChannelValue / redDepth : 0; + + this._greenMask = p.readUint32(); + this._greenShift = BitUtils.countTrailingZeroBits(this._greenMask); + const greenDepth = this._greenMask >> this._greenShift; + this._greenScale = redDepth > 0 ? maxChannelValue / greenDepth : 0; + + this._blueMask = p.readUint32(); + this._blueShift = BitUtils.countTrailingZeroBits(this._blueMask); + const blueDepth = this._blueMask >> this._blueShift; + this._blueScale = redDepth > 0 ? maxChannelValue / blueDepth : 0; + + if ( + this._headerSize > 40 || + this._compression === BmpCompressionMode.alphaBitfields + ) { + this._alphaMask = p.readUint32(); + this._alphaShift = BitUtils.countTrailingZeroBits(this._alphaMask); + const alphaDepth = this._alphaMask >>> this._alphaShift; + this._alphaScale = alphaDepth > 0 ? maxChannelValue / alphaDepth : 0; + } else { + if (this._bitsPerPixel === 16) { + this._alphaMask = 0xff000000; + this._alphaShift = 24; + this._alphaScale = 1.0; + } else { + this._alphaMask = 0xff000000; + this._alphaShift = 24; + this._alphaScale = 1.0; + } + } + } else { + if (this._bitsPerPixel === 16) { + this._redMask = 0x7c00; + this._redShift = 10; + const redDepth = this._redMask >> this._redShift; + this._redScale = redDepth > 0 ? maxChannelValue / redDepth : 0; + + this._greenMask = 0x03e0; + this._greenShift = 5; + const greenDepth = this._greenMask >> this._greenShift; + this._greenScale = redDepth > 0 ? maxChannelValue / greenDepth : 0; + + this._blueMask = 0x001f; + this._blueShift = 0; + const blueDepth = this._blueMask >> this._blueShift; + this._blueScale = redDepth > 0 ? maxChannelValue / blueDepth : 0; + + this._alphaMask = 0x00000000; + this._alphaShift = 0; + this._alphaScale = 0.0; + } else { + this._redMask = 0x00ff0000; + this._redShift = 16; + this._redScale = 1.0; + + this._greenMask = 0x0000ff00; + this._greenShift = 8; + this._greenScale = 1.0; + + this._blueMask = 0x000000ff; + this._blueShift = 0; + this._blueScale = 1.0; + + this._alphaMask = 0xff000000; + this._alphaShift = 24; + this._alphaScale = 1.0; + } } - return compression; - } - private compressionModeToString(): string { - switch (this._compression) { - case BitmapCompressionMode.BI_BITFIELDS: - return 'BI_BITFIELDS'; - case BitmapCompressionMode.NONE: - return 'none'; - } - throw new NotImplementedError(); - } + const headerRead = p.offset - this._startPos; - private readPalette(p: InputBuffer): void { - const colors = this._totalColors === 0 ? 1 << this._bpp : this._totalColors; - const colorBytes = this._headerSize === 12 ? 3 : 4; - const colorPalette: number[] = []; - for (let i = 0; i < colors; i++) { - const color = this.readRgba(p, colorBytes === 3 ? 100 : undefined); - colorPalette.push(color); + const remainingHeaderBytes = this._headerSize - headerRead; + p.skip(remainingHeaderBytes); + + if (this._bitsPerPixel <= 8) { + this.readPalette(p); } - this._colorPalette = colorPalette; } - private readRgba(input: InputBuffer, aDefault?: number): number { - if (this._readBottomUp) { + private readPalette(input: InputBuffer): void { + const numColors = + this._totalColors === 0 ? 1 << this._bitsPerPixel : this._totalColors; + const numChannels = 3; + this._palette = new PaletteUint8(numColors, numChannels); + for (let i = 0; i < numColors; ++i) { const b = input.readByte(); const g = input.readByte(); const r = input.readByte(); - const a = aDefault ?? input.readByte(); - return Color.getColor(r, g, b, this.ignoreAlphaChannel ? 255 : a); - } else { - const r = input.readByte(); - const b = input.readByte(); - const g = input.readByte(); - const a = aDefault ?? input.readByte(); - return Color.getColor(r, b, g, this.ignoreAlphaChannel ? 255 : a); + // ignored + const a = input.readByte(); + this._palette.setRgba(i, r, g, b, a); } } - public decodeRgba(input: InputBuffer, pixel: (color: number) => void): void { - if (this._colorPalette !== undefined) { - if (this._bpp === 1) { - const b = input.readByte().toString(2).padStart(8, '0'); - for (let i = 0; i < 8; i++) { - pixel(this._colorPalette![parseInt(b[i])]); + public decodePixel( + input: InputBuffer, + pixel: (r: number, g: number, b: number, a: number) => void + ): void { + if (this._palette !== undefined) { + if (this._bitsPerPixel === 1) { + const bi = input.readByte(); + for (let i = 7; i >= 0; --i) { + const b = (bi >> i) & 0x1; + pixel(b, 0, 0, 0); } return; - } else if (this._bpp === 4) { - const b = input.readByte(); - const left = b >> 4; - const right = b & 0x0f; - pixel(this._colorPalette[left]); - pixel(this._colorPalette[right]); + } else if (this._bitsPerPixel === 2) { + const bi = input.readByte(); + for (let i = 6; i >= 0; i -= 2) { + const b = (bi >> i) & 0x2; + pixel(b, 0, 0, 0); + } + } else if (this._bitsPerPixel === 4) { + const bi = input.readByte(); + const b1 = (bi >> 4) & 0xf; + pixel(b1, 0, 0, 0); + const b2 = bi & 0xf; + pixel(b2, 0, 0, 0); return; - } else if (this._bpp === 8) { + } else if (this._bitsPerPixel === 8) { const b = input.readByte(); - pixel(this._colorPalette[b]); + pixel(b, 0, 0, 0); return; } } + if ( - this._bpp === 32 && - this._compression === BitmapCompressionMode.BI_BITFIELDS + this._compression === BmpCompressionMode.bitfields && + this._bitsPerPixel === 32 ) { - pixel(this.readRgba(input)); + const p = input.readUint32(); + const r = Math.trunc( + ((p & this._redMask) >> this._redShift) * this._redScale + ); + const g = Math.trunc( + ((p & this._greenMask) >> this._greenShift) * this._greenScale + ); + const b = Math.trunc( + ((p & this._blueMask) >> this._blueShift) * this._blueScale + ); + const a = this.ignoreAlphaChannel + ? 255 + : Math.trunc( + ((p & this._alphaMask) >> this._alphaShift) * this._alphaScale + ); + pixel(r, g, b, a); return; - } - if (this._bpp === 32 && this._compression === BitmapCompressionMode.NONE) { - pixel(this.readRgba(input)); + } else if ( + this._bitsPerPixel === 32 && + this._compression === BmpCompressionMode.none + ) { + const b = input.readByte(); + const g = input.readByte(); + const r = input.readByte(); + const a = input.readByte(); + pixel(r, g, b, this.ignoreAlphaChannel ? 255 : a); return; - } - if (this._bpp === 24) { - pixel(this.readRgba(input, 255)); + } else if (this._bitsPerPixel === 24) { + const b = input.readByte(); + const g = input.readByte(); + const r = input.readByte(); + pixel(r, g, b, 255); + return; + } else if (this._bitsPerPixel === 16) { + const p = input.readUint16(); + const r = Math.trunc( + ((p & this._redMask) >> this._redShift) * this._redScale + ); + const g = Math.trunc( + ((p & this._greenMask) >> this._greenShift) * this._greenScale + ); + const b = Math.trunc( + ((p & this._blueMask) >> this._blueShift) * this._blueScale + ); + const a = this.ignoreAlphaChannel + ? 255 + : Math.trunc( + ((p & this._alphaMask) >> this._alphaShift) * this._alphaScale + ); + pixel(r, g, b, a); return; + } else { + throw new LibError( + `Unsupported bitsPerPixel (${this._bitsPerPixel}) or compression (${this._compression}).` + ); } - // If (this.bpp === 16) { - // return this._rgbaFrom16(input); - // } - throw new ImageError( - `Unsupported bpp (${this._bpp}) or compression (${this._compression}).` - ); - } - - // TODO: finish decoding for 16 bit - // private rgbaFrom16(input: InputBuffer): number[] { - // const maskRed = 0x7C00; - // const maskGreen = 0x3E0; - // const maskBlue = 0x1F; - // const pixel = input.readUint16(); - // return [ (pixel & maskRed), (pixel & maskGreen), (pixel & maskBlue), 0 ]; - // } - - public toString(): string { - return JSON.stringify( - { - headerSize: this._headerSize, - width: this._width, - height: this._height, - planes: this._planes, - bpp: this._bpp, - file: this._fileHeader.toJson(), - compression: this.compressionModeToString(), - imageSize: this._imageSize, - xppm: this._xppm, - yppm: this._yppm, - totalColors: this._totalColors, - importantColors: this._importantColors, - readBottomUp: this._readBottomUp, - v5redMask: BitOperators.debugBits32(this._v5redMask), - v5greenMask: BitOperators.debugBits32(this._v5greenMask), - v5blueMask: BitOperators.debugBits32(this._v5blueMask), - v5alphaMask: BitOperators.debugBits32(this._v5alphaMask), - }, - undefined, - 2 - ); } } diff --git a/src/formats/decode-info.ts b/src/formats/decode-info.ts index 2e1789f..12ace45 100644 --- a/src/formats/decode-info.ts +++ b/src/formats/decode-info.ts @@ -1,5 +1,7 @@ /** @format */ +import { Color } from '../color/color'; + /** * Provides information about the image being decoded. */ @@ -17,7 +19,7 @@ export interface DecodeInfo { /** * The suggested background color of the canvas. */ - get backgroundColor(): number; + get backgroundColor(): Color | undefined; /** * The number of frames that can be decoded. diff --git a/src/formats/decoder.ts b/src/formats/decoder.ts index 6735bdd..f992be9 100644 --- a/src/formats/decoder.ts +++ b/src/formats/decoder.ts @@ -1,8 +1,6 @@ /** @format */ -import { FrameAnimation } from '../common/frame-animation'; -import { MemoryImage } from '../common/memory-image'; -import { HdrImage } from '../hdr/hdr-image'; +import { MemoryImage } from '../image/image'; import { DecodeInfo } from './decode-info'; /** @@ -13,36 +11,14 @@ import { DecodeInfo } from './decode-info'; * can reduce the color resolution back down to their required formats. * * Some image formats support multiple frames, often for encoding animation. - * In such cases, the **decodeImage** method will decode the first (or otherwise - * specified with the **frame** parameter) frame of the file. **decodeAnimation** - * will decode all frames from the image. **startDecode** will initiate - * decoding of the file, and **decodeFrame** will then decode a specific frame - * from the file, allowing for animations to be decoded one frame at a time. - * Some formats, such as TIFF, may store multiple frames, but their use of - * frames is for multiple page documents and not animation. The terms - * 'animation' and 'frames' simply refer to 'pages' in this case. - * - * If an image file does not have multiple frames, **decodeAnimation** and - * **startDecode** / **decodeFrame** will return the single image of the - * file. As such, if you are not sure if a file is animated or not, you can - * use the animated functions and process it as a single frame image if it - * has only 1 frame, and as an animation if it has more than 1 frame. - * - * Most animated formats do not store full images for frames, but rather - * some frames will store full images and others will store partial 'change' - * images. For these files, **decodeAnimation** will always return all images - * fully composited, meaning full frame images. Decoding frames individually - * using **startDecode** and **decodeFrame** will return the potentially partial - * image. In this case, the **DecodeInfo** returned by **startDecode** will include - * the width and height resolution of the animation canvas, and each **MemoryImage** - * returned by **decodeFrame** will have x, y, width and height properties - * indicating where in the canvas the frame image should be drawn. It will - * also have a disposeMethod property that specifies what should be done to - * the canvas prior to drawing the frame: **DisposeMode.none** indicates the - * canvas should be left alone; **DisposeMode.clear** indicates the canvas - * should be cleared. For partial frame images,**DisposeMode.none** is used - * so that the partial-frame is drawn on top of the previous frame, applying - * it's changes to the image. + * In such cases, the **decode** method will decode all of the frames, + * unless the frame argument is specified for a particular frame to decode. + * **startDecode** will initiate decoding of the file, and **decodeFrame** will + * then decode a specific frame from the file, allowing for animations to be + * decoded one frame at a time. Some formats, such as TIFF, may store multiple + * frames, but their use of frames is for multiple page documents and not + * animation. The terms 'animation' and 'frames' simply refer to 'pages' in + * this case. */ export interface Decoder { /** @@ -59,51 +35,25 @@ export interface Decoder { /** * Start decoding the data as an animation sequence, but don't actually - * process the frames until they are requested with decodeFrame. + * process the frames until they are requested with **decodeFrame**. */ startDecode(bytes: Uint8Array): DecodeInfo | undefined; /** - * Decode a single frame from the data that was set with **startDecode**. - * If **frame** is out of the range of available frames, undefined is returned. - * Non animated image files will only have **frame** 0. A **MemoryImage** - * is returned, which provides the image, and top-left coordinates of the - * image, as animated frames may only occupy a subset of the canvas. + * Decode the file and extract a single image from it. If the file is + * animated, and **frame** is specified, that particular frame will be decoded. + * Otherwise if the image is animated and **frame** is undefined, the returned + * MemoryImage will include all frames. If there was a problem decoding the + * MemoryImage, undefined will be returned. */ - decodeFrame(frame: number): MemoryImage | undefined; + decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined; /** - * Decode a single high dynamic range (HDR) frame from the data that was set - * with **startDecode**. If the format of the file does not support HDR images, - * the regular image will be converted to an HDR image as (color / 255). + * Decode a single frame from the data that was set with **startDecode**. * If **frame** is out of the range of available frames, undefined is returned. - * Non animated image files will only have **frame** 0. A **MemoryImage** + * Non animated image files will only have **frame** 0. A MemoryImage * is returned, which provides the image, and top-left coordinates of the * image, as animated frames may only occupy a subset of the canvas. */ - decodeHdrFrame(frame: number): HdrImage | undefined; - - /** - * Decode all of the frames from an animation. If the file is not an - * animation, a single frame animation is returned. If there was a problem - * decoding the file, undefined is returned. - */ - decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined; - - /** - * Decode the file and extract a single image from it. If the file is - * animated, the specified **frame** will be decoded. If there was a problem - * decoding the file, undefined is returned. - */ - decodeImage(bytes: Uint8Array, frame?: number): MemoryImage | undefined; - - /** - * Decode the file and extract a single High Dynamic Range (HDR) image from - * it. HDR images are stored in floating-poing values. If the format of the - * file does not support HDR images, the regular image will be converted to - * an HDR image as (color / 255). If the file is animated, the specified - * **frame** will be decoded. If there was a problem decoding the file, undefined is - * returned. - */ - decodeHdrImage(bytes: Uint8Array, frame?: number): HdrImage | undefined; + decodeFrame(frame: number): MemoryImage | undefined; } diff --git a/src/formats/dib-decoder.ts b/src/formats/dib-decoder.ts index d3ed533..2c408d7 100644 --- a/src/formats/dib-decoder.ts +++ b/src/formats/dib-decoder.ts @@ -5,9 +5,9 @@ import { BmpDecoder } from './bmp-decoder'; import { BmpInfo } from './bmp/bmp-info'; export class DibDecoder extends BmpDecoder { - constructor(input: InputBuffer, info: BmpInfo) { - super(); - this.input = input; - this.info = info; + constructor(input: InputBuffer, info: BmpInfo, forceRgba = false) { + super(forceRgba); + this._input = input; + this._info = info; } } diff --git a/src/formats/encoder.ts b/src/formats/encoder.ts index ce9f3d3..747035f 100644 --- a/src/formats/encoder.ts +++ b/src/formats/encoder.ts @@ -1,25 +1,21 @@ /** @format */ -import { FrameAnimation } from '../common/frame-animation'; -import { MemoryImage } from '../common/memory-image'; +import { MemoryImage } from '../image/image'; /** * Base class for image format encoders. */ export interface Encoder { /** - * Does this encoder support animation? + * True if the encoder supports animated images; otherwise false. */ get supportsAnimation(): boolean; /** - * Encode a single image. + * Encode an **image** to an image format. + * If **singleFrame** is true, only the one MemoryImage will be encoded; + * otherwise if image has animation, all frames of the **image** will be + * encoded if the encoder supports animation. */ - encodeImage(image: MemoryImage): Uint8Array; - - /** - * Encode an animation. Not all formats support animation, and undefined - * will be returned if not. - */ - encodeAnimation(animation: FrameAnimation): Uint8Array | undefined; + encode(image: MemoryImage, singleFrame?: boolean): Uint8Array; } diff --git a/src/formats/gif-decoder.ts b/src/formats/gif-decoder.ts index bbe3c56..a5fc1e2 100644 --- a/src/formats/gif-decoder.ts +++ b/src/formats/gif-decoder.ts @@ -1,91 +1,81 @@ /** @format */ -import { FrameAnimation } from '../common/frame-animation'; import { InputBuffer } from '../common/input-buffer'; import { ArrayUtils } from '../common/array-utils'; -import { MemoryImage } from '../common/memory-image'; -import { ImageError } from '../error/image-error'; -import { HdrImage } from '../hdr/hdr-image'; -import { ImageTransform } from '../transform/image-transform'; import { Decoder } from './decoder'; import { GifColorMap } from './gif/gif-color-map'; import { GifImageDesc } from './gif/gif-image-desc'; import { GifInfo } from './gif/gif-info'; +import { MemoryImage } from '../image/image'; +import { ColorUint8 } from '../color/color-uint8'; /** * A decoder for the GIF image format. This supports both single frame and * animated GIF files, and transparency. */ export class GifDecoder implements Decoder { - private static readonly STAMP_SIZE: number = 6; + private static readonly _stampSize: number = 6; + private static readonly _gif87Stamp: string = 'GIF87a'; + private static readonly _gif89Stamp: string = 'GIF89a'; - private static readonly GIF87_STAMP: string = 'GIF87a'; + private static readonly _imageDescRecordType: number = 0x2c; + private static readonly _extensionRecordType: number = 0x21; + private static readonly _terminateRecordType: number = 0x3b; - private static readonly GIF89_STAMP: string = 'GIF89a'; + private static readonly _graphicControlExt: number = 0xf9; + private static readonly _applicationExt: number = 0xff; - private static readonly IMAGE_DESC_RECORD_TYPE: number = 0x2c; - - private static readonly EXTENSION_RECORD_TYPE: number = 0x21; - - private static readonly TERMINATE_RECORD_TYPE: number = 0x3b; - - private static readonly GRAPHIC_CONTROL_EXT: number = 0xf9; - - private static readonly APPLICATION_EXT: number = 0xff; - - private static readonly LZ_MAX_CODE: number = 4095; - - private static readonly LZ_BITS: number = 12; + private static readonly _lzMaxCode: number = 4095; + private static readonly _lzBits: number = 12; // Impossible code, to signal empty. - private static readonly NO_SUCH_CODE: number = 4098; + private static readonly _noSuchCode: number = 4098; - private static readonly CODE_MASKS: number[] = [ + private static readonly _codeMasks: number[] = [ 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, ]; - private static readonly INTERLACED_OFFSET: number[] = [0, 4, 2, 1]; - - private static readonly INTERLACED_JUMP: number[] = [8, 8, 4, 2]; + private static readonly _interlacedOffset: number[] = [0, 4, 2, 1]; + private static readonly _interlacedJump: number[] = [8, 8, 4, 2]; - private info?: GifInfo; + private _input?: InputBuffer; - private input?: InputBuffer; + private _info?: GifInfo; - private repeat = 0; + private _repeat = 0; - private buffer?: Uint8Array; + private _buffer?: Uint8Array; - private stack!: Uint8Array; + private _stack!: Uint8Array; - private suffix!: Uint8Array; + private _suffix!: Uint8Array; - private prefix?: Uint32Array; + private _prefix?: Uint32Array; - private bitsPerPixel = 0; + private _bitsPerPixel = 0; - private pixelCount?: number; + private _pixelCount?: number; - private currentShiftDWord = 0; + private _currentShiftDWord = 0; - private currentShiftState = 0; + private _currentShiftState = 0; - private stackPtr = 0; + private _stackPtr = 0; - private currentCode?: number; + private _currentCode?: number; - private lastCode = 0; + private _lastCode = 0; - private maxCode1 = 0; + private _maxCode1 = 0; - private runningBits = 0; + private _runningBits = 0; - private runningCode = 0; + private _runningCode = 0; - private eofCode = 0; + private _eofCode = 0; - private clearCode = 0; + private _clearCode = 0; /** * How many frames are available to decode? @@ -94,7 +84,7 @@ export class GifDecoder implements Decoder { * to the constructor, or calling getInfo. */ public get numFrames(): number { - return this.info !== undefined ? this.info.numFrames : 0; + return this._info !== undefined ? this._info.numFrames : 0; } constructor(bytes?: Uint8Array) { @@ -107,7 +97,7 @@ export class GifDecoder implements Decoder { * Routine to trace the Prefixes linked list until we get a prefix which is * not code, but a pixel value (less than ClearCode). Returns that pixel value. * If image is defective, we might loop here forever, so we limit the loops to - * the maximum possible if image O.k. - LZ_MAX_CODE times. + * the maximum possible if image O.k. - lzMaxCode times. */ private static getPrefixChar( prefix: Uint32Array, @@ -116,11 +106,11 @@ export class GifDecoder implements Decoder { ): number { let c = code; let i = 0; - while (c > clearCode && i++ <= GifDecoder.LZ_MAX_CODE) { - if (c > GifDecoder.LZ_MAX_CODE) { - return GifDecoder.NO_SUCH_CODE; + while (c > clearCode && i++ <= GifDecoder._lzMaxCode) { + if (c > GifDecoder._lzMaxCode) { + return GifDecoder._noSuchCode; } - c = prefix[code]; + c = prefix[c]; } return c; } @@ -132,52 +122,53 @@ export class GifDecoder implements Decoder { line: Uint8Array ): void { if (colorMap !== undefined) { - for (let x = 0, width = line.length; x < width; ++x) { - image.setPixel(x, y, colorMap.getColor(line[x])); + const width = line.length; + for (let x = 0; x < width; ++x) { + image.setPixelRgb(x, y, line[x], 0, 0); } } } private getInfo(): boolean { - if (this.input === undefined) { + if (this._input === undefined) { return false; } - const tag = this.input.readString(GifDecoder.STAMP_SIZE); - if (tag !== GifDecoder.GIF87_STAMP && tag !== GifDecoder.GIF89_STAMP) { + const tag = this._input.readString(GifDecoder._stampSize); + if (tag !== GifDecoder._gif87Stamp && tag !== GifDecoder._gif89Stamp) { return false; } - const width = this.input.readUint16(); - const height = this.input.readUint16(); + const width = this._input.readUint16(); + const height = this._input.readUint16(); - const b = this.input.readByte(); + const b = this._input.readByte(); const colorResolution = (((b & 0x70) + 1) >> 4) + 1; const bitsPerPixel = (b & 0x07) + 1; - const backgroundColor = this.input.readByte(); + const backgroundColor = new ColorUint8( + new Uint8Array([this._input.readByte()]) + ); - this.input.skip(1); + this._input.skip(1); let globalColorMap: GifColorMap | undefined = undefined; // Is there a global color map? if ((b & 0x80) !== 0) { - globalColorMap = new GifColorMap({ - numColors: 1 << bitsPerPixel, - }); + globalColorMap = new GifColorMap(1 << bitsPerPixel); // Get the global color map: for (let i = 0; i < globalColorMap.numColors; ++i) { - const r = this.input.readByte(); - const g = this.input.readByte(); - const b = this.input.readByte(); + const r = this._input.readByte(); + const g = this._input.readByte(); + const b = this._input.readByte(); globalColorMap.setColor(i, r, g, b); } } - const isGif89 = tag === GifDecoder.GIF89_STAMP; + const isGif89 = tag === GifDecoder._gif89Stamp; - this.info = new GifInfo({ + this._info = new GifInfo({ width: width, height: height, colorResolution: colorResolution, @@ -190,11 +181,11 @@ export class GifDecoder implements Decoder { } private skipImage(): GifImageDesc | undefined { - if (this.input === undefined || this.input.isEOS) { + if (this._input === undefined || this._input.isEOS) { return undefined; } - const gifImage = new GifImageDesc(this.input); - this.input.skip(1); + const gifImage = new GifImageDesc(this._input); + this._input.skip(1); this.skipRemainder(); return gifImage; } @@ -205,16 +196,16 @@ export class GifDecoder implements Decoder { * The block should NOT be freed by the user (not dynamically allocated). */ private skipRemainder(): boolean { - if (this.input === undefined || this.input.isEOS) { + if (this._input === undefined || this._input.isEOS) { return true; } - let b = this.input.readByte(); - while (b !== 0 && !this.input.isEOS) { - this.input.skip(b); - if (this.input.isEOS) { + let b = this._input.readByte(); + while (b !== 0 && !this._input.isEOS) { + this._input.skip(b); + if (this._input.isEOS) { return true; } - b = this.input.readByte(); + b = this._input.readByte(); } return true; } @@ -226,7 +217,7 @@ export class GifDecoder implements Decoder { const b1 = input.readByte(); const b2 = input.readByte(); if (b1 === 0x03 && b2 === 0x01) { - this.repeat = input.readUint16(); + this._repeat = input.readUint16(); } } else { this.skipRemainder(); @@ -246,7 +237,7 @@ export class GifDecoder implements Decoder { const transparentFlag = b & 0x1; const recordType = input.peekBytes(1).getByte(0); - if (recordType === GifDecoder.IMAGE_DESC_RECORD_TYPE) { + if (recordType === GifDecoder._imageDescRecordType) { input.skip(1); const gifImage = this.skipImage(); if (gifImage === undefined) { @@ -259,94 +250,28 @@ export class GifDecoder implements Decoder { if (transparentFlag !== 0) { if ( gifImage.colorMap === undefined && - this.info!.globalColorMap !== undefined + this._info!.globalColorMap !== undefined ) { - gifImage.colorMap = GifColorMap.from(this.info!.globalColorMap); + gifImage.colorMap = GifColorMap.from(this._info!.globalColorMap); } if (gifImage.colorMap !== undefined) { gifImage.colorMap.transparent = transparent; } } - this.info!.frames.push(gifImage); - } - } - - private decodeFrameImage(gifImage: GifImageDesc): MemoryImage | undefined { - if (this.buffer === undefined) { - this.initDecode(); - } - - this.bitsPerPixel = this.input!.readByte(); - this.clearCode = 1 << this.bitsPerPixel; - this.eofCode = this.clearCode + 1; - this.runningCode = this.eofCode + 1; - this.runningBits = this.bitsPerPixel + 1; - this.maxCode1 = 1 << this.runningBits; - this.stackPtr = 0; - this.lastCode = GifDecoder.NO_SUCH_CODE; - this.currentShiftState = 0; - this.currentShiftDWord = 0; - this.buffer![0] = 0; - this.prefix!.fill(GifDecoder.NO_SUCH_CODE, 0, this.prefix!.length); - - const width = gifImage.width; - const height = gifImage.height; - - if ( - gifImage.x + width > this.info!.width || - gifImage.y + height > this.info!.height - ) { - return undefined; - } - - const colorMap = - gifImage.colorMap !== undefined - ? gifImage.colorMap - : this.info!.globalColorMap; - - this.pixelCount = width * height; - - const image = new MemoryImage({ - width: width, - height: height, - }); - const line = new Uint8Array(width); - - if (gifImage.interlaced) { - const row = gifImage.y; - for (let i = 0, j = 0; i < 4; ++i) { - for ( - let y = row + GifDecoder.INTERLACED_OFFSET[i]; - y < row + height; - y += GifDecoder.INTERLACED_JUMP[i], ++j - ) { - if (!this.getLine(line)) { - return image; - } - GifDecoder.updateImage(image, y, colorMap, line); - } - } - } else { - for (let y = 0; y < height; ++y) { - if (!this.getLine(line)) { - return image; - } - GifDecoder.updateImage(image, y, colorMap, line); - } + this._info!.frames.push(gifImage); } - return image; } private getLine(line: Uint8Array): boolean { - this.pixelCount = this.pixelCount! - line.length; + this._pixelCount = this._pixelCount! - line.length; if (!this.decompressLine(line)) { return false; } // Flush any remainder blocks. - if (this.pixelCount === 0) { + if (this._pixelCount === 0) { this.skipRemainder(); } @@ -360,17 +285,17 @@ export class GifDecoder implements Decoder { * order the complete the whole image. */ private decompressLine(line: Uint8Array): boolean { - if (this.stackPtr > GifDecoder.LZ_MAX_CODE) { + if (this._stackPtr > GifDecoder._lzMaxCode) { return false; } const lineLen = line.length; let i = 0; - if (this.stackPtr !== 0) { + if (this._stackPtr !== 0) { // Let pop the stack off before continuing to read the gif file: - while (this.stackPtr !== 0 && i < lineLen) { - line[i++] = this.stack[--this.stackPtr]; + while (this._stackPtr !== 0 && i < lineLen) { + line[i++] = this._stack[--this._stackPtr]; } } @@ -378,118 +303,118 @@ export class GifDecoder implements Decoder { // Decode LineLen items. while (i < lineLen) { - this.currentCode = this.decompressInput(); - if (this.currentCode === undefined) { + this._currentCode = this.decompressInput(); + if (this._currentCode === undefined) { return false; } - if (this.currentCode === this.eofCode) { + if (this._currentCode === this._eofCode) { // Note however that usually we will not be here as we will stop // decoding as soon as we got all the pixel, or EOF code will // not be read at all, and DGifGetLine/Pixel clean everything. return false; } - if (this.currentCode === this.clearCode) { + if (this._currentCode === this._clearCode) { // We need to start over again: - for (let j = 0; j <= GifDecoder.LZ_MAX_CODE; j++) { - this.prefix![j] = GifDecoder.NO_SUCH_CODE; + for (let j = 0; j <= GifDecoder._lzMaxCode; j++) { + this._prefix![j] = GifDecoder._noSuchCode; } - this.runningCode = this.eofCode + 1; - this.runningBits = this.bitsPerPixel + 1; - this.maxCode1 = 1 << this.runningBits; - this.lastCode = GifDecoder.NO_SUCH_CODE; + this._runningCode = this._eofCode + 1; + this._runningBits = this._bitsPerPixel + 1; + this._maxCode1 = 1 << this._runningBits; + this._lastCode = GifDecoder._noSuchCode; } else { // Its regular code - if in pixel range simply add it to output // stream, otherwise trace to codes linked list until the prefix // is in pixel range: - if (this.currentCode < this.clearCode) { + if (this._currentCode < this._clearCode) { // This is simple - its pixel scalar, so add it to output: - line[i++] = this.currentCode; + line[i++] = this._currentCode; } else { // Its a code to needed to be traced: trace the linked list // until the prefix is a pixel, while pushing the suffix // pixels on our stack. If we done, pop the stack in reverse // (thats what stack is good for!) order to output. */ - if (this.prefix![this.currentCode] === GifDecoder.NO_SUCH_CODE) { + if (this._prefix![this._currentCode] === GifDecoder._noSuchCode) { // Only allowed if CrntCode is exactly the running code: // In that case CrntCode = XXXCode, CrntCode or the // prefix code is last code and the suffix char is // exactly the prefix of last code! - if (this.currentCode === this.runningCode - 2) { - currentPrefix = this.lastCode; + if (this._currentCode === this._runningCode - 2) { + currentPrefix = this._lastCode; const prefixChar = GifDecoder.getPrefixChar( - this.prefix!, - this.lastCode, - this.clearCode + this._prefix!, + this._lastCode, + this._clearCode ); - this.stack[this.stackPtr++] = prefixChar; - this.suffix[this.runningCode - 2] = prefixChar; + this._stack[this._stackPtr++] = prefixChar; + this._suffix[this._runningCode - 2] = prefixChar; } else { return false; } } else { - currentPrefix = this.currentCode; + currentPrefix = this._currentCode; } - // Now (if image is O.K.) we should not get an NO_SUCH_CODE + // Now (if image is O.K.) we should not get an noSuchCode // During the trace. As we might loop forever, in case of // defective image, we count the number of loops we trace - // and stop if we got LZ_MAX_CODE. obviously we can not + // and stop if we got lzMaxCode. obviously we can not // loop more than that. let j = 0; while ( - j++ <= GifDecoder.LZ_MAX_CODE && - currentPrefix > this.clearCode && - currentPrefix <= GifDecoder.LZ_MAX_CODE + j++ <= GifDecoder._lzMaxCode && + currentPrefix > this._clearCode && + currentPrefix <= GifDecoder._lzMaxCode ) { - this.stack[this.stackPtr++] = this.suffix[currentPrefix]; - currentPrefix = this.prefix![currentPrefix]; + this._stack[this._stackPtr++] = this._suffix[currentPrefix]; + currentPrefix = this._prefix![currentPrefix]; } if ( - j >= GifDecoder.LZ_MAX_CODE || - currentPrefix > GifDecoder.LZ_MAX_CODE + j >= GifDecoder._lzMaxCode || + currentPrefix > GifDecoder._lzMaxCode ) { return false; } // Push the last character on stack: - this.stack[this.stackPtr++] = currentPrefix; + this._stack[this._stackPtr++] = currentPrefix; // Now lets pop all the stack into output: - while (this.stackPtr !== 0 && i < lineLen) { - line[i++] = this.stack[--this.stackPtr]; + while (this._stackPtr !== 0 && i < lineLen) { + line[i++] = this._stack[--this._stackPtr]; } } if ( - this.lastCode !== GifDecoder.NO_SUCH_CODE && - this.prefix![this.runningCode - 2] === GifDecoder.NO_SUCH_CODE + this._lastCode !== GifDecoder._noSuchCode && + this._prefix![this._runningCode - 2] === GifDecoder._noSuchCode ) { - this.prefix![this.runningCode - 2] = this.lastCode; + this._prefix![this._runningCode - 2] = this._lastCode; - if (this.currentCode === this.runningCode - 2) { + if (this._currentCode === this._runningCode - 2) { // Only allowed if CrntCode is exactly the running code: // In that case CrntCode = XXXCode, CrntCode or the // prefix code is last code and the suffix char is // exactly the prefix of last code! - this.suffix[this.runningCode - 2] = GifDecoder.getPrefixChar( - this.prefix!, - this.lastCode, - this.clearCode + this._suffix[this._runningCode - 2] = GifDecoder.getPrefixChar( + this._prefix!, + this._lastCode, + this._clearCode ); } else { - this.suffix[this.runningCode - 2] = GifDecoder.getPrefixChar( - this.prefix!, - this.currentCode, - this.clearCode + this._suffix[this._runningCode - 2] = GifDecoder.getPrefixChar( + this._prefix!, + this._currentCode, + this._clearCode ); } } - this.lastCode = this.currentCode; + this._lastCode = this._currentCode; } } @@ -503,35 +428,35 @@ export class GifDecoder implements Decoder { */ private decompressInput(): number | undefined { // The image can't contain more than LZ_BITS per code. - if (this.runningBits > GifDecoder.LZ_BITS) { + if (this._runningBits > GifDecoder._lzBits) { return undefined; } - while (this.currentShiftState < this.runningBits) { + while (this._currentShiftState < this._runningBits) { // Needs to get more bytes from input stream for next code: const nextByte = this.bufferedInput()!; - this.currentShiftDWord |= nextByte << this.currentShiftState; - this.currentShiftState += 8; + this._currentShiftDWord |= nextByte << this._currentShiftState; + this._currentShiftState += 8; } const code: number = - this.currentShiftDWord & GifDecoder.CODE_MASKS[this.runningBits]; + this._currentShiftDWord & GifDecoder._codeMasks[this._runningBits]; - this.currentShiftDWord >>= this.runningBits; - this.currentShiftState -= this.runningBits; + this._currentShiftDWord >>= this._runningBits; + this._currentShiftState -= this._runningBits; // If code cannot fit into RunningBits bits, must raise its size. Note // however that codes above 4095 are used for special signaling. - // If we're using LZ_BITS bits already and we're at the max code, just + // If we're using lzBits bits already and we're at the max code, just // keep using the table as it is, don't increment Private->RunningCode. if ( - this.runningCode < GifDecoder.LZ_MAX_CODE + 2 && - ++this.runningCode > this.maxCode1 && - this.runningBits < GifDecoder.LZ_BITS + this._runningCode < GifDecoder._lzMaxCode + 2 && + ++this._runningCode > this._maxCode1 && + this._runningBits < GifDecoder._lzBits ) { - this.maxCode1 <<= 1; - this.runningBits++; + this._maxCode1 <<= 1; + this._runningBits++; } return code; @@ -545,44 +470,119 @@ export class GifDecoder implements Decoder { */ private bufferedInput(): number | undefined { let nextByte = 0; - if (this.buffer![0] === 0) { + if (this._buffer![0] === 0) { // Needs to read the next buffer - this one is empty: - this.buffer![0] = this.input!.readByte(); + this._buffer![0] = this._input!.readByte(); // There shouldn't be any empty data blocks here as the LZW spec // says the LZW termination code should come first. Therefore we // shouldn't be inside this routine at that point. - if (this.buffer![0] === 0) { + if (this._buffer![0] === 0) { return undefined; } - const from = this.input!.readBytes(this.buffer![0]).toUint8Array(); - ArrayUtils.setRange(this.buffer!, 1, 1 + this.buffer![0], from); + const from = this._input!.readBytes(this._buffer![0]).toUint8Array(); + + ArrayUtils.copyRange(from, 0, this._buffer![0], this._buffer!, 1); - nextByte = this.buffer![1]; + nextByte = this._buffer![1]; // We use now the second place as last char read! - this.buffer![1] = 2; - this.buffer![0]--; + this._buffer![1] = 2; + this._buffer![0]--; } else { - nextByte = this.buffer![this.buffer![1]++]; - this.buffer![0]--; + nextByte = this._buffer![this._buffer![1]++]; + this._buffer![0]--; } return nextByte; } private initDecode(): void { - this.buffer = new Uint8Array(256); - this.stack = new Uint8Array(GifDecoder.LZ_MAX_CODE); - this.suffix = new Uint8Array(GifDecoder.LZ_MAX_CODE + 1); - this.prefix = new Uint32Array(GifDecoder.LZ_MAX_CODE + 1); + this._buffer = new Uint8Array(256); + this._stack = new Uint8Array(GifDecoder._lzMaxCode); + this._suffix = new Uint8Array(GifDecoder._lzMaxCode + 1); + this._prefix = new Uint32Array(GifDecoder._lzMaxCode + 1); + } + + private decodeImage(gifImage: GifImageDesc): MemoryImage | undefined { + if (this._input === undefined || this._info === undefined) { + return undefined; + } + + if (this._buffer === undefined) { + this.initDecode(); + } + + this._bitsPerPixel = this._input.readByte(); + this._clearCode = 1 << this._bitsPerPixel; + this._eofCode = this._clearCode + 1; + this._runningCode = this._eofCode + 1; + this._runningBits = this._bitsPerPixel + 1; + this._maxCode1 = 1 << this._runningBits; + this._stackPtr = 0; + this._lastCode = GifDecoder._noSuchCode; + this._currentShiftState = 0; + this._currentShiftDWord = 0; + this._buffer![0] = 0; + this._prefix!.fill(GifDecoder._noSuchCode, 0, this._prefix!.length); + + const width = gifImage.width; + const height = gifImage.height; + + if ( + gifImage.x + width > this._info.width || + gifImage.y + height > this._info.height + ) { + return undefined; + } + + const colorMap = + gifImage.colorMap !== undefined + ? gifImage.colorMap! + : this._info.globalColorMap!; + + this._pixelCount = width * height; + + const image = new MemoryImage({ + width: width, + height: height, + numChannels: 1, + palette: colorMap.getPalette(), + }); + + const line = new Uint8Array(width); + + if (gifImage.interlaced) { + const row = gifImage.y; + for (let i = 0, j = 0; i < 4; ++i) { + for ( + let y = row + GifDecoder._interlacedOffset[i]; + y < row + height; + y += GifDecoder._interlacedJump[i], ++j + ) { + if (!this.getLine(line)) { + return image; + } + GifDecoder.updateImage(image, y, colorMap, line); + } + } + } else { + for (let y = 0; y < height; ++y) { + if (!this.getLine(line)) { + return image; + } + GifDecoder.updateImage(image, y, colorMap, line); + } + } + + return image; } /** * Is the given file a valid Gif image? */ public isValidFile(bytes: Uint8Array): boolean { - this.input = new InputBuffer({ + this._input = new InputBuffer({ buffer: bytes, }); return this.getInfo(); @@ -593,7 +593,7 @@ export class GifDecoder implements Decoder { * If the file is not a valid Gif image, undefined is returned. */ public startDecode(bytes: Uint8Array): GifInfo | undefined { - this.input = new InputBuffer({ + this._input = new InputBuffer({ buffer: bytes, }); @@ -602,102 +602,67 @@ export class GifDecoder implements Decoder { } try { - while (!this.input.isEOS) { - const recordType = this.input.readByte(); + while (!this._input.isEOS) { + const recordType = this._input.readByte(); switch (recordType) { - case GifDecoder.IMAGE_DESC_RECORD_TYPE: { + case GifDecoder._imageDescRecordType: { const gifImage = this.skipImage(); if (gifImage === undefined) { - return this.info; + return this._info; } - this.info!.frames.push(gifImage); + this._info!.frames.push(gifImage); break; } - case GifDecoder.EXTENSION_RECORD_TYPE: { - const extCode = this.input.readByte(); - if (extCode === GifDecoder.APPLICATION_EXT) { - this.readApplicationExt(this.input); - } else if (extCode === GifDecoder.GRAPHIC_CONTROL_EXT) { - this.readGraphicsControlExt(this.input); + case GifDecoder._extensionRecordType: { + const extCode = this._input.readByte(); + if (extCode === GifDecoder._applicationExt) { + this.readApplicationExt(this._input); + } else if (extCode === GifDecoder._graphicControlExt) { + this.readGraphicsControlExt(this._input); } else { this.skipRemainder(); } break; } - case GifDecoder.TERMINATE_RECORD_TYPE: { - // this._numFrames = info.numFrames; - return this.info; + case GifDecoder._terminateRecordType: { + return this._info; } default: break; } } } catch (error) { - const strError = JSON.stringify(error); - throw new ImageError(strError); + // ignore } - // this._numFrames = info.numFrames; - return this.info; + return this._info; } - public decodeFrame(frame: number): MemoryImage | undefined { - if (this.input === undefined || this.info === undefined) { + public decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined { + if (this.startDecode(bytes) === undefined || this._info === undefined) { return undefined; } - if (frame >= this.info.frames.length || frame < 0) { - return undefined; + if (this._info.numFrames === 1) { + return this.decodeFrame(frame ?? 0); } - // this._frame = frame; - const gifImage = this.info.frames[frame]; - this.input.offset = gifImage.inputPosition; - - return this.decodeFrameImage(this.info.frames[frame]); - } - - public decodeHdrFrame(frame: number): HdrImage | undefined { - const img = this.decodeFrame(frame); - if (img === undefined) { - return undefined; - } - return HdrImage.fromImage(img); - } - - /** - * Decode all of the frames of an animated gif. For single image gifs, - * this will return an animation with a single frame. - */ - public decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined { - if (this.startDecode(bytes) === undefined) { - return undefined; - } - - if (this.input === undefined || this.info === undefined) { - return undefined; - } - - const animation = new FrameAnimation({ - width: this.info.width, - height: this.info.height, - loopCount: this.repeat, - }); - + let firstImage: MemoryImage | undefined = undefined; let lastImage: MemoryImage | undefined = undefined; - - for (let i = 0; i < this.info.numFrames; ++i) { - const frame = this.info.frames[i]; + for (let i = 0; i < this._info.numFrames; ++i) { + const frame = this._info.frames[i]; const image = this.decodeFrame(i); if (image === undefined) { return undefined; } - if (lastImage === undefined) { + // Convert to MS + image.frameDuration = frame.duration * 10; + + if (firstImage === undefined || lastImage === undefined) { + firstImage = image; lastImage = image; - // Convert to MS - lastImage.duration = frame.duration * 10; - animation.addFrame(lastImage); + image.loopCount = this._repeat; continue; } @@ -709,56 +674,54 @@ export class GifDecoder implements Decoder { frame.clearFrame ) { lastImage = image; - // Convert to MS - lastImage.duration = frame.duration * 10; - animation.addFrame(lastImage); + firstImage.addFrame(lastImage); continue; } if (frame.clearFrame) { + const colorMap = + frame.colorMap !== undefined + ? frame.colorMap + : this._info.globalColorMap!; + lastImage = new MemoryImage({ width: lastImage.width, height: lastImage.height, + numChannels: 1, + palette: colorMap.getPalette(), }); - const colorMap = - frame.colorMap !== undefined - ? frame.colorMap - : this.info!.globalColorMap; - lastImage.fill(colorMap!.getColor(this.info!.backgroundColor)); + lastImage.clear(colorMap.getColor(this._info.backgroundColor!.r)); } else { lastImage = MemoryImage.from(lastImage); } - ImageTransform.copyInto({ - dst: lastImage, - src: image, - dstX: frame.x, - dstY: frame.y, - }); + lastImage.frameDuration = image.frameDuration; - // Convert 1/100 sec to ms. - lastImage.duration = frame.duration * 10; + for (const p of image) { + if (p.a !== 0) { + lastImage.setPixel(p.x + frame.x, p.y + frame.y, p); + } + } - animation.addFrame(lastImage); + firstImage.addFrame(lastImage); } - return animation; + return firstImage; } - public decodeImage(bytes: Uint8Array, frame = 0): MemoryImage | undefined { - if (this.startDecode(bytes) === undefined) { + public decodeFrame(frame: number): MemoryImage | undefined { + if (this._input === undefined || this._info === undefined) { return undefined; } - // this._frame = 0; - // this._numFrames = 1; - return this.decodeFrame(frame); - } - public decodeHdrImage(bytes: Uint8Array, frame = 0): HdrImage | undefined { - const img = this.decodeImage(bytes, frame); - if (img === undefined) { + if (frame >= this._info.frames.length || frame < 0) { return undefined; } - return HdrImage.fromImage(img); + + // this._frame = frame; + const gifImage = this._info.frames[frame]; + this._input.offset = gifImage.inputPosition; + + return this.decodeImage(this._info.frames[frame]); } } diff --git a/src/formats/gif-encoder.ts b/src/formats/gif-encoder.ts index 34c2d9c..07f730f 100644 --- a/src/formats/gif-encoder.ts +++ b/src/formats/gif-encoder.ts @@ -1,13 +1,16 @@ /** @format */ -import { DitherKernel } from '../common/dither-kernel'; -import { DitherPixel } from '../common/dither-pixel'; -import { FrameAnimation } from '../common/frame-animation'; -import { MemoryImage } from '../common/memory-image'; -import { NeuralQuantizer } from '../common/neural-quantizer'; +import { NeuralQuantizer } from '../image/neural-quantizer'; import { OutputBuffer } from '../common/output-buffer'; -import { TextCodec } from '../common/text-codec'; +import { StringUtils } from '../common/string-utils'; import { Encoder } from './encoder'; +import { QuantizerType } from '../image/quantizer-type'; +import { MemoryImage } from '../image/image'; +import { OctreeQuantizer } from '../image/octree-quantizer'; +import { Quantizer } from '../image/quantizer'; +import { Filter } from '../filter/filter'; +import { LibError } from '../error/lib-error'; +import { DitherKernel } from '../filter/dither-kernel'; export interface GifEncoderInitOptions { delay?: number; @@ -18,188 +21,211 @@ export interface GifEncoderInitOptions { } export class GifEncoder implements Encoder { - private static readonly gif89Id = 'GIF89a'; + private static readonly _gif89Id = 'GIF89a'; - private static readonly imageDescRecordType = 0x2c; + private static readonly _imageDescRecordType = 0x2c; + private static readonly _extensionRecordType = 0x21; + private static readonly _terminateRecordType = 0x3b; - private static readonly extensionRecordType = 0x21; - - private static readonly terminateRecordType = 0x3b; - - private static readonly applicationExt = 0xff; - - private static readonly graphicControlExt = 0xf9; - - private static readonly eof = -1; - - private static readonly bits = 12; + private static readonly _applicationExt = 0xff; + private static readonly _graphicControlExt = 0xf9; + private static readonly _eof = -1; + private static readonly _bits = 12; // 80% occupancy - private static readonly hsize = 5003; - - private static readonly masks = [ + private static readonly _hSize = 5003; + private static readonly _masks = [ 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff, ]; - private lastImage?: Uint8Array; + private _delay: number; - private lastImageDuration?: number; + private _repeat: number; - private lastColorMap?: NeuralQuantizer; + private _numColors: number; - private width!: number; + private _quantizerType: QuantizerType; - private height!: number; + private _samplingFactor: number; - private encodedFrames: number; + private _lastImage?: MemoryImage; - private curAccum = 0; + private _lastImageDuration?: number; - private curBits = 0; + private _lastColorMap?: Quantizer; - private nBits = 0; + private _width!: number; - private initBits = 0; + private _height!: number; - private EOFCode = 0; + private _encodedFrames: number; - private maxCode = 0; + private _curAccum = 0; - private clearCode = 0; + private _curBits = 0; - private freeEnt = 0; + private _nBits = 0; - private clearFlag = false; + private _initBits = 0; - private block!: Uint8Array; + private _eofCode = 0; - private blockSize = 0; + private _maxCode = 0; - private outputBuffer?: OutputBuffer; + private _clearCode = 0; - private delay: number; + private _freeEnt = 0; - private repeat: number; + private _clearFlag = false; - private samplingFactor: number; + private _block!: Uint8Array; - private dither: DitherKernel; + private _blockSize = 0; - private ditherSerpentine: boolean; + private _outputBuffer?: OutputBuffer; + + private _dither: DitherKernel; + + private _ditherSerpentine: boolean; /** * Does this encoder support animation? */ private readonly _supportsAnimation = true; - get supportsAnimation(): boolean { + public get supportsAnimation(): boolean { return this._supportsAnimation; } - constructor(options?: GifEncoderInitOptions) { - this.delay = options?.delay ?? 80; - this.repeat = options?.repeat ?? 0; - this.samplingFactor = options?.samplingFactor ?? 10; - this.dither = options?.dither ?? DitherKernel.FloydSteinberg; - this.ditherSerpentine = options?.ditherSerpentine ?? false; - this.encodedFrames = 0; + constructor(opt?: GifEncoderInitOptions) { + this._delay = opt?.delay ?? 80; + this._repeat = opt?.repeat ?? 0; + this._numColors = 256; + this._quantizerType = QuantizerType.neural; + this._samplingFactor = opt?.samplingFactor ?? 10; + this._dither = opt?.dither ?? DitherKernel.floydSteinberg; + this._ditherSerpentine = opt?.ditherSerpentine ?? false; + this._encodedFrames = 0; } - private addImage( - image: Uint8Array | undefined, - width: number, - height: number, - colorMap: Uint8Array, - numColors: number - ): void { + private addImage(image: MemoryImage, width: number, height: number): void { + if (!image.hasPalette) { + throw new LibError('GIF can only encode palette images.'); + } + + const palette = image.palette!; + const numColors = palette.numColors; + + const out = this._outputBuffer!; + // Image desc - this.outputBuffer!.writeByte(GifEncoder.imageDescRecordType); - // Image position x,y = 0,0 - this.outputBuffer!.writeUint16(0); - this.outputBuffer!.writeUint16(0); - // Image size - this.outputBuffer!.writeUint16(width); - this.outputBuffer!.writeUint16(height); + out.writeByte(GifEncoder._imageDescRecordType); + // image position x,y = 0,0 + out.writeUint16(0); + out.writeUint16(0); + // image size + out.writeUint16(width); + out.writeUint16(height); + + const paletteBytes = palette.toUint8Array(); // Local Color Map // (0x80: Use LCM, 0x07: Palette Size (7 = 8-bit)) - this.outputBuffer!.writeByte(0x87); - this.outputBuffer!.writeBytes(colorMap); + out.writeByte(0x87); + + const numChannels = palette.numChannels; + if (numChannels === 3) { + out.writeBytes(paletteBytes); + } else if (numChannels === 4) { + for (let i = 0, pi = 0; i < numColors; ++i, pi += 4) { + out.writeByte(paletteBytes[pi]); + out.writeByte(paletteBytes[pi + 1]); + out.writeByte(paletteBytes[pi + 2]); + } + } else if (numChannels === 1 || numChannels === 2) { + for (let i = 0, pi = 0; i < numColors; ++i, pi += numChannels) { + const g = paletteBytes[pi]; + out.writeByte(g); + out.writeByte(g); + out.writeByte(g); + } + } + for (let i = numColors; i < 256; ++i) { - this.outputBuffer!.writeByte(0); - this.outputBuffer!.writeByte(0); - this.outputBuffer!.writeByte(0); + out.writeByte(0); + out.writeByte(0); + out.writeByte(0); } - this.encodeLZW(image, width, height); + this.encodeLZW(image); } - private encodeLZW( - image: Uint8Array | undefined, - width: number, - height: number - ): void { - this.curAccum = 0; - this.curBits = 0; - this.blockSize = 0; - this.block = new Uint8Array(256); + private encodeLZW(image: MemoryImage): void { + this._curAccum = 0; + this._curBits = 0; + this._blockSize = 0; + this._block = new Uint8Array(256); const initCodeSize = 8; - this.outputBuffer!.writeByte(initCodeSize); - - const hTab = new Int32Array(GifEncoder.hsize); - const codeTab = new Int32Array(GifEncoder.hsize); - let remaining = width * height; - let curPixel = 0; - - this.initBits = initCodeSize + 1; - this.nBits = this.initBits; - this.maxCode = (1 << this.nBits) - 1; - this.clearCode = 1 << (this.initBits - 1); - this.EOFCode = this.clearCode + 1; - this.clearFlag = false; - this.freeEnt = this.clearCode + 2; - - const _nextPixel = () => { - if (remaining === 0) { - return GifEncoder.eof; + this._outputBuffer!.writeByte(initCodeSize); + + const hTab = new Int32Array(GifEncoder._hSize); + const codeTab = new Int32Array(GifEncoder._hSize); + const pIter = image[Symbol.iterator](); + let pIterRes = pIter.next(); + + this._initBits = initCodeSize + 1; + this._nBits = this._initBits; + this._maxCode = (1 << this._nBits) - 1; + this._clearCode = 1 << (this._initBits - 1); + this._eofCode = this._clearCode + 1; + this._clearFlag = false; + this._freeEnt = this._clearCode + 2; + let pFinished = false; + + const nextPixel = (): number => { + if (pFinished) { + return GifEncoder._eof; + } + const r = Math.trunc(pIterRes.value.index); + if (((pIterRes = pIter.next()), pIterRes.done)) { + pFinished = true; } - --remaining; - return image![curPixel++] & 0xff; + return r; }; - let ent = _nextPixel(); + let ent = nextPixel(); - let hshift = 0; - for (let fcode = GifEncoder.hsize; fcode < 65536; fcode *= 2) { - hshift++; + let hShift = 0; + for (let fCode = GifEncoder._hSize; fCode < 65536; fCode *= 2) { + hShift++; } - hshift = 8 - hshift; + hShift = 8 - hShift; - const hSizeReg = GifEncoder.hsize; + const hSizeReg = GifEncoder._hSize; for (let i = 0; i < hSizeReg; ++i) { hTab[i] = -1; } - this.output(this.clearCode); + this.output(this._clearCode); let outerLoop = true; while (outerLoop) { outerLoop = false; - let c = _nextPixel(); - while (c !== GifEncoder.eof) { - const fcode = (c << GifEncoder.bits) + ent; - // XOR hashing - let i = (c << hshift) ^ ent; + let c = nextPixel(); + while (c !== GifEncoder._eof) { + const fcode = (c << GifEncoder._bits) + ent; + // xor hashing + let i = (c << hShift) ^ ent; if (hTab[i] === fcode) { ent = codeTab[i]; - c = _nextPixel(); + c = nextPixel(); continue; } else if (hTab[i] >= 0) { - // Non-empty slot - // Secondary hash (after G. Knott) + // non-empty slot + // secondary hash (after G. Knott) let disp = hSizeReg - i; if (i === 0) { disp = 1; @@ -223,137 +249,164 @@ export class GifEncoder implements Encoder { this.output(ent); ent = c; - if (this.freeEnt < 1 << GifEncoder.bits) { - // Code -> hashtable - codeTab[i] = this.freeEnt++; + if (this._freeEnt < 1 << GifEncoder._bits) { + // code -> hashtable + codeTab[i] = this._freeEnt++; hTab[i] = fcode; } else { - for (let i = 0; i < GifEncoder.hsize; ++i) { + for (let i = 0; i < GifEncoder._hSize; ++i) { hTab[i] = -1; } - this.freeEnt = this.clearCode + 2; - this.clearFlag = true; - this.output(this.clearCode); + this._freeEnt = this._clearCode + 2; + this._clearFlag = true; + this.output(this._clearCode); } - c = _nextPixel(); + c = nextPixel(); } } this.output(ent); - this.output(this.EOFCode); + this.output(this._eofCode); - this.outputBuffer!.writeByte(0); + this._outputBuffer!.writeByte(0); } private output(code: number | undefined): void { - this.curAccum &= GifEncoder.masks[this.curBits]; + this._curAccum &= GifEncoder._masks[this._curBits]; - if (this.curBits > 0) { - this.curAccum |= code! << this.curBits; + if (this._curBits > 0) { + this._curAccum |= code! << this._curBits; } else { - this.curAccum = code!; + this._curAccum = code!; } - this.curBits += this.nBits; + this._curBits += this._nBits; - while (this.curBits >= 8) { - this.addToBlock(this.curAccum & 0xff); - this.curAccum >>= 8; - this.curBits -= 8; + while (this._curBits >= 8) { + this.addToBlock(this._curAccum & 0xff); + this._curAccum >>= 8; + this._curBits -= 8; } // If the next entry is going to be too big for the code size, // then increase it, if possible. - if (this.freeEnt > this.maxCode || this.clearFlag) { - if (this.clearFlag) { - this.nBits = this.initBits; - this.maxCode = (1 << this.nBits) - 1; - this.clearFlag = false; + if (this._freeEnt > this._maxCode || this._clearFlag) { + if (this._clearFlag) { + this._nBits = this._initBits; + this._maxCode = (1 << this._nBits) - 1; + this._clearFlag = false; } else { - ++this.nBits; - if (this.nBits === GifEncoder.bits) { - this.maxCode = 1 << GifEncoder.bits; + ++this._nBits; + if (this._nBits === GifEncoder._bits) { + this._maxCode = 1 << GifEncoder._bits; } else { - this.maxCode = (1 << this.nBits) - 1; + this._maxCode = (1 << this._nBits) - 1; } } } - if (code === this.EOFCode) { + if (code === this._eofCode) { // At EOF, write the rest of the buffer. - while (this.curBits > 0) { - this.addToBlock(this.curAccum & 0xff); - this.curAccum >>= 8; - this.curBits -= 8; + while (this._curBits > 0) { + this.addToBlock(this._curAccum & 0xff); + this._curAccum >>= 8; + this._curBits -= 8; } this.writeBlock(); } } private writeBlock(): void { - if (this.blockSize > 0) { - this.outputBuffer!.writeByte(this.blockSize); - this.outputBuffer!.writeBytes(this.block, this.blockSize); - this.blockSize = 0; + if (this._blockSize > 0) { + this._outputBuffer!.writeByte(this._blockSize); + this._outputBuffer!.writeBytes(this._block, this._blockSize); + this._blockSize = 0; } } private addToBlock(c: number): void { - this.block[this.blockSize++] = c; - if (this.blockSize >= 254) { + this._block[this._blockSize++] = c; + if (this._blockSize >= 254) { this.writeBlock(); } } private writeApplicationExt(): void { - this.outputBuffer!.writeByte(GifEncoder.extensionRecordType); - this.outputBuffer!.writeByte(GifEncoder.applicationExt); + this._outputBuffer!.writeByte(GifEncoder._extensionRecordType); + this._outputBuffer!.writeByte(GifEncoder._applicationExt); // Data block size - this.outputBuffer!.writeByte(11); - const appCodeUnits = TextCodec.getCodePoints('NETSCAPE2.0'); + this._outputBuffer!.writeByte(11); + const appCodeUnits = StringUtils.getCodePoints('NETSCAPE2.0'); // App identifier - this.outputBuffer!.writeBytes(appCodeUnits); - this.outputBuffer!.writeBytes(new Uint8Array([0x03, 0x01])); + this._outputBuffer!.writeBytes(appCodeUnits); + this._outputBuffer!.writeBytes(new Uint8Array([0x03, 0x01])); // Loop count - this.outputBuffer!.writeUint16(this.repeat); + this._outputBuffer!.writeUint16(this._repeat); // Block terminator - this.outputBuffer!.writeByte(0); + this._outputBuffer!.writeByte(0); } - private writeGraphicsCtrlExt(): void { - this.outputBuffer!.writeByte(GifEncoder.extensionRecordType); - this.outputBuffer!.writeByte(GifEncoder.graphicControlExt); - // Data block size - this.outputBuffer!.writeByte(4); + private writeGraphicsCtrlExt(image: MemoryImage): void { + this._outputBuffer!.writeByte(GifEncoder._extensionRecordType); + this._outputBuffer!.writeByte(GifEncoder._graphicControlExt); + // data block size + this._outputBuffer!.writeByte(4); + + let transparentIndex = 0; + let hasTransparency = 0; + const palette = image.palette!; + const nc = palette.numChannels; + const pa = nc - 1; + if (nc === 4 || nc === 2) { + const p = palette.toUint8Array(); + const l = palette.numColors; + for (let i = 0, pi = pa; i < l; ++i, pi += nc) { + const a = p[pi]; + if (a === 0) { + hasTransparency = 1; + transparentIndex = i; + break; + } + } + } - const transparency = 0; - // Dispose = no action - const dispose = 0; + // dispose: 0 = no action, 2 = clear + const dispose = 2; - // packed fields - this.outputBuffer!.writeByte(0 | dispose | 0 | transparency); + // 1:3 reserved + const fields = + 0 | + // 4:6 disposal + (dispose << 2) | + // 7 user input - 0 = none + 0 | + // 8 transparency flag + hasTransparency; - // Delay x 1/100 sec - this.outputBuffer!.writeUint16(this.lastImageDuration ?? this.delay); - // Transparent color index - this.outputBuffer!.writeByte(0); - // Block terminator - this.outputBuffer!.writeByte(0); + // packed fields + this._outputBuffer!.writeByte(fields); + + // delay x 1/100 sec + this._outputBuffer!.writeUint16(this._lastImageDuration ?? this._delay); + // transparent color index + this._outputBuffer!.writeByte(transparentIndex); + // block terminator + this._outputBuffer!.writeByte(0); } // GIF header and Logical Screen Descriptor private writeHeader(width: number, height: number): void { - const idCodeUnits = TextCodec.getCodePoints(GifEncoder.gif89Id); - this.outputBuffer!.writeBytes(idCodeUnits); - this.outputBuffer!.writeUint16(width); - this.outputBuffer!.writeUint16(height); + const idCodeUnits = StringUtils.getCodePoints(GifEncoder._gif89Id); + this._outputBuffer!.writeBytes(idCodeUnits); + this._outputBuffer!.writeUint16(width); + this._outputBuffer!.writeUint16(height); // global color map parameters (not being used). - this.outputBuffer!.writeByte(0); + this._outputBuffer!.writeByte(0); // Background color index. - this.outputBuffer!.writeByte(0); + this._outputBuffer!.writeByte(0); // Aspect - this.outputBuffer!.writeByte(0); + this._outputBuffer!.writeByte(0); } /** @@ -367,33 +420,27 @@ export class GifEncoder implements Encoder { */ private finish(): Uint8Array | undefined { let bytes: Uint8Array | undefined = undefined; - if (this.outputBuffer === undefined) { + if (this._outputBuffer === undefined) { return bytes; } - if (this.encodedFrames === 0) { - this.writeHeader(this.width, this.height); + if (this._encodedFrames === 0) { + this.writeHeader(this._width, this._height); this.writeApplicationExt(); } else { - this.writeGraphicsCtrlExt(); + this.writeGraphicsCtrlExt(this._lastImage!); } - this.addImage( - this.lastImage, - this.width, - this.height, - this.lastColorMap!.colorMap8, - 256 - ); + this.addImage(this._lastImage!, this._width, this._height); - this.outputBuffer.writeByte(GifEncoder.terminateRecordType); + this._outputBuffer.writeByte(GifEncoder._terminateRecordType); - this.lastImage = undefined; - this.lastColorMap = undefined; - this.encodedFrames = 0; + this._lastImage = undefined; + this._lastColorMap = undefined; + this._encodedFrames = 0; - bytes = this.outputBuffer.getBytes(); - this.outputBuffer = undefined; + bytes = this._outputBuffer.getBytes(); + this._outputBuffer = undefined; return bytes; } @@ -403,69 +450,85 @@ export class GifEncoder implements Encoder { * Optional frame **duration** is in 1/100 sec. * */ public addFrame(image: MemoryImage, duration?: number): void { - if (this.outputBuffer === undefined) { - this.outputBuffer = new OutputBuffer(); - - this.lastColorMap = new NeuralQuantizer(image, 256, this.samplingFactor); - this.lastImage = DitherPixel.getDitherPixels( - image, - this.lastColorMap, - this.dither, - this.ditherSerpentine - ); - this.lastImageDuration = duration; - - this.width = image.width; - this.height = image.height; + if (this._outputBuffer === undefined) { + this._outputBuffer = new OutputBuffer(); + + if (!image.hasPalette) { + if (this._quantizerType === QuantizerType.neural) { + this._lastColorMap = new NeuralQuantizer( + image, + this._numColors, + this._samplingFactor + ); + } else { + this._lastColorMap = new OctreeQuantizer(image, this._numColors); + } + + this._lastImage = Filter.ditherImage({ + image: image, + quantizer: this._lastColorMap, + kernel: this._dither, + serpentine: this._ditherSerpentine, + }); + } else { + this._lastImage = image; + } + + this._lastImageDuration = duration; + + this._width = image.width; + this._height = image.height; return; } - if (this.encodedFrames === 0) { - this.writeHeader(this.width, this.height); + if (this._encodedFrames === 0) { + this.writeHeader(this._width, this._height); this.writeApplicationExt(); } - this.writeGraphicsCtrlExt(); - - this.addImage( - this.lastImage, - this.width, - this.height, - this.lastColorMap!.colorMap8, - 256 - ); - this.encodedFrames++; - - this.lastColorMap = new NeuralQuantizer(image, 256, this.samplingFactor); - this.lastImage = DitherPixel.getDitherPixels( - image, - this.lastColorMap, - this.dither, - this.ditherSerpentine - ); - this.lastImageDuration = duration; + this.writeGraphicsCtrlExt(this._lastImage!); + + this.addImage(this._lastImage!, this._width, this._height); + this._encodedFrames++; + + if (!image.hasPalette) { + if (this._quantizerType === QuantizerType.neural) { + this._lastColorMap = new NeuralQuantizer( + image, + this._numColors, + this._samplingFactor + ); + } else { + this._lastColorMap = new OctreeQuantizer(image, this._numColors); + } + + this._lastImage = Filter.ditherImage({ + image: image, + quantizer: this._lastColorMap!, + kernel: this._dither, + serpentine: this._ditherSerpentine, + }); + } else { + this._lastImage = image; + } + + this._lastImageDuration = duration; } /** * Encode a single frame image. */ - public encodeImage(image: MemoryImage): Uint8Array { - this.addFrame(image); - return this.finish()!; - } + public encode(image: MemoryImage, singleFrame = false): Uint8Array { + if (!image.hasAnimation || singleFrame) { + this.addFrame(image); + return this.finish()!; + } - /** - * Encode an animation. - */ - public encodeAnimation(animation: FrameAnimation): Uint8Array | undefined { - this.repeat = animation.loopCount; - for (const f of animation) { - this.addFrame( - f, - // Convert ms to 1 / 100 sec. - Math.floor(f.duration / 10) - ); + this._repeat = image.loopCount; + for (const f of image.frames) { + // Convert ms to 1/100 sec. + this.addFrame(f, Math.trunc(f.frameDuration / 10)); } - return this.finish(); + return this.finish()!; } } diff --git a/src/formats/gif/gif-color-map.ts b/src/formats/gif/gif-color-map.ts index 3af6f66..5fcb5a4 100644 --- a/src/formats/gif/gif-color-map.ts +++ b/src/formats/gif/gif-color-map.ts @@ -1,26 +1,20 @@ /** @format */ -import { Color } from '../../common/color'; - -export interface GifColorMapInitOptions { - numColors: number; - bitsPerPixel?: number; - colors?: Uint8Array; - transparent?: number; -} +import { ColorUint8 } from '../../color/color-uint8'; +import { PaletteUint8 } from '../../image/palette-uint8'; export class GifColorMap { - private readonly _colors: Uint8Array; - public get colors(): Uint8Array { - return this._colors; - } - private readonly _numColors: number; public get numColors(): number { return this._numColors; } - private readonly _bitsPerPixel: number; + private readonly _palette: PaletteUint8; + public get palette(): PaletteUint8 { + return this._palette; + } + + private _bitsPerPixel: number; public get bitsPerPixel(): number { return this._bitsPerPixel; } @@ -33,12 +27,10 @@ export class GifColorMap { return this._transparent; } - constructor(options: GifColorMapInitOptions) { - this._numColors = options.numColors; - this._bitsPerPixel = - options.bitsPerPixel ?? GifColorMap.bitSize(options.numColors); - this._colors = options.colors ?? new Uint8Array(options.numColors * 3); - this._transparent = options.transparent; + constructor(numColors: number, palette?: PaletteUint8) { + this._numColors = numColors; + this._palette = palette ?? new PaletteUint8(numColors, 3); + this._bitsPerPixel = GifColorMap.bitSize(numColors); } private static bitSize(n: number): number { @@ -51,53 +43,56 @@ export class GifColorMap { } public static from(other: GifColorMap) { - return new GifColorMap({ - numColors: other.numColors, - bitsPerPixel: other.bitsPerPixel, - colors: other.colors, - transparent: other.transparent, - }); - } - - public getByte(index: number): number { - return this._colors[index]; - } - - public setByte(index: number, value: number): number { - return (this._colors[index] = value); + const palette = PaletteUint8.from(other._palette); + const r = new GifColorMap(other.numColors, palette); + r._bitsPerPixel = other._bitsPerPixel; + r._transparent = other._transparent; + return r; } - public getColor(index: number): number { - const ci = index * 3; - const a = index === this._transparent ? 0 : 255; - return Color.getColor( - this._colors[ci], - this._colors[ci + 1], - this._colors[ci + 2], - a - ); + public getColor(index: number): ColorUint8 { + const r = this.getRed(index); + const g = this.getGreen(index); + const b = this.getBlue(index); + const a = this.getAlpha(index); + return ColorUint8.rgba(r, g, b, a); } public setColor(index: number, r: number, g: number, b: number): void { - const ci = index * 3; - this._colors[ci] = r; - this._colors[ci + 1] = g; - this._colors[ci + 2] = b; + this._palette.setRgb(index, r, g, b); } public getRed(color: number): number { - return this._colors[color * 3]; + return Math.trunc(this._palette.getRed(color)); } public getGreen(color: number): number { - return this._colors[color * 3 + 1]; + return Math.trunc(this._palette.getGreen(color)); } public getBlue(color: number): number { - return this._colors[color * 3 + 2]; + return Math.trunc(this._palette.getBlue(color)); } public getAlpha(color: number): number { return color === this._transparent ? 0 : 255; } + + public getPalette(): PaletteUint8 { + if (this._transparent === undefined) { + return this._palette; + } + const p = new PaletteUint8(this._palette.numColors, 4); + const l = this._palette.numColors; + for (let i = 0; i < l; ++i) { + p.setRgba( + i, + this.getRed(i), + this.getGreen(i), + this.getBlue(i), + this.getAlpha(i) + ); + } + return p; + } } diff --git a/src/formats/gif/gif-image-desc.ts b/src/formats/gif/gif-image-desc.ts index 3c207dc..3316413 100644 --- a/src/formats/gif/gif-image-desc.ts +++ b/src/formats/gif/gif-image-desc.ts @@ -73,9 +73,7 @@ export class GifImageDesc { this._interlaced = (b & 0x40) !== 0; if ((b & 0x80) !== 0) { - this._colorMap = new GifColorMap({ - numColors: 1 << bitsPerPixel, - }); + this._colorMap = new GifColorMap(1 << bitsPerPixel); for (let i = 0; i < this._colorMap.numColors; ++i) { this._colorMap.setColor( i, diff --git a/src/formats/gif/gif-info.ts b/src/formats/gif/gif-info.ts index e5389df..90dd3f1 100644 --- a/src/formats/gif/gif-info.ts +++ b/src/formats/gif/gif-info.ts @@ -1,5 +1,6 @@ /** @format */ +import { Color } from '../../color/color'; import { DecodeInfo } from '../decode-info'; import { GifColorMap } from './gif-color-map'; import { GifImageDesc } from './gif-image-desc'; @@ -7,7 +8,7 @@ import { GifImageDesc } from './gif-image-desc'; export interface GifInfoInitOptions { width?: number; height?: number; - backgroundColor?: number; + backgroundColor?: Color; frames?: Array; colorResolution?: number; globalColorMap?: GifColorMap; @@ -15,18 +16,18 @@ export interface GifInfoInitOptions { } export class GifInfo implements DecodeInfo { - private _width; + private _width = 0; public get width(): number { return this._width; } - private _height; + private _height = 0; public get height(): number { return this._height; } - private _backgroundColor; - public get backgroundColor(): number { + private _backgroundColor: Color | undefined = undefined; + public get backgroundColor(): Color | undefined { return this._backgroundColor; } @@ -54,13 +55,13 @@ export class GifInfo implements DecodeInfo { return this.frames.length; } - constructor(options?: GifInfoInitOptions) { - this._width = options?.width ?? 0; - this._height = options?.height ?? 0; - this._backgroundColor = options?.backgroundColor ?? 0xffffffff; - this._frames = options?.frames ?? new Array(); - this._colorResolution = options?.colorResolution ?? 0; - this._globalColorMap = options?.globalColorMap; - this._isGif89 = options?.isGif89 ?? false; + constructor(opt?: GifInfoInitOptions) { + this._width = opt?.width ?? 0; + this._height = opt?.height ?? 0; + this._backgroundColor = opt?.backgroundColor; + this._frames = opt?.frames ?? new Array(); + this._colorResolution = opt?.colorResolution ?? 0; + this._globalColorMap = opt?.globalColorMap; + this._isGif89 = opt?.isGif89 ?? false; } } diff --git a/src/formats/ico-decoder.ts b/src/formats/ico-decoder.ts index 4d65706..732c1f0 100644 --- a/src/formats/ico-decoder.ts +++ b/src/formats/ico-decoder.ts @@ -1,154 +1,156 @@ /** @format */ -import { FrameAnimation } from '../common/frame-animation'; import { InputBuffer } from '../common/input-buffer'; -import { ArrayUtils } from '../common/array-utils'; -import { MemoryImage } from '../common/memory-image'; import { OutputBuffer } from '../common/output-buffer'; -import { NotImplementedError } from '../error/not-implemented-error'; -import { HdrImage } from '../hdr/hdr-image'; -import { BitmapFileHeader } from './bmp/bitmap-file-header'; +import { BmpFileHeader } from './bmp/bmp-file-header'; import { Decoder } from './decoder'; import { DibDecoder } from './dib-decoder'; import { IcoBmpInfo } from './ico/ico-bmp-info'; import { IcoInfo } from './ico/ico-info'; import { PngDecoder } from './png-decoder'; +import { MemoryImage } from '../image/image'; +import { FrameType } from '../image/frame-type'; export class IcoDecoder implements Decoder { - _input?: InputBuffer; - _icoInfo?: IcoInfo; + private _input?: InputBuffer; + private _info?: IcoInfo; - get numFrames(): number { - return this._icoInfo !== undefined ? this._icoInfo.numFrames : 0; + public get numFrames(): number { + return this._info !== undefined ? this._info.numFrames : 0; } public isValidFile(bytes: Uint8Array): boolean { this._input = new InputBuffer({ buffer: bytes, }); - this._icoInfo = IcoInfo.read(this._input); - return this._icoInfo !== undefined; + this._info = IcoInfo.read(this._input); + return this._info !== undefined; } public startDecode(bytes: Uint8Array): IcoInfo | undefined { this._input = new InputBuffer({ buffer: bytes, }); - this._icoInfo = IcoInfo.read(this._input); - return this._icoInfo; + this._info = IcoInfo.read(this._input); + return this._info; + } + + public decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined { + const info = this.startDecode(bytes); + if (info === undefined) { + return undefined; + } + + if (info.images.length === 1 || frame !== undefined) { + return this.decodeFrame(frame ?? 0); + } + + let firstImage: MemoryImage | undefined = undefined; + for (let i = 0; i < info.images.length; i++) { + const frame = this.decodeFrame(i); + if (frame === undefined) { + continue; + } + if (firstImage === undefined) { + frame.frameType = FrameType.sequence; + firstImage = frame; + } else { + firstImage.addFrame(frame); + } + } + + return firstImage; } public decodeFrame(frame: number): MemoryImage | undefined { if ( this._input === undefined || - this._icoInfo === undefined || - frame >= this._icoInfo.numFrames + this._info === undefined || + frame >= this._info.numFrames ) { return undefined; } - const imageInfo = this._icoInfo.images![frame]; - const imageBuffer = ArrayUtils.copyUint8( - this._input.buffer, + + const imageInfo = this._info.images[frame]; + const imageBuffer = this._input.buffer.subarray( this._input.start + imageInfo.bytesOffset, this._input.start + imageInfo.bytesOffset + imageInfo.bytesSize ); const png = new PngDecoder(); if (png.isValidFile(imageBuffer)) { - return png.decodeImage(imageBuffer); + return png.decode(imageBuffer); } - // Should be bmp. + + // should be bmp. const dummyBmpHeader = new OutputBuffer({ size: 14, }); - dummyBmpHeader.writeUint16(BitmapFileHeader.BMP_HEADER_FILETYPE); + dummyBmpHeader.writeUint16(BmpFileHeader.signature); dummyBmpHeader.writeUint32(imageInfo.bytesSize); dummyBmpHeader.writeUint32(0); dummyBmpHeader.writeUint32(0); + const bmpInfo = new IcoBmpInfo( new InputBuffer({ buffer: imageBuffer, }), - new BitmapFileHeader( + new BmpFileHeader( new InputBuffer({ buffer: dummyBmpHeader.getBytes(), }) ) ); + if (bmpInfo.headerSize !== 40 && bmpInfo.planes !== 1) { - // Invalid header. + // invalid header. return undefined; } + let offset = 0; - if (bmpInfo.totalColors === 0 && bmpInfo.bpp <= 8) { - // 14 + ... - offset = 40 + 4 * (1 << bmpInfo.bpp); + if (bmpInfo.totalColors === 0 && bmpInfo.bitsPerPixel <= 8) { + offset = 40 + 4 * (1 << bmpInfo.bitsPerPixel); } else { - // 14 + ... offset = 40 + 4 * bmpInfo.totalColors; } - bmpInfo.fileHeader.offset = offset; + + bmpInfo.header.imageOffset = offset; dummyBmpHeader.length -= 4; dummyBmpHeader.writeUint32(offset); const inp = new InputBuffer({ buffer: imageBuffer, }); - const bmp = new DibDecoder(inp, bmpInfo); + const bmp = new DibDecoder(inp, bmpInfo, true); + const image = bmp.decodeFrame(0); - if (image === undefined) { - return undefined; - } - if (bmpInfo.bpp >= 32) { + if (image === undefined || bmpInfo.bitsPerPixel >= 32) { return image; } + const padding = 32 - (bmpInfo.width % 32); - const rowLength = Math.floor( + const rowLength = Math.trunc( (padding === 32 ? bmpInfo.width : bmpInfo.width + padding) / 8 ); + // AND bitmask for (let y = 0; y < bmpInfo.height; y++) { const line = bmpInfo.readBottomUp ? y : image.height - 1 - y; const row = inp.readBytes(rowLength); + const p = image.getPixel(0, line); for (let x = 0; x < bmpInfo.width; ) { const b = row.readByte(); for (let j = 7; j > -1 && x < bmpInfo.width; j--) { if ((b & (1 << j)) !== 0) { - // Just set the pixel to completely transparent. - image.setPixelRgba(x, line, 0, 0, 0, 0); + // set the pixel to completely transparent. + p.a = 0; } + p.next(); x++; } } } - return image; - } - - public decodeHdrFrame(frame: number): HdrImage | undefined { - const img = this.decodeFrame(frame); - if (img === undefined) { - return undefined; - } - return HdrImage.fromImage(img); - } - - public decodeAnimation(_: Uint8Array): FrameAnimation | undefined { - throw new NotImplementedError(); - } - - public decodeImage(bytes: Uint8Array, frame = 0): MemoryImage | undefined { - const info = this.startDecode(bytes); - if (info === undefined) { - return undefined; - } - return this.decodeFrame(frame); - } - public decodeHdrImage(bytes: Uint8Array, frame = 0): HdrImage | undefined { - const img = this.decodeImage(bytes, frame); - if (img === undefined) { - return undefined; - } - return HdrImage.fromImage(img); + return image; } /** @@ -161,8 +163,8 @@ export class IcoDecoder implements Decoder { } let largestFrame = 0; let largestSize = 0; - for (let i = 0; i < this._icoInfo!.images!.length; i++) { - const image = this._icoInfo!.images![i]; + for (let i = 0; i < info.images.length; i++) { + const image = info.images[i]; const size = image.width * image.height; if (size > largestSize) { largestSize = size; diff --git a/src/formats/ico/ico-bmp-info.ts b/src/formats/ico/ico-bmp-info.ts index 01ac518..3495853 100644 --- a/src/formats/ico/ico-bmp-info.ts +++ b/src/formats/ico/ico-bmp-info.ts @@ -8,7 +8,7 @@ export class IcoBmpInfo extends BmpInfo { } public get ignoreAlphaChannel(): boolean { - return this.headerSize === 40 && this.bpp === 32 + return this.headerSize === 40 && this.bitsPerPixel === 32 ? false : super.ignoreAlphaChannel; } diff --git a/src/formats/ico/ico-info-image.ts b/src/formats/ico/ico-info-image.ts index 2f485ef..d9ce639 100644 --- a/src/formats/ico/ico-info-image.ts +++ b/src/formats/ico/ico-info-image.ts @@ -1,5 +1,15 @@ /** @format */ +export interface IcoInfoImageInitOptions { + width: number; + height: number; + colorPalette: number; + bytesSize: number; + bytesOffset: number; + colorPlanes: number; + bitsPerPixel: number; +} + export class IcoInfoImage { private readonly _width: number; public get width(): number { @@ -36,21 +46,13 @@ export class IcoInfoImage { return this._bitsPerPixel; } - constructor( - width: number, - height: number, - colorPalette: number, - bytesSize: number, - bytesOffset: number, - colorPlanes: number, - bitsPerPixel: number - ) { - this._width = width; - this._height = height; - this._colorPalette = colorPalette; - this._bytesSize = bytesSize; - this._bytesOffset = bytesOffset; - this._colorPlanes = colorPlanes; - this._bitsPerPixel = bitsPerPixel; + constructor(opt: IcoInfoImageInitOptions) { + this._width = opt.width; + this._height = opt.height; + this._colorPalette = opt.colorPalette; + this._bytesSize = opt.bytesSize; + this._bytesOffset = opt.bytesOffset; + this._colorPlanes = opt.colorPlanes; + this._bitsPerPixel = opt.bitsPerPixel; } } diff --git a/src/formats/ico/ico-info.ts b/src/formats/ico/ico-info.ts index 5413916..cf01472 100644 --- a/src/formats/ico/ico-info.ts +++ b/src/formats/ico/ico-info.ts @@ -1,28 +1,13 @@ /** @format */ +import { Color } from '../../color/color'; +import { ArrayUtils } from '../../common/array-utils'; import { InputBuffer } from '../../common/input-buffer'; import { DecodeInfo } from '../decode-info'; import { IcoInfoImage } from './ico-info-image'; - -const TYPE_ICO = 1; -const TYPE_CUR = 2; +import { IcoType, IcoTypeLength } from './ico-type'; export class IcoInfo implements DecodeInfo { - private readonly _type?: number; - public get type(): number | undefined { - return this._type; - } - - private readonly _images?: IcoInfoImage[]; - public get images(): IcoInfoImage[] | undefined { - return this._images; - } - - private readonly _numFrames: number; - public get numFrames(): number { - return this._numFrames; - } - private _width = 0; public get width(): number { return this._width; @@ -33,14 +18,29 @@ export class IcoInfo implements DecodeInfo { return this._height; } - private _backgroundColor = 0xffffffff; - public get backgroundColor(): number { + private readonly _type: IcoType; + public get type(): IcoType { + return this._type; + } + + private readonly _numFrames: number; + public get numFrames(): number { + return this._numFrames; + } + + private _backgroundColor: Color | undefined = undefined; + public get backgroundColor(): Color | undefined { return this._backgroundColor; } - constructor(numFrames: number, type?: number, images?: IcoInfoImage[]) { - this._numFrames = numFrames; + private readonly _images: IcoInfoImage[]; + public get images(): IcoInfoImage[] { + return this._images; + } + + constructor(type: number, numFrames: number, images: IcoInfoImage[]) { this._type = type; + this._numFrames = numFrames; this._images = images; } @@ -48,37 +48,33 @@ export class IcoInfo implements DecodeInfo { if (input.readUint16() !== 0) { return undefined; } - const type = input.readUint16(); - if (![TYPE_ICO, TYPE_CUR].includes(type)) { + const t = input.readUint16(); + if (t >= IcoTypeLength) { return undefined; } - if (type === TYPE_CUR) { - // We currently do not support CUR format. + const type = t as IcoType; + if (type === IcoType.cur) { + // CUR format not yet supported. return undefined; } + const imageCount = input.readUint16(); - const images: IcoInfoImage[] = []; - for (let i = 0; i < imageCount; i++) { - const width = input.readByte(); - const height = input.readByte(); - const colorPalette = input.readByte(); - input.skip(1); - const colorPlanes = input.readUint16(); - const bitsPerPixel = input.readUint16(); - const bytesSize = input.readUint32(); - const bytesOffset = input.readUint32(); - const image = new IcoInfoImage( - width, - height, - colorPalette, - bytesSize, - bytesOffset, - colorPlanes, - bitsPerPixel - ); - images.push(image); - } - return new IcoInfo(imageCount, type, images); + const images = ArrayUtils.generate( + imageCount, + (_) => + new IcoInfoImage({ + width: input.readByte(), + height: input.readByte(), + colorPalette: input.readByte(), + // ignore 1 byte + colorPlanes: (input.skip(1), input).readUint16(), + bitsPerPixel: input.readUint16(), + bytesSize: input.readUint32(), + bytesOffset: input.readUint32(), + }) + ); + + return new IcoInfo(type, imageCount, images); } } diff --git a/src/formats/ico/ico-type.ts b/src/formats/ico/ico-type.ts new file mode 100644 index 0000000..6dc64de --- /dev/null +++ b/src/formats/ico/ico-type.ts @@ -0,0 +1,9 @@ +/** @format */ + +export enum IcoType { + invalid, + ico, + cur, +} + +export const IcoTypeLength = 3; diff --git a/src/formats/jpeg-decoder.ts b/src/formats/jpeg-decoder.ts index dd40538..83133dc 100644 --- a/src/formats/jpeg-decoder.ts +++ b/src/formats/jpeg-decoder.ts @@ -1,10 +1,8 @@ /** @format */ -import { FrameAnimation } from '../common/frame-animation'; import { InputBuffer } from '../common/input-buffer'; -import { MemoryImage } from '../common/memory-image'; -import { ImageError } from '../error/image-error'; -import { HdrImage } from '../hdr/hdr-image'; +import { LibError } from '../error/lib-error'; +import { MemoryImage } from '../image/image'; import { Decoder } from './decoder'; import { JpegData } from './jpeg/jpeg-data'; import { JpegInfo } from './jpeg/jpeg-info'; @@ -13,12 +11,11 @@ import { JpegInfo } from './jpeg/jpeg-info'; * Decode a jpeg encoded image. */ export class JpegDecoder implements Decoder { - private info?: JpegInfo; - - private input?: InputBuffer; + private _input?: InputBuffer; + private _info?: JpegInfo; public get numFrames(): number { - return this.info !== undefined ? this.info.numFrames : 0; + return this._info !== undefined ? this._info.numFrames : 0; } /** @@ -29,66 +26,36 @@ export class JpegDecoder implements Decoder { } public startDecode(bytes: Uint8Array): JpegInfo | undefined { - this.input = new InputBuffer({ + this._input = new InputBuffer({ buffer: bytes, bigEndian: true, }); - this.info = new JpegData().readInfo(bytes); - return this.info; + this._info = new JpegData().readInfo(bytes); + return this._info; } public decodeFrame(_: number): MemoryImage | undefined { - if (this.input === undefined) { + if (this._input === undefined) { return undefined; } + const jpeg = new JpegData(); - jpeg.read(this.input.buffer); + jpeg.read(this._input.buffer); if (jpeg.frames.length !== 1) { - throw new ImageError('only single frame JPEGs supported'); + throw new LibError('Only single frame JPEGs supported.'); } return jpeg.getImage(); } - public decodeHdrFrame(frame: number): HdrImage | undefined { - const img = this.decodeFrame(frame); - if (img === undefined) { - return undefined; - } - return HdrImage.fromImage(img); - } - - public decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined { - const image = this.decodeImage(bytes); - if (image === undefined) { - return undefined; - } - - const animation = new FrameAnimation({ - width: image.width, - height: image.height, - }); - animation.addFrame(image); - - return animation; - } - - public decodeImage(bytes: Uint8Array, _?: number): MemoryImage | undefined { + public decode(bytes: Uint8Array, _frame?: number): MemoryImage | undefined { const jpeg = new JpegData(); jpeg.read(bytes); if (jpeg.frames.length !== 1) { - throw new ImageError('only single frame JPEGs supported'); + throw new LibError('Only single frame JPEGs supported.'); } return jpeg.getImage(); } - - public decodeHdrImage(bytes: Uint8Array, frame = 0): HdrImage | undefined { - const img = this.decodeImage(bytes, frame); - if (img === undefined) { - return undefined; - } - return HdrImage.fromImage(img); - } } diff --git a/src/formats/jpeg-encoder.ts b/src/formats/jpeg-encoder.ts index 92b43df..f221223 100644 --- a/src/formats/jpeg-encoder.ts +++ b/src/formats/jpeg-encoder.ts @@ -1,37 +1,37 @@ /** @format */ -import { FrameAnimation } from '../common/frame-animation'; -import { MathOperators } from '../common/math-operators'; -import { MemoryImage } from '../common/memory-image'; +import { ArrayUtils } from '../common/array-utils'; +import { MathUtils } from '../common/math-utils'; import { OutputBuffer } from '../common/output-buffer'; import { ExifData } from '../exif/exif-data'; +import { MemoryImage } from '../image/image'; import { Encoder } from './encoder'; -import { Jpeg } from './jpeg/jpeg'; +import { JpegMarker } from './jpeg/jpeg-marker'; /** * Encode an image to the JPEG format. */ export class JpegEncoder implements Encoder { - private static readonly ZIGZAG: number[] = [ + private static readonly _zigzag: number[] = [ 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63, ]; - private static readonly STD_DC_LUMINANCE_NR_CODES: number[] = [ + private static readonly _stdDcLuminanceNrCodes: number[] = [ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, ]; - private static readonly STD_DC_LUMINANCE_VALUES: number[] = [ + private static readonly _stdDcLuminanceValues: number[] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ]; - private static readonly STD_AC_LUMINANCE_NR_CODES: number[] = [ + private static readonly _stdAcLuminanceNrCodes: number[] = [ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d, ]; - private static readonly STD_AC_LUMINANCE_VALUES: number[] = [ + private static readonly _stdAcLuminanceValues: number[] = [ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, @@ -48,19 +48,19 @@ export class JpegEncoder implements Encoder { 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, ]; - private static readonly STD_DC_CHROMINANCE_NR_CODES: number[] = [ + private static readonly _stdDcChrominanceNrCodes: number[] = [ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, ]; - private static readonly STD_DC_CHROMINANCE_VALUES: number[] = [ + private static readonly _stdDcChrominanceValues: number[] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ]; - private static readonly STD_AC_CHROMINANCE_NR_CODES: number[] = [ + private static readonly _stdAcChrominanceNrCodes: number[] = [ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77, ]; - private static readonly STD_AC_CHROMINANCE_VALUES: number[] = [ + private static readonly _stdAcChrominanceValues: number[] = [ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, @@ -77,36 +77,39 @@ export class JpegEncoder implements Encoder { 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, ]; - private readonly tableY = new Uint8Array(64); - private readonly tableUV = new Uint8Array(64); - private readonly ftableY = new Float32Array(64); - private readonly ftableUV = new Float32Array(64); + private readonly _tableY = new Uint8Array(64); + private readonly _tableUv = new Uint8Array(64); + private readonly _fdTableY = new Float32Array(64); + private readonly _fdTableUv = new Float32Array(64); - private readonly bitcode = new Array | undefined>(65535).fill( + private readonly _bitCode = ArrayUtils.fill( + 65535, undefined ); - private readonly category = new Array(65535).fill( + private readonly _category = ArrayUtils.fill( + 65535, undefined ); - private readonly outputfDCTQuant = new Array(64).fill( + private readonly _outputfDCTQuant = ArrayUtils.fill( + 64, undefined ); - private readonly DU = new Array(64).fill(undefined); + private readonly _du = ArrayUtils.fill(64, undefined); - private readonly YDU: Float32Array = new Float32Array(64); - private readonly UDU: Float32Array = new Float32Array(64); - private readonly VDU: Float32Array = new Float32Array(64); - private readonly tableRGBYUV: Int32Array = new Int32Array(2048); + private readonly _ydu: Float32Array = new Float32Array(64); + private readonly _udu: Float32Array = new Float32Array(64); + private readonly _vdu: Float32Array = new Float32Array(64); + private readonly _tableRgbYuv: Int32Array = new Int32Array(2048); - private htYDC: Array | undefined> | undefined; - private htUVDC: Array | undefined> | undefined; - private htYAC!: Array | undefined>; - private htUVAC!: Array | undefined>; + private _ydcHuffman: Array | undefined> | undefined; + private _uvdcHuffman: Array | undefined> | undefined; + private _yacHuffman!: Array | undefined>; + private _uvacHuffman!: Array | undefined>; - private currentQuality?: number; + private _currentQuality?: number; - private byteNew = 0; - private bytePos = 7; + private _byteNew = 0; + private _bytePos = 7; private _supportsAnimation = false; public get supportsAnimation(): boolean { @@ -116,7 +119,7 @@ export class JpegEncoder implements Encoder { constructor(quality = 100) { this.initHuffmanTable(); this.initCategoryNumber(); - this.initRGBYUVTable(); + this.initRgbYuvTable(); this.setQuality(quality); } @@ -124,22 +127,22 @@ export class JpegEncoder implements Encoder { nrcodes: number[], stdTable: number[] ): Array | undefined> { - let codevalue = 0; + let codeValue = 0; let posInTable = 0; - const HT = new Array | undefined>(); + const ht = new Array | undefined>(); for (let k = 1; k <= 16; k++) { for (let j = 1; j <= nrcodes[k]; j++) { const index = stdTable[posInTable]; - if (HT.length <= index) { - HT.length = index + 1; + if (ht.length <= index) { + ht.length = index + 1; } - HT[index] = [codevalue, k]; + ht[index] = [codeValue, k]; posInTable++; - codevalue++; + codeValue++; } - codevalue *= 2; + codeValue *= 2; } - return HT; + return ht; } private static writeMarker(fp: OutputBuffer, marker: number): void { @@ -148,7 +151,7 @@ export class JpegEncoder implements Encoder { } private static writeAPP0(out: OutputBuffer): void { - JpegEncoder.writeMarker(out, Jpeg.M_APP0); + JpegEncoder.writeMarker(out, JpegMarker.app0); // Length out.writeUint16(16); // J @@ -186,10 +189,10 @@ export class JpegEncoder implements Encoder { exif.write(exifData); const exifBytes = exifData.getBytes(); - this.writeMarker(out, Jpeg.M_APP1); - out.writeUint16(exifBytes.length + 8); - // Exif\0\0 + this.writeMarker(out, JpegMarker.app1); + // Signature: Exif\0\0 const exifSignature = 0x45786966; + out.writeUint16(exifBytes.length + 8); out.writeUint32(exifSignature); out.writeUint16(0); out.writeBytes(exifBytes); @@ -200,7 +203,7 @@ export class JpegEncoder implements Encoder { width: number, height: number ): void { - JpegEncoder.writeMarker(out, Jpeg.M_SOF0); + JpegEncoder.writeMarker(out, JpegMarker.sof0); // Length, truecolor YUV JPG out.writeUint16(17); // Precision @@ -230,7 +233,7 @@ export class JpegEncoder implements Encoder { } private static writeSOS(out: OutputBuffer): void { - JpegEncoder.writeMarker(out, Jpeg.M_SOS); + JpegEncoder.writeMarker(out, JpegMarker.sos); // Length out.writeUint16(12); // Nrofcomponents @@ -256,102 +259,102 @@ export class JpegEncoder implements Encoder { } private static writeDHT(out: OutputBuffer): void { - JpegEncoder.writeMarker(out, Jpeg.M_DHT); + JpegEncoder.writeMarker(out, JpegMarker.dht); // Length out.writeUint16(0x01a2); // HTYDCinfo out.writeByte(0); for (let i = 0; i < 16; i++) { - out.writeByte(JpegEncoder.STD_DC_LUMINANCE_NR_CODES[i + 1]); + out.writeByte(JpegEncoder._stdDcLuminanceNrCodes[i + 1]); } for (let j = 0; j <= 11; j++) { - out.writeByte(JpegEncoder.STD_DC_LUMINANCE_VALUES[j]); + out.writeByte(JpegEncoder._stdDcLuminanceValues[j]); } // HTYACinfo out.writeByte(0x10); for (let k = 0; k < 16; k++) { - out.writeByte(JpegEncoder.STD_AC_LUMINANCE_NR_CODES[k + 1]); + out.writeByte(JpegEncoder._stdAcLuminanceNrCodes[k + 1]); } for (let l = 0; l <= 161; l++) { - out.writeByte(JpegEncoder.STD_AC_LUMINANCE_VALUES[l]); + out.writeByte(JpegEncoder._stdAcLuminanceValues[l]); } // HTUDCinfo out.writeByte(1); for (let m = 0; m < 16; m++) { - out.writeByte(JpegEncoder.STD_DC_CHROMINANCE_NR_CODES[m + 1]); + out.writeByte(JpegEncoder._stdDcChrominanceNrCodes[m + 1]); } for (let n = 0; n <= 11; n++) { - out.writeByte(JpegEncoder.STD_DC_CHROMINANCE_VALUES[n]); + out.writeByte(JpegEncoder._stdDcChrominanceValues[n]); } // HTUACinfo out.writeByte(0x11); for (let o = 0; o < 16; o++) { - out.writeByte(JpegEncoder.STD_AC_CHROMINANCE_NR_CODES[o + 1]); + out.writeByte(JpegEncoder._stdAcChrominanceNrCodes[o + 1]); } for (let p = 0; p <= 161; p++) { - out.writeByte(JpegEncoder.STD_AC_CHROMINANCE_VALUES[p]); + out.writeByte(JpegEncoder._stdAcChrominanceValues[p]); } } private initHuffmanTable(): void { - this.htYDC = JpegEncoder.computeHuffmanTable( - JpegEncoder.STD_DC_LUMINANCE_NR_CODES, - JpegEncoder.STD_DC_LUMINANCE_VALUES + this._ydcHuffman = JpegEncoder.computeHuffmanTable( + JpegEncoder._stdDcLuminanceNrCodes, + JpegEncoder._stdDcLuminanceValues ); - this.htUVDC = JpegEncoder.computeHuffmanTable( - JpegEncoder.STD_DC_CHROMINANCE_NR_CODES, - JpegEncoder.STD_DC_CHROMINANCE_VALUES + this._uvdcHuffman = JpegEncoder.computeHuffmanTable( + JpegEncoder._stdDcChrominanceNrCodes, + JpegEncoder._stdDcChrominanceValues ); - this.htYAC = JpegEncoder.computeHuffmanTable( - JpegEncoder.STD_AC_LUMINANCE_NR_CODES, - JpegEncoder.STD_AC_LUMINANCE_VALUES + this._yacHuffman = JpegEncoder.computeHuffmanTable( + JpegEncoder._stdAcLuminanceNrCodes, + JpegEncoder._stdAcLuminanceValues ); - this.htUVAC = JpegEncoder.computeHuffmanTable( - JpegEncoder.STD_AC_CHROMINANCE_NR_CODES, - JpegEncoder.STD_AC_CHROMINANCE_VALUES + this._uvacHuffman = JpegEncoder.computeHuffmanTable( + JpegEncoder._stdAcChrominanceNrCodes, + JpegEncoder._stdAcChrominanceValues ); } private initCategoryNumber(): void { - let nrlower = 1; - let nrupper = 2; + let nrLower = 1; + let nrUpper = 2; for (let cat = 1; cat <= 15; cat++) { // Positive numbers - for (let nr = nrlower; nr < nrupper; nr++) { - this.category[32767 + nr] = cat; - this.bitcode[32767 + nr] = [nr, cat]; + for (let nr = nrLower; nr < nrUpper; nr++) { + this._category[32767 + nr] = cat; + this._bitCode[32767 + nr] = [nr, cat]; } // Negative numbers - for (let nrneg = -(nrupper - 1); nrneg <= -nrlower; nrneg++) { - this.category[32767 + nrneg] = cat; - this.bitcode[32767 + nrneg] = [nrupper - 1 + nrneg, cat]; + for (let nrneg = -(nrUpper - 1); nrneg <= -nrLower; nrneg++) { + this._category[32767 + nrneg] = cat; + this._bitCode[32767 + nrneg] = [nrUpper - 1 + nrneg, cat]; } - nrlower <<= 1; - nrupper <<= 1; + nrLower <<= 1; + nrUpper <<= 1; } } - private initRGBYUVTable(): void { + private initRgbYuvTable(): void { for (let i = 0; i < 256; i++) { - this.tableRGBYUV[i] = 19595 * i; - this.tableRGBYUV[i + 256] = 38470 * i; - this.tableRGBYUV[i + 512] = 7471 * i + 0x8000; - this.tableRGBYUV[i + 768] = -11059 * i; - this.tableRGBYUV[i + 1024] = -21709 * i; - this.tableRGBYUV[i + 1280] = 32768 * i + 0x807fff; - this.tableRGBYUV[i + 1536] = -27439 * i; - this.tableRGBYUV[i + 1792] = -5329 * i; + this._tableRgbYuv[i] = 19595 * i; + this._tableRgbYuv[i + 256] = 38470 * i; + this._tableRgbYuv[i + 512] = 7471 * i + 0x8000; + this._tableRgbYuv[i + 768] = -11059 * i; + this._tableRgbYuv[i + 1024] = -21709 * i; + this._tableRgbYuv[i + 1280] = 32768 * i + 0x807fff; + this._tableRgbYuv[i + 1536] = -27439 * i; + this._tableRgbYuv[i + 1792] = -5329 * i; } } private setQuality(quality: number): void { - const q = MathOperators.clampInt(quality, 1, 100); + const q = MathUtils.clampInt(quality, 1, 100); - if (this.currentQuality === q) { + if (this._currentQuality === q) { // Don't re-calc if unchanged return; } @@ -364,11 +367,11 @@ export class JpegEncoder implements Encoder { } this.initQuantTables(sf); - this.currentQuality = q; + this._currentQuality = q; } private initQuantTables(sf: number): void { - const YQT: number[] = [ + const yqt: number[] = [ 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, @@ -376,16 +379,16 @@ export class JpegEncoder implements Encoder { ]; for (let i = 0; i < 64; i++) { - let t = Math.floor((YQT[i] * sf + 50) / 100); + let t = Math.floor((yqt[i] * sf + 50) / 100); if (t < 1) { t = 1; } else if (t > 255) { t = 255; } - this.tableY[JpegEncoder.ZIGZAG[i]] = t; + this._tableY[JpegEncoder._zigzag[i]] = t; } - const UVQT: number[] = [ + const uvqt: number[] = [ 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, @@ -393,13 +396,13 @@ export class JpegEncoder implements Encoder { ]; for (let j = 0; j < 64; j++) { - let u = Math.floor((UVQT[j] * sf + 50) / 100); + let u = Math.floor((uvqt[j] * sf + 50) / 100); if (u < 1) { u = 1; } else if (u > 255) { u = 255; } - this.tableUV[JpegEncoder.ZIGZAG[j]] = u; + this._tableUv[JpegEncoder._zigzag[j]] = u; } const aasf: number[] = [ @@ -410,12 +413,12 @@ export class JpegEncoder implements Encoder { let k = 0; for (let row = 0; row < 8; row++) { for (let col = 0; col < 8; col++) { - this.ftableY[k] = - 1.0 / - (this.tableY[JpegEncoder.ZIGZAG[k]] * aasf[row] * aasf[col] * 8.0); - this.ftableUV[k] = - 1.0 / - (this.tableUV[JpegEncoder.ZIGZAG[k]] * aasf[row] * aasf[col] * 8.0); + this._fdTableY[k] = + 1 / + (this._tableY[JpegEncoder._zigzag[k]] * aasf[row] * aasf[col] * 8.0); + this._fdTableUv[k] = + 1 / + (this._tableUv[JpegEncoder._zigzag[k]] * aasf[row] * aasf[col] * 8.0); k++; } } @@ -428,9 +431,7 @@ export class JpegEncoder implements Encoder { ): Array { // Pass 1: process rows. let dataOff = 0; - const I8 = 8; - const I64 = 64; - for (let i = 0; i < I8; ++i) { + for (let i = 0; i < 8; ++i) { const d0 = data[dataOff]; const d1 = data[dataOff + 1]; const d2 = data[dataOff + 2]; @@ -498,7 +499,7 @@ export class JpegEncoder implements Encoder { // Pass 2: process columns. dataOff = 0; - for (let i = 0; i < I8; ++i) { + for (let i = 0; i < 8; ++i) { const d0 = data[dataOff]; const d1 = data[dataOff + 8]; const d2 = data[dataOff + 16]; @@ -564,29 +565,29 @@ export class JpegEncoder implements Encoder { } // Quantize/descale the coefficients - for (let i = 0; i < I64; ++i) { + for (let i = 0; i < 64; ++i) { // Apply the quantization and scaling factor & Round to nearest integer const fDCTQuant = data[i] * fdtbl[i]; - this.outputfDCTQuant[i] = + this._outputfDCTQuant[i] = fDCTQuant > 0.0 ? Math.trunc(fDCTQuant + 0.5) : Math.trunc(fDCTQuant - 0.5); } - return this.outputfDCTQuant; + return this._outputfDCTQuant; } private writeDQT(out: OutputBuffer): void { - JpegEncoder.writeMarker(out, Jpeg.M_DQT); + JpegEncoder.writeMarker(out, JpegMarker.dqt); // Length out.writeUint16(132); out.writeByte(0); for (let i = 0; i < 64; i++) { - out.writeByte(this.tableY[i]); + out.writeByte(this._tableY[i]); } out.writeByte(1); for (let j = 0; j < 64; j++) { - out.writeByte(this.tableUV[j]); + out.writeByte(this._tableUv[j]); } } @@ -595,106 +596,106 @@ export class JpegEncoder implements Encoder { let posval = bits[1] - 1; while (posval >= 0) { if ((value & (1 << posval)) !== 0) { - this.byteNew |= 1 << this.bytePos; + this._byteNew |= 1 << this._bytePos; } posval--; - this.bytePos--; - if (this.bytePos < 0) { - if (this.byteNew === 0xff) { + this._bytePos--; + if (this._bytePos < 0) { + if (this._byteNew === 0xff) { out.writeByte(0xff); out.writeByte(0); } else { - out.writeByte(this.byteNew); + out.writeByte(this._byteNew); } - this.bytePos = 7; - this.byteNew = 0; + this._bytePos = 7; + this._byteNew = 0; } } } private resetBits(): void { - this.byteNew = 0; - this.bytePos = 7; + this._byteNew = 0; + this._bytePos = 7; } private processDU( out: OutputBuffer, - CDU: Float32Array, + cdu: Float32Array, fdtbl: Float32Array, - DC: number, - HTAC: Array | undefined>, - HTDC?: Array | undefined> + dc: number, + htac: Array, + htdc?: Array ): number | undefined { - const EOB = HTAC[0x00]; - const M16zeroes = HTAC[0xf0]; + const eob = htac[0x00]; + const m16Zeroes = htac[0xf0]; const I16 = 16; const I63 = 63; const I64 = 64; - const DU_DCT = this.fDCTQuant(CDU, fdtbl); - let dc = DC; + const duDct = this.fDCTQuant(cdu, fdtbl); + let _dc = dc; let pos = 0; // ZigZag reorder for (let j = 0; j < I64; ++j) { - this.DU[JpegEncoder.ZIGZAG[j]] = DU_DCT[j]; + this._du[JpegEncoder._zigzag[j]] = duDct[j]; } - const Diff = this.DU[0]! - dc; - dc = this.DU[0]!; + const diff = this._du[0]! - _dc; + _dc = this._du[0]!; // Encode DC - if (Diff === 0) { + if (diff === 0) { // Diff might be 0 - this.writeBits(out, HTDC![0]!); + this.writeBits(out, htdc![0]!); } else { - pos = 32767 + Diff; - this.writeBits(out, HTDC![this.category[pos]!]!); - this.writeBits(out, this.bitcode[pos]!); + pos = 32767 + diff; + this.writeBits(out, htdc![this._category[pos]!]!); + this.writeBits(out, this._bitCode[pos]!); } // Encode ACs let end0pos = 63; // eslint-disable-next-line no-empty - for (; end0pos > 0 && this.DU[end0pos] === 0; end0pos--) {} + for (; end0pos > 0 && this._du[end0pos] === 0; end0pos--) {} //End0pos = first element in reverse order !=0 if (end0pos === 0) { - this.writeBits(out, EOB!); - return dc; + this.writeBits(out, eob!); + return _dc; } let i = 1; while (i <= end0pos) { const startpos = i; // eslint-disable-next-line no-empty - for (; this.DU[i] === 0 && i <= end0pos; ++i) {} + for (; this._du[i] === 0 && i <= end0pos; ++i) {} let nrzeroes = i - startpos; if (nrzeroes >= I16) { const lng = nrzeroes >> 4; for (let nrmarker = 1; nrmarker <= lng; ++nrmarker) { - this.writeBits(out, M16zeroes!); + this.writeBits(out, m16Zeroes!); } nrzeroes &= 0xf; } - pos = 32767 + this.DU[i]!; - this.writeBits(out, HTAC[(nrzeroes << 4) + this.category[pos]!]!); - this.writeBits(out, this.bitcode[pos]!); + pos = 32767 + this._du[i]!; + this.writeBits(out, htac[(nrzeroes << 4) + this._category[pos]!]!); + this.writeBits(out, this._bitCode[pos]!); i++; } if (end0pos !== I63) { - this.writeBits(out, EOB!); + this.writeBits(out, eob!); } - return dc; + return _dc; } - public encodeImage(image: MemoryImage): Uint8Array { + public encode(image: MemoryImage, _singleFrame = false): Uint8Array { const fp = new OutputBuffer({ bigEndian: true, }); // Add JPEG headers - JpegEncoder.writeMarker(fp, Jpeg.M_SOI); + JpegEncoder.writeMarker(fp, JpegMarker.soi); JpegEncoder.writeAPP0(fp); JpegEncoder.writeAPP1(fp, image.exifData); this.writeDQT(fp); @@ -703,112 +704,105 @@ export class JpegEncoder implements Encoder { JpegEncoder.writeSOS(fp); // Encode 8x8 macroblocks - let DCY: number | undefined = 0; - let DCU: number | undefined = 0; - let DCV: number | undefined = 0; + let dcy: number | undefined = 0; + let dcu: number | undefined = 0; + let dcv: number | undefined = 0; this.resetBits(); const width = image.width; const height = image.height; - const imageData = image.getBytes(); - const quadWidth = width * 4; - // Let tripleWidth: number = width * 3; - // let first: Boolean = true; - let y = 0; while (y < height) { let x = 0; - while (x < quadWidth) { - const start = quadWidth * y + x; + while (x < width) { for (let pos = 0; pos < 64; pos++) { // / 8 const row = pos >> 3; // % 8 - const col = (pos & 7) * 4; - let p = start + row * quadWidth + col; + const col = pos & 7; - if (y + row >= height) { - // Padding bottom - p -= quadWidth * (y + 1 + row - height); + let yy = y + row; + let xx = x + col; + + if (yy >= height) { + // padding bottom + yy -= y + 1 + row - height; } - if (x + col >= quadWidth) { - // Padding right - p -= x + col - quadWidth + 4; + if (xx >= width) { + // padding right + xx -= x + col - width + 1; } - const r = imageData[p++]; - const g = imageData[p++]; - const b = imageData[p++]; + const p = image.getPixel(xx, yy); + const r = Math.trunc(p.r); + const g = Math.trunc(p.g); + const b = Math.trunc(p.b); - // Calculate YUV values - this.YDU[pos] = - ((this.tableRGBYUV[r] + - this.tableRGBYUV[g + 256] + - this.tableRGBYUV[b + 512]) >> + // calculate YUV values + this._ydu[pos] = + ((this._tableRgbYuv[r] + + this._tableRgbYuv[g + 256] + + this._tableRgbYuv[b + 512]) >> 16) - 128.0; - this.UDU[pos] = - ((this.tableRGBYUV[r + 768] + - this.tableRGBYUV[g + 1024] + - this.tableRGBYUV[b + 1280]) >> + this._udu[pos] = + ((this._tableRgbYuv[r + 768] + + this._tableRgbYuv[g + 1024] + + this._tableRgbYuv[b + 1280]) >> 16) - 128.0; - this.VDU[pos] = - ((this.tableRGBYUV[r + 1280] + - this.tableRGBYUV[g + 1536] + - this.tableRGBYUV[b + 1792]) >> + this._vdu[pos] = + ((this._tableRgbYuv[r + 1280] + + this._tableRgbYuv[g + 1536] + + this._tableRgbYuv[b + 1792]) >> 16) - 128.0; } - DCY = this.processDU( + dcy = this.processDU( fp, - this.YDU, - this.ftableY, - DCY!, - this.htYAC, - this.htYDC + this._ydu, + this._fdTableY, + dcy!, + this._yacHuffman, + this._ydcHuffman ); - DCU = this.processDU( + dcu = this.processDU( fp, - this.UDU, - this.ftableUV, - DCU!, - this.htUVAC, - this.htUVDC + this._udu, + this._fdTableUv, + dcu!, + this._uvacHuffman, + this._uvdcHuffman ); - DCV = this.processDU( + dcv = this.processDU( fp, - this.VDU, - this.ftableUV, - DCV!, - this.htUVAC, - this.htUVDC + this._vdu, + this._fdTableUv, + dcv!, + this._uvacHuffman, + this._uvdcHuffman ); - x += 32; + x += 8; } y += 8; } // Do the bit alignment of the EOI marker - if (this.bytePos >= 0) { - const fillBits = [(1 << (this.bytePos + 1)) - 1, this.bytePos + 1]; + if (this._bytePos >= 0) { + const fillBits = [(1 << (this._bytePos + 1)) - 1, this._bytePos + 1]; this.writeBits(fp, fillBits); } - JpegEncoder.writeMarker(fp, Jpeg.M_EOI); + JpegEncoder.writeMarker(fp, JpegMarker.eoi); return fp.getBytes(); } - - public encodeAnimation(_: FrameAnimation): Uint8Array | undefined { - return undefined; - } } diff --git a/src/formats/jpeg/huffman-node.ts b/src/formats/jpeg/huffman-node.ts new file mode 100644 index 0000000..a39fc6a --- /dev/null +++ b/src/formats/jpeg/huffman-node.ts @@ -0,0 +1,3 @@ +/** @format */ + +export abstract class HuffmanNode {} diff --git a/src/formats/jpeg/huffman-parent.ts b/src/formats/jpeg/huffman-parent.ts new file mode 100644 index 0000000..2221964 --- /dev/null +++ b/src/formats/jpeg/huffman-parent.ts @@ -0,0 +1,15 @@ +/** @format */ + +import { HuffmanNode } from './huffman-node'; + +export class HuffmanParent extends HuffmanNode { + private readonly _children: Array; + public get children(): Array { + return this._children; + } + + constructor(children: Array) { + super(); + this._children = children; + } +} diff --git a/src/formats/jpeg/huffman-value.ts b/src/formats/jpeg/huffman-value.ts new file mode 100644 index 0000000..18e5be9 --- /dev/null +++ b/src/formats/jpeg/huffman-value.ts @@ -0,0 +1,15 @@ +/** @format */ + +import { HuffmanNode } from './huffman-node'; + +export class HuffmanValue extends HuffmanNode { + private readonly _value: number; + public get value(): number { + return this._value; + } + + constructor(value: number) { + super(); + this._value = value; + } +} diff --git a/src/formats/jpeg/component-data.ts b/src/formats/jpeg/jpeg-component-data.ts similarity index 86% rename from src/formats/jpeg/component-data.ts rename to src/formats/jpeg/jpeg-component-data.ts index 60c3cf2..2739625 100644 --- a/src/formats/jpeg/component-data.ts +++ b/src/formats/jpeg/jpeg-component-data.ts @@ -1,6 +1,6 @@ /** @format */ -export class ComponentData { +export class JpegComponentData { private _hSamples: number; public get hSamples(): number { return this._hSamples; @@ -21,8 +21,8 @@ export class ComponentData { return this._maxVSamples; } - private _lines: Array; - public get lines(): Array { + private _lines: Array; + public get lines(): Array { return this._lines; } @@ -41,7 +41,7 @@ export class ComponentData { maxHSamples: number, vSamples: number, maxVSamples: number, - lines: Array + lines: Array ) { this._hSamples = hSamples; this._maxHSamples = maxHSamples; diff --git a/src/formats/jpeg/jpeg-component.ts b/src/formats/jpeg/jpeg-component.ts index 51f91c2..1bf4b8e 100644 --- a/src/formats/jpeg/jpeg-component.ts +++ b/src/formats/jpeg/jpeg-component.ts @@ -1,5 +1,7 @@ /** @format */ +import { HuffmanNode } from './huffman-node'; + export class JpegComponent { private readonly _quantizationTableList: Array; @@ -30,19 +32,19 @@ export class JpegComponent { return this._blocksPerColumn; } - private _huffmanTableDC: [] = []; - public set huffmanTableDC(v: []) { + private _huffmanTableDC: Array = []; + public set huffmanTableDC(v: Array) { this._huffmanTableDC = v; } - public get huffmanTableDC(): [] { + public get huffmanTableDC(): Array { return this._huffmanTableDC; } - private _huffmanTableAC: [] = []; - public set huffmanTableAC(v: []) { + private _huffmanTableAC: Array = []; + public set huffmanTableAC(v: Array) { this._huffmanTableAC = v; } - public get huffmanTableAC(): [] { + public get huffmanTableAC(): Array { return this._huffmanTableAC; } diff --git a/src/formats/jpeg/jpeg-data.ts b/src/formats/jpeg/jpeg-data.ts index 46de3f8..d5fd80f 100644 --- a/src/formats/jpeg/jpeg-data.ts +++ b/src/formats/jpeg/jpeg-data.ts @@ -1,11 +1,8 @@ /** @format */ import { InputBuffer } from '../../common/input-buffer'; -import { ArrayUtils } from '../../common/array-utils'; -import { MemoryImage } from '../../common/memory-image'; -import { ImageError } from '../../error/image-error'; -import { ComponentData } from './component-data'; -import { Jpeg } from './jpeg'; +import { LibError } from '../../error/lib-error'; +import { JpegComponentData } from './jpeg-component-data'; import { JpegAdobe } from './jpeg-adobe'; import { JpegComponent } from './jpeg-component'; import { JpegFrame } from './jpeg-frame'; @@ -15,121 +12,37 @@ import { JpegJfif } from './jpeg-jfif'; import { JpegQuantize } from './jpeg-quantize'; import { JpegScan } from './jpeg-scan'; import { ExifData } from '../../exif/exif-data'; +import { ArrayUtils } from '../../common/array-utils'; +import { JpegMarker } from './jpeg-marker'; +import { MemoryImage } from '../../image/image'; +import { HuffmanNode } from './huffman-node'; +import { HuffmanValue } from './huffman-value'; +import { HuffmanParent } from './huffman-parent'; export class JpegData { - static readonly CRR = [ - -179, -178, -177, -175, -174, -172, -171, -170, -168, -167, -165, -164, - -163, -161, -160, -158, -157, -156, -154, -153, -151, -150, -149, -147, - -146, -144, -143, -142, -140, -139, -137, -136, -135, -133, -132, -130, - -129, -128, -126, -125, -123, -122, -121, -119, -118, -116, -115, -114, - -112, -111, -109, -108, -107, -105, -104, -102, -101, -100, -98, -97, -95, - -94, -93, -91, -90, -88, -87, -86, -84, -83, -81, -80, -79, -77, -76, -74, - -73, -72, -70, -69, -67, -66, -64, -63, -62, -60, -59, -57, -56, -55, -53, - -52, -50, -49, -48, -46, -45, -43, -42, -41, -39, -38, -36, -35, -34, -32, - -31, -29, -28, -27, -25, -24, -22, -21, -20, -18, -17, -15, -14, -13, -11, - -10, -8, -7, -6, -4, -3, -1, 0, 1, 3, 4, 6, 7, 8, 10, 11, 13, 14, 15, 17, - 18, 20, 21, 22, 24, 25, 27, 28, 29, 31, 32, 34, 35, 36, 38, 39, 41, 42, 43, - 45, 46, 48, 49, 50, 52, 53, 55, 56, 57, 59, 60, 62, 63, 64, 66, 67, 69, 70, - 72, 73, 74, 76, 77, 79, 80, 81, 83, 84, 86, 87, 88, 90, 91, 93, 94, 95, 97, - 98, 100, 101, 102, 104, 105, 107, 108, 109, 111, 112, 114, 115, 116, 118, - 119, 121, 122, 123, 125, 126, 128, 129, 130, 132, 133, 135, 136, 137, 139, - 140, 142, 143, 144, 146, 147, 149, 150, 151, 153, 154, 156, 157, 158, 160, - 161, 163, 164, 165, 167, 168, 170, 171, 172, 174, 175, 177, 178, + public static readonly dctZigZag = [ + 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, + 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, + 54, 47, 55, 62, 63, + // extra entries for safety in decoder + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, ]; - static readonly CRG = [ - 5990656, 5943854, 5897052, 5850250, 5803448, 5756646, 5709844, 5663042, - 5616240, 5569438, 5522636, 5475834, 5429032, 5382230, 5335428, 5288626, - 5241824, 5195022, 5148220, 5101418, 5054616, 5007814, 4961012, 4914210, - 4867408, 4820606, 4773804, 4727002, 4680200, 4633398, 4586596, 4539794, - 4492992, 4446190, 4399388, 4352586, 4305784, 4258982, 4212180, 4165378, - 4118576, 4071774, 4024972, 3978170, 3931368, 3884566, 3837764, 3790962, - 3744160, 3697358, 3650556, 3603754, 3556952, 3510150, 3463348, 3416546, - 3369744, 3322942, 3276140, 3229338, 3182536, 3135734, 3088932, 3042130, - 2995328, 2948526, 2901724, 2854922, 2808120, 2761318, 2714516, 2667714, - 2620912, 2574110, 2527308, 2480506, 2433704, 2386902, 2340100, 2293298, - 2246496, 2199694, 2152892, 2106090, 2059288, 2012486, 1965684, 1918882, - 1872080, 1825278, 1778476, 1731674, 1684872, 1638070, 1591268, 1544466, - 1497664, 1450862, 1404060, 1357258, 1310456, 1263654, 1216852, 1170050, - 1123248, 1076446, 1029644, 982842, 936040, 889238, 842436, 795634, 748832, - 702030, 655228, 608426, 561624, 514822, 468020, 421218, 374416, 327614, - 280812, 234010, 187208, 140406, 93604, 46802, 0, -46802, -93604, -140406, - -187208, -234010, -280812, -327614, -374416, -421218, -468020, -514822, - -561624, -608426, -655228, -702030, -748832, -795634, -842436, -889238, - -936040, -982842, -1029644, -1076446, -1123248, -1170050, -1216852, - -1263654, -1310456, -1357258, -1404060, -1450862, -1497664, -1544466, - -1591268, -1638070, -1684872, -1731674, -1778476, -1825278, -1872080, - -1918882, -1965684, -2012486, -2059288, -2106090, -2152892, -2199694, - -2246496, -2293298, -2340100, -2386902, -2433704, -2480506, -2527308, - -2574110, -2620912, -2667714, -2714516, -2761318, -2808120, -2854922, - -2901724, -2948526, -2995328, -3042130, -3088932, -3135734, -3182536, - -3229338, -3276140, -3322942, -3369744, -3416546, -3463348, -3510150, - -3556952, -3603754, -3650556, -3697358, -3744160, -3790962, -3837764, - -3884566, -3931368, -3978170, -4024972, -4071774, -4118576, -4165378, - -4212180, -4258982, -4305784, -4352586, -4399388, -4446190, -4492992, - -4539794, -4586596, -4633398, -4680200, -4727002, -4773804, -4820606, - -4867408, -4914210, -4961012, -5007814, -5054616, -5101418, -5148220, - -5195022, -5241824, -5288626, -5335428, -5382230, -5429032, -5475834, - -5522636, -5569438, -5616240, -5663042, -5709844, -5756646, -5803448, - -5850250, -5897052, -5943854, - ]; - - static readonly CBG = [ - 2919680, 2897126, 2874572, 2852018, 2829464, 2806910, 2784356, 2761802, - 2739248, 2716694, 2694140, 2671586, 2649032, 2626478, 2603924, 2581370, - 2558816, 2536262, 2513708, 2491154, 2468600, 2446046, 2423492, 2400938, - 2378384, 2355830, 2333276, 2310722, 2288168, 2265614, 2243060, 2220506, - 2197952, 2175398, 2152844, 2130290, 2107736, 2085182, 2062628, 2040074, - 2017520, 1994966, 1972412, 1949858, 1927304, 1904750, 1882196, 1859642, - 1837088, 1814534, 1791980, 1769426, 1746872, 1724318, 1701764, 1679210, - 1656656, 1634102, 1611548, 1588994, 1566440, 1543886, 1521332, 1498778, - 1476224, 1453670, 1431116, 1408562, 1386008, 1363454, 1340900, 1318346, - 1295792, 1273238, 1250684, 1228130, 1205576, 1183022, 1160468, 1137914, - 1115360, 1092806, 1070252, 1047698, 1025144, 1002590, 980036, 957482, - 934928, 912374, 889820, 867266, 844712, 822158, 799604, 777050, 754496, - 731942, 709388, 686834, 664280, 641726, 619172, 596618, 574064, 551510, - 528956, 506402, 483848, 461294, 438740, 416186, 393632, 371078, 348524, - 325970, 303416, 280862, 258308, 235754, 213200, 190646, 168092, 145538, - 122984, 100430, 77876, 55322, 32768, 10214, -12340, -34894, -57448, -80002, - -102556, -125110, -147664, -170218, -192772, -215326, -237880, -260434, - -282988, -305542, -328096, -350650, -373204, -395758, -418312, -440866, - -463420, -485974, -508528, -531082, -553636, -576190, -598744, -621298, - -643852, -666406, -688960, -711514, -734068, -756622, -779176, -801730, - -824284, -846838, -869392, -891946, -914500, -937054, -959608, -982162, - -1004716, -1027270, -1049824, -1072378, -1094932, -1117486, -1140040, - -1162594, -1185148, -1207702, -1230256, -1252810, -1275364, -1297918, - -1320472, -1343026, -1365580, -1388134, -1410688, -1433242, -1455796, - -1478350, -1500904, -1523458, -1546012, -1568566, -1591120, -1613674, - -1636228, -1658782, -1681336, -1703890, -1726444, -1748998, -1771552, - -1794106, -1816660, -1839214, -1861768, -1884322, -1906876, -1929430, - -1951984, -1974538, -1997092, -2019646, -2042200, -2064754, -2087308, - -2109862, -2132416, -2154970, -2177524, -2200078, -2222632, -2245186, - -2267740, -2290294, -2312848, -2335402, -2357956, -2380510, -2403064, - -2425618, -2448172, -2470726, -2493280, -2515834, -2538388, -2560942, - -2583496, -2606050, -2628604, -2651158, -2673712, -2696266, -2718820, - -2741374, -2763928, -2786482, -2809036, -2831590, - ]; - - static readonly CBB = [ - -227, -225, -223, -222, -220, -218, -216, -214, -213, -211, -209, -207, - -206, -204, -202, -200, -198, -197, -195, -193, -191, -190, -188, -186, - -184, -183, -181, -179, -177, -175, -174, -172, -170, -168, -167, -165, - -163, -161, -159, -158, -156, -154, -152, -151, -149, -147, -145, -144, - -142, -140, -138, -136, -135, -133, -131, -129, -128, -126, -124, -122, - -120, -119, -117, -115, -113, -112, -110, -108, -106, -105, -103, -101, -99, - -97, -96, -94, -92, -90, -89, -87, -85, -83, -82, -80, -78, -76, -74, -73, - -71, -69, -67, -66, -64, -62, -60, -58, -57, -55, -53, -51, -50, -48, -46, - -44, -43, -41, -39, -37, -35, -34, -32, -30, -28, -27, -25, -23, -21, -19, - -18, -16, -14, -12, -11, -9, -7, -5, -4, -2, 0, 2, 4, 5, 7, 9, 11, 12, 14, - 16, 18, 19, 21, 23, 25, 27, 28, 30, 32, 34, 35, 37, 39, 41, 43, 44, 46, 48, - 50, 51, 53, 55, 57, 58, 60, 62, 64, 66, 67, 69, 71, 73, 74, 76, 78, 80, 82, - 83, 85, 87, 89, 90, 92, 94, 96, 97, 99, 101, 103, 105, 106, 108, 110, 112, - 113, 115, 117, 119, 120, 122, 124, 126, 128, 129, 131, 133, 135, 136, 138, - 140, 142, 144, 145, 147, 149, 151, 152, 154, 156, 158, 159, 161, 163, 165, - 167, 168, 170, 172, 174, 175, 177, 179, 181, 183, 184, 186, 188, 190, 191, - 193, 195, 197, 198, 200, 202, 204, 206, 207, 209, 211, 213, 214, 216, 218, - 220, 222, 223, 225, - ]; + // The basic DCT block is 8x8 samples + public static readonly dctSize = 8; + // DCTSIZE squared; # of elements in a block + public static readonly dctSize2 = 64; + // Quantization tables are 0..3 + public static readonly numQuantizationTables = 4; + // Huffman tables are numbered 0..3 + public static readonly numHuffmanTables = 4; + // Arith-coding tables are numbered 0..15 + public static readonly numArithTables = 16; + // JPEG limit on # of components in one scan + public static readonly maxCompsInScan = 4; + // JPEG limit on sampling factors + public static readonly maxSamplingFactor = 4; private _input!: InputBuffer; public get input(): InputBuffer { @@ -166,9 +79,9 @@ export class JpegData { return this._exifData; } - private readonly _quantizationTables = new Array( - Jpeg.NUM_QUANT_TBLS - ); + private readonly _quantizationTables = ArrayUtils.fill< + Int16Array | undefined + >(JpegData.numQuantizationTables, undefined); public get quantizationTables(): Array { return this._quantizationTables; } @@ -178,18 +91,26 @@ export class JpegData { return this._frames; } - private readonly _huffmanTablesAC = new Array<[] | undefined>(); - public get huffmanTablesAC(): Array<[] | undefined> { + private readonly _huffmanTablesAC: Array< + Array | undefined + > = []; + public get huffmanTablesAC(): Array< + Array | undefined + > { return this._huffmanTablesAC; } - private readonly _huffmanTablesDC = new Array<[] | undefined>(); - public get huffmanTablesDC(): Array<[] | undefined> { + private readonly _huffmanTablesDC: Array< + Array | undefined + > = []; + public get huffmanTablesDC(): Array< + Array | undefined + > { return this._huffmanTablesDC; } - private readonly _components = new Array(); - public get components(): Array { + private readonly _components = new Array(); + public get components(): Array { return this._components; } @@ -203,76 +124,76 @@ export class JpegData { private readMarkers(): void { let marker = this.nextMarker(); - if (marker !== Jpeg.M_SOI) { + if (marker !== JpegMarker.soi) { // SOI (Start of Image) - throw new ImageError('Start Of Image marker not found.'); + throw new LibError('Start Of Image marker not found.'); } marker = this.nextMarker(); - while (marker !== Jpeg.M_EOI && !this._input.isEOS) { + while (marker !== JpegMarker.eoi && !this._input.isEOS) { const block = this.readBlock(); switch (marker) { - case Jpeg.M_APP0: - case Jpeg.M_APP1: - case Jpeg.M_APP2: - case Jpeg.M_APP3: - case Jpeg.M_APP4: - case Jpeg.M_APP5: - case Jpeg.M_APP6: - case Jpeg.M_APP7: - case Jpeg.M_APP8: - case Jpeg.M_APP9: - case Jpeg.M_APP10: - case Jpeg.M_APP11: - case Jpeg.M_APP12: - case Jpeg.M_APP13: - case Jpeg.M_APP14: - case Jpeg.M_APP15: - case Jpeg.M_COM: + case JpegMarker.app0: + case JpegMarker.app1: + case JpegMarker.app2: + case JpegMarker.app3: + case JpegMarker.app4: + case JpegMarker.app5: + case JpegMarker.app6: + case JpegMarker.app7: + case JpegMarker.app8: + case JpegMarker.app9: + case JpegMarker.app10: + case JpegMarker.app11: + case JpegMarker.app12: + case JpegMarker.app13: + case JpegMarker.app14: + case JpegMarker.app15: + case JpegMarker.com: this.readAppData(marker, block); break; // DQT (Define Quantization Tables) - case Jpeg.M_DQT: + case JpegMarker.dqt: this.readDQT(block); break; // SOF0 (Start of Frame, Baseline DCT) - case Jpeg.M_SOF0: + case JpegMarker.sof0: // SOF1 (Start of Frame, Extended DCT) // falls through - case Jpeg.M_SOF1: + case JpegMarker.sof1: // SOF2 (Start of Frame, Progressive DCT) // falls through - case Jpeg.M_SOF2: + case JpegMarker.sof2: this.readFrame(marker, block); break; - case Jpeg.M_SOF3: - case Jpeg.M_SOF5: - case Jpeg.M_SOF6: - case Jpeg.M_SOF7: - case Jpeg.M_JPG: - case Jpeg.M_SOF9: - case Jpeg.M_SOF10: - case Jpeg.M_SOF11: - case Jpeg.M_SOF13: - case Jpeg.M_SOF14: - case Jpeg.M_SOF15: - throw new ImageError(`Unhandled frame type ${marker.toString(16)}`); + case JpegMarker.sof3: + case JpegMarker.sof5: + case JpegMarker.sof6: + case JpegMarker.sof7: + case JpegMarker.jpg: + case JpegMarker.sof9: + case JpegMarker.sof10: + case JpegMarker.sof11: + case JpegMarker.sof13: + case JpegMarker.sof14: + case JpegMarker.sof15: + throw new LibError(`Unhandled frame type ${marker.toString(16)}`); // DHT (Define Huffman Tables) - case Jpeg.M_DHT: + case JpegMarker.dht: this.readDHT(block); break; // DRI (Define Restart Interval) - case Jpeg.M_DRI: + case JpegMarker.dri: this.readDRI(block); break; // SOS (Start of Scan) - case Jpeg.M_SOS: + case JpegMarker.sos: this.readSOS(block); break; @@ -296,7 +217,7 @@ export class JpegData { } if (marker !== 0) { - throw new ImageError(`Unknown JPEG marker ${marker.toString(16)}`); + throw new LibError(`Unknown JPEG marker ${marker.toString(16)}`); } break; } @@ -308,7 +229,7 @@ export class JpegData { private skipBlock(): void { const length = this._input.readUint16(); if (length < 2) { - throw new ImageError('Invalid Block'); + throw new LibError('Invalid Block'); } this._input.skip(length - 2); } @@ -327,7 +248,7 @@ export class JpegData { } let marker = this.nextMarker(); - if (marker !== Jpeg.M_SOI) { + if (marker !== JpegMarker.soi) { return false; } @@ -335,12 +256,12 @@ export class JpegData { let hasSOS = false; marker = this.nextMarker(); - while (marker !== Jpeg.M_EOI && !this._input.isEOS) { + while (marker !== JpegMarker.eoi && !this._input.isEOS) { // EOI (End of image) const sectionByteSize = this._input.readUint16(); if (sectionByteSize < 2) { // Jpeg section consists of more than 2 bytes at least - // return success only when SOF and SOS have already found (as a jpeg without EOF.) + // return success only when SOF and SOS have already found (as a jpeg without EOF) break; } @@ -348,17 +269,17 @@ export class JpegData { switch (marker) { // SOF0 (Start of Frame, Baseline DCT) - case Jpeg.M_SOF0: + case JpegMarker.sof0: // SOF1 (Start of Frame, Extended DCT) // falls through - case Jpeg.M_SOF1: + case JpegMarker.sof1: // SOF2 (Start of Frame, Progressive DCT) // falls through - case Jpeg.M_SOF2: + case JpegMarker.sof2: hasSOF = true; break; // SOS (Start of Scan) - case Jpeg.M_SOS: + case JpegMarker.sos: hasSOS = true; break; default: @@ -377,7 +298,7 @@ export class JpegData { }); let marker = this.nextMarker(); - if (marker !== Jpeg.M_SOI) { + if (marker !== JpegMarker.soi) { return undefined; } @@ -387,22 +308,22 @@ export class JpegData { let hasSOS = false; marker = this.nextMarker(); - while (marker !== Jpeg.M_EOI && !this._input.isEOS) { + while (marker !== JpegMarker.eoi && !this._input.isEOS) { // EOI (End of image) switch (marker) { // SOF0 (Start of Frame, Baseline DCT) - case Jpeg.M_SOF0: + case JpegMarker.sof0: // SOF1 (Start of Frame, Extended DCT) // falls through - case Jpeg.M_SOF1: + case JpegMarker.sof1: // SOF2 (Start of Frame, Progressive DCT) // falls through - case Jpeg.M_SOF2: + case JpegMarker.sof2: hasSOF = true; this.readFrame(marker, this.readBlock()); break; // SOS (Start of Scan) - case Jpeg.M_SOS: + case JpegMarker.sos: hasSOS = true; this.skipBlock(); break; @@ -433,7 +354,7 @@ export class JpegData { this.readMarkers(); if (this._frames.length !== 1) { - throw new ImageError('Only single frame JPEGs supported'); + throw new LibError('Only single frame JPEGs supported'); } if (this._frame !== undefined) { @@ -443,7 +364,7 @@ export class JpegData { ); if (component !== undefined) { this.components.push( - new ComponentData( + new JpegComponentData( component.hSamples, this._frame.maxHSamples, component.vSamples, @@ -463,7 +384,7 @@ export class JpegData { private static buildHuffmanTable( codeLengths: Uint8Array, values: Uint8Array - ): Array { + ): Array { let k = 0; const code = new Array(); let length = 16; @@ -481,7 +402,7 @@ export class JpegData { if (p.children.length <= p.index) { p.children.length = p.index + 1; } - p.children[p.index] = values[k]; + p.children[p.index] = new HuffmanValue(values[k]); while (p.index > 0) { p = code.pop()!; } @@ -493,7 +414,7 @@ export class JpegData { if (p.children.length <= p.index) { p.children.length = p.index + 1; } - p.children[p.index] = q.children; + p.children[p.index] = new HuffmanParent(q.children); p = q; } k++; @@ -506,7 +427,7 @@ export class JpegData { if (p.children.length <= p.index) { p.children.length = p.index + 1; } - p.children[p.index] = q.children; + p.children[p.index] = new HuffmanParent(q.children); p = q; } } @@ -516,13 +437,16 @@ export class JpegData { private static buildComponentData( component: JpegComponent - ): Array { + ): Array { const blocksPerLine = component.blocksPerLine; const blocksPerColumn = component.blocksPerColumn; const samplesPerLine = blocksPerLine << 3; const R = new Int32Array(64); const r = new Uint8Array(64); - const lines = new Array(blocksPerColumn * 8); + const lines = ArrayUtils.fill( + blocksPerColumn * 8, + undefined + ); let l = 0; for (let blockRow = 0; blockRow < blocksPerColumn; blockRow++) { @@ -544,7 +468,7 @@ export class JpegData { for (let j = 0; j < 8; j++) { const line = lines[scanLine + j]; for (let i = 0; i < 8; i++) { - line[sample + i] = r[offset++]; + line![sample + i] = r[offset++]; } } } @@ -554,15 +478,15 @@ export class JpegData { } public static toFix(val: number): number { - const FIXED_POINT = 20; - const ONE = 1 << FIXED_POINT; - return Math.trunc(val * ONE) & 0xffffffff; + const fixedPoint = 20; + const one = 1 << fixedPoint; + return Math.trunc(val * one) & 0xffffffff; } private readBlock(): InputBuffer { const length = this._input.readUint16(); if (length < 2) { - throw new ImageError('Invalid Block'); + throw new LibError('Invalid Block'); } return this._input.readBytes(length - 2); } @@ -608,7 +532,7 @@ export class JpegData { private readAppData(marker: number, block: InputBuffer): void { const appData = block; - if (marker === Jpeg.M_APP0) { + if (marker === JpegMarker.app0) { // 'JFIF\0' if ( appData.getByte(0) === 0x4a && @@ -639,10 +563,10 @@ export class JpegData { thumbData ); } - } else if (marker === Jpeg.M_APP1) { + } else if (marker === JpegMarker.app1) { // 'EXIF\0' this.readExifData(appData); - } else if (marker === Jpeg.M_APP14) { + } else if (marker === JpegMarker.app14) { // 'Adobe\0' if ( appData.getByte(0) === 0x41 && @@ -658,7 +582,7 @@ export class JpegData { const transformCode = appData.getByte(11); this._adobe = new JpegAdobe(version, flags0, flags1, transformCode); } - } else if (marker === Jpeg.M_COM) { + } else if (marker === JpegMarker.com) { // Comment try { this._comment = appData.readStringUtf8(); @@ -675,8 +599,8 @@ export class JpegData { const prec = n >> 4; n &= 0x0f; - if (n >= Jpeg.NUM_QUANT_TBLS) { - throw new ImageError('Invalid number of quantization tables'); + if (n >= JpegData.numQuantizationTables) { + throw new LibError('Invalid number of quantization tables'); } if (this._quantizationTables[n] === undefined) { @@ -685,26 +609,26 @@ export class JpegData { const tableData = this._quantizationTables[n]; if (tableData !== undefined) { - for (let i = 0; i < Jpeg.DCTSIZE2; i++) { + for (let i = 0; i < JpegData.dctSize2; i++) { const tmp: number = prec !== 0 ? block.readUint16() : block.readByte(); - tableData[Jpeg.dctZigZag[i]] = tmp; + tableData[JpegData.dctZigZag[i]] = tmp; } } } if (!block.isEOS) { - throw new ImageError('Bad length for DQT block'); + throw new LibError('Bad length for DQT block'); } } private readFrame(marker: number, block: InputBuffer): void { if (this._frame !== undefined) { - throw new ImageError('Duplicate JPG frame data found.'); + throw new LibError('Duplicate JPG frame data found.'); } - const extended = marker === Jpeg.M_SOF1; - const progressive = marker === Jpeg.M_SOF2; + const extended = marker === JpegMarker.sof1; + const progressive = marker === JpegMarker.sof2; const precision = block.readByte(); const scanLines = block.readUint16(); const samplesPerLine = block.readUint16(); @@ -749,12 +673,9 @@ export class JpegData { count += bits[j]; } - const huffmanValues = new Uint8Array(count); - for (let j = 0; j < count; j++) { - huffmanValues[j] = block.readByte(); - } + const huffmanValues = block.readBytes(count).toUint8Array(); - let ht: Array = []; + let ht: Array | undefined> = []; if ((index & 0x10) !== 0) { // AC table definition index -= 0x10; @@ -778,8 +699,8 @@ export class JpegData { private readSOS(block: InputBuffer): void { const n = block.readByte(); - if (n < 1 || n > Jpeg.MAX_COMPS_IN_SCAN) { - throw new ImageError('Invalid SOS block'); + if (n < 1 || n > JpegData.maxCompsInScan) { + throw new LibError('Invalid SOS block'); } const components = new Array(); @@ -788,7 +709,7 @@ export class JpegData { const c = block.readByte(); if (!this._frame!.components.has(id)) { - throw new ImageError('Invalid Component in SOS block'); + throw new LibError('Invalid Component in SOS block'); } const component = this._frame!.components.get(id); if (component !== undefined) { @@ -808,8 +729,8 @@ export class JpegData { const spectralEnd = block.readByte(); const successiveApproximation = block.readByte(); - const Ah = (successiveApproximation >> 4) & 15; - const Al = successiveApproximation & 15; + const ah = (successiveApproximation >> 4) & 15; + const al = successiveApproximation & 15; const scan = new JpegScan( this._input, @@ -817,8 +738,8 @@ export class JpegData { components, spectralStart, spectralEnd, - Ah, - Al, + ah, + al, this._resetInterval ); scan.decode(); diff --git a/src/formats/jpeg/jpeg-frame.ts b/src/formats/jpeg/jpeg-frame.ts index 7d8b0e3..d54380d 100644 --- a/src/formats/jpeg/jpeg-frame.ts +++ b/src/formats/jpeg/jpeg-frame.ts @@ -1,5 +1,6 @@ /** @format */ +import { ArrayUtils } from '../../common/array-utils'; import { JpegComponent } from './jpeg-component'; export class JpegFrame { @@ -76,21 +77,6 @@ export class JpegFrame { this._samplesPerLine = samplesPerLine; } - private static getEmptyBlocks( - blocksPerLineForMcu: number, - blocksPerColumnForMcu: number - ) { - const blocks = new Array>(); - for (let ic = 0; ic < blocksPerColumnForMcu; ic++) { - const line = new Array(blocksPerLineForMcu); - for (let ir = 0; ir < blocksPerLineForMcu; ir++) { - line[ir] = new Int32Array(64); - } - blocks[ic] = line; - } - return blocks; - } - public prepare(): void { for (const [_, component] of this._components) { this._maxHSamples = Math.max(this._maxHSamples, component.hSamples); @@ -110,10 +96,16 @@ export class JpegFrame { ); const blocksPerLineForMcu = this._mcusPerLine * component.hSamples; const blocksPerColumnForMcu = this._mcusPerColumn * component.vSamples; - const blocks = JpegFrame.getEmptyBlocks( - blocksPerLineForMcu, - blocksPerColumnForMcu + + const blocks = ArrayUtils.generate( + blocksPerColumnForMcu, + (_) => + ArrayUtils.generate( + blocksPerLineForMcu, + (_) => new Int32Array(64) + ) ); + component.setBlocks(blocks, blocksPerLine, blocksPerColumn); } } diff --git a/src/formats/jpeg/jpeg-huffman.ts b/src/formats/jpeg/jpeg-huffman.ts index 7a2417b..00dbfbf 100644 --- a/src/formats/jpeg/jpeg-huffman.ts +++ b/src/formats/jpeg/jpeg-huffman.ts @@ -1,8 +1,10 @@ /** @format */ +import { HuffmanNode } from './huffman-node'; + export class JpegHuffman { - private readonly _children: Array = new Array(); - public get children(): Array { + private readonly _children: Array = []; + public get children(): Array { return this._children; } diff --git a/src/formats/jpeg/jpeg-info.ts b/src/formats/jpeg/jpeg-info.ts index c21de58..b2d8751 100644 --- a/src/formats/jpeg/jpeg-info.ts +++ b/src/formats/jpeg/jpeg-info.ts @@ -1,5 +1,6 @@ /** @format */ +import { Color } from '../../color/color'; import { DecodeInfo } from '../decode-info'; export class JpegInfo implements DecodeInfo { @@ -13,16 +14,16 @@ export class JpegInfo implements DecodeInfo { return this._height; } - private _backgroundColor = 0xffffffff; - public get backgroundColor(): number { - return this._backgroundColor; - } - private _numFrames = 1; public get numFrames(): number { return this._numFrames; } + private _backgroundColor: Color | undefined = undefined; + public get backgroundColor(): Color | undefined { + return this._backgroundColor; + } + public setSize(width: number, height: number) { this._width = width; this._height = height; diff --git a/src/formats/jpeg/jpeg-marker.ts b/src/formats/jpeg/jpeg-marker.ts new file mode 100644 index 0000000..b308d55 --- /dev/null +++ b/src/formats/jpeg/jpeg-marker.ts @@ -0,0 +1,83 @@ +/** @format */ + +export enum JpegMarker { + sof0 = 0xc0, + sof1 = 0xc1, + sof2 = 0xc2, + sof3 = 0xc3, + sof5 = 0xc5, + sof6 = 0xc6, + sof7 = 0xc7, + + jpg = 0xc8, + sof9 = 0xc9, + sof10 = 0xca, + sof11 = 0xcb, + + sof13 = 0xcd, + sof14 = 0xce, + sof15 = 0xcf, + + dht = 0xc4, + + dac = 0xcc, + + rst0 = 0xd0, + rst1 = 0xd1, + rst2 = 0xd2, + rst3 = 0xd3, + rst4 = 0xd4, + rst5 = 0xd5, + rst6 = 0xd6, + rst7 = 0xd7, + + soi = 0xd8, + eoi = 0xd9, + sos = 0xda, + dqt = 0xdb, + dnl = 0xdc, + dri = 0xdd, + dhp = 0xde, + exp = 0xdf, + + // JFIF, JFXX, CIFF, AVI1, Ocad + app0 = 0xe0, + // EXIF, ExtendedXMP, XMP, QVCI, FLIR + app1 = 0xe1, + // ICC_Profile, FPXR, MPF, PreviewImage + app2 = 0xe2, + // Meta, Stim, PreviewImage + app3 = 0xe3, + // Scalado, FPXR, PreviewImage + app4 = 0xe4, + // RMETA, PreviewImage + app5 = 0xe5, + // EPPIM, NITF, HP_TDHD, GoPro + app6 = 0xe6, + // Pentax, Qualcomm + app7 = 0xe7, + // SPIFF + app8 = 0xe8, + // MediaJukebox + app9 = 0xe9, + // Comment + app10 = 0xea, + // Jpeg-HDR + app11 = 0xeb, + // PictureInfo, Ducky + app12 = 0xec, + // Photoshop, Adobe_CM + app13 = 0xed, + // ADOBE + app14 = 0xee, + // GraphicConverter + app15 = 0xef, + + jpg0 = 0xf0, + jpg13 = 0xfd, + com = 0xfe, + + tem = 0x01, + + error = 0x100, +} diff --git a/src/formats/jpeg/jpeg-quantize.ts b/src/formats/jpeg/jpeg-quantize.ts index 52ca972..fb91654 100644 --- a/src/formats/jpeg/jpeg-quantize.ts +++ b/src/formats/jpeg/jpeg-quantize.ts @@ -1,31 +1,32 @@ /** @format */ -import { BitOperators } from '../../common/bit-operators'; -import { Color } from '../../common/color'; -import { MemoryImage } from '../../common/memory-image'; -import { RgbChannelSet } from '../../common/rgb-channel-set'; -import { ImageError } from '../../error/image-error'; +import { MathUtils } from '../../common/math-utils'; +import { LibError } from '../../error/lib-error'; import { ExifData } from '../../exif/exif-data'; -import { ComponentData } from './component-data'; +import { MemoryImage } from '../../image/image'; +import { JpegComponentData } from './jpeg-component-data'; import { JpegData } from './jpeg-data'; export abstract class JpegQuantize { - private static dctClip: Uint8Array | undefined; - - private static clamp8(i: number) { - if (i < 0) { - return 0; + private static readonly _dctClipOffset = 256; + private static readonly _dctClipLength = 768; + private static readonly _dctClip = JpegQuantize.createDctClip(); + + private static createDctClip(): Uint8Array { + const result = new Uint8Array(JpegQuantize._dctClipLength); + let i = 0; + for (i = -256; i < 0; ++i) { + result[JpegQuantize._dctClipOffset + i] = 0; + } + for (i = 0; i < 256; ++i) { + result[JpegQuantize._dctClipOffset + i] = i; } - if (i > 255) { - return 255; + for (i = 256; i < 512; ++i) { + result[JpegQuantize._dctClipOffset + i] = 255; } - return i; + return result; } - // These functions contain bit-shift operations that fail with HTML builds. - // A conditional import is used to use a modified version for HTML builds - // to work around this javascript bug, while keeping the native version fast. - // Quantize the coefficients and apply IDCT. // // A port of poppler's IDCT method which in turn is taken from: @@ -40,49 +41,33 @@ export abstract class JpegQuantize { ): void { const p = dataIn; - const dctClipOffset = 256; - const dctClipLength = 768; - if (JpegQuantize.dctClip === undefined) { - JpegQuantize.dctClip = new Uint8Array(dctClipLength); - for (let i = -256; i < 0; ++i) { - JpegQuantize.dctClip[dctClipOffset + i] = 0; - } - for (let i = 0; i < 256; ++i) { - JpegQuantize.dctClip[dctClipOffset + i] = i; - } - for (let i = 256; i < 512; ++i) { - JpegQuantize.dctClip[dctClipOffset + i] = 255; - } - } - // IDCT constants (20.12 fixed point format) - // cos(pi/16)*4096 - const COS_1 = 4017; + const cos1 = 4017; // sin(pi/16)*4096 - const SIN_1 = 799; + const sin1 = 799; // cos(3*pi/16)*4096 - const COS_3 = 3406; + const cos3 = 3406; // sin(3*pi/16)*4096 - const SIN_3 = 2276; + const sin3 = 2276; // cos(6*pi/16)*4096 - const COS_6 = 1567; + const cos6 = 1567; // sin(6*pi/16)*4096 - const SIN_6 = 3784; + const sin6 = 3784; // sqrt(2)*4096 - const SQRT_2 = 5793; - // sqrt(2)/2 - const SQRT_1D2 = 2896; + const sqrt2 = 5793; + // sqrt(2) / 2 + const sqrt102 = 2896; - // De-quantize + // de-quantize for (let i = 0; i < 64; i++) { p[i] = coefBlock[i] * quantizationTable[i]; } - // Inverse DCT on rows + // inverse DCT on rows let row = 0; for (let i = 0; i < 8; ++i, row += 8) { - // Check for all-zero AC coefficients + // check for all-zero AC coefficients if ( p[1 + row] === 0 && p[2 + row] === 0 && @@ -92,7 +77,7 @@ export abstract class JpegQuantize { p[6 + row] === 0 && p[7 + row] === 0 ) { - const t = BitOperators.shiftR(SQRT_2 * p[0 + row] + 512, 10); + const t = (sqrt2 * p[0 + row] + 512) >> 10; p[row + 0] = t; p[row + 1] = t; p[row + 2] = t; @@ -104,51 +89,45 @@ export abstract class JpegQuantize { continue; } - // Stage 4 - let v0 = BitOperators.shiftR(SQRT_2 * p[0 + row] + 128, 8); - let v1 = BitOperators.shiftR(SQRT_2 * p[4 + row] + 128, 8); + // stage 4 + let v0 = (sqrt2 * p[0 + row] + 128) >> 8; + let v1 = (sqrt2 * p[4 + row] + 128) >> 8; let v2 = p[2 + row]; let v3 = p[6 + row]; - let v4 = BitOperators.shiftR( - SQRT_1D2 * (p[1 + row] - p[7 + row]) + 128, - 8 - ); - let v7 = BitOperators.shiftR( - SQRT_1D2 * (p[1 + row] + p[7 + row]) + 128, - 8 - ); - let v5 = BitOperators.shiftL(p[3 + row], 4); - let v6 = BitOperators.shiftL(p[5 + row], 4); - - // Stage 3 - let t = BitOperators.shiftR(v0 - v1 + 1, 1); - v0 = BitOperators.shiftR(v0 + v1 + 1, 1); + let v4 = (sqrt102 * (p[1 + row] - p[7 + row]) + 128) >> 8; + let v7 = (sqrt102 * (p[1 + row] + p[7 + row]) + 128) >> 8; + let v5 = p[3 + row] << 4; + let v6 = p[5 + row] << 4; + + // stage 3 + let t = (v0 - v1 + 1) >> 1; + v0 = (v0 + v1 + 1) >> 1; v1 = t; - t = BitOperators.shiftR(v2 * SIN_6 + v3 * COS_6 + 128, 8); - v2 = BitOperators.shiftR(v2 * COS_6 - v3 * SIN_6 + 128, 8); + t = (v2 * sin6 + v3 * cos6 + 128) >> 8; + v2 = (v2 * cos6 - v3 * sin6 + 128) >> 8; v3 = t; - t = BitOperators.shiftR(v4 - v6 + 1, 1); - v4 = BitOperators.shiftR(v4 + v6 + 1, 1); + t = (v4 - v6 + 1) >> 1; + v4 = (v4 + v6 + 1) >> 1; v6 = t; - t = BitOperators.shiftR(v7 + v5 + 1, 1); - v5 = BitOperators.shiftR(v7 - v5 + 1, 1); + t = (v7 + v5 + 1) >> 1; + v5 = (v7 - v5 + 1) >> 1; v7 = t; - // Stage 2 - t = BitOperators.shiftR(v0 - v3 + 1, 1); - v0 = BitOperators.shiftR(v0 + v3 + 1, 1); + // stage 2 + t = (v0 - v3 + 1) >> 1; + v0 = (v0 + v3 + 1) >> 1; v3 = t; - t = BitOperators.shiftR(v1 - v2 + 1, 1); - v1 = BitOperators.shiftR(v1 + v2 + 1, 1); + t = (v1 - v2 + 1) >> 1; + v1 = (v1 + v2 + 1) >> 1; v2 = t; - t = BitOperators.shiftR(v4 * SIN_3 + v7 * COS_3 + 2048, 12); - v4 = BitOperators.shiftR(v4 * COS_3 - v7 * SIN_3 + 2048, 12); + t = (v4 * sin3 + v7 * cos3 + 2048) >> 12; + v4 = (v4 * cos3 - v7 * sin3 + 2048) >> 12; v7 = t; - t = BitOperators.shiftR(v5 * SIN_1 + v6 * COS_1 + 2048, 12); - v5 = BitOperators.shiftR(v5 * COS_1 - v6 * SIN_1 + 2048, 12); + t = (v5 * sin1 + v6 * cos1 + 2048) >> 12; + v5 = (v5 * cos1 - v6 * sin1 + 2048) >> 12; v6 = t; - // Stage 1 + // stage 1 p[0 + row] = v0 + v7; p[7 + row] = v0 - v7; p[1 + row] = v1 + v6; @@ -159,11 +138,11 @@ export abstract class JpegQuantize { p[4 + row] = v3 - v4; } - // Inverse DCT on columns + // inverse DCT on columns for (let i = 0; i < 8; ++i) { const col = i; - // Check for all-zero AC coefficients + // check for all-zero AC coefficients if ( p[1 * 8 + col] === 0 && p[2 * 8 + col] === 0 && @@ -173,7 +152,7 @@ export abstract class JpegQuantize { p[6 * 8 + col] === 0 && p[7 * 8 + col] === 0 ) { - const t = BitOperators.shiftR(SQRT_2 * dataIn[i] + 8192, 14); + const t = (sqrt2 * dataIn[i] + 8192) >> 14; p[0 * 8 + col] = t; p[1 * 8 + col] = t; p[2 * 8 + col] = t; @@ -185,51 +164,45 @@ export abstract class JpegQuantize { continue; } - // Stage 4 - let v0 = BitOperators.shiftR(SQRT_2 * p[0 * 8 + col] + 2048, 12); - let v1 = BitOperators.shiftR(SQRT_2 * p[4 * 8 + col] + 2048, 12); + // stage 4 + let v0 = (sqrt2 * p[0 * 8 + col] + 2048) >> 12; + let v1 = (sqrt2 * p[4 * 8 + col] + 2048) >> 12; let v2 = p[2 * 8 + col]; let v3 = p[6 * 8 + col]; - let v4 = BitOperators.shiftR( - SQRT_1D2 * (p[1 * 8 + col] - p[7 * 8 + col]) + 2048, - 12 - ); - let v7 = BitOperators.shiftR( - SQRT_1D2 * (p[1 * 8 + col] + p[7 * 8 + col]) + 2048, - 12 - ); + let v4 = (sqrt102 * (p[1 * 8 + col] - p[7 * 8 + col]) + 2048) >> 12; + let v7 = (sqrt102 * (p[1 * 8 + col] + p[7 * 8 + col]) + 2048) >> 12; let v5 = p[3 * 8 + col]; let v6 = p[5 * 8 + col]; - // Stage 3 - let t = BitOperators.shiftR(v0 - v1 + 1, 1); - v0 = BitOperators.shiftR(v0 + v1 + 1, 1); + // stage 3 + let t = (v0 - v1 + 1) >> 1; + v0 = (v0 + v1 + 1) >> 1; v1 = t; - t = BitOperators.shiftR(v2 * SIN_6 + v3 * COS_6 + 2048, 12); - v2 = BitOperators.shiftR(v2 * COS_6 - v3 * SIN_6 + 2048, 12); + t = (v2 * sin6 + v3 * cos6 + 2048) >> 12; + v2 = (v2 * cos6 - v3 * sin6 + 2048) >> 12; v3 = t; - t = BitOperators.shiftR(v4 - v6 + 1, 1); - v4 = BitOperators.shiftR(v4 + v6 + 1, 1); + t = (v4 - v6 + 1) >> 1; + v4 = (v4 + v6 + 1) >> 1; v6 = t; - t = BitOperators.shiftR(v7 + v5 + 1, 1); - v5 = BitOperators.shiftR(v7 - v5 + 1, 1); + t = (v7 + v5 + 1) >> 1; + v5 = (v7 - v5 + 1) >> 1; v7 = t; - // Stage 2 - t = BitOperators.shiftR(v0 - v3 + 1, 1); - v0 = BitOperators.shiftR(v0 + v3 + 1, 1); + // stage 2 + t = (v0 - v3 + 1) >> 1; + v0 = (v0 + v3 + 1) >> 1; v3 = t; - t = BitOperators.shiftR(v1 - v2 + 1, 1); - v1 = BitOperators.shiftR(v1 + v2 + 1, 1); + t = (v1 - v2 + 1) >> 1; + v1 = (v1 + v2 + 1) >> 1; v2 = t; - t = BitOperators.shiftR(v4 * SIN_3 + v7 * COS_3 + 2048, 12); - v4 = BitOperators.shiftR(v4 * COS_3 - v7 * SIN_3 + 2048, 12); + t = (v4 * sin3 + v7 * cos3 + 2048) >> 12; + v4 = (v4 * cos3 - v7 * sin3 + 2048) >> 12; v7 = t; - t = BitOperators.shiftR(v5 * SIN_1 + v6 * COS_1 + 2048, 12); - v5 = BitOperators.shiftR(v5 * COS_1 - v6 * SIN_1 + 2048, 12); + t = (v5 * sin1 + v6 * cos1 + 2048) >> 12; + v5 = (v5 * cos1 - v6 * sin1 + 2048) >> 12; v6 = t; - // Stage 1 + // stage 1 p[0 * 8 + col] = v0 + v7; p[7 * 8 + col] = v0 - v7; p[1 * 8 + col] = v1 + v6; @@ -240,11 +213,11 @@ export abstract class JpegQuantize { p[4 * 8 + col] = v3 - v4; } - // Convert to 8-bit integers + // convert to 8-bit integers for (let i = 0; i < 64; ++i) { dataOut[i] = - JpegQuantize.dctClip[ - dctClipOffset + 128 + BitOperators.shiftR(p[i] + 8, 4) + JpegQuantize._dctClip[ + JpegQuantize._dctClipOffset + 128 + ((p[i] + 8) >> 4) ]; } } @@ -253,266 +226,262 @@ export abstract class JpegQuantize { const orientation = jpeg.exifData.imageIfd.hasOrientation ? jpeg.exifData.imageIfd.orientation! : 0; + + const w = jpeg.width!; + const h = jpeg.height!; const flipWidthHeight = orientation >= 5 && orientation <= 8; - const width = flipWidthHeight ? jpeg.height : jpeg.width; - const height = flipWidthHeight ? jpeg.width : jpeg.height; + const width = flipWidthHeight ? h : w; + const height = flipWidthHeight ? w : h; const image = new MemoryImage({ width: width, height: height, - rgbChannelSet: RgbChannelSet.rgb, }); // Copy exif data, except for ORIENTATION which we're baking. image.exifData = ExifData.from(jpeg.exifData); image.exifData.imageIfd.orientation = undefined; - let component1: ComponentData | undefined = undefined; - let component2: ComponentData | undefined = undefined; - let component3: ComponentData | undefined = undefined; - let component4: ComponentData | undefined = undefined; + let component1: JpegComponentData | undefined = undefined; + let component2: JpegComponentData | undefined = undefined; + let component3: JpegComponentData | undefined = undefined; + let component4: JpegComponentData | undefined = undefined; let component1Line: Uint8Array | undefined = undefined; let component2Line: Uint8Array | undefined = undefined; let component3Line: Uint8Array | undefined = undefined; let component4Line: Uint8Array | undefined = undefined; - let offset = 0; - let Y = 0; - let Cb = 0; - let Cr = 0; - let K = 0; - let C = 0; - let M = 0; - let Ye = 0; - let R = 0; - let G = 0; - let B = 0; let colorTransform = false; - const h1 = jpeg.height - 1; - const w1 = jpeg.width - 1; + const h1 = h - 1; + const w1 = w - 1; switch (jpeg.components.length) { - case 1: { - const component1 = jpeg.components[0]; - const lines = component1.lines; - const hShift1 = component1.hScaleShift; - const vShift1 = component1.vScaleShift; - for (let y = 0; y < jpeg.height; y++) { - const y1 = y >> vShift1; - const component1Line = lines[y1]; - for (let x = 0; x < jpeg.width; x++) { - const x1 = x >> hShift1; - const Y = component1Line[x1]; - const c = Color.getColor(Y, Y, Y); - if (orientation === 2) { - image.setPixel(w1 - x, y, c); - } else if (orientation === 3) { - image.setPixel(w1 - x, h1 - y, c); - } else if (orientation === 4) { - image.setPixel(x, h1 - y, c); - } else if (orientation === 5) { - image.setPixel(y, x, c); - } else if (orientation === 6) { - image.setPixel(h1 - y, x, c); - } else if (orientation === 7) { - image.setPixel(h1 - y, w1 - x, c); - } else if (orientation === 8) { - image.setPixel(y, w1 - x, c); - } else { - image.setPixelByIndex(offset++, c); + case 1: + { + component1 = jpeg.components[0]; + const lines = component1.lines; + const hShift1 = component1.hScaleShift; + const vShift1 = component1.vScaleShift; + for (let y = 0; y < h; y++) { + const y1 = y >> vShift1; + component1Line = lines[y1]; + for (let x = 0; x < w; x++) { + const x1 = x >> hShift1; + const cy = component1Line![x1]; + + if (orientation === 2) { + image.setPixelRgb(w1 - x, y, cy, cy, cy); + } else if (orientation === 3) { + image.setPixelRgb(w1 - x, h1 - y, cy, cy, cy); + } else if (orientation === 4) { + image.setPixelRgb(x, h1 - y, cy, cy, cy); + } else if (orientation === 5) { + image.setPixelRgb(y, x, cy, cy, cy); + } else if (orientation === 6) { + image.setPixelRgb(h1 - y, x, cy, cy, cy); + } else if (orientation === 7) { + image.setPixelRgb(h1 - y, w1 - x, cy, cy, cy); + } else if (orientation === 8) { + image.setPixelRgb(y, w1 - x, cy, cy, cy); + } else { + image.setPixelRgb(x, y, cy, cy, cy); + } } } } break; - } - // case 2: - // { - // // PDF might compress two component data in custom color-space - // component1 = jpeg.components[0]; - // component2 = jpeg.components[1]; - // let hShift1: number = component1.hScaleShift; - // let vShift1: number = component1.vScaleShift; - // let hShift2: number = component2.hScaleShift; - // let vShift2: number = component2.vScaleShift; - - // for (let y = 0; y < height; y++) { - // let y1 = y >> vShift1; - // let y2 = y >> vShift2; - // component1Line = component1.lines[y1]; - // component2Line = component2.lines[y2]; - - // for (let x = 0; x < width; x++) { - // let x1 = x >> hShift1; - // let x2 = x >> hShift2; - - // Y = component1Line![x1]; - // // data[offset++] = Y; - - // Y = component2Line![x2]; - // // data[offset++] = Y; - // } - // } - // break; - // } - case 3: { - // The default transform for three components is true - colorTransform = true; - - component1 = jpeg.components[0]; - component2 = jpeg.components[1]; - component3 = jpeg.components[2]; - - const lines1 = component1.lines; - const lines2 = component2.lines; - const lines3 = component3.lines; - - const hShift1 = component1.hScaleShift; - const vShift1 = component1.vScaleShift; - const hShift2 = component2.hScaleShift; - const vShift2 = component2.vScaleShift; - const hShift3 = component3.hScaleShift; - const vShift3 = component3.vScaleShift; - - for (let y = 0; y < jpeg.height; y++) { - const y1 = y >> vShift1; - const y2 = y >> vShift2; - const y3 = y >> vShift3; - - component1Line = lines1[y1]; - component2Line = lines2[y2]; - component3Line = lines3[y3]; - - for (let x = 0; x < jpeg.width; x++) { - const x1 = x >> hShift1; - const x2 = x >> hShift2; - const x3 = x >> hShift3; - - Y = component1Line[x1] << 8; - Cb = component2Line[x2] - 128; - Cr = component3Line[x3] - 128; - - R = Y + 359 * Cr + 128; - G = Y - 88 * Cb - 183 * Cr + 128; - B = Y + 454 * Cb + 128; - - R = this.clamp8(BitOperators.shiftR(R, 8)); - G = this.clamp8(BitOperators.shiftR(G, 8)); - B = this.clamp8(BitOperators.shiftR(B, 8)); - const c = Color.getColor(R, G, B); - if (orientation === 2) { - image.setPixel(w1 - x, y, c); - } else if (orientation === 3) { - image.setPixel(w1 - x, h1 - y, c); - } else if (orientation === 4) { - image.setPixel(x, h1 - y, c); - } else if (orientation === 5) { - image.setPixel(y, x, c); - } else if (orientation === 6) { - image.setPixel(h1 - y, x, c); - } else if (orientation === 7) { - image.setPixel(h1 - y, w1 - x, c); - } else if (orientation === 8) { - image.setPixel(y, w1 - x, c); - } else { - image.setPixelByIndex(offset++, c); + case 2: + // { + // // PDF might compress two component data in custom color-space + // component1 = jpeg.components[0]; + // component2 = jpeg.components[1]; + // const hShift1 = component1.hScaleShift; + // const vShift1 = component1.vScaleShift; + // const hShift2 = component2.hScaleShift; + // const vShift2 = component2.vScaleShift; + + // for (let y = 0; y < h; ++y) { + // const y1 = y >> vShift1; + // const y2 = y >> vShift2; + // component1Line = component1.lines[y1]; + // component2Line = component2.lines[y2]; + + // for (let x = 0; x < w; ++x) { + // const x1 = x >> hShift1; + // const x2 = x >> hShift2; + + // let cy = component1Line![x1]; + // // data[offset++] = cy; + + // cy = component2Line![x2]; + // // data[offset++] = cy; + // } + // } + // } + break; + case 3: + { + // The default transform for three components is true + colorTransform = true; + + component1 = jpeg.components[0]; + component2 = jpeg.components[1]; + component3 = jpeg.components[2]; + + const lines1 = component1.lines; + const lines2 = component2.lines; + const lines3 = component3.lines; + + const hShift1 = component1.hScaleShift; + const vShift1 = component1.vScaleShift; + const hShift2 = component2.hScaleShift; + const vShift2 = component2.vScaleShift; + const hShift3 = component3.hScaleShift; + const vShift3 = component3.vScaleShift; + + for (let y = 0; y < h; y++) { + const y1 = y >> vShift1; + const y2 = y >> vShift2; + const y3 = y >> vShift3; + + component1Line = lines1[y1]; + component2Line = lines2[y2]; + component3Line = lines3[y3]; + + for (let x = 0; x < w; x++) { + const x1 = x >> hShift1; + const x2 = x >> hShift2; + const x3 = x >> hShift3; + + const cy = component1Line![x1] << 8; + const cb = component2Line![x2] - 128; + const cr = component3Line![x3] - 128; + + let r = cy + 359 * cr + 128; + let g = cy - 88 * cb - 183 * cr + 128; + let b = cy + 454 * cb + 128; + r = MathUtils.clampInt255(r >> 8); + g = MathUtils.clampInt255(g >> 8); + b = MathUtils.clampInt255(b >> 8); + + if (orientation === 2) { + image.setPixelRgb(w1 - x, y, r, g, b); + } else if (orientation === 3) { + image.setPixelRgb(w1 - x, h1 - y, r, g, b); + } else if (orientation === 4) { + image.setPixelRgb(x, h1 - y, r, g, b); + } else if (orientation === 5) { + image.setPixelRgb(y, x, r, g, b); + } else if (orientation === 6) { + image.setPixelRgb(h1 - y, x, r, g, b); + } else if (orientation === 7) { + image.setPixelRgb(h1 - y, w1 - x, r, g, b); + } else if (orientation === 8) { + image.setPixelRgb(y, w1 - x, r, g, b); + } else { + image.setPixelRgb(x, y, r, g, b); + } } } } break; - } - case 4: { - if (jpeg.adobe === undefined) { - throw new ImageError('Unsupported color mode (4 components)'); - } - // The default transform for four components is false - colorTransform = false; - // The adobe transform marker overrides any previous setting - if (jpeg.adobe.transformCode !== 0) { - colorTransform = true; - } + case 4: + { + if (jpeg.adobe === undefined) { + throw new LibError('Unsupported color mode (4 components)'); + } + // The default transform for four components is false + colorTransform = false; + // The adobe transform marker overrides any previous setting + if (jpeg.adobe!.transformCode !== 0) { + colorTransform = true; + } - component1 = jpeg.components[0]; - component2 = jpeg.components[1]; - component3 = jpeg.components[2]; - component4 = jpeg.components[3]; - - const lines1 = component1.lines; - const lines2 = component2.lines; - const lines3 = component3.lines; - const lines4 = component4.lines; - - const hShift1 = component1.hScaleShift; - const vShift1 = component1.vScaleShift; - const hShift2 = component2.hScaleShift; - const vShift2 = component2.vScaleShift; - const hShift3 = component3.hScaleShift; - const vShift3 = component3.vScaleShift; - const hShift4 = component4.hScaleShift; - const vShift4 = component4.vScaleShift; - - for (let y = 0; y < jpeg.height; y++) { - const y1 = y >> vShift1; - const y2 = y >> vShift2; - const y3 = y >> vShift3; - const y4 = y >> vShift4; - component1Line = lines1[y1]; - component2Line = lines2[y2]; - component3Line = lines3[y3]; - component4Line = lines4[y4]; - for (let x = 0; x < jpeg.width; x++) { - const x1 = x >> hShift1; - const x2 = x >> hShift2; - const x3 = x >> hShift3; - const x4 = x >> hShift4; - if (!colorTransform) { - C = component1Line[x1]; - M = component2Line[x2]; - Ye = component3Line[x3]; - K = component4Line[x4]; - } else { - Y = component1Line[x1]; - Cb = component2Line[x2]; - Cr = component3Line[x3]; - K = component4Line[x4]; - - C = 255 - this.clamp8(Math.trunc(Y + 1.402 * (Cr - 128))); - M = - 255 - - this.clamp8( - Math.trunc( - Y - 0.3441363 * (Cb - 128) - 0.71413636 * (Cr - 128) - ) - ); - Ye = 255 - this.clamp8(Math.trunc(Y + 1.772 * (Cb - 128))); - } - R = BitOperators.shiftR(C * K, 8); - G = BitOperators.shiftR(M * K, 8); - B = BitOperators.shiftR(Ye * K, 8); - const c = Color.getColor(R, G, B); - if (orientation === 2) { - image.setPixel(w1 - x, y, c); - } else if (orientation === 3) { - image.setPixel(w1 - x, h1 - y, c); - } else if (orientation === 4) { - image.setPixel(x, h1 - y, c); - } else if (orientation === 5) { - image.setPixel(y, x, c); - } else if (orientation === 6) { - image.setPixel(h1 - y, x, c); - } else if (orientation === 7) { - image.setPixel(h1 - y, w1 - x, c); - } else if (orientation === 8) { - image.setPixel(y, w1 - x, c); - } else { - image.setPixelByIndex(offset++, c); + component1 = jpeg.components[0]; + component2 = jpeg.components[1]; + component3 = jpeg.components[2]; + component4 = jpeg.components[3]; + + const lines1 = component1.lines; + const lines2 = component2.lines; + const lines3 = component3.lines; + const lines4 = component4.lines; + + const hShift1 = component1.hScaleShift; + const vShift1 = component1.vScaleShift; + const hShift2 = component2.hScaleShift; + const vShift2 = component2.vScaleShift; + const hShift3 = component3.hScaleShift; + const vShift3 = component3.vScaleShift; + const hShift4 = component4.hScaleShift; + const vShift4 = component4.vScaleShift; + + for (let y = 0; y < jpeg.height!; y++) { + const y1 = y >> vShift1; + const y2 = y >> vShift2; + const y3 = y >> vShift3; + const y4 = y >> vShift4; + component1Line = lines1[y1]; + component2Line = lines2[y2]; + component3Line = lines3[y3]; + component4Line = lines4[y4]; + for (let x = 0; x < jpeg.width!; x++) { + const x1 = x >> hShift1; + const x2 = x >> hShift2; + const x3 = x >> hShift3; + const x4 = x >> hShift4; + let cc = 0; + let cm = 0; + let cy = 0; + let ck = 0; + if (!colorTransform) { + cc = component1Line![x1]; + cm = component2Line![x2]; + cy = component3Line![x3]; + ck = component4Line![x4]; + } else { + cy = component1Line![x1]; + const cb = component2Line![x2]; + const cr = component3Line![x3]; + ck = component4Line![x4]; + + cc = 255 - MathUtils.clampInt255(cy + 1.402 * (cr - 128)); + cm = + 255 - + MathUtils.clampInt255( + cy - 0.3441363 * (cb - 128) - 0.71413636 * (cr - 128) + ); + cy = 255 - MathUtils.clampInt255(cy + 1.772 * (cb - 128)); + } + const r = (cc * ck) >> 8; + const g = (cm * ck) >> 8; + const b = (cy * ck) >> 8; + + if (orientation === 2) { + image.setPixelRgb(w1 - x, y, r, g, b); + } else if (orientation === 3) { + image.setPixelRgb(w1 - x, h1 - y, r, g, b); + } else if (orientation === 4) { + image.setPixelRgb(x, h1 - y, r, g, b); + } else if (orientation === 5) { + image.setPixelRgb(y, x, r, g, b); + } else if (orientation === 6) { + image.setPixelRgb(h1 - y, x, r, g, b); + } else if (orientation === 7) { + image.setPixelRgb(h1 - y, w1 - x, r, g, b); + } else if (orientation === 8) { + image.setPixelRgb(y, w1 - x, r, g, b); + } else { + image.setPixelRgb(x, y, r, g, b); + } } } } break; - } default: - throw new ImageError('Unsupported color mode'); + throw new LibError('Unsupported color mode'); } + return image; } } diff --git a/src/formats/jpeg/jpeg-scan.ts b/src/formats/jpeg/jpeg-scan.ts index 9a21dbd..1bceaa1 100644 --- a/src/formats/jpeg/jpeg-scan.ts +++ b/src/formats/jpeg/jpeg-scan.ts @@ -1,12 +1,19 @@ /** @format */ import { InputBuffer } from '../../common/input-buffer'; -import { ImageError } from '../../error/image-error'; -import { Jpeg } from './jpeg'; +import { LibError } from '../../error/lib-error'; +import { HuffmanNode } from './huffman-node'; +import { HuffmanParent } from './huffman-parent'; +import { HuffmanValue } from './huffman-value'; import { JpegComponent } from './jpeg-component'; +import { JpegData } from './jpeg-data'; import { JpegFrame } from './jpeg-frame'; +import { JpegMarker } from './jpeg-marker'; -type DecodeFunction = (component: JpegComponent, block: Int32Array) => void; +export type DecodeFunction = ( + component: JpegComponent, + block: Int32Array +) => void; export class JpegScan { private _input: InputBuffer; @@ -150,11 +157,8 @@ export class JpegScan { if (this._bitsData === 0xff) { const nextByte = this.input.readByte(); if (nextByte !== 0) { - throw new ImageError( - `unexpected marker: ${((this._bitsData << 8) | nextByte).toString( - 16 - )}` - ); + const marker = ((this._bitsData << 8) | nextByte).toString(16); + throw new LibError(`unexpected marker: ${marker}`); } } @@ -162,13 +166,17 @@ export class JpegScan { return (this._bitsData >> 7) & 1; } - private decodeHuffman(tree: []): number | undefined { - let node = tree; + private decodeHuffman( + tree: Array + ): number | undefined { + let node: HuffmanNode | undefined = new HuffmanParent(tree); let bit: number | undefined = undefined; while ((bit = this.readBit()) !== undefined) { - node = node[bit]; - if (typeof node === 'number') { - return Math.trunc(node); + if (node instanceof HuffmanParent) { + node = node.children[bit]; + } + if (node instanceof HuffmanValue) { + return node.value; } } return undefined; @@ -222,7 +230,7 @@ export class JpegScan { s = this.receiveAndExtend(s); - const z = Jpeg.dctZigZag[k]; + const z = JpegData.dctZigZag[k]; zz[z] = s; k++; } @@ -259,7 +267,7 @@ export class JpegScan { continue; } k += r; - const z = Jpeg.dctZigZag[k]; + const z = JpegData.dctZigZag[k]; zz[z] = this.receiveAndExtend(s) * (1 << this._successive); k++; } @@ -271,13 +279,13 @@ export class JpegScan { let s = 0; let r = 0; while (k <= e) { - const z = Jpeg.dctZigZag[k]; + const z = JpegData.dctZigZag[k]; switch (this._successiveACState) { case 0: { // Initial state const rs = this.decodeHuffman(component.huffmanTableAC); if (rs === undefined) { - throw new ImageError('Invalid progressive encoding'); + throw new LibError('Invalid progressive encoding'); } s = rs & 15; r = rs >> 4; @@ -291,7 +299,7 @@ export class JpegScan { } } else { if (s !== 1) { - throw new ImageError('invalid ACn encoding'); + throw new LibError('invalid ACn encoding'); } this._successiveACNextValue = this.receiveAndExtend(s); this._successiveACState = r !== 0 ? 2 : 3; @@ -440,7 +448,7 @@ export class JpegScan { const m1 = this._input.getByte(0); const m2 = this._input.getByte(1); if (m1 === 0xff) { - if (m2 >= Jpeg.M_RST0 && m2 <= Jpeg.M_RST7) { + if (m2 >= JpegMarker.rst0 && m2 <= JpegMarker.rst7) { this._input.skip(2); } else { break; diff --git a/src/formats/jpeg/jpeg-utils.ts b/src/formats/jpeg/jpeg-utils.ts new file mode 100644 index 0000000..ac06abe --- /dev/null +++ b/src/formats/jpeg/jpeg-utils.ts @@ -0,0 +1,204 @@ +/** @format */ + +import { InputBuffer } from '../../common/input-buffer'; +import { OutputBuffer } from '../../common/output-buffer'; +import { ExifData } from '../../exif/exif-data'; +import { JpegMarker } from './jpeg-marker'; + +export class JpegUtils { + // Exif\0\0 + private static readonly _exifSignature = 0x45786966; + + private readExifData(block: InputBuffer | undefined): ExifData | undefined { + if (block === undefined) { + return undefined; + } + + // Exif Header + const signature = block.readUint32(); + if (signature !== JpegUtils._exifSignature) { + return undefined; + } + if (block.readUint16() !== 0) { + return undefined; + } + + return ExifData.fromInputBuffer(block); + } + + private writeAPP1(out: OutputBuffer, exif: ExifData): void { + if (exif.isEmpty) { + return; + } + + const exifData = new OutputBuffer(); + exif.write(exifData); + const exifBytes = exifData.getBytes(); + + out.writeUint16(exifBytes.length + 8); + out.writeUint32(JpegUtils._exifSignature); + out.writeUint16(0); + out.writeBytes(exifBytes); + } + + private readBlock(input: InputBuffer): InputBuffer | undefined { + const length = input.readUint16(); + if (length < 2) { + return undefined; + } + return input.readBytes(length - 2); + } + + private skipBlock(input: InputBuffer, output?: OutputBuffer): boolean { + const length = input.readUint16(); + output?.writeUint16(length); + if (length < 2) { + return false; + } + if (output !== undefined) { + output.writeBuffer(input.readBytes(length - 2)); + } else { + input.skip(length - 2); + } + return true; + } + + private nextMarker(input: InputBuffer, output?: OutputBuffer): number { + let c = 0; + if (input.isEOS) { + return c; + } + + do { + do { + c = input.readByte(); + output?.writeByte(c); + } while (c !== 0xff && !input.isEOS); + + if (input.isEOS) { + return c; + } + + do { + c = input.readByte(); + output?.writeByte(c); + } while (c === 0xff && !input.isEOS); + } while (c === 0 && !input.isEOS); + + return c; + } + + public decodeExif(data: Uint8Array): ExifData | undefined { + const input = new InputBuffer({ + buffer: data, + bigEndian: true, + }); + + // Some other formats have embedded jpeg, or jpeg-like data. + // Only validate if the image starts with the StartOfImage tag. + const soiCheck = input.peekBytes(2); + if (soiCheck.getByte(0) !== 0xff || soiCheck.getByte(1) !== 0xd8) { + return undefined; + } + + let marker = this.nextMarker(input); + if (marker !== JpegMarker.soi) { + return undefined; + } + + let exif: ExifData | undefined = undefined; + marker = this.nextMarker(input); + while (marker !== JpegMarker.eoi && !input.isEOS) { + switch (marker) { + case JpegMarker.app1: + exif = this.readExifData(this.readBlock(input)); + if (exif !== undefined) { + return exif; + } + break; + default: + this.skipBlock(input); + break; + } + marker = this.nextMarker(input); + } + + return undefined; + } + + public injectExif(exif: ExifData, data: Uint8Array): Uint8Array | undefined { + const input = new InputBuffer({ + buffer: data, + bigEndian: true, + }); + + // Some other formats have embedded jpeg, or jpeg-like data. + // Only validate if the image starts with the StartOfImage tag. + const soiCheck = input.peekBytes(2); + if (soiCheck.getByte(0) !== 0xff || soiCheck.getByte(1) !== 0xd8) { + return undefined; + } + + const output = new OutputBuffer({ + size: data.length, + bigEndian: true, + }); + + let marker = this.nextMarker(input, output); + if (marker !== JpegMarker.soi) { + return undefined; + } + + // Check to see if the JPEG file has an EXIF block + let hasExifBlock = false; + const startOffset = input.offset; + marker = this.nextMarker(input); + while (!hasExifBlock && marker !== JpegMarker.eoi && !input.isEOS) { + if (marker === JpegMarker.app1) { + const block = this.readBlock(input); + const signature = block?.readUint32(); + if (signature === JpegUtils._exifSignature) { + hasExifBlock = true; + break; + } + } else { + this.skipBlock(input); + } + marker = this.nextMarker(input); + } + + input.offset = startOffset; + + // If the JPEG file does not have an EXIF block, add a new one. + if (!hasExifBlock) { + this.writeAPP1(output, exif); + // No need to parse the remaining individual blocks, just write out + // the remainder of the file. + output.writeBuffer(input.readBytes(input.length)); + return output.getBytes(); + } + + marker = this.nextMarker(input, output); + while (marker !== JpegMarker.eoi && !input.isEOS) { + if (marker === JpegMarker.app1) { + const saveOffset = input.offset; + // block length + input.skip(2); + const signature = input.readUint32(); + input.offset = saveOffset; + if (signature === JpegUtils._exifSignature) { + this.skipBlock(input); + this.writeAPP1(output, exif); + // No need to parse the remaining individual blocks, just write out + // the remainder of the file. + output.writeBuffer(input.readBytes(input.length)); + return output.getBytes(); + } + } + this.skipBlock(input, output); + marker = this.nextMarker(input, output); + } + + return output.getBytes(); + } +} diff --git a/src/formats/jpeg/jpeg.ts b/src/formats/jpeg/jpeg.ts deleted file mode 100644 index 500049d..0000000 --- a/src/formats/jpeg/jpeg.ts +++ /dev/null @@ -1,108 +0,0 @@ -/** @format */ - -export abstract class Jpeg { - public static readonly dctZigZag = [ - 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, - 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, - 54, 47, 55, 62, 63, - // Extra entries for safety in decoder - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - ]; - - // The basic DCT block is 8x8 samples - public static readonly DCTSIZE = 8; - // DCTSIZE squared; # of elements in a block - public static readonly DCTSIZE2 = 64; - // Quantization tables are numbered 0..3 - public static readonly NUM_QUANT_TBLS = 4; - // Huffman tables are numbered 0..3 - public static readonly NUM_HUFF_TBLS = 4; - // Arith-coding tables are numbered 0..15 - public static readonly NUM_ARITH_TBLS = 16; - // JPEG limit on # of components in one scan - public static readonly MAX_COMPS_IN_SCAN = 4; - // JPEG limit on sampling factors - public static readonly MAX_SAMP_FACTOR = 4; - - public static readonly M_SOF0 = 0xc0; - public static readonly M_SOF1 = 0xc1; - public static readonly M_SOF2 = 0xc2; - public static readonly M_SOF3 = 0xc3; - - public static readonly M_SOF5 = 0xc5; - public static readonly M_SOF6 = 0xc6; - public static readonly M_SOF7 = 0xc7; - - public static readonly M_JPG = 0xc8; - public static readonly M_SOF9 = 0xc9; - public static readonly M_SOF10 = 0xca; - public static readonly M_SOF11 = 0xcb; - - public static readonly M_SOF13 = 0xcd; - public static readonly M_SOF14 = 0xce; - public static readonly M_SOF15 = 0xcf; - - public static readonly M_DHT = 0xc4; - - public static readonly M_DAC = 0xcc; - - public static readonly M_RST0 = 0xd0; - public static readonly M_RST1 = 0xd1; - public static readonly M_RST2 = 0xd2; - public static readonly M_RST3 = 0xd3; - public static readonly M_RST4 = 0xd4; - public static readonly M_RST5 = 0xd5; - public static readonly M_RST6 = 0xd6; - public static readonly M_RST7 = 0xd7; - - public static readonly M_SOI = 0xd8; - public static readonly M_EOI = 0xd9; - public static readonly M_SOS = 0xda; - public static readonly M_DQT = 0xdb; - public static readonly M_DNL = 0xdc; - public static readonly M_DRI = 0xdd; - public static readonly M_DHP = 0xde; - public static readonly M_EXP = 0xdf; - - // JFIF, JFXX, CIFF, AVI1, Ocad - public static readonly M_APP0 = 0xe0; - // EXIF, ExtendedXMP, XMP, QVCI, FLIR - public static readonly M_APP1 = 0xe1; - // ICC_Profile, FPXR, MPF, PreviewImage - public static readonly M_APP2 = 0xe2; - // Meta, Stim, PreviewImage - public static readonly M_APP3 = 0xe3; - // Scalado, FPXR, PreviewImage - public static readonly M_APP4 = 0xe4; - // RMETA, PreviewImage - public static readonly M_APP5 = 0xe5; - // EPPIM, NITF, HP_TDHD, GoPro - public static readonly M_APP6 = 0xe6; - // Pentax, Qualcomm - public static readonly M_APP7 = 0xe7; - // SPIFF - public static readonly M_APP8 = 0xe8; - // MediaJukebox - public static readonly M_APP9 = 0xe9; - // Comment - public static readonly M_APP10 = 0xea; - // Jpeg-HDR - public static readonly M_APP11 = 0xeb; - // PictureInfo, Ducky - public static readonly M_APP12 = 0xec; - // Photoshop, Adobe_CM - public static readonly M_APP13 = 0xed; - // ADOBE - public static readonly M_APP14 = 0xee; - // GraphicConverter - public static readonly M_APP15 = 0xef; - - public static readonly M_JPG0 = 0xf0; - public static readonly M_JPG13 = 0xfd; - public static readonly M_COM = 0xfe; - - public static readonly M_TEM = 0x01; - - public static readonly M_ERROR = 0x100; -} diff --git a/src/formats/png-decoder.ts b/src/formats/png-decoder.ts index 30f32eb..68b360c 100644 --- a/src/formats/png-decoder.ts +++ b/src/formats/png-decoder.ts @@ -1,59 +1,44 @@ /** @format */ import { inflate } from 'uzip'; -import { Color } from '../common/color'; import { Crc32 } from '../common/crc32'; -import { FrameAnimation } from '../common/frame-animation'; -import { ICCPCompressionMode } from '../common/iccp-compression-mode'; -import { ICCProfileData } from '../common/icc-profile-data'; import { InputBuffer } from '../common/input-buffer'; import { ArrayUtils } from '../common/array-utils'; -import { MemoryImage } from '../common/memory-image'; -import { RgbChannelSet } from '../common/rgb-channel-set'; -import { TextCodec } from '../common/text-codec'; -import { ImageError } from '../error/image-error'; -import { NotImplementedError } from '../error/not-implemented-error'; -import { HdrImage } from '../hdr/hdr-image'; -import { ImageTransform } from '../transform/image-transform'; +import { StringUtils } from '../common/string-utils'; +import { LibError } from '../error/lib-error'; import { DecodeInfo } from './decode-info'; import { Decoder } from './decoder'; import { PngFrame } from './png/png-frame'; import { PngInfo } from './png/png-info'; +import { PngColorType } from './png/png-color-type'; +import { PngDisposeMode } from './png/png-dispose-mode'; +import { PngBlendMode } from './png/png-blend-mode'; +import { ColorRgba8 } from '../color/color-rgba8'; +import { ColorRgb8 } from '../color/color-rgb8'; +import { MemoryImage, MemoryImageCreateOptions } from '../image/image'; +import { PaletteUint8 } from '../image/palette-uint8'; +import { Format } from '../color/format'; +import { IccProfile } from '../image/icc-profile'; +import { IccProfileCompression } from '../image/icc-profile-compression'; +import { Draw } from '../draw/draw'; +import { BlendMode } from '../draw/blend-mode'; +import { PngFilterType } from './png/png-filter-type'; +import { Pixel } from '../image/pixel'; /** * Decode a PNG encoded image. */ export class PngDecoder implements Decoder { - private static readonly GRAYSCALE = 0; - - private static readonly RGB = 2; - - private static readonly INDEXED = 3; - - private static readonly GRAYSCALE_ALPHA = 4; - - private static readonly RGBA = 6; - - private static readonly FILTER_NONE = 0; - - private static readonly FILTER_SUB = 1; - - private static readonly FILTER_UP = 2; - - private static readonly FILTER_AVERAGE = 3; - - private static readonly FILTER_PAETH = 4; - - private _info?: PngInfo; - public get info(): PngInfo | undefined { - return this._info; - } - private _input?: InputBuffer; public get input(): InputBuffer | undefined { return this._input; } + private _info: PngInfo = new PngInfo(); + public get info(): PngInfo { + return this._info; + } + private _progressY = 0; public get progressY(): number { return this._progressY; @@ -73,42 +58,43 @@ export class PngDecoder implements Decoder { * The number of frames that can be decoded. */ public get numFrames(): number { - return this._info !== undefined ? this._info.numFrames : 0; + return this._info.numFrames; } private static unfilter( - filterType: number, + filterType: PngFilterType, bpp: number, row: Uint8Array, - prevRow: Uint8Array + prevRow?: Uint8Array ): void { const rowBytes = row.length; switch (filterType) { - case PngDecoder.FILTER_NONE: + case PngFilterType.none: break; - case PngDecoder.FILTER_SUB: + case PngFilterType.sub: for (let x = bpp; x < rowBytes; ++x) { row[x] = (row[x] + row[x - bpp]) & 0xff; } break; - case PngDecoder.FILTER_UP: + case PngFilterType.up: for (let x = 0; x < rowBytes; ++x) { - row[x] = (row[x] + prevRow[x]) & 0xff; + const b = prevRow !== undefined ? prevRow[x] : 0; + row[x] = (row[x] + b) & 0xff; } break; - case PngDecoder.FILTER_AVERAGE: + case PngFilterType.average: for (let x = 0; x < rowBytes; ++x) { const a = x < bpp ? 0 : row[x - bpp]; - const b = prevRow[x]; + const b = prevRow !== undefined ? prevRow[x] : 0; row[x] = (row[x] + ((a + b) >> 1)) & 0xff; } break; - case PngDecoder.FILTER_PAETH: + case PngFilterType.paeth: for (let x = 0; x < rowBytes; ++x) { const a = x < bpp ? 0 : row[x - bpp]; - const b = prevRow[x]; - const c = x < bpp ? 0 : prevRow[x - bpp]; + const b = prevRow !== undefined ? prevRow[x] : 0; + const c = x < bpp || prevRow === undefined ? 0 : prevRow[x - bpp]; const p = a + b - c; @@ -129,31 +115,15 @@ export class PngDecoder implements Decoder { } break; default: - throw new ImageError(`Invalid filter value: ${filterType}`); + throw new LibError(`Invalid filter value: ${filterType}`); } } - private static convert16to8(c: number): number { - return c >> 8; - } - - private static convert1to8(c: number): number { - return c === 0 ? 0 : 255; - } - - private static convert2to8(c: number): number { - return c * 85; - } - - private static convert4to8(c: number): number { - return c << 4; - } - /** * Return the CRC of the bytes */ private static crc(type: string, bytes: Uint8Array): number { - const typeCodeUnits = TextCodec.getCodePoints(type); + const typeCodeUnits = StringUtils.getCodePoints(type); const crc = Crc32.getChecksum({ buffer: typeCodeUnits, }); @@ -177,20 +147,19 @@ export class PngDecoder implements Decoder { passHeight: number ): void { let channels = 1; - if (this._info!.colorType === PngDecoder.GRAYSCALE_ALPHA) { + if (this._info.colorType === PngColorType.grayscaleAlpha) { channels = 2; - } else if (this._info!.colorType === PngDecoder.RGB) { + } else if (this._info.colorType === PngColorType.rgb) { channels = 3; - } else if (this._info!.colorType === PngDecoder.RGBA) { + } else if (this._info.colorType === PngColorType.rgba) { channels = 4; } - const pixelDepth = channels * this._info!.bits!; + const pixelDepth = channels * this._info.bits; const bpp = (pixelDepth + 7) >> 3; const rowBytes = (pixelDepth * passWidth + 7) >> 3; - const line = new Uint8Array(rowBytes); - const inData = [line, line]; + const inData: Array = [undefined, undefined]; const pixel = [0, 0, 0, 0]; @@ -200,10 +169,10 @@ export class PngDecoder implements Decoder { srcY < passHeight; ++srcY, dstY += yStep, ri = 1 - ri, this._progressY++ ) { - const filterType = input.readByte(); + const filterType = input.readByte() as PngFilterType; inData[ri] = input.readBytes(rowBytes).toUint8Array(); - const row = inData[ri]; + const row = inData[ri]!; const prevRow = inData[1 - ri]; // Before the image is compressed, it was filtered to improve compression. @@ -230,15 +199,12 @@ export class PngDecoder implements Decoder { ++srcX, dstX += xStep ) { this.readPixel(rowInput, pixel); - const c = this.getColor(pixel); - image.setPixel(dstX, dstY, c); + this.setPixel(image.getPixel(dstX, dstY), pixel); if (blockWidth > 1 || blockHeight > 1) { - // Let xMax: number = Math.min(dstX + blockWidth, _info.width); - // let xPixels: number = xMax - dstX; for (let i = 0; i < blockHeight; ++i) { for (let j = 0; j < blockWidth; ++j) { - image.setPixelSafe(dstX + j, dstY + j, c); + this.setPixel(image.getPixelSafe(dstX + j, dstY + i), pixel); } } } @@ -248,18 +214,18 @@ export class PngDecoder implements Decoder { private process(input: InputBuffer, image: MemoryImage): void { let channels = 1; - if (this._info!.colorType === PngDecoder.GRAYSCALE_ALPHA) { + if (this._info.colorType === PngColorType.grayscaleAlpha) { channels = 2; - } else if (this._info!.colorType === PngDecoder.RGB) { + } else if (this._info.colorType === PngColorType.rgb) { channels = 3; - } else if (this._info!.colorType === PngDecoder.RGBA) { + } else if (this._info.colorType === PngColorType.rgba) { channels = 4; } const pixelDepth = channels * this._info!.bits!; - const w = this._info!.width; - const h = this._info!.height; + const w = this._info.width; + const h = this._info.height; const rowBytes = (w * pixelDepth + 7) >> 3; const bpp = (pixelDepth + 7) >> 3; @@ -269,8 +235,10 @@ export class PngDecoder implements Decoder { const pixel = [0, 0, 0, 0]; - for (let y = 0, pi = 0, ri = 0; y < h; ++y, ri = 1 - ri) { - const filterType = input.readByte(); + const pIter = image[Symbol.iterator](); + let pIterRes = pIter.next(); + for (let y = 0, ri = 0; y < h; ++y, ri = 1 - ri) { + const filterType = input.readByte() as PngFilterType; inData[ri] = input.readBytes(rowBytes).toUint8Array(); const row = inData[ri]; @@ -291,7 +259,8 @@ export class PngDecoder implements Decoder { for (let x = 0; x < w; ++x) { this.readPixel(rowInput, pixel); - image.setPixelByIndex(pi++, this.getColor(pixel)); + this.setPixel(pIterRes.value, pixel); + pIterRes = pIter.next(); } } } @@ -320,7 +289,7 @@ export class PngDecoder implements Decoder { // Not enough buffer while (this._bitBufferLen < numBits) { if (input.isEOS) { - throw new ImageError('Invalid PNG data.'); + throw new LibError('Invalid PNG data.'); } // Input byte @@ -365,235 +334,91 @@ export class PngDecoder implements Decoder { * Read the next pixel from the input stream. */ private readPixel(input: InputBuffer, pixel: number[]): void { - switch (this._info!.colorType) { - case PngDecoder.GRAYSCALE: - pixel[0] = this.readBits(input, this._info!.bits!); + switch (this._info.colorType) { + case PngColorType.grayscale: + pixel[0] = this.readBits(input, this._info.bits!); return; - case PngDecoder.RGB: - pixel[0] = this.readBits(input, this._info!.bits!); - pixel[1] = this.readBits(input, this._info!.bits!); - pixel[2] = this.readBits(input, this._info!.bits!); + case PngColorType.rgb: + pixel[0] = this.readBits(input, this._info.bits!); + pixel[1] = this.readBits(input, this._info.bits!); + pixel[2] = this.readBits(input, this._info.bits!); return; - case PngDecoder.INDEXED: - pixel[0] = this.readBits(input, this._info!.bits!); + case PngColorType.indexed: + pixel[0] = this.readBits(input, this._info.bits!); return; - case PngDecoder.GRAYSCALE_ALPHA: - pixel[0] = this.readBits(input, this._info!.bits!); - pixel[1] = this.readBits(input, this._info!.bits!); + case PngColorType.grayscaleAlpha: + pixel[0] = this.readBits(input, this._info.bits!); + pixel[1] = this.readBits(input, this._info.bits!); return; - case PngDecoder.RGBA: - pixel[0] = this.readBits(input, this._info!.bits!); - pixel[1] = this.readBits(input, this._info!.bits!); - pixel[2] = this.readBits(input, this._info!.bits!); - pixel[3] = this.readBits(input, this._info!.bits!); + case PngColorType.rgba: + pixel[0] = this.readBits(input, this._info.bits!); + pixel[1] = this.readBits(input, this._info.bits!); + pixel[2] = this.readBits(input, this._info.bits!); + pixel[3] = this.readBits(input, this._info.bits!); return; } - throw new NotImplementedError( - `Invalid color type: ${this._info!.colorType}.` - ); + throw new LibError(`Invalid color type: ${this._info.colorType}.`); } - /** - * Get the color with the list of components. - */ - private getColor(raw: number[]): number { - switch (this._info!.colorType) { - case PngDecoder.GRAYSCALE: { - let g = 0; - switch (this._info!.bits) { - case 1: - g = PngDecoder.convert1to8(raw[0]); - break; - case 2: - g = PngDecoder.convert2to8(raw[0]); - break; - case 4: - g = PngDecoder.convert4to8(raw[0]); - break; - case 8: - g = raw[0]; - break; - case 16: - g = PngDecoder.convert16to8(raw[0]); - break; - } - - g = this._info!.colorLut![g]; - - if (this._info!.transparency !== undefined) { - const a = - ((this._info!.transparency[0] & 0xff) << 24) | - (this._info!.transparency[1] & 0xff); - if (raw[0] === a) { - return Color.getColor(g, g, g, 0); - } + // Get the color with the list of components. + private setPixel(p: Pixel, raw: number[]): void { + switch (this._info.colorType) { + case PngColorType.grayscale: + if (this._info.transparency !== undefined && this._info.bits > 8) { + const t = this._info.transparency!; + const a = ((t[0] & 0xff) << 24) | (t[1] & 0xff); + const g = raw[0]; + p.setRgba(g, g, g, g !== a ? p.maxChannelValue : 0); + return; } - - return Color.getColor(g, g, g); - } - case PngDecoder.RGB: { - let r = 0; - let g = 0; - let b = 0; - switch (this._info!.bits) { - case 1: - r = PngDecoder.convert1to8(raw[0]); - g = PngDecoder.convert1to8(raw[1]); - b = PngDecoder.convert1to8(raw[2]); - break; - case 2: - r = PngDecoder.convert2to8(raw[0]); - g = PngDecoder.convert2to8(raw[1]); - b = PngDecoder.convert2to8(raw[2]); - break; - case 4: - r = PngDecoder.convert4to8(raw[0]); - g = PngDecoder.convert4to8(raw[1]); - b = PngDecoder.convert4to8(raw[2]); - break; - case 8: - r = raw[0]; - g = raw[1]; - b = raw[2]; - break; - case 16: - r = PngDecoder.convert16to8(raw[0]); - g = PngDecoder.convert16to8(raw[1]); - b = PngDecoder.convert16to8(raw[2]); - break; - } - - r = this._info!.colorLut![r]!; - g = this._info!.colorLut![g]!; - b = this._info!.colorLut![b]!; - - if (this._info!.transparency !== undefined) { - const tr = - ((this._info!.transparency[0] & 0xff) << 8) | - (this._info!.transparency[1] & 0xff); - const tg = - ((this._info!.transparency[2] & 0xff) << 8) | - (this._info!.transparency[3] & 0xff); - const tb = - ((this._info!.transparency[4] & 0xff) << 8) | - (this._info!.transparency[5] & 0xff); - if (raw[0] === tr && raw[1] === tg && raw[2] === tb) { - return Color.getColor(r, g, b, 0); + p.setRgb(raw[0], 0, 0); + return; + case PngColorType.rgb: + { + const r = raw[0]; + const g = raw[1]; + const b = raw[2]; + + if (this._info.transparency !== undefined) { + const t = this._info.transparency!; + const tr = ((t[0] & 0xff) << 8) | (t[1] & 0xff); + const tg = ((t[2] & 0xff) << 8) | (t[3] & 0xff); + const tb = ((t[4] & 0xff) << 8) | (t[5] & 0xff); + if (raw[0] !== tr || raw[1] !== tg || raw[2] !== tb) { + p.setRgba(r, g, b, p.maxChannelValue); + return; + } } - } - return Color.getColor(r, g, b); - } - case PngDecoder.INDEXED: { - const p = raw[0] * 3; - - const a = - this._info!.transparency !== undefined && - raw[0] < this._info!.transparency.length - ? this._info!.transparency[raw[0]] - : 255; - - if (p >= this._info!.palette!.length) { - return Color.getColor(255, 255, 255, a); - } - - const r = this._info!.palette![p]!; - const g = this._info!.palette![p + 1]!; - const b = this._info!.palette![p + 2]!; - - return Color.getColor(r, g, b, a); - } - case PngDecoder.GRAYSCALE_ALPHA: { - let g = 0; - let a = 0; - switch (this._info!.bits) { - case 1: - g = PngDecoder.convert1to8(raw[0]); - a = PngDecoder.convert1to8(raw[1]); - break; - case 2: - g = PngDecoder.convert2to8(raw[0]); - a = PngDecoder.convert2to8(raw[1]); - break; - case 4: - g = PngDecoder.convert4to8(raw[0]); - a = PngDecoder.convert4to8(raw[1]); - break; - case 8: - g = raw[0]; - a = raw[1]; - break; - case 16: - g = PngDecoder.convert16to8(raw[0]); - a = PngDecoder.convert16to8(raw[1]); - break; + p.setRgb(r, g, b); } - - g = this._info!.colorLut![g]!; - - return Color.getColor(g, g, g, a); - } - case PngDecoder.RGBA: { - let r = 0; - let g = 0; - let b = 0; - let a = 0; - switch (this._info!.bits) { - case 1: - r = PngDecoder.convert1to8(raw[0]); - g = PngDecoder.convert1to8(raw[1]); - b = PngDecoder.convert1to8(raw[2]); - a = PngDecoder.convert1to8(raw[3]); - break; - case 2: - r = PngDecoder.convert2to8(raw[0]); - g = PngDecoder.convert2to8(raw[1]); - b = PngDecoder.convert2to8(raw[2]); - a = PngDecoder.convert2to8(raw[3]); - break; - case 4: - r = PngDecoder.convert4to8(raw[0]); - g = PngDecoder.convert4to8(raw[1]); - b = PngDecoder.convert4to8(raw[2]); - a = PngDecoder.convert4to8(raw[3]); - break; - case 8: - r = raw[0]; - g = raw[1]; - b = raw[2]; - a = raw[3]; - break; - case 16: - r = PngDecoder.convert16to8(raw[0]); - g = PngDecoder.convert16to8(raw[1]); - b = PngDecoder.convert16to8(raw[2]); - a = PngDecoder.convert16to8(raw[3]); - break; - } - - r = this._info!.colorLut![r]!; - g = this._info!.colorLut![g]!; - b = this._info!.colorLut![b]!; - - return Color.getColor(r, g, b, a); - } + return; + case PngColorType.indexed: + p.index = raw[0]; + return; + case PngColorType.grayscaleAlpha: + p.setRgb(raw[0], raw[1], 0); + return; + case PngColorType.rgba: + p.setRgba(raw[0], raw[1], raw[2], raw[3]); + return; } - throw new ImageError(`Invalid color type: ${this._info!.colorType}.`); + throw new LibError(`Invalid color type: ${this._info.colorType}.`); } /** * Is the given file a valid PNG image? */ public isValidFile(bytes: Uint8Array): boolean { - const input = new InputBuffer({ + this._input = new InputBuffer({ buffer: bytes, bigEndian: true, }); - const pngHeader = input.readBytes(8); - const PNG_HEADER = [137, 80, 78, 71, 13, 10, 26, 10]; + const headerBytes = this._input.readBytes(8); + const expectedHeaderBytes = [137, 80, 78, 71, 13, 10, 26, 10]; for (let i = 0; i < 8; ++i) { - if (pngHeader.getByte(i) !== PNG_HEADER[i]) { + if (headerBytes.getByte(i) !== expectedHeaderBytes[i]) { return false; } } @@ -605,16 +430,8 @@ export class PngDecoder implements Decoder { * process the frames until they are requested with decodeFrame. */ public startDecode(bytes: Uint8Array): DecodeInfo | undefined { - this._input = new InputBuffer({ - buffer: bytes, - bigEndian: true, - }); - const pngHeader = this._input.readBytes(8); - const expectedHeader = [137, 80, 78, 71, 13, 10, 26, 10]; - for (let i = 0; i < 8; ++i) { - if (pngHeader.getByte(i) !== expectedHeader[i]) { - return undefined; - } + if (!this.isValidFile(bytes) || this._input === undefined) { + return undefined; } while (true) { @@ -622,122 +439,99 @@ export class PngDecoder implements Decoder { let chunkSize = this._input.readUint32(); const chunkType = this._input.readString(4); switch (chunkType) { - case 'tEXt': { - if (this._info === undefined) { - this._info = new PngInfo(); - } - const txtData = this._input.readBytes(chunkSize).toUint8Array(); - for (let i = 0, l = txtData.length; i < l; ++i) { - if (txtData[i] === 0) { - const key = TextCodec.latin1Decoder.decode( - ArrayUtils.copyUint8(txtData, 0, i) - ); - const text = TextCodec.latin1Decoder.decode( - ArrayUtils.copyUint8(txtData, i + 1) - ); - this._info.textData.set(key, text); - break; + case 'tEXt': + { + const txtData = this._input.readBytes(chunkSize).toUint8Array(); + const l = txtData.length; + for (let i = 0; i < l; ++i) { + if (txtData[i] === 0) { + const key = StringUtils.latin1Decoder.decode( + ArrayUtils.copyUint8(txtData, 0, i) + ); + const text = StringUtils.latin1Decoder.decode( + ArrayUtils.copyUint8(txtData, i + 1) + ); + this._info.textData.set(key, text); + break; + } } + // CRC + this._input.skip(4); } - // CRC - this._input.skip(4); break; - } case 'IHDR': { const hdr = InputBuffer.from(this._input.readBytes(chunkSize)); const hdrBytes: Uint8Array = hdr.toUint8Array(); - - const width = hdr.readUint32(); - const height = hdr.readUint32(); - const bits = hdr.readByte(); - const colorType = hdr.readByte(); - const compressionMethod = hdr.readByte(); - const filterMethod = hdr.readByte(); - const interlaceMethod = hdr.readByte(); - - this._info = new PngInfo({ - width: width, - height: height, - bits: bits, - colorType: colorType, - compressionMethod: compressionMethod, - filterMethod: filterMethod, - interlaceMethod: interlaceMethod, - }); - - // Validate some of the info in the header to make sure we support - // the proposed image data. - if ( - ![ - PngDecoder.GRAYSCALE, - PngDecoder.RGB, - PngDecoder.INDEXED, - PngDecoder.GRAYSCALE_ALPHA, - PngDecoder.RGBA, - ].includes(this._info.colorType!) - ) { - return undefined; - } + this._info.width = hdr.readUint32(); + this._info.height = hdr.readUint32(); + this._info.bits = hdr.readByte(); + this._info.colorType = hdr.readByte(); + this._info.compressionMethod = hdr.readByte(); + this._info.filterMethod = hdr.readByte(); + this._info.interlaceMethod = hdr.readByte(); if (this._info.filterMethod !== 0) { return undefined; } switch (this._info.colorType) { - case PngDecoder.GRAYSCALE: + case PngColorType.grayscale: if (![1, 2, 4, 8, 16].includes(this._info.bits!)) { return undefined; } break; - case PngDecoder.RGB: + case PngColorType.rgb: if (![8, 16].includes(this._info.bits!)) { return undefined; } break; - case PngDecoder.INDEXED: + case PngColorType.indexed: if (![1, 2, 4, 8].includes(this._info.bits!)) { return undefined; } break; - case PngDecoder.GRAYSCALE_ALPHA: + case PngColorType.grayscaleAlpha: if (![8, 16].includes(this._info.bits!)) { return undefined; } break; - case PngDecoder.RGBA: + case PngColorType.rgba: if (![8, 16].includes(this._info.bits!)) { return undefined; } break; + default: + // The proposed image data is not supported. + return undefined; } const crc = this._input.readUint32(); const computedCrc = PngDecoder.crc(chunkType, hdrBytes); if (crc !== computedCrc) { - throw new ImageError(`Invalid ${chunkType} checksum`); + throw new LibError(`Invalid ${chunkType} checksum`); } break; } case 'PLTE': { - this._info!.palette = this._input.readBytes(chunkSize).toUint8Array(); + this._info.palette = this._input.readBytes(chunkSize).toUint8Array(); const crc = this._input.readUint32(); - const computedCrc = PngDecoder.crc(chunkType, this._info!.palette); + const computedCrc = PngDecoder.crc(chunkType, this._info.palette); if (crc !== computedCrc) { - throw new ImageError(`Invalid ${chunkType} checksum`); + throw new LibError(`Invalid ${chunkType} checksum`); } break; } case 'tRNS': { - this._info!.transparency = this._input + this._info.transparency = this._input .readBytes(chunkSize) .toUint8Array(); const crc = this._input.readUint32(); const computedCrc = PngDecoder.crc( chunkType, - this._info!.transparency + this._info.transparency ); if (crc !== computedCrc) { - throw new ImageError(`Invalid ${chunkType} checksum`); + throw new LibError(`Invalid ${chunkType} checksum`); } break; } @@ -749,20 +543,20 @@ export class PngDecoder implements Decoder { } case 'gAMA': { if (chunkSize !== 4) { - throw new ImageError('Invalid gAMA chunk'); + throw new LibError('Invalid gAMA chunk'); } const gammaInt = this._input.readUint32(); // CRC this._input.skip(4); - // A gamma of 1.0 doesn't have any affect, so pretend we didn't get + // A gamma of 1 doesn't have any affect, so pretend we didn't get // a gamma in that case. if (gammaInt !== 100000) { - this._info!.gamma = gammaInt / 100000.0; + this._info.gamma = gammaInt / 100000.0; } break; } case 'IDAT': { - this._info!.idat.push(inputPos); + this._info.idat.push(inputPos); this._input.skip(chunkSize); // CRC this._input.skip(4); @@ -770,8 +564,8 @@ export class PngDecoder implements Decoder { } case 'acTL': { // Animation control chunk - this._info!.numFrames = this._input.readUint32(); - this._info!.repeat = this._input.readUint32(); + this._info.numFrames = this._input.readUint32(); + this._info.repeat = this._input.readUint32(); // CRC this._input.skip(4); break; @@ -785,8 +579,8 @@ export class PngDecoder implements Decoder { const yOffset = this._input.readUint32(); const delayNum = this._input.readUint16(); const delayDen = this._input.readUint16(); - const dispose = this._input.readByte(); - const blend = this._input.readByte(); + const dispose = this._input.readByte() as PngDisposeMode; + const blend = this._input.readByte() as PngBlendMode; // CRC this._input.skip(4); @@ -801,12 +595,12 @@ export class PngDecoder implements Decoder { dispose: dispose, blend: blend, }); - this._info!.frames.push(frame); + this._info.frames.push(frame); break; } case 'fdAT': { const sequenceNumber = this._input.readUint32(); - const frame = this._info!.frames[this._info!.frames.length - 1]; + const frame = this._info.frames[this._info.frames.length - 1]; frame.fdat.push(inputPos); this._input.skip(chunkSize - 4); // CRC @@ -814,24 +608,35 @@ export class PngDecoder implements Decoder { break; } case 'bKGD': { - if (this._info!.colorType === 3) { + if (this._info.colorType === PngColorType.indexed) { const paletteIndex = this._input.readByte(); chunkSize--; const p3 = paletteIndex * 3; - const r = this._info!.palette![p3]!; - const g = this._info!.palette![p3 + 1]!; - const b = this._info!.palette![p3 + 2]!; - this._info!.backgroundColor = Color.fromRgb(r, g, b); + const r = this._info.palette![p3]!; + const g = this._info.palette![p3 + 1]!; + const b = this._info.palette![p3 + 2]!; + if (this._info.transparency !== undefined) { + const isTransparent = + this._info.transparency.includes(paletteIndex); + this._info.backgroundColor = new ColorRgba8( + r, + g, + b, + isTransparent ? 0 : 255 + ); + } else { + this._info.backgroundColor = new ColorRgb8(r, g, b); + } } else if ( - this._info!.colorType === 0 || - this._info!.colorType === 4 + this._info.colorType === PngColorType.grayscale || + this._info.colorType === PngColorType.grayscaleAlpha ) { /* Const gray: number = */ this._input.readUint16(); chunkSize -= 2; } else if ( - this._info!.colorType === 2 || - this._info!.colorType === 6 + this._info.colorType === PngColorType.rgb || + this._info.colorType === PngColorType.rgba ) { /* Const r: number = */ this._input.readUint16(); @@ -849,12 +654,12 @@ export class PngDecoder implements Decoder { break; } case 'iCCP': { - this._info!.iCCPName = this._input.readString(); + this._info.iccpName = this._input.readString(); // 0: deflate - this._info!.iCCPCompression = this._input.readByte(); - chunkSize -= this._info!.iCCPName.length + 2; + this._info.iccpCompression = this._input.readByte(); + chunkSize -= this._info.iccpName.length + 2; const profile = this._input.readBytes(chunkSize); - this._info!.iCCPData = profile.toUint8Array(); + this._info.iccpData = profile.toUint8Array(); // CRC this._input.skip(4); break; @@ -883,7 +688,7 @@ export class PngDecoder implements Decoder { * Decode the frame (assuming **startDecode** has already been called). */ public decodeFrame(frame: number): MemoryImage | undefined { - if (this._input === undefined || this._info === undefined) { + if (this._input === undefined) { return undefined; } @@ -893,8 +698,9 @@ export class PngDecoder implements Decoder { if (!this._info.isAnimated || frame === 0) { let totalSize = 0; + const len = this._info.idat.length; const dataBlocks: Uint8Array[] = new Array(); - for (let i = 0, len = this._info.idat.length; i < len; ++i) { + for (let i = 0; i < len; ++i) { this._input.offset = this._info.idat[i]; const chunkSize = this._input.readUint32(); const chunkType = this._input.readString(4); @@ -904,7 +710,7 @@ export class PngDecoder implements Decoder { const crc = this._input.readUint32(); const computedCrc = PngDecoder.crc(chunkType, data); if (crc !== computedCrc) { - throw new ImageError(`Invalid ${chunkType} checksum`); + throw new LibError(`Invalid ${chunkType} checksum`); } } imageData = new Uint8Array(totalSize); @@ -915,7 +721,7 @@ export class PngDecoder implements Decoder { } } else { if (frame < 0 || frame >= this._info.frames.length) { - throw new ImageError(`Invalid Frame Number: ${frame}`); + throw new LibError(`Invalid Frame Number: ${frame}`); } const f = this._info.frames[frame]; @@ -943,18 +749,16 @@ export class PngDecoder implements Decoder { } } - const rgbChannelSet: RgbChannelSet = - this._info.colorType === PngDecoder.GRAYSCALE_ALPHA || - this._info.colorType === PngDecoder.RGBA || - this._info.transparency !== undefined - ? RgbChannelSet.rgba - : RgbChannelSet.rgb; - - const image = new MemoryImage({ - width: width!, - height: height!, - rgbChannelSet: rgbChannelSet, - }); + let numChannels = + this._info.colorType === PngColorType.indexed + ? 1 + : this._info.colorType === PngColorType.grayscale + ? 1 + : this._info.colorType === PngColorType.grayscaleAlpha + ? 2 + : this._info.colorType === PngColorType.rgba + ? 4 + : 3; let uncompressed: Uint8Array | undefined = undefined; try { @@ -971,29 +775,118 @@ export class PngDecoder implements Decoder { }); this.resetBits(); - // Set up a LUT to transform colors for gamma correction. - if (this._info.colorLut === undefined) { - this._info.colorLut = []; - for (let i = 0; i < 256; i++) { - const c = i; - this._info.colorLut.push(c); + let palette: PaletteUint8 | undefined = undefined; + + // Non-indexed PNGs may have a palette, but it only provides a suggested + // set of colors to which an RGB color can be quantized if not displayed + // directly. In this case, just ignore the palette. + if (this._info.colorType === PngColorType.indexed) { + if (this._info.palette !== undefined) { + const p = this._info.palette!; + const numColors = Math.trunc(p.length / 3); + const t = this._info.transparency; + const tl = t !== undefined ? t.length : 0; + const nc = t !== undefined ? 4 : 3; + palette = new PaletteUint8(numColors, nc); + for (let i = 0, pi = 0; i < numColors; ++i, pi += 3) { + let a = 255; + if (nc === 4 && i < tl) { + a = t![i]; + } + palette.setRgba(i, p[pi]!, p[pi + 1]!, p[pi + 2]!, a); + } } + } - // Apply the LUT to the palette, if necessary. - if (this._info.palette !== undefined && this._info.gamma !== undefined) { - for (let i = 0; i < this._info.palette.length; ++i) { - this._info.palette[i] = this._info.colorLut[this._info.palette[i]]; + // grayscale images with no palette but with transparency, get + // converted to a indexed palette image. + if ( + this._info.colorType === PngColorType.grayscale && + this._info.transparency !== undefined && + palette === undefined && + this._info.bits <= 8 + ) { + const t = this._info.transparency!; + const nt = t.length; + const numColors = 1 << this._info.bits; + palette = new PaletteUint8(numColors, 4); + // palette color are 8-bit, so convert the grayscale bit value to the + // 8-bit palette value. + const to8bit = + this._info.bits === 1 + ? 255 + : this._info.bits === 2 + ? 85 + : this._info.bits === 4 + ? 17 + : 1; + for (let i = 0; i < numColors; ++i) { + const g = i * to8bit; + palette.setRgba(i, g, g, g, 255); + } + for (let i = 0; i < nt; i += 2) { + const ti = ((t[i] & 0xff) << 8) | (t[i + 1] & 0xff); + if (ti < numColors) { + palette.set(ti, 3, 0); } } } + const format = + this._info.bits === 1 + ? Format.uint1 + : this._info.bits === 2 + ? Format.uint2 + : this._info.bits === 4 + ? Format.uint4 + : this._info.bits === 16 + ? Format.uint16 + : Format.uint8; + + if ( + this._info.colorType === PngColorType.grayscale && + this._info.transparency !== undefined && + this._info.bits > 8 + ) { + numChannels = 4; + } + + if ( + this._info.colorType === PngColorType.rgb && + this._info.transparency !== undefined + ) { + numChannels = 4; + } + + const opt: MemoryImageCreateOptions = { + width: width, + height: height, + numChannels: numChannels, + palette: palette, + format: format, + }; + + if (this._info.iccpData !== undefined) { + opt.iccProfile = new IccProfile( + this._info.iccpName, + IccProfileCompression.deflate, + this._info.iccpData + ); + } + + if (this._info.textData.size > 0) { + opt.textData = new Map(this._info.textData); + } + + const image = new MemoryImage(opt); + const origW = this._info.width; const origH = this._info.height; - this._info.width = width!; - this._info.height = height!; + this._info.width = width; + this._info.height = height; - const w = width!; - const h = height!; + const w = width; + const h = height; this._progressY = 0; if (this._info.interlaceMethod !== 0) { this.processPass(input, image, 0, 0, 8, 8, (w + 7) >> 3, (h + 7) >> 3); @@ -1010,58 +903,32 @@ export class PngDecoder implements Decoder { this._info.width = origW; this._info.height = origH; - if (this._info.iCCPData !== undefined) { - image.iccProfile = new ICCProfileData( - this._info.iCCPName, - ICCPCompressionMode.deflate, - this._info.iCCPData - ); - } - - if (this._info.textData.size > 0) { - image.addTextData(this._info.textData); - } - return image; } - public decodeHdrFrame(frame: number): HdrImage | undefined { - const img = this.decodeFrame(frame); - if (img === undefined) { - return undefined; - } - return HdrImage.fromImage(img); - } - - public decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined { + public decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined { if (this.startDecode(bytes) === undefined) { return undefined; } - const animation = new FrameAnimation({ - width: this._info!.width, - height: this._info!.height, - }); - - if (!this._info!.isAnimated) { - const image = this.decodeFrame(0)!; - animation.addFrame(image); - return animation; + if (!this._info.isAnimated || frame !== undefined) { + return this.decodeFrame(frame ?? 0); } + let firstImage: MemoryImage | undefined = undefined; let lastImage: MemoryImage | undefined = undefined; - for (let i = 0; i < this._info!.numFrames; ++i) { - const frame = this._info!.frames[i]; + for (let i = 0; i < this._info.numFrames; ++i) { + const frame = this._info.frames[i]; const image = this.decodeFrame(i); if (image === undefined) { continue; } - if (lastImage === undefined) { + if (firstImage === undefined || lastImage === undefined) { + firstImage = image; lastImage = image; // Convert to MS - lastImage.duration = Math.trunc(frame.delay * 1000); - animation.addFrame(lastImage); + lastImage.frameDuration = Math.trunc(frame.delay * 1000); continue; } @@ -1070,57 +937,42 @@ export class PngDecoder implements Decoder { image.height === lastImage.height && frame.xOffset === 0 && frame.yOffset === 0 && - frame.blend === PngFrame.APNG_BLEND_OP_SOURCE + frame.blend === PngBlendMode.source ) { lastImage = image; // Convert to MS - lastImage.duration = Math.trunc(frame.delay * 1000); - animation.addFrame(lastImage); + lastImage.frameDuration = Math.trunc(frame.delay * 1000); + firstImage.addFrame(lastImage); continue; } const dispose = frame.dispose; - if (dispose === PngFrame.APNG_DISPOSE_OP_BACKGROUND) { - lastImage = new MemoryImage({ - width: lastImage.width, - height: lastImage.height, - }); - lastImage.fill(this._info!.backgroundColor); - } else if (dispose === PngFrame.APNG_DISPOSE_OP_PREVIOUS) { + if (dispose === PngDisposeMode.background) { + lastImage = MemoryImage.from(lastImage); + lastImage.clear(this._info.backgroundColor); + } else if (dispose === PngDisposeMode.previous) { lastImage = MemoryImage.from(lastImage); } else { lastImage = MemoryImage.from(lastImage); } // Convert to MS - lastImage.duration = Math.trunc(frame.delay * 1000); + lastImage.frameDuration = Math.trunc(frame.delay * 1000); - ImageTransform.copyInto({ + Draw.compositeImage({ dst: lastImage, src: image, dstX: frame.xOffset, dstY: frame.yOffset, - blend: frame.blend === PngFrame.APNG_BLEND_OP_OVER, + blend: + frame.blend === PngBlendMode.over + ? BlendMode.alpha + : BlendMode.direct, }); - animation.addFrame(lastImage); - } - - return animation; - } - - public decodeImage(bytes: Uint8Array, frame = 0): MemoryImage | undefined { - if (this.startDecode(bytes) === undefined) { - return undefined; + firstImage.addFrame(lastImage); } - return this.decodeFrame(frame); - } - public decodeHdrImage(bytes: Uint8Array, frame = 0): HdrImage | undefined { - const img = this.decodeImage(bytes, frame); - if (img === undefined) { - return undefined; - } - return HdrImage.fromImage(img); + return firstImage; } } diff --git a/src/formats/png-encoder.ts b/src/formats/png-encoder.ts index 43f18c8..a2cacb0 100644 --- a/src/formats/png-encoder.ts +++ b/src/formats/png-encoder.ts @@ -1,21 +1,22 @@ /** @format */ import { deflate } from 'uzip'; -import { BlendMode } from '../common/blend-mode'; -import { Color } from '../common/color'; import { Crc32 } from '../common/crc32'; -import { DisposeMode } from '../common/dispose-mode'; -import { FrameAnimation } from '../common/frame-animation'; -import { ICCProfileData } from '../common/icc-profile-data'; -import { MemoryImage } from '../common/memory-image'; import { OutputBuffer } from '../common/output-buffer'; -import { RgbChannelSet } from '../common/rgb-channel-set'; -import { TextCodec } from '../common/text-codec'; +import { StringUtils } from '../common/string-utils'; import { CompressionLevel } from '../common/typings'; import { Encoder } from './encoder'; +import { Quantizer } from '../image/quantizer'; +import { PngFilterType } from './png/png-filter-type'; +import { MemoryImage } from '../image/image'; +import { Format } from '../color/format'; +import { NeuralQuantizer } from '../image/neural-quantizer'; +import { PngColorType } from './png/png-color-type'; +import { Palette } from '../image/palette'; +import { IccProfile } from '../image/icc-profile'; export interface PngEncoderInitOptions { - filter?: number; + filter?: PngFilterType; level?: CompressionLevel; } @@ -23,66 +24,40 @@ export interface PngEncoderInitOptions { * Encode an image to the PNG format. */ export class PngEncoder implements Encoder { - private static readonly FILTER_NONE = 0; + private _globalQuantizer: Quantizer | undefined; - private static readonly FILTER_SUB = 1; + private _filter: PngFilterType; - private static readonly FILTER_UP = 2; + private _level: number; - private static readonly FILTER_AVERAGE = 3; + private _repeat = 0; - private static readonly FILTER_PAETH = 4; + private _frames = 0; - private static readonly FILTER_AGRESSIVE = 5; + private _sequenceNumber = 0; - private rgbChannelSet?: RgbChannelSet; + private _isAnimated = false; - private filter: number; - - private level: number; - - private repeat = 0; - - private xOffset = 0; - - private yOffset = 0; - - private delay?: number; - - private disposeMethod: DisposeMode = DisposeMode.none; - - private blendMethod: BlendMode = BlendMode.source; - - private width = 0; - - private height = 0; - - private frames = 0; - - private sequenceNumber = 0; - - private isAnimated = false; - - private output?: OutputBuffer; + private _output: OutputBuffer | undefined; /** * Does this encoder support animation? */ private _supportsAnimation = true; - get supportsAnimation() { + public get supportsAnimation() { return this._supportsAnimation; } - constructor(options?: PngEncoderInitOptions) { - this.filter = options?.filter ?? PngEncoder.FILTER_PAETH; - this.level = options?.level ?? 6; + constructor(opt?: PngEncoderInitOptions) { + this._filter = opt?.filter ?? PngFilterType.paeth; + this._level = opt?.level ?? 6; } /** * Return the CRC of the bytes */ private static crc(type: string, bytes: Uint8Array): number { - const typeCodeUnits = TextCodec.getCodePoints(type); + const typeCodeUnits = StringUtils.getCodePoints(type); const crc = Crc32.getChecksum({ buffer: typeCodeUnits, }); @@ -98,119 +73,91 @@ export class PngEncoder implements Encoder { chunk: Uint8Array ): void { out.writeUint32(chunk.length); - const typeCodeUnits = TextCodec.getCodePoints(type); + const typeCodeUnits = StringUtils.getCodePoints(type); out.writeBytes(typeCodeUnits); out.writeBytes(chunk); const crc = PngEncoder.crc(type, chunk); out.writeUint32(crc); } - private static filterSub( - image: MemoryImage, - oi: number, - row: number, - out: Uint8Array + private static write( + bpc: number, + row: Uint8Array, + ri: number, + out: Uint8Array, + oi: number ): number { - let oindex = oi; - - out[oindex++] = PngEncoder.FILTER_SUB; - - out[oindex++] = Color.getRed(image.getPixel(0, row)); - out[oindex++] = Color.getGreen(image.getPixel(0, row)); - out[oindex++] = Color.getBlue(image.getPixel(0, row)); - if (image.rgbChannelSet === RgbChannelSet.rgba) { - out[oindex++] = Color.getAlpha(image.getPixel(0, row)); + let _bpc = bpc; + let _oi = oi; + _bpc--; + while (_bpc >= 0) { + out[_oi++] = row[ri + _bpc]; + _bpc--; } + return _oi; + } - for (let x = 1; x < image.width; ++x) { - const ar = Color.getRed(image.getPixel(x - 1, row)); - const ag = Color.getGreen(image.getPixel(x - 1, row)); - const ab = Color.getBlue(image.getPixel(x - 1, row)); - - const r = Color.getRed(image.getPixel(x, row)); - const g = Color.getGreen(image.getPixel(x, row)); - const b = Color.getBlue(image.getPixel(x, row)); - - out[oindex++] = (r - ar) & 0xff; - out[oindex++] = (g - ag) & 0xff; - out[oindex++] = (b - ab) & 0xff; - if (image.rgbChannelSet === RgbChannelSet.rgba) { - const aa = Color.getAlpha(image.getPixel(x - 1, row)); - const a = Color.getAlpha(image.getPixel(x, row)); - out[oindex++] = (a - aa) & 0xff; + private static filterSub( + row: Uint8Array, + bpc: number, + bpp: number, + out: Uint8Array, + oi: number + ): number { + let _oi = oi; + out[_oi++] = PngFilterType.sub; + for (let x = 0; x < bpp; x += bpc) { + _oi = PngEncoder.write(bpc, row, x, out, _oi); + } + const l = row.length; + for (let x = bpp; x < l; x += bpc) { + for (let c = 0, c2 = bpc - 1; c < bpc; ++c, --c2) { + out[_oi++] = (row[x + c2] - row[x + c2 - bpp]) & 0xff; } } - - return oindex; + return _oi; } private static filterUp( - image: MemoryImage, + row: Uint8Array, + bpc: number, + out: Uint8Array, oi: number, - row: number, - out: Uint8Array + prevRow?: Uint8Array ): number { - let oindex = oi; - - out[oindex++] = PngEncoder.FILTER_UP; - - for (let x = 0; x < image.width; ++x) { - const br = row === 0 ? 0 : Color.getRed(image.getPixel(x, row - 1)); - const bg = row === 0 ? 0 : Color.getGreen(image.getPixel(x, row - 1)); - const bb = row === 0 ? 0 : Color.getBlue(image.getPixel(x, row - 1)); - - const xr = Color.getRed(image.getPixel(x, row)); - const xg = Color.getGreen(image.getPixel(x, row)); - const xb = Color.getBlue(image.getPixel(x, row)); - - out[oindex++] = (xr - br) & 0xff; - out[oindex++] = (xg - bg) & 0xff; - out[oindex++] = (xb - bb) & 0xff; - if (image.rgbChannelSet === RgbChannelSet.rgba) { - const ba = row === 0 ? 0 : Color.getAlpha(image.getPixel(x, row - 1)); - const xa = Color.getAlpha(image.getPixel(x, row)); - out[oindex++] = (xa - ba) & 0xff; + let _oi = oi; + out[_oi++] = PngFilterType.up; + const l = row.length; + for (let x = 0; x < l; x += bpc) { + for (let c = 0, c2 = bpc - 1; c < bpc; ++c, --c2) { + const b = prevRow !== undefined ? prevRow[x + c2] : 0; + out[_oi++] = (row[x + c2] - b) & 0xff; } } - - return oindex; + return _oi; } private static filterAverage( - image: MemoryImage, + row: Uint8Array, + bpc: number, + bpp: number, + out: Uint8Array, oi: number, - row: number, - out: Uint8Array + prevRow?: Uint8Array ): number { - let oindex = oi; - - out[oindex++] = PngEncoder.FILTER_AVERAGE; - - for (let x = 0; x < image.width; ++x) { - const ar = x === 0 ? 0 : Color.getRed(image.getPixel(x - 1, row)); - const ag = x === 0 ? 0 : Color.getGreen(image.getPixel(x - 1, row)); - const ab = x === 0 ? 0 : Color.getBlue(image.getPixel(x - 1, row)); - - const br = row === 0 ? 0 : Color.getRed(image.getPixel(x, row - 1)); - const bg = row === 0 ? 0 : Color.getGreen(image.getPixel(x, row - 1)); - const bb = row === 0 ? 0 : Color.getBlue(image.getPixel(x, row - 1)); - - const xr = Color.getRed(image.getPixel(x, row)); - const xg = Color.getGreen(image.getPixel(x, row)); - const xb = Color.getBlue(image.getPixel(x, row)); - - out[oindex++] = (xr - ((ar + br) >> 1)) & 0xff; - out[oindex++] = (xg - ((ag + bg) >> 1)) & 0xff; - out[oindex++] = (xb - ((ab + bb) >> 1)) & 0xff; - if (image.rgbChannelSet === RgbChannelSet.rgba) { - const aa = x === 0 ? 0 : Color.getAlpha(image.getPixel(x - 1, row)); - const ba = row === 0 ? 0 : Color.getAlpha(image.getPixel(x, row - 1)); - const xa = Color.getAlpha(image.getPixel(x, row)); - out[oindex++] = (xa - ((aa + ba) >> 1)) & 0xff; + let _oi = oi; + out[_oi++] = PngFilterType.average; + const l = row.length; + for (let x = 0; x < l; x += bpc) { + for (let c = 0, c2 = bpc - 1; c < bpc; ++c, --c2) { + const x2 = x + c2; + const p1 = x2 < bpp ? 0 : row[x2 - bpp]; + const p2 = prevRow === undefined ? 0 : prevRow[x2]; + const p3 = row[x2]; + out[_oi++] = p3 - ((p1 + p2) >> 1); } } - - return oindex; + return _oi; } private static paethPredictor(a: number, b: number, c: number): number { @@ -227,84 +174,59 @@ export class PngEncoder implements Encoder { } private static filterPaeth( - image: MemoryImage, + row: Uint8Array, + bpc: number, + bpp: number, + out: Uint8Array, oi: number, - row: number, - out: Uint8Array + prevRow?: Uint8Array ): number { - let oindex = oi; - - out[oindex++] = PngEncoder.FILTER_PAETH; - for (let x = 0; x < image.width; ++x) { - const ar = x === 0 ? 0 : Color.getRed(image.getPixel(x - 1, row)); - const ag = x === 0 ? 0 : Color.getGreen(image.getPixel(x - 1, row)); - const ab = x === 0 ? 0 : Color.getBlue(image.getPixel(x - 1, row)); - - const br = row === 0 ? 0 : Color.getRed(image.getPixel(x, row - 1)); - const bg = row === 0 ? 0 : Color.getGreen(image.getPixel(x, row - 1)); - const bb = row === 0 ? 0 : Color.getBlue(image.getPixel(x, row - 1)); - - const cr = - row === 0 || x === 0 ? 0 : Color.getRed(image.getPixel(x - 1, row - 1)); - const cg = - row === 0 || x === 0 - ? 0 - : Color.getGreen(image.getPixel(x - 1, row - 1)); - const cb = - row === 0 || x === 0 - ? 0 - : Color.getBlue(image.getPixel(x - 1, row - 1)); - - const xr = Color.getRed(image.getPixel(x, row)); - const xg = Color.getGreen(image.getPixel(x, row)); - const xb = Color.getBlue(image.getPixel(x, row)); - - const pr = PngEncoder.paethPredictor(ar, br, cr); - const pg = PngEncoder.paethPredictor(ag, bg, cg); - const pb = PngEncoder.paethPredictor(ab, bb, cb); - - out[oindex++] = (xr - pr) & 0xff; - out[oindex++] = (xg - pg) & 0xff; - out[oindex++] = (xb - pb) & 0xff; - if (image.rgbChannelSet === RgbChannelSet.rgba) { - const aa = x === 0 ? 0 : Color.getAlpha(image.getPixel(x - 1, row)); - const ba = row === 0 ? 0 : Color.getAlpha(image.getPixel(x, row - 1)); - const ca = - row === 0 || x === 0 - ? 0 - : Color.getAlpha(image.getPixel(x - 1, row - 1)); - const xa = Color.getAlpha(image.getPixel(x, row)); - const pa = PngEncoder.paethPredictor(aa, ba, ca); - out[oindex++] = (xa - pa) & 0xff; + let _oi = oi; + out[_oi++] = PngFilterType.paeth; + const l = row.length; + for (let x = 0; x < l; x += bpc) { + for (let c = 0, c2 = bpc - 1; c < bpc; ++c, --c2) { + const x2 = x + c2; + const p0 = x2 < bpp ? 0 : row[x2 - bpp]; + const p1 = prevRow === undefined ? 0 : prevRow[x2]; + const p2 = x2 < bpp || prevRow === undefined ? 0 : prevRow[x2 - bpp]; + const p = row[x2]; + const pi = PngEncoder.paethPredictor(p0, p1, p2); + out[_oi++] = (p - pi) & 0xff; } } - - return oindex; + return _oi; } private static filterNone( - image: MemoryImage, - oi: number, - row: number, - out: Uint8Array + rowBytes: Uint8Array, + bpc: number, + out: Uint8Array, + oi: number ): number { - let oindex = oi; - out[oindex++] = PngEncoder.FILTER_NONE; - for (let x = 0; x < image.width; ++x) { - const c = image.getPixel(x, row); - out[oindex++] = Color.getRed(c); - out[oindex++] = Color.getGreen(c); - out[oindex++] = Color.getBlue(c); - if (image.rgbChannelSet === RgbChannelSet.rgba) { - out[oindex++] = Color.getAlpha(image.getPixel(x, row)); + let _oi = oi; + out[_oi++] = PngFilterType.none; + if (bpc === 1) { + const l = rowBytes.length; + for (let i = 0; i < l; ++i) { + out[_oi++] = rowBytes[i]; + } + } else { + const l = rowBytes.length; + for (let i = 0; i < l; i += bpc) { + _oi = PngEncoder.write(bpc, rowBytes, i, out, _oi); } } - return oindex; + return _oi; } - private writeHeader(width: number, height: number): void { + private static numChannels(image: MemoryImage): number { + return image.hasPalette ? 1 : image.numChannels; + } + + private writeHeader(image: MemoryImage): void { // PNG file signature - this.output!.writeBytes( + this._output!.writeBytes( new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]) ); @@ -312,41 +234,50 @@ export class PngEncoder implements Encoder { const chunk = new OutputBuffer({ bigEndian: true, }); - chunk.writeUint32(width); - chunk.writeUint32(height); - chunk.writeByte(8); - chunk.writeByte(this.rgbChannelSet === RgbChannelSet.rgb ? 2 : 6); - // Compression method + + // width + chunk.writeUint32(image.width); + // height + chunk.writeUint32(image.height); + // bit depth + chunk.writeByte(image.bitsPerChannel); + chunk.writeByte( + image.hasPalette + ? PngColorType.indexed + : image.numChannels === 1 + ? PngColorType.grayscale + : image.numChannels === 2 + ? PngColorType.grayscaleAlpha + : image.numChannels === 3 + ? PngColorType.rgb + : PngColorType.rgba + ); + // compression method: 0:deflate chunk.writeByte(0); - // Filter method + // filter method: 0:adaptive chunk.writeByte(0); - // Interlace method + // interlace method: 0:no interlace chunk.writeByte(0); - PngEncoder.writeChunk(this.output!, 'IHDR', chunk.getBytes()); + PngEncoder.writeChunk(this._output!, 'IHDR', chunk.getBytes()); } - private writeICCPChunk(_?: OutputBuffer, iccp?: ICCProfileData): void { - if (iccp === undefined) { - return; - } - + private writeICCPChunk(iccp: IccProfile): void { const chunk = new OutputBuffer({ bigEndian: true, }); - // Name - const nameCodeUnits = TextCodec.getCodePoints(iccp.name); + // name + const nameCodeUnits = StringUtils.getCodePoints(iccp.name); chunk.writeBytes(nameCodeUnits); chunk.writeByte(0); - // Compression - // 0 - deflate + // compression (0 - deflate) chunk.writeByte(0); // profile data chunk.writeBytes(iccp.compressed()); - PngEncoder.writeChunk(this.output!, 'iCCP', chunk.getBytes()); + PngEncoder.writeChunk(this._output!, 'iCCP', chunk.getBytes()); } private writeAnimationControlChunk(): void { @@ -354,166 +285,247 @@ export class PngEncoder implements Encoder { bigEndian: true, }); // Number of frames - chunk.writeUint32(this.frames); + chunk.writeUint32(this._frames); // Loop count - chunk.writeUint32(this.repeat); - PngEncoder.writeChunk(this.output!, 'acTL', chunk.getBytes()); + chunk.writeUint32(this._repeat); + PngEncoder.writeChunk(this._output!, 'acTL', chunk.getBytes()); } - private applyFilter(image: MemoryImage, out: Uint8Array): void { - let oi = 0; - for (let y = 0; y < image.height; ++y) { - switch (this.filter) { - case PngEncoder.FILTER_SUB: - oi = PngEncoder.filterSub(image, oi, y, out); - break; - case PngEncoder.FILTER_UP: - oi = PngEncoder.filterUp(image, oi, y, out); - break; - case PngEncoder.FILTER_AVERAGE: - oi = PngEncoder.filterAverage(image, oi, y, out); - break; - case PngEncoder.FILTER_PAETH: - oi = PngEncoder.filterPaeth(image, oi, y, out); - break; - case PngEncoder.FILTER_AGRESSIVE: - // TODO Apply all five filters and select the filter that produces - // the smallest sum of absolute values per row. - oi = PngEncoder.filterPaeth(image, oi, y, out); - break; - default: - oi = PngEncoder.filterNone(image, oi, y, out); - break; - } - } - } - - private writeFrameControlChunk(): void { + private writeFrameControlChunk(image: MemoryImage): void { const chunk = new OutputBuffer({ bigEndian: true, }); - chunk.writeUint32(this.sequenceNumber); - chunk.writeUint32(this.width); - chunk.writeUint32(this.height); - chunk.writeUint32(this.xOffset); - chunk.writeUint32(this.yOffset); - chunk.writeUint16(this.delay!); - // Delay denominator + + chunk.writeUint32(this._sequenceNumber); + chunk.writeUint32(image.width); + chunk.writeUint32(image.height); + // xOffset + chunk.writeUint32(0); + // yOffset + chunk.writeUint32(0); + chunk.writeUint16(image.frameDuration); + // delay denominator chunk.writeUint16(1000); - chunk.writeByte(this.disposeMethod); - chunk.writeByte(this.blendMethod); - PngEncoder.writeChunk(this.output!, 'fcTL', chunk.getBytes()); + // dispose method 0: APNG_DISPOSE_OP_NONE + chunk.writeByte(1); + // blend method 0: APNG_BLEND_OP_SOURCE + chunk.writeByte(0); + PngEncoder.writeChunk(this._output!, 'fcTL', chunk.getBytes()); + } + + private writePalette(palette: Palette): void { + if ( + palette.format === Format.uint8 && + palette.numChannels === 3 && + palette.numColors === 256 + ) { + PngEncoder.writeChunk(this._output!, 'PLTE', palette.toUint8Array()); + } else { + const chunk = new OutputBuffer({ + size: palette.numColors * 3, + bigEndian: true, + }); + const nc = palette.numColors; + for (let i = 0; i < nc; ++i) { + chunk.writeByte(Math.trunc(palette.getRed(i))); + chunk.writeByte(Math.trunc(palette.getGreen(i))); + chunk.writeByte(Math.trunc(palette.getBlue(i))); + } + PngEncoder.writeChunk(this._output!, 'PLTE', chunk.getBytes()); + } + + if (palette.numChannels === 4) { + const chunk = new OutputBuffer({ + size: palette.numColors, + bigEndian: true, + }); + const nc = palette.numColors; + for (let i = 0; i < nc; ++i) { + const a = Math.trunc(palette.getAlpha(i)); + chunk.writeByte(a); + } + PngEncoder.writeChunk(this._output!, 'tRNS', chunk.getBytes()); + } } private writeTextChunk(keyword: string, text: string): void { const chunk = new OutputBuffer({ bigEndian: true, }); - const keywordBytes = TextCodec.getCodePoints(keyword); - const textBytes = TextCodec.getCodePoints(text); + const keywordBytes = StringUtils.getCodePoints(keyword); + const textBytes = StringUtils.getCodePoints(text); chunk.writeBytes(keywordBytes); chunk.writeByte(0); chunk.writeBytes(textBytes); - PngEncoder.writeChunk(this.output!, 'tEXt', chunk.getBytes()); + PngEncoder.writeChunk(this._output!, 'tEXt', chunk.getBytes()); + } + + private filter(image: MemoryImage, out: Uint8Array): void { + let oi = 0; + const filter = image.hasPalette ? PngFilterType.none : this._filter; + const buffer = image.buffer; + const rowStride = image.data!.rowStride; + const nc = PngEncoder.numChannels(image); + const bpp = (nc * image.bitsPerChannel + 7) >> 3; + const bpc = (image.bitsPerChannel + 7) >> 3; + + let rowOffset = 0; + let prevRow: Uint8Array | undefined = undefined; + for (let y = 0; y < image.height; ++y) { + const rowBytes = + buffer !== undefined + ? new Uint8Array(buffer, rowOffset, rowStride) + : new Uint8Array(); + rowOffset += rowStride; + + switch (filter) { + case PngFilterType.sub: + oi = PngEncoder.filterSub(rowBytes, bpc, bpp, out, oi); + break; + case PngFilterType.up: + oi = PngEncoder.filterUp(rowBytes, bpc, out, oi, prevRow); + break; + case PngFilterType.average: + oi = PngEncoder.filterAverage(rowBytes, bpc, bpp, out, oi, prevRow); + break; + case PngFilterType.paeth: + oi = PngEncoder.filterPaeth(rowBytes, bpc, bpp, out, oi, prevRow); + break; + default: + oi = PngEncoder.filterNone(rowBytes, bpc, out, oi); + break; + } + prevRow = rowBytes; + } } public addFrame(image: MemoryImage): void { - this.xOffset = image.xOffset; - this.yOffset = image.xOffset; - this.delay = image.duration; - this.disposeMethod = image.disposeMethod; - this.blendMethod = image.blendMethod; - - if (this.output === undefined) { - this.output = new OutputBuffer({ + let _image = image; + // PNG can't encode HDR formats, and can only encode formats with fewer + // than 8 bits if they have a palette. In the case of incompatible + // formats, convert them to uint8. + if ( + (_image.isHdrFormat && _image.format !== Format.uint16) || + (_image.bitsPerChannel < 8 && + !_image.hasPalette && + _image.numChannels > 1) + ) { + _image = _image.convert({ + format: Format.uint8, + }); + } + + if (this._output === undefined) { + this._output = new OutputBuffer({ bigEndian: true, }); - this.rgbChannelSet = image.rgbChannelSet; - this.width = image.width; - this.height = image.height; + this.writeHeader(_image); - this.writeHeader(this.width, this.height); + if (_image.iccProfile !== undefined) { + this.writeICCPChunk(_image.iccProfile); + } - this.writeICCPChunk(this.output, image.iccProfile); + if (_image.hasPalette) { + if (this._globalQuantizer !== undefined) { + this.writePalette(this._globalQuantizer!.palette); + } else { + this.writePalette(_image.palette!); + } + } - if (this.isAnimated) { + if (this._isAnimated) { this.writeAnimationControlChunk(); } } + const nc = PngEncoder.numChannels(_image); + + const channelBytes = _image.format === Format.uint16 ? 2 : 1; + // Include room for the filter bytes (1 byte per row). const filteredImage = new Uint8Array( - image.width * image.height * image.numberOfChannels + image.height + _image.width * _image.height * nc * channelBytes + image.height ); - this.applyFilter(image, filteredImage); + this.filter(_image, filteredImage); const compressed = deflate(filteredImage, { - level: this.level, + level: this._level, }); - if (image.textData !== undefined) { - for (const [key, value] of image.textData) { + if (_image.textData !== undefined) { + for (const [key, value] of _image.textData) { this.writeTextChunk(key, value); } } - if (this.isAnimated) { - this.writeFrameControlChunk(); - this.sequenceNumber++; + if (this._isAnimated) { + this.writeFrameControlChunk(_image); + this._sequenceNumber++; } - if (this.sequenceNumber <= 1) { - PngEncoder.writeChunk(this.output!, 'IDAT', compressed); + if (this._sequenceNumber <= 1) { + PngEncoder.writeChunk(this._output, 'IDAT', compressed); } else { - // FdAT chunk + // fdAT chunk const fdat = new OutputBuffer({ bigEndian: true, }); - fdat.writeUint32(this.sequenceNumber); + fdat.writeUint32(this._sequenceNumber); fdat.writeBytes(compressed); - PngEncoder.writeChunk(this.output!, 'fdAT', fdat.getBytes()); + PngEncoder.writeChunk(this._output, 'fdAT', fdat.getBytes()); - this.sequenceNumber++; + this._sequenceNumber++; } } public finish(): Uint8Array | undefined { let bytes: Uint8Array | undefined = undefined; - if (this.output === undefined) { + if (this._output === undefined) { return bytes; } - PngEncoder.writeChunk(this.output, 'IEND', new Uint8Array()); + PngEncoder.writeChunk(this._output, 'IEND', new Uint8Array()); - this.sequenceNumber = 0; + this._sequenceNumber = 0; - bytes = this.output.getBytes(); - this.output = undefined; + bytes = this._output.getBytes(); + this._output = undefined; return bytes; } /** - * Encode a single frame image. + * Encode **image** to the PNG format. */ - encodeImage(image: MemoryImage): Uint8Array { - this.isAnimated = false; - this.addFrame(image); - return this.finish()!; - } - - /** - * Encode an animation. - */ - public encodeAnimation(animation: FrameAnimation): Uint8Array | undefined { - this.isAnimated = true; - this.frames = animation.frames.length; - this.repeat = animation.loopCount; + public encode(image: MemoryImage, singleFrame = false): Uint8Array { + if (!image.hasAnimation || singleFrame) { + this._isAnimated = false; + this.addFrame(image); + } else { + this._isAnimated = true; + this._frames = image.frames.length; + this._repeat = image.loopCount; + + if (image.hasPalette) { + const q = new NeuralQuantizer(image); + this._globalQuantizer = q; + for (const frame of image.frames) { + if (frame !== image) { + q.addImage(frame); + } + } + } - for (const f of animation) { - this.addFrame(f); + for (const frame of image.frames) { + if (this._globalQuantizer !== undefined) { + const newImage = this._globalQuantizer.getIndexImage(frame); + this.addFrame(newImage); + } else { + this.addFrame(frame); + } + } } - return this.finish(); + return this.finish()!; } } diff --git a/src/common/blend-mode.ts b/src/formats/png/png-blend-mode.ts similarity index 90% rename from src/common/blend-mode.ts rename to src/formats/png/png-blend-mode.ts index 367153d..73daeee 100644 --- a/src/common/blend-mode.ts +++ b/src/formats/png/png-blend-mode.ts @@ -1,6 +1,6 @@ /** @format */ -export enum BlendMode { +export enum PngBlendMode { /** * No alpha blending should be done when drawing this frame (replace pixels in canvas). */ diff --git a/src/formats/png/png-color-type.ts b/src/formats/png/png-color-type.ts new file mode 100644 index 0000000..6ae769e --- /dev/null +++ b/src/formats/png/png-color-type.ts @@ -0,0 +1,9 @@ +/** @format */ + +export enum PngColorType { + grayscale = 0, + rgb = 2, + indexed = 3, + grayscaleAlpha = 4, + rgba = 6, +} diff --git a/src/formats/png/png-dispose-mode.ts b/src/formats/png/png-dispose-mode.ts new file mode 100644 index 0000000..fa92a76 --- /dev/null +++ b/src/formats/png/png-dispose-mode.ts @@ -0,0 +1,7 @@ +/** @format */ + +export enum PngDisposeMode { + none, + background, + previous, +} diff --git a/src/formats/png/png-filter-type.ts b/src/formats/png/png-filter-type.ts new file mode 100644 index 0000000..6f0e0a0 --- /dev/null +++ b/src/formats/png/png-filter-type.ts @@ -0,0 +1,9 @@ +/** @format */ + +export enum PngFilterType { + none, + sub, + up, + average, + paeth, +} diff --git a/src/formats/png/png-frame.ts b/src/formats/png/png-frame.ts index 7b852ec..5c2ad3c 100644 --- a/src/formats/png/png-frame.ts +++ b/src/formats/png/png-frame.ts @@ -1,5 +1,8 @@ /** @format */ +import { PngBlendMode } from './png-blend-mode'; +import { PngDisposeMode } from './png-dispose-mode'; + export interface PngFrameInitOptions { sequenceNumber?: number; width?: number; @@ -14,65 +17,53 @@ export interface PngFrameInitOptions { // Decodes a frame from a PNG animation. export class PngFrame { - // DisposeMode - public static readonly APNG_DISPOSE_OP_NONE = 0; - - public static readonly APNG_DISPOSE_OP_BACKGROUND = 1; - - public static readonly APNG_DISPOSE_OP_PREVIOUS = 2; - - // BlendMode - public static readonly APNG_BLEND_OP_SOURCE = 0; - - public static readonly APNG_BLEND_OP_OVER = 1; - private readonly _fdat: number[] = []; public get fdat(): number[] { return this._fdat; } - private _sequenceNumber?: number; - public get sequenceNumber(): number | undefined { + private _sequenceNumber: number; + public get sequenceNumber(): number { return this._sequenceNumber; } - private _width?: number; - public get width(): number | undefined { + private _width: number; + public get width(): number { return this._width; } - private _height?: number; - public get height(): number | undefined { + private _height: number; + public get height(): number { return this._height; } - private _xOffset?: number; - public get xOffset(): number | undefined { + private _xOffset: number; + public get xOffset(): number { return this._xOffset; } - private _yOffset?: number; - public get yOffset(): number | undefined { + private _yOffset: number; + public get yOffset(): number { return this._yOffset; } - private _delayNum?: number; - public get delayNum(): number | undefined { + private _delayNum: number; + public get delayNum(): number { return this._delayNum; } - private _delayDen?: number; - public get delayDen(): number | undefined { + private _delayDen: number; + public get delayDen(): number { return this._delayDen; } - private _dispose?: number; - public get dispose(): number | undefined { + private _dispose: PngDisposeMode; + public get dispose(): PngDisposeMode { return this._dispose; } - private _blend?: number; - public get blend(): number | undefined { + private _blend: PngBlendMode; + public get blend(): PngBlendMode { return this._blend; } @@ -86,15 +77,15 @@ export class PngFrame { return this._delayNum / this._delayDen; } - constructor(options: PngFrameInitOptions) { - this._sequenceNumber = options?.sequenceNumber; - this._width = options?.width; - this._height = options?.height; - this._xOffset = options?.xOffset; - this._yOffset = options?.yOffset; - this._delayNum = options?.delayNum; - this._delayDen = options?.delayDen; - this._dispose = options?.dispose; - this._blend = options?.blend; + constructor(opt: PngFrameInitOptions) { + this._sequenceNumber = opt?.sequenceNumber ?? 0; + this._width = opt?.width ?? 0; + this._height = opt?.height ?? 0; + this._xOffset = opt?.xOffset ?? 0; + this._yOffset = opt?.yOffset ?? 0; + this._delayNum = opt?.delayNum ?? 0; + this._delayDen = opt?.delayDen ?? 0; + this._dispose = opt?.dispose ?? PngDisposeMode.none; + this._blend = opt?.blend ?? PngBlendMode.source; } } diff --git a/src/formats/png/png-info.ts b/src/formats/png/png-info.ts index c523cf6..4fa9498 100644 --- a/src/formats/png/png-info.ts +++ b/src/formats/png/png-info.ts @@ -1,6 +1,8 @@ /** @format */ +import { Color } from '../../color/color'; import { DecodeInfo } from '../decode-info'; +import { PngColorType } from './png-color-type'; import { PngFrame } from './png-frame'; export interface PngInfoInitOptions { @@ -15,12 +17,12 @@ export interface PngInfoInitOptions { export class PngInfo implements DecodeInfo { private _width = 0; - public set width(v: number) { - this._width = v; - } public get width(): number { return this._width; } + public set width(v: number) { + this._width = v; + } private _height = 0; public set height(v: number) { @@ -30,101 +32,108 @@ export class PngInfo implements DecodeInfo { return this._height; } - private _backgroundColor = 0x00ffffff; - public set backgroundColor(v: number) { - this._backgroundColor = v; - } - public get backgroundColor(): number { + private _backgroundColor: Color | undefined = undefined; + public get backgroundColor(): Color | undefined { return this._backgroundColor; } + public set backgroundColor(v: Color | undefined) { + this._backgroundColor = v; + } private _numFrames = 1; - public set numFrames(v: number) { - this._numFrames = v; - } public get numFrames(): number { return this._numFrames; } + public set numFrames(v: number) { + this._numFrames = v; + } - private _bits?: number; - public get bits(): number | undefined { + private _bits: number; + public get bits(): number { return this._bits; } + public set bits(v: number) { + this._bits = v; + } - private _colorType?: number; - public get colorType(): number | undefined { + private _colorType: PngColorType | undefined; + public get colorType(): PngColorType | undefined { return this._colorType; } + public set colorType(v: PngColorType | undefined) { + this._colorType = v; + } - private _compressionMethod?: number; - public get compressionMethod(): number | undefined { + private _compressionMethod: number; + public get compressionMethod(): number { return this._compressionMethod; } + public set compressionMethod(v: number) { + this._compressionMethod = v; + } - private _filterMethod?: number; - public get filterMethod(): number | undefined { + private _filterMethod: number; + public get filterMethod(): number { return this._filterMethod; } + public set filterMethod(v: number) { + this._filterMethod = v; + } - private _interlaceMethod?: number; - public get interlaceMethod(): number | undefined { + private _interlaceMethod: number; + public get interlaceMethod(): number { return this._interlaceMethod; } + public set interlaceMethod(v: number) { + this._interlaceMethod = v; + } private _palette?: Uint8Array; - public set palette(v: Uint8Array | undefined) { - this._palette = v; - } public get palette(): Uint8Array | undefined { return this._palette; } + public set palette(v: Uint8Array | undefined) { + this._palette = v; + } private _transparency?: Uint8Array; - public set transparency(v: Uint8Array | undefined) { - this._transparency = v; - } public get transparency(): Uint8Array | undefined { return this._transparency; } - - private _colorLut?: number[]; - public set colorLut(v: number[] | undefined) { - this._colorLut = v; - } - public get colorLut(): number[] | undefined { - return this._colorLut; + public set transparency(v: Uint8Array | undefined) { + this._transparency = v; } private _gamma?: number; - public set gamma(v: number | undefined) { - this._gamma = v; - } public get gamma(): number | undefined { return this._gamma; } + public set gamma(v: number | undefined) { + this._gamma = v; + } - private _iCCPName = ''; - public set iCCPName(v: string) { - this._iCCPName = v; + private _iccpName = ''; + public get iccpName(): string { + return this._iccpName; } - public get iCCPName(): string { - return this._iCCPName; + public set iccpName(v: string) { + this._iccpName = v; } - private _iCCPCompression = 0; - public set iCCPCompression(v: number) { - this._iCCPCompression = v; + private _iccpCompression = 0; + public get iccpCompression(): number { + return this._iccpCompression; } - public get iCCPCompression(): number { - return this._iCCPCompression; + public set iccpCompression(v: number) { + this._iccpCompression = v; } - private _iCCPData?: Uint8Array; - public set iCCPData(v: Uint8Array | undefined) { - this._iCCPData = v; + private _iccpData?: Uint8Array; + public get iccpData(): Uint8Array | undefined { + return this._iccpData; } - public get iCCPData(): Uint8Array | undefined { - return this._iCCPData; + public set iccpData(v: Uint8Array | undefined) { + this._iccpData = v; } private _textData: Map = new Map(); @@ -133,12 +142,12 @@ export class PngInfo implements DecodeInfo { } private _repeat = 0; - public set repeat(v: number) { - this._repeat = v; - } public get repeat(): number { return this._repeat; } + public set repeat(v: number) { + this._repeat = v; + } private readonly _idat: number[] = []; public get idat(): number[] { @@ -154,13 +163,13 @@ export class PngInfo implements DecodeInfo { return this._frames.length > 0; } - constructor(options?: PngInfoInitOptions) { - this._width = options?.width ?? 0; - this._height = options?.height ?? 0; - this._bits = options?.bits; - this._colorType = options?.colorType; - this._compressionMethod = options?.compressionMethod; - this._filterMethod = options?.filterMethod; - this._interlaceMethod = options?.interlaceMethod; + constructor(opt?: PngInfoInitOptions) { + this._width = opt?.width ?? 0; + this._height = opt?.height ?? 0; + this._bits = opt?.bits ?? 0; + this._colorType = opt?.colorType; + this._compressionMethod = opt?.compressionMethod ?? 0; + this._filterMethod = opt?.filterMethod ?? 0; + this._interlaceMethod = opt?.interlaceMethod ?? 0; } } diff --git a/src/formats/tga-decoder.ts b/src/formats/tga-decoder.ts index 070f217..912cb8a 100644 --- a/src/formats/tga-decoder.ts +++ b/src/formats/tga-decoder.ts @@ -1,141 +1,313 @@ /** @format */ -import { Color } from '../common/color'; -import { FrameAnimation } from '../common/frame-animation'; import { InputBuffer } from '../common/input-buffer'; -import { MemoryImage } from '../common/memory-image'; -import { RgbChannelSet } from '../common/rgb-channel-set'; -import { HdrImage } from '../hdr/hdr-image'; +import { MemoryImage } from '../image/image'; +import { Palette } from '../image/palette'; import { Decoder } from './decoder'; +import { TgaImageType } from './tga/tga-image-type'; import { TgaInfo } from './tga/tga-info'; /** - * Decode a TGA image. This only supports the 24-bit uncompressed format. + * Decode a TGA image. This only supports the 24-bit and 32-bit uncompressed format. */ export class TgaDecoder implements Decoder { - private info: TgaInfo | undefined = undefined; - - private input: InputBuffer | undefined = undefined; + private _input: InputBuffer | undefined = undefined; + private _info: TgaInfo | undefined = undefined; public get numFrames(): number { - return this.info !== undefined ? 1 : 0; + return this._info !== undefined ? 1 : 0; } - /** - * Is the given file a valid TGA image? - */ - public isValidFile(bytes: Uint8Array): boolean { - const input = new InputBuffer({ - buffer: bytes, - bigEndian: true, - }); - - const header = input.readBytes(18); - if (header.getByte(2) !== 2) { - return false; - } - if (header.getByte(16) !== 24 && header.getByte(16) !== 32) { - return false; + private decodeColorMap(colorMap: Uint8Array, palette: Palette): void { + if (this._info === undefined || this._input === undefined) { + return; } - return true; - } - - public startDecode(bytes: Uint8Array): TgaInfo | undefined { - this.input = new InputBuffer({ - buffer: bytes, - bigEndian: true, + const cm = new InputBuffer({ + buffer: colorMap, }); - const header = this.input.readBytes(18); - if (header.getByte(2) !== 2) { - return undefined; + if (this._info.colorMapDepth === 16) { + const color = this._input.readUint16(); + const r = (color & 0x7c00) >> 7; + const g = (color & 0x3e0) >> 2; + const b = (color & 0x1f) << 3; + const a = (color & 0x8000) !== 0 ? 0 : 255; + for (let i = 0; i < this._info.colorMapLength; ++i) { + palette.setRed(i, r); + palette.setGreen(i, g); + palette.setBlue(i, b); + palette.setAlpha(i, a); + } + } else { + const hasAlpha = this._info.colorMapDepth === 32; + for (let i = 0; i < this._info.colorMapLength; ++i) { + const b = cm.readByte(); + const g = cm.readByte(); + const r = cm.readByte(); + const a = hasAlpha ? cm.readByte() : 255; + palette.setRed(i, r); + palette.setGreen(i, g); + palette.setBlue(i, b); + palette.setAlpha(i, a); + } } - if (header.getByte(16) !== 24 && header.getByte(16) !== 32) { + } + + private decodeRle(): MemoryImage | undefined { + if (this._info === undefined || this._input === undefined) { return undefined; } - const width = - (header.getByte(12) & 0xff) | ((header.getByte(13) & 0xff) << 8); - const height = - (header.getByte(14) & 0xff) | ((header.getByte(15) & 0xff) << 8); - const imageOffset = this.input.offset; - const bitsPerPixel = header.getByte(16); - - this.info = new TgaInfo({ - width: width, - height: height, - imageOffset: imageOffset, - bitsPerPixel: bitsPerPixel, + const bpp = this._info.pixelDepth; + const hasAlpha = bpp === 16 || bpp === 32; + const image = new MemoryImage({ + width: this._info.width, + height: this._info.height, + numChannels: hasAlpha ? 4 : 3, + withPalette: this._info.hasColorMap, }); - return this.info; + const rleBit = 0x80; + const rleMask = 0x7f; + + if (image.palette !== undefined && this._info.colorMap !== undefined) { + this.decodeColorMap(this._info.colorMap, image.palette); + } + + const w = image.width; + const h = image.height; + let y = h - 1; + let x = 0; + while (!this._input.isEOS && y >= 0) { + const c = this._input.readByte(); + const count = (c & rleMask) + 1; + + if ((c & rleBit) !== 0) { + if (bpp === 8) { + const r = this._input.readByte(); + for (let i = 0; i < count; ++i) { + image.setPixelR(x++, y, r); + if (x >= w) { + x = 0; + y--; + if (y < 0) { + break; + } + } + } + } else if (bpp === 16) { + const color = this._input.readUint16(); + const r = (color & 0x7c00) >> 7; + const g = (color & 0x3e0) >> 2; + const b = (color & 0x1f) << 3; + const a = (color & 0x8000) !== 0 ? 0 : 255; + for (let i = 0; i < count; ++i) { + image.setPixelRgba(x++, y, r, g, b, a); + if (x >= w) { + x = 0; + y--; + if (y < 0) { + break; + } + } + } + } else { + const b = this._input.readByte(); + const g = this._input.readByte(); + const r = this._input.readByte(); + const a = hasAlpha ? this._input.readByte() : 255; + for (let i = 0; i < count; ++i) { + image.setPixelRgba(x++, y, r, g, b, a); + if (x >= w) { + x = 0; + y--; + if (y < 0) { + break; + } + } + } + } + } else { + if (bpp === 8) { + for (let i = 0; i < count; ++i) { + const r = this._input.readByte(); + image.setPixelR(x++, y, r); + if (x >= w) { + x = 0; + y--; + if (y < 0) { + break; + } + } + } + } else if (bpp === 16) { + for (let i = 0; i < count; ++i) { + const color = this._input.readUint16(); + const r = (color & 0x7c00) >> 7; + const g = (color & 0x3e0) >> 2; + const b = (color & 0x1f) << 3; + const a = (color & 0x8000) !== 0 ? 0 : 255; + image.setPixelRgba(x++, y, r, g, b, a); + if (this._input.isEOS) { + break; + } + if (x >= w) { + x = 0; + y--; + if (y < 0) { + break; + } + } + } + } else { + for (let i = 0; i < count; ++i) { + const b = this._input.readByte(); + const g = this._input.readByte(); + const r = this._input.readByte(); + const a = hasAlpha ? this._input.readByte() : 255; + image.setPixelRgba(x++, y, r, g, b, a); + if (x >= w) { + x = 0; + y--; + if (y < 0) { + break; + } + } + } + } + } + + if (x >= w) { + x = 0; + y--; + if (y < 0) { + break; + } + } + } + + return image; } - public decodeFrame(_frame: number): MemoryImage | undefined { - if (this.info === undefined || this.input === undefined) { + private decodeRgb(): MemoryImage | undefined { + if (this._info === undefined || this._input === undefined) { return undefined; } - this.input.offset = this.info.imageOffset!; + this._input.offset = this._info.imageOffset; + + const bpp = this._info.pixelDepth; + const hasAlpha = + bpp === 16 || + bpp === 32 || + (this._info.hasColorMap && + (this._info.colorMapDepth === 16 || this._info.colorMapDepth === 32)); + const image = new MemoryImage({ - width: this.info.width, - height: this.info.height, - rgbChannelSet: RgbChannelSet.rgb, + width: this._info.width, + height: this._info.height, + numChannels: hasAlpha ? 4 : 3, + withPalette: this._info.hasColorMap, }); - for (let y = image.height - 1; y >= 0; --y) { - for (let x = 0; x < image.width; ++x) { - const b = this.input.readByte(); - const g = this.input.readByte(); - const r = this.input.readByte(); - const a = this.info.bitsPerPixel === 32 ? this.input.readByte() : 255; - image.setPixel(x, y, Color.getColor(r, g, b, a)); + + if (this._info.hasColorMap) { + this.decodeColorMap(this._info.colorMap!, image.palette!); + } + + if (bpp === 8) { + for (let y = image.height - 1; y >= 0; --y) { + for (let x = 0; x < image.width; ++x) { + const index = this._input.readByte(); + image.setPixelR(x, y, index); + } + } + } else if (bpp === 16) { + for (let y = image.height - 1; y >= 0; --y) { + for (let x = 0; x < image.width; ++x) { + const color = this._input.readUint16(); + const r = (color & 0x7c00) >> 7; + const g = (color & 0x3e0) >> 2; + const b = (color & 0x1f) << 3; + const a = (color & 0x8000) !== 0 ? 0 : 255; + image.setPixelRgba(x, y, r, g, b, a); + } + } + } else { + for (let y = image.height - 1; y >= 0; --y) { + for (let x = 0; x < image.width; ++x) { + const b = this._input.readByte(); + const g = this._input.readByte(); + const r = this._input.readByte(); + const a = hasAlpha ? this._input.readByte() : 255; + image.setPixelRgba(x, y, r, g, b, a); + } } } return image; } - public decodeHdrFrame(frame: number): HdrImage | undefined { - const img = this.decodeFrame(frame); - if (img === undefined) { - return undefined; - } - return HdrImage.fromImage(img); + /** + * Is the given file a valid TGA image? + */ + public isValidFile(bytes: Uint8Array): boolean { + const input = new InputBuffer({ + buffer: bytes, + }); + + this._info = new TgaInfo(); + this._info.read(input); + return this._info.isValid(); } - public decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined { - const image = this.decodeImage(bytes); - if (image === undefined) { + public startDecode(bytes: Uint8Array): TgaInfo | undefined { + this._info = new TgaInfo(); + this._input = new InputBuffer({ buffer: bytes }); + + const header = this._input.readBytes(18); + this._info.read(header); + if (!this._info.isValid()) { return undefined; } - const animation = new FrameAnimation({ - width: image.width, - height: image.height, - }); + this._input.skip(this._info.idLength); + + // Decode colormap + if (this._info.hasColorMap) { + const size = this._info.colorMapLength * (this._info.colorMapDepth >> 3); + this._info.colorMap = this._input.readBytes(size).toUint8Array(); + } - animation.addFrame(image); + this._info.imageOffset = this._input.offset; - return animation; + return this._info; } - public decodeImage(bytes: Uint8Array, frame = 0): MemoryImage | undefined { + public decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined { if (this.startDecode(bytes) === undefined) { return undefined; } - return this.decodeFrame(frame); + return this.decodeFrame(frame ?? 0); } - public decodeHdrImage( - bytes: Uint8Array, - frame?: number | undefined - ): HdrImage | undefined { - const img = this.decodeImage(bytes, frame); - if (img === undefined) { + public decodeFrame(_frame: number): MemoryImage | undefined { + if (this._info === undefined || this._input === undefined) { return undefined; } - return HdrImage.fromImage(img); + + if (this._info.imageType === TgaImageType.rgb) { + return this.decodeRgb(); + } else if ( + this._info.imageType === TgaImageType.rgbRle || + this._info.imageType === TgaImageType.paletteRle + ) { + return this.decodeRle(); + } else if (this._info.imageType === TgaImageType.palette) { + return this.decodeRgb(); + } + + return undefined; } } diff --git a/src/formats/tga-encoder.ts b/src/formats/tga-encoder.ts index 9080155..b76b0d9 100644 --- a/src/formats/tga-encoder.ts +++ b/src/formats/tga-encoder.ts @@ -1,10 +1,7 @@ /** @format */ -import { Color } from '../common/color'; -import { FrameAnimation } from '../common/frame-animation'; -import { MemoryImage } from '../common/memory-image'; import { OutputBuffer } from '../common/output-buffer'; -import { RgbChannelSet } from '../common/rgb-channel-set'; +import { MemoryImage } from '../image/image'; import { Encoder } from './encoder'; /** @@ -16,7 +13,7 @@ export class TgaEncoder implements Encoder { return this._supportsAnimation; } - public encodeImage(image: MemoryImage): Uint8Array { + public encode(image: MemoryImage, _singleFrame = false): Uint8Array { const out = new OutputBuffer({ bigEndian: true, }); @@ -29,26 +26,32 @@ export class TgaEncoder implements Encoder { header[13] = (image.width >> 8) & 0xff; header[14] = image.height & 0xff; header[15] = (image.height >> 8) & 0xff; - header[16] = image.rgbChannelSet === RgbChannelSet.rgb ? 24 : 32; + const nc = image.palette?.numChannels ?? image.numChannels; + header[16] = nc === 3 ? 24 : 32; out.writeBytes(header); - for (let y = image.height - 1; y >= 0; --y) { - for (let x = 0; x < image.width; ++x) { - const c = image.getPixel(x, y); - out.writeByte(Color.getBlue(c)); - out.writeByte(Color.getGreen(c)); - out.writeByte(Color.getRed(c)); - if (image.rgbChannelSet === RgbChannelSet.rgba) { - out.writeByte(Color.getAlpha(c)); + if (nc === 4) { + for (let y = image.height - 1; y >= 0; --y) { + for (let x = 0; x < image.width; ++x) { + const c = image.getPixel(x, y); + out.writeByte(Math.trunc(c.b)); + out.writeByte(Math.trunc(c.g)); + out.writeByte(Math.trunc(c.r)); + out.writeByte(Math.trunc(c.a)); + } + } + } else { + for (let y = image.height - 1; y >= 0; --y) { + for (let x = 0; x < image.width; ++x) { + const c = image.getPixel(x, y); + out.writeByte(Math.trunc(c.b)); + out.writeByte(Math.trunc(c.g)); + out.writeByte(Math.trunc(c.r)); } } } return out.getBytes(); } - - public encodeAnimation(_animation: FrameAnimation): Uint8Array | undefined { - return undefined; - } } diff --git a/src/formats/tga/tga-image-type.ts b/src/formats/tga/tga-image-type.ts new file mode 100644 index 0000000..bb8d274 --- /dev/null +++ b/src/formats/tga/tga-image-type.ts @@ -0,0 +1,18 @@ +/** @format */ + +export enum TgaImageType { + none, + palette, + rgb, + gray, + reserved4, + reserved5, + reserved6, + reserved7, + reserved8, + paletteRle, + rgbRle, + grayRle, +} + +export const TgaImageTypeLength = 12; diff --git a/src/formats/tga/tga-info.ts b/src/formats/tga/tga-info.ts index 93ca3d3..6aa9d52 100644 --- a/src/formats/tga/tga-info.ts +++ b/src/formats/tga/tga-info.ts @@ -1,6 +1,9 @@ /** @format */ +import { Color } from '../../color/color'; +import { InputBuffer } from '../../common/input-buffer'; import { DecodeInfo } from '../decode-info'; +import { TgaImageType, TgaImageTypeLength } from './tga-image-type'; export interface TgaInfoInitOptions { width?: number; @@ -10,49 +13,168 @@ export interface TgaInfoInitOptions { } export class TgaInfo implements DecodeInfo { - private readonly _width: number = 0; + /** + * The number of frames that can be decoded. + */ + private readonly _numFrames: number = 1; + public get numFrames(): number { + return this._numFrames; + } + + private readonly _backgroundColor: Color | undefined = undefined; + public get backgroundColor(): Color | undefined { + return this._backgroundColor; + } + + private _idLength = 0; + public get idLength(): number { + return this._idLength; + } + + private _colorMapType = 0; + public get colorMapType(): number { + return this._colorMapType; + } + + private _imageType: TgaImageType = TgaImageType.none; + public get imageType(): TgaImageType { + return this._imageType; + } + + private _colorMapOrigin = 0; + public get colorMapOrigin(): number { + return this._colorMapOrigin; + } + + private _colorMapLength = 0; + public get colorMapLength(): number { + return this._colorMapLength; + } + + private _colorMapDepth = 0; + public get colorMapDepth(): number { + return this._colorMapDepth; + } + + private _offsetX = 0; + public get offsetX(): number { + return this._offsetX; + } + + private _offsetY = 0; + public get offsetY(): number { + return this._offsetY; + } + + private _width = 0; public get width(): number { return this._width; } - protected readonly _height: number = 0; + protected _height = 0; public get height(): number { return this._height; } - private readonly _backgroundColor: number = 0xffffffff; - public get backgroundColor(): number { - return this._backgroundColor; + protected _pixelDepth = 0; + public get pixelDepth(): number { + return this._pixelDepth; } - /** - * The number of frames that can be decoded. - */ - private readonly _numFrames: number = 1; - public get numFrames(): number { - return this._numFrames; + protected _flags = 0; + public get flags(): number { + return this._flags; + } + + protected _colorMap: Uint8Array | undefined; + public get colorMap(): Uint8Array | undefined { + return this._colorMap; + } + public set colorMap(v: Uint8Array | undefined) { + this._colorMap = v; + } + + protected _screenOrigin = 0; + public get screenOrigin(): number { + return this._screenOrigin; } /** * Offset in the input file the image data starts at. */ - private readonly _imageOffset: number | undefined = undefined; - public get imageOffset(): number | undefined { + private _imageOffset = 0; + public get imageOffset(): number { return this._imageOffset; } + public set imageOffset(v: number) { + this._imageOffset = v; + } - /** - * Bits per pixel. - */ - private readonly _bitsPerPixel: number | undefined = undefined; - public get bitsPerPixel(): number | undefined { - return this._bitsPerPixel; + public get hasColorMap(): boolean { + return ( + this._imageType === TgaImageType.palette || + this._imageType === TgaImageType.paletteRle + ); + } + + public read(header: InputBuffer): void { + if (header.length < 18) { + return; + } + // 0 + this._idLength = header.readByte(); + // 1 + this._colorMapType = header.readByte(); + const it = header.readByte(); + // 2 + this._imageType = + it < TgaImageTypeLength ? (it as TgaImageType) : TgaImageType.none; + // 3 + this._colorMapOrigin = header.readUint16(); + // 5 + this._colorMapLength = header.readUint16(); + // 7 + this._colorMapDepth = header.readByte(); + // 8 + this._offsetX = header.readUint16(); + // 10 + this._offsetY = header.readUint16(); + // 12 + this._width = header.readUint16(); + // 14 + this._height = header.readUint16(); + // 16 + this._pixelDepth = header.readByte(); + // 17 + this._flags = header.readByte(); + this._screenOrigin = (this._flags & 0x30) >> 4; } - constructor(options?: TgaInfoInitOptions) { - this._width = options?.width ?? 0; - this._height = options?.height ?? 0; - this._imageOffset = options?.imageOffset ?? undefined; - this._bitsPerPixel = options?.bitsPerPixel ?? undefined; + public isValid(): boolean { + if ( + this._pixelDepth !== 8 && + this._pixelDepth !== 16 && + this._pixelDepth !== 24 && + this._pixelDepth !== 32 + ) { + return false; + } + + if (this.hasColorMap) { + if (this._colorMapLength > 256 || this._colorMapType !== 1) { + return false; + } + if ( + this._colorMapDepth !== 16 && + this._colorMapDepth !== 24 && + this._colorMapDepth !== 32 + ) { + return false; + } + } else if (this._colorMapType === 1) { + return false; + } + + return true; } } diff --git a/src/formats/tiff-decoder.ts b/src/formats/tiff-decoder.ts index 87cd5bc..70a5e6c 100644 --- a/src/formats/tiff-decoder.ts +++ b/src/formats/tiff-decoder.ts @@ -1,21 +1,19 @@ /** @format */ -import { FrameAnimation } from '../common/frame-animation'; -import { FrameType } from '../common/frame-type'; import { InputBuffer } from '../common/input-buffer'; -import { MemoryImage } from '../common/memory-image'; import { ExifData } from '../exif/exif-data'; -import { HdrImage } from '../hdr/hdr-image'; +import { FrameType } from '../image/frame-type'; +import { MemoryImage } from '../image/image'; import { Decoder } from './decoder'; import { TiffImage } from './tiff/tiff-image'; import { TiffInfo } from './tiff/tiff-info'; export class TiffDecoder implements Decoder { - private static readonly TIFF_SIGNATURE = 42; - private static readonly TIFF_LITTLE_ENDIAN = 0x4949; - private static readonly TIFF_BIG_ENDIAN = 0x4d4d; + private static readonly _tiffSignature = 42; + private static readonly _tiffLittleEndian = 0x4949; + private static readonly _tiffBigEndian = 0x4d4d; - private input!: InputBuffer; + private _input!: InputBuffer; private _info: TiffInfo | undefined = undefined; public get info(): TiffInfo | undefined { @@ -41,14 +39,14 @@ export class TiffDecoder implements Decoder { private readHeader(p: InputBuffer): TiffInfo | undefined { const byteOrder = p.readUint16(); if ( - byteOrder !== TiffDecoder.TIFF_LITTLE_ENDIAN && - byteOrder !== TiffDecoder.TIFF_BIG_ENDIAN + byteOrder !== TiffDecoder._tiffLittleEndian && + byteOrder !== TiffDecoder._tiffBigEndian ) { return undefined; } let bigEndian = false; - if (byteOrder === TiffDecoder.TIFF_BIG_ENDIAN) { + if (byteOrder === TiffDecoder._tiffBigEndian) { p.bigEndian = true; bigEndian = true; } else { @@ -58,11 +56,12 @@ export class TiffDecoder implements Decoder { let signature = 0; signature = p.readUint16(); - if (signature !== TiffDecoder.TIFF_SIGNATURE) { + if (signature !== TiffDecoder._tiffSignature) { return undefined; } let offset = p.readUint32(); + const ifdOffset = offset; const p2 = InputBuffer.from(p); p2.offset = offset; @@ -90,7 +89,7 @@ export class TiffDecoder implements Decoder { ? new TiffInfo({ bigEndian: bigEndian, signature: signature, - ifdOffset: offset, + ifdOffset: ifdOffset, images: images, }) : undefined; @@ -111,10 +110,10 @@ export class TiffDecoder implements Decoder { * If the file is not a valid TIFF image, undefined is returned. */ public startDecode(bytes: Uint8Array): TiffInfo | undefined { - this.input = new InputBuffer({ + this._input = new InputBuffer({ buffer: bytes, }); - this._info = this.readHeader(this.input); + this._info = this.readHeader(this._input); if (this.info !== undefined) { const buffer = new InputBuffer({ buffer: bytes, @@ -127,91 +126,56 @@ export class TiffDecoder implements Decoder { /** * Decode a single frame from the data stat was set with **startDecode**. * If **frame** is out of the range of available frames, undefined is returned. - * Non animated image files will only have **frame** 0. An **AnimationFrame** - * is returned, which provides the image, and top-left coordinates of the - * image, as animated frames may only occupy a subset of the canvas. + * Non animated image files will only have **frame** 0. */ public decodeFrame(frame: number): MemoryImage | undefined { if (this._info === undefined) { return undefined; } - const image = this._info.images[frame].decode(this.input); + const image = this._info.images[frame].decode(this._input); if (this._exifData !== undefined) { image.exifData = this._exifData; } return image; } - public decodeHdrFrame(frame: number): HdrImage | undefined { - if (this._info === undefined) { - return undefined; - } - return this._info.images[frame].decodeHdr(this.input); - } - - /** - * Decode all of the frames from an animation. If the file is not an - * animation, a single frame animation is returned. If there was a problem - * decoding the file, undefined is returned. - */ - public decodeAnimation(bytes: Uint8Array): FrameAnimation | undefined { - if (this.startDecode(bytes) === undefined) { - return undefined; - } - - const animation = new FrameAnimation({ - width: this._info!.width, - height: this._info!.height, - frameType: FrameType.page, - }); - - for (let i = 0, len = this.numFrames; i < len; ++i) { - const image = this.decodeFrame(i); - animation.addFrame(image!); - } - - return animation; - } - /** * Decode the file and extract a single image from it. If the file is * animated, the specified **frame** will be decoded. If there was a problem * decoding the file, undefined is returned. */ - public decodeImage(bytes: Uint8Array, frame = 0): MemoryImage | undefined { - this.input = new InputBuffer({ + public decode(bytes: Uint8Array, frame?: number): MemoryImage | undefined { + this._input = new InputBuffer({ buffer: bytes, }); - this._info = this.readHeader(this.input); + this._info = this.readHeader(this._input); if (this._info === undefined) { return undefined; } - const image = this._info.images[frame].decode(this.input); - const buffer = new InputBuffer({ - buffer: bytes, - }); - image.exifData = ExifData.fromInputBuffer(buffer); - return image; - } - - public decodeHdrImage(bytes: Uint8Array, frame = 0): HdrImage | undefined { - this.input = new InputBuffer({ - buffer: bytes, - }); + const len = this.numFrames; + if (len === 1 || frame !== undefined) { + return this.decodeFrame(frame ?? 0); + } - this._info = this.readHeader(this.input); - if (this._info === undefined) { + const image = this.decodeFrame(0); + if (image === undefined) { return undefined; } + image.exifData = ExifData.fromInputBuffer( + new InputBuffer({ + buffer: bytes, + }) + ); + image.frameType = FrameType.page; + + for (let i = 1; i < len; ++i) { + const frame = this.decodeFrame(i); + image.addFrame(frame); + } - const image = this._info.images[frame].decodeHdr(this.input); - const buffer = new InputBuffer({ - buffer: bytes, - }); - image.exifData = ExifData.fromInputBuffer(buffer); return image; } } diff --git a/src/formats/tiff-encoder.ts b/src/formats/tiff-encoder.ts index 0491c6c..526ea2f 100644 --- a/src/formats/tiff-encoder.ts +++ b/src/formats/tiff-encoder.ts @@ -1,190 +1,98 @@ /** @format */ -import { FrameAnimation } from '../common/frame-animation'; -import { MemoryImage } from '../common/memory-image'; +import { Format, FormatType } from '../color/format'; import { OutputBuffer } from '../common/output-buffer'; -import { HdrImage } from '../hdr/hdr-image'; -import { HdrSlice } from '../hdr/hdr-slice'; +import { LibError } from '../error/lib-error'; +import { ExifData } from '../exif/exif-data'; +import { IfdUndefinedValue } from '../exif/ifd-value/ifd-undefined-value'; +import { MemoryImage } from '../image/image'; import { Encoder } from './encoder'; -import { TiffEntry } from './tiff/tiff-entry'; -import { TiffImage } from './tiff/tiff-image'; +import { TiffCompression } from './tiff/tiff-compression'; +import { TiffFormat } from './tiff/tiff-format'; +import { TiffPhotometricType } from './tiff/tiff-photometric-type'; /** - * Encode a TIFF image. + * Encode a MemoryImage to the TIFF format. */ export class TiffEncoder implements Encoder { - private static readonly LITTLE_ENDIAN = 0x4949; - private static readonly SIGNATURE = 42; - private _supportsAnimation = false; public get supportsAnimation(): boolean { return this._supportsAnimation; } - private writeHeader(out: OutputBuffer): void { - // byteOrder - out.writeUint16(TiffEncoder.LITTLE_ENDIAN); - // TIFF signature - out.writeUint16(TiffEncoder.SIGNATURE); - // Offset to the start of the IFD tags - out.writeUint32(8); - } - - private writeImage(out: OutputBuffer, image: MemoryImage): void { - // number of IFD entries - out.writeUint16(11); - - this.writeEntryUint32(out, TiffImage.TAG_IMAGE_WIDTH, image.width); - this.writeEntryUint32(out, TiffImage.TAG_IMAGE_LENGTH, image.height); - this.writeEntryUint16(out, TiffImage.TAG_BITS_PER_SAMPLE, 8); - this.writeEntryUint16( - out, - TiffImage.TAG_COMPRESSION, - TiffImage.COMPRESSION_NONE - ); - this.writeEntryUint16( - out, - TiffImage.TAG_PHOTOMETRIC_INTERPRETATION, - TiffImage.PHOTOMETRIC_RGB - ); - this.writeEntryUint16(out, TiffImage.TAG_SAMPLES_PER_PIXEL, 4); - this.writeEntryUint16( - out, - TiffImage.TAG_SAMPLE_FORMAT, - TiffImage.FORMAT_UINT - ); - - this.writeEntryUint32(out, TiffImage.TAG_ROWS_PER_STRIP, image.height); - this.writeEntryUint16(out, TiffImage.TAG_PLANAR_CONFIGURATION, 1); - this.writeEntryUint32( - out, - TiffImage.TAG_STRIP_BYTE_COUNTS, - image.width * image.height * 4 - ); - this.writeEntryUint32(out, TiffImage.TAG_STRIP_OFFSETS, out.length + 4); - out.writeBytes(image.getBytes()); + private getSampleFormat(image: MemoryImage): number { + switch (image.formatType) { + case FormatType.uint: + return TiffFormat.uint; + case FormatType.int: + return TiffFormat.int; + case FormatType.float: + return TiffFormat.float; + } + throw new LibError('Unknown TIFF format type.'); } - private writeHdrImage(out: OutputBuffer, image: HdrImage): void { - // number of IFD entries - out.writeUint16(11); - - this.writeEntryUint32(out, TiffImage.TAG_IMAGE_WIDTH, image.width); - this.writeEntryUint32(out, TiffImage.TAG_IMAGE_LENGTH, image.height); - this.writeEntryUint16( - out, - TiffImage.TAG_BITS_PER_SAMPLE, - image.bitsPerSample - ); - this.writeEntryUint16( - out, - TiffImage.TAG_COMPRESSION, - TiffImage.COMPRESSION_NONE - ); - this.writeEntryUint16( - out, - TiffImage.TAG_PHOTOMETRIC_INTERPRETATION, - image.numberOfChannels === 1 - ? TiffImage.PHOTOMETRIC_BLACKISZERO - : TiffImage.PHOTOMETRIC_RGB - ); - this.writeEntryUint16( - out, - TiffImage.TAG_SAMPLES_PER_PIXEL, - image.numberOfChannels - ); - this.writeEntryUint16( - out, - TiffImage.TAG_SAMPLE_FORMAT, - this.getSampleFormat(image) - ); + public encode(image: MemoryImage, _singleFrame = false): Uint8Array { + let img = image; - const bytesPerSample = Math.trunc(image.bitsPerSample / 8); - const imageSize = - image.width * image.height * image.slices.size * bytesPerSample; + const out = new OutputBuffer(); - this.writeEntryUint32(out, TiffImage.TAG_ROWS_PER_STRIP, image.height); - this.writeEntryUint16(out, TiffImage.TAG_PLANAR_CONFIGURATION, 1); - this.writeEntryUint32(out, TiffImage.TAG_STRIP_BYTE_COUNTS, imageSize); - this.writeEntryUint32(out, TiffImage.TAG_STRIP_OFFSETS, out.length + 4); + // TIFF is really just an EXIF structure (or, really, EXIF is just a TIFF + // structure). - const channels: Uint8Array[] = []; - if (image.blue !== undefined) { - // ? Why does this channel order working but not RGB? - channels.push(image.blue.getBytes()); - } - if (image.red !== undefined) { - channels.push(image.red.getBytes()); - } - if (image.green !== undefined) { - channels.push(image.green.getBytes()); + const exif = new ExifData(); + if (img.exifData.size > 0) { + exif.imageIfd.copyFrom(img.exifData.imageIfd); } - if (image.alpha !== undefined) { - channels.push(image.alpha.getBytes()); - } - if (image.depth !== undefined) { - channels.push(image.depth.getBytes()); + + // TODO: support encoding HDR images to TIFF. + if (img.isHdrFormat) { + img = img.convert({ + format: Format.uint8, + }); } - for (let y = 0, pi = 0; y < image.height; ++y) { - for (let x = 0; x < image.width; ++x, pi += bytesPerSample) { - for (let c = 0; c < channels.length; ++c) { - const ch = channels[c]; - for (let b = 0; b < bytesPerSample; ++b) { - out.writeByte(ch[pi + b]); - } + const type = + img.numChannels === 1 + ? TiffPhotometricType.blackIsZero + : img.hasPalette + ? TiffPhotometricType.palette + : TiffPhotometricType.rgb; + + const nc = img.numChannels; + + const ifd0 = exif.imageIfd; + ifd0.setValue('ImageWidth', img.width); + ifd0.setValue('ImageHeight', img.height); + ifd0.setValue('BitsPerSample', img.bitsPerChannel); + ifd0.setValue('SampleFormat', this.getSampleFormat(img)); + ifd0.setValue('SamplesPerPixel', img.hasPalette ? 1 : nc); + ifd0.setValue('Compression', TiffCompression.none); + ifd0.setValue('PhotometricInterpretation', type); + ifd0.setValue('RowsPerStrip', img.height); + ifd0.setValue('PlanarConfiguration', 1); + ifd0.setValue('TileWidth', img.width); + ifd0.setValue('TileLength', img.height); + ifd0.setValue('StripByteCounts', img.byteLength); + ifd0.setValue('StripOffsets', new IfdUndefinedValue(img.toUint8Array())); + + if (img.hasPalette) { + const p = img.palette!; + // Only support RGB palettes + const numCh = 3; + const numC = p.numColors; + const colorMap = new Uint16Array(numC * numCh); + for (let c = 0, ci = 0; c < numCh; ++c) { + for (let i = 0; i < numC; ++i) { + colorMap[ci++] = Math.trunc(p.get(i, c)) << 8; } } - } - } - private getSampleFormat(image: HdrImage): number { - switch (image.sampleFormat) { - case HdrSlice.UINT: - return TiffImage.FORMAT_UINT; - case HdrSlice.INT: - return TiffImage.FORMAT_INT; + ifd0.setValue('ColorMap', colorMap); } - return TiffImage.FORMAT_FLOAT; - } - - private writeEntryUint16(out: OutputBuffer, tag: number, data: number): void { - out.writeUint16(tag); - out.writeUint16(TiffEntry.TYPE_SHORT); - // number of values - out.writeUint32(1); - out.writeUint16(data); - // pad to 4 bytes - out.writeUint16(0); - } - - private writeEntryUint32(out: OutputBuffer, tag: number, data: number): void { - out.writeUint16(tag); - out.writeUint16(TiffEntry.TYPE_LONG); - // number of values - out.writeUint32(1); - out.writeUint32(data); - } - public encodeImage(image: MemoryImage): Uint8Array { - const out = new OutputBuffer(); - this.writeHeader(out); - this.writeImage(out, image); - // no offset to the next image - out.writeUint32(0); - return out.getBytes(); - } + exif.write(out); - public encodeAnimation(_animation: FrameAnimation): Uint8Array | undefined { - return undefined; - } - - public encodeHdrImage(image: HdrImage): Uint8Array { - const out = new OutputBuffer(); - this.writeHeader(out); - this.writeHdrImage(out, image); - // no offset to the next image - out.writeUint32(0); return out.getBytes(); } } diff --git a/src/formats/tiff/tiff-bit-reader.ts b/src/formats/tiff/tiff-bit-reader.ts index 9199b68..094160f 100644 --- a/src/formats/tiff/tiff-bit-reader.ts +++ b/src/formats/tiff/tiff-bit-reader.ts @@ -3,16 +3,16 @@ import { InputBuffer } from '../../common/input-buffer'; export class TiffBitReader { - private static readonly BITMASK = [0, 1, 3, 7, 15, 31, 63, 127, 255]; + private static readonly _bitMask = [0, 1, 3, 7, 15, 31, 63, 127, 255]; - private bitBuffer = 0; + private _bitBuffer = 0; - private bitPosition = 0; + private _bitPosition = 0; - private input: InputBuffer; + private _input: InputBuffer; constructor(input: InputBuffer) { - this.input = input; + this._input = input; } /** @@ -24,34 +24,34 @@ export class TiffBitReader { return 0; } - if (this.bitPosition === 0) { - this.bitPosition = 8; - this.bitBuffer = this.input.readByte(); + if (this._bitPosition === 0) { + this._bitPosition = 8; + this._bitBuffer = this._input.readByte(); } let value = 0; - while (nBits > this.bitPosition) { + while (nBits > this._bitPosition) { value = - (value << this.bitPosition) + - (this.bitBuffer & TiffBitReader.BITMASK[this.bitPosition]); - nBits -= this.bitPosition; - this.bitPosition = 8; - this.bitBuffer = this.input.readByte(); + (value << this._bitPosition) + + (this._bitBuffer & TiffBitReader._bitMask[this._bitPosition]); + nBits -= this._bitPosition; + this._bitPosition = 8; + this._bitBuffer = this._input.readByte(); } if (nBits > 0) { - if (this.bitPosition === 0) { - this.bitPosition = 8; - this.bitBuffer = this.input.readByte(); + if (this._bitPosition === 0) { + this._bitPosition = 8; + this._bitBuffer = this._input.readByte(); } value = (value << nBits) + - ((this.bitBuffer >> (this.bitPosition - nBits)) & - TiffBitReader.BITMASK[nBits]); + ((this._bitBuffer >> (this._bitPosition - nBits)) & + TiffBitReader._bitMask[nBits]); - this.bitPosition -= nBits; + this._bitPosition -= nBits; } return value; @@ -65,6 +65,6 @@ export class TiffBitReader { * Flush the rest of the bits in the buffer so the next read starts at the next byte. */ public flushByte() { - return (this.bitPosition = 0); + return (this._bitPosition = 0); } } diff --git a/src/formats/tiff/tiff-compression.ts b/src/formats/tiff/tiff-compression.ts new file mode 100644 index 0000000..e8e6a76 --- /dev/null +++ b/src/formats/tiff/tiff-compression.ts @@ -0,0 +1,28 @@ +/** @format */ + +export enum TiffCompression { + none = 1, + ccittRle = 2, + ccittFax3 = 3, + ccittFax4 = 4, + lzw = 5, + oldJpeg = 6, + jpeg = 7, + next = 32766, + ccittRlew = 32771, + packBits = 32773, + thunderScan = 32809, + it8ctpad = 32895, + tt8lw = 32896, + it8mp = 32897, + it8bl = 32898, + pixarFilm = 32908, + pixarLog = 32909, + deflate = 32946, + zip = 8, + dcs = 32947, + jbig = 34661, + sgiLog = 34676, + sgiLog24 = 34677, + jp2000 = 34712, +} diff --git a/src/formats/tiff/tiff-entry.ts b/src/formats/tiff/tiff-entry.ts index ef23357..81091b7 100644 --- a/src/formats/tiff/tiff-entry.ts +++ b/src/formats/tiff/tiff-entry.ts @@ -1,80 +1,54 @@ /** @format */ import { InputBuffer } from '../../common/input-buffer'; -import { ImageError } from '../../error/image-error'; +import { LibError } from '../../error/lib-error'; +import { ExifImageTags } from '../../exif/exif-tag'; +import { IfdValueType, IfdValueTypeSize } from '../../exif/ifd-value-type'; +import { IfdAsciiValue } from '../../exif/ifd-value/ifd-ascii-value'; +import { IfdByteValue } from '../../exif/ifd-value/ifd-byte-value'; +import { IfdDoubleValue } from '../../exif/ifd-value/ifd-double-value'; +import { IfdLongValue } from '../../exif/ifd-value/ifd-long-value'; +import { IfdRationalValue } from '../../exif/ifd-value/ifd-rational-value'; +import { IfdSByteValue } from '../../exif/ifd-value/ifd-sbyte-value'; +import { IfdSingleValue } from '../../exif/ifd-value/ifd-single-value'; +import { IfdSLongValue } from '../../exif/ifd-value/ifd-slong-value'; +import { IfdSRationalValue } from '../../exif/ifd-value/ifd-srational-value'; +import { IfdSShortValue } from '../../exif/ifd-value/ifd-sshort-value'; +import { IfdValue } from '../../exif/ifd-value/ifd-value'; import { TiffImage } from './tiff-image'; export interface TiffEntryInitOptions { tag: number; type: number; - numValues: number; + count: number; p: InputBuffer; + valueOffset: number; } export class TiffEntry { - private static readonly SIZE_OF_TYPE: number[] = [ - // 0 = n/a - 0, - // 1 = byte - 1, - // 2 = ascii - 1, - // 3 = short - 2, - // 4 = long - 4, - // 5 = rational - 8, - // 6 = sbyte - 1, - // 7 = undefined - 1, - // 8 = sshort - 2, - // 9 = slong - 4, - // 10 = srational - 8, - // 11 = float - 4, - // 12 = double - 8, 0, - ]; - - public static readonly TYPE_BYTE = 1; - public static readonly TYPE_ASCII = 2; - public static readonly TYPE_SHORT = 3; - public static readonly TYPE_LONG = 4; - public static readonly TYPE_RATIONAL = 5; - public static readonly TYPE_SBYTE = 6; - public static readonly TYPE_UNDEFINED = 7; - public static readonly TYPE_SSHORT = 8; - public static readonly TYPE_SLONG = 9; - public static readonly TYPE_SRATIONAL = 10; - public static readonly TYPE_FLOAT = 11; - public static readonly TYPE_DOUBLE = 12; - private _tag: number; public get tag(): number { return this._tag; } - private _type: number; - public get type(): number { + private _type: IfdValueType; + public get type(): IfdValueType { return this._type; } - private _numValues: number; - public get numValues(): number { - return this._numValues; + private _count: number; + public get count(): number { + return this._count; } - private _valueOffset: number | undefined; - public get valueOffset(): number | undefined { + private _valueOffset: number; + public get valueOffset(): number { return this._valueOffset; } - public set valueOffset(v: number | undefined) { - this._valueOffset = v; + + private _value: IfdValue | undefined; + public get value(): IfdValue | undefined { + return this._value; } private _p: InputBuffer; @@ -82,120 +56,69 @@ export class TiffEntry { return this._p; } - get isValid(): boolean { - return this._type < 13 && this._type > 0; - } - - get typeSize(): number { - return this.isValid ? TiffEntry.SIZE_OF_TYPE[this._type] : 0; - } - - get isString(): boolean { - return this._type === TiffEntry.TYPE_ASCII; + public get isValid(): boolean { + return this._type !== IfdValueType.none; } - constructor(options: TiffEntryInitOptions) { - this._tag = options.tag; - this._type = options.type; - this._numValues = options.numValues; - this._p = options.p; + public get typeSize(): number { + return this.isValid ? IfdValueTypeSize[this._type] : 0; } - private readValueInternal(): number { - switch (this._type) { - case TiffEntry.TYPE_BYTE: - case TiffEntry.TYPE_ASCII: - return this._p.readByte(); - case TiffEntry.TYPE_SHORT: - return this._p.readUint16(); - case TiffEntry.TYPE_LONG: - return this._p.readUint32(); - case TiffEntry.TYPE_RATIONAL: { - const num = this._p.readUint32(); - const den = this._p.readUint32(); - if (den === 0) { - return 0; - } - return Math.trunc(num / den); - } - case TiffEntry.TYPE_SBYTE: - throw new ImageError('Unhandled value type: SBYTE'); - case TiffEntry.TYPE_UNDEFINED: - return this._p.readByte(); - case TiffEntry.TYPE_SSHORT: - throw new ImageError('Unhandled value type: SSHORT'); - case TiffEntry.TYPE_SLONG: - throw new ImageError('Unhandled value type: SLONG'); - case TiffEntry.TYPE_SRATIONAL: - throw new ImageError('Unhandled value type: SRATIONAL'); - case TiffEntry.TYPE_FLOAT: - throw new ImageError('Unhandled value type: FLOAT'); - case TiffEntry.TYPE_DOUBLE: - throw new ImageError('Unhandled value type: DOUBLE'); - } - return 0; + public get isString(): boolean { + return this._type === IfdValueType.ascii; } - public toString() { - if (TiffImage.TAG_NAME.has(this._tag)) { - return `${TiffImage.TAG_NAME.get(this._tag)}: $type $numValues`; - } - return `<${this._tag}>: ${this._type} ${this._numValues}`; + constructor(opt: TiffEntryInitOptions) { + this._tag = opt.tag; + this._type = opt.type; + this._count = opt.count; + this._p = opt.p; + this._valueOffset = opt.valueOffset; } - public readValue(): number { - this._p.offset = this._valueOffset!; - return this.readValueInternal(); - } - - public readValues(): number[] { - this._p.offset = this._valueOffset!; - const values: number[] = []; - for (let i = 0; i < this._numValues; ++i) { - values.push(this.readValueInternal()); + public read(): IfdValue | undefined { + if (this._value !== undefined) { + return this._value; } - return values; - } - public readString(): string { - if (this._type !== TiffEntry.TYPE_ASCII) { - throw new ImageError('readString requires ASCII entity'); + this._p.offset = this._valueOffset; + const data = this.p.readBytes(this._count * this.typeSize); + switch (this._type) { + case IfdValueType.byte: + return (this._value = IfdByteValue.data(data, this._count)); + case IfdValueType.ascii: + return (this._value = IfdAsciiValue.data(data, this._count)); + case IfdValueType.undefined: + return (this._value = IfdByteValue.data(data, this._count)); + case IfdValueType.short: + return (this._value = IfdSShortValue.data(data, this._count)); + case IfdValueType.long: + return (this._value = IfdLongValue.data(data, this._count)); + case IfdValueType.rational: + return (this._value = IfdRationalValue.data(data, this._count)); + case IfdValueType.single: + return (this._value = IfdSingleValue.data(data, this._count)); + case IfdValueType.double: + return (this._value = IfdDoubleValue.data(data, this._count)); + case IfdValueType.sByte: + return (this._value = IfdSByteValue.data(data, this._count)); + case IfdValueType.sShort: + return (this._value = IfdSShortValue.data(data, this._count)); + case IfdValueType.sLong: + return (this._value = IfdSLongValue.data(data, this._count)); + case IfdValueType.sRational: + return (this._value = IfdSRationalValue.data(data, this._count)); + default: + case IfdValueType.none: + return undefined; } - // TODO: ASCII fields can contain multiple strings, separated with a NULL. - return String.fromCharCode(...this.readValues()); } - public read(): number[] { - this._p.offset = this._valueOffset!; - const values: number[] = []; - for (let i = 0; i < this._numValues; ++i) { - switch (this._type) { - case TiffEntry.TYPE_BYTE: - case TiffEntry.TYPE_ASCII: - values.push(this._p.readByte()); - break; - case TiffEntry.TYPE_SHORT: - values.push(this._p.readUint16()); - break; - case TiffEntry.TYPE_LONG: - values.push(this._p.readUint32()); - break; - case TiffEntry.TYPE_RATIONAL: { - const num = this._p.readUint32(); - const den = this._p.readUint32(); - if (den !== 0) { - values.push(num / den); - } - break; - } - case TiffEntry.TYPE_FLOAT: - values.push(this._p.readFloat32()); - break; - case TiffEntry.TYPE_DOUBLE: - values.push(this._p.readFloat64()); - break; - } + public toString(): string { + const exifTag = ExifImageTags.get(this._tag); + if (exifTag !== undefined) { + return `${exifTag.name}: ${this._type} ${this._count}`; } - return values; + return `${this.constructor.name} (<${this._tag}>: ${this._type} ${this._count})`; } } diff --git a/src/formats/tiff/tiff-fax-decoder.ts b/src/formats/tiff/tiff-fax-decoder.ts index cf65cf9..cfc25a8 100644 --- a/src/formats/tiff/tiff-fax-decoder.ts +++ b/src/formats/tiff/tiff-fax-decoder.ts @@ -1,7 +1,7 @@ /** @format */ import { InputBuffer } from '../../common/input-buffer'; -import { ImageError } from '../../error/image-error'; +import { LibError } from '../../error/lib-error'; export interface TiffFaxDecoderInitOptions { fillOrder: number; @@ -10,7 +10,7 @@ export interface TiffFaxDecoderInitOptions { } export class TiffFaxDecoder { - private static readonly TABLE1: number[] = [ + private static readonly _table1: number[] = [ // 0 bits are left in first byte - SHOULD NOT HAPPEN 0x00, // 1 bits are left in first byte @@ -31,7 +31,7 @@ export class TiffFaxDecoder { 0xff, ]; - private static readonly TABLE2: number[] = [ + private static readonly _table2: number[] = [ // 0 0x00, // 1 @@ -55,7 +55,7 @@ export class TiffFaxDecoder { /** * Table to be used when **fillOrder** = 2, for flipping bytes. */ - private static readonly FLIP_TABLE: number[] = [ + private static readonly _flipTable: number[] = [ 0, -128, 64, -64, 32, -96, 96, -32, 16, -112, 80, -48, 48, -80, 112, -16, 8, -120, 72, -56, 40, -88, 104, -24, 24, -104, 88, -40, 56, -72, 120, -8, 4, -124, 68, -60, 36, -92, 100, -28, 20, -108, 84, -44, 52, -76, 116, -12, 12, @@ -77,7 +77,7 @@ export class TiffFaxDecoder { /** * The main 10 bit white runs lookup table */ - private static readonly WHITE: number[] = [ + private static readonly _white: number[] = [ // 0 - 7 6430, 6400, 6400, 6400, 3225, 3225, 3225, 3225, // 8 - 15 @@ -339,7 +339,7 @@ export class TiffFaxDecoder { /** * Additional make up codes for both White and Black runs */ - private static readonly ADDITIONAL_MAKEUP: number[] = [ + private static readonly _additionalMakeup: number[] = [ 28679, 28679, 31752, -32759, -31735, -30711, -29687, -28663, 29703, 29703, 30727, 30727, -27639, -26615, -25591, -24567, ]; @@ -347,19 +347,19 @@ export class TiffFaxDecoder { /** * Initial black run look up table, uses the first 4 bits of a code */ - private static readonly INIT_BLACK: number[] = [ + private static readonly _initBlack: number[] = [ // 0 - 7 3226, 6412, 200, 168, 38, 38, 134, 134, // 8 - 15 100, 100, 100, 100, 68, 68, 68, 68, ]; - private static readonly TWO_BIT_BLACK: number[] = [292, 260, 226, 226]; + private static readonly _twoBitBlack: number[] = [292, 260, 226, 226]; /** * Main black run table, using the last 9 bits of possible 13 bit code */ - private static readonly BLACK: number[] = [ + private static readonly _black: number[] = [ // 0 - 7 62, 62, 30, 30, 0, 0, 0, 0, // 8 - 15 @@ -490,7 +490,7 @@ export class TiffFaxDecoder { 390, 390, 390, 390, 390, 390, 390, 390, ]; - private static readonly TWO_D_CODES: number[] = [ + private static readonly _twoDCodes: number[] = [ // 0 - 7 80, 88, 23, 71, 30, 30, 62, 62, // 8 - 15 @@ -542,71 +542,71 @@ export class TiffFaxDecoder { // Data structures needed to store changing elements for the previous // and the current scanline - private changingElemSize = 0; - private prevChangingElems?: Array; - private currChangingElems?: Array; - private data!: InputBuffer; - private bitPointer = 0; - private bytePointer = 0; + private _changingElemSize = 0; + private _prevChangingElements?: Array; + private _currChangingElements?: Array; + private _data!: InputBuffer; + private _bitPointer = 0; + private _bytePointer = 0; // Element at which to start search in getNextChangingElement - private lastChangingElement = 0; - private compression = 2; + private _lastChangingElement = 0; + private _compression = 2; // Variables set by T4Options - // @ts-ignore - private uncompressedMode = 0; - private fillBits = 0; - private oneD = 0; - - constructor(options: TiffFaxDecoderInitOptions) { - this._fillOrder = options.fillOrder; - this._width = options.width; - this._height = options.height; - this.prevChangingElems = new Array(this._width); - this.prevChangingElems.fill(0); - this.currChangingElems = new Array(this._width); - this.currChangingElems.fill(0); + private _uncompressedMode = 0; + private _fillBits = 0; + private _oneD = 0; + + constructor(opt: TiffFaxDecoderInitOptions) { + this._fillOrder = opt.fillOrder; + this._width = opt.width; + this._height = opt.height; + this._prevChangingElements = new Array(this._width); + this._prevChangingElements.fill(0); + this._currChangingElements = new Array(this._width); + this._currChangingElements.fill(0); } private nextNBits(bitsToGet: number): number { let b = 0; let next = 0; let next2next = 0; - const l = this.data.length - 1; - const bp = this.bytePointer; + const l = this._data.length - 1; + const bp = this._bytePointer; if (this._fillOrder === 1) { - b = this.data.getByte(bp); + b = this._data.getByte(bp); if (bp === l) { next = 0x00; next2next = 0x00; } else if (bp + 1 === l) { - next = this.data.getByte(bp + 1); + next = this._data.getByte(bp + 1); next2next = 0x00; } else { - next = this.data.getByte(bp + 1); - next2next = this.data.getByte(bp + 2); + next = this._data.getByte(bp + 1); + next2next = this._data.getByte(bp + 2); } } else if (this._fillOrder === 2) { - b = TiffFaxDecoder.FLIP_TABLE[this.data.getByte(bp) & 0xff]; + b = TiffFaxDecoder._flipTable[this._data.getByte(bp) & 0xff]; if (bp === l) { next = 0x00; next2next = 0x00; } else if (bp + 1 === l) { - next = TiffFaxDecoder.FLIP_TABLE[this.data.getByte(bp + 1) & 0xff]; + next = TiffFaxDecoder._flipTable[this._data.getByte(bp + 1) & 0xff]; next2next = 0x00; } else { - next = TiffFaxDecoder.FLIP_TABLE[this.data.getByte(bp + 1) & 0xff]; - next2next = TiffFaxDecoder.FLIP_TABLE[this.data.getByte(bp + 2) & 0xff]; + next = TiffFaxDecoder._flipTable[this._data.getByte(bp + 1) & 0xff]; + next2next = + TiffFaxDecoder._flipTable[this._data.getByte(bp + 2) & 0xff]; } } else { - throw new ImageError('TIFFFaxDecoder7'); + throw new LibError('TIFFFaxDecoder7'); } - const bitsLeft = 8 - this.bitPointer; + const bitsLeft = 8 - this._bitPointer; let bitsFromNextByte = bitsToGet - bitsLeft; let bitsFromNext2NextByte = 0; if (bitsFromNextByte > 8) { @@ -614,28 +614,28 @@ export class TiffFaxDecoder { bitsFromNextByte = 8; } - this.bytePointer = this.bytePointer! + 1; + this._bytePointer = this._bytePointer! + 1; - const i1 = (b & TiffFaxDecoder.TABLE1[bitsLeft]) << (bitsToGet - bitsLeft); + const i1 = (b & TiffFaxDecoder._table1[bitsLeft]) << (bitsToGet - bitsLeft); let i2 = - (next & TiffFaxDecoder.TABLE2[bitsFromNextByte]) >> + (next & TiffFaxDecoder._table2[bitsFromNextByte]) >> (8 - bitsFromNextByte); let i3 = 0; if (bitsFromNext2NextByte !== 0) { i2 <<= bitsFromNext2NextByte; i3 = - (next2next & TiffFaxDecoder.TABLE2[bitsFromNext2NextByte]) >> + (next2next & TiffFaxDecoder._table2[bitsFromNext2NextByte]) >> (8 - bitsFromNext2NextByte); i2 |= i3; - this.bytePointer += 1; - this.bitPointer = bitsFromNext2NextByte; + this._bytePointer += 1; + this._bitPointer = bitsFromNext2NextByte; } else { if (bitsFromNextByte === 8) { - this.bitPointer = 0; - this.bytePointer += 1; + this._bitPointer = 0; + this._bytePointer += 1; } else { - this.bitPointer = bitsFromNextByte; + this._bitPointer = bitsFromNextByte; } } @@ -645,49 +645,49 @@ export class TiffFaxDecoder { private nextLesserThan8Bits(bitsToGet: number): number { let b = 0; let next = 0; - const l = this.data.length - 1; - const bp = this.bytePointer; + const l = this._data.length - 1; + const bp = this._bytePointer; if (this._fillOrder === 1) { - b = this.data.getByte(bp); + b = this._data.getByte(bp); if (bp === l) { next = 0x00; } else { - next = this.data.getByte(bp + 1); + next = this._data.getByte(bp + 1); } } else if (this._fillOrder === 2) { - b = TiffFaxDecoder.FLIP_TABLE[this.data.getByte(bp) & 0xff]; + b = TiffFaxDecoder._flipTable[this._data.getByte(bp) & 0xff]; if (bp === l) { next = 0x00; } else { - next = TiffFaxDecoder.FLIP_TABLE[this.data.getByte(bp + 1) & 0xff]; + next = TiffFaxDecoder._flipTable[this._data.getByte(bp + 1) & 0xff]; } } else { - throw new ImageError('TIFFFaxDecoder7'); + throw new LibError('TIFFFaxDecoder7'); } - const bitsLeft = 8 - this.bitPointer; + const bitsLeft = 8 - this._bitPointer; const bitsFromNextByte = bitsToGet - bitsLeft; const shift = bitsLeft - bitsToGet; let i1 = 0; let i2 = 0; if (shift >= 0) { - i1 = (b & TiffFaxDecoder.TABLE1[bitsLeft]) >> shift; - this.bitPointer += bitsToGet; - if (this.bitPointer === 8) { - this.bitPointer = 0; - this.bytePointer += 1; + i1 = (b & TiffFaxDecoder._table1[bitsLeft]) >> shift; + this._bitPointer += bitsToGet; + if (this._bitPointer === 8) { + this._bitPointer = 0; + this._bytePointer += 1; } } else { - i1 = (b & TiffFaxDecoder.TABLE1[bitsLeft]) << -shift; + i1 = (b & TiffFaxDecoder._table1[bitsLeft]) << -shift; i2 = - (next & TiffFaxDecoder.TABLE2[bitsFromNextByte]) >> + (next & TiffFaxDecoder._table2[bitsFromNextByte]) >> (8 - bitsFromNextByte); i1 |= i2; - this.bytePointer += 1; - this.bitPointer = bitsFromNextByte; + this._bytePointer += 1; + this._bitPointer = bitsFromNextByte; } return i1; @@ -697,13 +697,13 @@ export class TiffFaxDecoder { * Move pointer backwards by given amount of bits */ private updatePointer(bitsToMoveBack: number): void { - const i = this.bitPointer - bitsToMoveBack; + const i = this._bitPointer - bitsToMoveBack; if (i < 0) { - this.bytePointer -= 1; - this.bitPointer = 8 + i; + this._bytePointer -= 1; + this._bitPointer = 8 + i; } else { - this.bitPointer = i; + this._bitPointer = i; } } @@ -711,9 +711,9 @@ export class TiffFaxDecoder { * Move to the next byte boundary */ private advancePointer(): boolean { - if (this.bitPointer !== 0) { - this.bytePointer += 1; - this.bitPointer = 0; + if (this._bitPointer !== 0) { + this._bytePointer += 1; + this._bitPointer = 0; } return true; @@ -776,14 +776,14 @@ export class TiffFaxDecoder { let isWhite = true; // Initialize starting of the changing elements array - this.changingElemSize = 0; + this._changingElemSize = 0; // While scanline not complete while (offset < this._width) { while (isWhite) { // White run current = this.nextNBits(10); - entry = TiffFaxDecoder.WHITE[current]; + entry = TiffFaxDecoder._white[current]; // Get the 3 fields from the entry isT = entry & 0x0001; @@ -795,7 +795,7 @@ export class TiffFaxDecoder { twoBits = this.nextLesserThan8Bits(2); // Consolidate the 2 bits and last 2 bits into 4 bits current = ((current << 2) & 0x000c) | twoBits; - entry = TiffFaxDecoder.ADDITIONAL_MAKEUP[current]; + entry = TiffFaxDecoder._additionalMakeup[current]; // 3 bits 0000 0111 bits = (entry >> 1) & 0x07; // 12 bits @@ -806,10 +806,10 @@ export class TiffFaxDecoder { this.updatePointer(4 - bits); } else if (bits === 0) { // ERROR - throw new ImageError('TIFFFaxDecoder0'); + throw new LibError('TIFFFaxDecoder0'); } else if (bits === 15) { // EOL - throw new ImageError('TIFFFaxDecoder1'); + throw new LibError('TIFFFaxDecoder1'); } else { // 11 bits - 0000 0111 1111 1111 = 0x07ff code = (entry >> 5) & 0x07ff; @@ -818,7 +818,7 @@ export class TiffFaxDecoder { this.updatePointer(10 - bits); if (isT === 0) { isWhite = false; - this.currChangingElems![this.changingElemSize++] = offset; + this._currChangingElements![this._changingElemSize++] = offset; } } } @@ -826,7 +826,7 @@ export class TiffFaxDecoder { // Check whether this run completed one width, if so // advance to next byte boundary for compression = 2. if (offset === this._width) { - if (this.compression === 2) { + if (this._compression === 2) { this.advancePointer(); } break; @@ -835,7 +835,7 @@ export class TiffFaxDecoder { while (isWhite === false) { // Black run current = this.nextLesserThan8Bits(4); - entry = TiffFaxDecoder.INIT_BLACK[current]; + entry = TiffFaxDecoder._initBlack[current]; // Get the 3 fields from the entry isT = entry & 0x0001; @@ -844,7 +844,7 @@ export class TiffFaxDecoder { if (code === 100) { current = this.nextNBits(9); - entry = TiffFaxDecoder.BLACK[current]; + entry = TiffFaxDecoder._black[current]; // Get the 3 fields from the entry isT = entry & 0x0001; @@ -855,7 +855,7 @@ export class TiffFaxDecoder { // Additional makeup codes this.updatePointer(5); current = this.nextLesserThan8Bits(4); - entry = TiffFaxDecoder.ADDITIONAL_MAKEUP[current]; + entry = TiffFaxDecoder._additionalMakeup[current]; // 3 bits 0000 0111 bits = (entry >> 1) & 0x07; // 12 bits @@ -867,7 +867,7 @@ export class TiffFaxDecoder { this.updatePointer(4 - bits); } else if (bits === 15) { // EOL code - throw new ImageError('TIFFFaxDecoder2'); + throw new LibError('TIFFFaxDecoder2'); } else { this.setToBlack(buffer, lineOffset, offset, code); offset += code; @@ -875,13 +875,13 @@ export class TiffFaxDecoder { this.updatePointer(9 - bits); if (isT === 0) { isWhite = true; - this.currChangingElems![this.changingElemSize++] = offset; + this._currChangingElements![this._changingElemSize++] = offset; } } } else if (code === 200) { // Is a Terminating code current = this.nextLesserThan8Bits(2); - entry = TiffFaxDecoder.TWO_BIT_BLACK[current]; + entry = TiffFaxDecoder._twoBitBlack[current]; code = (entry >> 5) & 0x07ff; bits = (entry >> 1) & 0x0f; @@ -890,7 +890,7 @@ export class TiffFaxDecoder { this.updatePointer(2 - bits); isWhite = true; - this.currChangingElems![this.changingElemSize++] = offset; + this._currChangingElements![this._changingElemSize++] = offset; } else { // Is a Terminating code this.setToBlack(buffer, lineOffset, offset, code); @@ -898,35 +898,35 @@ export class TiffFaxDecoder { this.updatePointer(4 - bits); isWhite = true; - this.currChangingElems![this.changingElemSize++] = offset; + this._currChangingElements![this._changingElemSize++] = offset; } } // Check whether this run completed one width if (offset === this._width) { - if (this.compression === 2) { + if (this._compression === 2) { this.advancePointer(); } break; } } - this.currChangingElems![this.changingElemSize++] = offset; + this._currChangingElements![this._changingElemSize++] = offset; } private readEOL(): number { - if (this.fillBits === 0) { + if (this._fillBits === 0) { if (this.nextNBits(12) !== 1) { - throw new ImageError('TIFFFaxDecoder6'); + throw new LibError('TIFFFaxDecoder6'); } - } else if (this.fillBits === 1) { + } else if (this._fillBits === 1) { // First EOL code word xxxx 0000 0000 0001 will occur // As many fill bits will be present as required to make // the EOL code of 12 bits end on a byte boundary. - const bitsLeft = 8 - this.bitPointer; + const bitsLeft = 8 - this._bitPointer; if (this.nextNBits(bitsLeft) !== 0) { - throw new ImageError('TIFFFaxDecoder8'); + throw new LibError('TIFFFaxDecoder8'); } // If the number of bitsLeft is less than 8, then to have a 12 @@ -935,7 +935,7 @@ export class TiffFaxDecoder { // that. if (bitsLeft < 4) { if (this.nextNBits(8) !== 0) { - throw new ImageError('TIFFFaxDecoder8'); + throw new LibError('TIFFFaxDecoder8'); } } @@ -946,13 +946,13 @@ export class TiffFaxDecoder { while ((n = this.nextNBits(8)) !== 1) { // If not all zeros if (n !== 0) { - throw new ImageError('TIFFFaxDecoder8'); + throw new LibError('TIFFFaxDecoder8'); } } } // If one dimensional encoding mode, then always return 1 - if (this.oneD === 0) { + if (this._oneD === 0) { return 1; } else { // Otherwise for 2D encoding mode, @@ -967,13 +967,14 @@ export class TiffFaxDecoder { ret: Array ): void { // Local copies of instance variables - const pce = this.prevChangingElems; - const ces = this.changingElemSize; + const pce = this._prevChangingElements; + const ces = this._changingElemSize; // If the previous match was at an odd element, we still // have to search the preceeding element. // int start = lastChangingElement & ~0x1; - let start = this.lastChangingElement > 0 ? this.lastChangingElement - 1 : 0; + let start = + this._lastChangingElement > 0 ? this._lastChangingElement - 1 : 0; if (isWhite) { // Search even numbered elements start &= ~0x1; @@ -986,7 +987,7 @@ export class TiffFaxDecoder { for (; i < ces; i += 2) { const temp = pce![i]!; if (temp > a0!) { - this.lastChangingElement = i; + this._lastChangingElement = i; ret[0] = temp; break; } @@ -1012,7 +1013,7 @@ export class TiffFaxDecoder { while (isWhite) { current = this.nextNBits(10); - entry = TiffFaxDecoder.WHITE[current]; + entry = TiffFaxDecoder._white[current]; // Get the 3 fields from the entry isT = entry & 0x0001; @@ -1024,7 +1025,7 @@ export class TiffFaxDecoder { twoBits = this.nextLesserThan8Bits(2); // Consolidate the 2 new bits and last 2 bits into 4 bits current = ((current << 2) & 0x000c) | twoBits; - entry = TiffFaxDecoder.ADDITIONAL_MAKEUP[current]; + entry = TiffFaxDecoder._additionalMakeup[current]; // 3 bits 0000 0111 bits = (entry >> 1) & 0x07; // 12 bits @@ -1033,10 +1034,10 @@ export class TiffFaxDecoder { this.updatePointer(4 - bits); } else if (bits === 0) { // ERROR - throw new ImageError('TIFFFaxDecoder0'); + throw new LibError('TIFFFaxDecoder0'); } else if (bits === 15) { // EOL - throw new ImageError('TIFFFaxDecoder1'); + throw new LibError('TIFFFaxDecoder1'); } else { // 11 bits - 0000 0111 1111 1111 = 0x07ff code = (entry >> 5) & 0x07ff; @@ -1065,7 +1066,7 @@ export class TiffFaxDecoder { while (!isWhite) { current = this.nextLesserThan8Bits(4); - entry = TiffFaxDecoder.INIT_BLACK[current]; + entry = TiffFaxDecoder._initBlack[current]; // Get the 3 fields from the entry isT = entry & 0x0001; @@ -1074,7 +1075,7 @@ export class TiffFaxDecoder { if (code === 100) { current = this.nextNBits(9); - entry = TiffFaxDecoder.BLACK[current]; + entry = TiffFaxDecoder._black[current]; // Get the 3 fields from the entry isT = entry & 0x0001; @@ -1085,7 +1086,7 @@ export class TiffFaxDecoder { // Additional makeup codes this.updatePointer(5); current = this.nextLesserThan8Bits(4); - entry = TiffFaxDecoder.ADDITIONAL_MAKEUP[current]; + entry = TiffFaxDecoder._additionalMakeup[current]; // 3 bits 0000 0111 bits = (entry >> 1) & 0x07; // 12 bits @@ -1095,7 +1096,7 @@ export class TiffFaxDecoder { this.updatePointer(4 - bits); } else if (bits === 15) { // EOL code - throw new ImageError('TIFFFaxDecoder2'); + throw new LibError('TIFFFaxDecoder2'); } else { runLength += code; this.updatePointer(9 - bits); @@ -1106,7 +1107,7 @@ export class TiffFaxDecoder { } else if (code === 200) { // Is a Terminating code current = this.nextLesserThan8Bits(2); - entry = TiffFaxDecoder.TWO_BIT_BLACK[current]; + entry = TiffFaxDecoder._twoBitBlack[current]; code = (entry >> 5) & 0x07ff; runLength += code; bits = (entry >> 1) & 0x0f; @@ -1132,9 +1133,9 @@ export class TiffFaxDecoder { startX: number, height: number ): void { - this.data = compData; - this.bitPointer = 0; - this.bytePointer = 0; + this._data = compData; + this._bitPointer = 0; + this._bytePointer = 0; let lineOffset = 0; const scanlineStride = Math.trunc((this._width + 7) / 8); @@ -1155,11 +1156,11 @@ export class TiffFaxDecoder { height: number, tiffT4Options: number ): void { - this.data = compData; - this.compression = 3; + this._data = compData; + this._compression = 3; - this.bitPointer = 0; - this.bytePointer = 0; + this._bitPointer = 0; + this._bytePointer = 0; const scanlineStride = Math.trunc((this._width + 7) / 8); @@ -1179,13 +1180,13 @@ export class TiffFaxDecoder { // 1D/2D encoding - dealt with this in readEOL // uncompressedMode - haven't dealt with this yet. - this.oneD = tiffT4Options & 0x01; - this.uncompressedMode = (tiffT4Options & 0x02) >> 1; - this.fillBits = (tiffT4Options & 0x04) >> 2; + this._oneD = tiffT4Options & 0x01; + this._uncompressedMode = (tiffT4Options & 0x02) >> 1; + this._fillBits = (tiffT4Options & 0x04) >> 2; // The data must start with an EOL code if (this.readEOL() !== 1) { - throw new ImageError('TIFFFaxDecoder3'); + throw new LibError('TIFFFaxDecoder3'); } let lineOffset = 0; @@ -1204,9 +1205,9 @@ export class TiffFaxDecoder { // Initialize previous scanlines changing elements, and // initialize current scanline's changing elements array - temp = this.prevChangingElems; - this.prevChangingElems = this.currChangingElems; - this.currChangingElems = temp; + temp = this._prevChangingElements; + this._prevChangingElements = this._currChangingElements; + this._currChangingElements = temp; currIndex = 0; // a0 has to be set just before the start of this scanline. @@ -1214,7 +1215,7 @@ export class TiffFaxDecoder { isWhite = true; bitOffset = startX; - this.lastChangingElement = 0; + this._lastChangingElement = 0; while (bitOffset < this._width) { // Get the next changing element @@ -1227,7 +1228,7 @@ export class TiffFaxDecoder { entry = this.nextLesserThan8Bits(7); // Run these through the 2DCodes table - entry = TiffFaxDecoder.TWO_D_CODES[entry] & 0xff; + entry = TiffFaxDecoder._twoDCodes[entry] & 0xff; // Get the code and the number of bits used up code = (entry & 0x78) >> 3; @@ -1251,21 +1252,21 @@ export class TiffFaxDecoder { if (isWhite) { number = this.decodeWhiteCodeWord(); bitOffset += number; - this.currChangingElems![currIndex++] = bitOffset; + this._currChangingElements![currIndex++] = bitOffset; number = this.decodeBlackCodeWord(); this.setToBlack(out, lineOffset, bitOffset, number); bitOffset += number; - this.currChangingElems![currIndex++] = bitOffset; + this._currChangingElements![currIndex++] = bitOffset; } else { number = this.decodeBlackCodeWord(); this.setToBlack(out, lineOffset, bitOffset, number); bitOffset += number; - this.currChangingElems![currIndex++] = bitOffset; + this._currChangingElements![currIndex++] = bitOffset; number = this.decodeWhiteCodeWord(); bitOffset += number; - this.currChangingElems![currIndex++] = bitOffset; + this._currChangingElements![currIndex++] = bitOffset; } a0 = bitOffset; @@ -1273,7 +1274,7 @@ export class TiffFaxDecoder { // Vertical a1 = b1 + (code - 5); - this.currChangingElems![currIndex++] = a1; + this._currChangingElements![currIndex++] = a1; // We write the current color till a1 - 1 pos, // since a1 is where the next color starts @@ -1286,14 +1287,14 @@ export class TiffFaxDecoder { this.updatePointer(7 - bits); } else { - throw new ImageError('TIFFFaxDecoder4'); + throw new LibError('TIFFFaxDecoder4'); } } // Add the changing element beyond the current scanline for the // other color too - this.currChangingElems![currIndex++] = bitOffset; - this.changingElemSize = currIndex; + this._currChangingElements![currIndex++] = bitOffset; + this._changingElemSize = currIndex; } else { // 1D encoded scanline follows this.decodeNextScanline(out, lineOffset, startX); @@ -1310,11 +1311,11 @@ export class TiffFaxDecoder { height: number, tiffT6Options: number ): void { - this.data = compData; - this.compression = 4; + this._data = compData; + this._compression = 4; - this.bitPointer = 0; - this.bytePointer = 0; + this._bitPointer = 0; + this._bytePointer = 0; const scanlineStride = Math.trunc((this._width + 7) / 8); @@ -1333,17 +1334,17 @@ export class TiffFaxDecoder { const b = new Array(2); b.fill(0); - this.uncompressedMode = (tiffT6Options & 0x02) >> 1; + this._uncompressedMode = (tiffT6Options & 0x02) >> 1; // Local cached reference - let cce = this.currChangingElems!; + let cce = this._currChangingElements!; // Assume invisible preceding row of all white pixels and insert // both black and white changing elements beyond the end of this // imaginary scanline. - this.changingElemSize = 0; - cce[this.changingElemSize++] = this._width; - cce[this.changingElemSize++] = this._width; + this._changingElemSize = 0; + cce[this._changingElemSize++] = this._width; + cce[this._changingElemSize++] = this._width; let lineOffset = 0; let bitOffset = 0; @@ -1356,16 +1357,16 @@ export class TiffFaxDecoder { // Assign the changing elements of the previous scanline to // prevChangingElems and start putting this new scanline's // changing elements into the currChangingElems. - temp = this.prevChangingElems; - this.prevChangingElems = this.currChangingElems; - cce = (this.currChangingElems = temp)!; + temp = this._prevChangingElements; + this._prevChangingElements = this._currChangingElements; + cce = (this._currChangingElements = temp)!; currIndex = 0; // Start decoding the scanline at startX in the raster bitOffset = startX; // Reset search start position for getNextChangingElement - this.lastChangingElement = 0; + this._lastChangingElement = 0; // Till one whole scanline is decoded while (bitOffset < this._width) { @@ -1377,7 +1378,7 @@ export class TiffFaxDecoder { // Get the next seven bits entry = this.nextLesserThan8Bits(7); // Run these through the 2DCodes table - entry = TiffFaxDecoder.TWO_D_CODES[entry] & 0xff; + entry = TiffFaxDecoder._twoDCodes[entry] & 0xff; // Get the code and the number of bits used up code = (entry & 0x78) >> 3; @@ -1441,7 +1442,7 @@ export class TiffFaxDecoder { this.updatePointer(7 - bits); } else if (code === 11) { if (this.nextLesserThan8Bits(3) !== 7) { - throw new ImageError('TIFFFaxDecoder5'); + throw new LibError('TIFFFaxDecoder5'); } let zeros = 0; @@ -1506,7 +1507,7 @@ export class TiffFaxDecoder { } } } else { - throw new ImageError(`TIFFFaxDecoder5 ${code}`); + throw new LibError(`TIFFFaxDecoder5 ${code}`); } } @@ -1515,7 +1516,7 @@ export class TiffFaxDecoder { cce[currIndex++] = bitOffset; // Number of changing elements in this scanline. - this.changingElemSize = currIndex; + this._changingElemSize = currIndex; lineOffset += scanlineStride; } diff --git a/src/formats/tiff/tiff-format.ts b/src/formats/tiff/tiff-format.ts new file mode 100644 index 0000000..f13055a --- /dev/null +++ b/src/formats/tiff/tiff-format.ts @@ -0,0 +1,8 @@ +/** @format */ + +export enum TiffFormat { + invalid, + uint, + int, + float, +} diff --git a/src/formats/tiff/tiff-image-type.ts b/src/formats/tiff/tiff-image-type.ts new file mode 100644 index 0000000..64ec5d0 --- /dev/null +++ b/src/formats/tiff/tiff-image-type.ts @@ -0,0 +1,14 @@ +/** @format */ + +export enum TiffImageType { + bilevel, + gray4bit, + gray, + grayAlpha, + palette, + rgb, + rgba, + yCbCrSub, + generic, + invalid, +} diff --git a/src/formats/tiff/tiff-image.ts b/src/formats/tiff/tiff-image.ts index 7f6ef0c..f8e3c08 100644 --- a/src/formats/tiff/tiff-image.ts +++ b/src/formats/tiff/tiff-image.ts @@ -1,179 +1,30 @@ /** @format */ import { inflate } from 'uzip'; -import { BitOperators } from '../../common/bit-operators'; -import { Color } from '../../common/color'; +import { ColorUtils } from '../../color/color-utils'; +import { Format } from '../../color/format'; +import { ArrayUtils } from '../../common/array-utils'; +import { BitUtils } from '../../common/bit-utils'; +import { Float16 } from '../../common/float16'; import { InputBuffer } from '../../common/input-buffer'; -import { MathOperators } from '../../common/math-operators'; -import { MemoryImage } from '../../common/memory-image'; -import { ImageError } from '../../error/image-error'; -import { Half } from '../../hdr/half'; -import { HdrImage } from '../../hdr/hdr-image'; -import { HdrSlice } from '../../hdr/hdr-slice'; +import { LibError } from '../../error/lib-error'; +import { ExifTagNameToID } from '../../exif/exif-tag'; +import { IfdValueType, IfdValueTypeSize } from '../../exif/ifd-value-type'; +import { MemoryImage } from '../../image/image'; import { JpegDecoder } from '../jpeg-decoder'; import { TiffBitReader } from './tiff-bit-reader'; +import { TiffCompression } from './tiff-compression'; import { TiffEntry } from './tiff-entry'; import { TiffFaxDecoder } from './tiff-fax-decoder'; +import { TiffFormat } from './tiff-format'; +import { TiffImageType } from './tiff-image-type'; import { LzwDecoder } from './tiff-lzw-decoder'; +import { + TiffPhotometricType, + TiffPhotometricTypeLength, +} from './tiff-photometric-type'; export class TiffImage { - // Compression types - public static readonly COMPRESSION_NONE = 1; - public static readonly COMPRESSION_CCITT_RLE = 2; - public static readonly COMPRESSION_CCITT_FAX3 = 3; - public static readonly COMPRESSION_CCITT_FAX4 = 4; - public static readonly COMPRESSION_LZW = 5; - public static readonly COMPRESSION_OLD_JPEG = 6; - public static readonly COMPRESSION_JPEG = 7; - public static readonly COMPRESSION_NEXT = 32766; - public static readonly COMPRESSION_CCITT_RLEW = 32771; - public static readonly COMPRESSION_PACKBITS = 32773; - public static readonly COMPRESSION_THUNDERSCAN = 32809; - public static readonly COMPRESSION_IT8CTPAD = 32895; - public static readonly COMPRESSION_IT8LW = 32896; - public static readonly COMPRESSION_IT8MP = 32897; - public static readonly COMPRESSION_IT8BL = 32898; - public static readonly COMPRESSION_PIXARFILM = 32908; - public static readonly COMPRESSION_PIXARLOG = 32909; - public static readonly COMPRESSION_DEFLATE = 32946; - public static readonly COMPRESSION_ZIP = 8; - public static readonly COMPRESSION_DCS = 32947; - public static readonly COMPRESSION_JBIG = 34661; - public static readonly COMPRESSION_SGILOG = 34676; - public static readonly COMPRESSION_SGILOG24 = 34677; - public static readonly COMPRESSION_JP2000 = 34712; - - // Photometric types - public static readonly PHOTOMETRIC_BLACKISZERO = 1; - public static readonly PHOTOMETRIC_RGB = 2; - - // Image types - public static readonly TYPE_UNSUPPORTED = -1; - public static readonly TYPE_BILEVEL = 0; - public static readonly TYPE_GRAY_4BIT = 1; - public static readonly TYPE_GRAY = 2; - public static readonly TYPE_GRAY_ALPHA = 3; - public static readonly TYPE_PALETTE = 4; - public static readonly TYPE_RGB = 5; - public static readonly TYPE_RGB_ALPHA = 6; - public static readonly TYPE_YCBCR_SUB = 7; - public static readonly TYPE_GENERIC = 8; - - // Sample Formats - public static readonly FORMAT_UINT = 1; - public static readonly FORMAT_INT = 2; - public static readonly FORMAT_FLOAT = 3; - - // Tag types - public static readonly TAG_ARTIST = 315; - public static readonly TAG_BITS_PER_SAMPLE = 258; - public static readonly TAG_CELL_LENGTH = 265; - public static readonly TAG_CELL_WIDTH = 264; - public static readonly TAG_COLOR_MAP = 320; - public static readonly TAG_COMPRESSION = 259; - public static readonly TAG_DATE_TIME = 306; - public static readonly TAG_EXIF_IFD = 34665; - public static readonly TAG_EXTRA_SAMPLES = 338; - public static readonly TAG_FILL_ORDER = 266; - public static readonly TAG_FREE_BYTE_COUNTS = 289; - public static readonly TAG_FREE_OFFSETS = 288; - public static readonly TAG_GRAY_RESPONSE_CURVE = 291; - public static readonly TAG_GRAY_RESPONSE_UNIT = 290; - public static readonly TAG_HOST_COMPUTER = 316; - public static readonly TAG_ICC_PROFILE = 34675; - public static readonly TAG_IMAGE_DESCRIPTION = 270; - public static readonly TAG_IMAGE_LENGTH = 257; - public static readonly TAG_IMAGE_WIDTH = 256; - public static readonly TAG_IPTC = 33723; - public static readonly TAG_MAKE = 271; - public static readonly TAG_MAX_SAMPLE_VALUE = 281; - public static readonly TAG_MIN_SAMPLE_VALUE = 280; - public static readonly TAG_MODEL = 272; - public static readonly TAG_NEW_SUBFILE_TYPE = 254; - public static readonly TAG_ORIENTATION = 274; - public static readonly TAG_PHOTOMETRIC_INTERPRETATION = 262; - public static readonly TAG_PHOTOSHOP = 34377; - public static readonly TAG_PLANAR_CONFIGURATION = 284; - public static readonly TAG_PREDICTOR = 317; - public static readonly TAG_RESOLUTION_UNIT = 296; - public static readonly TAG_ROWS_PER_STRIP = 278; - public static readonly TAG_SAMPLES_PER_PIXEL = 277; - public static readonly TAG_SOFTWARE = 305; - public static readonly TAG_STRIP_BYTE_COUNTS = 279; - public static readonly TAG_STRIP_OFFSETS = 273; - public static readonly TAG_SUBFILE_TYPE = 255; - public static readonly TAG_T4_OPTIONS = 292; - public static readonly TAG_T6_OPTIONS = 293; - public static readonly TAG_THRESHOLDING = 263; - public static readonly TAG_TILE_WIDTH = 322; - public static readonly TAG_TILE_LENGTH = 323; - public static readonly TAG_TILE_OFFSETS = 324; - public static readonly TAG_TILE_BYTE_COUNTS = 325; - public static readonly TAG_SAMPLE_FORMAT = 339; - public static readonly TAG_XMP = 700; - public static readonly TAG_X_RESOLUTION = 282; - public static readonly TAG_Y_RESOLUTION = 283; - public static readonly TAG_YCBCR_COEFFICIENTS = 529; - public static readonly TAG_YCBCR_SUBSAMPLING = 530; - public static readonly TAG_YCBCR_POSITIONING = 531; - - public static readonly TAG_NAME: Map = new Map< - number, - string - >([ - [TiffImage.TAG_ARTIST, 'artist'], - [TiffImage.TAG_BITS_PER_SAMPLE, 'bitsPerSample'], - [TiffImage.TAG_CELL_LENGTH, 'cellLength'], - [TiffImage.TAG_CELL_WIDTH, 'cellWidth'], - [TiffImage.TAG_COLOR_MAP, 'colorMap'], - [TiffImage.TAG_COMPRESSION, 'compression'], - [TiffImage.TAG_DATE_TIME, 'dateTime'], - [TiffImage.TAG_EXIF_IFD, 'exifIFD'], - [TiffImage.TAG_EXTRA_SAMPLES, 'extraSamples'], - [TiffImage.TAG_FILL_ORDER, 'fillOrder'], - [TiffImage.TAG_FREE_BYTE_COUNTS, 'freeByteCounts'], - [TiffImage.TAG_FREE_OFFSETS, 'freeOffsets'], - [TiffImage.TAG_GRAY_RESPONSE_CURVE, 'grayResponseCurve'], - [TiffImage.TAG_GRAY_RESPONSE_UNIT, 'grayResponseUnit'], - [TiffImage.TAG_HOST_COMPUTER, 'hostComputer'], - [TiffImage.TAG_ICC_PROFILE, 'iccProfile'], - [TiffImage.TAG_IMAGE_DESCRIPTION, 'imageDescription'], - [TiffImage.TAG_IMAGE_LENGTH, 'imageLength'], - [TiffImage.TAG_IMAGE_WIDTH, 'imageWidth'], - [TiffImage.TAG_IPTC, 'iptc'], - [TiffImage.TAG_MAKE, 'make'], - [TiffImage.TAG_MAX_SAMPLE_VALUE, 'maxSampleValue'], - [TiffImage.TAG_MIN_SAMPLE_VALUE, 'minSampleValue'], - [TiffImage.TAG_MODEL, 'model'], - [TiffImage.TAG_NEW_SUBFILE_TYPE, 'newSubfileType'], - [TiffImage.TAG_ORIENTATION, 'orientation'], - [TiffImage.TAG_PHOTOMETRIC_INTERPRETATION, 'photometricInterpretation'], - [TiffImage.TAG_PHOTOSHOP, 'photoshop'], - [TiffImage.TAG_PLANAR_CONFIGURATION, 'planarConfiguration'], - [TiffImage.TAG_PREDICTOR, 'predictor'], - [TiffImage.TAG_RESOLUTION_UNIT, 'resolutionUnit'], - [TiffImage.TAG_ROWS_PER_STRIP, 'rowsPerStrip'], - [TiffImage.TAG_SAMPLES_PER_PIXEL, 'samplesPerPixel'], - [TiffImage.TAG_SOFTWARE, 'software'], - [TiffImage.TAG_STRIP_BYTE_COUNTS, 'stripByteCounts'], - [TiffImage.TAG_STRIP_OFFSETS, 'stropOffsets'], - [TiffImage.TAG_SUBFILE_TYPE, 'subfileType'], - [TiffImage.TAG_T4_OPTIONS, 't4Options'], - [TiffImage.TAG_T6_OPTIONS, 't6Options'], - [TiffImage.TAG_THRESHOLDING, 'thresholding'], - [TiffImage.TAG_TILE_WIDTH, 'tileWidth'], - [TiffImage.TAG_TILE_LENGTH, 'tileLength'], - [TiffImage.TAG_TILE_OFFSETS, 'tileOffsets'], - [TiffImage.TAG_TILE_BYTE_COUNTS, 'tileByteCounts'], - [TiffImage.TAG_XMP, 'xmp'], - [TiffImage.TAG_X_RESOLUTION, 'xResolution'], - [TiffImage.TAG_Y_RESOLUTION, 'yResolution'], - [TiffImage.TAG_YCBCR_COEFFICIENTS, 'yCbCrCoefficients'], - [TiffImage.TAG_YCBCR_SUBSAMPLING, 'yCbCrSubsampling'], - [TiffImage.TAG_YCBCR_POSITIONING, 'yCbCrPositioning'], - [TiffImage.TAG_SAMPLE_FORMAT, 'sampleFormat'], - ]); - private readonly _tags: Map = new Map(); public get tags(): Map { return this._tags; @@ -189,8 +40,8 @@ export class TiffImage { return this._height; } - private _photometricType: number | undefined; - public get photometricType(): number | undefined { + private _photometricType: TiffPhotometricType = TiffPhotometricType.unknown; + public get photometricType(): TiffPhotometricType { return this._photometricType; } @@ -209,13 +60,13 @@ export class TiffImage { return this._samplesPerPixel; } - private _sampleFormat = TiffImage.FORMAT_UINT; - public get sampleFormat(): number { + private _sampleFormat: TiffFormat = TiffFormat.uint; + public get sampleFormat(): TiffFormat { return this._sampleFormat; } - private _imageType = TiffImage.TYPE_UNSUPPORTED; - public get imageType(): number { + private _imageType: TiffImageType = TiffImageType.invalid; + public get imageType(): TiffImageType { return this._imageType; } @@ -299,23 +150,24 @@ export class TiffImage { return this._extraSamples; } - private _colorMap: number[] | undefined; - public get colorMap(): number[] | undefined { + private _colorMapSamples = 0; + public get colorMapSamples(): number { + return this._colorMapSamples; + } + + private _colorMap: Uint16Array | undefined; + public get colorMap(): Uint16Array | undefined { return this._colorMap; } // Starting index in the [colorMap] for the red channel. - private colorMapRed = 0; + private _colorMapRed = 0; // Starting index in the [colorMap] for the green channel. - private colorMapGreen = 0; + private _colorMapGreen = 0; // Starting index in the [colorMap] for the blue channel. - private colorMapBlue = 0; - - private image?: MemoryImage; - - private hdrImage?: HdrImage; + private _colorMapBlue = 0; public get isValid(): boolean { return this._width !== 0 && this._height !== 0; @@ -323,86 +175,121 @@ export class TiffImage { constructor(p: InputBuffer) { const p3 = InputBuffer.from(p); + const numDirEntries = p.readUint16(); for (let i = 0; i < numDirEntries; ++i) { const tag = p.readUint16(); - const type = p.readUint16(); - const numValues = p.readUint32(); - const entry = new TiffEntry({ - tag: tag, - type: type, - numValues: numValues, - p: p3, - }); - + const ti = p.readUint16(); + const type = ti as IfdValueType; + const typeSize = IfdValueTypeSize[ti]; + const count = p.readUint32(); + let valueOffset = 0; // The value for the tag is either stored in another location, // or within the tag itself (if the size fits in 4 bytes). // We're not reading the data here, just storing offsets. - if (entry.numValues * entry.typeSize > 4) { - entry.valueOffset = p.readUint32(); + if (count * typeSize > 4) { + valueOffset = p.readUint32(); } else { - entry.valueOffset = p.offset; - p.offset += 4; + valueOffset = p.offset; + p.skip(4); } + const entry = new TiffEntry({ + tag: tag, + type: type, + count: count, + p: p3, + valueOffset: valueOffset, + }); + this._tags.set(entry.tag, entry); - if (entry.tag === TiffImage.TAG_IMAGE_WIDTH) { - this._width = entry.readValue(); - } else if (entry.tag === TiffImage.TAG_IMAGE_LENGTH) { - this._height = entry.readValue(); - } else if (entry.tag === TiffImage.TAG_PHOTOMETRIC_INTERPRETATION) { - this._photometricType = entry.readValue(); - } else if (entry.tag === TiffImage.TAG_COMPRESSION) { - this._compression = entry.readValue(); - } else if (entry.tag === TiffImage.TAG_BITS_PER_SAMPLE) { - this._bitsPerSample = entry.readValue(); - } else if (entry.tag === TiffImage.TAG_SAMPLES_PER_PIXEL) { - this._samplesPerPixel = entry.readValue(); - } else if (entry.tag === TiffImage.TAG_PREDICTOR) { - this._predictor = entry.readValue(); - } else if (entry.tag === TiffImage.TAG_SAMPLE_FORMAT) { - this._sampleFormat = entry.readValue(); - } else if (entry.tag === TiffImage.TAG_COLOR_MAP) { - this._colorMap = entry.readValues(); - this.colorMapRed = 0; - this.colorMapGreen = Math.trunc(this._colorMap.length / 3); - this.colorMapBlue = this.colorMapGreen * 2; + if (tag === ExifTagNameToID.get('ImageWidth')) { + this._width = entry.read()?.toInt() ?? 0; + } else if (tag === ExifTagNameToID.get('ImageLength')) { + this._height = entry.read()?.toInt() ?? 0; + } else if (tag === ExifTagNameToID.get('PhotometricInterpretation')) { + const v = entry.read(); + if (v === undefined) { + this._photometricType = TiffPhotometricType.unknown; + } else { + const pt = v.toInt(); + if (pt < TiffPhotometricTypeLength) { + this._photometricType = pt as TiffPhotometricType; + } else { + this._photometricType = TiffPhotometricType.unknown; + } + } + } else if (tag === ExifTagNameToID.get('Compression')) { + this._compression = entry.read()?.toInt() ?? 0; + } else if (tag === ExifTagNameToID.get('BitsPerSample')) { + this._bitsPerSample = entry.read()?.toInt() ?? 0; + } else if (tag === ExifTagNameToID.get('SamplesPerPixel')) { + this._samplesPerPixel = entry.read()?.toInt() ?? 0; + } else if (tag === ExifTagNameToID.get('Predictor')) { + this._predictor = entry.read()?.toInt() ?? 0; + } else if (tag === ExifTagNameToID.get('SampleFormat')) { + const v = entry.read()?.toInt() ?? 0; + this._sampleFormat = v as TiffFormat; + } else if (tag === ExifTagNameToID.get('ColorMap')) { + const v = entry.read(); + if (v !== undefined) { + this._colorMap = new Uint16Array(v.toData().buffer); + this._colorMapRed = 0; + this._colorMapGreen = Math.trunc(this._colorMap.length / 3); + this._colorMapBlue = this._colorMapGreen * 2; + } } } + if ( + this._colorMap !== undefined && + this._photometricType === TiffPhotometricType.palette + ) { + // Only support RGB palettes. + this._colorMapSamples = 3; + this._samplesPerPixel = 1; + } + if (this._width === 0 || this._height === 0) { return; } if (this._colorMap !== undefined && this._bitsPerSample === 8) { - for (let i = 0, len = this._colorMap.length; i < len; ++i) { - this._colorMap[i] >>= 8; + const cm = this._colorMap; + const len = cm.length; + for (let i = 0; i < len; ++i) { + cm[i] >>= 8; } } - if (this._photometricType === 0) { + if (this._photometricType === TiffPhotometricType.whiteIsZero) { this._isWhiteZero = true; } - if (this.hasTag(TiffImage.TAG_TILE_OFFSETS)) { + if (this.hasTag(ExifTagNameToID.get('TileOffsets')!)) { this._tiled = true; // Image is in tiled format - this._tileWidth = this.readTag(TiffImage.TAG_TILE_WIDTH); - this._tileHeight = this.readTag(TiffImage.TAG_TILE_LENGTH); - this._tileOffsets = this.readTagList(TiffImage.TAG_TILE_OFFSETS); - this._tileByteCounts = this.readTagList(TiffImage.TAG_TILE_BYTE_COUNTS); + this._tileWidth = this.readTag(ExifTagNameToID.get('TileWidth')!); + this._tileHeight = this.readTag(ExifTagNameToID.get('TileLength')!); + this._tileOffsets = this.readTagList(ExifTagNameToID.get('TileOffsets')!); + this._tileByteCounts = this.readTagList( + ExifTagNameToID.get('TileByteCounts')! + ); } else { this._tiled = false; - this._tileWidth = this.readTag(TiffImage.TAG_TILE_WIDTH, this._width); - if (!this.hasTag(TiffImage.TAG_ROWS_PER_STRIP)) { + this._tileWidth = this.readTag( + ExifTagNameToID.get('TileWidth')!, + this._width + ); + if (!this.hasTag(ExifTagNameToID.get('RowsPerStrip')!)) { this._tileHeight = this.readTag( - TiffImage.TAG_TILE_LENGTH, + ExifTagNameToID.get('TileLength')!, this._height ); } else { - const l = this.readTag(TiffImage.TAG_ROWS_PER_STRIP); + const l = this.readTag(ExifTagNameToID.get('RowsPerStrip')!); let infinity = 1; infinity = (infinity << 32) - 1; if (l === infinity) { @@ -413,8 +300,12 @@ export class TiffImage { } } - this._tileOffsets = this.readTagList(TiffImage.TAG_STRIP_OFFSETS); - this._tileByteCounts = this.readTagList(TiffImage.TAG_STRIP_BYTE_COUNTS); + this._tileOffsets = this.readTagList( + ExifTagNameToID.get('StripOffsets')! + ); + this._tileByteCounts = this.readTagList( + ExifTagNameToID.get('StripByteCounts')! + ); } // Calculate number of tiles and the tileSize in bytes @@ -426,92 +317,86 @@ export class TiffImage { ); this._tileSize = this._tileWidth * this._tileHeight * this._samplesPerPixel; - this._fillOrder = this.readTag(TiffImage.TAG_FILL_ORDER, 1); - this._t4Options = this.readTag(TiffImage.TAG_T4_OPTIONS); - this._t6Options = this.readTag(TiffImage.TAG_T6_OPTIONS); - this._extraSamples = this.readTag(TiffImage.TAG_EXTRA_SAMPLES); + this._fillOrder = this.readTag(ExifTagNameToID.get('FillOrder')!, 1); + this._t4Options = this.readTag(ExifTagNameToID.get('T4Options')!); + this._t6Options = this.readTag(ExifTagNameToID.get('T6Options')!); + this._extraSamples = this.readTag(ExifTagNameToID.get('ExtraSamples')!); // Determine which kind of image we are dealing with. switch (this._photometricType) { - // WhiteIsZero - case 0: - // BlackIsZero - // falls through - case 1: + case TiffPhotometricType.whiteIsZero: + case TiffPhotometricType.blackIsZero: if (this._bitsPerSample === 1 && this._samplesPerPixel === 1) { - this._imageType = TiffImage.TYPE_BILEVEL; + this._imageType = TiffImageType.bilevel; } else if (this._bitsPerSample === 4 && this._samplesPerPixel === 1) { - this._imageType = TiffImage.TYPE_GRAY_4BIT; + this._imageType = TiffImageType.gray4bit; } else if (this._bitsPerSample % 8 === 0) { if (this._samplesPerPixel === 1) { - this._imageType = TiffImage.TYPE_GRAY; + this._imageType = TiffImageType.gray; } else if (this._samplesPerPixel === 2) { - this._imageType = TiffImage.TYPE_GRAY_ALPHA; + this._imageType = TiffImageType.grayAlpha; } else { - this._imageType = TiffImage.TYPE_GENERIC; + this._imageType = TiffImageType.generic; } } break; - // RGB - case 2: + case TiffPhotometricType.rgb: if (this._bitsPerSample % 8 === 0) { if (this._samplesPerPixel === 3) { - this._imageType = TiffImage.TYPE_RGB; + this._imageType = TiffImageType.rgb; } else if (this._samplesPerPixel === 4) { - this._imageType = TiffImage.TYPE_RGB_ALPHA; + this._imageType = TiffImageType.rgba; } else { - this._imageType = TiffImage.TYPE_GENERIC; + this._imageType = TiffImageType.generic; } } break; - // RGB Palette - case 3: + case TiffPhotometricType.palette: if ( this._samplesPerPixel === 1 && + this._colorMap !== undefined && (this._bitsPerSample === 4 || this._bitsPerSample === 8 || this._bitsPerSample === 16) ) { - this._imageType = TiffImage.TYPE_PALETTE; + this._imageType = TiffImageType.palette; } break; - // Transparency mask - case 4: + case TiffPhotometricType.transparencyMask: + // Transparency mask if (this._bitsPerSample === 1 && this._samplesPerPixel === 1) { - this._imageType = TiffImage.TYPE_BILEVEL; + this._imageType = TiffImageType.bilevel; } break; - // YCbCr - case 6: + case TiffPhotometricType.yCbCr: if ( - this._compression === TiffImage.COMPRESSION_JPEG && + this._compression === TiffCompression.jpeg && this._bitsPerSample === 8 && this._samplesPerPixel === 3 ) { - this._imageType = TiffImage.TYPE_RGB; + this._imageType = TiffImageType.rgb; } else { - if (this.hasTag(TiffImage.TAG_YCBCR_SUBSAMPLING)) { - const v = this._tags - .get(TiffImage.TAG_YCBCR_SUBSAMPLING)! - .readValues(); - this._chromaSubH = v[0]; - this._chromaSubV = v[1]; + if (this.hasTag(ExifTagNameToID.get('YCbCrSubSampling')!)) { + const s = ExifTagNameToID.get('YCbCrSubSampling')!; + const v = this._tags.get(s)!.read()!; + this._chromaSubH = v.toInt(); + this._chromaSubV = v.toInt(1); } else { this._chromaSubH = 2; this._chromaSubV = 2; } if (this._chromaSubH * this._chromaSubV === 1) { - this._imageType = TiffImage.TYPE_GENERIC; + this._imageType = TiffImageType.generic; } else if (this._bitsPerSample === 8 && this._samplesPerPixel === 3) { - this._imageType = TiffImage.TYPE_YCBCR_SUB; + this._imageType = TiffImageType.yCbCrSub; } } break; - // Other including CMYK, CIE L*a*b*, unknown. default: + // Other including CMYK, CIE L*a*b*, unknown. if (this._bitsPerSample % 8 === 0) { - this._imageType = TiffImage.TYPE_GENERIC; + this._imageType = TiffImageType.generic; } break; } @@ -521,18 +406,21 @@ export class TiffImage { if (!this.hasTag(type)) { return defaultValue; } - return this._tags.get(type)!.readValue(); + return this._tags.get(type)!.read()?.toInt() ?? 0; } private readTagList(type: number): number[] | undefined { if (!this.hasTag(type)) { return undefined; } - return this._tags.get(type)!.readValues(); + const tag = this._tags.get(type)!; + const value = tag.read()!; + return ArrayUtils.generate(tag.count, (i) => value.toInt(i)); } private decodeBilevelTile( p: InputBuffer, + image: MemoryImage, tileX: number, tileY: number ): void { @@ -544,8 +432,8 @@ export class TiffImage { const byteCount = this._tileByteCounts![tileIndex]; - let bdata: InputBuffer | undefined = undefined; - if (this._compression === TiffImage.COMPRESSION_PACKBITS) { + let byteData: InputBuffer | undefined = undefined; + if (this._compression === TiffCompression.packBits) { // Since the decompressed data will still be packed // 8 pixels into 1 byte, calculate bytesInThisTile let bytesInThisTile = 0; @@ -555,17 +443,17 @@ export class TiffImage { bytesInThisTile = (Math.trunc(this._tileWidth / 8) + 1) * this._tileHeight; } - bdata = new InputBuffer({ + byteData = new InputBuffer({ buffer: new Uint8Array(this._tileWidth * this._tileHeight), }); - this.decodePackbits(p, bytesInThisTile, bdata.buffer); - } else if (this._compression === TiffImage.COMPRESSION_LZW) { - bdata = new InputBuffer({ + this.decodePackBits(p, bytesInThisTile, byteData.buffer); + } else if (this._compression === TiffCompression.lzw) { + byteData = new InputBuffer({ buffer: new Uint8Array(this._tileWidth * this._tileHeight), }); const decoder = new LzwDecoder(); - decoder.decode(InputBuffer.from(p, 0, byteCount), bdata.buffer); + decoder.decode(InputBuffer.from(p, 0, byteCount), byteData.buffer); // Horizontal Differencing Predictor if (this._predictor === 2) { @@ -578,15 +466,15 @@ export class TiffImage { i++ ) { const b = - bdata.getByte(count) + - bdata.getByte(count - this._samplesPerPixel); - bdata.setByte(count, b); + byteData.getByte(count) + + byteData.getByte(count - this._samplesPerPixel); + byteData.setByte(count, b); count++; } } } - } else if (this._compression === TiffImage.COMPRESSION_CCITT_RLE) { - bdata = new InputBuffer({ + } else if (this._compression === TiffCompression.ccittRle) { + byteData = new InputBuffer({ buffer: new Uint8Array(this._tileWidth * this._tileHeight), }); try { @@ -595,12 +483,12 @@ export class TiffImage { width: this._tileWidth, height: this._tileHeight, }); - decoder.decode1D(bdata, p, 0, this._tileHeight); + decoder.decode1D(byteData, p, 0, this._tileHeight); } catch (_) { // skip } - } else if (this._compression === TiffImage.COMPRESSION_CCITT_FAX3) { - bdata = new InputBuffer({ + } else if (this._compression === TiffCompression.ccittFax3) { + byteData = new InputBuffer({ buffer: new Uint8Array(this._tileWidth * this._tileHeight), }); try { @@ -609,12 +497,12 @@ export class TiffImage { width: this._tileWidth, height: this._tileHeight, }); - decoder.decode2D(bdata, p, 0, this._tileHeight, this._t4Options); + decoder.decode2D(byteData, p, 0, this._tileHeight, this._t4Options); } catch (_) { // skip } - } else if (this._compression === TiffImage.COMPRESSION_CCITT_FAX4) { - bdata = new InputBuffer({ + } else if (this._compression === TiffCompression.ccittFax4) { + byteData = new InputBuffer({ buffer: new Uint8Array(this._tileWidth * this._tileHeight), }); try { @@ -623,53 +511,56 @@ export class TiffImage { width: this._tileWidth, height: this._tileHeight, }); - decoder.decodeT6(bdata, p, 0, this._tileHeight, this._t6Options); + decoder.decodeT6(byteData, p, 0, this._tileHeight, this._t6Options); } catch (_) { // skip } - } else if (this._compression === TiffImage.COMPRESSION_ZIP) { + } else if (this._compression === TiffCompression.zip) { const data = p.toUint8Array(0, byteCount); const outData = inflate(data); - bdata = new InputBuffer({ + byteData = new InputBuffer({ buffer: outData, }); - } else if (this._compression === TiffImage.COMPRESSION_DEFLATE) { + } else if (this._compression === TiffCompression.deflate) { const data = p.toUint8Array(0, byteCount); const outData = inflate(data); - bdata = new InputBuffer({ + byteData = new InputBuffer({ buffer: outData, }); - } else if (this._compression === TiffImage.COMPRESSION_NONE) { - bdata = p; + } else if (this._compression === TiffCompression.none) { + byteData = p; } else { - throw new ImageError( - `Unsupported Compression Type: ${this._compression}` - ); + throw new LibError(`Unsupported Compression Type: ${this._compression}`); } - const br = new TiffBitReader(bdata); - const white = this._isWhiteZero ? 0xff000000 : 0xffffffff; - const black = this._isWhiteZero ? 0xffffffff : 0xff000000; + const br = new TiffBitReader(byteData); + const mx = image.maxChannelValue; + const black = this._isWhiteZero ? mx : 0; + const white = this._isWhiteZero ? 0 : mx; - const img = this.image!; for (let y = 0, py = outY; y < this._tileHeight; ++y, ++py) { for (let x = 0, px = outX; x < this._tileWidth; ++x, ++px) { - if (py >= img.height || px >= img.width) break; + if (py >= image.height || px >= image.width) break; if (br.readBits(1) === 0) { - img.setPixel(px, py, black); + image.setPixelRgb(px, py, black, 0, 0); } else { - img.setPixel(px, py, white); + image.setPixelRgb(px, py, white, 0, 0); } } br.flushByte(); } } - private decodeTile(p: InputBuffer, tileX: number, tileY: number): void { + private decodeTile( + p: InputBuffer, + image: MemoryImage, + tileX: number, + tileY: number + ): void { // Read the data, uncompressing as needed. There are four cases: // bilevel, palette-RGB, 4-bit grayscale, and everything else. - if (this._imageType === TiffImage.TYPE_BILEVEL) { - this.decodeBilevelTile(p, tileX, tileY); + if (this._imageType === TiffImageType.bilevel) { + this.decodeBilevelTile(p, image, tileX, tileY); return; } @@ -688,84 +579,74 @@ export class TiffImage { bytesInThisTile *= 4; } - let bdata: InputBuffer | undefined = undefined; + let byteData: InputBuffer | undefined = undefined; if ( this._bitsPerSample === 8 || this._bitsPerSample === 16 || this._bitsPerSample === 32 || this._bitsPerSample === 64 ) { - if (this._compression === TiffImage.COMPRESSION_NONE) { - bdata = p; - } else if (this._compression === TiffImage.COMPRESSION_LZW) { - bdata = new InputBuffer({ + if (this._compression === TiffCompression.none) { + byteData = p; + } else if (this._compression === TiffCompression.lzw) { + byteData = new InputBuffer({ buffer: new Uint8Array(bytesInThisTile), }); const decoder = new LzwDecoder(); try { - decoder.decode(InputBuffer.from(p, 0, byteCount), bdata.buffer); + decoder.decode(InputBuffer.from(p, 0, byteCount), byteData.buffer); } catch (e) { - console.error(e); + // ignore } // Horizontal Differencing Predictor if (this._predictor === 2) { let count = 0; for (let j = 0; j < this._tileHeight; j++) { count = this._samplesPerPixel * (j * this._tileWidth + 1); - for ( - let i = this._samplesPerPixel, - len = this._tileWidth * this._samplesPerPixel; - i < len; - i++ - ) { - const b = - bdata.getByte(count) + - bdata.getByte(count - this._samplesPerPixel); - bdata.setByte(count, b); + const len = this._tileWidth * this._samplesPerPixel; + for (let i = this._samplesPerPixel; i < len; i++) { + byteData.setByte( + count, + byteData.getByte(count) + + byteData.getByte(count - this._samplesPerPixel) + ); count++; } } } - } else if (this._compression === TiffImage.COMPRESSION_PACKBITS) { - bdata = new InputBuffer({ + } else if (this._compression === TiffCompression.packBits) { + byteData = new InputBuffer({ buffer: new Uint8Array(bytesInThisTile), }); - this.decodePackbits(p, bytesInThisTile, bdata.buffer); - } else if (this._compression === TiffImage.COMPRESSION_DEFLATE) { + this.decodePackBits(p, bytesInThisTile, byteData.buffer); + } else if (this._compression === TiffCompression.deflate) { const data = p.toUint8Array(0, byteCount); const outData = inflate(data); - bdata = new InputBuffer({ + byteData = new InputBuffer({ buffer: outData, }); - } else if (this._compression === TiffImage.COMPRESSION_ZIP) { + } else if (this._compression === TiffCompression.zip) { const data = p.toUint8Array(0, byteCount); const outData = inflate(data); - bdata = new InputBuffer({ + byteData = new InputBuffer({ buffer: outData, }); - } else if (this._compression === TiffImage.COMPRESSION_OLD_JPEG) { - this.image ??= new MemoryImage({ - width: this._width, - height: this._height, - }); + } else if (this._compression === TiffCompression.oldJpeg) { const data = p.toUint8Array(0, byteCount); - const tile = new JpegDecoder().decodeImage(data); + const tile = new JpegDecoder().decode(data); if (tile !== undefined) { this.jpegToImage( tile, - this.image, + image, outX, outY, this._tileWidth, this._tileHeight ); } - if (this.hdrImage !== undefined) { - this.hdrImage = HdrImage.fromImage(this.image); - } return; } else { - throw new ImageError( + throw new LibError( `Unsupported Compression Type: ${this._compression}` ); } @@ -781,279 +662,164 @@ export class TiffImage { ++x, ++px ) { if (this._samplesPerPixel === 1) { - if (this._sampleFormat === TiffImage.FORMAT_FLOAT) { - let sample = 0.0; + if (this._sampleFormat === TiffFormat.float) { + let sample = 0; if (this._bitsPerSample === 32) { - sample = bdata.readFloat32(); + sample = byteData.readFloat32(); } else if (this._bitsPerSample === 64) { - sample = bdata.readFloat64(); + sample = byteData.readFloat64(); } else if (this._bitsPerSample === 16) { - sample = Half.halfToDouble(bdata.readUint16()); - } - if (this.hdrImage !== undefined) { - this.hdrImage.setRed(px, py, sample); - } - if (this.image !== undefined) { - const gray = MathOperators.clampInt255(sample * 255); - let c = 0; - if ( - this._photometricType === 3 && - this._colorMap !== undefined - ) { - c = Color.getColor( - this._colorMap[this.colorMapRed + gray], - this._colorMap[this.colorMapGreen + gray], - this._colorMap[this.colorMapBlue + gray] - ); - } else { - c = Color.getColor(gray, gray, gray); - } - this.image.setPixel(px, py, c); + sample = Float16.float16ToDouble(byteData.readUint16()); } + image.setPixelR(px, py, sample); } else { - let gray = 0; + let sample = 0; if (this._bitsPerSample === 8) { - gray = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt8() - : bdata.readByte(); + sample = + this._sampleFormat === TiffFormat.int + ? byteData.readInt8() + : byteData.readByte(); } else if (this._bitsPerSample === 16) { - gray = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt16() - : bdata.readUint16(); + sample = + this._sampleFormat === TiffFormat.int + ? byteData.readInt16() + : byteData.readUint16(); } else if (this._bitsPerSample === 32) { - gray = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt32() - : bdata.readUint32(); + sample = + this._sampleFormat === TiffFormat.int + ? byteData.readInt32() + : byteData.readUint32(); } - if (this.hdrImage !== undefined) { - this.hdrImage.setRed(px, py, gray); + if (this._photometricType === TiffPhotometricType.whiteIsZero) { + const mx = Math.trunc(image.maxChannelValue); + sample = mx - sample; } - if (this.image !== undefined) { - gray = - this._bitsPerSample === 16 - ? gray >> 8 - : this._bitsPerSample === 32 - ? gray >> 24 - : gray; - if (this._photometricType === 0) { - gray = 255 - gray; - } - - let c = 0; - if ( - this._photometricType === 3 && - this._colorMap !== undefined - ) { - c = Color.getColor( - this._colorMap[this.colorMapRed + gray], - this._colorMap[this.colorMapGreen + gray], - this._colorMap[this.colorMapBlue + gray] - ); - } else { - c = Color.getColor(gray, gray, gray); - } - - this.image.setPixel(px, py, c); - } + image.setPixelR(px, py, sample); } } else if (this._samplesPerPixel === 2) { let gray = 0; let alpha = 0; if (this._bitsPerSample === 8) { gray = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt8() - : bdata.readByte(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt8() + : byteData.readByte(); alpha = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt8() - : bdata.readByte(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt8() + : byteData.readByte(); } else if (this._bitsPerSample === 16) { gray = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt16() - : bdata.readUint16(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt16() + : byteData.readUint16(); alpha = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt16() - : bdata.readUint16(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt16() + : byteData.readUint16(); } else if (this._bitsPerSample === 32) { gray = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt32() - : bdata.readUint32(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt32() + : byteData.readUint32(); alpha = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt32() - : bdata.readUint32(); - } - - if (this.hdrImage !== undefined) { - this.hdrImage.setRed(px, py, gray); - this.hdrImage.setGreen(px, py, alpha); + this._sampleFormat === TiffFormat.int + ? byteData.readInt32() + : byteData.readUint32(); } - if (this.image !== undefined) { - gray = - this._bitsPerSample === 16 - ? gray >> 8 - : this._bitsPerSample === 32 - ? gray >> 24 - : gray; - alpha = - this._bitsPerSample === 16 - ? alpha >> 8 - : this._bitsPerSample === 32 - ? alpha >> 24 - : alpha; - const c = Color.getColor(gray, gray, gray, alpha); - this.image.setPixel(px, py, c); - } + image.setPixelRgb(px, py, gray, alpha, 0); } else if (this._samplesPerPixel === 3) { - if (this._sampleFormat === TiffImage.FORMAT_FLOAT) { + if (this._sampleFormat === TiffFormat.float) { let r = 0.0; let g = 0.0; let b = 0.0; if (this._bitsPerSample === 32) { - r = bdata.readFloat32(); - g = bdata.readFloat32(); - b = bdata.readFloat32(); + r = byteData.readFloat32(); + g = byteData.readFloat32(); + b = byteData.readFloat32(); } else if (this._bitsPerSample === 64) { - r = bdata.readFloat64(); - g = bdata.readFloat64(); - b = bdata.readFloat64(); + r = byteData.readFloat64(); + g = byteData.readFloat64(); + b = byteData.readFloat64(); } else if (this._bitsPerSample === 16) { - r = Half.halfToDouble(bdata.readUint16()); - g = Half.halfToDouble(bdata.readUint16()); - b = Half.halfToDouble(bdata.readUint16()); - } - if (this.hdrImage !== undefined) { - this.hdrImage.setRed(px, py, r); - this.hdrImage.setGreen(px, py, g); - this.hdrImage.setBlue(px, py, b); - } - if (this.image !== undefined) { - const ri = MathOperators.clampInt255(r * 255); - const gi = MathOperators.clampInt255(g * 255); - const bi = MathOperators.clampInt255(b * 255); - const c = Color.getColor(ri, gi, bi); - this.image.setPixel(px, py, c); + r = Float16.float16ToDouble(byteData.readUint16()); + g = Float16.float16ToDouble(byteData.readUint16()); + b = Float16.float16ToDouble(byteData.readUint16()); } + image.setPixelRgb(px, py, r, g, b); } else { let r = 0; let g = 0; let b = 0; if (this._bitsPerSample === 8) { r = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt8() - : bdata.readByte(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt8() + : byteData.readByte(); g = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt8() - : bdata.readByte(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt8() + : byteData.readByte(); b = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt8() - : bdata.readByte(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt8() + : byteData.readByte(); } else if (this._bitsPerSample === 16) { r = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt16() - : bdata.readUint16(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt16() + : byteData.readUint16(); g = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt16() - : bdata.readUint16(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt16() + : byteData.readUint16(); b = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt16() - : bdata.readUint16(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt16() + : byteData.readUint16(); } else if (this._bitsPerSample === 32) { r = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt32() - : bdata.readUint32(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt32() + : byteData.readUint32(); g = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt32() - : bdata.readUint32(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt32() + : byteData.readUint32(); b = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt32() - : bdata.readUint32(); - } - - if (this.hdrImage !== undefined) { - this.hdrImage.setRed(px, py, r); - this.hdrImage.setGreen(px, py, g); - this.hdrImage.setBlue(px, py, b); + this._sampleFormat === TiffFormat.int + ? byteData.readInt32() + : byteData.readUint32(); } - if (this.image !== undefined) { - r = - this._bitsPerSample === 16 - ? r >> 8 - : this._bitsPerSample === 32 - ? r >> 24 - : r; - g = - this._bitsPerSample === 16 - ? g >> 8 - : this._bitsPerSample === 32 - ? g >> 24 - : g; - b = - this._bitsPerSample === 16 - ? b >> 8 - : this._bitsPerSample === 32 - ? b >> 24 - : b; - const c = Color.getColor(r, g, b); - this.image.setPixel(px, py, c); - } + image.setPixelRgb(px, py, r, g, b); } } else if (this._samplesPerPixel >= 4) { - if (this._sampleFormat === TiffImage.FORMAT_FLOAT) { + if (this._sampleFormat === TiffFormat.float) { let r = 0.0; let g = 0.0; let b = 0.0; let a = 0.0; if (this._bitsPerSample === 32) { - r = bdata.readFloat32(); - g = bdata.readFloat32(); - b = bdata.readFloat32(); - a = bdata.readFloat32(); + r = byteData.readFloat32(); + g = byteData.readFloat32(); + b = byteData.readFloat32(); + a = byteData.readFloat32(); } else if (this._bitsPerSample === 64) { - r = bdata.readFloat64(); - g = bdata.readFloat64(); - b = bdata.readFloat64(); - a = bdata.readFloat64(); + r = byteData.readFloat64(); + g = byteData.readFloat64(); + b = byteData.readFloat64(); + a = byteData.readFloat64(); } else if (this._bitsPerSample === 16) { - r = Half.halfToDouble(bdata.readUint16()); - g = Half.halfToDouble(bdata.readUint16()); - b = Half.halfToDouble(bdata.readUint16()); - a = Half.halfToDouble(bdata.readUint16()); - } - if (this.hdrImage !== undefined) { - this.hdrImage.setRed(px, py, r); - this.hdrImage.setGreen(px, py, g); - this.hdrImage.setBlue(px, py, b); - this.hdrImage.setAlpha(px, py, a); - } - if (this.image !== undefined) { - const ri = MathOperators.clampInt255(r * 255); - const gi = MathOperators.clampInt255(g * 255); - const bi = MathOperators.clampInt255(b * 255); - const ai = MathOperators.clampInt255(a * 255); - const c = Color.getColor(ri, gi, bi, ai); - this.image.setPixel(px, py, c); + r = Float16.float16ToDouble(byteData.readUint16()); + g = Float16.float16ToDouble(byteData.readUint16()); + b = Float16.float16ToDouble(byteData.readUint16()); + a = Float16.float16ToDouble(byteData.readUint16()); } + image.setPixelRgba(px, py, r, g, b, a); } else { let r = 0; let g = 0; @@ -1061,98 +827,72 @@ export class TiffImage { let a = 0; if (this._bitsPerSample === 8) { r = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt8() - : bdata.readByte(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt8() + : byteData.readByte(); g = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt8() - : bdata.readByte(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt8() + : byteData.readByte(); b = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt8() - : bdata.readByte(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt8() + : byteData.readByte(); a = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt8() - : bdata.readByte(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt8() + : byteData.readByte(); } else if (this._bitsPerSample === 16) { r = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt16() - : bdata.readUint16(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt16() + : byteData.readUint16(); g = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt16() - : bdata.readUint16(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt16() + : byteData.readUint16(); b = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt16() - : bdata.readUint16(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt16() + : byteData.readUint16(); a = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt16() - : bdata.readUint16(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt16() + : byteData.readUint16(); } else if (this._bitsPerSample === 32) { r = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt32() - : bdata.readUint32(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt32() + : byteData.readUint32(); g = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt32() - : bdata.readUint32(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt32() + : byteData.readUint32(); b = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt32() - : bdata.readUint32(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt32() + : byteData.readUint32(); a = - this._sampleFormat === TiffImage.FORMAT_INT - ? bdata.readInt32() - : bdata.readUint32(); + this._sampleFormat === TiffFormat.int + ? byteData.readInt32() + : byteData.readUint32(); } - if (this.hdrImage !== undefined) { - this.hdrImage.setRed(px, py, r); - this.hdrImage.setGreen(px, py, g); - this.hdrImage.setBlue(px, py, b); - this.hdrImage.setAlpha(px, py, a); + if (this._photometricType === TiffPhotometricType.cmyk) { + const rgba = ColorUtils.cmykToRgb(r, g, b, a); + r = rgba[0]; + g = rgba[1]; + b = rgba[2]; + a = Math.trunc(image.maxChannelValue); } - if (this.image !== undefined) { - r = - this._bitsPerSample === 16 - ? r >> 8 - : this._bitsPerSample === 32 - ? r >> 24 - : r; - g = - this._bitsPerSample === 16 - ? g >> 8 - : this._bitsPerSample === 32 - ? g >> 24 - : g; - b = - this._bitsPerSample === 16 - ? b >> 8 - : this._bitsPerSample === 32 - ? b >> 24 - : b; - a = - this._bitsPerSample === 16 - ? a >> 8 - : this._bitsPerSample === 32 - ? a >> 24 - : a; - const c = Color.getColor(r, g, b, a); - this.image.setPixel(px, py, c); - } + image.setPixelRgba(px, py, r, g, b, a); } } } } } else { - throw new ImageError(`Unsupported bitsPerSample: ${this._bitsPerSample}`); + throw new LibError(`Unsupported bitsPerSample: ${this._bitsPerSample}`); } } @@ -1176,7 +916,7 @@ export class TiffImage { /** * Uncompress packbits compressed image data. */ - private decodePackbits( + private decodePackBits( data: InputBuffer, arraySize: number, dst: Uint8Array @@ -1185,7 +925,7 @@ export class TiffImage { let dstCount = 0; while (dstCount < arraySize) { - const b = BitOperators.toInt8(data.getByte(srcCount++)); + const b = BitUtils.uint8ToInt8(data.getByte(srcCount++)); if (b >= 0 && b <= 127) { // literal run packet for (let i = 0; i < b + 1; ++i) { @@ -1205,36 +945,68 @@ export class TiffImage { } public decode(p: InputBuffer): MemoryImage { - this.image = new MemoryImage({ + const isFloat = this._sampleFormat === TiffFormat.float; + const isInt = this._sampleFormat === TiffFormat.int; + const format = + this._bitsPerSample === 1 + ? Format.uint1 + : this._bitsPerSample === 2 + ? Format.uint2 + : this._bitsPerSample === 4 + ? Format.uint4 + : isFloat && this._bitsPerSample === 16 + ? Format.float16 + : isFloat && this._bitsPerSample === 32 + ? Format.float32 + : isFloat && this._bitsPerSample === 64 + ? Format.float64 + : isInt && this._bitsPerSample === 8 + ? Format.int8 + : isInt && this._bitsPerSample === 16 + ? Format.int16 + : isInt && this._bitsPerSample === 32 + ? Format.int32 + : this._bitsPerSample === 16 + ? Format.uint16 + : this._bitsPerSample === 32 + ? Format.uint32 + : Format.uint8; + const hasPalette = + this._colorMap !== undefined && + this._photometricType === TiffPhotometricType.palette; + const numChannels = hasPalette ? 3 : this._samplesPerPixel; + + const image = new MemoryImage({ width: this._width, height: this._height, + format: format, + numChannels: numChannels, + withPalette: hasPalette, }); - for (let tileY = 0, ti = 0; tileY < this._tilesY; ++tileY) { - for (let tileX = 0; tileX < this._tilesX; ++tileX, ++ti) { - this.decodeTile(p, tileX, tileY); + + if (hasPalette) { + const p = image.palette!; + const cm = this._colorMap!; + const numChannels = 3; + // Only support RGB palettes + const numColors = Math.trunc(cm.length / numChannels); + for (let i = 0; i < numColors; ++i) { + p.setRgb( + i, + cm[this._colorMapRed + i], + cm[this._colorMapGreen + i], + cm[this._colorMapBlue + i] + ); } } - return this.image; - } - public decodeHdr(p: InputBuffer): HdrImage { - this.hdrImage = HdrImage.create( - this._width, - this._height, - this._samplesPerPixel, - this._sampleFormat === TiffImage.FORMAT_UINT - ? HdrSlice.UINT - : this._sampleFormat === TiffImage.FORMAT_INT - ? HdrSlice.INT - : HdrSlice.FLOAT, - this._bitsPerSample - ); for (let tileY = 0, ti = 0; tileY < this._tilesY; ++tileY) { for (let tileX = 0; tileX < this._tilesX; ++tileX, ++ti) { - this.decodeTile(p, tileX, tileY); + this.decodeTile(p, image, tileX, tileY); } } - return this.hdrImage; + + return image; } public hasTag(tag: number): boolean { diff --git a/src/formats/tiff/tiff-info.ts b/src/formats/tiff/tiff-info.ts index 543d268..ac8158e 100644 --- a/src/formats/tiff/tiff-info.ts +++ b/src/formats/tiff/tiff-info.ts @@ -1,5 +1,6 @@ /** @format */ +import { Color } from '../../color/color'; import { DecodeInfo } from '../decode-info'; import { TiffImage } from './tiff-image'; @@ -41,8 +42,8 @@ export class TiffInfo implements DecodeInfo { return this._height; } - private _backgroundColor = 0xffffffff; - get backgroundColor(): number { + private _backgroundColor: Color | undefined = undefined; + public get backgroundColor(): Color | undefined { throw this._backgroundColor; } @@ -50,11 +51,11 @@ export class TiffInfo implements DecodeInfo { return this._images.length; } - constructor(options: TiffInfoInitOptions) { - this._bigEndian = options.bigEndian; - this._signature = options.signature; - this._ifdOffset = options.ifdOffset; - this._images = options.images; + constructor(opt: TiffInfoInitOptions) { + this._bigEndian = opt.bigEndian; + this._signature = opt.signature; + this._ifdOffset = opt.ifdOffset; + this._images = opt.images; if (this._images.length > 0) { this._width = this._images[0].width; this._height = this._images[0].height; diff --git a/src/formats/tiff/tiff-lzw-decoder.ts b/src/formats/tiff/tiff-lzw-decoder.ts index 32bf79f..9e2d218 100644 --- a/src/formats/tiff/tiff-lzw-decoder.ts +++ b/src/formats/tiff/tiff-lzw-decoder.ts @@ -1,50 +1,50 @@ /** @format */ import { InputBuffer } from '../../common/input-buffer'; -import { ImageError } from '../../error/image-error'; +import { LibError } from '../../error/lib-error'; export class LzwDecoder { - private static readonly LZ_MAX_CODE = 4095; - private static readonly NO_SUCH_CODE = 4098; - private static readonly AND_TABLE: number[] = [511, 1023, 2047, 4095]; - - private readonly buffer = new Uint8Array(4096); - - private bitsToGet = 9; - private bytePointer = 0; - private nextData = 0; - private nextBits = 0; - private data!: Uint8Array; - private dataLength!: number; - private out!: Uint8Array; - private outPointer!: number; - private table!: Uint8Array; - private prefix!: Uint32Array; - private tableIndex?: number; - private bufferLength!: number; + private static readonly _lzMaxCode = 4095; + private static readonly _noSuchCode = 4098; + private static readonly _andTable: number[] = [511, 1023, 2047, 4095]; + + private readonly _buffer = new Uint8Array(4096); + + private _bitsToGet = 9; + private _bytePointer = 0; + private _nextData = 0; + private _nextBits = 0; + private _data!: Uint8Array; + private _dataLength!: number; + private _out!: Uint8Array; + private _outPointer!: number; + private _table!: Uint8Array; + private _prefix!: Uint32Array; + private _tableIndex?: number; + private _bufferLength!: number; private addString(string: number, newString: number): void { - this.table[this.tableIndex!] = newString; - this.prefix[this.tableIndex!] = string; - this.tableIndex = this.tableIndex! + 1; - - if (this.tableIndex === 511) { - this.bitsToGet = 10; - } else if (this.tableIndex === 1023) { - this.bitsToGet = 11; - } else if (this.tableIndex === 2047) { - this.bitsToGet = 12; + this._table[this._tableIndex!] = newString; + this._prefix[this._tableIndex!] = string; + this._tableIndex = this._tableIndex! + 1; + + if (this._tableIndex === 511) { + this._bitsToGet = 10; + } else if (this._tableIndex === 1023) { + this._bitsToGet = 11; + } else if (this._tableIndex === 2047) { + this._bitsToGet = 12; } } private getString(code: number): void { - this.bufferLength = 0; + this._bufferLength = 0; let c = code; - this.buffer[this.bufferLength++] = this.table[c]; - c = this.prefix[c]; - while (c !== LzwDecoder.NO_SUCH_CODE) { - this.buffer[this.bufferLength++] = this.table[c]; - c = this.prefix[c]; + this._buffer[this._bufferLength++] = this._table[c]; + c = this._prefix[c]; + while (c !== LzwDecoder._noSuchCode) { + this._buffer[this._bufferLength++] = this._table[c]; + c = this._prefix[c]; } } @@ -52,23 +52,23 @@ export class LzwDecoder { * Returns the next 9, 10, 11 or 12 bits */ private getNextCode(): number { - if (this.bytePointer >= this.dataLength) { + if (this._bytePointer >= this._dataLength) { return 257; } - while (this.nextBits < this.bitsToGet) { - if (this.bytePointer >= this.dataLength) { + while (this._nextBits < this._bitsToGet) { + if (this._bytePointer >= this._dataLength) { return 257; } - this.nextData = - ((this.nextData << 8) + this.data[this.bytePointer++]) & 0xffffffff; - this.nextBits += 8; + this._nextData = + ((this._nextData << 8) + this._data[this._bytePointer++]) & 0xffffffff; + this._nextBits += 8; } - this.nextBits -= this.bitsToGet; + this._nextBits -= this._bitsToGet; const code = - (this.nextData >> this.nextBits) & - LzwDecoder.AND_TABLE[this.bitsToGet - 9]; + (this._nextData >> this._nextBits) & + LzwDecoder._andTable[this._bitsToGet - 9]; return code; } @@ -77,65 +77,65 @@ export class LzwDecoder { * Initialize the string table. */ private initializeStringTable(): void { - this.table = new Uint8Array(LzwDecoder.LZ_MAX_CODE + 1); - this.prefix = new Uint32Array(LzwDecoder.LZ_MAX_CODE + 1); - this.prefix.fill(LzwDecoder.NO_SUCH_CODE, 0, this.prefix.length); + this._table = new Uint8Array(LzwDecoder._lzMaxCode + 1); + this._prefix = new Uint32Array(LzwDecoder._lzMaxCode + 1); + this._prefix.fill(LzwDecoder._noSuchCode, 0, this._prefix.length); for (let i = 0; i < 256; i++) { - this.table[i] = i; + this._table[i] = i; } - this.bitsToGet = 9; + this._bitsToGet = 9; - this.tableIndex = 258; + this._tableIndex = 258; } public decode(p: InputBuffer, out: Uint8Array): void { - this.out = out; + this._out = out; const outLen = out.length; - this.outPointer = 0; - this.data = p.buffer; - this.dataLength = this.data.length; - this.bytePointer = p.offset; + this._outPointer = 0; + this._data = p.buffer; + this._dataLength = this._data.length; + this._bytePointer = p.offset; - if (this.data[0] === 0x00 && this.data[1] === 0x01) { - throw new ImageError('Invalid LZW Data'); + if (this._data[0] === 0x00 && this._data[1] === 0x01) { + throw new LibError('Invalid LZW Data'); } this.initializeStringTable(); - this.nextData = 0; - this.nextBits = 0; + this._nextData = 0; + this._nextBits = 0; let oldCode = 0; let code = this.getNextCode(); - while (code !== 257 && this.outPointer < outLen) { + while (code !== 257 && this._outPointer < outLen) { if (code === 256) { this.initializeStringTable(); code = this.getNextCode(); - this.bufferLength = 0; + this._bufferLength = 0; if (code === 257) { break; } - this.out[this.outPointer++] = code; + this._out[this._outPointer++] = code; oldCode = code; } else { - if (code < this.tableIndex!) { + if (code < this._tableIndex!) { this.getString(code); - for (let i = this.bufferLength - 1; i >= 0; --i) { - this.out[this.outPointer++] = this.buffer[i]; + for (let i = this._bufferLength - 1; i >= 0; --i) { + this._out[this._outPointer++] = this._buffer[i]; } - this.addString(oldCode, this.buffer[this.bufferLength - 1]); + this.addString(oldCode, this._buffer[this._bufferLength - 1]); oldCode = code; } else { this.getString(oldCode); - for (let i = this.bufferLength - 1; i >= 0; --i) { - this.out[this.outPointer++] = this.buffer[i]; + for (let i = this._bufferLength - 1; i >= 0; --i) { + this._out[this._outPointer++] = this._buffer[i]; } - this.out[this.outPointer++] = this.buffer[this.bufferLength - 1]; - this.addString(oldCode, this.buffer[this.bufferLength - 1]); + this._out[this._outPointer++] = this._buffer[this._bufferLength - 1]; + this.addString(oldCode, this._buffer[this._bufferLength - 1]); oldCode = code; } diff --git a/src/formats/tiff/tiff-photometric-type.ts b/src/formats/tiff/tiff-photometric-type.ts new file mode 100644 index 0000000..2a5a954 --- /dev/null +++ b/src/formats/tiff/tiff-photometric-type.ts @@ -0,0 +1,39 @@ +/** @format */ + +export enum TiffPhotometricType { + // 0 + whiteIsZero, + // 1 + blackIsZero, + // 2 + rgb, + // 3 + palette, + // 4 + transparencyMask, + // 5 + cmyk, + // 6 + yCbCr, + // 7 + reserved7, + // 8 + cieLab, + // 9 + iccLab, + // 10 + ituLab, + // 32844 + logL, + // 32845 + logLuv, + // 32803 + colorFilterArray, + // 34892 + linearRaw, + // 51177 + depth, + unknown, +} + +export const TiffPhotometricTypeLength = 17; diff --git a/src/formats/win-encoder.ts b/src/formats/win-encoder.ts index 3b5e25f..144cf55 100644 --- a/src/formats/win-encoder.ts +++ b/src/formats/win-encoder.ts @@ -1,9 +1,8 @@ /** @format */ -import { FrameAnimation } from '../common/frame-animation'; -import { MemoryImage } from '../common/memory-image'; import { OutputBuffer } from '../common/output-buffer'; -import { ImageError } from '../error/image-error'; +import { LibError } from '../error/lib-error'; +import { MemoryImage } from '../image/image'; import { Encoder } from './encoder'; import { PngEncoder } from './png-encoder'; @@ -13,7 +12,7 @@ export abstract class WinEncoder implements Encoder { return this._type; } - private _supportsAnimation = false; + private _supportsAnimation = true; get supportsAnimation(): boolean { return this._supportsAnimation; } @@ -26,32 +25,39 @@ export abstract class WinEncoder implements Encoder { return 0; } + public encode(image: MemoryImage, singleFrame = false): Uint8Array { + if (image.hasAnimation && !singleFrame) { + return this.encodeImages(image.frames); + } else { + return this.encodeImages([image]); + } + } + public encodeImages(images: MemoryImage[]): Uint8Array { const count = images.length; const out = new OutputBuffer(); - // Header - // Reserved + // header out.writeUint16(0); - // Type: ICO => 1; CUR => 2 - out.writeUint16(this.type); + // type: ICO => 1; CUR => 2 + out.writeUint16(this._type); out.writeUint16(count); - // File header with image directory byte size + // file header with image directory byte size let offset = 6 + count * 16; - const imageDatas: Uint8Array[] = []; + const imageDataList: Uint8Array[] = []; let i = 0; for (const img of images) { if (img.width > 256 || img.height > 256) { - throw new ImageError('ICO and CUR support only sizes until 256'); + throw new LibError('ICO and CUR support only sizes until 256'); } - // Image width in pixels + // image width in pixels out.writeByte(img.width); - // Image height in pixels + // image height in pixels out.writeByte(img.height); // Color count, should be 0 if more than 256 colors out.writeByte(0); @@ -61,32 +67,23 @@ export abstract class WinEncoder implements Encoder { out.writeUint16(this.bitsPerPixelOrYHotSpot(i)); // Use png instead of bmp encoded data, it's supported since Windows Vista - const data = new PngEncoder().encodeImage(img); + const data: Uint8Array = new PngEncoder().encode(img); - // Size of the image's data in bytes + // size of the image's data in bytes out.writeUint32(data.length); - - // Offset of data from the beginning of the file + // offset of data from the beginning of the file out.writeUint32(offset); // add the size of bytes to get the new begin of the next image offset += data.length; i++; - imageDatas.push(data); + imageDataList.push(data); } - for (const imageData of imageDatas) { + for (const imageData of imageDataList) { out.writeBytes(imageData); } return out.getBytes(); } - - public encodeImage(image: MemoryImage): Uint8Array { - return this.encodeImages([image]); - } - - public encodeAnimation(_: FrameAnimation): Uint8Array | undefined { - return undefined; - } } diff --git a/src/hdr/hdr-image.ts b/src/hdr/hdr-image.ts deleted file mode 100644 index 25c77ce..0000000 --- a/src/hdr/hdr-image.ts +++ /dev/null @@ -1,474 +0,0 @@ -/** @format */ - -import { MemoryImage } from '../common/memory-image'; -import { RgbChannelSet } from '../common/rgb-channel-set'; -import { ExifData } from '../exif/exif-data'; -import { HdrSlice } from './hdr-slice'; - -/** - * A high dynamic range RGBA image stored in 16-bit or 32-bit floating-point - * channels. - */ -export class HdrImage { - /** - * Red value of a sample - */ - private static R = 'R'; - /** - * Green value of a sample - */ - private static G = 'G'; - /** - * Blue value of a sample - */ - private static B = 'B'; - /** - * Alpha/opacity - */ - private static A = 'A'; - /** - * Distance of the front of a sample from the viewer - */ - private static Z = 'Z'; - - private readonly _slices: Map = new Map(); - public get slices(): Map { - return this._slices; - } - - private _red: HdrSlice | undefined = undefined; - public get red(): HdrSlice | undefined { - return this._red; - } - - private _green: HdrSlice | undefined = undefined; - public get green(): HdrSlice | undefined { - return this._green; - } - - private _blue: HdrSlice | undefined = undefined; - public get blue(): HdrSlice | undefined { - return this._blue; - } - - private _alpha: HdrSlice | undefined = undefined; - public get alpha(): HdrSlice | undefined { - return this._alpha; - } - - private _depth: HdrSlice | undefined = undefined; - public get depth(): HdrSlice | undefined { - return this._depth; - } - - private _exifData: ExifData | undefined = undefined; - public get exifData(): ExifData | undefined { - return this._exifData; - } - public set exifData(v: ExifData | undefined) { - this._exifData = v; - } - - /** - * Does the image have any color channels? - */ - get hasColor(): boolean { - return ( - this.red !== undefined || - this.green !== undefined || - this.blue !== undefined - ); - } - - /** - * Does the image have an alpha channel? - */ - get hasAlpha(): boolean { - return this.alpha !== undefined; - } - - /** - * Does the image have a depth channel? - */ - get hasDepth(): boolean { - return this.depth !== undefined; - } - - /** - * The width of the framebuffer. - */ - get width(): number { - if (this.slices.size > 0) { - const firstSlice = this.slices.values().next().value as HdrSlice; - return firstSlice.width; - } else { - return 0; - } - } - - /** - * The height of the framebuffer. - */ - get height(): number { - if (this.slices.size > 0) { - const firstSlice = this.slices.values().next().value as HdrSlice; - return firstSlice.height; - } else { - return 0; - } - } - - /** - * The number of bits per sample. - */ - get bitsPerSample(): number { - if (this.red !== undefined) { - return this.red.bitsPerSample; - } else { - if (this.slices.size > 0) { - const firstSlice = this.slices.values().next().value as HdrSlice; - return firstSlice.bitsPerSample; - } else { - return 0; - } - } - } - - get sampleFormat(): number { - if (this.red !== undefined) { - return this.red.format; - } else { - if (this.slices.size > 0) { - const firstSlice = this.slices.values().next().value as HdrSlice; - return firstSlice.format; - } else { - return 0; - } - } - } - - /** - * The number of channels used by the image - */ - get numberOfChannels(): number { - return this.slices.size; - } - - /** - * Create an RGB[A] image. - */ - public static create( - width: number, - height: number, - channels: number, - type: number, - bitsPerSample: number - ): HdrImage { - const image = new HdrImage(); - if (0 <= channels && channels <= 4) { - const channelList = [HdrImage.R, HdrImage.G, HdrImage.B, HdrImage.A]; - for (let i = 0; i < channels; ++i) { - image.addChannel( - new HdrSlice({ - name: channelList[i], - width: width, - height: height, - format: type, - bitsPerSample: bitsPerSample, - }) - ); - } - return image; - } else { - return image; - } - } - - /** - * Create a copy of the **other** HdrImage. - */ - public static from(other: HdrImage): HdrImage { - const image = new HdrImage(); - for (const [, value] of other.slices) { - image.addChannel(HdrSlice.from(value)); - } - return image; - } - - /** - * Create an HDR image from a LDR **MemoryImage** by transforming the channel values - * to the range [**0**, **1**]. - */ - public static fromImage( - other: MemoryImage, - type: number = HdrSlice.FLOAT, - bitsPerSample = 16 - ): HdrImage { - const image = new HdrImage(); - image.addChannel( - new HdrSlice({ - name: HdrImage.R, - width: other.width, - height: other.height, - format: type, - bitsPerSample: bitsPerSample, - }) - ); - image.addChannel( - new HdrSlice({ - name: HdrImage.G, - width: other.width, - height: other.height, - format: type, - bitsPerSample: bitsPerSample, - }) - ); - image.addChannel( - new HdrSlice({ - name: HdrImage.B, - width: other.width, - height: other.height, - format: type, - bitsPerSample: bitsPerSample, - }) - ); - if (other.rgbChannelSet === RgbChannelSet.rgba) { - image.addChannel( - new HdrSlice({ - name: HdrImage.A, - width: other.width, - height: other.height, - format: type, - bitsPerSample: bitsPerSample, - }) - ); - } - const rgb = other.getBytes(); - for (let y = 0, si = 0; y < other.height; ++y) { - for (let x = 0; x < other.width; ++x) { - image.setRed(x, y, rgb[si++] / 255); - image.setGreen(x, y, rgb[si++] / 255); - image.setBlue(x, y, rgb[si++] / 255); - if (image.alpha !== undefined) { - image.setAlpha(x, y, rgb[si++] / 255); - } - } - } - return image; - } - - /** - * Get the value of the red channel at the given pixel coordinates **x**, **y**. - */ - public getRed(x: number, y: number): number { - if (this.red !== undefined) { - return this.red.isFloat ? this.red.getFloat(x, y) : this.red.getInt(x, y); - } else { - return 0; - } - } - - /** - * Set the value of the red channel at the given pixel coordinates **x**, **y**. - */ - public setRed(x: number, y: number, c: number): void { - if (this.red !== undefined) { - if (this.red.isFloat) { - this.red.setFloat(x, y, c); - } else { - this.red.setInt(x, y, c); - } - } - } - - public setRedInt(x: number, y: number, c: number): void { - if (this.red !== undefined) { - this.red.setInt(x, y, c); - } - } - - /** - * Get the value of the green channel at the given pixel coordinates **x**, **y**. - */ - public getGreen(x: number, y: number): number { - if (this.green !== undefined) { - return this.green.isFloat - ? this.green.getFloat(x, y) - : this.green.getInt(x, y); - } else { - return 0; - } - } - - /** - * Set the value of the green channel at the given pixel coordinates **x**, **y**. - */ - public setGreen(x: number, y: number, c: number): void { - if (this.green !== undefined) { - if (this.green.isFloat) { - this.green.setFloat(x, y, c); - } else { - this.green.setInt(x, y, c); - } - } - } - - public setGreenInt(x: number, y: number, c: number): void { - if (this.green !== undefined) { - this.green.setInt(x, y, c); - } - } - - /** - * Get the value of the blue channel at the given pixel coordinates **x**, **y**. - */ - public getBlue(x: number, y: number): number { - if (this.blue !== undefined) { - return this.blue.isFloat - ? this.blue.getFloat(x, y) - : this.blue.getInt(x, y); - } else { - return 0; - } - } - /** - * Set the value of the blue channel at the given pixel coordinates **x**, **y**. - */ - public setBlue(x: number, y: number, c: number): void { - if (this.blue !== undefined) { - if (this.blue.isFloat) { - this.blue.setFloat(x, y, c); - } else { - this.blue.setInt(x, y, c); - } - } - } - - public setBlueInt(x: number, y: number, c: number): void { - if (this.blue !== undefined) { - this.blue.setInt(x, y, c); - } - } - - /** - * Get the value of the alpha channel at the given pixel coordinates **x**, **y**. - */ - public getAlpha(x: number, y: number): number { - if (this.alpha !== undefined) { - return this.alpha.isFloat - ? this.alpha.getFloat(x, y) - : this.alpha.getInt(x, y); - } else { - return 0; - } - } - - /** - * Set the value of the alpha channel at the given pixel coordinates **x**, **y**. - */ - public setAlpha(x: number, y: number, c: number): void { - if (this.alpha !== undefined) { - if (this.alpha.isFloat) { - this.alpha.setFloat(x, y, c); - } else { - this.alpha.setInt(x, y, c); - } - } - } - - public setAlphaInt(x: number, y: number, c: number): void { - if (this.alpha !== undefined) { - this.alpha.setInt(x, y, c); - } - } - - /** - * Get the value of the depth channel at the given pixel coordinates **x**, **y**. - */ - public getDepth(x: number, y: number): number { - if (this.depth !== undefined) { - return this.depth.isFloat - ? this.depth.getFloat(x, y) - : this.depth.getInt(x, y); - } else { - return 0; - } - } - - /** - * Set the value of the depth channel at the given pixel coordinates **x**, **y**. - */ - public setDepth(x: number, y: number, c: number): void { - if (this.depth !== undefined) { - if (this.depth.isFloat) { - this.depth.setFloat(x, y, c); - } else { - this.depth.setInt(x, y, c); - } - } - } - - public setDepthInt(x: number, y: number, c: number): void { - if (this.depth !== undefined) { - this.depth.setInt(x, y, c); - } - } - - /** - * Does this image contain the given channel? - */ - public hasChannel(ch: string): boolean { - return this.slices.has(ch); - } - - /** - * Access a framebuffer slice by name. - */ - public getChannel(ch: string): HdrSlice | undefined { - return this.slices.get(ch); - } - - /** - * Add a channel **slice** to the - */ - public addChannel(slice: HdrSlice): void { - const ch = slice.name; - this.slices.set(ch, slice); - switch (ch) { - case HdrImage.R: - this._red = slice; - break; - case HdrImage.G: - this._green = slice; - break; - case HdrImage.B: - this._blue = slice; - break; - case HdrImage.A: - this._alpha = slice; - break; - case HdrImage.Z: - this._depth = slice; - break; - } - } - - /** - * Convert the framebuffer to an floating-point image, as a sequence of - * floats in RGBA order. - */ - public toFloatRgba(): Float32Array { - const rgba = new Float32Array(this.width * this.height * 4); - const w = this.width; - const h = this.height; - for (let y = 0, di = 0; y < h; ++y) { - for (let x = 0; x < w; ++x) { - rgba[di++] = this.red === undefined ? 0.0 : this.red.getFloat(x, y); - rgba[di++] = this.green === undefined ? 0.0 : this.green.getFloat(x, y); - rgba[di++] = this.blue === undefined ? 0.0 : this.blue.getFloat(x, y); - rgba[di++] = this.alpha === undefined ? 1.0 : this.alpha.getFloat(x, y); - } - } - return rgba; - } -} diff --git a/src/hdr/hdr-slice.ts b/src/hdr/hdr-slice.ts deleted file mode 100644 index cb6a403..0000000 --- a/src/hdr/hdr-slice.ts +++ /dev/null @@ -1,208 +0,0 @@ -/** @format */ - -import { ArrayUtils } from '../common/array-utils'; -import { TypedArray } from '../common/typings'; -import { NotImplementedError } from '../error/not-implemented-error'; -import { Half } from './half'; - -export interface HdrSliceInitOptions { - name: string; - width: number; - height: number; - format: number; - bitsPerSample: number; - data?: TypedArray; -} - -/** - * A slice is the data for an image framebuffer for a single channel. - */ -export class HdrSlice { - public static UINT = 0; - public static INT = 1; - public static FLOAT = 3; - - private readonly _data: TypedArray; - /** - * **data** will be one of the type data lists, depending on the **type** and - * **bitsPerSample**. 16-bit FLOAT slices will be stored in a **Uint16Array**. - */ - public get data(): TypedArray { - return this._data; - } - - private readonly _name: string; - public get name(): string { - return this._name; - } - - private readonly _width: number; - public get width(): number { - return this._width; - } - - private readonly _height: number; - public get height(): number { - return this._height; - } - - /** - * Indicates the type of data stored by the slice, either **HdrSlice.INT**, - * **HdrSlice.FLOAT**, or **HdrSlice.UINT**. - */ - private readonly _format: number; - public get format(): number { - return this._format; - } - - /** - * How many bits per sample, either 8, 16, 32, or 64. - */ - private readonly _bitsPerSample: number; - public get bitsPerSample(): number { - return this._bitsPerSample; - } - - private get maxIntSize(): number { - let v = 0xffffffff; - if (this._bitsPerSample === 8) { - v = 0xff; - } else if (this._bitsPerSample === 16) { - v = 0xffff; - } - if (this._format === HdrSlice.INT) { - v -= 1; - } - return v; - } - - /** - * Does this channel store floating-point data? - */ - public get isFloat(): boolean { - return this._format === HdrSlice.FLOAT; - } - - constructor(options: HdrSliceInitOptions) { - this._name = options.name; - this._width = options.width; - this._height = options.height; - this._format = options.format; - this._bitsPerSample = options.bitsPerSample; - this._data = - options.data ?? - HdrSlice.allocateDataForType( - options.width * options.height, - options.format, - options.bitsPerSample - ); - } - - private static allocateDataForType( - size: number, - type: number, - bitsPerSample: number - ): TypedArray { - switch (type) { - case HdrSlice.INT: - if (bitsPerSample === 8) { - return new Int8Array(size); - } else if (bitsPerSample === 16) { - return new Int16Array(size); - } else if (bitsPerSample === 32) { - return new Int32Array(size); - } - break; - case HdrSlice.UINT: - if (bitsPerSample === 8) { - return new Uint8Array(size); - } else if (bitsPerSample === 16) { - return new Uint16Array(size); - } else if (bitsPerSample === 32) { - return new Uint32Array(size); - } - break; - case HdrSlice.FLOAT: - if (bitsPerSample === 16) { - return new Uint16Array(size); - } else if (bitsPerSample === 32) { - return new Float32Array(size); - } else if (bitsPerSample === 64) { - return new Float64Array(size); - } - break; - } - throw new NotImplementedError(); - } - - /** - * Create a copy of the **other** HdrSlice. - */ - public static from(other: HdrSlice): HdrSlice { - return new HdrSlice({ - name: other._name, - width: other._width, - height: other._height, - format: other._format, - bitsPerSample: other._bitsPerSample, - data: ArrayUtils.copy(other.data), - }); - } - - /** - * Get the raw bytes of the data buffer. - */ - public getBytes(): Uint8Array { - return new Uint8Array(this._data.buffer); - } - - /** - * Get the float value of the sample at the coordinates **x**,**y**. - * **Half** samples are converted to double. - */ - public getFloat(x: number, y: number): number { - const pi = y * this._width + x; - if (this._format === HdrSlice.INT || this._format === HdrSlice.UINT) { - return Math.trunc(this._data[pi]) / this.maxIntSize; - } - const s = - this._format === HdrSlice.FLOAT && this._bitsPerSample === 16 - ? Half.halfToDouble(this._data[pi]) - : this._data[pi]; - return s; - } - - /** - * Set the float value of the sample at the coordinates **x**,**y** for - * **FLOAT** slices. - */ - public setFloat(x: number, y: number, v: number): void { - if (this._format !== HdrSlice.FLOAT) { - return; - } - const pi = y * this._width + x; - if (this._bitsPerSample === 16) { - this._data[pi] = Half.doubleToHalf(v); - } else { - this._data[pi] = v; - } - } - - /** - * Get the int value of the sample at the coordinates **x**,**y**. - * An exception will occur if the slice stores FLOAT data. - */ - public getInt(x: number, y: number): number { - const pi = y * this._width + x; - return Math.trunc(this._data[pi]); - } - - /** - * Set the int value of the sample at the coordinates **x**,**y** for **INT** and - * **UINT** slices. - */ - public setInt(x: number, y: number, v: number): void { - const pi = y * this._width + x; - this._data[pi] = Math.trunc(v); - } -} diff --git a/src/hdr/hdr-to-image.ts b/src/hdr/hdr-to-image.ts deleted file mode 100644 index 8e44fbf..0000000 --- a/src/hdr/hdr-to-image.ts +++ /dev/null @@ -1,93 +0,0 @@ -/** @format */ - -import { MathOperators } from '../common/math-operators'; -import { MemoryImage } from '../common/memory-image'; -import { ImageError } from '../error/image-error'; -import { HdrImage } from './hdr-image'; - -export abstract class HdrToImage { - /** - * Convert a high dynamic range image to a low dynamic range image, - * with optional exposure control. - */ - public static hdrToImage(hdr: HdrImage, exposure?: number): MemoryImage { - const knee = (x: number, f: number) => Math.log(x * f + 1.0) / f; - const gamma = (h: number, m: number) => { - let x = Math.max(0, h * m); - if (x > 1.0) { - x = 1.0 + knee(x - 1, 0.184874); - } - return Math.pow(x, 0.4545) * 84.66; - }; - - const image = new MemoryImage({ - width: hdr.width, - height: hdr.height, - }); - const pixels = image.getBytes(); - - if (!hdr.hasColor) { - throw new ImageError('Only RGB[A] images are currently supported.'); - } - - const m = - exposure !== undefined - ? Math.pow(2.0, MathOperators.clamp(exposure + 2.47393, -20.0, 20.0)) - : 1.0; - - for (let y = 0, di = 0; y < hdr.height; ++y) { - for (let x = 0; x < hdr.width; ++x) { - let r = hdr.getRed(x, y); - let g = hdr.numberOfChannels == 1 ? r : hdr.getGreen(x, y); - let b = hdr.numberOfChannels == 1 ? r : hdr.getBlue(x, y); - - if (!Number.isFinite(r) || Number.isNaN(r)) { - r = 0.0; - } - if (!Number.isFinite(g) || Number.isNaN(g)) { - g = 0.0; - } - if (!Number.isFinite(b) || Number.isNaN(b)) { - b = 0.0; - } - - let ri = 0; - let gi = 0; - let bi = 0; - if (exposure !== undefined) { - ri = gamma(r, m); - gi = gamma(g, m); - bi = gamma(b, m); - } else { - ri = r * 255.0; - gi = g * 255.0; - bi = b * 255.0; - } - - // Normalize the color - const mi = Math.max(ri, Math.max(gi, bi)); - if (mi > 255.0) { - ri = 255.0 * (ri / mi); - gi = 255.0 * (gi / mi); - bi = 255.0 * (bi / mi); - } - - pixels[di++] = MathOperators.clampInt255(ri); - pixels[di++] = MathOperators.clampInt255(gi); - pixels[di++] = MathOperators.clampInt255(bi); - - if (hdr.alpha !== undefined) { - let a = hdr.alpha!.getFloat(x, y); - if (!Number.isFinite(a) || Number.isNaN(a)) { - a = 1.0; - } - pixels[di++] = MathOperators.clampInt255(a * 255.0); - } else { - pixels[di++] = 255; - } - } - } - - return image; - } -} diff --git a/src/image/frame-type.ts b/src/image/frame-type.ts new file mode 100644 index 0000000..5a9d6ec --- /dev/null +++ b/src/image/frame-type.ts @@ -0,0 +1,22 @@ +/** @format */ + +/** + * The type of image this frame represents. Multi-page formats, such as + * TIFF, can represent the frames of an animation as pages in a document. + */ +export enum FrameType { + /** + * The frames of this document are to be interpreted as animation. + */ + animation, + + /** + * The frames of this document are to be interpreted as pages of a document. + */ + page, + + /** + * The frames of this document are to be interpreted as a sequence of images. + */ + sequence, +} diff --git a/src/common/heap-node.ts b/src/image/heap-node.ts similarity index 100% rename from src/common/heap-node.ts rename to src/image/heap-node.ts diff --git a/src/common/iccp-compression-mode.ts b/src/image/icc-profile-compression.ts similarity index 50% rename from src/common/iccp-compression-mode.ts rename to src/image/icc-profile-compression.ts index 2474e58..abc44dd 100644 --- a/src/common/iccp-compression-mode.ts +++ b/src/image/icc-profile-compression.ts @@ -1,6 +1,6 @@ /** @format */ -export enum ICCPCompressionMode { +export enum IccProfileCompression { none, deflate, } diff --git a/src/common/icc-profile-data.ts b/src/image/icc-profile.ts similarity index 59% rename from src/common/icc-profile-data.ts rename to src/image/icc-profile.ts index c02d612..58c1e39 100644 --- a/src/common/icc-profile-data.ts +++ b/src/image/icc-profile.ts @@ -1,20 +1,20 @@ /** @format */ -import { deflate, inflate } from 'uzip'; -import { ICCPCompressionMode } from './iccp-compression-mode'; -import { ArrayUtils } from './array-utils'; +import { inflate, deflate } from 'uzip'; +import { ArrayUtils } from '../common/array-utils'; +import { IccProfileCompression } from './icc-profile-compression'; /** * ICC Profile data stored with an image. */ -export class ICCProfileData { +export class IccProfile { private _name: string; public get name(): string { return this._name; } - private _compression: ICCPCompressionMode; - public get compression(): ICCPCompressionMode { + private _compression: IccProfileCompression; + public get compression(): IccProfileCompression { return this._compression; } @@ -25,7 +25,7 @@ export class ICCProfileData { constructor( name: string, - compression: ICCPCompressionMode, + compression: IccProfileCompression, data: Uint8Array ) { this._name = name; @@ -33,8 +33,8 @@ export class ICCProfileData { this._data = data; } - public static from(other: ICCProfileData) { - return new ICCProfileData( + public static from(other: IccProfile) { + return new IccProfile( other._name, other._compression, ArrayUtils.copyUint8(other._data) @@ -45,11 +45,11 @@ export class ICCProfileData { * Returns the compressed data of the ICC Profile, compressing the stored data as necessary. */ public compressed(): Uint8Array { - if (this._compression === ICCPCompressionMode.deflate) { + if (this._compression === IccProfileCompression.deflate) { return this._data; } this._data = deflate(this._data); - this._compression = ICCPCompressionMode.deflate; + this._compression = IccProfileCompression.deflate; return this._data; } @@ -57,11 +57,15 @@ export class ICCProfileData { * Returns the uncompressed data of the ICC Profile, decompressing the stored data as necessary. */ public decompressed(): Uint8Array { - if (this._compression === ICCPCompressionMode.deflate) { + if (this._compression === IccProfileCompression.deflate) { return this._data; } this._data = inflate(this._data); - this._compression = ICCPCompressionMode.none; + this._compression = IccProfileCompression.none; return this._data; } + + public clone(): IccProfile { + return IccProfile.from(this); + } } diff --git a/src/image/image-data-float16.ts b/src/image/image-data-float16.ts new file mode 100644 index 0000000..eb425ba --- /dev/null +++ b/src/image/image-data-float16.ts @@ -0,0 +1,305 @@ +/** @format */ + +import { ChannelOrder } from '../color/channel-order'; +import { Color } from '../color/color'; +import { Format, FormatType } from '../color/format'; +import { MemoryImageData } from './image-data'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; +import { PixelFloat16 } from './pixel-float16'; +import { PixelRangeIterator } from './pixel-range-iterator'; +import { ColorFloat16 } from '../color/color-float16'; +import { Float16 } from '../common/float16'; + +export class MemoryImageDataFloat16 + implements MemoryImageData, Iterable +{ + private readonly _width: number; + public get width(): number { + return this._width; + } + + private readonly _height: number; + public get height(): number { + return this._height; + } + + private readonly _data: Uint16Array; + public get data(): Uint16Array { + return this._data; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get format(): Format { + return Format.float16; + } + + public get formatType(): FormatType { + return FormatType.float; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get rowStride(): number { + return this._width * this._numChannels * 2; + } + + public get iterator(): PixelFloat16 { + return PixelFloat16.imageData(this); + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get length(): number { + return this._data.byteLength; + } + + public get maxChannelValue(): number { + return 1; + } + + public get maxIndexValue(): number { + return 1; + } + + public get hasPalette(): boolean { + return this.palette !== undefined; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get isLdrFormat(): boolean { + return !this.isHdrFormat; + } + + public get bitsPerChannel(): number { + return 16; + } + + constructor( + width: number, + height: number, + numChannels: number, + data?: Uint16Array + ) { + this._width = width; + this._height = height; + this._numChannels = numChannels; + this._data = + data ?? new Uint16Array(this._width * this._height * this._numChannels); + } + + public static from( + other: MemoryImageDataFloat16, + skipPixels = false + ): MemoryImageDataFloat16 { + const data = skipPixels + ? new Uint16Array(other.data.length) + : other.data.slice(); + return new MemoryImageDataFloat16( + other.width, + other.height, + other._numChannels, + data + ); + } + + public getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator { + return new PixelRangeIterator( + PixelFloat16.imageData(this), + x, + y, + width, + height + ); + } + + public getColor(r: number, g: number, b: number, a?: number): Color { + return a === undefined + ? ColorFloat16.rgb(r, g, b) + : ColorFloat16.rgba(r, g, b, a); + } + + public getPixel(x: number, y: number, pixel?: Pixel): Pixel { + let p = pixel; + if (p === undefined || !(p instanceof PixelFloat16) || p.image !== this) { + p = PixelFloat16.imageData(this); + } + p.setPosition(x, y); + return p; + } + + public setPixel(x: number, y: number, p: Color): void { + this.setPixelRgba(x, y, p.r, p.g, p.b, p.a); + } + + public setPixelR(x: number, y: number, r: number): void { + const index = y * this._width * this._numChannels + x * this.numChannels; + this.data[index] = Float16.doubleToFloat16(r); + } + + public setPixelRgb( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + const index = y * this._width * this._numChannels + x * this._numChannels; + this._data[index] = Float16.doubleToFloat16(r); + if (this._numChannels > 1) { + this._data[index + 1] = Float16.doubleToFloat16(g); + if (this._numChannels > 2) { + this._data[index + 2] = Float16.doubleToFloat16(b); + } + } + } + + public setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + const index = y * this._width * this._numChannels + x * this._numChannels; + this._data[index] = Float16.doubleToFloat16(r); + if (this._numChannels > 1) { + this._data[index + 1] = Float16.doubleToFloat16(g); + if (this._numChannels > 2) { + this._data[index + 2] = Float16.doubleToFloat16(b); + if (this._numChannels > 3) { + this._data[index + 3] = Float16.doubleToFloat16(a); + } + } + } + } + + public setPixelRgbSafe( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgb(x, y, r, g, b); + } + + public setPixelRgbaSafe( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgba(x, y, r, g, b, a); + } + + public clear(_c?: Color): void {} + + public clone(skipPixels = false): MemoryImageDataFloat16 { + return MemoryImageDataFloat16.from(this, skipPixels); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } + + public getBytes(order?: ChannelOrder | undefined): Uint8Array { + if (order === undefined) { + return this.toUint8Array(); + } + + if (this.numChannels === 4) { + if ( + order === ChannelOrder.abgr || + order === ChannelOrder.argb || + order === ChannelOrder.bgra + ) { + const tempImage = this.clone(); + if (order === ChannelOrder.abgr) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (order === ChannelOrder.argb) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (order === ChannelOrder.bgra) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + return tempImage.toUint8Array(); + } + } else if (this.numChannels === 3) { + if (order === ChannelOrder.bgr) { + const tempImage = this.clone(); + for (const p of tempImage) { + const r = p.r; + p.r = p.b; + p.b = r; + } + return tempImage.toUint8Array(); + } + } + + return this.toUint8Array(); + } + + public toString(): string { + return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`; + } + + public [Symbol.iterator](): Iterator { + return PixelFloat16.imageData(this); + } +} diff --git a/src/image/image-data-float32.ts b/src/image/image-data-float32.ts new file mode 100644 index 0000000..a9d842a --- /dev/null +++ b/src/image/image-data-float32.ts @@ -0,0 +1,304 @@ +/** @format */ + +import { ChannelOrder } from '../color/channel-order'; +import { Color } from '../color/color'; +import { Format, FormatType } from '../color/format'; +import { MemoryImageData } from './image-data'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; +import { PixelFloat32 } from './pixel-float32'; +import { PixelRangeIterator } from './pixel-range-iterator'; +import { ColorFloat32 } from '../color/color-float32'; + +export class MemoryImageDataFloat32 + implements MemoryImageData, Iterable +{ + private readonly _width: number; + public get width(): number { + return this._width; + } + + private readonly _height: number; + public get height(): number { + return this._height; + } + + private readonly _data: Float32Array; + public get data(): Float32Array { + return this._data; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get format(): Format { + return Format.float32; + } + + public get formatType(): FormatType { + return FormatType.float; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get rowStride(): number { + return this._width * this._numChannels * 4; + } + + public get iterator(): PixelFloat32 { + return PixelFloat32.imageData(this); + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get length(): number { + return this._data.byteLength; + } + + public get maxChannelValue(): number { + return 1; + } + + public get maxIndexValue(): number { + return 1; + } + + public get hasPalette(): boolean { + return this.palette !== undefined; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get isLdrFormat(): boolean { + return !this.isHdrFormat; + } + + public get bitsPerChannel(): number { + return 32; + } + + constructor( + width: number, + height: number, + numChannels: number, + data?: Float32Array + ) { + this._width = width; + this._height = height; + this._numChannels = numChannels; + this._data = + data ?? new Float32Array(this._width * this._height * this._numChannels); + } + + public static from( + other: MemoryImageDataFloat32, + skipPixels = false + ): MemoryImageDataFloat32 { + const data = skipPixels + ? new Float32Array(other.data.length) + : other.data.slice(); + return new MemoryImageDataFloat32( + other.width, + other.height, + other._numChannels, + data + ); + } + + public getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator { + return new PixelRangeIterator( + PixelFloat32.imageData(this), + x, + y, + width, + height + ); + } + + public getColor(r: number, g: number, b: number, a?: number): Color { + return a === undefined + ? ColorFloat32.rgb(r, g, b) + : ColorFloat32.rgba(r, g, b, a); + } + + public getPixel(x: number, y: number, pixel?: Pixel): Pixel { + let p = pixel; + if (p === undefined || !(p instanceof PixelFloat32) || p.image !== this) { + p = PixelFloat32.imageData(this); + } + p.setPosition(x, y); + return p; + } + + public setPixel(x: number, y: number, p: Color): void { + this.setPixelRgba(x, y, p.r, p.g, p.b, p.a); + } + + public setPixelR(x: number, y: number, r: number): void { + const index = y * this._width * this._numChannels + x * this.numChannels; + this.data[index] = r; + } + + public setPixelRgb( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + const index = y * this._width * this._numChannels + x * this._numChannels; + this._data[index] = r; + if (this._numChannels > 1) { + this._data[index + 1] = g; + if (this._numChannels > 2) { + this._data[index + 2] = b; + } + } + } + + public setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + const index = y * this._width * this._numChannels + x * this._numChannels; + this._data[index] = r; + if (this._numChannels > 1) { + this._data[index + 1] = g; + if (this._numChannels > 2) { + this._data[index + 2] = b; + if (this._numChannels > 3) { + this._data[index + 3] = a; + } + } + } + } + + public setPixelRgbSafe( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgb(x, y, r, g, b); + } + + public setPixelRgbaSafe( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgba(x, y, r, g, b, a); + } + + public clear(_c?: Color): void {} + + public clone(skipPixels = false): MemoryImageDataFloat32 { + return MemoryImageDataFloat32.from(this, skipPixels); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } + + public getBytes(order?: ChannelOrder | undefined): Uint8Array { + if (order === undefined) { + return this.toUint8Array(); + } + + if (this.numChannels === 4) { + if ( + order === ChannelOrder.abgr || + order === ChannelOrder.argb || + order === ChannelOrder.bgra + ) { + const tempImage = this.clone(); + if (order === ChannelOrder.abgr) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (order === ChannelOrder.argb) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (order === ChannelOrder.bgra) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + return tempImage.toUint8Array(); + } + } else if (this.numChannels === 3) { + if (order === ChannelOrder.bgr) { + const tempImage = this.clone(); + for (const p of tempImage) { + const r = p.r; + p.r = p.b; + p.b = r; + } + return tempImage.toUint8Array(); + } + } + + return this.toUint8Array(); + } + + public toString(): string { + return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`; + } + + public [Symbol.iterator](): Iterator { + return PixelFloat32.imageData(this); + } +} diff --git a/src/image/image-data-float64.ts b/src/image/image-data-float64.ts new file mode 100644 index 0000000..570b73d --- /dev/null +++ b/src/image/image-data-float64.ts @@ -0,0 +1,305 @@ +/** @format */ + +import { ChannelOrder } from '../color/channel-order'; +import { Color } from '../color/color'; +import { Format, FormatType } from '../color/format'; +import { MemoryImageData } from './image-data'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; +import { PixelFloat64 } from './pixel-float64'; +import { PixelRangeIterator } from './pixel-range-iterator'; +import { ColorFloat64 } from '../color/color-float64'; + +export class MemoryImageDataFloat64 + implements MemoryImageData, Iterable +{ + private readonly _width: number; + public get width(): number { + return this._width; + } + + private readonly _height: number; + public get height(): number { + return this._height; + } + + private readonly _data: Float64Array; + public get data(): Float64Array { + return this._data; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get format(): Format { + return Format.float64; + } + + public get formatType(): FormatType { + return FormatType.float; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get rowStride(): number { + return this._width * this._numChannels * 8; + } + + public get iterator(): PixelFloat64 { + return PixelFloat64.imageData(this); + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get length(): number { + return this._data.byteLength; + } + + public get maxChannelValue(): number { + return 1; + } + + public get maxIndexValue(): number { + return 1; + } + + public get hasPalette(): boolean { + return this.palette !== undefined; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get isLdrFormat(): boolean { + return !this.isHdrFormat; + } + + public get bitsPerChannel(): number { + return 64; + } + + constructor( + width: number, + height: number, + numChannels: number, + data?: Float64Array + ) { + this._width = width; + this._height = height; + this._numChannels = numChannels; + this._data = + data ?? + new Float64Array(this._width * this._height * 4 * this._numChannels); + } + + public static from( + other: MemoryImageDataFloat64, + skipPixels = false + ): MemoryImageDataFloat64 { + const data = skipPixels + ? new Float64Array(other.data.length) + : other.data.slice(); + return new MemoryImageDataFloat64( + other.width, + other.height, + other._numChannels, + data + ); + } + + public getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator { + return new PixelRangeIterator( + PixelFloat64.imageData(this), + x, + y, + width, + height + ); + } + + public getColor(r: number, g: number, b: number, a?: number): Color { + return a === undefined + ? ColorFloat64.rgb(r, g, b) + : ColorFloat64.rgba(r, g, b, a); + } + + public getPixel(x: number, y: number, pixel?: Pixel): Pixel { + let p = pixel; + if (p === undefined || !(p instanceof PixelFloat64) || p.image !== this) { + p = PixelFloat64.imageData(this); + } + p.setPosition(x, y); + return p; + } + + public setPixel(x: number, y: number, p: Color): void { + this.setPixelRgba(x, y, p.r, p.g, p.b, p.a); + } + + public setPixelR(x: number, y: number, r: number): void { + const index = y * this._width * this._numChannels + x * this.numChannels; + this.data[index] = r; + } + + public setPixelRgb( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + const index = y * this._width * this._numChannels + x * this._numChannels; + this._data[index] = r; + if (this._numChannels > 1) { + this._data[index + 1] = g; + if (this._numChannels > 2) { + this._data[index + 2] = b; + } + } + } + + public setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + const index = y * this._width * this._numChannels + x * this._numChannels; + this._data[index] = r; + if (this._numChannels > 1) { + this._data[index + 1] = g; + if (this._numChannels > 2) { + this._data[index + 2] = b; + if (this._numChannels > 3) { + this._data[index + 3] = a; + } + } + } + } + + public setPixelRgbSafe( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgb(x, y, r, g, b); + } + + public setPixelRgbaSafe( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgba(x, y, r, g, b, a); + } + + public clear(_c?: Color): void {} + + public clone(skipPixels = false): MemoryImageDataFloat64 { + return MemoryImageDataFloat64.from(this, skipPixels); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } + + public getBytes(order?: ChannelOrder | undefined): Uint8Array { + if (order === undefined) { + return this.toUint8Array(); + } + + if (this.numChannels === 4) { + if ( + order === ChannelOrder.abgr || + order === ChannelOrder.argb || + order === ChannelOrder.bgra + ) { + const tempImage = this.clone(); + if (order === ChannelOrder.abgr) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (order === ChannelOrder.argb) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (order === ChannelOrder.bgra) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + return tempImage.toUint8Array(); + } + } else if (this.numChannels === 3) { + if (order === ChannelOrder.bgr) { + const tempImage = this.clone(); + for (const p of tempImage) { + const r = p.r; + p.r = p.b; + p.b = r; + } + return tempImage.toUint8Array(); + } + } + + return this.toUint8Array(); + } + + public toString(): string { + return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`; + } + + public [Symbol.iterator](): Iterator { + return PixelFloat64.imageData(this); + } +} diff --git a/src/image/image-data-int16.ts b/src/image/image-data-int16.ts new file mode 100644 index 0000000..626d4e3 --- /dev/null +++ b/src/image/image-data-int16.ts @@ -0,0 +1,307 @@ +/** @format */ + +import { ChannelOrder } from '../color/channel-order'; +import { Color } from '../color/color'; +import { ColorInt16 } from '../color/color-int16'; +import { Format, FormatType } from '../color/format'; +import { MemoryImageData } from './image-data'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; +import { PixelInt16 } from './pixel-int16'; +import { PixelRangeIterator } from './pixel-range-iterator'; + +export class MemoryImageDataInt16 implements MemoryImageData, Iterable { + private readonly _width: number; + public get width(): number { + return this._width; + } + + private readonly _height: number; + public get height(): number { + return this._height; + } + + private readonly _data: Int16Array; + public get data(): Int16Array { + return this._data; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get format(): Format { + return Format.int16; + } + + public get formatType(): FormatType { + return FormatType.int; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get rowStride(): number { + return this._width * this._numChannels * 2; + } + + public get iterator(): PixelInt16 { + return PixelInt16.imageData(this); + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get length(): number { + return this._data.byteLength; + } + + public get maxChannelValue(): number { + return 0x7fff; + } + + public get maxIndexValue(): number { + return 0x7fff; + } + + public get hasPalette(): boolean { + return this.palette !== undefined; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get isLdrFormat(): boolean { + return !this.isHdrFormat; + } + + public get bitsPerChannel(): number { + return 16; + } + + constructor( + width: number, + height: number, + numChannels: number, + data?: Int16Array + ) { + this._width = width; + this._height = height; + this._numChannels = numChannels; + this._data = + data ?? new Int16Array(this._width * this._height * this._numChannels); + } + + public static from( + other: MemoryImageDataInt16, + skipPixels = false + ): MemoryImageDataInt16 { + const data = skipPixels + ? new Int16Array(other.data.length) + : other.data.slice(); + return new MemoryImageDataInt16( + other.width, + other.height, + other._numChannels, + data + ); + } + + public getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator { + return new PixelRangeIterator( + PixelInt16.imageData(this), + x, + y, + width, + height + ); + } + + public getColor(r: number, g: number, b: number, a?: number): Color { + return a === undefined + ? ColorInt16.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b)) + : ColorInt16.rgba( + Math.trunc(r), + Math.trunc(g), + Math.trunc(b), + Math.trunc(a) + ); + } + + public getPixel(x: number, y: number, pixel?: Pixel): Pixel { + let p = pixel; + if (p === undefined || !(p instanceof PixelInt16) || p.image !== this) { + p = PixelInt16.imageData(this); + } + p.setPosition(x, y); + return p; + } + + public setPixel(x: number, y: number, p: Color): void { + this.setPixelRgba(x, y, p.r, p.g, p.b, p.a); + } + + public setPixelR(x: number, y: number, r: number): void { + const index = y * this.width * this.numChannels + x * this.numChannels; + this.data[index] = Math.trunc(r); + } + + public setPixelRgb( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + const index = y * this.width * this.numChannels + x * this._numChannels; + this._data[index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[index + 2] = Math.trunc(b); + } + } + } + + public setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + const index = y * this.width * this.numChannels + x * this._numChannels; + this._data[index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[index + 2] = Math.trunc(b); + if (this._numChannels > 3) { + this._data[index + 3] = Math.trunc(a); + } + } + } + } + + public setPixelRgbSafe( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgb(x, y, r, g, b); + } + + public setPixelRgbaSafe( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgba(x, y, r, g, b, a); + } + + public clear(_c?: Color): void {} + + public clone(skipPixels = false): MemoryImageDataInt16 { + return MemoryImageDataInt16.from(this, skipPixels); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } + + public getBytes(order?: ChannelOrder | undefined): Uint8Array { + if (order === undefined) { + return this.toUint8Array(); + } + + if (this.numChannels === 4) { + if ( + order === ChannelOrder.abgr || + order === ChannelOrder.argb || + order === ChannelOrder.bgra + ) { + const tempImage = this.clone(); + if (order === ChannelOrder.abgr) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (order === ChannelOrder.argb) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (order === ChannelOrder.bgra) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + return tempImage.toUint8Array(); + } + } else if (this.numChannels === 3) { + if (order === ChannelOrder.bgr) { + const tempImage = this.clone(); + for (const p of tempImage) { + const r = p.r; + p.r = p.b; + p.b = r; + } + return tempImage.toUint8Array(); + } + } + + return this.toUint8Array(); + } + + public toString(): string { + return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`; + } + + public [Symbol.iterator](): Iterator { + return PixelInt16.imageData(this); + } +} diff --git a/src/image/image-data-int32.ts b/src/image/image-data-int32.ts new file mode 100644 index 0000000..884f47e --- /dev/null +++ b/src/image/image-data-int32.ts @@ -0,0 +1,308 @@ +/** @format */ + +import { ChannelOrder } from '../color/channel-order'; +import { Color } from '../color/color'; +import { ColorInt32 } from '../color/color-int32'; +import { Format, FormatType } from '../color/format'; +import { StringUtils } from '../common/string-utils'; +import { MemoryImageData } from './image-data'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; +import { PixelInt32 } from './pixel-int32'; +import { PixelRangeIterator } from './pixel-range-iterator'; + +export class MemoryImageDataInt32 implements MemoryImageData, Iterable { + private readonly _width: number; + public get width(): number { + return this._width; + } + + private readonly _height: number; + public get height(): number { + return this._height; + } + + private readonly _data: Int32Array; + public get data(): Int32Array { + return this._data; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get format(): Format { + return Format.int32; + } + + public get formatType(): FormatType { + return FormatType.int; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get rowStride(): number { + return this._width * this._numChannels * 4; + } + + public get iterator(): PixelInt32 { + return PixelInt32.imageData(this); + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get length(): number { + return this._data.byteLength; + } + + public get maxChannelValue(): number { + return 0x7fffffff; + } + + public get maxIndexValue(): number { + return 0x7fffffff; + } + + public get hasPalette(): boolean { + return this.palette !== undefined; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get isLdrFormat(): boolean { + return !this.isHdrFormat; + } + + public get bitsPerChannel(): number { + return 32; + } + + constructor( + width: number, + height: number, + numChannels: number, + data?: Int32Array + ) { + this._width = width; + this._height = height; + this._numChannels = numChannels; + this._data = + data ?? new Int32Array(this._width * this._height * this._numChannels); + } + + public static from( + other: MemoryImageDataInt32, + skipPixels = false + ): MemoryImageDataInt32 { + const data = skipPixels + ? new Int32Array(other.data.length) + : other.data.slice(); + return new MemoryImageDataInt32( + other.width, + other.height, + other._numChannels, + data + ); + } + + public getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator { + return new PixelRangeIterator( + PixelInt32.imageData(this), + x, + y, + width, + height + ); + } + + public getColor(r: number, g: number, b: number, a?: number): Color { + return a === undefined + ? ColorInt32.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b)) + : ColorInt32.rgba( + Math.trunc(r), + Math.trunc(g), + Math.trunc(b), + Math.trunc(a) + ); + } + + public getPixel(x: number, y: number, pixel?: Pixel): Pixel { + let p = pixel; + if (p === undefined || !(p instanceof PixelInt32) || p.image !== this) { + p = PixelInt32.imageData(this); + } + p.setPosition(x, y); + return p; + } + + public setPixel(x: number, y: number, p: Color): void { + this.setPixelRgba(x, y, p.r, p.g, p.b, p.a); + } + + public setPixelR(x: number, y: number, r: number): void { + const index = y * this.width * this.numChannels + x * this.numChannels; + this.data[index] = Math.trunc(r); + } + + public setPixelRgb( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + const index = y * this.width * this.numChannels + x * this._numChannels; + this._data[index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[index + 2] = Math.trunc(b); + } + } + } + + public setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + const index = y * this.width * this.numChannels + x * this._numChannels; + this._data[index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[index + 2] = Math.trunc(b); + if (this._numChannels > 3) { + this._data[index + 3] = Math.trunc(a); + } + } + } + } + + public setPixelRgbSafe( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgb(x, y, r, g, b); + } + + public setPixelRgbaSafe( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgba(x, y, r, g, b, a); + } + + public clear(_c?: Color): void {} + + public clone(skipPixels = false): MemoryImageDataInt32 { + return MemoryImageDataInt32.from(this, skipPixels); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } + + public getBytes(order?: ChannelOrder | undefined): Uint8Array { + if (order === undefined) { + return this.toUint8Array(); + } + + if (this.numChannels === 4) { + if ( + order === ChannelOrder.abgr || + order === ChannelOrder.argb || + order === ChannelOrder.bgra + ) { + const tempImage = this.clone(); + if (order === ChannelOrder.abgr) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (order === ChannelOrder.argb) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (order === ChannelOrder.bgra) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + return tempImage.toUint8Array(); + } + } else if (this.numChannels === 3) { + if (order === ChannelOrder.bgr) { + const tempImage = this.clone(); + for (const p of tempImage) { + const r = p.r; + p.r = p.b; + p.b = r; + } + return tempImage.toUint8Array(); + } + } + + return this.toUint8Array(); + } + + public toString(): string { + return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`; + } + + public [Symbol.iterator](): Iterator { + return PixelInt32.imageData(this); + } +} diff --git a/src/image/image-data-int8.ts b/src/image/image-data-int8.ts new file mode 100644 index 0000000..c27eaa3 --- /dev/null +++ b/src/image/image-data-int8.ts @@ -0,0 +1,307 @@ +/** @format */ + +import { ChannelOrder } from '../color/channel-order'; +import { Color } from '../color/color'; +import { ColorInt8 } from '../color/color-int8'; +import { Format, FormatType } from '../color/format'; +import { MemoryImageData } from './image-data'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; +import { PixelInt8 } from './pixel-int8'; +import { PixelRangeIterator } from './pixel-range-iterator'; + +export class MemoryImageDataInt8 implements MemoryImageData, Iterable { + private readonly _width: number; + public get width(): number { + return this._width; + } + + private readonly _height: number; + public get height(): number { + return this._height; + } + + private readonly _data: Int8Array; + public get data(): Int8Array { + return this._data; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get format(): Format { + return Format.int8; + } + + public get formatType(): FormatType { + return FormatType.int; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get rowStride(): number { + return this._width * this._numChannels; + } + + public get iterator(): PixelInt8 { + return PixelInt8.imageData(this); + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get length(): number { + return this._data.byteLength; + } + + public get maxChannelValue(): number { + return 0x7f; + } + + public get maxIndexValue(): number { + return 0x7f; + } + + public get hasPalette(): boolean { + return this.palette !== undefined; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get isLdrFormat(): boolean { + return !this.isHdrFormat; + } + + public get bitsPerChannel(): number { + return 8; + } + + constructor( + width: number, + height: number, + numChannels: number, + data?: Int8Array + ) { + this._width = width; + this._height = height; + this._numChannels = numChannels; + this._data = + data ?? new Int8Array(this._width * this._height * this._numChannels); + } + + public static from( + other: MemoryImageDataInt8, + skipPixels = false + ): MemoryImageDataInt8 { + const data = skipPixels + ? new Int8Array(other.data.length) + : other.data.slice(); + return new MemoryImageDataInt8( + other.width, + other.height, + other._numChannels, + data + ); + } + + public getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator { + return new PixelRangeIterator( + PixelInt8.imageData(this), + x, + y, + width, + height + ); + } + + public getColor(r: number, g: number, b: number, a?: number): Color { + return a === undefined + ? ColorInt8.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b)) + : ColorInt8.rgba( + Math.trunc(r), + Math.trunc(g), + Math.trunc(b), + Math.trunc(a) + ); + } + + public getPixel(x: number, y: number, pixel?: Pixel): Pixel { + let p = pixel; + if (p === undefined || !(p instanceof PixelInt8) || p.image !== this) { + p = PixelInt8.imageData(this); + } + p.setPosition(x, y); + return p; + } + + public setPixel(x: number, y: number, p: Color): void { + this.setPixelRgba(x, y, p.r, p.g, p.b, p.a); + } + + public setPixelR(x: number, y: number, r: number): void { + const index = y * this.rowStride + x * this.numChannels; + this.data[index] = Math.trunc(r); + } + + public setPixelRgb( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + const index = y * this.rowStride + x * this._numChannels; + this._data[index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[index + 2] = Math.trunc(b); + } + } + } + + public setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + const index = y * this.rowStride + x * this._numChannels; + this._data[index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[index + 2] = Math.trunc(b); + if (this._numChannels > 3) { + this._data[index + 3] = Math.trunc(a); + } + } + } + } + + public setPixelRgbSafe( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgb(x, y, r, g, b); + } + + public setPixelRgbaSafe( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgba(x, y, r, g, b, a); + } + + public clear(_c?: Color): void {} + + public clone(skipPixels = false): MemoryImageDataInt8 { + return MemoryImageDataInt8.from(this, skipPixels); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } + + public getBytes(order?: ChannelOrder | undefined): Uint8Array { + if (order === undefined) { + return this.toUint8Array(); + } + + if (this.numChannels === 4) { + if ( + order === ChannelOrder.abgr || + order === ChannelOrder.argb || + order === ChannelOrder.bgra + ) { + const tempImage = this.clone(); + if (order === ChannelOrder.abgr) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (order === ChannelOrder.argb) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (order === ChannelOrder.bgra) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + return tempImage.toUint8Array(); + } + } else if (this.numChannels === 3) { + if (order === ChannelOrder.bgr) { + const tempImage = this.clone(); + for (const p of tempImage) { + const r = p.r; + p.r = p.b; + p.b = r; + } + return tempImage.toUint8Array(); + } + } + + return this.toUint8Array(); + } + + public toString(): string { + return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`; + } + + public [Symbol.iterator](): Iterator { + return PixelInt8.imageData(this); + } +} diff --git a/src/image/image-data-uint1.ts b/src/image/image-data-uint1.ts new file mode 100644 index 0000000..a7388ba --- /dev/null +++ b/src/image/image-data-uint1.ts @@ -0,0 +1,326 @@ +/** @format */ + +import { ChannelOrder } from '../color/channel-order'; +import { Color } from '../color/color'; +import { Format, FormatType } from '../color/format'; +import { MemoryImageData } from './image-data'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; +import { PixelUint1 } from './pixel-uint1'; +import { PixelRangeIterator } from './pixel-range-iterator'; +import { ColorUint1 } from '../color/color-uint1'; + +export class MemoryImageDataUint1 implements MemoryImageData, Iterable { + private pixel?: PixelUint1; + + private readonly _width: number; + public get width(): number { + return this._width; + } + + private readonly _height: number; + public get height(): number { + return this._height; + } + + private readonly _data: Uint8Array; + public get data(): Uint8Array { + return this._data; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get format(): Format { + return Format.uint1; + } + + public get formatType(): FormatType { + return FormatType.uint; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + private _rowStride: number; + public get rowStride(): number { + return this._rowStride; + } + + public get iterator(): PixelUint1 { + return PixelUint1.imageData(this); + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get length(): number { + return this._data.byteLength; + } + + public get maxChannelValue(): number { + return this._palette?.maxChannelValue ?? 1; + } + + public get maxIndexValue(): number { + return 1; + } + + public get hasPalette(): boolean { + return this.palette !== undefined; + } + + private _palette?: Palette; + public get palette(): Palette | undefined { + return this._palette; + } + + public get isHdrFormat(): boolean { + return false; + } + + public get isLdrFormat(): boolean { + return !this.isHdrFormat; + } + + public get bitsPerChannel(): number { + return 1; + } + + constructor( + width: number, + height: number, + numChannels: number, + data?: Uint8Array + ) { + this._width = width; + this._height = height; + this._numChannels = numChannels; + this._rowStride = Math.ceil((this._width * this._numChannels) / 8); + this._palette = undefined; + this._data = + data ?? new Uint8Array(Math.max(this._rowStride * this._height, 1)); + } + + public static palette( + width: number, + height: number, + palette?: Palette + ): MemoryImageDataUint1 { + const rowStride = Math.ceil(width / 8); + const data = new Uint8Array(Math.max(rowStride * height, 1)); + const d = new MemoryImageDataUint1(width, height, 1, data); + d._rowStride = rowStride; + d._palette = palette; + return d; + } + + public static from( + other: MemoryImageDataUint1, + skipPixels = false + ): MemoryImageDataUint1 { + const data = skipPixels + ? new Uint8Array(other.data.length) + : other.data.slice(); + const d = new MemoryImageDataUint1( + other.width, + other.height, + other._numChannels, + data + ); + d._rowStride = other.rowStride; + d._palette = other.palette?.clone(); + return d; + } + + public getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator { + return new PixelRangeIterator( + PixelUint1.imageData(this), + x, + y, + width, + height + ); + } + + public getColor(r: number, g: number, b: number, a?: number): Color { + return a === undefined + ? ColorUint1.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b)) + : ColorUint1.rgba( + Math.trunc(r), + Math.trunc(g), + Math.trunc(b), + Math.trunc(a) + ); + } + + public getPixel(x: number, y: number, pixel?: Pixel): Pixel { + let p = pixel; + if (p === undefined || !(p instanceof PixelUint1) || p.image !== this) { + p = PixelUint1.imageData(this); + } + p.setPosition(x, y); + return p; + } + + public setPixel(x: number, y: number, p: Color): void { + this.setPixelRgba(x, y, p.r, p.g, p.b, p.a); + } + + public setPixelR(x: number, y: number, r: number): void { + if (this._numChannels < 1) { + return; + } + this.pixel ??= PixelUint1.imageData(this); + this.pixel.setPosition(x, y); + this.pixel.index = r; + } + + public setPixelRgb( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (this._numChannels < 1) { + return; + } + this.pixel ??= PixelUint1.imageData(this); + this.pixel.setPosition(x, y); + this.pixel.setRgb(r, g, b); + } + + public setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (this._numChannels < 1) { + return; + } + this.pixel ??= PixelUint1.imageData(this); + this.pixel.setPosition(x, y); + this.pixel.setRgba(r, g, b, a); + } + + public setPixelRgbSafe( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgb(x, y, r, g, b); + } + + public setPixelRgbaSafe( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgba(x, y, r, g, b, a); + } + + public clear(_c?: Color): void {} + + public clone(skipPixels = false): MemoryImageDataUint1 { + return MemoryImageDataUint1.from(this, skipPixels); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } + + public getBytes(order?: ChannelOrder | undefined): Uint8Array { + if (order === undefined) { + return this.toUint8Array(); + } + + if (this.numChannels === 4) { + if ( + order === ChannelOrder.abgr || + order === ChannelOrder.argb || + order === ChannelOrder.bgra + ) { + const tempImage = this.clone(); + if (order === ChannelOrder.abgr) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (order === ChannelOrder.argb) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (order === ChannelOrder.bgra) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + return tempImage.toUint8Array(); + } + } else if (this.numChannels === 3) { + if (order === ChannelOrder.bgr) { + const tempImage = this.clone(); + for (const p of tempImage) { + const r = p.r; + p.r = p.b; + p.b = r; + } + return tempImage.toUint8Array(); + } + } + + return this.toUint8Array(); + } + + public toString(): string { + return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`; + } + + public [Symbol.iterator](): Iterator { + return PixelUint1.imageData(this); + } +} diff --git a/src/image/image-data-uint16.ts b/src/image/image-data-uint16.ts new file mode 100644 index 0000000..782e985 --- /dev/null +++ b/src/image/image-data-uint16.ts @@ -0,0 +1,307 @@ +/** @format */ + +import { ChannelOrder } from '../color/channel-order'; +import { Color } from '../color/color'; +import { Format, FormatType } from '../color/format'; +import { MemoryImageData } from './image-data'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; +import { PixelUint16 } from './pixel-uint16'; +import { PixelRangeIterator } from './pixel-range-iterator'; +import { ColorUint16 } from '../color/color-uint16'; + +export class MemoryImageDataUint16 implements MemoryImageData, Iterable { + private readonly _width: number; + public get width(): number { + return this._width; + } + + private readonly _height: number; + public get height(): number { + return this._height; + } + + private readonly _data: Uint16Array; + public get data(): Uint16Array { + return this._data; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get format(): Format { + return Format.uint16; + } + + public get formatType(): FormatType { + return FormatType.uint; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get rowStride(): number { + return this._width * this._numChannels * 2; + } + + public get iterator(): PixelUint16 { + return PixelUint16.imageData(this); + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get length(): number { + return this._data.byteLength; + } + + public get maxChannelValue(): number { + return 0xffff; + } + + public get maxIndexValue(): number { + return 0xffff; + } + + public get hasPalette(): boolean { + return this.palette !== undefined; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get isLdrFormat(): boolean { + return !this.isHdrFormat; + } + + public get bitsPerChannel(): number { + return 16; + } + + constructor( + width: number, + height: number, + numChannels: number, + data?: Uint16Array + ) { + this._width = width; + this._height = height; + this._numChannels = numChannels; + this._data = + data ?? new Uint16Array(this._width * this._height * this._numChannels); + } + + public static from( + other: MemoryImageDataUint16, + skipPixels = false + ): MemoryImageDataUint16 { + const data = skipPixels + ? new Uint16Array(other.data.length) + : other.data.slice(); + return new MemoryImageDataUint16( + other.width, + other.height, + other._numChannels, + data + ); + } + + public getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator { + return new PixelRangeIterator( + PixelUint16.imageData(this), + x, + y, + width, + height + ); + } + + public getColor(r: number, g: number, b: number, a?: number): Color { + return a === undefined + ? ColorUint16.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b)) + : ColorUint16.rgba( + Math.trunc(r), + Math.trunc(g), + Math.trunc(b), + Math.trunc(a) + ); + } + + public getPixel(x: number, y: number, pixel?: Pixel): Pixel { + let p = pixel; + if (p === undefined || !(p instanceof PixelUint16) || p.image !== this) { + p = PixelUint16.imageData(this); + } + p.setPosition(x, y); + return p; + } + + public setPixel(x: number, y: number, p: Color): void { + this.setPixelRgba(x, y, p.r, p.g, p.b, p.a); + } + + public setPixelR(x: number, y: number, r: number): void { + const index = y * this._width * this._numChannels + x * this.numChannels; + this.data[index] = Math.trunc(r); + } + + public setPixelRgb( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + const index = y * this._width * this._numChannels + x * this._numChannels; + this._data[index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[index + 2] = Math.trunc(b); + } + } + } + + public setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + const index = y * this._width * this._numChannels + x * this._numChannels; + this._data[index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[index + 2] = Math.trunc(b); + if (this._numChannels > 3) { + this._data[index + 3] = Math.trunc(a); + } + } + } + } + + public setPixelRgbSafe( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgb(x, y, r, g, b); + } + + public setPixelRgbaSafe( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgba(x, y, r, g, b, a); + } + + public clear(_c?: Color): void {} + + public clone(skipPixels = false): MemoryImageDataUint16 { + return MemoryImageDataUint16.from(this, skipPixels); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } + + public getBytes(order?: ChannelOrder | undefined): Uint8Array { + if (order === undefined) { + return this.toUint8Array(); + } + + if (this.numChannels === 4) { + if ( + order === ChannelOrder.abgr || + order === ChannelOrder.argb || + order === ChannelOrder.bgra + ) { + const tempImage = this.clone(); + if (order === ChannelOrder.abgr) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (order === ChannelOrder.argb) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (order === ChannelOrder.bgra) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + return tempImage.toUint8Array(); + } + } else if (this.numChannels === 3) { + if (order === ChannelOrder.bgr) { + const tempImage = this.clone(); + for (const p of tempImage) { + const r = p.r; + p.r = p.b; + p.b = r; + } + return tempImage.toUint8Array(); + } + } + + return this.toUint8Array(); + } + + public toString(): string { + return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`; + } + + public [Symbol.iterator](): Iterator { + return PixelUint16.imageData(this); + } +} diff --git a/src/image/image-data-uint2.ts b/src/image/image-data-uint2.ts new file mode 100644 index 0000000..355706f --- /dev/null +++ b/src/image/image-data-uint2.ts @@ -0,0 +1,326 @@ +/** @format */ + +import { ChannelOrder } from '../color/channel-order'; +import { Color } from '../color/color'; +import { Format, FormatType } from '../color/format'; +import { MemoryImageData } from './image-data'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; +import { PixelUint2 } from './pixel-uint2'; +import { PixelRangeIterator } from './pixel-range-iterator'; +import { ColorUint2 } from '../color/color-uint2'; + +export class MemoryImageDataUint2 implements MemoryImageData, Iterable { + private _pixel?: PixelUint2; + + private readonly _width: number; + public get width(): number { + return this._width; + } + + private readonly _height: number; + public get height(): number { + return this._height; + } + + private readonly _data: Uint8Array; + public get data(): Uint8Array { + return this._data; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get format(): Format { + return Format.uint2; + } + + public get formatType(): FormatType { + return FormatType.uint; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + private _rowStride: number; + public get rowStride(): number { + return this._rowStride; + } + + public get iterator(): PixelUint2 { + return PixelUint2.imageData(this); + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get length(): number { + return this._data.byteLength; + } + + public get maxChannelValue(): number { + return this._palette?.maxChannelValue ?? 3; + } + + public get maxIndexValue(): number { + return 1; + } + + public get hasPalette(): boolean { + return this.palette !== undefined; + } + + private _palette?: Palette; + public get palette(): Palette | undefined { + return this._palette; + } + + public get isHdrFormat(): boolean { + return false; + } + + public get isLdrFormat(): boolean { + return !this.isHdrFormat; + } + + public get bitsPerChannel(): number { + return 2; + } + + constructor( + width: number, + height: number, + numChannels: number, + data?: Uint8Array + ) { + this._width = width; + this._height = height; + this._numChannels = numChannels; + this._rowStride = Math.ceil((this._width * (this._numChannels << 1)) / 8); + this._palette = undefined; + this._data = + data ?? new Uint8Array(Math.max(this._rowStride * this._height, 1)); + } + + public static palette( + width: number, + height: number, + palette?: Palette + ): MemoryImageDataUint2 { + const rowStride = Math.ceil(width / 4); + const data = new Uint8Array(Math.max(rowStride * height, 1)); + const d = new MemoryImageDataUint2(width, height, 1, data); + d._rowStride = rowStride; + d._palette = palette; + return d; + } + + public static from( + other: MemoryImageDataUint2, + skipPixels = false + ): MemoryImageDataUint2 { + const data = skipPixels + ? new Uint8Array(other.data.length) + : other.data.slice(); + const d = new MemoryImageDataUint2( + other.width, + other.height, + other._numChannels, + data + ); + d._rowStride = other.rowStride; + d._palette = other.palette?.clone(); + return d; + } + + public getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator { + return new PixelRangeIterator( + PixelUint2.imageData(this), + x, + y, + width, + height + ); + } + + public getColor(r: number, g: number, b: number, a?: number): Color { + return a === undefined + ? ColorUint2.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b)) + : ColorUint2.rgba( + Math.trunc(r), + Math.trunc(g), + Math.trunc(b), + Math.trunc(a) + ); + } + + public getPixel(x: number, y: number, pixel?: Pixel): Pixel { + let p = pixel; + if (p === undefined || !(p instanceof PixelUint2) || p.image !== this) { + p = PixelUint2.imageData(this); + } + p.setPosition(x, y); + return p; + } + + public setPixel(x: number, y: number, p: Color): void { + this.setPixelRgba(x, y, p.r, p.g, p.b, p.a); + } + + public setPixelR(x: number, y: number, r: number): void { + if (this._numChannels < 1) { + return; + } + this._pixel ??= PixelUint2.imageData(this); + this._pixel.setPosition(x, y); + this._pixel.index = r; + } + + public setPixelRgb( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (this._numChannels < 1) { + return; + } + this._pixel ??= PixelUint2.imageData(this); + this._pixel.setPosition(x, y); + this._pixel.setRgb(r, g, b); + } + + public setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (this._numChannels < 1) { + return; + } + this._pixel ??= PixelUint2.imageData(this); + this._pixel.setPosition(x, y); + this._pixel.setRgba(r, g, b, a); + } + + public setPixelRgbSafe( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgb(x, y, r, g, b); + } + + public setPixelRgbaSafe( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgba(x, y, r, g, b, a); + } + + public clear(_c?: Color): void {} + + public clone(skipPixels = false): MemoryImageDataUint2 { + return MemoryImageDataUint2.from(this, skipPixels); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } + + public getBytes(order?: ChannelOrder | undefined): Uint8Array { + if (order === undefined) { + return this.toUint8Array(); + } + + if (this.numChannels === 4) { + if ( + order === ChannelOrder.abgr || + order === ChannelOrder.argb || + order === ChannelOrder.bgra + ) { + const tempImage = this.clone(); + if (order === ChannelOrder.abgr) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (order === ChannelOrder.argb) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (order === ChannelOrder.bgra) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + return tempImage.toUint8Array(); + } + } else if (this.numChannels === 3) { + if (order === ChannelOrder.bgr) { + const tempImage = this.clone(); + for (const p of tempImage) { + const r = p.r; + p.r = p.b; + p.b = r; + } + return tempImage.toUint8Array(); + } + } + + return this.toUint8Array(); + } + + public toString(): string { + return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`; + } + + public [Symbol.iterator](): Iterator { + return PixelUint2.imageData(this); + } +} diff --git a/src/image/image-data-uint32.ts b/src/image/image-data-uint32.ts new file mode 100644 index 0000000..98e50b0 --- /dev/null +++ b/src/image/image-data-uint32.ts @@ -0,0 +1,307 @@ +/** @format */ + +import { ChannelOrder } from '../color/channel-order'; +import { Color } from '../color/color'; +import { Format, FormatType } from '../color/format'; +import { MemoryImageData } from './image-data'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; +import { PixelUint32 } from './pixel-uint32'; +import { PixelRangeIterator } from './pixel-range-iterator'; +import { ColorUint32 } from '../color/color-uint32'; + +export class MemoryImageDataUint32 implements MemoryImageData, Iterable { + private readonly _width: number; + public get width(): number { + return this._width; + } + + private readonly _height: number; + public get height(): number { + return this._height; + } + + private readonly _data: Uint32Array; + public get data(): Uint32Array { + return this._data; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get format(): Format { + return Format.uint32; + } + + public get formatType(): FormatType { + return FormatType.uint; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get rowStride(): number { + return this._width * this._numChannels * 4; + } + + public get iterator(): PixelUint32 { + return PixelUint32.imageData(this); + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get length(): number { + return this._data.byteLength; + } + + public get maxChannelValue(): number { + return 0xffffffff; + } + + public get maxIndexValue(): number { + return 0xffffffff; + } + + public get hasPalette(): boolean { + return this.palette !== undefined; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get isHdrFormat(): boolean { + return true; + } + + public get isLdrFormat(): boolean { + return !this.isHdrFormat; + } + + public get bitsPerChannel(): number { + return 32; + } + + constructor( + width: number, + height: number, + numChannels: number, + data?: Uint32Array + ) { + this._width = width; + this._height = height; + this._numChannels = numChannels; + this._data = + data ?? new Uint32Array(this._width * this._height * this._numChannels); + } + + public static from( + other: MemoryImageDataUint32, + skipPixels = false + ): MemoryImageDataUint32 { + const data = skipPixels + ? new Uint32Array(other.data.length) + : other.data.slice(); + return new MemoryImageDataUint32( + other.width, + other.height, + other._numChannels, + data + ); + } + + public getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator { + return new PixelRangeIterator( + PixelUint32.imageData(this), + x, + y, + width, + height + ); + } + + public getColor(r: number, g: number, b: number, a?: number): Color { + return a === undefined + ? ColorUint32.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b)) + : ColorUint32.rgba( + Math.trunc(r), + Math.trunc(g), + Math.trunc(b), + Math.trunc(a) + ); + } + + public getPixel(x: number, y: number, pixel?: Pixel): Pixel { + let p = pixel; + if (p === undefined || !(p instanceof PixelUint32) || p.image !== this) { + p = PixelUint32.imageData(this); + } + p.setPosition(x, y); + return p; + } + + public setPixel(x: number, y: number, p: Color): void { + this.setPixelRgba(x, y, p.r, p.g, p.b, p.a); + } + + public setPixelR(x: number, y: number, r: number): void { + const index = y * this._width * this._numChannels + x * this.numChannels; + this.data[index] = Math.trunc(r); + } + + public setPixelRgb( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + const index = y * this._width * this._numChannels + x * this._numChannels; + this._data[index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[index + 2] = Math.trunc(b); + } + } + } + + public setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + const index = y * this._width * this._numChannels + x * this._numChannels; + this._data[index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[index + 2] = Math.trunc(b); + if (this._numChannels > 3) { + this._data[index + 3] = Math.trunc(a); + } + } + } + } + + public setPixelRgbSafe( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgb(x, y, r, g, b); + } + + public setPixelRgbaSafe( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgba(x, y, r, g, b, a); + } + + public clear(_c?: Color): void {} + + public clone(skipPixels = false): MemoryImageDataUint32 { + return MemoryImageDataUint32.from(this, skipPixels); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } + + public getBytes(order?: ChannelOrder | undefined): Uint8Array { + if (order === undefined) { + return this.toUint8Array(); + } + + if (this.numChannels === 4) { + if ( + order === ChannelOrder.abgr || + order === ChannelOrder.argb || + order === ChannelOrder.bgra + ) { + const tempImage = this.clone(); + if (order === ChannelOrder.abgr) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (order === ChannelOrder.argb) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (order === ChannelOrder.bgra) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + return tempImage.toUint8Array(); + } + } else if (this.numChannels === 3) { + if (order === ChannelOrder.bgr) { + const tempImage = this.clone(); + for (const p of tempImage) { + const r = p.r; + p.r = p.b; + p.b = r; + } + return tempImage.toUint8Array(); + } + } + + return this.toUint8Array(); + } + + public toString(): string { + return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`; + } + + public [Symbol.iterator](): Iterator { + return PixelUint32.imageData(this); + } +} diff --git a/src/image/image-data-uint4.ts b/src/image/image-data-uint4.ts new file mode 100644 index 0000000..29d6b8a --- /dev/null +++ b/src/image/image-data-uint4.ts @@ -0,0 +1,333 @@ +/** @format */ + +import { ChannelOrder } from '../color/channel-order'; +import { Color } from '../color/color'; +import { Format, FormatType } from '../color/format'; +import { MemoryImageData } from './image-data'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; +import { PixelUint4 } from './pixel-uint4'; +import { PixelRangeIterator } from './pixel-range-iterator'; +import { ColorUint4 } from '../color/color-uint4'; + +export class MemoryImageDataUint4 implements MemoryImageData, Iterable { + private _pixel?: PixelUint4; + + private readonly _width: number; + public get width(): number { + return this._width; + } + + private readonly _height: number; + public get height(): number { + return this._height; + } + + private readonly _data: Uint8Array; + public get data(): Uint8Array { + return this._data; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get format(): Format { + return Format.uint4; + } + + public get formatType(): FormatType { + return FormatType.uint; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + private _rowStride: number; + public get rowStride(): number { + return this._rowStride; + } + + public get iterator(): PixelUint4 { + return PixelUint4.imageData(this); + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get length(): number { + return this._data.byteLength; + } + + public get maxChannelValue(): number { + return this._palette?.maxChannelValue ?? 15; + } + + public get maxIndexValue(): number { + return 15; + } + + public get hasPalette(): boolean { + return this.palette !== undefined; + } + + private _palette?: Palette; + public get palette(): Palette | undefined { + return this._palette; + } + + public get isHdrFormat(): boolean { + return false; + } + + public get isLdrFormat(): boolean { + return !this.isHdrFormat; + } + + public get bitsPerChannel(): number { + return 4; + } + + constructor( + width: number, + height: number, + numChannels: number, + data?: Uint8Array + ) { + this._width = width; + this._height = height; + this._numChannels = numChannels; + this._rowStride = + this._numChannels === 2 + ? this._width + : this._numChannels === 4 + ? this._width * 2 + : this._numChannels === 3 + ? Math.ceil(this._width * 1.5) + : Math.ceil(this._width / 2); + this._palette = undefined; + this._data = + data ?? new Uint8Array(Math.max(this._rowStride * this._height, 1)); + } + + public static palette( + width: number, + height: number, + palette?: Palette + ): MemoryImageDataUint4 { + const rowStride = Math.ceil(width / 2); + const data = new Uint8Array(Math.max(rowStride * height, 1)); + const d = new MemoryImageDataUint4(width, height, 1, data); + d._rowStride = rowStride; + d._palette = palette; + return d; + } + + public static from( + other: MemoryImageDataUint4, + skipPixels = false + ): MemoryImageDataUint4 { + const data = skipPixels + ? new Uint8Array(other.data.length) + : other.data.slice(); + const d = new MemoryImageDataUint4( + other.width, + other.height, + other._numChannels, + data + ); + d._rowStride = other.rowStride; + d._palette = other.palette?.clone(); + return d; + } + + public getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator { + return new PixelRangeIterator( + PixelUint4.imageData(this), + x, + y, + width, + height + ); + } + + public getColor(r: number, g: number, b: number, a?: number): Color { + return a === undefined + ? ColorUint4.rgb(Math.trunc(r), Math.trunc(g), Math.trunc(b)) + : ColorUint4.rgba( + Math.trunc(r), + Math.trunc(g), + Math.trunc(b), + Math.trunc(a) + ); + } + + public getPixel(x: number, y: number, pixel?: Pixel): Pixel { + let p = pixel; + if (p === undefined || !(p instanceof PixelUint4) || p.image !== this) { + p = PixelUint4.imageData(this); + } + p.setPosition(x, y); + return p; + } + + public setPixel(x: number, y: number, p: Color): void { + this.setPixelRgba(x, y, p.r, p.g, p.b, p.a); + } + + public setPixelR(x: number, y: number, r: number): void { + if (this._numChannels < 1) { + return; + } + this._pixel ??= PixelUint4.imageData(this); + this._pixel.setPosition(x, y); + this._pixel.index = r; + } + + public setPixelRgb( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (this._numChannels < 1) { + return; + } + this._pixel ??= PixelUint4.imageData(this); + this._pixel.setPosition(x, y); + this._pixel.setRgb(r, g, b); + } + + public setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (this._numChannels < 1) { + return; + } + this._pixel ??= PixelUint4.imageData(this); + this._pixel.setPosition(x, y); + this._pixel.setRgba(r, g, b, a); + } + + public setPixelRgbSafe( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgb(x, y, r, g, b); + } + + public setPixelRgbaSafe( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgba(x, y, r, g, b, a); + } + + public clear(_c?: Color): void {} + + public clone(skipPixels = false): MemoryImageDataUint4 { + return MemoryImageDataUint4.from(this, skipPixels); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } + + public getBytes(order?: ChannelOrder | undefined): Uint8Array { + if (order === undefined) { + return this.toUint8Array(); + } + + if (this.numChannels === 4) { + if ( + order === ChannelOrder.abgr || + order === ChannelOrder.argb || + order === ChannelOrder.bgra + ) { + const tempImage = this.clone(); + if (order === ChannelOrder.abgr) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (order === ChannelOrder.argb) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (order === ChannelOrder.bgra) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + return tempImage.toUint8Array(); + } + } else if (this.numChannels === 3) { + if (order === ChannelOrder.bgr) { + const tempImage = this.clone(); + for (const p of tempImage) { + const r = p.r; + p.r = p.b; + p.b = r; + } + return tempImage.toUint8Array(); + } + } + + return this.toUint8Array(); + } + + public toString(): string { + return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`; + } + + public [Symbol.iterator](): Iterator { + return PixelUint4.imageData(this); + } +} diff --git a/src/image/image-data-uint8.ts b/src/image/image-data-uint8.ts new file mode 100644 index 0000000..b46996a --- /dev/null +++ b/src/image/image-data-uint8.ts @@ -0,0 +1,360 @@ +/** @format */ + +import { ChannelOrder } from '../color/channel-order'; +import { Color } from '../color/color'; +import { Format, FormatType } from '../color/format'; +import { MemoryImageData } from './image-data'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; +import { PixelUint8 } from './pixel-uint8'; +import { PixelRangeIterator } from './pixel-range-iterator'; +import { ColorRgb8 } from '../color/color-rgb8'; +import { ColorRgba8 } from '../color/color-rgba8'; +import { MathUtils } from '../common/math-utils'; + +export class MemoryImageDataUint8 implements MemoryImageData, Iterable { + private readonly _width: number; + public get width(): number { + return this._width; + } + + private readonly _height: number; + public get height(): number { + return this._height; + } + + private readonly _data: Uint8Array; + public get data(): Uint8Array { + return this._data; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get format(): Format { + return Format.uint8; + } + + public get formatType(): FormatType { + return FormatType.uint; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get rowStride(): number { + return this._width * this._numChannels; + } + + public get iterator(): PixelUint8 { + return PixelUint8.imageData(this); + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get length(): number { + return this._data.byteLength; + } + + public get maxChannelValue(): number { + return this._palette?.maxChannelValue ?? 255; + } + + public get maxIndexValue(): number { + return 255; + } + + public get hasPalette(): boolean { + return this.palette !== undefined; + } + + private _palette?: Palette; + public get palette(): Palette | undefined { + return this._palette; + } + + public get isHdrFormat(): boolean { + return false; + } + + public get isLdrFormat(): boolean { + return !this.isHdrFormat; + } + + public get bitsPerChannel(): number { + return 8; + } + + constructor( + width: number, + height: number, + numChannels: number, + data?: Uint8Array + ) { + this._width = width; + this._height = height; + this._numChannels = numChannels; + this._palette = undefined; + this._data = + data ?? new Uint8Array(this._width * this._height * this._numChannels); + } + + public static palette( + width: number, + height: number, + palette?: Palette + ): MemoryImageDataUint8 { + const data = new Uint8Array(width * height); + const d = new MemoryImageDataUint8(width, height, 1, data); + d._palette = palette; + return d; + } + + public static from( + other: MemoryImageDataUint8, + skipPixels = false + ): MemoryImageDataUint8 { + const data = skipPixels + ? new Uint8Array(other.data.length) + : other.data.slice(); + const d = new MemoryImageDataUint8( + other.width, + other.height, + other._numChannels, + data + ); + d._palette = other.palette?.clone(); + return d; + } + + public getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator { + return new PixelRangeIterator( + PixelUint8.imageData(this), + x, + y, + width, + height + ); + } + + public getColor(r: number, g: number, b: number, a?: number): Color { + return a === undefined + ? new ColorRgb8( + MathUtils.clampInt255(r), + MathUtils.clampInt255(g), + MathUtils.clampInt255(b) + ) + : new ColorRgba8( + MathUtils.clampInt255(r), + MathUtils.clampInt255(g), + MathUtils.clampInt255(b), + MathUtils.clampInt255(a) + ); + } + + public getPixel(x: number, y: number, pixel?: Pixel): Pixel { + let p = pixel; + if (p === undefined || !(p instanceof PixelUint8) || p.image !== this) { + p = PixelUint8.imageData(this); + } + p.setPosition(x, y); + return p; + } + + public setPixel(x: number, y: number, p: Color): void { + this.setPixelRgba(x, y, p.r, p.g, p.b, p.a); + } + + public setPixelR(x: number, y: number, r: number): void { + const index = y * this.rowStride + x * this.numChannels; + this.data[index] = Math.trunc(r); + } + + public setPixelRgb( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + const index = y * this.rowStride + x * this._numChannels; + this._data[index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[index + 2] = Math.trunc(b); + } + } + } + + public setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + const index = y * this.rowStride + x * this._numChannels; + this._data[index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[index + 2] = Math.trunc(b); + if (this._numChannels > 3) { + this._data[index + 3] = Math.trunc(a); + } + } + } + } + + public setPixelRgbSafe( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgb(x, y, r, g, b); + } + + public setPixelRgbaSafe( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return; + } + this.setPixelRgba(x, y, r, g, b, a); + } + + public clear(c?: Color): void { + const c8 = c?.convert({ + format: Format.uint8, + }); + if (this._numChannels === 1) { + const ri = c8 === undefined ? 0 : MathUtils.clampInt255(c8.r); + this._data.fill(ri); + } else if (this._numChannels === 2) { + const ri = c8 === undefined ? 0 : MathUtils.clampInt255(c8.r); + const gi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.g); + const rg = (gi << 8) | ri; + const u16 = new Uint16Array(this._data.buffer); + u16.fill(rg); + } else if (this._numChannels === 4) { + const ri = c8 === undefined ? 0 : MathUtils.clampInt255(c8.r); + const gi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.g); + const bi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.b); + const ai = c8 === undefined ? 0 : MathUtils.clampInt255(c8.a); + const rgba = (ai << 24) | (bi << 16) | (gi << 8) | ri; + const u32 = new Uint32Array(this._data.buffer); + u32.fill(rgba); + } else { + const ri = c8 === undefined ? 0 : MathUtils.clampInt255(c8.r); + const gi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.g); + const bi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.b); + // rgb is the slow case since we can't pack the channels + for (const p of this) { + p.r = ri; + p.g = gi; + p.b = bi; + } + } + } + + public clone(skipPixels = false): MemoryImageDataUint8 { + return MemoryImageDataUint8.from(this, skipPixels); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } + + public getBytes(order?: ChannelOrder | undefined): Uint8Array { + if (order === undefined) { + return this.toUint8Array(); + } + + if (this.numChannels === 4) { + if ( + order === ChannelOrder.abgr || + order === ChannelOrder.argb || + order === ChannelOrder.bgra + ) { + const tempImage = this.clone(); + if (order === ChannelOrder.abgr) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (order === ChannelOrder.argb) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (order === ChannelOrder.bgra) { + for (const p of tempImage) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + return tempImage.toUint8Array(); + } + } else if (this.numChannels === 3) { + if (order === ChannelOrder.bgr) { + const tempImage = this.clone(); + for (const p of tempImage) { + const r = p.r; + p.r = p.b; + p.b = r; + } + return tempImage.toUint8Array(); + } + } + + return this.toUint8Array(); + } + + public toString(): string { + return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`; + } + + public [Symbol.iterator](): Iterator { + return PixelUint8.imageData(this); + } +} diff --git a/src/image/image-data.ts b/src/image/image-data.ts new file mode 100644 index 0000000..6afeb83 --- /dev/null +++ b/src/image/image-data.ts @@ -0,0 +1,183 @@ +/** @format */ + +import { ChannelOrder } from '../color/channel-order'; +import { Color } from '../color/color'; +import { Format, FormatType } from '../color/format'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +export interface MemoryImageData extends Iterable { + get width(): number; + + get height(): number; + + get numChannels(): number; + + /** + * The channel **Format** of the image. + */ + get format(): Format; + + /** + * Whether the image has uint, int, or float data. + */ + get formatType(): FormatType; + + /** + * True if the image format is "high dynamic range." HDR formats include: + * float16, float32, float64, int8, int16, and int32. + */ + get isHdrFormat(): boolean; + + /** + * True if the image format is "low dynamic range." LDR formats include: + * uint1, uint2, uint4, and uint8. + */ + get isLdrFormat(): boolean; + + /** + * The number of bits per color channel. Can be 1, 2, 4, 8, 16, 32, or 64. + */ + get bitsPerChannel(): number; + + /** + * The maximum value of a pixel channel, based on the **format** of the image. + * If the image has a **palette**, this will be the maximum value of a palette + * color channel. Float format images will have a **maxChannelValue** of 1, + * though they can have values above that. + */ + get maxChannelValue(): number; + + /** + * The maximum value of a palette index, based on the **format** of the image. + * This differs from **maxChannelValue** in that it will not be affected by + * the format of the **palette**. + */ + get maxIndexValue(): number; + + /** + * True if the image has a palette. If the image has a palette, then the + * image data has 1 channel for the palette index of the pixel. + */ + get hasPalette(): boolean; + + /** + * The **Palette** of the image, or undefined if the image does not have one. + */ + get palette(): Palette | undefined; + + /** + * The size of the image data in bytes. + */ + get byteLength(): number; + + /** + * The size of the image data in bytes. + */ + get length(): number; + + /** + * The **ArrayBufferLike** storage of the image. + */ + get buffer(): ArrayBufferLike; + + /** + * The size, in bytes, of a row if pixels in the data. + */ + get rowStride(): number; + + /** + * Returns a pixel iterator for iterating over a rectangular range of pixels + * in the image. + */ + getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator; + + /** + * Create a **Color** object with the format and number of channels of the + * image. + */ + getColor(r: number, g: number, b: number, a?: number): Color; + + /** + * Return the **Pixel** at the given coordinates. If **pixel** is provided, + * it will be updated and returned rather than allocating a new **Pixel**. + */ + getPixel(x: number, y: number, pixel?: Pixel): Pixel; + + /** + * Set the color of the pixel at the given coordinates to the color of the + * given Color **c**. + */ + setPixel(x: number, y: number, c: Color): void; + + /** + * Set the red channel of the pixel, or the index value for palette images. + */ + setPixelR(x: number, y: number, r: number): void; + + /** + * Set the color of the **Pixel** at the given coordinates to the given + * color values **r**, **g**, **b**. + */ + setPixelRgb(x: number, y: number, r: number, g: number, b: number): void; + + /** + * Set the color of the **Pixel** at the given coordinates to the given + * color values **r**, **g**, **b**, and **a**. + */ + setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void; + + /** + * Calls **setPixelRgb**, but ensures **x** and **y** are within the extents + * of the image, otherwise it returns without setting the pixel. + */ + setPixelRgbSafe(x: number, y: number, r: number, g: number, b: number): void; + + /** + * Calls **setPixelRgba**, but ensures **x** and **y** are within the extents + * of the image, otherwise it returns without setting the pixel. + */ + setPixelRgbaSafe( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void; + + /** + * Set all of the pixels to the Color **c**, or all values to 0 if **c** is not + * given. + */ + clear(c?: Color): void; + + /** + * Get the copy of this image data. + */ + clone(noPixels?: boolean): MemoryImageData; + + /** + * The storage data of the image. + */ + toUint8Array(): Uint8Array; + + /** + * Similar to toUint8Array, but will convert the channels of the image pixels + * to the given **order**. If that happens, the returned bytes will be a copy + * and not a direct view of the image data. + */ + getBytes(order?: ChannelOrder): Uint8Array; +} diff --git a/src/image/image-utils.ts b/src/image/image-utils.ts new file mode 100644 index 0000000..091fb50 --- /dev/null +++ b/src/image/image-utils.ts @@ -0,0 +1,182 @@ +/** @format */ + +import { Line } from '../common/line'; +import { Point } from '../common/point'; +import { Rectangle } from '../common/rectangle'; +import { Pixel } from './pixel'; + +export abstract class ImageUtils { + /** + * Test if the pixel **p** is within the circle centered at **center** with a + * squared radius of **rad2**. This will test the corners, edges, and center + * of the pixel and return the ratio of samples within the circle. + */ + public static circleTest( + p: Pixel, + center: Point, + rad2: number, + antialias = true + ): number { + let total = 0; + const dx1 = p.x - center.x; + const dy1 = p.y - center.y; + const d1 = dx1 * dx1 + dy1 * dy1; + const r1 = d1 <= rad2 ? 1 : 0; + total += r1; + + const dx2 = p.x + 1 - center.x; + const dy2 = p.y - center.y; + const d2 = dx2 * dx2 + dy2 * dy2; + const r2 = d2 <= rad2 ? 1 : 0; + total += r2; + + const dx3 = p.x + 1 - center.x; + const dy3 = p.y + 1 - center.y; + const d3 = dx3 * dx3 + dy3 * dy3; + const r3 = d3 <= rad2 ? 1 : 0; + total += r3; + + const dx4 = p.x - center.x; + const dy4 = p.y + 1 - center.y; + const d4 = dx4 * dx4 + dy4 * dy4; + const r4 = d4 <= rad2 ? 1 : 0; + total += r4; + + const dx5 = p.x + 0.5 - center.x; + const dy5 = p.y - center.y; + const d5 = dx5 * dx5 + dy5 * dy5; + const r5 = d5 <= rad2 ? 1 : 0; + total += r5; + + const dx6 = p.x + 0.5 - center.x; + const dy6 = p.y + 1 - center.y; + const d6 = dx6 * dx6 + dy6 * dy6; + const r6 = d6 <= rad2 ? 1 : 0; + total += r6; + + const dx7 = p.x - center.x; + const dy7 = p.y + 0.5 - center.y; + const d7 = dx7 * dx7 + dy7 * dy7; + const r7 = d7 <= rad2 ? 1 : 0; + total += r7; + + const dx8 = p.x + 1 - center.x; + const dy8 = p.y + 0.5 - center.y; + const d8 = dx8 * dx8 + dy8 * dy8; + const r8 = d8 <= rad2 ? 1 : 0; + total += r8; + + const dx9 = p.x + 0.5 - center.x; + const dy9 = p.y + 0.5 - center.y; + const d9 = dx9 * dx9 + dy9 * dy9; + const r9 = d9 <= rad2 ? 1 : 0; + total += r9; + + return antialias ? total / 9 : total > 0 ? 1 : 0; + } + + /** + * Clip a line to a rectangle using the Cohen–Sutherland clipping algorithm. + * **line** is a Line object. + * **rect** is a Rectangle object. + * Results are stored in **line**. + * If **line** falls completely outside of **rect**, false is returned, otherwise + * true is returned. + */ + public static clipLine(rect: Rectangle, line: Line): boolean { + const xmin = rect.left; + const ymin = rect.top; + const xmax = rect.right; + const ymax = rect.bottom; + + // 0000 + const inside = 0; + // 0001 + const left = 1; + // 0010 + const right = 2; + // 0100 + const bottom = 4; + // 1000 + const top = 8; + + const computeOutCode = (p: Point): number => { + // initialized as being inside of clip window + let code = inside; + if (p.x < xmin) { + // to the left of clip window + code |= left; + } else if (p.x > xmax) { + // to the right of clip window + code |= right; + } + + if (p.y < ymin) { + // below the clip window + code |= bottom; + } else if (p.y > ymax) { + // above the clip window + code |= top; + } + + return code; + }; + + // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle + let outcode1 = computeOutCode(new Point(line.x1, line.y1)); + let outcode2 = computeOutCode(new Point(line.x2, line.y2)); + let accept = false; + + while (true) { + if ((outcode1 | outcode2) === 0) { + // Bitwise OR is 0. Trivially accept and get out of loop + accept = true; + break; + } else if ((outcode1 & outcode2) !== 0) { + // Bitwise AND is not 0. Trivially reject and get out of loop + break; + } else { + // failed both tests, so calculate the line segment to clip + // from an outside point to an intersection with clip edge + + // At least one endpoint is outside the clip rectangle; pick it. + const outcodeOut = outcode1 !== 0 ? outcode1 : outcode2; + + let x = 0; + let y = 0; + + // Now find the intersection point; + // use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0) + if ((outcodeOut & top) !== 0) { + // point is above the clip rectangle + x = line.x1 + Math.trunc((line.dx * (ymax - line.y1)) / line.dy); + y = ymax; + } else if ((outcodeOut & bottom) !== 0) { + // point is below the clip rectangle + x = line.x1 + Math.trunc((line.dx * (ymin - line.y1)) / line.dy); + y = ymin; + } else if ((outcodeOut & right) !== 0) { + // point is to the right of clip rectangle + y = line.y1 + Math.trunc((line.dy * (xmax - line.x1)) / line.dx); + x = xmax; + } else if ((outcodeOut & left) !== 0) { + // point is to the left of clip rectangle + y = line.y1 + Math.trunc((line.dy * (xmin - line.x1)) / line.dx); + x = xmin; + } + + // Now we move outside point to intersection point to clip + // and get ready for next pass. + if (outcodeOut === outcode1) { + line.movePoint1(x, y); + outcode1 = computeOutCode(new Point(line.x1, line.y1)); + } else { + line.movePoint2(x, y); + outcode2 = computeOutCode(new Point(line.x2, line.y2)); + } + } + } + + return accept; + } +} diff --git a/src/image/image.ts b/src/image/image.ts new file mode 100644 index 0000000..a0037d2 --- /dev/null +++ b/src/image/image.ts @@ -0,0 +1,1333 @@ +/** @format */ + +import { ChannelOrder, ChannelOrderLength } from '../color/channel-order'; +import { Color } from '../color/color'; +import { ColorUint8 } from '../color/color-uint8'; +import { ColorUtils } from '../color/color-utils'; +import { + Format, + FormatMaxValue, + FormatSize, + FormatType, +} from '../color/format'; +import { ArrayUtils } from '../common/array-utils'; +import { Interpolation } from '../common/interpolation'; +import { MathUtils } from '../common/math-utils'; +import { LibError } from '../error/lib-error'; +import { ExifData } from '../exif/exif-data'; +import { FrameType } from './frame-type'; +import { IccProfile } from './icc-profile'; +import { MemoryImageData } from './image-data'; +import { MemoryImageDataFloat16 } from './image-data-float16'; +import { MemoryImageDataFloat32 } from './image-data-float32'; +import { MemoryImageDataFloat64 } from './image-data-float64'; +import { MemoryImageDataInt16 } from './image-data-int16'; +import { MemoryImageDataInt32 } from './image-data-int32'; +import { MemoryImageDataInt8 } from './image-data-int8'; +import { MemoryImageDataUint1 } from './image-data-uint1'; +import { MemoryImageDataUint16 } from './image-data-uint16'; +import { MemoryImageDataUint2 } from './image-data-uint2'; +import { MemoryImageDataUint32 } from './image-data-uint32'; +import { MemoryImageDataUint4 } from './image-data-uint4'; +import { MemoryImageDataUint8 } from './image-data-uint8'; +import { Palette } from './palette'; +import { PaletteFloat16 } from './palette-float16'; +import { PaletteFloat32 } from './palette-float32'; +import { PaletteFloat64 } from './palette-float64'; +import { PaletteInt16 } from './palette-int16'; +import { PaletteInt32 } from './palette-int32'; +import { PaletteInt8 } from './palette-int8'; +import { PaletteUint16 } from './palette-uint16'; +import { PaletteUint32 } from './palette-uint32'; +import { PaletteUint8 } from './palette-uint8'; +import { Pixel, UndefinedPixel } from './pixel'; + +interface MemoryImageInitializeOptions { + width: number; + height: number; + format?: Format; + numChannels?: number; + withPalette?: boolean; + paletteFormat?: Format; + palette?: Palette; + exifData?: ExifData; + iccProfile?: IccProfile; +} + +export interface MemoryImageCreateOptions extends MemoryImageInitializeOptions { + loopCount?: number; + frameType?: FrameType; + frameDuration?: number; + frameIndex?: number; + backgroundColor?: Color; + textData?: Map; +} + +export interface MemoryImageFromBytesOptions extends MemoryImageCreateOptions { + bytes: ArrayBufferLike; + rowStride?: number; + channelOrder?: ChannelOrder; +} + +export interface MemoryImageCloneOptions { + skipAnimation?: boolean; + skipPixels?: boolean; +} + +export interface MemoryImageConvertOptions { + format?: Format; + numChannels?: number; + alpha?: number; + withPalette?: boolean; + skipAnimation?: boolean; +} + +export interface MemoryImageColorExtremes { + min: number; + max: number; +} + +/** + * A MemoryImage is a container for MemoryImageData and other various metadata + * representing an image in memory. + */ +export class MemoryImage implements Iterable { + private _data?: MemoryImageData; + public get data(): MemoryImageData | undefined { + return this._data; + } + + private get numPixelColors(): number { + return this.format === Format.uint1 + ? 2 + : this.format === Format.uint2 + ? 4 + : this.format === Format.uint4 + ? 16 + : this.format === Format.uint8 + ? 256 + : 0; + } + + /** + * The format of the image pixels. + */ + public get format(): Format { + return this._data?.format ?? Format.uint8; + } + + /** + * Indicates whether this image has a palette. + */ + public get hasPalette(): boolean { + return this._data?.palette !== undefined; + } + + /** + * The palette if the image has one, undefined otherwise. + */ + public get palette(): Palette | undefined { + return this._data?.palette; + } + + /** + * The number of color channels for the image. + */ + public get numChannels(): number { + return this.palette?.numChannels ?? this._data?.numChannels ?? 0; + } + + /** + * Indicates whether this image is animated. + * An image is considered animated if it has more than one frame, as the + * first image in the frames list is the image itself. + */ + public get hasAnimation(): boolean { + return this._frames.length > 1; + } + + /** + * The number of frames in this MemoryImage. A MemoryImage will have at least one + * frame, itself, so it's considered animated if it has more than one + * frame. + */ + public get numFrames(): number { + return this._frames.length; + } + + private _exifData?: ExifData; + /** + * The EXIF metadata for the image. If an ExifData hasn't been created + * for the image yet, one will be added. + */ + public get exifData(): ExifData { + this._exifData ??= new ExifData(); + return this._exifData; + } + public set exifData(exif: ExifData) { + this._exifData = exif; + } + + /** + * The maximum value of a pixel channel, based on the format of the image. + * If the image has a **palette**, this will be the maximum value of a palette + * color channel. Float format images will have a **maxChannelValue** of 1, + * though they can have values above that. + */ + public get maxChannelValue(): number { + return this._data?.maxChannelValue ?? 0; + } + + /** + * The maximum value of a palette index, based on the format of the image. + * This differs from **maxChannelValue** in that it will not be affected by + * the format of the **palette**. + */ + public get maxIndexValue(): number { + return this.data?.maxIndexValue ?? 0; + } + + /** + * Indicates whether this image supports using a palette. + */ + public get supportsPalette(): boolean { + return ( + this.format === Format.uint1 || + this.format === Format.uint2 || + this.format === Format.uint4 || + this.format === Format.uint8 + ); + } + + /** + * The width of the image in pixels. + */ + public get width(): number { + return this.data?.width ?? 0; + } + + /** + * The height of the image in pixels. + */ + public get height(): number { + return this.data?.height ?? 0; + } + + /** + * The general type of the format, whether it's uint data, int data, or + * float data (regardless of precision). + */ + public get formatType(): FormatType { + return this.data?.formatType ?? FormatType.uint; + } + + /** + * Indicates whether this image is valid and has data. + */ + public get isValid(): boolean { + return this._data !== undefined && this.width > 0 && this.height > 0; + } + + /** + * The ArrayBufferLike of the image storage data or undefined if not initialized. + */ + public get buffer(): ArrayBufferLike | undefined { + return this._data?.buffer; + } + + /** + * The length in bytes of the image data buffer. + */ + public get byteLength(): number { + return this._data?.buffer.byteLength ?? 0; + } + + /** + * The length in bytes of a row of pixels in the image buffer. + */ + public get rowStride(): number { + return this._data?.rowStride ?? 0; + } + + /** + * Indicates whether this image is a Low Dynamic Range (regular) image. + */ + public get isLdrFormat(): boolean { + return this._data?.isLdrFormat ?? false; + } + + /** + * Indicates whether this image is a High Dynamic Range image. + */ + public get isHdrFormat(): boolean { + return this._data?.isHdrFormat ?? false; + } + + /** + * The number of bits per color channel. + */ + public get bitsPerChannel(): number { + return this._data?.bitsPerChannel ?? 0; + } + + /** + * Indicates whether this MemoryImage has an alpha channel. + */ + public get hasAlpha(): boolean { + return this.numChannels === 4; + } + + /** + * Named non-color channels used by this image. + */ + private _extraChannels?: Map; + + private _iccProfile: IccProfile | undefined; + public get iccProfile(): IccProfile | undefined { + return this._iccProfile; + } + public set iccProfile(v: IccProfile | undefined) { + this._iccProfile = v; + } + + private _textData: Map | undefined; + public get textData(): Map | undefined { + return this._textData; + } + + private _backgroundColor?: Color; + /** + * The suggested background color to clear the canvas with. + */ + public get backgroundColor(): Color | undefined { + return this._backgroundColor; + } + public set backgroundColor(v: Color | undefined) { + this._backgroundColor = v; + } + + private _loopCount: number; + /** + * How many times should the animation loop (0 means forever) + */ + public get loopCount(): number { + return this._loopCount; + } + public set loopCount(v: number) { + this._loopCount = v; + } + + private _frameType: FrameType; + /** + * Gets or sets how should the frames be interpreted. + * If the **frameType** is _FrameType.animation_, the frames are part + * of an animated sequence. If the **frameType** is _FrameType.page_, + * the frames are the pages of a document. + */ + public get frameType(): FrameType { + return this._frameType; + } + public set frameType(v: FrameType) { + this._frameType = v; + } + + /** + * The list of sub-frames for the image, if it's an animation. An image + * is considered animated if it has more than one frame, as the first + * frame will be the image itself. + */ + private _frames: MemoryImage[] = []; + public get frames(): MemoryImage[] { + return this._frames; + } + + private _frameDuration: number; + /** + * How long this frame should be displayed, in milliseconds. + * A duration of 0 indicates no delay and the next frame will be drawn + * as quickly as it can. + */ + public get frameDuration(): number { + return this._frameDuration; + } + public set frameDuration(v: number) { + this._frameDuration = v; + } + + /** + * Index of this image in the parent animations frame list. + */ + private _frameIndex: number; + public get frameIndex(): number { + return this._frameIndex; + } + + constructor(opt?: MemoryImageCreateOptions) { + if (opt !== undefined) { + this._loopCount = opt.loopCount ?? 0; + this._frameType = opt.frameType ?? FrameType.sequence; + this._frameDuration = opt.frameDuration ?? 0; + this._frameIndex = opt.frameIndex ?? 0; + this._backgroundColor = opt.backgroundColor; + this._textData = opt.textData; + this._frames.push(this); + this.initialize({ + width: opt.width, + height: opt.height, + format: opt.format ?? Format.uint8, + numChannels: opt.numChannels ?? 3, + withPalette: opt.withPalette ?? false, + paletteFormat: opt.paletteFormat ?? Format.uint8, + palette: opt.palette, + exifData: opt.exifData, + iccProfile: opt.iccProfile, + }); + } else { + // create an empty image + this._loopCount = 0; + this._frameType = FrameType.sequence; + this._frameDuration = 0; + this._frameIndex = 0; + } + } + + public static fromResized( + other: MemoryImage, + width: number, + height: number, + skipAnimation = false + ): MemoryImage { + const image = new MemoryImage({ + width: width, + height: height, + loopCount: other._loopCount, + frameType: other._frameType, + frameDuration: other._frameDuration, + frameIndex: other._frameIndex, + backgroundColor: other._backgroundColor?.clone(), + format: other.format, + numChannels: other.numChannels, + withPalette: other.hasPalette, + paletteFormat: other.palette?.format, + palette: other.palette, + exifData: other._exifData?.clone(), + iccProfile: other._iccProfile?.clone(), + textData: + other._textData !== undefined + ? new Map(other._textData) + : undefined, + }); + + if (other._extraChannels !== undefined) { + image._extraChannels = new Map( + other._extraChannels + ); + } + + if (!skipAnimation) { + const numFrames = other.numFrames; + for (let fi = 1; fi < numFrames; ++fi) { + const frame = other._frames[fi]; + image.addFrame(MemoryImage.fromResized(frame, width, height)); + } + } + + return image; + } + + /** + * Creates a copy of the given **other** MemoryImage. + */ + public static from( + other: MemoryImage, + skipAnimation = false, + skipPixels = false + ): MemoryImage { + const image = new MemoryImage(); + image._data = other.data?.clone(skipPixels); + image._exifData = other._exifData?.clone(); + image._iccProfile = other.iccProfile?.clone(); + image._frameType = other.frameType; + image._loopCount = other._loopCount; + image._backgroundColor = other._backgroundColor?.clone(); + image._frameDuration = other._frameDuration; + image._frameIndex = other._frameIndex; + if (other._extraChannels !== undefined) { + image._extraChannels = new Map( + other._extraChannels + ); + } + if (other._textData !== undefined) { + image._textData = new Map(other.textData); + } + image._frames.push(image); + if (!skipAnimation && other.hasAnimation) { + const numFrames = other.numFrames; + for (let fi = 1; fi < numFrames; ++fi) { + const frame = other._frames[fi]; + image.addFrame(MemoryImage.from(frame)); + } + } + return image; + } + + /** + * Create an image from raw data in **bytes**. + * + * **format** defines the order of color channels in **bytes**. + * An HTML canvas element stores colors in _Format.rgba_ format; + * a MemoryImage object stores colors in _Format.rgba_ format. + * + * **rowStride** is the row stride, in bytes, of the source data **bytes**. + * This may be different than the rowStride of the MemoryImage, as some data + * sources align rows to different byte alignments and include padding. + * + * **order** can be used if the source **bytes** has a different channel order + * than RGBA. _ChannelOrder.bgra_ will rearrange the color channels from + * BGRA to what MemoryImage wants, RGBA. + * + * If **numChannels** and **order** are not provided, a default of 3 for + * **numChannels** and _ChannelOrder.rgba_ for **order** will be assumed. + */ + public static fromBytes(opt: MemoryImageFromBytesOptions): MemoryImage { + const image = new MemoryImage(); + image._loopCount = opt.loopCount ?? 0; + image._frameType = opt.frameType ?? FrameType.sequence; + image._frameDuration = opt.frameDuration ?? 0; + image._frameIndex = opt.frameIndex ?? 0; + image._backgroundColor = opt.backgroundColor; + image._textData = opt.textData; + image._frames.push(image); + + const format = opt.format ?? Format.uint8; + const withPalette = opt.withPalette ?? false; + const paletteFormat = opt.paletteFormat ?? Format.uint8; + const numChannels = + opt.numChannels ?? + (opt.channelOrder !== undefined + ? ChannelOrderLength.get(opt.channelOrder)! + : 3); + + if (numChannels < 0 || numChannels > 4) { + throw new LibError('A MemoryImage can only have 1-4 channels.'); + } + + let channelOrder = + opt.channelOrder ?? + (numChannels === 3 + ? ChannelOrder.rgb + : numChannels === 4 + ? ChannelOrder.rgba + : numChannels === 1 + ? ChannelOrder.red + : ChannelOrder.grayAlpha); + + if (numChannels === 1) { + // There is only one channel order + channelOrder = ChannelOrder.red; + } else if (numChannels === 2) { + // There is only one channel order + channelOrder = ChannelOrder.grayAlpha; + } else if (numChannels === 3) { + if ( + channelOrder !== ChannelOrder.rgb && + channelOrder !== ChannelOrder.bgr + ) { + // The user asked for a channel order that conflicts with the number + // of channels. + channelOrder = ChannelOrder.rgb; + } + } else if (numChannels === 4) { + if ( + channelOrder !== ChannelOrder.bgra && + channelOrder !== ChannelOrder.rgba && + channelOrder !== ChannelOrder.abgr && + channelOrder !== ChannelOrder.argb + ) { + // The user asked for a channel order that conflicts with the number + // of channels. + channelOrder = ChannelOrder.rgba; + } + } + + image.initialize({ + width: opt.width, + height: opt.height, + format: format, + numChannels: numChannels, + withPalette: withPalette, + paletteFormat: paletteFormat, + palette: opt.palette, + exifData: opt.exifData, + iccProfile: opt.iccProfile, + }); + + if (image.data !== undefined) { + const toBytes = image.data.toUint8Array(); + const fromBytes = new Uint8Array(opt.bytes); + + const rowStride = + opt.rowStride ?? opt.width * numChannels * FormatSize.get(format)!; + const dataStride = image.data.rowStride; + const stride = Math.min(rowStride, dataStride); + + let dOff = 0; + let bOff = 0; + for ( + let y = 0; + y < opt.height; + ++y, bOff += rowStride, dOff += dataStride + ) { + ArrayUtils.copyRange(fromBytes, bOff, bOff + stride, toBytes, dOff); + } + + if (numChannels === 3 && channelOrder === ChannelOrder.bgr) { + for (const p of image) { + const r = p.r; + p.r = p.b; + p.b = r; + } + } else if (numChannels === 4 && channelOrder === ChannelOrder.abgr) { + for (const p of image) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (numChannels === 4 && channelOrder === ChannelOrder.argb) { + for (const p of image) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (numChannels === 4 && channelOrder === ChannelOrder.bgra) { + for (const p of image) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + } + return image; + } + + private initialize(opt: MemoryImageInitializeOptions): void { + const format = opt.format ?? Format.uint8; + const numChannels = opt.numChannels ?? 3; + const withPalette = opt.withPalette ?? false; + const paletteFormat = opt.paletteFormat ?? Format.uint8; + + if (numChannels < 1 || numChannels > 4) { + throw new LibError( + `Invalid number of channels for image (${numChannels}). Must be between 1 and 4.` + ); + } + + this._iccProfile = opt.iccProfile; + + if (opt.exifData !== undefined) { + this._exifData = opt.exifData.clone(); + } + + const palette = + opt.palette ?? + (withPalette && this.supportsPalette + ? this.createPalette(paletteFormat, numChannels) + : undefined); + + this.createImageData(opt.width, opt.height, format, numChannels, palette); + } + + private createImageData( + width: number, + height: number, + format: Format, + numChannels: number, + palette?: Palette + ): void { + switch (format) { + case Format.uint1: + if (palette === undefined) { + this._data = new MemoryImageDataUint1(width, height, numChannels); + } else { + this._data = MemoryImageDataUint1.palette(width, height, palette); + } + break; + case Format.uint2: + if (palette === undefined) { + this._data = new MemoryImageDataUint2(width, height, numChannels); + } else { + this._data = MemoryImageDataUint2.palette(width, height, palette); + } + break; + case Format.uint4: + if (palette === undefined) { + this._data = new MemoryImageDataUint4(width, height, numChannels); + } else { + this._data = MemoryImageDataUint4.palette(width, height, palette); + } + break; + case Format.uint8: + if (palette === undefined) { + this._data = new MemoryImageDataUint8(width, height, numChannels); + } else { + this._data = MemoryImageDataUint8.palette(width, height, palette); + } + break; + case Format.uint16: + this._data = new MemoryImageDataUint16(width, height, numChannels); + break; + case Format.uint32: + this._data = new MemoryImageDataUint32(width, height, numChannels); + break; + case Format.int8: + this._data = new MemoryImageDataInt8(width, height, numChannels); + break; + case Format.int16: + this._data = new MemoryImageDataInt16(width, height, numChannels); + break; + case Format.int32: + this._data = new MemoryImageDataInt32(width, height, numChannels); + break; + case Format.float16: + this._data = new MemoryImageDataFloat16(width, height, numChannels); + break; + case Format.float32: + this._data = new MemoryImageDataFloat32(width, height, numChannels); + break; + case Format.float64: + this._data = new MemoryImageDataFloat64(width, height, numChannels); + break; + } + } + + private createPalette( + paletteFormat: Format, + numChannels: number + ): Palette | undefined { + switch (paletteFormat) { + case Format.uint1: + return undefined; + case Format.uint2: + return undefined; + case Format.uint4: + return undefined; + case Format.uint8: + return new PaletteUint8(this.numPixelColors, numChannels); + case Format.uint16: + return new PaletteUint16(this.numPixelColors, numChannels); + case Format.uint32: + return new PaletteUint32(this.numPixelColors, numChannels); + case Format.int8: + return new PaletteInt8(this.numPixelColors, numChannels); + case Format.int16: + return new PaletteInt16(this.numPixelColors, numChannels); + case Format.int32: + return new PaletteInt32(this.numPixelColors, numChannels); + case Format.float16: + return new PaletteFloat16(this.numPixelColors, numChannels); + case Format.float32: + return new PaletteFloat32(this.numPixelColors, numChannels); + case Format.float64: + return new PaletteFloat64(this.numPixelColors, numChannels); + } + throw new LibError('Unknown palette format.'); + } + + /** + * Add a frame to the animation of this MemoryImage. + */ + public addFrame(image?: MemoryImage): MemoryImage { + const img = image ?? MemoryImage.from(this, true, true); + img._frameIndex = this._frames.length; + if (this._frames[this._frames.length - 1] !== img) { + this._frames.push(img); + } + return img; + } + + /** + * Get a frame from this image. If the MemoryImage is not animated, this + * MemoryImage will be returned; otherwise the particular frame MemoryImage will + * be returned. + */ + public getFrame(index: number): MemoryImage { + return this._frames[index]; + } + + /** + * Create a copy of this image. + */ + public clone(opt?: MemoryImageCloneOptions): MemoryImage { + const skipAnimation = opt?.skipAnimation ?? false; + const skipPixels = opt?.skipPixels ?? false; + return MemoryImage.from(this, skipAnimation, skipPixels); + } + + public hasExtraChannel(name: string): boolean { + return this._extraChannels !== undefined && this._extraChannels.has(name); + } + + public getExtraChannel(name: string): MemoryImageData | undefined { + return this._extraChannels !== undefined + ? this._extraChannels.get(name) + : undefined; + } + + public setExtraChannel(name: string, data?: MemoryImageData): void { + if (this._extraChannels === undefined && data === undefined) { + return; + } + + this._extraChannels ??= new Map(); + + if (data === undefined) { + this._extraChannels.delete(name); + } else { + this._extraChannels.set(name, data); + } + + if (this._extraChannels.size === 0) { + this._extraChannels = undefined; + } + } + + /** + * Returns a pixel iterator for iterating over a rectangular range of pixels + * in the image. + */ + public getRange( + x: number, + y: number, + width: number, + height: number + ): Iterator { + return this.data!.getRange(x, y, width, height); + } + + /** + * Get a Uint8Array view of the image storage data. + */ + public toUint8Array(): Uint8Array { + return ( + this._data?.toUint8Array() ?? + (this.buffer !== undefined + ? new Uint8Array(this.buffer) + : new Uint8Array()) + ); + } + + /** + * Similar to **toUint8Array**, but will convert the channels of the image pixels + * to the given **order**. If that happens, the returned bytes will be a copy + * and not a direct view of the image data. + */ + public getBytes(order?: ChannelOrder): Uint8Array { + return this._data?.getBytes(order) ?? this.toUint8Array(); + } + + /** + * Remap the color channels to the given **order**. Normally MemoryImage color + * channels are stored in rgba order for 4 channel images, and + * rgb order for 3 channel images. This method lets you re-arrange the + * color channels in-place without needing to clone the image for preparing + * image data for external usage that requires alternative channel ordering. + */ + public remapChannels(order: ChannelOrder): void { + if (this.numChannels === 4) { + if ( + order === ChannelOrder.abgr || + order === ChannelOrder.argb || + order === ChannelOrder.bgra + ) { + if (order === ChannelOrder.abgr) { + for (const p of this) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = b; + p.b = g; + p.a = r; + } + } else if (order === ChannelOrder.argb) { + for (const p of this) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = a; + p.g = r; + p.b = g; + p.a = b; + } + } else if (order === ChannelOrder.bgra) { + for (const p of this) { + const r = p.r; + const g = p.g; + const b = p.b; + const a = p.a; + p.r = b; + p.g = g; + p.b = r; + p.a = a; + } + } + } + } else if (this.numChannels === 3) { + if (order === ChannelOrder.bgr) { + for (const p of this) { + const r = p.r; + p.r = p.b; + p.b = r; + } + } + } + } + + /** + * Returns true if the given pixel coordinates is within the dimensions + * of the image. + */ + public isBoundsSafe(x: number, y: number): boolean { + return x >= 0 && y >= 0 && x < this.width && y < this.height; + } + + /** + * Create a Color object with the format and number of channels of the + * image. + */ + public getColor(r: number, g: number, b: number, a?: number): Color { + return this._data?.getColor(r, g, b, a) ?? new ColorUint8(0); + } + + /** + * Return the Pixel at the given coordinates **x**,**y**. If **pixel** is provided, + * it will be updated and returned rather than allocating a new Pixel. + */ + public getPixel(x: number, y: number, pixel?: Pixel): Pixel { + return this._data?.getPixel(x, y, pixel) ?? UndefinedPixel; + } + + /** + * Get the pixel from the given **x**, **y** coordinate. If the pixel coordinates + * are out of bounds, PixelUndefined is returned. + */ + public getPixelSafe(x: number, y: number, pixel?: Pixel): Pixel { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return UndefinedPixel; + } + return this.getPixel(x, y, pixel); + } + + /** + * Get the pixel from the given **x**, **y** coordinate. If the pixel coordinates + * are out of range of the image, they will be clamped to the resolution. + */ + public getPixelClamped(x: number, y: number, pixel?: Pixel): Pixel { + const _x = MathUtils.clamp(x, 0, this.width - 1); + const _y = MathUtils.clamp(y, 0, this.height - 1); + return this.getPixel(_x, _y, pixel); + } + + /** + * Get the pixel using the given **interpolation** type for non-integer pixel + * coordinates. + */ + public getPixelInterpolate( + fx: number, + fy: number, + interpolation = Interpolation.linear + ): Color { + switch (interpolation) { + case Interpolation.nearest: + return this.getPixelSafe(Math.trunc(fx), Math.trunc(fy)); + case Interpolation.linear: + case Interpolation.average: + return this.getPixelLinear(fx, fy); + case Interpolation.cubic: + return this.getPixelCubic(fx, fy); + } + throw new LibError('Unknown Interpolation mode.'); + } + + /** + * Get the pixel using linear interpolation for non-integer pixel + * coordinates. + */ + public getPixelLinear(fx: number, fy: number): Color { + const x = Math.trunc(fx) - (fx >= 0 ? 0 : 1); + const nx = x + 1; + const y = Math.trunc(fy) - (fy >= 0 ? 0 : 1); + const ny = y + 1; + const dx = fx - x; + const dy = fy - y; + + const linear = ( + icc: number, + inc: number, + icn: number, + inn: number + ): number => { + return ( + icc + dx * (inc - icc + dy * (icc + inn - icn - inc)) + dy * (icn - icc) + ); + }; + + const icc = this.getPixelSafe(x, y); + const icn = ny >= this.height ? icc : this.getPixelSafe(x, ny); + const inc = nx >= this.width ? icc : this.getPixelSafe(nx, y); + const inn = + nx >= this.width || ny >= this.height ? icc : this.getPixelSafe(nx, ny); + + return this.getColor( + linear(icc.r, inc.r, icn.r, inn.r), + linear(icc.g, inc.g, icn.g, inn.g), + linear(icc.b, inc.b, icn.b, inn.b), + linear(icc.a, inc.a, icn.a, inn.a) + ); + } + + /** + * Get the pixel using cubic interpolation for non-integer pixel + * coordinates. + */ + public getPixelCubic(fx: number, fy: number): Color { + const x = Math.trunc(fx) - (fx >= 0 ? 0 : 1); + const px = x - 1; + const nx = x + 1; + const ax = x + 2; + const y = Math.trunc(fy) - (fy >= 0 ? 0 : 1); + const py = y - 1; + const ny = y + 1; + const ay = y + 2; + + const dx = fx - x; + const dy = fy - y; + + const cubic = ( + dx: number, + ipp: number, + icp: number, + inp: number, + iap: number + ): number => { + return ( + icp + + 0.5 * + (dx * (-ipp + inp) + + dx * dx * (2 * ipp - 5 * icp + 4 * inp - iap) + + dx * dx * dx * (-ipp + 3 * icp - 3 * inp + iap)) + ); + }; + + const icc = this.getPixelSafe(x, y); + + const ipp = px < 0 || py < 0 ? icc : this.getPixelSafe(px, py); + const icp = px < 0 ? icc : this.getPixelSafe(x, py); + const inp = py < 0 || nx >= this.width ? icc : this.getPixelSafe(nx, py); + const iap = ax >= this.width || py < 0 ? icc : this.getPixelSafe(ax, py); + + const ip0 = cubic(dx, ipp.r, icp.r, inp.r, iap.r); + const ip1 = cubic(dx, ipp.g, icp.g, inp.g, iap.g); + const ip2 = cubic(dx, ipp.b, icp.b, inp.b, iap.b); + const ip3 = cubic(dx, ipp.a, icp.a, inp.a, iap.a); + + const ipc = px < 0 ? icc : this.getPixelSafe(px, y); + const inc = nx >= this.width ? icc : this.getPixelSafe(nx, y); + const iac = ax >= this.width ? icc : this.getPixelSafe(ax, y); + + const ic0 = cubic(dx, ipc.r, icc.r, inc.r, iac.r); + const ic1 = cubic(dx, ipc.g, icc.g, inc.g, iac.g); + const ic2 = cubic(dx, ipc.b, icc.b, inc.b, iac.b); + const ic3 = cubic(dx, ipc.a, icc.a, inc.a, iac.a); + + const ipn = px < 0 || ny >= this.height ? icc : this.getPixelSafe(px, ny); + const icn = ny >= this.height ? icc : this.getPixelSafe(x, ny); + const inn = + nx >= this.width || ny >= this.height ? icc : this.getPixelSafe(nx, ny); + const ian = + ax >= this.width || ny >= this.height ? icc : this.getPixelSafe(ax, ny); + + const in0 = cubic(dx, ipn.r, icn.r, inn.r, ian.r); + const in1 = cubic(dx, ipn.g, icn.g, inn.g, ian.g); + const in2 = cubic(dx, ipn.b, icn.b, inn.b, ian.b); + const in3 = cubic(dx, ipn.a, icn.a, inn.a, ian.a); + + const ipa = px < 0 || ay >= this.height ? icc : this.getPixelSafe(px, ay); + const ica = ay >= this.height ? icc : this.getPixelSafe(x, ay); + const ina = + nx >= this.width || ay >= this.height ? icc : this.getPixelSafe(nx, ay); + const iaa = + ax >= this.width || ay >= this.height ? icc : this.getPixelSafe(ax, ay); + + const ia0 = cubic(dx, ipa.r, ica.r, ina.r, iaa.r); + const ia1 = cubic(dx, ipa.g, ica.g, ina.g, iaa.g); + const ia2 = cubic(dx, ipa.b, ica.b, ina.b, iaa.b); + const ia3 = cubic(dx, ipa.a, ica.a, ina.a, iaa.a); + + const c0 = cubic(dy, ip0, ic0, in0, ia0); + const c1 = cubic(dy, ip1, ic1, in1, ia1); + const c2 = cubic(dy, ip2, ic2, in2, ia2); + const c3 = cubic(dy, ip3, ic3, in3, ia3); + + return this.getColor( + Math.trunc(c0), + Math.trunc(c1), + Math.trunc(c2), + Math.trunc(c3) + ); + } + + /** + * Set the color of the pixel at the given coordinates to the color of the + * given Color **c**. + */ + public setPixel(x: number, y: number, c: Color | Pixel): void { + // TODO: improve the class check for being a Pixel + if ('image' in c && 'index' in c) { + if (c.image.hasPalette) { + if (this.hasPalette) { + this.setPixelIndex(x, y, c.index); + return; + } + } + } + this._data?.setPixelRgba(x, y, c.r, c.g, c.b, c.a); + } + + /** + * Set the index value for palette images, or the red channel otherwise. + */ + public setPixelIndex(x: number, y: number, i: number): void { + this._data?.setPixelR(x, y, i); + } + + /** + * Set the red (or index) color channel of a pixel. + */ + public setPixelR(x: number, y: number, i: number): void { + this._data?.setPixelR(x, y, i); + } + + /** + * Set the color of the Pixel at the given coordinates to the given + * color values **r**, **g**, **b**. + */ + public setPixelRgb( + x: number, + y: number, + r: number, + g: number, + b: number + ): void { + this._data?.setPixelRgb(x, y, r, g, b); + } + + /** + * Set the color of the Pixel at the given coordinates to the given + * color values **r**, **g**, **b**, and **a**. + */ + public setPixelRgba( + x: number, + y: number, + r: number, + g: number, + b: number, + a: number + ): void { + this._data?.setPixelRgba(x, y, r, g, b, a); + } + + /** + * Set all pixels in the image to the given **color**. If no color is provided + * the image will be initialized to 0. + */ + public clear(color?: Color): void { + this._data?.clear(color); + } + + /** + * Convert this image to a new **format** or number of channels, **numChannels**. + * If the new number of channels is 4 and the current image does + * not have an alpha channel, then the given **alpha** value will be used + * to set the new alpha channel. If **alpha** is not provided, then the + * **maxChannelValue** will be used to set the alpha. If **withPalette** is + * true, and to target format and **numChannels** has fewer than 256 colors, + * then the new image will be converted to use a palette. + */ + public convert(opt: MemoryImageConvertOptions): MemoryImage { + const format = opt.format ?? this.format; + const numChannels = opt.numChannels ?? this.numChannels; + const alpha = opt.alpha ?? FormatMaxValue.get(format); + let withPalette = opt.withPalette ?? false; + const skipAnimation = opt.skipAnimation ?? false; + + if ( + (withPalette && + (numChannels >= 4 || + !( + format === Format.uint1 || + format === Format.uint2 || + format === Format.uint4 || + (format === Format.uint8 && numChannels === 1) + ))) || + (format < Format.uint8 && this.format >= Format.uint8) + ) { + withPalette = false; + } + + if ( + format === this.format && + numChannels === this.numChannels && + ((!withPalette && this.palette === undefined) || + (withPalette && this.palette !== undefined)) + ) { + // Same format and number of channels + return MemoryImage.from(this); + } + + let firstFrame: MemoryImage | undefined = undefined; + for (const frame of this._frames) { + const newImage = new MemoryImage({ + width: frame.width, + height: frame.height, + format: format, + numChannels: numChannels, + withPalette: withPalette, + exifData: frame._exifData?.clone(), + iccProfile: frame._iccProfile?.clone(), + backgroundColor: frame._backgroundColor?.clone(), + frameType: frame._frameType, + loopCount: frame._loopCount, + frameDuration: frame._frameDuration, + textData: + frame._textData !== undefined + ? new Map(frame.textData) + : undefined, + }); + + if (firstFrame !== undefined) { + firstFrame.addFrame(newImage); + } else { + firstFrame = newImage; + } + + const pal = newImage.palette; + const f = newImage.palette?.format ?? format; + if (pal !== undefined) { + const usedColors = new Map(); + let numColors = 0; + const op = frame.getPixel(0, 0); + let c: Color | undefined = undefined; + for (const np of newImage) { + const nr = Math.floor(op.rNormalized * 255); + const ng = Math.floor(op.gNormalized * 255); + const nb = Math.floor(op.bNormalized * 255); + const h = ColorUtils.rgbaToUint32(nr, ng, nb, 0); + if (usedColors.has(h)) { + np.index = usedColors.get(h)!; + } else { + usedColors.set(h, numColors); + np.index = numColors; + c = ColorUtils.convertColor({ + from: op, + to: c, + format: f, + numChannels: numChannels, + alpha: alpha, + }); + pal.setRgb(numColors, c.r, c.g, c.b); + numColors++; + } + op.next(); + } + } else { + const op = frame.getPixel(0, 0); + for (const np of newImage) { + ColorUtils.convertColor({ + from: op, + to: np, + alpha: alpha, + }); + op.next(); + } + } + + if (skipAnimation) { + break; + } + } + + return firstFrame!; + } + + /** + * Add text metadata to the image. + */ + public addTextData(data: Map): void { + this._textData ??= new Map(); + for (const [key, value] of data) { + this._textData.set(key, value); + } + } + + public getColorExtremes(): MemoryImageColorExtremes { + let first = true; + let min = 0; + let max = 0; + for (const p of this) { + for (let i = 0; i < p.length; i++) { + const c = p.getChannel(i); + if (first || c < min) { + min = c; + } + if (first || c > max) { + max = c; + } + } + first = false; + } + return { + min: min, + max: max, + }; + } + + public toString(): string { + return `${this.constructor.name} (w: ${this.width}, h: ${this.height}, f: ${ + Format[this.format] + }, ch: ${this.numChannels})`; + } + + /** + * Returns a pixel iterator for iterating over all of the pixels in the + * image. + */ + public [Symbol.iterator](): Iterator { + return this._data !== undefined + ? this._data[Symbol.iterator]() + : { + next: () => + >{ + done: true, + value: UndefinedPixel, + }, + }; + } +} diff --git a/src/image/neural-quantizer.ts b/src/image/neural-quantizer.ts new file mode 100644 index 0000000..4d616b7 --- /dev/null +++ b/src/image/neural-quantizer.ts @@ -0,0 +1,633 @@ +/** @format */ + +import { Color } from '../color/color'; +import { ColorRgb8 } from '../color/color-rgb8'; +import { ColorRgba8 } from '../color/color-rgba8'; +import { MathUtils } from '../common/math-utils'; +import { MemoryImage } from './image'; +import { PaletteUint32 } from './palette-uint32'; +import { PaletteUint8 } from './palette-uint8'; +import { Pixel } from './pixel'; +import { Quantizer } from './quantizer'; + +/** + * Compute a color map with a given number of colors that best represents + * the given image. + */ +export class NeuralQuantizer implements Quantizer { + // No. of learning cycles + private static readonly _numCycles: number = 100; + + // Alpha starts at 1 + private static readonly _alphaBiasShift: number = 10; + + // Biased by 10 bits + private static readonly _initAlpha: number = + 1 << NeuralQuantizer._alphaBiasShift; + + private static readonly _radiusBiasShift: number = 8; + + private static readonly _radiusBias: number = + 1 << NeuralQuantizer._radiusBiasShift; + + private static readonly _alphaRadiusBiasShift: number = + NeuralQuantizer._alphaBiasShift + NeuralQuantizer._radiusBiasShift; + + private static readonly alphaRadiusBias: number = + 1 << NeuralQuantizer._alphaRadiusBiasShift; + + // Factor of 1/30 each cycle + private static readonly _radiusDec: number = 30; + + private static readonly _gamma: number = 1024; + + private static readonly _beta: number = 1 / 1024; + + private static readonly _betaGamma: number = + NeuralQuantizer._beta * NeuralQuantizer._gamma; + + // Four primes near 500 - assume no image has a length so large + // that it is divisible by all four primes + + private static readonly _prime1 = 499; + + private static readonly _prime2 = 491; + + private static readonly _prime3 = 487; + + private static readonly _prime4 = 503; + + private static readonly _smallImageBytes = 3 * NeuralQuantizer._prime4; + + private readonly _netIndex = new Int32Array(256); + + private _samplingFactor: number; + + // Number of colors used + private _netSize = 16; + + // Number of reserved colors used + private _specials = 3; + + // Reserved background color + private _bgColor = 0; + + private _cutNetSize = 0; + + private _maxNetPos = 0; + + // For 256 cols, radius starts at 32 + private _initRadius = 0; + + private _initBiasRadius = 0; + + private _radiusPower!: Int32Array; + + /** + * The network itself + */ + private _network!: number[]; + + private _paletteInternal!: PaletteUint32; + + private _palette!: PaletteUint8; + public get palette(): PaletteUint8 { + return this._palette; + } + + /** + * Bias array for learning + */ + private _bias!: number[]; + + // Freq array for learning + private _freq!: number[]; + + /** + * How many colors are in the **palette**? + */ + public get numColors(): number { + return this._netSize; + } + + /** + * 10 is a reasonable **samplingFactor** according to + * https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/. + */ + constructor(image: MemoryImage, numberOfColors = 256, samplingFactor = 10) { + this._samplingFactor = samplingFactor; + this.initialize(numberOfColors); + this.addImage(image); + } + + private initialize(numberOfColors: number): void { + // Number of colours used + this._netSize = Math.max(numberOfColors, 4); + this._cutNetSize = this._netSize - this._specials; + this._maxNetPos = this._netSize - 1; + // For 256 cols, radius starts at 32 + this._initRadius = Math.floor(this._netSize / 8); + this._initBiasRadius = this._initRadius * NeuralQuantizer._radiusBias; + this._paletteInternal = new PaletteUint32(256, 4); + this._palette = new PaletteUint8(256, 3); + // Number of reserved colors used + this._specials = 3; + this._bgColor = this._specials - 1; + this._radiusPower = new Int32Array(this._netSize >> 3); + + this._network = new Array(this._netSize * 3).fill(0); + this._bias = new Array(this._netSize).fill(0); + this._freq = new Array(this._netSize).fill(0); + + // Black + this._network[0] = 0.0; + this._network[1] = 0.0; + this._network[2] = 0.0; + + // White + this._network[3] = 255.0; + this._network[4] = 255.0; + this._network[5] = 255.0; + + // RESERVED bgColor + // background + const f = 1 / this._netSize; + for (let i = 0; i < this._specials; ++i) { + this._freq[i] = f; + this._bias[i] = 0.0; + } + + for ( + let i = this._specials, p = this._specials * 3; + i < this._netSize; + ++i + ) { + this._network[p++] = (255 * (i - this._specials)) / this._cutNetSize; + this._network[p++] = (255 * (i - this._specials)) / this._cutNetSize; + this._network[p++] = (255 * (i - this._specials)) / this._cutNetSize; + + this._freq[i] = f; + this._bias[i] = 0.0; + } + } + + private updateRadiusPower(rad: number, alpha: number): void { + for (let i = 0; i < rad; i++) { + this._radiusPower[i] = Math.trunc( + alpha * + (((rad * rad - i * i) * NeuralQuantizer._radiusBias) / (rad * rad)) + ); + } + } + + private specialFind(b: number, g: number, r: number): number { + for (let i = 0, p = 0; i < this._specials; i++) { + if ( + this._network[p++] === b && + this._network[p++] === g && + this._network[p++] === r + ) { + return i; + } + } + return -1; + } + + /** + * Search for biased BGR values + */ + private contest(b: number, g: number, r: number): number { + // Finds closest neuron (min dist) and updates freq + // finds best neuron (min dist-bias) and returns position + // for frequently chosen neurons, freq[i] is high and bias[i] is negative + // bias[i] = gamma*((1/netSize)-freq[i]) + + let bestD = 1.0e30; + let bestBiasDist = bestD; + let bestPos = -1; + let bestBiasPos = bestPos; + + for ( + let i = this._specials, p = this._specials * 3; + i < this._netSize; + i++ + ) { + let dist = this._network[p++] - b; + if (dist < 0) { + dist = -dist; + } + let a = this._network[p++] - g; + if (a < 0) { + a = -a; + } + dist += a; + a = this._network[p++] - r; + if (a < 0) { + a = -a; + } + dist += a; + if (dist < bestD) { + bestD = dist; + bestPos = i; + } + + const biasDist = dist - this._bias[i]; + if (biasDist < bestBiasDist) { + bestBiasDist = biasDist; + bestBiasPos = i; + } + this._freq[i] -= NeuralQuantizer._beta * this._freq[i]; + this._bias[i] += NeuralQuantizer._betaGamma * this._freq[i]; + } + + this._freq[bestPos] += NeuralQuantizer._beta; + this._bias[bestPos] -= NeuralQuantizer._betaGamma; + return bestBiasPos; + } + + private alterSingle( + alpha: number, + i: number, + b: number, + g: number, + r: number + ): void { + // Move neuron i towards biased (b,g,r) by factor alpha + const p = i * 3; + this._network[p] -= alpha * (this._network[p] - b); + this._network[p + 1] -= alpha * (this._network[p + 1] - g); + this._network[p + 2] -= alpha * (this._network[p + 2] - r); + } + + private alterNeighbors( + _: number, + rad: number, + i: number, + b: number, + g: number, + r: number + ): void { + let lo = i - rad; + if (lo < this._specials - 1) { + lo = this._specials - 1; + } + + let hi = i + rad; + if (hi > this._netSize) { + hi = this._netSize; + } + + let j = i + 1; + let k = i - 1; + let m = 1; + while (j < hi || k > lo) { + const a = this._radiusPower[m++]; + if (j < hi) { + const p = j * 3; + this._network[p] -= + (a * (this._network[p] - b)) / NeuralQuantizer.alphaRadiusBias; + this._network[p + 1] -= + (a * (this._network[p + 1] - g)) / NeuralQuantizer.alphaRadiusBias; + this._network[p + 2] -= + (a * (this._network[p + 2] - r)) / NeuralQuantizer.alphaRadiusBias; + j++; + } + if (k > lo) { + const p = k * 3; + this._network[p] -= + (a * (this._network[p] - b)) / NeuralQuantizer.alphaRadiusBias; + this._network[p + 1] -= + (a * (this._network[p + 1] - g)) / NeuralQuantizer.alphaRadiusBias; + this._network[p + 2] -= + (a * (this._network[p + 2] - r)) / NeuralQuantizer.alphaRadiusBias; + k--; + } + } + } + + private learn(image: MemoryImage): void { + let biasRadius = this._initBiasRadius; + const alphaDec = 30 + Math.floor((this._samplingFactor - 1) / 3); + const lengthCount = image.width * image.height; + const samplePixels = Math.floor(lengthCount / this._samplingFactor); + let delta = Math.max( + Math.floor(samplePixels / NeuralQuantizer._numCycles), + 1 + ); + let alpha = NeuralQuantizer._initAlpha; + + if (delta === 0) { + delta = 1; + } + + let rad = biasRadius >> NeuralQuantizer._radiusBiasShift; + if (rad <= 1) { + rad = 0; + } + + this.updateRadiusPower(rad, alpha); + + let step = 0; + let pos = 0; + if (lengthCount < NeuralQuantizer._smallImageBytes) { + this._samplingFactor = 1; + step = 1; + } else if (lengthCount % NeuralQuantizer._prime1 !== 0) { + step = NeuralQuantizer._prime1; + } else { + if (lengthCount % NeuralQuantizer._prime2 !== 0) { + step = NeuralQuantizer._prime2; + } else { + if (lengthCount % NeuralQuantizer._prime3 !== 0) { + step = NeuralQuantizer._prime3; + } else { + step = NeuralQuantizer._prime4; + } + } + } + + const w = image.width; + const h = image.height; + + let x = 0; + let y = 0; + let i = 0; + while (i < samplePixels) { + const p = image.getPixel(x, y); + + const red = p.r; + const green = p.g; + const blue = p.b; + + if (i === 0) { + // Remember background colour + this._network[this._bgColor * 3] = blue; + this._network[this._bgColor * 3 + 1] = green; + this._network[this._bgColor * 3 + 2] = red; + } + + let j = this.specialFind(blue, green, red); + j = j < 0 ? this.contest(blue, green, red) : j; + + if (j >= this._specials) { + // Don't learn for specials + const a = Number(alpha) / NeuralQuantizer._initAlpha; + this.alterSingle(a, j, blue, green, red); + if (rad > 0) { + // Alter neighbours + this.alterNeighbors(a, rad, j, blue, green, red); + } + } + + pos += step; + x += step; + while (x > w) { + x -= w; + y++; + } + while (pos >= lengthCount) { + pos -= lengthCount; + y -= h; + } + + i++; + if (i % delta === 0) { + alpha -= Math.floor(alpha / alphaDec); + biasRadius -= Math.floor(biasRadius / NeuralQuantizer._radiusDec); + rad = biasRadius >> NeuralQuantizer._radiusBiasShift; + if (rad <= 1) { + rad = 0; + } + this.updateRadiusPower(rad, alpha); + } + } + } + + private fix(): void { + for (let i = 0, p = 0; i < this._netSize; i++) { + for (let j = 0; j < 3; ++j, ++p) { + const x = MathUtils.clampInt255(Math.trunc(0.5 + this._network[p])); + this._paletteInternal.set(i, j, x); + } + this._paletteInternal.set(i, 3, i); + } + } + + /** + * Insertion sort of network and building of netindex[0..255] + */ + private inxBuild(): void { + let previousColor = 0; + let startPos = 0; + + for (let i = 0; i < this._netSize; i++) { + let smallPos = i; + // index on g + let smallVal = this._paletteInternal.get(i, 1); + + // find smallest in i..netSize-1 + for (let j = i + 1; j < this._netSize; j++) { + if (this._paletteInternal.get(j, 1) < smallVal) { + smallPos = j; + // index on g + smallVal = this._paletteInternal.get(j, 1); + } + } + + const p = i; + const q = smallPos; + + // swap p (i) and q (smallPos) entries + if (i !== smallPos) { + let j = this._paletteInternal.get(q, 0); + this._paletteInternal.set(q, 0, this._paletteInternal.get(p, 0)); + this._paletteInternal.set(p, 0, j); + + j = this._paletteInternal.get(q, 1); + this._paletteInternal.set(q, 1, this._paletteInternal.get(p, 1)); + this._paletteInternal.set(p, 1, j); + + j = this._paletteInternal.get(q, 2); + this._paletteInternal.set(q, 2, this._paletteInternal.get(p, 2)); + this._paletteInternal.set(p, 2, j); + + j = this._paletteInternal.get(q, 3); + this._paletteInternal.set(q, 3, this._paletteInternal.get(p, 3)); + this._paletteInternal.set(p, 3, j); + } + + // smallVal entry is now in position i + if (smallVal !== previousColor) { + this._netIndex[previousColor] = (startPos + i) >> 1; + for (let j = previousColor + 1; j < smallVal; j++) { + this._netIndex[j] = i; + } + previousColor = Math.trunc(smallVal); + startPos = i; + } + } + + this._netIndex[previousColor] = (startPos + this._maxNetPos) >> 1; + for (let j = previousColor + 1; j < 256; j++) { + // really 256 + this._netIndex[j] = this._maxNetPos; + } + } + + private copyPalette(): void { + for (let i = 0; i < this._netSize; ++i) { + this._palette.setRgb( + i, + Math.abs(this._paletteInternal.get(i, 2)), + Math.abs(this._paletteInternal.get(i, 1)), + Math.abs(this._paletteInternal.get(i, 0)) + ); + } + } + + /** + * Search for BGR values 0..255 and return color index + */ + private inxSearch(b: number, g: number, r: number): number { + // Biggest possible dist is 256*3 + let bestD = 1000; + let best = -1; + // Index on g + let i = this._netIndex[g]; + // Start at netIndex[g] and work outwards + let j = i - 1; + + while (i < this._netSize || j >= 0) { + if (i < this._netSize) { + // Inx key + let dist = this._paletteInternal.get(i, 1) - g; + if (dist >= bestD) { + // Stop iter + i = this._netSize; + } else { + if (dist < 0) { + dist = -dist; + } + let a = this._paletteInternal.get(i, 0) - b; + if (a < 0) { + a = -a; + } + dist += a; + if (dist < bestD) { + a = this._paletteInternal.get(i, 2) - r; + if (a < 0) { + a = -a; + } + dist += a; + if (dist < bestD) { + bestD = Math.trunc(dist); + best = i; + } + } + i++; + } + } + + if (j >= 0) { + const p = j * 4; + // Inx key - reverse dif + let dist = g - this._paletteInternal.get(j, 1); + if (dist >= bestD) { + // Stop iter + j = -1; + } else { + if (dist < 0) { + dist = -dist; + } + let a = this._paletteInternal.get(j, 0) - b; + if (a < 0) { + a = -a; + } + dist += a; + if (dist < bestD) { + a = this._paletteInternal.get(j, 2) - r; + if (a < 0) { + a = -a; + } + dist += a; + if (dist < bestD) { + bestD = Math.trunc(dist); + best = j; + } + } + j--; + } + } + } + return best; + } + + /** + * Find the index of the closest color to **c** in the **palette**. + */ + public getColorIndex(c: Color): number { + const r = Math.trunc(c.r); + const g = Math.trunc(c.g); + const b = Math.trunc(c.b); + return this.inxSearch(b, g, r); + } + + /** + * Find the index of the closest color to **r**,**g**,**b** in the **palette**. + */ + public getColorIndexRgb(r: number, g: number, b: number): number { + return this.inxSearch(b, g, r); + } + + /** + * Find the color closest to **c** in the **palette**. + */ + public getQuantizedColor(c: Color): Color { + const i = this.getColorIndex(c); + const out = + c.length === 4 ? new ColorRgba8(0, 0, 0, 255) : new ColorRgb8(0, 0, 0); + out.r = this.palette.get(i, 0); + out.g = this.palette.get(i, 1); + out.b = this.palette.get(i, 2); + if (c.length === 4) { + out.a = c.a; + } + return out; + } + + /** + * Convert the **image** to a palette image. + */ + public getIndexImage(image: MemoryImage): MemoryImage { + const target = new MemoryImage({ + width: image.width, + height: image.height, + numChannels: 1, + palette: this.palette, + }); + + const imageIt = image[Symbol.iterator](); + const targetIt = target[Symbol.iterator](); + let imageItRes: IteratorResult | undefined = undefined; + let targetItRes: IteratorResult | undefined = undefined; + while ( + (((imageItRes = imageIt.next()), (targetItRes = targetIt.next())), + !imageItRes.done && !targetItRes.done) + ) { + const t = targetItRes.value; + t.setChannel(0, this.getColorIndex(imageItRes.value)); + } + + return target; + } + + /** + * Add an image to the quantized color table. + */ + public addImage(image: MemoryImage): void { + this.learn(image); + this.fix(); + this.inxBuild(); + this.copyPalette(); + } +} diff --git a/src/common/octree-node.ts b/src/image/octree-node.ts similarity index 84% rename from src/common/octree-node.ts rename to src/image/octree-node.ts index b774595..8dd60da 100644 --- a/src/common/octree-node.ts +++ b/src/image/octree-node.ts @@ -1,5 +1,7 @@ /** @format */ +import { ArrayUtils } from '../common/array-utils'; + export class OctreeNode { // sum of all colors represented by this node. private _r = 0; @@ -42,14 +44,22 @@ export class OctreeNode { this._heapIndex = v; } + private _paletteIndex = 0; + public get paletteIndex(): number { + return this._paletteIndex; + } + public set paletteIndex(v: number) { + this._paletteIndex = v; + } + private _parent: OctreeNode | undefined; public get parent(): OctreeNode | undefined { return this._parent; } - private _children: Array = new Array< + private _children: Array = ArrayUtils.fill< OctreeNode | undefined - >(8).fill(undefined); + >(8, undefined); public get children(): Array { return this._children; } diff --git a/src/common/octree-quantizer.ts b/src/image/octree-quantizer.ts similarity index 54% rename from src/common/octree-quantizer.ts rename to src/image/octree-quantizer.ts index 1b4e85e..a0851ca 100644 --- a/src/common/octree-quantizer.ts +++ b/src/image/octree-quantizer.ts @@ -1,9 +1,12 @@ /** @format */ -import { Color } from './color'; +import { Color } from '../color/color'; +import { ColorRgb8 } from '../color/color-rgb8'; import { HeapNode } from './heap-node'; -import { MemoryImage } from './memory-image'; +import { MemoryImage } from './image'; import { OctreeNode } from './octree-node'; +import { PaletteUint8 } from './palette-uint8'; +import { Pixel } from './pixel'; import { Quantizer } from './quantizer'; /** @@ -11,19 +14,23 @@ import { Quantizer } from './quantizer'; * from https://rosettacode.org/wiki/Color_quantization/C */ export class OctreeQuantizer implements Quantizer { - private static readonly ON_INHEAP = 1; + private static readonly _inHeap = 1; - private readonly root: OctreeNode; + private readonly _root: OctreeNode; + + private _palette!: PaletteUint8; + public get palette(): PaletteUint8 { + return this._palette; + } constructor(image: MemoryImage, numberOfColors = 256) { - this.root = new OctreeNode(0, 0); + this._root = new OctreeNode(0, 0); const heap = new HeapNode(); - for (let si = 0; si < image.length; ++si) { - const c = image.getPixelByIndex(si); - const r = Color.getRed(c); - const g = Color.getGreen(c); - const b = Color.getBlue(c); - this.heapAdd(heap, this.nodeInsert(this.root, r, g, b)); + for (const p of image) { + const r = Math.trunc(p.r); + const g = Math.trunc(p.g); + const b = Math.trunc(p.b); + this.heapAdd(heap, this.nodeInsert(this._root, r, g, b)); } const nc = numberOfColors + 1; @@ -38,6 +45,17 @@ export class OctreeQuantizer implements Quantizer { got.g = Math.round(got.g / c); got.b = Math.round(got.b / c); } + + const nodes: OctreeNode[] = []; + this.getNodes(nodes, this._root); + + this._palette = new PaletteUint8(nodes.length, 3); + const l = nodes.length; + for (let i = 0; i < l; ++i) { + nodes[i].paletteIndex = i; + const n = nodes[i]; + this._palette.setRgb(i, n.r, n.g, n.b); + } } private nodeInsert( @@ -81,13 +99,13 @@ export class OctreeQuantizer implements Quantizer { } private heapAdd(h: HeapNode, p: OctreeNode): void { - if ((p.flags & OctreeQuantizer.ON_INHEAP) !== 0) { + if ((p.flags & OctreeQuantizer._inHeap) !== 0) { this.downHeap(h, p); this.upHeap(h, p); return; } - p.flags |= OctreeQuantizer.ON_INHEAP; + p.flags |= OctreeQuantizer._inHeap; p.heapIndex = h.n; h.buf.push(p); this.upHeap(h, p); @@ -163,14 +181,49 @@ export class OctreeQuantizer implements Quantizer { return ac < bc ? -1 : ac > bc ? 1 : 0; } + private getNodes(nodes: OctreeNode[], node: OctreeNode): void { + if (node.childCount === 0) { + nodes.push(node); + return; + } + for (const n of node.children) { + if (n !== undefined) { + this.getNodes(nodes, n); + } + } + } + + public getColorIndex(c: Color): number { + return this.getColorIndexRgb( + Math.trunc(c.r), + Math.trunc(c.g), + Math.trunc(c.b) + ); + } + + public getColorIndexRgb(r: number, g: number, b: number): number { + let root: OctreeNode | undefined = this._root; + for (let bit = 1 << 7; bit !== 0; bit >>= 1) { + const i = + ((g & bit) !== 0 ? 1 : 0) * 4 + + ((r & bit) !== 0 ? 1 : 0) * 2 + + ((b & bit) !== 0 ? 1 : 0); + if (root!.children[i] === undefined) { + break; + } + root = root!.children[i]; + } + return root?.paletteIndex ?? 0; + } + /** - * Find the index of the closest color to **c** in the **colorMap**. + * Find the index of the closest color to **c** in the **palette**. */ - public getQuantizedColor(c: number): number { - let r = Color.getRed(c); - let g = Color.getGreen(c); - let b = Color.getBlue(c); - let root: OctreeNode | undefined = this.root; + public getQuantizedColor(c: Color): Color { + let r = Math.trunc(c.r); + let g = Math.trunc(c.g); + let b = Math.trunc(c.b); + let root: OctreeNode | undefined = this._root; for (let bit = 1 << 7; bit !== 0; bit >>= 1) { const i = @@ -186,6 +239,33 @@ export class OctreeQuantizer implements Quantizer { r = root!.r; g = root!.g; b = root!.b; - return Color.getColor(r, g, b); + + return new ColorRgb8(r, g, b); + } + + /** + * Convert the **image** to a palette image. + */ + public getIndexImage(image: MemoryImage): MemoryImage { + const target = new MemoryImage({ + width: image.width, + height: image.height, + numChannels: 1, + palette: this.palette, + }); + + const imageIt = image[Symbol.iterator](); + const targetIt = target[Symbol.iterator](); + let imageItRes: IteratorResult | undefined = undefined; + let targetItRes: IteratorResult | undefined = undefined; + while ( + (((imageItRes = imageIt.next()), (targetItRes = targetIt.next())), + !imageItRes.done && !targetItRes.done) + ) { + const t = targetItRes.value; + t.setChannel(0, this.getColorIndex(imageItRes.value)); + } + + return target; } } diff --git a/src/image/palette-float16.ts b/src/image/palette-float16.ts new file mode 100644 index 0000000..6a8ce35 --- /dev/null +++ b/src/image/palette-float16.ts @@ -0,0 +1,152 @@ +/** @format */ + +import { Format } from '../color/format'; +import { Float16 } from '../common/float16'; +import { Palette } from './palette'; + +export class PaletteFloat16 implements Palette { + private readonly _data: Uint16Array; + public get data(): Uint16Array { + return this._data; + } + + private readonly _numColors: number; + public get numColors(): number { + return this._numColors; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get byteLength(): number { + return this.data.byteLength; + } + + public get buffer(): ArrayBufferLike { + return this.data.buffer; + } + + public get format(): Format { + return Format.float16; + } + + public get maxChannelValue(): number { + return 1; + } + + constructor(numColors: number, numChannels: number, data?: Uint16Array) { + this._numColors = numColors; + this._numChannels = numChannels; + this._data = data ?? new Uint16Array(numColors * numChannels); + } + + public static from(other: PaletteFloat16) { + return new PaletteFloat16(other.numColors, other.numChannels, other.data); + } + + public setRgb(index: number, r: number, g: number, b: number): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Float16.doubleToFloat16(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Float16.doubleToFloat16(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Float16.doubleToFloat16(b); + } + } + } + + public setRgba( + index: number, + r: number, + g: number, + b: number, + a: number + ): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Float16.doubleToFloat16(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Float16.doubleToFloat16(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Float16.doubleToFloat16(b); + if (this._numChannels > 3) { + this._data[_index + 3] = Float16.doubleToFloat16(a); + } + } + } + } + + public set(index: number, channel: number, value: number): void { + let _index = index; + if (channel < this._numChannels) { + _index *= this._numChannels; + this._data[_index + channel] = Float16.doubleToFloat16(value); + } + } + + public get(index: number, channel: number): number { + return channel < this._numChannels + ? Float16.float16ToDouble(this._data[index * this._numChannels + channel]) + : 0; + } + + public getRed(index: number): number { + let _index = index; + _index *= this._numChannels; + return Float16.float16ToDouble(this._data[_index]); + } + + public getGreen(index: number): number { + let _index = index; + if (this._numChannels < 2) { + return 0; + } + _index *= this._numChannels; + return Float16.float16ToDouble(this._data[_index + 1]); + } + + public getBlue(index: number): number { + let _index = index; + if (this._numChannels < 3) { + return 0; + } + _index *= this._numChannels; + return Float16.float16ToDouble(this._data[_index + 2]); + } + + public getAlpha(index: number) { + let _index = index; + if (this._numChannels < 4) { + return 255; + } + _index *= this._numChannels; + return Float16.float16ToDouble(this._data[_index + 3]); + } + + public setRed(index: number, value: number): void { + this.set(index, 0, value); + } + + public setGreen(index: number, value: number): void { + this.set(index, 1, value); + } + + public setBlue(index: number, value: number): void { + this.set(index, 2, value); + } + + public setAlpha(index: number, value: number): void { + this.set(index, 3, value); + } + + public clone(): PaletteFloat16 { + return PaletteFloat16.from(this); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } +} diff --git a/src/image/palette-float32.ts b/src/image/palette-float32.ts new file mode 100644 index 0000000..e1eccf7 --- /dev/null +++ b/src/image/palette-float32.ts @@ -0,0 +1,151 @@ +/** @format */ + +import { Format } from '../color/format'; +import { Palette } from './palette'; + +export class PaletteFloat32 implements Palette { + private readonly _data: Float32Array; + public get data(): Float32Array { + return this._data; + } + + private readonly _numColors: number; + public get numColors(): number { + return this._numColors; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get byteLength(): number { + return this.data.byteLength; + } + + public get buffer(): ArrayBufferLike { + return this.data.buffer; + } + + public get format(): Format { + return Format.float32; + } + + public get maxChannelValue(): number { + return 1; + } + + constructor(numColors: number, numChannels: number, data?: Float32Array) { + this._numColors = numColors; + this._numChannels = numChannels; + this._data = data ?? new Float32Array(numColors * numChannels); + } + + public static from(other: PaletteFloat32) { + return new PaletteFloat32(other.numColors, other.numChannels, other.data); + } + + public setRgb(index: number, r: number, g: number, b: number): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = r; + if (this._numChannels > 1) { + this._data[_index + 1] = g; + if (this._numChannels > 2) { + this._data[_index + 2] = b; + } + } + } + + public setRgba( + index: number, + r: number, + g: number, + b: number, + a: number + ): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = r; + if (this._numChannels > 1) { + this._data[_index + 1] = g; + if (this._numChannels > 2) { + this._data[_index + 2] = b; + if (this._numChannels > 3) { + this._data[_index + 3] = a; + } + } + } + } + + public set(index: number, channel: number, value: number): void { + let _index = index; + if (channel < this._numChannels) { + _index *= this._numChannels; + this._data[_index + channel] = value; + } + } + + public get(index: number, channel: number): number { + return channel < this._numChannels + ? this._data[index * this._numChannels + channel] + : 0; + } + + public getRed(index: number): number { + let _index = index; + _index *= this._numChannels; + return this._data[_index]; + } + + public getGreen(index: number): number { + let _index = index; + if (this._numChannels < 2) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 1]; + } + + public getBlue(index: number): number { + let _index = index; + if (this._numChannels < 3) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 2]; + } + + public getAlpha(index: number) { + let _index = index; + if (this._numChannels < 4) { + return 255; + } + _index *= this._numChannels; + return this._data[_index + 3]; + } + + public setRed(index: number, value: number): void { + this.set(index, 0, value); + } + + public setGreen(index: number, value: number): void { + this.set(index, 1, value); + } + + public setBlue(index: number, value: number): void { + this.set(index, 2, value); + } + + public setAlpha(index: number, value: number): void { + this.set(index, 3, value); + } + + public clone(): PaletteFloat32 { + return PaletteFloat32.from(this); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } +} diff --git a/src/image/palette-float64.ts b/src/image/palette-float64.ts new file mode 100644 index 0000000..8a8d66f --- /dev/null +++ b/src/image/palette-float64.ts @@ -0,0 +1,151 @@ +/** @format */ + +import { Format } from '../color/format'; +import { Palette } from './palette'; + +export class PaletteFloat64 implements Palette { + private readonly _data: Float64Array; + public get data(): Float64Array { + return this._data; + } + + private readonly _numColors: number; + public get numColors(): number { + return this._numColors; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get byteLength(): number { + return this.data.byteLength; + } + + public get buffer(): ArrayBufferLike { + return this.data.buffer; + } + + public get format(): Format { + return Format.float64; + } + + public get maxChannelValue(): number { + return 1; + } + + constructor(numColors: number, numChannels: number, data?: Float64Array) { + this._numColors = numColors; + this._numChannels = numChannels; + this._data = data ?? new Float64Array(numColors * numChannels); + } + + public static from(other: PaletteFloat64) { + return new PaletteFloat64(other.numColors, other.numChannels, other.data); + } + + public setRgb(index: number, r: number, g: number, b: number): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = r; + if (this._numChannels > 1) { + this._data[_index + 1] = g; + if (this._numChannels > 2) { + this._data[_index + 2] = b; + } + } + } + + public setRgba( + index: number, + r: number, + g: number, + b: number, + a: number + ): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = r; + if (this._numChannels > 1) { + this._data[_index + 1] = g; + if (this._numChannels > 2) { + this._data[_index + 2] = b; + if (this._numChannels > 3) { + this._data[_index + 3] = a; + } + } + } + } + + public set(index: number, channel: number, value: number): void { + let _index = index; + if (channel < this._numChannels) { + _index *= this._numChannels; + this._data[_index + channel] = value; + } + } + + public get(index: number, channel: number): number { + return channel < this._numChannels + ? this._data[index * this._numChannels + channel] + : 0; + } + + public getRed(index: number): number { + let _index = index; + _index *= this._numChannels; + return this._data[_index]; + } + + public getGreen(index: number): number { + let _index = index; + if (this._numChannels < 2) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 1]; + } + + public getBlue(index: number): number { + let _index = index; + if (this._numChannels < 3) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 2]; + } + + public getAlpha(index: number) { + let _index = index; + if (this._numChannels < 4) { + return 255; + } + _index *= this._numChannels; + return this._data[_index + 3]; + } + + public setRed(index: number, value: number): void { + this.set(index, 0, value); + } + + public setGreen(index: number, value: number): void { + this.set(index, 1, value); + } + + public setBlue(index: number, value: number): void { + this.set(index, 2, value); + } + + public setAlpha(index: number, value: number): void { + this.set(index, 3, value); + } + + public clone(): PaletteFloat64 { + return PaletteFloat64.from(this); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } +} diff --git a/src/image/palette-int16.ts b/src/image/palette-int16.ts new file mode 100644 index 0000000..08cef6c --- /dev/null +++ b/src/image/palette-int16.ts @@ -0,0 +1,151 @@ +/** @format */ + +import { Format } from '../color/format'; +import { Palette } from './palette'; + +export class PaletteInt16 implements Palette { + private readonly _data: Int16Array; + public get data(): Int16Array { + return this._data; + } + + private readonly _numColors: number; + public get numColors(): number { + return this._numColors; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get format(): Format { + return Format.int16; + } + + public get maxChannelValue(): number { + return 0x7fff; + } + + constructor(numColors: number, numChannels: number, data?: Int16Array) { + this._numColors = numColors; + this._numChannels = numChannels; + this._data = data ?? new Int16Array(numColors * numChannels); + } + + public static from(other: PaletteInt16) { + return new PaletteInt16(other.numColors, other.numChannels, other.data); + } + + public setRgb(index: number, r: number, g: number, b: number): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Math.trunc(b); + } + } + } + + public setRgba( + index: number, + r: number, + g: number, + b: number, + a: number + ): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Math.trunc(b); + if (this._numChannels > 3) { + this._data[_index + 3] = Math.trunc(a); + } + } + } + } + + public set(index: number, channel: number, value: number): void { + let _index = index; + if (channel < this._numChannels) { + _index *= this._numChannels; + this._data[_index + channel] = Math.trunc(value); + } + } + + public get(index: number, channel: number): number { + return channel < this._numChannels + ? this._data[index * this._numChannels + channel] + : 0; + } + + public getRed(index: number): number { + let _index = index; + _index *= this._numChannels; + return this._data[_index]; + } + + public getGreen(index: number): number { + let _index = index; + if (this._numChannels < 2) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 1]; + } + + public getBlue(index: number): number { + let _index = index; + if (this._numChannels < 3) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 2]; + } + + public getAlpha(index: number) { + let _index = index; + if (this._numChannels < 4) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 3]; + } + + public setRed(index: number, value: number): void { + this.set(index, 0, value); + } + + public setGreen(index: number, value: number): void { + this.set(index, 1, value); + } + + public setBlue(index: number, value: number): void { + this.set(index, 2, value); + } + + public setAlpha(index: number, value: number): void { + this.set(index, 3, value); + } + + public clone(): PaletteInt16 { + return PaletteInt16.from(this); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } +} diff --git a/src/image/palette-int32.ts b/src/image/palette-int32.ts new file mode 100644 index 0000000..41a1841 --- /dev/null +++ b/src/image/palette-int32.ts @@ -0,0 +1,151 @@ +/** @format */ + +import { Format } from '../color/format'; +import { Palette } from './palette'; + +export class PaletteInt32 implements Palette { + private readonly _data: Int32Array; + public get data(): Int32Array { + return this._data; + } + + private readonly _numColors: number; + public get numColors(): number { + return this._numColors; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get format(): Format { + return Format.int32; + } + + public get maxChannelValue(): number { + return 0x7fffffff; + } + + constructor(numColors: number, numChannels: number, data?: Int32Array) { + this._numColors = numColors; + this._numChannels = numChannels; + this._data = data ?? new Int32Array(numColors * numChannels); + } + + public static from(other: PaletteInt32) { + return new PaletteInt32(other.numColors, other.numChannels, other.data); + } + + public setRgb(index: number, r: number, g: number, b: number): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Math.trunc(b); + } + } + } + + public setRgba( + index: number, + r: number, + g: number, + b: number, + a: number + ): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Math.trunc(b); + if (this._numChannels > 3) { + this._data[_index + 3] = Math.trunc(a); + } + } + } + } + + public set(index: number, channel: number, value: number): void { + let _index = index; + if (channel < this._numChannels) { + _index *= this._numChannels; + this._data[_index + channel] = Math.trunc(value); + } + } + + public get(index: number, channel: number): number { + return channel < this._numChannels + ? this._data[index * this._numChannels + channel] + : 0; + } + + public getRed(index: number): number { + let _index = index; + _index *= this._numChannels; + return this._data[_index]; + } + + public getGreen(index: number): number { + let _index = index; + if (this._numChannels < 2) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 1]; + } + + public getBlue(index: number): number { + let _index = index; + if (this._numChannels < 3) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 2]; + } + + public getAlpha(index: number) { + let _index = index; + if (this._numChannels < 4) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 3]; + } + + public setRed(index: number, value: number): void { + this.set(index, 0, value); + } + + public setGreen(index: number, value: number): void { + this.set(index, 1, value); + } + + public setBlue(index: number, value: number): void { + this.set(index, 2, value); + } + + public setAlpha(index: number, value: number): void { + this.set(index, 3, value); + } + + public clone(): PaletteInt32 { + return PaletteInt32.from(this); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } +} diff --git a/src/image/palette-int8.ts b/src/image/palette-int8.ts new file mode 100644 index 0000000..7cb083a --- /dev/null +++ b/src/image/palette-int8.ts @@ -0,0 +1,151 @@ +/** @format */ + +import { Format } from '../color/format'; +import { Palette } from './palette'; + +export class PaletteInt8 implements Palette { + private readonly _data: Int8Array; + public get data(): Int8Array { + return this._data; + } + + private readonly _numColors: number; + public get numColors(): number { + return this._numColors; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get byteLength(): number { + return this.data.byteLength; + } + + public get buffer(): ArrayBufferLike { + return this.data.buffer; + } + + public get format(): Format { + return Format.int8; + } + + public get maxChannelValue(): number { + return 0x7f; + } + + constructor(numColors: number, numChannels: number, data?: Int8Array) { + this._numColors = numColors; + this._numChannels = numChannels; + this._data = data ?? new Int8Array(numColors * numChannels); + } + + public static from(other: PaletteInt8) { + return new PaletteInt8(other.numColors, other.numChannels, other.data); + } + + public setRgb(index: number, r: number, g: number, b: number): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Math.trunc(b); + } + } + } + + public setRgba( + index: number, + r: number, + g: number, + b: number, + a: number + ): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Math.trunc(b); + if (this._numChannels > 3) { + this._data[_index + 3] = Math.trunc(a); + } + } + } + } + + public set(index: number, channel: number, value: number): void { + let _index = index; + if (channel < this._numChannels) { + _index *= this._numChannels; + this._data[_index + channel] = Math.trunc(value); + } + } + + public get(index: number, channel: number): number { + return channel < this._numChannels + ? this._data[index * this._numChannels + channel] + : 0; + } + + public getRed(index: number): number { + let _index = index; + _index *= this._numChannels; + return this._data[_index]; + } + + public getGreen(index: number): number { + let _index = index; + if (this._numChannels < 2) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 1]; + } + + public getBlue(index: number): number { + let _index = index; + if (this._numChannels < 3) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 2]; + } + + public getAlpha(index: number) { + let _index = index; + if (this._numChannels < 4) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 3]; + } + + public setRed(index: number, value: number): void { + this.set(index, 0, value); + } + + public setGreen(index: number, value: number): void { + this.set(index, 1, value); + } + + public setBlue(index: number, value: number): void { + this.set(index, 2, value); + } + + public setAlpha(index: number, value: number): void { + this.set(index, 3, value); + } + + public clone(): PaletteInt8 { + return PaletteInt8.from(this); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } +} diff --git a/src/image/palette-uint16.ts b/src/image/palette-uint16.ts new file mode 100644 index 0000000..183cc47 --- /dev/null +++ b/src/image/palette-uint16.ts @@ -0,0 +1,151 @@ +/** @format */ + +import { Format } from '../color/format'; +import { Palette } from './palette'; + +export class PaletteUint16 implements Palette { + private readonly _data: Uint16Array; + public get data(): Uint16Array { + return this._data; + } + + private readonly _numColors: number; + public get numColors(): number { + return this._numColors; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get format(): Format { + return Format.uint16; + } + + public get maxChannelValue(): number { + return 0xffff; + } + + constructor(numColors: number, numChannels: number, data?: Uint16Array) { + this._numColors = numColors; + this._numChannels = numChannels; + this._data = data ?? new Uint16Array(numColors * numChannels); + } + + public static from(other: PaletteUint16) { + return new PaletteUint16(other.numColors, other.numChannels, other.data); + } + + public setRgb(index: number, r: number, g: number, b: number): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Math.trunc(b); + } + } + } + + public setRgba( + index: number, + r: number, + g: number, + b: number, + a: number + ): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Math.trunc(b); + if (this._numChannels > 3) { + this._data[_index + 3] = Math.trunc(a); + } + } + } + } + + public set(index: number, channel: number, value: number): void { + let _index = index; + if (channel < this._numChannels) { + _index *= this._numChannels; + this._data[_index + channel] = Math.trunc(value); + } + } + + public get(index: number, channel: number): number { + return channel < this._numChannels + ? this._data[index * this._numChannels + channel] + : 0; + } + + public getRed(index: number): number { + let _index = index; + _index *= this._numChannels; + return this._data[_index]; + } + + public getGreen(index: number): number { + let _index = index; + if (this._numChannels < 2) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 1]; + } + + public getBlue(index: number): number { + let _index = index; + if (this._numChannels < 3) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 2]; + } + + public getAlpha(index: number) { + let _index = index; + if (this._numChannels < 4) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 3]; + } + + public setRed(index: number, value: number): void { + this.set(index, 0, value); + } + + public setGreen(index: number, value: number): void { + this.set(index, 1, value); + } + + public setBlue(index: number, value: number): void { + this.set(index, 2, value); + } + + public setAlpha(index: number, value: number): void { + this.set(index, 3, value); + } + + public clone(): PaletteUint16 { + return PaletteUint16.from(this); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } +} diff --git a/src/image/palette-uint32.ts b/src/image/palette-uint32.ts new file mode 100644 index 0000000..336dc2f --- /dev/null +++ b/src/image/palette-uint32.ts @@ -0,0 +1,151 @@ +/** @format */ + +import { Format } from '../color/format'; +import { Palette } from './palette'; + +export class PaletteUint32 implements Palette { + private readonly _data: Uint32Array; + public get data(): Uint32Array { + return this._data; + } + + private readonly _numColors: number; + public get numColors(): number { + return this._numColors; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get format(): Format { + return Format.uint32; + } + + public get maxChannelValue(): number { + return 0xffffffff; + } + + constructor(numColors: number, numChannels: number, data?: Uint32Array) { + this._numColors = numColors; + this._numChannels = numChannels; + this._data = data ?? new Uint32Array(numColors * numChannels); + } + + public static from(other: PaletteUint32) { + return new PaletteUint32(other.numColors, other.numChannels, other.data); + } + + public setRgb(index: number, r: number, g: number, b: number): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Math.trunc(b); + } + } + } + + public setRgba( + index: number, + r: number, + g: number, + b: number, + a: number + ): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Math.trunc(b); + if (this._numChannels > 3) { + this._data[_index + 3] = Math.trunc(a); + } + } + } + } + + public set(index: number, channel: number, value: number): void { + let _index = index; + if (channel < this._numChannels) { + _index *= this._numChannels; + this._data[_index + channel] = Math.trunc(value); + } + } + + public get(index: number, channel: number): number { + return channel < this._numChannels + ? this._data[index * this._numChannels + channel] + : 0; + } + + public getRed(index: number): number { + let _index = index; + _index *= this._numChannels; + return this._data[_index]; + } + + public getGreen(index: number): number { + let _index = index; + if (this._numChannels < 2) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 1]; + } + + public getBlue(index: number): number { + let _index = index; + if (this._numChannels < 3) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 2]; + } + + public getAlpha(index: number) { + let _index = index; + if (this._numChannels < 4) { + return 0; + } + _index *= this._numChannels; + return this._data[_index + 3]; + } + + public setRed(index: number, value: number): void { + this.set(index, 0, value); + } + + public setGreen(index: number, value: number): void { + this.set(index, 1, value); + } + + public setBlue(index: number, value: number): void { + this.set(index, 2, value); + } + + public setAlpha(index: number, value: number): void { + this.set(index, 3, value); + } + + public clone(): PaletteUint32 { + return PaletteUint32.from(this); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } +} diff --git a/src/image/palette-uint8.ts b/src/image/palette-uint8.ts new file mode 100644 index 0000000..48ed237 --- /dev/null +++ b/src/image/palette-uint8.ts @@ -0,0 +1,163 @@ +/** @format */ + +import { Format } from '../color/format'; +import { Palette } from './palette'; + +export class PaletteUint8 implements Palette { + private readonly _data: Uint8Array; + public get data(): Uint8Array { + return this._data; + } + + private readonly _numColors: number; + public get numColors(): number { + return this._numColors; + } + + private readonly _numChannels: number; + public get numChannels(): number { + return this._numChannels; + } + + public get byteLength(): number { + return this._data.byteLength; + } + + public get buffer(): ArrayBufferLike { + return this._data.buffer; + } + + public get format(): Format { + return Format.uint8; + } + + public get maxChannelValue(): number { + return 255; + } + + constructor(numColors: number, numChannels: number, data?: Uint8Array) { + this._numColors = numColors; + this._numChannels = numChannels; + this._data = data ?? new Uint8Array(numColors * numChannels); + } + + public static from(other: PaletteUint8) { + return new PaletteUint8(other.numColors, other.numChannels, other.data); + } + + public setRgb(index: number, r: number, g: number, b: number): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Math.trunc(b); + } + } + } + + public setRgba( + index: number, + r: number, + g: number, + b: number, + a: number + ): void { + let _index = index; + _index *= this._numChannels; + this._data[_index] = Math.trunc(r); + if (this._numChannels > 1) { + this._data[_index + 1] = Math.trunc(g); + if (this._numChannels > 2) { + this._data[_index + 2] = Math.trunc(b); + if (this._numChannels > 3) { + this._data[_index + 3] = Math.trunc(a); + } + } + } + } + + public set(index: number, channel: number, value: number): void { + let _index = index; + if (channel < this._numChannels) { + _index *= this._numChannels; + this._data[_index + channel] = Math.trunc(value); + } + } + + public get(index: number, channel: number): number { + return channel < this._numChannels + ? this._data[index * this._numChannels + channel] + : 0; + } + + public getRed(index: number): number { + let _index = index; + _index *= this._numChannels; + if (_index >= this._data.length) { + return 0; + } + return this._data[_index]; + } + + public getGreen(index: number): number { + let _index = index; + if (this._numChannels < 2) { + return 0; + } + _index *= this._numChannels; + if (_index >= this._data.length) { + return 0; + } + return this._data[_index + 1]; + } + + public getBlue(index: number): number { + let _index = index; + if (this._numChannels < 3) { + return 0; + } + _index *= this._numChannels; + if (_index >= this._data.length) { + return 0; + } + return this._data[_index + 2]; + } + + public getAlpha(index: number) { + let _index = index; + if (this._numChannels < 4) { + return 255; + } + _index *= this._numChannels; + if (_index >= this._data.length) { + return 0; + } + return this._data[_index + 3]; + } + + public setRed(index: number, value: number): void { + this.set(index, 0, value); + } + + public setGreen(index: number, value: number): void { + this.set(index, 1, value); + } + + public setBlue(index: number, value: number): void { + this.set(index, 2, value); + } + + public setAlpha(index: number, value: number): void { + this.set(index, 3, value); + } + + public clone(): PaletteUint8 { + return PaletteUint8.from(this); + } + + public toUint8Array(): Uint8Array { + return new Uint8Array(this.buffer); + } +} diff --git a/src/image/palette.ts b/src/image/palette.ts new file mode 100644 index 0000000..dd69d3c --- /dev/null +++ b/src/image/palette.ts @@ -0,0 +1,96 @@ +/** @format */ + +import { Format } from '../color/format'; + +export interface Palette { + /** + * The size of the palette data in bytes. + */ + get byteLength(): number; + /** + * The byte buffer storage of the palette data. + */ + get buffer(): ArrayBufferLike; + /** + * The number of colors stored in the palette. + */ + get numColors(): number; + /** + * The number of channels per color. + */ + get numChannels(): number; + get maxChannelValue(): number; + /** + * The format of the color data. + */ + get format(): Format; + /** + * Set the RGB color of a palette entry at **index**. If the palette has fewer + * channels than are set, the unsupported channels will be ignored. + */ + setRgb(index: number, r: number, g: number, b: number): void; + /** + * Set the RGBA color of a palette entry at **index**. If the palette has fewer + * channels than are set, the unsupported channels will be ignored. + */ + setRgba(index: number, r: number, g: number, b: number, a: number): void; + /** + * Set a specific **channel** **value** of the palette entry at **index**. If the + * palette has fewer channels than **channel**, the value will be ignored. + */ + set(index: number, channel: number, value: number): void; + /** + * Get the the value of a specific **channel** of the palette entry at **index**. + * If the palette has fewer colors than **index** or fewer channels than + * **channel**, 0 will be returned. + */ + get(index: number, channel: number): number; + /** + * Get the red channel of the palette entry at **index**. If the palette has + * fewer colors or channels, 0 will be returned. + */ + getRed(index: number): number; + /** + * Set the red channel of the palette entry at **index**. If the palette has + * fewer colors or channels, it will be ignored. + */ + setRed(index: number, value: number): void; + /** + * Get the green channel of the palette entry at **index**. If the palette has + * fewer colors or channels, 0 will be returned. + */ + getGreen(index: number): number; + /** + * Set the green channel of the palette entry at **index**. If the palette has + * fewer colors or channels, it will be ignored. + */ + setGreen(index: number, value: number): void; + /** + * Get the blue channel of the palette entry at **index**. If the palette has + * fewer colors or channels, 0 will be returned. + */ + getBlue(index: number): number; + /** + * Set the blue channel of the palette entry at **index**. If the palette has + * fewer colors or channels, it will be ignored. + */ + setBlue(index: number, value: number): void; + /** + * Get the alpha channel of the palette entry at **index**. If the palette has + * fewer colors or channels, 0 will be returned. + */ + getAlpha(index: number): number; + /** + * Set the alpha channel of the palette entry at **index**. If the palette has + * fewer colors or channels, it will be ignored. + */ + setAlpha(index: number, value: number): void; + /** + * Create a copy of the Palette. + */ + clone(): Palette; + /** + * A Uint8Array view of the palette buffer storage. + */ + toUint8Array(): Uint8Array; +} diff --git a/src/image/pixel-float16.ts b/src/image/pixel-float16.ts new file mode 100644 index 0000000..e5cb71e --- /dev/null +++ b/src/image/pixel-float16.ts @@ -0,0 +1,335 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color, ColorConvertOptions } from '../color/color'; +import { ColorUtils } from '../color/color-utils'; +import { Format } from '../color/format'; +import { ArrayUtils } from '../common/array-utils'; +import { Float16 } from '../common/float16'; +import { MemoryImage } from './image'; +import { MemoryImageDataFloat16 } from './image-data-float16'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +export class PixelFloat16 implements Pixel, Iterable, Iterator { + private _index: number; + + private readonly _image: MemoryImageDataFloat16; + public get image(): MemoryImageDataFloat16 { + return this._image; + } + + private _x: number; + public get x(): number { + return this._x; + } + + private _y: number; + public get y(): number { + return this._y; + } + + public get xNormalized(): number { + return this.width > 1 ? this._x / (this.width - 1) : 0; + } + + public get yNormalized(): number { + return this.height > 1 ? this._y / (this.height - 1) : 0; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get data(): Uint16Array { + return this._image.data; + } + + public get isValid(): boolean { + return ( + this._x >= 0 && + this._x < this._image.width - 1 && + this._y >= 0 && + this._y < this._image.height - 1 + ); + } + + public get width(): number { + return this._image.width; + } + + public get height(): number { + return this._image.width; + } + + public get length(): number { + return this._image.numChannels; + } + + public get numChannels(): number { + return this._image.numChannels; + } + + public get maxChannelValue(): number { + return this._image.maxChannelValue; + } + + public get maxIndexValue(): number { + return this._image.maxIndexValue; + } + + public get format(): Format { + return Format.float16; + } + + public get isLdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get isHdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get hasPalette(): boolean { + return this._image.hasPalette; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get r(): number { + return this.numChannels > 0 + ? Float16.float16ToDouble(this.data[this._index]) + : 0; + } + public set r(r: number) { + if (this.numChannels > 0) { + this.data[this._index] = Float16.doubleToFloat16(r); + } + } + + public get g(): number { + return this.numChannels > 1 + ? Float16.float16ToDouble(this.data[this._index + 1]) + : 0; + } + public set g(g: number) { + if (this.numChannels > 1) { + this.data[this._index + 1] = Float16.doubleToFloat16(g); + } + } + + public get b(): number { + return this.numChannels > 2 + ? Float16.float16ToDouble(this.data[this._index + 2]) + : 0; + } + public set b(b: number) { + if (this.numChannels > 2) { + this.data[this._index + 2] = Float16.doubleToFloat16(b); + } + } + + public get a(): number { + return this.numChannels > 3 + ? Float16.float16ToDouble(this.data[this._index + 3]) + : 0; + } + public set a(a: number) { + if (this.numChannels > 3) { + this.data[this._index + 3] = Float16.doubleToFloat16(a); + } + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor( + x: number, + y: number, + index: number, + image: MemoryImageDataFloat16 + ) { + this._image = image; + this._index = index; + this._x = x; + this._y = y; + } + + public static imageData(image: MemoryImageDataFloat16) { + return new PixelFloat16(-1, 0, -image.numChannels, image); + } + + public static image(image: MemoryImage) { + return new PixelFloat16( + -1, + 0, + -image.numChannels, + image.data instanceof MemoryImageDataFloat16 + ? (image.data as MemoryImageDataFloat16) + : new MemoryImageDataFloat16(0, 0, 0) + ); + } + + public static from(other: PixelFloat16) { + return new PixelFloat16(other.x, other.y, other._index, other.image); + } + + public next(): IteratorResult { + this._x++; + if (this._x === this.width) { + this._x = 0; + this._y++; + if (this._y === this.height) { + return >{ + done: true, + value: this, + }; + } + } + this._index += this.numChannels; + return >{ + done: this._index >= this.image.data.length, + value: this, + }; + } + + public setPosition(x: number, y: number): void { + this._x = x; + this._y = y; + this._index = + this._y * this._image.width * this._image.numChannels + + this._x * this._image.numChannels; + } + + public setPositionNormalized(x: number, y: number): void { + return this.setPosition( + Math.floor(x * (this.width - 1)), + Math.floor(y * (this.height - 1)) + ); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.numChannels + ? Float16.float16ToDouble(this.data[this._index + channel]) + : 0; + } + } + + public getChannelNormalized(channel: Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(channel: number, value: number): void { + if (channel < this.numChannels) { + this.data[this._index + channel] = Float16.doubleToFloat16(value); + } + } + + public set(color: Color): void { + if (this.numChannels > 0) { + this.r = color.r; + this.g = color.g; + this.b = color.b; + this.a = color.a; + } + } + + public setRgb(r: number, g: number, b: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Float16.doubleToFloat16(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Float16.doubleToFloat16(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Float16.doubleToFloat16(b); + } + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Float16.doubleToFloat16(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Float16.doubleToFloat16(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Float16.doubleToFloat16(b); + if (this.numChannels > 3) { + this.data[this._index + 3] = Float16.doubleToFloat16(a); + } + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public equals(other: Pixel | number[]): boolean { + if (other instanceof PixelFloat16) { + return ArrayUtils.equals(this.toArray(), other.toArray()); + } + if (Array.isArray(other)) { + return ArrayUtils.equals(this.toArray(), other); + } + return false; + } + + public clone(): PixelFloat16 { + return PixelFloat16.from(this); + } + + public convert(opt: ColorConvertOptions): Color { + return ColorUtils.convertColor({ + from: this, + format: opt.format, + numChannels: opt.numChannels, + alpha: opt.alpha, + }); + } + + public [Symbol.iterator](): Iterator { + return this; + } +} diff --git a/src/image/pixel-float32.ts b/src/image/pixel-float32.ts new file mode 100644 index 0000000..d535649 --- /dev/null +++ b/src/image/pixel-float32.ts @@ -0,0 +1,326 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color, ColorConvertOptions } from '../color/color'; +import { ColorUtils } from '../color/color-utils'; +import { Format } from '../color/format'; +import { ArrayUtils } from '../common/array-utils'; +import { MemoryImage } from './image'; +import { MemoryImageDataFloat32 } from './image-data-float32'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +export class PixelFloat32 implements Pixel, Iterable, Iterator { + private _index: number; + + private readonly _image: MemoryImageDataFloat32; + public get image(): MemoryImageDataFloat32 { + return this._image; + } + + private _x: number; + public get x(): number { + return this._x; + } + + private _y: number; + public get y(): number { + return this._y; + } + + public get xNormalized(): number { + return this.width > 1 ? this._x / (this.width - 1) : 0; + } + + public get yNormalized(): number { + return this.height > 1 ? this._y / (this.height - 1) : 0; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get data(): Float32Array { + return this._image.data; + } + + public get isValid(): boolean { + return ( + this._x >= 0 && + this._x < this._image.width - 1 && + this._y >= 0 && + this._y < this._image.height - 1 + ); + } + + public get width(): number { + return this._image.width; + } + + public get height(): number { + return this._image.width; + } + + public get length(): number { + return this._image.numChannels; + } + + public get numChannels(): number { + return this._image.numChannels; + } + + public get maxChannelValue(): number { + return this._image.maxChannelValue; + } + + public get maxIndexValue(): number { + return this._image.maxIndexValue; + } + + public get format(): Format { + return Format.float32; + } + + public get isLdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get isHdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get hasPalette(): boolean { + return this._image.hasPalette; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get r(): number { + return this.numChannels > 0 ? this.data[this._index] : 0; + } + public set r(r: number) { + if (this.numChannels > 0) { + this.data[this._index] = r; + } + } + + public get g(): number { + return this.numChannels > 1 ? this.data[this._index + 1] : 0; + } + public set g(g: number) { + if (this.numChannels > 1) { + this.data[this._index + 1] = g; + } + } + + public get b(): number { + return this.numChannels > 2 ? this.data[this._index + 2] : 0; + } + public set b(b: number) { + if (this.numChannels > 2) { + this.data[this._index + 2] = b; + } + } + + public get a(): number { + return this.numChannels > 3 ? this.data[this._index + 3] : 1; + } + public set a(a: number) { + if (this.numChannels > 3) { + this.data[this._index + 3] = a; + } + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor( + x: number, + y: number, + index: number, + image: MemoryImageDataFloat32 + ) { + this._image = image; + this._index = index; + this._x = x; + this._y = y; + } + + public static imageData(image: MemoryImageDataFloat32) { + return new PixelFloat32(-1, 0, -image.numChannels, image); + } + + public static image(image: MemoryImage) { + return new PixelFloat32( + -1, + 0, + -image.numChannels, + image.data instanceof MemoryImageDataFloat32 + ? (image.data as MemoryImageDataFloat32) + : new MemoryImageDataFloat32(0, 0, 0) + ); + } + + public static from(other: PixelFloat32) { + return new PixelFloat32(other.x, other.y, other._index, other.image); + } + + public next(): IteratorResult { + this._x++; + if (this._x === this.width) { + this._x = 0; + this._y++; + if (this._y === this.height) { + return >{ + done: true, + value: this, + }; + } + } + this._index += this.numChannels; + return >{ + done: this._index >= this.image.data.length, + value: this, + }; + } + + public setPosition(x: number, y: number): void { + this._x = x; + this._y = y; + this._index = + this._y * this._image.width * this._image.numChannels + + this._x * this._image.numChannels; + } + + public setPositionNormalized(x: number, y: number): void { + return this.setPosition( + Math.floor(x * (this.width - 1)), + Math.floor(y * (this.height - 1)) + ); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.numChannels ? this.data[this._index + channel] : 0; + } + } + + public getChannelNormalized(channel: Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(channel: number, value: number): void { + if (channel < this.numChannels) { + this.data[this._index + channel] = value; + } + } + + public set(color: Color): void { + this.r = color.r; + this.g = color.g; + this.b = color.b; + this.a = color.a; + } + + public setRgb(r: number, g: number, b: number): void { + if (this.numChannels > 0) { + this.data[this._index] = r; + if (this.numChannels > 1) { + this.data[this._index + 1] = g; + if (this.numChannels > 2) { + this.data[this._index + 2] = b; + } + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + if (this.numChannels > 0) { + this.data[this._index] = r; + if (this.numChannels > 1) { + this.data[this._index + 1] = g; + if (this.numChannels > 2) { + this.data[this._index + 2] = b; + if (this.numChannels > 3) { + this.data[this._index + 3] = a; + } + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public equals(other: Pixel | number[]): boolean { + if (other instanceof PixelFloat32) { + return ArrayUtils.equals(this.toArray(), other.toArray()); + } + if (Array.isArray(other)) { + return ArrayUtils.equals(this.toArray(), other); + } + return false; + } + + public clone(): PixelFloat32 { + return PixelFloat32.from(this); + } + + public convert(opt: ColorConvertOptions): Color { + return ColorUtils.convertColor({ + from: this, + format: opt.format, + numChannels: opt.numChannels, + alpha: opt.alpha, + }); + } + + public toString(): string { + return `${this.constructor.name} (${this.toArray()})`; + } + + public [Symbol.iterator](): Iterator { + return this; + } +} diff --git a/src/image/pixel-float64.ts b/src/image/pixel-float64.ts new file mode 100644 index 0000000..7f2458b --- /dev/null +++ b/src/image/pixel-float64.ts @@ -0,0 +1,326 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color, ColorConvertOptions } from '../color/color'; +import { ColorUtils } from '../color/color-utils'; +import { Format } from '../color/format'; +import { ArrayUtils } from '../common/array-utils'; +import { MemoryImage } from './image'; +import { MemoryImageDataFloat64 } from './image-data-float64'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +export class PixelFloat64 implements Pixel, Iterable, Iterator { + private _index: number; + + private readonly _image: MemoryImageDataFloat64; + public get image(): MemoryImageDataFloat64 { + return this._image; + } + + private _x: number; + public get x(): number { + return this._x; + } + + private _y: number; + public get y(): number { + return this._y; + } + + public get xNormalized(): number { + return this.width > 1 ? this._x / (this.width - 1) : 0; + } + + public get yNormalized(): number { + return this.height > 1 ? this._y / (this.height - 1) : 0; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get data(): Float64Array { + return this._image.data; + } + + public get isValid(): boolean { + return ( + this._x >= 0 && + this._x < this._image.width - 1 && + this._y >= 0 && + this._y < this._image.height - 1 + ); + } + + public get width(): number { + return this._image.width; + } + + public get height(): number { + return this._image.width; + } + + public get length(): number { + return this._image.numChannels; + } + + public get numChannels(): number { + return this._image.numChannels; + } + + public get maxChannelValue(): number { + return this._image.maxChannelValue; + } + + public get maxIndexValue(): number { + return this._image.maxIndexValue; + } + + public get format(): Format { + return Format.float64; + } + + public get isLdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get isHdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get hasPalette(): boolean { + return this._image.hasPalette; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get r(): number { + return this.numChannels > 0 ? this.data[this._index] : 0; + } + public set r(r: number) { + if (this.numChannels > 0) { + this.data[this._index] = r; + } + } + + public get g(): number { + return this.numChannels > 1 ? this.data[this._index + 1] : 0; + } + public set g(g: number) { + if (this.numChannels > 1) { + this.data[this._index + 1] = g; + } + } + + public get b(): number { + return this.numChannels > 2 ? this.data[this._index + 2] : 0; + } + public set b(b: number) { + if (this.numChannels > 2) { + this.data[this._index + 2] = b; + } + } + + public get a(): number { + return this.numChannels > 3 ? this.data[this._index + 3] : 0; + } + public set a(a: number) { + if (this.numChannels > 3) { + this.data[this._index + 3] = a; + } + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor( + x: number, + y: number, + index: number, + image: MemoryImageDataFloat64 + ) { + this._image = image; + this._index = index; + this._x = x; + this._y = y; + } + + public static imageData(image: MemoryImageDataFloat64) { + return new PixelFloat64(-1, 0, -image.numChannels, image); + } + + public static image(image: MemoryImage) { + return new PixelFloat64( + -1, + 0, + -image.numChannels, + image.data instanceof MemoryImageDataFloat64 + ? (image.data as MemoryImageDataFloat64) + : new MemoryImageDataFloat64(0, 0, 0) + ); + } + + public static from(other: PixelFloat64) { + return new PixelFloat64(other.x, other.y, other._index, other.image); + } + + [Symbol.iterator](): Iterator { + return this; + } + + public next(): IteratorResult { + this._x++; + if (this._x === this.width) { + this._x = 0; + this._y++; + if (this._y === this.height) { + return >{ + done: true, + value: this, + }; + } + } + this._index += this.numChannels; + return >{ + done: this._index >= this.image.data.length, + value: this, + }; + } + + public setPosition(x: number, y: number): void { + this._x = x; + this._y = y; + this._index = + this._y * this._image.width * this._image.numChannels + + this._x * this._image.numChannels; + } + + public setPositionNormalized(x: number, y: number): void { + return this.setPosition( + Math.floor(x * (this.width - 1)), + Math.floor(y * (this.height - 1)) + ); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.numChannels ? this.data[this._index + channel] : 0; + } + } + + public getChannelNormalized(channel: Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(channel: number, value: number): void { + if (channel < this.numChannels) { + this.data[this._index + channel] = value; + } + } + + public set(color: Color): void { + this.r = color.r; + this.g = color.g; + this.b = color.b; + this.a = color.a; + } + + public setRgb(r: number, g: number, b: number): void { + if (this.numChannels > 0) { + this.data[this._index] = r; + if (this.numChannels > 1) { + this.data[this._index + 1] = g; + if (this.numChannels > 2) { + this.data[this._index + 2] = b; + } + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + if (this.numChannels > 0) { + this.data[this._index] = r; + if (this.numChannels > 1) { + this.data[this._index + 1] = g; + if (this.numChannels > 2) { + this.data[this._index + 2] = b; + if (this.numChannels > 3) { + this.data[this._index + 3] = a; + } + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public equals(other: Pixel | number[]): boolean { + if (other instanceof PixelFloat64) { + return ArrayUtils.equals(this.toArray(), other.toArray()); + } + if (Array.isArray(other)) { + return ArrayUtils.equals(this.toArray(), other); + } + return false; + } + + public clone(): PixelFloat64 { + return PixelFloat64.from(this); + } + + public convert(opt: ColorConvertOptions): Color { + return ColorUtils.convertColor({ + from: this, + format: opt.format, + numChannels: opt.numChannels, + alpha: opt.alpha, + }); + } + + public toString(): string { + return `${this.constructor.name} (${this.toArray()})`; + } +} diff --git a/src/image/pixel-int16.ts b/src/image/pixel-int16.ts new file mode 100644 index 0000000..30cc51d --- /dev/null +++ b/src/image/pixel-int16.ts @@ -0,0 +1,326 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color, ColorConvertOptions } from '../color/color'; +import { ColorUtils } from '../color/color-utils'; +import { Format } from '../color/format'; +import { ArrayUtils } from '../common/array-utils'; +import { MemoryImage } from './image'; +import { MemoryImageDataInt16 } from './image-data-int16'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +export class PixelInt16 implements Pixel, Iterable, Iterator { + private _index: number; + + private readonly _image: MemoryImageDataInt16; + public get image(): MemoryImageDataInt16 { + return this._image; + } + + private _x: number; + public get x(): number { + return this._x; + } + + private _y: number; + public get y(): number { + return this._y; + } + + public get xNormalized(): number { + return this.width > 1 ? this._x / (this.width - 1) : 0; + } + + public get yNormalized(): number { + return this.height > 1 ? this._y / (this.height - 1) : 0; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get data(): Int16Array { + return this._image.data; + } + + public get isValid(): boolean { + return ( + this._x >= 0 && + this._x < this._image.width - 1 && + this._y >= 0 && + this._y < this._image.height - 1 + ); + } + + public get width(): number { + return this._image.width; + } + + public get height(): number { + return this._image.width; + } + + public get length(): number { + return this._image.numChannels; + } + + public get numChannels(): number { + return this._image.numChannels; + } + + public get maxChannelValue(): number { + return this._image.maxChannelValue; + } + + public get maxIndexValue(): number { + return this._image.maxIndexValue; + } + + public get format(): Format { + return Format.int16; + } + + public get isLdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get isHdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get hasPalette(): boolean { + return this._image.hasPalette; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get r(): number { + return this.numChannels > 0 ? this.data[this._index] : 0; + } + public set r(r: number) { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + } + } + + public get g(): number { + return this.numChannels > 1 ? this.data[this._index + 1] : 0; + } + public set g(g: number) { + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + } + } + + public get b(): number { + return this.numChannels > 2 ? this.data[this._index + 2] : 0; + } + public set b(b: number) { + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + } + } + + public get a(): number { + return this.numChannels > 3 ? this.data[this._index + 3] : 0; + } + public set a(a: number) { + if (this.numChannels > 3) { + this.data[this._index + 3] = Math.trunc(a); + } + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor( + x: number, + y: number, + index: number, + image: MemoryImageDataInt16 + ) { + this._image = image; + this._index = index; + this._x = x; + this._y = y; + } + + public static imageData(image: MemoryImageDataInt16) { + return new PixelInt16(-1, 0, -image.numChannels, image); + } + + public static image(image: MemoryImage) { + return new PixelInt16( + -1, + 0, + -image.numChannels, + image.data instanceof MemoryImageDataInt16 + ? (image.data as MemoryImageDataInt16) + : new MemoryImageDataInt16(0, 0, 0) + ); + } + + public static from(other: PixelInt16) { + return new PixelInt16(other.x, other.y, other._index, other.image); + } + + public next(): IteratorResult { + this._x++; + if (this._x === this.width) { + this._x = 0; + this._y++; + if (this._y === this.height) { + return >{ + done: true, + value: this, + }; + } + } + this._index += this.numChannels; + return >{ + done: this._index >= this.image.data.length, + value: this, + }; + } + + public setPosition(x: number, y: number): void { + this._x = x; + this._y = y; + this._index = + this._y * this._image.width * this._image.numChannels + + this._x * this._image.numChannels; + } + + public setPositionNormalized(x: number, y: number): void { + return this.setPosition( + Math.floor(x * (this.width - 1)), + Math.floor(y * (this.height - 1)) + ); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.numChannels ? this.data[this._index + channel] : 0; + } + } + + public getChannelNormalized(channel: Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(channel: number, value: number): void { + if (channel < this.numChannels) { + this.data[this._index + channel] = Math.trunc(value); + } + } + + public set(color: Color): void { + this.r = color.r; + this.g = color.g; + this.b = color.b; + this.a = color.a; + } + + public setRgb(r: number, g: number, b: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + } + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + if (this.numChannels > 3) { + this.data[this._index + 3] = Math.trunc(a); + } + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public equals(other: Pixel | number[]): boolean { + if (other instanceof PixelInt16) { + return ArrayUtils.equals(this.toArray(), other.toArray()); + } + if (Array.isArray(other)) { + return ArrayUtils.equals(this.toArray(), other); + } + return false; + } + + public clone(): PixelInt16 { + return PixelInt16.from(this); + } + + public convert(opt: ColorConvertOptions): Color { + return ColorUtils.convertColor({ + from: this, + format: opt.format, + numChannels: opt.numChannels, + alpha: opt.alpha, + }); + } + + public toString(): string { + return `${this.constructor.name} (${this.toArray()})`; + } + + public [Symbol.iterator](): Iterator { + return this; + } +} diff --git a/src/image/pixel-int32.ts b/src/image/pixel-int32.ts new file mode 100644 index 0000000..96c0bf7 --- /dev/null +++ b/src/image/pixel-int32.ts @@ -0,0 +1,326 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color, ColorConvertOptions } from '../color/color'; +import { ColorUtils } from '../color/color-utils'; +import { Format } from '../color/format'; +import { ArrayUtils } from '../common/array-utils'; +import { MemoryImage } from './image'; +import { MemoryImageDataInt32 } from './image-data-int32'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +export class PixelInt32 implements Pixel, Iterable, Iterator { + private _index: number; + + private readonly _image: MemoryImageDataInt32; + public get image(): MemoryImageDataInt32 { + return this._image; + } + + private _x: number; + public get x(): number { + return this._x; + } + + private _y: number; + public get y(): number { + return this._y; + } + + public get xNormalized(): number { + return this.width > 1 ? this._x / (this.width - 1) : 0; + } + + public get yNormalized(): number { + return this.height > 1 ? this._y / (this.height - 1) : 0; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get data(): Int32Array { + return this._image.data; + } + + public get isValid(): boolean { + return ( + this._x >= 0 && + this._x < this._image.width - 1 && + this._y >= 0 && + this._y < this._image.height - 1 + ); + } + + public get width(): number { + return this._image.width; + } + + public get height(): number { + return this._image.width; + } + + public get length(): number { + return this._image.numChannels; + } + + public get numChannels(): number { + return this._image.numChannels; + } + + public get maxChannelValue(): number { + return this._image.maxChannelValue; + } + + public get maxIndexValue(): number { + return this._image.maxIndexValue; + } + + public get format(): Format { + return Format.int32; + } + + public get isLdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get isHdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get hasPalette(): boolean { + return this._image.hasPalette; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get r(): number { + return this.numChannels > 0 ? this.data[this._index] : 0; + } + public set r(r: number) { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + } + } + + public get g(): number { + return this.numChannels > 1 ? this.data[this._index + 1] : 0; + } + public set g(g: number) { + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + } + } + + public get b(): number { + return this.numChannels > 2 ? this.data[this._index + 2] : 0; + } + public set b(b: number) { + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + } + } + + public get a(): number { + return this.numChannels > 3 ? this.data[this._index + 3] : 0; + } + public set a(a: number) { + if (this.numChannels > 3) { + this.data[this._index + 3] = Math.trunc(a); + } + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor( + x: number, + y: number, + index: number, + image: MemoryImageDataInt32 + ) { + this._image = image; + this._index = index; + this._x = x; + this._y = y; + } + + public static imageData(image: MemoryImageDataInt32) { + return new PixelInt32(-1, 0, -image.numChannels, image); + } + + public static image(image: MemoryImage) { + return new PixelInt32( + -1, + 0, + -image.numChannels, + image.data instanceof MemoryImageDataInt32 + ? (image.data as MemoryImageDataInt32) + : new MemoryImageDataInt32(0, 0, 0) + ); + } + + public static from(other: PixelInt32) { + return new PixelInt32(other.x, other.y, other._index, other.image); + } + + public next(): IteratorResult { + this._x++; + if (this._x === this.width) { + this._x = 0; + this._y++; + if (this._y === this.height) { + return >{ + done: true, + value: this, + }; + } + } + this._index += this.numChannels; + return >{ + done: this._index >= this.image.data.length, + value: this, + }; + } + + public setPosition(x: number, y: number): void { + this._x = x; + this._y = y; + this._index = + this._y * this._image.width * this._image.numChannels + + this._x * this._image.numChannels; + } + + public setPositionNormalized(x: number, y: number): void { + return this.setPosition( + Math.floor(x * (this.width - 1)), + Math.floor(y * (this.height - 1)) + ); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.numChannels ? this.data[this._index + channel] : 0; + } + } + + public getChannelNormalized(channel: Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(channel: number, value: number): void { + if (channel < this.numChannels) { + this.data[this._index + channel] = Math.trunc(value); + } + } + + public set(color: Color): void { + this.r = color.r; + this.g = color.g; + this.b = color.b; + this.a = color.a; + } + + public setRgb(r: number, g: number, b: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + } + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + if (this.numChannels > 3) { + this.data[this._index + 3] = Math.trunc(a); + } + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public equals(other: Pixel | number[]): boolean { + if (other instanceof PixelInt32) { + return ArrayUtils.equals(this.toArray(), other.toArray()); + } + if (Array.isArray(other)) { + return ArrayUtils.equals(this.toArray(), other); + } + return false; + } + + public clone(): PixelInt32 { + return PixelInt32.from(this); + } + + public convert(opt: ColorConvertOptions): Color { + return ColorUtils.convertColor({ + from: this, + format: opt.format, + numChannels: opt.numChannels, + alpha: opt.alpha, + }); + } + + public toString(): string { + return `${this.constructor.name} (${this.toArray()})`; + } + + public [Symbol.iterator](): Iterator { + return this; + } +} diff --git a/src/image/pixel-int8.ts b/src/image/pixel-int8.ts new file mode 100644 index 0000000..f20aeda --- /dev/null +++ b/src/image/pixel-int8.ts @@ -0,0 +1,321 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color, ColorConvertOptions } from '../color/color'; +import { ColorUtils } from '../color/color-utils'; +import { Format } from '../color/format'; +import { ArrayUtils } from '../common/array-utils'; +import { MemoryImage } from './image'; +import { MemoryImageDataInt8 } from './image-data-int8'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +export class PixelInt8 implements Pixel, Iterable, Iterator { + private _index: number; + + private readonly _image: MemoryImageDataInt8; + public get image(): MemoryImageDataInt8 { + return this._image; + } + + private _x: number; + public get x(): number { + return this._x; + } + + private _y: number; + public get y(): number { + return this._y; + } + + public get xNormalized(): number { + return this.width > 1 ? this._x / (this.width - 1) : 0; + } + + public get yNormalized(): number { + return this.height > 1 ? this._y / (this.height - 1) : 0; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get data(): Int8Array { + return this._image.data; + } + + public get isValid(): boolean { + return ( + this._x >= 0 && + this._x < this._image.width - 1 && + this._y >= 0 && + this._y < this._image.height - 1 + ); + } + + public get width(): number { + return this._image.width; + } + + public get height(): number { + return this._image.width; + } + + public get length(): number { + return this._image.numChannels; + } + + public get numChannels(): number { + return this._image.numChannels; + } + + public get maxChannelValue(): number { + return this._image.maxChannelValue; + } + + public get maxIndexValue(): number { + return this._image.maxIndexValue; + } + + public get format(): Format { + return Format.int8; + } + + public get isLdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get isHdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get hasPalette(): boolean { + return this._image.hasPalette; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get r(): number { + return this.numChannels > 0 ? this.data[this._index] : 0; + } + public set r(r: number) { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + } + } + + public get g(): number { + return this.numChannels > 1 ? this.data[this._index + 1] : 0; + } + public set g(g: number) { + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + } + } + + public get b(): number { + return this.numChannels > 2 ? this.data[this._index + 2] : 0; + } + public set b(b: number) { + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + } + } + + public get a(): number { + return this.numChannels > 3 ? this.data[this._index + 3] : 0; + } + public set a(a: number) { + if (this.numChannels > 3) { + this.data[this._index + 3] = Math.trunc(a); + } + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor(x: number, y: number, index: number, image: MemoryImageDataInt8) { + this._image = image; + this._index = index; + this._x = x; + this._y = y; + } + + public static imageData(image: MemoryImageDataInt8) { + return new PixelInt8(-1, 0, -image.numChannels, image); + } + + public static image(image: MemoryImage) { + return new PixelInt8( + -1, + 0, + -image.numChannels, + image.data instanceof MemoryImageDataInt8 + ? (image.data as MemoryImageDataInt8) + : new MemoryImageDataInt8(0, 0, 0) + ); + } + + public static from(other: PixelInt8) { + return new PixelInt8(other.x, other.y, other._index, other.image); + } + + public next(): IteratorResult { + this._x++; + if (this._x === this.width) { + this._x = 0; + this._y++; + if (this._y === this.height) { + return >{ + done: true, + value: this, + }; + } + } + this._index += this.numChannels; + return >{ + done: this._index >= this.image.data.length, + value: this, + }; + } + + public setPosition(x: number, y: number): void { + this._x = x; + this._y = y; + this._index = + this._y * this._image.width * this._image.numChannels + + this._x * this._image.numChannels; + } + + public setPositionNormalized(x: number, y: number): void { + return this.setPosition( + Math.floor(x * (this.width - 1)), + Math.floor(y * (this.height - 1)) + ); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.numChannels ? this.data[this._index + channel] : 0; + } + } + + public getChannelNormalized(channel: Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(channel: number, value: number): void { + if (channel < this.numChannels) { + this.data[this._index + channel] = Math.trunc(value); + } + } + + public set(color: Color): void { + this.r = color.r; + this.g = color.g; + this.b = color.b; + this.a = color.a; + } + + public setRgb(r: number, g: number, b: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + } + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + if (this.numChannels > 3) { + this.data[this._index + 3] = Math.trunc(a); + } + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public equals(other: Pixel | number[]): boolean { + if (other instanceof PixelInt8) { + return ArrayUtils.equals(this.toArray(), other.toArray()); + } + if (Array.isArray(other)) { + return ArrayUtils.equals(this.toArray(), other); + } + return false; + } + + public clone(): PixelInt8 { + return PixelInt8.from(this); + } + + public convert(opt: ColorConvertOptions): Color { + return ColorUtils.convertColor({ + from: this, + format: opt.format, + numChannels: opt.numChannels, + alpha: opt.alpha, + }); + } + + public toString(): string { + return `${this.constructor.name} (${this.toArray()})`; + } + + public [Symbol.iterator](): Iterator { + return this; + } +} diff --git a/src/image/pixel-range-iterator.ts b/src/image/pixel-range-iterator.ts new file mode 100644 index 0000000..6294625 --- /dev/null +++ b/src/image/pixel-range-iterator.ts @@ -0,0 +1,41 @@ +/** @format */ + +import { Pixel } from './pixel'; + +export class PixelRangeIterator implements Iterator { + private _pixel: Pixel; + private _x1: number; + private _y1: number; + private _x2: number; + private _y2: number; + + constructor( + pixel: Pixel, + x: number, + y: number, + width: number, + height: number + ) { + this._pixel = pixel; + this._x1 = x; + this._y1 = y; + this._x2 = x + width - 1; + this._y2 = y + height - 1; + this._pixel.setPosition(x - 1, y); + } + + public next(): IteratorResult { + if (this._pixel.x + 1 > this._x2) { + this._pixel.setPosition(this._x1, this._pixel.y + 1); + return { + done: this._pixel.y > this._y2, + value: this._pixel, + }; + } + return this._pixel.next(); + } + + public [Symbol.iterator](): IterableIterator { + return this; + } +} diff --git a/src/image/pixel-uint1.ts b/src/image/pixel-uint1.ts new file mode 100644 index 0000000..3a1d2f3 --- /dev/null +++ b/src/image/pixel-uint1.ts @@ -0,0 +1,388 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color, ColorConvertOptions } from '../color/color'; +import { ColorUtils } from '../color/color-utils'; +import { Format } from '../color/format'; +import { ArrayUtils } from '../common/array-utils'; +import { MathUtils } from '../common/math-utils'; +import { MemoryImage } from './image'; +import { MemoryImageDataUint1 } from './image-data-uint1'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +export class PixelUint1 implements Pixel, Iterable, Iterator { + private _index: number; + private _bitIndex: number; + private _rowOffset: number; + + private readonly _image: MemoryImageDataUint1; + public get image(): MemoryImageDataUint1 { + return this._image; + } + + private _x: number; + public get x(): number { + return this._x; + } + + private _y: number; + public get y(): number { + return this._y; + } + + public get xNormalized(): number { + return this.width > 1 ? this._x / (this.width - 1) : 0; + } + + public get yNormalized(): number { + return this.height > 1 ? this._y / (this.height - 1) : 0; + } + + public get index(): number { + return this.getChannelInternal(0); + } + public set index(i: number) { + this.setChannel(0, i); + } + + public get data(): Uint8Array { + return this._image.data; + } + + public get isValid(): boolean { + return ( + this._x >= 0 && + this._x < this._image.width - 1 && + this._y >= 0 && + this._y < this._image.height - 1 + ); + } + + public get width(): number { + return this._image.width; + } + + public get height(): number { + return this._image.width; + } + + public get length(): number { + return this.palette?.numChannels ?? this._image.numChannels; + } + + public get numChannels(): number { + return this._image.numChannels; + } + + public get maxChannelValue(): number { + return this._image.maxChannelValue; + } + + public get maxIndexValue(): number { + return this._image.maxIndexValue; + } + + public get format(): Format { + return Format.uint1; + } + + public get isLdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get isHdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get hasPalette(): boolean { + return this._image.hasPalette; + } + + public get palette(): Palette | undefined { + return this._image.palette; + } + + public get r(): number { + return this.getChannel(0); + } + public set r(r: number) { + this.setChannel(0, r); + } + + public get g(): number { + return this.getChannel(1); + } + public set g(g: number) { + this.setChannel(1, g); + } + + public get b(): number { + return this.getChannel(2); + } + public set b(b: number) { + this.setChannel(2, b); + } + + public get a(): number { + return this.getChannel(3); + } + public set a(a: number) { + this.setChannel(3, a); + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + public get imageLength(): number { + return this._image.length; + } + + constructor( + x: number, + y: number, + index: number, + bitIndex: number, + rowOffset: number, + image: MemoryImageDataUint1 + ) { + this._image = image; + this._index = index; + this._bitIndex = bitIndex; + this._rowOffset = rowOffset; + this._x = x; + this._y = y; + } + + public static imageData(image: MemoryImageDataUint1) { + return new PixelUint1(-1, 0, 0, -1, 0, image); + } + + public static image(image: MemoryImage) { + return new PixelUint1( + -1, + 0, + 0, + -1, + 0, + image.data instanceof MemoryImageDataUint1 + ? (image.data as MemoryImageDataUint1) + : new MemoryImageDataUint1(0, 0, 0) + ); + } + + public static from(other: PixelUint1) { + return new PixelUint1( + other.x, + other.y, + other._index, + other._bitIndex, + other._rowOffset, + other.image + ); + } + + private getChannelInternal(channel: number): number { + let i = this._index; + let bi = 7 - (this._bitIndex + channel); + if (bi < 0) { + bi += 8; + i++; + } + if (i >= this._image.data.length) { + return 0; + } + return (this._image.data[i] >> bi) & 0x1; + } + + public next(): IteratorResult { + this._x++; + if (this._x === this.width) { + this._x = 0; + this._y++; + this._bitIndex = 0; + this._index++; + this._rowOffset += this.image.rowStride; + return >{ + done: this._y >= this.height, + value: this, + }; + } + + const nc = this.numChannels; + if (this.palette !== undefined || nc === 1) { + this._bitIndex++; + if (this._bitIndex > 7) { + this._bitIndex = 0; + this._index++; + } + } else { + const bpp = this.image.numChannels; + this._bitIndex = (this._x * bpp) & 0x7; + this._index = this._rowOffset + ((this._x * bpp) >> 3); + } + return >{ + done: this._index >= this.imageLength, + value: this, + }; + } + + public setPosition(x: number, y: number): void { + this._x = x; + this._y = y; + const bpp = this._image.numChannels; + this._rowOffset = this._y * this._image.rowStride; + this._index = this._rowOffset + ((this._x * bpp) >> 3); + this._bitIndex = (this._x * bpp) & 0x7; + } + + public setPositionNormalized(x: number, y: number): void { + return this.setPosition( + Math.floor(x * (this.width - 1)), + Math.floor(y * (this.height - 1)) + ); + } + + public getChannel(channel: number | Channel): number { + if (this.palette !== undefined) { + return this.palette.get(this.getChannelInternal(0), channel); + } else { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.numChannels + ? this.getChannelInternal(channel) + : 0; + } + } + } + + public getChannelNormalized(channel: Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(channel: number, value: number): void { + if (channel >= this.numChannels) { + return; + } + + let i = this._index; + let bi = 7 - (this._bitIndex + channel); + if (bi < 0) { + bi += 8; + i++; + } + + let v = this.data[i]; + + const vi = MathUtils.clampInt(value, 0, 1); + const msk = [0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f]; + const mask = msk[bi]; + v = (v & mask) | (vi << bi); + this.data[i] = v; + } + + public set(color: Color): void { + this.r = color.r; + this.g = color.g; + this.b = color.b; + this.a = color.a; + } + + public setRgb(r: number, g: number, b: number): void { + const nc = this.image.numChannels; + if (nc > 0) { + this.setChannel(0, r); + if (nc > 1) { + this.setChannel(1, g); + if (nc > 2) { + this.setChannel(2, b); + } + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + const nc = this.numChannels; + if (nc > 0) { + this.setChannel(0, r); + if (nc > 1) { + this.setChannel(1, g); + if (nc > 2) { + this.setChannel(2, b); + if (nc > 3) { + this.setChannel(3, a); + } + } + } + } + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public equals(other: Pixel | number[]): boolean { + if (other instanceof PixelUint1) { + return ArrayUtils.equals(this.toArray(), other.toArray()); + } + if (Array.isArray(other)) { + return ArrayUtils.equals(this.toArray(), other); + } + return false; + } + + public clone(): PixelUint1 { + return PixelUint1.from(this); + } + + public convert(opt: ColorConvertOptions): Color { + return ColorUtils.convertColor({ + from: this, + format: opt.format, + numChannels: opt.numChannels, + alpha: opt.alpha, + }); + } + + public toString(): string { + return `${this.constructor.name} (${this.toArray()})`; + } + + public [Symbol.iterator](): Iterator { + return this; + } +} diff --git a/src/image/pixel-uint16.ts b/src/image/pixel-uint16.ts new file mode 100644 index 0000000..3813736 --- /dev/null +++ b/src/image/pixel-uint16.ts @@ -0,0 +1,326 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color, ColorConvertOptions } from '../color/color'; +import { ColorUtils } from '../color/color-utils'; +import { Format } from '../color/format'; +import { ArrayUtils } from '../common/array-utils'; +import { MemoryImage } from './image'; +import { MemoryImageDataUint16 } from './image-data-uint16'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +export class PixelUint16 implements Pixel, Iterable, Iterator { + private _index: number; + + private readonly _image: MemoryImageDataUint16; + public get image(): MemoryImageDataUint16 { + return this._image; + } + + private _x: number; + public get x(): number { + return this._x; + } + + private _y: number; + public get y(): number { + return this._y; + } + + public get xNormalized(): number { + return this.width > 1 ? this._x / (this.width - 1) : 0; + } + + public get yNormalized(): number { + return this.height > 1 ? this._y / (this.height - 1) : 0; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get data(): Uint16Array { + return this._image.data; + } + + public get isValid(): boolean { + return ( + this._x >= 0 && + this._x < this._image.width - 1 && + this._y >= 0 && + this._y < this._image.height - 1 + ); + } + + public get width(): number { + return this._image.width; + } + + public get height(): number { + return this._image.width; + } + + public get length(): number { + return this._image.numChannels; + } + + public get numChannels(): number { + return this._image.numChannels; + } + + public get maxChannelValue(): number { + return this._image.maxChannelValue; + } + + public get maxIndexValue(): number { + return this._image.maxIndexValue; + } + + public get format(): Format { + return Format.uint16; + } + + public get isLdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get isHdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get hasPalette(): boolean { + return this._image.hasPalette; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get r(): number { + return this.numChannels > 0 ? this.data[this._index] : 0; + } + public set r(r: number) { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + } + } + + public get g(): number { + return this.numChannels > 1 ? this.data[this._index + 1] : 0; + } + public set g(g: number) { + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + } + } + + public get b(): number { + return this.numChannels > 2 ? this.data[this._index + 2] : 0; + } + public set b(b: number) { + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + } + } + + public get a(): number { + return this.numChannels > 3 ? this.data[this._index + 3] : 0; + } + public set a(a: number) { + if (this.numChannels > 3) { + this.data[this._index + 3] = Math.trunc(a); + } + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor( + x: number, + y: number, + index: number, + image: MemoryImageDataUint16 + ) { + this._image = image; + this._index = index; + this._x = x; + this._y = y; + } + + public static imageData(image: MemoryImageDataUint16) { + return new PixelUint16(-1, 0, -image.numChannels, image); + } + + public static image(image: MemoryImage) { + return new PixelUint16( + -1, + 0, + -image.numChannels, + image.data instanceof MemoryImageDataUint16 + ? (image.data as MemoryImageDataUint16) + : new MemoryImageDataUint16(0, 0, 0) + ); + } + + public static from(other: PixelUint16) { + return new PixelUint16(other.x, other.y, other._index, other.image); + } + + public next(): IteratorResult { + this._x++; + if (this._x === this.width) { + this._x = 0; + this._y++; + if (this._y === this.height) { + return >{ + done: true, + value: this, + }; + } + } + this._index += this.numChannels; + return >{ + done: this._index >= this.image.data.length, + value: this, + }; + } + + public setPosition(x: number, y: number): void { + this._x = x; + this._y = y; + this._index = + this._y * this._image.width * this._image.numChannels + + this._x * this._image.numChannels; + } + + public setPositionNormalized(x: number, y: number): void { + return this.setPosition( + Math.floor(x * (this.width - 1)), + Math.floor(y * (this.height - 1)) + ); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.numChannels ? this.data[this._index + channel] : 0; + } + } + + public getChannelNormalized(channel: Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(channel: number, value: number): void { + if (channel < this.numChannels) { + this.data[this._index + channel] = Math.trunc(value); + } + } + + public set(color: Color): void { + this.r = color.r; + this.g = color.g; + this.b = color.b; + this.a = color.a; + } + + public setRgb(r: number, g: number, b: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + } + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + if (this.numChannels > 3) { + this.data[this._index + 3] = Math.trunc(a); + } + } + } + } + } + + public equals(other: Pixel | number[]): boolean { + if (other instanceof PixelUint16) { + return ArrayUtils.equals(this.toArray(), other.toArray()); + } + if (Array.isArray(other)) { + return ArrayUtils.equals(this.toArray(), other); + } + return false; + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone(): PixelUint16 { + return PixelUint16.from(this); + } + + public convert(opt: ColorConvertOptions): Color { + return ColorUtils.convertColor({ + from: this, + format: opt.format, + numChannels: opt.numChannels, + alpha: opt.alpha, + }); + } + + public toString(): string { + return `${this.constructor.name} (${this.toArray()})`; + } + + public [Symbol.iterator](): Iterator { + return this; + } +} diff --git a/src/image/pixel-uint2.ts b/src/image/pixel-uint2.ts new file mode 100644 index 0000000..bab1eeb --- /dev/null +++ b/src/image/pixel-uint2.ts @@ -0,0 +1,385 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color, ColorConvertOptions } from '../color/color'; +import { ColorUtils } from '../color/color-utils'; +import { Format } from '../color/format'; +import { ArrayUtils } from '../common/array-utils'; +import { MathUtils } from '../common/math-utils'; +import { MemoryImage } from './image'; +import { MemoryImageDataUint2 } from './image-data-uint2'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +export class PixelUint2 implements Pixel, Iterable, Iterator { + private _index: number; + private _bitIndex: number; + private _rowOffset: number; + + private readonly _image: MemoryImageDataUint2; + public get image(): MemoryImageDataUint2 { + return this._image; + } + + private _x: number; + public get x(): number { + return this._x; + } + + private _y: number; + public get y(): number { + return this._y; + } + + public get xNormalized(): number { + return this.width > 1 ? this._x / (this.width - 1) : 0; + } + + public get yNormalized(): number { + return this.height > 1 ? this._y / (this.height - 1) : 0; + } + + public get index(): number { + return this.getChannelInternal(0); + } + public set index(i: number) { + this.setChannel(0, i); + } + + public get data(): Uint8Array { + return this._image.data; + } + + public get isValid(): boolean { + return ( + this._x >= 0 && + this._x < this._image.width - 1 && + this._y >= 0 && + this._y < this._image.height - 1 + ); + } + + public get width(): number { + return this._image.width; + } + + public get height(): number { + return this._image.width; + } + + public get length(): number { + return this.palette?.numChannels ?? this._image.numChannels; + } + + public get numChannels(): number { + return this._image.numChannels; + } + + public get maxChannelValue(): number { + return this._image.maxChannelValue; + } + + public get maxIndexValue(): number { + return this._image.maxIndexValue; + } + + public get format(): Format { + return Format.uint2; + } + + public get isLdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get isHdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get hasPalette(): boolean { + return this._image.hasPalette; + } + + public get palette(): Palette | undefined { + return this._image.palette; + } + + public get r(): number { + return this.getChannel(0); + } + public set r(r: number) { + this.setChannel(0, r); + } + + public get g(): number { + return this.getChannel(1); + } + public set g(g: number) { + this.setChannel(1, g); + } + + public get b(): number { + return this.getChannel(2); + } + public set b(b: number) { + this.setChannel(2, b); + } + + public get a(): number { + return this.getChannel(3); + } + public set a(a: number) { + this.setChannel(3, a); + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + public get bitsPerPixel(): number { + return this._image.palette !== undefined ? 2 : this._image.numChannels << 1; + } + + constructor( + x: number, + y: number, + index: number, + bitIndex: number, + rowOffset: number, + image: MemoryImageDataUint2 + ) { + this._image = image; + this._index = index; + this._bitIndex = bitIndex; + this._rowOffset = rowOffset; + this._x = x; + this._y = y; + } + + public static imageData(image: MemoryImageDataUint2) { + return new PixelUint2(-1, 0, 0, -2, 0, image); + } + + public static image(image: MemoryImage) { + return new PixelUint2( + -1, + 0, + 0, + -2, + 0, + image.data instanceof MemoryImageDataUint2 + ? (image.data as MemoryImageDataUint2) + : new MemoryImageDataUint2(0, 0, 0) + ); + } + + public static from(other: PixelUint2) { + return new PixelUint2( + other.x, + other.y, + other._index, + other._bitIndex, + other._rowOffset, + other.image + ); + } + + private getChannelInternal(channel: number): number { + let i = this._index; + let bi = 6 - (this._bitIndex + (channel << 1)); + if (bi < 0) { + bi += 8; + i++; + } + return (this._image.data[i] >> bi) & 0x3; + } + + public next(): IteratorResult { + this._x++; + if (this._x === this.width) { + this._x = 0; + this._y++; + this._bitIndex = 0; + this._index++; + this._rowOffset += this.image.rowStride; + return >{ + done: this._y >= this.height, + value: this, + }; + } + + const nc = this.numChannels; + if (this.palette !== undefined || nc === 1) { + this._bitIndex += 2; + if (this._bitIndex > 7) { + this._bitIndex = 0; + this._index++; + } + } else { + const bpp = this.bitsPerPixel; + this._bitIndex = (this._x * bpp) & 0x7; + this._index = this._rowOffset + ((this._x * bpp) >> 3); + } + return >{ + done: this._index >= this.image.data.length, + value: this, + }; + } + + public setPosition(x: number, y: number): void { + this._x = x; + this._y = y; + const bpp = this.bitsPerPixel; + this._rowOffset = this._y * this._image.rowStride; + this._index = this._rowOffset + ((this._x * bpp) >> 3); + this._bitIndex = (this._x * bpp) & 0x7; + } + + public setPositionNormalized(x: number, y: number): void { + return this.setPosition( + Math.floor(x * (this.width - 1)), + Math.floor(y * (this.height - 1)) + ); + } + + public getChannel(channel: number | Channel): number { + if (this.palette !== undefined) { + return this.palette.get(this.getChannelInternal(0), channel); + } else { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.numChannels + ? this.getChannelInternal(channel) + : 0; + } + } + } + + public getChannelNormalized(channel: Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(channel: number, value: number): void { + if (channel >= this.image.numChannels) { + return; + } + + let i = this._index; + let bi = 6 - (this._bitIndex + (channel << 1)); + if (bi < 0) { + bi += 8; + i++; + } + + let v = this.data[i]; + + const vi = MathUtils.clampInt(value, 0, 3); + const msk = [0xfc, 0xf3, 0xcf, 0x3f]; + const mask = msk[bi >> 1]; + v = (v & mask) | (vi << bi); + this.data[i] = v; + } + + public set(color: Color): void { + this.r = color.r; + this.g = color.g; + this.b = color.b; + this.a = color.a; + } + + public setRgb(r: number, g: number, b: number): void { + const nc = this.image.numChannels; + if (nc > 0) { + this.setChannel(0, r); + if (nc > 1) { + this.setChannel(1, g); + if (nc > 2) { + this.setChannel(2, b); + } + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + const nc = this.image.numChannels; + if (nc > 0) { + this.setChannel(0, r); + if (nc > 1) { + this.setChannel(1, g); + if (nc > 2) { + this.setChannel(2, b); + if (nc > 3) { + this.setChannel(3, a); + } + } + } + } + } + + public equals(other: Pixel | number[]): boolean { + if (other instanceof PixelUint2) { + return ArrayUtils.equals(this.toArray(), other.toArray()); + } + if (Array.isArray(other)) { + return ArrayUtils.equals(this.toArray(), other); + } + return false; + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone(): PixelUint2 { + return PixelUint2.from(this); + } + + public convert(opt: ColorConvertOptions): Color { + return ColorUtils.convertColor({ + from: this, + format: opt.format, + numChannels: opt.numChannels, + alpha: opt.alpha, + }); + } + + public toString(): string { + return `${this.constructor.name} (${this.toArray()})`; + } + + public [Symbol.iterator](): Iterator { + return this; + } +} diff --git a/src/image/pixel-uint32.ts b/src/image/pixel-uint32.ts new file mode 100644 index 0000000..d9da192 --- /dev/null +++ b/src/image/pixel-uint32.ts @@ -0,0 +1,326 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color, ColorConvertOptions } from '../color/color'; +import { ColorUtils } from '../color/color-utils'; +import { Format } from '../color/format'; +import { ArrayUtils } from '../common/array-utils'; +import { MemoryImage } from './image'; +import { MemoryImageDataUint32 } from './image-data-uint32'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +export class PixelUint32 implements Pixel, Iterable, Iterator { + private _index: number; + + private readonly _image: MemoryImageDataUint32; + public get image(): MemoryImageDataUint32 { + return this._image; + } + + private _x: number; + public get x(): number { + return this._x; + } + + private _y: number; + public get y(): number { + return this._y; + } + + public get xNormalized(): number { + return this.width > 1 ? this._x / (this.width - 1) : 0; + } + + public get yNormalized(): number { + return this.height > 1 ? this._y / (this.height - 1) : 0; + } + + public get index(): number { + return this.r; + } + public set index(i: number) { + this.r = i; + } + + public get data(): Uint32Array { + return this._image.data; + } + + public get isValid(): boolean { + return ( + this._x >= 0 && + this._x < this._image.width - 1 && + this._y >= 0 && + this._y < this._image.height - 1 + ); + } + + public get width(): number { + return this._image.width; + } + + public get height(): number { + return this._image.width; + } + + public get length(): number { + return this._image.numChannels; + } + + public get numChannels(): number { + return this._image.numChannels; + } + + public get maxChannelValue(): number { + return this._image.maxChannelValue; + } + + public get maxIndexValue(): number { + return this._image.maxIndexValue; + } + + public get format(): Format { + return Format.uint32; + } + + public get isLdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get isHdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get hasPalette(): boolean { + return this._image.hasPalette; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get r(): number { + return this.numChannels > 0 ? this.data[this._index] : 0; + } + public set r(r: number) { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + } + } + + public get g(): number { + return this.numChannels > 1 ? this.data[this._index + 1] : 0; + } + public set g(g: number) { + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + } + } + + public get b(): number { + return this.numChannels > 2 ? this.data[this._index + 2] : 0; + } + public set b(b: number) { + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + } + } + + public get a(): number { + return this.numChannels > 3 ? this.data[this._index + 3] : 0; + } + public set a(a: number) { + if (this.numChannels > 3) { + this.data[this._index + 3] = Math.trunc(a); + } + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor( + x: number, + y: number, + index: number, + image: MemoryImageDataUint32 + ) { + this._image = image; + this._index = index; + this._x = x; + this._y = y; + } + + public static imageData(image: MemoryImageDataUint32) { + return new PixelUint32(-1, 0, -image.numChannels, image); + } + + public static image(image: MemoryImage) { + return new PixelUint32( + -1, + 0, + -image.numChannels, + image.data instanceof MemoryImageDataUint32 + ? (image.data as MemoryImageDataUint32) + : new MemoryImageDataUint32(0, 0, 0) + ); + } + + public static from(other: PixelUint32) { + return new PixelUint32(other.x, other.y, other._index, other.image); + } + + public next(): IteratorResult { + this._x++; + if (this._x === this.width) { + this._x = 0; + this._y++; + if (this._y === this.height) { + return >{ + done: true, + value: this, + }; + } + } + this._index += this.numChannels; + return >{ + done: this._index >= this.image.data.length, + value: this, + }; + } + + public setPosition(x: number, y: number): void { + this._x = x; + this._y = y; + this._index = + this._y * this._image.width * this._image.numChannels + + this._x * this._image.numChannels; + } + + public setPositionNormalized(x: number, y: number): void { + return this.setPosition( + Math.floor(x * (this.width - 1)), + Math.floor(y * (this.height - 1)) + ); + } + + public getChannel(channel: number | Channel): number { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.numChannels ? this.data[this._index + channel] : 0; + } + } + + public getChannelNormalized(channel: Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(channel: number, value: number): void { + if (channel < this.numChannels) { + this.data[this._index + channel] = Math.trunc(value); + } + } + + public set(color: Color): void { + this.r = color.r; + this.g = color.g; + this.b = color.b; + this.a = color.a; + } + + public setRgb(r: number, g: number, b: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + } + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + if (this.numChannels > 3) { + this.data[this._index + 3] = Math.trunc(a); + } + } + } + } + } + + public equals(other: Pixel | number[]): boolean { + if (other instanceof PixelUint32) { + return ArrayUtils.equals(this.toArray(), other.toArray()); + } + if (Array.isArray(other)) { + return ArrayUtils.equals(this.toArray(), other); + } + return false; + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone(): PixelUint32 { + return PixelUint32.from(this); + } + + public convert(opt: ColorConvertOptions): Color { + return ColorUtils.convertColor({ + from: this, + format: opt.format, + numChannels: opt.numChannels, + alpha: opt.alpha, + }); + } + + public toString(): string { + return `${this.constructor.name} (${this.toArray()})`; + } + + public [Symbol.iterator](): Iterator { + return this; + } +} diff --git a/src/image/pixel-uint4.ts b/src/image/pixel-uint4.ts new file mode 100644 index 0000000..8f620fd --- /dev/null +++ b/src/image/pixel-uint4.ts @@ -0,0 +1,385 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color, ColorConvertOptions } from '../color/color'; +import { ColorUtils } from '../color/color-utils'; +import { Format } from '../color/format'; +import { ArrayUtils } from '../common/array-utils'; +import { MathUtils } from '../common/math-utils'; +import { MemoryImage } from './image'; +import { MemoryImageDataUint4 } from './image-data-uint4'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +export class PixelUint4 implements Pixel, Iterable, Iterator { + private _index: number; + private _bitIndex: number; + + private readonly _image: MemoryImageDataUint4; + public get image(): MemoryImageDataUint4 { + return this._image; + } + + private _x: number; + public get x(): number { + return this._x; + } + + private _y: number; + public get y(): number { + return this._y; + } + + public get xNormalized(): number { + return this.width > 1 ? this._x / (this.width - 1) : 0; + } + + public get yNormalized(): number { + return this.height > 1 ? this._y / (this.height - 1) : 0; + } + + public get index(): number { + return this.getChannelInternal(0); + } + public set index(i: number) { + this.setChannel(0, i); + } + + public get data(): Uint8Array { + return this._image.data; + } + + public get isValid(): boolean { + return ( + this._x >= 0 && + this._x < this._image.width - 1 && + this._y >= 0 && + this._y < this._image.height - 1 + ); + } + + public get width(): number { + return this._image.width; + } + + public get height(): number { + return this._image.width; + } + + public get length(): number { + return this.palette?.numChannels ?? this._image.numChannels; + } + + public get numChannels(): number { + return this._image.numChannels; + } + + public get maxChannelValue(): number { + return this._image.maxChannelValue; + } + + public get maxIndexValue(): number { + return this._image.maxIndexValue; + } + + public get format(): Format { + return Format.uint4; + } + + public get isLdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get isHdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get hasPalette(): boolean { + return this._image.hasPalette; + } + + public get palette(): Palette | undefined { + return this._image.palette; + } + + public get r(): number { + return this.getChannel(0); + } + public set r(r: number) { + this.setChannel(0, r); + } + + public get g(): number { + return this.getChannel(1); + } + public set g(g: number) { + this.setChannel(1, g); + } + + public get b(): number { + return this.getChannel(2); + } + public set b(b: number) { + this.setChannel(2, b); + } + + public get a(): number { + return this.getChannel(3); + } + public set a(a: number) { + this.setChannel(3, a); + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor( + x: number, + y: number, + index: number, + bitIndex: number, + image: MemoryImageDataUint4 + ) { + this._image = image; + this._index = index; + this._bitIndex = bitIndex; + this._x = x; + this._y = y; + } + + public static imageData(image: MemoryImageDataUint4) { + return new PixelUint4(-1, 0, 0, -(image.numChannels << 2), image); + } + + public static image(image: MemoryImage) { + return new PixelUint4( + -1, + 0, + 0, + -(image.numChannels << 2), + image.data instanceof MemoryImageDataUint4 + ? (image.data as MemoryImageDataUint4) + : new MemoryImageDataUint4(0, 0, 0) + ); + } + + public static from(other: PixelUint4) { + return new PixelUint4( + other.x, + other.y, + other._index, + other._bitIndex, + other.image + ); + } + + private getChannelInternal(channel: number): number { + let i = this._index; + let bi = 4 - (this._bitIndex + (channel << 2)); + if (bi < 0) { + bi += 8; + i++; + } + return (this._image.data[i] >> bi) & 0xf; + } + + public next(): IteratorResult { + this._x++; + if (this._x === this.width) { + // skip row stride padding bits + this._x = 0; + this._y++; + this._bitIndex = 0; + this._index = this._y * this.image.rowStride; + return >{ + done: this._y >= this.height, + value: this, + }; + } + const nc = this.image.numChannels; + if (this.palette !== undefined || nc === 1) { + this._bitIndex += 4; + if (this._bitIndex > 7) { + this._bitIndex = 0; + this._index++; + } + } else { + const bpp = nc << 2; + this._bitIndex += bpp; + while (this._bitIndex > 7) { + this._bitIndex -= 8; + this._index++; + } + } + return >{ + done: this._index >= this.image.data.length, + value: this, + }; + } + + public setPosition(x: number, y: number): void { + this._x = x; + this._y = y; + const bpp = this.image.numChannels * 4; + const w = this.image.width; + const rowStride = this.image.rowStride; + this._index = + bpp === 4 + ? this._y * rowStride + (this._x >> 1) + : bpp === 8 + ? this._y * w + this._x + : bpp === 16 + ? this._y * rowStride + (this._x << 1) + : this._y * rowStride + ((this._x * bpp) >> 3); + this._bitIndex = bpp > 7 ? (this._x * bpp) & 0x4 : (this._x * bpp) & 0x7; + } + + public setPositionNormalized(x: number, y: number): void { + return this.setPosition( + Math.floor(x * (this.width - 1)), + Math.floor(y * (this.height - 1)) + ); + } + + public getChannel(channel: number | Channel): number { + if (this.palette !== undefined) { + return this.palette.get(this.getChannelInternal(0), channel); + } else { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.numChannels + ? this.getChannelInternal(channel) + : 0; + } + } + } + + public getChannelNormalized(channel: Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(channel: number, value: number): void { + if (channel >= this.image.numChannels) { + return; + } + + let i = this._index; + let bi = 4 - (this._bitIndex + (channel << 2)); + if (bi < 0) { + bi += 8; + i++; + } + + let v = this.data[i]; + + const vi = MathUtils.clampInt(value, 0, 15); + const mask = bi === 4 ? 0x0f : 0xf0; + v = (v & mask) | (vi << bi); + this.data[i] = v; + } + + public set(color: Color): void { + this.r = color.r; + this.g = color.g; + this.b = color.b; + this.a = color.a; + } + + public setRgb(r: number, g: number, b: number): void { + const nc = this.image.numChannels; + if (nc > 0) { + this.setChannel(0, r); + if (nc > 1) { + this.setChannel(1, g); + if (nc > 2) { + this.setChannel(2, b); + } + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + const nc = this.image.numChannels; + if (nc > 0) { + this.setChannel(0, r); + if (nc > 1) { + this.setChannel(1, g); + if (nc > 2) { + this.setChannel(2, b); + if (nc > 3) { + this.setChannel(3, a); + } + } + } + } + } + + public equals(other: Pixel | number[]): boolean { + if (other instanceof PixelUint4) { + return ArrayUtils.equals(this.toArray(), other.toArray()); + } + if (Array.isArray(other)) { + return ArrayUtils.equals(this.toArray(), other); + } + return false; + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone(): PixelUint4 { + return PixelUint4.from(this); + } + + public convert(opt: ColorConvertOptions): Color { + return ColorUtils.convertColor({ + from: this, + format: opt.format, + numChannels: opt.numChannels, + alpha: opt.alpha, + }); + } + + public toString(): string { + return `${this.constructor.name} (${this.toArray()})`; + } + + public [Symbol.iterator](): Iterator { + return this; + } +} diff --git a/src/image/pixel-uint8.ts b/src/image/pixel-uint8.ts new file mode 100644 index 0000000..5c0aefb --- /dev/null +++ b/src/image/pixel-uint8.ts @@ -0,0 +1,353 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color, ColorConvertOptions } from '../color/color'; +import { ColorUtils } from '../color/color-utils'; +import { Format } from '../color/format'; +import { ArrayUtils } from '../common/array-utils'; +import { MathUtils } from '../common/math-utils'; +import { MemoryImage } from './image'; +import { MemoryImageDataUint8 } from './image-data-uint8'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +export class PixelUint8 implements Pixel, Iterable, Iterator { + private _index: number; + + private readonly _image: MemoryImageDataUint8; + public get image(): MemoryImageDataUint8 { + return this._image; + } + + private _x: number; + public get x(): number { + return this._x; + } + + private _y: number; + public get y(): number { + return this._y; + } + + public get xNormalized(): number { + return this.width > 1 ? this._x / (this.width - 1) : 0; + } + + public get yNormalized(): number { + return this.height > 1 ? this._y / (this.height - 1) : 0; + } + + public get index(): number { + return this.data[this._index]; + } + public set index(i: number) { + this.data[this._index] = MathUtils.clampInt255(i); + } + + public get data(): Uint8Array { + return this._image.data; + } + + public get isValid(): boolean { + return ( + this._x >= 0 && + this._x < this._image.width - 1 && + this._y >= 0 && + this._y < this._image.height - 1 + ); + } + + public get width(): number { + return this._image.width; + } + + public get height(): number { + return this._image.width; + } + + public get length(): number { + return this.palette?.numChannels ?? this._image.numChannels; + } + + public get numChannels(): number { + return this._image.numChannels; + } + + public get maxChannelValue(): number { + return this._image.maxChannelValue; + } + + public get maxIndexValue(): number { + return this._image.maxIndexValue; + } + + public get format(): Format { + return Format.uint8; + } + + public get isLdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get isHdrFormat(): boolean { + return this._image.isLdrFormat; + } + + public get hasPalette(): boolean { + return this._image.hasPalette; + } + + public get palette(): Palette | undefined { + return this._image.palette; + } + + public get r(): number { + return this.palette === undefined + ? this.numChannels > 0 + ? this.data[this._index] + : 0 + : this.palette.getRed(this.data[this._index]); + } + public set r(r: number) { + if (this.numChannels > 0) { + this.data[this._index] = MathUtils.clampInt255(r); + } + } + + public get g(): number { + return this.palette === undefined + ? this.numChannels > 1 + ? this.data[this._index + 1] + : 0 + : this.palette.getGreen(this.data[this._index]); + } + public set g(g: number) { + if (this.numChannels > 1) { + this.data[this._index + 1] = MathUtils.clampInt255(g); + } + } + + public get b(): number { + return this.palette === undefined + ? this.numChannels > 2 + ? this.data[this._index + 2] + : 0 + : this.palette.getBlue(this.data[this._index]); + } + public set b(b: number) { + if (this.numChannels > 2) { + this.data[this._index + 2] = MathUtils.clampInt255(b); + } + } + + public get a(): number { + return this.palette === undefined + ? this.numChannels > 3 + ? this.data[this._index + 3] + : 255 + : this.palette.getAlpha(this.data[this._index]); + } + public set a(a: number) { + if (this.numChannels > 3) { + this.data[this._index + 3] = MathUtils.clampInt255(a); + } + } + + public get rNormalized(): number { + return this.r / this.maxChannelValue; + } + public set rNormalized(v: number) { + this.r = v * this.maxChannelValue; + } + + public get gNormalized(): number { + return this.g / this.maxChannelValue; + } + public set gNormalized(v: number) { + this.g = v * this.maxChannelValue; + } + + public get bNormalized(): number { + return this.b / this.maxChannelValue; + } + public set bNormalized(v: number) { + this.b = v * this.maxChannelValue; + } + + public get aNormalized(): number { + return this.a / this.maxChannelValue; + } + public set aNormalized(v: number) { + this.a = v * this.maxChannelValue; + } + + public get luminance(): number { + return ColorUtils.getLuminance(this); + } + + public get luminanceNormalized(): number { + return ColorUtils.getLuminanceNormalized(this); + } + + constructor( + x: number, + y: number, + index: number, + image: MemoryImageDataUint8 + ) { + this._image = image; + this._index = index; + this._x = x; + this._y = y; + } + + public static imageData(image: MemoryImageDataUint8) { + return new PixelUint8(-1, 0, -image.numChannels, image); + } + + public static image(image: MemoryImage) { + return new PixelUint8( + -1, + 0, + -image.numChannels, + image.data instanceof MemoryImageDataUint8 + ? (image.data as MemoryImageDataUint8) + : new MemoryImageDataUint8(0, 0, 0) + ); + } + + public static from(other: PixelUint8) { + return new PixelUint8(other.x, other.y, other._index, other.image); + } + + public next(): IteratorResult { + this._x++; + if (this._x === this.width) { + this._x = 0; + this._y++; + if (this._y === this.height) { + return >{ + done: true, + value: this, + }; + } + } + this._index += this.palette === undefined ? this.numChannels : 1; + return >{ + done: this._index >= this.image.data.length, + value: this, + }; + } + + public setPosition(x: number, y: number): void { + this._x = x; + this._y = y; + this._index = + this._y * this._image.width * this._image.numChannels + + this._x * this._image.numChannels; + } + + public setPositionNormalized(x: number, y: number): void { + return this.setPosition( + Math.floor(x * (this.width - 1)), + Math.floor(y * (this.height - 1)) + ); + } + + public getChannel(channel: number | Channel): number { + if (this.palette !== undefined) { + return this.palette.get(this.data[this._index], channel); + } else { + if (channel === Channel.luminance) { + return this.luminance; + } else { + return channel < this.data.length + ? this.data[this._index + channel] + : 0; + } + } + } + + public getChannelNormalized(channel: Channel): number { + return this.getChannel(channel) / this.maxChannelValue; + } + + public setChannel(channel: number, value: number): void { + if (channel < this.numChannels) { + this.data[this._index + channel] = MathUtils.clampInt255(value); + } + } + + public set(color: Color): void { + if (this._image.hasPalette) { + this._index = color.index; + } else { + this.r = color.r; + this.g = color.g; + this.b = color.b; + this.a = color.a; + } + } + + public setRgb(r: number, g: number, b: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + } + } + } + } + + public setRgba(r: number, g: number, b: number, a: number): void { + if (this.numChannels > 0) { + this.data[this._index] = Math.trunc(r); + if (this.numChannels > 1) { + this.data[this._index + 1] = Math.trunc(g); + if (this.numChannels > 2) { + this.data[this._index + 2] = Math.trunc(b); + if (this.numChannels > 3) { + this.data[this._index + 3] = Math.trunc(a); + } + } + } + } + } + + public equals(other: Pixel | number[]): boolean { + if (other instanceof PixelUint8) { + return ArrayUtils.equals(this.toArray(), other.toArray()); + } + if (Array.isArray(other)) { + return ArrayUtils.equals(this.toArray(), other); + } + return false; + } + + public toArray(): number[] { + return ArrayUtils.generate(this.length, (i) => this.getChannel(i)); + } + + public clone(): PixelUint8 { + return PixelUint8.from(this); + } + + public convert(opt: ColorConvertOptions): Color { + return ColorUtils.convertColor({ + from: this, + format: opt.format, + numChannels: opt.numChannels, + alpha: opt.alpha, + }); + } + + public toString(): string { + return `${this.constructor.name} (${this.toArray()})`; + } + + public [Symbol.iterator](): Iterator { + return this; + } +} diff --git a/src/image/pixel-undefined.ts b/src/image/pixel-undefined.ts new file mode 100644 index 0000000..3b3878f --- /dev/null +++ b/src/image/pixel-undefined.ts @@ -0,0 +1,193 @@ +/** @format */ + +import { Channel } from '../color/channel'; +import { Color, ColorConvertOptions } from '../color/color'; +import { Format } from '../color/format'; +import { MemoryImageData } from './image-data'; +import { MemoryImageDataUint8 } from './image-data-uint8'; +import { Palette } from './palette'; +import { Pixel } from './pixel'; + +/** + * Represents an invalid pixel. + */ +export class PixelUndefined implements Pixel, Iterable, Iterator { + private static readonly _nullImageData = new MemoryImageDataUint8(0, 0, 0); + + public get image(): MemoryImageData { + return PixelUndefined._nullImageData; + } + + public get isValid(): boolean { + return false; + } + + public get width(): number { + return 0; + } + + public get height(): number { + return 0; + } + + public get x(): number { + return 0; + } + + public get y(): number { + return 0; + } + + public get xNormalized(): number { + return 0; + } + + public get yNormalized(): number { + return 0; + } + + public get length(): number { + return 0; + } + + public get maxChannelValue(): number { + return 0; + } + + public get maxIndexValue(): number { + return 0; + } + + public get format(): Format { + return Format.uint8; + } + + public get isLdrFormat(): boolean { + return false; + } + + public get isHdrFormat(): boolean { + return false; + } + + public get hasPalette(): boolean { + return false; + } + + public get palette(): Palette | undefined { + return undefined; + } + + public get index(): number { + return 0; + } + + public set index(_i: number) {} + + public get r(): number { + return 0; + } + + public set r(_r: number) {} + + public get g(): number { + return 0; + } + + public set g(_g: number) {} + + public get b(): number { + return 0; + } + + public set b(_b: number) {} + + public get a(): number { + return 0; + } + + public set a(_a: number) {} + + public get rNormalized(): number { + return 0; + } + + public set rNormalized(_v: number) {} + + public get gNormalized(): number { + return 0; + } + + public set gNormalized(_v: number) {} + + public get bNormalized(): number { + return 0; + } + + public set bNormalized(_v: number) {} + + public get aNormalized(): number { + return 0; + } + + public set aNormalized(_v: number) {} + + public get luminance(): number { + return 0; + } + + public get luminanceNormalized(): number { + return 0; + } + + public getChannel(_channel: number): number { + return 0; + } + + public getChannelNormalized(_channel: Channel): number { + return 0; + } + + public setChannel(_channel: number, _value: number): void {} + + public set(_color: Color): void {} + + public setRgb(_r: number, _g: number, _b: number): void {} + + public setRgba(_r: number, _g: number, _b: number, _a: number): void {} + + public clone(): Color { + return new PixelUndefined(); + } + + public convert(_options: ColorConvertOptions): Color { + return this; + } + + public setPosition(_x: number, _y: number): void {} + + public setPositionNormalized(_x: number, _y: number): void {} + + public equals(other: Pixel): boolean { + return other instanceof PixelUndefined; + } + + public next(): IteratorResult { + return { + done: true, + value: this, + }; + } + + public toArray(): number[] { + return []; + } + + public toString(): string { + return `${this.constructor.name} (undefined)`; + } + + public [Symbol.iterator](): Iterator { + return this; + } +} diff --git a/src/image/pixel.ts b/src/image/pixel.ts new file mode 100644 index 0000000..3af7b5c --- /dev/null +++ b/src/image/pixel.ts @@ -0,0 +1,57 @@ +/** @format */ + +import { Color } from '../color/color'; +import { MemoryImageData } from './image-data'; +import { PixelUndefined } from './pixel-undefined'; + +export interface Pixel extends Color, Iterator { + /** + * The [MemoryImageData] this pixel refers to. + */ + get image(): MemoryImageData; + /** + * True if this points to a valid pixel, otherwise false. + */ + get isValid(): boolean; + /** + * The width in pixels of the image data this pixel refers to. + */ + get width(): number; + /** + * The height in pixels of the image data this pixel refers to. + */ + get height(): number; + /** + * The x coordinate of the pixel. + */ + get x(): number; + /** + * The y coordinate of the pixel. + */ + get y(): number; + /** + * The normalized x coordinate of the pixel, in the range [0, 1]. + */ + get xNormalized(): number; + /** + * The normalized y coordinate of the pixel, in the range [0, 1]. + */ + get yNormalized(): number; + /** + * Set the coordinates of the pixel. + */ + setPosition(x: number, y: number): void; + /** + * Set the normalized coordinates of the pixel, in the range [0, 1]. + */ + setPositionNormalized(x: number, y: number): void; + /** + * Tests if this pixel has the same values as the given pixel or color. + */ + equals(other: Pixel | number[]): boolean; +} + +/** + * UndefinedPixel is used to represent an invalid pixel. + */ +export const UndefinedPixel = new PixelUndefined(); diff --git a/src/image/quantizer-type.ts b/src/image/quantizer-type.ts new file mode 100644 index 0000000..986c5c3 --- /dev/null +++ b/src/image/quantizer-type.ts @@ -0,0 +1,6 @@ +/** @format */ + +export enum QuantizerType { + octree, + neural, +} diff --git a/src/image/quantizer.ts b/src/image/quantizer.ts new file mode 100644 index 0000000..6aede2c --- /dev/null +++ b/src/image/quantizer.ts @@ -0,0 +1,28 @@ +/** @format */ + +import { Color } from '../color/color'; +import { MemoryImage } from './image'; +import { Palette } from './palette'; + +/** + * Interface for color quantizers, which reduce the total number of colors + * used by an image to a given maximum, used to convert images to palette + * images. + */ +export interface Quantizer { + get palette(): Palette; + + getColorIndex(c: Color): number; + + getColorIndexRgb(r: number, g: number, b: number): number; + + /** + * Find the index of the closest color to **c** in the **palette**. + */ + getQuantizedColor(c: Color): Color; + + /** + * Convert the **image** to a palette image. + */ + getIndexImage(image: MemoryImage): MemoryImage; +} diff --git a/src/index.ts b/src/index.ts index 8f25a42..90e093d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,9 @@ /** @format */ -import { FrameAnimation } from './common/frame-animation'; -import { MemoryImage } from './common/memory-image'; import { CompressionLevel, TypedArray } from './common/typings'; import { BmpDecoder } from './formats/bmp-decoder'; import { BmpEncoder } from './formats/bmp-encoder'; +import { Encoder } from './formats/encoder'; import { Decoder } from './formats/decoder'; import { GifDecoder } from './formats/gif-decoder'; import { GifEncoder } from './formats/gif-encoder'; @@ -18,74 +17,94 @@ import { TgaDecoder } from './formats/tga-decoder'; import { TgaEncoder } from './formats/tga-encoder'; import { TiffDecoder } from './formats/tiff-decoder'; import { TiffEncoder } from './formats/tiff-encoder'; +import { MemoryImage } from './image/image'; +import { PngFilterType } from './formats/png/png-filter-type'; +import { DitherKernel } from './filter/dither-kernel'; +import { ExifData } from './exif/exif-data'; +import { JpegUtils } from './formats/jpeg/jpeg-utils'; + +// Export types from 'color' directory +export { ChannelOrder, ChannelOrderLength } from './color/channel-order'; +export { Channel } from './color/channel'; +export { ColorFloat16 } from './color/color-float16'; +export { ColorFloat32 } from './color/color-float32'; +export { ColorFloat64 } from './color/color-float64'; +export { ColorInt8 } from './color/color-int8'; +export { ColorInt16 } from './color/color-int16'; +export { ColorInt32 } from './color/color-int32'; +export { ColorRgb8 } from './color/color-rgb8'; +export { ColorRgba8 } from './color/color-rgba8'; +export { ColorUint1 } from './color/color-uint1'; +export { ColorUint2 } from './color/color-uint2'; +export { ColorUint4 } from './color/color-uint4'; +export { ColorUint8 } from './color/color-uint8'; +export { ColorUint16 } from './color/color-uint16'; +export { ColorUint32 } from './color/color-uint32'; +export { Color, ColorConvertOptions } from './color/color'; +export { + Format, + FormatType, + FormatMaxValue, + FormatSize, + FormatToFormatType, + convertFormatValue, +} from './color/format'; // Export types from 'common' directory export { ArrayUtils } from './common/array-utils'; -export { BitOperators } from './common/bit-operators'; -export { BlendMode } from './common/blend-mode'; -export { ColorChannel } from './common/color-channel'; -export { ColorModel } from './common/color-model'; -export { Color } from './common/color'; -export { Crc32, Crc32Parameters } from './common/crc32'; -export { DisposeMode } from './common/dispose-mode'; -export { DitherKernel } from './common/dither-kernel'; -export { DitherPixel } from './common/dither-pixel'; -export { - FrameAnimation, - FrameAnimationInitOptions, -} from './common/frame-animation'; -export { FrameType } from './common/frame-type'; -export { HeapNode } from './common/heap-node'; -export { ICCProfileData } from './common/icc-profile-data'; -export { ICCPCompressionMode } from './common/iccp-compression-mode'; +export { BitUtils } from './common/bit-utils'; +export { Crc32, Crc32Options } from './common/crc32'; +export { Float16 } from './common/float16'; export { InputBuffer, InputBufferInitOptions } from './common/input-buffer'; export { Interpolation } from './common/interpolation'; export { Line } from './common/line'; -export { MathOperators } from './common/math-operators'; -export { - MemoryImage, - MemoryImageInitOptions, - MemoryImageInitOptionsColorModel, - RgbMemoryImageInitOptions, -} from './common/memory-image'; -export { NeuralQuantizer } from './common/neural-quantizer'; -export { OctreeNode } from './common/octree-node'; -export { OctreeQuantizer } from './common/octree-quantizer'; +export { MathUtils } from './common/math-utils'; export { OutputBuffer, OutputBufferInitOptions } from './common/output-buffer'; export { Point } from './common/point'; -export { Quantizer } from './common/quantizer'; export { RandomUtils } from './common/random-utils'; export { Rational } from './common/rational'; export { Rectangle } from './common/rectangle'; -export { RgbChannelSet } from './common/rgb-channel-set'; -export { TextCodec } from './common/text-codec'; -export { CompressionLevel, TypedArray, BufferEncoding } from './common/typings'; +export { StringUtils } from './common/string-utils'; +export { BufferEncoding, CompressionLevel, TypedArray } from './common/typings'; // Export types from 'draw' directory -export { DrawImageOptions } from './draw/draw-image-options'; -export { DrawLineOptions } from './draw/draw-line-options'; -export { Draw } from './draw/draw'; -export { FillFloodOptions } from './draw/fill-flood-options'; -export { MaskFloodOptions } from './draw/mask-flood-options'; +export { BlendMode } from './draw/blend-mode'; +export { CircleQuadrant } from './draw/circle-quadrant'; +export { + Draw, + CompositeImageOptions, + DrawCircleOptions, + DrawLineOptions, + DrawPixelOptions, + DrawPolygonOptions, + DrawRectOptions, + FillCircleOptions, + FillFloodOptions, + FillOptions, + FillPolygonOptions, + FillRectOptions, + MaskFloodOptions, +} from './draw/draw'; + +// Export types from 'error' directory +export { LibError } from './error/lib-error'; // Export types from 'exif' directory -export { ExifAsciiValue } from './exif/exif-value/exif-ascii-value'; -export { ExifByteValue } from './exif/exif-value/exif-byte-value'; -export { ExifDoubleValue } from './exif/exif-value/exif-double-value'; -export { ExifLongValue } from './exif/exif-value/exif-long-value'; -export { ExifRationalValue } from './exif/exif-value/exif-rational-value'; -export { ExifSByteValue } from './exif/exif-value/exif-sbyte-value'; -export { ExifShortValue } from './exif/exif-value/exif-short-value'; -export { ExifSingleValue } from './exif/exif-value/exif-single-value'; -export { ExifSLongValue } from './exif/exif-value/exif-slong-value'; -export { ExifSRationalValue } from './exif/exif-value/exif-srational-value'; -export { ExifSShortValue } from './exif/exif-value/exif-sshort-value'; -export { ExifUndefinedValue } from './exif/exif-value/exif-undefined-value'; -export { ExifValue } from './exif/exif-value/exif-value'; +export { IfdAsciiValue } from './exif/ifd-value/ifd-ascii-value'; +export { IfdByteValue } from './exif/ifd-value/ifd-byte-value'; +export { IfdDoubleValue } from './exif/ifd-value/ifd-double-value'; +export { IfdLongValue } from './exif/ifd-value/ifd-long-value'; +export { IfdRationalValue } from './exif/ifd-value/ifd-rational-value'; +export { IfdSByteValue } from './exif/ifd-value/ifd-sbyte-value'; +export { IfdShortValue } from './exif/ifd-value/ifd-short-value'; +export { IfdSingleValue } from './exif/ifd-value/ifd-single-value'; +export { IfdSLongValue } from './exif/ifd-value/ifd-slong-value'; +export { IfdSRationalValue } from './exif/ifd-value/ifd-srational-value'; +export { IfdSShortValue } from './exif/ifd-value/ifd-sshort-value'; +export { IfdUndefinedValue } from './exif/ifd-value/ifd-undefined-value'; +export { IfdValue } from './exif/ifd-value/ifd-value'; export { ExifData } from './exif/exif-data'; export { ExifEntry } from './exif/exif-entry'; -export { ExifIFDContainer } from './exif/exif-ifd-container'; -export { ExifIFD } from './exif/exif-ifd'; export { ExifTag, ExifTagInitOptions, @@ -94,110 +113,340 @@ export { ExifInteropTags, ExifTagNameToID, } from './exif/exif-tag'; +export { IfdContainer } from './exif/ifd-container'; +export { IfdDirectory } from './exif/ifd-directory'; export { - ExifValueType, - ExifValueTypeSize, - ExifValueTypeString, - getExifValueTypeSize, - getExifValueTypeString, -} from './exif/exif-value-type'; + IfdValueType, + IfdValueTypeSize, + getIfdValueTypeSize, + getIfdValueTypeString, +} from './exif/ifd-value-type'; // Export types from 'filter' directory -export { AdjustColorOptions } from './filter/adjust-color-options'; -export { ColorOffsetOptions } from './filter/color-offset-options'; -export { ConvolutionOptions } from './filter/convolution-options'; -export { ImageFilter } from './filter/image-filter'; +export { DitherKernel, DitherKernels } from './filter/dither-kernel'; +export { + Filter, + AdjustColorOptions, + BillboardOptions, + BleachBypassOptions, + BulgeDistortionOptions, + BumpToNormalOptions, + ChromaticAberrationOptions, + ColorHalftone, + ColorOffsetOptions, + ContrastOptions, + ConvolutionOptions, + CopyImageChannelsOptions, + DitherImageOptions, + DotScreenOptions, + DropShadowOptions, + EdgeGlowOptions, + EmbossOptions, + GammaOptions, + GaussianBlurOptions, + GrayscaleOptions, + HdrToLdrOptions, + HexagonPixelateOptions, + InvertOptions, + LuminanceThresholdOptions, + MonochromeOptions, + NoiseOptions, + NormalizeOptions, + PixelateOptions, + QuantizeOptions, + ReinhardToneMapOptions, + RemapColorsOptions, + ScaleRgbaOptions, + SeparableConvolutionOptions, + SepiaOptions, + SketchOptions, + SmoothOptions, + SobelOptions, + StretchDistortionOptions, + VignetteOptions, +} from './filter/filter'; export { NoiseType } from './filter/noise-type'; export { PixelateMode } from './filter/pixelate-mode'; export { QuantizeMethod } from './filter/quantize-method'; -export { QuantizeOptions } from './filter/quantize-options'; -export { RemapColorsOptions } from './filter/remap-colors-options'; -export { SeparableKernel } from './filter/separable-kernel'; -export { VignetteOptions } from './filter/vignette-options'; +export { + SeparableKernel, + SeparableKernelApplyOptions, +} from './filter/separable-kernel'; // Export types from 'formats' directory -export { BmpDecoder } from './formats/bmp-decoder'; -export { BmpEncoder } from './formats/bmp-encoder'; -export { DecodeInfo } from './formats/decode-info'; -export { Decoder } from './formats/decoder'; -export { Encoder } from './formats/encoder'; -export { GifDecoder } from './formats/gif-decoder'; -export { GifEncoder, GifEncoderInitOptions } from './formats/gif-encoder'; -export { IcoDecoder } from './formats/ico-decoder'; -export { IcoEncoder } from './formats/ico-encoder'; -export { JpegDecoder } from './formats/jpeg-decoder'; -export { JpegEncoder } from './formats/jpeg-encoder'; -export { PngDecoder } from './formats/png-decoder'; -export { PngEncoder, PngEncoderInitOptions } from './formats/png-encoder'; -export { TgaDecoder } from './formats/tga-decoder'; -export { TgaEncoder } from './formats/tga-encoder'; -export { TiffDecoder } from './formats/tiff-decoder'; -export { TiffEncoder } from './formats/tiff-encoder'; - -export { BitmapCompressionMode } from './formats/bmp/bitmap-compression-mode'; -export { BitmapFileHeader } from './formats/bmp/bitmap-file-header'; +export { BmpCompressionMode } from './formats/bmp/bmp-compression-mode'; +export { BmpFileHeader } from './formats/bmp/bmp-file-header'; export { BmpInfo } from './formats/bmp/bmp-info'; -export { - GifColorMap, - GifColorMapInitOptions, -} from './formats/gif/gif-color-map'; +export { GifColorMap } from './formats/gif/gif-color-map'; export { GifImageDesc } from './formats/gif/gif-image-desc'; export { GifInfo, GifInfoInitOptions } from './formats/gif/gif-info'; export { IcoBmpInfo } from './formats/ico/ico-bmp-info'; -export { IcoInfoImage } from './formats/ico/ico-info-image'; +export { + IcoInfoImage, + IcoInfoImageInitOptions, +} from './formats/ico/ico-info-image'; export { IcoInfo } from './formats/ico/ico-info'; +export { IcoType, IcoTypeLength } from './formats/ico/ico-type'; -export { ComponentData } from './formats/jpeg/component-data'; +export { HuffmanNode } from './formats/jpeg/huffman-node'; +export { HuffmanParent } from './formats/jpeg/huffman-parent'; +export { HuffmanValue } from './formats/jpeg/huffman-value'; export { JpegAdobe } from './formats/jpeg/jpeg-adobe'; +export { JpegComponentData } from './formats/jpeg/jpeg-component-data'; export { JpegComponent } from './formats/jpeg/jpeg-component'; export { JpegData } from './formats/jpeg/jpeg-data'; export { JpegFrame } from './formats/jpeg/jpeg-frame'; export { JpegHuffman } from './formats/jpeg/jpeg-huffman'; export { JpegInfo } from './formats/jpeg/jpeg-info'; export { JpegJfif } from './formats/jpeg/jpeg-jfif'; +export { JpegMarker } from './formats/jpeg/jpeg-marker'; export { JpegQuantize } from './formats/jpeg/jpeg-quantize'; export { JpegScan } from './formats/jpeg/jpeg-scan'; -export { Jpeg } from './formats/jpeg/jpeg'; +export { JpegUtils } from './formats/jpeg/jpeg-utils'; +export { PngBlendMode } from './formats/png/png-blend-mode'; +export { PngColorType } from './formats/png/png-color-type'; +export { PngDisposeMode } from './formats/png/png-dispose-mode'; +export { PngFilterType } from './formats/png/png-filter-type'; export { PngFrame, PngFrameInitOptions } from './formats/png/png-frame'; export { PngInfo, PngInfoInitOptions } from './formats/png/png-info'; -export { TgaInfo } from './formats/tga/tga-info'; +export { TgaImageType, TgaImageTypeLength } from './formats/tga/tga-image-type'; +export { TgaInfo, TgaInfoInitOptions } from './formats/tga/tga-info'; export { TiffBitReader } from './formats/tiff/tiff-bit-reader'; +export { TiffCompression } from './formats/tiff/tiff-compression'; export { TiffEntry, TiffEntryInitOptions } from './formats/tiff/tiff-entry'; export { TiffFaxDecoder, TiffFaxDecoderInitOptions, } from './formats/tiff/tiff-fax-decoder'; +export { TiffFormat } from './formats/tiff/tiff-format'; +export { TiffImageType } from './formats/tiff/tiff-image-type'; export { TiffImage } from './formats/tiff/tiff-image'; export { TiffInfo, TiffInfoInitOptions } from './formats/tiff/tiff-info'; export { LzwDecoder } from './formats/tiff/tiff-lzw-decoder'; +export { + TiffPhotometricType, + TiffPhotometricTypeLength, +} from './formats/tiff/tiff-photometric-type'; -// Export types from 'hdr' directory -export { Half } from './hdr/half'; -export { HdrImage } from './hdr/hdr-image'; -export { HdrSlice, HdrSliceInitOptions } from './hdr/hdr-slice'; -export { HdrToImage } from './hdr/hdr-to-image'; +export { BmpDecoder } from './formats/bmp-decoder'; +export { BmpEncoder } from './formats/bmp-encoder'; +export { DecodeInfo } from './formats/decode-info'; +export { Decoder } from './formats/decoder'; +export { DibDecoder } from './formats/dib-decoder'; +export { Encoder } from './formats/encoder'; +export { GifDecoder } from './formats/gif-decoder'; +export { GifEncoder, GifEncoderInitOptions } from './formats/gif-encoder'; +export { IcoDecoder } from './formats/ico-decoder'; +export { IcoEncoder } from './formats/ico-encoder'; +export { JpegDecoder } from './formats/jpeg-decoder'; +export { JpegEncoder } from './formats/jpeg-encoder'; +export { PngDecoder } from './formats/png-decoder'; +export { PngEncoder, PngEncoderInitOptions } from './formats/png-encoder'; +export { TgaDecoder } from './formats/tga-decoder'; +export { TgaEncoder } from './formats/tga-encoder'; +export { TiffDecoder } from './formats/tiff-decoder'; +export { TiffEncoder } from './formats/tiff-encoder'; +export { WinEncoder } from './formats/win-encoder'; + +// Export types from 'image' directory +export { FrameType } from './image/frame-type'; +export { HeapNode } from './image/heap-node'; +export { IccProfile } from './image/icc-profile'; +export { IccProfileCompression } from './image/icc-profile-compression'; +export { MemoryImageDataFloat16 } from './image/image-data-float16'; +export { MemoryImageDataFloat32 } from './image/image-data-float32'; +export { MemoryImageDataFloat64 } from './image/image-data-float64'; +export { MemoryImageDataInt8 } from './image/image-data-int8'; +export { MemoryImageDataInt16 } from './image/image-data-int16'; +export { MemoryImageDataInt32 } from './image/image-data-int32'; +export { MemoryImageDataUint1 } from './image/image-data-uint1'; +export { MemoryImageDataUint2 } from './image/image-data-uint2'; +export { MemoryImageDataUint4 } from './image/image-data-uint4'; +export { MemoryImageDataUint8 } from './image/image-data-uint8'; +export { MemoryImageDataUint16 } from './image/image-data-uint16'; +export { MemoryImageDataUint32 } from './image/image-data-uint32'; +export { MemoryImageData } from './image/image-data'; +export { ImageUtils } from './image/image-utils'; +export { + MemoryImage, + MemoryImageCloneOptions, + MemoryImageColorExtremes, + MemoryImageConvertOptions, + MemoryImageCreateOptions, + MemoryImageFromBytesOptions, +} from './image/image'; +export { NeuralQuantizer } from './image/neural-quantizer'; +export { OctreeNode } from './image/octree-node'; +export { OctreeQuantizer } from './image/octree-quantizer'; +export { PaletteFloat16 } from './image/palette-float16'; +export { PaletteFloat32 } from './image/palette-float32'; +export { PaletteFloat64 } from './image/palette-float64'; +export { PaletteInt8 } from './image/palette-int8'; +export { PaletteInt16 } from './image/palette-int16'; +export { PaletteInt32 } from './image/palette-int32'; +export { PaletteUint8 } from './image/palette-uint8'; +export { PaletteUint16 } from './image/palette-uint16'; +export { PaletteUint32 } from './image/palette-uint32'; +export { Palette } from './image/palette'; +export { PixelFloat16 } from './image/pixel-float16'; +export { PixelFloat32 } from './image/pixel-float32'; +export { PixelFloat64 } from './image/pixel-float64'; +export { PixelInt8 } from './image/pixel-int8'; +export { PixelInt16 } from './image/pixel-int16'; +export { PixelInt32 } from './image/pixel-int32'; +export { PixelUint1 } from './image/pixel-uint1'; +export { PixelUint2 } from './image/pixel-uint2'; +export { PixelUint4 } from './image/pixel-uint4'; +export { PixelUint8 } from './image/pixel-uint8'; +export { PixelUint16 } from './image/pixel-uint16'; +export { PixelUint32 } from './image/pixel-uint32'; +export { PixelUndefined } from './image/pixel-undefined'; +export { PixelRangeIterator } from './image/pixel-range-iterator'; +export { Pixel, UndefinedPixel } from './image/pixel'; +export { QuantizerType } from './image/quantizer-type'; +export { Quantizer } from './image/quantizer'; // Export types from 'transform' directory -export { CopyIntoOptions } from './transform/copy-into-options'; +export { FlipDirection } from './transform/flip-direction'; export { + Transform, + CopyCropCircleOptions, + CopyCropOptions, + CopyRectifyOptions, + CopyResizeCropSquareOptions, CopyResizeOptionsUsingHeight, CopyResizeOptionsUsingWidth, -} from './transform/copy-resize-options'; -export { FlipDirection } from './transform/flip-direction'; -export { ImageTransform } from './transform/image-transform'; + CopyRotateOptions, + FlipOptions, + TransformOptions, + TrimOptions, +} from './transform/transform'; export { TrimMode } from './transform/trim-mode'; export { TrimSide } from './transform/trim-side'; -export { TrimTransform } from './transform/trim'; + +// In-place exports +export interface DecodeOptions { + data: TypedArray; +} + +export interface DecodeImageOptions extends DecodeOptions { + frame?: number; +} + +export interface DecodeNamedImageOptions extends DecodeImageOptions { + name: string; +} + +export interface EncodeOptions { + image: MemoryImage; +} + +export interface EncodeNamedImageOptions extends EncodeOptions { + name: string; +} + +export interface EncodeJpgOptions extends EncodeOptions { + quality?: number; +} + +export interface InjectJpgExifOptions extends DecodeOptions { + exifData: ExifData; +} + +export interface EncodeAnimatedOptions extends EncodeOptions { + singleFrame?: boolean; +} + +export interface EncodePngOptions extends EncodeAnimatedOptions { + level?: CompressionLevel; + filter?: PngFilterType; +} + +export interface EncodeGifOptions extends EncodeAnimatedOptions { + repeat?: number; + samplingFactor?: number; + dither?: DitherKernel; + ditherSerpentine?: boolean; +} + +export interface EncodeIcoImagesOptions { + images: MemoryImage[]; +} + +/** + * Return the Decoder that can decode image with the given **name**, + * by looking at the file extension. + */ +export function findDecoderForNamedImage(name: string): Decoder | undefined { + const n = name.toLowerCase(); + if (n.endsWith('.jpg') || n.endsWith('.jpeg')) { + return new JpegDecoder(); + } + if (n.endsWith('.png')) { + return new PngDecoder(); + } + if (n.endsWith('.tga')) { + return new TgaDecoder(); + } + if (n.endsWith('.gif')) { + return new GifDecoder(); + } + if (n.endsWith('.tif') || n.endsWith('.tiff')) { + return new TiffDecoder(); + } + if (n.endsWith('.bmp')) { + return new BmpDecoder(); + } + if (n.endsWith('.ico')) { + return new IcoDecoder(); + } + return undefined; +} /** - * Find a **Decoder** that is able to decode the given image **data**. - * Use this is you don't know the type of image it is. Since this will - * validate the image against all known decoders, it is potentially very slow. + * Return the Encoder that can decode image with the given **name**, + * by looking at the file extension. + */ +export function findEncoderForNamedImage(name: string): Encoder | undefined { + const n = name.toLowerCase(); + if (n.endsWith('.jpg') || n.endsWith('.jpeg')) { + return new JpegEncoder(); + } + if (n.endsWith('.png')) { + return new PngEncoder(); + } + if (n.endsWith('.tga')) { + return new TgaEncoder(); + } + if (n.endsWith('.gif')) { + return new GifEncoder(); + } + if (n.endsWith('.tif') || n.endsWith('.tiff')) { + return new TiffEncoder(); + } + if (n.endsWith('.bmp')) { + return new BmpEncoder(); + } + if (n.endsWith('.ico')) { + return new IcoEncoder(); + } + if (n.endsWith('.cur')) { + return new IcoEncoder(); + } + return undefined; +} + +/** + * Find a Decoder that is able to decode the given image **data**. + * Use this is you don't know the type of image it is. + * + * **WARNING:** Since this will check the image data against all known decoders, + * it is much slower than using an explicit decoder. */ export function findDecoderForData(data: TypedArray): Decoder | undefined { // The letious decoders will be creating a Uint8List for their InputStream @@ -245,215 +494,129 @@ export function findDecoderForData(data: TypedArray): Decoder | undefined { /** * Decode the given image file bytes by first identifying the format of the - * file and using that decoder to decode the file into a single frame [Image]. - */ -export function decodeImage(data: TypedArray): MemoryImage | undefined { - const decoder = findDecoderForData(data); - if (decoder === undefined) { - return undefined; - } - const dataUint8 = new Uint8Array(data); - return decoder.decodeImage(dataUint8); -} - -/** - * Decode the given image file bytes by first identifying the format of the - * file and using that decoder to decode the file into an **FrameAnimation** - * containing one or more **MemoryImage** frames. - */ -export function decodeAnimation(data: TypedArray): FrameAnimation | undefined { - const decoder = findDecoderForData(data); - if (decoder === undefined) { - return undefined; - } - const dataUint8 = new Uint8Array(data); - return decoder.decodeAnimation(dataUint8); -} - -/** - * Return the **Decoder** that can decode image with the given **name**, - * by looking at the file extension. See also **findDecoderForData** to - * determine the decoder to use given the bytes of the file. - */ -export function getDecoderForNamedImage(name: string): Decoder | undefined { - const n = name.toLowerCase(); - if (n.endsWith('.jpg') || n.endsWith('.jpeg')) { - return new JpegDecoder(); - } - if (n.endsWith('.png')) { - return new PngDecoder(); - } - if (n.endsWith('.tga')) { - return new TgaDecoder(); - } - if (n.endsWith('.gif')) { - return new GifDecoder(); - } - if (n.endsWith('.tif') || n.endsWith('.tiff')) { - return new TiffDecoder(); - } - if (n.endsWith('.bmp')) { - return new BmpDecoder(); - } - if (n.endsWith('.ico')) { - return new IcoDecoder(); - } - return undefined; -} - -/** - * Identify the format of the image using the file extension of the given - * **name**, and decode the given file **bytes** to an **FrameAnimation** with one or more - * **MemoryImage** frames. See also **decodeAnimation**. + * file and using that decoder to decode the file into a single frame MemoryImage. + * + * **WARNING:** Since this will check the image data against all known decoders, + * it is much slower than using an explicit decoder. */ -export function decodeNamedAnimation( - data: TypedArray, - name: string -): FrameAnimation | undefined { - const decoder = getDecoderForNamedImage(name); +export function decodeImage(opt: DecodeImageOptions): MemoryImage | undefined { + const decoder = findDecoderForData(opt.data); if (decoder === undefined) { return undefined; } - const dataUint8 = new Uint8Array(data); - return decoder.decodeAnimation(dataUint8); + const dataUint8 = new Uint8Array(opt.data); + return decoder.decode(dataUint8, opt.frame); } /** - * Identify the format of the image using the file extension of the given - * **name**, and decode the given file **data** to a single frame **MemoryImage**. See - * also **decodeImage**. + * Decodes the given image file bytes, using the filename extension to + * determine the decoder. */ export function decodeNamedImage( - data: TypedArray, - name: string + opt: DecodeNamedImageOptions ): MemoryImage | undefined { - const decoder = getDecoderForNamedImage(name); - if (decoder === undefined) { - return undefined; + const decoder = findDecoderForNamedImage(opt.name); + if (decoder !== undefined) { + const dataUint8 = new Uint8Array(opt.data); + return decoder.decode(dataUint8, opt.frame); } - const dataUint8 = new Uint8Array(data); - return decoder.decodeImage(dataUint8); + return decodeImage(opt); } /** - * Identify the format of the image and encode it with the appropriate - * **Encoder**. + * Encode the MemoryImage to the format determined by the file extension of **name**. + * If a format wasn't able to be identified, undefined will be returned. + * Otherwise the encoded format bytes of the image will be returned. */ export function encodeNamedImage( - image: MemoryImage, - name: string + opt: EncodeNamedImageOptions ): Uint8Array | undefined { - const n = name.toLowerCase(); - if (n.endsWith('.jpg') || n.endsWith('.jpeg')) { - return encodeJpg(image); - } - if (n.endsWith('.png')) { - return encodePng(image); - } - if (n.endsWith('.tga')) { - return encodeTga(image); - } - if (n.endsWith('.gif')) { - return encodeGif(image); - } - if (n.endsWith('.ico')) { - return encodeIco(image); - } - if (n.endsWith('.bmp')) { - return encodeBmp(image); + const encoder = findEncoderForNamedImage(opt.name); + if (encoder === undefined) { + return undefined; } - return undefined; + return encoder.encode(opt.image); } /** * Decode a JPG formatted image. */ -export function decodeJpg(data: TypedArray): MemoryImage | undefined { - const dataUint8 = new Uint8Array(data); - return new JpegDecoder().decodeImage(dataUint8); +export function decodeJpg(opt: DecodeOptions): MemoryImage | undefined { + const dataUint8 = new Uint8Array(opt.data); + return new JpegDecoder().decode(dataUint8); } /** * Encode an image to the JPEG format. */ -export function encodeJpg(image: MemoryImage, quality = 100): Uint8Array { - return new JpegEncoder(quality).encodeImage(image); +export function encodeJpg(opt: EncodeJpgOptions): Uint8Array { + const quality = opt.quality ?? 100; + return new JpegEncoder(quality).encode(opt.image); } /** - * Decode a PNG formatted image. + * Decode only the ExifData from a JPEG file, returning undefined if it was + * unable to. */ -export function decodePng(data: TypedArray): MemoryImage | undefined { - const dataUint8 = new Uint8Array(data); - return new PngDecoder().decodeImage(dataUint8); +export function decodeJpgExif(opt: DecodeOptions): ExifData | undefined { + const dataUint8 = new Uint8Array(opt.data); + return new JpegUtils().decodeExif(dataUint8); } /** - * Decode a PNG formatted animation. + * Inject ExifData into a JPEG file, replacing any existing EXIF data. + * The new JPEG file bytes will be returned, otherwise undefined if there was an + * issue. */ -export function decodePngAnimation( - data: TypedArray -): FrameAnimation | undefined { - const dataUint8 = new Uint8Array(data); - return new PngDecoder().decodeAnimation(dataUint8); +export function injectJpgExif( + opt: InjectJpgExifOptions +): Uint8Array | undefined { + const dataUint8 = new Uint8Array(opt.data); + return new JpegUtils().injectExif(opt.exifData, dataUint8); } /** - * Encode an image to the PNG format. + * Decode a PNG formatted image. */ -export function encodePng( - image: MemoryImage, - level: CompressionLevel = 6 -): Uint8Array { - return new PngEncoder({ - level: level, - }).encodeImage(image); +export function decodePng(opt: DecodeImageOptions): MemoryImage | undefined { + const dataUint8 = new Uint8Array(opt.data); + return new PngDecoder().decode(dataUint8, opt.frame); } /** - * Encode an animation to the PNG format. + * Encode an image to the PNG format. */ -export function encodePngAnimation( - animation: FrameAnimation, - level: CompressionLevel = 6 -): Uint8Array | undefined { +export function encodePng(opt: EncodePngOptions): Uint8Array { + const singleFrame = opt.singleFrame ?? false; + const level = opt.level ?? 6; + const filter = opt.filter ?? PngFilterType.paeth; return new PngEncoder({ + filter: filter, level: level, - }).encodeAnimation(animation); + }).encode(opt.image, singleFrame); } /** * Decode a Targa formatted image. */ -export function decodeTga(data: TypedArray): MemoryImage | undefined { - const dataUint8 = new Uint8Array(data); - return new TgaDecoder().decodeImage(dataUint8); +export function decodeTga(opt: DecodeImageOptions): MemoryImage | undefined { + const dataUint8 = new Uint8Array(opt.data); + return new TgaDecoder().decode(dataUint8, opt.frame); } /** * Encode an image to the Targa format. */ -export function encodeTga(image: MemoryImage): Uint8Array { - return new TgaEncoder().encodeImage(image); +export function encodeTga(opt: EncodeOptions): Uint8Array { + return new TgaEncoder().encode(opt.image); } /** * Decode a GIF formatted image (first frame for animations). */ -export function decodeGif(data: TypedArray): MemoryImage | undefined { - const dataUint8 = new Uint8Array(data); - return new GifDecoder().decodeImage(dataUint8); -} - -/** - * Decode an animated GIF file. If the GIF isn't animated, the animation - * will contain a single frame with the GIF's image. - */ -export function decodeGifAnimation( - data: TypedArray -): FrameAnimation | undefined { - const dataUint8 = new Uint8Array(data); - return new GifDecoder().decodeAnimation(dataUint8); +export function decodeGif(opt: DecodeImageOptions): MemoryImage | undefined { + const dataUint8 = new Uint8Array(opt.data); + return new GifDecoder().decode(dataUint8, opt.frame); } /** @@ -468,97 +631,70 @@ export function decodeGifAnimation( * If you know that you have less than 256 colors in your frames * anyway, you should supply a very large **samplingFactor** for maximum performance. */ -export function encodeGif(image: MemoryImage, samplingFactor = 10): Uint8Array { +export function encodeGif(opt: EncodeGifOptions): Uint8Array { + const singleFrame = opt.singleFrame ?? false; + const repeat = opt.repeat ?? 0; + const samplingFactor = opt.samplingFactor ?? 10; + const dither = opt.dither ?? DitherKernel.floydSteinberg; + const ditherSerpentine = opt.ditherSerpentine ?? false; return new GifEncoder({ + repeat: repeat, samplingFactor: samplingFactor, - }).encodeImage(image); -} - -/** - * Encode an animation to the GIF format. - * - * The **samplingFactor** specifies the sampling factor for - * NeuQuant image quantization. It is responsible for reducing - * the amount of unique colors in your images to 256. - * According to https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/, - * a sampling factor of 10 gives you a reasonable trade-off between - * image quality and quantization speed. - * If you know that you have less than 256 colors in your frames - * anyway, you should supply a very large **samplingFactor** for maximum performance. - * - * Here, `30` is used a default value for the **samplingFactor** as - * encoding animations is usually a process that takes longer than - * encoding a single image (see **encodeGif**). - */ -export function encodeGifAnimation( - animation: FrameAnimation, - samplingFactor = 10 -): Uint8Array | undefined { - return new GifEncoder({ - samplingFactor: samplingFactor, - }).encodeAnimation(animation); + dither: dither, + ditherSerpentine: ditherSerpentine, + }).encode(opt.image, singleFrame); } /** * Decode a TIFF formatted image. */ -export function decodeTiff(data: TypedArray): MemoryImage | undefined { - const dataUint8 = new Uint8Array(data); - return new TiffDecoder().decodeImage(dataUint8); -} - -/** - * Decode an multi-image (animated) TIFF file. If the tiff doesn't have - * multiple images, the animation will contain a single frame with the tiff's - * image. - */ -export function decodeTiffAnimation( - data: TypedArray -): FrameAnimation | undefined { - const dataUint8 = new Uint8Array(data); - return new TiffDecoder().decodeAnimation(dataUint8); +export function decodeTiff(opt: DecodeImageOptions): MemoryImage | undefined { + const dataUint8 = new Uint8Array(opt.data); + return new TiffDecoder().decode(dataUint8, opt.frame); } /** * Encode an image to the TIFF format. */ -export function encodeTiff(image: MemoryImage): Uint8Array { - return new TiffEncoder().encodeImage(image); +export function encodeTiff(opt: EncodeAnimatedOptions): Uint8Array { + const singleFrame = opt.singleFrame ?? false; + return new TiffEncoder().encode(opt.image, singleFrame); } /** * Decode a BMP formatted image. */ -export function decodeBmp(data: TypedArray): MemoryImage | undefined { - const dataUint8 = new Uint8Array(data); - return new BmpDecoder().decodeImage(dataUint8); +export function decodeBmp(opt: DecodeOptions): MemoryImage | undefined { + const dataUint8 = new Uint8Array(opt.data); + return new BmpDecoder().decode(dataUint8); } /** * Encode an image to the BMP format. */ -export function encodeBmp(image: MemoryImage): Uint8Array { - return new BmpEncoder().encodeImage(image); +export function encodeBmp(opt: EncodeOptions): Uint8Array { + return new BmpEncoder().encode(opt.image); } /** - * Encode an image to the ICO format. + * Decode an ICO image. */ -export function encodeIco(image: MemoryImage): Uint8Array { - return new IcoEncoder().encodeImage(image); +export function decodeIco(opt: DecodeImageOptions): MemoryImage | undefined { + const dataUint8 = new Uint8Array(opt.data); + return new IcoDecoder().decode(dataUint8, opt.frame); } /** - * Encode a list of images to the ICO format. + * Encode an image to the ICO format. */ -export function encodeIcoImages(images: MemoryImage[]): Uint8Array { - return new IcoEncoder().encodeImages(images); +export function encodeIco(opt: EncodeAnimatedOptions): Uint8Array { + const singleFrame = opt.singleFrame ?? false; + return new IcoEncoder().encode(opt.image, singleFrame); } /** - * Decode an ICO image. + * Encode a list of images to the ICO format. */ -export function decodeIco(data: TypedArray): MemoryImage | undefined { - const dataUint8 = new Uint8Array(data); - return new IcoDecoder().decodeImage(dataUint8); +export function encodeIcoImages(opt: EncodeIcoImagesOptions): Uint8Array { + return new IcoEncoder().encodeImages(opt.images); } diff --git a/src/transform/copy-into-options.ts b/src/transform/copy-into-options.ts deleted file mode 100644 index 4e1dead..0000000 --- a/src/transform/copy-into-options.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** @format */ - -import { MemoryImage } from '../common/memory-image'; - -export interface CopyIntoOptions { - dst: MemoryImage; - src: MemoryImage; - dstX?: number; - dstY?: number; - srcX?: number; - srcY?: number; - srcW?: number; - srcH?: number; - blend?: boolean; - center?: boolean; -} diff --git a/src/transform/copy-resize-options.ts b/src/transform/copy-resize-options.ts deleted file mode 100644 index 896a9af..0000000 --- a/src/transform/copy-resize-options.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** @format */ - -import { Interpolation } from '../common/interpolation'; -import { MemoryImage } from '../common/memory-image'; - -export interface CopyResizeOptionsUsingWidth { - image: MemoryImage; - width: number; - height?: number; - interpolation?: Interpolation; -} - -export interface CopyResizeOptionsUsingHeight { - image: MemoryImage; - height: number; - width?: number; - interpolation?: Interpolation; -} diff --git a/src/transform/image-transform.ts b/src/transform/image-transform.ts deleted file mode 100644 index 6b71ec5..0000000 --- a/src/transform/image-transform.ts +++ /dev/null @@ -1,578 +0,0 @@ -/** @format */ - -import { MemoryImage } from '../common/memory-image'; -import { RgbChannelSet } from '../common/rgb-channel-set'; -import { ImageError } from '../error/image-error'; -import { Point } from '../common/point'; -import { Rectangle } from '../common/rectangle'; -import { FlipDirection } from './flip-direction'; -import { - CopyResizeOptionsUsingHeight, - CopyResizeOptionsUsingWidth, -} from './copy-resize-options'; -import { CopyIntoOptions } from './copy-into-options'; -import { Draw } from '../draw/draw'; -import { Interpolation } from '../common/interpolation'; -import { Color } from '../common/color'; -import { MathOperators } from '../common/math-operators'; -import { ExifData } from '../exif/exif-data'; - -export abstract class ImageTransform { - /** - * Returns a copy of the **src** image, rotated by **angle** degrees. - */ - public static copyRotate( - src: MemoryImage, - angle: number, - interpolation: Interpolation = Interpolation.nearest - ): MemoryImage { - const nangle: number = angle % 360.0; - - // Optimized version for orthogonal angles. - if (nangle % 90 === 0) { - const wm1 = src.width - 1; - const hm1 = src.height - 1; - - const iangle = Math.floor(nangle / 90.0); - switch (iangle) { - case 1: { - // 90 deg. - const dst = new MemoryImage({ - width: src.height, - height: src.width, - rgbChannelSet: src.rgbChannelSet, - exifData: src.exifData, - iccProfile: src.iccProfile, - }); - for (let y = 0; y < dst.height; ++y) { - for (let x = 0; x < dst.width; ++x) { - dst.setPixel(x, y, src.getPixel(y, hm1 - x)); - } - } - return dst; - } - case 2: { - // 180 deg. - const dst = new MemoryImage({ - width: src.width, - height: src.height, - rgbChannelSet: src.rgbChannelSet, - exifData: src.exifData, - iccProfile: src.iccProfile, - }); - for (let y = 0; y < dst.height; ++y) { - for (let x = 0; x < dst.width; ++x) { - dst.setPixel(x, y, src.getPixel(wm1 - x, hm1 - y)); - } - } - return dst; - } - case 3: { - // 270 deg. - const dst = new MemoryImage({ - width: src.height, - height: src.width, - rgbChannelSet: src.rgbChannelSet, - exifData: src.exifData, - iccProfile: src.iccProfile, - }); - for (let y = 0; y < dst.height; ++y) { - for (let x = 0; x < dst.width; ++x) { - dst.setPixel(x, y, src.getPixel(wm1 - y, x)); - } - } - return dst; - } - default: { - // 0 deg. - return MemoryImage.from(src); - } - } - } - - // Generic angle. - const rad = (nangle * Math.PI) / 180.0; - const ca = Math.cos(rad); - const sa = Math.sin(rad); - const ux = Math.abs(src.width * ca); - const uy = Math.abs(src.width * sa); - const vx = Math.abs(src.height * sa); - const vy = Math.abs(src.height * ca); - const w2 = 0.5 * src.width; - const h2 = 0.5 * src.height; - const dw2 = 0.5 * (ux + vx); - const dh2 = 0.5 * (uy + vy); - - const dst = new MemoryImage({ - width: Math.trunc(ux + vx), - height: Math.trunc(uy + vy), - rgbChannelSet: RgbChannelSet.rgba, - exifData: src.exifData, - iccProfile: src.iccProfile, - }); - - for (let y = 0; y < dst.height; ++y) { - for (let x = 0; x < dst.width; ++x) { - const c = src.getPixelInterpolate( - w2 + (x - dw2) * ca + (y - dh2) * sa, - h2 - (x - dw2) * sa + (y - dh2) * ca, - interpolation - ); - dst.setPixel(x, y, c); - } - } - - return dst; - } - - /** - * If **image** has an orientation value in its exif data, this will rotate the - * image so that it physically matches its orientation. This can be used to - * bake the orientation of the image for image formats that don't support exif - * data. - */ - public static bakeOrientation(image: MemoryImage): MemoryImage { - const bakedImage = MemoryImage.from(image); - if ( - !image.exifData.imageIfd.hasOrientation || - image.exifData.imageIfd.orientation === 1 - ) { - return bakedImage; - } - - // Copy all exif data except for orientation - bakedImage.exifData = ExifData.from(image.exifData); - bakedImage.exifData.imageIfd.orientation = undefined; - - switch (image.exifData.imageIfd.orientation) { - case 2: - return ImageTransform.flipHorizontal(bakedImage); - case 3: - return ImageTransform.flip(bakedImage, FlipDirection.both); - case 4: { - const rotated = ImageTransform.copyRotate(bakedImage, 180); - return ImageTransform.flipHorizontal(rotated); - } - case 5: { - const rotated = ImageTransform.copyRotate(bakedImage, 90); - return ImageTransform.flipHorizontal(rotated); - } - case 6: - return ImageTransform.copyRotate(bakedImage, 90); - case 7: { - const rotated = ImageTransform.copyRotate(bakedImage, -90); - return ImageTransform.flipHorizontal(rotated); - } - case 8: - return ImageTransform.copyRotate(bakedImage, -90); - } - return bakedImage; - } - - /** - * Returns a resized copy of the **src** image. - * If **height** isn't specified, then it will be determined by the aspect - * ratio of **src** and **width**. - * If **width** isn't specified, then it will be determined by the aspect ratio - * of **src** and **height**. - */ - public static copyResize( - options: CopyResizeOptionsUsingWidth | CopyResizeOptionsUsingHeight - ): MemoryImage { - options.interpolation ??= Interpolation.nearest; - options.width ??= 0; - options.height ??= 0; - - if (options.width === 0 && options.height === 0) { - throw new ImageError('CopyResize: wrong size'); - } - - const src = ImageTransform.bakeOrientation(options.image); - - if (options.height === 0) { - options.height = Math.trunc(options.width * (src.height / src.width)); - } - - if (options.width === 0) { - options.width = Math.trunc(options.height * (src.width / src.height)); - } - - if (options.width === src.width && options.height === src.height) { - return src.clone(); - } - - const dst = new MemoryImage({ - width: options.width, - height: options.height, - rgbChannelSet: src.rgbChannelSet, - exifData: src.exifData, - iccProfile: src.iccProfile, - }); - - const dy = src.height / options.height; - const dx = src.width / options.width; - - if (options.interpolation === Interpolation.average) { - const sData = src.getBytes(); - const sw4 = src.width * 4; - - for (let y = 0; y < options.height; ++y) { - const y1 = Math.trunc(y * dy); - let y2 = Math.trunc((y + 1) * dy); - if (y2 === y1) { - y2++; - } - - for (let x = 0; x < options.width; ++x) { - const x1 = Math.trunc(x * dx); - let x2 = Math.trunc((x + 1) * dx); - if (x2 === x1) { - x2++; - } - - let r = 0; - let g = 0; - let b = 0; - let a = 0; - let np = 0; - for (let sy = y1; sy < y2; ++sy) { - let si = sy * sw4 + x1 * 4; - for (let sx = x1; sx < x2; ++sx, ++np) { - r += sData[si++]; - g += sData[si++]; - b += sData[si++]; - a += sData[si++]; - } - } - dst.setPixel( - x, - y, - Color.getColor( - Math.floor(r / np), - Math.floor(g / np), - Math.floor(b / np), - Math.floor(a / np) - ) - ); - } - } - } else if (options.interpolation === Interpolation.nearest) { - const scaleX = new Int32Array(options.width); - for (let x = 0; x < options.width; ++x) { - scaleX[x] = Math.trunc(x * dx); - } - for (let y = 0; y < options.height; ++y) { - const y2 = Math.trunc(y * dy); - for (let x = 0; x < options.width; ++x) { - dst.setPixel(x, y, src.getPixel(scaleX[x], y2)); - } - } - } else { - // Copy the pixels from this image to the new image. - for (let y = 0; y < options.height; ++y) { - const y2 = y * dy; - for (let x = 0; x < options.width; ++x) { - const x2 = x * dx; - dst.setPixel( - x, - y, - src.getPixelInterpolate(x2, y2, options.interpolation) - ); - } - } - } - - return dst; - } - - /** - * Returns a resized and square cropped copy of the **src** image of **size** size. - */ - public static copyResizeCropSquare( - src: MemoryImage, - size: number - ): MemoryImage { - if (size <= 0) { - throw new ImageError('Invalid size'); - } - - let height = size; - let width = size; - if (src.width < src.height) { - height = Math.trunc(size * (src.height / src.width)); - } else if (src.width > src.height) { - width = Math.trunc(size * (src.width / src.height)); - } - - const dst = new MemoryImage({ - width: size, - height: size, - rgbChannelSet: src.rgbChannelSet, - exifData: src.exifData, - iccProfile: src.iccProfile, - }); - - const dy = src.height / height; - const dx = src.width / width; - - const xOffset = Math.trunc((width - size) / 2); - const yOffset = Math.trunc((height - size) / 2); - - const scaleX = new Int32Array(size); - for (let x = 0; x < size; ++x) { - scaleX[x] = Math.trunc((x + xOffset) * dx); - } - - for (let y = 0; y < size; ++y) { - const y2 = Math.trunc((y + yOffset) * dy); - for (let x = 0; x < size; ++x) { - dst.setPixel(x, y, src.getPixel(scaleX[x], y2)); - } - } - - return dst; - } - - /** - * Copies a rectangular portion of one image to another image. **dst** is the - * destination image, **src** is the source image identifier. - * - * In other words, copyInto will take an rectangular area from **src** of - * width **srcW** and height **srcH** at position (**srcX**,**srcY**) and place it - * in a rectangular area of **dst** of width **dstW** and height **dstH** at - * position (**dstX**,**dstY**). - * - * If the source and destination coordinates and width and heights differ, - * appropriate stretching or shrinking of the image fragment will be performed. - * The coordinates refer to the upper left corner. This function can be used to - * copy regions within the same image (if **dst** is the same as **src**) - * but if the regions overlap the results will be unpredictable. - * - * **dstX** and **dstY** represent the X and Y position where the **src** will start - * printing. - * - * if **center** is true, the **src** will be centered in **dst**. - */ - public static copyInto(options: CopyIntoOptions): MemoryImage { - options.dstX ??= 0; - options.dstY ??= 0; - options.srcX ??= 0; - options.srcY ??= 0; - options.srcW ??= options.src.width; - options.srcH ??= options.src.height; - options.blend ??= true; - options.center ??= false; - - if (options.center) { - { - // If src is wider than dst - let wdt = options.dst.width - options.src.width; - if (wdt < 0) { - wdt = 0; - } - options.dstX = Math.floor(wdt / 2); - } - { - // If src is higher than dst - let hight = options.dst.height - options.src.height; - if (hight < 0) { - hight = 0; - } - options.dstY = Math.floor(hight / 2); - } - } - - if (options.blend) { - for (let y = 0; y < options.srcH; ++y) { - for (let x = 0; x < options.srcW; ++x) { - const pos = new Point(options.dstX + x, options.dstY + y); - Draw.drawPixel( - options.dst, - pos, - options.src.getPixel(options.srcX + x, options.srcY + y) - ); - } - } - } else { - for (let y = 0; y < options.srcH; ++y) { - for (let x = 0; x < options.srcW; ++x) { - options.dst.setPixel( - options.dstX + x, - options.dstY + y, - options.src.getPixel(options.srcX + x, options.srcY + y) - ); - } - } - } - - return options.dst; - } - - /** - * Returns a cropped copy of **src**. - */ - public static copyCrop( - src: MemoryImage, - x: number, - y: number, - w: number, - h: number - ): MemoryImage { - // Make sure crop rectangle is within the range of the src image. - const _x = MathOperators.clampInt(x, 0, src.width - 1); - const _y = MathOperators.clampInt(y, 0, src.height - 1); - let _w = w; - if (_x + _w > src.width) { - _w = src.width - _x; - } - let _h = h; - if (_y + _h > src.height) { - _h = src.height - _y; - } - - const dst = new MemoryImage({ - width: _w, - height: _h, - rgbChannelSet: src.rgbChannelSet, - exifData: src.exifData, - iccProfile: src.iccProfile, - }); - - for (let yi = 0, sy = _y; yi < _h; ++yi, ++sy) { - for (let xi = 0, sx = _x; xi < _w; ++xi, ++sx) { - dst.setPixel(xi, yi, src.getPixel(sx, sy)); - } - } - - return dst; - } - - /** - * Returns a round cropped copy of **src**. - */ - public static copyCropCircle( - src: MemoryImage, - radius?: number, - center?: Point - ): MemoryImage { - const defaultRadius = Math.trunc(Math.min(src.width, src.height) / 2); - const c = - center ?? - new Point(Math.trunc(src.width / 2), Math.trunc(src.height / 2)); - let r = radius ?? defaultRadius; - - // Make sure center point is within the range of the src image - c.move( - MathOperators.clampInt(c.x, 0, src.width - 1), - MathOperators.clampInt(c.y, 0, src.height - 1) - ); - r = r < 1 ? defaultRadius : r; - - // topLeft.x - const tlx = Math.trunc(c.x) - r; - // topLeft.y - const tly = Math.trunc(c.y) - r; - - const dst = new MemoryImage({ - width: r * 2, - height: r * 2, - iccProfile: src.iccProfile, - }); - - for (let yi = 0, sy = tly; yi < r * 2; ++yi, ++sy) { - for (let xi = 0, sx = tlx; xi < r * 2; ++xi, ++sx) { - if ((xi - r) * (xi - r) + (yi - r) * (yi - r) <= r * r) { - dst.setPixel(xi, yi, src.getPixelSafe(sx, sy)); - } - } - } - - return dst; - } - - /** - * Returns a copy of the **src** image, where the given rectangle - * has been mapped to the full image. - */ - public static copyRectify( - src: MemoryImage, - rect: Rectangle, - toImage?: MemoryImage - ): MemoryImage { - const dst = toImage ?? MemoryImage.from(src); - for (let y = 0; y < dst.height; ++y) { - const v = y / (dst.height - 1); - for (let x = 0; x < dst.width; ++x) { - const u = x / (dst.width - 1); - // bilinear interpolation - const srcPixelCoord = new Point(rect.left, rect.top) - .mul(1 - u) - .mul(1 - v) - .add(new Point(rect.right, rect.top).mul(u).mul(1 - v)) - .add(new Point(rect.left, rect.bottom).mul(1 - u).mul(v)) - .add(new Point(rect.right, rect.bottom).mul(u).mul(v)); - const srcPixel = src.getPixel(srcPixelCoord.xt, srcPixelCoord.yt); - dst.setPixel(x, y, srcPixel); - } - } - return dst; - } - - /** - * Flips the **src** image using the given **mode**, which can be one of: - * **FlipDirection.horizontal**, **FlipDirection.vertical**, or **FlipDirection.both**. - */ - public static flip(src: MemoryImage, direction: FlipDirection): MemoryImage { - switch (direction) { - case FlipDirection.horizontal: - ImageTransform.flipHorizontal(src); - break; - case FlipDirection.vertical: - ImageTransform.flipVertical(src); - break; - case FlipDirection.both: - ImageTransform.flipVertical(src); - ImageTransform.flipHorizontal(src); - break; - } - return src; - } - - /** - * Flip the **src** image vertically. - */ - public static flipVertical(src: MemoryImage): MemoryImage { - const w = src.width; - const h = src.height; - const h2 = Math.floor(h / 2); - for (let y = 0; y < h2; ++y) { - const y1 = y * w; - const y2 = (h - 1 - y) * w; - for (let x = 0; x < w; ++x) { - const t = src.getPixelByIndex(y2 + x); - src.setPixelByIndex(y2 + x, src.getPixelByIndex(y1 + x)); - src.setPixelByIndex(y1 + x, t); - } - } - return src; - } - - /** - * Flip the src image horizontally. - */ - public static flipHorizontal(src: MemoryImage): MemoryImage { - const w = src.width; - const h = src.height; - const w2 = Math.floor(src.width / 2); - for (let y = 0; y < h; ++y) { - const y1 = y * w; - for (let x = 0; x < w2; ++x) { - const x2 = w - 1 - x; - const t = src.getPixelByIndex(y1 + x2); - src.setPixelByIndex(y1 + x2, src.getPixelByIndex(y1 + x)); - src.setPixelByIndex(y1 + x, t); - } - } - return src; - } -} diff --git a/src/transform/transform.ts b/src/transform/transform.ts new file mode 100644 index 0000000..b99fa07 --- /dev/null +++ b/src/transform/transform.ts @@ -0,0 +1,1061 @@ +/** @format */ + +import { LibError } from '../error/lib-error'; +import { Point } from '../common/point'; +import { Interpolation } from '../common/interpolation'; +import { MathUtils } from '../common/math-utils'; +import { ExifData } from '../exif/exif-data'; +import { MemoryImage } from '../image/image'; +import { ImageUtils } from '../image/image-utils'; +import { Pixel } from '../image/pixel'; +import { FlipDirection } from './flip-direction'; +import { TrimSide } from './trim-side'; +import { Rectangle } from '../common/rectangle'; +import { Draw } from '../draw/draw'; +import { BlendMode } from '../draw/blend-mode'; +import { TrimMode } from './trim-mode'; + +export interface TransformOptions { + image: MemoryImage; +} + +export interface CopyCropCircleOptions extends TransformOptions { + radius?: number; + center?: Point; + antialias?: boolean; +} + +export interface CopyCropOptions extends TransformOptions { + rect: Rectangle; + radius?: number; + antialias?: boolean; +} + +export interface CopyRectifyOptions extends TransformOptions { + topLeft: Point; + topRight: Point; + bottomLeft: Point; + bottomRight: Point; + interpolation?: Interpolation; + toImage?: MemoryImage; +} + +export interface CopyResizeCropSquareOptions extends TransformOptions { + size: number; + interpolation?: Interpolation; + radius?: number; + antialias?: boolean; +} + +export interface CopyResizeOptionsUsingWidth extends TransformOptions { + width: number; + height?: number; + interpolation?: Interpolation; +} + +export interface CopyResizeOptionsUsingHeight extends TransformOptions { + height: number; + width?: number; + interpolation?: Interpolation; +} + +export interface CopyRotateOptions extends TransformOptions { + angle: number; + interpolation?: Interpolation; +} + +export interface FlipOptions extends TransformOptions { + direction: FlipDirection; +} + +export interface TrimOptions extends TransformOptions { + mode?: TrimMode; + sides?: TrimSide; +} + +export abstract class Transform { + private static rotate90(src: MemoryImage) { + let firstFrame: MemoryImage | undefined = undefined; + for (const frame of src.frames) { + const dst: MemoryImage = + firstFrame?.addFrame() ?? + MemoryImage.fromResized(frame, frame.height, frame.width, true); + firstFrame ??= dst; + const hm1 = frame.height - 1; + for (let y = 0; y < dst.height; ++y) { + for (let x = 0; x < dst.width; ++x) { + dst.setPixel(x, y, frame.getPixel(y, hm1 - x)); + } + } + } + return firstFrame!; + } + + private static rotate180(src: MemoryImage) { + let firstFrame: MemoryImage | undefined = undefined; + for (const frame of src.frames) { + const wm1 = frame.width - 1; + const hm1 = frame.height - 1; + const dst: MemoryImage = + firstFrame?.addFrame() ?? MemoryImage.from(frame, true, true); + firstFrame ??= dst; + for (let y = 0; y < dst.height; ++y) { + for (let x = 0; x < dst.width; ++x) { + dst.setPixel(x, y, frame.getPixel(wm1 - x, hm1 - y)); + } + } + } + return firstFrame!; + } + + private static rotate270(src: MemoryImage) { + let firstFrame: MemoryImage | undefined = undefined; + for (const frame of src.frames) { + const wm1 = src.width - 1; + const dst: MemoryImage = + firstFrame?.addFrame() ?? + MemoryImage.fromResized(frame, frame.height, frame.width, true); + firstFrame ??= dst; + for (let y = 0; y < dst.height; ++y) { + for (let x = 0; x < dst.width; ++x) { + dst.setPixel(x, y, frame.getPixel(wm1 - y, x)); + } + } + } + return firstFrame!; + } + + /** + * Find the crop area to be used by the trim function. + * + * Returns the Rectangle. You could pass these constraints + * to the **copyCrop** function to crop the image. + */ + private static findTrim(opt: TrimOptions): Rectangle { + const mode = opt.mode ?? TrimMode.transparent; + const sides = opt.sides ?? TrimSide.all; + + let h = opt.image.height; + let w = opt.image.width; + + const bg = + mode === TrimMode.topLeftColor + ? opt.image.getPixel(0, 0) + : mode === TrimMode.bottomRightColor + ? opt.image.getPixel(w - 1, h - 1) + : undefined; + + let xMin = w; + let xMax = 0; + let yMin: number | undefined = undefined; + let yMax = 0; + + for (let y = 0; y < h; ++y) { + let first = true; + for (let x = 0; x < w; ++x) { + const c = opt.image.getPixel(x, y); + if ( + (mode === TrimMode.transparent && c.a !== 0) || + (mode !== TrimMode.transparent && (bg === undefined || !c.equals(bg))) + ) { + if (xMin > x) { + xMin = x; + } + if (xMax < x) { + xMax = x; + } + yMin ??= y; + + yMax = y; + + if (first) { + x = xMax; + first = false; + } + } + } + } + + // A trim wasn't found + if (yMin === undefined) { + return new Rectangle(0, 0, w, h); + } + + if (!(sides & TrimSide.top)) { + yMin = 0; + } + if (!(sides & TrimSide.bottom)) { + yMax = h - 1; + } + if (!(sides & TrimSide.left)) { + xMin = 0; + } + if (!(sides & TrimSide.right)) { + xMax = w - 1; + } + + // Image width in pixels + w = 1 + xMax - xMin; + // Image height in pixels + h = 1 + yMax - yMin; + + return Rectangle.fromXYWH(xMin, yMin, w, h); + } + + /** + * If **image** has an orientation value in its exif data, this will rotate the + * image so that it physically matches its orientation. This can be used to + * bake the orientation of the image for image formats that don't support exif + * data. + */ + public static bakeOrientation(opt: TransformOptions): MemoryImage { + const bakedImage = MemoryImage.from(opt.image); + if ( + !opt.image.exifData.imageIfd.hasOrientation || + opt.image.exifData.imageIfd.orientation === 1 + ) { + return bakedImage; + } + + // Copy all exif data except for orientation + bakedImage.exifData = ExifData.from(opt.image.exifData); + bakedImage.exifData.imageIfd.orientation = undefined; + + switch (opt.image.exifData.imageIfd.orientation) { + case 2: + return Transform.flipHorizontal({ + image: bakedImage, + }); + case 3: + return Transform.flip({ + image: bakedImage, + direction: FlipDirection.both, + }); + case 4: { + const rotated = Transform.copyRotate({ + image: bakedImage, + angle: 180, + }); + return Transform.flipHorizontal({ + image: rotated, + }); + } + case 5: { + const rotated = Transform.copyRotate({ + image: bakedImage, + angle: 90, + }); + return Transform.flipHorizontal({ + image: rotated, + }); + } + case 6: + return Transform.copyRotate({ + image: bakedImage, + angle: 90, + }); + case 7: { + const rotated = Transform.copyRotate({ + image: bakedImage, + angle: -90, + }); + return Transform.flipHorizontal({ + image: rotated, + }); + } + case 8: + return Transform.copyRotate({ + image: bakedImage, + angle: -90, + }); + } + return bakedImage; + } + + /** + * Returns a cropped copy of **image**. + */ + public static copyCrop(opt: CopyCropOptions): MemoryImage { + let image = opt.image; + const radius = opt.radius ?? 0; + const antialias = opt.antialias ?? true; + + // Make sure crop rectangle is within the range of the src image. + const x = MathUtils.clampInt(opt.rect.left, 0, image.width - 1); + const y = MathUtils.clampInt(opt.rect.top, 0, image.height - 1); + + const width = + x + opt.rect.width > image.width ? image.width - x : opt.rect.width; + const height = + y + opt.rect.height > image.height ? image.height - y : opt.rect.height; + + if (radius > 0 && image.hasPalette) { + image = image.convert({ + numChannels: image.numChannels, + }); + } + + let firstFrame: MemoryImage | undefined = undefined; + const numFrames = image.numFrames; + for (let i = 0; i < numFrames; ++i) { + const frame = image.frames[i]; + const dst: MemoryImage = + firstFrame?.addFrame() ?? + MemoryImage.fromResized(frame, width, height, true); + firstFrame ??= dst; + + if (radius > 0) { + const rad = Math.round(radius); + const rad2 = rad * rad; + const x1 = x; + const y1 = y; + const x2 = x + width; + const y2 = y + height; + const c1x = x1 + rad - 1; + const c1y = y1 + rad - 1; + const c2x = x2 - rad + 1; + const c2y = y1 + rad - 1; + const c3x = x2 - rad + 1; + const c3y = y2 - rad + 1; + const c4x = x1 + rad - 1; + const c4y = y2 - rad + 1; + + const iter = image.getRange(x1, y1, width, height); + let iterRes: IteratorResult | undefined = undefined; + while (((iterRes = iter.next()), !iterRes.done)) { + const p = iterRes.value; + const px = p.x; + const py = p.y; + + let a = 1; + if (px < c1x && py < c1y) { + a = ImageUtils.circleTest(p, new Point(c1x, c1y), rad2, antialias); + if (a === 0) { + dst.setPixelRgba(p.x - x1, p.y - y1, 0, 0, 0, 0); + continue; + } + } else if (px > c2x && py < c2y) { + a = ImageUtils.circleTest(p, new Point(c2x, c2y), rad2, antialias); + if (a === 0) { + dst.setPixelRgba(p.x - x1, p.y - y1, 0, 0, 0, 0); + continue; + } + } else if (px > c3x && py > c3y) { + a = ImageUtils.circleTest(p, new Point(c3x, c3y), rad2, antialias); + if (a === 0) { + dst.setPixelRgba(p.x - x1, p.y - y1, 0, 0, 0, 0); + continue; + } + } else if (px < c4x && py > c4y) { + a = ImageUtils.circleTest(p, new Point(c4x, c4y), rad2, antialias); + if (a === 0) { + dst.setPixelRgba(p.x - x1, p.y - y1, 0, 0, 0, 0); + continue; + } + } + + if (a !== 1) { + dst.getPixel(p.x - x1, p.y - y1).setRgba(p.r, p.g, p.b, p.a * a); + } else { + dst.setPixel(p.x - x1, p.y - y1, p); + } + } + } else { + for (const p of dst) { + p.set(frame.getPixel(x + p.x, y + p.y)); + } + } + } + + return firstFrame!; + } + + /** + * Returns a circle cropped copy of **image**, centered at **centerX** and + * **centerY** and with the given **radius**. If **radius** is not provided, + * a radius filling the image will be used. If **centerX** is not provided, + * the horizontal mid-point of the image will be used. If **centerY** is not + * provided, the vertical mid-point of the image will be used. + */ + public static copyCropCircle(opt: CopyCropCircleOptions): MemoryImage { + let image = opt.image; + let centerX = opt.center?.x ?? Math.trunc(image.width / 2); + let centerY = opt.center?.y ?? Math.trunc(image.height / 2); + let radius = + opt.radius ?? Math.trunc(Math.min(image.width, image.height) / 2); + const antialias = opt.antialias ?? true; + + // Make sure center point is within the range of the src image + centerX = MathUtils.clamp(centerX, 0, image.width - 1); + centerY = MathUtils.clamp(centerY, 0, image.height - 1); + if (radius < 1) { + radius = Math.trunc(Math.min(image.width, image.height) / 2); + } + + // topLeft.x + const tlx = centerX - radius; + // topLeft.y + const tly = centerY - radius; + + const wh = radius * 2; + const radiusSqr = radius * radius; + + if (image.hasPalette) { + image = image.convert({ + numChannels: 4, + }); + } + + let firstFrame: MemoryImage | undefined = undefined; + const numFrames = image.numFrames; + for (let i = 0; i < numFrames; ++i) { + const frame = image.frames[i]; + const dst: MemoryImage = + firstFrame?.addFrame() ?? MemoryImage.fromResized(frame, wh, wh, true); + firstFrame ??= dst; + + const bg = frame.backgroundColor ?? image.backgroundColor; + if (bg !== undefined) { + dst.clear(bg); + } + + const dh = dst.height; + const dw = radius * 2; + for (let yi = 0, sy = tly; yi < dh; ++yi, ++sy) { + for (let xi = 0, sx = tlx; xi < dw; ++xi, ++sx) { + const p = frame.getPixel(sx, sy); + const a = ImageUtils.circleTest( + p, + new Point(centerX, centerY), + radiusSqr, + antialias + ); + + if (a !== 1) { + dst.getPixel(xi, yi).setRgba(p.r, p.g, p.b, p.a * a); + } else { + dst.setPixel(xi, yi, p); + } + } + } + } + + return firstFrame!; + } + + /** + * Returns a copy of the **image** image, flipped by the given **direction**. + */ + public static copyFlip(opt: FlipOptions): MemoryImage { + return Transform.flip({ + image: opt.image.clone(), + direction: opt.direction, + }); + } + + /** + * Returns a copy of the **image**, where the given rectangle + * has been mapped to the full image. + */ + public static copyRectify(opt: CopyRectifyOptions): MemoryImage { + const interpolation = opt.interpolation ?? Interpolation.nearest; + + // You can't interpolate index pixels, so we need to convert the image + // to a non-palette image if non-nearest interpolation is used. + const src = + interpolation !== Interpolation.nearest && opt.image.hasPalette + ? opt.image.convert({ + numChannels: opt.image.numChannels, + }) + : opt.image; + + let firstFrame: MemoryImage | undefined = undefined; + for (const frame of src.frames) { + const dst: MemoryImage = + firstFrame?.addFrame() ?? opt.toImage ?? MemoryImage.from(frame, true); + firstFrame ??= dst; + for (let y = 0; y < dst.height; ++y) { + const v = y / (dst.height - 1); + for (let x = 0; x < dst.width; ++x) { + const u = x / (dst.width - 1); + // bilinear interpolation + const srcPixelCoord = opt.topLeft + .mul((1 - u) * (1 - v)) + .add( + opt.topRight + .mul(u * (1 - v)) + .add( + opt.bottomLeft + .mul((1 - u) * v) + .add(opt.bottomRight.mul(u * v)) + ) + ); + + const srcPixel = + interpolation === Interpolation.nearest + ? frame.getPixel( + Math.trunc(srcPixelCoord.x), + Math.trunc(srcPixelCoord.y) + ) + : frame.getPixelInterpolate( + srcPixelCoord.x, + srcPixelCoord.y, + interpolation + ); + + dst.setPixel(x, y, srcPixel); + } + } + } + + return firstFrame!; + } + + /** + * Returns a resized copy of the **image**. + * + * If **height** isn't specified, then it will be determined by the aspect + * ratio of **image** and **width**. + * + * If **width** isn't specified, then it will be determined by the aspect ratio + * of **image** and **height**. + */ + public static copyResize( + opt: CopyResizeOptionsUsingWidth | CopyResizeOptionsUsingHeight + ): MemoryImage { + let src = opt.image; + let interpolation = opt.interpolation ?? Interpolation.nearest; + + if (opt.width === undefined && opt.height === undefined) { + throw new LibError('Invalid size. Please specify the width or height.'); + } + + // You can't interpolate index pixels + if (src.hasPalette) { + interpolation = Interpolation.nearest; + } + + if ( + src.exifData.imageIfd.hasOrientation && + src.exifData.imageIfd.orientation !== 1 + ) { + src = Transform.bakeOrientation({ + image: src, + }); + } + + // this block sets [width] and [height] if null or negative. + const height = + opt.height === undefined || opt.height <= 0 + ? Math.trunc(opt.width! * (src.height / src.width)) + : opt.height; + + const width = + opt.width === undefined || opt.width <= 0 + ? Math.trunc(opt.height! * (src.width / src.height)) + : opt.width; + + if (width === src.width && height === src.height) { + return src.clone(); + } + + const scaleX = new Int32Array(width); + const dx = src.width / width; + for (let x = 0; x < width; ++x) { + scaleX[x] = Math.trunc(x * dx); + } + + let firstFrame: MemoryImage | undefined = undefined; + const numFrames = src.numFrames; + for (let i = 0; i < numFrames; ++i) { + const frame = src.frames[i]; + const dst: MemoryImage = + firstFrame?.addFrame() ?? + MemoryImage.fromResized(frame, width, height, true); + firstFrame ??= dst; + + const dy = frame.height / height; + const dx = frame.width / width; + + if (interpolation === Interpolation.average) { + for (let y = 0; y < height; ++y) { + const y1 = Math.trunc(y * dy); + let y2 = Math.trunc((y + 1) * dy); + if (y2 === y1) { + y2++; + } + + for (let x = 0; x < width; ++x) { + const x1 = Math.trunc(x * dx); + let x2 = Math.trunc((x + 1) * dx); + if (x2 === x1) { + x2++; + } + + let r = 0; + let g = 0; + let b = 0; + let a = 0; + let np = 0; + for (let sy = y1; sy < y2; ++sy) { + for (let sx = x1; sx < x2; ++sx, ++np) { + const s = frame.getPixel(sx, sy); + r += s.r; + g += s.g; + b += s.b; + a += s.a; + } + } + dst.setPixel(x, y, dst.getColor(r / np, g / np, b / np, a / np)); + } + } + } else if (interpolation === Interpolation.nearest) { + for (let y = 0; y < height; ++y) { + const y2 = Math.trunc(y * dy); + for (let x = 0; x < width; ++x) { + dst.setPixel(x, y, frame.getPixel(scaleX[x], y2)); + } + } + } else { + // Copy the pixels from this image to the new image. + for (let y = 0; y < height; ++y) { + const y2 = y * dy; + for (let x = 0; x < width; ++x) { + const x2 = x * dx; + dst.setPixel( + x, + y, + frame.getPixelInterpolate(x2, y2, interpolation) + ); + } + } + } + } + + return firstFrame!; + } + + /** + * Returns a resized and square cropped copy of the **image** of **size** size. + */ + public static copyResizeCropSquare( + opt: CopyResizeCropSquareOptions + ): MemoryImage { + const src = opt.image; + let interpolation = opt.interpolation ?? Interpolation.nearest; + const radius = opt.radius ?? 0; + const antialias = opt.antialias ?? true; + + if (opt.size <= 0) { + throw new LibError('Invalid size.'); + } + + // You can't interpolate index pixels + if (src.hasPalette) { + interpolation = Interpolation.nearest; + } + + let height = opt.size; + let width = opt.size; + if (src.width < src.height) { + height = Math.trunc(opt.size * (src.height / src.width)); + } else if (src.width > src.height) { + width = Math.trunc(opt.size * (src.width / src.height)); + } + + const dy = src.height / height; + const dx = src.width / width; + + const xOffset = Math.trunc((width - opt.size) / 2); + const yOffset = Math.trunc((height - opt.size) / 2); + + const scaleX = + interpolation === Interpolation.nearest + ? new Int32Array(opt.size) + : undefined; + + if (scaleX !== undefined) { + for (let x = 0; x < opt.size; ++x) { + scaleX[x] = Math.trunc((x + xOffset) * dx); + } + } + + let firstFrame: MemoryImage | undefined = undefined; + for (const frame of src.frames) { + const dst: MemoryImage = + firstFrame?.addFrame() ?? + MemoryImage.fromResized(frame, opt.size, opt.size, true); + firstFrame ??= dst; + + // Rounded corners + if (radius > 0) { + const rad = Math.round(radius); + const rad2 = rad * rad; + const x1 = 0; + const y1 = 0; + const x2 = opt.size - 1; + const y2 = opt.size - 1; + const c1x = x1 + rad - 1; + const c1y = y1 + rad - 1; + const c2x = x2 - rad + 1; + const c2y = y1 + rad - 1; + const c3x = x2 - rad + 1; + const c3y = y2 - rad + 1; + const c4x = x1 + rad - 1; + const c4y = y2 - rad + 1; + + const iter = dst.getRange(x1, y1, width, height); + let iterRes: IteratorResult | undefined = undefined; + while (((iterRes = iter.next()), !iterRes.done)) { + const p = iterRes.value; + const px = p.x; + const py = p.y; + + let a = 1; + if (px < c1x && py < c1y) { + a = ImageUtils.circleTest(p, new Point(c1x, c1y), rad2, antialias); + if (a === 0) { + p.setRgba(0, 0, 0, 0); + continue; + } + } else if (px > c2x && py < c2y) { + a = ImageUtils.circleTest(p, new Point(c2x, c2y), rad2, antialias); + if (a === 0) { + p.setRgba(0, 0, 0, 0); + continue; + } + } else if (px > c3x && py > c3y) { + a = ImageUtils.circleTest(p, new Point(c3x, c3y), rad2, antialias); + if (a === 0) { + p.setRgba(0, 0, 0, 0); + continue; + } + } else if (px < c4x && py > c4y) { + a = ImageUtils.circleTest(p, new Point(c4x, c4y), rad2, antialias); + if (a === 0) { + p.setRgba(0, 0, 0, 0); + continue; + } + } + + if (interpolation === Interpolation.nearest) { + const sy = Math.trunc((p.y + yOffset) * dy); + const sp = frame.getPixel(scaleX![p.x], sy); + p.setRgba(sp.r, sp.g, sp.b, sp.a * a); + } else { + const x = p.x * dx; + const y = p.y * dy; + const sp = frame.getPixelInterpolate(x, y, interpolation); + const spa = sp.a * a; + p.setRgba(sp.r, sp.g, sp.b, spa); + } + } + + return dst; + } + + if (interpolation === Interpolation.nearest) { + for (let y = 0; y < opt.size; ++y) { + const y2 = Math.trunc((y + yOffset) * dy); + for (let x = 0; x < opt.size; ++x) { + dst.setPixel(x, y, frame.getPixel(scaleX![x], y2)); + } + } + } else { + for (const p of dst) { + const x = p.x * dx; + const y = p.y * dy; + p.set(frame.getPixelInterpolate(x, y, interpolation)); + } + } + } + + return firstFrame!; + } + + /** + * Returns a copy of the **image**, rotated by **angle** degrees. + */ + public static copyRotate(opt: CopyRotateOptions): MemoryImage { + const src = opt.image; + let interpolation = opt.interpolation ?? Interpolation.nearest; + + const nAngle = opt.angle % 360; + + // You can't interpolate index pixels + if (src.hasPalette) { + interpolation = Interpolation.nearest; + } + + // Optimized version for orthogonal angles. + if (nAngle % 90 === 0) { + const iAngle = Math.trunc(nAngle / 90); + switch (iAngle) { + case 1: + // 90 deg. + return Transform.rotate90(src); + case 2: + // 180 deg. + return Transform.rotate180(src); + case 3: + // 270 deg. + return Transform.rotate270(src); + default: + // 0 deg. + return MemoryImage.from(src); + } + } + + // Generic angle. + const rad = (nAngle * Math.PI) / 180; + const ca = Math.cos(rad); + const sa = Math.sin(rad); + const ux = Math.abs(src.width * ca); + const uy = Math.abs(src.width * sa); + const vx = Math.abs(src.height * sa); + const vy = Math.abs(src.height * ca); + const w2 = 0.5 * src.width; + const h2 = 0.5 * src.height; + const dw2 = 0.5 * (ux + vx); + const dh2 = 0.5 * (uy + vy); + + let firstFrame: MemoryImage | undefined = undefined; + const numFrames = src.numFrames; + for (let i = 0; i < numFrames; ++i) { + const frame = src.frames[i]; + const dst: MemoryImage = + firstFrame?.addFrame() ?? + MemoryImage.fromResized( + src, + Math.trunc(ux + vx), + Math.trunc(uy + vy), + true + ); + firstFrame ??= dst; + const bg = frame.backgroundColor ?? src.backgroundColor; + if (bg !== undefined) { + dst.clear(bg); + } + + for (const p of dst) { + const x = p.x; + const y = p.y; + const x2 = w2 + (x - dw2) * ca + (y - dh2) * sa; + const y2 = h2 - (x - dw2) * sa + (y - dh2) * ca; + if (frame.isBoundsSafe(x2, y2)) { + const c = frame.getPixelInterpolate(x2, y2, interpolation); + dst.setPixel(x, y, c); + } + } + } + + return firstFrame!; + } + + /** + * Flips the **image** using the given **direction**, which can be one of: + * _FlipDirection.horizontal_, _FlipDirection.vertical_ or _FlipDirection.both_. + */ + public static flip(opt: FlipOptions): MemoryImage { + switch (opt.direction) { + case FlipDirection.horizontal: + Transform.flipHorizontal(opt); + break; + case FlipDirection.vertical: + Transform.flipVertical(opt); + break; + case FlipDirection.both: + Transform.flipHorizontalVertical(opt); + break; + } + + return opt.image; + } + + /** + * Flips the **image** vertically. + */ + public static flipVertical(opt: TransformOptions): MemoryImage { + const numFrames = opt.image.numFrames; + for (let i = 0; i < numFrames; ++i) { + const frame = opt.image.frames[i]; + const w = frame.width; + const h = frame.height; + const h2 = Math.trunc(h / 2); + if (opt.image.hasPalette) { + for (let y = 0, y2 = h - 1; y < h2; ++y, --y2) { + for (let x = 0; x < w; ++x) { + const p1 = frame.getPixel(x, y); + const p2 = frame.getPixel(x, y2); + const t = p1.index; + p1.index = p2.index; + p2.index = t; + } + } + } else { + for (let y = 0, y2 = h - 1; y < h2; ++y, --y2) { + for (let x = 0; x < w; ++x) { + const p1 = frame.getPixel(x, y); + const p2 = frame.getPixel(x, y2); + let t = p1.r; + p1.r = p2.r; + p2.r = t; + + t = p1.g; + p1.g = p2.g; + p2.g = t; + + t = p1.b; + p1.b = p2.b; + p2.b = t; + + t = p1.a; + p1.a = p2.a; + p2.a = t; + } + } + } + } + return opt.image; + } + + /** + * Flips the **image** horizontally. + */ + public static flipHorizontal(opt: TransformOptions): MemoryImage { + const numFrames = opt.image.numFrames; + for (let i = 0; i < numFrames; ++i) { + const frame = opt.image.frames[i]; + const w = frame.width; + const h = frame.height; + const w2 = Math.trunc(w / 2); + if (opt.image.hasPalette) { + for (let y = 0; y < h; ++y) { + for (let x = 0, x2 = w - 1; x < w2; ++x, --x2) { + const p1 = frame.getPixel(x, y); + const p2 = frame.getPixel(x2, y); + const t = p1.index; + p1.index = p2.index; + p2.index = t; + } + } + } else { + for (let y = 0; y < h; ++y) { + for (let x = 0, x2 = w - 1; x < w2; ++x, --x2) { + const p1 = frame.getPixel(x, y); + const p2 = frame.getPixel(x2, y); + let t = p1.r; + p1.r = p2.r; + p2.r = t; + + t = p1.g; + p1.g = p2.g; + p2.g = t; + + t = p1.b; + p1.b = p2.b; + p2.b = t; + + t = p1.a; + p1.a = p2.a; + p2.a = t; + } + } + } + } + return opt.image; + } + + /** + * Flip the **image** horizontally and vertically. + */ + public static flipHorizontalVertical(opt: TransformOptions): MemoryImage { + const numFrames = opt.image.numFrames; + for (let i = 0; i < numFrames; ++i) { + const frame = opt.image.frames[i]; + const w = frame.width; + const h = frame.height; + const h2 = Math.trunc(h / 2); + if (frame.hasPalette) { + for (let y = 0, y2 = h - 1; y < h2; ++y, --y2) { + for (let x = 0, x2 = w - 1; x < w; ++x, --x2) { + const p1 = frame.getPixel(x, y); + const p2 = frame.getPixel(x2, y2); + const t = p1.index; + p1.index = p2.index; + p2.index = t; + } + } + } else { + for (let y = 0, y2 = h - 1; y < h2; ++y, --y2) { + for (let x = 0, x2 = w - 1; x < w; ++x, --x2) { + const p1 = frame.getPixel(x, y); + const p2 = frame.getPixel(x2, y2); + let t = p1.r; + p1.r = p2.r; + p2.r = t; + + t = p1.g; + p1.g = p2.g; + p2.g = t; + + t = p1.b; + p1.b = p2.b; + p2.b = t; + + t = p1.a; + p1.a = p2.a; + p2.a = t; + } + } + } + } + return opt.image; + } + + /** + * Automatically crops the image by finding the corners of the image that + * meet the **mode** criteria (not transparent or a different color). + * + * **mode** can be either _TrimMode.transparent_, _TrimMode.topLeftColor_ or + * _TrimMode.bottomRightColor_. + * + * **sides** can be used to control which sides of the image get trimmed, + * and can be any combination of _TrimSide.top_, _TrimSide.bottom_, _TrimSide.left_, + * and _TrimSide.right_. + */ + public static trim(opt: TrimOptions): MemoryImage { + const mode = opt.mode ?? TrimMode.topLeftColor; + const sides = opt.sides ?? TrimSide.all; + + if (mode === TrimMode.transparent && opt.image.numChannels === 3) { + return MemoryImage.from(opt.image); + } + + const crop = Transform.findTrim({ + image: opt.image, + mode: mode, + sides: sides, + }); + + let firstFrame: MemoryImage | undefined = undefined; + for (const frame of opt.image.frames) { + const dst: MemoryImage = + firstFrame?.addFrame() ?? + MemoryImage.fromResized(frame, crop.width, crop.height, true); + firstFrame ??= dst; + + Draw.compositeImage({ + dst: dst, + src: opt.image, + srcX: crop.left, + srcY: crop.top, + srcW: crop.width, + srcH: crop.height, + blend: BlendMode.direct, + }); + } + + return firstFrame!; + } +} diff --git a/src/transform/trim-mode.ts b/src/transform/trim-mode.ts index 804e02d..aeed214 100644 --- a/src/transform/trim-mode.ts +++ b/src/transform/trim-mode.ts @@ -5,16 +5,14 @@ export enum TrimMode { * Trim an image to the top-left and bottom-right most non-transparent pixels */ transparent, - /** - * Trim an image to the top-left and bottom-right most pixels that are not the - * same as the top-left most pixel of the image. + * Trim an image to the top-left and bottom-right most pixels that are not + * the same as the top-left most pixel of the image. */ topLeftColor, - /** - * Trim an image to the top-left and bottom-right most pixels that are not the - * same as the bottom-right most pixel of the image. + * Trim an image to the top-left and bottom-right most pixels that are not + * the same as the bottom-right most pixel of the image. */ bottomRightColor, } diff --git a/src/transform/trim-side.ts b/src/transform/trim-side.ts index e611a05..ebfebb0 100644 --- a/src/transform/trim-side.ts +++ b/src/transform/trim-side.ts @@ -1,41 +1,9 @@ /** @format */ -export class TrimSide { - /** - * Trim the image down from the top. - */ - public static readonly top = new TrimSide(1); - - /** - * Trim the image up from the bottom. - */ - public static readonly bottom = new TrimSide(2); - - /** - * Trim the left edge of the image. - */ - public static readonly left = new TrimSide(4); - - /** - * Trim the right edge of the image. - */ - public static readonly right = new TrimSide(8); - - /** - * Trim all edges of the image. - */ - public static readonly all = new TrimSide(1 | 2 | 4 | 8); - - private value: number; - - constructor(...sides: [number | TrimSide, ...(number | TrimSide)[]]) { - this.value = 0; - for (const s of sides) { - this.value |= typeof s === 'number' ? s : s.value; - } - } - - public has(side: TrimSide) { - return (this.value & side.value) !== 0; - } +export enum TrimSide { + top = 1, + bottom = 2, + left = 4, + right = 8, + all = top | bottom | left | right, } diff --git a/src/transform/trim.ts b/src/transform/trim.ts deleted file mode 100644 index 410a7ea..0000000 --- a/src/transform/trim.ts +++ /dev/null @@ -1,133 +0,0 @@ -/** @format */ - -import { MemoryImage } from '../common/memory-image'; -import { RgbChannelSet } from '../common/rgb-channel-set'; -import { Rectangle } from '../common/rectangle'; -import { TrimMode } from './trim-mode'; -import { TrimSide } from './trim-side'; -import { ImageTransform } from './image-transform'; -import { Color } from '../common/color'; - -export abstract class TrimTransform { - /** - * Find the crop area to be used by the trim function. - * Returns the Rectangle. You could pass these constraints - * to the **copyCrop** function to crop the image. - */ - private static findTrim( - src: MemoryImage, - mode: TrimMode = TrimMode.transparent, - sides: TrimSide = TrimSide.all - ) { - let h = src.height; - let w = src.width; - - const bg = - mode === TrimMode.topLeftColor - ? src.getPixel(0, 0) - : mode === TrimMode.bottomRightColor - ? src.getPixel(w - 1, h - 1) - : 0; - - let xmin = w; - let xmax = 0; - let ymin: number | undefined = undefined; - let ymax = 0; - - for (let y = 0; y < h; ++y) { - let first = true; - for (let x = 0; x < w; ++x) { - const c = src.getPixel(x, y); - if ( - (mode === TrimMode.transparent && Color.getAlpha(c) !== 0) || - (mode !== TrimMode.transparent && c !== bg) - ) { - if (xmin > x) { - xmin = x; - } - if (xmax < x) { - xmax = x; - } - ymin ??= y; - - ymax = y; - - if (first) { - x = xmax; - first = false; - } - } - } - } - - // A trim wasn't found - if (ymin === undefined) { - return new Rectangle(0, 0, w, h); - } - - if (!sides.has(TrimSide.top)) { - ymin = 0; - } - if (!sides.has(TrimSide.bottom)) { - ymax = h - 1; - } - if (!sides.has(TrimSide.left)) { - xmin = 0; - } - if (!sides.has(TrimSide.right)) { - xmax = w - 1; - } - - // Image width in pixels - w = 1 + xmax - xmin; - // Image height in pixels - h = 1 + ymax - ymin; - - return new Rectangle(xmin, ymin, w, h); - } - - /** - * Automatically crops the image by finding the corners of the image that - * meet the **mode** criteria (not transparent or a different color). - * - * **mode** can be either **TrimMode.transparent**, **TrimMode.topLeftColor** or - * **TrimMode.bottomRightColor**. - * - * **sides** can be used to control which sides of the image get trimmed, - * and can be any combination of **TrimSide.top**, **TrimSide.bottom**, **TrimSide.left**, - * and **TrimSide.right**. - */ - public static trim( - src: MemoryImage, - mode: TrimMode = TrimMode.transparent, - sides: TrimSide = TrimSide.all - ): MemoryImage { - if ( - mode === TrimMode.transparent && - src.rgbChannelSet === RgbChannelSet.rgb - ) { - return MemoryImage.from(src); - } - - const crop = TrimTransform.findTrim(src, mode, sides); - - const dst = new MemoryImage({ - width: crop.width, - height: crop.height, - exifData: src.exifData, - iccProfile: src.iccProfile, - }); - - ImageTransform.copyInto({ - dst: dst, - src: src, - srcX: crop.left, - srcY: crop.top, - srcW: crop.width, - srcH: crop.height, - blend: false, - }); - - return dst; - } -} diff --git a/test/_examples/create-thumbnail.ts b/test/_examples/create-thumbnail.ts new file mode 100644 index 0000000..be3a14d --- /dev/null +++ b/test/_examples/create-thumbnail.ts @@ -0,0 +1,35 @@ +/** @format */ + +import { readFileSync, writeFileSync } from 'fs'; +import { decodePng, encodeIco, Filter, Transform } from '../../src'; + +function createThumbnail() { + const input = readFileSync('test.png'); + + // decoding PNG bytes to MemoryImage + const image = decodePng({ + data: input, + }); + + if (image === undefined) return; + + // making resized thumbnail + const thumbnail = Transform.copyResize({ + image: image, + width: 150, + }); + + // applying vignette filter + Filter.vignette({ + image: thumbnail, + }); + + // encoding MemoryImage to ICO bytes + const output = encodeIco({ + image: thumbnail, + }); + + writeFileSync('thumbnail.ico', output); +} + +createThumbnail(); diff --git a/test/res/png/test_apng.png b/test/_input/apng/test_apng.png similarity index 100% rename from test/res/png/test_apng.png rename to test/_input/apng/test_apng.png diff --git a/test/res/png/test_apng2.png b/test/_input/apng/test_apng2.png similarity index 100% rename from test/res/png/test_apng2.png rename to test/_input/apng/test_apng2.png diff --git a/test/res/png/test_apng3.png b/test/_input/apng/test_apng3.png similarity index 100% rename from test/res/png/test_apng3.png rename to test/_input/apng/test_apng3.png diff --git a/test/res/ico/child.ico b/test/_input/bmp/alpha.bmp similarity index 52% rename from test/res/ico/child.ico rename to test/_input/bmp/alpha.bmp index cfcaf815cddacdc728583cfc5e0066bd1f0566c9..ce40bc3b160763b426e39a27a5be5fd9b40846cf 100644 GIT binary patch literal 73146 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 G@9+Z@ULw!{ literal 0 HcmV?d00001 diff --git a/test/res/bmp/buck_1.bmp b/test/_input/bmp/buck_1.bmp similarity index 100% rename from test/res/bmp/buck_1.bmp rename to test/_input/bmp/buck_1.bmp diff --git a/test/res/bmp/buck_24.bmp b/test/_input/bmp/buck_24.bmp similarity index 100% rename from test/res/bmp/buck_24.bmp rename to test/_input/bmp/buck_24.bmp diff --git a/test/res/bmp/buck_32.bmp b/test/_input/bmp/buck_32.bmp similarity index 100% rename from test/res/bmp/buck_32.bmp rename to test/_input/bmp/buck_32.bmp diff --git a/test/_input/bmp/buck_4.bmp b/test/_input/bmp/buck_4.bmp new file mode 100644 index 0000000000000000000000000000000000000000..47b50a65eb90fdedb97a1075e410e52a367fa082 GIT binary patch literal 28396 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 literal 0 HcmV?d00001 diff --git a/test/_input/bmp/buck_8.bmp b/test/_input/bmp/buck_8.bmp new file mode 100644 index 0000000000000000000000000000000000000000..38b6cee3cbb34296d11ac07bb17ff4e1dfae8d99 GIT binary patch literal 56876 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

(FrxQp8-7jjcJ@mc_{7uJLmHDi)n>+2 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 literal 0 HcmV?d00001 diff --git a/test/_input/bmp/rgba16.bmp b/test/_input/bmp/rgba16.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d9be4040cd96074f902ef04cdc0565e29e4ea67 GIT binary patch literal 131128 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 svZ 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 Uv}yl8{i|vJU;78QeikhFKSb=>QUCw| literal 0 HcmV?d00001 diff --git a/test/_input/bmp/rgba32.bmp b/test/_input/bmp/rgba32.bmp new file mode 100644 index 0000000000000000000000000000000000000000..512464388b19c7a91296217eebc57b843e4435a4 GIT binary patch literal 262282 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

~@b~c6r1y>7HAeG_QCj)jNUN>Aj8F;giUu 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

{Jy6NNO8!;yuabY2{Hx?&CI2eaVUs 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

    *L+w8xq{&ja}WM&E4F> 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 literal 0 HcmV?d00001 diff --git a/test/_input/gif/buck_24.gif b/test/_input/gif/buck_24.gif new file mode 100644 index 0000000000000000000000000000000000000000..5554b7878611e53d792924a24db59320192f550b GIT binary patch literal 39289 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 ~M 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 euD9fX6K)hk`s9yUiu?k8 z10_|E2qK~~GdH`@9=;55lyHgjMj7wN?OyiY%vw?RV_+}{(X$}` zkiRp}d#2#VM9RE@(KQaI zUnaWs7TXteX8N); ON)^VQz<8Ga>-ryC<7BY_ literal 0 HcmV?d00001 diff --git a/test/_input/ico/orf-favicon.ico b/test/_input/ico/orf-favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..5ac5042ec3956fbc49f5bf771a8d3c5f1348a4db GIT binary patch literal 22382 zcmeI4Pl#m29mlKF$&Qg-Tg26iafb-Wsw*rAn;e3(1WY^(tdNW3CW-_?gs2BWVR{u5 z%xEBxLx^h#K^a8|33v!G&?kjtjl1d+2*hp4Wx>Q96VX8@+xdKF-mkZ&rrvv1uV2s1 zGB$kYSFh^#zv@-htL}NubzIk7d8LESx*vSexg*ZG+1d5$CF-A}?=>x18R?mPRP zI|vU=NUYaGoP#g?j7B5p<15$y=?M5GI14^4pt9(~E=>pi}I1>YX()#meBuB=Wr)?}fF!B4?c z;A@@^`DXl-l9KC;+d(I8I&h3%7bS)^?oZ<%eY7cY=ZnZ9R?R}?aGT55#v=;PcT4z8|0lH11~R%=tlg)ljF0x%{j0hS z{m%6tN_6>ppEA9L&l(3&{l-_K^Nh6{h3{V_yuSTcjo&CTnx}l8wX)Z~sZBE0Zj`!d z*^lMtL$hlX`_syQ+4#HJY>Q%lTH~+m{(IcFU-*!F|7lH#^{;>bmCZl@M)s{o%|Sjt^&!7g(=Tn|Kyh zJA=8Eu4ISZ{*399ZrPBnHJb#abBd#&560&dst7()ihXsG9_A2vW z0CM9@<(F>R*zo+g-MPS@W8h7Y8pou3vUO|+#C-#Pyt0LHhk29j8@3}4*u58gyp6G2 zF66_#Ta^QB?FDV_p)HO{seIZy%{-ugKgjvsYtoo<<>lM{Y2*OC*MYx-T%Wd@Up`*f zW)9G&e!moAw_MBDR>lE(bieQ9F>f)4R6b8UAE2Y{x$ZnVUkBRfo+zNQ>gvvT!WiqW zE58@3yGQUxYh0a;l=e5!^J8!blHbPFWbctCwEGX_Z!e20w;o-0fOkR4Sc~zzl4BD)$0o4#GP3(}?4|Icvj?O*7GFwT z((?lPbq_YZ_nww~N<2+?3f~r?De;CpimBE&c;*}GUu+Un6B+zdp2PT3uIKCQp|{EN zyT)a0ZtHBPw#yc1axV<3Y@k!;HYs`Zc{DHes`O5y4V(Lb=2_pDlyd1g61sHGl%m7u zxg#e&^nV>Z0DcXA4}J@N2EGqUf9Dso0srm5_a&wLXiS&t&~-9XU-G(w-oxOJHTrc9 z`V)|x2Y9u|NQv8cPR8O#ht6qp&nlDlHt78k_zaj2byVYe!*`)EpNl@z9;r^B->w)p zohwtP^Jbr~uKZ@1Pkuc*wU@2a6>EPVxlO-4@^xDozBe*$+-b5#k=L1f%#X6V2Tit& zqVG2Fzf8Tpy)($pllv(0&Tl_tvN4J-tx<1f>h$$n`JtG8 zzYZIRGVQ$N%d3q1=?oouPOV(;X>T$&Tg*QFC%V26`s-iI7jPc?)M|n^N%9_Cg)$@vKUh+IcW3zOW%v6-0wb5)%jPG^G`jae>o-g zHhHkw1MfD7zx4c5{-JNsKxgfKxaHWjwzhu$UBo}%AbyRnN7{_BN*A^k8~T{?{fBa! zyPnwnHPsy8mwbD=VeE>j^329^4&SkcHk1cFhqXQ*pmQH+GUlyslD_}+a*(^Om>p5g ziCOD{*^Nj!*TYRM1t{R8y91~fJ_SLobI&z{QBd0>2P z&?SqbDaD_?VAuZst+)^NlY?FP`$ro$#J_8Q|LWyH<6tM>3-Ya%-@RJQAw|FDgSO|y zR^~eS7WzA_Yi#Yx|9|lFNe*`H|Gxxz(DQ2_=-F%@G&w&= ziCH|-EgMPCanp!1MJN8v0-dFu1Q$SRd?BA?r9-+Z&uvot+72H4*159I)_2YSzivmK zKeyTV|IA6)<6`2 zz9<4B(pXT$XND+1e1Y=Zs(AWtZbdQ!y(0k~L%k>AfLs{Up=_;6c44`9K~!%#a5Dop z>UT!Gs*yhwp?VX7s4Nt84%+2F8a0Z=d%3u{9j(rQP1MExGfK8 o?+x+T@-(J>$A=sZM9I-mlpI;!Q9xi9`^EZc+;7&8@_X~=|Fxe<#{d8T literal 0 HcmV?d00001 diff --git a/test/_input/ico/wikipedia-favicon.ico b/test/_input/ico/wikipedia-favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..e70021849bdf154b79a9eb6fd1621e5c51571d40 GIT binary patch literal 2734 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 a0(=Y*FChcsAOFNh{)vzL6Ce2}KJrg|{NqRV% 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