private static TDataType[] ToArray <TDataType>(ExifDataType dataType, ReadOnlySpan <byte> data, ConverterMethod <TDataType> converter) { int dataTypeSize = (int)ExifDataTypes.GetSize(dataType); int length = data.Length / dataTypeSize; var result = new TDataType[length]; for (int i = 0; i < length; i++) { ReadOnlySpan <byte> buffer = data.Slice(i * dataTypeSize, dataTypeSize); result.SetValue(converter(buffer), i); } return(result); }
private static uint GetLength(IExifValue value) => GetNumberOfComponents(value) * ExifDataTypes.GetSize(value.DataType);
private bool TryReadValue(out ExifValue exifValue) { exifValue = default; // 2 | 2 | 4 | 4 // tag | type | count | value offset if (this.RemainingLength < 12) { return(false); } var tag = (ExifTagValue)this.ReadUInt16(); ExifDataType dataType = EnumUtils.Parse(this.ReadUInt16(), ExifDataType.Unknown); // Ensure that the data type is valid if (dataType == ExifDataType.Unknown) { return(false); } uint numberOfComponents = this.ReadUInt32(); // Issue #132: ExifDataType == Undefined is treated like a byte array. // If numberOfComponents == 0 this value can only be handled as an inline value and must fallback to 4 (bytes) if (dataType == ExifDataType.Undefined && numberOfComponents == 0) { numberOfComponents = 4; } uint size = numberOfComponents * ExifDataTypes.GetSize(dataType); this.TryReadSpan(4, out ReadOnlySpan <byte> offsetBuffer); object value; if (size > 4) { int oldIndex = this.position; uint newIndex = this.ConvertToUInt32(offsetBuffer); // Ensure that the new index does not overrun the data if (newIndex > int.MaxValue) { this.AddInvalidTag(new UnkownExifTag(tag)); return(false); } this.position = (int)newIndex; if (this.RemainingLength < size) { this.AddInvalidTag(new UnkownExifTag(tag)); this.position = oldIndex; return(false); } this.TryReadSpan((int)size, out ReadOnlySpan <byte> dataBuffer); value = this.ConvertValue(dataType, dataBuffer, numberOfComponents); this.position = oldIndex; } else { value = this.ConvertValue(dataType, offsetBuffer, numberOfComponents); } exifValue = ExifValues.Create(tag) ?? ExifValues.Create(tag, dataType, numberOfComponents); if (exifValue is null) { this.AddInvalidTag(new UnkownExifTag(tag)); return(false); } if (!exifValue.TrySetValue(value)) { return(false); } return(true); }