public IccDirectory Extract([NotNull] IndexedReader reader) { // TODO review whether the 'tagPtr' values below really do require IndexedReader or whether SequentialReader may be used instead var directory = new IccDirectory(); try { var profileByteCount = reader.GetInt32(IccDirectory.TagProfileByteCount); directory.Set(IccDirectory.TagProfileByteCount, profileByteCount); // For these tags, the int value of the tag is in fact its offset within the buffer. Set4ByteString(directory, IccDirectory.TagCmmType, reader); SetInt32(directory, IccDirectory.TagProfileVersion, reader); Set4ByteString(directory, IccDirectory.TagProfileClass, reader); Set4ByteString(directory, IccDirectory.TagColorSpace, reader); Set4ByteString(directory, IccDirectory.TagProfileConnectionSpace, reader); SetDate(directory, IccDirectory.TagProfileDateTime, reader); Set4ByteString(directory, IccDirectory.TagSignature, reader); Set4ByteString(directory, IccDirectory.TagPlatform, reader); SetInt32(directory, IccDirectory.TagCmmFlags, reader); Set4ByteString(directory, IccDirectory.TagDeviceMake, reader); var model = reader.GetInt32(IccDirectory.TagDeviceModel); if (model != 0) { directory.Set(IccDirectory.TagDeviceModel, model <= 0x20202020 ? (object)model : GetStringFromUInt32(unchecked ((uint)model))); } SetInt32(directory, IccDirectory.TagRenderingIntent, reader); SetInt64(directory, IccDirectory.TagDeviceAttr, reader); var xyz = new[] { reader.GetS15Fixed16(IccDirectory.TagXyzValues), reader.GetS15Fixed16(IccDirectory.TagXyzValues + 4), reader.GetS15Fixed16(IccDirectory.TagXyzValues + 8) }; directory.Set(IccDirectory.TagXyzValues, xyz); // Process 'ICC tags' var tagCount = reader.GetInt32(IccDirectory.TagTagCount); directory.Set(IccDirectory.TagTagCount, tagCount); for (var i = 0; i < tagCount; i++) { var pos = IccDirectory.TagTagCount + 4 + i * 12; var tagType = reader.GetInt32(pos); var tagPtr = reader.GetInt32(pos + 4); var tagLen = reader.GetInt32(pos + 8); var b = reader.GetBytes(tagPtr, tagLen); directory.Set(tagType, b); } } catch (Exception ex) { directory.AddError("Exception reading ICC profile: " + ex.Message); } return(directory); }
private static void SetDate([NotNull] IccDirectory directory, int tagType, [NotNull] IndexedReader reader) { var year = reader.GetUInt16(tagType); var month = reader.GetUInt16(tagType + 2); var day = reader.GetUInt16(tagType + 4); var hours = reader.GetUInt16(tagType + 6); var minutes = reader.GetUInt16(tagType + 8); var seconds = reader.GetUInt16(tagType + 10); if (DateUtil.IsValidDate(year, month, day) && DateUtil.IsValidTime(hours, minutes, seconds)) { directory.Set(tagType, new DateTime(year, month, day, hours, minutes, seconds, kind: DateTimeKind.Utc)); } else { directory.AddError($"ICC data describes an invalid date/time: year={year} month={month} day={day} hour={hours} minute={minutes} second={seconds}"); } }