"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _ = require("../"); var _uint = require("../parsers/uint8"); // a set of 0x00 terminated subblocks var subBlocksSchema = { blocks: function blocks(stream) { var terminator = 0x00; var chunks = []; var streamSize = stream.data.length; var total = 0; for (var size = (0, _uint.readByte)()(stream); size !== terminator; size = (0, _uint.readByte)()(stream)) { // size becomes undefined for some case when file is corrupted and terminator is not proper // null check to avoid recursion if (!size) break; // catch corrupted files with no terminator if (stream.pos + size >= streamSize) { var availableSize = streamSize - stream.pos; chunks.push((0, _uint.readBytes)(availableSize)(stream)); total += availableSize; break; } chunks.push((0, _uint.readBytes)(size)(stream)); total += size; } var result = new Uint8Array(total); var offset = 0; for (var i = 0; i < chunks.length; i++) { result.set(chunks[i], offset); offset += chunks[i].length; } return result; } }; // global control extension var gceSchema = (0, _.conditional)({ gce: [{ codes: (0, _uint.readBytes)(2) }, { byteSize: (0, _uint.readByte)() }, { extras: (0, _uint.readBits)({ future: { index: 0, length: 3 }, disposal: { index: 3, length: 3 }, userInput: { index: 6 }, transparentColorGiven: { index: 7 } }) }, { delay: (0, _uint.readUnsigned)(true) }, { transparentColorIndex: (0, _uint.readByte)() }, { terminator: (0, _uint.readByte)() }] }, function (stream) { var codes = (0, _uint.peekBytes)(2)(stream); return codes[0] === 0x21 && codes[1] === 0xf9; }); // image pipeline block var imageSchema = (0, _.conditional)({ image: [{ code: (0, _uint.readByte)() }, { descriptor: [{ left: (0, _uint.readUnsigned)(true) }, { top: (0, _uint.readUnsigned)(true) }, { width: (0, _uint.readUnsigned)(true) }, { height: (0, _uint.readUnsigned)(true) }, { lct: (0, _uint.readBits)({ exists: { index: 0 }, interlaced: { index: 1 }, sort: { index: 2 }, future: { index: 3, length: 2 }, size: { index: 5, length: 3 } }) }] }, (0, _.conditional)({ lct: (0, _uint.readArray)(3, function (stream, result, parent) { return Math.pow(2, parent.descriptor.lct.size + 1); }) }, function (stream, result, parent) { return parent.descriptor.lct.exists; }), { data: [{ minCodeSize: (0, _uint.readByte)() }, subBlocksSchema] }] }, function (stream) { return (0, _uint.peekByte)()(stream) === 0x2c; }); // plain text block var textSchema = (0, _.conditional)({ text: [{ codes: (0, _uint.readBytes)(2) }, { blockSize: (0, _uint.readByte)() }, { preData: function preData(stream, result, parent) { return (0, _uint.readBytes)(parent.text.blockSize)(stream); } }, subBlocksSchema] }, function (stream) { var codes = (0, _uint.peekBytes)(2)(stream); return codes[0] === 0x21 && codes[1] === 0x01; }); // application block var applicationSchema = (0, _.conditional)({ application: [{ codes: (0, _uint.readBytes)(2) }, { blockSize: (0, _uint.readByte)() }, { id: function id(stream, result, parent) { return (0, _uint.readString)(parent.blockSize)(stream); } }, subBlocksSchema] }, function (stream) { var codes = (0, _uint.peekBytes)(2)(stream); return codes[0] === 0x21 && codes[1] === 0xff; }); // comment block var commentSchema = (0, _.conditional)({ comment: [{ codes: (0, _uint.readBytes)(2) }, subBlocksSchema] }, function (stream) { var codes = (0, _uint.peekBytes)(2)(stream); return codes[0] === 0x21 && codes[1] === 0xfe; }); var schema = [{ header: [{ signature: (0, _uint.readString)(3) }, { version: (0, _uint.readString)(3) }] }, { lsd: [{ width: (0, _uint.readUnsigned)(true) }, { height: (0, _uint.readUnsigned)(true) }, { gct: (0, _uint.readBits)({ exists: { index: 0 }, resolution: { index: 1, length: 3 }, sort: { index: 4 }, size: { index: 5, length: 3 } }) }, { backgroundColorIndex: (0, _uint.readByte)() }, { pixelAspectRatio: (0, _uint.readByte)() }] }, (0, _.conditional)({ gct: (0, _uint.readArray)(3, function (stream, result) { return Math.pow(2, result.lsd.gct.size + 1); }) }, function (stream, result) { return result.lsd.gct.exists; }), // content frames { frames: (0, _.loop)([gceSchema, applicationSchema, commentSchema, imageSchema, textSchema], function (stream) { var nextCode = (0, _uint.peekByte)()(stream); // rather than check for a terminator, we should check for the existence // of an ext or image block to avoid infinite loops //var terminator = 0x3B; //return nextCode !== terminator; return nextCode === 0x21 || nextCode === 0x2c; }) }]; var _default = schema; exports["default"] = _default;