Skip to content

Add gif support#249

Open
ppkn wants to merge 3 commits intomainfrom
dpip/gif
Open

Add gif support#249
ppkn wants to merge 3 commits intomainfrom
dpip/gif

Conversation

@ppkn
Copy link
Collaborator

@ppkn ppkn commented Mar 4, 2026

I'm often asked if we support animated GIFs. This was a hurried attempt at adding GIF support.

Demos

Both of these demos show some blinking. I haven't diagnosed what is causing that.

Animated GIF

PXL_20260304_185939177.mp4

Remote Animated GIF

PXL_20260304_185958257.mp4

the jpeg library is /jpegLib/ &\
the png library is /pngLib/ {
the png library is /pngLib/ &\
the gif library is /gifLib/ {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how much I like adding yet another dependency to image.folk. There isn't a good story for graceful degradation here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could split it into independent handlers for gif/png/jpeg that all check if the path applies to them and return if not?

Copy link
Collaborator Author

@ppkn ppkn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is a lot shorter and cleaner than I expected. I left a couple of comments on things that may need improvement.

Right now there are two Wishes, one for still gifs and one for animated gifs. Wish $this displays gif "example.gif" actually delegates to Wish $this displays image "example.gif" when there is only 1 frame. I wonder if instead we invert that by checking the number of frames in the image.folk When and delegating to animated-gif.folk when the llength of frames is > 1. That way we have a consistent image user api.

// Box the Image struct into a Tcl object
Jim_Obj *imObj;
$[$cc ret Image imObj im]
Jim_ListAppendElement(interp, framesList, imObj);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sort of uncomfortable with how little I understand this (especially line 31). It works but I'd like to understand the mechanisms behind $cc ret a bit better.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pretty deep cut -- I think I originally made ret and argtype purely for internal use in the C compiler library (to generate function prologues/epilogues). ret should generate Tcl code to turn Image into Jim_Obj (and assign it into imObj). It depends on the rtype already being defined in $cc, which happens when you extend imageLib.

Makefile Outdated
$< -I./vendor/jimtcl -I./vendor/tracy/public

vendor/gifdec/gifdec.o: vendor/gifdec/gifdec.c vendor/gifdec/gifdec.h
cc -c -O2 -g -fPIC -fno-omit-frame-pointer $(if $(ASAN_ENABLE),-fsanitize=address -fsanitize-recover=address,) -o$@ \
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know for sure we need this fPIC flag, but I don't know how much Gemini cargo culted the rest of this compilation step.

@ppkn ppkn marked this pull request as ready for review March 4, 2026 19:04
@ppkn ppkn changed the title WIP Add gif support Add gif support Mar 4, 2026
@osnr
Copy link
Collaborator

osnr commented Mar 4, 2026

Blinking probably a larger Folk issue. Maybe addressable with some use of -atomically. Will look into next week

@osnr
Copy link
Collaborator

osnr commented Mar 4, 2026

(I don't think it's a blocker for this)

@osnr
Copy link
Collaborator

osnr commented Mar 4, 2026

I think you forgot to check in gifdec? I also think mentioning it in the Makefile along with core modules of Folk is not good practice -- would be better to build from source in gif-lib.folk and not mention it anywhere else.

uint16_t h = gif->height;
gd_close_gif(gif);

Jim_Obj *result = Jim_NewDictObj(interp, NULL, 0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be more elegant to define this as a struct Gif and return that on the stack instead of having the Tcl encoding inline here, I think

@osnr
Copy link
Collaborator

osnr commented Mar 4, 2026

I think you forgot to check in gifdec? I also think mentioning it in the Makefile along with core modules of Folk is not good practice -- would be better to build from source in gif-lib.folk and not mention it anywhere else.

i.e., just pass gifdec.c as a cflags into $cc so that it gets compiled alongside the Folk-generated C

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants