Skip to content

Commit

Permalink
Fix Blu-ray sup files with overlapping subs being dropped - thx mwali…
Browse files Browse the repository at this point in the history
…mu :)

Fix #4392
(also fix bdsup in transport streams and mkv)
  • Loading branch information
niksedk committed Sep 28, 2020
1 parent 7c557f7 commit 94b5f9a
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 22 deletions.
3 changes: 2 additions & 1 deletion Changelog.txt
@@ -1,6 +1,6 @@
Subtitle Edit Changelog

3.5.17 (xth September 2020) BETA
3.5.17 (xth October 2020) BETA
* NEW:
* Add new subtitle formats - thx Holmgeir
* Add new subtitle (Excel) format - thx Jecy
Expand Down Expand Up @@ -50,6 +50,7 @@
* Netflix quality check: Customizable and new rules - thx OmrSi/Jan
* Make "Merge dialog" work when one line is selected - thx OmrSi
* FIXED:
* Fix drop of subs in bd .sup files with overlap - thx mwalimu
* Fix for overlap in "Tools -> Adjust durations" - thx Christian
* Fix bug in EBU STL ms to frames - thx Lucius Snow
* Fix some shortcuts being written to text box - thx rebawest
Expand Down
44 changes: 26 additions & 18 deletions libse/BluRaySup/BluRaySupParser.cs
Expand Up @@ -282,19 +282,27 @@ public Bitmap GetBitmap()
var r = Rectangle.Empty;
for (int ioIndex = 0; ioIndex < PcsObjects.Count; ioIndex++)
{
var ioRect = new Rectangle(PcsObjects[ioIndex].Origin, BitmapObjects[ioIndex][0].Size);
r = r.IsEmpty ? ioRect : Rectangle.Union(r, ioRect);
if (ioIndex < BitmapObjects.Count)
{
var ioRect = new Rectangle(PcsObjects[ioIndex].Origin, BitmapObjects[ioIndex][0].Size);
r = r.IsEmpty ? ioRect : Rectangle.Union(r, ioRect);
}
}

var mergedBmp = new Bitmap(r.Width, r.Height, PixelFormat.Format32bppArgb);
for (var ioIndex = 0; ioIndex < PcsObjects.Count; ioIndex++)
{
var offset = PcsObjects[ioIndex].Origin - new Size(r.Location);
using (var singleBmp = SupDecoder.DecodeImage(PcsObjects[ioIndex], BitmapObjects[ioIndex], PaletteInfos))
using (var gSideBySide = Graphics.FromImage(mergedBmp))
if (ioIndex < BitmapObjects.Count)
{
gSideBySide.DrawImage(singleBmp, offset.X, offset.Y);
var offset = PcsObjects[ioIndex].Origin - new Size(r.Location);
using (var singleBmp = SupDecoder.DecodeImage(PcsObjects[ioIndex], BitmapObjects[ioIndex], PaletteInfos))
using (var gSideBySide = Graphics.FromImage(mergedBmp))
{
gSideBySide.DrawImage(singleBmp, offset.X, offset.Y);
}
}
}

return mergedBmp;
}

Expand Down Expand Up @@ -372,7 +380,9 @@ public static List<PcsData> ParseBluRaySup(string fileName, StringBuilder log)
{
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return ParseBluRaySup(fs, log, false);
var lastPalettes = new Dictionary<int, List<PaletteInfo>>();
var lastBitmapObjects = new Dictionary<int, List<OdsData>>();
return ParseBluRaySup(fs, log, false, lastPalettes, lastBitmapObjects);
}
}

Expand Down Expand Up @@ -422,7 +432,7 @@ private static PcsObject ParsePcs(byte[] buffer, int offset)
// skipped: 8bit window_id_ref
// object_cropped_flag: 0x80, forced_on_flag = 0x040, 6bit reserved
int forcedCropped = buffer[14 + offset];
pcs.IsForced = ((forcedCropped & 0x40) == 0x40);
pcs.IsForced = (forcedCropped & 0x40) == 0x40;
pcs.Origin = new Point(BigEndianInt16(buffer, 15 + offset), BigEndianInt16(buffer, 17 + offset));
return pcs;
}
Expand Down Expand Up @@ -496,17 +506,17 @@ private static bool CompletePcs(PcsData pcs, Dictionary<int, List<OdsData>> bitm

pcs.PaletteInfos = new List<PaletteInfo>(palettes[pcs.PaletteId]);
pcs.BitmapObjects = new List<List<OdsData>>();
var found = false;
for (int index = 0; index < pcs.PcsObjects.Count; index++)
{
int objId = pcs.PcsObjects[index].ObjectId;
if (!bitmapObjects.ContainsKey(objId))
if (bitmapObjects.ContainsKey(objId))
{
return false;
pcs.BitmapObjects.Add(bitmapObjects[objId]);
found = true;
}

pcs.BitmapObjects.Add(bitmapObjects[objId]);
}
return true;
return found;
}

/// <summary>
Expand Down Expand Up @@ -591,13 +601,12 @@ private static OdsData ParseOds(byte[] buffer, SupSegment segment, bool forceFir
};
}

