Fix Blu-ray sup files with overlapping subs being dropped - thx mwalimu :)

Fix #4392
(also fix bdsup in transport streams and mkv)
This commit is contained in:
Nikolaj Olsson 2020-09-28 12:11:31 +02:00
parent 7c557f73b4
commit 94b5f9ae5b
5 changed files with 36 additions and 22 deletions

View File

@ -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

View File

@ -282,19 +282,27 @@ namespace Nikse.SubtitleEdit.Core.BluRaySup
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 @@ namespace Nikse.SubtitleEdit.Core.BluRaySup
{
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);
}
}
@ -422,7 +432,7 @@ namespace Nikse.SubtitleEdit.Core.BluRaySup
// 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 @@ namespace Nikse.SubtitleEdit.Core.BluRaySup
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>
@ -591,13 +601,12 @@ namespace Nikse.SubtitleEdit.Core.BluRaySup
};
}
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];
@ -658,7 +667,7 @@ namespace Nikse.SubtitleEdit.Core.BluRaySup
}
break;
case 0x15: // Image bitmap data
case 0x15: // Object Definition Segment (image bitmap data)
if (latestPcs != null)
{
#if DEBUG
@ -744,8 +753,7 @@ namespace Nikse.SubtitleEdit.Core.BluRaySup
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;
}
}

View File

@ -196,6 +196,8 @@ namespace Nikse.SubtitleEdit.Core.ContainerFormats.TransportStream
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];
@ -204,7 +206,7 @@ namespace Nikse.SubtitleEdit.Core.ContainerFormats.TransportStream
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();

View File

@ -1662,6 +1662,8 @@ namespace Nikse.SubtitleEdit.Forms
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);
@ -1675,7 +1677,7 @@ namespace Nikse.SubtitleEdit.Forms
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);

View File

@ -12438,6 +12438,7 @@ namespace Nikse.SubtitleEdit.Forms
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);
@ -12452,7 +12453,7 @@ namespace Nikse.SubtitleEdit.Forms
}
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);