2using System.Diagnostics.CodeAnalysis;
24 using MemoryStream StreamData =
new(Data);
25 return TryParse(StreamData, out Record);
37 long Start = Data.Position;
38 long MaxRecordLength = Data.Length - Start;
44 if (!Data.TryRead(out
string? s) || s !=
"FAC")
47 if (!Data.TryRead(out s) || !
int.TryParse(s, out
int i))
51 int Revision = i % 10;
53 if (!Data.TryRead(out uint RecordLength) ||
54 RecordLength < 68 || RecordLength > MaxRecordLength)
59 if (!Data.TryRead(out ushort NrRepresentations) || NrRepresentations == 0)
64 if (!Data.TryRead(out
bool Certification))
67 if (!Data.TryRead(out ushort TemporalSemantics))
77 long RepresentationStart = Data.Position;
78 long MaxRepresentationLength = Data.Length - RepresentationStart;
82 if (!Data.TryRead(out uint RepresentationLength) ||
83 RepresentationLength < 51 || RepresentationLength > MaxRepresentationLength)
90 if (!Data.TryRead(out DateTime CaptureDateAndTime))
96 if (!Data.TryRead(out ushort NrLandmarkPoints))
99 if (!Data.TryRead(out
byte GenderUntyped) || (GenderUntyped > 2 && GenderUntyped < 0xff) ||
100 !Data.TryRead(out
byte EyeColourUntyped) || EyeColourUntyped > 7 ||
101 !Data.TryRead(out
byte HairColourUntyped))
112 if (!Data.TryRead(out
byte SubjectHeight))
116 if (!Data.TryRead(3, out uint PropertyMask) ||
117 !Data.TryRead(out ushort ExpressionMask) ||
118 !Data.TryRead(3, out uint PoseAngle) ||
119 !Data.TryRead(3, out uint PoseAngleUncertainty))
124 if (NrLandmarkPoints > 0)
128 if (!Data.TryRead(out
byte FaceImageTypeRaw) || FaceImageTypeRaw > 3 ||
129 !Data.TryRead(out
byte ImageDataTypeRaw) || ImageDataTypeRaw > 3 ||
130 !Data.TryRead(out ushort Width) ||
131 !Data.TryRead(out ushort Height))
139 if (Version < 3 && ImageDataTypeRaw < 2)
147 if (!Data.TryRead(out
byte SpatialSamplingRateLevel) ||
148 !Data.TryRead(out
byte PostAcquisitionProcessing) ||
149 !Data.TryRead(out
byte CrossReference))
155 if (!Data.TryRead(out
byte ImageColourSpace))
160 if (!Data.TryRead(out
byte SourceType) ||
161 !Data.TryRead(out ushort DeviceType) ||
162 !Data.TryRead(out ushort Quality))
168 int BytesLeft = (int)RepresentationLength - (
int)(Data.Position - RepresentationStart);
172 if (!Data.TryRead(BytesLeft, out
byte[] ImageData))
184 private static bool TryRead(
this Stream Data,
int N, out
byte[] Binary)
186 Binary =
new byte[N];
187 return Data.TryReadAll(Binary, 0, N) == N;
190 private static bool TryRead(
this Stream Data, out
bool Result)
192 if (!Data.TryRead(out
byte b) || b > 1)
204 private static bool TryRead(
this Stream Data, out
byte Result)
206 int i = Data.ReadByte();
220 private static bool TryRead(
this Stream Data, out ushort Result)
224 for (
int i = 0; i < 2; i++)
226 int j = Data.ReadByte();
237 private static bool TryRead(
this Stream Data, out uint Result)
239 return Data.TryRead(4, out Result);
242 private static bool TryRead(
this Stream Data,
int N, out uint Result)
246 for (
int i = 0; i < N; i++)
248 int j = Data.ReadByte();
259 private static bool TryRead(
this Stream Data, [NotNullWhen(
true)] out
string? Result)
261 return Data.TryRead(Encoding.ASCII, out Result);
264 private static bool TryRead(
this Stream Data, Encoding Encoding,
265 [NotNullWhen(
true)] out
string? Result)
267 using MemoryStream Temp =
new();
271 int i = Data.ReadByte();
280 Result = Encoding.GetString(Temp.ToArray());
284 Temp.WriteByte((
byte)i);
288 private static bool TryRead(
this Stream Data, out DateTime Result)
290 if (!Data.TryRead(out ushort Year) || Year < 1800 || Year > 9999 ||
291 !Data.TryRead(out
byte Month) || Month < 1 || Month > 12 ||
292 !Data.TryRead(out
byte Day) || Day < 1 || Day > DateTime.DaysInMonth(Year, Month) ||
293 !Data.TryRead(out
byte Hour) || Hour > 59 ||
294 !Data.TryRead(out
byte Minute) || Minute > 59 ||
295 !Data.TryRead(out
byte Second) || Second > 59 ||
296 !Data.TryRead(out ushort Millisecond) || Millisecond > 1000)
298 Result = DateTime.MinValue;
303 Result =
new DateTime(Year, Month, Day, Hour, Minute, Second, Millisecond, DateTimeKind.Utc);
Biometric Data Interchange Record (BDIR)
ISO 19794-5: Biometric Data interchange formats - Part 5: Face image data.
static bool TryParse(byte[] Data, [NotNullWhen(true)] out BiometricDataInterchangeRecord? Record)
Tries to parse biometric data from ISO 19794-5 compliant data.
static bool TryParse(Stream Data, [NotNullWhen(true)] out BiometricDataInterchangeRecord? Record)
Tries to parse biometric data from ISO 19794-5 compliant data.
Contains a representation of biometric data of a face.
Contains a representation of biometric data.
A chunked list is a linked list of chunks of objects of type T .
void Add(T Item)
Adds an item to the collection.
FaceImageType
ICAO 9303 / ISO 19794-5 face image type.
ImageDataType
ICAO 9303 / ISO 19794-5 image data type.
HairColour
ISO 19794-5 hair colour enumeration.
EyeColour
ISO 19794-5 eye colour enumeration.
Gender
ISO 19794-5 gender enumeration.