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);
        }
示例#2
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
        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!");
            }
        }