Skip to content

Commit

Permalink
fix: disposal 3
Browse files Browse the repository at this point in the history
  • Loading branch information
qq15725 committed May 17, 2023
1 parent 3b6340a commit 78fb77c
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 12 deletions.
10 changes: 6 additions & 4 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,12 @@ <h2>Demo</h2>

async function init() {
const source = await fetch(img.src).then(res => res.arrayBuffer())
const { width, height } = decode(source)
frames = await decodeFrames(source, { workerUrl })
encoder.width = width
encoder.height = height
const gif = decode(source)
frames = await decodeFrames(source)
encoder.width = gif.width
encoder.height = gif.height
// eslint-disable-next-line no-console
console.log(gif)
render()
}

Expand Down
31 changes: 23 additions & 8 deletions src/decode-frames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ export function decodeFrames(source: BufferSource, options?: DecodeFramesOptions
frames: globalFrames,
} = gif

const backgroundColorIndex = gif.globalColorTable && globalColorTable
? gif.backgroundColorIndex
: undefined

const backgroundColor = backgroundColorIndex !== undefined && globalColorTable
? globalColorTable[backgroundColorIndex]
: [0, 0, 0]

const frames = range
? globalFrames.slice(range[0], range[1] + 1)
: globalFrames
Expand Down Expand Up @@ -72,32 +80,39 @@ export function decodeFrames(source: BufferSource, options?: DecodeFramesOptions

const {
transparent,
transparentIndex: transparentIndex_,
transparentIndex: localTransparentIndex,
} = graphicControl ?? {}

const palette = localColorTable ? colorTable : globalColorTable
const transparentIndex = transparent ? transparentIndex_ : -1
const transparentIndex = transparent ? localTransparentIndex : -1

const compressedData = mergeBuffers(
imageDataPositions.map(
([begin, length]) => array.subarray(begin, begin + length),
),
)

let colorIndexes = lzwDecode(lzwMinCodeSize, compressedData, width * height)
let colorIndexs = lzwDecode(lzwMinCodeSize, compressedData, width * height)

if (interlaced) {
colorIndexes = deinterlace(colorIndexes, width)
colorIndexs = deinterlace(colorIndexs, width)
}

if (previousFrame && previousFrame?.disposal !== 1) {
const { left, top, width, height } = previousFrame
if (previousFrame?.disposal !== 1) {
const { left = 0, top = 0, width = globalWidth, height = globalHeight } = previousFrame ?? {}
const bottom = top + height
for (let y = top; y < bottom; y++) {
const globalOffset = y * globalWidth + left
for (let x = 0; x < width; x++) {
const index = (globalOffset + x) * 4
pixels[index] = pixels[index + 1] = pixels[index + 2] = pixels[index + 3] = 0
if (transparentIndex === backgroundColorIndex) {
pixels[index] = pixels[index + 1] = pixels[index + 2] = pixels[index + 3] = 0
} else {
pixels[index] = backgroundColor[0]
pixels[index + 1] = backgroundColor[1]
pixels[index + 2] = backgroundColor[2]
pixels[index + 3] = 255
}
}
}
}
Expand All @@ -106,7 +121,7 @@ export function decodeFrames(source: BufferSource, options?: DecodeFramesOptions
const globalOffset = y * globalWidth + left
const localOffset = (y - top) * width
for (let x = 0; x < width; x++) {
const colorIndex = colorIndexes[localOffset + x]
const colorIndex = colorIndexs[localOffset + x]
if (colorIndex === transparentIndex) continue
const [r, g, b] = palette?.[colorIndex] ?? [0, 0, 0]
const index = (globalOffset + x) * 4
Expand Down

1 comment on commit 78fb77c

@vercel
Copy link

@vercel vercel bot commented on 78fb77c May 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

modern-gif – ./

modern-gif.vercel.app
modern-gif-qq15725.vercel.app
modern-gif-git-main-qq15725.vercel.app

Please sign in to comment.