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)

110 lines 3.91 kB
import { Format } from '../color/format.js'; import { InputBuffer } from '../common/input-buffer.js'; import { MemoryImage } from '../image/image.js'; import { BmpFileHeader } from './bmp/bmp-file-header.js'; import { BmpInfo } from './bmp/bmp-info.js'; import { ImageFormat } from './image-format.js'; export class BmpDecoder { get format() { return ImageFormat.bmp; } get numFrames() { return this._info !== undefined ? this._info.numFrames : 0; } constructor(forceRgba = false) { this._forceRgba = forceRgba; } isValidFile(bytes) { return BmpFileHeader.isValidFile(new InputBuffer({ buffer: bytes, })); } startDecode(bytes) { if (!this.isValidFile(bytes)) { return undefined; } this._input = new InputBuffer({ buffer: bytes, }); this._info = new BmpInfo(this._input); return this._info; } decodeFrame(_frameIndex) { if (this._input === undefined || this._info === undefined) { return undefined; } 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: inf.width, height: inf.height, format: format, numChannels: nc, palette: palette, }); for (let y = image.height - 1; y >= 0; --y) { const line = inf.readBottomUp ? y : image.height - 1 - y; const row = this._input.readRange(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++; } }); } } return image; } decode(opt) { var _a; const bytes = opt.bytes; const frameIndex = (_a = opt.frameIndex) !== null && _a !== void 0 ? _a : 0; if (this.startDecode(bytes) === undefined) { return undefined; } return this.decodeFrame(frameIndex); } } //# sourceMappingURL=bmp-decoder.js.map