Preparing for 3.2.3, removed Microsoft translate (unless you add your own BingApiId in the settings.xml file)

git-svn-id: https://subtitleedit.googlecode.com/svn/trunk@782 99eadd0c-20b8-1223-b5c4-2a2b2df33de2
This commit is contained in:
niksedk 2011-11-06 10:42:54 +00:00
parent 957f075867
commit 9ee3041007
12 changed files with 609 additions and 61 deletions

View File

@ -34,6 +34,8 @@
this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.groupBoxImageSettings = new System.Windows.Forms.GroupBox();
this.label1 = new System.Windows.Forms.Label();
this.comboBoxResolution = new System.Windows.Forms.ComboBox();
this.comboBoxHAlign = new System.Windows.Forms.ComboBox();
this.labelHorizontalAlign = new System.Windows.Forms.Label();
this.checkBoxAntiAlias = new System.Windows.Forms.CheckBox();
@ -51,8 +53,6 @@
this.labelImageResolution = new System.Windows.Forms.Label();
this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
this.subtitleListView1 = new Nikse.SubtitleEdit.Controls.SubtitleListView();
this.comboBoxResolution = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.groupBoxImageSettings.SuspendLayout();
this.SuspendLayout();
@ -128,6 +128,31 @@
this.groupBoxImageSettings.TabStop = false;
this.groupBoxImageSettings.Text = "Image settings";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(10, 81);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(51, 13);
this.label1.TabIndex = 26;
this.label1.Text = "Video res";
this.label1.Visible = false;
//
// comboBoxResolution
//
this.comboBoxResolution.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxResolution.FormattingEnabled = true;
this.comboBoxResolution.Items.AddRange(new object[] {
"1080p (1920x1080)",
"720p (1280x720)",
"480p (848x480)",
"PAL (720x576)",
"NTSC (720x480)"});
this.comboBoxResolution.Location = new System.Drawing.Point(100, 78);
this.comboBoxResolution.Name = "comboBoxResolution";
this.comboBoxResolution.Size = new System.Drawing.Size(121, 21);
this.comboBoxResolution.TabIndex = 25;
//
// comboBoxHAlign
//
this.comboBoxHAlign.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
@ -135,20 +160,22 @@
this.comboBoxHAlign.Items.AddRange(new object[] {
"Left",
"Center"});
this.comboBoxHAlign.Location = new System.Drawing.Point(100, 79);
this.comboBoxHAlign.Location = new System.Drawing.Point(100, 105);
this.comboBoxHAlign.Name = "comboBoxHAlign";
this.comboBoxHAlign.Size = new System.Drawing.Size(121, 21);
this.comboBoxHAlign.TabIndex = 23;
this.comboBoxHAlign.Visible = false;
this.comboBoxHAlign.SelectedIndexChanged += new System.EventHandler(this.comboBoxHAlign_SelectedIndexChanged);
//
// labelHorizontalAlign
//
this.labelHorizontalAlign.AutoSize = true;
this.labelHorizontalAlign.Location = new System.Drawing.Point(10, 82);
this.labelHorizontalAlign.Location = new System.Drawing.Point(10, 108);
this.labelHorizontalAlign.Name = "labelHorizontalAlign";
this.labelHorizontalAlign.Size = new System.Drawing.Size(30, 13);
this.labelHorizontalAlign.TabIndex = 22;
this.labelHorizontalAlign.Text = "Align";
this.labelHorizontalAlign.Visible = false;
//
// checkBoxAntiAlias
//
@ -360,30 +387,6 @@
this.subtitleListView1.View = System.Windows.Forms.View.Details;
this.subtitleListView1.SelectedIndexChanged += new System.EventHandler(this.subtitleListView1_SelectedIndexChanged);
//
// comboBoxResolution
//
this.comboBoxResolution.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxResolution.FormattingEnabled = true;
this.comboBoxResolution.Items.AddRange(new object[] {
"1080p (1920x1080)",
"720p (1280x720)",
"480p (848x480)",
"PAL (720x576)",
"NTSC (720x480)"});
this.comboBoxResolution.Location = new System.Drawing.Point(100, 106);
this.comboBoxResolution.Name = "comboBoxResolution";
this.comboBoxResolution.Size = new System.Drawing.Size(121, 21);
this.comboBoxResolution.TabIndex = 25;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(10, 109);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(51, 13);
this.label1.TabIndex = 26;
this.label1.Text = "Video res";
//
// ExportPngXml
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);

View File

@ -37,16 +37,30 @@ namespace Nikse.SubtitleEdit.Forms
{
SetupImageParameters();
saveFileDialog1.Title = "Choose Blu-ray sup file name...";
saveFileDialog1.DefaultExt = ".sup";
saveFileDialog1.AddExtension = true;
if (_exportType == "BLURAYSUP")
{
saveFileDialog1.Title = "Choose Blu-ray sup file name...";
saveFileDialog1.DefaultExt = "sup";
saveFileDialog1.AddExtension = true;
}
else if (_exportType == "VOBSUB")
{
saveFileDialog1.Title = "Choose Vobsub file name...";
saveFileDialog1.DefaultExt = "sub";
saveFileDialog1.AddExtension = true;
}
if (_exportType == "BLURAYSUP" && saveFileDialog1.ShowDialog(this) == DialogResult.OK ||
if (_exportType == "BLURAYSUP" && saveFileDialog1.ShowDialog(this) == DialogResult.OK ||
_exportType == "VOBSUB" && saveFileDialog1.ShowDialog(this) == DialogResult.OK ||
_exportType == "BDNXML" && folderBrowserDialog1.ShowDialog(this) == DialogResult.OK)
{
FileStream bluRaySupFile = null;
if (_exportType == "BLURAYSUP")
bluRaySupFile = new FileStream(saveFileDialog1.FileName, FileMode.Create);
FileStream binarySubtitleFile = null;
Nikse.SubtitleEdit.Logic.VobSub.VobSubWriter vobSubWriter = null;
if (_exportType == "BLURAYSUP")
binarySubtitleFile = new FileStream(saveFileDialog1.FileName, FileMode.Create);
else if (_exportType == "VOBSUB")
vobSubWriter = new Logic.VobSub.VobSubWriter(saveFileDialog1.FileName);
progressBar1.Value = 0;
progressBar1.Maximum = _subtitle.Paragraphs.Count-1;
@ -74,7 +88,7 @@ namespace Nikse.SubtitleEdit.Forms
width = 720;
height = 480;
}
const int border = 25;
int imagesSavedCount = 0;
StringBuilder sb = new StringBuilder();
@ -93,7 +107,11 @@ namespace Nikse.SubtitleEdit.Forms
brSub.Width = height;
brSub.Height = width;
byte[] buffer = Nikse.SubtitleEdit.Logic.BluRaySup.BluRaySupPicture.CreateSupFrame(brSub, bmp);
bluRaySupFile.Write(buffer, 0, buffer.Length);
binarySubtitleFile.Write(buffer, 0, buffer.Length);
}
else if (_exportType == "VOBSUB")
{
vobSubWriter.WriteParagraph(p, bmp);
}
else
{
@ -117,7 +135,13 @@ namespace Nikse.SubtitleEdit.Forms
progressBar1.Visible = false;
if (_exportType == "BLURAYSUP")
{
bluRaySupFile.Close();
binarySubtitleFile.Close();
MessageBox.Show(string.Format(Configuration.Settings.Language.Main.SavedSubtitleX, saveFileDialog1.FileName));
}
else if (_exportType == "VOBSUB")
{
vobSubWriter.CloseSubFile();
vobSubWriter.WriteIdxFile();
MessageBox.Show(string.Format(Configuration.Settings.Language.Main.SavedSubtitleX, saveFileDialog1.FileName));
}
else
@ -306,17 +330,15 @@ namespace Nikse.SubtitleEdit.Forms
return s;
}
internal void Initialize(Subtitle subtitle, string exportType)
internal void Initialize(Subtitle subtitle, string exportType, string fileName)
{
_exportType = exportType;
if (exportType == "BLURAYSUP")
{
this.Text = "Blu-ray SUP";
}
Text = "Blu-ray SUP";
else if (exportType == "VOBSUB")
Text = "VobSub (sub/idx)";
else
{
this.Text = Configuration.Settings.Language.ExportPngXml.Title;
}
Text = Configuration.Settings.Language.ExportPngXml.Title;
groupBoxImageSettings.Text = Configuration.Settings.Language.ExportPngXml.ImageSettings;
labelSubtitleFont.Text = Configuration.Settings.Language.ExportPngXml.FontFamily;
labelSubtitleFontSize.Text = Configuration.Settings.Language.ExportPngXml.FontSize;
@ -325,7 +347,7 @@ namespace Nikse.SubtitleEdit.Forms
buttonBorderColor.Text = Configuration.Settings.Language.ExportPngXml.BorderColor;
labelBorderWidth.Text = Configuration.Settings.Language.ExportPngXml.BorderWidth;
buttonExport.Text = Configuration.Settings.Language.ExportPngXml.ExportAllLines;
buttonCancel.Text = Configuration.Settings.Language.General.Cancel;
buttonCancel.Text = Configuration.Settings.Language.General.OK;
labelImageResolution.Text = string.Empty;
subtitleListView1.InitializeLanguage(Configuration.Settings.Language.General, Configuration.Settings);
Utilities.InitializeSubtitleFont(subtitleListView1);

View File

@ -19,7 +19,6 @@ namespace Nikse.SubtitleEdit.Forms
bool _breakTranslation;
bool _googleTranslate = true;
MicrosoftTranslationService.SoapService _microsoftTranslationService = null;
private const string BingApiId = "C2C2E9A508E6748F0494D68DFD92FAA1FF9B0BA4";
private bool _googleApiNotWorking = false;
public class ComboBoxItem
@ -286,7 +285,8 @@ namespace Nikse.SubtitleEdit.Forms
public static string TranslateTextViaApi(string input, string languagePair)
{
string googleApiKey = "ABQIAAAA4j5cWwa3lDH0RkZceh7PjBTDmNAghl5kWSyuukQ0wtoJG8nFBxRPlalq-gAvbeCXMCkmrysqjXV1Gw";
// string googleApiKey = "ABQIAAAA4j5cWwa3lDH0RkZceh7PjBTDmNAghl5kWSyuukQ0wtoJG8nFBxRPlalq-gAvbeCXMCkmrysqjXV1Gw";
string googleApiKey = Configuration.Settings.Tools.GoogleApiKey;
string[] arr = languagePair.Split('|');
string from = arr[0];
@ -785,6 +785,7 @@ namespace Nikse.SubtitleEdit.Forms
progressBar1.Visible = true;
labelPleaseWait.Visible = true;
int start = 0;
bool overQuota = false;
try
{
StringBuilder sb = new StringBuilder();
@ -792,23 +793,43 @@ namespace Nikse.SubtitleEdit.Forms
foreach (Paragraph p in _subtitle.Paragraphs)
{
string text = string.Format("<p>{0}</p>|", p.Text);
if ((HttpUtility.UrlEncode(sb.ToString() + text)).Length >= textMaxSize)
if (!overQuota)
{
FillTranslatedText(client.Translate(BingApiId, sb.ToString().Replace(Environment.NewLine, "<br />"), from, to, "text/plain", "general"), start, index - 1);
sb = new StringBuilder();
progressBar1.Refresh();
Application.DoEvents();
start = index;
if ((HttpUtility.UrlEncode(sb.ToString() + text)).Length >= textMaxSize)
{
try
{
FillTranslatedText(client.Translate(Configuration.Settings.Tools.MicrosoftBingApiId, sb.ToString().Replace(Environment.NewLine, "<br />"), from, to, "text/plain", "general"), start, index - 1);
}
catch (System.Web.Services.Protocols.SoapHeaderException exception)
{
MessageBox.Show("Sorry, MS is closing their free api: " + exception.Message);
overQuota = true;
}
sb = new StringBuilder();
progressBar1.Refresh();
Application.DoEvents();
start = index;
}
sb.Append(text);
}
sb.Append(text);
index++;
progressBar1.Value = index;
if (_breakTranslation)
break;
}
if (sb.Length > 0)
FillTranslatedText(client.Translate(BingApiId, sb.ToString().Replace(Environment.NewLine, "<br />"), from, to, "text/plain", "general"), start, index - 1);
if (sb.Length > 0 && !overQuota)
{
try
{
FillTranslatedText(client.Translate(Configuration.Settings.Tools.MicrosoftBingApiId, sb.ToString().Replace(Environment.NewLine, "<br />"), from, to, "text/plain", "general"), start, index - 1);
}
catch (System.Web.Services.Protocols.SoapHeaderException exception)
{
MessageBox.Show("Sorry, MS is closing their free api: " + exception.Message);
overQuota = true;
}
}
}
finally
{

View File

@ -88,6 +88,7 @@
this.toolStripMenuItemExport = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemExportPngXml = new System.Windows.Forms.ToolStripMenuItem();
this.bluraySupToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.vobSubsubidxToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemCavena890 = new System.Windows.Forms.ToolStripMenuItem();
this.eBUSTLToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.pACScreenElectronicsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -931,6 +932,7 @@
this.toolStripMenuItemExport.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItemExportPngXml,
this.bluraySupToolStripMenuItem,
this.vobSubsubidxToolStripMenuItem,
this.toolStripMenuItemCavena890,
this.eBUSTLToolStripMenuItem,
this.pACScreenElectronicsToolStripMenuItem,
@ -954,6 +956,14 @@
this.bluraySupToolStripMenuItem.Text = "Blu-ray sup...";
this.bluraySupToolStripMenuItem.Click += new System.EventHandler(this.bluraySupToolStripMenuItem_Click);
//
// vobSubsubidxToolStripMenuItem
//
this.vobSubsubidxToolStripMenuItem.Name = "vobSubsubidxToolStripMenuItem";
this.vobSubsubidxToolStripMenuItem.Size = new System.Drawing.Size(245, 22);
this.vobSubsubidxToolStripMenuItem.Text = "VobSub (sub/idx)...";
this.vobSubsubidxToolStripMenuItem.Visible = false;
this.vobSubsubidxToolStripMenuItem.Click += new System.EventHandler(this.vobSubsubidxToolStripMenuItem_Click);
//
// toolStripMenuItemCavena890
//
this.toolStripMenuItemCavena890.Name = "toolStripMenuItemCavena890";
@ -4050,6 +4060,7 @@
private System.Windows.Forms.ToolStripMenuItem plainTextToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem plainTextWithoutLineBreaksToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem bluraySupToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem vobSubsubidxToolStripMenuItem;
}
}

View File

@ -889,6 +889,9 @@ namespace Nikse.SubtitleEdit.Forms
toolStripMenuItemImportTimeCodes.Text = _language.Menu.File.ImportTimecodes;
toolStripMenuItemExport.Text = _language.Menu.File.Export;
toolStripMenuItemExportPngXml.Text = _language.Menu.File.ExportBdnXml;
if (!string.IsNullOrEmpty(_language.Menu.File.ExportBluRaySup)) //TODO: Remove in 3.3
bluraySupToolStripMenuItem.Text = _language.Menu.File.ExportBluRaySup;
vobSubsubidxToolStripMenuItem.Text = _language.Menu.File.ExportVobSub;
toolStripMenuItemCavena890.Text = _language.Menu.File.ExportCavena890;
eBUSTLToolStripMenuItem.Text = _language.Menu.File.ExportEbu;
pACScreenElectronicsToolStripMenuItem.Text = _language.Menu.File.ExportPac;
@ -982,6 +985,7 @@ namespace Nikse.SubtitleEdit.Forms
toolStripMenuItemAutoTranslate.Text = _language.Menu.AutoTranslate.Title;
translateByGoogleToolStripMenuItem.Text = _language.Menu.AutoTranslate.TranslatePoweredByGoogle;
translatepoweredByMicrosoftToolStripMenuItem.Text = _language.Menu.AutoTranslate.TranslatePoweredByMicrosoft;
translatepoweredByMicrosoftToolStripMenuItem.Visible = Configuration.Settings.Tools.MicrosoftBingApiId != "C2C2E9A508E6748F0494D68DFD92FAA1FF9B0BA4";
translateFromSwedishToDanishToolStripMenuItem.Text = _language.Menu.AutoTranslate.TranslateFromSwedishToDanish;
optionsToolStripMenuItem.Text = _language.Menu.Options.Title;
@ -11264,7 +11268,7 @@ namespace Nikse.SubtitleEdit.Forms
private void toolStripMenuItemExportPngXml_Click(object sender, EventArgs e)
{
ExportPngXml exportBdnXmlPng = new ExportPngXml();
exportBdnXmlPng.Initialize(_subtitle, "BDNXML");
exportBdnXmlPng.Initialize(_subtitle, "BDNXML", _fileName);
exportBdnXmlPng.ShowDialog(this);
}
@ -11632,7 +11636,14 @@ namespace Nikse.SubtitleEdit.Forms
private void bluraySupToolStripMenuItem_Click(object sender, EventArgs e)
{
ExportPngXml exportBdnXmlPng = new ExportPngXml();
exportBdnXmlPng.Initialize(_subtitle, "BLURAYSUP");
exportBdnXmlPng.Initialize(_subtitle, "BLURAYSUP", _fileName);
exportBdnXmlPng.ShowDialog(this);
}
private void vobSubsubidxToolStripMenuItem_Click(object sender, EventArgs e)
{
ExportPngXml exportBdnXmlPng = new ExportPngXml();
exportBdnXmlPng.Initialize(_subtitle, "VOBSUB", _fileName);
exportBdnXmlPng.ShowDialog(this);
}

View File

@ -681,7 +681,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAD2
CAAAAk1TRnQBSQFMAgEBAgEAAXgBDAF4AQwBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
CAAAAk1TRnQBSQFMAgEBAgEAAZABDAGQAQwBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA

View File

@ -785,6 +785,8 @@ namespace Nikse.SubtitleEdit.Logic
ImportTimecodes = "Import time codes...",
Export = "Export",
ExportBdnXml = "BDN xml/png...",
ExportBluRaySup = "Blu-ray sup...",
ExportVobSub = "VobSub (sub/idx)...",
ExportCavena890 = "Cavena 890...",
ExportEbu = "EBU stl...",
ExportPac = "PAC (Screen Electronics)...",

View File

@ -707,6 +707,8 @@
public string ImportTimecodes { get; set; }
public string Export { get; set; }
public string ExportBdnXml { get; set; }
public string ExportBluRaySup { get; set; }
public string ExportVobSub { get; set; }
public string ExportCavena890 { get; set; }
public string ExportEbu { get; set; }
public string ExportPac { get; set; }

View File

@ -54,6 +54,262 @@ namespace Nikse.SubtitleEdit.Logic
}
}
/// <summary>
/// Convert a x-color image to four colors, for e.g. dvd sub pictures.
/// Colors CAN be in any order but should not...
/// </summary>
/// <param name="background">Background color</param>
/// <param name="pattern">Pattern color, normally white or yellow</param>
/// <param name="emphasis1">Emphasis 1, normally black or near black (border)</param>
/// <param name="emphasis2">Emphasis 1, normally black or near black (anti-alias)</param>
public void ConverToFourColors(Color background, Color pattern, Color emphasis1, Color emphasis2)
{
byte[] backgroundBuffer = new byte[4];
backgroundBuffer[0] = (byte)background.B;
backgroundBuffer[1] = (byte)background.G;
backgroundBuffer[2] = (byte)background.R;
backgroundBuffer[3] = (byte)background.A;
byte[] patternBuffer = new byte[4];
patternBuffer[0] = (byte)pattern.B;
patternBuffer[1] = (byte)pattern.G;
patternBuffer[2] = (byte)pattern.R;
patternBuffer[3] = (byte)pattern.A;
byte[] emphasis1Buffer = new byte[4];
emphasis1Buffer[0] = (byte)emphasis1.B;
emphasis1Buffer[1] = (byte)emphasis1.G;
emphasis1Buffer[2] = (byte)emphasis1.R;
emphasis1Buffer[3] = (byte)emphasis1.A;
byte[] emphasis2Buffer = new byte[4];
emphasis2Buffer[0] = (byte)emphasis2.B;
emphasis2Buffer[1] = (byte)emphasis2.G;
emphasis2Buffer[2] = (byte)emphasis2.R;
emphasis2Buffer[3] = (byte)emphasis2.A;
for (int i = 0; i < _bitmapData.Length; i += 4)
{
int smallestDiff = 10000; // Math.Abs(backgroundBuffer[0] - _bitmapData[i]) + Math.Abs(backgroundBuffer[1] - _bitmapData[i + 1]) + Math.Abs(backgroundBuffer[2] - _bitmapData[i + 2]) + Math.Abs(backgroundBuffer[3] - _bitmapData[i + 3]);
byte[] buffer = backgroundBuffer;
if (backgroundBuffer[3] == 0 && _bitmapData[i+3] < 10) // transparent
smallestDiff = 0;
int patternDiff = Math.Abs(patternBuffer[0] - _bitmapData[i]) + Math.Abs(patternBuffer[1] - _bitmapData[i + 1]) + Math.Abs(patternBuffer[2] - _bitmapData[i + 2]) + Math.Abs(patternBuffer[3] - _bitmapData[i + 3]);
if (patternDiff < smallestDiff)
{
smallestDiff = patternDiff;
buffer = patternBuffer;
}
int emphasis1Diff = Math.Abs(emphasis1Buffer[0] - _bitmapData[i]) + Math.Abs(emphasis1Buffer[1] - _bitmapData[i + 1]) + Math.Abs(emphasis1Buffer[2] - _bitmapData[i + 2]) + Math.Abs(emphasis1Buffer[3] - _bitmapData[i + 3]);
if (emphasis1Diff < smallestDiff)
{
smallestDiff = emphasis1Diff;
buffer = emphasis1Buffer;
}
int emphasis2Diff = Math.Abs(emphasis2Buffer[0] - _bitmapData[i]) + Math.Abs(emphasis2Buffer[1] - _bitmapData[i + 1]) + Math.Abs(emphasis2Buffer[2] - _bitmapData[i + 2]) + Math.Abs(emphasis2Buffer[3] - _bitmapData[i + 3]);
if (emphasis2Diff < smallestDiff)
{
smallestDiff = emphasis2Diff;
buffer = emphasis2Buffer;
}
else if (_bitmapData[i + 3] >= 10 && _bitmapData[i + 3] < 90) // anti-alias
{
smallestDiff = emphasis2Diff;
buffer = emphasis2Buffer;
}
Buffer.BlockCopy(buffer, 0, _bitmapData, i, 4);
}
}
public byte[] RunLengthEncodeForDvd(Color background, Color pattern, Color emphasis1, Color emphasis2)
{
byte[] bufferEqual = new byte[Width * Height];
byte[] bufferUnEqual = new byte[Width * Height];
int indexBufferEqual = 0;
int indexBufferUnEqual = 0;
bool indexHalfNibble = false;
int lastColor = -1;
int count = -1;
_pixelAddress = -4;
for (int y = 0; y < Height; y++)
{
int index;
byte[] buffer;
if (y % 2 == 0)
{
index = indexBufferEqual;
buffer = bufferEqual;
}
else
{
index = indexBufferUnEqual;
buffer = bufferUnEqual;
}
indexHalfNibble = false;
lastColor = -1;
count = 0;
for (int x = 0; x < Width; x++)
{
int color = GetDvdColor(x, y, background, pattern, emphasis1, emphasis2);
if (lastColor == -1)
{
lastColor = color;
count = 1;
}
else if (lastColor == color)
{
count++;
}
else
{
WriteRLE(ref indexHalfNibble, lastColor, count, ref index, buffer);
lastColor = color;
count = 1;
}
}
if (count > 0)
WriteRLE(ref indexHalfNibble, lastColor, count, ref index, buffer);
if (indexHalfNibble)
index++;
if (y % 2 == 0)
{
indexBufferEqual = index;
bufferEqual = buffer;
}
else
{
indexBufferUnEqual = index;
bufferUnEqual = buffer;
}
}
byte[] result = new byte[indexBufferEqual + indexBufferUnEqual];
Buffer.BlockCopy(bufferEqual, 0, result, 0, indexBufferEqual);
Buffer.BlockCopy(bufferUnEqual, 0, result, indexBufferEqual, indexBufferUnEqual);
return result;
}
private void WriteRLE(ref bool indexHalfNibble, int lastColor, int count, ref int index, byte[] buffer)
{
if (count <= Nikse.SubtitleEdit.Logic.VobSub.Helper.B00000011) // 1-3 repetitions
{
WriteOneNibble(buffer, count, lastColor, ref index, ref indexHalfNibble);
}
else if (count <= Nikse.SubtitleEdit.Logic.VobSub.Helper.B00001111) // 4-15 repetitions
{
WriteTwoNibbles(buffer, count, lastColor, ref index, indexHalfNibble);
}
else if (count <= Nikse.SubtitleEdit.Logic.VobSub.Helper.B00111111) // 4-15 repetitions
{
WriteThreeNibbles(buffer, count, lastColor, ref index, ref indexHalfNibble); // 16-63 repetitions
}
else // 64-255 repetitions
{
int factor = count / 255;
for (int i=0; i<factor; i++)
WriteFourNibbles(buffer, 0xff, lastColor, ref index, indexHalfNibble);
int rest = count % 255;
if (rest > 0)
WriteFourNibbles(buffer, rest, lastColor, ref index, indexHalfNibble);
}
}
private void WriteFourNibbles(byte[] buffer, int count, int color, ref int index, bool indexHalfNibble)
{
int n = (count << 2) + color;
if (indexHalfNibble)
{
index++;
byte firstNibble = (byte)(n >> 4);
buffer[index] = firstNibble;
index++;
byte secondNibble = (byte)((n & Nikse.SubtitleEdit.Logic.VobSub.Helper.B00001111) << 4);
buffer[index] = (byte)secondNibble;
}
else
{
byte firstNibble = (byte)(n >> 8);
buffer[index] = firstNibble;
index++;
byte secondNibble = (byte)(n & Nikse.SubtitleEdit.Logic.VobSub.Helper.B11111111);
buffer[index] = (byte)secondNibble;
}
}
private void WriteThreeNibbles(byte[] buffer, int count, int color, ref int index, ref bool indexHalfNibble)
{
byte n = (byte)((count << 2) + color);
if (indexHalfNibble)
{
index++;
buffer[index] = n;
}
else
{
buffer[index] = (byte)(n >> 4);
index++;
buffer[index] = (byte)(n << 4);
}
indexHalfNibble = !indexHalfNibble;
}
private void WriteTwoNibbles(byte[] buffer, int count, int color, ref int index, bool indexHalfNibble)
{
byte n = (byte)((count << 2) + color);
if (indexHalfNibble)
{
byte firstNibble = (byte)(n >> 4);
buffer[index] = (byte)(buffer[index] & firstNibble);
byte secondNibble = (byte)(n << 4);
index++;
buffer[index] = (byte)secondNibble;
}
else
{
buffer[index] = n;
index++;
}
}
private void WriteOneNibble(byte[] buffer, int count, int color, ref int index, ref bool indexHalfNibble)
{
byte n = (byte)((count << 2) + color);
if (indexHalfNibble)
{
buffer[index] = (byte)(buffer[index] & n);
index++;
}
else
{
buffer[index] = (byte)(n << 4);
}
indexHalfNibble = !indexHalfNibble;
}
private int GetDvdColor(int x, int y, Color background, Color pattern, Color emphasis1, Color emphasis2)
{
Color c = GetPixelNext();
if (emphasis2 == c)
return 3;
else if (emphasis1 == c)
return 2;
if (pattern == c)
return 1;
return 0;
}
public void Fill(Color color)
{
byte[] buffer = new byte[4];

View File

@ -79,6 +79,8 @@ namespace Nikse.SubtitleEdit.Logic
public bool SpellCheckAutoChangeNames { get; set; }
public bool OcrFixUseHardcodedRules { get; set; }
public string Interjections { get; set; }
public string MicrosoftBingApiId { get; set; }
public string GoogleApiKey { get; set; }
public ToolsSettings()
{
@ -91,6 +93,8 @@ namespace Nikse.SubtitleEdit.Logic
SpellCheckAutoChangeNames = true;
OcrFixUseHardcodedRules = true;
Interjections = "Ah;Ahh;Ahhh;Eh;Ehh;Ehhh;Hm;Hmm;Hmmm;Phew;Gah;Oh;Ohh;Ohhh;Ow;Oww;Owww;Ugh;Ughh;Uh;Uhh;Uhhh;Whew";
MicrosoftBingApiId = "C2C2E9A508E6748F0494D68DFD92FAA1FF9B0BA4";
GoogleApiKey = "ABQIAAAA4j5cWwa3lDH0RkZceh7PjBTDmNAghl5kWSyuukQ0wtoJG8nFBxRPlalq-gAvbeCXMCkmrysqjXV1Gw";
}
}
@ -880,6 +884,12 @@ namespace Nikse.SubtitleEdit.Logic
subNode = node.SelectSingleNode("Interjections");
if (subNode != null)
settings.Tools.Interjections = subNode.InnerText;
subNode = node.SelectSingleNode("MicrosoftBingApiId");
if (subNode != null)
settings.Tools.MicrosoftBingApiId = subNode.InnerText;
subNode = node.SelectSingleNode("GoogleApiKey");
if (subNode != null)
settings.Tools.GoogleApiKey = subNode.InnerText;
settings.SsaStyle = new Nikse.SubtitleEdit.Logic.SsaStyleSettings();
node = doc.DocumentElement.SelectSingleNode("SsaStyle");
@ -1373,6 +1383,8 @@ namespace Nikse.SubtitleEdit.Logic
textWriter.WriteElementString("SpellCheckAutoChangeNames", settings.Tools.SpellCheckAutoChangeNames.ToString());
textWriter.WriteElementString("OcrFixUseHardcodedRules", settings.Tools.OcrFixUseHardcodedRules.ToString());
textWriter.WriteElementString("Interjections", settings.Tools.Interjections);
textWriter.WriteElementString("MicrosoftBingApiId", settings.Tools.MicrosoftBingApiId);
textWriter.WriteElementString("GoogleApiKey", settings.Tools.GoogleApiKey);
textWriter.WriteEndElement();
textWriter.WriteStartElement("SsaStyle", "");

