image-rs / image

Encoding and decoding images in Rust
Apache License 2.0
4.89k stars 605 forks source link

Proposed API for animated images #145

Open nwin opened 9 years ago

nwin commented 9 years ago

Did I forgot something? I think we should aim for GIF and APNG. MNG does not make much sense. Nobody uses it and it is not backwards compatible with PNG.

type ImageResult<T> = Option<T>; // just a placeholder
type Color = u8; // just a placeholder

/// Image buffer that does not require extra allocations
struct ImageBuffer<'a> {
    buffer: &'a mut [u8],
    width: uint,
    height: uint,
    color: Color
}

/// Specifies the repetitions of the animation
enum Repetitions {
    Finite(uint),
    Infinite
}

trait AnimatedImage {
    /// The delay between the frames
    fn delay(&self) -> uint;
    /// Repeat
    fn repeat(&self) -> Repetitions;
    /// Number of animation frames
    fn frames(&self) -> uint;
    /// Updates the image buffer used for the animation
    fn next_frame(&self, buffer: ImageBuffer) -> ImageResult<()>;
}

trait ImageDecoder {
    /// Returns true if the image is an animated image
    fn is_animated(&self) -> bool;
    /// Retuns None if self.is_animated() == False
    fn get_animation(&self) -> Option<&AnimatedImage>;
}
bvssvni commented 9 years ago

I prefer Repetition instead of Repetitions because it sound like an iterator.

bvssvni commented 9 years ago

Ops, misread again, I was correct after all. I thought of AnimatedImage as an extension of a normal image that made it a "frame", for example the delay until next frame. An Animation could be composed of AnimatedImage.

There is probably no general solution for abstracting animated images, so I too think we should aim for GIF and APNG.

bvssvni commented 9 years ago

Or, perhaps there is? If we think of an animation as a function of time that returns an image

f(t) -> img

The image could be well defined for t >= 0. It means, you can only access frames for positive values of time because formats does not necessary specify frames for negative values of time.

The loop information can formally be defined as a function of the animation, which means it does not depend on time.

f(t) -> img => f.frame(t, &mut img);
repeat(f) -> Repetition => f.repeat() -> Repetition
frames(f) -> uint => f.frames() -> uint
delay(f(t)) -> uint => f.frame_info(t) -> FrameInfo, frame_info().delay() -> uint
nwin commented 9 years ago

I think Repetitions is correct because I distinguish the amount of repetitions and not whether there is a repetition at all. Just invert the enum: "5 Repetitions" vs. "5 Repetition".

Maybe AnimatedImage is a bad name:

trait Frames {
    /// Repeat
    fn repetitions(&self) -> Repetitions;
    /// Number of animation frames
    fn len(&self) -> uint;
}

impl Iterator<(Delay, ImageBuffer)> for Frames {
  ...
}
bvssvni commented 9 years ago

What about Repeat::Finite(5)? Making it a verb doesn't sound that bad.

The iterator looks nice. Liked the Frames name.