You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 771cdcd
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -35,6 +35,8 @@ Upgrading from 3.x? Upgrade to the latest 3.x release first, fix the deprecation
35
35
36
36
-**The positional arguments of `new Frame()`, `Frame.from()` and `new Animation()` are removed, and `Animation.decode()` takes no flag**: `new Frame(width, height, duration, xOffset, yOffset, disposalMode)` is `new Frame(width, height, { duration, xOffset, yOffset, disposalMode })`, `Frame.from(image, duration, xOffset, yOffset, disposalMode)` is `Frame.from(image, { duration, xOffset, yOffset, disposalMode })`, `new Animation(frames, loopCount)` is `new Animation(frames, { loopCount })`, and `Animation.decode(data, true)` is `Animation.decode(data, { onlyFirstFrame: true })`.
37
37
38
+
-**`Image.decode()` returns the first frame of an animation**: a GIF or an animated WebP, which threw in 3.x, is an `Image` of its first frame, composed onto the canvas as `Animation.decode()` composes it, and decoding stops after that frame, so it is fast on long animations. Animated JPEG XLs and AVIF sequences were already their first frame. An APNG is still its default image, what viewers without APNG support show. Use `Animation.decode()` for all the frames.
39
+
38
40
-**`decode()` returns an `Animation` only for files with several frames**: a GIF, APNG, animated WebP or JPEG XL with more than one frame is an `Animation` (`decode(gif)` used to be a `GIF`), and one with a single frame is an `Image`, like a still image (a one-frame GIF used to be a `GIF`). With `onlyFirstFrame`, the first frame comes back as an `Image`, since the frame count isn't read.
39
41
40
42
-**The `GIF` class is removed**: `new GIF(frames, loopCount)` is `new Animation(frames, { loopCount })`, `GIF.decode(data)` is `Animation.decode(data)` and `gif.encode(quality)` is `animation.encodeGIF({ quality })`. `Animation` decodes and encodes GIFs the same way it does APNGs and WebPs.
if(frames.length!==4)panic(`${name}: ${frames.length} frames instead of 4`);
169
+
constreference=frames[0];
170
+
if(image.width!==reference.width||image.height!==reference.height)panic(`${name}: ${image.width}x${image.height} instead of ${reference.width}x${reference.height}`);
171
+
if(sha256(image.bitmap)!==sha256(reference.bitmap))panic(`${name}: Image.decode is not the first frame of Animation.decode`);
172
+
if(sha256(image.bitmap)===sha256(frames[1].bitmap))panic(`${name}: the frames should differ`);
173
+
}
174
+
// options apply to the first frame: maxPixels counts the canvas
175
+
awaitthrowsA(()=>Image.decode(movingFiles.GIF,{maxPixels: 10}),RangeError,'Image.decode maxPixels of an animated GIF');
176
+
if((awaitImage.decode(movingFiles.GIF,{maxPixels: 96})).width!==12)panic('Image.decode: a GIF whose canvas fits maxPixels should decode');
177
+
178
+
// an APNG whose default image (IDAT) isn't part of the animation: Image.decode gives that image, what viewers without
179
+
// APNG support show, and Animation.decode only the frames of the animation
if(shown.constructor!==Image||sha256(shown.bitmap)!==sha256((awaitImage.decode(defaultPNG)).bitmap))panic('APNG with a separate default image: Image.decode should give the default image');
212
+
constanimated=awaitAnimation.decode(separate);
213
+
if(animated.length!==1||sha256(animated.frames[0].bitmap)!==sha256((awaitImage.decode(framePNG)).bitmap))panic('APNG with a separate default image: Animation.decode should give only the animation\'s frame');
214
+
215
+
// a large animation: Image.decode stops after its first frame, so it takes a fraction of the time of all 50 frames
if(firstFrame.constructor!==Image||firstFrame.width!==96||firstFrame.height!==72)panic('animated WebP: Image.decode should give an Image of the canvas');
43
+
if(sha256(firstFrame.bitmap)!==animated[0])panic('animated WebP: Image.decode is not the first frame libwebp composites');
47
44
constanimation=awaitAnimation.decode(data);
48
45
if(!(awaitdecode(data)instanceofAnimation))panic('decode() should return an Animation for animated WebPs');
49
46
if(animation.length!==4||animation.loopCount!==Infinity)panic('animated WebP: wrong frame or loop count');
0 commit comments