UNPKG

image-in-browser

Version:

Package for encoding / decoding images, transforming images, applying filters, drawing primitives on images on the client side (no need for server Node.js)

900 lines 37.7 kB
import { ChannelOrder, ChannelOrderLength } from '../color/channel-order.js'; import { ColorUint8 } from '../color/color-uint8.js'; import { ColorUtils } from '../color/color-utils.js'; import { Format, FormatMaxValue, FormatType, getRowStride, } from '../color/format.js'; import { ArrayUtils } from '../common/array-utils.js'; import { Interpolation } from '../common/interpolation.js'; import { MathUtils } from '../common/math-utils.js'; import { LibError } from '../error/lib-error.js'; import { ExifData } from '../exif/exif-data.js'; import { FrameType } from './frame-type.js'; import { MemoryImageDataFloat16 } from './image-data-float16.js'; import { MemoryImageDataFloat32 } from './image-data-float32.js'; import { MemoryImageDataFloat64 } from './image-data-float64.js'; import { MemoryImageDataInt16 } from './image-data-int16.js'; import { MemoryImageDataInt32 } from './image-data-int32.js'; import { MemoryImageDataInt8 } from './image-data-int8.js'; import { MemoryImageDataUint1 } from './image-data-uint1.js'; import { MemoryImageDataUint16 } from './image-data-uint16.js'; import { MemoryImageDataUint2 } from './image-data-uint2.js'; import { MemoryImageDataUint32 } from './image-data-uint32.js'; import { MemoryImageDataUint4 } from './image-data-uint4.js'; import { MemoryImageDataUint8 } from './image-data-uint8.js'; import { PaletteFloat16 } from './palette-float16.js'; import { PaletteFloat32 } from './palette-float32.js'; import { PaletteFloat64 } from './palette-float64.js'; import { PaletteInt16 } from './palette-int16.js'; import { PaletteInt32 } from './palette-int32.js'; import { PaletteInt8 } from './palette-int8.js'; import { PaletteUint16 } from './palette-uint16.js'; import { PaletteUint32 } from './palette-uint32.js'; import { PaletteUint8 } from './palette-uint8.js'; import { UndefinedPixel } from './pixel.js'; export class MemoryImage { get data() { return this._data; } get format() { var _a, _b; return (_b = (_a = this._data) === null || _a === void 0 ? void 0 : _a.format) !== null && _b !== void 0 ? _b : Format.uint8; } get hasPalette() { var _a; return ((_a = this._data) === null || _a === void 0 ? void 0 : _a.palette) !== undefined; } get palette() { var _a; return (_a = this._data) === null || _a === void 0 ? void 0 : _a.palette; } set palette(p) { if (this._data !== undefined) { this._data.palette = p; } } get numChannels() { var _a, _b, _c, _d; return (_d = (_b = (_a = this.palette) === null || _a === void 0 ? void 0 : _a.numChannels) !== null && _b !== void 0 ? _b : (_c = this._data) === null || _c === void 0 ? void 0 : _c.numChannels) !== null && _d !== void 0 ? _d : 0; } get hasAnimation() { return this._frames.length > 1; } get numFrames() { return this._frames.length; } get exifData() { var _a; (_a = this._exifData) !== null && _a !== void 0 ? _a : (this._exifData = new ExifData()); return this._exifData; } set exifData(exif) { this._exifData = exif; } get maxChannelValue() { var _a, _b; return (_b = (_a = this._data) === null || _a === void 0 ? void 0 : _a.maxChannelValue) !== null && _b !== void 0 ? _b : 0; } get maxIndexValue() { var _a, _b; return (_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a.maxIndexValue) !== null && _b !== void 0 ? _b : 0; } get supportsPalette() { return (this.format === Format.uint1 || this.format === Format.uint2 || this.format === Format.uint4 || this.format === Format.uint8 || this.format === Format.uint16); } get width() { var _a, _b; return (_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : 0; } get height() { var _a, _b; return (_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a.height) !== null && _b !== void 0 ? _b : 0; } get formatType() { var _a, _b; return (_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a.formatType) !== null && _b !== void 0 ? _b : FormatType.uint; } get isValid() { return this._data !== undefined && this.width > 0 && this.height > 0; } get buffer() { var _a; return (_a = this._data) === null || _a === void 0 ? void 0 : _a.buffer; } get byteLength() { var _a, _b; return (_b = (_a = this._data) === null || _a === void 0 ? void 0 : _a.buffer.byteLength) !== null && _b !== void 0 ? _b : 0; } get rowStride() { var _a, _b; return (_b = (_a = this._data) === null || _a === void 0 ? void 0 : _a.rowStride) !== null && _b !== void 0 ? _b : 0; } get isLdrFormat() { var _a, _b; return (_b = (_a = this._data) === null || _a === void 0 ? void 0 : _a.isLdrFormat) !== null && _b !== void 0 ? _b : false; } get isHdrFormat() { var _a, _b; return (_b = (_a = this._data) === null || _a === void 0 ? void 0 : _a.isHdrFormat) !== null && _b !== void 0 ? _b : false; } get bitsPerChannel() { var _a, _b; return (_b = (_a = this._data) === null || _a === void 0 ? void 0 : _a.bitsPerChannel) !== null && _b !== void 0 ? _b : 0; } get hasAlpha() { return this.numChannels === 2 || this.numChannels === 4; } get iccProfile() { return this._iccProfile; } set iccProfile(v) { this._iccProfile = v; } get textData() { return this._textData; } get backgroundColor() { return this._backgroundColor; } set backgroundColor(v) { this._backgroundColor = v; } get loopCount() { return this._loopCount; } set loopCount(v) { this._loopCount = v; } get frameType() { return this._frameType; } set frameType(v) { this._frameType = v; } get frames() { return this._frames; } get frameDuration() { return this._frameDuration; } set frameDuration(v) { this._frameDuration = v; } get frameIndex() { return this._frameIndex; } set frameIndex(v) { this._frameIndex = v; } constructor(opt) { var _a, _b, _c, _d, _e, _f, _g, _h; this._frames = []; if (opt !== undefined) { this._loopCount = (_a = opt.loopCount) !== null && _a !== void 0 ? _a : 0; this._frameType = (_b = opt.frameType) !== null && _b !== void 0 ? _b : FrameType.sequence; this._frameDuration = (_c = opt.frameDuration) !== null && _c !== void 0 ? _c : 0; this._frameIndex = (_d = opt.frameIndex) !== null && _d !== void 0 ? _d : 0; this._backgroundColor = opt.backgroundColor; this._textData = opt.textData; this._frames.push(this); this.initialize({ width: opt.width, height: opt.height, format: (_e = opt.format) !== null && _e !== void 0 ? _e : Format.uint8, numChannels: (_f = opt.numChannels) !== null && _f !== void 0 ? _f : 3, withPalette: (_g = opt.withPalette) !== null && _g !== void 0 ? _g : false, paletteFormat: (_h = opt.paletteFormat) !== null && _h !== void 0 ? _h : Format.uint8, palette: opt.palette, exifData: opt.exifData, iccProfile: opt.iccProfile, }); } else { this._loopCount = 0; this._frameType = FrameType.sequence; this._frameDuration = 0; this._frameIndex = 0; } } static getNumPixelColors(format) { return format === Format.uint1 ? 2 : format === Format.uint2 ? 4 : format === Format.uint4 ? 16 : format === Format.uint8 ? 256 : format === Format.uint16 ? 65536 : 0; } static fromResized(other, width, height, skipAnimation = false) { var _a, _b, _c, _d; const image = new MemoryImage({ width: width, height: height, loopCount: other._loopCount, frameType: other._frameType, frameDuration: other._frameDuration, frameIndex: other._frameIndex, backgroundColor: (_a = other._backgroundColor) === null || _a === void 0 ? void 0 : _a.clone(), format: other.format, numChannels: other.numChannels, withPalette: other.hasPalette, paletteFormat: (_b = other.palette) === null || _b === void 0 ? void 0 : _b.format, palette: other.palette, exifData: (_c = other._exifData) === null || _c === void 0 ? void 0 : _c.clone(), iccProfile: (_d = other._iccProfile) === null || _d === void 0 ? void 0 : _d.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; } static from(other, skipAnimation = false, skipPixels = false) { var _a, _b, _c, _d; const image = new MemoryImage(); image._data = (_a = other.data) === null || _a === void 0 ? void 0 : _a.clone(skipPixels); image._exifData = (_b = other._exifData) === null || _b === void 0 ? void 0 : _b.clone(); image._iccProfile = (_c = other.iccProfile) === null || _c === void 0 ? void 0 : _c.clone(); image._frameType = other.frameType; image._loopCount = other._loopCount; image._backgroundColor = (_d = other._backgroundColor) === null || _d === void 0 ? void 0 : _d.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; } static fromBytes(opt) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l; const byteOffset = (_a = opt.byteOffset) !== null && _a !== void 0 ? _a : 0; const image = new MemoryImage(); image._loopCount = (_b = opt.loopCount) !== null && _b !== void 0 ? _b : 0; image._frameType = (_c = opt.frameType) !== null && _c !== void 0 ? _c : FrameType.sequence; image._frameDuration = (_d = opt.frameDuration) !== null && _d !== void 0 ? _d : 0; image._frameIndex = (_e = opt.frameIndex) !== null && _e !== void 0 ? _e : 0; image._backgroundColor = opt.backgroundColor; image._textData = opt.textData; image._frames.push(image); const format = (_f = opt.format) !== null && _f !== void 0 ? _f : Format.uint8; const withPalette = (_g = opt.withPalette) !== null && _g !== void 0 ? _g : false; const paletteFormat = (_h = opt.paletteFormat) !== null && _h !== void 0 ? _h : Format.uint8; const numChannels = (_j = opt.numChannels) !== null && _j !== void 0 ? _j : (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 = (_k = opt.channelOrder) !== null && _k !== void 0 ? _k : (numChannels === 3 ? ChannelOrder.rgb : numChannels === 4 ? ChannelOrder.rgba : numChannels === 1 ? ChannelOrder.red : ChannelOrder.grayAlpha); if (numChannels === 1) { channelOrder = ChannelOrder.red; } else if (numChannels === 2) { channelOrder = ChannelOrder.grayAlpha; } else if (numChannels === 3) { if (channelOrder !== ChannelOrder.rgb && channelOrder !== ChannelOrder.bgr) { channelOrder = ChannelOrder.rgb; } } else if (numChannels === 4) { if (channelOrder !== ChannelOrder.bgra && channelOrder !== ChannelOrder.rgba && channelOrder !== ChannelOrder.abgr && channelOrder !== ChannelOrder.argb) { 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, byteOffset); const rowStride = (_l = opt.rowStride) !== null && _l !== void 0 ? _l : getRowStride(opt.width, numChannels, 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, toBytes, dOff, stride); } 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; } initialize(opt) { var _a, _b, _c, _d, _e; const format = (_a = opt.format) !== null && _a !== void 0 ? _a : Format.uint8; const numChannels = (_b = opt.numChannels) !== null && _b !== void 0 ? _b : 3; const withPalette = (_c = opt.withPalette) !== null && _c !== void 0 ? _c : false; const paletteFormat = (_d = opt.paletteFormat) !== null && _d !== void 0 ? _d : Format.uint8; this._iccProfile = opt.iccProfile; if (opt.exifData !== undefined) { this._exifData = opt.exifData.clone(); } const palette = (_e = opt.palette) !== null && _e !== void 0 ? _e : (withPalette && this.supportsPalette ? this.createPalette(format, paletteFormat, numChannels) : undefined); this.createImageData(opt.width, opt.height, format, numChannels, palette); } createImageData(width, height, format, numChannels, palette) { 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: if (palette === undefined) { this._data = new MemoryImageDataUint16(width, height, numChannels); } else { this._data = MemoryImageDataUint16.palette(width, height, palette); } 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; } } createPalette(format, paletteFormat, numChannels) { switch (paletteFormat) { case Format.uint1: return undefined; case Format.uint2: return undefined; case Format.uint4: return undefined; case Format.uint8: return new PaletteUint8(MemoryImage.getNumPixelColors(format), numChannels); case Format.uint16: return new PaletteUint16(MemoryImage.getNumPixelColors(format), numChannels); case Format.uint32: return new PaletteUint32(MemoryImage.getNumPixelColors(format), numChannels); case Format.int8: return new PaletteInt8(MemoryImage.getNumPixelColors(format), numChannels); case Format.int16: return new PaletteInt16(MemoryImage.getNumPixelColors(format), numChannels); case Format.int32: return new PaletteInt32(MemoryImage.getNumPixelColors(format), numChannels); case Format.float16: return new PaletteFloat16(MemoryImage.getNumPixelColors(format), numChannels); case Format.float32: return new PaletteFloat32(MemoryImage.getNumPixelColors(format), numChannels); case Format.float64: return new PaletteFloat64(MemoryImage.getNumPixelColors(format), numChannels); } throw new LibError('Unknown palette format.'); } addFrame(image) { const img = image !== null && image !== void 0 ? 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; } getFrame(index) { return this._frames[index]; } clone(opt) { var _a, _b; const skipAnimation = (_a = opt === null || opt === void 0 ? void 0 : opt.skipAnimation) !== null && _a !== void 0 ? _a : false; const skipPixels = (_b = opt === null || opt === void 0 ? void 0 : opt.skipPixels) !== null && _b !== void 0 ? _b : false; return MemoryImage.from(this, skipAnimation, skipPixels); } hasExtraChannel(name) { return this._extraChannels !== undefined && this._extraChannels.has(name); } getExtraChannel(name) { return this._extraChannels !== undefined ? this._extraChannels.get(name) : undefined; } setExtraChannel(name, data) { var _a; if (this._extraChannels === undefined && data === undefined) { return; } (_a = this._extraChannels) !== null && _a !== void 0 ? _a : (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; } } getRange(x, y, width, height) { return this.data.getRange(x, y, width, height); } toUint8Array() { var _a, _b; return ((_b = (_a = this._data) === null || _a === void 0 ? void 0 : _a.toUint8Array()) !== null && _b !== void 0 ? _b : (this.buffer !== undefined ? new Uint8Array(this.buffer) : new Uint8Array())); } getBytes(opt) { var _a, _b, _c, _d, _e, _f; const order = opt === null || opt === void 0 ? void 0 : opt.order; const alpha = opt === null || opt === void 0 ? void 0 : opt.alpha; if (order !== undefined) { const length = ChannelOrderLength.get(order); if (length !== this.numChannels) { const self = this.convert({ numChannels: length, alpha: alpha, }); return ((_b = (_a = self.data) === null || _a === void 0 ? void 0 : _a.getBytes({ order: order, inPlace: true, })) !== null && _b !== void 0 ? _b : this.toUint8Array()); } else { return ((_d = (_c = this.data) === null || _c === void 0 ? void 0 : _c.getBytes({ order: order, inPlace: false, })) !== null && _d !== void 0 ? _d : this.toUint8Array()); } } else { return ((_f = (_e = this.data) === null || _e === void 0 ? void 0 : _e.getBytes({ order: order, })) !== null && _f !== void 0 ? _f : this.toUint8Array()); } } remapChannels(order) { 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; } } } } isBoundsSafe(x, y) { return x >= 0 && y >= 0 && x < this.width && y < this.height; } getColor(r, g, b, a) { var _a, _b; return (_b = (_a = this._data) === null || _a === void 0 ? void 0 : _a.getColor(r, g, b, a)) !== null && _b !== void 0 ? _b : new ColorUint8(0); } getPixel(x, y, pixel) { var _a, _b; return (_b = (_a = this._data) === null || _a === void 0 ? void 0 : _a.getPixel(x, y, pixel)) !== null && _b !== void 0 ? _b : UndefinedPixel; } getPixelSafe(x, y, pixel) { if (x < 0 || x >= this.width || y < 0 || y >= this.height) { return UndefinedPixel; } return this.getPixel(x, y, pixel); } getPixelClamped(x, y, 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); } getPixelIndex(x, y) { var _a; const index = (_a = this._data) === null || _a === void 0 ? void 0 : _a.getPixel(x, y).index; return index !== undefined ? Math.trunc(index) : 0; } getPixelInterpolate(fx, fy, interpolation = Interpolation.linear) { 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.'); } getPixelLinear(fx, fy) { 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, inc, icn, inn) => { 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)); } getPixelCubic(fx, fy) { 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, ipp, icp, inp, iap) => { 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)); } setPixel(x, y, c) { var _a; if ('image' in c && 'index' in c) { if (c.image.hasPalette) { if (this.hasPalette) { this.setPixelIndex(x, y, c.index); return; } } } (_a = this._data) === null || _a === void 0 ? void 0 : _a.setPixelRgba(x, y, c.r, c.g, c.b, c.a); } setPixelIndex(x, y, i) { var _a; (_a = this._data) === null || _a === void 0 ? void 0 : _a.setPixelR(x, y, i); } setPixelR(x, y, i) { var _a; (_a = this._data) === null || _a === void 0 ? void 0 : _a.setPixelR(x, y, i); } setPixelRgb(x, y, r, g, b) { var _a; (_a = this._data) === null || _a === void 0 ? void 0 : _a.setPixelRgb(x, y, r, g, b); } setPixelRgba(x, y, r, g, b, a) { var _a; (_a = this._data) === null || _a === void 0 ? void 0 : _a.setPixelRgba(x, y, r, g, b, a); } clear(color) { var _a; (_a = this._data) === null || _a === void 0 ? void 0 : _a.clear(color); } convert(opt) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; const format = (_a = opt.format) !== null && _a !== void 0 ? _a : this.format; const numChannels = (_b = opt.numChannels) !== null && _b !== void 0 ? _b : this.numChannels; const alpha = (_c = opt.alpha) !== null && _c !== void 0 ? _c : FormatMaxValue.get(format); const withPalette = (_d = opt.withPalette) !== null && _d !== void 0 ? _d : false; const skipAnimation = (_e = opt.skipAnimation) !== null && _e !== void 0 ? _e : false; if (format === this.format && numChannels === this.numChannels && ((!withPalette && this.palette === undefined) || (withPalette && this.palette !== undefined))) { return MemoryImage.from(this); } let firstFrame = undefined; for (const frame of this._frames) { const newImage = new MemoryImage({ width: frame.width, height: frame.height, format: format, numChannels: numChannels, withPalette: withPalette, exifData: (_f = frame._exifData) === null || _f === void 0 ? void 0 : _f.clone(), iccProfile: (_g = frame._iccProfile) === null || _g === void 0 ? void 0 : _g.clone(), backgroundColor: (_h = frame._backgroundColor) === null || _h === void 0 ? void 0 : _h.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 = (_k = (_j = newImage.palette) === null || _j === void 0 ? void 0 : _j.format) !== null && _k !== void 0 ? _k : format; if (pal !== undefined) { const usedColors = new Map(); let numColors = 0; const op = frame.getPixel(0, 0); let c = 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; } addTextData(data) { var _a; (_a = this._textData) !== null && _a !== void 0 ? _a : (this._textData = new Map()); for (const [key, value] of data) { this._textData.set(key, value); } } getColorExtremes() { 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, }; } toString() { return `${this.constructor.name} (w: ${this.width}, h: ${this.height}, f: ${Format[this.format]}, ch: ${this.numChannels})`; } [Symbol.iterator]() { return this._data !== undefined ? this._data[Symbol.iterator]() : { next: () => ({ done: true, value: UndefinedPixel, }), }; } } //# sourceMappingURL=image.js.map