print on mac os: fix double color management when using printer ICC profiles#20721
Conversation
How would it reapply the ICC profile? Is it because the profile is already set on the CUPS printer (global to the OS)? |
|
What it looks like I'm seeing is that on Linux CUPS,
Once the generated PDF is sent to CUPS, I believe this is the code path that would result in an additional icc application: When
|
0687f49 to
5e1f2b3
Compare
Those people are affected, but anyway the setting is wrong. If colord has a profile configured then it is wrong to set the same profile in the print dialog. So I agree with you on this part, this is a wrong user's setting. I need to understand the other cases... It has been a long time since I have worked on this part. More later. |
When a printer ICC profile is selected, darktable applies the color
conversion via LittleCMS but fails to communicate this to the
downstream CUPS pipeline, causing incorrect color output.
This commit fixes the issue on both Linux and macOS:
1. The printer.profile field on the print info struct was never
populated from the user's profile selection, so the cm-calibration
CUPS option was always set to "false". Fixed by propagating the
profile selection into printer.profile before calling dt_print_file().
2. On Linux, cm-calibration=true tells pdftoraster to skip its own
color management, preventing double conversion.
3. On macOS, cgpdftoraster ignores cm-calibration entirely. Two
additional fixes are needed:
- Embed the ICC profile in the PDF so cgpdftoraster knows the
pixel data is not sRGB (without this, it misinterprets the
already-converted data).
- Send AP_ColorMatchingMode=AP_ApplicationColorMatching (both
dot and underscore variants) to tell cgpdftoraster and the
printer driver that the application already handled color
matching.
Note: on Linux, the ICC profile must NOT be embedded in the PDF —
Poppler (inside pdftoraster) would see the ICCBased color space and
convert the data back to sRGB, undoing the LittleCMS conversion.
Tested on macOS with Canon Pixma Pro-100 against Capture One output.
5e1f2b3 to
51983a4
Compare
|
Okay, I have reworked this PR and printed about 30 test prints to see if i can figure out what's happening, as well as done some decompilation of apple's What I've found is that cgpdftoraster will skip all color management if Doing some experimentation w/ LittleCMS, I determined that converting pixel data, but not embedding the icc profile leads to preview images that look identical to my prints that are too magenta. So somewhere along the line, probably inside core graphics, something is interpreting DeviceRGB pixels as either sRGB, or some internal mac color space, I'm not really sure which, and then when that canvas is rasterized, the pixels are mismatched from their color space. So I believe that embedding the ICC profile is the correct thing to do on mac, and I've gated that behind the Based on auditing the code for oss/linux cups, I'm not really sure if it's correct to embed the ICC profile, but I suspect not, based on pdftoraster wanting to convert back to srgb. Presumably, to let cups/ppd deal with colors itself. Incidentally, when I started wondering if lcms and color-sync were just producing different outputs, I discovered that converting an image via lcms and not embedding the icc profile ends up with an image that when previewed, looks exactly like my magenta-shifted prints. Just embedding the icc into one of those already converted images ends up fixing the preview to look correct and match the capture one print and the printed output of this pr. |
TurboGit
left a comment
There was a problem hiding this comment.
Looks good, please just need a release notes entry. TIA.
When a printer ICC profile is selected, darktable applies the color conversion via LittleCMS but then fails to communicate this to the downstream CUPS pipeline, causing double color management:
The printer.profile field on the print info struct was never populated from the user's profile selection, so the cm-calibration CUPS option was always set to "false". This meant the CUPS pdftoraster filter (Linux) would re-apply color management to already-converted data. Fixed by propagating the profile selection into printer.profile before calling dt_print_file(). For users using TurboPrint for ICC profiles, this remains 'false' if no ICC profile is selected. @TurboGit - if you're still active, please chime in if this doesn't match your understanding. However, I don't use Darktable on Linux at the moment, so I don't have great ways of testing this. I am not totally sure of this fix, but I believe it is directionally correct towards telling CUPS that the embedded pixel data has already been converted.
On macOS, Apple's cgpdftoraster filter ignores cm-calibration entirely. It reads the PDF color space metadata and assumes DeviceRGB means sRGB, then converts via ColorSync. The printer ICC profile was never embedded in the generated PDF (code existed but was commented out with a "???" note since 2015). Fixed by embedding the profile via dt_pdf_add_icc() so cgpdftoraster recognizes the actual color space.
Test Prints (macos)
I have been printing for a while with CaptureOne and I believe the results are good enough to benchmark against, and with this patch, the Darktable prints now match CaptureOne.