Files
crosspoint-reader-mod/platformio.ini

98 lines
2.7 KiB
INI
Raw Normal View History

2025-12-08 23:13:33 +11:00
[platformio]
default_envs = default
extra_configs = platformio.local.ini
2025-12-03 22:00:29 +11:00
2026-01-13 00:56:21 +11:00
[crosspoint]
2026-02-23 17:59:24 +11:00
version = 1.1.1
2026-01-13 00:56:21 +11:00
2025-12-08 23:13:33 +11:00
[base]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.37/platform-espressif32.zip
2025-12-03 22:00:29 +11:00
board = esp32-c3-devkitm-1
framework = arduino
monitor_speed = 115200
upload_speed = 921600
check_tool = cppcheck
check_flags = --enable=all --suppress=missingIncludeSystem --suppress=unusedFunction --suppress=unmatchedSuppression --suppress=*:*/.pio/* --inline-suppr
check_skip_packages = yes
2025-12-03 22:00:29 +11:00
board_upload.flash_size = 16MB
board_upload.maximum_size = 16777216
board_upload.offset_address = 0x10000
build_flags =
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
-DEINK_DISPLAY_SINGLE_BUFFER_MODE=1
-DDISABLE_FS_H_WARNING=1
-DDESTRUCTOR_CLOSES_FILE=1
2025-12-08 23:13:33 +11:00
# https://libexpat.github.io/doc/api/latest/#XML_GE
-DXML_GE=0
-DXML_CONTEXT_BYTES=1024
-std=gnu++2a
# Enable UTF-8 long file names in SdFat
-DUSE_UTF8_LONG_NAMES=1
# Increase PNG scanline buffer to support up to 2048px wide images
feat: add png jpeg support (#556) ## 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 <mpg@mpg.is> Co-authored-by: Dave Allie <dave@daveallie.com>
2026-02-16 08:56:59 +00:00
# Default is (320*4+1)*2=2562, we need more for larger images
-DPNG_MAX_BUFFERED_PIXELS=16416
-Wno-bidi-chars
feat: dump crash report to sdcard (#1145) ## Summary This allow dumping crash message (i.e. assertion fail) and stack trace to `crash_report.txt` file on sdcard. The stack trace can then be decoded using https://esphome.github.io/esp-stacktrace-decoder/ Could be useful to debug things like https://github.com/crosspoint-reader/crosspoint-reader/issues/1137 where error doesn't always happen. May also be useful to show a screen to tell what happen (show on next boot after crash), similar to [flipper zero crash message](https://www.reddit.com/r/flipperzero/comments/10f8m3f/anyone_who_can_tell_me_why_this_message_pops_up/) , but this is better to be a dedicated PR (I'm missing the `drawTextWrapped` function, too lazy to code it ; update: exactly what I need in https://github.com/crosspoint-reader/crosspoint-reader/pull/1141) To test this: - Option 1: add an `assert(false)` somewhere in the code - Option 2: try dereferencing a nullptr - Option 3: try `throw` an exception Example of a crash report: ``` CrossPoint version: 1.1.0-dev Panic reason: abort() was called at PC 0x4214585b on core 0 Recent logs: [196] [DBG] [GFX] Time = 2 ms from clearScreen to displayBuffer [1831] [DBG] [RBS] Recent books loaded from file (7 entries) [1832] [DBG] [ACT] Exiting activity: Boot [1832] [DBG] [ACT] Entering activity: Home [1891] [DBG] [GFX] Time = 54 ms from clearScreen to displayBuffer [2521] [DBG] [GFX] Time = 46 ms from clearScreen to displayBuffer [4839] [DBG] [PWR] Going to low-power mode [10048] [INF] [MEM] Free: 134164 bytes, Total: 232372 bytes, Min Free: 133664 bytes [20060] [INF] [MEM] Free: 134164 bytes, Total: 232372 bytes, Min Free: 133664 bytes [30072] [INF] [MEM] Free: 134164 bytes, Total: 232372 bytes, Min Free: 133664 bytes [34453] [DBG] [PWR] Restoring normal CPU frequency [34485] [DBG] [GFX] Time = 30 ms from clearScreen to displayBuffer [35182] [DBG] [GFX] Time = 31 ms from clearScreen to displayBuffer [36675] [DBG] [GFX] Time = 30 ms from clearScreen to displayBuffer [38800] [DBG] [GFX] Time = 30 ms from clearScreen to displayBuffer [40079] [INF] [MEM] Free: 134164 bytes, Total: 232372 bytes, Min Free: 133664 bytes Stack memory: 0x3FCB0650: 0x00000000 0x00000000 0x3FCB0668 0x4038DBB6 0x00000000 0x00000000 0x3FCA0030 0x3FC936D0 0x3FCB0670: 0x3FCB067C 0x3FC936EC 0x3FCB0668 0x34313234 0x62353835 0x00000000 0x726F6261 0x20292874 0x3FCB0690: 0x20736177 0x6C6C6163 0x61206465 0x43502074 0x34783020 0x35343132 0x20623538 0x63206E6F 0x3FCB06B0: 0x2065726F 0x00000030 0x3FCA0000 0xB37A603F 0x00000001 0x3FCA7000 0x3FCABCDC 0x4214585E 0x3FCB06D0: 0x3FCA7000 0x3FCA7000 0x3FCABCDC 0x421458AA 0x3FCABCDC 0x3FCA7000 0x3FCABCDC 0x421459CC 0x3FCB06F0: 0x3FCA7000 0x3FCA7000 0x42145D5A 0x3C205624 0x40388560 0x3FCA7000 0x3FCABCFC 0x42079866 0x3FCB0710: 0x3FCA7000 0x3FCA7000 0x00009C9A 0x4207B7F6 0x3FCA7000 0x42090000 0x001B7740 0x00000001 0x3FCB0730: 0x3FCA7000 0x3FCA7000 0x00000001 0x600C0028 0x00000001 0x3FCA1000 0x00000000 0x00000000 0x3FCB0750: 0x00000000 0x00000000 0x00000000 0xB37A603F 0x00000000 0x00000000 0x00000000 0x00000000 0x3FCB0770: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x42090000 0x3FCA7000 0x4208F9C4 0x3FCB0790: 0x00000000 0x00000000 0x00000000 0x40388368 0x00000000 0x00000000 0x00000000 0x00000000 0x3FCB07B0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0xA5A5A5A5 0xA5A5A5A5 0xA5A5A5A5 0x3FCB07D0: 0xA5A5A5A5 0xA5A5A5A5 0xA5A5A5A5 0xA5A5A5A5 0xBAAD5678 0xDA6D3601 0x5EB5B9C5 0x2602E480 0x3FCB07F0: 0x2BCDD33F 0x15556D4A 0x1F2140A0 0x5D59BEE3 0x8E76449F 0x6FB2D0CE 0xF5F46FAC 0x0112946A 0x3FCB0810: 0x3B0B32E0 0x7A52B537 0x46801DB4 0xDA85DF9F 0x37E83D20 0x12861028 0x47A702BB 0x287A3C8A 0x3FCB0830: 0x03632209 0xD44C5489 0x5E258453 0xFDA77529 0xE6748E23 0xADCF1394 0x67AD6778 0x2C208663 0x3FCB0850: 0xC7985786 0xD4AA3AB2 0x312E1760 0xEC7AEAAE 0x1857020E 0x48003E7E 0xD6CB8763 0x9B4A3F66 0x3FCB0870: 0x4B79E9F6 0xCBF739F0 0x3794C641 0xD0DBA3CB 0x95B9BE15 0x581C9983 0xDE62EFB6 0x20C67C5B 0x3FCB0890: 0x1E4A3DF3 0xFB317C74 0xC0D86103 0x1D79ED56 0x72FE0862 0x3D38B0C8 0xD27EB587 0x0E0A4C40 0x3FCB08B0: 0xF643ADC0 0x56D114D7 0x703AF879 0xAC7F3075 0x89C78C23 0xEDA86814 0xF767B3E3 0x0528838F 0x3FCB08D0: 0x50ED4662 0x11FD38E7 0x8A5A83BB 0x658159BD 0x781AF696 0x8A700F79 0x526DDE23 0xC8472505 0x3FCB08F0: 0x21AACC02 0xCB89369E 0xB82E5BE2 0x4C6C9D7D 0x9E724D9B 0xDC1067F7 0x84478FBC 0x4E89C444 0x3FCB0910: 0x973F4229 0x49F93DA8 0xE30200F6 0xD1B5C391 0x8363A89F 0x2409E74C 0x3AFF7B52 0xCBEC2349 0x3FCB0930: 0xD38F6695 0xBC3EA980 0xF067EBB1 0x7F87D167 0x92B3823B 0x9F0617D7 0xA7537C57 0x12CAB3D4 0x3FCB0950: 0xC82EEE37 0x84D4B4BC 0xE1E2261C 0x488F0ADA 0x96EAF2FF 0x0BC493A0 0xCE614467 0x3829053D 0x3FCB0970: 0xA41156BE 0x2747B77D 0x64DEA90B 0xE704AB0A 0xE4B01006 0x8D51903C 0x56CD3CF2 0x07E0A8E8 0x3FCB0990: 0xD1DE05CE 0x33368522 0xD1889988 0x3A3097F4 0xB0796D09 0xC78948AA 0x6DEFC56E 0xD5C2E1D9 0x3FCB09B0: 0xFD6DD8FA 0xA957B675 0xC202D80D 0x733FF8F4 0xA1484913 0x0B9AFBA6 0x330C07EA 0x2C09AD4C 0x3FCB09D0: 0x3B1E08F7 0x3FCAE7D0 0x00000170 0xABBA1234 0x0000015C 0x3FCB00E0 0x00009C93 0x3FCA13C4 0x3FCB09F0: 0x3FCA13C4 0x3FCB09E4 0x3FCA13BC 0x00000018 0x00000000 0x00000000 0x3FCB09E4 0x00000000 0x3FCB0A10: 0x00000001 0x3FCAE7E0 0x706F6F6C 0x6B736154 0x00000000 0x00000000 0x3FCB07D0 0x00000005 0x3FCB0A30: 0x00000000 0x00000001 0x00000000 0x3FCAB444 0x4209AFF0 0x0017E38F 0x00000000 0x3FCA7BD0 ``` --- ### 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** --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-06 17:46:13 +01:00
-Wl,--wrap=panic_print_backtrace,--wrap=panic_abort
2025-12-03 22:00:29 +11:00
build_unflags =
-std=gnu++11
2025-12-08 23:13:33 +11:00
; Board configuration
board_build.flash_mode = dio
board_build.flash_size = 16MB
board_build.partitions = partitions.csv
Add connect to Wifi and File Manager Webserver (#41) ## Summary - **What is the goal of this PR?** Implements wireless EPUB file management via a built-in web server, enabling users to upload, browse, organize, and delete EPUB files from any device on the same WiFi network without needing a computer cable connection. - **What changes are included?** - **New Web Server** ([`CrossPointWebServer.cpp`](src/CrossPointWebServer.cpp), [`CrossPointWebServer.h`](src/CrossPointWebServer.h)): - HTTP server on port 80 with a responsive HTML/CSS interface - Home page showing device status (version, IP, free memory) - File Manager with folder navigation and breadcrumb support - EPUB file upload with progress tracking - Folder creation and file/folder deletion - XSS protection via HTML escaping - Hidden system folders (`.` prefixed, "System Volume Information", "XTCache") - **WiFi Screen** ([`WifiScreen.cpp`](src/screens/WifiScreen.cpp), [`WifiScreen.h`](src/screens/WifiScreen.h)): - Network scanning with signal strength indicators - Visual indicators for encrypted (`*`) and saved (`+`) networks - State machine managing: scanning, network selection, password entry, connecting, save/forget prompts - 15-second connection timeout handling - Integration with web server (starts on connect, stops on exit) - **WiFi Credential Storage** ([`WifiCredentialStore.cpp`](src/WifiCredentialStore.cpp), [`WifiCredentialStore.h`](src/WifiCredentialStore.h)): - Persistent storage in `/sd/.crosspoint/wifi.bin` - XOR obfuscation for stored passwords (basic protection against casual reading) - Up to 8 saved networks with add/remove/update operations - **On-Screen Keyboard** ([`OnScreenKeyboard.cpp`](src/screens/OnScreenKeyboard.cpp), [`OnScreenKeyboard.h`](src/screens/OnScreenKeyboard.h)): - Reusable QWERTY keyboard component with shift support - Special keys: Shift, Space, Backspace, Done - Support for password masking mode - **Settings Screen Integration** ([`SettingsScreen.h`](src/screens/SettingsScreen.h)): - Added WiFi action to navigate to the new WiFi screen - **Documentation** ([`docs/webserver.md`](docs/webserver.md)): - Comprehensive user guide covering WiFi setup, web interface usage, file management, troubleshooting, and security notes - See this for more screenshots! - Working "displays the right way in GitHub" on my repo: https://github.com/olearycrew/crosspoint-reader/blob/feature/connect-to-wifi/docs/webserver.md **Video demo** https://github.com/user-attachments/assets/283e32dc-2d9f-4ae2-848e-01f41166a731 ## Additional Context - **Security considerations**: The web server has no authentication—anyone on the same WiFi network can access files. This is documented as a limitation, recommending use only on trusted private networks. Password obfuscation in the credential store is XOR-based, not cryptographically secure. - **Memory implications**: The web server and WiFi stack consume significant memory. The implementation properly cleans up (stops server, disconnects WiFi, sets `WIFI_OFF` mode) when exiting the WiFi screen to free resources. - **Async operations**: Network scanning and connection use async patterns with FreeRTOS tasks to prevent blocking the UI. The display task handles rendering on a dedicated thread with mutex protection. - **Browser compatibility**: The web interface uses standard HTML5/CSS3/JavaScript and is tested to work with all modern browsers on desktop and mobile. --------- Co-authored-by: Dave Allie <dave@daveallie.com>
2025-12-19 09:05:43 -05:00
extra_scripts =
pre:scripts/build_html.py
feat: User-Interface I18n System (#728) ## Summary **What is the goal of this PR?** This PR introduces Internationalization (i18n) support, enabling users to switch the UI language dynamically. **What changes are included?** - Core Logic: Added I18n class (`lib/I18n/I18n.h/cpp`) to manage language state and string retrieval. - Data Structures: - `lib/I18n/I18nStrings.h/cpp`: Static string arrays for each supported language. - `lib/I18n/I18nKeys.h`: Enum definitions for type-safe string access. - `lib/I18n/translations.csv`: single source of truth. - Documentation: Added `docs/i18n.md` detailing the workflow for developers and translators. - New Settings activity: `src/activities/settings/LanguageSelectActivity.h/cpp` ## Additional Context This implementation (building on concepts from #505) prioritizes performance and memory efficiency. The core approach is to store all localized strings for each language in dedicated arrays and access them via enums. This provides O(1) access with zero runtime overhead, and avoids the heap allocations, hashing, and collision handling required by `std::map` or `std::unordered_map`. The main trade-off is that enums and string arrays must remain perfectly synchronized—any mismatch would result in incorrect strings being displayed in the UI. To eliminate this risk, I added a Python script that automatically generates `I18nStrings.h/.cpp` and `I18nKeys.h` from a CSV file, which will serve as the single source of truth for all translations. The full design and workflow are documented in `docs/i18n.md`. ### Next Steps - [x] Python script `generate_i18n.py` to auto-generate C++ files from CSV - [x] Populate translations.csv with initial translations. Currently available translations: English, Español, Français, Deutsch, Čeština, Português (Brasil), Русский, Svenska. Thanks, community! **Status:** EDIT: ready to be merged. As a proof of concept, the SPANISH strings currently mirror the English ones, but are fully uppercased. --- ### AI Usage Did you use AI tools to help write this code? _**< PARTIALLY >**_ I used AI for the black work of replacing strings with I18n references across the project, and for generating the documentation. EDIT: also some help with merging changes from master. --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: yeyeto2788 <juanernestobiondi@gmail.com>
2026-02-16 15:28:42 +02:00
pre:scripts/gen_i18n.py
feat: replace picojpeg with JPEGDEC for JPEG image decoding (#1136) ## Summary Replaces the picojpeg library with bitbank2/JPEGDEC for JPEG decoding in the EPUB image pipeline. JPEGDEC provides built-in coarse scaling (1/2, 1/4, 1/8), 8-bit grayscale output, and streaming block-based decoding via callbacks. Includes a pre-build patch script for two JPEGDEC changes affecting progressive JPEG support and EIGHT_BIT_GRAYSCALE mode. Closes #912 ## Additional Context # Example progressive jpeg <img src="https://github.com/user-attachments/assets/e63bb4f8-f862-4aa0-a01f-d1ef43a4b27a" width="400" height="800" /> Good performance increase from JPEGDEC over picojpeg cc @bitbank2 thanks ## Baseline JPEG Decode Performance: picojpeg vs JPEGDEC (float in callback) vs JPEGDEC (fixed-point in callback) Tested with `test_jpeg_images.epub` on device (ESP32-C3), first decode (no cache). | Image | Source | Output | picojpeg | JPEGDEC float | JPEGDEC fixed-point | vs picojpeg | vs float | |-------|--------|--------|----------|---------------|---------------------|-------------|----------| | jpeg_format.jpg | 350x250 | 350x250 | 313 ms | 256 ms | **104 ms** | **3.0x** | **2.5x** | | grayscale_test.jpg | 400x600 | 400x600 | 768 ms | 661 ms | **246 ms** | **3.1x** | **2.7x** | | gradient_test.jpg | 400x500 | 400x500 | 707 ms | 597 ms | **247 ms** | **2.9x** | **2.4x** | | centering_test.jpg | 350x400 | 350x400 | 502 ms | 412 ms | **169 ms** | **3.0x** | **2.4x** | | scaling_test.jpg | 1200x1500 | 464x580 | 5487 ms | 1114 ms | **668 ms** | **8.2x** | **1.7x** | | wide_scaling_test.jpg | 1807x736 | 464x188 | 4237 ms | 642 ms | **497 ms** | **8.5x** | **1.3x** | | cache_test_1.jpg | 400x300 | 400x300 | 422 ms | 348 ms | **141 ms** | **3.0x** | **2.5x** | | cache_test_2.jpg | 400x300 | 400x300 | 424 ms | 349 ms | **142 ms** | **3.0x** | **2.5x** | ### Summary - **1:1 scale (fixed-point vs float)**: ~2.5x faster — eliminating software float on the FPU-less ESP32-C3 is the dominant win - **1:1 scale (fixed-point vs picojpeg)**: ~3.0x faster overall - **Downscaled images (vs picojpeg)**: 8-9x faster — JPEGDEC's coarse scaling + fixed-point draw callback - **Downscaled images (fixed-point vs float)**: 1.3-1.7x — less dramatic since JPEG library decode dominates over the draw callback for fewer output pixels - The fixed-point optimization alone (vs float JPEGDEC) saved **~60% of render time** on 1:1 images, confirming that software float emulation was the primary bottleneck in the draw callback - See thread for discussions on quality of progressive images, https://github.com/crosspoint-reader/crosspoint-reader/pull/1136#issuecomment-3952952315 - and the conclusion https://github.com/crosspoint-reader/crosspoint-reader/pull/1136#issuecomment-3959379386 - Proposal to improve quality added at https://github.com/crosspoint-reader/crosspoint-reader/discussions/1179 --- ### 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 >**_ --------- Co-authored-by: Dave Allie <dave@daveallie.com>
2026-03-01 01:24:58 +00:00
pre:scripts/patch_jpegdec.py
feat: Add git branch to version information on settings screen (#1225) ## Summary * **What is the goal of this PR?** During my development I am frequently jumping from branch to branch flashing test versions on my device. It becomes sometimes quite difficult to figure out which version of the software I am currently looking at. * **What changes are included?** - Dev builds now display the current git branch in the version string shown on the Settings screen (e.g. 1.1.0-dev+feat-my-feature), making it easier to identify which firmware is running on the device when switching between branches frequently. - Release, RC, and slim builds are unaffected — they continue to set their version string statically in platformio.ini. <img width="480" height="800" alt="after" src="https://github.com/user-attachments/assets/d2ab3d69-ab6b-47a1-8eb7-1b40b1d3b106" /> ## Additional Context A new PlatformIO pre-build script (scripts/git_branch.py) runs automatically before every dev build. It reads the base version from the [crosspoint] section of platformio.ini, queries git rev-parse --abbrev-ref HEAD for the current branch, and injects the combined string as the CROSSPOINT_VERSION preprocessor define. In a detached HEAD state it falls back to the short commit SHA. If git is unavailable it warns and falls back to unknown. The script can also be run directly with python scripts/git_branch.py for validation without triggering a full build. --- ### 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? _**< YES | PARTIALLY | NO >**_
2026-03-01 02:07:08 +01:00
pre:scripts/git_branch.py
Add connect to Wifi and File Manager Webserver (#41) ## Summary - **What is the goal of this PR?** Implements wireless EPUB file management via a built-in web server, enabling users to upload, browse, organize, and delete EPUB files from any device on the same WiFi network without needing a computer cable connection. - **What changes are included?** - **New Web Server** ([`CrossPointWebServer.cpp`](src/CrossPointWebServer.cpp), [`CrossPointWebServer.h`](src/CrossPointWebServer.h)): - HTTP server on port 80 with a responsive HTML/CSS interface - Home page showing device status (version, IP, free memory) - File Manager with folder navigation and breadcrumb support - EPUB file upload with progress tracking - Folder creation and file/folder deletion - XSS protection via HTML escaping - Hidden system folders (`.` prefixed, "System Volume Information", "XTCache") - **WiFi Screen** ([`WifiScreen.cpp`](src/screens/WifiScreen.cpp), [`WifiScreen.h`](src/screens/WifiScreen.h)): - Network scanning with signal strength indicators - Visual indicators for encrypted (`*`) and saved (`+`) networks - State machine managing: scanning, network selection, password entry, connecting, save/forget prompts - 15-second connection timeout handling - Integration with web server (starts on connect, stops on exit) - **WiFi Credential Storage** ([`WifiCredentialStore.cpp`](src/WifiCredentialStore.cpp), [`WifiCredentialStore.h`](src/WifiCredentialStore.h)): - Persistent storage in `/sd/.crosspoint/wifi.bin` - XOR obfuscation for stored passwords (basic protection against casual reading) - Up to 8 saved networks with add/remove/update operations - **On-Screen Keyboard** ([`OnScreenKeyboard.cpp`](src/screens/OnScreenKeyboard.cpp), [`OnScreenKeyboard.h`](src/screens/OnScreenKeyboard.h)): - Reusable QWERTY keyboard component with shift support - Special keys: Shift, Space, Backspace, Done - Support for password masking mode - **Settings Screen Integration** ([`SettingsScreen.h`](src/screens/SettingsScreen.h)): - Added WiFi action to navigate to the new WiFi screen - **Documentation** ([`docs/webserver.md`](docs/webserver.md)): - Comprehensive user guide covering WiFi setup, web interface usage, file management, troubleshooting, and security notes - See this for more screenshots! - Working "displays the right way in GitHub" on my repo: https://github.com/olearycrew/crosspoint-reader/blob/feature/connect-to-wifi/docs/webserver.md **Video demo** https://github.com/user-attachments/assets/283e32dc-2d9f-4ae2-848e-01f41166a731 ## Additional Context - **Security considerations**: The web server has no authentication—anyone on the same WiFi network can access files. This is documented as a limitation, recommending use only on trusted private networks. Password obfuscation in the credential store is XOR-based, not cryptographically secure. - **Memory implications**: The web server and WiFi stack consume significant memory. The implementation properly cleans up (stops server, disconnects WiFi, sets `WIFI_OFF` mode) when exiting the WiFi screen to free resources. - **Async operations**: Network scanning and connection use async patterns with FreeRTOS tasks to prevent blocking the UI. The display task handles rendering on a dedicated thread with mutex protection. - **Browser compatibility**: The web interface uses standard HTML5/CSS3/JavaScript and is tested to work with all modern browsers on desktop and mobile. --------- Co-authored-by: Dave Allie <dave@daveallie.com>
2025-12-19 09:05:43 -05:00
2025-12-03 22:00:29 +11:00
; Libraries
lib_deps =
BatteryMonitor=symlink://open-x4-sdk/libs/hardware/BatteryMonitor
2025-12-06 12:35:41 +11:00
InputManager=symlink://open-x4-sdk/libs/hardware/InputManager
EInkDisplay=symlink://open-x4-sdk/libs/display/EInkDisplay
SDCardManager=symlink://open-x4-sdk/libs/hardware/SDCardManager
bblanchon/ArduinoJson @ 7.4.2
ricmoo/QRCode @ 0.0.1
feat: add png jpeg support (#556) ## 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 <mpg@mpg.is> Co-authored-by: Dave Allie <dave@daveallie.com>
2026-02-16 08:56:59 +00:00
bitbank2/PNGdec @ ^1.0.0
feat: replace picojpeg with JPEGDEC for JPEG image decoding (#1136) ## Summary Replaces the picojpeg library with bitbank2/JPEGDEC for JPEG decoding in the EPUB image pipeline. JPEGDEC provides built-in coarse scaling (1/2, 1/4, 1/8), 8-bit grayscale output, and streaming block-based decoding via callbacks. Includes a pre-build patch script for two JPEGDEC changes affecting progressive JPEG support and EIGHT_BIT_GRAYSCALE mode. Closes #912 ## Additional Context # Example progressive jpeg <img src="https://github.com/user-attachments/assets/e63bb4f8-f862-4aa0-a01f-d1ef43a4b27a" width="400" height="800" /> Good performance increase from JPEGDEC over picojpeg cc @bitbank2 thanks ## Baseline JPEG Decode Performance: picojpeg vs JPEGDEC (float in callback) vs JPEGDEC (fixed-point in callback) Tested with `test_jpeg_images.epub` on device (ESP32-C3), first decode (no cache). | Image | Source | Output | picojpeg | JPEGDEC float | JPEGDEC fixed-point | vs picojpeg | vs float | |-------|--------|--------|----------|---------------|---------------------|-------------|----------| | jpeg_format.jpg | 350x250 | 350x250 | 313 ms | 256 ms | **104 ms** | **3.0x** | **2.5x** | | grayscale_test.jpg | 400x600 | 400x600 | 768 ms | 661 ms | **246 ms** | **3.1x** | **2.7x** | | gradient_test.jpg | 400x500 | 400x500 | 707 ms | 597 ms | **247 ms** | **2.9x** | **2.4x** | | centering_test.jpg | 350x400 | 350x400 | 502 ms | 412 ms | **169 ms** | **3.0x** | **2.4x** | | scaling_test.jpg | 1200x1500 | 464x580 | 5487 ms | 1114 ms | **668 ms** | **8.2x** | **1.7x** | | wide_scaling_test.jpg | 1807x736 | 464x188 | 4237 ms | 642 ms | **497 ms** | **8.5x** | **1.3x** | | cache_test_1.jpg | 400x300 | 400x300 | 422 ms | 348 ms | **141 ms** | **3.0x** | **2.5x** | | cache_test_2.jpg | 400x300 | 400x300 | 424 ms | 349 ms | **142 ms** | **3.0x** | **2.5x** | ### Summary - **1:1 scale (fixed-point vs float)**: ~2.5x faster — eliminating software float on the FPU-less ESP32-C3 is the dominant win - **1:1 scale (fixed-point vs picojpeg)**: ~3.0x faster overall - **Downscaled images (vs picojpeg)**: 8-9x faster — JPEGDEC's coarse scaling + fixed-point draw callback - **Downscaled images (fixed-point vs float)**: 1.3-1.7x — less dramatic since JPEG library decode dominates over the draw callback for fewer output pixels - The fixed-point optimization alone (vs float JPEGDEC) saved **~60% of render time** on 1:1 images, confirming that software float emulation was the primary bottleneck in the draw callback - See thread for discussions on quality of progressive images, https://github.com/crosspoint-reader/crosspoint-reader/pull/1136#issuecomment-3952952315 - and the conclusion https://github.com/crosspoint-reader/crosspoint-reader/pull/1136#issuecomment-3959379386 - Proposal to improve quality added at https://github.com/crosspoint-reader/crosspoint-reader/discussions/1179 --- ### 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 >**_ --------- Co-authored-by: Dave Allie <dave@daveallie.com>
2026-03-01 01:24:58 +00:00
bitbank2/JPEGDEC @ ^1.8.0
links2004/WebSockets @ 2.7.3
2025-12-08 23:13:33 +11:00
[env:default]
extends = base
build_flags =
${base.build_flags}
feat: Add git branch to version information on settings screen (#1225) ## Summary * **What is the goal of this PR?** During my development I am frequently jumping from branch to branch flashing test versions on my device. It becomes sometimes quite difficult to figure out which version of the software I am currently looking at. * **What changes are included?** - Dev builds now display the current git branch in the version string shown on the Settings screen (e.g. 1.1.0-dev+feat-my-feature), making it easier to identify which firmware is running on the device when switching between branches frequently. - Release, RC, and slim builds are unaffected — they continue to set their version string statically in platformio.ini. <img width="480" height="800" alt="after" src="https://github.com/user-attachments/assets/d2ab3d69-ab6b-47a1-8eb7-1b40b1d3b106" /> ## Additional Context A new PlatformIO pre-build script (scripts/git_branch.py) runs automatically before every dev build. It reads the base version from the [crosspoint] section of platformio.ini, queries git rev-parse --abbrev-ref HEAD for the current branch, and injects the combined string as the CROSSPOINT_VERSION preprocessor define. In a detached HEAD state it falls back to the short commit SHA. If git is unavailable it warns and falls back to unknown. The script can also be run directly with python scripts/git_branch.py for validation without triggering a full build. --- ### 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? _**< YES | PARTIALLY | NO >**_
2026-03-01 02:07:08 +01:00
; CROSSPOINT_VERSION is set by scripts/git_branch.py (includes current branch)
-DENABLE_SERIAL_LOG
-DLOG_LEVEL=2 ; Set log level to debug for development builds
2025-12-08 23:13:33 +11:00
[env:gh_release]
extends = base
build_flags =
${base.build_flags}
2026-01-13 00:56:21 +11:00
-DCROSSPOINT_VERSION=\"${crosspoint.version}\"
-DENABLE_SERIAL_LOG
-DLOG_LEVEL=0 ; Set log level to error for release builds
2026-02-06 03:18:47 +11:00
[env:gh_release_rc]
extends = base
build_flags =
${base.build_flags}
2026-02-06 03:49:00 +11:00
-DCROSSPOINT_VERSION=\"${crosspoint.version}-rc+${sysenv.CROSSPOINT_RC_HASH}\"
-DENABLE_SERIAL_LOG
-DLOG_LEVEL=1 ; Set log level to info for release candidate builds
[env:slim]
extends = base
build_flags =
${base.build_flags}
-DCROSSPOINT_VERSION=\"${crosspoint.version}-slim\"
; serial output is disabled in slim builds to save space
-UENABLE_SERIAL_LOG