benjajaja / ratatui-image

Ratatui widget for rendering image graphics in terminals that support it
https://crates.io/crates/ratatui-image
MIT License
96 stars 14 forks source link

fix: Send requested area in ThreadImage to ensure consistent calculations #34

Open aschey opened 3 weeks ago

aschey commented 3 weeks ago

Ran into a bit of an edge case with rounding behavior in ThreadImage. I think the best way to explain it is with an example.

  1. Attempt to render an image with some irregular dimensions (say 39x19).
  2. Render the image in a rect which does not cleanly preserve the aspect ratio (say 5x5).
  3. needs_resize_rect will calculate the rendering area of the 39x19 image in a 5x5 rect. The result is 5x2, preserving the aspect ratio.
  4. The resize thread receives the area to resize into, which is 5x2.
  5. The resize thread calls resize_encode, which will again call needs_resize_rect, this time attempting to render the 39x19 image into the 5x2 rect calculated previously. Due to the loss of precision from rounding, the result is different this time - it says the result should be a 4x2 rect.
  6. The next time the image is rendered, the UI thread will again perform step 3 and say that the desired size is 5x2 rather than 4x2, creating an infinite loop where both the resize thread and the UI thread think the image needs to be resized.

This is the simplest fix I could think of. Instead of sending the calculated area to the resize thread and assuming the rounded values will match, we send the requested area so that the values passed to needs_resize_rect will always be consistent.

I suppose the other option here might be to skip the size check on the resize thread and always resize it to the area calculated by the UI thread. That may require a bit of an API change though. I'd be willing to explore this avenue as well if you'd like.

Let me know if this is unclear or if I'm missing anything, thanks!