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); }
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)); }