So you have extracted your beloved Nikon input color profiles from an installation of Capture NX-D, Capture NX 2 or ViewNX-i using the guide “How_to_get_Nikon_ICM_profiles” from Rawpedia, placed the .icm files in /usr/share/darktable/color/in
, activated the “unbreak input profile” preset and then got confused, because those profiles are all called the same in the “input profiles” dropdown and it’s just guesswork which profile to use?
Well, then this guide is for you!
The main culprit here is the comment (<desc></desc>
tag) of the .icm file. The aforementioned Nikon tools all put a generic string there and that is what Darktable shows you.
The redneck method would be to simply grab a Hex editor of your choice, e. g. HxD is quite a good one, for Linux far less superior choices exist - I would perhaps recommend wxHexEditor, if you’re not already using the one coming with your favourite development IDE.
With the hex editor you locate the offending comment and overwrite with a string of choice which can’t be longer than the original one or strange things will happen. Problem solved. Windows users may like this approach, because from here on it gets complicated.
But wait, there’s a less tedious and more sophisticated approach - especially, if you have tons of input profiles maybe from other origins and do not want to edit every file manually. This involves exploiting the cirumstance that .icc/.icm files are not much more than “compiled” XML structures and we can use tools & scripts to convert them to XML (iccToXml
) and then back to .icm (iccFromXml
) after programmatically making the comment change. You could also tweak the profile in XML form or even create your completely own one!
So in case of Nikon NEF input files, the process is to (temporarily) install one of those tools - Linux users might want to use Wine for that - and monitor files such as %APPDATA%\Local\Temp\Nkn<random strings>.tmp
being created during raw image processing, which are .icm input profiles that are used, e. g. “Neutral”, “Monochrome”, “Landscape”, “Portrait”, “Vivid”, “D2XMODE1-3” and so on. You would the name those .tmp files approprately, ideally with no fancy characters, spaces and keeping them as short as possible minding the width of the Darktable input profile dropdown. Something like Nikon_D300_200ISO_Neutral.icm
is fine.
Those files typically end up at /usr/share/darktable/color/in
if all users should be able to use them (Windows would perhaps use %appdata%\Darktable
and so on for that purpose), on Linux you need to do some finalization
sudo mkdir /usr/share/darktable/color/in; sudo cp *.icm /usr/share/darktable/color/in
sudo chmod ugo-x /usr/share/darktable/color/in/*.icm; sudo chmod ugo+r /usr/share/darktable/color/in/*.icm
so everything can be accessed properly.
Now where to get iccToXml and iccFromXml? These are hosted at the Sampleicc Sourceforge repo and the Sourceforge iccxml repo respectively. Unfortunately I was not able to locate neither Linux nor Windows binaries or package downloads.
For Linux building those yourselve is fairly easy following the guide mentioned in this AskUbuntu-thread 741574 dubbed “how-can-i-rename-a-color-profile-and-change-the-title-stored-in-the-icc-file”, the gist of it is:
sudo apt-get install build-essential
sudo apt-get install libxml2-dev
sudo apt-get install libtiff5-dev
cd $HOME
mkdir icc
cd icc
wget [have to cripple the URL because of board restrictions]netcologne.dl.sourceforge.net/project/sampleicc/sampleicc%20tar/SampleIcc-1.6.8/SampleICC-1.6.8.tar.gz
wget [have to cripple the URL because of board restrictions]netcologne.dl.sourceforge.net/project/iccxml/IccXML-Src/IccXML-0.9.8/IccXML-0.9.8.tar.gz
tar -xzf SampleICC-1.6.8.tar.gz
cd SampleICC-1.6.8/
./configure --prefix=$HOME/icc/
make -j
make install
tar -xzf ../IccXML-0.9.8.tar.gz
cd IccXML-0.9.8/
PKG_CONFIG_PATH=$HOME/icc/lib/pkgconfig ./configure --prefix=$HOME/icc
make -j
make install
which is a complete nobrainer, worked like a charm in my case and leaves you with the two necessary files ./iccToXml
and ./iccFromXml
in your local ~/icc/bin
directory.
Windows users might have more trouble resolving the libtiff and libxml dependecies and getting everything running with MS Visual Studio. There is a README but you’re essentlally on your own here.
From there you could convert from .icm to .xml with ./iccToXml Nikon_D300_200ISO_Neutral.icm Nikon_D300_200ISO_Neutral.xml
, open up the XML with a text editor, fiddle with what’s between the tags <TagSignature>desc</TagSignature>
manually and write back the updated .icm with./iccFromXml Nikon_D300_200ISO_Neutral.xml Nikon_D300_200ISO_Neutral.icm
and call it a day.
But wait, there is still more! For the Linux users among you, I have written the script below which automatically updates the comment with the bare file name of the .icm profile (minus the path and extension), even accepting wildcards like ./icccomment.sh *.icm
. Here it is:
#!/bin/bash
# Script to update description tag of .icc/.icm files with file name.
# Changelog:
# 1.0: Initial Linux release.
version="1.0"
# References:
# rawpedia.rawtherapee.com/How_to_get_Nikon_ICM_profiles
# askubuntu.com/questions/741574/how-can-i-rename-a-color-profile-and-change-the-title-stored-in-the-icc-file/745506#745506
# sampleicc.sourceforge.net/
# sourceforge.net/projects/iccxml/
# regexr.com/85gtj
# discuss.pixls.us/t/input-color-profiles-in-darktable/33147
# docs.darktable.org/usermanual/4.0/en/module-reference/processing-modules/input-color-profile/
# Place input color profiles in /usr/share/darktable/color/in
# Define allowed extensions
ALLOWED_EXTENSIONS=("icc" "icm")
# Function to display help message.
display_help() {
echo "Usage: ${0##*/} <icc_or_icm_file>"
echo "Performs a regex search for '<TagSignature>desc</TagSignature>' and modifies the argument"
echo "'<ASCII><![CDATA[description]]></ASCII>' by replacing the string 'description' by the bare name"
echo "of the .icc or .icm file. No path, no extension. In place modification, wildcards allowed."
}
# Strip off path and extension from filename.
strip_path_and_extension() {
filename="$1"
filename_without_path="${filename##*/}" # Strip off path.
filename_without_extension="${filename_without_path%.*}" # Strip off extension.
echo "$filename_without_extension"
}
# Function to process each file.
process_file() {
local file="$1"
# Extract filename without path and extension, create file name for XML.
local base_name=$(strip_path_and_extension "$file")
local xml_file="${base_name}.xml"
echo "Opening '$file'..."
# Convert icm to xml.
$ICC_TO_XML "$file" "$xml_file" || { echo "Failed to convert '$file' to XML."; return 3; }
# Update XML file with the new description using perl and a regex.
perl -p0e "s|(<textDescriptionType>\s*<TagSignature>desc</TagSignature>.*?<ASCII><!\[CDATA\[)[^]]+(\]\]><\/ASCII>)|\1$base_name\2|s" -i "$xml_file"
# Convert XML back to .icm with modified suffix.
$ICC_FROM_XML "$xml_file" "$file" || { echo "Failed to convert '$xml_file' back to '$file'."; return 5; }
# Clean up.
rm "$xml_file"
echo "Updated '$file' with new description: '$base_name'."
}
echo "This is ${0##*/} V. $version,"
echo "a tool to update the description tag of .icc/.icm files with their file name."
# Check if no arguments are provided, then display help and exit.
if [ "$#" -eq 0 ]; then
display_help
exit 1
fi
# Check if local iccToXml and iccFromXml are available.
if [[ -x ./iccToXml && -x ./iccFromXml ]]; then
ICC_TO_XML="./iccToXml"
ICC_FROM_XML="./iccFromXml"
else
echo "Local iccToXml or iccFromXml not found. Please ensure they are in the current directory."
exit 2
fi
# Process each file provided as arguments.
for pattern in "$@"; do
# Expand wildcards and process each matching file.
for file in $pattern; do
# Check if the file exists and has a valid extension.
if [[ -f "$file" ]]; then
extension="${file##*.}"
if [[ " ${ALLOWED_EXTENSIONS[@]} " =~ " ${extension} " ]]; then
process_file "$file"
else
echo "Skipping '$file': Not a valid .${extension} file."
fi
else
echo "Skipping '$file': File does not exist."
fi
done
done
This script is using the two aforementioned tools and some Perl regular expression magic to apply the modifications. Feel free to tweak it as you like, your .icc/.icm profiles might look a bit different, but the process is essentially the same. Remember that you need to make it executable by entering
chmod ug+x icccomment.sh
in a terminal prompt, assuming you called the file icccomment.sh
like I did.
Some final words about Darktable automatization:
To properly use Nikon profiles extracted from Capture NX-D, Capture NX 2 or ViewNX-i, you need to activate the “unbreak input profile” preset, set it to mode “gamma”, linear to a fairly low value such as around 0.02 and gamma to about 0.45. Compare back and forth with the embedded EXIF thumbnail in the .nef file e. g. with XnView MP
to get as close to a match as possible.
You would then want to create an autoload preset via Darktable/Global Preferences/Presets/unbreak input profile with a proper model/maker filter and the “ auto apply this filter to matching images” checkbox checked. Or just import the attached
Nikon D300.dtpreset (1.0 KB).
While you are at it, pay attention to other auto load presets that might interfere with your image, especially Darktable/Global Preferences/Presets/base curve, which could have “nikon like” or “nikon like alternate” on autoload depending on the processing pipeline activated in Darktable/Global Preferences/processing. I put auto-apply pixel workflow defaults on “none” and auto-apply chromatic adaptation defaults on “legacy” but YMMV.
One final step is to get rid of the “standard color matrix” input profile which is the default (but poor) choice for Nikon NEF images.
You guessed it, this requires yet another auto-load preset, “input color profile” this time. There select an appropriate input profile from the drop down (which now takes into account the .icm files copied to /usr/share/darktable/color/in
earlier and - thanks to our comment tweaking - with an easy to read description. I typically start with the Nikon neutral profile which requires linear Rec.2020 RGB as a working profile and gamut clipping off.
I have exported it for your convenience as well:
Nikon D300.dtpreset (1.0 KB)
, but make sure to adjust the input profile name, because Darktable might not find it otherwise.
That was quite a long writeup, please apologize. Also apologize, that the board software does not allow more than 4 hyperlinks for new users, so I had to cloak things here and there a bit but hope, you’ll find out nevertheless. And we sure learned something today - sure I did. In any case: Have a nice day and even more fun with proper Nikon profiles in Darktable.