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)
726 lines (725 loc) • 22.5 kB
TypeScript
/** @format */
import { InputBuffer } from '../../common/input-buffer.js';
import { MemoryImage } from '../../image/image.js';
import { WebPInfo } from './webp-info.js';
import { WebPInfoInternal } from './webp-info-internal.js';
/**
* WebP lossy format
*/
export declare class VP8 {
/**
* VP8 Frame Header
*/
private readonly _frameHeader;
/**
* VP8 Picture Header
*/
private readonly _picHeader;
/**
* VP8 Filter Header
*/
private readonly _filterHeader;
/**
* VP8 Segment Header
*/
private readonly _segmentHeader;
/**
* Input buffer for Uint8Array
*/
private _input;
/**
* Internal WebP information
*/
private readonly _webp;
/**
* Public getter for WebP information
*/
get webp(): WebPInfo;
/**
* Main data source
*/
private _br;
private _dsp;
private _output?;
/**
* Left crop value
*/
private _cropLeft;
/**
* Right crop value
*/
private _cropRight;
/**
* Top crop value
*/
private _cropTop;
/**
* Bottom crop value
*/
private _cropBottom;
/**
* Width in macroblock units
*/
private _mbWidth;
/**
* Height in macroblock units
*/
private _mbHeight;
/**
* Top-left macroblock X coordinate that must be in-loop filtered
*/
private _tlMbX;
/**
* Top-left macroblock Y coordinate that must be in-loop filtered
*/
private _tlMbY;
/**
* Bottom-right macroblock X coordinate that must be decoded
*/
private _brMbX;
/**
* Bottom-right macroblock Y coordinate that must be decoded
*/
private _brMbY;
/**
* Number of partitions
*/
private _numPartitions;
/**
* Per-partition boolean decoders
*/
private readonly _partitions;
/**
* Dithering strength, deduced from decoding options
* whether to use dithering or not
*/
private readonly _dither;
/**
* Dequantization (one set of DC/AC dequant factor per segment)
*/
private readonly _dqm;
/**
* Probabilities
*/
private _proba?;
/**
* Whether to use skip probability
*/
private _useSkipProba;
/**
* Skip probability
*/
private _skipP;
/**
* Top intra modes values: 4 * _mbWidth
*/
private _intraT?;
/**
* Left intra modes values
*/
private readonly _intraL;
/**
* Segment of the currently parsed block
*/
private _segment;
/**
* Top Y/U/V samples
*/
private _yuvT;
/**
* Contextual macroblock info (mb_w_ + 1)
*/
private _mbInfo;
/**
* Filter strength info
*/
private _fInfo;
/**
* Main block for Y/U/V (size = YUV_SIZE)
*/
private _yuvBlock;
/**
* Macroblock row for storing unfiltered samples
*/
private _cacheY;
private _cacheU;
private _cacheV;
private _cacheYStride;
private _cacheUVStride;
private _tmpY;
private _tmpU;
private _tmpV;
private _y;
private _u;
private _v;
private _a?;
/**
* Current position in macroblock units (X coordinate)
*/
private _mbX;
/**
* Current position in macroblock units (Y coordinate)
*/
private _mbY;
/**
* Parsed reconstruction data
*/
private _mbData;
/**
* Filter type: 0=off, 1=simple, 2=complex
*/
private _filterType;
/**
* Precalculated per-segment/type filter strengths
*/
private _fStrengths;
/**
* Alpha-plane decoder object
*/
private _alpha;
/**
* Compressed alpha data (if present)
*/
private _alphaData?;
/**
* Alpha plane data
*/
private _alphaPlane;
/**
* Constructs a new VP8 instance.
* @param {InputBuffer<Uint8Array>} input - Input buffer of Uint8Array type.
* @param {WebPInfoInternal} webp - WebPInfoInternal object containing webp information.
*/
constructor(input: InputBuffer<Uint8Array>, webp: WebPInfoInternal);
/**
* Clips the value v to the range [0, M].
* @param {number} v - The value to be clipped.
* @param {number} M - The maximum value for clipping.
* @returns {number} The clipped value.
*/
private static clip;
/**
* Checks the mode based on mbX and mbY values.
* @param {number} mbX - Macroblock X coordinate.
* @param {number} mbY - Macroblock Y coordinate.
* @param {number} [mode] - Optional mode value.
* @returns {number | undefined} The mode or undefined.
*/
private static checkMode;
/**
* Retrieves the headers.
* @returns {boolean} True if headers are successfully retrieved, otherwise false.
*/
private getHeaders;
/**
* Parses the segment header.
* @param {VP8SegmentHeader} hdr - VP8SegmentHeader object containing segment header information.
* @param {VP8Proba} [proba] - Optional VP8Proba object containing probability information.
* @returns {boolean} True if segment header is successfully parsed, otherwise false.
*/
private parseSegmentHeader;
/**
* Parses the filter header.
*
* @returns {boolean} True if filter header is successfully parsed, otherwise false.
*/
private parseFilterHeader;
/**
* Parses the partitions from the given input buffer.
*
* @param {InputBuffer<Uint8Array>} input - The input buffer containing the data to be parsed.
* @returns {boolean} true if the partitions were successfully parsed, false otherwise.
*/
private parsePartitions;
/**
* Parses quantization parameters and updates the dequantization matrices.
*
* This method reads quantization values from the bit reader and updates the
* dequantization matrices for each macroblock segment based on the segment
* header and quantization parameters.
*/
private parseQuant;
/**
* Parses the probability values for VP8 codec.
* This method updates the probability values used in the decoding process.
* It iterates through types, bands, contexts, and probabilities to set the appropriate values.
* It also checks and sets the skip probability if applicable.
*/
private parseProba;
/**
* Precomputes the filter strengths for each macroblock segment.
* This method calculates the filter strength based on the segment header,
* filter header, and other parameters, and updates the filter strengths
* for each segment and sub-block.
*/
private precomputeFilterStrengths;
/**
* Initializes the frame for processing.
*
* This method sets up various buffers and parameters required for processing
* the frame, including alpha data, filter strengths, YUV samples, and caches.
* It also defines the area where in-loop filtering can be skipped in case of cropping.
*
* @returns {boolean} - Returns true when initialization is successful.
*/
private initFrame;
/**
* Parses the frame by iterating through macroblock rows and columns.
* For each macroblock, it decodes and processes the row.
*
* @returns {boolean} - Returns true if the frame is successfully parsed, otherwise false.
*/
private parseFrame;
/**
* Processes a row by reconstructing it and then determining whether to use a filter
* based on certain conditions.
*
* @returns {boolean} - The result of finishing the row, potentially using a filter.
*/
private processRow;
/**
* Reconstructs a row of macroblocks by processing each macroblock in the row.
* This involves rotating left samples, initializing top-left samples, bringing
* top samples into the cache, predicting and adding residuals, and transferring
* reconstructed samples to the final destination.
*/
private reconstructRow;
/**
* Transforms the input buffer based on the specified bit pattern.
*
* @param {number} bits - The bit pattern used to determine the type of transformation.
* @param {InputBuffer<Int16Array>} src - The source input buffer containing Int16Array data.
* @param {InputBuffer<Uint8Array>} dst - The destination input buffer to store the transformed Uint8Array data.
*/
private doTransform;
/**
* Performs a UV transform on the given input buffers based on the provided bits.
*
* @param {number} bits - A number representing the bits to check for non-zero coefficients.
* @param {InputBuffer<Int16Array>} src - The source input buffer containing Int16Array data.
* @param {InputBuffer<Uint8Array>} dst - The destination input buffer to store the transformed Uint8Array data.
*/
private doUVTransform;
/**
* Applies filtering to the macroblock at the specified coordinates.
*
* @param {number} mbX - The x-coordinate of the macroblock.
* @param {number} mbY - The y-coordinate of the macroblock.
*/
private doFilter;
/**
* Filters a row of data by iterating through a range of X coordinates
* and applying a filter function to each coordinate.
*
* @private
*/
private filterRow;
/**
* Applies a dithering effect to the current row.
*/
private ditherRow;
/**
* Processes the current row of macroblocks, applying filters and dithering if necessary,
* and updates the internal buffers for the next row.
*
* @param {boolean} useFilter - Indicates whether to apply the filter to the current row.
* @returns {boolean} Returns true if the row was successfully processed, false otherwise.
*/
private finishRow;
/**
* Puts the specified width and height at the given Y-coordinate.
* Emits fancy RGB and alpha RGB values.
*
* @param {number} mbY - The Y-coordinate.
* @param {number} mbW - The width to be put.
* @param {number} mbH - The height to be put.
* @returns {boolean} Returns true if the width and height are greater than 0, otherwise false.
*/
private put;
/**
* Clips the given value to an 8-bit range based on specific conditions.
*
* @param {number} v - The value to be clipped.
* @returns {number} The clipped value, either shifted right by a fixed amount or set to 0 or 255.
*/
private clip8;
/**
* Converts YUV color space values to the Red (R) component in RGB color space.
*
* @param {number} y - The Y (luminance) component of the YUV color space.
* @param {number} v - The V (chrominance) component of the YUV color space.
* @returns {number} The Red (R) component in RGB color space.
*/
private yuvToR;
/**
* Converts YUV color components to the green (G) component in RGB color space.
*
* @param {number} y - The Y (luminance) component of the YUV color space.
* @param {number} u - The U (chrominance) component of the YUV color space.
* @param {number} v - The V (chrominance) component of the YUV color space.
* @returns {number} The green (G) component in the RGB color space.
*/
private yuvToG;
/**
* Converts YUV to Blue component.
* @param {number} y - Luminance component.
* @param {number} u - Chrominance component U.
* @returns {number} Blue component.
*/
private yuvToB;
/**
* Converts YUV to RGB.
* @param {number} y - Luminance component.
* @param {number} u - Chrominance component U.
* @param {number} v - Chrominance component V.
* @param {InputBuffer<Uint8Array>} rgb - Buffer to store RGB values.
*/
private yuvToRgb;
/**
* Converts YUV to RGBA.
* @param {number} y - Luminance component.
* @param {number} u - Chrominance component U.
* @param {number} v - Chrominance component V.
* @param {InputBuffer<Uint8Array>} rgba - Buffer to store RGBA values.
*/
private yuvToRgba;
/**
* Upsamples YUV components.
* @param {InputBuffer<Uint8Array>} topY - Top Y component buffer.
* @param {InputBuffer<Uint8Array> | undefined} bottomY - Bottom Y component buffer.
* @param {InputBuffer<Uint8Array>} topU - Top U component buffer.
* @param {InputBuffer<Uint8Array>} topV - Top V component buffer.
* @param {InputBuffer<Uint8Array>} curU - Current U component buffer.
* @param {InputBuffer<Uint8Array>} curV - Current V component buffer.
* @param {InputBuffer<Uint8Array>} topDst - Top destination buffer.
* @param {InputBuffer<Uint8Array> | undefined} bottomDst - Bottom destination buffer.
* @param {number} len - Length of the buffer.
*/
private upSample;
/**
* Emits alpha values for RGB.
* @param {number} mbY - Macroblock Y position.
* @param {number} mbW - Macroblock width.
* @param {number} mbH - Macroblock height.
*/
private emitAlphaRGB;
/**
* Emits fancy RGB values.
* @param {number} mbY - Macroblock Y position.
* @param {number} mbW - Macroblock width.
* @param {number} mbH - Macroblock height.
* @returns {number} Number of lines output.
*/
private emitFancyRGB;
/**
* Decompresses alpha rows.
* @param {number} row - Starting row.
* @param {number} numRows - Number of rows to decompress.
* @returns {InputBuffer<Uint8Array> | undefined} Buffer containing decompressed alpha rows.
*/
private decompressAlphaRows;
/**
* Decodes a macroblock.
* @param {VP8BitReader} [tokenBr] - Optional bit reader for tokens.
* @returns {boolean} True if decoding was successful.
*/
private decodeMB;
/**
* Parses residuals for a macroblock.
* @param {VP8MB} mb - Macroblock information.
* @param {VP8BitReader} [tokenBr] - Optional bit reader for tokens.
* @returns {boolean} True if parsing was successful.
*/
private parseResiduals;
/**
* Performs a Walsh-Hadamard Transform (WHT) on the input buffer and stores the result in the output buffer.
*
* @param {InputBuffer<Int16Array>} src - The source input buffer containing the data to be transformed.
* @param {InputBuffer<Int16Array>} out - The output buffer where the transformed data will be stored.
*/
private transformWHT;
/**
* Computes the non-zero coefficients.
* @param {number} nzCoeffs - The number of non-zero coefficients.
* @param {number} nz - The number of non-zero coefficients in the current block.
* @param {number} dcNz - The number of non-zero DC coefficients.
* @returns {number} The computed non-zero coefficients.
*/
private nzCodeBits;
/**
* Retrieves a large value based on bit reading.
* @param {VP8BitReader} br - The bit reader.
* @param {Uint8Array} p - The probability array.
* @returns {number} The large value.
*/
private getLargeValue;
/**
* Returns the position of the last non-zero coefficient plus one.
* @param {VP8BitReader | undefined} br - The bit reader.
* @param {VP8BandProbas[]} prob - The probability bands.
* @param {number} ctx - The context.
* @param {Int32Array} dq - The dequantization values.
* @param {number} n - The initial coefficient index.
* @param {InputBuffer<Int16Array>} out - The output buffer.
* @returns {number} The position of the last non-zero coefficient plus one.
*/
private getCoeffs;
/**
* Parses the intra mode.
*/
private parseIntraMode;
/**
* Decodes the header of the input stream.
* @returns {boolean} True if the header is successfully decoded, false otherwise.
*/
decodeHeader(): boolean;
/**
* Decodes the input stream and returns the decoded image.
* @returns {MemoryImage | undefined} The decoded image or undefined if decoding fails.
*/
decode(): MemoryImage | undefined;
/**
* Computes the vertical position of a macroblock.
* @param {number} mbY - The macroblock Y-coordinate.
* @returns {number} The vertical position of the macroblock.
*/
macroBlockVPos(mbY: number): number;
/**
* How many extra lines are needed on the MB boundary
* for caching, given a filtering level.
* Simple filter: up to 2 luma samples are read and 1 is written.
* Complex filter: up to 4 luma samples are read and 3 are written. Same for
* U/V, so it's 8 samples total (because of the 2x upsampling).
*/
static readonly filterExtraRows: number[];
/**
* VP8 signature constant.
*/
static readonly vp8Signature = 2752925;
/**
* Number of probabilities in the macroblock feature tree.
*/
static readonly mbFeatureTreeProbs = 3;
/**
* Number of macroblock segments.
*/
static readonly numMbSegments = 4;
/**
* Number of reference loop filter deltas.
*/
static readonly numRefLfDeltas = 4;
/**
* Number of mode loop filter deltas.
* I4x4, ZERO, *, SPLIT
*/
static readonly numModeLfDeltas = 4;
/**
* Maximum number of partitions.
*/
static readonly maxNumPartitions = 8;
/**
* 4x4 prediction modes.
*/
static readonly bDcPred = 0;
static readonly bTmPred = 1;
static readonly bVePred = 2;
static readonly bHePred = 3;
static readonly bRdPred = 4;
static readonly bVrPred = 5;
static readonly bLdPred = 6;
static readonly bVlPred = 7;
static readonly bHdPred = 8;
static readonly bHuPred = 9;
/**
* Number of 4x4 prediction modes.
*/
static readonly numBModes: number;
/**
* Luma16 or UV prediction modes.
*/
static readonly dcPred = 0;
static readonly vPred = 2;
static readonly hPred = 3;
static readonly tmPred = 1;
static readonly bPred: number;
/**
* Special prediction modes.
*/
static readonly bDcPredNoTop = 4;
static readonly bDcPredNoLeft = 5;
static readonly bDcPredNoTopLeft = 6;
static readonly numBDcModes = 7;
/**
* Number of types.
*/
static readonly numTypes = 4;
/**
* Number of bands.
*/
static readonly numBands = 8;
/**
* Number of contexts.
*/
static readonly numCtx = 3;
/**
* Number of probabilities.
*/
static readonly numProbas = 11;
/**
* Common stride used by yuv[].
*/
static readonly bps = 32;
/**
* YUV size.
*/
static readonly yuvSize: number;
/**
* Y size.
*/
static readonly ySize: number;
/**
* Y offset.
*/
static readonly yOffset: number;
/**
* U offset.
*/
static readonly uOffset: number;
/**
* V offset.
*/
static readonly vOffset: number;
/**
* Fixed-point precision for RGB->YUV.
*/
static readonly yuvFix = 16;
/**
* Half value for YUV fixed-point precision.
*/
static readonly yuvHalf: number;
/**
* Mask value for YUV fixed-point precision.
*/
static readonly yuvMask: number;
/**
* Minimum value of r/g/b output.
*/
static readonly yuvRangeMin = -227;
/**
* Maximum value of r/g/b output.
*/
static readonly yuvRangeMax: number;
/**
* Fixed-point precision for YUV->RGB.
*/
static readonly yuvFix2 = 14;
/**
* Half value for YUV->RGB fixed-point precision.
*/
static readonly yuvHalf2: number;
/**
* Mask value for YUV->RGB fixed-point precision.
*/
static readonly yuvMask2: number;
/**
* XOR mask value for YUV->RGB fixed-point precision.
*/
static readonly xorYuvMask2: number;
/**
* 14b fixed-point version of ITU-R BT.601 constants.
* 1.164 = 255 / 219
*/
static readonly kYScale = 19077;
/**
* 1.596 = 255 / 112 * 0.701
*/
static readonly kVToR = 26149;
/**
* 0.391 = 255 / 112 * 0.886 * 0.114 / 0.587
*/
static readonly kUToG = 6419;
/**
* 0.813 = 255 / 112 * 0.701 * 0.299 / 0.587
*/
static readonly kVToG = 13320;
/**
* 2.018 = 255 / 112 * 0.886
*/
static readonly kUToB = 33050;
/**
* Constant for red channel.
*/
static readonly kRCst: number;
/**
* Constant for green channel.
*/
static readonly kGCst: number;
/**
* Constant for blue channel.
*/
static readonly kBCst: number;
/**
* Intra4 prediction modes for Y.
*/
static readonly kYModesIntra4: number[];
/**
* Probabilities for B modes.
*/
static readonly kBModesProba: Array<Array<Array<number>>>;
/**
* A 4-dimensional array representing the probability coefficients for Proba0.
*/
static readonly coeffsProba0: Array<Array<Array<Array<number>>>>;
/**
* A 4-dimensional array representing the probability coefficients for UpdateProba.
*/
static readonly coeffsUpdateProba: Array<Array<Array<Array<number>>>>;
/**
* Represents a table of DC values.
*/
static readonly dcTable: number[];
/**
* Represents a table of AC values.
*/
static readonly acTable: number[];
/**
* Scan order for VP8.
*/
static readonly kScan: number[];
/**
* Band order for VP8.
*/
static readonly kBands: number[];
/**
* Category 3 probabilities for VP8.
*/
static readonly kCat3: number[];
/**
* Category 4 probabilities for VP8.
*/
static readonly kCat4: number[];
/**
* Category 5 probabilities for VP8.
*/
static readonly kCat5: number[];
/**
* Category 6 probabilities for VP8.
*/
static readonly kCat6: number[];
/**
* Combined categories 3, 4, 5, and 6 probabilities for VP8.
*/
static readonly kCat3456: Array<Array<number>>;
/**
* Zigzag order for VP8.
*/
static readonly kZigzag: number[];
/**
* How many extra lines are needed on the MB boundary
* for caching, given a filtering level.
* Simple filter: up to 2 luma samples are read and 1 is written.
* Complex filter: up to 4 luma samples are read and 3 are written. Same for
* U/V, so it's 8 samples total (because of the 2x upsampling).
*/
static readonly kFilterExtraRows: number[];
}