Exemple #1
0
        ReadJpegSegments(IEnumerable <byte[]> segments, JpegSegmentType segmentType)
        {
            // ICC data can be spread across multiple JPEG segments.

            // Skip any segments that do not contain the required preamble
            var iccSegments = segments.Where(segment => segment.Length > SegmentHeaderLength && IsSubarrayEqualTo(segment, 0, _jpegSegmentPreambleBytes)).ToList();

            if (iccSegments.Count == 0)
            {
                return(new Directory[0]);
            }

            byte[] buffer;
            if (iccSegments.Count == 1)
            {
                buffer = new byte[iccSegments[0].Length - SegmentHeaderLength];
                Array.Copy(iccSegments[0], SegmentHeaderLength, buffer, 0, iccSegments[0].Length - SegmentHeaderLength);
            }
            else
            {
                // Concatenate all buffers
                var totalLength = iccSegments.Sum(s => s.Length - SegmentHeaderLength);
                buffer = new byte[totalLength];
                for (int i = 0, pos = 0; i < iccSegments.Count; i++)
                {
                    var segment = iccSegments[i];
                    Array.Copy(segment, SegmentHeaderLength, buffer, pos, segment.Length - SegmentHeaderLength);
                    pos += segment.Length - SegmentHeaderLength;
                }
            }

            return(new[] { Extract(new ByteArrayReader(buffer)) });
        }
        /// <exception cref="System.IO.IOException"/>
        /// <exception cref="Com.Drew.Imaging.Jpeg.JpegProcessingException"/>
        public static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                PrintUsage();
                System.Environment.Exit(1);
            }
            string filePath = args[0];

            if (!new FilePath(filePath).Exists())
            {
                System.Console.Error.Println("File does not exist");
                PrintUsage();
                System.Environment.Exit(1);
            }
            ICollection <JpegSegmentType> segmentTypes = new HashSet <JpegSegmentType>();

            for (int i = 1; i < args.Length; i++)
            {
                JpegSegmentType segmentType = JpegSegmentType.ValueOf(args[i].ToUpper());
                if (!segmentType.canContainMetadata)
                {
                    System.Console.Error.Printf("WARNING: Segment type %s cannot contain metadata so it may not be necessary to extract it%n", segmentType);
                }
                segmentTypes.Add(segmentType);
            }
            if (segmentTypes.Count == 0)
            {
                // If none specified, use all that could reasonably contain metadata
                Sharpen.Collections.AddAll(segmentTypes, JpegSegmentType.canContainMetadataTypes);
            }
            JpegSegmentData segmentData = JpegSegmentReader.ReadSegments(new FilePath(filePath), segmentTypes.AsIterable());

            SaveSegmentFiles(filePath, segmentData);
        }
