"Set name" (Edit Keyword Set, Save Keyword Set) read 标签集名称 /
標籤集名稱, the colour label sets' term; it is 关键字集名称 /
關鍵字集名稱, as the rest of the dialog says. "Edit Set…" says what it
edits: 编辑关键字集… / 編輯關鍵字集….
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Edit Set… on Recent Keywords saves a new set (`new: true`): a name
another set has is refused, where it used to replace that set.
- The dialog checks names before saving and says why in the user's
language ("There is a keyword set “…” already"; Recent Keywords is
built in), instead of showing the engine's message.
- A set deleted while its dialog was open is saved again, as a new set,
rather than refused with no way out but Cancel.
- Save as a new set (Lightroom Classic's Save as New Preset) keeps the
edited set and saves the edits under the new name.
Russian gets "Recent Keywords", which showed in English.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saving compared set names by any letter's case while using, deleting
and the current set compared ASCII case only: "été" saved over "ÉTÉ"
but couldn't use or delete it. Every set command (and Recent Keywords)
now compares names one way, as keywords are compared.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saving Recent Keywords as a set under the name of an existing one
(Edit Set… on Recent Keywords) replaced that set's keywords without a
word, while renaming onto a taken name was refused. `keyword.saveSet`
takes `new: true` for a set that must be new, and refuses a name
another set has.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`keyword.saveSet {name, replace}` without `keywords` took the current
set's keywords, so renaming a set that wasn't current gave it another
set's nine. The keywords default to the renamed set's own now (the
current nine only for a new set), and an empty `replace` is no rename.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The nine fields took their width from what the dialog had while it
found its size: the first two columns came out squeezed ("ceremony"
showed "ceren") and the third wide. They are now equal columns of a
set width.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Keyword Set menu gets Edit Set… (Lightroom Classic's Edit Keyword
Set): the set's name and its nine keywords, one field per ⌥ key, typed
in place. Editing Recent Keywords and naming them saves a new set and
makes it current; editing a named set renames it in its place. An
empty field is an empty slot, shown as an idle button so the others
keep their keys. Return in any field saves; a set without a name says
so and the dialog stays open. Russian gets "Set name", and the label
check covers the new labels.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
For Edit Keyword Set (Lightroom Classic's), `keyword.saveSet`:
- keeps each slot in its place: an empty one ("") is an empty slot, so
the keywords after it keep their ⌥ keys (empty ones were dropped and
the rest moved up); trailing empty slots go, nine at most;
- holds each keyword once, whatever its case: a second one leaves its
slot empty;
- with `replace`, renames that set in its place among the sets and
keeps it current; a name another set has is refused.
⌥ on an empty slot does nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A DNG can state a white level the sensor never reaches (an iPhone 15 Pro Max Bayer DNG states 4095 but clips at 3567), so clipped highlights were not recognised and white balance tinted them magenta. On decode, samples that form a plateau clearly below the white level, with nothing above it, are raised to the white level. RENDER_CACHE_VERSION 25 (needs adjusting at merge).
German says "Es werden keine Stichwörter exportiert", the natural word
order; Japanese names the view "書き出されるキーワード" (the keywords
that will be exported) rather than the vaguer "書き出される内容".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lightroom Classic's Keywording box has three views; the box had two.
The switch now offers Keywords, & Containing (the selection's keywords
with the keywords containing them, flat and read only) and Will Export,
the two read-only views cached per selection. The label check covers
the box's other labels passed through variables too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The box emptied itself on Esc, on top of the shared field's own undo of
the edit: text left there by an earlier edit (ended by clicking away)
went too. Esc now gives back what the box held before the edit, as
every text field does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`chips_stay_on_one_line` held by construction once chips were drawn at
a fixed height with their × on their own line. It now checks that every
chip is on one line inside the panel and that none overlaps another,
with a keyword longer than the panel among them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drawn as one widget, a chip and its × lost the names a button gave
them: screen readers met unlabeled buttons. The chip is now named after
its whole keyword (even when cut short on screen) and the × "Remove
“…”". Both answer under ids made from their keyword rather than their
place in the row, so a chip's open menu stays with its keyword when the
chips change underneath it (an undo, a sync).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A photo listed twice in the selection counted twice, and an id the
library doesn't have counted in "of": the chips, Will Export and the
Keyword List's tick boxes now count the distinct selected photos.
- The chips looked each keyword's spelling up by scanning every photo
(178 ms with 20,000 photos and 2,000 keywords selected, at every
change while selected): they now take the keyword list's spelling
(`Catalog::listed_path`) or the first one seen, 26 ms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A chip too long for its row was cut with the file-path shortener, which
keeps the start: "Places › Portugal ›…" lost the keyword's own name and
the asterisk of a partial one. `chip_label` now cuts from the front
("…Lisbon › Belém tower *"). A chip also had two tooltips (its whole
name, and how many selected photos have it); it has one with both.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`keyword.toggleFromSet` checked whether every target photo had the
keyword by ASCII case, while the set's buttons and the rest of the
keyword code match any letter's case: with "ÄRZTE" and "ärzte" on the
photos the button showed on, but ⌥N added the keyword (a no-op) instead
of taking it off, so it could never be toggled off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keyword commands act on the selected photos, or on the active photo
when the selection is empty (`Session::targets`), but the Keywording
box, the keyword set's buttons, the suggestions and the Keyword List's
tick boxes read the selection only: with just an active photo the box
showed nothing while typed keywords went to it. They now all use the
photos the commands use.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The keyword rows of the parity tracker describe the box and the chip
menu; What's New explains the chips, Will Export and what follows the
selection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A chip was a frame laid out in what was left of its line: one that
didn't fit wrapped its own text, down to a letter a line, and pushed
its × to the next line. A chip is now one widget measured before it is
placed (its name cut short to fit the row), so the row moves it whole
to the next line; the Will Export names alike.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Suggestions were worked out from the active photo's keywords: a keyword
it had wasn't suggested though other selected photos lacked it. They
now leave out only the keywords every selected photo has, and build on
those for keywords used with them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Keyword to paint" gets the Cut / Copy / Paste / Select All menu and
Esc, and Return starts painting as the Paint button does. It stays
fixed while painting.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lightroom Classic's Keywording box can show the keywords that will be
exported rather than those entered. A Keywords / Will Export switch
under the box now does the same for the selection: the names exported
files carry as the keyword tag options say (a keyword left out of
export goes, parents and synonyms come), one only some of the photos
carry marked with an asterisk. Read only; cached per selection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The nine buttons showed "on" when the active photo had the keyword,
while their ⌥1–⌥9 toggle acts on every selected photo. A button is now
on when every selected photo has its keyword, and marked with an
asterisk when only some do, as the chips are.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It gets the Cut / Copy / Paste / Select All menu (paste a list of
keywords from elsewhere), Return gives the keywords to every selected
photo as before, and Esc gives up what was typed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The chip menu offered Delete Keyword, which takes the keyword off every
photo in the library, beside "Remove from Photo". It now acts on the
selected photos only: Add to All Selected Photos (for a keyword only
some have), Remove from Selected Photos, Show Photos with Keyword, and
Edit Keyword Tag… (the Keyword List's dialog, for renaming too).
Deleting a keyword from the library is the Keyword List's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lightroom Classic 15.6 imports an XMP packet's channel curves only when it holds
ToneCurvePV2012 and all three of ToneCurvePV2012Red/Green/Blue; any partial set
(master + one or two channels, channels without the master) imports without
channel curves. #416 read them whenever the master curve was present.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The chips at the top of the Keywords panel showed the active photo's
keywords, while adding and removing applied to every selected photo:
with several selected they misreported what the selection had. They
are now the keywords of every selected photo, each once whatever its
case (`panels::keywording`, cached per selection), and one only some
of them have is marked with an asterisk ("On 1 of 2 selected photos").
Only the × removes a keyword, from every selected photo: a click on
the chip itself used to remove it too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of #535 (items 4 and 5).
- Pre-2017 bodies without Sony crop tags shot in the camera's 16:9 mode now get
the 16:9 crop of their camera JPEG: width from FullImageSize, anchored left as
before (drops the ILCE-7SM2's 32 padding columns); height from FullImageSize
(ILCE-7SM2) or from an Exif image size of the same width (DSLR-A580, whose
FullImageSize still says 3:2); centred vertically at an even offset, as
measured by registering each camera JPEG on its raw. The aspect now matches
the JPEG, so the camera-look fit runs: ILCE-7SM2 dE 15.2 -> 4.8,
DSLR-A580 dE 26.7 -> 3.9 (vs main 88ea1a8).
- The DSC-R1's SR2 (maker-note FileFormat 1 0 0 0) stores encrypted samples and
decoded to noise; it is now Unsupported in full and header mode and imports
preview-only with that reason.
- Only these 3 of 140 Sony decodes change; render cache version 26 (23-25 are
taken by #568, #542, #575).
- Tests: crop helper (3:2 unchanged, both 16:9 sources, even offsets, hostile
sizes), synthetic Sony file with FileFormat SR2 vs ARW, corpus test of the
two crops and the SR2 refusal; three samples added to the corpus list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The parity row said Person shapes exported files: it is stored only.
It now also covers the list without a selection, the default parent's
reach (typed keywords too) and keywords' hierarchy on import. The
synonyms' doc no longer says search finds them, which it doesn't yet.
What's New follows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With nothing selected a tick box still offered "Add to Selected
Photos", and while a filter holds the levels open the triangle lit up
on hover though a click does nothing. Neither does now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The toast said every dropped photo got the keyword, those that had it
already included. It now counts the photos that didn't have it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lightroom Classic puts new keywords typed for photos inside the keyword
marked Put New Keywords Inside This Keyword; only + did here. The
Keywords panel's box now does too (`Catalog::typed_keyword`): a new
name goes inside the default parent, while a keyword the library has,
or a path typed whole, stays as typed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Russian had no "Person": the option showed in English (it reaches
`tr` through a variable). A test now checks that every label the
Keyword List passes that way is in every language's file.
- The merge confirmation's button said "Merge", which some languages
translate as merging photos (HDR, panorama): it says "Merge Keywords".
- Traditional Chinese uses 匯出 for Export, as everywhere else in the
file, not 轉存; "Export Containing Keywords" means the parent
keywords in both Chinese files (上層 / 上级), not "included" ones.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Keyword List ended a keyword drag only while it was drawn: with
another panel opened mid-drag, the drag lingered until the list came
back. `keyword_list::drag_feedback` now runs every frame, like the
album drag's: the drag ends with the button's release wherever it is,
or with Esc. A press on a tick box that moves no longer picks the
keyword up. The test that a keyword can't be dropped inside itself
now checks that no move was even tried.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After a rename (Edit Keyword Tag), a drag or a merge made in the list,
the picked keyword still named the old path (the highlight went and −
was greyed out for a keyword that was there) and the renamed levels
closed. The pick and the open levels now follow the keyword, and the
levels containing it open, so a keyword dropped into another stays in
sight.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of #535 (item 1). Stacked on #542 (SR2 black levels); supersedes its
positional keystream tables.
- White balance is WB_RGGBLevels (0x7313), the gains the camera applied:
the raw IFD's plain copy when present, else the copy in the encrypted
SR2SubIFD, which every ARW from the DSLR-A200 on carries (identical to
the plain one on all 57 CC0 files that have both). The maker note's
Tag2010 gains stay only as a last resort.
- 14 bodies had no white balance and rendered green whenever the camera
look was rejected (A450 ... A700, NEX-3/5/C3, SLT-A33/A35/A55,
ILCE-6001, UMC-R10C). On others Tag2010 missed the applied gains by up
to 100 % (ILCE-3500 at 5600 K: R -31 / B +101 % against the camera
JPEG's neutral pixels, now +4 / +0 %; ILCE-7S on Shade -9 / +15 ->
-1 / +1 %; SLT-A57 -25 / +26 -> -6 / -3 %).
- New vendor/sr2.rs decrypts the whole SR2SubIFD, found black-box:
exiftool -v5's decrypted dump as known plaintext gives the keystream
(key 11 22 33 44, the same at every position in 126 CC0 ARWs from 97
bodies, 15 layouts); an exhaustive search over lag pairs found
k[n] = k[n-63] ^ k[n-127] on 32-bit words, so the first 127 words
generate the rest, matching all 126 files (5.2 MB of keystream).
- The SR2 black level (0x7310) is now read through the same decryptor,
replacing #542's head and per-position keystream tables: one SR2
decryption path. Identical results on all 131 Sony files (every
value #542 decoded; the 51 it could not are the files' plain 0x7310).
Unit tests pin the keystream against answers recorded without the
generator: every byte #542 and #148 had recovered, the SHA-256 of the
whole 62112-byte keystream recovered from the CC0 DSLR-A700 sample, and
the encrypted WB_RGGBLevels of four CC0 files (one per layout) with the
levels ExifTool decrypts.
- Sweep (4f350c4 -> this): gains equal ExifTool's decrypted
WB_RGGBLevels on all 100 decoded CC0 CFA files; on 83 files with
>= 200 JPEG-neutral pixels, within 10 % of the camera's applied gains
71 -> 83, over 10 % 5 -> 0. Accepted fits unchanged (max 0.15 dE);
forced fallback median dE 18.50 -> 18.06, neutral-area cast on the 22
changed files 8.8 -> 1.2.
- Corpus test for five CC0 samples (A500, A33, A700, ILCE-3500 5600 K,
ILCE-7S Shade; three added to RAW_SAMPLES); the pre-2017 test's gains
move to WB_RGGBLevels (RX100 III, RX100, ILCE-7RM2: within 2.6 % of
the old Tag2010 values in Auto). Synthetic tests for decryption,
directory parsing, source precedence, black level through the full
DNGPrivateData chain, and hostile input; #542's layout tests (incl.
the A700 trap) now run through the decryptor.
- Render cache version 25.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In Create / Edit Keyword Tag only the name field answered Return: typed
synonyms followed by Return did nothing. Return in Synonyms now creates
(or saves) the keyword too, as a dialog's default button does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With no photo active the whole right panel said "No photo selected",
so the library's Keyword List disappeared: keywords couldn't be made
or organized before choosing a photo. The Keywords panel now shows the
list without a selection (its tick boxes wait for one), under a note
that selecting photos gives them keywords.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Keyword List took a drop wherever the pointer was inside a row's or
the title's rectangle, even where the panel had scrolled it out of
sight: a keyword released over the app's top bar, where the list's
title was hidden, went to the top level. Drops now need the pointer on
the visible part of the panel too; photos dropped from the grid alike.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of #535 (items 2 and 3).
- SR2SubIFD black level: decrypt the directory's first entry (always the
black level, 0x7310) to find where its value sits, and decrypt it with the
keystream known for that position (1638, 2166, 2418, 2510). The fixed read at
2510 gave 354-365 on the DSLR-A450/A500/A550 and 975 on the DSLR-A700, where
ExifTool and the data floor say 512 (A700 render: dE 20.1 -> 8.8,
dL* -9.8 -> 0.0). Keystreams recovered black-box (plain 0x7310 and exiftool -v3
as known plaintext), consistent over 115 ARWs from 97 bodies, 15 layouts.
- Downsized lossless M/S ARWs (linear YCbCr): black 1024 and white 16895, i.e.
the recorded 512 plus 512, measured against same-scene full-size codings on
12 files from 4 bodies (offset 1015-1052, scale 0.98-1.02). The 512 pedestal
lifted shadows by ~3 % of white; M/S renders now match their full-size twins
(7RM5 M dE 6.7 -> 3.1).
- Only these 16 of 140 Sony files change; render cache version 24.
- Tests: synthetic SR2 blocks for every known layout (incl. the A700 trap),
YCbCr black/white; corpus test of black levels against the data floor;
A500 and A700 samples added to the corpus list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every row worked out its tick box from every selected photo's keywords,
every frame: with 20,000 photos selected a frame took seconds. `Ticks`
now counts each keyword over the selection once, cached by library
revision and selection, and each row looks its count up: 2.8 ms a
frame for 20,024 selected photos. The check that the picked keyword
still exists reads the cached tree instead of scanning every photo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fitted with `lightcraft-cli calibrate` to 125 usable ILCE-7CR ARWs (of 131,
September 2025 to September 2026, Standard creative style) and their
in-camera JPEGs; aggregate colour statistics only.
Without it, 8 of the 131 photos fail the fit gates and open with the
neutral matrix (dE76 6-26 against the camera JPEG). On 26 withheld photos
(profile fitted to the other 105) mean dE76 goes 4.07 -> 3.29 and both
withheld rejections are accepted (26.0 -> 6.1, 6.2 -> 5.5); the 24
withheld photos whose own fit was accepted are about unchanged (12
improve, mean 3.06 -> 3.08, worst regression 1.8). With the final profile
all 131 are accepted. The nine public raw.pixls.us ILCE-7CR codings stay
accepted (mean 1.59 -> 1.99).
A corpus test checks the public lossless-L sample's fit keeps exactly the
built-in profile's matrix and table.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rename, merge and delete answered `changed` with every change they
made, so with the keyword list it no longer meant photos (renaming a
keyword no photo has said 2). `changed` is photos again, and `listed`
counts the keyword list's changes (what Purge reports).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The YCbCr M coding's pedestal is corrected separately (#535, item 3), so
this test no longer depends on which change lands first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Three CC0 raw.pixls.us files of one ILCE-7CR (61 MP) scene: lossless
compressed L and M (subsampled YCbCr) and compressed ARW2. A raw corpus
test pins model, colour-filter layout, black level, white level, as-shot
gains and default crop, and checks that the lossless and compressed
mosaics agree inside the crop (green block correlation 0.9976). An engine
corpus test checks each gets a fitted camera look, not the neutral
fallback. All nine public codings decode and fit (mean dE76 1.59 against
their camera JPEGs).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>