ProcessJpegSegmentData(IEnumerable <IJpegSegmentMetadataReader> readers, JpegSegmentData segmentData)
 {
     // Pass the appropriate byte arrays to each reader.
     return((from reader in readers
             from segmentType in reader.GetSegmentTypes()
             from directory in reader.ReadJpegSegments(segmentData.GetSegments(segmentType), segmentType)
             select directory)
            .ToList());
 }
 public void TestContainsSegment()
 {
     var segmentData = new JpegSegmentData();
     var segmentType = JpegSegmentType.App3;
     var segmentBytes = new byte[] { 1, 2, 3 };
     Assert.True(!segmentData.ContainsSegment(segmentType));
     segmentData.AddSegment(segmentType, segmentBytes);
     Assert.True(segmentData.ContainsSegment(segmentType));
 }
 public void TestAddAndGetSegment()
 {
     var segmentData = new JpegSegmentData();
     var segmentType = JpegSegmentType.App3;
     var segmentBytes = new byte[] { 1, 2, 3 };
     segmentData.AddSegment(segmentType, segmentBytes);
     Assert.Equal(1, segmentData.GetSegmentCount(segmentType));
     Assert.Equal(segmentBytes, segmentData.GetSegment(segmentType));
 }
 public void TestSegmentWithMultipleOccurrences()
 {
     var segmentData = new JpegSegmentData();
     var segmentType = JpegSegmentType.App3;
     var segmentBytes1 = new byte[] { 1, 2, 3 };
     var segmentBytes2 = new byte[] { 3, 2, 1 };
     segmentData.AddSegment(segmentType, segmentBytes1);
     segmentData.AddSegment(segmentType, segmentBytes2);
     Assert.Equal(2, segmentData.GetSegmentCount(segmentType));
     Assert.Equal(segmentBytes1, segmentData.GetSegment(segmentType));
     Assert.Equal(segmentBytes2, segmentData.GetSegment(segmentType, occurrence: 1));
 }
 public void TestAddingMultipleSegments()
 {
     var segmentData = new JpegSegmentData();
     var segmentType1 = JpegSegmentType.App3;
     var segmentType2 = JpegSegmentType.App4;
     var segmentBytes1 = new byte[] { 1, 2, 3 };
     var segmentBytes2 = new byte[] { 3, 2, 1 };
     segmentData.AddSegment(segmentType1, segmentBytes1);
     segmentData.AddSegment(segmentType2, segmentBytes2);
     Assert.Equal(1, segmentData.GetSegmentCount(segmentType1));
     Assert.Equal(1, segmentData.GetSegmentCount(segmentType2));
     Assert.Equal(segmentBytes1, segmentData.GetSegment(segmentType1));
     Assert.Equal(segmentBytes2, segmentData.GetSegment(segmentType2));
 }
 public void TestRemoveSegment()
 {
     var segmentData = new JpegSegmentData();
     var segmentType = JpegSegmentType.App3;
     var segmentBytes1 = new byte[] { 1, 2, 3 };
     var segmentBytes2 = new byte[] { 3, 2, 1 };
     segmentData.AddSegment(segmentType, segmentBytes1);
     segmentData.AddSegment(segmentType, segmentBytes2);
     Assert.Equal(2, segmentData.GetSegmentCount(segmentType));
     Assert.True(segmentData.ContainsSegment(segmentType));
     Assert.Equal(segmentBytes1, segmentData.GetSegment(segmentType));
     segmentData.RemoveAllSegments(segmentType);
     Assert.True(!segmentData.ContainsSegment(segmentType));
     Assert.Equal(0, segmentData.GetSegmentCount(segmentType));
 }
        private static void SaveSegmentFiles(string jpegFilePath, JpegSegmentData segmentData)
        {
            foreach (var segmentType in segmentData.GetSegmentTypes())
            {
                IList<byte[]> segments = segmentData.GetSegments(segmentType).ToList();

                if (segments.Count == 0)
                    continue;

                var format = segments.Count > 1 ? "{0}.{1}.{2}" : "{0}.{1}";

                for (var i = 0; i < segments.Count; i++)
                {
                    var outputFilePath = string.Format(format, jpegFilePath, segmentType.ToString().ToLower(), i);

                    Console.Out.WriteLine("Writing: " + outputFilePath);
                    File.WriteAllBytes(outputFilePath, segments[i]);
                }
            }
        }
     ProcessJpegSegmentData(IEnumerable<IJpegSegmentMetadataReader> readers, JpegSegmentData segmentData)
 {
     // Pass the appropriate byte arrays to each reader.
     return (from reader in readers
             from segmentType in reader.GetSegmentTypes()
             from directory in reader.ReadJpegSegments(segmentData.GetSegments(segmentType), segmentType)
             select directory)
             .ToList();
 }
        public static JpegSegmentData ReadSegments([NotNull] SequentialReader reader, [CanBeNull] ICollection<JpegSegmentType> segmentTypes = null)
        {
            // Must be big-endian
            Debug.Assert(reader.IsMotorolaByteOrder);

            // first two bytes should be JPEG magic number
            var magicNumber = reader.GetUInt16();

            if (magicNumber != 0xFFD8)
                throw new JpegProcessingException($"JPEG data is expected to begin with 0xFFD8 (ÿØ) not 0x{magicNumber:X4}");

            var segmentData = new JpegSegmentData();
            do
            {
                // Find the segment marker. Markers are zero or more 0xFF bytes, followed
                // by a 0xFF and then a byte not equal to 0x00 or 0xFF.
                var segmentIdentifier = reader.GetByte();
                var segmentTypeByte = reader.GetByte();

                // Read until we have a 0xFF byte followed by a byte that is not 0xFF or 0x00
                while (segmentIdentifier != 0xFF || segmentTypeByte == 0xFF || segmentTypeByte == 0)
                {
                    segmentIdentifier = segmentTypeByte;
                    segmentTypeByte = reader.GetByte();
                }

                var segmentType = (JpegSegmentType)segmentTypeByte;

                if (segmentType == JpegSegmentType.Sos)
                {
                    // The 'Start-Of-Scan' segment's length doesn't include the image data, instead would
                    // have to search for the two bytes: 0xFF 0xD9 (EOI).
                    // It comes last so simply return at this point
                    return segmentData;
                }

                if (segmentType == JpegSegmentType.Eoi)
                {
                    // the 'End-Of-Image' segment -- this should never be found in this fashion
                    return segmentData;
                }

                // next 2-bytes are <segment-size>: [high-byte] [low-byte]
                var segmentLength = (int)reader.GetUInt16();

                // segment length includes size bytes, so subtract two
                segmentLength -= 2;

                if (segmentLength < 0)
                    throw new JpegProcessingException("JPEG segment size would be less than zero");

                // Check whether we are interested in this segment
                if (segmentTypes == null || segmentTypes.Contains(segmentType))
                {
                    var segmentBytes = reader.GetBytes(segmentLength);
                    Debug.Assert(segmentLength == segmentBytes.Length);
                    segmentData.AddSegment(segmentType, segmentBytes);
                }
                else
                {
                    // Some of the JPEG is truncated, so just return what data we've already gathered
                    if (!reader.TrySkip(segmentLength))
                    {
                        return segmentData;
                    }
                }
            }
            while (true);
        }