Exemple #3
0
        /// <summary>
        /// Split data array to segments of length at most <paramref name="maxSegmentSize"/> bytes
        /// </summary>
        /// <param name="data">Data to split</param>
        /// <param name="type">Type of each JPEG segment</param>
        /// <param name="header">
        /// Header of each JPEG segment. All characters have to be ASCII.
        /// </param>
        /// <param name="maxSegmentSize">
        /// Maximal size of the JPEG segment (excluding the 2 size bytes)
        /// </param>
        /// <returns>JPEG segments enumerator</returns>
        public static IEnumerable <JpegSegment> SplitSegmentData(
            byte[] data,
            JpegSegmentType type,
            string header,
            long maxSegmentSize = MaxSegmentSize)
        {
            if (header.Length >= maxSegmentSize)
            {
                throw new ArgumentException(
                          "Header must fit in the JPEG segment with some data.");
            }

            long dataOffset = 0;

            while (dataOffset < data.Length)
            {
                long bufferSize = Math.Min(
                    data.Length - dataOffset,
                    maxSegmentSize - header.Length);
                var buffer = new byte[bufferSize + header.Length];

                // copy header
                for (int i = 0; i < header.Length; ++i)
                {
                    buffer[i] = (byte)header[i];
                }

                // copy part of the data
                Array.Copy(data, dataOffset, buffer, header.Length, bufferSize);
                dataOffset += bufferSize;
                yield return(new JpegSegment(type, buffer, 0));
            }
        }
     ReadJpegSegments(IEnumerable<byte[]> segments, JpegSegmentType segmentType)
 {
     var preambleLength = JpegSegmentPreamble.Length;
     return segments
         .Where(segment => segment.Length >= preambleLength + 1 && JpegSegmentPreamble == Encoding.UTF8.GetString(segment, 0, preambleLength))
         .SelectMany(segment => Extract(new SequentialByteArrayReader(segment, preambleLength + 1), segment.Length - preambleLength - 1))
         .ToList();
 }
 public JpegSegment(JpegSegmentType type, int length, int padding, long offset, string preamble)
 {
     Type     = type;
     Length   = length;
     Padding  = padding;
     Offset   = offset;
     Preamble = preamble;
 }
            ReadJpegSegments(IEnumerable<byte[]> segments, JpegSegmentType segmentType)
        {
            Debug.Assert(segmentType == JpegSegmentType.App1);

            return segments
                .Where(segment => segment.Length >= JpegSegmentPreamble.Length && Encoding.UTF8.GetString(segment, 0, JpegSegmentPreamble.Length) == JpegSegmentPreamble)
                .SelectMany(segment => Extract(new ByteArrayReader(segment), JpegSegmentPreamble.Length))
                .ToList();
        }
