UNPKG

@remotion/gif

Version:

Embed GIFs in a Remotion video

60 lines (59 loc) 2.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.decompressFrames = exports.decompressFrame = exports.parseGIF = void 0; /* eslint-disable no-console */ const gif_1 = require("../js-binary-schema-parser/gif"); const parser_1 = require("../js-binary-schema-parser/parser"); const uint8_parser_1 = require("../js-binary-schema-parser/uint8-parser"); const deinterlace_1 = require("./deinterlace"); const lzw_1 = require("./lzw"); const parseGIF = (arrayBuffer) => { const byteData = new Uint8Array(arrayBuffer); return (0, parser_1.parse)((0, uint8_parser_1.buildStream)(byteData), gif_1.GIF); }; exports.parseGIF = parseGIF; const decompressFrame = (frame, gct) => { var _a, _b, _c; if (!frame.image) { console.warn('gif frame does not have associated image.'); return null; } const { image } = frame; // get the number of pixels const totalPixels = image.descriptor.width * image.descriptor.height; // do lzw decompression let pixels = (0, lzw_1.lzw)(image.data.minCodeSize, image.data.blocks, totalPixels); // deal with interlacing if necessary if ((_a = image.descriptor.lct) === null || _a === void 0 ? void 0 : _a.interlaced) { pixels = (0, deinterlace_1.deinterlace)(pixels, image.descriptor.width); } const resultImage = { pixels, dims: { top: frame.image.descriptor.top, left: frame.image.descriptor.left, width: frame.image.descriptor.width, height: frame.image.descriptor.height, }, colorTable: ((_b = image.descriptor.lct) === null || _b === void 0 ? void 0 : _b.exists) ? image.lct : gct, // Same behavior as FFmpeg: If delay is 0, we set it to 100ms // https://github.com/FFmpeg/FFmpeg/blob/060fc4e3a5acae27e5fbf2ff06419dff08a7d318/libavformat/gifdec.c#L62-L68 delay: (((_c = frame.gce) === null || _c === void 0 ? void 0 : _c.delay) || 10) * 10, disposalType: frame.gce ? frame.gce.extras.disposal : 1, transparentIndex: frame.gce ? frame.gce.extras.transparentColorGiven ? frame.gce.transparentColorIndex : -1 : -1, }; return resultImage; }; exports.decompressFrame = decompressFrame; const decompressFrames = (parsedGif) => { return parsedGif.frames .filter((f) => !('application' in f)) .map((f) => (0, exports.decompressFrame)(f, parsedGif.gct)); }; exports.decompressFrames = decompressFrames;