From e353a684c26b07f1cd482092c7560f7c4d483a49 Mon Sep 17 00:00:00 2001 From: Kim Woelders Date: Thu, 27 Oct 2022 18:40:36 +0200 Subject: [PATCH] multiframe: Move frame info to allocated record Avoid the overhead in ImlibImage when not doing multiframe loads. --- src/lib/Imlib2_Loader.h | 21 ++++++---- src/lib/api.c | 26 ++++++++---- src/lib/image.c | 24 +++++++++-- src/lib/image.h | 23 +++++++---- src/modules/loaders/loader_gif.c | 68 ++++++++++++++++++------------ src/modules/loaders/loader_ico.c | 8 ++-- src/modules/loaders/loader_jxl.c | 30 ++++++++------ src/modules/loaders/loader_png.c | 69 +++++++++++++++++-------------- src/modules/loaders/loader_ps.c | 10 +++-- src/modules/loaders/loader_webp.c | 47 ++++++++++++--------- 10 files changed, 200 insertions(+), 126 deletions(-) diff --git a/src/lib/Imlib2_Loader.h b/src/lib/Imlib2_Loader.h index a8f650c..8b77165 100644 --- a/src/lib/Imlib2_Loader.h +++ b/src/lib/Imlib2_Loader.h @@ -131,6 +131,17 @@ typedef struct _ImlibImageTag { struct _ImlibImageTag *next; } ImlibImageTag; +typedef struct { + int canvas_w; /* Canvas size */ + int canvas_h; + int frame_count; /* Number of frames */ + int frame_x; /* Frame origin */ + int frame_y; + int frame_flags; /* Frame flags */ + int frame_delay; /* Frame delay (ms) */ + int loop_count; /* Animation loops */ +} ImlibImageFrame; + struct _ImlibImage { ImlibImageFileInfo *fi; ImlibLdCtx *lc; @@ -141,14 +152,6 @@ struct _ImlibImage { char rsvd[3]; int frame; - int canvas_w; /* Canvas size */ - int canvas_h; - int frame_count; /* Number of frames */ - int frame_x; /* Frame origin */ - int frame_y; - int frame_flags; /* Frame flags */ - int frame_delay; /* Frame delay (ms) */ - int loop_count; /* Animation loops */ }; /* Must match the ones in Imlib2.h.in */ @@ -176,6 +179,8 @@ void __imlib_FreeTag(ImlibImage * im, ImlibImageTag * t); const char *__imlib_GetKey(const ImlibImage * im); +ImlibImageFrame *__imlib_GetFrame(ImlibImage * im); + void __imlib_LoadProgressSetPass(ImlibImage * im, int pass, int n_pass); int __imlib_LoadProgress(ImlibImage * im, diff --git a/src/lib/api.c b/src/lib/api.c index 41595a4..9409c61 100644 --- a/src/lib/api.c +++ b/src/lib/api.c @@ -677,21 +677,31 @@ EAPI void imlib_image_get_frame_info(Imlib_Frame_Info * info) { ImlibImage *im; + ImlibImageFrame *fp; CHECK_PARAM_POINTER("image", ctx->image); CAST_IMAGE(im, ctx->image); - info->loop_count = im->loop_count; - info->frame_count = im->frame_count; + fp = im->pframe; + if (!fp) + { + memset(info, 0, sizeof(Imlib_Frame_Info)); + info->canvas_w = info->frame_w = im->w; + info->canvas_h = info->frame_h = im->h; + return; + } + + info->loop_count = fp->loop_count; + info->frame_count = fp->frame_count; info->frame_num = im->frame; - info->canvas_w = im->canvas_w ? im->canvas_w : im->w; - info->canvas_h = im->canvas_h ? im->canvas_h : im->h; - info->frame_x = im->frame_x; - info->frame_y = im->frame_y; + info->canvas_w = fp->canvas_w ? fp->canvas_w : im->w; + info->canvas_h = fp->canvas_h ? fp->canvas_h : im->h; + info->frame_x = fp->frame_x; + info->frame_y = fp->frame_y; info->frame_w = im->w; info->frame_h = im->h; - info->frame_flags = im->frame_flags; - info->frame_delay = im->frame_delay ? im->frame_delay : 100; + info->frame_flags = fp->frame_flags; + info->frame_delay = fp->frame_delay ? fp->frame_delay : 100; } EAPI void diff --git a/src/lib/image.c b/src/lib/image.c index 820de3a..73860c7 100644 --- a/src/lib/image.c +++ b/src/lib/image.c @@ -207,6 +207,8 @@ __imlib_ConsumeImage(ImlibImage * im) if (im->fi) __imlib_ImageFileContextPop(im); + free(im->pframe); + free(im); } @@ -729,8 +731,11 @@ __imlib_LoadProgress(ImlibImage * im, int x, int y, int w, int h) lc->area += w * h; lc->pct = (100. * lc->area + .1) / (im->w * im->h); - x += im->frame_x; - y += im->frame_y; + if (im->pframe) + { + x += im->pframe->frame_x; + y += im->pframe->frame_y; + } rc = !lc->progress(im, lc->pct, x, y, w, h); @@ -762,8 +767,11 @@ __imlib_LoadProgressRows(ImlibImage * im, int row, int nrows) pct = (100 * nrtot * (lc->pass + 1)) / (im->h * lc->n_pass); if (pct == 100 || pct >= lc->pct + lc->granularity) { - col += im->frame_x; - row += im->frame_y; + if (im->pframe) + { + col += im->pframe->frame_x; + row += im->pframe->frame_y; + } rc = !lc->progress(im, pct, col, row, im->w, nrows); lc->row = nrtot; lc->pct += lc->granularity; @@ -772,6 +780,14 @@ __imlib_LoadProgressRows(ImlibImage * im, int row, int nrows) return rc; } +__EXPORT__ ImlibImageFrame * +__imlib_GetFrame(ImlibImage * im) +{ + if (im->frame > 0 && !im->pframe) + im->pframe = calloc(1, sizeof(ImlibImageFrame)); + return im->pframe; +} + /* free and image - if its uncachable and refcoutn is 0 - free it in reality */ void __imlib_FreeImage(ImlibImage * im) diff --git a/src/lib/image.h b/src/lib/image.h index a0a1765..0c3ed0f 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -42,6 +42,17 @@ typedef struct _ImlibImageTag { struct _ImlibImageTag *next; } ImlibImageTag; +typedef struct { + int canvas_w; /* Canvas size */ + int canvas_h; + int frame_count; /* Number of frames */ + int frame_x; /* Frame origin */ + int frame_y; + int frame_flags; /* Frame flags */ + int frame_delay; /* Frame delay (ms) */ + int loop_count; /* Animation loops */ +} ImlibImageFrame; + struct _ImlibImage { ImlibImageFileInfo *fi; ImlibLdCtx *lc; @@ -52,14 +63,6 @@ struct _ImlibImage { char rsvd[3]; int frame; - int canvas_w; /* Canvas size */ - int canvas_h; - int frame_count; /* Number of frames */ - int frame_x; /* Frame origin */ - int frame_y; - int frame_flags; /* Frame flags */ - int frame_delay; /* Frame delay (ms) */ - int loop_count; /* Animation loops */ /* vvv Private vvv */ ImlibLoader *loader; @@ -75,6 +78,8 @@ struct _ImlibImage { ImlibBorder border; ImlibImageTag *tags; ImlibImageDataMemoryFunction data_memory_func; + + ImlibImageFrame *pframe; /* ^^^ Private ^^^ */ }; @@ -124,6 +129,8 @@ ImlibImageTag *__imlib_RemoveTag(ImlibImage * im, const char *key); void __imlib_FreeTag(ImlibImage * im, ImlibImageTag * t); void __imlib_FreeAllTags(ImlibImage * im); +ImlibImageFrame *__imlib_GetFrame(ImlibImage * im); + void __imlib_SetCacheSize(int size); int __imlib_GetCacheSize(void); int __imlib_CurrentCacheSize(void); diff --git a/src/modules/loaders/loader_gif.c b/src/modules/loaders/loader_gif.c index aac328a..3d49715 100644 --- a/src/modules/loaders/loader_gif.c +++ b/src/modules/loaders/loader_gif.c @@ -65,7 +65,9 @@ _load(ImlibImage * im, int load_data) int i, j, bg, bits; int transp; uint32_t colormap[256]; - int fcount, frame, multiframe; + int fcount, frame; + bool multiframe; + ImlibImageFrame *pf; rc = LOAD_FAIL; rows = NULL; @@ -85,20 +87,21 @@ _load(ImlibImage * im, int load_data) transp = -1; fcount = 0; frame = im->frame; - if (frame > 0) + pf = __imlib_GetFrame(im); + if (pf) { - im->frame_count = gif->ImageCount; - im->loop_count = 0; /* Loop forever */ - if (im->frame_count > 1) - im->frame_flags |= FF_IMAGE_ANIMATED; - im->canvas_w = gif->SWidth; - im->canvas_h = gif->SHeight; + pf->frame_count = gif->ImageCount; + pf->loop_count = 0; /* Loop forever */ + if (pf->frame_count > 1) + pf->frame_flags |= FF_IMAGE_ANIMATED; + pf->canvas_w = gif->SWidth; + pf->canvas_h = gif->SHeight; D("Canvas WxH=%dx%d frames=%d repeat=%d\n", - im->canvas_w, im->canvas_h, im->frame_count, im->loop_count); + pf->canvas_w, pf->canvas_h, pf->frame_count, pf->loop_count); #if 0 - if (frame > 1 && frame > im->frame_count) + if (frame > 1 && frame > pf->frame_count) goto quit; #endif } @@ -155,16 +158,23 @@ _load(ImlibImage * im, int load_data) im->w = gif->Image.Width; im->h = gif->Image.Height; - im->frame_x = gif->Image.Left; - im->frame_y = gif->Image.Top; + if (pf) + { + pf->frame_x = gif->Image.Left; + pf->frame_y = gif->Image.Top; + + D("Canvas WxH=%dx%d frame=%d/%d X,Y=%d,%d WxH=%dx%d\n", + pf->canvas_w, pf->canvas_h, gif->ImageCount, + pf->frame_count, pf->frame_x, pf->frame_y, im->w, im->h); + } + else + { + D("WxH=%dx%d\n", im->w, im->h); + } if (!IMAGE_DIMENSIONS_OK(im->w, im->h)) goto quit; - D("Canvas WxH=%dx%d frame=%d/%d X,Y=%d,%d WxH=%dx%d\n", - im->canvas_w, im->canvas_h, gif->ImageCount, im->frame_count, - im->frame_x, im->frame_y, im->w, im->h); - DL(" CM S=%p I=%p\n", cmap, gif->Image.ColorMap); if (gif->Image.ColorMap) cmap = gif->Image.ColorMap; @@ -203,7 +213,7 @@ _load(ImlibImage * im, int load_data) } /* Break if no specific frame was requested */ - if (frame == 0) + if (!pf) break; } else if (rec == EXTENSION_RECORD_TYPE) @@ -218,20 +228,20 @@ _load(ImlibImage * im, int load_data) DL(" EXTENSION_RECORD_TYPE(%d): ic=%d: ext_code=%02x: %02x %02x %02x %02x %02x\n", // rec, gif->ImageCount, ext_code, ext[0], ext[1], ext[2], ext[3], ext[4]); - if (ext_code == GRAPHICS_EXT_FUNC_CODE + if (pf && ext_code == GRAPHICS_EXT_FUNC_CODE && gif->ImageCount == frame - 1) { bits = ext[1]; - im->frame_delay = 10 * (0x100 * ext[3] + ext[2]); + pf->frame_delay = 10 * (0x100 * ext[3] + ext[2]); if (bits & 1) transp = ext[4]; disp = (bits >> 2) & 0x7; if (disp == 2 || disp == 3) - im->frame_flags |= FF_FRAME_DISPOSE_CLEAR; - im->frame_flags |= FF_FRAME_BLEND; + pf->frame_flags |= FF_FRAME_DISPOSE_CLEAR; + pf->frame_flags |= FF_FRAME_BLEND; D(" Frame %d: disp=%d ui=%d tr=%d, delay=%d transp = #%02x\n", // gif->ImageCount + 1, disp, (bits >> 1) & 1, bits & 1, - im->frame_delay, transp); + pf->frame_delay, transp); } ext = NULL; DGifGetExtensionNext(gif, &ext); @@ -244,14 +254,18 @@ _load(ImlibImage * im, int load_data) } im->has_alpha = transp >= 0; - im->frame_count = fcount; - multiframe = im->frame_count > 1; - if (multiframe) - im->frame_flags |= FF_IMAGE_ANIMATED; + multiframe = false; + if (pf) + { + pf->frame_count = fcount; + multiframe = pf->frame_count > 1; + if (multiframe) + pf->frame_flags |= FF_IMAGE_ANIMATED; + } if (!rows) { - if (frame > 1 && frame > im->frame_count) + if (pf && frame > 1 && frame > pf->frame_count) QUIT_WITH_RC(LOAD_BADFRAME); goto quit; diff --git a/src/modules/loaders/loader_ico.c b/src/modules/loaders/loader_ico.c index 0ebf4ec..5225971 100644 --- a/src/modules/loaders/loader_ico.c +++ b/src/modules/loaders/loader_ico.c @@ -272,6 +272,7 @@ _load(ImlibImage * im, int load_data) ie_t *ie; uint32_t *pdst; uint32_t pixel; + ImlibImageFrame *pf; rc = LOAD_FAIL; @@ -304,11 +305,12 @@ _load(ImlibImage * im, int load_data) rc = LOAD_BADIMAGE; /* Format accepted */ frame = im->frame; - if (frame > 0) + pf = __imlib_GetFrame(im); + if (pf) { - im->frame_count = ico.idir.icons; + pf->frame_count = ico.idir.icons; - if (frame > 1 && frame > im->frame_count) + if (frame > 1 && frame > pf->frame_count) QUIT_WITH_RC(LOAD_BADFRAME); } diff --git a/src/modules/loaders/loader_jxl.c b/src/modules/loaders/loader_jxl.c index 8bd9acc..07528b2 100644 --- a/src/modules/loaders/loader_jxl.c +++ b/src/modules/loaders/loader_jxl.c @@ -48,6 +48,7 @@ _load(ImlibImage * im, int load_data) JxlBasicInfo info; JxlFrameHeader fhdr; int frame, delay_unit; + ImlibImageFrame *pf; #if MAX_RUNNERS > 0 size_t n_runners; @@ -100,6 +101,7 @@ _load(ImlibImage * im, int load_data) goto quit; frame = im->frame; + pf = __imlib_GetFrame(im); delay_unit = 0; for (;;) @@ -137,23 +139,23 @@ _load(ImlibImage * im, int load_data) im->h = info.ysize; im->has_alpha = info.alpha_bits > 0; - if (frame > 0) + if (pf) { if (info.have_animation) { - im->frame_count = 1234567890; // FIXME - Hack - im->loop_count = info.animation.num_loops; - im->frame_flags |= FF_IMAGE_ANIMATED; - im->canvas_w = info.xsize; - im->canvas_h = info.ysize; + pf->frame_count = 1234567890; // FIXME - Hack + pf->loop_count = info.animation.num_loops; + pf->frame_flags |= FF_IMAGE_ANIMATED; + pf->canvas_w = info.xsize; + pf->canvas_h = info.ysize; } D("Canvas WxH=%dx%d frames=%d repeat=%d\n", - im->canvas_w, im->canvas_h, - im->frame_count, im->loop_count); + pf->canvas_w, pf->canvas_h, + pf->frame_count, pf->loop_count); - if (frame > 1 && im->frame_count > 0 - && frame > im->frame_count) + if (frame > 1 && pf->frame_count > 0 + && frame > pf->frame_count) QUIT_WITH_RC(LOAD_BADFRAME); if (frame > 1) @@ -178,12 +180,14 @@ _load(ImlibImage * im, int load_data) break; case JXL_DEC_FRAME: + if (!pf) + break; JxlDecoderGetFrameHeader(dec, &fhdr); if (fhdr.is_last) - im->frame_count = frame; - im->frame_delay = fhdr.duration * delay_unit; + pf->frame_count = frame; + pf->frame_delay = fhdr.duration * delay_unit; D("Frame duration=%d tc=%08x nl=%d last=%d\n", - im->frame_delay, fhdr.timecode, fhdr.name_length, fhdr.is_last); + pf->frame_delay, fhdr.timecode, fhdr.name_length, fhdr.is_last); break; case JXL_DEC_FULL_IMAGE: diff --git a/src/modules/loaders/loader_png.c b/src/modules/loaders/loader_png.c index 79f5b02..4832499 100644 --- a/src/modules/loaders/loader_png.c +++ b/src/modules/loaders/loader_png.c @@ -274,7 +274,7 @@ row_callback(png_struct * png_ptr, png_byte * new_row, if (im->lc) { - if (im->frame_count > 1) + if (im->frame > 0) { if (done) __imlib_LoadProgress(im, 0, 0, im->w, im->h); @@ -304,6 +304,7 @@ _load(ImlibImage * im, int load_data) int w, h, frame, fcount; bool save_fdat, seen_actl, seen_fctl; png_chunk_t cbuf; + ImlibImageFrame *pf; /* read header */ rc = LOAD_FAIL; @@ -338,7 +339,8 @@ _load(ImlibImage * im, int load_data) info_callback, row_callback, NULL); frame = im->frame; - if (frame <= 0) + pf = __imlib_GetFrame(im); + if (!pf) goto scan_done; /* Animation info requested. Look it up to find the frame's @@ -376,11 +378,11 @@ _load(ImlibImage * im, int load_data) case PNG_TYPE_acTL: seen_actl = true; #define P (&chunk->actl) - im->frame_count = htonl(P->num_frames); - im->loop_count = htonl(P->num_plays); - D("num_frames=%d num_plays=%d\n", im->frame_count, + pf->frame_count = htonl(P->num_frames); + pf->loop_count = htonl(P->num_plays); + D("num_frames=%d num_plays=%d\n", pf->frame_count, htonl(P->num_plays)); - if (frame > im->frame_count) + if (frame > pf->frame_count) QUIT_WITH_RC(LOAD_BADFRAME); break; #undef P @@ -453,29 +455,32 @@ _load(ImlibImage * im, int load_data) im->w = htonl(pfctl->w); im->h = htonl(pfctl->h); #endif - im->canvas_w = w; - im->canvas_h = h; - im->frame_x = htonl(pfctl->x); - im->frame_y = htonl(pfctl->y); - if (pfctl->dispose_op == APNG_DISPOSE_OP_BACKGROUND) - im->frame_flags |= FF_FRAME_DISPOSE_CLEAR; - else if (pfctl->dispose_op == APNG_DISPOSE_OP_PREVIOUS) - im->frame_flags |= FF_FRAME_DISPOSE_PREV; - if (pfctl->blend_op != APNG_BLEND_OP_SOURCE) - im->frame_flags |= FF_FRAME_BLEND; - val = htons(pfctl->delay_den); - if (val == 0) - val = 100; - im->frame_delay = 1000 * htons(pfctl->delay_num) / val; + if (pf) + { + pf->canvas_w = w; + pf->canvas_h = h; + pf->frame_x = htonl(pfctl->x); + pf->frame_y = htonl(pfctl->y); + if (pfctl->dispose_op == APNG_DISPOSE_OP_BACKGROUND) + pf->frame_flags |= FF_FRAME_DISPOSE_CLEAR; + else if (pfctl->dispose_op == APNG_DISPOSE_OP_PREVIOUS) + pf->frame_flags |= FF_FRAME_DISPOSE_PREV; + if (pfctl->blend_op != APNG_BLEND_OP_SOURCE) + pf->frame_flags |= FF_FRAME_BLEND; + val = htons(pfctl->delay_den); + if (val == 0) + val = 100; + pf->frame_delay = 1000 * htons(pfctl->delay_num) / val; - D("WxH=%dx%d(%dx%d) X,Y=%d,%d depth=%d color=%d comp=%d filt=%d interlace=%d disp=%d blend=%d delay=%d/%d\n", // - htonl(pfctl->w), htonl(pfctl->h), - im->canvas_w, im->canvas_h, im->frame_x, im->frame_y, - P->depth, P->color, P->comp, P->filt, P->interl, - pfctl->dispose_op, pfctl->blend_op, - pfctl->delay_num, pfctl->delay_den); + D("WxH=%dx%d(%dx%d) X,Y=%d,%d depth=%d color=%d comp=%d filt=%d interlace=%d disp=%d blend=%d delay=%d/%d\n", // + htonl(pfctl->w), htonl(pfctl->h), + pf->canvas_w, pf->canvas_h, pf->frame_x, pf->frame_y, + P->depth, P->color, P->comp, P->filt, P->interl, + pfctl->dispose_op, pfctl->blend_op, + pfctl->delay_num, pfctl->delay_den); + } - if (frame <= 1) + if (!pf || frame <= 1) break; /* Process actual IHDR chunk */ /* Process fake IHDR for frame */ @@ -493,7 +498,7 @@ _load(ImlibImage * im, int load_data) /* Needed chunks should now be read */ /* Note - Just before starting to process data chunks libpng will * call info_callback() */ - if (im->frame_count <= 0) + if (!pf || pf->frame_count <= 0) break; /* Regular PNG - Process actual IDAT chunk */ if (frame == 1 && seen_fctl) break; /* APNG, First frame is IDAT */ @@ -506,10 +511,12 @@ _load(ImlibImage * im, int load_data) case PNG_TYPE_acTL: #define P (&chunk->actl) - if (im->frame_count > 1) - im->frame_flags |= FF_IMAGE_ANIMATED; + if (!pf) + continue; + if (pf->frame_count > 1) + pf->frame_flags |= FF_IMAGE_ANIMATED; D("num_frames=%d num_plays=%d\n", - im->frame_count, htonl(P->num_plays)); + pf->frame_count, htonl(P->num_plays)); continue; #undef P diff --git a/src/modules/loaders/loader_ps.c b/src/modules/loaders/loader_ps.c index 8ca6023..dded974 100644 --- a/src/modules/loaders/loader_ps.c +++ b/src/modules/loaders/loader_ps.c @@ -22,6 +22,7 @@ _load(ImlibImage * im, int load_data) unsigned char *src; uint32_t *dst; int i, j; + ImlibImageFrame *pf; rc = LOAD_FAIL; spdoc = NULL; @@ -47,12 +48,13 @@ _load(ImlibImage * im, int load_data) rc = LOAD_BADIMAGE; /* Format accepted */ frame = im->frame; - if (frame > 0) + pf = __imlib_GetFrame(im); + if (pf) { - im->frame_count = spectre_document_get_n_pages(spdoc); - D("Pages=%d\n", im->frame_count); + pf->frame_count = spectre_document_get_n_pages(spdoc); + D("Pages=%d\n", pf->frame_count); - if (frame > 1 && frame > im->frame_count) + if (frame > 1 && frame > pf->frame_count) QUIT_WITH_RC(LOAD_BADFRAME); } else diff --git a/src/modules/loaders/loader_webp.c b/src/modules/loaders/loader_webp.c index 963cec2..bb0923c 100644 --- a/src/modules/loaders/loader_webp.c +++ b/src/modules/loaders/loader_webp.c @@ -17,6 +17,7 @@ _load(ImlibImage * im, int load_data) WebPDemuxer *demux; WebPIterator iter; int frame; + ImlibImageFrame *pf; rc = LOAD_FAIL; @@ -34,19 +35,21 @@ _load(ImlibImage * im, int load_data) rc = LOAD_BADIMAGE; /* Format accepted */ frame = im->frame; - if (frame > 0) + pf = __imlib_GetFrame(im); + if (pf) { - im->frame_count = WebPDemuxGetI(demux, WEBP_FF_FRAME_COUNT); - im->loop_count = WebPDemuxGetI(demux, WEBP_FF_LOOP_COUNT); - if (im->frame_count > 1) - im->frame_flags |= FF_IMAGE_ANIMATED; - im->canvas_w = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); - im->canvas_h = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); + frame = im->frame; + pf->frame_count = WebPDemuxGetI(demux, WEBP_FF_FRAME_COUNT); + pf->loop_count = WebPDemuxGetI(demux, WEBP_FF_LOOP_COUNT); + if (pf->frame_count > 1) + pf->frame_flags |= FF_IMAGE_ANIMATED; + pf->canvas_w = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); + pf->canvas_h = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); D("Canvas WxH=%dx%d frames=%d repeat=%d\n", - im->canvas_w, im->canvas_h, im->frame_count, im->loop_count); + pf->canvas_w, pf->canvas_h, pf->frame_count, pf->loop_count); - if (frame > 1 && frame > im->frame_count) + if (frame > 1 && frame > pf->frame_count) QUIT_WITH_RC(LOAD_BADFRAME); } else @@ -61,18 +64,22 @@ _load(ImlibImage * im, int load_data) im->w = iter.width; im->h = iter.height; - im->frame_x = iter.x_offset; - im->frame_y = iter.y_offset; - im->frame_delay = iter.duration; - if (iter.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) - im->frame_flags |= FF_FRAME_DISPOSE_CLEAR; - if (iter.blend_method == WEBP_MUX_BLEND) - im->frame_flags |= FF_FRAME_BLEND; + if (pf) + { + pf->frame_x = iter.x_offset; + pf->frame_y = iter.y_offset; + pf->frame_delay = iter.duration; + if (iter.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) + pf->frame_flags |= FF_FRAME_DISPOSE_CLEAR; + if (iter.blend_method == WEBP_MUX_BLEND) + pf->frame_flags |= FF_FRAME_BLEND; - D("Canvas WxH=%dx%d frame=%d/%d X,Y=%d,%d WxH=%dx%d alpha=%d T=%d dm=%d co=%d bl=%d\n", // - im->canvas_w, im->canvas_h, iter.frame_num, im->frame_count, - im->frame_x, im->frame_y, im->w, im->h, iter.has_alpha, - im->frame_delay, iter.dispose_method, iter.complete, iter.blend_method); + D("Canvas WxH=%dx%d frame=%d/%d X,Y=%d,%d WxH=%dx%d alpha=%d T=%d dm=%d co=%d bl=%d\n", // + pf->canvas_w, pf->canvas_h, iter.frame_num, pf->frame_count, + pf->frame_x, pf->frame_y, im->w, im->h, iter.has_alpha, + pf->frame_delay, iter.dispose_method, iter.complete, + iter.blend_method); + } if (!IMAGE_DIMENSIONS_OK(im->w, im->h)) goto quit;