animated portable network graphics encoder logic

default===frame1/default!==frame1を経由してencoderを使用可能。

encoder

1. throw
if(0xffffffff<plays)throw Error()

2. declare values, frames
const vs=[],frames=b?fs.length:fs.length-1

3. declare actl, fctl
,actl=new Uint8Array(12),fctl=new Uint8Array(30)

4. set acTL
actl.set(types[1].to4Array())
actl.set(frames.to4Array(),4)
actl.set(plays.to4Array(),8)

5. set fcTL
fctl.set(types[2].to4Array())
fctl.set(width.to4Array(),8)
fctl.set(height.to4Array(),12)
fctl.set((1).to2Array(),24)
fctl.set(frames.to2Array(),26)

6. set acTL(, fcTL), IDAT(, fcTL, PLTE, tRNS)
await fs[0].fromObjectURL(async u=>{
    let i=8
    const v=await c(width,height,u),idat=[types[3].to4Array()]
    vs.push(v.subarray(0,i))
    while(i<v.length){
        const length=v.toNumberFrom4(i),type=v.toNumberFrom4(i+=4)
        i+=4
        if(types[3]===type)idat.push(v.subarray(i,i+length))
        else if([types[0],types[6],types[7]].includes(type))vs.push(v.subarray(i-8,4+i+length))
        i+=4+length
    }
    vs.push(chunks[0](actl))
    if(b)vs.push(chunks[1](fctl))
    vs.push(chunks[2](idat))
    if(message)message(1)
})

7. set fcTL, fdAT
await forEach(true,fs.length-1,async(_,i)=>{
    const sequence=2*i+(1&b)
    fctl.set(sequence.to4Array(),4)
    await fs[1+i].fromObjectURL(async u=>{
        let i=8
        const v=await c(width,height,u),fdat=[types[4].to4Array(),(1+sequence).to4Array()]
        while(i<v.length){
            const length=v.toNumberFrom4(i),type=v.toNumberFrom4(i+=4)
            i+=4
            if(types[3]===type)fdat.push(v.subarray(i,i+length))
            i+=4+length
        }
        vs.push(chunks[1](fctl),chunks[2](fdat))
    })
    if(message)message(2+i)
})

8. set IEND
vs.push(chunks[3]())

9. return
return new Blob(vs.toValues(),{type:`image/apng`})