Skip to content

Commit

Permalink
fix(ops): output single frame before evaluating timeout (#201)
Browse files Browse the repository at this point in the history
  • Loading branch information
Waldeedle authored and skidder committed Dec 2, 2024
1 parent 5266da5 commit 4cb4523
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 61 deletions.
9 changes: 5 additions & 4 deletions ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,6 @@ func (o *ImageOps) Transform(d Decoder, opt *ImageOptions, dst []byte) ([]byte,

// transform the frames and encode them until we run out of frames or the timeout is reached
for {
// break out if we're creating a single frame and we've already done one
if opt.DisableAnimatedOutput && frameCount > 0 {
return o.encodeEmpty(enc, opt.EncodeOptions)
}
err = o.decode(d)
emptyFrame := false
if err != nil {
Expand Down Expand Up @@ -333,6 +329,11 @@ func (o *ImageOps) Transform(d Decoder, opt *ImageOptions, dst []byte) ([]byte,

frameCount++

// break out if we're creating a single frame and we've already done one
if opt.DisableAnimatedOutput {
return o.encodeEmpty(enc, opt.EncodeOptions)
}

if opt.MaxEncodeFrames != 0 && frameCount == opt.MaxEncodeFrames {
err = o.skipToEnd(d)
if err != io.EOF {
Expand Down
134 changes: 77 additions & 57 deletions webp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,60 +224,67 @@ func testNewWebpEncoderWithAnimatedWebPSource(t *testing.T) {
quality int
resizeMethod ImageOpsSizeMethod
disableAnimatedOutput bool
encodeTimeout time.Duration
}{
{
name: "Animated WebP - Party Discord",
inputPath: "testdata/party-discord.webp",
outputPath: "testdata/out/party-discord_out_webpsource_resize.webp",
width: 26,
height: 17,
quality: 60,
resizeMethod: ImageOpsResize,
name: "Animated WebP - Party Discord",
inputPath: "testdata/party-discord.webp",
outputPath: "testdata/out/party-discord_out_webpsource_resize.webp",
width: 26,
height: 17,
quality: 60,
resizeMethod: ImageOpsResize,
encodeTimeout: 300,
},
{
name: "Animated WebP - Resize #1",
inputPath: "testdata/ferry_sunset.webp",
outputPath: "testdata/out/ferry_sunset_out_resize.webp",
width: 266,
height: 99,
quality: 60,
resizeMethod: ImageOpsResize,
name: "Animated WebP - Resize #1",
inputPath: "testdata/ferry_sunset.webp",
outputPath: "testdata/out/ferry_sunset_out_resize.webp",
width: 266,
height: 99,
quality: 60,
resizeMethod: ImageOpsResize,
encodeTimeout: 300,
},
{
name: "Animated WebP - Resize #2",
inputPath: "testdata/animated-webp-supported.webp",
outputPath: "testdata/out/animated-webp-supported_out_resize.webp",
width: 400,
height: 400,
quality: 60,
resizeMethod: ImageOpsResize,
name: "Animated WebP - Resize #2",
inputPath: "testdata/animated-webp-supported.webp",
outputPath: "testdata/out/animated-webp-supported_out_resize.webp",
width: 400,
height: 400,
quality: 60,
resizeMethod: ImageOpsResize,
encodeTimeout: 300,
},
{
name: "Animated WebP - Fit #1",
inputPath: "testdata/animated-webp-supported.webp",
outputPath: "testdata/out/animated-webp-supported_out_fit.webp",
width: 400,
height: 400,
quality: 80,
resizeMethod: ImageOpsFit,
name: "Animated WebP - Fit #1",
inputPath: "testdata/animated-webp-supported.webp",
outputPath: "testdata/out/animated-webp-supported_out_fit.webp",
width: 400,
height: 400,
quality: 80,
resizeMethod: ImageOpsFit,
encodeTimeout: 300,
},
{
name: "Animated WebP - No resize",
inputPath: "testdata/animated-webp-supported.webp",
outputPath: "testdata/out/animated-webp-supported_out_no_resize.webp",
width: 0,
height: 0,
quality: 100,
resizeMethod: ImageOpsNoResize,
name: "Animated WebP - No resize",
inputPath: "testdata/animated-webp-supported.webp",
outputPath: "testdata/out/animated-webp-supported_out_no_resize.webp",
width: 0,
height: 0,
quality: 100,
resizeMethod: ImageOpsNoResize,
encodeTimeout: 300,
},
{
name: "Animated WebP - Fit #2",
inputPath: "testdata/animated-webp-supported.webp",
outputPath: "testdata/out/animated-webp-supported_out.webp",
width: 200,
height: 200,
quality: 60,
resizeMethod: ImageOpsFit,
name: "Animated WebP - Fit #2",
inputPath: "testdata/animated-webp-supported.webp",
outputPath: "testdata/out/animated-webp-supported_out.webp",
width: 200,
height: 200,
quality: 60,
resizeMethod: ImageOpsFit,
encodeTimeout: 300,
},
{
name: "Animated WebP - create single frame",
Expand All @@ -288,24 +295,37 @@ func testNewWebpEncoderWithAnimatedWebPSource(t *testing.T) {
quality: 60,
resizeMethod: ImageOpsFit,
disableAnimatedOutput: true,
encodeTimeout: 300,
},
{
name: "Animated WebP - Crashing input",
inputPath: "testdata/8202024-BGS-Headless-Horseman-OO-1200x1200-optimize.webp",
outputPath: "testdata/out/8202024-BGS-Headless-Horseman-OO-1200x1200-optimize_out.webp",
width: 200,
height: 200,
quality: 60,
resizeMethod: ImageOpsFit,
name: "Animated WebP - create single frame without encode timeout set",
inputPath: "testdata/big_buck_bunny_720_5s.webp",
outputPath: "testdata/out/big_buck_bunny_720_5s_single_frame_out_without_encode_timeout_set.webp",
width: 200,
height: 200,
quality: 60,
resizeMethod: ImageOpsFit,
disableAnimatedOutput: true,
},
{
name: "Animated WebP - Crashing input",
inputPath: "testdata/8202024-BGS-Headless-Horseman-OO-1200x1200-optimize.webp",
outputPath: "testdata/out/8202024-BGS-Headless-Horseman-OO-1200x1200-optimize_out.webp",
width: 200,
height: 200,
quality: 60,
resizeMethod: ImageOpsFit,
encodeTimeout: 300,
},
{
name: "Animated WebP - complex dispose and blend",
inputPath: "testdata/complex_dispose_and_blend.webp",
outputPath: "testdata/out/complex_dispose_and_blend_out.webp",
width: 960,
height: 540,
quality: 60,
resizeMethod: ImageOpsFit,
name: "Animated WebP - complex dispose and blend",
inputPath: "testdata/complex_dispose_and_blend.webp",
outputPath: "testdata/out/complex_dispose_and_blend_out.webp",
width: 960,
height: 540,
quality: 60,
resizeMethod: ImageOpsFit,
encodeTimeout: 300,
},
}

Expand Down Expand Up @@ -337,7 +357,7 @@ func testNewWebpEncoderWithAnimatedWebPSource(t *testing.T) {
ResizeMethod: tc.resizeMethod,
Width: tc.width,
Height: tc.height,
EncodeTimeout: time.Second * 300,
EncodeTimeout: time.Second * tc.encodeTimeout,
DisableAnimatedOutput: tc.disableAnimatedOutput,
}

Expand Down

0 comments on commit 4cb4523

Please sign in to comment.