dloebl / cgif Goto Github PK
View Code? Open in Web Editor NEWGIF encoder written in C
License: MIT License
GIF encoder written in C
License: MIT License
As of now, cgif requires more memory for writing interlaced GIFs.
For more details:
Line 526 in b05de32
As of now our tests only check whether the resulting file is a valid GIF image.
However, we should add tests that check whether the input image data matches the output image data.
To achieve this, we would need to pass the GIF image created to an actual GIF decoder.
Steps:
There appears to be a small memory leak when cgif_close is called without first adding a frame by calling cgif_addframe. It appears cgif_close will skip some cleanups when pGIF->CurResult is != CGIF_OK. In this case, it’s CGIF_PENDING and so pGIF doesn’t get freed within cgif_raw_close. I appreciate this isn’t the most typical use case for cgif, but it is possible for it to happen in my application if it has to close down before having had chance to add a frame. Thanks for a great library.
Hi Daniel,
I'm researching permissively-licenced open source GIF encoding libraries to add as a possible dependency of libvips and am very happy to discover this repo, including the huge bonus that it has tests 🎉
I realise this code is less than a month old but it already seems to be well-written and fully-featured, which is a very good sign, thank you.
I have a few questions after briefly reading and testing the code. I suspect these are things you've already thought of but not got round to yet so I can break these out into separate enhancement issues if that's easier.
CGIF
prefix, e.g. CGIFFrameConfig
, CGIF_FRAME_ATTR_...
etc.?write
function pointer to the GIFConfig
(CGIFConfig
?) struct?all_optim
appears to segfault randomly).I'd be happy to use some of our Open Collective donations to help fund this work, and/or submit PRs where appropriate too.
Can I install this code as a package on Centos? i am new on linux
The file size of a frame after LZW encoding could be reduced further by using so-called clear codes.
A clear code resets the LZW dictionary. Afterwards, the encoding is continued with a fresh LZW dictionary and the initial minimum code size.
As of now, cgif always issues a clear code once the dictionary is full (4096 entries). However, it can be beneficial regarding the file size to reset it earlier or later.
This is an optimization problem. We would need to find an adequate heuristic to find an approximate optimum here.
(I'd be happy to contribute this feature if PRs are welcome).
Currently, we have to set the global/local color table manually.
However, when writing an RGBA buffer, it would be much easier if the library could quantize the colors into a 256-bit space.
GIFLIB, for example, has a GifQuantizeColors
function that is very handy for creating frame-local color tables.
It's common for GIF images to include transparent pixels as part of a frame (often as a single frame "animated" image) and typically this would be the first entry/index in the palette.
I've had a quick go at hacking this into cgif via a FRAME_ATTR_HAS_TRANSPARENCY
flag and it seems to work.
diff --git a/cgif.c b/cgif.c
index 81567c0..4154dd1 100644
--- a/cgif.c
+++ b/cgif.c
@@ -556,7 +556,7 @@ int cgif_addframe(GIF* pGIF, FrameConfig* pConfig) {
pFrame->aGraphicExt[1] = 0xF9;
pFrame->aGraphicExt[2] = 0x04;
pFrame->aGraphicExt[3] = 0x04;
- if(pFrame->config.genFlags & FRAME_GEN_USE_TRANSPARENCY) {
+ if((pFrame->config.genFlags & FRAME_GEN_USE_TRANSPARENCY) || (pConfig->attrFlags & FRAME_ATTR_HAS_TRANSPARENCY)) {
pFrame->aGraphicExt[3] |= 0x01;
}
pFrame->aGraphicExt[6] = pFrame->transIndex;
diff --git a/cgif.h b/cgif.h
index 80e617c..8fb0603 100644
--- a/cgif.h
+++ b/cgif.h
@@ -10,6 +10,7 @@
#define GIF_ATTR_IS_ANIMATED (1uL << 1) // make an animated GIF (default is non-animated GIF)
#define GIF_ATTR_NO_GLOBAL_TABLE (1uL << 2) // disable global color table (global color table is default)
#define FRAME_ATTR_USE_LOCAL_TABLE (1uL << 0) // use a local color table for a frame (local color table is not used by default)
+#define FRAME_ATTR_HAS_TRANSPARENCY (1uL << 1) // palette contains transparency at index 0
// flags to decrease GIF-size
#define FRAME_GEN_USE_TRANSPARENCY (1uL << 0) // use transparency optimization (setting pixels identical to previous frame transparent)
#define FRAME_GEN_USE_DIFF_WINDOW (1uL << 1) // do encoding just for the sub-window that has changed from previous frame
It's quite likely there's a better/cleaner way to do this.
I'm happy to submit a PR but would welcome any thoughts/improvements on the approach/API.
I'm trying to encode an animated GIF file that only plays once and then stops. However, when I set CGIF_Config->numLoops
to 1, it plays twice, and when I set it to 0, it results in an infinite loop, making it impossible to do so. Example GIF:
I re-encoded the GIF with ImageMagick to have a proper loop count, here's what it's supposed to look like:
After comparing the two GIFs above in a hex editor, I can see that the one that properly loops doesn't have a NETSCAPE2.0
application extension. Perhaps there could be a way to specify that it's not needed?
Right now cgif only works on little-endian systems. The GIF format requires little-endian for multi-byte fields.
Steps:
In generated and installed file:
Version: undefined
This will make impossible to check minimal version (if needed) in other tools
I was setting the palette color count incorrectly (size of the buffer instead of number of 3 tuples in it). Excuse my ignorance.
Here, in cgif_raw.c, there is a bounds check that requires the LCT size to be lower than 256. However, the LCT is a RGBRGBRGB...
buffer. So for N colors, there will be 3*N entries.
Meaning, for 100 colors—which is less than the maximum of 256 that the GIF format allows—the buffer will have a size of 300, and therefore fail the bounds check.
This seems like an oversight, but I wanted to confirm before forking the repo.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.