diff --git a/Changelog.txt b/Changelog.txt index c988905cde..ffaa0ea65e 100644 --- a/Changelog.txt +++ b/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 @@ -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 diff --git a/libse/BluRaySup/BluRaySupParser.cs b/libse/BluRaySup/BluRaySupParser.cs index 90a01d76ed..62e0e8a980 100644 --- a/libse/BluRaySup/BluRaySupParser.cs +++ b/libse/BluRaySup/BluRaySupParser.cs @@ -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; } @@ -372,7 +380,9 @@ public static List 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>(); + var lastBitmapObjects = new Dictionary>(); + return ParseBluRaySup(fs, log, false, lastPalettes, lastBitmapObjects); } } @@ -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; } @@ -496,17 +506,17 @@ private static bool CompletePcs(PcsData pcs, Dictionary> bitm pcs.PaletteInfos = new List(palettes[pcs.PaletteId]); pcs.BitmapObjects = new List>(); + 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; } /// @@ -591,13 +601,12 @@ private static OdsData ParseOds(byte[] buffer, SupSegment segment, bool forceFir }; } - public static List ParseBluRaySup(Stream ms, StringBuilder log, bool fromMatroskaFile, Dictionary> lastPalettes = null) + public static List ParseBluRaySup(Stream ms, StringBuilder log, bool fromMatroskaFile, Dictionary> lastPalettes, Dictionary> bitmapObjects) { long position = ms.Position; int segmentCount = 0; var palettes = new Dictionary>(); bool forceFirstOds = true; - var bitmapObjects = new Dictionary>(); PcsData latestPcs = null; var pcsList = new List(); var headerBuffer = fromMatroskaFile ? new byte[3] : new byte[HeaderSize]; @@ -658,7 +667,7 @@ public static List 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 @@ -744,8 +753,7 @@ public static List 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; } } diff --git a/libse/ContainerFormats/TransportStream/TransportStreamParser.cs b/libse/ContainerFormats/TransportStream/TransportStreamParser.cs index bebe6a4aa7..4107d4470e 100644 --- a/libse/ContainerFormats/TransportStream/TransportStreamParser.cs +++ b/libse/ContainerFormats/TransportStream/TransportStreamParser.cs @@ -196,6 +196,8 @@ public void Parse(Stream ms, LoadTransportStreamCallback callback) var sb = new StringBuilder(); var subList = new List(); var offset = (long)(firstVideoMs ?? 0); // when to use firstMs ? + var lastPalettes = new Dictionary>(); + var lastBitmapObjects = new Dictionary>(); for (var index = 0; index < list.Count; index++) { var item = list[index]; @@ -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(); diff --git a/src/Forms/BatchConvert.cs b/src/Forms/BatchConvert.cs index 765aa43e4c..7161327bae 100644 --- a/src/Forms/BatchConvert.cs +++ b/src/Forms/BatchConvert.cs @@ -1662,6 +1662,8 @@ internal static List LoadBluRaySupFromMatroska(Matroska var subtitles = new List(); var log = new StringBuilder(); var clusterStream = new MemoryStream(); + var lastPalettes = new Dictionary>(); + var lastBitmapObjects = new Dictionary>(); foreach (var p in sub) { byte[] buffer = p.GetData(track); @@ -1675,7 +1677,7 @@ internal static List 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); diff --git a/src/Forms/Main.cs b/src/Forms/Main.cs index 0706f0baad..4dcfa3d1fc 100644 --- a/src/Forms/Main.cs +++ b/src/Forms/Main.cs @@ -12438,6 +12438,7 @@ private bool LoadBluRaySubFromMatroska(MatroskaTrackInfo matroskaSubtitleInfo, M var log = new StringBuilder(); var clusterStream = new MemoryStream(); var lastPalettes = new Dictionary>(); + var lastBitmapObjects = new Dictionary>(); foreach (var p in sub) { byte[] buffer = p.GetData(matroskaSubtitleInfo); @@ -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);