diff --git a/Codecs/Image/Jpeg/JpegImage.cs b/Codecs/Image/Jpeg/JpegImage.cs
index c49edacb..f369a9f3 100644
--- a/Codecs/Image/Jpeg/JpegImage.cs
+++ b/Codecs/Image/Jpeg/JpegImage.cs
@@ -56,7 +56,7 @@ public static JpegImage FromStream(Stream stream)
case Jpeg.Markers.StartOfDifferentialProgressiveArithmeticFrame:
case Jpeg.Markers.StartOfProgressiveArithmeticFrame:
case Jpeg.Markers.StartOfProgressiveHuffmanFrame:
- case Jpeg.Markers.HeirarchicalProgression:
+ case Jpeg.Markers.HeirarchicalProgression:
switch (marker.FunctionCode)
{
case Jpeg.Markers.StartOfDifferentialProgressiveHuffmanFrame:
@@ -70,7 +70,7 @@ public static JpegImage FromStream(Stream stream)
StartOfFrame tag;
- if(marker.FunctionCode == Jpeg.Markers.HeirarchicalProgression)
+ if (marker.FunctionCode == Jpeg.Markers.HeirarchicalProgression)
{
tag = new HeirarchicalProgression(marker);
}
@@ -78,7 +78,7 @@ public static JpegImage FromStream(Stream stream)
{
tag = new StartOfFrame(marker);
}
-
+
int bitDepth = Binary.Clamp(Binary.BitsPerByte, Binary.BitsPerInteger, tag.P);
height = tag.Y;
width = tag.X;
@@ -110,7 +110,7 @@ public static JpegImage FromStream(Stream stream)
var mediaComponent = new JpegComponent((byte)quantizationTableNumber, (byte)componentId, bitsPerComponent);
mediaComponents[componentIndex] = mediaComponent;
-
+
remains -= frameComponent.Count;
}
@@ -127,12 +127,12 @@ public static JpegImage FromStream(Stream stream)
if (read < dataSegment.Count)
dataSegment = dataSegment.Slice(0, read);
break;
- }
+ }
case Jpeg.Markers.AppFirst:
case Jpeg.Markers.AppLast:
var app = new App(marker);
- if(app.MajorVersion >= 1 && app.MinorVersion >= 2)
+ if (app.MajorVersion >= 1 && app.MinorVersion >= 2)
{
var appExtension = new AppExtension(app);
thumbnailData = appExtension.ThumbnailData;
@@ -185,7 +185,7 @@ public void Save(Stream stream)
markerBuffer.Remove(Jpeg.Markers.QuantizationTable);
- foreach(var marker in markerBuffer.Values.Where(markerBuffer => Jpeg.Markers.IsApplicationMarker(markerBuffer.FunctionCode)))
+ foreach (var marker in markerBuffer.Values.Where(markerBuffer => Jpeg.Markers.IsApplicationMarker(markerBuffer.FunctionCode)))
{
WriteMarker(stream, marker);
@@ -222,8 +222,11 @@ public void Save(Stream stream)
// Write the image data
stream.Write(Data.Array, Data.Offset, Data.Count);
- // Write the EOI marker
- WriteEmptyMarker(stream, Jpeg.Markers.EndOfInformation);
+ if (Data[Data.Count - 1] != Jpeg.Markers.EndOfInformation)
+ {
+ // Write the EOI marker
+ WriteEmptyMarker(stream, Jpeg.Markers.EndOfInformation);
+ }
}
private void WriteStartOfFrame(byte functionCode, Stream stream)
diff --git a/Codecs/Image/Jpeg/JpegUnitTests.cs b/Codecs/Image/Jpeg/JpegUnitTests.cs
index 1aa720d1..8f0fdd6d 100644
--- a/Codecs/Image/Jpeg/JpegUnitTests.cs
+++ b/Codecs/Image/Jpeg/JpegUnitTests.cs
@@ -208,9 +208,10 @@ private static void DumpMarker(Marker marker)
}
else
{
- Console.Write(BitConverter.ToString(marker.Data.Array, marker.Data.Offset, Math.Min(16, marker.Data.Count)));
+ using var slice = marker.Data;
+ Console.Write(BitConverter.ToString(slice.Array, slice.Offset, Math.Min(16, slice.Count)));
}
- if (marker.Data.Count > 16)
+ if (marker.DataLength > 16)
Console.WriteLine(" ...");
else
Console.WriteLine();
diff --git a/Codecs/Image/Jpeg/Marker.cs b/Codecs/Image/Jpeg/Marker.cs
index fa9216c3..b7429818 100644
--- a/Codecs/Image/Jpeg/Marker.cs
+++ b/Codecs/Image/Jpeg/Marker.cs
@@ -37,6 +37,8 @@ public int Length
public int MarkerLength => DataLength + 2;
+ public int DataOffset => Offset + PrefixBytes + LengthBytes;
+
public MemorySegment Data => Count > PrefixBytes + LengthBytes ? this.Slice(PrefixBytes + LengthBytes) : Empty;
public bool IsEmpty => DataLength == 0;
diff --git a/Codecs/Image/Jpeg/Markers/App.cs b/Codecs/Image/Jpeg/Markers/App.cs
index 13b38c0b..2a6058f7 100644
--- a/Codecs/Image/Jpeg/Markers/App.cs
+++ b/Codecs/Image/Jpeg/Markers/App.cs
@@ -11,20 +11,44 @@ public class App : Marker
public string Identifier
{
- get => Encoding.UTF8.GetString(Data.Array, Data.Offset, 5);
- set => Encoding.UTF8.GetBytes(value, 0, 5, Data.Array, Data.Offset);
+ get
+ {
+ using var slice = Data;
+ return Encoding.UTF8.GetString(slice.Array, slice.Offset, 5);
+ }
+ set
+ {
+ using var slice = Data;
+ Encoding.UTF8.GetBytes(value, 0, 5, slice.Array, slice.Offset);
+ }
}
public byte MajorVersion
{
- get => Data[6];
- set => Data[6] = value;
+ get
+ {
+ using var slice = Data;
+ return slice[6];
+ }
+ set
+ {
+ using var slice = Data;
+ slice[6] = value;
+ }
}
public byte MinorVersion
{
- get => Data[7];
- set => Data[7] = value;
+ get
+ {
+ using var slice = Data;
+ return slice[7];
+ }
+ set
+ {
+ using var slice = Data;
+ slice[7] = value;
+ }
}
public Version Version
@@ -39,44 +63,93 @@ public Version Version
public int DensityUnits
{
- get => Data[8];
- set => Data[8] = (byte)value;
+ get
+ {
+ using var slice = Data;
+ return slice[8];
+ }
+ set
+ {
+ using var slice = Data;
+ slice[8] = (byte)value;
+ }
}
public int XDensity
{
- get => Binary.Read16(Data.Array, Data.Offset + 9, Binary.IsLittleEndian);
- set => Binary.Write16(Data.Array, Data.Offset + 9, Binary.IsLittleEndian, (ushort)value);
+ get
+ {
+ using var slice = Data;
+ return Binary.Read16(slice.Array, slice.Offset + 9, Binary.IsLittleEndian);
+ }
+ set
+ {
+ using var slice = Data;
+ Binary.Write16(slice.Array, slice.Offset + 9, Binary.IsLittleEndian, (ushort)value);
+ }
}
public int YDensity
{
- get => Binary.Read16(Data.Array, Data.Offset + 11, Binary.IsLittleEndian);
- set => Binary.Write16(Data.Array, Data.Offset + 11, Binary.IsLittleEndian, (ushort)value);
+ get
+ {
+ using var slice = Data;
+ return Binary.Read16(slice.Array, slice.Offset + 11, Binary.IsLittleEndian);
+ }
+ set
+ {
+ using var slice = Data;
+ Binary.Write16(slice.Array, slice.Offset + 11, Binary.IsLittleEndian, (ushort)value);
+ }
}
public int XThumbnail
{
- get => Data[12];
- set => Data[12] = (byte)value;
+ get
+ {
+ using var slice = Data;
+ return slice[12];
+ }
+ set
+ {
+ using var slice = Data;
+ slice[12] = (byte)value;
+ }
}
public int YThumbnail
{
- get => Data[13];
- set => Data[13] = (byte)value;
+ get
+ {
+ using var slice = Data;
+ return slice[13];
+ }
+ set
+ {
+ using var slice = Data;
+ slice[13] = (byte)value;
+ }
}
public MemorySegment ThumbnailData
{
- get => Data.Slice(14);
- set => value.CopyTo(Data.Array, Data.Offset + 14);
+ get
+ {
+ using var slice = Data;
+ return slice.Slice(14);
+ }
+ set
+ {
+ using var slice = Data;
+ value.CopyTo(slice);
+ }
}
public App(byte functionCode, MemorySegment data)
: base(functionCode, Length + data.Count)
{
- data.CopyTo(Data.Array, Data.Offset + 14);
+ using var slice = Data;
+ data.CopyTo(slice);
}
public App(Marker marker) : base(marker)
diff --git a/Codecs/Image/Jpeg/Markers/AppExtension.cs b/Codecs/Image/Jpeg/Markers/AppExtension.cs
index 6eda60f3..4bc1900a 100644
--- a/Codecs/Image/Jpeg/Markers/AppExtension.cs
+++ b/Codecs/Image/Jpeg/Markers/AppExtension.cs
@@ -22,14 +22,14 @@ public AppExtension(MemorySegment data)
public string Identifier
{
- get => Encoding.UTF8.GetString(Data.Array, Data.Offset, 5);
- set => Encoding.UTF8.GetBytes(value, 0, 5, Data.Array, Data.Offset);
+ get => Encoding.UTF8.GetString(Array, DataOffset, 5);
+ set => Encoding.UTF8.GetBytes(value, 0, 5, Array, DataOffset);
}
public int ThumbnailFormat
{
- get => Data[6];
- set => Data[6] = (byte)value;
+ get => Array[DataOffset + 6];
+ set => Array[DataOffset + 6] = (byte)value;
}
public ThumbnailFormatType ThumbnailFormatType
@@ -40,7 +40,7 @@ public ThumbnailFormatType ThumbnailFormatType
public MemorySegment ThumbnailData
{
- get => Data.Slice(DataLength > 0 ? 6 : 0);
+ get => this.Slice(DataOffset + DataLength > 0 ? Length : 0);
set
{
using var slice = ThumbnailData;
diff --git a/Codecs/Image/Jpeg/Markers/Exp.cs b/Codecs/Image/Jpeg/Markers/Exp.cs
index d7d096d1..0b4df9bb 100644
--- a/Codecs/Image/Jpeg/Markers/Exp.cs
+++ b/Codecs/Image/Jpeg/Markers/Exp.cs
@@ -11,12 +11,12 @@ public int Eh
{
get
{
- var bitOffset = Binary.BytesToBits(Data.Offset);
+ var bitOffset = Binary.BytesToBits(DataOffset);
return (int)this.ReadBits(bitOffset, Binary.Four, Binary.BitOrder.MostSignificant);
}
set
{
- var bitOffset = Binary.BytesToBits(Data.Offset);
+ var bitOffset = Binary.BytesToBits(DataOffset);
this.WriteBits(ref bitOffset, Binary.Four, value, Binary.BitOrder.MostSignificant);
}
}
@@ -25,12 +25,12 @@ public int Ev
{
get
{
- var bitOffset = Binary.BytesToBits(Data.Offset) + Binary.Four;
+ var bitOffset = Binary.BytesToBits(DataOffset) + Binary.Four;
return (int)this.ReadBits(bitOffset, Binary.Four, Binary.BitOrder.MostSignificant);
}
set
{
- var bitOffset = Binary.BytesToBits(Data.Offset) + Binary.Four;
+ var bitOffset = Binary.BytesToBits(DataOffset) + Binary.Four;
this.WriteBits(ref bitOffset, Binary.Four, value, Binary.BitOrder.MostSignificant);
}
}
diff --git a/Codecs/Image/Jpeg/Markers/NumberOfLines.cs b/Codecs/Image/Jpeg/Markers/NumberOfLines.cs
index 350f7625..0216409f 100644
--- a/Codecs/Image/Jpeg/Markers/NumberOfLines.cs
+++ b/Codecs/Image/Jpeg/Markers/NumberOfLines.cs
@@ -11,8 +11,8 @@ public class NumberOfLines : Marker
///
public int Nl
{
- get => Binary.Read16(Array, Data.Offset + 2, Binary.IsLittleEndian);
- set => Binary.Write16(Array, Data.Offset + 2, Binary.IsLittleEndian, (ushort)value);
+ get => Binary.Read16(Array, DataOffset + 2, Binary.IsLittleEndian);
+ set => Binary.Write16(Array, DataOffset + 2, Binary.IsLittleEndian, (ushort)value);
}
public NumberOfLines(byte functionCode, int numberOfLines)
diff --git a/Codecs/Image/Jpeg/Markers/StartOfFrame.cs b/Codecs/Image/Jpeg/Markers/StartOfFrame.cs
index 2fa653ba..31ca1712 100644
--- a/Codecs/Image/Jpeg/Markers/StartOfFrame.cs
+++ b/Codecs/Image/Jpeg/Markers/StartOfFrame.cs
@@ -17,8 +17,8 @@ public class StartOfFrame : Marker
///
public int P
{
- get => Data[0];
- set => Data[0] = (byte)value;
+ get => Array[DataOffset];
+ set => Array[DataOffset] = (byte)value;
}
///
@@ -26,8 +26,8 @@ public int P
///
public int Y
{
- get => Binary.ReadU16(Array, Data.Offset + 1, Binary.IsLittleEndian);
- set => Binary.Write16(Array, Data.Offset + 1, Binary.IsLittleEndian, (ushort)value);
+ get => Binary.ReadU16(Array, DataOffset + 1, Binary.IsLittleEndian);
+ set => Binary.Write16(Array, DataOffset + 1, Binary.IsLittleEndian, (ushort)value);
}
///
@@ -35,8 +35,8 @@ public int Y
///
public int X
{
- get => Binary.ReadU16(Array, Data.Offset + 3, Binary.IsLittleEndian);
- set => Binary.Write16(Array, Data.Offset + 3, Binary.IsLittleEndian, (ushort)value);
+ get => Binary.ReadU16(Array, DataOffset + 3, Binary.IsLittleEndian);
+ set => Binary.Write16(Array, DataOffset + 3, Binary.IsLittleEndian, (ushort)value);
}
///
@@ -44,8 +44,8 @@ public int X
///
public int Nf
{
- get => Binary.ReadU8(Data.Array, Data.Offset + 5, Binary.IsBigEndian);
- set => Binary.Write8(Data.Array, Data.Offset + 5, Binary.IsBigEndian, (byte)value);
+ get => Binary.ReadU8(Array, DataOffset + 5, Binary.IsBigEndian);
+ set => Binary.Write8(Array, DataOffset + 5, Binary.IsBigEndian, (byte)value);
}
///
@@ -58,13 +58,12 @@ public int Nf
get
{
var offset = Length + index * FrameComponent.Length;
- using var slice = Data.Slice(offset, FrameComponent.Length);
- return new FrameComponent(slice);
+ return new FrameComponent(this.Slice(DataOffset + offset, FrameComponent.Length));
}
set
{
var offset = Length + index * FrameComponent.Length;
- using var slice = Data.Slice(offset, FrameComponent.Length);
+ using var slice = this.Slice(DataOffset + offset, FrameComponent.Length);
value.CopyTo(slice);
}
}
diff --git a/Codecs/Image/Jpeg/Markers/StartOfScan.cs b/Codecs/Image/Jpeg/Markers/StartOfScan.cs
index cc091dae..a195236f 100644
--- a/Codecs/Image/Jpeg/Markers/StartOfScan.cs
+++ b/Codecs/Image/Jpeg/Markers/StartOfScan.cs
@@ -28,8 +28,8 @@ public StartOfScan(MemorySegment data)
///
public int Ns
{
- get => Data[0];
- set => Data[0] = (byte)value;
+ get => Array[DataOffset];
+ set => Array[DataOffset] = (byte)value;
}
///
@@ -57,13 +57,13 @@ public IEnumerable Components
get
{
var offset = 1 + index * ScanComponentSelectorType.Length;
- using var slice = Data.Slice(offset, ScanComponentSelectorType.Length);
+ using var slice = this.Slice(DataOffset + offset, ScanComponentSelectorType.Length);
return new ScanComponentSelectorType(slice);
}
set
{
var offset = 1 + index * ScanComponentSelectorType.Length;
- using var slice = Data.Slice(offset, ScanComponentSelectorType.Length);
+ using var slice = this.Slice(DataOffset + offset, ScanComponentSelectorType.Length);
value.CopyTo(slice);
}
}
@@ -76,12 +76,12 @@ public int Ss
get
{
var offset = 1 + Ns * ScanComponentSelectorType.Length;
- return Data[offset];
+ return Array[DataOffset + offset];
}
set
{
var offset = 1 + Ns * ScanComponentSelectorType.Length;
- Data[offset] = (byte)value;
+ Array[DataOffset + offset] = (byte)value;
}
}
@@ -93,12 +93,12 @@ public int Se
get
{
var offset = Ns * ScanComponentSelectorType.Length + 1;
- return Data[offset];
+ return Array[DataOffset + offset];
}
set
{
var offset = Ns * ScanComponentSelectorType.Length + 1;
- Data[offset] = (byte)value;
+ Array[DataOffset + offset] = (byte)value;
}
}
@@ -110,12 +110,14 @@ public int Ah
get
{
var bitOffset = Binary.BytesToBits(1 + Ns * ScanComponentSelectorType.Length + 1 + 1);
- return (int)Binary.ReadBits(Data.Array, ref bitOffset, Binary.Four, Binary.BitOrder.MostSignificant);
+ using var slice = Data;
+ return (int)slice.ReadBits(ref bitOffset, Binary.Four, Binary.BitOrder.MostSignificant);
}
set
{
var bitOffset = Binary.BytesToBits(1 + Ns * ScanComponentSelectorType.Length + 1 + 1);
- Binary.WriteBits(Data.Array, ref bitOffset, Binary.Four, value, Binary.BitOrder.MostSignificant);
+ using var slice = Data;
+ slice.WriteBits(ref bitOffset, Binary.Four, value, Binary.BitOrder.MostSignificant);
}
}
@@ -127,12 +129,14 @@ public int Al
get
{
var bitOffset = Binary.BytesToBits(1 + Ns * ScanComponentSelectorType.Length + 1 + 1) + Binary.Four;
- return (int)Binary.ReadBits(Data.Array, ref bitOffset, Binary.Four, Binary.BitOrder.MostSignificant);
+ using var slice = Data;
+ return (int)slice.ReadBits(ref bitOffset, Binary.Four, Binary.BitOrder.MostSignificant);
}
set
{
var bitOffset = Binary.BytesToBits(1 + Ns * ScanComponentSelectorType.Length + 1 + 1) + Binary.Four;
- Binary.WriteBits(Data.Array, ref bitOffset, Binary.Four, value, Binary.BitOrder.MostSignificant);
+ using var slice = Data;
+ slice.WriteBits(ref bitOffset, Binary.Four, value, Binary.BitOrder.MostSignificant);
}
}
}
diff --git a/Codecs/Image/Jpeg/Markers/TextComment.cs b/Codecs/Image/Jpeg/Markers/TextComment.cs
index a47c8524..bb00f07c 100644
--- a/Codecs/Image/Jpeg/Markers/TextComment.cs
+++ b/Codecs/Image/Jpeg/Markers/TextComment.cs
@@ -8,8 +8,8 @@ public class TextComment : Marker
{
public string Comment
{
- get => Encoding.UTF8.GetString(Array, Data.Offset, Data.Count);
- set => Encoding.UTF8.GetBytes(value, 0, value.Length, Data.Array, Data.Offset);
+ get => Encoding.UTF8.GetString(Array, DataOffset, DataLength);
+ set => Encoding.UTF8.GetBytes(value, 0, value.Length, Array, DataOffset);
}
public TextComment(byte functionCode, string comment)