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)

149 lines 4.95 kB
import { ArrayUtils } from '../../common/array-utils.js'; import { VP8LImageTransformType } from './vp8l-image-transform-type.js'; import { VP8LInternal } from './vp8l-internal.js'; import { WebPFilters } from './webp-filters.js'; import { WebPInfo } from './webp-info.js'; export class WebPAlpha { get input() { return this._input; } get width() { return this._width; } get height() { return this._height; } get method() { return this._method; } get filter() { return this._filter; } get preProcessing() { return this._preProcessing; } get rsrv() { return this._rsrv; } get isAlphaDecoded() { return this._isAlphaDecoded; } get vp8l() { return this._vp8l; } get use8bDecode() { return this._use8bDecode; } get isValid() { if (this._method < WebPAlpha.alphaNoCompression || this._method > WebPAlpha.alphaLosslessCompression || this._filter >= WebPFilters.fitlerLast || this._preProcessing > WebPAlpha.alphaPreprocessedLevels || this._rsrv !== 0) { return false; } return true; } constructor(input, width, height) { this._width = 0; this._height = 0; this._method = 0; this._filter = 0; this._preProcessing = 0; this._rsrv = 1; this._isAlphaDecoded = false; this._use8bDecode = false; this._input = input; this._width = width; this._height = height; const b = input.read(); this._method = b & 0x03; this._filter = (b >>> 2) & 0x03; this._preProcessing = (b >>> 4) & 0x03; this._rsrv = (b >>> 6) & 0x03; if (this.isValid) { if (this._method === WebPAlpha.alphaNoCompression) { const alphaDecodedSize = width * height; if (input.length < alphaDecodedSize) { this._rsrv = 1; } } else if (this._method === WebPAlpha.alphaLosslessCompression) { if (!this.decodeAlphaHeader()) { this._rsrv = 1; } } else { this._rsrv = 1; } } } dequantizeLevels(_data, width, height, row, numRows) { if (width <= 0 || height <= 0 || row < 0 || numRows < 0 || row + numRows > height) { return false; } return true; } decodeAlphaImageStream(lastRow, output) { this._vp8l.opaque = output; return this._use8bDecode ? this._vp8l.decodeAlphaData(this._vp8l.webp.width, this._vp8l.webp.height, lastRow) : this._vp8l.decodeImageData(this._vp8l.pixels, this._vp8l.webp.width, this._vp8l.webp.height, lastRow, this._vp8l.extractAlphaRows); } decodeAlphaHeader() { const webp = new WebPInfo(); webp.width = this._width; webp.height = this._height; this._vp8l = new VP8LInternal(this._input, webp); this._vp8l.ioWidth = this._width; this._vp8l.ioHeight = this._height; this._vp8l.decodeImageStream(webp.width, webp.height, true); if (this._vp8l.transforms.length === 1 && this._vp8l.transforms[0].type === VP8LImageTransformType.colorIndexing && this._vp8l.is8bOptimizable()) { this._use8bDecode = true; this._vp8l.allocateInternalBuffers8b(); } else { this._use8bDecode = false; this._vp8l.allocateInternalBuffers32b(); } return true; } decode(row, numRows, output) { if (!this.isValid) { return false; } const unfilterFunc = WebPFilters.unfilters[this._filter]; if (this._method === WebPAlpha.alphaNoCompression) { const offset = row * this._width; const numPixels = numRows * this._width; ArrayUtils.copyRange(this._input.buffer, this._input.position + offset, output, offset, numPixels); } else { if (!this.decodeAlphaImageStream(row + numRows, output)) { return false; } } if (unfilterFunc !== undefined) { unfilterFunc(this._width, this._height, this._width, row, numRows, output); } if (this._preProcessing === WebPAlpha.alphaPreprocessedLevels) { if (!this.dequantizeLevels(output, this._width, this._height, row, numRows)) { return false; } } if (row + numRows === this._height) { this._isAlphaDecoded = true; } return true; } } WebPAlpha.alphaNoCompression = 0; WebPAlpha.alphaLosslessCompression = 1; WebPAlpha.alphaPreprocessedLevels = 1; //# sourceMappingURL=webp-alpha.js.map