@n.see/gif-parser
Advanced tools
Comparing version 1.0.7 to 1.1.0
@@ -1,115 +0,73 @@ | ||
var __defProp = Object.defineProperty; | ||
var __defProps = Object.defineProperties; | ||
var __getOwnPropDescs = Object.getOwnPropertyDescriptors; | ||
var __getOwnPropSymbols = Object.getOwnPropertySymbols; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
var __propIsEnum = Object.prototype.propertyIsEnumerable; | ||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
var __spreadValues = (a, b) => { | ||
for (var prop in b || (b = {})) | ||
if (__hasOwnProp.call(b, prop)) | ||
__defNormalProp(a, prop, b[prop]); | ||
if (__getOwnPropSymbols) | ||
for (var prop of __getOwnPropSymbols(b)) { | ||
if (__propIsEnum.call(b, prop)) | ||
__defNormalProp(a, prop, b[prop]); | ||
} | ||
return a; | ||
}; | ||
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); | ||
var __publicField = (obj, key, value) => { | ||
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); | ||
return value; | ||
}; | ||
class Stream { | ||
constructor(arrayBuffer, littleEndian) { | ||
__publicField(this, "index", 0); | ||
__publicField(this, "dataView"); | ||
this.arrayBuffer = arrayBuffer; | ||
this.littleEndian = littleEndian; | ||
this.dataView = new DataView(arrayBuffer); | ||
this.littleEndian = littleEndian || false; | ||
var z = Object.defineProperty; | ||
var B = (o, t, e) => t in o ? z(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e; | ||
var s = (o, t, e) => (B(o, typeof t != "symbol" ? t + "" : t, e), e); | ||
class I { | ||
constructor(t, e) { | ||
s(this, "index", 0); | ||
s(this, "dataView"); | ||
this.arrayBuffer = t, this.littleEndian = e, this.dataView = new DataView(t), this.littleEndian = e || !1; | ||
} | ||
check(size) { | ||
if (this.index + size <= this.dataView.byteLength) { | ||
return true; | ||
} | ||
return false; | ||
check(t) { | ||
return this.index + t <= this.dataView.byteLength; | ||
} | ||
seek(x) { | ||
this.index += x; | ||
seek(t) { | ||
this.index += t; | ||
} | ||
peekByte(offset = 0) { | ||
this.check(1 + offset); | ||
return this.dataView.getUint8(this.index + offset); | ||
peekByte(t = 0) { | ||
return this.check(1 + t), this.dataView.getUint8(this.index + t); | ||
} | ||
slice(offset, length) { | ||
const ab = new Uint8Array(this.dataView.buffer, offset, length); | ||
return ab; | ||
slice(t, e) { | ||
return new Uint8Array(this.dataView.buffer, t, e); | ||
} | ||
readUint8() { | ||
this.check(1); | ||
const value = this.dataView.getUint8(this.index); | ||
this.seek(1); | ||
return value; | ||
const t = this.dataView.getUint8(this.index); | ||
return this.seek(1), t; | ||
} | ||
readUint8Array(len) { | ||
const r = []; | ||
for (let i = 0; i < len; i++) { | ||
r.push(this.readUint8()); | ||
} | ||
return r; | ||
readUint8Array(t) { | ||
const e = []; | ||
for (let i = 0; i < t; i++) | ||
e.push(this.readUint8()); | ||
return e; | ||
} | ||
readUint16() { | ||
this.check(2); | ||
const value = this.dataView.getUint16(this.index, this.littleEndian); | ||
this.seek(2); | ||
return value; | ||
const t = this.dataView.getUint16(this.index, this.littleEndian); | ||
return this.seek(2), t; | ||
} | ||
readUint32() { | ||
this.check(4); | ||
const val = this.dataView.getUint32(this.index, this.littleEndian); | ||
this.seek(4); | ||
return val; | ||
const t = this.dataView.getUint32(this.index, this.littleEndian); | ||
return this.seek(4), t; | ||
} | ||
readInt32() { | ||
this.check(4); | ||
const val = this.dataView.getInt32(this.index, this.littleEndian); | ||
this.seek(4); | ||
return val; | ||
const t = this.dataView.getInt32(this.index, this.littleEndian); | ||
return this.seek(4), t; | ||
} | ||
readString(len) { | ||
let str = ""; | ||
for (let i = 0; i < len; i++) { | ||
str += String.fromCharCode(this.readUint8()); | ||
} | ||
return str; | ||
readString(t) { | ||
let e = ""; | ||
for (let i = 0; i < t; i++) | ||
e += String.fromCharCode(this.readUint8()); | ||
return e; | ||
} | ||
readEscapedString(len) { | ||
let str = ""; | ||
for (let i = 0; i < len; i++) { | ||
const char = this.readUint8(); | ||
if (char >= 32 && char <= 126) { | ||
str += String.fromCharCode(char); | ||
} else { | ||
str += `\\x${char.toString(16).padStart(2, "0")}`; | ||
} | ||
readEscapedString(t) { | ||
let e = ""; | ||
for (let i = 0; i < t; i++) { | ||
const r = this.readUint8(); | ||
r >= 32 && r <= 126 ? e += String.fromCharCode(r) : e += `\\x${r.toString(16).padStart(2, "0")}`; | ||
} | ||
return str; | ||
return e; | ||
} | ||
readNullTerminatedString() { | ||
let str = ""; | ||
let val = this.readUint8(); | ||
while (val !== 0) { | ||
str += String.fromCharCode(val); | ||
val = this.readUint8(); | ||
} | ||
return str; | ||
let t = "", e = this.readUint8(); | ||
for (; e !== 0; ) | ||
t += String.fromCharCode(e), e = this.readUint8(); | ||
return t; | ||
} | ||
hasMore(x) { | ||
this.check(1); | ||
return this.index <= this.dataView.byteLength - (x || 1); | ||
hasMore(t) { | ||
return this.check(1), this.index <= this.dataView.byteLength - (t || 1); | ||
} | ||
setOffset(offset) { | ||
this.index = offset; | ||
setOffset(t) { | ||
this.index = t; | ||
} | ||
@@ -120,49 +78,41 @@ getOffset() { | ||
readInt8() { | ||
const value = this.dataView.getInt8(this.index); | ||
this.seek(1); | ||
return value; | ||
const t = this.dataView.getInt8(this.index); | ||
return this.seek(1), t; | ||
} | ||
} | ||
function bitsToNumber(ba) { | ||
return ba.reduce((s, n) => s * 2 + n, 0); | ||
function S(o) { | ||
return o.reduce((t, e) => t * 2 + e, 0); | ||
} | ||
function byteToBits(bite) { | ||
let a = []; | ||
for (let i = 7; i >= 0; i--) { | ||
a.push(!!(bite & 1 << i)); | ||
} | ||
return a.map((n) => Number(n)); | ||
function T(o) { | ||
let t = []; | ||
for (let e = 7; e >= 0; e--) | ||
t.push(!!(o & 1 << e)); | ||
return t.map((e) => Number(e)); | ||
} | ||
function loadGif(url) { | ||
return fetch(url).then((resp) => resp.arrayBuffer()); | ||
function Z(o) { | ||
return fetch(o).then((t) => t.arrayBuffer()); | ||
} | ||
function getBytes(stream, offset, length) { | ||
function b(o, t, e) { | ||
try { | ||
return stream.slice(offset, length); | ||
} catch (error) { | ||
return o.slice(t, e); | ||
} catch { | ||
return new Uint8Array(0); | ||
} | ||
} | ||
function numberToHex(n) { | ||
const hex = parseInt(`${n}`).toString(16); | ||
return (hex.length === 2 ? hex : `0${hex}`).toUpperCase(); | ||
function U(o) { | ||
const t = parseInt(`${o}`).toString(16); | ||
return (t.length === 2 ? t : `0${t}`).toUpperCase(); | ||
} | ||
class Header { | ||
constructor(stream) { | ||
__publicField(this, "type", "Header"); | ||
__publicField(this, "offset", 0); | ||
__publicField(this, "length", 0); | ||
__publicField(this, "bytes", new Uint8Array(0)); | ||
__publicField(this, "signature", ""); | ||
__publicField(this, "version", ""); | ||
this.stream = stream; | ||
this.stream = stream; | ||
class L { | ||
constructor(t) { | ||
s(this, "type", "Header"); | ||
s(this, "offset", 0); | ||
s(this, "length", 0); | ||
s(this, "bytes", new Uint8Array(0)); | ||
s(this, "signature", ""); | ||
s(this, "version", ""); | ||
this.stream = t, this.stream = t; | ||
} | ||
parse() { | ||
this.offset = this.stream.getOffset(); | ||
this.signature = this.stream.readString(3); | ||
this.version = this.stream.readString(3); | ||
this.length = this.stream.getOffset() - this.offset; | ||
console.log("this.signature", this.signature); | ||
if (this.signature !== "GIF") | ||
if (this.offset = this.stream.getOffset(), this.signature = this.stream.readString(3), this.version = this.stream.readString(3), this.length = this.stream.getOffset() - this.offset, console.log("this.signature", this.signature), this.signature !== "GIF") | ||
throw new Error("Not a GIF file."); | ||
@@ -175,3 +125,3 @@ } | ||
length: this.length, | ||
bytes: getBytes(this.stream, this.offset, this.length), | ||
bytes: b(this.stream, this.offset, this.length), | ||
data: { | ||
@@ -184,29 +134,21 @@ signature: this.signature, | ||
} | ||
class LogicalScreenDescriptor { | ||
constructor(stream) { | ||
__publicField(this, "type", "LogicalScreenDescriptor"); | ||
__publicField(this, "offset", 0); | ||
__publicField(this, "length", 0); | ||
__publicField(this, "bytes", new Uint8Array(0)); | ||
__publicField(this, "width", 0); | ||
__publicField(this, "height", 0); | ||
__publicField(this, "packedFields", []); | ||
__publicField(this, "globalColorTableFlag", 0); | ||
__publicField(this, "colorResolution", 0); | ||
__publicField(this, "sortFlag", 0); | ||
__publicField(this, "globalColorTableSize", 0); | ||
__publicField(this, "backgroundColorIndex", 0); | ||
__publicField(this, "pixelAspectRatio", 0); | ||
this.stream = stream; | ||
this.stream = stream; | ||
class A { | ||
constructor(t) { | ||
s(this, "type", "LogicalScreenDescriptor"); | ||
s(this, "offset", 0); | ||
s(this, "length", 0); | ||
s(this, "bytes", new Uint8Array(0)); | ||
s(this, "width", 0); | ||
s(this, "height", 0); | ||
s(this, "packedFields", []); | ||
s(this, "globalColorTableFlag", 0); | ||
s(this, "colorResolution", 0); | ||
s(this, "sortFlag", 0); | ||
s(this, "globalColorTableSize", 0); | ||
s(this, "backgroundColorIndex", 0); | ||
s(this, "pixelAspectRatio", 0); | ||
this.stream = t, this.stream = t; | ||
} | ||
parse() { | ||
this.offset = this.stream.getOffset(); | ||
this.width = this.stream.readUint16(); | ||
this.height = this.stream.readUint16(); | ||
this.packedFields = byteToBits(this.stream.readUint8()); | ||
this.handlerPackedField(this.packedFields); | ||
this.backgroundColorIndex = this.stream.readUint8(); | ||
this.pixelAspectRatio = this.stream.readInt8(); | ||
this.length = this.stream.getOffset() - this.offset; | ||
this.offset = this.stream.getOffset(), this.width = this.stream.readUint16(), this.height = this.stream.readUint16(), this.packedFields = T(this.stream.readUint8()), this.handlerPackedField(this.packedFields), this.backgroundColorIndex = this.stream.readUint8(), this.pixelAspectRatio = this.stream.readInt8(), this.length = this.stream.getOffset() - this.offset; | ||
} | ||
@@ -224,3 +166,3 @@ hasGlobalColorTable() { | ||
length: this.length, | ||
bytes: getBytes(this.stream, this.offset, this.length), | ||
bytes: b(this.stream, this.offset, this.length), | ||
data: { | ||
@@ -239,27 +181,21 @@ width: this.width, | ||
} | ||
handlerPackedField(rb) { | ||
const bits = [...rb]; | ||
this.globalColorTableFlag = bits.shift() || 0; | ||
this.colorResolution = bitsToNumber(bits.splice(0, 3)) + 1; | ||
this.sortFlag = bits.shift() || 0; | ||
this.globalColorTableSize = bitsToNumber(bits.splice(0, 3)); | ||
handlerPackedField(t) { | ||
const e = [...t]; | ||
this.globalColorTableFlag = e.shift() || 0, this.colorResolution = S(e.splice(0, 3)) + 1, this.sortFlag = e.shift() || 0, this.globalColorTableSize = S(e.splice(0, 3)); | ||
} | ||
} | ||
class ColorTable { | ||
constructor(stream, type) { | ||
__publicField(this, "type", ""); | ||
__publicField(this, "offset", 0); | ||
__publicField(this, "length", 0); | ||
__publicField(this, "bytes", new Uint8Array(0)); | ||
__publicField(this, "colors", []); | ||
this.stream = stream; | ||
this.stream = stream; | ||
this.type = type; | ||
class F { | ||
constructor(t, e) { | ||
s(this, "type", ""); | ||
s(this, "offset", 0); | ||
s(this, "length", 0); | ||
s(this, "bytes", new Uint8Array(0)); | ||
s(this, "colors", []); | ||
this.stream = t, this.stream = t, this.type = e; | ||
} | ||
parse({ size = 0 }) { | ||
const globalColorTableSize = 1 << size + 1; | ||
parse({ size: t = 0 }) { | ||
const e = 1 << t + 1; | ||
this.offset = this.stream.getOffset(); | ||
for (let i = 0; i < globalColorTableSize; i++) { | ||
for (let i = 0; i < e; i++) | ||
this.colors.push(this.stream.readUint8Array(3)); | ||
} | ||
this.length = this.stream.getOffset() - this.offset; | ||
@@ -272,3 +208,3 @@ } | ||
length: this.length, | ||
bytes: getBytes(this.stream, this.offset, this.length), | ||
bytes: b(this.stream, this.offset, this.length), | ||
data: this.colors | ||
@@ -278,13 +214,13 @@ }; | ||
} | ||
class GlobalColorTable extends ColorTable { | ||
constructor(stream) { | ||
super(stream, "GlobalColorTable"); | ||
class v extends F { | ||
constructor(t) { | ||
super(t, "GlobalColorTable"); | ||
} | ||
} | ||
class BaseExtension { | ||
constructor(stream) { | ||
__publicField(this, "stream"); | ||
this.stream = stream; | ||
class x { | ||
constructor(t) { | ||
s(this, "stream"); | ||
this.stream = t; | ||
} | ||
parse(param) { | ||
parse(t) { | ||
} | ||
@@ -294,53 +230,37 @@ export() { | ||
readSubBlocks() { | ||
const offset = this.stream.getOffset(); | ||
let size = this.stream.readInt8(); | ||
let length = 1; | ||
const blocks = []; | ||
while (size > 0) { | ||
blocks.push({ offset: offset + length, length: size }); | ||
length += size + 1; | ||
this.stream.seek(size); | ||
size = this.stream.readUint8(); | ||
} | ||
const t = this.stream.getOffset(); | ||
let e = this.stream.readInt8(), i = 1; | ||
const r = []; | ||
for (; e > 0; ) | ||
r.push({ offset: t + i, length: e }), i += e + 1, this.stream.seek(e), e = this.stream.readUint8(); | ||
return { | ||
blocks, | ||
blocksLength: length | ||
blocks: r, | ||
blocksLength: i | ||
}; | ||
} | ||
} | ||
class GraphicsControlExtension extends BaseExtension { | ||
constructor(stream) { | ||
super(stream); | ||
__publicField(this, "type", "GraphicsControlExtension"); | ||
__publicField(this, "offset", 0); | ||
__publicField(this, "length", 0); | ||
__publicField(this, "bytes", new Uint8Array(0)); | ||
__publicField(this, "introducer", ""); | ||
__publicField(this, "label", ""); | ||
__publicField(this, "blockSize", 0); | ||
__publicField(this, "packedFields", []); | ||
__publicField(this, "reserved", []); | ||
__publicField(this, "disposalMethod", 0); | ||
__publicField(this, "userInputFlag", 0); | ||
__publicField(this, "transparentColorFlag", 0); | ||
__publicField(this, "delayTime", 0); | ||
__publicField(this, "transparentColorIndex", 0); | ||
__publicField(this, "blockTerminator", ""); | ||
this.stream = stream; | ||
class R extends x { | ||
constructor(e) { | ||
super(e); | ||
s(this, "type", "GraphicsControlExtension"); | ||
s(this, "offset", 0); | ||
s(this, "length", 0); | ||
s(this, "bytes", new Uint8Array(0)); | ||
s(this, "introducer", ""); | ||
s(this, "label", ""); | ||
s(this, "blockSize", 0); | ||
s(this, "packedFields", []); | ||
s(this, "reserved", []); | ||
s(this, "disposalMethod", 0); | ||
s(this, "userInputFlag", 0); | ||
s(this, "transparentColorFlag", 0); | ||
s(this, "delayTime", 0); | ||
s(this, "transparentColorIndex", 0); | ||
s(this, "blockTerminator", ""); | ||
this.stream = e; | ||
} | ||
parse({ introducer = 0, label = 0 }) { | ||
this.offset = this.stream.getOffset() - 2; | ||
this.introducer = String.fromCharCode(introducer); | ||
this.label = numberToHex(label); | ||
this.blockSize = this.stream.readUint8(); | ||
this.packedFields = byteToBits(this.stream.readUint8()); | ||
const bits = [...this.packedFields]; | ||
this.reserved = bits.splice(0, 3); | ||
this.disposalMethod = bitsToNumber(bits.splice(0, 3)); | ||
this.userInputFlag = bits.shift() || 0; | ||
this.transparentColorFlag = bits.shift() || 0; | ||
this.delayTime = this.stream.readUint16(); | ||
this.transparentColorIndex = this.stream.readUint8(); | ||
this.blockTerminator = this.stream.readString(1); | ||
this.length = this.stream.getOffset() - this.offset; | ||
parse({ introducer: e = 0, label: i = 0 }) { | ||
this.offset = this.stream.getOffset() - 2, this.introducer = String.fromCharCode(e), this.label = U(i), this.blockSize = this.stream.readUint8(), this.packedFields = T(this.stream.readUint8()); | ||
const r = [...this.packedFields]; | ||
this.reserved = r.splice(0, 3), this.disposalMethod = S(r.splice(0, 3)), this.userInputFlag = r.shift() || 0, this.transparentColorFlag = r.shift() || 0, this.delayTime = this.stream.readUint16(), this.transparentColorIndex = this.stream.readUint8(), this.blockTerminator = this.stream.readString(1), this.length = this.stream.getOffset() - this.offset; | ||
} | ||
@@ -352,3 +272,3 @@ export() { | ||
length: this.length, | ||
bytes: getBytes(this.stream, this.offset, this.length), | ||
bytes: b(this.stream, this.offset, this.length), | ||
data: { | ||
@@ -370,16 +290,14 @@ introducer: this.introducer, | ||
} | ||
class CommentExtension extends BaseExtension { | ||
constructor(stream) { | ||
super(stream); | ||
__publicField(this, "type", "CommentExtension"); | ||
__publicField(this, "offset", 0); | ||
__publicField(this, "length", 0); | ||
__publicField(this, "bytes", new Uint8Array(0)); | ||
__publicField(this, "comment", {}); | ||
this.stream = stream; | ||
class G extends x { | ||
constructor(e) { | ||
super(e); | ||
s(this, "type", "CommentExtension"); | ||
s(this, "offset", 0); | ||
s(this, "length", 0); | ||
s(this, "bytes", new Uint8Array(0)); | ||
s(this, "comment", {}); | ||
this.stream = e; | ||
} | ||
parse({ introducer, label }) { | ||
this.offset = this.stream.getOffset(); | ||
this.comment = this.readSubBlocks(); | ||
this.length = this.stream.getOffset() - this.offset; | ||
parse({ introducer: e, label: i }) { | ||
this.offset = this.stream.getOffset(), this.comment = this.readSubBlocks(), this.length = this.stream.getOffset() - this.offset; | ||
} | ||
@@ -391,3 +309,3 @@ export() { | ||
length: this.length, | ||
bytes: getBytes(this.stream, this.offset, this.length), | ||
bytes: b(this.stream, this.offset, this.length), | ||
data: this.comment | ||
@@ -397,31 +315,20 @@ }; | ||
} | ||
class PlainTextExtension extends BaseExtension { | ||
constructor(stream) { | ||
super(stream); | ||
__publicField(this, "type", "PlainTextExtension"); | ||
__publicField(this, "blockSize", 0); | ||
__publicField(this, "left", 0); | ||
__publicField(this, "top", 0); | ||
__publicField(this, "width", 0); | ||
__publicField(this, "height", 0); | ||
__publicField(this, "cellWidth", 0); | ||
__publicField(this, "cellHeight", 0); | ||
__publicField(this, "foregroundColorIndex", 0); | ||
__publicField(this, "backgroundColorIndex", 0); | ||
__publicField(this, "data", {}); | ||
this.stream = stream; | ||
class V extends x { | ||
constructor(e) { | ||
super(e); | ||
s(this, "type", "PlainTextExtension"); | ||
s(this, "blockSize", 0); | ||
s(this, "left", 0); | ||
s(this, "top", 0); | ||
s(this, "width", 0); | ||
s(this, "height", 0); | ||
s(this, "cellWidth", 0); | ||
s(this, "cellHeight", 0); | ||
s(this, "foregroundColorIndex", 0); | ||
s(this, "backgroundColorIndex", 0); | ||
s(this, "data", {}); | ||
this.stream = e; | ||
} | ||
parse({ introducer, label }) { | ||
this.offset = this.stream.getOffset(); | ||
this.blockSize = this.stream.readUint8(); | ||
this.left = this.stream.readUint16(); | ||
this.top = this.stream.readUint16(); | ||
this.width = this.stream.readUint16(); | ||
this.height = this.stream.readUint16(); | ||
this.cellWidth = this.stream.readUint8(); | ||
this.cellHeight = this.stream.readUint8(); | ||
this.foregroundColorIndex = this.stream.readUint8(); | ||
this.backgroundColorIndex = this.stream.readUint8(); | ||
this.data = this.readSubBlocks(); | ||
this.length = this.stream.getOffset() - this.offset; | ||
parse({ introducer: e, label: i }) { | ||
this.offset = this.stream.getOffset(), this.blockSize = this.stream.readUint8(), this.left = this.stream.readUint16(), this.top = this.stream.readUint16(), this.width = this.stream.readUint16(), this.height = this.stream.readUint16(), this.cellWidth = this.stream.readUint8(), this.cellHeight = this.stream.readUint8(), this.foregroundColorIndex = this.stream.readUint8(), this.backgroundColorIndex = this.stream.readUint8(), this.data = this.readSubBlocks(), this.length = this.stream.getOffset() - this.offset; | ||
} | ||
@@ -433,3 +340,3 @@ export() { | ||
length: this.length, | ||
bytes: getBytes(this.stream, this.offset, this.length), | ||
bytes: b(this.stream, this.offset, this.length), | ||
data: this.data | ||
@@ -439,24 +346,18 @@ }; | ||
} | ||
class NetscapeExtension extends BaseExtension { | ||
constructor(stream) { | ||
super(stream); | ||
__publicField(this, "type", "NetscapeExtension"); | ||
__publicField(this, "offset", 0); | ||
__publicField(this, "length", 0); | ||
__publicField(this, "bytes", new Uint8Array(0)); | ||
__publicField(this, "blockSize", 0); | ||
__publicField(this, "subblock", 0); | ||
__publicField(this, "loop", 0); | ||
__publicField(this, "terminator", 0); | ||
__publicField(this, "decode", ""); | ||
this.stream = stream; | ||
class M extends x { | ||
constructor(e) { | ||
super(e); | ||
s(this, "type", "NetscapeExtension"); | ||
s(this, "offset", 0); | ||
s(this, "length", 0); | ||
s(this, "bytes", new Uint8Array(0)); | ||
s(this, "blockSize", 0); | ||
s(this, "subblock", 0); | ||
s(this, "loop", 0); | ||
s(this, "terminator", 0); | ||
s(this, "decode", ""); | ||
this.stream = e; | ||
} | ||
parse({ introducer, label }) { | ||
this.offset = this.stream.getOffset(); | ||
this.blockSize = this.stream.readUint8(); | ||
this.subblock = this.stream.readUint8(); | ||
this.loop = this.stream.readUint16(); | ||
this.terminator = this.stream.readInt8(); | ||
this.decode = `Loop: ${this.loop > 0 ? this.loop : "forever"}`; | ||
this.length = this.stream.getOffset() - this.offset; | ||
parse({ introducer: e, label: i }) { | ||
this.offset = this.stream.getOffset(), this.blockSize = this.stream.readUint8(), this.subblock = this.stream.readUint8(), this.loop = this.stream.readUint16(), this.terminator = this.stream.readInt8(), this.decode = `Loop: ${this.loop > 0 ? this.loop : "forever"}`, this.length = this.stream.getOffset() - this.offset; | ||
} | ||
@@ -468,3 +369,3 @@ export() { | ||
length: this.length, | ||
bytes: getBytes(this.stream, this.offset, this.length), | ||
bytes: b(this.stream, this.offset, this.length), | ||
data: { | ||
@@ -480,151 +381,107 @@ blockSize: this.blockSize, | ||
} | ||
const _XMP = class { | ||
constructor(source) { | ||
__publicField(this, "buffer", null); | ||
if (source instanceof ArrayBuffer) { | ||
this.buffer = source; | ||
} else if (source instanceof Uint8Array) { | ||
this.buffer = source.buffer; | ||
} else if (typeof source === "string" || source instanceof String) { | ||
this.fromDataUri(source); | ||
} | ||
const g = class { | ||
constructor(t) { | ||
s(this, "buffer", null); | ||
t instanceof ArrayBuffer ? this.buffer = t : t instanceof Uint8Array ? this.buffer = t.buffer : (typeof t == "string" || t instanceof String) && this.fromDataUri(t); | ||
} | ||
static dataUriToBuffer(dataUri) { | ||
let byteString = atob(dataUri.split(",")[1]), length = byteString.length, out = new ArrayBuffer(length), arr = new Uint8Array(out); | ||
for (let i = 0; i < length; i++) { | ||
arr[i] = byteString.charCodeAt(i); | ||
} | ||
return out; | ||
static dataUriToBuffer(t) { | ||
let e = atob(t.split(",")[1]), i = e.length, r = new ArrayBuffer(i), a = new Uint8Array(r); | ||
for (let c = 0; c < i; c++) | ||
a[c] = e.charCodeAt(c); | ||
return r; | ||
} | ||
static find(source) { | ||
let buffer; | ||
if (source instanceof ArrayBuffer) { | ||
buffer = source; | ||
} else if (source instanceof Uint8Array) { | ||
this.buffer = source.buffer; | ||
} else if (typeof source === "string" || source instanceof String) { | ||
buffer = _XMP.dataUriToBuffer(source); | ||
} | ||
let view = new DataView(buffer); | ||
if (!buffer) { | ||
static find(t) { | ||
let e; | ||
t instanceof ArrayBuffer ? e = t : t instanceof Uint8Array ? this.buffer = t.buffer : (typeof t == "string" || t instanceof String) && (e = g.dataUriToBuffer(t)); | ||
let i = new DataView(e); | ||
if (!e) | ||
return; | ||
} | ||
const startStr = "<x:xmpmeta", startStrLength = startStr.length, maxStart = buffer.byteLength - startStrLength, endStr = "x:xmpmeta>", endStrLength = endStr.length, maxEnd = buffer.byteLength - endStrLength; | ||
let start = 2, end = start + startStrLength, found = false; | ||
while (start < maxStart) { | ||
if (_XMP.stringFromBuffer(view, start, startStrLength) == startStr) { | ||
found = true; | ||
const r = "<x:xmpmeta", a = r.length, c = e.byteLength - a, f = "x:xmpmeta>", p = f.length, h = e.byteLength - p; | ||
let n = 2, l = n + a, d = !1; | ||
for (; n < c; ) | ||
if (g.stringFromBuffer(i, n, a) == r) { | ||
d = !0; | ||
break; | ||
} else { | ||
start++; | ||
} | ||
} | ||
if (!found) { | ||
console.warn("XMP not found"); | ||
return null; | ||
} | ||
while (end < maxEnd) { | ||
if (_XMP.stringFromBuffer(view, end, endStrLength) == endStr) { | ||
break; | ||
} else { | ||
end++; | ||
} | ||
} | ||
end += endStrLength; | ||
return _XMP.stringFromBuffer(view, start, end - start); | ||
} else | ||
n++; | ||
if (!d) | ||
return console.warn("XMP not found"), null; | ||
for (; l < h && g.stringFromBuffer(i, l, p) != f; ) | ||
l++; | ||
return l += p, g.stringFromBuffer(i, n, l - n); | ||
} | ||
static stringFromBuffer(buffer, start, length) { | ||
let out = ""; | ||
for (let i = start; i < start + length; i++) { | ||
out += String.fromCharCode(buffer.getUint8(i)); | ||
} | ||
return out; | ||
static stringFromBuffer(t, e, i) { | ||
let r = ""; | ||
for (let a = e; a < e + i; a++) | ||
r += String.fromCharCode(t.getUint8(a)); | ||
return r; | ||
} | ||
static execFind(str, reg) { | ||
let result = []; | ||
let isEmpty = true; | ||
while (isEmpty) { | ||
let regRxpRxecArray = reg.exec(str); | ||
if (regRxpRxecArray) { | ||
result.push(regRxpRxecArray); | ||
} else { | ||
isEmpty = false; | ||
} | ||
static execFind(t, e) { | ||
let i = [], r = !0; | ||
for (; r; ) { | ||
let a = e.exec(t); | ||
a ? i.push(a) : r = !1; | ||
} | ||
return result; | ||
return i; | ||
} | ||
static toTree(result) { | ||
let tree = []; | ||
if (!result || !result.length) { | ||
return tree; | ||
} | ||
const first = result.shift(); | ||
const firstEndIndex = result.findIndex((item) => { | ||
return `</${first.tag}>` === item.raw; | ||
}); | ||
result.splice(firstEndIndex, 1); | ||
tree.push(__spreadProps(__spreadValues({}, first), { | ||
children: _XMP.toTree(result) | ||
})); | ||
return tree; | ||
static toTree(t) { | ||
let e = []; | ||
if (!t || !t.length) | ||
return e; | ||
const i = t.shift(), r = t.findIndex((a) => `</${i.tag}>` === a.raw); | ||
return t.splice(r, 1), e.push({ | ||
...i, | ||
children: g.toTree(t) | ||
}), e; | ||
} | ||
static parse(xmp) { | ||
if (!xmp) { | ||
static parse(t) { | ||
if (!t) | ||
return null; | ||
} | ||
const lineReg = new RegExp(`<[^>]+>`, "gi"); | ||
const lineList = _XMP.execFind(xmp, lineReg); | ||
const out = lineList.map((item, i) => { | ||
const tagReg = new RegExp("<(.*?)\\s", "g"); | ||
const attrReg = new RegExp('\\s(.*?)="(.*?)"', "g"); | ||
const raw = item[0]; | ||
const tagRes = tagReg.exec(raw); | ||
const attrExecList = _XMP.execFind(raw, attrReg); | ||
let attrs = {}; | ||
attrExecList.forEach((element) => { | ||
const [, key, value] = element; | ||
attrs[key] = value; | ||
}); | ||
return { | ||
raw, | ||
tag: tagRes ? tagRes[1] : null, | ||
attrs | ||
const e = new RegExp("<[^>]+>", "gi"), r = g.execFind(t, e).map((a, c) => { | ||
const f = new RegExp("<(.*?)\\s", "g"), p = new RegExp('\\s(.*?)="(.*?)"', "g"), h = a[0], n = f.exec(h), l = g.execFind(h, p); | ||
let d = {}; | ||
return l.forEach((y) => { | ||
const [, k, C] = y; | ||
d[k] = C; | ||
}), { | ||
raw: h, | ||
tag: n ? n[1] : null, | ||
attrs: d | ||
}; | ||
}); | ||
return _XMP.toTree(out); | ||
return g.toTree(r); | ||
} | ||
fromDataUri(dataUri) { | ||
this.buffer = _XMP.dataUriToBuffer(dataUri); | ||
fromDataUri(t) { | ||
this.buffer = g.dataUriToBuffer(t); | ||
} | ||
find() { | ||
return _XMP.find(this.buffer) || ""; | ||
return g.find(this.buffer) || ""; | ||
} | ||
parse() { | ||
let xmp = this.find(); | ||
return _XMP.parse(xmp); | ||
let t = this.find(); | ||
return g.parse(t); | ||
} | ||
}; | ||
let XMP = _XMP; | ||
__publicField(XMP, "buffer", null); | ||
class XMPDataExtension extends BaseExtension { | ||
constructor(stream) { | ||
super(stream); | ||
__publicField(this, "type", "XMPDataExtension"); | ||
__publicField(this, "offset", 0); | ||
__publicField(this, "length", 0); | ||
__publicField(this, "bytes", new Uint8Array(0)); | ||
__publicField(this, "blockSize", 0); | ||
__publicField(this, "xmpData", []); | ||
this.stream = stream; | ||
let w = g; | ||
s(w, "buffer", null); | ||
class P extends x { | ||
constructor(e) { | ||
super(e); | ||
s(this, "type", "XMPDataExtension"); | ||
s(this, "offset", 0); | ||
s(this, "length", 0); | ||
s(this, "bytes", new Uint8Array(0)); | ||
s(this, "blockSize", 0); | ||
s(this, "xmpData", []); | ||
this.stream = e; | ||
} | ||
parse({ introducer, label }) { | ||
parse({ introducer: e, label: i }) { | ||
this.offset = this.stream.getOffset(); | ||
const { blocks } = this.readSubBlocks(); | ||
blocks.forEach((item) => { | ||
this.blockSize += item.length; | ||
const { blocks: r } = this.readSubBlocks(); | ||
r.forEach((f) => { | ||
this.blockSize += f.length; | ||
}); | ||
const arrayBuffer = this.stream.slice(this.offset, this.blockSize); | ||
let xmp = new XMP(arrayBuffer); | ||
this.xmpData = xmp.parse(); | ||
this.length = this.stream.getOffset() - this.offset; | ||
const a = this.stream.slice(this.offset, this.blockSize); | ||
let c = new w(a); | ||
this.xmpData = c.parse(), this.length = this.stream.getOffset() - this.offset; | ||
} | ||
@@ -636,3 +493,3 @@ export() { | ||
length: this.length, | ||
bytes: getBytes(this.stream, this.offset, this.length), | ||
bytes: b(this.stream, this.offset, this.length), | ||
data: { | ||
@@ -645,17 +502,14 @@ blockSize: this.blockSize, | ||
} | ||
class UnknownApplicationExtension extends BaseExtension { | ||
constructor(stream) { | ||
super(stream); | ||
__publicField(this, "type", "UnknownApplicationExtension"); | ||
__publicField(this, "offset", 0); | ||
__publicField(this, "length", 0); | ||
__publicField(this, "bytes", new Uint8Array(0)); | ||
__publicField(this, "appData", {}); | ||
this.stream = stream; | ||
class N extends x { | ||
constructor(e) { | ||
super(e); | ||
s(this, "type", "UnknownApplicationExtension"); | ||
s(this, "offset", 0); | ||
s(this, "length", 0); | ||
s(this, "bytes", new Uint8Array(0)); | ||
s(this, "appData", {}); | ||
this.stream = e; | ||
} | ||
parse({ introducer, label }) { | ||
console.log("introducer, label", introducer, label); | ||
this.offset = this.stream.getOffset(); | ||
this.appData = this.readSubBlocks(); | ||
this.length = this.stream.getOffset() - this.offset; | ||
parse({ introducer: e, label: i }) { | ||
console.log("introducer, label", e, i), this.offset = this.stream.getOffset(), this.appData = this.readSubBlocks(), this.length = this.stream.getOffset() - this.offset; | ||
} | ||
@@ -667,3 +521,3 @@ export() { | ||
length: this.length, | ||
bytes: getBytes(this.stream, this.offset, this.length), | ||
bytes: b(this.stream, this.offset, this.length), | ||
data: this.appData | ||
@@ -673,42 +527,22 @@ }; | ||
} | ||
class ApplicationExtension extends BaseExtension { | ||
constructor(stream) { | ||
super(stream); | ||
__publicField(this, "type", "ApplicationExtension"); | ||
__publicField(this, "offset", 0); | ||
__publicField(this, "length", 0); | ||
__publicField(this, "bytes", new Uint8Array(0)); | ||
__publicField(this, "introducer", ""); | ||
__publicField(this, "label", ""); | ||
__publicField(this, "blockSize", 0); | ||
__publicField(this, "identifier", ""); | ||
__publicField(this, "authenticationCode", ""); | ||
__publicField(this, "appData"); | ||
__publicField(this, "netscapeExtension"); | ||
__publicField(this, "xmpdataExtension"); | ||
__publicField(this, "unknownApplicationExtension"); | ||
this.stream = stream; | ||
this.netscapeExtension = new NetscapeExtension(stream); | ||
this.xmpdataExtension = new XMPDataExtension(stream); | ||
this.unknownApplicationExtension = new UnknownApplicationExtension(stream); | ||
this.appData = {}; | ||
class $ extends x { | ||
constructor(e) { | ||
super(e); | ||
s(this, "type", "ApplicationExtension"); | ||
s(this, "offset", 0); | ||
s(this, "length", 0); | ||
s(this, "bytes", new Uint8Array(0)); | ||
s(this, "introducer", ""); | ||
s(this, "label", ""); | ||
s(this, "blockSize", 0); | ||
s(this, "identifier", ""); | ||
s(this, "authenticationCode", ""); | ||
s(this, "appData"); | ||
s(this, "netscapeExtension"); | ||
s(this, "xmpdataExtension"); | ||
s(this, "unknownApplicationExtension"); | ||
this.stream = e, this.netscapeExtension = new M(e), this.xmpdataExtension = new P(e), this.unknownApplicationExtension = new N(e), this.appData = {}; | ||
} | ||
parse({ introducer = 0, label = 0 }) { | ||
this.introducer = String.fromCharCode(introducer); | ||
this.label = numberToHex(label); | ||
this.offset = this.stream.getOffset() - 2; | ||
this.blockSize = this.stream.readInt8(); | ||
this.identifier = this.stream.readString(8); | ||
this.authenticationCode = this.stream.readString(3); | ||
if (this.identifier === "NETSCAPE") { | ||
this.netscapeExtension.parse({ introducer, label }); | ||
this.appData = this.netscapeExtension.export(); | ||
} else if (this.identifier === "XMP Data") { | ||
this.xmpdataExtension.parse({ introducer, label }); | ||
this.appData = this.xmpdataExtension.export(); | ||
} else { | ||
this.unknownApplicationExtension.parse({ introducer, label }); | ||
this.appData = this.unknownApplicationExtension.export(); | ||
} | ||
this.length = this.stream.getOffset() - this.offset; | ||
parse({ introducer: e = 0, label: i = 0 }) { | ||
this.introducer = String.fromCharCode(e), this.label = U(i), this.offset = this.stream.getOffset() - 2, this.blockSize = this.stream.readInt8(), this.identifier = this.stream.readString(8), this.authenticationCode = this.stream.readString(3), this.identifier === "NETSCAPE" ? (this.netscapeExtension.parse({ introducer: e, label: i }), this.appData = this.netscapeExtension.export()) : this.identifier === "XMP Data" ? (this.xmpdataExtension.parse({ introducer: e, label: i }), this.appData = this.xmpdataExtension.export()) : (this.unknownApplicationExtension.parse({ introducer: e, label: i }), this.appData = this.unknownApplicationExtension.export()), this.length = this.stream.getOffset() - this.offset; | ||
} | ||
@@ -720,3 +554,3 @@ export() { | ||
length: this.length, | ||
bytes: getBytes(this.stream, this.offset, this.length), | ||
bytes: b(this.stream, this.offset, this.length), | ||
data: { | ||
@@ -733,13 +567,11 @@ introducer: this.introducer, | ||
} | ||
class UnknownExtension extends BaseExtension { | ||
constructor(stream) { | ||
super(stream); | ||
__publicField(this, "type", "UnknownExtension"); | ||
__publicField(this, "data", {}); | ||
this.stream = stream; | ||
class H extends x { | ||
constructor(e) { | ||
super(e); | ||
s(this, "type", "UnknownExtension"); | ||
s(this, "data", {}); | ||
this.stream = e; | ||
} | ||
parse({ introducer, label }) { | ||
this.offset = this.stream.getOffset(); | ||
this.data = this.readSubBlocks(); | ||
this.length = this.stream.getOffset() - this.offset; | ||
parse({ introducer: e, label: i }) { | ||
this.offset = this.stream.getOffset(), this.data = this.readSubBlocks(), this.length = this.stream.getOffset() - this.offset; | ||
} | ||
@@ -751,3 +583,3 @@ export() { | ||
length: this.length, | ||
bytes: getBytes(this.stream, this.offset, this.length), | ||
bytes: b(this.stream, this.offset, this.length), | ||
data: this.data | ||
@@ -757,44 +589,29 @@ }; | ||
} | ||
class Extension { | ||
constructor(stream) { | ||
__publicField(this, "extensionBlock", {}); | ||
__publicField(this, "graphicsControlExtension"); | ||
__publicField(this, "plainTextExtension"); | ||
__publicField(this, "commentExtension"); | ||
__publicField(this, "applicationExtension"); | ||
__publicField(this, "unknownExtension"); | ||
this.stream = stream; | ||
this.stream = stream; | ||
this.graphicsControlExtension = new GraphicsControlExtension(stream); | ||
this.commentExtension = new CommentExtension(stream); | ||
this.plainTextExtension = new PlainTextExtension(stream); | ||
this.applicationExtension = new ApplicationExtension(stream); | ||
this.unknownExtension = new UnknownExtension(stream); | ||
class W { | ||
constructor(t) { | ||
s(this, "extensionBlock", {}); | ||
s(this, "graphicsControlExtension"); | ||
s(this, "plainTextExtension"); | ||
s(this, "commentExtension"); | ||
s(this, "applicationExtension"); | ||
s(this, "unknownExtension"); | ||
this.stream = t, this.stream = t, this.graphicsControlExtension = new R(t), this.commentExtension = new G(t), this.plainTextExtension = new V(t), this.applicationExtension = new $(t), this.unknownExtension = new H(t); | ||
} | ||
parse({ introducer }) { | ||
const label = this.stream.readUint8(); | ||
switch (label) { | ||
parse({ introducer: t }) { | ||
const e = this.stream.readUint8(); | ||
switch (e) { | ||
case 249: | ||
{ | ||
this.graphicsControlExtension.parse({ introducer, label }); | ||
this.extensionBlock = this.graphicsControlExtension.export(); | ||
} | ||
this.graphicsControlExtension.parse({ introducer: t, label: e }), this.extensionBlock = this.graphicsControlExtension.export(); | ||
break; | ||
case 254: | ||
this.commentExtension.parse({ introducer, label }); | ||
this.extensionBlock = this.commentExtension.export(); | ||
this.commentExtension.parse({ introducer: t, label: e }), this.extensionBlock = this.commentExtension.export(); | ||
break; | ||
case 1: | ||
this.plainTextExtension.parse({ introducer, label }); | ||
this.extensionBlock = this.plainTextExtension.export(); | ||
this.plainTextExtension.parse({ introducer: t, label: e }), this.extensionBlock = this.plainTextExtension.export(); | ||
break; | ||
case 255: | ||
{ | ||
this.applicationExtension.parse({ introducer, label }); | ||
this.extensionBlock = this.applicationExtension.export(); | ||
} | ||
this.applicationExtension.parse({ introducer: t, label: e }), this.extensionBlock = this.applicationExtension.export(); | ||
break; | ||
default: | ||
this.unknownExtension.parse({ introducer, label }); | ||
this.extensionBlock = this.unknownExtension.export(); | ||
this.unknownExtension.parse({ introducer: t, label: e }), this.extensionBlock = this.unknownExtension.export(); | ||
break; | ||
@@ -807,26 +624,25 @@ } | ||
} | ||
class LocalColorTable extends ColorTable { | ||
constructor(stream) { | ||
super(stream, "LocalColorTable"); | ||
class j extends F { | ||
constructor(t) { | ||
super(t, "LocalColorTable"); | ||
} | ||
} | ||
class ImageDescriptor { | ||
constructor(stream) { | ||
__publicField(this, "type", "ImageDescriptor"); | ||
__publicField(this, "offset", 0); | ||
__publicField(this, "length", 0); | ||
__publicField(this, "bytes", new Uint8Array(0)); | ||
__publicField(this, "introducer", ""); | ||
__publicField(this, "left", 0); | ||
__publicField(this, "top", 0); | ||
__publicField(this, "width", 0); | ||
__publicField(this, "height", 0); | ||
__publicField(this, "packedFields", []); | ||
__publicField(this, "localColorTableFlag", 0); | ||
__publicField(this, "interlaceFlag", 0); | ||
__publicField(this, "sortFlag", 0); | ||
__publicField(this, "reserved", []); | ||
__publicField(this, "localColorTableSize", 0); | ||
this.stream = stream; | ||
this.stream = stream; | ||
class X { | ||
constructor(t) { | ||
s(this, "type", "ImageDescriptor"); | ||
s(this, "offset", 0); | ||
s(this, "length", 0); | ||
s(this, "bytes", new Uint8Array(0)); | ||
s(this, "introducer", ""); | ||
s(this, "left", 0); | ||
s(this, "top", 0); | ||
s(this, "width", 0); | ||
s(this, "height", 0); | ||
s(this, "packedFields", []); | ||
s(this, "localColorTableFlag", 0); | ||
s(this, "interlaceFlag", 0); | ||
s(this, "sortFlag", 0); | ||
s(this, "reserved", []); | ||
s(this, "localColorTableSize", 0); | ||
this.stream = t, this.stream = t; | ||
} | ||
@@ -839,17 +655,6 @@ hasLocalColorTable() { | ||
} | ||
parse({ introducer = 0 }) { | ||
this.introducer = String.fromCharCode(introducer); | ||
this.offset = this.stream.getOffset() - 1; | ||
this.left = this.stream.readUint16(); | ||
this.top = this.stream.readUint16(); | ||
this.width = this.stream.readUint16(); | ||
this.height = this.stream.readUint16(); | ||
this.packedFields = byteToBits(this.stream.readUint8()); | ||
const bits = [...this.packedFields]; | ||
this.localColorTableFlag = bits.shift() || 0; | ||
this.interlaceFlag = bits.shift() || 0; | ||
this.sortFlag = bits.shift() || 0; | ||
this.reserved = bits.splice(0, 2); | ||
this.localColorTableSize = bitsToNumber(bits.splice(0, 3)); | ||
this.length = this.stream.getOffset() - this.offset; | ||
parse({ introducer: t = 0 }) { | ||
this.introducer = String.fromCharCode(t), this.offset = this.stream.getOffset() - 1, this.left = this.stream.readUint16(), this.top = this.stream.readUint16(), this.width = this.stream.readUint16(), this.height = this.stream.readUint16(), this.packedFields = T(this.stream.readUint8()); | ||
const e = [...this.packedFields]; | ||
this.localColorTableFlag = e.shift() || 0, this.interlaceFlag = e.shift() || 0, this.sortFlag = e.shift() || 0, this.reserved = e.splice(0, 2), this.localColorTableSize = S(e.splice(0, 3)), this.length = this.stream.getOffset() - this.offset; | ||
} | ||
@@ -861,3 +666,3 @@ export() { | ||
length: this.length, | ||
bytes: getBytes(this.stream, this.offset, this.length), | ||
bytes: b(this.stream, this.offset, this.length), | ||
data: { | ||
@@ -879,67 +684,40 @@ introducer: this.introducer, | ||
} | ||
class BitReader { | ||
constructor(bytes) { | ||
__publicField(this, "bytes"); | ||
__publicField(this, "byteOffset"); | ||
__publicField(this, "bitOffset"); | ||
__publicField(this, "totalByteOffset"); | ||
this.bytes = bytes || new Int8Array(); | ||
this.byteOffset = 0; | ||
this.bitOffset = 0; | ||
this.totalByteOffset = 0; | ||
class q { | ||
constructor(t) { | ||
s(this, "bytes"); | ||
s(this, "byteOffset"); | ||
s(this, "bitOffset"); | ||
s(this, "totalByteOffset"); | ||
this.bytes = t || new Int8Array(), this.byteOffset = 0, this.bitOffset = 0, this.totalByteOffset = 0; | ||
} | ||
readBits(len) { | ||
let result = 0; | ||
let rbits = 0; | ||
while (rbits < len) { | ||
if (this.byteOffset >= this.bytes.length) { | ||
throw new Error(`Not enough bytes to read ${len} bits (read ${rbits} bits)`); | ||
} | ||
const bbits = Math.min(8 - this.bitOffset, len - rbits); | ||
const mask = 255 >> 8 - bbits << this.bitOffset; | ||
result += (this.bytes[this.byteOffset] & mask) >> this.bitOffset << rbits; | ||
rbits += bbits; | ||
this.bitOffset += bbits; | ||
if (this.bitOffset === 8) { | ||
this.byteOffset += 1; | ||
this.totalByteOffset += 1; | ||
this.bitOffset = 0; | ||
} | ||
readBits(t) { | ||
let e = 0, i = 0; | ||
for (; i < t; ) { | ||
if (this.byteOffset >= this.bytes.length) | ||
throw new Error(`Not enough bytes to read ${t} bits (read ${i} bits)`); | ||
const r = Math.min(8 - this.bitOffset, t - i), a = 255 >> 8 - r << this.bitOffset; | ||
e += (this.bytes[this.byteOffset] & a) >> this.bitOffset << i, i += r, this.bitOffset += r, this.bitOffset === 8 && (this.byteOffset += 1, this.totalByteOffset += 1, this.bitOffset = 0); | ||
} | ||
return result; | ||
return e; | ||
} | ||
hasBits(len = 1) { | ||
if (len > 12) { | ||
throw new Error(`Exceeds max bit size: ${len} (max: 12)`); | ||
} | ||
hasBits(t = 1) { | ||
if (t > 12) | ||
throw new Error(`Exceeds max bit size: ${t} (max: 12)`); | ||
if (this.byteOffset >= this.bytes.length) | ||
return false; | ||
const bitsRemain = 8 - this.bitOffset; | ||
if (len <= bitsRemain) | ||
return true; | ||
const bytesRemain = this.bytes.length - this.byteOffset - 1; | ||
if (bytesRemain < 1) | ||
return false; | ||
if (len > bitsRemain + 8 * bytesRemain) | ||
return false; | ||
return true; | ||
return !1; | ||
const e = 8 - this.bitOffset; | ||
if (t <= e) | ||
return !0; | ||
const i = this.bytes.length - this.byteOffset - 1; | ||
return !(i < 1 || t > e + 8 * i); | ||
} | ||
setBytes(bytes, byteOffset = 0, bitOffset = 0) { | ||
this.bytes = bytes; | ||
this.byteOffset = byteOffset; | ||
this.bitOffset = bitOffset; | ||
setBytes(t, e = 0, i = 0) { | ||
this.bytes = t, this.byteOffset = e, this.bitOffset = i; | ||
} | ||
pushBytes(bytes) { | ||
pushBytes(t) { | ||
if (this.hasBits()) { | ||
const remainBytes = this.bytes.length - this.byteOffset; | ||
const extended = new Uint8Array(remainBytes + bytes.length); | ||
extended.set(this.bytes.slice(this.byteOffset)); | ||
extended.set(bytes, remainBytes); | ||
this.bytes = extended; | ||
this.byteOffset = 0; | ||
} else { | ||
this.bytes = bytes; | ||
this.byteOffset = 0; | ||
this.bitOffset = 0; | ||
} | ||
const e = this.bytes.length - this.byteOffset, i = new Uint8Array(e + t.length); | ||
i.set(this.bytes.slice(this.byteOffset)), i.set(t, e), this.bytes = i, this.byteOffset = 0; | ||
} else | ||
this.bytes = t, this.byteOffset = 0, this.bitOffset = 0; | ||
} | ||
@@ -953,82 +731,48 @@ getState() { | ||
} | ||
class ImageContent { | ||
constructor(stream) { | ||
__publicField(this, "type", "ImageContent"); | ||
__publicField(this, "offset", 0); | ||
__publicField(this, "length", 0); | ||
__publicField(this, "bytes", new Uint8Array(0)); | ||
__publicField(this, "children", {}); | ||
this.stream = stream; | ||
this.stream = stream; | ||
class J { | ||
constructor(t) { | ||
s(this, "type", "ImageContent"); | ||
s(this, "offset", 0); | ||
s(this, "length", 0); | ||
s(this, "bytes", new Uint8Array(0)); | ||
s(this, "children", {}); | ||
this.stream = t, this.stream = t; | ||
} | ||
parse() { | ||
this.offset = this.stream.getOffset(); | ||
const lzwData = this.readImageContent(); | ||
this.children = this.lzwDecode(lzwData); | ||
this.length = this.stream.getOffset() - this.offset; | ||
const t = this.readImageContent(); | ||
this.children = this.lzwDecode(t), this.length = this.stream.getOffset() - this.offset; | ||
} | ||
lzwDecode(data) { | ||
const { blocks, lzwMinimumCodeSize } = data; | ||
const indexStream = []; | ||
const codeUnits = []; | ||
let codeStream = []; | ||
let codeTable = []; | ||
const br = new BitReader(); | ||
const clearCode = 2 << lzwMinimumCodeSize - 1; | ||
const eoiCode = clearCode + 1; | ||
let lastCode = eoiCode; | ||
let size = lzwMinimumCodeSize + 1; | ||
let growCode = (2 << size - 1) - 1; | ||
let isInitialized = false; | ||
for (const { offset, length } of blocks) { | ||
br.pushBytes(this.stream.slice(offset, length)); | ||
while (br.hasBits(size)) { | ||
const codeStart = br.getState(); | ||
const code = br.readBits(size); | ||
if (code === eoiCode) { | ||
codeStream.push(code); | ||
lzwDecode(t) { | ||
const { blocks: e, lzwMinimumCodeSize: i } = t, r = [], a = []; | ||
let c = [], f = []; | ||
const p = new q(), h = 2 << i - 1, n = h + 1; | ||
let l = n, d = i + 1, y = (2 << d - 1) - 1, k = !1; | ||
for (const { offset: C, length: D } of e) | ||
for (p.pushBytes(this.stream.slice(C, D)); p.hasBits(d); ) { | ||
const O = p.getState(), m = p.readBits(d); | ||
if (m === n) { | ||
c.push(m); | ||
break; | ||
} else if (code === clearCode) { | ||
codeUnits.push({ stream: [], table: [], start: codeStart }); | ||
codeStream = codeUnits[codeUnits.length - 1].stream; | ||
codeTable = codeUnits[codeUnits.length - 1].table; | ||
for (let i = 0; i <= eoiCode; i++) { | ||
codeTable[i] = i < clearCode ? [i] : []; | ||
} | ||
lastCode = eoiCode; | ||
size = lzwMinimumCodeSize + 1; | ||
growCode = (2 << size - 1) - 1; | ||
isInitialized = false; | ||
} else if (!isInitialized) { | ||
indexStream.push(...codeTable[code]); | ||
isInitialized = true; | ||
} else { | ||
let k = 0; | ||
const prevCode = codeStream[codeStream.length - 1]; | ||
if (code <= lastCode) { | ||
indexStream.push(...codeTable[code]); | ||
k = codeTable[code][0]; | ||
} else { | ||
k = codeTable[prevCode][0]; | ||
indexStream.push(...codeTable[prevCode], k); | ||
} | ||
if (lastCode < 4095) { | ||
lastCode += 1; | ||
codeTable[lastCode] = [...codeTable[prevCode], k]; | ||
if (lastCode === growCode && lastCode < 4095) { | ||
size += 1; | ||
growCode = (2 << size - 1) - 1; | ||
} | ||
} | ||
} else if (m === h) { | ||
a.push({ stream: [], table: [], start: O }), c = a[a.length - 1].stream, f = a[a.length - 1].table; | ||
for (let u = 0; u <= n; u++) | ||
f[u] = u < h ? [u] : []; | ||
l = n, d = i + 1, y = (2 << d - 1) - 1, k = !1; | ||
} else if (!k) | ||
r.push(...f[m]), k = !0; | ||
else { | ||
let u = 0; | ||
const E = c[c.length - 1]; | ||
m <= l ? (r.push(...f[m]), u = f[m][0]) : (u = f[E][0], r.push(...f[E], u)), l < 4095 && (l += 1, f[l] = [...f[E], u], l === y && l < 4095 && (d += 1, y = (2 << d - 1) - 1)); | ||
} | ||
codeStream.push(code); | ||
c.push(m); | ||
} | ||
} | ||
return Object.assign({}, data, { | ||
indexStream, | ||
clearCode, | ||
eoiCode, | ||
codeUnits, | ||
blockCount: blocks.length, | ||
codeUnitCount: codeUnits.length | ||
return Object.assign({}, t, { | ||
indexStream: r, | ||
clearCode: h, | ||
eoiCode: n, | ||
codeUnits: a, | ||
blockCount: e.length, | ||
codeUnitCount: a.length | ||
}); | ||
@@ -1041,3 +785,3 @@ } | ||
length: this.length, | ||
bytes: getBytes(this.stream, this.offset, this.length), | ||
bytes: b(this.stream, this.offset, this.length), | ||
data: this.children | ||
@@ -1047,79 +791,59 @@ }; | ||
readImageContent() { | ||
const offset = this.stream.getOffset(); | ||
const lzwMinimumCodeSize = this.stream.readUint8(); | ||
let { blocks } = this.readSubBlocks(); | ||
const length = this.stream.getOffset() - offset; | ||
const t = this.stream.getOffset(), e = this.stream.readUint8(); | ||
let { blocks: i } = this.readSubBlocks(); | ||
const r = this.stream.getOffset() - t; | ||
return { | ||
offset, | ||
length, | ||
offset: t, | ||
length: r, | ||
type: "image", | ||
lzwMinimumCodeSize, | ||
blocks | ||
lzwMinimumCodeSize: e, | ||
blocks: i | ||
}; | ||
} | ||
readSubBlocks() { | ||
const offset = this.stream.getOffset(); | ||
let blockSize = this.stream.readUint8(); | ||
let length = 1; | ||
const blocks = []; | ||
while (blockSize > 0) { | ||
blocks.push({ offset: offset + length, length: blockSize }); | ||
length += blockSize + 1; | ||
this.stream.seek(blockSize); | ||
blockSize = this.stream.readUint8(); | ||
} | ||
length += 1; | ||
return { | ||
blocks, | ||
blocksLength: length | ||
const t = this.stream.getOffset(); | ||
let e = this.stream.readUint8(), i = 1; | ||
const r = []; | ||
for (; e > 0; ) | ||
r.push({ offset: t + i, length: e }), i += e + 1, this.stream.seek(e), e = this.stream.readUint8(); | ||
return i += 1, { | ||
blocks: r, | ||
blocksLength: i | ||
}; | ||
} | ||
} | ||
class ImageData { | ||
constructor(stream) { | ||
__publicField(this, "localColorTable"); | ||
__publicField(this, "imageDescriptor"); | ||
__publicField(this, "imageContent"); | ||
this.stream = stream; | ||
this.stream = stream; | ||
this.localColorTable = new LocalColorTable(stream); | ||
this.imageDescriptor = new ImageDescriptor(stream); | ||
this.imageContent = new ImageContent(stream); | ||
class K { | ||
constructor(t) { | ||
s(this, "localColorTable"); | ||
s(this, "imageDescriptor"); | ||
s(this, "imageContent"); | ||
this.stream = t, this.stream = t, this.localColorTable = new j(t), this.imageDescriptor = new X(t), this.imageContent = new J(t); | ||
} | ||
parse({ introducer }) { | ||
this.imageDescriptor.parse({ introducer }); | ||
if (this.imageDescriptor.hasLocalColorTable()) { | ||
const localColorTableSize = this.imageDescriptor.getLocalColorTableSize(); | ||
this.localColorTable.parse({ size: localColorTableSize }); | ||
parse({ introducer: t }) { | ||
if (this.imageDescriptor.parse({ introducer: t }), this.imageDescriptor.hasLocalColorTable()) { | ||
const e = this.imageDescriptor.getLocalColorTableSize(); | ||
this.localColorTable.parse({ size: e }); | ||
} | ||
this.imageContent.parse(); | ||
} | ||
createFrame(colorTable, cidx, width, height) { | ||
const canvas = document.createElement("canvas"); | ||
canvas.width = width; | ||
canvas.height = height; | ||
const context = canvas.getContext("2d"); | ||
const imgData = context.createImageData(width, height); | ||
const pixels = imgData.data; | ||
for (let i = 0, poff = 0; i < cidx.length; i += 1, poff += 4) { | ||
pixels[poff + 0] = colorTable[cidx[i]][0]; | ||
pixels[poff + 1] = colorTable[cidx[i]][1]; | ||
pixels[poff + 2] = colorTable[cidx[i]][2]; | ||
pixels[poff + 3] = cidx[i] !== 88 ? 255 : 0; | ||
} | ||
return imgData; | ||
createFrame(t, e, i, r) { | ||
const a = document.createElement("canvas"); | ||
a.width = i, a.height = r; | ||
const f = a.getContext("2d").createImageData(i, r), p = f.data; | ||
for (let h = 0, n = 0; h < e.length; h += 1, n += 4) | ||
p[n + 0] = t[e[h]][0], p[n + 1] = t[e[h]][1], p[n + 2] = t[e[h]][2], p[n + 3] = e[h] !== 88 ? 255 : 0; | ||
return f; | ||
} | ||
exportFrameData(globalColorTableExportData) { | ||
const { width, height, left, top, localColorTableFlag } = this.imageDescriptor.export().data; | ||
const { indexStream } = this.imageContent.export().data; | ||
let colorTableData = this.imageDescriptor.hasLocalColorTable() ? this.localColorTable.export() : globalColorTableExportData || {}; | ||
exportFrameData(t) { | ||
const { width: e, height: i, left: r, top: a, localColorTableFlag: c } = this.imageDescriptor.export().data, { indexStream: f } = this.imageContent.export().data; | ||
let p = this.imageDescriptor.hasLocalColorTable() ? this.localColorTable.export() : t || {}; | ||
return { | ||
type: "Frame", | ||
data: { | ||
width, | ||
height, | ||
left, | ||
top, | ||
localColorTableFlag, | ||
imageData: this.createFrame(colorTableData.data, indexStream, width, height) | ||
width: e, | ||
height: i, | ||
left: r, | ||
top: a, | ||
localColorTableFlag: c, | ||
imageData: this.createFrame(p.data, f, e, i) | ||
} | ||
@@ -1129,36 +853,28 @@ }; | ||
export() { | ||
const id = this.imageDescriptor.export(); | ||
const ic = this.imageContent.export(); | ||
if (!this.imageDescriptor.hasLocalColorTable()) { | ||
return [id, ic]; | ||
} | ||
const lct = this.localColorTable.export(); | ||
return [id, lct, ic]; | ||
const t = this.imageDescriptor.export(), e = this.imageContent.export(); | ||
if (!this.imageDescriptor.hasLocalColorTable()) | ||
return [t, e]; | ||
const i = this.localColorTable.export(); | ||
return [t, i, e]; | ||
} | ||
} | ||
class Block { | ||
constructor(stream) { | ||
__publicField(this, "type", "Block"); | ||
__publicField(this, "offset", 0); | ||
__publicField(this, "length", 0); | ||
__publicField(this, "blocks", []); | ||
__publicField(this, "extension"); | ||
__publicField(this, "imageData"); | ||
this.stream = stream; | ||
this.stream = stream; | ||
this.extension = new Extension(this.stream); | ||
this.imageData = new ImageData(this.stream); | ||
class Q { | ||
constructor(t) { | ||
s(this, "type", "Block"); | ||
s(this, "offset", 0); | ||
s(this, "length", 0); | ||
s(this, "blocks", []); | ||
s(this, "extension"); | ||
s(this, "imageData"); | ||
this.stream = t, this.stream = t, this.extension = new W(this.stream), this.imageData = new K(this.stream); | ||
} | ||
parse(globalColorTableExportData) { | ||
this.offset = this.stream.getOffset(); | ||
while (this.stream.hasMore()) { | ||
const introducer = this.stream.readUint8(); | ||
switch (String.fromCharCode(introducer)) { | ||
parse(t) { | ||
for (this.offset = this.stream.getOffset(); this.stream.hasMore(); ) { | ||
const e = this.stream.readUint8(); | ||
switch (String.fromCharCode(e)) { | ||
case "!": | ||
this.extension.parse({ introducer }); | ||
this.blocks.push(this.extension.export()); | ||
this.extension.parse({ introducer: e }), this.blocks.push(this.extension.export()); | ||
break; | ||
case ",": | ||
this.imageData.parse({ introducer }); | ||
this.blocks.push(...this.imageData.export()); | ||
this.imageData.parse({ introducer: e }), this.blocks.push(...this.imageData.export()); | ||
break; | ||
@@ -1169,3 +885,3 @@ case ";": | ||
default: | ||
throw new Error("Unknown block: 0x" + introducer.toString(16)); | ||
throw new Error("Unknown block: 0x" + e.toString(16)); | ||
} | ||
@@ -1179,57 +895,33 @@ } | ||
} | ||
class Parser { | ||
constructor(arrayBuffer) { | ||
__publicField(this, "parsed"); | ||
__publicField(this, "blockList"); | ||
__publicField(this, "dataList"); | ||
__publicField(this, "stream"); | ||
__publicField(this, "header"); | ||
__publicField(this, "logicalScreenDescriptor"); | ||
__publicField(this, "globalColorTable"); | ||
__publicField(this, "block"); | ||
__publicField(this, "isExport", false); | ||
console.log("GifParser init"); | ||
this.parsed = false; | ||
this.blockList = []; | ||
this.dataList = []; | ||
this.stream = new Stream(arrayBuffer, true); | ||
this.header = new Header(this.stream); | ||
this.logicalScreenDescriptor = new LogicalScreenDescriptor(this.stream); | ||
this.globalColorTable = new GlobalColorTable(this.stream); | ||
this.block = new Block(this.stream); | ||
this.parse(); | ||
class _ { | ||
constructor(t) { | ||
s(this, "parsed"); | ||
s(this, "blockList"); | ||
s(this, "dataList"); | ||
s(this, "stream"); | ||
s(this, "header"); | ||
s(this, "logicalScreenDescriptor"); | ||
s(this, "globalColorTable"); | ||
s(this, "block"); | ||
s(this, "isExport", !1); | ||
console.log("GifParser init"), this.parsed = !1, this.blockList = [], this.dataList = [], this.stream = new I(t, !0), this.header = new L(this.stream), this.logicalScreenDescriptor = new A(this.stream), this.globalColorTable = new v(this.stream), this.block = new Q(this.stream), this.parse(); | ||
} | ||
parse() { | ||
if (this.parsed) { | ||
return; | ||
if (!this.parsed) { | ||
if (this.header.parse(), this.logicalScreenDescriptor.parse(), this.logicalScreenDescriptor.hasGlobalColorTable()) { | ||
const t = this.logicalScreenDescriptor.getGlobalColorTableSize(); | ||
this.globalColorTable.parse({ size: t }); | ||
} | ||
this.block.parse(this.logicalScreenDescriptor.hasGlobalColorTable() ? this.globalColorTable.export() : void 0), this.parsed = !0; | ||
} | ||
this.header.parse(); | ||
this.logicalScreenDescriptor.parse(); | ||
if (this.logicalScreenDescriptor.hasGlobalColorTable()) { | ||
const size = this.logicalScreenDescriptor.getGlobalColorTableSize(); | ||
this.globalColorTable.parse({ size }); | ||
} | ||
this.block.parse(this.logicalScreenDescriptor.hasGlobalColorTable() ? this.globalColorTable.export() : void 0); | ||
this.parsed = true; | ||
} | ||
getSize() { | ||
const { data } = this.logicalScreenDescriptor.export(); | ||
return [data.width, data.height]; | ||
const { data: t } = this.logicalScreenDescriptor.export(); | ||
return [t.width, t.height]; | ||
} | ||
export() { | ||
if (this.isExport) { | ||
return; | ||
} | ||
this.blockList.push(this.header.export()); | ||
this.blockList.push(this.logicalScreenDescriptor.export()); | ||
if (this.logicalScreenDescriptor.hasGlobalColorTable()) { | ||
this.blockList.push(this.globalColorTable.export()); | ||
} | ||
this.blockList.push(...this.block.export()); | ||
this.dataHandler(); | ||
this.isExport = true; | ||
this.isExport || (this.blockList.push(this.header.export()), this.blockList.push(this.logicalScreenDescriptor.export()), this.logicalScreenDescriptor.hasGlobalColorTable() && this.blockList.push(this.globalColorTable.export()), this.blockList.push(...this.block.export()), this.dataHandler(), this.isExport = !0); | ||
} | ||
exportWarn() { | ||
console.warn.call(this, `parser.export()`); | ||
return []; | ||
return console.warn.call(this, "parser.export()"), []; | ||
} | ||
@@ -1240,92 +932,65 @@ getBlockList() { | ||
getDataList() { | ||
if (!this.isExport) { | ||
return this.exportWarn(); | ||
} | ||
return this.dataList; | ||
return this.isExport ? this.dataList : this.exportWarn(); | ||
} | ||
createImageData({ colorTable, indexStream, width, height, transparency }) { | ||
const canvas = document.createElement("canvas"); | ||
canvas.width = width; | ||
canvas.height = height; | ||
const context = canvas.getContext("2d"); | ||
const imageData = context.createImageData(width, height); | ||
const pixels = imageData.data; | ||
for (let i = 0, poff = 0; i < indexStream.length; i += 1, poff += 4) { | ||
if (indexStream[i] !== transparency) { | ||
pixels[poff + 0] = colorTable[indexStream[i]][0]; | ||
pixels[poff + 1] = colorTable[indexStream[i]][1]; | ||
pixels[poff + 2] = colorTable[indexStream[i]][2]; | ||
pixels[poff + 3] = 255; | ||
} else { | ||
pixels[poff + 0] = 0; | ||
pixels[poff + 1] = 0; | ||
pixels[poff + 2] = 0; | ||
pixels[poff + 3] = 0; | ||
} | ||
} | ||
return imageData; | ||
createImageData({ colorTable: t, indexStream: e, width: i, height: r, transparency: a }) { | ||
const c = document.createElement("canvas"); | ||
c.width = i, c.height = r; | ||
const p = c.getContext("2d").createImageData(i, r), h = p.data; | ||
for (let n = 0, l = 0; n < e.length; n += 1, l += 4) | ||
e[n] !== a ? (h[l + 0] = t[e[n]][0], h[l + 1] = t[e[n]][1], h[l + 2] = t[e[n]][2], h[l + 3] = 255) : (h[l + 0] = 0, h[l + 1] = 0, h[l + 2] = 0, h[l + 3] = 0); | ||
return p; | ||
} | ||
dataHandler() { | ||
let frameData = {}; | ||
const globalColorTable = this.blockList.find((item) => item.type === "GlobalColorTable"); | ||
this.blockList.forEach((item) => { | ||
if (item.type === "GraphicsControlExtension") { | ||
frameData[item.type] = item.data; | ||
this.dataList.push(item); | ||
} else if (item.type === "ImageDescriptor") { | ||
frameData[item.type] = item.data; | ||
this.dataList.push(item); | ||
} else if (item.type === "ImageContent") { | ||
frameData[item.type] = item.data; | ||
this.dataList.push(item); | ||
const { delayTime, disposalMethod, transparentColorFlag, transparentColorIndex } = frameData.GraphicsControlExtension; | ||
const { localColorTableFlag, left, top, width, height } = frameData.ImageDescriptor; | ||
const { indexStream } = frameData.ImageContent; | ||
const transparency = transparentColorFlag ? transparentColorIndex : null; | ||
const colorTable = localColorTableFlag ? null : globalColorTable == null ? void 0 : globalColorTable.data; | ||
frameData["Frame"] = { | ||
delayTime, | ||
disposalMethod, | ||
transparency, | ||
colorTable, | ||
indexStream, | ||
left, | ||
top, | ||
width, | ||
height | ||
}; | ||
Object.assign(frameData["Frame"], { | ||
imageData: this.createImageData(frameData["Frame"]) | ||
}); | ||
this.dataList.push({ | ||
let t = {}; | ||
const e = this.blockList.find((i) => i.type === "GlobalColorTable"); | ||
this.blockList.forEach((i) => { | ||
if (i.type === "GraphicsControlExtension") | ||
t[i.type] = i.data, this.dataList.push(i); | ||
else if (i.type === "ImageDescriptor") | ||
t[i.type] = i.data, this.dataList.push(i); | ||
else if (i.type === "ImageContent") { | ||
t[i.type] = i.data, this.dataList.push(i); | ||
const { delayTime: r, disposalMethod: a, transparentColorFlag: c, transparentColorIndex: f } = t.GraphicsControlExtension, { localColorTableFlag: p, left: h, top: n, width: l, height: d } = t.ImageDescriptor, { indexStream: y } = t.ImageContent, k = c ? f : null, C = p ? null : e == null ? void 0 : e.data; | ||
t.Frame = { | ||
delayTime: r, | ||
disposalMethod: a, | ||
transparency: k, | ||
colorTable: C, | ||
indexStream: y, | ||
left: h, | ||
top: n, | ||
width: l, | ||
height: d | ||
}, Object.assign(t.Frame, { | ||
imageData: this.createImageData(t.Frame) | ||
}), this.dataList.push({ | ||
type: "Frame", | ||
data: frameData["Frame"] | ||
data: t.Frame | ||
}); | ||
} else { | ||
this.dataList.push(item); | ||
} | ||
} else | ||
this.dataList.push(i); | ||
}); | ||
} | ||
getFrames() { | ||
if (!this.isExport) { | ||
return this.exportWarn(); | ||
} | ||
return this.dataList.filter((item) => item.type === "Frame").map((item) => { | ||
const { delayTime, transparency, left, top, width, height, imageData } = item.data; | ||
return this.isExport ? this.dataList.filter((t) => t.type === "Frame").map((t) => { | ||
const { delayTime: e, transparency: i, left: r, top: a, width: c, height: f, imageData: p } = t.data; | ||
return { | ||
delayTime, | ||
transparency, | ||
left, | ||
top, | ||
width, | ||
height, | ||
imageData | ||
delayTime: e, | ||
transparency: i, | ||
left: r, | ||
top: a, | ||
width: c, | ||
height: f, | ||
imageData: p | ||
}; | ||
}); | ||
}) : this.exportWarn(); | ||
} | ||
getBlockItem(type) { | ||
const currentItem = this.blockList.find((item) => item.type === type); | ||
return currentItem && currentItem.data; | ||
getBlockItem(t) { | ||
const e = this.blockList.find((i) => i.type === t); | ||
return e && e.data; | ||
} | ||
} | ||
export { Parser, loadGif }; | ||
export { | ||
_ as Parser, | ||
Z as loadGif | ||
}; |
@@ -1,1 +0,1 @@ | ||
var st=Object.defineProperty,it=Object.defineProperties;var rt=Object.getOwnPropertyDescriptors;var B=Object.getOwnPropertySymbols;var at=Object.prototype.hasOwnProperty,ot=Object.prototype.propertyIsEnumerable;var D=(g,d,b)=>d in g?st(g,d,{enumerable:!0,configurable:!0,writable:!0,value:b}):g[d]=b,I=(g,d)=>{for(var b in d||(d={}))at.call(d,b)&&D(g,b,d[b]);if(B)for(var b of B(d))ot.call(d,b)&&D(g,b,d[b]);return g},L=(g,d)=>it(g,rt(d));var s=(g,d,b)=>(D(g,typeof d!="symbol"?d+"":d,b),b);(function(g,d){typeof exports=="object"&&typeof module!="undefined"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(g=typeof globalThis!="undefined"?globalThis:g||self,d(g.gifParser={}))})(this,function(g){"use strict";class d{constructor(t,e){s(this,"index",0);s(this,"dataView");this.arrayBuffer=t,this.littleEndian=e,this.dataView=new DataView(t),this.littleEndian=e||!1}check(t){return this.index+t<=this.dataView.byteLength}seek(t){this.index+=t}peekByte(t=0){return this.check(1+t),this.dataView.getUint8(this.index+t)}slice(t,e){return new Uint8Array(this.dataView.buffer,t,e)}readUint8(){this.check(1);const t=this.dataView.getUint8(this.index);return this.seek(1),t}readUint8Array(t){const e=[];for(let i=0;i<t;i++)e.push(this.readUint8());return e}readUint16(){this.check(2);const t=this.dataView.getUint16(this.index,this.littleEndian);return this.seek(2),t}readUint32(){this.check(4);const t=this.dataView.getUint32(this.index,this.littleEndian);return this.seek(4),t}readInt32(){this.check(4);const t=this.dataView.getInt32(this.index,this.littleEndian);return this.seek(4),t}readString(t){let e="";for(let i=0;i<t;i++)e+=String.fromCharCode(this.readUint8());return e}readEscapedString(t){let e="";for(let i=0;i<t;i++){const r=this.readUint8();r>=32&&r<=126?e+=String.fromCharCode(r):e+=`\\x${r.toString(16).padStart(2,"0")}`}return e}readNullTerminatedString(){let t="",e=this.readUint8();for(;e!==0;)t+=String.fromCharCode(e),e=this.readUint8();return t}hasMore(t){return this.check(1),this.index<=this.dataView.byteLength-(t||1)}setOffset(t){this.index=t}getOffset(){return this.index}readInt8(){const t=this.dataView.getInt8(this.index);return this.seek(1),t}}function b(o){return o.reduce((t,e)=>t*2+e,0)}function T(o){let t=[];for(let e=7;e>=0;e--)t.push(!!(o&1<<e));return t.map(e=>Number(e))}function A(o){return fetch(o).then(t=>t.arrayBuffer())}function m(o,t,e){try{return o.slice(t,e)}catch{return new Uint8Array(0)}}function O(o){const t=parseInt(`${o}`).toString(16);return(t.length===2?t:`0${t}`).toUpperCase()}class v{constructor(t){s(this,"type","Header");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"signature","");s(this,"version","");this.stream=t,this.stream=t}parse(){if(this.offset=this.stream.getOffset(),this.signature=this.stream.readString(3),this.version=this.stream.readString(3),this.length=this.stream.getOffset()-this.offset,console.log("this.signature",this.signature),this.signature!=="GIF")throw new Error("Not a GIF file.")}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:m(this.stream,this.offset,this.length),data:{signature:this.signature,version:this.version}}}}class R{constructor(t){s(this,"type","LogicalScreenDescriptor");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"width",0);s(this,"height",0);s(this,"packedFields",[]);s(this,"globalColorTableFlag",0);s(this,"colorResolution",0);s(this,"sortFlag",0);s(this,"globalColorTableSize",0);s(this,"backgroundColorIndex",0);s(this,"pixelAspectRatio",0);this.stream=t,this.stream=t}parse(){this.offset=this.stream.getOffset(),this.width=this.stream.readUint16(),this.height=this.stream.readUint16(),this.packedFields=T(this.stream.readUint8()),this.handlerPackedField(this.packedFields),this.backgroundColorIndex=this.stream.readUint8(),this.pixelAspectRatio=this.stream.readInt8(),this.length=this.stream.getOffset()-this.offset}hasGlobalColorTable(){return!!this.globalColorTableFlag}getGlobalColorTableSize(){return this.globalColorTableSize}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:m(this.stream,this.offset,this.length),data:{width:this.width,height:this.height,packedFields:this.packedFields,globalColorTableFlag:this.globalColorTableFlag,colorResolution:this.colorResolution,sortFlag:this.sortFlag,globalColorTableSize:this.globalColorTableSize,backgroundColorIndex:this.backgroundColorIndex,pixelAspectRatio:this.pixelAspectRatio}}}handlerPackedField(t){const e=[...t];this.globalColorTableFlag=e.shift()||0,this.colorResolution=b(e.splice(0,3))+1,this.sortFlag=e.shift()||0,this.globalColorTableSize=b(e.splice(0,3))}}class z{constructor(t,e){s(this,"type","");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"colors",[]);this.stream=t,this.stream=t,this.type=e}parse({size:t=0}){const e=1<<t+1;this.offset=this.stream.getOffset();for(let i=0;i<e;i++)this.colors.push(this.stream.readUint8Array(3));this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:m(this.stream,this.offset,this.length),data:this.colors}}}class G extends z{constructor(t){super(t,"GlobalColorTable")}}class k{constructor(t){s(this,"stream");this.stream=t}parse(t){}export(){}readSubBlocks(){const t=this.stream.getOffset();let e=this.stream.readInt8(),i=1;const r=[];for(;e>0;)r.push({offset:t+i,length:e}),i+=e+1,this.stream.seek(e),e=this.stream.readUint8();return{blocks:r,blocksLength:i}}}class M extends k{constructor(t){super(t);s(this,"type","GraphicsControlExtension");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"introducer","");s(this,"label","");s(this,"blockSize",0);s(this,"packedFields",[]);s(this,"reserved",[]);s(this,"disposalMethod",0);s(this,"userInputFlag",0);s(this,"transparentColorFlag",0);s(this,"delayTime",0);s(this,"transparentColorIndex",0);s(this,"blockTerminator","");this.stream=t}parse({introducer:t=0,label:e=0}){this.offset=this.stream.getOffset()-2,this.introducer=String.fromCharCode(t),this.label=O(e),this.blockSize=this.stream.readUint8(),this.packedFields=T(this.stream.readUint8());const i=[...this.packedFields];this.reserved=i.splice(0,3),this.disposalMethod=b(i.splice(0,3)),this.userInputFlag=i.shift()||0,this.transparentColorFlag=i.shift()||0,this.delayTime=this.stream.readUint16(),this.transparentColorIndex=this.stream.readUint8(),this.blockTerminator=this.stream.readString(1),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:m(this.stream,this.offset,this.length),data:{introducer:this.introducer,label:this.label,blockSize:this.blockSize,packedFields:this.packedFields,reserved:this.reserved,disposalMethod:this.disposalMethod,userInputFlag:this.userInputFlag,transparentColorFlag:this.transparentColorFlag,delayTime:this.delayTime,transparentColorIndex:this.transparentColorIndex,blockTerminator:this.blockTerminator}}}}class P extends k{constructor(t){super(t);s(this,"type","CommentExtension");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"comment",{});this.stream=t}parse({introducer:t,label:e}){this.offset=this.stream.getOffset(),this.comment=this.readSubBlocks(),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:m(this.stream,this.offset,this.length),data:this.comment}}}class V extends k{constructor(t){super(t);s(this,"type","PlainTextExtension");s(this,"blockSize",0);s(this,"left",0);s(this,"top",0);s(this,"width",0);s(this,"height",0);s(this,"cellWidth",0);s(this,"cellHeight",0);s(this,"foregroundColorIndex",0);s(this,"backgroundColorIndex",0);s(this,"data",{});this.stream=t}parse({introducer:t,label:e}){this.offset=this.stream.getOffset(),this.blockSize=this.stream.readUint8(),this.left=this.stream.readUint16(),this.top=this.stream.readUint16(),this.width=this.stream.readUint16(),this.height=this.stream.readUint16(),this.cellWidth=this.stream.readUint8(),this.cellHeight=this.stream.readUint8(),this.foregroundColorIndex=this.stream.readUint8(),this.backgroundColorIndex=this.stream.readUint8(),this.data=this.readSubBlocks(),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:m(this.stream,this.offset,this.length),data:this.data}}}class N extends k{constructor(t){super(t);s(this,"type","NetscapeExtension");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"blockSize",0);s(this,"subblock",0);s(this,"loop",0);s(this,"terminator",0);s(this,"decode","");this.stream=t}parse({introducer:t,label:e}){this.offset=this.stream.getOffset(),this.blockSize=this.stream.readUint8(),this.subblock=this.stream.readUint8(),this.loop=this.stream.readUint16(),this.terminator=this.stream.readInt8(),this.decode=`Loop: ${this.loop>0?this.loop:"forever"}`,this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:m(this.stream,this.offset,this.length),data:{blockSize:this.blockSize,subblock:this.subblock,loop:this.loop,terminator:this.terminator,decode:this.decode}}}}const x=class{constructor(t){s(this,"buffer",null);t instanceof ArrayBuffer?this.buffer=t:t instanceof Uint8Array?this.buffer=t.buffer:(typeof t=="string"||t instanceof String)&&this.fromDataUri(t)}static dataUriToBuffer(t){let e=atob(t.split(",")[1]),i=e.length,r=new ArrayBuffer(i),a=new Uint8Array(r);for(let f=0;f<i;f++)a[f]=e.charCodeAt(f);return r}static find(t){let e;t instanceof ArrayBuffer?e=t:t instanceof Uint8Array?this.buffer=t.buffer:(typeof t=="string"||t instanceof String)&&(e=x.dataUriToBuffer(t));let i=new DataView(e);if(!e)return;const r="<x:xmpmeta",a=r.length,f=e.byteLength-a,c="x:xmpmeta>",p=c.length,h=e.byteLength-p;let n=2,l=n+a,u=!1;for(;n<f;)if(x.stringFromBuffer(i,n,a)==r){u=!0;break}else n++;if(!u)return console.warn("XMP not found"),null;for(;l<h&&x.stringFromBuffer(i,l,p)!=c;)l++;return l+=p,x.stringFromBuffer(i,n,l-n)}static stringFromBuffer(t,e,i){let r="";for(let a=e;a<e+i;a++)r+=String.fromCharCode(t.getUint8(a));return r}static execFind(t,e){let i=[],r=!0;for(;r;){let a=e.exec(t);a?i.push(a):r=!1}return i}static toTree(t){let e=[];if(!t||!t.length)return e;const i=t.shift(),r=t.findIndex(a=>`</${i.tag}>`===a.raw);return t.splice(r,1),e.push(L(I({},i),{children:x.toTree(t)})),e}static parse(t){if(!t)return null;const e=new RegExp("<[^>]+>","gi"),r=x.execFind(t,e).map((a,f)=>{const c=new RegExp("<(.*?)\\s","g"),p=new RegExp('\\s(.*?)="(.*?)"',"g"),h=a[0],n=c.exec(h),l=x.execFind(h,p);let u={};return l.forEach(w=>{const[,S,E]=w;u[S]=E}),{raw:h,tag:n?n[1]:null,attrs:u}});return x.toTree(r)}fromDataUri(t){this.buffer=x.dataUriToBuffer(t)}find(){return x.find(this.buffer)||""}parse(){let t=this.find();return x.parse(t)}};let U=x;s(U,"buffer",null);class $ extends k{constructor(t){super(t);s(this,"type","XMPDataExtension");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"blockSize",0);s(this,"xmpData",[]);this.stream=t}parse({introducer:t,label:e}){this.offset=this.stream.getOffset();const{blocks:i}=this.readSubBlocks();i.forEach(f=>{this.blockSize+=f.length});const r=this.stream.slice(this.offset,this.blockSize);let a=new U(r);this.xmpData=a.parse(),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:m(this.stream,this.offset,this.length),data:{blockSize:this.blockSize,xmpData:this.xmpData}}}}class H extends k{constructor(t){super(t);s(this,"type","UnknownApplicationExtension");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"appData",{});this.stream=t}parse({introducer:t,label:e}){console.log("introducer, label",t,e),this.offset=this.stream.getOffset(),this.appData=this.readSubBlocks(),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:m(this.stream,this.offset,this.length),data:this.appData}}}class W extends k{constructor(t){super(t);s(this,"type","ApplicationExtension");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"introducer","");s(this,"label","");s(this,"blockSize",0);s(this,"identifier","");s(this,"authenticationCode","");s(this,"appData");s(this,"netscapeExtension");s(this,"xmpdataExtension");s(this,"unknownApplicationExtension");this.stream=t,this.netscapeExtension=new N(t),this.xmpdataExtension=new $(t),this.unknownApplicationExtension=new H(t),this.appData={}}parse({introducer:t=0,label:e=0}){this.introducer=String.fromCharCode(t),this.label=O(e),this.offset=this.stream.getOffset()-2,this.blockSize=this.stream.readInt8(),this.identifier=this.stream.readString(8),this.authenticationCode=this.stream.readString(3),this.identifier==="NETSCAPE"?(this.netscapeExtension.parse({introducer:t,label:e}),this.appData=this.netscapeExtension.export()):this.identifier==="XMP Data"?(this.xmpdataExtension.parse({introducer:t,label:e}),this.appData=this.xmpdataExtension.export()):(this.unknownApplicationExtension.parse({introducer:t,label:e}),this.appData=this.unknownApplicationExtension.export()),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:m(this.stream,this.offset,this.length),data:{introducer:this.introducer,label:this.label,blockSize:this.blockSize,identifier:this.identifier,authenticationCode:this.authenticationCode,appData:this.appData}}}}class j extends k{constructor(t){super(t);s(this,"type","UnknownExtension");s(this,"data",{});this.stream=t}parse({introducer:t,label:e}){this.offset=this.stream.getOffset(),this.data=this.readSubBlocks(),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:m(this.stream,this.offset,this.length),data:this.data}}}class X{constructor(t){s(this,"extensionBlock",{});s(this,"graphicsControlExtension");s(this,"plainTextExtension");s(this,"commentExtension");s(this,"applicationExtension");s(this,"unknownExtension");this.stream=t,this.stream=t,this.graphicsControlExtension=new M(t),this.commentExtension=new P(t),this.plainTextExtension=new V(t),this.applicationExtension=new W(t),this.unknownExtension=new j(t)}parse({introducer:t}){const e=this.stream.readUint8();switch(e){case 249:this.graphicsControlExtension.parse({introducer:t,label:e}),this.extensionBlock=this.graphicsControlExtension.export();break;case 254:this.commentExtension.parse({introducer:t,label:e}),this.extensionBlock=this.commentExtension.export();break;case 1:this.plainTextExtension.parse({introducer:t,label:e}),this.extensionBlock=this.plainTextExtension.export();break;case 255:this.applicationExtension.parse({introducer:t,label:e}),this.extensionBlock=this.applicationExtension.export();break;default:this.unknownExtension.parse({introducer:t,label:e}),this.extensionBlock=this.unknownExtension.export();break}}export(){return this.extensionBlock}}class q extends z{constructor(t){super(t,"LocalColorTable")}}class J{constructor(t){s(this,"type","ImageDescriptor");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"introducer","");s(this,"left",0);s(this,"top",0);s(this,"width",0);s(this,"height",0);s(this,"packedFields",[]);s(this,"localColorTableFlag",0);s(this,"interlaceFlag",0);s(this,"sortFlag",0);s(this,"reserved",[]);s(this,"localColorTableSize",0);this.stream=t,this.stream=t}hasLocalColorTable(){return!!this.localColorTableFlag}getLocalColorTableSize(){return this.localColorTableSize}parse({introducer:t=0}){this.introducer=String.fromCharCode(t),this.offset=this.stream.getOffset()-1,this.left=this.stream.readUint16(),this.top=this.stream.readUint16(),this.width=this.stream.readUint16(),this.height=this.stream.readUint16(),this.packedFields=T(this.stream.readUint8());const e=[...this.packedFields];this.localColorTableFlag=e.shift()||0,this.interlaceFlag=e.shift()||0,this.sortFlag=e.shift()||0,this.reserved=e.splice(0,2),this.localColorTableSize=b(e.splice(0,3)),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:m(this.stream,this.offset,this.length),data:{introducer:this.introducer,left:this.left,top:this.top,width:this.width,height:this.height,packedFields:this.packedFields,localColorTableFlag:this.localColorTableFlag,interlaceFlag:this.interlaceFlag,sortFlag:this.sortFlag,reserved:this.reserved,localColorTableSize:this.localColorTableSize}}}}class K{constructor(t){s(this,"bytes");s(this,"byteOffset");s(this,"bitOffset");s(this,"totalByteOffset");this.bytes=t||new Int8Array,this.byteOffset=0,this.bitOffset=0,this.totalByteOffset=0}readBits(t){let e=0,i=0;for(;i<t;){if(this.byteOffset>=this.bytes.length)throw new Error(`Not enough bytes to read ${t} bits (read ${i} bits)`);const r=Math.min(8-this.bitOffset,t-i),a=255>>8-r<<this.bitOffset;e+=(this.bytes[this.byteOffset]&a)>>this.bitOffset<<i,i+=r,this.bitOffset+=r,this.bitOffset===8&&(this.byteOffset+=1,this.totalByteOffset+=1,this.bitOffset=0)}return e}hasBits(t=1){if(t>12)throw new Error(`Exceeds max bit size: ${t} (max: 12)`);if(this.byteOffset>=this.bytes.length)return!1;const e=8-this.bitOffset;if(t<=e)return!0;const i=this.bytes.length-this.byteOffset-1;return!(i<1||t>e+8*i)}setBytes(t,e=0,i=0){this.bytes=t,this.byteOffset=e,this.bitOffset=i}pushBytes(t){if(this.hasBits()){const e=this.bytes.length-this.byteOffset,i=new Uint8Array(e+t.length);i.set(this.bytes.slice(this.byteOffset)),i.set(t,e),this.bytes=i,this.byteOffset=0}else this.bytes=t,this.byteOffset=0,this.bitOffset=0}getState(){return{bitOffset:this.bitOffset,byteOffset:this.totalByteOffset}}}class Q{constructor(t){s(this,"type","ImageContent");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"children",{});this.stream=t,this.stream=t}parse(){this.offset=this.stream.getOffset();const t=this.readImageContent();this.children=this.lzwDecode(t),this.length=this.stream.getOffset()-this.offset}lzwDecode(t){const{blocks:e,lzwMinimumCodeSize:i}=t,r=[],a=[];let f=[],c=[];const p=new K,h=2<<i-1,n=h+1;let l=n,u=i+1,w=(2<<u-1)-1,S=!1;for(const{offset:E,length:tt}of e)for(p.pushBytes(this.stream.slice(E,tt));p.hasBits(u);){const et=p.getState(),C=p.readBits(u);if(C===n){f.push(C);break}else if(C===h){a.push({stream:[],table:[],start:et}),f=a[a.length-1].stream,c=a[a.length-1].table;for(let y=0;y<=n;y++)c[y]=y<h?[y]:[];l=n,u=i+1,w=(2<<u-1)-1,S=!1}else if(!S)r.push(...c[C]),S=!0;else{let y=0;const F=f[f.length-1];C<=l?(r.push(...c[C]),y=c[C][0]):(y=c[F][0],r.push(...c[F],y)),l<4095&&(l+=1,c[l]=[...c[F],y],l===w&&l<4095&&(u+=1,w=(2<<u-1)-1))}f.push(C)}return Object.assign({},t,{indexStream:r,clearCode:h,eoiCode:n,codeUnits:a,blockCount:e.length,codeUnitCount:a.length})}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:m(this.stream,this.offset,this.length),data:this.children}}readImageContent(){const t=this.stream.getOffset(),e=this.stream.readUint8();let{blocks:i}=this.readSubBlocks();const r=this.stream.getOffset()-t;return{offset:t,length:r,type:"image",lzwMinimumCodeSize:e,blocks:i}}readSubBlocks(){const t=this.stream.getOffset();let e=this.stream.readUint8(),i=1;const r=[];for(;e>0;)r.push({offset:t+i,length:e}),i+=e+1,this.stream.seek(e),e=this.stream.readUint8();return i+=1,{blocks:r,blocksLength:i}}}class Y{constructor(t){s(this,"localColorTable");s(this,"imageDescriptor");s(this,"imageContent");this.stream=t,this.stream=t,this.localColorTable=new q(t),this.imageDescriptor=new J(t),this.imageContent=new Q(t)}parse({introducer:t}){if(this.imageDescriptor.parse({introducer:t}),this.imageDescriptor.hasLocalColorTable()){const e=this.imageDescriptor.getLocalColorTableSize();this.localColorTable.parse({size:e})}this.imageContent.parse()}createFrame(t,e,i,r){const a=document.createElement("canvas");a.width=i,a.height=r;const c=a.getContext("2d").createImageData(i,r),p=c.data;for(let h=0,n=0;h<e.length;h+=1,n+=4)p[n+0]=t[e[h]][0],p[n+1]=t[e[h]][1],p[n+2]=t[e[h]][2],p[n+3]=e[h]!==88?255:0;return c}exportFrameData(t){const{width:e,height:i,left:r,top:a,localColorTableFlag:f}=this.imageDescriptor.export().data,{indexStream:c}=this.imageContent.export().data;let p=this.imageDescriptor.hasLocalColorTable()?this.localColorTable.export():t||{};return{type:"Frame",data:{width:e,height:i,left:r,top:a,localColorTableFlag:f,imageData:this.createFrame(p.data,c,e,i)}}}export(){const t=this.imageDescriptor.export(),e=this.imageContent.export();if(!this.imageDescriptor.hasLocalColorTable())return[t,e];const i=this.localColorTable.export();return[t,i,e]}}class Z{constructor(t){s(this,"type","Block");s(this,"offset",0);s(this,"length",0);s(this,"blocks",[]);s(this,"extension");s(this,"imageData");this.stream=t,this.stream=t,this.extension=new X(this.stream),this.imageData=new Y(this.stream)}parse(t){for(this.offset=this.stream.getOffset();this.stream.hasMore();){const e=this.stream.readUint8();switch(String.fromCharCode(e)){case"!":this.extension.parse({introducer:e}),this.blocks.push(this.extension.export());break;case",":this.imageData.parse({introducer:e}),this.blocks.push(...this.imageData.export());break;case";":console.log("end block");break;default:throw new Error("Unknown block: 0x"+e.toString(16))}}this.length=this.stream.getOffset()-this.offset}export(){return this.blocks}}class _{constructor(t){s(this,"parsed");s(this,"blockList");s(this,"dataList");s(this,"stream");s(this,"header");s(this,"logicalScreenDescriptor");s(this,"globalColorTable");s(this,"block");s(this,"isExport",!1);console.log("GifParser init"),this.parsed=!1,this.blockList=[],this.dataList=[],this.stream=new d(t,!0),this.header=new v(this.stream),this.logicalScreenDescriptor=new R(this.stream),this.globalColorTable=new G(this.stream),this.block=new Z(this.stream),this.parse()}parse(){if(!this.parsed){if(this.header.parse(),this.logicalScreenDescriptor.parse(),this.logicalScreenDescriptor.hasGlobalColorTable()){const t=this.logicalScreenDescriptor.getGlobalColorTableSize();this.globalColorTable.parse({size:t})}this.block.parse(this.logicalScreenDescriptor.hasGlobalColorTable()?this.globalColorTable.export():void 0),this.parsed=!0}}getSize(){const{data:t}=this.logicalScreenDescriptor.export();return[t.width,t.height]}export(){this.isExport||(this.blockList.push(this.header.export()),this.blockList.push(this.logicalScreenDescriptor.export()),this.logicalScreenDescriptor.hasGlobalColorTable()&&this.blockList.push(this.globalColorTable.export()),this.blockList.push(...this.block.export()),this.dataHandler(),this.isExport=!0)}exportWarn(){return console.warn.call(this,"parser.export()"),[]}getBlockList(){return this.blockList}getDataList(){return this.isExport?this.dataList:this.exportWarn()}createImageData({colorTable:t,indexStream:e,width:i,height:r,transparency:a}){const f=document.createElement("canvas");f.width=i,f.height=r;const p=f.getContext("2d").createImageData(i,r),h=p.data;for(let n=0,l=0;n<e.length;n+=1,l+=4)e[n]!==a?(h[l+0]=t[e[n]][0],h[l+1]=t[e[n]][1],h[l+2]=t[e[n]][2],h[l+3]=255):(h[l+0]=0,h[l+1]=0,h[l+2]=0,h[l+3]=0);return p}dataHandler(){let t={};const e=this.blockList.find(i=>i.type==="GlobalColorTable");this.blockList.forEach(i=>{if(i.type==="GraphicsControlExtension")t[i.type]=i.data,this.dataList.push(i);else if(i.type==="ImageDescriptor")t[i.type]=i.data,this.dataList.push(i);else if(i.type==="ImageContent"){t[i.type]=i.data,this.dataList.push(i);const{delayTime:r,disposalMethod:a,transparentColorFlag:f,transparentColorIndex:c}=t.GraphicsControlExtension,{localColorTableFlag:p,left:h,top:n,width:l,height:u}=t.ImageDescriptor,{indexStream:w}=t.ImageContent,S=f?c:null,E=p?null:e==null?void 0:e.data;t.Frame={delayTime:r,disposalMethod:a,transparency:S,colorTable:E,indexStream:w,left:h,top:n,width:l,height:u},Object.assign(t.Frame,{imageData:this.createImageData(t.Frame)}),this.dataList.push({type:"Frame",data:t.Frame})}else this.dataList.push(i)})}getFrames(){return this.isExport?this.dataList.filter(t=>t.type==="Frame").map(t=>{const{delayTime:e,transparency:i,left:r,top:a,width:f,height:c,imageData:p}=t.data;return{delayTime:e,transparency:i,left:r,top:a,width:f,height:c,imageData:p}}):this.exportWarn()}getBlockItem(t){const e=this.blockList.find(i=>i.type===t);return e&&e.data}}g.Parser=_,g.loadGif=A,Object.defineProperty(g,"__esModule",{value:!0}),g[Symbol.toStringTag]="Module"}); | ||
(function(g,b){typeof exports=="object"&&typeof module<"u"?b(exports):typeof define=="function"&&define.amd?define(["exports"],b):(g=typeof globalThis<"u"?globalThis:g||self,b(g.gifParser={}))})(this,function(g){"use strict";var Z=Object.defineProperty;var _=(g,b,x)=>b in g?Z(g,b,{enumerable:!0,configurable:!0,writable:!0,value:x}):g[b]=x;var s=(g,b,x)=>(_(g,typeof b!="symbol"?b+"":b,x),x);class b{constructor(t,e){s(this,"index",0);s(this,"dataView");this.arrayBuffer=t,this.littleEndian=e,this.dataView=new DataView(t),this.littleEndian=e||!1}check(t){return this.index+t<=this.dataView.byteLength}seek(t){this.index+=t}peekByte(t=0){return this.check(1+t),this.dataView.getUint8(this.index+t)}slice(t,e){return new Uint8Array(this.dataView.buffer,t,e)}readUint8(){this.check(1);const t=this.dataView.getUint8(this.index);return this.seek(1),t}readUint8Array(t){const e=[];for(let i=0;i<t;i++)e.push(this.readUint8());return e}readUint16(){this.check(2);const t=this.dataView.getUint16(this.index,this.littleEndian);return this.seek(2),t}readUint32(){this.check(4);const t=this.dataView.getUint32(this.index,this.littleEndian);return this.seek(4),t}readInt32(){this.check(4);const t=this.dataView.getInt32(this.index,this.littleEndian);return this.seek(4),t}readString(t){let e="";for(let i=0;i<t;i++)e+=String.fromCharCode(this.readUint8());return e}readEscapedString(t){let e="";for(let i=0;i<t;i++){const r=this.readUint8();r>=32&&r<=126?e+=String.fromCharCode(r):e+=`\\x${r.toString(16).padStart(2,"0")}`}return e}readNullTerminatedString(){let t="",e=this.readUint8();for(;e!==0;)t+=String.fromCharCode(e),e=this.readUint8();return t}hasMore(t){return this.check(1),this.index<=this.dataView.byteLength-(t||1)}setOffset(t){this.index=t}getOffset(){return this.index}readInt8(){const t=this.dataView.getInt8(this.index);return this.seek(1),t}}function x(o){return o.reduce((t,e)=>t*2+e,0)}function U(o){let t=[];for(let e=7;e>=0;e--)t.push(!!(o&1<<e));return t.map(e=>Number(e))}function z(o){return fetch(o).then(t=>t.arrayBuffer())}function u(o,t,e){try{return o.slice(t,e)}catch{return new Uint8Array(0)}}function D(o){const t=parseInt(`${o}`).toString(16);return(t.length===2?t:`0${t}`).toUpperCase()}class B{constructor(t){s(this,"type","Header");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"signature","");s(this,"version","");this.stream=t,this.stream=t}parse(){if(this.offset=this.stream.getOffset(),this.signature=this.stream.readString(3),this.version=this.stream.readString(3),this.length=this.stream.getOffset()-this.offset,console.log("this.signature",this.signature),this.signature!=="GIF")throw new Error("Not a GIF file.")}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:u(this.stream,this.offset,this.length),data:{signature:this.signature,version:this.version}}}}class I{constructor(t){s(this,"type","LogicalScreenDescriptor");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"width",0);s(this,"height",0);s(this,"packedFields",[]);s(this,"globalColorTableFlag",0);s(this,"colorResolution",0);s(this,"sortFlag",0);s(this,"globalColorTableSize",0);s(this,"backgroundColorIndex",0);s(this,"pixelAspectRatio",0);this.stream=t,this.stream=t}parse(){this.offset=this.stream.getOffset(),this.width=this.stream.readUint16(),this.height=this.stream.readUint16(),this.packedFields=U(this.stream.readUint8()),this.handlerPackedField(this.packedFields),this.backgroundColorIndex=this.stream.readUint8(),this.pixelAspectRatio=this.stream.readInt8(),this.length=this.stream.getOffset()-this.offset}hasGlobalColorTable(){return!!this.globalColorTableFlag}getGlobalColorTableSize(){return this.globalColorTableSize}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:u(this.stream,this.offset,this.length),data:{width:this.width,height:this.height,packedFields:this.packedFields,globalColorTableFlag:this.globalColorTableFlag,colorResolution:this.colorResolution,sortFlag:this.sortFlag,globalColorTableSize:this.globalColorTableSize,backgroundColorIndex:this.backgroundColorIndex,pixelAspectRatio:this.pixelAspectRatio}}}handlerPackedField(t){const e=[...t];this.globalColorTableFlag=e.shift()||0,this.colorResolution=x(e.splice(0,3))+1,this.sortFlag=e.shift()||0,this.globalColorTableSize=x(e.splice(0,3))}}class O{constructor(t,e){s(this,"type","");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"colors",[]);this.stream=t,this.stream=t,this.type=e}parse({size:t=0}){const e=1<<t+1;this.offset=this.stream.getOffset();for(let i=0;i<e;i++)this.colors.push(this.stream.readUint8Array(3));this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:u(this.stream,this.offset,this.length),data:this.colors}}}class L extends O{constructor(t){super(t,"GlobalColorTable")}}class k{constructor(t){s(this,"stream");this.stream=t}parse(t){}export(){}readSubBlocks(){const t=this.stream.getOffset();let e=this.stream.readInt8(),i=1;const r=[];for(;e>0;)r.push({offset:t+i,length:e}),i+=e+1,this.stream.seek(e),e=this.stream.readUint8();return{blocks:r,blocksLength:i}}}class A extends k{constructor(e){super(e);s(this,"type","GraphicsControlExtension");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"introducer","");s(this,"label","");s(this,"blockSize",0);s(this,"packedFields",[]);s(this,"reserved",[]);s(this,"disposalMethod",0);s(this,"userInputFlag",0);s(this,"transparentColorFlag",0);s(this,"delayTime",0);s(this,"transparentColorIndex",0);s(this,"blockTerminator","");this.stream=e}parse({introducer:e=0,label:i=0}){this.offset=this.stream.getOffset()-2,this.introducer=String.fromCharCode(e),this.label=D(i),this.blockSize=this.stream.readUint8(),this.packedFields=U(this.stream.readUint8());const r=[...this.packedFields];this.reserved=r.splice(0,3),this.disposalMethod=x(r.splice(0,3)),this.userInputFlag=r.shift()||0,this.transparentColorFlag=r.shift()||0,this.delayTime=this.stream.readUint16(),this.transparentColorIndex=this.stream.readUint8(),this.blockTerminator=this.stream.readString(1),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:u(this.stream,this.offset,this.length),data:{introducer:this.introducer,label:this.label,blockSize:this.blockSize,packedFields:this.packedFields,reserved:this.reserved,disposalMethod:this.disposalMethod,userInputFlag:this.userInputFlag,transparentColorFlag:this.transparentColorFlag,delayTime:this.delayTime,transparentColorIndex:this.transparentColorIndex,blockTerminator:this.blockTerminator}}}}class v extends k{constructor(e){super(e);s(this,"type","CommentExtension");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"comment",{});this.stream=e}parse({introducer:e,label:i}){this.offset=this.stream.getOffset(),this.comment=this.readSubBlocks(),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:u(this.stream,this.offset,this.length),data:this.comment}}}class R extends k{constructor(e){super(e);s(this,"type","PlainTextExtension");s(this,"blockSize",0);s(this,"left",0);s(this,"top",0);s(this,"width",0);s(this,"height",0);s(this,"cellWidth",0);s(this,"cellHeight",0);s(this,"foregroundColorIndex",0);s(this,"backgroundColorIndex",0);s(this,"data",{});this.stream=e}parse({introducer:e,label:i}){this.offset=this.stream.getOffset(),this.blockSize=this.stream.readUint8(),this.left=this.stream.readUint16(),this.top=this.stream.readUint16(),this.width=this.stream.readUint16(),this.height=this.stream.readUint16(),this.cellWidth=this.stream.readUint8(),this.cellHeight=this.stream.readUint8(),this.foregroundColorIndex=this.stream.readUint8(),this.backgroundColorIndex=this.stream.readUint8(),this.data=this.readSubBlocks(),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:u(this.stream,this.offset,this.length),data:this.data}}}class G extends k{constructor(e){super(e);s(this,"type","NetscapeExtension");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"blockSize",0);s(this,"subblock",0);s(this,"loop",0);s(this,"terminator",0);s(this,"decode","");this.stream=e}parse({introducer:e,label:i}){this.offset=this.stream.getOffset(),this.blockSize=this.stream.readUint8(),this.subblock=this.stream.readUint8(),this.loop=this.stream.readUint16(),this.terminator=this.stream.readInt8(),this.decode=`Loop: ${this.loop>0?this.loop:"forever"}`,this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:u(this.stream,this.offset,this.length),data:{blockSize:this.blockSize,subblock:this.subblock,loop:this.loop,terminator:this.terminator,decode:this.decode}}}}const m=class{constructor(t){s(this,"buffer",null);t instanceof ArrayBuffer?this.buffer=t:t instanceof Uint8Array?this.buffer=t.buffer:(typeof t=="string"||t instanceof String)&&this.fromDataUri(t)}static dataUriToBuffer(t){let e=atob(t.split(",")[1]),i=e.length,r=new ArrayBuffer(i),a=new Uint8Array(r);for(let f=0;f<i;f++)a[f]=e.charCodeAt(f);return r}static find(t){let e;t instanceof ArrayBuffer?e=t:t instanceof Uint8Array?this.buffer=t.buffer:(typeof t=="string"||t instanceof String)&&(e=m.dataUriToBuffer(t));let i=new DataView(e);if(!e)return;const r="<x:xmpmeta",a=r.length,f=e.byteLength-a,c="x:xmpmeta>",p=c.length,h=e.byteLength-p;let n=2,l=n+a,d=!1;for(;n<f;)if(m.stringFromBuffer(i,n,a)==r){d=!0;break}else n++;if(!d)return console.warn("XMP not found"),null;for(;l<h&&m.stringFromBuffer(i,l,p)!=c;)l++;return l+=p,m.stringFromBuffer(i,n,l-n)}static stringFromBuffer(t,e,i){let r="";for(let a=e;a<e+i;a++)r+=String.fromCharCode(t.getUint8(a));return r}static execFind(t,e){let i=[],r=!0;for(;r;){let a=e.exec(t);a?i.push(a):r=!1}return i}static toTree(t){let e=[];if(!t||!t.length)return e;const i=t.shift(),r=t.findIndex(a=>`</${i.tag}>`===a.raw);return t.splice(r,1),e.push({...i,children:m.toTree(t)}),e}static parse(t){if(!t)return null;const e=new RegExp("<[^>]+>","gi"),r=m.execFind(t,e).map((a,f)=>{const c=new RegExp("<(.*?)\\s","g"),p=new RegExp('\\s(.*?)="(.*?)"',"g"),h=a[0],n=c.exec(h),l=m.execFind(h,p);let d={};return l.forEach(w=>{const[,S,E]=w;d[S]=E}),{raw:h,tag:n?n[1]:null,attrs:d}});return m.toTree(r)}fromDataUri(t){this.buffer=m.dataUriToBuffer(t)}find(){return m.find(this.buffer)||""}parse(){let t=this.find();return m.parse(t)}};let T=m;s(T,"buffer",null);class M extends k{constructor(e){super(e);s(this,"type","XMPDataExtension");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"blockSize",0);s(this,"xmpData",[]);this.stream=e}parse({introducer:e,label:i}){this.offset=this.stream.getOffset();const{blocks:r}=this.readSubBlocks();r.forEach(c=>{this.blockSize+=c.length});const a=this.stream.slice(this.offset,this.blockSize);let f=new T(a);this.xmpData=f.parse(),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:u(this.stream,this.offset,this.length),data:{blockSize:this.blockSize,xmpData:this.xmpData}}}}class V extends k{constructor(e){super(e);s(this,"type","UnknownApplicationExtension");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"appData",{});this.stream=e}parse({introducer:e,label:i}){console.log("introducer, label",e,i),this.offset=this.stream.getOffset(),this.appData=this.readSubBlocks(),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:u(this.stream,this.offset,this.length),data:this.appData}}}class P extends k{constructor(e){super(e);s(this,"type","ApplicationExtension");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"introducer","");s(this,"label","");s(this,"blockSize",0);s(this,"identifier","");s(this,"authenticationCode","");s(this,"appData");s(this,"netscapeExtension");s(this,"xmpdataExtension");s(this,"unknownApplicationExtension");this.stream=e,this.netscapeExtension=new G(e),this.xmpdataExtension=new M(e),this.unknownApplicationExtension=new V(e),this.appData={}}parse({introducer:e=0,label:i=0}){this.introducer=String.fromCharCode(e),this.label=D(i),this.offset=this.stream.getOffset()-2,this.blockSize=this.stream.readInt8(),this.identifier=this.stream.readString(8),this.authenticationCode=this.stream.readString(3),this.identifier==="NETSCAPE"?(this.netscapeExtension.parse({introducer:e,label:i}),this.appData=this.netscapeExtension.export()):this.identifier==="XMP Data"?(this.xmpdataExtension.parse({introducer:e,label:i}),this.appData=this.xmpdataExtension.export()):(this.unknownApplicationExtension.parse({introducer:e,label:i}),this.appData=this.unknownApplicationExtension.export()),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:u(this.stream,this.offset,this.length),data:{introducer:this.introducer,label:this.label,blockSize:this.blockSize,identifier:this.identifier,authenticationCode:this.authenticationCode,appData:this.appData}}}}class N extends k{constructor(e){super(e);s(this,"type","UnknownExtension");s(this,"data",{});this.stream=e}parse({introducer:e,label:i}){this.offset=this.stream.getOffset(),this.data=this.readSubBlocks(),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:u(this.stream,this.offset,this.length),data:this.data}}}class ${constructor(t){s(this,"extensionBlock",{});s(this,"graphicsControlExtension");s(this,"plainTextExtension");s(this,"commentExtension");s(this,"applicationExtension");s(this,"unknownExtension");this.stream=t,this.stream=t,this.graphicsControlExtension=new A(t),this.commentExtension=new v(t),this.plainTextExtension=new R(t),this.applicationExtension=new P(t),this.unknownExtension=new N(t)}parse({introducer:t}){const e=this.stream.readUint8();switch(e){case 249:this.graphicsControlExtension.parse({introducer:t,label:e}),this.extensionBlock=this.graphicsControlExtension.export();break;case 254:this.commentExtension.parse({introducer:t,label:e}),this.extensionBlock=this.commentExtension.export();break;case 1:this.plainTextExtension.parse({introducer:t,label:e}),this.extensionBlock=this.plainTextExtension.export();break;case 255:this.applicationExtension.parse({introducer:t,label:e}),this.extensionBlock=this.applicationExtension.export();break;default:this.unknownExtension.parse({introducer:t,label:e}),this.extensionBlock=this.unknownExtension.export();break}}export(){return this.extensionBlock}}class H extends O{constructor(t){super(t,"LocalColorTable")}}class W{constructor(t){s(this,"type","ImageDescriptor");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"introducer","");s(this,"left",0);s(this,"top",0);s(this,"width",0);s(this,"height",0);s(this,"packedFields",[]);s(this,"localColorTableFlag",0);s(this,"interlaceFlag",0);s(this,"sortFlag",0);s(this,"reserved",[]);s(this,"localColorTableSize",0);this.stream=t,this.stream=t}hasLocalColorTable(){return!!this.localColorTableFlag}getLocalColorTableSize(){return this.localColorTableSize}parse({introducer:t=0}){this.introducer=String.fromCharCode(t),this.offset=this.stream.getOffset()-1,this.left=this.stream.readUint16(),this.top=this.stream.readUint16(),this.width=this.stream.readUint16(),this.height=this.stream.readUint16(),this.packedFields=U(this.stream.readUint8());const e=[...this.packedFields];this.localColorTableFlag=e.shift()||0,this.interlaceFlag=e.shift()||0,this.sortFlag=e.shift()||0,this.reserved=e.splice(0,2),this.localColorTableSize=x(e.splice(0,3)),this.length=this.stream.getOffset()-this.offset}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:u(this.stream,this.offset,this.length),data:{introducer:this.introducer,left:this.left,top:this.top,width:this.width,height:this.height,packedFields:this.packedFields,localColorTableFlag:this.localColorTableFlag,interlaceFlag:this.interlaceFlag,sortFlag:this.sortFlag,reserved:this.reserved,localColorTableSize:this.localColorTableSize}}}}class j{constructor(t){s(this,"bytes");s(this,"byteOffset");s(this,"bitOffset");s(this,"totalByteOffset");this.bytes=t||new Int8Array,this.byteOffset=0,this.bitOffset=0,this.totalByteOffset=0}readBits(t){let e=0,i=0;for(;i<t;){if(this.byteOffset>=this.bytes.length)throw new Error(`Not enough bytes to read ${t} bits (read ${i} bits)`);const r=Math.min(8-this.bitOffset,t-i),a=255>>8-r<<this.bitOffset;e+=(this.bytes[this.byteOffset]&a)>>this.bitOffset<<i,i+=r,this.bitOffset+=r,this.bitOffset===8&&(this.byteOffset+=1,this.totalByteOffset+=1,this.bitOffset=0)}return e}hasBits(t=1){if(t>12)throw new Error(`Exceeds max bit size: ${t} (max: 12)`);if(this.byteOffset>=this.bytes.length)return!1;const e=8-this.bitOffset;if(t<=e)return!0;const i=this.bytes.length-this.byteOffset-1;return!(i<1||t>e+8*i)}setBytes(t,e=0,i=0){this.bytes=t,this.byteOffset=e,this.bitOffset=i}pushBytes(t){if(this.hasBits()){const e=this.bytes.length-this.byteOffset,i=new Uint8Array(e+t.length);i.set(this.bytes.slice(this.byteOffset)),i.set(t,e),this.bytes=i,this.byteOffset=0}else this.bytes=t,this.byteOffset=0,this.bitOffset=0}getState(){return{bitOffset:this.bitOffset,byteOffset:this.totalByteOffset}}}class X{constructor(t){s(this,"type","ImageContent");s(this,"offset",0);s(this,"length",0);s(this,"bytes",new Uint8Array(0));s(this,"children",{});this.stream=t,this.stream=t}parse(){this.offset=this.stream.getOffset();const t=this.readImageContent();this.children=this.lzwDecode(t),this.length=this.stream.getOffset()-this.offset}lzwDecode(t){const{blocks:e,lzwMinimumCodeSize:i}=t,r=[],a=[];let f=[],c=[];const p=new j,h=2<<i-1,n=h+1;let l=n,d=i+1,w=(2<<d-1)-1,S=!1;for(const{offset:E,length:Q}of e)for(p.pushBytes(this.stream.slice(E,Q));p.hasBits(d);){const Y=p.getState(),C=p.readBits(d);if(C===n){f.push(C);break}else if(C===h){a.push({stream:[],table:[],start:Y}),f=a[a.length-1].stream,c=a[a.length-1].table;for(let y=0;y<=n;y++)c[y]=y<h?[y]:[];l=n,d=i+1,w=(2<<d-1)-1,S=!1}else if(!S)r.push(...c[C]),S=!0;else{let y=0;const F=f[f.length-1];C<=l?(r.push(...c[C]),y=c[C][0]):(y=c[F][0],r.push(...c[F],y)),l<4095&&(l+=1,c[l]=[...c[F],y],l===w&&l<4095&&(d+=1,w=(2<<d-1)-1))}f.push(C)}return Object.assign({},t,{indexStream:r,clearCode:h,eoiCode:n,codeUnits:a,blockCount:e.length,codeUnitCount:a.length})}export(){return{type:this.type,offset:this.offset,length:this.length,bytes:u(this.stream,this.offset,this.length),data:this.children}}readImageContent(){const t=this.stream.getOffset(),e=this.stream.readUint8();let{blocks:i}=this.readSubBlocks();const r=this.stream.getOffset()-t;return{offset:t,length:r,type:"image",lzwMinimumCodeSize:e,blocks:i}}readSubBlocks(){const t=this.stream.getOffset();let e=this.stream.readUint8(),i=1;const r=[];for(;e>0;)r.push({offset:t+i,length:e}),i+=e+1,this.stream.seek(e),e=this.stream.readUint8();return i+=1,{blocks:r,blocksLength:i}}}class q{constructor(t){s(this,"localColorTable");s(this,"imageDescriptor");s(this,"imageContent");this.stream=t,this.stream=t,this.localColorTable=new H(t),this.imageDescriptor=new W(t),this.imageContent=new X(t)}parse({introducer:t}){if(this.imageDescriptor.parse({introducer:t}),this.imageDescriptor.hasLocalColorTable()){const e=this.imageDescriptor.getLocalColorTableSize();this.localColorTable.parse({size:e})}this.imageContent.parse()}createFrame(t,e,i,r){const a=document.createElement("canvas");a.width=i,a.height=r;const c=a.getContext("2d").createImageData(i,r),p=c.data;for(let h=0,n=0;h<e.length;h+=1,n+=4)p[n+0]=t[e[h]][0],p[n+1]=t[e[h]][1],p[n+2]=t[e[h]][2],p[n+3]=e[h]!==88?255:0;return c}exportFrameData(t){const{width:e,height:i,left:r,top:a,localColorTableFlag:f}=this.imageDescriptor.export().data,{indexStream:c}=this.imageContent.export().data;let p=this.imageDescriptor.hasLocalColorTable()?this.localColorTable.export():t||{};return{type:"Frame",data:{width:e,height:i,left:r,top:a,localColorTableFlag:f,imageData:this.createFrame(p.data,c,e,i)}}}export(){const t=this.imageDescriptor.export(),e=this.imageContent.export();if(!this.imageDescriptor.hasLocalColorTable())return[t,e];const i=this.localColorTable.export();return[t,i,e]}}class J{constructor(t){s(this,"type","Block");s(this,"offset",0);s(this,"length",0);s(this,"blocks",[]);s(this,"extension");s(this,"imageData");this.stream=t,this.stream=t,this.extension=new $(this.stream),this.imageData=new q(this.stream)}parse(t){for(this.offset=this.stream.getOffset();this.stream.hasMore();){const e=this.stream.readUint8();switch(String.fromCharCode(e)){case"!":this.extension.parse({introducer:e}),this.blocks.push(this.extension.export());break;case",":this.imageData.parse({introducer:e}),this.blocks.push(...this.imageData.export());break;case";":console.log("end block");break;default:throw new Error("Unknown block: 0x"+e.toString(16))}}this.length=this.stream.getOffset()-this.offset}export(){return this.blocks}}class K{constructor(t){s(this,"parsed");s(this,"blockList");s(this,"dataList");s(this,"stream");s(this,"header");s(this,"logicalScreenDescriptor");s(this,"globalColorTable");s(this,"block");s(this,"isExport",!1);console.log("GifParser init"),this.parsed=!1,this.blockList=[],this.dataList=[],this.stream=new b(t,!0),this.header=new B(this.stream),this.logicalScreenDescriptor=new I(this.stream),this.globalColorTable=new L(this.stream),this.block=new J(this.stream),this.parse()}parse(){if(!this.parsed){if(this.header.parse(),this.logicalScreenDescriptor.parse(),this.logicalScreenDescriptor.hasGlobalColorTable()){const t=this.logicalScreenDescriptor.getGlobalColorTableSize();this.globalColorTable.parse({size:t})}this.block.parse(this.logicalScreenDescriptor.hasGlobalColorTable()?this.globalColorTable.export():void 0),this.parsed=!0}}getSize(){const{data:t}=this.logicalScreenDescriptor.export();return[t.width,t.height]}export(){this.isExport||(this.blockList.push(this.header.export()),this.blockList.push(this.logicalScreenDescriptor.export()),this.logicalScreenDescriptor.hasGlobalColorTable()&&this.blockList.push(this.globalColorTable.export()),this.blockList.push(...this.block.export()),this.dataHandler(),this.isExport=!0)}exportWarn(){return console.warn.call(this,"parser.export()"),[]}getBlockList(){return this.blockList}getDataList(){return this.isExport?this.dataList:this.exportWarn()}createImageData({colorTable:t,indexStream:e,width:i,height:r,transparency:a}){const f=document.createElement("canvas");f.width=i,f.height=r;const p=f.getContext("2d").createImageData(i,r),h=p.data;for(let n=0,l=0;n<e.length;n+=1,l+=4)e[n]!==a?(h[l+0]=t[e[n]][0],h[l+1]=t[e[n]][1],h[l+2]=t[e[n]][2],h[l+3]=255):(h[l+0]=0,h[l+1]=0,h[l+2]=0,h[l+3]=0);return p}dataHandler(){let t={};const e=this.blockList.find(i=>i.type==="GlobalColorTable");this.blockList.forEach(i=>{if(i.type==="GraphicsControlExtension")t[i.type]=i.data,this.dataList.push(i);else if(i.type==="ImageDescriptor")t[i.type]=i.data,this.dataList.push(i);else if(i.type==="ImageContent"){t[i.type]=i.data,this.dataList.push(i);const{delayTime:r,disposalMethod:a,transparentColorFlag:f,transparentColorIndex:c}=t.GraphicsControlExtension,{localColorTableFlag:p,left:h,top:n,width:l,height:d}=t.ImageDescriptor,{indexStream:w}=t.ImageContent,S=f?c:null,E=p?null:e==null?void 0:e.data;t.Frame={delayTime:r,disposalMethod:a,transparency:S,colorTable:E,indexStream:w,left:h,top:n,width:l,height:d},Object.assign(t.Frame,{imageData:this.createImageData(t.Frame)}),this.dataList.push({type:"Frame",data:t.Frame})}else this.dataList.push(i)})}getFrames(){return this.isExport?this.dataList.filter(t=>t.type==="Frame").map(t=>{const{delayTime:e,transparency:i,left:r,top:a,width:f,height:c,imageData:p}=t.data;return{delayTime:e,transparency:i,left:r,top:a,width:f,height:c,imageData:p}}):this.exportWarn()}getBlockItem(t){const e=this.blockList.find(i=>i.type===t);return e&&e.data}}g.Parser=K,g.loadGif=z,Object.defineProperties(g,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}); |
{ | ||
"name": "@n.see/gif-parser", | ||
"files": [ | ||
"dist" | ||
], | ||
"version": "1.0.7", | ||
"description": "gif-parser", | ||
"main": "./dist/gif-parser.umd.js", | ||
"module": "./dist/gif-parser.es.js", | ||
"types": "./dist/types/src/index.d.ts", | ||
"exports": { | ||
".": { | ||
"import": "./dist/gif-parser.es.js", | ||
"require": "./dist/gif-parser.umd.js" | ||
} | ||
}, | ||
"scripts": { | ||
"dev": "vite", | ||
"build": "vite build", | ||
"serve": "vite preview", | ||
"release": "npm publish --access=public" | ||
}, | ||
"devDependencies": { | ||
"typescript": "^4.3.2", | ||
"vite": "^2.5.2", | ||
"vite-plugin-dts": "^0.8.3" | ||
}, | ||
"keywords": [ | ||
"gif", | ||
"parser", | ||
"ts", | ||
"es6", | ||
"typescript" | ||
], | ||
"author": "n.see", | ||
"license": "ISC" | ||
"name": "@n.see/gif-parser", | ||
"files": [ | ||
"dist" | ||
], | ||
"version": "1.1.0", | ||
"description": "gif-parser", | ||
"main": "./dist/gif-parser.umd.js", | ||
"module": "./dist/gif-parser.es.js", | ||
"types": "./dist/types/src/index.d.ts", | ||
"exports": { | ||
".": { | ||
"import": "./dist/gif-parser.es.js", | ||
"require": "./dist/gif-parser.umd.js" | ||
} | ||
}, | ||
"scripts": { | ||
"dev": "vite", | ||
"build": "vite build", | ||
"serve": "vite preview", | ||
"release": "npm publish --access=public" | ||
}, | ||
"keywords": [ | ||
"gif", | ||
"parser", | ||
"ts", | ||
"es6", | ||
"typescript" | ||
], | ||
"author": "n.see", | ||
"license": "ISC" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
0
77745
1654
3