Exemple #7
0
        ReadJpegSegments(IEnumerable <byte[]> segments, JpegSegmentType segmentType)
        {
            var preambleLength = JpegSegmentPreamble.Length;

            return(segments
                   .Where(segment => segment.Length >= preambleLength + 1 && JpegSegmentPreamble == Encoding.UTF8.GetString(segment, 0, preambleLength))
                   .SelectMany(segment => Extract(new SequentialByteArrayReader(segment, preambleLength + 1), segment.Length - preambleLength - 1))
                   .ToList());
        }
        /// <summary>Removes a specified instance of a segment's data from the collection.</summary>
        /// <remarks>
        /// Removes a specified instance of a segment's data from the collection.  Use this method when more than one
        /// occurrence of segment data exists for a given type exists.
        /// </remarks>
        /// <param name="segmentType">identifies the required segment</param>
        /// <param name="occurrence">the zero-based index of the segment occurrence to remove.</param>
        public void RemoveSegmentOccurrence(JpegSegmentType segmentType, int occurrence)
        {
            IList <byte[]> segmentList;

            if (_segmentDataMap.TryGetValue(segmentType, out segmentList))
            {
                segmentList.RemoveAt(occurrence);
            }
        }
        ReadJpegSegments(IEnumerable <byte[]> segments, JpegSegmentType segmentType)
        {
            Debug.Assert(segmentType == JpegSegmentType.App1);

            return(segments
                   .Where(segment => segment.Length >= JpegSegmentPreamble.Length && Encoding.UTF8.GetString(segment, 0, JpegSegmentPreamble.Length) == JpegSegmentPreamble)
                   .SelectMany(segment => Extract(new ByteArrayReader(segment), JpegSegmentPreamble.Length))
                   .ToList());
        }
        ReadJpegSegments(IEnumerable <byte[]> segments, JpegSegmentType segmentType)
        {
            return(segments
                   .Where(segment => segment.Length == 12 && Preamble.Equals(Encoding.ASCII.GetString(segment, 0, Preamble.Length), StringComparison.OrdinalIgnoreCase))
                   .Select(bytes => Extract(new SequentialByteArrayReader(bytes)))
#if NET35
                   .Cast <Directory>()
#endif
                   .ToList());
        }
            ReadJpegSegments(IEnumerable<byte[]> segments, JpegSegmentType segmentType)
        {
            return segments
                .Where(segment => segment.Length == 12 && Preamble.Equals(Encoding.ASCII.GetString(segment, 0, Preamble.Length), StringComparison.OrdinalIgnoreCase))
                .Select(bytes => Extract(new SequentialByteArrayReader(bytes)))
#if NET35
                .Cast<Directory>()
#endif
                .ToList();
        }
            ReadJpegSegments(IEnumerable<byte[]> segments, JpegSegmentType segmentType)
        {
            // Ensure data starts with the IPTC marker byte
            return segments
                .Where(segment => segment.Length != 0 && segment[0] == IptcMarkerByte)
                .Select(segment => Extract(new SequentialByteArrayReader(segment), segment.Length))
#if NET35
                .Cast<Directory>()
#endif
                .ToList();
        }
        private IList <byte[]> GetOrCreateSegmentList(JpegSegmentType segmentType)
        {
            IList <byte[]> segmentList;

            if (!_segmentDataMap.TryGetValue(segmentType, out segmentList))
            {
                segmentList = new List <byte[]>();
                _segmentDataMap[segmentType] = segmentList;
            }
            return(segmentList);
        }
        ReadJpegSegments(IEnumerable <byte[]> segments, JpegSegmentType segmentType)
        {
            // Ensure data starts with the IPTC marker byte
            return(segments
                   .Where(segment => segment.Length != 0 && segment[0] == IptcMarkerByte)
                   .Select(segment => Extract(new SequentialByteArrayReader(segment), segment.Length))
#if NET35
                   .Cast <Directory>()
#endif
                   .ToList());
        }
        ReadJpegSegments(IEnumerable <byte[]> segments, JpegSegmentType segmentType)
        {
            // Skip segments not starting with the required header
            return(segments
                   .Where(segment => segment.Length >= Preamble.Length && Preamble == Encoding.ASCII.GetString(segment, 0, Preamble.Length))
                   .Select(segment => Extract(new SequentialByteArrayReader(segment, Preamble.Length)))
#if NET35
                   .Cast <Directory>()
#endif
                   .ToList());
        }
            ReadJpegSegments(IEnumerable<byte[]> segments, JpegSegmentType segmentType)
        {
            // Skip segments not starting with the required header
            return segments
                .Where(segment => segment.Length >= Preamble.Length && Preamble == Encoding.ASCII.GetString(segment, 0, Preamble.Length))
                .Select(segment => Extract(new SequentialByteArrayReader(segment, Preamble.Length)))
#if NET35
                .Cast<Directory>()
#endif
                .ToList();
        }
        ReadJpegSegments(IEnumerable <byte[]> segments, JpegSegmentType segmentType)
        {
            Debug.Assert(segmentType == JpegSegmentType.Com);

            // TODO store bytes in the directory to allow different encodings when decoding

            // The entire contents of the segment are the comment
            return(segments.Select(segment => new JpegCommentDirectory(Encoding.UTF8.GetString(segment)))
#if NET35
                   .Cast <Directory>()
#endif
                   .ToList());
        }
        /// <summary>Gets whether this JPEG segment type might contain metadata.</summary>
        /// <remarks>Used to exclude large image-data-only segment from certain types of processing.</remarks>
        public static bool CanContainMetadata(this JpegSegmentType type)
        {
            switch (type)
            {
            case JpegSegmentType.Soi:
            case JpegSegmentType.Dqt:
            case JpegSegmentType.Dht:
                return(false);

            default:
                return(true);
            }
        }
            ReadJpegSegments(IEnumerable<byte[]> segments, JpegSegmentType segmentType)
        {
            Debug.Assert(segmentType == JpegSegmentType.Com);

            // TODO store bytes in the directory to allow different encodings when decoding

            // The entire contents of the segment are the comment
            return segments.Select(segment => new JpegCommentDirectory(Encoding.UTF8.GetString(segment)))
#if NET35
                .Cast<Directory>()
#endif
                .ToList();
        }
