Skip to content

feat: add png jpeg support#556

Merged
daveallie merged 32 commits intocrosspoint-reader:masterfrom
martinbrook:mbrook-png-jpeg-no-bmp
Feb 16, 2026
Merged

feat: add png jpeg support#556
daveallie merged 32 commits intocrosspoint-reader:masterfrom
martinbrook:mbrook-png-jpeg-no-bmp

Conversation

@martinbrook
Copy link
Contributor

@martinbrook martinbrook commented Jan 26, 2026

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

  • Open EPUB with JPEG images - verify images display with proper grayscale
  • Open EPUB with PNG images - verify images display correctly and no crash
  • Navigate away from image page and back - verify faster load from cache
  • Verify grayscale tones render correctly (not just black/white dithering)
  • Verify large images are scaled down to fit screen
  • Verify images are centered horizontally
  • Verify page serialization/deserialization works with images
  • Verify images rendered in landscape mode

Test Results

png
jpeg

20260128_231123790
20260128_231012253
20260128_231004209
20260128_230954997
20260128_230945717
20260128_230938313
20260128_230925546
20260128_230918374


AI Usage

Did you use AI tools to help write this code? < YES >

@martinbrook martinbrook marked this pull request as draft January 26, 2026 19:04
@martinbrook
Copy link
Contributor Author

martinbrook commented Jan 26, 2026

Some logs and video in discussion , #11 (comment)

@martinbrook martinbrook force-pushed the mbrook-png-jpeg-no-bmp branch 4 times, most recently from c4bce4e to d9c204f Compare January 27, 2026 23:39
@martinbrook martinbrook changed the title epub: add png jpeg support feat: add png jpeg support Jan 27, 2026
@martinbrook martinbrook marked this pull request as ready for review January 27, 2026 23:55
@martinbrook
Copy link
Contributor Author

closes #11

@fischer-hub
Copy link
Contributor

fischer-hub commented Jan 28, 2026

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?

@martinbrook
Copy link
Contributor Author

martinbrook commented Jan 28, 2026

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.

@fischer-hub
Copy link
Contributor

First, thanks for testing this on your device, did you use the provided test epubs or your own epubs?

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!

@martinbrook
Copy link
Contributor Author

First, thanks for testing this on your device, did you use the provided test epubs or your own epubs?

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 ?

@martinbrook
Copy link
Contributor Author

First, thanks for testing this on your device, did you use the provided test epubs or your own epubs?

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!

Ok, I've pushed a fix, its works well on the test epubs, let me know if it works for you?

@fischer-hub
Copy link
Contributor

Hey @martinbrook just flashed the fix, wow it works great now! Even images within text blocks render correctly for me! Awesome really

@martinbrook
Copy link
Contributor Author

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.

@fischer-hub
Copy link
Contributor

image

@lukestein
Copy link
Contributor

Thanks again for testing and reporting back. If its possible so share a screenshot I'd appreciate that, if not no worries.

Looking great. Thanks!! 🎉

IMG_3166

@Unintendedsideeffects
Copy link

@martinbrook great work!

@martinbrook
Copy link
Contributor Author

Code duplication in jpeg and png decoders needs removing

@martinbrook
Copy link
Contributor Author

martinbrook commented Jan 29, 2026

Opus 4.5 PR #556 Review: feat: add png jpeg support

Overview

This PR adds embedded image rendering for EPUB files, supporting JPEG and PNG formats with 4-level grayscale dithering and a pixel cache (.pxc) for performance. The architecture is clean and well-structured overall, but there are several issues worth addressing.


Issues

1. Thread-safety / Global mutable state in PNG decoder (High)

PngToFramebufferConverter.cpp relies heavily on file-scope global variables (gRenderer, gConfig, gScale, gCacheBuffer, etc.) to pass state into the PNGdec callbacks. While this works given the single-threaded embedded context, it's fragile and prevents any future concurrent use. The JPEG decoder handles this better with its JpegContext struct passed through pCallback_data.

At minimum, a comment should document this constraint. Ideally, the globals could be grouped into a struct to make the coupling explicit and reduce the chance of stale state.

2. Duplicated code between JPEG and PNG decoders (Medium)

The following are duplicated verbatim across both converter files:

  • bayer4x4 matrix
  • applyBayerDither4Level() function
  • drawPixelWithRenderMode() function
  • PixelCache / cacheSetPixel() logic (structurally identical but one uses a struct, the other uses globals)

These should be extracted into a shared utility (e.g., DitherUtils.h or into the base ImageToFramebufferDecoder).

3. PixelCache duplicated differently in JPEG vs PNG (Medium)

