2025-12-21 17:15:17 +11:00
|
|
|
#pragma once
|
|
|
|
|
|
fix: make file system operations thread-safe (HalFile) (#1212)
## Summary
Fix https://github.com/crosspoint-reader/crosspoint-reader/issues/1137
Introducing `HalFile`, a thin wrapper around `FsFile` that uses a global
mutex to protect file operations.
To test this PR, place the code below somewhere in the code base (I
placed it in `onGoToRecentBooks`)
```cpp
static auto testTask = [](void* param) {
for (int i = 0; i < 10; i++) {
String json = Storage.readFile("/.crosspoint/settings.json");
LOG_DBG("TEST_TASK", "Read settings.json, bytes read: %u", json.length());
}
vTaskDelete(nullptr);
};
xTaskCreate(testTask, "test0", 8192, nullptr, 1, nullptr);
xTaskCreate(testTask, "test1", 8192, nullptr, 1, nullptr);
xTaskCreate(testTask, "test2", 8192, nullptr, 1, nullptr);
xTaskCreate(testTask, "test3", 8192, nullptr, 1, nullptr);
delay(1000);
```
It will reliably lead to crash on `master`, but will function correctly
with this PR.
A macro renaming trick is used to avoid changing too many downstream
code files.
---
### 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? **PARTIALLY**, only to
help with tedious copy-paste tasks
---------
Co-authored-by: Zach Nelson <zach@zdnelson.com>
2026-02-28 11:15:27 +01:00
|
|
|
#include <HalStorage.h>
|
|
|
|
|
|
2025-12-30 15:09:30 +10:00
|
|
|
class Print;
|
2025-12-21 17:15:17 +11:00
|
|
|
class ZipFile;
|
|
|
|
|
|
|
|
|
|
class JpegToBmpConverter {
|
|
|
|
|
static unsigned char jpegReadCallback(unsigned char* pBuf, unsigned char buf_size,
|
|
|
|
|
unsigned char* pBytes_actually_read, void* pCallback_data);
|
fix: make file system operations thread-safe (HalFile) (#1212)
## Summary
Fix https://github.com/crosspoint-reader/crosspoint-reader/issues/1137
Introducing `HalFile`, a thin wrapper around `FsFile` that uses a global
mutex to protect file operations.
To test this PR, place the code below somewhere in the code base (I
placed it in `onGoToRecentBooks`)
```cpp
static auto testTask = [](void* param) {
for (int i = 0; i < 10; i++) {
String json = Storage.readFile("/.crosspoint/settings.json");
LOG_DBG("TEST_TASK", "Read settings.json, bytes read: %u", json.length());
}
vTaskDelete(nullptr);
};
xTaskCreate(testTask, "test0", 8192, nullptr, 1, nullptr);
xTaskCreate(testTask, "test1", 8192, nullptr, 1, nullptr);
xTaskCreate(testTask, "test2", 8192, nullptr, 1, nullptr);
xTaskCreate(testTask, "test3", 8192, nullptr, 1, nullptr);
delay(1000);
```
It will reliably lead to crash on `master`, but will function correctly
with this PR.
A macro renaming trick is used to avoid changing too many downstream
code files.
---
### 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? **PARTIALLY**, only to
help with tedious copy-paste tasks
---------
Co-authored-by: Zach Nelson <zach@zdnelson.com>
2026-02-28 11:15:27 +01:00
|
|
|
static bool jpegFileToBmpStreamInternal(FsFile& jpegFile, Print& bmpOut, int targetWidth, int targetHeight,
|
2026-01-27 10:21:15 +01:00
|
|
|
bool oneBit, bool crop = true);
|
2025-12-21 17:15:17 +11:00
|
|
|
|
|
|
|
|
public:
|
2026-01-27 10:21:15 +01:00
|
|
|
static bool jpegFileToBmpStream(FsFile& jpegFile, Print& bmpOut, bool crop = true);
|
Add cover image display in *Continue Reading* card with framebuffer caching (#200)
## Summary
* **What is the goal of this PR?** (e.g., Fixes a bug in the user
authentication module,
Display the book cover image in the **"Continue Reading"** card on the
home screen, with fast navigation using framebuffer caching.
* **What changes are included?**
- Display book cover image in the "Continue Reading" card on home screen
- Load cover from cached BMP (same as sleep screen cover)
- Add framebuffer store/restore functions (`copyStoredBwBuffer`,
`freeStoredBwBuffer`) for fast navigation after initial render
- Fix `drawBitmap` scaling bug: apply scale to offset only, not to base
coordinates
- Add white text boxes behind title/author/continue reading label for
readability on cover
- Support both EPUB and XTC file cover images
- Increase HomeActivity task stack size from 2048 to 4096 for cover
image rendering
## Additional Context
* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks, specific areas to
focus on).
- Performance: First render loads cover from SD card (~800ms),
subsequent navigation uses cached framebuffer (~instant)
- Memory: Framebuffer cache uses ~48KB (6 chunks × 8KB) while on home
screen, freed on exit
- Fallback: If cover image is not available, falls back to standard
text-only display
- The `drawBitmap` fix corrects a bug where screenY = (y + offset) scale
was incorrectly scaling the base coordinates. Now correctly uses screenY
= y + (offset scale)
2026-01-14 19:24:02 +09:00
|
|
|
// Convert with custom target size (for thumbnails)
|
|
|
|
|
static bool jpegFileToBmpStreamWithSize(FsFile& jpegFile, Print& bmpOut, int targetMaxWidth, int targetMaxHeight);
|
|
|
|
|
// Convert to 1-bit BMP (black and white only, no grays) for fast home screen rendering
|
|
|
|
|
static bool jpegFileTo1BitBmpStreamWithSize(FsFile& jpegFile, Print& bmpOut, int targetMaxWidth, int targetMaxHeight);
|
2025-12-21 17:15:17 +11:00
|
|
|
};
|