fix(frame): keep the offset on the frame - #127
Merged
Merged
Conversation
Frame::setOffsetLeft() and setOffsetTop() stored the offset with set(), which puts a meta item of that name on the vips image. xoffset and yoffset are header properties though, and get() reads the property first, so offsetLeft() and offsetTop() kept returning 0 after a set. The write also went to the vips image in place, and for a single-frame core that image is the core's own. The header properties are no home for the offset anyway: crop, extract_area, flip or rotate overwrite them with values of their own, and no encoder writes them out. Core::frame() extracts with extract_area(), so every frame past the first reported the negated extract origin as its offset, where GD and Imagick report 0. Keep the offset on the frame as the GD driver does, and leave the vips image alone.
deluxetom
approved these changes
Sep 9, 2026
Member
|
Thanks. |
olivervogel
pushed a commit
that referenced
this pull request
Sep 9, 2026
Frame::setOffsetLeft() and setOffsetTop() stored the offset with set(), which puts a meta item of that name on the vips image. xoffset and yoffset are header properties though, and get() reads the property first, so offsetLeft() and offsetTop() kept returning 0 after a set. The write also went to the vips image in place, and for a single-frame core that image is the core's own. The header properties are no home for the offset anyway: crop, extract_area, flip or rotate overwrite them with values of their own, and no encoder writes them out. Core::frame() extracts with extract_area(), so every frame past the first reported the negated extract origin as its offset, where GD and Imagick report 0. Keep the offset on the frame as the GD driver does, and leave the vips image alone.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Frame::setOffset()has no effect with the vips driver, andoffsetTop()reports the extract origin on animations:setOffsetLeft()andsetOffsetTop()usedset('xoffset', ...), which stores a meta item of that name.xoffsetandyoffsetare header properties, andget()reads the property first, so the meta item is never seen. The write also went to the vips image in place, and for a single-frame coreframe()hands out the core's own image.The header properties are no home for the offset anyway. They are libvips pipeline bookkeeping:
crop,extract_area,fliporrotateoverwrite them with values of their own, which is where the-15comes from (Core::frame()extracts withextract_area()), and no encoder writes them out. The offset now lives on the frame as two properties, like the GD driver does, and the vips image is left alone. Nothing in the driver reads frame offsets, so this only changes what the public getters report.