public JpegXmpPackets GetXmpPackets() { if (!fileParsed) { ParseFile(); fileParsed = true; } if (mainXmpPacket == null) { // The file does not contain any XMP data. return(null); } if (mergedXmpPacket == null) { if (extendedXmpPacket != null) { mergedXmpPacket = XmpUtil.MergeExtendedXmp(mainXmpPacket, extendedXmpPacket); } else { mergedXmpPacket = mainXmpPacket.Clone(); } } return(new JpegXmpPackets(mainXmpPacket, extendedXmpPacket, mergedXmpPacket)); }
private void GatherXmpDataFromFile(EndianBinaryReader reader) { ushort marker = reader.ReadUInt16(); // Check the file signature. if (marker == JpegMarkers.StartOfImage) { while (reader.Position < reader.Length) { marker = reader.ReadUInt16(); if (marker == 0xFFFF) { // Skip the first padding byte and read the marker again. reader.Position++; continue; } if (marker == JpegMarkers.StartOfScan || marker == JpegMarkers.EndOfImage) { // The application data segments always come before these markers. break; } ushort segmentLength = reader.ReadUInt16(); if (segmentLength < 2) { ExceptionUtil.ThrowFormatException($"JPEG segment length must be in the range of [2, 65535], actual value: { segmentLength }"); } // The segment length field includes its own length in the total. segmentLength -= sizeof(ushort); if (marker == JpegMarkers.App1) { if (mainXmpPacket == null && segmentLength >= MainXmpSignatureLength) { string sig = reader.ReadAsciiString(MainXmpSignatureLength); if (sig.Equals(MainXmpSignature, StringComparison.Ordinal)) { byte[] xmpPacketBytes = reader.ReadBytes(segmentLength - MainXmpSignatureLength); mainXmpPacket = new XmpPacket(xmpPacketBytes); extendedXmpGuid = XmpUtil.GetExtendedXmpGuid(mainXmpPacket); continue; } else { reader.Position -= MainXmpSignatureLength; } } if (segmentLength >= ExtendedXmpPrefixLength) { string sig = reader.ReadAsciiString(ExtendedXmpSignatureLength); if (sig.Equals(ExtendedXmpSignature, StringComparison.Ordinal)) { string guid = reader.ReadAsciiString(ExtendedXmpGUIDLength); uint length = reader.ReadUInt32(); uint offset = reader.ReadUInt32(); byte[] data = reader.ReadBytes(segmentLength - ExtendedXmpPrefixLength); if (extendedXmpChunks.TryGetValue(guid, out ExtendedXmp value)) { value.AddChunk(data, offset, length); } else { extendedXmpChunks.Add(guid, new ExtendedXmp(data, offset, length)); } continue; } else { segmentLength -= ExtendedXmpSignatureLength; } } } reader.Position += segmentLength; } } }