Skip to content

Support generic image stack decoding + tiff stack decoding#2706

Open
soraxas wants to merge 7 commits intoimage-rs:mainfrom
soraxas:feat/generic-image-stack
Open

Support generic image stack decoding + tiff stack decoding#2706
soraxas wants to merge 7 commits intoimage-rs:mainfrom
soraxas:feat/generic-image-stack

Conversation

@soraxas
Copy link

@soraxas soraxas commented Dec 23, 2025

addresses #1894, closes #2064

Features

  • separate animation into a more generic image stack
  • implement image stack decoding for tiff

Open for discussion

  • Some of the api had changed.
  • I've rename the struct Frames to Stack as the name is more generic (i.e. frame tends to imply width, height and data type are the same, but it won't be true in all format, e.g., tiff)
  • I've replaced the AnimationDecoder with the more generic ImageStackDecoder (need to import that trait instead), which turns into an iterator that output some generic image-like object
    • e.g. all previous implementation now returns AnimationFrame which is a container that contains Frame<...> and a delay float
    • The newly implemented tiff turns Frame<DynamicImage>, because tiff can contains frames of different size.

Added an example for reading tiff image stack:

$ cargo run --example tiff_img_stack test.tiff
[examples/tiff_img_stack.rs:27:9] i = 0
Frame 0: dimensions: (1620, 1080), color: Rgb8
[examples/tiff_img_stack.rs:27:9] i = 1
Frame 1: dimensions: (2000, 4800), color: Rgb8
[examples/tiff_img_stack.rs:27:9] i = 2
Frame 2: dimensions: (1958, 849), color: Rgb8

Summary

  • All iterable decoder is under ImageStackDecoder<...>, produce -> iterable Stack<...>
    • Generic image list: struct Stack<Frame<I>> { ... } contains a list of frame w/ x, y offset + a generic Image buffer I
      • e.g. for gif, I is rbg image
      • for tiff, I is DynamicImage
    • Animation: struct Stack<AnimationFrame> { ... } where animation frame contains a float delay + a Frame<I> (e.g. gif)

Signed-off-by: Tin Lai <tin@tinyiu.com>

use super trait

Signed-off-by: Tin Lai <tin@tinyiu.com>
Signed-off-by: Tin Lai <tin@tinyiu.com>
Signed-off-by: Tin Lai <tin@tinyiu.com>
Signed-off-by: Tin Lai <tin@tinyiu.com>
Signed-off-by: Tin Lai <tin@tinyiu.com>
Signed-off-by: Tin Lai <tin@tinyiu.com>
Signed-off-by: Tin Lai <tin@tinyiu.com>
@soraxas
Copy link
Author

soraxas commented Jan 13, 2026

Can we have some indication as to whether this is a right direction to support generic image stack? Thanks

@fintelia
Copy link
Contributor

There's ongoing changes to ImageDecoder in #2672 to have it handle animation / image sequences but the PR is still in flux. Once that is complete we'll have a better sense of where things stand. My hope is that we can expose a dyn-compatible trait for animation decoding (which AnimationDecoder currently isn't)

@197g
Copy link
Member

197g commented Jan 14, 2026

In my view, there's a bunch of (weakly motivated) complexity here. Making the frame type generic for instance makes me wonder what other instantiations there should be, on what groups they are related, beyond some getter-style methods there is little that's there. (#2672 noted as it follows through more consequently on separating the sequence metadata from the image color data). Turning the frame into DynamicImage could be an orthogonal start.

Also visible on trait ImageStackDecoder: that interface is so generic, it's hard to distinguish from IntoIterator<C>. It returns Stack<'a, C> which is itself a lean wrapper around Box<dyn Iterator<Item=Result<C, _>> + 'a>. It does not add much in terms of data relationship, nor methods that would be domain specific to the image use case. The problem with such indirection is that, due to absence of specialization, it gets much harder to optimize effectively for anything all-quantized over them; hence last year's trend of toning that way down in some core concepts. I'm currently rather wary of adding new ones without data backing up a very concrete use case that they enable. (Expanding existing traits with new capabilities is much preferred where possible).

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.

More convenient way to work with multipage /-layer tiffs

3 participants