The JPEG decoder uses a well-encapsulated PixelCache struct with allocate(), setPixel(), writeToFile(). The PNG decoder reimplements the same thing with bare globals (gCacheBuffer, cacheSetPixel(), inline write logic). The PNG side should reuse the PixelCache struct from the JPEG side, or both should share a common implementation.

4. renderFromCache pixel rendering logic inconsistency (Low-Medium)

In ImageBlock.cpp:renderFromCache(), the getRenderMode() call is made inside the inner pixel loop for every pixel. This is unlikely to change mid-render — hoisting it out of the loop would be a minor performance improvement. More importantly, the rendering logic for pixel value 0 (black) and 3 (white) differs subtly from drawPixelWithRenderMode():

  • renderFromCache: BW mode draws when pixelValue < 3 (draws 0, 1, 2)
  • drawPixelWithRenderMode: identical logic

This is consistent, but the fact that renderFromCache hand-rolls this logic instead of calling the shared function is another duplication point.

5. Missing getDimensions virtual call (Low)

ImageToFramebufferDecoder declares getDimensions() as a pure virtual, but ImageBlock never calls it — dimensions are stored at construction time. If dimensions come from the HTML parser's image extraction, this is fine, but the getDimensions method appears unused except potentially by the parser. Worth confirming.

6. isFormatSupported checks full path, not extension (Low)

ImageDecoderFactory::isFormatSupported() passes the full imagePath to supportsFormat(), but getDecoder() correctly extracts the extension first. The supportsFormat() implementations only match against extensions like .jpg, .png, so isFormatSupported("foo/bar.jpg") would return false because "foo/bar.jpg" != ".jpg". This function appears unused currently but is a bug waiting to happen.

7. PNG file opened twice (Low)

In PngToFramebufferConverter::decodeToFramebuffer(), an FsFile file is opened at the start, but then png.open() triggers pngOpen() which opens a second FsFile via new FsFile(). The first file is closed at the end but was never actually used for decoding. This is a minor resource leak / dead code.

8. No cache invalidation (Low)

If the source image changes (e.g., different EPUB with same internal paths), stale .pxc cache files could be served. The 1-pixel tolerance check on dimensions isn't sufficient for detecting content changes. A hash or timestamp check would be more robust, though this may be acceptable for the current use case.

9. PixelCache / gCacheBuffer not freed on early return paths (Low)

In the JPEG decoder, if MCU decode fails mid-way (status != 0), the function returns false without freeing the PixelCache. The PixelCache destructor will handle cleanup since it's stack-allocated with RAII, so this is actually fine. However, in the PNG decoder, gCacheBuffer is correctly freed in the error path — good.

10. Memory allocation without size limits (Low)

PixelCache::allocate() computes bytesPerRow * h without checking for overflow or enforcing a max allocation size. On an MCU with limited RAM, a large image (e.g., 2048x1536 at the MAX_SOURCE limits) would attempt to allocate ~768KB for the cache buffer, which would fail on most embedded targets. The malloc failure is handled, but a proactive size check with a log message would be more informative.


Positive Notes

  • The Bayer dithering approach is well-suited for the 4-level grayscale display
  • Pixel cache format is compact and efficient (2 bits/pixel)
  • MCU-based JPEG decoding with all scan types handled (grayscale, YH1V1, YH2V1, YH1V2, YH2V2)
  • Graceful fallback to alt text on decode failure
  • The page break fix (commit 3982f24) is a good UX improvement
  • Serialization/deserialization for PageImage integrates cleanly with the existing PageElement hierarchy

Recommendation

The PR is in good shape functionally. The main concerns are the code duplication across decoders and the global state in the PNG decoder. I'd suggest addressing items 2, 3, and 6 before merge, and documenting item 1 at minimum.

@martinbrook martinbrook force-pushed the mbrook-png-jpeg-no-bmp branch from 3982f24 to 12e9c3e Compare January 30, 2026 18:59
@martinbrook
Copy link
Contributor Author

martinbrook commented Jan 30, 2026

PR #556 Review: Changes Made

1. Thread-safety / Global mutable state in PNG decoder (High) — Fixed

Problem: PngToFramebufferConverter.cpp used ~15 file-scope global variables (gRenderer, gConfig, gScale, gCacheBuffer, pngFile, etc.) to pas
s state into PNGdec callbacks.

Changes:

  • Created a PngContext struct containing all rendering, scaling, and cache state.
  • The draw callback (pngDrawCallback) receives the context via pDraw->pUser, set by png.decode(&ctx, 0).
  • File I/O callbacks (pngReadWithHandle, pngSeekWithHandle, pngCloseWithHandle) access the FsFile* via pFile->fHandle, eliminating the global file
    pointer.
  • getDimensionsStatic simplified to use the same handle-based callbacks.
  • The only remaining file-scope state is static PNG png, a stateless decoder object reused between calls.

Files changed: PngToFramebufferConverter.cpp


