Skip to content

cgifsave: number of colours in palette is one less than it could/should be #2852

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
lovell opened this issue Jun 10, 2022 · 4 comments
Closed
Labels

Comments

@lovell
Copy link
Member

lovell commented Jun 10, 2022

The number of colours in the palette of GIF output via cgifsave is currently set to one less than it could be due to this line:

vips__quantise_set_max_colors( cgif->attr, (1 << cgif->bitdepth) - 1 );

This can be highlighted by setting bitdepth to 1, resulting in a call to liq_set_max_colors with the value 1, which is out of the 2-256 range it supports. We currently ignore the error return code so the output GIF has the (default) bitdepth of 8, which is incorrect.

I'm probably to blame here as I originally wrote this code, with the logic of decrementing by 1 to allow space for an extra "colour" for the transparency, if any. However I think with all the recent updates to this code that this logic is no longer required, so the following change should fix this.

- vips__quantise_set_max_colors( cgif->attr, (1 << cgif->bitdepth) - 1 );
+ vips__quantise_set_max_colors( cgif->attr, 1 << cgif->bitdepth );

I'm aware there's more refactoring going on in and around this code so am creating an issue to track it rather than open a PR that may conflict with any work-in-progress.

@jcupitt
Copy link
Member

jcupitt commented Jun 10, 2022

Ooop, good catch, I'll fix it in my branch.

@jcupitt
Copy link
Member

jcupitt commented Jun 10, 2022

Should be fixed with #2853

@jcupitt jcupitt closed this as completed Jun 10, 2022
@kleisauke
Copy link
Member

I noticed that this change produces artefacts with skate.gif from #2824 (comment), see:

$ vips copy skate.gif[n=-1] x.gif

https://t0.nl/x.gif

Reverting it back to (1 << cgif->bitdepth) - 1 seems to fix it.

@@ -731,7 +731,7 @@ vips_foreign_save_cgif_build( VipsObject *object )
 	/* Set up libimagequant.
 	 */
 	cgif->attr = vips__quantise_attr_create();
-	vips__quantise_set_max_colors( cgif->attr, 1 << cgif->bitdepth );
+	vips__quantise_set_max_colors( cgif->attr, (1 << cgif->bitdepth) - 1 );
 	vips__quantise_set_quality( cgif->attr, 0, 100 );
 	vips__quantise_set_speed( cgif->attr, 11 - cgif->effort );

@lovell
Copy link
Member Author

lovell commented Jun 13, 2022

This looks like it might be something to do with CGIF_FRAME_GEN_USE_TRANSPARENCY. Perhaps we should restore the decrement and clamp to a 2-256 range. If max colours equals 2 then we might also have to unset CGIF_FRAME_GEN_USE_TRANSPARENCY.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants