public XmpDirectory Extract([NotNull] byte[] xmpBytes, int offset, int length) { if (offset < 0) { throw new ArgumentOutOfRangeException(nameof(offset), "Must be zero or greater."); } if (length < 0) { throw new ArgumentOutOfRangeException(nameof(length), "Must be zero or greater."); } if (xmpBytes.Length < offset + length) { throw new ArgumentException("Extends beyond length of byte array.", nameof(length)); } // Trim any trailing null bytes // https://github.com/drewnoakes/metadata-extractor-dotnet/issues/154 while (xmpBytes[offset + length - 1] == 0) { length--; } var directory = new XmpDirectory(); try { var xmpMeta = XmpMetaFactory.ParseFromBuffer(xmpBytes, offset, length); directory.SetXmpMeta(xmpMeta); } catch (XmpException e) { directory.AddError("Error processing XMP data: " + e.Message); } return(directory); }
private static IReadOnlyList <XmpDirectory> ReadJpegSegments(IEnumerable <JpegSegment> segments) { // This is a modified version of XmpReader.ReadJpegSegments // The original version specifically tests the buffer against the classic XMP preamble and discards everything else. // Here we also test against the extended XMP preamble and regroup all the extended segments into a single buffer. // Note that we do not import any of the usual tags as in ProcessXmpTags(). Users of the class have to go // through XmpMeta methods. var directories = new List <XmpDirectory>(); byte[] extendedData = null; int maxPreambleLength = Math.Max(XmpJpegPreamble.Length, XmpJpegExtendedPreamble.Length); try { foreach (var segment in segments) { string extractedPreamble = Encoding.UTF8.GetString(segment.Bytes, 0, maxPreambleLength); if (extractedPreamble.StartsWith(XmpJpegPreamble)) { ParseNormalXmpSegment(directories, segment.Bytes); } else if (extractedPreamble.StartsWith(XmpJpegExtendedPreamble)) { ParseExtendedXmpSegment(ref extendedData, segment.Bytes); } } } catch (JpegProcessingException) { return(directories); } if (extendedData == null) { return(directories); } // We have collected extended XMP data, let's parse the reconstructed buffer. XmpDirectory directory = new XmpDirectory(); try { var xmpMeta = XmpMetaFactory.ParseFromBuffer(extendedData); directory.SetXmpMeta(xmpMeta); } catch (XmpException e) { directory.AddError("Error processing XMP data: " + e.Message); } directories.Add(directory); return(directories); }
public XmpDirectory Extract([NotNull] byte[] xmpBytes, int offset, int length) { var directory = new XmpDirectory(); try { var xmpMeta = XmpMetaFactory.ParseFromBuffer(xmpBytes, offset, length); directory.SetXmpMeta(xmpMeta); } catch (XmpException e) { directory.AddError("Error processing XMP data: " + e.Message); } return(directory); }
/// <summary> /// Performs the XMP data extraction. /// <para /> /// The extraction is done with Adobe's XMPCore library. /// </summary> public XmpDirectory Extract([NotNull] byte[] xmpBytes) { var directory = new XmpDirectory(); try { var xmpMeta = XmpMetaFactory.ParseFromBuffer(xmpBytes); ProcessXmpTags(directory, xmpMeta); } catch (XmpException e) { directory.AddError("Error processing XMP data: " + e.Message); } return(directory); }
public XmpDirectory Extract([NotNull] byte[] xmpBytes, int offset, int length) { if (offset < 0) { throw new ArgumentOutOfRangeException(nameof(offset), "Must be zero or greater."); } if (length < 0) { throw new ArgumentOutOfRangeException(nameof(length), "Must be zero or greater."); } if (xmpBytes.Length < offset + length) { throw new ArgumentException("Extends beyond length of byte array.", nameof(length)); } // Trim any trailing null bytes // https://github.com/drewnoakes/metadata-extractor-dotnet/issues/154 while (xmpBytes[offset + length - 1] == 0) { length--; } var directory = new XmpDirectory(); try { // Limit photoshop:DocumentAncestors node as it can reach over 100000 items and make parsing extremely slow. // This is not a typical value but it may happen https://forums.adobe.com/thread/2081839 var parseOptions = new ParseOptions(); parseOptions.SetXMPNodesToLimit(new Dictionary <string, int>() { { "photoshop:DocumentAncestors", 1000 } }); var xmpMeta = XmpMetaFactory.ParseFromBuffer(xmpBytes, offset, length, parseOptions); directory.SetXmpMeta(xmpMeta); } catch (XmpException e) { directory.AddError("Error processing XMP data: " + e.Message); } return(directory); }
private static void ParseNormalXmpSegment(List <XmpDirectory> directories, byte[] segmentBytes) { byte[] xmpBytes = new byte[segmentBytes.Length - XmpJpegPreamble.Length]; Array.Copy(segmentBytes, XmpJpegPreamble.Length, xmpBytes, 0, xmpBytes.Length); XmpDirectory directory = new XmpDirectory(); try { var xmpMeta = XmpMetaFactory.ParseFromBuffer(xmpBytes); directory.SetXmpMeta(xmpMeta); } catch (XmpException e) { directory.AddError("Error processing XMP data: " + e.Message); } directories.Add(directory); }
private void CompareResults(String orig, String curr) { PdfReader cmpReader = new PdfReader(CMP_FOLDER + orig); PdfReader outReader = new PdfReader(OUT_FOLDER + curr); byte[] cmpBytes = cmpReader.Metadata, outBytes = outReader.Metadata; IXmpMeta xmpMeta = XmpMetaFactory.ParseFromBuffer(cmpBytes); XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_XMP, XmpBasicProperties.CREATEDATE, true, true); XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_XMP, XmpBasicProperties.MODIFYDATE, true, true); XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_XMP, XmpBasicProperties.METADATADATE, true, true); XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_PDF, PdfProperties.PRODUCER, true, true); cmpBytes = XmpMetaFactory.SerializeToBuffer(xmpMeta, new SerializeOptions(SerializeOptions.SORT)); xmpMeta = XmpMetaFactory.ParseFromBuffer(outBytes); XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_XMP, XmpBasicProperties.CREATEDATE, true, true); XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_XMP, XmpBasicProperties.MODIFYDATE, true, true); XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_XMP, XmpBasicProperties.METADATADATE, true, true); XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_PDF, PdfProperties.PRODUCER, true, true); outBytes = XmpMetaFactory.SerializeToBuffer(xmpMeta, new SerializeOptions(SerializeOptions.SORT)); XmlDiff xmldiff = new XmlDiff(XmlDiffOptions.None); if (!xmldiff.Compare(new XmlTextReader(new MemoryStream(cmpBytes)), new XmlTextReader(new MemoryStream(outBytes)))) { String currXmlName = curr.Replace(".pdf", ".xml"); FileStream outStream = new FileStream(OUT_FOLDER + "cmp_" + currXmlName, FileMode.Create); outStream.Write(cmpBytes, 0, cmpBytes.Length); outStream = new FileStream(OUT_FOLDER + currXmlName, FileMode.Create); outStream.Write(outBytes, 0, outBytes.Length); Assert.Fail("The XMP packages are different!"); } }