Add ICC profiles color spaces and output intent support, and add tests - #1383
Open
BobLd wants to merge 13 commits into
Open
Add ICC profiles color spaces and output intent support, and add tests#1383BobLd wants to merge 13 commits into
BobLd wants to merge 13 commits into
Conversation
BobLd
force-pushed
the
feature/icc-profile-support-5-split
branch
from
August 16, 2026 16:10
828ec44 to
42e37ec
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The code changes were made with AI assistance.
PdfPig can now support ICC profiles for colour management.
ParsingOptions.IccProfileServicenow lets a caller plug in a colour management module (like Unicolour). No ICC profile management is done in PdfPig.When one is configured,
/ICCBasedcolour spaces convert through their embedded profile instead of always deferring to the alternate. A document's output intents are parsed, exposed on the graphics state, and, when the service asks for it, applied: device colours (DeviceGray, DeviceRGB, DeviceCMYK) are converted through the output intent's profile rather than the built-in approximations. Rendering intent is now passed through every colour conversion, and images take their default/Decodearray from the colour space, which fixes Lab images decoding near-black.Without an ICC profile service configured, behaviour is unchanged.
Breaking changes
1.
CurrentGraphicsStatecolour setters removedCurrentStrokingColorandCurrentNonStrokingColorare now[Obsolete(..., error: true)]on the setter, and throwNotSupportedExceptionif reached by an assembly compiled against an older version.Why. A colour assigned straight into the graphics state carries no colour space and no operands, so it cannot answer a later
rioperator and would silently pin itself to whatever intent happened to be in force.Getters are unchanged.
2.
BaseStreamProcessor<T>constructor gainedpageDictionaryAffects custom stream processors.
Pass the page dictionary so page-level
/OutputIntents(PDF 2.0, Table 31) are picked up; passnullif you have none, and the document catalog's intents are used instead.3.
XObjectFactory.ReadImagegainedParsingOptionsInside a
BaseStreamProcessorsubclass,ParsingOptionsis already available as a property, so the call becomes..., resourceStore, ParsingOptions).The options carry
IccProfileService, which is what lets a JPEG 2000 image decode the ICC profile embedded in its own codestream.4.
ColorSpaceDetailsByteConverter.Convert6-argument overload gainedRenderingIntent5.
IResourceStoregained four membersOnly breaking if you implement the interface yourself. Minimal opt-out implementations:
Returning
null/empty everywhere reproduces the previous behaviour exactly: ICC-based colour spaces fall back to their alternate, and no output intent is in effect.6.
InlineImageBuilderconstructor now requiresParsingOptionsThe implicit public parameterless constructor is gone, replaced by
public InlineImageBuilder(ParsingOptions options).The options are needed so an inline image's soft mask can be read through
XObjectFactory.ReadImage, which now takes them (see item 3).7.
IIccProfileServicecarries the output intent policyApplying an output intent is impossible without a service to parse its profile, so the capability and the decision to use it are the same thing and live together:
Answering
falseandnullreproduces the behaviour of a service that only parses profiles:/ICCBasedcolour spaces are colour-managed, device colours are not.Opting out entirely
Without
ParsingOptions.IccProfileServiceset, no ICC colour management happens and/ICCBasedspaces behave as before. With one set but answeringUseOutputIntentfalse,/ICCBasedspaces are colour-managed and device colours are left alone, which is the recommended default: 14.11.5 sets "no expectation" that device colours are converted to the output intent's target, and says such conversion is "undesirable" in some workflows.The only behaviour that changes for every caller regardless is the default
/Decodearray (above).