View File

@ -0,0 +1,207 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.IO;
namespace Nikse.SubtitleEdit.Logic.VobSub
{
public class VobSubWriter
{
/// <summary>
/// 14 bytes Mpeg 2 pack header
/// </summary>
private static byte[] Mpeg2PackHeaderBuffer =
{
0x00, 0x00, 0x01, // Start code
0xba, // MPEG-2 Pack ID
0x44, 0x02, 0xec, 0xdf, // System clock reference
0xfe, 0x57,
0x01, 0x89, 0xc3, // Program mux rate
0xf8, // stuffing byte
};
/// <summary>
/// 9 bytes packetized elementary stream header (PES)
/// </summary>
private static byte[] PacketizedElementaryStreamHeaderBuffer =
{
0x00, 0x00, 0x01, // Start code
0xbd, // bd = Private stream 1 (non MPEG audio, subpictures)
0x00, 0x00, // PES packet length
0x81, // Flags: PES scrambling control, PES priority, data alignment indicator, copyright, original or copy
0x81, // Flags: PTS DTS flags, ESCR flag, ES rate flag, DSM trick mode flag, additional copy info flag, PES CRC flag, PES extension flag
0x05, // PES header data length
};
/// <summary>
/// 5 bytes presentation time stamp (PTS)
/// </summary>
private static byte[] PresentationTimeStampBuffer =
{
0x21, // 0010 3=PTS 32..30 1
0x00, 0x01, // 15=PTS 29..15 1
0x00, 0x01, // 15=PTS 14..00 1
};
private string _subFileName;
private FileStream _subFile;
StringBuilder _idx = new StringBuilder();
public VobSubWriter(string subFileName)
{
_subFileName = subFileName;
_idx = CreateIdxHeader();
_subFile = new FileStream(subFileName, FileMode.Create);
}
public void WriteParagraph(Paragraph p, Bitmap bmp)
{
// timestamp: 00:00:33:900, filepos: 000000000
_idx.AppendLine(string.Format("timestamp: {0:00}:{1:00}:{2:00}:{3:000}, filepos: {4}", p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, p.StartTime.Milliseconds, _subFile.Position.ToString("X").PadLeft(9, '0')));
// write binary vobsub file (duration + image)
long start = _subFile.Position;
_subFile.Write(Mpeg2PackHeaderBuffer, 0, Mpeg2PackHeaderBuffer.Length);
NikseBitmap nbmp = new NikseBitmap(bmp);
nbmp.ConverToFourColors(Color.Transparent, Color.White, Color.FromArgb(200, 0, 0, 0), Color.FromArgb(200, 25, 25, 25));
var outBmp = nbmp.GetBitmap();
outBmp.Save(@"D:\download\-_-" + p.Number.ToString() + ".bmp");
bmp.Save(@"D:\download\-__" + p.Number.ToString() + ".bmp");
outBmp.Dispose();
var imageBuffer = nbmp.RunLengthEncodeForDvd(Color.Transparent, Color.White, Color.FromArgb(200, 0, 0, 0), Color.FromArgb(200, 25, 25, 25));
// PES size
int length = Mpeg2PackHeaderBuffer.Length + PacketizedElementaryStreamHeaderBuffer.Length + 10 + imageBuffer.Length;
PacketizedElementaryStreamHeaderBuffer[4] = (byte)(length / 256);
PacketizedElementaryStreamHeaderBuffer[5] = (byte)(length % 256);
_subFile.Write(PacketizedElementaryStreamHeaderBuffer, 0, PacketizedElementaryStreamHeaderBuffer.Length);
// PTS (timestamp)
FillPTS(p.StartTime);
_subFile.Write(PresentationTimeStampBuffer, 0, PresentationTimeStampBuffer.Length);
// HeaderDataLength = buffer[index + 8];
// language id
// int id = buffer[9 + HeaderDataLength];
// if (id >= 0x20 && id <= 0x40) // x3f 0r x40 ?
// SubPictureStreamId = id;
//}
for (long i = _subFile.Position - start; i < 0x800; i++) // 2048 packet size - pad with 0xff
_subFile.WriteByte(0xff);
}
/// <summary>
/// Write the 5 PTS bytes to buffer
/// </summary>
private void FillPTS(TimeCode timeCode)
{
string pre = "0011"; // 0011 or 0010 ?
// pre = "0010";
long newPts = (long)(timeCode.TotalMilliseconds); // TODO: Calculation from milliseconds
string bString = Convert.ToString(newPts, 2).PadLeft(33, '0');
string fiveBytesString = pre + bString.Substring(0, 3) + "1" + bString.Substring(3, 15) + "1" + bString.Substring(18, 15) + "1";
for (int i = 0; i < 5; i++)
{
byte b = Convert.ToByte(fiveBytesString.Substring((i * 8), 8), 2);
PresentationTimeStampBuffer[i] = b;
}
}
public void CloseSubFile()
{
if (_subFile != null)
_subFile.Close();
_subFile = null;
}
public void WriteIdxFile()
{
string idxFileName = _subFileName.Substring(0, _subFileName.Length - 3) + "idx";
System.IO.File.WriteAllText(idxFileName, _idx.ToString().Trim());
}
private StringBuilder CreateIdxHeader()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(@"# VobSub index file, v7 (do not modify this line!)
#
# To repair desyncronization, you can insert gaps this way:
# (it usually happens after vob id changes)
#
# delay: [sign]hh:mm:ss:ms
#
# Where:
# [sign]: +, - (optional)
# hh: hours (0 <= hh)
# mm/ss: minutes/seconds (0 <= mm/ss <= 59)
# ms: milliseconds (0 <= ms <= 999)
#
# Note: You can't position a sub before the previous with a negative value.
#
# You can also modify timestamps or delete a few subs you don't like.
# Just make sure they stay in increasing order.
# Settings
# Original frame size
size: 720x480
# Origin, relative to the upper-left corner, can be overloaded by aligment
org: 0, 0
# Image scaling (hor,ver), origin is at the upper-left corner or at the alignment coord (x, y)
scale: 100%, 100%
# Alpha blending
alpha: 100%
# Smoothing for very blocky images (use OLD for no filtering)
smooth: OFF
# In millisecs
fadein/out: 50, 50
# Force subtitle placement relative to (org.x, org.y)
align: OFF at LEFT TOP
# For correcting non-progressive desync. (in millisecs or hh:mm:ss:ms)
# Note: Not effective in DirectVobSub, use 'delay: ... ' instead.
time offset: 0
# ON: displays only forced subtitles, OFF: shows everything
forced subs: OFF
# The original palette of the DVD
palette: 000000, ffffff, 000000, 191919, 828282, 828282, 828282, ffffff, 828282, bababa, 828282, 828282, 828282, 828282, 828282, 828282
# Custom colors (transp idxs and the four colors)
custom colors: OFF, tridx: 0000, colors: 000000, 000000, 000000, 000000
# Language index in use
langidx: 0
# English
id: en, index: 0
# Decomment next line to activate alternative name in DirectVobSub / Windows Media Player 6.x
# alt: English
# Vob/Cell ID: 3, 1 (PTS: 0)");
return sb;
}
}
}

View File

@ -682,6 +682,7 @@
<Compile Include="Logic\VobSub\VobSubParser.cs" />
<Compile Include="Logic\VobSub\VobSubMergedPack.cs" />
<Compile Include="Logic\VobSub\VobSubPack.cs" />
<Compile Include="Logic\VobSub\VobSubWriter.cs" />
<Compile Include="Logic\WordSpellChecker.cs" />
<Compile Include="Logic\zlib\Adler32.cs" />
<Compile Include="Logic\zlib\Deflate.cs" />