public static List<PcsData> ParseBluRaySup(Stream ms, StringBuilder log, bool fromMatroskaFile, Dictionary<int, List<PaletteInfo>> lastPalettes = null)
public static List<PcsData> ParseBluRaySup(Stream ms, StringBuilder log, bool fromMatroskaFile, Dictionary<int, List<PaletteInfo>> lastPalettes, Dictionary<int, List<OdsData>> bitmapObjects)
{
long position = ms.Position;
int segmentCount = 0;
var palettes = new Dictionary<int, List<PaletteInfo>>();
bool forceFirstOds = true;
var bitmapObjects = new Dictionary<int, List<OdsData>>();
PcsData latestPcs = null;
var pcsList = new List<PcsData>();
var headerBuffer = fromMatroskaFile ? new byte[3] : new byte[HeaderSize];
Expand Down Expand Up @@ -658,7 +667,7 @@ public static List<PcsData> ParseBluRaySup(Stream ms, StringBuilder log, bool fr
}
break;

case 0x15: // Image bitmap data
case 0x15: // Object Definition Segment (image bitmap data)
if (latestPcs != null)
{
#if DEBUG
Expand Down Expand Up @@ -744,8 +753,7 @@ public static List<PcsData> ParseBluRaySup(Stream ms, StringBuilder log, bool fr
int y = BigEndianInt16(buffer, 4 + offset);
int width = BigEndianInt16(buffer, 6 + offset);
int height = BigEndianInt16(buffer, 8 + offset);
log.AppendLine(string.Format("WinId: {4}, X: {0}, Y: {1}, Width: {2}, Height: {3}",
x, y, width, height, windowId));
log.AppendLine(string.Format("WinId: {4}, X: {0}, Y: {1}, Width: {2}, Height: {3}", x, y, width, height, windowId));
offset += 9;
}
}
Expand Down
Expand Up @@ -196,6 +196,8 @@ public void Parse(Stream ms, LoadTransportStreamCallback callback)
var sb = new StringBuilder();
var subList = new List<TransportStreamSubtitle>();
var offset = (long)(firstVideoMs ?? 0); // when to use firstMs ?
var lastPalettes = new Dictionary<int, List<PaletteInfo>>();
var lastBitmapObjects = new Dictionary<int, List<BluRaySupParser.OdsData>>();
for (var index = 0; index < list.Count; index++)
{
var item = list[index];
Expand All @@ -204,7 +206,7 @@ public void Parse(Stream ms, LoadTransportStreamCallback callback)
if (item.DataIdentifier == 0x80)
{
bdMs.Position = 0;
var bdList = BluRaySupParser.ParseBluRaySup(bdMs, sb, true);
var bdList = BluRaySupParser.ParseBluRaySup(bdMs, sb, true, lastPalettes, lastBitmapObjects);
if (bdList.Count > 0)
{
var startMs = currentList.First().PresentationTimestampToMilliseconds();
Expand Down
4 changes: 3 additions & 1 deletion src/Forms/BatchConvert.cs
Expand Up @@ -1662,6 +1662,8 @@ internal static List<BluRaySupParser.PcsData> LoadBluRaySupFromMatroska(Matroska
var subtitles = new List<BluRaySupParser.PcsData>();
var log = new StringBuilder();
var clusterStream = new MemoryStream();
var lastPalettes = new Dictionary<int, List<PaletteInfo>>();
var lastBitmapObjects = new Dictionary<int, List<BluRaySupParser.OdsData>>();
foreach (var p in sub)
{
byte[] buffer = p.GetData(track);
Expand All @@ -1675,7 +1677,7 @@ internal static List<BluRaySupParser.PcsData> LoadBluRaySupFromMatroska(Matroska
subtitles[subtitles.Count - 1].EndTime = (long)((p.Start - 1) * 90.0);
}
clusterStream.Position = 0;
var list = BluRaySupParser.ParseBluRaySup(clusterStream, log, true);
var list = BluRaySupParser.ParseBluRaySup(clusterStream, log, true, lastPalettes, lastBitmapObjects);
foreach (var sup in list)
{
sup.StartTime = (long)((p.Start - 1) * 90.0);
Expand Down
3 changes: 2 additions & 1 deletion src/Forms/Main.cs
Expand Up @@ -12438,6 +12438,7 @@ private bool LoadBluRaySubFromMatroska(MatroskaTrackInfo matroskaSubtitleInfo, M
var log = new StringBuilder();
var clusterStream = new MemoryStream();
var lastPalettes = new Dictionary<int, List<PaletteInfo>>();
var lastBitmapObjects = new Dictionary<int, List<BluRaySupParser.OdsData>>();
foreach (var p in sub)
{
byte[] buffer = p.GetData(matroskaSubtitleInfo);
Expand All @@ -12452,7 +12453,7 @@ private bool LoadBluRaySubFromMatroska(MatroskaTrackInfo matroskaSubtitleInfo, M
}

clusterStream.Position = 0;
var list = BluRaySupParser.ParseBluRaySup(clusterStream, log, true, lastPalettes);
var list = BluRaySupParser.ParseBluRaySup(clusterStream, log, true, lastPalettes, lastBitmapObjects);
foreach (var sup in list)
{
sup.StartTime = (long)((p.Start - 1) * 90.0);
Expand Down

0 comments on commit 94b5f9a

Please sign in to comment.