Exemple #20
0
        /// <summary>
        /// Check segment type and header.
        /// </summary>
        /// <param name="segment">JPEG segment</param>
        /// <param name="type">Expected type</param>
        /// <param name="header">Expected header</param>
        /// <returns>true iff the segment has given type and header</returns>
        public static bool MatchSegment(JpegSegment segment, JpegSegmentType type, string header)
        {
            if (segment.Type != type || segment.Bytes.Length < header.Length)
            {
                return(false);
            }

            for (int i = 0; i < header.Length; ++i)
            {
                if ((char)segment.Bytes[i] != header[i])
                {
                    return(false);
                }
            }

            return(true);
        }
        ReadJpegSegments(IEnumerable <byte[]> segments, JpegSegmentType segmentType)
        {
            var directories = new List <Directory>();

            foreach (var segmentBytes in segments)
            {
                // XMP in a JPEG file has an identifying preamble which is not valid XML
                var preambleLength = XmpJpegPreamble.Length;
                if (segmentBytes.Length >= preambleLength && XmpJpegPreamble.Equals(Encoding.UTF8.GetString(segmentBytes, 0, preambleLength), StringComparison.OrdinalIgnoreCase))
                {
                    var xmlBytes = new byte[segmentBytes.Length - preambleLength];
                    Array.Copy(segmentBytes, preambleLength, xmlBytes, 0, xmlBytes.Length);
                    directories.Add(Extract(xmlBytes));
                }
            }

            return(directories);
        }
            ReadJpegSegments(IEnumerable<byte[]> segments, JpegSegmentType segmentType)
        {
            var directories = new List<Directory>();

            foreach (var segmentBytes in segments)
            {
                // XMP in a JPEG file has an identifying preamble which is not valid XML
                var preambleLength = XmpJpegPreamble.Length;
                if (segmentBytes.Length >= preambleLength && XmpJpegPreamble.Equals(Encoding.UTF8.GetString(segmentBytes, 0, preambleLength), StringComparison.OrdinalIgnoreCase))
                {
                    var xmlBytes = new byte[segmentBytes.Length - preambleLength];
                    Array.Copy(segmentBytes, preambleLength, xmlBytes, 0, xmlBytes.Length);
                    directories.Add(Extract(xmlBytes));
                }
            }

            return directories;
        }
Exemple #23
0
        /// <summary>Gets whether this JPEG segment type's marker is followed by a length indicator.</summary>
        public static bool ContainsPayload(this JpegSegmentType type)
        {
            // ReSharper disable once SwitchStatementMissingSomeCases
            switch (type)
            {
            case JpegSegmentType.Soi:
            case JpegSegmentType.Eoi:
            case JpegSegmentType.Rst0:
            case JpegSegmentType.Rst1:
            case JpegSegmentType.Rst2:
            case JpegSegmentType.Rst3:
            case JpegSegmentType.Rst4:
            case JpegSegmentType.Rst5:
            case JpegSegmentType.Rst6:
            case JpegSegmentType.Rst7:
                return(false);

            default:
                return(true);
            }
        }
Exemple #24
0
        /// <summary>
        /// Copy segment data from multiple segments without header to a single array.
        /// </summary>
        /// <param name="segments">All segments</param>
        /// <param name="type">Type of segments to copy</param>
        /// <param name="header">Header of the segments to copy (first bytes, ASCII characters only)</param>
        /// <returns></returns>
        public static byte[] JoinSegmentData(
            IEnumerable <JpegSegment> segments,
            JpegSegmentType type,
            string header)
        {
            // compute the exact size
            long size = 0;

            foreach (var segment in segments)
            {
                if (MatchSegment(segment, type, header))
                {
                    size += segment.Bytes.Length - header.Length;
                }
            }

            // copy segments
            var  buffer       = new byte[size];
            long bufferOffset = 0;

            foreach (var segment in segments)
            {
                if (MatchSegment(segment, type, header))
                {
                    var bytesToCopyCount = segment.Bytes.Length - header.Length;
                    Array.Copy(
                        segment.Bytes,
                        header.Length,
                        buffer,
                        bufferOffset,
                        bytesToCopyCount);
                    bufferOffset += bytesToCopyCount;
                }
            }

            return(buffer);
        }
