diff --git a/src/Forms/Main.Designer.cs b/src/Forms/Main.Designer.cs index c0d8161ad..6b79cf3b4 100644 --- a/src/Forms/Main.Designer.cs +++ b/src/Forms/Main.Designer.cs @@ -73,6 +73,7 @@ this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripMenuItemImportDvdSubtitles = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItemSubIdx = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItemImportBluRaySup = new System.Windows.Forms.ToolStripMenuItem(); this.matroskaImportStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItemManualAnsi = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItemImportText = new System.Windows.Forms.ToolStripMenuItem(); @@ -656,6 +657,7 @@ this.toolStripSeparator1, this.toolStripMenuItemImportDvdSubtitles, this.toolStripMenuItemSubIdx, + this.toolStripMenuItemImportBluRaySup, this.matroskaImportStripMenuItem, this.toolStripMenuItemManualAnsi, this.toolStripMenuItemImportText, @@ -742,6 +744,13 @@ this.toolStripMenuItemSubIdx.Text = "Import/OCR VobSub (sub/idx) subtitle..."; this.toolStripMenuItemSubIdx.Click += new System.EventHandler(this.ToolStripMenuItemSubIdxClick1); // + // toolStripMenuItemImportBluRaySup + // + this.toolStripMenuItemImportBluRaySup.Name = "toolStripMenuItemImportBluRaySup"; + this.toolStripMenuItemImportBluRaySup.Size = new System.Drawing.Size(334, 22); + this.toolStripMenuItemImportBluRaySup.Text = "Import/OCR BluRay sup file..."; + this.toolStripMenuItemImportBluRaySup.Click += new System.EventHandler(this.toolStripMenuItemImportBluRaySup_Click); + // // matroskaImportStripMenuItem // this.matroskaImportStripMenuItem.Name = "matroskaImportStripMenuItem"; @@ -3137,6 +3146,7 @@ private System.Windows.Forms.TrackBar trackBarWaveFormPosition; private System.Windows.Forms.Label labelVideoInfo; private System.Windows.Forms.ToolStripMenuItem showhideWaveFormToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemImportBluRaySup; } } diff --git a/src/Forms/Main.cs b/src/Forms/Main.cs index af8247b4c..ba3f4ef60 100644 --- a/src/Forms/Main.cs +++ b/src/Forms/Main.cs @@ -14,6 +14,7 @@ using Nikse.SubtitleEdit.Logic.Enums; using Nikse.SubtitleEdit.Logic.SubtitleFormats; using Nikse.SubtitleEdit.Logic.VideoPlayers; using Nikse.SubtitleEdit.Logic.VobSub; +using Nikse.SubtitleEdit.Logic.BluRaySup; namespace Nikse.SubtitleEdit.Forms { @@ -139,6 +140,8 @@ namespace Nikse.SubtitleEdit.Forms labelVideoInfo.Text = string.Empty; Text = Title; timeUpDownStartTime.TimeCode = new TimeCode(0, 0, 0, 0); + checkBoxAutoRepeatOn.Checked = Configuration.Settings.General.AutoRepeatOn; + checkBoxAutoContinue.Checked = Configuration.Settings.General.AutoContinueOn; SetFormatToSubRip(); @@ -450,6 +453,10 @@ namespace Nikse.SubtitleEdit.Forms toolStripMenuItemCompare.Text = _language.Menu.File.Compare; toolStripMenuItemImportDvdSubtitles.Text = _language.Menu.File.ImportOcrFromDvd; toolStripMenuItemSubIdx.Text = _language.Menu.File.ImportOcrVobSubSubtitle; + + //toolStripMenuItemImportBluRaySup.Visible = false; //TODO: add blu ray sup import/ocr + toolStripMenuItemImportBluRaySup.Text = _language.Menu.File.ImportBluRaySupFile; + matroskaImportStripMenuItem.Text = _language.Menu.File.ImportSubtitleFromMatroskaFile; toolStripMenuItemManualAnsi.Text = _language.Menu.File.ImportSubtitleWithManualChosenEncoding; toolStripMenuItemImportText.Text = _language.Menu.File.ImportText; @@ -843,8 +850,9 @@ namespace Nikse.SubtitleEdit.Forms fileName), Title, MessageBoxButtons.YesNoCancel) != DialogResult.Yes) return; } - - MakeHistoryForUndo(string.Format(_language.BeforeLoadOf, Path.GetFileName(fileName))); + + if (_subtitle.HistoryItems.Count > 0 || _subtitle.Paragraphs.Count > 0) + MakeHistoryForUndo(string.Format(_language.BeforeLoadOf, Path.GetFileName(fileName))); SubtitleFormat format = _subtitle.LoadSubtitle(fileName, out encoding, encoding); @@ -3454,6 +3462,9 @@ namespace Nikse.SubtitleEdit.Forms //TODO: save in adjust all lines ...Configuration.Settings.General.DefaultAdjustMilliseconds = (int)timeUpDownAdjust.TimeCode.TotalMilliseconds; + Configuration.Settings.General.AutoRepeatOn = checkBoxAutoRepeatOn.Checked; + Configuration.Settings.General.AutoContinueOn = checkBoxAutoContinue.Checked; + Configuration.Settings.Save(); } } @@ -4078,6 +4089,7 @@ namespace Nikse.SubtitleEdit.Forms _fileName = Path.ChangeExtension(vobSubOcr.FileName, ".srt"); Text = Title + " - " + _fileName; + _converted = true; Configuration.Settings.Save(); } @@ -4169,7 +4181,12 @@ namespace Nikse.SubtitleEdit.Forms private void Main_KeyDown(object sender, KeyEventArgs e) { - if (e.KeyCode == Keys.Right && e.Modifiers == Keys.Control) + if (e.Modifiers == Keys.Control && e.KeyCode == Keys.Z) + { + ShowHistoryforUndoToolStripMenuItemClick(null, null); + e.SuppressKeyPress = true; + } + else if (e.KeyCode == Keys.Right && e.Modifiers == Keys.Control) { if (!textBoxListViewText.Focused) { @@ -4282,6 +4299,13 @@ namespace Nikse.SubtitleEdit.Forms e.SuppressKeyPress = true; } } + else if (e.Modifiers == Keys.None && e.KeyCode == Keys.F6) + { + if (mediaPlayer.VideoPlayer != null) + { + GotoSubPositionAndPause(); + } + } else if (e.Modifiers == Keys.None && e.KeyCode == Keys.F7) { if (mediaPlayer.VideoPlayer != null) @@ -4324,6 +4348,7 @@ namespace Nikse.SubtitleEdit.Forms } else if (e.Modifiers == Keys.None && e.KeyCode == Keys.F12) { + StopAutoDuration(); buttonSetEnd_Click(null, null); e.SuppressKeyPress = true; } @@ -4347,6 +4372,7 @@ namespace Nikse.SubtitleEdit.Forms } else if (e.Modifiers == Keys.None && e.KeyCode == Keys.F12) { + StopAutoDuration(); buttonSetEnd_Click(null, null); e.SuppressKeyPress = true; } @@ -6291,5 +6317,58 @@ namespace Nikse.SubtitleEdit.Forms } } + private void toolStripMenuItemImportBluRaySup_Click(object sender, EventArgs e) + { + if (ContinueNewOrExit()) + { + openFileDialog1.Title = _language.OpenBluRaySupFile; + openFileDialog1.FileName = string.Empty; + openFileDialog1.Filter = _language.BluRaySupFiles + "|*.sup"; + if (openFileDialog1.ShowDialog(this) == DialogResult.OK) + { + ImportAndOcrBluRaySup(openFileDialog1.FileName); + } + } + } + + private void ImportAndOcrBluRaySup(string fileName) + { + StringBuilder log = new StringBuilder(); + var subtitles = BluRaySupParser.ParseBluRaySup(fileName, log); + if (subtitles.Count > 0) + { + var vobSubOcr = new VobSubOcr(); + vobSubOcr.Initialize(subtitles, Configuration.Settings.VobSubOcr); + vobSubOcr.FileName = Path.GetFileName(fileName); + if (vobSubOcr.ShowDialog(this) == DialogResult.OK) + { + MakeHistoryForUndo(_language.BeforeImportingBluRaySupFile); + + _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"); + Text = Title + " - " + _fileName; + _converted = true; + + Configuration.Settings.Save(); + } + } + } + + } } \ No newline at end of file diff --git a/src/Forms/Main.resx b/src/Forms/Main.resx index 94b65953e..21ead9cd3 100644 --- a/src/Forms/Main.resx +++ b/src/Forms/Main.resx @@ -291,47 +291,47 @@ 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 RK5CYII= diff --git a/src/Forms/OCRSpellCheck.Designer.cs b/src/Forms/OCRSpellCheck.Designer.cs index 1982fb971..6d1bb1973 100644 --- a/src/Forms/OCRSpellCheck.Designer.cs +++ b/src/Forms/OCRSpellCheck.Designer.cs @@ -63,7 +63,7 @@ // buttonAbort // this.buttonAbort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonAbort.Location = new System.Drawing.Point(512, 404); + this.buttonAbort.Location = new System.Drawing.Point(623, 442); this.buttonAbort.Name = "buttonAbort"; this.buttonAbort.Size = new System.Drawing.Size(85, 21); this.buttonAbort.TabIndex = 24; @@ -86,9 +86,9 @@ this.groupBoxSuggestions.Controls.Add(this.buttonUseSuggestionAlways); this.groupBoxSuggestions.Controls.Add(this.buttonUseSuggestion); this.groupBoxSuggestions.Controls.Add(this.listBoxSuggestions); - this.groupBoxSuggestions.Location = new System.Drawing.Point(320, 211); + this.groupBoxSuggestions.Location = new System.Drawing.Point(320, 249); this.groupBoxSuggestions.Name = "groupBoxSuggestions"; - this.groupBoxSuggestions.Size = new System.Drawing.Size(277, 187); + this.groupBoxSuggestions.Size = new System.Drawing.Size(388, 187); this.groupBoxSuggestions.TabIndex = 32; this.groupBoxSuggestions.TabStop = false; this.groupBoxSuggestions.Text = "Suggestions"; @@ -96,7 +96,7 @@ // buttonUseSuggestionAlways // this.buttonUseSuggestionAlways.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.buttonUseSuggestionAlways.Location = new System.Drawing.Point(180, 16); + this.buttonUseSuggestionAlways.Location = new System.Drawing.Point(291, 16); this.buttonUseSuggestionAlways.Name = "buttonUseSuggestionAlways"; this.buttonUseSuggestionAlways.Size = new System.Drawing.Size(87, 21); this.buttonUseSuggestionAlways.TabIndex = 33; @@ -107,7 +107,7 @@ // buttonUseSuggestion // this.buttonUseSuggestion.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.buttonUseSuggestion.Location = new System.Drawing.Point(95, 16); + this.buttonUseSuggestion.Location = new System.Drawing.Point(206, 16); this.buttonUseSuggestion.Name = "buttonUseSuggestion"; this.buttonUseSuggestion.Size = new System.Drawing.Size(79, 21); this.buttonUseSuggestion.TabIndex = 32; @@ -122,7 +122,7 @@ this.listBoxSuggestions.FormattingEnabled = true; this.listBoxSuggestions.Location = new System.Drawing.Point(6, 39); this.listBoxSuggestions.Name = "listBoxSuggestions"; - this.listBoxSuggestions.Size = new System.Drawing.Size(261, 134); + this.listBoxSuggestions.Size = new System.Drawing.Size(372, 134); this.listBoxSuggestions.TabIndex = 30; // // GroupBoxEditWord @@ -135,7 +135,7 @@ this.GroupBoxEditWord.Controls.Add(this.textBoxWord); this.GroupBoxEditWord.Controls.Add(this.buttonSkipOnce); this.GroupBoxEditWord.Controls.Add(this.buttonAddToNames); - this.GroupBoxEditWord.Location = new System.Drawing.Point(12, 211); + this.GroupBoxEditWord.Location = new System.Drawing.Point(12, 249); this.GroupBoxEditWord.Name = "GroupBoxEditWord"; this.GroupBoxEditWord.Size = new System.Drawing.Size(302, 187); this.GroupBoxEditWord.TabIndex = 33; @@ -217,7 +217,7 @@ this.groupBoxEditWholeText.Controls.Add(this.buttonSkipText); this.groupBoxEditWholeText.Controls.Add(this.buttonChangeWholeText); this.groupBoxEditWholeText.Controls.Add(this.textBoxWholeText); - this.groupBoxEditWholeText.Location = new System.Drawing.Point(12, 210); + this.groupBoxEditWholeText.Location = new System.Drawing.Point(12, 248); this.groupBoxEditWholeText.Name = "groupBoxEditWholeText"; this.groupBoxEditWholeText.Size = new System.Drawing.Size(302, 188); this.groupBoxEditWholeText.TabIndex = 37; @@ -261,7 +261,7 @@ this.groupBoxTextAsImage.Controls.Add(this.pictureBoxText); this.groupBoxTextAsImage.Location = new System.Drawing.Point(12, 12); this.groupBoxTextAsImage.Name = "groupBoxTextAsImage"; - this.groupBoxTextAsImage.Size = new System.Drawing.Size(585, 114); + this.groupBoxTextAsImage.Size = new System.Drawing.Size(696, 152); this.groupBoxTextAsImage.TabIndex = 34; this.groupBoxTextAsImage.TabStop = false; this.groupBoxTextAsImage.Text = "Image text"; @@ -273,7 +273,7 @@ | System.Windows.Forms.AnchorStyles.Right))); this.pictureBoxText.Location = new System.Drawing.Point(6, 18); this.pictureBoxText.Name = "pictureBoxText"; - this.pictureBoxText.Size = new System.Drawing.Size(573, 89); + this.pictureBoxText.Size = new System.Drawing.Size(684, 127); this.pictureBoxText.TabIndex = 32; this.pictureBoxText.TabStop = false; // @@ -284,9 +284,9 @@ this.groupBoxText.Controls.Add(this.richTextBoxParagraph); this.groupBoxText.Controls.Add(this.buttonEditWholeText); this.groupBoxText.Controls.Add(this.buttonEditWord); - this.groupBoxText.Location = new System.Drawing.Point(12, 132); + this.groupBoxText.Location = new System.Drawing.Point(12, 170); this.groupBoxText.Name = "groupBoxText"; - this.groupBoxText.Size = new System.Drawing.Size(585, 72); + this.groupBoxText.Size = new System.Drawing.Size(696, 72); this.groupBoxText.TabIndex = 38; this.groupBoxText.TabStop = false; this.groupBoxText.Text = "Text"; @@ -326,7 +326,7 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(609, 435); + this.ClientSize = new System.Drawing.Size(720, 473); this.Controls.Add(this.groupBoxText); this.Controls.Add(this.groupBoxTextAsImage); this.Controls.Add(this.buttonAbort); diff --git a/src/Forms/VobSubOcr.cs b/src/Forms/VobSubOcr.cs index 9d9302947..47dc2e55b 100644 --- a/src/Forms/VobSubOcr.cs +++ b/src/Forms/VobSubOcr.cs @@ -82,6 +82,11 @@ namespace Nikse.SubtitleEdit.Forms List _vobSubMergedPackist; List _palette; + // BluRay sup + List _bluRaySubtitlesOriginal; + List _bluRaySubtitles; + Nikse.SubtitleEdit.Logic.BluRaySup.BluRaySupPalette _defaultPaletteInfo; + // Tesseract OCR //tessnet2.Tesseract _tesseractOcrEngine; // object _tesseractOcrEngine; @@ -220,6 +225,40 @@ namespace Nikse.SubtitleEdit.Forms checkBoxCustomFourColors.Checked = true; } + internal void Initialize(List subtitles, VobSubOcrSettings vobSubOcrSettings) + { + 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 = 11; // vobSubOcrSettings.XOrMorePixelsMakesSpace; + _vobSubOcrSettings = vobSubOcrSettings; + + InitializeModi(); + InitializeTesseract(); + LoadImageCompareCharacterDatabaseList(); + + 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; + + _bluRaySubtitlesOriginal = subtitles; + + groupBoxImagePalette.Visible = false; + + Text = Configuration.Settings.Language.VobSubOcr.TitleBluRay; + } + + private void LoadImageCompareCharacterDatabaseList() { @@ -324,6 +363,45 @@ namespace Nikse.SubtitleEdit.Forms return true; } + private void LoadBluRaySup() + { + _subtitle = new Subtitle(); + + _bluRaySubtitles = new List(); + int max = _bluRaySubtitlesOriginal.Count; + for (int i = 0; i < max; i++) + { + var x = _bluRaySubtitlesOriginal[i]; + if ((checkBoxShowOnlyForced.Checked && x.IsForced) || + checkBoxShowOnlyForced.Checked == false) + { + _bluRaySubtitles.Add(x); + Paragraph p = new Paragraph(); + p.StartTime = new TimeCode(TimeSpan.FromMilliseconds((x.StartTime + 45) / 90.0)); + p.EndTime = new TimeCode(TimeSpan.FromMilliseconds((x.EndTime + 45) / 90.0)); + _subtitle.Paragraphs.Add(p); + } + } + _subtitle.Renumber(1); + + FixShortDisplayTimes(_subtitle); + + subtitleListView1.Fill(_subtitle); + subtitleListView1.SelectIndexAndEnsureVisible(0); + + numericUpDownStartNumber.Maximum = max; + if (numericUpDownStartNumber.Maximum > 0 && numericUpDownStartNumber.Minimum <= 1) + numericUpDownStartNumber.Value = 1; + + buttonOK.Enabled = true; + buttonCancel.Enabled = true; + buttonStartOcr.Enabled = true; + buttonStop.Enabled = false; + buttonNewCharacterDatabase.Enabled = true; + buttonEditCharacterDatabase.Enabled = true; + buttonStartOcr.Focus(); + } + private void LoadVobRip() { _subtitle = new Subtitle(); @@ -385,7 +463,21 @@ namespace Nikse.SubtitleEdit.Forms private Bitmap GetSubtitleBitmap(int index) { - if (checkBoxCustomFourColors.Checked) + if (_bluRaySubtitlesOriginal != null) + { + if (_bluRaySubtitles[index].Palettes.Count == 0 && _defaultPaletteInfo == null) + { + for (int i = 0; i < _bluRaySubtitlesOriginal.Count; i++) + { + if (_bluRaySubtitlesOriginal[i].Palettes.Count > 0) + { + _defaultPaletteInfo = _bluRaySubtitlesOriginal[i].DecodePalette(null); + } + } + } + return _bluRaySubtitles[index].DecodeImage(_defaultPaletteInfo); + } + else if (checkBoxCustomFourColors.Checked) { Color pattern = pictureBoxPattern.BackColor; Color emphasis1 = pictureBoxEmphasis1.BackColor; @@ -405,22 +497,36 @@ namespace Nikse.SubtitleEdit.Forms private long GetSubtitleStartTimeMilliseconds(int index) { - return (long)_vobSubMergedPackist[index].StartTime.TotalMilliseconds; + if (_bluRaySubtitlesOriginal != null) + return (_bluRaySubtitles[index].StartTime + 45) / 90; + else + return (long)_vobSubMergedPackist[index].StartTime.TotalMilliseconds; } private long GetSubtitleEndTimeMilliseconds(int index) { - return (long)_vobSubMergedPackist[index].EndTime.TotalMilliseconds; - } + if (_bluRaySubtitlesOriginal != null) + return (_bluRaySubtitles[index].EndTime + 45) / 90; + else + return (long)_vobSubMergedPackist[index].EndTime.TotalMilliseconds; + } + + private int GetSubtitleCount() + { + if (_bluRaySubtitlesOriginal != null) + return _bluRaySubtitles.Count; + else + return _vobSubMergedPackist.Count; + } private void ShowSubtitleImage(int index) { - int numberOfImages = _vobSubMergedPackist.Count; + int numberOfImages = GetSubtitleCount(); if (index < numberOfImages) { groupBoxSubtitleImage.Text = string.Format(Configuration.Settings.Language.VobSubOcr.SubtitleImageXofY, index + 1, numberOfImages); - pictureBoxSubtitleImage.Image = GetSubtitleBitmap(index); // SubtitleCreator.SUP.GetBitmap(index); + pictureBoxSubtitleImage.Image = GetSubtitleBitmap(index); pictureBoxSubtitleImage.Refresh(); } else @@ -476,7 +582,10 @@ namespace Nikse.SubtitleEdit.Forms if (smallestIndex >= 0) { double differencePercentage = smallestDifference * 100.0 / (target.Width * target.Height); - if (differencePercentage < _vobSubOcrSettings.AllowDifferenceInPercent) // should be around 1.0... + double maxDiff= _vobSubOcrSettings.AllowDifferenceInPercent; // should be around 1.0 for vob/sub... + if (_bluRaySubtitlesOriginal != null) + maxDiff = 14; // let bluray sup have a 14% diff + if (differencePercentage < maxDiff) //_vobSubOcrSettings.AllowDifferenceInPercent) // should be around 1.0... { XmlNode node = _compareDoc.DocumentElement.SelectSingleNode("FileName[.='" + _compareBitmaps[smallestIndex].Name + "']"); if (node != null) @@ -789,28 +898,46 @@ namespace Nikse.SubtitleEdit.Forms private void FormVobSubOcr_Shown(object sender, EventArgs e) { - _vobSubMergedPackistOriginal = new List(); - bool hasIdxTimeCodes = false; - bool hasForcedSubtitles = false; - foreach (var x in _vobSubMergedPackist) + if (_bluRaySubtitlesOriginal != null) { - _vobSubMergedPackistOriginal.Add(x); - if (x.IdxLine != null) - hasIdxTimeCodes = true; - if (x.SubPicture.Forced) - hasForcedSubtitles = true; + LoadBluRaySup(); + bool hasForcedSubtitles = false; + foreach (var x in _bluRaySubtitlesOriginal) + { + if (x.IsForced) + { + hasForcedSubtitles = true; + break; + } + } + checkBoxShowOnlyForced.Enabled = hasForcedSubtitles; + checkBoxUseTimeCodesFromIdx.Visible = false; + } + else + { + _vobSubMergedPackistOriginal = new List(); + bool hasIdxTimeCodes = false; + bool hasForcedSubtitles = false; + foreach (var x in _vobSubMergedPackist) + { + _vobSubMergedPackistOriginal.Add(x); + if (x.IdxLine != null) + hasIdxTimeCodes = true; + if (x.SubPicture.Forced) + hasForcedSubtitles = true; + } + checkBoxUseTimeCodesFromIdx.CheckedChanged -= checkBoxUseTimeCodesFromIdx_CheckedChanged; + checkBoxUseTimeCodesFromIdx.Visible = hasIdxTimeCodes; + checkBoxUseTimeCodesFromIdx.Checked = hasIdxTimeCodes; + checkBoxUseTimeCodesFromIdx.CheckedChanged += checkBoxUseTimeCodesFromIdx_CheckedChanged; + checkBoxShowOnlyForced.Enabled = hasForcedSubtitles; + LoadVobRip(); } - checkBoxUseTimeCodesFromIdx.CheckedChanged -= checkBoxUseTimeCodesFromIdx_CheckedChanged; - checkBoxUseTimeCodesFromIdx.Visible = hasIdxTimeCodes; - checkBoxUseTimeCodesFromIdx.Checked = hasIdxTimeCodes; - checkBoxUseTimeCodesFromIdx.CheckedChanged += checkBoxUseTimeCodesFromIdx_CheckedChanged; - checkBoxShowOnlyForced.Enabled = hasForcedSubtitles; - LoadVobRip(); } private void ButtonOkClick(object sender, EventArgs e) { - if (Configuration.Settings.VobSubOcr.XOrMorePixelsMakesSpace != (int)numericUpDownPixelsIsSpace.Value) + if (Configuration.Settings.VobSubOcr.XOrMorePixelsMakesSpace != (int)numericUpDownPixelsIsSpace.Value && _bluRaySubtitlesOriginal == null) { Configuration.Settings.VobSubOcr.XOrMorePixelsMakesSpace = (int)numericUpDownPixelsIsSpace.Value; Configuration.Settings.Save(); @@ -843,7 +970,7 @@ namespace Nikse.SubtitleEdit.Forms _abort = false; - int max = _vobSubMergedPackist.Count; + int max = GetSubtitleCount(); progressBar1.Maximum = max; progressBar1.Value = 0; @@ -1093,6 +1220,8 @@ namespace Nikse.SubtitleEdit.Forms subtitleListView1.SetBackgroundColor(index, Color.Orange); else if (wordsNotFound == 1) subtitleListView1.SetBackgroundColor(index, Color.Yellow); + else if (line.Trim().Length == 0) + subtitleListView1.SetBackgroundColor(index, Color.Orange); else subtitleListView1.SetBackgroundColor(index, Color.Green); } @@ -1107,6 +1236,8 @@ namespace Nikse.SubtitleEdit.Forms subtitleListView1.SetBackgroundColor(index, Color.Orange); else if (badWords > 0) subtitleListView1.SetBackgroundColor(index, Color.Yellow); + else if (line.Trim().Length == 0) + subtitleListView1.SetBackgroundColor(index, Color.Orange); else subtitleListView1.SetBackgroundColor(index, Color.Green); } @@ -1598,7 +1729,10 @@ namespace Nikse.SubtitleEdit.Forms { Subtitle oldSubtitle = new Subtitle(_subtitle); subtitleListView1.BeginUpdate(); - LoadVobRip(); + if (_bluRaySubtitlesOriginal != null) + LoadBluRaySup(); + else + LoadVobRip(); for (int i = 0; i < _subtitle.Paragraphs.Count; i++) { Paragraph current = _subtitle.Paragraphs[i]; @@ -1634,5 +1768,6 @@ namespace Nikse.SubtitleEdit.Forms subtitleListView1.EndUpdate(); } + } } diff --git a/src/Logic/BluRaySup/BluRaySupPalette.cs b/src/Logic/BluRaySup/BluRaySupPalette.cs new file mode 100644 index 000000000..58ba93e16 --- /dev/null +++ b/src/Logic/BluRaySup/BluRaySupPalette.cs @@ -0,0 +1,468 @@ +/* + * Copyright 2009 Volker Oth (0xdeadbeef) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTE: Converted to C# and modified by Nikse.dk@gmail.com + */ + +namespace Nikse.SubtitleEdit.Logic.BluRaySup +{ + + public class BluRaySupPalette + { + /** Number of palette entries */ + private int size; + /** Byte buffer for RED info */ + private byte[] r; + /** Byte buffer for GREEN info */ + private byte[] g; + /** Byte buffer for BLUE info */ + private byte[] b; + /** Byte buffer for alpha info */ + private byte[] a; + /** Byte buffer for Y (luminance) info */ + private byte[] y; + /** Byte buffer for Cb (chrominance blue) info */ + private byte[] cb; + /** Byte buffer for Cr (chrominance red) info */ + private byte[] cr; + /** Use BT.601 color model instead of BT.709 */ + private bool useBT601; + + /** + * Convert YCBCr color info to RGB + * @param y 8 bit luminance + * @param cb 8 bit chrominance blue + * @param cr 8 bit chrominance red + * @return Integer array with red, blue, green component (in this order) + */ + static int[] YCbCr2Rgb(int y, int cb, int cr, bool useBt601) + { + int[] rgb = new int[3]; + double y1, r, g, b; + + y -= 16; + cb -= 128; + cr -= 128; + + y1 = y * 1.164383562; + if (useBt601) + { + /* BT.601 for YCbCr 16..235 -> RGB 0..255 (PC) */ + r = y1 + cr * 1.596026317; + g = y1 - cr * 0.8129674985 - cb * 0.3917615979; + b = y1 + cb * 2.017232218; + } + else + { + /* BT.709 for YCbCr 16..235 -> RGB 0..255 (PC) */ + r = y1 + cr * 1.792741071; + g = y1 - cr * 0.5329093286 - cb * 0.2132486143; + b = y1 + cb * 2.112401786; + } + rgb[0] = (int)(r + 0.5); + rgb[1] = (int)(g + 0.5); + rgb[2] = (int)(b + 0.5); + for (int i = 0; i < 3; i++) + { + if (rgb[i] < 0) + rgb[i] = 0; + else if (rgb[i] > 255) + rgb[i] = 255; + } + return rgb; + } + + /** + * Convert RGB color info to YCBCr + * @param r 8 bit red component + * @param g 8 bit green component + * @param b 8 bit blue component + * @return Integer array with luminance (Y), chrominance blue (Cb), chrominance red (Cr) (in this order) + */ + static int[] Rgb2YCbCr(int r, int g, int b, bool useBt601) + { + int[] yCbCr = new int[3]; + double y, cb, cr; + + if (useBt601) + { + /* BT.601 for RGB 0..255 (PC) -> YCbCr 16..235 */ + y = r * 0.299 * 219 / 255 + g * 0.587 * 219 / 255 + b * 0.114 * 219 / 255; + cb = -r * 0.168736 * 224 / 255 - g * 0.331264 * 224 / 255 + b * 0.5 * 224 / 255; + cr = r * 0.5 * 224 / 255 - g * 0.418688 * 224 / 255 - b * 0.081312 * 224 / 255; + } + else + { + /* BT.709 for RGB 0..255 (PC) -> YCbCr 16..235 */ + y = r * 0.2126 * 219 / 255 + g * 0.7152 * 219 / 255 + b * 0.0722 * 219 / 255; + cb = -r * 0.2126 / 1.8556 * 224 / 255 - g * 0.7152 / 1.8556 * 224 / 255 + b * 0.5 * 224 / 255; + cr = r * 0.5 * 224 / 255 - g * 0.7152 / 1.5748 * 224 / 255 - b * 0.0722 / 1.5748 * 224 / 255; + } + yCbCr[0] = 16 + (int)(y + 0.5); + yCbCr[1] = 128 + (int)(cb + 0.5); + yCbCr[2] = 128 + (int)(cr + 0.5); + for (int i = 0; i < 3; i++) + { + if (yCbCr[i] < 16) + yCbCr[i] = 16; + else + { + if (i == 0) + { + if (yCbCr[i] > 235) + yCbCr[i] = 235; + } + else + { + if (yCbCr[i] > 240) + yCbCr[i] = 240; + } + } + } + return yCbCr; + } + + /** + * Ctor - initializes palette with transparent black (RGBA: 0x00000000) + * @param palSize Number of palette entries + * @param use601 Use BT.601 instead of BT.709 + */ + public BluRaySupPalette(int palSize, bool use601) + { + size = palSize; + useBT601 = use601; + r = new byte[size]; + g = new byte[size]; + b = new byte[size]; + a = new byte[size]; + y = new byte[size]; + cb = new byte[size]; + cr = new byte[size]; + + // set at least all alpha values to invisible + int[] yCbCr = Rgb2YCbCr(0, 0, 0, useBT601); + for (int i = 0; i < palSize; i++) + { + a[i] = 0; + r[i] = 0; + g[i] = 0; + b[i] = 0; + y[i] = (byte)yCbCr[0]; + cb[i] = (byte)yCbCr[1]; + cr[i] = (byte)yCbCr[2]; + } + } + + /** + * Ctor - initializes palette with transparent black (RGBA: 0x00000000) + * @param palSize Number of palette entries + */ + public BluRaySupPalette(int palSize) + : this(palSize, false) + { + + } + + /** + * Ctor - construct palette from red, green blue and alpha buffers + * @param red Byte buffer containing the red components + * @param green Byte buffer containing the green components + * @param blue Byte buffer containing the blue components + * @param alpha Byte buffer containing the alpha components + * @param use601 Use BT.601 instead of BT.709 + */ + public BluRaySupPalette(byte[] red, byte[] green, byte[] blue, byte[] alpha, bool use601) + { + size = red.Length; + useBT601 = use601; + r = new byte[size]; + g = new byte[size]; + b = new byte[size]; + a = new byte[size]; + y = new byte[size]; + cb = new byte[size]; + cr = new byte[size]; + + int[] yCbCr; + for (int i = 0; i < size; i++) + { + a[i] = alpha[i]; + r[i] = red[i]; + g[i] = green[i]; + b[i] = blue[i]; + yCbCr = Rgb2YCbCr(r[i] & 0xff, g[i] & 0xff, b[i] & 0xff, useBT601); + y[i] = (byte)yCbCr[0]; + cb[i] = (byte)yCbCr[1]; + cr[i] = (byte)yCbCr[2]; + } + } + + /** + * Ctor - construct palette from red, green blue and alpha buffers + * @param red Byte buffer containing the red components + * @param green Byte buffer containing the green components + * @param blue Byte buffer containing the blue components + * @param alpha Byte buffer containing the alpha components + */ + public BluRaySupPalette(byte[] red, byte[] green, byte[] blue, byte[] alpha) + : this(red, green, blue, alpha, false) + { + } + + /** + * Ctor - construct new (independent) palette from existing one + * @param p Palette to copy values from + */ + public BluRaySupPalette(BluRaySupPalette p) + { + size = p.GetSize(); + useBT601 = p.UsesBt601(); + r = new byte[size]; + g = new byte[size]; + b = new byte[size]; + a = new byte[size]; + y = new byte[size]; + cb = new byte[size]; + cr = new byte[size]; + + for (int i = 0; i < size; i++) + { + a[i] = p.a[i]; + r[i] = p.r[i]; + g[i] = p.g[i]; + b[i] = p.b[i]; + y[i] = p.y[i]; + cb[i] = p.cb[i]; + cr[i] = p.cr[i]; + } + } + + /** + * Set palette index "index" to color "c" in ARGB format + * @param index Palette index + * @param c Color in ARGB format + */ + public void SetArgb(int index, int c) + { + int a1 = (c >> 24) & 0xff; + int r1 = (c >> 16) & 0xff; + int g1 = (c >> 8) & 0xff; + int b1 = c & 0xff; + SetRgb(index, r1, g1, b1); + SetAlpha(index, a1); + } + + /** + * Return palette entry at index as Integer in ARGB format + * @param index Palette index + * @return Palette entry at index as Integer in ARGB format + */ + public int GetArgb(int index) + { + return ((a[index] & 0xff) << 24) | ((r[index] & 0xff) << 16) | ((g[index] & 0xff) << 8) | (b[index] & 0xff); + } + + /** + * Set palette entry (RGB mode) + * @param index Palette index + * @param red 8bit red component + * @param green 8bit green component + * @param blue 8bit blue component + */ + public void SetRgb(int index, int red, int green, int blue) + { + r[index] = (byte)red; + g[index] = (byte)green; + b[index] = (byte)blue; + // create yCbCr + int[] yCbCr = Rgb2YCbCr(red, green, blue, useBT601); + y[index] = (byte)yCbCr[0]; + cb[index] = (byte)yCbCr[1]; + cr[index] = (byte)yCbCr[2]; + } + + /** + * Set palette entry (YCbCr mode) + * @param index Palette index + * @param yn 8bit Y component + * @param cbn 8bit Cb component + * @param crn 8bit Cr component + */ + public void SetYCbCr(int index, int yn, int cbn, int crn) + { + y[index] = (byte)yn; + cb[index] = (byte)cbn; + cr[index] = (byte)crn; + // create RGB + int[] rgb = YCbCr2Rgb(yn, cbn, crn, useBT601); + r[index] = (byte)rgb[0]; + g[index] = (byte)rgb[1]; + b[index] = (byte)rgb[2]; + } + + /** + * Set alpha channel + * @param index Palette index + * @param alpha 8bit alpha channel value + */ + public void SetAlpha(int index, int alpha) + { + a[index] = (byte)alpha; + } + + /** + * Get alpha channel + * @param index Palette index + * @return 8bit alpha channel value + */ + public int GetAlpha(int index) + { + return a[index] & 0xff; + } + + /** + * Return byte array of alpha channel components + * @return Byte array of alpha channel components (don't modify!) + */ + public byte[] GetAlpha() + { + return a; + } + + /** + * Get Integer array containing 8bit red, green, blue components (in this order) + * @param index Palette index + * @return Integer array containing 8bit red, green, blue components (in this order) + */ + public int[] GetRgb(int index) + { + int[] rgb = new int[3]; + rgb[0] = r[index] & 0xff; + rgb[1] = g[index] & 0xff; + rgb[2] = b[index] & 0xff; + return rgb; + } + + /** + * Get Integer array containing 8bit Y, Cb, Cr components (in this order) + * @param index Palette index + * @return Integer array containing 8bit Y, Cb, Cr components (in this order) + */ + public int[] GetYCbCr(int index) + { + int[] yCbCr = new int[3]; + yCbCr[0] = y[index] & 0xff; + yCbCr[1] = cb[index] & 0xff; + yCbCr[2] = cr[index] & 0xff; + return yCbCr; + } + + /** + * Return byte array of red components + * @return Byte array of red components (don't modify!) + */ + public byte[] GetR() + { + return r; + } + + /** + * Return byte array of green components + * @return Byte array of green components (don't modify!) + */ + public byte[] GetG() + { + return g; + } + + /** + * Return byte array of blue components + * @return Byte array of blue components (don't modify!) + */ + public byte[] GetB() + { + return b; + } + + /** + * Return byte array of Y components + * @return Byte array of Y components (don't modify!) + */ + public byte[] GetY() + { + return y; + } + + /** + * Return byte array of Cb components + * @return Byte array of Cb components (don't modify!) + */ + public byte[] GetCb() + { + return cb; + } + + /** + * Return byte array of Cr components + * @return Byte array of Cr components (don't modify!) + */ + public byte[] GetCr() + { + return cr; + } + + /** + * Get size of palette (number of entries) + * @return Size of palette (number of entries) + */ + public int GetSize() + { + return size; + } + + /** + * Return index of most transparent palette entry or the index of the first completely transparent color + * @return Index of most transparent palette entry or the index of the first completely transparent color + */ + public int GetTransparentIndex() + { + // find (most) transparent index in palette + int transpIdx = 0; + int minAlpha = 0x100; + for (int i = 0; i < size; i++) + { + if ((a[i] & 0xff) < minAlpha) + { + minAlpha = a[i] & 0xff; + transpIdx = i; + if (minAlpha == 0) + break; + } + } + return transpIdx; + } + + /** + * Get: use of BT.601 color model instead of BT.709 + * @return True if BT.601 is used + */ + public bool UsesBt601() + { + return useBT601; + } + + } +} + diff --git a/src/Logic/BluRaySup/BluRaySupParser.cs b/src/Logic/BluRaySup/BluRaySupParser.cs new file mode 100644 index 000000000..3d6e20cd7 --- /dev/null +++ b/src/Logic/BluRaySup/BluRaySupParser.cs @@ -0,0 +1,660 @@ +/* + * Copyright 2009 Volker Oth (0xdeadbeef) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTE: Converted to C# and modified by Nikse.dk@gmail.com + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace Nikse.SubtitleEdit.Logic.BluRaySup +{ + public static class BluRaySupParser + { + + private class SupSegment + { + /// + /// Type of segment + /// + public int Type; + + /// + /// segment size in bytes + /// + public int Size; + + /// + /// segment PTS time stamp + /// + public long PtsTimestamp; + + /// + /// segment DTS time stamp + /// + public long DtsTimestamp; + } + + + /** PGS composition state */ + private enum CompositionState + { + /** normal: doesn't have to be complete */ + Normal, + /** acquisition point */ + AcquPoint, + /** epoch start - clears the screen */ + EpochStart, + /** epoch continue */ + EpochContinue, + /** unknown value */ + Invalid + } + + private static byte[] packetHeader = + { + 0x50, 0x47, // 0: "PG" + 0x00, 0x00, 0x00, 0x00, // 2: PTS - presentation time stamp + 0x00, 0x00, 0x00, 0x00, // 6: DTS - decoding time stamp + 0x00, // 10: segment_type + 0x00, 0x00, // 11: segment_length (bytes following till next PG) + }; + + private static byte[] headerPCSStart = + { + 0x00, 0x00, 0x00, 0x00, // 0: video_width, video_height + 0x10, // 4: hi nibble: frame_rate (0x10=24p), lo nibble: reserved + 0x00, 0x00, // 5: composition_number (increased by start and end header) + (byte)0x80, // 7: composition_state (0x80: epoch start) + 0x00, // 8: palette_update_flag (0x80), 7bit reserved + 0x00, // 9: palette_id_ref (0..7) + 0x01, // 10: number_of_composition_objects (0..2) + 0x00, 0x00, // 11: 16bit object_id_ref + 0x00, // 13: window_id_ref (0..1) + 0x00, // 14: object_cropped_flag: 0x80, forced_on_flag = 0x040, 6bit reserved + 0x00, 0x00, 0x00, 0x00 // 15: composition_object_horizontal_position, composition_object_vertical_position + }; + + private static byte[] headerPCSEnd = + { + 0x00, 0x00, 0x00, 0x00, // 0: video_width, video_height + 0x10, // 4: hi nibble: frame_rate (0x10=24p), lo nibble: reserved + 0x00, 0x00, // 5: composition_number (increased by start and end header) + 0x00, // 7: composition_state (0x00: normal) + 0x00, // 8: palette_update_flag (0x80), 7bit reserved + 0x00, // 9: palette_id_ref (0..7) + 0x00, // 10: number_of_composition_objects (0..2) + }; + + private static byte[] headerODSFirst = + { + 0x00, 0x00, // 0: object_id + 0x00, // 2: object_version_number + (byte)0xC0, // 3: first_in_sequence (0x80), last_in_sequence (0x40), 6bits reserved + 0x00, 0x00, 0x00, // 4: object_data_length - full RLE buffer length (including 4 bytes size info) + 0x00, 0x00, 0x00, 0x00, // 7: object_width, object_height + }; + + private static byte[] headerODSNext = + { + 0x00, 0x00, // 0: object_id + 0x00, // 2: object_version_number + (byte)0x40, // 3: first_in_sequence (0x80), last_in_sequence (0x40), 6bits reserved + }; + + private static byte[] headerWDS = + { + 0x01, // 0 : number of windows (currently assumed 1, 0..2 is legal) + 0x00, // 1 : window id (0..1) + 0x00, 0x00, 0x00, 0x00, // 2 : x-ofs, y-ofs + 0x00, 0x00, 0x00, 0x00 // 6 : width, height + }; + + + /// + /// Parses a BluRay sup file + /// + /// BluRay sup file name + /// Parsing info is logged here + /// List of BluRaySupPictures + public static List ParseBluRaySup(string fileName, StringBuilder log) + { + using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + return ParseBluRaySup(fs, log); + } + } + + /// + /// Can be used with e.g. MemoryStream or FileStream + /// + /// memory stream containing sup data + /// Text parser log + public static List ParseBluRaySup(Stream ms, StringBuilder log) + { + SupSegment segment; + BluRaySupPicture pic = null; + BluRaySupPicture picLast = null; + BluRaySupPicture picTmp = null; + List subPictures = new List(); + int odsCtr = 0; + int pdsCtr = 0; + int odsCtrOld = 0; + int pdsCtrOld = 0; + int compNum = -1; + int compNumOld = -1; + int compCount = 0; + long ptsPcs = 0; + bool paletteUpdate = false; + CompositionState cs = CompositionState.Invalid; + ms.Position = 0; + long position = 0; + int i = 0; + const int headerSize = 13; + byte[] buffer; + while (position < ms.Length) + { + string[] so = new string[1]; // hack to return string + + ms.Seek(position, SeekOrigin.Begin); + buffer = new byte[headerSize]; + ms.Read(buffer, 0, buffer.Length); + segment = ReadSegment(buffer, log); + position += headerSize; + buffer = new byte[segment.Size]; + ms.Read(buffer, 0, buffer.Length); + log.Append(i + ": "); + switch (segment.Type) + { + case 0x14: // Palette + log.AppendLine(string.Format("0x14 - Palette - PDS offset={0} size={1}", position, segment.Size)); + + if (compNum != compNumOld) + { + if (pic != null) + { + so[0] = null; + int ps = ParsePds(buffer, segment, pic, so); + if (ps >= 0) + { + log.AppendLine(", " + so[0]); + if (ps > 0) // don't count empty palettes + pdsCtr++; + } + else + { + log.AppendLine(); + log.AppendLine(so[0]); + } + } + else + { + log.AppendLine(); + log.AppendLine("missing PTS start -> ignored"); + } + } + else + { + log.AppendLine(", comp # unchanged -> ignored"); + } + break; + + case 0x15: // Image bitmap data + log.AppendLine(string.Format("0x15 - bitmap data - ODS offset={0} size={1}", position, segment.Size)); + + if (compNum != compNumOld) + { + if (!paletteUpdate) + { + if (pic != null) + { + so[0] = null; + if (ParseOds(buffer, segment, pic, so)) + odsCtr++; + if (so[0] != null) + log.Append(", " + so[0]); + log.AppendLine(", img size: " + pic.Width + "*" + pic.Height); + } + else + { + log.AppendLine(); + log.AppendLine("missing PTS start -> ignored"); + } + } + else + { + log.AppendLine(); + log.AppendLine("palette update only -> ignored"); + } + } + else + { + log.AppendLine(", comp # unchanged -> ignored"); + } + break; + + case 0x16: + log.AppendLine(string.Format("0x16 - Time codes, offset={0} size={1}", position, segment.Size)); + + compNum = BigEndianInt16(buffer, 5); + cs = GetCompositionState(buffer[7]); + paletteUpdate = buffer[8] == 0x80; + ptsPcs = segment.PtsTimestamp; + if (segment.Size >= 0x13) + compCount = 1; // could be also 2, but we'll ignore this for the moment + else + compCount = 0; + if (cs == CompositionState.Invalid) + { + log.AppendLine("Illegal composition state at offset " + position); + } + else if (cs == CompositionState.EpochStart) + { + //new frame + if (subPictures.Count > 0 && (odsCtr == 0 || pdsCtr == 0)) + { + log.AppendLine("missing PDS/ODS: last epoch is discarded"); + subPictures.RemoveAt(subPictures.Count - 1); + compNumOld = compNum - 1; + if (subPictures.Count > 0) + picLast = subPictures[subPictures.Count - 1]; + else + picLast = null; + } + else + picLast = pic; + + pic = new BluRaySupPicture(); + subPictures.Add(pic); // add to list + pic.StartTime = segment.PtsTimestamp; + log.AppendLine("#> " + (subPictures.Count) + " (" + ToolBox.PtsToTimeString(pic.StartTime) + ")"); + + so[0] = null; + ParsePcs(segment, pic, so, buffer); + // fix end time stamp of previous pic if still missing + if (picLast != null && picLast.EndTime == 0) + picLast.EndTime = pic.StartTime; + + if (so[0] != null) + log.AppendLine(", " + so[0]); + else + log.AppendLine(); + log.Append(Environment.NewLine + "PTS start: " + ToolBox.PtsToTimeString(pic.StartTime)); + log.AppendLine(", screen size: " + pic.Width + "*" + pic.Height); + odsCtr = 0; + pdsCtr = 0; + odsCtrOld = 0; + pdsCtrOld = 0; + picTmp = null; + } + else + { + if (pic == null) + { + log.AppendLine(" Missing start of epoch at offset " + position); + break; + } + log.Append("PCS ofs:" + ToolBox.ToHex(buffer, 0, 8) + ", "); + switch (cs) + { + case CompositionState.EpochContinue: + log.AppendLine(" CONT, "); + break; + case CompositionState.AcquPoint: + log.AppendLine(" ACQU, "); + break; + case CompositionState.Normal: + log.AppendLine(" NORM, "); + break; + } + log.AppendLine("size: " + segment.Size + ", comp#: " + compNum + ", forced: " + pic.IsForced); + if (compNum != compNumOld) + { + so[0] = null; + // store state to be able to revert to it + picTmp = new BluRaySupPicture(pic); // deep copy + picTmp.EndTime = ptsPcs; + // create new pic + ParsePcs(segment, pic, so, buffer); + } + if (so[0] != null) + log.AppendLine(", " + so[0]); + log.AppendLine(", pal update: " + paletteUpdate); + log.AppendLine("PTS: " + ToolBox.PtsToTimeString(segment.PtsTimestamp)); + } + break; + + case 0x17: + log.AppendLine(string.Format("0x17 - WDS offset={0} size={1}", position, segment.Size)); + + int x = BigEndianInt16(buffer, 2); + int y = BigEndianInt16(buffer, 4); + int width = BigEndianInt16(buffer, 6); + int height = BigEndianInt16(buffer, 8); + + log.AppendLine(string.Format("width:{0}, height:{1}", width, height)); + break; + + case 0x80: + log.AppendLine(string.Format("0x18 - END offset={0} size={1}", position, segment.Size)); + + // decide whether to store this last composition section as caption or merge it + if (cs == CompositionState.EpochStart) + { + if (compCount > 0 && odsCtr > odsCtrOld && compNum != compNumOld && IsPictureMergable(picLast, pic)) + { + // the last start epoch did not contain any (new) content + // and should be merged to the previous frame + subPictures.RemoveAt(subPictures.Count - 1); + pic = picLast; + if (subPictures.Count > 0) + picLast = subPictures[subPictures.Count - 1]; + else + picLast = null; + log.AppendLine("#< caption merged"); + } + } + else + { + long startTime = 0; + if (pic != null) + { + startTime = pic.StartTime; // store + pic.StartTime = ptsPcs; // set for testing merge + } + + if (compCount > 0 && odsCtr > odsCtrOld && compNum != compNumOld && !IsPictureMergable(picTmp, pic)) + { + // last PCS should be stored as separate caption + if (odsCtr - odsCtrOld > 1 || pdsCtr - pdsCtrOld > 1) + log.AppendLine("multiple PDS/ODS definitions: result may be erratic"); + // replace pic with picTmp (deepCopy created before new PCS) + subPictures[subPictures.Count - 1] = picTmp; // replace in list + picLast = picTmp; + subPictures.Add(pic); // add to list + log.AppendLine("#< " + (subPictures.Count) + " (" + ToolBox.PtsToTimeString(pic.StartTime) + ")"); + odsCtrOld = odsCtr; + } + else + { + if (pic != null) + { + // merge with previous pic + pic.StartTime = startTime; // restore + pic.EndTime = ptsPcs; + // for the unlikely case that forced flag changed during one captions + if (picTmp != null && picTmp.IsForced) + pic.IsForced = true; + + if (pdsCtr > pdsCtrOld || paletteUpdate) + log.AppendLine("palette animation: result may be erratic\n"); + } + else + log.AppendLine("end without at least one epoch start"); + + } + } + + pdsCtrOld = pdsCtr; + compNumOld = compNum; + break; + default: + log.AppendLine(string.Format("0x?? - END offset={0} UNKOWN SEGMENT TYPE={1}", position, segment.Type)); + break; + } + log.AppendLine(); + position += segment.Size; + i++; + } + return subPictures; + } + + /// + /// Checks if two SubPicture object can be merged because the time gap between them is rather small + /// and the embedded objects seem to be identical + /// + /// first SubPicture object (earlier) + /// 2nd SubPicture object (later) + /// return true if the SubPictures can be merged + private static bool IsPictureMergable(BluRaySupPicture a, BluRaySupPicture b) + { + bool eq = false; + if (a != null && b != null) + { + if (a.EndTime == 0 || b.StartTime - a.EndTime < Core.GetMergePtSdiff()) + { + ImageObject ao = a.ObjectIdImage; + ImageObject bo = b.ObjectIdImage; + if (ao != null && bo != null) + if (ao.BufferSize == bo.BufferSize && ao.Width == bo.Width && ao.Height == bo.Height) + eq = true; + } + } + return eq; + } + + /// + /// Parse an PCS packet which contains width/height info + /// + /// object containing info about the current segment + /// SubPicture object containing info about the current caption + /// reference to message string + /// Raw data buffer, starting right after segment + private static void ParsePcs(SupSegment segment, BluRaySupPicture pic, string[] msg, byte[] buffer) + { + if (segment.Size >= 4) + { + pic.Width = BigEndianInt16(buffer, 0); // video_width + pic.Height = BigEndianInt16(buffer, 2); // video_height + int type = buffer[4]; // hi nibble: frame_rate, lo nibble: reserved + int num = BigEndianInt16(buffer, 5); // composition_number + // skipped: + // 8bit composition_state: 0x00: normal, 0x40: acquisition point + // 0x80: epoch start, 0xC0: epoch continue, 6bit reserved + // 8bit palette_update_flag (0x80), 7bit reserved + int palId = buffer[9]; // 8bit palette_id_ref + int coNum = buffer[10]; // 8bit number_of_composition_objects (0..2) + if (coNum > 0) + { + // composition_object: + int objId = BigEndianInt16(buffer, 11); // 16bit object_id_ref + msg[0] = "palID: " + palId + ", objID: " + objId; + if (pic.ImageObjects == null) + pic.ImageObjects = new List(); + ImageObject imgObj; + if (objId >= pic.ImageObjects.Count) + { + imgObj = new ImageObject(); + pic.ImageObjects.Add(imgObj); + } + else + imgObj = pic.GetImageObject(objId); + imgObj.PaletteId = palId; + pic.ObjectId = objId; + + // skipped: 8bit window_id_ref + if (segment.Size >= 0x13) + { + pic.FramesPerSecondType = type; + // object_cropped_flag: 0x80, forced_on_flag = 0x040, 6bit reserved + int forcedCropped = buffer[14]; + pic.CompositionNumber = num; + pic.IsForced = ((forcedCropped & 0x40) == 0x40); + imgObj.XOffset = BigEndianInt16(buffer, 15); // composition_object_horizontal_position + imgObj.YOffset = BigEndianInt16(buffer, 17); // composition_object_vertical_position + // if (object_cropped_flag==1) + // 16bit object_cropping_horizontal_position + // 16bit object_cropping_vertical_position + // 16bit object_cropping_width + // object_cropping_height + } + } + } + } + + /// + /// parse an ODS packet which contain the image data + /// + /// raw byte date, starting right after segment + /// object containing info about the current segment + /// SubPicture object containing info about the current caption + /// reference to message string + /// true if this is a valid new object (neither invalid nor a fragment) + private static bool ParseOds(byte[] buffer, SupSegment segment, BluRaySupPicture pic, string[] msg) + { + ImageObjectFragment info; + + int objId = BigEndianInt16(buffer, 0); // 16bit object_id + int objVer = buffer[2]; // 16bit object_id nikse - index 2 or 1??? + int objSeq = buffer[3]; // 8bit first_in_sequence (0x80), + // last_in_sequence (0x40), 6bits reserved + bool first = (objSeq & 0x80) == 0x80; + bool last = (objSeq & 0x40) == 0x40; + + if (pic.ImageObjects == null) + pic.ImageObjects = new List(); + ImageObject imgObj; + if (objId >= pic.ImageObjects.Count) + { + imgObj = new ImageObject(); + pic.ImageObjects.Add(imgObj); + } + else + imgObj = pic.GetImageObject(objId); + + if (imgObj.Fragments == null || first) + { // 8bit object_version_number + // skipped: + // 24bit object_data_length - full RLE buffer length (including 4 bytes size info) + int width = BigEndianInt16(buffer, 7); // object_width + int height = BigEndianInt16(buffer, 9); // object_height + + if (width <= pic.Width && height <= pic.Height) + { + imgObj.Fragments = new List(); + info = new ImageObjectFragment(); + info.ImagePacketSize = segment.Size - 11; // Image packet size (image bytes) + info.ImageBuffer = new byte[info.ImagePacketSize]; + Buffer.BlockCopy(buffer, 11, info.ImageBuffer, 0, info.ImagePacketSize); + imgObj.Fragments.Add(info); + imgObj.BufferSize = info.ImagePacketSize; + imgObj.Height = height; + imgObj.Width = width; + msg[0] = "ID: " + objId + ", update: " + objVer + ", seq: " + (first ? "first" : "") + + ((first && last) ? "/" : "") + (last ? "" + "last" : ""); + return true; + } + System.Diagnostics.Debug.Print("Invalid image size - ignored"); + return false; + } + // object_data_fragment + // skipped: + // 16bit object_id + // 8bit object_version_number + // 8bit first_in_sequence (0x80), last_in_sequence (0x40), 6bits reserved + info = new ImageObjectFragment(); + info.ImagePacketSize = segment.Size - 4; + info.ImageBuffer = new byte[info.ImagePacketSize]; + Buffer.BlockCopy(buffer, 4, info.ImageBuffer, 0, info.ImagePacketSize); + imgObj.Fragments.Add(info); + imgObj.BufferSize += info.ImagePacketSize; // total size (may contain several packets) + msg[0] = "ID: " + objId + ", update: " + objVer + ", seq: " + (first ? "first" : "") + ((first && last) ? "/" : "") + (last ? "" + "last" : ""); + return false; + } + + private static CompositionState GetCompositionState(byte type) + { + switch (type) + { + case 0x00: + return CompositionState.Normal; + case 0x40: + return CompositionState.AcquPoint; + case 0x80: + return CompositionState.EpochStart; + case 0xC0: + return CompositionState.EpochContinue; + default: + return CompositionState.Invalid; + } + } + + private static int BigEndianInt16(byte[] buffer, int index) + { + return (buffer[index + 1]) + (buffer[index + 0] << 8); + } + + private static uint BigEndianInt32(byte[] buffer, int index) + { + return (uint)((buffer[index + 3]) + (buffer[index + 2] << 8) + (buffer[index + 1] << 0x10) + (buffer[index + 0] << 0x18)); + } + + private static SupSegment ReadSegment(byte[] buffer, StringBuilder log) + { + SupSegment segment = new SupSegment(); + if (buffer[0] == 0x50 && buffer[1] == 0x47) // 80 + 71 - P G + { + segment.PtsTimestamp = BigEndianInt32(buffer, 2); // read PTS + segment.DtsTimestamp = BigEndianInt32(buffer, 6); // read PTS + segment.Type = buffer[10]; + segment.Size = BigEndianInt16(buffer, 11); + } + else + { + log.AppendLine("Unable to read segment - PG missing!"); + } + return segment; + } + + /// + /// parse an PDS packet which contain palette info + /// + /// Buffer of raw byte data, starting right after segment + /// object containing info about the current segment + /// SubPicture object containing info about the current caption + /// reference to message string + /// number of valid palette entries (-1 for fault) + private static int ParsePds(byte[] buffer, SupSegment segment, BluRaySupPicture pic, string[] msg) + { + int paletteId = buffer[0]; // 8bit palette ID (0..7) + // 8bit palette version number (incremented for each palette change) + int paletteUpdate = buffer[1]; + if (pic.Palettes == null) + { + pic.Palettes = new List>(); + for (int i = 0; i < 8; i++) + pic.Palettes.Add(new List()); + } + if (paletteId > 7) + { + msg[0] = "Illegal palette id at offset " + ToolBox.ToHex(buffer, 0, 8); + return -1; + } + List al = pic.Palettes[paletteId]; + if (al == null) + al = new List(); + PaletteInfo p = new PaletteInfo(); + p.PaletteSize = (segment.Size - 2) / 5; + p.PaletteBuffer = new byte[p.PaletteSize * 5]; + Buffer.BlockCopy(buffer, 2, p.PaletteBuffer, 0, p.PaletteSize * 5); // save palette buffer in palette object + al.Add(p); + msg[0] = "ID: " + paletteId + ", update: " + paletteUpdate + ", " + p.PaletteSize + " entries"; + return p.PaletteSize; + } + + } +} diff --git a/src/Logic/BluRaySup/BluRaySupPicture.cs b/src/Logic/BluRaySup/BluRaySupPicture.cs new file mode 100644 index 000000000..3991b70b6 --- /dev/null +++ b/src/Logic/BluRaySup/BluRaySupPicture.cs @@ -0,0 +1,403 @@ +/* + * Copyright 2009 Volker Oth (0xdeadbeef) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTE: Converted to C# and modified by Nikse.dk@gmail.com + */ + +using System; +using System.Collections.Generic; +using System.Drawing; + +namespace Nikse.SubtitleEdit.Logic.BluRaySup +{ + + public class BluRaySupPicture + { + /// + /// screen width + /// + public int Width { get; set; } + + /// + /// screen height + /// + public int Height { get; set; } + + /// + /// start time in milliseconds + /// + public long StartTime { get; set; } + + /// + /// end time in milliseconds + /// + public long EndTime { get; set; } + + /// + /// if true, this is a forced subtitle + /// + public bool IsForced { get; set; } + + /// + /// composition number - increased at start and end PCS + /// + public int CompositionNumber { get; set; } + + /// + /// objectID used in decoded object + /// + public int ObjectId { get; set; } + + /// + /// list of ODS packets containing image info + /// + public List ImageObjects; + + /// + /// width of subtitle window (might be larger than image) + /// + public int WindowWidth { get; set; } + + /// + /// height of subtitle window (might be larger than image) + /// + public int WindowHeight { get; set; } + + /// + /// upper left corner of subtitle window x + /// + public int WindowXOffset { get; set; } + + /// + /// upper left corner of subtitle window y + /// + public int WindowYOffset { get; set; } + + /// + /// FPS type (e.g. 0x10 = 24p) + /// + public int FramesPerSecondType { get; set; } + + /** list of (list of) palette info - there are up to 8 palettes per epoch, each can be updated several times */ + public List> Palettes; + + public BluRaySupPicture(BluRaySupPicture subPicture) + { + Width = subPicture.Width; + Height = subPicture.Height; + StartTime = subPicture.StartTime; + EndTime = subPicture.EndTime; + IsForced = subPicture.IsForced; + CompositionNumber = subPicture.CompositionNumber; + + ObjectId = subPicture.ObjectId; + ImageObjects = new List(); + foreach (ImageObject io in subPicture.ImageObjects) + ImageObjects.Add(io); + WindowWidth = subPicture.WindowWidth; + WindowHeight = subPicture.WindowHeight; + WindowXOffset = subPicture.WindowXOffset; + WindowYOffset = subPicture.WindowYOffset; + FramesPerSecondType = subPicture.FramesPerSecondType; + Palettes = new List>(); + foreach (List palette in subPicture.Palettes) + { + List p = new List(); + foreach (PaletteInfo pi in palette) + { + p.Add(new PaletteInfo(pi)); + } + Palettes.Add(p); + } + } + + public BluRaySupPicture() + { + } + + public ImageObject GetImageObject(int index) + { + return ImageObjects[index]; + } + + internal ImageObject ObjectIdImage + { + get + { + return ImageObjects[ObjectId]; + } + } + + + /// + /// decode palette from the input stream + /// + /// SubPicture object containing info about the current caption + /// Palette object + public BluRaySupPalette DecodePalette(BluRaySupPalette defaultPalette) + { + BluRaySupPicture pic = this; + bool fadeOut = false; + if (pic.Palettes.Count == 0 || pic.ObjectIdImage.PaletteId >= pic.Palettes.Count) + { + System.Diagnostics.Debug.Print("Palette not found in objectID=" + pic.ObjectId + " PaletteId=" + pic.ObjectIdImage.PaletteId + "!"); + if (defaultPalette == null) + return new BluRaySupPalette(256, Core.UsesBt601()); + else + return new BluRaySupPalette(defaultPalette); + } + List pl = pic.Palettes[pic.ObjectIdImage.PaletteId]; + BluRaySupPalette palette = new BluRaySupPalette(256, Core.UsesBt601()); + // by definition, index 0xff is always completely transparent + // also all entries must be fully transparent after initialization + + for (int j = 0; j < pl.Count; j++) + { + PaletteInfo p = pl[j]; + int index = 0; + + for (int i = 0; i < p.PaletteSize; i++) + { + // each palette entry consists of 5 bytes + int palIndex = p.PaletteBuffer[index]; + int y = p.PaletteBuffer[++index]; + int cr, cb; + if (Core.GetSwapCrCb()) + { + cb = p.PaletteBuffer[++index]; + cr = p.PaletteBuffer[++index]; + } + else + { + cr = p.PaletteBuffer[++index]; + cb = p.PaletteBuffer[++index]; + } + int alpha = p.PaletteBuffer[++index]; + + int alphaOld = palette.GetAlpha(palIndex); + // avoid fading out + if (alpha >= alphaOld) + { + if (alpha < Core.GetAlphaCrop()) + {// to not mess with scaling algorithms, make transparent color black + y = 16; + cr = 128; + cb = 128; + } + palette.SetAlpha(palIndex, alpha); + } + else fadeOut = true; + + palette.SetYCbCr(palIndex, y, cb, cr); + index++; + } + } + if (fadeOut) + System.Diagnostics.Debug.Print("fade out detected -> patched palette\n"); + return palette; + } + + /// + /// Decode caption from the input stream + /// + /// SubPicture object containing info about the caption + /// index of the transparent color + /// bitmap of the decoded caption + public Bitmap DecodeImage(BluRaySupPalette defaultPalette) + { + int w = ObjectIdImage.Width; + int h = ObjectIdImage.Height; + + if (w > Width || h > Height) + throw new Exception("Subpicture too large: " + w + "x" + h); + + //Bitmap bm = new Bitmap(w, h); + FastBitmap bm = new FastBitmap(new Bitmap(w, h)); + bm.LockImage(); + BluRaySupPalette pal = DecodePalette(defaultPalette); + + int index = 0; + int ofs = 0; + int xpos = 0; + + // just for multi-packet support, copy all of the image data in one common buffer + byte[] buf = new byte[ObjectIdImage.BufferSize]; + foreach (ImageObjectFragment fragment in ObjectIdImage.Fragments) + { + Buffer.BlockCopy(fragment.ImageBuffer, 0, buf, index, fragment.ImagePacketSize); + index += fragment.ImagePacketSize; + } + + + index = 0; + do + { + int b = buf[index++] & 0xff; + if (b == 0) + { + b = buf[index++] & 0xff; + if (b == 0) + { + // next line + ofs = (ofs / w) * w; + if (xpos < w) + ofs += w; + xpos = 0; + } + else + { + int size; + if ((b & 0xC0) == 0x40) + { + // 00 4x xx -> xxx zeroes + size = ((b - 0x40) << 8) + (buf[index++] & 0xff); + for (int i = 0; i < size; i++) + PutPixel(bm, ofs++, 0, pal); + xpos += size; + } + else if ((b & 0xC0) == 0x80) + { + // 00 8x yy -> x times value y + size = (b - 0x80); + b = buf[index++] & 0xff; + for (int i = 0; i < size; i++) + PutPixel(bm, ofs++, b, pal); + xpos += size; + } + else if ((b & 0xC0) != 0) + { + // 00 cx yy zz -> xyy times value z + size = ((b - 0xC0) << 8) + (buf[index++] & 0xff); + b = buf[index++] & 0xff; + for (int i = 0; i < size; i++) + PutPixel(bm, ofs++, b, pal); + xpos += size; + } + else + { + // 00 xx -> xx times 0 + for (int i = 0; i < b; i++) + PutPixel(bm, ofs++, 0, pal); + xpos += b; + } + } + } + else + { + PutPixel(bm, ofs++, b, pal); + xpos++; + } + } while (index < buf.Length); + + bm.UnlockImage(); + return bm.GetBitmap(); + } + + private static void PutPixel(FastBitmap bmp, int index, int color, BluRaySupPalette palette) + { + int x = index % bmp.Width; + int y = index / bmp.Width; + if (color > 0 && x < bmp.Width && y < bmp.Height) + bmp.SetPixel(x, y, Color.FromArgb(palette.GetArgb(color))); + } + + + } + + public class ImageObject + { + /// + /// list of ODS packets containing image info + /// + public List Fragments; + + /// + /// palette identifier + /// + public int PaletteId { get; set; } + + /// + /// overall size of RLE buffer (might be spread over several packages) + /// + public int BufferSize { get; set; } + + /// + /// with of subtitle image + /// + public int Width { get; set; } + + /// + /// height of subtitle image + /// + public int Height { get; set; } + + /// + /// upper left corner of subtitle x + /// + public int XOffset { get; set; } + + /// + /// upper left corner of subtitle y + /// + public int YOffset { get; set; } + } + + + /// + /// contains offset and size of one fragment containing (parts of the) RLE buffer + /// + public class ImageObjectFragment + { + /// + /// size of this part of the RLE buffer + /// + public int ImagePacketSize { get; set; } + + /// + /// Buffer for raw image data fragment + /// + public byte[] ImageBuffer { get; set; } + } + + + /// + /// contains offset and size of one update of a palette + /// + public class PaletteInfo + { + /// + /// number of palette entries + /// + public int PaletteSize { get; set; } + + /// + /// raw palette data + /// + public byte[] PaletteBuffer { get; set; } + + public PaletteInfo() + { + } + + public PaletteInfo(PaletteInfo paletteInfo) + { + PaletteSize = paletteInfo.PaletteSize; + PaletteBuffer = new byte[paletteInfo.PaletteBuffer.Length]; + Buffer.BlockCopy(paletteInfo.PaletteBuffer, 0, PaletteBuffer, 0, PaletteBuffer.Length); + } + } + + +} diff --git a/src/Logic/BluRaySup/Core.cs b/src/Logic/BluRaySup/Core.cs new file mode 100644 index 000000000..6d7649d9a --- /dev/null +++ b/src/Logic/BluRaySup/Core.cs @@ -0,0 +1,87 @@ +/* + * Copyright 2009 Volker Oth (0xdeadbeef) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTE: Converted to C# and modified by Nikse.dk@gmail.com + */ +namespace Nikse.SubtitleEdit.Logic.BluRaySup +{ + public static class Core + { + + /** Use BT.601 color model instead of BT.709 */ + private const bool UseBt601 = false; + + /** Flag that defines whether to swap Cr/Cb components when loading a SUP */ + private const bool SwapCrCb = false; + + /** Alpha threshold for cropping */ + private const int AlphaCrop = 14; + + /** Two equal captions are merged of they are closer than 200ms (0.2*90000 = 18000) */ + private const int MergePtSdiff = 18000; + + /** Frames per seconds for 24p (23.976) */ + public static double Fps24P = 24000.0 / 1001; + /** Frames per seconds for wrong 24P (23.975) */ + public static double Fps23975 = 23.975; + /** Frames per seconds for 24Hz (24.0) */ + public static double Fps24Hz = 24.0; + /** Frames per seconds for PAL progressive (25.0) */ + public static double FpsPal = 25.0; + /** Frames per seconds for NTSC progressive (29.97) */ + public static double FpsNtsc = 30000.0 / 1001; + /** Frames per seconds for PAL interlaced (50.0) */ + public static double FpsPalI = 50.0; + /** Frames per seconds for NTSC interlaced (59.94) */ + public static double FpsNtscI = 60000.0 / 1001; + + /** + * Get maximum time difference for merging captions. + * @return Maximum time difference for merging captions + */ + public static int GetMergePtSdiff() + { + return MergePtSdiff; + } + + /** + * Get: use of BT.601 color model instead of BT.709. + * @return True if BT.601 is used + */ + public static bool UsesBt601() + { + return UseBt601; + } + + /** + * Get flag that defines whether to swap Cr/Cb components when loading a SUP. + * @return True: swap cr/cb + */ + public static bool GetSwapCrCb() + { + return SwapCrCb; + } + + /** + * Get alpha threshold for cropping. + * @return Alpha threshold for cropping + */ + public static int GetAlphaCrop() + { + return AlphaCrop; + } + + } +} diff --git a/src/Logic/BluRaySup/ToolBox.cs b/src/Logic/BluRaySup/ToolBox.cs new file mode 100644 index 000000000..04ab2d437 --- /dev/null +++ b/src/Logic/BluRaySup/ToolBox.cs @@ -0,0 +1,98 @@ +/* + * Copyright 2009 Volker Oth (0xdeadbeef) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTE: Converted to C# and modified by Nikse.dk@gmail.com + */ +using System.Text; + +namespace Nikse.SubtitleEdit.Logic.BluRaySup +{ + public static class ToolBox + { + + /// + /// Convert bytes to a C-style hex string with leading zeroes + /// + public static string ToHex(byte[] buffer, int index, int digits) + { + var sb = new StringBuilder(); + for (int i = index; i < index + digits; i++) + { + string s = string.Format("{0:X}", buffer[i]); + if (s.Length < 2) + sb.Append("0"); + sb.Append(s); + } + return "0x" + sb; + } + + /// + /// Convert a long integer to a C-style hex string with leading zeroes + /// + public static string ToHex(int number, int index, int digits) + { + string s = string.Format("{0:X}", number); + if (s.Length < digits) + s.PadLeft(digits, '0'); + return "0x" + s; + } + + + /// + /// Convert an integer to a string with leading zeroes + /// + /// Integer value to convert + /// Number of digits to display - note that a 32bit number can have only 10 digits + /// String version of integer with trailing zeroes + public static string ZeroTrim(int i, int digits) + { + string s = i.ToString(); + return s.PadLeft(digits, '0'); + } + + /** + * Convert time in milliseconds to array containing hours, minutes, seconds and milliseconds + * @param ms Time in milliseconds + * @return Array containing hours, minutes, seconds and milliseconds (in this order) + */ + public static int[] MillisecondsToTime(long ms) + { + int[] time = new int[4]; + // time[0] = hours + time[0] = (int)(ms / (60 * 60 * 1000)); + ms -= time[0] * 60 * 60 * 1000; + // time[1] = minutes + time[1] = (int)(ms / (60 * 1000)); + ms -= time[1] * 60 * 1000; + // time[2] = seconds + time[2] = (int)(ms / 1000); + ms -= time[2] * 1000; + time[3] = (int)ms; + return time; + } + + /** + * Convert time in 90kHz ticks to string hh:mm:ss.ms + * @param pts Time in 90kHz resolution + * @return String in format hh:mm:ss:ms + */ + public static string PtsToTimeString(long pts) + { + int[] time = MillisecondsToTime((pts + 45) / 90); + return ZeroTrim(time[0], 2) + ":" + ZeroTrim(time[1], 2) + ":" + ZeroTrim(time[2], 2) + "." + ZeroTrim(time[3], 3); + } + + } +} \ No newline at end of file diff --git a/src/Logic/ImageSplitter.cs b/src/Logic/ImageSplitter.cs index 224fc2a29..117783846 100644 --- a/src/Logic/ImageSplitter.cs +++ b/src/Logic/ImageSplitter.cs @@ -8,6 +8,13 @@ namespace Nikse.SubtitleEdit.Logic { public static bool IsColorClose(Color a, Color b, int tolerance) { + if (a.A < 120 && b.A < 120) + return true; // transparent + + if (a.A > 250 && a.R > 90 && a.G > 90 && a.B > 90 && + b.A > 250 && b.R > 90 && b.G > 90 && b.B > 90) + return true; // dark, non transparent + int diff = (a.R + a.G + a.B) - (b.R + b.G + b.B); return diff < tolerance && diff > -tolerance; } @@ -131,7 +138,9 @@ namespace Nikse.SubtitleEdit.Logic for (int y = 1; y < bmp1.Height; y++) { if (!IsColorClose(bmp1.GetPixel(x, y), bmp2.GetPixel(x, y), 20)) + { different++; + } } } return different; diff --git a/src/Logic/SubtitleFormats/UleadSubtitleFormat.cs b/src/Logic/SubtitleFormats/UleadSubtitleFormat.cs index 2568be17d..30ee4b61e 100644 --- a/src/Logic/SubtitleFormats/UleadSubtitleFormat.cs +++ b/src/Logic/SubtitleFormats/UleadSubtitleFormat.cs @@ -45,12 +45,10 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats #Subtitle text begin"; const string Footer = @"#Subtitle text end - #Subtitle text attribute begin -#/R:1,856 /FP:8 /FS:24 +#/R:1,{0} /FP:8 /FS:24 #Subtitle text attribute end"; - StringBuilder sb = new StringBuilder(); sb.AppendLine(Header); int index = 0; @@ -63,7 +61,7 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats sb.AppendLine(Utilities.RemoveHtmlTags(p.Text)); index++; } - sb.AppendLine(Footer); + sb.AppendLine(string.Format(Footer, subtitle.Paragraphs.Count)); return sb.ToString(); } diff --git a/src/Resources/da-DK.xml b/src/Resources/da-DK.xml index 1c3f7051b..96efbe8da 100644 --- a/src/Resources/da-DK.xml +++ b/src/Resources/da-DK.xml @@ -372,6 +372,7 @@ Sammenlign... Import/OCR undertekster fra VOB/IFO (dvd) ... Importer/OCR VobSub (sub/idx) undertekst... + Importer/OCR BluRay sup fil... Importer undertekster fra Matroska fil... Importer undertekst med manuel valgt tegnsæt... Importer tekst... @@ -672,7 +673,10 @@ Fortsæt? Header ikke gyldig VobSub fil: {0} Åbn VobSub (sub/idx) undertekst... VobSub undertekst filer - Før import af VobSub undertekster + Åbn BluRay sup fil... + BluRay sup filer + Før import af VobSub undertekst + Før import af BluRay sup undertekst Før vis udvalgte linjer tidligere/senere Vis tidligere/senere udført på udvalgte linjer Dobbelt ord via regex {0} @@ -973,7 +977,8 @@ Fortsæt? Billede - Importer/OCR VobSub (sub/idx) undertekster + Importer/OCR VobSub (sub/idx) undertekst + Importer/OCR BluRay (.sup) undertekst OCR-metoden OCR via Microsoft Office Document Imaging (MODI). Kræver MS Office OCR via Tesseract diff --git a/src/Resources/da-DK.xml.zip b/src/Resources/da-DK.xml.zip index f4f186a7a..5eef89dec 100644 Binary files a/src/Resources/da-DK.xml.zip and b/src/Resources/da-DK.xml.zip differ diff --git a/src/Resources/es-ES.xml b/src/Resources/es-ES.xml index 5061d4250..3dca95fb7 100644 --- a/src/Resources/es-ES.xml +++ b/src/Resources/es-ES.xml @@ -371,6 +371,7 @@ de inicio del próximo texto &Comparar... Importar/OCR subtítulo desde vob/ifo (dvd) ... Importar/subtítuloOCR VobSub (sub/idx)... + Importar/subtítuloOCR BluRay (.sup)... Importar subtítulo desde archivo Matroska... Importar subtítulo de modo manual eligiendo codificador... Importar texto... @@ -671,7 +672,10 @@ Continuar? Encabezado de archivoVobSub inválido: {0} Abrir subtítulo VobSub (sub/idx)... Subtítulos de archivos VobSub + Abrir subtítulo BluRay (.sup)... + Subtítulos de archivos BluRay Antes de importar subtítulos VobSub + Antes de importar subtítulos BluRay Antes de mostrar las líneas seleccionadas antes/después Mostrar el antes/después realizado sobre las líneas seleccionadas @@ -975,6 +979,7 @@ Continuar? Importar/subtítuloOCR VobSub (sub/idx) + Importar/subtítuloOCR BluRay (.sup) método OCR OCR vía Microsoft Office Document Imaging (MODI). MS Office requerido OCR a traves de Tesseract diff --git a/src/Resources/es-ES.xml.zip b/src/Resources/es-ES.xml.zip index 434fa87c8..ea4882ceb 100644 Binary files a/src/Resources/es-ES.xml.zip and b/src/Resources/es-ES.xml.zip differ diff --git a/src/Resources/fr-FR.xml b/src/Resources/fr-FR.xml index 3bfe7b5c3..38e4a0f1e 100644 --- a/src/Resources/fr-FR.xml +++ b/src/Resources/fr-FR.xml @@ -1,56 +1,56 @@ - - - - Subtitle Edit - 3.0 - Traduction française par zwim (zwim@free.fr) - fr-FR - &OK - A&nnuler - Activer - Aucun - Aperçu - Fichiers sous-titre - Tous fichiers - Fichiers vidéo - Ouvrir sous-titre... - Ouvrir fichier vidéo... - Pas de vidéo chargée - Info vidéo - Position / durée : {0} - Temps initial - Temps final - Durée - Numéro - Texte - heure:min:sec:msec - Gras - Italique - Visible - Cadence de trame - Nom - Nom du fichier : {0} ({1}) - Résolution : {0} - cadence de trame : {0:0.0###} - Trames au total : {0:#,##0.##} - Encodage vidéo : {0} - Longueur des lignes : - Longueur totale : {0} - Longueur totale : {0} (coupez la ligne!) - Indisponible - Chevauchement ligne préc. ({0:#,##0.###}) - Chevauchement ({0:#,##0.###}) - Chevauchement suivant ({0:#,##0.###}) - Négatif - Expression régulière invalide ! - Sous-titre sauvegardé - Sous-titre courant - Texte original - Ouvrir fichier sous-titre original... - Patientez... - - - A propos de Subtitle Edit + + + + Subtitle Edit + 3.0 + Traduction française par zwim (zwim@free.fr) + fr-FR + &OK + A&nnuler + Activer + Aucun + Aperçu + Fichiers sous-titre + Tous fichiers + Fichiers vidéo + Ouvrir sous-titre... + Ouvrir fichier vidéo... + Pas de vidéo chargée + Info vidéo + Position / durée : {0} + Temps initial + Temps final + Durée + Numéro + Texte + heure:min:sec:msec + Gras + Italique + Visible + Cadence de trame + Nom + Nom du fichier : {0} ({1}) + Résolution : {0} + cadence de trame : {0:0.0###} + Trames au total : {0:#,##0.##} + Encodage vidéo : {0} + Longueur des lignes : + Longueur totale : {0} + Longueur totale : {0} (coupez la ligne!) + Indisponible + Chevauchement ligne préc. ({0:#,##0.###}) + Chevauchement ({0:#,##0.###}) + Chevauchement suivant ({0:#,##0.###}) + Négatif + Expression régulière invalide ! + Sous-titre sauvegardé + Sous-titre courant + Texte original + Ouvrir fichier sous-titre original... + Patientez... + + + A propos de Subtitle Edit Subtitle Edit est un logiciel gratuit distribué sous licence publique GNU. Vous pouvez le distribuer, le modifier et l'utiliser librement. @@ -60,976 +60,981 @@ Visitez www.nikse.dk pour obtenir la dernière version. Les suggestions sont plus que bienvenues. -Email : mailto:nikse.dk@gmail.com - - - Ajouter à la liste noms/etc - Ajouter à la liste noms/bruit (sensible à la casse) - - - Générer forme à partir des données - Fichier vidéo source: - Générer forme à partir des données - Ceci peut prendre quelques minutes - patientez - VLC Media Player introuvable - Subtitle Edit a besoin de VLC media player 1.1.x ou suivant pour extraire les données audio - Voulez-vous aller sur le site de VLC media player? - Génération du fichier des pics... - Extraction audio: {0:0.0} secondes - Extraction audio: {0}:{1:00} secondes - - - Ajuster les durées - Ajuster selon - Secondes - Pourcentage - Ajouter des secondes - Déterminer en % de la durée - Note : L'instant d'affichage ne recouvre pas le temps initial du texte suivant - Veuillez sélectionner une valeur dans la liste déroulante - - Veuillez choisir - - - - Lignes sélectionnées équilibrées auto - Enlever les retours à la ligne dans la sélection - Ligne# - Avant - Après - Lignes trouvées : {0} - Seulement les lignes coupées plus longues de - Seulement les lignes non-coupées plus courtes de - - - Changer la casse - Changer la casse en - Casse normale. Les phrases commencent par une majuscule. - Fixer la casse des noms (via Dictionaries\NamesEtc.xml) - Fixer seulement la casse des noms (via Dictionaries\NamesEtc.xml) - Changer seulement les lignes en majuscules. - TOUT EN MAJUSCULE - Tout en minuscule - - - Changer la casse - Noms - Noms trouvés dans le sous-titre : {0} - Activé - Nom - Ligne# - Avant - Après - Lignes trouvées : {0} - - - Changer la cadence de trame - Convertir la cadence de trame du sous-titre - Vitesse de départ - Vitesse désirée - - - Choisissez l'encodage - Page de code - Afficher nom - Choisissez un encodage - - - Choisissez la langue - Langue - - - Comparer les sous-titres - Différence &précédente - Différence &suivante - Les sous-titres ne sont pas similaires - Nombre de différences : {0} - Cacher les lignes identiques - Ne considérer que les différences dans le texte - - - Ripper les sous-titres à partir de ifo/vobs (dvd) - fichiers DVD/info - Fichier IFO - Fichiers IFO - Fichiers VOB - Ajouter... - Retirer - Nettoyer - Monter - Descendre - Langues - PAL/NTSC - PAL (25fps) - NTSC (30fps) - Démarrer l'extraction - Interrompre - Interrompue par l'utilisateur - Données sous-titres de lecture... - Ripper fichier vob {1} de {2}: {0} - - - Choix de la langue - Choix de la langue (stream-id) - Langue inconnue - Image du sous-titre {0}/{1} - {2}x{3} - - - Effet karaoke - Choisissez une couleur : - Millisecs. total: - Délai de fin en millisecs.: - - - Effet machine à écrire - Millisecs. total: - Délai de fin en millisecs.: - - - Rechercher - Chercher - Normal - Sensible à la casse - Expression régulière - - - Chercher la ligne de sous-titre - Re&chercher - Chercher &suivant - - - Correction des erreurs fréquentes - Etape 1/2 - Choix des erreurs à corriger - Quoi faire - Exemple - Tout sélect. - Inverser sélect. - < &Retour - &Suivant > - Etape 2/2 - Vérification des corrections - Corrections - Rapport - Ligne# - Fonction - Avant - Après - Ligne vide supprimée - Ligne vide supprimée au début - Ligne vide supprimée à la fin - Supprimer les lignes vides/sauts de lignes inutiles - Lignes vides supprimées : {0} - Corriger les temps d'affichage qui se chevauchent - Corriger les temps d'affichage trop courts - Corriger les temps d'affichage trop longs - Corriger le marquage en italique invalide - Supprimer les espaces inutiles - Supprimer la ponctuation inutile - Rajouter les espaces manquants - Couper les lignes longues - Supprimer les sauts de lignes dans les paragraphes courts avec une seule phrase - Corriger le 'i' majuscule à l'intérieur des mots (erreur OCR) - Remplacer les apostrophes doubles (' ') par un guillemet (") - Ajouter un point quand la ligne suivante commence par une majuscule - Commencer par une majuscule après un paragraphe - Mettre une majuscule après un point dans un paragraphe - Remplacer le i minuscule isolé par un I (Anglais) - Corriger les erreurs OCR fréquentes (d'après la liste des correctifs OCR) - Erreurs OCR fréquentes corrigées (d'après le fichier OcrReplaceList) : {0} - Corriger le 'i' danois - Retourner les points d'exclamation et d'interrogation espagnols - Ajout du guillemet (") manquant - Ajouter des guillemets (") manquants - Corriger les lignes commençant par un tiret (-) - Correction de la ligne commençant par un tiret (-) - Tirets corrigés : {0} - "Comment ça va ? -> "Comment ça va ?" - Guillemets ajoutés : {0} - Corriger les sous-titres de plus de deux lignes - Correction du sous-titre de plus de deux lignes - Sous-titre de plus de deux lignes corrigés : {0} - Analyse... - Rien à corriger :) - Corrections trouvées : {0} - Corrections effectuées : {0} - Rien à corriger mais quelques points peuvent être améliorés - voir le rapport - "Le remplacement du 'i' minuscule isolé en 'I' (Anglais)" est activé mais le sous-titre actuel ne semble pas être de l'anglais. - Continuer - Continuer quand même ? - Unchecked "Fix alone lowercase 'i' to 'I' (English)" - {0} i mis en majuscule - Mettre la première lettre en majuscule après un paragraphe - Fusionner ligne courte - {0} saut(s) de lignes ajouté(s) - Couper ligne longue - Corriger temps long - Corriger italique - Corriger temps court - Corriger chevauchement temporel - <i>Qu'est-ce j'en ai à faire.<i> -> <i>Qu'est-ce j'en ai à faire.</i> - Hé toi , là bas. -> Hé toi, là bas. - Hé toi !. -> Hé toi ! - Hé.Toi. -> Hé. Toi. - La fIn est proche. -> La fin est proche. - What do i care. -> What do I care. - Texte n°{0} : Le temps initial est postérieur au temps final : {4}{1} --> {2} {3} - Impossible de corriger le texte n°{0} : temps initial > temps final : {1} - {0} Corrigé en : {1}{2} - Impossible de corriger le texte n°{0} : {1} - {0} chevauchement(s) temporel(s) corrigé(s) - {0} temps d'affichage prolongé(s) - {0} marquage(s) html corrigé(s) - {0} temps d'affichage raccourci(s) - {0} ligne(s) recollée(s) - Espace inutile - {0} epace(s) inutile(s) enlevé(s) - Ponctuation inutile - {0} point(s) inutile(s) enlevé(s) - Correction espace manquant - {0} epace(s) manquant(s) ajouté(s) - Correction du 'i' majuscule dans un mot en minuscule - {0} point(s) ajouté(s). - Ajout point final - {0} apostrophe(s) double(s) corrigée(s). - {0} 'i' majuscule(s) trouvé(s) dans un mot en minuscules - Rafraîchir corrections disponibles - Effectuer les corrections sélectionnées - &Couper - &Joindre - Correction '--' -> '...' - Effacer les >> - Effacer les '...' en début de ligne - Apparier les [ dans une ligne - Remplacer les symboles musicaux (i.e. âTª) par le symbole préféré - Correction des '--' -> '...' - Enlever les >> depuis le début - Enlever les ... depuis le début - Correction des [ manquants - Remplacer les âTª par des * - {0} '--' corrigé(s) - {0} >> effacé(s) - {0} '...' en début enlevé(s) - {0} [ manquant(s) dans une ligne ajouté(s) - {0} notation(s) musicale(s) dans une ligne corrigée(s) - 'Whoa-- um yeah!' --> 'Whoa... um yeah!' - '>> Robert : ça gaze !' --> 'Robert : ça gaze !' - '... et ensuite nous' -> 'et ensuite nous' - 'clic] Attention !' --> '[clic] Attention !' - 'âTª sweet dreams are' --> '♫ sweet dreams are' - {0} messages traces importants! - - - Besoin de dictionnaires ? - Le correcteur d'orthographe de Subtitle Edit est basé sur le moteur - NHunspell qui utilise les dictionnaires d'Open Office. - Récupérez les dictionnaires ici : - Liste de dictionnaires du Wiki d'Open Office - Récuperer tous les dictionnaires - Choisir sa langue et cliquer sur télécharger - Ouvrir le dossier 'Dictionaries' - Télécharger - {0} a été téléchargé et installé - - - Google translate - De: - A: - Traduire - S'il vous plaît patienter... Cela peut prendre un certain temps - Réalisé avec Google traduction - Réalisé avec Microsoft traduction - - - Aller au sous-titre numéro - {0} n'est pas un nombre valide - - - Importer text - Ouvrir le fichier texte... - Options d'importation - Scinder - Découpage automatique du texte - Une ligne est un sous-titre - Fusionner les lignes courtes avec suite - Supprimez les lignes vides - Supprimez les lignes sans lettres - Écart entre les sous-titres (en millisecondes) - Auto - Fixé - &Actualiser - &Suivant>> - Les fichiers texte - Aperçu - paragraphes modification: {0} - -
- - - &Fichier - &Nouveau - &Ouvrir - &Réouvrir - &Sauver - Sauver so&us... - Ouvrir répertoire contenant les sous-titres - &Comparer... - Import/sous-titres OCR de VOB/IFO (DVD) ... - Import/OCR VobSub (sub/idx) sous-titres... - Sous-titres d'importation de fichier Matroska... - Sous-titres d'importation avec le codage choisi manuel... - Importer texte... - Importer temporisation... - &Quitter - - - &Edition - Montrer l'&historique (pour annulation) - Montrer texte original (mode traduction) - Cacher texte original - &Insérer un symbole unicode - Re&chercher - Chercher &suivant - &Remplacer - Remplacement &multiple... - &Aller au sous-titre n°... - - - Ou&tils - Ajuster &durées... - Correction des &erreurs fréquentes... - Nouvelle &numérotation... - Supprimer le texte pour &malentendants... - Changer la &casse... - Changer la vites&se de trame... - &Fusionner les lignes courtes... - Temps d'affichage minimum entre paragraphes... - T&rier par - Texte - alphabétique - Texte - longueur max d'une ligne - Texte - longueur totale - Texte - nombre de lignes - Part&itionner les sous-titres... - Compléter les so&us-titres... - - - - Orthographe - &Vérifier orthographe - Trouver doublons - Télécharger dictionnaires... - Ajouter des mots à la liste noms/etc - - - Synchronisation - Ajuster tous les temps (montrer précédent/Suivant) - &Synchronisation visuelle... - Synchronisation par points... - - - Traduction - Traduire (avec Google)... - Traduire (avec Microsoft) - Traduire du Suèdois au Danois (avec nikse.dk) - - - &Options - &Configuration... - Choix de la &langue... - - - &Aide - &Aide - A &propos - - - Nouveau - Ouvrir - Sauver - Sauver sous - Rechercher - Remplacer - Synchronisation visuelle - Correcteur d'orthographe - Configuration - Aide - Montrer/cacher forme sonore - Montrer/cacher vidéo - - - Effacer - Insérer avant - Insérer après - Scinder - Fusionner les lignes sélectionnées - Fusionner avec la ligne précédente - Fusionner avec la ligne suivante - Normal - Souligner - Couleur... - Nom de la fonte... - Balance automatique des lignes sélectionnées... - Retirez les retours à la ligne des lignes sélectionnées... - Effet machine à écrire... - Effet karaoké... - Afficher les options sélectionnées lignes plus tôt/tard... - Lignes choisies en synchronisation visuelle... - Traduction Google des lignes sélectionnées... - Régler la durée des lignes sélectionnées... - Correction des erreurs communes dans les lignes sélectionnées... - Changer la casse pour les lignes sélectionnées... - - - - Format de sous-titre - Encodage de fichier - Vue liste - Vue source - Annuler changement - < Préc. - Suiv. > - Couper - Joindre - - - Traduire - Créer - Ajuster - Sélectionner sous-titre courant pendant la lecture - Répétition automatique - Répétition automatique activée - Nombre de répétitions - Continuation automatique - Cont. automatique activée - Durée de la pause (secondes) - Texte original - < Pré&cédent - &Stop - &Lire - &Suivant > - Lecture... - Répéter...temps précédent - Répéter...{0} temps restant - Suite automatique dans une seconde - Suite automatique dans {0} secondes - Frappe en cours...suite automatique interrompue - &Insérer nouveau sous-titre - Automatique - Lecture juste avant &texte - Pause - Aller à la sélection puis pause - Définir &début - Définir &fin et aller au suivant - Définir f&in - Définir déb&ut et décaler la suite - Chercher texte en ligne - Traduction Google - Google - << secs - secs >> - Position vidéo: - <alt+flèche haut/bas> pour avancer/reculer d'un sous-titre - <ctrl+flèche gauche/droite> - <alt+flèche haut/bas> pour avancer/reculer d'un sous-titre - Temps modifié précédent dans le signal : {0} - Nouveau texte inséré à {0} - - Enregistrer les modifications sans titre? - Enregistrer les modifications de {0}? - Sauver sous-titre comme... - Pas de sous-titres chargé - Synchronisation visuelle - lignes sélectionnées - Synchronisation visuelle - Avant de synchronisation visuelle - Synchronisation visuelle effectués sur des lignes sélectionnées - Synchronisation visuelle effectuée - Importer ce sous-titre VobSub? - Fichier supérieure à 10 Mo: {0} - Continuer malgré tout? - Avant chargement de {0} - Sous-titres chargés {0} - Sous-titre vide ou très court chargé {0} - Le fichier est vide ou très courte! - Fichier introuvable: {0} - Sous-titres enregistrés {0} - Ffichier sur disque modifié - Écraser le fichier {0} modifiée à {1} {2}{3} avec le fichier actuel chargé à {4} {5}? - Impossible d'enregistrer le fichier sous-titre {0} - Avant nouveau - Nouveau - Avant de convertir en {0} - Converti en {0} - Avant de montrer précédent - Avant de montrer suivant - Ligne numéro: {0:#,##0.##} - Ouvrir fichier vidéo... - Nouvelle cadence de frame ({0}) a été utilisée pour calculer l'heure de début/fin - Nouvelle cadence de frame ({0}) a été utilisé pour le calcul des numéros de frame de début/fin - L'élément de recherche n'a pas été trouvé. Souhaitez-vous recommencer à partir du haut du document et faire une nouvelle recherche? - Continuer trouver? - "{0} 'trouvé à la ligne {1} - '{0}' introuvable - Avant de remplacer: {0} - Correspondance trouve: {0} - Aucune correspondance trouvée: {0} - Riien trouvé à remplacer - Nb de remplacement: {0} - Correspondance trouvée à la ligne {0}: {1} - Un remplacement effectué. - Avant les modifications apportées en mode Source - Impossible d'analyser le texte source! - Aller au numéro de la ligne {0} - Créer/modifier les lignes changées appliqués - Lignes sélectionnées - Avant le réglage du temps d'affichage - Afficher les temps ajustés: {0} - Avant les corrections d'erreurs courantes - Erreurs courantes corrigées dans les lignes sélectionnées - Erreurs courantes corrigées - Avant renumérotation - Renuméroté à partir de: {0} - Avant l'enlèvement des SMS pour les malentendants - Messages pour malentendants enlevé: Une ligne - Messages pour malentendants enlevé: {0} lignes - Sous-titre découpé +Email : mailto:nikse.dk@gmail.com + + + Ajouter à la liste noms/etc + Ajouter à la liste noms/bruit (sensible à la casse) + + + Générer forme à partir des données + Fichier vidéo source: + Générer forme à partir des données + Ceci peut prendre quelques minutes - patientez + VLC Media Player introuvable + Subtitle Edit a besoin de VLC media player 1.1.x ou suivant pour extraire les données audio + Voulez-vous aller sur le site de VLC media player? + Génération du fichier des pics... + Extraction audio: {0:0.0} secondes + Extraction audio: {0}:{1:00} secondes + + + Ajuster les durées + Ajuster selon + Secondes + Pourcentage + Ajouter des secondes + Déterminer en % de la durée + Note : L'instant d'affichage ne recouvre pas le temps initial du texte suivant + Veuillez sélectionner une valeur dans la liste déroulante + - Veuillez choisir - + + + Lignes sélectionnées équilibrées auto + Enlever les retours à la ligne dans la sélection + Ligne# + Avant + Après + Lignes trouvées : {0} + Seulement les lignes coupées plus longues de + Seulement les lignes non-coupées plus courtes de + + + Changer la casse + Changer la casse en + Casse normale. Les phrases commencent par une majuscule. + Fixer la casse des noms (via Dictionaries\NamesEtc.xml) + Fixer seulement la casse des noms (via Dictionaries\NamesEtc.xml) + Changer seulement les lignes en majuscules. + TOUT EN MAJUSCULE + Tout en minuscule + + + Changer la casse - Noms + Noms trouvés dans le sous-titre : {0} + Activé + Nom + Ligne# + Avant + Après + Lignes trouvées : {0} + + + Changer la cadence de trame + Convertir la cadence de trame du sous-titre + Vitesse de départ + Vitesse désirée + + + Choisissez l'encodage + Page de code + Afficher nom + Choisissez un encodage + + + Choisissez la langue + Langue + + + Comparer les sous-titres + Différence &précédente + Différence &suivante + Les sous-titres ne sont pas similaires + Nombre de différences : {0} + Cacher les lignes identiques + Ne considérer que les différences dans le texte + + + Ripper les sous-titres à partir de ifo/vobs (dvd) + fichiers DVD/info + Fichier IFO + Fichiers IFO + Fichiers VOB + Ajouter... + Retirer + Nettoyer + Monter + Descendre + Langues + PAL/NTSC + PAL (25fps) + NTSC (30fps) + Démarrer l'extraction + Interrompre + Interrompue par l'utilisateur + Données sous-titres de lecture... + Ripper fichier vob {1} de {2}: {0} + + + Choix de la langue + Choix de la langue (stream-id) + Langue inconnue + Image du sous-titre {0}/{1} - {2}x{3} + + + Effet karaoke + Choisissez une couleur : + Millisecs. total: + Délai de fin en millisecs.: + + + Effet machine à écrire + Millisecs. total: + Délai de fin en millisecs.: + + + Rechercher + Chercher + Normal + Sensible à la casse + Expression régulière + + + Chercher la ligne de sous-titre + Re&chercher + Chercher &suivant + + + Correction des erreurs fréquentes + Etape 1/2 - Choix des erreurs à corriger + Quoi faire + Exemple + Tout sélect. + Inverser sélect. + < &Retour + &Suivant > + Etape 2/2 - Vérification des corrections + Corrections + Rapport + Ligne# + Fonction + Avant + Après + Ligne vide supprimée + Ligne vide supprimée au début + Ligne vide supprimée à la fin + Supprimer les lignes vides/sauts de lignes inutiles + Lignes vides supprimées : {0} + Corriger les temps d'affichage qui se chevauchent + Corriger les temps d'affichage trop courts + Corriger les temps d'affichage trop longs + Corriger le marquage en italique invalide + Supprimer les espaces inutiles + Supprimer la ponctuation inutile + Rajouter les espaces manquants + Couper les lignes longues + Supprimer les sauts de lignes dans les paragraphes courts avec une seule phrase + Corriger le 'i' majuscule à l'intérieur des mots (erreur OCR) + Remplacer les apostrophes doubles (' ') par un guillemet (") + Ajouter un point quand la ligne suivante commence par une majuscule + Commencer par une majuscule après un paragraphe + Mettre une majuscule après un point dans un paragraphe + Remplacer le i minuscule isolé par un I (Anglais) + Corriger les erreurs OCR fréquentes (d'après la liste des correctifs OCR) + Erreurs OCR fréquentes corrigées (d'après le fichier OcrReplaceList) : {0} + Corriger le 'i' danois + Retourner les points d'exclamation et d'interrogation espagnols + Ajout du guillemet (") manquant + Ajouter des guillemets (") manquants + Corriger les lignes commençant par un tiret (-) + Correction de la ligne commençant par un tiret (-) + Tirets corrigés : {0} + "Comment ça va ? -> "Comment ça va ?" + Guillemets ajoutés : {0} + Corriger les sous-titres de plus de deux lignes + Correction du sous-titre de plus de deux lignes + Sous-titre de plus de deux lignes corrigés : {0} + Analyse... + Rien à corriger :) + Corrections trouvées : {0} + Corrections effectuées : {0} + Rien à corriger mais quelques points peuvent être améliorés - voir le rapport + "Le remplacement du 'i' minuscule isolé en 'I' (Anglais)" est activé mais le sous-titre actuel ne semble pas être de l'anglais. + Continuer + Continuer quand même ? + Unchecked "Fix alone lowercase 'i' to 'I' (English)" + {0} i mis en majuscule + Mettre la première lettre en majuscule après un paragraphe + Fusionner ligne courte + {0} saut(s) de lignes ajouté(s) + Couper ligne longue + Corriger temps long + Corriger italique + Corriger temps court + Corriger chevauchement temporel + <i>Qu'est-ce j'en ai à faire.<i> -> <i>Qu'est-ce j'en ai à faire.</i> + Hé toi , là bas. -> Hé toi, là bas. + Hé toi !. -> Hé toi ! + Hé.Toi. -> Hé. Toi. + La fIn est proche. -> La fin est proche. + What do i care. -> What do I care. + Texte n°{0} : Le temps initial est postérieur au temps final : {4}{1} --> {2} {3} + Impossible de corriger le texte n°{0} : temps initial > temps final : {1} + {0} Corrigé en : {1}{2} + Impossible de corriger le texte n°{0} : {1} + {0} chevauchement(s) temporel(s) corrigé(s) + {0} temps d'affichage prolongé(s) + {0} marquage(s) html corrigé(s) + {0} temps d'affichage raccourci(s) + {0} ligne(s) recollée(s) + Espace inutile + {0} epace(s) inutile(s) enlevé(s) + Ponctuation inutile + {0} point(s) inutile(s) enlevé(s) + Correction espace manquant + {0} epace(s) manquant(s) ajouté(s) + Correction du 'i' majuscule dans un mot en minuscule + {0} point(s) ajouté(s). + Ajout point final + {0} apostrophe(s) double(s) corrigée(s). + {0} 'i' majuscule(s) trouvé(s) dans un mot en minuscules + Rafraîchir corrections disponibles + Effectuer les corrections sélectionnées + &Couper + &Joindre + Correction '--' -> '...' + Effacer les >> + Effacer les '...' en début de ligne + Apparier les [ dans une ligne + Remplacer les symboles musicaux (i.e. âTª) par le symbole préféré + Correction des '--' -> '...' + Enlever les >> depuis le début + Enlever les ... depuis le début + Correction des [ manquants + Remplacer les âTª par des * + {0} '--' corrigé(s) + {0} >> effacé(s) + {0} '...' en début enlevé(s) + {0} [ manquant(s) dans une ligne ajouté(s) + {0} notation(s) musicale(s) dans une ligne corrigée(s) + 'Whoa-- um yeah!' --> 'Whoa... um yeah!' + '>> Robert : ça gaze !' --> 'Robert : ça gaze !' + '... et ensuite nous' -> 'et ensuite nous' + 'clic] Attention !' --> '[clic] Attention !' + 'âTª sweet dreams are' --> '♫ sweet dreams are' + {0} messages traces importants! + + + Besoin de dictionnaires ? + Le correcteur d'orthographe de Subtitle Edit est basé sur le moteur + NHunspell qui utilise les dictionnaires d'Open Office. + Récupérez les dictionnaires ici : + Liste de dictionnaires du Wiki d'Open Office + Récuperer tous les dictionnaires + Choisir sa langue et cliquer sur télécharger + Ouvrir le dossier 'Dictionaries' + Télécharger + {0} a été téléchargé et installé + + + Google translate + De: + A: + Traduire + S'il vous plaît patienter... Cela peut prendre un certain temps + Réalisé avec Google traduction + Réalisé avec Microsoft traduction + + + Aller au sous-titre numéro + {0} n'est pas un nombre valide + + + Importer text + Ouvrir le fichier texte... + Options d'importation + Scinder + Découpage automatique du texte + Une ligne est un sous-titre + Fusionner les lignes courtes avec suite + Supprimez les lignes vides + Supprimez les lignes sans lettres + Écart entre les sous-titres (en millisecondes) + Auto + Fixé + &Actualiser + &Suivant>> + Les fichiers texte + Aperçu - paragraphes modification: {0} + +
+ + + &Fichier + &Nouveau + &Ouvrir + &Réouvrir + &Sauver + Sauver so&us... + Ouvrir répertoire contenant les sous-titres + &Comparer... + Import/sous-titres OCR de VOB/IFO (DVD) ... + Import/OCR VobSub (sub/idx) sous-titres... + Import/OCR BluRay (.sup) sous-titres... + Sous-titres d'importation de fichier Matroska... + Sous-titres d'importation avec le codage choisi manuel... + Importer texte... + Importer temporisation... + &Quitter + + + &Edition + Montrer l'&historique (pour annulation) + Montrer texte original (mode traduction) + Cacher texte original + &Insérer un symbole unicode + Re&chercher + Chercher &suivant + &Remplacer + Remplacement &multiple... + &Aller au sous-titre n°... + + + Ou&tils + Ajuster &durées... + Correction des &erreurs fréquentes... + Nouvelle &numérotation... + Supprimer le texte pour &malentendants... + Changer la &casse... + Changer la vites&se de trame... + &Fusionner les lignes courtes... + Temps d'affichage minimum entre paragraphes... + T&rier par + Texte - alphabétique + Texte - longueur max d'une ligne + Texte - longueur totale + Texte - nombre de lignes + Part&itionner les sous-titres... + Compléter les so&us-titres... + + + + Orthographe + &Vérifier orthographe + Trouver doublons + Télécharger dictionnaires... + Ajouter des mots à la liste noms/etc + + + Synchronisation + Ajuster tous les temps (montrer précédent/Suivant) + &Synchronisation visuelle... + Synchronisation par points... + + + Traduction + Traduire (avec Google)... + Traduire (avec Microsoft) + Traduire du Suèdois au Danois (avec nikse.dk) + + + &Options + &Configuration... + Choix de la &langue... + + + &Aide + &Aide + A &propos + + + Nouveau + Ouvrir + Sauver + Sauver sous + Rechercher + Remplacer + Synchronisation visuelle + Correcteur d'orthographe + Configuration + Aide + Montrer/cacher forme sonore + Montrer/cacher vidéo + + + Effacer + Insérer avant + Insérer après + Scinder + Fusionner les lignes sélectionnées + Fusionner avec la ligne précédente + Fusionner avec la ligne suivante + Normal + Souligner + Couleur... + Nom de la fonte... + Balance automatique des lignes sélectionnées... + Retirez les retours à la ligne des lignes sélectionnées... + Effet machine à écrire... + Effet karaoké... + Afficher les options sélectionnées lignes plus tôt/tard... + Lignes choisies en synchronisation visuelle... + Traduction Google des lignes sélectionnées... + Régler la durée des lignes sélectionnées... + Correction des erreurs communes dans les lignes sélectionnées... + Changer la casse pour les lignes sélectionnées... + + + + Format de sous-titre + Encodage de fichier + Vue liste + Vue source + Annuler changement + < Préc. + Suiv. > + Couper + Joindre + + + Traduire + Créer + Ajuster + Sélectionner sous-titre courant pendant la lecture + Répétition automatique + Répétition automatique activée + Nombre de répétitions + Continuation automatique + Cont. automatique activée + Durée de la pause (secondes) + Texte original + < Pré&cédent + &Stop + &Lire + &Suivant > + Lecture... + Répéter...temps précédent + Répéter...{0} temps restant + Suite automatique dans une seconde + Suite automatique dans {0} secondes + Frappe en cours...suite automatique interrompue + &Insérer nouveau sous-titre + Automatique + Lecture juste avant &texte + Pause + Aller à la sélection puis pause + Définir &début + Définir &fin et aller au suivant + Définir f&in + Définir déb&ut et décaler la suite + Chercher texte en ligne + Traduction Google + Google + << secs + secs >> + Position vidéo: + <alt+flèche haut/bas> pour avancer/reculer d'un sous-titre + <ctrl+flèche gauche/droite> + <alt+flèche haut/bas> pour avancer/reculer d'un sous-titre + Temps modifié précédent dans le signal : {0} + Nouveau texte inséré à {0} + + Enregistrer les modifications sans titre? + Enregistrer les modifications de {0}? + Sauver sous-titre comme... + Pas de sous-titres chargé + Synchronisation visuelle - lignes sélectionnées + Synchronisation visuelle + Avant de synchronisation visuelle + Synchronisation visuelle effectués sur des lignes sélectionnées + Synchronisation visuelle effectuée + Importer ce sous-titre VobSub? + Fichier supérieure à 10 Mo: {0} + Continuer malgré tout? + Avant chargement de {0} + Sous-titres chargés {0} + Sous-titre vide ou très court chargé {0} + Le fichier est vide ou très courte! + Fichier introuvable: {0} + Sous-titres enregistrés {0} + Ffichier sur disque modifié + Écraser le fichier {0} modifiée à {1} {2}{3} avec le fichier actuel chargé à {4} {5}? + Impossible d'enregistrer le fichier sous-titre {0} + Avant nouveau + Nouveau + Avant de convertir en {0} + Converti en {0} + Avant de montrer précédent + Avant de montrer suivant + Ligne numéro: {0:#,##0.##} + Ouvrir fichier vidéo... + Nouvelle cadence de frame ({0}) a été utilisée pour calculer l'heure de début/fin + Nouvelle cadence de frame ({0}) a été utilisé pour le calcul des numéros de frame de début/fin + L'élément de recherche n'a pas été trouvé. Souhaitez-vous recommencer à partir du haut du document et faire une nouvelle recherche? + Continuer trouver? + "{0} 'trouvé à la ligne {1} + '{0}' introuvable + Avant de remplacer: {0} + Correspondance trouve: {0} + Aucune correspondance trouvée: {0} + Riien trouvé à remplacer + Nb de remplacement: {0} + Correspondance trouvée à la ligne {0}: {1} + Un remplacement effectué. + Avant les modifications apportées en mode Source + Impossible d'analyser le texte source! + Aller au numéro de la ligne {0} + Créer/modifier les lignes changées appliqués + Lignes sélectionnées + Avant le réglage du temps d'affichage + Afficher les temps ajustés: {0} + Avant les corrections d'erreurs courantes + Erreurs courantes corrigées dans les lignes sélectionnées + Erreurs courantes corrigées + Avant renumérotation + Renuméroté à partir de: {0} + Avant l'enlèvement des SMS pour les malentendants + Messages pour malentendants enlevé: Une ligne + Messages pour malentendants enlevé: {0} lignes + Sous-titre découpé Ceci concatènera un sous-titre au sous-titre actuellement chargé qui devrait déjà être en synchronisation avec un fichier vidéo. -Poursuivre? - Compléter des sous-titres - Sous-titre ouvert à compléter... - Synchronisation visuelle - ajouter deuxième partie de sous-titre - Ajouter ce sous-titre synchronisé? - Avant ajout - Sous-titre ajouté: {0} - Sous-titre non ajouté! - Traduction Google - Traduction Microsoft - Avant la traduction Google - Lignes sélectionnées traduites - Sous-titre traduit - Traduire sous-titre Suèdois actuellement chargé en Danois - Traduire les sous-titres Suédois actuellement chargés (est-ce bien du suédois?) en Danois? - Traduction par www.nikse.dk/mt... - Avant traduction du Suédois en Danois - Traduction du Suédois en Danois terminée - Traduction du Suédois en Danois échouée - Avant d'annuler - Annuler effectué - Rien à annuler - Nom de langue invalide : {0} - Impossible de changer de langue! - Nombre de mots corrigés: {0} - Nombre de mots ignorés: {0} - Nombre de mots corrects: {0} - Nombre de mots ajoutés au dictionnaire: {0} - Nombre de hits pour nom: {0} - Correcteur d'orthographe - Avant la vérification orthographique - Vérification orthographique: Changé '{0}' en '{1} " - Avant d'ajouter <{0}> tag - <{0}> tags ajoutés - ligne {0} de {1} - {0} lignes supprimées - Avant de supprimer {0} lignes - Supprimer {0} lignes? - Ligne supprimée - Avant de supprimer une ligne - Supprimer une ligne? - Avant d'insérer ligne - Ligne insérée - Avant ligne mise à jour dans listview - Avant de définir la fonte à normale - Avant séparer la ligne - Line séparée - Avant de fusionner les lignes - Lignes fusionnées - Avant de régler la couleur - Avant de définir le nom de fonte - Avant effet machine à écrire - Avant effet karaoké - Avant d'importer des sous-titres du DVD - Ouvrir le fichier Matroska... - Fichiers Matroska - Aucun sous-titre trouvé - Ce n'est pas un fichier matroska valide : {0} - Analyse du fichier Matroska. Patientez... - Avant l'importation de sous-titres du fichier Matroska - Sous-titre importés de fichier Matroska - Déposer fichier '{0}' impossible - fichier trop volumineux - Vous ne pouvez déposer qu'un fichier - Avant de créer/modifier les lignes - Ouvrir sous-titre... - Avant de changer la casse - Nombre de lignes avec la casse changée: {0}/{1} - Nombre de lignes dont la casse est changée: {0}/{1} - Nombre de lignes avec la casse changée: {0}/{1}, casse changée pour les noms : {2} - Avant le changement de cadence de frames - Cadence de frame changée de {0} en {1} - {0} introuvable! Importer le fichiers VobSub quand même? - En-tête non valide fichier VobSub : {0} - Ouvrir sous-titres VobSub (sub/idx)... - Fichiers sous-titres VobSub - Avant d'importer des sous-titres VobSub - Avant de montrer les lignes précédentes/suivantes sélectionnées - Montrer précédent/suivant effectué sur les lignes sélectionnées - Double mots via regex {0} - Avant le tri: {0} - Triés par: {0} - Avant l'équilibre automatique des lignes sélectionnées - Nombre de lignes équilibrée automatiquement: {0} - Avant de supprimer la coupure de lignes des lignes sélectionnées - Nombre de lignes avec des coupures de lignes enlevés: {0} - Avant le remplacement multiple - Nombre de lignes avec du texte remplacé: {0} - Le nom "{0} 'a été ajouté à la liste noms/etc. - Le nom '{0} n'a pas été ajouté à la liste noms/etc - {0} lignes sélectionnées - Sous-titre contenant des notes de musique unicode. Ils seront perdus en sauvegardant avec encodage ANSI.Poursuivre la sauvegarde? - Sous-titre contenantt des codes de temps négatifs. Continuer la sauvegarde? - Avant de fusionner les lignes courtes - Nombre de lignes fusionnées: {0} - Avant la mise au minimum du temps d'affichage entre les paragraphes - Nombre de lignes avec le temps minimum d'affichage entre les paragraphes changé : {0} - Avant d'importer le fichier texte - Fichier texte importé - Avant le point de synchronisation - Point de synchronisation effectué - Avant d'importer les codes de temps - Codes de temps importés de {0}: {1} - Avant insertion du sous-titre à la position vidéo - Avant définir l'heure de début et décaler la suite - Continuer avec la correction orthographique actuelle? -
- +Poursuivre? + Compléter des sous-titres + Sous-titre ouvert à compléter... + Synchronisation visuelle - ajouter deuxième partie de sous-titre + Ajouter ce sous-titre synchronisé? + Avant ajout + Sous-titre ajouté: {0} + Sous-titre non ajouté! + Traduction Google + Traduction Microsoft + Avant la traduction Google + Lignes sélectionnées traduites + Sous-titre traduit + Traduire sous-titre Suèdois actuellement chargé en Danois + Traduire les sous-titres Suédois actuellement chargés (est-ce bien du suédois?) en Danois? + Traduction par www.nikse.dk/mt... + Avant traduction du Suédois en Danois + Traduction du Suédois en Danois terminée + Traduction du Suédois en Danois échouée + Avant d'annuler + Annuler effectué + Rien à annuler + Nom de langue invalide : {0} + Impossible de changer de langue! + Nombre de mots corrigés: {0} + Nombre de mots ignorés: {0} + Nombre de mots corrects: {0} + Nombre de mots ajoutés au dictionnaire: {0} + Nombre de hits pour nom: {0} + Correcteur d'orthographe + Avant la vérification orthographique + Vérification orthographique: Changé '{0}' en '{1} " + Avant d'ajouter <{0}> tag + <{0}> tags ajoutés + ligne {0} de {1} + {0} lignes supprimées + Avant de supprimer {0} lignes + Supprimer {0} lignes? + Ligne supprimée + Avant de supprimer une ligne + Supprimer une ligne? + Avant d'insérer ligne + Ligne insérée + Avant ligne mise à jour dans listview + Avant de définir la fonte à normale + Avant séparer la ligne + Line séparée + Avant de fusionner les lignes + Lignes fusionnées + Avant de régler la couleur + Avant de définir le nom de fonte + Avant effet machine à écrire + Avant effet karaoké + Avant d'importer des sous-titres du DVD + Ouvrir le fichier Matroska... + Fichiers Matroska + Aucun sous-titre trouvé + Ce n'est pas un fichier matroska valide : {0} + Analyse du fichier Matroska. Patientez... + Avant l'importation de sous-titres du fichier Matroska + Sous-titre importés de fichier Matroska + Déposer fichier '{0}' impossible - fichier trop volumineux + Vous ne pouvez déposer qu'un fichier + Avant de créer/modifier les lignes + Ouvrir sous-titre... + Avant de changer la casse + Nombre de lignes avec la casse changée: {0}/{1} + Nombre de lignes dont la casse est changée: {0}/{1} + Nombre de lignes avec la casse changée: {0}/{1}, casse changée pour les noms : {2} + Avant le changement de cadence de frames + Cadence de frame changée de {0} en {1} + {0} introuvable! Importer le fichiers VobSub quand même? + En-tête non valide fichier VobSub : {0} + Ouvrir sous-titres VobSub (sub/idx)... + Fichiers sous-titres VobSub + Ouvrir sous-titres BluRay (.sup)... + Fichiers sous-titres BluRay + Avant d'importer des sous-titres VobSub + Avant d'importer des sous-titres BluRay + Avant de montrer les lignes précédentes/suivantes sélectionnées + Montrer précédent/suivant effectué sur les lignes sélectionnées + Double mots via regex {0} + Avant le tri: {0} + Triés par: {0} + Avant l'équilibre automatique des lignes sélectionnées + Nombre de lignes équilibrée automatiquement: {0} + Avant de supprimer la coupure de lignes des lignes sélectionnées + Nombre de lignes avec des coupures de lignes enlevés: {0} + Avant le remplacement multiple + Nombre de lignes avec du texte remplacé: {0} + Le nom "{0} 'a été ajouté à la liste noms/etc. + Le nom '{0} n'a pas été ajouté à la liste noms/etc + {0} lignes sélectionnées + Sous-titre contenant des notes de musique unicode. Ils seront perdus en sauvegardant avec encodage ANSI.Poursuivre la sauvegarde? + Sous-titre contenantt des codes de temps négatifs. Continuer la sauvegarde? + Avant de fusionner les lignes courtes + Nombre de lignes fusionnées: {0} + Avant la mise au minimum du temps d'affichage entre les paragraphes + Nombre de lignes avec le temps minimum d'affichage entre les paragraphes changé : {0} + Avant d'importer le fichier texte + Fichier texte importé + Avant le point de synchronisation + Point de synchronisation effectué + Avant d'importer les codes de temps + Codes de temps importés de {0}: {1} + Avant insertion du sous-titre à la position vidéo + Avant définir l'heure de début et décaler la suite + Continuer avec la correction orthographique actuelle? +
+ Choisir les sous-titres du fichier Matroska - - Plus d'un sous-titre trouvées - choisir svp - Piste {0} - {1} - Langue: {2} - type: {3} - - - Fusionner les lignes courtes - Maximum de caractères dans un paragraphe - Maximum de millisecondes entre les lignes - Nombre de fusions: {0} - Ligne # - Texte fusionné - - - Remplacement multiple - Trouvez quoi - Remplacer par - Normal - Sensible à la casse - Expression régulière - Ligne # - Avant - Après - Lignes trouvés: {0} - Effacer - Ajouter - &Mise à jour - Activé - Type de recherche - - - Supprimer le texte pour les malentendants - Règles de supprssion du texte - Supprimer le texte entre: - '[' Et ']' - '(' Et ')' - '(' Et ')' - '?' et '?' - et - Supprimer le texte devant un deux points (':') - Seulement si le texte est en MAJUSCULE - Seulement dans une ligne séparée - Ligne # - Avant - Après - Lignes trouvés: {0} - Supprimer le texte si il contient: - - - Remplacer - Trouvez quoi: - Normal - Sensible à la casse - Expression régulière - Remplacer par - &Trouver - &Remplacer - Remplacer &tous - - - Régler le temps d'affichage minimum entre les paragraphes - Aperçu - paragraphes modifiés: {0} - Afficher uniquement les lignes modifiées - Minimum de millisecondes entre les lignes - - - Définir point de synchronisation à la ligne {0} - Synchroniser le code de point de temps - << 3 secs - << ½ sec - ½ sec >> - 3 secs >> - - - Configuration - Général - Lecture vidéo - Forme de l'onde - Outils - Listes de mots - Style SSA - Proxy - Afficher les boutons de la barre d'outils - Nouveau - Ouvrir - Sauver - Sauver sous - Chercher - Remplacer - Synchronisation visuelle - Orthographe - Config. - Aide - Divers - Voir la cadence dans la barre d'outils - Vitesse de trame par défaut - Encodage fichier par défaut - Détection auto du codage ANSI - Longueur maximale de sous-titre - Police de sous-titre - Taille de sous-titre - Se souvenir des fichiers récents (pour réouverture) - Démarrer avec le dernier fichier chargé - Se rappeler la position et la taille de la fenêtre principale - Démarrer en vue source - Supprimer les lignes vides lors de l'ouverture d'un sous-titre - Afficher les sauts de ligne dans la vue liste avec - Double-cliquer sur une ligne dans la fenêtre principale fera - Rien - Aller à la position vidéo puis pause - Aller à la position vidéo puis lire - Aller à la boite d'édition de texte - Moteur de rendu vidéo - DirectShow - quartz.dll du dossier system32/ - DirectX géré - Microsoft.DirectX.AudioVideoPlayback - .NET Managed code de DirectX - Windows Media Player - WMP ActiveX control - VLC Media Player - libvlc.dll de VLC Media Player 1.1.0 ou plus récent - Montrer bouton stop - Volume par défaut - 0 pour muet, 100 pour le volume le plus fort - Controles principaux de la fenêtre vidéo - Recherche texte et url personnalisée - Apparence de la forme de l'onde - Couleur de la grille - Montrer les lignes de la grille - Couleur - Couleur sélectionnée - Couleur de fond - Couleur du texte - Vider le répertoire 'WaveForms' - Le répertoire 'WaveForms' contient {0} fichiers ({1:0.00} MB) - Style du SSA (Sub Station Alpha) - Choisir fonte - Choisir couleur - Exemple - Un petit texte 123... - Langue - Liste Nom/ignore (sensible à la casse) - Ajouter nom - Ajouter mot - Enlever - Ajouter paire - Liste utilisateur - Liste correctif OCR - Emplacement - Utiliser le fichier web partagé Names_Etc.xml - Mot ajouter : {0} - Le mot existe déjà ! - Mot introuvable - Enlever {0} ? - Impossible de mettre à jour en ligne NamesEtc.xml! - Configuration du serveur proxy - Adresse du proxy - Authentification - Nom d'utilisateur - Mot de passe - Domaine - Lire X secondes puis retour. X = - Paragraphe de la première scène - Paragraphe de la dernière scène - Début + {0} - Fin - {0} - Corriger les erreurs fréquentes - Fusionner les lignes plus courtes que - Symbole musical - Symboles musicaux à remplacer (séparer par des espaces) - - - Afficher les options sélectionnées lignes plus tôt/tard - Voir précédent - Voir suivant - Ajustement total: {0} - - - Historique (pour annuler - Choisissez le point de retour en arrière - - Description - Comparer les éléments de l'historique - Comparer avec actuelle - Retour en arrière - - - Correcteur orthographique - Texte complet - Mot introuvable - Langue - Changer - Changer tous - &Passer - Passer &tous - Ajouter au dictionnaire utilisateur - Ajouter à la liste des noms (sensible à la casse) - Interrompre - Utiliser - Toujours &utiliser - Suggestions - Orthographe [{0}] - {1} - Editer texte entier - Editer un mot - Ajouter '{0}' à la liste nom/etc - Correction automatique seulement si la casse diffère - Texte de l'image - Vérification d'orthographe terminée - Vérification d'orthographe interrompue - - - Partitionner sous-titres - Entrer la durée de la 1ère partie de la vidéo ou - cliquer pour selectionner la vidéo: - &Couper - &Fait - Rien à partitionner! - Sauver partie 1 sous... - Sauver partie 2 sous... - Partie1 - Partie2 - Impossible de sauver {0} - - - Nouvelle numérotation... - Démarrer à partir de : - Oups, veuillez entrer un nombre - - - Synchronisation par points - Poser au moins deux points de synchro pour esquisser la synchro - Poser point de synchro - Enlever point de synchro - Points de synchro : {0} - La synchronization par points nécessite au moins 2 points de synchro - - - Type de sous-titre inconnu - Si vous voulez que cela soit corrigé, veuillez envoyer un email à mailto:niksedk@gmail.com avec une copie de ce sous-titre. - - - Synchronisation visuelle - Scène initiale - Scène finale - Synchroniser - < ½ sec - < 3 sec - Lire {0} s puis retour - Rechercher texte - Aller sous-position - Conserver les modifications ? - Les sous-titres ont été changés dans 'Synchro visuelle'. - Synchronisation terminée ! - La scène de début doit venir avant la scène finale ! - <ctrl+flèche gauche/droite> pour avancer/reculer de100 ms - - - Edite image compare base de données - Choisir les caractère(s) - Fichiers de comparaison des images - Image comparée courante - Texte associé à l'image - Est &italique - &Mise à jour - &Effacer - Image taille double - Fichier image introuvable - Image - - - Import/OCR VobSub (sub/idx) sous-titres - Méthode OCR - OCR par Microsoft Office Document Imaging (MODI). Nécessite MS Office - OCR par Tesseract - Langue - OCR par comparaison d'images - Base d'images - Nb de pixels dans l'espace - Nouveau - Editer - Lancer OCR - Stop - Lancer OCR à partir du sous-titre No: - Chargement des images VobSub... - Image sous-titre - Texte sous-titre - Impossible de créer le «dossier de la base de caractères ': {0} - Image sous-titre {0} sur {1} - Palette image - Utiliser couleurs personnalisées - Transparent - Demander pour les mots inconnus - Tenter de deviner mots inconnus - Coupure auto de paragraphe de plus de deux lignes - Tous les correctifs - Suppositions utilisées - Mots inconnus - Correction auto OCR /vérification orthographe - Correction des erreurs OCR - Sauver sous-titre image sous... - Tenter MS MODI OCR pour mots inconnus - Dictionnaire : {0} - De droite à gauche - Montrer uniquement les sous-titres forcés - Utiliser les codes de temps du fichier .idx - - - VobSub - Image vers texte manuel - Réduire sélection - Agrandir sélection - Image sous-titre - Caractère(s) - Caractère(s) comme texte - &Italique - Inte&rrompre - - - Nouveau dossier - Nom du dossier de la base des caractères - - - Cliquer pour ajouter une forme sonore - secondes - Agrandissement - Rétrécissement - Ajouter le texte ici - Supprimer texte - Couper - Couper au curseur - Fusionner avec le précédent - Fusionner avec le suivant - Lire sélection - + + Plus d'un sous-titre trouvées - choisir svp + Piste {0} - {1} - Langue: {2} - type: {3} + + + Fusionner les lignes courtes + Maximum de caractères dans un paragraphe + Maximum de millisecondes entre les lignes + Nombre de fusions: {0} + Ligne # + Texte fusionné + + + Remplacement multiple + Trouvez quoi + Remplacer par + Normal + Sensible à la casse + Expression régulière + Ligne # + Avant + Après + Lignes trouvés: {0} + Effacer + Ajouter + &Mise à jour + Activé + Type de recherche + + + Supprimer le texte pour les malentendants + Règles de supprssion du texte + Supprimer le texte entre: + '[' Et ']' + '(' Et ')' + '(' Et ')' + '?' et '?' + et + Supprimer le texte devant un deux points (':') + Seulement si le texte est en MAJUSCULE + Seulement dans une ligne séparée + Ligne # + Avant + Après + Lignes trouvés: {0} + Supprimer le texte si il contient: + + + Remplacer + Trouvez quoi: + Normal + Sensible à la casse + Expression régulière + Remplacer par + &Trouver + &Remplacer + Remplacer &tous + + + Régler le temps d'affichage minimum entre les paragraphes + Aperçu - paragraphes modifiés: {0} + Afficher uniquement les lignes modifiées + Minimum de millisecondes entre les lignes + + + Définir point de synchronisation à la ligne {0} + Synchroniser le code de point de temps + << 3 secs + << ½ sec + ½ sec >> + 3 secs >> + + + Configuration + Général + Lecture vidéo + Forme de l'onde + Outils + Listes de mots + Style SSA + Proxy + Afficher les boutons de la barre d'outils + Nouveau + Ouvrir + Sauver + Sauver sous + Chercher + Remplacer + Synchronisation visuelle + Orthographe + Config. + Aide + Divers + Voir la cadence dans la barre d'outils + Vitesse de trame par défaut + Encodage fichier par défaut + Détection auto du codage ANSI + Longueur maximale de sous-titre + Police de sous-titre + Taille de sous-titre + Se souvenir des fichiers récents (pour réouverture) + Démarrer avec le dernier fichier chargé + Se rappeler la position et la taille de la fenêtre principale + Démarrer en vue source + Supprimer les lignes vides lors de l'ouverture d'un sous-titre + Afficher les sauts de ligne dans la vue liste avec + Double-cliquer sur une ligne dans la fenêtre principale fera + Rien + Aller à la position vidéo puis pause + Aller à la position vidéo puis lire + Aller à la boite d'édition de texte + Moteur de rendu vidéo + DirectShow + quartz.dll du dossier system32/ + DirectX géré + Microsoft.DirectX.AudioVideoPlayback - .NET Managed code de DirectX + Windows Media Player + WMP ActiveX control + VLC Media Player + libvlc.dll de VLC Media Player 1.1.0 ou plus récent + Montrer bouton stop + Volume par défaut + 0 pour muet, 100 pour le volume le plus fort + Controles principaux de la fenêtre vidéo + Recherche texte et url personnalisée + Apparence de la forme de l'onde + Couleur de la grille + Montrer les lignes de la grille + Couleur + Couleur sélectionnée + Couleur de fond + Couleur du texte + Vider le répertoire 'WaveForms' + Le répertoire 'WaveForms' contient {0} fichiers ({1:0.00} MB) + Style du SSA (Sub Station Alpha) + Choisir fonte + Choisir couleur + Exemple + Un petit texte 123... + Langue + Liste Nom/ignore (sensible à la casse) + Ajouter nom + Ajouter mot + Enlever + Ajouter paire + Liste utilisateur + Liste correctif OCR + Emplacement + Utiliser le fichier web partagé Names_Etc.xml + Mot ajouter : {0} + Le mot existe déjà ! + Mot introuvable + Enlever {0} ? + Impossible de mettre à jour en ligne NamesEtc.xml! + Configuration du serveur proxy + Adresse du proxy + Authentification + Nom d'utilisateur + Mot de passe + Domaine + Lire X secondes puis retour. X = + Paragraphe de la première scène + Paragraphe de la dernière scène + Début + {0} + Fin - {0} + Corriger les erreurs fréquentes + Fusionner les lignes plus courtes que + Symbole musical + Symboles musicaux à remplacer (séparer par des espaces) + + + Afficher les options sélectionnées lignes plus tôt/tard + Voir précédent + Voir suivant + Ajustement total: {0} + + + Historique (pour annuler + Choisissez le point de retour en arrière + + Description + Comparer les éléments de l'historique + Comparer avec actuelle + Retour en arrière + + + Correcteur orthographique + Texte complet + Mot introuvable + Langue + Changer + Changer tous + &Passer + Passer &tous + Ajouter au dictionnaire utilisateur + Ajouter à la liste des noms (sensible à la casse) + Interrompre + Utiliser + Toujours &utiliser + Suggestions + Orthographe [{0}] - {1} + Editer texte entier + Editer un mot + Ajouter '{0}' à la liste nom/etc + Correction automatique seulement si la casse diffère + Texte de l'image + Vérification d'orthographe terminée + Vérification d'orthographe interrompue + + + Partitionner sous-titres + Entrer la durée de la 1ère partie de la vidéo ou + cliquer pour selectionner la vidéo: + &Couper + &Fait + Rien à partitionner! + Sauver partie 1 sous... + Sauver partie 2 sous... + Partie1 + Partie2 + Impossible de sauver {0} + + + Nouvelle numérotation... + Démarrer à partir de : + Oups, veuillez entrer un nombre + + + Synchronisation par points + Poser au moins deux points de synchro pour esquisser la synchro + Poser point de synchro + Enlever point de synchro + Points de synchro : {0} + La synchronization par points nécessite au moins 2 points de synchro + + + Type de sous-titre inconnu + Si vous voulez que cela soit corrigé, veuillez envoyer un email à mailto:niksedk@gmail.com avec une copie de ce sous-titre. + + + Synchronisation visuelle + Scène initiale + Scène finale + Synchroniser + < ½ sec + < 3 sec + Lire {0} s puis retour + Rechercher texte + Aller sous-position + Conserver les modifications ? + Les sous-titres ont été changés dans 'Synchro visuelle'. + Synchronisation terminée ! + La scène de début doit venir avant la scène finale ! + <ctrl+flèche gauche/droite> pour avancer/reculer de100 ms + + + Edite image compare base de données + Choisir les caractère(s) + Fichiers de comparaison des images + Image comparée courante + Texte associé à l'image + Est &italique + &Mise à jour + &Effacer + Image taille double + Fichier image introuvable + Image + + + Import/OCR VobSub (sub/idx) sous-titres + Import/OCR BluRay (.sup) sous-titres + Méthode OCR + OCR par Microsoft Office Document Imaging (MODI). Nécessite MS Office + OCR par Tesseract + Langue + OCR par comparaison d'images + Base d'images + Nb de pixels dans l'espace + Nouveau + Editer + Lancer OCR + Stop + Lancer OCR à partir du sous-titre No: + Chargement des images VobSub... + Image sous-titre + Texte sous-titre + Impossible de créer le «dossier de la base de caractères ': {0} + Image sous-titre {0} sur {1} + Palette image + Utiliser couleurs personnalisées + Transparent + Demander pour les mots inconnus + Tenter de deviner mots inconnus + Coupure auto de paragraphe de plus de deux lignes + Tous les correctifs + Suppositions utilisées + Mots inconnus + Correction auto OCR /vérification orthographe + Correction des erreurs OCR + Sauver sous-titre image sous... + Tenter MS MODI OCR pour mots inconnus + Dictionnaire : {0} + De droite à gauche + Montrer uniquement les sous-titres forcés + Utiliser les codes de temps du fichier .idx + + + VobSub - Image vers texte manuel + Réduire sélection + Agrandir sélection + Image sous-titre + Caractère(s) + Caractère(s) comme texte + &Italique + Inte&rrompre + + + Nouveau dossier + Nom du dossier de la base des caractères + + + Cliquer pour ajouter une forme sonore + secondes + Agrandissement + Rétrécissement + Ajouter le texte ici + Supprimer texte + Couper + Couper au curseur + Fusionner avec le précédent + Fusionner avec le suivant + Lire sélection +
\ No newline at end of file diff --git a/src/Resources/fr-FR.xml.zip b/src/Resources/fr-FR.xml.zip index 66272e31f..cc2cf2fbc 100644 Binary files a/src/Resources/fr-FR.xml.zip and b/src/Resources/fr-FR.xml.zip differ diff --git a/src/Resources/pl-PL.xml b/src/Resources/pl-PL.xml index 6c0c855af..adbc440f1 100644 --- a/src/Resources/pl-PL.xml +++ b/src/Resources/pl-PL.xml @@ -371,6 +371,7 @@ Email: mailto:nikse.dk@gmail.com Po&równaj... Importuj/OCR napisy z VOB/IFO (DVD)... Importuj/OCR napisy z VobSub (sub/idx)... + Importuj/OCR napisy z BluRay (.sup)... Importuj napisy z pliku Matroska... Importuj napisy z ręcznym wyborem kodowania... Importuj tekst... @@ -671,7 +672,10 @@ Kontynuować? Błędny nagłówek pliku VobSub: {0} Otwórz napisy VobSub (sub/idx)... Pliki napisów VobSub + Otwórz napisy BluRay (.sup)... + Pliki napisów BluRay (.sup) Przed importowaniem napisów VobSub + Przed importowaniem napisów BluRay (.sup) Przed wybraniem wcześniejszego/późniejszego ukazywania się linii Wykonanie na wybranych liniach wcześniejszego/późniejszego ukazywania się Podwójne wyrazy via regex {0} @@ -973,6 +977,7 @@ Kontynuować? Import/OCR napisów VobSub (sub/idx) + Import/OCR napisów BluRay (.sup) Metody OCR OCR za pomocą MS MODI. Wymagany MS Office OCR przy użyciu Tesseract diff --git a/src/Resources/pl-PL.xml.zip b/src/Resources/pl-PL.xml.zip index c97d6e284..2baef6d83 100644 Binary files a/src/Resources/pl-PL.xml.zip and b/src/Resources/pl-PL.xml.zip differ diff --git a/src/Resources/ro-RO.xml b/src/Resources/ro-RO.xml index 4fdcaac05..edaaa62e5 100644 --- a/src/Resources/ro-RO.xml +++ b/src/Resources/ro-RO.xml @@ -368,6 +368,7 @@ E-mail: nikse.dk @gmail.com &Compara... Import/subtitrarea OCR din vob/IFO (DVD) ... Import/OCR VobSub (sub/idx) subtitrarea... + Import/OCR BluRay (,sup) subtitrarea... Import subtitrare din fisier Matroska... Import subtitrare cu alegerea manuala a codarii... Import text simplu... @@ -668,7 +669,10 @@ E-mail: nikse.dk @gmail.com Antetul nu este valabil pentru fisier VobSubr: {0} Deschide subtitrare VobSub (sub/idx)... Fisier subtitrare VobSub + Deschide subtitrare BluRay (.sup)... + Fisier subtitrare BluRay Inainte de a importa subtitrare VobSub + Inainte de a importa subtitrare BluRay (.sup) Inainte de a arata liniile selectate mai devreme/tarziu Arata mai devreme/tarziu efectuate pe liniile selectate Cuvinte dublate via regex {0} @@ -970,6 +974,7 @@ E-mail: nikse.dk @gmail.com Import subtitrare /OCR VobSub (sub/idx) + Import subtitrare /OCR BluRay (.sup) OCR metoda OCR, prin intermediul Microsoft Office Document Imaging (MODI). Necesita MS Office OCR prin Tesseract diff --git a/src/Resources/ro-RO.xml.zip b/src/Resources/ro-RO.xml.zip index 3cb8f1ab9..4c4ae082c 100644 Binary files a/src/Resources/ro-RO.xml.zip and b/src/Resources/ro-RO.xml.zip differ diff --git a/src/Resources/sr-Cyrl-CS.xml b/src/Resources/sr-Cyrl-CS.xml index 37ce29787..99099fce8 100644 --- a/src/Resources/sr-Cyrl-CS.xml +++ b/src/Resources/sr-Cyrl-CS.xml @@ -1,4 +1,4 @@ - + Subtitle Edit @@ -370,6 +370,7 @@ C# изворни кôд се налази на интернет страниц &Упореди... Увези/препознај знакове титла из VOB/IFO датотеке (ДВД)... Увези/препознај знакове VobSub титла... + Увези/препознај знакове BluRay титла... Увези титл из матрошка датотеке... Увези титл с ручно изабраним кодним распоредом... Увези чист текст... @@ -599,8 +600,7 @@ C# изворни кôд се налази на интернет страниц Качење титла Отвори титл за качење... Визуелна синхронизација — качење другог дела титла - - + Додај овај синхронизовани титлове? Пре качења Прикачено титлова: {0} Титл није прикачен! @@ -671,7 +671,10 @@ C# изворни кôд се налази на интернет страниц Заглавље није исправна VobSub датотека: {0} Отварање VobSub титла... VobSub титлови + Отварање BluRay (.sup) титла... + BluRay титлови Пре увоза VobSub титла + Пре увоза BluRay титла Пре приказивања изабране линије раније/касније Прикажи изабране линије раније или касније Дупле речи путем регекса {0} @@ -694,10 +697,8 @@ C# изворни кôд се налази на интернет страниц Измењено броја линија с минималним временом приказа између пасуса: {0} Пре увоза чистог текста Текст је увезен - - - - + Пре тачка синхронизације + Тачка синхронизације урадити Пре увоза временских одредница Временске одреднице су увезене из {0}: {1} Пре постављања титла у положај видео записа @@ -975,6 +976,7 @@ C# изворни кôд се налази на интернет страниц Увожење/препознавање знакова VobSub титла + Увожење/препознавање знакова BluRay титла Метода препознавања знакова Препознавање знакова путем Microsoft Office Document Imaging (MODI). Захтева MS Office Препознавање знакова путем хиперкоцке diff --git a/src/Resources/sr-Cyrl-CS.xml.zip b/src/Resources/sr-Cyrl-CS.xml.zip index 7c81b5bcc..78b4b9632 100644 Binary files a/src/Resources/sr-Cyrl-CS.xml.zip and b/src/Resources/sr-Cyrl-CS.xml.zip differ diff --git a/src/Resources/sr-Latn-CS.xml b/src/Resources/sr-Latn-CS.xml index 68e92ed2d..009f4057f 100644 --- a/src/Resources/sr-Latn-CS.xml +++ b/src/Resources/sr-Latn-CS.xml @@ -1,4 +1,4 @@ - + Subtitle Edit @@ -370,6 +370,7 @@ E-pošta: mailto:nikse.dk@gmail.com &Uporedi... Uvezi/prepoznaj znakove titla iz VOB/IFO datoteke (DVD)... Uvezi/prepoznaj znakove VobSub titla... + Uvezi/prepoznaj znakove BluRay (.sup) titla... Uvezi titl iz matroška datoteke... Uvezi titl s ručno izabranim kodnim rasporedom... Uvezi čist tekst... @@ -599,8 +600,7 @@ koji bi trebalo da je već sinhronizovan s video zapisom. Kačenje titla Otvori titl za kačenje... Vizuelna sinhronizacija — kačenje drugog dela titla - - + Додај овај синхронизовани титлове? Pre kačenja Prikačeno titlova: {0} Titl nije prikačen! @@ -671,7 +671,10 @@ koji bi trebalo da je već sinhronizovan s video zapisom. Zaglavlje nije ispravna VobSub datoteka: {0} Otvaranje VobSub titla... VobSub titlovi + Otvaranje BluRay titla... + BluRay (.sup) titlovi Pre uvoza VobSub titla + Pre uvoza BluRay titla Pre prikazivanja izabrane linije ranije/kasnije Prikaži izabrane linije ranije ili kasnije Duple reči putem regeksa {0} @@ -694,10 +697,8 @@ koji bi trebalo da je već sinhronizovan s video zapisom. Izmenjeno broja linija s minimalnim vremenom prikaza između pasusa: {0} Pre uvoza čistog teksta Tekst je uvezen - - - - + Пре тачка синхронизације + Тачка синхронизације урадити Pre uvoza vremenskih odrednica Vremenske odrednice su uvezene iz {0}: {1} Pre postavljanja titla u položaj video zapisa @@ -975,6 +976,7 @@ koji bi trebalo da je već sinhronizovan s video zapisom. Uvoženje/prepoznavanje znakova VobSub titla + Uvoženje/prepoznavanje znakova BluRay titla Metoda prepoznavanja znakova Prepoznavanje znakova putem Microsoft Office Document Imaging (MODI). Zahteva MS Office Prepoznavanje znakova putem hiperkocke diff --git a/src/Resources/sr-Latn-CS.xml.zip b/src/Resources/sr-Latn-CS.xml.zip index 596e57ee0..e2bd25ff1 100644 Binary files a/src/Resources/sr-Latn-CS.xml.zip and b/src/Resources/sr-Latn-CS.xml.zip differ diff --git a/src/Resources/sv-SE.xml b/src/Resources/sv-SE.xml index b39e738b8..526f285fc 100644 --- a/src/Resources/sv-SE.xml +++ b/src/Resources/sv-SE.xml @@ -371,6 +371,7 @@ &Jämför... Importera/OCR textning från VOB/IFO (DVD) ... Importera/OCR VobSub (sub/idx) undertext... + Importera/OCR BluRay (.sup) undertext... Importera undertext från Matroska fil... Importera undertext med manuell valda kodningen... Importera enbart text... @@ -671,7 +672,10 @@ Rubrik inte giltigt VobSub fil: {0} Öppna VobSub (sub/idx) undertext... VobSub undertext filer + Öppna BluRay (.sup) undertext... + BluRay undertext filer Innan du importerar VobSub undertext + Innan du importerar BluRay undertext Före visa valda rader tidigare/senare Visa tidigare/senare utförs på utvalda rader Dubbel ord via regex {0} @@ -973,6 +977,7 @@ Import/OCR VobSub (sub/idx) undertext + Import/OCR BluRay (.sup) undertext OCR-metod OCR via Microsoft Office Document Imaging (MODI). Kräver MS Office OCR via Tesseract diff --git a/src/Resources/sv-SE.xml.zip b/src/Resources/sv-SE.xml.zip index eb75fc9dc..9c5bfd190 100644 Binary files a/src/Resources/sv-SE.xml.zip and b/src/Resources/sv-SE.xml.zip differ diff --git a/src/SubtitleEdit.csproj b/src/SubtitleEdit.csproj index 63b50bc67..56e1f003f 100644 --- a/src/SubtitleEdit.csproj +++ b/src/SubtitleEdit.csproj @@ -369,6 +369,11 @@ VobSubOcrNewFolder.cs + + + + + @@ -436,6 +441,8 @@ + + @@ -670,7 +677,7 @@ Designer - +