11/* eslint-disable @typescript-eslint/no-magic-numbers */
22/* eslint-disable @typescript-eslint/no-non-null-assertion */
3- import { type ICoordinates , type IRgb , type IRgba , type IShapeDrawData , half } from "@tsparticles/engine" ;
43import { type IImage , type ImageParticle , loadImage } from "../Utils.js" ;
4+ import { type IRgb , type IRgba , type IShapeDrawData , half , originPoint } from "@tsparticles/engine" ;
55import { InterlaceOffsets , InterlaceSteps } from "./Constants.js" ;
66import type { ApplicationExtension } from "./Types/ApplicationExtension.js" ;
77import { ByteStream } from "./ByteStream.js" ;
@@ -10,11 +10,7 @@ import type { GIF } from "./Types/GIF.js";
1010import { GIFDataHeaders } from "./Types/GIFDataHeaders.js" ;
1111import type { GIFProgressCallbackFunction } from "./Types/GIFProgressCallbackFunction.js" ;
1212
13- const origin : ICoordinates = {
14- x : 0 ,
15- y : 0 ,
16- } ,
17- defaultFrame = 0 ,
13+ const defaultFrame = 0 ,
1814 initialTime = 0 ,
1915 firstIndex = 0 ,
2016 defaultLoopCount = 0 ;
@@ -156,6 +152,23 @@ function parseExtensionBlock(
156152 }
157153}
158154
155+ /**
156+ * __read `len` bits from `imageData` at `pos`__
157+ * @param imageData - `Uint8ClampedArray` to read from
158+ * @param pos - bit position in `imageData`
159+ * @param len - bit length to read [1-12 bits]
160+ * @returns `len` bits at `pos`
161+ */
162+ function readBits ( imageData : Uint8Array , pos : number , len : number ) : number {
163+ const bytePos = pos >>> 3 ,
164+ bitPos = pos & 7 ;
165+ return (
166+ ( ( imageData [ bytePos ] ! + ( imageData [ bytePos + 1 ] ! << 8 ) + ( imageData [ bytePos + 2 ] ! << 16 ) ) &
167+ ( ( ( 1 << len ) - 1 ) << bitPos ) ) >>>
168+ bitPos
169+ ) ;
170+ }
171+
159172/**
160173 * __parsing one image block in GIF data stream__
161174 * @param byteStream - GIF data stream
@@ -239,22 +252,7 @@ async function parseImageBlock(
239252
240253 const minCodeSize = byteStream . nextByte ( ) ,
241254 imageData = byteStream . readSubBlocksBin ( ) ,
242- clearCode = 1 << minCodeSize ,
243- /**
244- * __read `len` bits from `imageData` at `pos`__
245- * @param pos - bit position in `imageData`
246- * @param len - bit length to read [1-12 bits]
247- * @returns `len` bits at `pos`
248- */
249- readBits = ( pos : number , len : number ) : number => {
250- const bytePos = pos >>> 3 ,
251- bitPos = pos & 7 ;
252- return (
253- ( ( imageData [ bytePos ] ! + ( imageData [ bytePos + 1 ] ! << 8 ) + ( imageData [ bytePos + 2 ] ! << 16 ) ) &
254- ( ( ( 1 << len ) - 1 ) << bitPos ) ) >>>
255- bitPos
256- ) ;
257- } ;
255+ clearCode = 1 << minCodeSize ;
258256
259257 if ( interlacedFlag ) {
260258 for ( let code = 0 , size = minCodeSize + 1 , pos = 0 , dic = [ [ 0 ] ] , pass = 0 ; pass < 4 ; pass ++ ) {
@@ -266,7 +264,7 @@ async function parseImageBlock(
266264 while ( ! exit ) {
267265 const last = code ;
268266
269- code = readBits ( pos , size ) ;
267+ code = readBits ( imageData , pos , size ) ;
270268 pos += size + 1 ;
271269
272270 if ( code === clearCode ) {
@@ -333,7 +331,7 @@ async function parseImageBlock(
333331 for ( ; ; ) {
334332 const last = code ;
335333
336- code = readBits ( pos , size ) ;
334+ code = readBits ( imageData , pos , size ) ;
337335 pos += size ;
338336
339337 if ( code === clearCode ) {
@@ -431,7 +429,7 @@ export function getGIFLoopAmount(gif: GIF): number {
431429 return extension . data [ 1 ] ! + ( extension . data [ 2 ] ! << 8 ) ;
432430 }
433431
434- return NaN ;
432+ return Number . NaN ;
435433}
436434
437435/**
@@ -634,7 +632,7 @@ export function drawGif(data: IShapeDrawData<ImageParticle>, canvasSettings?: Ca
634632 offscreenContext . imageSmoothingQuality = "low" ;
635633 offscreenContext . imageSmoothingEnabled = false ;
636634
637- offscreenContext . clearRect ( origin . x , origin . y , offscreenCanvas . width , offscreenCanvas . height ) ;
635+ offscreenContext . clearRect ( originPoint . x , originPoint . y , offscreenCanvas . width , offscreenCanvas . height ) ;
638636
639637 particle . gifLoopCount ??= image . gifLoopCount ?? defaultLoopCount ;
640638
@@ -661,7 +659,7 @@ export function drawGif(data: IShapeDrawData<ImageParticle>, canvasSettings?: Ca
661659
662660 context . drawImage ( offscreenCanvas , pos . x , pos . y ) ;
663661
664- offscreenContext . clearRect ( origin . x , origin . y , offscreenCanvas . width , offscreenCanvas . height ) ;
662+ offscreenContext . clearRect ( originPoint . x , originPoint . y , offscreenCanvas . width , offscreenCanvas . height ) ;
665663
666664 break ;
667665 case DisposalMethod . Combine :
@@ -675,7 +673,7 @@ export function drawGif(data: IShapeDrawData<ImageParticle>, canvasSettings?: Ca
675673
676674 context . drawImage ( offscreenCanvas , pos . x , pos . y ) ;
677675
678- offscreenContext . clearRect ( origin . x , origin . y , offscreenCanvas . width , offscreenCanvas . height ) ;
676+ offscreenContext . clearRect ( originPoint . x , originPoint . y , offscreenCanvas . width , offscreenCanvas . height ) ;
679677
680678 if ( ! image . gifData . globalColorTable . length ) {
681679 offscreenContext . putImageData ( image . gifData . frames [ firstIndex ] ! . image , pos . x + frame . left , pos . y + frame . top ) ;
@@ -687,8 +685,8 @@ export function drawGif(data: IShapeDrawData<ImageParticle>, canvasSettings?: Ca
687685 case DisposalMethod . RestorePrevious :
688686 {
689687 const previousImageData = offscreenContext . getImageData (
690- origin . x ,
691- origin . y ,
688+ originPoint . x ,
689+ originPoint . y ,
692690 offscreenCanvas . width ,
693691 offscreenCanvas . height ,
694692 ) ;
@@ -697,8 +695,8 @@ export function drawGif(data: IShapeDrawData<ImageParticle>, canvasSettings?: Ca
697695
698696 context . drawImage ( offscreenCanvas , pos . x , pos . y ) ;
699697
700- offscreenContext . clearRect ( origin . x , origin . y , offscreenCanvas . width , offscreenCanvas . height ) ;
701- offscreenContext . putImageData ( previousImageData , origin . x , origin . y ) ;
698+ offscreenContext . clearRect ( originPoint . x , originPoint . y , offscreenCanvas . width , offscreenCanvas . height ) ;
699+ offscreenContext . putImageData ( previousImageData , originPoint . x , originPoint . y ) ;
702700 }
703701 break ;
704702 }
@@ -716,7 +714,7 @@ export function drawGif(data: IShapeDrawData<ImageParticle>, canvasSettings?: Ca
716714 frameIndex = firstIndex ;
717715
718716 // ? so apparently some GIFs seam to set the disposal method of the last frame wrong?...so this is a "fix" for that (clear after the last frame)
719- offscreenContext . clearRect ( origin . x , origin . y , offscreenCanvas . width , offscreenCanvas . height ) ;
717+ offscreenContext . clearRect ( originPoint . x , originPoint . y , offscreenCanvas . width , offscreenCanvas . height ) ;
720718 }
721719
722720 particle . gifFrame = frameIndex ;
0 commit comments