Exemple #25
0
        /// <summary>Reads JPEG SOF values and returns them in a <see cref="JpegDirectory"/>.</summary>
        public JpegDirectory Extract(byte[] segmentBytes, JpegSegmentType segmentType)
        {
            var directory = new JpegDirectory();

            // The value of TagCompressionType is determined by the segment type found
            directory.Set(JpegDirectory.TagCompressionType, (int)segmentType - (int)JpegSegmentType.Sof0);

            SequentialReader reader = new SequentialByteArrayReader(segmentBytes);

            try
            {
                directory.Set(JpegDirectory.TagDataPrecision, reader.GetByte());
                directory.Set(JpegDirectory.TagImageHeight, reader.GetUInt16());
                directory.Set(JpegDirectory.TagImageWidth, reader.GetUInt16());
                var componentCount = reader.GetByte();
                directory.Set(JpegDirectory.TagNumberOfComponents, componentCount);
                // for each component, there are three bytes of data:
                // 1 - Component ID: 1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q
                // 2 - Sampling factors: bit 0-3 vertical, 4-7 horizontal
                // 3 - Quantization table number
                for (var i = 0; i < (int)componentCount; i++)
                {
                    int componentId             = reader.GetByte();
                    int samplingFactorByte      = reader.GetByte();
                    int quantizationTableNumber = reader.GetByte();
                    var component = new JpegComponent(componentId, samplingFactorByte, quantizationTableNumber);
                    directory.Set(JpegDirectory.TagComponentData1 + i, component);
                }
            }
            catch (IOException ex)
            {
                directory.AddError(ex.Message);
            }

            return(directory);
        }
        /// <summary>Reads JPEG SOF values and returns them in a <see cref="JpegDirectory"/>.</summary>
        public JpegDirectory Extract(byte[] segmentBytes, JpegSegmentType segmentType)
        {
            var directory = new JpegDirectory();

            // The value of TagCompressionType is determined by the segment type found
            directory.Set(JpegDirectory.TagCompressionType, (int)segmentType - (int)JpegSegmentType.Sof0);

            SequentialReader reader = new SequentialByteArrayReader(segmentBytes);

            try
            {
                directory.Set(JpegDirectory.TagDataPrecision, reader.GetByte());
                directory.Set(JpegDirectory.TagImageHeight, reader.GetUInt16());
                directory.Set(JpegDirectory.TagImageWidth, reader.GetUInt16());
                var componentCount = reader.GetByte();
                directory.Set(JpegDirectory.TagNumberOfComponents, componentCount);
                // for each component, there are three bytes of data:
                // 1 - Component ID: 1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q
                // 2 - Sampling factors: bit 0-3 vertical, 4-7 horizontal
                // 3 - Quantization table number
                for (var i = 0; i < (int)componentCount; i++)
                {
                    int componentId = reader.GetByte();
                    int samplingFactorByte = reader.GetByte();
                    int quantizationTableNumber = reader.GetByte();
                    var component = new JpegComponent(componentId, samplingFactorByte, quantizationTableNumber);
                    directory.Set(JpegDirectory.TagComponentData1 + i, component);
                }
            }
            catch (IOException ex)
            {
                directory.AddError(ex.Message);
            }

            return directory;
        }
Exemple #27
0
        public static IList <Directory> ProcessSegmentBytes(string filePath, JpegSegmentType type)
        {
            var segment = new JpegSegment(type, TestDataUtil.GetBytes(filePath), 0);

            return(new ExifReader().ReadJpegSegments(new[] { segment }).ToList());
        }
Exemple #28
0
        public virtual void Extract(sbyte[] segmentBytes, Com.Drew.Metadata.Metadata metadata, JpegSegmentType segmentType)
        {
            JpegCommentDirectory directory = metadata.GetOrCreateDirectory <JpegCommentDirectory>();

            // The entire contents of the directory are the comment
            directory.SetString(JpegCommentDirectory.TagComment, Sharpen.Runtime.GetStringForBytes(segmentBytes));
        }
