Skip to content

Commit 976b322

Browse files
committed
fix delay metadata for webp and jxl save
we could modify a const pointer in some cases, causing unexpected side effects via the operation cache see #4479
1 parent c0f7970 commit 976b322

File tree

3 files changed

+43
-38
lines changed

3 files changed

+43
-38
lines changed

libvips/foreign/cgifsave.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -666,8 +666,7 @@ vips_foreign_save_cgif_write_frame(VipsForeignSaveCgif *cgif)
666666

667667
if (cgif->delay &&
668668
cgif->page_number < cgif->delay_length)
669-
frame_config.delay =
670-
rint(cgif->delay[cgif->page_number] / 10.0);
669+
frame_config.delay = rint(cgif->delay[cgif->page_number] / 10.0);
671670

672671
/* Attach a local palette, if we need one.
673672
*/

libvips/foreign/jxlsave.c

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,24 @@ vips_foreign_save_jxl_process_output(VipsForeignSaveJxl *jxl)
302302
return 0;
303303
}
304304

305+
static int
306+
vips_foreign_save_jxl_get_delay(VipsForeignSaveJxl *jxl, int page_number)
307+
{
308+
int delay;
309+
310+
if (jxl->delay &&
311+
page_number < jxl->delay_length)
312+
delay = jxl->delay[page_number];
313+
else
314+
// the old gif delay field was in centiseconds, so convert to ms
315+
delay = jxl->gif_delay * 10;
316+
317+
/* Force frames with a small or no duration to 100ms for consistency
318+
* with web browsers and other transcoding tools.
319+
*/
320+
return VIPS_MIN(100, delay);
321+
}
322+
305323
static int
306324
vips_foreign_save_jxl_add_frame(VipsForeignSaveJxl *jxl)
307325
{
@@ -326,10 +344,9 @@ vips_foreign_save_jxl_add_frame(VipsForeignSaveJxl *jxl)
326344

327345
if (!jxl->is_animated)
328346
header.duration = 0xffffffff;
329-
else if (jxl->delay && jxl->page_number < jxl->delay_length)
330-
header.duration = jxl->delay[jxl->page_number];
331347
else
332-
header.duration = jxl->gif_delay * 10;
348+
header.duration =
349+
vips_foreign_save_jxl_get_delay(jxl, jxl->page_number);
333350

334351
JxlEncoderSetFrameHeader(frame_settings, &header);
335352
}
@@ -472,7 +489,6 @@ vips_foreign_save_jxl_build(VipsObject *object)
472489

473490
VipsImage *in;
474491
VipsBandFormat format;
475-
int i;
476492

477493
if (VIPS_OBJECT_CLASS(vips_foreign_save_jxl_parent_class)->build(object))
478494
return -1;
@@ -696,8 +712,7 @@ vips_foreign_save_jxl_build(VipsObject *object)
696712
*/
697713
jxl->gif_delay = 10;
698714
if (vips_image_get_typeof(save->ready, "gif-delay") &&
699-
vips_image_get_int(save->ready, "gif-delay",
700-
&jxl->gif_delay))
715+
vips_image_get_int(save->ready, "gif-delay", &jxl->gif_delay))
701716
return -1;
702717

703718
/* New images have an array of ints instead.
@@ -714,17 +729,6 @@ vips_foreign_save_jxl_build(VipsObject *object)
714729
if (vips_image_get_typeof(save->ready, "delay") ||
715730
vips_image_get_typeof(save->ready, "gif-delay"))
716731
jxl->is_animated = TRUE;
717-
718-
/* Force frames with a small or no duration to 100ms
719-
* to be consistent with web browsers and other
720-
* transcoding tools.
721-
*/
722-
if (jxl->gif_delay <= 1)
723-
jxl->gif_delay = 10;
724-
725-
for (i = 0; i < jxl->delay_length; i++)
726-
if (jxl->delay[i] <= 10)
727-
jxl->delay[i] = 100;
728732
}
729733

730734
#ifdef DEBUG

libvips/foreign/webpsave.c

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,24 @@ vips_foreign_save_webp_write_webp_image(VipsForeignSaveWebp *webp,
294294
return 0;
295295
}
296296

297+
static int
298+
vips_foreign_save_webp_get_delay(VipsForeignSaveWebp *webp, int page_number)
299+
{
300+
int delay;
301+
302+
if (webp->delay &&
303+
page_number < webp->delay_length)
304+
delay = webp->delay[page_number];
305+
else
306+
// the old gif delay field was in centiseconds, so convert to ms
307+
delay = webp->gif_delay * 10;
308+
309+
/* Force frames with a small or no duration to 100ms for consistency
310+
* with web browsers and other transcoding tools.
311+
*/
312+
return VIPS_MIN(100, delay);
313+
}
314+
297315
/* We have a complete frame --- write!
298316
*/
299317
static int
@@ -318,11 +336,8 @@ vips_foreign_save_webp_write_frame(VipsForeignSaveWebp *webp)
318336

319337
/* Adjust current timestamp
320338
*/
321-
if (webp->delay &&
322-
webp->page_number < webp->delay_length)
323-
webp->timestamp_ms += webp->delay[webp->page_number];
324-
else
325-
webp->timestamp_ms += webp->gif_delay * 10;
339+
webp->timestamp_ms +=
340+
vips_foreign_save_webp_get_delay(webp, webp->page_number);
326341
}
327342
else {
328343
/* Single image write
@@ -636,7 +651,6 @@ vips_foreign_save_webp_init_anim_enc(VipsForeignSaveWebp *webp)
636651
int page_height = vips_image_get_page_height(save->ready);
637652

638653
WebPAnimEncoderOptions anim_config;
639-
int i;
640654

641655
/* Init config for animated write
642656
*/
@@ -659,31 +673,19 @@ vips_foreign_save_webp_init_anim_enc(VipsForeignSaveWebp *webp)
659673
/* Get delay array
660674
*
661675
* There might just be the old gif-delay field. This is centiseconds.
676+
* New images have an array of ints giving millisecond durations.
662677
*/
663678
webp->gif_delay = 10;
664679
if (vips_image_get_typeof(save->ready, "gif-delay") &&
665680
vips_image_get_int(save->ready, "gif-delay", &webp->gif_delay))
666681
return -1;
667682

668-
/* New images have an array of ints instead.
669-
*/
670683
webp->delay = NULL;
671684
if (vips_image_get_typeof(save->ready, "delay") &&
672685
vips_image_get_array_int(save->ready, "delay",
673686
&webp->delay, &webp->delay_length))
674687
return -1;
675688

676-
/* Force frames with a small or no duration to 100ms
677-
* to be consistent with web browsers and other
678-
* transcoding tools.
679-
*/
680-
if (webp->gif_delay <= 1)
681-
webp->gif_delay = 10;
682-
683-
for (i = 0; i < webp->delay_length; i++)
684-
if (webp->delay[i] <= 10)
685-
webp->delay[i] = 100;
686-
687689
return 0;
688690
}
689691

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy