feat: add png jpeg support#556
Conversation
|
Some logs and video in discussion , #11 (comment) |
c4bce4e to
d9c204f
Compare
|
closes #11 |
|
When testing this, the images render really nicely! However, I noticed that when a chapter begins with an image, the first chapter page only contains the chapter title, and the image (and chapter text) will only be placed onto the next page, even when the image is quite small and would fit onto the first chapter page. Is this expected? |
First, thanks for testing this on your device, did you use the provided test epubs or your own epubs? Yes , for this first iteration, flowing text and images is not handled. |
I used my own! It contains some small images as decoration between text blocks so I noticed this quite fast. But otherwise it works impressively well! |
I'll see if there is a quick fix but I don't want to block this PR. Can you share your epub ? |
Ok, I've pushed a fix, its works well on the test epubs, let me know if it works for you? |
|
Hey @martinbrook just flashed the fix, wow it works great now! Even images within text blocks render correctly for me! Awesome really |
Thanks again for testing and reporting back. If its possible so share a screenshot I'd appreciate that, if not no worries. |
|
@martinbrook great work! |
|
Code duplication in jpeg and png decoders needs removing |
Opus 4.5 PR #556 Review:
|
3982f24 to
12e9c3e
Compare
PR #556 Review: Changes Made1. Thread-safety / Global mutable state in PNG decoder (High) — FixedProblem: Changes:
Files changed: 2. Duplicated code between JPEG and PNG decoders (Medium) — FixedProblem: Changes:
Files changed: 3.
|
|
All tests still passing after review fixes |
8f7e734 to
a2d3264
Compare
|
Amazing. Great work @martinbrook |
|
I discovered this project because I recently grabbed the eBook version of: A Knight of the Seven Kingdoms, as I wanted to read it prior to watching the film. Being a recent eBook convert, with the x4 as my main and only device, I began reading. However, this story (being a short story) is accompanied by a lot of wonderful illustrations - which I sadly could not view on this device (even with Crosspoint). That was, until, I discovered this project - because of this, I learnt how to flash via Git and build the project to test it on my own device. Please find attached a couple of images (which obviously look better in person). My first test, the pages with images loaded terribly long - until I used the EPUB Workflow Calibre plugin to compress / convert files for the xteink x4 (which helped with the load times). I also set refresh frequency to only 5 pages (I am not sure if it significantly improved load times, but I personally find this genuinely a readable experience). Please watch the video below for a better understanding of my experience and you can hear the clicks and watch for the image load times. This book file is a bit odd, as it had the images embedded twice, so sometimes you will see that in the viewing. But overall, a readable experience. Thank you for your work! |
When anti-aliasing is off, images are rendered in 1-bit without grayscale tones, so half refresh provides no benefit. Use fast refresh in this case for faster page transitions.
f09cc99 to
056f3c7
Compare
|
rebased onto master, re-validated with test epubs |
Hi @martinbrook Below is the video for comparison: VID_20260213164854.mp4
|
Nice work @pablohc some great performance gains here both perceived and real. I tried to give it a test but since I rebased I've picked up the Serial to LOG_ change so your cherry-picked commit fails to build now with this branch. Maybe we can get your changes in once #556 gets merged or maybe you could rebase your change. @daveallie any preference on the order here as I know you were keen to get this merged as its quite a large PR now? |
|
No problem for me @martinbrook , I will test your last commit (056f3c7) and try to replicate same logic and imageblock refresh this night. |
- Page: getImageBoundingBox() and PageImage::getImageBlock() - HalDisplay/GfxRenderer: displayWindow() for partial refresh - EpubReaderActivity: double FAST_REFRESH for image pages when pagesUntilFullRefresh > 1 (avoids half refresh ~1582ms, ~550ms savings) Co-authored-by: Cursor <[email protected]>
|
Hi @martinbrook new tests based on last commit. Below is the video for comparison: Black X4 commit 056f3c7 <<< // >>> White X4 commit 2d8cbcf VID_20260214034356.mp4
|
|
It’s such great news to see this PR merged!! Looking forward to the new release. |
Brings in the image decoding infrastructure from upstream PR crosspoint-reader#556: - ImageToFramebufferDecoder interface for format-specific decoders - JpegToFramebufferConverter with Bayer dithering - PngToFramebufferConverter with line-based conversion - ImageDecoderFactory for format detection - PixelCache for caching decoded images Co-Authored-By: Claude Opus 4.5 <[email protected]>
Extends the sleep image feature to support PNG and JPEG formats in addition to the existing BMP support. Changes: - Add renderImageSleepScreen() using ImageDecoderFactory from PR crosspoint-reader#556 - Update validateSleepImagesOnce() to scan for .png, .jpg, .jpeg files - Support sleep.png, sleep.jpg, sleep.jpeg in root directory - Rename cache from SleepBmpCache to SleepImageCache - Update web server to invalidate cache for all image formats - Full 4-level grayscale support via multi-pass rendering Users can now place PNG/JPEG images in /sleep/ folder or use /sleep.png, /sleep.jpg as alternatives to /sleep.bmp Co-Authored-By: Claude Opus 4.5 <[email protected]>
## Summary
- Add embedded image support to EPUB rendering with JPEG and PNG
decoders
- Implement pixel caching system to cache decoded/dithered images to SD
card for faster re-rendering
- Add 4-level grayscale support for display
## Changes
### New Image Rendering System
- Add `ImageBlock` class to represent an image with its cached path and
display dimensions
- Add `PageImage` class as a new `PageElement` type for images on pages
- Add `ImageToFramebufferDecoder` interface for format-specific image
decoders
- Add `JpegToFramebufferConverter` - JPEG decoder with Bayer dithering
and scaling
- Add `PngToFramebufferConverter` - PNG decoder with Bayer dithering and
scaling
- Add `ImageDecoderFactory` to select appropriate decoder based on file
extension
- Add `getRenderMode()` to GfxRenderer for grayscale render mode queries
### Dithering and Grayscale
- Implement 4x4 Bayer ordered dithering for 4-level grayscale output
- Stateless algorithm works correctly with MCU block decoding
- Handles scaling without artifacts
- Add grayscale render mode support (BW, GRAYSCALE_LSB, GRAYSCALE_MSB)
- Image decoders and cache renderer respect current render mode
- Enables proper 4-level e-ink grayscale when anti-aliasing is enabled
### Pixel Caching
- Cache decoded/dithered images to `.pxc` files on SD card
- Cache format: 2-bit packed pixels (4 pixels per byte) with
width/height header
- On subsequent renders, load directly from cache instead of re-decoding
- Cache renderer supports grayscale render modes for multi-pass
rendering
- Significantly improves page navigation speed for image-heavy EPUBs
### HTML Parser Integration
- Update `ChapterHtmlSlimParser` to process `<img>` tags and extract
images from EPUB
- Resolve relative image paths within EPUB ZIP structure
- Extract images to cache directory before decoding
- Create `PageImage` elements with proper scaling to fit viewport
- Fall back to alt text display if image processing fails
### Build Configuration
- Add `PNG_MAX_BUFFERED_PIXELS=6402` to support up to 800px wide images
### Test Script
- Generate test EPUBs with annotated JPEG and PNG images
- Test cases cover: grayscale (4 levels), centering, scaling, cache
performance
## Test plan
- [x] Open EPUB with JPEG images - verify images display with proper
grayscale
- [x] Open EPUB with PNG images - verify images display correctly and no
crash
- [x] Navigate away from image page and back - verify faster load from
cache
- [x] Verify grayscale tones render correctly (not just black/white
dithering)
- [x] Verify large images are scaled down to fit screen
- [x] Verify images are centered horizontally
- [x] Verify page serialization/deserialization works with images
- [x] Verify images rendered in landscape mode
## Test Results
[png](https://photos.app.goo.gl/5zFUb8xA8db3dPd19)
[jpeg](https://photos.app.goo.gl/SwtwaL2DSQwKybhw7)








---
### AI Usage
Did you use AI tools to help write this code? _**< YES >**_
---------
Co-authored-by: Matthías Páll Gissurarson <[email protected]>
Co-authored-by: Dave Allie <[email protected]>
Extends the sleep image feature to support PNG and JPEG formats in addition to the existing BMP support. Changes: - Add renderImageSleepScreen() using ImageDecoderFactory from PR crosspoint-reader#556 - Update validateSleepImagesOnce() to scan for .png, .jpg, .jpeg files - Support sleep.png, sleep.jpg, sleep.jpeg in root directory - Rename cache from SleepBmpCache to SleepImageCache - Update web server to invalidate cache for all image formats - Full 4-level grayscale support via multi-pass rendering Users can now place PNG/JPEG images in /sleep/ folder or use /sleep.png, /sleep.jpg as alternatives to /sleep.bmp Co-Authored-By: Claude Opus 4.5 <[email protected]>
|
@martinbrook I got a my X4 to crash completely when running your PR from the recent merge commit (6c3a615). The book causing this crash is this one here from standardebooks.org: The Maltese Falcon I'm trying this with the "Compatible epub" provided at that link. Here's the debugging_monitor-output, looks like a double-free to me? |
## Summary
- Add embedded image support to EPUB rendering with JPEG and PNG
decoders
- Implement pixel caching system to cache decoded/dithered images to SD
card for faster re-rendering
- Add 4-level grayscale support for display
## Changes
### New Image Rendering System
- Add `ImageBlock` class to represent an image with its cached path and
display dimensions
- Add `PageImage` class as a new `PageElement` type for images on pages
- Add `ImageToFramebufferDecoder` interface for format-specific image
decoders
- Add `JpegToFramebufferConverter` - JPEG decoder with Bayer dithering
and scaling
- Add `PngToFramebufferConverter` - PNG decoder with Bayer dithering and
scaling
- Add `ImageDecoderFactory` to select appropriate decoder based on file
extension
- Add `getRenderMode()` to GfxRenderer for grayscale render mode queries
### Dithering and Grayscale
- Implement 4x4 Bayer ordered dithering for 4-level grayscale output
- Stateless algorithm works correctly with MCU block decoding
- Handles scaling without artifacts
- Add grayscale render mode support (BW, GRAYSCALE_LSB, GRAYSCALE_MSB)
- Image decoders and cache renderer respect current render mode
- Enables proper 4-level e-ink grayscale when anti-aliasing is enabled
### Pixel Caching
- Cache decoded/dithered images to `.pxc` files on SD card
- Cache format: 2-bit packed pixels (4 pixels per byte) with
width/height header
- On subsequent renders, load directly from cache instead of re-decoding
- Cache renderer supports grayscale render modes for multi-pass
rendering
- Significantly improves page navigation speed for image-heavy EPUBs
### HTML Parser Integration
- Update `ChapterHtmlSlimParser` to process `<img>` tags and extract
images from EPUB
- Resolve relative image paths within EPUB ZIP structure
- Extract images to cache directory before decoding
- Create `PageImage` elements with proper scaling to fit viewport
- Fall back to alt text display if image processing fails
### Build Configuration
- Add `PNG_MAX_BUFFERED_PIXELS=6402` to support up to 800px wide images
### Test Script
- Generate test EPUBs with annotated JPEG and PNG images
- Test cases cover: grayscale (4 levels), centering, scaling, cache
performance
## Test plan
- [x] Open EPUB with JPEG images - verify images display with proper
grayscale
- [x] Open EPUB with PNG images - verify images display correctly and no
crash
- [x] Navigate away from image page and back - verify faster load from
cache
- [x] Verify grayscale tones render correctly (not just black/white
dithering)
- [x] Verify large images are scaled down to fit screen
- [x] Verify images are centered horizontally
- [x] Verify page serialization/deserialization works with images
- [x] Verify images rendered in landscape mode
## Test Results
[png](https://photos.app.goo.gl/5zFUb8xA8db3dPd19)
[jpeg](https://photos.app.goo.gl/SwtwaL2DSQwKybhw7)








---
### AI Usage
Did you use AI tools to help write this code? _**< YES >**_
---------
Co-authored-by: Matthías Páll Gissurarson <[email protected]>
Co-authored-by: Dave Allie <[email protected]>
## Summary
- Add embedded image support to EPUB rendering with JPEG and PNG
decoders
- Implement pixel caching system to cache decoded/dithered images to SD
card for faster re-rendering
- Add 4-level grayscale support for display
## Changes
### New Image Rendering System
- Add `ImageBlock` class to represent an image with its cached path and
display dimensions
- Add `PageImage` class as a new `PageElement` type for images on pages
- Add `ImageToFramebufferDecoder` interface for format-specific image
decoders
- Add `JpegToFramebufferConverter` - JPEG decoder with Bayer dithering
and scaling
- Add `PngToFramebufferConverter` - PNG decoder with Bayer dithering and
scaling
- Add `ImageDecoderFactory` to select appropriate decoder based on file
extension
- Add `getRenderMode()` to GfxRenderer for grayscale render mode queries
### Dithering and Grayscale
- Implement 4x4 Bayer ordered dithering for 4-level grayscale output
- Stateless algorithm works correctly with MCU block decoding
- Handles scaling without artifacts
- Add grayscale render mode support (BW, GRAYSCALE_LSB, GRAYSCALE_MSB)
- Image decoders and cache renderer respect current render mode
- Enables proper 4-level e-ink grayscale when anti-aliasing is enabled
### Pixel Caching
- Cache decoded/dithered images to `.pxc` files on SD card
- Cache format: 2-bit packed pixels (4 pixels per byte) with
width/height header
- On subsequent renders, load directly from cache instead of re-decoding
- Cache renderer supports grayscale render modes for multi-pass
rendering
- Significantly improves page navigation speed for image-heavy EPUBs
### HTML Parser Integration
- Update `ChapterHtmlSlimParser` to process `<img>` tags and extract
images from EPUB
- Resolve relative image paths within EPUB ZIP structure
- Extract images to cache directory before decoding
- Create `PageImage` elements with proper scaling to fit viewport
- Fall back to alt text display if image processing fails
### Build Configuration
- Add `PNG_MAX_BUFFERED_PIXELS=6402` to support up to 800px wide images
### Test Script
- Generate test EPUBs with annotated JPEG and PNG images
- Test cases cover: grayscale (4 levels), centering, scaling, cache
performance
## Test plan
- [x] Open EPUB with JPEG images - verify images display with proper
grayscale
- [x] Open EPUB with PNG images - verify images display correctly and no
crash
- [x] Navigate away from image page and back - verify faster load from
cache
- [x] Verify grayscale tones render correctly (not just black/white
dithering)
- [x] Verify large images are scaled down to fit screen
- [x] Verify images are centered horizontally
- [x] Verify page serialization/deserialization works with images
- [x] Verify images rendered in landscape mode
## Test Results
[png](https://photos.app.goo.gl/5zFUb8xA8db3dPd19)
[jpeg](https://photos.app.goo.gl/SwtwaL2DSQwKybhw7)








---
### AI Usage
Did you use AI tools to help write this code? _**< YES >**_
---------
Co-authored-by: Matthías Páll Gissurarson <[email protected]>
Co-authored-by: Dave Allie <[email protected]>
## Summary * **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Epub image support was added in #556. The goal of this PR is to document that in the readme. * **What changes are included?** Only the checkmark in the readme. ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**< NO >**_
…BMBi feat: add png jpeg support (crosspoint-reader#556)
## Summary * **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Epub image support was added in crosspoint-reader#556. The goal of this PR is to document that in the readme. * **What changes are included?** Only the checkmark in the readme. ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**< NO >**_
Sorry I didn't see this one. I've just downloaded this and I don't see the crash on my device which is on 1.1.1 plus some changes for progressive jpegs. Can you try a 1.1.1 |
|
No worries, I made this report before the 1.1 release candidate, the issue was fixed there 👍 |







Summary
Changes
New Image Rendering System
ImageBlockclass to represent an image with its cached path and display dimensionsPageImageclass as a newPageElementtype for images on pagesImageToFramebufferDecoderinterface for format-specific image decodersJpegToFramebufferConverter- JPEG decoder with Bayer dithering and scalingPngToFramebufferConverter- PNG decoder with Bayer dithering and scalingImageDecoderFactoryto select appropriate decoder based on file extensiongetRenderMode()to GfxRenderer for grayscale render mode queriesDithering and Grayscale
Pixel Caching
.pxcfiles on SD cardHTML Parser Integration
ChapterHtmlSlimParserto process<img>tags and extract images from EPUBPageImageelements with proper scaling to fit viewportBuild Configuration
PNG_MAX_BUFFERED_PIXELS=6402to support up to 800px wide imagesTest Script
Test plan
Test Results
png
jpeg
AI Usage
Did you use AI tools to help write this code? < YES >