Exemple #29
0
 public virtual bool CanProcess(sbyte[] segmentBytes, JpegSegmentType segmentType)
 {
     // The entire contents of the byte[] is the comment. There's nothing here to discriminate upon.
     return(true);
 }
 /// <summary>Removes all segments from the collection having the specified type.</summary>
 /// <param name="segmentType">identifies the required segment</param>
 public void RemoveAllSegments(JpegSegmentType segmentType)
 {
     _segmentDataMap.Remove(segmentType);
 }
 public virtual void ReadJpegSegments([NotNull] Iterable <sbyte[]> segments, [NotNull] Com.Drew.Metadata.Metadata metadata, [NotNull] JpegSegmentType segmentType)
 {
     foreach (sbyte[] segmentBytes in segments)
     {
         // Ensure data starts with the IPTC marker byte
         if (segmentBytes.Length != 0 && segmentBytes[0] == unchecked ((int)(0x1c)))
         {
             Extract(new SequentialByteArrayReader(segmentBytes), metadata, segmentBytes.Length);
         }
     }
 }
Exemple #32
0
 public JpegSegment(JpegSegmentType type, byte[] bytes, long offset)
 {
     Type   = type;
     Bytes  = bytes;
     Offset = offset;
 }
 private IList<byte[]> GetSegmentList(JpegSegmentType segmentType)
 {
     IList<byte[]> list;
     return _segmentDataMap.TryGetValue(segmentType, out list) ? list : null;
 }
 public virtual bool CanProcess(sbyte[] segmentBytes, JpegSegmentType segmentType)
 {
     return(segmentBytes.Length > 12 && "Photoshop 3.0".Equals(Sharpen.Runtime.GetStringForBytes(segmentBytes, 0, 13)));
 }
 public virtual void Extract(sbyte[] segmentBytes, Com.Drew.Metadata.Metadata metadata, JpegSegmentType segmentType)
 {
     Extract(new SequentialByteArrayReader(segmentBytes), metadata);
 }
 /// <summary>Adds segment bytes to the collection.</summary>
 /// <param name="segmentType">the type of the segment being added</param>
 /// <param name="segmentBytes">the byte array holding data for the segment being added</param>
 public void AddSegment(JpegSegmentType segmentType, [NotNull] byte[] segmentBytes)
 {
     GetOrCreateSegmentList(segmentType).Add(segmentBytes);
 }
 public byte[] GetSegment(JpegSegmentType segmentType, int occurrence = 0)
 {
     var segmentList = GetSegmentList(segmentType);
     return segmentList != null && segmentList.Count > occurrence ? segmentList[occurrence] : null;
 }
 public IEnumerable<byte[]> GetSegments(JpegSegmentType segmentType) => GetSegmentList(segmentType) ?? Enumerable.Empty<byte[]>();
Exemple #39
0
 public static T ProcessSegmentBytes <T>(string filePath, JpegSegmentType type) where T : Directory
 {
     return(ProcessSegmentBytes(filePath, type).OfType <T>().First());
 }
 /// <summary>Determines whether data is present for a given segment type.</summary>
 /// <param name="segmentType">identifies the required segment</param>
 /// <returns>true if data exists, otherwise false</returns>
 public bool ContainsSegment(JpegSegmentType segmentType)
 {
     return _segmentDataMap.ContainsKey(segmentType);
 }
 public virtual bool CanProcess(sbyte[] segmentBytes, JpegSegmentType segmentType)
 {
     return(segmentBytes.Length == 12 && Sharpen.Runtime.EqualsIgnoreCase("Adobe", Sharpen.Runtime.GetStringForBytes(segmentBytes, 0, 5)));
 }
 /// <summary>Removes a specified instance of a segment's data from the collection.</summary>
 /// <remarks>
 /// Removes a specified instance of a segment's data from the collection.  Use this method when more than one
 /// occurrence of segment data exists for a given type exists.
 /// </remarks>
 /// <param name="segmentType">identifies the required segment</param>
 /// <param name="occurrence">the zero-based index of the segment occurrence to remove.</param>
 public void RemoveSegmentOccurrence(JpegSegmentType segmentType, int occurrence)
 {
     IList<byte[]> segmentList;
     if (_segmentDataMap.TryGetValue(segmentType, out segmentList))
     {
         segmentList.RemoveAt(occurrence);
     }
 }
 private IList<byte[]> GetOrCreateSegmentList(JpegSegmentType segmentType)
 {
     IList<byte[]> segmentList;
     if (!_segmentDataMap.TryGetValue(segmentType, out segmentList))
     {
         segmentList = new List<byte[]>();
         _segmentDataMap[segmentType] = segmentList;
     }
     return segmentList;
 }
