SixLabors/ImageSharp · error · ArgumentOutOfRangeException

Source PCS is not supported

Error message

Source PCS {sourceParams.PcsType} is not supported

What it means

GetTargetPcsWithPerceptualAdjustment (single-value path) decodes the source PCS value but found a source PCS type other than CieLab or CieXYZ. Perceptual-intent conversion with v2 black-point compensation only supports those two PCS encodings, so an unexpected signature triggers ArgumentOutOfRangeException.

Solutions

  1. Verify the source profile's PCS signature is 'XYZ ' or 'Lab ' and replace the profile if not.
  2. Regenerate the profile with a compliant tool.
  3. Use a different rendering intent that avoids the perceptual adjustment path if the profiles allow it.

Example fix

// before
var options = new ColorConversionOptions
{
    SourceIccProfile = corruptProfile, // PCS signature invalid
    TargetIccProfile = target,
    RenderingIntent = RenderingIntent.Perceptual
};

// after
var options = new ColorConversionOptions
{
    SourceIccProfile = IccProfile.Parse(File.ReadAllBytes("valid.icc")),
    TargetIccProfile = target,
    RenderingIntent = RenderingIntent.Perceptual
};
Defensive patterns

Strategy: validation

Validate before calling

bool supported = sourceProfile.Header.ColorSpace is IccColorSpaceType.CieXyz or IccColorSpaceType.CieLab;
if (!supported) throw new InvalidOperationException("Unsupported source PCS for perceptual intent.");

Type guard

bool HasKnownSourcePcs(ConversionParams p) => p.PcsType is IccColorSpaceType.CieXyz or IccColorSpaceType.CieLab;

Try / catch

try { return converter.ConvertUsingIccProfile<TFrom, TTo>(in color); }
catch (ArgumentOutOfRangeException ex) when (ex.Message.Contains("Source PCS"))
{ /* replace profile or use different intent */ }

Prevention

When it happens

Trigger: ConvertUsingIccProfile with rendering intent Perceptual where the source profile header declares a PCS color space other than XYZ or CIELab.

Common situations: Profiles with damaged headers; custom/proprietary profiles reusing PCS slots; misparsed profile bytes shifting the PCS signature field.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13). Data as JSON: /api/errors/ee5ebd32320459d7. Report an issue: GitHub.

Appendix: source

Thrown at src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsIcc.cs:384

        ColorProfileConverter pcsConverter)
    {
        // all conversions are funneled through XYZ in case PCS adjustments need to be made
        CieXyz xyz;

        switch (sourceParams.PcsType)
        {
            // 16-bit Lab encodings changed from v2 to v4, but 16-bit LUTs always use the legacy encoding regardless of version
            // so convert Lab to modern v4 encoding when returned from a 16-bit LUT
            case IccColorSpaceType.CieLab:
                sourcePcs = sourceParams.Is16BitLutEntry ? LabV2ToLab(sourcePcs) : sourcePcs;
                CieLab lab = CieLab.FromScaledVector4(sourcePcs);
                xyz = pcsConverter.Convert<CieLab, CieXyz>(in lab);
                break;
            case IccColorSpaceType.CieXyz:
                xyz = CieXyz.FromScaledVector4(sourcePcs);
                break;
            default:
                throw new ArgumentOutOfRangeException($"Source PCS {sourceParams.PcsType} is not supported");
        }

        bool oneProfileHasV2PerceptualAdjustment = sourceParams.HasV2PerceptualHandling ^ targetParams.HasV2PerceptualHandling;

        // when converting from device to PCS with v2 perceptual intent
        // the black point needs to be adjusted to v4 after converting the PCS values
        if (sourceParams.HasNoPerceptualHandling ||
            (oneProfileHasV2PerceptualAdjustment && sourceParams.HasV2PerceptualHandling))
        {
            Vector3 vector = xyz.ToVector3();

            // when using LAB PCS, negative values are clipped before PCS adjustment (in DemoIccMAX)
            if (sourceParams.PcsType == IccColorSpaceType.CieLab)
            {
                vector = Vector3.Max(vector, Vector3.Zero);
            }

            xyz = new CieXyz(AdjustPcsFromV2BlackPoint(vector));

View on GitHub (pinned to 59ce6af6fc)