Example #10
0
        public static JpegSegmentData ReadSegments([NotNull] SequentialReader reader, [CanBeNull] ICollection <JpegSegmentType> segmentTypes = null)
        {
            // Must be big-endian
            Debug.Assert(reader.IsMotorolaByteOrder);

            // first two bytes should be JPEG magic number
            var magicNumber = reader.GetUInt16();

            if (magicNumber != 0xFFD8)
            {
                throw new JpegProcessingException($"JPEG data is expected to begin with 0xFFD8 (ÿØ) not 0x{magicNumber:X4}");
            }

            var segmentData = new JpegSegmentData();

            do
            {
                // Find the segment marker. Markers are zero or more 0xFF bytes, followed
                // by a 0xFF and then a byte not equal to 0x00 or 0xFF.
                var segmentIdentifier = reader.GetByte();

                // We must have at least one 0xFF byte
                if (segmentIdentifier != 0xFF)
                {
                    throw new JpegProcessingException($"Expected JPEG segment start identifier 0xFF, not 0x{segmentIdentifier:X2}");
                }

                // Read until we have a non-0xFF byte. This identifies the segment type.
                var segmentTypeByte = reader.GetByte();
                while (segmentTypeByte == 0xFF)
                {
                    segmentTypeByte = reader.GetByte();
                }

                if (segmentTypeByte == 0)
                {
                    throw new JpegProcessingException("Expected non-zero byte as part of JPEG marker identifier");
                }

                var segmentType = (JpegSegmentType)segmentTypeByte;

                if (segmentType == JpegSegmentType.Sos)
                {
                    // The 'Start-Of-Scan' segment's length doesn't include the image data, instead would
                    // have to search for the two bytes: 0xFF 0xD9 (EOI).
                    // It comes last so simply return at this point
                    return(segmentData);
                }

                if (segmentType == JpegSegmentType.Eoi)
                {
                    // the 'End-Of-Image' segment -- this should never be found in this fashion
                    return(segmentData);
                }

                // next 2-bytes are <segment-size>: [high-byte] [low-byte]
                var segmentLength = (int)reader.GetUInt16();

                // segment length includes size bytes, so subtract two
                segmentLength -= 2;

                if (segmentLength < 0)
                {
                    throw new JpegProcessingException("JPEG segment size would be less than zero");
                }

                // Check whether we are interested in this segment
                if (segmentTypes == null || segmentTypes.Contains(segmentType))
                {
                    var segmentBytes = reader.GetBytes(segmentLength);
                    Debug.Assert(segmentLength == segmentBytes.Length);
                    segmentData.AddSegment(segmentType, segmentBytes);
                }
                else
                {
                    // Some of the JPEG is truncated, so just return what data we've already gathered
                    if (!reader.TrySkip(segmentLength))
                    {
                        return(segmentData);
                    }
                }
            }while (true);
        }
 public void TestRemoveSegmentOccurrence()
 {
     var segmentData = new JpegSegmentData();
     var segmentType = JpegSegmentType.App3;
     var segmentBytes1 = new byte[] { 1, 2, 3 };
     var segmentBytes2 = new byte[] { 3, 2, 1 };
     segmentData.AddSegment(segmentType, segmentBytes1);
     segmentData.AddSegment(segmentType, segmentBytes2);
     Assert.Equal(2, segmentData.GetSegmentCount(segmentType));
     Assert.Equal(segmentBytes1, segmentData.GetSegment(segmentType));
     segmentData.RemoveSegmentOccurrence(segmentType, 0);
     Assert.Equal(segmentBytes2, segmentData.GetSegment(segmentType));
 }