Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 172 additions & 0 deletions faststack.working-menus/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# ChangeLog

Todo: Add image brightness control / cropping. Make batches a bit more intuitive. Make it work on Linux / Mac. Create Windows .exe. Write better documentation / help. Add splash screen / icon.

## [1.0.0] - 2025-11-21

### Major Features
- **Batch Selection System:** New batch selection mode for drag-and-drop operations
- `{` to begin batch, `}` to end batch, `\` to clear all batches
- `X` or `S` keys remove individual images from batches/stacks (shrinks or splits ranges)
- Batches automatically cleared after successful drag operation
- Multiple files can now be dragged to browsers and external applications simultaneously
- **Manual Flag Toggles:** Added keyboard shortcuts to manually control metadata flags
- `U` toggles uploaded flag
- `Ctrl+E` toggles edited flag
- `Ctrl+S` toggles stacked flag
- **Edited Flag Tracking:** New metadata flag for images edited in Photoshop
- Displays "Edited on [date]" in status bar (green)
- Can be manually toggled with `Ctrl+E`
- **Jump to Image Dialog:** Press `G` to jump directly to any image by number
- Dynamic input field sizing based on image count
- Proper keyboard event capture while dialog is open

### UI/UX Improvements
- **Auto Zoom Reset:** Image view automatically resets to fit-window after drag operations
- **Smooth Window Dragging:** Fixed flickering when dragging title bar by using global coordinates
- **Status Bar Enhancements:**
- Added batch info display (green badge showing position/count)
- Added uploaded status display
- Added edited status display

### Bug Fixes
- **Multi-file Drag:** Simplified drag implementation to work correctly with Chrome and other browsers

## [0.9.0] - 2025-11-20

### Performance Improvements
- **Zero-Copy JPEG Read:** Eliminated memory copy by passing mmap directly to decoders, reducing I/O time by 25-60% for large JPEGs.
- **Filter Performance:** Cached image list in memory to eliminate disk scans on every filter keystroke (100-1000x faster for large directories).
- **Smart Cache Management:** Removed unnecessary cache clearing on resize/zoom - LRU naturally evicts old entries while allowing instant reuse.
- **Generation Thrashing Fix:** Navigation no longer increments generation counter, preventing cache invalidation on every keystroke.
- **Directional Prefetching:** Asymmetric prefetch now biases 70% ahead and 30% behind in travel direction for faster sequential browsing.
- **ICC Transform Caching:** Cached ICC color transforms to eliminate repeated transform builds during color-managed viewing.
- **TurboJPEG for ICC:** ICC color path now uses TurboJPEG for decode+resize, then Pillow only for color conversion.

### Features
- **JPG Fallback for Helicon:** Helicon Focus stacking now works with JPG-only workflows when RAW files absent.
- **Comprehensive Timing Instrumentation:** Added detailed decode timing logs in debug mode for performance analysis.
- **Added a Jump to Photo feature that can be activated by pressing the G key

## [0.8.0] - 2025-11-20

### Added
- Backspace key now deletes images (in addition to Delete key). Control-Z restores.
- Photoshop integration now automatically uses RAW files when available, falling back to JPG.
- We now have some new color modes in the view menu to make the images in your monitor reflect reality. ICC profile mode works best on my system - try it if the images are over-saturated - or turn down the saturation in saturation mode. Test it out by loading an image in Faststack and Photoshop or another image viewer and make sure the colors look the same.

## [0.7.0] - 2025-11-20

### Added
- **High-DPI Display Support:** Images now render at full physical pixel resolution on 4K displays by accounting for `devicePixelRatio` in display size calculations.
- **Ctrl+0 Zoom Reset:** Added keyboard shortcut to reset zoom and pan to fit window (like Photoshop), with visual feedback.
- **Active Filter Indicator:** Footer now displays active filename filter in yellow bold text for better visibility.
- **Directory Path Display:** Title bar now shows the current working directory path, centered between menu and window controls.

### Fixed
- **Property Name Mismatch:** Corrected `get_stack_summary` to `stackSummary` in UIState to match QML property naming conventions.
- **FilterDialog Theme Support:** Enhanced FilterDialog with proper Material theme support and background styling for consistent dark/light mode appearance.
- **Missing Signal Emissions:** Added `stackSummaryChanged` signal emission when stacks are created, cleared, or processed.

### Changed
- **Improved Error Handling:** Replaced broad `Exception` catches with specific exception types (`OSError`, `subprocess.SubprocessError`, `FileNotFoundError`, `IOError`, `PermissionError`).
- **Better Logging:** Changed `log.error()` to `log.exception()` to include full tracebacks for debugging.
- **Argument Parsing:** Now uses `shlex.split()` with platform-aware parsing (Windows vs POSIX) for proper handling of quoted paths and special characters.

### Testing
- **Executable Validator Tests:** Added comprehensive test suite for executable path validation with 8 test cases covering various security scenarios.

## [0.6.0] - 2025-11-03

### Fixed
- Resolved an issue where the prefetch range was not being applied correctly after changing the prefetch radius in settings.
- Corrected `decode_jpeg_thumb_rgb` to ensure that thumbnails generated by PyTurboJPEG do not exceed the `max_dim` by falling back to Pillow resizing when necessary.
- Addressed excessive metadata queries during application startup by deferring UI synchronization until after images are loaded.
- Fixed a bug where the zoom state callback was not firing, leading to low-resolution images being served when zoomed in.
- Resolved a QML error "Cannot assign to non-existent property 'scaleTransform'" by correctly placing the scale change handlers within the `Scale` transform.
- Handled the empty image files case in preloading to prevent unnecessary processing and correctly update the UI.

## [0.5.0] - 2025-11-03

### Added
- Load full-resolution images when zooming in for maximum detail.
- Call Helicon Focus for each defined stack when multiple stacks are present.

### Changed
- The filesystem watcher is now less sensitive to spurious modification events, reducing unnecessary refreshes.
- The preloading process now shares the same thread pool as the prefetcher for better resource utilization.
- Stacks are now cleared automatically after being sent to Helicon Focus.

### Fixed
- Corrected a `ValueError` in `PyTurboJPEG` caused by unsupported scaling factors.
- Resolved an `AttributeError` in the JPEG scaling factor calculation.
- Fixed an issue where panning the image was not working correctly.
- Addressed a bug where panning speed was incorrect at high zoom levels.
- Ensured that stale prefetcher futures are cancelled when the display size changes.

### Performance
- Improved image decoding performance by using `PyTurboJPEG` for resized decoding.
- Tuned the number of prefetcher thread pool workers based on system CPU cores.
- Replaced synchronous file reads with memory-mapped I/O for faster image loading.
- Optimized image resizing by using `BILINEAR` resampling for large downscales.
- Debounced display size change notifications to reduce redundant UI updates.

## Version 0.4

### Todo

Make it use the full res image when zooming in
When multiple stacks are selected, call Helicon multiple times
After Helicon is called, clear the stacks
Fix S key - I guess it should remove an image from the stack? Clarify what it does now.

### New Features
- **Two-tier caching system:** Implemented a two-tier caching system to prefetch display-sized images, significantly improving performance and reducing GPU memory usage.
- **"Preload All Images" feature:** Added a new menu option under "Actions" to preload all images in the current directory into the cache, ensuring quick access even for unviewed images.
- **Progress bar for preloading:** Introduced a visual progress bar in the footer to display the status of the "Preload All Images" operation.

### Changes
- **Theming improvements:** Adjusted the Material theme to ensure the menubar background is black in dark mode, providing a more consistent user experience.
- **Window behavior:** Changed the application window to a borderless fullscreen mode, allowing for normal Alt-Tab behavior and better integration with the operating system.

## Version 0.3

### New Features
- Implemented a "Settings" dialog with the following configurable options:
- Helicon Focus executable path (with validation).
- Image cache size (in GB).
- Image prefetch radius.
- Application theme (Dark/Light).
- Default image directory.

## Version 0.2

### New Features
- Added an "Actions" menu with the following options:
- "Run Stacks": Launch Helicon Focus with selected files or all stacks.
- "Clear Stacks": Clear all defined stacks.
- "Show Stacks": Display a dialog with information about the defined stacks.
- Pressing the 'S' key now adds or removes a RAW file from the selection for processing.
- Implemented tracking for stacked images:
- `EntryMetadata` now includes `stacked` (boolean) and `stacked_date` (string) fields.
- `launch_helicon` records stacking status and date upon successful launch.
- The footer in `Main.qml` displays "Stacked: [date]" for previously stacked images.

### Changes
- Pressing the 'Enter' key will now launch Helicon Focus with the selected RAW files. If no files are selected, it will launch with all defined stacks.
- Refactored the theme toggling logic in `Main.qml` to use a boolean `isDarkTheme` property for more robustness.

### Bug Fixes
- Fixed an issue where both the main "Enter" key and the numeric keypad "Enter" key were not consistently recognized.
- The "Show Stacks" and "Key Bindings" dialogs now correctly follow the application's theme (light/dark mode).
- Fixed a bug that caused the "Show Stacks" dialog to be blank.
- Resolved a `NameError` caused by using `Optional` without importing it.
- Corrected an import error for `EntryMetadata` in the tests.
- Updated a test to assert the correct default version number.
- Fixed a `TypeError` in tests caused by a missing `stack_id` field in the `EntryMetadata` model.
- Resolved a QML issue where `anchors.fill` conflicted with manual positioning, preventing panning and zooming.
- Corrected the `launch_helicon` method to only clear the `selected_raws` set if Helicon Focus is launched successfully.
- Resolved `TypeError` and `Invalid property assignment` errors in QML related to settings dialog initialization and property bindings.
- Fixed QML warnings related to invalid anchor usage in `Main.qml`.
- Fixed missing minimize, maximize, and close buttons by correctly configuring the custom title bar.
- Resolved QML warnings about `mouse` parameter not being declared in `MouseArea` signal handlers.
25 changes: 25 additions & 0 deletions faststack.working-menus/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
The MIT License (MIT)
=====================

Copyright © 2025 Alan Rockefeller

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the “Software”), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
60 changes: 60 additions & 0 deletions faststack.working-menus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# FastStack

# Version 1.0 - November 21, 2025
# By Alan Rockefeller

Ultra-fast, caching JPG viewer designed for culling and selecting RAW or JPG files for focus stacking and website upload.

This tool is optimized for speed, using `libjpeg-turbo` for decoding, aggressive prefetching, and byte-aware LRU caches to provide a fluid experience when reviewing thousands of images.

## Features

- **Instant Navigation:** Sub-10ms next/previous image switching, high peformance decoding via `PyTurboJPEG`.
- **Zoom & Pan:** Smooth zooming and panning.
- **Stack Selection:** Group images into stacks (`[`, `]`) and select them for processing (`S`).
- **Helicon Focus Integration:** Launch Helicon Focus with your selected RAW files with a single keypress (`Enter`).
- **Photoshop Integration:** Edit current image in Photoshop (E key) - uses RAW files when available
- **Clipboard Support:** Copy image path to clipboard (Ctrl+C)
- **Image Filtering:** Filter images by filename
- **Drag & Drop:** Drag images to external applications. Press { and } to batch files to drag & drop multiple images.
- **Theme Support:** Toggle between light and dark themes
- **Delete & Undo:** Move images to recycle bin (Delete/Backspace) with undo support (Ctrl+Z)
- **Has Memory:** Starts where you left off, tells you which images have been edited, stacked and uploaded
- **RAW Pairing:** Automatically maps JPGs to their corresponding RAW files (`.CR3`, `.ARW`, `.NEF`, etc.).
- **Configurable:** Adjust cache sizes, prefetch behavior, and Helicon Focus / Photoshop paths via a settings dialog and a persistent `.ini` file.
- **Accurate Colors:** Uses monitor ICC profile to display colors correctly.

## Installation & Usage

1. **Install Dependencies:**
```bash
pip install -r requirements.txt
```

2. **Run the App:**
```bash
python -m faststack.app "C:\path\to\your\images"
```

## Keyboard Shortcuts

- `J` / `Right Arrow`: Next Image
- `K` / `Left Arrow`: Previous Image
- `G`: Go to image #
- `S`: Toggle selection of current image for stacking
- `B`: Toggle selection of current image for batch drag & drop
- `[`: Begin new stack group
- `]`: End current stack group
- `{`: Begin new drag & drop batch
- `}`: End current drag & drop batch
- '\': Clear drag & drop batch
- 'U': Toggle uploaded flag
- 'Ctrl+E': Toggle edited flag
- 'Ctrl+S': Toggle stacked flag
- `Enter`: Launch Helicon Focus with selected RAWs
- `P`: Edit in Photoshop (uses RAW file if available)
- `Delete` / `Backspace`: Move image to recycle bin
- `Ctrl+Z`: Undo last delete
- `Ctrl+C`: Copy image path to clipboard
- `Ctrl+0`: Reset zoom and pan
- `C`: Clear all stacks
72 changes: 72 additions & 0 deletions faststack.working-menus/faststack.egg-info/PKG-INFO
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
Metadata-Version: 2.4
Name: faststack
Version: 1.0
Summary: Ultra-fast JPG Viewer for Focus Stacking Selection and website upload
Author-email: Alan Rockefeller <alanrockefeller@gmail.com>
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: Microsoft :: Windows
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PySide6<7.0,>=6.0
Requires-Dist: PyTurboJPEG<2.0,>=1.8
Requires-Dist: numpy<3.0,>=2.0
Requires-Dist: cachetools<6.0,>=5.0
Requires-Dist: watchdog<5.0,>=4.0
Requires-Dist: typer<1.0,>=0.12
Requires-Dist: Pillow<11.0,>=10.0
Requires-Dist: pytest<9.0,>=8.0
Dynamic: license-file

# FastStack

# Version 1.0 - November 21, 2025
# By Alan Rockefeller

Ultra-fast, caching JPG viewer designed for culling and selecting RAW or JPG files for focus stacking.

This tool is optimized for speed, using `libjpeg-turbo` for decoding, aggressive prefetching, and byte-aware LRU caches to provide a fluid experience when reviewing thousands of images.

## Features

- **Instant Navigation:** Sub-10ms next/previous image switching on cache hits.
- **High-Performance Decoding:** Uses `PyTurboJPEG` for fast JPEG decoding, with a fallback to `Pillow`.
- **Zoom & Pan:** Smooth, mipmapped zooming and panning.
- **RAW Pairing:** Automatically maps JPGs to their corresponding RAW files (`.CR3`, `.ARW`, `.NEF`, etc.).
- **Stack Selection:** Group images into stacks (`[`, `]`) and select them for processing (`S`).
- **Helicon Focus Integration:** Launch Helicon Focus with your selected RAW files with a single keypress (`Enter`).
- **Sidecar Metadata:** Saves flags, rejections, and stack groupings to a non-destructive `faststack.json` file.
- **Configurable:** Adjust cache sizes, prefetch behavior, and Helicon Focus path via a settings dialog and a persistent `.ini` file.
- **Photoshop Integration:** Edit current image in Photoshop (E key)
- **Clipboard Support:** Copy image path to clipboard (Ctrl+C)
- **Image Filtering:** Filter images by filename
- **Drag & Drop:** Drag images to external applications
- **Theme Support:** Toggle between light and dark themes

## Installation & Usage

1. **Install Dependencies:**
```bash
pip install -r requirements.txt
```

2. **Run the App:**
```bash
python -m faststack.app "C:\path\to\your\images"
```

## Keyboard Shortcuts

- `J` / `Right Arrow`: Next Image
- `K` / `Left Arrow`: Previous Image
- `G`: Toggle Grid View
- `S`: Toggle selection of current image for stacking
- `[`: Begin new stack group
- `]`: End current stack group
- `Space`: Toggle Flag
- `X`: Toggle Reject
- `Enter`: Launch Helicon Focus with selected RAWs
- `E`: Edit in Photoshop
- `Ctrl+C`: Copy image path to clipboard
- `C`: Clear all stacks
14 changes: 14 additions & 0 deletions faststack.working-menus/faststack.egg-info/SOURCES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
LICENSE
README.md
pyproject.toml
faststack/__init__.py
faststack/app.py
faststack/config.py
faststack/logging_setup.py
faststack/models.py
faststack.egg-info/PKG-INFO
faststack.egg-info/SOURCES.txt
faststack.egg-info/dependency_links.txt
faststack.egg-info/entry_points.txt
faststack.egg-info/requires.txt
faststack.egg-info/top_level.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

2 changes: 2 additions & 0 deletions faststack.working-menus/faststack.egg-info/entry_points.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[console_scripts]
faststack = faststack.app:main
8 changes: 8 additions & 0 deletions faststack.working-menus/faststack.egg-info/requires.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
PySide6<7.0,>=6.0
PyTurboJPEG<2.0,>=1.8
numpy<3.0,>=2.0
cachetools<6.0,>=5.0
watchdog<5.0,>=4.0
typer<1.0,>=0.12
Pillow<11.0,>=10.0
pytest<9.0,>=8.0
1 change: 1 addition & 0 deletions faststack.working-menus/faststack.egg-info/top_level.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
faststack
Empty file.
Loading