mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-08-20 04:31:25 +08:00
Tests - not correct - to remove
This commit is contained in:
parent
2c5cb69a64
commit
af7aefb096
@ -17,13 +17,13 @@
|
||||
Directory.CreateDirectory(OutputFolder);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void IccXyzTest()
|
||||
{
|
||||
var path = IntegrationHelpers.GetSpecificTestDocumentPath("xyztest.pdf");
|
||||
using (var document = PdfDocument.Open(path))
|
||||
{
|
||||
// page 1
|
||||
var page1 = document.GetPage(1);
|
||||
var paths = page1.ExperimentalAccess.Paths
|
||||
.OrderBy(p => p.GetBoundingRectangle().Value.Centroid.X)
|
||||
@ -80,6 +80,52 @@
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IccLabProfile8bitLUT()
|
||||
{
|
||||
var path = IntegrationHelpers.GetSpecificTestDocumentPath("icc-lab-8bit.pdf");
|
||||
using (var document = PdfDocument.Open(path))
|
||||
{
|
||||
var page1 = document.GetPage(1);
|
||||
var paths = page1.ExperimentalAccess.Paths
|
||||
.OrderBy(p => p.GetBoundingRectangle().Value.Centroid.X)
|
||||
.ThenBy(p => p.GetBoundingRectangle().Value.Centroid.Y)
|
||||
.ToArray();
|
||||
|
||||
var grouped = page1.ExperimentalAccess.Paths
|
||||
.GroupBy(p => p.GetBoundingRectangle().Value.Centroid.X)
|
||||
.ToDictionary(kvp => kvp.Key, kvp => kvp);
|
||||
|
||||
/*
|
||||
* If all the profiles were rendered correctly, for the 3 "Lab" files we'd expect to see:
|
||||
* stripe 1: lab(0 0 0) - black
|
||||
* stripe 2: lab(100% 0 0) - white
|
||||
* stripe 3: lab(75% 0 50) - mustard (#CEB759)
|
||||
* stripe 4: lab(75% 50 0) - pink (#FF92BB)
|
||||
*/
|
||||
|
||||
var black = grouped[30].Single().FillColor;
|
||||
var white = grouped[60].Single().FillColor;
|
||||
var mustard = grouped[90].Single().FillColor; // rgb(206,183,89)
|
||||
var pink = grouped[120].Single().FillColor; // rgb(255,146,187)
|
||||
|
||||
AssertColor(206, 183, 89, mustard);
|
||||
AssertColor(255, 146, 187, pink);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssertColor(byte r, byte g, byte b, IColor color)
|
||||
{
|
||||
var rgb = color.ToRGBValues();
|
||||
var rAct = ConvertToByte(rgb.r);
|
||||
var gAct = ConvertToByte(rgb.g);
|
||||
var bAct = ConvertToByte(rgb.b);
|
||||
|
||||
Assert.Equal(r, rAct);
|
||||
Assert.Equal(g, gAct);
|
||||
Assert.Equal(b, bAct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IccLabProfileMatrixv4()
|
||||
{
|
||||
@ -422,7 +468,7 @@
|
||||
|
||||
private static byte ConvertToByte(decimal componentValue)
|
||||
{
|
||||
var rounded = Math.Round(componentValue * 255, MidpointRounding.AwayFromZero);
|
||||
var rounded = Math.Round(componentValue * 255m, MidpointRounding.AwayFromZero);
|
||||
return (byte)rounded;
|
||||
}
|
||||
}
|
||||
|
@ -1161,7 +1161,7 @@
|
||||
return transformed;
|
||||
}
|
||||
|
||||
private static double g(double x)
|
||||
internal static double g(double x)
|
||||
{
|
||||
if (x > 6.0 / 29.0)
|
||||
{
|
||||
@ -1355,7 +1355,7 @@
|
||||
return new double[] { 0, 0, 0 }; // Black RGB
|
||||
}
|
||||
|
||||
if (Profile.TryProcess(values, out double[] xyz) && xyz.Length == 3)
|
||||
if (Profile.TryProcessToPcs(values, null, out double[] xyz) && xyz.Length == 3) // No rendering intent for now
|
||||
{
|
||||
double x = xyz[0];
|
||||
double y = xyz[1];
|
||||
@ -1395,7 +1395,44 @@
|
||||
return RGBColor.Black;
|
||||
}
|
||||
|
||||
if (Profile.TryProcess(values, out double[] xyz) && xyz.Length == 3)
|
||||
if (values.Any(x => x > 1.0))
|
||||
{
|
||||
//values[0] /= 100.0;
|
||||
//values[1] = (values[1] + 127.0) / 255.0;
|
||||
//values[2] = (values[2] + 127.0) / 255.0;
|
||||
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
values[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (Profile.Header.ColourSpace == IccColourSpaceType.CIELABorPCSLAB)
|
||||
{
|
||||
//values[0] /= 100.0;
|
||||
//values[1] = (values[1] + 127.0) / 256.0;
|
||||
//values[2] = (values[2] + 127.0) / 256.0;
|
||||
|
||||
// Component Ranges: L*: [0 100]; a* and b*: [−128 127]
|
||||
//double b = PdfFunction.ClipToRange(values[1], -128.0, 127.0);
|
||||
//double c = PdfFunction.ClipToRange(values[2], -128.0, 127.0);
|
||||
|
||||
//double M = (values[0] + 16.0) / 116.0;
|
||||
//double L = M + (b / 500.0);
|
||||
//double N = M - (c / 200.0);
|
||||
|
||||
//IccXyz referenceWhite = Profile.Header.nCIEXYZ;
|
||||
|
||||
//values[0] = LabColorSpaceDetails.g(L) * referenceWhite.X; // X
|
||||
//values[1] = LabColorSpaceDetails.g(M) * referenceWhite.Y; // Y
|
||||
//values[2] = LabColorSpaceDetails.g(N) * referenceWhite.Z; // Z
|
||||
|
||||
//var labColor = labColorSpaceDetails.GetColor(values[0], values[1], values[2]);
|
||||
//values[0] =
|
||||
}
|
||||
|
||||
|
||||
if (Profile.TryProcessToPcs(values, null, out double[] xyz) && xyz.Length == 3) // No rendering intent for now
|
||||
{
|
||||
double x = xyz[0];
|
||||
double y = xyz[1];
|
||||
@ -1408,7 +1445,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
return labColorSpaceDetails.GetColor(x, y, z);
|
||||
return labColorSpaceDetails.GetColor(x * 100.0, y * 255.0 - 127.0, z * 255.0 - 127.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1437,7 +1474,8 @@
|
||||
int outputSize = (int)(decoded.Count * outputCount / (double)NumberOfColorComponents);
|
||||
var transformed = new byte[outputSize];
|
||||
|
||||
Parallel.For(0, decoded.Count / NumberOfColorComponents, i =>
|
||||
//Parallel.For(0, decoded.Count / NumberOfColorComponents, i =>
|
||||
for (int i = 0; i < decoded.Count / NumberOfColorComponents; i++)
|
||||
{
|
||||
double[] comps = new double[NumberOfColorComponents];
|
||||
for (int n = 0; n < NumberOfColorComponents; n++)
|
||||
@ -1450,7 +1488,8 @@
|
||||
{
|
||||
transformed[i * outputCount + c] = ConvertToByte(colors[c]);
|
||||
}
|
||||
});
|
||||
}
|
||||
//);
|
||||
return transformed;
|
||||
}
|
||||
|
||||
@ -1512,4 +1551,4 @@
|
||||
throw new InvalidOperationException("UnsupportedColorSpaceDetails");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,13 @@ namespace IccProfileNet
|
||||
index += w;
|
||||
}
|
||||
|
||||
return clut[(int)index];
|
||||
int indexInt = (int)index;
|
||||
if (indexInt > clut.Length - 1)
|
||||
{
|
||||
//indexInt = clut.Length - 1;
|
||||
}
|
||||
|
||||
return clut[indexInt];
|
||||
}
|
||||
|
||||
internal static double[] Lookup(double[] input, double[][] clut, int clutGridPoints)
|
||||
@ -40,10 +46,17 @@ namespace IccProfileNet
|
||||
double index = 0;
|
||||
for (int i = 0; i < input.Length; i++)
|
||||
{
|
||||
index += input[i] * Math.Pow(clutGridPoints, input.Length - i);
|
||||
double pow = Math.Pow(clutGridPoints, input.Length - i);
|
||||
index += input[i] * pow;
|
||||
}
|
||||
|
||||
return clut[(int)index];
|
||||
int indexInt = (int)index;
|
||||
if (indexInt > clut.Length - 1)
|
||||
{
|
||||
//indexInt = indexInt % clut.Length;
|
||||
}
|
||||
|
||||
return clut[indexInt];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -144,209 +144,236 @@ namespace IccProfileNet
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryProcessOld(double[] input, out double[] output)
|
||||
private bool TryProcessGrayTRC(double[] input, out double[] output)
|
||||
{
|
||||
throw new NotImplementedException($"Unsuported ICC profile v{Header.VersionMajor}");
|
||||
// 8.3.4 Monochrome Input profiles
|
||||
// 8.4.4 Monochrome Display profiles
|
||||
// 8.5.3 Monochrome Output profiles
|
||||
if (Tags.TryGetValue(IccTags.GrayTRCTag, out var kTrcTag) && kTrcTag is IccBaseCurveType kTrc)
|
||||
{
|
||||
double v = kTrc.Process(input.Single());
|
||||
output = new double[] { v, v, v };
|
||||
return true;
|
||||
}
|
||||
|
||||
//switch (Header.VersionMajor)
|
||||
//{
|
||||
// case 2:
|
||||
// return TryProcess2(input, out output);
|
||||
|
||||
// case 4:
|
||||
// return TryProcess4(input, out output);
|
||||
|
||||
// default:
|
||||
// throw new NotImplementedException($"Unsuported ICC profile v{Header.VersionMajor}");
|
||||
//}
|
||||
output = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryProcess(double[] input, out double[] output)
|
||||
private bool TryProcessTRCMatrix(double[] input, out double[] output)
|
||||
{
|
||||
try
|
||||
// 8.3.3 Three-component matrix-based Input profiles
|
||||
// 8.4.3 Three-component matrix-based Display profiles
|
||||
// See p197 of Wiley book
|
||||
if (Tags.TryGetValue(IccTags.RedMatrixColumnTag, out var rmcTag) && rmcTag is IccXyzType rmc &&
|
||||
Tags.TryGetValue(IccTags.GreenMatrixColumnTag, out var gmcTag) && gmcTag is IccXyzType gmc &&
|
||||
Tags.TryGetValue(IccTags.BlueMatrixColumnTag, out var bmcTag) && bmcTag is IccXyzType bmc &&
|
||||
Tags.TryGetValue(IccTags.RedTRCTag, out var rTrcTag) && rTrcTag is IccBaseCurveType rTrc &&
|
||||
Tags.TryGetValue(IccTags.GreenTRCTag, out var gTrcTag) && gTrcTag is IccBaseCurveType gTrc &&
|
||||
Tags.TryGetValue(IccTags.BlueTRCTag, out var bTrcTag) && bTrcTag is IccBaseCurveType bTrc)
|
||||
{
|
||||
// Optional
|
||||
// Tags.TryGetValue(IccTags.ChromaticAdaptationTag, out var caTag) && caTag is IccS15Fixed16ArrayType ca
|
||||
|
||||
double channel1 = input[0];
|
||||
double channel2 = input[1];
|
||||
double channel3 = input[2];
|
||||
|
||||
double lR = rTrc.Process(channel1);
|
||||
double lG = gTrc.Process(channel2);
|
||||
double lB = bTrc.Process(channel3);
|
||||
|
||||
double cX = (rmc.Xyz.X * lR) + (gmc.Xyz.X * lG) + (bmc.Xyz.X * lB);
|
||||
double cY = (rmc.Xyz.Y * lR) + (gmc.Xyz.Y * lG) + (bmc.Xyz.Y * lB);
|
||||
double cZ = (rmc.Xyz.Z * lR) + (gmc.Xyz.Z * lG) + (bmc.Xyz.Z * lB);
|
||||
|
||||
output = new double[] { cX, cY, cZ };
|
||||
return true;
|
||||
}
|
||||
|
||||
output = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process from Device space to PCS.
|
||||
/// <para>
|
||||
/// A to B.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public bool TryProcessToPcs(double[] input, IccRenderingIntent? renderingIntent, out double[] output)
|
||||
{
|
||||
// See Table 25 — Profile type/profile tag and defined rendering intents
|
||||
|
||||
//try
|
||||
//{
|
||||
if (TryProcessGrayTRC(input, out output))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TryProcessTRCMatrix(input, out output))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (renderingIntent == null)
|
||||
{
|
||||
// use profile rendering intent
|
||||
renderingIntent = Header.RenderingIntent;
|
||||
}
|
||||
|
||||
switch (Header.ProfileClass)
|
||||
{
|
||||
case IccProfileClass.Input:
|
||||
{
|
||||
// 8.3 Input profiles
|
||||
// 8.3.2 N-component LUT-based Input profiles
|
||||
if (Tags.TryGetValue(IccTags.AToB0Tag, out var lutAB0TagI) &&
|
||||
lutAB0TagI is IccLutABType lutAb0I)
|
||||
{
|
||||
//output = lutAB.Process(input, Header);
|
||||
//return true;
|
||||
}
|
||||
|
||||
// 8.3.3 Three-component matrix-based Input profiles
|
||||
if (Tags.TryGetValue(IccTags.RedMatrixColumnTag, out var rmcTagI) &&
|
||||
Tags.TryGetValue(IccTags.RedTRCTag, out var rTrcTagI))
|
||||
{
|
||||
// Check other taggs
|
||||
}
|
||||
|
||||
// 8.3.4 Monochrome Input profiles
|
||||
if (Tags.TryGetValue(IccTags.GrayTRCTag, out var kTrcTag) && kTrcTag is IccBaseCurveType kTrc)
|
||||
{
|
||||
double v = kTrc.Process(input.Single());
|
||||
output = new double[] { v, v, v };
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IccProfileClass.Display:
|
||||
{
|
||||
// 8.4 Display profiles
|
||||
// 8.4.2 N-Component LUT-based Display profilesS
|
||||
if (Tags.TryGetValue(IccTags.AToB0Tag, out var lutAB0TagD) && lutAB0TagD is IccLutABType lutAb0D &&
|
||||
Tags.TryGetValue(IccTags.BToA0Tag, out var lutBA0TagD) && lutBA0TagD is IccLutABType lutBa0D)
|
||||
{
|
||||
output = lutBa0D.Process(input, Header);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 8.4.3 Three-component matrix-based Display profiles
|
||||
// See p197 of Wiley book
|
||||
if (Tags.TryGetValue(IccTags.RedMatrixColumnTag, out var rmcTag) && rmcTag is IccXyzType rmc &&
|
||||
Tags.TryGetValue(IccTags.GreenMatrixColumnTag, out var gmcTag) && gmcTag is IccXyzType gmc &&
|
||||
Tags.TryGetValue(IccTags.BlueMatrixColumnTag, out var bmcTag) && bmcTag is IccXyzType bmc &&
|
||||
|
||||
Tags.TryGetValue(IccTags.RedTRCTag, out var rTrcTag) && rTrcTag is IccBaseCurveType rTrc &&
|
||||
Tags.TryGetValue(IccTags.GreenTRCTag, out var gTrcTag) && gTrcTag is IccBaseCurveType gTrc &&
|
||||
Tags.TryGetValue(IccTags.BlueTRCTag, out var bTrcTag) && bTrcTag is IccBaseCurveType bTrc)
|
||||
{
|
||||
// Optional
|
||||
// Tags.TryGetValue(IccTags.ChromaticAdaptationTag, out var caTag) && caTag is IccS15Fixed16ArrayType ca
|
||||
|
||||
double channel1 = input[0];
|
||||
double channel2 = input[1];
|
||||
double channel3 = input[2];
|
||||
|
||||
double lR = rTrc.Process(channel1);
|
||||
double lG = gTrc.Process(channel2);
|
||||
double lB = bTrc.Process(channel3);
|
||||
|
||||
double cX = rmc.Xyz.X * lR + gmc.Xyz.X * lG + bmc.Xyz.X * lB;
|
||||
double cY = rmc.Xyz.Y * lR + gmc.Xyz.Y * lG + bmc.Xyz.Y * lB;
|
||||
double cZ = rmc.Xyz.Z * lR + gmc.Xyz.Z * lG + bmc.Xyz.Z * lB;
|
||||
|
||||
output = new double[] { cX, cY, cZ };
|
||||
return true;
|
||||
}
|
||||
|
||||
// 8.4.4 Monochrome Display profiles
|
||||
if (Tags.TryGetValue(IccTags.GrayTRCTag, out var kTrcTag) && kTrcTag is IccBaseCurveType kTrc)
|
||||
{
|
||||
double v = kTrc.Process(input.Single());
|
||||
output = new double[] { v, v, v };
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IccProfileClass.Output:
|
||||
{
|
||||
// 8.5.2 N-component LUT-based Output profiles
|
||||
if (Tags.TryGetValue(IccTags.AToB0Tag, out var lutAB0Tag) && lutAB0Tag is IIccClutType lutAb0 &&
|
||||
Tags.TryGetValue(IccTags.AToB1Tag, out var lutAB1Tag) && lutAB1Tag is IIccClutType lutAb1 &&
|
||||
Tags.TryGetValue(IccTags.AToB2Tag, out var lutAB2Tag) && lutAB2Tag is IIccClutType lutAb2 &&
|
||||
|
||||
|
||||
Tags.TryGetValue(IccTags.BToA0Tag, out var lutBA0Tag) && lutBA0Tag is IIccClutType lutBa0 &&
|
||||
Tags.TryGetValue(IccTags.BToA1Tag, out var lutBA1Tag) && lutBA1Tag is IIccClutType lutBa1 &&
|
||||
Tags.TryGetValue(IccTags.BToA2Tag, out var lutBA2Tag) && lutBA2Tag is IIccClutType lutBa2 &&
|
||||
|
||||
Tags.TryGetValue(IccTags.GamutTag, out var gamutTag))
|
||||
{
|
||||
// Optional??
|
||||
// Tags.TryGetValue(IccTags.ColorantTableTag, out var colorantTableTag)
|
||||
switch (Header.RenderingIntent)
|
||||
{
|
||||
case IccRenderingIntent.Perceptual:
|
||||
output = lutAb0.Process(input, Header);
|
||||
return true;
|
||||
|
||||
case IccRenderingIntent.MediaRelativeColorimetric:
|
||||
output = lutAb1.Process(input, Header);
|
||||
return true;
|
||||
|
||||
case IccRenderingIntent.Saturation:
|
||||
output = lutAb2.Process(input, Header);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 8.5.3 Monochrome Output profiles
|
||||
if (Tags.TryGetValue(IccTags.GrayTRCTag, out var tag))
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IccProfileClass.DeviceLink:
|
||||
{
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
|
||||
case IccProfileClass.ColorSpace:
|
||||
{
|
||||
// 8.7 ColorSpace profile
|
||||
if (Tags.TryGetValue(IccTags.AToB0Tag, out var lutAB0Tag) &&
|
||||
Tags.TryGetValue(IccTags.BToA0Tag, out var lutBA0Tag))
|
||||
// 8.3.2 N-component LUT-based Input profiles
|
||||
// 8.4.2 N-Component LUT-based Display profiles
|
||||
// 8.5.2 N-component LUT-based Output profiles
|
||||
|
||||
if (renderingIntent == IccRenderingIntent.Perceptual && Tags.TryGetValue(IccTags.AToB0Tag, out var lutAB0Tag)
|
||||
&& lutAB0Tag is IIccClutType lutAb0)
|
||||
{
|
||||
// TODO - check
|
||||
if (lutAB0Tag is IccLutABType lutAb0)
|
||||
{
|
||||
output = lutAb0.Process(input, Header);
|
||||
return true;
|
||||
}
|
||||
else if (lutAB0Tag is IccBaseLutType lutAb0bis)
|
||||
{
|
||||
output = lutAb0bis.Process(input, Header);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("");
|
||||
}
|
||||
output = lutAb0.Process(input, Header);
|
||||
return true;
|
||||
}
|
||||
else if (renderingIntent == IccRenderingIntent.MediaRelativeColorimetric && Tags.TryGetValue(IccTags.AToB1Tag, out var lutAB1Tag)
|
||||
&& lutAB1Tag is IIccClutType lutAb1)
|
||||
{
|
||||
output = lutAb1.Process(input, Header);
|
||||
return true;
|
||||
}
|
||||
else if (renderingIntent == IccRenderingIntent.Saturation && Tags.TryGetValue(IccTags.AToB2Tag, out var lutAB2Tag)
|
||||
&& lutAB2Tag is IIccClutType lutAb2)
|
||||
{
|
||||
output = lutAb2.Process(input, Header);
|
||||
return true;
|
||||
}
|
||||
else if (Tags.TryGetValue(IccTags.AToB0Tag, out var lutAB0TagDefault) && lutAB0TagDefault is IIccClutType lutAb0Default)
|
||||
{
|
||||
output = lutAb0Default.Process(input, Header);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IccProfileClass.Abstract:
|
||||
case IccProfileClass.DeviceLink:
|
||||
case IccProfileClass.NamedColor: // undefined actually
|
||||
{
|
||||
if (Tags.TryGetValue(IccTags.AToB0Tag, out var lutAB0Tag))
|
||||
// TODO - use IIccClutType instead?
|
||||
if (Tags.TryGetValue(IccTags.AToB0Tag, out var lutAB0Tag) && lutAB0Tag is IIccClutType lutAb0)
|
||||
{
|
||||
// TODO - check
|
||||
if (lutAB0Tag is IccLutABType lutAb0)
|
||||
{
|
||||
output = lutAb0.Process(input, Header);
|
||||
return true;
|
||||
}
|
||||
else if (lutAB0Tag is IccBaseLutType lutAb0bis)
|
||||
{
|
||||
output = lutAb0bis.Process(input, Header);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("");
|
||||
}
|
||||
output = lutAb0.Process(input, Header);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IccProfileClass.NamedColor:
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("TODO");
|
||||
}
|
||||
//}
|
||||
//catch (Exception ex)
|
||||
//{
|
||||
// // Ignore
|
||||
// System.Diagnostics.Debug.WriteLine(ex);
|
||||
// output = null;
|
||||
// return false;
|
||||
//}
|
||||
|
||||
output = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process from PCS to Device space.
|
||||
/// <para>
|
||||
/// B to A.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public bool TryProcessFromPcs(double[] input, IccRenderingIntent? renderingIntent, out double[] output)
|
||||
{
|
||||
// TODO
|
||||
|
||||
// See Table 25 — Profile type/profile tag and defined rendering intents
|
||||
|
||||
try
|
||||
{
|
||||
if (TryProcessGrayTRC(input, out output)) // TODO - Need inversion
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TryProcessTRCMatrix(input, out output)) // TODO - Need inversion
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (renderingIntent == null)
|
||||
{
|
||||
// use profile rendering intent
|
||||
renderingIntent = Header.RenderingIntent;
|
||||
}
|
||||
|
||||
switch (Header.ProfileClass)
|
||||
{
|
||||
case IccProfileClass.Input:
|
||||
case IccProfileClass.Display:
|
||||
case IccProfileClass.Output:
|
||||
case IccProfileClass.ColorSpace:
|
||||
{
|
||||
// TODO
|
||||
// 8.3.2 N-component LUT-based Input profiles
|
||||
// 8.4.2 N-Component LUT-based Display profiles
|
||||
// 8.5.2 N-component LUT-based Output profiles
|
||||
if (Tags.TryGetValue(IccTags.BToA0Tag, out var lutBA0Tag) && lutBA0Tag is IIccClutType lutBa0 &&
|
||||
Tags.TryGetValue(IccTags.BToA1Tag, out var lutBA1Tag) && lutBA1Tag is IIccClutType lutBa1 &&
|
||||
Tags.TryGetValue(IccTags.BToA2Tag, out var lutBA2Tag) && lutBA2Tag is IIccClutType lutBa2)
|
||||
{
|
||||
// Optional??
|
||||
// Tags.TryGetValue(IccTags.GamutTag, out var gamutTag)
|
||||
// Tags.TryGetValue(IccTags.ColorantTableTag, out var colorantTableTag)
|
||||
|
||||
switch (renderingIntent)
|
||||
{
|
||||
case IccRenderingIntent.Perceptual:
|
||||
output = lutBa0.Process(input, Header);
|
||||
return true;
|
||||
|
||||
case IccRenderingIntent.MediaRelativeColorimetric:
|
||||
output = lutBa1.Process(input, Header);
|
||||
return true;
|
||||
|
||||
case IccRenderingIntent.Saturation:
|
||||
output = lutBa2.Process(input, Header);
|
||||
return true;
|
||||
|
||||
default:
|
||||
output = lutBa0.Process(input, Header);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IccProfileClass.Abstract:
|
||||
case IccProfileClass.DeviceLink:
|
||||
case IccProfileClass.NamedColor: // undefined actually
|
||||
{
|
||||
if (Tags.TryGetValue(IccTags.BToA0Tag, out var lutBA0Tag) && lutBA0Tag is IccLutABType lutBa0)
|
||||
{
|
||||
output = lutBa0.Process(input, Header);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
throw new ArgumentOutOfRangeException("TODO");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
@ -366,4 +393,4 @@ namespace IccProfileNet
|
||||
return $"ICC Profile v{Header}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user