Skip to content

cgifsave: remove regressions from 2853 #2870

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

Merged
merged 3 commits into from
Jun 19, 2022

Conversation

DarthSim
Copy link
Contributor

Hey!

This PR fixes a few regressions introduced in #2853.

e4271e1: My original approach intent picking the best suitable palette. But after #2835 it picks the global palette if it is good enough even if the previous local palette is better.
c33d2a2: #2835 changed palette comparison and interpalette_maxerror of 40 became too high. Also, int is not prcisive enough for this new method and double should be used.
4a9c96a: only changed pels should be copied to cgif->previous_frame.

The first two commits fix #2864.

@jcupitt
Copy link
Member

jcupitt commented Jun 18, 2022

Hi @DarthSim, sorry for breaking this :( I'll look at your PR tomorrow.

@jcupitt
Copy link
Member

jcupitt commented Jun 19, 2022

Hi again,

I noticed a failure with skate.gif. With:

$ vips copy skate.gif[n=10] x.gif

I see:

x

I think it's just because with this GIF there are no transparent palette entries. If I change the transparancy section to this:

        /* Pixels which are equal to pixels in the previous frame can be made
         * transparent, provided no alpha channel constraint is present.
         */
        if( page_index > 0 &&
                has_transparency &&
                !has_alpha_constraint ) {
                vips_foreign_save_cgif_set_transparent( cgif,
                        cgif->previous_frame, frame_bytes, cgif->index, 
                        n_pels, 0 );

                frame_config.attrFlags &= ~CGIF_FRAME_ATTR_HAS_ALPHA;
                frame_config.attrFlags |= CGIF_FRAME_ATTR_HAS_SET_TRANS;
                frame_config.transIndex = 0;
        }
        else {
                /* Take a copy of the RGBA frame.
                 */
                memcpy( cgif->previous_frame, frame_bytes, 4 * n_pels );
        }

(ie. only set pixels transparent if we have transparency in the palette) it seem to work.

Of course this means that GIFs which are video clips will hardly ever use transparency optimisation, since they will usually fill the palette and not have a transparent entry.

Perhaps vips__quantise_image_quantize_fixed() should always make palettes with index 0 as transparent?

We have a little code in vips_foreign_save_cgif_build() that tries to do this for the first frame, but of course that's often not enough.

@jcupitt
Copy link
Member

jcupitt commented Jun 19, 2022

Ah, @kleisauke suggests another fix: #2852 (comment)

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

To leave a palette entry clear for transparency. We'd still need to add the transparent element though.

@jcupitt
Copy link
Member

jcupitt commented Jun 19, 2022

Ah of course that's also in @dloebl's PR: #2863 ahem I'm slowly catching up.

@jcupitt jcupitt merged commit 41da0d2 into libvips:master Jun 19, 2022
@jcupitt
Copy link
Member

jcupitt commented Jun 19, 2022

... so combined with that other PR, all my test GIFs pass. Thanks you for fixing my mess, @DarthSim.

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.

cgifsave: inter-frame maxerror might be unlimited
2 participants