diff --git a/libsup/WindowDefinition.cs b/libsup/WindowDefinition.cs
new file mode 100644
index 0000000..5718b7d
--- /dev/null
+++ b/libsup/WindowDefinition.cs
@@ -0,0 +1,85 @@
+using JetBrains.Annotations;
+using System;
+using System.IO;
+
+namespace libsup
+{
+ ///
+ /// A window
+ ///
+ [PublicAPI]
+ public sealed class WindowDefinition
+ {
+ ///
+ /// Gets the window identifier.
+ ///
+ ///
+ /// The window identifier.
+ ///
+ public byte WindowId { get; }
+ ///
+ /// Gets the window horizontal position.
+ ///
+ ///
+ /// The window horizontal position.
+ ///
+ public ushort WindowHorizontalPosition { get; }
+ ///
+ /// Gets the window vertical position.
+ ///
+ ///
+ /// The window vertical position.
+ ///
+ public ushort WindowVerticalPosition { get; }
+ ///
+ /// Gets the width of the window.
+ ///
+ ///
+ /// The width of the window.
+ ///
+ public ushort WindowWidth { get; }
+ ///
+ /// Gets the height of the window.
+ ///
+ ///
+ /// The height of the window.
+ ///
+ public ushort WindowHeight { get; }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ internal WindowDefinition()
+ {
+ // do nothing
+ }
+ internal WindowDefinition(byte[] bytes)
+ {
+ // Check for invalid amount of bytes in the given byte collection.
+ if (bytes.Length != 9)
+ {
+ throw new InvalidDataException(
+ "The given byte array has an invalid amount of data and cannot be parsed as a window item!");
+ }
+
+ // Map the byte values in the given collection to their corresponding properties.
+ WindowId = bytes[0];
+
+ var horizpos = bytes.Slice(1, 2);
+ var vertipos = bytes.Slice(3, 2);
+ var width = bytes.Slice(5, 2);
+ var height = bytes.Slice(7, 2);
+
+ if (!BitConverter.IsLittleEndian)
+ {
+ Array.Reverse(horizpos);
+ Array.Reverse(vertipos);
+ Array.Reverse(width);
+ Array.Reverse(height);
+ }
+ WindowHorizontalPosition = BitConverter.ToUInt16(horizpos, 0);
+ WindowVerticalPosition = BitConverter.ToUInt16(vertipos, 0);
+ WindowWidth = BitConverter.ToUInt16(width, 0);
+ WindowHeight = BitConverter.ToUInt16(height, 0);
+ }
+ }
+}
diff --git a/libsup/WindowDefinitionSegment.cs b/libsup/WindowDefinitionSegment.cs
index a849fa8..bbb71d1 100644
--- a/libsup/WindowDefinitionSegment.cs
+++ b/libsup/WindowDefinitionSegment.cs
@@ -1,6 +1,6 @@
-using System;
+using JetBrains.Annotations;
+using System.Collections.Immutable;
using System.IO;
-using JetBrains.Annotations;
namespace libsup
{
@@ -19,30 +19,19 @@ public sealed class WindowDefinitionSegment : SegmentDetail
public override SegmentType SegmentType => SegmentType.WDS;
///
- /// ID of this window.
+ /// Number of windows defined in this segment. Added support for multiple
+ /// windows based on the PGS spec. available here:
+ /// https://blog.thescorpius.com/index.php/2017/07/15/presentation-graphic-stream-sup-files-bluray-subtitle-format/
///
- public byte WindowId { get; }
+ public byte NumberOfWindows { get; internal set; } = 1;
///
- /// X offset from the top left pixel of the window in the screen.
+ /// Gets the windows.
///
- public ushort WindowHorizontalPosition { get; }
-
- ///
- /// Y offset from the top left pixel of the window in the screen.
- ///
- public ushort WindowVerticalPosition { get; }
-
- ///
- /// Width of the window.
- ///
- public ushort WindowWidth { get; }
-
- ///
- /// Height of the window.
- ///
- public ushort WindowHeight { get; }
-
+ ///
+ /// The windows.
+ ///
+ public ImmutableList Windows { get; }
///
public override object Clone()
{
@@ -50,16 +39,13 @@ public override object Clone()
}
///
- /// Create a clone of an existing .
+ /// Initializes a new instance of the class.
///
- /// The original .
+ /// The old.
private WindowDefinitionSegment(WindowDefinitionSegment old)
{
- WindowId = old.WindowId;
- WindowHorizontalPosition = old.WindowHorizontalPosition;
- WindowVerticalPosition = old.WindowVerticalPosition;
- WindowWidth = old.WindowWidth;
- WindowHeight = old.WindowHeight;
+ NumberOfWindows = old.NumberOfWindows;
+ Windows = ImmutableList.Empty.AddRange(old.Windows);
}
///
@@ -78,27 +64,12 @@ internal WindowDefinitionSegment(byte[] bytes)
}
// Read values into temporary byte arrays.
- var winid = bytes.Slice(0, 1);
- var horizpos = bytes.Slice(1, 2);
- var vertipos = bytes.Slice(3, 2);
- var width = bytes.Slice(5, 2);
- var height = bytes.Slice(7, 2);
-
- // Reverse the big-endian encoded arrays if our system is not a big-endian system.
- if (!BitConverter.IsLittleEndian)
+ var numWindows = bytes.Slice(0, 1);
+ Windows = ImmutableList.Empty;
+ for (var i = 1; i < bytes.Length; i += MinimumLength)
{
- Array.Reverse(horizpos);
- Array.Reverse(vertipos);
- Array.Reverse(width);
- Array.Reverse(height);
+ Windows = Windows.Add(new WindowDefinition(bytes.Slice(i, 9)));
}
-
- // Map the byte arrays into their corresponding property.
- WindowId = winid[0];
- WindowHorizontalPosition = BitConverter.ToUInt16(horizpos, 0);
- WindowVerticalPosition = BitConverter.ToUInt16(vertipos, 0);
- WindowWidth = BitConverter.ToUInt16(width, 0);
- WindowHeight = BitConverter.ToUInt16(height, 0);
}
}
}