private AvifItemData ReadColorImage(uint itemId) { ItemLocationEntry entry = this.parser.TryGetItemLocation(itemId); if (entry is null) { ExceptionUtil.ThrowFormatException("The color image item location was not found."); } return(this.parser.ReadItemData(entry)); }
public AvifItemData ReadItemData(ItemLocationEntry entry) { if (entry is null) { ExceptionUtil.ThrowArgumentNullException(nameof(entry)); } AvifItemData data; if (entry.Extents.Count == 1) { long offset = CalculateExtentOffset(entry.BaseOffset, entry.ConstructionMethod, entry.Extents[0]); this.reader.Position = offset; ulong totalItemSize = entry.TotalItemSize; if (totalItemSize <= ManagedAvifItemDataMaxSize) { ManagedAvifItemData managedItemData = new ManagedAvifItemData((int)totalItemSize, this.arrayPool); this.reader.ProperRead(managedItemData.GetBuffer(), 0, (int)managedItemData.Length); data = managedItemData; } else { UnmanagedAvifItemData unmanagedItemData = new UnmanagedAvifItemData(totalItemSize); try { this.reader.ProperRead(unmanagedItemData.UnmanagedBuffer, 0, totalItemSize); data = unmanagedItemData; unmanagedItemData = null; } finally { unmanagedItemData?.Dispose(); } } } else { data = ReadDataFromMultipleExtents(entry); } return(data); }
public byte[] GetExifData() { VerifyNotDisposed(); ItemLocationEntry entry = this.parser.TryGetExifLocation(this.primaryItemId); if (entry != null) { ulong length = entry.TotalItemSize; // Ignore any EXIF blocks that are larger than 2GB. if (length < int.MaxValue) { using (AvifItemData itemData = this.parser.ReadItemData(entry)) using (Stream stream = itemData.GetStream()) { // The EXIF data block has a header that indicates the number of bytes // that come before the start of the TIFF header. // See ISO/IEC 23008-12:2017 section A.2.1. long tiffStartOffset = stream.TryReadUInt32BigEndian(); if (tiffStartOffset != -1) { long dataLength = (long)length - tiffStartOffset - sizeof(uint); if (dataLength > 0) { if (tiffStartOffset != 0) { stream.Position += tiffStartOffset; } byte[] bytes = new byte[dataLength]; stream.ProperRead(bytes, 0, bytes.Length); return(bytes); } } } } } return(null); }
private ImageGridDescriptor TryGetImageGridDescriptor(uint itemId) { IItemInfoEntry entry = TryGetItemInfoEntry(itemId); if (entry != null && entry.ItemType == ItemInfoEntryTypes.ImageGrid) { ItemLocationEntry locationEntry = TryGetItemLocation(itemId); if (locationEntry != null) { if (locationEntry.TotalItemSize < ImageGridDescriptor.SmallDescriptorLength) { ExceptionUtil.ThrowFormatException("Invalid image grid descriptor length."); } using (AvifItemData itemData = ReadItemData(locationEntry)) { Stream stream = null; try { stream = itemData.GetStream(); using (EndianBinaryReader imageGridReader = new EndianBinaryReader(stream, this.reader.Endianess, this.arrayPool)) { stream = null; return(new ImageGridDescriptor(imageGridReader, itemData.Length)); } } finally { stream?.Dispose(); } } } } return(null); }
public byte[] GetXmpData() { VerifyNotDisposed(); ItemLocationEntry entry = this.parser.TryGetXmpLocation(this.primaryItemId); if (entry != null) { ulong length = entry.TotalItemSize; // Ignore any XMP packets that are larger than 2GB. if (length < int.MaxValue) { using (AvifItemData itemData = this.parser.ReadItemData(entry)) { return(itemData.ToArray()); } } } return(null); }
private AvifItemData ReadDataFromMultipleExtents(ItemLocationEntry entry) { AvifItemData data; IReadOnlyList <ItemLocationExtent> extents = entry.Extents; ulong totalItemSize = entry.TotalItemSize; if (totalItemSize <= ManagedAvifItemDataMaxSize) { ManagedAvifItemData managedItemData = new ManagedAvifItemData((int)totalItemSize, this.arrayPool); int offset = 0; int remainingBytes = (int)managedItemData.Length; byte[] bytes = managedItemData.GetBuffer(); for (int i = 0; i < extents.Count; i++) { ItemLocationExtent extent = extents[i]; long itemOffset = CalculateExtentOffset(entry.BaseOffset, entry.ConstructionMethod, extent); int length = (int)extent.Length; if (length > remainingBytes) { throw new FormatException("The extent length is greater than the number of bytes remaining for the item."); } this.reader.Position = itemOffset; this.reader.ProperRead(bytes, offset, length); offset += length; remainingBytes -= length; } if (remainingBytes > 0) { // This should never happen, the total item size is the sum of all the extent sizes. throw new FormatException("The item has more data than was read from the extents."); } data = managedItemData; } else { UnmanagedAvifItemData unmanagedItemData = new UnmanagedAvifItemData(totalItemSize); try { ulong offset = 0; ulong remainingBytes = totalItemSize; for (int i = 0; i < extents.Count; i++) { ItemLocationExtent extent = extents[i]; long itemOffset = CalculateExtentOffset(entry.BaseOffset, entry.ConstructionMethod, extent); ulong length = extent.Length; if (length > remainingBytes) { throw new FormatException("The extent length is greater than the number of bytes remaining for the item."); } this.reader.Position = itemOffset; this.reader.ProperRead(unmanagedItemData.UnmanagedBuffer, offset, length); offset += length; remainingBytes -= length; } if (remainingBytes > 0) { // This should never happen, the total item size is the sum of all the extent sizes. throw new FormatException("The item has more data than was read from the extents."); } data = unmanagedItemData; unmanagedItemData = null; } finally { unmanagedItemData?.Dispose(); } } return(data); }