Exemple #44
0
 /// <summary>Gets whether this JPEG segment is intended to hold application specific data.</summary>
 public static bool IsApplicationSpecific(this JpegSegmentType type) => type >= JpegSegmentType.App0 && type <= JpegSegmentType.AppF;
 public IReadOnlyList<Directory> ReadJpegSegments(IEnumerable<byte[]> segments, JpegSegmentType segmentType)
     => segments.Select(segmentBytes => Extract(segmentBytes, segmentType)).ToList();
 /// <summary>Returns the count of segment data byte arrays stored for a given segment type.</summary>
 /// <param name="segmentType">identifies the required segment</param>
 /// <returns>the segment count (zero if no segments exist).</returns>
 public int GetSegmentCount(JpegSegmentType segmentType)
 {
     return GetSegmentList(segmentType)?.Count ?? 0;
 }
Exemple #47
0
 public virtual void ReadJpegSegments([NotNull] Iterable <sbyte[]> segments, [NotNull] Com.Drew.Metadata.Metadata metadata, [NotNull] JpegSegmentType segmentType)
 {
     System.Diagnostics.Debug.Assert((segmentType == JpegSegmentType.App1));
     foreach (sbyte[] segmentBytes in segments)
     {
         // Filter any segments containing unexpected preambles
         if (segmentBytes.Length < JpegSegmentPreamble.Length || !Sharpen.Runtime.GetStringForBytes(segmentBytes, 0, JpegSegmentPreamble.Length).Equals(JpegSegmentPreamble))
         {
             continue;
         }
         Extract(new ByteArrayReader(segmentBytes), metadata, JpegSegmentPreamble.Length);
     }
 }
 /// <summary>Version specifically for dealing with XMP found in JPEG segments.</summary>
 /// <remarks>
 /// Version specifically for dealing with XMP found in JPEG segments. This form of XMP has a peculiar preamble, which
 /// must be removed before parsing the XML.
 /// </remarks>
 /// <param name="segments">The byte array from which the metadata should be extracted.</param>
 /// <param name="metadata">
 /// The
 /// <see cref="Com.Drew.Metadata.Metadata"/>
 /// object into which extracted values should be merged.
 /// </param>
 /// <param name="segmentType">
 /// The
 /// <see cref="Com.Drew.Imaging.Jpeg.JpegSegmentType"/>
 /// being read.
 /// </param>
 public virtual void ReadJpegSegments([NotNull] Iterable <sbyte[]> segments, [NotNull] Com.Drew.Metadata.Metadata metadata, [NotNull] JpegSegmentType segmentType)
 {
     foreach (sbyte[] segmentBytes in segments)
     {
         // XMP in a JPEG file has an identifying preamble which is not valid XML
         int preambleLength = XmpJpegPreamble.Length;
         if (segmentBytes.Length < preambleLength || !Sharpen.Runtime.EqualsIgnoreCase(XmpJpegPreamble, Sharpen.Runtime.GetStringForBytes(segmentBytes, 0, preambleLength)))
         {
             continue;
         }
         sbyte[] xmlBytes = new sbyte[segmentBytes.Length - preambleLength];
         System.Array.Copy(segmentBytes, preambleLength, xmlBytes, 0, xmlBytes.Length);
         Extract(xmlBytes, metadata);
     }
 }