Working on improving vobsub...

git-svn-id: https://subtitleedit.googlecode.com/svn/trunk@645 99eadd0c-20b8-1223-b5c4-2a2b2df33de2
This commit is contained in:
niksedk 2011-09-17 13:19:52 +00:00
parent b3d1380622
commit bd9db00e64
6 changed files with 242 additions and 18 deletions

View File

@ -1411,10 +1411,18 @@ namespace Nikse.SubtitleEdit.Forms
return;
}
if (Path.GetExtension(fileName).ToLower() == ".sup" && IsBluRaySupFile(fileName))
if (Path.GetExtension(fileName).ToLower() == ".sup")
{
ImportAndOcrBluRaySup(fileName);
return;
if (IsBluRaySupFile(fileName))
{
ImportAndOcrBluRaySup(fileName);
return;
}
else if (IsSpDvdSupFile(fileName))
{
ImportAndOcrSpDvdSup(fileName);
return;
}
}
if (Path.GetExtension(fileName).ToLower() == ".mkv")
@ -6055,6 +6063,90 @@ namespace Nikse.SubtitleEdit.Forms
return (buffer[0] == 0x50 && buffer[1] == 0x47); // 80 + 71 - P G
}
private bool IsSpDvdSupFile(string subFileName)
{
byte[] buffer = new byte[SpHeader.SpHeaderLength];
var fs = new FileStream(subFileName, FileMode.Open, FileAccess.Read, FileShare.Read) { Position = 0 };
int bytesRead = fs.Read(buffer, 0, buffer.Length);
if (bytesRead == buffer.Length)
{
var header = new SpHeader(buffer);
if (header.Identifier == "SP" && header.NextBlockPosition > 4)
{
buffer = new byte[header.NextBlockPosition];
bytesRead = fs.Read(buffer, 0, buffer.Length);
if (bytesRead == buffer.Length)
{
buffer = new byte[SpHeader.SpHeaderLength];
bytesRead = fs.Read(buffer, 0, buffer.Length);
if (bytesRead == buffer.Length)
{
header = new SpHeader(buffer);
fs.Close();
return header.Identifier == "SP";
}
}
}
}
fs.Close();
return false;
}
private void ImportAndOcrSpDvdSup(string fileName)
{
var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read) { Position = 0 };
byte[] buffer = new byte[SpHeader.SpHeaderLength];
int bytesRead = fs.Read(buffer, 0, buffer.Length);
var header = new SpHeader(buffer);
var spList = new List<SpHeader>();
while (header.Identifier == "SP" && bytesRead > 0 && header.NextBlockPosition > 4)
{
buffer = new byte[header.NextBlockPosition];
bytesRead = fs.Read(buffer, 0, buffer.Length);
if (bytesRead == buffer.Length)
{
header.AddPicture(buffer);
spList.Add(header);
}
buffer = new byte[SpHeader.SpHeaderLength];
bytesRead = fs.Read(buffer, 0, buffer.Length);
header = new SpHeader(buffer);
}
fs.Close();
var vobSubOcr = new VobSubOcr();
vobSubOcr.Initialize(fileName, null, Configuration.Settings.VobSubOcr, spList);
if (vobSubOcr.ShowDialog(this) == DialogResult.OK)
{
MakeHistoryForUndo(_language.BeforeImportingVobSubFile);
FileNew();
_subtitle.Paragraphs.Clear();
SetCurrentFormat(new SubRip().FriendlyName);
_subtitle.WasLoadedWithFrameNumbers = false;
_subtitle.CalculateFrameNumbersFromTimeCodes(CurrentFrameRate);
foreach (Paragraph p in vobSubOcr.SubtitleFromOcr.Paragraphs)
{
_subtitle.Paragraphs.Add(p);
}
ShowSource();
SubtitleListview1.Fill(_subtitle, _subtitleAlternate);
_change = true;
_subtitleListViewIndex = -1;
SubtitleListview1.FirstVisibleIndex = -1;
SubtitleListview1.SelectIndexAndEnsureVisible(0);
_fileName = Path.ChangeExtension(vobSubOcr.FileName, ".srt");
SetTitle();
_converted = true;
Configuration.Settings.Save();
}
}
private void ImportAndOcrVobSubSubtitleNew(string fileName)
{
if (IsVobSubFile(fileName, true))
@ -7502,7 +7594,7 @@ namespace Nikse.SubtitleEdit.Forms
if (SubtitleListview1.IsAlternateTextColumnVisible && Configuration.Settings.General.ShowOriginalAsPreviewIfAvailable)
{
int index = -1;
if (SubtitleListview1.SelectedItems.Count > 0)
if (SubtitleListview1.SelectedItems.Count > 0 && _subtitle.Paragraphs.Count > 0)
{
int i = SubtitleListview1.SelectedItems[0].Index;
var p = Utilities.GetOriginalParagraph(i, _subtitle.Paragraphs[i], _subtitleAlternate.Paragraphs);

View File

@ -110,6 +110,9 @@ namespace Nikse.SubtitleEdit.Forms
List<Logic.BluRaySup.BluRaySupPicture> _bluRaySubtitles;
Nikse.SubtitleEdit.Logic.BluRaySup.BluRaySupPalette _defaultPaletteInfo;
// SP list
List<SpHeader> _spList;
string _lastLine;
string _languageId;
@ -451,9 +454,7 @@ namespace Nikse.SubtitleEdit.Forms
if (ChooseLanguage.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
{
_vobSubMergedPackist = ChooseLanguage.SelectedVobSubMergedPacks;
SetTesseractLanguageFromLanguageString(ChooseLanguage.SelectedLanguageString);
}
else
{
@ -683,8 +684,26 @@ namespace Nikse.SubtitleEdit.Forms
Color pattern;
Color emphasis1;
Color emphasis2;
if (_bdnXmlSubtitle != null)
if (_spList != null)
{
Bitmap spBmp;
if (checkBoxCustomFourColors.Checked)
{
GetCustomColors(out background, out pattern, out emphasis1, out emphasis2);
spBmp = _spList[index].Picture.GetBitmap(null, background, pattern, emphasis1, emphasis2, true);
if (checkBoxAutoTransparentBackground.Checked)
spBmp.MakeTransparent();
return spBmp;
}
spBmp = _spList[index].Picture.GetBitmap(null, Color.Transparent, Color.Black, Color.White, Color.Black, false);
if (checkBoxAutoTransparentBackground.Checked)
spBmp.MakeTransparent();
return spBmp;
}
else if (_bdnXmlSubtitle != null)
{
if (index >= 0 && index < _bdnXmlSubtitle.Paragraphs.Count)
{
@ -716,7 +735,7 @@ namespace Nikse.SubtitleEdit.Forms
}
}
fbmp.UnlockImage();
}
}
if (checkBoxAutoTransparentBackground.Checked)
b.MakeTransparent();
return b;
@ -774,16 +793,20 @@ namespace Nikse.SubtitleEdit.Forms
private long GetSubtitleStartTimeMilliseconds(int index)
{
if (_bdnXmlSubtitle != null)
if (_spList != null)
return (long) (_spList[index].StartTime.TotalMilliseconds);
else if (_bdnXmlSubtitle != null)
return (long)_bdnXmlSubtitle.Paragraphs[index].StartTime.TotalMilliseconds;
else if (_bluRaySubtitlesOriginal != null)
return (_bluRaySubtitles[index].StartTime + 45) / 90;
else
else
return (long)_vobSubMergedPackist[index].StartTime.TotalMilliseconds;
}
private long GetSubtitleEndTimeMilliseconds(int index)
{
if (_spList != null)
return (long)(_spList[index].StartTime.TotalMilliseconds + _spList[index].Picture.Delay.TotalMilliseconds);
if (_bdnXmlSubtitle != null)
return (long)_bdnXmlSubtitle.Paragraphs[index].EndTime.TotalMilliseconds;
else if (_bluRaySubtitlesOriginal != null)
@ -794,7 +817,9 @@ namespace Nikse.SubtitleEdit.Forms
private int GetSubtitleCount()
{
if (_bdnXmlSubtitle != null)
if (_spList != null)
return _spList.Count;
else if (_bdnXmlSubtitle != null)
return _bdnXmlSubtitle.Paragraphs.Count;
else if (_bluRaySubtitlesOriginal != null)
return _bluRaySubtitles.Count;
@ -1565,7 +1590,20 @@ namespace Nikse.SubtitleEdit.Forms
private void FormVobSubOcr_Shown(object sender, EventArgs e)
{
if (_bdnXmlOriginal != null)
if (_spList != null)
{
checkBoxShowOnlyForced.Visible = false;
checkBoxUseTimeCodesFromIdx.Visible = false;
buttonOK.Enabled = true;
buttonCancel.Enabled = true;
buttonStartOcr.Enabled = true;
buttonStop.Enabled = false;
buttonNewCharacterDatabase.Enabled = true;
buttonEditCharacterDatabase.Enabled = true;
buttonStartOcr.Focus();
}
else if (_bdnXmlOriginal != null)
{
LoadBdnXml();
bool hasForcedSubtitles = false;
@ -2845,5 +2883,51 @@ namespace Nikse.SubtitleEdit.Forms
SubtitleListView1SelectedIndexChanged(null, null);
}
internal void Initialize(string fileName, List<Color> palette, VobSubOcrSettings vobSubOcrSettings, List<SpHeader> spList)
{
_spList = spList;
_useNewSubIdxCode = false;
buttonOK.Enabled = false;
buttonCancel.Enabled = false;
buttonStartOcr.Enabled = false;
buttonStop.Enabled = false;
buttonNewCharacterDatabase.Enabled = false;
buttonEditCharacterDatabase.Enabled = false;
labelStatus.Text = string.Empty;
progressBar1.Visible = false;
progressBar1.Maximum = 100;
progressBar1.Value = 0;
numericUpDownPixelsIsSpace.Value = vobSubOcrSettings.XOrMorePixelsMakesSpace;
_vobSubOcrSettings = vobSubOcrSettings;
InitializeModi();
InitializeTesseract();
LoadImageCompareCharacterDatabaseList();
_palette = palette;
if (_palette == null)
checkBoxCustomFourColors.Checked = true;
if (Configuration.Settings.VobSubOcr.LastOcrMethod == "BitmapCompare" && comboBoxOcrMethod.Items.Count > 1)
comboBoxOcrMethod.SelectedIndex = 1;
else if (Configuration.Settings.VobSubOcr.LastOcrMethod == "MODI" && comboBoxOcrMethod.Items.Count > 2)
comboBoxOcrMethod.SelectedIndex = 2;
else
comboBoxOcrMethod.SelectedIndex = 0;
FileName = fileName;
Text += " - " + Path.GetFileName(FileName);
foreach (SpHeader header in _spList)
{
Paragraph p = new Paragraph(string.Empty, header.StartTime.TotalMilliseconds, header.StartTime.TotalMilliseconds + header.Picture.Delay.TotalMilliseconds);
_subtitle.Paragraphs.Add(p);
}
subtitleListView1.Fill(_subtitle);
subtitleListView1.SelectIndexAndEnsureVisible(0);
}
}
}

View File

@ -301,6 +301,11 @@ namespace Nikse.SubtitleEdit.Logic.VobSub
return 0;
}
public static int GetLittleEndian32(byte[] buffer, int index)
{
return ((int)buffer[index + 3] << 24 | (int)buffer[index + 2] << 16 | (int)buffer[index + 1] << 8 | (int)buffer[index + 0]);
}
public static string GetBinaryString(byte[] buffer, int index, int count)
{
var sb = new StringBuilder();

View File

@ -0,0 +1,36 @@
using System;
namespace Nikse.SubtitleEdit.Logic.VobSub
{
public class SpHeader
{
public static int SpHeaderLength = 14;
public string Identifier { get; private set; }
public TimeSpan StartTime { get; private set; }
public int Unknown1 { get; private set; }
public int Unknown2 { get; private set; }
public int NextBlockPosition { get; private set; }
public int ControlSequencePosition { get; private set; }
public SubPicture Picture { get; private set; }
public SpHeader(byte[] buffer)
{
Identifier = System.Text.Encoding.ASCII.GetString(buffer, 0, 2);
int startMilliseconds = (int)Helper.GetLittleEndian32(buffer, 2) / 90;
StartTime = TimeSpan.FromMilliseconds(startMilliseconds);
NextBlockPosition = Helper.GetEndianWord(buffer, 10) -4;
ControlSequencePosition = Helper.GetEndianWord(buffer, 12) -4;
}
public SubPicture AddPicture(byte[] buffer)
{
Picture = new SubPicture(buffer, ControlSequencePosition, -4);
return Picture;
}
}
}

View File

@ -79,14 +79,14 @@ namespace Nikse.SubtitleEdit.Logic.VobSub
int imageBottomFieldDataAddress = 0;
bool bitmapGenerated = false;
double largestDelay = -999999;
int displayControlSequenceTableAddress = _startDisplayControlSequenceTableAddress;
int displayControlSequenceTableAddress = _startDisplayControlSequenceTableAddress - _pixelDataAddressOffset;
int lastDisplayControlSequenceTableAddress = 0;
displayControlSequenceTableAddresses.Add(displayControlSequenceTableAddress);
int commandIndex = 0;
while (displayControlSequenceTableAddress > lastDisplayControlSequenceTableAddress && displayControlSequenceTableAddress + 5 < _data.Length && commandIndex < _data.Length)
while (displayControlSequenceTableAddress > lastDisplayControlSequenceTableAddress && displayControlSequenceTableAddress + 1 < _data.Length && commandIndex < _data.Length)
{
int delayBeforeExecute = Helper.GetEndianWord(_data, displayControlSequenceTableAddress);
commandIndex = displayControlSequenceTableAddress + 4;
int delayBeforeExecute = Helper.GetEndianWord(_data, displayControlSequenceTableAddress + _pixelDataAddressOffset);
commandIndex = displayControlSequenceTableAddress + 4 + _pixelDataAddressOffset;
int command = _data[commandIndex];
int numberOfCommands = 0;
while (command != 0xFF && numberOfCommands < 1000 && commandIndex < _data.Length)
@ -168,6 +168,9 @@ namespace Nikse.SubtitleEdit.Logic.VobSub
break;
case (int)DisplayControlCommand.End: // FF (255) - Stop looping of Display Control Commands
break;
default:
commandIndex++;
break;
}
if (commandIndex >= _data.Length) // in case of bad files...
break;
@ -175,7 +178,10 @@ namespace Nikse.SubtitleEdit.Logic.VobSub
}
lastDisplayControlSequenceTableAddress = displayControlSequenceTableAddress;
displayControlSequenceTableAddress = Helper.GetEndianWord(_data, displayControlSequenceTableAddress + 2);
if (_pixelDataAddressOffset == -4)
displayControlSequenceTableAddress = Helper.GetEndianWord(_data, commandIndex+3);
else
displayControlSequenceTableAddress = Helper.GetEndianWord(_data, displayControlSequenceTableAddress + 2);
}
if (createBitmap && !bitmapGenerated) // StopDisplay not needed (delay will be zero - should be just before start of next subtitle)
bmp = GenerateBitmap(ImageDisplayArea, imageTopFieldDataAddress, imageBottomFieldDataAddress, fourColors);

View File

@ -644,6 +644,7 @@
<Compile Include="Logic\VobSub\IdxParagraph.cs" />
<Compile Include="Logic\VobSub\Mpeg2Header.cs" />
<Compile Include="Logic\VobSub\PacketizedElementaryStream.cs" />
<Compile Include="Logic\VobSub\SpHeader.cs" />
<Compile Include="Logic\VobSub\SubPicture.cs" />
<Compile Include="Logic\VobSub\VobSubParser.cs" />
<Compile Include="Logic\VobSub\VobSubMergedPack.cs" />