2. Duplicated code between JPEG and PNG decoders (Medium) — Fixed

Problem: bayer4x4 matrix, applyBayerDither4Level(), drawPixelWithRenderMode(), and PixelCache/cacheSetPixel() logic were duplicated verbatim a
cross both converter files.

Changes:

  • Extracted bayer4x4, applyBayerDither4Level(), and drawPixelWithRenderMode() into a new shared header DitherUtils.h as inline functions.
  • Extracted PixelCache struct into a new shared header PixelCache.h.
  • Both decoders now #include these shared headers instead of defining their own copies.
  • Standardised drawPixelWithRenderMode to take GfxRenderer& (reference) consistently.

Files changed: JpegToFramebufferConverter.cpp, PngToFramebufferConverter.cpp
Files created: DitherUtils.h, PixelCache.h


3. PixelCache duplicated differently in JPEG vs PNG (Medium) — Fixed

Problem: The JPEG decoder had a well-encapsulated PixelCache struct; the PNG decoder reimplemented the same thing with bare globals.

Resolution: Addressed as part of comment 2. Both decoders now use the shared PixelCache from PixelCache.h. The PNG decoder's PngContext holds a PixelCache cache member.

Files changed: Same as comment 2.


4. renderFromCache pixel rendering logic inconsistency (Low-Medium) — Fixed

Problem: renderFromCache() in ImageBlock.cpp hand-rolled the same pixel rendering logic that exists in drawPixelWithRenderMode(), creating a third
copy. It also called getRenderMode() redundantly per row.

Changes:

  • Replaced the inline rendering logic with a call to the shared drawPixelWithRenderMode() from DitherUtils.h.
  • Removed the now-unnecessary getRenderMode() variable.

Files changed: ImageBlock.cpp


5. Missing getDimensions virtual call (Low) — No change needed

Problem: The review questioned whether the virtual getDimensions() method was unused.

Finding: It is used — ChapterHtmlSlimParser.cpp:162 calls it through the virtual interface on an ImageToFramebufferDecoder* pointer. The concrete im
plementations delegate to their getDimensionsStatic() variants. Working as intended.


6. isFormatSupported checks full path, not extension (Low) — Fixed

Problem: ImageDecoderFactory::isFormatSupported() passed the full imagePath to supportsFormat(), which only matches bare extensions like .jpg. T
his meant it would always return false for actual file paths.

Changes:

  • Replaced the body with return getDecoder(imagePath) != nullptr;, which already correctly extracts the extension before checking.

Files changed: ImageDecoderFactory.cpp


7. PNG file opened twice (Low) — Fixed

Problem: decodeToFramebuffer() opened an FsFile at the start that was never used for decoding — png.open() opened a second file internally.

Resolution: Addressed as part of comment 1. The redundant FsFile file was removed. png.open() now uses pngOpenWithHandle which manages the file l
ifecycle via pFile->fHandle.

Files changed: Same as comment 1.


8. No cache invalidation (Low) — No change needed

Problem: If the source image changes, stale .pxc cache files could be served.

Finding: The existing architecture mitigates this: each EPUB gets its own hash-based cache directory (.crosspoint/epub_<hash>/), and images are extrac
ted with unique naming (img_<spineIndex>_<counter>.<ext>). Different EPUBs never share cache directories. The only realistic risk is modifying an EPUB fil
e in-place on the SD card, which is not a typical use case for an embedded e-reader. Adding content hashing would add complexity and performance cost on the
MCU without meaningful benefit.


9. PixelCache / gCacheBuffer not freed on early return paths (Low) — No change needed

Problem: The review noted potential resource leaks on early returns.

Finding: The review itself concluded this is fine — PixelCache is stack-allocated with RAII, so the destructor handles cleanup. With the comment 2 ch
anges, both decoders use the shared PixelCache which has a destructor that frees the buffer. In the PNG decoder, PixelCache is a member of the stack-all
ocated PngContext, so it's also cleaned up automatically.


10. Memory allocation without size limits (Low) — Fixed

Problem: PixelCache::allocate() had no upper bound check. A large image could attempt to allocate ~768KB on a RAM-constrained MCU, failing silently on
malloc.

Changes:

  • Added a MAX_CACHE_BYTES limit of 256KB.
  • Before calling malloc, the buffer size is checked against this limit with a descriptive log message on rejection.
  • Cast bytesPerRow * h to size_t to prevent integer overflow.
  • Callers already handle allocation failure gracefully by continuing without caching.

Files changed: PixelCache.h

@martinbrook
Copy link
Contributor Author

All tests still passing after review fixes

@fqlx
Copy link

fqlx commented Feb 1, 2026

Amazing. Great work @martinbrook

@me-mitch
Copy link

me-mitch commented Feb 2, 2026

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).

20260202_211820

20260202_211748

20260202_211649

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!

Testing png jpeg image support

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.
@martinbrook martinbrook force-pushed the mbrook-png-jpeg-no-bmp branch from f09cc99 to 056f3c7 Compare February 13, 2026 15:45
@martinbrook
Copy link
Contributor Author

rebased onto master, re-validated with test epubs

@pablohc
Copy link
Contributor

pablohc commented Feb 13, 2026

Hi @martinbrook according to my testing, the implemented solution (applying HALF-REFRESH on pages with images) works correctly with AntiAliasing enabled, eliminating residual text.
Optimization suggestion: apply HALF-REFRESH in pages with images only when AntiAliasing is ON. When AntiAliasing is OFF, images are rendered in 1-bit without intermediate grayscale tones, so HALF-REFRESH provides no benefit and only slows down transitions. Maintaining FAST-REFRESH in this case would improve speed in "low quality/fast" mode.

@pablohc I've added this optimisation, when AA is off images are now refreshed much quicker.

fix: only force half refresh for image pages when anti-aliasing is on

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.

Hi @martinbrook
I've been doing tests based on the feedback from @ngxson #725 (comment)

Below is the video for comparison:
Black X4 #556 commit (f09cc99) <<< // >>> White X4 commit (6177eea)

VID_20260213164854.mp4
image

@martinbrook
Copy link
Contributor Author

martinbrook commented Feb 13, 2026

Hi @martinbrook I've been doing tests based on the feedback from @ngxson #725 (comment)

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?

@pablohc
Copy link
Contributor

pablohc commented Feb 13, 2026

No problem for me @martinbrook , I will test your last commit (056f3c7) and try to replicate same logic and imageblock refresh this night.

pablohc added a commit to pablohc/crosspoint-reader that referenced this pull request Feb 14, 2026
- 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]>
@pablohc
Copy link
Contributor

pablohc commented Feb 14, 2026

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
image

daveallie
daveallie previously approved these changes Feb 16, 2026
Copy link
Member

@daveallie daveallie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the size and general complexity, I am keen to get this merged as is and review the additional improvements from @pablohc in a followup PR

@daveallie daveallie merged commit 6c3a615 into crosspoint-reader:master Feb 16, 2026
6 checks passed
@icannotttt
Copy link

It’s such great news to see this PR merged!! Looking forward to the new release.

Unintendedsideeffects added a commit to Unintendedsideeffects/crosspoint-reader that referenced this pull request Feb 17, 2026
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]>
Unintendedsideeffects added a commit to Unintendedsideeffects/crosspoint-reader that referenced this pull request Feb 17, 2026
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]>
Unintendedsideeffects pushed a commit to Unintendedsideeffects/crosspoint-reader that referenced this pull request Feb 17, 2026
## 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)


![20260128_231123790](https://github.com/user-attachments/assets/78855971-4bb8-441a-b207-0a292b9739f5)

![20260128_231012253](https://github.com/user-attachments/assets/f08fb63f-1b73-41d9-a25e-78232ec0c495)

![20260128_231004209](https://github.com/user-attachments/assets/06c94acc-8a06-4955-978e-6e583399478d)

![20260128_230954997](https://github.com/user-attachments/assets/49bc44d5-0f2c-416b-9199-4d680fb0f4c3)

![20260128_230945717](https://github.com/user-attachments/assets/93446da5-2e07-410c-89c9-6a21d14e5acb)

![20260128_230938313](https://github.com/user-attachments/assets/4c74c72a-3d40-4a25-b0f3-acc703f42c00)

![20260128_230925546](https://github.com/user-attachments/assets/8d8f62ee-c8fc-4f19-a12c-da29083bb766)

![20260128_230918374](https://github.com/user-attachments/assets/f007d5db-41cc-4fa6-bb22-9e767ee7b00d)


                                                                       
---

### 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]>
Unintendedsideeffects added a commit to Unintendedsideeffects/crosspoint-reader that referenced this pull request Feb 17, 2026
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]>
@allgoewer
Copy link
Contributor

allgoewer commented Feb 17, 2026

@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?

[18:27:13] [IMG] Rendering image at 8,261: /.crosspoint/epub_1065909436/img_0_0.png (463x145)
[18:27:13] [IMG] File does not exist: /.crosspoint/epub_1065909436/img_0_0.pxc
[18:27:13] [IMG] Decoding and caching: /.crosspoint/epub_1065909436/img_0_0.png
[18:27:13] [IMG] Using PNG decoder
[18:27:13] [PNG] Decoding PNG: /.crosspoint/epub_1065909436/img_0_0.png
[18:27:13] [PNG] PNG 1400x440 -> 463x145 (scale 0.33), bpp: 8
[18:27:13] [IMG] Allocated cache buffer: 16820 bytes for 463x145
[18:27:13] [PNG] Decode failed: 2
CORRUPT HEAP: Bad tail at 0x3fcbe67c. Expected 0xbaad5678 got 0x00000000
assert failed: multi_heap_free multi_heap_poisoning.c:259 (head != NULL)
Core  0 register dump:
MEPC    : 0x4038242a  RA      : 0x40387a44  SP      : 0x3fcb1ff0  GP      : 0x3fc8ee00
TP      : 0x3f81bb68  T0      : 0x37363534  T1      : 0x7271706f  T2      : 0x33323130
S0/FP   : 0x3fcb2168  S1      : 0x0000007f  A0      : 0x3fcb2054  A1      : 0x3fc9189d
A2      : 0x00000001  A3      : 0x00000029  A4      : 0x00000001  A5      : 0x3fca6000
A6      : 0x7a797877  A7      : 0x76757473  S2      : 0x3fcb2048  S3      : 0x00000001
S4      : 0x3fcb2048  S5      : 0x4038cc7e  S6      : 0x00001a33  S7      : 0x00001a43
S8      : 0x3fcae504  S9      : 0x3fcb224c  S10     : 0x000001cf  S11     : 0x00000091
T3      : 0x6e6d6c6b  T4      : 0x6a696867  T5      : 0x66656463  T6      : 0x62613938
MSTATUS : 0x00001801  MTVEC   : 0x40380001  MCAUSE  : 0x00000007  MTVAL   : 0x00000000
MHARTID : 0x00000000
Stack memory:
3fcb1ff0: 0x3f81bb68 0x3fcbe675 0x3c5cb758 0x4038d158 0x0000001e 0x0000001e 0x3fcb2110 0x3fc9189c
3fcb2010: 0xffffffff 0x00000000 0x3fcb2110 0x00393532 0xffffffff 0x3fc91984 0x3c5cb758 0x3fc91d74
3fcb2030: 0x3c5cb7c1 0x3fc91994 0x3fcb201c 0x3fc91998 0x3c5cb79c 0x3fc9189c 0x00000000 0x00000000
3fcb2050: 0xff000000 0x65737361 0x66207472 0x656c6961 0x6d203a64 0x69746c75 0x6165685f 0x72665f70
3fcb2070: 0x6d206565 0x69746c75 0x6165685f 0x6f705f70 0x6e6f7369 0x2e676e69 0x35323a63 0x68282039
3fcb2090: 0x20646165 0x4e203d21 0x294c4c55 0x00000000 0x000001cf 0x3fcb224c 0x3fcae504 0x00001a43
3fcb20b0: 0x00001a33 0x00000001 0x00000002 0x3fcb2380 0x00000001 0x3fcb2550 0x3fcbe67c 0x40048722
3fcb20d0: 0x3fcae504 0x3fcb224c 0x000001cf 0x00000091 0x3fca6000 0x3fcaf260 0x3fca5520 0x3fcb2104
3fcb20f0: 0x3c5e58e0 0x00000000 0x3fcaf260 0x4038ce3a 0x00000000 0x3fcbe67c 0xbaad5678 0x00000000
3fcb2110: 0x00000001 0x00000000 0xa0000000 0x4782fae0 0x3fca6000 0x00000001 0x00000002 0x3fcb2380
3fcb2130: 0x3fca6000 0x3fcb2558 0x3fca7360 0x4038cc7e 0x00001a43 0x3fc9e000 0x3fcb2558 0x42047144
3fcb2150: 0x40000000 0x3fd52a6c 0x00000008 0x40387fae 0x00000000 0x00000578 0x000001b8 0x00001a32
3fcb2170: 0xa0000000 0x0000000a 0x60043000 0x3fc9e124 0x3fcb2380 0x000001e0 0x00000320 0x3ea95362
3fcb2190: 0x00000578 0x000001b8 0x000001cf 0x00000091 0x00000000 0x3fcbe68c 0x000001cf 0x00000091
3fcb21b0: 0x00000074 0x00000008 0x00000105 0xbaad5601 0x00000000 0x00000000 0x3fcb221c 0x8e6c7768
3fcb21d0: 0x3fcaabd0 0x3fcaec6c 0x00000008 0x3fca6000 0x00000091 0x3fcb221c 0x3fca6000 0x3c566b28
3fcb21f0: 0x3fc9e4ec 0x3fcb2288 0x3fcb221c 0x4205eb40 0x3fcaf254 0x3fcaf248 0x3fca7360 0x4038cb30
3fcb2210: 0x3fcaf254 0x3fcaf250 0x3fcb2288 0x3936365b 0x5b205d33 0x5d474d49 0x69735520 0x5020676e
3fcb2230: 0x6420474e 0x646f6365 0x000a7265 0x00000028 0x00000029 0x3fcb224c 0x00000003 0x00474e50
3fcb2250: 0x00000004 0x00000028 0x00000008 0x4782fae0 0x00000091 0x00000105 0x00001a25 0x8e6c7768
3fcb2270: 0x3fcaabd0 0x3fcaec6c 0x00000008 0x3fca6000 0x00000091 0x00000105 0x00001a25 0x3fcae504
3fcb2290: 0x3fc9e124 0x3fc9e000 0x3fcaec68 0x42044972 0x3fc9e124 0x00000004 0x0000000d 0x3fcb233c
3fcb22b0: 0x0000003c 0x3fca6000 0x3c1614f8 0x3c567000 0x30393536 0x00000028 0x3c1614f8 0x00000000
3fcb22d0: 0x000003e8 0x00000000 0x00000000 0x0000000a 0x3fca5520 0x00000005 0x00000000 0x00000000
3fcb22f0: 0x00009780 0x0000b236 0x00000198 0x3fcaac60 0x00000002 0x00000001 0x8e6c7768 0x00000001
3fcb2310: 0x00000000 0x00000000 0x3c1614f8 0x00000000 0x000003e8 0x00000000 0x3fcae9be 0x8e6c7768
3fcb2330: 0x3fcaabd0 0x00000000 0x0000008c 0x00000167 0x3fca6110 0x3fca6104 0x3fca610c 0x3fca6108
3fcb2350: 0x3fcaabd0 0x3fcae548 0x3c161000 0x00000008 0x00000000 0x00000000 0x3fcaf1b8 0x00000028
3fcb2370: 0x00000048 0x3fcaedf0 0x3fca6000 0x4038cb30 0x00000008 0x00000105 0x000001cf 0x00000091
3fcb2390: 0x01000101 0x3fcaf214 0x00000028 0x00000028 0x3fcaf0b0 0x3fcb23f0 0x3fcaee08 0x4782fae0
3fcb23b0: 0x3fca6000 0x3fcaac60 0x00000002 0x8e6c7768 0x3fcaabd0 0x0000001b 0x00000008 0x3fcaac60
3fcb23d0: 0x3fc8e7f8 0x3fcaf168 0x0000000e 0x00000008 0x8e6c7768 0x3fc9e124
0x3fcaf160 0x42042fd4
ELF file SHA256: f808f21646c0ea14
Rebooting...

saslv pushed a commit to saslv/crosspoint-reader that referenced this pull request Feb 19, 2026
## 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)


![20260128_231123790](https://github.com/user-attachments/assets/78855971-4bb8-441a-b207-0a292b9739f5)

![20260128_231012253](https://github.com/user-attachments/assets/f08fb63f-1b73-41d9-a25e-78232ec0c495)

![20260128_231004209](https://github.com/user-attachments/assets/06c94acc-8a06-4955-978e-6e583399478d)

![20260128_230954997](https://github.com/user-attachments/assets/49bc44d5-0f2c-416b-9199-4d680fb0f4c3)

![20260128_230945717](https://github.com/user-attachments/assets/93446da5-2e07-410c-89c9-6a21d14e5acb)

![20260128_230938313](https://github.com/user-attachments/assets/4c74c72a-3d40-4a25-b0f3-acc703f42c00)

![20260128_230925546](https://github.com/user-attachments/assets/8d8f62ee-c8fc-4f19-a12c-da29083bb766)

![20260128_230918374](https://github.com/user-attachments/assets/f007d5db-41cc-4fa6-bb22-9e767ee7b00d)


                                                                       
---

### 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]>
el pushed a commit to el/crosspoint-reader that referenced this pull request Feb 19, 2026
## 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)


![20260128_231123790](https://github.com/user-attachments/assets/78855971-4bb8-441a-b207-0a292b9739f5)

![20260128_231012253](https://github.com/user-attachments/assets/f08fb63f-1b73-41d9-a25e-78232ec0c495)

![20260128_231004209](https://github.com/user-attachments/assets/06c94acc-8a06-4955-978e-6e583399478d)

![20260128_230954997](https://github.com/user-attachments/assets/49bc44d5-0f2c-416b-9199-4d680fb0f4c3)

![20260128_230945717](https://github.com/user-attachments/assets/93446da5-2e07-410c-89c9-6a21d14e5acb)

![20260128_230938313](https://github.com/user-attachments/assets/4c74c72a-3d40-4a25-b0f3-acc703f42c00)

![20260128_230925546](https://github.com/user-attachments/assets/8d8f62ee-c8fc-4f19-a12c-da29083bb766)

![20260128_230918374](https://github.com/user-attachments/assets/f007d5db-41cc-4fa6-bb22-9e767ee7b00d)


                                                                       
---

### 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]>
daveallie pushed a commit that referenced this pull request Feb 20, 2026
## 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 >**_
anthonydgallo added a commit to anthonydgallo/crosspoint-reader that referenced this pull request Feb 20, 2026
lukestein pushed a commit to lukestein/crosspoint-reader that referenced this pull request Feb 20, 2026
## 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 >**_
@martinbrook
Copy link
Contributor Author

martinbrook commented Feb 24, 2026

@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?

[18:27:13] [IMG] Rendering image at 8,261: /.crosspoint/epub_1065909436/img_0_0.png (463x145)
[18:27:13] [IMG] File does not exist: /.crosspoint/epub_1065909436/img_0_0.pxc
[18:27:13] [IMG] Decoding and caching: /.crosspoint/epub_1065909436/img_0_0.png
[18:27:13] [IMG] Using PNG decoder
[18:27:13] [PNG] Decoding PNG: /.crosspoint/epub_1065909436/img_0_0.png
[18:27:13] [PNG] PNG 1400x440 -> 463x145 (scale 0.33), bpp: 8
[18:27:13] [IMG] Allocated cache buffer: 16820 bytes for 463x145
[18:27:13] [PNG] Decode failed: 2
CORRUPT HEAP: Bad tail at 0x3fcbe67c. Expected 0xbaad5678 got 0x00000000
assert failed: multi_heap_free multi_heap_poisoning.c:259 (head != NULL)
Core  0 register dump:
MEPC    : 0x4038242a  RA      : 0x40387a44  SP      : 0x3fcb1ff0  GP      : 0x3fc8ee00
TP      : 0x3f81bb68  T0      : 0x37363534  T1      : 0x7271706f  T2      : 0x33323130
S0/FP   : 0x3fcb2168  S1      : 0x0000007f  A0      : 0x3fcb2054  A1      : 0x3fc9189d
A2      : 0x00000001  A3      : 0x00000029  A4      : 0x00000001  A5      : 0x3fca6000
A6      : 0x7a797877  A7      : 0x76757473  S2      : 0x3fcb2048  S3      : 0x00000001
S4      : 0x3fcb2048  S5      : 0x4038cc7e  S6      : 0x00001a33  S7      : 0x00001a43
S8      : 0x3fcae504  S9      : 0x3fcb224c  S10     : 0x000001cf  S11     : 0x00000091
T3      : 0x6e6d6c6b  T4      : 0x6a696867  T5      : 0x66656463  T6      : 0x62613938
MSTATUS : 0x00001801  MTVEC   : 0x40380001  MCAUSE  : 0x00000007  MTVAL   : 0x00000000
MHARTID : 0x00000000
Stack memory:
3fcb1ff0: 0x3f81bb68 0x3fcbe675 0x3c5cb758 0x4038d158 0x0000001e 0x0000001e 0x3fcb2110 0x3fc9189c
3fcb2010: 0xffffffff 0x00000000 0x3fcb2110 0x00393532 0xffffffff 0x3fc91984 0x3c5cb758 0x3fc91d74
3fcb2030: 0x3c5cb7c1 0x3fc91994 0x3fcb201c 0x3fc91998 0x3c5cb79c 0x3fc9189c 0x00000000 0x00000000
3fcb2050: 0xff000000 0x65737361 0x66207472 0x656c6961 0x6d203a64 0x69746c75 0x6165685f 0x72665f70
3fcb2070: 0x6d206565 0x69746c75 0x6165685f 0x6f705f70 0x6e6f7369 0x2e676e69 0x35323a63 0x68282039
3fcb2090: 0x20646165 0x4e203d21 0x294c4c55 0x00000000 0x000001cf 0x3fcb224c 0x3fcae504 0x00001a43
3fcb20b0: 0x00001a33 0x00000001 0x00000002 0x3fcb2380 0x00000001 0x3fcb2550 0x3fcbe67c 0x40048722
3fcb20d0: 0x3fcae504 0x3fcb224c 0x000001cf 0x00000091 0x3fca6000 0x3fcaf260 0x3fca5520 0x3fcb2104
3fcb20f0: 0x3c5e58e0 0x00000000 0x3fcaf260 0x4038ce3a 0x00000000 0x3fcbe67c 0xbaad5678 0x00000000
3fcb2110: 0x00000001 0x00000000 0xa0000000 0x4782fae0 0x3fca6000 0x00000001 0x00000002 0x3fcb2380
3fcb2130: 0x3fca6000 0x3fcb2558 0x3fca7360 0x4038cc7e 0x00001a43 0x3fc9e000 0x3fcb2558 0x42047144
3fcb2150: 0x40000000 0x3fd52a6c 0x00000008 0x40387fae 0x00000000 0x00000578 0x000001b8 0x00001a32
3fcb2170: 0xa0000000 0x0000000a 0x60043000 0x3fc9e124 0x3fcb2380 0x000001e0 0x00000320 0x3ea95362
3fcb2190: 0x00000578 0x000001b8 0x000001cf 0x00000091 0x00000000 0x3fcbe68c 0x000001cf 0x00000091
3fcb21b0: 0x00000074 0x00000008 0x00000105 0xbaad5601 0x00000000 0x00000000 0x3fcb221c 0x8e6c7768
3fcb21d0: 0x3fcaabd0 0x3fcaec6c 0x00000008 0x3fca6000 0x00000091 0x3fcb221c 0x3fca6000 0x3c566b28
3fcb21f0: 0x3fc9e4ec 0x3fcb2288 0x3fcb221c 0x4205eb40 0x3fcaf254 0x3fcaf248 0x3fca7360 0x4038cb30
3fcb2210: 0x3fcaf254 0x3fcaf250 0x3fcb2288 0x3936365b 0x5b205d33 0x5d474d49 0x69735520 0x5020676e
3fcb2230: 0x6420474e 0x646f6365 0x000a7265 0x00000028 0x00000029 0x3fcb224c 0x00000003 0x00474e50
3fcb2250: 0x00000004 0x00000028 0x00000008 0x4782fae0 0x00000091 0x00000105 0x00001a25 0x8e6c7768
3fcb2270: 0x3fcaabd0 0x3fcaec6c 0x00000008 0x3fca6000 0x00000091 0x00000105 0x00001a25 0x3fcae504
3fcb2290: 0x3fc9e124 0x3fc9e000 0x3fcaec68 0x42044972 0x3fc9e124 0x00000004 0x0000000d 0x3fcb233c
3fcb22b0: 0x0000003c 0x3fca6000 0x3c1614f8 0x3c567000 0x30393536 0x00000028 0x3c1614f8 0x00000000
3fcb22d0: 0x000003e8 0x00000000 0x00000000 0x0000000a 0x3fca5520 0x00000005 0x00000000 0x00000000
3fcb22f0: 0x00009780 0x0000b236 0x00000198 0x3fcaac60 0x00000002 0x00000001 0x8e6c7768 0x00000001
3fcb2310: 0x00000000 0x00000000 0x3c1614f8 0x00000000 0x000003e8 0x00000000 0x3fcae9be 0x8e6c7768
3fcb2330: 0x3fcaabd0 0x00000000 0x0000008c 0x00000167 0x3fca6110 0x3fca6104 0x3fca610c 0x3fca6108
3fcb2350: 0x3fcaabd0 0x3fcae548 0x3c161000 0x00000008 0x00000000 0x00000000 0x3fcaf1b8 0x00000028
3fcb2370: 0x00000048 0x3fcaedf0 0x3fca6000 0x4038cb30 0x00000008 0x00000105 0x000001cf 0x00000091
3fcb2390: 0x01000101 0x3fcaf214 0x00000028 0x00000028 0x3fcaf0b0 0x3fcb23f0 0x3fcaee08 0x4782fae0
3fcb23b0: 0x3fca6000 0x3fcaac60 0x00000002 0x8e6c7768 0x3fcaabd0 0x0000001b 0x00000008 0x3fcaac60
3fcb23d0: 0x3fc8e7f8 0x3fcaf168 0x0000000e 0x00000008 0x8e6c7768 0x3fc9e124
0x3fcaf160 0x42042fd4
ELF file SHA256: f808f21646c0ea14
Rebooting...

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

[101349] [DBG] [IMG] Rendering image at 8,71: /.crosspoint/epub_1714430535/img_0_0.png (463x145)
[101355] [IMG] File does not exist: /.crosspoint/epub_1714430535/img_0_0.pxc
[101364] [DBG] [IMG] Decoding and caching: /.crosspoint/epub_1714430535/img_0_0.png
[101364] [DBG] [IMG] Using PNG decoder
[101364] [DBG] [PNG] Decoding PNG: /.crosspoint/epub_1714430535/img_0_0.png
[101375] [DBG] [PNG] PNG 1400x440 -> 463x145 (scale 0.33), bpp: 8
[101375] [DBG] [IMG] Allocated cache buffer: 16820 bytes for 463x145
[101841] [DBG] [PNG] PNG decoding complete - render time: 466 ms
[101878] [DBG] [IMG] Cache written: /.crosspoint/epub_1714430535/img_0_0.pxc (463x145, 16824 bytes)
[101878] [DBG] [IMG] Decode successful
[101918] [DBG] [GFX] Time = 594 ms from clearScreen to displayBuffer

@allgoewer
Copy link
Contributor

No worries, I made this report before the 1.1 release candidate, the issue was fixed there 👍

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.