Storage: view pictures, PNG, JPEG, BMP and GIF (#45) #85

Merged
twisla merged 1 commits from storage-images into main 2026-10-07 19:25:15 +00:00
Owner

For #45: the Storage App shows pictures. PNG, JPEG, BMP, and the first picture of a GIF.

What it does

  • Enter on a picture shows it, shrunk to fit. Enter again: its own size, with the arrows moving half a screen. i: its size in pixels. Tab: hex.
  • Dithered to the screen's 256 colours. A colour the screen has exactly is untouched, so the Shell's screenshots are shown pixel for pixel.
  • Decoded once into the screen's own buffer and kept there: no copy in memory. App::retainsContent() / contentLost() are the new hooks for that.
  • Decoding runs on the storage task. The picture appears as it comes, and Back leaves at once.
  • What can't be shown (progressive JPEG, interlaced PNG, compressed or 16-bit BMP) opens as hex with the reason.

Changed from the plan

  • Our own PNG decoder instead of the display library's. The library's needs 44 KB in one block; after one picture the largest free block was 43 to 47 KB and PNGs were refused. Ours needs 32 KB and is host-tested.
  • Background decoding instead of waiting behind a "Decoding..." line. Waiting tripped the main loop's watchdog on a 12 megapixel JPEG and restarted the device.

Checked

  • 527 host tests pass; 20 are new, against real files made with Pillow (every PNG colour type, GIFs plain/interlaced/transparent, BMPs), plus corrupted copies of each.
  • On the device: colour bars in all four formats at two sizes, a transparent PNG, a real Shell screenshot, a progressive JPEG, an animated GIF, a 12 MP JPEG (6.9 s), zoom and moving, Back mid-decode, hex and help panel round trips.

Not checked: a photograph from a real camera, a Toast over a picture, a PNG with IRC connected, the card pulled mid-decode, the real keyboard.

Costs 21 KB of flash. Also corrects two leftover "up to 16 KB" sentences from #47.

Design, measurements and what went wrong: docs/milestones/F1.md, "Pictures in the Storage App".

🤖 Generated with Claude Code

https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT

For #45: the Storage App shows pictures. PNG, JPEG, BMP, and the first picture of a GIF. **What it does** - Enter on a picture shows it, shrunk to fit. Enter again: its own size, with the arrows moving half a screen. `i`: its size in pixels. Tab: hex. - Dithered to the screen's 256 colours. A colour the screen has exactly is untouched, so the Shell's screenshots are shown pixel for pixel. - Decoded once into the screen's own buffer and kept there: no copy in memory. `App::retainsContent()` / `contentLost()` are the new hooks for that. - Decoding runs on the storage task. The picture appears as it comes, and Back leaves at once. - What can't be shown (progressive JPEG, interlaced PNG, compressed or 16-bit BMP) opens as hex with the reason. **Changed from the plan** - **Our own PNG decoder** instead of the display library's. The library's needs 44 KB in one block; after one picture the largest free block was 43 to 47 KB and PNGs were refused. Ours needs 32 KB and is host-tested. - **Background decoding** instead of waiting behind a "Decoding..." line. Waiting tripped the main loop's watchdog on a 12 megapixel JPEG and restarted the device. **Checked** - 527 host tests pass; 20 are new, against real files made with Pillow (every PNG colour type, GIFs plain/interlaced/transparent, BMPs), plus corrupted copies of each. - On the device: colour bars in all four formats at two sizes, a transparent PNG, a real Shell screenshot, a progressive JPEG, an animated GIF, a 12 MP JPEG (6.9 s), zoom and moving, Back mid-decode, hex and help panel round trips. **Not checked:** a photograph from a real camera, a Toast over a picture, a PNG with IRC connected, the card pulled mid-decode, the real keyboard. Costs 21 KB of flash. Also corrects two leftover "up to 16 KB" sentences from #47. Design, measurements and what went wrong: docs/milestones/F1.md, "Pictures in the Storage App". 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
twisla added 1 commit 2026-10-07 19:04:42 +00:00
Storage: view pictures, PNG, JPEG, BMP and GIF (#45)
Site / build (pull_request) Successful in 10s
CI / build (pull_request) Successful in 1m56s
2c18762614
Enter on a picture shows it: shrunk to fit the screen, or at its own size
with Enter again and the arrows to move. Dithered to the screen's 256
colours; a colour the screen has exactly is left alone, so screenshots are
shown as they are.

The picture is decoded once, straight into the screen's buffer, and kept
there (App::retainsContent): no copy in memory. Decoding runs on the
storage task, so the keys keep working and a 12 megapixel photograph
appears as it comes instead of tripping the watchdog.

PNG, BMP and GIF are read by decoders of our own, host-tested against files
made by Pillow; the PNG one needs 32 KB where the display library's needed
44 KB in one block, which the device often doesn't have. JPEG uses the
library's TJpgDec.

Also corrects two sentences that still gave 16 KB as the editing limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
twisla merged commit 1c9f90f92e into main 2026-10-07 19:25:15 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: twisla/roro9stack#85