A while ago, I've performed some related experiments, trying to get how color management works in Ghostscript 9.27 for pdf output. This gist aims to provide some reproducible examples of gs behaviour. Related to this SO question.
The example input used here is a simple pdf (no built-in profiles), that contains:
- Page 1:
- Column1 is RGB image (DeviceRGB = no built-in profile, no colorimetrically defined colorspace)
- Column2 is a set of a table cells filled with the same RGB colors
- Column3 is a set of a table cells filled with somewhat-close CMYK colors (converted as sRGB->RSWOP)
- Page 2
- all the same
- small transparent tikz pic
Notes:
- Its source tex code is attached (same in overleaf).
- Built with XeLaTeX from TexLive 2018.
- The arrow shows the point, where I click to make
Output Preview -> Object Inspector
show something.
For these experiments, I also use (included in this repo as well):
- The cmyk_des_renderintent.icc
profile, quite useful for debugging. As documented in "Ghostscript 9.21 Color Management",
it is designed such that different intents output different colors:
- the "Perceptual" rendering intent (0) outputs cyan only,
- the "RelativeColorimetric" intent (1) outputs magenta only
- and "Saturation" intent (2) outputs yellow only.
- gs/lib/PDFX_def.ps
from the Ghostscript repo, modified to utilize
cmyk_des_renderintent.icc
. A prefix file for creating PDF/X-3.
At least two things that might be called "embedded profile":
- whole-file "Output intent profile" (used in PDF/X-3)
- object-specific ICC based colorspace, defined via a profile (e.g. in embedded sRGB image)
Exp | output | PDF/X-3 | sColorConversionStrategy | dProcessColorModel | sOutputICCProfile |
---|---|---|---|---|---|
1 | Y | UseDeviceIndependentColor | DeviceCMYK | cmyk_des_renderintent.icc | |
2 | Y | CMYK | DeviceCMYK | cmyk_des_renderintent.icc | |
3 | N | CMYK | DeviceCMYK | cmyk_des_renderintent.icc | |
3t | tiff | N | CMYK | DeviceCMYK | cmyk_des_renderintent.icc |
4 | N | UseDeviceIndependentColor | <none> | <none> | |
5 | N | UseDeviceIndependentColor | DeviceCMYK | cmyk_des_renderintent.icc |
Ghostscript (9.12-9.27, not sure about earlier) supports PDF/X-3 output. As a part of it, there is a possibility to embed an "output intent" icc profile.
Let's start from the following (same in conv_v1.bat
):
gswin64c -dPDFX -dBATCH -dNOPAUSE -dHaveTransparency=false -r20 -dProcessColorModel=/DeviceCMYK -sColorConversionStrategy=UseDeviceIndependentColor -sDefaultRGBProfile="default_rgb.icc" -sOutputICCProfile="cmyk_des_renderintent.icc" -dRenderIntent=1 -dDefaultRenderingIntent=/Perceptual -sDEVICE=pdfwrite -sOutputFile=colorbar_v1.pdf PDFX_IntCmyk.ps Colorbar.pdf
Here's how the resulting "colorbar_v1.pdf" (attached) looks like in Foxit reader 9.5 (it ignores output intent):
Here's how the same file looks like in Adobe Acrobat DC (it takes output intent into account):
The same file looks different in two different viewers because the "Output Intent" icc profile is applied by the viewer, during pdf rendering. The output intent profile is also visible in Adobe Preflight:
Few more details about what's actually happening here:
gswin64c
is Windows CLI-only version of the gs. Use justgs
on linux, the rest is the same.-dHaveTransparency=false
makes sure that the 2nd page would get rasterized (due to the presence of a tikz pic with transparency)-r20
makes sure rasterization would be clearly visible (due to just 20dpi)-sOutputICCProfile="cmyk_des_renderintent.icc" -dRenderIntent=1
makes rasterizer produce magenta output.- This demonstrates that some color conversion is possible, but... only where rasterization happens. (Compare with "Exp 3t" below)
- Note that
OutputICCProfile
parameter is not mentioned in current docs, since this (9.27 docs are a bit outdated). RenderIntent
is also undocumented. It only affects rasterization as well.
-dDefaultRenderingIntent=/Perceptual
puts said intent to metadata, alongside "Output Intent icc profile" (which is specified inPDFX_IntCmyk.ps
), without affecting any stored color values. This makes Acrobat draw everything in cyan.-dProcessColorModel=/DeviceCMYK
is required, but only valid choice is/DeviceCMYK
, due to-sOutputICCProfile="cmyk_des_renderintent.icc"
.
(When-sColorConversionStrategy=UseDeviceIndependentColor
,-dProcessColorModel
would control whether the second page would beICCBasedRGB
orICCBasedCMYK
, if we drop other conflicting options. This would slightly affect colors we get there.)-sDefaultRGBProfile="default_rgb.icc"
is a placeholder for possible experiments with input icc profiles (they generally work OK). Same default is set if this parameter is omitted.
The following is a naive modification of the first command, attempting to convert everything to CMYK (same in conv_v2.bat
):
gswin64c -dPDFX -dBATCH -dNOPAUSE -dHaveTransparency=false -r20 -dProcessColorModel=/DeviceCMYK -sColorConversionStrategy=CMYK -sDefaultRGBProfile="default_rgb.icc" -sOutputICCProfile="cmyk_des_renderintent.icc" -dRenderIntent=1 -dDefaultRenderingIntent=/Perceptual -sDEVICE=pdfwrite -sOutputFile=colorbar_v2.pdf PDFX_IntCmyk.ps Colorbar.pdf
This produces a very different result - now there's just some "saturation adjustment" visible in both Acrobat (more saturated) and Foxit (less saturated).
Note that dProcessColorModel
is still required here (despite of note 6), see this.
Now we know the effect of the PDFX_IntCmyk.ps
. Let's check the result without it (same in conv_v3.bat
):
gswin64c -dBATCH -dNOPAUSE -dHaveTransparency=false -r20 -dProcessColorModel=/DeviceCMYK -sColorConversionStrategy=CMYK -sDefaultRGBProfile="default_rgb.icc" -sOutputICCProfile="cmyk_des_renderintent.icc" -dRenderIntent=1 -dDefaultRenderingIntent=/Perceptual -sDEVICE=pdfwrite -sOutputFile=colorbar_v3.pdf Colorbar.pdf
Acrobat now shows the same as Foxit - now there's no "output intent" profile.
Both results now look much like the original, even the rasterized part (except that it's low-res). The sOutputICCProfile
has no effect.
Now, let's do the same for tiff
output, where -sOutputICCProfile
is honored (same in conv_v3t.bat
):
gswin64c -dBATCH -dNOPAUSE -dHaveTransparency=false -r20 -dProcessColorModel=/DeviceCMYK -sColorConversionStrategy=CMYK -sDefaultRGBProfile="default_rgb.icc" -sOutputICCProfile="cmyk_des_renderintent.icc" -dRenderIntent=1 -dDefaultRenderingIntent=/Perceptual -sDEVICE=tiff32nc -sOutputFile=colorbar_v3t.tiff Colorbar.pdf
We get two-page tiff file, with both pages in magenta:
Just for reference, let's convert to "DeviceIndependent" (ICCBased) colors, without mentioning any output profiles:
gswin64c -dBATCH -dNOPAUSE -dHaveTransparency=false -r20 -sColorConversionStrategy=UseDeviceIndependentColor -sDefaultRGBProfile="default_rgb.icc" -dRenderIntent=1 -dDefaultRenderingIntent=/Perceptual -sDEVICE=pdfwrite -sOutputFile=colorbar_v4.pdf Colorbar.pdf
Like "Exp 1", but without PDF/X-3:
gswin64c -dBATCH -dNOPAUSE -dHaveTransparency=false -r20 -dProcessColorModel=/DeviceCMYK -sColorConversionStrategy=UseDeviceIndependentColor -sDefaultRGBProfile="default_rgb.icc" -sOutputICCProfile="cmyk_des_renderintent.icc" -dRenderIntent=1 -dDefaultRenderingIntent=/Perceptual -sDEVICE=pdfwrite -sOutputFile=colorbar_v5.pdf Colorbar.pdf
Adobe Acrobat (Tools -> Print Production -> Convert Colors
), with the following set of options:
produces the following result:
Foxit:
Acrobat:
Now, let's try to not embed the profile:
This produces the following result.
Foxit:
Acrobat:
-sColorConversionStrategy=UseDeviceIndependentColor
converts your colors toICCBasedRGB
/ICCBasedCMYK
.- This makes colors "colorimetrically defined", and means that "some icc profile is embedded" (see Adobe Preflight screenshots, especially in Exp 4).
- The "how are colors converted?" and "how do I adjust parameters of this conversion?" are, in a general case, far trickier questions.
- Acrobat embeds the profile, selected by user and actually converts colors using it. Ghostscript is unable to do that.
- The "Output intent profile" works as expected.
AFAIU, it requires-sColorConversionStrategy=UseDeviceIndependentColor
. - The
-sOutputICCProfile
does not work for pdf the way it works for tiff. It is undocumented here.
(But it still affects pages being rasterized, when converting to DeviceIndependent colors. Not sure if it's a bug or a feature.) - There's no simple way to, say, avoid color clipping (by specifying intent), when converting from
DeviceRGB
toDeviceCMYK
. Acrobat, with "embed profile" unchecked, allows to produce a DeviceCMYK file, with colors converted according to the specified icc profile. Ghostscript is unable to do that.
-
gs simply ignores unknown switches.
-
icc profiles contain independent
local_value->ICC
andICC->local_value
tables. Comparecmyk_des_renderintent.icc
andcmyk_src_renderintent.icc
from this folder (e.g. with ICC Profile Inspector). -
Docs do warn, that only a small subset of color management options is supported for pdf output. You can only set default input color profile (e.g. for objects that do not have a profile), but you cannot set: output ICC profile, black generation options, etc.
-
Docs say:
DeviceRGB color values are passed unchanged. If a user needs a non trivial color adjustment, a non trivial DefaultRGB color space must be defined. Transfer functions and halftone phases are skipped.
- The 2nd sentence here is probably be related to files in gs\Resource\ColorSpace folder. This might be the clue to at least some limited color management capabilities for related color conversions. I've never tried that.
- The 1st and the 3rd sentences, probably, explain why we see no color conversions (nothing like what Acrobat produces)
- In the docs, these 3 sentences seem to be related to
-dPDFX
, but, actually, the seem to be true for all cases.