mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-31 21:48:53 -06:00
Merge PR #2021: Fix reference app catalog video classification and filtering
docs/gaps.md, docs/parity-checklist.md: kept main's header and rows, added the PR's video text and revision row. crates/engine/src/lightroom_catalog.rs: the PR's two tests moved to lightroom_catalog/tests.rs (main split the module). Dropped the PR's unrelated hunks (slide_overlay.rs, tests_export.rs, raw corpus tests) per the review.
This commit is contained in:
@@ -1016,6 +1016,10 @@ pub(crate) fn apply_prepared(s: &mut crate::Session, mut data: CatalogImport, co
|
||||
}
|
||||
p
|
||||
};
|
||||
// Offline videos bypass file probing; Lightroom's format still identifies their kind.
|
||||
if text(&src.image, "fileFormat").eq_ignore_ascii_case("VIDEO") {
|
||||
p.kind = lightcraft_catalog::MediaKind::Video;
|
||||
}
|
||||
ids.insert(src.source_id, p.id);
|
||||
index.photos.insert(identity(&data, src), p.id.0);
|
||||
let keep_develop = existing_id.is_some() && p.edited.is_some() && !update_existing;
|
||||
@@ -1080,7 +1084,14 @@ pub(crate) fn apply_prepared(s: &mut crate::Session, mut data: CatalogImport, co
|
||||
if copy_masters.contains(&src.source_id) {
|
||||
planned.insert(photo_id, p.clone());
|
||||
}
|
||||
if s.catalog.photo(p.id).is_some() {
|
||||
if let Some(old) = s.catalog.photo(p.id) {
|
||||
if old.kind != p.kind {
|
||||
// Repair older imports with existing reversible operations. Removing just the
|
||||
// record leaves album/stack membership intact; the enclosing batch is atomic.
|
||||
let mut repaired = (**old).clone();
|
||||
repaired.kind = p.kind;
|
||||
ops.extend([Op::RemovePhoto { id: p.id }, Op::AddPhoto { photo: Box::new(repaired) }]);
|
||||
}
|
||||
if was_local && promoted.insert(p.id) {
|
||||
imported += 1;
|
||||
ops.push(Op::SetLocal { id: p.id, local: false });
|
||||
|
||||
@@ -548,6 +548,83 @@ fn photo_tables(root: (&str, &str)) -> Vec<(&'static str, &'static str, Vec<SqlV
|
||||
]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn native_video_import_is_visible_in_video_filter() {
|
||||
let dir = std::env::temp_dir().join(format!("lightcraft-lrcat-video-filter-{}", std::process::id()));
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let path = dir.join("videos.lrcat");
|
||||
let mut tables = photo_tables((dir.to_str().unwrap(), ""));
|
||||
tables[2].2[2] = SqlValue::Text("clip.MOV".into());
|
||||
tables[3].2[3] = SqlValue::Text("VIDEO".into());
|
||||
std::fs::write(&path, native_catalog(&tables)).unwrap();
|
||||
let mut s = crate::Session::new();
|
||||
let imported = s.execute("library.importLightroom", &json!({"path": path})).unwrap();
|
||||
let id = PhotoId(imported["mapping"]["1"].as_u64().unwrap());
|
||||
assert_eq!(s.catalog.photo(id).unwrap().kind, lightcraft_catalog::MediaKind::Video);
|
||||
s.execute("library.filter", &json!({"kind": "video"})).unwrap();
|
||||
assert_eq!(s.visible(), &[id]);
|
||||
s.execute("library.filter", &json!({"kind": "image"})).unwrap();
|
||||
assert!(s.visible().is_empty());
|
||||
s.execute("edit.undo", &json!({})).unwrap();
|
||||
assert!(s.catalog.is_empty());
|
||||
s.execute("edit.redo", &json!({})).unwrap();
|
||||
s.execute("library.filter", &json!({"kind": "video"})).unwrap();
|
||||
assert_eq!(s.visible(), &[id]);
|
||||
std::fs::remove_dir_all(dir).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn native_video_reimport_repairs_kind_without_losing_edits_or_memberships() {
|
||||
let dir = std::env::temp_dir().join(format!("lightcraft-lrcat-video-reimport-{}", std::process::id()));
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let path = dir.join("videos.lrcat");
|
||||
let mut tables = photo_tables((dir.to_str().unwrap(), ""));
|
||||
tables[2].2[2] = SqlValue::Text("clip.MOV".into());
|
||||
tables[3].2[3] = SqlValue::Text("VIDEO".into());
|
||||
std::fs::write(&path, native_catalog(&tables)).unwrap();
|
||||
let mut s = crate::Session::new();
|
||||
let id = s.catalog.alloc_photo_id();
|
||||
let mut photo =
|
||||
Photo::new(id, Source::File { path: dir.join("Photos/clip.MOV").to_string_lossy().into() }, "clip.MOV", "VIDEO", 1920, 1080, "before");
|
||||
photo.rating = 5;
|
||||
photo.flag = Flag::Pick;
|
||||
photo.file_size = 1234;
|
||||
photo.content_hash = Some("existing-content".into());
|
||||
s.commit("Previous import", Op::AddPhoto { photo: Box::new(photo) }).unwrap();
|
||||
let mut settings = lightcraft_develop::DevelopSettings::default();
|
||||
settings.light.exposure = 0.75;
|
||||
s.set_develop(id, settings, "Personal edit").unwrap();
|
||||
let peer_id = s.catalog.alloc_photo_id();
|
||||
let peer = Photo::new(peer_id, Source::File { path: "/missing/peer.jpg".into() }, "peer.jpg", "JPEG", 20, 10, "before");
|
||||
s.commit("Peer", Op::AddPhoto { photo: Box::new(peer) }).unwrap();
|
||||
let mut album = Album::new(s.catalog.alloc_album_id(), "Personal album");
|
||||
album.photos = vec![id, peer_id];
|
||||
s.commit("Album", Op::AddAlbum { album: album.clone() }).unwrap();
|
||||
let stack = lightcraft_catalog::Stack { id: s.catalog.alloc_stack_id(), photos: vec![id, peer_id], collapsed: false };
|
||||
s.commit("Stack", Op::AddStack { stack: stack.clone() }).unwrap();
|
||||
let before = s.catalog.to_snapshot();
|
||||
let mut expected = (**s.catalog.photo(id).unwrap()).clone();
|
||||
expected.kind = lightcraft_catalog::MediaKind::Video;
|
||||
s.execute("library.filter", &json!({"kind": "video"})).unwrap();
|
||||
assert!(s.visible().is_empty());
|
||||
let result = s.execute("library.importLightroom", &json!({"path": path})).unwrap();
|
||||
assert_eq!(result["mapping"]["1"], id.0);
|
||||
assert_eq!(result["imported"], 0);
|
||||
assert_eq!(result["preservedExistingEdits"], 1);
|
||||
assert_eq!(s.catalog.photo(id).unwrap().as_ref(), &expected);
|
||||
assert_eq!(s.visible(), &[id]);
|
||||
let after = s.catalog.to_snapshot();
|
||||
assert_eq!(s.catalog.album(album.id), Some(&album));
|
||||
assert_eq!(s.catalog.stack(stack.id), Some(&stack));
|
||||
s.execute("edit.undo", &json!({})).unwrap();
|
||||
assert_eq!(s.catalog.to_snapshot(), before);
|
||||
assert!(s.visible().is_empty());
|
||||
s.execute("edit.redo", &json!({})).unwrap();
|
||||
assert_eq!(s.catalog.to_snapshot(), after);
|
||||
assert_eq!(s.visible(), &[id]);
|
||||
std::fs::remove_dir_all(dir).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reads_native_sqlite_tables_without_lightroom_or_external_processes() {
|
||||
let bytes = native_catalog(&photo_tables(("/catalog/", "")));
|
||||
|
||||
+2
-1
@@ -27,7 +27,7 @@ Hours are Opus 5.5 agent wall-clock hours (see [target-app-parity.md](target-app
|
||||
| 10 B | **Per-model verification thin, plus cheap per-body decode fixes**: 551 of 1,446 Adobe models verified (38%), ~85% of photographers on a verified body; Nikon 5 bodies verified, Canon 34, Leica 14 (the Q3 by a recorded check of 38 private DNGs). Cheap fixes: Z 6II packed 14-bit NEF (#769, PR #671), Sony A100 regression (#702); F828 SRF now discovered and imported as preview-only, sensor decoding still missing, DSLR-A200…A390 / A850 12-bit ARW (#535) | measured: [raw/coverage.tsv](raw/coverage.tsv) | per-body bugs (levels, crops, WB) surface only from users | 25–45 | [raw-parity](raw-parity.md#by-maker-measured) |
|
||||
| 11 | **Enhance: Raw Details, Super Resolution; AI denoise without shippable weights or X-Trans** | ENH rows 0%; denoise Bayer only, RawNIND weights GPL and opt-in | Fujifilm users get no AI denoise; nobody gets it out of the box | 30–60 + model decision | [raw-parity](raw-parity.md#demosaic-levels-crops-and-lens-metadata) |
|
||||
| 12 | **Content-aware / generative remove, detect distractions, reflections removal** | REM rows 75%; patch synthesis missing | cleanup work goes back to Photoshop | 25–45 (+ generative model) | [target-app-parity](target-app-parity.md#ai) |
|
||||
| 13 | **Lightroom catalog migration is one-way and approximate**: unsupported Adobe profiles / AI settings archived, history kept as data; main-file pages read on demand up to 16 GiB, with dense-table and WAL bounds retained (#798); offline record counts and destination are now shown in a lasting import result; before an import the app asks whether the catalog merges into the open library or goes into a new library (opt-out in Settings, #2672) | lightroom-catalog-import.md | switching users lose some looks | 8–12 | [file-format-parity](file-format-parity.md) |
|
||||
| 13 | **Lightroom catalog migration is one-way and approximate**: unsupported Adobe profiles / AI settings archived, history kept as data; main-file pages read on demand up to 16 GiB, with dense-table and WAL bounds retained (#798); offline record counts and destination are now shown in a lasting import result; catalog VIDEO records match the Videos filter, with older classification repaired on reimport; before an import the app asks whether the catalog merges into the open library or goes into a new library (opt-out in Settings, #2672) | lightroom-catalog-import.md | switching users lose some looks | 8–12 | [file-format-parity](file-format-parity.md) |
|
||||
| 14 | **HDR display** (EDR / Windows HDR); the headroom limit and SDR rendition from `crs` XMP (the HDR switch, `HDREditMode`, is read). HLG AVIF export done; the display's SDR/HDR decision is tested, blocked on eframe's 8-bit surface | HDR rows 70%; LR-VIEW-HDR-DISPLAY ⬜ | HDR editing works blind on HDR monitors | 12–25 | [hardware-parity](hardware-parity.md) |
|
||||
| 15 | **Print module**: identity plate / watermark / photo info overlays, Cut Guides for the packages, Custom Package Auto Layout, printer-driver Page Setup and direct printing, JPEG file output (the Print dialog writes a colour-managed PDF) | LRC-PRINT rows | Classic users who print | 15–25 | [target-app-parity](target-app-parity.md#features) |
|
||||
| 16 | **Map view, Book, Slideshow module, publish services** | LRC-MAP / BOOK / SS rows ⬜ | Classic users; publish services matter for Flickr / SmugMug workflows | 60–100 | [target-app-parity](target-app-parity.md#features) |
|
||||
@@ -106,6 +106,7 @@ Beta-blocking gaps (B) total **~230–430 h**; with the stability and platform w
|
||||
| 2026-10-12 | minor | Gap 10: SR2/SRF folder discovery fixed; F828 imports as preview-only. Sensor decoding remains a gap; readiness scores unchanged |
|
||||
| 2026-10-23 | minor | Gap 28: ⌘L / Ctrl+L (Library ▸ Enable Filters) puts the filter aside and brings it back as it was; the entry drops ⌘L; hours unchanged |
|
||||
| 2026-10-15 | minor | Gap 28: `\` shows / hides the Filter Bar in the grids; the entry drops `[` `]` (#509), flag cycling (#1490) and F1 (Help), already on main; ⌘L is the filter-bar key left; hours unchanged |
|
||||
| 2026-10-16 | patch | Gap 13: catalog VIDEO records match the Videos filter, including after reimport of older records (#1940, filter issue only). Video playback, frame previews and folder-sync discovery remain outside this repair; no gap closed or counts changed. |
|
||||
| 2026-10-14 | minor | Gap 26: at 100k photos stack and album lookups are indexed, so an "In a Stack" or "Album" smart album counts in ~14 ms (was 0.6–2.7 s); open time unchanged |
|
||||
| 2026-10-14 | minor | Gap 10: Camera-coverage sweep (#1327): 30 models verified on 40 CC0 files (coverage.py 515 → 545 verified); sensor verification does not establish colour parity (#1277) |
|
||||
| 2026-10-14 | minor | Gap 21: de, es, fr, ja and uk catalogs filled (97–99%); 55–90 h → 40–70 h |
|
||||
|
||||
@@ -73,6 +73,11 @@ edits are preserved by default; `updateExisting=true` explicitly replaces them.
|
||||
identity prevents reimport from duplicating virtual copies and collections. One undo step reverses
|
||||
catalog changes; any saved recovery archives remain available.
|
||||
|
||||
Records marked `VIDEO` in the source catalog appear in the **Videos** type filter, including
|
||||
offline originals. Reimport also repairs the classification of videos imported as images by
|
||||
older builds, preserving their IDs, edits and album/stack membership. This does not add video
|
||||
playback, frame previews or video discovery through folder synchronization.
|
||||
|
||||
Before changing records, the importer attempts to save source image records, decoded XMP,
|
||||
verbatim develop settings, history, snapshots and collection content to compressed
|
||||
`Interop/lightroom-import-N.lca` recovery archives in the LightCraft library. Archiving is
|
||||
|
||||
@@ -699,7 +699,7 @@ From `08-lightroom-classic-extras.md` (Classic-only features) and part 2 of `06-
|
||||
| LRC-LIB-SURVEY | Survey view | P2 | ✅ | `cmd:view.survey` | N |
|
||||
| LRC-LIB-REFVIEW | Reference view | P2 | ✅ | `cmd:view.reference`, `cmd:photo.setReference`, `crates/ui-egui/src/panels/compare.rs` (`show_reference`) | View ▸ Reference View (⇧R): the reference photo beside the active one (edited with the Edit panel); photo menu ▸ Set as Reference Photo; each pane says “Rendering…” (widget `compare:rendering:<pane>`) or “This photo can't be opened” (`compare:renderFailed:<pane>`) as the loupe does. Escape → Detail without losing edits; pins are catalog-local; missing/deleted photos refused and deleted references no longer drawn (Windows regression/native smoke verified) |
|
||||
| LRC-LIB-CATALOG-PANEL | Catalog sets | P1 | ✅ | `cmd:library.source` (`missing`) | all, recently added, picks, recently deleted, missing photos (when any) |
|
||||
| LRC-LIB-CATALOG-IMPORT | Native Lightroom Classic catalog import | P1 | 🟡 | `cmd:library.inspectLightroom`, `cmd:library.importLightroom`, `cmd:file.importLightroom`, `crates/engine/src/lightroom_catalog.rs`, `crates/ui-egui/src/dialogs/lightroom_destination.rs`, `crates/ui-egui/src/tests/lightroom_destination.rs`, `docs/lightroom-catalog-import.md` | before the import starts, File ▸ Import Lightroom Catalog… asks where the catalog goes: merge into the open library (named, with its photo count; preselected when it is empty) or create a new library (named after the catalog file, next to the open library, both editable), which is made and opened following File ▸ New Library…'s rules before the import; Cancel does nothing; Settings ▸ General ▸ "When importing a Lightroom catalog" (Ask where to import it / Always merge into the open library) or the window's "Don't ask again" turns it off; `file.importLightroom` takes `into` (`open` / `new`), `name`, `location` to choose without the window; a session in memory merges without asking (issue #2672); read-only `.lrcat` plus committed WAL pages (also WAL-only tables with main schema format 0), in-tree read-only Rust SQLite B-tree reader; on-demand main-file pages up to 16 GiB with existing table/record bounds (WAL still capped at 1 GiB, issue #798); background inspection/import with progress/cancellation, per-open library identity checks; persistent result with destination library, offline-original counts and Show in Library, dismissed when switching libraries; offline Local records are promoted without probing missing files; originals in place, ratings/flags/labels, XMP, hierarchical keywords, collection sets/regular collections, virtual copies, mapped develop settings; stable reimport identities, undo, missing-file placeholders, a root folder not found at its recorded path looked up relative to the catalog (Lightroom's `relativePathFromCatalog`, so a project folder copied from another computer stays linked; reported as a warning), existing edits preserved. Best-effort deduplicated recovery archives retain settings/history/snapshots/collection rules (32 MiB each, eight archives/128 MiB aggregate); archive limits/write failures and optional-table limits warn without blocking photo import; unrelated unsupported tables and opaque SQL BLOBs skipped. Custom white balance on relative-WB raws (`RAW` in Lightroom's terms) stays As Shot and is reported, since the catalog keeps no as-shot white to shift from (issue #510). An image whose file, folder or root folder record is missing from the catalog, or whose original path is empty, is skipped with its virtual copies instead of failing the whole import; the report lists them as data (`skipped`: image id and reason) and the result window counts them in the UI language (PR #2230). Adobe rendering, AI data and native history replay remain incomplete; no writes to Lightroom catalogs. Open Library given a Lightroom catalog folder, an `.lrdata` / `.lrcat-data` folder or the `.lrcat` makes no library there and offers this import with the catalog found (`cmd:app.openLibrary`, `crates/engine/src/lightroom_folder.rs`; issue #891) |
|
||||
| LRC-LIB-CATALOG-IMPORT | Native Lightroom Classic catalog import | P1 | 🟡 | `cmd:library.inspectLightroom`, `cmd:library.importLightroom`, `cmd:file.importLightroom`, `crates/engine/src/lightroom_catalog.rs`, `crates/ui-egui/src/dialogs/lightroom_destination.rs`, `crates/ui-egui/src/tests/lightroom_destination.rs`, `docs/lightroom-catalog-import.md` | before the import starts, File ▸ Import Lightroom Catalog… asks where the catalog goes: merge into the open library (named, with its photo count; preselected when it is empty) or create a new library (named after the catalog file, next to the open library, both editable), which is made and opened following File ▸ New Library…'s rules before the import; Cancel does nothing; Settings ▸ General ▸ "When importing a Lightroom catalog" (Ask where to import it / Always merge into the open library) or the window's "Don't ask again" turns it off; `file.importLightroom` takes `into` (`open` / `new`), `name`, `location` to choose without the window; a session in memory merges without asking (issue #2672); read-only `.lrcat` plus committed WAL pages (also WAL-only tables with main schema format 0), in-tree read-only Rust SQLite B-tree reader; on-demand main-file pages up to 16 GiB with existing table/record bounds (WAL still capped at 1 GiB, issue #798); background inspection/import with progress/cancellation, per-open library identity checks; persistent result with destination library, offline-original counts and Show in Library, dismissed when switching libraries; offline Local records are promoted without probing missing files; originals in place, ratings/flags/labels, XMP, hierarchical keywords, collection sets/regular collections, virtual copies, mapped develop settings; stable reimport identities, undo, missing-file placeholders; VIDEO records match the Videos filter, with reimport repairing older image classification while keeping edits and memberships; a root folder not found at its recorded path looked up relative to the catalog (Lightroom's `relativePathFromCatalog`, so a project folder copied from another computer stays linked; reported as a warning), existing edits preserved. Best-effort deduplicated recovery archives retain settings/history/snapshots/collection rules (32 MiB each, eight archives/128 MiB aggregate); archive limits/write failures and optional-table limits warn without blocking photo import; unrelated unsupported tables and opaque SQL BLOBs skipped. Custom white balance on relative-WB raws (`RAW` in Lightroom's terms) stays As Shot and is reported, since the catalog keeps no as-shot white to shift from (issue #510). An image whose file, folder or root folder record is missing from the catalog, or whose original path is empty, is skipped with its virtual copies instead of failing the whole import; the report lists them as data (`skipped`: image id and reason) and the result window counts them in the UI language (PR #2230). Adobe rendering, AI data and native history replay remain incomplete; no writes to Lightroom catalogs. Open Library given a Lightroom catalog folder, an `.lrdata` / `.lrcat-data` folder or the `.lrcat` makes no library there and offers this import with the catalog found (`cmd:app.openLibrary`, `crates/engine/src/lightroom_folder.rs`; issue #891) |
|
||||
| LRC-LIB-CATALOG-LOCK | Catalog open in one program at a time | P1 | ✅ | `cmd:app.openLibrary`, `crates/catalog/src/lock.rs`, `crates/engine/src/library.rs` (`open_library`) | exclusive OS lock on `catalog.lock` for the session (app and `lightcraft-cli --library`); a second opener is refused with who has it (`catalog.lock.owner`: program, process, computer); released by the OS on a crash, so never stale; file systems without locks open unprotected with a warning (the app's notices, `library.info` → `settingsWarnings`, and the CLI's stderr; issue #171); no read-only mode; the browser build (OPFS) has no guard across tabs yet. A library that can't be opened at launch (locked, unreadable, newer format, drive missing) shows a window — Try Again, Choose Another Library…, Continue Without Saving (then a banner; nothing written), Quit — instead of a silent demo session (`crates/ui-egui/src/panels/library_problem.rs`); the lock is released explicitly when the library closes, not by letting its file handle close, so a program another thread is starting at that moment (which holds a copy of every file handle until it is launched) cannot keep the library "already open" for a moment (issue #680) |
|
||||
| LRC-LIB-CATALOG-SWITCH | New / Open Recent catalog, catalog name shown | P1 | ✅ | `cmd:app.newLibrary`, `cmd:app.openLibrary`, `cmd:app.recentLibraries`, `cmd:app.clearRecentLibraries`, `crates/ui-egui/src/dialogs/settings.rs`, `crates/ui-egui/src/panels/left.rs`, `crates/ui-egui/src/panels/library_problem.rs` (`launch_plan`, `show_chooser`), `crates/ui-egui/src/tests/launch_library.rs` | File ▸ New Library… (name, then location), File ▸ Open Recent Library (last 8; missing ones greyed out, dropped when opened; Remove from List ▸ one entry, or `app.recentLibraries {remove}`, which forgets only the path; Clear), the open library's name under My Photos and in the window title (issue #902); Open/New refused during imports and their folder scans; a library that can't be opened leaves the current one and its reference pin intact; a successful switch clears the catalog-local reference pin; ⌘O (Ctrl+O on Windows and Linux) runs Open Library… and asks for a folder once (`crates/ui-egui/src/tests/keymap.rs`: `cmd_o_opens_the_library_picker_once`); a dialog or a text field with the focus keeps the key; Settings ▸ General ▸ At launch: Open the last library (default) or Ask me, a window listing the recent libraries (name, folder, when last opened; missing, unreadable or no-longer-library ones greyed out with the reason, checked read-only — nothing is locked or written, so a library another program has open is reported, with who has it, when Open is pressed; the last one selected; Open, Open Another…, New Library…, Remove from List, Quit; ↑ ↓ Return Esc), also shown once when Alt/Option is held in the first 2 s after the window appears (macOS reports an Option key held since before launch only once it changes); `--library` and `LIGHTCRAFT_LIBRARY` come first and `lightcraft-cli` never asks (issue #1290) |
|
||||
| LRC-LIB-FOLDERS | Disk folder tree | P1 | ✅ | `cmd:library.browse`, `cmd:folder.rename`, `cmd:folder.move`, `crates/ui-egui/src/panels/left.rs` (`local_section`, `folder_tree`) | standard places + the browsed folder + Browse Folder…, each an expandable tree of subfolders, breadcrumb navigation; context menu: Rename Folder…, Move Folder To…, Show in Finder (on disk, photos relinked; one undo step each: undo / redo move the folder back and forth, refused when the destination is taken) |
|
||||
@@ -846,6 +846,7 @@ Latin stays upright. Advanced Japanese composition remains open. Regression cove
|
||||
| 2026-10-13 | minor | LRC-LIB-KEYWORDS: the Keyword List marks a keyword that has an applied keyword inside it (a dot in its box); status unchanged |
|
||||
| 2026-10-12 | minor | LR-IMP-FORMATS: folder discovery includes SR2/SRF; MCP and CLI reuse the engine extension list. DSC-F828 remains preview-only; decoder support and row status unchanged |
|
||||
| 2026-10-15 | patch | KEYC-RATING: `\` shows / hides the Filter Bar in Photo Grid and Square Grid (Show Original in Detail); status unchanged (🟡) |
|
||||
| 2026-10-16 | patch | LRC-LIB-CATALOG-IMPORT: VIDEO records appear in the Videos filter; reimport repairs older classification with edits, memberships and undo preserved (#1940, filter issue only). Status and summary counts unchanged. |
|
||||
| 2026-10-12 | minor | LR-EDIT-OPTICS-PROFILE: Sony ARW shading, CA and distortion tables decoded with settings and provenance (raw IFD, `SR2SubIFD` fallback); applied corrections unchanged (ILCE-7RM4A and ILCE-7RM6 distortion); status unchanged (🟡) |
|
||||
| 2026-10-14 | minor | LR-IMP-CAMERA-COVERAGE: Camera-coverage sweep (#1327): 30 models verified on 40 CC0 files (coverage.py 515 → 545 verified); sensor verification does not establish colour parity (#1277); status unchanged (🟡) |
|
||||
| 2026-10-13 | minor | LR-MERGE-PANO: a panorama's DNG takes its `AsShotNeutral` from the median of its frames' vendor white-balance multipliers (CR2, NEF, ARW…) instead of the first frame's tags, and frames now carry the multipliers (issue #1144); status unchanged (✅) |
|
||||
|
||||
Reference in New Issue
Block a user