private string GetTagDataString(int tagType) { try { var bytes = Directory.GetByteArray(tagType); if (bytes == null) { return(Directory.GetString(tagType)); } var reader = new ByteArrayReader(bytes); var iccTagType = (IccTagType)reader.GetInt32(0); switch (iccTagType) { case IccTagType.Text: { #if !NETSTANDARD1_3 try { return(Encoding.ASCII.GetString(bytes, 8, bytes.Length - 8 - 1)); } catch #endif { return(Encoding.UTF8.GetString(bytes, 8, bytes.Length - 8 - 1)); } } case IccTagType.Desc: { var stringLength = reader.GetInt32(8); return(Encoding.UTF8.GetString(bytes, 12, stringLength - 1)); } case IccTagType.Sig: { return(IccReader.GetStringFromUInt32(reader.GetUInt32(8))); } case IccTagType.Meas: { var observerType = reader.GetInt32(8); var x = reader.GetS15Fixed16(12); var y = reader.GetS15Fixed16(16); var z = reader.GetS15Fixed16(20); var geometryType = reader.GetInt32(24); var flare = reader.GetS15Fixed16(28); var illuminantType = reader.GetInt32(32); string observerString; switch (observerType) { case 0: observerString = "Unknown"; break; case 1: observerString = "1931 2\u00b0"; break; case 2: observerString = "1964 10\u00b0"; break; default: observerString = $"Unknown ({observerType})"; break; } string geometryString; switch (geometryType) { case 0: geometryString = "Unknown"; break; case 1: geometryString = "0/45 or 45/0"; break; case 2: geometryString = "0/d or d/0"; break; default: geometryString = $"Unknown ({observerType})"; break; } string illuminantString; switch (illuminantType) { case 0: illuminantString = "unknown"; break; case 1: illuminantString = "D50"; break; case 2: illuminantString = "D65"; break; case 3: illuminantString = "D93"; break; case 4: illuminantString = "F2"; break; case 5: illuminantString = "D55"; break; case 6: illuminantString = "A"; break; case 7: illuminantString = "Equi-Power (E)"; break; case 8: illuminantString = "F8"; break; default: illuminantString = $"Unknown ({illuminantType})"; break; } return($"{observerString} Observer, Backing ({x:0.###}, {y:0.###}, {z:0.###}), Geometry {geometryString}, Flare {(long)Math.Round(flare*100)}%, Illuminant {illuminantString}"); } case IccTagType.XyzArray: { var res = new StringBuilder(); var count = (bytes.Length - 8) / 12; for (var i = 0; i < count; i++) { var x = reader.GetS15Fixed16(8 + i * 12); var y = reader.GetS15Fixed16(8 + i * 12 + 4); var z = reader.GetS15Fixed16(8 + i * 12 + 8); if (i > 0) { res.Append(", "); } res.AppendFormat("({0:0.####}, {1:0.####}, {2:0.####})", x, y, z); } return(res.ToString()); } case IccTagType.Mluc: { var int1 = reader.GetInt32(8); var res = new StringBuilder(); res.Append(int1); for (var i = 0; i < int1; i++) { var str = IccReader.GetStringFromUInt32(reader.GetUInt32(16 + i * 12)); var len = reader.GetInt32(16 + i * 12 + 4); var ofs = reader.GetInt32(16 + i * 12 + 8); string name; try { name = Encoding.BigEndianUnicode.GetString(bytes, ofs, len); } catch { name = Encoding.UTF8.GetString(bytes, ofs, len); } res.Append(" ").Append(str).Append("(").Append(name).Append(")"); } return(res.ToString()); } case IccTagType.Curv: { var num = reader.GetInt32(8); var res = new StringBuilder(); for (var i = 0; i < num; i++) { if (i != 0) { res.Append(", "); } res.Append(FormatDoubleAsString(reader.GetUInt16(12 + i * 2) / 65535.0, 7, false)); } return(res.ToString()); } default: { return($"{IccReader.GetStringFromUInt32(unchecked((uint)iccTagType))} (0x{(int)iccTagType:X8}): {bytes.Length} bytes"); } } } catch (IOException) { // TODO decode these values during IccReader.extract so we can report any errors at that time // It is convention to return null if a description cannot be formulated. // If an error is to be reported, it should be done during the extraction process. return(null); } }